Die Allokation vom Output Buffer (Größe: Caps.OutputReportByteLength + 1) und das einfügen der Daten im Stream (HidP_SetUsageValue) funktioniert.
Was nicht funktioniert ist da Senden der Daten mit HidD_SetOutputReport: Es schlägt fehl und das Gerät meldet sich ab. :(
Interessanterweise: Schreibe ich die Daten mit WriteFile direkt, funktioniert das, bewegt sich am Gerät jedoch nichts.
So gehe ich vor:
Initialisierung:
- Device-Liste abfragen, für jedes Device:
- Handles erzeugen (jeweils eins für 0, GENERIC_READ und GENERIC_WRITE)
- Namen, Hersteller, Preparsed Data lesen.
- Capabilities abfragen.
- Blob für Output Buffer erzeugen (Caps.OutputReportByteLength + 1) [+1 byte für die Report ID]
- Buttons und Values zwischenspeichern, ranging von Indices.
- Konfiguration zwecks Name und Anpassung von Buttons (Kalibrierungsdaten, Namen für Buttons und Slider).
- Setzen des Wertes vom Benutzer-Bereich in den logischen Device-Bereich (Slider, Kalibrierung).
- Setzen des ersten Bytes für die Report ID.
- Setzen des Wertes via HidP_SetUsageValue(). Funktioniert.
- Senden des Buffers via HidD_SetOutputReport().
Code: Alles auswählen
/// <summary> Sets the feedback. </summary>
///
/// <exception cref="DynamicException"> Thrown when a Dynamic error condition occurs. </exception>
///
/// <param name="hDevice"> The NT device. </param>
/// <param name="PreparsedData"> [in,out] Information describing the preparsed data. </param>
/// <param name="Page"> The page. </param>
/// <param name="Usage"> The usage. </param>
/// <param name="State"> The state. </param>
inline void SetFeedback(const HANDLE hDevice, PHIDP_PREPARSED_DATA &PreparsedData, const USHORT Page, const USHORT Usage, const ULONG State) const
{
NTSTATUS ret = 0;
memcpy_s(m_FeedbackData->Edit(), 1, &m_ReportID, 1);
if (HIDP_STATUS_SUCCESS != (ret = HidP_SetUsageValue( HidP_Output, Page, 0, Usage, State, PreparsedData,
(PCHAR)m_FeedbackData->Edit() + 1, static_cast<ULONG>(m_FeedbackData->Size() - 1))))
throw DynamicException(L"Failed to set feedback data", L"Failed to set the feedback value for a control.", TS_STAMP);
DWORD NumBytesWritten = 0;
// if(FALSE == WriteFile(hDevice, m_FeedbackData->Get(), cast<DWORD>(m_FeedbackData->Size()), &NumBytesWritten, nullptr))
if (FALSE == HidD_SetOutputReport(hDevice, m_FeedbackData->Edit(), static_cast<ULONG>(m_FeedbackData->Size())))
{
LPWSTR errorText = NULL;
const auto h = HRESULT_FROM_WIN32(GetLastError());
// Only for description what happened.
FormatMessageW( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, h, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), (LPTSTR)&errorText, 0, nullptr);
wstring Message;
if (NULL != errorText)
{
Message = wstring(L"Failed to set the output report for a device control: ") + errorText;
LocalFree(errorText);
errorText = NULL;
}
else
{
Message = L"Failed to set the output report for a device control.";
}
throw DynamicException(L"Failed to set feedback data", Message, TS_STAMP);
}
// wprintf_s(L"IO\tNum bytes written: %i", NumBytesWritten);
}
Ich weiß ehrlich gesagt nicht mehr, ob Logitech mal wieder etwas für sich verschlüsselt.
Hab mich schon bei TrackIR aufgeregt, OptiTrack unbedingt einarbeiten zu müssen.
Gruß,
Patrick