2017-01-11 49 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

私たちのデバイスを生産している人と通信した後、出力バッファが間違って埋められていることがわかりました。非ゼロの2バイトは、インデックス1と2のバイトであり、インデックス0と1のバイトではありません。

関連する問題