00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
#include "cmp.h"
00028
#include "stdlib.h"
00029
#include "parseini.h"
00030
#include "geninst.h"
00031
#include "rules.h"
00032
#include "acpitabl.h"
00033
#include "ntacpi.h"
00034
00035 #define TABLE_ENTRIES_FROM_RSDT_POINTER(p) (((p)->Header.Length-min((p)->Header.Length, sizeof(DESCRIPTION_HEADER))) / 4)
00036
00037
00038
00039
00040
00041
00042 #define SYSTEM_BIOS_LENGTH 0x10000
00043
00044
00045
00046
00047
00048 #define PNPBIOS_SIGNATURE 'PnP$'
00049
00050
typedef
00051 BOOLEAN
00052 (* PFN_RULE)(
00053 IN PVOID InfHandle,
00054 IN PCHAR
Description,
00055 IN ULONG RuleIndex
00056 );
00057
00058 typedef struct _PNP_BIOS_TABLE PNP_BIOS_TABLE, *
PPNP_BIOS_TABLE;
00059
00060
#pragma pack(push, 1)
00061
00062 struct _PNP_BIOS_TABLE
00063 {
00064 ULONG
Signature;
00065 UCHAR
Version;
00066 UCHAR
Length;
00067 USHORT ControlField;
00068 UCHAR
CheckSum;
00069 ULONG
EventNotification;
00070 USHORT RMOffset;
00071 USHORT RMSegment;
00072 USHORT PMOffset;
00073 ULONG
PMSegment;
00074 ULONG
Oem;
00075 USHORT RMData;
00076 ULONG
PMData;
00077 };
00078
00079
#pragma pack(pop)
00080
00081 ULONG
00082
CmpComputeChecksum(
00083 IN PCHAR Address,
00084 IN ULONG Size
00085 );
00086
00087
NTSTATUS
00088
CmpFindRSDTTable(
00089 OUT
PACPI_BIOS_MULTI_NODE *Rsdt
00090 );
00091
00092
NTSTATUS
00093
CmpGetRegistryValue(
00094 IN HANDLE KeyName,
00095 IN PWSTR ValueName,
00096 OUT PKEY_VALUE_PARTIAL_INFORMATION *Information
00097 );
00098
00099
PDESCRIPTION_HEADER
00100
CmpFindACPITable(
00101 IN ULONG Signature,
00102 IN OUT PULONG Length
00103 );
00104
00105 BOOLEAN
00106
CmpCheckOperator(
00107 IN PCHAR Operator,
00108 IN ULONG Lhs,
00109 IN ULONG Rhs
00110 );
00111
00112 PVOID
00113
CmpMapPhysicalAddress(
00114 IN OUT PVOID *BaseAddress,
00115 IN ULONG Address,
00116 IN ULONG Size
00117 );
00118
00119 BOOLEAN
00120
CmpGetInfData(
00121 IN PVOID InfHandle,
00122 IN PCHAR Section,
00123 IN ULONG KeyIndex,
00124 IN ULONG LineIndex,
00125 IN OUT PCHAR Buffer,
00126 IN OUT PULONG BufferSize
00127 );
00128
00129 PVOID
00130
CmpFindPattern(
00131 IN PCHAR Buffer,
00132 IN ULONG BufSize,
00133 IN PCHAR Pattern,
00134 IN ULONG PatSize,
00135 IN BOOLEAN IgnoreCase,
00136 IN ULONG Step
00137 );
00138
00139 ULONG
00140
CmpGetPnPBIOSTableAddress(
00141 VOID
00142 );
00143
00144 BOOLEAN
00145
CmpMatchDescription(
00146 IN PVOID InfHandle,
00147 IN PCHAR Description
00148 );
00149
00150 BOOLEAN
00151
CmpMatchDateRule(
00152 IN PVOID InfHandle,
00153 IN PCHAR Description,
00154 IN ULONG RuleIndex
00155 );
00156
00157 BOOLEAN
00158
CmpMatchMemoryRule(
00159 IN PVOID InfHandle,
00160 IN PCHAR Description,
00161 IN ULONG RuleIndex
00162 );
00163
00164 BOOLEAN
00165
CmpMatchSearchRule(
00166 IN PVOID InfHandle,
00167 IN PCHAR Description,
00168 IN ULONG RuleIndex
00169 );
00170
00171 BOOLEAN
00172
CmpMatchNextMatchRule(
00173 IN PVOID InfHandle,
00174 IN PCHAR Description,
00175 IN ULONG RuleIndex
00176 );
00177
00178 BOOLEAN
00179
CmpMatchPointerRule(
00180 IN PVOID InfHandle,
00181 IN PCHAR Description,
00182 IN ULONG RuleIndex
00183 );
00184
00185 BOOLEAN
00186
CmpMatchOemIdRule(
00187 IN PVOID InfHandle,
00188 IN PCHAR Description,
00189 IN ULONG RuleIndex
00190 );
00191
00192 BOOLEAN
00193
CmpMatchPModeRule(
00194 IN PVOID InfHandle,
00195 IN PCHAR Description,
00196 IN ULONG RuleIndex
00197 );
00198
00199 BOOLEAN
00200
CmpMatchRmPmSameRule(
00201 IN PVOID InfHandle,
00202 IN PCHAR Description,
00203 IN ULONG RuleIndex
00204 );
00205
00206 BOOLEAN
00207
CmpMatchInstallRule(
00208 IN PVOID InfHandle,
00209 IN PCHAR Description,
00210 IN ULONG RuleIndex
00211 );
00212
00213 BOOLEAN
00214
CmpMatchAcpiOemIdRule(
00215 IN PVOID InfHandle,
00216 IN PCHAR Description,
00217 IN ULONG RuleIndex
00218 );
00219
00220 BOOLEAN
00221
CmpMatchAcpiOemTableIdRule(
00222 IN PVOID InfHandle,
00223 IN PCHAR Description,
00224 IN ULONG RuleIndex
00225 );
00226
00227 BOOLEAN
00228
CmpMatchAcpiOemRevisionRule(
00229 IN PVOID InfHandle,
00230 IN PCHAR Description,
00231 IN ULONG RuleIndex
00232 );
00233
00234 BOOLEAN
00235
CmpMatchAcpiRevisionRule(
00236 IN PVOID InfHandle,
00237 IN PCHAR Description,
00238 IN ULONG RuleIndex
00239 );
00240
00241 BOOLEAN
00242
CmpMatchAcpiCreatorRevisionRule(
00243 IN PVOID InfHandle,
00244 IN PCHAR Description,
00245 IN ULONG RuleIndex
00246 );
00247
00248
00249
00250
00251
00252 #define NUM_OF_RULES 14
00253
00254
00255
00256
00257
00258
struct {
00259 PCHAR
Name;
00260 PFN_RULE Action;
00261 }
gRuleTable[
NUM_OF_RULES] =
00262 {
00263 {
"Date",
CmpMatchDateRule},
00264 {
"Memory",
CmpMatchMemoryRule},
00265 {
"Search",
CmpMatchSearchRule},
00266 {
"NextMatch",
CmpMatchNextMatchRule},
00267 {
"Pointer",
CmpMatchPointerRule},
00268 {
"OemId",
CmpMatchOemIdRule},
00269 {
"PMode",
CmpMatchPModeRule},
00270 {
"RmPmSame",
CmpMatchRmPmSameRule},
00271 {
"Install",
CmpMatchInstallRule},
00272 {
"ACPIOemId",
CmpMatchAcpiOemIdRule},
00273 {
"ACPIOemTableId",
CmpMatchAcpiOemTableIdRule},
00274 {
"ACPIOemRevision",
CmpMatchAcpiOemRevisionRule},
00275 {
"ACPIRevision",
CmpMatchAcpiRevisionRule},
00276 {
"ACPICreatorRevision",
CmpMatchAcpiCreatorRevisionRule}
00277 };
00278
00279 PVOID
gSearchAddress =
NULL;
00280
00281 static WCHAR
rgzMultiFunctionAdapter[] =
L"\\Registry\\Machine\\Hardware\\Description\\System\\MultifunctionAdapter";
00282 static WCHAR
rgzAcpiConfigurationData[] =
L"Configuration Data";
00283 static WCHAR
rgzAcpiIdentifier[] =
L"Identifier";
00284 static WCHAR
rgzBIOSIdentifier[] =
L"ACPI BIOS";
00285
00286
#ifdef ALLOC_PRAGMA
00287
#pragma alloc_text(INIT,CmpFindACPITable)
00288
#pragma alloc_text(INIT,CmpFindRSDTTable)
00289
#pragma alloc_text(INIT,CmpComputeChecksum)
00290
#pragma alloc_text(INIT,CmpCheckOperator)
00291
#pragma alloc_text(INIT,CmpMapPhysicalAddress)
00292
#pragma alloc_text(INIT,CmpGetInfData)
00293
#pragma alloc_text(INIT,CmpFindPattern)
00294
#pragma alloc_text(INIT,CmpGetPnPBIOSTableAddress)
00295
#pragma alloc_text(INIT,CmpMatchInfList)
00296
#pragma alloc_text(INIT,CmpMatchDescription)
00297
#pragma alloc_text(INIT,CmpMatchDateRule)
00298
#pragma alloc_text(INIT,CmpMatchMemoryRule)
00299
#pragma alloc_text(INIT,CmpMatchSearchRule)
00300
#pragma alloc_text(INIT,CmpMatchNextMatchRule)
00301
#pragma alloc_text(INIT,CmpMatchPointerRule)
00302
#pragma alloc_text(INIT,CmpMatchOemIdRule)
00303
#pragma alloc_text(INIT,CmpMatchPModeRule)
00304
#pragma alloc_text(INIT,CmpMatchRmPmSameRule)
00305
#pragma alloc_text(INIT,CmpMatchInstallRule)
00306
#pragma alloc_text(INIT,CmpMatchAcpiOemIdRule)
00307
#pragma alloc_text(INIT,CmpMatchAcpiOemTableIdRule)
00308
#pragma alloc_text(INIT,CmpMatchAcpiOemRevisionRule)
00309
#pragma alloc_text(INIT,CmpMatchAcpiRevisionRule)
00310
#pragma alloc_text(INIT,CmpMatchAcpiCreatorRevisionRule)
00311
#endif
00312
00313
00314 BOOLEAN
00315 CmpMatchInfList(
00316 IN PVOID InfImage,
00317 IN ULONG ImageSize,
00318 IN PCHAR Section
00319 )
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341 {
00342 PCHAR computerName;
00343 ULONG i = 0;
00344 PVOID infHandle;
00345 BOOLEAN result =
FALSE;
00346
00347 infHandle =
CmpOpenInfFile(InfImage, ImageSize);
00348
00349
if (infHandle)
00350 {
00351
00352
00353
00354
00355
CmpGenInstall(infHandle,
"Cleanup");
00356
00357
00358
00359
00360
00361
00362
while ((computerName =
CmpGetSectionLineIndex(infHandle, Section, i++, 0)))
00363 {
00364
00365
00366
00367
00368
gSearchAddress =
NULL;
00369
00370
00371
00372
00373
00374
00375
00376
if (
CmpMatchDescription(infHandle, computerName))
00377 {
00378
DbgPrint(
"CmpMatchInfList: Machine matches %s description!\n", computerName);
00379 result =
TRUE;
00380 }
00381 }
00382
00383
CmpCloseInfFile(infHandle);
00384 }
00385
00386
00387
00388
00389
00390
return (result);
00391 }
00392
00393 BOOLEAN
00394 CmpMatchDescription(
00395 IN PVOID InfHandle,
00396 IN PCHAR Description
00397 )
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417 {
00418 ULONG ruleNumber;
00419 ULONG i;
00420 PCHAR ruleName;
00421
00422
00423
00424
00425
00426
if (
CmpSearchInfSection(InfHandle,
Description))
00427 {
00428
00429
00430
00431
00432
00433 ruleNumber = 0;
00434
while ((ruleName =
CmpGetKeyName(InfHandle,
Description, ruleNumber)))
00435 {
00436
00437
00438
00439
00440
for ( i = 0;
00441 i <
NUM_OF_RULES &&
00442 _stricmp(ruleName,
gRuleTable[i].
Name);
00443 i++);
00444
00445
00446
00447
00448
00449
00450
if ( i >=
NUM_OF_RULES ||
00451 !(*
gRuleTable[i].Action)(InfHandle,
Description, ruleNumber++))
00452 {
00453
return (
FALSE);
00454 }
00455 }
00456
00457
00458
00459
00460
00461
00462
if (ruleNumber)
00463 {
00464
return (
TRUE);
00465 }
00466 }
00467
00468
00469
00470
00471
00472
return (
FALSE);
00473 }
00474
00475 BOOLEAN
00476 CmpMatchDateRule(
00477 IN PVOID InfHandle,
00478 IN PCHAR Description,
00479 IN ULONG RuleIndex
00480 )
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515 {
00516 PCHAR op;
00517 PCHAR month;
00518 PCHAR day;
00519 PCHAR year;
00520 ULONG infDate;
00521 ULONG yr;
00522 ULONG biosDate;
00523
CHAR temp[3];
00524 PVOID baseAddress;
00525 PCHAR address;
00526
00527 op =
CmpGetSectionLineIndex(InfHandle,
Description, RuleIndex, 0);
00528 month =
CmpGetSectionLineIndex(InfHandle,
Description, RuleIndex, 1);
00529 day =
CmpGetSectionLineIndex(InfHandle,
Description, RuleIndex, 2);
00530 year =
CmpGetSectionLineIndex(InfHandle,
Description, RuleIndex, 3);
00531
00532
if (op && month && day && year)
00533 {
00534 yr = strtoul(year,
NULL, 16);
00535 infDate = ((yr < 0x80) ? 0x20000000 : 0x19000000) +
00536 (yr << 16) +
00537 (strtoul(month,
NULL, 16) << 8) +
00538 (strtoul(day,
NULL, 16));
00539
00540 address =
CmpMapPhysicalAddress(&baseAddress, 0xFFFF5, 8);
00541
if (address)
00542 {
00543 temp[2] =
'\0';
00544
00545 RtlCopyBytes(temp, address + 6, 2);
00546 yr = strtoul(temp,
NULL, 16);
00547 biosDate = ((yr < 0x80) ? 0x20000000 : 0x19000000) +
00548 (yr << 16);
00549
00550 RtlCopyBytes(temp, address, 2);
00551 biosDate |= (strtoul(temp,
NULL, 16) << 8);
00552
00553 RtlCopyBytes(temp, address + 3, 2);
00554 biosDate |= strtoul(temp,
NULL, 16);
00555
00556 ZwUnmapViewOfSection(NtCurrentProcess(), baseAddress);
00557
00558
if (
CmpCheckOperator(op, biosDate, infDate))
00559 {
00560
return (
TRUE);
00561 }
00562 }
00563 }
00564
00565
return (
FALSE);
00566 }
00567
00568 BOOLEAN
00569 CmpMatchMemoryRule(
00570 IN PVOID InfHandle,
00571 IN PCHAR Description,
00572 IN ULONG RuleIndex
00573 )
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611 {
00612 BOOLEAN match =
FALSE;
00613 PCHAR segment;
00614 PCHAR offset;
00615
CHAR data[
MAX_DESCRIPTION_LEN + 1];
00616 ULONG cbData;
00617 PVOID baseAddress;
00618 PCHAR address;
00619 ULONG memory;
00620
00621
00622
00623
00624
00625 segment =
CmpGetSectionLineIndex(InfHandle,
Description, RuleIndex, 0);
00626 offset =
CmpGetSectionLineIndex(InfHandle,
Description, RuleIndex, 1);
00627
00628
if (segment && offset)
00629 {
00630
00631
00632
00633
00634 cbData =
sizeof(data);
00635
if (
CmpGetInfData(InfHandle,
Description, RuleIndex, 2, data, &cbData))
00636 {
00637 memory = (strtoul(segment,
NULL, 16) << 4) + strtoul(offset,
NULL, 16);
00638
00639
00640
00641
00642
00643 address =
CmpMapPhysicalAddress(&baseAddress, memory, cbData);
00644
if (address)
00645 {
00646
00647
00648
00649
00650
00651 match = (RtlCompareMemory(address, data, cbData) == cbData);
00652
00653
00654
00655
00656
00657 ZwUnmapViewOfSection(NtCurrentProcess(), baseAddress);
00658 }
00659 }
00660 }
00661
00662
return (match);
00663 }
00664
00665 BOOLEAN
00666 CmpMatchSearchRule(
00667 IN PVOID InfHandle,
00668 IN PCHAR Description,
00669 IN ULONG RuleIndex
00670 )
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704 {
00705 BOOLEAN match =
FALSE;
00706 PCHAR segment;
00707 PCHAR offset;
00708 PCHAR size;
00709
CHAR data[
MAX_DESCRIPTION_LEN + 1];
00710 ULONG cbData;
00711 ULONG memory;
00712 ULONG length;
00713 PVOID baseAddress;
00714 PCHAR address;
00715
00716 segment =
CmpGetSectionLineIndex(InfHandle,
Description, RuleIndex, 0);
00717 offset =
CmpGetSectionLineIndex(InfHandle,
Description, RuleIndex, 1);
00718 size =
CmpGetSectionLineIndex(InfHandle,
Description, RuleIndex, 2);
00719
00720
if (segment && offset && size)
00721 {
00722
00723
00724
00725
00726 cbData =
sizeof(data);
00727
if (
CmpGetInfData(InfHandle,
Description, RuleIndex, 3, data, &cbData))
00728 {
00729 memory = (strtoul(segment,
NULL, 16) << 4) + strtoul(offset,
NULL, 16);
00730
00731
00732
00733
00734
00735 length = strtoul(size,
NULL, 16);
00736 address =
CmpMapPhysicalAddress(&baseAddress, memory, length);
00737
if (address)
00738 {
00739
gSearchAddress =
CmpFindPattern(address, length, data, cbData,
FALSE, 0);
00740
if (
gSearchAddress)
00741 {
00742
00743
00744
00745
00746 (PCHAR)
gSearchAddress -= (ULONG)address;
00747 (PCHAR)
gSearchAddress += memory;
00748 match =
TRUE;
00749 }
00750
00751
00752
00753
00754
00755 ZwUnmapViewOfSection(NtCurrentProcess(), baseAddress);
00756 }
00757 }
00758 }
00759
00760
return (match);
00761 }
00762
00763 BOOLEAN
00764 CmpMatchNextMatchRule(
00765 IN PVOID InfHandle,
00766 IN PCHAR Description,
00767 IN ULONG RuleIndex
00768 )
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802 {
00803 BOOLEAN match =
FALSE;
00804 PCHAR offset;
00805
CHAR data[
MAX_DESCRIPTION_LEN + 1];
00806 ULONG cbData;
00807 PVOID baseAddress;
00808 PCHAR address;
00809
00810
if (
gSearchAddress)
00811 {
00812 offset =
CmpGetSectionLineIndex(InfHandle,
Description, RuleIndex, 0);
00813
if (offset)
00814 {
00815
00816
00817
00818
00819 cbData =
sizeof(data);
00820
00821
if (
CmpGetInfData(InfHandle,
Description, RuleIndex, 1, data, &cbData))
00822 {
00823 (PCHAR)
gSearchAddress += strtoul(offset,
NULL, 16);
00824
00825
00826
00827
00828
00829 address =
CmpMapPhysicalAddress(&baseAddress, (ULONG)
gSearchAddress, cbData);
00830
if (address)
00831 {
00832
00833
00834
00835
00836
00837 match = (RtlCompareMemory(address, data, cbData) == cbData);
00838
00839
00840
00841
00842
00843 ZwUnmapViewOfSection(NtCurrentProcess(), baseAddress);
00844 }
00845 }
00846 }
00847 }
00848
00849
return (match);
00850 }
00851
00852 BOOLEAN
00853 CmpMatchPointerRule(
00854 IN PVOID InfHandle,
00855 IN PCHAR Description,
00856 IN ULONG RuleIndex
00857 )
00858 {
00859 BOOLEAN match =
FALSE;
00860 PCHAR segment1;
00861 PCHAR offset1;
00862 PCHAR segment2;
00863 PCHAR offset2;
00864 PCHAR index;
00865 PCHAR op;
00866
CHAR data[
MAX_DESCRIPTION_LEN + 1];
00867 ULONG cbData;
00868 ULONG memory;
00869 ULONG pointer;
00870 PVOID baseAddress;
00871 PCHAR address;
00872
00873 segment1 =
CmpGetSectionLineIndex(InfHandle,
Description, RuleIndex, 0);
00874 offset1 =
CmpGetSectionLineIndex(InfHandle,
Description, RuleIndex, 1);
00875 segment2 =
CmpGetSectionLineIndex(InfHandle,
Description, RuleIndex, 2);
00876 offset2 =
CmpGetSectionLineIndex(InfHandle,
Description, RuleIndex, 3);
00877 index =
CmpGetSectionLineIndex(InfHandle,
Description, RuleIndex, 4);
00878 op =
CmpGetSectionLineIndex(InfHandle,
Description, RuleIndex, 5);
00879
00880
if ( segment1 && offset1 &&
00881 segment2 && offset2 &&
00882 index && op)
00883 {
00884
00885
00886
00887
00888 cbData =
sizeof(data);
00889
00890
if (
CmpGetInfData(InfHandle,
Description, RuleIndex, 6, data, &cbData))
00891 {
00892
if (
strlen(offset2) == 0)
00893 {
00894 memory = strtoul(segment2,
NULL, 16) << 4;
00895 }
00896
else
00897 {
00898 memory = (strtoul(segment2,
NULL, 16) << 4) + strtoul(offset2,
NULL, 16);
00899 }
00900
00901 address =
CmpMapPhysicalAddress(&baseAddress, memory, 4);
00902
if (address)
00903 {
00904 pointer = *((
PUSHORT)address);
00905
00906
00907
00908
00909
00910 ZwUnmapViewOfSection(NtCurrentProcess(), baseAddress);
00911
00912
if (
strlen(offset1) == 0)
00913 {
00914 memory = (strtoul(segment1,
NULL, 16) << 4) + pointer;
00915 }
00916
else
00917 {
00918 memory = (strtoul(segment1,
NULL, 16) << 4) + strtoul(offset1,
NULL, 16);
00919 address =
CmpMapPhysicalAddress(&baseAddress, memory, 2);
00920
if (address)
00921 {
00922 memory = ((*(
PUSHORT)address) << 4) + pointer;
00923
00924
00925
00926
00927
00928 ZwUnmapViewOfSection(NtCurrentProcess(), baseAddress);
00929 }
00930 }
00931
00932 memory += strtoul(index,
NULL, 16);
00933
00934
00935
00936
00937
00938 address =
CmpMapPhysicalAddress(&baseAddress, memory, cbData);
00939
if (address)
00940 {
00941 match =
CmpCheckOperator(op, RtlCompareMemory(address, data, cbData), cbData);
00942
00943
00944
00945
00946
00947 ZwUnmapViewOfSection(NtCurrentProcess(), baseAddress);
00948 }
00949 }
00950 }
00951 }
00952
00953
return (match);
00954 }
00955
00956 BOOLEAN
00957 CmpMatchOemIdRule(
00958 IN PVOID InfHandle,
00959 IN PCHAR Description,
00960 IN ULONG RuleIndex
00961 )
00962 {
00963 BOOLEAN match =
FALSE;
00964 ULONG address;
00965 PCHAR op;
00966 PCHAR oemIdStr;
00967 ULONG oemId;
00968 PCHAR baseAddress;
00969
PPNP_BIOS_TABLE biosTable;
00970
00971
00972
00973
00974
00975 address =
CmpGetPnPBIOSTableAddress();
00976
00977
00978
00979
00980
00981
if (address)
00982 {
00983 op =
CmpGetSectionLineIndex(InfHandle,
Description, RuleIndex, 0);
00984 oemIdStr =
CmpGetSectionLineIndex(InfHandle,
Description, RuleIndex, 1);
00985
if (op && oemIdStr)
00986 {
00987
00988
if (
strlen(oemIdStr) == 7 &&
00989 isalpha(oemIdStr[0]) &&
00990 isalpha(oemIdStr[1]) &&
00991 isalpha(oemIdStr[2]) &&
00992 isxdigit(oemIdStr[3]) &&
00993 isxdigit(oemIdStr[4]) &&
00994 isxdigit(oemIdStr[5]) &&
00995 isxdigit(oemIdStr[6]))
00996 {
00997
00998 biosTable = (
PPNP_BIOS_TABLE)
CmpMapPhysicalAddress(&baseAddress, address,
sizeof(PNP_BIOS_TABLE));
00999
if (biosTable)
01000 {
01001 oemId = ((ULONG)(oemIdStr[0] & 0x1F) << 26) +
01002 ((ULONG)(oemIdStr[1] & 0x1F) << 21) +
01003 ((ULONG)(oemIdStr[2] & 0x1F) << 16) +
01004 strtoul(&oemIdStr[3],
NULL, 16);
01005
01006
01007
01008
01009
01010
if (strcmp(op,
"=") == 0 || strcmp(op,
"==") == 0)
01011 {
01012 match = (oemId == biosTable->Oem);
01013 }
01014
else if( strcmp(op,
"<>") == 0 ||
01015 strcmp(op,
"!=") == 0 ||
01016 strcmp(op,
"=!") == 0)
01017 {
01018 match = (oemId != biosTable->Oem);
01019 }
01020
01021
01022
01023
01024
01025 ZwUnmapViewOfSection(NtCurrentProcess(), baseAddress);
01026 }
01027 }
01028 }
01029 }
01030
01031
return (match);
01032 }
01033
01034 BOOLEAN
01035 CmpMatchPModeRule(
01036 IN PVOID InfHandle,
01037 IN PCHAR Description,
01038 IN ULONG RuleIndex
01039 )
01040 {
01041 BOOLEAN match =
FALSE;
01042 ULONG address;
01043
CHAR data[
MAX_DESCRIPTION_LEN + 1];
01044 ULONG cbData;
01045 PVOID baseAddress;
01046
PPNP_BIOS_TABLE biosTable;
01047 ULONG pmAddress;
01048 PCHAR pmodeEntry;
01049
01050
01051
01052
01053
01054 address =
CmpGetPnPBIOSTableAddress();
01055
01056
01057
01058
01059
01060
if (address)
01061 {
01062
01063
01064
01065
01066 cbData =
sizeof(data);
01067
if (
CmpGetInfData(InfHandle,
Description, RuleIndex, 0, data, &cbData))
01068 {
01069 biosTable = (
PPNP_BIOS_TABLE)
CmpMapPhysicalAddress(&baseAddress, address,
sizeof(PNP_BIOS_TABLE));
01070
if (biosTable)
01071 {
01072 pmAddress = (biosTable->PMSegment << 4) + biosTable->PMOffset;
01073
01074
01075
01076
01077
01078 ZwUnmapViewOfSection(NtCurrentProcess(), baseAddress);
01079
01080 pmodeEntry =
CmpMapPhysicalAddress(&baseAddress, pmAddress,
SYSTEM_BIOS_LENGTH);
01081
if (pmodeEntry)
01082 {
01083
if (*pmodeEntry == 0xE9)
01084 {
01085 pmodeEntry += (3 + (*((
PUSHORT)&pmodeEntry[1])));
01086 }
01087
01088 match = (RtlCompareMemory(pmodeEntry, data, cbData) == cbData);
01089
01090
01091
01092
01093
01094 ZwUnmapViewOfSection(NtCurrentProcess(), baseAddress);
01095 }
01096 }
01097 }
01098 }
01099
01100
return (match);
01101 }
01102
01103 BOOLEAN
01104 CmpMatchRmPmSameRule(
01105 IN PVOID InfHandle,
01106 IN PCHAR Description,
01107 IN ULONG RuleIndex
01108 )
01109 {
01110 BOOLEAN match =
FALSE;
01111 ULONG address;
01112 PCHAR baseAddress;
01113
PPNP_BIOS_TABLE biosTable;
01114
01115
01116
01117
01118
01119 address =
CmpGetPnPBIOSTableAddress();
01120
01121
01122
01123
01124
01125
if (address)
01126 {
01127 biosTable =
CmpMapPhysicalAddress(&baseAddress, address,
sizeof(PNP_BIOS_TABLE));
01128
if (biosTable)
01129 {
01130 match = ( biosTable->RMSegment == biosTable->PMSegment &&
01131 biosTable->RMOffset == biosTable->PMOffset);
01132
01133
01134
01135
01136
01137 ZwUnmapViewOfSection(NtCurrentProcess(), baseAddress);
01138 }
01139 }
01140
01141
return (match);
01142 }
01143
01144 BOOLEAN
01145 CmpMatchInstallRule(
01146 IN PVOID InfHandle,
01147 IN PCHAR Description,
01148 IN ULONG RuleIndex
01149 )
01150 {
01151 BOOLEAN match =
FALSE;
01152 PCHAR install;
01153
01154 install =
CmpGetSectionLineIndex(InfHandle,
Description, RuleIndex, 0);
01155
if (install)
01156 {
01157
if (
CmpGenInstall(InfHandle, install))
01158 {
01159
01160
01161
01162
01163 match =
TRUE;
01164 }
01165 }
01166
01167
return (match);
01168 }
01169
01170 BOOLEAN
01171 CmpMatchAcpiOemIdRule(
01172 IN PVOID InfHandle,
01173 IN PCHAR Description,
01174 IN ULONG RuleIndex
01175 )
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208 {
01209 BOOLEAN anyCase =
FALSE;
01210 BOOLEAN match =
FALSE;
01211 PCHAR tableName;
01212 PCHAR oemId;
01213 PCHAR optionalArgs;
01214 ULONG length;
01215
PDESCRIPTION_HEADER header;
01216
CHAR tableOemId[7];
01217 STRING acpiString;
01218 STRING tableString;
01219
01220 tableName =
CmpGetSectionLineIndex(
01221 InfHandle,
01222
Description,
01223 RuleIndex,
01224 0
01225 );
01226 oemId =
CmpGetSectionLineIndex(
01227 InfHandle,
01228
Description,
01229 RuleIndex,
01230 1
01231 );
01232
if (tableName && oemId) {
01233
01234
01235
01236
01237 optionalArgs =
CmpGetSectionLineIndex(
01238 InfHandle,
01239
Description,
01240 RuleIndex,
01241 2
01242 );
01243
if (optionalArgs) {
01244
01245
if (_stricmp(optionalArgs,
"any") == 0) {
01246
01247 anyCase =
TRUE;
01248
01249 }
01250
01251 }
01252
01253
01254
01255
01256 header =
CmpFindACPITable(*(PULONG)tableName, &length);
01257
if (header) {
01258
01259
01260
01261
01262 RtlZeroMemory(tableOemId,
sizeof(tableOemId));
01263 RtlCopyMemory(tableOemId, header->
OEMID,
sizeof(header->
OEMID));
01264
RtlInitString( &tableString, tableOemId );
01265
01266
01267
01268
01269
RtlInitString( &acpiString, oemId );
01270
01271
01272
01273
01274 match =
RtlEqualString( &acpiString, &tableString, anyCase );
01275
01276
01277
01278
01279
MmUnmapIoSpace(header, length );
01280
01281 }
01282
01283 }
01284
return (match);
01285 }
01286
01287 BOOLEAN
01288 CmpMatchAcpiOemTableIdRule(
01289 IN PVOID InfHandle,
01290 IN PCHAR Description,
01291 IN ULONG RuleIndex
01292 )
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325 {
01326 BOOLEAN match =
FALSE;
01327 PCHAR tableName;
01328 PCHAR oemTableId;
01329 ULONG length;
01330
PDESCRIPTION_HEADER header;
01331 ULONG idLength;
01332
CHAR acpiOemTableId[8];
01333
01334 tableName =
CmpGetSectionLineIndex(
01335 InfHandle,
01336
Description,
01337 RuleIndex,
01338 0
01339 );
01340 oemTableId =
CmpGetSectionLineIndex(
01341 InfHandle,
01342
Description,
01343 RuleIndex,
01344 1
01345 );
01346
if (tableName && oemTableId) {
01347
01348
01349
01350
01351 header =
CmpFindACPITable(*(PULONG)tableName, &length);
01352
if (header) {
01353
01354 RtlZeroMemory(acpiOemTableId,
sizeof(acpiOemTableId));
01355 idLength =
strlen(oemTableId);
01356
if (idLength >
sizeof(acpiOemTableId)) {
01357
01358 idLength =
sizeof(acpiOemTableId);
01359
01360 }
01361 RtlCopyMemory(acpiOemTableId, oemTableId, idLength);
01362 match = RtlEqualMemory(acpiOemTableId, header->
OEMTableID,
sizeof(header->
OEMTableID));
01363
MmUnmapIoSpace( header, length );
01364
01365 }
01366
01367 }
01368
return (match);
01369 }
01370
01371 BOOLEAN
01372 CmpMatchAcpiOemRevisionRule(
01373 IN PVOID InfHandle,
01374 IN PCHAR Description,
01375 IN ULONG RuleIndex
01376 )
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409 {
01410 BOOLEAN match =
FALSE;
01411 PCHAR op;
01412 PCHAR tableName;
01413 PCHAR oemRevisionStr;
01414 ULONG oemRevision;
01415 ULONG length;
01416
PDESCRIPTION_HEADER header;
01417
01418 op =
CmpGetSectionLineIndex(
01419 InfHandle,
01420
Description,
01421 RuleIndex,
01422 0
01423 );
01424 tableName =
CmpGetSectionLineIndex(
01425 InfHandle,
01426
Description,
01427 RuleIndex,
01428 1
01429 );
01430 oemRevisionStr =
CmpGetSectionLineIndex(
01431 InfHandle,
01432
Description,
01433 RuleIndex,
01434 2
01435 );
01436
if (op && tableName && oemRevisionStr) {
01437
01438
01439
01440
01441 header =
CmpFindACPITable(*(PULONG)tableName, &length);
01442
if (header) {
01443
01444
RtlCharToInteger(oemRevisionStr, 16, &oemRevision);
01445 match =
CmpCheckOperator(op, header->
OEMRevision, oemRevision);
01446
MmUnmapIoSpace(header, length);
01447
01448 }
01449
01450 }
01451
return(match);
01452
01453 }
01454
01455 BOOLEAN
01456 CmpMatchAcpiRevisionRule(
01457 IN PVOID InfHandle,
01458 IN PCHAR Description,
01459 IN ULONG RuleIndex
01460 )
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493 {
01494 BOOLEAN match =
FALSE;
01495 PCHAR op;
01496 PCHAR tableName;
01497 PCHAR revisionStr;
01498 ULONG revision;
01499 ULONG length;
01500
PDESCRIPTION_HEADER header;
01501
01502 op =
CmpGetSectionLineIndex(
01503 InfHandle,
01504
Description,
01505 RuleIndex,
01506 0
01507 );
01508 tableName =
CmpGetSectionLineIndex(
01509 InfHandle,
01510
Description,
01511 RuleIndex,
01512 1
01513 );
01514 revisionStr =
CmpGetSectionLineIndex(
01515 InfHandle,
01516
Description,
01517 RuleIndex,
01518 2
01519 );
01520
if (op && tableName && revisionStr){
01521
01522
01523
01524
01525 header =
CmpFindACPITable(*(PULONG)tableName, &length);
01526
if (header) {
01527
01528
RtlCharToInteger(revisionStr, 16, &revision);
01529 match =
CmpCheckOperator(op, header->
Revision, revision);
01530
MmUnmapIoSpace(header, length);
01531
01532 }
01533
01534 }
01535
return(match);
01536
01537 }
01538
01539 BOOLEAN
01540 CmpMatchAcpiCreatorRevisionRule(
01541 IN PVOID InfHandle,
01542 IN PCHAR Description,
01543 IN ULONG RuleIndex
01544 )
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577 {
01578 BOOLEAN match =
FALSE;
01579 PCHAR op;
01580 PCHAR tableName;
01581 PCHAR creatorRevisionStr;
01582 ULONG creatorRevision;
01583 ULONG length;
01584
PDESCRIPTION_HEADER header;
01585
01586 op =
CmpGetSectionLineIndex(
01587 InfHandle,
01588
Description,
01589 RuleIndex,
01590 0
01591 );
01592 tableName =
CmpGetSectionLineIndex(
01593 InfHandle,
01594
Description,
01595 RuleIndex,
01596 1
01597 );
01598 creatorRevisionStr =
CmpGetSectionLineIndex(
01599 InfHandle,
01600
Description,
01601 RuleIndex,
01602 2
01603 );
01604
if (op && tableName && creatorRevisionStr) {
01605
01606
01607
01608
01609 header =
CmpFindACPITable(*(PULONG)tableName, &length);
01610
if (header){
01611
01612
RtlCharToInteger(creatorRevisionStr, 16, &creatorRevision);
01613 match =
CmpCheckOperator(op, header->
CreatorRev, creatorRevision);
01614
MmUnmapIoSpace( header, length );
01615
01616 }
01617
01618 }
01619
return(match);
01620 }
01621
01622 BOOLEAN
01623 CmpMatchAcpiCreatorIdRule(
01624 IN PVOID InfHandle,
01625 IN PCHAR Description,
01626 IN ULONG RuleIndex
01627 )
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656 {
01657 BOOLEAN match =
FALSE;
01658 PCHAR tableName;
01659 PCHAR creatorId;
01660 ULONG length;
01661
PDESCRIPTION_HEADER header;
01662 ULONG idLength;
01663
CHAR acpiCreatorId[6];
01664
01665 tableName =
CmpGetSectionLineIndex(
01666 InfHandle,
01667
Description,
01668 RuleIndex,
01669 0
01670 );
01671 creatorId =
CmpGetSectionLineIndex(
01672 InfHandle,
01673
Description,
01674 RuleIndex,
01675 1
01676 );
01677
if (tableName && creatorId) {
01678
01679
01680
01681
01682 header =
CmpFindACPITable(*(PULONG)tableName, &length);
01683
if (header) {
01684
01685 RtlZeroMemory(acpiCreatorId,
sizeof(acpiCreatorId));
01686 idLength =
strlen(creatorId);
01687
if (idLength >
sizeof(acpiCreatorId)) {
01688
01689 idLength =
sizeof(acpiCreatorId);
01690
01691 }
01692 RtlCopyMemory(acpiCreatorId, creatorId, idLength);
01693 match = RtlEqualMemory(acpiCreatorId, header->
CreatorID,
sizeof(header->
CreatorID));
01694
MmUnmapIoSpace( header, length );
01695
01696 }
01697
01698 }
01699
return(match);
01700 }
01701
01702 BOOLEAN
01703 CmpGetInfData(
01704 IN PVOID InfHandle,
01705 IN PCHAR Section,
01706 IN ULONG LineIndex,
01707 IN ULONG ValueIndex,
01708 IN OUT PCHAR Buffer,
01709 IN OUT PULONG BufferSize
01710 )
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747 {
01748 BOOLEAN result =
FALSE;
01749 ULONG cbData;
01750 PCHAR data;
01751 ULONG remainingBytes;
01752
01753
01754
01755
01756
01757
if (
Buffer &&
BufferSize && *
BufferSize)
01758 {
01759
01760
01761
01762
01763 PCHAR
type =
CmpGetSectionLineIndex(InfHandle, Section, LineIndex, ValueIndex++);
01764
if (
type)
01765 {
01766
01767
01768
01769
01770 remainingBytes = *
BufferSize;
01771
01772
01773
01774
01775
01776
if (_stricmp(
type,
"B") == 0)
01777 {
01778
01779
01780
01781
01782
01783
for (result =
TRUE; result ==
TRUE && remainingBytes; remainingBytes--)
01784 {
01785
CHAR value;
01786
01787
01788
01789
01790
01791 data =
CmpGetSectionLineIndex(InfHandle, Section, LineIndex, ValueIndex++);
01792
if (data)
01793 {
01794
01795
01796
01797
01798 value = (
CHAR)strtoul(data,
NULL, 16);
01799
if (value == 0 && strcmp(data,
"00") && strcmp(data,
"0"))
01800 {
01801 result =
FALSE;
01802 }
01803
else
01804 {
01805 *
Buffer++ = value;
01806 }
01807 }
01808
else
01809 {
01810
break;
01811 }
01812 }
01813
01814
01815
01816
01817
01818 *
BufferSize -= remainingBytes;
01819 }
01820
01821
01822
01823
01824
01825
else if(_stricmp(
type,
"S") == 0)
01826 {
01827
01828
01829
01830
01831 data =
CmpGetSectionLineIndex(InfHandle, Section, LineIndex, ValueIndex);
01832
01833
01834
01835
01836
01837 cbData =
min(remainingBytes,
strlen(data));
01838 RtlCopyBytes(
Buffer, data, cbData);
01839
01840
01841
01842
01843
01844 *
BufferSize = cbData;
01845 result =
TRUE;
01846 }
01847 }
01848 }
01849
01850
return (result);
01851 }
01852
01853 PVOID
01854 CmpMapPhysicalAddress(
01855 IN OUT PVOID *BaseAddress,
01856 IN ULONG Address,
01857 IN ULONG Size
01858 )
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879 {
01880 UNICODE_STRING sectionName;
01881 OBJECT_ATTRIBUTES objectAttributes;
01882 HANDLE sectionHandle;
01883
NTSTATUS status;
01884 PVOID baseAddress;
01885 ULONG viewSize;
01886 LARGE_INTEGER viewBase;
01887 PVOID ptr =
NULL;
01888
01889 *BaseAddress =
NULL;
01890
01891
RtlInitUnicodeString(§ionName,
L"\\Device\\PhysicalMemory");
01892 InitializeObjectAttributes( &objectAttributes,
01893 §ionName,
01894 OBJ_CASE_INSENSITIVE,
01895 (HANDLE)
NULL,
01896 (PSECURITY_DESCRIPTOR)
NULL);
01897 status = ZwOpenSection( §ionHandle,
01898 SECTION_MAP_READ,
01899 &objectAttributes);
01900
if (
NT_SUCCESS(status))
01901 {
01902 baseAddress =
NULL;
01903 viewSize =
Size;
01904 viewBase.LowPart = Address & ~(0xFFF);
01905 viewBase.HighPart = 0;
01906 status = ZwMapViewOfSection( sectionHandle,
01907 NtCurrentProcess(),
01908 &baseAddress,
01909 0,
01910 viewSize,
01911 &viewBase,
01912 &viewSize,
01913 ViewUnmap,
01914 MEM_DOS_LIM,
01915 PAGE_READWRITE);
01916
if (
NT_SUCCESS(status))
01917 {
01918 ptr = (PVOID)((PCHAR)baseAddress + (Address & 0xFFF));
01919 *BaseAddress = baseAddress;
01920 }
01921 }
01922
01923
return (ptr);
01924 }
01925
01926 BOOLEAN
01927 CmpCheckOperator(
01928 IN PCHAR Operator,
01929 IN ULONG Lhs,
01930 IN ULONG Rhs
01931 )
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954 {
01955 BOOLEAN result =
FALSE;
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
if (strcmp(Operator,
"=") == 0 || strcmp(Operator,
"==") == 0)
01966 {
01967 result = (Lhs == Rhs);
01968 }
01969
01970
01971
01972
01973
01974
else if( strcmp(Operator,
"!=") == 0 ||
01975 strcmp(Operator,
"<>") == 0 ||
01976 strcmp(Operator,
"=!") == 0)
01977 {
01978 result = (Lhs != Rhs);
01979 }
01980
01981
01982
01983
01984
01985
else if(strcmp(Operator,
"<") == 0)
01986 {
01987 result = (Lhs < Rhs);
01988 }
01989
01990
01991
01992
01993
01994
else if(strcmp(Operator,
"<=") == 0 || strcmp(Operator,
"=<") == 0)
01995 {
01996 result = (Lhs <= Rhs);
01997 }
01998
01999
02000
02001
02002
02003
else if(strcmp(Operator,
">") == 0)
02004 {
02005 result = (Lhs > Rhs);
02006 }
02007
02008
02009
02010
02011
02012
else if(strcmp(Operator,
">=") == 0 || strcmp(Operator,
"=>") == 0)
02013 {
02014 result = (Lhs >= Rhs);
02015 }
02016
else
02017 {
02018
DbgPrint(
"Invalid operator %s used!\n", Operator);
02019 }
02020
02021
return (result);
02022 }
02023
02024 PVOID
02025 CmpFindPattern(
02026 IN PCHAR Buffer,
02027 IN ULONG BufSize,
02028 IN PCHAR Pattern,
02029 IN ULONG PatSize,
02030 IN BOOLEAN IgnoreCase,
02031 IN ULONG Step
02032 )
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058 {
02059 PCHAR bufEnd;
02060
02061
if (PatSize > BufSize)
02062 {
02063
return (
NULL);
02064 }
02065
02066
if (PatSize == 0)
02067 {
02068 PatSize =
strlen(
Pattern);
02069 }
02070
02071
if (Step == 0)
02072 {
02073 Step = 1;
02074 }
02075
02076
for ( bufEnd =
Buffer + BufSize;
02077
Buffer + PatSize < bufEnd;
02078
Buffer += Step)
02079 {
02080
if (IgnoreCase)
02081 {
02082
if (_strnicmp(
Buffer,
Pattern, PatSize) == 0)
02083 {
02084
return (
Buffer);
02085 }
02086 }
02087
else
02088 {
02089
if (strncmp(
Buffer,
Pattern, PatSize) == 0)
02090 {
02091
return (
Buffer);
02092 }
02093 }
02094 }
02095
02096
return (
NULL);
02097 }
02098
02099 ULONG
02100 CmpGetPnPBIOSTableAddress(
02101 VOID
02102 )
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122 {
02123
static ULONG tableAddress = (ULONG)-1;
02124 PVOID baseAddress;
02125
PPNP_BIOS_TABLE address;
02126
PPNP_BIOS_TABLE lastAddress;
02127 ULONG i;
02128 ULONG checksum;
02129
02130
if (tableAddress == (ULONG)-1)
02131 {
02132
02133
02134
02135
02136 address = (
PPNP_BIOS_TABLE)
CmpMapPhysicalAddress(&baseAddress, 0xF0000,
SYSTEM_BIOS_LENGTH);
02137
if (address)
02138 {
02139
for ( lastAddress = (
PPNP_BIOS_TABLE)((PCHAR)address +
SYSTEM_BIOS_LENGTH - 0x10);
02140 address < lastAddress;
02141 (PCHAR)address += 0x10)
02142 {
02143
if (address->Signature ==
PNPBIOS_SIGNATURE)
02144 {
02145
for ( i = 0, checksum = 0;
02146 i < address->Length;
02147 i++)
02148 {
02149 checksum += ((PUCHAR)address)[i];
02150 }
02151
02152
if ( (checksum & 0xFF) == 0 &&
02153 address->Length >= 0x21)
02154 {
02155 tableAddress = 0xF0000 + (
SYSTEM_BIOS_LENGTH - 10) - ((PCHAR)lastAddress - (PCHAR)address);
02156
break;
02157 }
02158 }
02159 }
02160
02161
02162
02163
02164
02165 ZwUnmapViewOfSection(NtCurrentProcess(), baseAddress);
02166 }
02167 }
02168
02169
return (tableAddress);
02170 }
02171
02172
PDESCRIPTION_HEADER
02173 CmpFindACPITable(
02174 IN ULONG Signature,
02175 IN OUT PULONG Length
02176 )
02177 {
02178
PDESCRIPTION_HEADER header =
NULL;
02179
PDESCRIPTION_HEADER tempHeader =
NULL;
02180
static PHYSICAL_ADDRESS rsdtAddress = { -1, -1 };
02181 ULONG length = 0;
02182
02183
02184
02185
02186
if (rsdtAddress.QuadPart == -1) {
02187
02188
NTSTATUS status;
02189
PACPI_BIOS_MULTI_NODE rsdpMulti;
02190
02191 rsdtAddress.QuadPart = 0;
02192
02193
02194
02195 status =
CmpFindRSDTTable( &rsdpMulti );
02196
if (!
NT_SUCCESS(status)) {
02197
02198
return NULL;
02199
02200 }
02201
02202
02203
02204
02205 rsdtAddress.LowPart = rsdpMulti->
RsdtAddress.LowPart;
02206 rsdtAddress.HighPart = rsdpMulti->
RsdtAddress.HighPart;
02207
02208
02209
02210
02211
ExFreePool( rsdpMulti );
02212
02213 }
02214
02215
02216
02217
02218
if (rsdtAddress.QuadPart) {
02219
02220
02221
02222
02223 tempHeader =
MmMapIoSpace(
02224 rsdtAddress,
02225
sizeof(
DESCRIPTION_HEADER),
02226
MmCached
02227 );
02228
if (tempHeader ==
NULL) {
02229
02230
DbgPrint(
"CmpFindACPITable: Cannot map RSDT at %I64x\n", rsdtAddress.QuadPart);
02231
return NULL;
02232
02233 }
02234
02235
02236
02237
02238
if (Signature ==
RSDT_SIGNATURE) {
02239
02240 header = tempHeader;
02241 length =
sizeof(
DESCRIPTION_HEADER);
02242
02243 }
else if (Signature ==
DSDT_SIGNATURE) {
02244
02245
PFADT fadt;
02246 PHYSICAL_ADDRESS dsdtAddress;
02247 ULONG tempLength;
02248
02249 fadt = (
PFADT)
CmpFindACPITable(
FADT_SIGNATURE, &length );
02250
if (fadt) {
02251
02252 dsdtAddress.HighPart = 0;
02253 dsdtAddress.LowPart = fadt->
dsdt;
02254
02255
02256
02257
02258
MmUnmapIoSpace( fadt, length );
02259
02260
02261
02262
02263 header =
MmMapIoSpace(
02264 dsdtAddress,
02265
sizeof(
DESCRIPTION_HEADER),
02266
MmCached
02267 );
02268
if (header ==
NULL) {
02269
02270
DbgPrint(
02271
"CmpFindACPITable: Cannot map DSDT at %I64x\n",
02272 dsdtAddress.QuadPart
02273 );
02274
MmUnmapIoSpace( tempHeader,
sizeof(
DESCRIPTION_HEADER) );
02275
return NULL;
02276
02277 }
02278 length =
sizeof(
DESCRIPTION_HEADER);
02279
02280 }
else {
02281
02282
DbgPrint(
"CmpFindACPITable: Cannot find FADT\n");
02283
MmUnmapIoSpace( tempHeader,
sizeof(
DESCRIPTION_HEADER) );
02284
return NULL;
02285
02286 }
02287
02288 }
else {
02289
02290 PHYSICAL_ADDRESS tableAddress;
02291
PRSDT rsdt;
02292 ULONG i;
02293 ULONG num;
02294 ULONG rsdtLength;
02295
02296
02297
02298
02299 rsdtLength = tempHeader->
Length;
02300 rsdt = (
PRSDT)
MmMapIoSpace( rsdtAddress, rsdtLength,
MmCached );
02301
if (rsdt ==
NULL) {
02302
02303
DbgPrint(
02304
"CmpFindACPITable: Cannot map RSDT at %I64x\n",
02305 rsdtAddress.QuadPart
02306 );
02307
MmUnmapIoSpace( tempHeader,
sizeof(
DESCRIPTION_HEADER) );
02308
return NULL;
02309
02310 }
02311
02312
02313
02314
02315
MmUnmapIoSpace( tempHeader,
sizeof(
DESCRIPTION_HEADER) );
02316
02317
02318
02319
02320 num =
TABLE_ENTRIES_FROM_RSDT_POINTER( rsdt );
02321
for (i = 0; i < num ; i ++) {
02322
02323
02324
02325
02326 tableAddress.HighPart = 0;
02327 tableAddress.LowPart = rsdt->
Tables[i];
02328
02329
02330
02331
02332 tempHeader =
MmMapIoSpace(
02333 tableAddress,
02334
sizeof(
DESCRIPTION_HEADER),
02335
MmCached
02336 );
02337
if (!tempHeader) {
02338
02339
DbgPrint(
02340
"CmpFindACPITable: Cannot map header at %I64x\n",
02341 tableAddress.QuadPart
02342 );
02343
MmUnmapIoSpace( rsdt, rsdtLength );
02344
return NULL;
02345
02346 }
02347
02348
02349
02350
02351
if (tempHeader->
Signature != Signature) {
02352
02353
MmUnmapIoSpace( tempHeader,
sizeof(
DESCRIPTION_HEADER) );
02354
continue;
02355
02356 }
02357
02358
02359
02360
02361
if (Signature ==
FADT_SIGNATURE) {
02362
02363
02364
02365
02366 length = tempHeader->
Length;
02367 header =
MmMapIoSpace( tableAddress, length,
MmCached );
02368
02369
02370
02371
02372
MmUnmapIoSpace( tempHeader,
sizeof(
DESCRIPTION_HEADER) );
02373
02374
02375
02376
02377
if (header ==
NULL ) {
02378
02379
DbgPrint(
02380
"CmpFindACPITable: Cannot map FADT at %I64x\n",
02381 tableAddress.QuadPart
02382 );
02383
MmUnmapIoSpace( rsdt, rsdtLength );
02384
return NULL;
02385
02386 }
02387
02388 }
else {
02389
02390
02391
02392
02393 length =
sizeof(
DESCRIPTION_HEADER);
02394 header = tempHeader;
02395
02396 }
02397
02398 }
02399
02400
02401
02402
02403
MmUnmapIoSpace( rsdt, rsdtLength );
02404
02405 }
02406
02407
02408
02409
02410
if (Length) {
02411
02412
if (header) {
02413
02414 *Length = length;
02415
02416 }
else {
02417
02418 *Length = 0;
02419
02420 }
02421
02422 }
02423
02424 }
02425
02426
return (header);
02427 }
02428
02429
NTSTATUS
02430 CmpFindRSDTTable(
02431 OUT
PACPI_BIOS_MULTI_NODE *Rsdt
02432 )
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453 {
02454 BOOLEAN same;
02455 HANDLE hMFunc;
02456 HANDLE hBus;
02457
NTSTATUS status;
02458 OBJECT_ATTRIBUTES objectAttributes;
02459
PACPI_BIOS_MULTI_NODE multiNode;
02460 PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
02461 PCM_PARTIAL_RESOURCE_LIST prl;
02462 PKEY_VALUE_PARTIAL_INFORMATION valueInfo;
02463 PWSTR p;
02464 ULONG i;
02465 ULONG length;
02466 ULONG multiNodeSize;
02467 UNICODE_STRING unicodeString;
02468 UNICODE_STRING unicodeValueName;
02469 UNICODE_STRING biosId;
02470 WCHAR wbuffer[10];
02471
02472
PAGED_CODE();
02473
02474
02475
02476
02477
RtlInitUnicodeString( &unicodeString,
rgzMultiFunctionAdapter );
02478 InitializeObjectAttributes(
02479 &objectAttributes,
02480 &unicodeString,
02481 OBJ_CASE_INSENSITIVE,
02482
NULL,
02483
NULL
02484 );
02485 status = ZwOpenKey( &hMFunc, KEY_READ, &objectAttributes );
02486
if (!
NT_SUCCESS(status)) {
02487
02488
DbgPrint(
"CmpFindRSDTTable: Cannot open MultifunctionAdapter registry key.\n");
02489
return status;
02490
02491 }
02492
02493
02494
02495
02496
02497 unicodeString.Buffer = wbuffer;
02498 unicodeString.MaximumLength =
sizeof(wbuffer);
02499
RtlInitUnicodeString( &biosId,
rgzBIOSIdentifier );
02500
02501
02502
02503
02504
for (i = 0;
TRUE; i++) {
02505
02506
02507
02508
02509
RtlIntegerToUnicodeString( i, 10, &unicodeString);
02510 InitializeObjectAttributes(
02511 &objectAttributes,
02512 &unicodeString,
02513 OBJ_CASE_INSENSITIVE,
02514 hMFunc,
02515
NULL
02516 );
02517
02518
02519
02520
02521 status = ZwOpenKey( &hBus, KEY_READ, &objectAttributes );
02522
if (!
NT_SUCCESS(status)) {
02523
02524
02525
02526
02527
DbgPrint(
"CmpFindRSDTTable: ACPI BIOS MultifunctionAdapter registry key not found.\n");
02528 ZwClose (hMFunc);
02529
return STATUS_UNSUCCESSFUL;
02530
02531 }
02532
02533
02534
02535
02536 status =
CmpGetRegistryValue( hBus,
rgzAcpiIdentifier, &valueInfo );
02537
if (!
NT_SUCCESS (status)) {
02538
02539 ZwClose( hBus );
02540
continue;
02541
02542 }
02543
02544 p = (PWSTR) ((PUCHAR) valueInfo->Data);
02545 unicodeValueName.Buffer = p;
02546 unicodeValueName.MaximumLength = (
USHORT)valueInfo->DataLength;
02547 length = valueInfo->DataLength;
02548
02549
02550
02551
02552
while (length) {
02553
02554
if (p[length /
sizeof(WCHAR) - 1] == UNICODE_NULL) {
02555
02556 length -= 2;
02557
02558 }
else {
02559
02560
break;
02561 }
02562
02563 }
02564
02565
02566
02567
02568 unicodeValueName.Length = (
USHORT)length;
02569 same =
RtlEqualUnicodeString( &biosId, &unicodeValueName,
TRUE );
02570
ExFreePool( valueInfo );
02571
if (!same) {
02572
02573 ZwClose( hBus );
02574
continue;
02575
02576 }
02577
02578
02579
02580
02581 status =
CmpGetRegistryValue(
02582 hBus,
02583
rgzAcpiConfigurationData,
02584 &valueInfo
02585 );
02586 ZwClose( hBus );
02587
if (!
NT_SUCCESS(status)) {
02588
02589
continue ;
02590
02591 }
02592
02593
02594
02595
02596
02597 prl = (PCM_PARTIAL_RESOURCE_LIST)(valueInfo->Data);
02598 prd = &prl->PartialDescriptors[0];
02599 multiNode = (
PACPI_BIOS_MULTI_NODE)
02600 ( (PCHAR) prd +
sizeof(CM_PARTIAL_RESOURCE_LIST) );
02601
break;
02602
02603 }
02604
02605
02606
02607
02608 multiNodeSize =
sizeof(
ACPI_BIOS_MULTI_NODE) +
02609 ( (ULONG)(multiNode->
Count - 1) *
sizeof(
ACPI_E820_ENTRY) );
02610 *Rsdt = (
PACPI_BIOS_MULTI_NODE)
ExAllocatePoolWithTag(
02611
NonPagedPool,
02612 multiNodeSize,
02613 'IPCA'
02614 );
02615
if (*Rsdt ==
NULL) {
02616
02617
ExFreePool( valueInfo );
02618
return STATUS_INSUFFICIENT_RESOURCES;
02619
02620 }
02621 RtlCopyMemory(*Rsdt, multiNode, multiNodeSize);
02622
02623
02624
02625
02626
ExFreePool(valueInfo);
02627
02628
02629
02630
02631
return STATUS_SUCCESS;
02632 }
02633
02634
NTSTATUS
02635 CmpGetRegistryValue(
02636 IN HANDLE KeyHandle,
02637 IN PWSTR ValueName,
02638 OUT PKEY_VALUE_PARTIAL_INFORMATION *Information
02639 )
02640
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665 {
02666
NTSTATUS status;
02667 PKEY_VALUE_PARTIAL_INFORMATION infoBuffer;
02668 ULONG keyValueLength;
02669 UNICODE_STRING unicodeString;
02670
02671
PAGED_CODE();
02672
02673
RtlInitUnicodeString( &unicodeString,
ValueName );
02674
02675
02676
02677
02678
02679 status = ZwQueryValueKey(
02680 KeyHandle,
02681 &unicodeString,
02682 KeyValuePartialInformation,
02683 (PVOID)
NULL,
02684 0,
02685 &keyValueLength
02686 );
02687
if (status != STATUS_BUFFER_OVERFLOW &&
02688 status != STATUS_BUFFER_TOO_SMALL) {
02689
02690
return status;
02691
02692 }
02693
02694
02695
02696
02697 infoBuffer =
ExAllocatePoolWithTag(
02698
NonPagedPool,
02699 keyValueLength,
02700 'IPCA'
02701 );
02702
if (!infoBuffer) {
02703
02704
return STATUS_INSUFFICIENT_RESOURCES;
02705
02706 }
02707
02708
02709
02710
02711 status = ZwQueryValueKey(
02712 KeyHandle,
02713 &unicodeString,
02714 KeyValuePartialInformation,
02715 infoBuffer,
02716 keyValueLength,
02717 &keyValueLength
02718 );
02719
if (!
NT_SUCCESS( status )) {
02720
02721
ExFreePool( infoBuffer );
02722
02723
return status;
02724
02725 }
02726
02727
02728
02729
02730
02731 *Information = infoBuffer;
02732
return STATUS_SUCCESS;
02733
02734 }
02735
02736