00369 :
00370
00371 This routine creates x86 specific entries in
the registry.
00372
00373 Arguments:
00374
00375 LoaderBlock - supplies a pointer to
the LoaderBlock passed in from
the
00376 OS Loader.
00377
00378 Returns:
00379
00380
NTSTATUS code
for sucess or
reason of
failure.
00381
00382 --*/
00383 {
00384
NTSTATUS Status;
00385 ULONG VideoBiosStart;
00386 UNICODE_STRING
KeyName;
00387 UNICODE_STRING
ValueName;
00388 UNICODE_STRING ValueData;
00389 ANSI_STRING AnsiString;
00390 OBJECT_ATTRIBUTES
ObjectAttributes;
00391 ULONG Disposition;
00392 HANDLE ParentHandle;
00393 HANDLE BaseHandle, NpxHandle;
00394 HANDLE CurrentControlSet;
00395
CONFIGURATION_COMPONENT_DATA CurrentEntry;
00396 PUCHAR VendorID;
00397 UCHAR
Buffer[
MAXIMUM_BIOS_VERSION_LENGTH];
00398 PKPRCB Prcb;
00399 ULONG i, Junk;
00400 ULONG VersionsLength = 0, Length;
00401 PCHAR VersionStrings, VersionPointer;
00402 UNICODE_STRING SectionName;
00403 ULONG ViewSize;
00404 LARGE_INTEGER ViewBase;
00405 PVOID BaseAddress;
00406 HANDLE SectionHandle;
00407
USHORT DeviceIndexTable[
NUMBER_TYPES];
00408 ULONG CpuIdFunction;
00409 ULONG MaxExtFn;
00410 PULONG NameString =
NULL;
00411
struct {
00412
union {
00413 UCHAR Bytes[
CPUID_PROCESSOR_NAME_STRING_SZ];
00414 ULONG DWords[1];
00415 } u;
00416 } ProcessorNameString;
00417
00418
for (i = 0; i <
NUMBER_TYPES; i++) {
00419 DeviceIndexTable[i] = 0;
00420 }
00421
00422 InitializeObjectAttributes( &ObjectAttributes,
00423 &CmRegistryMachineHardwareDescriptionSystemName,
00424 OBJ_CASE_INSENSITIVE,
00425 NULL,
00426 NULL
00427 );
00428
00429
Status =
NtOpenKey( &ParentHandle,
00430 KEY_READ,
00431 &ObjectAttributes
00432 );
00433
00434
if (!
NT_SUCCESS(Status)) {
00435
00436
return Status;
00437 }
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
RtlInitUnicodeString( &KeyName,
00449 L
"CentralProcessor"
00450 );
00451
00452 InitializeObjectAttributes(
00453 &ObjectAttributes,
00454 &KeyName,
00455 0,
00456 ParentHandle,
00457 NULL
00458 );
00459
00460
ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;
00461
00462
Status =
NtCreateKey(
00463 &BaseHandle,
00464 KEY_READ | KEY_WRITE,
00465 &ObjectAttributes,
00466 TITLE_INDEX_VALUE,
00467 &CmClassName[ProcessorClass],
00468 0,
00469 &Disposition
00470 );
00471
00472
NtClose (BaseHandle);
00473
00474
if (Disposition == REG_CREATED_NEW_KEY) {
00475
00476
00477
00478
00479
00480
00481
CmpConfigurationData = (PCM_FULL_RESOURCE_DESCRIPTOR)
ExAllocatePool(
00482 PagedPool,
00483 CmpConfigurationAreaSize
00484 );
00485
00486
if (
CmpConfigurationData ==
NULL) {
00487
00488
NtClose (ParentHandle);
00489
return(STATUS_INSUFFICIENT_RESOURCES);
00490 }
00491
00492
for (i=0; i < (ULONG)
KeNumberProcessors; i++) {
00493 Prcb =
KiProcessorBlock[i];
00494
00495 RtlZeroMemory (&CurrentEntry,
sizeof CurrentEntry);
00496 CurrentEntry.
ComponentEntry.
Class =
ProcessorClass;
00497 CurrentEntry.
ComponentEntry.
Type =
CentralProcessor;
00498 CurrentEntry.
ComponentEntry.
Key = i;
00499 CurrentEntry.
ComponentEntry.
AffinityMask = 1 << i;
00500
00501 CurrentEntry.
ComponentEntry.
Identifier =
Buffer;
00502
#ifndef _IA64_
00503
if (Prcb->CpuID == 0) {
00504
00505
00506
00507
00508
00509
sprintf (Buffer, CmpID1,
00510 Prcb->CpuType,
00511 (Prcb->CpuStep >> 8) +
'A',
00512 Prcb->CpuStep & 0xff
00513 );
00514
00515 }
else {
00516
00517
00518
00519
00520
00521
sprintf (Buffer, CmpID2,
00522 Prcb->CpuType,
00523 (Prcb->CpuStep >> 8),
00524 Prcb->CpuStep & 0xff
00525 );
00526 }
00527
#endif _IA64_
00528
00529 CurrentEntry.
ComponentEntry.
IdentifierLength =
00530
strlen (Buffer) + 1;
00531
00532
Status =
CmpInitializeRegistryNode(
00533 &CurrentEntry,
00534 ParentHandle,
00535 &BaseHandle,
00536 -1,
00537 (ULONG)-1,
00538 DeviceIndexTable
00539 );
00540
00541
if (!
NT_SUCCESS(Status)) {
00542
return(
Status);
00543 }
00544
00545
00546
#ifndef _IA64_
00547
if (
KeI386NpxPresent) {
00548 RtlZeroMemory (&CurrentEntry,
sizeof CurrentEntry);
00549 CurrentEntry.
ComponentEntry.
Class =
ProcessorClass;
00550 CurrentEntry.
ComponentEntry.
Type =
FloatingPointProcessor;
00551 CurrentEntry.
ComponentEntry.
Key = i;
00552 CurrentEntry.
ComponentEntry.
AffinityMask = 1 << i;
00553
00554 CurrentEntry.
ComponentEntry.
Identifier =
Buffer;
00555
00556
if (Prcb->CpuType == 3) {
00557
00558
00559
00560
00561
00562
00563 strcpy (Buffer,
"80387");
00564 }
00565
00566 CurrentEntry.
ComponentEntry.
IdentifierLength =
00567
strlen (Buffer) + 1;
00568
00569
Status =
CmpInitializeRegistryNode(
00570 &CurrentEntry,
00571 ParentHandle,
00572 &NpxHandle,
00573 -1,
00574 (ULONG)-1,
00575 DeviceIndexTable
00576 );
00577
00578
if (!
NT_SUCCESS(Status)) {
00579
NtClose(BaseHandle);
00580
return(
Status);
00581 }
00582
00583
NtClose(NpxHandle);
00584 }
00585
00586
00587
00588
00589
00590
00591 VendorID = Prcb->CpuID ? Prcb->VendorString :
NULL;
00592
00593
00594
00595
00596
00597
00598
KeSetSystemAffinityThread(Prcb->SetMember);
00599
00600
if (!Prcb->CpuID) {
00601
00602
00603
00604
00605
00606
if (
Ke386CyrixId ()) {
00607 VendorID =
CmpCyrixID;
00608 }
00609 }
else {
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
if (strcmp(VendorID, CmpAmdID) == 0) {
00621
00622
CPUID(CPUID_EXTFN_BASE, &MaxExtFn, &Junk, &Junk, &Junk);
00623
00624
if (MaxExtFn >= (
CPUID_EXTFN_PROCESSOR_NAME + 2)) {
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634 NameString = &ProcessorNameString.u.DWords[0];
00635
00636
for (CpuIdFunction =
CPUID_EXTFN_PROCESSOR_NAME;
00637 CpuIdFunction <= (
CPUID_EXTFN_PROCESSOR_NAME+2);
00638 CpuIdFunction++) {
00639
00640
CPUID(CpuIdFunction,
00641 NameString,
00642 NameString + 1,
00643 NameString + 2,
00644 NameString + 3);
00645 NameString += 4;
00646 }
00647
00648
00649
00650
00651
00652 ProcessorNameString.u.Bytes[
CPUID_PROCESSOR_NAME_STRING_SZ-1] = 0;
00653 }
00654 }
00655 }
00656
00657
00658
00659
00660
00661
KeRevertToUserAffinityThread();
00662
00663
if (NameString) {
00664
00665
00666
00667
00668
00669
RtlInitUnicodeString(
00670 &ValueName,
00671 CmpProcessorNameString
00672 );
00673
00674
RtlInitAnsiString(
00675 &AnsiString,
00676 ProcessorNameString.u.Bytes
00677 );
00678
00679
RtlAnsiStringToUnicodeString(
00680 &ValueData,
00681 &AnsiString,
00682 TRUE
00683 );
00684
00685
Status =
NtSetValueKey(
00686 BaseHandle,
00687 &ValueName,
00688 TITLE_INDEX_VALUE,
00689 REG_SZ,
00690 ValueData.Buffer,
00691 ValueData.Length +
sizeof( UNICODE_NULL )
00692 );
00693
00694
RtlFreeUnicodeString(&ValueData);
00695 }
00696
00697
if (VendorID) {
00698
00699
00700
00701
00702
00703
RtlInitUnicodeString(
00704 &ValueName,
00705 CmpVendorID
00706 );
00707
00708
RtlInitAnsiString(
00709 &AnsiString,
00710 VendorID
00711 );
00712
00713
RtlAnsiStringToUnicodeString(
00714 &ValueData,
00715 &AnsiString,
00716 TRUE
00717 );
00718
00719
Status =
NtSetValueKey(
00720 BaseHandle,
00721 &ValueName,
00722 TITLE_INDEX_VALUE,
00723 REG_SZ,
00724 ValueData.Buffer,
00725 ValueData.Length +
sizeof( UNICODE_NULL )
00726 );
00727
00728
RtlFreeUnicodeString(&ValueData);
00729 }
00730
00731
if (Prcb->FeatureBits) {
00732
00733
00734
00735
00736
RtlInitUnicodeString(
00737 &ValueName,
00738 CmpFeatureBits
00739 );
00740
00741
Status =
NtSetValueKey(
00742 BaseHandle,
00743 &ValueName,
00744 TITLE_INDEX_VALUE,
00745 REG_DWORD,
00746 &Prcb->FeatureBits,
00747 sizeof (Prcb->FeatureBits)
00748 );
00749 }
00750
00751
if (Prcb->MHz) {
00752
00753
00754
00755
00756
RtlInitUnicodeString(
00757 &ValueName,
00758 CmpMHz
00759 );
00760
00761
Status =
NtSetValueKey(
00762 BaseHandle,
00763 &ValueName,
00764 TITLE_INDEX_VALUE,
00765 REG_DWORD,
00766 &Prcb->MHz,
00767 sizeof (Prcb->MHz)
00768 );
00769 }
00770
00771
if (Prcb->UpdateSignature.QuadPart) {
00772
00773
00774
00775
00776
RtlInitUnicodeString(
00777 &ValueName,
00778 CmpUpdateSignature
00779 );
00780
00781
Status =
NtSetValueKey(
00782 BaseHandle,
00783 &ValueName,
00784 TITLE_INDEX_VALUE,
00785 REG_BINARY,
00786 &Prcb->UpdateSignature,
00787 sizeof (Prcb->UpdateSignature)
00788 );
00789 }
00790
00791
NtClose(BaseHandle);
00792
#endif _IA64_
00793
}
00794
00795
ExFreePool((PVOID)CmpConfigurationData);
00796 }
00797
00798
#ifndef _IA64_
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
RtlInitUnicodeString(
00809 &SectionName,
00810 L
"\\Device\\PhysicalMemory"
00811 );
00812
00813 InitializeObjectAttributes(
00814 &ObjectAttributes,
00815 &SectionName,
00816 OBJ_CASE_INSENSITIVE,
00817 (HANDLE) NULL,
00818 (PSECURITY_DESCRIPTOR) NULL
00819 );
00820
00821
Status = ZwOpenSection(
00822 &SectionHandle,
00823 SECTION_ALL_ACCESS,
00824 &ObjectAttributes
00825 );
00826
00827
if (!
NT_SUCCESS(Status)) {
00828
00829
00830
00831
00832
00833
goto AllDone;
00834 }
00835
00836
00837
00838
00839
00840
00841 BaseAddress = 0;
00842 ViewSize = 0x1000;
00843 ViewBase.LowPart = 0;
00844 ViewBase.HighPart = 0;
00845
00846
Status =ZwMapViewOfSection(
00847 SectionHandle,
00848 NtCurrentProcess(),
00849 &BaseAddress,
00850 0,
00851 ViewSize,
00852 &ViewBase,
00853 &ViewSize,
00854 ViewUnmap,
00855 MEM_DOS_LIM,
00856 PAGE_READWRITE
00857 );
00858
00859
if (!
NT_SUCCESS(Status)) {
00860 VideoBiosStart =
VIDEO_BIOS_START;
00861 }
else {
00862 VideoBiosStart = (*((PULONG)BaseAddress +
INT10_VECTOR) & 0xFFFF0000) >> 12;
00863 VideoBiosStart += (*((PULONG)BaseAddress +
INT10_VECTOR) & 0x0000FFFF);
00864 VideoBiosStart &= 0xffff8000;
00865
if (VideoBiosStart <
VIDEO_BIOS_START) {
00866 VideoBiosStart =
VIDEO_BIOS_START;
00867 }
00868
Status = ZwUnmapViewOfSection(
00869 NtCurrentProcess(),
00870 BaseAddress
00871 );
00872 }
00873
00874 VersionStrings =
ExAllocatePool(PagedPool, VERSION_DATA_LENGTH);
00875 BaseAddress = 0;
00876 ViewSize =
SYSTEM_BIOS_LENGTH;
00877 ViewBase.LowPart =
SYSTEM_BIOS_START;
00878 ViewBase.HighPart = 0;
00879
00880
Status =ZwMapViewOfSection(
00881 SectionHandle,
00882 NtCurrentProcess(),
00883 &BaseAddress,
00884 0,
00885 ViewSize,
00886 &ViewBase,
00887 &ViewSize,
00888 ViewUnmap,
00889 MEM_DOS_LIM,
00890 PAGE_READWRITE
00891 );
00892
00893
if (
NT_SUCCESS(Status)) {
00894
if (
CmpGetBiosDate(BaseAddress, SYSTEM_BIOS_LENGTH, Buffer)) {
00895
00896
00897
00898
00899
00900
00901
RtlInitUnicodeString(
00902 &ValueName,
00903 L
"SystemBiosDate"
00904 );
00905
00906
RtlInitAnsiString(
00907 &AnsiString,
00908 Buffer
00909 );
00910
00911
RtlAnsiStringToUnicodeString(
00912 &ValueData,
00913 &AnsiString,
00914 TRUE
00915 );
00916
00917
Status =
NtSetValueKey(
00918 ParentHandle,
00919 &ValueName,
00920 TITLE_INDEX_VALUE,
00921 REG_SZ,
00922 ValueData.Buffer,
00923 ValueData.Length +
sizeof( UNICODE_NULL )
00924 );
00925
00926
RtlFreeUnicodeString(&ValueData);
00927 }
00928
00929
if (VersionStrings &&
CmpGetBiosVersion(BaseAddress, SYSTEM_BIOS_LENGTH, Buffer)) {
00930 VersionPointer = VersionStrings;
00931
do {
00932
00933
00934
00935
00936
00937
00938
00939
RtlInitAnsiString(
00940 &AnsiString,
00941 Buffer
00942 );
00943
00944
RtlAnsiStringToUnicodeString(
00945 &ValueData,
00946 &AnsiString,
00947 TRUE
00948 );
00949
00950 Length = ValueData.Length +
sizeof(UNICODE_NULL);
00951 RtlMoveMemory(VersionPointer,
00952 ValueData.Buffer,
00953 Length
00954 );
00955 VersionsLength += Length;
00956
RtlFreeUnicodeString(&ValueData);
00957
if (VersionsLength + (
MAXIMUM_BIOS_VERSION_LENGTH +
00958
sizeof(UNICODE_NULL)) * 2 >
PAGE_SIZE) {
00959
break;
00960 }
00961 VersionPointer += Length;
00962 }
while (
CmpGetBiosVersion(NULL, 0, Buffer));
00963
00964
if (VersionsLength != 0) {
00965
00966
00967
00968
00969
00970 *(PWSTR)VersionPointer = UNICODE_NULL;
00971 VersionsLength +=
sizeof(UNICODE_NULL);
00972
00973
00974
00975
00976
00977
00978
RtlInitUnicodeString(
00979 &ValueName,
00980 L
"SystemBiosVersion"
00981 );
00982
00983
Status =
NtSetValueKey(
00984 ParentHandle,
00985 &ValueName,
00986 TITLE_INDEX_VALUE,
00987 REG_MULTI_SZ,
00988 VersionStrings,
00989 VersionsLength
00990 );
00991 }
00992 }
00993 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
00994 }
00995
00996
00997
00998
00999
01000 BaseAddress = 0;
01001 ViewSize =
VIDEO_BIOS_LENGTH;
01002 ViewBase.LowPart = VideoBiosStart;
01003 ViewBase.HighPart = 0;
01004
01005
Status =ZwMapViewOfSection(
01006 SectionHandle,
01007 NtCurrentProcess(),
01008 &BaseAddress,
01009 0,
01010 ViewSize,
01011 &ViewBase,
01012 &ViewSize,
01013 ViewUnmap,
01014 MEM_DOS_LIM,
01015 PAGE_READWRITE
01016 );
01017
01018
if (
NT_SUCCESS(Status)) {
01019
if (
CmpGetBiosDate(BaseAddress, VIDEO_BIOS_LENGTH, Buffer)) {
01020
01021
RtlInitUnicodeString(
01022 &ValueName,
01023 L
"VideoBiosDate"
01024 );
01025
01026
RtlInitAnsiString(
01027 &AnsiString,
01028 Buffer
01029 );
01030
01031
RtlAnsiStringToUnicodeString(
01032 &ValueData,
01033 &AnsiString,
01034 TRUE
01035 );
01036
01037
Status =
NtSetValueKey(
01038 ParentHandle,
01039 &ValueName,
01040 TITLE_INDEX_VALUE,
01041 REG_SZ,
01042 ValueData.Buffer,
01043 ValueData.Length +
sizeof( UNICODE_NULL )
01044 );
01045
01046
RtlFreeUnicodeString(&ValueData);
01047 }
01048
01049
if (VersionStrings &&
CmpGetBiosVersion(BaseAddress, VIDEO_BIOS_LENGTH, Buffer)) {
01050 VersionPointer = VersionStrings;
01051
do {
01052
01053
01054
01055
01056
01057
01058
01059
RtlInitAnsiString(
01060 &AnsiString,
01061 Buffer
01062 );
01063
01064
RtlAnsiStringToUnicodeString(
01065 &ValueData,
01066 &AnsiString,
01067 TRUE
01068 );
01069
01070 Length = ValueData.Length +
sizeof(UNICODE_NULL);
01071 RtlMoveMemory(VersionPointer,
01072 ValueData.Buffer,
01073 Length
01074 );
01075 VersionsLength += Length;
01076
RtlFreeUnicodeString(&ValueData);
01077
if (VersionsLength + (
MAXIMUM_BIOS_VERSION_LENGTH +
01078
sizeof(UNICODE_NULL)) * 2 >
PAGE_SIZE) {
01079
break;
01080 }
01081 VersionPointer += Length;
01082 }
while (
CmpGetBiosVersion(NULL, 0, Buffer));
01083
01084
if (VersionsLength != 0) {
01085
01086
01087
01088
01089
01090 *(PWSTR)VersionPointer = UNICODE_NULL;
01091 VersionsLength +=
sizeof(UNICODE_NULL);
01092
01093
RtlInitUnicodeString(
01094 &ValueName,
01095 L
"VideoBiosVersion"
01096 );
01097
01098
Status =
NtSetValueKey(
01099 ParentHandle,
01100 &ValueName,
01101 TITLE_INDEX_VALUE,
01102 REG_MULTI_SZ,
01103 VersionStrings,
01104 VersionsLength
01105 );
01106 }
01107 }
01108 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
01109 }
01110 ZwClose(SectionHandle);
01111
if (VersionStrings) {
01112
ExFreePool((PVOID)VersionStrings);
01113 }
01114
01115 AllDone:
01116
01117
#endif _IA64_
01118
01119
NtClose (ParentHandle);
01120
01121
01122
01123
01124
01125
return STATUS_SUCCESS;
01126 }
}