Create an IRP Query file in the filter driver

Source: Internet
Author: User

When developing a file system filter driver in windows, we often need to query the file attribute information first. To achieve this small goal, you can call the Windows native API function zwqueryinformationfile and provide the name and structure of the file information class to be queried. However, if we process the information query request in the driver, we can avoid the problem of re-entry.

1. query IRP by creating a file by yourself

Ntstatus
Queryfileinformation (
Pdevice_object deviceobject,
Pfile_object fileobject,
File_information_class fileinformationclass,
Pvoid fileinfo,
Ulong fileinfolength
)
{
Pirp;
Kevent event;
Io_status_block iostatusblock;
Pio_stack_location iostacklocation;
 
//
// Initialize the event
//
Keinitializeevent (& event, icationicationevent, false );
 
//
// Allocate an IRP and use the stacksize of the target device object as the stack size of the newly created IRP. This is
// Standard method for providing the stack size.
//
IRP = ioallocateirp (deviceobject-> stacksize, false );
 
If (! IRP)
Return false;
 
//
// Set the relevant parameters of the IRP header. Because we use the IRP created by ioallocateir, there are many
// Set the domain, including the input buffer, synchronization event, and IRP Flag Fields.
// Query of file information is not very useful, and it is critical for file read/write.
//
IRP-> associatedirp. systembuffer = fileinfo;
IRP-> userevent = & event;
IRP-> useriosb = & iostatusblock;
IRP-> tail. Overlay. Thread = psgetcurrentthread ();
IRP-> tail. Overlay. originalfileobject = fileobject;
IRP-> requestormode = kernelmode;
IRP-> flags = 0;
 
//
// Set relevant parameters in the position of the IRP stack. The most important parameter is majorfunction, which determines
// Main functions of IRP. In addition, parameters. queryfile. fileinformationclass defines
// The file information you want to query.
//
Iostacklocation = iogetnextirpstacklocation (IRP );
Iostacklocation-> majorfunction = irp_mj_query_information;
Iostacklocation-> deviceobject = deviceobject;
Iostacklocation-> fileobject = fileobject;
Iostacklocation-> parameters. queryfile. Length = fileinfolength;
Iostacklocation-> parameters. queryfile. fileinformationclass = fileinformationclass;
 
//
// Installation IRP completion routine
//
Iosetcompletionroutine (IRP, queryfileinformationcompleted, 0, true );
 
(Void) iocalldriver (deviceobject, IRP );
 
//
// Wait for the synchronization time to return. We set the event to the signal state in the IRP completion routine.
//
Kewaitforsingleobject (& event, executive, kernelmode, true, 0 );
 
Return (nt_success (iostatusblock. Status ));
}

Ntstatus
Queryfileinformationcompleted (
Pdevice_object deviceobject,
Pirp,
Pvoid Context
)
{
//
// Copy the status information back into the "user" iosb.
//
* IRP-> useriosb = IRP-> iostatus;

If (! Nt_success (IRP-> iostatus. Status )){

Dbuplint ("queryfileinformationcompleted error on IRP: % x/N", IRP-> iostatus. Status ));
}

//
// Set the synchronization event to the signal state in the completion routine.
//
Kesetevent (IRP-> userevent, 0, false );

//
// Release the newly created IRP in the completion routine, because the I/O manager will not do this for us.
//
Iofreeirp (IRP );

//
// We return status_more_processing_required, which indicates that the IRP of the I/O manager has other
// The process is being accessed. Please do not delete it. In fact, this IRP should be released by ourselves rather than I/O.
// Manager, so this value must be returned in the self-created IRP completion routine. In addition, we do not
// Call iocompleterequest for this IRP.
//
Return status_more_processing_required;
}

2. The definition of the file basic information class in IFS is as follows:

Typedef struct _ file_basic_information {// ntddk WDM nthal
Large_integer creationtime; // ntddk WDM nthal
Large_integer lastaccesstime; // ntddk WDM nthal
Large_integer lastwritetime; // ntddk WDM nthal
Large_integer changetime; // ntddk WDM nthal
Ulong fileattributes; // ntddk WDM nthal
} File_basic_information, * pfile_basic_information; // ntddk WDM nthal

This structure contains the File Creation Time and modification time. In addition, the file attribute domain fileattributes contains the attributes used to record the file, including whether the file is a system file or a hidden file, this field may be a combination of the following tags:

