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

📄 ufnmdd.cpp

📁 freescale i.mx31 BSP CE5.0全部源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
         !pPddInterfaceInfo->pfnSetAddress || 
         !pPddInterfaceInfo->pfnIsEndpointHalted || 
         !pPddInterfaceInfo->pfnInitiateRemoteWakeup || 
         !pPddInterfaceInfo->pfnPowerDown || 
         !pPddInterfaceInfo->pfnPowerUp || 
         !pPddInterfaceInfo->pfnIOControl ) {
        fRet = FALSE;
    }

    return fRet;
}


// Initialize the MDD, PDD, and client.
extern "C"
DWORD
UFN_Init(
    LPCTSTR pszContext
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();
    
    DWORD dwErr;
    PUFN_MDD_CONTEXT pContext = NULL;
    CReg regActive;

    UFN_MDD_INTERFACE_INFO MddInterfaceInfo = {
        UFN_PDD_INTERFACE_VERSION, &UfnMdd_Notify
    };

    DEBUGCHK(pszContext);

    if (!regActive.Open(HKEY_LOCAL_MACHINE, pszContext)) {
        DEBUGMSG(ZONE_ERROR, (_T("%s Failed to open active key\r\n"), pszFname));
        goto EXIT;
    }

    // Allocate our context
    pContext = (PUFN_MDD_CONTEXT) LocalAlloc(LPTR, sizeof(*pContext));
    if (pContext == NULL) {
        DEBUGMSG(ZONE_ERROR, (_T("%s LocalAlloc failed. Error: %d\r\n"), pszFname, 
            GetLastError()));
        goto EXIT;
    }
    pContext->dwSig = UFN_MDD_SIG;
    pContext->Speed = BS_UNKNOWN_SPEED;

    pContext->bEnterTestMode = FALSE;
    pContext->iTestMode = 0;

    InitializeCriticalSection(&pContext->csMddAccess);
    InitializeCriticalSection(&pContext->csBusIoctlAccess);

    pContext->hevReadyForNotifications = CreateEvent(NULL, TRUE, TRUE, NULL);
    if (pContext->hevReadyForNotifications == NULL) {
        dwErr = GetLastError();
        DEBUGMSG(ZONE_ERROR, (_T("%s Failed to create event. Error = %d\r\n"),
            pszFname, dwErr));
        goto EXIT;
    }

    // Open the device key
    pContext->hKey = OpenDeviceKey(pszContext);
    if (pContext->hKey == NULL) {
        dwErr = GetLastError();
        DEBUGMSG(ZONE_ERROR, (_T("%s Failed to open device key \"%s\". Error = %d\r\n"),
            pszFname, pszContext, dwErr));
        goto EXIT;
    }

    pContext->pUfnBus = new CUfnBus(pszContext, pContext);
    if ( (pContext->pUfnBus == NULL) || (!pContext->pUfnBus->Init()) ) {
        goto EXIT;
    }

    // Initialize the PDD
    dwErr = UfnPdd_Init(pszContext, pContext, &MddInterfaceInfo, &pContext->PddInfo);
    if (dwErr != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_ERROR, (_T("%s PDD initialization failed.\r\n"), pszFname));
        goto EXIT;
    }

    if (IsPddInterfaceInfoValid(&pContext->PddInfo)) { 
        DEBUGMSG(ZONE_INIT, (_T("%s PDD has %u endpoints\r\n"), pszFname, 
            pContext->PddInfo.dwEndpointCount));

        DEBUGMSG(ZONE_INIT, (_T("%s PDD supports speeds 0x%x\r\n"), pszFname, 
            pContext->PddInfo.dwCapabilities));
        
        pContext->fPddInitialized = TRUE;
    }
    else {
        RETAILMSG(1, (_T("%s PDD interface info is invalid.\r\n"), 
            pszFname));
        // Try to call PDD's deinit.
        if (pContext->PddInfo.pfnDeinit) {
            pContext->PddInfo.pfnDeinit(pContext->PddInfo.pvPddContext);
        }
    }

