Windows File filter driver experience

Source: Internet
Author: User

Windows File filter driver experience
Author: ai3000

This article is reprinted by self-Driven Development Network

After reading chukuangren's second "file filter driver development tutorial", I was quite touched. I think that communication is based on equality. While complaining about the bad atmosphere and environment, we should first think about how much we actually paid? You don't need to complain if you want to ask for anything you don't want to pay. You can only blame yourself if you want to blame yourself. People who give their experiences are nothing more than two purposes. One is to lead some discussions and correct their wrong understandings so that they can gain more knowledge to make their progress faster. The second is to make a memo so that you can immediately find the relevant information when you forget it. I have also summarized some of the little experience I have accumulated when I used to drive file filtering in recent years. This note is just a small part of my thoughts after reading the chukuangren tutorial, it is not very comprehensive to think about where to write it. If you think about it again later, you will continue to supplement it. Due to work reasons
The Solaris driver and the Linux kernel have invested a lot of energy, and the file filter driver in Windows has never been touched, so the old saying is fixme.

1. Obtain the full file path and determine the time

Except for all irp_mj_xxx files that are created from scratch, do not try to obtain the full path from irp_mj_create, because only irp_mj_create
To create a valid file_object. In irp_read irp_write, they directly operate FCB (file control block.

2. Establish IRP transmission focus from scratch

No matter what type of IRP you create, irp_mj_create or irp_mj_directory_control, the most important thing to note is some flags. Different signs generate different results, and some results directly return failures. The flag here is not only IRP-> flags, but also io_stack_location-> flags and others. Especially if you want to achieve some special purposes, you need to note that, for example, irp_mn_query_directory, different flag results are very different.

3. Notes for retrieving full paths from the first IRP

When you create an irp_mj_query_information IRP from the beginning to obtain the full path, you must note that not only does irp_mj_create perform differentiated processing, but also does the same processing in irp_mj_close, otherwise, deadlock may be generated if the target is an NTFS file system. If it is NTFS, you also need to process fo_stream_file files in irp_mj_cleanup.

4. Obtain the local/Remote Access username (Domain Name/Sid)

The method is only available in irp_mj_create, because io_security_context is valid only in io_stack_location-> parameters. Create. securitycontext. In this way, you can obtain the access token from io_security_context-> securitycontext-> accessstate-> subjectsecuritycontext. xxxtoken to get the user name or Sid. Remember that there is a library in IFS, and its lib exports a function so that you can get the user name and domain name after obtaining the above information. But if you want to be compatible
If NT4 is used, the local and remote Sid can only be obtained through analysis.

5. file and directory judgment

The correct method has already been mentioned in the document of the Chu madman. If your file filter driver is compatible with all file systems, do not trust the data obtained from fileobject-> fscontext. The correct method is to get it after you pass irp_mj_create and then extend the device Stack from the underlying file system and return it to you.

6. Judgment point in encryption/Decryption

Only irp_paging_io, irp_synchronous_paging_io, and irp_nocache are correct. If there is a problem, I believe it is my own problem. Regarding whether fo_no_intermediate_buffering in file_object-> flags needs to be determined, the answer to this question is that as long as you have determined irp_nocache, you no longer need to judge file_object, because it will eventually set IRP-> flags to irp_nocache. For example, irp_defer_io_completion
Wait for the IRP to ignore it, because it is only a process. The final read/write is also described above. As for which of the above IRPs are sent by CC Mgr, which are sent by I/O Mgr, and when, this has been discussed and can be found.

7. Give an example to illustrate precautions for IRP transmission and completion

I only read the procedures described in Walter oney's "programming the Microsoft Windows Driver Model", but I still don't have the actual experience. I only introduced the basic concepts, let yourself have knowledge. Knowing how to use it, how to use it, and how to use it is a technology. From another perspective, we can divide the problem into two sections, which is conducive to the conclusion. In the filter driver, an IRP divides it into completeroutine and completeroutine. Therefore, you do not need to install completeroutine.
There are the following situations.

(1) Do nothing after obtaining this IRP. Call iocompleterequest () directly to return the result.
(2) do not do anything after obtaining this IRP, directly transfer it to the underlying device, use ioskipcurrentirpstacklocation (), and call iocalldriver () for transmission.
(3) Use iobuildsynchronousfsdrequest () or iobuilddeviceiocontrolrequest () to establish IRP.

You can use the preceding parameters as needed. In addition to some parameters and labels, you must pay attention to nothing related to the system mechanism. Then let's take a look at the situation where completeroutine needs to be installed. We further divide this situation into two types. One is the case where the flag returned in completeroutine is status_more_processing_required. The second is the flag outside the return position. The iomarkirppending () function is required. In completeroutine, the vast majority of these two cases require you to use one of them. So why do we need to install completeroutine?
What about it? That's because we are driving the IRP from the upper layer. We need to get the content as a reference when we return the driver to our layer through the underlying device stack, you also need to modify the content. Another case is that the driver is not driven by the upper layer, while the generated IRP is directly delivered to the underlying driver, and is returned to our layer after the device stack, we do not want it to continue to return, because the IRP itself is not from the upper layer. To sum up, let's take a look at iomarkirppending.

(1) Determine IRP-> pendingreturned in completeroutine, use iomarkirppending (), and then return. This method is not used when kesetevent () is not used and is not used when self-built IRPs are sent to the underlying driver for return. That is to say, it is possible that all my work is done in completeroutine. For example, during encryption/decryption, I will judge and modify the data returned by the underlying driver. After modification, because the status_more_processing_required flag is not used, it will extend the device heap to return up until the user obtains data. Note that in this case
Do not touch this IRP after completeroutine returns. That is to say, if you use iocompleterequest () at this time, a bsod error of multiple_irp_compliete_request will appear.

(2) directly return the status_more_processing_required flag in completeroutine. This situation occurs when the kesetevent () function is used. Here there are two small points.

1) When I use iocalldriver () and the underlying returned data passes through this layer, I want it to temporarily stop passing on, let the IRP take a rest for a while. After I complete the operation on the data returned by the IRP (generally, the operation is not performed on the returned data in completeroutine, that is to say, wait until the routine is returned and then perform the operation). I will call iocompleterequest () to extend the device stack to continue the return. Note that iocompleterequest () is called to make it return (). This is not the same as allocating resources from scratch as described below.
Iofreeirp () has been called in completeroutine to release the current IRP. For example, when I create a driver to change the file size and write the encryption mark to the file header, the irp_mj_query_information Query file is sent at the upper layer. I want to obtain the file information for judgment at this time, then, move the file pointer based on my judgment results. Note: The preceding steps are two steps. The first step is to obtain the file size first. At this time, I need to use the above method to first pass this IRP, after obtaining what I want, I will make a comparison. Wait for the appropriate time to complete the IRP, so that the data can be transmitted until the user receives the message. The second step is based on the following section.

