-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathTelemetryEngine.cpp
More file actions
73 lines (61 loc) · 2.4 KB
/
Copy pathTelemetryEngine.cpp
File metadata and controls
73 lines (61 loc) · 2.4 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
#include "TelemetryEngine.h"
#include <iostream>
TelemetryEngine::TelemetryEngine(HANDLE hDevice, ITelemetryObserver* observer)
: m_hDevice(hDevice), m_Observer(observer), m_MappedAddress(NULL), m_RingBuffer(NULL), m_IsRunning(false) {
}
TelemetryEngine::~TelemetryEngine() {
Stop(); // Ensure thread is killed if object goes out of scope
}
bool TelemetryEngine::Start() {
DWORD bytesReturned = 0;
BOOL mapSuccess = DeviceIoControl(
m_hDevice, IOCTL_WZD_MAP_MEMORY,
NULL, 0, &m_MappedAddress, sizeof(PVOID),
&bytesReturned, NULL
);
if (!mapSuccess || m_MappedAddress == NULL) {
return false;
}
m_RingBuffer = static_cast<PWZD_RING_BUFFER>(m_MappedAddress);
m_IsRunning = true;
m_ConsumerThread = std::thread(&TelemetryEngine::ConsumerLoop, this);
return true;
}
void TelemetryEngine::Stop() {
if (m_IsRunning) {
m_IsRunning = false;
if (m_ConsumerThread.joinable()) {
m_ConsumerThread.join();
}
}
}
void TelemetryEngine::ConsumerLoop() {
while (m_IsRunning) {
LONG currentTail = m_RingBuffer->Tail;
LONG state = _InterlockedCompareExchange(&m_RingBuffer->SlotStates[currentTail], WZDRB_SlotFree, WZDRB_SlotFree);
if (state == WZDRB_SlotReady) {
// Deep copy the event payload
//WZD_PROCESS_EVENT localEvent = m_RingBuffer->Events[currentTail]; not safe due to potential padding bytes
WZD_PROCESS_EVENT localEvent = {}; // Zero-initialize to prevent uninitialized data issues
memcpy(&localEvent, (void*)&m_RingBuffer->Events[currentTail], sizeof(WZD_PROCESS_EVENT));
// Free the slot immediately for the kernel
_InterlockedExchange(&m_RingBuffer->SlotStates[currentTail], WZDRB_SlotFree);
_InterlockedExchange(&m_RingBuffer->Tail, (currentTail + 1) & WZD_EVENT_MASK);
// Notify the Observer! (No printing here)
if (m_Observer) {
m_Observer->OnProcessEvent(localEvent);
}
}
else {
Sleep(1);
}
// Check for dropped events
LONG dropped = _InterlockedCompareExchange(&m_RingBuffer->DroppedEventsCount, 0, 0);
if (dropped > 0) {
_InterlockedExchange(&m_RingBuffer->DroppedEventsCount, 0);
if (m_Observer) {
m_Observer->OnDroppedEvents(dropped);
}
}
}
}