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.

4161 lines
139 KiB

  1. /*++
  2. Copyright (c) Microsoft 1998, All Rights Reserved
  3. Module Name:
  4. ecdisp.c
  5. Abstract:
  6. This module contains the code to handle the extended calls dialog box
  7. and the actions that can be performed in the dialog box.
  8. Environment:
  9. User mode
  10. Revision History:
  11. May-98 : Created
  12. --*/
  13. /*****************************************************************************
  14. /* Extended call display include files
  15. /*****************************************************************************/
  16. #include <windows.h>
  17. #include <limits.h>
  18. #include <stdlib.h>
  19. #include <math.h>
  20. #include <stdio.h>
  21. #include <setupapi.h>
  22. #include <vfw.h>
  23. #include <assert.h>
  24. #include "hidusage.h"
  25. #include "hidsdi.h"
  26. #include "hid.h"
  27. #include "hclient.h"
  28. #include "resource.h"
  29. #include "buffers.h"
  30. #include "ecdisp.h"
  31. #include "strings.h"
  32. #include "logpnp.h"
  33. /*****************************************************************************
  34. /* Local macro definitions for the supported function calls
  35. /*****************************************************************************/
  36. #define HID_DEVCALLS 20
  37. #define HID_PPDCALLS 29
  38. #define HID_NUMCALLS HID_DEVCALLS + HID_PPDCALLS
  39. #define HIDD_GET_HID_GUID 1
  40. #define HIDD_GET_FREE_PREPARSED_DATA 2
  41. #define HIDD_GET_CONFIGURATION 3
  42. #define HIDD_SET_CONFIGURATION 4
  43. #define HIDD_FLUSH_QUEUE 5
  44. #define HIDD_GET_ATTRIBUTES 6
  45. #define HIDD_SET_FEATURE 7
  46. #define HIDD_GET_FEATURE 8
  47. #define HIDD_GET_INPUT_REPORT 9
  48. #define HIDD_SET_OUTPUT_REPORT 10
  49. #define HIDD_GET_NUM_INPUT_BUFFERS 11
  50. #define HIDD_SET_NUM_INPUT_BUFFERS 12
  51. #define HIDD_GET_PHYSICAL_DESCRIPTOR 13
  52. #define HIDD_GET_MANUFACTURER_STRING 14
  53. #define HIDD_GET_PRODUCT_STRING 15
  54. #define HIDD_GET_INDEXED_STRING 16
  55. #define HIDD_GET_SERIAL_NUMBER_STRING 17
  56. #define HIDD_GET_MS_GENRE_DESCRIPTOR 18
  57. #define HID_READ_REPORT 19
  58. #define HID_WRITE_REPORT 20
  59. #define HIDP_GET_BUTTON_CAPS 21
  60. #define HIDP_GET_BUTTONS 22
  61. #define HIDP_GET_BUTTONS_EX 23
  62. #define HIDP_GET_CAPS 24
  63. #define HIDP_GET_DATA 25
  64. #define HIDP_GET_EXTENDED_ATTRIBUTES 26
  65. #define HIDP_GET_LINK_COLL_NODES 27
  66. #define HIDP_GET_SCALED_USAGE_VALUE 28
  67. #define HIDP_GET_SPECIFIC_BUTTON_CAPS 29
  68. #define HIDP_GET_SPECIFIC_VALUE_CAPS 30
  69. #define HIDP_GET_USAGES 31
  70. #define HIDP_GET_USAGES_EX 32
  71. #define HIDP_GET_USAGE_VALUE 33
  72. #define HIDP_GET_USAGE_VALUE_ARRAY 34
  73. #define HIDP_GET_VALUE_CAPS 35
  74. #define HIDP_INITIALIZE_REPORT_FOR_ID 36
  75. #define HIDP_MAX_DATA_LIST_LENGTH 37
  76. #define HIDP_MAX_USAGE_LIST_LENGTH 38
  77. #define HIDP_SET_BUTTONS 39
  78. #define HIDP_SET_DATA 40
  79. #define HIDP_SET_SCALED_USAGE_VALUE 41
  80. #define HIDP_SET_USAGES 42
  81. #define HIDP_SET_USAGE_VALUE 43
  82. #define HIDP_SET_USAGE_VALUE_ARRAY 44
  83. #define HIDP_TRANSLATE_USAGES 45
  84. #define HIDP_UNSET_BUTTONS 46
  85. #define HIDP_UNSET_USAGES 47
  86. #define HIDP_USAGE_LIST_DIFFERENCE 48
  87. #define HID_CLEAR_REPORT 49
  88. /*
  89. // These two definitions are not used by the display routines since
  90. // the two functions were molded together into one for purpose of execution
  91. */
  92. #define HIDD_GET_PREPARSED_DATA 50
  93. #define HIDD_FREE_PREPARSED_DATA 51
  94. #define IS_HIDD_FUNCTION(func) (((func) >= HIDD_GET_HID_GUID) && \
  95. ((func) <= HIDD_GET_MS_GENRE_DESCRIPTOR))
  96. #define IS_HIDP_FUNCTION(func) (((func) >= HIDP_GET_BUTTON_CAPS) && \
  97. ((func) <= HIDP_USAGE_LIST_DIFFERENCE))
  98. #define IS_HID_FUNCTION(func) (((func) >= HID_READ_REPORT) && \
  99. ((func) <= HID_WRITE_REPORT))
  100. #define IS_NOT_IMPLEMENTED(func) (((func) == HIDD_GET_CONFIGURATION) || \
  101. ((func) == HIDD_SET_CONFIGURATION) || \
  102. ((func) == HIDP_TRANSLATE_USAGES) || \
  103. (((func) == HIDP_INITIALIZE_REPORT_FOR_ID) && \
  104. (NULL == pfnHidP_InitializeReportForID)) || \
  105. (((func) == HIDP_GET_EXTENDED_ATTRIBUTES) && \
  106. (NULL == pfnHidP_GetExtendedAttributes)))
  107. /*****************************************************************************
  108. /* Local macro definitions for buffer display sizes
  109. /*****************************************************************************/
  110. #define NUM_INPUT_BUFFERS 16
  111. #define NUM_OUTPUT_BUFFERS 16
  112. #define NUM_FEATURE_BUFFERS 16
  113. /*****************************************************************************
  114. /* Local macro definition for HidP_SetData dialog box
  115. /*****************************************************************************/
  116. #define SETDATA_LISTBOX_FORMAT "Index: %u, DataValue: %u"
  117. /*****************************************************************************
  118. /* Local macro definition for display output to output windows
  119. /*****************************************************************************/
  120. #define TEMP_BUFFER_SIZE 1024
  121. #define STATUS_STRING(str, status) wsprintf(str, "Status: %s", ECDisp_GetHidAppStatusString(status))
  122. #define OUTSTRING(win, str) SendMessage(win, LB_ADDSTRING, 0, (LPARAM) str)
  123. #define OUTWSTRING(win, str) \
  124. { \
  125. size_t nBytes; \
  126. \
  127. nBytes = wcstombs(szTempBuffer, str, TEMP_BUFFER_SIZE-1); \
  128. if ((size_t) -1 == nBytes) { \
  129. OUTSTRING(win, "Cannot convert wide-character string"); \
  130. } \
  131. else { \
  132. szTempBuffer[nBytes] = '\0'; \
  133. OUTSTRING(win, szTempBuffer); \
  134. } \
  135. }
  136. #define DISPLAY_HIDD_STATUS(win, func, status) \
  137. { \
  138. wsprintf(szTempBuffer, \
  139. "%s returned: %s", \
  140. func, \
  141. (status).IsHidError ? "FALSE" : "TRUE"); \
  142. \
  143. OUTSTRING(win, szTempBuffer); \
  144. \
  145. if ((status).IsHidError) { \
  146. wsprintf(szTempBuffer, \
  147. "ErrorCode: %d", \
  148. GetLastError()); \
  149. }\
  150. OUTSTRING(win, szTempBuffer); \
  151. }
  152. #define DISPLAY_HIDP_STATUS(win, func, status) \
  153. { \
  154. wsprintf(szTempBuffer, \
  155. "%s returned: %s", \
  156. func, \
  157. ECDisp_GetHidAppStatusString(status.HidErrorCode)); \
  158. \
  159. OUTSTRING(win, szTempBuffer); \
  160. }
  161. #define ECDISP_ERROR(win, msg) \
  162. { \
  163. MessageBox(win, \
  164. msg, \
  165. HCLIENT_ERROR, \
  166. MB_ICONEXCLAMATION); \
  167. }
  168. #define GET_FUNCTION_NAME(index) ResolveFunctionName(index)
  169. /*****************************************************************************
  170. /* Local macro definition for retrieving data based on report type
  171. /*****************************************************************************/
  172. #define SELECT_ON_REPORT_TYPE(rt, ival, oval, fval, res) \
  173. { \
  174. switch ((rt)) { \
  175. case HidP_Input: \
  176. (res) = (ival); \
  177. break; \
  178. \
  179. case HidP_Output: \
  180. (res) = (oval); \
  181. break; \
  182. \
  183. case HidP_Feature: \
  184. (res) = (fval); \
  185. break; \
  186. \
  187. } \
  188. }
  189. /*****************************************************************************
  190. /* Local macro definition for calculating size of a usage value array buffer
  191. /*****************************************************************************/
  192. #define ROUND_TO_NEAREST_BYTE(val) (((val) % 8) ? ((val) / 8) + 1 : ((val) / 8))
  193. /*****************************************************************************
  194. /* Data types local to this module
  195. /*****************************************************************************/
  196. typedef struct _FUNCTION_NAMES
  197. {
  198. UINT uiIndex;
  199. char *szFunctionName;
  200. } FUNCTION_NAMES;
  201. typedef struct _PARAMETER_STATE
  202. {
  203. BOOL fInputReport;
  204. BOOL fOutputReport;
  205. BOOL fFeatureReport;
  206. BOOL fReportID;
  207. BOOL fUsagePage;
  208. BOOL fUsage;
  209. BOOL fLinkCollection;
  210. BOOL fInputReportSelect;
  211. BOOL fOutputReportSelect;
  212. BOOL fFeatureReportSelect;
  213. } PARAMETER_STATE;
  214. typedef enum { DLGBOX_INIT_FAILED = -1, DLGBOX_ERROR, DLGBOX_CANCEL, DLGBOX_OK } DLGBOX_STATUS;
  215. typedef struct _ECDISPLAY_PARAMS
  216. {
  217. HIDP_REPORT_TYPE ReportType;
  218. USAGE UsagePage;
  219. USAGE Usage;
  220. USHORT LinkCollection;
  221. UCHAR ReportID;
  222. PCHAR szListString;
  223. PCHAR szListString2;
  224. PUSAGE UsageList;
  225. PUSAGE UsageList2;
  226. ULONG ListLength;
  227. ULONG ListLength2;
  228. ULONG Index;
  229. union {
  230. PHIDP_DATA pDataList;
  231. PULONG pValueList;
  232. LONG ScaledValue;
  233. ULONG Value;
  234. };
  235. } ECDISPLAY_PARAMS, *PECDISPLAY_PARAMS;
  236. typedef struct _READ_PARAMS
  237. {
  238. PHID_DEVICE device;
  239. BOOLEAN stopThread;
  240. } READ_PARAMS, *PREAD_PARAMS;
  241. /*****************************************************************************
  242. /* Local data variables
  243. /*****************************************************************************/
  244. static CHAR szTempBuffer[TEMP_BUFFER_SIZE];
  245. static PBUFFER_DISPLAY pInputDisplay;
  246. static PBUFFER_DISPLAY pOutputDisplay;
  247. static PBUFFER_DISPLAY pFeatureDisplay;
  248. static FUNCTION_NAMES DeviceCalls[HID_DEVCALLS] = {
  249. { HIDD_GET_HID_GUID, "HidD_GetHidGuid" },
  250. { HIDD_GET_FREE_PREPARSED_DATA, "HidD_GetFreePreparsedData" },
  251. { HIDD_GET_CONFIGURATION, "HidD_GetConfiguration" },
  252. { HIDD_SET_CONFIGURATION, "HidD_SetConfiguration" },
  253. { HIDD_FLUSH_QUEUE, "HidD_FlushQueue" },
  254. { HIDD_GET_ATTRIBUTES, "HidD_GetAttributes" },
  255. { HIDD_SET_FEATURE, "HidD_SetFeature" },
  256. { HIDD_GET_FEATURE, "HidD_GetFeature" },
  257. { HIDD_GET_INPUT_REPORT, "HIDD_GetInputReport" },
  258. { HIDD_SET_OUTPUT_REPORT, "HidD_SetOutputReport" },
  259. { HIDD_GET_NUM_INPUT_BUFFERS, "HidD_GetNumInputBuffers" },
  260. { HIDD_SET_NUM_INPUT_BUFFERS, "HidD_SetNumInputBuffers" },
  261. { HIDD_GET_PHYSICAL_DESCRIPTOR, "HidD_GetPhysicalDescriptor" },
  262. { HIDD_GET_MANUFACTURER_STRING, "HidD_GetManufacturerString" },
  263. { HIDD_GET_PRODUCT_STRING, "HidD_GetProductString" },
  264. { HIDD_GET_INDEXED_STRING, "HidD_GetIndexedString" },
  265. { HIDD_GET_SERIAL_NUMBER_STRING, "HidD_GetSerialNumberString" },
  266. { HIDD_GET_MS_GENRE_DESCRIPTOR, "HidD_GetMsGenreDescriptor" },
  267. { HID_READ_REPORT, "Read Input Report" },
  268. { HID_WRITE_REPORT, "Write Report Buffer" }
  269. };
  270. static FUNCTION_NAMES PpdCalls[HID_PPDCALLS] = {
  271. { HIDP_GET_BUTTON_CAPS, "HidP_GetButtonCaps" },
  272. { HIDP_GET_BUTTONS, "HidP_GetButtons" },
  273. { HIDP_GET_BUTTONS_EX, "HidP_GetButtonsEx" },
  274. { HIDP_GET_CAPS, "HidP_GetCaps" },
  275. { HIDP_GET_DATA, "HidP_GetData" },
  276. { HIDP_GET_EXTENDED_ATTRIBUTES, "HidP_GetExtendedAttributes" },
  277. { HIDP_GET_LINK_COLL_NODES, "HidP_GetLinkCollectionNodes" },
  278. { HIDP_GET_SCALED_USAGE_VALUE, "HidP_GetScaledUsageValue" },
  279. { HIDP_GET_SPECIFIC_BUTTON_CAPS, "HidP_GetSpecificButtonCaps" },
  280. { HIDP_GET_SPECIFIC_VALUE_CAPS, "HidP_GetSpecificValueCaps" },
  281. { HIDP_GET_USAGES, "HidP_GetUsages" },
  282. { HIDP_GET_USAGES_EX, "HidP_GetUsagesEx" },
  283. { HIDP_GET_USAGE_VALUE, "HidP_GetUsageValue" },
  284. { HIDP_GET_USAGE_VALUE_ARRAY, "HidP_GetUsageValueArray" },
  285. { HIDP_GET_VALUE_CAPS, "HidP_GetValueCaps" },
  286. { HIDP_INITIALIZE_REPORT_FOR_ID, "HidP_InitializeReportForID" },
  287. { HIDP_MAX_DATA_LIST_LENGTH, "HidP_MaxDataListLength" },
  288. { HIDP_MAX_USAGE_LIST_LENGTH, "HidP_MaxUsageListLength" },
  289. { HIDP_SET_BUTTONS, "HidP_SetButtons" },
  290. { HIDP_SET_DATA, "HidP_SetData" },
  291. { HIDP_SET_SCALED_USAGE_VALUE, "HidP_SetScaledUsageValue" },
  292. { HIDP_SET_USAGES, "HidP_SetUsages" },
  293. { HIDP_SET_USAGE_VALUE, "HidP_SetUsageValue" },
  294. { HIDP_SET_USAGE_VALUE_ARRAY, "HidP_SetUsageValueArray" },
  295. { HIDP_TRANSLATE_USAGES, "HidP_TranslateUsagesToI8042ScanCodes" },
  296. { HIDP_UNSET_BUTTONS, "HidP_UnsetButtons" },
  297. { HIDP_UNSET_USAGES, "HidP_UnsetUsages" },
  298. { HIDP_USAGE_LIST_DIFFERENCE, "HidP_UsageListDifference" },
  299. { HID_CLEAR_REPORT, "Clear Report Buffer" }
  300. };
  301. static PARAMETER_STATE pState[HID_NUMCALLS] = {
  302. { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_GET_HID_GUID
  303. { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_GET_FREE_PREPARSED_DATA
  304. { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_GET_CONFIGURATION
  305. { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_SET_CONFIGURATION
  306. { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_FLUSH_QUEUE
  307. { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_GETATTRIBUTES
  308. { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE }, // HIDD_SET_FEATURE
  309. { FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE }, // HIDD_GET_FEATURE
  310. { FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE }, // HIDD_GET_INPUT_REPORT
  311. { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE }, // HIDD_SET_OUTPUT_REPORT
  312. { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_GET_NUM_INPUT_BUFFERS
  313. { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_SET_NUM_INPUT_BUFFERS
  314. { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_GET_PHYSICAL_DESCRIPTOR
  315. { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_GET_MANUFACTURER_STRING
  316. { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_GET_PRODUCT_STRING
  317. { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_GET_INDEXED_STRING
  318. { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_GET_SERIAL_NUMBER_STRING
  319. { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_GET_MS_GENRE_DESCRIPTOR
  320. { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE }, // HID_READ_REPORT
  321. { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE }, // HID_WRITE_BUFFER
  322. { TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDP_GET_BUTTON_CAPS
  323. { TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE }, // HIDP_GET_BUTTONS
  324. { TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE }, // HIDP_GET_BUTTONS_EX
  325. { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDP_GET_CAPS
  326. { TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE }, // HIDP_GET_DATA
  327. { TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE }, // HIDP_GET_EXTENDED_ATTRIBUTES
  328. { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDP_GET_LINK_COLL_NODES
  329. { TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // HIDP_GET_SCALED_USAGE_VALUE
  330. { TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE }, // HIDP_GET_SPECIFIC_BUTTON_CAPS
  331. { TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE }, // HIDP_GET_SPECIFIC_VALUE_CAPS
  332. { TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE }, // HIDP_GET_USAGES
  333. { TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE }, // HIDP_GET_USAGES_EX
  334. { TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // HIDP_GET_USAGE_VALUE
  335. { TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // HIDP_GET_USAGE_VALUE_ARRAY
  336. { TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDP_GET_VALUE_CAPS
  337. { TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE }, // HIDP_INITIALIZE_REPORT_FOR_ID
  338. { TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDP_MAX_DATA_LIST_LENGTH
  339. { TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDP_MAX_USAGE_LIST_LENGTH
  340. { TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE }, // HIDP_SET_BUTTONS
  341. { TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE }, // HIDP_SET_DATA
  342. { TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // HIDP_SET_SCALED_USAGE_VALUE
  343. { TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE }, // HIDP_SET_USAGES
  344. { TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // HIDP_SET_USAGE_VALUE
  345. { TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE }, // HIDP_SET_USAGE_VALUE_ARRAY
  346. { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDP_TRANSLATE_USAGES
  347. { TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE }, // HIDP_UNSET_BUTTONS
  348. { TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE }, // HIDP_UNSET_USAGES
  349. { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDP_USAGE_LIST_DIFFERENCE
  350. { TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE } // HID_CLEAR_BUFFER
  351. };
  352. /*****************************************************************************
  353. /* Local function declarations
  354. /*****************************************************************************/
  355. VOID
  356. vLoadExtCalls(
  357. HWND hExtCalls,
  358. BOOL IsLogicalDevice
  359. );
  360. VOID
  361. vSetReportType(
  362. HWND hDlg,
  363. LONG lId
  364. );
  365. VOID
  366. vInitEditText(
  367. HWND hText,
  368. INT cbTextSize,
  369. CHAR *pchText
  370. );
  371. VOID vEnableParameters(
  372. HWND hDlg,
  373. LRESULT iCallSelection
  374. );
  375. BOOL
  376. fGetAndVerifyParameters(
  377. HWND hDlg,
  378. PECDISPLAY_PARAMS pParams
  379. );
  380. BOOL
  381. ECDisp_Execute(
  382. IN INT FuncCall,
  383. IN OUT PEXTCALL_PARAMS CallParams,
  384. OUT PEXTCALL_STATUS CallStatus
  385. );
  386. VOID
  387. ECDisp_DisplayOutput(
  388. IN HWND hOutputWindow,
  389. IN INT FuncCall,
  390. IN PEXTCALL_PARAMS Results
  391. );
  392. VOID
  393. vExecuteAndDisplayOutput(
  394. HWND hOutputWindow,
  395. PHID_DEVICE pDevice,
  396. INT iFuncCall,
  397. PECDISPLAY_PARAMS pParams
  398. );
  399. CHAR *pchGetHidAppStatusString(
  400. NTSTATUS StatusCode
  401. );
  402. VOID
  403. vInitECControls(
  404. HWND hDlg,
  405. USHORT InputReportByteLength,
  406. PBUFFER_DISPLAY *ppInputDisplay,
  407. USHORT OutputReportByteLength,
  408. PBUFFER_DISPLAY *ppOutputDisplay,
  409. USHORT FeatureReportByteLength,
  410. PBUFFER_DISPLAY *ppFeatureDisplay,
  411. BOOL IsLogicalDevice
  412. );
  413. VOID
  414. BuildReportIDList(
  415. IN PHIDP_BUTTON_CAPS phidButtonCaps,
  416. IN USHORT nButtonCaps,
  417. IN PHIDP_VALUE_CAPS phidValueCaps,
  418. IN USHORT nValueCaps,
  419. OUT UCHAR **ppReportIDList,
  420. OUT INT *nReportIDs
  421. );
  422. LRESULT CALLBACK
  423. bSetUsagesDlgProc(
  424. HWND hDlg,
  425. UINT message,
  426. WPARAM wParam,
  427. LPARAM lParam
  428. );
  429. LRESULT CALLBACK
  430. bSetValueDlgProc(
  431. HWND hDlg,
  432. UINT message,
  433. WPARAM wParam,
  434. LPARAM lParam
  435. );
  436. LRESULT CALLBACK
  437. bSetInputBuffDlgProc(
  438. HWND hDlg,
  439. UINT message,
  440. WPARAM wParam,
  441. LPARAM lParam
  442. );
  443. LRESULT CALLBACK
  444. bSetDataDlgProc(
  445. HWND hDlg,
  446. UINT message,
  447. WPARAM wParam,
  448. LPARAM lParam
  449. );
  450. LRESULT CALLBACK
  451. bSetBufLenDlgProc(
  452. HWND hDlg,
  453. UINT message,
  454. WPARAM wParam,
  455. LPARAM lParam
  456. );
  457. LRESULT CALLBACK
  458. bSetInputBuffersDlgProc(
  459. HWND hDlg,
  460. UINT message,
  461. WPARAM wParam,
  462. LPARAM lParam
  463. );
  464. LRESULT CALLBACK
  465. bGetIndexedDlgProc(
  466. HWND hDlg,
  467. UINT message,
  468. WPARAM wParam,
  469. LPARAM lParam
  470. );
  471. LRESULT CALLBACK
  472. bGetUsageDiffDlgProc(
  473. HWND hDlg,
  474. UINT message,
  475. WPARAM wParam,
  476. LPARAM lParam
  477. );
  478. BOOL
  479. ConvertStringToUnsignedList(
  480. IN INT iUnsignedSize,
  481. IN INT iBase,
  482. IN OUT PCHAR InString,
  483. OUT PCHAR *UnsignedList,
  484. OUT PULONG nUnsigneds
  485. );
  486. BOOL
  487. ConvertStringToUlongList(
  488. IN OUT PCHAR InString,
  489. OUT PULONG *UlongList,
  490. OUT PULONG nUlongs
  491. );
  492. BOOL
  493. ConvertStringToUsageList(
  494. IN OUT PCHAR InString,
  495. OUT PUSAGE *UsageList,
  496. OUT PULONG nUsages
  497. );
  498. VOID
  499. ECDisp_MakeGUIDString(
  500. IN GUID guid,
  501. OUT CHAR szString[]
  502. );
  503. PCHAR
  504. ECDisp_GetHidAppStatusString(
  505. NTSTATUS StatusCode
  506. );
  507. BOOL
  508. ECDisp_ConvertUlongListToValueList(
  509. IN PULONG UlongList,
  510. IN ULONG nUlongs,
  511. IN USHORT BitSize,
  512. IN USHORT ReportCount,
  513. OUT PCHAR *ValueList,
  514. OUT PULONG ValueListSize
  515. );
  516. BOOL
  517. SetDlgItemIntHex(
  518. HWND hDlg,
  519. INT nIDDlgItem,
  520. UINT uValue,
  521. INT nBytes
  522. );
  523. PCHAR
  524. ResolveFunctionName(
  525. INT Index
  526. );
  527. DWORD WINAPI
  528. ECDisp_ReadThreadProc(
  529. LPVOID ThreadContext
  530. );
  531. VOID
  532. DisplayExtendedAttributes(
  533. IN HWND OutputWindow,
  534. IN PHIDP_UNKNOWN_TOKEN UnknownList,
  535. IN ULONG UnknownListLength
  536. );
  537. /*****************************************************************************
  538. /* Global function definitions
  539. /*****************************************************************************/
  540. LRESULT CALLBACK
  541. bExtCallDlgProc(
  542. HWND hDlg,
  543. UINT message,
  544. WPARAM wParam,
  545. LPARAM lParam
  546. )
  547. {
  548. static PHID_DEVICE pDevice;
  549. static CHAR szTempBuff[1024];
  550. static CHAR szLabel[512];
  551. static CHAR szValue[512];
  552. static INT iLBCounter;
  553. static UCHAR *pucInputReportIDs;
  554. static UCHAR *pucOutputReportIDs;
  555. static UCHAR *pucFeatureReportIDs;
  556. static INT nInputReportIDs;
  557. static INT nOutputReportIDs;
  558. static INT nFeatureReportIDs;
  559. static HANDLE ReadThread;
  560. static READ_THREAD_CONTEXT readContext;
  561. INT iIndex;
  562. ECDISPLAY_PARAMS params;
  563. DWORD threadID;
  564. switch(message)
  565. {
  566. case WM_INITDIALOG:
  567. /*
  568. // Initializing the dialog box involves the following steps:
  569. // 1) Determine from the parameter the pointer to the selected device
  570. // 2) Initializing the controls in the dialog box to their initial values
  571. // 3) Send a message that our list of routines has changed
  572. */
  573. pDevice = (PHID_DEVICE) lParam;
  574. vInitECControls(hDlg,
  575. pDevice -> Caps.InputReportByteLength,
  576. &pInputDisplay,
  577. pDevice -> Caps.OutputReportByteLength,
  578. &pOutputDisplay,
  579. pDevice -> Caps.FeatureReportByteLength,
  580. &pFeatureDisplay,
  581. LogPnP_IsLogicalDevice(pDevice));
  582. ReadThread = NULL;
  583. PostMessage(hDlg,
  584. WM_COMMAND,
  585. IDC_EXTCALLS + (CBN_SELCHANGE << 16),
  586. (LPARAM) GetDlgItem(hDlg,IDC_EXTCALLS));
  587. break;
  588. case WM_COMMAND:
  589. switch(LOWORD(wParam))
  590. {
  591. case IDC_EXTCALLS:
  592. switch (HIWORD(wParam))
  593. {
  594. case CBN_SELCHANGE:
  595. iIndex = (INT) SendDlgItemMessage(hDlg,
  596. IDC_EXTCALLS,
  597. CB_GETCURSEL,
  598. 0,
  599. 0);
  600. vEnableParameters(hDlg,
  601. SendDlgItemMessage(hDlg,
  602. IDC_EXTCALLS,
  603. CB_GETITEMDATA,
  604. iIndex,
  605. 0));
  606. break;
  607. }
  608. break;
  609. case IDC_INPUT_SELECT:
  610. if (CBN_SELCHANGE == HIWORD(wParam))
  611. {
  612. BufferDisplay_ChangeSelection(pInputDisplay);
  613. }
  614. break;
  615. case IDC_OUTPUT_SELECT:
  616. if (CBN_SELCHANGE == HIWORD(wParam))
  617. {
  618. BufferDisplay_ChangeSelection(pOutputDisplay);
  619. }
  620. break;
  621. case IDC_FEATURE_SELECT:
  622. if (CBN_SELCHANGE == HIWORD(wParam))
  623. {
  624. BufferDisplay_ChangeSelection(pFeatureDisplay);
  625. }
  626. break;
  627. case IDC_EXECUTE:
  628. /*
  629. // Get the parameters and verify that they are all correct
  630. // If there is an error, display an error message and
  631. // don't continue any further.
  632. */
  633. if ( !fGetAndVerifyParameters(hDlg, &params) )
  634. {
  635. ECDISP_ERROR(hDlg, "Error: One or more parameters are invalid");
  636. }
  637. /*
  638. // Else the parameters are valid and we can execute the call
  639. */
  640. else
  641. {
  642. iIndex = (INT) SendDlgItemMessage(hDlg, IDC_EXTCALLS, CB_GETCURSEL, 0, 0);
  643. iIndex = (INT) SendDlgItemMessage(hDlg, IDC_EXTCALLS, CB_GETITEMDATA, iIndex, 0);
  644. /*
  645. // Now that we know the function to execute we need to execute it
  646. // and output the data
  647. */
  648. SendDlgItemMessage(hDlg, IDC_CALLOUTPUT, LB_RESETCONTENT, 0, 0);
  649. vExecuteAndDisplayOutput(GetDlgItem(hDlg, IDC_CALLOUTPUT), pDevice, iIndex, &params);
  650. }
  651. break; /* end IDC_EXECUTE case */
  652. /*
  653. // Start up a read thread that can read input reports while
  654. // we operate on the other stuff
  655. */
  656. case IDC_READ_SYNCH:
  657. case IDC_READ_ASYNCH:
  658. if (NULL == ReadThread)
  659. {
  660. readContext.HidDevice = pDevice;
  661. readContext.TerminateThread = FALSE;
  662. readContext.DoOneRead = TRUE;
  663. readContext.DisplayEvent = NULL;
  664. readContext.DisplayWindow = hDlg;
  665. ReadThread = CreateThread( NULL,
  666. 0,
  667. (LOWORD(wParam) == IDC_READ_SYNCH) ?
  668. SynchReadThreadProc :
  669. AsynchReadThreadProc,
  670. (LPVOID) &readContext,
  671. 0,
  672. &threadID);
  673. if (NULL == ReadThread)
  674. {
  675. MessageBox(hDlg,
  676. "Unable to create read thread",
  677. HCLIENT_ERROR,
  678. MB_ICONEXCLAMATION);
  679. }
  680. else
  681. {
  682. EnableWindow(GetDlgItem(hDlg, IDC_READ_SYNCH),
  683. (LOWORD(wParam) == IDC_READ_SYNCH));
  684. EnableWindow(GetDlgItem(hDlg, IDC_READ_ASYNCH),
  685. (LOWORD(wParam) == IDC_READ_ASYNCH));
  686. SetWindowText(GetDlgItem(hDlg, LOWORD(wParam)),
  687. "Stop Read Thread");
  688. EnableWindow(GetDlgItem(hDlg, IDC_CANCEL), FALSE);
  689. }
  690. }
  691. else
  692. {
  693. readContext.TerminateThread = TRUE;
  694. WaitForSingleObject(ReadThread, INFINITE);
  695. ReadThread = NULL;
  696. SetWindowText(GetDlgItem(hDlg, IDC_READ_SYNCH),
  697. "Start Synchronous Read Thread");
  698. SetWindowText(GetDlgItem(hDlg, IDC_READ_ASYNCH),
  699. "Start Asynchronous Read Thread");
  700. EnableWindow(GetDlgItem(hDlg, IDC_READ_SYNCH), TRUE);
  701. EnableWindow(GetDlgItem(hDlg, IDC_READ_ASYNCH), TRUE);
  702. EnableWindow(GetDlgItem(hDlg, IDC_CANCEL), TRUE);
  703. }
  704. break;
  705. case IDC_CANCEL:
  706. BufferDisplay_Destroy(pInputDisplay);
  707. BufferDisplay_Destroy(pOutputDisplay);
  708. BufferDisplay_Destroy(pFeatureDisplay);
  709. EndDialog(hDlg, 0);
  710. break;
  711. }
  712. break;
  713. case WM_CLOSE:
  714. PostMessage(hDlg, WM_COMMAND, IDC_CANCEL, 0);
  715. break;
  716. }
  717. return FALSE;
  718. }
  719. VOID
  720. vLoadExtCalls(
  721. HWND hExtCalls,
  722. BOOL IsLogicalDevice
  723. )
  724. {
  725. INT iIndex;
  726. UINT uiIndex;
  727. /*
  728. // If we are a physical device, load the physical device specific calls as well
  729. */
  730. if (!IsLogicalDevice)
  731. {
  732. for (uiIndex = 0; uiIndex < HID_DEVCALLS; uiIndex++)
  733. {
  734. iIndex = (INT) SendMessage(hExtCalls,
  735. CB_ADDSTRING,
  736. 0,
  737. (LPARAM) DeviceCalls[uiIndex].szFunctionName);
  738. if (CB_ERR != iIndex || CB_ERRSPACE != iIndex)
  739. {
  740. SendMessage(hExtCalls,
  741. CB_SETITEMDATA,
  742. iIndex,
  743. DeviceCalls[uiIndex].uiIndex);
  744. }
  745. }
  746. }
  747. /*
  748. // Load the other device calls no matter what
  749. */
  750. for (uiIndex = 0; uiIndex < HID_PPDCALLS; uiIndex++)
  751. {
  752. iIndex = (INT) SendMessage(hExtCalls,
  753. CB_ADDSTRING,
  754. 0,
  755. (LPARAM) PpdCalls[uiIndex].szFunctionName);
  756. if (CB_ERR != iIndex || CB_ERRSPACE != iIndex)
  757. {
  758. SendMessage(hExtCalls,
  759. CB_SETITEMDATA,
  760. iIndex,
  761. PpdCalls[uiIndex].uiIndex);
  762. }
  763. }
  764. SendMessage(hExtCalls, CB_SETCURSEL, 0, 0);
  765. return;
  766. }
  767. VOID vSetReportType(
  768. HWND hDlg,
  769. LONG lId
  770. )
  771. {
  772. CheckRadioButton(hDlg, IDC_INPUT, IDC_FEATURE, lId);
  773. return;
  774. }
  775. VOID
  776. vInitEditText(
  777. HWND hText,
  778. INT cbTextSize,
  779. CHAR *pchText
  780. )
  781. {
  782. SendMessage(hText, EM_SETLIMITTEXT, (WPARAM) cbTextSize, 0);
  783. SendMessage(hText, EM_REPLACESEL, 0, (LPARAM) pchText);
  784. return;
  785. }
  786. VOID vEnableParameters(
  787. HWND hDlg,
  788. LRESULT iCallSelection
  789. )
  790. {
  791. EnableWindow(GetDlgItem(hDlg, IDC_INPUT), pState[iCallSelection-1].fInputReport);
  792. EnableWindow(GetDlgItem(hDlg, IDC_OUTPUT), pState[iCallSelection-1].fOutputReport);
  793. EnableWindow(GetDlgItem(hDlg, IDC_FEATURE), pState[iCallSelection-1].fFeatureReport);
  794. EnableWindow(GetDlgItem(hDlg, IDC_REPORTID), pState[iCallSelection-1].fReportID);
  795. EnableWindow(GetDlgItem(hDlg, IDC_USAGEPAGE), pState[iCallSelection-1].fUsagePage);
  796. EnableWindow(GetDlgItem(hDlg, IDC_USAGE), pState[iCallSelection-1].fUsage);
  797. EnableWindow(GetDlgItem(hDlg, IDC_LINKCOLL), pState[iCallSelection-1].fLinkCollection);
  798. EnableWindow(GetDlgItem(hDlg, IDC_INPUT_SELECT), pState[iCallSelection-1].fInputReportSelect);
  799. EnableWindow(GetDlgItem(hDlg, IDC_OUTPUT_SELECT), pState[iCallSelection-1].fOutputReportSelect);
  800. EnableWindow(GetDlgItem(hDlg, IDC_FEATURE_SELECT), pState[iCallSelection-1].fFeatureReportSelect);
  801. return;
  802. }
  803. BOOL
  804. fGetAndVerifyParameters(
  805. HWND hDlg,
  806. PECDISPLAY_PARAMS pParams
  807. )
  808. {
  809. /*
  810. // Declare a text buffer of size 7 since the parameter limit is at most 6
  811. // characters in the edit box.
  812. */
  813. CHAR WindowText[7];
  814. BOOL fStatus = TRUE;
  815. PCHAR nptr;
  816. if (IsDlgButtonChecked(hDlg, IDC_INPUT))
  817. {
  818. pParams -> ReportType = HidP_Input;
  819. }
  820. else if (IsDlgButtonChecked(hDlg, IDC_OUTPUT))
  821. {
  822. pParams -> ReportType = HidP_Output;
  823. }
  824. else
  825. {
  826. pParams -> ReportType = HidP_Feature;
  827. }
  828. /*
  829. // Get and verify the usage page window text;
  830. */
  831. GetWindowText(GetDlgItem(hDlg, IDC_USAGEPAGE), WindowText, 7);
  832. pParams -> UsagePage = (USAGE) strtol(WindowText, &nptr, 16);
  833. if (*nptr != '\0')
  834. {
  835. fStatus = FALSE;
  836. pParams -> UsagePage = 0;
  837. }
  838. /*
  839. // Get and verify the usage window text
  840. */
  841. GetWindowText(GetDlgItem(hDlg, IDC_USAGE), WindowText, 7);
  842. pParams -> Usage = (USAGE) strtol(WindowText, &nptr, 16);
  843. if (*nptr != '\0')
  844. {
  845. fStatus = FALSE;
  846. pParams -> Usage = 0;
  847. }
  848. /*
  849. // Get and verify the link collection window text
  850. */
  851. GetWindowText(GetDlgItem(hDlg, IDC_LINKCOLL), WindowText, 7);
  852. pParams -> LinkCollection = (USAGE) strtol(WindowText, &nptr, 16);
  853. if (*nptr != '\0')
  854. {
  855. fStatus = FALSE;
  856. pParams -> LinkCollection = 0;
  857. }
  858. GetWindowText(GetDlgItem(hDlg, IDC_REPORTID), WindowText, 7);
  859. pParams -> ReportID = (UCHAR) strtol(WindowText, &nptr, 10);
  860. if (*nptr != '\0')
  861. {
  862. fStatus = FALSE;
  863. pParams -> ReportID = 0;
  864. }
  865. return (fStatus);
  866. }
  867. VOID
  868. vInitECControls(
  869. HWND hDlg,
  870. USHORT InputReportByteLength,
  871. PBUFFER_DISPLAY *ppInputDisplay,
  872. USHORT OutputReportByteLength,
  873. PBUFFER_DISPLAY *ppOutputDisplay,
  874. USHORT FeatureReportByteLength,
  875. PBUFFER_DISPLAY *ppFeatureDisplay,
  876. BOOL IsLogicalDevice
  877. )
  878. {
  879. BOOLEAN fInitStatus;
  880. /*
  881. // Begin by initializing the combo box with the calls that can be executed
  882. */
  883. vLoadExtCalls(GetDlgItem(hDlg, IDC_EXTCALLS), IsLogicalDevice);
  884. /*
  885. // Set the radio buttons initially to the input report type
  886. */
  887. vSetReportType(hDlg, IDC_INPUT);
  888. /*
  889. // Initialize the edit controls text
  890. */
  891. vInitEditText(GetDlgItem(hDlg, IDC_USAGEPAGE), 6, "0x0000");
  892. vInitEditText(GetDlgItem(hDlg, IDC_USAGE), 6, "0x0000");
  893. vInitEditText(GetDlgItem(hDlg, IDC_LINKCOLL), 2, "0");
  894. vInitEditText(GetDlgItem(hDlg, IDC_REPORTID), 3, "0");
  895. /*
  896. // Initialize the report buffer boxes
  897. */
  898. fInitStatus = BufferDisplay_Init(GetDlgItem(hDlg, IDC_INPUT_SELECT),
  899. GetDlgItem(hDlg, IDC_INPUT_BUFFER),
  900. NUM_INPUT_BUFFERS,
  901. InputReportByteLength,
  902. HidP_Input,
  903. ppInputDisplay);
  904. if (!fInitStatus)
  905. {
  906. ECDISP_ERROR(hDlg, "Error initializing input buffer display");
  907. }
  908. fInitStatus = BufferDisplay_Init(GetDlgItem(hDlg, IDC_OUTPUT_SELECT),
  909. GetDlgItem(hDlg, IDC_OUTPUT_BUFFER),
  910. NUM_OUTPUT_BUFFERS,
  911. OutputReportByteLength,
  912. HidP_Output,
  913. ppOutputDisplay);
  914. if (!fInitStatus)
  915. {
  916. ECDISP_ERROR(hDlg, "Error initializing output buffer display");
  917. }
  918. fInitStatus = BufferDisplay_Init(GetDlgItem(hDlg, IDC_FEATURE_SELECT),
  919. GetDlgItem(hDlg, IDC_FEATURE_BUFFER),
  920. NUM_FEATURE_BUFFERS,
  921. FeatureReportByteLength,
  922. HidP_Feature,
  923. ppFeatureDisplay);
  924. if (!fInitStatus)
  925. {
  926. ECDISP_ERROR(hDlg, "Error initializing feature buffer display");
  927. }
  928. /*
  929. // Reset the output box content
  930. */
  931. SendMessage(GetDlgItem(hDlg, IDC_CALLOUTPUT), LB_RESETCONTENT, 0, 0);
  932. return;
  933. }
  934. BOOL
  935. ECDisp_Execute(
  936. IN INT FuncCall,
  937. IN OUT PEXTCALL_PARAMS CallParams,
  938. OUT PEXTCALL_STATUS CallStatus
  939. )
  940. /*++
  941. RoutineDescription:
  942. This routine is a complex routine for executing all of the functions. The
  943. routine was originally developed with consideration for future use that
  944. never materialized.
  945. It makes use of the calls in extcalls.c which basically execute the given
  946. function and does some verification on the buffers that are passed down to
  947. HID.DLL.
  948. The input parameters are specify the function call to execute, the
  949. call parameters structures and the call status structure.
  950. If any further buffers are needed for the specific calls, they will be
  951. allocated here.
  952. The CallStatus parameters is a structure set by the ExtCalls_ routines
  953. Future versions of the HClient sample may remove this routine and/or the
  954. ExtCalls_ routines to simply the code.
  955. --*/
  956. {
  957. BOOL ExecuteStatus;
  958. HIDP_VALUE_CAPS ValueCaps;
  959. USHORT ValueCapsLength;
  960. PULONG ValueList;
  961. NTSTATUS status;
  962. DWORD numBytes;
  963. ULONG size;
  964. /*
  965. // Initially assume everything will go correctly and will set otherwise
  966. // depending on the function call.
  967. */
  968. CallStatus -> IsHidError = FALSE;
  969. switch (FuncCall)
  970. {
  971. case HID_READ_REPORT:
  972. CallStatus -> IsHidError = !ReadFile(CallParams -> DeviceHandle,
  973. CallParams -> ReportBuffer,
  974. CallParams -> ReportLength,
  975. &numBytes,
  976. NULL);
  977. return (TRUE);
  978. break;
  979. case HID_WRITE_REPORT:
  980. CallStatus -> IsHidError = !WriteFile(CallParams -> DeviceHandle,
  981. CallParams -> ReportBuffer,
  982. CallParams -> ReportLength,
  983. &numBytes,
  984. NULL);
  985. return (TRUE);
  986. break;
  987. case HIDD_FLUSH_QUEUE:
  988. CallStatus -> IsHidError = !HidD_FlushQueue(CallParams -> DeviceHandle);
  989. return (TRUE);
  990. break;
  991. case HIDD_GET_HID_GUID:
  992. CallParams -> List = malloc(sizeof(GUID));
  993. if (NULL != CallParams -> List)
  994. {
  995. HidD_GetHidGuid((GUID *) CallParams -> List);
  996. }
  997. return (NULL != CallParams -> List);
  998. break;
  999. case HIDD_GET_PREPARSED_DATA:
  1000. CallStatus -> IsHidError = !HidD_GetPreparsedData(CallParams -> DeviceHandle,
  1001. CallParams -> ppPd);
  1002. return (TRUE);
  1003. case HIDD_FREE_PREPARSED_DATA:
  1004. CallStatus -> IsHidError = !HidD_FreePreparsedData(CallParams -> Ppd);
  1005. return (TRUE);
  1006. case HIDD_GET_ATTRIBUTES:
  1007. CallParams -> List = malloc(sizeof(HIDD_ATTRIBUTES));
  1008. if (NULL != CallParams -> List)
  1009. {
  1010. CallStatus -> IsHidError = !HidD_GetAttributes(CallParams -> DeviceHandle,
  1011. CallParams -> List);
  1012. }
  1013. return (NULL != CallParams -> List);
  1014. case HIDD_GET_FEATURE:
  1015. *(CallParams -> ReportBuffer) = CallParams -> ReportID;
  1016. CallStatus -> IsHidError = !HidD_GetFeature(CallParams -> DeviceHandle,
  1017. CallParams -> ReportBuffer,
  1018. CallParams -> ReportLength);
  1019. return (TRUE);
  1020. case HIDD_SET_FEATURE:
  1021. CallStatus -> IsHidError = !HidD_SetFeature(CallParams -> DeviceHandle,
  1022. CallParams -> ReportBuffer,
  1023. CallParams -> ReportLength);
  1024. return (TRUE);
  1025. case HIDD_GET_INPUT_REPORT:
  1026. *(CallParams -> ReportBuffer) = CallParams -> ReportID;
  1027. CallStatus -> IsHidError = !HidD_GetInputReport(CallParams -> DeviceHandle,
  1028. CallParams -> ReportBuffer,
  1029. CallParams -> ReportLength);
  1030. return (TRUE);
  1031. case HIDD_SET_OUTPUT_REPORT:
  1032. CallStatus -> IsHidError = !HidD_SetOutputReport(CallParams -> DeviceHandle,
  1033. CallParams -> ReportBuffer,
  1034. CallParams -> ReportLength);
  1035. return (TRUE);
  1036. case HIDD_GET_NUM_INPUT_BUFFERS:
  1037. CallStatus -> IsHidError = !HidD_GetNumInputBuffers(CallParams -> DeviceHandle,
  1038. &CallParams -> Value);
  1039. return (TRUE);
  1040. case HIDD_SET_NUM_INPUT_BUFFERS:
  1041. CallStatus -> IsHidError = !HidD_SetNumInputBuffers(CallParams -> DeviceHandle,
  1042. CallParams -> Value);
  1043. return (TRUE);
  1044. case HIDD_GET_PHYSICAL_DESCRIPTOR:
  1045. CallParams -> List = (PCHAR) malloc (CallParams -> ListLength);
  1046. if (NULL != CallParams -> List )
  1047. {
  1048. CallStatus -> IsHidError = !HidD_GetPhysicalDescriptor(CallParams -> DeviceHandle,
  1049. CallParams -> List,
  1050. CallParams -> ListLength);
  1051. }
  1052. return (NULL != CallParams -> List);
  1053. case HIDD_GET_MANUFACTURER_STRING:
  1054. CallParams -> List = (PWCHAR) malloc (CallParams -> ListLength);
  1055. if (NULL != CallParams -> List )
  1056. {
  1057. CallStatus -> IsHidError = !HidD_GetManufacturerString(CallParams -> DeviceHandle,
  1058. CallParams -> List,
  1059. CallParams -> ListLength);
  1060. }
  1061. return (NULL != CallParams -> List);
  1062. case HIDD_GET_PRODUCT_STRING:
  1063. CallParams -> List = (PWCHAR) malloc (CallParams -> ListLength);
  1064. if (NULL != CallParams -> List )
  1065. {
  1066. CallStatus -> IsHidError = !HidD_GetProductString(CallParams -> DeviceHandle,
  1067. CallParams -> List,
  1068. CallParams -> ListLength);
  1069. }
  1070. return (NULL != CallParams -> List);
  1071. case HIDP_GET_EXTENDED_ATTRIBUTES:
  1072. CallParams -> List = (PWCHAR) malloc (CallParams -> ListLength);
  1073. if (NULL != CallParams -> List )
  1074. {
  1075. status = pfnHidP_GetExtendedAttributes(CallParams -> ReportType,
  1076. (USHORT) CallParams -> Index,
  1077. CallParams -> Ppd,
  1078. CallParams -> List,
  1079. &CallParams -> ListLength);
  1080. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1081. CallStatus -> HidErrorCode = status;
  1082. }
  1083. return (NULL != CallParams -> List);
  1084. case HIDD_GET_INDEXED_STRING:
  1085. CallParams -> List = (PWCHAR) malloc (CallParams -> ListLength);
  1086. if (NULL != CallParams -> List )
  1087. {
  1088. CallStatus -> IsHidError = !HidD_GetIndexedString(CallParams -> DeviceHandle,
  1089. CallParams -> Index,
  1090. CallParams -> List,
  1091. CallParams -> ListLength);
  1092. }
  1093. return (NULL != CallParams -> List);
  1094. case HIDD_GET_SERIAL_NUMBER_STRING:
  1095. CallParams -> List = (PWCHAR) malloc (CallParams -> ListLength);
  1096. if (NULL != CallParams -> List )
  1097. {
  1098. CallStatus -> IsHidError = !HidD_GetSerialNumberString(CallParams -> DeviceHandle,
  1099. CallParams -> List,
  1100. CallParams -> ListLength);
  1101. }
  1102. return (NULL != CallParams -> List);
  1103. case HIDD_GET_MS_GENRE_DESCRIPTOR:
  1104. CallParams -> List = (PCHAR) malloc (CallParams -> ListLength);
  1105. if (NULL != CallParams -> List )
  1106. {
  1107. CallStatus -> IsHidError = !HidD_GetMsGenreDescriptor(CallParams -> DeviceHandle,
  1108. CallParams -> List,
  1109. CallParams -> ListLength);
  1110. }
  1111. return (NULL != CallParams -> List);
  1112. case HIDP_GET_BUTTON_CAPS:
  1113. size = CallParams -> ListLength * sizeof(HIDP_BUTTON_CAPS);
  1114. CallParams -> List = malloc(size);
  1115. if (NULL != CallParams -> List)
  1116. {
  1117. status = HidP_GetButtonCaps(CallParams -> ReportType,
  1118. CallParams -> List,
  1119. (PUSHORT) &CallParams -> ListLength,
  1120. CallParams -> Ppd);
  1121. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1122. CallStatus -> HidErrorCode = status;
  1123. }
  1124. return (NULL != CallParams -> List);
  1125. case HIDP_GET_BUTTONS:
  1126. CallParams -> ListLength = HidP_MaxUsageListLength(CallParams -> ReportType,
  1127. CallParams -> UsagePage,
  1128. CallParams -> Ppd);
  1129. CallParams -> List = malloc(CallParams -> ListLength * sizeof(USAGE));
  1130. if (NULL != CallParams -> List)
  1131. {
  1132. status = HidP_GetButtons(CallParams -> ReportType,
  1133. CallParams -> UsagePage,
  1134. CallParams -> LinkCollection,
  1135. CallParams -> List,
  1136. &CallParams -> ListLength,
  1137. CallParams -> Ppd,
  1138. CallParams -> ReportBuffer,
  1139. CallParams -> ReportLength);
  1140. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1141. CallStatus -> HidErrorCode = status;
  1142. }
  1143. return (NULL != CallParams -> List);
  1144. case HIDP_GET_BUTTONS_EX:
  1145. CallParams -> ListLength = HidP_MaxUsageListLength(CallParams -> ReportType,
  1146. CallParams -> UsagePage,
  1147. CallParams -> Ppd);
  1148. CallParams -> List = malloc(CallParams -> ListLength * sizeof(USAGE_AND_PAGE));
  1149. if (NULL != CallParams -> List)
  1150. {
  1151. status = HidP_GetButtonsEx(CallParams -> ReportType,
  1152. CallParams -> LinkCollection,
  1153. CallParams -> List,
  1154. &CallParams -> ListLength,
  1155. CallParams -> Ppd,
  1156. CallParams -> ReportBuffer,
  1157. CallParams -> ReportLength);
  1158. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1159. CallStatus -> HidErrorCode = status;
  1160. }
  1161. return (NULL != CallParams -> List);
  1162. case HIDP_GET_CAPS:
  1163. CallParams -> ListLength = sizeof(HIDP_CAPS);
  1164. CallParams -> List = malloc(sizeof(HIDP_CAPS));
  1165. if (NULL != CallParams -> List)
  1166. {
  1167. status = HidP_GetCaps(CallParams -> Ppd, CallParams -> List);
  1168. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1169. CallStatus -> HidErrorCode = status;
  1170. }
  1171. return (NULL != CallParams -> List);
  1172. case HIDP_GET_DATA:
  1173. CallParams -> ListLength = HidP_MaxDataListLength(CallParams -> ReportType,
  1174. CallParams -> Ppd);
  1175. CallParams -> List = malloc(CallParams -> ListLength * sizeof(HIDP_DATA));
  1176. if (NULL != CallParams -> List)
  1177. {
  1178. status = HidP_GetData(CallParams -> ReportType,
  1179. CallParams -> List,
  1180. &CallParams -> ListLength,
  1181. CallParams -> Ppd,
  1182. CallParams -> ReportBuffer,
  1183. CallParams -> ReportLength);
  1184. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1185. CallStatus -> HidErrorCode = status;
  1186. }
  1187. return (NULL != CallParams -> List);
  1188. case HIDP_GET_LINK_COLL_NODES:
  1189. CallParams -> List = malloc(CallParams -> ListLength * sizeof(HIDP_LINK_COLLECTION_NODE));
  1190. if (NULL != CallParams -> List)
  1191. {
  1192. status = HidP_GetLinkCollectionNodes(CallParams -> List,
  1193. &CallParams -> ListLength,
  1194. CallParams -> Ppd);
  1195. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1196. CallStatus -> HidErrorCode = status;
  1197. }
  1198. return (NULL != CallParams -> List);
  1199. case HIDP_GET_SCALED_USAGE_VALUE:
  1200. status = HidP_GetScaledUsageValue(CallParams -> ReportType,
  1201. CallParams -> UsagePage,
  1202. CallParams -> LinkCollection,
  1203. CallParams -> Usage,
  1204. &CallParams -> ScaledValue,
  1205. CallParams -> Ppd,
  1206. CallParams -> ReportBuffer,
  1207. CallParams -> ReportLength);
  1208. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1209. CallStatus -> HidErrorCode = status;
  1210. return (TRUE);
  1211. case HIDP_GET_SPECIFIC_BUTTON_CAPS:
  1212. CallParams -> List = malloc(CallParams -> ListLength * sizeof(HIDP_BUTTON_CAPS));
  1213. if (NULL != CallParams -> List)
  1214. {
  1215. status = HidP_GetSpecificButtonCaps(CallParams -> ReportType,
  1216. CallParams -> UsagePage,
  1217. CallParams -> LinkCollection,
  1218. CallParams -> Usage,
  1219. CallParams -> List,
  1220. (PUSHORT) &CallParams -> ListLength,
  1221. CallParams -> Ppd);
  1222. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1223. CallStatus -> HidErrorCode = status;
  1224. }
  1225. return (NULL != CallParams -> List);
  1226. case HIDP_GET_SPECIFIC_VALUE_CAPS:
  1227. CallParams -> List = malloc(CallParams -> ListLength * sizeof(HIDP_VALUE_CAPS));
  1228. if (NULL != CallParams -> List)
  1229. {
  1230. status = HidP_GetSpecificValueCaps(CallParams -> ReportType,
  1231. CallParams -> UsagePage,
  1232. CallParams -> LinkCollection,
  1233. CallParams -> Usage,
  1234. CallParams -> List,
  1235. (PUSHORT) &CallParams -> ListLength,
  1236. CallParams -> Ppd);
  1237. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1238. CallStatus -> HidErrorCode = status;
  1239. }
  1240. return (NULL != CallParams -> List);
  1241. case HIDP_GET_USAGES:
  1242. CallParams -> ListLength = HidP_MaxUsageListLength(CallParams -> ReportType,
  1243. CallParams -> UsagePage,
  1244. CallParams -> Ppd);
  1245. CallParams -> List = malloc(CallParams -> ListLength * sizeof(USAGE));
  1246. if (NULL != CallParams -> List)
  1247. {
  1248. status = HidP_GetUsages(CallParams -> ReportType,
  1249. CallParams -> UsagePage,
  1250. CallParams -> LinkCollection,
  1251. CallParams -> List,
  1252. &CallParams -> ListLength,
  1253. CallParams -> Ppd,
  1254. CallParams -> ReportBuffer,
  1255. CallParams -> ReportLength);
  1256. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1257. CallStatus -> HidErrorCode = status;
  1258. }
  1259. return (NULL != CallParams -> List);
  1260. case HIDP_GET_USAGES_EX:
  1261. CallParams -> ListLength = HidP_MaxUsageListLength(CallParams -> ReportType,
  1262. CallParams -> UsagePage,
  1263. CallParams -> Ppd);
  1264. CallParams -> List = malloc(CallParams -> ListLength * sizeof(USAGE_AND_PAGE));
  1265. if (NULL != CallParams -> List)
  1266. {
  1267. status = HidP_GetUsagesEx(CallParams -> ReportType,
  1268. CallParams -> LinkCollection,
  1269. CallParams -> List,
  1270. &CallParams -> ListLength,
  1271. CallParams -> Ppd,
  1272. CallParams -> ReportBuffer,
  1273. CallParams -> ReportLength);
  1274. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1275. CallStatus -> HidErrorCode = status;
  1276. }
  1277. return (NULL != CallParams -> List);
  1278. case HIDP_GET_USAGE_VALUE:
  1279. status = HidP_GetUsageValue(CallParams -> ReportType,
  1280. CallParams -> UsagePage,
  1281. CallParams -> LinkCollection,
  1282. CallParams -> Usage,
  1283. &CallParams -> Value,
  1284. CallParams -> Ppd,
  1285. CallParams -> ReportBuffer,
  1286. CallParams -> ReportLength);
  1287. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1288. CallStatus -> HidErrorCode = status;
  1289. return (TRUE);
  1290. case HIDP_GET_USAGE_VALUE_ARRAY:
  1291. ValueCapsLength = 1;
  1292. status = HidP_GetSpecificValueCaps(CallParams -> ReportType,
  1293. CallParams -> UsagePage,
  1294. CallParams -> LinkCollection,
  1295. CallParams -> Usage,
  1296. &ValueCaps,
  1297. &ValueCapsLength,
  1298. CallParams -> Ppd);
  1299. if (HIDP_STATUS_SUCCESS != status)
  1300. {
  1301. return (FALSE);
  1302. }
  1303. CallParams -> BitSize = ValueCaps.BitSize;
  1304. CallParams -> ReportCount = ValueCaps.ReportCount;
  1305. CallParams -> ListLength
  1306. = ROUND_TO_NEAREST_BYTE(CallParams -> BitSize * CallParams -> ReportCount);
  1307. CallParams -> List = malloc(CallParams -> ListLength);
  1308. if (NULL != CallParams -> List)
  1309. {
  1310. status = HidP_GetUsageValueArray(CallParams -> ReportType,
  1311. CallParams -> UsagePage,
  1312. CallParams -> LinkCollection,
  1313. CallParams -> Usage,
  1314. CallParams -> List,
  1315. (USHORT) CallParams -> ListLength,
  1316. CallParams -> Ppd,
  1317. CallParams -> ReportBuffer,
  1318. CallParams -> ReportLength);
  1319. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1320. CallStatus -> HidErrorCode = status;
  1321. }
  1322. return (NULL != CallParams -> List);
  1323. case HIDP_GET_VALUE_CAPS:
  1324. CallParams -> List = malloc(CallParams -> ListLength * sizeof(HIDP_VALUE_CAPS));
  1325. if (NULL != CallParams -> List)
  1326. {
  1327. status = HidP_GetValueCaps(CallParams -> ReportType,
  1328. CallParams -> List,
  1329. (PUSHORT) &CallParams -> ListLength,
  1330. CallParams -> Ppd);
  1331. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1332. CallStatus -> HidErrorCode = status;
  1333. }
  1334. case HIDP_INITIALIZE_REPORT_FOR_ID:
  1335. status = pfnHidP_InitializeReportForID(CallParams -> ReportType,
  1336. CallParams -> ReportID,
  1337. CallParams -> Ppd,
  1338. CallParams -> ReportBuffer,
  1339. CallParams -> ReportLength);
  1340. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1341. CallStatus -> HidErrorCode = status;
  1342. return (TRUE);
  1343. case HIDP_MAX_USAGE_LIST_LENGTH:
  1344. CallParams -> Value = HidP_MaxUsageListLength(CallParams -> ReportType,
  1345. CallParams -> UsagePage,
  1346. CallParams -> Ppd);
  1347. CallStatus -> IsHidError = FALSE;
  1348. CallStatus -> HidErrorCode = HIDP_STATUS_SUCCESS;
  1349. return (TRUE);
  1350. case HIDP_MAX_DATA_LIST_LENGTH:
  1351. CallParams -> Value = HidP_MaxDataListLength(CallParams -> ReportType,
  1352. CallParams -> Ppd);
  1353. CallStatus -> IsHidError = FALSE;
  1354. CallStatus -> HidErrorCode = HIDP_STATUS_SUCCESS;
  1355. return (TRUE);
  1356. case HIDP_SET_BUTTONS:
  1357. status = HidP_SetButtons(CallParams -> ReportType,
  1358. CallParams -> UsagePage,
  1359. CallParams -> LinkCollection,
  1360. CallParams -> List,
  1361. &CallParams -> ListLength,
  1362. CallParams -> Ppd,
  1363. CallParams -> ReportBuffer,
  1364. CallParams -> ReportLength);
  1365. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1366. CallStatus -> HidErrorCode = status;
  1367. return (TRUE);
  1368. case HIDP_SET_DATA:
  1369. status = HidP_SetData(CallParams -> ReportType,
  1370. CallParams -> List,
  1371. &CallParams -> ListLength,
  1372. CallParams -> Ppd,
  1373. CallParams -> ReportBuffer,
  1374. CallParams -> ReportLength);
  1375. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1376. CallStatus -> HidErrorCode = status;
  1377. return (TRUE);
  1378. case HIDP_SET_SCALED_USAGE_VALUE:
  1379. status = HidP_SetUsageValue(CallParams -> ReportType,
  1380. CallParams -> UsagePage,
  1381. CallParams -> LinkCollection,
  1382. CallParams -> Usage,
  1383. CallParams -> ScaledValue,
  1384. CallParams -> Ppd,
  1385. CallParams -> ReportBuffer,
  1386. CallParams -> ReportLength);
  1387. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1388. CallStatus -> HidErrorCode = status;
  1389. return (TRUE);
  1390. case HIDP_SET_USAGES:
  1391. status = HidP_SetUsages(CallParams -> ReportType,
  1392. CallParams -> UsagePage,
  1393. CallParams -> LinkCollection,
  1394. CallParams -> List,
  1395. &CallParams -> ListLength,
  1396. CallParams -> Ppd,
  1397. CallParams -> ReportBuffer,
  1398. CallParams -> ReportLength);
  1399. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1400. CallStatus -> HidErrorCode = status;
  1401. return (TRUE);
  1402. case HIDP_SET_USAGE_VALUE:
  1403. status = HidP_SetUsageValue(CallParams -> ReportType,
  1404. CallParams -> UsagePage,
  1405. CallParams -> LinkCollection,
  1406. CallParams -> Usage,
  1407. CallParams -> Value,
  1408. CallParams -> Ppd,
  1409. CallParams -> ReportBuffer,
  1410. CallParams -> ReportLength);
  1411. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1412. CallStatus -> HidErrorCode = status;
  1413. return (TRUE);
  1414. case HIDP_SET_USAGE_VALUE_ARRAY:
  1415. ValueCapsLength = 1;
  1416. status = HidP_GetSpecificValueCaps(CallParams -> ReportType,
  1417. CallParams -> UsagePage,
  1418. CallParams -> LinkCollection,
  1419. CallParams -> Usage,
  1420. &ValueCaps,
  1421. &ValueCapsLength,
  1422. CallParams -> Ppd);
  1423. if (HIDP_STATUS_SUCCESS != status)
  1424. {
  1425. return (FALSE);
  1426. }
  1427. CallParams -> BitSize = ValueCaps.BitSize;
  1428. CallParams -> ReportCount = ValueCaps.ReportCount;
  1429. ValueList = CallParams -> List;
  1430. ExecuteStatus = ECDisp_ConvertUlongListToValueList(ValueList,
  1431. CallParams -> ListLength,
  1432. CallParams -> BitSize,
  1433. CallParams -> ReportCount,
  1434. (PCHAR *) &CallParams -> List,
  1435. &CallParams -> ListLength);
  1436. if (!ExecuteStatus)
  1437. {
  1438. return (FALSE);
  1439. }
  1440. status = HidP_SetUsageValueArray(CallParams -> ReportType,
  1441. CallParams -> UsagePage,
  1442. CallParams -> LinkCollection,
  1443. CallParams -> Usage,
  1444. CallParams -> List,
  1445. (USHORT) CallParams -> ListLength,
  1446. CallParams -> Ppd,
  1447. CallParams -> ReportBuffer,
  1448. CallParams -> ReportLength);
  1449. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1450. CallStatus -> HidErrorCode = status;
  1451. return (TRUE);
  1452. case HIDP_UNSET_BUTTONS:
  1453. status = HidP_UnsetButtons(CallParams -> ReportType,
  1454. CallParams -> UsagePage,
  1455. CallParams -> LinkCollection,
  1456. CallParams -> List,
  1457. &CallParams -> ListLength,
  1458. CallParams -> Ppd,
  1459. CallParams -> ReportBuffer,
  1460. CallParams -> ReportLength);
  1461. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1462. CallStatus -> HidErrorCode = status;
  1463. return (TRUE);
  1464. case HIDP_UNSET_USAGES:
  1465. status = HidP_UnsetUsages(CallParams -> ReportType,
  1466. CallParams -> UsagePage,
  1467. CallParams -> LinkCollection,
  1468. CallParams -> List,
  1469. &CallParams -> ListLength,
  1470. CallParams -> Ppd,
  1471. CallParams -> ReportBuffer,
  1472. CallParams -> ReportLength);
  1473. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1474. CallStatus -> HidErrorCode = status;
  1475. return (TRUE);
  1476. case HIDP_USAGE_LIST_DIFFERENCE:
  1477. CallParams -> MakeList = (PUSAGE) malloc (sizeof(USAGE) * CallParams -> ListLength);
  1478. if (NULL == CallParams -> MakeList)
  1479. {
  1480. return (FALSE);
  1481. }
  1482. CallParams -> BreakList = (PUSAGE) malloc (sizeof(USAGE) * CallParams -> ListLength);
  1483. if (NULL == CallParams -> BreakList)
  1484. {
  1485. free(CallParams -> MakeList);
  1486. return (FALSE);
  1487. }
  1488. status = HidP_UsageListDifference(CallParams -> List,
  1489. CallParams -> List2,
  1490. CallParams -> BreakList,
  1491. CallParams -> MakeList,
  1492. CallParams -> ListLength);
  1493. CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
  1494. CallStatus -> HidErrorCode = status;
  1495. return (TRUE);
  1496. }
  1497. return (FALSE);
  1498. }
  1499. VOID
  1500. ECDisp_DisplayOutput(
  1501. IN HWND hOutputWindow,
  1502. IN INT FuncCall,
  1503. IN PEXTCALL_PARAMS Results
  1504. )
  1505. /*++
  1506. RoutineDescription:
  1507. This routine is responsible for displaying the output from calls to HID.DLL
  1508. functions. It must extract and interpret the appropriate data from the
  1509. PEXTCALL_PARAMS structure.
  1510. --*/
  1511. {
  1512. PHIDP_LINK_COLLECTION_NODE NodeList;
  1513. PHIDP_BUTTON_CAPS ButtonCaps;
  1514. PHIDP_VALUE_CAPS ValueCaps;
  1515. PHIDP_DATA DataList;
  1516. PHIDP_EXTENDED_ATTRIBUTES ExtAttrib;
  1517. PUSAGE_AND_PAGE UsageAndPageList;
  1518. PUSAGE UsageList;
  1519. PCHAR UsageValueArray;
  1520. PBUFFER_DISPLAY pDisplay;
  1521. PCHAR PhysDescString;
  1522. PCHAR GenreDescString;
  1523. ULONG Index;
  1524. switch (FuncCall) {
  1525. case HIDD_GET_HID_GUID:
  1526. strcpy(szTempBuffer, "HID Guid: ");
  1527. ECDisp_MakeGUIDString(*((LPGUID) Results -> List),
  1528. &szTempBuffer[strlen(szTempBuffer)]);
  1529. OUTSTRING(hOutputWindow, szTempBuffer);
  1530. break;
  1531. case HIDD_GET_ATTRIBUTES:
  1532. vDisplayDeviceAttributes((PHIDD_ATTRIBUTES) Results -> List,
  1533. hOutputWindow);
  1534. break;
  1535. case HIDD_GET_NUM_INPUT_BUFFERS:
  1536. wsprintf(szTempBuffer, "Number input buffers: %u", Results -> Value);
  1537. OUTSTRING(hOutputWindow, szTempBuffer);
  1538. break;
  1539. case HIDD_GET_MS_GENRE_DESCRIPTOR:
  1540. OUTSTRING(hOutputWindow, "MS Genre Descriptor");
  1541. OUTSTRING(hOutputWindow, "===================");
  1542. /*
  1543. // To display a physical descriptor, the procedure currently just
  1544. // creates a string data buffer by bytes and displays that
  1545. // in the results box. It will display in rows of 16 bytes apiece.
  1546. */
  1547. Index = 0;
  1548. while (Index < Results -> ListLength)
  1549. {
  1550. Strings_CreateDataBufferString(((PCHAR) Results -> List) + Index,
  1551. Results -> ListLength - Index,
  1552. 16,
  1553. 1,
  1554. &GenreDescString);
  1555. if (NULL != GenreDescString)
  1556. {
  1557. OUTSTRING(hOutputWindow, GenreDescString);
  1558. free(GenreDescString);
  1559. }
  1560. else
  1561. {
  1562. OUTSTRING(hOutputWindow, "Error trying to display ms genre descriptor");
  1563. }
  1564. Index += 16;
  1565. }
  1566. break;
  1567. case HIDD_GET_PHYSICAL_DESCRIPTOR:
  1568. OUTSTRING(hOutputWindow, "Physical Descriptor");
  1569. OUTSTRING(hOutputWindow, "===================");
  1570. /*
  1571. // To display a physical descriptor, the procedure currently just
  1572. // creates a string data buffer by bytes and displays that
  1573. // in the results box. It will display in rows of 16 bytes apiece.
  1574. */
  1575. Index = 0;
  1576. while (Index < Results -> ListLength)
  1577. {
  1578. Strings_CreateDataBufferString(((PCHAR) Results -> List) + Index,
  1579. Results -> ListLength - Index,
  1580. 16,
  1581. 1,
  1582. &PhysDescString);
  1583. if (NULL != PhysDescString)
  1584. {
  1585. OUTSTRING(hOutputWindow, PhysDescString);
  1586. free(PhysDescString);
  1587. }
  1588. else
  1589. {
  1590. OUTSTRING(hOutputWindow, "Error trying to display physical descriptor");
  1591. }
  1592. Index += 16;
  1593. }
  1594. break;
  1595. /*
  1596. // For the string descriptor call routines, the returned string is stored
  1597. // in the Results -> List parameter. It should be noted that the
  1598. // strings returned by these calls are wide-char strings and that these
  1599. // string are terminated with a NULL character if there was space withing
  1600. // the buffer to add such a character. If the buffer was only big enough
  1601. // to hold the characters of the string, there will be no null terminator
  1602. // and the output string display mechanism may fail to properly display this
  1603. // type of string. Fixing of this display mechanism is a future (low priority)
  1604. // workitem.
  1605. */
  1606. case HIDD_GET_PRODUCT_STRING:
  1607. OUTSTRING(hOutputWindow, "Product String");
  1608. OUTSTRING(hOutputWindow, "==============");
  1609. OUTWSTRING(hOutputWindow, Results -> List);
  1610. break;
  1611. case HIDD_GET_MANUFACTURER_STRING:
  1612. OUTSTRING(hOutputWindow, "Manufacturer String");
  1613. OUTSTRING(hOutputWindow, "===================");
  1614. OUTWSTRING(hOutputWindow, Results -> List);
  1615. break;
  1616. case HIDD_GET_INDEXED_STRING:
  1617. wsprintf(szTempBuffer, "Indexed String #%u:", Results -> Index);
  1618. OUTSTRING(hOutputWindow, szTempBuffer);
  1619. OUTSTRING(hOutputWindow, "===================");
  1620. OUTWSTRING(hOutputWindow, Results -> List);
  1621. break;
  1622. case HIDD_GET_SERIAL_NUMBER_STRING:
  1623. OUTSTRING(hOutputWindow, "Serial Number String");
  1624. OUTSTRING(hOutputWindow, "=====================");
  1625. OUTWSTRING(hOutputWindow, Results -> List);
  1626. break;
  1627. case HIDP_GET_BUTTON_CAPS:
  1628. case HIDP_GET_SPECIFIC_BUTTON_CAPS:
  1629. ButtonCaps = (PHIDP_BUTTON_CAPS) (Results -> List);
  1630. for (Index = 0; Index < Results -> ListLength; Index++, ButtonCaps++)
  1631. {
  1632. OUTSTRING(hOutputWindow, "==========================");
  1633. vDisplayButtonAttributes(ButtonCaps, hOutputWindow);
  1634. }
  1635. break;
  1636. /*
  1637. // HidP_GetButtons and HidP_GetUsages are in reality the same call.
  1638. // HidP_GetButtons actually a macro which gets redefined into
  1639. // HidP_GetUsages with the same parameter order. That is why their
  1640. // display mechanisms are identical. This call returns in the
  1641. // List parameter a list of Usages. The display mechanism converts
  1642. // these usages into a string of numbers.
  1643. */
  1644. case HIDP_GET_BUTTONS:
  1645. case HIDP_GET_USAGES:
  1646. OUTSTRING(hOutputWindow, "Usages Returned");
  1647. OUTSTRING(hOutputWindow, "===============");
  1648. UsageList = (PUSAGE) Results -> List;
  1649. for (Index = 0; Index < Results -> ListLength; Index++)
  1650. {
  1651. vCreateUsageString(UsageList + Index, szTempBuffer);
  1652. OUTSTRING(hOutputWindow, szTempBuffer);
  1653. }
  1654. break;
  1655. /*
  1656. // Like get their siblings, the normal get functions, these routines are
  1657. // currently one in the same. The difference between these routines
  1658. // and their siblings is the return of a usage page along with each
  1659. // usage. Therefore, both values must be displayed at the same time.
  1660. */
  1661. case HIDP_GET_BUTTONS_EX:
  1662. case HIDP_GET_USAGES_EX:
  1663. OUTSTRING(hOutputWindow, "Usages Returned");
  1664. OUTSTRING(hOutputWindow, "===============");
  1665. UsageAndPageList = (PUSAGE_AND_PAGE) Results -> List;
  1666. for (Index = 0; Index < Results -> ListLength; Index++)
  1667. {
  1668. vCreateUsageAndPageString(UsageAndPageList + Index,
  1669. szTempBuffer);
  1670. OUTSTRING(hOutputWindow, szTempBuffer);
  1671. }
  1672. break;
  1673. case HIDP_GET_CAPS:
  1674. vDisplayDeviceCaps((PHIDP_CAPS) Results -> List, hOutputWindow);
  1675. break;
  1676. case HIDP_GET_DATA:
  1677. OUTSTRING(hOutputWindow, "Data Indices");
  1678. OUTSTRING(hOutputWindow, "============");
  1679. DataList = (PHIDP_DATA) Results -> List;
  1680. for (Index = 0; Index < Results -> ListLength; Index++)
  1681. {
  1682. vDisplayDataAttributes(DataList+Index,
  1683. FALSE,
  1684. hOutputWindow);
  1685. }
  1686. break;
  1687. case HIDP_GET_EXTENDED_ATTRIBUTES:
  1688. OUTSTRING(hOutputWindow, "Extended Attributes");
  1689. OUTSTRING(hOutputWindow, "===================");
  1690. ExtAttrib = (PHIDP_EXTENDED_ATTRIBUTES) Results -> List;
  1691. DisplayExtendedAttributes(hOutputWindow,
  1692. ExtAttrib -> GlobalUnknowns,
  1693. ExtAttrib -> NumGlobalUnknowns);
  1694. break;
  1695. case HIDP_GET_LINK_COLL_NODES:
  1696. OUTSTRING(hOutputWindow, "Link Collection Nodes");
  1697. OUTSTRING(hOutputWindow, "=====================");
  1698. NodeList = (PHIDP_LINK_COLLECTION_NODE) Results -> List;
  1699. for (Index = 0; Index < Results -> ListLength; Index++)
  1700. {
  1701. OUTSTRING(hOutputWindow, "===========================");
  1702. vDisplayLinkCollectionNode(NodeList+Index,
  1703. Index,
  1704. hOutputWindow);
  1705. }
  1706. break;
  1707. case HIDP_GET_SCALED_USAGE_VALUE:
  1708. wsprintf(szTempBuffer, "Scaled usage value: %ld", Results -> ScaledValue);
  1709. OUTSTRING(hOutputWindow, szTempBuffer);
  1710. break;
  1711. case HIDP_GET_USAGE_VALUE:
  1712. wsprintf(szTempBuffer, "Usage value: %lu", Results -> Value);
  1713. OUTSTRING(hOutputWindow, szTempBuffer);
  1714. break;
  1715. /*
  1716. // To display a usage value array, we must extract each of the values
  1717. // in the array based on the ReportSize. The ReportSize is not necessarily
  1718. // an even byte size so we must use the special extraction routine to get
  1719. // each of the values in the array.
  1720. */
  1721. case HIDP_GET_USAGE_VALUE_ARRAY:
  1722. UsageValueArray = (PCHAR) Results -> List;
  1723. for (Index = 0; Index < Results -> ReportCount; Index++)
  1724. {
  1725. vCreateUsageValueStringFromArray(UsageValueArray,
  1726. Results -> BitSize,
  1727. (USHORT) Index,
  1728. szTempBuffer);
  1729. OUTSTRING(hOutputWindow, szTempBuffer);
  1730. }
  1731. break;
  1732. case HIDP_GET_VALUE_CAPS:
  1733. case HIDP_GET_SPECIFIC_VALUE_CAPS:
  1734. ValueCaps = (PHIDP_VALUE_CAPS) Results -> List;
  1735. for (Index = 0; Index < (INT) Results -> ListLength; Index++)
  1736. {
  1737. OUTSTRING(hOutputWindow, "==========================");
  1738. vDisplayValueAttributes(ValueCaps + Index,
  1739. hOutputWindow);
  1740. }
  1741. break;
  1742. case HIDP_MAX_DATA_LIST_LENGTH:
  1743. wsprintf(szTempBuffer, "MaxDataListLength: %u", Results -> Value);
  1744. OUTSTRING(hOutputWindow, szTempBuffer);
  1745. break;
  1746. case HIDP_MAX_USAGE_LIST_LENGTH:
  1747. wsprintf(szTempBuffer, "MaxUsageListLength: %u", Results -> Value);
  1748. OUTSTRING(hOutputWindow, szTempBuffer);
  1749. break;
  1750. /*
  1751. // For HidP_UsageListDifference, we need to display both of the make and
  1752. // break lists generated by the function. Therefore, we end up creating
  1753. // two different usage list strings.
  1754. */
  1755. case HIDP_USAGE_LIST_DIFFERENCE:
  1756. OUTSTRING(hOutputWindow, "Make List");
  1757. OUTSTRING(hOutputWindow, "=========");
  1758. UsageList = (PUSAGE) Results -> MakeList;
  1759. Index = 0;
  1760. while (0 != *(UsageList+Index) && Index < Results -> ListLength)
  1761. {
  1762. vCreateUsageString(UsageList + Index,
  1763. szTempBuffer);
  1764. OUTSTRING(hOutputWindow, szTempBuffer);
  1765. Index++;
  1766. }
  1767. OUTSTRING(hOutputWindow, "Break List");
  1768. OUTSTRING(hOutputWindow, "==========");
  1769. UsageList = (PUSAGE) Results -> BreakList;
  1770. Index = 0;
  1771. while (0 != *(UsageList+Index) && Index < Results -> ListLength)
  1772. {
  1773. vCreateUsageString(UsageList + Index,
  1774. szTempBuffer);
  1775. OUTSTRING(hOutputWindow, szTempBuffer);
  1776. Index++;
  1777. }
  1778. break;
  1779. /*
  1780. // These functions simply update the buffer that is specified as the
  1781. // input parameter. We must select the correct display buffer mechanism
  1782. // based on the ReportType for the call and then update the given report
  1783. // in that display mechanism.
  1784. */
  1785. case HID_READ_REPORT:
  1786. case HIDD_GET_FEATURE:
  1787. case HIDP_INITIALIZE_REPORT_FOR_ID:
  1788. case HIDP_SET_BUTTONS:
  1789. case HIDP_SET_DATA:
  1790. case HIDP_SET_SCALED_USAGE_VALUE:
  1791. case HIDP_SET_USAGES:
  1792. case HIDP_SET_USAGE_VALUE:
  1793. case HIDP_SET_USAGE_VALUE_ARRAY:
  1794. case HIDP_UNSET_BUTTONS:
  1795. case HIDP_UNSET_USAGES:
  1796. SELECT_ON_REPORT_TYPE(Results -> ReportType,
  1797. pInputDisplay,
  1798. pOutputDisplay,
  1799. pFeatureDisplay,
  1800. pDisplay);
  1801. BufferDisplay_UpdateBuffer(pDisplay,
  1802. Results -> ReportBuffer);
  1803. break;
  1804. }
  1805. return;
  1806. }
  1807. VOID
  1808. vExecuteAndDisplayOutput(
  1809. HWND hOutputWindow,
  1810. PHID_DEVICE pDevice,
  1811. INT iFuncCall,
  1812. PECDISPLAY_PARAMS params
  1813. )
  1814. /*++
  1815. RoutineDescription:
  1816. This routine is a long function that is responsible for retrieving all the
  1817. paramter for a given function call, setting up the CallParameters structure
  1818. and then call the execute routine to get the necessary results and status of
  1819. the operation. It is then responsible for displaying the appropriate status
  1820. and results if the function did not fail
  1821. This routine is a fairly long, complex routine to do a simple task. It may
  1822. be broken down in future versions to simplify some of the complexity.
  1823. --*/
  1824. {
  1825. EXTCALL_PARAMS CallParameters;
  1826. EXTCALL_STATUS CallStatus;
  1827. DLGBOX_STATUS iDlgStatus;
  1828. BOOL ExecuteStatus;
  1829. PBUFFER_DISPLAY pBufferDisplay;
  1830. PCHAR pCopyBuffer;
  1831. PCHAR endp;
  1832. UINT DlgBoxNumber;
  1833. BOOL List2Alloc;
  1834. BOOL MakeListAlloc;
  1835. BOOL BreakListAlloc;
  1836. HID_DEVICE readDevice, writeDevice;
  1837. BOOL status;
  1838. /*
  1839. // ExecuteAndDisplayOutput needless to say, consists of two parts:
  1840. // Executing and Displaying output. The first section involves the
  1841. // execution phase where all parameters are filled in if necessary
  1842. // and ECDisp_Execute is called
  1843. */
  1844. if (IS_NOT_IMPLEMENTED(iFuncCall))
  1845. {
  1846. OUTSTRING(hOutputWindow, "Function not yet implemented");
  1847. return;
  1848. }
  1849. /*
  1850. // Check first to see if this is a HID_CLEAR_REPORT command. If it is
  1851. // all we need to do is get the report buffer that is checked and
  1852. // then call the clear buffer command
  1853. */
  1854. if (HID_CLEAR_REPORT == iFuncCall)
  1855. {
  1856. SELECT_ON_REPORT_TYPE(params -> ReportType,
  1857. pInputDisplay,
  1858. pOutputDisplay,
  1859. pFeatureDisplay,
  1860. pBufferDisplay);
  1861. BufferDisplay_ClearBuffer(pBufferDisplay);
  1862. return;
  1863. }
  1864. /*
  1865. // Need to perform the following steps in order to get the parameters for
  1866. // our call and then execute the call:
  1867. // 1) Get any additional parameters not supplied by the above dialog
  1868. // procedure. This occurs for such functions as:
  1869. // HIDP_SET_BUTTONS
  1870. // HIDP_SET_DATA
  1871. // HIDP_SET_USAGES
  1872. // HIDP_SET_USAGE_VALUE
  1873. // HIDP_SET_SCALED_USAGE_VALUE
  1874. // HIDP_SET_USAGE_VALUE_ARRAY
  1875. // HIDP_UNSET_BUTTONS
  1876. // HIDP_UNSET_USAGES
  1877. // For these functions, a separate dialog box must be called
  1878. //
  1879. // 2) Fill in the common parameters from the passed in params struct
  1880. //
  1881. */
  1882. /*
  1883. // Step 1: We're storing the values retrieved by these additional dialog
  1884. // box in the params struct since we may actually be passed in
  1885. // these values in the future instead of getting them here. Hence,
  1886. // we won't break any of the code that follows the switch statement
  1887. */
  1888. switch (iFuncCall)
  1889. {
  1890. case HIDP_SET_BUTTONS:
  1891. case HIDP_SET_USAGES:
  1892. case HIDP_UNSET_BUTTONS:
  1893. case HIDP_UNSET_USAGES:
  1894. switch (iFuncCall)
  1895. {
  1896. case HIDP_SET_BUTTONS:
  1897. DlgBoxNumber = IDD_SET_BUTTONS;
  1898. break;
  1899. case HIDP_SET_USAGES:
  1900. DlgBoxNumber = IDD_SET_USAGES;
  1901. break;
  1902. case HIDP_UNSET_BUTTONS:
  1903. DlgBoxNumber = IDD_UNSET_BUTTONS;
  1904. break;
  1905. case HIDP_UNSET_USAGES:
  1906. DlgBoxNumber = IDD_UNSET_USAGES;
  1907. break;
  1908. }
  1909. iDlgStatus = (DLGBOX_STATUS) DialogBoxParam(NULL,
  1910. MAKEINTRESOURCE(DlgBoxNumber),
  1911. GetParent(hOutputWindow),
  1912. bSetUsagesDlgProc,
  1913. (LPARAM) params);
  1914. /*
  1915. // If the above call returns 1, then the dialog box routine
  1916. // successfully acquired a string from the user and put the
  1917. // pointer to it in params -> szListString.
  1918. // Now we need to convert the string to a usage list
  1919. */
  1920. if (DLGBOX_OK != iDlgStatus)
  1921. return;
  1922. ExecuteStatus = ConvertStringToUsageList(params -> szListString,
  1923. &params -> UsageList,
  1924. &params -> ListLength);
  1925. free(params -> szListString);
  1926. if (!ExecuteStatus)
  1927. {
  1928. ECDISP_ERROR(GetParent(hOutputWindow),
  1929. "Error getting usage list");
  1930. return;
  1931. }
  1932. break;
  1933. case HIDP_GET_EXTENDED_ATTRIBUTES:
  1934. iDlgStatus = (DLGBOX_STATUS) DialogBoxParam(NULL,
  1935. MAKEINTRESOURCE(IDD_GET_EXT_ATTRIB),
  1936. GetParent(hOutputWindow),
  1937. bGetIndexedDlgProc,
  1938. (LPARAM) params);
  1939. if (DLGBOX_OK != iDlgStatus)
  1940. return;
  1941. params -> Index = strtoul(params -> szListString, &endp, 10);
  1942. if ('\0' != *endp)
  1943. {
  1944. ECDISP_ERROR(GetParent(hOutputWindow),
  1945. "Invalid index value");
  1946. free(params -> szListString);
  1947. free(params -> szListString2);
  1948. return;
  1949. }
  1950. free(params -> szListString);
  1951. params -> ListLength = strtoul(params -> szListString2, &endp, 10);
  1952. if ('\0' != *endp)
  1953. {
  1954. ECDISP_ERROR(GetParent(hOutputWindow),
  1955. "Invalid buffer size");
  1956. free(params -> szListString2);
  1957. return;
  1958. }
  1959. free(params -> szListString2);
  1960. break;
  1961. case HIDD_GET_INDEXED_STRING:
  1962. iDlgStatus = (DLGBOX_STATUS) DialogBoxParam(NULL,
  1963. MAKEINTRESOURCE(IDD_GET_INDEX_STRING),
  1964. GetParent(hOutputWindow),
  1965. bGetIndexedDlgProc,
  1966. (LPARAM) params);
  1967. if (DLGBOX_OK != iDlgStatus)
  1968. return;
  1969. params -> Index = strtoul(params -> szListString, &endp, 10);
  1970. if ('\0' != *endp)
  1971. {
  1972. ECDISP_ERROR(GetParent(hOutputWindow),
  1973. "Invalid index value");
  1974. free(params -> szListString);
  1975. free(params -> szListString2);
  1976. return;
  1977. }
  1978. free(params -> szListString);
  1979. params -> ListLength = strtoul(params -> szListString2, &endp, 10);
  1980. if ('\0' != *endp)
  1981. {
  1982. ECDISP_ERROR(GetParent(hOutputWindow),
  1983. "Invalid buffer size");
  1984. free(params -> szListString2);
  1985. return;
  1986. }
  1987. free(params -> szListString2);
  1988. break;
  1989. case HIDD_GET_MS_GENRE_DESCRIPTOR:
  1990. case HIDD_GET_PHYSICAL_DESCRIPTOR:
  1991. case HIDD_GET_MANUFACTURER_STRING:
  1992. case HIDD_GET_PRODUCT_STRING:
  1993. case HIDD_GET_SERIAL_NUMBER_STRING:
  1994. iDlgStatus = (DLGBOX_STATUS) DialogBoxParam(NULL,
  1995. MAKEINTRESOURCE(IDD_SET_BUFFER_LENGTH),
  1996. GetParent(hOutputWindow),
  1997. bSetBufLenDlgProc,
  1998. (LPARAM) params);
  1999. if (DLGBOX_OK != iDlgStatus)
  2000. return;
  2001. params -> ListLength = strtoul(params -> szListString, &endp, 10);
  2002. if ('\0' != *endp)
  2003. {
  2004. free(params -> szListString);
  2005. ECDISP_ERROR(GetParent(hOutputWindow),
  2006. "Invalid buffer length");
  2007. return;
  2008. }
  2009. free(params -> szListString);
  2010. break;
  2011. case HIDD_SET_NUM_INPUT_BUFFERS:
  2012. iDlgStatus = (DLGBOX_STATUS) DialogBoxParam(NULL,
  2013. MAKEINTRESOURCE(IDD_SET_INPUT_BUFFERS),
  2014. GetParent(hOutputWindow),
  2015. bSetInputBuffDlgProc,
  2016. (LPARAM) params);
  2017. /*
  2018. // If the above call returns 1, then the dialog box routine
  2019. // successfully acquired a string from the user and put the
  2020. // pointer to it in params -> szListString.
  2021. // Now we need to convert the string to a usage list
  2022. */
  2023. if (DLGBOX_OK != iDlgStatus)
  2024. return;
  2025. params -> Value = strtoul(params -> szListString, &endp, 10);
  2026. if ('\0' != *endp)
  2027. {
  2028. ECDISP_ERROR(GetParent(hOutputWindow),
  2029. "Invalid value specified");
  2030. free(params -> szListString);
  2031. return;
  2032. }
  2033. free(params -> szListString);
  2034. break;
  2035. case HIDP_SET_DATA:
  2036. iDlgStatus = (DLGBOX_STATUS) DialogBoxParam(NULL,
  2037. MAKEINTRESOURCE(IDD_SET_DATA),
  2038. GetParent(hOutputWindow),
  2039. bSetDataDlgProc,
  2040. (LPARAM) params);
  2041. if (DLGBOX_OK != iDlgStatus)
  2042. return;
  2043. break;
  2044. case HIDP_SET_SCALED_USAGE_VALUE:
  2045. iDlgStatus = (DLGBOX_STATUS) DialogBoxParam(NULL,
  2046. MAKEINTRESOURCE(IDD_SET_SCALED_VALUE),
  2047. GetParent(hOutputWindow),
  2048. bSetValueDlgProc,
  2049. (LPARAM) params);
  2050. /*
  2051. // If the above call returns DLGBOX_OK, then the dialog box routine
  2052. // successfully acquired a string from the user and put the
  2053. // pointer to it in params -> szListString.
  2054. // Now we need to convert the string to a usage list
  2055. */
  2056. if (DLGBOX_OK != iDlgStatus)
  2057. return;
  2058. params -> ScaledValue = strtol(params -> szListString, &endp, 10);
  2059. if ('\0' != *endp)
  2060. {
  2061. ECDISP_ERROR(GetParent(hOutputWindow),
  2062. "Invalid scaled usage value");
  2063. free(params -> szListString);
  2064. return;
  2065. }
  2066. free(params -> szListString);
  2067. break;
  2068. case HIDP_SET_USAGE_VALUE:
  2069. iDlgStatus = (DLGBOX_STATUS) DialogBoxParam(NULL,
  2070. MAKEINTRESOURCE(IDD_SET_USAGE_VALUE),
  2071. GetParent(hOutputWindow),
  2072. bSetValueDlgProc,
  2073. (LPARAM) params);
  2074. /*
  2075. // If the above call returns 1, then the dialog box routine
  2076. // successfully acquired a string from the user and put the
  2077. // pointer to it in params -> szListString.
  2078. // Now we need to convert the string to a usage list
  2079. */
  2080. if (DLGBOX_OK != iDlgStatus)
  2081. return;
  2082. params -> Value = strtoul(params -> szListString, &endp, 10);
  2083. if ('\0' != *endp)
  2084. {
  2085. ECDISP_ERROR(GetParent(hOutputWindow),
  2086. "Invalid usage value");
  2087. free(params -> szListString);
  2088. return;
  2089. }
  2090. free(params -> szListString);
  2091. break;
  2092. case HIDP_SET_USAGE_VALUE_ARRAY:
  2093. iDlgStatus = (DLGBOX_STATUS) DialogBoxParam(NULL,
  2094. MAKEINTRESOURCE(IDD_SET_USAGE_VALUE_ARRAY),
  2095. GetParent(hOutputWindow),
  2096. bSetValueDlgProc,
  2097. (LPARAM) params);
  2098. /*
  2099. // If the above call returns 1, then the dialog box routine
  2100. // successfully acquired a string from the user and put the
  2101. // pointer to it in params -> szListString.
  2102. // Now we need to convert the string to a usage list
  2103. */
  2104. if (DLGBOX_OK != iDlgStatus)
  2105. return;
  2106. ExecuteStatus = ConvertStringToUlongList(params -> szListString,
  2107. &params -> pValueList,
  2108. &params -> ListLength);
  2109. free(params -> szListString);
  2110. if (!ExecuteStatus)
  2111. {
  2112. ECDISP_ERROR(GetParent(hOutputWindow),
  2113. "Error getting list of values");
  2114. return;
  2115. }
  2116. break;
  2117. case HIDP_USAGE_LIST_DIFFERENCE:
  2118. iDlgStatus = (DLGBOX_STATUS) DialogBoxParam(NULL,
  2119. MAKEINTRESOURCE(IDD_USAGE_LIST_DIFFERENCE),
  2120. GetParent(hOutputWindow),
  2121. bGetUsageDiffDlgProc,
  2122. (LPARAM) params);
  2123. if (DLGBOX_OK != iDlgStatus)
  2124. {
  2125. return;
  2126. }
  2127. ExecuteStatus = Strings_StringToUnsignedList(params -> szListString,
  2128. sizeof(USAGE),
  2129. 16,
  2130. (PCHAR *) &params -> UsageList,
  2131. &params -> ListLength);
  2132. if (!ExecuteStatus)
  2133. {
  2134. ECDISP_ERROR(GetParent(hOutputWindow),
  2135. "Error getting list of values");
  2136. free(params -> szListString);
  2137. free(params -> szListString2);
  2138. return;
  2139. }
  2140. ExecuteStatus = Strings_StringToUnsignedList(params -> szListString2,
  2141. sizeof(USAGE),
  2142. 16,
  2143. (PCHAR *) &params -> UsageList2,
  2144. &params -> ListLength2);
  2145. if (!ExecuteStatus)
  2146. {
  2147. ECDISP_ERROR(GetParent(hOutputWindow),
  2148. "Error getting list of values");
  2149. free(params -> szListString);
  2150. free(params -> szListString2);
  2151. free(params -> UsageList);
  2152. return;
  2153. }
  2154. free(params -> szListString);
  2155. free(params -> szListString2);
  2156. break;
  2157. }
  2158. /*
  2159. // Step 2: Extract the common parameters. It's probably easier
  2160. // to simply fill in the spots in call parameters whether they are used
  2161. // or not instead of filling in only those that are relevant to a given
  2162. // function. The details of some function relevant parameters are
  2163. // handled after this.
  2164. */
  2165. CallParameters.DeviceHandle = pDevice -> HidDevice;
  2166. CallParameters.ReportType = params -> ReportType;
  2167. CallParameters.Ppd = pDevice -> Ppd;
  2168. CallParameters.UsagePage = params -> UsagePage;
  2169. CallParameters.Usage = params -> Usage;
  2170. CallParameters.LinkCollection = params -> LinkCollection;
  2171. CallParameters.ReportID = params -> ReportID;
  2172. CallParameters.List = NULL;
  2173. CallParameters.List2 = NULL;
  2174. CallParameters.MakeList = NULL;
  2175. CallParameters.BreakList = NULL;
  2176. CallParameters.ListLength = 0;
  2177. List2Alloc = FALSE;
  2178. MakeListAlloc = FALSE;
  2179. BreakListAlloc = FALSE;
  2180. /*
  2181. // Step 3: Now we'll deal with those functions that require a report buffer of some kind
  2182. // which means we'll copy the current buffer of the selected reported
  2183. // type
  2184. */
  2185. switch (iFuncCall)
  2186. {
  2187. case HID_READ_REPORT:
  2188. memcpy(&readDevice, pDevice, sizeof(HID_DEVICE));
  2189. status = OpenHidDevice(pDevice -> DevicePath,
  2190. TRUE,
  2191. FALSE,
  2192. FALSE,
  2193. FALSE,
  2194. FALSE,
  2195. &readDevice);
  2196. if (!status)
  2197. {
  2198. OUTSTRING(hOutputWindow, "Unable to open device for reading");
  2199. }
  2200. CallParameters.DeviceHandle = readDevice.HidDevice;
  2201. CallParameters.ReportType = HidP_Input;
  2202. CallParameters.ReportBuffer = readDevice.InputReportBuffer;
  2203. CallParameters.ReportLength = readDevice.Caps.InputReportByteLength;
  2204. break;
  2205. case HID_WRITE_REPORT:
  2206. memcpy(&writeDevice, pDevice, sizeof(HID_DEVICE));
  2207. status = OpenHidDevice(pDevice -> DevicePath,
  2208. TRUE,
  2209. FALSE,
  2210. FALSE,
  2211. FALSE,
  2212. FALSE,
  2213. &writeDevice);
  2214. if (!status)
  2215. {
  2216. OUTSTRING(hOutputWindow, "Unable to open device for writing");
  2217. }
  2218. BufferDisplay_CopyCurrentBuffer(pOutputDisplay,
  2219. writeDevice.OutputReportBuffer);
  2220. CallParameters.DeviceHandle = writeDevice.HidDevice;
  2221. CallParameters.ReportType = HidP_Output;
  2222. CallParameters.ReportBuffer = writeDevice.OutputReportBuffer;
  2223. CallParameters.ReportLength = writeDevice.Caps.OutputReportByteLength;
  2224. break;
  2225. case HIDD_GET_INPUT_REPORT:
  2226. CallParameters.ReportType = HidP_Input;
  2227. CallParameters.ReportBuffer = pDevice -> InputReportBuffer;
  2228. CallParameters.ReportLength = pDevice -> Caps.InputReportByteLength;
  2229. break;
  2230. case HIDD_GET_FEATURE:
  2231. CallParameters.ReportType = HidP_Feature;
  2232. CallParameters.ReportBuffer = pDevice -> FeatureReportBuffer;
  2233. CallParameters.ReportLength = pDevice -> Caps.FeatureReportByteLength;
  2234. break;
  2235. case HIDD_GET_INDEXED_STRING:
  2236. case HIDP_GET_EXTENDED_ATTRIBUTES:
  2237. CallParameters.Index = params -> Index;
  2238. CallParameters.ListLength = params -> ListLength;
  2239. break;
  2240. case HIDD_SET_OUTPUT_REPORT:
  2241. CallParameters.ReportType = HidP_Output;
  2242. BufferDisplay_CopyCurrentBuffer(pOutputDisplay,
  2243. pDevice -> OutputReportBuffer);
  2244. CallParameters.ReportLength = BufferDisplay_GetBufferSize(pOutputDisplay);
  2245. CallParameters.ReportBuffer = pDevice -> OutputReportBuffer;
  2246. break;
  2247. case HIDD_SET_FEATURE:
  2248. CallParameters.ReportType = HidP_Feature;
  2249. BufferDisplay_CopyCurrentBuffer(pFeatureDisplay,
  2250. pDevice -> FeatureReportBuffer);
  2251. CallParameters.ReportLength = BufferDisplay_GetBufferSize(pFeatureDisplay);
  2252. CallParameters.ReportBuffer = pDevice -> FeatureReportBuffer;
  2253. break;
  2254. case HIDP_GET_BUTTONS:
  2255. case HIDP_GET_BUTTONS_EX:
  2256. case HIDP_GET_DATA:
  2257. case HIDP_GET_SCALED_USAGE_VALUE:
  2258. case HIDP_GET_USAGES:
  2259. case HIDP_GET_USAGES_EX:
  2260. case HIDP_GET_USAGE_VALUE:
  2261. case HIDP_GET_USAGE_VALUE_ARRAY:
  2262. case HIDP_INITIALIZE_REPORT_FOR_ID:
  2263. case HIDP_SET_BUTTONS:
  2264. case HIDP_SET_DATA:
  2265. case HIDP_SET_SCALED_USAGE_VALUE:
  2266. case HIDP_SET_USAGES:
  2267. case HIDP_SET_USAGE_VALUE:
  2268. case HIDP_SET_USAGE_VALUE_ARRAY:
  2269. case HIDP_UNSET_BUTTONS:
  2270. case HIDP_UNSET_USAGES:
  2271. switch (CallParameters.ReportType)
  2272. {
  2273. case HidP_Input:
  2274. pBufferDisplay = pInputDisplay;
  2275. pCopyBuffer = pDevice -> InputReportBuffer;
  2276. break;
  2277. case HidP_Output:
  2278. pBufferDisplay = pOutputDisplay;
  2279. pCopyBuffer = pDevice -> OutputReportBuffer;
  2280. break;
  2281. case HidP_Feature:
  2282. pBufferDisplay = pFeatureDisplay;
  2283. pCopyBuffer = pDevice -> FeatureReportBuffer;
  2284. break;
  2285. }
  2286. BufferDisplay_CopyCurrentBuffer(pBufferDisplay,
  2287. pCopyBuffer);
  2288. CallParameters.ReportLength = BufferDisplay_GetBufferSize(pBufferDisplay);
  2289. CallParameters.ReportBuffer = pCopyBuffer;
  2290. break;
  2291. default:
  2292. CallParameters.ReportLength = 0;
  2293. CallParameters.ReportBuffer = NULL;
  2294. }
  2295. /*
  2296. // Now, we need to deal with those functions which have a List that is
  2297. // used for either retrieving or gathering data. There are two different
  2298. // cases. The first involves the user inputting a buffer and the system
  2299. // performing some action on the buffer, such as SetButtons. We'll also
  2300. // the other functions that require one of the union fields to be set.
  2301. //
  2302. */
  2303. /*
  2304. // The second case is where data is retrieved for the device. In this case,
  2305. // all we do is specify either the number of elements need for the buffer,
  2306. // the execute routine will worry about allocating the correct amount of
  2307. // space for those elements. Remember, however, that if the Execute routine
  2308. // allocates space, we need to free it up.
  2309. */
  2310. /*
  2311. // Then there's the third case UsageListDifference which truly changes
  2312. // everything. We've got to determine the size of the resulting lists
  2313. // is the MaxSize of the other two lists. Plus, we need to insure that
  2314. // our buffers are 00 terminated if they are less than the max size, ie
  2315. // there not the same size as the larger buffer. This may require
  2316. // reallocation of the block.
  2317. */
  2318. switch (iFuncCall)
  2319. {
  2320. /*
  2321. // First Case functions
  2322. */
  2323. case HIDP_SET_DATA:
  2324. CallParameters.List = (PVOID) params -> pDataList;
  2325. CallParameters.ListLength = params -> ListLength;
  2326. break;
  2327. case HIDP_SET_BUTTONS:
  2328. case HIDP_UNSET_BUTTONS:
  2329. case HIDP_SET_USAGES:
  2330. case HIDP_UNSET_USAGES:
  2331. CallParameters.List = (PVOID) params -> UsageList;
  2332. CallParameters.ListLength = params -> ListLength;
  2333. break;
  2334. case HIDP_SET_USAGE_VALUE_ARRAY:
  2335. CallParameters.List = (PVOID) params -> pValueList;
  2336. CallParameters.ListLength = params -> ListLength;
  2337. break;
  2338. /*
  2339. // Second Case functions
  2340. */
  2341. case HIDP_GET_BUTTON_CAPS:
  2342. case HIDP_GET_SPECIFIC_BUTTON_CAPS:
  2343. SELECT_ON_REPORT_TYPE(CallParameters.ReportType,
  2344. pDevice -> Caps.NumberInputButtonCaps,
  2345. pDevice -> Caps.NumberOutputButtonCaps,
  2346. pDevice -> Caps.NumberFeatureButtonCaps,
  2347. CallParameters.ListLength);
  2348. break;
  2349. case HIDP_GET_LINK_COLL_NODES:
  2350. CallParameters.ListLength = pDevice -> Caps.NumberLinkCollectionNodes;
  2351. break;
  2352. case HIDD_GET_MS_GENRE_DESCRIPTOR:
  2353. case HIDD_GET_PHYSICAL_DESCRIPTOR:
  2354. case HIDD_GET_MANUFACTURER_STRING:
  2355. case HIDD_GET_PRODUCT_STRING:
  2356. case HIDD_GET_SERIAL_NUMBER_STRING:
  2357. CallParameters.ListLength = params -> ListLength;
  2358. break;
  2359. case HIDP_GET_VALUE_CAPS:
  2360. case HIDP_GET_SPECIFIC_VALUE_CAPS:
  2361. SELECT_ON_REPORT_TYPE(CallParameters.ReportType,
  2362. pDevice -> Caps.NumberInputValueCaps,
  2363. pDevice -> Caps.NumberOutputValueCaps,
  2364. pDevice -> Caps.NumberFeatureValueCaps,
  2365. CallParameters.ListLength);
  2366. case HIDD_GET_FREE_PREPARSED_DATA:
  2367. CallParameters.ppPd = &CallParameters.Ppd;
  2368. break;
  2369. case HIDP_SET_SCALED_USAGE_VALUE:
  2370. CallParameters.ScaledValue = params -> ScaledValue;
  2371. break;
  2372. case HIDP_SET_USAGE_VALUE:
  2373. case HIDD_SET_NUM_INPUT_BUFFERS:
  2374. CallParameters.Value = params -> Value;
  2375. break;
  2376. /*
  2377. // That third case
  2378. */
  2379. case HIDP_USAGE_LIST_DIFFERENCE:
  2380. CallParameters.ListLength = max(params -> ListLength,
  2381. params -> ListLength2);
  2382. CallParameters.List = params -> UsageList;
  2383. CallParameters.List2 = params -> UsageList2;
  2384. if (CallParameters.ListLength > params -> ListLength)
  2385. {
  2386. CallParameters.List = (PUSAGE) realloc(params -> UsageList,
  2387. (params -> ListLength+1) * sizeof(USAGE));
  2388. if (NULL == CallParameters.List)
  2389. {
  2390. ECDISP_ERROR(GetParent(hOutputWindow),
  2391. "Error allocating memory");
  2392. free(params -> UsageList);
  2393. free(params -> UsageList2);
  2394. return;
  2395. }
  2396. *(((PUSAGE) CallParameters.List) + CallParameters.ListLength - 1) = 0;
  2397. }
  2398. else if (CallParameters.ListLength > params -> ListLength2)
  2399. {
  2400. CallParameters.List2 = (PUSAGE) realloc(params -> UsageList2,
  2401. (params -> ListLength+1) * sizeof(USAGE));
  2402. if (NULL == CallParameters.List2)
  2403. {
  2404. ECDISP_ERROR(GetParent(hOutputWindow),
  2405. "Error allocating memory");
  2406. free(params -> UsageList);
  2407. free(params -> UsageList2);
  2408. return;
  2409. }
  2410. *(((PUSAGE) CallParameters.List2) + CallParameters.ListLength - 1) = 0;
  2411. }
  2412. List2Alloc = TRUE;
  2413. MakeListAlloc = TRUE;
  2414. BreakListAlloc = TRUE;
  2415. break;
  2416. }
  2417. /*
  2418. // Params are now set up and ready to go, let's execute
  2419. */
  2420. if (HIDD_GET_FREE_PREPARSED_DATA == iFuncCall)
  2421. {
  2422. ExecuteStatus = ECDisp_Execute(HIDD_GET_PREPARSED_DATA,
  2423. &CallParameters,
  2424. &CallStatus);
  2425. if (!ExecuteStatus)
  2426. {
  2427. OUTSTRING(hOutputWindow, "Unknown error: Couldn't execute function");
  2428. return;
  2429. }
  2430. DISPLAY_HIDD_STATUS(hOutputWindow,
  2431. "HidD_GetPreparsedData",
  2432. CallStatus);
  2433. if (!CallStatus.IsHidError)
  2434. {
  2435. ExecuteStatus = ECDisp_Execute(HIDD_FREE_PREPARSED_DATA,
  2436. &CallParameters,
  2437. &CallStatus);
  2438. OUTSTRING(hOutputWindow, "=======================");
  2439. if (!ExecuteStatus)
  2440. {
  2441. OUTSTRING(hOutputWindow, "Unknown error: Couldn't execute function");
  2442. return;
  2443. }
  2444. DISPLAY_HIDD_STATUS(hOutputWindow,
  2445. "HidD_FreePreparsedData",
  2446. CallStatus);
  2447. }
  2448. }
  2449. else
  2450. {
  2451. if ((HID_READ_REPORT == iFuncCall || HID_WRITE_REPORT == iFuncCall) &&
  2452. (!status))
  2453. {
  2454. //
  2455. // Indicate there was an error so we don't display anything further
  2456. //
  2457. CallStatus.IsHidError = TRUE;
  2458. }
  2459. else
  2460. {
  2461. ExecuteStatus = ECDisp_Execute(iFuncCall,
  2462. &CallParameters,
  2463. &CallStatus);
  2464. if (!ExecuteStatus)
  2465. {
  2466. OUTSTRING(hOutputWindow, "Unknown error: Couldn't execute function");
  2467. return;
  2468. }
  2469. if (IS_HIDD_FUNCTION(iFuncCall) || IS_HID_FUNCTION(iFuncCall))
  2470. {
  2471. DISPLAY_HIDD_STATUS(hOutputWindow,
  2472. GET_FUNCTION_NAME(iFuncCall),
  2473. CallStatus);
  2474. }
  2475. else
  2476. {
  2477. DISPLAY_HIDP_STATUS(hOutputWindow,
  2478. GET_FUNCTION_NAME(iFuncCall),
  2479. CallStatus);
  2480. }
  2481. }
  2482. }
  2483. /*
  2484. // Display the other results only if there wasn't a HID error
  2485. */
  2486. if (!CallStatus.IsHidError || (HIDP_STATUS_NULL == CallStatus.HidErrorCode))
  2487. {
  2488. OUTSTRING(hOutputWindow, "=======================");
  2489. /*
  2490. // Now that general status information has been displayed, we need to
  2491. // display the info for the parts that are dependent on the function being
  2492. // called
  2493. */
  2494. ECDisp_DisplayOutput(hOutputWindow,
  2495. iFuncCall,
  2496. &CallParameters);
  2497. }
  2498. if (CallParameters.List != NULL)
  2499. {
  2500. free(CallParameters.List);
  2501. }
  2502. if (List2Alloc && CallParameters.List2 != NULL)
  2503. {
  2504. free(CallParameters.List2);
  2505. }
  2506. if (MakeListAlloc && CallParameters.MakeList != NULL)
  2507. {
  2508. free(CallParameters.MakeList);
  2509. }
  2510. if (BreakListAlloc && CallParameters.BreakList != NULL)
  2511. {
  2512. free(CallParameters.BreakList);
  2513. }
  2514. return;
  2515. }
  2516. VOID
  2517. BuildReportIDList(
  2518. IN PHIDP_BUTTON_CAPS phidButtonCaps,
  2519. IN USHORT nButtonCaps,
  2520. IN PHIDP_VALUE_CAPS phidValueCaps,
  2521. IN USHORT nValueCaps,
  2522. OUT PUCHAR *ppReportIDList,
  2523. OUT INT *nReportIDs
  2524. )
  2525. /*++
  2526. RoutineDescription:
  2527. This routine builds a list of report IDs that are listed in the passed in set
  2528. of ButtonCaps and ValueCaps structure. It allocates a buffer to store all
  2529. the ReportIDs, if it can. Otherwise the buffer is returned as NULL.
  2530. Currently, this routine has no purpose in the HClient program. It was written
  2531. for some purpose which never materialized but was left in because it might be
  2532. useful in the future.
  2533. --*/
  2534. {
  2535. INT nAllocatedIDs;
  2536. INT nFoundIDs;
  2537. INT nWalkCount;
  2538. USHORT usIndex;
  2539. BOOL fIDFound;
  2540. UCHAR *pucBuffer;
  2541. UCHAR *pucOldBuffer;
  2542. UCHAR *pucWalk;
  2543. UCHAR ucReportID;
  2544. PHIDP_BUTTON_CAPS pButtonWalk;
  2545. PHIDP_VALUE_CAPS pValueWalk;
  2546. /*
  2547. // Initialize the output parameters in case there is some sort of failure
  2548. */
  2549. *nReportIDs = 0;
  2550. *ppReportIDList = NULL;
  2551. if (0 == nButtonCaps && 0 == nValueCaps)
  2552. return;
  2553. /*
  2554. // Initialize the beginning array size to 2 report IDs and alloc space
  2555. // for those IDs. If we need to add more report IDs we allocate more
  2556. // space
  2557. */
  2558. nAllocatedIDs = 2;
  2559. nFoundIDs = 0;
  2560. pButtonWalk = phidButtonCaps;
  2561. pValueWalk = phidValueCaps;
  2562. pucBuffer = (UCHAR *) malloc(sizeof(UCHAR) * nAllocatedIDs);
  2563. if (NULL == pucBuffer)
  2564. return;
  2565. /*
  2566. // Beginning with the button caps and then going to the value caps do the
  2567. // following
  2568. //
  2569. // 1) Take the report ID and search the array of report IDs looking for
  2570. // an existing report ID and add to the array if not there.
  2571. //
  2572. // 2) Add the report ID to the array in sorted order that way we sort the
  2573. // array at any time.
  2574. //
  2575. // 3) Must also realloc the array if we run out of array space
  2576. */
  2577. for (usIndex = 0; usIndex < nButtonCaps; usIndex++, pButtonWalk++)
  2578. {
  2579. ucReportID = pButtonWalk -> ReportID;
  2580. pucWalk = pucBuffer;
  2581. nWalkCount = 0;
  2582. fIDFound = FALSE;
  2583. while (!fIDFound && nWalkCount < nFoundIDs)
  2584. {
  2585. if (*pucWalk == ucReportID)
  2586. {
  2587. fIDFound = TRUE;
  2588. }
  2589. else if (ucReportID > *pucWalk)
  2590. {
  2591. pucWalk++;
  2592. nWalkCount++;
  2593. }
  2594. }
  2595. if (!fIDFound)
  2596. {
  2597. if (nFoundIDs == nAllocatedIDs)
  2598. {
  2599. nAllocatedIDs *= 2;
  2600. pucOldBuffer = pucBuffer;
  2601. pucBuffer = (UCHAR *) realloc(pucBuffer, sizeof(UCHAR) * nAllocatedIDs);
  2602. if (NULL == pucBuffer)
  2603. {
  2604. free(pucOldBuffer);
  2605. return;
  2606. }
  2607. pucWalk = pucBuffer + nWalkCount;
  2608. }
  2609. /*
  2610. // At this point, pucWalk points to the smallest ReportID in the
  2611. // buffer that is greater than the ReportID we want to insert.
  2612. // We need to bump all reportIDs beginning at pucWalk up one
  2613. // spot and insert the new ReportID at pucWalk
  2614. */
  2615. memmove (pucWalk+1, pucWalk, (nFoundIDs - nWalkCount) * sizeof(UCHAR));
  2616. *pucWalk = ucReportID;
  2617. nFoundIDs++;
  2618. }
  2619. }
  2620. *ppReportIDList = pucBuffer;
  2621. *nReportIDs = nFoundIDs;
  2622. return;
  2623. }
  2624. LRESULT CALLBACK
  2625. bSetUsagesDlgProc(
  2626. HWND hDlg,
  2627. UINT message,
  2628. WPARAM wParam,
  2629. LPARAM lParam
  2630. )
  2631. {
  2632. static PECDISPLAY_PARAMS pParams;
  2633. INT StringLength;
  2634. DLGBOX_STATUS RetValue;
  2635. switch (message)
  2636. {
  2637. case WM_INITDIALOG:
  2638. pParams = (PECDISPLAY_PARAMS) lParam;
  2639. SetDlgItemIntHex(hDlg,
  2640. IDC_USAGE_PAGE,
  2641. pParams -> UsagePage,
  2642. 2);
  2643. break;
  2644. case WM_COMMAND:
  2645. switch (LOWORD(wParam))
  2646. {
  2647. case IDOK:
  2648. StringLength = GetWindowTextLength(GetDlgItem(hDlg, IDC_USAGE_LIST));
  2649. if (StringLength > 0)
  2650. {
  2651. pParams -> szListString = (PCHAR) malloc(StringLength+1);
  2652. if (NULL == pParams -> szListString)
  2653. {
  2654. ECDISP_ERROR(hDlg, "Error allocating memory");
  2655. RetValue = DLGBOX_ERROR;
  2656. }
  2657. else
  2658. {
  2659. GetWindowText(GetDlgItem(hDlg, IDC_USAGE_LIST),
  2660. pParams -> szListString,
  2661. StringLength+1);
  2662. RetValue = DLGBOX_OK;
  2663. }
  2664. }
  2665. else
  2666. {
  2667. pParams -> szListString = NULL;
  2668. RetValue = DLGBOX_CANCEL;
  2669. }
  2670. EndDialog(hDlg, RetValue);
  2671. break;
  2672. case IDCANCEL:
  2673. EndDialog(hDlg, DLGBOX_CANCEL);
  2674. break;
  2675. }
  2676. break;
  2677. }
  2678. return (FALSE);
  2679. }
  2680. LRESULT CALLBACK
  2681. bSetValueDlgProc(
  2682. HWND hDlg,
  2683. UINT message,
  2684. WPARAM wParam,
  2685. LPARAM lParam
  2686. )
  2687. {
  2688. static PECDISPLAY_PARAMS pParams;
  2689. INT StringLength;
  2690. DLGBOX_STATUS RetValue;
  2691. switch (message)
  2692. {
  2693. case WM_INITDIALOG:
  2694. pParams = (PECDISPLAY_PARAMS) lParam;
  2695. SetDlgItemIntHex(hDlg,
  2696. IDC_USAGE_PAGE,
  2697. pParams -> UsagePage,
  2698. sizeof(USAGE));
  2699. SetDlgItemIntHex(hDlg,
  2700. IDC_USAGE,
  2701. pParams -> Usage,
  2702. sizeof(USAGE));
  2703. break;
  2704. case WM_COMMAND:
  2705. switch (LOWORD(wParam))
  2706. {
  2707. case IDOK:
  2708. StringLength = GetWindowTextLength(GetDlgItem(hDlg, IDC_VALUE));
  2709. if (StringLength > 0)
  2710. {
  2711. pParams -> szListString = (PCHAR) malloc(StringLength+1);
  2712. if (NULL == pParams -> szListString)
  2713. {
  2714. ECDISP_ERROR(hDlg, "Error allocating memory");
  2715. RetValue = DLGBOX_ERROR;
  2716. }
  2717. else
  2718. {
  2719. GetWindowText(GetDlgItem(hDlg, IDC_VALUE),
  2720. pParams -> szListString,
  2721. StringLength+1);
  2722. RetValue = DLGBOX_OK;
  2723. }
  2724. }
  2725. else
  2726. {
  2727. pParams -> szListString = NULL;
  2728. RetValue = DLGBOX_CANCEL;
  2729. }
  2730. EndDialog(hDlg, RetValue);
  2731. break;
  2732. case IDCANCEL:
  2733. EndDialog(hDlg, DLGBOX_CANCEL);
  2734. break;
  2735. }
  2736. break;
  2737. }
  2738. return (FALSE);
  2739. }
  2740. LRESULT CALLBACK
  2741. bSetInputBuffDlgProc(
  2742. HWND hDlg,
  2743. UINT message,
  2744. WPARAM wParam,
  2745. LPARAM lParam
  2746. )
  2747. {
  2748. static PECDISPLAY_PARAMS pParams;
  2749. INT StringLength;
  2750. DLGBOX_STATUS RetValue;
  2751. switch (message)
  2752. {
  2753. case WM_INITDIALOG:
  2754. pParams = (PECDISPLAY_PARAMS) lParam;
  2755. break;
  2756. case WM_COMMAND:
  2757. switch (LOWORD(wParam))
  2758. {
  2759. case IDOK:
  2760. StringLength = GetWindowTextLength(GetDlgItem(hDlg, IDC_INPUT_BUFFERS));
  2761. if (StringLength > 0)
  2762. {
  2763. pParams -> szListString = (PCHAR) malloc(StringLength+1);
  2764. if (NULL == pParams -> szListString)
  2765. {
  2766. ECDISP_ERROR(hDlg, "Error allocating memory");
  2767. RetValue = DLGBOX_ERROR;
  2768. }
  2769. else
  2770. {
  2771. GetWindowText(GetDlgItem(hDlg, IDC_INPUT_BUFFERS),
  2772. pParams -> szListString,
  2773. StringLength+1);
  2774. RetValue = DLGBOX_OK;
  2775. }
  2776. }
  2777. else
  2778. {
  2779. pParams -> szListString = NULL;
  2780. RetValue = DLGBOX_CANCEL;
  2781. }
  2782. EndDialog(hDlg, RetValue);
  2783. break;
  2784. case IDCANCEL:
  2785. EndDialog(hDlg, DLGBOX_CANCEL);
  2786. break;
  2787. }
  2788. break;
  2789. }
  2790. return (FALSE);
  2791. }
  2792. LRESULT CALLBACK
  2793. bSetDataDlgProc(
  2794. HWND hDlg,
  2795. UINT message,
  2796. WPARAM wParam,
  2797. LPARAM lParam
  2798. )
  2799. {
  2800. static CHAR DataString[1024];
  2801. static PECDISPLAY_PARAMS pParams;
  2802. UINT IndexValue;
  2803. ULONG Value;
  2804. BOOL lpTranslated;
  2805. DLGBOX_STATUS RetValue;
  2806. PCHAR endp;
  2807. INT ListBoxStatus;
  2808. PHIDP_DATA DataList;
  2809. PHIDP_DATA CurrData;
  2810. ULONG DataListLength;
  2811. ULONG Index;
  2812. switch (message)
  2813. {
  2814. case WM_INITDIALOG:
  2815. pParams = (PECDISPLAY_PARAMS) lParam;
  2816. SendMessage(GetDlgItem(hDlg, IDC_VALUE),
  2817. EM_SETLIMITTEXT,
  2818. (WPARAM) 1024,
  2819. 0);
  2820. break;
  2821. case WM_COMMAND:
  2822. switch (LOWORD(wParam))
  2823. {
  2824. case IDC_ADD_DATA:
  2825. IndexValue = GetDlgItemInt(hDlg,
  2826. IDC_INDEX,
  2827. &lpTranslated,
  2828. FALSE);
  2829. if (!lpTranslated)
  2830. {
  2831. ECDISP_ERROR(hDlg,
  2832. "Invalid index value: must be unsigned integer");
  2833. break;
  2834. }
  2835. if (0 == GetWindowText(GetDlgItem(hDlg, IDC_VALUE),
  2836. DataString, 1023))
  2837. {
  2838. ECDISP_ERROR(hDlg, "Invalid data value");
  2839. break;
  2840. }
  2841. CharUpperBuff(DataString, lstrlen(DataString));
  2842. if (0 == lstrcmp(DataString, "TRUE"))
  2843. {
  2844. Value = 1;
  2845. }
  2846. else if (0 == lstrcmp(DataString, "FALSE"))
  2847. {
  2848. Value = 0;
  2849. }
  2850. else
  2851. {
  2852. Value = strtoul(DataString, &endp, 10);
  2853. if (*endp != '\0')
  2854. {
  2855. ECDISP_ERROR(hDlg, "Invalid data value");
  2856. break;
  2857. }
  2858. }
  2859. wsprintf(DataString,
  2860. SETDATA_LISTBOX_FORMAT,
  2861. IndexValue,
  2862. Value);
  2863. ListBoxStatus = (INT) SendMessage(GetDlgItem(hDlg, IDC_DATA_LIST),
  2864. LB_ADDSTRING,
  2865. 0,
  2866. (LPARAM) DataString);
  2867. if (CB_ERR == ListBoxStatus || CB_ERRSPACE == ListBoxStatus)
  2868. {
  2869. ECDISP_ERROR(hDlg, "Error adding string to data list");
  2870. break;
  2871. }
  2872. break;
  2873. case IDC_REMOVE_DATA:
  2874. SendMessage(GetDlgItem(hDlg, IDC_DATA_LIST),
  2875. LB_DELETESTRING,
  2876. SendMessage(GetDlgItem(hDlg, IDC_DATA_LIST),
  2877. LB_GETCURSEL,
  2878. 0, 0),
  2879. 0);
  2880. break;
  2881. case IDOK:
  2882. DataListLength = (ULONG) SendMessage(GetDlgItem(hDlg, IDC_DATA_LIST),
  2883. LB_GETCOUNT,
  2884. 0, 0);
  2885. if (0 != DataListLength)
  2886. {
  2887. DataList = malloc(DataListLength * sizeof(HIDP_DATA));
  2888. if (NULL == DataList)
  2889. {
  2890. ECDISP_ERROR(hDlg, "Error allocating memory");
  2891. DataListLength = 0;
  2892. RetValue = DLGBOX_CANCEL;
  2893. break;
  2894. }
  2895. for (Index = 0, CurrData = DataList; Index < DataListLength; Index++, CurrData++)
  2896. {
  2897. SendMessage(GetDlgItem(hDlg, IDC_DATA_LIST),
  2898. LB_GETTEXT,
  2899. Index,
  2900. (LPARAM) DataString);
  2901. sscanf(DataString,
  2902. SETDATA_LISTBOX_FORMAT,
  2903. &IndexValue,
  2904. &Value);
  2905. CurrData -> DataIndex = (USHORT) IndexValue;
  2906. CurrData -> RawValue = Value;
  2907. }
  2908. RetValue = DLGBOX_OK;
  2909. }
  2910. else
  2911. {
  2912. DataList = NULL;
  2913. RetValue = DLGBOX_CANCEL;
  2914. }
  2915. pParams -> pDataList = DataList;
  2916. pParams -> ListLength = DataListLength;
  2917. EndDialog(hDlg, RetValue);
  2918. break;
  2919. case IDCANCEL:
  2920. EndDialog(hDlg, DLGBOX_CANCEL);
  2921. break;
  2922. }
  2923. break;
  2924. }
  2925. return (FALSE);
  2926. }
  2927. LRESULT CALLBACK
  2928. bSetBufLenDlgProc(
  2929. HWND hDlg,
  2930. UINT message,
  2931. WPARAM wParam,
  2932. LPARAM lParam
  2933. )
  2934. {
  2935. static PECDISPLAY_PARAMS pParams;
  2936. INT StringLength;
  2937. DLGBOX_STATUS RetValue;
  2938. switch (message)
  2939. {
  2940. case WM_INITDIALOG:
  2941. pParams = (PECDISPLAY_PARAMS) lParam;
  2942. break;
  2943. case WM_COMMAND:
  2944. switch (LOWORD(wParam))
  2945. {
  2946. case IDOK:
  2947. StringLength = GetWindowTextLength(GetDlgItem(hDlg, IDC_BUFFER_LENGTH));
  2948. if (StringLength > 0)
  2949. {
  2950. pParams -> szListString = (PCHAR) malloc(StringLength+1);
  2951. if (NULL == pParams -> szListString)
  2952. {
  2953. ECDISP_ERROR(hDlg, "Error allocating memory");
  2954. RetValue = DLGBOX_ERROR;
  2955. }
  2956. else
  2957. {
  2958. GetWindowText(GetDlgItem(hDlg, IDC_BUFFER_LENGTH),
  2959. pParams -> szListString,
  2960. StringLength+1);
  2961. RetValue = DLGBOX_OK;
  2962. }
  2963. }
  2964. else
  2965. {
  2966. pParams -> szListString = NULL;
  2967. RetValue = DLGBOX_CANCEL;
  2968. }
  2969. EndDialog(hDlg, RetValue);
  2970. break;
  2971. case IDCANCEL:
  2972. EndDialog(hDlg, DLGBOX_CANCEL);
  2973. break;
  2974. }
  2975. break;
  2976. }
  2977. return (FALSE);
  2978. }
  2979. LRESULT CALLBACK
  2980. bSetInputBuffersDlgProc(
  2981. HWND hDlg,
  2982. UINT message,
  2983. WPARAM wParam,
  2984. LPARAM lParam
  2985. )
  2986. {
  2987. static PECDISPLAY_PARAMS pParams;
  2988. INT StringLength;
  2989. DLGBOX_STATUS RetValue;
  2990. switch (message)
  2991. {
  2992. case WM_INITDIALOG:
  2993. pParams = (PECDISPLAY_PARAMS) lParam;
  2994. break;
  2995. case WM_COMMAND:
  2996. switch (LOWORD(wParam))
  2997. {
  2998. case IDOK:
  2999. StringLength = GetWindowTextLength(GetDlgItem(hDlg, IDC_INPUT_BUFFERS));
  3000. if (StringLength > 0)
  3001. {
  3002. pParams -> szListString = (PCHAR) malloc(StringLength+1);
  3003. if (NULL == pParams -> szListString)
  3004. {
  3005. ECDISP_ERROR(hDlg, "Error allocating memory");
  3006. RetValue = DLGBOX_ERROR;
  3007. }
  3008. else
  3009. {
  3010. GetWindowText(GetDlgItem(hDlg, IDC_INPUT_BUFFERS),
  3011. pParams -> szListString,
  3012. StringLength+1
  3013. );
  3014. RetValue = DLGBOX_OK;
  3015. }
  3016. }
  3017. else
  3018. {
  3019. pParams -> szListString = NULL;
  3020. RetValue = DLGBOX_CANCEL;
  3021. }
  3022. EndDialog(hDlg, RetValue);
  3023. break;
  3024. case IDCANCEL:
  3025. EndDialog(hDlg, DLGBOX_CANCEL);
  3026. break;
  3027. }
  3028. break;
  3029. }
  3030. return (FALSE);
  3031. }
  3032. LRESULT CALLBACK
  3033. bGetIndexedDlgProc(
  3034. HWND hDlg,
  3035. UINT message,
  3036. WPARAM wParam,
  3037. LPARAM lParam
  3038. )
  3039. {
  3040. static PECDISPLAY_PARAMS pParams;
  3041. INT StringLength;
  3042. INT StringLength2;
  3043. DLGBOX_STATUS RetValue;
  3044. switch (message)
  3045. {
  3046. case WM_INITDIALOG:
  3047. pParams = (PECDISPLAY_PARAMS) lParam;
  3048. break;
  3049. case WM_COMMAND:
  3050. switch (LOWORD(wParam))
  3051. {
  3052. case IDOK:
  3053. StringLength = GetWindowTextLength(GetDlgItem(hDlg, IDC_INDEX));
  3054. StringLength2 = GetWindowTextLength(GetDlgItem(hDlg, IDC_BUFFER_LENGTH));
  3055. if (StringLength <= 0 || StringLength2 <= 0)
  3056. {
  3057. pParams -> szListString = NULL;
  3058. pParams -> szListString2 = NULL;
  3059. RetValue = DLGBOX_CANCEL;
  3060. EndDialog(hDlg, DLGBOX_CANCEL);
  3061. }
  3062. pParams -> szListString = (PCHAR) malloc(StringLength+1);
  3063. pParams -> szListString2 = (PCHAR) malloc(StringLength2+1);
  3064. if (NULL == pParams -> szListString || NULL == pParams -> szListString2)
  3065. {
  3066. ECDISP_ERROR(hDlg, "Error allocating memory");
  3067. if (NULL != pParams -> szListString)
  3068. free(pParams -> szListString);
  3069. if (NULL != pParams -> szListString2)
  3070. free(pParams -> szListString2);
  3071. RetValue = DLGBOX_ERROR;
  3072. }
  3073. else
  3074. {
  3075. GetWindowText(GetDlgItem(hDlg, IDC_INDEX),
  3076. pParams -> szListString,
  3077. StringLength+1);
  3078. GetWindowText(GetDlgItem(hDlg, IDC_BUFFER_LENGTH),
  3079. pParams -> szListString2,
  3080. StringLength2+1);
  3081. RetValue = DLGBOX_OK;
  3082. }
  3083. EndDialog(hDlg, RetValue);
  3084. break;
  3085. case IDCANCEL:
  3086. EndDialog(hDlg, DLGBOX_CANCEL);
  3087. break;
  3088. }
  3089. break;
  3090. }
  3091. return (FALSE);
  3092. }
  3093. LRESULT CALLBACK
  3094. bGetUsageDiffDlgProc(
  3095. HWND hDlg,
  3096. UINT message,
  3097. WPARAM wParam,
  3098. LPARAM lParam
  3099. )
  3100. {
  3101. static PECDISPLAY_PARAMS pParams;
  3102. INT StringLength;
  3103. INT StringLength2;
  3104. DLGBOX_STATUS RetValue;
  3105. switch (message)
  3106. {
  3107. case WM_INITDIALOG:
  3108. pParams = (PECDISPLAY_PARAMS) lParam;
  3109. break;
  3110. case WM_COMMAND:
  3111. switch (LOWORD(wParam))
  3112. {
  3113. case IDOK:
  3114. StringLength = GetWindowTextLength(GetDlgItem(hDlg, IDC_USAGE_LIST1));
  3115. StringLength2 = GetWindowTextLength(GetDlgItem(hDlg, IDC_USAGE_LIST2));
  3116. if (StringLength <= 0)
  3117. {
  3118. pParams -> szListString = NULL;
  3119. }
  3120. else
  3121. {
  3122. pParams -> szListString = (PCHAR) malloc(StringLength+1);
  3123. if (NULL == pParams -> szListString)
  3124. {
  3125. ECDISP_ERROR(hDlg,
  3126. "Error allocating memory");
  3127. EndDialog(hDlg, DLGBOX_ERROR);
  3128. break;
  3129. }
  3130. }
  3131. if (StringLength2 <= 0)
  3132. {
  3133. pParams -> szListString = NULL;
  3134. }
  3135. else
  3136. {
  3137. pParams -> szListString2 = (PCHAR) malloc(StringLength2+1);
  3138. if (NULL == pParams -> szListString2)
  3139. {
  3140. ECDISP_ERROR(hDlg,
  3141. "Error allocating memory");
  3142. if (NULL != pParams -> szListString)
  3143. {
  3144. free(pParams -> szListString);
  3145. }
  3146. EndDialog(hDlg, DLGBOX_ERROR);
  3147. break;
  3148. }
  3149. }
  3150. GetWindowText(GetDlgItem(hDlg, IDC_USAGE_LIST1),
  3151. pParams -> szListString,
  3152. StringLength+1);
  3153. GetWindowText(GetDlgItem(hDlg, IDC_USAGE_LIST2),
  3154. pParams -> szListString2,
  3155. StringLength2+1);
  3156. RetValue = DLGBOX_OK;
  3157. EndDialog(hDlg, RetValue);
  3158. break;
  3159. case IDCANCEL:
  3160. EndDialog(hDlg, DLGBOX_CANCEL);
  3161. break;
  3162. }
  3163. break;
  3164. }
  3165. return (FALSE);
  3166. }
  3167. BOOL
  3168. ConvertStringToUsageList(
  3169. IN OUT PCHAR InString,
  3170. OUT PUSAGE *UsageList,
  3171. OUT PULONG nUsages
  3172. )
  3173. /*++
  3174. RoutineDescription:
  3175. This routine converts a string of values into a string of usages which are
  3176. currently 2 byte values. We use base 16 to specify that the usages should
  3177. be expressed as hexidecimal numbers.
  3178. --*/
  3179. {
  3180. return (Strings_StringToUnsignedList(InString,
  3181. sizeof(ULONG),
  3182. 16,
  3183. (PCHAR *) UsageList,
  3184. nUsages));
  3185. }
  3186. BOOL
  3187. ConvertStringToUlongList(
  3188. IN OUT PCHAR InString,
  3189. OUT PULONG *UlongList,
  3190. OUT PULONG nUlongs
  3191. )
  3192. /*++
  3193. RoutineDescription
  3194. This routine converts a string of values into a string of ulongs which are
  3195. currently 2 byte values. It requires that the numbers in the string be in
  3196. base 10
  3197. --*/
  3198. {
  3199. return (Strings_StringToUnsignedList(InString,
  3200. sizeof(ULONG),
  3201. 10,
  3202. (PCHAR *) UlongList,
  3203. nUlongs));
  3204. }
  3205. BOOL
  3206. SetDlgItemIntHex(
  3207. HWND hDlg,
  3208. INT nIDDlgItem,
  3209. UINT uValue,
  3210. INT nBytes
  3211. )
  3212. {
  3213. char szTempBuffer[] = "0x00000000";
  3214. int iEndIndex, iWidth;
  3215. assert (1 == nBytes || 2 == nBytes || 4 == nBytes);
  3216. /*
  3217. // Determine the width necessary to store the value
  3218. */
  3219. iWidth = ((int) floor(log(uValue)/log(16))) + 1;
  3220. assert (iWidth <= 2*nBytes);
  3221. iEndIndex = 2+2*nBytes;
  3222. wsprintf(&(szTempBuffer[iEndIndex-iWidth]), "%X", uValue);
  3223. SetDlgItemText(hDlg, nIDDlgItem, szTempBuffer);
  3224. return (TRUE);
  3225. }
  3226. VOID
  3227. ECDisp_MakeGUIDString(
  3228. IN GUID guid,
  3229. OUT CHAR szString[]
  3230. )
  3231. {
  3232. char szCharString[18];
  3233. int i;
  3234. for (i = 0; i < 8; i++)
  3235. {
  3236. wsprintf(&(szCharString[i]), "%x", guid.Data4[i]);
  3237. }
  3238. wsprintf(szString, "%x-%x%x-%s", guid.Data1, guid.Data2, guid.Data3, szCharString);
  3239. return;
  3240. }
  3241. PCHAR
  3242. ECDisp_GetHidAppStatusString(
  3243. NTSTATUS StatusCode
  3244. )
  3245. {
  3246. static CHAR hidString[128];
  3247. switch (StatusCode)
  3248. {
  3249. case HIDP_STATUS_SUCCESS:
  3250. return ("Success");
  3251. case HIDP_STATUS_NULL:
  3252. return ("Status NULL");
  3253. case HIDP_STATUS_INVALID_PREPARSED_DATA:
  3254. return ("Invalid Preparsed Data");
  3255. case HIDP_STATUS_INVALID_REPORT_TYPE:
  3256. return ("Invalid Report Type");
  3257. case HIDP_STATUS_INVALID_REPORT_LENGTH:
  3258. return ("Invalid Report Length");
  3259. case HIDP_STATUS_USAGE_NOT_FOUND:
  3260. return ("Usage not found");
  3261. case HIDP_STATUS_VALUE_OUT_OF_RANGE:
  3262. return ("Value out of range");
  3263. case HIDP_STATUS_BAD_LOG_PHY_VALUES:
  3264. return ("Bad logical physical values");
  3265. case HIDP_STATUS_BUFFER_TOO_SMALL:
  3266. return ("Buffer too small");
  3267. case HIDP_STATUS_INTERNAL_ERROR:
  3268. return ("Internal error");
  3269. case HIDP_STATUS_I8242_TRANS_UNKNOWN:
  3270. return ("I8242 Translation unknown");
  3271. case HIDP_STATUS_INCOMPATIBLE_REPORT_ID:
  3272. return ("Incompatible report ID");
  3273. case HIDP_STATUS_NOT_VALUE_ARRAY:
  3274. return ("Not value array");
  3275. case HIDP_STATUS_IS_VALUE_ARRAY:
  3276. return ("Is value array");
  3277. case HIDP_STATUS_DATA_INDEX_NOT_FOUND:
  3278. return ("Data index not found");
  3279. case HIDP_STATUS_DATA_INDEX_OUT_OF_RANGE:
  3280. return ("Data index out of range");
  3281. case HIDP_STATUS_BUTTON_NOT_PRESSED:
  3282. return ("Button not pressed");
  3283. case HIDP_STATUS_REPORT_DOES_NOT_EXIST:
  3284. return ("Report does not exist");
  3285. case HIDP_STATUS_NOT_IMPLEMENTED:
  3286. return ("Not implemented");
  3287. default:
  3288. sprintf(hidString, "Unknown HID Status error: 0x%x", StatusCode);
  3289. return (&hidString[0]);
  3290. }
  3291. }
  3292. BOOL
  3293. ECDisp_ConvertUlongListToValueList(
  3294. IN PULONG UlongList,
  3295. IN ULONG nUlongs,
  3296. IN USHORT BitSize,
  3297. IN USHORT ReportCount,
  3298. OUT PCHAR *ValueList,
  3299. OUT PULONG ValueListSize
  3300. )
  3301. /*++
  3302. RoutineDescription:
  3303. This routine takes a list of ULong values and formats a value list that is
  3304. used as input to HidP_SetUsageValueArray. Unfortunately, this HidP function
  3305. requires the caller to format the input buffer which means taking each of
  3306. the values in Ulong, truncating their values to meet bit size and then set
  3307. those bits at the appropriate spot in the buffer. That is the purpose of
  3308. this function
  3309. The function will return TRUE if everything succeeded, FALSE otherwise.
  3310. --*/
  3311. {
  3312. ULONG ulMask;
  3313. PCHAR List;
  3314. INT iByteIndex;
  3315. INT iByteOffset;
  3316. ULONG UlongIndex;
  3317. ULONG ListSize;
  3318. USHORT BitsToAdd;
  3319. USHORT nBits;
  3320. ULONG ulValue;
  3321. UCHAR LowByte;
  3322. *ValueList = NULL;
  3323. *ValueListSize = 0;
  3324. //
  3325. // Do some parameter validation...ReportCount should never be zero.
  3326. //
  3327. if (0 == ReportCount)
  3328. {
  3329. SetLastError(ERROR_INVALID_PARAMETER);
  3330. return (FALSE);
  3331. }
  3332. //
  3333. // Check the number of ulongs passed in is actually less than or equal
  3334. // to the report count and if not, use only the first ReportCount
  3335. // number of ULongs.
  3336. //
  3337. if (nUlongs > ReportCount)
  3338. {
  3339. nUlongs = ReportCount;
  3340. }
  3341. /*
  3342. // Allocate our buffer for the value list and return FALSE if it couldn't
  3343. // be done
  3344. */
  3345. ListSize = ROUND_TO_NEAREST_BYTE(BitSize * ReportCount);
  3346. List = (PCHAR) malloc(ListSize);
  3347. if (NULL == List)
  3348. {
  3349. SetLastError(ERROR_OUTOFMEMORY);
  3350. return (FALSE);
  3351. }
  3352. /*
  3353. // Initialize the buffer to all zeroes
  3354. */
  3355. memset(List, 0x00, ListSize);
  3356. /*
  3357. // Buffer has been allocated let's convert those values
  3358. */
  3359. /*
  3360. // Determine the mask that will be used to retrieve the cared about bits
  3361. // of our value
  3362. */
  3363. ulMask = (sizeof(ULONG)*8 == BitSize) ? ULONG_MAX : (1 << BitSize)-1;
  3364. /*
  3365. // Initialize the iByteIndex and iByteOffset fields before entering the
  3366. // conversion loop.
  3367. */
  3368. iByteIndex = 0;
  3369. iByteOffset = 0;
  3370. /*
  3371. // This is the main conversion loop. It performs the following steps on
  3372. // each Ulong in the ulong list
  3373. // 1) Sets BitsToAdd = BitSize
  3374. // 2) Gets the ulValue and the masks off the upper bits that we don't
  3375. // care about.
  3376. // 3) Determines how many bits can fit at the current byte index based
  3377. // on the current byte offset and the number of bits left to add
  3378. // 4) Retrieve those bits, shift them to the correct position and
  3379. // use bitwise or to get the correct values in the buffer
  3380. // 5) Increment the byte index and set our new byte offset
  3381. // 6) Shift our Ulong value right to get rid of least significant bits
  3382. // that have already been added
  3383. // 7) Repeat through step 3 until no more bits to add
  3384. */
  3385. for (UlongIndex = 0; UlongIndex < nUlongs; UlongIndex++)
  3386. {
  3387. BitsToAdd = BitSize;
  3388. ulValue = *(UlongList + UlongIndex) & ulMask;
  3389. while (BitsToAdd > 0)
  3390. {
  3391. nBits = min (8 - iByteOffset, BitsToAdd);
  3392. LowByte = (UCHAR) (ulValue & 0xFF);
  3393. LowByte = LowByte << iByteOffset;
  3394. *(List+iByteIndex) |= LowByte;
  3395. iByteIndex = (iByteOffset+nBits) >= 8 ? iByteIndex+1 : iByteIndex;
  3396. iByteOffset = (iByteOffset + nBits) % 8;
  3397. BitsToAdd -= nBits;
  3398. ulValue = ulValue >> nBits;
  3399. }
  3400. }
  3401. *ValueList = List;
  3402. *ValueListSize = ListSize;
  3403. return (TRUE);
  3404. }
  3405. PCHAR
  3406. ResolveFunctionName(
  3407. INT Index
  3408. )
  3409. {
  3410. PCHAR FuncName;
  3411. if (IS_HIDD_FUNCTION(Index) || IS_HID_FUNCTION(Index))
  3412. {
  3413. FuncName = DeviceCalls[Index-1].szFunctionName;
  3414. }
  3415. else
  3416. {
  3417. FuncName = PpdCalls[Index-HID_DEVCALLS-1].szFunctionName;
  3418. }
  3419. return (FuncName);
  3420. }
  3421. VOID
  3422. DisplayExtendedAttributes(
  3423. IN HWND OutputWindow,
  3424. IN PHIDP_UNKNOWN_TOKEN UnknownList,
  3425. IN ULONG UnknownListLength
  3426. )
  3427. {
  3428. PHIDP_UNKNOWN_TOKEN current;
  3429. ULONG index;
  3430. wsprintf(szTempBuffer, "Number of attributes: %d", UnknownListLength);
  3431. OUTSTRING(OutputWindow, szTempBuffer);
  3432. current = UnknownList;
  3433. for (index = 0; index < UnknownListLength; index++)
  3434. {
  3435. wsprintf(szTempBuffer,
  3436. "Token %d: %d BitField: 0x%X",
  3437. current -> Token,
  3438. current -> BitField);
  3439. OUTSTRING(OutputWindow, szTempBuffer);
  3440. }
  3441. return;
  3442. }