RvcDevMnt.cpp 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510
  1. #include "StdAfx.h"
  2. #include "RvcDevMnt.h"
  3. #include "FreeRDPWrapFSM.h"
  4. #include <tchar.h>
  5. #include <strsafe.h>
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #endif
  9. #pragma comment(lib, "SetupAPI.lib")
  10. #pragma comment(lib, "Newdev.lib")
  11. //
  12. // Copied Macros from ntddk.h
  13. //
  14. #define CONTAINING_RECORD(address, type, field) ((type *)( \
  15. (PCHAR)(address) - \
  16. (ULONG_PTR)(&((type *)0)->field)))
  17. #define InitializeListHead(ListHead) (\
  18. (ListHead)->Flink = (ListHead)->Blink = (ListHead))
  19. #define RemoveHeadList(ListHead) \
  20. (ListHead)->Flink;\
  21. {RemoveEntryList((ListHead)->Flink)}
  22. #define IsListEmpty(ListHead) \
  23. ((ListHead)->Flink == (ListHead))
  24. #define RemoveEntryList(Entry) {\
  25. PLIST_ENTRY _EX_Blink;\
  26. PLIST_ENTRY _EX_Flink;\
  27. _EX_Flink = (Entry)->Flink;\
  28. _EX_Blink = (Entry)->Blink;\
  29. _EX_Blink->Flink = _EX_Flink;\
  30. _EX_Flink->Blink = _EX_Blink;\
  31. }
  32. #define InsertTailList(ListHead,Entry) {\
  33. PLIST_ENTRY _EX_Blink;\
  34. PLIST_ENTRY _EX_ListHead;\
  35. _EX_ListHead = (ListHead);\
  36. _EX_Blink = _EX_ListHead->Blink;\
  37. (Entry)->Flink = _EX_ListHead;\
  38. (Entry)->Blink = _EX_Blink;\
  39. _EX_Blink->Flink = (Entry);\
  40. _EX_ListHead->Blink = (Entry);\
  41. }
  42. //
  43. // UpdateDriverForPlugAndPlayDevices
  44. //
  45. typedef BOOL(WINAPI *UpdateDriverForPlugAndPlayDevicesProto)(_In_opt_ HWND hwndParent,
  46. _In_ LPCTSTR HardwareId,
  47. _In_ LPCTSTR FullInfPath,
  48. _In_ DWORD InstallFlags,
  49. _Out_opt_ PBOOL bRebootRequired
  50. );
  51. typedef BOOL(WINAPI *SetupSetNonInteractiveModeProto)(_In_ BOOL NonInteractiveFlag
  52. );
  53. typedef BOOL(WINAPI *SetupUninstallOEMInfProto)(_In_ LPCTSTR InfFileName,
  54. _In_ DWORD Flags,
  55. PVOID Reserved
  56. );
  57. typedef BOOL(WINAPI *DiShowUpdateDeviceProto)(
  58. _In_opt_ HWND hwndParent,
  59. _In_ HDEVINFO DeviceInfoSet,
  60. _In_ PSP_DEVINFO_DATA DeviceInfoData,
  61. _In_ DWORD Flags,
  62. _Out_opt_ PBOOL NeedReboot
  63. );
  64. typedef BOOL(WINAPI *DiInstallDriverProto)(
  65. _In_opt_ HWND hwndParent,
  66. _In_ LPCTSTR FullInfPath,
  67. _In_ DWORD Flags,
  68. _Out_opt_ PBOOL NeedReboot
  69. );
  70. typedef BOOL(WINAPI *DiRollbackDriverProto)(
  71. _In_ HDEVINFO DeviceInfoSet,
  72. _In_ PSP_DEVINFO_DATA DeviceInfoData,
  73. _In_opt_ HWND hwndParent,
  74. _In_ DWORD Flags,
  75. _Out_opt_ PBOOL NeedReboot
  76. );
  77. typedef BOOL(WINAPI *InstallSelectedDriverProto)(
  78. _In_ HWND hwndParent,
  79. _In_ HDEVINFO DeviceInfoSet,
  80. _In_ LPCTSTR Reserved,
  81. _In_ BOOL Backup,
  82. _Out_ PDWORD bReboot
  83. );
  84. #if _SETUPAPI_VER >= _WIN32_WINNT_WINXP
  85. typedef BOOL(WINAPI *SetupVerifyInfFileProto)(_In_ LPCTSTR InfName,
  86. _In_opt_ PSP_ALTPLATFORM_INFO_V2 AltPlatformInfo,
  87. _Inout_ PSP_INF_SIGNER_INFO InfSignerInfo);
  88. #endif
  89. #ifdef _UNICODE
  90. #define UPDATEDRIVERFORPLUGANDPLAYDEVICES "UpdateDriverForPlugAndPlayDevicesW"
  91. #define SETUPUNINSTALLOEMINF "SetupUninstallOEMInfW"
  92. #else
  93. #define UPDATEDRIVERFORPLUGANDPLAYDEVICES "UpdateDriverForPlugAndPlayDevicesA"
  94. #define SETUPUNINSTALLOEMINF "SetupUninstallOEMInfA"
  95. #endif
  96. #define SETUPSETNONINTERACTIVEMODE "SetupSetNonInteractiveMode"
  97. #define SETUPVERIFYINFFILE "SetupVerifyInfFile"
  98. #define DISHOWUPDATEDEVICE "DiShowUpdateDevice"
  99. #define DIINSTALLDRIVER "DiInstallDriver"
  100. #define INSTALLSELECTEDDRIVER "InstallSelectedDriver"
  101. TCHAR DRIVER_NAME[] = "RvcHIDFiltr";
  102. const int DRIVER_NAME_LEN = strlen(DRIVER_NAME);
  103. HINSTANCE hInst;
  104. HWND ghWnd;
  105. LIST_ENTRY ListHead;
  106. LIST_ENTRY ListHeadForMonitor;
  107. HDEVNOTIFY hInterfaceNotification;
  108. HDEVNOTIFY hInterfaceNotificationForMonitor;
  109. static BOOL gbKbdAspire = FALSE;
  110. static BOOL gbMouAspire = FALSE;
  111. static CRITICAL_SECTION csListEntry;
  112. static CRITICAL_SECTION csListEntryForMonitor;
  113. #define Display2(fmt, ...) \
  114. Dbg("< RvcDevMnt> :" fmt, ##__VA_ARGS__)/*; \
  115. printf("< RvcDevMnt> :" fmt "\n", ##__VA_ARGS__)*/
  116. CFreeRDPWrapFSM * pMntFsm = NULL;
  117. void DevMnt_SetReference(PVOID param) {
  118. pMntFsm = reinterpret_cast<CFreeRDPWrapFSM*>(param);
  119. }
  120. UINT ToLowerCase(TCHAR *szChars)
  121. {
  122. if (szChars == NULL) {
  123. return 0;
  124. }
  125. UINT charsLen = lstrlen(szChars);
  126. UINT uCount = 0;
  127. for (UINT i = 0; i < charsLen; ++i) {
  128. if (szChars[i] >= 'A' && szChars[i] <= 'Z') {
  129. szChars[i] = szChars[i] + ('a' - 'A');
  130. uCount++;
  131. }
  132. }
  133. return uCount;
  134. }
  135. UINT ToUpperCase(TCHAR *szChars)
  136. {
  137. if (szChars == NULL) {
  138. return 0;
  139. }
  140. UINT charsLen = lstrlen(szChars);
  141. UINT uCount = 0;
  142. for (UINT i = 0; i < charsLen; ++i) {
  143. if (szChars[i] >= 'a' && szChars[i] <= 'z') {
  144. szChars[i] = szChars[i] + ('A' - 'a');
  145. uCount++;
  146. }
  147. }
  148. return uCount;
  149. }
  150. GUID* StrToGUID(const WCHAR *guid_string)
  151. {
  152. char buffer[64];
  153. GUID* guid = (GUID*)buffer;
  154. WCHAR upperGuid[40 + 1] = { 0 };
  155. for (auto i = 0; i < 40 + 1; i++)
  156. {
  157. upperGuid[i] = guid_string[i];
  158. if (upperGuid[i] >= L'a' && upperGuid[i] <= L'z')
  159. {
  160. upperGuid[i] += L'A' - L'a';
  161. }
  162. }
  163. swscanf_s(upperGuid, L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
  164. &guid->Data1,
  165. &guid->Data2,
  166. &guid->Data3,
  167. &guid->Data4[0],
  168. &guid->Data4[1],
  169. &guid->Data4[2],
  170. &guid->Data4[3],
  171. &guid->Data4[4],
  172. &guid->Data4[5],
  173. &guid->Data4[6],
  174. &guid->Data4[7]);
  175. return guid;
  176. }
  177. static GUID InterfaceGuid = *StrToGUID(L"{4D1E55B2-F16F-11CF-88CB-001111000030}");
  178. static GUID CCDGGuid = *StrToGUID(L"{c8213acc-9fde-4bd3-835a-0e35086c1ecc}");
  179. static GUID KeyboardGuid = *StrToGUID(L"{884b96c3-56ef-11d1-bc8c-00a0c91405dd}");
  180. static GUID MouseGuid = *StrToGUID(L"{378DE44C-56EF-11D1-BC8C-00A0C91405DD}");
  181. static const GUID MONITOR_GUID = {0xE6F07B5F, 0xEE97, 0x4a90,
  182. 0xB0, 0x76, 0x33, 0xF5, 0x7B, 0xF4, 0xEA, 0xA7 };
  183. TCHAR MouseDriverFileName[MAX_PATH] = "D:\\HIDFilter\\RvcMouFiltr.inf";
  184. TCHAR KeyboardDriverFileName[MAX_PATH] = "D:\\HIDFilter\\RvcKbdFiltr.inf";
  185. #define SYS_MOUSE_DRIVERNAME "RvcMouFiltr.inf"
  186. #define SYS_KEYBOARD_DRIVERNAME "RvcKbdFiltr.inf"
  187. void OnDevListChange(BOOL fIncreased);
  188. void OnMonitorChange(int currentCoun);
  189. UINT GetMonitorCount();
  190. BOOL IsDevDeficient(
  191. BOOL& bMouRequired,
  192. BOOL& bKbdRequired,
  193. USHORT* pUsMouCount,
  194. USHORT* pUsKbdCount);
  195. BOOLEAN DeviceNameMatches(LPTSTR DeviceName)
  196. {
  197. BOOLEAN matching = FALSE;
  198. matching = (_tcscmp(KEYBOARD_FRIENDLYNAME, DeviceName) == 0) ? TRUE : FALSE;
  199. if (!matching) {
  200. matching = (_tcscmp(MOUSE_FRIENDLYNAME, DeviceName) == 0) ? TRUE : FALSE;
  201. }
  202. return matching;
  203. }
  204. HANDLE GetDevTypeFromRawInfo(DEVTYPE* type, char* aimDevName)
  205. {
  206. HANDLE hDevice = NULL;
  207. PRAWINPUTDEVICELIST pRawDevList = NULL;
  208. UINT rawDevCount = 0;
  209. UINT uByteSize = 0;
  210. UINT ValidLen;
  211. char* ptGuid = NULL;
  212. if (type == NULL || aimDevName == NULL || strlen(aimDevName) == 0) {
  213. return NULL;
  214. }
  215. ValidLen = strlen(aimDevName);
  216. ptGuid = strchr(aimDevName, '{');
  217. if (ptGuid != NULL) {
  218. if (ptGuid - aimDevName <= 0) {
  219. return NULL;
  220. }
  221. ValidLen = ptGuid - aimDevName;
  222. }
  223. if (GetRawInputDeviceList(NULL, &rawDevCount, sizeof(RAWINPUTDEVICELIST)) != 0) {
  224. Display2("GetRawInputDeviceList error, GLE=%u", GetLastError());
  225. return NULL;
  226. }
  227. pRawDevList = static_cast<PRAWINPUTDEVICELIST>(HeapAlloc(
  228. GetProcessHeap(),
  229. HEAP_ZERO_MEMORY, sizeof(RAWINPUTDEVICELIST)*rawDevCount));
  230. if (pRawDevList == NULL)
  231. {
  232. return NULL;
  233. }
  234. *type = DEV_UNSUPPORT;
  235. UINT tmpDevCount = 0;
  236. if ((tmpDevCount = GetRawInputDeviceList(pRawDevList, &rawDevCount, sizeof(RAWINPUTDEVICELIST)))
  237. == static_cast<UINT>(-1)) {
  238. HeapFree(GetProcessHeap(), 0, pRawDevList);
  239. return NULL;
  240. }
  241. rawDevCount = tmpDevCount;
  242. for (UINT i = 0; i<rawDevCount; ++i) {
  243. UINT uInSize = MAX_PATH * 2;
  244. char devName[MAX_PATH * 2] = { 0 };
  245. UINT uRes1 = GetRawInputDeviceInfo(pRawDevList[i].hDevice,
  246. RIDI_DEVICENAME, devName, &uInSize);
  247. //the item which Conatins "ROOT" seems as combined device ??
  248. if (strstr(devName, "ROOT") != NULL) {
  249. //Display2("Combined device");
  250. continue;
  251. }
  252. ptGuid = strchr(devName, '{');
  253. if (ptGuid != NULL && ptGuid - devName > 0) {
  254. int len = ptGuid - devName;
  255. if (len == ValidLen) {
  256. if (!_strnicmp(devName, aimDevName, len)) {
  257. //Display2("%s(%04x):", devName, pRawDevList[i].hDevice);
  258. RID_DEVICE_INFO devInfo = { 0 };
  259. uInSize = sizeof(RID_DEVICE_INFO);
  260. UINT uRes2 = GetRawInputDeviceInfo(pRawDevList[i].hDevice,
  261. RIDI_DEVICEINFO, &devInfo, &uInSize);
  262. if (devInfo.dwType == RIM_TYPEHID) {
  263. *type = DEV_UNSUPPORT;
  264. }
  265. else if (devInfo.dwType == RIM_TYPEKEYBOARD) {
  266. *type = DEV_KEYBOARD;
  267. }
  268. else if (devInfo.dwType == RIM_TYPEMOUSE) {
  269. *type = DEV_MOUSE;
  270. }
  271. hDevice = pRawDevList[i].hDevice;
  272. break;
  273. }
  274. }
  275. }
  276. }
  277. HeapFree(GetProcessHeap(), 0, pRawDevList);
  278. return hDevice;
  279. }
  280. BOOL DetectAndSetDeviceType(PDEVICE_INFO devInfo)
  281. {
  282. if (devInfo == NULL) {
  283. return FALSE;
  284. }
  285. devInfo->Drivered = FALSE;
  286. devInfo->DevType = DEV_UNSUPPORT;
  287. devInfo->hRawDevice = GetDevTypeFromRawInfo(&devInfo->DevType, devInfo->DevicePath);
  288. if (strlen((LPCTSTR)devInfo->DeviceName) == strlen(KEYBOARD_FRIENDLYNAME)
  289. &&
  290. !memcmp(devInfo->DeviceName, KEYBOARD_FRIENDLYNAME, strlen(KEYBOARD_FRIENDLYNAME))) {
  291. devInfo->Drivered = TRUE;
  292. devInfo->DevType = DEV_KEYBOARD;
  293. }
  294. else if (strlen((LPCTSTR)devInfo->DeviceName) == strlen(MOUSE_FRIENDLYNAME)
  295. &&
  296. !memcmp(devInfo->DeviceName, MOUSE_FRIENDLYNAME, strlen(MOUSE_FRIENDLYNAME))) {
  297. devInfo->Drivered = TRUE;
  298. devInfo->DevType = DEV_MOUSE;
  299. }
  300. return TRUE;
  301. }
  302. BOOL HandleDeviceInterfaceChange(HWND hWnd, DWORD evtype, PDEV_BROADCAST_DEVICEINTERFACE dip)
  303. {
  304. DEV_BROADCAST_HANDLE filter;
  305. PDEVICE_INFO deviceInfo = NULL;
  306. HRESULT hr;
  307. BOOL fNeedOpen = FALSE;
  308. switch (evtype)
  309. {
  310. case DBT_DEVICEARRIVAL:
  311. //
  312. // New device arrived. Open handle to the device
  313. // and register notification of type DBT_DEVTYP_HANDLE
  314. //
  315. deviceInfo = static_cast<PDEVICE_INFO>(HeapAlloc(
  316. GetProcessHeap(),
  317. HEAP_ZERO_MEMORY, sizeof(DEVICE_INFO)));
  318. if (!deviceInfo)
  319. return FALSE;
  320. fNeedOpen = FALSE;
  321. if (!GetDeviceDescription(dip->dbcc_name,
  322. (PBYTE)deviceInfo->DeviceName,
  323. sizeof(deviceInfo->DeviceName),
  324. (PBYTE)deviceInfo->DeviceInstance,
  325. sizeof(deviceInfo->DeviceInstance), &fNeedOpen)) {
  326. //MessageBox(TEXT("GetDeviceDescription failed"), TEXT("Error!"), MB_OK);
  327. }
  328. Display2(TEXT("New device Arrived (Interface Change Notification): %s"),
  329. deviceInfo->DeviceName);
  330. hr = StringCchCopy(deviceInfo->DevicePath, MAX_PATH, dip->dbcc_name);
  331. if (FAILED(hr)){
  332. // DeviceInfo will be freed later by the cleanup routine.
  333. break;
  334. }
  335. if (!DetectAndSetDeviceType(deviceInfo)) {
  336. break;
  337. }
  338. if(deviceInfo->DevType == DEV_UNSUPPORT) {
  339. Display2(TEXT("Needless to the device: %s"), deviceInfo->DeviceName);
  340. break;
  341. }
  342. InitializeListHead(&deviceInfo->ListEntry);
  343. EnterCriticalSection(&csListEntry);
  344. InsertTailList(&ListHead, &deviceInfo->ListEntry);
  345. LeaveCriticalSection(&csListEntry);
  346. OnDevListChange(TRUE);
  347. deviceInfo->hDevice = CreateFile(dip->dbcc_name,
  348. /*GENERIC_READ | GENERIC_WRITE*/0,
  349. FILE_SHARE_READ | FILE_SHARE_WRITE,
  350. NULL,
  351. OPEN_EXISTING, 0, NULL);
  352. if (deviceInfo->hDevice == INVALID_HANDLE_VALUE) {
  353. Display2(TEXT("Failed to open the device: %s"), deviceInfo->DeviceName);
  354. break;
  355. }
  356. Display2(TEXT("Opened handled to the device: %s"), deviceInfo->DeviceName);
  357. memset(&filter, 0, sizeof(filter)); //zero the structure
  358. filter.dbch_size = sizeof(filter);
  359. filter.dbch_devicetype = DBT_DEVTYP_HANDLE;
  360. filter.dbch_handle = deviceInfo->hDevice;
  361. deviceInfo->hHandleNotification =
  362. RegisterDeviceNotification(hWnd, &filter, 0);
  363. break;
  364. case DBT_DEVICEREMOVECOMPLETE:
  365. Display2(TEXT("Remove Complete (Interface Change Notification)"));
  366. break;
  367. //
  368. // Device Removed.
  369. //
  370. default:
  371. Display2(TEXT("Unknown (Interface Change Notification)"));
  372. break;
  373. }
  374. return TRUE;
  375. }
  376. BOOL HandleDeviceChange(HWND hWnd, DWORD evtype, PDEV_BROADCAST_HANDLE dhp)
  377. {
  378. DEV_BROADCAST_HANDLE filter;
  379. PDEVICE_INFO deviceInfo = NULL;
  380. PLIST_ENTRY thisEntry;
  381. //
  382. // Walk the list to get the deviceInfo for this device
  383. // by matching the handle given in the notification.
  384. //
  385. for (thisEntry = ListHead.Flink; thisEntry != &ListHead;
  386. thisEntry = thisEntry->Flink)
  387. {
  388. deviceInfo = CONTAINING_RECORD(thisEntry, DEVICE_INFO, ListEntry);
  389. if (dhp->dbch_hdevnotify == deviceInfo->hHandleNotification) {
  390. break;
  391. }
  392. deviceInfo = NULL;
  393. }
  394. if (!deviceInfo) {
  395. Display2(TEXT("Error: spurious message, Event Type %x, Device Type %x"),
  396. evtype, dhp->dbch_devicetype);
  397. return FALSE;
  398. }
  399. switch (evtype)
  400. {
  401. case DBT_DEVICEQUERYREMOVE:
  402. Display2(TEXT("Query Remove (Handle Notification) %s"), deviceInfo->DeviceName);
  403. // User is trying to disable, uninstall, or eject our device.
  404. // Close the handle to the device so that the target device can
  405. // get removed. Do not unregister the notification
  406. // at this point, because we want to know whether
  407. // the device is successfully removed or not.
  408. //
  409. if (deviceInfo->hDevice != INVALID_HANDLE_VALUE) {
  410. CloseHandle(deviceInfo->hDevice);
  411. deviceInfo->hDevice = INVALID_HANDLE_VALUE;
  412. Display2(TEXT("Closed handle to device %s"), deviceInfo->DeviceName);
  413. }
  414. break;
  415. case DBT_DEVICEREMOVECOMPLETE:
  416. Display2(TEXT("Remove Complete (Handle Notification):%s"),
  417. deviceInfo->DeviceName);
  418. //
  419. // Device is getting surprise removed. So close
  420. // the handle to device and unregister the PNP notification.
  421. //
  422. if (deviceInfo->hHandleNotification) {
  423. UnregisterDeviceNotification(deviceInfo->hHandleNotification);
  424. deviceInfo->hHandleNotification = NULL;
  425. }
  426. if (deviceInfo->hDevice != INVALID_HANDLE_VALUE) {
  427. CloseHandle(deviceInfo->hDevice);
  428. deviceInfo->hDevice = INVALID_HANDLE_VALUE;
  429. Display2(TEXT("Closed handle to device %s"), deviceInfo->DeviceName);
  430. }
  431. //
  432. // Unlink this deviceInfo from the list and free the memory
  433. //
  434. EnterCriticalSection(&csListEntry);
  435. RemoveEntryList(&deviceInfo->ListEntry);
  436. LeaveCriticalSection(&csListEntry);
  437. HeapFree(GetProcessHeap(), 0, deviceInfo);
  438. OnDevListChange(FALSE);
  439. break;
  440. case DBT_DEVICEREMOVEPENDING:
  441. Display2(TEXT("Remove Pending (Handle Notification):%s"),
  442. deviceInfo->DeviceName);
  443. //
  444. // Device is successfully removed so unregister the notification
  445. // and free the memory.
  446. //
  447. if (deviceInfo->hHandleNotification) {
  448. UnregisterDeviceNotification(deviceInfo->hHandleNotification);
  449. deviceInfo->hHandleNotification = NULL;
  450. deviceInfo->hDevice = INVALID_HANDLE_VALUE;
  451. }
  452. //
  453. // Unlink this deviceInfo from the list and free the memory
  454. //
  455. EnterCriticalSection(&csListEntry);
  456. RemoveEntryList(&deviceInfo->ListEntry);
  457. LeaveCriticalSection(&csListEntry);
  458. HeapFree(GetProcessHeap(), 0, deviceInfo);
  459. OnDevListChange(FALSE);
  460. break;
  461. case DBT_DEVICEQUERYREMOVEFAILED:
  462. Display2(TEXT("Remove failed (Handle Notification):%s"), deviceInfo->DeviceName);
  463. //
  464. // Remove failed. So reopen the device and register for
  465. // notification on the new handle. But first we should unregister
  466. // the previous notification.
  467. //
  468. if (deviceInfo->hHandleNotification) {
  469. UnregisterDeviceNotification(deviceInfo->hHandleNotification);
  470. deviceInfo->hHandleNotification = NULL;
  471. }
  472. deviceInfo->hDevice = CreateFile(deviceInfo->DevicePath,
  473. /*GENERIC_READ | GENERIC_WRITE*/0,
  474. FILE_SHARE_READ | FILE_SHARE_WRITE,
  475. NULL, OPEN_EXISTING, 0, NULL);
  476. if (deviceInfo->hDevice == INVALID_HANDLE_VALUE) {
  477. Display2(TEXT("Failed to reopen the device: %s"),
  478. deviceInfo->DeviceName);
  479. HeapFree(GetProcessHeap(), 0, deviceInfo);
  480. break;
  481. }
  482. //
  483. // Register handle based notification to receive pnp
  484. // device change notification on the handle.
  485. //
  486. memset(&filter, 0, sizeof(filter)); //zero the structure
  487. filter.dbch_size = sizeof(filter);
  488. filter.dbch_devicetype = DBT_DEVTYP_HANDLE;
  489. filter.dbch_handle = deviceInfo->hDevice;
  490. deviceInfo->hHandleNotification =
  491. RegisterDeviceNotification(hWnd, &filter, 0);
  492. Display2(TEXT("Reopened device %s"), deviceInfo->DeviceName);
  493. break;
  494. default:
  495. Display2(TEXT("Unknown (Handle Notification)"), deviceInfo->DeviceName);
  496. break;
  497. }
  498. return TRUE;
  499. }
  500. BOOL HandleMonitorInterfaceChange(HWND hWnd, DWORD evType, PDEV_BROADCAST_DEVICEINTERFACE dip)
  501. {
  502. DEV_BROADCAST_HANDLE filter;
  503. PDEVICE_INFO deviceInfo = NULL;
  504. HRESULT hr;
  505. BOOL fNoUsed = FALSE;
  506. switch (evType)
  507. {
  508. case DBT_DEVICEARRIVAL:
  509. deviceInfo = static_cast<PDEVICE_INFO>(HeapAlloc(
  510. GetProcessHeap(),
  511. HEAP_ZERO_MEMORY, sizeof(DEVICE_INFO)));
  512. if (!deviceInfo)
  513. {
  514. return FALSE;
  515. }
  516. GetDeviceDescription(dip->dbcc_name,
  517. (PBYTE)deviceInfo->DeviceName,
  518. sizeof(deviceInfo->DeviceName),
  519. (PBYTE)deviceInfo->DeviceInstance,
  520. sizeof(deviceInfo->DeviceInstance), &fNoUsed);
  521. Display2(TEXT("New Monitor Arrived (Interface Change Notification): %s"),
  522. deviceInfo->DeviceName);
  523. hr = StringCchCopy(deviceInfo->DevicePath, MAX_PATH, dip->dbcc_name);
  524. if (FAILED(hr)) {
  525. break;
  526. }
  527. InitializeListHead(&deviceInfo->ListEntry);
  528. EnterCriticalSection(&csListEntryForMonitor);
  529. InsertTailList(&ListHeadForMonitor, &deviceInfo->ListEntry);
  530. LeaveCriticalSection(&csListEntryForMonitor);
  531. OnMonitorChange(GetMonitorCount());
  532. deviceInfo->hDevice = CreateFile(dip->dbcc_name,
  533. /*GENERIC_READ | GENERIC_WRITE*/0,
  534. FILE_SHARE_READ | FILE_SHARE_WRITE,
  535. NULL,
  536. OPEN_EXISTING, 0, NULL);
  537. if (deviceInfo->hDevice == INVALID_HANDLE_VALUE) {
  538. Display2(TEXT("Failed to open the device: %s"), deviceInfo->DeviceName);
  539. break;
  540. }
  541. Display2(TEXT("Opened handled to the Monitor device: %s"), deviceInfo->DeviceName);
  542. memset(&filter, 0, sizeof(filter)); //zero the structure
  543. filter.dbch_size = sizeof(filter);
  544. filter.dbch_devicetype = DBT_DEVTYP_HANDLE;
  545. filter.dbch_handle = deviceInfo->hDevice;
  546. deviceInfo->hHandleNotification =
  547. RegisterDeviceNotification(hWnd, &filter, 0);
  548. break;
  549. case DBT_DEVICEREMOVECOMPLETE:
  550. Display2(TEXT("Monitor Remove Complete (Interface Change Notification)"));
  551. break;
  552. default:
  553. Display2(TEXT("Monitor Unknown (Interface Change Notification)"));
  554. break;
  555. }
  556. return TRUE;
  557. }
  558. BOOL HandleMonitorChange(HWND hWnd, DWORD evType, PDEV_BROADCAST_HANDLE dhp)
  559. {
  560. DEV_BROADCAST_HANDLE filter;
  561. PDEVICE_INFO deviceInfo = NULL;
  562. PLIST_ENTRY thisEntry;
  563. for (thisEntry = ListHeadForMonitor.Flink; thisEntry != &ListHeadForMonitor;
  564. thisEntry = thisEntry->Flink)
  565. {
  566. deviceInfo = CONTAINING_RECORD(thisEntry, DEVICE_INFO, ListEntry);
  567. if (dhp->dbch_hdevnotify == deviceInfo->hHandleNotification) {
  568. break;
  569. }
  570. deviceInfo = NULL;
  571. }
  572. if (!deviceInfo) {
  573. Display2(TEXT("Monitor Error: spurious message, Event Type %x, Device Type %x"),
  574. evType, dhp->dbch_devicetype);
  575. return FALSE;
  576. }
  577. switch (evType)
  578. {
  579. case DBT_DEVICEQUERYREMOVE:
  580. Display2(TEXT("Monitor Remove (Handle Notification) %s"), deviceInfo->DeviceName);
  581. if (deviceInfo->hDevice != INVALID_HANDLE_VALUE) {
  582. CloseHandle(deviceInfo->hDevice);
  583. deviceInfo->hDevice = INVALID_HANDLE_VALUE;
  584. Display2(TEXT("Closed handle to device %s"), deviceInfo->DeviceName);
  585. }
  586. break;
  587. case DBT_DEVICEREMOVECOMPLETE:
  588. Display2(TEXT("Monitor Remove Complete (Handle Notification):%s"),
  589. deviceInfo->DeviceName);
  590. if (deviceInfo->hHandleNotification) {
  591. UnregisterDeviceNotification(deviceInfo->hHandleNotification);
  592. deviceInfo->hHandleNotification = NULL;
  593. }
  594. if (deviceInfo->hDevice != INVALID_HANDLE_VALUE) {
  595. CloseHandle(deviceInfo->hDevice);
  596. deviceInfo->hDevice = INVALID_HANDLE_VALUE;
  597. Display2(TEXT("Closed handle to device %s"), deviceInfo->DeviceName);
  598. }
  599. EnterCriticalSection(&csListEntryForMonitor);
  600. RemoveEntryList(&deviceInfo->ListEntry);
  601. LeaveCriticalSection(&csListEntryForMonitor);
  602. HeapFree(GetProcessHeap(), 0, deviceInfo);
  603. OnMonitorChange(GetMonitorCount());
  604. break;
  605. case DBT_DEVICEREMOVEPENDING:
  606. Display2(TEXT("Monitor Remove Pending (Handle Notification):%s"),
  607. deviceInfo->DeviceName);
  608. if (deviceInfo->hHandleNotification) {
  609. UnregisterDeviceNotification(deviceInfo->hHandleNotification);
  610. deviceInfo->hHandleNotification = NULL;
  611. deviceInfo->hDevice = INVALID_HANDLE_VALUE;
  612. }
  613. EnterCriticalSection(&csListEntryForMonitor);
  614. RemoveEntryList(&deviceInfo->ListEntry);
  615. LeaveCriticalSection(&csListEntryForMonitor);
  616. HeapFree(GetProcessHeap(), 0, deviceInfo);
  617. OnMonitorChange(GetMonitorCount());
  618. break;
  619. case DBT_DEVICEQUERYREMOVEFAILED:
  620. Display2(TEXT("Monitor Remove failed (Handle Notification):%s"), deviceInfo->DeviceName);
  621. if (deviceInfo->hHandleNotification) {
  622. UnregisterDeviceNotification(deviceInfo->hHandleNotification);
  623. deviceInfo->hHandleNotification = NULL;
  624. }
  625. deviceInfo->hDevice = CreateFile(deviceInfo->DevicePath,
  626. /*GENERIC_READ | GENERIC_WRITE*/0,
  627. FILE_SHARE_READ | FILE_SHARE_WRITE,
  628. NULL, OPEN_EXISTING, 0, NULL);
  629. if (deviceInfo->hDevice == INVALID_HANDLE_VALUE) {
  630. Display2(TEXT("Failed to reopen the device: %s"),
  631. deviceInfo->DeviceName);
  632. HeapFree(GetProcessHeap(), 0, deviceInfo);
  633. break;
  634. }
  635. memset(&filter, 0, sizeof(filter)); //zero the structure
  636. filter.dbch_size = sizeof(filter);
  637. filter.dbch_devicetype = DBT_DEVTYP_HANDLE;
  638. filter.dbch_handle = deviceInfo->hDevice;
  639. deviceInfo->hHandleNotification =
  640. RegisterDeviceNotification(hWnd, &filter, 0);
  641. Display2(TEXT("Reopened Monitor device %s"), deviceInfo->DeviceName);
  642. break;
  643. default:
  644. Display2(TEXT("Monitor Unknown (Handle Notification)"), deviceInfo->DeviceName);
  645. break;
  646. }
  647. return TRUE;
  648. }
  649. BOOLEAN Cleanup(HWND hWnd)
  650. {
  651. PDEVICE_INFO deviceInfo = NULL;
  652. PLIST_ENTRY thisEntry;
  653. EnterCriticalSection(&csListEntry);
  654. while (!IsListEmpty(&ListHead)) {
  655. thisEntry = RemoveHeadList(&ListHead);
  656. deviceInfo = CONTAINING_RECORD(thisEntry, DEVICE_INFO, ListEntry);
  657. if (deviceInfo->hHandleNotification) {
  658. UnregisterDeviceNotification(deviceInfo->hHandleNotification);
  659. deviceInfo->hHandleNotification = NULL;
  660. }
  661. if (deviceInfo->hDevice != INVALID_HANDLE_VALUE &&
  662. deviceInfo->hDevice != NULL) {
  663. CloseHandle(deviceInfo->hDevice);
  664. deviceInfo->hDevice = INVALID_HANDLE_VALUE;
  665. Display2(TEXT("Closed handle to device %s"), deviceInfo->DeviceName);
  666. }
  667. HeapFree(GetProcessHeap(), 0, deviceInfo);
  668. }
  669. LeaveCriticalSection(&csListEntry);
  670. EnterCriticalSection(&csListEntryForMonitor);
  671. while (!IsListEmpty(&ListHeadForMonitor)) {
  672. thisEntry = RemoveHeadList(&ListHeadForMonitor);
  673. deviceInfo = CONTAINING_RECORD(thisEntry, DEVICE_INFO, ListEntry);
  674. if (deviceInfo->hHandleNotification) {
  675. UnregisterDeviceNotification(deviceInfo->hHandleNotification);
  676. deviceInfo->hHandleNotification = NULL;
  677. }
  678. if (deviceInfo->hDevice != INVALID_HANDLE_VALUE &&
  679. deviceInfo->hDevice != NULL) {
  680. CloseHandle(deviceInfo->hDevice);
  681. deviceInfo->hDevice = INVALID_HANDLE_VALUE;
  682. Display2(TEXT("Closed handle to device %s"), deviceInfo->DeviceName);
  683. }
  684. HeapFree(GetProcessHeap(), 0, deviceInfo);
  685. }
  686. LeaveCriticalSection(&csListEntryForMonitor);
  687. return TRUE;
  688. }
  689. DWORD WINAPI DevMnt_MainWndStartAndLoop(LPVOID param)
  690. {
  691. static TCHAR szAppName[]=TEXT("Rvc InOut Device Management");
  692. static TCHAR szTitle[] =TEXT("Rvc InOut Device Application");
  693. HWND hWnd;
  694. MSG msg;
  695. WNDCLASS wndclass;
  696. HINSTANCE hInstance = GetModuleHandle (NULL);
  697. BOOL fGotMessage;
  698. wndclass.style = CS_HREDRAW | CS_VREDRAW;
  699. wndclass.lpfnWndProc = WndProc;
  700. wndclass.cbClsExtra = 0;
  701. wndclass.cbWndExtra = 0;
  702. wndclass.hInstance = hInstance;
  703. wndclass.hIcon = NULL;
  704. wndclass.hCursor = NULL;
  705. wndclass.hbrBackground= NULL;
  706. wndclass.lpszMenuName = NULL;
  707. wndclass.lpszClassName= szAppName;
  708. RegisterClass(&wndclass);
  709. hWnd = CreateWindow (szAppName,
  710. szTitle,
  711. WS_OVERLAPPEDWINDOW,
  712. CW_USEDEFAULT,
  713. CW_USEDEFAULT,
  714. CW_USEDEFAULT,
  715. CW_USEDEFAULT,
  716. NULL,
  717. NULL,
  718. hInstance,
  719. NULL);
  720. if(!hWnd) {
  721. return (0);
  722. }
  723. ghWnd = hWnd;
  724. ShowWindow (hWnd, SW_HIDE);
  725. UpdateWindow(hWnd);
  726. while ((fGotMessage = GetMessage (&msg, NULL, 0,0)) != 0 && fGotMessage != -1)
  727. {
  728. TranslateMessage(&msg);
  729. DispatchMessage(&msg);
  730. }
  731. return (0);
  732. }
  733. void DevMnt_Terminate()
  734. {
  735. SendMessage(ghWnd, WM_CLOSE, 0, 0);
  736. return;
  737. }
  738. BOOL CALLBACK MyInfoEnumProc(
  739. HMONITOR hMonitor,
  740. HDC hdcMonitor,
  741. LPRECT lprcMonitor,
  742. LPARAM dwData
  743. )
  744. {
  745. MONITORINFOEX mi;
  746. ZeroMemory(&mi, sizeof(mi));
  747. mi.cbSize = sizeof(mi);
  748. GetMonitorInfo(hMonitor, &mi);
  749. Display2(TEXT("DisplayDevice %s"), mi.szDevice);
  750. return TRUE;
  751. }
  752. UINT GetMonitorCount()
  753. {
  754. PLIST_ENTRY thisEntry;
  755. PDEVICE_INFO deviceInfo = NULL;
  756. UINT result = 0;
  757. EnterCriticalSection(&csListEntryForMonitor);
  758. for (thisEntry = ListHeadForMonitor.Flink; thisEntry != &ListHeadForMonitor;
  759. thisEntry = thisEntry->Flink)
  760. {
  761. deviceInfo = CONTAINING_RECORD(thisEntry, DEVICE_INFO, ListEntry);
  762. if (deviceInfo != NULL) {
  763. result++;
  764. }
  765. }
  766. LeaveCriticalSection(&csListEntryForMonitor);
  767. UINT screenNum = GetSystemMetrics(SM_CMONITORS);
  768. if(screenNum != result)
  769. {
  770. Display2(TEXT("WARNING: ListEntry'Count: %d, GetSystemMetrics'Count %d"), result, screenNum);
  771. }
  772. return result;
  773. }
  774. BOOL IsDevDeficient(
  775. BOOL& bMouRequired,
  776. BOOL& bKbdRequired,
  777. USHORT* pUsMouCount,
  778. USHORT* pUsKbdCount)
  779. {
  780. PLIST_ENTRY thisEntry;
  781. PDEVICE_INFO deviceInfo = NULL;
  782. USHORT kbdCount, mouCount, kbdDrvdCount, mouDrvdCount;
  783. bMouRequired = bKbdRequired = FALSE;
  784. kbdCount = mouCount = kbdDrvdCount = mouDrvdCount = 0;
  785. EnterCriticalSection(&csListEntry);
  786. for (thisEntry = ListHead.Flink; thisEntry != &ListHead;
  787. thisEntry = thisEntry->Flink)
  788. {
  789. deviceInfo = CONTAINING_RECORD(thisEntry, DEVICE_INFO, ListEntry);
  790. if (deviceInfo && deviceInfo->DevType != DEV_UNSUPPORT) {
  791. if (deviceInfo->DevType == DEV_MOUSE) {
  792. if(deviceInfo->Drivered)
  793. {mouDrvdCount++;}
  794. else
  795. {mouCount++;}
  796. }else if(deviceInfo->DevType == DEV_KEYBOARD) {
  797. if(deviceInfo->Drivered)
  798. {kbdDrvdCount++;}
  799. else
  800. {kbdCount++;}
  801. }
  802. }
  803. }
  804. LeaveCriticalSection(&csListEntry);
  805. if(pUsKbdCount != NULL) {
  806. *pUsKbdCount = kbdCount + kbdDrvdCount;
  807. }
  808. if(pUsMouCount != NULL) {
  809. *pUsMouCount = mouCount + mouDrvdCount;
  810. }
  811. if(mouDrvdCount == 0) {
  812. bMouRequired = TRUE;
  813. }
  814. if(kbdDrvdCount == 0) {
  815. bKbdRequired = TRUE;
  816. }
  817. return (bMouRequired || bKbdRequired);
  818. }
  819. LRESULT
  820. FAR PASCAL
  821. WndProc (
  822. HWND hWnd,
  823. UINT message,
  824. WPARAM wParam,
  825. LPARAM lParam
  826. )
  827. {
  828. DWORD nEventType = (DWORD)wParam;
  829. PDEV_BROADCAST_HDR p = (PDEV_BROADCAST_HDR) lParam;
  830. DEV_BROADCAST_DEVICEINTERFACE filter;
  831. switch (message)
  832. {
  833. case WM_CREATE:
  834. filter.dbcc_size = sizeof(filter);
  835. filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
  836. filter.dbcc_classguid = InterfaceGuid;
  837. hInterfaceNotification = RegisterDeviceNotification(hWnd, &filter, 0);
  838. filter.dbcc_size = sizeof(filter);
  839. filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
  840. filter.dbcc_classguid = MONITOR_GUID;
  841. hInterfaceNotificationForMonitor = RegisterDeviceNotification(hWnd, &filter, 0);
  842. if(hInterfaceNotificationForMonitor == NULL)
  843. {
  844. Display2("RegisterDeviceNotification for monitor failed, GLE=%u", GetLastError());
  845. }
  846. InitializeCriticalSection(&csListEntry);
  847. InitializeListHead(&ListHead);
  848. InitializeCriticalSection(&csListEntryForMonitor);
  849. InitializeListHead(&ListHeadForMonitor);
  850. if(RegisterHIDDeviceNotification(hWnd)) {
  851. OnDevListChange(TRUE);
  852. }
  853. RegisterMonitorDeviceNotification(hWnd);
  854. #ifdef TWINKLE_LOCAL_DEBUG
  855. GetMonitorCount();
  856. #endif // TWINKLE_LOCAL_DEBUG
  857. return 0;
  858. case WM_DEVICECHANGE:
  859. //
  860. // The DBT_DEVNODES_CHANGED broadcast message is sent
  861. // everytime a device is added or removed. This message
  862. // is typically handled by Device Manager kind of apps,
  863. // which uses it to refresh window whenever something changes.
  864. // The lParam is always NULL in this case.
  865. //
  866. if (DBT_DEVNODES_CHANGED == wParam) {
  867. //Display2(TEXT("Received DBT_DEVNODES_CHANGED broadcast message"));
  868. return 0;
  869. }
  870. //
  871. // All the events we're interested in come with lParam pointing to
  872. // a structure headed by a DEV_BROADCAST_HDR. This is denoted by
  873. // bit 15 of wParam being set, and bit 14 being clear.
  874. //
  875. if ((wParam & 0xC000) == 0x8000) {
  876. if (!p)
  877. return 0;
  878. if (p->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
  879. PDEV_BROADCAST_DEVICEINTERFACE b = (PDEV_BROADCAST_DEVICEINTERFACE)lParam;
  880. if (IsEqualGUID(b->dbcc_classguid, MONITOR_GUID)) {
  881. Display2(TEXT("Received DBT_DEVTYP_DEVICEINTERFACE for monitor..."));
  882. HandleMonitorInterfaceChange(hWnd, nEventType, (PDEV_BROADCAST_DEVICEINTERFACE)p);
  883. return 0;
  884. }
  885. HandleDeviceInterfaceChange(hWnd, nEventType, (PDEV_BROADCAST_DEVICEINTERFACE)p);
  886. } else if (p->dbch_devicetype == DBT_DEVTYP_HANDLE) {
  887. if(!HandleDeviceChange(hWnd, nEventType, (PDEV_BROADCAST_HANDLE)p))
  888. {
  889. HandleMonitorChange(hWnd, nEventType, (PDEV_BROADCAST_HANDLE)p);
  890. }
  891. }
  892. }
  893. return 0;
  894. case WM_POWERBROADCAST:
  895. HandlePowerBroadcast(hWnd, wParam, lParam);
  896. return 0;
  897. case WM_CLOSE:
  898. Cleanup(hWnd);
  899. UnregisterDeviceNotification(hInterfaceNotification);
  900. UnregisterDeviceNotification(hInterfaceNotificationForMonitor);
  901. DeleteCriticalSection(&csListEntry);
  902. DeleteCriticalSection(&csListEntryForMonitor);
  903. return DefWindowProc(hWnd, message, wParam, lParam);
  904. case WM_DESTROY:
  905. PostQuitMessage(0);
  906. return 0;
  907. }
  908. return DefWindowProc(hWnd, message, wParam, lParam);
  909. }
  910. BOOLEAN RegisterDevNotification(HWND hWnd, BOOL bHID)
  911. {
  912. HDEVINFO hardwareDeviceInfo;
  913. SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
  914. PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = NULL;
  915. SP_CLASSIMAGELIST_DATA deviceClassImageData;
  916. SP_DEVINFO_DATA devInfo;
  917. ULONG predictedLength = 0;
  918. ULONG requiredLength = 0;
  919. DWORD error;
  920. DEV_BROADCAST_HANDLE filter;
  921. PDEVICE_INFO deviceInfo = NULL;
  922. UINT i = 0;
  923. HRESULT hr;
  924. hardwareDeviceInfo = SetupDiGetClassDevs(
  925. (bHID ? (LPGUID)&InterfaceGuid : (LPGUID)&MONITOR_GUID),
  926. NULL, // Define no enumerator (global)
  927. NULL, // Define no
  928. (DIGCF_PRESENT | // Only Devices present
  929. DIGCF_DEVICEINTERFACE)); // Function class devices.
  930. if (INVALID_HANDLE_VALUE == hardwareDeviceInfo)
  931. {
  932. goto Error;
  933. }
  934. //
  935. // Enumerate devices of toaster class
  936. //
  937. deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);
  938. deviceClassImageData.cbSize = sizeof(deviceClassImageData);
  939. SetupDiGetClassImageList(&deviceClassImageData);
  940. ZeroMemory(&devInfo, sizeof(SP_DEVINFO_DATA));
  941. devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
  942. for (i = 0; SetupDiEnumDeviceInterfaces(hardwareDeviceInfo,
  943. 0, // No care about specific PDOs
  944. (bHID ? (LPGUID)&InterfaceGuid : (LPGUID)&MONITOR_GUID),
  945. i, //
  946. &deviceInterfaceData); i++) {
  947. //
  948. // Allocate a function class device data structure to
  949. // receive the information about this particular device.
  950. //
  951. //
  952. // First find out required length of the buffer
  953. //
  954. if (deviceInterfaceDetailData)
  955. {
  956. HeapFree(GetProcessHeap(), 0, deviceInterfaceDetailData);
  957. deviceInterfaceDetailData = NULL;
  958. }
  959. if (!SetupDiGetDeviceInterfaceDetail(
  960. hardwareDeviceInfo,
  961. &deviceInterfaceData,
  962. NULL, // probing so no output buffer yet
  963. 0, // probing so output buffer length of zero
  964. &requiredLength,
  965. NULL) && (error = GetLastError()) != ERROR_INSUFFICIENT_BUFFER)
  966. {
  967. goto Error;
  968. }
  969. predictedLength = requiredLength;
  970. deviceInterfaceDetailData = static_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA>(
  971. HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
  972. predictedLength));
  973. if (deviceInterfaceDetailData == NULL) {
  974. goto Error;
  975. }
  976. deviceInterfaceDetailData->cbSize =
  977. sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
  978. if (!SetupDiGetDeviceInterfaceDetail(
  979. hardwareDeviceInfo,
  980. &deviceInterfaceData,
  981. deviceInterfaceDetailData,
  982. predictedLength,
  983. &requiredLength,
  984. NULL))
  985. {
  986. goto Error;
  987. }
  988. deviceInfo = static_cast<PDEVICE_INFO>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
  989. sizeof(DEVICE_INFO)));
  990. if (deviceInfo == NULL)
  991. {
  992. goto Error;
  993. }
  994. //
  995. // Get the device details such as friendly name and SerialNo
  996. //
  997. BOOL fNeedOpen = FALSE;
  998. if (!GetDeviceDescription(deviceInterfaceDetailData->DevicePath,
  999. (PBYTE)deviceInfo->DeviceName,
  1000. sizeof(deviceInfo->DeviceName),
  1001. (PBYTE)deviceInfo->DeviceInstance,
  1002. sizeof(deviceInfo->DeviceInstance), &fNeedOpen) && bHID)
  1003. {
  1004. goto Error;
  1005. }
  1006. Display2(TEXT("Device: %s, %s"), deviceInfo->DeviceName, deviceInfo->DeviceInstance);
  1007. hr = StringCchCopy(deviceInfo->DevicePath, MAX_PATH, deviceInterfaceDetailData->DevicePath);
  1008. if (FAILED(hr))
  1009. {
  1010. goto Error;
  1011. }
  1012. if (bHID && !DetectAndSetDeviceType(deviceInfo)) {
  1013. goto Error;
  1014. }
  1015. if(bHID && deviceInfo->DevType == DEV_UNSUPPORT) {
  1016. Display2(TEXT("Needless to the device: %s"), deviceInfo->DeviceName);
  1017. continue;
  1018. }
  1019. //Display2(TEXT("==:%s"), deviceInterfaceDetailData->DevicePath);
  1020. //Display2(TEXT("==:%s"), deviceInfo->DeviceName);
  1021. //Display2(TEXT("==:%s"), deviceInfo->DeviceInstance);
  1022. //Display2(TEXT("==:%d"), deviceInfo->DevType);
  1023. InitializeListHead(&deviceInfo->ListEntry);
  1024. if(bHID)
  1025. {
  1026. EnterCriticalSection(&csListEntry);
  1027. InsertTailList(&ListHead, &deviceInfo->ListEntry);
  1028. LeaveCriticalSection(&csListEntry);
  1029. }
  1030. else
  1031. {
  1032. EnterCriticalSection(&csListEntryForMonitor);
  1033. InsertTailList(&ListHeadForMonitor, &deviceInfo->ListEntry);
  1034. LeaveCriticalSection(&csListEntryForMonitor);
  1035. }
  1036. //
  1037. // Open an handle to the device.
  1038. //
  1039. deviceInfo->hDevice = CreateFile(
  1040. deviceInterfaceDetailData->DevicePath,
  1041. /*GENERIC_READ | GENERIC_WRITE*/0,
  1042. FILE_SHARE_READ | FILE_SHARE_WRITE,
  1043. NULL, // no SECURITY_ATTRIBUTES structure
  1044. OPEN_EXISTING, // No special create flags
  1045. 0, // No special attributes
  1046. NULL);
  1047. if (INVALID_HANDLE_VALUE == deviceInfo->hDevice) {
  1048. Display2(TEXT("Failed to open the device: %s"), deviceInfo->DeviceName);
  1049. continue;
  1050. }
  1051. Display2(TEXT("Opened handled to the device: %s"), deviceInfo->DeviceName);
  1052. //
  1053. // Register handle based notification to receive pnp
  1054. // device change notification on the handle.
  1055. //
  1056. memset(&filter, 0, sizeof(filter)); //zero the structure
  1057. filter.dbch_size = sizeof(filter);
  1058. filter.dbch_devicetype = DBT_DEVTYP_HANDLE;
  1059. filter.dbch_handle = deviceInfo->hDevice;
  1060. deviceInfo->hHandleNotification = RegisterDeviceNotification(hWnd, &filter, 0);
  1061. }
  1062. if (deviceInterfaceDetailData)
  1063. HeapFree(GetProcessHeap(), 0, deviceInterfaceDetailData);
  1064. SetupDiDestroyDeviceInfoList(hardwareDeviceInfo);
  1065. return 1;
  1066. Error:
  1067. if (deviceInterfaceDetailData)
  1068. HeapFree(GetProcessHeap(), 0, deviceInterfaceDetailData);
  1069. SetupDiDestroyDeviceInfoList(hardwareDeviceInfo);
  1070. Cleanup(hWnd);
  1071. return 0;
  1072. }
  1073. BOOLEAN RegisterHIDDeviceNotification(HWND hWnd)
  1074. {
  1075. return RegisterDevNotification(hWnd, TRUE);
  1076. }
  1077. BOOLEAN RegisterMonitorDeviceNotification(HWND hWnd)
  1078. {
  1079. return RegisterDevNotification(hWnd, FALSE);
  1080. }
  1081. BOOL GetDeviceDescription(
  1082. LPTSTR DevPath,
  1083. PBYTE DevName, ULONG DevNameLen,
  1084. PBYTE DevInstance, ULONG InstanceLen, BOOL* pNeedOpen)
  1085. {
  1086. HDEVINFO hardwareDeviceInfo;
  1087. SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
  1088. SP_DEVINFO_DATA deviceInfoData;
  1089. DWORD dwRegType, error;
  1090. //hardwareDeviceInfo = SetupDiCreateDeviceInfoList(NULL, NULL);
  1091. //if (INVALID_HANDLE_VALUE == hardwareDeviceInfo)
  1092. //{
  1093. // goto Error;
  1094. //}
  1095. hardwareDeviceInfo = SetupDiGetClassDevs(&InterfaceGuid,
  1096. NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
  1097. if (INVALID_HANDLE_VALUE == hardwareDeviceInfo) {
  1098. goto Error;
  1099. }
  1100. ZeroMemory(&deviceInterfaceData, sizeof(deviceInterfaceData));
  1101. deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);
  1102. SetupDiOpenDeviceInterface(hardwareDeviceInfo, DevPath,
  1103. 0, //
  1104. &deviceInterfaceData);
  1105. ZeroMemory(&deviceInfoData, sizeof(deviceInfoData));
  1106. deviceInfoData.cbSize = sizeof(deviceInfoData);
  1107. if (!SetupDiGetDeviceInterfaceDetail(
  1108. hardwareDeviceInfo,
  1109. &deviceInterfaceData,
  1110. NULL, // probing so no output buffer yet
  1111. 0, // probing so output buffer length of zero
  1112. NULL,
  1113. &deviceInfoData) && (error = GetLastError()) != ERROR_INSUFFICIENT_BUFFER) {
  1114. goto Error;
  1115. }
  1116. //
  1117. // Get the friendly name for this instance, if that fails
  1118. // try to get the device description.
  1119. //
  1120. if (!SetupDiGetDeviceRegistryProperty(hardwareDeviceInfo, &deviceInfoData,
  1121. SPDRP_FRIENDLYNAME,
  1122. &dwRegType,
  1123. DevName,
  1124. DevNameLen,
  1125. NULL)) {
  1126. if (!SetupDiGetDeviceRegistryProperty(hardwareDeviceInfo, &deviceInfoData,
  1127. SPDRP_DEVICEDESC,
  1128. &dwRegType,
  1129. DevName,
  1130. DevNameLen,
  1131. NULL)){
  1132. goto Error;
  1133. }
  1134. }
  1135. if (DeviceNameMatches((LPTSTR)DevName)) {
  1136. //PrintFilters(hardwareDeviceInfo, &deviceInfoData);
  1137. }
  1138. //retrieve unique device instance identifiers (IDs).
  1139. if (!SetupDiGetDeviceInstanceId(hardwareDeviceInfo, &deviceInfoData,
  1140. (PSTR)DevInstance,
  1141. InstanceLen,
  1142. NULL)) {
  1143. Display2(TEXT("Instance id is not available for device: %s"), (LPCTSTR)DevName);
  1144. goto Error;
  1145. }
  1146. ZeroMemory(&deviceInfoData, sizeof(deviceInfoData));
  1147. deviceInfoData.cbSize = sizeof(deviceInfoData);
  1148. if (!SetupDiOpenDeviceInfo(hardwareDeviceInfo, (PCSTR)DevInstance, NULL, 0, &deviceInfoData))
  1149. {
  1150. Display2(TEXT("open deivce info failed %u for device: %s"), GetLastError(), (LPCTSTR)DevName);
  1151. goto Error;
  1152. }
  1153. DWORD dwDevType = 0;
  1154. DWORD dwRequired = 0;
  1155. DWORD dwSize = 0;
  1156. if (SetupDiGetDeviceRegistryProperty(
  1157. hardwareDeviceInfo, &deviceInfoData, SPDRP_DEVTYPE, NULL, NULL, 0, &dwRequired)) {
  1158. // we should not be successful at this point, so this call succeeding
  1159. // is an error condition
  1160. Display2(TEXT("in GetDeviceRegistryProperty() : call SetupDiGetDeviceRegistryProperty did not fail? (%x)"),
  1161. GetLastError());
  1162. goto Error;
  1163. }
  1164. if (GetLastError() == ERROR_INSUFFICIENT_BUFFER && dwRequired > 0)
  1165. {
  1166. LPBYTE btData = static_cast<PBYTE>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
  1167. sizeof(BYTE)*dwRequired));
  1168. dwSize = dwRequired;
  1169. if (!SetupDiGetDeviceRegistryProperty(
  1170. hardwareDeviceInfo, &deviceInfoData, SPDRP_DEVTYPE, NULL, btData, dwSize, &dwRequired)) {
  1171. HeapFree(GetProcessHeap(), 0, btData);
  1172. btData = NULL;
  1173. DWORD dwError = GetLastError();
  1174. Display2(TEXT("device type is not available for device: %s, GLE=%u"),
  1175. (LPCTSTR)DevName, GetLastError());
  1176. if (dwError != ERROR_INVALID_DATA)
  1177. {
  1178. goto Error;
  1179. }
  1180. } else {
  1181. dwDevType = *reinterpret_cast<PDWORD>(btData);
  1182. if (dwDevType == FILE_DEVICE_MOUSE)
  1183. {
  1184. *pNeedOpen = TRUE;
  1185. } else if (dwDevType == FILE_DEVICE_KEYBOARD)
  1186. {
  1187. *pNeedOpen = TRUE;
  1188. }
  1189. }
  1190. HeapFree(GetProcessHeap(), 0, btData);
  1191. btData = NULL;
  1192. }
  1193. SetupDiDestroyDeviceInfoList(hardwareDeviceInfo);
  1194. return TRUE;
  1195. Error:
  1196. SetupDiDestroyDeviceInfoList(hardwareDeviceInfo);
  1197. return FALSE;
  1198. }
  1199. BOOL HandlePowerBroadcast(HWND hWnd, WPARAM wParam, ::LPARAM lParam)
  1200. {
  1201. BOOL fRet = TRUE;
  1202. UNREFERENCED_PARAMETER(hWnd);
  1203. UNREFERENCED_PARAMETER(lParam);
  1204. switch (wParam)
  1205. {
  1206. case PBT_APMQUERYSTANDBY:
  1207. Display2(TEXT("PBT_APMQUERYSTANDBY"));
  1208. break;
  1209. case PBT_APMQUERYSUSPEND:
  1210. Display2(TEXT("PBT_APMQUERYSUSPEND"));
  1211. break;
  1212. case PBT_APMSTANDBY:
  1213. Display2(TEXT("PBT_APMSTANDBY"));
  1214. break;
  1215. case PBT_APMSUSPEND:
  1216. Display2(TEXT("PBT_APMSUSPEND"));
  1217. break;
  1218. case PBT_APMQUERYSTANDBYFAILED:
  1219. Display2(TEXT("PBT_APMQUERYSTANDBYFAILED"));
  1220. break;
  1221. case PBT_APMRESUMESTANDBY:
  1222. Display2(TEXT("PBT_APMRESUMESTANDBY"));
  1223. break;
  1224. case PBT_APMQUERYSUSPENDFAILED:
  1225. Display2(TEXT("PBT_APMQUERYSUSPENDFAILED"));
  1226. break;
  1227. case PBT_APMRESUMESUSPEND:
  1228. Display2(TEXT("PBT_APMRESUMESUSPEND"));
  1229. break;
  1230. case PBT_APMBATTERYLOW:
  1231. Display2(TEXT("PBT_APMBATTERYLOW"));
  1232. break;
  1233. case PBT_APMOEMEVENT:
  1234. Display2(TEXT("PBT_APMOEMEVENT"));
  1235. break;
  1236. case PBT_APMRESUMEAUTOMATIC:
  1237. Display2(TEXT("PBT_APMRESUMEAUTOMATIC"));
  1238. break;
  1239. case PBT_APMRESUMECRITICAL:
  1240. Display2(TEXT("PBT_APMRESUMECRITICAL"));
  1241. break;
  1242. case PBT_APMPOWERSTATUSCHANGE:
  1243. Display2(TEXT("PBT_APMPOWERSTATUSCHANGE"));
  1244. break;
  1245. default:
  1246. Display2(TEXT("Default"));
  1247. break;
  1248. }
  1249. return fRet;
  1250. }
  1251. void OnMonitorChange(int currentCoun)
  1252. {
  1253. if(pMntFsm != NULL)
  1254. {
  1255. pMntFsm->BroadMonitorNumChange(currentCoun);
  1256. }
  1257. }
  1258. void OnDevListChange(BOOL fIncreased)
  1259. {
  1260. UNREFERENCED_PARAMETER(fIncreased);
  1261. BOOL kbd = FALSE, mou = FALSE;
  1262. USHORT mouCnt, kbdCnt;
  1263. gbMouAspire = gbKbdAspire = FALSE;
  1264. if(IsDevDeficient(mou, kbd, &mouCnt, &kbdCnt)) {
  1265. if(mou && mouCnt > 0) {
  1266. gbMouAspire = TRUE;
  1267. }
  1268. if(kbd && kbdCnt > 0) {
  1269. gbKbdAspire = TRUE;
  1270. }
  1271. }
  1272. if(fIncreased && pMntFsm && (gbKbdAspire || gbMouAspire)) {
  1273. pMntFsm->RequireInstallDrv(gbKbdAspire, gbMouAspire);
  1274. }
  1275. }
  1276. BOOL DevMnt_IsNeedInstall(
  1277. BOOL& bMouRequired,
  1278. BOOL& bKbdRequired,
  1279. USHORT* pUsMouCount,
  1280. USHORT* pUsKbdCount)
  1281. {
  1282. return IsDevDeficient(bMouRequired, bKbdRequired, pUsMouCount, pUsKbdCount);
  1283. }
  1284. CRvcDevMnt::CRvcDevMnt(void)
  1285. {
  1286. }
  1287. CRvcDevMnt::~CRvcDevMnt(void)
  1288. {
  1289. }