[ros-diffs] [ion] 26685: - Add code to detect and save the BIOS Version string to the registry. We use the same detection patterns as Windows for now (Ver, Rev, Rel, v0-9). - All BIOS Version strings are scanned and saved in a REG_MULTI_SZ key, as on Windows. QEMU BIOS Version String is correctly detected as the CVS/SVN $ID tag, which is good enough.

ion at svn.reactos.org ion at svn.reactos.org
Thu May 10 23:36:25 CEST 2007


Author: ion
Date: Fri May 11 01:36:24 2007
New Revision: 26685

URL: http://svn.reactos.org/svn/reactos?rev=26685&view=rev
Log:
- Add code to detect and save the BIOS Version string to the registry. We use the same detection patterns as Windows for now (Ver, Rev, Rel, v0-9).
- All BIOS Version strings are scanned and saved in a REG_MULTI_SZ key, as on Windows. QEMU BIOS Version String is correctly detected as the CVS/SVN $ID tag, which is good enough.

Modified:
    trunk/reactos/ntoskrnl/config/i386/cmhardwr.c

Modified: trunk/reactos/ntoskrnl/config/i386/cmhardwr.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/i386/cmhardwr.c?rev=26685&r1=26684&r2=26685&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/config/i386/cmhardwr.c (original)
+++ trunk/reactos/ntoskrnl/config/i386/cmhardwr.c Fri May 11 01:36:24 2007
@@ -17,6 +17,17 @@
 
 PCHAR CmpID1 = "80%u86-%c%x";
 PCHAR CmpID2 = "x86 Family %u Model %u Stepping %u";
+PCHAR CmpBiosStrings[] =
+{
+    "Ver",
+    "Rev",
+    "Rel",
+    "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9",
+    "v 0", "v 1", "v 2", "v 3", "v 4", "v 5", "v 6", "v 7", "v 8", "v 9",
+    NULL
+};
+
+PCHAR CmpBiosBegin, CmpBiosSearchStart, CmpBiosSearchEnd;
 
 /* FUNCTIONS *****************************************************************/
 
@@ -117,30 +128,126 @@
     return FALSE;
 }
 
+BOOLEAN
+NTAPI
+CmpGetBiosVersion(IN PCHAR BiosStart,
+                  IN ULONG BiosLength,
+                  IN PCHAR BiosVersion)
+{
+    CHAR Buffer[128];
+    PCHAR p, pp;
+    USHORT i;
+
+    /* Check if we were given intitial data for the search */
+    if (BiosStart)
+    {
+        /* Save it for later use */
+        CmpBiosBegin = BiosStart;
+        CmpBiosSearchStart = BiosStart + 1;
+        CmpBiosSearchEnd = BiosStart + BiosLength - 2;
+    }
+
+    /* Now loop the BIOS area */
+    for (;;)
+    {
+        /* Start an initial search looking for numbers and periods */
+        pp = NULL;
+        while (CmpBiosSearchStart <= CmpBiosSearchEnd)
+        {
+            /* Check if we have an "x.y" version string */
+            if ((*CmpBiosSearchStart == '.') &&
+                (*(CmpBiosSearchStart + 1) >= '0') &&
+                (*(CmpBiosSearchStart + 1) <= '9') &&
+                (*(CmpBiosSearchStart - 1) >= '0') &&
+                (*(CmpBiosSearchStart - 1) <= '9'))
+            {
+                /* Start looking in this area for the actual BIOS Version */
+                pp = CmpBiosSearchStart;
+                break;
+            }
+            else
+            {
+                /* Keep searching */
+                CmpBiosSearchStart++;
+            }
+        }
+
+        /* Break out if we're went past the BIOS area */
+        if (CmpBiosSearchStart > CmpBiosSearchEnd) return FALSE;
+
+        /* Move to the next 2 bytes */
+        CmpBiosSearchStart += 2;
+
+        /* Null-terminate our scratch buffer and start the string here */
+        Buffer[127] = ANSI_NULL;
+        p = &Buffer[127];
+
+        /* Go back one character since we're doing this backwards */
+        pp--;
+
+        /* Loop the identifier we found as long as it's valid */
+        i = 0;
+        while ((i++ < 127) &&
+               (pp >= CmpBiosBegin) &&
+               (*pp >= ' ') &&
+               (*pp != '$'))
+        {
+            /* Copy the character */
+            *--p = *pp--;
+        }
+
+        /* Go past the last character since we went backwards */
+        pp++;
+
+        /* Loop the strings we recognize */
+        for (i = 0; CmpBiosStrings[i]; i++)
+        {
+            /* Check if a match was found */
+            if (strstr(p, CmpBiosStrings[i])) goto Match;
+        }
+    }
+
+Match:
+    /* Skip until we find a space */
+    for (; *pp == ' '; pp++);
+
+    /* Loop the final string */
+    i = 0;
+    do
+    {
+        /* Copy the character into the final string */
+        BiosVersion[i] = *pp++;
+    } while ((++i < 127) &&
+             (pp <= (CmpBiosSearchEnd + 1)) &&
+             (*pp >= ' ') &&
+             (*pp != '$'));
+
+    /* Null-terminate the version string */
+    BiosVersion[i] = ANSI_NULL;
+    return TRUE;
+}
+
 NTSTATUS
 NTAPI
 CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 {
     UNICODE_STRING KeyName, ValueName, Data, SectionName;
     OBJECT_ATTRIBUTES ObjectAttributes;
-    ULONG HavePae;
+    ULONG HavePae, CacheSize, ViewSize, Length, TotalLength = 0, i, Disposition;
     NTSTATUS Status;
     HANDLE KeyHandle, BiosHandle, SystemHandle, FpuHandle, SectionHandle;
-    ULONG Disposition;
     CONFIGURATION_COMPONENT_DATA ConfigData;
     CHAR Buffer[128];
-    ULONG i, ExtendedId, Dummy;
+    ULONG ExtendedId, Dummy;
     PKPRCB Prcb;
     USHORT IndexTable[MaximumType + 1] = {0};
     ANSI_STRING TempString;
-    PCHAR PartialString = NULL;
+    PCHAR PartialString = NULL, BiosVersion;
     CHAR CpuString[48];
-    ULONG CacheSize;
     PVOID BaseAddress = NULL;
     LARGE_INTEGER ViewBase = {{0}};
     ULONG_PTR VideoRomBase;
-    ULONG ViewSize;
-    PCHAR BiosVersion;
+    PCHAR CurrentVersion;
 
     /* Open the SMSS Memory Management key */
     RtlInitUnicodeString(&KeyName,
@@ -281,7 +388,7 @@
                 ConfigData.ComponentEntry.AffinityMask = AFFINITY_MASK(i);
                 ConfigData.ComponentEntry.Identifier = Buffer;
 
-                /* For 386 cpus, the CPU String is the identifier */
+                /* For 386 cpus, the CPU pp is the identifier */
                 if (Prcb->CpuType == 3) strcpy(Buffer, "80387");
 
                 /* Save the ID string length now that we've created it */
@@ -475,7 +582,7 @@
         ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
     }
 
-    /* Allocate BIOS Version String Buffer */
+    /* Allocate BIOS Version pp Buffer */
     BiosVersion = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, TAG_CM);
 
     /* Setup settings to map the 64K BIOS ROM */
@@ -539,6 +646,56 @@
 
             /* Close the bios information handle */
             NtClose(BiosHandle);
+
+            /* Get the BIOS Version */
+            if (CmpGetBiosVersion(BaseAddress, 16* PAGE_SIZE, Buffer))
+            {
+                /* Start at the beginning of our buffer */
+                CurrentVersion = BiosVersion;
+                do
+                {
+                    /* Convert to Unicode */
+                    RtlInitAnsiString(&TempString, Buffer);
+                    RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
+
+                    /* Calculate the length of this string and copy it in */
+                    Length = Data.Length + sizeof(UNICODE_NULL);
+                    RtlMoveMemory(CurrentVersion, Data.Buffer, Length);
+
+                    /* Free the unicode string */
+                    RtlFreeUnicodeString(&Data);
+
+                    /* Update the total length and see if we're out of space */
+                    TotalLength += Length;
+                    if (TotalLength + 256 + sizeof(UNICODE_NULL) > PAGE_SIZE)
+                    {
+                        /* One more string would push us out, so stop here */
+                        break;
+                    }
+
+                    /* Go to the next string inside the multi-string buffer */
+                    CurrentVersion += Length;
+
+                    /* Query the next BIOS Version */
+                } while (CmpGetBiosVersion(NULL, 0, Buffer));
+
+                /* Check if we found any strings at all */
+                if (TotalLength)
+                {
+                    /* Add the final null-terminator */
+                    *(PWSTR)CurrentVersion = UNICODE_NULL;
+                    TotalLength += sizeof(UNICODE_NULL);
+
+                    /* Write the BIOS Version to the registry */
+                    RtlInitUnicodeString(&ValueName, L"SystemBiosVersion");
+                    Status = NtSetValueKey(SystemHandle,
+                                           &ValueName,
+                                           0,
+                                           REG_MULTI_SZ,
+                                           BiosVersion,
+                                           TotalLength);
+                }
+            }
         }
 
         /* Unmap the section */




More information about the Ros-diffs mailing list