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

📄 hidparser.cxx

📁 wince4.2 bluetooth sdk
💻 CXX
📖 第 1 页 / 共 3 页
字号:
    if (LoadHidClients() == FALSE)
        goto EXIT;

    ForceReportProtocol();
    SetIdle();

    iErr = ERROR_SUCCESS;
    m_fIsInitialized = TRUE;


EXIT:
    if (!m_fIsInitialized)
        Deinitialize();

    return iErr;
}

void BTHHIDParser::Deinitialize()
{
    DWORD cCollections = 0;
    DWORD dwIdx;

    LockHidContextEx();
    m_UsbHid.Flags.UnloadPending = TRUE;
    ReleaseHidContextEx();

    if (m_UsbHid.hThread != NULL) 
    {
        WaitForSingleObject(m_UsbHid.hThread, INFINITE);
        CloseHandle(m_UsbHid.hThread);
    }

    if (m_UsbHid.phidpDeviceDesc != NULL) 
        cCollections = m_UsbHid.phidpDeviceDesc->CollectionDescLength;

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

    if (m_UsbHid.pClientHandles != NULL) 
    {
        // Notify each client that its device has been removed.
        for (dwIdx = 0; dwIdx < cCollections; ++dwIdx) 
        {
            PHID_CLIENT_HANDLE pHidClient = &m_UsbHid.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("Could not get client address of %s\r\n"), SZ_HID_CLIENT_NOTIFICATIONS));
                }
                else 
                {
                    __try 
                    {
                        (*lpNotifications)(HID_CLOSE_DEVICE, 0, 
                            pHidClient->lpvNotifyParameter);
                    } 
                    __except(EXCEPTION_EXECUTE_HANDLER) 
                    {
                            DEBUGMSG(ZONE_ERROR,(TEXT("Exception in notification proc\r\n")));
                    }
                }
                FreeLibrary(pHidClient->hInst);
            }
        }
        LocalFree(m_UsbHid.pClientHandles);
    }

    if (m_UsbHid.pQueues != NULL) 
        delete[] m_UsbHid.pQueues;

    if (m_UsbHid.hEP0Event != NULL) 
        CloseHandle(m_UsbHid.hEP0Event);

    if (m_UsbHid.pClientHandles != NULL) 
        LocalFree(m_UsbHid.pClientHandles);

    if (m_UsbHid.phidpDeviceDesc != NULL) 
    {
        HidP_FreeCollectionDescription(m_UsbHid.phidpDeviceDesc);
        LocalFree(m_UsbHid.phidpDeviceDesc);
    }
    
    DeleteCriticalSection(&m_UsbHid.csLock);
    ZeroMemory((void*) &m_UsbHid, sizeof(m_UsbHid));

    m_fIsInitialized = FALSE;
}

// We have data structures for each top level collection. This initializes them.
BOOL BTHHIDParser::InitializeTLCStructures()
{
    BOOL fRet = FALSE;
    DWORD cCollections;
    DWORD dwIdx;
    
    
    // Allocate our HID queues. One for each top level collection.
    cCollections = m_UsbHid.phidpDeviceDesc->CollectionDescLength;
    m_UsbHid.pQueues = new HidTLCQueue[cCollections];
    
    if (m_UsbHid.pQueues == NULL) {
        DEBUGMSG(ZONE_ERROR, (_T("Memory allocation error\r\n")));
        goto EXIT;
    }

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

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

        pClientHandle->Sig = USB_HID_CLIENT_SIG;
        pClientHandle->hInst = NULL;
        pClientHandle->lpvNotifyParameter = NULL;
        pClientHandle->pUsbHid = &m_UsbHid;
        pClientHandle->pQueue = &m_UsbHid.pQueues[dwIdx];
        pClientHandle->lpvContext = (LPVOID) this;
        pClientHandle->phidpPreparsedData = phidpCollection->PreparsedData;

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

    fRet = TRUE;

EXIT:
    return fRet;
}

// 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).
BOOL BTHHIDParser::LoadHidClients()
{
    BOOL fRet = FALSE;
    DWORD cCollections;
    DWORD dwIdx;
    DWORD dwType;
    LONG iErr;
    HID_DRIVER_SETTINGS driverSettings;

    cCollections = m_UsbHid.phidpDeviceDesc->CollectionDescLength;
    
    // this should come from SDP attributes
    memset(&driverSettings, 0, sizeof(driverSettings));

    for (dwIdx = 0; dwIdx < cCollections; ++dwIdx)
    {
        PHIDP_COLLECTION_DESC pCollection = &m_UsbHid.phidpDeviceDesc->CollectionDesc[dwIdx];
        PHID_CLIENT_HANDLE pClientHandle = &m_UsbHid.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.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("Could not enumerate subkey of LoadClient key. Error %i\r\n"), iErr));
            goto CONTINUE;
        }

        iErr = RegOpenKeyEx(hKey, szBuf, 0, 0, &hSubKey);
        if (iErr != ERROR_SUCCESS) {
            DEBUGMSG(ZONE_ERROR, (_T("Could not open subkey \"%s\"of LoadClient key. Error %i\r\n"), 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"), DLL_VALUE_SZ));
            goto CONTINUE;
        }

        hInst = LoadDriver(szBuf);
        if (hInst == NULL) {
            DEBUGMSG(ZONE_ERROR, (_T("Could not load client DLL %s\r\n"), szBuf));
            goto CONTINUE;
        }
        
        pfnAttach = (LPHID_CLIENT_ATTACH) GetProcAddress(hInst, SZ_HID_CLIENT_ATTACH);
        if (pfnAttach == NULL) {
            DEBUGMSG(ZONE_ERROR, (_T("Could not get the address of %s from %s\r\n"), 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("Exception in attach procedure %s in %s\r\n"), SZ_HID_CLIENT_ATTACH, szBuf));
        }

        if (fSuccess != TRUE) {
            DEBUGMSG(ZONE_ERROR, (_T("Failure in attach procedure %s in %s\r\n"), 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);
        }
    }

    fRet = TRUE;

//EXIT:
    return fRet;
}

void BTHHIDParser::LockHidContextEx()
{
    EnterCriticalSection(&m_UsbHid.csLock);
}

void BTHHIDParser::ReleaseHidContextEx()
{
    LeaveCriticalSection(&m_UsbHid.csLock);
}

// Return a report descriptor given the ID.
PHIDP_REPORT_IDS BTHHIDParser::GetReportDesc(PHIDP_DEVICE_DESC phidpDeviceDesc, DWORD dwReportID)
{
    PHIDP_REPORT_IDS pCurrReport = NULL;
    DWORD dwIdx;

    DEBUGCHK(phidpDeviceDesc != NULL);
    DEBUGCHK(phidpDeviceDesc->ReportIDs != NULL);
    
    for (dwIdx = 0; dwIdx < phidpDeviceDesc->ReportIDsLength; ++dwIdx)
    {
        pCurrReport = &phidpDeviceDesc->ReportIDs[dwIdx];
        DEBUGCHK(pCurrReport != NULL);
        
        if (pCurrReport->ReportID == dwReportID)
            break;
    }

    DEBUGCHK(pCurrReport != NULL);

    return pCurrReport;        
}

// Return a collection decriptor given the collection number. Also returns the
// index of the collection in the device context's array.
PHIDP_COLLECTION_DESC BTHHIDParser::GetCollectionDesc(PHIDP_DEVICE_DESC phidpDeviceDesc, DWORD dwCollectionNumber, PDWORD pdwCollectionIndex)
{
    PHIDP_COLLECTION_DESC pCurrColl = NULL;
    DWORD dwIdx;

    DEBUGCHK(phidpDeviceDesc != NULL);
    DEBUGCHK(phidpDeviceDesc->CollectionDesc != NULL);
    
    for (dwIdx = 0; dwIdx < phidpDeviceDesc->CollectionDescLength; ++dwIdx) 
    {
        pCurrColl = &phidpDeviceDesc->CollectionDesc[dwIdx];
        DEBUGCHK(pCurrColl != NULL);
        
        if (pCurrColl->CollectionNumber == dwCollectionNumber)
            break;
    }

    DEBUGCHK(pCurrColl != NULL);

    if (pdwCollectionIndex != NULL)
        *pdwCollectionIndex = dwIdx;

    return pCurrColl;        
}    

// If this report includes power events, perform them.
void BTHHIDParser::PerformPowerEvents(
    PHIDP_COLLECTION_DESC phidpCollection,
    BYTE *pbHidPacket,
    DWORD cbHidPacket
    )
{
    NTSTATUS status;
    ULONG uPowerEvents = 0;

⌨️ 快捷键说明

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