注册IRP_MJ_SHUTDOWN事件 基于ReactOS0303
发布时间:2020-12-15 03:32:32 所属栏目:百科 来源:网络整理
导读:系统关闭时,会向注册SHUTDOWN事件的设备驱动发送IRP_MJ_SHUTDOWN事件。 NTSTATUS STDCALLNtShutdownSystem(IN SHUTDOWN_ACTION Action){ if (Action ShutdownPowerOff) return STATUS_INVALID_PARAMETER; Status = PsCreateSystemThread(ThreadHandle,THREA
系统关闭时,会向注册SHUTDOWN事件的设备驱动发送IRP_MJ_SHUTDOWN事件。 NTSTATUS STDCALL NtShutdownSystem(IN SHUTDOWN_ACTION Action) { if (Action > ShutdownPowerOff) return STATUS_INVALID_PARAMETER; Status = PsCreateSystemThread(&ThreadHandle,THREAD_ALL_ACCESS,NULL,ShutdownThreadMain,(PVOID)Action); } VOID STDCALL ShutdownThreadMain(PVOID Context) { IoShutdownRegisteredDevices(); } VOID NTAPI IoShutdownRegisteredDevices(VOID) { ListEntry = ExInterlockedRemoveHeadList(&ShutdownListHead,&ShutdownListLock); while (ListEntry) { /* Get the shutdown entry */ ShutdownEntry = CONTAINING_RECORD(ListEntry,SHUTDOWN_ENTRY,ShutdownList); /* Get the attached device */ DeviceObject = IoGetAttachedDevice(ShutdownEntry->DeviceObject); /* Build the shutdown IRP and call the driver */ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN,DeviceObject,&Event,&StatusBlock); Status = IoCallDriver(DeviceObject,Irp); if (Status == STATUS_PENDING) { /* Wait on the driver */ KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL); } /* Free the shutdown entry and reset the event */ ExFreePool(ShutdownEntry); KeClearEvent(&Event); /* Go to the next entry */ ListEntry = ExInterlockedRemoveHeadList(&ShutdownListHead,&ShutdownListLock); } }调用Native API NtShutdownSystem时会遍历ShutdownListHead队列,取出每个元素,这个元素的结构中包含设备对象: typedef struct _SHUTDOWN_ENTRY { LIST_ENTRY ShutdownList; PDEVICE_OBJECT DeviceObject; } SHUTDOWN_ENTRY,*PSHUTDOWN_ENTRY;之后获得这个设备的设备栈深度并以此建立一个类型为IRP_MJ_SHUTDOWN的IRP请求包,以同步的方式发向设备栈的最上层设备。 设备栈中的设备驱动如果注册了IRP_MJ_SHUTDOWN事件那就调用相应的回调,如果没有注册就按默认的方式完成请求或者下发请求。 联系驱动程序注册IRP_MJ_SHUTDOWN事件和IoShutdownRegisteredDevices函数的是IoRegisterShutdownNotification---注册关机通知函数。这个函数新建SHUTDOWN_ENTRY结构,并填入设备对象,然后把SHUTDOWN_ENTRY结构挂入ShutdownListHead队列。 /* * @implemented */ NTSTATUS NTAPI IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject) { PSHUTDOWN_ENTRY Entry; /* Allocate the shutdown entry */ Entry = ExAllocatePoolWithTag(NonPagedPool,sizeof(SHUTDOWN_ENTRY),TAG_SHUTDOWN_ENTRY); if (!Entry) return STATUS_INSUFFICIENT_RESOURCES; Entry->DeviceObject = DeviceObject; /* Insert it into the list */ ExInterlockedInsertHeadList(&ShutdownListHead,&Entry->ShutdownList,&ShutdownListLock); DeviceObject->Flags |= DO_SHUTDOWN_REGISTERED; return STATUS_SUCCESS; } 驱动入口以如下的方式注册关闭通知: DriverEntry(pDriverObject,pRegistryPath) { pDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = Shutdown; IoRegisterShutdownNotification(pDriverObject); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- ruby – 如何安装Command-T,Pathogen,而不是使用RVM?
- 【LeetCode】10. Regular Expression Matching(C++)
- Swift之自定义UITableViewCell
- ruby – Nokogiri剥离所有属性
- 如何对结构的2D动态数组进行排序
- (?:exp)这样匹配表达式exp表示什么意思?
- objective-c – 内存管理:NSString的stringWithCString:e
- Oracle日期类型Date和timestamp需要注意的地方
- Vue2.x中的Render函数详解
- iphone – UIGestureRecognizers的自定义操作(带自定义参数