windows-nt/Source/XPSP1/NT/shell/shell32/recclean.cpp
2020-09-26 16:20:57 +08:00

194 lines
4.6 KiB
C++

#include "shellprv.h"
#include "emptyvc.h"
#include "recclean.h"
#include "ids.h"
STDAPI CRecycleBinCleaner_CreateInstance(LPUNKNOWN punkOuter, REFIID riid, void **ppvOut)
{
*ppvOut = NULL;
CRecycleBinCleaner *p = new CRecycleBinCleaner();
if (!p)
return E_OUTOFMEMORY;
HRESULT hres = p->QueryInterface(riid, ppvOut);
p->Release();
return hres;
}
CRecycleBinCleaner::CRecycleBinCleaner() : m_cRef(1)
{
// start ref at one
}
CRecycleBinCleaner::~CRecycleBinCleaner()
{
// cleanup - nothing yet
}
/*----------------------------------------------------------
QueryInterface handler for CRecycleBinCleaner
*/
STDMETHODIMP CRecycleBinCleaner::QueryInterface(REFIID riid, PVOID *ppvObj)
{
if (IsEqualIID(riid, IID_IUnknown) ||
IsEqualIID(riid, IID_IEmptyVolumeCache2))
{
*ppvObj = SAFECAST(this, IEmptyVolumeCache2 *);
}
else if (IsEqualIID(riid, IID_IEmptyVolumeCache))
{
*ppvObj = SAFECAST(this, IEmptyVolumeCache *);
}
else
{
*ppvObj = NULL;
return E_NOINTERFACE;
}
AddRef();
return NOERROR;
}
STDMETHODIMP_(ULONG) CRecycleBinCleaner::AddRef()
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CRecycleBinCleaner::Release()
{
m_cRef--;
if (m_cRef > 0)
return m_cRef;
delete this;
return 0;
}
STDMETHODIMP CRecycleBinCleaner::InitializeEx(
HKEY hkRegKey,
LPCWSTR pcwszVolume,
LPCWSTR pcwszKeyName,
LPWSTR *ppwszDisplayName,
LPWSTR *ppwszDescription,
LPWSTR *ppwszBtnText,
DWORD *pdwFlags
)
{
TCHAR szTmp[128];
int iLen;
iLen = 1 + LoadString( g_hinst, IDS_RECCLEAN_BTNTEXT, szTmp, ARRAYSIZE(szTmp));
if (iLen == 1) // and hence LoadString returned 0 (error)
return E_FAIL;
*ppwszBtnText = (LPWSTR)CoTaskMemAlloc( iLen * sizeof(WCHAR) );
if ( !*ppwszBtnText )
return E_OUTOFMEMORY;
SHTCharToUnicode(szTmp, *ppwszBtnText, iLen);
return Initialize(hkRegKey, pcwszVolume, ppwszDisplayName, ppwszDescription, pdwFlags);
}
STDMETHODIMP CRecycleBinCleaner::Initialize(HKEY hRegKey, LPCWSTR pszVolume,
LPWSTR *ppwszName, LPWSTR *ppwszDesc, DWORD *pdwFlags)
{
TCHAR szTmpName[256], szTmpDesc[512];
int iNameLen, iDescLen;
if(!pdwFlags)
return E_INVALIDARG;
*pdwFlags = EVCF_HASSETTINGS;
iNameLen = 1 + LoadString( g_hinst, IDS_RECCLEAN_NAMETEXT, szTmpName, ARRAYSIZE(szTmpName));
iDescLen = 1 + LoadString( g_hinst, IDS_RECCLEAN_DESCTEXT, szTmpDesc, ARRAYSIZE(szTmpDesc));
if ( (iNameLen == 1) || (iDescLen == 1) ) // meaning LoadString returned 0 (error)
return E_FAIL;
*ppwszName = (LPWSTR)CoTaskMemAlloc( iNameLen*sizeof(WCHAR) );
*ppwszDesc = (LPWSTR)CoTaskMemAlloc( iDescLen*sizeof(WCHAR) );
if ( !*ppwszName || !*ppwszDesc )
return E_OUTOFMEMORY;
SHTCharToUnicode(szTmpName, *ppwszName, iNameLen);
SHTCharToUnicode(szTmpDesc, *ppwszDesc, iDescLen);
StrCpyNW(m_szVolume, pszVolume, ARRAYSIZE(m_szVolume));
return S_OK;
}
STDMETHODIMP CRecycleBinCleaner::GetSpaceUsed(DWORDLONG *pdwSpaceUsed, IEmptyVolumeCacheCallBack *picb)
{
SHQUERYRBINFO qinfo;
if(!pdwSpaceUsed)
return E_INVALIDARG;
qinfo.cbSize = sizeof(SHQUERYRBINFO);
if(SUCCEEDED(SHQueryRecycleBinW(m_szVolume, &qinfo)))
{
*pdwSpaceUsed = qinfo.i64Size;
}
else
{
*pdwSpaceUsed = 0;
}
// call back to be nice
if(picb)
picb->ScanProgress(*pdwSpaceUsed, EVCCBF_LASTNOTIFICATION, NULL);
return S_OK;
}
STDMETHODIMP CRecycleBinCleaner::Purge(DWORDLONG dwSpaceToFree, IEmptyVolumeCacheCallBack *picb)
{
SHQUERYRBINFO qinfo;
if (picb)
{
qinfo.cbSize = sizeof(SHQUERYRBINFO);
SHQueryRecycleBinW(m_szVolume, &qinfo);
}
// we ignore dwSpaceToFree and clean everything
SHEmptyRecycleBin(NULL, m_szVolume, SHERB_NOCONFIRMATION | SHERB_NOPROGRESSUI | SHERB_NOSOUND);
// call back to be nice
if (picb)
{
picb->PurgeProgress(qinfo.i64Size, qinfo.i64Size, EVCCBF_LASTNOTIFICATION, NULL);
}
return S_OK;
}
STDMETHODIMP CRecycleBinCleaner::ShowProperties(HWND hwnd)
{
LPITEMIDLIST pidlBitBuck = SHCloneSpecialIDList(hwnd, CSIDL_BITBUCKET, TRUE);
if (pidlBitBuck)
{
SHELLEXECUTEINFO ei;
FillExecInfo(ei, hwnd, c_szOpen, szNULL, NULL, szNULL, SW_NORMAL);
ei.fMask |= SEE_MASK_IDLIST;
ei.lpIDList = pidlBitBuck;
ShellExecuteEx(&ei);
ILFree(pidlBitBuck);
}
return S_OK;
}
STDMETHODIMP CRecycleBinCleaner::Deactivate(LPDWORD pdwFlags)
{
// whatever, nothing to deactivate
return S_OK;
}