ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

pnpinit.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.