test: pnpmap.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# pnpmap.c File Reference

`#include "iop.h"`
`#include "pnpcvrt.h"`
`#include "pbios.h"`

Go to the source code of this file.

## Classes

struct | _EXCLUDED_PNPNODE
struct | _CLASSDATA
struct | _CLASS_DESCRIPTIONS_LIST
struct | _BIOS_DEVNODE_INFO

## Defines

#define | DebugPrint(X)
#define | MULTIFUNCTION_KEY_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"
#define | ENUMROOT_KEY_NAME L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\Root"
#define | BIOSINFO_KEY_NAME L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Biosinfo\\PNPBios"
#define | BIOSINFO_VALUE_NAME L"DisableNodes"
#define | DECODEINFO_VALUE_NAME L"FullDecodeChipsetOverride"
#define | INSTANCE_ID_PREFIX L"PnPBIOS_"
#define | DEFAULT_STRING_SIZE 80
#define | DEFAULT_VALUE_SIZE 80
#define | DEFAULT_DEVICE_DESCRIPTION L"Unknown device class"
#define | EXCLUSION_ENTRY(a) { a, sizeof(a) - sizeof(UNICODE_NULL) }
#define | EXCLUDED_DEVICES_COUNT (sizeof(ExcludedDevices) / sizeof(ExcludedDevices[0]))
#define | EXCLUDE_DISABLED_COUNT (sizeof(ExcludeIfDisabled) / sizeof(ExcludeIfDisabled[0]))
#define | CLASSLIST_ENTRY(a) { a, sizeof(a) / sizeof(a[0]) }
#define | CLASSLIST_COUNT ( sizeof(ClassDescriptionsList) / sizeof(ClassDescriptionsList[0]) )
#define | DECODE_FLAGS

## Typedefs

typedef _EXCLUDED_PNPNODE | EXCLUDED_PNPNODE
typedef _EXCLUDED_PNPNODE * | PEXCLUDED_PNPNODE
typedef _CLASSDATA | CLASSDATA
typedef _BIOS_DEVNODE_INFO | BIOS_DEVNODE_INFO
typedef _BIOS_DEVNODE_INFO * | PBIOS_DEVNODE_INFO

## Functions

NTSTATUS | PbBiosResourcesToNtResources (IN ULONG BusNumber, IN ULONG SlotNumber, IN OUT PUCHAR *BiosData, OUT PIO_RESOURCE_REQUIREMENTS_LIST *ReturnedList, OUT PULONG ReturnedLength)
VOID | PnPBiosExpandProductId (PUCHAR CompressedId, PWCHAR ProductIDStr)
NTSTATUS | PnPBiosIoResourceListToCmResourceList (IN PIO_RESOURCE_REQUIREMENTS_LIST IoResourceList, OUT PCM_RESOURCE_LIST *CmResourceList, OUT ULONG *CmResourceListSize)
NTSTATUS | PnPBiosExtractCompatibleIDs (IN PUCHAR *DevNodeData, IN ULONG DevNodeDataLength, OUT PWSTR *CompatibleIDs, OUT ULONG *CompatibleIDsLength)
NTSTATUS | PnPBiosTranslateInfo (IN VOID *BiosInfo, IN ULONG BiosInfoLength, OUT PBIOS_DEVNODE_INFO *DevNodeInfoList, OUT ULONG *NumberNodes)
LONG | PnPBiosFindMatchingDevNode (IN PWCHAR MapperName, IN PCM_RESOURCE_LIST ResourceList, IN PBIOS_DEVNODE_INFO DevNodeInfoList, IN ULONG NumberNodes)
NTSTATUS | PnPBiosEliminateDupes (IN PBIOS_DEVNODE_INFO DevNodeInfoList, IN ULONG NumberNodes)
PWCHAR | PnPBiosGetDescription (IN PBIOS_DEVNODE_INFO DevNodeInfoEntry)
NTSTATUS | PnPBiosWriteInfo (IN PBIOS_DEVNODE_INFO DevNodeInfoList, IN ULONG NumberNodes)
VOID | PnPBiosCopyIoDecode (IN HANDLE EnumRootKey, IN PBIOS_DEVNODE_INFO DevNodeInfo)
NTSTATUS | PnPBiosFreeDevNodeInfo (IN PBIOS_DEVNODE_INFO DevNodeInfoList, IN ULONG NumberNodes)
NTSTATUS | PnPBiosCheckForHardwareDisabled (IN PIO_RESOURCE_REQUIREMENTS_LIST IoResourceList, IN OUT PBOOLEAN Disabled)
BOOLEAN | PnPBiosCheckForExclusion (IN PEXCLUDED_PNPNODE ExclusionArray, IN ULONG ExclusionCount, IN PWCHAR PnpDeviceName, IN PWCHAR PnpCompatIds)
NTSTATUS | PnPBiosMapper (VOID)
VOID | PpFilterNtResource (IN PWCHAR PnpDeviceName, PIO_RESOURCE_REQUIREMENTS_LIST ResReqList)
NTSTATUS | ComPortDBAdd (IN HANDLE DeviceParamKey, IN PWSTR PortName)
NTSTATUS | PnPBiosGetBiosInfo (OUT PVOID *BiosInfo, OUT ULONG *BiosInfoLength)
BOOLEAN | PnPBiosIgnoreNode (PWCHAR PnpID, PWCHAR excludeNodes)
VOID | PnPGetDevnodeExcludeList (OUT PKEY_VALUE_FULL_INFORMATION *ExcludeList)
BOOLEAN | PnPCheckFixedIoOverrideDecodes (VOID)
BOOLEAN | PnPBiosCheckForExclusion (IN EXCLUDED_PNPNODE *Exclusions, IN ULONG ExclusionCount, IN PWCHAR PnpDeviceName, IN PWCHAR PnpCompatIds)
NTSTATUS | PnPBiosCopyDeviceParamKey (IN HANDLE EnumRootKey, IN PWCHAR SourcePath, IN PWCHAR DestinationPath)
NTSTATUS | PnPBiosMapper ()

## Variables

EXCLUDED_PNPNODE | ExcludedDevices []
EXCLUDED_PNPNODE | ExcludeIfDisabled []
CLASSDATA | Class1Descriptions []
CLASSDATA | Class2Descriptions []
CLASSDATA | Class3Descriptions []
CLASSDATA | Class4Descriptions []
CLASSDATA | Class5Descriptions []
CLASSDATA | Class6Descriptions []
CLASSDATA | Class7Descriptions []
CLASSDATA | Class8Descriptions []
CLASSDATA | Class9Descriptions []
CLASSDATA | Class10Descriptions []
CLASSDATA | Class11Descriptions []
CLASSDATA | Class12Descriptions []
_CLASS_DESCRIPTIONS_LIST | ClassDescriptionsList []

## Define Documentation

#define BIOSINFO_KEY_NAME L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Biosinfo\\PNPBios"

| Definition at line 86 of file pnpmap.c. Referenced by PnPCheckFixedIoOverrideDecodes(), and PnPGetDevnodeExcludeList().

#define BIOSINFO_VALUE_NAME L"DisableNodes"

| Definition at line 87 of file pnpmap.c. Referenced by PnPGetDevnodeExcludeList().

#define CLASSLIST_COUNT ( sizeof(ClassDescriptionsList) / sizeof(ClassDescriptionsList[0]) )

| Definition at line 255 of file pnpmap.c. Referenced by PnPBiosGetDescription().

#define CLASSLIST_ENTRY | ( | a |  | ) | { a, sizeof(a) / sizeof(a[0]) }

| Definition at line 231 of file pnpmap.c.

#define DebugPrint | ( | X |  | ) |

| Definition at line 74 of file pnpmap.c.

#define DECODE_FLAGS

Value:

    ( CM_RESOURCE_PORT_10_BIT_DECODE | \
                           CM_RESOURCE_PORT_12_BIT_DECODE | \
                           CM_RESOURCE_PORT_16_BIT_DECODE | \
                           CM_RESOURCE_PORT_POSITIVE_DECODE )

Referenced by PnPBiosCopyIoDecode().

#define DECODEINFO_VALUE_NAME L"FullDecodeChipsetOverride"

| Definition at line 88 of file pnpmap.c. Referenced by PnPCheckFixedIoOverrideDecodes().

#define DEFAULT_DEVICE_DESCRIPTION L"Unknown device class"

| Definition at line 95 of file pnpmap.c. Referenced by PnPBiosGetDescription().

#define DEFAULT_STRING_SIZE 80

| Definition at line 92 of file pnpmap.c. Referenced by PnPBiosCopyDeviceParamKey(), PnPBiosCopyIoDecode(), PnPBiosEliminateDupes(), PnPBiosGetBiosInfo(), and PnPBiosWriteInfo().

#define DEFAULT_VALUE_SIZE 80

| Definition at line 93 of file pnpmap.c. Referenced by PnPBiosCopyDeviceParamKey().

#define ENUMROOT_KEY_NAME L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\Root"

| Definition at line 83 of file pnpmap.c. Referenced by PnPBiosCopyIoDecode(), PnPBiosEliminateDupes(), and PnPBiosWriteInfo().

#define EXCLUDE_DISABLED_COUNT (sizeof(ExcludeIfDisabled) / sizeof(ExcludeIfDisabled[0]))

| Definition at line 124 of file pnpmap.c. Referenced by PnPBiosWriteInfo().

#define EXCLUDED_DEVICES_COUNT (sizeof(ExcludedDevices) / sizeof(ExcludedDevices[0]))

| Definition at line 117 of file pnpmap.c. Referenced by PnPBiosWriteInfo().

#define EXCLUSION_ENTRY | ( | a |  | ) | { a, sizeof(a) - sizeof(UNICODE_NULL) }

| Definition at line 98 of file pnpmap.c.

#define INSTANCE_ID_PREFIX L"PnPBIOS_"

| Definition at line 90 of file pnpmap.c. Referenced by PnPBiosEliminateDupes(), and PnPBiosWriteInfo().

#define MULTIFUNCTION_KEY_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"

| Definition at line 82 of file pnpmap.c. Referenced by PnPBiosGetBiosInfo().

## Typedef Documentation

typedef struct _BIOS_DEVNODE_INFO BIOS_DEVNODE_INFO

typedef struct _CLASSDATA CLASSDATA

typedef struct _EXCLUDED_PNPNODE EXCLUDED_PNPNODE

typedef struct _BIOS_DEVNODE_INFO * PBIOS_DEVNODE_INFO

| Referenced by PnPBiosMapper(), and PnPBiosTranslateInfo().

typedef struct _EXCLUDED_PNPNODE * PEXCLUDED_PNPNODE

## Function Documentation

NTSTATUS ComPortDBAdd | ( | IN HANDLE | DeviceParamKey,
|  | IN PWSTR | PortName
| ) |

| Referenced by MapperSeedKey(), and PnPBiosCopyDeviceParamKey().

NTSTATUS PbBiosResourcesToNtResources | ( | IN ULONG | BusNumber,
|  | IN ULONG | SlotNumber,
|  | IN OUT PUCHAR * | BiosData,
|  | OUT PIO_RESOURCE_REQUIREMENTS_LIST * | ReturnedList,
|  | OUT PULONG | ReturnedLength
| ) |

BOOLEAN PnPBiosCheckForExclusion | ( | IN EXCLUDED_PNPNODE * | Exclusions,
|  | IN ULONG | ExclusionCount,
|  | IN PWCHAR | PnpDeviceName,
|  | IN PWCHAR | PnpCompatIds
| ) |

Definition at line 835 of file pnpmap.c.

References FALSE, NULL, and TRUE.

Referenced by PnPBiosWriteInfo().

    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 }

BOOLEAN PnPBiosCheckForExclusion | ( | IN PEXCLUDED_PNPNODE | ExclusionArray,
|  | IN ULONG | ExclusionCount,
|  | IN PWCHAR | PnpDeviceName,
|  | IN PWCHAR | PnpCompatIds
| ) |

NTSTATUS PnPBiosCheckForHardwareDisabled | ( | IN PIO_RESOURCE_REQUIREMENTS_LIST | IoResourceList,
|  | IN OUT PBOOLEAN | Disabled
| ) |

Definition at line 2852 of file pnpmap.c.

References ASSERT, DebugPrint, FALSE, NULL, and TRUE.

Referenced by PnPBiosTranslateInfo().

    02858                    :
    02859
    02860     If this device has been assigned one or more resources, and each resource has a length of zero, then it is
    02861     hardware disabled.
    02862
    02863 Arguments:
    02864
    02865     IoResourceList - Resource obtained from BIOS that we're about to map to a CmResourceList
    02866
    02867     Disabled - Set to TRUE if the device is deemed to be disabled
    02868
    02869 Return Value:
    02870
    02871     STATUS_SUCCESS if no errors, otherwise the appropriate error.
    02872
    02873 --*/
    02874 {
    02875     BOOLEAN ParsedResource = FALSE;
    02876     PIO_RESOURCE_DESCRIPTOR ioDescriptor;
    02877     ULONG descIndex;
    02878     //
    02879     // Since this routine is only used to translate the allocated resources
    02880     // returned by the PnP BIOS, we can assume that there is only 1 alternative
    02881     // list
    02882     //
    02883
    02884     ASSERT(IoResourceList->AlternativeLists == 1);
    02885     ASSERT(Disabled != NULL);
    02886
    02887     *Disabled = FALSE;
    02888
    02889     //
    02890     // Translate each resource descriptor, currently we only handle ports,
    02891     // memory, interrupts, and dma.  The current implementation of the routine
    02892     // which converts from ISA PnP Resource data to IO_RESOURCE_REQUIREMENTS
    02893     // won't generate any other descriptor types given the data returned from
    02894     // the BIOS.
    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             // DbgBreakPoint();
    02938 #endif
    02939             break;
    02940         }
    02941     }
    02942
    02943     if (ParsedResource) {
    02944         //
    02945         // at least one empty resource, no non-empty resources
    02946         //
    02947         *Disabled = TRUE;
    02948     }
    02949
    02950     return STATUS_SUCCESS;
    02951
    02952 }

NTSTATUS PnPBiosCopyDeviceParamKey | ( | IN HANDLE | EnumRootKey,
|  | IN PWCHAR | SourcePath,
|  | IN PWCHAR | DestinationPath
| ) |

Definition at line 2089 of file pnpmap.c.

References ComPortDBAdd(), DebugPrint, DEFAULT_STRING_SIZE, DEFAULT_VALUE_SIZE, ExAllocatePool, ExFreePool(), IopOpenDeviceParametersSubkey(), IopOpenRegistryKeyEx(), L, NT_SUCCESS, NTSTATUS(), NULL, PagedPool, RtlCompareUnicodeString(), RtlInitUnicodeString(), TRUE, and USHORT.

Referenced by PnPBiosWriteInfo().

    02096                    :
    02097
    02098     Copy the Device Parameters key from the firmware mapper node in
    02099     DevNodeInfo->Replaces to the BIOS mapper node represented by DevNodeInfo.
    02100
    02101 Arguments:
    02102
    02103     EnumRootKey - Handle to Enum\Root.
    02104
    02105     SourcePath - Instance path of FW Mapper node relative to Enum\Root.
    02106
    02107     DestinationKey - Handle to destination instance key.
    02108
    02109 Return Value:
    02110
    02111     STATUS_SUCCESS if no errors, otherwise the appropriate error.
    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                     // ComPortDBRemove(SourcePath, &unicodeValue);
    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 }

VOID PnPBiosCopyIoDecode | ( | IN HANDLE | EnumRootKey,
|  | IN PBIOS_DEVNODE_INFO | DevNodeInfo
| ) |

Definition at line 2663 of file pnpmap.c.

References ASSERT, DebugPrint, DECODE_FLAGS, DEFAULT_STRING_SIZE, ENUMROOT_KEY_NAME, ExAllocatePool, ExFreePool(), IopCreateRegistryKeyEx(), L, NT_SUCCESS, NTSTATUS(), NULL, PagedPool, RtlInitUnicodeString(), and USHORT.

Referenced by PnPBiosWriteInfo().

    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         // If we didn't find a FW Mapper created devnode then there is nothing
    02686         // to do.
    02687         //
    02688         return;
    02689     }
    02690
    02691     //
    02692     // Search through the Boot Config and see if the device's I/O ports are
    02693     // 16 bit decode.
    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             // The default buffer was too small, free it and reallocate
    02777             // it to the required size.
    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 }

NTSTATUS PnPBiosEliminateDupes | ( | IN PBIOS_DEVNODE_INFO | DevNodeInfoList,
|  | IN ULONG | NumberNodes
| ) |

Definition at line 1725 of file pnpmap.c.

References DebugPrint, DEFAULT_STRING_SIZE, ENUMROOT_KEY_NAME, ExAllocatePool, ExFreePool(), Handle, INSTANCE_ID_PREFIX, IopOpenRegistryKeyEx(), L, NT_SUCCESS, NTSTATUS(), NULL, PagedPool, PnPBiosFindMatchingDevNode(), and RtlInitUnicodeString().

Referenced by PnPBiosMapper().

    01731                    :
    01732
    01733     This routine enumerates the Firmware Mapper generated devices under
    01734     Enum\Root.  Those that match entries in DevNodeInfoList have their registry
    01735     key name stored in the DevNodeInfoList entry so that the Firmare Mapper
    01736     instance may be removed later.
    01737
    01738 Arguments:
    01739
    01740     DevNodeInfoList - Array of BIOS_DEVNODE_INFO structures, one for each device
    01741         reported by the BIOS.
    01742
    01743     NumberNodes - Number of BIOS_DEVNODE_INFO elements pointed to by
    01744         DevNodeInfoList.
    01745
    01746 Return Value:
    01747
    01748     STATUS_SUCCESS if no errors, otherwise the appropriate error.
    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 }

VOID PnPBiosExpandProductId | ( | PUCHAR | CompressedId,
|  | PWCHAR | ProductIDStr
| ) |

Definition at line 687 of file pnpmap.c.

References CHAR.

Referenced by PnPBiosExtractCompatibleIDs(), and PnPBiosTranslateInfo().

    00693                    :
    00694
    00695     This function expands a PnP Device ID from the 4 byte compressed form into
    00696     an 7 character unicode string.  The string is then NUL terminated.
    00697
    00698 Arguments:
    00699
    00700     CompressedId - Pointer to the 4 byte compressed Device ID as defined in the
    00701         PnP Specification.
    00702
    00703     ProductIDStr - Pointer to the 16 byte buffer in which the unicode string
    00704         version of the ID is placed.
    00705
    00706
    00707 Return Value:
    00708
    00709     NONE.
    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 }

NTSTATUS PnPBiosExtractCompatibleIDs | ( | IN PUCHAR * | DevNodeData,
|  | IN ULONG | DevNodeDataLength,
|  | OUT PWSTR * | CompatibleIDs,
|  | OUT ULONG * | CompatibleIDsLength
| ) |

Definition at line 1026 of file pnpmap.c.

References ExAllocatePool, LARGE_RESOURCE_TAG, NULL, PagedPool, PnPBiosExpandProductId(), SMALL_TAG_MASK, SMALL_TAG_SIZE_MASK, TAG_COMPATIBLE_ID, TAG_COMPLETE_END, and USHORT.

