⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcibus.c

📁 WINCE5.0操作系统下的PCI总线驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
    //
    // 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 + -