⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmhardwr.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * PROJECT:         ReactOS Kernel
 * LICENSE:         GPL - See COPYING in the top level directory
 * FILE:            ntoskrnl/config/i386/cmhardwr.c
 * PURPOSE:         Configuration Manager - Hardware-Specific Code
 * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
 */

/* INCLUDES ******************************************************************/

#include "ntoskrnl.h"
#include "../cm.h"
#define NDEBUG
#include "debug.h"

/* GLOBALS *******************************************************************/

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 *****************************************************************/

BOOLEAN
NTAPI
CmpGetBiosDate(IN PCHAR BiosStart,
               IN ULONG BiosLength,
               IN PCHAR BiosDate,
               IN BOOLEAN FromBios)
{
    CHAR LastDate[11] = {0}, CurrentDate[11];
    PCHAR p, pp;

    /* Skip the signature and the magic, and loop the BIOS ROM */
    p = BiosStart + 2;
    pp = BiosStart + BiosLength - 5;
    while (p < pp)
    {
        /* Check for xx/yy/zz which we assume to be a date */
        if ((p[0] == '/') &&
            (p[3] == '/') &&
            (isdigit(p[-1])) &&
            (isdigit(p[1])) &&
            (isdigit(p[2])) &&
            (isdigit(p[4])) &&
            (isdigit(p[5])))
        {
            /* Copy the string proper */
            RtlMoveMemory(&CurrentDate[5], p - 2, 5);

            /* Add a 0 if the month only has one digit */
            if (!isdigit(CurrentDate[5])) CurrentDate[5] = '0';

            /* Now copy the year */
            CurrentDate[2] = p[4];
            CurrentDate[3] = p[5];
            CurrentDate[4] = CurrentDate[7] = CurrentDate[10] = ANSI_NULL;

            /* If the date comes from the BIOS, check if it's a 4-digit year */
            if ((FromBios) &&
                (isdigit(p[6])) &&
                (isdigit(p[7])) &&
                ((RtlEqualMemory(&p[4], "19", 2)) ||
                 (RtlEqualMemory(&p[4], "20", 2))))
            {
                /* Copy the year proper */
                CurrentDate[0] = p[4];
                CurrentDate[1] = p[5];
                CurrentDate[2] = p[6];
                CurrentDate[3] = p[7];
            }
            else
            {
                /* Otherwise, we'll just assume anything under 80 is 2000 */
                if (strtoul(&CurrentDate[2], NULL, 10) < 80)
                {
                    /* Hopefully your BIOS wasn't made in 1979 */
                    CurrentDate[0] = '2';
                    CurrentDate[1] = '0';
                }
                else
                {
                    /* Anything over 80, was probably made in the 1900s... */
                    CurrentDate[0] = '1';
                    CurrentDate[1] = '9';
                }
            }

            /* Add slashes were we previously had NULLs */
            CurrentDate[4] = CurrentDate[7] = '/';

            /* Check which date is newer */
            if (memcmp(LastDate, CurrentDate, 10) < 0)
            {
                /* Found a newer date, select it */
                RtlMoveMemory(LastDate, CurrentDate, 10);
            }

            p += 2;
        }
        p++;
    }

    /* Make sure we found a date */
    if (LastDate[0])
    {
        /* Copy the year at the pp, and keep only the last two digits */
        RtlMoveMemory(BiosDate, &LastDate[5], 5);
        BiosDate[5] = '/';
        BiosDate[6] = LastDate[2];
        BiosDate[7] = LastDate[3];
        BiosDate[8] = ANSI_NULL;
        return TRUE;
    }

    /* No date found, return empty string */
    BiosDate[0] = ANSI_NULL;
    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, CacheSize, ViewSize, Length, TotalLength = 0, i, Disposition;
    NTSTATUS Status;
    HANDLE KeyHandle, BiosHandle, SystemHandle, FpuHandle, SectionHandle;
    CONFIGURATION_COMPONENT_DATA ConfigData;
    CHAR Buffer[128];
    ULONG ExtendedId, Dummy;
    PKPRCB Prcb;
    USHORT IndexTable[MaximumType + 1] = {0};
    ANSI_STRING TempString;
    PCHAR PartialString = NULL, BiosVersion;
    CHAR CpuString[48];
    PVOID BaseAddress = NULL;
    LARGE_INTEGER ViewBase = {{0}};
    ULONG_PTR VideoRomBase;
    PCHAR CurrentVersion;

    /* Open the SMSS Memory Management key */
    RtlInitUnicodeString(&KeyName,
                         L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\"
                         L"Control\\Session Manager\\Memory Management");
    InitializeObjectAttributes(&ObjectAttributes,
                               &KeyName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);
    Status = NtOpenKey(&KeyHandle, KEY_READ | KEY_WRITE, &ObjectAttributes);
    if (NT_SUCCESS(Status))
    {
        /* Detect if PAE is enabled */
        HavePae = SharedUserData->ProcessorFeatures[PF_PAE_ENABLED];

        /* Set the value */
        RtlInitUnicodeString(&ValueName, L"PhysicalAddressExtension");
        NtSetValueKey(KeyHandle,
                      &ValueName,
                      0,
                      REG_DWORD,
                      &HavePae,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -