From 3da0aa3f4c16412afc71b8d6b312526a1264cab3 Mon Sep 17 00:00:00 2001 From: spx Date: Sat, 11 Sep 2010 19:39:45 +0000 Subject: [PATCH] [Application] - Added some codes to avoid loading a dll from current directory. [Library] - Added new functions to avoid loading a dll from current directory. (CSystem::RmSetDllDirectory(), CSystem::RmLoadLibrary()) --- Application/Application.cpp | 34 +++++++- Library/AboutDialog.cpp | 9 +- Library/Litestep.cpp | 3 +- Library/MeasureCPU.cpp | 3 +- Library/MeasureNet.cpp | 5 +- Library/MeasurePlugin.cpp | 18 ++-- Library/MeterWindow.cpp | 28 +++--- Library/Rainmeter.cpp | 35 +------- Library/Rainmeter.h | 9 -- Library/System.cpp | 166 ++++++++++++++++++++++++++++++++++-- Library/System.h | 24 ++++++ 11 files changed, 252 insertions(+), 82 deletions(-) diff --git a/Application/Application.cpp b/Application/Application.cpp index 2a5a6e65..2e64732f 100644 --- a/Application/Application.cpp +++ b/Application/Application.cpp @@ -43,6 +43,7 @@ BOOL InitApplication(HINSTANCE hInstance, const WCHAR* WinClass); HWND InitInstance(HINSTANCE hInstance, const WCHAR* WinClass, const WCHAR* WinName); LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); void Bang(const WCHAR* command); +HMODULE RmLoadSystemLibrary(LPCWSTR lpLibFileName); BOOL IsRunning(HANDLE* hMutex); /* @@ -72,6 +73,14 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmd _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); // _CrtSetBreakAlloc(5055); + // Avoid loading a dll from current directory + typedef BOOL (WINAPI *FPSETDLLDIRECTORYW)(LPCWSTR lpPathName); + FPSETDLLDIRECTORYW SetDllDirectoryW = (FPSETDLLDIRECTORYW)GetProcAddress(GetModuleHandle(L"Kernel32.dll"), "SetDllDirectoryW"); + if (SetDllDirectoryW) + { + SetDllDirectoryW(L""); + } + if (lpCmdLine && lpCmdLine[0] == L'!') { // It's a !bang @@ -218,6 +227,29 @@ void Bang(const WCHAR* command) } } +/* +** RmLoadSystemLibrary +** +** Loads a system dll from system32 directory. +** +*/ +HMODULE RmLoadSystemLibrary(LPCWSTR lpLibFileName) +{ + WCHAR buffer[MAX_PATH]; + std::wstring path; + + if (GetSystemDirectory(buffer, MAX_PATH)) + { + path = buffer; + path += L"\\"; + path += lpLibFileName; + + return LoadLibrary(path.c_str()); + } + + return NULL; +} + /* ** IsRunning ** @@ -239,7 +271,7 @@ BOOL IsRunning(HANDLE* hMutex) typedef void (WINAPI *FPMD5FINAL)(MD5_CTX *context); // Create MD5 digest from command line - HMODULE hCryptDll = LoadLibrary(L"cryptdll.dll"); + HMODULE hCryptDll = RmLoadSystemLibrary(L"cryptdll.dll"); if (!hCryptDll) // Unable to check the mutex { *hMutex = NULL; diff --git a/Library/AboutDialog.cpp b/Library/AboutDialog.cpp index 25a1c7f4..dd9a574e 100644 --- a/Library/AboutDialog.cpp +++ b/Library/AboutDialog.cpp @@ -18,6 +18,7 @@ #include "StdAfx.h" #include "Rainmeter.h" +#include "System.h" #include "MeterWindow.h" #include "Measure.h" #include "resource.h" @@ -360,12 +361,8 @@ void ScanPlugins() // Try to get the version and author std::wstring tmpSz = Rainmeter->GetPluginPath() + fileData.cFileName; - UINT oldMode = SetErrorMode(0); - SetErrorMode(oldMode | SEM_FAILCRITICALERRORS); // Prevent the system from displaying message box - SetLastError(ERROR_SUCCESS); - HMODULE dll = LoadLibrary(tmpSz.c_str()); - DWORD err = GetLastError(); - SetErrorMode(oldMode); // Reset + DWORD err = 0; + HMODULE dll = CSystem::RmLoadLibrary(tmpSz.c_str(), &err, true); if (dll) { GETPLUGINAUTHOR GetAuthorFunc = (GETPLUGINAUTHOR)GetProcAddress(dll, "GetPluginAuthor"); diff --git a/Library/Litestep.cpp b/Library/Litestep.cpp index 4663c669..eabe500c 100644 --- a/Library/Litestep.cpp +++ b/Library/Litestep.cpp @@ -20,6 +20,7 @@ #include "Litestep.h" #include "Error.h" #include "Rainmeter.h" +#include "System.h" #include #include #include @@ -67,7 +68,7 @@ void ResetLoggingFlag() void InitalizeLitestep() { // Use lsapi's methods instead of the stubs - HINSTANCE h = LoadLibrary(L"lsapi.dll"); + HINSTANCE h = CSystem::RmLoadLibrary(L"lsapi.dll"); if (h != NULL) { fpAddBangCommand = (FPADDBANGCOMMAND)GetProcAddress(h, "AddBangCommand"); diff --git a/Library/MeasureCPU.cpp b/Library/MeasureCPU.cpp index 810f693d..0530ec2b 100644 --- a/Library/MeasureCPU.cpp +++ b/Library/MeasureCPU.cpp @@ -19,6 +19,7 @@ #include "StdAfx.h" #include "MeasureCPU.h" #include "Rainmeter.h" +#include "System.h" #include "Error.h" #define STATUS_SUCCESS 0 @@ -148,7 +149,7 @@ bool CMeasureCPU::Update() { if (!CMeasure::PreUpdate()) return false; - if (CRainmeter::IsNT() != PLATFORM_9X) + if (CSystem::IsNT()) { if (m_Processor == 0 && m_GetSystemTimes) { diff --git a/Library/MeasureNet.cpp b/Library/MeasureNet.cpp index 8e2fab04..0fe9cd72 100644 --- a/Library/MeasureNet.cpp +++ b/Library/MeasureNet.cpp @@ -19,6 +19,7 @@ #include "StdAfx.h" #include "MeasureNet.h" #include "Rainmeter.h" +#include "System.h" BYTE* CMeasureNet::c_Table = NULL; UINT CMeasureNet::c_NumOfTables = 0; @@ -662,7 +663,7 @@ void CMeasureNet::InitializeNewApi() { if (c_IpHlpApiLibrary == NULL) { - c_IpHlpApiLibrary = LoadLibrary(L"IpHlpApi.dll"); + c_IpHlpApiLibrary = GetModuleHandle(L"IpHlpApi.dll"); if (c_IpHlpApiLibrary) { c_GetIfTable2Ex = (FPGETIFTABLE2EX)GetProcAddress(c_IpHlpApiLibrary, "GetIfTable2Ex"); @@ -675,7 +676,6 @@ void CMeasureNet::InitializeNewApi() { if (c_IpHlpApiLibrary) { - FreeLibrary(c_IpHlpApiLibrary); c_IpHlpApiLibrary = NULL; } c_GetIfTable2Ex = NULL; @@ -701,7 +701,6 @@ void CMeasureNet::FinalizeNewApi() { c_FreeMibTable(c_Table); - FreeLibrary(c_IpHlpApiLibrary); c_IpHlpApiLibrary = NULL; c_GetIfTable2Ex = NULL; c_FreeMibTable = NULL; diff --git a/Library/MeasurePlugin.cpp b/Library/MeasurePlugin.cpp index bba9c878..39c06be9 100644 --- a/Library/MeasurePlugin.cpp +++ b/Library/MeasurePlugin.cpp @@ -19,6 +19,7 @@ #include "StdAfx.h" #include "MeasurePlugin.h" #include "Rainmeter.h" +#include "System.h" #include "Error.h" extern CRainmeter* Rainmeter; @@ -71,7 +72,7 @@ bool CMeasurePlugin::Update() WCHAR buffer[MAX_PATH]; GetCurrentDirectory(MAX_PATH, buffer); - SetCurrentDirectory(m_MeterWindow->MakePathAbsolute(L"").c_str()); + SetCurrentDirectory((Rainmeter->GetSkinPath() + m_MeterWindow->GetSkinName()).c_str()); if(UpdateFunc) { @@ -120,14 +121,13 @@ void CMeasurePlugin::ReadConfig(CConfigParser& parser, const WCHAR* section) } m_PluginName = Rainmeter->GetPluginPath() + m_PluginName; - SetLastError(ERROR_SUCCESS); - m_Plugin = LoadLibrary(m_PluginName.c_str()); + DWORD err = 0; + m_Plugin = CSystem::RmLoadLibrary(m_PluginName.c_str(), &err); if(m_Plugin == NULL) { if (CRainmeter::GetDebug()) { - DWORD err = GetLastError(); DebugLog(L"Plugin: Unable to load plugin: \"%s\", ErrorCode=%i", m_PluginName.c_str(), err); } @@ -137,14 +137,13 @@ void CMeasurePlugin::ReadConfig(CConfigParser& parser, const WCHAR* section) { std::wstring pluginName = Rainmeter->GetPath() + m_PluginName.substr(pos + 1); - SetLastError(ERROR_SUCCESS); - m_Plugin = LoadLibrary(pluginName.c_str()); + err = 0; + m_Plugin = CSystem::RmLoadLibrary(pluginName.c_str(), &err); if (m_Plugin == NULL) { if (CRainmeter::GetDebug()) { - DWORD err = GetLastError(); DebugLog(L"Plugin: Unable to load plugin: \"%s\", ErrorCode=%i", pluginName.c_str(), err); } } @@ -176,7 +175,10 @@ void CMeasurePlugin::ReadConfig(CConfigParser& parser, const WCHAR* section) WCHAR buffer[MAX_PATH]; GetCurrentDirectory(MAX_PATH, buffer); - SetCurrentDirectory(m_MeterWindow->MakePathAbsolute(L"").c_str()); + SetCurrentDirectory((Rainmeter->GetSkinPath() + m_MeterWindow->GetSkinName()).c_str()); + + // Remove current directory from DLL search path + CSystem::RmSetDllDirectory(L""); double maxValue; maxValue = InitializeFunc(m_Plugin, parser.GetFilename().c_str(), section, m_ID); diff --git a/Library/MeterWindow.cpp b/Library/MeterWindow.cpp index 995c83d5..502e01bf 100644 --- a/Library/MeterWindow.cpp +++ b/Library/MeterWindow.cpp @@ -130,7 +130,7 @@ CMeterWindow::CMeterWindow(std::wstring& path, std::wstring& config, std::wstrin m_SkinName = config; m_SkinIniFile = iniFile; - m_User32Library = LoadLibrary(L"user32.dll"); + m_User32Library = GetModuleHandle(L"user32.dll"); m_UpdateCounter = 0; m_FontCollection = NULL; @@ -175,8 +175,6 @@ CMeterWindow::~CMeterWindow() if(m_FontCollection) delete m_FontCollection; - FreeLibrary(m_User32Library); - --c_InstanceCount; if (c_InstanceCount == 0) @@ -281,16 +279,20 @@ void CMeterWindow::IgnoreAeroPeek() { typedef HRESULT (WINAPI * FPDWMSETWINDOWATTRIBUTE)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute); #define DWMWA_EXCLUDED_FROM_PEEK 12 - HINSTANCE h = LoadLibrary(L"dwmapi.dll"); - if (h) + + if (CSystem::GetOSPlatform() >= OSPLATFORM_VISTA) { - FPDWMSETWINDOWATTRIBUTE DwmSetWindowAttribute = (FPDWMSETWINDOWATTRIBUTE)GetProcAddress(h, "DwmSetWindowAttribute"); - if (DwmSetWindowAttribute) + HINSTANCE h = CSystem::RmLoadLibrary(L"dwmapi.dll"); + if (h) { - BOOL bValue = TRUE; - DwmSetWindowAttribute(m_Window, DWMWA_EXCLUDED_FROM_PEEK, &bValue, sizeof(bValue)); + FPDWMSETWINDOWATTRIBUTE DwmSetWindowAttribute = (FPDWMSETWINDOWATTRIBUTE)GetProcAddress(h, "DwmSetWindowAttribute"); + if (DwmSetWindowAttribute) + { + BOOL bValue = TRUE; + DwmSetWindowAttribute(m_Window, DWMWA_EXCLUDED_FROM_PEEK, &bValue, sizeof(bValue)); + } + FreeLibrary(h); } - FreeLibrary(h); } } @@ -1662,8 +1664,8 @@ void CMeterWindow::ReadConfig() section = m_SkinName.c_str(); } - // Disable native transparency if not 2K/XP - if(CRainmeter::IsNT() == PLATFORM_9X || CRainmeter::IsNT() == PLATFORM_NT4) + // Disable native transparency if older OS + if (CSystem::GetOSPlatform() < OSPLATFORM_2K) { m_NativeTransparency = 0; } @@ -4558,7 +4560,7 @@ LRESULT CMeterWindow::OnCopyData(UINT uMsg, WPARAM wParam, LPARAM lParam) /* ** MakePathAbsolute ** -** Converts the path to absolute bu adding the skin's path to it (unless it already is absolute). +** Converts the path to absolute by adding the skin's path to it (unless it already is absolute). ** */ std::wstring CMeterWindow::MakePathAbsolute(std::wstring path) diff --git a/Library/Rainmeter.cpp b/Library/Rainmeter.cpp index 76f4653d..c92c1899 100644 --- a/Library/Rainmeter.cpp +++ b/Library/Rainmeter.cpp @@ -1300,11 +1300,12 @@ int CRainmeter::Initialize(HWND Parent, HINSTANCE Instance, LPCSTR szPath) tmpName[0] = L'\0'; } + m_Path = tmpName; + if(!c_DummyLitestep) InitalizeLitestep(); bool bDefaultIniLocation = false; - m_Path = tmpName; if (c_CmdLine.empty()) { m_IniFile = m_Path + L"Rainmeter.ini"; @@ -3187,38 +3188,6 @@ void CRainmeter::ResetStats() CMeasureNet::ResetStats(); } - -/* -** IsNT -** -** Checks which OS you are running -** -*/ -PLATFORM CRainmeter::IsNT() -{ - // Check if you are running a real OS - - OSVERSIONINFO osvi; - ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - - if(!GetVersionEx((OSVERSIONINFO*)&osvi)) - { - // Something's wrong, lets assime Win9x - return PLATFORM_9X; - } - - if(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) - { - // You got NT - if(osvi.dwMajorVersion <= 4) return PLATFORM_NT4; - if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) return PLATFORM_2K; - return PLATFORM_XP; - } - - return PLATFORM_9X; // Wintendo alert! -} - /* ** ShowContextMenu ** diff --git a/Library/Rainmeter.h b/Library/Rainmeter.h index 612c0dff..13832e66 100644 --- a/Library/Rainmeter.h +++ b/Library/Rainmeter.h @@ -40,14 +40,6 @@ #endif #define RAINMETER_VERSION MAKE_VER(1, 3, 0) -enum PLATFORM -{ - PLATFORM_9X, - PLATFORM_NT4, - PLATFORM_2K, - PLATFORM_XP -}; - void RainmeterRefresh(HWND, const char* arg); void RainmeterRefreshApp(HWND, const char* arg); void RainmeterRedraw(HWND, const char* arg); @@ -226,7 +218,6 @@ public: void ClearDeleteLaterList(); static std::vector ParseString(LPCTSTR str); - static PLATFORM IsNT(); static std::wstring ExtractPath(const std::wstring& strFilePath); static void ExpandEnvironmentVariables(std::wstring& strPath); diff --git a/Library/System.cpp b/Library/System.cpp index 008f9109..ee2c9736 100644 --- a/Library/System.cpp +++ b/Library/System.cpp @@ -51,6 +51,10 @@ HWINEVENTHOOK CSystem::c_WinEventHook = NULL; bool CSystem::c_DwmCompositionEnabled = false; bool CSystem::c_ShowDesktop = false; +OSPLATFORM CSystem::c_Platform = OSPLATFORM_UNKNOWN; + +FPSETDLLDIRECTORYW CSystem::c_SetDllDirectoryW = NULL; + extern CRainmeter* Rainmeter; /* @@ -974,6 +978,150 @@ LRESULT CALLBACK CSystem::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lP return DefWindowProc(hWnd, uMsg, wParam, lParam); } +/* +** GetOSPlatform +** +** Checks which OS you are running. +** +*/ +OSPLATFORM CSystem::GetOSPlatform() +{ + if (c_Platform == OSPLATFORM_UNKNOWN) + { + OSVERSIONINFOEX osvi = {sizeof(OSVERSIONINFOEX)}; + if (!GetVersionEx((OSVERSIONINFO*)&osvi) || osvi.dwPlatformId != VER_PLATFORM_WIN32_NT) + { + c_Platform = OSPLATFORM_9X; + } + else + { + if (osvi.dwMajorVersion <= 4) // NT4 or older + { + c_Platform = OSPLATFORM_NT4; + } + else if (osvi.dwMajorVersion == 5) // 2000 / XP (x64 / Server 2003, R2) + { + if (osvi.dwMinorVersion == 0) + { + c_Platform = OSPLATFORM_2K; + } + else if (osvi.dwMinorVersion == 1 && osvi.wServicePackMajor == 0) + { + c_Platform = OSPLATFORM_XP; + } + else + { + c_Platform = OSPLATFORM_XP_SP1; + } + } + else if (osvi.dwMajorVersion == 6) // Vista (Server 2008) / 7 (Server 2008R2) + { + if (osvi.dwMinorVersion == 0) + { + c_Platform = OSPLATFORM_VISTA; + } + else + { + c_Platform = OSPLATFORM_7; + } + } + else // newer OS + { + c_Platform = OSPLATFORM_7; + } + } + } + + return c_Platform; +} + +/* +** RmSetDllDirectory +** +** This function is a wrapper function for SetDllDirectory() that is enabled on Windows XP sp1 or newer. +** +** Adds a directory to the search path used to locate DLLs for the application. +** +** If lpPathName is an empty string (""), the call removes the current directory from the default DLL search order. +** If lpPathName is NULL, the function restores the default search order. +** +*/ +BOOL CSystem::RmSetDllDirectory(LPCWSTR lpPathName) +{ + if (GetOSPlatform() >= OSPLATFORM_XP_SP1) + { + if (!c_SetDllDirectoryW) + { + c_SetDllDirectoryW = (FPSETDLLDIRECTORYW)GetProcAddress(GetModuleHandle(L"Kernel32.dll"), "SetDllDirectoryW"); + } + + if (c_SetDllDirectoryW) + { + return c_SetDllDirectoryW(lpPathName); + } + } + + return FALSE; +} + +/* +** RmLoadLibrary +** +** This function is a wrapper function for LoadLibrary(). +** +** Avoids loading a DLL from current directory. +** +*/ +HMODULE CSystem::RmLoadLibrary(LPCWSTR lpLibFileName, DWORD* dwError, bool ignoreErrors) +{ + OSPLATFORM platform = GetOSPlatform(); + WCHAR buffer[MAX_PATH]; + + HMODULE hLib = NULL; + DWORD err; + UINT oldMode; + + if (ignoreErrors) + { + oldMode = SetErrorMode(0); + SetErrorMode(oldMode | SEM_FAILCRITICALERRORS); // Prevent the system from displaying message box + } + + if (platform < OSPLATFORM_XP_SP1) + { + // Replace current directory to application directory + GetCurrentDirectory(MAX_PATH, buffer); + SetCurrentDirectory(Rainmeter->GetPath().c_str()); + } + else + { + // Remove current directory from DLL search path + RmSetDllDirectory(L""); + } + + SetLastError(ERROR_SUCCESS); + hLib = LoadLibrary(lpLibFileName); + err = GetLastError(); + + if (platform < OSPLATFORM_XP_SP1) + { + // Reset to old current directory + SetCurrentDirectory(buffer); + } + + if (ignoreErrors) + { + SetErrorMode(oldMode); // Reset + } + + if (dwError) + { + *dwError = err; + } + + return hLib; +} + /* ** DwmIsCompositionEnabled ** @@ -985,18 +1133,22 @@ BOOL CSystem::DwmIsCompositionEnabled() BOOL fEnabled = FALSE; typedef HRESULT (WINAPI * FPDWMISCOMPOSITIONENABLED)(BOOL* pfEnabled); - HINSTANCE h = LoadLibrary(L"dwmapi.dll"); - if (h) + + if (CSystem::GetOSPlatform() >= OSPLATFORM_VISTA) { - FPDWMISCOMPOSITIONENABLED DwmIsCompositionEnabled = (FPDWMISCOMPOSITIONENABLED)GetProcAddress(h, "DwmIsCompositionEnabled"); - if (DwmIsCompositionEnabled) + HINSTANCE h = RmLoadLibrary(L"dwmapi.dll"); + if (h) { - if (DwmIsCompositionEnabled(&fEnabled) != S_OK) + FPDWMISCOMPOSITIONENABLED DwmIsCompositionEnabled = (FPDWMISCOMPOSITIONENABLED)GetProcAddress(h, "DwmIsCompositionEnabled"); + if (DwmIsCompositionEnabled) { - fEnabled = FALSE; + if (DwmIsCompositionEnabled(&fEnabled) != S_OK) + { + fEnabled = FALSE; + } } + FreeLibrary(h); } - FreeLibrary(h); } return fEnabled; } diff --git a/Library/System.h b/Library/System.h index c6c3a1c7..20dae671 100644 --- a/Library/System.h +++ b/Library/System.h @@ -24,6 +24,20 @@ #include #include +typedef BOOL (WINAPI *FPSETDLLDIRECTORYW)(LPCWSTR lpPathName); + +enum OSPLATFORM +{ + OSPLATFORM_UNKNOWN = 0, + OSPLATFORM_9X, + OSPLATFORM_NT4, + OSPLATFORM_2K, + OSPLATFORM_XP, + OSPLATFORM_XP_SP1, + OSPLATFORM_VISTA, + OSPLATFORM_7 +}; + struct MONITOR_INFO { bool active; @@ -64,6 +78,12 @@ public: static HWND GetHelperWindow() { return c_HelperWindow; } static void PrepareHelperWindow(HWND WorkerW); + static bool IsNT() { return (GetOSPlatform() >= OSPLATFORM_NT4); } + static OSPLATFORM GetOSPlatform(); + + static BOOL RmSetDllDirectory(LPCWSTR lpPathName); + static HMODULE RmLoadLibrary(LPCWSTR lpLibFileName, DWORD* dwError = NULL, bool ignoreErrors = false); + static bool CopyFiles(const std::wstring& strFrom, const std::wstring& strTo, bool bMove = false); static bool RemoveFile(const std::wstring& file); @@ -94,6 +114,10 @@ private: static bool c_DwmCompositionEnabled; static bool c_ShowDesktop; + + static OSPLATFORM c_Platform; + + static FPSETDLLDIRECTORYW c_SetDllDirectoryW; }; #endif