Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpnpinit.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: BSD - See COPYING.ARM in the top level directory 00004 * FILE: ntoskrnl/io/pnpmgr/pnpinit.c 00005 * PURPOSE: PnP Initialization Code 00006 * PROGRAMMERS: ReactOS Portable Systems Group 00007 */ 00008 00009 /* INCLUDES *******************************************************************/ 00010 00011 #include <ntoskrnl.h> 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 /* GLOBALS ********************************************************************/ 00016 00017 typedef struct _IOPNP_DEVICE_EXTENSION 00018 { 00019 PWCHAR CompatibleIdList; 00020 ULONG CompatibleIdListSize; 00021 } IOPNP_DEVICE_EXTENSION, *PIOPNP_DEVICE_EXTENSION; 00022 00023 PUNICODE_STRING PiInitGroupOrderTable; 00024 USHORT PiInitGroupOrderTableCount; 00025 INTERFACE_TYPE PnpDefaultInterfaceType; 00026 00027 /* FUNCTIONS ******************************************************************/ 00028 00029 INTERFACE_TYPE 00030 NTAPI 00031 IopDetermineDefaultInterfaceType(VOID) 00032 { 00033 /* FIXME: ReactOS doesn't support MicroChannel yet */ 00034 return Isa; 00035 } 00036 00037 NTSTATUS 00038 NTAPI 00039 IopInitializeArbiters(VOID) 00040 { 00041 /* FIXME: TODO */ 00042 return STATUS_SUCCESS; 00043 } 00044 00045 NTSTATUS 00046 NTAPI 00047 INIT_FUNCTION 00048 PiInitCacheGroupInformation(VOID) 00049 { 00050 HANDLE KeyHandle; 00051 NTSTATUS Status; 00052 PKEY_VALUE_FULL_INFORMATION KeyValueInformation; 00053 PUNICODE_STRING GroupTable; 00054 ULONG Count; 00055 UNICODE_STRING GroupString = 00056 RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet" 00057 L"\\Control\\ServiceGroupOrder"); 00058 00059 /* ReactOS HACK for SETUPLDR */ 00060 if (KeLoaderBlock->SetupLdrBlock) 00061 { 00062 /* Bogus data */ 00063 PiInitGroupOrderTableCount = 0; 00064 PiInitGroupOrderTable = (PVOID)0xBABEB00B; 00065 return STATUS_SUCCESS; 00066 } 00067 00068 /* Open the registry key */ 00069 Status = IopOpenRegistryKeyEx(&KeyHandle, 00070 NULL, 00071 &GroupString, 00072 KEY_READ); 00073 if (NT_SUCCESS(Status)) 00074 { 00075 /* Get the list */ 00076 Status = IopGetRegistryValue(KeyHandle, L"List", &KeyValueInformation); 00077 ZwClose(KeyHandle); 00078 00079 /* Make sure we got it */ 00080 if (NT_SUCCESS(Status)) 00081 { 00082 /* Make sure it's valid */ 00083 if ((KeyValueInformation->Type == REG_MULTI_SZ) && 00084 (KeyValueInformation->DataLength)) 00085 { 00086 /* Convert it to unicode strings */ 00087 Status = PnpRegMultiSzToUnicodeStrings(KeyValueInformation, 00088 &GroupTable, 00089 &Count); 00090 00091 /* Cache it for later */ 00092 PiInitGroupOrderTable = GroupTable; 00093 PiInitGroupOrderTableCount = (USHORT)Count; 00094 } 00095 else 00096 { 00097 /* Fail */ 00098 Status = STATUS_UNSUCCESSFUL; 00099 } 00100 00101 /* Free the information */ 00102 ExFreePool(KeyValueInformation); 00103 } 00104 } 00105 00106 /* Return status */ 00107 return Status; 00108 } 00109 00110 USHORT 00111 NTAPI 00112 PpInitGetGroupOrderIndex(IN HANDLE ServiceHandle) 00113 { 00114 NTSTATUS Status; 00115 PKEY_VALUE_FULL_INFORMATION KeyValueInformation; 00116 USHORT i; 00117 PVOID Buffer; 00118 UNICODE_STRING Group; 00119 PAGED_CODE(); 00120 00121 /* Make sure we have a cache */ 00122 if (!PiInitGroupOrderTable) return -1; 00123 00124 /* If we don't have a handle, the rest is easy -- return the count */ 00125 if (!ServiceHandle) return PiInitGroupOrderTableCount + 1; 00126 00127 /* Otherwise, get the group value */ 00128 Status = IopGetRegistryValue(ServiceHandle, L"Group", &KeyValueInformation); 00129 if (!NT_SUCCESS(Status)) return PiInitGroupOrderTableCount; 00130 00131 /* Make sure we have a valid string */ 00132 ASSERT(KeyValueInformation->Type == REG_SZ); 00133 ASSERT(KeyValueInformation->DataLength); 00134 00135 /* Convert to unicode string */ 00136 Buffer = (PVOID)((ULONG_PTR)KeyValueInformation + KeyValueInformation->DataOffset); 00137 PnpRegSzToString(Buffer, KeyValueInformation->DataLength, &Group.Length); 00138 Group.MaximumLength = (USHORT)KeyValueInformation->DataLength; 00139 Group.Buffer = Buffer; 00140 00141 /* Loop the groups */ 00142 for (i = 0; i < PiInitGroupOrderTableCount; i++) 00143 { 00144 /* Try to find a match */ 00145 if (RtlEqualUnicodeString(&Group, &PiInitGroupOrderTable[i], TRUE)) break; 00146 } 00147 00148 /* We're done */ 00149 ExFreePool(KeyValueInformation); 00150 return i; 00151 } 00152 00153 USHORT 00154 NTAPI 00155 PipGetDriverTagPriority(IN HANDLE ServiceHandle) 00156 { 00157 NTSTATUS Status; 00158 HANDLE KeyHandle = NULL; 00159 PKEY_VALUE_FULL_INFORMATION KeyValueInformation = NULL; 00160 PKEY_VALUE_FULL_INFORMATION KeyValueInformationTag; 00161 PKEY_VALUE_FULL_INFORMATION KeyValueInformationGroupOrderList; 00162 PVOID Buffer; 00163 UNICODE_STRING Group; 00164 PULONG GroupOrder; 00165 ULONG Count, Tag = 0; 00166 USHORT i = -1; 00167 UNICODE_STRING GroupString = 00168 RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet" 00169 L"\\Control\\ServiceGroupOrder"); 00170 00171 /* Open the key */ 00172 Status = IopOpenRegistryKeyEx(&KeyHandle, NULL, &GroupString, KEY_READ); 00173 if (!NT_SUCCESS(Status)) goto Quickie; 00174 00175 /* Read the group */ 00176 Status = IopGetRegistryValue(ServiceHandle, L"Group", &KeyValueInformation); 00177 if (!NT_SUCCESS(Status)) goto Quickie; 00178 00179 /* Make sure we have a group */ 00180 if ((KeyValueInformation->Type == REG_SZ) && 00181 (KeyValueInformation->DataLength)) 00182 { 00183 /* Convert to unicode string */ 00184 Buffer = (PVOID)((ULONG_PTR)KeyValueInformation + KeyValueInformation->DataOffset); 00185 PnpRegSzToString(Buffer, KeyValueInformation->DataLength, &Group.Length); 00186 Group.MaximumLength = (USHORT)KeyValueInformation->DataLength; 00187 Group.Buffer = Buffer; 00188 } 00189 00190 /* Now read the tag */ 00191 Status = IopGetRegistryValue(ServiceHandle, L"Tag", &KeyValueInformationTag); 00192 if (!NT_SUCCESS(Status)) goto Quickie; 00193 00194 /* Make sure we have a tag */ 00195 if ((KeyValueInformationTag->Type == REG_DWORD) && 00196 (KeyValueInformationTag->DataLength)) 00197 { 00198 /* Read it */ 00199 Tag = *(PULONG)((ULONG_PTR)KeyValueInformationTag + 00200 KeyValueInformationTag->DataOffset); 00201 } 00202 00203 /* We can get rid of this now */ 00204 ExFreePool(KeyValueInformationTag); 00205 00206 /* Now let's read the group's tag order */ 00207 Status = IopGetRegistryValue(KeyHandle, 00208 Group.Buffer, 00209 &KeyValueInformationGroupOrderList); 00210 00211 /* We can get rid of this now */ 00212 Quickie: 00213 if (KeyValueInformation) ExFreePool(KeyValueInformation); 00214 if (KeyHandle) NtClose(KeyHandle); 00215 if (!NT_SUCCESS(Status)) return -1; 00216 00217 /* We're on the success path -- validate the tag order*/ 00218 if ((KeyValueInformationGroupOrderList->Type == REG_BINARY) && 00219 (KeyValueInformationGroupOrderList->DataLength)) 00220 { 00221 /* Get the order array */ 00222 GroupOrder = (PULONG)((ULONG_PTR)KeyValueInformationGroupOrderList + 00223 KeyValueInformationGroupOrderList->DataOffset); 00224 00225 /* Get the count */ 00226 Count = *GroupOrder; 00227 ASSERT(((Count + 1) * sizeof(ULONG)) <= 00228 KeyValueInformationGroupOrderList->DataLength); 00229 00230 /* Now loop each tag */ 00231 GroupOrder++; 00232 for (i = 1; i <= Count; i++) 00233 { 00234 /* If we found it, we're out */ 00235 if (Tag == *GroupOrder) break; 00236 00237 /* Try the next one */ 00238 GroupOrder++; 00239 } 00240 } 00241 00242 /* Last buffer to free */ 00243 ExFreePool(KeyValueInformationGroupOrderList); 00244 return i; 00245 } 00246 00247 NTSTATUS 00248 NTAPI 00249 PipCallDriverAddDevice(IN PDEVICE_NODE DeviceNode, 00250 IN BOOLEAN LoadDriver, 00251 IN PDRIVER_OBJECT DriverObject) 00252 { 00253 NTSTATUS Status; 00254 HANDLE EnumRootKey, SubKey, ControlKey, ClassKey, PropertiesKey; 00255 UNICODE_STRING ClassGuid, Properties; 00256 UNICODE_STRING EnumRoot = RTL_CONSTANT_STRING(ENUM_ROOT); 00257 UNICODE_STRING ControlClass = 00258 RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class"); 00259 PKEY_VALUE_FULL_INFORMATION KeyValueInformation = NULL; 00260 PWCHAR Buffer; 00261 00262 /* Open enumeration root key */ 00263 Status = IopOpenRegistryKeyEx(&EnumRootKey, 00264 NULL, 00265 &EnumRoot, 00266 KEY_READ); 00267 if (!NT_SUCCESS(Status)) 00268 { 00269 DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status); 00270 return Status; 00271 } 00272 00273 /* Open instance subkey */ 00274 Status = IopOpenRegistryKeyEx(&SubKey, 00275 EnumRootKey, 00276 &DeviceNode->InstancePath, 00277 KEY_READ); 00278 if (!NT_SUCCESS(Status)) 00279 { 00280 DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status); 00281 ZwClose(EnumRootKey); 00282 return Status; 00283 } 00284 00285 /* Get class GUID */ 00286 Status = IopGetRegistryValue(SubKey, 00287 REGSTR_VAL_CLASSGUID, 00288 &KeyValueInformation); 00289 if (NT_SUCCESS(Status)) 00290 { 00291 /* Convert to unicode string */ 00292 Buffer = (PVOID)((ULONG_PTR)KeyValueInformation + KeyValueInformation->DataOffset); 00293 PnpRegSzToString(Buffer, KeyValueInformation->DataLength, &ClassGuid.Length); 00294 ClassGuid.MaximumLength = (USHORT)KeyValueInformation->DataLength; 00295 ClassGuid.Buffer = Buffer; 00296 00297 /* Open the key */ 00298 Status = IopOpenRegistryKeyEx(&ControlKey, 00299 NULL, 00300 &ControlClass, 00301 KEY_READ); 00302 if (!NT_SUCCESS(Status)) 00303 { 00304 /* No class key */ 00305 DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status); 00306 ClassKey = NULL; 00307 } 00308 else 00309 { 00310 /* Open the class key */ 00311 Status = IopOpenRegistryKeyEx(&ClassKey, 00312 ControlKey, 00313 &ClassGuid, 00314 KEY_READ); 00315 ZwClose(ControlKey); 00316 if (!NT_SUCCESS(Status)) 00317 { 00318 /* No class key */ 00319 DPRINT1("IopOpenRegistryKeyEx() failed with Status %08X\n", Status); 00320 ClassKey = NULL; 00321 } 00322 } 00323 00324 /* Check if we made it till here */ 00325 if (ClassKey) 00326 { 00327 /* Get the device properties */ 00328 RtlInitUnicodeString(&Properties, REGSTR_KEY_DEVICE_PROPERTIES); 00329 Status = IopOpenRegistryKeyEx(&PropertiesKey, 00330 ClassKey, 00331 &Properties, 00332 KEY_READ); 00333 if (!NT_SUCCESS(Status)) 00334 { 00335 /* No properties */ 00336 DPRINT("IopOpenRegistryKeyEx() failed with Status %08X\n", Status); 00337 PropertiesKey = NULL; 00338 } 00339 } 00340 00341 /* Free the registry data */ 00342 ExFreePool(KeyValueInformation); 00343 } 00344 00345 /* Do ReactOS-style setup */ 00346 IopAttachFilterDrivers(DeviceNode, TRUE); 00347 Status = IopInitializeDevice(DeviceNode, DriverObject); 00348 if (NT_SUCCESS(Status)) 00349 { 00350 IopAttachFilterDrivers(DeviceNode, FALSE); 00351 Status = IopStartDevice(DeviceNode); 00352 } 00353 00354 /* Return status */ 00355 return Status; 00356 } 00357 00358 NTSTATUS 00359 NTAPI 00360 INIT_FUNCTION 00361 IopInitializePlugPlayServices(VOID) 00362 { 00363 NTSTATUS Status; 00364 ULONG Disposition; 00365 HANDLE KeyHandle, EnumHandle, ParentHandle, TreeHandle, ControlHandle; 00366 UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET"); 00367 PDEVICE_OBJECT Pdo; 00368 00369 /* Initialize locks and such */ 00370 KeInitializeSpinLock(&IopDeviceTreeLock); 00371 00372 /* Get the default interface */ 00373 PnpDefaultInterfaceType = IopDetermineDefaultInterfaceType(); 00374 00375 /* Initialize arbiters */ 00376 Status = IopInitializeArbiters(); 00377 if (!NT_SUCCESS(Status)) return Status; 00378 00379 /* Setup the group cache */ 00380 Status = PiInitCacheGroupInformation(); 00381 if (!NT_SUCCESS(Status)) return Status; 00382 00383 /* Open the current control set */ 00384 Status = IopOpenRegistryKeyEx(&KeyHandle, 00385 NULL, 00386 &KeyName, 00387 KEY_ALL_ACCESS); 00388 if (!NT_SUCCESS(Status)) return Status; 00389 00390 /* Create the control key */ 00391 RtlInitUnicodeString(&KeyName, L"Control"); 00392 Status = IopCreateRegistryKeyEx(&ControlHandle, 00393 KeyHandle, 00394 &KeyName, 00395 KEY_ALL_ACCESS, 00396 REG_OPTION_NON_VOLATILE, 00397 &Disposition); 00398 if (!NT_SUCCESS(Status)) return Status; 00399 00400 /* Check if it's a new key */ 00401 if (Disposition == REG_CREATED_NEW_KEY) 00402 { 00403 HANDLE DeviceClassesHandle; 00404 00405 /* Create the device classes key */ 00406 RtlInitUnicodeString(&KeyName, L"DeviceClasses"); 00407 Status = IopCreateRegistryKeyEx(&DeviceClassesHandle, 00408 ControlHandle, 00409 &KeyName, 00410 KEY_ALL_ACCESS, 00411 REG_OPTION_NON_VOLATILE, 00412 &Disposition); 00413 if (!NT_SUCCESS(Status)) return Status; 00414 00415 ZwClose(DeviceClassesHandle); 00416 } 00417 00418 ZwClose(ControlHandle); 00419 00420 /* Create the enum key */ 00421 RtlInitUnicodeString(&KeyName, REGSTR_KEY_ENUM); 00422 Status = IopCreateRegistryKeyEx(&EnumHandle, 00423 KeyHandle, 00424 &KeyName, 00425 KEY_ALL_ACCESS, 00426 REG_OPTION_NON_VOLATILE, 00427 &Disposition); 00428 if (!NT_SUCCESS(Status)) return Status; 00429 00430 /* Check if it's a new key */ 00431 if (Disposition == REG_CREATED_NEW_KEY) 00432 { 00433 /* FIXME: DACLs */ 00434 DPRINT1("Need to build DACL\n"); 00435 } 00436 00437 /* Create the root key */ 00438 ParentHandle = EnumHandle; 00439 RtlInitUnicodeString(&KeyName, REGSTR_KEY_ROOTENUM); 00440 Status = IopCreateRegistryKeyEx(&EnumHandle, 00441 ParentHandle, 00442 &KeyName, 00443 KEY_ALL_ACCESS, 00444 REG_OPTION_NON_VOLATILE, 00445 &Disposition); 00446 NtClose(ParentHandle); 00447 if (!NT_SUCCESS(Status)) return Status; 00448 NtClose(EnumHandle); 00449 00450 /* Open the root key now */ 00451 RtlInitUnicodeString(&KeyName, L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\ENUM"); 00452 Status = IopOpenRegistryKeyEx(&EnumHandle, 00453 NULL, 00454 &KeyName, 00455 KEY_ALL_ACCESS); 00456 if (NT_SUCCESS(Status)) 00457 { 00458 /* Create the root dev node */ 00459 RtlInitUnicodeString(&KeyName, REGSTR_VAL_ROOT_DEVNODE); 00460 Status = IopCreateRegistryKeyEx(&TreeHandle, 00461 EnumHandle, 00462 &KeyName, 00463 KEY_ALL_ACCESS, 00464 REG_OPTION_NON_VOLATILE, 00465 NULL); 00466 NtClose(EnumHandle); 00467 if (NT_SUCCESS(Status)) NtClose(TreeHandle); 00468 } 00469 00470 /* Create the root driver */ 00471 Status = IoCreateDriver(NULL, PnpRootDriverEntry); 00472 if (!NT_SUCCESS(Status)) 00473 { 00474 DPRINT1("IoCreateDriverObject() failed\n"); 00475 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0); 00476 } 00477 00478 /* Create the root PDO */ 00479 Status = IoCreateDevice(IopRootDriverObject, 00480 sizeof(IOPNP_DEVICE_EXTENSION), 00481 NULL, 00482 FILE_DEVICE_CONTROLLER, 00483 0, 00484 FALSE, 00485 &Pdo); 00486 if (!NT_SUCCESS(Status)) 00487 { 00488 DPRINT1("IoCreateDevice() failed\n"); 00489 KeBugCheckEx(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0); 00490 } 00491 00492 /* This is a bus enumerated device */ 00493 Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE; 00494 00495 /* Create the root device node */ 00496 IopRootDeviceNode = PipAllocateDeviceNode(Pdo); 00497 00498 /* Set flags */ 00499 IopRootDeviceNode->Flags |= DNF_STARTED + DNF_PROCESSED + DNF_ENUMERATED + 00500 DNF_MADEUP + DNF_NO_RESOURCE_REQUIRED + 00501 DNF_ADDED; 00502 00503 /* Create instance path */ 00504 RtlCreateUnicodeString(&IopRootDeviceNode->InstancePath, 00505 REGSTR_VAL_ROOT_DEVNODE); 00506 00507 /* Call the add device routine */ 00508 IopRootDriverObject->DriverExtension->AddDevice(IopRootDriverObject, 00509 IopRootDeviceNode->PhysicalDeviceObject); 00510 00511 /* Initialize PnP-Event notification support */ 00512 Status = IopInitPlugPlayEvents(); 00513 if (!NT_SUCCESS(Status)) return Status; 00514 00515 /* Report the device to the user-mode pnp manager */ 00516 IopQueueTargetDeviceEvent(&GUID_DEVICE_ARRIVAL, 00517 &IopRootDeviceNode->InstancePath); 00518 00519 /* Initialize the Bus Type GUID List */ 00520 PnpBusTypeGuidList = ExAllocatePool(PagedPool, sizeof(IO_BUS_TYPE_GUID_LIST)); 00521 RtlZeroMemory(PnpBusTypeGuidList, sizeof(IO_BUS_TYPE_GUID_LIST)); 00522 ExInitializeFastMutex(&PnpBusTypeGuidList->Lock); 00523 00524 /* Launch the firmware mapper */ 00525 Status = IopUpdateRootKey(); 00526 if (!NT_SUCCESS(Status)) return Status; 00527 00528 /* Close the handle to the control set */ 00529 NtClose(KeyHandle); 00530 00531 /* We made it */ 00532 return STATUS_SUCCESS; 00533 } 00534 00535 /* EOF */ Generated on Sat May 26 2012 04:36:10 for ReactOS by
1.7.6.1
|