none
[SOLVED] Help DeviceIoControl in VB 2010 RRS feed

  • Question

  • I am trying to write a program that will send raw ATA packet commands using the ATA_PASS_THROUGHT_DIRECT approach. As for my testing if the code works, I try the simple command which is the "Identify Device".

    The problem is when I execute DeviceIoControl I get a returned status of "false" and I also check the error thru Err.LastDllError after the call of DeviceIoControl, surprisingly I get an error code of 1450 whcih means insufficient system resources.

    Appreciate any help from the community for pointers of what went wrong with my code. The source code are posted below for reference. Thanks.

    Imports System.Runtime.InteropServices
    
    Module AtaIoctl4
    
        Private Const INVALID_HANDLE_VALUE As Int64 = -1
    
        Private Const ATA_IDENTIFY_DATA_VENDOR_UNIQUE_LENGTH = &H3
        Private Const ATA_IDENTIFY_DATA_SERIAL_NUMBER_LENGTH = &HA
        Private Const ATA_IDENTIFY_DATA_LOT_CODE_LENGTH = &HA
        Private Const ATA_IDENTIFY_DATA_FIRMWARE_REV_LENGTH = &H8
        Private Const ATA_IDENTIFY_DATA_VENDOR_ID_LENGTH = &H28
        Private Const ATA_IDENTIFY_DATA_RESERVED2_LENGTH = &H30
        Private Const ATA_IDENTIFY_DATA_RESERVED3_LENGTH = &H4C
        Private Const ATA_IDENTIFY_DATA_MODEL_NUMBER_LENGTH = &H10
        Private Const ATA_IDENTIFY_DATA_SUB_MODEL_NUMBER_LENGTH = &H10
        Private Const ATA_IDENTIFY_DATA_MICROCODE_REV_DATE_LENGTH = &HC
        Private Const ATA_IDENTIFY_DATA_RESERVED4_LENGTH = &HD6
    
        Private Const GUID_DEVINTERFACE_DISK As String = "53f56307-b6bf-11d0-94f2-00a0c91efb8b"
        Private Const DIGCF_DEFAULT = &H1
        Private Const DIGCF_PRESENT = &H2
        Private Const DIGCF_ALLCLASSES = &H4
        Private Const DIGCF_PROFILE = &H8
        Private Const DIGCF_DEVICEINTERFACE = &H10
    
        Private Const SPDRP_PHYSICAL_DEVICE_OBJECT_NAME = &HE
    
        Private Const GENERIC_READ = &H80000000UI
        Private Const GENERIC_WRITE = &H40000000UI
        Private Const GENERIC_EXECUTE = &H20000000UI
        Private Const GENERIC_ALL = &H10000000UI
    
        Private Const FILE_SHARE_READ = &H1
        Private Const FILE_SHARE_WRITE = &H2
    
        Private Const OPEN_EXISTING = &H3
        Private Const FILE_FLAG_NO_BUFFERING = &H20000000UI
    
        Private Const IOCTL_SCSI_PROTOCOL = &H0
        Private Const IOCTL_ATA_PROTOCOL = &H1
    
        Private Const DATA_IO_BUFFER_SIZE = &H20200
    
        Private Const IOCTL_SCSI_BASE = &H4
        Private Const IOCTL_FUNCTION_TYPE = &H40C
        Private Const METHOD_BUFFERED = &H0
        Private Const FILE_READ_ACCESS = &H1
        Private Const FILE_WRITE_ACCESS = &H2
    
        Private Const IOCTL_ATA_FLAGS_DRDY_REQUIRED = (1 << 0)
        Private Const IOCTL_ATA_FLAGS_DATA_IN = (1 << 1)
        Private Const IOCTL_ATA_FLAGS_DATA_OUT = (1 << 2)
    
        Private Const IOCTL_ATA_FEATURE_REG = &H0
        Private Const IOCTL_ATA_SECTOR_COUNT_REG = &H1
        Private Const IOCTL_ATA_SECTOR_NUMBER_REG = &H2
        Private Const IOCTL_ATA_CYLLOW_REG = &H3
        Private Const IOCTL_ATA_CYLHIGH_REG = &H4
        Private Const IOCTL_ATA_DRIVE_HEAD_REG = &H5
        Private Const IOCTL_ATA_COMMAND_REG = &H6
    
        Private Const ATA_IDENTIFY_DATA_FEATURE_REG_VAL = &H1
        Private Const ATA_IDENTIFY_DATA_SECTOR_COUNT_REG_VAL = &H1
    
        Private Const ATA_CMD_IDENTIFY_DATA = &HEC
    
    
        <StructLayout(LayoutKind.Sequential)> _
        Private Structure ATA_IDENTIFY_DATA_STRUCT
            Public GenConfig As UShort
            Public NumCyls As UShort
            Public Reserved As UShort
            Public NumHeads As UShort
            Public BytesPerTrack As UShort
            Public BytesPerSector As UShort
            Public SectorsPerTrack As UShort
            <MarshalAs(UnmanagedType.ByValArray, _
                       sizeconst:=ATA_IDENTIFY_DATA_VENDOR_UNIQUE_LENGTH)> _
            Public VendorUnique() As UShort
            <MarshalAs(UnmanagedType.ByValArray, _
                       sizeconst:=ATA_IDENTIFY_DATA_SERIAL_NUMBER_LENGTH)> _
            Public SerialNumber() As Char
            <MarshalAs(UnmanagedType.ByValArray, _
                       sizeconst:=ATA_IDENTIFY_DATA_LOT_CODE_LENGTH)> _
            Public LotCode() As Char
            Public BufferType As UShort
            Public BufferSize As UShort
            Public EccSize As UShort
            <MarshalAs(UnmanagedType.ByValArray, _
                       sizeconst:=ATA_IDENTIFY_DATA_FIRMWARE_REV_LENGTH)> _
            Public FirmwareRev() As Char
            <MarshalAs(UnmanagedType.ByValArray, _
                       sizeconst:=ATA_IDENTIFY_DATA_VENDOR_ID_LENGTH)> _
            Public VendorId() As Char
            Public MoreVendorUnique As UShort
            Public DoubleWordIo As UShort
            Public Capabilities As UShort
            Public Reserved1 As UShort
            Public PioTiming As UShort
            Public DmaTiming As UShort
            Public ValidFields As UShort
            Public NumCurrentCyls As UShort
            Public NumCurrentHeads As UShort
            Public NumCurrentSectorsPerTrack As UShort
            Public CurrentSectorCapacity As UInteger
            Public MultSectorStuff As UShort
            Public TotalAddressableSectors As UInteger
            Public SingleWordDma As UShort
            Public MultiWordDma As UShort
            <MarshalAs(UnmanagedType.ByValArray, _
                       sizeconst:=ATA_IDENTIFY_DATA_RESERVED2_LENGTH)> _
            Public Reserved2() As Byte
            Public UltraDmaModes As Byte
            Public UltraDmaActive As Byte
            <MarshalAs(UnmanagedType.ByValArray, _
                       sizeconst:=ATA_IDENTIFY_DATA_RESERVED3_LENGTH)> _
            Public Reserved3() As Byte
            <MarshalAs(UnmanagedType.ByValArray, _
                       sizeconst:=ATA_IDENTIFY_DATA_MODEL_NUMBER_LENGTH)> _
            Public ModelNumber() As Char
            <MarshalAs(UnmanagedType.ByValArray, _
                       sizeconst:=ATA_IDENTIFY_DATA_SUB_MODEL_NUMBER_LENGTH)> _
            Public SubModelNumber() As Char
            <MarshalAs(UnmanagedType.ByValArray, _
                       sizeconst:=ATA_IDENTIFY_DATA_MICROCODE_REV_DATE_LENGTH)> _
            Public MicrocodeRevisionDate() As Char
            <MarshalAs(UnmanagedType.ByValArray, _
                       sizeconst:=ATA_IDENTIFY_DATA_RESERVED4_LENGTH)> _
            Public Reserved4() As Byte
        End Structure
    
        <StructLayout(LayoutKind.Sequential)> _
        Private Structure DISK_INFO_STRUCT
            Public AtaDiskInfo As ATA_IDENTIFY_DATA_STRUCT
        End Structure
    
        <StructLayout(LayoutKind.Sequential)> _
        Private Structure FILE_OBJECT_STRUCT
            Public DeviceHandle As IntPtr
            Public DiskProtocol As UInteger
        End Structure
    
        <StructLayout(LayoutKind.Sequential)> _
        Public Structure SP_DEVINFO_DATA
            Public CbSize As UInt32
            Public ClassGuid As Guid
            Public DevInst As UInt32
            Public Reserved As UInt32
        End Structure
    
        <StructLayout(LayoutKind.Sequential)> _
        Public Structure SP_DEVICE_INTERFACE_DATA
            Public CbSize As UInt32
            Public InterfaceClassGuid As Guid
            Public Flags As UInt32
            Public Reserved As UIntPtr
        End Structure
    
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
        Public Structure SP_DEVICE_INTERFACE_DETAIL_DATA
            Public CbSize As UInt32
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=256)> _
            Public DevicePath As String
        End Structure
    
        <StructLayout(LayoutKind.Sequential)> _
        Public Structure ATA_PASS_THROUGH_DIRECT
            Public Length As UShort
            Public AtaFlags As UShort
            Public PathId As Byte
            Public TargetId As Byte
            Public Lun As Byte
            Public ReservedAsUchar As Byte
            Public DataTransferLength As UInteger
            Public TimeOutValue As UInteger
            Public ReservedAsUlong As UInteger
            Public DataBuffer As IntPtr
            <MarshalAs(UnmanagedType.ByValArray, sizeconst:=8)> _
            Public PreviousTaskFile() As Byte
            <MarshalAs(UnmanagedType.ByValArray, sizeconst:=8)> _
            Public CurrentTaskFile() As Byte
        End Structure
    
        <StructLayout(LayoutKind.Sequential)> _
        Public Structure ATA_PASS_THROUGH_DIRECT_WITH_BUFFER
            Public AptDirect As ATA_PASS_THROUGH_DIRECT
            <MarshalAs(UnmanagedType.ByValArray, sizeconst:=512)> _
            Public Data() As Byte
        End Structure
    
    
        Public Declare Auto Function SetupDiGetClassDevs Lib "setupapi.dll" ( _
            ByRef ClassGuid As Guid, _
            ByRef Enumerator As Char, _
            ByVal HwndParent As IntPtr, _
            ByVal Flags As UInteger) As IntPtr
    
        Public Declare Auto Function SetupDiGetClassDevs Lib "setupapi.dll" ( _
            ByRef ClassGuid As Guid, _
            ByVal Enumerator As IntPtr, _
            ByVal HwndParent As IntPtr, _
            ByVal Flags As UInteger) As IntPtr
    
        Public Declare Auto Function SetupDiEnumDeviceInterfaces Lib "setupapi.dll" ( _
            ByVal DeviceInfoSet As IntPtr, _
            ByRef DeviceInfoData As SP_DEVINFO_DATA, _
            ByRef InterfaceClassGuid As Guid, _
            ByVal MemberIndex As UInteger, _
            ByRef DeviceInterfaceData As SP_DEVICE_INTERFACE_DATA) As Boolean
    
        Public Declare Auto Function SetupDiEnumDeviceInterfaces Lib "setupapi.dll" ( _
            ByVal DeviceInfoSet As IntPtr, _
            ByVal DeviceInfoData As UInteger, _
            ByRef InterfaceClassGuid As Guid, _
            ByVal MemberIndex As UInteger, _
            ByRef DeviceInterfaceData As SP_DEVICE_INTERFACE_DATA) As Boolean
    
        Public Declare Auto Function SetupDiGetDeviceInterfaceDetail Lib "setupapi.dll" ( _
            ByVal DeviceInfoSet As IntPtr, _
            ByRef DeviceInterfaceData As SP_DEVICE_INTERFACE_DATA, _
            ByRef DeviceInterfaceDetailData As SP_DEVICE_INTERFACE_DETAIL_DATA, _
            ByVal DeviceInterfaceDetailDataSize As UInteger, _
            ByRef RequiredSize As UInteger, _
            ByRef DeviceInfoData As SP_DEVINFO_DATA) As Boolean
    
        Public Declare Auto Function SetupDiGetDeviceInterfaceDetail Lib "setupapi.dll" ( _
            ByVal DeviceInfoSet As IntPtr, _
            ByRef DeviceInterfaceData As SP_DEVICE_INTERFACE_DATA, _
            ByVal DeviceInterfaceDetailData As IntPtr, _
            ByVal DeviceInterfaceDetailDataSize As UInteger, _
            ByRef RequiredSize As UInteger, _
            ByVal DeviceInfoData As IntPtr) As Boolean
    
        Public Declare Auto Function SetupDiGetDeviceRegistryProperty Lib "setupapi.dll" ( _
            ByVal DeviceInfoSet As IntPtr, _
            ByRef DeviceInfoData As SP_DEVINFO_DATA, _
            ByVal [Property] As UInteger, _
            ByRef PropertyRegDataType As UInteger, _
            ByRef PropertyBuffer As Byte, _
            ByVal PropertyBufferSize As UInteger, _
            ByRef RequiredSize As UInteger) As Boolean
    
        Public Declare Auto Function SetupDiGetDeviceRegistryProperty Lib "setupapi.dll" ( _
            ByVal DeviceInfoSet As IntPtr, _
            ByRef DeviceInfoData As SP_DEVINFO_DATA, _
            ByVal [Property] As UInteger, _
            ByVal PropertyRegDataType As IntPtr, _
            ByVal PropertyBuffer As IntPtr, _
            ByVal PropertyBufferSize As UInteger, _
            ByRef RequiredSize As UInteger) As Boolean
    
        Public Declare Auto Function CreateFile Lib "kernel32.dll" ( _
            ByVal LpFileName As String, _
            ByVal DwDesiredAccess As UInteger, _
            ByVal DwShareMode As UInteger, _
            ByVal LpSecurityAttributes As IntPtr, _
            ByVal DwCreationDisposition As UInteger, _
            ByVal DwFlagsAndAttributes As UInteger, _
            ByVal HTemplateFile As IntPtr) As IntPtr
    
        Public Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal DevHandle As IntPtr) As Boolean
    
        Public Declare Auto Function DeviceIoControl Lib "kernel32.dll" ( _
            ByVal HDevice As IntPtr, _
            ByVal DwIoControlCode As UInteger, _
            ByVal LpInBuffer As IntPtr, _
            ByVal InBufferSize As UInteger, _
            ByVal LpOutBuffer As IntPtr, _
            ByVal OutBufferSize As UInteger, _
            ByRef LpBytesReturned As UInteger, _
            ByVal LpOverlapped As IntPtr) As Boolean
    
        Public Declare Auto Function DeviceIoControl Lib "kernel32.dll" ( _
            ByVal HDevice As IntPtr, _
            ByVal DwIoControlCode As UInteger, _
            ByRef LpInBuffer As ATA_PASS_THROUGH_DIRECT_WITH_BUFFER, _
            ByVal InBufferSize As UInteger, _
            ByRef LpOutBuffer As ATA_PASS_THROUGH_DIRECT_WITH_BUFFER, _
            ByVal OutBufferSize As UInteger, _
            ByRef LpBytesReturned As UInteger, _
            ByVal LpOverlapped As IntPtr) As Boolean
    
    
        Private Function Ata_Secu_Scan_Device_N_Identify(ByVal NumbDevice As UInteger) As UInteger
            Dim DevIdx As UInteger
            Dim RetStatus As UInteger
            Dim DiskInfo As New DISK_INFO_STRUCT
    
            'this is temporary for now... debugging...
            DevIdx = NumbDevice
    
            'allocate the Drive Information
            DiskInfo.AtaDiskInfo.VendorUnique = New UShort(ATA_IDENTIFY_DATA_VENDOR_UNIQUE_LENGTH) {}
            DiskInfo.AtaDiskInfo.SerialNumber = New Char(ATA_IDENTIFY_DATA_SERIAL_NUMBER_LENGTH) {}
            DiskInfo.AtaDiskInfo.LotCode = New Char(ATA_IDENTIFY_DATA_LOT_CODE_LENGTH) {}
            DiskInfo.AtaDiskInfo.FirmwareRev = New Char(ATA_IDENTIFY_DATA_FIRMWARE_REV_LENGTH) {}
            DiskInfo.AtaDiskInfo.VendorId = New Char(ATA_IDENTIFY_DATA_VENDOR_ID_LENGTH) {}
            DiskInfo.AtaDiskInfo.Reserved2 = New Byte(ATA_IDENTIFY_DATA_RESERVED2_LENGTH) {}
            DiskInfo.AtaDiskInfo.Reserved3 = New Byte(ATA_IDENTIFY_DATA_RESERVED3_LENGTH) {}
            DiskInfo.AtaDiskInfo.ModelNumber = New Char(ATA_IDENTIFY_DATA_MODEL_NUMBER_LENGTH) {}
            DiskInfo.AtaDiskInfo.SubModelNumber = New Char(ATA_IDENTIFY_DATA_SUB_MODEL_NUMBER_LENGTH) {}
            DiskInfo.AtaDiskInfo.MicrocodeRevisionDate = New Char(ATA_IDENTIFY_DATA_MICROCODE_REV_DATE_LENGTH) {}
            DiskInfo.AtaDiskInfo.Reserved4 = New Byte(ATA_IDENTIFY_DATA_RESERVED4_LENGTH) {}
    
            RetStatus = Ioctl_Scan_Device_N_Identify(DevIdx, DiskInfo)
            Ata_Secu_Scan_Device_N_Identify = 0
    
        End Function
    
        Private Function Ioctl_Scan_Device_N_Identify(ByVal DevIdx As UInteger, _
                                                      ByRef DiskInfo As DISK_INFO_STRUCT) As UInteger
            Dim RetStatus As UInteger
            Dim FileObject As New FILE_OBJECT_STRUCT
    
            RetStatus = Ioctl_Open_Disk_File(DevIdx, FileObject)
            RetStatus = Ioctl_Get_Disk_info(FileObject, DiskInfo)
            CloseHandle(FileObject.DeviceHandle)
            Ioctl_Scan_Device_N_Identify = 0
    
        End Function
    
        Private Function Ioctl_Open_Disk_File(ByVal DevIdx As UInteger, _
                                              ByRef FileObject As FILE_OBJECT_STRUCT) As UInteger
            Dim DevIntfcDtlResult As Boolean
            Dim DevRegPropResult As Boolean
            Dim BuffReqSize As UInteger
    
            Dim DiskGuid As Guid
            Dim DevInfoHdl As IntPtr
            Dim SPDevInfoData As SP_DEVINFO_DATA = New SP_DEVINFO_DATA
            Dim SPInterfaceData As SP_DEVICE_INTERFACE_DATA = New SP_DEVICE_INTERFACE_DATA
            Dim PSPInterfaceData As SP_DEVICE_INTERFACE_DETAIL_DATA = New SP_DEVICE_INTERFACE_DETAIL_DATA
    
    
            DiskGuid = New Guid(GUID_DEVINTERFACE_DISK)
            DevInfoHdl = SetupDiGetClassDevs(DiskGuid, IntPtr.Zero, IntPtr.Zero, _
                                             DIGCF_PRESENT Or DIGCF_DEVICEINTERFACE)
    
            If DevInfoHdl = INVALID_HANDLE_VALUE Then
                Ioctl_Open_Disk_File = 1
                Exit Function
            End If
    
            SPInterfaceData.CbSize = Marshal.SizeOf(SPInterfaceData)
            If SetupDiEnumDeviceInterfaces(DevInfoHdl, 0, DiskGuid, _
                                           DevIdx, SPInterfaceData) = False Then
                Ioctl_Open_Disk_File = 1
                Exit Function
            End If
    
            DevIntfcDtlResult = SetupDiGetDeviceInterfaceDetail(DevInfoHdl, SPInterfaceData, _
                                                                IntPtr.Zero, 0, BuffReqSize, IntPtr.Zero)
    
            SPDevInfoData.CbSize = Marshal.SizeOf(SPDevInfoData)
            PSPInterfaceData.CbSize = Marshal.SizeOf(PSPInterfaceData.CbSize) _
                                    + Marshal.SystemDefaultCharSize
    
            DevIntfcDtlResult = SetupDiGetDeviceInterfaceDetail(DevInfoHdl, SPInterfaceData, _
                                                                PSPInterfaceData, BuffReqSize, _
                                                                BuffReqSize, SPDevInfoData)
    
            If DevIntfcDtlResult = False Then
                Ioctl_Open_Disk_File = 1
                Exit Function
            End If
    
            BuffReqSize = 0
            DevRegPropResult = SetupDiGetDeviceRegistryProperty(DevInfoHdl, SPDevInfoData, _
                                                                SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, _
                                                                IntPtr.Zero, IntPtr.Zero, 0, BuffReqSize)
    
            FileObject.DeviceHandle = CreateFile(PSPInterfaceData.DevicePath, _
                                                 GENERIC_READ Or GENERIC_WRITE, _
                                                 FILE_SHARE_READ Or FILE_SHARE_WRITE, _
                                                 IntPtr.Zero, OPEN_EXISTING, _
                                                 FILE_FLAG_NO_BUFFERING, IntPtr.Zero)
    
            If FileObject.DeviceHandle = INVALID_HANDLE_VALUE Then
                Ioctl_Open_Disk_File = 1
                Exit Function
            End If
    
            If PSPInterfaceData.DevicePath.Contains("ide") Then
                FileObject.DiskProtocol = IOCTL_ATA_PROTOCOL
                Ioctl_Open_Disk_File = 0
            Else
                FileObject.DiskProtocol = IOCTL_SCSI_PROTOCOL
                Ioctl_Open_Disk_File = 1
            End If
    
        End Function
    
        Private Function Ioctl_Get_Disk_info(ByRef FileObject As FILE_OBJECT_STRUCT, _
                                             ByRef DiskInfo As DISK_INFO_STRUCT) As UInteger
            Dim AptDirect As ATA_PASS_THROUGH_DIRECT = New ATA_PASS_THROUGH_DIRECT
            Dim AptDirectWb As ATA_PASS_THROUGH_DIRECT_WITH_BUFFER = New ATA_PASS_THROUGH_DIRECT_WITH_BUFFER
    
            Dim IoCntlCode As UInteger
            Dim InBufferSize As UInteger
            Dim BytesReturned As UInteger
            Dim DevIoCtlResult As Boolean
    
            AptDirect.Length = Marshal.SizeOf(AptDirect)
            AptDirect.AtaFlags = IOCTL_ATA_FLAGS_DATA_IN Or IOCTL_ATA_FLAGS_DRDY_REQUIRED
            AptDirect.DataTransferLength = Marshal.SizeOf(GetType(ATA_IDENTIFY_DATA_STRUCT))
            AptDirect.TimeOutValue = 1
            AptDirect.DataBuffer = Marshal.OffsetOf(GetType(ATA_PASS_THROUGH_DIRECT_WITH_BUFFER), "Data")
    
            AptDirect.CurrentTaskFile = New Byte(7) {}
            AptDirect.CurrentTaskFile(IOCTL_ATA_FEATURE_REG) = ATA_IDENTIFY_DATA_FEATURE_REG_VAL
            AptDirect.CurrentTaskFile(IOCTL_ATA_SECTOR_COUNT_REG) = ATA_IDENTIFY_DATA_SECTOR_COUNT_REG_VAL
            AptDirect.CurrentTaskFile(IOCTL_ATA_COMMAND_REG) = ATA_CMD_IDENTIFY_DATA
    
            AptDirectWb.AptDirect = AptDirect
            InBufferSize = Marshal.SizeOf(GetType(ATA_PASS_THROUGH_DIRECT_WITH_BUFFER))
    
            IoCntlCode = Ioctl_Control_Code(IOCTL_SCSI_BASE, _
                                            IOCTL_FUNCTION_TYPE, _
                                            METHOD_BUFFERED, _
                                            FILE_READ_ACCESS Or FILE_WRITE_ACCESS)
    
            DevIoCtlResult = DeviceIoControl(FileObject.DeviceHandle, _
                                             IoCntlCode, _
                                             AptDirectWb, _
                                             InBufferSize, _
                                             AptDirectWb, _
                                             InBufferSize, _
                                             BytesReturned, _
                                             IntPtr.Zero)
    
            Ioctl_Get_Disk_info = 0
        End Function
    
        Private Function Ioctl_Control_Code(ByVal DeviceType As UInteger, _
                                            ByVal DevIoFunc As UInteger, _
                                            ByVal Method As UInteger, _
                                            ByVal Access As UInteger) As UInteger
    
            Ioctl_Control_Code = ((DeviceType) << 16) Or ((Access) << 14) Or ((DevIoFunc) << 2) Or (Method)
    
        End Function
    
        Sub Main()
            Call Ata_Secu_Scan_Device_N_Identify(0)
    
        End Sub
    
    End Module


    • Moved by Youen Zen Wednesday, June 12, 2013 6:43 AM From VB forum
    • Edited by rrb011270 Tuesday, June 18, 2013 1:36 AM
    Monday, June 10, 2013 11:31 PM

