CreateFile() renvoie INVALID_HANDLE_VALUE mais GetLastError() est ERROR_SUCCESS
Je suis de l'ouverture d'un port série à l'aide CreateFile(). J'ai un cas de test (trop compliqué à redistribuer) qui est une source constante de CreateFile()
de retour INVALID_HANDLE_VALUE
et GetLastError()
de retour ERROR_SUCCESS
. Par les regards de lui, ce bug ne se produit que si un thread ouvre le port à l'exact même temps qu'un autre port il se ferme. Le fil de l'ouverture du port de la traverse de ce problème.
Je ne sais pas si cela fait une différence, mais plus tard dans le code, je l'ai associé le port avec un CompletionPort à l'aide de CreateIoCompletionPort.
Voici mon code:
HANDLE port = CreateFile(L"\\\\.\\COM1",
GENERIC_READ | GENERIC_WRITE,
0, //must be opened with exclusive-access
0, //default security attributes
OPEN_EXISTING, //must use OPEN_EXISTING
FILE_FLAG_OVERLAPPED, //overlapped I/O
0); //hTemplate must be NULL for comm devices
if (port == INVALID_HANDLE_VALUE)
{
DWORD errorCode = GetLastError();
cerr << L"CreateFile() failed with error: " << errorCode << endl;
}
Je suis sûr que ce genre de chose ne devrait pas arriver. Suis-je en train de faire quelque chose de mal? Comment puis-je obtenir de l'API pour retourner un résultat correct?
PLUS de DÉTAILS: Ce code est prise à partir d'un port série de la bibliothèque que j'ai développé: JPeripheral
Ici, c'est le réel (unsanitized) de code source:
JLong SerialChannel::nativeOpen(String name)
{
cerr << "nativeOpen(" << name << ")" << endl;
wstring nameWstring = name;
HANDLE port = CreateFile((L"\\\\.\\" + nameWstring).c_str(),
GENERIC_READ | GENERIC_WRITE,
0, //must be opened with exclusive-access
0, //default security attributes
OPEN_EXISTING, //must use OPEN_EXISTING
FILE_FLAG_OVERLAPPED, //overlapped I/O
0); //hTemplate must be NULL for comm devices
cerr << "nativeOpen.afterCreateFile(" << name << ")" << endl;
cerr << "port: " << port << ", errorCode: " << GetLastError() << endl;
if (port == INVALID_HANDLE_VALUE)
{
DWORD errorCode = GetLastError();
switch (errorCode)
{
case ERROR_FILE_NOT_FOUND:
throw PeripheralNotFoundException(jace::java_new<PeripheralNotFoundException>(name, Throwable()));
case ERROR_ACCESS_DENIED:
case ERROR_SHARING_VIOLATION:
throw PeripheralInUseException(jace::java_new<PeripheralInUseException>(name, Throwable()));
default:
{
throw IOException(jace::java_new<IOException>(L"CreateFile() failed with error: " +
getErrorMessage(GetLastError())));
}
}
}
//Associate the file handle with the existing completion port
HANDLE completionPort = CreateIoCompletionPort(port, ::jperipheral::worker->completionPort, Task::COMPLETION, 0);
if (completionPort==0)
{
throw AssertionError(jace::java_new<AssertionError>(L"CreateIoCompletionPort() failed with error: " +
getErrorMessage(GetLastError())));
}
cerr << "nativeOpen.afterCompletionPort(" << name << ")" << endl;
//Bind the native serial port to Java serial port
SerialPortContext* result = new SerialPortContext(port);
cerr << "nativeOpen.afterContext(" << name << ")" << endl;
return reinterpret_cast<intptr_t>(result);
}
Ici est la sortie réelle-je obtenir:
nativeOpen(COM1)
nativeOpen.afterCreateFile(COM1)
port: 00000374, errorCode: 0
nativeOpen.afterCompletionPort(COM1)
nativeOpen.afterContext(COM1)
[...]
nativeOpen(COM1)
nativeOpen.afterCreateFile(COM1)
port: FFFFFFFF, errorCode: 0
java.io.IOException: CreateFile() failed with error: The operation completed successfully.
Qu'est-ce que le matériel que vous avez accès?
Je suis d'accéder à un périphérique intégré, nous avons développé en interne. Il dispose d'une série DB9-port de connexion que j'ai connecté à mon PC (pas d'USB-RS232 adaptateurs ici).
J'ai posté le code-source complet pour votre examen.
Vous devez appeler
GetLastError
immédiatement après CreateFile
faliure, sans <<
entre les deux.
OriginalL'auteur Gili | 2011-10-05
Vous devez vous connecter pour publier un commentaire.
La sortie de eree appelle winapi appels sous le capot. Qui permet de réinitialiser le thread valeur d'erreur renvoyé par GetLastError(). Correctif:
cerr
instruction. J'ai seulement ajouté que récemment. Voyez-vous quelque chose de mal avec le code ci-dessus (moinscerr
)?La sortie de trace, tu as montré ne peut être généré par le code t gâcher la valeur de GetLastError. Je n'en doute pas, elle peut échouer, il existe de nombreuses raisons pour l'ouverture d'un port COM à l'échec.
Vous avez eu raison. Le code original invoqué
throw IOException(jace::java_new<IOException>(L"CreateFile() failed with error: " + getErrorMessage(GetLastError()))
. Remarquez comment beaucoup de code existe entre le point de défaillance et de la lecture deGetLastError()
. La lecture de la valeur plus rapidement résolu le problème. Merci!J'ai eu quelque chose de semblable arriver à moi, même si la seule chose entre CreateFile2 et GetLastError() a été "nouvelle wchar_t[messageLength]". C'était suffisant pour réinitialiser le message d'erreur renvoyé par GetLastError().
OriginalL'auteur Hans Passant