OSDev

для всех
Текущее время: 29 апр 2024, 01:33

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 7 ] 
Автор Сообщение
СообщениеДобавлено: 13 янв 2012, 16:34 
Аватара пользователя

Зарегистрирован: 14 мар 2011, 12:31
Сообщения: 970
Откуда: Дагоба
Осуществляю запись под Windows в устройство на низком уровне. Устройство открывается на запись в режиме FILE_SHARE_WRITE. Запись в загрузочный сектор происходит успешно, однако если диск в данный момент используется, то Windows при закрытии устройства сбрасывает в загрузочный сектор свою сохранённую копию этого сектора, перебивая тем самым мою запись (какого лешего??? я понимаю, может обновляется FSInfo, но зачем записывать бут??). Я хочу сделать блокировку устройства, - т.е. проверять, открыто ли устройство ОСью, и записывать сектор только в том случае, если Windows его в данный момент не использует, в противном случае выдавать сообщение о занятости и ничего не писать. Так вот не получается.
Открываю устройство:
HANDLE device = CreateFile ("\\\\.\\PhysicalDrive0", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, NULL);
пытаюсь ставить блокировку:
ok = LockFile (device, 0, 0, 512, 0);
получаю ошибку блокировки ВСЕГДА, если это устройство. Если это обычный файл, то блокировка работает нормально.
Мне же нужно поведение а-ля проверка диска под Windows, - пока с диска не ушли, диск не проверяется. Как только ушли и на диске нет ни одного открытого файла, проверка возможна.
Пытался использовать LockFileEx, - один хрен. Если убрать флаги FILE_SHARE_READ|FILE_SHARE_WRITE при открытии диска, ничего не меняется - диск открывается, как ни в чём ни бывало, и запись на диск происходит всегда, независимо от его занятости.

_________________
Yet Other Developer of Architecture.
The mistery of Yoda’s speech uncovered is:
Just an old Forth programmer Yoda was.

<<< OS Boot Tools. >>>


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 13 янв 2012, 17:52 
Аватара пользователя

Зарегистрирован: 16 май 2007, 23:46
Сообщения: 1126
Залочить можно файл. Устройство не залочишь. Но можно залочить все файлы.
А вообще я бы присмотрелся к технологии и апи дефрагментации.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 13 янв 2012, 17:57 