Answers

  • Hi,

    I already solved the issue with my code with error code=1450.

    Below are the snippet of the code I changed.

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

    Declaration

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

    I use the DeviceIoControl Declaration with the IntPtr type instead of the data structure type. See declaration below.

    Public Declare Auto Function DeviceIoControl Lib "kernel32.dll" ( _
            ByVal HDevice As IntPtr, _
            ByVal DwIoControlCode As UInteger, _
            ByVal LpInBuffer As IntPtr, _
            ByVal InBufferSize As UInteger, _
            ByVal LpOutBuffer As IntPtr, _
            ByVal OutBufferSize As UInteger, _
            ByRef LpBytesReturned As UInteger, _
            ByVal LpOverlapped As IntPtr) As Boolean

    Then the section of the code that uses this function was also modified as illustrated below.

    I change the code below:

    AptDirect.DataBuffer = Marshal.OffsetOf(GetType(ATA_PASS_THROUGH_DIRECT_WITH_BUFFER), "Data")
    

    to:

    Dim MyBuffer As IntPtr
    MyBuffer = Marshal.AllocHGlobal(512)
    AptDirect.DataBuffer = MyBuffer
    

    I don't know why it can't get the offset of the Data() from the declared ATA_PASS_THROUGH_DIRECT_WITH_BUFFER but now it is working.

    Next, I made some changes for the DeviceIoControl Parameters, illustrated below.

    Some code changes below:

    IoCntlCode = Ioctl_Control_Code(IOCTL_SCSI_BASE, _
                  IOCTL_FUNCTION_TYPE, _
                  METHOD_BUFFERED, _
                  FILE_READ_ACCESS Or FILE_WRITE_ACCESS)
    
    Dim AptWb As IntPtr = New IntPtr
    AptWb = Marshal.AllocHGlobal(Convert.ToInt32(InBufferSize))
    Marshal.StructureToPtr(AptDirect, AptWb, False)
    
    DevIoCtlResult = DeviceIoControl(FileObject.DeviceHandle, _
                                             IoCntlCode, _
                                             AptWb, _
                                             InBufferSize, _
                                             AptWb, _
                                             InBufferSize, _
                                             BytesReturned, _
                                             IntPtr.Zero)
    
    AptDirectWb = Marshal.PtrToStructure(AptWb, GetType(ATA_PASS_THROUGH_DIRECT_WITH_BUFFER))
    Marshal.FreeHGlobal(AptWb)
    
    Dim BuffOut(511) As Byte
    Marshal.Copy(MyBuffer, BuffOut, 0, 512)
    Marshal.FreeHGlobal(MyBuffer)
    

    With these changes, I can now send raw ATA packet commands. The code above sends the "identify device" which returned 512 bytes of data. With data parsing, you can be able to get the product IDs, firmware versions and other features supported by the target device like ATA security mode feature.

    Thanks to all.

    • Marked as answer by rrb011270 Tuesday, June 18, 2013 1:55 AM
    Tuesday, June 18, 2013 1:54 AM

All replies

  • Hi,

    We have a specific forum that discuss windows driver issue. In order to provide better support, I'll move this thread.

    Regards,


    Shanks Zen
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, June 12, 2013 6:43 AM
  • Are you running as admin AND elevated?

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Wednesday, June 12, 2013 7:06 AM
  • Thanks.
    Wednesday, June 12, 2013 11:09 PM
  • Yes I run devenv.exe as administrator.
    Wednesday, June 12, 2013 11:10 PM
  • Try running the app outside of the IDE as elevated, being admin is not enough

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    • Marked as answer by rrb011270 Thursday, June 13, 2013 8:58 AM
    • Unmarked as answer by rrb011270 Sunday, June 16, 2013 10:51 PM
    Thursday, June 13, 2013 6:15 AM
  • When you say "elevated", does this mean that I have to open a command prompt thru right-click then choose run as administrator?

    From there, run the executable.

    Thursday, June 13, 2013 7:05 AM
  • After compiling the code, the generated exe properties were modified under compatibility tab then I checked the "run as administrator".

    I open an elevated "command prompt" and run the exe from there. Unfortunately, I still get the same results. It is still not successful.

    I tried this on both release and debug compilation.

    Thursday, June 13, 2013 8:57 AM
  • Hi,

    I already solved the issue with my code with error code=1450.

    Below are the snippet of the code I changed.

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

    Declaration

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

    I use the DeviceIoControl Declaration with the IntPtr type instead of the data structure type. See declaration below.

    Public Declare Auto Function DeviceIoControl Lib "kernel32.dll" ( _
            ByVal HDevice As IntPtr, _
            ByVal DwIoControlCode As UInteger, _
            ByVal LpInBuffer As IntPtr, _
            ByVal InBufferSize As UInteger, _
            ByVal LpOutBuffer As IntPtr, _
            ByVal OutBufferSize As UInteger, _
            ByRef LpBytesReturned As UInteger, _
            ByVal LpOverlapped As IntPtr) As Boolean

    Then the section of the code that uses this function was also modified as illustrated below.

    I change the code below:

    AptDirect.DataBuffer = Marshal.OffsetOf(GetType(ATA_PASS_THROUGH_DIRECT_WITH_BUFFER), "Data")
    

    to:

    Dim MyBuffer As IntPtr
    MyBuffer = Marshal.AllocHGlobal(512)
    AptDirect.DataBuffer = MyBuffer
    

    I don't know why it can't get the offset of the Data() from the declared ATA_PASS_THROUGH_DIRECT_WITH_BUFFER but now it is working.

    Next, I made some changes for the DeviceIoControl Parameters, illustrated below.

    Some code changes below:

    IoCntlCode = Ioctl_Control_Code(IOCTL_SCSI_BASE, _
                  IOCTL_FUNCTION_TYPE, _
                  METHOD_BUFFERED, _
                  FILE_READ_ACCESS Or FILE_WRITE_ACCESS)
    
    Dim AptWb As IntPtr = New IntPtr
    AptWb = Marshal.AllocHGlobal(Convert.ToInt32(InBufferSize))
    Marshal.StructureToPtr(AptDirect, AptWb, False)
    
    DevIoCtlResult = DeviceIoControl(FileObject.DeviceHandle, _
                                             IoCntlCode, _
                                             AptWb, _
                                             InBufferSize, _
                                             AptWb, _
                                             InBufferSize, _
                                             BytesReturned, _
                                             IntPtr.Zero)
    
    AptDirectWb = Marshal.PtrToStructure(AptWb, GetType(ATA_PASS_THROUGH_DIRECT_WITH_BUFFER))
    Marshal.FreeHGlobal(AptWb)
    
    Dim BuffOut(511) As Byte
    Marshal.Copy(MyBuffer, BuffOut, 0, 512)
    Marshal.FreeHGlobal(MyBuffer)
    

    With these changes, I can now send raw ATA packet commands. The code above sends the "identify device" which returned 512 bytes of data. With data parsing, you can be able to get the product IDs, firmware versions and other features supported by the target device like ATA security mode feature.

    Thanks to all.

    • Marked as answer by rrb011270 Tuesday, June 18, 2013 1:55 AM
    Tuesday, June 18, 2013 1:54 AM