Referenced by PnPBiosTranslateInfo().

    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         // Determine the size of the BIOS resource descriptor
    01054         //
    01055
    01056         if (!(tagName & LARGE_RESOURCE_TAG)) {
    01057             increment = (USHORT)(tagName & SMALL_TAG_SIZE_MASK);
    01058             increment++;     // length of small tag
    01059             tagName &= SMALL_TAG_MASK;
    01060         } else {
    01061             increment = *(USHORT UNALIGNED *)(&currentPtr[1]);
    01062             increment += 3;     // length of large tag
    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         // Determine the size of the BIOS resource descriptor
    01100         //
    01101
    01102         if (!(tagName & LARGE_RESOURCE_TAG)) {
    01103             increment = (USHORT)(tagName & SMALL_TAG_SIZE_MASK);
    01104             increment++;     // length of small tag
    01105             tagName &= SMALL_TAG_MASK;
    01106         } else {
    01107             increment = *(USHORT UNALIGNED *)(&currentPtr[1]);
    01108             increment += 3;     // length of large tag
    01109         }
    01110
    01111         if (tagName == TAG_COMPATIBLE_ID) {
    01112
    01113             *idPtr = '*';
    01114             PnPBiosExpandProductId(&currentPtr[1], &idPtr[1]);
    01115             idPtr += 9;
    01116         }
    01117     }
    01118
    01119     *idPtr++ = '\0';  // Extra NUL for REG_MULTI_SZ
    01120     *CompatibleIDsLength = (ULONG)(idPtr - *CompatibleIDs) * sizeof(WCHAR);
    01121
    01122     return STATUS_SUCCESS;
    01123 }

LONG PnPBiosFindMatchingDevNode | ( | IN PWCHAR | MapperName,
|  | IN PCM_RESOURCE_LIST | ResourceList,
|  | IN PBIOS_DEVNODE_INFO | DevNodeInfoList,
|  | IN ULONG | NumberNodes
| ) |

Definition at line 1410 of file pnpmap.c.

References ASSERT, CHAR, DebugPrint, FALSE, and NULL.

Referenced by PnPBiosEliminateDupes().

    01418                    :
    01419
    01420     Given a list of resources this routine finds an entry in the
    01421     DevNodeInfoList whose BootConfig resources match.  A match is defined as
    01422     having at least overlapping I/O Ports or Memory Ranges.  If ResourceList doesn't
    01423     include any I/O Ports or Memory Ranges then a match is defined as exactly
    01424     the same interrupts and/or DMA channels.
    01425
    01426     This routine is used to find PnP BIOS reported devices which match devices
    01427     created by the Firmware Mapper.
    01428
    01429 Arguments:
    01430
    01431     ResourceList - Pointer to CM_RESOURCE_LIST describing the resources
    01432         currently used by the device for which a match is being searched.
    01433
    01434     DevNodeInfoList - Array of BIOS_DEVNODE_INFO structures, one for each device
    01435         reported by the BIOS.
    01436
    01437     NumberNodes - Number of BIOS_DEVNODE_INFO elements pointed to by
    01438         DevNodeInfoList.
    01439
    01440
    01441 Return Value:
    01442
    01443     Index of the entry in DevNodeInfoList whose BootConfig matches the resources
    01444     listed in ResourceList.  If no matching entry is found then -1 is returned.
    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     // In order to simplify the problem we assume there is only one list.  This
    01468     // assumption holds true in the BootConfig structures generated by the
    01469     // current firmware mapper.
    01470     //
    01471     ASSERT( ResourceList->Count == 1 );
    01472
    01473     sourceList = &ResourceList->List[0].PartialResourceList;
    01474
    01475 #if DEBUG_DUP_MATCH
    01476     //
    01477     // For debugging purposes we keep track of which resource entries map to
    01478     // each other.  These relationships are stored in a fixed CHAR array, thus
    01479     // the restriction on the number of descriptors.
    01480     //
    01481     ASSERT( sourceList->Count < 255 );
    01482 #endif
    01483
    01484     //
    01485     // Loop through each devnode and try and match it to the source resource
    01486     // list.
    01487     //
    01488     for (nodeIndex = 0; nodeIndex < NumberNodes; nodeIndex++) {
    01489
    01490         if (DevNodeInfoList[ nodeIndex ].BootConfig == NULL) {
    01491
    01492             continue;
    01493         }
    01494
    01495         //
    01496         // We found at least one potential match.  Let's double check if
    01497         // the PNP ids also match.  We use a lack of ID match to disqualify
    01498         // entries which don't match at least I/O ports or memory.
    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         // Loop through each source descriptor (resource) and try and match it
    01543         // to one of this devnode's descriptors.
    01544         //
    01545
    01546         for (sourceIndex = 0; sourceIndex < sourceList->Count; sourceIndex++) {
    01547
    01548             sourceDescriptor = &sourceList->PartialDescriptors[sourceIndex];
    01549
    01550             //
    01551             // We are recalculating the possible score unnecessarily each time
    01552             // we process a devnode.  We might save a small amount of time by
    01553             // looping through the source descriptors once at the beginning but
    01554             // its not clear it would make all that much difference given the
    01555             // few devices reported by the BIOS.
    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             // Try to find a resource in the target devnode which matches the
    01582             // current source resource.
    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 }

NTSTATUS PnPBiosFreeDevNodeInfo | ( | IN PBIOS_DEVNODE_INFO | DevNodeInfoList,
|  | IN ULONG | NumberNodes
| ) |

Definition at line 2956 of file pnpmap.c.

References ExFreePool(), and NULL.

Referenced by PnPBiosMapper().

    02962                    :
    02963
    02964     Free the dynamically allocated DevNodeInfoList as well as any dynamically
    02965     allocated dependent structures.
    02966
    02967 Arguments:
    02968
    02969     DevNodeInfoList - Array of BIOS_DEVNODE_INFO structures, one for each device
    02970         reported by the BIOS.
    02971
    02972     NumberNodes - Number of BIOS_DEVNODE_INFO elements pointed to by
    02973         DevNodeInfoList.
    02974
    02975 Return Value:
    02976
    02977     STATUS_SUCCESS if no errors, otherwise the appropriate error.
    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 }

NTSTATUS PnPBiosGetBiosInfo | ( | OUT PVOID * | BiosInfo,
|  | OUT ULONG * | BiosInfoLength
| ) |

Definition at line 399 of file pnpmap.c.

References ASSERT, DebugPrint, DEFAULT_STRING_SIZE, ExAllocatePool, ExFreePool(), IopOpenRegistryKeyEx(), L, MULTIFUNCTION_KEY_NAME, NT_SUCCESS, NTSTATUS(), NULL, PagedPool, and RtlInitUnicodeString().

