?? mouhid.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.
//
//
//
#include "mouhid.h"
#include <windev.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("MouHid"), {
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 };
#endif // DEBUG
// Conversions from button usages to mouse_event flags
static const DWORD g_rgdwUsageToDownButton[] = {
0, // Undefined
MOUSEEVENTF_LEFTDOWN,
MOUSEEVENTF_RIGHTDOWN,
MOUSEEVENTF_MIDDLEDOWN,
};
static const DWORD g_rgdwUsageToUpButton[] = {
0, // Undefined
MOUSEEVENTF_LEFTUP,
MOUSEEVENTF_RIGHTUP,
MOUSEEVENTF_MIDDLEUP,
};
#ifdef DEBUG
static
void
ValidateHidMouse(
PHID_MOUSE pHidMouse
);
#else
#define ValidateHidMouse(ptr)
#endif // DEBUG
BOOL
AllocateUsageLists(
PHID_MOUSE pHidMouse,
size_t cbUsages
);
void
DetermineWheelUsage(
PHID_MOUSE pHidMouse
);
void
SetButtonFlags(
PDWORD pdwFlags,
PUSAGE pUsages,
DWORD dwMaxUsages,
const DWORD *pdwUsageMappings,
DWORD cdwUsageMappings
);
void
ProcessMouseReport(
PHID_MOUSE pHidMouse,
PCHAR pbHidPacket,
DWORD cbHidPacket
);
void
MouseEvent(
DWORD dwFlags,
DWORD dx,
DWORD dy,
DWORD dz
);
VOID
FreeHidMouse(
PHID_MOUSE pHidMouse
);
// Dll entry function.
extern "C"
BOOL
DllEntry(
HANDLE hDllHandle,
DWORD dwReason,
LPVOID lpReserved
)
{
SETFNAME(_T("MOUHID 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
MouseThreadProc(
LPVOID lpParameter
)
{
SETFNAME(_T("MouseThreadProc"));
PHID_MOUSE pHidMouse = (PHID_MOUSE) lpParameter;
PCHAR pbHidPacket;
DWORD cbHidPacket;
DWORD cbBuffer;
DWORD dwErr;
DEBUGCHK(pHidMouse != NULL);
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
cbBuffer = pHidMouse->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)
{
ValidateHidMouse(pHidMouse);
// Get an interrupt report from the device.
dwErr = pHidMouse->pHidFuncs->lpGetInterruptReport(
pHidMouse->hDevice,
pbHidPacket,
cbBuffer,
&cbHidPacket,
NULL,
INFINITE);
if (dwErr == ERROR_DEVICE_REMOVED) {
// Exit thread
break;
}
else {
DEBUGCHK(dwErr == ERROR_SUCCESS);
ProcessMouseReport(pHidMouse, 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;
PHID_MOUSE pHidMouse;
size_t cbUsages;
DEBUGCHK(hDevice != NULL);
DEBUGCHK(pHidFuncs != NULL);
DEBUGCHK(phidpPreparsedData != NULL);
DEBUGCHK(ppvNotifyParameter != NULL);
// Allocate this keyboard's data structure and fill it.
pHidMouse = (PHID_MOUSE) LocalAlloc(LPTR, sizeof(HID_MOUSE));
if (pHidMouse == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("%s: LocalAlloc error:%d\r\n"), pszFname, GetLastError()));
goto EXIT;
}
pHidMouse->dwSig = HID_MOUSE_SIG;
pHidMouse->hDevice = hDevice;
pHidMouse->pHidFuncs = pHidFuncs;
pHidMouse->phidpPreparsedData = phidpPreparsedData;
HidP_GetCaps(pHidMouse->phidpPreparsedData, &pHidMouse->hidpCaps);
// Get the total number of usages that can be returned in an input packet.
pHidMouse->dwMaxUsages = HidP_MaxUsageListLength(HidP_Input,
HID_USAGE_PAGE_BUTTON, phidpPreparsedData);
cbUsages = pHidMouse->dwMaxUsages * sizeof(USAGE);
if (AllocateUsageLists(pHidMouse, cbUsages) == FALSE) {
goto EXIT;
}
// Do we have a mouse wheel?
DetermineWheelUsage(pHidMouse);
// Create the thread that will receive reports from this device
pHidMouse->hThread = CreateThread(NULL, 0, MouseThreadProc, pHidMouse, 0, NULL);
if (pHidMouse->hThread == NULL) {
DEBUGMSG(ZONE_ERROR, (_T("%s: Failed creating mouse thread\r\n"),
pszFname));
goto EXIT;
}
#ifdef DEBUG
pHidMouse->fhThreadInited = TRUE;
#endif
*ppvNotifyParameter = pHidMouse;
ValidateHidMouse(pHidMouse);
fRet = TRUE;
EXIT:
if ((fRet == FALSE) && (pHidMouse != NULL)) {
FreeHidMouse(pHidMouse);
}
return fRet;
}
#ifdef DEBUG
// Match function with typedef.
static LPHID_CLIENT_ATTACH g_pfnDeviceAttach = HIDDeviceAttach;
#endif
// Entry point for the HID driver to give us notifications.
extern "C"
BOOL
WINAPI
HIDDeviceNotifications(
DWORD dwMsg,
WPARAM wParam, // Message parameter
PVOID pvNotifyParameter
)
{
SETFNAME(_T("HIDDeviceNotifications"));
BOOL fRet = FALSE;
PHID_MOUSE pHidMouse = (PHID_MOUSE) pvNotifyParameter;
DWORD dwFlags = 0;
UNREFERENCED_PARAMETER(wParam);
if (VALID_HID_MOUSE(pHidMouse) == FALSE) {
DEBUGMSG(ZONE_ERROR, (_T("%s: Received invalid structure pointer\r\n"), pszFname));
goto EXIT;
}
ValidateHidMouse(pHidMouse);
switch(dwMsg) {
case HID_CLOSE_DEVICE:
// Free all of our resources.
WaitForSingleObject(pHidMouse->hThread, INFINITE);
CloseHandle(pHidMouse->hThread);
pHidMouse->hThread = NULL;
// Send ups for each button that is still down.
SetButtonFlags(&dwFlags, pHidMouse->puPrevUsages, pHidMouse->dwMaxUsages,
g_rgdwUsageToUpButton, dim(g_rgdwUsageToUpButton));
MouseEvent(dwFlags, 0, 0, 0);
FreeHidMouse(pHidMouse);
fRet = TRUE;
break;
default:
DEBUGMSG(ZONE_ERROR, (_T("%s: Unhandled message %u\r\n"), pszFname));
break;
};
EXIT:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -