-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIpc.cc
More file actions
157 lines (141 loc) · 3.88 KB
/
Ipc.cc
File metadata and controls
157 lines (141 loc) · 3.88 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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include <Ipc.hh>
/**
* @brief ctor Sets up the namedpipe
* @param pipe_name unicode string for the named pipe name
* @throws runtime error if namedpipe fails to create
*/
Ipc::Ipc(std::wstring pipe_name) : pipe_name_(std::move(pipe_name)) {
// @TODO add SD
pipe_handle_ = CreateNamedPipeW(pipe_name_.data(),
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
512,
512,
0,
nullptr);
if (pipe_handle_ == INVALID_HANDLE_VALUE) {
throw std::runtime_error("Ipc::Ipc: pipe creation failed");
}
}
/**
* @brief Cleans up on object destruction
*/
Ipc::~Ipc() {
if (pipe_handle_ != INVALID_HANDLE_VALUE) {
Stop();
CloseHandle(pipe_handle_);
}
}
/**
* @brief Starts listening on the named pipe.
*/
void Ipc::Listen()
{
while (is_running_) {
auto connected = ConnectNamedPipe(pipe_handle_, nullptr);
if ( connected || (GetLastError() == ERROR_PIPE_CONNECTED) )
{
HANDLE client_pipe = pipe_handle_;
try {
std::thread t(&Ipc::ClientHandler, client_pipe);
t.detach();//yolo
}catch (const std::exception& e) {
std::cerr << e.what() << std::endl;
}
//@TODO Fix permissions
pipe_handle_ = CreateNamedPipeW(pipe_name_.data(),
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
512,
512,
0,
nullptr);
if (pipe_handle_ == INVALID_HANDLE_VALUE) {
throw std::runtime_error("Ipc::Listen: pipe creation failed");
}
} else {
break;
}
}
}
/**
* @brief stops the IPC
*/
void Ipc::Stop()
{
is_running_ = false;
CancelIoEx(pipe_handle_, nullptr);
}
/**
* @brief Handles individually connected clients
* @param hPipe HANDLE to named pipe
*/
void Ipc::ClientHandler(const HANDLE hPipe) {
DWORD bytes_read = 0;
char buffer[sizeof(Message)];
while (true) {
bool success = ReadFile(hPipe, buffer, sizeof(buffer), &bytes_read, nullptr);
if (!success)
{
DWORD error = GetLastError();
if (error == ERROR_MORE_DATA) {
continue;
} else {
break;
}
}
if ( bytes_read > 0 && bytes_read >= sizeof(Message) ) {
const auto message = reinterpret_cast<Message*>(buffer);
ParseMessage(message);
}
}
DisconnectNamedPipe(hPipe);
CloseHandle(hPipe);
}
/**
* @brief Parses IPC response from Kernel event callbacks
* @param message Message type received from the kernel event.
*/
void Ipc::ParseMessage(const Message* message) {
auto& storage = Storage::GetInstance();
switch (message->tag) {
case Tag::ImageLoad: {
storage.InsertImageLoad(
message->image_load.process_id,
message->image_load.thread_id,
message->image_load.image_load
);
break;
}
case Tag::ProcessCreation: {
storage.InsertProcess(
message->creation.process_id,
LargeIntToTimeT(message->creation.creation_time)
);
break;
}
case Tag::ProcessExit: {
storage.RemoveProcess(message->exit.process_id);
break;
}
case Tag::ThreadExit: {
storage.RemoveThread(
message->thread_exit.process_id,
message->thread_exit.thread_id
);
break;
}
case Tag::ThreadCreation: {
storage.InsertThread(
message->thread_creation.process_id,
message->thread_creation.thread_id,
LargeIntToTimeT(message->thread_creation.creation_time)
);
break;
}
default:
break;
}
}