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

📄 wdu_lib.cpp

📁 采用windriver提供的API开发的D12应用程序源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

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

// Frees device info allocated with WDU_GetDeviceInfo()
void DLLCALLCONV WDU_PutDeviceInfo(WDU_DEVICE *pDeviceInfo)
{
    free(pDeviceInfo);
}

DWORD DLLCALLCONV WDU_GetDeviceAddr(WDU_DEVICE_HANDLE hDevice, ULONG *pAddress)
{
    DWORD dwStatus;
    WD_GET_DEVICE_PROPERTY Params; 

    BZERO(Params); 

    if (!hDevice || FindDeviceByCtx((DEVICE_CTX *)hDevice) != WD_STATUS_SUCCESS) 
        return WD_DEVICE_NOT_FOUND; 

    Params.h.dwUniqueID = ((DEVICE_CTX *)hDevice)->dwUniqueID;
    Params.pBuf = pAddress;
    Params.dwProperty = WdDevicePropertyAddress;
    Params.dwOptions = WD_DEVICE_USB;
    Params.dwBytes = sizeof(*pAddress);
    dwStatus = WD_GetDeviceProperty(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 

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

    TRACE("AddDeviceToDevList: device %p, before %p\n", pDeviceCtx, DevList);

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

static DWORD RemoveAllDevicesFromDevList(DRIVER_CTX *pDriverCtx)
{
#if defined(__KERNEL__)
    return WD_NOT_IMPLEMENTED;
#else
    DEVICE_CTX *pDeviceCtx;
    WDU_DEVICE_LIST_ITEM **ppDev = &DevList.pHead;
    WDU_DEVICE_LIST_ITEM *pDevTmp;
    DWORD dwStatus;

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

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

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

            WDU_PutDeviceInfo(pDeviceCtx->pDevice);
            free(pDeviceCtx);
            free(pDevTmp);
        }
        else
            ppDev = &(*ppDev)->next;
    }

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

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

    TRACE("FindDeviceByUniqueID: DevList.pHead %p, dwUniqueID 0x%lx\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%lx) - %s\n", 
            dwStatus, Stat2Str(dwStatus));
        return dwStatus;
    }

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

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

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

    return dwStatus;
}

static 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%lx) - %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%lx) - %s\n", 
            dwStatus, Stat2Str(dwStatus));
        return dwStatus;
    }
    if (!Found)
        dwStatus = WD_DEVICE_NOT_FOUND;
    return dwStatus;
}

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

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

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

    for (iter = &DevList.pHead; *iter; iter = &(*iter)->next)
    {
        if ((*iter)->pDeviceCtx->dwUniqueID == dwUniqueID && 
            (*iter)->pDeviceCtx->pDriverCtx == pDriverCtx)
        {
            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%lx) - %s\n", 
            dwStatus, Stat2Str(dwStatus));
        return dwStatus;
    }

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

DWORD DLLCALLCONV WDU_GetLangIDs(WDU_DEVICE_HANDLE hDevice, 
    PBYTE pbNumSupportedLangIDs, WDU_LANGID *pLangIDs, BYTE bNumLangIDs)
{
    DWORD dwStatus;
    DWORD dwBytesTransferred;
    BYTE bTmpNumIDs, bNumReadIDs;
    BYTE bSizeTrans; // size in bytes
    WDU_LANGID *pBuf = NULL;
    BYTE  setupPacket[] = { 0x80, 0x6, 0x0, 0x3, 0x0, 0x0, sizeof(bSizeTrans), 0x0};
  
    if (!pbNumSupportedLangIDs && !bNumLangIDs)
        return WD_INVALID_PARAMETER;
    
    // Read number of supported language IDs from the device
    dwStatus = WDU_TransferDefaultPipe(hDevice, TRUE, 0, &bSizeTrans, sizeof(bSizeTrans), 
        &dwBytesTransferred, setupPacket, WDU_TRANSFER_TIMEOUT);
    if (dwStatus)
    {
        ERR("WDU_GetLangIDs: Failed reading number of supported language IDs from the device:\n"
            "Error: 0x%lx (\"%s\")\n", dwStatus, Stat2Str(dwStatus));
        return dwStatus;
    }
    
    bTmpNumIDs = (BYTE)((bSizeTrans - 2)/sizeof(WDU_LANGID)); // First 2 bytes hold length and desc type, respectively

    if (pbNumSupportedLangIDs)
        *pbNumSupportedLangIDs = bTmpNumIDs;

    if (!bTmpNumIDs)
    {
        TRACE("WDU_GetLangIDs: No language IDs are supported for the device\n");
        return WD_STATUS_SUCCESS;
    }

    // Check if function was called only in order to get the number of supported language IDs
    if (!bNumLangIDs)
        return WD_STATUS_SUCCESS;
    
    if (!pLangIDs)
    {
        ERR("WDU_GetLangIDs: Received NULL language IDs array\n");
        return WD_INVALID_PARAMETER;
    }

    // Determine number of language IDs to read
    if (bNumLangIDs < bTmpNumIDs)
    {
        TRACE("WDU_GetLangIDs: Size of language IDs array (%d) is smaller than the number of "
            "supported language IDs (%d) - Returning only the first %d supported language IDs\n", 
            (int)bNumLangIDs, (int)bTmpNumIDs, (int)bNumLangIDs);
        bTmpNumIDs = bNumLangIDs;
        bSizeTrans = (BYTE)((bTmpNumIDs + 1) * sizeof(WDU_LANGID));
    }

    pBuf = (WDU_LANGID*)malloc(bSizeTrans);
    if (!pBuf)
    {
        ERR("WDU_GetLangIDs: Failed allocating memory for language IDs array\n");
        return WD_INSUFFICIENT_RESOURCES;
    }

    // update wLength for expected transfer size
    setupPacket[6] = (BYTE)(bSizeTrans & 0xFF);
    setupPacket[7] = (BYTE)((bSizeTrans & 0xFF00) >> 8);
        
    // Read supported language IDs from the device
    dwStatus = WDU_TransferDefaultPipe(hDevice, TRUE, 0, pBuf, bSizeTrans, 
        &dwBytesTransferred, setupPacket, WDU_TRANSFER_TIMEOUT);
    if (dwStatus)
    {
        ERR("WDU_GetLangIDs: Failed getting supported language IDs from the device:\n"
            "Error: 0x%lx (\"%s\")\n", dwStatus, Stat2Str(dwStatus));
        goto Exit;
    }

    bNumReadIDs = (BYTE)(dwBytesTransferred/sizeof(WDU_LANGID) - 1); // First WORD (LANGID) holds length and desc type
    if (bNumReadIDs != bTmpNumIDs)
    {
        ERR("WDU_GetLangIDs: Expected to read %d language IDs, read %d\n", 
            (int)bTmpNumIDs, (int)bNumReadIDs);
        dwStatus = WD_SYSTEM_INTERNAL_ERROR;
        goto Exit;
    }
    
    memcpy(pLangIDs, pBuf + 1, bSizeTrans - sizeof(WDU_LANGID)); // First WORD (LANGID) holds length and desc type

    dwStatus = WD_STATUS_SUCCESS;
    
Exit:
    free(pBuf);
    return dwStatus;
}