Зарегистрирован: 21 сен 2007, 17:24
Сообщения: 1088
Откуда: Балаково
Я честно говоря не встречал такой проблемы. Возможно потому, что у меня операции чтения и записи разделены, а у тебя открытие делается одновременно на чтение и запись. У меня работает так - сначала только чтение
HANDLE hDrive = CreateFile("\\\\.\\PhysicalDrive0", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
<чтение>
CloseHandle(hDrive);

потом только запись

hDrive = CreateFile("\\\\.\\PhysicalDrive0", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
<запись>
CloseHandle(hDrive);

Может провести верификацию записи? При расхождении делать несколько попыток, задействовав диалог с пользователем. При этом надо учитывать и изменившиеся данные сектора.

Возможно, мешает флаг FILE_FLAG_WRITE_THROUGH, нарушающий очерёдность (если она не соответствует системной политике), отсюда и коллизия.

Посмотри ещё справку на слово "FSCTL_LOCK_VOLUME"
вот пример
BOOL DeviceIoControl(
(HANDLE) hDevice, // handle to a volume
(DWORD) FSCTL_LOCK_VOLUME, // dwIoControlCode
NULL, // lpInBuffer
0, // nInBufferSize
NULL, // lpOutBuffer
0, // nOutBufferSize
(LPDWORD) lpBytesReturned, // number of bytes returned
(LPOVERLAPPED) lpOverlapped // OVERLAPPED structure
);
Правда, для системного диска она не работает. В общем нужны пляски с бубнами, залочить наверно не получится.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 15 янв 2012, 14:24 
Аватара пользователя

Зарегистрирован: 14 мар 2011, 12:31
Сообщения: 970
Откуда: Дагоба
Himik писал(а):
Может провести верификацию записи? При расхождении делать несколько попыток, задействовав диалог с пользователем. При этом надо учитывать и изменившиеся данные сектора.

Верификация ничего не даёт. Всё пишется правильно, как и должно. Если после записи вынуть флешку без "Безопасного извлечения устройства", то на ней остаются записанные именно мои данные. Но вот если перед этим сделать "безопасное...", то при закрытии устройства винда перезаписывает загрузочный сектор своими данными.

Himik писал(а):
Возможно, мешает флаг FILE_FLAG_WRITE_THROUGH, нарушающий очерёдность (если она не соответствует системной политике), отсюда и коллизия.

Не, этот флаг точно ни при чём. Проверялось. Кстати, коллизий с этим флагом быть не должно. Если в кэше до этого были другие данные в записываемой области, они нормально перезаписываются новыми и тут же всё сбрасывается на диск.

Himik писал(а):
Посмотри ещё справку на слово "FSCTL_LOCK_VOLUME"

Попробую копнуть в эту сторону.

Чё-то у мну проклёвывается мысль. Вероятно, с локом всё в порядке и лок даёт ошибку именно потому, что устройство действительно занято системой. А дисковые утилиты, видимо, связываются с каким-то сервисом и ПРОСЯТ освободить диск, т.е. закрыть его. После того, как они заканчивают работу, сообщают сервису о возможности повторного открытия диска. Соответственно, сервис может отказать в просьбе, и тогда (а не в момент лока) утилита сообщает о невозможности работы с ним. Кажется надо копать сюда.

_________________
Yet Other Developer of Architecture.
The mistery of Yoda’s speech uncovered is:
Just an old Forth programmer Yoda was.

<<< OS Boot Tools. >>>


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 15 янв 2012, 18:40 

Зарегистрирован: 21 сен 2007, 17:24
Сообщения: 1088
Откуда: Балаково
Yoda писал(а):
Himik писал(а):
Может провести верификацию записи? При расхождении делать несколько попыток, задействовав диалог с пользователем. При этом надо учитывать и изменившиеся данные сектора.

Верификация ничего не даёт. Всё пишется правильно, как и должно. Если после записи вынуть флешку без "Безопасного извлечения устройства", то на ней остаются записанные именно мои данные.

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

FSCTL_LOCK_VOLUME не работает только с диском на котором установлена Windows, а для флешки наверно сработает.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 17 янв 2012, 17:37 
Аватара пользователя

Зарегистрирован: 14 мар 2011, 12:31
Сообщения: 970
Откуда: Дагоба
Himik писал(а):
Что-то мне кажется, что проще это задокументировать как правильный вариант установки. Типа - это не баг, а фича.

Проще, но что-то в этом сильно неправильное.

Himik писал(а):
FSCTL_LOCK_VOLUME не работает только с диском на котором установлена Windows, а для флешки наверно сработает.

В общем раскопал ситуацию. Неприятность в том, что FSCTL_LOCK_VOLUME работает ТОЛЬКО для логических дисков. Для физических вызов всегда возвращает успешную блокировку, но нифига на самом деле не блокирует. И, похоже, это - фундаментальная [мерзкая] особенность виндофс. Разные дисковые утилиты ведут себя точно так же - если мы работаем с физическим устройством, то им пофигу, открыты файлы на них или нет... а вручную записанная в бут-сектор раздела инфа точно так же теряется при размонтировании этого раздела. Придётся 1. документировать эту ситуацию и 2. добавлять запись бута на логический раздел с полноценной блокировкой доступа.
Спасибо!

_________________
Yet Other Developer of Architecture.
The mistery of Yoda’s speech uncovered is:
Just an old Forth programmer Yoda was.

<<< OS Boot Tools. >>>


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 17 янв 2012, 21:09 

Зарегистрирован: 21 сен 2007, 17:24
Сообщения: 1088
Откуда: Балаково
Может это антивирус шалит?


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 7 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 24


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB