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

📄 hid.cpp

📁 cayman提供的PXA270 wince下的bsp源码包
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    )
{
    SETFNAME(_T("GetReportDescriptor"));

    BOOL fRet = FALSE;
    USB_DEVICE_REQUEST udr;
    BYTE *pRawReportDescriptor = NULL;
    NTSTATUS status;
    DWORD dwBytesTransferred;
    DWORD dwUsbErr;
    DWORD dwErr;

    DEBUGCHK(pUsbHid != NULL);
    DEBUGCHK(uReportDescriptorLength > 0);

    pRawReportDescriptor = (BYTE*) HidAlloc(uReportDescriptorLength);
    if (pRawReportDescriptor == NULL) {
        DEBUGMSG(ZONE_ERROR, (_T("%s: LocalAlloc error:%d\r\n"), pszFname, GetLastError()));
        goto EXIT;
    }

    // Do we send this to the endpoint or the interface?
    DetermineDestination(pUsbHid, &udr.bmRequestType, &udr.wIndex);
    udr.bmRequestType |= USB_REQUEST_DEVICE_TO_HOST;

    udr.bRequest = USB_REQUEST_GET_DESCRIPTOR;
    udr.wValue   = USB_DESCRIPTOR_MAKE_TYPE_AND_INDEX(HID_REPORT_DESCRIPTOR_TYPE, 0);
    udr.wLength  = uReportDescriptorLength;

    dwErr = IssueVendorTransfer(
        pUsbHid->pUsbFuncs,
        pUsbHid->hUsbDevice,
        DefaultTransferComplete, 
        pUsbHid->hEP0Event,
        (USB_IN_TRANSFER | USB_SHORT_TRANSFER_OK),
        &udr,
        pRawReportDescriptor,
        0,
        &dwBytesTransferred,
        GET_HID_DESCRIPTOR_TIMEOUT,
        &dwUsbErr);

    if ( (ERROR_SUCCESS != dwErr) || (USB_NO_ERROR != dwUsbErr) || 
         (dwBytesTransferred != uReportDescriptorLength) ) 
    {
        DEBUGMSG(ZONE_ERROR, (_T("%s: IssueVendorTransfer ERROR:%d 0x%x\n"), pszFname, dwErr, dwUsbErr));
        goto EXIT;
    }

    pUsbHid->phidpDeviceDesc = (PHIDP_DEVICE_DESC) HidAlloc(sizeof(HIDP_DEVICE_DESC));
    if (pUsbHid->phidpDeviceDesc == NULL) {
        DEBUGMSG(ZONE_ERROR, (_T("%s: LocalAlloc error:%d\r\n"), pszFname, GetLastError()));
        goto EXIT;
    }
    ZeroMemory(pUsbHid->phidpDeviceDesc, sizeof(PHIDP_DEVICE_DESC));

    // Good. We've got our report descriptor. Let's parse it.        
    status = HidP_GetCollectionDescription(
       pRawReportDescriptor,
       uReportDescriptorLength,
       0,
       pUsbHid->phidpDeviceDesc
       );

    if (NT_SUCCESS(status) == FALSE) {
        DEBUGMSG(ZONE_ERROR, (_T("%s: Problem parsing report descriptor Error: 0x%x\r\n"),
            pszFname, status));
        goto EXIT;
    }
    
    DumpHIDDeviceDescription(pUsbHid->phidpDeviceDesc);    
    fRet = TRUE;
    
EXIT:
    if (pRawReportDescriptor != NULL) HidFree(pRawReportDescriptor);
    NKDbgPrintfW(TEXT("Hid GetReportDescriptor:%d\r\n"),GetLastError());
    return fRet;
}


// Setup the pipes for this interface
static
BOOL
SetUsbInterface(
   PUSBHID_CONTEXT pUsbHid
   )
{
    SETFNAME(_T("SetUsbInterface"));

    BOOL fRet = FALSE;
    DWORD dwIndex;
    BYTE bNumEndpoints;

    DEBUGCHK(pUsbHid != NULL);
    DEBUGCHK(pUsbHid->pUsbInterface != NULL);

    // Parse the endpoints
    bNumEndpoints = pUsbHid->pUsbInterface->Descriptor.bNumEndpoints;
    for (dwIndex = 0; dwIndex < bNumEndpoints; ++dwIndex) 
    {
        LPCUSB_ENDPOINT pEndpoint;
        pEndpoint = pUsbHid->pUsbInterface->lpEndpoints + dwIndex;
        DEBUGCHK(pEndpoint != NULL);

        DUMP_USB_ENDPOINT_DESCRIPTOR(pEndpoint->Descriptor);

        // 
        // HID Class supports 1 mandatory Interrupt IN, and 1 optional Interrupt OUT
        // 
        if (USB_ENDPOINT_DIRECTION_IN(pEndpoint->Descriptor.bEndpointAddress))
        {
            if ( (NULL == pUsbHid->InterruptIn.hPipe) &&
               ( (pEndpoint->Descriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_INTERRUPT) ) 
            {
                // create the Interrupt In pipe
                pUsbHid->InterruptIn.hPipe = pUsbHid->pUsbFuncs->lpOpenPipe(pUsbHid->hUsbDevice,
                                                                            &pEndpoint->Descriptor);
                if (pUsbHid->InterruptIn.hPipe == NULL) {
                    DEBUGMSG(ZONE_ERROR, (TEXT("%s: OpenPipe error:%d\r\n"), pszFname, GetLastError()));
                    goto EXIT;
                }

                // setup any endpoint specific timers, buffers, context, etc.
                pUsbHid->InterruptIn.hEvent = CreateEvent(NULL, MANUAL_RESET_EVENT, FALSE, NULL);
                if (pUsbHid->InterruptIn.hEvent == NULL) {
                    DEBUGMSG(ZONE_ERROR, (TEXT("%s: CreateEvent error:%d\r\n"), pszFname, GetLastError()));
                    goto EXIT;
                }

                pUsbHid->InterruptIn.bIndex         = pEndpoint->Descriptor.bEndpointAddress;
                pUsbHid->InterruptIn.wMaxPacketSize = pEndpoint->Descriptor.wMaxPacketSize;
            }
            else {
                DEBUGCHK(FALSE); // The HID spec does not allow for this condition. You should not get here!
            }
        } 
        else if (USB_ENDPOINT_DIRECTION_OUT(pEndpoint->Descriptor.bEndpointAddress)) 
        {
            DEBUGMSG(ZONE_WARNING, (_T("%s: Driver does not support optional Iterrupt Out\r\n"),
                pszFname));      
        }
        else {
                DEBUGCHK(FALSE); // The HID spec does not allow for this condition. You should not get here!
        }
    }

    // Did we find our endpoint?
    if (pUsbHid->InterruptIn.hPipe == NULL) {
        DEBUGMSG(ZONE_ERROR, (_T("%s: No Interrupt In endpoint\r\n"), pszFname));
        goto EXIT;
    }

    // If we failed to find all of our endpoints then cleanup will occur later

    fRet = TRUE;

EXIT:
    NKDbgPrintfW(TEXT("Hid SetUsbInterface Fail:%d\r\n"),GetLastError());
    return fRet;
}


// Enable remote wakeup if possible.
static
BOOL
EnableRemoteWakeup(
    PUSBHID_CONTEXT pUsbHid
    )
{
    SETFNAME(_T("EnableRemotWakeup"));
    
    DWORD dwErr;
    
    DEBUGCHK(pUsbHid != NULL);
        
    dwErr = ClearOrSetFeature(
        pUsbHid->pUsbFuncs,
        pUsbHid->hUsbDevice,
        DefaultTransferComplete,
        pUsbHid->hEP0Event,
        USB_SEND_TO_DEVICE,
        USB_FEATURE_REMOTE_WAKEUP,
        0,
        1000,
        TRUE
        );

    if (dwErr != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_ERROR, (_T("%s: Set Feature failure  Error: 0x%x\r\n"), 
            pszFname, dwErr));
    }

    return dwErr == ERROR_SUCCESS;
}


