mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
Fixed line endings and applied gitignore
This commit is contained in:
@ -1,40 +1,40 @@
|
||||
#include <VerRsrc.h>
|
||||
#include "../../Version.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,1,0
|
||||
PRODUCTVERSION PRODUCTVER
|
||||
FILEFLAGSMASK 0x17L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_DLL
|
||||
FILESUBTYPE VFT_UNKNOWN
|
||||
{
|
||||
BLOCK "StringFileInfo"
|
||||
{
|
||||
BLOCK "040904E4"
|
||||
{
|
||||
VALUE "FileVersion", "1.0.1.0"
|
||||
VALUE "LegalCopyright", "<22> 2010 - gschoppe"
|
||||
VALUE "ProductName", "Rainmeter"
|
||||
#ifdef _WIN64
|
||||
VALUE "ProductVersion", STRPRODUCTVER " (64-bit)"
|
||||
#else
|
||||
VALUE "ProductVersion", STRPRODUCTVER " (32-bit)"
|
||||
#endif //_WIN64
|
||||
}
|
||||
}
|
||||
BLOCK "VarFileInfo"
|
||||
{
|
||||
VALUE "Translation", 0x409, 1252
|
||||
}
|
||||
}
|
||||
#include <VerRsrc.h>
|
||||
#include "../../Version.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,1,0
|
||||
PRODUCTVERSION PRODUCTVER
|
||||
FILEFLAGSMASK 0x17L
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_DLL
|
||||
FILESUBTYPE VFT_UNKNOWN
|
||||
{
|
||||
BLOCK "StringFileInfo"
|
||||
{
|
||||
BLOCK "040904E4"
|
||||
{
|
||||
VALUE "FileVersion", "1.0.1.0"
|
||||
VALUE "LegalCopyright", "<22> 2010 - gschoppe"
|
||||
VALUE "ProductName", "Rainmeter"
|
||||
#ifdef _WIN64
|
||||
VALUE "ProductVersion", STRPRODUCTVER " (64-bit)"
|
||||
#else
|
||||
VALUE "ProductVersion", STRPRODUCTVER " (32-bit)"
|
||||
#endif //_WIN64
|
||||
}
|
||||
}
|
||||
BLOCK "VarFileInfo"
|
||||
{
|
||||
VALUE "Translation", 0x409, 1252
|
||||
}
|
||||
}
|
||||
|
@ -1,35 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(SolutionDir)Build\VS\Rainmeter.Cpp.Default.props" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{4F8C4C09-431C-45C4-830B-32006E783C3A}</ProjectGuid>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<TargetName>RecycleManager</TargetName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<Import Project="$(SolutionDir)Build\VS\Rainmeter.Cpp.props" />
|
||||
<Import Project="$(SolutionDir)Build\VS\RainmeterPlugin.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="PluginRecycleManager.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="RecycleManager.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(SolutionDir)Build\VS\Rainmeter.Cpp.Default.props" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{4F8C4C09-431C-45C4-830B-32006E783C3A}</ProjectGuid>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<TargetName>RecycleManager</TargetName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<Import Project="$(SolutionDir)Build\VS\Rainmeter.Cpp.props" />
|
||||
<Import Project="$(SolutionDir)Build\VS\RainmeterPlugin.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="PluginRecycleManager.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="RecycleManager.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -1,291 +1,291 @@
|
||||
/*
|
||||
Copyright (C) 2005 Kimmo Pekkola, 2009 Greg Schoppe
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <Windows.h>
|
||||
#include <ShellAPI.h>
|
||||
#include <process.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include "../../Library/Export.h" // Rainmeter's exported functions
|
||||
|
||||
struct MeasureData
|
||||
{
|
||||
bool count;
|
||||
|
||||
MeasureData() : count(false) {}
|
||||
};
|
||||
|
||||
DWORD WINAPI QueryRecycleBinThreadProc(void* pParam);
|
||||
bool HasRecycleBinChanged();
|
||||
|
||||
double g_BinCount = 0;
|
||||
double g_BinSize = 0;
|
||||
|
||||
int g_UpdateCount = 0;
|
||||
int g_InstanceCount = 0;
|
||||
bool g_Thread = false;
|
||||
bool g_FreeInstanceInThread = false;
|
||||
CRITICAL_SECTION g_CriticalSection;
|
||||
|
||||
bool g_IsPlatformXP = false;
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
switch (fdwReason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
InitializeCriticalSection(&g_CriticalSection);
|
||||
|
||||
// Disable DLL_THREAD_ATTACH and DLL_THREAD_DETACH notification calls
|
||||
DisableThreadLibraryCalls(hinstDLL);
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
DeleteCriticalSection(&g_CriticalSection);
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PLUGIN_EXPORT void Initialize(void** data, void* rm)
|
||||
{
|
||||
MeasureData* measure = new MeasureData;
|
||||
*data = measure;
|
||||
|
||||
if (g_InstanceCount == 0)
|
||||
{
|
||||
OSVERSIONINFOEX osvi = {sizeof(OSVERSIONINFOEX)};
|
||||
GetVersionEx((OSVERSIONINFO*)&osvi);
|
||||
|
||||
// Not checking for osvi.dwMinorVersion >= 1 because pre-XP is not supported.
|
||||
g_IsPlatformXP = (osvi.dwMajorVersion == 5);
|
||||
}
|
||||
|
||||
++g_InstanceCount;
|
||||
}
|
||||
|
||||
PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue)
|
||||
{
|
||||
MeasureData* measure = (MeasureData*)data;
|
||||
|
||||
LPCWSTR value = RmReadString(rm, L"RecycleType", L"COUNT");
|
||||
if (_wcsicmp(L"COUNT", value) == 0)
|
||||
{
|
||||
measure->count = true;
|
||||
}
|
||||
else if (_wcsicmp(L"SIZE", value) == 0)
|
||||
{
|
||||
measure->count = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
WCHAR buffer[256];
|
||||
_snwprintf_s(buffer, _TRUNCATE, L"RecycleManager.dll: RecycleType=%s is not valid in [%s]", value, RmGetMeasureName(rm));
|
||||
RmLog(LOG_ERROR, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
PLUGIN_EXPORT double Update(void* data)
|
||||
{
|
||||
MeasureData* measure = (MeasureData*)data;
|
||||
|
||||
if (TryEnterCriticalSection(&g_CriticalSection))
|
||||
{
|
||||
if (!g_Thread)
|
||||
{
|
||||
++g_UpdateCount;
|
||||
if (g_UpdateCount > g_InstanceCount)
|
||||
{
|
||||
if (HasRecycleBinChanged())
|
||||
{
|
||||
// Delay next check.
|
||||
g_UpdateCount = g_InstanceCount * -2;
|
||||
|
||||
DWORD id;
|
||||
HANDLE thread = CreateThread(nullptr, 0, QueryRecycleBinThreadProc, nullptr, 0, &id);
|
||||
if (thread)
|
||||
{
|
||||
CloseHandle(thread);
|
||||
g_Thread = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_UpdateCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&g_CriticalSection);
|
||||
}
|
||||
|
||||
return measure->count ? g_BinCount : g_BinSize;
|
||||
}
|
||||
|
||||
PLUGIN_EXPORT void Finalize(void* data)
|
||||
{
|
||||
MeasureData* measure = (MeasureData*)data;
|
||||
delete measure;
|
||||
|
||||
--g_InstanceCount;
|
||||
if (g_InstanceCount == 0)
|
||||
{
|
||||
EnterCriticalSection(&g_CriticalSection);
|
||||
if (g_Thread && !g_FreeInstanceInThread)
|
||||
{
|
||||
// Increment ref count of this module so that it will not be unloaded prior to
|
||||
// thread completion.
|
||||
DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS;
|
||||
HMODULE module;
|
||||
GetModuleHandleEx(flags, (LPCWSTR)DllMain, &module);
|
||||
g_FreeInstanceInThread = true;
|
||||
}
|
||||
LeaveCriticalSection(&g_CriticalSection);
|
||||
}
|
||||
}
|
||||
|
||||
PLUGIN_EXPORT void ExecuteBang(void* data, LPCWSTR args)
|
||||
{
|
||||
MeasureData* measure = (MeasureData*)data;
|
||||
|
||||
if (_wcsicmp(args, L"EmptyBin") == 0)
|
||||
{
|
||||
SHEmptyRecycleBin(nullptr, nullptr, 0);
|
||||
}
|
||||
else if (_wcsicmp(args, L"EmptyBinSilent") == 0)
|
||||
{
|
||||
SHEmptyRecycleBin(nullptr, nullptr, SHERB_NOCONFIRMATION | SHERB_NOPROGRESSUI | SHERB_NOSOUND);
|
||||
}
|
||||
else if (_wcsicmp(args, L"OpenBin") == 0)
|
||||
{
|
||||
ShellExecute(nullptr, L"open", L"explorer.exe", L"/N,::{645FF040-5081-101B-9F08-00AA002F954E}", nullptr, SW_SHOW);
|
||||
}
|
||||
}
|
||||
|
||||
DWORD WINAPI QueryRecycleBinThreadProc(void* pParam)
|
||||
{
|
||||
// NOTE: Do not use CRT functions (since thread was created with CreateThread())!
|
||||
|
||||
SHQUERYRBINFO rbi = {0};
|
||||
rbi.cbSize = sizeof(SHQUERYRBINFO);
|
||||
SHQueryRecycleBin(nullptr, &rbi);
|
||||
g_BinCount = (double)rbi.i64NumItems;
|
||||
g_BinSize = (double)rbi.i64Size;
|
||||
|
||||
EnterCriticalSection(&g_CriticalSection);
|
||||
HMODULE module = nullptr;
|
||||
if (g_FreeInstanceInThread)
|
||||
{
|
||||
DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT;
|
||||
GetModuleHandleEx(flags, (LPCWSTR)DllMain, &module);
|
||||
g_FreeInstanceInThread = false;
|
||||
}
|
||||
|
||||
g_Thread = false;
|
||||
LeaveCriticalSection(&g_CriticalSection);
|
||||
|
||||
if (module)
|
||||
{
|
||||
// Decrement the ref count and possibly unload the module if this is
|
||||
// the last instance.
|
||||
FreeLibraryAndExitThread(module, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool HasRecycleBinChanged()
|
||||
{
|
||||
static DWORD s_LastVolumeCount = 0;
|
||||
static ULONGLONG s_LastWriteTime = 0;
|
||||
|
||||
bool changed = false;
|
||||
|
||||
// Check if items have been added to recycle bin since last check.
|
||||
HKEY volumeKey;
|
||||
const WCHAR* subKey = g_IsPlatformXP ?
|
||||
L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\BitBucket" :
|
||||
L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\BitBucket\\Volume";
|
||||
LSTATUS ls = RegOpenKeyEx(HKEY_CURRENT_USER, subKey, 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &volumeKey);
|
||||
if (ls == ERROR_SUCCESS)
|
||||
{
|
||||
DWORD volumeCount = 0;
|
||||
RegQueryInfoKey(volumeKey, nullptr, nullptr, nullptr, &volumeCount, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
|
||||
if (volumeCount != s_LastVolumeCount)
|
||||
{
|
||||
s_LastVolumeCount = volumeCount;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
WCHAR buffer[64];
|
||||
DWORD bufferSize = _countof(buffer);
|
||||
DWORD index = 0;
|
||||
|
||||
while ((ls = RegEnumKeyEx(volumeKey, index, buffer, &bufferSize, nullptr, nullptr, nullptr, nullptr)) == ERROR_SUCCESS)
|
||||
{
|
||||
HKEY volumeSubKey;
|
||||
ls = RegOpenKeyEx(volumeKey, buffer, 0, KEY_QUERY_VALUE, &volumeSubKey);
|
||||
if (ls == ERROR_SUCCESS)
|
||||
{
|
||||
ULONGLONG lastWriteTime;
|
||||
ls = RegQueryInfoKey(volumeSubKey, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, (FILETIME*)&lastWriteTime);
|
||||
if (ls == ERROR_SUCCESS)
|
||||
{
|
||||
if (lastWriteTime > s_LastWriteTime)
|
||||
{
|
||||
s_LastWriteTime = lastWriteTime;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
RegCloseKey(volumeSubKey);
|
||||
}
|
||||
|
||||
bufferSize = _countof(buffer);
|
||||
++index;
|
||||
}
|
||||
|
||||
RegCloseKey(volumeKey);
|
||||
}
|
||||
|
||||
if (!changed)
|
||||
{
|
||||
// Check if recycle bin has been emptied.
|
||||
HKEY iconKey;
|
||||
const WCHAR* subKey = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\{645FF040-5081-101B-9F08-00AA002F954E}\\DefaultIcon";
|
||||
ls = RegOpenKeyEx(HKEY_CURRENT_USER, subKey, 0, KEY_QUERY_VALUE, &iconKey);
|
||||
if (ls == ERROR_SUCCESS)
|
||||
{
|
||||
ULONGLONG lastWriteTime;
|
||||
ls = RegQueryInfoKey(iconKey, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, (FILETIME*)&lastWriteTime);
|
||||
if (ls == ERROR_SUCCESS)
|
||||
{
|
||||
if (lastWriteTime > s_LastWriteTime)
|
||||
{
|
||||
s_LastWriteTime = lastWriteTime;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
RegCloseKey(iconKey);
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
/*
|
||||
Copyright (C) 2005 Kimmo Pekkola, 2009 Greg Schoppe
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <Windows.h>
|
||||
#include <ShellAPI.h>
|
||||
#include <process.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include "../../Library/Export.h" // Rainmeter's exported functions
|
||||
|
||||
struct MeasureData
|
||||
{
|
||||
bool count;
|
||||
|
||||
MeasureData() : count(false) {}
|
||||
};
|
||||
|
||||
DWORD WINAPI QueryRecycleBinThreadProc(void* pParam);
|
||||
bool HasRecycleBinChanged();
|
||||
|
||||
double g_BinCount = 0;
|
||||
double g_BinSize = 0;
|
||||
|
||||
int g_UpdateCount = 0;
|
||||
int g_InstanceCount = 0;
|
||||
bool g_Thread = false;
|
||||
bool g_FreeInstanceInThread = false;
|
||||
CRITICAL_SECTION g_CriticalSection;
|
||||
|
||||
bool g_IsPlatformXP = false;
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
switch (fdwReason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
InitializeCriticalSection(&g_CriticalSection);
|
||||
|
||||
// Disable DLL_THREAD_ATTACH and DLL_THREAD_DETACH notification calls
|
||||
DisableThreadLibraryCalls(hinstDLL);
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
DeleteCriticalSection(&g_CriticalSection);
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PLUGIN_EXPORT void Initialize(void** data, void* rm)
|
||||
{
|
||||
MeasureData* measure = new MeasureData;
|
||||
*data = measure;
|
||||
|
||||
if (g_InstanceCount == 0)
|
||||
{
|
||||
OSVERSIONINFOEX osvi = {sizeof(OSVERSIONINFOEX)};
|
||||
GetVersionEx((OSVERSIONINFO*)&osvi);
|
||||
|
||||
// Not checking for osvi.dwMinorVersion >= 1 because pre-XP is not supported.
|
||||
g_IsPlatformXP = (osvi.dwMajorVersion == 5);
|
||||
}
|
||||
|
||||
++g_InstanceCount;
|
||||
}
|
||||
|
||||
PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue)
|
||||
{
|
||||
MeasureData* measure = (MeasureData*)data;
|
||||
|
||||
LPCWSTR value = RmReadString(rm, L"RecycleType", L"COUNT");
|
||||
if (_wcsicmp(L"COUNT", value) == 0)
|
||||
{
|
||||
measure->count = true;
|
||||
}
|
||||
else if (_wcsicmp(L"SIZE", value) == 0)
|
||||
{
|
||||
measure->count = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
WCHAR buffer[256];
|
||||
_snwprintf_s(buffer, _TRUNCATE, L"RecycleManager.dll: RecycleType=%s is not valid in [%s]", value, RmGetMeasureName(rm));
|
||||
RmLog(LOG_ERROR, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
PLUGIN_EXPORT double Update(void* data)
|
||||
{
|
||||
MeasureData* measure = (MeasureData*)data;
|
||||
|
||||
if (TryEnterCriticalSection(&g_CriticalSection))
|
||||
{
|
||||
if (!g_Thread)
|
||||
{
|
||||
++g_UpdateCount;
|
||||
if (g_UpdateCount > g_InstanceCount)
|
||||
{
|
||||
if (HasRecycleBinChanged())
|
||||
{
|
||||
// Delay next check.
|
||||
g_UpdateCount = g_InstanceCount * -2;
|
||||
|
||||
DWORD id;
|
||||
HANDLE thread = CreateThread(nullptr, 0, QueryRecycleBinThreadProc, nullptr, 0, &id);
|
||||
if (thread)
|
||||
{
|
||||
CloseHandle(thread);
|
||||
g_Thread = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_UpdateCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&g_CriticalSection);
|
||||
}
|
||||
|
||||
return measure->count ? g_BinCount : g_BinSize;
|
||||
}
|
||||
|
||||
PLUGIN_EXPORT void Finalize(void* data)
|
||||
{
|
||||
MeasureData* measure = (MeasureData*)data;
|
||||
delete measure;
|
||||
|
||||
--g_InstanceCount;
|
||||
if (g_InstanceCount == 0)
|
||||
{
|
||||
EnterCriticalSection(&g_CriticalSection);
|
||||
if (g_Thread && !g_FreeInstanceInThread)
|
||||
{
|
||||
// Increment ref count of this module so that it will not be unloaded prior to
|
||||
// thread completion.
|
||||
DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS;
|
||||
HMODULE module;
|
||||
GetModuleHandleEx(flags, (LPCWSTR)DllMain, &module);
|
||||
g_FreeInstanceInThread = true;
|
||||
}
|
||||
LeaveCriticalSection(&g_CriticalSection);
|
||||
}
|
||||
}
|
||||
|
||||
PLUGIN_EXPORT void ExecuteBang(void* data, LPCWSTR args)
|
||||
{
|
||||
MeasureData* measure = (MeasureData*)data;
|
||||
|
||||
if (_wcsicmp(args, L"EmptyBin") == 0)
|
||||
{
|
||||
SHEmptyRecycleBin(nullptr, nullptr, 0);
|
||||
}
|
||||
else if (_wcsicmp(args, L"EmptyBinSilent") == 0)
|
||||
{
|
||||
SHEmptyRecycleBin(nullptr, nullptr, SHERB_NOCONFIRMATION | SHERB_NOPROGRESSUI | SHERB_NOSOUND);
|
||||
}
|
||||
else if (_wcsicmp(args, L"OpenBin") == 0)
|
||||
{
|
||||
ShellExecute(nullptr, L"open", L"explorer.exe", L"/N,::{645FF040-5081-101B-9F08-00AA002F954E}", nullptr, SW_SHOW);
|
||||
}
|
||||
}
|
||||
|
||||
DWORD WINAPI QueryRecycleBinThreadProc(void* pParam)
|
||||
{
|
||||
// NOTE: Do not use CRT functions (since thread was created with CreateThread())!
|
||||
|
||||
SHQUERYRBINFO rbi = {0};
|
||||
rbi.cbSize = sizeof(SHQUERYRBINFO);
|
||||
SHQueryRecycleBin(nullptr, &rbi);
|
||||
g_BinCount = (double)rbi.i64NumItems;
|
||||
g_BinSize = (double)rbi.i64Size;
|
||||
|
||||
EnterCriticalSection(&g_CriticalSection);
|
||||
HMODULE module = nullptr;
|
||||
if (g_FreeInstanceInThread)
|
||||
{
|
||||
DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT;
|
||||
GetModuleHandleEx(flags, (LPCWSTR)DllMain, &module);
|
||||
g_FreeInstanceInThread = false;
|
||||
}
|
||||
|
||||
g_Thread = false;
|
||||
LeaveCriticalSection(&g_CriticalSection);
|
||||
|
||||
if (module)
|
||||
{
|
||||
// Decrement the ref count and possibly unload the module if this is
|
||||
// the last instance.
|
||||
FreeLibraryAndExitThread(module, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool HasRecycleBinChanged()
|
||||
{
|
||||
static DWORD s_LastVolumeCount = 0;
|
||||
static ULONGLONG s_LastWriteTime = 0;
|
||||
|
||||
bool changed = false;
|
||||
|
||||
// Check if items have been added to recycle bin since last check.
|
||||
HKEY volumeKey;
|
||||
const WCHAR* subKey = g_IsPlatformXP ?
|
||||
L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\BitBucket" :
|
||||
L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\BitBucket\\Volume";
|
||||
LSTATUS ls = RegOpenKeyEx(HKEY_CURRENT_USER, subKey, 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &volumeKey);
|
||||
if (ls == ERROR_SUCCESS)
|
||||
{
|
||||
DWORD volumeCount = 0;
|
||||
RegQueryInfoKey(volumeKey, nullptr, nullptr, nullptr, &volumeCount, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
|
||||
if (volumeCount != s_LastVolumeCount)
|
||||
{
|
||||
s_LastVolumeCount = volumeCount;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
WCHAR buffer[64];
|
||||
DWORD bufferSize = _countof(buffer);
|
||||
DWORD index = 0;
|
||||
|
||||
while ((ls = RegEnumKeyEx(volumeKey, index, buffer, &bufferSize, nullptr, nullptr, nullptr, nullptr)) == ERROR_SUCCESS)
|
||||
{
|
||||
HKEY volumeSubKey;
|
||||
ls = RegOpenKeyEx(volumeKey, buffer, 0, KEY_QUERY_VALUE, &volumeSubKey);
|
||||
if (ls == ERROR_SUCCESS)
|
||||
{
|
||||
ULONGLONG lastWriteTime;
|
||||
ls = RegQueryInfoKey(volumeSubKey, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, (FILETIME*)&lastWriteTime);
|
||||
if (ls == ERROR_SUCCESS)
|
||||
{
|
||||
if (lastWriteTime > s_LastWriteTime)
|
||||
{
|
||||
s_LastWriteTime = lastWriteTime;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
RegCloseKey(volumeSubKey);
|
||||
}
|
||||
|
||||
bufferSize = _countof(buffer);
|
||||
++index;
|
||||
}
|
||||
|
||||
RegCloseKey(volumeKey);
|
||||
}
|
||||
|
||||
if (!changed)
|
||||
{
|
||||
// Check if recycle bin has been emptied.
|
||||
HKEY iconKey;
|
||||
const WCHAR* subKey = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\{645FF040-5081-101B-9F08-00AA002F954E}\\DefaultIcon";
|
||||
ls = RegOpenKeyEx(HKEY_CURRENT_USER, subKey, 0, KEY_QUERY_VALUE, &iconKey);
|
||||
if (ls == ERROR_SUCCESS)
|
||||
{
|
||||
ULONGLONG lastWriteTime;
|
||||
ls = RegQueryInfoKey(iconKey, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, (FILETIME*)&lastWriteTime);
|
||||
if (ls == ERROR_SUCCESS)
|
||||
{
|
||||
if (lastWriteTime > s_LastWriteTime)
|
||||
{
|
||||
s_LastWriteTime = lastWriteTime;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
RegCloseKey(iconKey);
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
Reference in New Issue
Block a user