Проблема
Наша компания производит специализированные устройства под управлением Windows XP (если быть точнее, Windows XPe). Одно из несгибаемых юридических требований, с которыми мы сталкиваемся, заключается в том, что мы должны быстро определить, когда фиксированный IDE диск извлекается . Быстро, как в течение нескольких секунд.
Рассматриваемые диски являются дисками IDE. Они также защищены программным обеспечением от записи со слоем EWF (Enhanced Write Filter). Уровень EWF находится под файловой системой, защищая диск от записи. Если вы изменяете или записываете что-то на томе, защищенном EWF, реальные изменения происходят только на уровне памяти (но файловая система не знает об этом).
Проблема в том, что сама Windows, похоже, не замечает удаления фиксированного диска. Вы можете вытащить диск из машины, и Windows Explorer с удовольствием предоставит вам возможность просматривать каталоги и даже открывать файлы, если они все еще кэшируются в памяти. А благодаря слою EWF я даже могу записывать файлы на отсутствующий диск.
Мне нужно чистое программное решение. В идеале в C # /. Net 1.1, но у меня нет проблем с использованием pinvoke или C ++.
То, что я не могу сделать
- Нет, я не могу модернизировать тысячи устройств новым оборудованием.
- Нет, мы не можем просто использовать супер-клейкие диски для соответствия требованиям законодательства.
- Нет, нормальная запись / чтение файла не обнаружит ситуацию благодаря слою EWF.
- Нет, мы не можем отключить слой EWF.
- Нет, я не могу игнорировать юридические требования, даже если они глупые.
- Нет, я не могу обнаружить извлечение фиксированного диска, как для USB или другого съемного диска. Это фиксированные диски.
- Нет, я не могу использовать WMI (инструментарий управления Windows). Он не установлен на наших машинах.
- Нет, я не могу использовать версии .Net прошлых 1.1. Это не поместится на наших маленьких дисках. (Но если существует простое решение в более высокой версии .Net, я мог бы перенести его обратно на 1.1.)
Текущее неловкое решение
Я не доволен нашим текущим решением. Я ищу что-то более элегантное и эффективное.
То, что я сейчас делаю, включает в себя два потока.
Тема A опрашивает диск. Сначала он создает специальный файл на диске, используя Kernel32.dll:
Kernel32.CreateFile(
filename,
File_Access.GenericRead | File_Access.GenericWrite,
File_Share.Read | File_Share.Write,
IntPtr.Zero,
CreationDisposition.CreateAlways,
CreateFileFlagsAndAttributes.File_Attribute_Hidden | CreateFileFlagsAndAttributes.File_Attribute_System,
IntPtr.Zero);
Затем он опрашивает диск, вызывая
Kernel32.FlushFileBuffers(fileHandle);
Если диск был удален, то поток A будет зависать в течение long времени перед возвратом кода ошибки.
Тема B Тема опросов A.
Если поток B видит, что поток A заблокирован (некоторое время не обновлял специальную переменную), то поток B вызывает событие, когда диск был удален.
Мое текущее решение работает, но оно мне не нравится. Если кто-нибудь знает более чистое программное решение, я был бы признателен.