mirror of
				https://github.com/chibicitiberiu/rainmeter-studio.git
				synced 2024-02-24 04:33:31 +00:00 
			
		
		
		
	Further improvements to r1183.
This commit is contained in:
		@@ -18,6 +18,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define WIN32_LEAN_AND_MEAN
 | 
					#define WIN32_LEAN_AND_MEAN
 | 
				
			||||||
#include <Windows.h>
 | 
					#include <Windows.h>
 | 
				
			||||||
 | 
					#include <Sddl.h>
 | 
				
			||||||
#include <ShellAPI.h>
 | 
					#include <ShellAPI.h>
 | 
				
			||||||
#include <ShlObj.h>
 | 
					#include <ShlObj.h>
 | 
				
			||||||
#include <process.h>
 | 
					#include <process.h>
 | 
				
			||||||
@@ -34,21 +35,24 @@ struct MeasureData
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
struct BinData
 | 
					struct BinData
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	FILETIME lastWrite;
 | 
						ULONGLONG lastWrite;
 | 
				
			||||||
	HANDLE directory;
 | 
						HANDLE directory;
 | 
				
			||||||
	WCHAR drive;
 | 
						WCHAR drive;
 | 
				
			||||||
 | 
						bool isFAT;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned int __stdcall QueryRecycleBinThreadProc(void* pParam);
 | 
					unsigned int __stdcall QueryRecycleBinThreadProc(void* pParam);
 | 
				
			||||||
HRESULT GetFolderCLSID(LPCWSTR pszPath, CLSID* pathCLSID);
 | 
					HRESULT GetFolderCLSID(LPCWSTR pszPath, CLSID* pathCLSID);
 | 
				
			||||||
