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_PNPNODEPEXCLUDED_PNPNODE
typedef _CLASSDATA CLASSDATA
typedef _BIOS_DEVNODE_INFO BIOS_DEVNODE_INFO
typedef _BIOS_DEVNODE_INFOPBIOS_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, sizeof(a) / sizeof(a[0]) }
 

Definition at line 231 of file pnpmap.c.

#define DebugPrint  ) 
 

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, 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().


Generated on Sat May 15 19:45:14 2004 for test by doxygen 1.3.7