#include #include "stringutils.h" #include "debug.h" #include "util/process.h" #include #include extern "C" { DWORD GetEventData(HANDLE hEvent); BOOL SetEventData(HANDLE hEvent, DWORD dwData); } class HTCKeypadNotifications : public process { HANDLE _hDev; boost::mutex _mtx; struct keymon { HANDLE evfrom; HANDLE evto; int id; int code; }; typedef std::map keymon_map; keymon_map _keys; HANDLE _evchange; public: HTCKeypadNotifications() : _hDev(0) { _evchange= CreateEvent(0,0,0,0); opendev(); start(); } virtual ~HTCKeypadNotifications() { stop(); } virtual void processstop() { } void opendev() { _hDev= CreateFile(_T("KBD1:"), GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL); if (_hDev==NULL || _hDev==INVALID_HANDLE_VALUE) { error("CreateFile-KBD1"); } } bool kbd_ioctl(DWORD code, void *req, int reqlen, void *reply, int replen) { DWORD nReturned=0; if (!DeviceIoControl(_hDev, code, req, reqlen, reply, replen, &nReturned, NULL)) { error("kbd_ioctl 0x%x: err=%08lx", code, GetLastError()); return false; } return true; } // use this to find who is registered: // pmemdump -n device.exe 0x1E3B658 0x60 -4 -x bool kbd_register_notify(int id, int code, bool enable) { struct kbd_register { DWORD dwNotifyID; DWORD byKeyCode; DWORD bIsEnable; DWORD dwUnknown; } request= { id, code, enable?1:0, 0 }; if (enable) addevent(id, code); // else // delevent(id); // // note: size must be either 4 or 0x20 if (!kbd_ioctl(0xb2028, &request, 0x20, 0, 0)) return false; return true; } virtual const char*name() { return "HTCKeypadNotifications"; } virtual void service() { boost::mutex::scoped_lock lock(_mtx); std::vector events; std::vector ids; events.push_back(_evchange); for (keymon_map::iterator i= _keys.begin() ; i!=_keys.end() ; i++) { events.push_back((*i).second.evfrom); ids.push_back((*i).second.id); } // wait for getfrom event debugt("waiting for key\n"); lock.unlock(); DWORD rc= WaitForMultipleObjects(events.size(), &events.front(), FALSE, INFINITE); lock.lock(); debugt(" -> wait : 0x%x, #ids=%d, #ev=%d\n", rc, ids.size(), events.size()); if (rc==WAIT_OBJECT_0) return; if (rc>WAIT_OBJECT_0 && rc0x%x\n", rc); return; } ResetEvent(_evfrom); DWORD data= GetEventData(_evfrom); SetEventData(_evto, 0); SetEvent(_evto); debugt("keypress flag=%x, code=%02x\n", data&15, data>>4); } }; int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { DebugSetLogfile("testphoton.log"); debugt("photon: registering key events\n"); PhotonKeypadNotifications kn; debugt("monitoring\n"); Sleep(20000); return 0; }