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  

你可能感兴趣的:(reactos操作系统实现(74))