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

📄 pcmcia.c

📁 windows ce 3.00 嵌入式操作系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
}   // RunDetectors


//
// Function to start a driver in the devload manner or to LoadDriver(devdll) 
// and GetProcAddress(entry) and call an entrypoint.
//
// Return FALSE only if the driver key does not exist in the registry.
//
BOOL
LoadPCCardDriver(
    CARD_SOCKET_HANDLE hSock,
    LPTSTR PnpId,
    LPTSTR DevName
    )
{
    HKEY hDevKey;
    PFN_DEV_ENTRY pfnEntry;
    TCHAR DevDll[DEVDLL_LEN];
    TCHAR DevEntry[DEVENTRY_LEN];
    TCHAR RegPath[REG_PATH_LEN];
    TCHAR PnpMFCId[REG_PATH_LEN];
    DWORD status;
    DWORD ValLen;
    DWORD ValType;
    HMODULE hDevDll;

    //
    // Format the registry path for this device.
    //
    _tcscpy(RegPath, s_PcmciaKey);
    _tcscat(RegPath, TEXT("\\"));
    if (DevName == NULL) {
        _tcscat(RegPath, PnpId);
        //
        // Additional functions will have a "-n" appended to their PnpId where
        // 'n' is the function number. This is so we can have a PnpId registry
        // entry for each function.
        //
        if (hSock.uFunction > 0) {
            ValLen = _tcslen(RegPath);
            RegPath[ValLen]   = (TCHAR) '-';
            RegPath[ValLen+1] = (TCHAR) '0' + (TCHAR) hSock.uFunction;
            RegPath[ValLen+2] = (TCHAR) 0;
        }
    } else {
        _tcscat(RegPath, DevName);
    }

    //
    // If a driver exists for this PNP id, then use it.
    //
    status = RegOpenKeyEx(
                HKEY_LOCAL_MACHINE,
                RegPath,
                0,
                0,
                &hDevKey);
    if (status != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
            (TEXT("DEVICE!LoadPCCardDriver: RegOpenKeyEx(%s) returned %d\r\n"),
            RegPath, status));
        return FALSE;
    }

    //
    // Get the entrypoint and dll names.  If the entrypoint name does not exist
    // then call StartDriver which will call RegisterDevice on the driver's 
    // behalf.
    //
    ValLen = sizeof(DevEntry);
    status = RegQueryValueEx(
                hDevKey,
                DEVLOAD_ENTRYPOINT_VALNAME,
                NULL,
                &ValType,
                (PUCHAR)DevEntry,
                &ValLen);
    if (status != ERROR_SUCCESS) {
        _tcscpy(PnpMFCId, PnpId);
        if (hSock.uFunction > 0) {
            ValLen = _tcslen(PnpMFCId);
            if (ValLen > 5 && PnpMFCId[ValLen-5] == '-') {
                _tcsncpy(PnpMFCId + ValLen, PnpMFCId + ValLen - 5, 5);
                _tcsncpy(PnpMFCId + ValLen - 5, L"-DEV", 4);
                PnpMFCId[ValLen-1] = (TCHAR) '0' + (TCHAR) hSock.uFunction;
                PnpMFCId[ValLen+5] = (TCHAR) 0;
            } else {
                _tcscat(PnpMFCId, L"-DEV");
                PnpMFCId[ValLen+4] = (TCHAR) '0' + (TCHAR) hSock.uFunction;
                PnpMFCId[ValLen+5] = (TCHAR) 0;
            }
        }
    
        RegCloseKey(hDevKey);
        StartDriver(RegPath, PnpMFCId, MAX_LOAD_ORDER+1, hSock);
        return TRUE;
    }

    ValLen = sizeof(DevDll);
    status = RegQueryValueEx(
                hDevKey,
                s_DllName_ValName,
                NULL,
                &ValType,
                (PUCHAR)DevDll,
                &ValLen);
    RegCloseKey(hDevKey);
    if (status != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
            (TEXT("DEVICE!LoadPCCardDriver: RegQueryValueEx(DllName) returned %d\r\n"),
            status));
        return TRUE;
    }

    //
    // Load the dll, get the entrypoint's procaddr and call it.
    //
    hDevDll = LoadDriver(DevDll);
    if (hDevDll == NULL) {
        DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
            (TEXT("DEVICE!LoadPCCardDriver: LoadDriver(%s) failed %d\r\n"),
            DevDll, GetLastError()));
        return TRUE;
    }

    pfnEntry = (PFN_DEV_ENTRY) GetProcAddress(hDevDll, DevEntry);
    if (pfnEntry == NULL) {
        DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
            (TEXT("DEVICE!LoadPCCardDriver: GetProcAddr(%s, %s) failed %d\r\n"),
            DevDll, DevEntry, GetLastError()));
        FreeLibrary(hDevDll);
        return TRUE;
    }

    //
    // It is the device driver's responsibility to call RegisterDevice.
    // The following FreeLibrary will not unload the DLL if it has registered.
    //
    DEBUGMSG(ZONE_PCMCIA,
        (TEXT("DEVICE!LoadPCCardDriver: Calling %s:%s. socket handle = %d %d\r\n"),
        DevDll, DevEntry, hSock.uSocket, hSock.uFunction));
    (pfnEntry)(RegPath);
    FreeLibrary(hDevDll);
    return TRUE;
}   // LoadPCCardDriver


//
// Function to search the registry under HLM\Drivers\PCMCIA for a device driver
// for a newly inserted card.  If there is no driver associated with the card's
// PNP id, then look at the card's CIS to figure out what generic device driver
// to use.  If the generic driver doesn't recognize it, then see if one of the
// installable detection modules recognizes it.
//
VOID
FindPCCardDriver(
    CARD_SOCKET_HANDLE hSock,
    LPTSTR PnpId
    )
{
    DWORD status;
    UCHAR buf[sizeof(CARD_DATA_PARMS) + 256];
    PCARD_TUPLE_PARMS pParms;
    PCARD_DATA_PARMS  pTuple;
    PUCHAR pData;
    LPTSTR DevKeyName;
    UCHAR DevType;

    //
    // If there is a driver for this particular card, then try it first
    //
    if (LoadPCCardDriver(hSock, PnpId, NULL)) {
        return;
    }

    DevKeyName = NULL;
    DevType = PCCARD_TYPE_UNKNOWN;  // 0xff

    //
    // Find this card's device type to provide a hint to the detection modules
    // (Find the second one if possible to skip a potential CISTPL_FUNCID in a
    // MFCs global tuple chain)
    //
    pParms = (PCARD_TUPLE_PARMS)buf;
    pParms->hSocket = hSock;
    pParms->uDesiredTuple = CISTPL_FUNCID; // contains the device type.
    pParms->fAttributes = 0;
    status = pfnGetFirstTuple(pParms);
    if (status == CERR_SUCCESS) {
        if (hSock.uFunction > 0) {
            status = pfnGetNextTuple(pParms);
            if (status != CERR_SUCCESS) {
                status = pfnGetFirstTuple(pParms);
            }
        }
        if (status == CERR_SUCCESS) {
            pTuple = (PCARD_DATA_PARMS)buf;
            pTuple->uBufLen = sizeof(buf) - sizeof(CARD_DATA_PARMS);
            pTuple->uTupleOffset = 0;
            status = pfnGetTupleData(pTuple);
            if (status == CERR_SUCCESS) {
                pData = buf + sizeof(CARD_DATA_PARMS);
                DevType = *pData;
            } else {
                DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
                    (TEXT("DEVICE!FindPCCardDriver: CardGetTupleData returned %d\r\n"), status));
            }
        }
    } else {
        DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
            (TEXT("DEVICE!FindPCCardDriver: CardGetFirstTuple returned %d\r\n"), status));
    }

    DevKeyName = RunDetectors(hSock, DevType, (LPTSTR)buf, sizeof(buf)/sizeof(TCHAR));

    if (DevKeyName) {    
        if (LoadPCCardDriver(hSock, PnpId, DevKeyName)) {
            return;
        }
    } else {
        QueryDriverName(PnpId, DevType, hSock); // unrecognized card inserted,
                                                // ask user for driver name.
    }
    return;
}   // FindPCCardDriver


//
// Function to search through HLM\Drivers\Active for a matching CARD_SOCKET_HANDLE
// Return code is the device's handle.  A handle of 0 indicates that no match was
// found.  The active device number is copied to ActiveNum on success.
// 
DWORD
FindActiveBySocket(
    CARD_SOCKET_HANDLE hSock,
    LPTSTR RegPath
    )
{
    DWORD Handle;
    DWORD RegEnum;
    DWORD status;
    DWORD ValLen;
    DWORD ValType;
    LPTSTR RegPathPtr;
    HKEY DevKey;
    HKEY ActiveKey;
    TCHAR DevNum[DEVNAME_LEN];
    CARD_SOCKET_HANDLE hRegSock;

    _tcscpy(RegPath, s_ActiveKey);
    status = RegOpenKeyEx(
                    HKEY_LOCAL_MACHINE,
                    RegPath,
                    0,
                    0,
                    &ActiveKey);
    if (status != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,
            (TEXT("DEVICE!FindActiveBySocket: RegOpenKeyEx(%s) returned %d\r\n"),
            RegPath, status));
        return 0;
    }

    RegEnum = 0;
    while (1) {
        ValLen = sizeof(DevNum)/sizeof(TCHAR);
        status = RegEnumKeyEx(
                    ActiveKey,
                    RegEnum,
                    DevNum,
                    &ValLen,
                    NULL,
                    NULL,
                    NULL,
                    NULL);

        if (status != ERROR_SUCCESS) {
            DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,
                (TEXT("DEVICE!FindActiveBySocket: RegEnumKeyEx() returned %d\r\n"),
                status));
            RegCloseKey(ActiveKey);
            return 0;
        }

        status = RegOpenKeyEx(
                    ActiveKey,
                    DevNum,
                    0,
                    0,
                    &DevKey);
        if (status != ERROR_SUCCESS) {
            DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,
                (TEXT("DEVICE!FindActiveBySocket: RegOpenKeyEx(%s) returned %d\r\n"),
                DevNum, status));
            goto fabs_next;
        }

        //
        // See if the socket value matches
        //
        ValLen = sizeof(hRegSock);
        status = RegQueryValueEx(
                    DevKey,
                    DEVLOAD_SOCKET_VALNAME,
                    NULL,
                    &ValType,
                    (PUCHAR)&hRegSock,
                    &ValLen);
        if (status != ERROR_SUCCESS) {
            DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,
                (TEXT("DEVICE!FindActiveBySocket: RegQueryValueEx(%s\\Socket) returned %d\r\n"),
                DevNum, status));
            goto fabs_next;
        }

        //
        // Is this the one the caller wants?
        //
        if (!((hRegSock.uSocket == hSock.uSocket) &&
            (hRegSock.uFunction == hSock.uFunction))) {
            goto fabs_next;         // No.
        }

        ValLen = sizeof(Handle);
        status = RegQueryValueEx(
                    DevKey,
                    DEVLOAD_HANDLE_VALNAME,
                    NULL,
                    &ValType,
                    (PUCHAR)&Handle,
                    &ValLen);
        if (status != ERROR_SUCCESS) {
            DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,
                (TEXT("DEVICE!FindActiveBySocket: RegQueryValueEx(%s\\Handle) returned %d\r\n"),
                DevNum, status));
            //
            // We found the device, but can't get its handle.
            //
            Handle = 0;
        } else {
            //
            // Format the registry path
            //
            RegPathPtr = RegPath + _tcslen(RegPath);
            RegPathPtr[0] = (TCHAR)'\\';
            RegPathPtr++;
            _tcscpy(RegPathPtr, DevNum);
        }

        RegCloseKey(ActiveKey);
        RegCloseKey(DevKey);
        return Handle;

fabs_next:
        RegCloseKey(DevKey);
        RegEnum++;
    }   // while

}   // FindActiveBySocket


//
// Function to delete all the values under an active key that we were unable
// to delete (most likely because someone else has it opened).
//
VOID
DeleteActiveValues(
    LPTSTR ActivePath
    )
{
    HKEY hActiveKey;
    DWORD status;
    
    //
    // Open active key
    //
    status = RegOpenKeyEx(
                HKEY_LOCAL_MACHINE,
                ActivePath,
                0,
                0,
                &hActiveKey);
    if (status != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,
           (TEXT("DEVICE!DeleteActiveValues: RegOpenKeyEx(%s) returned %d\r\n"),
           ActivePath, status));
        return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -