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

📄 hidmdd.cpp

📁 hidclass source code for windows ce use
💻 CPP
📖 第 1 页 / 共 3 页
字号:
}


// Notifies the MDD of device changes.
BOOL
WINAPI
HidMdd_Notifications(
    DWORD  dwMsg,
    WPARAM wParam,    
    PVOID  pvNotifyParameter
    )
{
    SETFNAME(_T("HidMdd_Notifications"));
    
    BOOL fRet = FALSE;
    PHID_CONTEXT pHidContext = (PHID_CONTEXT) pvNotifyParameter;

    UNREFERENCED_PARAMETER(wParam);

    ValidateHidContext(pHidContext);
    
    switch(dwMsg) {
        case HID_MDD_CLOSE_DEVICE:
            FreeHidContext(pHidContext);
            fRet = TRUE;
            break;

        default:
            DEBUGMSG(ZONE_ERROR, (_T("%s: Unhandled message %u\r\n"), pszFname));
            break;
    };

    return fRet;
}



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

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

    DEBUGCHK(pReport != NULL);

    return pReport;        
}

    

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

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

    DEBUGCHK(pColl != NULL);

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

    return pColl;        
}    



// If this report includes power events, perform them.
static
void
PerformPowerEvents(
    PHIDP_COLLECTION_DESC phidpCollection,
    BYTE *pbHidPacket,
    DWORD cbHidPacket
    )
{
    SETFNAME(_T("PerformPowerEvents"));
    
    NTSTATUS status;
    ULONG uPowerEvents = 0;
    
    PREFAST_DEBUGCHK(phidpCollection != NULL);
    DEBUGCHK(pbHidPacket != NULL);

    status = HidP_SysPowerEvent((PCHAR) pbHidPacket, (USHORT) cbHidPacket, 
        phidpCollection->PreparsedData, &uPowerEvents);
    
    if (NT_SUCCESS(status)) 
    {
        DEBUGMSG(ZONE_HID_DATA, (_T("%s: Received power event 0x%08x\r\n"), 
            pszFname, uPowerEvents));
        
        if ((uPowerEvents & (SYS_BUTTON_SLEEP | SYS_BUTTON_POWER)) != 0) {
            SetSystemPowerState(NULL, POWER_STATE_SUSPEND, FALSE);
        }
    }    
}


// Called by the PDD when a new report arrives. The report is supplied
// in its raw format (ie. the report ID of 0 is not prepended).
DWORD
WINAPI
HidMdd_ProcessInterruptReport(
    PBYTE pData,
    DWORD cbData,
    PVOID pvNotifyParameter
    )
{
    SETFNAME(_T("HidMdd_ProcessInterruptReport"));

    PHID_CONTEXT pHidContext = (PHID_CONTEXT) pvNotifyParameter;
    PHIDP_REPORT_IDS phidpReport;
    PHIDP_COLLECTION_DESC phidpCollection;
    DWORD dwReportID;
    DWORD dwCollectionIndex;
    PHID_CLIENT_HANDLE pClientHandle;
    HidTLCQueue *pQueue;
    DWORD dwRet = ERROR_INVALID_PARAMETER;
   
    PREFAST_DEBUGCHK(pData != NULL);
    ValidateHidContext(pHidContext);

    if (pHidContext->hidpDeviceDesc.ReportIDs[0].ReportID == 0) {
        // The report ID is not returned in this report
        dwReportID = 0;
    }
    else {
        // We got a report ID.
        dwReportID = *pData;
    }

    // Get the report and collection data structures
    phidpReport = GetReportDesc(&pHidContext->hidpDeviceDesc, dwReportID);
    if (phidpReport != NULL) {
        phidpCollection = GetCollectionDesc(&pHidContext->hidpDeviceDesc, 
            phidpReport->CollectionNumber, &dwCollectionIndex);

        if (phidpCollection != NULL) {
            DEBUGCHK(dwCollectionIndex < pHidContext->hidpDeviceDesc.CollectionDescLength);

            OutputReport(pData, cbData, dwReportID, phidpCollection->UsagePage,
                phidpCollection->Usage);
            
            // Perform any power events listed in this report
            PerformPowerEvents(phidpCollection, pData, cbData);

            // Send this HID packet to the proper client
            pClientHandle = &pHidContext->pClientHandles[dwCollectionIndex];

            // Only queue this report if we have a client that will receive it.
            if (pClientHandle->hInst != NULL) 
            {
                pQueue = pClientHandle->pQueue;
                pQueue->Lock();
                if (pQueue->IsAccepting() == TRUE) {
                    if (pQueue->IsFull() == FALSE) {
                        BOOL fRet;
                        fRet = pQueue->Enqueue((PCHAR) pData, cbData, dwReportID);
                        DEBUGCHK(fRet);
                    }
                    else {
                        DEBUGMSG(ZONE_ERROR, 
                            (_T("%s: Error: Queue is full. Dropping packet.\r\n"), pszFname));
                    }
                }
                else {
                    DEBUGMSG(ZONE_HID_DATA, 
                        (_T("%s: Queue not accepting input. Dropping packet.\r\n"), pszFname));
                }
                pQueue->Unlock();
            }

            dwRet = ERROR_SUCCESS;
        }
    }

    DEBUGMSG(ZONE_ERROR && dwRet != ERROR_SUCCESS, 
        (_T("%s: Error: Received an invalid report.\r\n"), pszFname));

    return dwRet;
}




#define HID_DEVICE_CONTEXT_HANDLE 0xCAFE

#ifdef DEBUG
static DWORD g_dwInitCount = 0;
#endif


// Called by the PDD during XXX_Init. The PDD is responsible for 
// making sure the return value is stored and passed into
// HidMdd_Deinit.
DWORD
WINAPI
HidMdd_Init (
    LPCWSTR lpszDevKey
    )
{
    DEBUGCHK(lpszDevKey);
    
#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;
}


// Called by the PDD during XXX_Deinit. The PDD is responsible for 
// making sure dwContext is the same value returned from
// HidMdd_Init.
BOOL
WINAPI
HidMdd_Deinit(
    DWORD dwContext
    )
{
#ifdef DEBUG
    // Be sure that only one instance of this DLL is initialized.
    DEBUGCHK(g_dwInitCount == 1);
    --g_dwInitCount;
#endif

    DEBUGCHK(dwContext == HID_DEVICE_CONTEXT_HANDLE);

    return TRUE;
}


// Called by the PDD during XXX_Open. The PDD is responsible for 
// making sure the return value is stored and passed into
// HidMdd_Close.
DWORD
WINAPI
HidMdd_Open(
    DWORD dwContext,
    DWORD dwAccMode,
    DWORD dwShrMode
    )
{
    DEBUGCHK(dwContext == HID_DEVICE_CONTEXT_HANDLE);
    return HID_DEVICE_CONTEXT_HANDLE;
}


// Called by the PDD during XXX_Close. The PDD is responsible for 
// making sure dwContext is the same value returned from
// HidMdd_Open.
BOOL
WINAPI
HidMdd_Close(
    DWORD dwContext
    )
{
    DEBUGCHK(dwContext == HID_DEVICE_CONTEXT_HANDLE);
    return TRUE;
}


// Called by the PDD during XXX_IOControl. The PDD is responsible for 
// making sure dwContext is the same value returned from
// HidMdd_Open.
//
// IOCTLs with a Function value between 0x300 and 0x3FF are reserved 
// for the MDD.
BOOL
WINAPI
HidMdd_IOControl(
    DWORD          dwContext, 
    DWORD          dwIoControlCode, 
    LPVOID         lpInBuffer, 
    DWORD          nInBufferSize, 
    LPVOID         lpOutBuffer, 
    DWORD          nOutBufferSize, 
    LPDWORD        lpBytesReturned
    )
{
    return ERROR_NOT_SUPPORTED;
}


// Called by the PDD from its DLL entry function. This allows the MDD
// to initialize any MDD global variables.
BOOL 
WINAPI
HidMdd_DllEntry(
    DWORD dwReason
    )
{
    switch (dwReason) {
        case DLL_PROCESS_ATTACH:
            InitializeCriticalSection(&g_csHidRefCount);
            break;
            
        case DLL_PROCESS_DETACH:
            DeleteCriticalSection(&g_csHidRefCount);
            break;
    }

    return TRUE;
}


// The Init entry point for the public interface to the driver.
// Its only purpose is to keep a reference count so that the underlying
// named stream interface is only activated one time.
// dwClientInfo should be the registry path to the stream driver to load.
extern "C"
DWORD Init(
    LPCWSTR lpszDevKey,
    DWORD   dwClientInfo
    )
{
    TCHAR szHidDriverKey[DEVKEY_LEN];
    DWORD dwRet = 0;
    DWORD dwErr = ERROR_SUCCESS;
    
    EnterCriticalSection(&g_csHidRefCount);

    LPCTSTR pszHidDriverKey = (LPCTSTR) dwClientInfo;

    if (pszHidDriverKey == NULL) {
        dwErr = ERROR_INVALID_PARAMETER;
		goto EXIT;
    }

    BOOL fException = FALSE;
    __try {
        _tcsncpy(szHidDriverKey, pszHidDriverKey, dim(szHidDriverKey) - 1);
        szHidDriverKey[dim(szHidDriverKey) - 1] = 0; // Force null-termination
    }
    __except(EXCEPTION_EXECUTE_HANDLER) {
        fException = TRUE;
    }

    if (fException) {
        dwErr = ERROR_INVALID_PARAMETER;
        goto EXIT;
    }

    if (g_dwHidRefCount == 0) {
        DEBUGCHK(g_hMainHidDriver == NULL);
        g_hMainHidDriver = ActivateDeviceEx(szHidDriverKey, NULL, 0, NULL);
        if (g_hMainHidDriver == NULL) {
            dwErr = ERROR_DEVICE_NOT_AVAILABLE;
        }
    }

    dwRet = (DWORD) g_hMainHidDriver;

EXIT:
    if (dwErr != ERROR_SUCCESS) {
        SetLastError(dwErr);
        DEBUGCHK(dwRet == 0);
    }
    else {
        DEBUGCHK(dwRet != 0);
		++g_dwHidRefCount;
    }
    
    LeaveCriticalSection(&g_csHidRefCount);

    return dwRet;
}


// The Init entry point for the public interface to the driver.
// Its only purpose is to keep a reference count so that the underlying
// named stream interface is only deactivated one time.
extern "C"
BOOL Deinit(DWORD hDeviceContext)
{
    EnterCriticalSection(&g_csHidRefCount);

    DEBUGCHK(g_dwHidRefCount > 0);
    DEBUGCHK(hDeviceContext == (DWORD) g_hMainHidDriver);
        
    --g_dwHidRefCount;
    
    if (g_dwHidRefCount == 0) {
        DEBUGCHK(g_hMainHidDriver);
        DeactivateDevice(g_hMainHidDriver);
        g_hMainHidDriver = NULL;
    }
    
    LeaveCriticalSection(&g_csHidRefCount);
    
    return TRUE;
}

⌨️ 快捷键说明

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