J'utilise les appels d'API CreateFile, WriteFile et ReadFile pour écrire des données sur un périphérique USB. Le code que j'ai fonctionne parfaitement sur les systèmes 32 bits. CreateFile obtient un handle sur le périphérique, transmet ce handle et des données à WriteFile et lit à partir de ce handle avec ReadFile.L'appel WriteFile() fonctionne sur x86, mais pas sur x64. Obtenir le code d'erreur 6 - Le handle n'est pas valide en utilisant VB.NET
Mon problème est, le même code ne fonctionne pas sur un système 64 bits. L'erreur renvoyée par WriteFile est 6, Le handle est invalide. J'ai vérifié la validité du handle sur l'appel CreateFile et c'est un handle valide. Un appel à GetLastError() renvoie 0 après CreateFile. Le "fichier" est en cours d'ouverture pour une communication avec chevauchement et les appels d'initialisation superposés retournent également leurs propres valeurs.
Ma question: est-ce qu'il y a une sorte de considération différente que je dois faire parce que c'est un système 64 bits? Un drapeau différent? Un appel différent? Juste pour noter, j'ai fait un peu un hack sur le code pour le rendre synchrone (a enlevé le OVERLAPPED) et cela a fonctionné, donc je suppose que le problème est dans ma structure OVERLAPPED ou la manière dont je suis m initialiser les appels.
Toute aide est grandement appréciée.
Edit:
Voici mes signatures API et le code que je me sers pour ma mise en œuvre CHEVAUCHEMENT
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
Ce qui suit est le code pour l'écriture, où le problème se produit. Il convient de noter que dans la lecture, le paramètre hEvent de structure OVERLAPPED est initialisé de la même façon
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
Une chance de voir votre code? –
Je viens d'éditer mon post avec le code correspondant. – Brandon
N'utilisez pas Boolean pour le type BOOL. Int32 BOOL est une valeur de 32 bits, utilise int ou Int32. Pour toutes les fonctions avec des paramètres de chaîne, définissez explicitement MarshalAs et utilisez postfix A ou W en conséquence - juste pour la sécurité. Afficher la définition PInvoke de la structure OVERLAPPED. –