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

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

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