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

cmconfig.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Kernel
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * FILE:            ntoskrnl/config/cmconfig.c
00005  * PURPOSE:         Configuration Manager - System Configuration Routines
00006  * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
00007  */
00008 
00009 /* INCLUDES ******************************************************************/
00010 
00011 #include "ntoskrnl.h"
00012 #define NDEBUG
00013 #include "debug.h"
00014 
00015 /* FUNCTIONS *****************************************************************/
00016 
00017 NTSTATUS
00018 NTAPI
00019 INIT_FUNCTION
00020 CmpInitializeRegistryNode(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
00021                           IN HANDLE NodeHandle,
00022                           OUT PHANDLE NewHandle,
00023                           IN INTERFACE_TYPE InterfaceType,
00024                           IN ULONG BusNumber,
00025                           IN PUSHORT DeviceIndexTable)
00026 {
00027     NTSTATUS Status;
00028     OBJECT_ATTRIBUTES ObjectAttributes;
00029     UNICODE_STRING KeyName, ValueName, ValueData;
00030     HANDLE KeyHandle, ParentHandle;
00031     ANSI_STRING TempString;
00032     CHAR TempBuffer[12];
00033     WCHAR Buffer[12];
00034     PCONFIGURATION_COMPONENT Component;
00035     ULONG Disposition, Length = 0;
00036 
00037     /* Get the component */
00038     Component = &CurrentEntry->ComponentEntry;
00039 
00040     /* Set system class components to ARC system type */
00041     if (Component->Class == SystemClass) Component->Type = ArcSystem;
00042 
00043     /* Create a key for the component */
00044     InitializeObjectAttributes(&ObjectAttributes,
00045                                &CmTypeName[Component->Type],
00046                                OBJ_CASE_INSENSITIVE,
00047                                NodeHandle,
00048                                NULL);
00049     Status = NtCreateKey(&KeyHandle,
00050                          KEY_READ | KEY_WRITE,
00051                          &ObjectAttributes,
00052                          0,
00053                          NULL,
00054                          0,
00055                          &Disposition);
00056     if (!NT_SUCCESS(Status)) return Status;
00057 
00058     /* Check if this is anything but a system class component */
00059     if (Component->Class != SystemClass)
00060     {
00061         /* Build the sub-component string */
00062         RtlIntegerToChar(DeviceIndexTable[Component->Type]++,
00063                          10,
00064                          12,
00065                          TempBuffer);
00066         RtlInitAnsiString(&TempString, TempBuffer);
00067 
00068         /* Convert it to Unicode */
00069         RtlInitEmptyUnicodeString(&KeyName, Buffer, sizeof(Buffer));
00070         RtlAnsiStringToUnicodeString(&KeyName, &TempString, FALSE);
00071 
00072         /* Create the key */
00073         ParentHandle = KeyHandle;
00074         InitializeObjectAttributes(&ObjectAttributes,
00075                                    &KeyName,
00076                                    OBJ_CASE_INSENSITIVE,
00077                                    ParentHandle,
00078                                    NULL);
00079         Status = NtCreateKey(&KeyHandle,
00080                              KEY_READ | KEY_WRITE,
00081                              &ObjectAttributes,
00082                              0,
00083                              NULL,
00084                              0,
00085                              &Disposition);
00086         NtClose(ParentHandle);
00087 
00088         /* Fail if the key couldn't be created, and make sure it's a new key */
00089         if (!NT_SUCCESS(Status)) return Status;
00090         ASSERT(Disposition == REG_CREATED_NEW_KEY);
00091     }
00092 
00093     /* Setup the component information key */
00094     RtlInitUnicodeString(&ValueName, L"Component Information");
00095     Status = NtSetValueKey(KeyHandle,
00096                            &ValueName,
00097                            0,
00098                            REG_BINARY,
00099                            &Component->Flags,
00100                            FIELD_OFFSET(CONFIGURATION_COMPONENT,
00101                                         ConfigurationDataLength) -
00102                            FIELD_OFFSET(CONFIGURATION_COMPONENT, Flags));
00103     if (!NT_SUCCESS(Status))
00104     {
00105         /* Fail */
00106         NtClose(KeyHandle);
00107         return Status;
00108     }
00109 
00110     /* Check if we have an identifier */
00111     if (Component->IdentifierLength)
00112     {
00113         /* Build the string and convert it to Unicode */
00114         RtlInitUnicodeString(&ValueName, L"Identifier");
00115         RtlInitAnsiString(&TempString, Component->Identifier);
00116         Status = RtlAnsiStringToUnicodeString(&ValueData,
00117                                               &TempString,
00118                                               TRUE);
00119         if (NT_SUCCESS(Status))
00120         {
00121             /* Save the identifier in the registry */
00122             Status = NtSetValueKey(KeyHandle,
00123                                    &ValueName,
00124                                    0,
00125                                    REG_SZ,
00126                                    ValueData.Buffer,
00127                                    ValueData.Length + sizeof(UNICODE_NULL));
00128             RtlFreeUnicodeString(&ValueData);
00129         }
00130 
00131         /* Check for failure during conversion or registry write */
00132         if (!NT_SUCCESS(Status))
00133         {
00134             /* Fail */
00135             NtClose(KeyHandle);
00136             return Status;
00137         }
00138     }
00139 
00140     /* Setup the configuration data string */
00141     RtlInitUnicodeString(&ValueName, L"Configuration Data");
00142 
00143     /* Check if we got configuration data */
00144     if (CurrentEntry->ConfigurationData)
00145     {
00146         /* Calculate the total length and check if it fits into our buffer */
00147         Length = Component->ConfigurationDataLength +
00148                  FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList);
00149         if (Length > CmpConfigurationAreaSize)
00150         {
00151             ASSERTMSG("Component too large -- need reallocation!", FALSE);
00152         }
00153         else
00154         {
00155             /* Copy the data */
00156             RtlCopyMemory(&CmpConfigurationData->PartialResourceList.Version,
00157                           CurrentEntry->ConfigurationData,
00158                           Component->ConfigurationDataLength);
00159         }
00160     }
00161     else
00162     {
00163         /* No configuration data, setup defaults */
00164         CmpConfigurationData->PartialResourceList.Version = 0;
00165         CmpConfigurationData->PartialResourceList.Revision = 0;
00166         CmpConfigurationData->PartialResourceList.Count = 0;
00167         Length = FIELD_OFFSET(CM_PARTIAL_RESOURCE_LIST, PartialDescriptors) +
00168                  FIELD_OFFSET(CM_FULL_RESOURCE_DESCRIPTOR, PartialResourceList);
00169     }
00170 
00171     /* Set the interface type and bus number */
00172     CmpConfigurationData->InterfaceType = InterfaceType;
00173     CmpConfigurationData->BusNumber = BusNumber;
00174 
00175     /* Save the actual data */
00176     Status = NtSetValueKey(KeyHandle,
00177                            &ValueName,
00178                            0,
00179                            REG_FULL_RESOURCE_DESCRIPTOR,
00180                            CmpConfigurationData,
00181                            Length);
00182     if (!NT_SUCCESS(Status))
00183     {
00184         /* Fail */
00185         NtClose(KeyHandle);
00186     }
00187     else
00188     {
00189         /* Return the new handle */
00190         *NewHandle = KeyHandle;
00191     }
00192 
00193     /* Return status */
00194     return Status;
00195 }
00196 
00197 NTSTATUS
00198 NTAPI
00199 INIT_FUNCTION
00200 CmpSetupConfigurationTree(IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
00201                           IN HANDLE ParentHandle,
00202                           IN INTERFACE_TYPE InterfaceType,
00203                           IN ULONG BusNumber)
00204 {
00205     PCONFIGURATION_COMPONENT Component;
00206     USHORT DeviceIndexTable[MaximumType + 1] = {0};
00207     ULONG Interface = InterfaceType, Bus = BusNumber, i;
00208     NTSTATUS Status;
00209     HANDLE NewHandle;
00210 
00211     /* Loop each entry */
00212     while (CurrentEntry)
00213     {
00214         /* Check if this is an adapter */
00215         Component = &CurrentEntry->ComponentEntry;
00216         if ((Component->Class == AdapterClass) &&
00217             (CurrentEntry->Parent->ComponentEntry.Class == SystemClass))
00218         {
00219             /* Check what kind of adapter it is */
00220             switch (Component->Type)
00221             {
00222                 /* EISA */
00223                 case EisaAdapter:
00224                     
00225                     /* Fixup information */
00226                     Interface = Eisa;
00227                     Bus = CmpTypeCount[EisaAdapter]++;
00228                     break;
00229 
00230                 /* Turbo-channel */
00231                 case TcAdapter:
00232                     
00233                     /* Fixup information */
00234                     Interface = TurboChannel;
00235                     Bus = CmpTypeCount[TurboChannel]++;
00236                     break;
00237 
00238                 /* ISA, PCI, etc busses */
00239                 case MultiFunctionAdapter:
00240                     
00241                     /* Check if we have an  identifier */
00242                     if (Component->Identifier)
00243                     {
00244                         /* Loop each multi-function adapter type */
00245                         for (i = 0; CmpMultifunctionTypes[i].Identifier; i++)
00246                         {
00247                             /* Check for a name match */
00248                             if (!_stricmp(CmpMultifunctionTypes[i].Identifier,
00249                                           Component->Identifier))
00250                             {
00251                                 /* Match found */
00252                                 break;
00253                             }
00254                         }
00255                         
00256                         /* Fix up information */
00257                         Interface = CmpMultifunctionTypes[i].InterfaceType;
00258                         Bus = CmpMultifunctionTypes[i].Count++;
00259                     }
00260                     break;
00261 
00262                 /* SCSI Bus */
00263                 case ScsiAdapter:
00264                     
00265                     /* Fix up */
00266                     Interface = Internal;
00267                     Bus = CmpTypeCount[ScsiAdapter]++;
00268                     break;
00269 
00270                 /* Unknown */
00271                 default:
00272                     Interface = -1;
00273                     Bus = CmpUnknownBusCount++;
00274                     break;
00275             }
00276         }
00277         
00278         /* Dump information on the component */
00279 
00280         /* Setup the hardware node */
00281         Status = CmpInitializeRegistryNode(CurrentEntry,
00282                                            ParentHandle,
00283                                            &NewHandle,
00284                                            Interface,
00285                                            Bus,
00286                                            DeviceIndexTable);
00287         if (!NT_SUCCESS(Status)) return Status;
00288         
00289         /* Check for children */
00290         if (CurrentEntry->Child)
00291         {
00292             /* Recurse child */
00293             Status = CmpSetupConfigurationTree(CurrentEntry->Child,
00294                                                NewHandle,
00295                                                Interface,
00296                                                Bus);
00297             if (!NT_SUCCESS(Status))
00298             {
00299                 /* Fail */
00300                 NtClose(NewHandle);
00301                 return Status;
00302             }
00303         }
00304         
00305         /* Get to the next entry */
00306         NtClose(NewHandle);
00307         CurrentEntry = CurrentEntry->Sibling;
00308     }
00309     
00310     /* We're done */
00311     return STATUS_SUCCESS;
00312 }
00313 
00314 NTSTATUS
00315 NTAPI
00316 INIT_FUNCTION
00317 CmpInitializeHardwareConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
00318 {
00319     NTSTATUS Status;
00320     OBJECT_ATTRIBUTES ObjectAttributes;
00321     HANDLE KeyHandle;
00322     ULONG Disposition;
00323     UNICODE_STRING KeyName;
00324 
00325     /* Setup the key name */
00326     RtlInitUnicodeString(&KeyName,
00327                          L"\\Registry\\Machine\\Hardware\\DeviceMap");
00328     InitializeObjectAttributes(&ObjectAttributes,
00329                                &KeyName,
00330                                OBJ_CASE_INSENSITIVE,
00331                                NULL,
00332                                NULL);
00333 
00334     /* Create the device map key */
00335     Status = NtCreateKey(&KeyHandle,
00336                          KEY_READ | KEY_WRITE,
00337                          &ObjectAttributes,
00338                          0,
00339                          NULL,
00340                          0,
00341                          &Disposition);
00342     if (!NT_SUCCESS(Status)) return Status;
00343     NtClose(KeyHandle);
00344 
00345     /* Nobody should've created this key yet! */
00346     ASSERT(Disposition == REG_CREATED_NEW_KEY);
00347 
00348     /* Setup the key name */
00349     RtlInitUnicodeString(&KeyName,
00350                          L"\\Registry\\Machine\\Hardware\\Description");
00351     InitializeObjectAttributes(&ObjectAttributes,
00352                                &KeyName,
00353                                OBJ_CASE_INSENSITIVE,
00354                                NULL,
00355                                NULL);
00356 
00357     /* Create the description key */
00358     Status = NtCreateKey(&KeyHandle,
00359                           KEY_READ | KEY_WRITE,
00360                           &ObjectAttributes,
00361                           0,
00362                           NULL,
00363                           0,
00364                           &Disposition);
00365     if (!NT_SUCCESS(Status)) return Status;
00366 
00367     /* Nobody should've created this key yet! */
00368     ASSERT(Disposition == REG_CREATED_NEW_KEY);
00369 
00370     /* Allocate the configuration data buffer */
00371     CmpConfigurationData = ExAllocatePoolWithTag(PagedPool,
00372                                                  CmpConfigurationAreaSize,
00373                                                  TAG_CM);
00374     if (!CmpConfigurationData) return STATUS_INSUFFICIENT_RESOURCES;
00375 
00376     /* Check if we got anything from NTLDR */
00377     if (LoaderBlock->ConfigurationRoot)
00378     {
00379         /* Setup the configuration tree */
00380         Status = CmpSetupConfigurationTree(LoaderBlock->ConfigurationRoot,
00381                                            KeyHandle,
00382                                            -1,
00383                                            -1);
00384     }
00385     else
00386     {
00387         /* Nothing else to do */
00388         Status = STATUS_SUCCESS;
00389     }
00390 
00391     /* Close our handle, free the buffer and return status */
00392     ExFreePoolWithTag(CmpConfigurationData, TAG_CM);
00393     NtClose(KeyHandle);
00394     return Status;
00395 }

Generated on Sun May 27 2012 04:37:07 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.