comparison foosdk/sdk/foobar2000/helpers/win32_misc.cpp @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
comparison
equal deleted inserted replaced
0:e9bb126753e7 1:20d02a178406
1 #include "StdAfx.h"
2 #include "win32_misc.h"
3
4 #ifdef FOOBAR2000_MOBILE_WINDOWS
5 #include <pfc/pp-winapi.h>
6 #endif
7
8 #ifdef _WIN32
9
10 #include <SDK/modeless_dialog.h>
11
12 mutexScope::mutexScope(HANDLE hMutex_, abort_callback & abort) : hMutex(hMutex_) {
13 HANDLE h[2] = { hMutex, abort.get_abort_event() };
14 switch (WaitForMultipleObjectsEx(2, h, FALSE, INFINITE, FALSE)) {
15 case WAIT_OBJECT_0:
16 break; // and enter
17 case WAIT_OBJECT_0 + 1:
18 throw exception_aborted();
19 default:
20 uBugCheck();
21 }
22 }
23 mutexScope::~mutexScope() {
24 ReleaseMutex(hMutex);
25 }
26
27 CMutex::CMutex(const TCHAR * name) {
28 WIN32_OP_CRITICAL("CreateMutex", m_hMutex = CreateMutex(NULL, FALSE, name));
29 }
30 CMutex::~CMutex() {
31 CloseHandle(m_hMutex);
32 }
33
34 void CMutex::AcquireByHandle(HANDLE hMutex, abort_callback & aborter) {
35 SetLastError(0);
36 HANDLE hWait[2] = { hMutex, aborter.get_abort_event() };
37 switch (WaitForMultipleObjects(2, hWait, FALSE, INFINITE)) {
38 case WAIT_FAILED:
39 WIN32_OP_FAIL_CRITICAL("WaitForSingleObject");
40 case WAIT_OBJECT_0:
41 return;
42 case WAIT_OBJECT_0 + 1:
43 PFC_ASSERT(aborter.is_aborting());
44 throw exception_aborted();
45 default:
46 uBugCheck();
47 }
48 }
49
50 void CMutex::Acquire(abort_callback& aborter) {
51 AcquireByHandle(Handle(), aborter);
52 }
53
54 void CMutex::Release() {
55 ReleaseMutex(Handle());
56 }
57
58
59 CMutexScope::CMutexScope(CMutex & mutex, DWORD timeOutMS, const char * timeOutBugMsg) : m_mutex(mutex) {
60 SetLastError(0);
61 const unsigned div = 4;
62 for (unsigned walk = 0; walk < div; ++walk) {
63 switch (WaitForSingleObject(m_mutex.Handle(), timeOutMS / div)) {
64 case WAIT_FAILED:
65 WIN32_OP_FAIL_CRITICAL("WaitForSingleObject");
66 case WAIT_OBJECT_0:
67 return;
68 case WAIT_TIMEOUT:
69 break;
70 default:
71 uBugCheck();
72 }
73 }
74 TRACK_CODE(timeOutBugMsg, uBugCheck());
75 }
76
77 CMutexScope::CMutexScope(CMutex & mutex) : m_mutex(mutex) {
78 SetLastError(0);
79 switch (WaitForSingleObject(m_mutex.Handle(), INFINITE)) {
80 case WAIT_FAILED:
81 WIN32_OP_FAIL_CRITICAL("WaitForSingleObject");
82 case WAIT_OBJECT_0:
83 return;
84 default:
85 uBugCheck();
86 }
87 }
88
89 CMutexScope::CMutexScope(CMutex & mutex, abort_callback & aborter) : m_mutex(mutex) {
90 mutex.Acquire(aborter);
91 }
92
93 CMutexScope::~CMutexScope() {
94 ReleaseMutex(m_mutex.Handle());
95 }
96
97 #endif
98
99 #ifdef FOOBAR2000_DESKTOP_WINDOWS
100
101 void registerclass_scope_delayed::toggle_on(UINT p_style,WNDPROC p_wndproc,int p_clsextra,int p_wndextra,HICON p_icon,HCURSOR p_cursor,HBRUSH p_background,const TCHAR * p_class_name,const TCHAR * p_menu_name) {
102 toggle_off();
103 WNDCLASS wc = {};
104 wc.style = p_style;
105 wc.lpfnWndProc = p_wndproc;
106 wc.cbClsExtra = p_clsextra;
107 wc.cbWndExtra = p_wndextra;
108 wc.hInstance = core_api::get_my_instance();
109 wc.hIcon = p_icon;
110 wc.hCursor = p_cursor;
111 wc.hbrBackground = p_background;
112 wc.lpszMenuName = p_menu_name;
113 wc.lpszClassName = p_class_name;
114 WIN32_OP_CRITICAL("RegisterClass", (m_class = RegisterClass(&wc)) != 0);
115 }
116
117 void registerclass_scope_delayed::toggle_off() {
118 if (m_class != 0) {
119 UnregisterClass((LPCTSTR)m_class,core_api::get_my_instance());
120 m_class = 0;
121 }
122 }
123
124 void CModelessDialogEntry::Set(HWND p_new) {
125 auto api = modeless_dialog_manager::get();
126 if (m_wnd) api->remove(m_wnd);
127 m_wnd = p_new;
128 if (m_wnd) api->add(m_wnd);
129 }
130
131 OleInitializeScope::OleInitializeScope() {
132 if (FAILED(OleInitialize(NULL))) throw pfc::exception("OleInitialize() failure");
133 }
134 OleInitializeScope::~OleInitializeScope() {
135 OleUninitialize();
136 }
137
138 CoInitializeScope::CoInitializeScope() {
139 if (FAILED(CoInitialize(NULL))) throw pfc::exception("CoInitialize() failed");
140 }
141 CoInitializeScope::CoInitializeScope(DWORD params) {
142 if (FAILED(CoInitializeEx(NULL, params))) throw pfc::exception("CoInitialize() failed");
143 }
144 CoInitializeScope::~CoInitializeScope() {
145 CoUninitialize();
146 }
147
148 void winLocalFileScope::open(const char * inPath, file::ptr inReader, abort_callback & aborter) {
149 close();
150 if (inPath != nullptr) {
151 if (_extract_native_path_ptr(inPath)) {
152 pfc::string8 prefixed;
153 pfc::winPrefixPath(prefixed, inPath);
154 m_path = pfc::stringcvt::string_wide_from_utf8(prefixed);
155 m_isTemp = false;
156 return;
157 }
158 }
159
160 pfc::string8 tempPath; tempPath.prealloc(1024);
161 if (!uGetTempPath(tempPath)) uBugCheck();
162 tempPath.add_filename(PFC_string_formatter() << pfc::print_guid(pfc::createGUID()) );
163 if ( inPath != nullptr ) {
164 auto ext = pfc::string_extension(inPath);
165 if (ext.length() > 0) tempPath << "." << ext;
166 }
167
168 m_path = pfc::stringcvt::string_wide_from_utf8(tempPath);
169
170 if (inReader.is_empty()) {
171 if (inPath == NULL) uBugCheck();
172 inReader = fileOpenReadExisting(inPath, aborter, 1.0);
173 }
174
175 file::ptr writer = fileOpenWriteNew(PFC_string_formatter() << "file://" << tempPath, aborter, 1.0);
176 file::g_transfer_file(inReader, writer, aborter);
177 m_isTemp = true;
178 }
179 void winLocalFileScope::close() {
180 if (m_isTemp && m_path.length() > 0) {
181 pfc::lores_timer timer;
182 timer.start();
183 for (;;) {
184 if (DeleteFile(m_path.c_str())) break;
185 if (timer.query() > 1.0) break;
186 Sleep(10);
187 }
188 }
189 m_path.clear();
190 }
191
192 bool IsWindowsS() {
193 bool ret = false;
194 #if FB2K_TARGET_MICROSOFT_STORE
195 static bool cached = false;
196 static bool inited = false;
197 if ( inited ) {
198 ret = cached;
199 } else {
200 HKEY key;
201 if (RegOpenKey(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\CI\\Policy", &key) == 0) {
202 DWORD dwVal = 0, dwType;
203 DWORD valSize;
204 valSize = sizeof(dwVal);
205 if (RegQueryValueEx(key, L"SkuPolicyRequired", nullptr, &dwType, (LPBYTE)&dwVal, &valSize) == 0) {
206 if (dwType == REG_DWORD && dwVal != 0) ret = true;
207 }
208 RegCloseKey(key);
209 }
210 cached = ret;
211 inited = true;
212 }
213 #endif
214 return ret;
215 }
216
217 WORD GetOSVersion() {
218 // wrap libPPUI function
219 return ::GetOSVersionCode();
220 }
221 #endif // FOOBAR2000_DESKTOP_WINDOWS