2017-01-11 1 views
-2

일반 HID 장치 (마우스 또는 키보드가 아님)와 통신을 시도하고 있습니다. Microsoft의 설명서와 내가 찾은 몇 가지 예제 코드에 따라 필자는 장치와 통신을 시작할 수 있다고 생각했습니다. 불행히도 그것에 쓰는 것은 효과가 없습니다.HID WriteFile이 ERROR_INVALID_PARAMETER와 함께 실패합니다.

다음 코드는 일이 실패하는 지점에 도달합니다. 일부 정리 코드가 없거나 불완전하지만 코드가 올바른 VID 및 PID로 작동해야합니다. SetupDiEnumDeviceInterfaces을 호출 할 때 하드 코드 된 1은 내 장치가 내 컴퓨터에있는 인덱스입니다.

#include <Windows.h> 
#include <hidsdi.h> 
#include <SetupAPI.h> 
#include <cstdlib> 
#include <cstdint> 
std::uint16_t constexpr vid = /* My VID */; 
std::uint16_t constexpr pid = /* My PID */; 

int main(int argc, char* argv[]) 
{ 
    GUID hidGuid; 
    HidD_GetHidGuid(&hidGuid); 
    HDEVINFO info = SetupDiGetClassDevsA(&hidGuid, nullptr, nullptr, 
     DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); 
    if (info == INVALID_HANDLE_VALUE) 
     return 1; 
    SP_DEVICE_INTERFACE_DATA data; 
    data.cbSize = sizeof(data); 
    if (!SetupDiEnumDeviceInterfaces(info, nullptr, &hidGuid, 1, &data)) 
     return 1; 
    DWORD requiredSize; 
    if (SetupDiGetDeviceInterfaceDetailA(info, &data, nullptr, 0, 
     &requiredSize, nullptr) || GetLastError() != ERROR_INSUFFICIENT_BUFFER) 
     return 1; 
    SP_DEVICE_INTERFACE_DETAIL_DATA_A* detailData = 
     static_cast<SP_DEVICE_INTERFACE_DETAIL_DATA_A*>(
      std::malloc(requiredSize)); 
    detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); 
    if (!SetupDiGetDeviceInterfaceDetailA(info, &data, detailData, 
     requiredSize, nullptr, nullptr)) 
     return 1; 
    SetupDiDestroyDeviceInfoList(info); 
    HANDLE capsHandle = CreateFileA(detailData->DevicePath, 0, 
     FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, 
     OPEN_EXISTING, 0, nullptr); 
    if (capsHandle == INVALID_HANDLE_VALUE) 
     return 1; 
    HIDD_ATTRIBUTES attr; 
    attr.Size = sizeof(attr); 
    if (!HidD_GetAttributes(capsHandle, &attr)) 
     return 1; 
    if (attr.VendorID != vid || attr.ProductID != pid) 
     return 1; 
    PHIDP_PREPARSED_DATA preparsedData; 
    if (!HidD_GetPreparsedData(capsHandle, &preparsedData)) 
     return 1; 
    CloseHandle(capsHandle); 
    HIDP_CAPS caps; 
    if (HidP_GetCaps(preparsedData, &caps) != HIDP_STATUS_SUCCESS) 
     return 1; 
    HidD_FreePreparsedData(preparsedData); 
    std::uint8_t* inputBuffer = 
     static_cast<std::uint8_t*>(std::malloc(caps.InputReportByteLength)); 
    std::uint8_t* outputBuffer = 
     static_cast<std::uint8_t*>(std::malloc(caps.OutputReportByteLength)); 
    HANDLE hidHandle = CreateFileA(detailData->DevicePath, 
     GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 
     nullptr, OPEN_EXISTING, 0, nullptr); 
    if (hidHandle == INVALID_HANDLE_VALUE) 
     return 1; 
    ZeroMemory(outputBuffer, caps.OutputReportByteLength); 
    outputBuffer[0] = 11; 
    outputBuffer[1] = 12; 
    DWORD bytesWritten; 
    if (!WriteFile(hidHandle, outputBuffer, caps.OutputReportByteLength, 
     &bytesWritten, nullptr)) 
    { 
     auto x = GetLastError(); 
     return 1; 
    } 
    return 0; 
} 

WriteFile을 호출 할 때까지 예상대로 실행됩니다. 그 시점에서 실패하면 x에 값 87 (ERROR_INVALID_PARAMETER)이 지정됩니다. 왜 이것이 실패할까요? 모든 매개 변수가 나에게 맞는 것 같습니다.

+3

많은 코드를 제거했습니다. 모든 오류 검사 시작. MCVE는 좋을 것입니다. –

+0

모든 매개 변수의 값을 모두 확인 했습니까? 아니면 가정하고 있습니까? – immibis

+0

코드에서 테스트하여 단계별 디버거를 사용하여 모든 함수의 결과를 확인합니다. – Graznarak

답변

0

우리 장치를 생산하는 사람들과 의사 소통을 한 후, 출력 버퍼가 잘못 채워진다는 것이 발견되었습니다. 0이 아닌 두 바이트는 인덱스 0과 1의 바이트가 아닌 인덱스 1과 2의 바이트 여야합니다.

관련 문제