I'm using the p/invoke API calls for "CreateFile" and "DeviceIOControl" in a small program that creates a disk image.
As the code stands, it runs without errors, I can open the file handle (verified by reading data from it), however the call to the deviceiocontrol function to grab disk geometry (and calculate physical disk size) returns an empty object. I've tried varying the function signatures slightly, thinking maybe a data type somewhere was the issue, but with no effect.
I'll keep the code example as brief as possible here...
These are the structure and API function declarations I've settled on:
And this is the code that actually calls the functions:
As I said, the codes runs with no errors, however my "dg" object at the end there is full of zeros. I've tried changing the SafeFileHandles to Longs, as the older API examples all used, but that also changes nothing. Has anyone done this in VB or C# that can show me what might be wrong?
This is being done with VS2010, 3.5 framework, if it matters.
As the code stands, it runs without errors, I can open the file handle (verified by reading data from it), however the call to the deviceiocontrol function to grab disk geometry (and calculate physical disk size) returns an empty object. I've tried varying the function signatures slightly, thinking maybe a data type somewhere was the issue, but with no effect.
I'll keep the code example as brief as possible here...
These are the structure and API function declarations I've settled on:
Code:
Private Const IOCTL_DISK_GET_DRIVE_GEOMETRY As Long = &H70000
<System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)> _
Public Structure DISK_GEOMETRY
Public Cylinders As Long
Public MediaType As MEDIA_TYPE
Public TracksPerCylinder As Integer
Public SectorsPerTrack As Integer
Public BytesPerSector As Integer
Public ReadOnly Property DiskSize() As Long
Get
Return Cylinders * CLng(TracksPerCylinder) * CLng(SectorsPerTrack) * CLng(BytesPerSector)
End Get
End Property
End Structure
Public Enum Media_Type As Integer
Unknown = 0
Removable = 11
FixedMedia = 12
End Enum
<DllImport("Kernel32.dll", SetLastError:=False, CharSet:=CharSet.Auto)>
Public Shared Function DeviceIoControl( _
ByVal hDevice As Microsoft.Win32.SafeHandles.SafeFileHandle, _
ByVal IoControlCode As Long, _
<MarshalAs(UnmanagedType.AsAny), [In]()> ByVal InBuffer As Object, _
ByVal nInBufferSize As UInteger, _
<MarshalAs(UnmanagedType.AsAny), [Out]()> ByVal OutBuffer As Object, _
ByVal nOutBufferSize As UInteger, _
ByRef pBytesReturned As UInteger, _
<[In]()> ByRef Overlapped As Object) As Boolean
End Function
<DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function CreateFile( _
ByVal lpFileName As String, _
ByVal dwDesiredAccess As Int32, _
ByVal dwShareMode As Int32, _
ByVal lpSecurityAttributes As Int32, _
ByVal dwCreationDisposition As Int32, _
ByVal dwFlagsAndAttributes As Int32, _
ByVal hTemplateFile As Int32) As SafeFileHandle
End Function
And this is the code that actually calls the functions:
Code:
Dim hDevice As SafeFileHandle
hDevice = CreateFile("\\.\PHYSICALDRIVE0", _
0, _
FILE_SHARE_READ Or FILE_SHARE_WRITE, _
0, _
OPEN_EXISTING, _
0, 0)
If Not hDevice.IsInvalid Then
Dim dg As DISK_GEOMETRY
Dim bytesReturned As Long
DeviceIoControl(hDevice, _
IOCTL_DISK_GET_DRIVE_GEOMETRY, _
IntPtr.Zero, _
0, _
dg, _
Marshal.SizeOf(dg), _
bytesReturned, _
IntPtr.Zero)
debug.print(dg.DiskSize)
End If
hDevice.Close
As I said, the codes runs with no errors, however my "dg" object at the end there is full of zeros. I've tried changing the SafeFileHandles to Longs, as the older API examples all used, but that also changes nothing. Has anyone done this in VB or C# that can show me what might be wrong?
This is being done with VS2010, 3.5 framework, if it matters.