![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 例程是在运行在DISPATCH_LEVEL的IRQL级别 3 例程中不能使用分页内存 4 另外在函数首部使用 #pragma LOCKEDCODE 5 */ 6 7 #include "Driver.h" 8 9 #define DeviceName L"\Device\MyDDKDevice" 10 11 #pragma INITCODE 12 extern "C" NTSTATUS DriverEntry ( 13 IN PDRIVER_OBJECT pDriverObject, 14 IN PUNICODE_STRING pRegistryPath ) 15 { 16 NTSTATUS status; 17 KdPrint(("Enter DriverEntry ")); 18 19 pDriverObject->DriverUnload = UnloadDriver; 20 21 //设置派遣函数 22 23 /* 24 ARRAY_SIZE 定义设备结构体的个数 25 #define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0]) + __must_be_array(arr)) 26 27 */ 28 29 for (int i = 0; i < arraysize(pDriverObject->MajorFunction); ++i) //ARRAY_SIZE 定义设备结构体的个数 30 pDriverObject->MajorFunction[i] = DispatchFunction; 31 32 33 34 pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceIoControl; 35 36 //创建驱动设备对象 37 status = CreateDevice(pDriverObject); 38 39 KdPrint(("Leave DriverEntry ")); 40 return status; 41 } 42 43 #pragma LOCKEDCODE 44 VOID OnTimer( 45 IN PDEVICE_OBJECT DeviceObject, 46 IN PVOID Context) 47 { 48 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION) 49 DeviceObject->DeviceExtension; 50 KdPrint(("Enter OnTimer! ")); 51 52 //将计数器自锁减一 53 InterlockedDecrement(&pDevExt->lTimerCount); 54 55 /*如果计数器减到0,重新编程TIMER_OUT,整个过程是互锁运算 56 LONG __cdecl InterlockedCompareExchange( 57 58 __inout LONG volatile *Destination, //当前值 59 60 __in LONG Exchange, //当比较值与当前值相同时 替换当前值 61 62 __in LONG Comparand //比较值 63 64 PVOID __cdecl InterlockedCompareExchangePointer( 65 66 __inout PVOID volatile *Destination, 67 68 __in PVOID Exchange, 69 70 __in PVOID Comparand 71 72 这两个函数以原子方式执行一个测试和设置操作。对32位应用程序来说,这两个函数都对32位值进行操作; 73 在64位应用程序中,InterlockedCompareExchange对32位值进行操作而InterlockedCompareExchangePointer对64位值进行操作。 74 函数会将当前值(Destination指向的)与参数Comparand进行比较,如果两个值相同,那么函数会将*Destination修改为Exchange参数指定的值。 75 若不等,则*Destination保持不变。函数会返回*Destination原来的值。所有这些操作都是一个原子执行单元来完成的。 76 77 */ 78 LONG previousCount = InterlockedCompareExchange(&pDevExt->lTimerCount,TIMER_OUT,0); 79 80 //每隔三秒,计数器一个循环,输出以下log 81 if (previousCount==0) 82 { 83 KdPrint(("%d seconds time out! ",TIMER_OUT)); 84 } 85 86 //证明该线程运行在任意线程上下文的 87 /* 88 PEPROCESS pEProcess = IoGetCurrentProcess(); 89 PTSTR ProcessName = (PTSTR) ((ULONG)pEProcess + 0x174); 90 */ 91 PEPROCESS pEProcess = IoGetCurrentProcess(); 92 93 PTSTR ProcessName = (PTSTR)((ULONG)pEProcess + 0x174);//即可得到用户进程 94 95 KdPrint(("The current process is %s ",ProcessName)); 96 } 97 98 99 /************************************************************************ 100 * 函数名称:CreateDevice 101 * 功能描述:初始化设备对象 102 * 参数列表: 103 pDriverObject:从I/O管理器中传进来的驱动对象 104 * 返回 值:返回初始化状态 105 *************************************************************************/ 106 #pragma INITCODE 107 NTSTATUS CreateDevice ( 108 IN PDRIVER_OBJECT pDriverObject) 109 { 110 NTSTATUS status; 111 PDEVICE_OBJECT pDevObj; 112 PDEVICE_EXTENSION pDevExt; 113 114 //创建设备名称 115 UNICODE_STRING devName; 116 RtlInitUnicodeString(&devName,DeviceName); 117 118 //创建设备 119 status = IoCreateDevice( pDriverObject, 120 sizeof(DEVICE_EXTENSION), 121 &(UNICODE_STRING)devName, 122 FILE_DEVICE_UNKNOWN, 123 0, TRUE, 124 &pDevObj ); 125 if (!NT_SUCCESS(status)) 126 return status; 127 128 pDevObj->Flags |= DO_DIRECT_IO; 129 pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension; 130 pDevExt->pDevice = pDevObj; 131 pDevExt->ustrDeviceName = devName; 132 133 IoInitializeTimer(pDevObj,OnTimer,NULL); // 初始化IoTimer 134 135 //创建符号链接 136 // 不进行Ring3层的交互 则不需要进行创建符号链接 137 NICODE_STRING symLinkName; 138 RtlInitUnicodeString(&symLinkName,L"\??\HelloDDK"); 139 pDevExt->ustrSymLinkName = symLinkName; 140 status = IoCreateSymbolicLink( &symLinkName,&devName ); 141 if (!NT_SUCCESS(status)) 142 { 143 IoDeleteDevice( pDevObj ); 144 return status; 145 } 146 return STATUS_SUCCESS; 147 } 148 149 /************************************************************************ 150 * 函数名称:HelloDDKUnload 151 * 功能描述:负责驱动程序的卸载操作 152 * 参数列表: 153 pDriverObject:驱动对象 154 * 返回 值:返回状态 155 *************************************************************************/ 156 #pragma PAGEDCODE 157 VOID UnloadDriver (IN PDRIVER_OBJECT pDriverObject) 158 { 159 PDEVICE_OBJECT pNextObj; 160 KdPrint(("Enter DriverUnload ")); 161 pNextObj = pDriverObject->DeviceObject; 162 while (pNextObj != NULL) 163 { 164 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION) 165 pNextObj->DeviceExtension; 166 //删除符号链接 167 UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName; 168 IoDeleteSymbolicLink(&pLinkName); 169 pNextObj = pNextObj->NextDevice; 170 IoDeleteDevice( pDevExt->pDevice ); 171 } 172 } 173 174 /************************************************************************ 175 * 函数名称:HelloDDKDispatchRoutin 176 * 功能描述:对读IRP进行处理 177 * 参数列表: 178 pDevObj:功能设备对象 179 pIrp:从IO请求包 180 181 182 默认派遣例程 183 * 返回 值:返回状态 184 *************************************************************************/ 185 #pragma PAGEDCODE 186 NTSTATUS DispatchFunction(IN PDEVICE_OBJECT pDevObj, 187 IN PIRP pIrp) 188 { 189 190 191 KdPrint(("Enter HelloDDKDispatchRoutin ")); 192 193 PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp); 194 //建立一个字符串数组与IRP类型对应起来 195 static char* irpname[] = 196 { 197 "IRP_MJ_CREATE", 198 "IRP_MJ_CREATE_NAMED_PIPE", 199 "IRP_MJ_CLOSE", 200 "IRP_MJ_READ", 201 "IRP_MJ_WRITE", 202 "IRP_MJ_QUERY_INFORMATION", 203 "IRP_MJ_SET_INFORMATION", 204 "IRP_MJ_QUERY_EA", 205 "IRP_MJ_SET_EA", 206 "IRP_MJ_FLUSH_BUFFERS", 207 "IRP_MJ_QUERY_VOLUME_INFORMATION", 208 "IRP_MJ_SET_VOLUME_INFORMATION", 209 "IRP_MJ_DIRECTORY_CONTROL", 210 "IRP_MJ_FILE_SYSTEM_CONTROL", 211 "IRP_MJ_DEVICE_CONTROL", 212 "IRP_MJ_INTERNAL_DEVICE_CONTROL", 213 "IRP_MJ_SHUTDOWN", 214 "IRP_MJ_LOCK_CONTROL", 215 "IRP_MJ_CLEANUP", 216 "IRP_MJ_CREATE_MAILSLOT", 217 "IRP_MJ_QUERY_SECURITY", 218 "IRP_MJ_SET_SECURITY", 219 "IRP_MJ_POWER", 220 "IRP_MJ_SYSTEM_CONTROL", 221 "IRP_MJ_DEVICE_CHANGE", 222 "IRP_MJ_QUERY_QUOTA", 223 "IRP_MJ_SET_QUOTA", 224 "IRP_MJ_PNP", 225 }; 226 227 UCHAR type = stack->MajorFunction; 228 if (type >= arraysize(irpname)) 229 KdPrint((" - Unknown IRP, major type %X ", type)); 230 else 231 KdPrint((" %s ", irpname[type])); 232 233 NTSTATUS status = STATUS_SUCCESS; 234 // 完成IRP 235 pIrp->IoStatus.Status = status; 236 pIrp->IoStatus.Information = 0; // bytes xfered 237 IoCompleteRequest( pIrp, IO_NO_INCREMENT ); 238 239 KdPrint(("Leave HelloDDKDispatchRoutin ")); 240 241 return status; 242 } 243 244 #pragma PAGEDCODE 245 NTSTATUS DeviceIOControl(IN PDEVICE_OBJECT pDevObj, 246 IN PIRP pIrp) 247 { 248 NTSTATUS status = STATUS_SUCCESS; 249 KdPrint(("Enter HelloDDKDeviceIOControl ")); 250 251 //获得当前IRP堆栈 252 PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp); 253 //得到输入缓冲区大小 254 ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength; 255 //得到输出缓冲区大小 256 ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength; 257 //得到IOCTL码 258 ULONG code = stack->Parameters.DeviceIoControl.IoControlCode; 259 260 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION) 261 pDevObj->DeviceExtension; 262 263 ULONG info = 0; 264 265 switch (code) 266 { // process request 267 case IOCTL_START_TIMER: 268 { 269 KdPrint(("IOCTL_START_TIMER ")); 270 pDevExt->lTimerCount = TIMER_OUT; 271 IoStartTimer(pDevObj); //激活时钟 272 break; 273 } 274 case IOCTL_STOP: 275 { 276 KdPrint(("IOCTL_STOP ")); 277 IoStopTimer(pDevObj); // 停止时钟 278 break; 279 } 280 default: 281 status = STATUS_INVALID_VARIANT; 282 } 283 284 // 完成IRP 285 pIrp->IoStatus.Status = status; 286 pIrp->IoStatus.Information = info; // bytes xfered 287 IoCompleteRequest( pIrp, IO_NO_INCREMENT ); 288 289 KdPrint(("Leave HelloDDKDeviceIOControl ")); 290 291 return status; 292 }