SAMV71 Xplained Ultra Software Package 1.5

ecdisp.c

00001 /*++
00002 
00003 Copyright (c) Microsoft 1998, All Rights Reserved
00004 
00005 Module Name:
00006 
00007     ecdisp.c
00008 
00009 Abstract:
00010 
00011     This module contains the code to handle the extended calls dialog box
00012     and the actions that can be performed in the dialog box.
00013 
00014 Environment:
00015 
00016     User mode
00017 
00018 Revision History:
00019 
00020     May-98 : Created
00021 
00022 --*/
00023 
00024 /*****************************************************************************
00025 /* Extended call display include files
00026 /*****************************************************************************/
00027 #include <windows.h>
00028 #include <limits.h>
00029 #include <stdlib.h>
00030 #include <math.h>
00031 #include <stdio.h>
00032 #include <setupapi.h>
00033 #include <vfw.h>
00034 #include <assert.h>
00035 #include "hidusage.h"
00036 #include "hidsdi.h"
00037 #include "hid.h"
00038 #include "hclient.h"
00039 #include "resource.h"
00040 #include "buffers.h"
00041 #include "ecdisp.h"
00042 #include "strings.h"
00043 #include <strsafe.h>
00044 
00045 /*****************************************************************************
00046 /* Local macro definitions for the supported function calls
00047 /*****************************************************************************/
00048 
00049 #define HID_DEVCALLS                    20
00050 #define HID_PPDCALLS                    29
00051 
00052 #define HID_NUMCALLS                    HID_DEVCALLS + HID_PPDCALLS
00053 
00054 #define HIDD_GET_HID_GUID              1
00055 #define HIDD_GET_FREE_PREPARSED_DATA   2
00056 #define HIDD_GET_CONFIGURATION         3
00057 #define HIDD_SET_CONFIGURATION         4
00058 #define HIDD_FLUSH_QUEUE               5
00059 #define HIDD_GET_ATTRIBUTES            6
00060 #define HIDD_SET_FEATURE               7
00061 #define HIDD_GET_FEATURE               8
00062 #define HIDD_GET_INPUT_REPORT          9
00063 #define HIDD_SET_OUTPUT_REPORT        10
00064 #define HIDD_GET_NUM_INPUT_BUFFERS    11
00065 #define HIDD_SET_NUM_INPUT_BUFFERS    12
00066 #define HIDD_GET_PHYSICAL_DESCRIPTOR  13
00067 #define HIDD_GET_MANUFACTURER_STRING  14
00068 #define HIDD_GET_PRODUCT_STRING       15
00069 #define HIDD_GET_INDEXED_STRING       16
00070 #define HIDD_GET_SERIAL_NUMBER_STRING 17
00071 #define HIDD_GET_MS_GENRE_DESCRIPTOR  18
00072 #define HID_READ_REPORT               19
00073 #define HID_WRITE_REPORT              20
00074 #define HIDP_GET_BUTTON_CAPS          21
00075 #define HIDP_GET_BUTTONS              22
00076 #define HIDP_GET_BUTTONS_EX           23
00077 #define HIDP_GET_CAPS                 24
00078 #define HIDP_GET_DATA                 25
00079 #define HIDP_GET_EXTENDED_ATTRIBUTES  26
00080 #define HIDP_GET_LINK_COLL_NODES      27
00081 #define HIDP_GET_SCALED_USAGE_VALUE   28
00082 #define HIDP_GET_SPECIFIC_BUTTON_CAPS 29
00083 #define HIDP_GET_SPECIFIC_VALUE_CAPS  30
00084 #define HIDP_GET_USAGES               31
00085 #define HIDP_GET_USAGES_EX            32
00086 #define HIDP_GET_USAGE_VALUE          33
00087 #define HIDP_GET_USAGE_VALUE_ARRAY    34
00088 #define HIDP_GET_VALUE_CAPS           35
00089 #define HIDP_INITIALIZE_REPORT_FOR_ID 36
00090 #define HIDP_MAX_DATA_LIST_LENGTH     37
00091 #define HIDP_MAX_USAGE_LIST_LENGTH    38
00092 #define HIDP_SET_BUTTONS              39
00093 #define HIDP_SET_DATA                 40
00094 #define HIDP_SET_SCALED_USAGE_VALUE   41
00095 #define HIDP_SET_USAGES               42
00096 #define HIDP_SET_USAGE_VALUE          43
00097 #define HIDP_SET_USAGE_VALUE_ARRAY    44
00098 #define HIDP_TRANSLATE_USAGES         45
00099 #define HIDP_UNSET_BUTTONS            46
00100 #define HIDP_UNSET_USAGES             47
00101 #define HIDP_USAGE_LIST_DIFFERENCE    48
00102 #define HID_CLEAR_REPORT              49
00103 
00104 /*
00105 // These two definitions are not used by the display routines since
00106 //    the two functions were melded together into one for purpose of execution
00107 */
00108 
00109 #define HIDD_GET_PREPARSED_DATA       50
00110 #define HIDD_FREE_PREPARSED_DATA      51
00111 
00112 
00113 #define IS_HIDD_FUNCTION(func)        (((func) >= HIDD_GET_HID_GUID) && \
00114                                        ((func) <= HIDD_GET_MS_GENRE_DESCRIPTOR))
00115 
00116 
00117 #define IS_HIDP_FUNCTION(func)        (((func) >= HIDP_GET_BUTTON_CAPS) && \
00118                                        ((func) <= HIDP_USAGE_LIST_DIFFERENCE))
00119 
00120 #define IS_HID_FUNCTION(func)         (((func) >= HID_READ_REPORT) && \
00121                                        ((func) <= HID_WRITE_REPORT))
00122 
00123 #define IS_NOT_IMPLEMENTED(func)      (((func) == HIDD_GET_CONFIGURATION) || \
00124                                       ((func) == HIDD_SET_CONFIGURATION) || \
00125                                       ((func) == HIDP_TRANSLATE_USAGES) || \
00126                                       (((func) == HIDP_INITIALIZE_REPORT_FOR_ID) && \
00127                                        (NULL == pfnHidP_InitializeReportForID)) || \
00128                                       (((func) == HIDP_GET_EXTENDED_ATTRIBUTES) && \
00129                                        (NULL == pfnHidP_GetExtendedAttributes)))
00130 
00131 /*****************************************************************************
00132 /* Local macro definitions for buffer display sizes
00133 /*****************************************************************************/
00134 
00135 #define NUM_INPUT_BUFFERS       16
00136 #define NUM_OUTPUT_BUFFERS      16
00137 #define NUM_FEATURE_BUFFERS     16
00138 
00139 /*****************************************************************************
00140 /* Local macro definition for HidP_SetData dialog box
00141 /*****************************************************************************/
00142 
00143 #define SETDATA_LISTBOX_FORMAT  "Index: %u,  DataValue: %u"
00144 
00145 /*****************************************************************************
00146 /* Local macro definition for display output to output windows
00147 /*****************************************************************************/
00148 
00149 #define TEMP_BUFFER_SIZE 1024
00150 #define OUTSTRING(win, str)         SendMessage(win, LB_ADDSTRING, 0, (LPARAM) str)
00151 #define OUTWSTRING(win, str) \
00152 { \
00153     SIZE_T  nBytes; \
00154 \
00155     nBytes = wcstombs(szTempBuffer, str, TEMP_BUFFER_SIZE-1); \
00156     if ((SIZE_T) -1 == nBytes) { \
00157         OUTSTRING(win, "Cannot convert wide-character string"); \
00158     } \
00159     else { \
00160         szTempBuffer[nBytes] = '\0'; \
00161         OUTSTRING(win, szTempBuffer); \
00162     } \
00163 }
00164 
00165 #define DISPLAY_HIDD_STATUS(win, func, status, strret) \
00166 { \
00167     strret = StringCbPrintf(szTempBuffer, \
00168                    TEMP_BUFFER_SIZE,  \
00169                    "%s returned: %s", \
00170                    func, \
00171                    (status).IsHidError ? "FALSE" : "TRUE"); \
00172 \
00173     OUTSTRING(win, szTempBuffer); \
00174 \
00175     if ((status).IsHidError) { \
00176         strret = StringCbPrintf(szTempBuffer, \
00177                        TEMP_BUFFER_SIZE, \
00178                        "ErrorCode: %d", \
00179                        GetLastError()); \
00180     }\
00181     OUTSTRING(win, szTempBuffer); \
00182 }
00183 
00184 #define DISPLAY_HIDP_STATUS(win, func, status, strret) \
00185 { \
00186     strret = StringCbPrintf(szTempBuffer, \
00187                    TEMP_BUFFER_SIZE, \
00188                    "%s returned: %s", \
00189                    func, \
00190                    ECDisp_GetHidAppStatusString(status.HidErrorCode)); \
00191 \
00192     OUTSTRING(win, szTempBuffer); \
00193 }
00194 
00195 #define ECDISP_ERROR(win, msg) \
00196 { \
00197     MessageBox(win, \
00198                msg, \
00199                HCLIENT_ERROR, \
00200                MB_ICONEXCLAMATION); \
00201 }
00202 
00203 #define GET_FUNCTION_NAME(index)     ResolveFunctionName(index)
00204 
00205 
00206 /*****************************************************************************
00207 /* Local macro definition for retrieving data based on report type
00208 /*****************************************************************************/
00209 #define SELECT_ON_REPORT_TYPE(rt, ival, oval, fval, res) \
00210 { \
00211     switch ((rt)) { \
00212     case HidP_Input: \
00213         (res) = (ival); \
00214         break; \
00215 \
00216     case HidP_Output: \
00217         (res) = (oval); \
00218         break; \
00219 \
00220     case HidP_Feature: \
00221         (res) = (fval); \
00222         break; \
00223 \
00224     } \
00225 }
00226 
00227 /*****************************************************************************
00228 /* Local macro definition for calculating size of a usage value array buffer
00229 /*****************************************************************************/
00230 #define ROUND_TO_NEAREST_BYTE(val)  (((val) % 8) ? ((val) / 8) + 1 : ((val) / 8))
00231 
00232 /*****************************************************************************
00233 /* Data types local to this module
00234 /*****************************************************************************/
00235 
00236 typedef struct _FUNCTION_NAMES
00237 {
00238     UINT uiIndex;
00239     char *szFunctionName;
00240 } FUNCTION_NAMES;
00241 
00242 typedef struct _PARAMETER_STATE
00243 {
00244     BOOL fInputReport;
00245     BOOL fOutputReport;
00246     BOOL fFeatureReport;
00247     BOOL fReportID;
00248     BOOL fUsagePage;
00249     BOOL fUsage;
00250     BOOL fLinkCollection;
00251     BOOL fInputReportSelect;
00252     BOOL fOutputReportSelect;
00253     BOOL fFeatureReportSelect;
00254 } PARAMETER_STATE;
00255 
00256 typedef enum { DLGBOX_INIT_FAILED = -1, DLGBOX_ERROR, DLGBOX_CANCEL, DLGBOX_OK } DLGBOX_STATUS;
00257 
00258 typedef struct _ECDISPLAY_PARAMS
00259 {
00260     HIDP_REPORT_TYPE          ReportType;
00261     USAGE                     UsagePage;
00262     USAGE                     Usage;
00263     USHORT                    LinkCollection;
00264     UCHAR                     ReportID;
00265     PCHAR                     szListString;
00266     PCHAR                     szListString2;
00267     PUSAGE                    UsageList;
00268     PUSAGE                    UsageList2;
00269     ULONG                     ListLength;
00270     ULONG                     ListLength2;
00271     ULONG                     Index;
00272     union {
00273         PHIDP_DATA            pDataList;
00274         PULONG                pValueList;
00275         LONG                  ScaledValue;
00276         ULONG                 Value;
00277     };
00278 } ECDISPLAY_PARAMS, *PECDISPLAY_PARAMS;
00279 
00280 typedef struct _READ_PARAMS
00281 {
00282     PHID_DEVICE device;
00283     BOOLEAN     stopThread;
00284 } READ_PARAMS, *PREAD_PARAMS;
00285 
00286 /*****************************************************************************
00287 /* Local data variables
00288 /*****************************************************************************/
00289 
00290 static CHAR             szTempBuffer[TEMP_BUFFER_SIZE];
00291 
00292 static PBUFFER_DISPLAY  pInputDisplay;
00293 static PBUFFER_DISPLAY  pOutputDisplay;
00294 static PBUFFER_DISPLAY  pFeatureDisplay;
00295 
00296 static FUNCTION_NAMES DeviceCalls[HID_DEVCALLS] = {
00297                              { HIDD_GET_HID_GUID,               "HidD_GetHidGuid" },
00298                              { HIDD_GET_FREE_PREPARSED_DATA,    "HidD_GetFreePreparsedData" },
00299                              { HIDD_GET_CONFIGURATION,          "HidD_GetConfiguration" },
00300                              { HIDD_SET_CONFIGURATION,          "HidD_SetConfiguration" },
00301                              { HIDD_FLUSH_QUEUE,                "HidD_FlushQueue" },
00302                              { HIDD_GET_ATTRIBUTES,             "HidD_GetAttributes" },
00303                              { HIDD_SET_FEATURE,                "HidD_SetFeature" },
00304                              { HIDD_GET_FEATURE,                "HidD_GetFeature" },
00305                              { HIDD_GET_INPUT_REPORT,           "HIDD_GetInputReport" },
00306                              { HIDD_SET_OUTPUT_REPORT,          "HidD_SetOutputReport" },
00307                              { HIDD_GET_NUM_INPUT_BUFFERS,      "HidD_GetNumInputBuffers" },
00308                              { HIDD_SET_NUM_INPUT_BUFFERS,      "HidD_SetNumInputBuffers" },
00309                              { HIDD_GET_PHYSICAL_DESCRIPTOR,    "HidD_GetPhysicalDescriptor" },
00310                              { HIDD_GET_MANUFACTURER_STRING,    "HidD_GetManufacturerString" },
00311                              { HIDD_GET_PRODUCT_STRING,         "HidD_GetProductString" },
00312                              { HIDD_GET_INDEXED_STRING,         "HidD_GetIndexedString" },
00313                              { HIDD_GET_SERIAL_NUMBER_STRING,   "HidD_GetSerialNumberString" },
00314                              { HIDD_GET_MS_GENRE_DESCRIPTOR,    "HidD_GetMsGenreDescriptor" },
00315                              { HID_READ_REPORT,                 "Read Input Report"        },
00316                              { HID_WRITE_REPORT,                "Write Report Buffer"      }
00317 
00318 };
00319 
00320 static FUNCTION_NAMES PpdCalls[HID_PPDCALLS] = {
00321                              { HIDP_GET_BUTTON_CAPS,            "HidP_GetButtonCaps" },
00322                              { HIDP_GET_BUTTONS,                "HidP_GetButtons" },
00323                              { HIDP_GET_BUTTONS_EX,             "HidP_GetButtonsEx" },
00324                              { HIDP_GET_CAPS,                   "HidP_GetCaps" },
00325                              { HIDP_GET_DATA,                   "HidP_GetData" },
00326                              { HIDP_GET_EXTENDED_ATTRIBUTES,    "HidP_GetExtendedAttributes" },
00327                              { HIDP_GET_LINK_COLL_NODES,        "HidP_GetLinkCollectionNodes" },
00328                              { HIDP_GET_SCALED_USAGE_VALUE,     "HidP_GetScaledUsageValue" },
00329                              { HIDP_GET_SPECIFIC_BUTTON_CAPS,   "HidP_GetSpecificButtonCaps" },
00330                              { HIDP_GET_SPECIFIC_VALUE_CAPS,    "HidP_GetSpecificValueCaps" },
00331                              { HIDP_GET_USAGES,                 "HidP_GetUsages" },
00332                              { HIDP_GET_USAGES_EX,              "HidP_GetUsagesEx" },
00333                              { HIDP_GET_USAGE_VALUE,            "HidP_GetUsageValue" },
00334                              { HIDP_GET_USAGE_VALUE_ARRAY,      "HidP_GetUsageValueArray" },
00335                              { HIDP_GET_VALUE_CAPS,             "HidP_GetValueCaps" },
00336                              { HIDP_INITIALIZE_REPORT_FOR_ID,   "HidP_InitializeReportForID" },
00337                              { HIDP_MAX_DATA_LIST_LENGTH,       "HidP_MaxDataListLength" },
00338                              { HIDP_MAX_USAGE_LIST_LENGTH,      "HidP_MaxUsageListLength" },
00339                              { HIDP_SET_BUTTONS,                "HidP_SetButtons" },
00340                              { HIDP_SET_DATA,                   "HidP_SetData" },
00341                              { HIDP_SET_SCALED_USAGE_VALUE,     "HidP_SetScaledUsageValue" },
00342                              { HIDP_SET_USAGES,                 "HidP_SetUsages" },
00343                              { HIDP_SET_USAGE_VALUE,            "HidP_SetUsageValue" },
00344                              { HIDP_SET_USAGE_VALUE_ARRAY,      "HidP_SetUsageValueArray" },
00345                              { HIDP_TRANSLATE_USAGES,           "HidP_TranslateUsagesToI8042ScanCodes" },
00346                              { HIDP_UNSET_BUTTONS,              "HidP_UnsetButtons" },
00347                              { HIDP_UNSET_USAGES,               "HidP_UnsetUsages" },
00348                              { HIDP_USAGE_LIST_DIFFERENCE,      "HidP_UsageListDifference" },
00349                              { HID_CLEAR_REPORT,                "Clear Report Buffer"      }
00350 };
00351 
00352 static PARAMETER_STATE pState[HID_NUMCALLS] = {
00353                                          { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_GET_HID_GUID
00354                                          { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_GET_FREE_PREPARSED_DATA
00355                                          { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_GET_CONFIGURATION
00356                                          { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_SET_CONFIGURATION
00357                                          { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_FLUSH_QUEUE
00358                                          { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_GETATTRIBUTES
00359                                          { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,  TRUE }, // HIDD_SET_FEATURE
00360                                          { FALSE, FALSE, FALSE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE,  TRUE }, // HIDD_GET_FEATURE
00361                                          { FALSE, FALSE, FALSE,  TRUE, FALSE, FALSE, FALSE,  TRUE, FALSE, FALSE }, // HIDD_GET_INPUT_REPORT
00362                                          { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,  TRUE, FALSE }, // HIDD_SET_OUTPUT_REPORT
00363                                          { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_GET_NUM_INPUT_BUFFERS
00364                                          { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_SET_NUM_INPUT_BUFFERS
00365                                          { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_GET_PHYSICAL_DESCRIPTOR
00366                                          { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_GET_MANUFACTURER_STRING
00367                                          { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_GET_PRODUCT_STRING
00368                                          { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_GET_INDEXED_STRING
00369                                          { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_GET_SERIAL_NUMBER_STRING
00370                                          { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDD_GET_MS_GENRE_DESCRIPTOR
00371                                          { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,  TRUE, FALSE, FALSE }, // HID_READ_REPORT
00372                                          { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,  TRUE, FALSE }, // HID_WRITE_BUFFER
00373                                          {  TRUE,  TRUE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDP_GET_BUTTON_CAPS
00374                                          {  TRUE,  TRUE,  TRUE, FALSE,  TRUE, FALSE,  TRUE,  TRUE,  TRUE,  TRUE }, // HIDP_GET_BUTTONS
00375                                          {  TRUE,  TRUE,  TRUE, FALSE, FALSE, FALSE,  TRUE,  TRUE,  TRUE,  TRUE }, // HIDP_GET_BUTTONS_EX
00376                                          { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDP_GET_CAPS
00377                                          {  TRUE,  TRUE,  TRUE, FALSE, FALSE, FALSE, FALSE,  TRUE,  TRUE,  TRUE }, // HIDP_GET_DATA
00378                                          {  TRUE,  TRUE,  TRUE,  TRUE, FALSE, FALSE, FALSE,  TRUE,  TRUE,  TRUE }, // HIDP_GET_EXTENDED_ATTRIBUTES
00379                                          { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDP_GET_LINK_COLL_NODES
00380                                          {  TRUE,  TRUE,  TRUE, FALSE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE }, // HIDP_GET_SCALED_USAGE_VALUE
00381                                          {  TRUE,  TRUE,  TRUE, FALSE,  TRUE,  TRUE,  TRUE, FALSE, FALSE, FALSE }, // HIDP_GET_SPECIFIC_BUTTON_CAPS
00382                                          {  TRUE,  TRUE,  TRUE, FALSE,  TRUE,  TRUE,  TRUE, FALSE, FALSE, FALSE }, // HIDP_GET_SPECIFIC_VALUE_CAPS
00383                                          {  TRUE,  TRUE,  TRUE, FALSE,  TRUE, FALSE,  TRUE,  TRUE,  TRUE,  TRUE }, // HIDP_GET_USAGES
00384                                          {  TRUE,  TRUE,  TRUE, FALSE, FALSE, FALSE,  TRUE,  TRUE,  TRUE,  TRUE }, // HIDP_GET_USAGES_EX
00385                                          {  TRUE,  TRUE,  TRUE, FALSE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE }, // HIDP_GET_USAGE_VALUE
00386                                          {  TRUE,  TRUE,  TRUE, FALSE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE }, // HIDP_GET_USAGE_VALUE_ARRAY
00387                                          {  TRUE,  TRUE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDP_GET_VALUE_CAPS
00388                                          {  TRUE,  TRUE,  TRUE,  TRUE, FALSE, FALSE, FALSE,  TRUE,  TRUE,  TRUE }, // HIDP_INITIALIZE_REPORT_FOR_ID
00389                                          {  TRUE,  TRUE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDP_MAX_DATA_LIST_LENGTH
00390                                          {  TRUE,  TRUE,  TRUE, FALSE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDP_MAX_USAGE_LIST_LENGTH
00391                                          {  TRUE,  TRUE,  TRUE, FALSE,  TRUE, FALSE,  TRUE,  TRUE,  TRUE,  TRUE }, // HIDP_SET_BUTTONS
00392                                          {  TRUE,  TRUE,  TRUE, FALSE, FALSE, FALSE, FALSE,  TRUE,  TRUE,  TRUE }, // HIDP_SET_DATA
00393                                          {  TRUE,  TRUE,  TRUE, FALSE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE }, // HIDP_SET_SCALED_USAGE_VALUE
00394                                          {  TRUE,  TRUE,  TRUE, FALSE,  TRUE, FALSE,  TRUE,  TRUE,  TRUE,  TRUE }, // HIDP_SET_USAGES
00395                                          {  TRUE,  TRUE,  TRUE, FALSE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE }, // HIDP_SET_USAGE_VALUE
00396                                          {  TRUE,  TRUE,  TRUE, FALSE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE }, // HIDP_SET_USAGE_VALUE_ARRAY
00397                                          { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDP_TRANSLATE_USAGES
00398                                          {  TRUE,  TRUE,  TRUE, FALSE,  TRUE, FALSE,  TRUE,  TRUE,  TRUE,  TRUE }, // HIDP_UNSET_BUTTONS
00399                                          {  TRUE,  TRUE,  TRUE, FALSE,  TRUE, FALSE,  TRUE,  TRUE,  TRUE,  TRUE }, // HIDP_UNSET_USAGES
00400                                          { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE }, // HIDP_USAGE_LIST_DIFFERENCE
00401                                          {  TRUE,  TRUE,  TRUE, FALSE, FALSE, FALSE, FALSE,  TRUE,  TRUE,  TRUE }  // HID_CLEAR_BUFFER
00402                                         };
00403 
00404 
00405 /*****************************************************************************
00406 /* Local function declarations
00407 /*****************************************************************************/
00408 
00409 VOID
00410 vLoadExtCalls(
00411     HWND hExtCalls
00412 );
00413 
00414 VOID
00415 vSetReportType(
00416     HWND hDlg,
00417     LONG lId
00418 );
00419 
00420 VOID
00421 vInitEditText(
00422     HWND   hText,
00423     INT    cbTextSize,
00424     CHAR   *pchText
00425 );
00426 
00427 VOID vEnableParameters(
00428     HWND     hDlg,
00429     LRESULT  iCallSelection
00430 );
00431 
00432 BOOL
00433 fGetAndVerifyParameters(
00434     HWND              hDlg,
00435     PECDISPLAY_PARAMS pParams
00436 );
00437 
00438 BOOL
00439 ECDisp_Execute(
00440     IN     INT             FuncCall,
00441     IN OUT PEXTCALL_PARAMS CallParams,
00442     OUT    PEXTCALL_STATUS CallStatus
00443 );
00444 
00445 VOID
00446 ECDisp_DisplayOutput(
00447     IN HWND            hOutputWindow,
00448     IN INT             FuncCall,
00449     IN PEXTCALL_PARAMS Results
00450 );
00451 
00452 VOID
00453 vExecuteAndDisplayOutput(
00454     HWND              hOutputWindow,
00455     PHID_DEVICE       pDevice,
00456     INT               iFuncCall,
00457     PECDISPLAY_PARAMS pParams
00458 );
00459 
00460 CHAR *pchGetHidAppStatusString(
00461     NTSTATUS StatusCode
00462 );
00463 
00464 VOID
00465 vInitECControls(
00466     HWND            hDlg,
00467     USHORT          InputReportByteLength,
00468     PBUFFER_DISPLAY *ppInputDisplay,
00469     USHORT          OutputReportByteLength,
00470     PBUFFER_DISPLAY *ppOutputDisplay,
00471     USHORT          FeatureReportByteLength,
00472     PBUFFER_DISPLAY *ppFeatureDisplay
00473 );
00474 
00475 VOID
00476 BuildReportIDList(
00477     IN  PHIDP_BUTTON_CAPS  phidButtonCaps,
00478     IN  USHORT             nButtonCaps,
00479     IN  PHIDP_VALUE_CAPS   phidValueCaps,
00480     IN  USHORT             nValueCaps,
00481     OUT UCHAR            **ppReportIDList,
00482     OUT INT               *nReportIDs
00483 );
00484 
00485 LRESULT CALLBACK
00486 bSetUsagesDlgProc(
00487     HWND hDlg,
00488     UINT message,
00489     WPARAM wParam,
00490     LPARAM lParam
00491 );
00492 
00493 LRESULT CALLBACK
00494 bSetValueDlgProc(
00495     HWND hDlg,
00496     UINT message,
00497     WPARAM wParam,
00498     LPARAM lParam
00499 );
00500 
00501 LRESULT CALLBACK
00502 bSetInputBuffDlgProc(
00503     HWND hDlg,
00504     UINT message,
00505     WPARAM wParam,
00506     LPARAM lParam
00507 );
00508 
00509 LRESULT CALLBACK
00510 bSetDataDlgProc(
00511     HWND hDlg,
00512     UINT message,
00513     WPARAM wParam,
00514     LPARAM lParam
00515 );
00516 
00517 LRESULT CALLBACK
00518 bSetBufLenDlgProc(
00519     HWND hDlg,
00520     UINT message,
00521     WPARAM wParam,
00522     LPARAM lParam
00523 );
00524 
00525 LRESULT CALLBACK
00526 bSetInputBuffersDlgProc(
00527     HWND hDlg,
00528     UINT message,
00529     WPARAM wParam,
00530     LPARAM lParam
00531 );
00532 
00533 LRESULT CALLBACK
00534 bGetIndexedDlgProc(
00535     HWND hDlg,
00536     UINT message,
00537     WPARAM wParam,
00538     LPARAM lParam
00539 );
00540 
00541 LRESULT CALLBACK
00542 bGetUsageDiffDlgProc(
00543     HWND hDlg,
00544     UINT message,
00545     WPARAM wParam,
00546     LPARAM lParam
00547 );
00548 
00549 BOOL
00550 ConvertStringToUnsignedList(
00551     IN     INT     iUnsignedSize,
00552     IN     INT     iBase,
00553     IN OUT PCHAR   InString,
00554     OUT    PCHAR   *UnsignedList,
00555     OUT    PULONG  nUnsigneds
00556 );
00557 
00558 BOOL
00559 ConvertStringToUlongList(
00560     IN OUT PCHAR   InString,
00561     OUT    PULONG  *UlongList,
00562     OUT    PULONG  nUlongs
00563 );
00564 
00565 BOOL
00566 ConvertStringToUsageList(
00567     IN OUT PCHAR   InString,
00568     OUT    PUSAGE  *UsageList,
00569     OUT    PULONG  nUsages
00570 );
00571 
00572 VOID
00573 ECDisp_MakeGUIDString(
00574     IN  GUID guid,
00575     OUT CHAR szString[],
00576     IN  UINT uiBuffSize
00577 );
00578 
00579 PCHAR
00580 ECDisp_GetHidAppStatusString(
00581     NTSTATUS StatusCode
00582 );
00583 
00584 BOOL
00585 ECDisp_ConvertUlongListToValueList(
00586     IN  PULONG  UlongList,
00587     IN  ULONG   nUlongs,
00588     IN  USHORT  BitSize,
00589     IN  USHORT  ReportCount,
00590     OUT PCHAR   *ValueList,
00591     OUT PULONG  ValueListSize
00592 );
00593 
00594 BOOL
00595 SetDlgItemIntHex(
00596    HWND hDlg,
00597    INT nIDDlgItem,
00598    UINT uValue,
00599    INT nBytes
00600 );
00601 
00602 PCHAR
00603 ResolveFunctionName(
00604     INT Index
00605 );
00606 
00607 
00608 DWORD WINAPI
00609 ECDisp_ReadThreadProc(
00610     LPVOID  ThreadContext
00611 );
00612 
00613 VOID
00614 DisplayExtendedAttributes(
00615     IN  HWND                OutputWindow,
00616     IN  PHIDP_UNKNOWN_TOKEN UnknownList,
00617     IN  ULONG               UnknownListLength
00618 );
00619 
00620 /*****************************************************************************
00621 /* Global function definitions
00622 /*****************************************************************************/
00623 
00624 LRESULT CALLBACK
00625 bExtCallDlgProc(
00626     HWND hDlg,
00627     UINT message,
00628     WPARAM wParam,
00629     LPARAM lParam
00630 )
00631 {
00632     static PHID_DEVICE          pDevice;
00633     static CHAR                 szTempBuff[1024];
00634     static CHAR                 szLabel[512];
00635     static CHAR                 szValue[512];
00636     static INT                  iLBCounter;
00637     static UCHAR                *pucInputReportIDs;
00638     static UCHAR                *pucOutputReportIDs;
00639     static UCHAR                *pucFeatureReportIDs;
00640     static INT                  nInputReportIDs;
00641     static INT                  nOutputReportIDs;
00642     static INT                  nFeatureReportIDs;
00643     static HANDLE               ReadThread;
00644     static READ_THREAD_CONTEXT  readContext;
00645 
00646            INT                  iIndex;
00647            ECDISPLAY_PARAMS     params;
00648            DWORD                threadID;
00649 
00650     switch (message)
00651     {
00652     case WM_INITDIALOG:
00653 
00654         /*
00655         // Initializing the dialog box involves the following steps:
00656         //  1) Determine from the parameter the pointer to the selected device
00657         //  2) Initializing the controls in the dialog box to their initial values
00658         //  3) Send a message that our list of routines has changed
00659         */
00660 
00661         pDevice = (PHID_DEVICE) lParam;
00662 
00663         vInitECControls(hDlg,
00664                         pDevice -> Caps.InputReportByteLength,
00665                         &pInputDisplay,
00666                         pDevice -> Caps.OutputReportByteLength,
00667                         &pOutputDisplay,
00668                         pDevice -> Caps.FeatureReportByteLength,
00669                         &pFeatureDisplay);
00670 
00671         ReadThread = NULL;
00672 
00673         PostMessage(hDlg,
00674                     WM_COMMAND,
00675                     IDC_EXTCALLS + (CBN_SELCHANGE << 16),
00676                     (LPARAM) GetDlgItem(hDlg,IDC_EXTCALLS));
00677         break;
00678 
00679     case WM_COMMAND:
00680         switch (LOWORD(wParam))
00681         {
00682         case IDC_EXTCALLS:
00683             switch (HIWORD(wParam))
00684             {
00685             case CBN_SELCHANGE:
00686                 iIndex = (INT) SendDlgItemMessage(hDlg,
00687                                                   IDC_EXTCALLS,
00688                                                   CB_GETCURSEL,
00689                                                   0,
00690                                                   0);
00691                 vEnableParameters(hDlg,
00692                                   SendDlgItemMessage(hDlg,
00693                                                      IDC_EXTCALLS,
00694                                                      CB_GETITEMDATA,
00695                                                      iIndex,
00696                                                      0));
00697                 break;
00698             }
00699             break;
00700 
00701         case IDC_INPUT_SELECT:
00702             if (CBN_SELCHANGE == HIWORD(wParam))
00703             {
00704                 BufferDisplay_ChangeSelection(pInputDisplay);
00705             }
00706             break;
00707 
00708         case IDC_OUTPUT_SELECT:
00709             if (CBN_SELCHANGE == HIWORD(wParam))
00710             {
00711                  BufferDisplay_ChangeSelection(pOutputDisplay);
00712             }
00713             break;
00714 
00715         case IDC_FEATURE_SELECT:
00716             if (CBN_SELCHANGE == HIWORD(wParam))
00717             {
00718                  BufferDisplay_ChangeSelection(pFeatureDisplay);
00719             }
00720             break;
00721 
00722         case IDC_EXECUTE:
00723             /*
00724             // Get the parameters and verify that they are all correct
00725             //   If there is an error, display an error message and
00726             //   don't continue any further.
00727             */
00728 
00729             if ( !fGetAndVerifyParameters(hDlg, &params) )
00730             {
00731                 ECDISP_ERROR(hDlg, "Error: One or more parameters are invalid");
00732             }
00733 
00734             /*
00735             // Else the parameters are valid and we can execute the call
00736             */
00737 
00738             else
00739             {
00740                 iIndex = (INT) SendDlgItemMessage(hDlg, IDC_EXTCALLS, CB_GETCURSEL, 0, 0);
00741                 iIndex = (INT) SendDlgItemMessage(hDlg, IDC_EXTCALLS, CB_GETITEMDATA, iIndex, 0);
00742 
00743                 /*
00744                 // Now that we know the function to execute we need to execute it
00745                 //    and output the data
00746                 */
00747 
00748                 SendDlgItemMessage(hDlg, IDC_CALLOUTPUT, LB_RESETCONTENT, 0, 0);
00749                 vExecuteAndDisplayOutput(GetDlgItem(hDlg, IDC_CALLOUTPUT), pDevice, iIndex, &params);
00750             }
00751             break;  /* end IDC_EXECUTE case */
00752 
00753         /*
00754         // Start up a read thread that can read input reports while
00755         //  we operate on the other stuff
00756         */
00757 
00758         case IDC_READ_SYNCH:
00759         case IDC_READ_ASYNCH:
00760 
00761             if (NULL == ReadThread)
00762             {
00763                 readContext.HidDevice = pDevice;
00764                 readContext.TerminateThread = FALSE;
00765                 readContext.DoOneRead = TRUE;
00766                 readContext.DisplayEvent = NULL;
00767                 readContext.DisplayWindow = hDlg;
00768 
00769                 ReadThread = CreateThread(  NULL,
00770                                             0,
00771                                             (LOWORD(wParam) == IDC_READ_SYNCH) ?
00772                                             SynchReadThreadProc :
00773                                             AsynchReadThreadProc,
00774                                             (LPVOID) &readContext,
00775                                             0,
00776                                             &threadID);
00777 
00778                 if (NULL == ReadThread)
00779                 {
00780                     MessageBox(hDlg,
00781                                "Unable to create read thread",
00782                                HCLIENT_ERROR,
00783                                MB_ICONEXCLAMATION);
00784                 }
00785                 else
00786                 {
00787                     EnableWindow(GetDlgItem(hDlg, IDC_READ_SYNCH),
00788                                  (LOWORD(wParam) == IDC_READ_SYNCH));
00789 
00790                     EnableWindow(GetDlgItem(hDlg, IDC_READ_ASYNCH),
00791                                  (LOWORD(wParam) == IDC_READ_ASYNCH));
00792 
00793                     SetWindowText(GetDlgItem(hDlg, LOWORD(wParam)),
00794                                   "Stop Read Thread");
00795 
00796                     EnableWindow(GetDlgItem(hDlg, IDC_CANCEL), FALSE);
00797                 }
00798             }
00799             else
00800             {
00801                 readContext.TerminateThread = TRUE;
00802 
00803                 WaitForSingleObject(ReadThread, INFINITE);
00804 
00805                 ReadThread = NULL;
00806 
00807                 SetWindowText(GetDlgItem(hDlg, IDC_READ_SYNCH),
00808                               "Start Synchronous Read Thread");
00809 
00810                 SetWindowText(GetDlgItem(hDlg, IDC_READ_ASYNCH),
00811                               "Start Asynchronous Read Thread");
00812 
00813                 EnableWindow(GetDlgItem(hDlg, IDC_READ_SYNCH), TRUE);
00814                 EnableWindow(GetDlgItem(hDlg, IDC_READ_ASYNCH), TRUE);
00815                 EnableWindow(GetDlgItem(hDlg, IDC_CANCEL), TRUE);
00816             }
00817             break;
00818 
00819         case IDC_CANCEL:
00820             BufferDisplay_Destroy(pInputDisplay);
00821             BufferDisplay_Destroy(pOutputDisplay);
00822             BufferDisplay_Destroy(pFeatureDisplay);
00823             EndDialog(hDlg, 0);
00824             break;
00825         }
00826         break;
00827 
00828     case WM_CLOSE:
00829         PostMessage(hDlg, WM_COMMAND, IDC_CANCEL, 0);
00830         break;
00831 
00832     }
00833     return FALSE;
00834 }
00835 
00836 VOID
00837 vLoadExtCalls(
00838     HWND hExtCalls
00839 )
00840 {
00841     INT  iIndex;
00842     UINT uiIndex;
00843 
00844     /*
00845     // Load the physical device specific calls
00846     */
00847 
00848     for (uiIndex = 0; uiIndex < HID_DEVCALLS; uiIndex++)
00849     {
00850         iIndex = (INT) SendMessage(hExtCalls,
00851                                    CB_ADDSTRING,
00852                                    0,
00853                                    (LPARAM) DeviceCalls[uiIndex].szFunctionName);
00854 
00855         if (CB_ERR != iIndex && CB_ERRSPACE != iIndex)
00856         {
00857             SendMessage(hExtCalls,
00858                         CB_SETITEMDATA,
00859                         iIndex,
00860                         DeviceCalls[uiIndex].uiIndex);
00861         }
00862     }
00863 
00864     /*
00865     // Load the other device calls no matter what
00866     */
00867 
00868     for (uiIndex = 0; uiIndex < HID_PPDCALLS; uiIndex++)
00869     {
00870         iIndex = (INT) SendMessage(hExtCalls,
00871                                    CB_ADDSTRING,
00872                                    0,
00873                                    (LPARAM) PpdCalls[uiIndex].szFunctionName);
00874 
00875         if (CB_ERR != iIndex && CB_ERRSPACE != iIndex)
00876         {
00877             SendMessage(hExtCalls,
00878                         CB_SETITEMDATA,
00879                         iIndex,
00880                         PpdCalls[uiIndex].uiIndex);
00881         }
00882     }
00883     SendMessage(hExtCalls, CB_SETCURSEL, 0, 0);
00884 
00885     return;
00886 }
00887 
00888 VOID vSetReportType(
00889     HWND hDlg,
00890     LONG lId
00891 )
00892 {
00893     CheckRadioButton(hDlg, IDC_INPUT, IDC_FEATURE, lId);
00894     return;
00895 }
00896 
00897 VOID
00898 vInitEditText(
00899     HWND hText,
00900     INT  cbTextSize,
00901     CHAR *pchText
00902 )
00903 {
00904     SendMessage(hText, EM_SETLIMITTEXT, (WPARAM) cbTextSize, 0);
00905     SendMessage(hText, EM_REPLACESEL, 0, (LPARAM) pchText);
00906 
00907     return;
00908 }
00909 
00910 VOID vEnableParameters(
00911     HWND     hDlg,
00912     LRESULT  iCallSelection
00913 )
00914 {
00915     EnableWindow(GetDlgItem(hDlg, IDC_INPUT), pState[iCallSelection-1].fInputReport);
00916     EnableWindow(GetDlgItem(hDlg, IDC_OUTPUT), pState[iCallSelection-1].fOutputReport);
00917     EnableWindow(GetDlgItem(hDlg, IDC_FEATURE), pState[iCallSelection-1].fFeatureReport);
00918     EnableWindow(GetDlgItem(hDlg, IDC_REPORTID), pState[iCallSelection-1].fReportID);
00919     EnableWindow(GetDlgItem(hDlg, IDC_USAGEPAGE), pState[iCallSelection-1].fUsagePage);
00920     EnableWindow(GetDlgItem(hDlg, IDC_USAGE), pState[iCallSelection-1].fUsage);
00921     EnableWindow(GetDlgItem(hDlg, IDC_LINKCOLL), pState[iCallSelection-1].fLinkCollection);
00922     EnableWindow(GetDlgItem(hDlg, IDC_INPUT_SELECT), pState[iCallSelection-1].fInputReportSelect);
00923     EnableWindow(GetDlgItem(hDlg, IDC_OUTPUT_SELECT), pState[iCallSelection-1].fOutputReportSelect);
00924     EnableWindow(GetDlgItem(hDlg, IDC_FEATURE_SELECT), pState[iCallSelection-1].fFeatureReportSelect);
00925 
00926     return;
00927 }
00928 
00929 BOOL
00930 fGetAndVerifyParameters(
00931     HWND              hDlg,
00932     PECDISPLAY_PARAMS pParams
00933 )
00934 {
00935     /*
00936     // Declare a text buffer of size 7 since the parameter limit is at most 6
00937     //   characters in the edit box.
00938     */
00939 
00940     CHAR    WindowText[7];
00941     BOOL    fStatus = TRUE;
00942     PCHAR   nptr;
00943 
00944     if (IsDlgButtonChecked(hDlg, IDC_INPUT))
00945     {
00946         pParams -> ReportType = HidP_Input;
00947     }
00948     else if (IsDlgButtonChecked(hDlg, IDC_OUTPUT))
00949     {
00950         pParams -> ReportType = HidP_Output;
00951     }
00952     else
00953     {
00954         pParams -> ReportType = HidP_Feature;
00955     }
00956 
00957     /*
00958     // Get and verify the usage page window text;
00959     */
00960 
00961     GetWindowText(GetDlgItem(hDlg, IDC_USAGEPAGE), WindowText, 7);
00962 
00963     pParams -> UsagePage = (USAGE) strtol(WindowText, &nptr, 16);
00964 
00965     if (*nptr != '\0')
00966     {
00967         fStatus = FALSE;
00968         pParams -> UsagePage = 0;
00969     }
00970 
00971     /*
00972     // Get and verify the usage window text
00973     */
00974 
00975     GetWindowText(GetDlgItem(hDlg, IDC_USAGE), WindowText, 7);
00976 
00977     pParams -> Usage = (USAGE) strtol(WindowText, &nptr, 16);
00978 
00979     if (*nptr != '\0')
00980     {
00981         fStatus = FALSE;
00982         pParams -> Usage = 0;
00983     }
00984 
00985     /*
00986     // Get and verify the link collection window text
00987     */
00988 
00989     GetWindowText(GetDlgItem(hDlg, IDC_LINKCOLL), WindowText, 7);
00990 
00991     pParams -> LinkCollection = (USAGE) strtol(WindowText, &nptr, 16);
00992 
00993     if (*nptr != '\0')
00994     {
00995         fStatus = FALSE;
00996         pParams -> LinkCollection = 0;
00997     }
00998 
00999     GetWindowText(GetDlgItem(hDlg, IDC_REPORTID), WindowText, 7);
01000 
01001     pParams -> ReportID = (UCHAR) strtol(WindowText, &nptr, 10);
01002 
01003     if (*nptr != '\0')
01004     {
01005         fStatus = FALSE;
01006         pParams -> ReportID = 0;
01007     }
01008 
01009     return (fStatus);
01010 }
01011 
01012 VOID
01013 vInitECControls(
01014     HWND                hDlg,
01015     USHORT              InputReportByteLength,
01016     PBUFFER_DISPLAY     *ppInputDisplay,
01017     USHORT              OutputReportByteLength,
01018     PBUFFER_DISPLAY     *ppOutputDisplay,
01019     USHORT              FeatureReportByteLength,
01020     PBUFFER_DISPLAY     *ppFeatureDisplay
01021 )
01022 {
01023     BOOLEAN     fInitStatus;
01024 
01025     /*
01026     // Begin by initializing the combo box with the calls that can be executed
01027     */
01028 
01029     vLoadExtCalls(GetDlgItem(hDlg, IDC_EXTCALLS));
01030 
01031     /*
01032     // Set the radio buttons initially to the input report type
01033     */
01034 
01035     vSetReportType(hDlg, IDC_INPUT);
01036 
01037     /*
01038     // Initialize the edit controls text
01039     */
01040 
01041     vInitEditText(GetDlgItem(hDlg, IDC_USAGEPAGE), 6, "0x0000");
01042     vInitEditText(GetDlgItem(hDlg, IDC_USAGE), 6, "0x0000");
01043     vInitEditText(GetDlgItem(hDlg, IDC_LINKCOLL), 2, "0");
01044     vInitEditText(GetDlgItem(hDlg, IDC_REPORTID), 3, "0");
01045 
01046     /*
01047     // Initialize the report buffer boxes
01048     */
01049 
01050     fInitStatus = BufferDisplay_Init(GetDlgItem(hDlg, IDC_INPUT_SELECT),
01051                                      GetDlgItem(hDlg, IDC_INPUT_BUFFER),
01052                                      NUM_INPUT_BUFFERS,
01053                                      InputReportByteLength,
01054                                      HidP_Input,
01055                                      ppInputDisplay);
01056 
01057     if (!fInitStatus)
01058     {
01059         ECDISP_ERROR(hDlg, "Error initializing input buffer display");
01060     }
01061 
01062     fInitStatus = BufferDisplay_Init(GetDlgItem(hDlg, IDC_OUTPUT_SELECT),
01063                                      GetDlgItem(hDlg, IDC_OUTPUT_BUFFER),
01064                                      NUM_OUTPUT_BUFFERS,
01065                                      OutputReportByteLength,
01066                                      HidP_Output,
01067                                      ppOutputDisplay);
01068 
01069     if (!fInitStatus)
01070     {
01071         ECDISP_ERROR(hDlg,  "Error initializing output buffer display");
01072     }
01073 
01074     fInitStatus = BufferDisplay_Init(GetDlgItem(hDlg, IDC_FEATURE_SELECT),
01075                                      GetDlgItem(hDlg, IDC_FEATURE_BUFFER),
01076                                      NUM_FEATURE_BUFFERS,
01077                                      FeatureReportByteLength,
01078                                      HidP_Feature,
01079                                      ppFeatureDisplay);
01080 
01081     if (!fInitStatus)
01082     {
01083         ECDISP_ERROR(hDlg, "Error initializing feature buffer display");
01084     }
01085 
01086     /*
01087     // Reset the output box content
01088     */
01089 
01090     SendMessage(GetDlgItem(hDlg, IDC_CALLOUTPUT), LB_RESETCONTENT, 0, 0);
01091     return;
01092 }
01093 
01094 BOOL
01095 ECDisp_Execute(
01096     IN     INT             FuncCall,
01097     IN OUT PEXTCALL_PARAMS CallParams,
01098     OUT    PEXTCALL_STATUS CallStatus
01099 )
01100 /*++
01101 RoutineDescription:
01102     This routine is a complex routine for executing all of the functions.  The
01103     routine was originally developed with consideration for future use that
01104     never materialized.
01105 
01106     It makes use of the calls in extcalls.c which basically execute the given
01107     function and does some verification on the buffers that are passed down to
01108     HID.DLL.
01109 
01110     The input parameters are specify the function call to execute, the
01111     call parameters structures and the call status structure.
01112 
01113     If any further buffers are needed for the specific calls, they will be
01114     allocated here.
01115 
01116     The CallStatus parameters is a structure set by the ExtCalls_ routines
01117 
01118     Future versions of the HClient sample may remove this routine and/or the
01119     ExtCalls_ routines to simply the code.
01120 --*/
01121 {
01122     BOOL                ExecuteStatus;
01123     HIDP_VALUE_CAPS     ValueCaps;
01124     USHORT              ValueCapsLength;
01125     PULONG              ValueList;
01126 
01127     NTSTATUS            status;
01128     DWORD               numBytes;
01129     ULONG               size;
01130 
01131     /*
01132     // Initially assume everything will go correctly and will set otherwise
01133     //    depending on the function call.
01134     */
01135 
01136     CallStatus -> IsHidError = FALSE;
01137 
01138     switch (FuncCall)
01139     {
01140     case HID_READ_REPORT:
01141         CallStatus -> IsHidError = !ReadFile(CallParams -> DeviceHandle,
01142                                              CallParams -> ReportBuffer,
01143                                              CallParams -> ReportLength,
01144                                              &numBytes,
01145                                              NULL);
01146         return (TRUE);
01147         break;
01148 
01149     case HID_WRITE_REPORT:
01150         CallStatus -> IsHidError = !WriteFile(CallParams -> DeviceHandle,
01151                                               CallParams -> ReportBuffer,
01152                                               CallParams -> ReportLength,
01153                                               &numBytes,
01154                                               NULL);
01155         return (TRUE);
01156         break;
01157 
01158     case HIDD_FLUSH_QUEUE:
01159         CallStatus -> IsHidError = !HidD_FlushQueue(CallParams -> DeviceHandle);
01160         return (TRUE);
01161         break;
01162 
01163     case HIDD_GET_HID_GUID:
01164         CallParams -> List = malloc(sizeof(GUID));
01165 
01166         if (NULL != CallParams -> List)
01167         {
01168             HidD_GetHidGuid((GUID *) CallParams -> List);
01169         }
01170         return (NULL != CallParams -> List);
01171         break;
01172 
01173     case HIDD_GET_PREPARSED_DATA:
01174         CallStatus -> IsHidError = !HidD_GetPreparsedData(CallParams -> DeviceHandle,
01175                                                           CallParams -> ppPd);
01176         return (TRUE);
01177 
01178     case HIDD_FREE_PREPARSED_DATA:
01179         CallStatus -> IsHidError = !HidD_FreePreparsedData(CallParams -> Ppd);
01180         return (TRUE);
01181 
01182     case HIDD_GET_ATTRIBUTES:
01183         CallParams -> List = malloc(sizeof(HIDD_ATTRIBUTES));
01184 
01185         if (NULL != CallParams -> List)
01186         {
01187             CallStatus -> IsHidError = !HidD_GetAttributes(CallParams -> DeviceHandle,
01188                                                            CallParams -> List);
01189         }
01190         return (NULL != CallParams -> List);
01191 
01192     case HIDD_GET_FEATURE:
01193         *(CallParams -> ReportBuffer) = CallParams -> ReportID;
01194 
01195         CallStatus -> IsHidError = !HidD_GetFeature(CallParams -> DeviceHandle,
01196                                                     CallParams -> ReportBuffer,
01197                                                     CallParams -> ReportLength);
01198         return (TRUE);
01199 
01200     case HIDD_SET_FEATURE:
01201         CallStatus -> IsHidError = !HidD_SetFeature(CallParams -> DeviceHandle,
01202                                                     CallParams -> ReportBuffer,
01203                                                     CallParams -> ReportLength);
01204         return (TRUE);
01205 
01206     case HIDD_GET_INPUT_REPORT:
01207         *(CallParams -> ReportBuffer) = CallParams -> ReportID;
01208 
01209         CallStatus -> IsHidError = !HidD_GetInputReport(CallParams -> DeviceHandle,
01210                                                         CallParams -> ReportBuffer,
01211                                                         CallParams -> ReportLength);
01212         return (TRUE);
01213 
01214     case HIDD_SET_OUTPUT_REPORT:
01215         CallStatus -> IsHidError = !HidD_SetOutputReport(CallParams -> DeviceHandle,
01216                                                          CallParams -> ReportBuffer,
01217                                                          CallParams -> ReportLength);
01218         return (TRUE);
01219 
01220     case HIDD_GET_NUM_INPUT_BUFFERS:
01221         CallStatus -> IsHidError = !HidD_GetNumInputBuffers(CallParams -> DeviceHandle,
01222                                                             &CallParams -> Value);
01223         return (TRUE);
01224 
01225     case HIDD_SET_NUM_INPUT_BUFFERS:
01226         CallStatus -> IsHidError = !HidD_SetNumInputBuffers(CallParams -> DeviceHandle,
01227                                                             CallParams -> Value);
01228 
01229         return (TRUE);
01230 
01231     case HIDD_GET_PHYSICAL_DESCRIPTOR:
01232         CallParams -> List = (PCHAR) malloc (CallParams -> ListLength);
01233 
01234         if (NULL != CallParams -> List )
01235         {
01236             CallStatus -> IsHidError = !HidD_GetPhysicalDescriptor(CallParams -> DeviceHandle,
01237                                                                    CallParams -> List,
01238                                                                    CallParams -> ListLength);
01239         }
01240         return (NULL != CallParams -> List);
01241 
01242     case HIDD_GET_MANUFACTURER_STRING:
01243 
01244         CallParams -> List = (PWCHAR) malloc (CallParams -> ListLength);
01245 
01246         if (NULL != CallParams -> List )
01247         {
01248             CallStatus -> IsHidError = !HidD_GetManufacturerString(CallParams -> DeviceHandle,
01249                                                                    CallParams -> List,
01250                                                                    CallParams -> ListLength);
01251         }
01252         return (NULL != CallParams -> List);
01253 
01254     case HIDD_GET_PRODUCT_STRING:
01255         CallParams -> List = (PWCHAR) malloc (CallParams -> ListLength);
01256 
01257         if (NULL != CallParams -> List )
01258         {
01259             CallStatus -> IsHidError = !HidD_GetProductString(CallParams -> DeviceHandle,
01260                                                              CallParams -> List,
01261                                                              CallParams -> ListLength);
01262         }
01263         return (NULL != CallParams -> List);
01264 
01265     case HIDP_GET_EXTENDED_ATTRIBUTES:
01266         CallParams -> List = (PWCHAR) malloc (CallParams -> ListLength);
01267         if (NULL != CallParams -> List )
01268         {
01269             status = pfnHidP_GetExtendedAttributes(CallParams -> ReportType,
01270                                                   (USHORT) CallParams -> Index,
01271                                                    CallParams -> Ppd,
01272                                                    CallParams -> List,
01273                                                    &CallParams -> ListLength);
01274 
01275             CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01276             CallStatus -> HidErrorCode = status;
01277         }
01278         return (NULL != CallParams -> List);
01279 
01280     case HIDD_GET_INDEXED_STRING:
01281         CallParams -> List = (PWCHAR) malloc (CallParams -> ListLength);
01282 
01283         if (NULL != CallParams -> List )
01284         {
01285             CallStatus -> IsHidError = !HidD_GetIndexedString(CallParams -> DeviceHandle,
01286                                                               CallParams -> Index,
01287                                                               CallParams -> List,
01288                                                               CallParams -> ListLength);
01289         }
01290         return (NULL != CallParams -> List);
01291 
01292     case HIDD_GET_SERIAL_NUMBER_STRING:
01293         CallParams -> List = (PWCHAR) malloc (CallParams -> ListLength);
01294 
01295         if (NULL != CallParams -> List )
01296         {
01297             CallStatus -> IsHidError = !HidD_GetSerialNumberString(CallParams -> DeviceHandle,
01298                                                                    CallParams -> List,
01299                                                                    CallParams -> ListLength);
01300         }
01301         return (NULL != CallParams -> List);
01302 
01303     case HIDD_GET_MS_GENRE_DESCRIPTOR:
01304         CallParams -> List = (PCHAR) malloc (CallParams -> ListLength);
01305 
01306         if (NULL != CallParams -> List )
01307         {
01308             CallStatus -> IsHidError = !HidD_GetMsGenreDescriptor(CallParams -> DeviceHandle,
01309                                                                   CallParams -> List,
01310                                                                   CallParams -> ListLength);
01311         }
01312         return (NULL != CallParams -> List);
01313 
01314     case HIDP_GET_BUTTON_CAPS:
01315         size = CallParams -> ListLength * sizeof(HIDP_BUTTON_CAPS);
01316 
01317         CallParams -> List = malloc(size);
01318 
01319         if (NULL != CallParams -> List)
01320         {
01321             status = HidP_GetButtonCaps(CallParams -> ReportType,
01322                                         CallParams -> List,
01323                                         (PUSHORT) &CallParams -> ListLength,
01324                                         CallParams -> Ppd);
01325 
01326             CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01327             CallStatus -> HidErrorCode = status;
01328         }
01329         return (NULL != CallParams -> List);
01330 
01331     case HIDP_GET_BUTTONS:
01332 
01333         CallParams -> ListLength = HidP_MaxUsageListLength(CallParams -> ReportType,
01334                                                            CallParams -> UsagePage,
01335                                                            CallParams -> Ppd);
01336 
01337         CallParams -> List = malloc(CallParams -> ListLength * sizeof(USAGE));
01338 
01339         if (NULL != CallParams -> List)
01340         {
01341             status = HidP_GetButtons(CallParams -> ReportType,
01342                                      CallParams -> UsagePage,
01343                                      CallParams -> LinkCollection,
01344                                      CallParams -> List,
01345                                      &CallParams -> ListLength,
01346                                      CallParams -> Ppd,
01347                                      CallParams -> ReportBuffer,
01348                                      CallParams -> ReportLength);
01349 
01350             CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01351             CallStatus -> HidErrorCode = status;
01352         }
01353         return (NULL != CallParams -> List);
01354 
01355     case HIDP_GET_BUTTONS_EX:
01356 
01357         CallParams -> ListLength = HidP_MaxUsageListLength(CallParams -> ReportType,
01358                                                            CallParams -> UsagePage,
01359                                                            CallParams -> Ppd);
01360 
01361         CallParams -> List = malloc(CallParams -> ListLength * sizeof(USAGE_AND_PAGE));
01362 
01363         if (NULL != CallParams -> List)
01364         {
01365             status = HidP_GetButtonsEx(CallParams -> ReportType,
01366                                        CallParams -> LinkCollection,
01367                                        CallParams -> List,
01368                                        &CallParams -> ListLength,
01369                                        CallParams -> Ppd,
01370                                        CallParams -> ReportBuffer,
01371                                        CallParams -> ReportLength);
01372 
01373             CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01374             CallStatus -> HidErrorCode = status;
01375         }
01376         return (NULL != CallParams -> List);
01377 
01378 
01379     case HIDP_GET_CAPS:
01380 
01381         CallParams -> ListLength = sizeof(HIDP_CAPS);
01382 
01383         CallParams -> List = malloc(sizeof(HIDP_CAPS));
01384 
01385         if (NULL != CallParams -> List)
01386         {
01387             status = HidP_GetCaps(CallParams -> Ppd, CallParams -> List);
01388 
01389             CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01390             CallStatus -> HidErrorCode = status;
01391         }
01392         return (NULL != CallParams -> List);
01393 
01394     case HIDP_GET_DATA:
01395 
01396         CallParams -> ListLength = HidP_MaxDataListLength(CallParams -> ReportType,
01397                                                           CallParams -> Ppd);
01398 
01399         CallParams -> List = malloc(CallParams -> ListLength * sizeof(HIDP_DATA));
01400 
01401         if (NULL != CallParams -> List)
01402         {
01403             status = HidP_GetData(CallParams -> ReportType,
01404                                   CallParams -> List,
01405                                   &CallParams -> ListLength,
01406                                   CallParams -> Ppd,
01407                                   CallParams -> ReportBuffer,
01408                                   CallParams -> ReportLength);
01409 
01410             CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01411             CallStatus -> HidErrorCode = status;
01412         }
01413         return (NULL != CallParams -> List);
01414 
01415     case HIDP_GET_LINK_COLL_NODES:
01416         CallParams -> List = malloc(CallParams -> ListLength * sizeof(HIDP_LINK_COLLECTION_NODE));
01417 
01418         if (NULL != CallParams -> List)
01419         {
01420             status = HidP_GetLinkCollectionNodes(CallParams -> List,
01421                                                  &CallParams -> ListLength,
01422                                                  CallParams -> Ppd);
01423 
01424             CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01425             CallStatus -> HidErrorCode = status;
01426         }
01427         return (NULL != CallParams -> List);
01428 
01429     case HIDP_GET_SCALED_USAGE_VALUE:
01430 
01431         status = HidP_GetScaledUsageValue(CallParams -> ReportType,
01432                                           CallParams -> UsagePage,
01433                                           CallParams -> LinkCollection,
01434                                           CallParams -> Usage,
01435                                          &CallParams -> ScaledValue,
01436                                           CallParams -> Ppd,
01437                                           CallParams -> ReportBuffer,
01438                                           CallParams -> ReportLength);
01439 
01440         CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01441         CallStatus -> HidErrorCode = status;
01442 
01443         return (TRUE);
01444 
01445     case HIDP_GET_SPECIFIC_BUTTON_CAPS:
01446 
01447         CallParams -> List = malloc(CallParams -> ListLength * sizeof(HIDP_BUTTON_CAPS));
01448 
01449         if (NULL != CallParams -> List)
01450         {
01451             status = HidP_GetSpecificButtonCaps(CallParams -> ReportType,
01452                                                 CallParams -> UsagePage,
01453                                                 CallParams -> LinkCollection,
01454                                                 CallParams -> Usage,
01455                                                 CallParams -> List,
01456                                                 (PUSHORT) &CallParams -> ListLength,
01457                                                 CallParams -> Ppd);
01458 
01459             CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01460             CallStatus -> HidErrorCode = status;
01461        }
01462        return (NULL != CallParams -> List);
01463 
01464     case HIDP_GET_SPECIFIC_VALUE_CAPS:
01465 
01466         CallParams -> List = malloc(CallParams -> ListLength * sizeof(HIDP_VALUE_CAPS));
01467 
01468         if (NULL != CallParams -> List)
01469         {
01470             status = HidP_GetSpecificValueCaps(CallParams -> ReportType,
01471                                                CallParams -> UsagePage,
01472                                                CallParams -> LinkCollection,
01473                                                CallParams -> Usage,
01474                                                CallParams -> List,
01475                                                (PUSHORT) &CallParams -> ListLength,
01476                                                CallParams -> Ppd);
01477 
01478             CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01479             CallStatus -> HidErrorCode = status;
01480        }
01481        return (NULL != CallParams -> List);
01482 
01483     case HIDP_GET_USAGES:
01484         CallParams -> ListLength = HidP_MaxUsageListLength(CallParams -> ReportType,
01485                                                            CallParams -> UsagePage,
01486                                                            CallParams -> Ppd);
01487 
01488         CallParams -> List = malloc(CallParams -> ListLength * sizeof(USAGE));
01489 
01490         if (NULL != CallParams -> List)
01491         {
01492             status = HidP_GetUsages(CallParams -> ReportType,
01493                                     CallParams -> UsagePage,
01494                                     CallParams -> LinkCollection,
01495                                     CallParams -> List,
01496                                    &CallParams -> ListLength,
01497                                     CallParams -> Ppd,
01498                                     CallParams -> ReportBuffer,
01499                                     CallParams -> ReportLength);
01500 
01501             CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01502             CallStatus -> HidErrorCode = status;
01503        }
01504        return (NULL != CallParams -> List);
01505 
01506     case HIDP_GET_USAGES_EX:
01507         CallParams -> ListLength = HidP_MaxUsageListLength(CallParams -> ReportType,
01508                                                            CallParams -> UsagePage,
01509                                                            CallParams -> Ppd);
01510 
01511         CallParams -> List = malloc(CallParams -> ListLength * sizeof(USAGE_AND_PAGE));
01512 
01513         if (NULL != CallParams -> List)
01514         {
01515             status = HidP_GetUsagesEx(CallParams -> ReportType,
01516                                       CallParams -> LinkCollection,
01517                                       CallParams -> List,
01518                                      &CallParams -> ListLength,
01519                                       CallParams -> Ppd,
01520                                       CallParams -> ReportBuffer,
01521                                       CallParams -> ReportLength);
01522 
01523             CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01524             CallStatus -> HidErrorCode = status;
01525        }
01526        return (NULL != CallParams -> List);
01527 
01528     case HIDP_GET_USAGE_VALUE:
01529         status = HidP_GetUsageValue(CallParams -> ReportType,
01530                                     CallParams -> UsagePage,
01531                                     CallParams -> LinkCollection,
01532                                     CallParams -> Usage,
01533                                     &CallParams -> Value,
01534                                     CallParams -> Ppd,
01535                                     CallParams -> ReportBuffer,
01536                                     CallParams -> ReportLength);
01537 
01538         CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01539         CallStatus -> HidErrorCode = status;
01540 
01541         return (TRUE);
01542 
01543     case HIDP_GET_USAGE_VALUE_ARRAY:
01544 
01545         ValueCapsLength = 1;
01546         status = HidP_GetSpecificValueCaps(CallParams -> ReportType,
01547                                            CallParams -> UsagePage,
01548                                            CallParams -> LinkCollection,
01549                                            CallParams -> Usage,
01550                                            &ValueCaps,
01551                                            &ValueCapsLength,
01552                                            CallParams -> Ppd);
01553 
01554         if (HIDP_STATUS_SUCCESS != status)
01555         {
01556             return (FALSE);
01557         }
01558 
01559         CallParams -> BitSize     = ValueCaps.BitSize;
01560         CallParams -> ReportCount = ValueCaps.ReportCount;
01561         CallParams -> ListLength
01562                  = ROUND_TO_NEAREST_BYTE(CallParams -> BitSize * CallParams -> ReportCount);
01563 
01564         CallParams -> List = malloc(CallParams -> ListLength);
01565 
01566         if (NULL != CallParams -> List)
01567         {
01568             status = HidP_GetUsageValueArray(CallParams -> ReportType,
01569                                              CallParams -> UsagePage,
01570                                              CallParams -> LinkCollection,
01571                                              CallParams -> Usage,
01572                                              CallParams -> List,
01573                                              (USHORT) CallParams -> ListLength,
01574                                              CallParams -> Ppd,
01575                                              CallParams -> ReportBuffer,
01576                                              CallParams -> ReportLength);
01577 
01578             CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01579             CallStatus -> HidErrorCode = status;
01580         }
01581         return (NULL != CallParams -> List);
01582 
01583     case HIDP_GET_VALUE_CAPS:
01584         CallParams -> List = malloc(CallParams -> ListLength * sizeof(HIDP_VALUE_CAPS));
01585         if (NULL != CallParams -> List)
01586         {
01587             status = HidP_GetValueCaps(CallParams -> ReportType,
01588                                        CallParams -> List,
01589                                        (PUSHORT) &CallParams -> ListLength,
01590                                        CallParams -> Ppd);
01591 
01592             CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01593             CallStatus -> HidErrorCode = status;
01594         }
01595 
01596 
01597     case HIDP_INITIALIZE_REPORT_FOR_ID:
01598 
01599         status = pfnHidP_InitializeReportForID(CallParams -> ReportType,
01600                                                CallParams -> ReportID,
01601                                                CallParams -> Ppd,
01602                                                CallParams -> ReportBuffer,
01603                                                CallParams -> ReportLength);
01604 
01605         CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01606         CallStatus -> HidErrorCode = status;
01607 
01608         return (TRUE);
01609 
01610     case HIDP_MAX_USAGE_LIST_LENGTH:
01611 
01612         CallParams -> Value = HidP_MaxUsageListLength(CallParams -> ReportType,
01613                                                       CallParams -> UsagePage,
01614                                                       CallParams -> Ppd);
01615 
01616         CallStatus -> IsHidError = FALSE;
01617         CallStatus -> HidErrorCode = HIDP_STATUS_SUCCESS;
01618 
01619         return (TRUE);
01620 
01621     case HIDP_MAX_DATA_LIST_LENGTH:
01622 
01623         CallParams -> Value = HidP_MaxDataListLength(CallParams -> ReportType,
01624                                                      CallParams -> Ppd);
01625 
01626         CallStatus -> IsHidError = FALSE;
01627         CallStatus -> HidErrorCode = HIDP_STATUS_SUCCESS;
01628 
01629         return (TRUE);
01630 
01631     case HIDP_SET_BUTTONS:
01632 
01633         status = HidP_SetButtons(CallParams -> ReportType,
01634                                  CallParams -> UsagePage,
01635                                  CallParams -> LinkCollection,
01636                                  CallParams -> List,
01637                                  &CallParams -> ListLength,
01638                                  CallParams -> Ppd,
01639                                  CallParams -> ReportBuffer,
01640                                  CallParams -> ReportLength);
01641 
01642         CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01643         CallStatus -> HidErrorCode = status;
01644 
01645         return (TRUE);
01646 
01647     case HIDP_SET_DATA:
01648 
01649         status = HidP_SetData(CallParams -> ReportType,
01650                               CallParams -> List,
01651                               &CallParams -> ListLength,
01652                               CallParams -> Ppd,
01653                               CallParams -> ReportBuffer,
01654                               CallParams -> ReportLength);
01655 
01656         CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01657         CallStatus -> HidErrorCode = status;
01658 
01659         return (TRUE);
01660 
01661     case HIDP_SET_SCALED_USAGE_VALUE:
01662         status = HidP_SetUsageValue(CallParams -> ReportType,
01663                                     CallParams -> UsagePage,
01664                                     CallParams -> LinkCollection,
01665                                     CallParams -> Usage,
01666                                     CallParams -> ScaledValue,
01667                                     CallParams -> Ppd,
01668                                     CallParams -> ReportBuffer,
01669                                     CallParams -> ReportLength);
01670 
01671         CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01672         CallStatus -> HidErrorCode = status;
01673 
01674         return (TRUE);
01675 
01676     case HIDP_SET_USAGES:
01677         status = HidP_SetUsages(CallParams -> ReportType,
01678                                 CallParams -> UsagePage,
01679                                 CallParams -> LinkCollection,
01680                                 CallParams -> List,
01681                                &CallParams -> ListLength,
01682                                 CallParams -> Ppd,
01683                                 CallParams -> ReportBuffer,
01684                                 CallParams -> ReportLength);
01685 
01686         CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01687         CallStatus -> HidErrorCode = status;
01688 
01689         return (TRUE);
01690 
01691     case HIDP_SET_USAGE_VALUE:
01692         status = HidP_SetUsageValue(CallParams -> ReportType,
01693                                     CallParams -> UsagePage,
01694                                     CallParams -> LinkCollection,
01695                                     CallParams -> Usage,
01696                                     CallParams -> Value,
01697                                     CallParams -> Ppd,
01698                                     CallParams -> ReportBuffer,
01699                                     CallParams -> ReportLength);
01700 
01701         CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01702         CallStatus -> HidErrorCode = status;
01703 
01704         return (TRUE);
01705 
01706     case HIDP_SET_USAGE_VALUE_ARRAY:
01707 
01708         ValueCapsLength = 1;
01709         status = HidP_GetSpecificValueCaps(CallParams -> ReportType,
01710                                            CallParams -> UsagePage,
01711                                            CallParams -> LinkCollection,
01712                                            CallParams -> Usage,
01713                                            &ValueCaps,
01714                                            &ValueCapsLength,
01715                                            CallParams -> Ppd);
01716 
01717         if (HIDP_STATUS_SUCCESS != status)
01718         {
01719             return (FALSE);
01720         }
01721 
01722         CallParams -> BitSize     = ValueCaps.BitSize;
01723         CallParams -> ReportCount = ValueCaps.ReportCount;
01724 
01725         ValueList = CallParams -> List;
01726         ExecuteStatus = ECDisp_ConvertUlongListToValueList(ValueList,
01727                                                            CallParams -> ListLength,
01728                                                            CallParams -> BitSize,
01729                                                            CallParams -> ReportCount,
01730                                                            (PCHAR *) &CallParams -> List,
01731                                                            &CallParams -> ListLength);
01732 
01733         if (!ExecuteStatus)
01734         {
01735             return (FALSE);
01736         }
01737 
01738         status = HidP_SetUsageValueArray(CallParams -> ReportType,
01739                                          CallParams -> UsagePage,
01740                                          CallParams -> LinkCollection,
01741                                          CallParams -> Usage,
01742                                          CallParams -> List,
01743                                          (USHORT) CallParams -> ListLength,
01744                                          CallParams -> Ppd,
01745                                          CallParams -> ReportBuffer,
01746                                          CallParams -> ReportLength);
01747 
01748         CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01749         CallStatus -> HidErrorCode = status;
01750 
01751         return (TRUE);
01752 
01753     case HIDP_UNSET_BUTTONS:
01754         status = HidP_UnsetButtons(CallParams -> ReportType,
01755                                    CallParams -> UsagePage,
01756                                    CallParams -> LinkCollection,
01757                                    CallParams -> List,
01758                                    &CallParams -> ListLength,
01759                                    CallParams -> Ppd,
01760                                    CallParams -> ReportBuffer,
01761                                    CallParams -> ReportLength);
01762 
01763         CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01764         CallStatus -> HidErrorCode = status;
01765 
01766         return (TRUE);
01767 
01768     case HIDP_UNSET_USAGES:
01769         status = HidP_UnsetUsages(CallParams -> ReportType,
01770                                   CallParams -> UsagePage,
01771                                   CallParams -> LinkCollection,
01772                                   CallParams -> List,
01773                                  &CallParams -> ListLength,
01774                                   CallParams -> Ppd,
01775                                   CallParams -> ReportBuffer,
01776                                   CallParams -> ReportLength);
01777 
01778         CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01779         CallStatus -> HidErrorCode = status;
01780 
01781         return (TRUE);
01782 
01783     case HIDP_USAGE_LIST_DIFFERENCE:
01784         CallParams -> MakeList = (PUSAGE) malloc (sizeof(USAGE) * CallParams -> ListLength);
01785 
01786         if (NULL == CallParams -> MakeList)
01787         {
01788             return (FALSE);
01789         }
01790 
01791         CallParams -> BreakList = (PUSAGE) malloc (sizeof(USAGE) * CallParams -> ListLength);
01792         if (NULL == CallParams -> BreakList)
01793         {
01794             free(CallParams -> MakeList);
01795 
01796             return (FALSE);
01797         }
01798 
01799         status = HidP_UsageListDifference(CallParams -> List,
01800                                           CallParams -> List2,
01801                                           CallParams -> BreakList,
01802                                           CallParams -> MakeList,
01803                                           CallParams -> ListLength);
01804 
01805         CallStatus -> IsHidError = (HIDP_STATUS_SUCCESS != status);
01806         CallStatus -> HidErrorCode = status;
01807 
01808         return (TRUE);
01809     }
01810     return (FALSE);
01811 }
01812 
01813 VOID
01814 ECDisp_DisplayOutput(
01815     IN HWND            hOutputWindow,
01816     IN INT             FuncCall,
01817     IN PEXTCALL_PARAMS Results
01818 )
01819 /*++
01820 RoutineDescription:
01821     This routine is responsible for displaying the output from calls to HID.DLL
01822     functions.  It must extract and interpret the appropriate data from the
01823     PEXTCALL_PARAMS structure.
01824 --*/
01825 {
01826     PHIDP_LINK_COLLECTION_NODE NodeList;
01827     PHIDP_BUTTON_CAPS          ButtonCaps;
01828     PHIDP_VALUE_CAPS           ValueCaps;
01829     PHIDP_DATA                 DataList;
01830     PHIDP_EXTENDED_ATTRIBUTES  ExtAttrib;
01831     PUSAGE_AND_PAGE            UsageAndPageList;
01832     PUSAGE                     UsageList;
01833     PCHAR                      UsageValueArray;
01834     PBUFFER_DISPLAY            pDisplay;
01835     PCHAR                      PhysDescString;
01836     PCHAR                      GenreDescString;
01837     SIZE_T                     StringLength;
01838     UINT                       RemainingBuffer=0;
01839 
01840     ULONG                      Index;
01841     HRESULT                       stringReturn;
01842 
01843 
01844     switch (FuncCall) {
01845     case HIDD_GET_HID_GUID:
01846 
01847         stringReturn = StringCbCopy(szTempBuffer, TEMP_BUFFER_SIZE, "HID Guid: ");
01848         StringLength = strlen(szTempBuffer);
01849         if (StringLength < TEMP_BUFFER_SIZE)
01850         {
01851             RemainingBuffer = (UINT)(TEMP_BUFFER_SIZE - StringLength);
01852         }
01853         ECDisp_MakeGUIDString(*((LPGUID) Results -> List),
01854                               &szTempBuffer[StringLength],
01855                               RemainingBuffer);
01856 
01857         OUTSTRING(hOutputWindow, szTempBuffer);
01858         break;
01859 
01860     case HIDD_GET_ATTRIBUTES:
01861         vDisplayDeviceAttributes((PHIDD_ATTRIBUTES) Results -> List,
01862                                  hOutputWindow);
01863         break;
01864 
01865     case HIDD_GET_NUM_INPUT_BUFFERS:
01866         stringReturn = StringCbPrintf(szTempBuffer, TEMP_BUFFER_SIZE,
01867                        "Number input buffers: %u", Results -> Value);
01868 
01869         OUTSTRING(hOutputWindow, szTempBuffer);
01870         break;
01871 
01872     case HIDD_GET_MS_GENRE_DESCRIPTOR:
01873         OUTSTRING(hOutputWindow, "MS Genre Descriptor");
01874         OUTSTRING(hOutputWindow, "===================");
01875 
01876             /*
01877         // To display a physical descriptor, the procedure currently just
01878         //   creates a string data buffer by bytes and displays that
01879         //   in the results box.  It will display in rows of 16 bytes apiece.
01880         */
01881 
01882         Index = 0;
01883         while (Index < Results -> ListLength)
01884         {
01885             Strings_CreateDataBufferString(((PCHAR) Results -> List) + Index,
01886                                            Results -> ListLength - Index,
01887                                            16,
01888                                            1,
01889                                            &GenreDescString);
01890 
01891             if (NULL != GenreDescString)
01892             {
01893                 OUTSTRING(hOutputWindow, GenreDescString);
01894                 free(GenreDescString);
01895             }
01896             else
01897             {
01898                OUTSTRING(hOutputWindow, "Error trying to display ms genre descriptor");
01899             }
01900             Index += 16;
01901         }
01902         break;
01903 
01904     case HIDD_GET_PHYSICAL_DESCRIPTOR:
01905         OUTSTRING(hOutputWindow, "Physical Descriptor");
01906         OUTSTRING(hOutputWindow, "===================");
01907 
01908         /*
01909         // To display a physical descriptor, the procedure currently just
01910         //   creates a string data buffer by bytes and displays that
01911         //   in the results box.  It will display in rows of 16 bytes apiece.
01912         */
01913 
01914         Index = 0;
01915         while (Index < Results -> ListLength)
01916         {
01917             Strings_CreateDataBufferString(((PCHAR) Results -> List) + Index,
01918                                            Results -> ListLength - Index,
01919                                            16,
01920                                            1,
01921                                            &PhysDescString);
01922 
01923             if (NULL != PhysDescString)
01924             {
01925                 OUTSTRING(hOutputWindow, PhysDescString);
01926                 free(PhysDescString);
01927             }
01928             else
01929             {
01930                OUTSTRING(hOutputWindow, "Error trying to display physical descriptor");
01931             }
01932             Index += 16;
01933         }
01934         break;
01935 
01936     /*
01937     // For the string descriptor call routines, the returned string is stored
01938     //   in the Results -> List parameter.  It should be noted that the
01939     //   strings returned by these calls are wide-char strings and that these
01940     //   string are terminated with a NULL character if there was space within
01941     //   the buffer to add such a character.  If the buffer was only big enough
01942     //   to hold the characters of the string, there will be no null terminator
01943     //   and the output string display mechanism may fail to properly display this
01944     //   type of string.  Fixing of this display mechanism is a future (low priority)
01945     //   work-item.
01946     */
01947 
01948     case HIDD_GET_PRODUCT_STRING:
01949         OUTSTRING(hOutputWindow, "Product String");
01950         OUTSTRING(hOutputWindow, "==============");
01951         OUTWSTRING(hOutputWindow, Results -> List);
01952         break;
01953 
01954     case HIDD_GET_MANUFACTURER_STRING:
01955         OUTSTRING(hOutputWindow, "Manufacturer String");
01956         OUTSTRING(hOutputWindow, "===================");
01957         OUTWSTRING(hOutputWindow, Results -> List);
01958         break;
01959 
01960     case HIDD_GET_INDEXED_STRING:
01961         stringReturn = StringCbPrintf(szTempBuffer, TEMP_BUFFER_SIZE,
01962                        "Indexed String #%u:", Results -> Index);
01963 
01964         OUTSTRING(hOutputWindow, szTempBuffer);
01965         OUTSTRING(hOutputWindow, "===================");
01966         OUTWSTRING(hOutputWindow, Results -> List);
01967         break;
01968 
01969     case HIDD_GET_SERIAL_NUMBER_STRING:
01970         OUTSTRING(hOutputWindow, "Serial Number String");
01971         OUTSTRING(hOutputWindow, "=====================");
01972         OUTWSTRING(hOutputWindow, Results -> List);
01973         break;
01974 
01975     case HIDP_GET_BUTTON_CAPS:
01976     case HIDP_GET_SPECIFIC_BUTTON_CAPS:
01977 
01978         ButtonCaps = (PHIDP_BUTTON_CAPS) (Results -> List);
01979         for (Index = 0; Index < Results -> ListLength; Index++, ButtonCaps++)
01980         {
01981              OUTSTRING(hOutputWindow, "==========================");
01982              vDisplayButtonAttributes(ButtonCaps, hOutputWindow);
01983         }
01984         break;
01985 
01986     /*
01987     // HidP_GetButtons and HidP_GetUsages are in reality the same call.
01988     //   HidP_GetButtons actually a macro which gets redefined into
01989     //   HidP_GetUsages with the same parameter order.  That is why their
01990     //   display mechanisms are identical.  This call returns in the
01991     //   List parameter a list of Usages.  The display mechanism converts
01992     //   these usages into a string of numbers.
01993     */
01994 
01995     case HIDP_GET_BUTTONS:
01996     case HIDP_GET_USAGES:
01997 
01998         OUTSTRING(hOutputWindow, "Usages Returned");
01999         OUTSTRING(hOutputWindow, "===============");
02000 
02001         UsageList = (PUSAGE) Results -> List;
02002         for (Index = 0; Index < Results -> ListLength; Index++)
02003         {
02004             vCreateUsageString(UsageList + Index, szTempBuffer);
02005 
02006             OUTSTRING(hOutputWindow, szTempBuffer);
02007         }
02008         break;
02009 
02010     /*
02011     // Like get their siblings, the normal get functions, these routines are
02012     //   currently one in the same.  The difference between these routines
02013     //   and their siblings is the return of a usage page along with each
02014     //   usage.  Therefore, both values must be displayed at the same time.
02015     */
02016 
02017     case HIDP_GET_BUTTONS_EX:
02018     case HIDP_GET_USAGES_EX:
02019 
02020         OUTSTRING(hOutputWindow, "Usages Returned");
02021         OUTSTRING(hOutputWindow, "===============");
02022 
02023         UsageAndPageList = (PUSAGE_AND_PAGE) Results -> List;
02024         for (Index = 0; Index < Results -> ListLength; Index++)
02025         {
02026             vCreateUsageAndPageString(UsageAndPageList + Index,
02027                                       szTempBuffer);
02028 
02029             OUTSTRING(hOutputWindow, szTempBuffer);
02030         }
02031         break;
02032 
02033     case HIDP_GET_CAPS:
02034         vDisplayDeviceCaps((PHIDP_CAPS) Results -> List, hOutputWindow);
02035         break;
02036 
02037     case HIDP_GET_DATA:
02038         OUTSTRING(hOutputWindow, "Data Indices");
02039         OUTSTRING(hOutputWindow, "============");
02040 
02041         DataList = (PHIDP_DATA) Results -> List;
02042         for (Index = 0; Index < Results -> ListLength; Index++)
02043         {
02044             vDisplayDataAttributes(DataList+Index,
02045                                    FALSE,
02046                                    hOutputWindow);
02047         }
02048         break;
02049 
02050     case HIDP_GET_EXTENDED_ATTRIBUTES:
02051         OUTSTRING(hOutputWindow, "Extended Attributes");
02052         OUTSTRING(hOutputWindow, "===================");
02053 
02054         ExtAttrib = (PHIDP_EXTENDED_ATTRIBUTES) Results -> List;
02055 
02056         DisplayExtendedAttributes(hOutputWindow,
02057                                   ExtAttrib -> GlobalUnknowns,
02058                                   ExtAttrib -> NumGlobalUnknowns);
02059         break;
02060 
02061     case HIDP_GET_LINK_COLL_NODES:
02062 
02063         OUTSTRING(hOutputWindow, "Link Collection Nodes");
02064         OUTSTRING(hOutputWindow, "=====================");
02065 
02066         NodeList = (PHIDP_LINK_COLLECTION_NODE) Results -> List;
02067         for (Index = 0; Index < Results -> ListLength; Index++)
02068         {
02069             OUTSTRING(hOutputWindow, "===========================");
02070             vDisplayLinkCollectionNode(NodeList+Index,
02071                                        Index,
02072                                        hOutputWindow);
02073         }
02074         break;
02075 
02076     case HIDP_GET_SCALED_USAGE_VALUE:
02077 
02078         stringReturn = StringCbPrintf(szTempBuffer, TEMP_BUFFER_SIZE,
02079                        "Scaled usage value: %ld", Results -> ScaledValue);
02080         OUTSTRING(hOutputWindow, szTempBuffer);
02081 
02082         break;
02083 
02084     case HIDP_GET_USAGE_VALUE:
02085         stringReturn = StringCbPrintf(szTempBuffer, TEMP_BUFFER_SIZE,
02086                        "Usage value: %lu", Results -> Value);
02087         OUTSTRING(hOutputWindow, szTempBuffer);
02088         break;
02089 
02090     /*
02091     // To display a usage value array, we must extract each of the values
02092     //   in the array based on the ReportSize.  The ReportSize is not necessarily
02093     //   an even byte size so we must use the special extraction routine to get
02094     //   each of the values in the array.
02095     */
02096 
02097     case HIDP_GET_USAGE_VALUE_ARRAY:
02098 
02099         UsageValueArray = (PCHAR) Results -> List;
02100 
02101         for (Index = 0; Index < Results -> ReportCount; Index++)
02102         {
02103             vCreateUsageValueStringFromArray(UsageValueArray,
02104                                              Results -> BitSize,
02105                                              (USHORT) Index,
02106                                              szTempBuffer);
02107 
02108             OUTSTRING(hOutputWindow, szTempBuffer);
02109         }
02110         break;
02111 
02112     case HIDP_GET_VALUE_CAPS:
02113     case HIDP_GET_SPECIFIC_VALUE_CAPS:
02114 
02115         ValueCaps = (PHIDP_VALUE_CAPS) Results -> List;
02116 
02117         for (Index = 0; Index < (INT) Results -> ListLength; Index++)
02118         {
02119             OUTSTRING(hOutputWindow, "==========================");
02120             vDisplayValueAttributes(ValueCaps + Index,
02121                                     hOutputWindow);
02122         }
02123         break;
02124 
02125     case HIDP_MAX_DATA_LIST_LENGTH:
02126         stringReturn = StringCbPrintf(szTempBuffer, TEMP_BUFFER_SIZE,
02127                        "MaxDataListLength: %u", Results -> Value);
02128         OUTSTRING(hOutputWindow, szTempBuffer);
02129         break;
02130 
02131     case HIDP_MAX_USAGE_LIST_LENGTH:
02132         stringReturn = StringCbPrintf(szTempBuffer, TEMP_BUFFER_SIZE,
02133                        "MaxUsageListLength: %u", Results -> Value);
02134         OUTSTRING(hOutputWindow, szTempBuffer);
02135         break;
02136 
02137     /*
02138     // For HidP_UsageListDifference, we need to display both of the make and
02139     //   break lists generated by the function.  Therefore, we end up creating
02140     //   two different usage list strings.
02141     */
02142 
02143     case HIDP_USAGE_LIST_DIFFERENCE:
02144 
02145         OUTSTRING(hOutputWindow, "Make List");
02146         OUTSTRING(hOutputWindow, "=========");
02147 
02148         UsageList = (PUSAGE) Results -> MakeList;
02149         Index = 0;
02150 
02151         while (0 != *(UsageList+Index) && Index < Results -> ListLength)
02152         {
02153             vCreateUsageString(UsageList + Index,
02154                                szTempBuffer);
02155 
02156             OUTSTRING(hOutputWindow, szTempBuffer);
02157             Index++;
02158         }
02159 
02160         OUTSTRING(hOutputWindow, "Break List");
02161         OUTSTRING(hOutputWindow, "==========");
02162 
02163         UsageList = (PUSAGE) Results -> BreakList;
02164         Index = 0;
02165 
02166         while (0 != *(UsageList+Index) && Index < Results -> ListLength)
02167         {
02168             vCreateUsageString(UsageList + Index,
02169                                szTempBuffer);
02170 
02171             OUTSTRING(hOutputWindow, szTempBuffer);
02172             Index++;
02173         }
02174         break;
02175 
02176     /*
02177     // These functions simply update the buffer that is specified as the
02178     //   input parameter.  We must select the correct display buffer mechanism
02179     //   based on the ReportType for the call and then update the given report
02180     //   in that display mechanism.
02181     */
02182 
02183     case HID_READ_REPORT:
02184     case HIDD_GET_FEATURE:
02185     case HIDD_GET_INPUT_REPORT:
02186     case HIDP_INITIALIZE_REPORT_FOR_ID:
02187     case HIDP_SET_BUTTONS:
02188     case HIDP_SET_DATA:
02189     case HIDP_SET_SCALED_USAGE_VALUE:
02190     case HIDP_SET_USAGES:
02191     case HIDP_SET_USAGE_VALUE:
02192     case HIDP_SET_USAGE_VALUE_ARRAY:
02193     case HIDP_UNSET_BUTTONS:
02194     case HIDP_UNSET_USAGES:
02195         SELECT_ON_REPORT_TYPE(Results -> ReportType,
02196                               pInputDisplay,
02197                               pOutputDisplay,
02198                               pFeatureDisplay,
02199                               pDisplay);
02200 
02201         BufferDisplay_UpdateBuffer(pDisplay,
02202                                    Results -> ReportBuffer);
02203         break;
02204     }
02205     return;
02206 }
02207 
02208 VOID
02209 vExecuteAndDisplayOutput(
02210     HWND              hOutputWindow,
02211     PHID_DEVICE       pDevice,
02212     INT               iFuncCall,
02213     PECDISPLAY_PARAMS params
02214 )
02215 /*++
02216 RoutineDescription:
02217     This routine is a long function that is responsible for retrieving all the
02218     parameter for a given function call, setting up the CallParameters structure
02219     and then call the execute routine to get the necessary results and status of
02220     the operation.  It is then responsible for displaying the appropriate status
02221     and results if the function did not fail
02222 
02223     This routine is a fairly long, complex routine to do a simple task.  It may
02224     be broken down in future versions to simplify some of the complexity.
02225 --*/
02226 {
02227     EXTCALL_PARAMS    CallParameters;
02228     EXTCALL_STATUS    CallStatus;
02229 
02230     DLGBOX_STATUS     iDlgStatus;
02231     BOOL              ExecuteStatus;
02232     PBUFFER_DISPLAY   pBufferDisplay;
02233     PCHAR             pCopyBuffer;
02234     PCHAR             endp;
02235     UINT              DlgBoxNumber;
02236     BOOL              List2Alloc;
02237     BOOL              MakeListAlloc;
02238     BOOL              BreakListAlloc;
02239 
02240     HID_DEVICE        readDevice, writeDevice;
02241     BOOL              status;
02242     HRESULT              stringReturn;
02243 
02244     /*
02245     // ExecuteAndDisplayOutput needless to say, consists of two parts:
02246     //    Executing and Displaying output.  The first section involves the
02247     //     execution phase where all parameters are filled in if necessary
02248     //     and ECDisp_Execute is called
02249     */
02250 
02251     if (IS_NOT_IMPLEMENTED(iFuncCall))
02252     {
02253         OUTSTRING(hOutputWindow, "Function not yet implemented");
02254         return;
02255     }
02256 
02257     /*
02258     // Check first to see if this is a HID_CLEAR_REPORT command.  If it is
02259     //    all we need to do is get the report buffer that is checked and
02260     //    then call the clear buffer command
02261     */
02262 
02263     if (HID_CLEAR_REPORT == iFuncCall)
02264     {
02265         SELECT_ON_REPORT_TYPE(params -> ReportType,
02266                               pInputDisplay,
02267                               pOutputDisplay,
02268                               pFeatureDisplay,
02269                               pBufferDisplay);
02270 
02271         BufferDisplay_ClearBuffer(pBufferDisplay);
02272         return;
02273     }
02274 
02275     /*
02276     // Need to perform the following steps in order to get the parameters for
02277     //    our call and then execute the call:
02278     //      1) Get any additional parameters not supplied by the above dialog
02279     //           procedure.  This occurs for such functions as:
02280     //                  HIDP_SET_BUTTONS
02281     //                  HIDP_SET_DATA
02282     //                  HIDP_SET_USAGES
02283     //                  HIDP_SET_USAGE_VALUE
02284     //                  HIDP_SET_SCALED_USAGE_VALUE
02285     //                  HIDP_SET_USAGE_VALUE_ARRAY
02286     //                  HIDP_UNSET_BUTTONS
02287     //                  HIDP_UNSET_USAGES
02288     //          For these functions, a separate dialog box must be called
02289     //
02290     //      2) Fill in the common parameters from the passed in params struct
02291     //
02292     */
02293 
02294     /*
02295     // Step 1: We're storing the values retrieved by these additional dialog
02296     //          box in the params struct since we may actually be passed in
02297     //          these values in the future instead of getting them here.  Hence,
02298     //          we won't break any of the code that follows the switch statement
02299     */
02300 
02301     switch (iFuncCall)
02302     {
02303     case HIDP_SET_BUTTONS:
02304     case HIDP_SET_USAGES:
02305     case HIDP_UNSET_BUTTONS:
02306     case HIDP_UNSET_USAGES:
02307 
02308         switch (iFuncCall)
02309         {
02310         case HIDP_SET_BUTTONS:
02311             DlgBoxNumber = IDD_SET_BUTTONS;
02312             break;
02313 
02314         case HIDP_SET_USAGES:
02315             DlgBoxNumber = IDD_SET_USAGES;
02316             break;
02317 
02318         case HIDP_UNSET_BUTTONS:
02319             DlgBoxNumber = IDD_UNSET_BUTTONS;
02320             break;
02321 
02322         case HIDP_UNSET_USAGES:
02323             DlgBoxNumber = IDD_UNSET_USAGES;
02324             break;
02325         }
02326 
02327         iDlgStatus = (DLGBOX_STATUS) DialogBoxParam(NULL,
02328                                                     MAKEINTRESOURCE(DlgBoxNumber),
02329                                                     GetParent(hOutputWindow),
02330                                                     bSetUsagesDlgProc,
02331                                                     (LPARAM) params);
02332         /*
02333         // If the above call returns 1, then the dialog box routine
02334         //     successfully acquired a string from the user and put the
02335         //     pointer to it in params -> szListString.
02336         //     Now we need to convert the string to a usage list
02337         */
02338 
02339         if (DLGBOX_OK != iDlgStatus)
02340             return;
02341 
02342         ExecuteStatus = ConvertStringToUsageList(params -> szListString,
02343                                                  &params -> UsageList,
02344                                                  &params -> ListLength);
02345         free(params -> szListString);
02346 
02347         if (!ExecuteStatus)
02348         {
02349             ECDISP_ERROR(GetParent(hOutputWindow),
02350                          "Error getting usage list");
02351             return;
02352         }
02353         break;
02354 
02355     case HIDP_GET_EXTENDED_ATTRIBUTES:
02356         iDlgStatus = (DLGBOX_STATUS) DialogBoxParam(NULL,
02357                                                     MAKEINTRESOURCE(IDD_GET_EXT_ATTRIB),
02358                                                     GetParent(hOutputWindow),
02359                                                     bGetIndexedDlgProc,
02360                                                     (LPARAM) params);
02361 
02362         if (DLGBOX_OK != iDlgStatus)
02363             return;
02364 
02365         params -> Index = strtoul(params -> szListString, &endp, 10);
02366 
02367         if ('\0' != *endp)
02368         {
02369             ECDISP_ERROR(GetParent(hOutputWindow),
02370                          "Invalid index value");
02371 
02372             free(params -> szListString);
02373             free(params -> szListString2);
02374             return;
02375         }
02376 
02377         free(params -> szListString);
02378         params -> ListLength = strtoul(params -> szListString2, &endp, 10);
02379 
02380         if ('\0' != *endp)
02381         {
02382             ECDISP_ERROR(GetParent(hOutputWindow),
02383                          "Invalid buffer size");
02384 
02385             free(params -> szListString2);
02386             return;
02387         }
02388         free(params -> szListString2);
02389         break;
02390 
02391     case HIDD_GET_INDEXED_STRING:
02392         iDlgStatus = (DLGBOX_STATUS) DialogBoxParam(NULL,
02393                                                     MAKEINTRESOURCE(IDD_GET_INDEX_STRING),
02394                                                     GetParent(hOutputWindow),
02395                                                     bGetIndexedDlgProc,
02396                                                     (LPARAM) params);
02397 
02398         if (DLGBOX_OK != iDlgStatus)
02399             return;
02400 
02401         params -> Index = strtoul(params -> szListString, &endp, 10);
02402 
02403         if ('\0' != *endp)
02404         {
02405             ECDISP_ERROR(GetParent(hOutputWindow),
02406                          "Invalid index value");
02407 
02408             free(params -> szListString);
02409             free(params -> szListString2);
02410             return;
02411         }
02412 
02413         free(params -> szListString);
02414         params -> ListLength = strtoul(params -> szListString2, &endp, 10);
02415 
02416         if ('\0' != *endp)
02417         {
02418             ECDISP_ERROR(GetParent(hOutputWindow),
02419                          "Invalid buffer size");
02420             free(params -> szListString2);
02421             return;
02422         }
02423         free(params -> szListString2);
02424         break;
02425 
02426     case HIDD_GET_MS_GENRE_DESCRIPTOR:
02427     case HIDD_GET_PHYSICAL_DESCRIPTOR:
02428     case HIDD_GET_MANUFACTURER_STRING:
02429     case HIDD_GET_PRODUCT_STRING:
02430     case HIDD_GET_SERIAL_NUMBER_STRING:
02431         iDlgStatus = (DLGBOX_STATUS) DialogBoxParam(NULL,
02432                                                     MAKEINTRESOURCE(IDD_SET_BUFFER_LENGTH),
02433                                                     GetParent(hOutputWindow),
02434                                                     bSetBufLenDlgProc,
02435                                                     (LPARAM) params);
02436 
02437         if (DLGBOX_OK != iDlgStatus)
02438             return;
02439 
02440         params -> ListLength = strtoul(params -> szListString, &endp, 10);
02441 
02442         if ('\0' != *endp)
02443         {
02444             free(params -> szListString);
02445             ECDISP_ERROR(GetParent(hOutputWindow),
02446                          "Invalid buffer length");
02447             return;
02448         }
02449         free(params -> szListString);
02450         break;
02451 
02452     case HIDD_SET_NUM_INPUT_BUFFERS:
02453         iDlgStatus = (DLGBOX_STATUS) DialogBoxParam(NULL,
02454                                                     MAKEINTRESOURCE(IDD_SET_INPUT_BUFFERS),
02455                                                     GetParent(hOutputWindow),
02456                                                     bSetInputBuffDlgProc,
02457                                                     (LPARAM) params);
02458         /*
02459         // If the above call returns 1, then the dialog box routine
02460         //     successfully acquired a string from the user and put the
02461         //     pointer to it in params -> szListString.
02462         //     Now we need to convert the string to a usage list
02463         */
02464 
02465         if (DLGBOX_OK != iDlgStatus)
02466            return;
02467 
02468         params -> Value = strtoul(params -> szListString, &endp, 10);
02469 
02470         if ('\0' != *endp)
02471         {
02472             ECDISP_ERROR(GetParent(hOutputWindow),
02473                          "Invalid value specified");
02474 
02475             free(params -> szListString);
02476             return;
02477         }
02478         free(params -> szListString);
02479         break;
02480 
02481     case HIDP_SET_DATA:
02482         iDlgStatus = (DLGBOX_STATUS) DialogBoxParam(NULL,
02483                                                     MAKEINTRESOURCE(IDD_SET_DATA),
02484                                                     GetParent(hOutputWindow),
02485                                                     bSetDataDlgProc,
02486                                                     (LPARAM) params);
02487 
02488         if (DLGBOX_OK != iDlgStatus)
02489             return;
02490 
02491         break;
02492 
02493     case HIDP_SET_SCALED_USAGE_VALUE:
02494         iDlgStatus = (DLGBOX_STATUS) DialogBoxParam(NULL,
02495                                                     MAKEINTRESOURCE(IDD_SET_SCALED_VALUE),
02496                                                     GetParent(hOutputWindow),
02497                                                     bSetValueDlgProc,
02498                                                     (LPARAM) params);
02499         /*
02500         // If the above call returns DLGBOX_OK, then the dialog box routine
02501         //     successfully acquired a string from the user and put the
02502         //     pointer to it in params -> szListString.
02503         //     Now we need to convert the string to a usage list
02504         */
02505 
02506         if (DLGBOX_OK != iDlgStatus)
02507             return;
02508 
02509         params -> ScaledValue = strtol(params -> szListString, &endp, 10);
02510 
02511         if ('\0' != *endp)
02512         {
02513             ECDISP_ERROR(GetParent(hOutputWindow),
02514                          "Invalid scaled usage value");
02515 
02516             free(params -> szListString);
02517             return;
02518         }
02519 
02520         free(params -> szListString);
02521         break;
02522 
02523     case HIDP_SET_USAGE_VALUE:
02524         iDlgStatus = (DLGBOX_STATUS) DialogBoxParam(NULL,
02525                                                     MAKEINTRESOURCE(IDD_SET_USAGE_VALUE),
02526                                                     GetParent(hOutputWindow),
02527                                                     bSetValueDlgProc,
02528                                                     (LPARAM) params);
02529         /*
02530         // If the above call returns 1, then the dialog box routine
02531         //     successfully acquired a string from the user and put the
02532         //     pointer to it in params -> szListString.
02533         //     Now we need to convert the string to a usage list
02534         */
02535 
02536         if (DLGBOX_OK != iDlgStatus)
02537            return;
02538 
02539         params -> Value = strtoul(params -> szListString, &endp, 10);
02540 
02541         if ('\0' != *endp)
02542         {
02543             ECDISP_ERROR(GetParent(hOutputWindow),
02544                          "Invalid usage value");
02545 
02546             free(params -> szListString);
02547             return;
02548         }
02549         free(params -> szListString);
02550         break;
02551 
02552 
02553     case HIDP_SET_USAGE_VALUE_ARRAY:
02554         iDlgStatus = (DLGBOX_STATUS) DialogBoxParam(NULL,
02555                                                     MAKEINTRESOURCE(IDD_SET_USAGE_VALUE_ARRAY),
02556                                                     GetParent(hOutputWindow),
02557                                                     bSetValueDlgProc,
02558                                                     (LPARAM) params);
02559 
02560         /*
02561         // If the above call returns 1, then the dialog box routine
02562         //     successfully acquired a string from the user and put the
02563         //     pointer to it in params -> szListString.
02564         //     Now we need to convert the string to a usage list
02565         */
02566 
02567         if (DLGBOX_OK != iDlgStatus)
02568             return;
02569 
02570         ExecuteStatus = ConvertStringToUlongList(params -> szListString,
02571                                                  &params -> pValueList,
02572                                                  &params -> ListLength);
02573         free(params -> szListString);
02574 
02575         if (!ExecuteStatus)
02576         {
02577             ECDISP_ERROR(GetParent(hOutputWindow),
02578                          "Error getting list of values");
02579             return;
02580         }
02581         break;
02582 
02583     case HIDP_USAGE_LIST_DIFFERENCE:
02584         iDlgStatus = (DLGBOX_STATUS) DialogBoxParam(NULL,
02585                                                     MAKEINTRESOURCE(IDD_USAGE_LIST_DIFFERENCE),
02586                                                     GetParent(hOutputWindow),
02587                                                     bGetUsageDiffDlgProc,
02588                                                     (LPARAM) params);
02589 
02590         if (DLGBOX_OK != iDlgStatus)
02591         {
02592             return;
02593         }
02594 
02595         ExecuteStatus = Strings_StringToUnsignedList(params -> szListString,
02596                                                      sizeof(USAGE),
02597                                                      16,
02598                                                      (PCHAR *) &params -> UsageList,
02599                                                      &params -> ListLength);
02600 
02601         if (!ExecuteStatus)
02602         {
02603             ECDISP_ERROR(GetParent(hOutputWindow),
02604                          "Error getting list of values");
02605 
02606             free(params -> szListString);
02607             free(params -> szListString2);
02608             return;
02609         }
02610 
02611         ExecuteStatus = Strings_StringToUnsignedList(params -> szListString2,
02612                                                      sizeof(USAGE),
02613                                                      16,
02614                                                      (PCHAR *) &params -> UsageList2,
02615                                                      &params -> ListLength2);
02616 
02617         if (!ExecuteStatus)
02618         {
02619             ECDISP_ERROR(GetParent(hOutputWindow),
02620                          "Error getting list of values");
02621 
02622             free(params -> szListString);
02623             free(params -> szListString2);
02624             free(params -> UsageList);
02625             return;
02626         }
02627 
02628         free(params -> szListString);
02629         free(params -> szListString2);
02630         break;
02631     }
02632 
02633     /*
02634     // Step 2: Extract the common parameters.  It's probably easier
02635     //    to simply fill in the spots in call parameters whether they are used
02636     //    or not instead of filling in only those that are relevant to a given
02637     //    function.  The details of some function relevant parameters are
02638     //    handled after this.
02639     */
02640 
02641     CallParameters.DeviceHandle   = pDevice -> HidDevice;
02642     CallParameters.ReportType     = params -> ReportType;
02643     CallParameters.Ppd            = pDevice -> Ppd;
02644     CallParameters.UsagePage      = params -> UsagePage;
02645     CallParameters.Usage          = params -> Usage;
02646     CallParameters.LinkCollection = params -> LinkCollection;
02647     CallParameters.ReportID       = params -> ReportID;
02648     CallParameters.List           = NULL;
02649     CallParameters.List2          = NULL;
02650     CallParameters.MakeList       = NULL;
02651     CallParameters.BreakList      = NULL;
02652     CallParameters.ListLength     = 0;
02653 
02654     List2Alloc     = FALSE;
02655     MakeListAlloc  = FALSE;
02656     BreakListAlloc = FALSE;
02657 
02658     /*
02659     // Step 3: Now we'll deal with those functions that require a report buffer of some kind
02660     //    which means we'll copy the current buffer of the selected reported
02661     //    type
02662     */
02663 
02664     switch (iFuncCall)
02665     {
02666     case HID_READ_REPORT:
02667 
02668         status = OpenHidDevice(pDevice -> DevicePath,
02669                                TRUE,
02670                                FALSE,
02671                                FALSE,
02672                                FALSE,
02673                                &readDevice);
02674 
02675         if (!status)
02676         {
02677             OUTSTRING(hOutputWindow, "Unable to open device for reading");
02678         }
02679 
02680         CallParameters.DeviceHandle  = readDevice.HidDevice;
02681         CallParameters.ReportType   = HidP_Input;
02682         CallParameters.ReportBuffer = readDevice.InputReportBuffer;
02683         CallParameters.ReportLength = readDevice.Caps.InputReportByteLength;
02684         break;
02685 
02686     case HID_WRITE_REPORT:
02687 
02688         status = OpenHidDevice(pDevice -> DevicePath,
02689                                TRUE,
02690                                FALSE,
02691                                FALSE,
02692                                FALSE,
02693                                &writeDevice);
02694 
02695         if (!status)
02696         {
02697             OUTSTRING(hOutputWindow, "Unable to open device for writing");
02698         }
02699 
02700         BufferDisplay_CopyCurrentBuffer(pOutputDisplay,
02701                                         writeDevice.OutputReportBuffer);
02702 
02703         CallParameters.DeviceHandle  = writeDevice.HidDevice;
02704         CallParameters.ReportType    = HidP_Output;
02705         CallParameters.ReportBuffer  = writeDevice.OutputReportBuffer;
02706         CallParameters.ReportLength  = writeDevice.Caps.OutputReportByteLength;
02707         break;
02708 
02709     case HIDD_GET_INPUT_REPORT:
02710         CallParameters.ReportType   = HidP_Input;
02711         CallParameters.ReportBuffer = pDevice -> InputReportBuffer;
02712         CallParameters.ReportLength = pDevice -> Caps.InputReportByteLength;
02713         break;
02714 
02715     case HIDD_GET_FEATURE:
02716         CallParameters.ReportType   = HidP_Feature;
02717         CallParameters.ReportBuffer = pDevice -> FeatureReportBuffer;
02718         CallParameters.ReportLength = pDevice -> Caps.FeatureReportByteLength;
02719         break;
02720 
02721     case HIDD_GET_INDEXED_STRING:
02722     case HIDP_GET_EXTENDED_ATTRIBUTES:
02723         CallParameters.Index = params -> Index;
02724         CallParameters.ListLength  = params -> ListLength;
02725         break;
02726 
02727     case HIDD_SET_OUTPUT_REPORT:
02728         CallParameters.ReportType = HidP_Output;
02729         BufferDisplay_CopyCurrentBuffer(pOutputDisplay,
02730                                         pDevice -> OutputReportBuffer);
02731         CallParameters.ReportLength = BufferDisplay_GetBufferSize(pOutputDisplay);
02732         CallParameters.ReportBuffer = pDevice -> OutputReportBuffer;
02733         break;
02734 
02735     case HIDD_SET_FEATURE:
02736        CallParameters.ReportType = HidP_Feature;
02737        BufferDisplay_CopyCurrentBuffer(pFeatureDisplay,
02738                                        pDevice -> FeatureReportBuffer);
02739        CallParameters.ReportLength = BufferDisplay_GetBufferSize(pFeatureDisplay);
02740        CallParameters.ReportBuffer = pDevice -> FeatureReportBuffer;
02741        break;
02742 
02743     case HIDP_GET_BUTTONS:
02744     case HIDP_GET_BUTTONS_EX:
02745     case HIDP_GET_DATA:
02746     case HIDP_GET_SCALED_USAGE_VALUE:
02747     case HIDP_GET_USAGES:
02748     case HIDP_GET_USAGES_EX:
02749     case HIDP_GET_USAGE_VALUE:
02750     case HIDP_GET_USAGE_VALUE_ARRAY:
02751     case HIDP_INITIALIZE_REPORT_FOR_ID:
02752     case HIDP_SET_BUTTONS:
02753     case HIDP_SET_DATA:
02754     case HIDP_SET_SCALED_USAGE_VALUE:
02755     case HIDP_SET_USAGES:
02756     case HIDP_SET_USAGE_VALUE:
02757     case HIDP_SET_USAGE_VALUE_ARRAY:
02758     case HIDP_UNSET_BUTTONS:
02759     case HIDP_UNSET_USAGES:
02760 
02761         switch (CallParameters.ReportType)
02762         {
02763         case HidP_Input:
02764             pBufferDisplay = pInputDisplay;
02765             pCopyBuffer    = pDevice -> InputReportBuffer;
02766             break;
02767 
02768         case HidP_Output:
02769             pBufferDisplay = pOutputDisplay;
02770             pCopyBuffer    = pDevice -> OutputReportBuffer;
02771             break;
02772 
02773         case HidP_Feature:
02774             pBufferDisplay = pFeatureDisplay;
02775             pCopyBuffer    = pDevice -> FeatureReportBuffer;
02776             break;
02777 
02778         }
02779         BufferDisplay_CopyCurrentBuffer(pBufferDisplay,
02780                                         pCopyBuffer);
02781 
02782         CallParameters.ReportLength = BufferDisplay_GetBufferSize(pBufferDisplay);
02783         CallParameters.ReportBuffer = pCopyBuffer;
02784         break;
02785 
02786     default:
02787         CallParameters.ReportLength = 0;
02788         CallParameters.ReportBuffer = NULL;
02789     }
02790 
02791     /*
02792     // Now, we need to deal with those functions which have a List that is
02793     //   used for either retrieving or gathering data.  There are two different
02794     //   cases.  The first involves the user inputting a buffer and the system
02795     //   performing some action on the buffer, such as SetButtons.  We'll also
02796     //   the other functions that require one of the union fields to be set.
02797     //
02798     */
02799 
02800     /*
02801     // The second case is where data is retrieved for the device.  In this case,
02802     //     all we do is specify either the number of elements need for the buffer,
02803     //     the execute routine will worry about allocating the correct amount of
02804     //     space for those elements.  Remember, however, that if the Execute routine
02805     //     allocates space, we need to free it up.
02806     */
02807 
02808     /*
02809     // Then there's the third case UsageListDifference which truly changes
02810     //   everything.  We've got to determine the size of the resulting lists
02811     //   is the MaxSize of the other two lists.  Plus, we need to insure that
02812     //   our buffers are 00 terminated if they are less than the max size, ie
02813     //   there not the same size as the larger buffer.  This may require
02814     //   reallocation of the block.
02815     */
02816 
02817     switch (iFuncCall)
02818     {
02819     /*
02820     // First Case functions
02821     */
02822 
02823     case HIDP_SET_DATA:
02824         CallParameters.List       = (PVOID) params -> pDataList;
02825         CallParameters.ListLength = params -> ListLength;
02826         break;
02827 
02828     case HIDP_SET_BUTTONS:
02829     case HIDP_UNSET_BUTTONS:
02830     case HIDP_SET_USAGES:
02831     case HIDP_UNSET_USAGES:
02832         CallParameters.List       = (PVOID) params -> UsageList;
02833         CallParameters.ListLength = params -> ListLength;
02834         break;
02835 
02836     case HIDP_SET_USAGE_VALUE_ARRAY:
02837         CallParameters.List       = (PVOID) params -> pValueList;
02838         CallParameters.ListLength = params -> ListLength;
02839         break;
02840 
02841     /*
02842     // Second Case functions
02843     */
02844 
02845     case HIDP_GET_BUTTON_CAPS:
02846     case HIDP_GET_SPECIFIC_BUTTON_CAPS:
02847         SELECT_ON_REPORT_TYPE(CallParameters.ReportType,
02848                               pDevice -> Caps.NumberInputButtonCaps,
02849                               pDevice -> Caps.NumberOutputButtonCaps,
02850                               pDevice -> Caps.NumberFeatureButtonCaps,
02851                               CallParameters.ListLength);
02852         break;
02853 
02854     case HIDP_GET_LINK_COLL_NODES:
02855         CallParameters.ListLength = pDevice -> Caps.NumberLinkCollectionNodes;
02856         break;
02857 
02858     case HIDD_GET_MS_GENRE_DESCRIPTOR:
02859     case HIDD_GET_PHYSICAL_DESCRIPTOR:
02860     case HIDD_GET_MANUFACTURER_STRING:
02861     case HIDD_GET_PRODUCT_STRING:
02862     case HIDD_GET_SERIAL_NUMBER_STRING:
02863         CallParameters.ListLength = params -> ListLength;
02864         break;
02865 
02866     case HIDP_GET_VALUE_CAPS:
02867     case HIDP_GET_SPECIFIC_VALUE_CAPS:
02868         SELECT_ON_REPORT_TYPE(CallParameters.ReportType,
02869                               pDevice -> Caps.NumberInputValueCaps,
02870                               pDevice -> Caps.NumberOutputValueCaps,
02871                               pDevice -> Caps.NumberFeatureValueCaps,
02872                               CallParameters.ListLength);
02873 
02874     case HIDD_GET_FREE_PREPARSED_DATA:
02875         CallParameters.ppPd = &CallParameters.Ppd;
02876         break;
02877 
02878     case HIDP_SET_SCALED_USAGE_VALUE:
02879         CallParameters.ScaledValue = params -> ScaledValue;
02880         break;
02881 
02882     case HIDP_SET_USAGE_VALUE:
02883     case HIDD_SET_NUM_INPUT_BUFFERS:
02884         CallParameters.Value = params -> Value;
02885         break;
02886 
02887     /*
02888     // That third case
02889     */
02890 
02891     case HIDP_USAGE_LIST_DIFFERENCE:
02892         CallParameters.ListLength = max(params -> ListLength,
02893                                         params -> ListLength2);
02894 
02895         CallParameters.List  = params -> UsageList;
02896         CallParameters.List2 = params -> UsageList2;
02897 
02898         if (CallParameters.ListLength > params -> ListLength)
02899         {
02900             CallParameters.List = (PUSAGE) realloc(params -> UsageList,
02901                                                    (params -> ListLength+1) * sizeof(USAGE));
02902 
02903             if (NULL == CallParameters.List)
02904             {
02905                 ECDISP_ERROR(GetParent(hOutputWindow),
02906                              "Error allocating memory");
02907 
02908                 free(params -> UsageList);
02909                 free(params -> UsageList2);
02910 
02911                 return;
02912             }
02913 
02914             *(((PUSAGE) CallParameters.List) + CallParameters.ListLength - 1) = 0;
02915         }
02916         else if (CallParameters.ListLength > params -> ListLength2)
02917         {
02918             CallParameters.List2 = (PUSAGE) realloc(params -> UsageList2,
02919                                                    (params -> ListLength+1) * sizeof(USAGE));
02920 
02921             if (NULL == CallParameters.List2)
02922             {
02923                 ECDISP_ERROR(GetParent(hOutputWindow),
02924                              "Error allocating memory");
02925 
02926                 free(params -> UsageList);
02927                 free(params -> UsageList2);
02928                 return;
02929             }
02930 
02931             *(((PUSAGE) CallParameters.List2) + CallParameters.ListLength - 1) = 0;
02932         }
02933         List2Alloc = TRUE;
02934         MakeListAlloc = TRUE;
02935         BreakListAlloc = TRUE;
02936         break;
02937     }
02938 
02939     /*
02940     // Parameters are now set up and ready to go, let's execute
02941     */
02942 
02943     if (HIDD_GET_FREE_PREPARSED_DATA == iFuncCall)
02944     {
02945         ExecuteStatus = ECDisp_Execute(HIDD_GET_PREPARSED_DATA,
02946                                        &CallParameters,
02947                                        &CallStatus);
02948 
02949         if (!ExecuteStatus)
02950         {
02951             OUTSTRING(hOutputWindow, "Unknown error: Couldn't execute function");
02952             return;
02953         }
02954 
02955         DISPLAY_HIDD_STATUS(hOutputWindow,
02956                             "HidD_GetPreparsedData",
02957                             CallStatus,
02958                             stringReturn);
02959 
02960         if (!CallStatus.IsHidError)
02961         {
02962             ExecuteStatus = ECDisp_Execute(HIDD_FREE_PREPARSED_DATA,
02963                                            &CallParameters,
02964                                            &CallStatus);
02965 
02966             OUTSTRING(hOutputWindow, "=======================");
02967 
02968             if (!ExecuteStatus)
02969             {
02970                 OUTSTRING(hOutputWindow, "Unknown error: Couldn't execute function");
02971                 return;
02972             }
02973 
02974             DISPLAY_HIDD_STATUS(hOutputWindow,
02975                                 "HidD_FreePreparsedData",
02976                                 CallStatus,
02977                                 stringReturn);
02978         }
02979     }
02980     else
02981     {
02982         if ((HID_READ_REPORT == iFuncCall || HID_WRITE_REPORT == iFuncCall) &&
02983             (!status))
02984         {
02985             //
02986             // Indicate there was an error so we don't display anything further
02987             //
02988 
02989             CallStatus.IsHidError = TRUE;
02990         }
02991         else
02992         {
02993             ExecuteStatus = ECDisp_Execute(iFuncCall,
02994                                            &CallParameters,
02995                                            &CallStatus);
02996 
02997             if (!ExecuteStatus)
02998             {
02999                 OUTSTRING(hOutputWindow, "Unknown error: Couldn't execute function");
03000                 return;
03001             }
03002 
03003             if (IS_HIDD_FUNCTION(iFuncCall) || IS_HID_FUNCTION(iFuncCall))
03004             {
03005                 DISPLAY_HIDD_STATUS(hOutputWindow,
03006                                     GET_FUNCTION_NAME(iFuncCall),
03007                                     CallStatus,
03008                                     stringReturn);
03009 
03010             }
03011             else
03012             {
03013                 DISPLAY_HIDP_STATUS(hOutputWindow,
03014                                     GET_FUNCTION_NAME(iFuncCall),
03015                                     CallStatus,
03016                                     stringReturn);
03017             }
03018         }
03019     }
03020 
03021     /*
03022     // Display the other results only if there wasn't a HID error
03023     */
03024 
03025     if (!CallStatus.IsHidError || (HIDP_STATUS_NULL == CallStatus.HidErrorCode))
03026     {
03027         OUTSTRING(hOutputWindow, "=======================");
03028 
03029         /*
03030         // Now that general status information has been displayed, we need to
03031         //   display the info for the parts that are dependent on the function being
03032         //   called
03033         */
03034 
03035         ECDisp_DisplayOutput(hOutputWindow,
03036                             iFuncCall,
03037                             &CallParameters);
03038     }
03039 
03040     if (CallParameters.List != NULL)
03041     {
03042         free(CallParameters.List);
03043     }
03044 
03045     if (List2Alloc && CallParameters.List2 != NULL)
03046     {
03047         free(CallParameters.List2);
03048     }
03049 
03050     if (MakeListAlloc && CallParameters.MakeList != NULL)
03051     {
03052         free(CallParameters.MakeList);
03053     }
03054 
03055     if (BreakListAlloc && CallParameters.BreakList != NULL)
03056     {
03057         free(CallParameters.BreakList);
03058     }
03059 
03060     return;
03061 }
03062 
03063 VOID
03064 BuildReportIDList(
03065     IN  PHIDP_BUTTON_CAPS  phidButtonCaps,
03066     IN  USHORT             nButtonCaps,
03067     IN  PHIDP_VALUE_CAPS   phidValueCaps,
03068     IN  USHORT             nValueCaps,
03069     OUT PUCHAR            *ppReportIDList,
03070     OUT INT               *nReportIDs
03071 )
03072 /*++
03073 RoutineDescription:
03074     This routine builds a list of report IDs that are listed in the passed in set
03075     of ButtonCaps and ValueCaps structure.  It allocates a buffer to store all
03076     the ReportIDs, if it can.  Otherwise the buffer is returned as NULL.
03077 
03078     Currently, this routine has no purpose in the HClient program. It was written
03079     for some purpose which never materialized but was left in because it might be
03080     useful in the future.
03081 --*/
03082 {
03083     INT               nAllocatedIDs;
03084     INT               nFoundIDs;
03085     INT               nWalkCount;
03086     USHORT            usIndex;
03087     BOOL              fIDFound;
03088     UCHAR             *pucBuffer;
03089     UCHAR             *pucNewBuffer;
03090     UCHAR             *pucWalk;
03091     UCHAR             ucReportID;
03092     PHIDP_BUTTON_CAPS pButtonWalk;
03093     PHIDP_VALUE_CAPS  pValueWalk;
03094 
03095     /*
03096     // Initialize the output parameters in case there is some sort of failure
03097     */
03098 
03099     *nReportIDs = 0;
03100     *ppReportIDList = NULL;
03101 
03102     if (0 == nButtonCaps && 0 == nValueCaps)
03103         return;
03104 
03105     /*
03106     // Initialize the beginning array size to 2 report IDs and alloc space
03107     // for those IDs.  If we need to add more report IDs we allocate more
03108     // space
03109     */
03110 
03111     nAllocatedIDs = 2;
03112     nFoundIDs = 0;
03113     pButtonWalk = phidButtonCaps;
03114     pValueWalk = phidValueCaps;
03115 
03116     pucBuffer = (UCHAR *) malloc(sizeof(UCHAR) * nAllocatedIDs);
03117     if (NULL == pucBuffer)
03118         return;
03119 
03120     /*
03121     // Beginning with the button caps and then going to the value caps do the
03122     // following
03123     //
03124     // 1) Take the report ID and search the array of report IDs looking for
03125     //       an existing report ID and add to the array if not there.
03126     //
03127     // 2) Add the report ID to the array in sorted order that way we sort the
03128     //      array at any time.
03129     //
03130     // 3) Must also realloc the array if we run out of array space
03131     */
03132 
03133     for (usIndex = 0; usIndex < nButtonCaps; usIndex++, pButtonWalk++)
03134     {
03135         ucReportID = pButtonWalk -> ReportID;
03136 
03137         pucWalk = pucBuffer;
03138         nWalkCount = 0;
03139         fIDFound = FALSE;
03140 
03141         while (!fIDFound && nWalkCount < nFoundIDs)
03142         {
03143             if (*pucWalk == ucReportID)
03144             {
03145                 fIDFound = TRUE;
03146             }
03147             else if (ucReportID > *pucWalk)
03148             {
03149                 pucWalk++;
03150                 nWalkCount++;
03151             }
03152         }
03153 
03154         if (!fIDFound)
03155         {
03156             if (nFoundIDs == nAllocatedIDs)
03157             {
03158                 nAllocatedIDs *= 2;
03159 
03160                 pucNewBuffer = (UCHAR *) realloc(pucBuffer, sizeof(UCHAR) * nAllocatedIDs);
03161 
03162                 if (NULL == pucNewBuffer)
03163                 {
03164                     free(pucBuffer);
03165                     pucBuffer = NULL;
03166                     return;
03167                 }
03168                 else
03169                 {
03170                     pucBuffer = pucNewBuffer;
03171                 }
03172 
03173                 pucWalk = pucBuffer + nWalkCount;
03174             }
03175 
03176             /*
03177             // At this point, pucWalk points to the smallest ReportID in the
03178             //   buffer that is greater than the ReportID we want to insert.
03179             //   We need to bump all reportIDs beginning at pucWalk up one
03180             //   spot and insert the new ReportID at pucWalk
03181             */
03182 
03183             memmove (pucWalk+1, pucWalk, (nFoundIDs - nWalkCount) * sizeof(UCHAR));
03184             *pucWalk = ucReportID;
03185             nFoundIDs++;
03186         }
03187     }
03188 
03189     *ppReportIDList = pucBuffer;
03190     *nReportIDs = nFoundIDs;
03191 
03192     return;
03193 }
03194 
03195 LRESULT CALLBACK
03196 bSetUsagesDlgProc(
03197     HWND hDlg,
03198     UINT message,
03199     WPARAM wParam,
03200     LPARAM lParam
03201 )
03202 {
03203     static PECDISPLAY_PARAMS  pParams;
03204            INT                StringLength;
03205            DLGBOX_STATUS      RetValue;
03206 
03207     switch (message)
03208     {
03209     case WM_INITDIALOG:
03210 
03211         pParams = (PECDISPLAY_PARAMS) lParam;
03212 
03213         SetDlgItemIntHex(hDlg,
03214                          IDC_USAGE_PAGE,
03215                          pParams -> UsagePage,
03216                          2);
03217         break;
03218 
03219     case WM_COMMAND:
03220         switch (LOWORD(wParam))
03221         {
03222         case IDOK:
03223             StringLength = GetWindowTextLength(GetDlgItem(hDlg, IDC_USAGE_LIST));
03224 
03225             if (StringLength > 0)
03226             {
03227                 pParams -> szListString = (PCHAR) malloc(StringLength+1);
03228                 if (NULL == pParams -> szListString)
03229                 {
03230                     ECDISP_ERROR(hDlg, "Error allocating memory");
03231                     RetValue = DLGBOX_ERROR;
03232                 }
03233                 else
03234                 {
03235                     GetWindowText(GetDlgItem(hDlg, IDC_USAGE_LIST),
03236                                   pParams -> szListString,
03237                                   StringLength+1);
03238 
03239                     RetValue = DLGBOX_OK;
03240                 }
03241             }
03242             else
03243             {
03244                 pParams -> szListString = NULL;
03245                 RetValue = DLGBOX_CANCEL;
03246             }
03247 
03248             EndDialog(hDlg, RetValue);
03249             break;
03250 
03251         case IDCANCEL:
03252             EndDialog(hDlg, DLGBOX_CANCEL);
03253             break;
03254         }
03255         break;
03256     }
03257     return (FALSE);
03258 }
03259 
03260 LRESULT CALLBACK
03261 bSetValueDlgProc(
03262     HWND hDlg,
03263     UINT message,
03264     WPARAM wParam,
03265     LPARAM lParam
03266 )
03267 {
03268     static PECDISPLAY_PARAMS  pParams;
03269            INT                StringLength;
03270            DLGBOX_STATUS      RetValue;
03271 
03272     switch (message)
03273     {
03274     case WM_INITDIALOG:
03275 
03276         pParams = (PECDISPLAY_PARAMS) lParam;
03277 
03278         SetDlgItemIntHex(hDlg,
03279                          IDC_USAGE_PAGE,
03280                          pParams -> UsagePage,
03281                          sizeof(USAGE));
03282 
03283         SetDlgItemIntHex(hDlg,
03284                          IDC_USAGE,
03285                          pParams -> Usage,
03286                          sizeof(USAGE));
03287         break;
03288 
03289     case WM_COMMAND:
03290         switch (LOWORD(wParam))
03291         {
03292         case IDOK:
03293             StringLength = GetWindowTextLength(GetDlgItem(hDlg, IDC_VALUE));
03294 
03295             if (StringLength > 0)
03296             {
03297                 pParams -> szListString = (PCHAR) malloc(StringLength+1);
03298                 if (NULL == pParams -> szListString)
03299                 {
03300                     ECDISP_ERROR(hDlg, "Error allocating memory");
03301 
03302                     RetValue = DLGBOX_ERROR;
03303                 }
03304                 else
03305                 {
03306                     GetWindowText(GetDlgItem(hDlg, IDC_VALUE),
03307                                   pParams -> szListString,
03308                                   StringLength+1);
03309 
03310                     RetValue = DLGBOX_OK;
03311                 }
03312             }
03313             else
03314             {
03315                 pParams -> szListString = NULL;
03316                 RetValue = DLGBOX_CANCEL;
03317             }
03318 
03319             EndDialog(hDlg, RetValue);
03320             break;
03321 
03322         case IDCANCEL:
03323             EndDialog(hDlg, DLGBOX_CANCEL);
03324             break;
03325         }
03326         break;
03327     }
03328     return (FALSE);
03329 }
03330 
03331 LRESULT CALLBACK
03332 bSetInputBuffDlgProc(
03333     HWND hDlg,
03334     UINT message,
03335     WPARAM wParam,
03336     LPARAM lParam
03337 )
03338 {
03339     static PECDISPLAY_PARAMS  pParams;
03340            INT                StringLength;
03341            DLGBOX_STATUS      RetValue;
03342 
03343     switch (message)
03344     {
03345     case WM_INITDIALOG:
03346         pParams = (PECDISPLAY_PARAMS) lParam;
03347         break;
03348 
03349     case WM_COMMAND:
03350         switch (LOWORD(wParam))
03351         {
03352         case IDOK:
03353             StringLength = GetWindowTextLength(GetDlgItem(hDlg, IDC_INPUT_BUFFERS));
03354 
03355             if (StringLength > 0)
03356             {
03357                 pParams -> szListString = (PCHAR) malloc(StringLength+1);
03358 
03359                 if (NULL == pParams -> szListString)
03360                 {
03361                     ECDISP_ERROR(hDlg, "Error allocating memory");
03362 
03363                     RetValue = DLGBOX_ERROR;
03364                 }
03365                 else
03366                 {
03367                     GetWindowText(GetDlgItem(hDlg, IDC_INPUT_BUFFERS),
03368                                   pParams -> szListString,
03369                                   StringLength+1);
03370 
03371                     RetValue = DLGBOX_OK;
03372                 }
03373             }
03374             else
03375             {
03376                 pParams -> szListString = NULL;
03377                 RetValue = DLGBOX_CANCEL;
03378             }
03379 
03380             EndDialog(hDlg, RetValue);
03381             break;
03382 
03383         case IDCANCEL:
03384             EndDialog(hDlg, DLGBOX_CANCEL);
03385             break;
03386         }
03387         break;
03388     }
03389     return (FALSE);
03390 }
03391 
03392 
03393 LRESULT CALLBACK
03394 bSetDataDlgProc(
03395     HWND hDlg,
03396     UINT message,
03397     WPARAM wParam,
03398     LPARAM lParam
03399 )
03400 {
03401     static CHAR               DataString[TEMP_BUFFER_SIZE];
03402     static PECDISPLAY_PARAMS  pParams;
03403            UINT               IndexValue;
03404            ULONG              Value;
03405            BOOL               lpTranslated;
03406            DLGBOX_STATUS      RetValue;
03407            PCHAR              endp;
03408            INT                ListBoxStatus;
03409            PHIDP_DATA         DataList;
03410            PHIDP_DATA         CurrData;
03411            ULONG              DataListLength;
03412            ULONG              Index;
03413            HRESULT              stringReturn;
03414            INT                  iReturn;
03415 
03416     switch (message)
03417     {
03418     case WM_INITDIALOG:
03419 
03420         pParams = (PECDISPLAY_PARAMS) lParam;
03421         SendMessage(GetDlgItem(hDlg, IDC_VALUE),
03422                     EM_SETLIMITTEXT,
03423                     (WPARAM) 1024,
03424                     0);
03425         break;
03426 
03427     case WM_COMMAND:
03428         switch (LOWORD(wParam))
03429         {
03430         case IDC_ADD_DATA:
03431             IndexValue = GetDlgItemInt(hDlg,
03432                                        IDC_INDEX,
03433                                        &lpTranslated,
03434                                        FALSE);
03435             if (!lpTranslated)
03436             {
03437                 ECDISP_ERROR(hDlg,
03438                            "Invalid index value: must be unsigned integer");
03439                 break;
03440             }
03441 
03442             if (0 == GetWindowText(GetDlgItem(hDlg, IDC_VALUE),
03443                                    DataString, 1023))
03444             {
03445                 ECDISP_ERROR(hDlg, "Invalid data value");
03446                 break;
03447             }
03448 
03449             CharUpperBuff(DataString, lstrlen(DataString));
03450 
03451             if (0 == lstrcmp(DataString, "TRUE"))
03452             {
03453                 Value = 1;
03454             }
03455             else if (0 == lstrcmp(DataString, "FALSE"))
03456             {
03457                 Value = 0;
03458             }
03459             else
03460             {
03461                 Value = strtoul(DataString, &endp, 10);
03462                 if (*endp != '\0')
03463                 {
03464                     ECDISP_ERROR(hDlg, "Invalid data value");
03465                     break;
03466                 }
03467             }
03468             stringReturn = StringCbPrintf(DataString,
03469                            TEMP_BUFFER_SIZE,
03470                            SETDATA_LISTBOX_FORMAT,
03471                            IndexValue,
03472                            Value);
03473 
03474             ListBoxStatus = (INT) SendMessage(GetDlgItem(hDlg, IDC_DATA_LIST),
03475                                               LB_ADDSTRING,
03476                                               0,
03477                                               (LPARAM) DataString);
03478 
03479             if (CB_ERR == ListBoxStatus || CB_ERRSPACE == ListBoxStatus)
03480             {
03481                 ECDISP_ERROR(hDlg, "Error adding string to data list");
03482                 break;
03483             }
03484             break;
03485 
03486         case IDC_REMOVE_DATA:
03487             SendMessage(GetDlgItem(hDlg, IDC_DATA_LIST),
03488                         LB_DELETESTRING,
03489                         SendMessage(GetDlgItem(hDlg, IDC_DATA_LIST),
03490                                     LB_GETCURSEL,
03491                                     0, 0),
03492                         0);
03493             break;
03494 
03495         case IDOK:
03496             DataListLength = (ULONG) SendMessage(GetDlgItem(hDlg, IDC_DATA_LIST),
03497                                                  LB_GETCOUNT,
03498                                                  0, 0);
03499 
03500             if (0 != DataListLength)
03501             {
03502                 DataList = malloc(DataListLength * sizeof(HIDP_DATA));
03503                 if (NULL == DataList)
03504                 {
03505                     ECDISP_ERROR(hDlg, "Error allocating memory");
03506 
03507                     DataListLength = 0;
03508                     RetValue = DLGBOX_CANCEL;
03509                     break;
03510                 }
03511 
03512                 for (Index = 0, CurrData = DataList; Index < DataListLength; Index++, CurrData++)
03513                 {
03514                     SendMessage(GetDlgItem(hDlg, IDC_DATA_LIST),
03515                                 LB_GETTEXT,
03516                                 Index,
03517                                 (LPARAM) DataString);
03518 
03519                     iReturn = sscanf(DataString,
03520                            SETDATA_LISTBOX_FORMAT,
03521                            &IndexValue,
03522                            &Value);
03523 
03524                     CurrData -> DataIndex = (USHORT) IndexValue;
03525                     CurrData -> RawValue = Value;
03526                 }
03527                 RetValue = DLGBOX_OK;
03528             }
03529             else
03530             {
03531                 DataList = NULL;
03532                 RetValue = DLGBOX_CANCEL;
03533             }
03534 
03535             pParams -> pDataList = DataList;
03536             pParams -> ListLength = DataListLength;
03537             EndDialog(hDlg, RetValue);
03538             break;
03539 
03540         case IDCANCEL:
03541             EndDialog(hDlg, DLGBOX_CANCEL);
03542             break;
03543         }
03544         break;
03545     }
03546     return (FALSE);
03547 }
03548 
03549 LRESULT CALLBACK
03550 bSetBufLenDlgProc(
03551     HWND hDlg,
03552     UINT message,
03553     WPARAM wParam,
03554     LPARAM lParam
03555 )
03556 {
03557     static PECDISPLAY_PARAMS  pParams;
03558            INT                StringLength;
03559            DLGBOX_STATUS      RetValue;
03560 
03561     switch (message)
03562     {
03563    case WM_INITDIALOG:
03564 
03565         pParams = (PECDISPLAY_PARAMS) lParam;
03566         break;
03567 
03568     case WM_COMMAND:
03569         switch (LOWORD(wParam))
03570         {
03571         case IDOK:
03572             StringLength = GetWindowTextLength(GetDlgItem(hDlg, IDC_BUFFER_LENGTH));
03573 
03574             if (StringLength > 0)
03575             {
03576                 pParams -> szListString = (PCHAR) malloc(StringLength+1);
03577                 if (NULL == pParams -> szListString)
03578                 {
03579                     ECDISP_ERROR(hDlg, "Error allocating memory");
03580 
03581                     RetValue = DLGBOX_ERROR;
03582 
03583                 }
03584                 else
03585                 {
03586                     GetWindowText(GetDlgItem(hDlg, IDC_BUFFER_LENGTH),
03587                                   pParams -> szListString,
03588                                   StringLength+1);
03589 
03590                     RetValue = DLGBOX_OK;
03591                 }
03592             }
03593             else
03594             {
03595                 pParams -> szListString = NULL;
03596                 RetValue = DLGBOX_CANCEL;
03597             }
03598 
03599             EndDialog(hDlg, RetValue);
03600             break;
03601 
03602         case IDCANCEL:
03603             EndDialog(hDlg, DLGBOX_CANCEL);
03604             break;
03605         }
03606         break;
03607     }
03608     return (FALSE);
03609 }
03610 
03611 LRESULT CALLBACK
03612 bSetInputBuffersDlgProc(
03613     HWND hDlg,
03614     UINT message,
03615     WPARAM wParam,
03616     LPARAM lParam
03617 )
03618 {
03619     static PECDISPLAY_PARAMS  pParams;
03620            INT                StringLength;
03621            DLGBOX_STATUS      RetValue;
03622 
03623     switch (message)
03624     {
03625     case WM_INITDIALOG:
03626 
03627         pParams = (PECDISPLAY_PARAMS) lParam;
03628         break;
03629 
03630     case WM_COMMAND:
03631         switch (LOWORD(wParam))
03632         {
03633         case IDOK:
03634             StringLength = GetWindowTextLength(GetDlgItem(hDlg, IDC_INPUT_BUFFERS));
03635 
03636             if (StringLength > 0)
03637             {
03638                 pParams -> szListString = (PCHAR) malloc(StringLength+1);
03639 
03640                 if (NULL == pParams -> szListString)
03641                 {
03642                     ECDISP_ERROR(hDlg, "Error allocating memory");
03643                     RetValue = DLGBOX_ERROR;
03644                 }
03645                 else
03646                 {
03647                     GetWindowText(GetDlgItem(hDlg, IDC_INPUT_BUFFERS),
03648                                   pParams -> szListString,
03649                                   StringLength+1
03650                                  );
03651                     RetValue = DLGBOX_OK;
03652                 }
03653             }
03654             else
03655             {
03656                 pParams -> szListString = NULL;
03657                 RetValue = DLGBOX_CANCEL;
03658             }
03659 
03660             EndDialog(hDlg, RetValue);
03661             break;
03662 
03663         case IDCANCEL:
03664             EndDialog(hDlg, DLGBOX_CANCEL);
03665             break;
03666         }
03667         break;
03668     }
03669     return (FALSE);
03670 }
03671 
03672 LRESULT CALLBACK
03673 bGetIndexedDlgProc(
03674     HWND hDlg,
03675     UINT message,
03676     WPARAM wParam,
03677     LPARAM lParam
03678 )
03679 {
03680     static PECDISPLAY_PARAMS  pParams;
03681            INT                StringLength;
03682            INT                StringLength2;
03683            DLGBOX_STATUS      RetValue;
03684 
03685     switch (message)
03686     {
03687     case WM_INITDIALOG:
03688 
03689         pParams = (PECDISPLAY_PARAMS) lParam;
03690         break;
03691 
03692     case WM_COMMAND:
03693         switch (LOWORD(wParam))
03694         {
03695         case IDOK:
03696             StringLength  = GetWindowTextLength(GetDlgItem(hDlg, IDC_INDEX));
03697             StringLength2 = GetWindowTextLength(GetDlgItem(hDlg, IDC_BUFFER_LENGTH));
03698 
03699             if (StringLength <= 0 || StringLength2 <= 0)
03700             {
03701                 pParams -> szListString = NULL;
03702                 pParams -> szListString2 = NULL;
03703                 RetValue = DLGBOX_CANCEL;
03704                 EndDialog(hDlg, DLGBOX_CANCEL);
03705             }
03706 
03707             pParams -> szListString = (PCHAR) malloc(StringLength+1);
03708             pParams -> szListString2 = (PCHAR) malloc(StringLength2+1);
03709 
03710             if (NULL == pParams -> szListString || NULL == pParams -> szListString2)
03711             {
03712                    ECDISP_ERROR(hDlg, "Error allocating memory");
03713 
03714                    if (NULL != pParams -> szListString)
03715                        free(pParams -> szListString);
03716 
03717                    if (NULL != pParams -> szListString2)
03718                        free(pParams -> szListString2);
03719 
03720                    RetValue = DLGBOX_ERROR;
03721             }
03722             else
03723             {
03724                 GetWindowText(GetDlgItem(hDlg, IDC_INDEX),
03725                               pParams -> szListString,
03726                               StringLength+1);
03727 
03728                 GetWindowText(GetDlgItem(hDlg, IDC_BUFFER_LENGTH),
03729                               pParams -> szListString2,
03730                               StringLength2+1);
03731 
03732                 RetValue = DLGBOX_OK;
03733             }
03734             EndDialog(hDlg, RetValue);
03735             break;
03736 
03737         case IDCANCEL:
03738             EndDialog(hDlg, DLGBOX_CANCEL);
03739             break;
03740         }
03741         break;
03742     }
03743     return (FALSE);
03744 }
03745 
03746 LRESULT CALLBACK
03747 bGetUsageDiffDlgProc(
03748     HWND hDlg,
03749     UINT message,
03750     WPARAM wParam,
03751     LPARAM lParam
03752 )
03753 {
03754     static PECDISPLAY_PARAMS  pParams;
03755            INT                StringLength;
03756            INT                StringLength2;
03757            DLGBOX_STATUS      RetValue;
03758 
03759     switch (message)
03760     {
03761     case WM_INITDIALOG:
03762 
03763         pParams = (PECDISPLAY_PARAMS) lParam;
03764         break;
03765 
03766     case WM_COMMAND:
03767         switch (LOWORD(wParam))
03768         {
03769         case IDOK:
03770             StringLength  = GetWindowTextLength(GetDlgItem(hDlg, IDC_USAGE_LIST1));
03771             StringLength2 = GetWindowTextLength(GetDlgItem(hDlg, IDC_USAGE_LIST2));
03772 
03773             if (StringLength <= 0)
03774             {
03775                 pParams -> szListString = NULL;
03776             }
03777             else
03778             {
03779                 pParams -> szListString = (PCHAR) malloc(StringLength+1);
03780                 if (NULL == pParams -> szListString)
03781                 {
03782                     ECDISP_ERROR(hDlg,
03783                                  "Error allocating memory");
03784 
03785                     EndDialog(hDlg, DLGBOX_ERROR);
03786                     break;
03787                 }
03788             }
03789 
03790             if (StringLength2 <= 0)
03791             {
03792                 pParams -> szListString2 = NULL;
03793             }
03794             else
03795             {
03796                 pParams -> szListString2 = (PCHAR) malloc(StringLength2+1);
03797                 if (NULL == pParams -> szListString2)
03798                 {
03799                     ECDISP_ERROR(hDlg,
03800                                  "Error allocating memory");
03801 
03802                     if (NULL != pParams -> szListString)
03803                     {
03804                         free(pParams -> szListString);
03805                     }
03806                     EndDialog(hDlg, DLGBOX_ERROR);
03807                     break;
03808                 }
03809             }
03810 
03811             if ( !(pParams->szListString) )
03812             {
03813                 GetWindowText(GetDlgItem(hDlg, IDC_USAGE_LIST1),
03814                               pParams -> szListString,
03815                               StringLength+1);
03816             }
03817 
03818             if (pParams->szListString2 != NULL)
03819             {
03820                 GetWindowText(GetDlgItem(hDlg, IDC_USAGE_LIST2),
03821                               pParams -> szListString2,
03822                               StringLength2+1);
03823             }
03824 
03825             RetValue = DLGBOX_OK;
03826 
03827             EndDialog(hDlg, RetValue);
03828             break;
03829 
03830         case IDCANCEL:
03831             EndDialog(hDlg, DLGBOX_CANCEL);
03832             break;
03833         }
03834         break;
03835     }
03836     return (FALSE);
03837 }
03838 
03839 BOOL
03840 ConvertStringToUsageList(
03841     IN OUT PCHAR   InString,
03842     OUT    PUSAGE  *UsageList,
03843     OUT    PULONG  nUsages
03844 )
03845 /*++
03846 RoutineDescription:
03847     This routine converts a string of values into a string of usages which are
03848     currently 2 byte values.  We use base 16 to specify that the usages should
03849     be expressed as hexadecimal numbers.
03850 --*/
03851 {
03852     return (Strings_StringToUnsignedList(InString,
03853                                          sizeof(ULONG),
03854                                          16,
03855                                          (PCHAR *) UsageList,
03856                                          nUsages));
03857 }
03858 
03859 BOOL
03860 ConvertStringToUlongList(
03861     IN OUT PCHAR   InString,
03862     OUT    PULONG  *UlongList,
03863     OUT    PULONG  nUlongs
03864 )
03865 /*++
03866 RoutineDescription
03867     This routine converts a string of values into a string of ulongs which are
03868     currently 2 byte values.  It requires that the numbers in the string be in
03869     base 10
03870 --*/
03871 {
03872     return (Strings_StringToUnsignedList(InString,
03873                                          sizeof(ULONG),
03874                                          10,
03875                                          (PCHAR *) UlongList,
03876                                          nUlongs));
03877 }
03878 
03879 BOOL
03880 SetDlgItemIntHex(
03881    HWND hDlg,
03882    INT nIDDlgItem,
03883    UINT uValue,
03884    INT nBytes
03885 )
03886 {
03887     char szTempBuff[] = "0x00000000";
03888     int  iEndIndex, iWidth;
03889     HRESULT stringReturn;
03890 
03891     assert (1 == nBytes || 2 == nBytes || 4 == nBytes);
03892 
03893     /*
03894     // Determine the width necessary to store the value
03895     */
03896 
03897     stringReturn = StringCbPrintf(szTempBuff,
03898                    (sizeof(szTempBuff)),
03899                    "0x%*X", (nBytes*2), uValue);
03900 
03901     SetDlgItemText(hDlg, nIDDlgItem, szTempBuff);
03902 
03903     return (TRUE);
03904 }
03905 
03906 VOID
03907 ECDisp_MakeGUIDString(
03908     IN  GUID guid,
03909     OUT CHAR szString[],
03910     IN  UINT uiBuffSize
03911 )
03912 {
03913     CHAR szCharString[18];
03914     INT i;
03915     HRESULT stringReturn;
03916 
03917     for (i = 0; i < 8; i++)
03918     {
03919         stringReturn = StringCbPrintf(&(szCharString[i]), sizeof(szCharString),
03920                        "%x", guid.Data4[i]);
03921     }
03922 
03923     stringReturn = StringCbPrintf(szString, uiBuffSize,
03924                    "%x-%x%x-%s", guid.Data1, guid.Data2, guid.Data3, szCharString);
03925     return;
03926 }
03927 
03928 PCHAR
03929 ECDisp_GetHidAppStatusString(
03930     NTSTATUS StatusCode
03931 )
03932 {
03933     static CHAR hidString[128];
03934     HRESULT        stringReturn;
03935 
03936     switch (StatusCode)
03937     {
03938     case HIDP_STATUS_SUCCESS:
03939         return ("Success");
03940 
03941     case HIDP_STATUS_NULL:
03942         return ("Status NULL");
03943 
03944     case HIDP_STATUS_INVALID_PREPARSED_DATA:
03945         return ("Invalid Prepared Data");
03946 
03947     case HIDP_STATUS_INVALID_REPORT_TYPE:
03948         return ("Invalid Report Type");
03949 
03950     case HIDP_STATUS_INVALID_REPORT_LENGTH:
03951         return ("Invalid Report Length");
03952 
03953     case HIDP_STATUS_USAGE_NOT_FOUND:
03954         return ("Usage not found");
03955 
03956     case HIDP_STATUS_VALUE_OUT_OF_RANGE:
03957         return ("Value out of range");
03958 
03959     case HIDP_STATUS_BAD_LOG_PHY_VALUES:
03960         return ("Bad logical physical values");
03961 
03962     case HIDP_STATUS_BUFFER_TOO_SMALL:
03963         return ("Buffer too small");
03964 
03965     case HIDP_STATUS_INTERNAL_ERROR:
03966         return ("Internal error");
03967 
03968     case HIDP_STATUS_I8242_TRANS_UNKNOWN:
03969         return ("I8242 Translation unknown");
03970 
03971     case HIDP_STATUS_INCOMPATIBLE_REPORT_ID:
03972         return ("Incompatible report ID");
03973 
03974     case HIDP_STATUS_NOT_VALUE_ARRAY:
03975         return ("Not value array");
03976 
03977     case HIDP_STATUS_IS_VALUE_ARRAY:
03978         return ("Is value array");
03979 
03980     case HIDP_STATUS_DATA_INDEX_NOT_FOUND:
03981         return ("Data index not found");
03982 
03983     case HIDP_STATUS_DATA_INDEX_OUT_OF_RANGE:
03984         return ("Data index out of range");
03985 
03986     case HIDP_STATUS_BUTTON_NOT_PRESSED:
03987         return ("Button not pressed");
03988 
03989     case HIDP_STATUS_REPORT_DOES_NOT_EXIST:
03990         return ("Report does not exist");
03991 
03992     case HIDP_STATUS_NOT_IMPLEMENTED:
03993         return ("Not implemented");
03994 
03995     default:
03996         stringReturn = StringCbPrintf(hidString, sizeof(hidString),
03997                        "Unknown HID Status error: 0x%x", StatusCode);
03998         return (hidString);
03999     }
04000 }
04001 
04002 BOOL
04003 ECDisp_ConvertUlongListToValueList(
04004     IN  PULONG  UlongList,
04005     IN  ULONG   nUlongs,
04006     IN  USHORT  BitSize,
04007     IN  USHORT  ReportCount,
04008     OUT PCHAR   *ValueList,
04009     OUT PULONG  ValueListSize
04010 )
04011 /*++
04012 RoutineDescription:
04013     This routine takes a list of ULong values and formats a value list that is
04014     used as input to HidP_SetUsageValueArray.  Unfortunately, this HidP function
04015     requires the caller to format the input buffer which means taking each of
04016     the values in Ulong, truncating their values to meet bit size and then set
04017     those bits at the appropriate spot in the buffer.  That is the purpose of
04018     this function
04019 
04020     The function will return TRUE if everything succeeded, FALSE otherwise.
04021 --*/
04022 {
04023 
04024     ULONG       ulMask;
04025     PCHAR       List;
04026     INT         iByteIndex;
04027     INT         iByteOffset;
04028     ULONG       UlongIndex;
04029     ULONG       ListSize;
04030     USHORT      BitsToAdd;
04031     USHORT      nBits;
04032     ULONG       ulValue;
04033     UCHAR       LowByte;
04034 
04035     *ValueList = NULL;
04036     *ValueListSize = 0;
04037 
04038     //
04039     // Do some parameter validation...ReportCount should never be zero.
04040     //
04041 
04042     if (0 == ReportCount)
04043     {
04044         SetLastError(ERROR_INVALID_PARAMETER);
04045 
04046         return (FALSE);
04047     }
04048 
04049     //
04050     // Check the number of ulongs passed in is actually less than or equal
04051     //  to the report count and if not, use only the first ReportCount
04052     //  number of ULongs.
04053     //
04054 
04055     if (nUlongs > ReportCount)
04056     {
04057         nUlongs = ReportCount;
04058     }
04059 
04060     /*
04061     // Allocate our buffer for the value list and return FALSE if it couldn't
04062     //   be done
04063     */
04064 
04065     ListSize = ROUND_TO_NEAREST_BYTE(BitSize * ReportCount);
04066     List = (PCHAR) malloc(ListSize);
04067 
04068     if (NULL == List)
04069     {
04070         SetLastError(ERROR_OUTOFMEMORY);
04071         return (FALSE);
04072     }
04073 
04074     /*
04075     // Initialize the buffer to all zeroes
04076     */
04077 
04078     memset(List, 0x00, ListSize);
04079 
04080     /*
04081     // Buffer has been allocated let's convert those values
04082     */
04083 
04084     /*
04085     // Determine the mask that will be used to retrieve the cared about bits
04086     //   of our value
04087     */
04088 
04089     ulMask = (sizeof(ULONG)*8 == BitSize) ? ULONG_MAX : (1 << BitSize)-1;
04090 
04091     /*
04092     // Initialize the iByteIndex and iByteOffset fields before entering the
04093     //    conversion loop.
04094     */
04095 
04096     iByteIndex = 0;
04097     iByteOffset = 0;
04098 
04099     /*
04100     // This is the main conversion loop.  It performs the following steps on
04101     //    each Ulong in the ulong list
04102     //      1) Sets BitsToAdd = BitSize
04103     //      2) Gets the ulValue and the masks off the upper bits that we don't
04104     //           care about.
04105     //      3) Determines how many bits can fit at the current byte index based
04106     //          on the current byte offset and the number of bits left to add
04107     //      4) Retrieve those bits, shift them to the correct position and
04108     //            use bitwise or to get the correct values in the buffer
04109     //      5) Increment the byte index and set our new byte offset
04110     //      6) Shift our Ulong value right to get rid of least significant bits
04111     //           that have already been added
04112     //      7) Repeat through step 3 until no more bits to add
04113     */
04114 
04115     for (UlongIndex = 0; UlongIndex < nUlongs; UlongIndex++)
04116     {
04117         BitsToAdd = BitSize;
04118 
04119         ulValue = *(UlongList + UlongIndex) & ulMask;
04120 
04121         while (BitsToAdd > 0)
04122         {
04123             nBits = min (8 - iByteOffset, BitsToAdd);
04124 
04125             LowByte = (UCHAR) (ulValue & 0xFF);
04126 
04127             LowByte = LowByte << iByteOffset;
04128 
04129             *(List+iByteIndex) |= LowByte;
04130 
04131             iByteIndex = (iByteOffset+nBits) >= 8 ? iByteIndex+1 : iByteIndex;
04132             iByteOffset = (iByteOffset + nBits) % 8;
04133 
04134             BitsToAdd -= nBits;
04135 
04136             ulValue = ulValue >> nBits;
04137         }
04138     }
04139 
04140     *ValueList = List;
04141     *ValueListSize = ListSize;
04142 
04143     return (TRUE);
04144 }
04145 
04146 PCHAR
04147 ResolveFunctionName(
04148     INT Index
04149 )
04150 {
04151     PCHAR   FuncName;
04152 
04153     if (IS_HIDD_FUNCTION(Index) || IS_HID_FUNCTION(Index))
04154     {
04155         FuncName = DeviceCalls[Index-1].szFunctionName;
04156     }
04157     else
04158     {
04159         FuncName = PpdCalls[Index-HID_DEVCALLS-1].szFunctionName;
04160     }
04161 
04162     return (FuncName);
04163 }
04164 
04165 VOID
04166 DisplayExtendedAttributes(
04167     IN  HWND                OutputWindow,
04168     IN  PHIDP_UNKNOWN_TOKEN UnknownList,
04169     IN  ULONG               UnknownListLength
04170 )
04171 {
04172     PHIDP_UNKNOWN_TOKEN current;
04173     ULONG               index;
04174     HRESULT                stringReturn;
04175 
04176     stringReturn = StringCbPrintf(szTempBuffer, TEMP_BUFFER_SIZE,
04177                    "Number of attributes: %d", UnknownListLength);
04178     OUTSTRING(OutputWindow, szTempBuffer);
04179 
04180     current = UnknownList;
04181     for (index = 0; index < UnknownListLength; index++)
04182     {
04183        stringReturn = StringCbPrintf(szTempBuffer,
04184                       TEMP_BUFFER_SIZE,
04185                       "Token: %d  BitField: 0x%X",
04186                       current -> Token,
04187                       current -> BitField);
04188 
04189         OUTSTRING(OutputWindow, szTempBuffer);
04190     }
04191 
04192     return;
04193 }
04194 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines