1
+ #include " Utils.hpp"
2
+ #include " RegHelper.hpp"
3
+ #include " SystemHelper.hpp"
4
+ #include " ThemeHelper.hpp"
5
+ #include " Api.hpp"
6
+
7
+ using namespace TranslucentFlyouts ;
8
+
9
+ bool Api::IsServiceRunning (std::wstring_view serviceName)
10
+ {
11
+ return wil::unique_handle{ OpenFileMappingFromApp (FILE_MAP_READ, FALSE , serviceName.data ()) }.get () != nullptr ;
12
+ }
13
+
14
+ bool Api::IsHostProcess (std::wstring_view serviceName)
15
+ {
16
+ auto serviceInfo{ Api::GetServiceInfo (serviceName) };
17
+
18
+ DWORD processId{0 };
19
+ if (serviceInfo && GetWindowThreadProcessId (serviceInfo->hostWindow , &processId) && processId == GetCurrentProcessId ())
20
+ {
21
+ return true ;
22
+ }
23
+
24
+ return false ;
25
+ }
26
+
27
+ Api::unique_service_info Api::GetServiceInfo (std::wstring_view serviceName, bool readOnly)
28
+ {
29
+ wil::unique_handle fileMapping{ OpenFileMappingW (FILE_MAP_READ | (readOnly ? 0 : FILE_MAP_WRITE), FALSE , serviceName.data ())};
30
+ return unique_service_info{ reinterpret_cast <ServiceInfo*>(MapViewOfFileFromApp (fileMapping.get (), FILE_MAP_READ | (readOnly ? 0 : FILE_MAP_WRITE), 0 , 0 )) };
31
+ }
32
+ std::pair<wil::unique_handle, Api::unique_service_info> Api::CreateService (std::wstring_view serviceName)
33
+ {
34
+ wil::unique_handle fileMapping{ nullptr };
35
+ Api::unique_service_info serviceInfo{ nullptr };
36
+
37
+ fileMapping.reset (
38
+ CreateFileMappingFromApp (
39
+ INVALID_HANDLE_VALUE,
40
+ nullptr ,
41
+ PAGE_READWRITE | SEC_COMMIT,
42
+ sizeof (Api::ServiceInfo),
43
+ serviceName.data ()
44
+ )
45
+ );
46
+ if (!fileMapping)
47
+ {
48
+ return std::make_pair<wil::unique_handle, Api::unique_service_info>(std::move (fileMapping), std::move (serviceInfo));
49
+ }
50
+ serviceInfo.reset (
51
+ reinterpret_cast <Api::ServiceInfo*>(
52
+ MapViewOfFileFromApp (
53
+ fileMapping.get (),
54
+ FILE_MAP_READ | FILE_MAP_WRITE,
55
+ 0 ,
56
+ 0
57
+ )
58
+ )
59
+ );
60
+
61
+ return std::make_pair<wil::unique_handle, Api::unique_service_info>(std::move (fileMapping), std::move (serviceInfo));
62
+ }
63
+ bool Api::IsCurrentProcessInBlockList ()
64
+ {
65
+ using namespace std ::literals;
66
+ // TranslucentFlyouts won't be loaded into one of these process
67
+ // These processes are quite annoying because TranslucentFlyouts will not be automatically unloaded by them
68
+ // Some of them even have no chance to show flyouts and other UI elements
69
+ const std::array blockList
70
+ {
71
+ L" sihost.exe" sv,
72
+ L" WSHost.exe" sv,
73
+ L" spoolsv.exe" sv,
74
+ L" dllhost.exe" sv,
75
+ L" svchost.exe" sv,
76
+ L" taskhostw.exe" sv,
77
+ L" searchhost.exe" sv,
78
+ L" backgroundTaskHost.exe" sv,
79
+ L" RuntimeBroker.exe" sv,
80
+ L" smartscreen.exe" sv,
81
+ L" Widgets.exe" sv,
82
+ L" WidgetService.exe" sv,
83
+ L" GameBar.exe" sv,
84
+ L" GameBarFTServer.exe" sv,
85
+ L" ShellExperienceHost.exe" sv,
86
+ L" StartMenuExperienceHost.exe" sv,
87
+ L" WindowsPackageManagerServer.exe" sv,
88
+ L" msedgewebview2.exe" sv,
89
+ L" Microsoft.SharePoint.exe" sv,
90
+ L" PerfWatson2.exe" sv,
91
+ L" splwow64.exe" sv,
92
+ L" ServiceHub.VSDetouredHost.exe" sv,
93
+ L" CoreWidgetProvider.exe" sv
94
+ };
95
+ auto is_in_list = [](const auto list)
96
+ {
97
+ for (auto item : list)
98
+ {
99
+ if (GetModuleHandleW (item.data ()))
100
+ {
101
+ return true ;
102
+ }
103
+ }
104
+
105
+ return false ;
106
+ };
107
+
108
+ return is_in_list (blockList);
109
+ }
110
+
111
+ bool Api::InteractiveIO::OutputToConsole (
112
+ StringType strType,
113
+ WaitType waitType,
114
+ UINT strResourceId,
115
+ std::wstring_view prefixStr,
116
+ std::wstring_view additionalStr,
117
+ bool requireConsole
118
+ )
119
+ {
120
+ if (!requireConsole)
121
+ {
122
+ Startup ();
123
+ }
124
+ else if (!GetConsoleWindow ())
125
+ {
126
+ return false ;
127
+ }
128
+
129
+ static WCHAR str[32768 + 1 ]{};
130
+ LoadStringW (wil::GetModuleInstanceHandle (), strResourceId, str, 32768 );
131
+
132
+ switch (strType)
133
+ {
134
+ case StringType::Notification:
135
+ {
136
+ SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_INTENSITY);
137
+ break ;
138
+ }
139
+ case StringType::Warning:
140
+ {
141
+ SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
142
+ break ;
143
+ }
144
+ case StringType::Error:
145
+ {
146
+ SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_INTENSITY);
147
+ break ;
148
+ }
149
+ default :
150
+ break ;
151
+ }
152
+
153
+ auto outputString{std::format (L" {}{}{}" , prefixStr, str, additionalStr)};
154
+ std::wcout << outputString;
155
+ OutputDebugStringW (outputString.c_str ());
156
+
157
+ SetConsoleTextAttribute (GetStdHandle (STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY);
158
+
159
+ switch (waitType)
160
+ {
161
+ case WaitType::NoWait:
162
+ {
163
+ break ;
164
+ }
165
+ case WaitType::WaitYN:
166
+ {
167
+ char input{ };
168
+ do
169
+ {
170
+ input = getchar ();
171
+ if (input == ' Y' || input == ' y' )
172
+ {
173
+ return true ;
174
+ }
175
+ if (input == ' N' || input == ' n' )
176
+ {
177
+ return false ;
178
+ }
179
+ } while (true );
180
+ break ;
181
+ }
182
+ case WaitType::WaitAnyKey:
183
+ {
184
+ system (" pause>nul" );
185
+ break ;
186
+ }
187
+ default :
188
+ break ;
189
+ }
190
+
191
+ return true ;
192
+ }
193
+
194
+ void Api::InteractiveIO::Startup ()
195
+ {
196
+ if (GetConsoleWindow () || AttachConsole (ATTACH_PARENT_PROCESS) || AllocConsole ())
197
+ {
198
+ FILE* fpstdin{ stdin }, * fpstdout{ stdout }, * fpstderr{ stderr };
199
+ _wfreopen_s (&fpstdin, L" CONIN$" , L" r" , stdin);
200
+ _wfreopen_s (&fpstdout, L" CONOUT$" , L" w" , stdout);
201
+ _wfreopen_s (&fpstderr, L" CONOUT$" , L" w" , stderr);
202
+
203
+ std::ios_base::sync_with_stdio (false );
204
+ std::wcin.tie (0 );
205
+
206
+ std::wcout.imbue (std::locale (" chs" ));
207
+ }
208
+ }
209
+
210
+ void Api::InteractiveIO::Shutdown ()
211
+ {
212
+ if (GetConsoleWindow ())
213
+ {
214
+ fclose (stdin);
215
+ fclose (stdout);
216
+ fclose (stderr);
217
+
218
+ FreeConsole ();
219
+ }
220
+ }
221
+
222
+ bool Api::IsPartDisabled (std::wstring_view part)
223
+ {
224
+ return IsPartDisabledExternally (part) ||
225
+ RegHelper::Get<DWORD>(
226
+ { part, L" " },
227
+ L" Disabled" ,
228
+ 0 ,
229
+ 1
230
+ ) ||
231
+ RegHelper::Get<DWORD>({ L" DisabledList" , part }, Utils::get_process_name (), 0 , 1 );
232
+ }
233
+
234
+ bool Api::IsPartDisabledExternally (std::wstring_view part)
235
+ {
236
+ SYSTEM_POWER_STATUS powerStatus{};
237
+ return (
238
+ IsStartAllBackTakingOver (part) ||
239
+ GetSystemMetrics (SM_CLEANBOOT) ||
240
+ ThemeHelper::IsHighContrast () ||
241
+ (
242
+ GetSystemPowerStatus (&powerStatus) &&
243
+ powerStatus.SystemStatusFlag
244
+ )
245
+ );
246
+ }
247
+
248
+ bool Api::IsStartAllBackTakingOver (std::wstring_view part)
249
+ {
250
+ if (GetModuleHandleW (L" StartAllBackX64.dll" ))
251
+ {
252
+ if (!part.empty () || !_wcsicmp (part.data (), L" Menu" ))
253
+ {
254
+ auto immersiveMenus{ wil::reg::try_get_value_dword (HKEY_CURRENT_USER, L" SOFTWARE\\ StartIsBack" , L" ImmersiveMenus" ) };
255
+ if (immersiveMenus && immersiveMenus.value () == 0 )
256
+ {
257
+ return false ;
258
+ }
259
+ }
260
+ if (!part.empty () || !_wcsicmp (part.data (), L" Tooltip" ))
261
+ {
262
+ auto immersiveTooltips{ wil::reg::try_get_value_dword (HKEY_CURRENT_USER, L" SOFTWARE\\ StartIsBack" , L" NoDarkTooltips" ) };
263
+ if (immersiveTooltips && immersiveTooltips.value () == 0 )
264
+ {
265
+ return false ;
266
+ }
267
+ }
268
+
269
+ auto disabled{ wil::reg::try_get_value_dword (HKEY_CURRENT_USER, L" SOFTWARE\\ StartIsBack" , L" Disabled" ) };
270
+ if (disabled && disabled.value ())
271
+ {
272
+ return false ;
273
+ }
274
+
275
+ return true ;
276
+ }
277
+
278
+ return false ;
279
+ }
0 commit comments