-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPipeserver.cpp
More file actions
70 lines (61 loc) · 2.26 KB
/
Pipeserver.cpp
File metadata and controls
70 lines (61 loc) · 2.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// PipeServer.cpp
// Administrates named pipes server for IPC communications.
#include "PipeServer.h" // relies on named pipes api through windows.h
PipeServer::PipeServer(const wchar_t *name) : _name(name) {} // Constructor
PipeServer::~PipeServer() { Close(); } // Destructor, calls Close()
// Check PipeServer.md for docs
bool PipeServer::CreateAndListen()
{
Close(); // close instance if already open
_hPipe = CreateNamedPipeW(
_name.c_str(),
PIPE_ACCESS_OUTBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
1, 1 << 16, 1 << 16, 0, nullptr);
if (_hPipe == INVALID_HANDLE_VALUE)
return false;
BOOL ok = ConnectNamedPipe(_hPipe, nullptr) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
return ok == TRUE;
}
// If no client is connected, wait for one.
// Allows for worker thread to ensure a connection is present before sending stuff.
bool PipeServer::EnsureClient()
{
if (_hPipe != INVALID_HANDLE_VALUE)
return true;
return CreateAndListen();
}
// Sends a length-prefixed JSON frame through the pipe.
bool PipeServer::SendFrame(const std::string &json)
{
// if no client, try to create and listen
if (_hPipe == INVALID_HANDLE_VALUE && !CreateAndListen())
return false;
DWORD len = static_cast<DWORD>(json.size()); // gets size of payload (DWORD type for this case)
// prevent giant payloads (over 8 MiB this case)
if (len > 8 * 1024 * 1024)
return false;
DWORD wrote = 0;
if (!WriteFile(_hPipe, &len, sizeof(len), &wrote, nullptr) || wrote != sizeof(len)) // write length prefix
{
Close(); // on failed write, close (and reset) pipe
return false;
}
if (!WriteFile(_hPipe, json.data(), len, &wrote, nullptr) || wrote != len) // write payload
{
Close(); // on failed write, close (and reset) pipe
return false;
}
return true;
}
// Ensures any open handle is properly closed
void PipeServer::Close()
{
if (_hPipe != INVALID_HANDLE_VALUE)
{
FlushFileBuffers(_hPipe);
DisconnectNamedPipe(_hPipe);
CloseHandle(_hPipe);
_hPipe = INVALID_HANDLE_VALUE;
}
}