|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1993 Microsoft Corporation
4:
5: Module Name:
6:
7: simpldrv.c
8:
9: Abstract:
10:
11: A simple kernel-mode driver sample.
12:
13: Environment:
14:
15: kernel mode only
16:
17: Notes:
18:
19: See readme.txt
20:
21: Revision History:
22:
23: 06-25-93 : created
24:
25: --*/
26:
27: #include "ntddk.h"
28: #include "stdarg.h"
29: #include "stdio.h"
30: #include "simpldrv.h"
31:
32:
33:
34: //
35: // The following is the debug print macro- when we are building checked
36: // drivers "DBG" will be defined (by the \ddk\setenv.cmd script), and we
37: // will see debug messages appearing on the KD screen on the host debug
38: // machine. When we build free drivers "DBG" is not defined, and calls
39: // to SimplDrvKdPrint are removed.
40: //
41:
42: #ifdef DBG
43: #define SimplDrvKdPrint(arg) DbgPrint arg
44: #else
45: #define SimplDrvKdPrint(arg)
46: #endif
47:
48:
49:
50: NTSTATUS
51: SimplDrvDispatch(
52: IN PDEVICE_OBJECT DeviceObject,
53: IN PIRP Irp
54: );
55:
56: VOID
57: SimplDrvUnload(
58: IN PDRIVER_OBJECT DriverObject
59: );
60:
61:
62:
63: NTSTATUS
64: DriverEntry(
65: IN PDRIVER_OBJECT DriverObject,
66: IN PUNICODE_STRING RegistryPath
67: )
68: /*++
69:
70: Routine Description:
71:
72: Installable driver initialization entry point.
73: This entry point is called directly by the I/O system.
74:
75: Arguments:
76:
77: DriverObject - pointer to the driver object
78:
79: RegistryPath - pointer to a unicode string representing the path
80: to driver-specific key in the registry
81:
82: Return Value:
83:
84: STATUS_SUCCESS if successful,
85: STATUS_UNSUCCESSFUL otherwise
86:
87: --*/
88: {
89:
90: PDEVICE_OBJECT deviceObject = NULL;
91: NTSTATUS ntStatus;
92: WCHAR deviceNameBuffer[] = L"\\Device\\SimplDrv";
93: UNICODE_STRING deviceNameUnicodeString;
94: PDEVICE_EXTENSION deviceExtension;
95: WCHAR deviceLinkBuffer[] = L"\\DosDevices\\SIMPLDRV";
96: UNICODE_STRING deviceLinkUnicodeString;
97:
98:
99: SimplDrvKdPrint (("SIMPLDRV.SYS: entering DriverEntry\n"));
100:
101:
102:
103: //
104: // A real driver would:
105: //
106: // 1. Report it's resources (IoReportResourceUsage)
107: //
108: // 2. Attempt to locate the device(s) it supports
109:
110:
111:
112: //
113: // OK, we've claimed our resources & found our h/w, so create
114: // a device and initialize stuff...
115: //
116:
117: RtlInitUnicodeString (&deviceNameUnicodeString,
118: deviceNameBuffer
119: );
120:
121:
122:
123: //
124: // Create an EXCLUSIVE device, i.e. only 1 thread at a time can send
125: // i/o requests.
126: //
127:
128: ntStatus = IoCreateDevice (DriverObject,
129: sizeof (DEVICE_EXTENSION),
130: &deviceNameUnicodeString,
131: FILE_DEVICE_SIMPLDRV,
132: 0,
133: TRUE,
134: &deviceObject
135: );
136:
137: if (NT_SUCCESS(ntStatus))
138: {
139: deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension;
140:
141:
142:
143: //
144: // Set up synchronization objects, state info,, etc.
145: //
146:
147:
148:
149: //
150: // Create a symbolic link that Win32 apps can specify to gain access
151: // to this driver/device
152: //
153:
154: RtlInitUnicodeString (&deviceLinkUnicodeString,
155: deviceLinkBuffer
156: );
157:
158: ntStatus = IoCreateSymbolicLink (&deviceLinkUnicodeString,
159: &deviceNameUnicodeString
160: );
161:
162:
163: if (!NT_SUCCESS(ntStatus))
164: {
165: SimplDrvKdPrint (("SIMPLDRV.SYS: IoCreateSymbolicLink failed\n"));
166: }
167:
168:
169:
170: //
171: // Create dispatch points for device control, create, close.
172: //
173:
174: DriverObject->MajorFunction[IRP_MJ_CREATE] =
175: DriverObject->MajorFunction[IRP_MJ_CLOSE] =
176: DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = SimplDrvDispatch;
177: DriverObject->DriverUnload = SimplDrvUnload;
178: }
179:
180:
181: done_DriverEntry:
182:
183: if (!NT_SUCCESS(ntStatus))
184: {
185: //
186: // Something went wrong, so clean up (free resources, etc.)
187: //
188:
189: if (deviceObject)
190:
191: IoDeleteDevice (deviceObject);
192: }
193:
194: return ntStatus;
195: }
196:
197:
198:
199: NTSTATUS
200: SimplDrvDispatch(
201: IN PDEVICE_OBJECT DeviceObject,
202: IN PIRP Irp
203: )
204: /*++
205:
206: Routine Description:
207:
208: Process the IRPs sent to this device.
209:
210: Arguments:
211:
212: DeviceObject - pointer to a device object
213:
214: Irp - pointer to an I/O Request Packet
215:
216: Return Value:
217:
218:
219: --*/
220: {
221:
222: PIO_STACK_LOCATION irpStack;
223: PDEVICE_EXTENSION deviceExtension;
224: PVOID ioBuffer;
225: ULONG inputBufferLength;
226: ULONG outputBufferLength;
227: ULONG ioControlCode;
228: NTSTATUS ntStatus;
229:
230:
231:
232: Irp->IoStatus.Status = STATUS_SUCCESS;
233: Irp->IoStatus.Information = 0;
234:
235:
236: //
237: // Get a pointer to the current location in the Irp. This is where
238: // the function codes and parameters are located.
239: //
240:
241: irpStack = IoGetCurrentIrpStackLocation (Irp);
242:
243:
244:
245: //
246: // Get a pointer to the device extension
247: //
248:
249: deviceExtension = DeviceObject->DeviceExtension;
250:
251:
252:
253: //
254: // Get the pointer to the input/output buffer and it's length
255: //
256:
257: ioBuffer = Irp->AssociatedIrp.SystemBuffer;
258: inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
259: outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
260:
261:
262:
263: switch (irpStack->MajorFunction)
264: {
265: case IRP_MJ_CREATE:
266:
267: SimplDrvKdPrint (("SIMPLDRV.SYS: IRP_MJ_CREATE\n"));
268:
269: break;
270:
271: case IRP_MJ_CLOSE:
272:
273: SimplDrvKdPrint (("SIMPLDRV.SYS: IRP_MJ_CLOSE\n"));
274:
275: break;
276:
277: case IRP_MJ_DEVICE_CONTROL:
278:
279: SimplDrvKdPrint (("SIMPLDRV.SYS: IRP_MJ_DEVICE_CONTROL\n"));
280:
281: ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
282:
283: switch (ioControlCode)
284: {
285:
286: case IOCTL_SIMPLDRV_HELLO:
287: {
288: //
289: // Some app is saying hello
290: //
291:
292: break;
293: }
294:
295: default:
296:
297: Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
298:
299: SimplDrvKdPrint (("SIMPLDRV.SYS: unknown IRP_MJ_DEVICE_CONTROL\n"));
300:
301: break;
302:
303: }
304:
305: break;
306: }
307:
308:
309: //
310: // DON'T get cute and try to use the status field of
311: // the irp in the return status. That IRP IS GONE as
312: // soon as you call IoCompleteRequest.
313: //
314:
315: ntStatus = Irp->IoStatus.Status;
316:
317: IoCompleteRequest (Irp,
318: IO_NO_INCREMENT
319: );
320:
321:
322: //
323: // We never have pending operation so always return the status code.
324: //
325:
326: return ntStatus;
327: }
328:
329:
330:
331: VOID
332: SimplDrvUnload(
333: IN PDRIVER_OBJECT DriverObject
334: )
335: /*++
336:
337: Routine Description:
338:
339: Free all the allocated resources, etc.
340:
341: Arguments:
342:
343: DriverObject - pointer to a driver object
344:
345: Return Value:
346:
347:
348: --*/
349: {
350: WCHAR deviceLinkBuffer[] = L"\\DosDevices\\SIMPLDRV";
351: UNICODE_STRING deviceLinkUnicodeString;
352:
353:
354:
355: //
356: // Free any resources
357: //
358:
359:
360:
361: //
362: // Delete the symbolic link
363: //
364:
365: RtlInitUnicodeString (&deviceLinkUnicodeString,
366: deviceLinkBuffer
367: );
368:
369: IoDeleteSymbolicLink (&deviceLinkUnicodeString);
370:
371:
372:
373: //
374: // Delete the device object
375: //
376:
377: IoDeleteDevice (DriverObject->DeviceObject);
378:
379: SimplDrvKdPrint (("SIMPLDRV.SYS: unloading\n"));
380: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.