Documents & code‎ > ‎

Win32 Disk Management IO Control Codes - SET DRIVE LAYOUT

Win32 Disk Management IO Control Codes - SET DRIVE LAYOUT   
post id12 
post length17569 
post datetime12/9/2009 6:52:57 PM 
post ip77.51.3.219 

 

Win32 Disk Management IO Control Codes - SET DRIVE LAYOUT 

Дата подачи: 24.01.2009   


Win32 Disk Management I/O Control Codes 
(from winioctl.h). 


 GET DRIVE LAYOUT 
 SET DRIVE LAYOUT 


[Продолжение прошлогодней темы…] 


смотрим все логические диски разделов 1-го физического диска и у кого ФАТ16 - меняем на ФАТ32. 



' на всякий случай, при необходимости пройтись непосредственно по 
' томам (вернее логич. дискам) можно 
' применить такую конструкци. 

For Each str As String In Environment.GetLogicalDrives() 

Dim Handle As Integer = CreateFile(String.Concat("\\.\", Left(str, Len(str) - 1)) _ 
, GENERIC_ALL _ 
, FILE_SHARE_READ Or FILE_SHARE_WRITE _ 
, 0 _ 
, OPEN_EXISTING _ 
, FILE_ATTRIBUTE_NORMAL _ 
, 0) 

' обход томов, смонтированных на 
' что-либо рассматривалось 
' ранее. 

GetVolumeNameForVolumeMountPoint(str) 

... 
... 

Next 


Example [Visual Basic]: 



Option Strict Off : Option Explicit On 

Imports Tested.Emicrox.DiskManagement _ 
      , Tested.Emicrox.Exception _ 
      , Tested.Emicrox.TAPE _ 
      , Tested.Emicrox.IO 

Public Module Main 
    ' 
    <STAThread()Sub Main() 
        ' 
        Dim Handle As Integer = CreateFile("\\.\PHYSICALDRIVE0" _ 
        , GENERIC_READ Or GENERIC_WRITE _ 
        , FILE_SHARE_READ Or FILE_SHARE_WRITE _ 
        , 0 _ 
        , OPEN_EXISTING _ 
        , FILE_ATTRIBUTE_NORMAL _ 
        , 0) 
        ' 
        If Not (Handle = -1) Then 
            ' 
            Dim DriverLayout = Z_Get_Drive_Layout(Handle) 
            ' 
            With DriverLayout 
                ' 
                For As Integer = 0 To .PartitionCount 
                    ' 
                    With .PartitionEnTry(i) 
                        ' 
                        If (.PartitionType = PartitionType.FAT16) _ 
                        Or (.PartitionType = PartitionType.FAT32) _ 
                        Or (.PartitionType = PartitionType.NTFS) Then 
                            ' 
                            If (.PartitionType = PartitionType.FAT16) And Not (.BootIndicator = 1) Then 
                                ' 
                                ' ну, или как-то так... 
                                ' 
                                .PartitionType = PartitionType.FAT32 
                                ' 
                                Z_Set_Drive_Layout(Handle, DriverLayout) 
                                ' 
                            End If 
                            ' 
                        End If 
                        ' 
                    End With 
                    ' 
                Next 
                ' 
            End With 
            ' 
            CloseHandle(Handle) 
            ' 
        Else 
            ' 
            Console.WriteLine(String.Concat("error opening device: " _ 
            , GetErrorMessage()) _ 
            ) 
            ' 
        End If 
        ' 
        Console.ReadLine() 
        ' 
    End Sub 
    ' 
End Module 

---------- 

Namespace Emicrox 
    ' 
    <SuppressUnmanagedCodeSecurity()> _ 
    Public NotInheritable Class DiskManagement 
        ' 
#Region "---------- DISK LAYOUT ----------" 
        ' 
        Shared Function Z_Get_Drive_Layout(ByVal Handle As Integer) 
            ' 
            Dim ret = Nothing 
            ' 
            Dim ptrSize = 1024 
            ' 
            Dim ptr As IntPtr = Marshal.AllocHGlobal(ptrSize) 
            ' 
            If Not (DeviceIoControl(Handle _ 
            , IOCTL_DISK_GET_DRIVE_LAYOUT, Nothing, 0, ptr, ptrSize _ 
            , New Integer, 0) = 0) Then 
                ' 
                ret = Marshal.PtrToStructure(ptr _ 
                , GetType(DRIVE_LAYOUT_INFORMATION)) 
                ' 
            Else 
                ' 
                Console.WriteLine(String.Concat("error get drive layout: " _ 
                , GetErrorMessage()) _ 
                ) 
                ' 
            End If 
            ' 
            Marshal.FreeHGlobal(ptr) 
            ' 
            Return ret 
            ' 
        End Function 
        ' 
        Shared Sub Z_Set_Drive_Layout(ByVal Handle As Integer, ByVal drivelayout As DRIVE_LAYOUT_INFORMATION) 
            ' 
            Dim ptrSize = Marshal.SizeOf(drivelayout) 
            ' 
            Dim ptr As IntPtr = Marshal.AllocHGlobal(ptrSize) 
            ' 
            Marshal.StructureToPtr(drivelayout, ptr, True) 
            ' 
            If Not (DeviceIoControl(Handle _ 
            , IOCTL_DISK_SET_DRIVE_LAYOUT, ptr, ptrSize, Nothing, 0 _ 
            , New Integer, 0) = 0) Then 
                ' 
            Else 
                ' 
                Console.WriteLine(String.Concat("error set drive layout: " _ 
                , GetErrorMessage()) _ 
                ) 
                ' 
            End If 
            ' 
            Marshal.FreeHGlobal(ptr) 
            ' 
        End Sub 
        ' 
        Const IOCTL_DISK_GET_DRIVE_LAYOUT_EX As Integer = 458832 
        Const IOCTL_DISK_SET_DRIVE_LAYOUT_EX As Integer = 507988 
        Const IOCTL_DISK_GET_DRIVE_LAYOUT As Integer = 475148 
        Const IOCTL_DISK_SET_DRIVE_LAYOUT As Integer = 507920 
        ' 
        Public Enum PartitionType As Byte 
            FAT16 = 6 
            FAT32 = 11 
            NTFS = 7 
        End Enum 
        ' 
        <StructLayout(LayoutKind.Sequential)> _ 
        Public Structure DRIVE_LAYOUT_INFORMATION 
            Public PartitionCount As Integer 
            Public Signature As Integer 
            <MarshalAs(UnmanagedType.ByValArray, SizeConst:=56)> Public PartitionEnTry() As PARTITION_INFORMATION 
        End Structure 
        ' 
        <StructLayout(LayoutKind.Explicit)> _ 
        Public Structure PARTITION_INFORMATION 
            <FieldOffset(0)> Public StartingOffset As Long 
            <FieldOffset(8)> Public PartitionLength As Long 
            <FieldOffset(16)> Public HiddenSectors As Integer 
            <FieldOffset(20)> Public PartitionNumber As Integer 
            <FieldOffset(24)> Public PartitionType As Byte 
            <FieldOffset(25)> Public BootIndicator As Byte 
            <FieldOffset(26)> Public RecognizedPartition As Byte 
            <FieldOffset(27)> Public RewritePartition As Byte 
        End Structure 
        ' 
#End Region 
        ' 
        <DllImport("kernel32")> _ 
                Public Shared Function DeviceIoControl( _ 
        ByVal hDevice As Integer, _ 
        ByVal dwIoControlCode As Integer, _ 
        ByVal lpInBuffer As [IntPtr], _ 
        ByVal nInBufferSize As Integer, _ 
        ByVal lpOutBuffer As [IntPtr], _ 
        ByVal nOutBufferSize As Integer, _ 
        ByRef lpBytesReturned As Integer, _ 
        ByVal lpOverlapped As Integer _ 
        ) As Integer 
        End Function 
        ' 
    End Class 
    ' 
    ' 
End Namespace 

---------- 

Namespace Emicrox 
    ' 
    <SuppressUnmanagedCodeSecurity()> _ 
    Public Class Exception 
        ' 
        Shared FORMAT_MESSAGE_ALLOCATE_BUFFER As Integer = &H100 
        Shared FORMAT_MESSAGE_IGNORE_INSERTS As Integer = &H200 
        Shared FORMAT_MESSAGE_FROM_SYSTEM As Integer = &H1000 
        ' 
        Public Shared Function GetErrorMessage() As String 
            ' 
            Dim errorCode = GetLastError() 
            ' 
            Dim msgSize As Integer = 255 
            ' 
            Dim lpMsgBuf As String = Nothing 
            ' 
            Dim dwFlags As Integer = FORMAT_MESSAGE_ALLOCATE_BUFFER _ 
            Or FORMAT_MESSAGE_FROM_SYSTEM _ 
            Or FORMAT_MESSAGE_IGNORE_INSERTS 
            ' 
            Dim lpSource As IntPtr = IntPtr.Zero 
            ' 
            Dim lpArguments As IntPtr = IntPtr.Zero 
            ' 
            Dim ReturnVal As Integer _ 
            = FormatMessage(dwFlags, lpSource, errorCode, 0, lpMsgBuf, msgSize, lpArguments) 
            ' 
            If ReturnVal = 0 Then 
                ' 
                Return errorCode.ToString() 
                ' 
            Else 
                ' 
                Return lpMsgBuf 
                ' 
            End If 
            ' 
        End Function 
        ' 
        ' 
        <DllImport("kernel32")> _ 
                Public Shared Function GetLastError( _ 
        ) As Integer 
        End Function 
        ' 
        <DllImport("kernel32.dll")> _ 
                Public Shared Function FormatMessage( _ 
        ByVal dwFlags As Integer, _ 
        ByRef lpSource As IntPtr, _ 
        ByVal dwMessageId As Integer, _ 
        ByVal dwLanguageId As Integer, _ 
        ByRef lpBuffer As [String], _ 
        ByVal nSize As Integer, _ 
        ByRef Arguments As IntPtr _ 
        ) As Integer 
        End Function 
        ' 
    End Class 
    ' 
End Namespace 

Namespace Emicrox 
    ' 
    <SuppressUnmanagedCodeSecurity()> _ 
    Public Class IO 
        ' 
        Public Const FILE_SHARE_READ = &H1 
        Public Const FILE_SHARE_WRITE = &H2 
        Public Const FILE_SHARE_DELETE = &H4 
        ' ... 
        ' 
        <DllImport("kernel32", EnTryPoint:="CreateFileA", ExactSpelling:=True, CharSet:=CharSet.[Ansi])> _ 
                Public Shared Function CreateFile( _ 
        <MarshalAs(UnmanagedType.VBByRefStr)> ByRef lpFileName As String, _ 
        ByVal dwDesiredAccess As UInteger, _ 
        ByVal dwShareMode As Integer, _ 
        ByVal lpSecurityAttributes As Integer, _ 
        ByVal dwCreationDisposition As Integer, _ 
        ByVal dwFlagsAndAttributes As Integer, _ 
        ByVal hTemplateFile As Integer _ 
        ) As Integer 
        End Function 
        ' ... 
        ' 
    End Class 
    ' 
End Namespace 



THE END. 






------------------------------------- 
коррект от: 24.01.2009 


ВРЕМЕННО! Будет удалено.. 

Для внутреннего пользования! ;)) 