2) When I create an IRP from scratch, when I use ioallocate () or iobuildasynchronousfsdrequest () to create an IRP call iocalldriver (), the underlying layer returns data to my layer, I don't want this IRP to be passed up to the device stack. This IRP is built at my level, and the upper layer does not know such an IRP. So here I will use iofreeirp () in completeroutine to release this IRP and not let it continue to pass. Note that after the completeroutine function returns
IRP has been released. If there are any operations on this IRP at this time, the consequences will be disastrous and bsod errors will inevitably occur. The example given in the previous section only completes the first step. Here we will continue with the second step. The first step is to reuse this IRP to get the file size. Although we know the size at this time, however, I still cannot know whether the file has been encrypted. At this time, I need to create an irp_mj_read IRP from the ground up here to read the file and determine whether the file I have encrypted has been used. If yes, reduce the size, then return again. Note: The return here refers to the first step of IRP return. Instead of the one we created. All created in completeroutine
.

8. Introduction to completed IRP operations

When an underlying driver calls the iocompleterequest () function, basically all device stack IRP processing is done in it. Including the identification of some flags of IRP> flags, processing of APC, and throwing multiple_irp_complete_requests errors. When the device stack keeps calling the completeroutine installed by the driver, if status_more_processing_required is found, the rollback will stop. This is why you can use this flag in completeroutine to pause.
IRP.

9. Usage of obquerynamestring

This function may be used in some environments. Its upper-layer function is zwqueryobject (). In some cases, the system may be suspended or bsod is used directly. It traverses the object from the obprootdirectoryobject in Object Manager and obtains the object name through object_header_to_name_info. Today, I asked polymeta, which seems to be triggered when processing pipe. This problem occurs in the 2000 system. It seems to have been patched on XP.

10. reimport Problems

In fact, this issue has been clearly introduced in the ifs faq a long time ago, including the handling methods and possible problems caused by each method. The q34 In the ifs faq describes four methods, including creating IRP from the beginning, using shadowdevice, using feature strings, and using iocreatefilespecifydeviceobjecthint () function in XP Based on the thread ID. In addition, we will briefly introduce the above issues to be addressed in different environments. In q33, the solution to the file_complete_if_oplocked problem encountered in CIFS is introduced.

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.