views:

95

answers:

3

I'm working in a sort of encapsulation of the windows filesystem.

When the user request to open a file, windows calls to my driver to provide the data. In normal operation the driver return the file contents which is cached, However, in some cases the real file is not cached and I need to download it from the network.

The question is if it's possible to keep Windows trying to read the file without blocking the entire drive operation neither the software which open the file, giving the user a chance to cancel the opening process.

At first, i tried to block the driver until data is available, this solution is the more straightforward to implement, but the user experiencie isn't the best. Moreover, relying in network transfer isn't a good idea, the transfer could last for many time and the driver will be block all that time.

The second way I have implemented, consist in return only data when the file is cached and when the file isn't available tell windows that the file is 0 size length, and download the file in a background proccess. With this, the driver don't block windows, and the user experience improve, but the user need to open N times the file until data is available.

I think that the best solution will be to return windows a message like "No data available, try again in 5 secs", i think that if the driver return the apropiate error code to windows this could be achieved, but the error list is too long and the names aren't always as descriptive as you want.

Do you have some advice implementing this? Thanks in advance.

A: 

you could spawn a thread that tries again and again, reporting the result on success or timeout.

Tobias Langner
A: 

To me showing a message "No data available, try again in 5 secs" sounds very bad, but it depends on your senario ( You could perhaps elaborate on what your and goal is).

Regarding getting data from the network, this sounds like a prime example of where threading comes into play. Have you considered copying the file in a worker thread? That way you dont have to block anything, and the user does not feel like the system is hanging

EKS
I didn't mean to show that message to the user, there was only a way to ilustrate the behavior of the driver. What i want is to ask windows to retry querying for the data.Is clear, that the solution involve to create a thread, but the purpose is to left the app that read the file waiting till the data is available but always letting the user cancel the process.Thanks for answering :)
HyLian
+3  A: 

The behavior you implement is correct for a driver. The responsibility for handling slow I/O lies at a higher level. For instance, Windows Explorer is very careful in NOT trying to retrieve even a single byte from any file, relying purely on metadata.

However, do not return a failure code when you're busy. It's that failure which would force users to repeatedly open a file.

MSalters
So, the correct implementation of a driver is to return the bytes readed whether you have something to read or not?In Some apps like Windows image viewer, if you return them 0 bytes readed, they stop retrying it, no error shown but you need to reopen the file. Thanks for answering :)
HyLian
I'm not sure at which level you're trying to operate now. You're dealing with IRP's right? That's an entirely different layer then the Win32 API.
MSalters
You're right, i'm not implementing directly the driver, i'm using Dokan ( http://dokan-dev.net/en/ ), but yes I have to respond to IRP_MJ_READ, and diving into Dokan source code, what it is really returning when i have no data to return is STATUS_END_OF_FILE.
HyLian
Can't blame an application for interpreting that as "End of file" really. Seems you might want to submit another question explicitly addressing Dokan.
MSalters
you still could add some kind of timeout option, so the user of your driver can decide how long he wants to wait for the file to open. If it takes to long, you can return a timeout error.
Tobias Langner
And to clarify: it seems that you should return STATUS_PENDING instead of tying up the CPU or failing the read.
MSalters