diff --git a/Library/Litestep.cpp b/Library/Litestep.cpp index 0d4ffdc0..d2131612 100644 --- a/Library/Litestep.cpp +++ b/Library/Litestep.cpp @@ -29,8 +29,8 @@ static CRITICAL_SECTION g_CsLogDelay = {0}; void InitalizeLitestep() { - InitializeCriticalSection(&g_CsLog); - InitializeCriticalSection(&g_CsLogDelay); + CSystem::InitializeCriticalSection(&g_CsLog); + CSystem::InitializeCriticalSection(&g_CsLogDelay); } void FinalizeLitestep() diff --git a/Library/System.cpp b/Library/System.cpp index 40167146..9556ce70 100644 --- a/Library/System.cpp +++ b/Library/System.cpp @@ -51,8 +51,6 @@ HWINEVENTHOOK CSystem::c_WinEventHook = NULL; bool CSystem::c_ShowDesktop = false; -OSPLATFORM CSystem::c_Platform = OSPLATFORM_UNKNOWN; - std::wstring CSystem::c_WorkingDirectory; std::vector CSystem::c_IniFileMappings; @@ -102,8 +100,6 @@ void CSystem::Initialize(HINSTANCE instance) SetWindowPos(c_Window, HWND_BOTTOM, 0, 0, 0, 0, ZPOS_FLAGS); SetWindowPos(c_HelperWindow, HWND_BOTTOM, 0, 0, 0, 0, ZPOS_FLAGS); - SetOSPlatform(); - c_Monitors.monitors.reserve(4); SetMultiMonitorInfo(); @@ -548,32 +544,34 @@ void CSystem::UpdateWorkareaInfo() ** Sets the OS platform. ** */ -void CSystem::SetOSPlatform() +OSPLATFORM CSystem::InitOSPlatform() { OSVERSIONINFOEX osvi = {sizeof(OSVERSIONINFOEX)}; if (GetVersionEx((OSVERSIONINFO*)&osvi)) { - if (osvi.dwMajorVersion == 5) + switch (osvi.dwMajorVersion) { + case 5: // Not checking for osvi.dwMinorVersion >= 1 because Rainmeter won't run on pre-XP - c_Platform = OSPLATFORM_XP; - } - else if (osvi.dwMajorVersion == 6) - { - if (osvi.dwMinorVersion == 0) + return OSPLATFORM_XP; + + case 6: + switch (osvi.dwMinorVersion) { - c_Platform = OSPLATFORM_VISTA; // Vista, Server 2008 + case 0: + return OSPLATFORM_VISTA; // Vista, Server 2008 + + case 1: + return OSPLATFORM_7; // 7, Server 2008R2 + + default: + return OSPLATFORM_8; // 8, Server 2012 } - else - { - c_Platform = OSPLATFORM_7; // 7, Server 2008R2 - } - } - else // newer OS - { - c_Platform = OSPLATFORM_7; + break; } } + + return OSPLATFORM_8; // newer OS } /* @@ -1119,6 +1117,28 @@ void CSystem::ResetWorkingDirectory() } } +/* +** Initializes a critical section object by using InitializeCriticalSectionEx function with CRITICAL_SECTION_NO_DEBUG_INFO flag. +** For more details: http://stackoverflow.com/questions/804848/critical-sections-leaking-memory-on-vista-win2008/ +** +*/ +void CSystem::InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection) +{ + typedef BOOL (WINAPI * FPINITCRITEX)(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags); + static FPINITCRITEX InitializeCriticalSectionEx = (GetOSPlatform() >= OSPLATFORM_VISTA) ? + (FPINITCRITEX)GetProcAddress(GetModuleHandle(L"Kernel32"), "InitializeCriticalSectionEx") : nullptr; + + if (InitializeCriticalSectionEx) + { + if (InitializeCriticalSectionEx(lpCriticalSection, 0, CRITICAL_SECTION_NO_DEBUG_INFO)) + { + return; + } + } + + ::InitializeCriticalSectionAndSpinCount(lpCriticalSection, 0); +} + /* ** Sets clipboard text to given string. ** diff --git a/Library/System.h b/Library/System.h index f2783288..1dd14768 100644 --- a/Library/System.h +++ b/Library/System.h @@ -24,10 +24,10 @@ enum OSPLATFORM { - OSPLATFORM_UNKNOWN = 0, OSPLATFORM_XP, OSPLATFORM_VISTA, - OSPLATFORM_7 + OSPLATFORM_7, + OSPLATFORM_8 }; struct MonitorInfo @@ -67,7 +67,7 @@ public: static HWND GetHelperWindow() { return c_HelperWindow; } static void PrepareHelperWindow(HWND WorkerW = GetWorkerW()); - static OSPLATFORM GetOSPlatform() { return c_Platform; } + static OSPLATFORM GetOSPlatform() { static OSPLATFORM c_Platform = InitOSPlatform(); return c_Platform; } static ULONGLONG GetTickCount64(); static POINT GetCursorPosition(); @@ -79,6 +79,7 @@ public: static HMODULE RmLoadLibrary(LPCWSTR lpLibFileName, DWORD* dwError = NULL); static void ResetWorkingDirectory(); + static void InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection); static void SetClipboardText(const std::wstring& text); static void SetWallpaper(const std::wstring& wallpaper, const std::wstring& style); @@ -98,7 +99,7 @@ private: static void ClearMultiMonitorInfo() { c_Monitors.monitors.clear(); } static void UpdateWorkareaInfo(); - static void SetOSPlatform(); + static OSPLATFORM InitOSPlatform(); static HWND GetDefaultShellWindow(); static HWND GetWorkerW(); @@ -116,8 +117,6 @@ private: static bool c_ShowDesktop; - static OSPLATFORM c_Platform; - static std::wstring c_WorkingDirectory; static std::vector c_IniFileMappings;