2 votes

ReadFile winapi échoue lors de la lecture du dossier partagé de la boîte virtuelle. GetLastError génère l'erreur 183

J'appelle la fonction winapi ReadFile pour lire des données dans le dossier partagé de virtualbox. ReadFile échoue. GetLastError envoie le code d'erreur 183 'Cannot create a file when that file already exists'. Cela arrive parfois sur les dossiers partagés vmware.

Mon exemple de code

bool ret = ReadFile(hFile, buf, size, &bytesRead, nullptr);
if (ret == FALSE)
{
    logger << L"err: " + ToString(GetLastError());
}

//out:
//err: 183

Quelqu'un peut-il m'aider à résoudre cette étrange erreur ?

-1voto

Michael Kohne Points 8233

Tout d'abord, votre extrait de code est un peu... bancal. ReadFile renvoie un BOOL (un type défini par Microsoft qui existait à l'époque où le langage C n'avait pas encore de "bool"). Vous l'assignez ensuite à un bool de style C, puis vous comparez ce bool à la constante MS "FALSE". Tel qu'il est écrit, ce n'est PAS faux, mais c'est une mauvaise idée de passer inutilement d'une forme de booléen à l'autre, car cela tend à rendre plus difficile la compréhension du sens réel du test.

Deuxièmement, je soupçonne que ce code n'est PAS exactement le code qui échoue !

Je dis cela parce que je PEUX produire le comportement décrit en inversant simplement le sens du test sur le fichier ReadFile. C'est-à-dire que si vous vérifiez GetLastError lorsque ReadFile renvoie true, il donnera (sur ma machine, aujourd'hui, lors de la lecture d'un port série) l'erreur 183 ! Je soupçonne donc que, dans le code réel, l'OP a en quelque sorte manqué le test booléen (comme je l'ai fait plus tôt dans la journée), provoquant ainsi l'apparente fausse erreur de ReadFile.

Ma solution consiste à réécrire le test pour qu'il soit aussi simple que possible, en utilisant le moins de formes booléennes possible, afin d'avoir les meilleures chances de ne pas rater le test.

Si vous modifiez le code comme suit (en supposant que vous n'avez pas besoin de la valeur de retour de ReadFile ailleurs) :

if (!ReadFile(hFile, buf, size, &bytesRead, nullptr))
{
    DWORD err = GetLastError();
    logger << L"err: " + ToString(err);
}

Ce code permet de voir facilement le sens du test en question et réduit la possibilité d'écrire le test de manière erronée.

Si vous avez vraiment besoin de garder le "ret", faites-le :

BOOL ret = ReadFile(hFile, buf, size, &bytesRead, nullptr);
if (!ret)
{
    DWORD err = GetLastError();
    logger << L"err: " + ToString(err);
}

Dans les deux cas, vous noterez que j'ai extrait l'appel GetLastError de la ligne de journal. C'est pour s'assurer que rien ne peut se produire entre l'appel à ReadFile et l'appel à GetLastError.

EDIT : Révisé pour clarifier mes opinions. La version originale n'indiquait pas que je pensais que l'OP avait posté un code différent de celui qui était défaillant.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X