2010-09-20 53 views
0

我正在使用CreateFile,WriteFile和ReadFile API调用将一些数据写入USB设备。我的代码在32位系统上完美工作。 CreateFile获取设备句柄,将该句柄和一些数据传递给WriteFile,并使用ReadFile从该句柄中读取数据。WriteFile()调用适用于x86,但不适用于x64。获取错误代码6 - 该句柄无效使用VB.NET

我的问题是,相同的代码不适用于64位系统。从WriteFile返回的错误是6,句柄无效。我在CreateFile调用中检查了句柄的有效性,它是一个有效的句柄。 GetLastError()的调用在CreateFile之后返回0。正在为重叠通信打开“文件”,并且重叠的初始化调用也返回它们的适当值。

我的问题:我需要做一些不同的考虑,因为它是一个64位系统?另一面旗帜?完全不同的电话?我只是做了一些破解代码以使其同步(取出OVERLAPPED),它的工作,所以我假设问题是在我的OVERLAPPED结构或我的方式, m初始化电话。

任何帮助,非常感谢。

编辑:

下面是我的API签名,我用我的OVERLAPPED实施

Private Declare Auto Function CreateFile Lib "kernel32.dll" _ 
            (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 


Private Declare Auto Function WriteFile Lib "kernel32.dll" _ 
            (ByVal hFile As IntPtr, ByVal Buffer As Byte(), _ 
            ByVal nNumberOfBytesToWrite As Integer, _ 
            ByRef lpNumberOfBytesWritten As Integer, _ 
            ByRef lpOverlapped As OVERLAPPED) As Boolean 

Private Declare Auto Function ReadFile Lib "kernel32.dll" _ 
            (ByVal hFile As IntPtr, _ 
            ByVal Buffer As Byte(), _ 
            ByVal nNumberOfBytesToRead As Integer, _ 
            ByRef lpNumberOfBytesRead As Integer, _ 
            ByRef lpOverlapped As OVERLAPPED) As Boolean 

Private Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal hFile As IntPtr) As Boolean 

Private Declare Auto Function CancelIo Lib "kernel32.dll" (ByVal hObject As IntPtr) As Boolean 

Private Declare Auto Function GetOverlappedResult Lib "kernel32.dll" (_ 
            ByVal hFile As IntPtr, ByRef lpOverlapped As OVERLAPPED, _ 
            ByRef lpNumberOfBytesTransferred As Integer, _ 
            ByVal bWait As Boolean) As Boolean 

Private Declare Auto Function CreateEvent Lib "kernel32.dll" (_ 
            ByVal lpEventAttributes As Integer, ByVal bManualReset As Boolean, _ 
            ByVal bInitialState As Boolean, _ 
            <MarshalAs(UnmanagedType.LPStr)> ByVal lpName As String) As IntPtr 

Private Declare Auto Function WaitForSingleObject Lib "kernel32.dll" (_ 
            ByVal hHandle As IntPtr, ByVal dwMilliseconds As Integer) As Integer 

下面的代码是写,在问题发生时的代码。应当指出的是,在读取,重叠结构的hEvent参数以同样的方式

Try 

     With IOStructure 
      .overlap.hEvent = CreateEvent(Nothing, True, False, Nothing) 
      If .overlap.hEvent = 0 Then 
       writeSuccess = False 
      Else 
       writeSuccess = WriteFile(.hdevice, .writeBuf, .writeBuf.Length, .bytesWritten, .overlap) 

       'If the write didn't succeed, check to see if it's pending 
       If Not writeSuccess Then 

        If Err.LastDllError <> ERROR_IO_PENDING Then 'The write failed 
         writeSuccess = False 
        Else ' Write is pending 

         Select Case WaitForSingleObject(.overlap.hEvent, .timeout * 0.1) 'Wait for the write to complete 

          Case 0 'The write completed, check the overlapped structure for the signalled event. 
           writeSuccess = GetOverlappedResult(.hdevice, .overlap, .bytesWritten, 0) 
          Case Else 
           writeSuccess = False 
         End Select 
        End If 

       End If 
      End If 
      CloseHandle(.overlap.hEvent) 
     End With 
     ' Thread.Sleep(IOStructure.timeout * 0.3) 
     ' End While 
    Catch 
     writeSuccess = False 
    End Try 
+1

有没有机会看到你的代码? – 2010-09-20 16:06:55

+0

我刚刚使用相关代码编辑了我的帖子。 – Brandon 2010-09-20 18:19:50

+1

不要对BOOL类型使用布尔值。 Int32 BOOL是32位值,使用int或Int32。对于具有字符串参数的所有函数,明确定义MarshalAs并相应地使用A或W后缀 - 仅仅是为了安全。显示OVERLAPPED结构的PInvoke定义。 – 2010-09-21 10:04:40

回答

1

我有同样的问题初始化......我发现,当我明确地归零的重叠结构无效的处理错误消失:

Dim ovl As OVERLAPPED 
static ovlRead As IntPtr = Nothing 

' Marshal (allocate unmanaged) structure only once 
If IsNothing(ovlRead) then 
    ovlRead = Marshal.AllocHGlobal(Marshal.SizeOf(ovl)) 

    Marshal.WriteInt32(ovlRead, 0, 0) 
    Marshal.WriteInt32(ovlRead, 4, 0) 
    Marshal.WriteInt32(ovlRead, 8, 0) 
    Marshal.WriteInt32(ovlRead, 12, 0) 
    Marshal.WriteInt32(ovlRead, 16, 0) 
End If 

祝你好运。

1

我有完全相同的问题。同样的症状。我固定它通过

  1. 在程序启动时,我首先打开我清除I/O缓冲器
  2. 我然后写使用的WriteFile将其初始化一个0×00(空)字到该端口本身的端口。

和BINGO它的工作原理。自那以后没有问题。

相关问题