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 = "80%u86-%c%x";
00018 PCHAR CmpID2 = "x86 Family %u Model %u Stepping %u";
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 where 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, Length, TotalLength = 0, i, Disposition;
00236     SIZE_T ViewSize;
00237     NTSTATUS Status;
00238     HANDLE KeyHandle, BiosHandle, SystemHandle, FpuHandle, SectionHandle;
00239     CONFIGURATION_COMPONENT_DATA ConfigData;
00240     CHAR Buffer[128];
00241     ULONG ExtendedId, Dummy;
00242     PKPRCB Prcb;
00243     USHORT IndexTable[MaximumType + 1] = {0};
00244     ANSI_STRING TempString;
00245     PCHAR PartialString = NULL, BiosVersion;
00246     CHAR CpuString[48];
00247     PVOID BaseAddress = NULL;
00248     LARGE_INTEGER ViewBase = {{0, 0}};
00249     ULONG_PTR VideoRomBase;
00250     PCHAR CurrentVersion;
00251     extern UNICODE_STRING KeRosProcessorName, KeRosBiosDate, KeRosBiosVersion;
00252     extern UNICODE_STRING KeRosVideoBiosDate, KeRosVideoBiosVersion;
00253 
00254     /* Open the SMSS Memory Management key */
00255     RtlInitUnicodeString(&KeyName,
00256                          L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\"
00257                          L"Control\\Session Manager\\Memory Management");
00258     InitializeObjectAttributes(&ObjectAttributes,
00259                                &KeyName,
00260                                OBJ_CASE_INSENSITIVE,
00261                                NULL,
00262                                NULL);
00263     Status = NtOpenKey(&KeyHandle, KEY_READ | KEY_WRITE, &ObjectAttributes);
00264     if (NT_SUCCESS(Status))
00265     {
00266         /* Detect if PAE is enabled */
00267         HavePae = SharedUserData->ProcessorFeatures[PF_PAE_ENABLED];
00268 
00269         /* Set the value */
00270         RtlInitUnicodeString(&ValueName, L"PhysicalAddressExtension");
00271         NtSetValueKey(KeyHandle,
00272                       &ValueName,
00273                       0,
00274                       REG_DWORD,
00275                       &HavePae,
00276                       sizeof(HavePae));
00277 
00278         /* Close the key */
00279         NtClose(KeyHandle);
00280     }
00281 
00282     /* Open the hardware description key */
00283     RtlInitUnicodeString(&KeyName,
00284                          L"\\Registry\\Machine\\Hardware\\Description\\System");
00285     InitializeObjectAttributes(&ObjectAttributes,
00286                                &KeyName,
00287                                OBJ_CASE_INSENSITIVE,
00288                                NULL,
00289                                NULL);
00290     Status = NtOpenKey(&SystemHandle, KEY_READ | KEY_WRITE, &ObjectAttributes);
00291     if (!NT_SUCCESS(Status)) return Status;
00292 
00293     /* Create the BIOS Information key */
00294     RtlInitUnicodeString(&KeyName,
00295                          L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\"
00296                          L"Control\\BIOSINFO");
00297     InitializeObjectAttributes(&ObjectAttributes,
00298                                &KeyName,
00299                                OBJ_CASE_INSENSITIVE,
00300                                NULL,
00301                                NULL);
00302     Status = NtCreateKey(&BiosHandle,
00303                          KEY_ALL_ACCESS,
00304                          &ObjectAttributes,
00305                          0,
00306                          NULL,
00307                          REG_OPTION_NON_VOLATILE,
00308                          &Disposition);
00309     if (ExpInTextModeSetup)
00310     {
00311         if (!NT_SUCCESS(Status))
00312             BiosHandle = NULL;
00313     }
00314     else if (!NT_SUCCESS(Status))
00315         return Status;
00316 
00317     /* Create the CPU Key, and check if it already existed */
00318     RtlInitUnicodeString(&KeyName, L"CentralProcessor");
00319     InitializeObjectAttributes(&ObjectAttributes,
00320                                &KeyName,
00321                                OBJ_CASE_INSENSITIVE,
00322                                SystemHandle,
00323                                NULL);
00324     Status = NtCreateKey(&KeyHandle,
00325                          KEY_READ | KEY_WRITE,
00326                          &ObjectAttributes,
00327                          0,
00328                          NULL,
00329                          0,
00330                          &Disposition);
00331     NtClose(KeyHandle);
00332 
00333     /* The key shouldn't already exist */
00334     if (Disposition == REG_CREATED_NEW_KEY)
00335     {
00336         /* Allocate the configuration data for cmconfig.c */
00337         CmpConfigurationData = ExAllocatePoolWithTag(PagedPool,
00338                                                      CmpConfigurationAreaSize,
00339                                                      TAG_CM);
00340         if (!CmpConfigurationData) return STATUS_INSUFFICIENT_RESOURCES;
00341 
00342         /* Loop all CPUs */
00343         for (i = 0; i < KeNumberProcessors; i++)
00344         {
00345             /* Get the PRCB */
00346             Prcb = KiProcessorBlock[i];
00347 
00348             /* Setup the Configuration Entry for the Processor */
00349             RtlZeroMemory(&ConfigData, sizeof (ConfigData));
00350             ConfigData.ComponentEntry.Class = ProcessorClass;
00351             ConfigData.ComponentEntry.Type = CentralProcessor;
00352             ConfigData.ComponentEntry.Key = i;
00353             ConfigData.ComponentEntry.AffinityMask = AFFINITY_MASK(i);
00354             ConfigData.ComponentEntry.Identifier = Buffer;
00355 
00356             /* Check if the CPU doesn't support CPUID */
00357             if (!Prcb->CpuID)
00358             {
00359                 /* Build ID1-style string for older CPUs */
00360                 sprintf(Buffer,
00361                         CmpID1,
00362                         Prcb->CpuType,
00363                         (Prcb->CpuStep >> 8) + 'A',
00364                         Prcb->CpuStep & 0xff);
00365             }
00366             else
00367             {
00368                 /* Build ID2-style string for newer CPUs */
00369                 sprintf(Buffer,
00370                         CmpID2,
00371                         Prcb->CpuType,
00372                         (Prcb->CpuStep >> 8),
00373                         Prcb->CpuStep & 0xff);
00374             }
00375 
00376             /* Save the ID string length now that we've created it */
00377             ConfigData.ComponentEntry.IdentifierLength = (ULONG)strlen(Buffer) + 1;
00378 
00379             /* Initialize the registry configuration node for it */
00380             Status = CmpInitializeRegistryNode(&ConfigData,
00381                                                SystemHandle,
00382                                                &KeyHandle,
00383                                                InterfaceTypeUndefined,
00384                                                0xFFFFFFFF,
00385                                                IndexTable);
00386             if (!NT_SUCCESS(Status)) return(Status);
00387 
00388             /* Check if we have an FPU */
00389             if (KeI386NpxPresent)
00390             {
00391                 /* Setup the Configuration Entry for the FPU */
00392                 RtlZeroMemory(&ConfigData, sizeof(ConfigData));
00393                 ConfigData.ComponentEntry.Class = ProcessorClass;
00394                 ConfigData.ComponentEntry.Type = FloatingPointProcessor;
00395                 ConfigData.ComponentEntry.Key = i;
00396                 ConfigData.ComponentEntry.AffinityMask = AFFINITY_MASK(i);
00397                 ConfigData.ComponentEntry.Identifier = Buffer;
00398 
00399                 /* For 386 cpus, the CPU pp is the identifier */
00400                 if (Prcb->CpuType == 3) strcpy(Buffer, "80387");
00401 
00402                 /* Save the ID string length now that we've created it */
00403                 ConfigData.ComponentEntry.IdentifierLength = (ULONG)strlen(Buffer) + 1;
00404 
00405                 /* Initialize the registry configuration node for it */
00406                 Status = CmpInitializeRegistryNode(&ConfigData,
00407                                                    SystemHandle,
00408                                                    &FpuHandle,
00409                                                    InterfaceTypeUndefined,
00410                                                    0xFFFFFFFF,
00411                                                    IndexTable);
00412                 if (!NT_SUCCESS(Status))
00413                 {
00414                     /* Failed, close the CPU handle and return */
00415                     NtClose(KeyHandle);
00416                     return Status;
00417                 }
00418 
00419                 /* Close this new handle */
00420                 NtClose(FpuHandle);
00421 
00422                 /* Stay on this CPU only */
00423                 KeSetSystemAffinityThread(Prcb->SetMember);
00424                 if (!Prcb->CpuID)
00425                 {
00426                     /* Uh oh, no CPUID! */
00427                 }
00428                 else
00429                 {
00430                     /* Check if we have extended CPUID that supports name ID */
00431                     CPUID(0x80000000, &ExtendedId, &Dummy, &Dummy, &Dummy);
00432                     if (ExtendedId >= 0x80000004)
00433                     {
00434                         /* Do all the CPUIDs required to get the full name */
00435                         PartialString = CpuString;
00436                         for (ExtendedId = 2; ExtendedId <= 4; ExtendedId++)
00437                         {
00438                             /* Do the CPUID and save the name string */
00439                             CPUID(0x80000000 | ExtendedId,
00440                                   (PULONG)PartialString,
00441                                   (PULONG)PartialString + 1,
00442                                   (PULONG)PartialString + 2,
00443                                   (PULONG)PartialString + 3);
00444 
00445                             /* Go to the next name string */
00446                             PartialString += 16;
00447                         }
00448 
00449                         /* Null-terminate it */
00450                         CpuString[47] = ANSI_NULL;
00451                     }
00452                 }
00453 
00454                 /* Go back to user affinity */
00455                 KeRevertToUserAffinityThread();
00456 
00457                 /* Check if we have a CPU Name */
00458                 if (PartialString)
00459                 {
00460                     /* Convert it to Unicode */
00461                     RtlInitAnsiString(&TempString, CpuString);
00462                     RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
00463 
00464                     /* Add it to the registry */
00465                     RtlInitUnicodeString(&ValueName, L"ProcessorNameString");
00466                     Status = NtSetValueKey(KeyHandle,
00467                                            &ValueName,
00468                                            0,
00469                                            REG_SZ,
00470                                            Data.Buffer,
00471                                            Data.Length + sizeof(UNICODE_NULL));
00472 
00473                     /* ROS: Save a copy for bugzilla reporting */
00474                     RtlCreateUnicodeString(&KeRosProcessorName, Data.Buffer);
00475 
00476                     /* Free the temporary buffer */
00477                     RtlFreeUnicodeString(&Data);
00478                 }
00479 
00480                 /* Check if we had a Vendor ID */
00481                 if (Prcb->VendorString[0])
00482                 {
00483                     /* Convert it to Unicode */
00484                     RtlInitAnsiString(&TempString, Prcb->VendorString);
00485                     RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
00486 
00487                     /* Add it to the registry */
00488                     RtlInitUnicodeString(&ValueName, L"VendorIdentifier");
00489                     Status = NtSetValueKey(KeyHandle,
00490                                            &ValueName,
00491                                            0,
00492                                            REG_SZ,
00493                                            Data.Buffer,
00494                                            Data.Length + sizeof(UNICODE_NULL));
00495 
00496                     /* Free the temporary buffer */
00497                     RtlFreeUnicodeString(&Data);
00498                 }
00499 
00500                 /* Check if we have features bits */
00501                 if (Prcb->FeatureBits)
00502                 {
00503                     /* Add them to the registry */
00504                     RtlInitUnicodeString(&ValueName, L"FeatureSet");
00505                     Status = NtSetValueKey(KeyHandle,
00506                                            &ValueName,
00507                                            0,
00508                                            REG_DWORD,
00509                                            &Prcb->FeatureBits,
00510                                            sizeof(Prcb->FeatureBits));
00511                 }
00512 
00513                 /* Check if we detected the CPU Speed */
00514                 if (Prcb->MHz)
00515                 {
00516                     /* Add it to the registry */
00517                     RtlInitUnicodeString(&ValueName, L"~MHz");
00518                     Status = NtSetValueKey(KeyHandle,
00519                                            &ValueName,
00520                                            0,
00521                                            REG_DWORD,
00522                                            &Prcb->MHz,
00523                                            sizeof(Prcb->MHz));
00524                 }
00525 
00526                 /* Check if we have an update signature */
00527                 if (Prcb->UpdateSignature.QuadPart)
00528                 {
00529                     /* Add it to the registry */
00530                     RtlInitUnicodeString(&ValueName, L"Update Signature");
00531                     Status = NtSetValueKey(KeyHandle,
00532                                            &ValueName,
00533                                            0,
00534                                            REG_BINARY,
00535                                            &Prcb->UpdateSignature,
00536                                            sizeof(Prcb->UpdateSignature));
00537                 }
00538 
00539                 /* Close the processor handle */
00540                 NtClose(KeyHandle);
00541 
00542                 /* FIXME: Detect CPU mismatches */
00543             }
00544         }
00545 
00546         /* Free the configuration data */
00547         ExFreePoolWithTag(CmpConfigurationData, TAG_CM);
00548     }
00549 
00550     /* Open physical memory */
00551     RtlInitUnicodeString(&SectionName, L"\\Device\\PhysicalMemory");
00552     InitializeObjectAttributes(&ObjectAttributes,
00553                                &SectionName,
00554                                OBJ_CASE_INSENSITIVE,
00555                                NULL,
00556                                NULL);
00557     Status = ZwOpenSection(&SectionHandle,
00558                            SECTION_ALL_ACCESS,
00559                            &ObjectAttributes);
00560     if (!NT_SUCCESS(Status)) goto Quickie;
00561 
00562     /* Map the first 1KB of memory to get the IVT */
00563     ViewSize = PAGE_SIZE;
00564     Status = ZwMapViewOfSection(SectionHandle,
00565                                 NtCurrentProcess(),
00566                                 &BaseAddress,
00567                                 0,
00568                                 ViewSize,
00569                                 &ViewBase,
00570                                 &ViewSize,
00571                                 ViewUnmap,
00572                                 MEM_DOS_LIM,
00573                                 PAGE_READWRITE);
00574     if (!NT_SUCCESS(Status))
00575     {
00576         /* Assume default */
00577         VideoRomBase = 0xC0000;
00578     }
00579     else
00580     {
00581         /* Calculate the base address from the vector */
00582         VideoRomBase = (*((PULONG)BaseAddress + 0x10) >> 12) & 0xFFFF0;
00583         VideoRomBase += *((PULONG)BaseAddress + 0x10) & 0xFFF0;
00584 
00585         /* Now get to the actual ROM Start and make sure it's not invalid*/
00586         VideoRomBase &= 0xFFFF8000;
00587         if (VideoRomBase < 0xC0000) VideoRomBase = 0xC0000;
00588 
00589         /* And unmap the section */
00590         ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
00591     }
00592 
00593     /* Allocate BIOS Version pp Buffer */
00594     BiosVersion = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, TAG_CM);
00595 
00596     /* Setup settings to map the 64K BIOS ROM */
00597     BaseAddress = 0;
00598     ViewSize = 16 * PAGE_SIZE;
00599     ViewBase.LowPart = 0xF0000;
00600     ViewBase.HighPart = 0;
00601 
00602     /* Map it */
00603     Status = ZwMapViewOfSection(SectionHandle,
00604                                 NtCurrentProcess(),
00605                                 &BaseAddress,
00606                                 0,
00607                                 ViewSize,
00608                                 &ViewBase,
00609                                 &ViewSize,
00610                                 ViewUnmap,
00611                                 MEM_DOS_LIM,
00612                                 PAGE_READWRITE);
00613     if (NT_SUCCESS(Status))
00614     {
00615         /* Scan the ROM to get the BIOS Date */
00616         if (CmpGetBiosDate(BaseAddress, 16 * PAGE_SIZE, Buffer, TRUE))
00617         {
00618             /* Convert it to Unicode */
00619             RtlInitAnsiString(&TempString, Buffer);
00620             RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
00621 
00622             /* Write the date into the registry */
00623             RtlInitUnicodeString(&ValueName, L"SystemBiosDate");
00624             Status = NtSetValueKey(SystemHandle,
00625                                    &ValueName,
00626                                    0,
00627                                    REG_SZ,
00628                                    Data.Buffer,
00629                                    Data.Length + sizeof(UNICODE_NULL));
00630 
00631             /* Free the string */
00632             RtlFreeUnicodeString(&Data);
00633 
00634             if (BiosHandle)
00635             {
00636                 /* Get the BIOS Date Identifier */
00637                 RtlCopyMemory(Buffer, (PCHAR)BaseAddress + (16 * PAGE_SIZE - 11), 8);
00638                 Buffer[8] = ANSI_NULL;
00639 
00640                 /* Convert it to unicode */
00641                 RtlInitAnsiString(&TempString, Buffer);
00642                 Status = RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
00643                 if (NT_SUCCESS(Status))
00644                 {
00645                     /* Save it to the registry */
00646                     Status = NtSetValueKey(BiosHandle,
00647                                            &ValueName,
00648                                            0,
00649                                            REG_SZ,
00650                                            Data.Buffer,
00651                                            Data.Length + sizeof(UNICODE_NULL));
00652 
00653                     /* ROS: Save a copy for bugzilla reporting */
00654                     RtlCreateUnicodeString(&KeRosBiosDate, Data.Buffer);
00655 
00656                     /* Free the string */
00657                     RtlFreeUnicodeString(&Data);
00658                 }
00659 
00660                 /* Close the bios information handle */
00661                 NtClose(BiosHandle);
00662             }
00663         }
00664 
00665         /* Get the BIOS Version */
00666         if (CmpGetBiosVersion(BaseAddress, 16 * PAGE_SIZE, Buffer))
00667         {
00668             /* Start at the beginning of our buffer */
00669             CurrentVersion = BiosVersion;
00670             do
00671             {
00672                 /* Convert to Unicode */
00673                 RtlInitAnsiString(&TempString, Buffer);
00674                 RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
00675 
00676                 /* Calculate the length of this string and copy it in */
00677                 Length = Data.Length + sizeof(UNICODE_NULL);
00678                 RtlMoveMemory(CurrentVersion, Data.Buffer, Length);
00679 
00680                 /* Free the unicode string */
00681                 RtlFreeUnicodeString(&Data);
00682 
00683                 /* Update the total length and see if we're out of space */
00684                 TotalLength += Length;
00685                 if (TotalLength + 256 + sizeof(UNICODE_NULL) > PAGE_SIZE)
00686                 {
00687                     /* One more string would push us out, so stop here */
00688                     break;
00689                 }
00690 
00691                 /* Go to the next string inside the multi-string buffer */
00692                 CurrentVersion += Length;
00693 
00694                 /* Query the next BIOS Version */
00695             } while (CmpGetBiosVersion(NULL, 0, Buffer));
00696 
00697             /* Check if we found any strings at all */
00698             if (TotalLength)
00699             {
00700                 /* Add the final null-terminator */
00701                 *(PWSTR)CurrentVersion = UNICODE_NULL;
00702                 TotalLength += sizeof(UNICODE_NULL);
00703 
00704                 /* Write the BIOS Version to the registry */
00705                 RtlInitUnicodeString(&ValueName, L"SystemBiosVersion");
00706                 Status = NtSetValueKey(SystemHandle,
00707                                        &ValueName,
00708                                        0,
00709                                        REG_MULTI_SZ,
00710                                        BiosVersion,
00711                                        TotalLength);
00712 
00713                 /* ROS: Save a copy for bugzilla reporting */
00714                 RtlCreateUnicodeString(&KeRosBiosVersion, (PWCH)BiosVersion);
00715             }
00716         }
00717 
00718         /* Unmap the section */
00719         ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
00720     }
00721 
00722     /* Now prepare for Video BIOS Mapping of 32KB */
00723     BaseAddress = 0;
00724     ViewSize = 8 * PAGE_SIZE;
00725     ViewBase.QuadPart = VideoRomBase;
00726 
00727     /* Map it */
00728     Status = ZwMapViewOfSection(SectionHandle,
00729                                 NtCurrentProcess(),
00730                                 &BaseAddress,
00731                                 0,
00732                                 ViewSize,
00733                                 &ViewBase,
00734                                 &ViewSize,
00735                                 ViewUnmap,
00736                                 MEM_DOS_LIM,
00737                                 PAGE_READWRITE);
00738     if (NT_SUCCESS(Status))
00739     {
00740         /* Scan the ROM to get the BIOS Date */
00741         if (CmpGetBiosDate(BaseAddress, 8 * PAGE_SIZE, Buffer, FALSE))
00742         {
00743             /* Convert it to Unicode */
00744             RtlInitAnsiString(&TempString, Buffer);
00745             RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
00746 
00747             /* Write the date into the registry */
00748             RtlInitUnicodeString(&ValueName, L"VideoBiosDate");
00749             Status = NtSetValueKey(SystemHandle,
00750                                    &ValueName,
00751                                    0,
00752                                    REG_SZ,
00753                                    Data.Buffer,
00754                                    Data.Length + sizeof(UNICODE_NULL));
00755 
00756             /* ROS: Save a copy for bugzilla reporting */
00757             RtlCreateUnicodeString(&KeRosVideoBiosDate, Data.Buffer);
00758 
00759             /* Free the string */
00760             RtlFreeUnicodeString(&Data);
00761         }
00762 
00763         /* Get the Video BIOS Version */
00764         if (CmpGetBiosVersion(BaseAddress, 8 * PAGE_SIZE, Buffer))
00765         {
00766             /* Start at the beginning of our buffer */
00767             CurrentVersion = BiosVersion;
00768             do
00769             {
00770                 /* Convert to Unicode */
00771                 RtlInitAnsiString(&TempString, Buffer);
00772                 RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
00773 
00774                 /* Calculate the length of this string and copy it in */
00775                 Length = Data.Length + sizeof(UNICODE_NULL);
00776                 RtlMoveMemory(CurrentVersion, Data.Buffer, Length);
00777 
00778                 /* Free the unicode string */
00779                 RtlFreeUnicodeString(&Data);
00780 
00781                 /* Update the total length and see if we're out of space */
00782                 TotalLength += Length;
00783                 if (TotalLength + 256 + sizeof(UNICODE_NULL) > PAGE_SIZE)
00784                 {
00785                     /* One more string would push us out, so stop here */
00786                     break;
00787                 }
00788 
00789                 /* Go to the next string inside the multi-string buffer */
00790                 CurrentVersion += Length;
00791 
00792                 /* Query the next BIOS Version */
00793             } while (CmpGetBiosVersion(NULL, 0, Buffer));
00794 
00795             /* Check if we found any strings at all */
00796             if (TotalLength)
00797             {
00798                 /* Add the final null-terminator */
00799                 *(PWSTR)CurrentVersion = UNICODE_NULL;
00800                 TotalLength += sizeof(UNICODE_NULL);
00801 
00802                 /* Write the BIOS Version to the registry */
00803                 RtlInitUnicodeString(&ValueName, L"VideoBiosVersion");
00804                 Status = NtSetValueKey(SystemHandle,
00805                                        &ValueName,
00806                                        0,
00807                                        REG_MULTI_SZ,
00808                                        BiosVersion,
00809                                        TotalLength);
00810 
00811                 /* ROS: Save a copy for bugzilla reporting */
00812                 RtlCreateUnicodeString(&KeRosVideoBiosVersion, (PWCH)BiosVersion);
00813             }
00814         }
00815 
00816         /* Unmap the section */
00817         ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
00818     }
00819 
00820     /* Close the section */
00821     ZwClose(SectionHandle);
00822 
00823     /* Free the BIOS version string buffer */
00824     if (BiosVersion) ExFreePoolWithTag(BiosVersion, TAG_CM);
00825 
00826 Quickie:
00827     /* Close the procesor handle */
00828     NtClose(KeyHandle);
00829     return STATUS_SUCCESS;
00830 }

Generated on Sat May 26 2012 04:35:57 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.