首页 >> 编程开发 >> 其他 >> 正文

reactos操作系统实现(74)

  很多驱动程序,都是通过硬件检测时写到注册表里保存起来的,因此读取注册表里键值列表,就知道有多少设备需要需要加载了。下面就从注册表里创建一组驱动程序列表,实现的代码如下:

#001  NTSTATUS INIT_FUNCTION
#002  IoCreateDriverList(VOID)
#003  {
#004       RTL_QUERY_REGISTRY_TABLE QueryTable[2];
#005       PKEY_BASIC_INFORMATION KeyInfo = NULL;
#006       OBJECT_ATTRIBUTES ObjectAttributes;

  注册表里的键。

#007       UNICODE_STRING ServicesKeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services");
#008       UNICODE_STRING SubKeyName;
#009       HANDLE KeyHandle;
#010       NTSTATUS Status;
#011       ULONG Index;
#012 
#013       ULONG KeyInfoLength = 0;
#014       ULONG ReturnedLength;
#015 
#016       DPRINT("IoCreateDriverList() called\n");
#017 

  初始化全局变量的驱动程序组和服务列表。

#018       /* Initialize basic variables */
#019       InitializeListHead(&GroupListHead);
#020       InitializeListHead(&ServiceListHead);
#021 

  清空查询表的数据。

#022       /* Build group order list */
#023       RtlZeroMemory(&QueryTable,
#024              sizeof(QueryTable));
#025 

  设置查询的名称。

#026       QueryTable[0].Name = L"List";

  设置查询的回调函数。

#027       QueryTable[0].QueryRoutine = IopCreateGroupListEntry;
#028 

  建立组列表。

#029       Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
#030              L"ServiceGroupOrder",
#031              QueryTable,
#032              NULL,
#033              NULL);
#034       if (!NT_SUCCESS(Status))
#035              return(Status);
#036 

  枚举服务和创建服务列表。

#037       /* Enumerate services and create the service list */
#038       InitializeObjectAttributes(&ObjectAttributes,
#039              &ServicesKeyName,
#040              OBJ_CASE_INSENSITIVE,
#041              NULL,
#042              NULL);
#043 

  打开注册表的键。

#044       Status = ZwOpenKey(&KeyHandle,
#045              KEY_ENUMERATE_SUB_KEYS,
#046              &ObjectAttributes);
#047       if (!NT_SUCCESS(Status))
#048       {
#049              return(Status);
#050       }
#051 
#052       KeyInfoLength = sizeof(KEY_BASIC_INFORMATION) + MAX_PATH * sizeof(WCHAR);
#053       KeyInfo = ExAllocatePool(NonPagedPool, KeyInfoLength);
#054       if (KeyInfo == NULL)
#055       {
#056              ZwClose(KeyHandle);
#057              return(STATUS_INSUFFICIENT_RESOURCES);
#058       }
#059 
#060       Index = 0;

  循环地枚举所有注册表里的键。

#061       while (TRUE)
#062       {
#063              Status = ZwEnumerateKey(KeyHandle,
#064                     Index,
#065                     KeyBasicInformation,
#066                     KeyInfo,
#067                     KeyInfoLength,
#068                     &ReturnedLength);
#069              if (NT_SUCCESS(Status))
#070              {
#071                     if (KeyInfo->NameLength < MAX_PATH * sizeof(WCHAR))
#072                     {
#073 
#074                            SubKeyName.Length = (USHORT)KeyInfo->NameLength;
#075                            SubKeyName.MaximumLength = (USHORT)KeyInfo->NameLength + sizeof(WCHAR);
#076                            SubKeyName.Buffer = KeyInfo->Name;
#077                            SubKeyName.Buffer[SubKeyName.Length / sizeof(WCHAR)] = 0;
#078 
#079                            DPRINT("KeyName: '%wZ'\n", &SubKeyName);

  每个子键都创建一个入口,保存到全局变量ServiceListHead里。

#080                            IopCreateServiceListEntry(&SubKeyName);
#081                     }
#082              }
#083 
#084              if (!NT_SUCCESS(Status))
#085                     break;
#086 
#087              Index++;
#088       }
#089 
#090       ExFreePool(KeyInfo);
#091       ZwClose(KeyHandle);
#092 
#093       DPRINT("IoCreateDriverList() done\n");
#094 
#095       return(STATUS_SUCCESS);
#096  }
#097