|
|
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.