# Define file_attribute_readonly 0x00000001 // read-only
# Define file_attribute_hidden 0x00000002 // hide
# Define file_attribute_system 0x00000004 // System
# Define file_attribute_directory 0x00000010 // directory
# Define file_attribute_archive 0x00000020 // stream
# Define file_attribute_device 0x00000040 // Device
# Define file_attribute_normal 0x00000080 // normal

# Define file_attribute_temporary 0x00000100 // temporary
# Define file_attribute_sparse_file 0x00000200 // sparse file
# Define file_attribute_reparse_point 0x00000400 //
# Define file_attribute_compressed 0x00000800 // Compression

# Define file_attribute_offline 0x00001000 //
# Define file_attribute_not_content_indexed 0x00002000 //
# Define file_attribute_encrypted 0x00004000 // encryption, valid only after ntfs5

# Define file_attribute_valid_flags 0x00007fb7
# Define file_attribute_valid_set_flags 0x000031a7

Therefore, we can determine the nature of the file by using the attribute field in the basic information of the file that is successfully opened.

The function is defined as follows:
Ntstatus
Queryfilebasicinformation (
Pdevice_object deviceobject,
Pfile_object fileobject,
Pfile_basic_information filebasicinfo,
Ulong fileinfolength
)
{
Return queryfileinformation (
Deviceobject,
Fileobject,
Filebasicinformation,
Filebasicinfo,
Fileinfolength
);
}

Call instance:

Filebasicinfo = exallocatepoolwithtag (nonpagedpool, sizeof (file_basic_information), filter_pool_flag );
 
If (! Filebasicinfo)
{
Freefullpathnamebuffer (ansipathname, fullpathname );
Exfreepool (filectx );
Return completerequest (IRP, status_insufficient_resources, 0 );
}
 
Status = queryfilebasicinformation (
Hookext-> filesystem,
Fileobject,
Filebasicinfo,
Sizeof (file_basic_information)
);

If (! Nt_success (Status ))
{
Exfreepool (filebasicinfo );
IRP-> iostatus. Status = status;
Iocompleterequest (IRP, io_no_increment );
Return status;
}
 
If (filebasicinfo-> fileattributes & file_attribute_system)
{
Exfreepool (filebasicinfo );
IRP-> iostatus. Status = STATUS_SUCCESS;
Iocompleterequest (IRP, io_no_increment );
Return status;
}

If (filebasicinfo-> fileattributes & file_attribute_encrypted)
{
Exfreepool (filebasicinfo );
IRP-> iostatus. Status = STATUS_SUCCESS;
Iocompleterequest (IRP, io_no_increment );
Return status;
}

If (filebasicinfo-> fileattributes & file_attribute_directory)
{
Exfreepool (filebasicinfo );
IRP-> iostatus. Status = STATUS_SUCCESS;
Iocompleterequest (IRP, io_no_increment );
Return status;
}
 
Exfreepool (filebasicinfo );

3. The standard file information is defined as follows:

Typedef struct _ file_standard_information {// ntddk WDM nthal
Large_integer allocationsize; // ntddk WDM nthal
Large_integer endoffile; // ntddk WDM nthal
Ulong numberoflinks; // ntddk WDM nthal
Boolean deletepending; // ntddk WDM nthal
Boolean directory; // ntddk WDM nthal
} File_standard_information, * pfile_standard_information; // ntddk WDM nthal

Allocationsize is the size of the disk space allocated to the file by the file system after the file is created or modified. This value is generally an integer multiple of the physical sector size, it is larger than the actual size of the file. If the actual size of the file exceeds this value, the file system automatically expands this value to meet the needs of file increase.

Endoffile describes the actual file size.

Numberoflinks describes the total number of hard connections in a file.

Directory describes whether a file is a directory. You can query the file standard information to obtain the file length and whether the file is a directory.

The function is defined as follows:
Ntstatus
Queryfilestandardinformation (
Pdevice_object deviceobject,
Pfile_object fileobject,
Pfile_standard_information filestandardinfo,
Ulong fileinfolength
)
{
Return queryfileinformation (
Deviceobject,
Fileobject,
Filestandardinformation,
Filestandardinfo,
Fileinfolength
);
}

The same as the call instance.

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.