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

📄 hid.cpp

📁 cayman提供的PXA270 wince下的bsp源码包
💻 CPP
📖 第 1 页 / 共 4 页
字号:
        hKeyVendor = OpenSpecificClientRegKey(hKeyRoot, pdwVendorVals, cCurrVendor);
        if (hKeyVendor != NULL)
        {
            for (cCurrInterface = (INT) cdwInterfaceVals; 
                 cCurrInterface >= 0; 
                 --cCurrInterface)
            {
                hKeyInterface = OpenSpecificClientRegKey(hKeyVendor, pdwInterfaceVals, cCurrInterface);
                if (hKeyInterface != NULL)
                {
                    for (cCurrTLC = (INT) cdwTLCVals; cCurrTLC >= 0; --cCurrTLC)
                    {
                        hKeyRet = OpenSpecificClientRegKey(hKeyInterface, pdwTLCVals, cCurrTLC);
                        if (hKeyRet != NULL) {
                            // We found our key
                            break;
                        }
                    }
                    
                    RegCloseKey(hKeyInterface);

                    if (hKeyRet != NULL) {
                        // We found our key
                        break;
                    }
                } 
            }

            RegCloseKey(hKeyVendor);

            if (hKeyRet != NULL) {
                // We found our key.
                break;
            }
        }
    }

    if (hKeyRet != NULL) {
        // We found a match. Fill in the driver settings used.
        PDWORD rgpdwDriverSettings[] = {
            &pDriverSettingsUsed->dwVendorId,
            &pDriverSettingsUsed->dwProductId,
            &pDriverSettingsUsed->dwReleaseNumber,
            &pDriverSettingsUsed->dwInterfaceNumber,
            &pDriverSettingsUsed->dwCollection,
            &pDriverSettingsUsed->dwUsagePage,
            &pDriverSettingsUsed->dwUsage,
        };

        // Fill in the matching vendor info
        for (iIdx = 0; iIdx < cCurrVendor; ++iIdx) {
            *rgpdwDriverSettings[iIdx] = pdwVendorVals[iIdx];
        }

        // Fill in the matching interface info
        for (iIdx = 0; iIdx < cCurrInterface; ++iIdx) {
            *rgpdwDriverSettings[iIdx + cdwVendorVals] = pdwInterfaceVals[iIdx];
        }

        // Fill in the matching TLC info
        for (iIdx = 0; iIdx < cCurrTLC; ++iIdx) {
            *rgpdwDriverSettings[iIdx + cdwVendorVals + cdwInterfaceVals] 
                = pdwTLCVals[iIdx];
        }
    }

    return hKeyRet;
}


// Get the registry key for the HID client that will best service the device
// descripted in pDriverSettings.
// Returns the registry key and the actual driver settings that matched the key.
static
HKEY
FindClientRegKey(
    const HID_DRIVER_SETTINGS *pDriverSettings,
    PHID_DRIVER_SETTINGS pDriverSettingsUsed
    )
{
    SETFNAME(_T("FindClientRegKey"));

    const DWORD rgdwVendorVals[] = { 
        pDriverSettings->dwVendorId, 
        pDriverSettings->dwProductId, 
        pDriverSettings->dwReleaseNumber 
        };
    const DWORD rgdwInterfaceVals[] = { 
        pDriverSettings->dwInterfaceNumber,
        pDriverSettings->dwCollection
        };
    const DWORD rgdwTLCVals[] = { 
        pDriverSettings->dwUsagePage, 
        pDriverSettings->dwUsage 
        };

    HKEY hKeyRoot = NULL;
    HKEY hKeyRet = NULL;
    LONG iErr;

    DEBUGCHK(pDriverSettings != NULL);
    DEBUGCHK(pDriverSettingsUsed != NULL);
    
    memset(pDriverSettingsUsed, (BYTE) HID_NO_INFO, sizeof(HID_DRIVER_SETTINGS));

    iErr = RegOpenKey(HKEY_LOCAL_MACHINE, LOAD_CLIENTS_PATH_SZ, &hKeyRoot);
    if (iErr != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_ERROR, (_T("%s: Failed opening HID client key [HKLM\\%s]\r\n"),
            pszFname, LOAD_CLIENTS_PATH_SZ));
        goto EXIT;
    }

    // Now find the most specific match.
    hKeyRet = OpenClientRegKey(hKeyRoot, 
        rgdwVendorVals, dim(rgdwVendorVals), 
        rgdwInterfaceVals, dim(rgdwInterfaceVals),
        rgdwTLCVals, dim(rgdwTLCVals), 
        pDriverSettingsUsed);
    
    if (hKeyRet == NULL) {
        DEBUGMSG(ZONE_WARNING, (_T("%s: Could not find a suitable HID client driver\r\n"), pszFname));
        goto EXIT;
    }

EXIT:
    if (hKeyRoot != NULL) RegCloseKey(hKeyRoot);
    NKDbgPrintfW(TEXT("Hid FindClientRegKey Fail:%d\r\n"),GetLastError());
    return hKeyRet;
}


// Load a HID client for each top level collection, if possible.
// Returns FALSE if there was a major error. Returns TRUE even
// if certain TLC's do not have clients. This is not an error
// because internal processing will still be performed on unhandled
// reports (like power events).
static
BOOL
LoadHidClients(
    PUSBHID_CONTEXT pUsbHid
    )
{
    SETFNAME(_T("LoadHidClients"));

    BOOL fRet = FALSE;
    PCUSB_DEVICE pDeviceInfo; 
    DWORD cCollections;
    DWORD dwIdx;
    DWORD dwType;
    LONG iErr;
    HID_DRIVER_SETTINGS driverSettings;
    
    DEBUGCHK(pUsbHid != NULL);
    ValidateHidContext(pUsbHid);

    cCollections = pUsbHid->phidpDeviceDesc->CollectionDescLength;
    pDeviceInfo = pUsbHid->pUsbFuncs->lpGetDeviceInfo(pUsbHid->hUsbDevice);
    
    if (pDeviceInfo == NULL) {
        DEBUGMSG(ZONE_ERROR, (_T("%s: Failure getting USB device info\r\n"), pszFname));
        goto EXIT;
    }

    driverSettings.dwVendorId = pDeviceInfo->Descriptor.idVendor;
    driverSettings.dwProductId = pDeviceInfo->Descriptor.idProduct;
    driverSettings.dwReleaseNumber = pDeviceInfo->Descriptor.bcdDevice; 
    driverSettings.dwInterfaceNumber = 
        pUsbHid->pUsbInterface->Descriptor.bInterfaceNumber;

    for (dwIdx = 0; dwIdx < cCollections; ++dwIdx)
    {
        PHIDP_COLLECTION_DESC pCollection = &pUsbHid->phidpDeviceDesc->CollectionDesc[dwIdx];
        PHID_CLIENT_HANDLE pClientHandle = &pUsbHid->pClientHandles[dwIdx];
        TCHAR szBuf[MAX_PATH];
        DWORD cchBuf = dim(szBuf);
        HKEY hKey;
        HKEY hSubKey = NULL;
        HINSTANCE hInst = NULL;
        LPHID_CLIENT_ATTACH pfnAttach;
        BOOL fSuccess = FALSE;

        DEBUGCHK(pClientHandle->hInst == NULL);
        DEBUGCHK(pClientHandle->pQueue != NULL);

        driverSettings.dwCollection = pCollection->CollectionNumber;
        driverSettings.dwUsagePage = pCollection->UsagePage;
        driverSettings.dwUsage = pCollection->Usage;

        hKey = FindClientRegKey(&driverSettings, &pClientHandle->driverSettings);

        if (hKey == NULL) {
            // No match for top level collection. Just continue.
            goto CONTINUE;
        }
        
        iErr = RegEnumKeyEx(hKey, 0, szBuf, &cchBuf, NULL, NULL, NULL, NULL);
        if (iErr != ERROR_SUCCESS) {
            DEBUGMSG(ZONE_ERROR, (_T("%s: Could not enumerate subkey of LoadClient key. Error %i\r\n"),
                pszFname, iErr));
            goto CONTINUE;
        }

        iErr = RegOpenKey(hKey, szBuf, &hSubKey);
        if (iErr != ERROR_SUCCESS) {
            DEBUGMSG(ZONE_ERROR, (_T("%s: Could not open subkey \"%s\"of LoadClient key. Error %i\r\n"),
                pszFname, szBuf, iErr));
            goto CONTINUE;
        }

        cchBuf = dim(szBuf);
        iErr = RegQueryValueEx(hSubKey, DLL_VALUE_SZ, NULL, &dwType, (PBYTE) szBuf, &cchBuf);
        if (iErr != ERROR_SUCCESS || dwType != REG_SZ) {
            DEBUGMSG(ZONE_ERROR, (_T("s: Could not get %s value in LoadClient key.\r\n"),
                pszFname, DLL_VALUE_SZ));
            goto CONTINUE;
        }

        hInst = LoadDriver(szBuf);
        if (hInst == NULL) {
            DEBUGMSG(ZONE_ERROR, (_T("%s: Could not load client DLL %s\r\n"), pszFname, szBuf));
            goto CONTINUE;
        }
        
        pfnAttach = (LPHID_CLIENT_ATTACH) GetProcAddress(hInst, SZ_HID_CLIENT_ATTACH);
        if (pfnAttach == NULL) {
            DEBUGMSG(ZONE_ERROR, (_T("%s: Could not get the address of %s from %s\r\n"),
                pszFname, SZ_HID_CLIENT_ATTACH, szBuf));
            goto CONTINUE;
        }

        __try {
            fSuccess = (*pfnAttach)(
                (HID_HANDLE) pClientHandle,
                &g_HidFuncs, 
                &pClientHandle->driverSettings,
                pCollection->PreparsedData,
                &pClientHandle->lpvNotifyParameter,
                0);
        }
        __except(EXCEPTION_EXECUTE_HANDLER) {
            DEBUGMSG(ZONE_ERROR, (_T("%s: Exception in attach procedure %s in %s\r\n"),
                pszFname, SZ_HID_CLIENT_ATTACH, szBuf));
        }

        if (fSuccess != TRUE) {
            DEBUGMSG(ZONE_INIT, (_T("%s: Failure in attach procedure %s in %s\r\n"),
                pszFname, SZ_HID_CLIENT_ATTACH, szBuf));
            goto CONTINUE;
        }

        // Turn on this client's queue.
        pClientHandle->pQueue->AcceptNewReports(TRUE);

        // Finally this client has been initialized. Save our hInst.
        pClientHandle->hInst = hInst;
        
CONTINUE:
        if (hKey != NULL) RegCloseKey(hKey);
        if (hSubKey != NULL) RegCloseKey(hSubKey);
        if (pClientHandle->hInst == NULL) {
            // We did not successfully initialize the client.
            if (hInst != NULL) FreeLibrary(hInst);

            DEBUGMSG(ZONE_INIT, (_T("%s: No client found for HID top level collection 0x%X-0x%X on interface 0x%X\r\n"),
                pszFname, pCollection->UsagePage, pCollection->Usage, 
                pUsbHid->pUsbInterface->Descriptor.bInterfaceNumber));
        }
    }

    fRet = TRUE;

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


// We have data structures for each top level collection. This initializes them.
static
BOOL
InitializeTLCStructures(
    PUSBHID_CONTEXT pUsbHid
    )
{
    SETFNAME(_T("InitializeTLCStructures"));

    BOOL fRet = FALSE;
    DWORD cCollections;
    DWORD dwIdx;
    
    DEBUGCHK(pUsbHid != NULL);
    
    // Allocate our HID queues. One for each top level collection.
    cCollections = pUsbHid->phidpDeviceDesc->CollectionDescLength;
    pUsbHid->pQueues = new HidTLCQueue[cCollections];
    
    if (pUsbHid->pQueues == NULL) {
        DEBUGMSG(ZONE_ERROR, (_T("%s: Memory allocation error\r\n"), pszFname));
        goto EXIT;
    }

    // Allocate our HID client handles. One for each TLC.
    pUsbHid->pClientHandles = (PHID_CLIENT_HANDLE) HidAlloc(sizeof(HID_CLIENT_HANDLE) * cCollections);
    if (pUsbHid->pClientHandles == NULL) {
        DEBUGMSG(ZONE_ERROR, (_T("%s: LocalAlloc error:%d\r\n"), pszFname, GetLastError()));
        goto EXIT;
    }

    // Initialize our HID queues and client handles.
    for (dwIdx = 0; dwIdx < cCollections; ++dwIdx) 
    {        
        BOOL fSucceeded;
        PHIDP_COLLECTION_DESC phidpCollection = &pUsbHid->phidpDeviceDesc->CollectionDesc[dwIdx];
        PHID_CLIENT_HANDLE pClientHandle = &pUsbHid->pClientHandles[dwIdx];
        
        fSucceeded = pUsbHid->pQueues[dwIdx].Initialize(
            HID_TLC_QUEUE_DEFAULT_CAPACITY, 
            phidpCollection->InputLength);

        pClientHandle->Sig = USB_HID_CLIENT_SIG;
        pClientHandle->hInst = NULL;
        pClientHandle->lpvNotifyParameter = NULL;
        pClientHandle->pUsbHid = pUsbHid;
        pClientHandle->pQueue = &pUsbHid->pQueues[dwIdx];
        pClientHandle->phidpPreparsedData = phidpCollection->PreparsedData;

        if (fSucceeded == FALSE) {
            DEBUGMSG(ZONE_ERROR, (_T("%s: Failed initializing queue\r\n"), pszFname));
            goto EXIT;
        }
    }

    fRet = TRUE;

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


// Creates and returns the HID device context.
// Returns NULL if error.
PUSBHID_CONTEXT
CreateHidDevice(
    USB_HANDLE hUsbDevice,
    PCUSB_FUNCS pUsbFuncs,
    PCUSB_INTERFACE pUsbInterface
    )
{
    SETFNAME(_T("CreateHidInterface"));
    PUSBHID_CONTEXT pUsbHid = NULL;
    BOOL fErr = TRUE;
    PCUSB_DEVICE pDeviceInfo = NULL;
    PHID_DESCRIPTOR pHidDescriptor = NULL;
    PCUSB_ENDPOINT pEndpoint = NULL;

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

    DEBUGCHK(pUsbFuncs != NULL);
    DEBUGCHK(pUsbInterface != NULL);

    pDeviceInfo = (*pUsbFuncs->lpGetDeviceInfo)(hUsbDevice);
    if (pDeviceInfo == NULL) {
        DEBUGMSG(ZONE_ERROR, (_T("%s: Failure getting USB device info\r\n"), pszFname));
        goto EXIT;
    }

    DUMP_USB_DEVICE_DESCRIPTOR(pDeviceInfo->Descriptor);
    DUMP_USB_CONFIGURATION_DESCRIPTOR(pDeviceInfo->lpActiveConfig->Descriptor);

    pUsbHid = (PUSBHID_CONTEXT)HidAlloc(sizeof(USBHID_CONTEXT));
    if (pUsbHid == NULL) {
        DEBUGMSG(ZONE_ERROR, (TEXT("%s: LocalAlloc error:%d\r\n"), pszFname, GetLastError()));
        goto EXIT;
    }

    ZeroMemory(pUsbHid, sizeof(USBHID_CONTEXT));

    pUsbHid->Sig = USB_HID_SIG;
    InitializeCriticalSection(&pUsbHid->csLock);
    pUsbHid->hUsbDevice = hUsbDevice;
    pUsbHid->pUsbInterface = pUsbInterface;

    DUMP_USB_INTERFACE_DESCRIPTOR(pUsbHid->pUsbInterface->Descriptor, 
        pUsbHid->pUsbInterface->Descriptor.bInterfaceNumber);

    if (pUsbInterface->lpEndpoints == NULL) {
        DEBUGMSG(ZONE_ERROR,(TEXT("%s: Missing endpoint descriptors\r\n"), pszFname));
        goto EXIT;
    }
    pEndpoint = &pUsbInterface->lpEndpoints[0];
    DEBUGCHK(pEndpoint != NULL);
    
    // Regarding bSendToInterface.  The original HID spec said that the Hid
    // descriptor would come after the interface and endpoint descriptors.
    // It also said that class specific commands should be sent to the endpoint.
    // The next spec said that the HID descriptor would come after the interface
    // descriptor (not at the end) and that commands should be sent to the
    // interface, not to the endpoint.  So, I'm assuming that if I find the
    // Hid descriptor after the interface, the device is following the new spec
    // and I should send commands to the interface.  Otherwise, I'll send them
    // to the endpoint, as stated in the old spec.
    pHidDescriptor = (PHID_DESCRIPTOR) pUsbInterface->lpvExtended;
    
    if (pHidDescriptor == NULL) {
        pHidDescriptor = (PHID_DESCRIPTOR) pUsbInterface->lpEndpoints->lpvExtended;
        if (pHidDescriptor == NULL) {
            DEBUGMSG(ZONE_ERROR, (_T("%s: Missing HID descriptor\r\n"), pszFname));
            goto EXIT;
        }
        else {
            pUsbHid->fSendToInterface = FALSE;

⌨️ 快捷键说明

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