2010-11-30 4 views
7

Nous sommes actuellement confrontés au problème d'un appel à WriteFile (ou, plutôt CFile :: Write - mais qui appelle simplement WriteFile en interne) provoquant l'erreur Win32 5ERROR_ACCESS_DENIED.Qu'est-ce qui fait que WriteFile renvoie ERROR_ACCESS_DENIED?

(EDIT:.! Notez que nous ne pouvons pas repro le comportement Tout ce que nous avons à l'heure actuelle est un fichier journal indiquant la ligne de source où le CFile :: Write a été et contenant comme erreur ERROR_ACCESS_DENIED)

(EDIT : Le fichier est sur un locale lecteur et il est en fait un fichier et non un répertoire)

maintenant, WriteFiles's documentation ne vous aide pas vraiment, et d'expérimenter avec une simple application de test donne les résultats suivants:.

  1. WriteFile va cause ERROR_ACCESS_DENIED si elle est appelée pour un handle de fichier qui n'est pas ouvert pour l'écriture (ie. est ouvert pour la lecture seulement).
  2. Il ne pas la cause ERROR_ACCESS_DENIED si
    • La poignée est pas valide ou le fichier n'est pas ouvert du tout
    • L'accès droits, ou le drapeau protégé d'écriture pour le fichier sont modifiés après le fichier a été ouvert par le processus. (Si ceux-ci sont modifiés avant le fichier est ouvert, nous jamais à WriteFile, car l'ouverture du fichier échouera.)
    • Le fichier est verrouillé en quelque sorte par un autre processus/poignée (Ce sera au meilleur résultat dans l'erreur 32 ERROR_SHARING_VIOLATION).

Cela nous laisse la situation, qui semble la seule possibilité pour cet appel à l'échec si le fichier a été effectivement ouvert avec le drapeau de lecture au lieu du drapeau d'écriture. Cependant, en regardant notre code, cela semble extrêmement improbable. (En raison de notre suivi, nous pouvons être sûrs que WriteFile a échoué et nous peut être sûr que l'erreur est ERROR_ACCESS_DENIED, nous ne pouvons pas être 100,1% sûr des drapeaux d'ouverture, car ceux-ci ne sont pas tracées.)

Y a-t-il d'autres circonstances connues où WriteFile (CFile :: Write) provoquerait un ERROR_ACCESS_DENIED?

Remarque: Pour clarifier plus le contexte de cette question:

  • Le fichier a été ouvert , donc il ne peut pas être un répertoire ou somesuch
  • Tous les tests indiquent que j'effectués en le fichier est ouvert il ne peut pas être supprimé, donc le fichier doit toujours avoir été sur l'appel à WriteFile
  • Le fichier se trouve sur un lecteur local et non sur un lecteur réseau.

Je dois ajouter que nous courons sur si vous pouvez le déboguer, et Windows XP SP3 l'application est compilé avec Visual Studio 2005.

+1

pourquoi ne pouvez-vous tracer les drapeaux d'ouverture? Si vous ne voulez pas modifier le code, utilisez simplement le moniteur de processus pour les inspecter. –

+0

Bien sûr, nous pouvons ajouter le traçage. Cela arrive seulement de temps en temps sur un site client. Il n'y a aucun moyen que nous serons en mesure d'ajouter un débogueur là. –

+1

Les pilotes de filtre de système de fichiers peuvent également causer cela, l'exemple le plus évident étant les scanners anti-virus (bien qu'il existe d'autres tels que le cryptage, etc.). – Luke

Répondre

3

La question était

Quelles sont les causes WriteFile retourner ERROR_ACCESS_DENIED?

et je l'ai dit dans la question

  1. WriteFile fera ERROR_ACCESS_DENIED si elle est appelée pour une poignée de fichier non ouvert pour l'écriture (ie est ouvert pour lecture seulement) .

Après avoir ajouté l'enregistrement supplémentaire pour les drapeaux ouverts et un autre incident, il se trouve que c'était correct. La journalisation des drapeaux ouverts montre qu'au moment de l'erreur, l'objet fichier a été ouvert avec CFile :: modeRead et que nous avons donc ERROR_ACCESS_DENIED.

N'a pas encore découvert quel chemin de code bizarre mène à cela, mais cela va juste montrer: Ne faites jamais confiance à votre propre code. :-)

(Oh, et BTW. Ce ne ::WriteFile qui a échoué, mais l'API ::FlushFileBuffers, mais apparemment qui retourne la même erreur.)

+0

Si cela répondait à votre propre question, veuillez le marquer comme tel. – RedX

+0

@RedX: Merci. Je ne l'ai pas fait immédiatement parce que je pensais que les réponses personnelles étaient bloquées pendant un certain temps. Cela semble s'appliquer à l'âge de la question et non à la réponse. –

0

vous devriez. il pourrait être un million de choses:

  • msdn est mauvais (il arrive beaucoup)
  • une application (virus?) hooking WriteFile et causer différents problèmes du système de fichiers comportement
  • ?
  • quelque chose de mal dans votre exploitation forestière, ou observations
+2

À mon humble avis, cela aurait dû être un commentaire.Le débogage du problème n'est pas possible pour le moment. –

1

Il existe environ une dizaine de situations différentes pouvant entraîner ERROR_ACCESS_DENIED. En interne, tout WriteFile fait appel NtWriteFile et mapper son code d'erreur NTSTATUS (quelque peu significatif) dans un HRESULT moins significatif. ERROR_ACCESS_DENIED peut, entre autres choses, indiquer que le fichier est sur un volume réseau et que quelque chose s'est mal passé avec les permissions d'écriture, ou que le fichier n'est vraiment pas un fichier mais un répertoire.

+0

Le fichier n'est pas sur un réseau volumje et c'est en fait un fichier. –