diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/foosdk/sdk/foobar2000/helpers/win32_misc.cpp	Mon Jan 05 02:15:46 2026 -0500
@@ -0,0 +1,221 @@
+#include "StdAfx.h"
+#include "win32_misc.h"
+
+#ifdef FOOBAR2000_MOBILE_WINDOWS
+#include <pfc/pp-winapi.h>
+#endif
+
+#ifdef _WIN32
+
+#include <SDK/modeless_dialog.h>
+
+mutexScope::mutexScope(HANDLE hMutex_, abort_callback & abort) : hMutex(hMutex_) {
+	HANDLE h[2] = { hMutex, abort.get_abort_event() };
+	switch (WaitForMultipleObjectsEx(2, h, FALSE, INFINITE, FALSE)) {
+	case WAIT_OBJECT_0:
+		break; // and enter
+	case WAIT_OBJECT_0 + 1:
+		throw exception_aborted();
+	default:
+		uBugCheck();
+	}
+}
+mutexScope::~mutexScope() {
+	ReleaseMutex(hMutex);
+}
+
+CMutex::CMutex(const TCHAR * name) {
+	WIN32_OP_CRITICAL("CreateMutex", m_hMutex = CreateMutex(NULL, FALSE, name));
+}
+CMutex::~CMutex() {
+	CloseHandle(m_hMutex);
+}
+
+void CMutex::AcquireByHandle(HANDLE hMutex, abort_callback & aborter) {
+	SetLastError(0);
+	HANDLE hWait[2] = { hMutex, aborter.get_abort_event() };
+	switch (WaitForMultipleObjects(2, hWait, FALSE, INFINITE)) {
+	case WAIT_FAILED:
+		WIN32_OP_FAIL_CRITICAL("WaitForSingleObject");
+	case WAIT_OBJECT_0:
+		return;
+	case WAIT_OBJECT_0 + 1:
+		PFC_ASSERT(aborter.is_aborting());
+		throw exception_aborted();
+	default:
+		uBugCheck();
+	}
+}
+
+void CMutex::Acquire(abort_callback& aborter) {
+	AcquireByHandle(Handle(), aborter);
+}
+
+void CMutex::Release() {
+	ReleaseMutex(Handle());
+}
+
+
+CMutexScope::CMutexScope(CMutex & mutex, DWORD timeOutMS, const char * timeOutBugMsg) : m_mutex(mutex) {
+	SetLastError(0);
+	const unsigned div = 4;
+	for (unsigned walk = 0; walk < div; ++walk) {
+		switch (WaitForSingleObject(m_mutex.Handle(), timeOutMS / div)) {
+		case WAIT_FAILED:
+			WIN32_OP_FAIL_CRITICAL("WaitForSingleObject");
+		case WAIT_OBJECT_0:
+			return;
+		case WAIT_TIMEOUT:
+			break;
+		default:
+			uBugCheck();
+		}
+	}
+	TRACK_CODE(timeOutBugMsg, uBugCheck());
+}
+
+CMutexScope::CMutexScope(CMutex & mutex) : m_mutex(mutex) {
+	SetLastError(0);
+	switch (WaitForSingleObject(m_mutex.Handle(), INFINITE)) {
+	case WAIT_FAILED:
+		WIN32_OP_FAIL_CRITICAL("WaitForSingleObject");
+	case WAIT_OBJECT_0:
+		return;
+	default:
+		uBugCheck();
+	}
+}
+
+CMutexScope::CMutexScope(CMutex & mutex, abort_callback & aborter) : m_mutex(mutex) {
+	mutex.Acquire(aborter);
+}
+
+CMutexScope::~CMutexScope() {
+	ReleaseMutex(m_mutex.Handle());
+}
+
+#endif
+
+#ifdef FOOBAR2000_DESKTOP_WINDOWS
+
+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) {
+	toggle_off();
+	WNDCLASS wc = {};
+	wc.style = p_style;
+	wc.lpfnWndProc = p_wndproc;
+	wc.cbClsExtra = p_clsextra;
+	wc.cbWndExtra = p_wndextra;
+	wc.hInstance = core_api::get_my_instance();
+	wc.hIcon = p_icon;
+	wc.hCursor = p_cursor;
+	wc.hbrBackground = p_background;
+	wc.lpszMenuName = p_menu_name;
+	wc.lpszClassName = p_class_name;
+	WIN32_OP_CRITICAL("RegisterClass", (m_class = RegisterClass(&wc)) != 0);
+}
+
+void registerclass_scope_delayed::toggle_off() {
+	if (m_class != 0) {
+		UnregisterClass((LPCTSTR)m_class,core_api::get_my_instance());
+		m_class = 0;
+	}
+}
+
+void CModelessDialogEntry::Set(HWND p_new) {
+	auto api = modeless_dialog_manager::get();
+	if (m_wnd) api->remove(m_wnd);
+	m_wnd = p_new;
+	if (m_wnd) api->add(m_wnd);
+}
+
+OleInitializeScope::OleInitializeScope() {
+	if (FAILED(OleInitialize(NULL))) throw pfc::exception("OleInitialize() failure");
+}
+OleInitializeScope::~OleInitializeScope() {
+	OleUninitialize();
+}
+
+CoInitializeScope::CoInitializeScope() {
+	if (FAILED(CoInitialize(NULL))) throw pfc::exception("CoInitialize() failed");
+}
+CoInitializeScope::CoInitializeScope(DWORD params) {
+	if (FAILED(CoInitializeEx(NULL, params))) throw pfc::exception("CoInitialize() failed");
+}
+CoInitializeScope::~CoInitializeScope() {
+	CoUninitialize();
+}
+
+void winLocalFileScope::open(const char * inPath, file::ptr inReader, abort_callback & aborter) {
+	close();
+	if (inPath != nullptr) {
+		if (_extract_native_path_ptr(inPath)) {
+			pfc::string8 prefixed;
+			pfc::winPrefixPath(prefixed, inPath);
+			m_path = pfc::stringcvt::string_wide_from_utf8(prefixed);
+			m_isTemp = false;
+			return;
+		}
+	}
+
+	pfc::string8 tempPath; tempPath.prealloc(1024);
+	if (!uGetTempPath(tempPath)) uBugCheck();
+	tempPath.add_filename(PFC_string_formatter() << pfc::print_guid(pfc::createGUID()) );
+	if ( inPath != nullptr ) {
+		auto ext = pfc::string_extension(inPath);
+		if (ext.length() > 0) tempPath << "." << ext;
+	}
+
+	m_path = pfc::stringcvt::string_wide_from_utf8(tempPath);
+
+	if (inReader.is_empty()) {
+		if (inPath == NULL) uBugCheck();
+		inReader = fileOpenReadExisting(inPath, aborter, 1.0);
+	}
+
+	file::ptr writer = fileOpenWriteNew(PFC_string_formatter() << "file://" << tempPath, aborter, 1.0);
+	file::g_transfer_file(inReader, writer, aborter);
+	m_isTemp = true;
+}
+void winLocalFileScope::close() {
+	if (m_isTemp && m_path.length() > 0) {
+		pfc::lores_timer timer;
+		timer.start();
+		for (;;) {
+			if (DeleteFile(m_path.c_str())) break;
+			if (timer.query() > 1.0) break;
+			Sleep(10);
+		}
+	}
+	m_path.clear();
+}
+
+bool IsWindowsS() {
+	bool ret = false;
+#if FB2K_TARGET_MICROSOFT_STORE
+	static bool cached = false;
+	static bool inited = false;
+	if ( inited ) {
+		ret = cached;
+	} else {
+		HKEY key;
+		if (RegOpenKey(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\CI\\Policy", &key) == 0) {
+			DWORD dwVal = 0, dwType;
+			DWORD valSize;
+			valSize = sizeof(dwVal);
+			if (RegQueryValueEx(key, L"SkuPolicyRequired", nullptr, &dwType, (LPBYTE)&dwVal, &valSize) == 0) {
+				if (dwType == REG_DWORD && dwVal != 0) ret = true;
+			}
+			RegCloseKey(key);
+		}
+		cached = ret;
+		inited = true;
+	}
+#endif
+	return ret;
+}
+
+WORD GetOSVersion() {
+	// wrap libPPUI function
+	return ::GetOSVersionCode();
+}
+#endif // FOOBAR2000_DESKTOP_WINDOWS