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

📄 hid.cpp

📁 cayman提供的PXA270 wince下的bsp源码包
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        }
    }
    else {
        pUsbHid->fSendToInterface = TRUE;
    }

    DUMP_USB_HID_DESCRIPTOR((*pHidDescriptor));

    pUsbHid->pUsbFuncs = pUsbFuncs;

    pUsbHid->Flags.Open = FALSE;
    pUsbHid->Flags.UnloadPending = FALSE;

    // set the USB interface/pipes
    if (SetUsbInterface(pUsbHid) == FALSE) {
        DEBUGMSG(ZONE_ERROR, (_T("%s: SetUsbInterface failed!\r\n"), pszFname));
        goto EXIT;
    }

    // create endpoint 0 event
    pUsbHid->hEP0Event = CreateEvent(NULL, MANUAL_RESET_EVENT, FALSE, NULL);
    if (pUsbHid->hEP0Event == NULL) {
        DEBUGMSG(ZONE_ERROR, (TEXT("%s: CreateEvent error:%d\r\n"), pszFname, GetLastError()));
        goto EXIT;
    }

    // Get the report descriptor for our interface.
    if (GetReportDescriptor(pUsbHid, pHidDescriptor->wDescriptorLength) == FALSE) {
        goto EXIT;
    }

    // Set up our data structres for each top level collection.
    if (InitializeTLCStructures(pUsbHid) == FALSE) {
        goto EXIT;
    }

    // Create the thread that receives the data from the device.
    if (CreateInterruptThread(pUsbHid) == FALSE) {
        goto EXIT;
    }

    ValidateHidContext(pUsbHid);
    
//    NKDbgPrintfW(TEXT("Before LoadHidClients\r\n"));
    
    // Load client drivers for our top level collections
    if (LoadHidClients(pUsbHid) == FALSE) {
        goto EXIT;
    }

//    NKDbgPrintfW(TEXT("After LoadHidClients\r\n"));
    
    // Mouse and keyboard HID devices might have a boot protocol that can be 
    // used at boot time. We never use the boot protocol and the devices
    // should default to the standard report format, but they are not 
    // guaranteed to. Therefore, we will manually set the report protocol here.
    if (pUsbInterface->Descriptor.bInterfaceSubClass == HID_INTERFACE_BOOT_SUBCLASS) {
        SetReportProtocol(pUsbHid);
    }
//NKDbgPrintfW(TEXT("SetReportProtocol\r\n"));
    // According to the HID spec, keyboards are set to idle 500 ms before 
    // sending an empty report. We want infinite idling.
//    SetIdle(pUsbHid, NULL);
//NKDbgPrintfW(TEXT("SetIdle\r\n"));    
    // Set this device to wake the system if applicable. We don't care if it fails.
    if (pDeviceInfo->lpActiveConfig->Descriptor.bmAttributes & USB_CONFIG_REMOTE_WAKEUP) {
//        EnableRemoteWakeup(pUsbHid);
    }
//NKDbgPrintfW(TEXT("EnableRemoteWakeup\r\n"));
    // We can now start our interrupt thread.
    ResumeThread(pUsbHid->hThread);
//NKDbgPrintfW(TEXT("ResumeThread\r\n"));
    fErr = FALSE;

EXIT:
    if ((fErr == TRUE) && (pUsbHid != NULL)) {
        RemoveDeviceContext(pUsbHid);
		pUsbHid = NULL;
    }
    NKDbgPrintfW(TEXT("Hid CreateHidDevice:%d\r\n"),GetLastError());
    DEBUGMSG(ZONE_INIT, (_T("-%s\r\n"), pszFname));
    return pUsbHid;
}