Referenced by PnPBiosMapper().

    00405                    :
    00406
    00407     This function retrieves the PnP BIOS info accumulated by NTDETECT.COM and
    00408     placed in the registry.
    00409
    00410 Arguments:
    00411
    00412     BiosInfo - Set to a dynamically allocated block of information retrieved
    00413         from the PnP BIOS by NTDETECT.  This block should be freed using
    00414         ExFreePool.  The contents of the block are the PnP BIOS
    00415         Installation Check Structure followed by the DevNode Structures reported
    00416         by the BIOS.  The detailed format is documented in the PnP BIOS spec.
    00417
    00418     BiosInfoLength - Length of the block whose address is stored in BiosInfo.
    00419
    00420
    00421 Return Value:
    00422
    00423     STATUS_SUCCESS if no errors, otherwise the appropriate error.
    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     // The PnP BIOS info is written to one of the subkeys under
    00442     // MULTIFUNCTION_KEY_NAME.  The appropriate key is determined by
    00443     // enumerating the subkeys and using the first one which has a value named
    00444     // "Identifier" that is "PNP BIOS".
    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     // Allocate memory for key names returned from ZwEnumerateKey and values
    00467     // returned from ZwQueryValueKey.
    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     // Enumerate each key under HKLM\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter
    00493     // to locate the one representing the PnP BIOS information.
    00494     //
    00495     for (index = 0; ; index++) {
    00496
    00497         status = ZwEnumerateKey( multifunctionKey,   // handle of key to enumerate
    00498                                  index,              // index of subkey to enumerate
    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         // We found a subkey, NUL terminate the name and open the subkey.
    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         // Now we need to check the Identifier value in the subkey to see if
    00542         // it is PNP BIOS.
    00543         //
    00544         RtlInitUnicodeString(&valueName, L"Identifier");
    00545
    00546         status = ZwQueryValueKey( biosKey,
    00547                                   &valueName,
    00548                                   KeyValuePartialInformation,
    00549                                   valueInfo,
    00550                                   valueInfoLength,
    00551                                   &returnedLength);
    00552
    00553
    00554         // lets see if its the PNP BIOS identifier
    00555         if (NT_SUCCESS(status)) {
    00556
    00557             if (wcscmp((PWSTR)valueInfo->Data, L"PNP BIOS") == 0) {
    00558
    00559                 //
    00560                 // We found the PnP BIOS subkey, retrieve the BIOS info which
    00561                 // is stored in the "Configuration Data" value.
    00562                 //
    00563                 // We'll start off with our default value buffer and increase
    00564                 // its size if necessary.
    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                         // The default buffer was too small, free it and reallocate
    00582                         // it to the required size.
    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                     // We now have the PnP BIOS data but it is buried inside
    00608                     // the resource structures.  Do some consistency checks and
    00609                     // then extract it into its own buffer.
    00610                     //
    00611
    00612                     ASSERT(valueInfo->Type == REG_FULL_RESOURCE_DESCRIPTOR);
    00613
    00614                     biosValue = (PCM_FULL_RESOURCE_DESCRIPTOR)valueInfo->Data;
    00615
    00616                     //
    00617                     // BUGBUG - The WMI folks added another list so we should
    00618                     // search for the PnPBIOS one, but for now the BIOS one is
    00619                     // always first.
    00620                     //
    00621                     //ASSERT(biosValue->PartialResourceList.Count == 1);
    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                 // We found the PnP BIOS entry, so close the key handle and
    00652                 // return.
    00653                 //
    00654
    00655                 ZwClose(biosKey);
    00656
    00657                 break;
    00658             }
    00659         }
    00660
    00661         //
    00662         // That wasn't it so close this handle and try the next subkey.
    00663         //
    00664         ZwClose(biosKey);
    00665     }
    00666
    00667     //
    00668     // Cleanup the dynamically allocated temporary buffers.
    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 }

PWCHAR PnPBiosGetDescription | ( | IN PBIOS_DEVNODE_INFO | DevNodeInfoEntry | ) |

Definition at line 2053 of file pnpmap.c.

References ClassDescriptionsList, CLASSLIST_COUNT, Count, DEFAULT_DEVICE_DESCRIPTION, _CLASSDATA::Description, and _CLASSDATA::Value.

Referenced by PnPBiosWriteInfo().

    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         // The last description entry is the default so there is no use
    02072         // comparing it, if we get that far just use it.
    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 }

BOOLEAN PnPBiosIgnoreNode | ( | PWCHAR | PnpID,
|  | PWCHAR | excludeNodes
| ) |

Definition at line 726 of file pnpmap.c.

References ASSERT, FALSE, and TRUE.

Referenced by PnPBiosWriteInfo().

    00730 {
    00731     BOOLEAN bRet=FALSE;
    00732     ULONG   keyLen;
    00733     PWCHAR  pTmp;
    00734
    00735     ASSERT (excludeNodes);
    00736
    00737     //
    00738     //excludeNodes is multi-sz, so walk through each one and check it.
    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 }

NTSTATUS PnPBiosIoResourceListToCmResourceList | ( | IN PIO_RESOURCE_REQUIREMENTS_LIST | IoResourceList,
|  | OUT PCM_RESOURCE_LIST * | CmResourceList,
|  | OUT ULONG * | CmResourceListSize
| ) |

Definition at line 890 of file pnpmap.c.

References ASSERT, DebugPrint, ExAllocatePool, NULL, and PagedPool.

Referenced by PnPBiosTranslateInfo().

    00897                    :
    00898
    00899     Converts an IO_RESOURCE_REQUIREMENTS_LIST into a CM_RESOURCE_LIST.  This
    00900     routine is used to convert the list of resources currently being used by a
    00901     device into a form suitable for writing to the BootConfig registry value.
    00902
    00903 Arguments:
    00904
    00905     IoResourceList - Pointer to the input list.
    00906
    00907     CmResourceList - Pointer to a PCM_RESOURCE_LIST which is set to the
    00908         dynamically allocated and filled in using the data from IoResourceList.
    00909
    00910     CmResourceListSize - Pointer to a variable which is set to the size in bytes
    00911         of the dynamically allocated *CmResourceList.
    00912
    00913 Return Value:
    00914
    00915     STATUS_SUCCESS if no errors, otherwise the appropriate error.
    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     // Since this routine is only used to translate the allocated resources
    00926     // returned by the PnP BIOS, we can assume that there is only 1 alternative
    00927     // list
    00928     //
    00929
    00930     ASSERT(IoResourceList->AlternativeLists == 1);
    00931
    00932     //
    00933     // Calculate the size of the translated list and allocate memory for it.
    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     // Copy the header info from the requirements list to the resource list.
    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     // Translate each resource descriptor, currently we only handle ports,
    00964     // memory, interrupts, and dma.  The current implementation of the routine
    00965     // which converts from ISA PnP Resource data to IO_RESOURCE_REQUIREMENTS
    00966     // won't generate any other descriptor types given the data returned from
    00967     // the BIOS.
    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             // DbgBreakPoint();
    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 }

NTSTATUS PnPBiosMapper | ( |  | ) |

Definition at line 3008 of file pnpmap.c.

References ExFreePool(), NT_SUCCESS, NTSTATUS(), PBIOS_DEVNODE_INFO, PnPBiosEliminateDupes(), PnPBiosFreeDevNodeInfo(), PnPBiosGetBiosInfo(), PnPBiosTranslateInfo(), and PnPBiosWriteInfo().

Referenced by IopInitializePlugPlayServices().

    03011                    :
    03012
    03013     Map the information provided from the PnP BIOS and stored in the registry by
    03014     NTDETECT into root enumerated devices.
    03015
    03016 Arguments:
    03017
    03018     NONE
    03019
    03020 Return Value:
    03021
    03022     STATUS_SUCCESS if no errors, otherwise the appropriate error.
    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 }

NTSTATUS PnPBiosMapper | ( | VOID |  | ) |

NTSTATUS PnPBiosTranslateInfo | ( | IN VOID * | BiosInfo,
|  | IN ULONG | BiosInfoLength,
|  | OUT PBIOS_DEVNODE_INFO * | DevNodeInfoList,
|  | OUT ULONG * | NumberNodes
| ) |

Definition at line 1126 of file pnpmap.c.

References ASSERT, _BIOS_DEVNODE_INFO::Attributes, _BIOS_DEVNODE_INFO::BasicConfig, _BIOS_DEVNODE_INFO::BootConfig, _BIOS_DEVNODE_INFO::CompatibleIDs, DebugPrint, ExAllocatePool, ExFreePool(), FALSE, _BIOS_DEVNODE_INFO::FirmwareDisabled, Handle, _BIOS_DEVNODE_INFO::Handle, NT_SUCCESS, NTSTATUS(), NULL, PagedPool, PBIOS_DEVNODE_INFO, PnPBiosCheckForHardwareDisabled(), PnPBiosExpandProductId(), PnPBiosExtractCompatibleIDs(), PnPBiosIoResourceListToCmResourceList(), PnPCheckFixedIoOverrideDecodes(), PpBiosResourcesToNtResources(), PPCONVERTFLAG_FORCE_FIXED_IO_16BIT_DECODE, PPCONVERTFLAG_SET_RESTART_LCPRI, PpFilterNtResource(), _BIOS_DEVNODE_INFO::ProductId, _BIOS_DEVNODE_INFO::Replaces, and _BIOS_DEVNODE_INFO::TypeCode.

Referenced by PnPBiosMapper().

    01134                    :
    01135
    01136     Translates the devnode info retrieved from the BIOS.
    01137
    01138 Arguments:
    01139
    01140     BiosInfo - The PnP BIOS Installation Check Structure followed by the
    01141         DevNode Structures reported by the BIOS.  The detailed format is
    01142         documented in the PnP BIOS spec.
    01143
    01144     BiosInfoLength - Length in bytes of the block whose address is stored in
    01145         BiosInfo.
    01146
    01147     DevNodeInfoList - Dynamically allocated array of BIOS_DEVNODE_INFO
    01148         structures, one for each device reported by the BIOS.  The information
    01149         supplied by the BIOS: device ID, type, current resources, and supported
    01150         configurations is converted into a more useful format.  For example the
    01151         current resource allocation is converted from ISA PnP descriptors into
    01152         an IO_RESOURCE_REQUIREMENTS_LIST and then into a CM_RESOURCE_LIST for
    01153         storing into the BootConfig registry value.
    01154
    01155     NumberNodes - Number of BIOS_DEVNODE_INFO elements pointed to by
    01156         DevNodeInfoList.
    01157
    01158 Return Value:
    01159
    01160     STATUS_SUCCESS if no errors, otherwise the appropriate error.
    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     // Make sure the data is at least large enough to hold the BIOS Installation
    01185     // Check structure and check that the PnP signature is correct.
    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     // First scan the data and count the devnodes to determine the size of our
    01209     // allocated data structures.
    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     // Allocate the list of translated devnodes.
    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     // Should we force all fixed IO decodes to 16bit?
    01245     //
    01246     if (PnPCheckFixedIoOverrideDecodes()) {
    01247
    01248         convertFlags |= PPCONVERTFLAG_FORCE_FIXED_IO_16BIT_DECODE;
    01249     }
    01250
    01251     //
    01252     // Now scan the data translating the info for each devnode into an entry in
    01253     // our devNodeInfo array.
    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         // We use the Product ID field as the DeviceID key name.  So we insert
    01276         // an initial asterisk so we don't have to copy and mangle it later.
    01277         //
    01278         devNodeInfo[nodeIndex].ProductId[0] = '*';
    01279
    01280         PnPBiosExpandProductId((PUCHAR)&devNodeHeader->ProductId, &devNodeInfo[nodeIndex].ProductId[1]);
    01281
    01282         devNodeInfo[nodeIndex].ProductId[9] = '\0';  // Extra NUL for REG_MULTI_SZ
    01283
    01284         //
    01285         // The handle is used as part of the Instance ID
    01286         devNodeInfo[nodeIndex].Handle = devNodeHeader->Node;
    01287
    01288         //
    01289         // The type code and attributes aren't currently used but are copied
    01290         // for completeness.
    01291         //
    01292         RtlCopyMemory( &devNodeInfo[nodeIndex].TypeCode,
    01293                        devNodeHeader->DeviceType,
    01294                        sizeof(devNodeInfo[nodeIndex].TypeCode) );
    01295
    01296         devNodeInfo[nodeIndex].Attributes = devNodeHeader->DeviceAttributes;
    01297
    01298         //
    01299         // Replaces will eventually be set to the path of the Firmware
    01300         // Enumerated devnode which duplicates this one (if a duplicate exists).
    01301         //
    01302         devNodeInfo[nodeIndex].Replaces = NULL;
    01303
    01304         //
    01305         // CompatibleIDs will be set to the list of compatible IDs.
    01306         //
    01307         devNodeInfo[nodeIndex].CompatibleIDs = NULL;
    01308
    01309         //
    01310         // Convert the allocated resources from ISA PnP resource descriptor
    01311         // format to an IO_RESOURCE_REQUIREMENTS_LIST.
    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,            /* BusNumber */
    01320                                                0,            /* SlotNumber */
    01321                                                &configPtr,   /* BiosData */
    01322                                                convertFlags, /* ConvertFlags */
    01323                                                &tempResReqList, /* ReturnedList */
    01324                                                &configListLength);    /* ReturnedLength */
    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                 // Now we need to convert from a IO_RESOURCE_REQUIREMENTS_LIST to a
    01339                 // CM_RESOURCE_LIST.
    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         // Convert the supported resource configurations from ISA PnP resource
    01361         // descriptor format to an IO_RESOURCE_REQUIREMENTS_LIST.
    01362         //
    01363         status = PpBiosResourcesToNtResources( 0,            /* BusNumber */
    01364                                                0,            /* SlotNumber */
    01365                                                &configPtr,   /* BiosData */
    01366                                                convertFlags | PPCONVERTFLAG_SET_RESTART_LCPRI, /* ConvertFlags */
    01367                                                &devNodeInfo[nodeIndex].BasicConfig, /* ReturnedList */
    01368                                                &devNodeInfo[nodeIndex].BasicConfigLength );  /* ReturnedLength */
    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         // Convert the list of compatible IDs if present
    01390         //
    01391
    01392         ASSERT(remainingNodeLength >= 0);
    01393
    01394         status = PnPBiosExtractCompatibleIDs( &configPtr,       // BiosData
    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 }

