00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <basetyps.h>
00021 #include <stdlib.h>
00022 #include <wtypes.h>
00023 #include <setupapi.h>
00024 #include "hidsdi.h"
00025 #include "hid.h"
00026 #include <strsafe.h>
00027
00028 BOOLEAN
00029 FindKnownHidDevices (
00030 OUT PHID_DEVICE * HidDevices,
00031 OUT PULONG NumberDevices
00032 )
00033
00034
00035
00036
00037
00038 {
00039 HDEVINFO hardwareDeviceInfo;
00040 SP_DEVICE_INTERFACE_DATA deviceInfoData;
00041 ULONG i;
00042 BOOLEAN done;
00043 PHID_DEVICE hidDeviceInst;
00044 GUID hidGuid;
00045 PSP_DEVICE_INTERFACE_DETAIL_DATA functionClassDeviceData = NULL;
00046 ULONG predictedLength = 0;
00047 ULONG requiredLength = 0;
00048 PHID_DEVICE newHidDevices;
00049
00050
00051 HidD_GetHidGuid (&hidGuid);
00052
00053 *HidDevices = NULL;
00054 *NumberDevices = 0;
00055
00056
00057
00058
00059 hardwareDeviceInfo = SetupDiGetClassDevs ( &hidGuid,
00060 NULL,
00061 NULL,
00062 (DIGCF_PRESENT |
00063 DIGCF_DEVICEINTERFACE));
00064
00065
00066
00067
00068
00069 *NumberDevices = 4;
00070 done = FALSE;
00071 deviceInfoData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);
00072
00073 i=0;
00074 while (!done)
00075 {
00076 *NumberDevices *= 2;
00077
00078 if (*HidDevices)
00079 {
00080 newHidDevices =
00081 realloc (*HidDevices, (*NumberDevices * sizeof (HID_DEVICE)));
00082
00083 if (NULL == newHidDevices)
00084 {
00085 free(*HidDevices);
00086 }
00087
00088 *HidDevices = newHidDevices;
00089 }
00090 else
00091 {
00092 *HidDevices = calloc (*NumberDevices, sizeof (HID_DEVICE));
00093 }
00094
00095 if (NULL == *HidDevices)
00096 {
00097 SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
00098 return FALSE;
00099 }
00100
00101 hidDeviceInst = *HidDevices + i;
00102
00103 for (; i < *NumberDevices; i++, hidDeviceInst++)
00104 {
00105 if (SetupDiEnumDeviceInterfaces (hardwareDeviceInfo,
00106 0,
00107 &hidGuid,
00108 i,
00109 &deviceInfoData))
00110 {
00111
00112
00113
00114
00115
00116 SetupDiGetDeviceInterfaceDetail (
00117 hardwareDeviceInfo,
00118 &deviceInfoData,
00119 NULL,
00120 0,
00121 &requiredLength,
00122 NULL);
00123
00124
00125 predictedLength = requiredLength;
00126
00127 functionClassDeviceData = malloc (predictedLength);
00128 if (functionClassDeviceData)
00129 {
00130 functionClassDeviceData->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
00131 }
00132 else
00133 {
00134 SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
00135 return FALSE;
00136 }
00137
00138
00139
00140
00141
00142 if (! SetupDiGetDeviceInterfaceDetail (
00143 hardwareDeviceInfo,
00144 &deviceInfoData,
00145 functionClassDeviceData,
00146 predictedLength,
00147 &requiredLength,
00148 NULL))
00149 {
00150 SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
00151 free(functionClassDeviceData);
00152 return FALSE;
00153 }
00154
00155
00156
00157
00158
00159 if (! OpenHidDevice (functionClassDeviceData -> DevicePath,
00160 FALSE,
00161 FALSE,
00162 FALSE,
00163 FALSE,
00164 hidDeviceInst))
00165 {
00166 SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
00167 free(functionClassDeviceData);
00168 return FALSE;
00169 }
00170
00171 }
00172 else
00173 {
00174 if (ERROR_NO_MORE_ITEMS == GetLastError())
00175 {
00176 done = TRUE;
00177 break;
00178 }
00179 }
00180 }
00181 }
00182
00183 *NumberDevices = i;
00184
00185 SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
00186 free(functionClassDeviceData);
00187 return TRUE;
00188 }
00189
00190 BOOLEAN
00191 OpenHidDevice (
00192 IN PCHAR DevicePath,
00193 IN BOOL HasReadAccess,
00194 IN BOOL HasWriteAccess,
00195 IN BOOL IsOverlapped,
00196 IN BOOL IsExclusive,
00197 IN OUT PHID_DEVICE HidDevice
00198 )
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 {
00210 DWORD accessFlags = 0;
00211 DWORD sharingFlags = 0;
00212 BOOLEAN bSuccess;
00213 INT iDevicePathSize;
00214 HRESULT stringReturn;
00215
00216 iDevicePathSize = strlen(DevicePath) + 1;
00217
00218 HidDevice -> DevicePath = malloc(iDevicePathSize);
00219
00220 if (NULL == HidDevice -> DevicePath)
00221 {
00222 return (FALSE);
00223 }
00224
00225 stringReturn = StringCbCopy(HidDevice -> DevicePath, iDevicePathSize, DevicePath);
00226
00227 if (HasReadAccess)
00228 {
00229 accessFlags |= GENERIC_READ;
00230 }
00231
00232 if (HasWriteAccess)
00233 {
00234 accessFlags |= GENERIC_WRITE;
00235 }
00236
00237 if (!IsExclusive)
00238 {
00239 sharingFlags = FILE_SHARE_READ | FILE_SHARE_WRITE;
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249 HidDevice->HidDevice = CreateFile (DevicePath,
00250 accessFlags,
00251 sharingFlags,
00252 NULL,
00253 OPEN_EXISTING,
00254 0,
00255 NULL);
00256
00257 if (INVALID_HANDLE_VALUE == HidDevice->HidDevice)
00258 {
00259 free(HidDevice -> DevicePath);
00260 HidDevice -> DevicePath = INVALID_HANDLE_VALUE;
00261 return FALSE;
00262 }
00263
00264 HidDevice -> OpenedForRead = HasReadAccess;
00265 HidDevice -> OpenedForWrite = HasWriteAccess;
00266 HidDevice -> OpenedOverlapped = IsOverlapped;
00267 HidDevice -> OpenedExclusive = IsExclusive;
00268
00269
00270
00271
00272
00273
00274
00275
00276 if (!HidD_GetPreparsedData (HidDevice->HidDevice, &HidDevice->Ppd))
00277 {
00278 free(HidDevice -> DevicePath);
00279 HidDevice -> DevicePath = NULL;
00280 CloseHandle(HidDevice -> HidDevice);
00281 HidDevice -> HidDevice = INVALID_HANDLE_VALUE;
00282 return FALSE;
00283 }
00284
00285 if (!HidD_GetAttributes (HidDevice->HidDevice, &HidDevice->Attributes))
00286 {
00287 free(HidDevice -> DevicePath);
00288 HidDevice -> DevicePath = NULL;
00289 CloseHandle(HidDevice -> HidDevice);
00290 HidDevice -> HidDevice = INVALID_HANDLE_VALUE;
00291 HidD_FreePreparsedData (HidDevice->Ppd);
00292 HidDevice->Ppd = NULL;
00293
00294 return FALSE;
00295 }
00296
00297 if (!HidP_GetCaps (HidDevice->Ppd, &HidDevice->Caps))
00298 {
00299 free(HidDevice -> DevicePath);
00300 HidDevice -> DevicePath = NULL;
00301 CloseHandle(HidDevice -> HidDevice);
00302 HidDevice -> HidDevice = INVALID_HANDLE_VALUE;
00303 HidD_FreePreparsedData (HidDevice->Ppd);
00304 HidDevice->Ppd = NULL;
00305
00306 return FALSE;
00307 }
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 bSuccess = FillDeviceInfo(HidDevice);
00324
00325 if (FALSE == bSuccess)
00326 {
00327 CloseHidDevice(HidDevice);
00328 return (FALSE);
00329 }
00330
00331 if (IsOverlapped)
00332 {
00333 CloseHandle(HidDevice->HidDevice);
00334
00335 HidDevice->HidDevice = CreateFile (DevicePath,
00336 accessFlags,
00337 sharingFlags,
00338 NULL,
00339 OPEN_EXISTING,
00340 FILE_FLAG_OVERLAPPED,
00341 NULL);
00342
00343 if (INVALID_HANDLE_VALUE == HidDevice->HidDevice)
00344 {
00345 CloseHidDevice(HidDevice);
00346 return FALSE;
00347 }
00348 }
00349
00350 return (TRUE);
00351 }
00352
00353 BOOLEAN
00354 FillDeviceInfo(
00355 IN PHID_DEVICE HidDevice
00356 )
00357 {
00358 USHORT numValues;
00359 USHORT numCaps;
00360 PHIDP_BUTTON_CAPS buttonCaps;
00361 PHIDP_VALUE_CAPS valueCaps;
00362 PHID_DATA data;
00363 ULONG i;
00364 USAGE usage;
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 HidDevice->InputReportBuffer = (PCHAR)
00375 calloc (HidDevice->Caps.InputReportByteLength, sizeof (CHAR));
00376
00377
00378
00379
00380
00381
00382
00383 HidDevice->InputButtonCaps = buttonCaps = (PHIDP_BUTTON_CAPS)
00384 calloc (HidDevice->Caps.NumberInputButtonCaps, sizeof (HIDP_BUTTON_CAPS));
00385
00386 if (NULL == buttonCaps)
00387 {
00388 return (FALSE);
00389 }
00390
00391 HidDevice->InputValueCaps = valueCaps = (PHIDP_VALUE_CAPS)
00392 calloc (HidDevice->Caps.NumberInputValueCaps, sizeof (HIDP_VALUE_CAPS));
00393
00394 if (NULL == valueCaps)
00395 {
00396 return(FALSE);
00397 }
00398
00399
00400
00401
00402
00403 numCaps = HidDevice->Caps.NumberInputButtonCaps;
00404
00405 HidP_GetButtonCaps (HidP_Input,
00406 buttonCaps,
00407 &numCaps,
00408 HidDevice->Ppd);
00409
00410 numCaps = HidDevice->Caps.NumberInputValueCaps;
00411
00412 HidP_GetValueCaps (HidP_Input,
00413 valueCaps,
00414 &numCaps,
00415 HidDevice->Ppd);
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 numValues = 0;
00431 for (i = 0; i < HidDevice->Caps.NumberInputValueCaps; i++, valueCaps++)
00432 {
00433 if (valueCaps->IsRange)
00434 {
00435 numValues += valueCaps->Range.UsageMax - valueCaps->Range.UsageMin + 1;
00436 }
00437 else
00438 {
00439 numValues++;
00440 }
00441 }
00442 valueCaps = HidDevice->InputValueCaps;
00443
00444
00445
00446
00447
00448
00449
00450
00451 HidDevice->InputDataLength = HidDevice->Caps.NumberInputButtonCaps
00452 + numValues;
00453
00454 HidDevice->InputData = data = (PHID_DATA)
00455 calloc (HidDevice->InputDataLength, sizeof (HID_DATA));
00456
00457 if (NULL == data)
00458 {
00459 return (FALSE);
00460 }
00461
00462
00463
00464
00465
00466 for (i = 0;
00467 i < HidDevice->Caps.NumberInputButtonCaps;
00468 i++, data++, buttonCaps++)
00469 {
00470 data->IsButtonData = TRUE;
00471 data->Status = HIDP_STATUS_SUCCESS;
00472 data->UsagePage = buttonCaps->UsagePage;
00473 if (buttonCaps->IsRange)
00474 {
00475 data->ButtonData.UsageMin = buttonCaps -> Range.UsageMin;
00476 data->ButtonData.UsageMax = buttonCaps -> Range.UsageMax;
00477 }
00478 else
00479 {
00480 data -> ButtonData.UsageMin = data -> ButtonData.UsageMax = buttonCaps -> NotRange.Usage;
00481 }
00482
00483 data->ButtonData.MaxUsageLength = HidP_MaxUsageListLength (
00484 HidP_Input,
00485 buttonCaps->UsagePage,
00486 HidDevice->Ppd);
00487 data->ButtonData.Usages = (PUSAGE)
00488 calloc (data->ButtonData.MaxUsageLength, sizeof (USAGE));
00489
00490 data->ReportID = buttonCaps -> ReportID;
00491 }
00492
00493
00494
00495
00496
00497 for (i = 0; i < numValues; i++, valueCaps++)
00498 {
00499 if (valueCaps->IsRange)
00500 {
00501 for (usage = valueCaps->Range.UsageMin;
00502 usage <= valueCaps->Range.UsageMax;
00503 usage++)
00504 {
00505 data->IsButtonData = FALSE;
00506 data->Status = HIDP_STATUS_SUCCESS;
00507 data->UsagePage = valueCaps->UsagePage;
00508 data->ValueData.Usage = usage;
00509 data->ReportID = valueCaps -> ReportID;
00510 data++;
00511 }
00512 }
00513 else
00514 {
00515 data->IsButtonData = FALSE;
00516 data->Status = HIDP_STATUS_SUCCESS;
00517 data->UsagePage = valueCaps->UsagePage;
00518 data->ValueData.Usage = valueCaps->NotRange.Usage;
00519 data->ReportID = valueCaps -> ReportID;
00520 data++;
00521 }
00522 }
00523
00524
00525
00526
00527
00528 HidDevice->OutputReportBuffer = (PCHAR)
00529 calloc (HidDevice->Caps.OutputReportByteLength, sizeof (CHAR));
00530
00531 HidDevice->OutputButtonCaps = buttonCaps = (PHIDP_BUTTON_CAPS)
00532 calloc (HidDevice->Caps.NumberOutputButtonCaps, sizeof (HIDP_BUTTON_CAPS));
00533
00534 if (NULL == buttonCaps)
00535 {
00536 return (FALSE);
00537 }
00538
00539 HidDevice->OutputValueCaps = valueCaps = (PHIDP_VALUE_CAPS)
00540 calloc (HidDevice->Caps.NumberOutputValueCaps, sizeof (HIDP_VALUE_CAPS));
00541
00542 if (NULL == valueCaps)
00543 {
00544 return (FALSE);
00545 }
00546
00547 numCaps = HidDevice->Caps.NumberOutputButtonCaps;
00548 HidP_GetButtonCaps (HidP_Output,
00549 buttonCaps,
00550 &numCaps,
00551 HidDevice->Ppd);
00552
00553 numCaps = HidDevice->Caps.NumberOutputValueCaps;
00554 HidP_GetValueCaps (HidP_Output,
00555 valueCaps,
00556 &numCaps,
00557 HidDevice->Ppd);
00558
00559 numValues = 0;
00560 for (i = 0; i < HidDevice->Caps.NumberOutputValueCaps; i++, valueCaps++)
00561 {
00562 if (valueCaps->IsRange)
00563 {
00564 numValues += valueCaps->Range.UsageMax
00565 - valueCaps->Range.UsageMin + 1;
00566 }
00567 else
00568 {
00569 numValues++;
00570 }
00571 }
00572 valueCaps = HidDevice->OutputValueCaps;
00573
00574 HidDevice->OutputDataLength = HidDevice->Caps.NumberOutputButtonCaps
00575 + numValues;
00576
00577 HidDevice->OutputData = data = (PHID_DATA)
00578 calloc (HidDevice->OutputDataLength, sizeof (HID_DATA));
00579
00580 if (NULL == data)
00581 {
00582 return (FALSE);
00583 }
00584
00585 for (i = 0;
00586 i < HidDevice->Caps.NumberOutputButtonCaps;
00587 i++, data++, buttonCaps++)
00588 {
00589 data->IsButtonData = TRUE;
00590 data->Status = HIDP_STATUS_SUCCESS;
00591 data->UsagePage = buttonCaps->UsagePage;
00592
00593 if (buttonCaps->IsRange)
00594 {
00595 data->ButtonData.UsageMin = buttonCaps -> Range.UsageMin;
00596 data->ButtonData.UsageMax = buttonCaps -> Range.UsageMax;
00597 }
00598 else
00599 {
00600 data -> ButtonData.UsageMin = data -> ButtonData.UsageMax = buttonCaps -> NotRange.Usage;
00601 }
00602
00603 data->ButtonData.MaxUsageLength = HidP_MaxUsageListLength (
00604 HidP_Output,
00605 buttonCaps->UsagePage,
00606 HidDevice->Ppd);
00607
00608 data->ButtonData.Usages = (PUSAGE)
00609 calloc (data->ButtonData.MaxUsageLength, sizeof (USAGE));
00610
00611 data->ReportID = buttonCaps -> ReportID;
00612 }
00613
00614 for (i = 0; i < numValues; i++, valueCaps++)
00615 {
00616 if (valueCaps->IsRange)
00617 {
00618 for (usage = valueCaps->Range.UsageMin;
00619 usage <= valueCaps->Range.UsageMax;
00620 usage++)
00621 {
00622 data->IsButtonData = FALSE;
00623 data->Status = HIDP_STATUS_SUCCESS;
00624 data->UsagePage = valueCaps->UsagePage;
00625 data->ValueData.Usage = usage;
00626 data->ReportID = valueCaps -> ReportID;
00627 data++;
00628 }
00629 }
00630 else
00631 {
00632 data->IsButtonData = FALSE;
00633 data->Status = HIDP_STATUS_SUCCESS;
00634 data->UsagePage = valueCaps->UsagePage;
00635 data->ValueData.Usage = valueCaps->NotRange.Usage;
00636 data->ReportID = valueCaps -> ReportID;
00637 data++;
00638 }
00639 }
00640
00641
00642
00643
00644
00645 HidDevice->FeatureReportBuffer = (PCHAR)
00646 calloc (HidDevice->Caps.FeatureReportByteLength, sizeof (CHAR));
00647
00648 HidDevice->FeatureButtonCaps = buttonCaps = (PHIDP_BUTTON_CAPS)
00649 calloc (HidDevice->Caps.NumberFeatureButtonCaps, sizeof (HIDP_BUTTON_CAPS));
00650
00651 if (NULL == buttonCaps)
00652 {
00653 return (FALSE);
00654 }
00655
00656 HidDevice->FeatureValueCaps = valueCaps = (PHIDP_VALUE_CAPS)
00657 calloc (HidDevice->Caps.NumberFeatureValueCaps, sizeof (HIDP_VALUE_CAPS));
00658
00659 if (NULL == valueCaps)
00660 {
00661 return (FALSE);
00662 }
00663
00664 numCaps = HidDevice->Caps.NumberFeatureButtonCaps;
00665 HidP_GetButtonCaps (HidP_Feature,
00666 buttonCaps,
00667 &numCaps,
00668 HidDevice->Ppd);
00669
00670 numCaps = HidDevice->Caps.NumberFeatureValueCaps;
00671 HidP_GetValueCaps (HidP_Feature,
00672 valueCaps,
00673 &numCaps,
00674 HidDevice->Ppd);
00675
00676 numValues = 0;
00677 for (i = 0; i < HidDevice->Caps.NumberFeatureValueCaps; i++, valueCaps++)
00678 {
00679 if (valueCaps->IsRange)
00680 {
00681 numValues += valueCaps->Range.UsageMax
00682 - valueCaps->Range.UsageMin + 1;
00683 }
00684 else
00685 {
00686 numValues++;
00687 }
00688 }
00689 valueCaps = HidDevice->FeatureValueCaps;
00690
00691 HidDevice->FeatureDataLength = HidDevice->Caps.NumberFeatureButtonCaps
00692 + numValues;
00693
00694 HidDevice->FeatureData = data = (PHID_DATA)
00695 calloc (HidDevice->FeatureDataLength, sizeof (HID_DATA));
00696
00697 if (NULL == data)
00698 {
00699 return (FALSE);
00700 }
00701
00702
00703 for (i = 0;
00704 i < HidDevice->Caps.NumberFeatureButtonCaps;
00705 i++, data++, buttonCaps++)
00706 {
00707 data->IsButtonData = TRUE;
00708 data->Status = HIDP_STATUS_SUCCESS;
00709 data->UsagePage = buttonCaps->UsagePage;
00710
00711 if (buttonCaps->IsRange)
00712 {
00713 data->ButtonData.UsageMin = buttonCaps -> Range.UsageMin;
00714 data->ButtonData.UsageMax = buttonCaps -> Range.UsageMax;
00715 }
00716 else
00717 {
00718 data -> ButtonData.UsageMin = data -> ButtonData.UsageMax = buttonCaps -> NotRange.Usage;
00719 }
00720
00721 data->ButtonData.MaxUsageLength = HidP_MaxUsageListLength (
00722 HidP_Feature,
00723 buttonCaps->UsagePage,
00724 HidDevice->Ppd);
00725 data->ButtonData.Usages = (PUSAGE)
00726 calloc (data->ButtonData.MaxUsageLength, sizeof (USAGE));
00727
00728 data->ReportID = buttonCaps -> ReportID;
00729 }
00730
00731 for (i = 0; i < numValues; i++, valueCaps++)
00732 {
00733 if (valueCaps->IsRange)
00734 {
00735 for (usage = valueCaps->Range.UsageMin;
00736 usage <= valueCaps->Range.UsageMax;
00737 usage++)
00738 {
00739 data->IsButtonData = FALSE;
00740 data->Status = HIDP_STATUS_SUCCESS;
00741 data->UsagePage = valueCaps->UsagePage;
00742 data->ValueData.Usage = usage;
00743 data->ReportID = valueCaps -> ReportID;
00744 data++;
00745 }
00746 }
00747 else
00748 {
00749 data->IsButtonData = FALSE;
00750 data->Status = HIDP_STATUS_SUCCESS;
00751 data->UsagePage = valueCaps->UsagePage;
00752 data->ValueData.Usage = valueCaps->NotRange.Usage;
00753 data->ReportID = valueCaps -> ReportID;
00754 data++;
00755 }
00756 }
00757
00758 return (TRUE);
00759 }
00760
00761 VOID
00762 CloseHidDevices(
00763 IN PHID_DEVICE HidDevices,
00764 IN ULONG NumberDevices
00765 )
00766 {
00767 ULONG Index;
00768
00769 for (Index = 0; Index < NumberDevices; Index++)
00770 {
00771 CloseHidDevice(HidDevices+Index);
00772 }
00773
00774 return;
00775 }
00776
00777 VOID
00778 CloseHidDevice (
00779 IN PHID_DEVICE HidDevice
00780 )
00781 {
00782 free(HidDevice -> DevicePath);
00783
00784 if (INVALID_HANDLE_VALUE != HidDevice -> HidDevice)
00785 {
00786 CloseHandle(HidDevice -> HidDevice);
00787 HidDevice -> HidDevice = INVALID_HANDLE_VALUE;
00788 }
00789
00790 if (NULL != HidDevice -> Ppd)
00791 {
00792 HidD_FreePreparsedData(HidDevice -> Ppd);
00793 HidDevice -> Ppd = NULL;
00794 }
00795
00796 if (NULL != HidDevice -> InputReportBuffer)
00797 {
00798 free(HidDevice -> InputReportBuffer);
00799 HidDevice -> InputReportBuffer = NULL;
00800 }
00801
00802 if (NULL != HidDevice -> InputData)
00803 {
00804 free(HidDevice -> InputData);
00805 HidDevice -> InputData = NULL;
00806 }
00807
00808 if (NULL != HidDevice -> InputButtonCaps)
00809 {
00810 free(HidDevice -> InputButtonCaps);
00811 HidDevice -> InputButtonCaps = NULL;
00812 }
00813
00814 if (NULL != HidDevice -> InputValueCaps)
00815 {
00816 free(HidDevice -> InputValueCaps);
00817 HidDevice -> InputValueCaps = NULL;
00818 }
00819
00820 if (NULL != HidDevice -> OutputReportBuffer)
00821 {
00822 free(HidDevice -> OutputReportBuffer);
00823 HidDevice -> OutputReportBuffer = NULL;
00824 }
00825
00826 if (NULL != HidDevice -> OutputData)
00827 {
00828 free(HidDevice -> OutputData);
00829 HidDevice -> OutputData = NULL;
00830 }
00831
00832 if (NULL != HidDevice -> OutputButtonCaps)
00833 {
00834 free(HidDevice -> OutputButtonCaps);
00835 HidDevice -> OutputButtonCaps = NULL;
00836 }
00837
00838 if (NULL != HidDevice -> OutputValueCaps)
00839 {
00840 free(HidDevice -> OutputValueCaps);
00841 HidDevice -> OutputValueCaps = NULL;
00842 }
00843
00844 if (NULL != HidDevice -> FeatureReportBuffer)
00845 {
00846 free(HidDevice -> FeatureReportBuffer);
00847 HidDevice -> FeatureReportBuffer = NULL;
00848 }
00849
00850 if (NULL != HidDevice -> FeatureData)
00851 {
00852 free(HidDevice -> FeatureData);
00853 HidDevice -> FeatureData = NULL;
00854 }
00855
00856 if (NULL != HidDevice -> FeatureButtonCaps)
00857 {
00858 free(HidDevice -> FeatureButtonCaps);
00859 HidDevice -> FeatureButtonCaps = NULL;
00860 }
00861
00862 if (NULL != HidDevice -> FeatureValueCaps)
00863 {
00864 free(HidDevice -> FeatureValueCaps);
00865 HidDevice -> FeatureValueCaps = NULL;
00866 }
00867
00868 return;
00869 }
00870