一般的な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
)が割り当てられます。なぜこれが失敗するのだろうか?すべてのパラメータが正しいと思われます。
多くのコードを削除しました。すべてのエラーが開始をチェックしています。 MCVEはいいでしょう。 –
すべてのパラメータのすべての値をチェックしましたか、それとも仮定していますか? – immibis
すべての関数の結果は、コードでテストし、ステップスルーデバッガで数値を検証することによって検証されます。 – Graznarak