Ошибка WriteFile № 5 отказала в доступе под Win Vista/Seven

Я много гуглил, и я не мог найти ответа на эту проблему...

У меня есть консольное приложение C++, которое считывает SD-карту объемом 1 ГБ, исправляет неправильно закрытые файлы и соответственно записывает таблицу FAT. SD-карта прописывается в начале прошивки в кастомном аппарате. Он работал нормально до Xp и перестал работать в Win Vista/seven. Я попытался повысить привилегии: в учетной записи администратора я запустил окно cmd, используя метод «запуск от имени администратора», но безуспешно. Я также пробовал с манифестом, запрашивающим наивысшие доступные привилегии, но не повезло.

Я прочитал в каком-то посте, что «Windows Vista вообще не позволяет вам получать доступ к дискам из процессов пользовательского режима. Кто-нибудь знает о каком-либо способе обойти это поведение?

Я работаю над обходным путем, однако я хотел бы знать, невозможно ли это или нет

Изменить:

Это мой первый пост здесь, поэтому я не совсем понимаю проблему со ссылками... Но я вообще не отношусь к спаму... просто спрашиваю на сайте, управляемом сообществом :)

Код выглядит так

hDevice = CreateFile(buffer,GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,NULL, OPEN_EXISTING,0,NULL); 

Затем я читаю информацию BTB с SD и ищу неправильно закрытый файл.

Наконец при попытке записи на SD

WriteFile(hDevice,buffer,SD_SECTOR_SIZE, &temp, 0)

Я получаю отказ в доступе (ошибка № 5)

Строка в CreateFile() — это \.\g: поскольку буква g соответствует SD-карте на моей машине. Все это работает нормально, и, как я уже говорил, работает на XP. Я также пытался использовать: DeviceIoControl с FSCTL_LOCK_VOLUME, но это дает ошибку ошибки памяти.

Надеюсь, это поможет понять и спасибо за любую помощь


person andy    schedule 30.08.2010    source источник
comment
+1 за: работаю над обходным путем...   -  person Chubsdad    schedule 30.08.2010
comment
Должен быть способ получить доступ к необработанным файлам на диске из Vista / Seven - как еще утилиты для подготовки загрузочных USB-накопителей Linux могут установить свой загрузчик?   -  person bdonlan    schedule 30.08.2010
comment
@andy, не могли бы вы опубликовать пример кода, показывающий, что вы делаете, чтобы мы могли увидеть, что может быть не так?   -  person bdonlan    schedule 30.08.2010
comment
Энди, я объединил ваши учетные записи, так что теперь вы снова стали владельцем этого вопроса. Я также добавил дополнительную информацию, которую вы дали в ответ на свой вопрос.   -  person balpha    schedule 30.08.2010


Ответы (2)


Я думаю, это связано со строкой пути «буфер»; Я столкнулся с той же проблемой. Путь, который вы используете для доступа к устройству, должен выглядеть так: "\\.\PhysicalDrive%d" %d – десятичный номер диска.

Начиная с Vista в этой строке учитывается регистр. Проверьте правописание. Вам также нужны права администратора, как и раньше в XP.

Для томов. письмо должно быть ЗАГЛАВНЫМ, например. "\\.\Г:"

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

Кроме того: я забыл упомянуть, что буфер, в который вы читаете/записываете данные, должен быть выровнен по страницам, а чтение должно быть кратно размеру сектора. VirtualAlloc() делает это

person Dominik Weber    schedule 30.08.2010
comment
Спасибо Балфа за ваши правки! Спасибо Доминик за ваш ответ :) Я думаю, что синтаксис lpFileName в CreateFile всегда начинается с \\.\ как указано в msdn.microsoft.com/en-us/library/aa363858%28VS.85%29.aspx Кажется, что заглавная буква не помогает вообще в моем случае. Я также пробовал \\.\PhysicalDriveXX (XX равно 1 в моем случае), но позже ReadFile(hDevice,inf_buffer,SD_SECTOR_SIZE, &tmp,0); ничего не возвращает в inf_buffer, кроме пустого. Однако CreateFile вообще не жалуется. Этот последний тест выполняется при отладке на XP с помощью ms vc++6 (машина разработки) - person andy; 31.08.2010
comment
Спасибо, Энди. Путь, который я ввел, содержит две косые черты, но эта косая черта является escape-символом, так что на самом деле вам нужно ввести четыре, чтобы получить два. Я также вспомнил немного о выравнивании буфера. Если вы можете открыть файл, имя и разрешения верны, если чтение не удается, это размер/выравнивание буфера и/или блокировка. Я думаю, что блокировка более важна, когда вы хотите писать. - person Dominik Weber; 31.08.2010

Перед записью необработанных данных необходимо отключить том.

Из MSDN:

Запись в дескриптор тома будет выполнена успешно, если на томе нет смонтированной файловой системы или если выполняется одно из следующих условий:

  • Сектора для записи являются загрузочными секторами.
  • Сектора, которые должны быть записаны, находятся за пределами пространства файловой системы.
  • Вы явно заблокировали или размонтировали том с помощью FSCTL_LOCK_VOLUME или FSCTL_DISMOUNT_VOLUME.
  • Том не имеет фактической файловой системы. (Другими словами, у него смонтирована файловая система RAW.)

Запись на дескриптор диска будет успешной, если выполняется одно из следующих условий:

  • Сектора для записи не попадают в экстенты тома.
  • Сектора, которые нужно записать, попадают в смонтированный том, но вы явно заблокировали или размонтировали том с помощью FSCTL_LOCK_VOLUME или FSCTL_DISMOUNT_VOLUME.
  • Сектора, которые должны быть записаны, попадают в том, на котором нет смонтированной файловой системы, кроме RAW.

Пример кода:

BOOL bResult = DeviceIoControl(hDevice,                // device to be queried
                               FSCTL_DISMOUNT_VOLUME,  // operation to perform
                               NULL, 0,                // no input buffer
                               pdg, sizeof(*pdg),      // output buffer
                               &junk,                  // # of bytes returned
                               (LPOVERLAPPED)NULL);    // synchronous I/O
person Pierre    schedule 26.01.2012
comment
Всегда включайте в свой ответ ссылки на соответствующие статьи/документацию MSDN. - person Cody Gray; 26.01.2012