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