Windows File System filter driver development tutorial (6)

Source: Internet
Author: User
Windows File System filter driver development tutorial 6. Transmission of IRP, file system control dispatch

Now we have to start writing dispatch functions because your device has been bound to the file system control device. Windows sends a file system request to your driver. If you cannot handle it properly, your system will crash.

The simplest way to handle this is to transfer requests to the device we are bound without any change. How to obtain the device we are bound? This device has been recorded in our device extensions in the previous section.

// ------------ I use this function to quickly obtain the device I have bound -----------
// Get the bound Device
_ Inline wd_dev * my_dev_attached (wd_dev * Dev)
{
Return (wdff_dev_ext *) wd_dev_ext (Dev)-> attached_to;
}

How do I transmit requests? When iocalldriver is used, the first parameter of this call is the device object pointer, and the second parameter is the IRP pointer.

An IRP has a set of io_stack_location. As mentioned earlier, IRP is transmitted in a device stack. Io_stack_location corresponds to the device stack. This parameter is used to save some parameters of an IRP request in the current device stack. If I want to transmit the request to the next device, I should copy the current io_statck_location to the next device.

I have written some functions to handle io_stack_location, and wd_irp_call is used to wrap the iocalldriver function.

// --------------------- Content in WDF. h ----------------------------
Typdef wd_irpsp pio_stack_locaion;

_ Inline wd_irpsp * wd_cur_io_stack (wd_irp * IRP)
{
Return iogetcurrentirpstacklocation (IRP );
}

_ Inline wd_void wd_skip_io_stack (wd_pirirp)
{
Ioskipcurrentirpstacklocation (IRP );
}

_ Inline wd_void wd_copy_io_stack (wd_irp * IRP)
{
Iocopycurrentirpstacklocationtonext (IRP );
}

_ Inline wd_stat wd_irp_call (wd_dev * Dev, wd_piririrp)
{
Return iocalldriver (Dev, IRP );
}

With the above, I can now write a default dispatch functions.

// The default process is very simple. Ignore the current call stack and send it directly to the bound device.
Wd_stat my_disp_default (in wd_dev * Dev, in wd_pirirp)
{
Wd_dev * attached_dev;
If (! Is_my_dev (Dev ))
Return wd_irp_failed (IRP, wd_stat_invalid_dev_req );
If (is_my_cdo (Dev ))
Return wd_irp_failed (IRP, wd_stat_invalid_dev_req );
Attached_dev = my_dev_attached (Dev );
If (! Attached_dev)
Return wd_irp_failed (IRP, wd_stat_invalid_dev_req );
Wd_skip_io_stack (IRP );
Return wd_irp_call (attached_dev, IRP );
}

The above function is_my_dev is used to determine whether the device is my device. This process is simple. Run Dev to get the driverobject pointer and check whether the driver is my own. Is_my_cdo () is used to determine whether the device is my control device. Do not forget that we first generate a control device with this driver in wd_main. The actual control device does not do anything, so any request to it is illegal. An error is returned. The wd_irp_failed function immediately causes an IRP failure. The content is as follows:

// This function can immediately fail an IRP.
_ Inline wd_stat wd_irp_failed (wd_piririrp, wd_stat status_error)
{
IRP-> iostatus. Status = status_error;
IRP-> iostatus. Information = 0;
Return wd_irp_over (IRP );
}

In this way, an invalid error request is immediately returned without changing the IRP sent to my driver. However, this situation rarely happens.

If you want your driver to run immediately, make all dispacth functions call my_disp_default. This driver can be bound to the control device of the file system and output some debugging information. But it is not bound to volume. Therefore, it cannot directly monitor file read/write.

For a device bound to a file system control device, other requests can be directly called by default. Note that the dispatch processing function my_disp_file_sys_ctl () is mounted to irp_mj_file_system_control ().

Irp_mj_file_system_control is the main function number of IRP. A function number is generally used under each primary function number. These two items indicate an IRP function.

The primary function number and secondary function number are the first two bytes of io_stack_location.

// ---------------- The feature number I have redefined -------------------
Enum {
Wd_irp_mn_mount = irp_mn_mount_volume,
Wd_irp_mn_load_filesys = irp_mn_load_file_system,
Wd_irp_mn_user_req = irp_mn_user_fs_request
};
Enum {
Wdf_fsctl_dismount = fsctl_dismount_volume
};

To obtain the function number, you must first obtain the current io_stack_location, which has the wd_cur_io_stack function above. I believe this will not affect you.

When volumne is mounted or dismount, my_disp_file_sys_ctl () is called. For specific judgment methods, see the followingCodeNow:

// You can see that other functions in the distribution function are easy to process, but the file_sys_ctl
// Processing is complicated. We have bound the file system driver control to the policy function.
// Create an object. When the file system obtains the actual media, a new device object is generated,
// This kind of device is called volume (volume), and this kind of device is generated in mount in file_sys
// And unmount. After this operation is captured
// Our device object must be generated and bound to such a volume before binding to this volume
// File operations.
Wd_stat my_disp_file_sys_ctl (in wd_dev * Dev, in wd_piririrp)
{
Wd_dev * attached_dev;
Wd_io_stack * stack = wd_cur_io_stack (IRP );
If (! Is_my_dev (Dev ))
Return wd_irp_failed (IRP, wd_stat_invalid_dev_req );
Switch (wd_irpsp_minor (stack ))
{
Case wd_irp_mn_mount:
// Here, a volume is being mounted
Return my_fsctl_mount (Dev, IRP );
Case wd_irp_mn_load_filesys:
Return my_fsctl_load_fs (Dev, IRP );
Case wd_irp_mn_user_req:
{
Switch (wd_irpsp_fs_ctl_code (stack ))
{
Case wdf_fsctl_dismount:
// Here, a volume is dismount
Return my_fsctl_dismount (Dev, IRP );
}
}
}
Wd_skip_io_stack (IRP );
Attached_dev = my_dev_attached (Dev );
Return wd_irp_call (attached_dev, IRP );
}

You have to write two new functions, my_fsctl_mount () and my_fsctl_dismount (), to process the mount and dismount of the volume. obviously, you should generate a device or delete, bind, or unbind it. Soon, you will be able to fully monitor all the volumes.

This is the perfect solution to dynamically monitor all volumes.

If it is in XP or above, a call can be made to obtain the mounted volume on a file system. But it cannot be used in 2000. So we didn't use that method. What's more, just getting the mounted volume is not what I want.

There is also a my_fsctl_load_fs function. Occurs in irp_mn_load_filesys. I only want to explain this function code A LITTLE BIT: When a file identification tool (see the above) decides to load a real file system, it will generate such an IRP.

Now you can modify your driver so that debugging information is output during volume loading and uninstallation when the USB flash drive is inserted and pulled out. Let's look back at our context:

A. Generate a control device. You must specify a name for the control settings.

B. Set dispatch functions.

C. set fast Io functions.

D. Compile a my_fs_notify callback function to bind the activated fs cdo.

E. Use wdff_reg_notify to call the registration callback function.

F. Compile the default dispatch functions.

E. Process irp_mj_file_system_control and monitor the mount and dismount of volumne.

F. The next step is to bind volumne. Please try again.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.