reactos操作系统实现(53)

在前面的代码分析里,发现创建一个线程,而这个线程运行的主函数PnpEventThread。那么创建这个线程是用来做什么事情的呢?那就得去分析文件reactos/base/setup/usetup/interface/devinst.c里的代码,如下:

#001 DWORD WINAPI

#002 PnpEventThread(IN LPVOID lpParameter)

#003 {

#004 NTSTATUS Status;

#005

#006 DPRINT1("Device PnpEventThread 20090721/n");

#007

调用函数EventThread来做真实的事件处理。

#008 Status = EventThread(lpParameter);

调用内核API函数NtTerminateThread来终止线程运行。

#009 NtTerminateThread(NtCurrentThread(),Status);

#010 return 0;

#011 }

继续查看函数EventThread代码

#001 NTSTATUS

#002 EventThread(IN LPVOID lpParameter)

#003 {

初始化两个准备使用的注册表键值。

#004 UNICODE_STRING EnumU = RTL_CONSTANT_STRING(L"//Registry//Machine//SYstem//CurrentControlSet//Enum");

#005 UNICODE_STRING ServicesU = RTL_CONSTANT_STRING(L"//Registry//Machine//SYstem//CurrentControlSet//Services");

#006 PPLUGPLAY_EVENT_BLOCK PnpEvent;

#007 OBJECT_ATTRIBUTES ObjectAttributes;

#008 ULONG PnpEventSize;

#009 HINF hInf;

#010 HANDLE hEnum,hServices;

#011 NTSTATUS Status;

#012

获取参数。

#013 hInf = *(HINF *)lpParameter;

#014

打开系统枚举键。

#015 InitializeObjectAttributes(&ObjectAttributes,&EnumU,OBJ_CASE_INSENSITIVE,NULL,NULL);

#016 Status = NtOpenKey(&hEnum,&ObjectAttributes);

#017 if (!NT_SUCCESS(Status))

#018 {

#019 DPRINT1("NtOpenKey('%wZ') Failed with status 0x%08lx/n",Status);

#020 return Status;

#021 }

#022

创建系统服务键。

#023 InitializeObjectAttributes(&ObjectAttributes,&ServicesU,NULL);

#024 Status = NtCreateKey(&hServices,&ObjectAttributes,NULL);

#025 if (!NT_SUCCESS(Status))

#026 {

#027 DPRINT1("NtCreateKey('%wZ') Failed with status 0x%08lx/n",Status);

#028 NtClose(hEnum);

#029 return Status;

#030 }

#031

分配使用堆内存空间。

#032 PnpEventSize = 0x1000;

#033 PnpEvent = (PPLUGPLAY_EVENT_BLOCK)RtlAllocateHeap(ProcessHeap,PnpEventSize);

#034 if (PnpEvent == NULL)

#035 {

#036 NtClose(hEnum);

#037 NtClose(hServices);

#038 return STATUS_NO_MEMORY;

#039 }

#040

循环地进行线程处理工作。

#041 for (;;)

#042 {

#043 DPRINT("Calling NtGetPlugPlayEvent()/n");

#044

等待下一个即插即用事件。

#045 /* Wait for the next pnp event */

#046 Status = NtGetPlugPlayEvent(0,PnpEvent,PnpEventSize);

#047

是否前面分配的缓冲区太小。

#048 /* Resize the buffer for the PnP event if it's too small. */

#049 if (Status == STATUS_BUFFER_TOO_SMALL)

#050 {

#051 PnpEventSize += 0x400;

#052 RtlFreeHeap(ProcessHeap,PnpEvent);

#053 PnpEvent = (PPLUGPLAY_EVENT_BLOCK)RtlAllocateHeap(ProcessHeap,PnpEventSize);

#054 if (PnpEvent == NULL)

#055 {

#056 NtClose(hEnum);

#057 NtClose(hServices);

#058 return STATUS_NO_MEMORY;

#059 }

#060 continue;

#061 }

#062

等待事件出错处理。

#063 if (!NT_SUCCESS(Status))

#064 {

#065 DPRINT("NtPlugPlayEvent() Failed (Status %lx)/n",Status);

#066 break;

#067 }

#068

处理枚举的设备。

#069 /* Process the pnp event */

#070 DPRINT("Received PnP Event/n");

#071 if (IsEqualIID(&PnpEvent->EventGuid,(REFGUID)&GUID_DEVICE_ENUMERATED))

#072 {

#073 DPRINT1("Device arrival event: %s/n",PnpEvent->TargetDevice.deviceids);

调用函数InstallDevice来安装设备。

#074 InstallDevice(hInf,hEnum,hServices,PnpEvent->TargetDevice.deviceids);

#075 }

#076 else

#077 {

#078 DPRINT("UnkNown event/n");

#079 }

#080

通知可以处理下一个事件。

#081 /* Dequeue the current pnp event and signal the next one */

#082 NtPlugPlayControl(PlugPlayControlUserResponse,0);

#083 }

#084

#085 RtlFreeHeap(ProcessHeap,PnpEvent);

#086 NtClose(hEnum);

#087 NtClose(hServices);

#088

#089 return STATUS_SUCCESS;

#090 }

函数 EventThread 里,主要就是循环地处理设备事件,调用函数 InstallDevice 来安装设备驱动程序。

相关文章

一、前言 在组件方面react和Vue一样的,核心思想玩的就是组件...
前言: 前段时间学习完react后,刚好就接到公司一个react项目...
前言: 最近收到组长通知我们项目组后面新开的项目准备统一技...
react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom...