📄 conshid.cpp
字号:
}
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_CONSUMER pHidConsumer = (PHID_CONSUMER) pvNotifyParameter;
UNREFERENCED_PARAMETER(wParam);
if (VALID_HID_CONSUMER(pHidConsumer) == FALSE) {
DEBUGMSG(ZONE_ERROR, (_T("%s: Received invalid structure pointer\r\n"), pszFname));
goto EXIT;
}
ValidateHidConsumer(pHidConsumer);
switch(dwMsg) {
case HID_CLOSE_DEVICE:
// Free all of our resources.
WaitForSingleObject(pHidConsumer->hThread, INFINITE);
CloseHandle(pHidConsumer->hThread);
pHidConsumer->hThread = NULL;
// Key up all keys that are still down.
SendKeyboardUsages(pHidConsumer->puPrevUsages, pHidConsumer->dwMaxUsages,
HidP_Keyboard_Break);
FreeHidConsumer(pHidConsumer);
fRet = TRUE;
break;
default:
DEBUGMSG(ZONE_ERROR, (_T("%s: Unhandled message %u\r\n"), pszFname));
break;
};
EXIT:
return fRet;
}
#ifdef DEBUG
// Match function with typedef.
static LPHID_CLIENT_NOTIFICATIONS g_pfnDeviceNotifications = HIDDeviceNotifications;
#endif
// Allocate the usage lists for this device. The lists are allocated in
// a single block and then divided up.
//
// Note: There may not be any usages for this device so cbUsages may be 0.
static
BOOL
AllocateUsageLists(
PHID_CONSUMER pHidConsumer,
size_t cbUsages
)
{
SETFNAME(_T("AllocateUsageLists"));
BOOL fRet = FALSE;
size_t cbTotal;
PBYTE pbStart;
DWORD dwIdx;
PUSAGE *rgppUsage[] = {
&pHidConsumer->puPrevUsages,
&pHidConsumer->puCurrUsages,
&pHidConsumer->puBreakUsages,
&pHidConsumer->puMakeUsages
};
DEBUGCHK(pHidConsumer != NULL);
// Allocate a block of memory for all the usage lists
cbTotal = cbUsages * dim(rgppUsage);
pbStart = (PBYTE) LocalAlloc(LPTR, cbTotal);
if (pbStart == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("%s: LocalAlloc error:%d\r\n"), pszFname, GetLastError()));
goto EXIT;
}
// Divide the block.
for (dwIdx = 0; dwIdx < dim(rgppUsage); ++dwIdx) {
*rgppUsage[dwIdx] = (PUSAGE) (pbStart + (cbUsages * dwIdx));
}
fRet = TRUE;
EXIT:
return fRet;
}
// Free the memory used by pHidConsumer
void
FreeHidConsumer(
PHID_CONSUMER pHidConsumer
)
{
DEBUGCHK(pHidConsumer != NULL);
DEBUGCHK(pHidConsumer->hThread == NULL); // We do not close the thread handle
if (pHidConsumer->puPrevUsages != NULL) LocalFree(pHidConsumer->puPrevUsages);
LocalFree(pHidConsumer);
}
// Process a report from this device.
static
void
ProcessConsumerReport(
PHID_CONSUMER pHidConsumer,
PCHAR pbHidPacket,
DWORD cbHidPacket
)
{
SETFNAME(_T("ProcessConsumerReport"));
BOOL fRollover = FALSE;
ULONG uCurrUsages;
DWORD cbUsageList;
NTSTATUS status;
DEBUGCHK(pHidConsumer != NULL);
DEBUGCHK(pbHidPacket != NULL);
uCurrUsages = pHidConsumer->dwMaxUsages;
cbUsageList = uCurrUsages * sizeof(*pHidConsumer->puPrevUsages);
status = HidP_GetUsages(
HidP_Input,
HID_USAGE_PAGE_CONSUMER,
0,
pHidConsumer->puCurrUsages,
&uCurrUsages, // IN OUT parameter
pHidConsumer->phidpPreparsedData,
pbHidPacket,
cbHidPacket
);
DEBUGCHK(NT_SUCCESS(status));
DEBUGCHK(uCurrUsages <= pHidConsumer->dwMaxUsages);
// Determine what keys went down and up.
status = HidP_UsageListDifference(
pHidConsumer->puPrevUsages,
pHidConsumer->puCurrUsages,
pHidConsumer->puBreakUsages,
pHidConsumer->puMakeUsages,
pHidConsumer->dwMaxUsages
);
DEBUGCHK(NT_SUCCESS(status));
// Send key ups
SendKeyboardUsages(pHidConsumer->puBreakUsages, pHidConsumer->dwMaxUsages,
HidP_Keyboard_Break);
// Send key downs
SendKeyboardUsages(pHidConsumer->puMakeUsages, pHidConsumer->dwMaxUsages,
HidP_Keyboard_Make);
// Save current usages
memcpy(pHidConsumer->puPrevUsages, pHidConsumer->puCurrUsages, cbUsageList);
}
// Converts the usages to virtual keys and sends them off.
// Returns the number of usages converted.
static
DWORD
SendKeyboardUsages(
PUSAGE pUsages,
DWORD dwMaxUsages,
HIDP_KEYBOARD_DIRECTION hidpKeyEvent
)
{
SETFNAME(_T("SendKeyboardUsages"));
DWORD dwUsage;
DWORD dwAssn;
DEBUGCHK(pUsages != NULL);
for (dwUsage = 0; dwUsage < dwMaxUsages; ++dwUsage) {
// Determine virtual key mapping
const USAGE usage = pUsages[dwUsage];
UINT uiSc = 0;
DWORD dwFlags = 0;
UINT uiVk;
if (usage == 0) {
// No more usages
break;
}
// Find what virtual key matches this usage
for (dwAssn = 0; dwAssn < sizeof(g_rgUsageToScAssn); ++dwAssn) {
if (g_rgUsageToScAssn[dwAssn].usage == usage) {
uiSc = g_rgUsageToScAssn[dwAssn].uiSc;
break;
}
}
if (uiSc != 0) {
DEBUGMSG(ZONE_USAGES, (_T("%s: Usage Page: 0x%04x Usage: 0x%04x -> SC: 0x%06x\r\n"),
pszFname, HID_USAGE_PAGE_CONSUMER, usage, uiSc));
// Set the key flags
if (hidpKeyEvent == HidP_Keyboard_Break) {
dwFlags |= KEYEVENTF_KEYUP;
}
DEBUGCHK(IsAPIReady(SH_WMGR) == TRUE); // Exception if FALSE
uiVk = MapVirtualKey(uiSc, MAP_SC_TO_VK);
// The key is extended if it matches 0x0000e0xx
if ((uiSc & 0xFFFFFF00) == 0xE000) {
dwFlags |= KEYEVENTF_EXTENDEDKEY;
}
KeyboardEvent(uiVk, uiSc, dwFlags);
}
else {
DEBUGMSG(ZONE_WARNING, (_T("%s: No scan code for Usage Page: 0x%04x Usage: 0x%04x\r\n"),
pszFname, HID_USAGE_PAGE_CONSUMER, usage));
}
}
return dwUsage;
}
static
void
KeyboardEvent(
UINT vk,
UINT sc,
DWORD dwFlags
)
{
SETFNAME(_T("KeyboardEvent"));
UINT8 uiVk = (UINT8) vk;
UINT8 uiSc = (UINT8) sc;
DEBUGCHK((uiVk != 0) || (uiSc != 0));
DEBUGMSG(ZONE_USAGES, (_T("%s: Keybd event: vk: 0x%02x sc: 0x%02x flags: 0x%08x\r\n"),
pszFname, uiVk, uiSc, dwFlags));
keybd_event(uiVk, uiSc, dwFlags, 0);
}
#ifdef DEBUG
// Validate a PHID_CONSUMER structure
static
void
ValidateHidConsumer(
PHID_CONSUMER pHidConsumer
)
{
DWORD cbUsageList;
DEBUGCHK(pHidConsumer != NULL);
DEBUGCHK(pHidConsumer->dwSig == HID_CONSUMER_SIG);
DEBUGCHK(pHidConsumer->hDevice != NULL);
DEBUGCHK(pHidConsumer->pHidFuncs != NULL);
DEBUGCHK(pHidConsumer->phidpPreparsedData != NULL);
DEBUGCHK(pHidConsumer->hidpCaps.UsagePage == HID_USAGE_PAGE_CONSUMER);
DEBUGCHK(pHidConsumer->hidpCaps.Usage == HID_CONSUMER_COLLECTION_CONSUMER_CONTROL);
if (pHidConsumer->fhThreadInited == TRUE) {
DEBUGCHK(pHidConsumer->hThread != NULL);
}
cbUsageList = pHidConsumer->dwMaxUsages * sizeof(*pHidConsumer->puPrevUsages);
DEBUGCHK(pHidConsumer->puPrevUsages != NULL);
DEBUGCHK(LocalSize(pHidConsumer->puPrevUsages) == cbUsageList * 4);
DEBUGCHK((DWORD) pHidConsumer->puCurrUsages == ((DWORD) pHidConsumer->puPrevUsages) + cbUsageList);
DEBUGCHK((DWORD) pHidConsumer->puBreakUsages == ((DWORD) pHidConsumer->puCurrUsages) + cbUsageList);
DEBUGCHK((DWORD) pHidConsumer->puMakeUsages == ((DWORD) pHidConsumer->puBreakUsages) + cbUsageList);
}
#endif // DEBUG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -