|
1
|
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
|