加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

reactos操作系统实现(53)

发布时间:2020-12-15 05:01:27 所属栏目:百科 来源:网络整理
导读:在前面的代码分析里,发现创建一个线程,而这个线程运行的主函数是 PnpEventThread 。那么创建这个线程是用来做什么事情的呢?那就得去分析文件 reactos/base/setup/usetup/interface/devinst.c 里的代码,如下: #001 DWORD WINAPI #002 PnpEventThread(IN

在前面的代码分析里,发现创建一个线程,而这个线程运行的主函数是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 来安装设备驱动程序。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读