wdu_lib.c

来自「一个基于windriver开发的」· C语言 代码 · 共 646 行 · 第 1/2 页

C
646
字号
        {
            ERR("EventHandler: unable to get device info for device"
                " handle 0x%x dwUniqueID 0x%x\n", 
                hDevice, pDeviceCtx->dwUniqueID);
            RemoveDeviceFromDevList(pEvent->u.Usb.dwUniqueID, &pDummyDeviceCtx);
            free(pDeviceCtx);
            return;
        }

        bControlDevice = pDriverCtx->EventTable.pfDeviceAttach(hDevice, 
            pDeviceCtx->pDevice, pDriverCtx->EventTable.pUserData);
        if (!bControlDevice)
        {
            TRACE("EventHandler: bControlDevice==FALSE; pDriverCtx 0x%x\n", pDriverCtx);
            RemoveDeviceFromDevList(pEvent->u.Usb.dwUniqueID, &pDummyDeviceCtx);
            free(pDeviceCtx->pDevice); // because GetDeviceInfo calls malloc
            free(pDeviceCtx);
        }

        pEvent->dwOptions |= bControlDevice ? WD_ACCEPT_CONTROL : 0;
        break;
    case WD_REMOVE:
        dwStatus = RemoveDeviceFromDevList(pEvent->u.Usb.dwUniqueID, &pDeviceCtx);
        if (dwStatus)
            // device is not mine or may has been closed by WDU_Uninit
            break;

        // DEVICE_CTX * is used as WDU_DEVICE_HANDLE
        pDriverCtx->EventTable.pfDeviceDetach((WDU_DEVICE_HANDLE) pDeviceCtx, pDriverCtx->EventTable.pUserData);

        free(pDeviceCtx->pDevice); // because GetDeviceInfo calls malloc
        free(pDeviceCtx);

        break;
    case WD_POWER_CHANGED_D0:
    case WD_POWER_CHANGED_D1:
    case WD_POWER_CHANGED_D2:
    case WD_POWER_CHANGED_D3:
    case WD_POWER_SYSTEM_WORKING:
    case WD_POWER_SYSTEM_SLEEPING1:
    case WD_POWER_SYSTEM_SLEEPING2:
    case WD_POWER_SYSTEM_SLEEPING3:
    case WD_POWER_SYSTEM_HIBERNATE:
    case WD_POWER_SYSTEM_SHUTDOWN:
        dwStatus = FindDeviceByUniqueID(pEvent->u.Usb.dwUniqueID, &pDeviceCtx);
        if (dwStatus)
        {
            // device is not mine or may have been closed by WDU_Uninit
            break;
        }

        bChangePower = pDriverCtx->EventTable.pfPowerChange((WDU_DEVICE_HANDLE) pDeviceCtx, pEvent->dwAction, 
            pDriverCtx->EventTable.pUserData);
        // XXX return in the event structure if the user says it's ok to change power
        //  (not implemented yet)
        break;
    }
}

// ppDeviceInfo is set to point to an allocated buffer containing the info.
// The caller should free the buffer after the use.
DWORD DLLCALLCONV WDU_GetDeviceInfo(WDU_DEVICE_HANDLE hDevice, WDU_DEVICE **ppDeviceInfo)
{
    DWORD dwStatus;

    PARAMS_INIT(WDU_GET_DEVICE_DATA);
    // first call with pBuf NULL, return dwBytes
    dwStatus = WD_UGetDeviceData(GET_HWD(hDevice), &Params);
    if (dwStatus != WD_STATUS_SUCCESS)
        return dwStatus;
    *ppDeviceInfo = (WDU_DEVICE *) malloc(Params.dwBytes);
    if (!ppDeviceInfo)
    {
        ERR("WDU_GetDeviceInfo: cannot alloc memory\n");
        return WD_INSUFFICIENT_RESOURCES;
    }

    Params.pBuf = *ppDeviceInfo;
    // second call with correct pBuf and dwBytes
    dwStatus = WD_UGetDeviceData(GET_HWD(hDevice), &Params);
    return dwStatus;
}

//
// simplified transfers
//

DWORD DLLCALLCONV WDU_TransferDefaultPipe(WDU_DEVICE_HANDLE hDevice, DWORD fRead, 
    DWORD dwOptions, PVOID pBuffer, DWORD dwBufferSize, PDWORD pdwBytesTransferred, 
    PBYTE pSetupPacket, DWORD dwTimeout)
{
    return WDU_Transfer(hDevice, 0, fRead, 
    dwOptions, pBuffer, dwBufferSize, pdwBytesTransferred, 
    pSetupPacket, dwTimeout);
}

