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

📄 ufnmdd.cpp

📁 freescale i.mx31 BSP CE5.0全部源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        dwRet = GetLastError();
        DEBUGMSG(ZONE_ERROR, (_T("%s LocalAlloc failed. Error: %d\r\n"), pszFname, 
            dwRet));
        goto EXIT;
    }
    
    memcpy(pConfigDest->pInterfaces, pConfigSource->pInterfaces, cbInterfaces);

    DWORD cInterfaces = pConfigDest->Descriptor.bNumInterfaces;
    // Clear out each interface's pointers
    for (DWORD dwInterface = 0; dwInterface < cInterfaces; ++dwInterface) {
        PUFN_INTERFACE pInterfaceDest = &pConfigDest->pInterfaces[dwInterface];
        pInterfaceDest->pEndpoints = NULL;
        pInterfaceDest->pvExtended = NULL;
    }
    
    // Copy each interface's extended descriptor
    for (DWORD dwInterface = 0; dwInterface < cInterfaces; ++dwInterface) {
        PUFN_INTERFACE pInterfaceSource = &pConfigSource->pInterfaces[dwInterface];
        PUFN_INTERFACE pInterfaceDest = &pConfigDest->pInterfaces[dwInterface];

        // TODO: Fail on alternate interface
        
        dwRet = CopyExtendedDesc(&pInterfaceDest->pvExtended, 
            &pInterfaceDest->cbExtended,
            pInterfaceSource->pvExtended,
            pInterfaceSource->cbExtended);
        if (dwRet != ERROR_SUCCESS) {
            goto EXIT;
        }

        // Copy the endpoint structures
        DWORD cEndpoints = pInterfaceSource->Descriptor.bNumEndpoints;

        if (cEndpoints > 0) {
            DWORD cbEndpoints;
            cbEndpoints = cEndpoints * sizeof(UFN_ENDPOINT);
            pInterfaceDest->pEndpoints = (PUFN_ENDPOINT)
                LocalAlloc(0, cbEndpoints);
            if (pInterfaceDest->pEndpoints == NULL) {
                dwRet = GetLastError();
                DEBUGMSG(ZONE_ERROR, (_T("%s LocalAlloc failed. Error: %d\r\n"), pszFname, 
                    dwRet));
                goto EXIT;
            }

            memcpy(pInterfaceDest->pEndpoints, pInterfaceSource->pEndpoints, 
                cbEndpoints);

            // Clear out each endpoint's pointers
            for (DWORD dwEndpoint = 0; dwEndpoint < cEndpoints; ++dwEndpoint) {
                PUFN_ENDPOINT pDestEndpoint = 
                    &pInterfaceDest->pEndpoints[dwEndpoint];
                pDestEndpoint->pvExtended = NULL;
            }
            
            // Copy each endpoint's extended descriptors
            for (DWORD dwEndpoint = 0; dwEndpoint < cEndpoints; ++dwEndpoint) {
                PUFN_ENDPOINT pSourceEndpoint = 
                    &pInterfaceSource->pEndpoints[dwEndpoint];
                PUFN_ENDPOINT pDestEndpoint = 
                    &pInterfaceDest->pEndpoints[dwEndpoint];
                dwRet = CopyExtendedDesc(&pDestEndpoint->pvExtended, &pDestEndpoint->cbExtended,
                    pSourceEndpoint->pvExtended, pSourceEndpoint->cbExtended);
                if (dwRet != ERROR_SUCCESS) {
                    goto EXIT;
                }
            }
        }
    }

    dwRet = ERROR_SUCCESS;

EXIT:
    FUNCTION_LEAVE_MSG();

    return dwRet;
}


// Free all allocated data in a config tree structure.
static
VOID
FreeConfig(
    PUFN_CONFIGURATION pConfig
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    PREFAST_DEBUGCHK(pConfig);

    if (pConfig->pInterfaces) {
        const DWORD cInterfaces = pConfig->Descriptor.bNumInterfaces;
        for (DWORD dwInterface = 0; dwInterface < cInterfaces; ++dwInterface) {
            PUFN_INTERFACE pInterface = &pConfig->pInterfaces[dwInterface];
            if (pInterface->pEndpoints) {
                DWORD cEndpoints = pInterface->Descriptor.bNumEndpoints;
                for (DWORD dwEndpoint = 0; dwEndpoint < cEndpoints; ++dwEndpoint) {
                    PUFN_ENDPOINT pSourceEndpoint = 
                        &pInterface->pEndpoints[dwEndpoint];

                    // Free this endpoint's extended descriptor
                    if (pSourceEndpoint->pvExtended) {
                        LocalFree(pSourceEndpoint->pvExtended);
                    }
                }

                // Free the endpoint structures
                LocalFree(pInterface->pEndpoints);
            }

            // Free the interface's extended descriptor
            if (pInterface->pvExtended) {
                LocalFree(pInterface->pvExtended);
            }
        }

        // Free the interface structure
        LocalFree(pConfig->pInterfaces);
        pConfig->pInterfaces = NULL;
    }
    
    // Free the config's extended descriptor
    if (pConfig->pvExtended) {
        LocalFree(pConfig->pvExtended);
        pConfig->pvExtended = NULL;
    }

    FUNCTION_LEAVE_MSG();
}


// Copy string descriptors.
static
DWORD
CopyStrings(
    PUFN_MDD_CONTEXT    pContext,
    PCUFN_STRING_SET    pStringSets,
    DWORD               cStringSets
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    ValidateContext(pContext);
    PREFAST_DEBUGCHK(pStringSets);
    DEBUGCHK(cStringSets);

    DWORD dwRet = ERROR_INVALID_PARAMETER;
    DWORD dwStringSet;
    DWORD dwString;
    DWORD cbStringSets;
    DWORD cbStringArray;
    DWORD cbStringArrays;
    DWORD cbBuffer;
    PBYTE pbBuffer;

    // Get the count of bytes in the strings
    DWORD cbStrings = 0;
    DWORD cStrings = pStringSets->cStrings;
    for (dwStringSet = 0; dwStringSet < cStringSets; ++dwStringSet) {
        PCUFN_STRING_SET pStringSet = &pStringSets[dwStringSet];

        if (pStringSet->cStrings != cStrings) {
            DEBUGMSG(ZONE_ERROR, (_T("%s String count across locales do not match\r\n"), 
                pszFname));
            goto EXIT;
        }

        for (dwString = 0; dwString < pStringSet->cStrings; ++dwString) {
            LPCWSTR pszString = pStringSet->ppszStrings[dwString];
            DWORD cchString = wcslen(pszString);
            
            if (cchString >= MAX_STRING_DESC_WCHARS) {
                DEBUGMSG(ZONE_ERROR, (_T("%s String %s is too long\r\n"), pszFname,
                    pszString));
                goto EXIT;
            }
            
            cbStrings += (cchString + 1) * sizeof(WCHAR);
        }
    }

    cbStringSets = cStringSets * sizeof(UFN_STRING_SET);
    cbStringArray = pStringSets->cStrings * sizeof(*pStringSets->ppszStrings);
    cbStringArrays = cbStringArray * cStringSets;
    cbBuffer = cbStringSets + cbStringArrays + cbStrings;
    
    pbBuffer = (PBYTE) LocalAlloc(0, cbBuffer);
    if (pbBuffer == NULL) {
        dwRet = GetLastError();
        DEBUGMSG(ZONE_ERROR, (_T("%s LocalAlloc failed. Error: %d\r\n"), pszFname, 
            dwRet));
        goto EXIT;
    }

    pContext->pStringSets = (PUFN_STRING_SET) pbBuffer;

    // Copy string sets
    memcpy(pContext->pStringSets, pStringSets, cbStringSets);

    // Assign string pointer arrays
    pbBuffer += cbStringSets;
    for (dwStringSet = 0; dwStringSet < cStringSets; ++dwStringSet) {
        PUFN_STRING_SET pStringSetDst = &pContext->pStringSets[dwStringSet];
        pStringSetDst->ppszStrings = (LPCWSTR *) pbBuffer;
        pbBuffer += cbStringArray;
    }

    // Copy each string
    for (dwStringSet = 0; dwStringSet < cStringSets; ++dwStringSet) {
        PCUFN_STRING_SET pStringSetSrc = &pStringSets[dwStringSet];
        PUFN_STRING_SET pStringSetDst = &pContext->pStringSets[dwStringSet];

        for (dwString = 0; dwString < pStringSetSrc->cStrings; ++dwString) {
            LPCWSTR pszSrc = pStringSetSrc->ppszStrings[dwString];
            LPWSTR pszDst = (LPWSTR) pbBuffer;

            DWORD cchString = wcslen(pszSrc);
            wcsncpy(pszDst, pszSrc, cchString);
            pszDst[cchString] = 0;

            pStringSetDst->ppszStrings[dwString] = pszDst;
            pbBuffer += (cchString + 1) * sizeof(WCHAR);
        }
    }

    pContext->cStringSets = cStringSets;

    dwRet = ERROR_SUCCESS;
    
EXIT:
    FUNCTION_LEAVE_MSG();

    return dwRet;
}


