Jump to content











Photo
- - - - -

Redirecting block requests to Imdisk

imdisk

  • Please log in to reply
3 replies to this topic

#1 Reshama

Reshama
  • Members
  • 2 posts
  •  
    United States

Posted 06 April 2015 - 06:08 AM

First of all I would like to thank the excellent authors of Imdisk for a job well done. This is a very useful tool.

 

However, I am stuck with a particular problem and was hoping the folks in this group could help.

 

Here is the issue. I am writing a filter layer on top of a regular disk class driver. This filter driver (sitting below NTFS FS driver and above the disk class storage driver) has to redirect certain block requests to a remote block storage server. To realize this, I am using Imdisk to fetch the blocks from the remote server using 'devio' in the other end. The Imdisk drive is mapped to a local drive letter 'R:' and is also available at "\Device\ImDisk0".

 

Here is the issue I am facing:

 

I need this to be functional even when the system boots - so at some stage in the boot when all the relevant drivers are loaded (my filter driver, storage class driver, tcp/ip driver and imdisk) I need to have this mechanism functional. That is, any read request that hits my filter driver has to be redirected not to the underlying local storage but to the remote storage provided by Imdisk. I need this to work _only_ for read requests and for certain blocks that is determined by my filter driver as being remotely available.

 

I tried opening the Imdisk device from my filter driver's start function using the path "\Device\ImDisk0" (ZwFileOpen) but the call fails because ImDisk gets loaded later on in the boot process and even if it gets loaded the drive letter will not be mapped till the 'imdisk' command line is invoked. 

 

I already set the starttype to '0' (to indicate that it is a boot start driver) in the INF file. But not sure how to hardcode the ability to map the drive and create the path "\Device\ImDisk0" when the driver loads.

 

So in essence, is there a way to load ImDisk early in the boot process and hardcode the mapping of the drive letter to the remote block server so that when my filter driver loads the path "\Device\ImDisk0" is already available and functional? 

 

Also is there a way to ensure that Imdisk loads before my filter driver?

 

Thanks much.



#2 Olof Lagerkvist

Olof Lagerkvist

    Gold Member

  • Developer
  • 1448 posts
  • Location:Borås, Sweden
  •  
    Sweden

Posted 06 April 2015 - 12:13 PM

Interesting project.

First of all, some basic settings for ImDisk are possible to configure directly in the registry so that the driver reads them and initiate a virtual disk directly during system startup. Then, using the sc.exe tool (or directly in the registry) you could specify dependencies such that ImDisk driver loads before other drivers you need for this solution. Also, if you don't use a filesystem at the remote device but rather use it as a "raw" device where you simply read and write at specific byte offsets, it would be better for you to add a flag to the ImDisk device that cause the driver to create the device as FILE_DEVICE_UNKNOWN instead of FILE_DEVICE_DISK. This will avoid the need for filesystem drivers to mount a filesystem on the device before you can use it from your own driver and that could be important in early stage of system startup. Otherwise, needed filesystem drivers could need disk drivers which are of course not fully initialized before your filter driver loads.

Additionally, you should really avoid using drive letters in early stages of system startup. Use full native paths such as \Device\ImDisk0 and similar, never \??\R: or anything like that.

But then, there is a problem with this entire approach that makes it impossible anyway for this particular scenario. The problem is that in order to connect to a remote computer using TCP/IP, the driver needs to communicate with a user mode service, ImDskSvc ("helper service"), that makes the actual connection. Of course a user mode service cannot load as early in the boot process as you would need in this case.

#3 Reshama

Reshama
  • Members
  • 2 posts
  •  
    United States

Posted 07 April 2015 - 04:04 AM

Thanks for the prompt reply Olof. This is very helpful.

 

I'll follow your suggestions. 

 

a) I'll try to create the registry entries to hardcode the creation of the drive when the ImDisk driver gets loaded. Is there a writeup somewhere which I can use to learn the registry entries ImDisk expects to create the drive mapped to the remote server?  

 

B) I was trying to figure out if there is an easy way to change the load order of the drivers such that my driver loads after ImDisk loads, but I am unable to find a way to do in this case. It looks like minifilter drivers (sitting about the FS) have a 'load order' parameter in their INF file, but it is not clear if that mechanism would work for filter drivers sitting above disk class drivers. Do you know how to achieve this?

 

c) Alternately, even if my driver loads before Imdisk, is there a way for my driver to learn that the device "\Device\ImDisk0" is available at some future point when ImDisk loads and initializes? I would certainly prefer this latter method (than changing the load order) since then it would work which ever order the drivers get loaded.

 

BTW, good point about this entire scheme working only after the user space service is loaded. Of course, the sooner the entire thing starts working after the boot, the better it is for me, but I think I can live with this limitation.

 

Thanks much once again.



#4 Olof Lagerkvist

Olof Lagerkvist

    Gold Member

  • Developer
  • 1448 posts
  • Location:Borås, Sweden
  •  
    Sweden

Posted 07 April 2015 - 09:13 AM

Start, LoadOrder and Group parameters are practically not used for plug-and-play drivers. They are instead loaded along with registered filter drivers by plug-and-play manager as needed in their plug-and-play device dependency tree. The concept of Start, LoadOrder, Group and IoAttachDevice function are legacy features used in pre-plug-and-play version of Windows NT kernel. Nowadays filters are registered as UpperFilter or LowerFilter for a device class or device and then plug-and-play manager automatically loads them and call their AddDevice routine so that they can get their parameters from the device registry key and not the key for the specific driver and so that they can register to the device stack with IoAttachDeviceToDeviceStack instead.

There are however a few exceptions where the "legacy scheme" for driver load order is still used. This applies to the Start parameter that needs to be set to "boot" for drivers and filters in the storage stack that need to be loaded by system boot loader together with the kernel so that they are immediately available when system starts up. So, your filter needs sc config start= boot as well, even though it is a plug-and-play filter.

Then I would recommend you to set ImDisk driver to start= auto and set it to depend on ImDskSvc service. This way it will automatically load the helper service before itself and this will happen when user mode starts up, which is earliest possible in this case. There have been a few posts about the registry parameters in this forum so you could probably search for "LoadDevices" "registry" or similar in the forum search.

But to get everything right regarding the registry settings I would rather recommend you to use the -P command line switch:
imdisk -a -t proxy -o ip,raw -f 10.0.0.1:9000 -P
(Replace 10.0.0.1:9000 with your actual target ip and port.)

You can then see what is saved in the registry as parameters to do what that command line does at system startup. You should also only use the raw parameter to -o switch if you are really using the device as a raw device and therefore do not want a filesystem loaded on it. If you are working with files and directories on the ImDisk virtual disk you need a filesystem on it and therefore cannot use "raw".

Then, from your filter driver you could for example periodically probe for \Device\ImDisk0 until it is found. You could also find out if ImDisk driver has loaded but had been unable to load this device by checking if \Device\ImDiskCtl device exists but not \Device\ImDisk0 and if \Device\ImDiskCtl does not have the DO_DEVICE_INITIALIZING flag set (it is cleared when the driver has finished loading).





Also tagged with one or more of these keywords: imdisk

1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users