NTSTATUS PnPBiosWriteInfo | ( | IN PBIOS_DEVNODE_INFO | DevNodeInfoList,
|  | IN ULONG | NumberNodes
| ) |

Definition at line 2289 of file pnpmap.c.

References DebugPrint, DEFAULT_STRING_SIZE, ENUMROOT_KEY_NAME, EXCLUDE_DISABLED_COUNT, EXCLUDED_DEVICES_COUNT, ExcludedDevices, ExcludeIfDisabled, ExFreePool(), Handle, INSTANCE_ID_PREFIX, IopCreateRegistryKeyEx(), IopDeleteKeyRecursive(), IopOpenRegistryKeyEx(), L, NT_SUCCESS, NTSTATUS(), NULL, PnPBiosCheckForExclusion(), PnPBiosCopyDeviceParamKey(), PnPBiosCopyIoDecode(), PnPBiosGetDescription(), PnPBiosIgnoreNode(), PnPGetDevnodeExcludeList(), and RtlInitUnicodeString().

Referenced by PnPBiosMapper().

    02295                    :
    02296
    02297     Creates an entry under Enum\Root for each DevNodeInfoList element.  Also
    02298     removes any duplicate entries which were created by the Firmware Mapper.
    02299
    02300     Note: Currently entries for the Keyboard, Mouse, and PCI bus are ignored.
    02301
    02302 Arguments:
    02303
    02304     DevNodeInfoList - Array of BIOS_DEVNODE_INFO structures, one for each device
    02305         reported by the BIOS.
    02306
    02307     NumberNodes - Number of BIOS_DEVNODE_INFO elements pointed to by
    02308         DevNodeInfoList.
    02309
    02310 Return Value:
    02311
    02312     STATUS_SUCCESS if no errors, otherwise the appropriate error.
    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     // Reasons why a node might be excluded (i.e not enumerated)
    02361     // * included in ExcludedDevices array (non-conditional)
    02362     // * included in CCS\Control\BiosInfo\PnpBios\DisableNodes via biosinfo.inf
    02363     // * resources are disabled and device is included in the
    02364     //   ExcludeIfDisabled array
    02365
    02366     PnPGetDevnodeExcludeList (&excludeList);
    02367
    02368     for (nodeIndex = 0; nodeIndex < NumberNodes; nodeIndex++) {
    02369
    02370         //
    02371         // Check if this node is in the 'ignore on this machine' list.
    02372         //
    02373
    02374         if ( excludeList &&
    02375              PnPBiosIgnoreNode( &DevNodeInfoList[ nodeIndex ].ProductId[1],
    02376                                 (PWCHAR)((PUCHAR)excludeList+excludeList->DataOffset))) {
    02377             continue;
    02378         }
    02379
    02380         // Checking for nodes we always exclude
    02381         if ( PnPBiosCheckForExclusion( ExcludedDevices,
    02382                                        EXCLUDED_DEVICES_COUNT,
    02383                                        DevNodeInfoList[ nodeIndex ].ProductId,
    02384                                        DevNodeInfoList[ nodeIndex ].CompatibleIDs)) {
    02385             //
    02386             // If we are skipping the device, we need to first copy the decode
    02387             // info that the BIOS supplied to the ntdetected device's Boot
    02388             // Config which was generated by the FW mapper.
    02389             //
    02390             PnPBiosCopyIoDecode( enumRootKey, &DevNodeInfoList[ nodeIndex ] );
    02391
    02392             //
    02393             // Skip excluded devices, ie busses, mice and keyboards for now.
    02394             //
    02395
    02396             continue;
    02397         }
    02398
    02399         // Checking for nodes we exclude if disabled
    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             // If we are replacing a FW Mapper devnode we need to copy the
    02613             // Device Parameters subkey.
    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         // Now check if the entry just written duplicates one written by the
    02641         // Firmware Mapper.  If it does then remove the Firmware Mapper entry.
    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 }
    VOID

BOOLEAN PnPCheckFixedIoOverrideDecodes | ( | VOID |  | ) |

Definition at line 788 of file pnpmap.c.

References ASSERT, BIOSINFO_KEY_NAME, DECODEINFO_VALUE_NAME, ExFreePool(), FALSE, IopGetRegistryValue(), IopOpenRegistryKeyEx(), NT_SUCCESS, NTSTATUS(), NULL, and RtlInitUnicodeString().

Referenced by PnPBiosTranslateInfo().

    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         // Don't really need to complain, likely not there.
    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 }

VOID PnPGetDevnodeExcludeList | ( | OUT PKEY_VALUE_FULL_INFORMATION * | ExcludeList | ) |

Definition at line 759 of file pnpmap.c.

References BIOSINFO_KEY_NAME, BIOSINFO_VALUE_NAME, IopGetRegistryValue(), IopOpenRegistryKeyEx(), NT_SUCCESS, NTSTATUS(), NULL, RtlInitUnicodeString(), and VOID().

Referenced by PnPBiosWriteInfo().

    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         // Don't really need to complain, likely not there.
    00778         //
    00779         return;
    00780     }
    00781
    00782     (VOID) IopGetRegistryValue (biosKey,BIOSINFO_VALUE_NAME,ExcludeList);
    00783
    00784     ZwClose (biosKey);
    00785 }

VOID PpFilterNtResource | ( | IN PWCHAR | PnpDeviceName,
|  | PIO_RESOURCE_REQUIREMENTS_LIST | ResReqList
| ) |

Definition at line 3065 of file pnpmap.c.

References KeI386MachineType, L, and NULL.

Referenced by PnPBiosTranslateInfo().

    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             // account for any resource descriptors in addition to the single
    03111             // imbedded one I've already accounted for (if there aren't any,
    03112             // then I'll end up subtracting off the extra imbedded descriptor
    03113             // from the previous step)
    03114             //
    03115             //
    03116             // finally, account for any extra device specific data at the end of
    03117             // the last partial resource descriptor (if any)
    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                     // some bios asks for 1 too many io port for ide channel
    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 }

## Variable Documentation

CLASSDATA Class10Descriptions[]

Initial value:

     {
        { 0x0000, L"Generic dock" },
        { 0x8000, L"Other dock" },
    }

Definition at line 211 of file pnpmap.c.

CLASSDATA Class11Descriptions[]

Initial value:

     {
        { 0x0000, L"386" },
        { 0x0100, L"486" },
        { 0x0200, L"Pentium" },
        { 0x1000, L"Alpha" },
        { 0x4000, L"Co-processor" }
    }

Definition at line 216 of file pnpmap.c.

CLASSDATA Class12Descriptions[]

Initial value:

     {
        { 0x0000, L"Firewire" },
        { 0x0100, L"Access bus" },
        { 0x0200, L"SSA" },
        { 0x8000, L"Other serial bus" }
    }

Definition at line 224 of file pnpmap.c.

CLASSDATA Class1Descriptions[]

Initial value:

     {
        { 0x0000, L"SCSI Controller" },
        { 0x0100, L"IDE Controller" },
        { 0x0200, L"Floppy Controller" },
        { 0x0300, L"IPI Controller" },
        { 0x0400, L"RAID Controller" },
        { 0x8000, L"Other Mass Storage" }
    }

Definition at line 131 of file pnpmap.c.

CLASSDATA Class2Descriptions[]

Initial value:

     {
        { 0x0000, L"Ethernet" },
        { 0x0100, L"Token ring" },
        { 0x0200, L"FDDI" },
        { 0x0300, L"ATM" },
        { 0x8000, L"Other network" }
    }

Definition at line 140 of file pnpmap.c.

CLASSDATA Class3Descriptions[]

Initial value:

     {
        { 0x0000, L"VGA" },
        { 0x0001, L"SVGA" },
        { 0x0100, L"XGA" },
        { 0x8000, L"Other display" }
    }

Definition at line 148 of file pnpmap.c.

CLASSDATA Class4Descriptions[]

Initial value:

     {
        { 0x0000, L"Video device" },
        { 0x0100, L"Audio device" },
        { 0x8000, L"Other multimedia" }
    }

Definition at line 155 of file pnpmap.c.

CLASSDATA Class5Descriptions[]

Initial value:

     {
        { 0x0000, L"RAM memory" },
        { 0x0100, L"Flash memory" },
        { 0x8000, L"Other memory" }
    }

Definition at line 161 of file pnpmap.c.

CLASSDATA Class6Descriptions[]

Initial value:

     {
        { 0x0000, L"HOST / PCI" },
        { 0x0100, L"PCI / ISA" },
        { 0x0200, L"PCI / EISA" },
        { 0x0300, L"PCI / MCA" },
        { 0x0400, L"PCI / PCI" },
        { 0x0500, L"PCI / PCMCIA" },
        { 0x0600, L"NuBus" },
        { 0x0700, L"Cardbus" },
        { 0x8000, L"Other bridge" }
    }

Definition at line 167 of file pnpmap.c.

CLASSDATA Class7Descriptions[]

Initial value:

     {
        { 0x0000, L"XT Serial" },
        { 0x0001, L"16450" },
        { 0x0002, L"16550" },
        { 0x0100, L"Parallel output only" },
        { 0x0101, L"BiDi Parallel" },
        { 0x0102, L"ECP 1.x parallel" },
        { 0x8000, L"Other comm" }
    }

Definition at line 179 of file pnpmap.c.

CLASSDATA Class8Descriptions[]

Initial value:

     {
        { 0x0000, L"Generic 8259" },
        { 0x0001, L"ISA PIC" },
        { 0x0002, L"EISA PIC" },
        { 0x0100, L"Generic 8237" },
        { 0x0101, L"ISA DMA" },
        { 0x0102, L"EISA DMA" },
        { 0x0200, L"Generic 8254" },
        { 0x0201, L"ISA timer" },
        { 0x0202, L"EISA timer" },
        { 0x0300, L"Generic RTC" },
        { 0x0301, L"ISA RTC" },
        { 0x8000, L"Other system device" }
    }

Definition at line 189 of file pnpmap.c.

CLASSDATA Class9Descriptions[]

Initial value:

     {
        { 0x0000, L"Keyboard" },
        { 0x0100, L"Digitizer" },
        { 0x0200, L"Mouse" },
        { 0x8000, L"Other input" }
    }

Definition at line 204 of file pnpmap.c.

struct _CLASS_DESCRIPTIONS_LIST ClassDescriptionsList[]

| Referenced by PnPBiosGetDescription().

EXCLUDED_PNPNODE ExcludedDevices[]

Initial value:

      {
        EXCLUSION_ENTRY(L"*PNP03"),
        EXCLUSION_ENTRY(L"*PNP0A"),
        EXCLUSION_ENTRY(L"*PNP0E"),
        EXCLUSION_ENTRY(L"*PNP0F"),
        EXCLUSION_ENTRY(L"*nEC13"),
        EXCLUSION_ENTRY(L"*nEC1E"),
        EXCLUSION_ENTRY(L"*nEC1F"),
        EXCLUSION_ENTRY(L"*IBM3780"),
        EXCLUSION_ENTRY(L"*IBM3781")
    }

Definition at line 105 of file pnpmap.c.

Referenced by PnPBiosWriteInfo().

EXCLUDED_PNPNODE ExcludeIfDisabled[]

Initial value:

     {
        EXCLUSION_ENTRY(L"*PNP0C01"),
        EXCLUSION_ENTRY(L"*PNP0C02")
    }

Definition at line 119 of file pnpmap.c.

Referenced by PnPBiosWriteInfo().