EXIT:
    if (pContext && !pContext->fPddInitialized) {
        // Failed to initialize. Free resources.
        FreeContext(pContext);
        pContext = NULL;
    }
    
    FUNCTION_LEAVE_MSG();
    
    return (DWORD) pContext;
}


extern "C" 
BOOL
UFN_PreDeinit (
    DWORD dwContext
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();
    
    DWORD dwRet = ERROR_SUCCESS;
    PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) dwContext;
    
    VERIFY_PCONTEXT();
    
    ValidateContext(pContext);

    // No threads to release
    
EXIT:
    FUNCTION_LEAVE_MSG();
    
    return (dwRet == ERROR_SUCCESS);
}


// Deinitialize the client, PDD, and MDD.
extern "C" 
BOOL
UFN_Deinit (
    DWORD dwContext
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DWORD dwRet = ERROR_SUCCESS;
    PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) dwContext;
    
    VERIFY_PCONTEXT();
    
    ValidateContext(pContext);
    FreeContext(pContext);
    
EXIT:
    FUNCTION_LEAVE_MSG();
    
    return (dwRet == ERROR_SUCCESS);
}


static
VOID
ValidateBusContext(
    PUFN_MDD_BUS_OPEN_CONTEXT pBusContext
    )
{
    PREFAST_DEBUGCHK(pBusContext);
    DEBUGCHK(pBusContext->dwSig == UFN_MDD_BUS_SIG);
    DEBUGCHK(pBusContext->pMddContext);
    ValidateContext(pBusContext->pMddContext);
    DEBUGCHK(pBusContext->hkClients);
}


extern "C" 
DWORD
UFN_Open (
    DWORD dwContext,
    DWORD dwAccessMode, 
    DWORD dwShareMode
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DWORD dwRet;
    PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) dwContext;
    DEBUGCHK(IS_VALID_MDD_CONTEXT(pContext));

    if (dwAccessMode & DEVACCESS_BUSNAMESPACE) {
        // This is a bus access
        PUFN_MDD_BUS_OPEN_CONTEXT pBusContext = (PUFN_MDD_BUS_OPEN_CONTEXT) 
            LocalAlloc(LPTR, sizeof(UFN_MDD_BUS_OPEN_CONTEXT));
        if (pBusContext) {
            pBusContext->dwSig = UFN_MDD_BUS_SIG;
            pBusContext->pMddContext = pContext;

            DWORD dwErr = CUfnBus::OpenFunctionKey(&pBusContext->hkClients);
            if (dwErr != ERROR_SUCCESS) {
                LocalFree(pBusContext);
                pBusContext = NULL;
            }
        }

        if (pBusContext) {
            ValidateBusContext(pBusContext);
        }

        dwRet = (DWORD) pBusContext;
    }
    else {
        // Standard access
        dwRet = (DWORD) pContext;
    }
    
    FUNCTION_LEAVE_MSG();
    
    return dwRet;
}


extern "C" 
BOOL
UFN_PreClose (
    DWORD dwContext
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();
    
    DWORD dwRet = ERROR_SUCCESS;
    PUFN_MDD_CONTEXT_SIG pMddContextSig = (PUFN_MDD_CONTEXT_SIG) dwContext;
    
    if (pMddContextSig == NULL) {
        dwRet = ERROR_INVALID_HANDLE;
    }
    else if (pMddContextSig->dwSig == UFN_MDD_BUS_SIG) {
        PUFN_MDD_BUS_OPEN_CONTEXT pBusContext = 
            (PUFN_MDD_BUS_OPEN_CONTEXT) pMddContextSig;
        ValidateBusContext(pBusContext);
    }
    else if (pMddContextSig->dwSig == UFN_MDD_SIG) {
        PUFN_MDD_CONTEXT pMddContext = 
            (PUFN_MDD_CONTEXT) pMddContextSig;
        ValidateContext(pMddContext);
    }
    
    // No threads to release.

    if (dwRet != ERROR_SUCCESS) {
        SetLastError(dwRet);
    }

    FUNCTION_LEAVE_MSG();
    
    return (dwRet == ERROR_SUCCESS);
}


