Windows File System filter driver development tutorial (2)

Source: Internet
Author: User
Windows File System filter driver development tutorial 2. Hello world, driver object and device object

The driver object mentioned here is a data structure named driver_object in DDK. Any driverProgramThey all correspond to a driver_object. How can I get the driver_object corresponding to the driver I wrote? The driver entry function is DriverEntry. Therefore, when you write a driver, you will write the followingCode:

Ntstatus DriverEntry (in pdriver_object driverobject, in punicode_string registrypath)
{
}

This function is quite likeC LanguageThe main (). In that you commonly use is a meaningless macro. It only indicates that the following parameter is an input, and the corresponding out parameter indicates that this parameter is a return. Reference is not used here, so if you want to return results in the parameter, all input pointers.

Driverobject is the driver_object corresponding to the driver you wrote. It is allocated when the system loads your driver. Registerypath is the Registry path used to record Driver-related parameters.

Driverobject has a set of function pointers called dispatch functions.

The main task of development driver is to write these dispatch functions by yourself. When the system uses your driver, it will send IRP to your do (this is the way all windows drivers work together ). Your task is to process these requests in the dispatch function. You can make the IRP fail, return it successfully, modify the IRPs, or even issue the IRPs by yourself.

The device object refers to device_object. Do.

But in fact, Each IRP is sent to do. Only the IRP of the DO generated by the driver,
Will be sent to the driver for processing.

When an application opens a file and reads and writes a file, the Windows system converts these requests into IRPs and sends them to the file system driver.

The file system filter driver can filter these IRPs. In this way, you have the ability to capture and change file system operations.

File Systems (FS) such as FAT32 and NTFS may generate several devices. First, the file system driver itself often generates a control device (CDO). The main task of this device is to modify the internal configuration of the entire driver. Therefore, a driver only corresponds to one CDO.

Another device is the volume mounted by the file system. One FS may have multiple volume volumes, or none of them. To explain, if you have four partitions: C:, D:, E:, F. C:, D: Is NTFS, E:, F: Is fat32. then C:, D: Is the two volume device objects of fat.

In fact, "C:" Is the Symbolic Link name of the device. Instead of the real device name. You can open the symbolic links viewer and you can see:

C: \ device \ harddiskvolume1

Therefore, the device name is \ device \ harddiskvolume1 ".

It can also be seen that the file system driver generates a deviceobject for each volume, rather than for each file. In fact, the IRPs for reading and writing files are all sent to the volume device object. It does not generate a "file device object ".

Having mastered these concepts, we now use simple code to generate our CDO, which is the first step for us to develop a file system driver.

I don't like Microsoft-style code. It's too long and ugly. I have redefined most data structures and functions. For this reason, I wrote a header file named WDF. h to help me convert the file. Interested readers can send an email to ask for this file. It doesn't matter. I always write the prototype of the wd_xxx series in the DDK.

// ----------------- Content in wdf_filter.c -------------------------

# Include "WDF. H"

Wd_stat wdff_cdo_create (in wd_drv * driver,
In wd_size exten_len,
In wd_ustr * Name,
Out wd_dev ** device)
{
Return wd_dev_create (
Driver,
Exten_len,
Name,
Wd_dev_disk_fs,
Wdf_dev_secure_open,
Wd_false,
Device );
}

Wd_stat wd_main (in wd_drv * driver,
In wd_ustr * reg_path)
{
Wd_ustr name;
Wd_stat status = wd_stat_suc;

// Then I generate a control device, although my control device does nothing
Wd_ustr_init (& name, l "\ FileSystem \ filters \ our_fs_filter ");
Status = wdff_cdo_create (driver, 0, & name, & g_cdo );

If (! Wd_suc (Status ))
{
If (status = wd_stat_path_not_found)
{
// This occurs when the \ FileSystem \ filters path does not exist. This path is
// Added on XP. So it will run here in 2000
Wd_ustr_init (& name, l "\ FileSystem \ our_fs_filter ");
Status = wdff_cdo_create (driver, 0, & name, & g_cdo );
};
If (! Wd_suc (Status ))
{
Wd_printf0 ("error: create CDO failed. \ r \ n ");
Return status;
}
}

Wd_printf0 ("success: create cdo OK. \ r \ n ");
Return status;
}

To make the Code look like the above, I have to make a lot of conversions. For example

# Define DriverEntry wd_main

It's a good feeling that you can finally work in a function that looks more like main. The function wd_dev_create internally calls iocreatedevice. While wd_suc is actually a macro like success.

// ---------------------- Content in WDF. h ------------------------------
# Include "ntifs. H"

# Define in
# Define out
# Define optional
# Define wd_ustr unicode_string
# Define wdp_ustr punicode_string
# Define wd_main DriverEntry

// Device and driver object type
Typedef driver_object wd_drv;
Typedef device_object wd_dev;
Typedef driver_object wd_pdrv;
Typedef pdevice_object wd_pdev;

Enum {
Wd_dev_disk_fs = file_device_disk_file_system,
Wd_dev_cdrom_fs = file_device_cd_rom_file_system,
Wd_dev_network_fs = file_device_network_file_system
};

// Status-related types and macros
Typedef ntstatus wd_stat;

Enum {
Wd_stat_suc = STATUS_SUCCESS,
Wd_stat_path_not_found = status_object_path_not_found,
Wd_stat_insufficient_res = status_insufficient_resources,
Wd_stat_invalid_dev_req = status_invalid_device_request,
Wd_stat_no_such_dev = status_no_such_device,
Wd_stat_image_already_loaded = status_image_already_loaded,
Wd_stat_more_processing = status_more_processing_required,
Wd_stat_pending = status_pending
};

_ Inline wd_bool wd_suc (wd_stat state)
{
Return nt_success (State );
}

# Define wd_printf0 dbuplint

_ Inline wd_void wd_ustr_init (in out wd_ustr * STR,
In const wd_wchar * chars)
{
Rtlinitunicodestring (STR, chars );
};

_ Inline wd_void wd_ustr_init_em (
In out wd_ustr * STR,
In wd_wchar * chars,
In wd_size size)
{
Rtlinitemptyunicodestring (STR, chars, size );
};

In the WDF. h file, I only extract the required parts. You have a simple "driver" complete code. It can even be compiled and installed. (modify the sfilter. inf file. The method is to change multiple sfilters to "our_fs_filter". I hope you will not encounter any problems during this process ). Then place WDF. h and wdf_filter.c in your new directory, which should contain two other files. One is makefile. Copy it from the sfilter directory. The other is sources. Enter the following content:
Targetname = our_fs_filter
Targetpath = OBJ
Targettype = driver
Drivertype = FS
Browser_info = 1
Sources = wdf_filter.c

After compiling with DDK, you will get our_fs_filter.sys. Install this file in the same directory as the INF file described above.

This driver does not play any role, but you have successfully completed "Hello World ".

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.