Что заставляет WriteFile возвращать ERROR_ACCESS_DENIED? - PullRequest
7 голосов
/ 30 ноября 2010

В настоящее время мы сталкиваемся с проблемой вызова WriteFile (или, скорее, CFile :: Write - но это просто вызывает WriteFile внутри), что вызывает ошибку Win32 5 ERROR_ACCESS_DENIED.

(EDIT: Обратите внимание, что мы не можем воспроизвести поведение. Все, что у нас есть на данный момент, - это файл журнала, указывающий исходную строку, где находился CFile :: Write, и содержащий ошибку ERROR_ACCESS_DENIED!)

(РЕДАКТИРОВАТЬ: файлна локальном диске, и это фактически файл, а не каталог.)

Теперь, Документация WriteFiles на самом деле не помогает, и экспериментирует с простымtest-app выдает следующие результаты:

  1. WriteFile вызовет причину ERROR_ACCESS_DENIED, если оно вызывается для дескриптора файла, который не открыт для записи (то есть открыт только для чтения).
  2. Это будет не вызвать ERROR_ACCESS_DENIED, если
    • Дескриптор недопустим или файл не открыт вообще
    • Права доступа или защита от записиd флаг для файла изменен после файл был открыт процессом.(Если они были изменены за до открытия файла, то мы никогда не попадем в WriteFile, потому что открытие файла завершится неудачей.)
    • Файл каким-то образом заблокирован другим процессом / дескриптором (это приведет кв лучшем случае ошибка 32 ERROR_SHARING_VIOLATION).

Это оставляет нас в ситуации, которая, по-видимому, единственная возможность для этого вызова потерпеть неудачу, если файл действительно был открыт сфлаг чтения вместо флага записи.Однако, глядя на наш код, это кажется крайне маловероятным.(Из-за нашей трассировки мы можем быть уверены, что WriteFile не удалось, а мы можем быть уверены, что ошибка ERROR_ACCESS_DENIED, мы не можем быть на 100,1% уверены воткрывающие флаги, потому что они не прослеживаются.)

Существуют ли другие известные обстоятельства, когда WriteFile (CFile :: Write) может вызвать ERROR_ACCESS_DENIED?

Примечание :Чтобы дополнительно уточнить контекст этого вопроса:

  • Файл был открыт , поэтому он не может быть каталогом или чем-то таким
  • Все выполненные тесты указываютчто, пока файл открыт, его нельзя удалить, поэтому файл должен все еще быть там при вызове WriteFile
  • Файл расположен на локальном диске, а не на сетевом диске.

Я должен добавить, что мы работаем на WIndows XP sp3 и приложение скомпилировано с Visual Studio 2005.

Ответы [ 4 ]

4 голосов
/ 04 апреля 2011

Вопрос был

Что заставляет WriteFile возвращать ERROR_ACCESS_DENIED?

, и я указал в вопросе

  1. WriteFileвызовет ERROR_ACCESS_DENIED, если он вызывается для дескриптора файла, который не открыт для записи (то есть открыт только для чтения).

После добавления дополнительной регистрации для флагов открытия и другого инцидента,оказывается, это было правильно.Регистрация для открытых флагов показывает, что в точке ошибки объект файла был открыт с помощью CFile :: modeRead, и поэтому мы получили ERROR_ACCESS_DENIED.

Пока не выяснили, какой странный путь кода приводит к этому,но это показывает, что вы никогда не доверяете своему собственному коду.: -)

(Да, и между прочим, это был не ::WriteFile, который потерпел неудачу, но API ::FlushFileBuffers, но, очевидно, который возвращает ту же ошибку.)

1 голос
/ 30 ноября 2010

Может быть, это: http://support.microsoft.com/kb/842792?

1 голос
/ 30 ноября 2010

Существует около десятка различных ситуаций, которые могут привести к ERROR_ACCESS_DENIED.Внутренне все, что делает WriteFile, вызывает NtWriteFile и отображает его (несколько значимый) код ошибки NTSTATUS в менее значимый HRESULT.

Среди прочего, ERROR_ACCESS_DENIED может указывать на то, что файл находится на сетевом томе и что-то не так с разрешениями на запись, или что файл действительно является не файлом, а каталогом.

0 голосов
/ 30 ноября 2010

если вы можете отладить его, вы должны.это может быть миллион вещей:

  • msdn неправильно (это часто случается)
  • какое-то приложение (вирус?) перехватывает WriteFile и вызывает другое поведение
  • проблема с файловой системой?
  • что-то не так в вашей записи или наблюдениях
...