Quickly detect removal of fixed IDE drive in Windows XP
The Problem
Our company make specialized devices running Windows XP (Windows XPe, to be precise). One of the unbending legal requirements we face is that we must quickly detect when a fixed IDE drive is removed. Quickly as in within a few seconds.
The drives in question are IDE drives. They are also software-protected from writes with an EWF (Enhanced Write Filter) layer. The EWF layer sits under the file system, protecting the disk from writes. If you change or write something on an EWF-protected volume, the actual changes happen only in a memory layer (but the file system isn't aware of that).
The problem is that Windows itself doesn't seem to notice fixed drive removal. You 开发者_高级运维can pull the drive out of the machine, and Windows Explorer will be happy to let you browse directories and even open files if they happen to still be cached in memory. And thanks to the EWF layer, I can even seem to write files to the missing drive.
I need a clean software-only solution. Ideally in C#/.Net 1.1, but I have no problem with using pinvoke or C++.
Things I can't do
- No, I can't retrofit thousands of devices with new hardware.
- No, we can't just super-glue drives in to meet legal requirements.
- No, a normal file write/read won't detect the situation, thanks to the EWF layer.
- No, we can't turn off the EWF layer.
- No, I can't ignore legal requirements, even if they are silly.
- No, I can't detect fixed drive removal the way I would for a USB or other removable drive. These are fixed drives.
- No, I can't use WMI (Windows Management Instrumentation). It isn't installed on our machines.
- No I can't use versions of .Net past 1.1. It won't fit on our small drives. (But if an easy solution exists in a higher version of .Net, I might be able to port it back to 1.1.)
Current awkward solution
I'm not happy with our current solution. I'm looking for something more elegant and efficient.
What I'm currently doing involves two threads.
Thread A polls the drive. It first creates a special file on the drive using 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);
Then it polls the drive by calling
Kernel32.FlushFileBuffers(fileHandle);
If the drive has been removed, then thread A will hang for a long time before returning an error code.
Thread B polls thread A.
If thread B sees that thread A has locked up (hasn't updated a special variable in a while), then thread B raises an event that the drive has been removed.
My current solution works, but I don't like it. If anyone knows a cleaner software-only solution, I would appreciate it.
I'm shocked and amazed that the system doesn't fall over dead if you yank out a fixed IDE drive. Like, really shocked. But, hey...
Are you sure can't just fix this with super glue? :)
First, the reason why Windows doesn't notice is because notification of device removal has to come from the bus driver. In this case, the IDE bus doesn't support what we call "surprise remove" so no one ever gets told that the disk is unplugged. I suspect that communications just start timing out, which is why your flush trick works.
Not sure if you're going to come up with any cleaner solution though. If you really, really need this and can restrict it to just a particular release of XP, someone might be able to analyze the drivers involved here and exploit a path that would give you a quicker result. But there's clearly nothing architected in Windows to deal with this and so that's like real work.
-scott
Have you looked in here:
http://msdn.microsoft.com/en-us/library/aa363217(VS.85).aspx
Looks like what you are looking for.
精彩评论