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

📄 debug.cpp

📁 hidclass source code for windows ce use
💻 CPP
字号:
//
// 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:  

    debug.cpp

Abstract:  
    Debug for Human Interface Device (HID) Class.

Functions:

Notes: 

--*/

#include "hidmdd.h"


#ifdef DEBUG


//
// ***** Debug utility functions *****
//


// Debug Alloc
HLOCAL
HidAlloc(
    SIZE_T cb
    )
{
    LPVOID ptr;
    
    DEBUGCHK(cb != 0);

    ptr = LocalAlloc(LMEM_FIXED, cb);

    return ptr;
}


// Debug Free
HLOCAL
HidFree(
    LPVOID ptr
    )
{
    DEBUGCHK(ptr != NULL);
    
    return LocalFree(ptr);
}


// IsLocked helper function
BOOL
DebugIsLocked(
    INT cInCS
    )
{
    return cInCS > 0;
}


// Lock helper function
void
DebugLock(
    LPCRITICAL_SECTION pCS,
    INT *pcInCS
    )
{
    DEBUGCHK(*pcInCS < 10); // Check for cycle
    EnterCriticalSection(pCS);
    ++(*pcInCS);
}


// Unlock helper function
void
DebugUnlock(
    LPCRITICAL_SECTION pCS,
    INT *pcInCS
    )
{
    DEBUGCHK(DebugIsLocked(*pcInCS) == TRUE);
    --(*pcInCS);
    LeaveCriticalSection(pCS);
}



// 
// The following are used only by the MDD
//

// Verify the integrity of a Hid context.
void
ValidateHidContext(
    PCHID_CONTEXT pHidContext
    )
{
    DWORD cCollections;
    DWORD dwIdx;
    
    PREFAST_DEBUGCHK(pHidContext != NULL);
    DEBUGCHK(pHidContext->Sig == HID_SIG);
    DEBUGCHK(pHidContext->hPddDevice != NULL);
    DEBUGCHK(pHidContext->hidpDeviceDesc.CollectionDesc != NULL);
    
    cCollections = pHidContext->hidpDeviceDesc.CollectionDescLength;
    
    DEBUGCHK(pHidContext->pQueues != NULL);
    DEBUGCHK(pHidContext->pClientHandles != NULL);
    DEBUGCHK(LocalSize(pHidContext->pClientHandles) >= 
        (sizeof(HID_CLIENT_HANDLE) * cCollections));

    for (dwIdx = 0; dwIdx < cCollections; ++dwIdx) {
        const HidTLCQueue *pQueue = &pHidContext->pQueues[dwIdx];
        
        DEBUGCHK(pQueue == pHidContext->pClientHandles[dwIdx].pQueue);
        pQueue->Validate();

        // Do not call ValidateClientHandle here or infinite loop will result.
    }
}


// Verify the integrity of the HID client handle
void
ValidateClientHandle(
    PHID_CLIENT_HANDLE pHidClient 
    )
{
    DEBUGCHK(pHidClient != NULL);
    DEBUGCHK(IsBadReadPtr(pHidClient, sizeof(*pHidClient)) == FALSE);
    DEBUGCHK(pHidClient->Sig == HID_CLIENT_SIG);
    PREFAST_DEBUGCHK(pHidClient->pQueue != NULL);
    pHidClient->pQueue->Validate();
    DEBUGCHK(pHidClient->phidpPreparsedData != NULL);
    DEBUGCHK(pHidClient->pHidContext != NULL);
    ValidateHidContext(pHidClient->pHidContext);
}


// Output a Hid device description
void 
DumpHIDDeviceDescription(
    const HIDP_DEVICE_DESC *phidpDeviceDesc
    )
{
    UINT ui;
    
    PREFAST_DEBUGCHK(phidpDeviceDesc != NULL);
    
    if (ZONE_PARSE)
    {
        DEBUGMSG(1, (_T("\r\n")));
        DEBUGMSG(1, (_T("Hid Device Description:\r\n")));
        
        for (ui = 0; ui < phidpDeviceDesc->CollectionDescLength; ++ui)
        {
            const HIDP_COLLECTION_DESC *phidpCollDesc = phidpDeviceDesc->CollectionDesc + ui;
            PREFAST_DEBUGCHK(phidpCollDesc != NULL);

            DEBUGMSG(1, (_T("Collection #%u: Usage Page 0x%x Usage 0x%x\r\n"), 
                phidpCollDesc->CollectionNumber, phidpCollDesc->UsagePage, 
                phidpCollDesc->Usage));
            DEBUGMSG(1, (_T("Input Length 0x%x Output Length 0x%x Feature Length 0x%x\r\n"),
                phidpCollDesc->InputLength, phidpCollDesc->OutputLength, 
                phidpCollDesc->FeatureLength));
        }
        
        for (ui = 0; ui < phidpDeviceDesc->ReportIDsLength; ++ui)
        {
            const HIDP_REPORT_IDS *phidpReports = phidpDeviceDesc->ReportIDs + ui;
            PREFAST_DEBUGCHK(phidpReports != NULL);

            DEBUGMSG(1, (_T("Collection #%u, Report #%u\r\n"),
                phidpReports->CollectionNumber, phidpReports->ReportID));
            DEBUGMSG(1, (_T("Input Length 0x%x Output Length 0x%x Feature Length 0x%x\r\n"),
                phidpReports->InputLength, phidpReports->OutputLength, 
                phidpReports->FeatureLength));
        }

        DEBUGMSG(1, (_T("\r\n")));
    }
}


static const LPCTSTR g_rgpszItems[] =
{
    _T("!RSVD!"),
    _T("Usage Page"), //x01
    _T("Usage"), //x02
    _T("!RSVD!"),
    _T("!RSVD!"),
    _T("Logical Min"), //x05
    _T("Usage Min"), //x06
    _T("!RSVD!"),
    _T("!RSVD!"),
    _T("Logical Max"), //x09
    _T("Usage Max"), //x0a
    _T("!RSVD!"),
    _T("!RSVD!"),
    _T("Physical Min"), //x0d
    _T("Designator Index"), //x0e
    _T("!RSVD!"),
    _T("!RSVD!"),
    _T("Physical Max"), //x11
    _T("Designator Min"), //x12
    _T("!RSVD!"),
    _T("!RSVD!"),
    _T("Unit Exponent"), //x15
    _T("Designator Max"), //x16
    _T("!RSVD!"),
    _T("!RSVD!"),
    _T("Unit"), //x19
    _T("!RSVD!"),
    _T("!RSVD!"),
    _T("!RSVD!"),
    _T("Report Size"), //x1d
    _T("String Index"), //x1e
    _T("!RSVD!"),
    _T("Input"), //x20
    _T("Report ID"), //x21
    _T("String Min"), //x22
    _T("!RSVD!"),
    _T("Output"), //x24
    _T("Report Count"), //x25
    _T("String Max"), //x26
    _T("!RSVD!"),
    _T("Collection"), //x28
    _T("Push"), //x29
    _T("Delimiter"), //x2a
    _T("!RSVD!"),
    _T("Feature"), //x2c
    _T("Pop"), //x2d
    _T("!RSVD!"),
    _T("!RSVD!"),
    _T("End Collection"), //x30
    _T("!RSVD!"),
    _T("!RSVD!"),
    _T("!RSVD!"),
    _T("!RSVD!"),
    _T("!RSVD!"),
    _T("!RSVD!"),
    _T("!RSVD!"),
    _T("!RSVD!"),
    _T("!RSVD!"),
    _T("!RSVD!"),
    _T("!RSVD!"),
    _T("!RSVD!"),
    _T("!RSVD!"),
    _T("!RSVD!"),
    _T("!RSVD!"), //x3F
};


#define HID_LONG_ITEM 0xFE
#define HID_ITEM_LENGTH_MASK 0x03
#define HID_ITEM_TYPE_MASK 0x0C
#define HID_ITEM_TYPE_SHIFT 2
#define HID_ITEM_TAG_MASK 0xF0
#define HID_ITEM_TAG_SHIFT 4

// Retrieves the size of the data from the item byte.
// Returns HID_LONG_ITEM if long data item.
static
BYTE
GetDataSize(
    BYTE bItem
    )
{    
    BYTE bLength;

    if (bItem == HID_LONG_ITEM) {
        bLength = HID_LONG_ITEM;
    }
    else {
        bLength = bItem & HID_ITEM_LENGTH_MASK;

        // 0-2 means 0-2, 3 means 4
        if (bLength == 0x03) {
            bLength = 4;
        }
    }

    return bLength;
}


// Returns the data for this item.
static
DWORD
GetData(
    const BYTE *pbBuffer,
    DWORD dwLength
    )
{
    DWORD dwValue = 0;
    DWORD dwTemp;
    DWORD dwIdx;

    DEBUGCHK(pbBuffer != NULL);
    DEBUGCHK(dwLength <= 4);

    for (dwIdx = 0; dwIdx < dwLength; ++dwIdx) {
        dwTemp = pbBuffer[dwIdx];
        dwValue = (dwTemp << 24) | (dwValue >> 8);
    }

    while (dwIdx < 4) {
        dwValue >>= 8;
        ++dwIdx;
    }

    return dwValue;
}


// Outputs the HID report descriptor in a readable format.
void
DumpHIDReportDescriptor(
    const BYTE *pbReportDescriptor,
    DWORD cbReportDescriptor
    )
{
    static const LPCTSTR rgpszFmtStrings[] = {
        _T(""),
        _T("%02X"),
        _T("%04X"),
        _T(""),
        _T("%08X"),
    };
    
    DWORD dwIdx;
    DWORD cbItemData = 0;

    DEBUGCHK( dim(g_rgpszItems) == 1 + 
        ((HID_ITEM_TAG_MASK | HID_ITEM_TYPE_MASK) >> HID_ITEM_TYPE_SHIFT) );

    for (dwIdx = 0; dwIdx < cbReportDescriptor; dwIdx += (cbItemData + 1)) {
        BYTE bItem = pbReportDescriptor[dwIdx];
        TCHAR szUnsignedData[9];
        DWORD dwData;

        cbItemData = GetDataSize(bItem);
        if (cbItemData == HID_LONG_ITEM) {
            cbItemData = pbReportDescriptor[dwIdx + 1];
            DEBUGMSG(ZONE_PARSE,
                (_T("RDesc idx %3d (%02X) len=%d -- Long item\r\n"),
                     dwIdx, bItem, cbItemData));
            ++cbItemData; // Skip length byte
            continue;
        }

        dwData = GetData(&pbReportDescriptor[dwIdx + 1], cbItemData);

        BYTE bTagAndType = bItem >> HID_ITEM_TYPE_SHIFT;

        DEBUGCHK(cbItemData < dim(rgpszFmtStrings));
        _stprintf(szUnsignedData, rgpszFmtStrings[cbItemData], dwData);

        DEBUGCHK(bTagAndType < dim(g_rgpszItems));
        DEBUGMSG(ZONE_PARSE,
            (_T("RDesc idx %03X (%02X) len=%d tag=%02X (%-16s) data=%8s\r\n"),
            dwIdx, bItem, cbItemData, bTagAndType,
            g_rgpszItems[bTagAndType], szUnsignedData));
    }
}


#endif // DEBUG


⌨️ 快捷键说明

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