Win32 Disk Management I/O Control Codes 
(from winioctl.h). 

 SET DRIVE LAYOUT 

Кратко по поводу защиты данных на флешке: 

Суть: Модифицируем структуру разделов съёмного диска перед его извлечением. Комбинируя такми значениями таблицы разделов, как [PartitionType], [PartitionLength] и [StartOfset] получаем своеобразное неординарное сочетание параметров, без восстановления которых работа с данными как бы не возможна. 

До: 

 

После: 

 

Результат: 

 


----------------------- 


Option Strict Off : Option Explicit On 

Imports System.Runtime.InteropServices 

Public Module Main 

    <DllImport("kernel32")> _ 
        Public Shared Function DeviceIoControl( _ 
    <[In]()> ByVal hDevice As Integer, _ 
    <[In]()> ByVal dwIoControlCode As Integer, _ 
    <[In]()> ByVal lpInBuffer As [IntPtr], _ 
    <[In]()> ByVal nInBufferSize As Integer, _ 
    <[Out]()> ByVal lpOutBuffer As [IntPtr], _ 
    <[In]()> ByVal nOutBufferSize As Integer, _ 
    <[In]()> ByRef lpBytesReturned As Integer, _ 
    <[In]()> ByVal lpOverlapped As Integer _ 
    ) As Integer 
    End Function 

    <StructLayout(LayoutKind.Sequential)> _ 
    Public Structure DRIVE_LAYOUT_INFORMATION 
        Public PartitionCount As Integer 
        Public Signature As Integer 
        <MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> Public PartitionEnTry() As PARTITION_INFORMATION 
    End Structure 

    <StructLayout(LayoutKind.Explicit)> _ 
    Public Structure PARTITION_INFORMATION 
        <FieldOffset(0)> Public StartingOffset As Long 
        <FieldOffset(8)> Public PartitionLength As Long 
        <FieldOffset(16)> Public HiddenSectors As Integer 
        <FieldOffset(20)> Public PartitionNumber As Integer 
        <FieldOffset(24)> Public PartitionType As Byte 
        <FieldOffset(25)> Public BootIndicator As Boolean 
        <FieldOffset(26)> Public RecognizedPartition As Boolean 
        <FieldOffset(27)> Public RewritePartition As Boolean 
    End Structure 

    Shared Function Z_Get_Drive_Layout(ByVal Handle As Integer) 
        ' 
        Dim ret = Nothing 
        ' 
        Dim ptrSize = Marshal.SizeOf(New DRIVE_LAYOUT_INFORMATION) 
        ' 
        Dim ptr As IntPtr = Marshal.AllocHGlobal(ptrSize) 
        ' 
If Not (DeviceIoControl(Handle _ 
, [475148.0F], Nothing, 0, ptr, ptrSize _ 
New Integer, 0) = 0) Then 
            ' 
            ret = Marshal.PtrToStructure(ptr _ 
            , GetType(DRIVE_LAYOUT_INFORMATION)) 
            ' 
        End If 
        ' 
        Marshal.FreeHGlobal(ptr) 
        ' 
        Return ret 
        ' 
    End Function 
    ' 
    Shared Sub Z_Set_Drive_Layout(ByVal Handle As Integer, ByVal drivelayout As DRIVE_LAYOUT_INFORMATION) 
        ' 
        Dim ptrSize = Marshal.SizeOf(drivelayout) 
        ' 
        Dim ptr As IntPtr = Marshal.AllocHGlobal(ptrSize) 
        ' 
        Marshal.StructureToPtr(drivelayout, ptr, True) 
        ' 
If Not (DeviceIoControl(Handle _ 
, [507920.0F], ptr, ptrSize, Nothing, 0 _ 
New Integer, 0) = 0) Then 
        End If 
        ' 
        Marshal.FreeHGlobal(ptr) 
        ' 
    End Sub 

    Shared Sub Z_Update_Properties(ByVal Handle As Integer) 
        ' 
If Not (DeviceIoControl(Handle _ 
, [459072.0F], Nothing, 0, Nothing, 0 _ 
New Integer, 0) = 0) Then 
        Else 
            ' 
            Console.WriteLine(String.Concat(GetErrorMessage())) 
            ' 
        End If 
        ' 
    End Sub 

    <STAThread()Sub Main() 
        ' 
        Dim Handle As Integer = CreateFile("\\.\K:" _ 
        , &H80000000L _ 
        + &H40000000L _ 
        + &H20000000L, &H1 _ 
        + &H2 _ 
        + &H4 _ 
        , 0, 3, 128, 0) 
        ' 
        If Not (Handle = -1) Then 
            ' 
            Dim DriverLayout = Z_Get_Drive_Layout(Handle) 
            ' 
            ' 1-й [из 4-х]: 
            With DriverLayout.PartitionEnTry(0) 
                ' 
                .RewritePartition = True 
                ' 
                Select Case .PartitionType 
                    Case 7.0F 'NTFS 
                        ' 
                        ' [1] Encripted... 
                        ' 
                        .PartitionLength = 1024 
.PartitionType = [2.0F] 
                        ' 
                    Case 2.0F 'none 
                        ' 
                        ' [2] Decripted... 
                        ' 
.PartitionLength = [original value] 
.PartitionType = [7.0F] 
                        ' 
                End Select 
                ' 
            End With 
            ' 
            Z_Set_Drive_Layout(Handle, DriverLayout) 
            ' 
            Z_Update_Properties(Handle) 
            ' 
            CloseHandle(Handle) 
            ' 
        End If 
        ' 
    End Sub 
    ' 
End Module 




То же самое можно реализовать и вообще не прибегая к [DeviceIoControl] , а исключительно используя абсолютные офсеты, 
например: 

из MSDN: 

Partition Table on Basic Disks 
The partition table, which is a 64-byte data Structure that is used to identify the type and location of partitions on a hard disk, conforms to a standard layout, independent of the operating system. Each partition table enTry is 16 bytes long, With a maximum of four entries. EachenTry starts at a predetermined offset from the beginning of the sector, As follows: 

 

• Partition 1 0x01BE (446) 
0x01BE 1 byte 80 Boot Indicator. Indicates whether the 
volume 
is the 
active partition. Legal values include: 
• 00. Do not use For booting. 
• 80. Active partition. 
0x01BF 1 byte 01 Starting Head. 
0x01C0 6 bits 01 *2 Starting Sector. Only bits 0–5 are 
used. The 
upper two bits, 6 and 7, are used by the Starting Cylinder field. 
0x01C1 10 bits 00 * Starting Cylinder. Uses 1 byte in 
addition to 
the upper 2 bits from the Starting Sector field to make up the 
cylinder value. The Starting Cylinder is a 10-bit number that hAs 
maximum value of 1023. 
0x01C2 1 byte 07 System ID. Defines the volume type. See 
the table 
titled “System ID Values” later in this section For sample values. 
0x01C3 1 byte FE Ending Head. 
0x01C4 6 bits BF * Ending Sector. Only bits 0–5 are used. 
The upper 
two bits, 6 and 7, are used by the Ending Cylinder field. 
0x01C5 10 bits 09 * Ending Cylinder. Uses 1 byte in 
addition to the 
upper 2 bits from the Ending Sector field to make up the cylinder 
value. The Ending Cylinder is a 10-bit number, With a maximum value 
of 1023. 
0x01C6 4 bytes 3F 00 00 00 Relative Sectors. The offset 
from the 
beginning of the disk to the beginning of the volume, counting by 
sectors. 
0x01CA 4 bytes 4B F5 7F 00 Total Sectors. The total number 
of sectors in the volume. 
• Partition 2 0x01CE (462) 
• Partition 3 0x01DE (478) 
• Partition 4 0x01EE (494) 


и т.д… 
[подробнее – в MS:SDK] 


THE END. 
Comments