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