DWORD DLLCALLCONV WDU_TransferBulk(WDU_DEVICE_HANDLE hDevice, DWORD dwPipeNum, DWORD fRead, 
    DWORD dwOptions, PVOID pBuffer, DWORD dwBufferSize, PDWORD pdwBytesTransferred, 
    DWORD dwTimeout)
{
    return WDU_Transfer(hDevice, dwPipeNum, fRead, 
    dwOptions, pBuffer, dwBufferSize, pdwBytesTransferred, 
    NULL, dwTimeout);
}

DWORD DLLCALLCONV WDU_TransferIsoch(WDU_DEVICE_HANDLE hDevice, DWORD dwPipeNum, DWORD fRead, 
    DWORD dwOptions, PVOID pBuffer, DWORD dwBufferSize, PDWORD pdwBytesTransferred, 
    DWORD dwTimeout)
{
    return WDU_Transfer(hDevice, dwPipeNum, fRead, 
    dwOptions, pBuffer, dwBufferSize, pdwBytesTransferred, 
    NULL, dwTimeout);
}

DWORD DLLCALLCONV WDU_TransferInterrupt(WDU_DEVICE_HANDLE hDevice, DWORD dwPipeNum, DWORD fRead, 
    DWORD dwOptions, PVOID pBuffer, DWORD dwBufferSize, PDWORD pdwBytesTransferred, 
    DWORD dwTimeout)
{
    return WDU_Transfer(hDevice, dwPipeNum, fRead, 
    dwOptions, pBuffer, dwBufferSize, pdwBytesTransferred, 
    NULL, dwTimeout);
}

// Private Functions 

DWORD AddDeviceToDevList(DEVICE_CTX *pDeviceCtx)
{
    WDU_DEVICE_LIST_ITEM *pDevItem;
    DWORD dwStatus;

    TRACE("AddDeviceToDevList device 0x%x before 0x%x\n", pDeviceCtx, DevList);

    dwStatus = OsEventWait(DevList.hEvent, WDU_DEVLIST_TIMEOUT);
    if (dwStatus)
    {
        ERR("AddDeviceToDevList: error waiting for device list event: dwStatus (0x%x) - %s\n", 
            dwStatus, Stat2Str(dwStatus));
        return dwStatus;
    }

    pDevItem = (WDU_DEVICE_LIST_ITEM *) calloc(1, sizeof(WDU_DEVICE_LIST_ITEM));
    pDevItem->pDeviceCtx = pDeviceCtx;
    pDevItem->next = DevList.pHead;

    DevList.pHead = pDevItem;

    dwStatus = OsEventSignal(DevList.hEvent);
    if (dwStatus)
    {
        ERR("AddDeviceToDevList: error signaling device list event: dwStatus (0x%x) - %s\n", 
            dwStatus, Stat2Str(dwStatus));
    }
    return dwStatus;
}

DWORD RemoveAllDevicesFromDevList(DRIVER_CTX *pDriverCtx)
{
    DEVICE_CTX *pDeviceCtx;
    WDU_DEVICE_LIST_ITEM **ppDev = &DevList.pHead;
    WDU_DEVICE_LIST_ITEM *pDevTmp;
    DWORD dwStatus;

    TRACE("RemoveAllDevicesFromDevList: pDriverCtx 0x%x\n", pDriverCtx);

    dwStatus = OsEventWait(DevList.hEvent, WDU_DEVLIST_TIMEOUT);
    if (dwStatus)
    {
        ERR("RemoveAllDevicesFromDevList: error waiting for device list event: dwStatus (0x%x) - %s\n", 
            dwStatus, Stat2Str(dwStatus));
        return dwStatus;
    }

    while (*ppDev)
    {
        pDeviceCtx = (*ppDev)->pDeviceCtx;
        if (pDeviceCtx->pDriverCtx == pDriverCtx)
        {
            pDevTmp = *ppDev;
            *ppDev = (*ppDev)->next;

            free(pDeviceCtx->pDevice); // because GetDeviceInfo calls malloc
            free(pDeviceCtx);
            free(pDevTmp);
        }
        else
            ppDev = &(*ppDev)->next;
    }

    dwStatus = OsEventSignal(DevList.hEvent);
    if (dwStatus)
    {
        ERR("RemoveAllDevicesFromDevList: error signaling device list event: dwStatus (0x%x) - %s\n", 
            dwStatus, Stat2Str(dwStatus));
    }
    return dwStatus;
}

