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

📄 load.c

📁 YLP270的Windows CE5.0 bsp源码。
💻 C
📖 第 1 页 / 共 2 页
字号:
            //
            if (hSock.uFunction > 0) {
                ValLen = _tcslen(RegPath);
                RegPath[ValLen]   = (TCHAR) '-';
                RegPath[ValLen+1] = (TCHAR) '0' + (TCHAR) hSock.uFunction;
                RegPath[ValLen+2] = (TCHAR) 0;
            }
        } else {
            ValLen = _tcslen(RegPath);
            _tcsncpy(RegPath + ValLen, DevName, DEVKEY_LEN - ValLen);
            RegPath[DEVKEY_LEN - 1] = 0;
        }
    }

    //
    // 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_INIT|ZONE_ERROR,
            (TEXT("PCMCIA:LoadPCCardDriver: RegOpenKeyEx(%s) returned %d\r\n"),
            RegPath, status));
        return FALSE;
    }

    // Handle the interrupt pending bit is bad case
    if (pLsock != NULL) {
        ValLen = sizeof(intrpend);
        status = RegQueryValueEx(
                    hDevKey,
                    DEVLOAD_INTRPEND_VALNAME,
                    NULL,
                    &ValType,
                    (PUCHAR)&intrpend,
                    &ValLen);
        if (status == ERROR_SUCCESS && ValType == DEVLOAD_INTRPEND_VALTYPE && intrpend != 0)
            pLsock->fFlags |= LOG_SOCK_FLAG_NO_INTR_ACK;
    }
    
    //
    // 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) {
        _tcsncpy(PnpMFCId, PnpId, DEVKEY_LEN - 1);
        PnpMFCId[DEVKEY_LEN - 1] = 0;
        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 {
                if (ValLen >= DEVKEY_LEN - 5)
                    ValLen = DEVKEY_LEN - 6;
                _tcscpy(PnpMFCId + ValLen, L"-DEV");
                PnpMFCId[ValLen+4] = (TCHAR) '0' + (TCHAR) hSock.uFunction;
                PnpMFCId[ValLen+5] = (TCHAR) 0;
            }
        }

        RegCloseKey(hDevKey);

        {
            REGINI reg[4];
            DWORD  dwBusType=PCMCIABus;
            TCHAR tBuf[] = DEVLOAD_SOCKET_VALNAME TEXT("\0") DEVLOAD_PNPID_VALNAME TEXT("\0") DEVLOAD_REPARMS_VALNAME TEXT("\0");

            reg[0].lpszVal = DEVLOAD_SOCKET_VALNAME;
            reg[0].dwType = DEVLOAD_SOCKET_VALTYPE;
            reg[0].pData = (PBYTE) &hSock;
            reg[0].dwLen = sizeof(hSock);
            reg[1].lpszVal = DEVLOAD_PNPID_VALNAME;
            reg[1].dwType = DEVLOAD_PNPID_VALTYPE;
            reg[1].pData = (PBYTE) PnpMFCId;
            reg[1].dwLen = (_tcslen(PnpMFCId) + 1) * sizeof(TCHAR);
            reg[2].lpszVal = DEVLOAD_REPARMS_VALNAME;
            reg[2].dwType = DEVLOAD_REPARMS_VALTYPE;
            reg[2].pData = (PBYTE) tBuf;
            reg[2].dwLen = sizeof(tBuf);
            reg[3].lpszVal = DEVLOAD_INTERFACETYPE_VALNAME;
            reg[3].dwType  = DEVLOAD_INTERFACETYPE_VALTYPE;
            reg[3].pData = (PBYTE) &dwBusType;
            reg[3].dwLen = sizeof(dwBusType);

            if (pLsock) {
                DEBUGCHK(RegPath != NULL);
                pLsock->hDriver = ActivateDeviceEx(RegPath, &reg[0], sizeof(reg)/sizeof(reg[0]), NULL);
                if(pLsock->hDriver == NULL) {
                    DEBUGMSG(ZONE_INIT || ZONE_ERROR, 
                        (_T("PCMCIA:LoadPCCardDriver: ActivateDeviceEx('%s') failed %d\r\n"),
                        RegPath, GetLastError()));
                    return FALSE;
                }
            }
        }

        return TRUE;
    }

    ValLen = sizeof(DevDll);
    status = RegQueryValueEx(
                hDevKey,
                DEVLOAD_DLLNAME_VALNAME,
                NULL,
                &ValType,
                (PUCHAR)DevDll,
                &ValLen);
    RegCloseKey(hDevKey);
    if (status != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR,
            (TEXT("PCMCIA: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_INIT|ZONE_ERROR,
            (TEXT("PCMCIA:LoadPCCardDriver: LoadDriver(%s) failed %d\r\n"),
            DevDll, GetLastError()));
        return TRUE;
    }

    pfnEntry = (PFN_DEV_ENTRY) GetProcAddress(hDevDll, DevEntry);
    if (pfnEntry == NULL) {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR,
            (TEXT("PCMCIA: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_INIT,
        (TEXT("PCMCIA:LoadPCCardDriver: Calling %s:%s. socket handle = %d %d\r\n"),
        DevDll, DevEntry, hSock.uSocket, hSock.uFunction));
    try {
        (pfnEntry)(RegPath);
    } except (EXCEPTION_EXECUTE_HANDLER) {
        RETAILMSG(1, (TEXT("!PCMCIA:LoadPCCardDriver: entrypoint (%s:%s) faulted!\n"),
                      DevDll, DevEntry));
    }
    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.
//
static VOID
FindPCCardDriver(
    CARD_SOCKET_HANDLE hSock,
    LPTSTR PnpId
    )
{
    PPHYS_SOCKET pPsock = &v_Sockets[hSock.uSocket];
    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, 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 = CardGetFirstTuple(pParms);
    if (status == CERR_SUCCESS) {
        if (hSock.uFunction > 0) {
            status = CardGetNextTuple(pParms);
            if (status != CERR_SUCCESS) {
                status = CardGetFirstTuple(pParms);
            }
        }
        if (status == CERR_SUCCESS) {
            pTuple = (PCARD_DATA_PARMS)buf;
            pTuple->uBufLen = sizeof(buf) - sizeof(CARD_DATA_PARMS);
            pTuple->uTupleOffset = 0;
            status = CardGetTupleData(pTuple);
            if (status == CERR_SUCCESS) {
                pData = buf + sizeof(CARD_DATA_PARMS);
                DevType = *pData;
            } else {
                DEBUGMSG(ZONE_INIT|ZONE_ERROR,
                    (TEXT("PCMCIA:FindPCCardDriver: CardGetTupleData returned %d\r\n"), status));
            }
        }
    } else {
        DEBUGMSG(ZONE_INIT|ZONE_ERROR,
            (TEXT("PCMCIA:FindPCCardDriver: CardGetFirstTuple returned %d\r\n"), status));
    }

    DevKeyName = RunDetectors(hSock, DevType, (LPTSTR)buf, sizeof(buf)/sizeof(TCHAR));
    EnterCriticalSection(&v_DetectCrit);
    if (pPsock->DetectState >= DETECT_REDO) {
        LeaveCriticalSection(&v_DetectCrit);
        return;
    }
    LeaveCriticalSection(&v_DetectCrit);

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

static DWORD
FindDriversThread (
    LPVOID arg
    )
{
    PPHYS_SOCKET pPsock = (PPHYS_SOCKET) arg;
    CARD_SOCKET_HANDLE hSock = pPsock->pLsock->hSock;
    PLOG_SOCKET pLsock;
    UINT i;

FDT_begin:
    for (i = 0; i < pPsock->cFunctions; i++) {
        hSock.uFunction = i;
        pLsock = I_FindSocket(hSock);
        if (pLsock == NULL) {
            DEBUGMSG(ZONE_ERROR, (TEXT("PCMCIA:FindDriversThread no logical socket for F%d\n"), i));
        } else {
            FindPCCardDriver(pLsock->hSock, pPsock->pDevId);
        }

        EnterCriticalSection(&v_DetectCrit);
        if (pPsock->DetectState == DETECT_REDO) {
            pPsock->DetectState = DETECT_PROG;
            LeaveCriticalSection(&v_DetectCrit);
            goto FDT_begin;
        } else if (pPsock->DetectState == DETECT_QUIT) {
            pPsock->DetectState = DETECT_NONE;
            LeaveCriticalSection(&v_DetectCrit);
            goto FDT_end;
        }
        LeaveCriticalSection(&v_DetectCrit);
    }

    EnterCriticalSection(&v_DetectCrit);
    if (pPsock->DetectState == DETECT_REDO) {
        pPsock->DetectState = DETECT_PROG;
        LeaveCriticalSection(&v_DetectCrit);
        goto FDT_begin;
    } else {
        pPsock->DetectState = DETECT_NONE;
    }
    LeaveCriticalSection(&v_DetectCrit);

FDT_end:
    pPsock->fFlags &= ~PHYS_SOCK_FLAG_ACTIVE;

    //
    // If no clients are using this card, shut down power to
    // the PCMCIA adapter, until a configuration is requested.
    //
    PcmciaPowerOff(
        hSock.uSocket,
        FALSE,
        (CARD_CLIENT_HANDLE)CARDSERV_CLIENT_HANDLE);

    // Invalidate the thread handle so that the callback thread knows we're done;
    // this is important for when the card is removed.
    pPsock->hLoad = NULL;

    return 0;
}

VOID
CardServLoadDriver (
    UINT8 uSocket
    )
{
    PPHYS_SOCKET pPsock = &v_Sockets[uSocket];
    PDCARD_SOCKET_STATE State;
    HANDLE hThd;
    CARD_SOCKET_HANDLE hSock;
    int i;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("PCMCIA:CardServLoadDriver on socket %d\n"), uSocket));
    DEBUGCHK(pPsock->hLoad == NULL);
    DEBUGCHK(pPsock->pDevId == NULL);

    //
    // If the socket is a low power socket, then skip
    // the battery check
    //
    if (PDCardGetSocket(uSocket, &State) != CERR_SUCCESS) {
        return;
    }

    if (!(State.fSocketCaps & SOCK_CAP_LOW_VOLT)) {
        //
        // If the device is on battery power, query the
        // user before applying power to the PC card
        //
        PcmciaPowerOff(uSocket, TRUE, (CARD_CLIENT_HANDLE)CARDSERV_CLIENT_HANDLE);
        if (!BatteryCheck(uSocket)) {
            // choose not to power the socket - remove insertion callbacks
            // Kill resuming flag (CE_CARD_INSERTION would normally do this for us)
            v_Sockets[uSocket].fFlags &= ~PHYS_SOCK_FLAG_RESUMING;
            return;
        }
    }
    v_Sockets[uSocket].fFlags |= PHYS_SOCK_FLAG_ACTIVE;
    PcmciaPowerOn(uSocket);

    //
    // Compute card's device ID
    //
    i = CreateFunctions(uSocket);
    if (i == 0) {
        DEBUGMSG(ZONE_ERROR, (TEXT("PCMCIA:CardServLoadDriver no functions found\n")));
        return;
    }
    
    if (CreateDeviceID(uSocket, FALSE) != CERR_SUCCESS) {
        DEBUGMSG(ZONE_ERROR, (TEXT("PCMCIA:CardServLoadDriver cannot create deviceID\n")));
        return;
    }
    DEBUGCHK(pPsock->pDevId != NULL);

    hSock.uSocket = uSocket;
    hSock.uFunction = 0;
    CallbackAll(CE_CARD_INSERTION, CE_CARD_INSERTION, NULL, hSock, CALLBACK_FLAG_ALL_FUNCTIONS);

    EnterCriticalSection(&v_DetectCrit);
    if (pPsock->DetectState != DETECT_NONE) {
        pPsock->DetectState = DETECT_REDO;
        LeaveCriticalSection(&v_DetectCrit);
        return;
    }
    pPsock->DetectState = DETECT_PROG;
    LeaveCriticalSection(&v_DetectCrit);
    hThd = CreateThread(0, 0, FindDriversThread, (LPVOID) pPsock, 0, (LPDWORD) &pPsock->hLoad);
    if (!hThd) {
        DEBUGMSG(ZONE_WARNING, (TEXT("PCMCIA:CardServLoadDriver cannot create a driver loading thread\n")));
        return;
    }
    CeSetThreadPriority(hThd, g_LoaderPrio);
    CloseHandle(hThd);

    // Driver will eventually get loaded and register itself.
    // Now we can proceed with queueing callbacks.
    return;
}

VOID
CardServFreeDriver (
    UINT8 uSocket
    )
{
    PLOG_SOCKET pLsock;
    HANDLE hDev;

    DEBUGMSG(ZONE_CALLBACK|ZONE_FUNCTION, (TEXT("PCMCIA:CardServFreeDriver sock %d\n"), uSocket));
    
    // If hLoad is invalid, then the load thread is done
    // and the wait will fail immediately; otherwise, the wait will
    // block until the load thread completes. The load thread
    // invalidates hLoad just before it exits.
    WaitForSingleObject(v_Sockets[uSocket].hLoad, INFINITE);
    DEBUGCHK(v_Sockets[uSocket].hLoad == NULL);

    EnterCriticalSection(&v_SocketCrit);
    pLsock = v_Sockets[uSocket].pLsock;
    while (pLsock) {
        hDev = pLsock->hDriver;
        if (hDev) {
            pLsock->hDriver = NULL;
            LeaveCriticalSection(&v_SocketCrit);
            DEBUGMSG(ZONE_CALLBACK, (TEXT("PCMCIA deactivating sock %d func %d\n"),
                                       pLsock->hSock.uSocket, pLsock->hSock.uFunction));
            DeactivateDevice(hDev);
            EnterCriticalSection(&v_SocketCrit);
            pLsock = v_Sockets[uSocket].pLsock;
        } else
            pLsock = pLsock->Next;
    }
    LeaveCriticalSection(&v_SocketCrit);
}

⌨️ 快捷键说明

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