|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1991, 1992 Microsoft Corporation
4:
5: Module Name:
6:
7: krnldrvr.c
8:
9: Abstract:
10:
11: This is the NT Kernel driver component of the DOSIOCTL sample.
12:
13: Environment:
14:
15: kernel mode only
16:
17: Notes:
18:
19: This kernel driver's sole responsibility is to respond to a
20: single IOCTL and return a fixed DWORD of information. This in
21: itself would not be a significant accomplishment. However, in
22: the context of the pieces of the DOSIOCTL sample, the interesting
23: trick is that this driver places the information directly in a DOS
24: application's buffer.
25:
26: The way this is accomplished is through a DOS driver and VDD. An
27: IOCTL read is issued from the DOS application, and the pointer
28: supplied in that request is passed along to this driver. (The
29: IOCTL used is BUFFERED, so the I/O subsystem actually does do a
30: single copy)
31:
32: The piece of information supplied here is the DWORD 0x12345678.
33: This data will then be displayed by the DOS application.
34:
35: Obviously, the drivers supplied in this sample are only skeletons.
36: But having the working communication mechanism in place makes for
37: a good starting point for any new driver.
38:
39: Revision History:
40:
41: --*/
42:
43: #include "ntddk.h"
44: #include "string.h"
45: #include "krnldrvr.h"
46:
47:
48: typedef struct _KDVR_DEVICE_EXTENSION {
49:
50: ULONG Information;
51:
52: } KDVR_DEVICE_EXTENSION, *PKDVR_DEVICE_EXTENSION;
53:
54:
55:
56: //
57: // Function declarations
58: //
59: static
60: NTSTATUS
61: KdvrDispatch(
62: IN PDEVICE_OBJECT DeviceObject,
63: IN PIRP Irp
64: );
65:
66: static
67: NTSTATUS
68: KdvrDispatchIoctl(
69: IN PDEVICE_OBJECT DeviceObject,
70: IN PIRP Irp
71: );
72:
73: VOID
74: KdvrUnloadDriver(
75: IN PDRIVER_OBJECT DriverObject
76: );
77:
78: NTSTATUS
79: DriverEntry(
80: IN PDRIVER_OBJECT DriverObject,
81: IN PUNICODE_STRING RegistryPath
82: )
83:
84: /*++
85:
86: Routine Description:
87:
88: This is the initialization routine for the KRNLDRVR sample device driver.
89: This routine creates the device object, symbolic link, and initializes
90: a device extension.
91:
92: Arguments:
93:
94: DriverObject - Pointer to driver object created by the system.
95:
96: Return Value:
97:
98: The function value is the final status from the initialization operation.
99:
100: --*/
101:
102: {
103: UNICODE_STRING nameString, linkString;
104: PDEVICE_OBJECT deviceObject;
105: NTSTATUS status;
106: PKDVR_DEVICE_EXTENSION extension;
107:
108:
109: //
110: // Create the device object.
111: //
112:
113: RtlInitUnicodeString( &nameString, L"\\Device\\Krnldrvr" );
114:
115: status = IoCreateDevice( DriverObject,
116: sizeof(KDVR_DEVICE_EXTENSION),
117: &nameString,
118: FILE_DEVICE_UNKNOWN,
119: 0,
120: TRUE,
121: &deviceObject );
122:
123: if (!NT_SUCCESS( status ))
124: return status;
125:
126: //
127: // Create the symbolic link so the VDD can find us.
128: //
129:
130: RtlInitUnicodeString( &linkString, L"\\DosDevices\\KRNLDRVR" );
131:
132: status = IoCreateSymbolicLink (&linkString, &nameString);
133:
134: if (!NT_SUCCESS( status )) {
135:
136: IoDeleteDevice (DriverObject->DeviceObject);
137: return status;
138: }
139:
140: //
141: // Initialize the driver object with this device driver's entry points.
142: //
143:
144: DriverObject->DriverUnload = KdvrUnloadDriver;
145: DriverObject->MajorFunction[IRP_MJ_CREATE] = KdvrDispatch;
146: DriverObject->MajorFunction[IRP_MJ_CLOSE] = KdvrDispatch;
147: DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = KdvrDispatchIoctl;
148:
149: extension = deviceObject->DeviceExtension;
150:
151: //
152: // Initialize the device extension. This piece of information is
153: // initialized to a recognizable arbitrary value so that we know that
154: // the IOCTL from the DOS app actually worked.
155: //
156:
157: extension->Information = 0x12345678;
158:
159: KrnldrvrDump(KDVRDIAG1, ("Krnldrvr: Initialized\n"));
160:
161: return STATUS_SUCCESS;
162: }
163:
164: VOID
165: KdvrUnloadDriver(
166: IN PDRIVER_OBJECT DriverObject
167: )
168:
169: /*++
170:
171: Routine Description:
172:
173: This is the unload routine for the KRNLDRVR sample device driver.
174: This routine deletes the device object and symbolic link created
175: in the DriverEntry routine.
176:
177: Arguments:
178:
179: DriverObject - Pointer to driver object created by the system.
180:
181: Return Value:
182:
183: The function value is the final status from the initialization operation.
184:
185: --*/
186:
187: {
188: UNICODE_STRING nameString, linkString;
189:
190: KrnldrvrDump(KDVRDIAG1, ("Krnldrvr: Unload\n"));
191:
192: IoDeleteDevice (DriverObject->DeviceObject);
193:
194: RtlInitUnicodeString( &linkString, L"\\DosDevices\\KRNLDRVR" );
195: RtlInitUnicodeString( &nameString, L"\\Device\\Krnldrvr" );
196:
197: IoDeleteSymbolicLink (&linkString);
198:
199: }
200:
201: static
202: NTSTATUS
203: KdvrDispatch(
204: IN PDEVICE_OBJECT DeviceObject,
205: IN PIRP Irp
206: )
207:
208: /*++
209:
210: Routine Description:
211:
212: This routine is the main dispatch routine for this device driver.
213: No real work is done in this sample routine, but output
214: generated here is useful for debugging.
215:
216:
217: Arguments:
218:
219: DeviceObject - Pointer to the device object for this driver.
220: Irp - Pointer to the request packet representing the I/O request.
221:
222: Return Value:
223:
224: The function value is the status of the operation.
225:
226:
227: --*/
228:
229: {
230: NTSTATUS status;
231: PIO_STACK_LOCATION irpSp;
232:
233: UNREFERENCED_PARAMETER( DeviceObject );
234: irpSp = IoGetCurrentIrpStackLocation( Irp );
235:
236: switch (irpSp->MajorFunction) {
237:
238: case IRP_MJ_CREATE:
239:
240: KrnldrvrDump(KDVRDIAG1, ("Krnldrvr: Create\n"));
241: Irp->IoStatus.Status = STATUS_SUCCESS;
242: Irp->IoStatus.Information = 0L;
243: break;
244:
245: case IRP_MJ_CLOSE:
246:
247: KrnldrvrDump(KDVRDIAG1, ("Krnldrvr: Close\n\n"));
248: Irp->IoStatus.Status = STATUS_SUCCESS;
249: Irp->IoStatus.Information = 0L;
250: break;
251:
252: }
253:
254: status = Irp->IoStatus.Status;
255: IoCompleteRequest( Irp, 0 );
256: return status;
257: }
258:
259: static
260: NTSTATUS
261: KdvrDispatchIoctl(
262: IN PDEVICE_OBJECT DeviceObject,
263: IN PIRP Irp
264: )
265:
266: /*++
267:
268: Routine Description:
269:
270: This routine is the dispatch routine for IoDeviceControl().
271: The only supported IOCTL here returns a single DWORD of information.
272:
273: Arguments:
274:
275: DeviceObject - Pointer to the device object for this driver.
276: Irp - Pointer to the request packet representing the I/O request.
277:
278: Return Value:
279:
280: The function value is the status of the operation.
281:
282:
283: --*/
284:
285: {
286: NTSTATUS status;
287: PIO_STACK_LOCATION irpSp;
288: PULONG OutputBuffer;
289: PKDVR_DEVICE_EXTENSION extension = DeviceObject->DeviceExtension;
290:
291:
292: irpSp = IoGetCurrentIrpStackLocation( Irp );
293:
294: switch (irpSp->Parameters.DeviceIoControl.IoControlCode) {
295:
296: case IOCTL_KRNLDRVR_GET_INFORMATION:
297:
298: KrnldrvrDump(KDVRDIAG1, ("Krnldrvr: Processing IOCTL\n"));
299:
300: Irp->IoStatus.Status = STATUS_SUCCESS;
301:
302: OutputBuffer = (PULONG) Irp->AssociatedIrp.SystemBuffer;
303:
304: if (irpSp->Parameters.DeviceIoControl.OutputBufferLength <
305: sizeof(ULONG)) {
306:
307: Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
308: break;
309:
310: }
311:
312: *OutputBuffer = extension->Information;
313:
314: Irp->IoStatus.Information = sizeof( ULONG );
315:
316: break;
317:
318: }
319:
320:
321: status = Irp->IoStatus.Status;
322: IoCompleteRequest( Irp, 0 );
323: return status;
324: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.