DWORD FindDeviceByUniqueID(DWORD dwUniqueID, DEVICE_CTX **ppDeviceCtx)
{
    WDU_DEVICE_LIST_ITEM *iter;
    DWORD dwStatus;
    BOOL Found = FALSE;

    TRACE("FindDeviceByUniqueID: DevList.pHead 0x%x, dwUniqueID 0x%x\n", DevList.pHead, dwUniqueID);
    *ppDeviceCtx = NULL;

    dwStatus = OsEventWait(DevList.hEvent, WDU_DEVLIST_TIMEOUT);
    if (dwStatus)
    {
        ERR("FindDeviceByUniqueID: error waiting for device list event: dwStatus (0x%x) - %s\n", 
            dwStatus, Stat2Str(dwStatus));
        return dwStatus;
    }

    for (iter = DevList.pHead; iter; iter = iter->next)
    {
        if (iter->pDeviceCtx->dwUniqueID == dwUniqueID)
        {
            Found = TRUE;
            break;
        }
    }

    dwStatus = OsEventSignal(DevList.hEvent);
    if (dwStatus)
    {
        ERR("FindDeviceByUniqueID: error signaling device list event: dwStatus (0x%x) - %s\n", 
            dwStatus, Stat2Str(dwStatus));
        return dwStatus;
    }

    if (Found)
        *ppDeviceCtx = iter->pDeviceCtx;
    else
        dwStatus = WD_DEVICE_NOT_FOUND;

    return dwStatus;
}

DWORD FindDeviceByCtx(DEVICE_CTX *pDeviceCtx)
{
    WDU_DEVICE_LIST_ITEM *iter;
    DWORD dwStatus;
    BOOL Found = FALSE;

    dwStatus = OsEventWait(DevList.hEvent, WDU_DEVLIST_TIMEOUT);
    if (dwStatus)
    {
        ERR("FindDeviceByCtx: error waiting for device list event: dwStatus (0x%x) - %s\n", 
            dwStatus, Stat2Str(dwStatus));
        return dwStatus;
    }

    for (iter = DevList.pHead; iter; iter = iter->next)
    {
        if (iter->pDeviceCtx == pDeviceCtx)
        {
            Found = TRUE;
            break;
        }
    }

    dwStatus = OsEventSignal(DevList.hEvent);
    if (dwStatus)
    {
        ERR("FindDeviceByCtx: error signaling device list event: dwStatus (0x%x) - %s\n", 
            dwStatus, Stat2Str(dwStatus));
        return dwStatus;
    }
    if (!Found)
        dwStatus = WD_DEVICE_NOT_FOUND;
    return dwStatus;
}

DWORD RemoveDeviceFromDevList(DWORD dwUniqueID, DEVICE_CTX **ppDeviceCtx)
{
    WDU_DEVICE_LIST_ITEM **iter, *tmp;
    DWORD dwStatus;
    BOOL Found = FALSE;

    TRACE("RemoveDeviceFromDevList: DevList 0x%x, dwUniqueID 0x%x\n", DevList, dwUniqueID);
    *ppDeviceCtx = NULL;

    dwStatus = OsEventWait(DevList.hEvent, WDU_DEVLIST_TIMEOUT);
    if (dwStatus)
    {
        ERR("RemoveDeviceFromDevList: error waiting for device list event: dwStatus (0x%x) - %s\n", 
            dwStatus, Stat2Str(dwStatus));
        return dwStatus;
    }

    for (iter = &DevList.pHead; *iter; iter = &(*iter)->next)
    {
        if ((*iter)->pDeviceCtx->dwUniqueID == dwUniqueID)
        {
            Found = TRUE;
            break;
        }
    }
    if (Found)
    {
        tmp = *iter;
        *ppDeviceCtx = (*iter)->pDeviceCtx;

        // remove the device
        *iter = (*iter)->next;
        free(tmp);
    }

    dwStatus = OsEventSignal(DevList.hEvent);
    if (dwStatus)
    {
        ERR("RemoveDeviceFromDevList: error signaling device list event: dwStatus (0x%x) - %s\n", 
            dwStatus, Stat2Str(dwStatus));
        return dwStatus;
    }

    if (!Found)
        dwStatus = WD_DEVICE_NOT_FOUND;
    return dwStatus;
}

⌨️ 快捷键说明

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