discord-rpc/src/connection_win.cpp

80 lines
1.9 KiB
C++
Raw Normal View History

#include "connection.h"
#define WIN32_LEAN_AND_MEAN
#define NOMCX
#define NOSERVICE
#define NOIME
#include <windows.h>
2017-07-20 22:58:23 +01:00
int GetProcessId()
{
return ::GetCurrentProcessId();
}
2017-07-17 17:28:54 +01:00
struct BaseConnectionWin : public BaseConnection {
HANDLE pipe{INVALID_HANDLE_VALUE};
};
2017-07-17 17:28:54 +01:00
static BaseConnectionWin Connection;
static const wchar_t* PipeName = L"\\\\?\\pipe\\discord-ipc";
2017-07-17 17:28:54 +01:00
/*static*/ BaseConnection* BaseConnection::Create()
{
2017-07-17 17:28:54 +01:00
return &Connection;
}
2017-07-17 17:28:54 +01:00
/*static*/ void BaseConnection::Destroy(BaseConnection*& c)
{
2017-07-17 17:28:54 +01:00
auto self = reinterpret_cast<BaseConnectionWin*>(c);
self->Close();
c = nullptr;
}
2017-07-17 17:28:54 +01:00
bool BaseConnection::Open()
{
2017-07-17 17:28:54 +01:00
auto self = reinterpret_cast<BaseConnectionWin*>(this);
for (;;) {
self->pipe = ::CreateFileW(PipeName, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr);
if (self->pipe != INVALID_HANDLE_VALUE) {
2017-07-17 17:28:54 +01:00
return true;
}
if (GetLastError() != ERROR_PIPE_BUSY) {
2017-07-17 17:28:54 +01:00
return false;
}
if (!WaitNamedPipeW(PipeName, 10000)) {
2017-07-17 17:28:54 +01:00
return false;
}
}
}
2017-07-17 17:28:54 +01:00
bool BaseConnection::Close()
{
2017-07-17 17:28:54 +01:00
auto self = reinterpret_cast<BaseConnectionWin*>(this);
::CloseHandle(self->pipe);
self->pipe = INVALID_HANDLE_VALUE;
2017-07-17 17:28:54 +01:00
return true;
}
2017-07-17 17:28:54 +01:00
bool BaseConnection::Write(const void* data, size_t length)
{
2017-07-17 17:28:54 +01:00
auto self = reinterpret_cast<BaseConnectionWin*>(this);
return ::WriteFile(self->pipe, data, length, nullptr, nullptr) == TRUE;
}
2017-07-17 17:28:54 +01:00
bool BaseConnection::Read(void* data, size_t length)
{
2017-07-17 17:28:54 +01:00
auto self = reinterpret_cast<BaseConnectionWin*>(this);
DWORD bytesAvailable = 0;
if (::PeekNamedPipe(self->pipe, nullptr, 0, nullptr, &bytesAvailable, nullptr)) {
if (bytesAvailable >= length) {
if (::ReadFile(self->pipe, data, length, nullptr, nullptr) == TRUE) {
return true;
}
}
}
return false;
}