微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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 来安装设备驱动程序。

原文地址:https://www.jb51.cc/react/308480.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