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

📄 conshid.cpp

📁 cayman提供的PXA270 wince下的bsp源码包
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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.
//
//
//

#include "conshid.h"
#include <windev.h>
#include "Oemioctl.h"

#ifdef DEBUG

// Debug Zones
#define DBG_ERROR              0x0001
#define DBG_WARNING            0x0002
#define DBG_INIT               0x0004
#define DBG_FUNCTION           0x0008

#define DBG_USAGES             0x0010

DBGPARAM dpCurSettings = {
        TEXT("ConsHid"), {
        TEXT("Errors"), TEXT("Warnings"), TEXT("Init"), TEXT("Function"),
        TEXT("Usages"), TEXT(""), TEXT(""), TEXT(""),
        TEXT(""), TEXT(""), TEXT(""), TEXT(""),
        TEXT(""), TEXT(""), TEXT(""), TEXT("") },
        DBG_ERROR | DBG_WARNING };
        

static
void
ValidateHidConsumer(
    PHID_CONSUMER pHidConsumer
    );

#else

#define ValidateHidConsumer(ptr)

#endif // DEBUG


// MapVirtualKey(x, 3) converts scan codes to virtual keys
#define MAP_SC_TO_VK 3


// Describes an association from a Usage to an AT Scan Code
struct USAGE_TO_SC_ASSOCIATION {
    USAGE  usage;
    UINT16 uiSc;
};


// Usage to Virtual Key table
static const USAGE_TO_SC_ASSOCIATION g_rgUsageToScAssn[] = {
    { HID_CONSUMER_SCAN_NEXT_TRACK,             0xE04D },
    { HID_CONSUMER_SCAN_PREVIOUS_TRACK,         0xE015 },
	{ HID_CONSUMER_STOP,                        0xE03B },
	{ HID_CONSUMER_PLAY_PAUSE,                  0xE034 },

    { HID_CONSUMER_VOLUME_MUTE,                 0xE023 },
    { HID_CONSUMER_VOLUME_INCREMENT,            0xE032 },
    { HID_CONSUMER_VOLUME_DECREMENT,            0xE021 },

    { HID_CONSUMER_LAUNCH_CONFIGURATION,        0xE050 },
    { HID_CONSUMER_LAUNCH_EMAIL,                0xE048 },
    { HID_CONSUMER_LAUNCH_CALCULATOR,           0xE02B },
    { HID_CONSUMER_LAUNCH_BROWSER,              0xE040 },

    { HID_CONSUMER_APP_SEARCH,                  0xE010 },
    { HID_CONSUMER_APP_HOME,                    0xE03A },
    { HID_CONSUMER_APP_BACK,                    0xE038 },
    { HID_CONSUMER_APP_FORWARD,                 0xE030 },
    { HID_CONSUMER_APP_STOP,                    0xE028 },
    { HID_CONSUMER_APP_REFRESH,                 0xE020 },
    { HID_CONSUMER_APP_BOOKMARKS,               0xE018 },
};


DWORD
SendKeyboardUsages(
    PUSAGE pUsages,
    DWORD dwMaxUsages,
    HIDP_KEYBOARD_DIRECTION keyEvent 
    );

void 
KeyboardEvent(
    UINT vk,
    UINT sc,
    DWORD dwFlags
    );

void
ProcessConsumerReport(
    PHID_CONSUMER pHidConsumer,
    PCHAR pbHidPacket,
    DWORD cbHidPacket
    );

BOOL
AllocateUsageLists(
    PHID_CONSUMER pHidConsumer,
    size_t cbUsages
    );

VOID
FreeHidConsumer(
    PHID_CONSUMER pHidConsumer
    );



// Dll entry function.
extern "C" 
BOOL
DllEntry(
    HANDLE hDllHandle,
    DWORD dwReason, 
    LPVOID lpReserved
    )
{
    SETFNAME(_T("CONSHID DllEntry"));
    
    UNREFERENCED_PARAMETER(lpReserved);
    
    switch (dwReason) {
        case DLL_PROCESS_ATTACH:
            DEBUGREGISTER((HINSTANCE)hDllHandle);

            DEBUGMSG(ZONE_INIT, (_T("%s: Attach\r\n"), pszFname));
            DisableThreadLibraryCalls((HMODULE) hDllHandle);
            break;
            
        case DLL_PROCESS_DETACH:
            DEBUGMSG(ZONE_INIT, (_T("%s: Detach\r\n"), pszFname));
            break;
            
        default:
            break;
    }
    
    return TRUE ;
}


// Get interrupt reports from the device. Thread exits when the device has
// been removed.
static
DWORD
WINAPI
ConsumerThreadProc(
    LPVOID lpParameter
    )
{
    SETFNAME(_T("ConsumerThreadProc"));

    PHID_CONSUMER pHidConsumer = (PHID_CONSUMER) lpParameter;
    BOOL  fGWEReady = FALSE;
    PCHAR pbHidPacket;
    DWORD cbHidPacket;
    DWORD cbBuffer;
    DWORD dwErr;
    
    DEBUGCHK(pHidConsumer != NULL);

	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
    
    cbBuffer = pHidConsumer->hidpCaps.InputReportByteLength;
    
    pbHidPacket = (PCHAR) LocalAlloc(LMEM_FIXED, cbBuffer);
    if (pbHidPacket == NULL) {
        DEBUGMSG(ZONE_ERROR, (TEXT("%s: LocalAlloc error:%d\r\n"), pszFname, GetLastError()));
        goto EXIT;
    }

    while (TRUE) 
    {
        ValidateHidConsumer(pHidConsumer);
        
        // Get an interrupt report from the device.
        dwErr = pHidConsumer->pHidFuncs->lpGetInterruptReport(
            pHidConsumer->hDevice,
            pbHidPacket,
            cbBuffer,
            &cbHidPacket,
            NULL,
            INFINITE);

        // Make sure gwes is ready to accept keystrokes.
        // Since USB is part of device.exe it can attempt to send keystrokes
        // before gwes is present (if something is leaning on keyboard at poweron).
        if (fGWEReady == FALSE) {
            fGWEReady = IsAPIReady(SH_WMGR);
        }

        if (dwErr == ERROR_DEVICE_REMOVED) { 
            // Exit thread 
            break;
        }
        else if (fGWEReady == FALSE) {
            // We cannot do anything with these keystrokes.
            DEBUGMSG(ZONE_ERROR, (_T("%s: Discarding keyboard event, no GWES yet\n"),
                pszFname));
            continue;
        }
        else {
            DEBUGCHK(dwErr == ERROR_SUCCESS);
            ProcessConsumerReport(pHidConsumer, pbHidPacket, cbHidPacket);
        }
    }

EXIT:
    if (pbHidPacket != NULL) LocalFree(pbHidPacket);
    DEBUGMSG(ZONE_FUNCTION, (_T("%s: Exiting thread\r\n"), pszFname));
    
    return 0;
}


// Entry point for the HID driver. Initializes the structures for this 
// keyboard and starts the thread that will receive interrupt reports.
extern "C"
BOOL
HIDDeviceAttach(
    HID_HANDLE                 hDevice, 
    PCHID_FUNCS                pHidFuncs,
    const HID_DRIVER_SETTINGS *pDriverSettings,
    PHIDP_PREPARSED_DATA       phidpPreparsedData,
    PVOID                     *ppvNotifyParameter,
    DWORD                      dwUnused
    )
{
    SETFNAME(_T("HIDDeviceAttach"));

    BOOL fRet = FALSE;
    size_t cbUsages;
    PHID_CONSUMER pHidConsumer;

    DEBUGCHK(hDevice != NULL);
    DEBUGCHK(pHidFuncs != NULL);
    DEBUGCHK(phidpPreparsedData != NULL);
    DEBUGCHK(ppvNotifyParameter != NULL);

    // Allocate this device's data structure and fill it.
    pHidConsumer = (PHID_CONSUMER) LocalAlloc(LPTR, sizeof(HID_CONSUMER));
    if (pHidConsumer == NULL) {
        DEBUGMSG(ZONE_ERROR, (TEXT("%s: LocalAlloc error:%d\r\n"), pszFname, GetLastError()));
        goto EXIT;
    }

    pHidConsumer->dwSig = HID_CONSUMER_SIG;
    pHidConsumer->hDevice = hDevice;
    pHidConsumer->pHidFuncs = pHidFuncs;
    pHidConsumer->phidpPreparsedData = phidpPreparsedData;
    HidP_GetCaps(pHidConsumer->phidpPreparsedData, &pHidConsumer->hidpCaps);
    
    // Get the total number of usages that can be returned in an input packet.
    pHidConsumer->dwMaxUsages = HidP_MaxUsageListLength(HidP_Input, 
        HID_USAGE_PAGE_CONSUMER, phidpPreparsedData);
    if (pHidConsumer->dwMaxUsages == 0) {
        DEBUGMSG(ZONE_WARNING, (_T("%s: This collection does not have any ")
            _T("understood usages and will be ignored\r\n"), pszFname));
        goto EXIT;
    }
    
    cbUsages = pHidConsumer->dwMaxUsages * sizeof(*pHidConsumer->puPrevUsages);

    if (AllocateUsageLists(pHidConsumer, cbUsages) == FALSE) {
        goto EXIT;
    }
	
    // Create the thread that will receive reports from this device
    pHidConsumer->hThread = CreateThread(NULL, 0, ConsumerThreadProc, pHidConsumer, 0, NULL);
    if (pHidConsumer->hThread == NULL) {
        DEBUGMSG(ZONE_ERROR, (_T("%s: Failed creating keyboard thread\r\n"), 
            pszFname));
        goto EXIT;
    }
    else
    {
        ThreadInfo TI;
        TI.ThreadHandle = pHidConsumer->hThread;
        strcpy((char *)TI.ThreadName, "USB ConsumerThreadProc");
        KernelIoControl(IOCTL_SET_THREAD, (LPVOID)&TI, sizeof(ThreadInfo), NULL, 0, NULL);
    }
#ifdef DEBUG
    pHidConsumer->fhThreadInited = TRUE;
#endif


    *ppvNotifyParameter = pHidConsumer;
    ValidateHidConsumer(pHidConsumer);
    fRet = TRUE;

EXIT:
    if ((fRet == FALSE) && (pHidConsumer != NULL)) {
        FreeHidConsumer(pHidConsumer);

⌨️ 快捷键说明

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