-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbinding.cpp
More file actions
137 lines (115 loc) · 4.86 KB
/
Copy pathbinding.cpp
File metadata and controls
137 lines (115 loc) · 4.86 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
#include <napi.h>
#include <windows.h>
#include <string>
// WDA_EXCLUDEFROMCAPTURE is 0x00000011 (excludes the window from screen capture)
#ifndef WDA_EXCLUDEFROMCAPTURE
#define WDA_EXCLUDEFROMCAPTURE 0x00000011
#endif
Napi::Boolean EnforceDisplayAffinity(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
// 1. Argument Validation
if (info.Length() < 1) {
Napi::TypeError::New(env, "Argument expected: HWND Buffer").ThrowAsJavaScriptException();
return Napi::Boolean::New(env, false);
}
if (!info[0].IsBuffer()) {
Napi::TypeError::New(env, "Argument must be a Buffer").ThrowAsJavaScriptException();
return Napi::Boolean::New(env, false);
}
Napi::Buffer<char> buffer = info[0].As<Napi::Buffer<char>>();
char* data = buffer.Data();
size_t length = buffer.ByteLength();
// 2. Safe HWND Extraction
HWND hwnd = nullptr;
if (length == sizeof(HWND)) {
hwnd = *reinterpret_cast<HWND*>(data);
} else if (length == 8) {
hwnd = reinterpret_cast<HWND>(*reinterpret_cast<uint64_t*>(data));
} else if (length == 4) {
hwnd = reinterpret_cast<HWND>(static_cast<LONG_PTR>(*reinterpret_cast<uint32_t*>(data)));
} else {
Napi::Error::New(env, "Invalid buffer length for Win32 HWND").ThrowAsJavaScriptException();
return Napi::Boolean::New(env, false);
}
// 3. HWND Validity Verification
if (hwnd == nullptr || !IsWindow(hwnd)) {
Napi::Error::New(env, "Provided HWND is invalid or null").ThrowAsJavaScriptException();
return Napi::Boolean::New(env, false);
}
// 4. Invoke Win32 API to enforce screen share invisibility
SetLastError(ERROR_SUCCESS);
BOOL success = SetWindowDisplayAffinity(hwnd, WDA_EXCLUDEFROMCAPTURE);
// 5. Invoke Win32 API to enforce Task Manager Invisibility (Demotion to Background Process)
// We strip the standard Application flag and forcefully apply the Tool Window flag.
// This removes the app from the primary Task Manager "Apps" list and the Alt+Tab menu.
LONG_PTR exStyle = GetWindowLongPtrW(hwnd, GWL_EXSTYLE);
exStyle &= ~WS_EX_APPWINDOW;
exStyle |= WS_EX_TOOLWINDOW;
SetWindowLongPtrW(hwnd, GWL_EXSTYLE, exStyle);
if (!success) {
DWORD errorCode = GetLastError();
Napi::Error error = Napi::Error::New(
env,
"SetWindowDisplayAffinity failed with Win32 error " + std::to_string(errorCode)
);
error.Set("win32Error", Napi::Number::New(env, errorCode));
error.ThrowAsJavaScriptException();
return Napi::Boolean::New(env, false);
}
return Napi::Boolean::New(env, true);
}
Napi::Value GetDisplayAffinity(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
// 1. Argument Validation
if (info.Length() < 1) {
Napi::TypeError::New(env, "Argument expected: HWND Buffer").ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsBuffer()) {
Napi::TypeError::New(env, "Argument must be a Buffer").ThrowAsJavaScriptException();
return env.Null();
}
Napi::Buffer<char> buffer = info[0].As<Napi::Buffer<char>>();
char* data = buffer.Data();
size_t length = buffer.ByteLength();
// 2. Safe HWND Extraction
HWND hwnd = nullptr;
if (length == sizeof(HWND)) {
hwnd = *reinterpret_cast<HWND*>(data);
} else if (length == 8) {
hwnd = reinterpret_cast<HWND>(*reinterpret_cast<uint64_t*>(data));
} else if (length == 4) {
hwnd = reinterpret_cast<HWND>(static_cast<LONG_PTR>(*reinterpret_cast<uint32_t*>(data)));
} else {
Napi::Error::New(env, "Invalid buffer length for Win32 HWND").ThrowAsJavaScriptException();
return env.Null();
}
// 3. HWND Validity Verification
if (hwnd == nullptr || !IsWindow(hwnd)) {
Napi::Error::New(env, "Provided HWND is invalid or null").ThrowAsJavaScriptException();
return env.Null();
}
// 4. Call GetWindowDisplayAffinity
DWORD affinity = 0;
SetLastError(ERROR_SUCCESS);
BOOL success = GetWindowDisplayAffinity(hwnd, &affinity);
if (!success) {
DWORD errorCode = GetLastError();
Napi::Error error = Napi::Error::New(
env,
"GetWindowDisplayAffinity failed with Win32 error " + std::to_string(errorCode)
);
error.Set("win32Error", Napi::Number::New(env, errorCode));
error.ThrowAsJavaScriptException();
return env.Null();
}
return Napi::Number::New(env, affinity);
}
Napi::Object Init(Napi::Env env, Napi::Object exports) {
exports.Set(Napi::String::New(env, "EnforceDisplayAffinity"),
Napi::Function::New(env, EnforceDisplayAffinity));
exports.Set(Napi::String::New(env, "GetWindowDisplayAffinity"),
Napi::Function::New(env, GetDisplayAffinity));
return exports;
}
NODE_API_MODULE(display_affinity, Init)