Driver development is really a headache, and there is no feeling for a few days. Find a piece of code. Although the sparrow is a little dirty, you can have a basic understanding of the entire framework after reading it, which is of great reference value. Share it here.
// Header file
# Ifdef _ cplusplus
Extern "C"
{
# Endif
# Include <WDM. h>
# Ifdef _ cplusplus
}
# Endif
Typedef struct _ device_extension
{
Pdevice_object fdo;
Pdevice_object nextstackdevice;
Unicode_string ifsymlinkname;
} Device_extension, * pdevice_extension;
Ntstatus hellowdmadddevice (in pdriver_object driverobject,
In pdevice_object physicaldeviceobject );
Ntstatus hellowdmpnp (in pdevice_object fdo,
In pirp );
// Main program
// The required header file declares the function modules and variables:
# Include "hellowdm. H"
/*************************************** ************************
Function Name: DriverEntry ()
Function Description: WDM program entry
**************************************** ***********************/
// Extern "C" is required, indicating "using C link ". This statement can be omitted if your file name is hellowdm. C.
Extern "C"
Ntstatus DriverEntry (in pdriver_object driverobject,
In punicode_string registrypath)
{
// Specify the "add device" message to be processed by the "hellowdmadddevice ()" function:
Driverobject-> driverextension-> adddevice = hellowdmadddevice;
// Specify the "plug-and-play" message to be processed by the "hellowdmpnp ()" function:
Driverobject-> majorfunction [irp_mj_pnp] = hellowdmpnp;
// Return an ntstatus value STATUS_SUCCESS. Almost all driver routines must return an ntstatus value, which is defined in detail in the ntstatus. h DDK header file.
Return STATUS_SUCCESS;
}
/*************************************** ************************
Function Name: hellowdmadddevice ()
Function Description: processes "add device" messages.
**************************************** ***********************/
Ntstatus hellowdmadddevice (in pdriver_object driverobject,
In pdevice_object physicaldeviceobject)
{
// Define the returned value of the ntstatus type:
Ntstatus status;
// Define a function device object ):
Pdevice_object fdo;
// Create a feature device object and store it in fdo:
Status = iocreatedevice (
Driverobject, // driver object
Sizeof (device_extension), // the size of the required device extension
Null, // device name, null
File_device_unknown, // The type of the device. One of the file_device_xxx values listed in the standard header file WDM. h or ntddk. h.
0, // constants are combined with or to indicate that the media can be deleted and read-only.
False, // if only one thread can access the device at a time, the value is true; otherwise, the value is false.
& Fdo); // The returned device object.
// Nt_success macro is used to test whether the iocreatedevice kernel is successfully completed. Do not forget to check whether all calls to the kernel are successful. Nt_error macro is not the same! Nt_success, preferably! Nt_success, because in addition to errors, it also intercepts warning information.
If (! Nt_success (Status ))
Return status;
// Create a device extension object dx to store the pointer to fdo:
Pdevice_extension dx = (pdevice_extension) fdo-> deviceextension;
DX-> fdo = fdo;
// Use the ioattachdevicetodevicestack function to connect the hellowdm device to the device Stack:
DX-> nextstackdevice = ioattachdevicetodevicestack (fdo, physicaldeviceobject );
// Set flags of fdo. There are two "bits" that must be changed. One is that the do_device_initializing flag must be cleared. If iocreatedevice () is called in the DriverEntry routine, this flag does not need to be cleared. Also, the do_buffer_io flag must be set:
Fdo-> flags | = do_buffered_io | do_power_pagable;
Fdo-> flags & = ~ Do_device_initializing;
// Return value:
Return STATUS_SUCCESS;
}
/*************************************** ************************
Function Name: hellowdmpnp ()
Function Description: process the "out-of-the-box" message.
**************************************** ***********************/
Ntstatus hellowdmpnp (in pdevice_object fdo,
In pirp)
{
// Create a device extension object dx to store the pointer to fdo:
Pdevice_extension dx = (pdevice_extension) fdo-> deviceextension;
// Obtain the current IRP through iogetcurrentirpstacklocation () and obtain the minor function:
Pio_stack_location irpstack = iogetcurrentirpstacklocation (IRP );
Ulong minorfunction = irpstack-> minorfunction;
// Then pass the minor function to the next device Stack:
Ioskipcurrentirpstacklocation (IRP );
Ntstatus status = iocalldriver (DX-> nextstackdevice, IRP );
// Process the "plug-and-play" function code:
// When minor function is equal to irp_mn_remove_device, it indicates that a device has been removed or removed. In this case, cancel resource allocation and delete the device:
If (minorfunction = irp_mn_remove_device)
{
// Cancel the device interface:
Iosetdeviceinterfacestate (& DX-> ifsymlinkname, false );
Rtlfreeunicodestring (& DX-> ifsymlinkname );
// Call iodetachdevice () to remove fdo from the device Stack:
If (DX-> nextstackdevice)
Iodetachdevice (DX-> nextstackdevice );
// Delete fdo:
Iodeletedevice (fdo );
}
// Return value:
Return status;
}