Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

518 lines
17 KiB

  1. /***************************************************************************************************
  2. **
  3. ** MODULE:
  4. **
  5. **
  6. ** DESCRIPTION:
  7. **
  8. **
  9. ** AUTHOR: Daniel Dean.
  10. **
  11. **
  12. **
  13. ** CREATED:
  14. **
  15. **
  16. **
  17. **
  18. ** (C) C O P Y R I G H T D A N I E L D E A N 1 9 9 6.
  19. ***************************************************************************************************/
  20. #include <WINDOWS.H>
  21. #include <string.h>
  22. #include <hidsdi.h>
  23. #include <hidusage.h>
  24. #include "CLASS.H"
  25. #include "IOCTL.H"
  26. #include "resource.h"
  27. /***************************************************************************************************
  28. **
  29. ** IOCTLChannelDesc.
  30. **
  31. ** DESCRIPTION:
  32. **
  33. ** PARAMETERS:
  34. **
  35. ** RETURNS:
  36. **
  37. ***************************************************************************************************/
  38. LPARAM IOCTLChannelDesc(HWND hWnd)
  39. {
  40. FARPROC lpfnProc;
  41. HINSTANCE hInstance = (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE);
  42. if((lpfnProc=(FARPROC)MakeProcInstance(ChannelDialogProc, hInstance)) != NULL)
  43. {
  44. DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_CHANNELDIALOG), hWnd, lpfnProc,(LPARAM)hWnd);
  45. FreeProcInstance(lpfnProc);
  46. }
  47. return SUCCESS;
  48. }
  49. /***************************************************************************************************
  50. **
  51. ** ChannelDialogProc()
  52. **
  53. ** DESCRIPTION: Dialog Box procedure fot the Channel Info dialog
  54. **
  55. ** PARAMETERS:
  56. **
  57. ** RETURNS:
  58. **
  59. ***************************************************************************************************/
  60. BOOL CALLBACK ChannelDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  61. {
  62. static HWND hwndMama;
  63. static PCHILD_INFO pChildInfo;
  64. static ULONG Index = 0;
  65. static BOOL fValues = TRUE; // Are we displaying 'Value' channels?
  66. // If not we are displaying 'Button' channels
  67. HANDLE hListBox;
  68. char buff[32];
  69. switch(uMsg)
  70. {
  71. case WM_INITDIALOG:
  72. hwndMama = (HWND)lParam;
  73. pChildInfo = (PCHILD_INFO)GetDeviceInfo(hwndMama);
  74. SendMessage(hDlg,WM_COMMAND,IDC_NEXT,0);
  75. return TRUE;
  76. case WM_COMMAND:
  77. {
  78. switch(wParam)
  79. {
  80. case IDOK:
  81. EndDialog(hDlg,0);
  82. return TRUE;
  83. case IDC_NEXT:
  84. hListBox = GetDlgItem(hDlg,IDC_ITEMLIST);
  85. SendMessage(hListBox,LB_RESETCONTENT,0,0);
  86. if( fValues )
  87. {
  88. wsprintf(buff,"Value Channel %d",Index);
  89. SetWindowText(hDlg,buff);
  90. if( Index < pChildInfo->NumValues )
  91. {
  92. wsprintf(buff,"UsagePage = %d",pChildInfo->pValueCaps[Index].UsagePage);
  93. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  94. wsprintf(buff,"ReportID = %d",pChildInfo->pValueCaps[Index].ReportID);
  95. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  96. if( pChildInfo->pValueCaps[Index].IsRange)
  97. {
  98. wsprintf(buff,"UsageMin = %d",pChildInfo->pValueCaps[Index].Range.UsageMin);
  99. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  100. wsprintf(buff,"UsageMax = %d",pChildInfo->pValueCaps[Index].Range.UsageMax);
  101. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  102. wsprintf(buff,"StringMin = %d",pChildInfo->pValueCaps[Index].Range.StringMin);
  103. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  104. wsprintf(buff,"StringMax = %d",pChildInfo->pValueCaps[Index].Range.StringMax);
  105. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  106. wsprintf(buff,"DesignatorMin = %d",pChildInfo->pValueCaps[Index].Range.DesignatorMin);
  107. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  108. wsprintf(buff,"DesignatorMax = %d",pChildInfo->pValueCaps[Index].Range.DesignatorMax);
  109. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  110. }
  111. else
  112. {
  113. wsprintf(buff,"Usage = %d",pChildInfo->pValueCaps[Index].NotRange.Usage);
  114. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  115. wsprintf(buff,"StringIndex = %d",pChildInfo->pValueCaps[Index].NotRange.StringIndex);
  116. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  117. wsprintf(buff,"DesignatorIndex = %d",pChildInfo->pValueCaps[Index].NotRange.DesignatorIndex);
  118. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  119. }
  120. if( pChildInfo->pValueCaps[Index].HasNull )
  121. {
  122. wsprintf(buff,"NULL = %d",pChildInfo->pValueCaps[Index].Null);
  123. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  124. }
  125. wsprintf(buff,"LogicalMin = %d",pChildInfo->pValueCaps[Index].LogicalMin);
  126. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  127. wsprintf(buff,"LogicalMax = %d",pChildInfo->pValueCaps[Index].LogicalMax);
  128. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  129. wsprintf(buff,"PhysicalMin = %d",pChildInfo->pValueCaps[Index].PhysicalMin);
  130. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  131. wsprintf(buff,"PhysicalMax = %d",pChildInfo->pValueCaps[Index].PhysicalMax);
  132. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  133. Index++;
  134. }
  135. else
  136. {
  137. Index = 0;
  138. fValues = FALSE;
  139. }
  140. }
  141. else
  142. if( Index < pChildInfo->NumButtons )
  143. {
  144. hListBox = GetDlgItem(hDlg,IDC_ITEMLIST);
  145. wsprintf(buff,"Button Channel %d",Index);
  146. SetWindowText(hDlg,buff);
  147. wsprintf(buff,"UsagePage = %d",pChildInfo->pValueCaps[Index].UsagePage);
  148. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  149. wsprintf(buff,"ReportID = %d",pChildInfo->pValueCaps[Index].ReportID);
  150. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  151. if( pChildInfo->pValueCaps[Index].IsRange)
  152. {
  153. wsprintf(buff,"UsageMin = %d",pChildInfo->pValueCaps[Index].Range.UsageMin);
  154. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  155. wsprintf(buff,"UsageMax = %d",pChildInfo->pValueCaps[Index].Range.UsageMax);
  156. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  157. wsprintf(buff,"StringMin = %d",pChildInfo->pValueCaps[Index].Range.StringMin);
  158. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  159. wsprintf(buff,"StringMax = %d",pChildInfo->pValueCaps[Index].Range.StringMax);
  160. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  161. wsprintf(buff,"DesignatorMin = %d",pChildInfo->pValueCaps[Index].Range.DesignatorMin);
  162. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  163. wsprintf(buff,"DesignatorMax = %d",pChildInfo->pValueCaps[Index].Range.DesignatorMax);
  164. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  165. }
  166. else
  167. {
  168. wsprintf(buff,"Usage = %d",pChildInfo->pValueCaps[Index].NotRange.Usage);
  169. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  170. wsprintf(buff,"StringIndex = %d",pChildInfo->pValueCaps[Index].NotRange.StringIndex);
  171. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  172. wsprintf(buff,"DesignatorIndex = %d",pChildInfo->pValueCaps[Index].NotRange.DesignatorIndex);
  173. SendMessage(hListBox,LB_ADDSTRING,0,(LPARAM)(LPCTSTR)buff);
  174. }
  175. Index++;
  176. }
  177. else
  178. {
  179. fValues = TRUE;
  180. Index = 0;
  181. }
  182. return TRUE;
  183. }
  184. }//end case WM_COMMAND
  185. }//end switch(uMsg)
  186. return FALSE;
  187. }
  188. /***************************************************************************************************
  189. **
  190. ** IOCTLDeviceDesc.
  191. **
  192. ** DESCRIPTION:
  193. **
  194. ** PARAMETERS:
  195. **
  196. ** RETURNS:
  197. **
  198. ***************************************************************************************************/
  199. LPARAM IOCTLDeviceDesc(HWND hWnd)
  200. {
  201. return SUCCESS;
  202. }
  203. /***************************************************************************************************
  204. **
  205. ** IOCTLRead.
  206. **
  207. ** DESCRIPTION:
  208. **
  209. ** PARAMETERS:
  210. **
  211. ** RETURNS:
  212. **
  213. ***************************************************************************************************/
  214. LPARAM IOCTLRead(HWND hWnd)
  215. {
  216. ULONG dwThreadID;
  217. HANDLE hThread;
  218. PREADTHREAD pThreadData;
  219. OutputDebugString(">>>>HIDMON.EXE: IOCTLRead() Enter\n");
  220. // If a read or a write is in progress stop it
  221. if(GetThreadData(hWnd))
  222. IOCTLStop(hWnd);
  223. // Get the number of bytes of data for this device
  224. // Allocate and setup a thread variables
  225. pThreadData = (PREADTHREAD) GlobalAlloc(GPTR, sizeof(READTHREAD));
  226. if(!pThreadData)
  227. {
  228. MessageBox(hWnd,"IOCTLRead(): GlobalAlloc fialed","Ooops!",MB_OK);
  229. return FALSE;
  230. }
  231. pThreadData->hEditWin = GetEditWin(hWnd);
  232. pThreadData->ThisThread = TRUE;
  233. pThreadData->hDevice = GetDeviceHandle(hWnd);
  234. pThreadData->hWnd = hWnd;
  235. // Create Data notification thread
  236. hThread = CreateThread((LPSECURITY_ATTRIBUTES) NULL,
  237. (DWORD) 0,
  238. (LPTHREAD_START_ROUTINE) ReadWatch,
  239. (LPVOID) pThreadData,
  240. CREATE_SUSPENDED,
  241. &dwThreadID);
  242. if(!hThread)
  243. {
  244. GlobalFree(pThreadData);
  245. MessageBox(hWnd,"IOCTLRead(): CreateThread fialed","Ooops!",MB_OK);
  246. return FAILURE;
  247. }
  248. SetThreadData(hWnd, pThreadData);
  249. // Set Thread priority and start thread
  250. SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
  251. ResumeThread(hThread);
  252. return SUCCESS;
  253. }
  254. /***************************************************************************************************
  255. **
  256. ** IOCTLWrite.
  257. **
  258. ** DESCRIPTION:
  259. **
  260. ** PARAMETERS:
  261. **
  262. ** RETURNS:
  263. **
  264. ***************************************************************************************************/
  265. LPARAM IOCTLWrite(HWND hWnd)
  266. {
  267. ULONG dwReturn = 0;
  268. OVERLAPPED Overlapped;
  269. // If a read or a write is in progress stop it
  270. if(GetThreadData(hWnd))
  271. IOCTLStop(hWnd);
  272. // Need a way to get data froom user
  273. // Need a way to get channel number from user
  274. Overlapped.Offset = 3;
  275. Overlapped.hEvent = NULL;
  276. dwReturn = 0;
  277. WriteFile(GetDeviceHandle(hWnd), (PVOID) "Hello", sizeof("Hello"), &dwReturn, &Overlapped);
  278. return SUCCESS;
  279. }
  280. /***************************************************************************************************
  281. **
  282. ** IOCTLStop.
  283. **
  284. ** DESCRIPTION:
  285. **
  286. ** PARAMETERS:
  287. **
  288. ** RETURNS:
  289. **
  290. ***************************************************************************************************/
  291. LPARAM IOCTLStop(HWND hWnd)
  292. {
  293. PREADTHREAD pThreadData;
  294. OutputDebugString(">>>>HIDMON.EXE: IOCTLStop() Enter\n");
  295. pThreadData = GetThreadData(hWnd);
  296. if(pThreadData)
  297. {
  298. SetThreadData(hWnd, 0);
  299. pThreadData->ThisThread = FALSE;
  300. }
  301. // Allow the thread to die
  302. //Sleep(250);
  303. OutputDebugString(">>>>HIDMON.EXE: IOCTLStop() Exit\n");
  304. return SUCCESS;
  305. }
  306. /*******************************************************************************
  307. **
  308. ** FUNCTION: ReadWatch()
  309. **
  310. ** PURPOSE: Read next available packet and display in child window
  311. **
  312. **
  313. **
  314. *******************************************************************************/
  315. #define MAX_CHARS_PER_LINE 128
  316. VOID CALLBACK ReadWatch(HWND hWnd, UINT uMsg, UINT TimerID, DWORD dwTime)
  317. {
  318. PUCHAR WriteBuffer;
  319. PUCHAR ReadBuffer;
  320. ULONG NumChannels;
  321. ULONG NumBytes;
  322. ULONG LogicalReturn;
  323. READTHREAD ThreadData;
  324. OVERLAPPED OV;
  325. PCHILD_INFO pChildInfo;
  326. OutputDebugString(">>>>HIDMON.EXE: ReadWatch() Enter\n");
  327. // Retrieve info for this child
  328. pChildInfo = (PCHILD_INFO)GetDeviceInfo(hWnd);
  329. NumChannels = pChildInfo->hidCaps->NumberInputValueCaps +
  330. pChildInfo->hidCaps->NumberInputButtonCaps;
  331. NumBytes = pChildInfo->hidCaps->InputReportByteLength;
  332. // Allocate memory for our ReadBuffer
  333. ReadBuffer = (PUCHAR) GlobalAlloc(GPTR,NumBytes);
  334. if(!ReadBuffer)
  335. return;// FALSE;
  336. // Allocate memory for our 'screen' buffer
  337. WriteBuffer = (PUCHAR) GlobalAlloc(GPTR,NumChannels*MAX_CHARS_PER_LINE);
  338. if(!WriteBuffer)
  339. {
  340. GlobalFree(ReadBuffer);
  341. return;// FALSE;
  342. }
  343. // Setup read buffer
  344. memset(ReadBuffer, 0, NumBytes);
  345. // Setup overlapped structure
  346. memset(&OV, 0, sizeof(OVERLAPPED));
  347. // Start read
  348. LogicalReturn = ReadFileEx(GetDeviceHandle(hWnd),
  349. (LPVOID) ReadBuffer,
  350. NumBytes,
  351. &OV,
  352. NULL);
  353. // Print error message if failed
  354. if(!LogicalReturn)
  355. SendMessage(ThreadData.hEditWin,
  356. WM_SETTEXT,
  357. (WPARAM) sizeof("ReadFile FAILED!"),
  358. (LPARAM) "ReadFile FAILED!");
  359. else
  360. if( LogicalReturn )
  361. {
  362. PCHAR pChar = WriteBuffer;
  363. NTSTATUS rc;
  364. char tmpBuff[256],tmpBuff2[256];
  365. ULONG i,Value;
  366. //
  367. // Parse the data from our last Read
  368. //
  369. // Clear the buffer
  370. memset(WriteBuffer,'\0',NumChannels*MAX_CHARS_PER_LINE);
  371. // Make Text strings
  372. // First do the Value channels
  373. for(i=0;i<pChildInfo->hidCaps->NumberInputValueCaps;i++)
  374. {
  375. rc = HidP_GetUsageValue(HidP_Input,
  376. pChildInfo->pValueCaps[i].UsagePage,
  377. 0,
  378. pChildInfo->pValueCaps[i].NotRange.Usage,
  379. &Value,
  380. pChildInfo->hidPPData,
  381. ReadBuffer,
  382. NumBytes );
  383. wsprintf(tmpBuff,"Value: Usage[%02d]:[%02d] = %d\r\n",
  384. pChildInfo->pValueCaps[i].UsagePage,
  385. pChildInfo->pValueCaps[i].NotRange.Usage,
  386. Value );
  387. strcat(WriteBuffer,tmpBuff);
  388. }
  389. // Then do the button channels
  390. for(i=0;i<pChildInfo->hidCaps->NumberInputButtonCaps;i++)
  391. {
  392. PUCHAR pUsageList;
  393. DWORD ulUsageListLen;
  394. //UCHAR TempBuff[256];
  395. // Get the maximum usage list length
  396. ulUsageListLen = HidP_MaxUsageListLength( HidP_Input,
  397. pChildInfo->pButtonCaps[i].UsagePage,
  398. pChildInfo->hidPPData );
  399. pUsageList = (PUCHAR)GlobalAlloc(GMEM_FIXED,ulUsageListLen);
  400. wsprintf( tmpBuff,"Buttons:[%02d]:[%02d] = ",pChildInfo->pButtonCaps[i].UsagePage,
  401. pChildInfo->pButtonCaps[i].NotRange.Usage);
  402. ulUsageListLen++;
  403. rc = HidP_GetUsages(HidP_Input,
  404. pChildInfo->pButtonCaps[i].UsagePage,
  405. pChildInfo->pButtonCaps[i].LinkCollection,
  406. pUsageList,
  407. &ulUsageListLen,
  408. pChildInfo->hidPPData,
  409. ReadBuffer,
  410. NumBytes );
  411. // if Buttons are pressed
  412. if( ulUsageListLen )
  413. {
  414. ULONG i;
  415. for(i=0;i<ulUsageListLen;i++)
  416. {
  417. wsprintf(tmpBuff2,"0x%02X ",pUsageList[i]);
  418. strcat(tmpBuff,tmpBuff2);
  419. }
  420. }
  421. strcat(tmpBuff,"\r\n");
  422. strcat(WriteBuffer,tmpBuff);
  423. GlobalFree(pUsageList);
  424. //i=pChildInfo->NumButtons;
  425. }
  426. SendMessage(GetEditWin(hWnd),//ThreadData.hEditWin,
  427. WM_SETTEXT,
  428. (WPARAM) strlen(WriteBuffer),
  429. (LPARAM) WriteBuffer);
  430. }// end if(LogicalReturn)
  431. //
  432. GlobalFree(ReadBuffer);
  433. GlobalFree(WriteBuffer);
  434. //TESTING!!
  435. OutputDebugString(">>>>HIDMON.EXE: ReadWatch() Exit\n");
  436. return;// TRUE;
  437. }