Leaked source code of windows server 2003
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.

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