Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencmconfig.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
1.7.6.1
|