// Free string descriptors in pContext.
static
VOID
FreeStrings(
    PUFN_MDD_CONTEXT pContext
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();
    
    PREFAST_DEBUGCHK(pContext);
    
    LocalFree(pContext->pStringSets);
    pContext->pStringSets = NULL;
    pContext->cStringSets = 0;

    FUNCTION_LEAVE_MSG();
}


// Free all allocated USB structures in pContext.
static
VOID
FreeUsbStructs(
    PUFN_MDD_CONTEXT pContext
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    ValidateContext(pContext);

    if (pContext->pStringSets) {
        FreeStrings(pContext);
        pContext->pStringSets = NULL;
    }

    if (pContext->pHighSpeedConfigDesc) {
        LocalFree(pContext->pHighSpeedConfigDesc);
        pContext->pHighSpeedConfigDesc = NULL;
    }

    if (pContext->pFullSpeedConfigDesc) {
        LocalFree(pContext->pFullSpeedConfigDesc);
        pContext->pFullSpeedConfigDesc = NULL;
    }

    if ( pContext->HighSpeedConfig.pInterfaces ||
         pContext->HighSpeedConfig.pvExtended ) {
        FreeConfig(&pContext->HighSpeedConfig);
    }

    if ( pContext->FullSpeedConfig.dwCount ||
         pContext->FullSpeedConfig.pvExtended ) {
        FreeConfig(&pContext->FullSpeedConfig);
    }

    FUNCTION_LEAVE_MSG();
}
    

// Copy the user-supplied USB structures to the pContext.
static
DWORD
CopyUsbStructs(
    PUFN_MDD_CONTEXT        pContext,
    PUSB_DEVICE_DESCRIPTOR  pHighSpeedDeviceDesc,
    PUFN_CONFIGURATION      pHighSpeedConfig,
    PUSB_DEVICE_DESCRIPTOR  pFullSpeedDeviceDesc,
    PUFN_CONFIGURATION      pFullSpeedConfig,
    PCUFN_STRING_SET        pStringSets,
    DWORD                   cStringSets
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DWORD dwRet = ERROR_SUCCESS;
    
    ValidateContext(pContext);
    DEBUGCHK(pHighSpeedDeviceDesc);
    DEBUGCHK(pFullSpeedDeviceDesc);
    DEBUGCHK(pHighSpeedConfig);
    DEBUGCHK(pFullSpeedConfig);
    DEBUGCHK(pStringSets || (cStringSets == 0));
    
    struct CONFIG_SPEED_VALUES {
        PUSB_DEVICE_DESCRIPTOR pDestDeviceDesc;
        PUSB_DEVICE_DESCRIPTOR pSourceDeviceDesc;
        PUFN_CONFIGURATION pDestConfig;
        PUFN_CONFIGURATION pSourceConfig;
        PUSB_CONFIGURATION_DESCRIPTOR *ppConfigDesc;
    };

    const CONFIG_SPEED_VALUES rgpConfigVals[] = { // destination-source pairs
        {
            &pContext->HighSpeedDeviceDesc, pHighSpeedDeviceDesc,
            &pContext->HighSpeedConfig, pHighSpeedConfig, 
            &pContext->pHighSpeedConfigDesc 
        },
        {
            &pContext->FullSpeedDeviceDesc, pFullSpeedDeviceDesc,
            &pContext->FullSpeedConfig, pFullSpeedConfig, 
            &pContext->pFullSpeedConfigDesc
        }
    };
        
    // Copy high and full speed structures
    for (DWORD dwConfig = 0; dwConfig < dim(rgpConfigVals); ++dwConfig) {
        const CONFIG_SPEED_VALUES *pConfigVals = &rgpConfigVals[dwConfig];

        // Copy the device descriptor
        memcpy(pConfigVals->pDestDeviceDesc, pConfigVals->pSourceDeviceDesc,
            sizeof(USB_DEVICE_DESCRIPTOR));

        // Copy the config tree structure
        dwRet = CopyConfig(pConfigVals->pDestConfig, pConfigVals->pSourceConfig);
        if (dwRet != ERROR_SUCCESS) {
            goto EXIT;
        }
        
        // Create the conglomerate configuration descriptor
        dwRet = CreateConfigDesc(pConfigVals->ppConfigDesc, pConfigVals->pDestConfig);
        if (dwRet != ERROR_SUCCESS) {
            goto EXIT;
        }

        DEBUGCHK(*pConfigVals->ppConfigDesc);
    }

    // Copy string descriptors
    if (cStringSets != 0) {
        dwRet = CopyStrings(pContext, pStringSets, cStringSets);
        if (dwRet != ERROR_SUCCESS) {
            goto EXIT;
        }

        DEBUGCHK(pContext->pStringSets);
        DEBUGCHK(pContext->cStringSets);
    }

EXIT:
    if (dwRet != ERROR_SUCCESS) {
        // Free all allocated data
        FreeUsbStructs(pContext);
    }
    
    FUNCTION_LEAVE_MSG();

    return dwRet;
}


