📄 hidparser.cxx
字号:
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("Received power event 0x%08x\r\n"),uPowerEvents));
if ((uPowerEvents & (SYS_BUTTON_SLEEP | SYS_BUTTON_POWER)) != 0)
{
keybd_event(VK_OFF, 0, 0, 0);
keybd_event(VK_OFF, 0, KEYEVENTF_KEYUP, 0);
}
}
}
HKEY BTHHIDParser::OpenSpecificClientRegKey(
HKEY hKeyRoot,
const DWORD *pdwVals,
DWORD cdwVals
)
{
HKEY hKeyRet = NULL;
TCHAR szBuf[40];
TCHAR* pszCur = szBuf;
DWORD dwIdx;
int ichWritten;
const TCHAR* pszKey;
DEBUGCHK(cdwVals * 11 + 1 < dim(szBuf));
if (cdwVals == 0) {
// Try default
pszKey = DEFAULT_SZ;
}
else
{
// Build key string
for (dwIdx = 0; dwIdx < cdwVals; ++dwIdx)
{
ichWritten = _stprintf(pszCur, _T("%u_"), pdwVals[dwIdx]);
pszCur += ichWritten;
}
*(pszCur - 1) = 0; // Remove the last _
pszKey = szBuf;
}
RegOpenKeyEx(hKeyRoot, pszKey, 0, 0, &hKeyRet);
return hKeyRet;
}
// Contains most of the logic to find and open the proper HID client key.
// The algorithm searches for the most specific vendor key of the form
// idVendor_idProduct_bcdDevice. Then its subkeys are searched for the most
// specific interface key of the form bInterface_bCollection. Then its
// subkeys are searched for the most specific top level collection key
// of the form UsagePage_Usage.
//
// The order of vendor precedence is described below.
//
// idVendor_idProduct_bcdDevice
// idVendor_idProduct
// idVendor
// Default
//
// The order of interface precedence is described below.
//
// bInterface_bCollection
// bInterface
// Default
//
// The order of TLC precedence is
//
// UsagePage_Usage
// UsagePage
// Default
//
// So the order of checking would be
// 1. idVendor_idProduct_bcdDevice\bInterface_bCollection\UsagePage_Usage
// 2. idVendor_idProduct_bcdDevice\bInterface_bCollection\UsagePage
// 3. idVendor_idProduct_bcdDevice\bInterface_bCollection\Default
// 4. idVendor_idProduct_bcdDevice\bInterface\UsagePage_Usage
// ...
// 7. idVendor_idProduct_bcdDevice\Default\UsagePage_Usage
// ...
// 10. idVendor_idProduct\bInterface_bCollection\UsagePage_Usage
// ...
// 42. Default\bInterface_bCollection\Default
// 43. Default\bInterface\UsagePage_Usage
// 44. Default\bInterface\UsagePage
// 45. Default\bInterface\Default
// 46. Default\Default\UsagePage_Usage
// 47. Default\Default\UsagePage
// 48. Default\Default\Default
//
HKEY
BTHHIDParser::OpenClientRegKey(
HKEY hKeyRoot,
const DWORD *pdwVendorVals,
DWORD cdwVendorVals,
const DWORD *pdwInterfaceVals,
DWORD cdwInterfaceVals,
const DWORD *pdwTLCVals,
DWORD cdwTLCVals,
PHID_DRIVER_SETTINGS pDriverSettingsUsed
)
{
SETFNAME(_T("OpenClientRegKey"));
HKEY hKeyRet = NULL;
HKEY hKeyVendor;
HKEY hKeyInterface;
INT cCurrVendor = -1;
INT cCurrInterface = -1;
INT cCurrTLC = -1;
INT iIdx;
DEBUGCHK(pdwVendorVals != NULL);
DEBUGCHK(pdwInterfaceVals != NULL);
DEBUGCHK(pdwTLCVals != NULL);
for (cCurrVendor = (INT) cdwVendorVals; cCurrVendor >= 0; --cCurrVendor)
{
hKeyVendor = OpenSpecificClientRegKey(hKeyRoot, pdwVendorVals, cCurrVendor);
if (hKeyVendor != NULL)
{
for (cCurrInterface = (INT) cdwInterfaceVals;
cCurrInterface >= 0;
--cCurrInterface)
{
hKeyInterface = OpenSpecificClientRegKey(hKeyVendor, pdwInterfaceVals, cCurrInterface);
if (hKeyInterface != NULL)
{
for (cCurrTLC = (INT) cdwTLCVals; cCurrTLC >= 0; --cCurrTLC)
{
hKeyRet = OpenSpecificClientRegKey(hKeyInterface, pdwTLCVals, cCurrTLC);
if (hKeyRet != NULL) {
// We found our key
break;
}
}
RegCloseKey(hKeyInterface);
if (hKeyRet != NULL) {
// We found our key
break;
}
}
}
RegCloseKey(hKeyVendor);
if (hKeyRet != NULL) {
// We found our key.
break;
}
}
}
if (hKeyRet != NULL) {
// We found a match. Fill in the driver settings used.
PDWORD rgpdwDriverSettings[] = {
&pDriverSettingsUsed->dwVendorId,
&pDriverSettingsUsed->dwProductId,
&pDriverSettingsUsed->dwReleaseNumber,
&pDriverSettingsUsed->dwInterfaceNumber,
&pDriverSettingsUsed->dwCollection,
&pDriverSettingsUsed->dwUsagePage,
&pDriverSettingsUsed->dwUsage,
};
// Fill in the matching vendor info
for (iIdx = 0; iIdx < cCurrVendor; ++iIdx) {
*rgpdwDriverSettings[iIdx] = pdwVendorVals[iIdx];
}
// Fill in the matching interface info
for (iIdx = 0; iIdx < cCurrInterface; ++iIdx) {
*rgpdwDriverSettings[iIdx + cdwVendorVals] = pdwInterfaceVals[iIdx];
}
// Fill in the matching TLC info
for (iIdx = 0; iIdx < cCurrTLC; ++iIdx) {
*rgpdwDriverSettings[iIdx + cdwVendorVals + cdwInterfaceVals]
= pdwTLCVals[iIdx];
}
}
return hKeyRet;
}
// Get the registry key for the HID client that will best service the device
// descripted in pDriverSettings.
// Returns the registry key and the actual driver settings that matched the key.
HKEY
BTHHIDParser::FindClientRegKey(
const HID_DRIVER_SETTINGS *pDriverSettings,
PHID_DRIVER_SETTINGS pDriverSettingsUsed
)
{
SETFNAME(_T("FindClientRegKey"));
const DWORD rgdwVendorVals[] = {
pDriverSettings->dwVendorId,
pDriverSettings->dwProductId,
pDriverSettings->dwReleaseNumber
};
const DWORD rgdwInterfaceVals[] = {
pDriverSettings->dwInterfaceNumber,
pDriverSettings->dwCollection
};
const DWORD rgdwTLCVals[] = {
pDriverSettings->dwUsagePage,
pDriverSettings->dwUsage
};
HKEY hKeyRoot = NULL;
HKEY hKeyRet = NULL;
LONG iErr;
DEBUGCHK(pDriverSettings != NULL);
DEBUGCHK(pDriverSettingsUsed != NULL);
memset(pDriverSettingsUsed, (BYTE) HID_NO_INFO, sizeof(HID_DRIVER_SETTINGS));
iErr = RegOpenKey(HKEY_LOCAL_MACHINE, LOAD_CLIENTS_PATH_SZ, &hKeyRoot);
if (iErr != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ERROR, (_T("%s: Failed opening HID client key [HKLM\\%s]\r\n"),
pszFname, LOAD_CLIENTS_PATH_SZ));
goto EXIT;
}
// Now find the most specific match.
hKeyRet = OpenClientRegKey(hKeyRoot,
rgdwVendorVals, dim(rgdwVendorVals),
rgdwInterfaceVals, dim(rgdwInterfaceVals),
rgdwTLCVals, dim(rgdwTLCVals),
pDriverSettingsUsed);
if (hKeyRet == NULL) {
DEBUGMSG(ZONE_WARNING, (_T("%s: Could not find a suitable HID client driver\r\n"), pszFname));
goto EXIT;
}
EXIT:
if (hKeyRoot != NULL) RegCloseKey(hKeyRoot);
return hKeyRet;
}
IBTHHIDReportHandler* BTHHIDParser::GetHandler()
{
return m_pReportHandler;
}
DWORD GetReport(HID_HANDLE hDevice, HIDP_REPORT_TYPE type, PCHAR pBuffer, DWORD cbBuffer, PDWORD pcbTransferred, DWORD dwTimeout)
{
int iErr = ERROR_INVALID_PARAMETER;
int iReportID = *pBuffer;
PHID_CLIENT_HANDLE pHidClient = (PHID_CLIENT_HANDLE) hDevice;
IBTHHIDParser* pParser = (IBTHHIDParser*) pHidClient->lpvContext;
IBTHHIDReportHandler* pHandler = pParser->GetHandler();
// Skip the report ID
++pBuffer;
--cbBuffer;
DEBUGCHK(pHandler != NULL);
iErr = pHandler->GetReport(iReportID, (E_BTHID_REPORT_TYPES) (type + 1), pBuffer, cbBuffer, pcbTransferred, dwTimeout);
if (iErr != ERROR_SUCCESS)
SetLastError(iErr);
return iErr;
}
DWORD SetReport(HID_HANDLE hDevice, HIDP_REPORT_TYPE type, PCHAR pBuffer, DWORD cbBuffer, DWORD dwTimeout)
{
int iErr = ERROR_INVALID_PARAMETER;
PHID_CLIENT_HANDLE pHidClient = (PHID_CLIENT_HANDLE) hDevice;
IBTHHIDParser* pParser = (IBTHHIDParser*) pHidClient->lpvContext;
IBTHHIDReportHandler* pHandler = pParser->GetHandler();
DEBUGCHK(pHandler != NULL);
iErr = pHandler->SetReport((E_BTHID_REPORT_TYPES) (type + 1), pBuffer, cbBuffer, dwTimeout);
if (iErr != ERROR_SUCCESS)
SetLastError(iErr);
return iErr;
}
DWORD GetInterruptReport(HID_HANDLE hDevice, PCHAR pbBuffer, DWORD cbBuffer, PDWORD pcbTransferred, HANDLE hCancel, DWORD dwTimeout)
{
PHID_CLIENT_HANDLE pHidClient = (PHID_CLIENT_HANDLE) hDevice;
DWORD dwErr;
if (VALID_CLIENT_HANDLE(pHidClient) == FALSE)
{
DEBUGMSG(ZONE_ERROR, (_T("Invalid device handle in GetInterruptReport.\r\n")));
dwErr = ERROR_INVALID_HANDLE;
goto Error;
}
if (pbBuffer == NULL || pcbTransferred == NULL)
{
DEBUGMSG(ZONE_ERROR, (_T("Invalid parameters in GetInterruptReport.\r\n")));
dwErr = ERROR_INVALID_PARAMETER;
goto Error;
}
DEBUGCHK(IsBadWritePtr(pbBuffer, cbBuffer) == FALSE);
DEBUGCHK(IsBadWritePtr(pcbTransferred, sizeof(*pcbTransferred)) == FALSE);
BTHHIDParser::ValidateClientHandleEx(pHidClient);
dwErr = pHidClient->pQueue->Dequeue(pbBuffer, cbBuffer, pcbTransferred,
hCancel, dwTimeout);
Error:
if (dwErr != ERROR_SUCCESS)
SetLastError(dwErr);
return dwErr;
}
IBTHHIDParser* HIDParserAlloc(IBTHHIDReportHandler* pReportHandler)
{
return new BTHHIDParser(pReportHandler);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -