2 * PROJECT: ReactOS Kernel
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: ntoskrnl/io/pnpmgr/pnpinit.c
5 * PURPOSE: PnP Initialization Code
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
15 /* GLOBALS ********************************************************************/
17 PUNICODE_STRING PiInitGroupOrderTable
;
18 ULONG PiInitGroupOrderTableCount
;
20 /* FUNCTIONS ******************************************************************/
24 PiInitCacheGroupInformation(VOID
)
28 PKEY_VALUE_FULL_INFORMATION KeyValueInformation
;
29 PUNICODE_STRING GroupTable
;
31 UNICODE_STRING GroupString
=
32 RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\System\\CurrentControlSet"
33 L
"\\Control\\ServiceGroupOrder");
35 /* ReactOS HACK for SETUPLDR */
36 if (KeLoaderBlock
->SetupLdrBlock
)
39 PiInitGroupOrderTableCount
= 0;
40 PiInitGroupOrderTable
= (PVOID
)0xBABEB00B;
41 return STATUS_SUCCESS
;
44 /* Open the registry key */
45 Status
= IopOpenRegistryKeyEx(&KeyHandle
,
49 if (NT_SUCCESS(Status
))
52 Status
= IopGetRegistryValue(KeyHandle
, L
"List", &KeyValueInformation
);
55 /* Make sure we got it */
56 if (NT_SUCCESS(Status
))
58 /* Make sure it's valid */
59 if ((KeyValueInformation
->Type
== REG_MULTI_SZ
) &&
60 (KeyValueInformation
->DataLength
))
62 /* Convert it to unicode strings */
63 Status
= PnpRegMultiSzToUnicodeStrings(KeyValueInformation
,
67 /* Cache it for later */
68 PiInitGroupOrderTable
= GroupTable
;
69 PiInitGroupOrderTableCount
= Count
;
74 Status
= STATUS_UNSUCCESSFUL
;
77 /* Free the information */
78 ExFreePool(KeyValueInformation
);
88 PpInitGetGroupOrderIndex(IN HANDLE ServiceHandle
)
91 PKEY_VALUE_FULL_INFORMATION KeyValueInformation
;
97 /* Make sure we have a cache */
98 if (!PiInitGroupOrderTable
) return -1;
100 /* If we don't have a handle, the rest is easy -- return the count */
101 if (!ServiceHandle
) return PiInitGroupOrderTableCount
+ 1;
103 /* Otherwise, get the group value */
104 Status
= IopGetRegistryValue(ServiceHandle
, L
"Group", &KeyValueInformation
);
105 if (!NT_SUCCESS(Status
)) return PiInitGroupOrderTableCount
;
107 /* Make sure we have a valid string */
108 ASSERT(KeyValueInformation
->Type
== REG_SZ
);
109 ASSERT(KeyValueInformation
->DataLength
);
111 /* Convert to unicode string */
112 Buffer
= (PVOID
)((ULONG_PTR
)KeyValueInformation
+ KeyValueInformation
->DataOffset
);
113 PnpRegSzToString(Buffer
, KeyValueInformation
->DataLength
, &Group
.Length
);
114 Group
.MaximumLength
= KeyValueInformation
->DataLength
;
115 Group
.Buffer
= Buffer
;
117 /* Loop the groups */
118 for (i
= 0; i
< PiInitGroupOrderTableCount
; i
++)
120 /* Try to find a match */
121 if (RtlEqualUnicodeString(&Group
, &PiInitGroupOrderTable
[i
], TRUE
)) break;
125 ExFreePool(KeyValueInformation
);
131 PipGetDriverTagPriority(IN HANDLE ServiceHandle
)
134 HANDLE KeyHandle
= NULL
;
135 PKEY_VALUE_FULL_INFORMATION KeyValueInformation
= NULL
;
136 PKEY_VALUE_FULL_INFORMATION KeyValueInformationTag
;
137 PKEY_VALUE_FULL_INFORMATION KeyValueInformationGroupOrderList
;
139 UNICODE_STRING Group
;
141 ULONG i
= -1, Count
, Tag
= 0;
142 UNICODE_STRING GroupString
=
143 RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\System\\CurrentControlSet"
144 L
"\\Control\\ServiceGroupOrder");
147 Status
= IopOpenRegistryKeyEx(&KeyHandle
, NULL
, &GroupString
, KEY_READ
);
148 if (!NT_SUCCESS(Status
)) goto Quickie
;
151 Status
= IopGetRegistryValue(ServiceHandle
, L
"Group", &KeyValueInformation
);
152 if (!NT_SUCCESS(Status
)) goto Quickie
;
154 /* Make sure we have a group */
155 if ((KeyValueInformation
->Type
== REG_SZ
) &&
156 (KeyValueInformation
->DataLength
))
158 /* Convert to unicode string */
159 Buffer
= (PVOID
)((ULONG_PTR
)KeyValueInformation
+ KeyValueInformation
->DataOffset
);
160 PnpRegSzToString(Buffer
, KeyValueInformation
->DataLength
, &Group
.Length
);
161 Group
.MaximumLength
= KeyValueInformation
->DataLength
;
162 Group
.Buffer
= Buffer
;
165 /* Now read the tag */
166 Status
= IopGetRegistryValue(ServiceHandle
, L
"Tag", &KeyValueInformationTag
);
167 if (!NT_SUCCESS(Status
)) goto Quickie
;
169 /* Make sure we have a tag */
170 if ((KeyValueInformationTag
->Type
== REG_DWORD
) &&
171 (KeyValueInformationTag
->DataLength
))
174 Tag
= *(PULONG
)((ULONG_PTR
)KeyValueInformationTag
+
175 KeyValueInformationTag
->DataOffset
);
178 /* We can get rid of this now */
179 ExFreePool(KeyValueInformationTag
);
181 /* Now let's read the group's tag order */
182 Status
= IopGetRegistryValue(KeyHandle
,
184 &KeyValueInformationGroupOrderList
);
186 /* We can get rid of this now */
188 if (KeyValueInformation
) ExFreePool(KeyValueInformation
);
189 if (KeyHandle
) NtClose(KeyHandle
);
190 if (!NT_SUCCESS(Status
)) return -1;
192 /* We're on the success path -- validate the tag order*/
193 if ((KeyValueInformationGroupOrderList
->Type
== REG_BINARY
) &&
194 (KeyValueInformationGroupOrderList
->DataLength
))
196 /* Get the order array */
197 GroupOrder
= (PULONG
)((ULONG_PTR
)KeyValueInformationGroupOrderList
+
198 KeyValueInformationGroupOrderList
->DataOffset
);
202 ASSERT(((Count
+ 1) * sizeof(ULONG
)) <=
203 KeyValueInformationGroupOrderList
->DataLength
);
205 /* Now loop each tag */
207 for (i
= 1; i
<= Count
; i
++)
209 /* If we found it, we're out */
210 if (Tag
== *GroupOrder
) break;
212 /* Try the next one */
217 /* Last buffer to free */
218 ExFreePool(KeyValueInformationGroupOrderList
);