// Finds out if endpoint 0 is supportable for these parameters.
static
DWORD
IsEndpointZeroSupportable(
    PUFN_MDD_CONTEXT pContext,
    PUSB_DEVICE_DESCRIPTOR pDeviceDesc,
    UFN_BUS_SPEED Speed
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    ValidateContext(pContext);
    PREFAST_DEBUGCHK(pDeviceDesc);

    DWORD dwRet = ERROR_SUCCESS;

    USB_ENDPOINT_DESCRIPTOR EndpointDesc;
    InitializeEndpointZeroDescriptor(pContext, pDeviceDesc->bMaxPacketSize0, &EndpointDesc);
    
    if ( !ValidatePacketSize(Speed, &EndpointDesc) ||
         (pContext->PddInfo.pfnIsEndpointSupportable(pContext->PddInfo.pvPddContext, 0, Speed, 
            &EndpointDesc, 0, 0, 0) != ERROR_SUCCESS) ) {
        dwRet = ERROR_INVALID_PARAMETER;
        DEBUGMSG(ZONE_ERROR, (_T("%s Cannot satisfy %s speed EP0 packet size requirement of %u\r\n"), 
            pszFname, GetSpeedString(Speed), pDeviceDesc->bMaxPacketSize0));
        goto EXIT;
    }
    pDeviceDesc->bMaxPacketSize0 = (BYTE) EndpointDesc.wMaxPacketSize;

EXIT:
    FUNCTION_LEAVE_MSG();

    return dwRet;
}


// Finds out if an entire interface is supportable.
static
DWORD
IsInterfaceSupportable(
    PUFN_MDD_CONTEXT pContext,
    PUFN_INTERFACE pInterface,
    UFN_BUS_SPEED Speed,
    BYTE bConfiguration
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    ValidateContext(pContext);
    PREFAST_DEBUGCHK(pInterface);

    DWORD dwRet = ERROR_INVALID_PARAMETER;
    DWORD cEndpoints = pInterface->Descriptor.bNumEndpoints;

    if ( cEndpoints && (pInterface->pEndpoints == NULL) ) {
        DEBUGMSG(ZONE_ERROR, (_T("%s No endpoint structure provided\r\n"),
            pszFname));
        goto EXIT;
    }
    
    DWORD dwEndpoint;
    for (dwEndpoint = 0; dwEndpoint < cEndpoints; ++dwEndpoint) {
        PUFN_ENDPOINT pEndpoint = &pInterface->pEndpoints[dwEndpoint];

        if (!ValidatePacketSize(Speed, &pEndpoint->Descriptor)) {
            DEBUGMSG(ZONE_ERROR, (_T("%s Invalid packet size for endpoint 0x%x\r\n"),
                pszFname, pEndpoint->Descriptor.bEndpointAddress));
            goto EXIT;
        }

        // Do not check endoint 0.
        for (DWORD dwPipe = 1; dwPipe < pContext->PddInfo.dwEndpointCount; ++dwPipe) {
            PCPipe pPipe = &pContext->pPipes[dwPipe];
            
            if (pPipe->IsReserved(Speed)) {
                continue;
            }

            if (pContext->PddInfo.pfnIsEndpointSupportable(pContext->PddInfo.pvPddContext, 
                    pPipe->GetPhysicalEndpoint(), Speed,
                    &pEndpoint->Descriptor, bConfiguration, pInterface->Descriptor.bInterfaceNumber,
                    pInterface->Descriptor.bAlternateSetting) == ERROR_SUCCESS) {
                DEBUGMSG(ZONE_FUNCTION, 
                    (_T("%s Endpoint index %u can be supported by physical endpoint %u\r\n"), 
                    pszFname, dwEndpoint, pPipe->GetPhysicalEndpoint()));

⌨️ 快捷键说明

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