[Reprinted] Using DeviceIoControl and CreateFile In the WDM Driver

Source: Internet
Author: User
Title: [Results 3.4] Using DeviceIoControl In the WDM driver, CreateFile for: Fire shadow time: 2008-01-08,23: 49 link: http://bbs.pediy.com/showthread.php? T = 57948 using the WDM driver Demo circulating on the Internet, add some comments by yourself, it seems that it is not the result-driven part: /*************************************** * *********************************/* This file contains the implementation for mandatory part for/* Pseudo Driver to work with the support of I/O Control Code/* handling. /*/************************************* ***********************************/# include <wdm. h> # include "DrvMain. h "# include ".. \ Program Files \ B Asic \ WDMDefault. h "# include ".. \ Program Files \ PnP. h "# include ".. \ Program Files \ PM. h "UNICODE_STRING Global_sz_Drv_RegInfo; UNICODE_STRING Global_sz_DeviceName; PDEVICE_POWER_INFORMATION Global_PowerInfo_Ptr; NTSTATUS DriverEntry (// The first parameter of DriverEntry is a pointer // pointing to a newly initialized driver object, this object represents your driver. IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) {dbuplint ("In DriverEntry: Begin \ r \ n"); // Save the device service key name RtlInitUnicodeString (& Global_sz_Drv_RegInfo, registryPath-> Buffer); // Initialize function pointers DriverObject-> DriverUnload = DriverUnload; // check DriverObject-> DriverExtension-> AddDevice = AddDevice; driverObject-> MajorFunction [IRP_MJ_CREATE] = PsdoDispatchCreate; DriverObje Ct-> MajorFunction [callback] = PsdoDispatchClose; DriverObject-> MajorFunction [callback] = callback; DriverObject-> MajorFunction [callback] = PsdoDispatchPower; DriverObject-> MajorFunction [callback] = PsdoDispatchPnP; dbuplint ("In DriverEntry: End \ r \ n"); return STATUS_SUCCESS ;} NTSTATUS AddDevice (// The DriverObject parameter points to a driver object // It is the driver object you initialize in the DriverEntry routine. Parameters parameter // number of physical device objects pointing to the bottom of the device stack IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT extensions) {ULONG DeviceExtensionSize; PDEVICE_EXTENSION p_DVCEXT; PDEVICE_OBJECT ptr_PDO; NTSTATUS; ULONG idxpwr; dbuplint ("In AddDevice: Begin \ r \ n"); // device name RtlInitUnicodeString (& Global_sz_DeviceName, L "\ DosDevices \ pseudo dodevice "); // Get DEVICE_EXTENSION required memory space Devi CeExtensionSize = sizeof (DEVICE_EXTENSION); // create a device. The WDM driver creates the device status = IoCreateDevice (DriverObject, DeviceExtensionSize, & Global_sz_DeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, // store the Device Object pointer & ptr_PDO); if (NT_SUCCESS (status) {// Set Device Object Flags // clear the DO_DEVICE_INITIALIZING flag // when this flag is Set, the I/O manager rejects any request to open the device handle or to attach another device object to the device object. // After the driver initialization is complete, you must clear this flag ptr_PDO-> Flags & = ~ DO_DEVICE_INITIALIZING; // There are two flag bits in the device object that need to be initialized in AddDevice, and they will not change in the future. They are the // DO_BUFFERED_IO and DO_DIRECT_IO flags. You can only set and use one of the flag. It will determine how you process the/from the user mode memory buffer/In the buffered mode, the I/O manager first creates a system buffer with the same size as the user mode data buffer. And your driver will use this // system buffer to work. The I/O manager is responsible for copying data between the system buffer zone and the user mode buffer zone. // In direct mode, the I/O manager locks the physical memory page containing the user mode buffer and creates a memory Descriptor Table called MDL) to describe the lock page. Therefore, your driver will work with MDL. Ptr_PDO-> Flags | = DO_DIRECT_IO; // Device Extension memory maps // initialize the Device Extension p_DVCEXT = ptr_PDO-> DeviceExtension; // Save the new Device object p_DVCEXT-> DeviceObject = ptr_PDO; // Initialize driver description string RtlInitUnicodeString (& p_DVCEXT-> Device_Description, L "This is a Pseudo Device Driver \ r \ n" L "Created by mjtsai 2003/1/25 \ r \ n "); // initialize the spin lock IoInitializeRemoveLock (& p_DVCEXT-> RemoveLock, 'kcol', 0, 0); // Initi Alize driver power state p_DVCEXT-> SysPwrState = PowerSystemWorking; // full power supply status p_DVCEXT-> DevPwrState = PowerDeviceD0; // Initialize device power information // The duration = ExAllocatePool (NonPagedPool, sizeof (DEVICE_POWER_INFORMATION); RtlZeroMemory (Global_PowerInfo_Ptr, sizeof (DEVICE_POWER_INFORMATION); Global_PowerInfo_Ptr-> SupportQueryCapability = FALSE; Global_PowerInfo_Ptr-> De ViceD1 = 0; response-> DeviceD2 = 0; Global_PowerInfo_Ptr-> WakeFromD0 = 0; response-> WakeFromD1 = 0; response-> WakeFromD2 = 0; Global_PowerInfo_Ptr-> WakeFromD3 = 0; success-> DeviceWake = 0; success-> SystemWake = 0; for (IdxPwrState = 0; IdxPwrState <PowerSystemMaximum; IdxPwrState ++) {Global_PowerInfo_Ptr-> DeviceState [IdxPwrState] = 0;} // Store next-layered device object // Attach device object to device stack // The first parameter of IoAttachDeviceToDeviceStack is the address of the newly created device object // The second parameter is the device object pointer. The second parameter of AddDevice is also the address. // The return value is the address of any device object under you. It can be a device object, it can also be other low/level filter device objects // in this example, link the new device object to the p_DVCEXT-> NextDeviceObject = IoAttachDeviceToDeviceStack (ptr_PDO, PhysicalDeviceObject) on the underlying physical device object );} dbuplint ("In AddDevice: End \ r \ n"); return status;} VOID DriverUnload (IN PDRIVER_OBJECT DriverObject) {PDEVICE_EXTENSION p_DVCEXT; dbuplint ("In DriverUnload: begin \ r \ n "); p_DVCEXT = DriverObject-> DeviceObject-> DeviceExtension; ExFre EPool (Global_PowerInfo_Ptr); RtlFreeUnicodeString (& Global_sz_Drv_RegInfo); RtlFreeUnicodeString (& p_DVCEXT-> Device_Description ); // reduce the connection between the caller's device object and the device object of the underlying driver // reduce the reference count for p_DVCEXT-> DeviceObject // If the count is 0 and the underlying driver has been marked as an unmount operation, the underlying driver is uninstalled IoDetachDevice (p_DVCEXT-> DeviceObject); // removes a device object from the system. When the reference count of p_DVCEXT-> NextDeviceObject is 0. // If the value is not 0, it is marked as "to be deleted. IoDeleteDevice (p_DVCEXT-> NextDeviceObject); dbuplint ("In DriverUnload: End \ r \ n"); return;} NTSTATUS failed (IN PDEVICE_OBJECT DeviceObject, in pirp) {paip_io_stk; PDEVICE_EXTENSION p_DVCEXT; NTSTATUS status; dbuplint ("IRP_MJ_CREATE Received: Begin \ r \ n"); // obtain the current IRP stack position p_IO_STK = IoGetCurrentIrpStackLocation (Irp ); // DeviceExtension this structure can be used to save the information of each device instance p_DVCEXT = Devi CeObject-> DeviceExtension; // increase the Count status = running (& p_DVCEXT-> RemoveLock, p_IO_STK-> FileObject); if (NT_SUCCESS (status) {CompleteRequest (Irp, STATUS_SUCCESS, 0); dbuplint ("IRP_MJ_CREATE Received: End \ r \ n"); return STATUS_SUCCESS;} else {IoReleaseRemoveLock (& p_DVCEXT-> RemoveLock, p_IO_STK-> FileObject ); completeRequest (Irp, status, 0); dbuplint ("IRP_MJ_CREATE Received: End \ r \ n"); r Eturn status ;}} NTSTATUS failed (IN PDEVICE_OBJECT DeviceObject, IN pirirp) {PIO_STACK_LOCATION p_IO_STK; PDEVICE_EXTENSION p_DVCEXT; dbuplint ("begreceived: Begin \ r \ n "); p_IO_STK = listen (Irp); p_DVCEXT = DeviceObject-> DeviceExtension; disconnect (& p_DVCEXT-> RemoveLock, p_IO_STK-> FileObject); CompleteRequest (Irp, timeout, 0); dbgprs (" IRP_MJ_CLOSE Received: Begin \ r \ n "); return STATUS_SUCCESS;} NTSTATUS reset (IN PDEVICE_OBJECT DeviceObject, IN piriririrp) {ULONG code, cbin, cbout, info, pwrinf_size; PIO_STACK_LOCATION p_IO_STK; PDEVICE_EXTENSION p_DVCEXT; PDEVICE_POWER_INFORMATION pValue; ULONG IdxPwrState; NTSTATUS status; p_IO_STK = reply (Irp); p_DVCEXT = DeviceObject-> DeviceExtension; // DeviceIoControl access code = p_IO_STK-> Parameters. deviceIoControl. ioControlCode; // The length of the input buffer. cbin = p_IO_STK-> Parameters. deviceIoControl. inputBufferLength; // output buffer length cbout = p_IO_STK-> Parameters. deviceIoControl. outputBufferLength; terminate (& p_DVCEXT-> RemoveLock, Irp); switch (code) {case when: if (p_DVCEXT-> Device_Description.Length> cbout) {cbout = p_DVCEXT-> Device_D EIP. length; info = cbout;} else {info = p_DVCEXT-> Device_Description.Length;} // copy data to the system buffer zone, the I/O manager is responsible for copying data to the user's buffer zone RtlCopyMemory (Irp-> AssociatedIrp. systemBuffer, p_DVCEXT-> Device_Description.Buffer, info); status = STATUS_SUCCESS; break; // skip case insensitive: pwrinf_size = sizeof (DEVICE_POWER_INFORMATION); if (pwrinf_size> cbout) {cbout = pwrinf_size; info = cbout;} else {Info = pwrinf_size;} // Display Related Device Power State dbuplint ("Support Query Device Capability: % $ r \ n", Global_PowerInfo_Ptr-> SupportQueryCapability? "Yes": "No"); dbuplint ("DeviceD1: % d \ r \ n", Global_PowerInfo_Ptr-> DeviceD1); dbuplint ("DeviceD2: % d \ r \ n ", Global_PowerInfo_Ptr-> DeviceD2); dbuplint (" WakeFromD0: % d \ r \ n ", Global_PowerInfo_Ptr-> WakeFromD0); dbuplint (" WakeFromD1: % d \ r \ n ", Global_PowerInfo_Ptr-> WakeFromD1); dbuplint (" WakeFromD2: % d \ r \ n ", Global_PowerInfo_Ptr-> WakeFromD2); dbuplint (" WakeFromD3: % d \ r \ n ", Global_PowerInfo_Ptr-> Wake FromD3); dbuplint ("SystemWake: % d \ r \ n", Global_PowerInfo_Ptr-> SystemWake); dbuplint ("DeviceWake: % d \ r \ n ", response-> DeviceWake); for (IdxPwrState = 0; IdxPwrState <PowerSystemMaximum; IdxPwrState ++) {dbuplint ("DeviceState [% d]: % d \ r \ n", IdxPwrState, global_PowerInfo_Ptr-> DeviceState [IdxPwrState]);} # ifdef _ DEF_HANDLE_BY_POWER_INFO_STRUCTURE pValue = (PDEVICE_POWER_INFORMATION) Irp-> AssociatedIrp. systemBuffer; pValue-> SupportQueryCapability = Global_PowerInfo_Ptr-> SupportQueryCapability; pValue-> DeviceD1 = Global_PowerInfo_Ptr-> DeviceD1; pValue-> DeviceD2 = Global_PowerInfo_Ptr-> deviced2; pValue-> DeviceWake = wake-> DeviceWake; pValue-> SystemWake = Global_PowerInfo_Ptr-> SystemWake; pValue-> WakeFromD0 = wake-> WakeFromD0; pValue-> WakeFromD1 = Glob Response-> response; pValue-> WakeFromD2 = response-> WakeFromD2; pValue-> response = response-> response; for (IdxPwrState = 0; IdxPwrState <PowerSystemMaximum; IdxPwrState ++) {pValue-> DeviceState [IdxPwrState] = Global_PowerInfo_Ptr-> DeviceState [IdxPwrState];} # else RtlCopyMemory (Irp-> AssociatedIrp. systemBuffer, Global_PowerInfo_Ptr, info); # endif status = STATUS _ SUCCESS; break; default: info = 0; status = enabled; break;} IoReleaseRemoveLock (& p_DVCEXT-> RemoveLock, Irp); CompleteRequest (Irp, STATUS_SUCCESS, info ); return status;}/* NTSTATUS CompleteRequest (in pirp Irp, in ntstatus status, IN ULONG_PTR info) {Irp-> IoStatus. status = status; Irp-> IoStatus. information = info; // The driver has processed the IRP and handed it to the I/O manager. IoCompleteRequest (Irp, IO_NO_INCREMENT); return status;} */user layer part: # include "stdafx. h "# include <winioctl. h>/* Self-Defined I/O Control Code * // I/O Control Code for Device Information retrieval // note the following buffer mode and the initial value of the adddevice function in the driver the buffer mode of is somewhat different // The explanation is as follows: // at that time, I pointed out that when a read/write request arrives, you must remember the mode used to access the user mode buffer indicated in AddDevice, whether it is the buffered mode or the direct mode (or neither ). Control requests also // use these addressing methods, but there are some differences. Instead of specifying the global addressing mode with a flag in the device object, you can specify the addressing mode for each IOCTL using the low two-digit feature code // In IOCTL. // In addition, the buffer method specified in IOCTL does not affect the addressing buffer of normal read/write IRPs. // # Define CTL_CODE (DeviceType, Function, Method, Access) (\ (DeviceType) <16) | (Access) <14) | (Function) <2) | (Method )) /// # define METHOD_BUFFERED 0 // # define METHOD_IN_DIRECT 1 // # define METHOD_OUT_DIRECT 2 // # define METHOD_NEITHER 3 # define rules \ CTL_CODE (\ FILE_DEVICE_UNKNOWN, \ 0x800, \ METHOD_BUFFERED, \ FILE_ANY_ACCESS) int main (int argc, char * argv []) {// second to last parameter: Open the device handle without specifying the FILE_FLAG_OVERLAPPED flag. Therefore, the call to // DeviceIoControl after this will not be returned until the driver responds to our request. // Used to set synchronous or asynchronous HANDLE hdevice = CreateFile ("\\\\. \ pseudo dodevice ", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (hdevice = INVALID_HANDLE_VALUE) {printf ("Unable to open pseudo dodevice device-error % d \ n", GetLastError (); return 1 ;}wchar_t answer [512] = {'\ 0 '}; DWORD junk; // only the output buffer is required. Note that answer is unicode if (DeviceIoControl (hdevice, IOCTL_READ_DEVICE_INFO, NULL, 0, answer, sizeof (answer), & junk, NULL )) {answer [junk] = 0; MessageBoxW (NULL, answer, L "look me", 0); wprintf (L "% s", answer );} else printf ("Error % d in call to DeviceIoControl \ n", GetLastError (); CloseHandle (hdevice); return 0;} How to compile code: Go to the Program Files folder, build "Basic", "PnP", "PM" respectively, and then Build "IOCTL_PW" how to install the driver: here we use the "add Hardware" method in "Control Panel, select "disk installation" and select the inf file in the "install" folder for installation (the normal method of dynamically loading the driver does not seem to be applicable to the WDM driver, and every time the screen is blue)

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.