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

📄 pcibus.c

📁 WINCE5.0操作系统下的PCI总线驱动
💻 C
📖 第 1 页 / 共 5 页
字号:

        //
        // 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 + -