extern "C" 
BOOL
UFN_Close (
    DWORD dwContext
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DWORD dwRet = ERROR_SUCCESS;
    PUFN_MDD_CONTEXT_SIG pMddContextSig = (PUFN_MDD_CONTEXT_SIG) dwContext;

    if (pMddContextSig == NULL) {
        dwRet = ERROR_INVALID_HANDLE;
    }
    else if (pMddContextSig->dwSig == UFN_MDD_BUS_SIG) {
        PUFN_MDD_BUS_OPEN_CONTEXT pBusContext = 
            (PUFN_MDD_BUS_OPEN_CONTEXT) pMddContextSig;
        ValidateBusContext(pBusContext);
        RegCloseKey(pBusContext->hkClients);
        LocalFree(pBusContext);
    }
    else if (pMddContextSig->dwSig == UFN_MDD_SIG) {
        PUFN_MDD_CONTEXT pMddContext = 
            (PUFN_MDD_CONTEXT) pMddContextSig;
        ValidateContext(pMddContext);
    }
    else {
        DEBUGCHK(FALSE);
        dwRet = ERROR_INVALID_HANDLE;
    }
    
    if (dwRet != ERROR_SUCCESS) {
        SetLastError(dwRet);
    }
    
    FUNCTION_LEAVE_MSG();

    return (dwRet == ERROR_SUCCESS);
}


// Pass power down request to the PDD.
extern "C"
void
UFN_PowerDown(
    DWORD dwContext
    )
{
    PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) dwContext;
    
    DEBUGCHK(IS_VALID_MDD_CONTEXT(pContext));

    if (!pContext->pUfnBus->IsChildPowerManaged()) {
        pContext->pUfnBus->SetChildDevicePowerState(D4);
    }
    
    pContext->PddInfo.pfnPowerDown(pContext->PddInfo.pvPddContext);
}


// Pass power up request to the PDD.
extern "C"
void
UFN_PowerUp(
    DWORD dwContext
    )
{
    PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) dwContext;
    
    DEBUGCHK(IS_VALID_MDD_CONTEXT(pContext));
    pContext->PddInfo.pfnPowerUp(pContext->PddInfo.pvPddContext);

    if (!pContext->pUfnBus->IsChildPowerManaged()) {
        pContext->pUfnBus->SetChildDevicePowerState(D0);
    }
}


DWORD
GetClientFunctions(
    PUFN_FUNCTIONS  pUfnFunctions
    )
{
    SETFNAME();
    PREFAST_DEBUGCHK(pUfnFunctions);
    DWORD dwRet = ERROR_SUCCESS;
    
    pUfnFunctions->lpRegisterDevice = &UfnMdd_RegisterDevice;
    pUfnFunctions->lpStart = &UfnMdd_Start;
    pUfnFunctions->lpStop = &UfnMdd_Stop;
    pUfnFunctions->lpDeregisterDevice = &UfnMdd_DeregisterDevice;
    pUfnFunctions->lpOpenPipe = &UfnMdd_OpenPipe;
    pUfnFunctions->lpClosePipe = &UfnMdd_ClosePipe;
    pUfnFunctions->lpIssueTransfer = &UfnMdd_IssueTransfer;
    pUfnFunctions->lpGetTransferStatus = &UfnMdd_GetTransferStatus;
    pUfnFunctions->lpAbortTransfer = &UfnMdd_AbortTransfer;
    pUfnFunctions->lpCloseTransfer = &UfnMdd_CloseTransfer;
    pUfnFunctions->lpStallPipe = &UfnMdd_StallPipe;
    pUfnFunctions->lpClearPipeStall = &UfnMdd_ClearPipeStall;
    pUfnFunctions->lpInitiateRemoteWakeup = &UfnMdd_InitiateRemoteWakeup;
    pUfnFunctions->lpSendControlStatusHandshake = &UfnMdd_SendControlStatusHandshake;

    return dwRet;
}


// IOCTLs with a Function value between 0x200 and 0x2FF are reserved 
// for the OEM and the PDD.
extern "C" 
BOOL
UFN_IOControl (
    DWORD  dwContext,
    DWORD  dwCode,
    PBYTE  pbInBuf,
    DWORD  cbInBuf,
    PBYTE  pbOutBuf,
    DWORD  cbOutBuf,
    PDWORD pcbActualOutBuf
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    BOOL fRet = FALSE;
    PUFN_MDD_CONTEXT_SIG pMddContextSig = (PUFN_MDD_CONTEXT_SIG) dwContext;

    if (pMddContextSig == NULL) {
        SetLastError(ERROR_INVALID_HANDLE);
    }
    else if (pMddContextSig->dwSig == UFN_MDD_BUS_SIG) {
        PUFN_MDD_BUS_OPEN_CONTEXT pBusContext = 
            (PUFN_MDD_BUS_OPEN_CONTEXT) pMddContextSig;
        ValidateBusContext(pBusContext);

        EnterCriticalSection(&pBusContext->pMddContext->csBusIoctlAccess);
        fRet = pBusContext->pMddContext->pUfnBus->IOControl(pBusContext, dwCode, pbInBuf, cbInBuf,
            pbOutBuf, cbOutBuf, pcbActualOutBuf);
        LeaveCriticalSection(&pBusContext->pMddContext->csBusIoctlAccess);
    }
    else if (pMddContextSig->dwSig == UFN_MDD_SIG) {
        PUFN_MDD_CONTEXT pMddContext = 
            (PUFN_MDD_CONTEXT) pMddContextSig;
        ValidateContext(pMddContext);
        
        // Pass all normal IOCTLs to the PDD
        DWORD dwRet = pMddContext->PddInfo.pfnIOControl(
            pMddContext->PddInfo.pvPddContext, EXTERN_IOCTL, dwCode,
            pbInBuf, cbInBuf, pbOutBuf, cbOutBuf, pcbActualOutBuf);
        if (dwRet != ERROR_SUCCESS) {
            SetLastError(dwRet);
        }
        else {
            fRet = TRUE;
        }
    }
    else {
        SetLastError(ERROR_INVALID_HANDLE);
    }

    FUNCTION_LEAVE_MSG();

    return fRet;
}


// Send a notification.
BOOL
SendDeviceNotification(
    LPUFN_NOTIFY lpNotify,
    PVOID        pvNotifyParameter,
    DWORD        dwMsg,
    DWORD        dwParam
    )
{
    SETFNAME();
    
    BOOL fRet = TRUE;
    
    __try {
        if (lpNotify) {
            (*lpNotify)(pvNotifyParameter, dwMsg, dwParam);
        }
    }
    __except(EXCEPTION_EXECUTE_HANDLER) {
        DEBUGMSG(ZONE_ERROR, (_T("%s Exception in notification routine!\r\n"), pszFname));
        fRet = FALSE;
    }

    return fRet;
}


extern "C"
BOOL
WINAPI
DllEntry(
    HANDLE hDllHandle,
    DWORD  dwReason, 
    LPVOID lpReserved
    )
{
    SETFNAME();
    
    switch (dwReason) {
        case DLL_PROCESS_ATTACH:
            DEBUGREGISTER((HINSTANCE)hDllHandle);
            DEBUGMSG(ZONE_INIT, (_T("%s Attach\r\n"), pszFname));
            DisableThreadLibraryCalls((HMODULE) hDllHandle);
            svsutil_Initialize();
            CTransferQueue<CUfnMddTransfer>::InitializeClass(DEFAULT_TRANSFER_LIST_SIZE);
            break;
            
        case DLL_PROCESS_DETACH:
            DEBUGMSG(ZONE_INIT, (_T("%s Detach\r\n"), pszFname));
            CTra

⌨️ 快捷键说明

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