driver.h
1 #pragma once 2 3 #ifdef __cplusplus 4 extern "C" { 5 #endif 6 7 #include8 9 ifdef __cplusplus 10 } 11 #endif 12 13 14 typedef struct _DEVICE_EXTERSION { 15 PDEVICE_OBJECT fdo; 16 PDEVICE_OBJECT NextStackDevice; 17 UNICODE_STRING ustrDeviceName; 18 UNICODE_STRING ustrSymLinkName; 19 } DEVICE_EXTERSION, *PDEVICE_EXTERSION; 20 21 NTSTATUS DriverEntry( IN PDRIVER_OBJECT, IN PUNICODE_STRING ); 22 NTSTATUS AddDevice( IN PDRIVER_OBJECT, IN PDEVICE_OBJECT ); 23 NTSTATUS Pnp( IN PDEVICE_OBJECT, IN PIRP ); 24 NTSTATUS Dispatch( IN PDEVICE_OBJECT, IN PIRP ); 25 VOID DriverUnload( IN PDRIVER_OBJECT );
driver.c
1 #include "driver.h" 2 3 #pragma code_seg("INIT") 4 EXTERN_C NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject, 5 IN PUNICODE_STRING pRegistryPath ) 6 { 7 KdPrint(("Entry DriverEntry\n")); 8 9 pDriverObject->DriverExtension->AddDevice = AddDevice; 10 pDriverObject->MajorFunction[IRP_MJ_PNP] = Pnp; 11 pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = 12 pDriverObject->MajorFunction[IRP_MJ_CREATE] = 13 pDriverObject->MajorFunction[IRP_MJ_CLOSE] = 14 pDriverObject->MajorFunction[IRP_MJ_WRITE] = 15 pDriverObject->MajorFunction[IRP_MJ_READ] = Dispatch; 16 pDriverObject->DriverUnload = DriverUnload; 17 18 KdPrint(("Leave DriverEntry\n")); 19 return STATUS_SUCCESS; 20 } 21 22 #pragma code_seg("PAGE") 23 NTSTATUS AddDevice( IN PDRIVER_OBJECT DriverObject, 24 IN PDEVICE_OBJECT PhysicalDeviceObject ) 25 { 26 PAGED_CODE(); 27 KdPrint(("Enter AddDevice")); 28 29 NTSTATUS status; 30 PDEVICE_OBJECT fdo; 31 UNICODE_STRING devName; 32 RtlInitUnicodeString(&devName, L"\\Device\\MyWdmDevice"); 33 status = IoCreateDevice( 34 DriverObject, 35 sizeof(DEVICE_EXTERSION), 36 &(UNICODE_STRING)devName, 37 FILE_DEVICE_UNKNOWN, 38 0, 39 FALSE, 40 &fdo ); 41 if (!NT_SUCCESS(status)) { 42 return status; 43 } 44 45 PDEVICE_EXTERSION pdx = (PDEVICE_EXTERSION)fdo->DeviceExtension; 46 pdx->fdo = fdo; 47 pdx->NextStackDevice = IoAttachDeviceToDeviceStack( fdo, PhysicalDeviceObject ); 48 UNICODE_STRING = symLinkName; 49 RtlInitUnicodeString( &symLinkName, L"\\DosDevices\\HelloWDM"); 50 51 pdx->ustrDeviceName = devName; 52 pdx->ustrSymLinkName = symLinkName; 53 status = IoCreateUnprotectedSymbolicLink( &(UNICODE_STRING)symLinkName, &(UNICODE_STRING)devName ); 54 55 if (!NT_SUCCESS(status)) { 56 IoCreateUnprotectedSymbolicLink( &pdx->ustrSymLinkName ); 57 status = IoCreateSymbolicLink( &symLinkName, &devName ); 58 if (!NT_SUCCESS(status)) { 59 return status; 60 } 61 } 62 63 fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE; 64 fdo->Flags &= ~DO_DEVICE_INITIALIZING; 65 66 KdPrint(("Leave AddDevice\n")); 67 return STATUS_SUCCESS; 68 } 69 70 71 72 #pragma code_seg("PAGE") 73 NTSTATUS DefaultPnpHandler( PDEVICE_EXTERSION pdx, PIRP Irp ) 74 { 75 PAGED_CODE(); 76 KdPrint(("Enter DefaultPnpHandler\n")); 77 IoSkipCurrentIrpStackLocation( Irp ); 78 KdPrint(("Leave DefaultPnpHandler\n")); 79 return IoCallDriver( pdx->NextStackDevice, Irp ); 80 } 81 82 #pragma code_seg("PAGE") 83 NTSTATUS HandleRemoveDevice( PDEVICE_EXTERSION pdx, PIRP Irp ) 84 { 85 PAGED_CODE(); 86 KdPrint(("Enter HandleRemoveDevice\n")); 87 88 Irp->IoStatus.Status = STATUS_SUCCESS; 89 NTSTATUS status = DefaultPnpHandler( pdx, Irp ); 90 IoDeleteSymbolicLink( &(UNICODE_STRING)pdx->ustrSymLinkName ); 91 92 if (pdx->NextStackDevice) { 93 IoDetachDevice( pdx->NextStackDevice ); 94 } 95 96 IoDetachDevice( pdx->fdo ); 97 KdPrint(("Leave HandleRemoveDevice\n")); 98 return status; 99 } 100 101 102 #pragma code_seg("PAGE") 103 NTSTATUS Pnp( IN PDEVICE_OBJECT fdo, 104 IN PIRP Irp) 105 { 106 PAGED_CODE(); 107 108 KdPrint(("Enter Pnp\n")); 109 NTSTATUS status = STATUS_SUCCESS; 110 PDEVICE_EXTERSION pdx = (PDEVICE_EXTERSION)fdo->DeviceExtension; 111 PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); 112 static NTSTATUS (*fcntab[])(PDEVICE_EXTERSION pdx, PIRP Irp) = 113 { 114 DefaultPnpHandler, // IRP_MN_STACK_DEVICE 115 DefaultPnpHandler, // IRP_MN_QUERY_REMOVE_DEVICE 116 HandleRemoveDevice, // IRP_MN_REMOVE_DEVICE 117 DefaultPnpHandler, // IRP_MN_CANCEL_REMOVE_DEVICE 118 DefaultPnpHandler, // IRP_MN_STOP_DEVICE 119 DefaultPnpHandler, // IRP_MN_QUERY_STOP_DEVICE 120 DefaultPnpHandler, // IRP_MN_CANCEL_STOP_DEVICE 121 DefaultPnpHandler, // IRP_MN_QUERY_DEVICE_RELATIONS 122 DefaultPnpHandler, // IRP_MN_QUERY_INTERFACE 123 DefaultPnpHandler, // IRP_MN_QUERY_CAPABILITIES 124 DefaultPnpHandler, // IRP_MN_QUERY_RESOURCES 125 DefaultPnpHandler, // IRP_MN_QUERY_RESOURCE_REQUIREMENTS 126 DefaultPnpHandler, // IRP_MN_QUERY_DEVICE_TEXT 127 DefaultPnpHandler, // IRP_MN_FILTER_RESOURCE_REQUIREMENTS 128 DefaultPnpHandler, // IRP_MN_ 129 DefaultPnpHandler, // IRP_MN_READ_CONFIG 130 DefaultPnpHandler, // IRP_MN_EJECT 131 DefaultPnpHandler, // IRP_MN_SET_LOCK 132 DefaultPnpHandler, // IRP_MN_QUERY_ID 133 DefaultPnpHandler, // IRP_MN_QUERY_PNP_DEVICE_STATE 134 DefaultPnpHandler, // IRP_MN_QUERY_BUS_INFORMATION 135 DefaultPnpHandler, // IRP_MN_DEVICE_USAGE_NOTIFICATION 136 DefaultPnpHandler, // IRP_MN_SURPRISE_REMOVAL 137 }; 138 139 ULONG fcn = stack->MinorFunction; 140 if (fcn >= sizeof(fcntab)/sizeof(fcntab[0])) { 141 status = DefaultPnpHandler( pdx, Irp ); 142 return status; 143 } 144 145 status = (*fcntab[fcn])(pdx, Irp); 146 KdPrint(("Leave Pnp\n")); 147 return status; 148 } 149 150 151 #pragma code_seg("PAGE") 152 NTSTATUS Dispatch( IN PDEVICE_OBJECT fdo, 153 IN PIRP Irp ) 154 { 155 PAGED_CODE(); 156 KdPrint(("Enter DispatchRoutine\n")); 157 Irp->IoStatus.Status = STATUS_SUCCESS; 158 Irp->IoStatus.Information = 0; 159 IoCompleteRequest( Irp, IO_NO_INCREMENT ); 160 KdPrint(("Leave DispatchRoutine\n")); 161 return STATUS_SUCCESS; 162 } 163 164 165 #pragma code_seg("PAGE") 166 VOID DriverUnload( IN PDRIVER_OBJECT DriverObject ) 167 { 168 PAGED_CODE(); 169 KdPrint(("Enter DriverUnload\n")); 170 KdPrint(("Leave DriverUnload\n")); 171 }