// Receives the interrupt reports from the device
static
DWORD
WINAPI
InterruptThreadProc(
    LPVOID lpParameter
    )
{
    SETFNAME(_T("InterruptThreadProc"));

    PUSBHID_CONTEXT pUsbHid = (PUSBHID_CONTEXT) lpParameter;
    BOOL fNoReportID;
    DWORD dwBytesTransferred;
    DWORD dwErr;
    USB_ERROR usbError;
    PBYTE pbDataBuffer = NULL, pbToTransfer;
    DWORD cbBuffer, cbToTransfer;
    BOOL fUnloadPending = FALSE;

    DEBUGCHK(pUsbHid != NULL);
    ValidateHidContext(pUsbHid);

	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);

    cbBuffer = cbToTransfer = pUsbHid->InterruptIn.wMaxPacketSize;

    // If there is only one report for an interface, including the report ID
    // at the start of each report is optional. We need to know whether
    // a report is coming or not, because when we hand off the report
    // a report ID must be included.
    fNoReportID = (pUsbHid->phidpDeviceDesc->ReportIDs[0].ReportID == 0);
    if (fNoReportID == TRUE) {
        // We will always include the report ID so add another byte for it.
        ++cbBuffer;
    }

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

    if (fNoReportID == TRUE) {
        // Leave the starting byte empty for the ID of 0
        pbDataBuffer[0] = 0;
        ++pbToTransfer;
    }
    
    while (fUnloadPending == FALSE)
    {    
#ifdef DEBUG
        FillMemory(pbToTransfer, cbToTransfer, 0xCC);
#endif

        dwErr = IssueInterruptTransfer(
            pUsbHid->pUsbFuncs, 
            pUsbHid->InterruptIn.hPipe, 
            DefaultTransferComplete, 
            pUsbHid->InterruptIn.hEvent, 
            USB_IN_TRANSFER | USB_SHORT_TRANSFER_OK,
            pbToTransfer,
            NULL,
            cbToTransfer,
            &dwBytesTransferred,
            INFINITE,
            &usbError
            );

        if ( (usbError == USB_DEVICE_NOT_RESPONDING_ERROR) || 
             (dwErr == ERROR_GEN_FAILURE) ) 
        {
            // Device has been unplugged. Allow time for USBDeviceNotifications
            // to get the news.
            Sleep(25);
        }

        if ((dwErr == ERROR_SUCCESS) && (usbError == USB_NO_ERROR)) 
        {
            // All is good. Send off the report.
            if (fNoReportID == TRUE) {
                // Increment the count of bytes transferred to include the ID.
                DEBUGCHK(pbDataBuffer[0] == 0);
                ++dwBytesTransferred;
            }
            
            ProcessReport(pUsbHid, pbDataBuffer, dwBytesTransferred);
        }

        fUnloadPending = pUsbHid->Flags.UnloadPending;
    }

EXIT:
    if (pbDataBuffer) HidFree(pbDataBuffer);

    return 0;
}


// Create the thread that will receive the device's interrupt data
BOOL
CreateInterruptThread(
    PUSBHID_CONTEXT pUsbHid
    )
{
    SETFNAME(_T("CreateInterruptThread"));

    BOOL fRet = FALSE;
    
    DEBUGCHK(pUsbHid != NULL);
	DEBUGCHK(VALID_CONTEXT(pUsbHid));

    pUsbHid->hThread = CreateThread(NULL, 0, InterruptThreadProc, pUsbHid, CREATE_SUSPENDED, NULL);

    if (pUsbHid->hThread == NULL) {
        DEBUGMSG(ZONE_ERROR, (TEXT("%s: CreateThread error:%d\r\n"), pszFname, GetLastError()));
        goto EXIT;
    }
    else
    {
        ThreadInfo TI;
        TI.ThreadHandle = pUsbHid->hThread;
        strcpy((char *)TI.ThreadName, "USB InterruptThreadProc");
        KernelIoControl(IOCTL_SET_THREAD, (LPVOID)&TI, sizeof(ThreadInfo), NULL, 0, NULL);
    }
    fRet = TRUE;

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


// Adds a new device to the list of HID devices. On failure, the list is
// in the original state.
BOOL
AddDeviceToList(
    PUSBHID_CONTEXT pUsbHid
    )
{
    SETFNAME(_T("AddDeviceToList"));
    BOOL fRet = FALSE;
    DWORD dwSize, dwIdx;
    PUSBHID_CONTEXT *rgpUsbHid;

    DEBUGCHK(pUsbHid != NULL);

    LockHidData();

    DEBUGCHK(g_fInitialized == TRUE);
    ValidateHidGlobals();

    dwSize = g_cpUsbHid;
    for (dwIdx = 0; dwIdx < dwSize; ++dwIdx) {
        if (g_rgpUsbHid[dwIdx] == NULL) {
            break;
        }
    }

    if (dwIdx == dwSize) 
    {
        // Time to enlarge the array
        dwSize *= 2;
        rgpUsbHid = (PUSBHID_CONTEXT*) HidReAlloc(g_rgpUsbHid, 
            HID_ARRAY_BYTE_SIZE(dwSize), LMEM_ZEROINIT | LMEM_MOVEABLE);
        if (rgpUsbHid == NULL) {
            DEBUGMSG(ZONE_ERROR, (TEXT("%s: LocalAlloc error:%d\r\n"), pszFname, GetLastError()));
            goto EXIT;
        }

        g_rgpUsbHid = rgpUsbHid;
        g_cpUsbHid = dwSize;
        
        ValidateHidGlobals();
    }

    DEBUGCHK(dwIdx < g_cpUsbHid);
    g_rgpUsbHid[dwIdx] = pUsbHid;        

    fRet = TRUE;
    
EXIT:
    ValidateHidGlobals();
    ReleaseHidData();

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


//
// ***** HID Stream Interface *****
//

#define HID_DEVICE_CONTEXT_HANDLE 0xCAFE

#ifdef DEBUG
static DWORD g_dwInitCount = 0;
#endif

extern "C" 
DWORD
HID_Init (DWORD dwCtx)
{
#ifdef DEBUG
    // Be sure that only one instance of this DLL is initialized.
    DEBUGCHK(g_dwInitCount == 0);
    ++g_dwInitCount;
#endif
   
   return HID_DEVICE_CONTEXT_HANDLE;
}

extern "C" 
BOOL
HID_Deinit (DWORD dwCtx)
{
#ifdef DEBUG
    // Be sure that only one instance of this DLL is initialized.
    DEBUGCHK(g_dwInitCount == 1);
    --g_dwInitCount;
#endif

    return dwCtx == HID_DEVICE_CONTEXT_HANDLE;
}

extern "C" 
DWORD
HID_Open (DWORD dwCtx, DWORD dwAccMode, DWORD dwShrMode)
{
    SETFNAME(_T("HID_Open"));
    
    DWORD dwRet = 0;

    LockHidData();
    
    if (dwCtx == HID_DEVICE_CONTEXT_HANDLE) 
    {
        if (g_fInitialized == FALSE) {
            DEBUGMSG(ZONE_ERROR, (_T("%s: ERROR_ACCESS_DENIED\r\n"), pszFname));
            SetLastError(ERROR_ACCESS_DENIED);
            goto EXIT;
        }
    }
    else {
        DEBUGMSG(ZONE_ERROR, (_T("%s: ERROR_FILE_NOT_FOUND\r\n"), pszFname));
        SetLastError(ERROR_FILE_NOT_FOUND);
        goto EXIT;
    }        

    dwRet = HID_DEVICE_CONTEXT_HANDLE;

EXIT:
    ReleaseHidData();
    NKDbgPrintfW(TEXT("Hid Open Fail:%d\r\n"),GetLastError());
    return dwRet;
}

extern "C" 
BOOL
HID_Close (DWORD dwCtx)
{
    SETFNAME(_T("HID_Close"));

    BOOL fRet = FALSE;

    if (dwCtx != HID_DEVICE_CONTEXT_HANDLE) {
        DEBUGMSG(ZONE_ERROR, (_T("%s: ERROR_INVALID_HANDLE\r\n"), pszFname));
        SetLastError(ERROR_INVALID_HANDLE);
        goto EXIT;
    }

    fRet = TRUE;

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

extern "C" 
DWORD
HID_Read (DWORD,LPVOID,DWORD)
{
   SetLastError(ERROR_NOT_SUPPORTED);
   return -1;
}

extern "C" 
DWORD
HID_Write (DWORD,LPCVOID,DWORD)
{
   SetLastError(ERROR_NOT_SUPPORTED);
   return -1;
}

extern "C" 
DWORD
HID_Seek (DWORD,long,DWORD)
{
   SetLastError(ERROR_NOT_SUPPORTED);
   return -1;
}

extern "C" 
BOOL
HID_IOControl (DWORD dwCtx, DWORD dwCode,
               PBYTE pInpBuf, DWORD dwInpLen,
               PBYTE pOutBuf, DWORD dwOutLen, PDWORD pdwActualOutLen)
{
    SETFNAME(_T("HID_IOControl"));

    BOOL fRet = FALSE;
    
    if (dwCtx != HID_DEVICE_CONTEXT_HANDLE) {
        DEBUGMSG(ZONE_ERROR, (_T("%s: ERROR_INVALID_HANDLE\r\n"), pszFname));
        SetLastError(ERROR_INVALID_HANDLE);
        goto EXIT;
    }

    // No supported HID IOControl values
    DEBUGMSG(ZONE_ERROR, (_T("%s(0x%x) ERROR_NOT_SUPPORTED\r\n"), pszFname));
    SetLastError(ERROR_NOT_SUPPORTED);

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

⌨️ 快捷键说明

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