00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #define __HCLIENT_C__
00025 #define LOG_FILE_NAME NULL
00026
00027
00028
00029
00030
00031 #include <windows.h>
00032 #include <stdlib.h>
00033 #include <stdio.h>
00034 #include <wtypes.h>
00035 #include <math.h>
00036 #include <assert.h>
00037 #include <dbt.h>
00038 #include "hidsdi.h"
00039 #include "hid.h"
00040 #include "resource.h"
00041 #include "resrc1.h"
00042 #include "hclient.h"
00043 #include "buffers.h"
00044 #include "ecdisp.h"
00045 #include "list.h"
00046 #include <strsafe.h>
00047
00048
00049
00050
00051
00052 #define INPUT_BUTTON 1
00053 #define INPUT_VALUE 2
00054 #define OUTPUT_BUTTON 3
00055 #define OUTPUT_VALUE 4
00056 #define FEATURE_BUTTON 5
00057 #define FEATURE_VALUE 6
00058 #define HID_CAPS 7
00059 #define DEVICE_ATTRIBUTES 8
00060
00061 #define MAX_LB_ITEMS 200
00062
00063 #define MAX_WRITE_ELEMENTS 100
00064 #define MAX_OUTPUT_ELEMENTS 50
00065
00066 #define CONTROL_COUNT 9
00067 #define MAX_LABEL 128
00068 #define MAX_VALUE 128
00069 #define SMALL_BUFF 128
00070
00071
00072
00073
00074
00075 #define GET_CURRENT_DEVICE(hDlg, pDevice) \
00076 { \
00077 pDevice = NULL; \
00078 iIndex = (INT) SendDlgItemMessage(hDlg, \
00079 IDC_DEVICES, \
00080 CB_GETCURSEL, \
00081 0, \
00082 0); \
00083 if (CB_ERR != iIndex) { \
00084 pDevice = (PHID_DEVICE) SendDlgItemMessage(hDlg, \
00085 IDC_DEVICES, \
00086 CB_GETITEMDATA, \
00087 iIndex, \
00088 0); \
00089 } \
00090 }
00091
00092
00093
00094
00095
00096 typedef struct rWriteDataStruct_type
00097 {
00098
00099 char szLabel[MAX_LABEL];
00100 char szValue[MAX_VALUE];
00101
00102 } rWriteDataStruct, *prWriteDataStruct;
00103
00104 typedef struct rGetWriteDataParams_type
00105 {
00106 prWriteDataStruct prItems;
00107 int iCount;
00108
00109 } rGetWriteDataParams, *prGetWriteDataParams;
00110
00111 typedef struct _DEVICE_LIST_NODE
00112 {
00113 LIST_NODE_HDR Hdr;
00114 HDEVNOTIFY NotificationHandle;
00115 HID_DEVICE HidDeviceInfo;
00116 BOOL DeviceOpened;
00117
00118 } DEVICE_LIST_NODE, *PDEVICE_LIST_NODE;
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 PGETEXTATTRIB pfnHidP_GetExtendedAttributes = NULL;
00134
00135 PINITREPORT pfnHidP_InitializeReportForID = NULL;
00136
00137
00138
00139
00140
00141 static HINSTANCE hGInstance;
00142
00143 static HANDLE HIDDLLModuleHandle;
00144
00145
00146
00147
00148
00149
00150
00151 static LIST PhysicalDeviceList;
00152
00153
00154
00155
00156
00157 VOID
00158 vReadDataFromControls(
00159 HWND hDlg,
00160 prWriteDataStruct prData,
00161 int iOffset,
00162 int iCount
00163 );
00164
00165 INT_PTR CALLBACK
00166 bGetDataDlgProc(
00167 HWND hDlg,
00168 UINT message,
00169 WPARAM wParam,
00170 LPARAM lParam
00171 );
00172
00173 INT_PTR CALLBACK
00174 bMainDlgProc(
00175 HWND hDlg,
00176 UINT message,
00177 WPARAM wParam,
00178 LPARAM lParam
00179 );
00180
00181 INT_PTR CALLBACK
00182 bFeatureDlgProc(
00183 HWND hDlg,
00184 UINT message,
00185 WPARAM wParam,
00186 LPARAM lParam
00187 );
00188
00189 INT_PTR CALLBACK
00190 bReadDlgProc(
00191 HWND hDlg,
00192 UINT message,
00193 WPARAM wParam,
00194 LPARAM lParam
00195 );
00196
00197 VOID
00198 vLoadItemTypes(
00199 HWND hItemTypes
00200 );
00201
00202 BOOL
00203 bGetData(
00204 prWriteDataStruct,
00205 int iCount,
00206 HWND hParent,
00207 char *pszDialogName
00208 );
00209
00210 VOID
00211 vLoadDevices(
00212 HWND hDeviceCombo
00213 );
00214
00215 VOID
00216 vFreeDeviceList(
00217 PHID_DEVICE DeviceList,
00218 ULONG nDevices
00219 );
00220
00221 VOID
00222 vDisplayInputButtons(
00223 PHID_DEVICE pDevice,
00224 HWND hControl
00225 );
00226
00227 VOID
00228 vDisplayInputValues(
00229 PHID_DEVICE pDevice,
00230 HWND hControl
00231 );
00232
00233 VOID
00234 vDisplayOutputButtons(
00235 PHID_DEVICE pDevice,
00236 HWND hControl
00237 );
00238
00239 VOID
00240 vDisplayOutputValues(
00241 PHID_DEVICE pDevice,
00242 HWND hControl
00243 );
00244
00245 VOID
00246 vDisplayFeatureButtons(
00247 PHID_DEVICE pDevice,
00248 HWND hControl
00249 );
00250
00251 VOID
00252 vDisplayFeatureValues(
00253 PHID_DEVICE pDevice,
00254 HWND hControl
00255 );
00256
00257 VOID
00258 vWriteDataToControls(
00259 HWND hDlg,
00260 prWriteDataStruct prData,
00261 int iOffset,
00262 int iCount
00263 );
00264
00265 int
00266 iPrepareDataFields(
00267 PHID_DATA pData,
00268 ULONG ulDataLength,
00269 rWriteDataStruct rWriteData[],
00270 int iMaxElements
00271 );
00272
00273 BOOL
00274 bParseData(
00275 PHID_DATA pData,
00276 rWriteDataStruct rWriteData[],
00277 INT iCount,
00278 INT *piErrorLine
00279 );
00280
00281 BOOL
00282 bSetButtonUsages(
00283 PHID_DATA pCap,
00284 PCHAR pszInputString
00285 );
00286
00287 VOID
00288 BuildReportIDList(
00289 IN PHIDP_BUTTON_CAPS phidButtonCaps,
00290 IN USHORT nButtonCaps,
00291 IN PHIDP_VALUE_CAPS phidValueCaps,
00292 IN USHORT nValueCaps,
00293 OUT UCHAR **ppReportIDList,
00294 OUT INT *nReportIDs
00295 );
00296
00297 VOID
00298 ReportToString(
00299 PHID_DATA pData,
00300 PCHAR szBuff,
00301 UINT iBuffSize
00302 );
00303
00304 BOOL
00305 RegisterHidDevice(
00306 IN HWND WindowHandle,
00307 IN PDEVICE_LIST_NODE DeviceNode
00308 );
00309
00310 VOID
00311 DestroyDeviceListCallback(
00312 IN PLIST_NODE_HDR ListNode
00313 );
00314
00315 char
00316 HalfBtoHex(
00317 IN BYTE chr
00318 );
00319
00320 int
00321 Hex2Int(
00322 IN char * str
00323 );
00324
00325
00326
00327
00328
00329
00330
00331
00332 int PASCAL
00333 WinMain(
00334 HINSTANCE hInstance,
00335 HINSTANCE hPrevInstance,
00336 LPSTR lpCmdLine,
00337 int nCmdShow
00338 )
00339 {
00340
00341
00342
00343
00344 hGInstance = hInstance;
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355 HIDDLLModuleHandle = LoadLibrary("HID.DLL");
00356
00357 if (NULL == HIDDLLModuleHandle)
00358 {
00359
00360
00361
00362
00363
00364 MessageBox(NULL,
00365 "Unable to open HID.DLL\n"
00366 "This should never occur",
00367 HCLIENT_ERROR,
00368 MB_ICONSTOP);
00369
00370 return (0);
00371 }
00372
00373
00374
00375
00376
00377 pfnHidP_GetExtendedAttributes = (PGETEXTATTRIB) GetProcAddress(HIDDLLModuleHandle,
00378 "HidP_GetExtendedAttributes");
00379
00380 pfnHidP_InitializeReportForID = (PINITREPORT) GetProcAddress(HIDDLLModuleHandle,
00381 "HidP_InitializeReportForID");
00382
00383
00384
00385
00386
00387 if (-1 == DialogBox(hInstance, "MAIN_DIALOG", NULL, bMainDlgProc))
00388 {
00389 MessageBox(NULL,
00390 "Unable to create root dialog!",
00391 "DialogBox failure",
00392 MB_ICONSTOP);
00393 }
00394
00395 FreeLibrary (HIDDLLModuleHandle);
00396
00397 return (0);
00398 }
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408 INT_PTR CALLBACK
00409 bMainDlgProc(
00410 HWND hDlg,
00411 UINT message,
00412 WPARAM wParam,
00413 LPARAM lParam
00414 )
00415 {
00416 static HWND hComboCtrl;
00417 static rWriteDataStruct rWriteData[MAX_OUTPUT_ELEMENTS];
00418 static HDEVNOTIFY diNotifyHandle;
00419
00420 static HID_DEVICE hidDevice;
00421 static READ_THREAD_CONTEXT readContext;
00422 static HANDLE readThread;
00423
00424 INT iIndex;
00425 INT iCount;
00426 CHAR szTempBuff[SMALL_BUFF];
00427 PHID_DEVICE pDevice;
00428 PHIDP_BUTTON_CAPS pButtonCaps;
00429 PHIDP_VALUE_CAPS pValueCaps;
00430 INT iErrorLine;
00431 INT iItemType;
00432 PHID_DEVICE tempDeviceList;
00433 ULONG numberDevices;
00434 PDEVICE_LIST_NODE listNode;
00435 DEV_BROADCAST_DEVICEINTERFACE broadcastInterface;
00436 HID_DEVICE writeDevice;
00437 BOOL status;
00438 HRESULT stringReturn;
00439 DWORD threadID;
00440
00441 switch (message)
00442 {
00443 case WM_INITDIALOG:
00444
00445
00446
00447
00448
00449
00450
00451 InitializeList(&PhysicalDeviceList);
00452
00453
00454
00455
00456
00457
00458 if (!FindKnownHidDevices(&tempDeviceList, &numberDevices))
00459 {
00460 EndDialog(hDlg, 0);
00461 return FALSE;
00462 }
00463
00464
00465
00466
00467
00468
00469 pDevice = tempDeviceList;
00470 for (iIndex = 0; (ULONG) iIndex < numberDevices; iIndex++, pDevice++)
00471 {
00472 listNode = malloc(sizeof(DEVICE_LIST_NODE));
00473
00474 if (NULL == listNode) {
00475
00476
00477
00478
00479
00480
00481
00482 DestroyListWithCallback(&PhysicalDeviceList, DestroyDeviceListCallback);
00483
00484 CloseHidDevices(pDevice, numberDevices - iIndex);
00485
00486 free(tempDeviceList);
00487
00488 EndDialog(hDlg, 0);
00489 return FALSE;
00490 }
00491
00492 listNode -> HidDeviceInfo = *pDevice;
00493 listNode -> DeviceOpened = TRUE;
00494
00495
00496
00497
00498
00499
00500 if (!RegisterHidDevice(hDlg, listNode))
00501 {
00502 DestroyListWithCallback(&PhysicalDeviceList, DestroyDeviceListCallback);
00503
00504 CloseHidDevices(pDevice, numberDevices - iIndex);
00505
00506 free(tempDeviceList);
00507 free(listNode);
00508
00509 EndDialog(hDlg, 0);
00510 return FALSE;
00511 }
00512
00513 InsertTail(&PhysicalDeviceList, listNode);
00514 }
00515
00516
00517
00518
00519
00520 free(tempDeviceList);
00521
00522
00523
00524
00525
00526
00527
00528 broadcastInterface.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
00529 broadcastInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
00530
00531 HidD_GetHidGuid(&broadcastInterface.dbcc_classguid);
00532
00533 diNotifyHandle = RegisterDeviceNotification(hDlg,
00534 &broadcastInterface,
00535 DEVICE_NOTIFY_WINDOW_HANDLE
00536 );
00537 if (NULL == diNotifyHandle)
00538 {
00539 DestroyListWithCallback(&PhysicalDeviceList, DestroyDeviceListCallback);
00540
00541 EndDialog(hDlg, 0);
00542 return FALSE;
00543 }
00544
00545
00546
00547
00548
00549
00550 vLoadDevices(GetDlgItem(hDlg, IDC_DEVICES));
00551
00552
00553
00554
00555
00556 vLoadItemTypes(GetDlgItem(hDlg, IDC_TYPE));
00557
00558
00559
00560
00561
00562
00563 PostMessage(hDlg,
00564 WM_COMMAND,
00565 IDC_DEVICES + (CBN_SELCHANGE<<16),
00566 (LPARAM) GetDlgItem(hDlg, IDC_DEVICES));
00567
00568
00569 SendDlgItemMessage(hDlg, IDC_CHECK_OH, BM_SETCHECK, BST_UNCHECKED, 0);
00570 SendDlgItemMessage(hDlg, IDC_CHECK_IH, BM_SETCHECK, BST_CHECKED, 0);
00571 SendDlgItemMessage(hDlg, IDC_EDIT_OUT, WM_SETTEXT, 0, (LPARAM)"Enter Output");
00572
00573 break;
00574
00575 case WM_DISPLAY_READ_DATA:
00576
00577
00578
00579
00580
00581 pDevice = (PHID_DEVICE) lParam;
00582
00583 SetEvent( readContext.DisplayEvent );
00584 break;
00585
00586 case WM_READ_DONE:
00587
00588 readThread = NULL;
00589 break;
00590
00591 case WM_COMMAND:
00592
00593 switch (LOWORD(wParam))
00594 {
00595
00596
00597
00598
00599
00600
00601 case IDC_READ:
00602 GET_CURRENT_DEVICE(hDlg, pDevice);
00603
00604 if (NULL != pDevice)
00605 {
00606 iIndex = (INT) DialogBoxParam(hGInstance,
00607 "READDATA",
00608 hDlg,
00609 bReadDlgProc,
00610 (LPARAM) pDevice);
00611 }
00612 break;
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625 case IDC_WRITE:
00626
00627 GET_CURRENT_DEVICE(hDlg, pDevice);
00628
00629 if (NULL != pDevice)
00630 {
00631
00632
00633
00634
00635
00636
00637
00638
00639 status = OpenHidDevice(pDevice -> DevicePath,
00640 FALSE,
00641 TRUE,
00642 FALSE,
00643 FALSE,
00644 &writeDevice);
00645
00646 if (!status)
00647 {
00648 MessageBox(hDlg,
00649 "Couldn't open device for write access",
00650 HCLIENT_ERROR,
00651 MB_ICONEXCLAMATION);
00652 }
00653 else
00654 {
00655 iCount = iPrepareDataFields(writeDevice.OutputData,
00656 writeDevice.OutputDataLength,
00657 rWriteData,
00658 MAX_OUTPUT_ELEMENTS);
00659
00660 if (bGetData(rWriteData, iCount, hDlg, "WRITEDATA"))
00661 {
00662
00663 if (bParseData(writeDevice.OutputData, rWriteData, iCount, &iErrorLine))
00664 {
00665 Write(&writeDevice);
00666 }
00667 else
00668 {
00669 stringReturn = StringCbPrintf(szTempBuff,
00670 SMALL_BUFF,
00671 "Unable to parse line %x of output data",
00672 iErrorLine);
00673
00674 MessageBox(hDlg,
00675 szTempBuff,
00676 HCLIENT_ERROR,
00677 MB_ICONEXCLAMATION);
00678 }
00679 }
00680 CloseHidDevice(&writeDevice);
00681 }
00682
00683 }
00684 break;
00685
00686
00687
00688
00689
00690
00691
00692
00693 case IDC_DEVICES:
00694 switch (HIWORD(wParam))
00695 {
00696 case CBN_SELCHANGE:
00697
00698 GET_CURRENT_DEVICE(hDlg, pDevice);
00699
00700 EnableWindow(GetDlgItem(hDlg, IDC_READ),
00701 (pDevice != NULL) &&
00702 (pDevice -> Caps.InputReportByteLength));
00703
00704 EnableWindow(GetDlgItem(hDlg, IDC_WRITE),
00705 (pDevice != NULL) &&
00706 (pDevice -> Caps.OutputReportByteLength));
00707
00708 EnableWindow(GetDlgItem(hDlg, IDC_FEATURES),
00709 (pDevice != NULL) &&
00710 (pDevice -> Caps.FeatureReportByteLength));
00711
00712 PostMessage(hDlg,
00713 WM_COMMAND,
00714 IDC_TYPE + (CBN_SELCHANGE<<16),
00715 (LPARAM) GetDlgItem(hDlg,IDC_TYPE));
00716 break;
00717
00718 }
00719 break;
00720
00721
00722
00723
00724
00725
00726
00727 case IDC_TYPE:
00728 switch (HIWORD(wParam))
00729 {
00730 case CBN_SELCHANGE:
00731 GET_CURRENT_DEVICE(hDlg, pDevice);
00732
00733 SendDlgItemMessage(hDlg,
00734 IDC_ITEMS,
00735 LB_RESETCONTENT,
00736 0,
00737 0);
00738
00739 SendDlgItemMessage(hDlg,
00740 IDC_ATTRIBUTES,
00741 LB_RESETCONTENT,
00742 0,
00743 0);
00744
00745 if (NULL != pDevice)
00746 {
00747 iIndex = (INT) SendDlgItemMessage(hDlg,
00748 IDC_TYPE,
00749 CB_GETCURSEL,
00750 0,
00751 0);
00752
00753 iItemType = (INT) SendDlgItemMessage(hDlg,
00754 IDC_TYPE,
00755 CB_GETITEMDATA,
00756 iIndex,
00757 0);
00758
00759 switch (iItemType)
00760 {
00761 case INPUT_BUTTON:
00762 vDisplayInputButtons(pDevice,GetDlgItem(hDlg,IDC_ITEMS));
00763 break;
00764
00765 case INPUT_VALUE:
00766 vDisplayInputValues(pDevice,GetDlgItem(hDlg,IDC_ITEMS));
00767 break;
00768
00769 case OUTPUT_BUTTON:
00770 vDisplayOutputButtons(pDevice,GetDlgItem(hDlg,IDC_ITEMS));
00771 break;
00772
00773 case OUTPUT_VALUE:
00774 vDisplayOutputValues(pDevice,GetDlgItem(hDlg,IDC_ITEMS));
00775 break;
00776
00777 case FEATURE_BUTTON:
00778 vDisplayFeatureButtons(pDevice,GetDlgItem(hDlg,IDC_ITEMS));
00779 break;
00780
00781 case FEATURE_VALUE:
00782 vDisplayFeatureValues(pDevice,GetDlgItem(hDlg,IDC_ITEMS));
00783 break;
00784 }
00785
00786 PostMessage(hDlg,
00787 WM_COMMAND,
00788 IDC_ITEMS + (LBN_SELCHANGE << 16),
00789 (LPARAM) GetDlgItem(hDlg,IDC_ITEMS));
00790 }
00791 break;
00792
00793 }
00794 break;
00795
00796 case IDC_ITEMS:
00797 switch (HIWORD(wParam))
00798 {
00799 case LBN_SELCHANGE:
00800
00801 iItemType = 0;
00802
00803 iIndex = (INT) SendDlgItemMessage(hDlg,
00804 IDC_TYPE,
00805 CB_GETCURSEL,
00806 0,
00807 0);
00808
00809 if (-1 != iIndex)
00810 {
00811 iItemType = (INT) SendDlgItemMessage(hDlg,
00812 IDC_TYPE,
00813 CB_GETITEMDATA,
00814 iIndex,
00815 0);
00816 }
00817
00818 iIndex = (INT) SendDlgItemMessage(hDlg,
00819 IDC_ITEMS,
00820 LB_GETCURSEL,
00821 0,
00822 0);
00823
00824 switch (iItemType)
00825 {
00826 case INPUT_BUTTON:
00827 case OUTPUT_BUTTON:
00828 case FEATURE_BUTTON:
00829
00830 pButtonCaps = NULL;
00831
00832 if (-1 != iIndex)
00833 {
00834 pButtonCaps = (PHIDP_BUTTON_CAPS) SendDlgItemMessage(hDlg,
00835 IDC_ITEMS,
00836 LB_GETITEMDATA,
00837 iIndex,
00838 0);
00839 }
00840
00841 SendDlgItemMessage(hDlg, IDC_ATTRIBUTES, LB_RESETCONTENT, 0, 0);
00842 if (NULL != pButtonCaps)
00843 {
00844 vDisplayButtonAttributes(pButtonCaps, GetDlgItem(hDlg,IDC_ATTRIBUTES));
00845 }
00846 break;
00847
00848 case INPUT_VALUE:
00849 case OUTPUT_VALUE:
00850 case FEATURE_VALUE:
00851
00852 pValueCaps = NULL;
00853
00854 if (-1 != iIndex)
00855 {
00856 pValueCaps = (PHIDP_VALUE_CAPS) SendDlgItemMessage(hDlg,
00857 IDC_ITEMS,
00858 LB_GETITEMDATA,
00859 iIndex,
00860 0);
00861 }
00862
00863 SendDlgItemMessage(hDlg, IDC_ATTRIBUTES, LB_RESETCONTENT, 0, 0);
00864
00865 if (NULL != pValueCaps)
00866 {
00867 vDisplayValueAttributes(pValueCaps,GetDlgItem(hDlg,IDC_ATTRIBUTES));
00868 }
00869 break;
00870
00871 case HID_CAPS:
00872 GET_CURRENT_DEVICE(hDlg, pDevice);
00873
00874 if (NULL != pDevice)
00875 {
00876 vDisplayDeviceCaps(&(pDevice -> Caps),GetDlgItem(hDlg,IDC_ATTRIBUTES));
00877 }
00878 break;
00879
00880 case DEVICE_ATTRIBUTES:
00881 GET_CURRENT_DEVICE(hDlg, pDevice);
00882
00883 if (NULL != pDevice)
00884 {
00885 SendDlgItemMessage(hDlg, IDC_ATTRIBUTES, LB_RESETCONTENT, 0, 0);
00886
00887 vDisplayDeviceAttributes(&(pDevice -> Attributes) ,GetDlgItem(hDlg,IDC_ATTRIBUTES));
00888 }
00889 break;
00890
00891 }
00892 break;
00893
00894 }
00895 break;
00896
00897 case IDC_CHECK_LED1:
00898 case IDC_CHECK_LED2:
00899
00900
00901
00902 {
00903 int bst1 = (int)SendDlgItemMessage(hDlg, IDC_CHECK_LED1, BM_GETCHECK, 0, 0);
00904 int bst2 = (int)SendDlgItemMessage(hDlg, IDC_CHECK_LED2, BM_GETCHECK, 0, 0);
00905 BYTE tmpBuffer[64 * 6];
00906 DWORD bytesWritten;
00907
00908 GET_CURRENT_DEVICE(hDlg, pDevice);
00909
00910 if (NULL == pDevice) break;
00911 if (!OpenHidDevice(pDevice->DevicePath,
00912 FALSE, TRUE, FALSE, FALSE, &hidDevice) ) {
00913 MessageBox(hDlg, "Can not open HID Device!", "Err LED", MB_ICONSTOP);
00914 break;
00915 }
00916
00917 tmpBuffer[0] = 0;
00918 tmpBuffer[1] = 0x80;
00919 if (bst1) tmpBuffer[1] |= 0x01;
00920 if (bst2) tmpBuffer[1] |= 0x02;
00921 if (!WriteFile(hidDevice.HidDevice,
00922 tmpBuffer,
00923 hidDevice.Caps.OutputReportByteLength,
00924 &bytesWritten, NULL)) {
00925 MessageBox(hDlg, "Failed to write!", "Err LED", MB_ICONSTOP);
00926 CheckDlgButton(hDlg, LOWORD(wParam), BST_UNCHECKED);
00927 }
00928
00929 CloseHidDevice(&hidDevice);
00930 }
00931 break;
00932
00933 case IDC_BUTTON_WR:
00934 GET_CURRENT_DEVICE(hDlg, pDevice);
00935
00936 if (NULL != pDevice)
00937 {
00938 BYTE tmpBuffer[64 * 6];
00939 DWORD bytesWritten;
00940 int i;
00941 if (!OpenHidDevice(pDevice -> DevicePath,
00942 FALSE,
00943 TRUE,
00944 FALSE,
00945 FALSE,
00946 &hidDevice)) {
00947 MessageBox(hDlg, "Can not open HID device!", "Err Write", MB_ICONSTOP);
00948 break;
00949 }
00950 else {
00951
00952 tmpBuffer[0] = 0;
00953 SendDlgItemMessage(hDlg, IDC_EDIT_OUT, WM_GETTEXT, 64*6 - 1, (LPARAM)(&tmpBuffer[1]));
00954 if (!WriteFile(hidDevice.HidDevice,
00955 tmpBuffer,
00956 hidDevice.Caps.OutputReportByteLength,
00957 &bytesWritten,
00958 NULL)) {
00959 MessageBox(hDlg, "Failed to write!", "Err Write", MB_ICONSTOP);
00960 }
00961 }
00962 CloseHidDevice(&hidDevice);
00963 }
00964
00965 break;
00966
00967 case IDC_CHECK_MON:
00968 {
00969 int mon = (int)SendDlgItemMessage(hDlg, IDC_CHECK_MON, BM_GETCHECK, 0, 0);
00970
00971 if (mon == BST_CHECKED) {
00972
00973 GET_CURRENT_DEVICE(hDlg, pDevice);
00974 if (NULL == pDevice) break;
00975
00976 if (!OpenHidDevice(pDevice->DevicePath,
00977 TRUE, FALSE, FALSE, FALSE, &hidDevice)) {
00978 MessageBox(hDlg, "Can not open HID device!", "Err Monitor", MB_ICONSTOP);
00979 CheckDlgButton(hDlg, IDC_CHECK_MON, BST_UNCHECKED);
00980 break;
00981 }
00982
00983 EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_RD), FALSE);
00984
00985 readContext.HidDevice = pDevice;
00986 readContext.TerminateThread = FALSE;
00987 readContext.DoOneRead = FALSE;
00988 readContext.DisplayEvent = NULL;
00989 readContext.DisplayWindow = hDlg;
00990
00991 readThread = CreateThread(NULL,
00992 0,
00993 MyReadThreadProc,
00994 (LPVOID) &readContext,
00995 0,
00996 &threadID);
00997 if (NULL == readThread) {
00998 MessageBox(hDlg, "Fail to create read thread", "Err MON", MB_ICONEXCLAMATION);
00999 CloseHidDevice(&hidDevice);
01000 SendDlgItemMessage(hDlg, IDC_CHECK_MON, BM_SETCHECK, BST_UNCHECKED, 0);
01001 }
01002 }
01003 else {
01004 readContext.TerminateThread = TRUE;
01005 WaitForSingleObject(readThread, INFINITE);
01006 EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_RD), TRUE);
01007 CloseHidDevice(&hidDevice);
01008 }
01009 }
01010 break;
01011
01012 case IDC_BUTTON_RD:
01013 GET_CURRENT_DEVICE(hDlg, pDevice);
01014
01015 if (NULL != pDevice)
01016 {
01017 if (!OpenHidDevice(pDevice -> DevicePath,
01018 TRUE,
01019 FALSE,
01020 FALSE,
01021 FALSE,
01022 &hidDevice)) {
01023 MessageBox(hDlg, "Can not open HID device!", "Err GetReport", MB_ICONSTOP);
01024 break;
01025 }
01026 if (!Read(&hidDevice)) {
01027 MessageBox(hDlg, "Failed to read!", "Err read", MB_ICONSTOP);
01028 }
01029 else {
01030
01031 int i;
01032 char * pBuff = szTempBuff, tmpChar;
01033 for(i = 1; i <= hidDevice.Caps.InputReportByteLength; i ++) {
01034
01035 *pBuff ++ = HalfBtoHex(hidDevice.InputReportBuffer[i] >> 4);
01036 *pBuff ++ = HalfBtoHex(hidDevice.InputReportBuffer[i]);
01037 *pBuff ++ = ' ';
01038 }
01039 *pBuff = 0;
01040
01041 SendDlgItemMessage(hDlg, IDC_EDIT_IN, WM_SETTEXT, 0, (LPARAM)szTempBuff);
01042
01043
01044 if (hidDevice.InputReportBuffer[1] & 0x80) {
01045
01046 if (hidDevice.InputReportBuffer[1] & 0x01) {
01047 SendDlgItemMessage(hDlg, IDC_CHECK_BTN1, BM_SETCHECK, BST_CHECKED, 0);
01048 }
01049 else {
01050 SendDlgItemMessage(hDlg, IDC_CHECK_BTN1, BM_SETCHECK, BST_UNCHECKED, 0);
01051 }
01052 if (hidDevice.InputReportBuffer[1] & 0x02) {
01053 SendDlgItemMessage(hDlg, IDC_CHECK_BTN2, BM_SETCHECK, BST_CHECKED, 0);
01054 }
01055 else {
01056 SendDlgItemMessage(hDlg, IDC_CHECK_BTN2, BM_SETCHECK, BST_UNCHECKED, 0);
01057 }
01058 CheckDlgButton(hDlg,
01059 IDC_CHECK_LEFT,
01060 (hidDevice.InputReportBuffer[1] & 0x04) ?
01061 BST_CHECKED : BST_UNCHECKED);
01062 CheckDlgButton(hDlg,
01063 IDC_CHECK_UP,
01064 (hidDevice.InputReportBuffer[1] & 0x08) ?
01065 BST_CHECKED : BST_UNCHECKED);
01066 CheckDlgButton(hDlg,
01067 IDC_CHECK_DOWN,
01068 (hidDevice.InputReportBuffer[1] & 0x10) ?
01069 BST_CHECKED : BST_UNCHECKED);
01070 CheckDlgButton(hDlg,
01071 IDC_CHECK_RIGHT,
01072 (hidDevice.InputReportBuffer[1] & 0x20) ?
01073 BST_CHECKED : BST_UNCHECKED);
01074 }
01075 }
01076 CloseHidDevice(&hidDevice);
01077 }
01078 break;
01079
01080 case IDC_BUTTON_SET:
01081 GET_CURRENT_DEVICE(hDlg, pDevice);
01082
01083 if (NULL != pDevice)
01084 {
01085 BYTE tmpBuffer[64 * 6];
01086 if (!OpenHidDevice(pDevice -> DevicePath,
01087 FALSE,
01088 TRUE,
01089 FALSE,
01090 FALSE,
01091 &hidDevice)) {
01092 MessageBox(hDlg, "Can not open HID device!", "Err Write", MB_ICONSTOP);
01093 break;
01094 }
01095 else {
01096
01097 tmpBuffer[0] = 0;
01098 SendDlgItemMessage(hDlg, IDC_EDIT_OUT, WM_GETTEXT, 64 * 6 - 1, (LPARAM)(&tmpBuffer[1]));
01099 if (!HidD_SetOutputReport(hidDevice.HidDevice,
01100 tmpBuffer,
01101 hidDevice.Caps.OutputReportByteLength)) {
01102 MessageBox(hDlg, "Failed to set report!", "Err SetReport", MB_ICONSTOP);
01103 }
01104 }
01105 CloseHidDevice(&hidDevice);
01106 }
01107 break;
01108
01109 case IDC_BUTTON_GET:
01110 GET_CURRENT_DEVICE(hDlg, pDevice);
01111
01112 if (NULL != pDevice)
01113 {
01114 BYTE tmpBuffer[66];
01115 if (!OpenHidDevice(pDevice -> DevicePath,
01116 TRUE,
01117 FALSE,
01118 FALSE,
01119 FALSE,
01120 &hidDevice)) {
01121 MessageBox(hDlg, "Can not open HID device!", "Err GetReport", MB_ICONSTOP);
01122 break;
01123 }
01124
01125 tmpBuffer[0] = 0;
01126 if (!HidD_GetInputReport(hidDevice.HidDevice,
01127 tmpBuffer,
01128 hidDevice.Caps.InputReportByteLength)) {
01129 MessageBox(hDlg, "Failed to get report!", "Err GetReport", MB_ICONSTOP);
01130 }
01131 else {
01132
01133 int i;
01134 char * pBuff = szTempBuff, tmpChar;
01135 for(i = 1; i < hidDevice.Caps.InputReportByteLength; i ++) {
01136
01137 *pBuff ++ = HalfBtoHex(tmpBuffer[i] >> 4);
01138 *pBuff ++ = HalfBtoHex(tmpBuffer[i]);
01139 *pBuff ++ = ' ';
01140 }
01141 *pBuff = 0;
01142
01143 SendDlgItemMessage(hDlg, IDC_EDIT_IN, WM_SETTEXT, 0, (LPARAM)szTempBuff);
01144 }
01145 CloseHidDevice(&hidDevice);
01146 }
01147 break;
01148
01149 case IDC_ABOUT:
01150
01151 MessageBox(hDlg,
01152 "Sample HID Test Application\nBased on MS DDK - hClient",
01153 "About HID Test",
01154 MB_ICONINFORMATION);
01155 break;
01156
01157 case IDOK:
01158 case IDCANCEL:
01159
01160
01161
01162
01163
01164 DestroyListWithCallback(&PhysicalDeviceList, DestroyDeviceListCallback);
01165
01166 EndDialog(hDlg,0);
01167
01168 break;
01169
01170 }
01171 break;
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200 case WM_DEVICECHANGE:
01201 switch (wParam)
01202 {
01203 PDEV_BROADCAST_HDR broadcastHdr;
01204
01205 case DBT_DEVICEARRIVAL:
01206
01207 broadcastHdr = (PDEV_BROADCAST_HDR) lParam;
01208
01209 if (DBT_DEVTYP_DEVICEINTERFACE == broadcastHdr -> dbch_devicetype)
01210 {
01211 PDEV_BROADCAST_DEVICEINTERFACE pbroadcastInterface;
01212 PDEVICE_LIST_NODE currNode, lastNode;
01213
01214 pbroadcastInterface = (PDEV_BROADCAST_DEVICEINTERFACE) lParam;
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224 if (!IsListEmpty(&PhysicalDeviceList))
01225 {
01226 currNode = (PDEVICE_LIST_NODE) GetListHead(&PhysicalDeviceList);
01227 lastNode = (PDEVICE_LIST_NODE) GetListTail(&PhysicalDeviceList);
01228
01229
01230
01231
01232
01233
01234 while (1)
01235 {
01236 if (0 == strcmp(currNode -> HidDeviceInfo.DevicePath,
01237 pbroadcastInterface -> dbcc_name))
01238 {
01239 return (TRUE);
01240 }
01241
01242 if (currNode == lastNode)
01243 {
01244 break;
01245 }
01246
01247 currNode = (PDEVICE_LIST_NODE) GetNextEntry(currNode);
01248 }
01249 }
01250
01251
01252
01253
01254
01255
01256
01257 listNode = (PDEVICE_LIST_NODE) malloc(sizeof(DEVICE_LIST_NODE));
01258
01259 if (NULL == listNode)
01260 {
01261 MessageBox(hDlg,
01262 "Error -- Couldn't allocate memory for new device list node",
01263 HCLIENT_ERROR,
01264 MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL);
01265
01266 break;
01267
01268 }
01269
01270
01271
01272
01273
01274 if (!OpenHidDevice (pbroadcastInterface -> dbcc_name,
01275 FALSE,
01276 FALSE,
01277 FALSE,
01278 FALSE,
01279 &(listNode -> HidDeviceInfo)))
01280 {
01281
01282 MessageBox(hDlg,
01283 "Error -- Couldn't open HID device",
01284 HCLIENT_ERROR,
01285 MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL);
01286
01287 free(listNode);
01288
01289 break;
01290 }
01291
01292 if (!RegisterHidDevice(hDlg, listNode))
01293 {
01294 MessageBox(hDlg,
01295 "Error -- Couldn't register handle notification",
01296 HCLIENT_ERROR,
01297 MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL);
01298
01299 CloseHidDevice(&(listNode -> HidDeviceInfo));
01300
01301 free(listNode);
01302
01303 break;
01304
01305 }
01306
01307 listNode -> DeviceOpened = TRUE;
01308
01309 InsertTail(&PhysicalDeviceList, listNode);
01310
01311 vLoadDevices(GetDlgItem(hDlg,IDC_DEVICES));
01312
01313 PostMessage(hDlg,
01314 WM_COMMAND,
01315 IDC_DEVICES + (CBN_SELCHANGE << 16),
01316 (LPARAM) GetDlgItem(hDlg,IDC_DEVICES));
01317
01318 }
01319 break;
01320
01321 case DBT_DEVICEQUERYREMOVE:
01322
01323
01324
01325
01326
01327
01328
01329
01330 broadcastHdr = (PDEV_BROADCAST_HDR) lParam;
01331
01332 if (DBT_DEVTYP_HANDLE == broadcastHdr -> dbch_devicetype)
01333 {
01334 PDEV_BROADCAST_HANDLE broadcastHandle;
01335 PDEVICE_LIST_NODE currNode;
01336 HANDLE deviceHandle;
01337
01338 broadcastHandle = (PDEV_BROADCAST_HANDLE) lParam;
01339
01340
01341
01342
01343
01344
01345 deviceHandle = (HANDLE) broadcastHandle -> dbch_handle;
01346
01347
01348
01349
01350
01351
01352 currNode = (PDEVICE_LIST_NODE) GetListHead(&PhysicalDeviceList);
01353
01354
01355
01356
01357
01358
01359 while (currNode -> HidDeviceInfo.HidDevice != deviceHandle)
01360 {
01361 currNode = (PDEVICE_LIST_NODE) GetNextEntry(currNode);
01362 }
01363
01364 CloseHidDevice(&(currNode -> HidDeviceInfo));
01365
01366 currNode -> DeviceOpened = FALSE;
01367 }
01368 return (TRUE);
01369
01370 case DBT_DEVICEREMOVEPENDING:
01371 case DBT_DEVICEREMOVECOMPLETE:
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383 broadcastHdr = (PDEV_BROADCAST_HDR) lParam;
01384
01385 if (DBT_DEVTYP_HANDLE == broadcastHdr -> dbch_devicetype)
01386 {
01387 PDEV_BROADCAST_HANDLE broadcastHandle;
01388 PDEVICE_LIST_NODE currNode;
01389 HANDLE deviceHandle;
01390
01391 broadcastHandle = (PDEV_BROADCAST_HANDLE) lParam;
01392
01393
01394
01395
01396
01397
01398 deviceHandle = (HANDLE) broadcastHandle -> dbch_handle;
01399
01400
01401
01402
01403
01404
01405 currNode = (PDEVICE_LIST_NODE) GetListHead(&PhysicalDeviceList);
01406
01407
01408
01409
01410
01411
01412 while (currNode -> HidDeviceInfo.HidDevice != deviceHandle)
01413 {
01414 currNode = (PDEVICE_LIST_NODE) GetNextEntry(currNode);
01415 }
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426 PostMessage(hDlg,
01427 WM_UNREGISTER_HANDLE,
01428 0,
01429 (LPARAM) currNode -> NotificationHandle);
01430
01431
01432
01433
01434
01435
01436 if (currNode -> DeviceOpened)
01437 {
01438 CloseHidDevice(&(currNode -> HidDeviceInfo));
01439 }
01440
01441 RemoveNode(currNode);
01442
01443 free(currNode);
01444
01445
01446
01447
01448
01449 vLoadDevices(GetDlgItem(hDlg,IDC_DEVICES));
01450
01451 PostMessage(hDlg,
01452 WM_COMMAND,
01453 IDC_DEVICES + (CBN_SELCHANGE << 16),
01454 (LPARAM) GetDlgItem(hDlg,IDC_DEVICES));
01455 }
01456 break;
01457
01458 default:
01459 break;
01460 }
01461 break;
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473 case WM_UNREGISTER_HANDLE:
01474 UnregisterDeviceNotification ( (HDEVNOTIFY) lParam );
01475 break;
01476
01477 }
01478 return FALSE;
01479 }
01480
01481
01482 BOOL
01483 bParseData(
01484 PHID_DATA pData,
01485 rWriteDataStruct rWriteData[],
01486 int iCount,
01487 int *piErrorLine
01488 )
01489 {
01490 INT iCap;
01491 PHID_DATA pWalk;
01492 BOOL noError = TRUE;
01493
01494 pWalk = pData;
01495
01496 for (iCap = 0; (iCap < iCount) && noError; iCap++)
01497 {
01498
01499
01500
01501
01502 if (!pWalk->IsButtonData)
01503 {
01504 pWalk -> ValueData.Value = atol(rWriteData[iCap].szValue);
01505 }
01506 else
01507 {
01508 if (!bSetButtonUsages(pWalk, rWriteData[iCap].szValue) )
01509 {
01510 *piErrorLine = iCap;
01511
01512 noError = FALSE;
01513 }
01514 }
01515 pWalk++;
01516 }
01517 return (noError);
01518 }
01519
01520 BOOL
01521 bSetButtonUsages(
01522 PHID_DATA pCap,
01523 PCHAR pszInputString
01524 )
01525 {
01526 CHAR szTempString[SMALL_BUFF];
01527 CHAR pszDelimiter[] = " ";
01528 PCHAR pszToken;
01529 INT iLoop;
01530 PUSAGE pUsageWalk;
01531 BOOL bNoError=TRUE;
01532 HRESULT stringReturn;
01533
01534 stringReturn = StringCbCopy(szTempString, SMALL_BUFF, pszInputString);
01535
01536 pszToken = strtok(szTempString, pszDelimiter);
01537
01538 pUsageWalk = pCap -> ButtonData.Usages;
01539
01540 memset(pUsageWalk, 0, pCap->ButtonData.MaxUsageLength * sizeof(USAGE));
01541
01542 for (iLoop = 0; ((ULONG) iLoop < pCap->ButtonData.MaxUsageLength) && (pszToken != NULL) && bNoError; iLoop++)
01543 {
01544 *pUsageWalk = (USAGE) atoi(pszToken);
01545
01546 pszToken = strtok(NULL, pszDelimiter);
01547
01548 pUsageWalk++;
01549 }
01550
01551 return bNoError;
01552 }
01553
01554
01555 INT
01556 iPrepareDataFields(
01557 PHID_DATA pData,
01558 ULONG ulDataLength,
01559 rWriteDataStruct rWriteData[],
01560 int iMaxElements
01561 )
01562 {
01563 INT i;
01564 PHID_DATA pWalk;
01565 HRESULT stringReturn;
01566
01567 pWalk = pData;
01568
01569 for (i = 0; (i < iMaxElements) && ((unsigned) i < ulDataLength); i++)
01570 {
01571 if (!pWalk->IsButtonData)
01572 {
01573 stringReturn = StringCbPrintf(rWriteData[i].szLabel,
01574 MAX_LABEL,
01575 "ValueCap; ReportID: 0x%x, UsagePage=0x%x, Usage=0x%x",
01576 pWalk->ReportID,
01577 pWalk->UsagePage,
01578 pWalk->ValueData.Usage);
01579 }
01580 else
01581 {
01582 stringReturn = StringCbPrintf(rWriteData[i].szLabel,
01583 MAX_LABEL,
01584 "Button; ReportID: 0x%x, UsagePage=0x%x, UsageMin: 0x%x, UsageMax: 0x%x",
01585 pWalk->ReportID,
01586 pWalk->UsagePage,
01587 pWalk->ButtonData.UsageMin,
01588 pWalk->ButtonData.UsageMax);
01589 }
01590 pWalk++;
01591 }
01592 return i;
01593 }
01594
01595
01596 INT_PTR CALLBACK
01597 bReadDlgProc(
01598 HWND hDlg,
01599 UINT message,
01600 WPARAM wParam,
01601 LPARAM lParam
01602 )
01603 {
01604 static INT iLbCounter;
01605 static CHAR szTempBuff[1024];
01606 static READ_THREAD_CONTEXT readContext;
01607 static HANDLE readThread;
01608 static HID_DEVICE syncDevice;
01609 static HID_DEVICE asyncDevice;
01610 static BOOL doAsyncReads;
01611 static BOOL doSyncReads;
01612
01613 PHID_DEVICE pDevice;
01614 DWORD threadID;
01615 INT iIndex;
01616 PHID_DATA pData;
01617 UINT uLoop;
01618
01619
01620 switch (message)
01621 {
01622 case WM_INITDIALOG:
01623
01624
01625
01626
01627
01628
01629 iLbCounter = 0;
01630 readThread = NULL;
01631 readContext.DisplayEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
01632
01633 if (NULL == readContext.DisplayEvent)
01634 {
01635 EndDialog(hDlg, 0);
01636 }
01637
01638
01639
01640
01641
01642
01643 pDevice = (PHID_DEVICE) lParam;
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653 doSyncReads = OpenHidDevice(pDevice -> DevicePath,
01654 TRUE,
01655 FALSE,
01656 FALSE,
01657 FALSE,
01658 &syncDevice);
01659
01660 if (!doSyncReads)
01661 {
01662 MessageBox(hDlg,
01663 "Unable to open device for synchronous reading",
01664 HCLIENT_ERROR,
01665 MB_ICONEXCLAMATION);
01666 }
01667
01668
01669
01670
01671
01672
01673
01674
01675 doAsyncReads = OpenHidDevice(pDevice -> DevicePath,
01676 TRUE,
01677 FALSE,
01678 TRUE,
01679 FALSE,
01680 &asyncDevice);
01681
01682 if (!doAsyncReads)
01683 {
01684 MessageBox(hDlg,
01685 "Unable to open device for asynchronous reading",
01686 HCLIENT_ERROR,
01687 MB_ICONEXCLAMATION);
01688 }
01689
01690 PostMessage(hDlg, WM_READ_DONE, 0, 0);
01691 break;
01692
01693 case WM_DISPLAY_READ_DATA:
01694
01695
01696
01697
01698
01699 pDevice = (PHID_DEVICE) lParam;
01700
01701
01702
01703
01704
01705 pData = pDevice -> InputData;
01706
01707 SendDlgItemMessage(hDlg,
01708 IDC_OUTPUT,
01709 LB_ADDSTRING,
01710 0,
01711 (LPARAM)"-------------------------------------------");
01712
01713 iLbCounter++;
01714
01715 if (iLbCounter > MAX_LB_ITEMS)
01716 {
01717 SendDlgItemMessage(hDlg,
01718 IDC_OUTPUT,
01719 LB_DELETESTRING,
01720 0,
01721 0);
01722 }
01723
01724 for (uLoop = 0; uLoop < pDevice->InputDataLength; uLoop++)
01725 {
01726 ReportToString(pData, szTempBuff, sizeof(szTempBuff));
01727
01728 iIndex = (INT) SendDlgItemMessage(hDlg,
01729 IDC_OUTPUT,
01730 LB_ADDSTRING,
01731 0,
01732 (LPARAM) szTempBuff);
01733
01734 SendDlgItemMessage(hDlg,
01735 IDC_OUTPUT,
01736 LB_SETCURSEL,
01737 iIndex,
01738 0);
01739
01740 iLbCounter++;
01741
01742 if (iLbCounter > MAX_LB_ITEMS)
01743 {
01744 SendDlgItemMessage(hDlg,
01745 IDC_OUTPUT,
01746 LB_DELETESTRING,
01747 0,
01748 0);
01749 }
01750 pData++;
01751 }
01752 SetEvent( readContext.DisplayEvent );
01753 break;
01754
01755 case WM_READ_DONE:
01756 EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
01757 EnableWindow(GetDlgItem(hDlg, IDC_READ_SYNCH), doSyncReads);
01758 EnableWindow(GetDlgItem(hDlg, IDC_READ_ASYNCH_ONCE), doAsyncReads);
01759 EnableWindow(GetDlgItem(hDlg, IDC_READ_ASYNCH_CONT), doAsyncReads);
01760
01761 SetWindowText(GetDlgItem(hDlg, IDC_READ_ASYNCH_ONCE),
01762 "One Asynchronous Read");
01763
01764 SetWindowText(GetDlgItem(hDlg, IDC_READ_ASYNCH_CONT),
01765 "Continuous Asynchronous Read");
01766
01767 readThread = NULL;
01768 break;
01769
01770 case WM_COMMAND:
01771 switch (LOWORD(wParam))
01772 {
01773 case IDC_READ_SYNCH:
01774
01775 EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
01776 EnableWindow(GetDlgItem(hDlg, IDC_READ_SYNCH), FALSE);
01777 EnableWindow(GetDlgItem(hDlg, IDC_READ_ASYNCH_ONCE), FALSE);
01778 EnableWindow(GetDlgItem(hDlg, IDC_READ_ASYNCH_CONT), FALSE);
01779
01780 Read(&syncDevice);
01781
01782 PostMessage(hDlg, WM_DISPLAY_READ_DATA, 0, (LPARAM) &syncDevice);
01783 PostMessage(hDlg, WM_READ_DONE, 0, 0);
01784
01785 break;
01786
01787 case IDC_READ_ASYNCH_ONCE:
01788 case IDC_READ_ASYNCH_CONT:
01789
01790
01791
01792
01793
01794
01795
01796 if (NULL == readThread)
01797 {
01798
01799
01800
01801
01802 readContext.HidDevice = &asyncDevice;
01803 readContext.TerminateThread = FALSE;
01804 readContext.DoOneRead = (IDC_READ_ASYNCH_ONCE == LOWORD(wParam));
01805 readContext.DisplayWindow = hDlg;
01806
01807 readThread = CreateThread( NULL,
01808 0,
01809 AsynchReadThreadProc,
01810 &readContext,
01811 0,
01812 &threadID);
01813
01814 if (NULL == readThread)
01815 {
01816 MessageBox(hDlg,
01817 "Unable to create read thread",
01818 HCLIENT_ERROR,
01819 MB_ICONEXCLAMATION);
01820 }
01821 else
01822 {
01823 EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
01824 EnableWindow(GetDlgItem(hDlg, IDC_READ_SYNCH), FALSE);
01825 EnableWindow(GetDlgItem(hDlg, IDC_READ_ASYNCH_ONCE),
01826 IDC_READ_ASYNCH_ONCE == LOWORD(wParam));
01827
01828 EnableWindow(GetDlgItem(hDlg, IDC_READ_ASYNCH_CONT),
01829 IDC_READ_ASYNCH_CONT == LOWORD(wParam));
01830
01831 SetWindowText(GetDlgItem(hDlg, LOWORD(wParam)),
01832 "Stop Asynchronous Read");
01833 }
01834 }
01835 else
01836 {
01837
01838
01839
01840
01841
01842 readContext.TerminateThread = TRUE;
01843 WaitForSingleObject(readThread, INFINITE);
01844 }
01845 break;
01846
01847 case IDCANCEL:
01848 readContext.TerminateThread = TRUE;
01849 WaitForSingleObject(readThread, INFINITE);
01850
01851
01852 case IDOK:
01853 CloseHidDevice(&asyncDevice);
01854 EndDialog(hDlg,0);
01855 break;
01856 }
01857 break;
01858 }
01859 return FALSE;
01860 }
01861
01862 VOID
01863 ReportToString(
01864 PHID_DATA pData,
01865 PCHAR szBuff,
01866 UINT iBuffSize
01867 )
01868 {
01869 PCHAR pszWalk;
01870 PUSAGE pUsage;
01871 ULONG i;
01872 UINT iRemainingBuffer;
01873 UINT iStringLength;
01874 HRESULT stringReturn;
01875
01876
01877
01878
01879
01880 if (pData -> IsButtonData)
01881 {
01882 stringReturn = StringCbPrintf (szBuff,
01883 iBuffSize,
01884 "Usage Page: 0x%x, Usages: ",
01885 pData -> UsagePage);
01886
01887 iRemainingBuffer = 0;
01888 iStringLength = strlen(szBuff);
01889 pszWalk = szBuff + iStringLength;
01890 if (iStringLength < iBuffSize)
01891 {
01892 iRemainingBuffer = iBuffSize - iStringLength;
01893 }
01894
01895
01896 for (i = 0, pUsage = pData -> ButtonData.Usages;
01897 i < pData -> ButtonData.MaxUsageLength;
01898 i++, pUsage++)
01899 {
01900 if (0 == *pUsage)
01901 {
01902 break;
01903 }
01904 stringReturn = StringCbPrintf (pszWalk, iRemainingBuffer, " 0x%x", *pUsage);
01905 iRemainingBuffer -= strlen(pszWalk);
01906 pszWalk += strlen(pszWalk);
01907 }
01908 }
01909 else
01910 {
01911 stringReturn = StringCbPrintf (szBuff,
01912 iBuffSize,
01913 "Usage Page: 0x%x, Usage: 0x%x, Scaled: %d Value: %d",
01914 pData->UsagePage,
01915 pData->ValueData.Usage,
01916 pData->ValueData.ScaledValue,
01917 pData->ValueData.Value);
01918 }
01919 }
01920
01921 INT_PTR CALLBACK
01922 bFeatureDlgProc(
01923 HWND hDlg,
01924 UINT message,
01925 WPARAM wParam,
01926 LPARAM lParam
01927 )
01928 {
01929 static PHID_DEVICE pDevice;
01930 static INT iLbCounter;
01931 static rWriteDataStruct rWriteData[MAX_WRITE_ELEMENTS];
01932 static CHAR szTempBuff[1024];
01933 INT iIndex;
01934 INT iCount;
01935 INT iErrorLine;
01936 PHID_DATA pData;
01937 UINT uLoop;
01938 HRESULT stringReturn;
01939
01940 switch (message)
01941 {
01942 case WM_INITDIALOG:
01943 iLbCounter = 0;
01944 pDevice = (PHID_DEVICE) lParam;
01945 break;
01946
01947 case WM_COMMAND:
01948 switch (LOWORD(wParam))
01949 {
01950 case IDC_READ:
01951
01952 GetFeature(pDevice);
01953
01954 pData = pDevice -> FeatureData;
01955
01956 SendDlgItemMessage(hDlg,
01957 IDC_OUTPUT,
01958 LB_ADDSTRING,
01959 0,
01960 (LPARAM)"------------ Read Features ---------------");
01961
01962 iLbCounter++;
01963
01964 if (iLbCounter > MAX_LB_ITEMS)
01965 {
01966 SendDlgItemMessage(hDlg,
01967 IDC_OUTPUT,
01968 LB_DELETESTRING,
01969 0,
01970 0);
01971 }
01972
01973 for (uLoop = 0; uLoop < pDevice -> FeatureDataLength; uLoop++)
01974 {
01975 ReportToString(pData, szTempBuff, sizeof(szTempBuff));
01976
01977 iIndex = (INT) SendDlgItemMessage(hDlg,
01978 IDC_OUTPUT,
01979 LB_ADDSTRING,
01980 0,
01981 (LPARAM) szTempBuff);
01982
01983 SendDlgItemMessage(hDlg,
01984 IDC_OUTPUT,
01985 LB_SETCURSEL,
01986 iIndex,
01987 (LPARAM) 0);
01988
01989 iLbCounter++;
01990 if (iLbCounter > MAX_LB_ITEMS)
01991 {
01992 SendDlgItemMessage(hDlg,
01993 IDC_OUTPUT,
01994 LB_DELETESTRING,
01995 0,
01996 0);
01997 }
01998 pData++;
01999 }
02000 break;
02001
02002 case IDC_WRITE:
02003 iCount = iPrepareDataFields(pDevice -> FeatureData,
02004 pDevice -> FeatureDataLength,
02005 rWriteData,
02006 MAX_OUTPUT_ELEMENTS);
02007
02008 if (bGetData(rWriteData, iCount, hDlg, "WRITEFEATURE"))
02009 {
02010 if (!bParseData(pDevice -> FeatureData, rWriteData,iCount, &iErrorLine))
02011 {
02012 stringReturn = StringCbPrintf(szTempBuff,
02013 sizeof(szTempBuff),
02014 "Unable to parse line %x of output data",
02015 iErrorLine);
02016
02017 MessageBox(hDlg,
02018 szTempBuff,
02019 HCLIENT_ERROR,
02020 MB_ICONEXCLAMATION);
02021 }
02022 else
02023 {
02024 if ( SetFeature(pDevice) )
02025 {
02026 SendDlgItemMessage(hDlg,
02027 IDC_OUTPUT,
02028 LB_ADDSTRING,
02029 0,
02030 (LPARAM)"------------ Write Feature ---------------");
02031 }
02032 else
02033 {
02034 SendDlgItemMessage(hDlg,
02035 IDC_OUTPUT,
02036 LB_ADDSTRING,
02037 0,
02038 (LPARAM)"------------ Write Feature Error ---------------");
02039 }
02040 }
02041 }
02042 break;
02043
02044 case IDOK:
02045 case IDCANCEL:
02046 EndDialog(hDlg,0);
02047 break;
02048 }
02049 break;
02050 }
02051 return FALSE;
02052 }
02053
02054 VOID
02055 vDisplayDeviceCaps(
02056 IN PHIDP_CAPS pCaps,
02057 IN HWND hControl
02058 )
02059 {
02060 static CHAR szTempBuff[SMALL_BUFF];
02061 HRESULT stringReturn;
02062
02063 SendMessage(hControl, LB_RESETCONTENT, 0, 0);
02064
02065 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Usage Page: 0x%x", pCaps -> UsagePage);
02066 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02067
02068 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Usage: 0x%x",pCaps -> Usage);
02069 SendMessage(hControl,LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02070
02071 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Input report byte length: %d",pCaps -> InputReportByteLength);
02072 SendMessage(hControl,LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02073
02074 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Output report byte length: %d",pCaps -> OutputReportByteLength);
02075 SendMessage(hControl,LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02076
02077 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Feature report byte length: %d",pCaps -> FeatureReportByteLength);
02078 SendMessage(hControl,LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02079
02080 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Number of collection nodes %d: ", pCaps -> NumberLinkCollectionNodes);
02081 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02082
02083 return;
02084 }
02085
02086 VOID
02087 vDisplayDeviceAttributes(
02088 PHIDD_ATTRIBUTES pAttrib,
02089 HWND hControl
02090 )
02091 {
02092 static CHAR szTempBuff[SMALL_BUFF];
02093 HRESULT stringReturn;
02094
02095 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Vendor ID: 0x%x", pAttrib -> VendorID);
02096 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02097
02098 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Product ID: 0x%x", pAttrib -> ProductID);
02099 SendMessage(hControl, LB_ADDSTRING, 0,(LPARAM) szTempBuff);
02100
02101 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Version Number 0x%x", pAttrib -> VersionNumber);
02102 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02103
02104 return;
02105 }
02106
02107 VOID
02108 vDisplayDataAttributes(
02109 PHIDP_DATA pData,
02110 BOOL IsButton,
02111 HWND hControl
02112 )
02113 {
02114 static CHAR szTempBuff[SMALL_BUFF];
02115 HRESULT stringReturn;
02116
02117 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) "================");
02118
02119 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Index: 0x%x", pData -> DataIndex);
02120 SendMessage(hControl,LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02121
02122 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "IsButton: %s", IsButton ? "TRUE" : "FALSE");
02123 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02124
02125 if (IsButton)
02126 {
02127 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Button pressed: %s", pData -> On ? "TRUE" : "FALSE");
02128 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02129 }
02130 else
02131 {
02132 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Data value: 0x%x", pData -> RawValue);
02133 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02134 }
02135 }
02136
02137 VOID
02138 vDisplayButtonAttributes(
02139 IN PHIDP_BUTTON_CAPS pButton,
02140 IN HWND hControl
02141 )
02142 {
02143 static CHAR szTempBuff[SMALL_BUFF];
02144 HRESULT stringReturn;
02145
02146 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Report ID: 0x%x", pButton->ReportID);
02147 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02148
02149 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Usage Page: 0x%x", pButton->UsagePage);
02150 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02151
02152 stringReturn = StringCbPrintf(szTempBuff,
02153 SMALL_BUFF,
02154 "Alias: %s",
02155 pButton -> IsAlias ? "TRUE" : "FALSE");
02156
02157 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02158
02159 stringReturn = StringCbPrintf(szTempBuff,
02160 SMALL_BUFF,
02161 "Link Collection: %hu",
02162 pButton -> LinkCollection);
02163
02164 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02165
02166 stringReturn = StringCbPrintf(szTempBuff,
02167 SMALL_BUFF,
02168 "Link Usage Page: 0x%x",
02169 pButton -> LinkUsagePage);
02170
02171 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02172
02173 stringReturn = StringCbPrintf(szTempBuff,
02174 SMALL_BUFF,
02175 "Link Usage: 0x%x",
02176 pButton -> LinkUsage);
02177
02178 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02179
02180 if (pButton->IsRange)
02181 {
02182 stringReturn = StringCbPrintf(szTempBuff,
02183 SMALL_BUFF,
02184 "Usage Min: 0x%x, Usage Max: 0x%x",
02185 pButton->Range.UsageMin,
02186 pButton->Range.UsageMax);
02187 }
02188 else
02189 {
02190 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Usage: 0x%x",pButton->NotRange.Usage);
02191
02192 }
02193 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02194
02195 if (pButton->IsRange)
02196 {
02197 stringReturn = StringCbPrintf(szTempBuff,
02198 SMALL_BUFF,
02199 "Data Index Min: 0x%x, Data Index Max: 0x%x",
02200 pButton->Range.DataIndexMin,
02201 pButton->Range.DataIndexMax);
02202
02203 }
02204 else
02205 {
02206 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "DataIndex: 0x%x",pButton->NotRange.DataIndex);
02207 }
02208
02209 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02210
02211 if (pButton->IsStringRange)
02212 {
02213 stringReturn = StringCbPrintf(szTempBuff,
02214 SMALL_BUFF,
02215 "String Min: 0x%x, String Max: 0x%x",
02216 pButton->Range.StringMin,
02217 pButton->Range.StringMax);
02218 }
02219 else
02220 {
02221 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "String Index: 0x%x",pButton->NotRange.StringIndex);
02222 }
02223 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02224
02225 if (pButton->IsDesignatorRange)
02226 {
02227 stringReturn = StringCbPrintf(szTempBuff,
02228 SMALL_BUFF,
02229 "Designator Min: 0x%x, Designator Max: 0x%x",
02230 pButton->Range.DesignatorMin,
02231 pButton->Range.DesignatorMax);
02232
02233 }
02234 else
02235 {
02236 stringReturn = StringCbPrintf(szTempBuff,
02237 SMALL_BUFF,
02238 "Designator Index: 0x%x",
02239 pButton->NotRange.DesignatorIndex);
02240 }
02241 SendMessage(hControl, LB_ADDSTRING, 0,(LPARAM) szTempBuff);
02242
02243 if (pButton->IsAbsolute)
02244 {
02245 SendMessage(hControl, LB_ADDSTRING,0, (LPARAM) "Absolute: Yes");
02246 }
02247 else
02248 {
02249 SendMessage(hControl, LB_ADDSTRING,0, (LPARAM) "Absolute: No");
02250 }
02251 return;
02252 }
02253
02254 VOID
02255 vDisplayValueAttributes(
02256 IN PHIDP_VALUE_CAPS pValue,
02257 HWND hControl
02258 )
02259 {
02260 static CHAR szTempBuff[SMALL_BUFF];
02261 HRESULT stringReturn;
02262
02263 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Report ID 0x%x", pValue->ReportID);
02264 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02265
02266 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Usage Page: 0x%x", pValue->UsagePage);
02267 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02268
02269 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Bit size: 0x%x", pValue->BitSize);
02270 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02271
02272 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Report Count: 0x%x", pValue->ReportCount);
02273 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02274
02275 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Unit Exponent: 0x%x", pValue->UnitsExp);
02276 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02277
02278 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Has Null: 0x%x", pValue->HasNull);
02279 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02280
02281
02282 if (pValue->IsAlias)
02283 {
02284 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Alias");
02285 }
02286 else
02287 {
02288 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "=====");
02289 }
02290 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02291
02292 if (pValue->IsRange)
02293 {
02294 stringReturn = StringCbPrintf(szTempBuff,
02295 SMALL_BUFF,
02296 "Usage Min: 0x%x, Usage Max 0x%x",
02297 pValue->Range.UsageMin,
02298 pValue->Range.UsageMax);
02299 }
02300 else
02301 {
02302 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Usage: 0x%x", pValue -> NotRange.Usage);
02303 }
02304 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02305
02306 if (pValue->IsRange)
02307 {
02308 stringReturn = StringCbPrintf(szTempBuff,
02309 SMALL_BUFF,
02310 "Data Index Min: 0x%x, Data Index Max: 0x%x",
02311 pValue->Range.DataIndexMin,
02312 pValue->Range.DataIndexMax);
02313 }
02314 else
02315 {
02316 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "DataIndex: 0x%x", pValue->NotRange.DataIndex);
02317 }
02318 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02319
02320 stringReturn = StringCbPrintf(szTempBuff,
02321 SMALL_BUFF,
02322 "Physical Minimum: %d, Physical Maximum: %d",
02323 pValue->PhysicalMin,
02324 pValue->PhysicalMax);
02325
02326 SendMessage(hControl, LB_ADDSTRING, 0,(LPARAM) szTempBuff);
02327
02328 stringReturn = StringCbPrintf(szTempBuff,
02329 SMALL_BUFF,
02330 "Logical Minimum: 0x%x, Logical Maximum: 0x%x",
02331 pValue->LogicalMin,
02332 pValue->LogicalMax);
02333
02334 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02335
02336 if (pValue->IsStringRange)
02337 {
02338 stringReturn = StringCbPrintf(szTempBuff,
02339 SMALL_BUFF,
02340 "String Min: 0x%x String Max 0x%x",
02341 pValue->Range.StringMin,
02342 pValue->Range.StringMax);
02343 }
02344 else
02345 {
02346 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "String Index: 0x%x",pValue->NotRange.StringIndex);
02347 }
02348 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02349
02350 if (pValue->IsDesignatorRange)
02351 {
02352 stringReturn = StringCbPrintf(szTempBuff,
02353 SMALL_BUFF,
02354 "Designator Minimum: 0x%x, Max: 0x%x",
02355 pValue->Range.DesignatorMin,
02356 pValue->Range.DesignatorMax);
02357 }
02358 else
02359 {
02360 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Designator Index: 0x%x",pValue->NotRange.DesignatorIndex);
02361 }
02362 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02363
02364 if (pValue->IsAbsolute)
02365 {
02366 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) "Absolute: Yes");
02367 }
02368 else
02369 {
02370 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) "Absolute: No");
02371 }
02372 return;
02373 }
02374
02375 VOID
02376 vDisplayInputButtons(
02377 IN PHID_DEVICE pDevice,
02378 IN HWND hControl
02379 )
02380 {
02381 INT iLoop;
02382 PHIDP_BUTTON_CAPS pButtonCaps;
02383 static CHAR szTempBuff[SMALL_BUFF];
02384 INT iIndex;
02385 HRESULT stringReturn;
02386
02387 SendMessage(hControl, LB_RESETCONTENT, 0, (LPARAM) 0);
02388
02389 pButtonCaps = pDevice->InputButtonCaps;
02390 for (iLoop = 0; iLoop < pDevice->Caps.NumberInputButtonCaps; iLoop++)
02391 {
02392 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Input button cap # %d", iLoop);
02393
02394 iIndex = (INT) SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02395
02396 if (-1 != iIndex)
02397 {
02398 SendMessage(hControl, LB_SETITEMDATA, iIndex,(LPARAM) pButtonCaps);
02399 }
02400
02401 pButtonCaps++;
02402 }
02403 SendMessage(hControl, LB_SETCURSEL, 0, 0 );
02404 }
02405
02406 VOID
02407 vDisplayOutputButtons(
02408 IN PHID_DEVICE pDevice,
02409 IN HWND hControl
02410 )
02411 {
02412 INT iLoop;
02413 static CHAR szTempBuff[SMALL_BUFF];
02414 INT iIndex;
02415 PHIDP_BUTTON_CAPS pButtonCaps;
02416 HRESULT stringReturn;
02417
02418 SendMessage(hControl, LB_RESETCONTENT, 0, (LPARAM) 0);
02419
02420 pButtonCaps = pDevice -> OutputButtonCaps;
02421
02422 for (iLoop = 0; iLoop < pDevice->Caps.NumberOutputButtonCaps; iLoop++)
02423 {
02424 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Output button cap # %d", iLoop);
02425 iIndex = (INT) SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02426
02427 if (-1 != iIndex)
02428 {
02429 SendMessage(hControl, LB_SETITEMDATA, iIndex, (LPARAM) pButtonCaps);
02430 }
02431 pButtonCaps++;
02432 }
02433
02434 SendMessage(hControl, LB_SETCURSEL, 0, 0);
02435 return;
02436 }
02437
02438 VOID
02439 vDisplayInputValues(
02440 IN PHID_DEVICE pDevice,
02441 IN HWND hControl
02442 )
02443 {
02444 INT iLoop;
02445 static CHAR szTempBuff[SMALL_BUFF];
02446 INT iIndex;
02447 PHIDP_VALUE_CAPS pValueCaps;
02448 HRESULT stringReturn;
02449
02450 SendMessage(hControl, LB_RESETCONTENT, 0, 0);
02451
02452 pValueCaps = pDevice -> InputValueCaps;
02453
02454 for (iLoop=0; iLoop < pDevice->Caps.NumberInputValueCaps; iLoop++)
02455 {
02456 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Input value cap # %d",iLoop);
02457 iIndex = (INT) SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02458
02459 if (-1 != iIndex)
02460 {
02461 SendMessage(hControl, LB_SETITEMDATA, iIndex,(LPARAM) pValueCaps);
02462 }
02463 pValueCaps++;
02464 }
02465
02466 SendMessage(hControl, LB_SETCURSEL, 0, 0);
02467 return;
02468 }
02469
02470 VOID
02471 vDisplayOutputValues(
02472 IN PHID_DEVICE pDevice,
02473 IN HWND hControl)
02474 {
02475 INT iLoop;
02476 static CHAR szTempBuff[SMALL_BUFF];
02477 INT iIndex;
02478 PHIDP_VALUE_CAPS pValueCaps;
02479 HRESULT stringReturn;
02480
02481 SendMessage(hControl, LB_RESETCONTENT, 0, 0);
02482 pValueCaps = pDevice -> OutputValueCaps;
02483
02484 for (iLoop = 0; iLoop < pDevice->Caps.NumberOutputValueCaps; iLoop++)
02485 {
02486 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Output value cap # %d", iLoop);
02487 iIndex = (INT) SendMessage(hControl,
02488 LB_ADDSTRING,
02489 0,
02490 (LPARAM) szTempBuff);
02491
02492 if (-1 != iIndex)
02493 {
02494 SendMessage(hControl, LB_SETITEMDATA, iIndex, (LPARAM) pValueCaps);
02495 }
02496 pValueCaps++;
02497 }
02498
02499 SendMessage(hControl, LB_SETCURSEL, 0, 0);
02500
02501 return;
02502 }
02503
02504 VOID
02505 vDisplayFeatureButtons(
02506 IN PHID_DEVICE pDevice,
02507 IN HWND hControl
02508 )
02509 {
02510 INT iLoop;
02511 static CHAR szTempBuff[SMALL_BUFF];
02512 INT iIndex;
02513 PHIDP_BUTTON_CAPS pButtonCaps;
02514 HRESULT stringReturn;
02515
02516 SendMessage(hControl, LB_RESETCONTENT, 0, 0);
02517
02518 pButtonCaps = pDevice -> FeatureButtonCaps;
02519
02520 for (iLoop = 0; iLoop < pDevice->Caps.NumberFeatureButtonCaps; iLoop++)
02521 {
02522 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Feature button cap # %d", iLoop);
02523 iIndex = (INT) SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02524
02525 if (-1 != iIndex)
02526 {
02527 SendMessage(hControl, LB_SETITEMDATA, iIndex, (LPARAM) pButtonCaps);
02528 }
02529 pButtonCaps++;
02530 }
02531 SendMessage(hControl, LB_SETCURSEL, 0, 0);
02532 return;
02533 }
02534
02535 VOID
02536 vDisplayFeatureValues(
02537 IN PHID_DEVICE pDevice,
02538 IN HWND hControl
02539 )
02540 {
02541 INT iLoop;
02542 static CHAR szTempBuff[SMALL_BUFF];
02543 INT iIndex;
02544 PHIDP_VALUE_CAPS pValueCaps;
02545 HRESULT stringReturn;
02546
02547 SendMessage(hControl, LB_RESETCONTENT, 0, 0);
02548 pValueCaps = pDevice ->FeatureValueCaps;
02549
02550 for (iLoop = 0; iLoop < pDevice->Caps.NumberFeatureValueCaps; iLoop++)
02551 {
02552 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Feature value cap # %d", iLoop);
02553 iIndex = (INT) SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02554
02555 if (-1 != iIndex)
02556 {
02557 SendMessage(hControl, LB_SETITEMDATA, iIndex, (LPARAM) pValueCaps);
02558 }
02559
02560 pValueCaps++;
02561 }
02562 SendMessage(hControl, LB_SETCURSEL, 0, 0);
02563 return;
02564 }
02565
02566 VOID
02567 vLoadItemTypes(
02568 IN HWND hItemTypes
02569 )
02570 {
02571 INT iIndex;
02572
02573 iIndex = (INT) SendMessage(hItemTypes, CB_ADDSTRING, 0, (LPARAM) "INPUT BUTTON");
02574
02575 if (-1 != iIndex)
02576 {
02577 SendMessage(hItemTypes, CB_SETITEMDATA, iIndex, INPUT_BUTTON);
02578
02579 iIndex = (INT) SendMessage(hItemTypes, CB_ADDSTRING, 0 ,(LPARAM) "INPUT VALUE");
02580 if (-1 != iIndex)
02581 {
02582 SendMessage(hItemTypes, CB_SETITEMDATA, iIndex, INPUT_VALUE);
02583 }
02584
02585 iIndex = (INT) SendMessage(hItemTypes, CB_ADDSTRING, 0, (LPARAM) "OUTPUT BUTTON");
02586 if (-1 != iIndex)
02587 {
02588 SendMessage(hItemTypes,CB_SETITEMDATA,iIndex,OUTPUT_BUTTON);
02589 }
02590
02591 iIndex = (INT) SendMessage(hItemTypes, CB_ADDSTRING, 0, (LPARAM) "OUTPUT VALUE");
02592 if (-1 != iIndex)
02593 {
02594 SendMessage(hItemTypes, CB_SETITEMDATA, iIndex, OUTPUT_VALUE);
02595 }
02596
02597 iIndex = (INT) SendMessage(hItemTypes, CB_ADDSTRING, 0, (LPARAM) "FEATURE BUTTON");
02598 if (-1 != iIndex)
02599 {
02600 SendMessage(hItemTypes, CB_SETITEMDATA, iIndex, FEATURE_BUTTON);
02601 }
02602
02603 iIndex = (INT) SendMessage(hItemTypes, CB_ADDSTRING, 0, (LPARAM) "FEATURE VALUE");
02604 if (-1 != iIndex)
02605 {
02606 SendMessage(hItemTypes, CB_SETITEMDATA, iIndex, FEATURE_VALUE);
02607 }
02608
02609 iIndex = (INT) SendMessage(hItemTypes, CB_ADDSTRING, 0, (LPARAM) "HID CAPS");
02610 if (-1 != iIndex )
02611 {
02612 SendMessage(hItemTypes, CB_SETITEMDATA, iIndex, HID_CAPS);
02613 }
02614
02615 iIndex = (INT) SendMessage(hItemTypes, CB_ADDSTRING, 0, (LPARAM) "DEVICE ATTRIBUTES");
02616 if (-1 != iIndex)
02617 {
02618 SendMessage(hItemTypes, CB_SETITEMDATA, iIndex, DEVICE_ATTRIBUTES);
02619 }
02620
02621 SendMessage(hItemTypes, CB_SETCURSEL, 0, 0);
02622 }
02623 }
02624
02625 VOID vLoadDevices(
02626 HWND hDeviceCombo
02627 )
02628 {
02629 PDEVICE_LIST_NODE currNode;
02630
02631 static CHAR szTempBuff[SMALL_BUFF];
02632 INT iIndex;
02633 HRESULT stringReturn;
02634
02635
02636
02637
02638
02639 SendMessage(hDeviceCombo, CB_RESETCONTENT, 0, 0);
02640
02641
02642 if (!IsListEmpty(&PhysicalDeviceList))
02643 {
02644 currNode = (PDEVICE_LIST_NODE) GetListHead(&PhysicalDeviceList);
02645
02646 do
02647 {
02648 stringReturn = StringCbPrintf(szTempBuff,
02649 SMALL_BUFF,
02650 "Device %d, UsagePage 0%x, Usage 0%x",
02651 HandleToULong(currNode -> HidDeviceInfo.HidDevice),
02652 currNode -> HidDeviceInfo.Caps.UsagePage,
02653 currNode -> HidDeviceInfo.Caps.Usage);
02654
02655 iIndex = (INT) SendMessage(hDeviceCombo, CB_ADDSTRING, 0, (LPARAM) szTempBuff);
02656
02657 if (CB_ERR != iIndex)
02658 {
02659 SendMessage(hDeviceCombo, CB_SETITEMDATA, iIndex, (LPARAM) &(currNode -> HidDeviceInfo));
02660 }
02661
02662 currNode = (PDEVICE_LIST_NODE) GetNextEntry(currNode);
02663
02664 } while ((PLIST) currNode != &PhysicalDeviceList);
02665
02666 }
02667
02668
02669 SendMessage(hDeviceCombo, CB_SETCURSEL, 0, 0);
02670
02671 return;
02672 }
02673
02674 BOOL
02675 bGetData(
02676 prWriteDataStruct pItems,
02677 INT iCount,
02678 HWND hParent,
02679 PCHAR pszDialogName
02680 )
02681 {
02682 rGetWriteDataParams rParams;
02683 static rWriteDataStruct arTempItems[MAX_WRITE_ELEMENTS];
02684 INT iResult;
02685
02686
02687 if (iCount > MAX_WRITE_ELEMENTS)
02688 {
02689 iCount = MAX_WRITE_ELEMENTS;
02690 }
02691
02692 memcpy( &(arTempItems[0]), pItems, sizeof(rWriteDataStruct)*iCount);
02693
02694 rParams.iCount = iCount;
02695 rParams.prItems = &(arTempItems[0]);
02696
02697 iResult = (INT) DialogBoxParam(hGInstance,
02698 pszDialogName,
02699 hParent,
02700 bGetDataDlgProc,
02701 (LPARAM) &rParams);
02702 if (iResult)
02703 {
02704 memcpy(pItems, arTempItems, sizeof(rWriteDataStruct)*iCount);
02705 }
02706 return iResult;
02707 }
02708
02709 INT_PTR CALLBACK
02710 bGetDataDlgProc(
02711 HWND hDlg,
02712 UINT message,
02713 WPARAM wParam,
02714 LPARAM lParam
02715 )
02716 {
02717 static prWriteDataStruct prData;
02718 static prGetWriteDataParams pParams;
02719 static INT iDisplayCount;
02720 static INT iScrollRange;
02721 static INT iCurrentScrollPos=0;
02722 static HWND hScrollBar;
02723 INT iTemp;
02724 SCROLLINFO rScrollInfo;
02725 INT iReturn;
02726
02727 switch (message)
02728 {
02729 case WM_INITDIALOG:
02730
02731 pParams = (prGetWriteDataParams) lParam;
02732 prData = pParams -> prItems;
02733 hScrollBar = GetDlgItem(hDlg, IDC_SCROLLBAR);
02734
02735 if (pParams -> iCount > CONTROL_COUNT)
02736 {
02737 iDisplayCount = CONTROL_COUNT;
02738 iScrollRange = pParams -> iCount - CONTROL_COUNT;
02739 rScrollInfo.fMask = SIF_RANGE | SIF_POS;
02740 rScrollInfo.nPos = 0;
02741 rScrollInfo.nMin = 0;
02742 rScrollInfo.nMax = iScrollRange;
02743 rScrollInfo.cbSize = sizeof(rScrollInfo);
02744 rScrollInfo.nPage = CONTROL_COUNT;
02745 iReturn = SetScrollInfo(hScrollBar,SB_CTL,&rScrollInfo,TRUE);
02746 }
02747 else
02748 {
02749 iDisplayCount=pParams->iCount;
02750 EnableWindow(hScrollBar,FALSE);
02751 }
02752 vWriteDataToControls(hDlg, prData, 0, pParams->iCount);
02753 break;
02754
02755 case WM_COMMAND:
02756 switch (LOWORD(wParam))
02757 {
02758 case IDOK:
02759 case ID_SEND:
02760 vReadDataFromControls(hDlg, prData, iCurrentScrollPos, iDisplayCount);
02761 EndDialog(hDlg,1);
02762 break;
02763
02764 case IDCANCEL:
02765 EndDialog(hDlg,0);
02766 break;
02767 }
02768 break;
02769
02770 case WM_VSCROLL:
02771 vReadDataFromControls(hDlg, prData, iCurrentScrollPos, iDisplayCount);
02772
02773 switch (LOWORD(wParam))
02774 {
02775 case SB_LINEDOWN:
02776 ++iCurrentScrollPos;
02777 break;
02778
02779 case SB_LINEUP:
02780 --iCurrentScrollPos;
02781 break;
02782
02783 case SB_THUMBPOSITION:
02784 iCurrentScrollPos = HIWORD(wParam);
02785
02786 case SB_PAGEUP:
02787 iCurrentScrollPos -= CONTROL_COUNT;
02788 break;
02789
02790 case SB_PAGEDOWN:
02791 iCurrentScrollPos += CONTROL_COUNT;
02792 break;
02793 }
02794
02795 if (iCurrentScrollPos < 0)
02796 {
02797 iCurrentScrollPos = 0;
02798 }
02799
02800 if (iCurrentScrollPos > iScrollRange)
02801 {
02802 iCurrentScrollPos = iScrollRange;
02803 }
02804
02805 SendMessage(hScrollBar, SBM_SETPOS, iCurrentScrollPos, TRUE);
02806 iTemp = LOWORD(wParam);
02807
02808 if ( (iTemp == SB_LINEDOWN) || (iTemp == SB_LINEUP) || (iTemp == SB_THUMBPOSITION)|| (iTemp == SB_PAGEUP) || (iTemp==SB_PAGEDOWN) )
02809 {
02810 vWriteDataToControls(hDlg, prData, iCurrentScrollPos, iDisplayCount);
02811 }
02812 break;
02813 }
02814 return FALSE;
02815 }
02816
02817 VOID
02818 vReadDataFromControls(
02819 HWND hDlg,
02820 prWriteDataStruct prData,
02821 INT iOffset,
02822 INT iCount
02823 )
02824 {
02825 INT iLoop;
02826 INT iValueControlID = IDC_OUT_EDIT1;
02827 prWriteDataStruct pDataWalk;
02828 HWND hValueWnd;
02829
02830 pDataWalk = prData + iOffset;
02831 for (iLoop = 0; (iLoop < iCount) && (iLoop < CONTROL_COUNT); iLoop++)
02832 {
02833 hValueWnd = GetDlgItem(hDlg, iValueControlID);
02834
02835 GetWindowText(hValueWnd, pDataWalk -> szValue, MAX_VALUE);
02836
02837 iValueControlID++;
02838
02839 pDataWalk++;
02840 }
02841
02842 return;
02843 }
02844
02845 VOID
02846 vWriteDataToControls(
02847 HWND hDlg,
02848 prWriteDataStruct prData,
02849 INT iOffset,
02850 INT iCount
02851 )
02852 {
02853 INT iLoop;
02854 INT iLabelControlID = IDC_OUT_LABEL1;
02855 INT iValueControlID = IDC_OUT_EDIT1;
02856 HWND hLabelWnd, hValueWnd;
02857 prWriteDataStruct pDataWalk;
02858
02859 pDataWalk = prData + iOffset;
02860
02861 for (iLoop = 0; (iLoop < iCount) && (iLoop < CONTROL_COUNT); iLoop++)
02862 {
02863 hLabelWnd = GetDlgItem(hDlg, iLabelControlID);
02864 hValueWnd = GetDlgItem(hDlg, iValueControlID);
02865
02866 ShowWindow(hLabelWnd, SW_SHOW);
02867 ShowWindow(hValueWnd, SW_SHOW);
02868
02869 SetWindowText(hLabelWnd, pDataWalk -> szLabel);
02870 SetWindowText(hValueWnd, pDataWalk -> szValue);
02871
02872 iLabelControlID++;
02873 iValueControlID++;
02874 pDataWalk++;
02875 }
02876
02877
02878
02879
02880
02881 for (; iLoop < CONTROL_COUNT; iLoop++)
02882 {
02883 hLabelWnd = GetDlgItem(hDlg,iLabelControlID);
02884 hValueWnd = GetDlgItem(hDlg,iValueControlID);
02885
02886 ShowWindow(hLabelWnd,SW_HIDE);
02887 ShowWindow(hValueWnd,SW_HIDE);
02888
02889 iLabelControlID++;
02890 iValueControlID++;
02891 }
02892 }
02893
02894 VOID
02895 vCreateUsageString(
02896 IN PUSAGE pUsageList,
02897 OUT CHAR szString[]
02898 )
02899 {
02900 HRESULT stringReturn;
02901
02902 stringReturn = StringCbPrintf(szString,
02903 SMALL_BUFF,
02904 "Usage: %#04x",
02905 *pUsageList);
02906
02907 return;
02908 }
02909
02910 VOID
02911 vCreateUsageAndPageString(
02912 IN PUSAGE_AND_PAGE pUsageList,
02913 OUT CHAR szString[]
02914 )
02915 {
02916 HRESULT stringReturn;
02917
02918 stringReturn = StringCbPrintf(szString,
02919 SMALL_BUFF,
02920 "Usage Page: %#04x Usage: %#04x",
02921 pUsageList -> UsagePage,
02922 pUsageList -> Usage);
02923
02924 return;
02925 }
02926
02927 VOID
02928 vDisplayLinkCollectionNode(
02929 IN PHIDP_LINK_COLLECTION_NODE pLCNode,
02930 IN ULONG ulLinkIndex,
02931 IN HWND hControl
02932 )
02933 {
02934 static CHAR szTempBuff[SMALL_BUFF];
02935 HRESULT stringReturn;
02936
02937 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Index: 0x%x", ulLinkIndex);
02938 SendMessage(hControl, LB_ADDSTRING, 0, (LPARAM) szTempBuff);
02939
02940 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Usage Page: 0x%x", pLCNode -> LinkUsagePage);
02941 SendMessage(hControl, LB_ADDSTRING,0, (LPARAM)szTempBuff);
02942
02943 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Usage: 0x%x", pLCNode -> LinkUsage);
02944 SendMessage(hControl, LB_ADDSTRING,0, (LPARAM) szTempBuff);
02945
02946 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Parent Index: 0x%x", pLCNode -> Parent);
02947 SendMessage(hControl, LB_ADDSTRING,0, (LPARAM) szTempBuff);
02948
02949 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Number of Children: 0x%x", pLCNode -> NumberOfChildren);
02950 SendMessage(hControl, LB_ADDSTRING,0, (LPARAM) szTempBuff);
02951
02952 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "Next Sibling: 0x%x", pLCNode -> NextSibling);
02953 SendMessage(hControl, LB_ADDSTRING,0, (LPARAM) szTempBuff);
02954
02955 stringReturn = StringCbPrintf(szTempBuff, SMALL_BUFF, "First Child: 0x%x", pLCNode -> FirstChild);
02956 SendMessage(hControl, LB_ADDSTRING,0, (LPARAM) szTempBuff);
02957
02958 return;
02959 }
02960
02961 VOID
02962 vCreateUsageValueStringFromArray(
02963 PCHAR pBuffer,
02964 USHORT BitSize,
02965 USHORT UsageIndex,
02966 CHAR szString[]
02967 )
02968
02969
02970
02971
02972
02973
02974
02975
02976 {
02977 INT iByteIndex;
02978 INT iByteOffset;
02979 UCHAR ucLeftoverBits;
02980 ULONG ulMask;
02981 ULONG ulValue;
02982 HRESULT stringReturn;
02983
02984
02985
02986
02987
02988
02989 iByteIndex = (UsageIndex * BitSize) >> 3;
02990 iByteOffset = (UsageIndex * BitSize) & 7;
02991
02992
02993
02994
02995
02996
02997 ulValue = *(PULONG) (pBuffer + iByteIndex);
02998
02999
03000
03001
03002
03003 ulValue = ulValue >> iByteOffset;
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019
03020
03021
03022
03023 if (BitSize > sizeof(ULONG)*8 - iByteOffset)
03024 {
03025
03026
03027
03028
03029
03030 ucLeftoverBits = *(pBuffer+iByteIndex+4);
03031
03032
03033
03034
03035
03036 ulMask = ucLeftoverBits << (24 + (8 - iByteOffset));
03037 ulValue |= ulMask;
03038
03039 }
03040 else if (BitSize < sizeof(ULONG)*8 - iByteOffset)
03041 {
03042
03043
03044
03045
03046
03047 ulMask = (1 << BitSize) - 1;
03048 ulValue &= ulMask;
03049 }
03050
03051
03052
03053
03054
03055 stringReturn = StringCbPrintf(szString, SMALL_BUFF, "Usage value: %lu", ulValue);
03056
03057 return;
03058 }
03059
03060
03061 BOOL
03062 RegisterHidDevice(
03063 IN HWND WindowHandle,
03064 IN PDEVICE_LIST_NODE DeviceNode
03065 )
03066 {
03067 DEV_BROADCAST_HANDLE broadcastHandle;
03068
03069 broadcastHandle.dbch_size = sizeof(DEV_BROADCAST_HANDLE);
03070 broadcastHandle.dbch_devicetype = DBT_DEVTYP_HANDLE;
03071 broadcastHandle.dbch_handle = DeviceNode -> HidDeviceInfo.HidDevice;
03072
03073 DeviceNode -> NotificationHandle = RegisterDeviceNotification(
03074 WindowHandle,
03075 &broadcastHandle,
03076 DEVICE_NOTIFY_WINDOW_HANDLE);
03077
03078 return (NULL != DeviceNode -> NotificationHandle);
03079 }
03080
03081 VOID
03082 DestroyDeviceListCallback(
03083 PLIST_NODE_HDR ListNode
03084 )
03085 {
03086 PDEVICE_LIST_NODE deviceNode;
03087
03088 deviceNode = (PDEVICE_LIST_NODE) ListNode;
03089
03090
03091
03092
03093
03094
03095
03096
03097 CloseHidDevice(&(deviceNode -> HidDeviceInfo));
03098
03099 if (NULL != deviceNode -> NotificationHandle)
03100 {
03101 UnregisterDeviceNotification(deviceNode -> NotificationHandle);
03102 }
03103
03104 free (deviceNode);
03105
03106 return;
03107 }
03108
03109 DWORD WINAPI
03110 AsynchReadThreadProc(
03111 PREAD_THREAD_CONTEXT Context
03112 )
03113 {
03114 HANDLE completionEvent;
03115 BOOL readStatus;
03116 DWORD waitStatus;
03117
03118
03119
03120
03121
03122 completionEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
03123
03124
03125
03126
03127
03128
03129 if (NULL == completionEvent)
03130 {
03131 goto AsyncRead_End;
03132 }
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149
03150 do
03151 {
03152
03153
03154
03155
03156
03157
03158 readStatus = ReadOverlapped( Context -> HidDevice, completionEvent );
03159
03160
03161 if (!readStatus)
03162 {
03163 break;
03164 }
03165
03166 while (!Context -> TerminateThread)
03167 {
03168
03169
03170
03171
03172 waitStatus = WaitForSingleObject (completionEvent, READ_THREAD_TIMEOUT );
03173
03174
03175
03176
03177
03178
03179 if ( WAIT_OBJECT_0 == waitStatus)
03180 {
03181 break;
03182 }
03183 }
03184
03185
03186
03187
03188
03189
03190
03191
03192 if (!Context -> TerminateThread)
03193 {
03194 UnpackReport(Context -> HidDevice -> InputReportBuffer,
03195 Context -> HidDevice -> Caps.InputReportByteLength,
03196 HidP_Input,
03197 Context -> HidDevice -> InputData,
03198 Context -> HidDevice -> InputDataLength,
03199 Context -> HidDevice -> Ppd);
03200
03201 if (NULL != Context -> DisplayEvent)
03202 {
03203 PostMessage(Context -> DisplayWindow,
03204 WM_DISPLAY_READ_DATA,
03205 0,
03206 (LPARAM) Context -> HidDevice);
03207
03208 WaitForSingleObject( Context -> DisplayEvent, INFINITE );
03209 }
03210 }
03211 } while ( !Context -> TerminateThread && !Context -> DoOneRead );
03212
03213
03214 AsyncRead_End:
03215
03216 PostMessage( Context -> DisplayWindow, WM_READ_DONE, 0, 0);
03217 ExitThread(0);
03218 return (0);
03219 }
03220
03221 DWORD WINAPI
03222 SynchReadThreadProc(
03223 PREAD_THREAD_CONTEXT Context
03224 )
03225 {
03226 do
03227 {
03228 Read(Context -> HidDevice);
03229
03230 UnpackReport(Context -> HidDevice -> InputReportBuffer,
03231 Context -> HidDevice -> Caps.InputReportByteLength,
03232 HidP_Input,
03233 Context -> HidDevice -> InputData,
03234 Context -> HidDevice -> InputDataLength,
03235 Context -> HidDevice -> Ppd);
03236
03237 if (NULL != Context -> DisplayEvent)
03238 {
03239 PostMessage(Context -> DisplayWindow,
03240 WM_DISPLAY_READ_DATA,
03241 0,
03242 (LPARAM) Context -> HidDevice);
03243
03244 WaitForSingleObject( Context -> DisplayEvent, INFINITE );
03245 }
03246 } while ( !Context -> TerminateThread && !Context -> DoOneRead );
03247
03248 PostMessage( Context -> DisplayWindow, WM_READ_DONE, 0, 0);
03249 ExitThread(0);
03250 return (0);
03251 }
03252
03253 DWORD WINAPI
03254 MyReadThreadProc(
03255 PREAD_THREAD_CONTEXT Context
03256 )
03257 {
03258 #if 1
03259 do {
03260 PostMessage(Context->DisplayWindow, WM_COMMAND, IDC_BUTTON_RD, IDC_BUTTON_RD);
03261 Sleep(100);
03262 } while ( !Context->TerminateThread && !Context->DoOneRead );
03263 #else
03264 do
03265 {
03266 Read(Context -> HidDevice);
03267
03268 UnpackReport(Context -> HidDevice -> InputReportBuffer,
03269 Context -> HidDevice -> Caps.InputReportByteLength,
03270 HidP_Input,
03271 Context -> HidDevice -> InputData,
03272 Context -> HidDevice -> InputDataLength,
03273 Context -> HidDevice -> Ppd);
03274
03275 if (NULL != Context -> DisplayEvent)
03276 {
03277 PostMessage(Context -> DisplayWindow,
03278 WM_DISPLAY_READ_DATA,
03279 0,
03280 (LPARAM) Context -> HidDevice);
03281
03282 WaitForSingleObject( Context -> DisplayEvent, INFINITE );
03283 }
03284 } while ( !Context -> TerminateThread && !Context -> DoOneRead );
03285 #endif
03286 ExitThread(0);
03287 return (0);
03288 }
03289
03290 char
03291 HalfBtoHex(IN BYTE chr)
03292 {
03293 BYTE tmp = 0xF & chr;
03294 if (tmp <= 9) {
03295 return (tmp + '0');
03296 }
03297 else {
03298 return (tmp - 10 + 'A');
03299 }
03300 }
03301
03302 int
03303 Hex2Int(IN char* str)
03304 {
03305 int result = 0;
03306 while (1) {
03307 char tmp = *str ++;
03308 if (tmp >= '0' && tmp <= '9') {
03309 result <<= 4;
03310 result += (tmp - '0');
03311 }
03312 else if (tmp >= 'A' && tmp <= 'F') {
03313 result <<= 4;
03314 result += (tmp - 'A' + 10);
03315 }
03316 else if (tmp >= 'a' && tmp <= 'f') {
03317 result <<= 4;
03318 result += (tmp - 'a' + 10);
03319 }
03320 else {
03321 break;
03322 }
03323 }
03324 return result;
03325 }