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 "iop.h"
00028
#pragma hdrstop
00029
#include "pnpcvrt.h"
00030
#include "pbios.h"
00031
00032
#if UMODETEST
00033
#undef IsNEC_98
00034
#define IsNEC_98 0
00035
#endif
00036
00037
#ifdef POOL_TAGGING
00038
#undef ExAllocatePool
00039
#define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,'PpaM')
00040
#endif
00041
00042
00043
00044
00045
00046
#if DBG
00047
00048
#define MAPPER_ERROR 0x00000001
00049
#define MAPPER_INFORMATION 0x00000002
00050
#define MAPPER_PNP_ID 0x00000004
00051
#define MAPPER_RESOURCES 0x00000008
00052
#define MAPPER_REGISTRY 0x00000010
00053
#define MAPPER_VERBOSE 0x00008000
00054
00055 ULONG PnPBiosMapperDebugMask = MAPPER_ERROR |
00056
00057
00058
00059
00060
00061 0;
00062
00063
#define DebugPrint(X) PnPBiosDebugPrint X
00064
00065
VOID
00066 PnPBiosDebugPrint(
00067 ULONG DebugMask,
00068 PCCHAR DebugMessage,
00069 ...
00070 );
00071
00072
#else
00073
00074 #define DebugPrint(X)
00075
00076
#endif // DBG
00077
00078
#if UMODETEST
00079
#define MULTIFUNCTION_KEY_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\TestSystem\\MultifunctionAdapter"
00080
#define ENUMROOT_KEY_NAME L"\\Registry\\Machine\\System\\TestControlSet\\Enum\\Root"
00081
#else
00082 #define MULTIFUNCTION_KEY_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"
00083 #define ENUMROOT_KEY_NAME L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\Root"
00084
#endif
00085
00086 #define BIOSINFO_KEY_NAME L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Biosinfo\\PNPBios"
00087 #define BIOSINFO_VALUE_NAME L"DisableNodes"
00088 #define DECODEINFO_VALUE_NAME L"FullDecodeChipsetOverride"
00089
00090 #define INSTANCE_ID_PREFIX L"PnPBIOS_"
00091
00092 #define DEFAULT_STRING_SIZE 80
00093 #define DEFAULT_VALUE_SIZE 80
00094
00095 #define DEFAULT_DEVICE_DESCRIPTION L"Unknown device class"
00096
00097
00098 #define EXCLUSION_ENTRY(a) { a, sizeof(a) - sizeof(UNICODE_NULL) }
00099
00100 typedef struct _EXCLUDED_PNPNODE {
00101 PWCHAR
Id;
00102 ULONG
IdLength;
00103 }
EXCLUDED_PNPNODE, *
PEXCLUDED_PNPNODE;
00104
00105 EXCLUDED_PNPNODE ExcludedDevices[] = {
00106
EXCLUSION_ENTRY(
L"*PNP03"),
00107
EXCLUSION_ENTRY(
L"*PNP0A"),
00108
EXCLUSION_ENTRY(
L"*PNP0E"),
00109
EXCLUSION_ENTRY(
L"*PNP0F"),
00110
EXCLUSION_ENTRY(
L"*nEC13"),
00111
EXCLUSION_ENTRY(
L"*nEC1E"),
00112
EXCLUSION_ENTRY(
L"*nEC1F"),
00113
EXCLUSION_ENTRY(
L"*IBM3780"),
00114
EXCLUSION_ENTRY(
L"*IBM3781")
00115 };
00116
00117 #define EXCLUDED_DEVICES_COUNT (sizeof(ExcludedDevices) / sizeof(ExcludedDevices[0]))
00118
00119 EXCLUDED_PNPNODE ExcludeIfDisabled[] = {
00120
EXCLUSION_ENTRY(
L"*PNP0C01"),
00121
EXCLUSION_ENTRY(
L"*PNP0C02")
00122 };
00123
00124 #define EXCLUDE_DISABLED_COUNT (sizeof(ExcludeIfDisabled) / sizeof(ExcludeIfDisabled[0]))
00125
00126 typedef struct _CLASSDATA {
00127 ULONG
Value;
00128 PWCHAR
Description;
00129 }
CLASSDATA;
00130
00131 CLASSDATA Class1Descriptions[] = {
00132 { 0x0000,
L"SCSI Controller" },
00133 { 0x0100,
L"IDE Controller" },
00134 { 0x0200,
L"Floppy Controller" },
00135 { 0x0300,
L"IPI Controller" },
00136 { 0x0400,
L"RAID Controller" },
00137 { 0x8000,
L"Other Mass Storage" }
00138 };
00139
00140 CLASSDATA Class2Descriptions[] = {
00141 { 0x0000,
L"Ethernet" },
00142 { 0x0100,
L"Token ring" },
00143 { 0x0200,
L"FDDI" },
00144 { 0x0300,
L"ATM" },
00145 { 0x8000,
L"Other network" }
00146 };
00147
00148 CLASSDATA Class3Descriptions[] = {
00149 { 0x0000,
L"VGA" },
00150 { 0x0001,
L"SVGA" },
00151 { 0x0100,
L"XGA" },
00152 { 0x8000,
L"Other display" }
00153 };
00154
00155 CLASSDATA Class4Descriptions[] = {
00156 { 0x0000,
L"Video device" },
00157 { 0x0100,
L"Audio device" },
00158 { 0x8000,
L"Other multimedia" }
00159 };
00160
00161 CLASSDATA Class5Descriptions[] = {
00162 { 0x0000,
L"RAM memory" },
00163 { 0x0100,
L"Flash memory" },
00164 { 0x8000,
L"Other memory" }
00165 };
00166
00167 CLASSDATA Class6Descriptions[] = {
00168 { 0x0000,
L"HOST / PCI" },
00169 { 0x0100,
L"PCI / ISA" },
00170 { 0x0200,
L"PCI / EISA" },
00171 { 0x0300,
L"PCI / MCA" },
00172 { 0x0400,
L"PCI / PCI" },
00173 { 0x0500,
L"PCI / PCMCIA" },
00174 { 0x0600,
L"NuBus" },
00175 { 0x0700,
L"Cardbus" },
00176 { 0x8000,
L"Other bridge" }
00177 };
00178
00179 CLASSDATA Class7Descriptions[] = {
00180 { 0x0000,
L"XT Serial" },
00181 { 0x0001,
L"16450" },
00182 { 0x0002,
L"16550" },
00183 { 0x0100,
L"Parallel output only" },
00184 { 0x0101,
L"BiDi Parallel" },
00185 { 0x0102,
L"ECP 1.x parallel" },
00186 { 0x8000,
L"Other comm" }
00187 };
00188
00189 CLASSDATA Class8Descriptions[] = {
00190 { 0x0000,
L"Generic 8259" },
00191 { 0x0001,
L"ISA PIC" },
00192 { 0x0002,
L"EISA PIC" },
00193 { 0x0100,
L"Generic 8237" },
00194 { 0x0101,
L"ISA DMA" },
00195 { 0x0102,
L"EISA DMA" },
00196 { 0x0200,
L"Generic 8254" },
00197 { 0x0201,
L"ISA timer" },
00198 { 0x0202,
L"EISA timer" },
00199 { 0x0300,
L"Generic RTC" },
00200 { 0x0301,
L"ISA RTC" },
00201 { 0x8000,
L"Other system device" }
00202 };
00203
00204 CLASSDATA Class9Descriptions[] = {
00205 { 0x0000,
L"Keyboard" },
00206 { 0x0100,
L"Digitizer" },
00207 { 0x0200,
L"Mouse" },
00208 { 0x8000,
L"Other input" }
00209 };
00210
00211 CLASSDATA Class10Descriptions[] = {
00212 { 0x0000,
L"Generic dock" },
00213 { 0x8000,
L"Other dock" },
00214 };
00215
00216 CLASSDATA Class11Descriptions[] = {
00217 { 0x0000,
L"386" },
00218 { 0x0100,
L"486" },
00219 { 0x0200,
L"Pentium" },
00220 { 0x1000,
L"Alpha" },
00221 { 0x4000,
L"Co-processor" }
00222 };
00223
00224 CLASSDATA Class12Descriptions[] = {
00225 { 0x0000,
L"Firewire" },
00226 { 0x0100,
L"Access bus" },
00227 { 0x0200,
L"SSA" },
00228 { 0x8000,
L"Other serial bus" }
00229 };
00230
00231 #define CLASSLIST_ENTRY(a) { a, sizeof(a) / sizeof(a[0]) }
00232
00233 struct _CLASS_DESCRIPTIONS_LIST {
00234
00235 CLASSDATA *
Descriptions;
00236 ULONG
Count;
00237
00238 }
ClassDescriptionsList[] = {
00239 {
NULL, 0 },
00240
CLASSLIST_ENTRY( Class1Descriptions ),
00241
CLASSLIST_ENTRY( Class2Descriptions ),
00242
CLASSLIST_ENTRY( Class3Descriptions ),
00243
CLASSLIST_ENTRY( Class4Descriptions ),
00244
CLASSLIST_ENTRY( Class5Descriptions ),
00245
CLASSLIST_ENTRY( Class6Descriptions ),
00246
CLASSLIST_ENTRY( Class7Descriptions ),
00247
CLASSLIST_ENTRY( Class8Descriptions ),
00248
CLASSLIST_ENTRY( Class9Descriptions ),
00249
CLASSLIST_ENTRY( Class10Descriptions ),
00250
CLASSLIST_ENTRY( Class11Descriptions ),
00251
CLASSLIST_ENTRY( Class12Descriptions )
00252
00253 };
00254
00255 #define CLASSLIST_COUNT ( sizeof(ClassDescriptionsList) / sizeof(ClassDescriptionsList[0]) )
00256
00257 typedef struct _BIOS_DEVNODE_INFO {
00258 WCHAR
ProductId[10];
00259 UCHAR
Handle;
00260 UCHAR
TypeCode[3];
00261 USHORT Attributes;
00262 PWSTR
Replaces;
00263
00264 PCM_RESOURCE_LIST
BootConfig;
00265 ULONG
BootConfigLength;
00266 PIO_RESOURCE_REQUIREMENTS_LIST
BasicConfig;
00267 ULONG
BasicConfigLength;
00268 PWSTR
CompatibleIDs;
00269 ULONG
CompatibleIDsLength;
00270 BOOLEAN
FirmwareDisabled;
00271
00272 }
BIOS_DEVNODE_INFO, *
PBIOS_DEVNODE_INFO;
00273
00274
NTSTATUS
00275
PbBiosResourcesToNtResources (
00276 IN ULONG BusNumber,
00277 IN ULONG SlotNumber,
00278 IN OUT PUCHAR *BiosData,
00279 OUT PIO_RESOURCE_REQUIREMENTS_LIST *ReturnedList,
00280 OUT PULONG ReturnedLength
00281 );
00282
00283
VOID
00284
PnPBiosExpandProductId(
00285 PUCHAR CompressedId,
00286 PWCHAR ProductIDStr
00287 );
00288
00289
NTSTATUS
00290
PnPBiosIoResourceListToCmResourceList(
00291 IN PIO_RESOURCE_REQUIREMENTS_LIST IoResourceList,
00292 OUT PCM_RESOURCE_LIST *CmResourceList,
00293 OUT ULONG *CmResourceListSize
00294 );
00295
00296
NTSTATUS
00297
PnPBiosExtractCompatibleIDs(
00298 IN PUCHAR *DevNodeData,
00299 IN ULONG DevNodeDataLength,
00300 OUT PWSTR *CompatibleIDs,
00301 OUT ULONG *CompatibleIDsLength
00302 );
00303
00304
NTSTATUS
00305
PnPBiosTranslateInfo(
00306 IN VOID *BiosInfo,
00307 IN ULONG BiosInfoLength,
00308 OUT PBIOS_DEVNODE_INFO *DevNodeInfoList,
00309 OUT ULONG *NumberNodes
00310 );
00311
00312 LONG
00313
PnPBiosFindMatchingDevNode(
00314 IN PWCHAR MapperName,
00315 IN PCM_RESOURCE_LIST ResourceList,
00316 IN PBIOS_DEVNODE_INFO DevNodeInfoList,
00317 IN ULONG NumberNodes
00318 );
00319
00320
NTSTATUS
00321
PnPBiosEliminateDupes(
00322 IN PBIOS_DEVNODE_INFO DevNodeInfoList,
00323 IN ULONG NumberNodes
00324 );
00325
00326 PWCHAR
00327
PnPBiosGetDescription(
00328 IN PBIOS_DEVNODE_INFO DevNodeInfoEntry
00329 );
00330
00331
NTSTATUS
00332
PnPBiosWriteInfo(
00333 IN PBIOS_DEVNODE_INFO DevNodeInfoList,
00334 IN ULONG NumberNodes
00335 );
00336
00337
VOID
00338
PnPBiosCopyIoDecode(
00339 IN HANDLE EnumRootKey,
00340 IN PBIOS_DEVNODE_INFO DevNodeInfo
00341 );
00342
00343
NTSTATUS
00344
PnPBiosFreeDevNodeInfo(
00345 IN PBIOS_DEVNODE_INFO DevNodeInfoList,
00346 IN ULONG NumberNodes
00347 );
00348
00349
NTSTATUS
00350
PnPBiosCheckForHardwareDisabled(
00351 IN PIO_RESOURCE_REQUIREMENTS_LIST IoResourceList,
00352 IN OUT PBOOLEAN Disabled
00353 );
00354
00355 BOOLEAN
00356
PnPBiosCheckForExclusion(
00357 IN PEXCLUDED_PNPNODE ExclusionArray,
00358 IN ULONG ExclusionCount,
00359 IN PWCHAR PnpDeviceName,
00360 IN PWCHAR PnpCompatIds
00361 );
00362
00363
NTSTATUS
00364
PnPBiosMapper(
00365 VOID
00366 );
00367
00368
VOID
00369
PpFilterNtResource (
00370 IN PWCHAR PnpDeviceName,
00371 PIO_RESOURCE_REQUIREMENTS_LIST ResReqList
00372 );
00373
00374
NTSTATUS
00375
ComPortDBAdd(
00376 IN HANDLE DeviceParamKey,
00377 IN PWSTR PortName
00378 );
00379
00380
#ifdef ALLOC_PRAGMA
00381
#pragma alloc_text(INIT, PnPBiosExpandProductId)
00382
#pragma alloc_text(INIT, PnPBiosIoResourceListToCmResourceList)
00383
#pragma alloc_text(INIT, PnPBiosExtractCompatibleIDs)
00384
#pragma alloc_text(INIT, PnPBiosTranslateInfo)
00385
#pragma alloc_text(INIT, PnPBiosFindMatchingDevNode)
00386
#pragma alloc_text(INIT, PnPBiosEliminateDupes)
00387
#pragma alloc_text(INIT, PnPBiosGetDescription)
00388
#pragma alloc_text(INIT, PnPBiosWriteInfo)
00389
#pragma alloc_text(INIT, PnPBiosCopyIoDecode)
00390
#pragma alloc_text(INIT, PnPBiosFreeDevNodeInfo)
00391
#pragma alloc_text(INIT, PnPBiosCheckForHardwareDisabled)
00392
#pragma alloc_text(INIT, PnPBiosCheckForExclusion)
00393
#pragma alloc_text(INIT, PnPBiosMapper)
00394
#pragma alloc_text(INIT, PpFilterNtResource)
00395
#pragma alloc_text(PAGE, PnPBiosGetBiosInfo)
00396
#endif
00397
00398
NTSTATUS
00399 PnPBiosGetBiosInfo(
00400 OUT PVOID *BiosInfo,
00401 OUT ULONG *BiosInfoLength
00402 )
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426 {
00427 UNICODE_STRING multifunctionKeyName, biosKeyName, valueName;
00428 HANDLE multifunctionKey =
NULL, biosKey =
NULL;
00429 PKEY_BASIC_INFORMATION keyBasicInfo =
NULL;
00430 ULONG keyBasicInfoLength;
00431 PKEY_VALUE_PARTIAL_INFORMATION valueInfo =
NULL;
00432 ULONG valueInfoLength;
00433 ULONG returnedLength;
00434
00435 PCM_FULL_RESOURCE_DESCRIPTOR biosValue;
00436
00437 ULONG index;
00438
NTSTATUS status = STATUS_UNSUCCESSFUL;
00439
00440
00441
00442
00443
00444
00445
00446
00447
RtlInitUnicodeString(&multifunctionKeyName,
MULTIFUNCTION_KEY_NAME);
00448
00449 status =
IopOpenRegistryKeyEx( &multifunctionKey,
00450
NULL,
00451 &multifunctionKeyName,
00452 KEY_READ
00453 );
00454
00455
if (!
NT_SUCCESS(status)) {
00456
00457
DebugPrint( (MAPPER_ERROR,
00458
"Could not open %S, status = %8.8X\n",
00459
MULTIFUNCTION_KEY_NAME,
00460 status) );
00461
00462
return STATUS_UNSUCCESSFUL;
00463 }
00464
00465
00466
00467
00468
00469 keyBasicInfoLength =
sizeof(KEY_BASIC_INFORMATION) +
DEFAULT_STRING_SIZE;
00470 keyBasicInfo =
ExAllocatePool(
PagedPool, keyBasicInfoLength +
sizeof(UNICODE_NULL));
00471
00472
if (keyBasicInfo ==
NULL) {
00473
00474 ZwClose( multifunctionKey );
00475
00476
return STATUS_NO_MEMORY;
00477 }
00478
00479 valueInfoLength =
sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
DEFAULT_STRING_SIZE;
00480 valueInfo =
ExAllocatePool(
PagedPool, valueInfoLength);
00481
00482
if (valueInfo ==
NULL) {
00483
00484
ExFreePool( keyBasicInfo );
00485
00486 ZwClose( multifunctionKey );
00487
00488
return STATUS_NO_MEMORY;
00489 }
00490
00491
00492
00493
00494
00495
for (index = 0; ; index++) {
00496
00497 status = ZwEnumerateKey( multifunctionKey,
00498 index,
00499 KeyBasicInformation,
00500 keyBasicInfo,
00501 keyBasicInfoLength,
00502 &returnedLength);
00503
00504
if (!
NT_SUCCESS(status)) {
00505
00506
if (status != STATUS_NO_MORE_ENTRIES) {
00507
00508
DebugPrint( (MAPPER_ERROR,
00509
"Could not enumerate under key %S, status = %8.8X\n",
00510
MULTIFUNCTION_KEY_NAME,
00511 status) );
00512 }
00513
00514
break;
00515 }
00516
00517
00518
00519
00520 keyBasicInfo->Name[ keyBasicInfo->NameLength / 2 ] =
L'\0';
00521
00522
RtlInitUnicodeString(&biosKeyName, keyBasicInfo->Name);
00523
00524 status =
IopOpenRegistryKeyEx( &biosKey,
00525 multifunctionKey,
00526 &biosKeyName,
00527 KEY_READ
00528 );
00529
00530
if (!
NT_SUCCESS(status)) {
00531
00532
DebugPrint( (MAPPER_ERROR,
00533
"Could not open registry key %S\\%S, status = %8.8X\n",
00534
MULTIFUNCTION_KEY_NAME,
00535 keyBasicInfo->Name,
00536 status) );
00537
break;
00538 }
00539
00540
00541
00542
00543
00544
RtlInitUnicodeString(&valueName,
L"Identifier");
00545
00546 status = ZwQueryValueKey( biosKey,
00547 &valueName,
00548 KeyValuePartialInformation,
00549 valueInfo,
00550 valueInfoLength,
00551 &returnedLength);
00552
00553
00554
00555
if (
NT_SUCCESS(status)) {
00556
00557
if (wcscmp((PWSTR)valueInfo->Data,
L"PNP BIOS") == 0) {
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
RtlInitUnicodeString(&valueName,
L"Configuration Data");
00568
00569 status = ZwQueryValueKey( biosKey,
00570 &valueName,
00571 KeyValuePartialInformation,
00572 valueInfo,
00573 valueInfoLength,
00574 &returnedLength);
00575
00576
if (!
NT_SUCCESS(status)) {
00577
00578
if (status == STATUS_BUFFER_TOO_SMALL || status == STATUS_BUFFER_OVERFLOW) {
00579
00580
00581
00582
00583
00584
ExFreePool( valueInfo );
00585
00586 valueInfoLength = returnedLength;
00587 valueInfo =
ExAllocatePool(
PagedPool, valueInfoLength );
00588
00589
if (valueInfo !=
NULL) {
00590
00591 status = ZwQueryValueKey( biosKey,
00592 &valueName,
00593 KeyValuePartialInformation,
00594 valueInfo,
00595 valueInfoLength,
00596 &returnedLength );
00597 }
else {
00598
00599 status = STATUS_NO_MEMORY;
00600 }
00601 }
00602 }
00603
00604
if (
NT_SUCCESS(status)) {
00605
00606
00607
00608
00609
00610
00611
00612
ASSERT(valueInfo->Type == REG_FULL_RESOURCE_DESCRIPTOR);
00613
00614 biosValue = (PCM_FULL_RESOURCE_DESCRIPTOR)valueInfo->Data;
00615
00616
00617
00618
00619
00620
00621
00622
00623 *BiosInfoLength = biosValue->PartialResourceList.PartialDescriptors[0].u.DeviceSpecificData.DataSize;
00624 *BiosInfo =
ExAllocatePool(
PagedPool, *BiosInfoLength);
00625
00626
if (*BiosInfo !=
NULL) {
00627
00628 RtlCopyMemory( *BiosInfo,
00629 &biosValue->PartialResourceList.PartialDescriptors[1],
00630 *BiosInfoLength );
00631
00632 status = STATUS_SUCCESS;
00633
00634 }
else {
00635
00636 *BiosInfoLength = 0;
00637
00638 status = STATUS_NO_MEMORY;
00639 }
00640
00641 }
else {
00642
00643
DebugPrint( (MAPPER_ERROR,
00644
"Error retrieving %S\\%S\\Configuration Data, status = %8.8X\n",
00645
MULTIFUNCTION_KEY_NAME,
00646 keyBasicInfo->Name,
00647 status) );
00648 }
00649
00650
00651
00652
00653
00654
00655 ZwClose(biosKey);
00656
00657
break;
00658 }
00659 }
00660
00661
00662
00663
00664 ZwClose(biosKey);
00665 }
00666
00667
00668
00669
00670
00671
if (valueInfo !=
NULL) {
00672
00673
ExFreePool(valueInfo);
00674 }
00675
00676
if (keyBasicInfo !=
NULL) {
00677
00678
ExFreePool(keyBasicInfo);
00679 }
00680
00681 ZwClose(multifunctionKey);
00682
00683
return status;
00684 }
00685
00686
VOID
00687 PnPBiosExpandProductId(
00688 PUCHAR CompressedId,
00689 PWCHAR ProductIDStr
00690 )
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712 {
00713
static CHAR HexDigits[16] =
"0123456789ABCDEF";
00714
00715 ProductIDStr[0] = (CompressedId[0] >> 2) + 0x40;
00716 ProductIDStr[1] = (((CompressedId[0] & 0x03) << 3) | (CompressedId[1] >> 5)) + 0x40;
00717 ProductIDStr[2] = (CompressedId[1] & 0x1f) + 0x40;
00718 ProductIDStr[3] = HexDigits[CompressedId[2] >> 4];
00719 ProductIDStr[4] = HexDigits[CompressedId[2] & 0x0F];
00720 ProductIDStr[5] = HexDigits[CompressedId[3] >> 4];
00721 ProductIDStr[6] = HexDigits[CompressedId[3] & 0x0F];
00722 ProductIDStr[7] = 0x00;
00723 }
00724
00725 BOOLEAN
00726 PnPBiosIgnoreNode (
00727 PWCHAR PnpID,
00728 PWCHAR excludeNodes
00729 )
00730 {
00731 BOOLEAN bRet=
FALSE;
00732 ULONG keyLen;
00733 PWCHAR pTmp;
00734
00735
ASSERT (excludeNodes);
00736
00737
00738
00739
00740 pTmp=excludeNodes;
00741
00742
while (*pTmp !=
'\0') {
00743
00744 keyLen = wcslen (pTmp);
00745
00746
if (RtlCompareMemory (PnpID,pTmp,keyLen*
sizeof (WCHAR)) == keyLen*
sizeof (WCHAR)) {
00747 bRet=
TRUE;
00748
break;
00749 }
00750 pTmp=pTmp+keyLen+1;
00751
00752 }
00753
00754
00755
return bRet;
00756 }
00757
00758
VOID
00759 PnPGetDevnodeExcludeList (
00760 OUT PKEY_VALUE_FULL_INFORMATION *ExcludeList
00761 )
00762 {
00763 UNICODE_STRING biosKeyName;
00764 HANDLE biosKey;
00765
NTSTATUS status;
00766
00767
RtlInitUnicodeString(&biosKeyName,
BIOSINFO_KEY_NAME);
00768 status =
IopOpenRegistryKeyEx( &biosKey,
00769
NULL,
00770 &biosKeyName,
00771 KEY_READ
00772 );
00773
00774
if (!
NT_SUCCESS(status)) {
00775
00776
00777
00778
00779
return;
00780 }
00781
00782 (
VOID)
IopGetRegistryValue (biosKey,
BIOSINFO_VALUE_NAME,ExcludeList);
00783
00784 ZwClose (biosKey);
00785 }
00786
00787 BOOLEAN
00788 PnPCheckFixedIoOverrideDecodes(
00789 VOID
00790 )
00791 {
00792 PKEY_VALUE_FULL_INFORMATION decodeFlagInfo=
NULL;
00793 UNICODE_STRING biosKeyName;
00794 HANDLE biosKey;
00795
NTSTATUS status;
00796 BOOLEAN overrideDecodes =
FALSE;
00797
00798
RtlInitUnicodeString(&biosKeyName,
BIOSINFO_KEY_NAME);
00799 status =
IopOpenRegistryKeyEx( &biosKey,
00800
NULL,
00801 &biosKeyName,
00802 KEY_READ
00803 );
00804
00805
if (!
NT_SUCCESS(status)) {
00806
00807
00808
00809
00810
return FALSE;
00811 }
00812
00813 status =
IopGetRegistryValue(biosKey,
DECODEINFO_VALUE_NAME, &decodeFlagInfo);
00814
00815
if (
NT_SUCCESS(status)) {
00816
00817
ASSERT(decodeFlagInfo->Type == REG_DWORD);
00818
if (decodeFlagInfo->DataLength ==
sizeof(ULONG)) {
00819
00820 overrideDecodes = (BOOLEAN) *((PULONG) decodeFlagInfo->Name);
00821 }
00822 }
00823
00824
if (decodeFlagInfo) {
00825
00826
ExFreePool(decodeFlagInfo);
00827 }
00828
00829 ZwClose (biosKey);
00830
00831
return overrideDecodes;
00832 }
00833
00834 BOOLEAN
00835 PnPBiosCheckForExclusion(
00836 IN
EXCLUDED_PNPNODE *Exclusions,
00837 IN ULONG ExclusionCount,
00838 IN PWCHAR PnpDeviceName,
00839 IN PWCHAR PnpCompatIds
00840 )
00841 {
00842 PWCHAR idPtr;
00843 ULONG exclusionIndex;
00844
00845
for (exclusionIndex = 0; exclusionIndex < ExclusionCount; exclusionIndex++) {
00846
00847 idPtr = PnpDeviceName;
00848
00849
if (RtlCompareMemory( idPtr,
00850 Exclusions[ exclusionIndex ].Id,
00851 Exclusions[ exclusionIndex ].IdLength) != Exclusions[ exclusionIndex ].IdLength ) {
00852
00853 idPtr = PnpCompatIds;
00854
00855
if (idPtr !=
NULL) {
00856
00857
while (*idPtr !=
'\0') {
00858
00859
if (RtlCompareMemory( idPtr,
00860 Exclusions[ exclusionIndex ].Id,
00861 Exclusions[ exclusionIndex ].IdLength) == Exclusions[ exclusionIndex ].IdLength ) {
00862
00863
break;
00864 }
00865
00866 idPtr += 9;
00867 }
00868
00869
if (*idPtr ==
'\0') {
00870
00871 idPtr =
NULL;
00872 }
00873 }
00874 }
00875
00876
if (idPtr !=
NULL) {
00877
00878
break;
00879 }
00880 }
00881
00882
if (exclusionIndex < ExclusionCount) {
00883
return TRUE;
00884 }
00885
00886
return FALSE;
00887 }
00888
00889
NTSTATUS
00890 PnPBiosIoResourceListToCmResourceList(
00891 IN PIO_RESOURCE_REQUIREMENTS_LIST IoResourceList,
00892 OUT PCM_RESOURCE_LIST *CmResourceList,
00893 OUT ULONG *CmResourceListSize
00894 )
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918 {
00919 PCM_PARTIAL_RESOURCE_LIST partialList;
00920 PCM_PARTIAL_RESOURCE_DESCRIPTOR partialDescriptor;
00921 PIO_RESOURCE_DESCRIPTOR ioDescriptor;
00922 ULONG descIndex;
00923
00924
00925
00926
00927
00928
00929
00930
ASSERT(IoResourceList->AlternativeLists == 1);
00931
00932
00933
00934
00935 *CmResourceListSize =
sizeof(CM_RESOURCE_LIST) +
00936 (IoResourceList->AlternativeLists - 1) *
sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
00937 (IoResourceList->List[0].Count - 1) *
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
00938
00939 *CmResourceList =
ExAllocatePool(
PagedPool, *CmResourceListSize );
00940
00941
if (*CmResourceList ==
NULL) {
00942
00943 *CmResourceListSize = 0;
00944
00945
return STATUS_NO_MEMORY;
00946 }
00947
00948
00949
00950
00951 (*CmResourceList)->Count = 1;
00952
00953 (*CmResourceList)->List[ 0 ].InterfaceType = IoResourceList->InterfaceType;
00954 (*CmResourceList)->List[ 0 ].BusNumber = IoResourceList->BusNumber;
00955
00956 partialList = &(*CmResourceList)->List[ 0 ].PartialResourceList;
00957
00958 partialList->Version = IoResourceList->List[ 0 ].Version;
00959 partialList->Revision = IoResourceList->List[ 0 ].Revision;
00960 partialList->Count = 0;
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970 partialDescriptor = &partialList->PartialDescriptors[ 0 ];
00971
for (descIndex = 0; descIndex < IoResourceList->List[ 0 ].Count; descIndex++) {
00972
00973 ioDescriptor = &IoResourceList->List[ 0 ].Descriptors[ descIndex ];
00974
00975
switch (ioDescriptor->Type) {
00976
00977
case CmResourceTypePort:
00978 partialDescriptor->u.Port.Start = ioDescriptor->u.Port.MinimumAddress;
00979 partialDescriptor->u.Port.Length = ioDescriptor->u.Port.Length;
00980
break;
00981
00982
case CmResourceTypeInterrupt:
00983
if (ioDescriptor->u.Interrupt.MinimumVector == (ULONG)(IsNEC_98 ? 7 : 2) ) {
00984 *CmResourceListSize -=
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
00985
continue;
00986 }
00987 partialDescriptor->u.Interrupt.Level = ioDescriptor->u.Interrupt.MinimumVector;
00988 partialDescriptor->u.Interrupt.Vector = ioDescriptor->u.Interrupt.MinimumVector;
00989 partialDescriptor->u.Interrupt.Affinity = ~0;
00990
break;
00991
00992
case CmResourceTypeMemory:
00993 partialDescriptor->u.Memory.Start = ioDescriptor->u.Memory.MinimumAddress;
00994 partialDescriptor->u.Memory.Length = ioDescriptor->u.Memory.Length;
00995
break;
00996
00997
case CmResourceTypeDma:
00998 partialDescriptor->u.Dma.Channel = ioDescriptor->u.Dma.MinimumChannel;
00999 partialDescriptor->u.Dma.Port = 0;
01000 partialDescriptor->u.Dma.Reserved1 = 0;
01001
break;
01002
01003
default:
01004
DebugPrint( (MAPPER_ERROR,
01005
"Unexpected ResourceType (%d) in I/O Descriptor\n",
01006 ioDescriptor->Type) );
01007
01008
#if DBG
01009
01010
#endif
01011
break;
01012 }
01013
01014 partialDescriptor->Type = ioDescriptor->Type;
01015 partialDescriptor->ShareDisposition = ioDescriptor->ShareDisposition;
01016 partialDescriptor->Flags = ioDescriptor->Flags;
01017 partialDescriptor++;
01018
01019 partialList->Count++;
01020 }
01021
01022
return STATUS_SUCCESS;
01023 }
01024
01025
NTSTATUS
01026 PnPBiosExtractCompatibleIDs(
01027 IN PUCHAR *DevNodeData,
01028 IN ULONG DevNodeDataLength,
01029 OUT PWSTR *CompatibleIDs,
01030 OUT ULONG *CompatibleIDsLength
01031 )
01032 {
01033 PWCHAR idPtr;
01034 PUCHAR currentPtr, endPtr;
01035 UCHAR tagName;
01036 ULONG increment;
01037 ULONG compatibleCount;
01038
01039 endPtr = &(*DevNodeData)[DevNodeDataLength];
01040
01041 compatibleCount = 0;
01042
01043
for (currentPtr = *DevNodeData; currentPtr < endPtr; currentPtr += increment) {
01044
01045 tagName = *currentPtr;
01046
01047
if (tagName ==
TAG_COMPLETE_END) {
01048
01049
break;
01050 }
01051
01052
01053
01054
01055
01056
if (!(tagName &
LARGE_RESOURCE_TAG)) {
01057 increment = (
USHORT)(tagName &
SMALL_TAG_SIZE_MASK);
01058 increment++;
01059 tagName &=
SMALL_TAG_MASK;
01060 }
else {
01061 increment = *(
USHORT UNALIGNED *)(¤tPtr[1]);
01062 increment += 3;
01063 }
01064
01065
if (tagName ==
TAG_COMPATIBLE_ID) {
01066
01067 compatibleCount++;
01068 }
01069 }
01070
01071
if (compatibleCount == 0) {
01072 *CompatibleIDs =
NULL;
01073 *CompatibleIDsLength = 0;
01074
01075
return STATUS_SUCCESS;
01076 }
01077
01078 *CompatibleIDsLength = (compatibleCount * 9 + 1) *
sizeof(WCHAR);
01079 *CompatibleIDs =
ExAllocatePool(
PagedPool, *CompatibleIDsLength);
01080
01081
if (*CompatibleIDs ==
NULL) {
01082
01083 *CompatibleIDsLength = 0;
01084
return STATUS_NO_MEMORY;
01085 }
01086
01087 idPtr = *CompatibleIDs;
01088
01089
for (currentPtr = *DevNodeData; currentPtr < endPtr; currentPtr += increment) {
01090
01091 tagName = *currentPtr;
01092
01093
if (tagName ==
TAG_COMPLETE_END) {
01094
01095
break;
01096 }
01097
01098
01099
01100
01101
01102
if (!(tagName &
LARGE_RESOURCE_TAG)) {
01103 increment = (
USHORT)(tagName &
SMALL_TAG_SIZE_MASK);
01104 increment++;
01105 tagName &=
SMALL_TAG_MASK;
01106 }
else {
01107 increment = *(
USHORT UNALIGNED *)(¤tPtr[1]);
01108 increment += 3;
01109 }
01110
01111
if (tagName ==
TAG_COMPATIBLE_ID) {
01112
01113 *idPtr =
'*';
01114
PnPBiosExpandProductId(¤tPtr[1], &idPtr[1]);
01115 idPtr += 9;
01116 }
01117 }
01118
01119 *idPtr++ =
'\0';
01120 *CompatibleIDsLength = (ULONG)(idPtr - *CompatibleIDs) *
sizeof(WCHAR);
01121
01122
return STATUS_SUCCESS;
01123 }
01124
01125
NTSTATUS
01126 PnPBiosTranslateInfo(
01127 IN VOID *BiosInfo,
01128 IN ULONG BiosInfoLength,
01129 OUT PBIOS_DEVNODE_INFO *DevNodeInfoList,
01130 OUT ULONG *NumberNodes
01131 )
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163 {
01164 PCM_PNP_BIOS_INSTALLATION_CHECK biosInstallCheck;
01165 PCM_PNP_BIOS_DEVICE_NODE devNodeHeader;
01166
PBIOS_DEVNODE_INFO devNodeInfo;
01167 PKEY_VALUE_FULL_INFORMATION excludeList=
NULL;
01168
01169 PIO_RESOURCE_REQUIREMENTS_LIST tempResReqList;
01170
01171 PUCHAR currentPtr;
01172 LONG lengthRemaining;
01173
01174 LONG remainingNodeLength;
01175
01176 ULONG numNodes;
01177 ULONG nodeIndex;
01178 PUCHAR configPtr;
01179 ULONG configListLength;
01180
NTSTATUS status;
01181 ULONG convertFlags = 0;
01182
01183
01184
01185
01186
01187
if (BiosInfoLength <
sizeof(CM_PNP_BIOS_INSTALLATION_CHECK)) {
01188
01189
DebugPrint( (MAPPER_ERROR,
01190
"BiosInfoLength (%d) is smaller than sizeof(PNPBIOS_INSTALLATION_CHECK) (%d)\n",
01191 BiosInfoLength,
01192
sizeof(CM_PNP_BIOS_INSTALLATION_CHECK)) );
01193
01194
return STATUS_UNSUCCESSFUL;
01195 }
01196
01197 biosInstallCheck = (PCM_PNP_BIOS_INSTALLATION_CHECK)BiosInfo;
01198
01199
if (biosInstallCheck->Signature[0] !=
'$' ||
01200 biosInstallCheck->Signature[1] !=
'P' ||
01201 biosInstallCheck->Signature[2] !=
'n' ||
01202 biosInstallCheck->Signature[3] !=
'P') {
01203
01204
return STATUS_UNSUCCESSFUL;
01205 }
01206
01207
01208
01209
01210
01211 currentPtr = (PUCHAR)BiosInfo + biosInstallCheck->Length;
01212 lengthRemaining = BiosInfoLength - biosInstallCheck->Length;
01213
01214
for (numNodes = 0; lengthRemaining >
sizeof(CM_PNP_BIOS_DEVICE_NODE); numNodes++) {
01215
01216 devNodeHeader = (PCM_PNP_BIOS_DEVICE_NODE)currentPtr;
01217
01218
if (devNodeHeader->Size > lengthRemaining) {
01219
01220
DebugPrint( (MAPPER_ERROR,
01221
"Node # %d, invalid size (%d), length remaining (%d)\n",
01222 devNodeHeader->Node,
01223 devNodeHeader->Size,
01224 lengthRemaining) );
01225
01226
return STATUS_UNSUCCESSFUL;
01227 }
01228
01229 currentPtr += devNodeHeader->Size;
01230 lengthRemaining -= devNodeHeader->Size;
01231 }
01232
01233
01234
01235
01236 devNodeInfo =
ExAllocatePool(
PagedPool, numNodes *
sizeof(
BIOS_DEVNODE_INFO) );
01237
01238
if (devNodeInfo ==
NULL) {
01239
01240
return STATUS_NO_MEMORY;
01241 }
01242
01243
01244
01245
01246
if (
PnPCheckFixedIoOverrideDecodes()) {
01247
01248 convertFlags |=
PPCONVERTFLAG_FORCE_FIXED_IO_16BIT_DECODE;
01249 }
01250
01251
01252
01253
01254
01255
01256 currentPtr = (PUCHAR)BiosInfo + biosInstallCheck->Length;
01257 lengthRemaining = BiosInfoLength - biosInstallCheck->Length;
01258
01259
for (nodeIndex = 0; nodeIndex < numNodes; nodeIndex++) {
01260
01261 devNodeHeader = (PCM_PNP_BIOS_DEVICE_NODE)currentPtr;
01262
01263
if (devNodeHeader->Size > lengthRemaining) {
01264
01265
DebugPrint( (MAPPER_ERROR,
01266
"Node # %d, invalid size (%d), length remaining (%d)\n",
01267 devNodeHeader->Node,
01268 devNodeHeader->Size,
01269 lengthRemaining) );
01270
01271
break;
01272 }
01273
01274
01275
01276
01277
01278 devNodeInfo[nodeIndex].
ProductId[0] =
'*';
01279
01280
PnPBiosExpandProductId((PUCHAR)&devNodeHeader->ProductId, &devNodeInfo[nodeIndex].
ProductId[1]);
01281
01282 devNodeInfo[nodeIndex].
ProductId[9] =
'\0';
01283
01284
01285
01286 devNodeInfo[nodeIndex].
Handle = devNodeHeader->Node;
01287
01288
01289
01290
01291
01292 RtlCopyMemory( &devNodeInfo[nodeIndex].TypeCode,
01293 devNodeHeader->DeviceType,
01294
sizeof(devNodeInfo[nodeIndex].
TypeCode) );
01295
01296 devNodeInfo[nodeIndex].
Attributes = devNodeHeader->DeviceAttributes;
01297
01298
01299
01300
01301
01302 devNodeInfo[nodeIndex].
Replaces =
NULL;
01303
01304
01305
01306
01307 devNodeInfo[nodeIndex].
CompatibleIDs =
NULL;
01308
01309
01310
01311
01312
01313 configPtr = currentPtr +
sizeof(*devNodeHeader);
01314 remainingNodeLength = devNodeHeader->Size -
sizeof(*devNodeHeader);
01315
01316 devNodeInfo[nodeIndex].
BootConfig =
NULL;
01317 devNodeInfo[nodeIndex].
FirmwareDisabled =
FALSE;
01318
01319 status =
PpBiosResourcesToNtResources( 0,
01320 0,
01321 &configPtr,
01322 convertFlags,
01323 &tempResReqList,
01324 &configListLength);
01325
01326 remainingNodeLength = devNodeHeader->Size - (LONG)(configPtr - (PUCHAR)devNodeHeader);
01327
01328
if (
NT_SUCCESS( status )) {
01329
01330
if (tempResReqList !=
NULL) {
01331
01332
PpFilterNtResource (
01333 devNodeInfo[nodeIndex].ProductId,
01334 tempResReqList
01335 );
01336
01337
01338
01339
01340
01341 status =
PnPBiosIoResourceListToCmResourceList( tempResReqList,
01342 &devNodeInfo[nodeIndex].BootConfig,
01343 &devNodeInfo[nodeIndex].BootConfigLength );
01344
01345 status =
PnPBiosCheckForHardwareDisabled(tempResReqList,&devNodeInfo[nodeIndex].FirmwareDisabled);
01346
01347
ExFreePool( tempResReqList );
01348
01349 }
01350
01351 }
else {
01352
01353
DebugPrint( (MAPPER_ERROR,
01354
"Error converting allocated resources for devnode # %d, status = %8.8X\n",
01355 devNodeInfo[nodeIndex].
Handle,
01356 status) );
01357 }
01358
01359
01360
01361
01362
01363 status =
PpBiosResourcesToNtResources( 0,
01364 0,
01365 &configPtr,
01366 convertFlags |
PPCONVERTFLAG_SET_RESTART_LCPRI,
01367 &devNodeInfo[nodeIndex].BasicConfig,
01368 &devNodeInfo[nodeIndex].BasicConfigLength );
01369
01370 remainingNodeLength = devNodeHeader->Size - (LONG)(configPtr - (PUCHAR)devNodeHeader);
01371
01372
if (!
NT_SUCCESS( status )) {
01373
01374 devNodeInfo[nodeIndex].
BasicConfig =
NULL;
01375
01376
DebugPrint( (MAPPER_ERROR,
01377
"Error converting allowed resources for devnode # %d, status = %8.8X\n",
01378 devNodeInfo[nodeIndex].
Handle,
01379 status) );
01380 }
else {
01381
01382
PpFilterNtResource (
01383 devNodeInfo[nodeIndex].ProductId,
01384 devNodeInfo[nodeIndex].BasicConfig
01385 );
01386 }
01387
01388
01389
01390
01391
01392
ASSERT(remainingNodeLength >= 0);
01393
01394 status =
PnPBiosExtractCompatibleIDs( &configPtr,
01395 (ULONG)remainingNodeLength,
01396 &devNodeInfo[nodeIndex].CompatibleIDs,
01397 &devNodeInfo[nodeIndex].CompatibleIDsLength );
01398
01399 currentPtr += devNodeHeader->Size;
01400 lengthRemaining -= devNodeHeader->Size;
01401
01402 }
01403
01404 *DevNodeInfoList = devNodeInfo;
01405 *NumberNodes = numNodes;
01406
return STATUS_SUCCESS;
01407 }
01408
01409 LONG
01410 PnPBiosFindMatchingDevNode(
01411 IN PWCHAR MapperName,
01412 IN PCM_RESOURCE_LIST ResourceList,
01413 IN PBIOS_DEVNODE_INFO DevNodeInfoList,
01414 IN ULONG NumberNodes
01415 )
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447 {
01448 PCM_PARTIAL_RESOURCE_LIST sourceList;
01449 PCM_PARTIAL_RESOURCE_LIST targetList;
01450 PCM_PARTIAL_RESOURCE_DESCRIPTOR sourceDescriptor;
01451 PCM_PARTIAL_RESOURCE_DESCRIPTOR targetDescriptor;
01452 ULONG nodeIndex, sourceIndex, targetIndex;
01453 LONG firstMatch = -1;
01454 LONG bestMatch = -1;
01455 ULONG numResourcesMatch;
01456 ULONG score, possibleScore, bestScore = 0;
01457 PWCHAR idPtr;
01458 BOOLEAN idsMatch;
01459 BOOLEAN bestIdsMatch =
FALSE;
01460
01461
#if DEBUG_DUP_MATCH
01462
CHAR sourceMapping[256];
01463
CHAR targetMapping[256];
01464
#endif
01465
01466
01467
01468
01469
01470
01471
ASSERT( ResourceList->Count == 1 );
01472
01473 sourceList = &ResourceList->List[0].PartialResourceList;
01474
01475
#if DEBUG_DUP_MATCH
01476
01477
01478
01479
01480
01481
ASSERT( sourceList->Count < 255 );
01482
#endif
01483
01484
01485
01486
01487
01488
for (nodeIndex = 0; nodeIndex < NumberNodes; nodeIndex++) {
01489
01490
if (DevNodeInfoList[ nodeIndex ].BootConfig ==
NULL) {
01491
01492
continue;
01493 }
01494
01495
01496
01497
01498
01499
01500
01501 idPtr = DevNodeInfoList[ nodeIndex ].ProductId;
01502
01503
if (RtlCompareMemory( idPtr, MapperName, 12 ) != 12) {
01504
01505 idPtr = DevNodeInfoList[ nodeIndex ].CompatibleIDs;
01506
01507
if (idPtr !=
NULL) {
01508
01509
while (*idPtr !=
'\0') {
01510
01511
if (RtlCompareMemory( idPtr, MapperName, 12 ) == 12) {
01512
01513
break;
01514 }
01515
01516 idPtr += 9;
01517 }
01518
01519
if (*idPtr ==
'\0') {
01520
01521 idPtr =
NULL;
01522 }
01523 }
01524 }
01525
01526 idsMatch = idPtr !=
NULL;
01527
01528
ASSERT( DevNodeInfoList[ nodeIndex ].BootConfig->Count == 1 );
01529
01530 targetList = &DevNodeInfoList[ nodeIndex ].BootConfig->List[0].PartialResourceList;
01531
01532
#if DEBUG_DUP_MATCH
01533
RtlFillMemory( sourceMapping,
sizeof(sourceMapping), -1 );
01534 RtlFillMemory( targetMapping,
sizeof(targetMapping), -1 );
01535
#endif
01536
01537 numResourcesMatch = 0;
01538 possibleScore = 0;
01539 score = 0;
01540
01541
01542
01543
01544
01545
01546
for (sourceIndex = 0; sourceIndex < sourceList->Count; sourceIndex++) {
01547
01548 sourceDescriptor = &sourceList->PartialDescriptors[sourceIndex];
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
switch (sourceDescriptor->Type) {
01559
01560
case CmResourceTypePort:
01561 possibleScore += 0x1100;
01562
break;
01563
01564
case CmResourceTypeInterrupt:
01565 possibleScore += 0x0001;
01566
break;
01567
01568
case CmResourceTypeMemory:
01569 possibleScore += 0x1100;
01570
break;
01571
01572
case CmResourceTypeDma:
01573 possibleScore += 0x0010;
01574
break;
01575
01576
default:
01577
continue;
01578 }
01579
01580
01581
01582
01583
01584
for (targetIndex = 0; targetIndex < targetList->Count; targetIndex++) {
01585
01586 targetDescriptor = &targetList->PartialDescriptors[targetIndex];
01587
01588
if (sourceDescriptor->Type == targetDescriptor->Type) {
01589
switch (sourceDescriptor->Type) {
01590
case CmResourceTypePort:
01591
if ((sourceDescriptor->u.Port.Start.LowPart + sourceDescriptor->u.Port.Length) <=
01592 targetDescriptor->u.Port.Start.LowPart ||
01593 (targetDescriptor->u.Port.Start.LowPart + targetDescriptor->u.Port.Length) <=
01594 sourceDescriptor->u.Port.Start.LowPart) {
01595
continue;
01596 }
01597
if (sourceDescriptor->u.Port.Start.LowPart ==
01598 targetDescriptor->u.Port.Start.LowPart &&
01599 sourceDescriptor->u.Port.Length ==
01600 targetDescriptor->u.Port.Length) {
01601
01602 score += 0x1100;
01603
01604 }
else {
01605
01606
DebugPrint( (MAPPER_INFORMATION,
01607
"Overlapping port resources, source = %4.4X-%4.4X, target = %4.4X-%4.4X\n",
01608 sourceDescriptor->u.Port.Start.LowPart,
01609 sourceDescriptor->u.Port.Start.LowPart + sourceDescriptor->u.Port.Length - 1,
01610 targetDescriptor->u.Port.Start.LowPart,
01611 targetDescriptor->u.Port.Start.LowPart + targetDescriptor->u.Port.Length - 1) );
01612
01613 score += 0x1000;
01614
01615 }
01616
break;
01617
01618
case CmResourceTypeInterrupt:
01619
if (sourceDescriptor->u.Interrupt.Level !=
01620 targetDescriptor->u.Interrupt.Level) {
01621
continue;
01622 }
01623 score += 0x0001;
01624
break;
01625
01626
case CmResourceTypeMemory:
01627
if ((sourceDescriptor->u.Memory.Start.LowPart + sourceDescriptor->u.Memory.Length) <=
01628 targetDescriptor->u.Memory.Start.LowPart ||
01629 (targetDescriptor->u.Memory.Start.LowPart + targetDescriptor->u.Memory.Length) <=
01630 sourceDescriptor->u.Memory.Start.LowPart) {
01631
01632
continue;
01633 }
01634
if (sourceDescriptor->u.Memory.Start.LowPart ==
01635 targetDescriptor->u.Memory.Start.LowPart &&
01636 sourceDescriptor->u.Memory.Length ==
01637 targetDescriptor->u.Memory.Length) {
01638
01639 score += 0x1100;
01640
01641 }
else {
01642
01643 score += 0x1000;
01644
01645 }
01646
break;
01647
01648
case CmResourceTypeDma:
01649
if (sourceDescriptor->u.Dma.Channel !=
01650 targetDescriptor->u.Dma.Channel) {
01651
01652
continue;
01653 }
01654 score += 0x0010;
01655
break;
01656
01657 }
01658
break;
01659 }
01660 }
01661
01662
if (targetIndex < targetList->Count) {
01663
#if DEBUG_DUP_MATCH
01664
sourceMapping[sourceIndex] = (
CHAR)targetIndex;
01665 targetMapping[targetIndex] = (
CHAR)sourceIndex;
01666
#endif
01667
numResourcesMatch++;
01668 }
01669 }
01670
01671
if (numResourcesMatch != 0) {
01672
if (firstMatch == -1) {
01673 firstMatch = nodeIndex;
01674 }
01675
01676
if ((score > bestScore) || (score == bestScore && !bestIdsMatch && idsMatch)) {
01677 bestScore = score;
01678 bestMatch = nodeIndex;
01679 bestIdsMatch = idsMatch;
01680 }
01681 }
01682 }
01683
01684
if (bestMatch != -1) {
01685
01686
if (bestScore == possibleScore) {
01687
01688
DebugPrint( (MAPPER_INFORMATION,
01689
"Perfect match, score = %4.4X, possible = %4.4X, index = %d\n",
01690 bestScore,
01691 possibleScore,
01692 bestMatch) );
01693
01694
if (possibleScore < 0x1000 && !bestIdsMatch) {
01695
01696 bestMatch = -1;
01697
01698 }
01699
01700 }
else if (possibleScore > 0x1000 && bestScore >= 0x1000) {
01701
01702
DebugPrint( (MAPPER_INFORMATION,
01703
"Best match is close enough, score = %4.4X, possible = %4.4X, index = %d\n",
01704 bestScore,
01705 possibleScore,
01706 bestMatch) );
01707
01708 }
else {
01709
01710
DebugPrint( (MAPPER_INFORMATION,
01711
"Best match is less than threshold, score = %4.4X, possible = %4.4X, index = %d\n",
01712 bestScore,
01713 possibleScore,
01714 bestMatch) );
01715
01716 bestMatch = -1;
01717
01718 }
01719 }
01720
01721
return bestMatch;
01722 }
01723
01724
NTSTATUS
01725 PnPBiosEliminateDupes(
01726 IN PBIOS_DEVNODE_INFO DevNodeInfoList,
01727 IN ULONG NumberNodes
01728 )
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751 {
01752 UNICODE_STRING enumRootKeyName, valueName;
01753 HANDLE enumRootKey;
01754 PKEY_BASIC_INFORMATION deviceBasicInfo =
NULL;
01755 ULONG deviceBasicInfoLength;
01756 UNICODE_STRING deviceKeyName;
01757 HANDLE deviceKey =
NULL;
01758 PKEY_BASIC_INFORMATION instanceBasicInfo =
NULL;
01759 ULONG instanceBasicInfoLength;
01760 WCHAR logConfStr[
DEFAULT_STRING_SIZE];
01761 UNICODE_STRING logConfKeyName;
01762 HANDLE logConfKey =
NULL;
01763
01764 PKEY_VALUE_PARTIAL_INFORMATION valueInfo =
NULL;
01765 ULONG valueInfoLength;
01766 ULONG returnedLength;
01767
01768 ULONG deviceIndex, instanceIndex;
01769
NTSTATUS status = STATUS_UNSUCCESSFUL;
01770
01771
RtlInitUnicodeString(&enumRootKeyName,
ENUMROOT_KEY_NAME);
01772
01773 status =
IopOpenRegistryKeyEx( &enumRootKey,
01774
NULL,
01775 &enumRootKeyName,
01776 KEY_READ
01777 );
01778
01779
if (!
NT_SUCCESS(status)) {
01780
01781
DebugPrint( (MAPPER_ERROR,
01782
"Could not open registry key %S, status = %8.8X\n",
01783
ENUMROOT_KEY_NAME,
01784 status) );
01785
01786
return STATUS_UNSUCCESSFUL;
01787 }
01788
01789 deviceBasicInfoLength =
sizeof(KEY_BASIC_INFORMATION) +
DEFAULT_STRING_SIZE;
01790 deviceBasicInfo =
ExAllocatePool(
PagedPool, deviceBasicInfoLength);
01791
01792 instanceBasicInfoLength =
sizeof(KEY_BASIC_INFORMATION) +
DEFAULT_STRING_SIZE;
01793 instanceBasicInfo =
ExAllocatePool(
PagedPool, instanceBasicInfoLength);
01794
01795 valueInfoLength =
sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
DEFAULT_STRING_SIZE;
01796 valueInfo =
ExAllocatePool(
PagedPool, valueInfoLength);
01797
01798
if (deviceBasicInfo !=
NULL && instanceBasicInfo !=
NULL && valueInfo !=
NULL) {
01799
01800
for (deviceIndex = 0; ; deviceIndex++) {
01801
01802 status = ZwEnumerateKey( enumRootKey,
01803 deviceIndex,
01804 KeyBasicInformation,
01805 deviceBasicInfo,
01806 deviceBasicInfoLength,
01807 &returnedLength);
01808
01809
if (!
NT_SUCCESS(status)) {
01810
01811
if (status != STATUS_NO_MORE_ENTRIES) {
01812
01813
DebugPrint( (MAPPER_ERROR,
01814
"Could not enumerate under key %S, status = %8.8X\n",
01815
ENUMROOT_KEY_NAME,
01816 status) );
01817 }
else {
01818 status = STATUS_SUCCESS;
01819 }
01820
break;
01821 }
01822
01823
if (deviceBasicInfo->Name[0] !=
'*') {
01824
continue;
01825 }
01826
01827 deviceBasicInfo->Name[ deviceBasicInfo->NameLength / 2 ] =
L'\0';
01828
RtlInitUnicodeString(&deviceKeyName, deviceBasicInfo->Name);
01829
01830 status =
IopOpenRegistryKeyEx( &deviceKey,
01831 enumRootKey,
01832 &deviceKeyName,
01833 KEY_READ
01834 );
01835
01836
if (!
NT_SUCCESS(status)) {
01837
01838
DebugPrint( (MAPPER_ERROR,
01839
"Could not open registry key %S\\%S, status = %8.8X\n",
01840
ENUMROOT_KEY_NAME,
01841 deviceBasicInfo->Name,
01842 status) );
01843
break;
01844 }
01845
01846
for (instanceIndex = 0; ; instanceIndex++) {
01847
01848 status = ZwEnumerateKey( deviceKey,
01849 instanceIndex,
01850 KeyBasicInformation,
01851 instanceBasicInfo,
01852 instanceBasicInfoLength,
01853 &returnedLength);
01854
01855
if (!
NT_SUCCESS(status)) {
01856
01857
if (status != STATUS_NO_MORE_ENTRIES) {
01858
DebugPrint( (MAPPER_ERROR,
01859
"Could not enumerate under key %S\\%S, status = %8.8X\n",
01860
ENUMROOT_KEY_NAME,
01861 deviceBasicInfo->Name,
01862 status) );
01863 }
else {
01864 status = STATUS_SUCCESS;
01865 }
01866
break;
01867 }
01868
01869
if (RtlCompareMemory( instanceBasicInfo->Name,
01870
INSTANCE_ID_PREFIX,
01871
sizeof(
INSTANCE_ID_PREFIX) -
sizeof(UNICODE_NULL)
01872 ) == (
sizeof(
INSTANCE_ID_PREFIX) -
sizeof(UNICODE_NULL))) {
01873
01874
continue;
01875 }
01876
01877 instanceBasicInfo->Name[ instanceBasicInfo->NameLength / 2 ] =
L'\0';
01878
01879 RtlCopyMemory( logConfStr,
01880 instanceBasicInfo->Name,
01881 instanceBasicInfo->NameLength );
01882
01883 logConfStr[ instanceBasicInfo->NameLength / 2 ] =
L'\\';
01884
01885 RtlCopyMemory( &logConfStr[ instanceBasicInfo->NameLength / 2 + 1 ],
01886 REGSTR_KEY_LOGCONF,
01887
sizeof(REGSTR_KEY_LOGCONF) );
01888
01889
RtlInitUnicodeString( &logConfKeyName, logConfStr );
01890
01891 status =
IopOpenRegistryKeyEx( &logConfKey,
01892 deviceKey,
01893 &logConfKeyName,
01894 KEY_READ
01895 );
01896
01897
if (!
NT_SUCCESS(status)) {
01898
01899
DebugPrint( (MAPPER_ERROR,
01900
"Could not open registry key %S\\%S\\%S, status = %8.8X\n",
01901
ENUMROOT_KEY_NAME,
01902 deviceBasicInfo->Name,
01903 logConfStr,
01904 status) );
01905
continue;
01906 }
01907
01908
RtlInitUnicodeString( &valueName, REGSTR_VAL_BOOTCONFIG );
01909
01910 status = ZwQueryValueKey( logConfKey,
01911 &valueName,
01912 KeyValuePartialInformation,
01913 valueInfo,
01914 valueInfoLength,
01915 &returnedLength );
01916
01917
if (!
NT_SUCCESS(status)) {
01918
01919
if (status == STATUS_BUFFER_TOO_SMALL || status == STATUS_BUFFER_OVERFLOW) {
01920
01921
ExFreePool( valueInfo );
01922
01923 valueInfoLength = returnedLength;
01924 valueInfo =
ExAllocatePool(
PagedPool, valueInfoLength );
01925
01926
if (valueInfo !=
NULL) {
01927
01928 status = ZwQueryValueKey( logConfKey,
01929 &valueName,
01930 KeyValuePartialInformation,
01931 valueInfo,
01932 valueInfoLength,
01933 &returnedLength );
01934 }
else {
01935
DebugPrint( (MAPPER_ERROR,
01936
"Error allocating memory for %S\\%S\\LogConf\\BootConfig value\n",
01937
ENUMROOT_KEY_NAME,
01938 deviceBasicInfo->Name) );
01939 valueInfoLength = 0;
01940 status = STATUS_NO_MEMORY;
01941
01942
break;
01943 }
01944
01945 }
else {
01946
DebugPrint( (MAPPER_ERROR,
01947
"Error retrieving %S\\%S\\LogConf\\BootConfig size, status = %8.8X\n",
01948
ENUMROOT_KEY_NAME,
01949 deviceBasicInfo->Name,
01950 status) );
01951
01952 status = STATUS_UNSUCCESSFUL;
01953 }
01954 }
01955
01956
if (
NT_SUCCESS( status )) {
01957 PCM_RESOURCE_LIST resourceList;
01958 LONG matchingIndex;
01959
01960 resourceList = (PCM_RESOURCE_LIST)valueInfo->Data;
01961
01962 matchingIndex =
PnPBiosFindMatchingDevNode( deviceBasicInfo->Name,
01963 resourceList,
01964 DevNodeInfoList,
01965 NumberNodes );
01966
01967
if (matchingIndex != -1) {
01968
01969 DevNodeInfoList[ matchingIndex ].Replaces =
ExAllocatePool(
PagedPool,
01970 deviceBasicInfo->NameLength + instanceBasicInfo->NameLength + 2 *
sizeof(UNICODE_NULL));
01971
01972
if (DevNodeInfoList[ matchingIndex ].Replaces !=
NULL) {
01973
01974 RtlCopyMemory( DevNodeInfoList[ matchingIndex ].Replaces,
01975 deviceBasicInfo->Name,
01976 deviceBasicInfo->NameLength );
01977
01978 DevNodeInfoList[ matchingIndex ].Replaces[ deviceBasicInfo->NameLength / 2 ] =
'\\';
01979
01980 RtlCopyMemory( &DevNodeInfoList[ matchingIndex ].Replaces[ deviceBasicInfo->NameLength / 2 + 1 ],
01981 instanceBasicInfo->Name,
01982 instanceBasicInfo->NameLength );
01983
01984 DevNodeInfoList[ matchingIndex ].Replaces[ (deviceBasicInfo->NameLength + instanceBasicInfo->NameLength) / 2 + 1 ] =
'\0';
01985
01986
DebugPrint( (MAPPER_INFORMATION,
01987
"Match found: %S\\%S%d replaces %S\n",
01988 DevNodeInfoList[ matchingIndex ].ProductId,
01989
INSTANCE_ID_PREFIX,
01990 DevNodeInfoList[ matchingIndex ].
Handle,
01991 DevNodeInfoList[ matchingIndex ].Replaces) );
01992 }
else {
01993
DebugPrint( (MAPPER_ERROR,
01994
"Error allocating memory for %S\\%S%d\\Replaces\n",
01995 DevNodeInfoList[ matchingIndex ].ProductId,
01996
INSTANCE_ID_PREFIX,
01997 DevNodeInfoList[ matchingIndex ].
Handle) );
01998 }
01999 }
else {
02000
DebugPrint( (MAPPER_INFORMATION,
02001
"No matching PnP Bios DevNode found for FW Enumerated device %S\\%S\n",
02002 deviceBasicInfo->Name,
02003 instanceBasicInfo->Name) );
02004 }
02005 }
else {
02006
DebugPrint( (MAPPER_ERROR,
02007
"Error retrieving %S\\%S\\%S\\BootConfig, status = %8.8X\n",
02008
ENUMROOT_KEY_NAME,
02009 deviceBasicInfo->Name,
02010 logConfStr,
02011 status) );
02012 }
02013
02014 ZwClose(logConfKey);
02015
02016 logConfKey =
NULL;
02017 }
02018
02019 ZwClose(deviceKey);
02020
02021 deviceKey =
NULL;
02022 }
02023 }
else {
02024 status = STATUS_NO_MEMORY;
02025 }
02026
02027
if (valueInfo !=
NULL) {
02028
ExFreePool(valueInfo);
02029 }
02030
02031
if (instanceBasicInfo !=
NULL) {
02032
ExFreePool(instanceBasicInfo);
02033 }
02034
02035
if (deviceBasicInfo !=
NULL) {
02036
ExFreePool(deviceBasicInfo);
02037 }
02038
02039
if (logConfKey !=
NULL) {
02040 ZwClose(logConfKey);
02041 }
02042
02043
if (deviceKey !=
NULL) {
02044 ZwClose(deviceKey);
02045 }
02046
02047 ZwClose(enumRootKey);
02048
02049
return status;
02050 }
02051
02052 PWCHAR
02053 PnPBiosGetDescription(
02054 IN PBIOS_DEVNODE_INFO DevNodeInfoEntry
02055 )
02056 {
02057 ULONG
class, subClass;
02058 LONG index;
02059
CLASSDATA *classDescriptions;
02060 LONG descriptionCount;
02061
02062
class = DevNodeInfoEntry->TypeCode[0];
02063 subClass = (DevNodeInfoEntry->TypeCode[1] << 8) | DevNodeInfoEntry->TypeCode[2];
02064
02065
if (
class > 0 &&
class <
CLASSLIST_COUNT) {
02066
02067 classDescriptions =
ClassDescriptionsList[
class ].Descriptions;
02068 descriptionCount =
ClassDescriptionsList[
class ].
Count;
02069
02070
02071
02072
02073
02074
for (index = 0; index < (descriptionCount - 1); index++) {
02075
02076
if (subClass == classDescriptions[ index ].
Value) {
02077
02078
break;
02079 }
02080 }
02081
02082
return classDescriptions[ index ].
Description;
02083 }
02084
02085
return DEFAULT_DEVICE_DESCRIPTION;
02086 }
02087
02088
NTSTATUS
02089 PnPBiosCopyDeviceParamKey(
02090 IN HANDLE EnumRootKey,
02091 IN PWCHAR SourcePath,
02092 IN PWCHAR DestinationPath
02093 )
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114 {
02115
NTSTATUS status;
02116 UNICODE_STRING sourceInstanceKeyName;
02117 HANDLE sourceInstanceKey =
NULL;
02118
02119 UNICODE_STRING deviceParamKeyName;
02120 HANDLE sourceDeviceParamKey =
NULL;
02121 HANDLE destinationDeviceParamKey =
NULL;
02122 UNICODE_STRING destinationInstanceKeyName;
02123
02124 PKEY_VALUE_FULL_INFORMATION valueFullInfo =
NULL;
02125 ULONG valueFullInfoLength;
02126 ULONG resultLength;
02127
02128 UNICODE_STRING valueName;
02129
02130 ULONG index;
02131
02132
RtlInitUnicodeString( &sourceInstanceKeyName, SourcePath );
02133
02134 status =
IopOpenRegistryKeyEx( &sourceInstanceKey,
02135 EnumRootKey,
02136 &sourceInstanceKeyName,
02137 KEY_ALL_ACCESS
02138 );
02139
02140
if (!
NT_SUCCESS(status)) {
02141
02142
DebugPrint( (MAPPER_ERROR,
02143
"PnPBiosCopyDeviceParamKey() - Could not open source instance key %S, status = %8.8X\n",
02144 SourcePath,
02145 status) );
02146
02147
return status;
02148 }
02149
02150
RtlInitUnicodeString(&deviceParamKeyName, REGSTR_KEY_DEVICEPARAMETERS);
02151
02152 status =
IopOpenRegistryKeyEx( &sourceDeviceParamKey,
02153 sourceInstanceKey,
02154 &deviceParamKeyName,
02155 KEY_ALL_ACCESS
02156 );
02157
02158
if (!
NT_SUCCESS(status)) {
02159
02160
if (status != STATUS_OBJECT_NAME_NOT_FOUND) {
02161
02162
DebugPrint( (MAPPER_ERROR,
02163
"PnPBiosCopyDeviceParamKey() - Could not open source device parameter key %S\\%S, status = %8.8X\n",
02164 SourcePath,
02165 deviceParamKeyName.Buffer,
02166 status) );
02167 }
02168
02169
goto Cleanup;
02170 }
02171
02172
RtlInitUnicodeString(&destinationInstanceKeyName, DestinationPath);
02173
02174 status =
IopOpenDeviceParametersSubkey( &destinationDeviceParamKey,
02175 EnumRootKey,
02176 &destinationInstanceKeyName,
02177 KEY_ALL_ACCESS );
02178
02179
if (!
NT_SUCCESS(status)) {
02180
02181
DebugPrint( (MAPPER_ERROR,
02182
"PnPBiosCopyDeviceParamKey() - Could not open destination device parameter key %S\\%S, status = %8.8X\n",
02183 DestinationPath,
02184 REGSTR_KEY_DEVICEPARAMETERS,
02185 status) );
02186
02187
goto Cleanup;
02188 }
02189
02190 valueFullInfoLength =
sizeof(KEY_VALUE_FULL_INFORMATION) +
DEFAULT_STRING_SIZE +
DEFAULT_VALUE_SIZE;
02191 valueFullInfo =
ExAllocatePool(
PagedPool, valueFullInfoLength);
02192
02193
if (valueFullInfo ==
NULL) {
02194
02195
goto Cleanup;
02196 }
02197
02198
for (index = 0; ; index++) {
02199 status = ZwEnumerateValueKey( sourceDeviceParamKey,
02200 index,
02201 KeyValueFullInformation,
02202 valueFullInfo,
02203 valueFullInfoLength,
02204 &resultLength );
02205
02206
if (
NT_SUCCESS(status)) {
02207 UNICODE_STRING sourcePathString;
02208 UNICODE_STRING serialPrefixString;
02209 UNICODE_STRING portNameString;
02210
02211 valueName.Length = (
USHORT)valueFullInfo->NameLength;
02212 valueName.MaximumLength = valueName.Length;
02213 valueName.Buffer = valueFullInfo->Name;
02214
02215
RtlInitUnicodeString(&sourcePathString, SourcePath);
02216
RtlInitUnicodeString(&serialPrefixString,
L"*PNP0501");
02217
02218
if (sourcePathString.Length > serialPrefixString.Length) {
02219 sourcePathString.Length = serialPrefixString.Length;
02220 }
02221
02222
if (
RtlCompareUnicodeString(&sourcePathString, &serialPrefixString,
TRUE) == 0) {
02223
02224
RtlInitUnicodeString(&portNameString,
L"PortName");
02225
02226
if (valueName.Length == 16 &&
02227
RtlCompareUnicodeString(&valueName, &portNameString,
TRUE) == 0) {
02228
02229
02230
ComPortDBAdd(destinationDeviceParamKey, (PWSTR)((PUCHAR)valueFullInfo + valueFullInfo->DataOffset));
02231
continue;
02232 }
02233 }
02234
02235 status = ZwSetValueKey( destinationDeviceParamKey,
02236 &valueName,
02237 valueFullInfo->TitleIndex,
02238 valueFullInfo->Type,
02239 (PUCHAR)valueFullInfo + valueFullInfo->DataOffset,
02240 valueFullInfo->DataLength );
02241 }
else {
02242
if (status == STATUS_BUFFER_OVERFLOW) {
02243
ExFreePool( valueFullInfo );
02244
02245 valueFullInfoLength = resultLength;
02246 valueFullInfo =
ExAllocatePool(
PagedPool, valueFullInfoLength);
02247
02248
if (valueFullInfo ==
NULL) {
02249 status = STATUS_NO_MEMORY;
02250 }
else {
02251 index--;
02252
continue;
02253 }
02254 }
else if (status != STATUS_NO_MORE_ENTRIES) {
02255
DebugPrint( (MAPPER_ERROR,
02256
"Could not enumerate under key %S\\%S, status = %8.8X\n",
02257 SourcePath,
02258 deviceParamKeyName.Buffer,
02259 status) );
02260 }
else {
02261 status = STATUS_SUCCESS;
02262 }
02263
02264
break;
02265 }
02266 }
02267
02268 Cleanup:
02269
if (sourceInstanceKey !=
NULL) {
02270 ZwClose( sourceInstanceKey );
02271 }
02272
02273
if (sourceDeviceParamKey !=
NULL) {
02274 ZwClose( sourceDeviceParamKey );
02275 }
02276
02277
if (destinationDeviceParamKey !=
NULL) {
02278 ZwClose( destinationDeviceParamKey );
02279 }
02280
02281
if (valueFullInfo !=
NULL) {
02282
ExFreePool( valueFullInfo );
02283 }
02284
02285
return status;
02286 }
02287
02288
NTSTATUS
02289 PnPBiosWriteInfo(
02290 IN PBIOS_DEVNODE_INFO DevNodeInfoList,
02291 IN ULONG NumberNodes
02292 )
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315 {
02316 PKEY_VALUE_FULL_INFORMATION excludeList=
NULL;
02317
02318 UNICODE_STRING enumRootKeyName;
02319 HANDLE enumRootKey;
02320 WCHAR instanceNameStr[
DEFAULT_STRING_SIZE];
02321 UNICODE_STRING instanceKeyName;
02322 HANDLE instanceKey;
02323 UNICODE_STRING controlKeyName;
02324 HANDLE controlKey;
02325 UNICODE_STRING logConfKeyName;
02326 HANDLE logConfKey;
02327
02328 UNICODE_STRING valueName;
02329 ULONG dwordValue;
02330 ULONG disposition;
02331
02332 PWCHAR descriptionStr;
02333 ULONG descriptionStrLength;
02334
02335 ULONG nodeIndex;
02336
NTSTATUS status;
02337
02338 BOOLEAN isNewDevice;
02339
02340
RtlInitUnicodeString(&enumRootKeyName,
ENUMROOT_KEY_NAME);
02341
02342 status =
IopOpenRegistryKeyEx( &enumRootKey,
02343
NULL,
02344 &enumRootKeyName,
02345 KEY_ALL_ACCESS
02346 );
02347
02348
if (!
NT_SUCCESS(status)) {
02349
02350
DebugPrint( (MAPPER_ERROR,
02351
"Could not open registry key %S, status = %8.8X\n",
02352
ENUMROOT_KEY_NAME,
02353 status) );
02354
02355
return STATUS_UNSUCCESSFUL;
02356
02357 }
02358
02359
02360
02361
02362
02363
02364
02365
02366
PnPGetDevnodeExcludeList (&excludeList);
02367
02368
for (nodeIndex = 0; nodeIndex < NumberNodes; nodeIndex++) {
02369
02370
02371
02372
02373
02374
if ( excludeList &&
02375
PnPBiosIgnoreNode( &DevNodeInfoList[ nodeIndex ].ProductId[1],
02376 (PWCHAR)((PUCHAR)excludeList+excludeList->DataOffset))) {
02377
continue;
02378 }
02379
02380
02381
if (
PnPBiosCheckForExclusion(
ExcludedDevices,
02382
EXCLUDED_DEVICES_COUNT,
02383 DevNodeInfoList[ nodeIndex ].ProductId,
02384 DevNodeInfoList[ nodeIndex ].CompatibleIDs)) {
02385
02386
02387
02388
02389
02390
PnPBiosCopyIoDecode( enumRootKey, &DevNodeInfoList[ nodeIndex ] );
02391
02392
02393
02394
02395
02396
continue;
02397 }
02398
02399
02400
if ( DevNodeInfoList[ nodeIndex ].FirmwareDisabled &&
02401
PnPBiosCheckForExclusion(
ExcludeIfDisabled,
02402
EXCLUDE_DISABLED_COUNT,
02403 DevNodeInfoList[ nodeIndex ].ProductId,
02404
NULL)) {
02405
continue;
02406 }
02407
02408 swprintf( instanceNameStr,
02409
L"%s\\%s%d",
02410 DevNodeInfoList[ nodeIndex ].ProductId,
02411
INSTANCE_ID_PREFIX,
02412 DevNodeInfoList[ nodeIndex ].
Handle );
02413
02414
RtlInitUnicodeString( &instanceKeyName, instanceNameStr );
02415
02416 status =
IopCreateRegistryKeyEx( &instanceKey,
02417 enumRootKey,
02418 &instanceKeyName,
02419 KEY_ALL_ACCESS,
02420 REG_OPTION_NON_VOLATILE,
02421 &disposition
02422 );
02423
02424
if (
NT_SUCCESS(status)) {
02425
02426 isNewDevice = disposition == REG_CREATED_NEW_KEY;
02427
02428
if (isNewDevice) {
02429
02430
RtlInitUnicodeString( &valueName,
L"DeviceDesc" );
02431
02432 descriptionStr =
PnPBiosGetDescription( &DevNodeInfoList[ nodeIndex ] );
02433 descriptionStrLength = wcslen(descriptionStr) * 2 +
sizeof(UNICODE_NULL);
02434
02435 status = ZwSetValueKey( instanceKey,
02436 &valueName,
02437 0,
02438 REG_SZ,
02439 descriptionStr,
02440 descriptionStrLength );
02441 }
02442
02443
RtlInitUnicodeString( &valueName, REGSTR_VAL_FIRMWAREIDENTIFIED );
02444 dwordValue = 1;
02445
02446 status = ZwSetValueKey( instanceKey,
02447 &valueName,
02448 0,
02449 REG_DWORD,
02450 &dwordValue,
02451
sizeof(dwordValue) );
02452
02453
if (isNewDevice) {
02454
02455
RtlInitUnicodeString( &valueName,
L"HardwareID" );
02456
02457 status = ZwSetValueKey( instanceKey,
02458 &valueName,
02459 0,
02460 REG_MULTI_SZ,
02461 DevNodeInfoList[ nodeIndex ].ProductId,
02462
sizeof(DevNodeInfoList[ nodeIndex ].ProductId) );
02463
02464
if (DevNodeInfoList[ nodeIndex ].CompatibleIDs !=
NULL) {
02465
02466
RtlInitUnicodeString( &valueName,
L"CompatibleIDs" );
02467
02468 status = ZwSetValueKey( instanceKey,
02469 &valueName,
02470 0,
02471 REG_MULTI_SZ,
02472 DevNodeInfoList[ nodeIndex ].CompatibleIDs,
02473 DevNodeInfoList[ nodeIndex ].CompatibleIDsLength );
02474 }
02475 }
02476
02477
RtlInitUnicodeString( &valueName,
L"Replaces" );
02478
02479
if (DevNodeInfoList[ nodeIndex ].Replaces !=
NULL) {
02480
02481 status = ZwSetValueKey( instanceKey,
02482 &valueName,
02483 0,
02484 REG_SZ,
02485 DevNodeInfoList[ nodeIndex ].Replaces,
02486 wcslen(DevNodeInfoList[ nodeIndex ].Replaces) * 2 +
sizeof(UNICODE_NULL) );
02487
02488 }
else if (!isNewDevice) {
02489
02490 status = ZwDeleteValueKey( instanceKey,
02491 &valueName );
02492 }
02493
02494
RtlInitUnicodeString( &controlKeyName, REGSTR_KEY_DEVICECONTROL );
02495
02496 status =
IopCreateRegistryKeyEx( &controlKey,
02497 instanceKey,
02498 &controlKeyName,
02499 KEY_ALL_ACCESS,
02500 REG_OPTION_VOLATILE,
02501
NULL
02502 );
02503
02504
if (
NT_SUCCESS(status)) {
02505
02506
RtlInitUnicodeString( &valueName, REGSTR_VAL_FIRMWAREMEMBER );
02507 dwordValue = 1;
02508
02509 status = ZwSetValueKey( controlKey,
02510 &valueName,
02511 0,
02512 REG_DWORD,
02513 &dwordValue,
02514
sizeof(dwordValue) );
02515
02516
RtlInitUnicodeString( &valueName,
L"PnpBiosDeviceHandle" );
02517 dwordValue = DevNodeInfoList[ nodeIndex ].Handle;
02518
02519 status = ZwSetValueKey( controlKey,
02520 &valueName,
02521 0,
02522 REG_DWORD,
02523 &dwordValue,
02524
sizeof(dwordValue) );
02525
02526
RtlInitUnicodeString( &valueName, REGSTR_VAL_FIRMWAREDISABLED );
02527 dwordValue = DevNodeInfoList[ nodeIndex ].FirmwareDisabled;
02528
02529 status = ZwSetValueKey( controlKey,
02530 &valueName,
02531 0,
02532 REG_DWORD,
02533 &dwordValue,
02534
sizeof(dwordValue) );
02535
02536
RtlInitUnicodeString( &valueName,
L"PnpBiosDeviceHandle" );
02537 dwordValue = DevNodeInfoList[ nodeIndex ].Handle;
02538
02539 ZwClose( controlKey );
02540
02541 }
else {
02542
02543
DebugPrint( (MAPPER_ERROR,
02544
"Could not open registry key %S\\%S\\%S\\Control, status = %8.8X\n",
02545
ENUMROOT_KEY_NAME,
02546 DevNodeInfoList[ nodeIndex ].ProductId,
02547 instanceNameStr,
02548 status) );
02549
02550 ZwClose( instanceKey );
02551 status = STATUS_UNSUCCESSFUL;
02552
02553
goto Cleanup;
02554 }
02555
02556
RtlInitUnicodeString( &logConfKeyName, REGSTR_KEY_LOGCONF );
02557
02558 status =
IopCreateRegistryKeyEx( &logConfKey,
02559 instanceKey,
02560 &logConfKeyName,
02561 KEY_ALL_ACCESS,
02562 REG_OPTION_NON_VOLATILE,
02563
NULL
02564 );
02565
02566
if (
NT_SUCCESS(status)) {
02567
02568
if (DevNodeInfoList[ nodeIndex ].BootConfig !=
NULL) {
02569
02570
RtlInitUnicodeString( &valueName, REGSTR_VAL_BOOTCONFIG );
02571
02572 status = ZwSetValueKey( logConfKey,
02573 &valueName,
02574 0,
02575 REG_RESOURCE_LIST,
02576 DevNodeInfoList[ nodeIndex ].BootConfig,
02577 DevNodeInfoList[ nodeIndex ].BootConfigLength );
02578
02579 }
02580
02581
if (DevNodeInfoList[ nodeIndex ].BasicConfig !=
NULL) {
02582
02583
RtlInitUnicodeString( &valueName, REGSTR_VAL_BASICCONFIGVECTOR );
02584
02585 status = ZwSetValueKey( logConfKey,
02586 &valueName,
02587 0,
02588 REG_RESOURCE_REQUIREMENTS_LIST,
02589 DevNodeInfoList[ nodeIndex ].BasicConfig,
02590 DevNodeInfoList[ nodeIndex ].BasicConfigLength );
02591
02592 }
02593
02594 ZwClose( logConfKey );
02595
02596 }
else {
02597
02598
DebugPrint( (MAPPER_ERROR,
02599
"Could not open registry key %S\\%S\\%S\\LogConf, status = %8.8X\n",
02600
ENUMROOT_KEY_NAME,
02601 DevNodeInfoList[ nodeIndex ].ProductId,
02602 instanceNameStr,
02603 status) );
02604
02605 ZwClose( instanceKey );
02606 status = STATUS_UNSUCCESSFUL;
02607
02608
goto Cleanup;
02609 }
02610
02611
02612
02613
02614
02615
if (isNewDevice && DevNodeInfoList[ nodeIndex ].Replaces !=
NULL) {
02616
02617 status =
PnPBiosCopyDeviceParamKey( enumRootKey,
02618 DevNodeInfoList[ nodeIndex ].Replaces,
02619 instanceNameStr );
02620 }
02621
02622 ZwClose( instanceKey );
02623
02624 }
else {
02625
02626
DebugPrint( (MAPPER_ERROR,
02627
"Could not open registry key %S\\%S\\%S, status = %8.8X\n",
02628
ENUMROOT_KEY_NAME,
02629 DevNodeInfoList[ nodeIndex ].ProductId,
02630 instanceNameStr,
02631 status) );
02632
02633 ZwClose( instanceKey );
02634 status = STATUS_UNSUCCESSFUL;
02635
02636
goto Cleanup;
02637 }
02638
02639
02640
02641
02642
02643
02644
if (DevNodeInfoList[ nodeIndex ].Replaces !=
NULL) {
02645
02646
IopDeleteKeyRecursive( enumRootKey, DevNodeInfoList[ nodeIndex ].Replaces );
02647
02648 }
02649 }
02650
02651 status = STATUS_SUCCESS;
02652
02653 Cleanup:
02654 ZwClose( enumRootKey );
02655
02656
if (excludeList) {
02657
ExFreePool (excludeList);
02658 }
02659
02660
return status;
02661 }
02662
VOID
02663 PnPBiosCopyIoDecode(
02664 IN HANDLE EnumRootKey,
02665 IN PBIOS_DEVNODE_INFO DevNodeInfo
02666 )
02667 {
02668 HANDLE deviceKey;
02669 WCHAR logConfKeyNameStr[
DEFAULT_STRING_SIZE];
02670 UNICODE_STRING logConfKeyName;
02671 HANDLE logConfKey;
02672 UNICODE_STRING valueName;
02673 PKEY_VALUE_PARTIAL_INFORMATION valueInfo =
NULL;
02674 ULONG valueInfoLength;
02675 ULONG returnedLength;
02676
NTSTATUS status;
02677 PCM_PARTIAL_RESOURCE_LIST partialResourceList;
02678 PCM_PARTIAL_RESOURCE_DESCRIPTOR partialDescriptor;
02679 ULONG index;
02680
USHORT flags;
02681
02682
if (DevNodeInfo->Replaces ==
NULL || DevNodeInfo->BootConfig ==
NULL) {
02683
02684
02685
02686
02687
02688
return;
02689 }
02690
02691
02692
02693
02694
02695
02696
ASSERT(DevNodeInfo->BootConfig->Count == 1);
02697
02698 partialResourceList = &DevNodeInfo->BootConfig->List[0].PartialResourceList;
02699
02700 partialDescriptor = &partialResourceList->PartialDescriptors[0];
02701
02702 flags = (
USHORT)~0;
02703
02704
#define DECODE_FLAGS ( CM_RESOURCE_PORT_10_BIT_DECODE | \
02705
CM_RESOURCE_PORT_12_BIT_DECODE | \
02706
CM_RESOURCE_PORT_16_BIT_DECODE | \
02707
CM_RESOURCE_PORT_POSITIVE_DECODE )
02708
02709
for ( index = 0; index < partialResourceList->Count; index++ ) {
02710
if (partialDescriptor->Type == CmResourceTypePort) {
02711
if (flags == (
USHORT)~0) {
02712 flags = partialDescriptor->Flags &
DECODE_FLAGS;
02713 }
else {
02714
ASSERT(flags == (partialDescriptor->Flags &
DECODE_FLAGS));
02715 }
02716 }
02717 partialDescriptor++;
02718 }
02719
02720
if (!(flags & (CM_RESOURCE_PORT_16_BIT_DECODE | CM_RESOURCE_PORT_POSITIVE_DECODE))) {
02721
return;
02722 }
02723
02724 swprintf( logConfKeyNameStr,
02725
L"%s\\%s",
02726 DevNodeInfo->Replaces,
02727 REGSTR_KEY_LOGCONF
02728 );
02729
02730
RtlInitUnicodeString( &logConfKeyName, logConfKeyNameStr );
02731
02732 status =
IopCreateRegistryKeyEx( &logConfKey,
02733 EnumRootKey,
02734 &logConfKeyName,
02735 KEY_ALL_ACCESS,
02736 REG_OPTION_NON_VOLATILE,
02737
NULL
02738 );
02739
02740
if (!
NT_SUCCESS(status)) {
02741
02742
DebugPrint( (MAPPER_ERROR,
02743
"Could not open registry key %S\\%S\\%S, status = %8.8X\n",
02744
ENUMROOT_KEY_NAME,
02745 DevNodeInfo->Replaces,
02746 REGSTR_KEY_LOGCONF,
02747 status) );
02748
02749
return;
02750 }
02751
02752 valueInfoLength =
sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
DEFAULT_STRING_SIZE;
02753 valueInfo =
ExAllocatePool(
PagedPool, valueInfoLength);
02754
02755
if (valueInfo ==
NULL) {
02756
02757 ZwClose( logConfKey );
02758
02759
return;
02760 }
02761
02762
RtlInitUnicodeString( &valueName, REGSTR_VAL_BOOTCONFIG );
02763
02764 status = ZwQueryValueKey( logConfKey,
02765 &valueName,
02766 KeyValuePartialInformation,
02767 valueInfo,
02768 valueInfoLength,
02769 &returnedLength);
02770
02771
if (!
NT_SUCCESS(status)) {
02772
02773
if (status == STATUS_BUFFER_TOO_SMALL || status == STATUS_BUFFER_OVERFLOW) {
02774
02775
02776
02777
02778
02779
ExFreePool( valueInfo );
02780
02781 valueInfoLength = returnedLength;
02782 valueInfo =
ExAllocatePool(
PagedPool, valueInfoLength );
02783
02784
if (valueInfo !=
NULL) {
02785
02786 status = ZwQueryValueKey( logConfKey,
02787 &valueName,
02788 KeyValuePartialInformation,
02789 valueInfo,
02790 valueInfoLength,
02791 &returnedLength );
02792
02793
if (!
NT_SUCCESS(status)) {
02794
DebugPrint( (MAPPER_ERROR,
02795
"Could not query registry value %S\\%S\\LogConf\\BootConfig, status = %8.8X\n",
02796
ENUMROOT_KEY_NAME,
02797 DevNodeInfo->Replaces,
02798 status) );
02799
02800
ExFreePool( valueInfo );
02801
02802 ZwClose( logConfKey );
02803
02804
return;
02805 }
02806 }
else {
02807
02808
DebugPrint( (MAPPER_ERROR,
02809
"Could not allocate memory for BootConfig value\n"
02810 ) );
02811
02812 ZwClose( logConfKey );
02813
02814
return;
02815 }
02816 }
02817 }
02818
02819 partialResourceList = &((PCM_RESOURCE_LIST)valueInfo->Data)->List[0].PartialResourceList;
02820
02821 partialDescriptor = &partialResourceList->PartialDescriptors[0];
02822
02823
for ( index = 0; index < partialResourceList->Count; index++ ) {
02824
if (partialDescriptor->Type == CmResourceTypePort) {
02825 partialDescriptor->Flags &= ~
DECODE_FLAGS;
02826 partialDescriptor->Flags |= flags;
02827 }
02828 partialDescriptor++;
02829 }
02830
02831 status = ZwSetValueKey( logConfKey,
02832 &valueName,
02833 0,
02834 REG_RESOURCE_LIST,
02835 valueInfo->Data,
02836 valueInfo->DataLength );
02837
02838
if (!
NT_SUCCESS(status)) {
02839
DebugPrint( (MAPPER_ERROR,
02840
"Could not set registry value %S\\%S\\LogConf\\BootConfig, status = %8.8X\n",
02841
ENUMROOT_KEY_NAME,
02842 DevNodeInfo->Replaces,
02843 status) );
02844 }
02845
02846
ExFreePool(valueInfo);
02847
02848 ZwClose(logConfKey);
02849 }
02850
02851
NTSTATUS
02852 PnPBiosCheckForHardwareDisabled(
02853 IN PIO_RESOURCE_REQUIREMENTS_LIST IoResourceList,
02854 IN OUT PBOOLEAN Disabled
02855 )
02856
02857
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874 {
02875 BOOLEAN ParsedResource =
FALSE;
02876 PIO_RESOURCE_DESCRIPTOR ioDescriptor;
02877 ULONG descIndex;
02878
02879
02880
02881
02882
02883
02884
ASSERT(IoResourceList->AlternativeLists == 1);
02885
ASSERT(Disabled !=
NULL);
02886
02887 *Disabled =
FALSE;
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897
for (descIndex = 0; descIndex < IoResourceList->List[ 0 ].Count; descIndex++) {
02898
02899 ioDescriptor = &IoResourceList->List[ 0 ].Descriptors[ descIndex ];
02900
02901
switch (ioDescriptor->Type) {
02902
02903
case CmResourceTypePort:
02904
if (ioDescriptor->u.Port.Length) {
02905
return STATUS_SUCCESS;
02906 }
02907 ParsedResource =
TRUE;
02908
break;
02909
02910
case CmResourceTypeInterrupt:
02911
if (ioDescriptor->u.Interrupt.MinimumVector != (ULONG)(-1)) {
02912
return STATUS_SUCCESS;
02913 }
02914 ParsedResource =
TRUE;
02915
break;
02916
02917
case CmResourceTypeMemory:
02918
if (ioDescriptor->u.Memory.Length) {
02919
return STATUS_SUCCESS;
02920 }
02921 ParsedResource =
TRUE;
02922
break;
02923
02924
case CmResourceTypeDma:
02925
if (ioDescriptor->u.Dma.MinimumChannel != (ULONG)(-1)) {
02926
return STATUS_SUCCESS;
02927 }
02928 ParsedResource =
TRUE;
02929
break;
02930
02931
default:
02932
DebugPrint( (MAPPER_ERROR,
02933
"Unexpected ResourceType (%d) in I/O Descriptor\n",
02934 ioDescriptor->Type) );
02935
02936
#if DBG
02937
02938
#endif
02939
break;
02940 }
02941 }
02942
02943
if (ParsedResource) {
02944
02945
02946
02947 *Disabled =
TRUE;
02948 }
02949
02950
return STATUS_SUCCESS;
02951
02952 }
02953
02954
02955
NTSTATUS
02956 PnPBiosFreeDevNodeInfo(
02957 IN PBIOS_DEVNODE_INFO DevNodeInfoList,
02958 IN ULONG NumberNodes
02959 )
02960
02961
02962
02963
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980 {
02981 ULONG nodeIndex;
02982
02983
for (nodeIndex = 0; nodeIndex < NumberNodes; nodeIndex++) {
02984
02985
if (DevNodeInfoList[nodeIndex].Replaces !=
NULL) {
02986
ExFreePool( DevNodeInfoList[nodeIndex].Replaces );
02987 }
02988
02989
if (DevNodeInfoList[nodeIndex].CompatibleIDs !=
NULL) {
02990
ExFreePool( DevNodeInfoList[nodeIndex].CompatibleIDs );
02991 }
02992
02993
if (DevNodeInfoList[nodeIndex].BootConfig !=
NULL) {
02994
ExFreePool( DevNodeInfoList[nodeIndex].BootConfig );
02995 }
02996
02997
if (DevNodeInfoList[nodeIndex].BasicConfig !=
NULL) {
02998
ExFreePool( DevNodeInfoList[nodeIndex].BasicConfig );
02999 }
03000 }
03001
03002
ExFreePool( DevNodeInfoList );
03003
03004
return STATUS_SUCCESS;
03005 }
03006
03007
NTSTATUS
03008 PnPBiosMapper()
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019
03020
03021
03022
03023
03024
03025 {
03026 PCM_RESOURCE_LIST biosInfo;
03027 ULONG length;
03028
NTSTATUS status;
03029
PBIOS_DEVNODE_INFO devNodeInfoList;
03030 ULONG numberNodes;
03031
03032 status =
PnPBiosGetBiosInfo( &biosInfo, &length );
03033
03034
if (!
NT_SUCCESS( status )) {
03035
03036
return status;
03037 }
03038
03039 status =
PnPBiosTranslateInfo( biosInfo,
03040 length,
03041 &devNodeInfoList,
03042 &numberNodes );
03043
03044
ExFreePool( biosInfo );
03045
03046
if (!
NT_SUCCESS( status )) {
03047
03048
return status;
03049 }
03050
03051 status =
PnPBiosEliminateDupes( devNodeInfoList, numberNodes );
03052
03053
if (
NT_SUCCESS( status )) {
03054
03055 status =
PnPBiosWriteInfo( devNodeInfoList, numberNodes );
03056
03057 }
03058
03059
PnPBiosFreeDevNodeInfo( devNodeInfoList, numberNodes );
03060
03061
return status;
03062 }
03063
03064
VOID
03065 PpFilterNtResource (
03066 IN PWCHAR PnpDeviceName,
03067 PIO_RESOURCE_REQUIREMENTS_LIST ResReqList
03068 )
03069 {
03070 PIO_RESOURCE_LIST ioResourceList;
03071 PIO_RESOURCE_DESCRIPTOR ioResourceDescriptors;
03072
03073
if (ResReqList ==
NULL) {
03074
return;
03075 }
03076
03077
if (IsNEC_98) {
03078
return;
03079 }
03080
03081
#if 0 //_X86_
03082
if (
KeI386MachineType == MACHINE_TYPE_EISA) {
03083
03084 PCM_FULL_RESOURCE_DESCRIPTOR fullDescriptor;
03085 PCM_PARTIAL_RESOURCE_DESCRIPTOR partialDescriptor;
03086 PUCHAR nextDescriptor;
03087 ULONG j;
03088 ULONG lastResourceIndex;
03089
03090 fullDescriptor = &ResourceList->List[0];
03091
03092
for (i = 0; i < ResourceList->Count; i++) {
03093
03094 partialResourceList = &fullDescriptor->PartialResourceList;
03095
03096
for (j = 0; j < partialResourceList->Count; j++) {
03097 partialDescriptor = &partialResourceList->PartialDescriptors[j];
03098
03099
if (partialDescriptor->Type == CmResourceTypePort) {
03100
if (partialDescriptor->u.Port.Start.HighPart == 0 &&
03101 (partialDescriptor->u.Port.Start.LowPart & 0x00000300) == 0) {
03102 partialDescriptor->Flags |= CM_RESOURCE_PORT_16_BIT_DECODE;
03103 }
03104 }
03105 }
03106
03107 nextDescriptor = (PUCHAR)fullDescriptor +
sizeof(CM_FULL_RESOURCE_DESCRIPTOR);
03108
03109
03110
03111
03112
03113
03114
03115
03116
03117
03118
03119
if (partialResourceList->Count > 0) {
03120
03121 nextDescriptor += (partialResourceList->Count - 1) *
03122
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
03123
03124 lastResourceIndex = partialResourceList->Count - 1;
03125
03126
if (partialResourceList->PartialDescriptors[lastResourceIndex].Type ==
03127 CmResourceTypeDeviceSpecific) {
03128
03129 nextDescriptor += partialResourceList->PartialDescriptors[lastResourceIndex].
03130 u.DeviceSpecificData.DataSize;
03131 }
03132 }
03133
03134 fullDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)nextDescriptor;
03135 }
03136 }
03137
#endif
03138
03139
if (RtlCompareMemory(PnpDeviceName,
03140
L"*PNP06",
03141
sizeof(
L"*PNP06") -
sizeof(WCHAR)) ==
03142
sizeof(
L"*PNP06") -
sizeof(WCHAR)) {
03143
03144 ULONG i, j;
03145
03146 ioResourceList = ResReqList->List;
03147
03148
for (j = 0; j < ResReqList->AlternativeLists; j++) {
03149
03150 ioResourceDescriptors = ioResourceList->Descriptors;
03151
03152
for (i = 0; i < ioResourceList->Count; i++) {
03153
03154
if (ioResourceDescriptors[i].Type == CmResourceTypePort) {
03155
03156
03157
03158
03159
if ((ioResourceDescriptors[i].u.Port.Length == 2) &&
03160 (ioResourceDescriptors[i].u.Port.MaximumAddress.QuadPart ==
03161 (ioResourceDescriptors[i].u.Port.MinimumAddress.QuadPart + 1))) {
03162
03163 ioResourceDescriptors[i].u.Port.Length = 1;
03164 ioResourceDescriptors[i].u.Port.MaximumAddress =
03165 ioResourceDescriptors[i].u.Port.MinimumAddress;
03166 }
03167 }
03168 }
03169
03170 ioResourceList = (PIO_RESOURCE_LIST) (ioResourceDescriptors + ioResourceList->Count);
03171 }
03172 }
03173 }
03174
03175
03176
03177
#if DBG
03178
VOID
03179 PnPBiosDebugPrint(
03180 ULONG DebugMask,
03181 PCCHAR DebugMessage,
03182 ...
03183 )
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201 {
03202 va_list ap;
03203
CHAR buffer[256];
03204
03205 va_start( ap, DebugMessage );
03206
03207
#define DBG_MSG_PREFIX "BiosMapper: "
03208
03209 strcpy(buffer, DBG_MSG_PREFIX);
03210
03211
if ( DebugMask & PnPBiosMapperDebugMask ) {
03212
03213 _vsnprintf( &buffer[
sizeof(DBG_MSG_PREFIX) - 1],
03214
sizeof(buffer) -
sizeof(DBG_MSG_PREFIX),
03215 DebugMessage,
03216 ap );
03217
03218
DbgPrint( buffer );
03219 }
03220
03221 va_end(ap);
03222
03223 }
03224
#endif
03225