Address: http://book.51cto.com/art/200912/174785.htm
When the driver and application layer use named pipeline communication, I don't know how to open the named pipeline path in the driver. The path name in the original driver is: "\ device \ namedpipe \ mypipe ", "\\\\. \ PIPE \ mypipe"
Then let's look at how iocreatefile () finds the device object named the pipeline driver module. After a named pipe is created, a corresponding node is created in the object directory, for example, "\ device \ namedpipe \ mypipe ". Note that the node "namedpipe" is a device object, and the device object provides a parsing function. In this way, the obopenobjectbyname () of object management can locate the "directory" \ device \ namedpipe "of the Named Pipe Based on the full path (if the target has not been created) or the object that represents the target. Both have pointer pointing to the device object of the named pipeline Driver Module (if loaded ). The following is about the driver module.
Let's take a look at the initialization of the named pipeline driver module:
- Ntstatus stdcall // ReactOS-0.3.3 \ drivers \ filesystems \ npfs. c
- DriverEntry (pdriver_object driverobject, punicode_string registrypath)
- {
- Pnpfs_device_extension deviceextension;
- ......
-
- Dprint ("Named Pipe FSD 0.0.2 \ n ");
- Assert (sizeof (npfs_context) <= field_offset (IRP, tail. Overlay. drivercontext ));
- Assert (sizeof (npfs_waiter_entry) <=
- Field_offset (IRP, tail. Overlay. drivercontext ));
-
- Driverobject-> majorfunction [irp_mj_create] = npfscreate;
- Driverobject-> majorfunction [irp_mj_create_named_pipe] =
- Npfscreatenamedpipe;
- Driverobject-> majorfunction [irp_mj_close] = npfsclose;
- Driverobject-> majorfunction [irp_mj_read] = npfsread;
- Driverobject-> majorfunction [irp_mj_write] = npfswrite;
- Driverobject-> majorfunction [irp_mj_query_information] =
- Npfsqueryinformation;
- Driverobject-> majorfunction [irp_mj_set_information] =
- Npfssetinformation;
- Driverobject-> majorfunction [irp_mj_query_volume_information] =
- Npfsqueryvolumeinformation;
- Driverobject-> majorfunction [irp_mj_cleanup] = npfscleanup;
- Driverobject-> majorfunction [irp_mj_flush_buffers] = npfsflushbuffers;
- Driverobject-> majorfunction [irp_mj_file_system_control] =
- Npfsfilesystemcontrol;
- Driverobject-> driverunload = NULL;
- Rtlinitunicodestring (& devicename, l "\ device \ namedpipe ");
- // Create a device object named "\ device \ namedpipe" in the object directory
- Status = iocreatedevice (driverobject, sizeof (npfs_device_extension ),
- & Amp; devicename, file_device_named_pipe, 0, false, & deviceobject );
- If (! Nt_success (Status) return status; // failed to create the device object
-
- /* Initialize the device object */
- Deviceobject-> flags = do_direct_io;
- /* Initialize the device extension */
- Deviceextension = deviceobject-> deviceextension;
- Initializelisthead (& deviceextension-> pipelisthead); // queues of all named pipelines FCB
- Initializelisthead (& deviceextension-> threadlisthead );
- Keinitializemutex (& deviceextension-> pipelistlock, 0 );
- Deviceextension-> emptywaitercount = 0;
- /* Set the Size Quotas */
- Deviceextension-> minquota = page_size;
- Deviceextension-> defaultquota = 8 * page_size;
- Deviceextension-> maxquota = 64 * page_size;
- Return STATUS_SUCCESS;
- }
Note that the function pointer with the main function irp_mj_create points to npfscreate (), and the function pointer with the main function irp_mj_create_named_pipe points to npfscreatenamedpipe (), the named pipeline driver is the only driving object that provides the main function later.
In addition, the adddevice function is not provided here, which indicates that the drive of the named pipeline is a "old-fashioned (legacy)" Single-device driver, its Device objects are not stacked on other device objects.
Because the path name is "\ device \ namedpipe", iocreatedevice () creates a device object named "namedpipe" under the node "\ device" in the object directory, and point it to the Created Named Pipe device object. Note that the file_device_named_pipe here is the device type, just like file_device_beep, and the type of the created object is the iodeviceobjecttype, that is, the device object. On the other hand, the device object provides resolution functions.
The Expansion Department of the device object has a queue pipelisthead, which contains all created named queues. Each named pipe has a "file control block", that is, the npfs_fcb data structure. The data structure is stored in the pipelisthead queue, which is like a single-layer directory. In addition, in essence, the named pipe is nothing more than the "Transfer Station" of data, so a certain amount of buffer space is required, and a quota is set here.
After a device object is created, the kernel's device driver framework can call its main function through IRP and iocalldriver. When you create or open a named pipeline, the kernel will create a file_object representing the specific access context for it, just like for other devices. It is the fileobject in the following code, the handle returned by the System Call represents the file object.
In the parsing function iopparsedevice () of the device object, when the file type is createfiletypenamedpipe, the primary function code of the generated irp_mj_create_named_pipe is irp_mj_create. That is to say, when the IRP reaches the device object of the named pipe driver module, the former indicates that this is the name pipe created by the server, and the latter indicates that this is the name pipe opened by the client.
Look at the specific main function, the most important of which is npfscreatenamedpipe () and npfscreate (). First look at the former. npfscreatenamedpipe () is a relatively large function and needs to be read in segments.