HANDLE GetRecycleBinHandle(WCHAR drive);
 | 
					HANDLE GetRecycleBinHandle(WCHAR drive, bool& isFAT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::vector<BinData> g_BinData;
 | 
					std::vector<BinData> g_BinData;
 | 
				
			||||||
double g_BinCount = 0;
 | 
					double g_BinCount = 0;
 | 
				
			||||||
double g_BinSize = 0;
 | 
					double g_BinSize = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
UINT g_UpdateCount = 0;
 | 
					bool g_IsXP = false;
 | 
				
			||||||
UINT g_InstanceCount = 0;
 | 
					
 | 
				
			||||||
 | 
					int g_UpdateCount = 0;
 | 
				
			||||||
 | 
					int g_InstanceCount = 0;
 | 
				
			||||||
HANDLE g_Thread = NULL;
 | 
					HANDLE g_Thread = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PLUGIN_EXPORT void Initialize(void** data, void* rm)
 | 
					PLUGIN_EXPORT void Initialize(void** data, void* rm)
 | 
				
			||||||
@@ -56,6 +60,19 @@ PLUGIN_EXPORT void Initialize(void** data, void* rm)
 | 
				
			|||||||
	MeasureData* measure = new MeasureData;
 | 
						MeasureData* measure = new MeasureData;
 | 
				
			||||||
	*data = measure;
 | 
						*data = measure;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (g_InstanceCount == 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							OSVERSIONINFOEX osvi = {sizeof(OSVERSIONINFOEX)};
 | 
				
			||||||
 | 
							if (GetVersionEx((OSVERSIONINFO*)&osvi))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (osvi.dwMajorVersion == 5)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									// Not checking for osvi.dwMinorVersion >= 1 because we won't run on pre-XP
 | 
				
			||||||
 | 
									g_IsXP = true;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	++g_InstanceCount;
 | 
						++g_InstanceCount;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -111,23 +128,28 @@ PLUGIN_EXPORT double Update(void* data)
 | 
				
			|||||||
			WCHAR* pos = wcschr(buffer, data.drive);
 | 
								WCHAR* pos = wcschr(buffer, data.drive);
 | 
				
			||||||
			if (pos != NULL)
 | 
								if (pos != NULL)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				*pos = DRIVE_HANDLED;
 | 
									if (data.lastWrite != -1)
 | 
				
			||||||
				++iter;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				if (data.lastWrite.dwHighDateTime != 0xFFFFFFFF &&
 | 
					 | 
				
			||||||
					data.lastWrite.dwLowDateTime != 0xFFFFFFFF)
 | 
					 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					FILETIME lastWrite;
 | 
										if (data.isFAT)
 | 
				
			||||||
					GetFileTime(data.directory, NULL, NULL, &lastWrite);
 | 
					 | 
				
			||||||
					if (data.lastWrite.dwHighDateTime != lastWrite.dwHighDateTime ||
 | 
					 | 
				
			||||||
						data.lastWrite.dwLowDateTime != lastWrite.dwLowDateTime)
 | 
					 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						data.lastWrite.dwHighDateTime = lastWrite.dwHighDateTime;
 | 
											// FAT/FAT32 doesn't update directory last write time.
 | 
				
			||||||
						data.lastWrite.dwLowDateTime = lastWrite.dwLowDateTime;
 | 
											// TODO: Fix me?
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										else
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											ULONGLONG lastWrite;
 | 
				
			||||||
 | 
											GetFileTime(data.directory, NULL, NULL, (FILETIME*)&lastWrite);
 | 
				
			||||||
 | 
											if (data.lastWrite != lastWrite)
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												data.lastWrite = lastWrite;
 | 
				
			||||||
							changed = true;
 | 
												changed = true;
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									*pos = DRIVE_HANDLED;
 | 
				
			||||||
 | 
									++iter;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				// Drive removed
 | 
									// Drive removed
 | 
				
			||||||
@@ -152,11 +174,10 @@ PLUGIN_EXPORT double Update(void* data)
 | 
				
			|||||||
				drive[0] = buffer[i];
 | 
									drive[0] = buffer[i];
 | 
				
			||||||
				if (GetDriveType(drive) == DRIVE_FIXED)
 | 
									if (GetDriveType(drive) == DRIVE_FIXED)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					data.directory = GetRecycleBinHandle(buffer[i]);
 | 
										data.directory = GetRecycleBinHandle(buffer[i], data.isFAT);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				data.lastWrite.dwHighDateTime =
 | 
									data.lastWrite = (data.directory || data.isFAT) ? 0 : -1;
 | 
				
			||||||
					data.lastWrite.dwLowDateTime = data.directory ? 0 : 0xFFFFFFFF;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				g_BinData.push_back(data);
 | 
									g_BinData.push_back(data);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -164,6 +185,8 @@ PLUGIN_EXPORT double Update(void* data)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		if (changed)
 | 
							if (changed)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								RmLog(LOG_WARNING, L"g_UpdateCount");
 | 
				
			||||||
 | 
								g_UpdateCount = -8;
 | 
				
			||||||
			g_Thread = (HANDLE)_beginthreadex(NULL, 0, QueryRecycleBinThreadProc, NULL, 0, NULL);
 | 
								g_Thread = (HANDLE)_beginthreadex(NULL, 0, QueryRecycleBinThreadProc, NULL, 0, NULL);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -246,82 +269,113 @@ HRESULT GetFolderCLSID(LPCWSTR path, CLSID* clsid)
 | 
				
			|||||||
	return hr;
 | 
						return hr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
HANDLE GetRecycleBinHandle(WCHAR drive)
 | 
					// Return value must be freed with LocalFree
 | 
				
			||||||
 | 
					LPWSTR GetCurrentUserSid()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	WCHAR search[] = L"\0:\\*";
 | 
						LPWSTR sidStr = NULL;
 | 
				
			||||||
 | 
						HANDLE hToken;
 | 
				
			||||||
 | 
						if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							DWORD dwBufSize = 0;
 | 
				
			||||||
 | 
							GetTokenInformation(hToken, TokenUser, NULL, 0, &dwBufSize);
 | 
				
			||||||
 | 
							BYTE* buf = new BYTE[dwBufSize];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (GetTokenInformation(hToken, TokenUser, buf, dwBufSize, &dwBufSize))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								TOKEN_USER* tu = (TOKEN_USER*)buf;
 | 
				
			||||||
 | 
								if (ConvertSidToStringSid(tu->User.Sid, &sidStr))
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							delete [] buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							CloseHandle(hToken);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return sidStr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HANDLE GetRecycleBinHandle(WCHAR drive, bool& isFAT)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						WCHAR search[] = L"\0:\\";
 | 
				
			||||||
	search[0] = drive;
 | 
						search[0] = drive;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	WIN32_FIND_DATA fd;
 | 
						WCHAR filesystem[16];
 | 
				
			||||||
	HANDLE hSearch = FindFirstFile(search, &fd);
 | 
						if (!GetVolumeInformation(search, NULL, 0, NULL, NULL, NULL, filesystem, _countof(filesystem)))
 | 
				
			||||||
	if (hSearch != INVALID_HANDLE_VALUE)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		bool found = false;
 | 
							return NULL;
 | 
				
			||||||
		std::wstring path;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		do
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			if ((fd.dwFileAttributes &
 | 
					 | 
				
			||||||
				(FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY)) == 0)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				continue;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			WCHAR buffer[MAX_PATH];
 | 
						isFAT = true;
 | 
				
			||||||
			int len = _snwprintf_s(buffer, _TRUNCATE, L"%c:\\%s\\*", drive, fd.cFileName);
 | 
						if (wcscmp(filesystem, L"NTFS") == 0)
 | 
				
			||||||
 | 
					 | 
				
			||||||
			// Find the SID-specific child directory
 | 
					 | 
				
			||||||
			HANDLE hChildSearch = FindFirstFile(buffer, &fd);
 | 
					 | 
				
			||||||
			if (hChildSearch != INVALID_HANDLE_VALUE)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
				do
 | 
							isFAT = false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if (wcscmp(filesystem, L"FAT") != 0 && wcscmp(filesystem, L"FAT32"))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
					if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
 | 
							RmLog(LOG_ERROR, L"RecycleManager.dll: Unsupported filesystem");
 | 
				
			||||||
						(fd.cFileName[0] == L'.') ||
 | 
							return NULL;
 | 
				
			||||||
						(wcsnlen(fd.cFileName, 10) < 10))
 | 
					 | 
				
			||||||
					{
 | 
					 | 
				
			||||||
						continue;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					path.assign(buffer, len - 1);
 | 
						const WCHAR* binFolder;
 | 
				
			||||||
					path += fd.cFileName;
 | 
						if (g_IsXP)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							binFolder = isFAT ? L"RECYCLED" : L"RECYCLER";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							binFolder = L"$RECYCLE.BIN";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						HANDLE hDir = NULL;
 | 
				
			||||||
 | 
						WCHAR binPath[MAX_PATH];
 | 
				
			||||||
 | 
						_snwprintf_s(binPath, _TRUNCATE, L"%s%s\\", search, binFolder);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DWORD binAttributes = GetFileAttributes(binPath);
 | 
				
			||||||
 | 
						if (binAttributes != INVALID_FILE_ATTRIBUTES &&
 | 
				
			||||||
 | 
							binAttributes & (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY))
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (isFAT)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (_waccess(binPath, 0) != -1)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									isFAT = true;
 | 
				
			||||||
 | 
									return hDir;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								// Get the correct, SID-specific bin for NTFS
 | 
				
			||||||
 | 
								LPWSTR currentSid = GetCurrentUserSid();
 | 
				
			||||||
 | 
								if (currentSid)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									wcscat(binPath, currentSid);
 | 
				
			||||||
 | 
									binAttributes = GetFileAttributes(binPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if (binAttributes != INVALID_FILE_ATTRIBUTES &&
 | 
				
			||||||
 | 
										binAttributes & FILE_ATTRIBUTE_DIRECTORY)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
					CLSID id;
 | 
										CLSID id;
 | 
				
			||||||
					HRESULT hr = GetFolderCLSID(path.c_str(), &id);
 | 
										HRESULT hr = GetFolderCLSID(binPath, &id);
 | 
				
			||||||
					if (SUCCEEDED(hr) && IsEqualGUID(CLSID_RecycleBin, id))
 | 
										if (SUCCEEDED(hr) && IsEqualGUID(CLSID_RecycleBin, id))
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						found = true;
 | 
											hDir = CreateFile(
 | 
				
			||||||
						break;
 | 
												binPath,
 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				while (FindNextFile(hChildSearch, &fd));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				FindClose(hChildSearch);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				if (found)
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					// Break out of main loop
 | 
					 | 
				
			||||||
					break;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		while (FindNextFile(hSearch, &fd));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		FindClose(hSearch);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (found)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			HANDLE hDir = CreateFile(
 | 
					 | 
				
			||||||
				path.c_str(),
 | 
					 | 
				
			||||||
							GENERIC_READ,
 | 
												GENERIC_READ,
 | 
				
			||||||
							FILE_SHARE_READ | FILE_SHARE_WRITE,
 | 
												FILE_SHARE_READ | FILE_SHARE_WRITE,
 | 
				
			||||||
							NULL,
 | 
												NULL,
 | 
				
			||||||
							OPEN_EXISTING,
 | 
												OPEN_EXISTING,
 | 
				
			||||||
							FILE_FLAG_BACKUP_SEMANTICS,
 | 
												FILE_FLAG_BACKUP_SEMANTICS,
 | 
				
			||||||
							NULL);
 | 
												NULL);
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									LocalFree(currentSid);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!hDir) RmLog(LOG_ERROR, L"RecycleManager.dll: Unable to find bin");
 | 
				
			||||||
	return hDir;
 | 
						return hDir;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return NULL;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user