1c2c66affSColin Finck /*
2c2c66affSColin Finck * PROJECT: ReactOS Kernel
3c2c66affSColin Finck * LICENSE: BSD - See COPYING.ARM in the top level directory
4c2c66affSColin Finck * FILE: ntoskrnl/io/pnpmgr/pnpinit.c
5c2c66affSColin Finck * PURPOSE: PnP Initialization Code
6c2c66affSColin Finck * PROGRAMMERS: ReactOS Portable Systems Group
7c2c66affSColin Finck */
8c2c66affSColin Finck
9c2c66affSColin Finck /* INCLUDES *******************************************************************/
10c2c66affSColin Finck
11c2c66affSColin Finck #include <ntoskrnl.h>
12c2c66affSColin Finck #define NDEBUG
13c2c66affSColin Finck #include <debug.h>
14c2c66affSColin Finck
15c2c66affSColin Finck /* GLOBALS ********************************************************************/
16c2c66affSColin Finck
17c2c66affSColin Finck PUNICODE_STRING PiInitGroupOrderTable;
18c2c66affSColin Finck USHORT PiInitGroupOrderTableCount;
19c2c66affSColin Finck INTERFACE_TYPE PnpDefaultInterfaceType;
202839c850SVictor Perevertkin BOOLEAN PnPBootDriversLoaded = FALSE;
21e5254974SVictor Perevertkin BOOLEAN PnPBootDriversInitialized = FALSE;
22c2c66affSColin Finck
23374f2b4dSVadim Galyant ARBITER_INSTANCE IopRootBusNumberArbiter;
24374f2b4dSVadim Galyant ARBITER_INSTANCE IopRootIrqArbiter;
25374f2b4dSVadim Galyant ARBITER_INSTANCE IopRootDmaArbiter;
26374f2b4dSVadim Galyant ARBITER_INSTANCE IopRootMemArbiter;
27374f2b4dSVadim Galyant ARBITER_INSTANCE IopRootPortArbiter;
28374f2b4dSVadim Galyant
292839c850SVictor Perevertkin extern KEVENT PiEnumerationFinished;
302839c850SVictor Perevertkin
31374f2b4dSVadim Galyant NTSTATUS NTAPI IopPortInitialize(VOID);
32374f2b4dSVadim Galyant NTSTATUS NTAPI IopMemInitialize(VOID);
33374f2b4dSVadim Galyant NTSTATUS NTAPI IopDmaInitialize(VOID);
34374f2b4dSVadim Galyant NTSTATUS NTAPI IopIrqInitialize(VOID);
35374f2b4dSVadim Galyant NTSTATUS NTAPI IopBusNumberInitialize(VOID);
36374f2b4dSVadim Galyant
37c2c66affSColin Finck /* FUNCTIONS ******************************************************************/
38c2c66affSColin Finck
39c2c66affSColin Finck INTERFACE_TYPE
40c2c66affSColin Finck NTAPI
IopDetermineDefaultInterfaceType(VOID)41c2c66affSColin Finck IopDetermineDefaultInterfaceType(VOID)
42c2c66affSColin Finck {
43c2c66affSColin Finck /* FIXME: ReactOS doesn't support MicroChannel yet */
44c2c66affSColin Finck return Isa;
45c2c66affSColin Finck }
46c2c66affSColin Finck
47c2c66affSColin Finck NTSTATUS
48c2c66affSColin Finck NTAPI
IopInitializeArbiters(VOID)49c2c66affSColin Finck IopInitializeArbiters(VOID)
50c2c66affSColin Finck {
51374f2b4dSVadim Galyant NTSTATUS Status;
52374f2b4dSVadim Galyant
53374f2b4dSVadim Galyant Status = IopPortInitialize();
54374f2b4dSVadim Galyant if (!NT_SUCCESS(Status))
55374f2b4dSVadim Galyant {
56374f2b4dSVadim Galyant DPRINT1("IopPortInitialize() return %X\n", Status);
57374f2b4dSVadim Galyant return Status;
58c2c66affSColin Finck }
59c2c66affSColin Finck
60374f2b4dSVadim Galyant Status = IopMemInitialize();
61374f2b4dSVadim Galyant if (!NT_SUCCESS(Status))
62374f2b4dSVadim Galyant {
63374f2b4dSVadim Galyant DPRINT1("IopMemInitialize() return %X\n", Status);
64374f2b4dSVadim Galyant return Status;
65374f2b4dSVadim Galyant }
66374f2b4dSVadim Galyant
67374f2b4dSVadim Galyant Status = IopDmaInitialize();
68374f2b4dSVadim Galyant if (!NT_SUCCESS(Status))
69374f2b4dSVadim Galyant {
70374f2b4dSVadim Galyant DPRINT1("IopDmaInitialize() return %X\n", Status);
71374f2b4dSVadim Galyant return Status;
72374f2b4dSVadim Galyant }
73374f2b4dSVadim Galyant
74374f2b4dSVadim Galyant Status = IopIrqInitialize();
75374f2b4dSVadim Galyant if (!NT_SUCCESS(Status))
76374f2b4dSVadim Galyant {
77374f2b4dSVadim Galyant DPRINT1("IopIrqInitialize() return %X\n", Status);
78374f2b4dSVadim Galyant return Status;
79374f2b4dSVadim Galyant }
80374f2b4dSVadim Galyant
81374f2b4dSVadim Galyant Status = IopBusNumberInitialize();
82374f2b4dSVadim Galyant if (!NT_SUCCESS(Status))
83374f2b4dSVadim Galyant {
84374f2b4dSVadim Galyant DPRINT1("IopBusNumberInitialize() return %X\n", Status);
85374f2b4dSVadim Galyant }
86374f2b4dSVadim Galyant
87374f2b4dSVadim Galyant return Status;
88374f2b4dSVadim Galyant }
89374f2b4dSVadim Galyant
90374f2b4dSVadim Galyant
915c7ce447SVictor Perevertkin CODE_SEG("INIT")
92c2c66affSColin Finck NTSTATUS
93c2c66affSColin Finck NTAPI
PiInitCacheGroupInformation(VOID)94c2c66affSColin Finck PiInitCacheGroupInformation(VOID)
95c2c66affSColin Finck {
96c2c66affSColin Finck HANDLE KeyHandle;
97c2c66affSColin Finck NTSTATUS Status;
98c2c66affSColin Finck PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
99c2c66affSColin Finck PUNICODE_STRING GroupTable;
100c2c66affSColin Finck ULONG Count;
101c2c66affSColin Finck UNICODE_STRING GroupString =
102c2c66affSColin Finck RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet"
103c2c66affSColin Finck L"\\Control\\ServiceGroupOrder");
104c2c66affSColin Finck
105c2c66affSColin Finck /* Open the registry key */
106c2c66affSColin Finck Status = IopOpenRegistryKeyEx(&KeyHandle,
107c2c66affSColin Finck NULL,
108c2c66affSColin Finck &GroupString,
109c2c66affSColin Finck KEY_READ);
110c2c66affSColin Finck if (NT_SUCCESS(Status))
111c2c66affSColin Finck {
112c2c66affSColin Finck /* Get the list */
113c2c66affSColin Finck Status = IopGetRegistryValue(KeyHandle, L"List", &KeyValueInformation);
114c2c66affSColin Finck ZwClose(KeyHandle);
115c2c66affSColin Finck
116c2c66affSColin Finck /* Make sure we got it */
117c2c66affSColin Finck if (NT_SUCCESS(Status))
118c2c66affSColin Finck {
119c2c66affSColin Finck /* Make sure it's valid */
120c2c66affSColin Finck if ((KeyValueInformation->Type == REG_MULTI_SZ) &&
121c2c66affSColin Finck (KeyValueInformation->DataLength))
122c2c66affSColin Finck {
123c2c66affSColin Finck /* Convert it to unicode strings */
124c2c66affSColin Finck Status = PnpRegMultiSzToUnicodeStrings(KeyValueInformation,
125c2c66affSColin Finck &GroupTable,
126c2c66affSColin Finck &Count);
127c2c66affSColin Finck
128c2c66affSColin Finck /* Cache it for later */
129c2c66affSColin Finck PiInitGroupOrderTable = GroupTable;
130c2c66affSColin Finck PiInitGroupOrderTableCount = (USHORT)Count;
131c2c66affSColin Finck }
132c2c66affSColin Finck else
133c2c66affSColin Finck {
134c2c66affSColin Finck /* Fail */
135c2c66affSColin Finck Status = STATUS_UNSUCCESSFUL;
136c2c66affSColin Finck }
137c2c66affSColin Finck
138c2c66affSColin Finck /* Free the information */
139c2c66affSColin Finck ExFreePool(KeyValueInformation);
140c2c66affSColin Finck }
141c2c66affSColin Finck }
142c2c66affSColin Finck
143c2c66affSColin Finck /* Return status */
144c2c66affSColin Finck return Status;
145c2c66affSColin Finck }
146c2c66affSColin Finck
147c2c66affSColin Finck USHORT
148c2c66affSColin Finck NTAPI
PpInitGetGroupOrderIndex(IN HANDLE ServiceHandle)149c2c66affSColin Finck PpInitGetGroupOrderIndex(IN HANDLE ServiceHandle)
150c2c66affSColin Finck {
151c2c66affSColin Finck NTSTATUS Status;
152c2c66affSColin Finck PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
153c2c66affSColin Finck USHORT i;
154c2c66affSColin Finck PVOID Buffer;
155c2c66affSColin Finck UNICODE_STRING Group;
156c2c66affSColin Finck PAGED_CODE();
157c2c66affSColin Finck
158c2c66affSColin Finck /* Make sure we have a cache */
159c2c66affSColin Finck if (!PiInitGroupOrderTable) return -1;
160c2c66affSColin Finck
161c2c66affSColin Finck /* If we don't have a handle, the rest is easy -- return the count */
162c2c66affSColin Finck if (!ServiceHandle) return PiInitGroupOrderTableCount + 1;
163c2c66affSColin Finck
164c2c66affSColin Finck /* Otherwise, get the group value */
165c2c66affSColin Finck Status = IopGetRegistryValue(ServiceHandle, L"Group", &KeyValueInformation);
166c2c66affSColin Finck if (!NT_SUCCESS(Status)) return PiInitGroupOrderTableCount;
167c2c66affSColin Finck
168c2c66affSColin Finck /* Make sure we have a valid string */
169c2c66affSColin Finck ASSERT(KeyValueInformation->Type == REG_SZ);
170c2c66affSColin Finck ASSERT(KeyValueInformation->DataLength);
171c2c66affSColin Finck
172c2c66affSColin Finck /* Convert to unicode string */
173c2c66affSColin Finck Buffer = (PVOID)((ULONG_PTR)KeyValueInformation + KeyValueInformation->DataOffset);
174c2c66affSColin Finck PnpRegSzToString(Buffer, KeyValueInformation->DataLength, &Group.Length);
175c2c66affSColin Finck Group.MaximumLength = (USHORT)KeyValueInformation->DataLength;
176c2c66affSColin Finck Group.Buffer = Buffer;
177c2c66affSColin Finck
178c2c66affSColin Finck /* Loop the groups */
179c2c66affSColin Finck for (i = 0; i < PiInitGroupOrderTableCount; i++)
180c2c66affSColin Finck {
181c2c66affSColin Finck /* Try to find a match */
182c2c66affSColin Finck if (RtlEqualUnicodeString(&Group, &PiInitGroupOrderTable[i], TRUE)) break;
183c2c66affSColin Finck }
184c2c66affSColin Finck
185c2c66affSColin Finck /* We're done */
186c2c66affSColin Finck ExFreePool(KeyValueInformation);
187c2c66affSColin Finck return i;
188c2c66affSColin Finck }
189c2c66affSColin Finck
190c2c66affSColin Finck USHORT
191c2c66affSColin Finck NTAPI
PipGetDriverTagPriority(IN HANDLE ServiceHandle)192c2c66affSColin Finck PipGetDriverTagPriority(IN HANDLE ServiceHandle)
193c2c66affSColin Finck {
194c2c66affSColin Finck NTSTATUS Status;
195c2c66affSColin Finck HANDLE KeyHandle = NULL;
196c2c66affSColin Finck PKEY_VALUE_FULL_INFORMATION KeyValueInformation = NULL;
197c2c66affSColin Finck PKEY_VALUE_FULL_INFORMATION KeyValueInformationTag;
198c2c66affSColin Finck PKEY_VALUE_FULL_INFORMATION KeyValueInformationGroupOrderList;
199c2c66affSColin Finck PVOID Buffer;
200c2c66affSColin Finck UNICODE_STRING Group;
201c2c66affSColin Finck PULONG GroupOrder;
202c2c66affSColin Finck ULONG Count, Tag = 0;
203c2c66affSColin Finck USHORT i = -1;
204c2c66affSColin Finck UNICODE_STRING GroupString =
205c2c66affSColin Finck RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet"
206c2c66affSColin Finck L"\\Control\\ServiceGroupOrder");
207c2c66affSColin Finck
208c2c66affSColin Finck /* Open the key */
209c2c66affSColin Finck Status = IopOpenRegistryKeyEx(&KeyHandle, NULL, &GroupString, KEY_READ);
210c2c66affSColin Finck if (!NT_SUCCESS(Status)) goto Quickie;
211c2c66affSColin Finck
212c2c66affSColin Finck /* Read the group */
213c2c66affSColin Finck Status = IopGetRegistryValue(ServiceHandle, L"Group", &KeyValueInformation);
214c2c66affSColin Finck if (!NT_SUCCESS(Status)) goto Quickie;
215c2c66affSColin Finck
216c2c66affSColin Finck /* Make sure we have a group */
217c2c66affSColin Finck if ((KeyValueInformation->Type == REG_SZ) &&
218c2c66affSColin Finck (KeyValueInformation->DataLength))
219c2c66affSColin Finck {
220c2c66affSColin Finck /* Convert to unicode string */
221c2c66affSColin Finck Buffer = (PVOID)((ULONG_PTR)KeyValueInformation + KeyValueInformation->DataOffset);
222c2c66affSColin Finck PnpRegSzToString(Buffer, KeyValueInformation->DataLength, &Group.Length);
223c2c66affSColin Finck Group.MaximumLength = (USHORT)KeyValueInformation->DataLength;
224c2c66affSColin Finck Group.Buffer = Buffer;
225c2c66affSColin Finck }
226c2c66affSColin Finck
227c2c66affSColin Finck /* Now read the tag */
228c2c66affSColin Finck Status = IopGetRegistryValue(ServiceHandle, L"Tag", &KeyValueInformationTag);
229c2c66affSColin Finck if (!NT_SUCCESS(Status)) goto Quickie;
230c2c66affSColin Finck
231c2c66affSColin Finck /* Make sure we have a tag */
232c2c66affSColin Finck if ((KeyValueInformationTag->Type == REG_DWORD) &&
233c2c66affSColin Finck (KeyValueInformationTag->DataLength))
234c2c66affSColin Finck {
235c2c66affSColin Finck /* Read it */
236c2c66affSColin Finck Tag = *(PULONG)((ULONG_PTR)KeyValueInformationTag +
237c2c66affSColin Finck KeyValueInformationTag->DataOffset);
238c2c66affSColin Finck }
239c2c66affSColin Finck
240c2c66affSColin Finck /* We can get rid of this now */
241c2c66affSColin Finck ExFreePool(KeyValueInformationTag);
242c2c66affSColin Finck
243c2c66affSColin Finck /* Now let's read the group's tag order */
244c2c66affSColin Finck Status = IopGetRegistryValue(KeyHandle,
245c2c66affSColin Finck Group.Buffer,
246c2c66affSColin Finck &KeyValueInformationGroupOrderList);
247c2c66affSColin Finck
248c2c66affSColin Finck /* We can get rid of this now */
249c2c66affSColin Finck Quickie:
250c2c66affSColin Finck if (KeyValueInformation) ExFreePool(KeyValueInformation);
251c2c66affSColin Finck if (KeyHandle) NtClose(KeyHandle);
252c2c66affSColin Finck if (!NT_SUCCESS(Status)) return -1;
253c2c66affSColin Finck
254c2c66affSColin Finck /* We're on the success path -- validate the tag order*/
255c2c66affSColin Finck if ((KeyValueInformationGroupOrderList->Type == REG_BINARY) &&
256c2c66affSColin Finck (KeyValueInformationGroupOrderList->DataLength))
257c2c66affSColin Finck {
258c2c66affSColin Finck /* Get the order array */
259c2c66affSColin Finck GroupOrder = (PULONG)((ULONG_PTR)KeyValueInformationGroupOrderList +
260c2c66affSColin Finck KeyValueInformationGroupOrderList->DataOffset);
261c2c66affSColin Finck
262c2c66affSColin Finck /* Get the count */
263c2c66affSColin Finck Count = *GroupOrder;
264c2c66affSColin Finck ASSERT(((Count + 1) * sizeof(ULONG)) <=
265c2c66affSColin Finck KeyValueInformationGroupOrderList->DataLength);
266c2c66affSColin Finck
267c2c66affSColin Finck /* Now loop each tag */
268c2c66affSColin Finck GroupOrder++;
269c2c66affSColin Finck for (i = 1; i <= Count; i++)
270c2c66affSColin Finck {
271c2c66affSColin Finck /* If we found it, we're out */
272c2c66affSColin Finck if (Tag == *GroupOrder) break;
273c2c66affSColin Finck
274c2c66affSColin Finck /* Try the next one */
275c2c66affSColin Finck GroupOrder++;
276c2c66affSColin Finck }
277c2c66affSColin Finck }
278c2c66affSColin Finck
279c2c66affSColin Finck /* Last buffer to free */
280c2c66affSColin Finck ExFreePool(KeyValueInformationGroupOrderList);
281c2c66affSColin Finck return i;
282c2c66affSColin Finck }
283c2c66affSColin Finck
2845c7ce447SVictor Perevertkin CODE_SEG("INIT")
285c2c66affSColin Finck NTSTATUS
286c2c66affSColin Finck NTAPI
IopInitializePlugPlayServices(VOID)287c2c66affSColin Finck IopInitializePlugPlayServices(VOID)
288c2c66affSColin Finck {
289c2c66affSColin Finck NTSTATUS Status;
290c2c66affSColin Finck ULONG Disposition;
291c2c66affSColin Finck HANDLE KeyHandle, EnumHandle, ParentHandle, TreeHandle, ControlHandle;
292c2c66affSColin Finck UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET");
293c2c66affSColin Finck UNICODE_STRING PnpManagerDriverName = RTL_CONSTANT_STRING(DRIVER_ROOT_NAME L"PnpManager");
294c2c66affSColin Finck PDEVICE_OBJECT Pdo;
295c2c66affSColin Finck
296c2c66affSColin Finck /* Initialize locks and such */
297c2c66affSColin Finck KeInitializeSpinLock(&IopDeviceTreeLock);
298121146e6SThomas Faber KeInitializeSpinLock(&IopDeviceActionLock);
299121146e6SThomas Faber InitializeListHead(&IopDeviceActionRequestList);
3002839c850SVictor Perevertkin KeInitializeEvent(&PiEnumerationFinished, NotificationEvent, TRUE);
301c2c66affSColin Finck
302c2c66affSColin Finck /* Get the default interface */
303c2c66affSColin Finck PnpDefaultInterfaceType = IopDetermineDefaultInterfaceType();
304c2c66affSColin Finck
305c2c66affSColin Finck /* Initialize arbiters */
306c2c66affSColin Finck Status = IopInitializeArbiters();
307c2c66affSColin Finck if (!NT_SUCCESS(Status)) return Status;
308c2c66affSColin Finck
309c2c66affSColin Finck /* Setup the group cache */
310c2c66affSColin Finck Status = PiInitCacheGroupInformation();
311c2c66affSColin Finck if (!NT_SUCCESS(Status)) return Status;
312c2c66affSColin Finck
313c2c66affSColin Finck /* Open the current control set */
314c2c66affSColin Finck Status = IopOpenRegistryKeyEx(&KeyHandle,
315c2c66affSColin Finck NULL,
316c2c66affSColin Finck &KeyName,
317c2c66affSColin Finck KEY_ALL_ACCESS);
318c2c66affSColin Finck if (!NT_SUCCESS(Status)) return Status;
319c2c66affSColin Finck
320c2c66affSColin Finck /* Create the control key */
321c2c66affSColin Finck RtlInitUnicodeString(&KeyName, L"Control");
322c2c66affSColin Finck Status = IopCreateRegistryKeyEx(&ControlHandle,
323c2c66affSColin Finck KeyHandle,
324c2c66affSColin Finck &KeyName,
325c2c66affSColin Finck KEY_ALL_ACCESS,
326c2c66affSColin Finck REG_OPTION_NON_VOLATILE,
327c2c66affSColin Finck &Disposition);
328c2c66affSColin Finck if (!NT_SUCCESS(Status)) return Status;
329c2c66affSColin Finck
330c2c66affSColin Finck /* Check if it's a new key */
331c2c66affSColin Finck if (Disposition == REG_CREATED_NEW_KEY)
332c2c66affSColin Finck {
333c2c66affSColin Finck HANDLE DeviceClassesHandle;
334c2c66affSColin Finck
335c2c66affSColin Finck /* Create the device classes key */
336c2c66affSColin Finck RtlInitUnicodeString(&KeyName, L"DeviceClasses");
337c2c66affSColin Finck Status = IopCreateRegistryKeyEx(&DeviceClassesHandle,
338c2c66affSColin Finck ControlHandle,
339c2c66affSColin Finck &KeyName,
340c2c66affSColin Finck KEY_ALL_ACCESS,
341c2c66affSColin Finck REG_OPTION_NON_VOLATILE,
342c2c66affSColin Finck &Disposition);
343c2c66affSColin Finck if (!NT_SUCCESS(Status)) return Status;
344c2c66affSColin Finck
345c2c66affSColin Finck ZwClose(DeviceClassesHandle);
346c2c66affSColin Finck }
347c2c66affSColin Finck
348c2c66affSColin Finck ZwClose(ControlHandle);
349c2c66affSColin Finck
350c2c66affSColin Finck /* Create the enum key */
351c2c66affSColin Finck RtlInitUnicodeString(&KeyName, REGSTR_KEY_ENUM);
352c2c66affSColin Finck Status = IopCreateRegistryKeyEx(&EnumHandle,
353c2c66affSColin Finck KeyHandle,
354c2c66affSColin Finck &KeyName,
355c2c66affSColin Finck KEY_ALL_ACCESS,
356c2c66affSColin Finck REG_OPTION_NON_VOLATILE,
357c2c66affSColin Finck &Disposition);
358c2c66affSColin Finck if (!NT_SUCCESS(Status)) return Status;
359c2c66affSColin Finck
360c2c66affSColin Finck /* Check if it's a new key */
361c2c66affSColin Finck if (Disposition == REG_CREATED_NEW_KEY)
362c2c66affSColin Finck {
363c2c66affSColin Finck /* FIXME: DACLs */
364c2c66affSColin Finck }
365c2c66affSColin Finck
366c2c66affSColin Finck /* Create the root key */
367c2c66affSColin Finck ParentHandle = EnumHandle;
368c2c66affSColin Finck RtlInitUnicodeString(&KeyName, REGSTR_KEY_ROOTENUM);
369c2c66affSColin Finck Status = IopCreateRegistryKeyEx(&EnumHandle,
370c2c66affSColin Finck ParentHandle,
371c2c66affSColin Finck &KeyName,
372c2c66affSColin Finck KEY_ALL_ACCESS,
373c2c66affSColin Finck REG_OPTION_NON_VOLATILE,
374c2c66affSColin Finck &Disposition);
375c2c66affSColin Finck NtClose(ParentHandle);
376c2c66affSColin Finck if (!NT_SUCCESS(Status)) return Status;
377c2c66affSColin Finck NtClose(EnumHandle);
378c2c66affSColin Finck
379c2c66affSColin Finck /* Open the root key now */
380c2c66affSColin Finck RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\ENUM");
381c2c66affSColin Finck Status = IopOpenRegistryKeyEx(&EnumHandle,
382c2c66affSColin Finck NULL,
383c2c66affSColin Finck &KeyName,
384c2c66affSColin Finck KEY_ALL_ACCESS);
385c2c66affSColin Finck if (NT_SUCCESS(Status))
386c2c66affSColin Finck {
387c2c66affSColin Finck /* Create the root dev node */
388c2c66affSColin Finck RtlInitUnicodeString(&KeyName, REGSTR_VAL_ROOT_DEVNODE);
389c2c66affSColin Finck Status = IopCreateRegistryKeyEx(&TreeHandle,
390c2c66affSColin Finck EnumHandle,
391c2c66affSColin Finck &KeyName,
392c2c66affSColin Finck KEY_ALL_ACCESS,
393c2c66affSColin Finck REG_OPTION_NON_VOLATILE,
394c2c66affSColin Finck NULL);
395c2c66affSColin Finck NtClose(EnumHandle);
396c2c66affSColin Finck if (NT_SUCCESS(Status)) NtClose(TreeHandle);
397c2c66affSColin Finck }
398c2c66affSColin Finck
399c2c66affSColin Finck /* Create the root driver */
400c2c66affSColin Finck Status = IoCreateDriver(&PnpManagerDriverName, PnpRootDriverEntry);
401c2c66affSColin Finck if (!NT_SUCCESS(Status))
402c2c66affSColin Finck {
403c2c66affSColin Finck DPRINT1("IoCreateDriverObject() failed\n");
404c2c66affSColin Finck KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
405c2c66affSColin Finck }
406c2c66affSColin Finck
407c2c66affSColin Finck /* Create the root PDO */
408c2c66affSColin Finck Status = IoCreateDevice(IopRootDriverObject,
409*bbf64c0cSVictor Perevertkin 0,
410c2c66affSColin Finck NULL,
411c2c66affSColin Finck FILE_DEVICE_CONTROLLER,
412c2c66affSColin Finck 0,
413c2c66affSColin Finck FALSE,
414c2c66affSColin Finck &Pdo);
415c2c66affSColin Finck if (!NT_SUCCESS(Status))
416c2c66affSColin Finck {
417c2c66affSColin Finck DPRINT1("IoCreateDevice() failed\n");
418c2c66affSColin Finck KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
419c2c66affSColin Finck }
420c2c66affSColin Finck
421c2c66affSColin Finck /* This is a bus enumerated device */
422c2c66affSColin Finck Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
423c2c66affSColin Finck
424c2c66affSColin Finck /* Create the root device node */
425c2c66affSColin Finck IopRootDeviceNode = PipAllocateDeviceNode(Pdo);
426c2c66affSColin Finck
427c2c66affSColin Finck /* Set flags */
428798fc13bSVictor Perevertkin IopRootDeviceNode->Flags |= DNF_MADEUP | DNF_ENUMERATED |
429798fc13bSVictor Perevertkin DNF_IDS_QUERIED | DNF_NO_RESOURCE_REQUIRED;
430c2c66affSColin Finck
431c2c66affSColin Finck /* Create instance path */
4323f16c861SJérôme Gardou if (!RtlCreateUnicodeString(&IopRootDeviceNode->InstancePath, REGSTR_VAL_ROOT_DEVNODE))
4333f16c861SJérôme Gardou {
4343f16c861SJérôme Gardou DPRINT1("RtlCreateUnicodeString() failed\n");
4353f16c861SJérôme Gardou KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
4363f16c861SJérôme Gardou }
437c2c66affSColin Finck
438*bbf64c0cSVictor Perevertkin PnpRootInitializeDevExtension();
439c2c66affSColin Finck
440798fc13bSVictor Perevertkin PiSetDevNodeState(IopRootDeviceNode, DeviceNodeStarted);
441798fc13bSVictor Perevertkin
442c2c66affSColin Finck /* Initialize PnP-Event notification support */
443c2c66affSColin Finck Status = IopInitPlugPlayEvents();
444c2c66affSColin Finck if (!NT_SUCCESS(Status)) return Status;
445c2c66affSColin Finck
446c2c66affSColin Finck /* Initialize the Bus Type GUID List */
447c2c66affSColin Finck PnpBusTypeGuidList = ExAllocatePool(PagedPool, sizeof(IO_BUS_TYPE_GUID_LIST));
448c2c66affSColin Finck RtlZeroMemory(PnpBusTypeGuidList, sizeof(IO_BUS_TYPE_GUID_LIST));
449c2c66affSColin Finck ExInitializeFastMutex(&PnpBusTypeGuidList->Lock);
450c2c66affSColin Finck
451798fc13bSVictor Perevertkin /* Initialize PnP root relations (this is a syncronous operation) */
452*bbf64c0cSVictor Perevertkin PiQueueDeviceAction(Pdo, PiActionEnumRootDevices, NULL, NULL);
453798fc13bSVictor Perevertkin
454c2c66affSColin Finck /* Launch the firmware mapper */
455c2c66affSColin Finck Status = IopUpdateRootKey();
456c2c66affSColin Finck if (!NT_SUCCESS(Status)) return Status;
457c2c66affSColin Finck
458c2c66affSColin Finck /* Close the handle to the control set */
459c2c66affSColin Finck NtClose(KeyHandle);
460c2c66affSColin Finck
4612839c850SVictor Perevertkin /* Initialize PnP root relations (this is a syncronous operation) */
462*bbf64c0cSVictor Perevertkin PiQueueDeviceAction(Pdo, PiActionEnumRootDevices, NULL, NULL);
4632839c850SVictor Perevertkin
464c2c66affSColin Finck /* We made it */
465c2c66affSColin Finck return STATUS_SUCCESS;
466c2c66affSColin Finck }
467c2c66affSColin Finck
468c2c66affSColin Finck /* EOF */
469