📄 pcibus.c
字号:
//
// 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;
}
// 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;
}
}
rc_Close_IKey:
RegCloseKey(IKey);
rc_Close_TKey:
RegCloseKey(TKey);
return RetVal;
}
#pragma prefast(disable: 53, "Fails alarm Reg Copy does not need null-terminate for data.")
//
// Copy contents of one registry key to another.
//
static BOOL
RegCopyKey(
HKEY TKey,
HKEY IKey
)
{
HKEY TSubKey;
HKEY ISubKey;
DWORD NumSubKeys;
DWORD MaxSubKeyLen;
DWORD MaxClassLen;
DWORD NumValues;
DWORD MaxValueNameLen;
DWORD MaxValueLen;
DWORD status;
DWORD Key;
DWORD Val;
WCHAR ValName[PCI_MAX_REG_NAME];
BYTE ValData[PCI_MAX_REG_DATA];
DWORD ValLen;
DWORD ValType;
DWORD Disposition;
BOOL RetVal = TRUE;
// Get info on Template Key
status = RegQueryInfoKey(
TKey,
NULL, // class name buffer (lpszClass)
NULL, // ptr to length of class name buffer (lpcchClass)
NULL, // reserved
&NumSubKeys, // ptr to number of sub-keys (lpcSubKeys)
&MaxSubKeyLen, // ptr to longest subkey name length (lpcchMaxSubKeyLen)
&MaxClassLen, // ptr to longest class string length (lpcchMaxClassLen)
&NumValues, // ptr to number of value entries (lpcValues)
&MaxValueNameLen, // ptr to longest value name length (lpcchMaxValueNameLen)
&MaxValueLen, // 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!RegCopyKey RegQueryInfoKey returned %d.\r\n"),
status));
return FALSE;
}
// Recurse for each sub-key
for (Key = 0; Key < NumSubKeys; Key++) {
// Get TKey sub-key according to Key
ValLen = sizeof(ValName) / sizeof(WCHAR);
status = RegEnumKeyEx(
TKey,
Key,
ValName,
&ValLen,
NULL,
NULL,
NULL,
NULL);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ENUM,
(TEXT("PCIBUS!RegCopyKey RegEnumKeyEx(%d) returned %d\r\n"),
ValName, status));
break;
}
// Open sub-key under TKey
status = RegOpenKeyEx(
TKey,
ValName,
0,
0,
&TSubKey);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ENUM|ZONE_ERROR,
(TEXT("PCIBUS!RegCopyKey RegOpenKeyEx(%s) returned %d\r\n"),
ValName, status));
continue;
}
// Open/create corresponding sub-key under IKey
status = RegCreateKeyEx(
IKey,
ValName,
0,
NULL,
0,
0,
NULL,
&ISubKey,
&Disposition);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ENUM|ZONE_ERROR,
(TEXT("PCIBUS!RegCopyKey RegCreateKeyEx(%s) returned %d\r\n"),
ValName, status));
RegCloseKey(TSubKey);
continue;
}
RegCopyKey(TSubKey, ISubKey);
RegCloseKey(TSubKey);
RegCloseKey(ISubKey);
}
// Copy values
for (Val = 0; Val < NumValues; Val++) {
// Get value names under TKey according to Val
ValLen = sizeof(ValName) / sizeof(WCHAR);
status = RegEnumValue(
TKey,
Val,
ValName,
&ValLen,
NULL,
NULL,
NULL,
NULL);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ENUM,
(TEXT("PCIBUS!RegCopyKey RegEnumValue(%d) returned %d\r\n"),
Val, status));
break;
}
// If corresponding value under IKey already exists, skip
status = RegQueryValueEx(
IKey,
ValName,
NULL,
NULL,
NULL,
NULL);
if (status == ERROR_SUCCESS) {
// Value exists, don't overwrite
continue;
}
// Read value from TKey
ValLen = sizeof(ValData);
status = RegQueryValueEx(
TKey,
ValName,
NULL,
&ValType,
ValData,
&ValLen);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ENUM,
(TEXT("PCIBUS!RegCopyKey RegQueryValueEx(%s) returned %d\r\n"),
ValName, status));
break;
}
// Write value to IKey
status = RegSetValueEx(
IKey,
ValName,
0,
ValType,
ValData,
ValLen);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ENUM|ZONE_ERROR,
(TEXT("PCIBUS!RegCopyKey RegSetValueEx(%s) returned %d.\r\n"),
ValName, status));
break;
}
}
return RetVal;
}
#pragma prefast(pop)
//
// Set value in registry.
//
static BOOL
RegSetVal(
HKEY Key,
LPCWSTR ValName,
DWORD ValType,
const PBYTE ValData,
DWORD ValLen
)
{
DWORD Status;
DWORD dwData = 0;
// If Type is DWORD, pad ValData and write as DWORD
if (ValType == REG_DWORD) {
if (ValLen > sizeof(DWORD)) {
// ValLen too big to fit into DWORD
DEBUGMSG(ZONE_ENUM|ZONE_ERROR, (L"PCIBUS!RegSetVal ERROR: ValLen (%d) > %d when ValType == REG_DWORD\r\n", ValLen, sizeof(DWORD)));
return FALSE;
}
memcpy(&dwData, ValData, ValLen);
ValLen = sizeof(dwData);
Status = RegSetValueEx(Key, ValName, 0, ValType, (PBYTE)&dwData, ValLen);
} else {
Status = RegSetValueEx(Key, ValName, 0, ValType, ValData, ValLen);
}
if (Status !=
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -