1 #ifdef __cplusplus
2 extern "C"
3 {
4 #endif
5 #include <wdm.h> // 不同点之一
6 #ifdef __cplusplus
7 }
8 #endif
9
10 typedef struct _DEVICE_EXTENSION
11 {
12 PDEVICE_OBJECT fdo;
13 PDEVICE_OBJECT NextStackDevice;
14 UNICODE_STRING ustrDeviceName;
15 UNICODE_STRING ustrSymbolicName;
16 }DEVICE_EXTENSION, *PDEVICE_EXTENSION;
17
18 #define PAGEDCODE code_seg("PAGE")
19 #define LOCKEDCODE code_seg()
20 #define INITCODE code_seg("INIT")
21 #define PAGEDDATA data_seg("PAGE")
22 #define LOCKEDDATA data_seg();
23 #define INITDATA data_seg("INIT")
24
25 #define arraysize(p) (sizeof(p) / sizeof((p)[0]))
26 #pragma PAGEDCODE
27
28
29 //////////////////////////////////////////////////////////////////////////
30 // 添加设备的处理例程
31 #pragma PAGEDCODE
32 NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT pDriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
33 {
34 PAGED_CODE(); // PAGED_CODE()宏确保本函数运行在低于APC_LEVEL的中断优先级级别上
35 KdPrint(("Enter HelloWDMAddDevice\n"));
36
37 NTSTATUS status;
38 PDEVICE_OBJECT fdo;
39 UNICODE_STRING devName;
40
41 RtlInitUnicodeString(&devName, L"\\Device\\MyWDMDevice");
42 IoCreateDevice(pDriverObject, sizeof(DEVICE_EXTENSION), &devName, FILE_DEVICE_UNKNOWN,
43 0, FALSE, &fdo);
44
45 PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
46 pdx->fdo = fdo;
47 pdx->ustrDeviceName = devName;
48 // 将fdo附加到pdo上
49 pdx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);
50
51 UNICODE_STRING symName;
52 RtlInitUnicodeString(&symName, L"\\DosDevice\\helloWDM");
53 status = IoCreateSymbolicLink(&symName, &devName);
54
55 if (!NT_SUCCESS(status))
56 {
57 IoDeleteSymbolicLink(&symName);
58 status = IoCreateSymbolicLink(&symName, &devName);
59 if (!NT_SUCCESS(status))
60 {
61 return status;
62 }
63 }
64
65 fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
66 fdo->Flags &= ~DO_DEVICE_INITIALIZING;
67
68 KdPrint(("Leaving AddDevice!"));
69 return STATUS_SUCCESS;
70 }
71 //////////////////////////////////////////////////////////////////////////
72 // 对PNP IRP进行默认处理(叫下层驱动对此pnp进行处理)
73 #pragma PAGEDCODE
74 NTSTATUS DefaultPnpHandler(PDEVICE_EXTENSION pdx, PIRP Irp)
75 {
76 PAGED_CODE();
77 KdPrint(("Enter DefaultPnpHandler..."));
78 IoSkipCurrentIrpStackLocation(Irp);
79 KdPrint(("Leaving DefaultPnpHandler"));
80 return IoCallDriver(pdx->NextStackDevice, Irp);
81 }
82
83
84 //////////////////////////////////////////////////////////////////////////
85 // IRP_MN_PNP_REMOVE_DEVICE这个irp的处理例程
86 #pragma PAGEDCODE
87 NTSTATUS HandleRemoveDevice(PDEVICE_EXTENSION pdx, PIRP Irp)
88 {
89 PAGED_CODE();
90 KdPrint(("Entering HandleRemoveDevice"));
91
92 Irp->IoStatus.Status = STATUS_SUCCESS;
93 NTSTATUS status = DefaultPnpHandler(pdx, Irp);
94 IoDeleteSymbolicLink(&pdx->ustrSymbolicName);
95
96 // 调用IoDetachDevice将fdo从设备栈中脱离
97 if (pdx->NextStackDevice)
98 {
99 IoDetachDevice(pdx->NextStackDevice);
100 }
101
102 // 删除FDO
103 IoDeleteDevice(pdx->fdo);
104 KdPrint(("Leave HandleRemoveDevice"));
105 return status;
106 }
107
108 #pragma PAGEDCODE
109 NTSTATUS HelloWDMDispatchRoutine(IN PDEVICE_OBJECT fdo,
110 IN PIRP Irp)
111 {
112 PAGED_CODE();
113 KdPrint(("Entering HelloWDMDispatchRoutine..."));
114 Irp->IoStatus.Status = STATUS_SUCCESS;
115 Irp->IoStatus.Information = 0;
116 IoCompleteRequest(Irp, IO_NO_INCREMENT);
117 KdPrint(("leaving HelloWDMDispatchRoutine..."));
118 return STATUS_SUCCESS;
119 }
120
121 #pragma PAGEDCODE
122 void HelloWDMUnload(IN PDRIVER_OBJECT pDriverObject)
123 {
124 PAGED_CODE();
125 KdPrint(("Enter HelloWDMUnload"));
126 KdPrint(("Leaving HelloWDMUnload"));
127 }
128
129 //////////////////////////////////////////////////////////////////////////
130 // pnp处理例程
131 #pragma PAGEDCODE
132 NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
133 {
134 PAGED_CODE();
135
136 KdPrint(("Entering HelloWDMPnp.."));
137 NTSTATUS status = STATUS_SUCCESS;
138 PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
139 PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
140
141 static NTSTATUS (*fcntab[])(PDEVICE_EXTENSION pdx, PIRP Irp) =
142 {
143 DefaultPnpHandler, // IRP_MN_START_DEVICE
144 DefaultPnpHandler, // IRP_MN_QUERY_REMOVE_DEVICE
145 HandleRemoveDevice, // IRP_MN_REMOVE_DEVICE !!注意,在这里添加了相应的处理程序
146 DefaultPnpHandler, // IRP_MN_CANCEL_REMOVE_DEVICE
147 DefaultPnpHandler, // IRP_MN_STOP_DEVICE
148 DefaultPnpHandler, // IRP_MN_QUERY_STOP_DEVICE
149 DefaultPnpHandler, // IRP_MN_CANCEL_STOP_DEVICE
150 DefaultPnpHandler, // IRP_MN_QUERY_DEVICE_RELATIONS
151 DefaultPnpHandler, // IRP_MN_QUERY_INTERFACE
152 DefaultPnpHandler, // IRP_MN_QUERY_CAPABILITIES
153 DefaultPnpHandler, // IRP_MN_QUERY_RESOURCES
154 DefaultPnpHandler, // IRP_MN_QUERY_RESOURCE_REQUIREMENTS
155 DefaultPnpHandler, // IRP_MN_QUERY_DEVICE_TEXT
156 DefaultPnpHandler, // IRP_MN_FILTER_RESOURCE_REQUIREMENTS
157 DefaultPnpHandler,
158 DefaultPnpHandler, // IRP_MN_READ_CONFIG
159 DefaultPnpHandler, // IRP_MN_WRITE_CONFIG
160 DefaultPnpHandler, // IRP_MN_EJECT
161 DefaultPnpHandler, // IRP_MN_SET_LOCK
162 DefaultPnpHandler, // IRP_MN_QUERY_ID
163 DefaultPnpHandler, // IRP_MN_QUERY_PNP_DEVICE_STAT
164 DefaultPnpHandler, // IRP_MN_QUERY_BUS_INFORMATION
165 DefaultPnpHandler, // IRP_MN_DEVICE_USAGE_NOTIFICATION
166 DefaultPnpHandler, // IRP_MN_SURPRISE_REMOVAL
167 };
168
169 ULONG fcn = stack->MinorFunction;
170 if (fcn >= arraysize(fcntab))
171 {
172 // 未知的IRP类型
173 status = DefaultPnpHandler(pdx, Irp);
174 return status;
175 }
176
177 #if DBG
178 static char * fcnname[] =
179 {
180 "IRP_MN_START_DEVICE",
181 "IRP_MN_QUERY_REMOVE_DEVICE",
182 "IRP_MN_REMOVE_DEVICE",
183 "IRP_MN_CANCEL_REMOVE_DEVICE",
184 "IRP_MN_STOP_DEVICE",
185 "IRP_MN_QUERY_STOP_DEVICE",
186 "IRP_MN_CANCEL_STOP_DEVICE",
187 "IRP_MN_QUERY_DEVICE_RELATIONS",
188 "IRP_MN_QUERY_INTERFACE",
189 "IRP_MN_QUERY_CAPABILITIES",
190 "IRP_MN_QUERY_RESOURCES",
191 "IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
192 "IRP_MN_QUERY_DEVICE_TEXT",
193 "IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
194 "",
195 "IRP_MN_READ_CONFIG",
196 "IRP_MN_WRITE_CONFIG",
197 "IRP_MN_EJECT",
198 "IRP_MN_SET_LOCK",
199 "IRP_MN_QUERY_ID",
200 "IRP_MN_QUERY_PNP_DEVICE_STAT",
201 "IRP_MN_QUERY_BUS_INFORMATION",
202 "IRP_MN_DEVICE_USAGE_NOTIFICATION",
203 "IRP_MN_SURPRISE_REMOVAL"
204 };
205
206 KdPrint(("PNP Request(%s)\n", fcnname[fcn]));
207 #endif //DBG
208 status = (*fcntab[fcn])(pdx, Irp);
209 KdPrint(("Leave helloWDM Pnp\n"));
210
211 return status;
212 }
213
214 //////////////////////////////////////////////////////////////////////////
215 // 驱动程序入口函数
216 extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
217 {
218 KdPrint(("Enter DriverEntry -- gmh"));
219
220 DriverObject->DriverExtension->AddDevice = HelloWDMAddDevice;
221 DriverObject->MajorFunction[IRP_MJ_PNP] = HelloWDMPnp;
222 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
223 DriverObject->MajorFunction[IRP_MJ_CREATE] =
224 DriverObject->MajorFunction[IRP_MJ_READ] =
225 DriverObject->MajorFunction[IRP_MJ_WRITE] = HelloWDMDispatchRoutine;
226 DriverObject->DriverUnload = HelloWDMUnload;
227
228 KdPrint(("Leaving DriverEntry -- gmh!"));
229 return STATUS_SUCCESS;
230 }