📄 pcibus.c
字号:
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[DEVNAME_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);
//
// 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) {
BestMatch = Match;
// There is at least a partial match, construct path to device key
wcscpy(RegPath, pInfo->RegPath);
wcscat(RegPath, TEXT("\\"));
wcscat(RegPath, DevName);
}
}
RegCloseKey(Key);
wcscpy(pInfo->RegPath, RegPath);
return BestMatch;
}
//
// 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;
DWORD ValType;
DWORD ValLen;
DWORD Index;
DWORD Disposition;
WCHAR InstKeyPath[DEVKEY_LEN];
WCHAR IndexStr[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;
}
// If InstanceIndex value exists, read it
ValLen = sizeof(Index);
status = RegQueryValueEx(TKey, PCIBUS_INSTANCEINDEX_VALNAME, NULL, &ValType, (PUCHAR)&Index, &ValLen);
if (status != ERROR_SUCCESS) {
// No InstanceIndex found, start with 1
Index = 1;
} else {
// InstanceIndex value found, increment
Index++;
}
// Write new InstanceIndex value
status = RegSetValueEx(TKey, PCIBUS_INSTANCEINDEX_VALNAME, 0, PCIBUS_INSTANCEINDEX_VALTYPE, (PUCHAR)&Index, sizeof(Index));
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ENUM|ZONE_ERROR, (L"PCIBUS!RegCopy RegSetValueEx(%s\\%s) returned %d.\r\n",
pInfo->RegPath, PCIBUS_INSTANCEINDEX_VALNAME, status));
RetVal = FALSE;
goto rc_Close_TKey;
}
//
// 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;
}
wcscpy(InstKeyPath, pInfo->RegPath);
*(InstKeyPath + (KeyPtr - pInfo->RegPath)) = (WCHAR)'\0';
wcscat(InstKeyPath, PCIBUS_INSTANCE_KEYNAME);
wcscat(InstKeyPath, (PWCHAR)(KeyPtr + wcslen(PCIBUS_TEMPLATE_KEYNAME)));
wsprintf(IndexStr, L"%d", Index);
if (wcslen(InstKeyPath) + wcslen(IndexStr) >= DEVKEY_LEN) {
DEBUGMSG(ZONE_ENUM|ZONE_ERROR, (L"PCIBUS!RegCopy Error: Created instance key '%s%s' exceeds %d character limit\r\n", InstKeyPath, IndexStr, DEVKEY_LEN - 1));
RetVal = FALSE;
goto rc_Close_TKey;
}
wcscat(InstKeyPath, IndexStr);
DEBUGMSG(ZONE_ENUM, (L"PCIbus!RegCopy Instance Key = '%s'\r\n", InstKeyPath));
// Create/open Instance key
status = RegCreateKeyEx(HKEY_LOCAL_MACHINE, InstKeyPath, 0, NULL, 0, 0, NULL, &IKey, &Disposition);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ENUM|ZONE_ERROR, (L"PCIBUS!RegCopy RegCreateKeyEx(%s) returned %d.\r\n",
InstKeyPath, status));
RetVal = FALSE;
goto rc_Close_TKey;
}
//
// Copy Template values to Instance values, without overwriting them
//
if (RegCopyKey(TKey, IKey) == FALSE) {
RetVal = FALSE;
goto rc_Close_IKey;
}
// Set device-specific indentifier information
if (RegSetVal(IKey, PCIBUS_CLASS_VALNAME, PCIBUS_CLASS_VALTYPE, (PBYTE)&pInfo->Cfg->BaseClass, sizeof(pInfo->Cfg->BaseClass)) == FALSE) {
RetVal = FALSE;
goto rc_Close_IKey;
}
if (RegSetVal(IKey, PCIBUS_SUBCLASS_VALNAME, PCIBUS_SUBCLASS_VALTYPE, (PBYTE)&pInfo->Cfg->SubClass, sizeof(pInfo->Cfg->SubClass)) == FALSE) {
RetVal = FALSE;
goto rc_Close_IKey;
}
if (RegSetVal(IKey, PCIBUS_PROGIF_VALNAME, PCIBUS_PROGIF_VALTYPE, (PBYTE)&pInfo->Cfg->ProgIf, sizeof(pInfo->Cfg->ProgIf)) == FALSE) {
RetVal = FALSE;
goto rc_Close_IKey;
}
if (RegSetVal(IKey, PCIBUS_VENDORID_VALNAME, PCIBUS_VENDORID_VALTYPE, (PBYTE)&pInfo->Cfg->VendorID, sizeof(pInfo->Cfg->VendorID)) == FALSE) {
RetVal = FALSE;
goto rc_Close_IKey;
}
if (RegSetVal(IKey, PCIBUS_DEVICEID_VALNAME, PCIBUS_DEVICEID_VALTYPE, (PBYTE)&pInfo->Cfg->DeviceID, sizeof(pInfo->Cfg->DeviceID)) == FALSE) {
RetVal = FALSE;
goto rc_Close_IKey;
}
if (RegSetVal(IKey, PCIBUS_REVISIONID_VALNAME, PCIBUS_REVISIONID_VALTYPE, (PBYTE)&pInfo->Cfg->RevisionID, sizeof(pInfo->Cfg->RevisionID)) == FALSE) {
RetVal = FALSE;
goto rc_Close_IKey;
}
switch (pInfo->Cfg->HeaderType & ~PCI_MULTIFUNCTION) {
case PCI_DEVICE_TYPE:
if (RegSetVal(IKey, PCIBUS_SUBVENDORID_VALNAME, PCIBUS_SUBVENDORID_VALTYPE, (PBYTE)&pInfo->Cfg->u.type0.SubVendorID, sizeof(pInfo->Cfg->u.type0.SubVendorID)) == FALSE) {
RetVal = FALSE;
goto rc_Close_IKey;
}
if (RegSetVal(IKey, PCIBUS_SUBSYSTEMID_VALNAME, PCIBUS_SUBSYSTEMID_VALTYPE, (PBYTE)&pInfo->Cfg->u.type0.SubSystemID, sizeof(pInfo->Cfg->u.type0.SubSystemID)) == FALSE) {
RetVal = FALSE;
goto rc_Close_IKey;
}
break;
case PCI_BRIDGE_TYPE:
break;
case PCI_CARDBUS_TYPE:
if (RegSetVal(IKey, PCIBUS_SUBVENDORID_VALNAME, PCIBUS_SUBVENDORID_VALTYPE, (PBYTE)&pInfo->Cfg->u.type2.SubVendorID, sizeof(pInfo->Cfg->u.type2.SubVendorID)) == FALSE) {
RetVal = FALSE;
goto rc_Close_IKey;
}
if (RegSetVal(IKey, PCIBUS_SUBSYSTEMID_VALNAME, PCIBUS_SUBSYSTEMID_VALTYPE, (PBYTE)&pInfo->Cfg->u.type2.SubSystemID, sizeof(pInfo->Cfg->u.type2.SubSystemID)) == FALSE) {
RetVal = FALSE;
goto rc_Close_IKey;
}
break;
default:
break;
}
// Set device location information: interface type (PCI) and bus, device and function numbers
if (RegSetVal(IKey, PCIBUS_IFCTYPE_VALNAME, PCIBUS_IFCTYPE_VALTYPE, (PBYTE)&IfcType, sizeof(IfcType)) == FALSE) {
RetVal = FALSE;
goto rc_Close_IKey;
}
if (RegSetVal(IKey, PCIBUS_BUSNUMBER_VALNAME, PCIBUS_BUSNUMBER_VALTYPE, (PBYTE)&pInfo->Bus, sizeof(pInfo->Bus)) == FALSE) {
RetVal = FALSE;
goto rc_Close_IKey;
}
if (RegSetVal(IKey, PCIBUS_DEVICENUMBER_VALNAME, PCIBUS_DEVICENUMBER_VALTYPE, (PBYTE)&pInfo->Device, sizeof(pInfo->Device)) == FALSE) {
RetVal = FALSE;
goto rc_Close_IKey;
}
if (RegSetVal(IKey, PCIBUS_FUNCTIONNUMBER_VALNAME, PCIBUS_FUNCTIONNUMBER_VALTYPE, (PBYTE)&pInfo->Function, sizeof(pInfo->Function)) == FALSE) {
RetVal = FALSE;
goto rc_Close_IKey;
}
// Set Memory Base and Length values
if (!RegSetList(IKey, PCIBUS_MEMBASE_VALNAME, pInfo->MemBase.Num, pInfo->MemBase.Reg)) {
RetVal = FALSE;
goto rc_Close_IKey;
}
if (!RegSetList(IKey, PCIBUS_MEMLEN_VALNAME, pInfo->MemLen.Num, pInfo->MemLen.Reg)) {
RetVal = FALSE;
goto rc_Close_IKey;
}
// Set I/O Base and Length values
if (!RegSetList(IKey, PCIBUS_IOBASE_VALNAME, pInfo->IoBase.Num, pInfo->IoBase.Reg)) {
RetVal = FALSE;
goto rc_Close_IKey;
}
if (!RegSetList(IKey, PCIBUS_IOLEN_VALNAME, pInfo->IoLen.Num, pInfo->IoLen.Reg)) {
RetVal = FALSE;
goto rc_Close_IKey;
}
// Get IRQ and interrupt pin
switch (pInfo->Cfg->HeaderType & ~PCI_MULTIFUNCTION) {
case PCI_DEVICE_TYPE: // Devices
Irq = pInfo->Cfg->u.type0.InterruptLine;
Pin = pInfo->Cfg->u.type0.InterruptPin;
break;
case PCI_BRIDGE_TYPE: // PCI-PCI bridge
Irq = pInfo->Cfg->u.type1.InterruptLine;
Pin = pInfo->Cfg->u.type1.InterruptPin;
break;
case PCI_CARDBUS_TYPE: // PCI-Cardbus bridge
Irq = pInfo->Cfg->u.type2.InterruptLine;
Pin = pInfo->Cfg->u.type2.InterruptPin;
break;
default:
DEBUGMSG(ZONE_ERROR, (L"PCIbus!RegCopy ERROR: invalid header type %d detected.\r\n", pInfo->Cfg->HeaderType));
RetVal = FALSE;
goto rc_Close_IKey;
}
// If Interrupt Pin register is 0, or if there is an invalid Interrupt Line value, there is no Irq
if (!((Pin == 0) || (Irq == 0) || (Irq == 0xFF))) {
// Write Irq value
if (RegSetVal(IKey, PCIBUS_IRQ_VALNAME, PCIBUS_IRQ_VALTYPE, (PBYTE)&Irq, sizeof(Irq)) == FALSE) {
RetVal = FALSE;
goto rc_Close_IKey;
}
// If driver not to be loaded (or will be unloaded immediately), don't request SysIntr
if (!(pInfo->DevFlags & (DEVFLAGS_NOLOAD | DEVFLAGS_UNLOAD))) {
// Request new SysIntr from Irq value
if (RequestSysIntr(Irq, &SysIntr) == FALSE) {
RetVal = FALSE;
goto rc_Close_IKey;
}
// Write SysIntr value
if (RegSetVal(IKey, PCIBUS_SYSINTR_VALNAME, PCIBUS_SYSINTR_VALTYPE, (PBYTE)&SysIntr, sizeof(SysIntr)) == FALSE) {
RetVal = FALSE;
goto rc_Close_IKey;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -