xref: /reactos/ntoskrnl/io/pnpmgr/pnpinit.c (revision bbf64c0c)
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