#define GET_STR_DESC_LEN 4096  /* max buffer size */
DWORD DLLCALLCONV WDU_GetStringDesc(WDU_DEVICE_HANDLE hDevice, BYTE bStrIndex, 
    PBYTE pbBuf, DWORD dwBufSize, WDU_LANGID langID, PDWORD pdwDescSize)
{    
    DWORD dwStatus, dwBytesTransferred;
    BYTE buf[GET_STR_DESC_LEN];
    BYTE  setupPacket[] = { 0x80, 0x6, 0x0, 0x3, 0x0, 0x0, (BYTE)(GET_STR_DESC_LEN & 0xFF), 
        (BYTE)((GET_STR_DESC_LEN & 0xFF00) >> 8) };
    DWORD dwDescSize;

    if (!pbBuf)
    {
        ERR("WDU_GetStringDesc: pbBuf is NULL\n");
        return WD_INVALID_PARAMETER;
    }
    
    if (!bStrIndex)
    {
        TRACE("WDU_GetStringDesc: Invalid string index (0)\n");
        return WD_INVALID_PARAMETER;
    }

    // set string index in the setup packet request
    setupPacket[2] = bStrIndex;

    if (!langID)
    {
        // get first language ID in supported language IDs list
        dwStatus = WDU_GetLangIDs(hDevice, NULL, &langID, 1);
        if (dwStatus)
            return dwStatus;
        
        if (!langID)
        {
            TRACE("WDU_GetStringDesc: No language IDs are supported for this device\n");
            return WD_OPERATION_FAILED;
        }
    }

    // wIndex = selected language ID
    setupPacket[4] = (BYTE)(langID & 0xFF);
    setupPacket[5] = (BYTE)((langID & 0xFF00) >> 8);

    BZERO(buf);
    dwStatus = WDU_TransferDefaultPipe(hDevice, TRUE, 0, &buf, GET_STR_DESC_LEN, &dwBytesTransferred, 
        setupPacket, WDU_TRANSFER_TIMEOUT);
    if (dwStatus)
    {
        ERR("WDU_GetStringDesc: Failed reading string descriptor from the device:\n"
            "Error: 0x%lx (\"%s\")\n", dwStatus, Stat2Str(dwStatus));
        return dwStatus;
    }

    if (dwBytesTransferred > 2)
    {
        dwDescSize = dwBytesTransferred - 2; // The descriptor string begins in the third byte

        if (dwDescSize && pdwDescSize)
            *pdwDescSize = dwDescSize;

        // return descriptor data to user.
        // If dwBufSize < dwDescSize the returned buffer will be truncated to dwBufSize
        memcpy(pbBuf, buf + 2, MIN(dwDescSize, dwBufSize));
    }
    else if (pdwDescSize)
        *pdwDescSize = 0;
        
    return WD_STATUS_SUCCESS;
}

⌨️ 快捷键说明

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