// Set the device protocol to report (not boot)
static
BOOL
SetReportProtocol(
    PUSBHID_CONTEXT pUsbHid
    )
{
    SETFNAME(_T("SetReportProtocol"));
    
    DWORD dwErr, dwBytesTransferred;
    USB_ERROR usbErr;
    USB_DEVICE_REQUEST udr;
    
    DEBUGCHK(pUsbHid != NULL);
    ValidateHidContext(pUsbHid);
    DEBUGCHK(pUsbHid->pUsbInterface->Descriptor.bInterfaceSubClass == HID_INTERFACE_BOOT_SUBCLASS);

    // Do we send this to the endpoint or the interface?
    DetermineDestination(pUsbHid, &udr.bmRequestType, &udr.wIndex);
    udr.bmRequestType |= USB_REQUEST_HOST_TO_DEVICE | USB_REQUEST_CLASS;

    udr.bRequest = USB_REQUEST_HID_SET_PROTOCOL;
    udr.wValue   = HID_REPORT_PROTOCOL;
    udr.wLength  = 0;

    dwErr = IssueVendorTransfer(
        pUsbHid->pUsbFuncs,
        pUsbHid->hUsbDevice,
        NULL, 
        NULL,
        USB_OUT_TRANSFER,
        &udr,
        NULL,
        0,
        &dwBytesTransferred,
        0,
        &usbErr);

    if ((dwErr != ERROR_SUCCESS) || (usbErr != USB_NO_ERROR) ) {
        DEBUGMSG(ZONE_ERROR, (_T("%s: Set report protocol error: 0x%x 0x%x\r\n"), 
            pszFname, dwErr, usbErr));
    }

    return (dwErr == ERROR_SUCCESS);
}


// Set the idle rate for the device.
// Returns the error values from IssueVendorTransfer.
static
DWORD
SetIdle(
    PUSBHID_CONTEXT pUsbHid,
    USB_ERROR *pUsbErr
    )
{
    SETFNAME(_T("HidSetIdle"));

    USB_DEVICE_REQUEST udr;
    DWORD dwBytesTransferred;
    DWORD dwErr;
    USB_ERROR UsbErr;

    DEBUGCHK(pUsbHid != NULL);
//NKDbgPrintfW(TEXT("LINE-%d\r\n"), __LINE__);
    ValidateHidContext(pUsbHid);
//NKDbgPrintfW(TEXT("LINE-%d\r\n"), __LINE__);
    // Do we send to the endpoint or interface?
    DetermineDestination(pUsbHid, &udr.bmRequestType, &udr.wIndex);
//NKDbgPrintfW(TEXT("LINE-%d\r\n"), __LINE__);
    udr.bmRequestType |= USB_REQUEST_HOST_TO_DEVICE | USB_REQUEST_CLASS;

    udr.bRequest = USB_REQUEST_HID_SET_IDLE;
    udr.wValue   = 0; // Set infinite idle for all reports.
    udr.wLength  = 0;

    dwErr = IssueVendorTransfer(
        pUsbHid->pUsbFuncs,
        pUsbHid->hUsbDevice,
        NULL, 
        NULL,
        USB_OUT_TRANSFER,
        &udr,
        NULL,
        0,
        &dwBytesTransferred,
        INFINITE,
        &UsbErr);
//NKDbgPrintfW(TEXT("LINE-%d\r\n"), __LINE__);
    if (pUsbErr != NULL) {
        *pUsbErr = UsbErr;
    }

    // SET_IDLE is not required according to the HID spec. If it is not 
    // present, we might stall endpoint 0. If so, clear the stall feature.
    if (UsbErr == USB_STALL_ERROR) {
        ClearEndpointZeroStall(pUsbHid);
    }
//NKDbgPrintfW(TEXT("LINE-%d\r\n"), __LINE__);
    return dwErr;
}


// Generic routine to return the subkey of the form 
// pdwVals[0]_pdwVals[1]_...pdwVals[cdwVals-1].
static
HKEY 
OpenSpecificClientRegKey(
    HKEY hKeyRoot,
    const DWORD *pdwVals,
    DWORD cdwVals
    )
{
    HKEY hKeyRet = NULL;
    TCHAR szBuf[40];
    TCHAR *pszCur = szBuf;
    const TCHAR *pszKey;
    DWORD dwIdx;
    int ichWritten;

    DEBUGCHK(cdwVals * 11 + 1 < dim(szBuf));

    if (cdwVals == 0) {
        // Try default
        pszKey = DEFAULT_SZ;
    }
    else 
    {
        // Build key string
        for (dwIdx = 0; dwIdx < cdwVals; ++dwIdx) {
            ichWritten = _stprintf(pszCur, _T("%u_"), pdwVals[dwIdx]);
            pszCur += ichWritten;
        }

        *(pszCur - 1) = 0; // Remove the last _
        pszKey = szBuf;
    }

    RegOpenKey(hKeyRoot, pszKey, &hKeyRet);

    return hKeyRet;    
}


// Contains most of the logic to find and open the proper HID client key.
// The algorithm searches for the most specific vendor key of the form
// idVendor_idProduct_bcdDevice. Then its subkeys are searched for the most
// specific interface key of the form bInterface_bCollection. Then its
// subkeys are searched for the most specific top level collection key 
// of the form UsagePage_Usage.
//
// The order of vendor precedence is described below.
//
// idVendor_idProduct_bcdDevice
// idVendor_idProduct
// idVendor
// Default
//
// The order of interface precedence is described below.
//
// bInterface_bCollection
// bInterface
// Default
//
// The order of TLC precedence is 
//
// UsagePage_Usage
// UsagePage
// Default
//
// So the order of checking would be
// 1. idVendor_idProduct_bcdDevice\bInterface_bCollection\UsagePage_Usage
// 2. idVendor_idProduct_bcdDevice\bInterface_bCollection\UsagePage
// 3. idVendor_idProduct_bcdDevice\bInterface_bCollection\Default
// 4. idVendor_idProduct_bcdDevice\bInterface\UsagePage_Usage
// ...
// 7. idVendor_idProduct_bcdDevice\Default\UsagePage_Usage
// ...
// 10. idVendor_idProduct\bInterface_bCollection\UsagePage_Usage
// ...
// 42. Default\bInterface_bCollection\Default
// 43. Default\bInterface\UsagePage_Usage
// 44. Default\bInterface\UsagePage
// 45. Default\bInterface\Default
// 46. Default\Default\UsagePage_Usage
// 47. Default\Default\UsagePage
// 48. Default\Default\Default
//
static
HKEY
OpenClientRegKey(
    HKEY hKeyRoot,
    const DWORD *pdwVendorVals, 
    DWORD cdwVendorVals,
    const DWORD *pdwInterfaceVals,
    DWORD cdwInterfaceVals,
    const DWORD *pdwTLCVals,
    DWORD cdwTLCVals,
    PHID_DRIVER_SETTINGS pDriverSettingsUsed
    )
{
    SETFNAME(_T("OpenClientRegKey"));

    HKEY hKeyRet = NULL;
    HKEY hKeyVendor;
    HKEY hKeyInterface;
    INT cCurrVendor = -1;
    INT cCurrInterface = -1;
    INT cCurrTLC = -1;
    INT iIdx;

    DEBUGCHK(pdwVendorVals != NULL);
    DEBUGCHK(pdwInterfaceVals != NULL);
    DEBUGCHK(pdwTLCVals != NULL);

    for (cCurrVendor = (INT) cdwVendorVals; cCurrVendor >= 0; --cCurrVendor)
    {

⌨️ 快捷键说明

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