📄 pcibus.c
字号:
//
// Adjust list lengths
//
if (VendorIDNum > MaxListNum) {
VendorIDNum = MaxListNum;
DEBUGMSG(ZONE_WARNING, (L"PCIBUS!RegMatchOne: Registry value list '%s\\%s' truncated to %d items.\r\n",
RegPath, PCIBUS_VENDORID_VALNAME, MaxListNum));
}
if (DeviceIDNum > MaxListNum) {
DeviceIDNum = MaxListNum;
DEBUGMSG(ZONE_WARNING, (L"PCIBUS!RegMatchOne: Registry value list '%s\\%s' truncated to %d items.\r\n",
RegPath, PCIBUS_DEVICEID_VALNAME, MaxListNum));
}
if (SubVendorIDNum > MaxListNum) {
SubVendorIDNum = MaxListNum;
DEBUGMSG(ZONE_WARNING, (L"PCIBUS!RegMatchOne: Registry value list '%s\\%s' truncated to %d items.\r\n",
RegPath, PCIBUS_SUBVENDORID_VALNAME, MaxListNum));
}
if (SubSystemIDNum > MaxListNum) {
SubSystemIDNum = MaxListNum;
DEBUGMSG(ZONE_WARNING, (L"PCIBUS!RegMatchOne: Registry value list '%s\\%s' truncated to %d items.\r\n",
RegPath, PCIBUS_SUBSYSTEMID_VALNAME, MaxListNum));
}
// Walk list pairs looking for match
for (i = 0; i < MaxListNum; i++) {
if (((USHORT)VendorIDs[i] == pInfo->Cfg->VendorID) && ((USHORT)DeviceIDs[i] == pInfo->Cfg->DeviceID)) {
if (!SubVendorIDNum) break;
if ((USHORT)SubVendorIDs[i] == pInfo->Cfg->u.type0.SubVendorID) {
if (!SubSystemIDNum) break;
if ((USHORT)SubSystemIDs[i] == pInfo->Cfg->u.type0.SubSystemID) break;
}
}
}
if (i == MaxListNum) {
// No match found
Match = 0;
goto RegMatchOne_Exit;
} else {
DEBUGMSG(ZONE_ENUM,
(TEXT("PCIBUS!RegMatchOne: Match for VendorID (0x%X), DeviceID (0x%X) found.\r\n"), VendorIDs[i], DeviceIDs[i]));
#ifdef DEBUG
if (SubVendorIDNum) {
if (SubSystemIDNum) {
DEBUGMSG(ZONE_ENUM, (L"PCIBUS!RegMatchOne: Match for SubVendorID (0x%X), SubSystemID (0x%X) found.\r\n",
SubVendorIDs[i], SubSystemIDs[i]));
} else {
DEBUGMSG(ZONE_ENUM, (L"PCIBUS!RegMatchOne: Match for SubVendorID (0x%X) found.\r\n",
SubVendorIDs[i]));
}
}
#endif
Match++;
}
//
// Examine RevisionID value, check against device's revision identification
//
RevisionIDNum = PCI_MAX_REG_LIST;
if (!RegGetList(DevKey, PCIBUS_REVISIONID_VALNAME, &RevisionIDNum, RevisionIDs) && (RevisionIDNum == PCI_MAX_REG_LIST)) {
DEBUGMSG(ZONE_WARNING, (L"PCIBUS!RegMatchOne: Registry value '%s\\%s' has more than %d items in multi_sz list. Ignoring the additional items.\r\n",
RegPath, PCIBUS_REVISIONID_VALNAME, PCI_MAX_REG_LIST));
}
if (!RevisionIDNum) {
// No VendorID value found
goto RegMatchOne_Exit;
}
// Scan list for match
for (i = 0; i < RevisionIDNum; i++) {
if ((UCHAR)RevisionIDs[i] == pInfo->Cfg->RevisionID) break;
}
if (i == RevisionIDNum) {
// No match found
Match = 0;
goto RegMatchOne_Exit;
} else {
DEBUGMSG(ZONE_ENUM, (L"PCIBUS!RegMatchOne: Match for RevisionID (0x%X) found.\r\n", RevisionIDs[i]));
Match++;
}
//
// Examine BusNumber value, check against device's bus number
//
ValLen = sizeof(Val32);
status = RegQueryValueEx(DevKey, PCIBUS_BUSNUMBER_VALNAME, NULL, &ValType, (PUCHAR)&Val32, &ValLen);
if (status != ERROR_SUCCESS) {
// No BusNumber value found
goto RegMatchOne_Exit;
}
if (Val32 != pInfo->Bus) {
// Bus number doesn't match
Match = 0;
goto RegMatchOne_Exit;
} else {
DEBUGMSG(ZONE_ENUM, (TEXT("PCIBUS!RegMatchOne Match for BusNumber (0x%X) found.\r\n"), Val32));
Match++;
}
//
// Examine DeviceNumber value, check against device's device number
//
ValLen = sizeof(Val32);
status = RegQueryValueEx(DevKey, PCIBUS_DEVICENUMBER_VALNAME, NULL, &ValType, (PUCHAR)&Val32, &ValLen);
if (status != ERROR_SUCCESS) {
// No DeviceNumber value found
goto RegMatchOne_Exit;
}
if (Val32 != pInfo->Device) {
// Device number doesn't match
Match = 0;
goto RegMatchOne_Exit;
} else {
DEBUGMSG(ZONE_ENUM, (TEXT("PCIBUS!RegMatchOne Match for DeviceNumber (0x%X) found.\r\n"), Val32));
Match++;
}
//
// Examine FunctionNumber value, check against device's function number
//
ValLen = sizeof(Val32);
status = RegQueryValueEx(DevKey, PCIBUS_FUNCTIONNUMBER_VALNAME, NULL, &ValType, (PUCHAR)&Val32, &ValLen);
if (status != ERROR_SUCCESS) {
// No FunctionNumber value found
goto RegMatchOne_Exit;
}
if (Val32 != pInfo->Function) {
// Function number doesn't match
Match = 0;
goto RegMatchOne_Exit;
} else {
DEBUGMSG(ZONE_ENUM, (TEXT("PCIBUS!RegMatchOne Match for FunctionNumber (0x%X) found.\r\n"), Val32));
Match++;
}
RegMatchOne_Exit:
RegCloseKey(DevKey);
return Match;
}
//
// Search registry for best device/registry match.
//
DWORD
RegMatch(
PPCI_DEV_INFO pInfo
)
{
HKEY Key;
DWORD DevLoadOrder;
DWORD LoadOrder;
DWORD NumDevKeys;
DWORD RegEnum;
DWORD status;
DWORD ValType;
DWORD ValLen;
DWORD Match = 0;
DWORD BestMatch = 0;
WCHAR DevName[DEVKEY_LEN];
WCHAR RegPath[DEVKEY_LEN];
DEBUGMSG(ZONE_FUNCTION, (L"PCIBUS!RegMatch+(%s, %d, %d, %d)\r\n", pInfo->RegPath, pInfo->Bus, pInfo->Device, pInfo->Function));
//
// Open key to be enumerated
//
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, pInfo->RegPath, 0, 0, &Key);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ENUM|ZONE_ERROR, (TEXT("PCIBUS!RegMatch RegOpenKeyEx(%s) returned %d.\r\n"), pInfo->RegPath, status));
return 0;
}
//
// Find out how many sub-keys there are
//
status = RegQueryInfoKey(
Key,
NULL, // class name buffer (lpszClass)
NULL, // ptr to length of class name buffer (lpcchClass)
NULL, // reserved
&NumDevKeys, // ptr to number of subkeys (lpcSubKeys)
&ValType, // ptr to longest subkey name length (lpcchMaxSubKeyLen)
&ValLen, // ptr to longest class string length (lpcchMaxClassLen)
&LoadOrder, // ptr to number of value entries (lpcValues)
&DevLoadOrder, // ptr to longest value name length (lpcchMaxValueNameLen)
&ValLen, // ptr to longest value data length (lpcbMaxValueData)
NULL, // ptr to security descriptor length
NULL); // ptr to last write time
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ENUM|ZONE_ERROR, (TEXT("PCIBUS!RegMatch RegQueryInfoKey(Class) returned %d.\r\n"), status));
RegCloseKey(Key);
return 0;
}
DEBUGMSG(ZONE_ENUM,
(TEXT("PCIBUS!RegMatch %d devices to search\r\n"), NumDevKeys));
//
// Base registry key
//
wcsncpy(RegPath, pInfo->RegPath, DEVKEY_LEN);
RegPath[DEVKEY_LEN-1]=0;
//
// Search for closest match
//
RegEnum = 0;
for (RegEnum = 0; RegEnum < NumDevKeys; RegEnum++) {
DEBUGMSG(ZONE_ENUM, (TEXT("PCIBUS!RegMatch RegEnum = %d\r\n"), RegEnum));
// Get sub-key according to RegEnum
ValLen = sizeof(DevName) / sizeof(WCHAR);
status = RegEnumKeyEx(Key, RegEnum, DevName, &ValLen, NULL, NULL, NULL, NULL);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ENUM, (TEXT("PCIBUS!RegMatch RegEnumKeyEx(%d) returned %d\r\n"), RegEnum, status));
break;
}
Match = RegMatchOne(pInfo, Key, DevName);
if (Match > BestMatch) {
if (wcslen(DevName) + wcslen(pInfo->RegPath) + 1 < DEVKEY_LEN) { // We can handle this registry.
BestMatch = Match;
// There is at least a partial match, construct path to device key
wcscpy(RegPath, pInfo->RegPath);
wcscat(RegPath, TEXT("\\"));
wcscat(RegPath, DevName);
RegPath[DEVKEY_LEN-1]=0;
}
}
}
RegCloseKey(Key);
wcsncpy(pInfo->RegPath, RegPath,DEVKEY_LEN);
pInfo->RegPath[DEVKEY_LEN-1] = 0;
return BestMatch;
}
//
// Open Non-Exist Instance Registry Key
//
#define NUMBER_OF_APPENDIX_BYTES 2
#define MAX_APPENDIX_NUMBER 100
static
HKEY OpenNonExistInstanceKey(LPCWSTR lpInstancePreFix)
{
HKEY hReturn=NULL;
WCHAR IndexStr[DEVKEY_LEN];
DWORD dwLen;
DWORD iIndex;
DEBUGMSG(ZONE_FUNCTION, (L"PCIBUS!OpenNonExistInstanceKey+(%s)\r\n", lpInstancePreFix ));
wcsncpy(IndexStr,lpInstancePreFix,DEVKEY_LEN-1);
IndexStr[DEVKEY_LEN-1] = 0;
dwLen=wcslen(IndexStr);
if (dwLen>= DEVKEY_LEN -NUMBER_OF_APPENDIX_BYTES-1) {
DEBUGMSG(ZONE_ENUM|ZONE_ERROR, (L"PCIBUS!OpenNonExistInstanceKey Error: instance key prefix '%s' len=%d exceeds %d character limit\r\n", IndexStr,dwLen, DEVKEY_LEN- 3));
return NULL;
}
// Assign an index, starting with index 1
for (iIndex=1;iIndex<MAX_APPENDIX_NUMBER;iIndex++) {
DWORD Disposition =0 ;
LONG status;
wsprintf(IndexStr+dwLen, L"%d", iIndex);
// Create/open Instance key
status = RegCreateKeyEx(HKEY_LOCAL_MACHINE, IndexStr, 0, NULL, 0, 0, NULL, &hReturn, &Disposition);
if (status==ERROR_SUCCESS) {
if (Disposition == REG_OPENED_EXISTING_KEY) { // If found it is existing, continue search.
DEBUGMSG(ZONE_ENUM|ZONE_ERROR, (L"PCIBUS::OpenNonExistInstanceKey(%s) returned open exist.continue search\r\n",
IndexStr));
RegCloseKey(hReturn);
hReturn = NULL;
}
else {
DEBUGMSG(ZONE_FUNCTION, (L"PCIBUS!OpenNonExistInstanceKey-(%s) returns key \r\n",IndexStr));
// Write new InstanceIndex value.. This instance value is need for DDKReg_GetPciInfo
status = RegSetValueEx(hReturn, PCIBUS_INSTANCEINDEX_VALNAME, 0, PCIBUS_INSTANCEINDEX_VALTYPE, (PUCHAR)&iIndex, sizeof(iIndex));
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ENUM|ZONE_ERROR, (L"PCIBUS!RegCopy RegSetValueEx(%s\\%s) returned %d.\r\n",
IndexStr, PCIBUS_INSTANCEINDEX_VALNAME, status));
RegCloseKey(hReturn);
hReturn = NULL;
}
return hReturn;
}
}
else {
DEBUGMSG(ZONE_ENUM|ZONE_ERROR, (L"PCIBUS::OpenNonExistInstanceKey(%s) returned fails\r\n", IndexStr));
break;
}
}
return NULL;
}
//
// Copy registry information for device from template key to instance key. Write device-specific information
// to instance key.
//
static BOOL
RegCopy(
PPCI_DEV_INFO pInfo
)
{
HKEY TKey;
HKEY IKey;
DWORD status;
WCHAR InstKeyPath[DEVKEY_LEN];
PWCHAR KeyPtr;
PWCHAR TmpKeyPtr;
INTERFACE_TYPE IfcType = PCIBus;
DWORD Irq, Pin, SysIntr;
BOOL RetVal = TRUE;
DEBUGMSG(ZONE_FUNCTION, (L"PCIBUS!RegCopy+(%s, %d, %d, %d)\r\n", pInfo->RegPath, pInfo->Bus, pInfo->Device, pInfo->Function));
//
// Open Template key
//
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, pInfo->RegPath, 0, 0, &TKey);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ENUM|ZONE_ERROR, (L"PCIBUS!RegCopy RegOpenKeyEx(%s) returned %d.\r\n", pInfo->RegPath, status));
return FALSE;
}
//
// Construct Instance key name
//
// Find last occurence of "Template" in key
KeyPtr = NULL;
TmpKeyPtr = wcsstr(pInfo->RegPath, PCIBUS_TEMPLATE_KEYNAME);
while (TmpKeyPtr != NULL) {
KeyPtr = TmpKeyPtr;
TmpKeyPtr += wcslen(PCIBUS_TEMPLATE_KEYNAME);
TmpKeyPtr = wcsstr(TmpKeyPtr, PCIBUS_TEMPLATE_KEYNAME);
};
if (KeyPtr == NULL) {
// Template key didn't have the word Template in it, report error
DEBUGMSG(ZONE_ENUM|ZONE_ERROR, (L"PCIBUS!RegCopy Key %s doesn't contain %s.\r\n",
pInfo->RegPath, PCIBUS_TEMPLATE_KEYNAME));
RetVal = FALSE;
goto rc_Close_TKey;
}
StringCchCopy(InstKeyPath, DEVKEY_LEN,pInfo->RegPath);
{
DWORD dwIndex = (KeyPtr - pInfo->RegPath);
if (dwIndex < DEVKEY_LEN)
InstKeyPath[dwIndex] = (WCHAR)'\0';
}
wcscat(InstKeyPath, PCIBUS_INSTANCE_KEYNAME);
wcscat(InstKeyPath, (PWCHAR)(KeyPtr + wcslen(PCIBUS_TEMPLATE_KEYNAME)));
IKey = OpenNonExistInstanceKey(InstKeyPath);
if (IKey ==NULL ) {
DEBUGMSG(ZONE_ENUM|ZONE_ERROR, (L"PCIBUS!RegCopy RegCreateKeyEx(%s) returned %d.\r\n",
InstKeyPath, status));
RetVal = FALSE;
goto rc_Close_TKey;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -