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

📄 hid.cpp

📁 cayman提供的PXA270 wince下的bsp源码包
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:  

    hid.cpp

Abstract:  
    USB Client Driver for Human Interface Device (HID) Class.

Functions:

Notes: 

--*/


#include "usbhid.h"
#include "Oemioctl.h"

#pragma warning( disable : 4100 )

#undef DEBUGMSG
#define DEBUGMSG(x,y) NKDbgPrintfW y
#undef SETFNAME
#define SETFNAME(name)          LPCTSTR pszFname = (name)

#define GET_HID_DESCRIPTOR_TIMEOUT 2000

// This is only used at initialization so the perf hit
// from a small initial size is negligible.
#define INITIAL_HID_CONTEXT_SIZE 1


// Global HID class data
CRITICAL_SECTION g_csHidLock; // Protects accesses to the following variables
BOOL g_fInitialized; // Has this global data been initialized?
PUSBHID_CONTEXT *g_rgpUsbHid; // Holds information for each HID interface
DWORD g_cpUsbHid; // Count of entries in g_rgpUsbHid
HANDLE g_hOSDevice; // The HID class device (HID0:)
#ifdef DEBUG
INT g_cInHidCS; // The current depth of g_csHidLock
#endif

// List of HID functions. Passed to HID clients.
static const HID_FUNCS g_HidFuncs =
{
    sizeof(HID_FUNCS), // DWORD dwCount;
    
    &GetReport,
    &SetReport,
    &GetInterruptReport,
};



// Helper function to close a pipe structure
static
void
ClosePipe(
    LPCUSB_FUNCS pUsbFuncs,
    PPIPE pPipe
    )
{
    DEBUGCHK(pUsbFuncs != NULL);
    DEBUGCHK(pPipe != NULL);

    if (pPipe->hPipe) {
        pUsbFuncs->lpClosePipe(pPipe->hPipe);
    }

    if (pPipe->hEvent) {
        CloseHandle(pPipe->hEvent);
    }
}


// Returns the index of the device in the global list. If not found,
// returns g_cpUsbHid.
static
DWORD
FindDeviceInList(
    PUSBHID_CONTEXT pUsbHid
    )
{
    DWORD dwSize, dwIdx;
    
    DEBUGCHK(pUsbHid != NULL);

    LockHidData();

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

    ReleaseHidData();

    return dwIdx;
}


// Is the device in the global list?
static 
BOOL
IsDeviceInList(
    PUSBHID_CONTEXT pUsbHid
    )
{
    DWORD dwIdx, dwSize;

    DEBUGCHK(pUsbHid != NULL);

    LockHidData();

    dwSize = g_cpUsbHid;
    dwIdx = FindDeviceInList(pUsbHid);

    ReleaseHidData();
    
    NKDbgPrintfW(TEXT("Hid IsDeviceInList:%d\r\n"),dwIdx);
    
    return dwIdx != dwSize;
}
    


// Removes a device from the global list.
static
void
RemoveDeviceFromList(
    PUSBHID_CONTEXT pUsbHid
    )
{
    SETFNAME(_T("RemoveDeviceFromList"));

    DWORD dwIdx;
    
    DEBUGCHK(pUsbHid != NULL);

    LockHidData();

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

    DEBUGCHK(IsDeviceInList(pUsbHid) == TRUE);
    dwIdx = FindDeviceInList(pUsbHid);
    DEBUGCHK(dwIdx != g_cpUsbHid);
    
    g_rgpUsbHid[dwIdx] = NULL;
    
    ValidateHidGlobals();
    
    ReleaseHidData();
}


// Frees all device handles and removes it from the global list.
void
RemoveDeviceContext(
   PUSBHID_CONTEXT pUsbHid
   )
{
    SETFNAME(_T("RemoveDeviceContext"));

    DWORD cCollections = 0;
    DWORD dwIdx;
    
    DEBUGCHK(pUsbHid != NULL);
    
    if (VALID_CONTEXT(pUsbHid)) {
        // Remove the device from the list if it is there.
        if (IsDeviceInList(pUsbHid) == TRUE) {
            RemoveDeviceFromList(pUsbHid);
        }
        
        // If nothing else, at least the CS was initialized.
        LockHidContext(pUsbHid);
        pUsbHid->Flags.UnloadPending = TRUE;
        ReleaseHidContext(pUsbHid);
        
        if (pUsbHid->InterruptIn.hPipe != NULL) {
            pUsbHid->pUsbFuncs->lpAbortPipeTransfers(pUsbHid->InterruptIn.hPipe, 0);
        }

        ClosePipe(pUsbHid->pUsbFuncs, &pUsbHid->InterruptIn);

        if (pUsbHid->hThread != NULL) {
            WaitForSingleObject(pUsbHid->hThread, INFINITE);
            CloseHandle(pUsbHid->hThread);
        }

        if (pUsbHid->phidpDeviceDesc != NULL) {
            cCollections = pUsbHid->phidpDeviceDesc->CollectionDescLength;
        }

        if (pUsbHid->pQueues != NULL)
        {
            // Tell each queue that it is closing.
            for (dwIdx = 0; dwIdx < cCollections; ++dwIdx) 
            {
                HidTLCQueue *pQueue = &pUsbHid->pQueues[dwIdx];
                if (pQueue->IsInitialized() == TRUE) {
                    pQueue->Close();
                }
            }
        }

        if (pUsbHid->pClientHandles != NULL) {
            // Notify each client that its device has been removed.
            for (dwIdx = 0; dwIdx < cCollections; ++dwIdx) {
                PHID_CLIENT_HANDLE pHidClient = &pUsbHid->pClientHandles[dwIdx];
                if (pHidClient->hInst != NULL) {
                    LPHID_CLIENT_NOTIFICATIONS lpNotifications;

                    lpNotifications = (LPHID_CLIENT_NOTIFICATIONS) 
                        GetProcAddress(pHidClient->hInst, SZ_HID_CLIENT_NOTIFICATIONS);

                    if (lpNotifications == NULL) {
                        DEBUGMSG(ZONE_ERROR, (_T("%s: Could not get client address of %s\r\n"),
                            pszFname, SZ_HID_CLIENT_NOTIFICATIONS));
                    }
                    else 
                    {
                        __try {
                            (*lpNotifications)(HID_CLOSE_DEVICE, 0, 
                                pHidClient->lpvNotifyParameter);
                        } 
                        __except(EXCEPTION_EXECUTE_HANDLER) {
                              DEBUGMSG(ZONE_ERROR,(TEXT("%s: Exception in notification proc\r\n"),pszFname));
                        }
                    }

					FreeLibrary(pHidClient->hInst);
                }
            }

            HidFree(pUsbHid->pClientHandles);
        }

        if (pUsbHid->pQueues != NULL) delete [] pUsbHid->pQueues;

        if (pUsbHid->hEP0Event != NULL) CloseHandle(pUsbHid->hEP0Event);

        if (pUsbHid->phidpDeviceDesc != NULL) {
            HidP_FreeCollectionDescription(pUsbHid->phidpDeviceDesc);
            HidFree(pUsbHid->phidpDeviceDesc);
        }
        
        DeleteCriticalSection(&pUsbHid->csLock);

        HidFree(pUsbHid);
    } 
    else {
        DEBUGMSG(ZONE_ERROR, (TEXT("%s: Invalid Parameter\r\n"), pszFname));
        DEBUGCHK(FALSE);
    }
}


// Initialize the global data if not already initialized.
BOOL
InitializeGlobalHidData(
    )
{
    SETFNAME(_T("InitializeGlobalHidData"));
    const DWORD cpUsbHid = INITIAL_HID_CONTEXT_SIZE;
    const TCHAR * const pszClientKey = CLIENT_REGKEY_SZ;
    BOOL fRet = FALSE;

    LockHidData();

    // Only initialize if we have not done so already.
    if (g_fInitialized == FALSE)
    {
        ValidateHidGlobals();

        g_rgpUsbHid = (PUSBHID_CONTEXT*) HidAlloc(HID_ARRAY_BYTE_SIZE(cpUsbHid));

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

        
        ZeroMemory(g_rgpUsbHid, HID_ARRAY_BYTE_SIZE(cpUsbHid));
        g_cpUsbHid = cpUsbHid;
        g_hOSDevice = ActivateDevice(pszClientKey, 0);

        if (g_hOSDevice == NULL) {
            DEBUGMSG(ZONE_ERROR, (_T("%s: Error on ActivateDevice(%s)\r\n"), pszFname, pszClientKey));
            goto EXIT;
        }

        // Finally we are totally initialized
        g_fInitialized = TRUE;
    }

    fRet = TRUE;

EXIT:
    if (fRet == FALSE) 
    {
        // Clean up allocated memory.
        DEBUGCHK(g_fInitialized == FALSE);
        DEBUGCHK(g_hOSDevice == NULL);
        
        if (g_rgpUsbHid != NULL) HidFree(g_rgpUsbHid);
        g_rgpUsbHid = NULL;
        g_cpUsbHid = 0;
    }
    NKDbgPrintfW(TEXT("Hid InitializeGlobalHidData Fail\r\n"));
    ReleaseHidData();
    ValidateHidGlobals();   
    
    return fRet;
}


// Frees the global HID data if there are no remaining devices.
void
FreeGlobalHidData(
    )
{
    DWORD dwSize, dwIdx;
    
    LockHidData();

    ValidateHidGlobals();

    if (g_fInitialized == TRUE)
    {
        // Are there any remaining HID devices?
        dwSize = g_cpUsbHid;
        for (dwIdx = 0; dwIdx < dwSize; ++dwIdx) {
            if (g_rgpUsbHid[dwIdx] != NULL) {
                break;
            }
        }

        if (dwIdx == dwSize) 
        {
            // No, free all global data.
            DeactivateDevice(g_hOSDevice);
            g_hOSDevice = NULL;
            HidFree(g_rgpUsbHid);
            g_rgpUsbHid = NULL;
            g_cpUsbHid = 0;
            g_fInitialized = FALSE;
        }
    }

    ValidateHidGlobals();
    
    ReleaseHidData();
}


// Returns the interface to use.
LPCUSB_INTERFACE
ParseUsbDescriptors(
    USB_HANDLE hUsbDevice,
    LPCUSB_FUNCS pUsbFuncs,
    LPCUSB_INTERFACE pCurrInterface
    )
{
    SETFNAME(_T("ParseUsbDescriptors"));

    LPCUSB_INTERFACE pHidInterface = NULL;

    DEBUGMSG(ZONE_INIT, (_T("+%s"), pszFname));

    DEBUGCHK(pUsbFuncs != NULL);
    DEBUGCHK(pCurrInterface != NULL);
    
    if (pCurrInterface != NULL) 
    {        
        // If loaded as an interface driver, ignore non HID interfaces
        if (pCurrInterface->Descriptor.bInterfaceClass != USB_DEVICE_CLASS_HUMAN_INTERFACE) {
            DEBUGMSG(ZONE_INIT, (TEXT("%s: DeviceAttach, ignoring non HID interface class %u\r\n"),
                pszFname, pCurrInterface->Descriptor.bInterfaceClass));
        }
        else {
            pHidInterface = pCurrInterface;
        }
    }

    DEBUGMSG(ZONE_INIT, (_T("-%s"), pszFname));
    return pHidInterface;
}


// Get the report descriptor from the device.
static
BOOL
GetReportDescriptor(
    PUSBHID_CONTEXT pUsbHid,
    USHORT uReportDescriptorLength

⌨️ 快捷键说明

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