mirror of
https://github.com/hyblocker/OpenVR-SpaceCalibrator.git
synced 2026-10-07 20:00:21 +02:00
94 lines
2.4 KiB
C++
94 lines
2.4 KiB
C++
#include "stdafx.h"
|
|
#include "IPCClient.h"
|
|
|
|
#include <string>
|
|
|
|
static std::string LastErrorString(DWORD lastError)
|
|
{
|
|
LPSTR buffer = nullptr;
|
|
size_t size = FormatMessageA(
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
NULL, lastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buffer, 0, NULL
|
|
);
|
|
|
|
std::string message(buffer, size);
|
|
LocalFree(buffer);
|
|
return message;
|
|
}
|
|
|
|
IPCClient::~IPCClient()
|
|
{
|
|
if (pipe && pipe != INVALID_HANDLE_VALUE)
|
|
CloseHandle(pipe);
|
|
}
|
|
|
|
void IPCClient::Connect()
|
|
{
|
|
LPTSTR pipeName = TEXT(OPENVR_SPACECALIBRATOR_PIPE_NAME);
|
|
|
|
WaitNamedPipe(pipeName, 1000);
|
|
pipe = CreateFile(pipeName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
|
|
|
|
if (pipe == INVALID_HANDLE_VALUE)
|
|
{
|
|
throw std::runtime_error("Space Calibrator driver unavailable. Make sure SteamVR is running, and the Space Calibrator addon is enabled in SteamVR settings.");
|
|
}
|
|
|
|
DWORD mode = PIPE_READMODE_MESSAGE;
|
|
if (!SetNamedPipeHandleState(pipe, &mode, 0, 0))
|
|
{
|
|
throw std::runtime_error("Couldn't set pipe mode. Error: " + LastErrorString(GetLastError()));
|
|
}
|
|
|
|
auto response = SendBlocking(protocol::Request(protocol::RequestHandshake));
|
|
if (response.type != protocol::ResponseHandshake || response.protocol.version != protocol::Version)
|
|
{
|
|
throw std::runtime_error(
|
|
"Incorrect driver version installed, try reinstalling OpenVR-SpaceCalibrator. (Client: " +
|
|
std::to_string(protocol::Version) +
|
|
", Driver: " +
|
|
std::to_string(response.protocol.version) +
|
|
")"
|
|
);
|
|
}
|
|
}
|
|
|
|
protocol::Response IPCClient::SendBlocking(const protocol::Request &request)
|
|
{
|
|
Send(request);
|
|
return Receive();
|
|
}
|
|
|
|
void IPCClient::Send(const protocol::Request &request)
|
|
{
|
|
DWORD bytesWritten;
|
|
BOOL success = WriteFile(pipe, &request, sizeof request, &bytesWritten, 0);
|
|
if (!success)
|
|
{
|
|
throw std::runtime_error("Error writing IPC request. Error: " + LastErrorString(GetLastError()));
|
|
}
|
|
}
|
|
|
|
protocol::Response IPCClient::Receive()
|
|
{
|
|
protocol::Response response(protocol::ResponseInvalid);
|
|
DWORD bytesRead;
|
|
|
|
BOOL success = ReadFile(pipe, &response, sizeof response, &bytesRead, 0);
|
|
if (!success)
|
|
{
|
|
DWORD lastError = GetLastError();
|
|
if (lastError != ERROR_MORE_DATA)
|
|
{
|
|
throw std::runtime_error("Error reading IPC response. Error: " + LastErrorString(lastError));
|
|
}
|
|
}
|
|
|
|
if (bytesRead != sizeof response)
|
|
{
|
|
throw std::runtime_error("Invalid IPC response with size " + std::to_string(bytesRead));
|
|
}
|
|
|
|
return response;
|
|
}
|