[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())
This commit is contained in:
spx 2010-09-11 19:39:45 +00:00
parent 3aa4673019
commit 3da0aa3f4c
11 changed files with 252 additions and 82 deletions

View File

@ -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;

View File

@ -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");

View File

@ -20,6 +20,7 @@
#include "Litestep.h"
#include "Error.h"
#include "Rainmeter.h"
#include "System.h"
#include <shellapi.h>
#include <crtdbg.h>
#include <stdio.h>
@ -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");

View File

@ -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)
{

View File

@ -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;

View File

@ -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);

View File

@ -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,7 +279,10 @@ 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 (CSystem::GetOSPlatform() >= OSPLATFORM_VISTA)
{
HINSTANCE h = CSystem::RmLoadLibrary(L"dwmapi.dll");
if (h)
{
FPDWMSETWINDOWATTRIBUTE DwmSetWindowAttribute = (FPDWMSETWINDOWATTRIBUTE)GetProcAddress(h, "DwmSetWindowAttribute");
@ -292,6 +293,7 @@ void CMeterWindow::IgnoreAeroPeek()
}
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)

View File

@ -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
**

View File

@ -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<std::wstring> ParseString(LPCTSTR str);
static PLATFORM IsNT();
static std::wstring ExtractPath(const std::wstring& strFilePath);
static void ExpandEnvironmentVariables(std::wstring& strPath);

View File

@ -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,7 +1133,10 @@ BOOL CSystem::DwmIsCompositionEnabled()
BOOL fEnabled = FALSE;
typedef HRESULT (WINAPI * FPDWMISCOMPOSITIONENABLED)(BOOL* pfEnabled);
HINSTANCE h = LoadLibrary(L"dwmapi.dll");
if (CSystem::GetOSPlatform() >= OSPLATFORM_VISTA)
{
HINSTANCE h = RmLoadLibrary(L"dwmapi.dll");
if (h)
{
FPDWMISCOMPOSITIONENABLED DwmIsCompositionEnabled = (FPDWMISCOMPOSITIONENABLED)GetProcAddress(h, "DwmIsCompositionEnabled");
@ -998,6 +1149,7 @@ BOOL CSystem::DwmIsCompositionEnabled()
}
FreeLibrary(h);
}
}
return fEnabled;
}

View File

@ -24,6 +24,20 @@
#include <windows.h>
#include <vector>
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