Tanveer, I'm sorry, but porting to VB doesn't change anything: I don't think the DllImportAttribute or GC was your problem. You still use "Long" (64 bit) all over the place, although "Integer" (32 bit) and "IntPtr" (processor-specific) should be used.
What's that: Declare Unicode Function CreateFile Lib "kernel32" Alias "CreateFileA" You are declaring a function to be Unicode, but use the ANSI version? This declaration works: Public Declare Unicode Function CreateFile Lib "kernel32" Alias "CreateFileW" ( _ ByVal lpFileName As String, ByVal dwDesiredAccess As Integer, ByVal dwShareMode As Integer, _ ByVal lpSecurityAttributes As IntPtr, ByVal dwCreationDisposition As Integer, _ ByVal dwFlagsAndAttributes As Integer, ByVal hTemplateFile As IntPtr) As IntPtr When you use it, you write: CreateFile("\\\\.\\Scsi0:", ...). Now this is wrong in VB, since VB does not use \ as a meta-character. Write "\\.\Scsi0" instead (I believe it mustn't have a trailing :, but I am not sure about that). When you had CreateFile ... As Long, it returned &HFFFFFFFF as a return value, which corresponds to -1 in 32 bits (signed). In 64 bits, however, it means 4294967295; so when you compared it with -1, the comparison yielded that they were different (although they weren't). Use an IntPtr instead (as in the above declaration). Also, to know what has gone wrong, in your else branch (if hFile is -1), throw a Win32Exception, so you can see what went wrong. Then you declare a buffer: Dim buffer() As Byte, ReDim buffer(560). Just Dim buffer(560) As Byte, which gets the same result. And if you make it (560), the array will be from 0..560, i.e. 561 bytes long. Make it Dim buffer(559) As Byte instead. For x = 0 To 559 buffer(x) = CType(0, Byte) End For This isn't needed, arrays are 0-initialized automatically. (Why casting 0 to Byte anyway?) I also don't think that the 42 lines of array initialization are nice, but I won't change that now. Let's go to DeviceIoControl. I would declare it as follows: Public Declare Ansi Function DeviceIoControl Lib "kernel32" ( _ ByVal hDevice As IntPtr, 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 IntPtr) As Boolean Now, I am not sure if you are allowed to pass the same pointer as InBuffer and OutBuffer, but I assume you know what you are doing, so let's keep that. The call now looks like this: Dim success As Boolean = _ DeviceIoControl(hFile, 315400, sb, 63, sb, 560, outBufferLength, IntPtr.Zero) At the end of this message, I have appended the whole source code again. Alas, I don't have a SCSI disk, so I can't really try it out. And, you know, VB.NET didn't buy you anything, I would've sticked with C# (the handle created by CreateFile is never GCed by .NET). Hope this helps Fabian Code: Imports System Imports System.Text Imports System.Runtime.InteropServices Imports System.ComponentModel Module VBHDD Public Class clsHDD Public Const GENERIC_READ As Integer = &H80000000 Public Const GENERIC_WRITE As Integer = &H40000000 Public Const FILE_SHARE_READ As Integer = &H1 Public Const FILE_SHARE_WRITE As Integer = &H2 Public Const OPEN_EXISTING As Integer = 3 Public Declare Unicode Function CreateFile Lib "kernel32" Alias "CreateFileW" ( _ ByVal lpFileName As String, ByVal dwDesiredAccess As Integer, ByVal dwShareMode As Integer, _ ByVal lpSecurityAttributes As IntPtr, ByVal dwCreationDisposition As Integer, _ ByVal dwFlagsAndAttributes As Integer, ByVal hTemplateFile As IntPtr) As IntPtr Public Declare Unicode Function CloseHandle Lib "kernel32" Alias "CloseHandle" ( _ ByVal hObject As IntPtr) As Boolean Public Declare Ansi Function DeviceIoControl Lib "kernel32" ( _ ByVal hDevice As IntPtr, 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 IntPtr) As Boolean Public Shared Function SCSI() As Long Dim hFile As IntPtr = CreateFile("\\.\Scsi0", GENERIC_READ Or GENERIC_WRITE, _ FILE_SHARE_READ Or FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero) Console.WriteLine("File Pointer ...{0}", hFile) If (hFile.ToInt32() = -1) Then Throw New Win32Exception Else Dim buffer(559) As Byte Dim x As Integer = 0 buffer(x) = CType(28, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 buffer(x) = CType(83, Byte) : x += 1 buffer(x) = CType(67, Byte) : x += 1 buffer(x) = CType(83, Byte) : x += 1 buffer(x) = CType(73, Byte) : x += 1 buffer(x) = CType(68, Byte) : x += 1 buffer(x) = CType(73, Byte) : x += 1 buffer(x) = CType(83, Byte) : x += 1 buffer(x) = CType(75, Byte) : x += 1 'Timeout buffer(x) = CType(16, Byte) : x += 1 buffer(x) = CType(39, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 'Control Code buffer(x) = CType(1, Byte) : x += 1 buffer(x) = CType(5, Byte) : x += 1 buffer(x) = CType(27, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 buffer(x) = CType(20, Byte) : x += 1 buffer(x) = CType(2, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 buffer(x) = CType(&HEC, Byte) : x += 1 buffer(x) = CType(0, Byte) : x += 1 For x = 0 To 63 Console.Write("{0}", Chr(buffer(x))) Next Dim sb As IntPtr = Marshal.AllocCoTaskMem(560) Marshal.Copy(buffer, 0, sb, 560) Dim outBufferLength As Integer = 0 Dim success As Boolean = _ DeviceIoControl(hFile, 315400, sb, 63, sb, 560, outBufferLength, IntPtr.Zero) If (success) Then Console.WriteLine("Passed ") Console.WriteLine("Returned sb: {0}", Marshal.PtrToStringAnsi(sb, outBufferLength)) Else Throw New Win32Exception Console.WriteLine("Failed outBufferLength: {0}", outBufferLength) Console.WriteLine("Input: {0}", Marshal.PtrToStringAnsi(sb, 560)) Console.ReadLine() End If Marshal.FreeHGlobal(sb) End If Return CloseHandle(hFile) End Function End Class Public Sub Main() Console.WriteLine("Exit Code ...{0}", clsHDD.SCSI) Console.ReadLine() End Sub End Module ----- Original Message ----- From: "Tanveer" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Wednesday, September 03, 2003 7:06 AM Subject: Re: [ADVANCED-DOTNET] Interop with DeviceIoControl > Dear Fabian, > > I have converted this to VB.NET and removed the DllImport attribute...this > seems to solve the GC-ed pointer problem...but still the return buffer is > not as desired. > > The complete code is: > > >>>>>>>>>>>>>>>>>>>>>>>>>>>>> > [...] see http://discuss.develop.com/archives/wa.exe?A2=ind0308e&L=advanced-dotnet&T=0&F=&S=&P=1797 > >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> > > Any ideas...? > > -Tanveer =================================== This list is hosted by DevelopMentorŪ http://www.develop.com NEW! ASP.NET courses you may be interested in: 2 Days of ASP.NET, 29 Sept 2003, in Redmond http://www.develop.com/courses/2daspdotnet Guerrilla ASP.NET, 13 Oct 2003, in Boston http://www.develop.com/courses/gaspdotnet View archives and manage your subscription(s) at http://discuss.develop.com