Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencmhardwr.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/i386/cmhardwr.c 00005 * PURPOSE: Configuration Manager - Hardware-Specific Code 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 /* GLOBALS *******************************************************************/ 00016 00017 PCHAR CmpID1 = "PowerPC %u"; 00018 PCHAR CmpID2 = "No Data"; 00019 PCHAR CmpBiosStrings[] = 00020 { 00021 "Ver", 00022 "Rev", 00023 "Rel", 00024 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", 00025 "v 0", "v 1", "v 2", "v 3", "v 4", "v 5", "v 6", "v 7", "v 8", "v 9", 00026 NULL 00027 }; 00028 00029 PCHAR CmpBiosBegin, CmpBiosSearchStart, CmpBiosSearchEnd; 00030 00031 /* FUNCTIONS *****************************************************************/ 00032 00033 BOOLEAN 00034 NTAPI 00035 CmpGetBiosDate(IN PCHAR BiosStart, 00036 IN ULONG BiosLength, 00037 IN PCHAR BiosDate, 00038 IN BOOLEAN FromBios) 00039 { 00040 CHAR LastDate[11] = {0}, CurrentDate[11]; 00041 PCHAR p, pp; 00042 00043 /* Skip the signature and the magic, and loop the BIOS ROM */ 00044 p = BiosStart + 2; 00045 pp = BiosStart + BiosLength - 5; 00046 while (p < pp) 00047 { 00048 /* Check for xx/yy/zz which we assume to be a date */ 00049 if ((p[0] == '/') && 00050 (p[3] == '/') && 00051 (isdigit(p[-1])) && 00052 (isdigit(p[1])) && 00053 (isdigit(p[2])) && 00054 (isdigit(p[4])) && 00055 (isdigit(p[5]))) 00056 { 00057 /* Copy the string proper */ 00058 RtlMoveMemory(&CurrentDate[5], p - 2, 5); 00059 00060 /* Add a 0 if the month only has one digit */ 00061 if (!isdigit(CurrentDate[5])) CurrentDate[5] = '0'; 00062 00063 /* Now copy the year */ 00064 CurrentDate[2] = p[4]; 00065 CurrentDate[3] = p[5]; 00066 CurrentDate[4] = CurrentDate[7] = CurrentDate[10] = ANSI_NULL; 00067 00068 /* If the date comes from the BIOS, check if it's a 4-digit year */ 00069 if ((FromBios) && 00070 (isdigit(p[6])) && 00071 (isdigit(p[7])) && 00072 ((RtlEqualMemory(&p[4], "19", 2)) || 00073 (RtlEqualMemory(&p[4], "20", 2)))) 00074 { 00075 /* Copy the year proper */ 00076 CurrentDate[0] = p[4]; 00077 CurrentDate[1] = p[5]; 00078 CurrentDate[2] = p[6]; 00079 CurrentDate[3] = p[7]; 00080 } 00081 else 00082 { 00083 /* Otherwise, we'll just assume anything under 80 is 2000 */ 00084 if (strtoul(&CurrentDate[2], NULL, 10) < 80) 00085 { 00086 /* Hopefully your BIOS wasn't made in 1979 */ 00087 CurrentDate[0] = '2'; 00088 CurrentDate[1] = '0'; 00089 } 00090 else 00091 { 00092 /* Anything over 80, was probably made in the 1900s... */ 00093 CurrentDate[0] = '1'; 00094 CurrentDate[1] = '9'; 00095 } 00096 } 00097 00098 /* Add slashes were we previously had NULLs */ 00099 CurrentDate[4] = CurrentDate[7] = '/'; 00100 00101 /* Check which date is newer */ 00102 if (memcmp(LastDate, CurrentDate, 10) < 0) 00103 { 00104 /* Found a newer date, select it */ 00105 RtlMoveMemory(LastDate, CurrentDate, 10); 00106 } 00107 00108 p += 2; 00109 } 00110 p++; 00111 } 00112 00113 /* Make sure we found a date */ 00114 if (LastDate[0]) 00115 { 00116 /* Copy the year at the pp, and keep only the last two digits */ 00117 RtlMoveMemory(BiosDate, &LastDate[5], 5); 00118 BiosDate[5] = '/'; 00119 BiosDate[6] = LastDate[2]; 00120 BiosDate[7] = LastDate[3]; 00121 BiosDate[8] = ANSI_NULL; 00122 return TRUE; 00123 } 00124 00125 /* No date found, return empty string */ 00126 BiosDate[0] = ANSI_NULL; 00127 return FALSE; 00128 } 00129 00130 BOOLEAN 00131 NTAPI 00132 CmpGetBiosVersion(IN PCHAR BiosStart, 00133 IN ULONG BiosLength, 00134 IN PCHAR BiosVersion) 00135 { 00136 CHAR Buffer[128]; 00137 PCHAR p, pp; 00138 USHORT i; 00139 00140 /* Check if we were given intitial data for the search */ 00141 if (BiosStart) 00142 { 00143 /* Save it for later use */ 00144 CmpBiosBegin = BiosStart; 00145 CmpBiosSearchStart = BiosStart + 1; 00146 CmpBiosSearchEnd = BiosStart + BiosLength - 2; 00147 } 00148 00149 /* Now loop the BIOS area */ 00150 for (;;) 00151 { 00152 /* Start an initial search looking for numbers and periods */ 00153 pp = NULL; 00154 while (CmpBiosSearchStart <= CmpBiosSearchEnd) 00155 { 00156 /* Check if we have an "x.y" version string */ 00157 if ((*CmpBiosSearchStart == '.') && 00158 (*(CmpBiosSearchStart + 1) >= '0') && 00159 (*(CmpBiosSearchStart + 1) <= '9') && 00160 (*(CmpBiosSearchStart - 1) >= '0') && 00161 (*(CmpBiosSearchStart - 1) <= '9')) 00162 { 00163 /* Start looking in this area for the actual BIOS Version */ 00164 pp = CmpBiosSearchStart; 00165 break; 00166 } 00167 else 00168 { 00169 /* Keep searching */ 00170 CmpBiosSearchStart++; 00171 } 00172 } 00173 00174 /* Break out if we're went past the BIOS area */ 00175 if (CmpBiosSearchStart > CmpBiosSearchEnd) return FALSE; 00176 00177 /* Move to the next 2 bytes */ 00178 CmpBiosSearchStart += 2; 00179 00180 /* Null-terminate our scratch buffer and start the string here */ 00181 Buffer[127] = ANSI_NULL; 00182 p = &Buffer[127]; 00183 00184 /* Go back one character since we're doing this backwards */ 00185 pp--; 00186 00187 /* Loop the identifier we found as long as it's valid */ 00188 i = 0; 00189 while ((i++ < 127) && 00190 (pp >= CmpBiosBegin) && 00191 (*pp >= ' ') && 00192 (*pp != '$')) 00193 { 00194 /* Copy the character */ 00195 *--p = *pp--; 00196 } 00197 00198 /* Go past the last character since we went backwards */ 00199 pp++; 00200 00201 /* Loop the strings we recognize */ 00202 for (i = 0; CmpBiosStrings[i]; i++) 00203 { 00204 /* Check if a match was found */ 00205 if (strstr(p, CmpBiosStrings[i])) goto Match; 00206 } 00207 } 00208 00209 Match: 00210 /* Skip until we find a space */ 00211 for (; *pp == ' '; pp++); 00212 00213 /* Loop the final string */ 00214 i = 0; 00215 do 00216 { 00217 /* Copy the character into the final string */ 00218 BiosVersion[i] = *pp++; 00219 } while ((++i < 127) && 00220 (pp <= (CmpBiosSearchEnd + 1)) && 00221 (*pp >= ' ') && 00222 (*pp != '$')); 00223 00224 /* Null-terminate the version string */ 00225 BiosVersion[i] = ANSI_NULL; 00226 return TRUE; 00227 } 00228 00229 NTSTATUS 00230 NTAPI 00231 CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock) 00232 { 00233 UNICODE_STRING KeyName, ValueName, Data, SectionName; 00234 OBJECT_ATTRIBUTES ObjectAttributes; 00235 ULONG HavePae, CacheSize, ViewSize, Length, TotalLength = 0, i, Disposition; 00236 NTSTATUS Status; 00237 HANDLE KeyHandle, BiosHandle, SystemHandle, FpuHandle, SectionHandle; 00238 CONFIGURATION_COMPONENT_DATA ConfigData; 00239 CHAR Buffer[128]; 00240 ULONG ExtendedId = 0; //, Dummy; 00241 PKPRCB Prcb; 00242 USHORT IndexTable[MaximumType + 1] = {0}; 00243 ANSI_STRING TempString; 00244 PCHAR PartialString = NULL, BiosVersion; 00245 CHAR CpuString[48]; 00246 PVOID BaseAddress = NULL; 00247 LARGE_INTEGER ViewBase = {{0}}; 00248 ULONG_PTR VideoRomBase; 00249 PCHAR CurrentVersion; 00250 extern UNICODE_STRING KeRosProcessorName, KeRosBiosDate, KeRosBiosVersion; 00251 extern UNICODE_STRING KeRosVideoBiosDate, KeRosVideoBiosVersion; 00252 00253 /* Open the SMSS Memory Management key */ 00254 RtlInitUnicodeString(&KeyName, 00255 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\" 00256 L"Control\\Session Manager\\Memory Management"); 00257 InitializeObjectAttributes(&ObjectAttributes, 00258 &KeyName, 00259 OBJ_CASE_INSENSITIVE, 00260 NULL, 00261 NULL); 00262 Status = NtOpenKey(&KeyHandle, KEY_READ | KEY_WRITE, &ObjectAttributes); 00263 if (NT_SUCCESS(Status)) 00264 { 00265 /* Detect if PAE is enabled */ 00266 HavePae = SharedUserData->ProcessorFeatures[PF_PAE_ENABLED]; 00267 00268 /* Set the value */ 00269 RtlInitUnicodeString(&ValueName, L"PhysicalAddressExtension"); 00270 NtSetValueKey(KeyHandle, 00271 &ValueName, 00272 0, 00273 REG_DWORD, 00274 &HavePae, 00275 sizeof(HavePae)); 00276 00277 /* Close the key */ 00278 NtClose(KeyHandle); 00279 } 00280 00281 /* Open the hardware description key */ 00282 RtlInitUnicodeString(&KeyName, 00283 L"\\Registry\\Machine\\Hardware\\Description\\System"); 00284 InitializeObjectAttributes(&ObjectAttributes, 00285 &KeyName, 00286 OBJ_CASE_INSENSITIVE, 00287 NULL, 00288 NULL); 00289 Status = NtOpenKey(&SystemHandle, KEY_READ | KEY_WRITE, &ObjectAttributes); 00290 if (!NT_SUCCESS(Status)) return Status; 00291 00292 /* Create the BIOS Information key */ 00293 RtlInitUnicodeString(&KeyName, 00294 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\" 00295 L"Control\\BIOSINFO"); 00296 InitializeObjectAttributes(&ObjectAttributes, 00297 &KeyName, 00298 OBJ_CASE_INSENSITIVE, 00299 NULL, 00300 NULL); 00301 Status = NtCreateKey(&BiosHandle, 00302 KEY_ALL_ACCESS, 00303 &ObjectAttributes, 00304 0, 00305 NULL, 00306 REG_OPTION_NON_VOLATILE, 00307 &Disposition); 00308 if (ExpInTextModeSetup) 00309 { 00310 if (!NT_SUCCESS(Status)) 00311 BiosHandle = NULL; 00312 } 00313 else if (!NT_SUCCESS(Status)) 00314 return Status; 00315 00316 /* Create the CPU Key, and check if it already existed */ 00317 RtlInitUnicodeString(&KeyName, L"CentralProcessor"); 00318 InitializeObjectAttributes(&ObjectAttributes, 00319 &KeyName, 00320 OBJ_CASE_INSENSITIVE, 00321 SystemHandle, 00322 NULL); 00323 Status = NtCreateKey(&KeyHandle, 00324 KEY_READ | KEY_WRITE, 00325 &ObjectAttributes, 00326 0, 00327 NULL, 00328 0, 00329 &Disposition); 00330 NtClose(KeyHandle); 00331 00332 /* The key shouldn't already exist */ 00333 if (Disposition == REG_CREATED_NEW_KEY) 00334 { 00335 /* Allocate the configuration data for cmconfig.c */ 00336 CmpConfigurationData = ExAllocatePoolWithTag(PagedPool, 00337 CmpConfigurationAreaSize, 00338 TAG_CM); 00339 if (!CmpConfigurationData) return STATUS_INSUFFICIENT_RESOURCES; 00340 00341 /* Loop all CPUs */ 00342 for (i = 0; i < KeNumberProcessors; i++) 00343 { 00344 /* Get the PRCB */ 00345 Prcb = KiProcessorBlock[i]; 00346 00347 /* Setup the Configuration Entry for the Processor */ 00348 RtlZeroMemory(&ConfigData, sizeof (ConfigData)); 00349 ConfigData.ComponentEntry.Class = ProcessorClass; 00350 ConfigData.ComponentEntry.Type = CentralProcessor; 00351 ConfigData.ComponentEntry.Key = i; 00352 ConfigData.ComponentEntry.AffinityMask = AFFINITY_MASK(i); 00353 ConfigData.ComponentEntry.Identifier = Buffer; 00354 00355 /* Check if the CPU doesn't support CPUID */ 00356 if (!Prcb->CpuID) 00357 { 00358 /* Build ID1-style string for older CPUs */ 00359 sprintf(Buffer, 00360 CmpID1, 00361 Prcb->CpuType, 00362 (Prcb->CpuStep >> 8) + 'A', 00363 Prcb->CpuStep & 0xff); 00364 } 00365 else 00366 { 00367 /* Build ID2-style string for newer CPUs */ 00368 sprintf(Buffer, 00369 CmpID2, 00370 Prcb->CpuType, 00371 (Prcb->CpuStep >> 8), 00372 Prcb->CpuStep & 0xff); 00373 } 00374 00375 /* Save the ID string length now that we've created it */ 00376 ConfigData.ComponentEntry.IdentifierLength = strlen(Buffer) + 1; 00377 00378 /* Initialize the registry configuration node for it */ 00379 Status = CmpInitializeRegistryNode(&ConfigData, 00380 SystemHandle, 00381 &KeyHandle, 00382 InterfaceTypeUndefined, 00383 0xFFFFFFFF, 00384 IndexTable); 00385 if (!NT_SUCCESS(Status)) return(Status); 00386 00387 { 00388 /* Setup the Configuration Entry for the FPU */ 00389 RtlZeroMemory(&ConfigData, sizeof(ConfigData)); 00390 ConfigData.ComponentEntry.Class = ProcessorClass; 00391 ConfigData.ComponentEntry.Type = FloatingPointProcessor; 00392 ConfigData.ComponentEntry.Key = i; 00393 ConfigData.ComponentEntry.AffinityMask = AFFINITY_MASK(i); 00394 ConfigData.ComponentEntry.Identifier = Buffer; 00395 00396 /* For 386 cpus, the CPU pp is the identifier */ 00397 if (Prcb->CpuType == 3) strcpy(Buffer, "80387"); 00398 00399 /* Save the ID string length now that we've created it */ 00400 ConfigData.ComponentEntry.IdentifierLength = strlen(Buffer) + 1; 00401 00402 /* Initialize the registry configuration node for it */ 00403 Status = CmpInitializeRegistryNode(&ConfigData, 00404 SystemHandle, 00405 &FpuHandle, 00406 InterfaceTypeUndefined, 00407 0xFFFFFFFF, 00408 IndexTable); 00409 if (!NT_SUCCESS(Status)) 00410 { 00411 /* Failed, close the CPU handle and return */ 00412 NtClose(KeyHandle); 00413 return Status; 00414 } 00415 00416 /* Close this new handle */ 00417 NtClose(FpuHandle); 00418 00419 /* Stay on this CPU only */ 00420 KeSetSystemAffinityThread(Prcb->SetMember); 00421 if (!Prcb->CpuID) 00422 { 00423 /* Uh oh, no CPUID! */ 00424 } 00425 else 00426 { 00427 /* Check if we have extended CPUID that supports name ID */ 00428 //Ki386Cpuid(0x80000000, &ExtendedId, &Dummy, &Dummy, &Dummy); 00429 if (ExtendedId >= 0x80000004) 00430 { 00431 /* Do all the CPUIDs requred to get the full name */ 00432 PartialString = CpuString; 00433 for (ExtendedId = 2; ExtendedId <= 4; ExtendedId++) 00434 { 00435 #if 0 00436 /* Do the CPUID and save the name string */ 00437 Ki386Cpuid(0x80000000 | ExtendedId, 00438 (PULONG)PartialString, 00439 (PULONG)PartialString + 1, 00440 (PULONG)PartialString + 2, 00441 (PULONG)PartialString + 3); 00442 #endif 00443 00444 /* Go to the next name string */ 00445 PartialString += 16; 00446 } 00447 00448 /* Null-terminate it */ 00449 CpuString[47] = ANSI_NULL; 00450 } 00451 } 00452 00453 /* Get the cache size while we're still localized */ 00454 CacheSize = 0; //((PKIPCR)KeGetPcr())->SecondLevelCacheSize; 00455 00456 /* Go back to user affinity */ 00457 KeRevertToUserAffinityThread(); 00458 00459 /* Check if we have a CPU Name */ 00460 if (PartialString) 00461 { 00462 /* Convert it to Unicode */ 00463 RtlInitAnsiString(&TempString, CpuString); 00464 RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE); 00465 00466 /* Add it to the registry */ 00467 RtlInitUnicodeString(&ValueName, L"ProcessorNameString"); 00468 Status = NtSetValueKey(KeyHandle, 00469 &ValueName, 00470 0, 00471 REG_SZ, 00472 Data.Buffer, 00473 Data.Length + sizeof(UNICODE_NULL)); 00474 00475 /* ROS: Save a copy for bugzilla reporting */ 00476 RtlCreateUnicodeString(&KeRosProcessorName, Data.Buffer); 00477 00478 /* Free the temporary buffer */ 00479 RtlFreeUnicodeString(&Data); 00480 } 00481 00482 /* Check if we had a Vendor ID */ 00483 if (Prcb->VendorString) 00484 { 00485 /* Convert it to Unicode */ 00486 RtlInitAnsiString(&TempString, Prcb->VendorString); 00487 RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE); 00488 00489 /* Add it to the registry */ 00490 RtlInitUnicodeString(&ValueName, L"VendorIdentifier"); 00491 Status = NtSetValueKey(KeyHandle, 00492 &ValueName, 00493 0, 00494 REG_SZ, 00495 Data.Buffer, 00496 Data.Length + sizeof(UNICODE_NULL)); 00497 00498 /* Free the temporary buffer */ 00499 RtlFreeUnicodeString(&Data); 00500 } 00501 00502 /* Check if we have features bits */ 00503 if (Prcb->FeatureBits) 00504 { 00505 /* Add them to the registry */ 00506 RtlInitUnicodeString(&ValueName, L"FeatureSet"); 00507 Status = NtSetValueKey(KeyHandle, 00508 &ValueName, 00509 0, 00510 REG_DWORD, 00511 &Prcb->FeatureBits, 00512 sizeof(Prcb->FeatureBits)); 00513 } 00514 00515 /* Check if we detected the CPU Speed */ 00516 if (Prcb->MHz) 00517 { 00518 /* Add it to the registry */ 00519 RtlInitUnicodeString(&ValueName, L"~MHz"); 00520 Status = NtSetValueKey(KeyHandle, 00521 &ValueName, 00522 0, 00523 REG_DWORD, 00524 &Prcb->MHz, 00525 sizeof(Prcb->MHz)); 00526 } 00527 00528 /* Check if we have an update signature */ 00529 if (Prcb->UpdateSignature.QuadPart) 00530 { 00531 /* Add it to the registry */ 00532 RtlInitUnicodeString(&ValueName, L"Update Signature"); 00533 Status = NtSetValueKey(KeyHandle, 00534 &ValueName, 00535 0, 00536 REG_BINARY, 00537 &Prcb->UpdateSignature, 00538 sizeof(Prcb->UpdateSignature)); 00539 } 00540 00541 /* Close the processor handle */ 00542 NtClose(KeyHandle); 00543 00544 /* FIXME: Detect CPU mismatches */ 00545 } 00546 } 00547 00548 /* Free the configuration data */ 00549 ExFreePool(CmpConfigurationData); 00550 } 00551 00552 /* Open physical memory */ 00553 RtlInitUnicodeString(&SectionName, L"\\Device\\PhysicalMemory"); 00554 InitializeObjectAttributes(&ObjectAttributes, 00555 &SectionName, 00556 OBJ_CASE_INSENSITIVE, 00557 NULL, 00558 NULL); 00559 Status = ZwOpenSection(&SectionHandle, 00560 SECTION_ALL_ACCESS, 00561 &ObjectAttributes); 00562 if (!NT_SUCCESS(Status)) goto Quickie; 00563 00564 /* Map the first 1KB of memory to get the IVT */ 00565 ViewSize = PAGE_SIZE; 00566 Status = ZwMapViewOfSection(SectionHandle, 00567 NtCurrentProcess(), 00568 &BaseAddress, 00569 0, 00570 ViewSize, 00571 &ViewBase, 00572 &ViewSize, 00573 ViewUnmap, 00574 MEM_DOS_LIM, 00575 PAGE_READWRITE); 00576 if (!NT_SUCCESS(Status)) 00577 { 00578 /* Assume default */ 00579 VideoRomBase = 0xC0000; 00580 } 00581 else 00582 { 00583 /* Calculate the base address from the vector */ 00584 VideoRomBase = (*((PULONG)BaseAddress + 0x10) >> 12) & 0xFFFF0; 00585 VideoRomBase += *((PULONG)BaseAddress + 0x10) & 0xFFF0; 00586 00587 /* Now get to the actual ROM Start and make sure it's not invalid*/ 00588 VideoRomBase &= 0xFFFF8000; 00589 if (VideoRomBase < 0xC0000) VideoRomBase = 0xC0000; 00590 00591 /* And unmap the section */ 00592 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress); 00593 } 00594 00595 /* Allocate BIOS Version pp Buffer */ 00596 BiosVersion = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, TAG_CM); 00597 00598 /* Setup settings to map the 64K BIOS ROM */ 00599 BaseAddress = 0; 00600 ViewSize = 16 * PAGE_SIZE; 00601 ViewBase.LowPart = 0xF0000; 00602 ViewBase.HighPart = 0; 00603 00604 /* Map it */ 00605 Status = ZwMapViewOfSection(SectionHandle, 00606 NtCurrentProcess(), 00607 &BaseAddress, 00608 0, 00609 ViewSize, 00610 &ViewBase, 00611 &ViewSize, 00612 ViewUnmap, 00613 MEM_DOS_LIM, 00614 PAGE_READWRITE); 00615 if (NT_SUCCESS(Status)) 00616 { 00617 /* Scan the ROM to get the BIOS Date */ 00618 if (CmpGetBiosDate(BaseAddress, 16 * PAGE_SIZE, Buffer, TRUE)) 00619 { 00620 /* Convert it to Unicode */ 00621 RtlInitAnsiString(&TempString, Buffer); 00622 RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE); 00623 00624 /* Write the date into the registry */ 00625 RtlInitUnicodeString(&ValueName, L"SystemBiosDate"); 00626 Status = NtSetValueKey(SystemHandle, 00627 &ValueName, 00628 0, 00629 REG_SZ, 00630 Data.Buffer, 00631 Data.Length + sizeof(UNICODE_NULL)); 00632 00633 /* Free the string */ 00634 RtlFreeUnicodeString(&Data); 00635 00636 if (BiosHandle) 00637 { 00638 /* Get the BIOS Date Identifier */ 00639 RtlCopyMemory(Buffer, (PCHAR)BaseAddress + (16*PAGE_SIZE - 11), 8); 00640 Buffer[8] = ANSI_NULL; 00641 00642 /* Convert it to unicode */ 00643 RtlInitAnsiString(&TempString, Buffer); 00644 Status = RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE); 00645 if (NT_SUCCESS(Status)) 00646 { 00647 /* Save it to the registry */ 00648 Status = NtSetValueKey(BiosHandle, 00649 &ValueName, 00650 0, 00651 REG_SZ, 00652 Data.Buffer, 00653 Data.Length + sizeof(UNICODE_NULL)); 00654 00655 /* ROS: Save a copy for bugzilla reporting */ 00656 RtlCreateUnicodeString(&KeRosBiosDate, Data.Buffer); 00657 00658 /* Free the string */ 00659 RtlFreeUnicodeString(&Data); 00660 } 00661 00662 /* Close the bios information handle */ 00663 NtClose(BiosHandle); 00664 } 00665 } 00666 00667 /* Get the BIOS Version */ 00668 if (CmpGetBiosVersion(BaseAddress, 16* PAGE_SIZE, Buffer)) 00669 { 00670 /* Start at the beginning of our buffer */ 00671 CurrentVersion = BiosVersion; 00672 do 00673 { 00674 /* Convert to Unicode */ 00675 RtlInitAnsiString(&TempString, Buffer); 00676 RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE); 00677 00678 /* Calculate the length of this string and copy it in */ 00679 Length = Data.Length + sizeof(UNICODE_NULL); 00680 RtlMoveMemory(CurrentVersion, Data.Buffer, Length); 00681 00682 /* Free the unicode string */ 00683 RtlFreeUnicodeString(&Data); 00684 00685 /* Update the total length and see if we're out of space */ 00686 TotalLength += Length; 00687 if (TotalLength + 256 + sizeof(UNICODE_NULL) > PAGE_SIZE) 00688 { 00689 /* One more string would push us out, so stop here */ 00690 break; 00691 } 00692 00693 /* Go to the next string inside the multi-string buffer */ 00694 CurrentVersion += Length; 00695 00696 /* Query the next BIOS Version */ 00697 } while (CmpGetBiosVersion(NULL, 0, Buffer)); 00698 00699 /* Check if we found any strings at all */ 00700 if (TotalLength) 00701 { 00702 /* Add the final null-terminator */ 00703 *(PWSTR)CurrentVersion = UNICODE_NULL; 00704 TotalLength += sizeof(UNICODE_NULL); 00705 00706 /* Write the BIOS Version to the registry */ 00707 RtlInitUnicodeString(&ValueName, L"SystemBiosVersion"); 00708 Status = NtSetValueKey(SystemHandle, 00709 &ValueName, 00710 0, 00711 REG_MULTI_SZ, 00712 BiosVersion, 00713 TotalLength); 00714 00715 /* ROS: Save a copy for bugzilla reporting */ 00716 RtlCreateUnicodeString(&KeRosBiosVersion, (PWCH)BiosVersion); 00717 } 00718 } 00719 00720 /* Unmap the section */ 00721 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress); 00722 } 00723 00724 /* Now prepare for Video BIOS Mapping of 32KB */ 00725 BaseAddress = 0; 00726 ViewSize = 8 * PAGE_SIZE; 00727 ViewBase.LowPart = VideoRomBase; 00728 ViewBase.HighPart = 0; 00729 00730 /* Map it */ 00731 Status = ZwMapViewOfSection(SectionHandle, 00732 NtCurrentProcess(), 00733 &BaseAddress, 00734 0, 00735 ViewSize, 00736 &ViewBase, 00737 &ViewSize, 00738 ViewUnmap, 00739 MEM_DOS_LIM, 00740 PAGE_READWRITE); 00741 if (NT_SUCCESS(Status)) 00742 { 00743 /* Scan the ROM to get the BIOS Date */ 00744 if (CmpGetBiosDate(BaseAddress, 8 * PAGE_SIZE, Buffer, FALSE)) 00745 { 00746 /* Convert it to Unicode */ 00747 RtlInitAnsiString(&TempString, Buffer); 00748 RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE); 00749 00750 /* Write the date into the registry */ 00751 RtlInitUnicodeString(&ValueName, L"VideoBiosDate"); 00752 Status = NtSetValueKey(SystemHandle, 00753 &ValueName, 00754 0, 00755 REG_SZ, 00756 Data.Buffer, 00757 Data.Length + sizeof(UNICODE_NULL)); 00758 00759 /* ROS: Save a copy for bugzilla reporting */ 00760 RtlCreateUnicodeString(&KeRosVideoBiosDate, Data.Buffer); 00761 00762 /* Free the string */ 00763 RtlFreeUnicodeString(&Data); 00764 } 00765 00766 /* Get the Video BIOS Version */ 00767 if (CmpGetBiosVersion(BaseAddress, 8* PAGE_SIZE, Buffer)) 00768 { 00769 /* Start at the beginning of our buffer */ 00770 CurrentVersion = BiosVersion; 00771 do 00772 { 00773 /* Convert to Unicode */ 00774 RtlInitAnsiString(&TempString, Buffer); 00775 RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE); 00776 00777 /* Calculate the length of this string and copy it in */ 00778 Length = Data.Length + sizeof(UNICODE_NULL); 00779 RtlMoveMemory(CurrentVersion, Data.Buffer, Length); 00780 00781 /* Free the unicode string */ 00782 RtlFreeUnicodeString(&Data); 00783 00784 /* Update the total length and see if we're out of space */ 00785 TotalLength += Length; 00786 if (TotalLength + 256 + sizeof(UNICODE_NULL) > PAGE_SIZE) 00787 { 00788 /* One more string would push us out, so stop here */ 00789 break; 00790 } 00791 00792 /* Go to the next string inside the multi-string buffer */ 00793 CurrentVersion += Length; 00794 00795 /* Query the next BIOS Version */ 00796 } while (CmpGetBiosVersion(NULL, 0, Buffer)); 00797 00798 /* Check if we found any strings at all */ 00799 if (TotalLength) 00800 { 00801 /* Add the final null-terminator */ 00802 *(PWSTR)CurrentVersion = UNICODE_NULL; 00803 TotalLength += sizeof(UNICODE_NULL); 00804 00805 /* Write the BIOS Version to the registry */ 00806 RtlInitUnicodeString(&ValueName, L"VideoBiosVersion"); 00807 Status = NtSetValueKey(SystemHandle, 00808 &ValueName, 00809 0, 00810 REG_MULTI_SZ, 00811 BiosVersion, 00812 TotalLength); 00813 00814 /* ROS: Save a copy for bugzilla reporting */ 00815 RtlCreateUnicodeString(&KeRosVideoBiosVersion, (PWCH)BiosVersion); 00816 } 00817 } 00818 00819 /* Unmap the section */ 00820 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress); 00821 } 00822 00823 /* Close the section */ 00824 ZwClose(SectionHandle); 00825 00826 /* Free the BIOS version string buffer */ 00827 if (BiosVersion) ExFreePool(BiosVersion); 00828 00829 Quickie: 00830 /* Close the procesor handle */ 00831 NtClose(KeyHandle); 00832 return STATUS_SUCCESS; 00833 } Generated on Fri May 25 2012 04:35:28 for ReactOS by
1.7.6.1
|