Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

457 lines
9.9 KiB

/*++
Copyright (c) 2001 Microsoft Corporation
Module Name:
diskcleaner.c
Abstract:
Implements the code specific to the disk cleaner COM server.
Author:
Jim Schmidt (jimschm) 21-Jan-2001
Revision History:
<alias> <date> <comments>
--*/
#include "pch.h"
#include "undop.h"
#include "com.h"
/*++
Routine Descriptions:
This constructor is a generic class factory that supports multiple object
types. Upon creation, the object interface pointer ref count is set to zero,
and the global number of objects for the dll is incremented.
The destructor simply decrements the DLL object count.
Arguments:
None.
Return Value:
None.
--*/
CUninstallDiskCleaner::CUninstallDiskCleaner (
VOID
)
{
//
// -Initialize the interface pointer count
// -Increment the DLL's global count of objects
//
_References = 0;
g_DllObjects++;
}
CUninstallDiskCleaner::~CUninstallDiskCleaner (
VOID
)
{
g_DllObjects--;
}
STDMETHODIMP
CUninstallDiskCleaner::QueryInterface (
IN REFIID InterfaceIdRef,
OUT PVOID *InterfacePtr
)
{
HRESULT hr = S_OK;
DEBUGMSG ((DBG_VERBOSE, __FUNCTION__ ": Entering"));
__try {
//
// Initialize out arg
//
__try {
*InterfacePtr = NULL;
}
__except(EXCEPTION_EXECUTE_HANDLER) {
hr = E_INVALIDARG;
}
if (hr != S_OK) {
DEBUGMSG ((DBG_ERROR, __FUNCTION__ ": Invalid InterfacePtr arg"));
__leave;
}
//
// Test for the supported interface
//
if (IsEqualIID (InterfaceIdRef, IID_IUnknown)) {
DEBUGMSG ((DBG_VERBOSE, "Caller requested IUnknown"));
*InterfacePtr = (LPUNKNOWN) this;
AddRef();
__leave;
}
if (IsEqualIID (InterfaceIdRef, IID_IEmptyVolumeCache)) {
DEBUGMSG ((DBG_VERBOSE, "Caller requested IEmptyVolumeCache"));
*InterfacePtr = (IEmptyVolumeCache*) this;
AddRef();
__leave;
}
DEBUGMSG ((DBG_WARNING, "Caller requested unknown interface"));
hr = E_NOINTERFACE;
}
__finally {
}
DEBUGMSG ((DBG_VERBOSE, __FUNCTION__ ": Leaving"));
return hr;
}
/*++
Routine Description:
AddRef is the standard IUnknown member function that increments the object
reference count.
Release is the standard IUnknown member function that decrements the object
reference count.
Arguments:
None.
Return Value:
The number of interface references.
--*/
STDMETHODIMP_(ULONG)
CUninstallDiskCleaner::AddRef (
VOID
)
{
return ++_References;
}
STDMETHODIMP_(ULONG)
CUninstallDiskCleaner::Release (
VOID
)
{
if (!_References) {
DEBUGMSG ((DBG_ERROR, "Can't release because there are no references"));
} else {
_References--;
if (!_References) {
delete this;
return 0;
}
}
return _References;
}
STDMETHODIMP
CUninstallDiskCleaner::Initialize (
IN HKEY hRegKey,
IN PCWSTR VolumePath,
OUT PWSTR *DisplayName,
OUT PWSTR *Description,
IN OUT DWORD *Flags
)
/*++
Routine Description:
The Initialize member function does most of the work for the disk cleaner.
It evaluates the backup files, and if they all exist, and the user has the
right to execute an uninstall, and if they are at least 7 days old, then
show the backup items in the list box.
Arguments:
hRegKey - Specifies the registry key for this object, used to store
properties and settings
VolumePath - Specifies the volume path selected by the user when they launch
disk cleanup
DisplayName - Receives the name to put in the disk cleaner list box, or NULL
to use the name stored in the registry
Description - Receives the verbose description to put in the disk cleaner
Details text control, or NULL to use the description stored in the
registry
Flags - Specifies flags that influence the behavior of this disk cleaner
object and flags that indicate which mode the disk cleaner is running
in. Receivies flags that control how the disk cleaner displays this
object's info in its UI.
Return Value:
S_FALSE - The disk cleaner will skip this object
S_OK - The disk cleaner will include this object in its UI
--*/
{
HRESULT hr = S_FALSE;
DWORD inFlags;
ULONGLONG diskSpace;
UNINSTALLSTATUS status;
DEBUGMSG ((DBG_VERBOSE, __FUNCTION__ ": Entering"));
__try {
__try{
//
// Initialize
//
inFlags = *Flags;
*DisplayName = NULL; // use the display name stored in the registry
*Description = NULL; // use the description stored in the registry
*Flags = 0; // unchecked by default, no property page
}
__except(EXCEPTION_EXECUTE_HANDLER){
hr = E_INVALIDARG;
}
if (hr != S_OK) {
DEBUGMSG ((DBG_ERROR, __FUNCTION__ ": Invalid arg(s)"));
__leave;
}
_Purged = FALSE;
//
// Check undo files. If they are not at least 7 days old, don't
// recommend them to be deleted.
//
status = SanityCheck (FAIL_IF_NOT_OLD, VolumePath, &diskSpace);
if (status == Uninstall_NewImage) {
DEBUGMSG ((DBG_WARNING, "OS Backup Image is too new to be listed in the disk cleaner"));
__leave;
}
if (diskSpace == 0) {
DEBUGMSG ((DBG_WARNING, "OS Backup Image is not present, isn't valid, can't be removed, or has missing registry entries"));
__leave;
}
//
// Files are old enough and are present on the machine. Initialize the
// IEmptyVolumeCache interface
//
if (inFlags & EVCF_SETTINGSMODE) {
DEBUGMSG ((DBG_VERBOSE, "We don't support settings mode"));
__leave;
}
hr = S_OK;
DEBUGMSG ((DBG_VERBOSE, "Successful initialization"));
}
__finally {
}
DEBUGMSG ((DBG_VERBOSE, __FUNCTION__ ": Leaving"));
return hr;
}
STDMETHODIMP
CUninstallDiskCleaner::GetSpaceUsed (
OUT DWORDLONG *SpaceUsed,
IN IEmptyVolumeCacheCallBack *Callback
)
/*++
Routine Description:
GetSpaceUsed is called by the disk cleaner after this object has
successfully initialized. Our job is to return the amount of disk space we
can clean up. Since all undo files are on the same drive, we don't care
about the volume restriction passed to the Initialize member function.
Arguments:
SpaceUsed - Receives the amount of disk space that we can recover upon
deletion. We don't take into account cluster savings, but maybe we
should.
Callback - Specifies an object that provides a progress interface. We don't
use this.
Return Value:
S_FALSE - Failed to get disk space values
S_OK - Success
--*/
{
ULONGLONG diskSpace;
HRESULT hr = S_FALSE;
DEBUGMSG ((DBG_VERBOSE, __FUNCTION__ ": Entering"));
__try {
__try{
//
// Initialize
//
*SpaceUsed = 0;
}
__except(EXCEPTION_EXECUTE_HANDLER){
hr = E_INVALIDARG;
}
if (hr != S_OK) {
DEBUGMSG ((DBG_ERROR, __FUNCTION__ ": Invalid arg(s)"));
__leave;
}
if (SanityCheck (QUICK_CHECK, NULL, &diskSpace) == Uninstall_NewImage) {
DEBUGMSG ((DBG_ERROR, "Sanity check failed"));
__leave;
}
DEBUGMSG ((DBG_VERBOSE, "Disk space: %I64u", diskSpace));
*SpaceUsed = (DWORDLONG) diskSpace;
hr = S_OK;
}
__finally {
}
DEBUGMSG ((DBG_VERBOSE, __FUNCTION__ ": Leaving"));
return hr;
}
STDMETHODIMP
CUninstallDiskCleaner::Purge (
IN DWORDLONG SpaceToFree,
IN IEmptyVolumeCacheCallBack *Callback
)
/*++
Routine Description:
Purge does the deletion. We don't care about the inbound arguments. If we
are called, it is because Initialize succeeded, and GetSpaceUsed returned a
valid number. These two things mean it is OK to remove uninstall capability.
Arguments:
SpaceToFree - Specifies the space to free. We expect this to equal the
value provided in GetSpaceUsed.
Callback - Specifies an interface for progress updates. We don't use this.
Return Value:
S_OK - Success
S_FALSE - Failed
--*/
{
HRESULT hr = S_FALSE;
DEBUGMSG ((DBG_VERBOSE, __FUNCTION__ ": Entering"));
__try {
if (!DoCleanup()) {
__leave;
}
_Purged = TRUE;
hr = S_OK;
}
__finally {
}
DEBUGMSG ((DBG_VERBOSE, __FUNCTION__ ": Leaving"));
return hr;
}
//
// NO-OP property page stub
//
STDMETHODIMP
CUninstallDiskCleaner::ShowProperties (
IN HWND hwnd
)
{
MYASSERT (FALSE);
return S_FALSE;
}
STDMETHODIMP
CUninstallDiskCleaner::Deactivate (
OUT DWORD *Flags
)
/*++
Routine Description:
Deactivate indicates if the uninstall list item should be permanently
removed from the disk cleaner or not, based on a successful deletion of the
backup image.
Arguments:
Flags - Receives the indicator to remove the list item from the disk
cleaner list
Return Value:
Always S_OK
--*/
{
//
// Done -- if we deleted uninstall, remove the list item
//
if(!Flags){
MYASSERT(FALSE);
return E_INVALIDARG;
}
*Flags = _Purged ? EVCF_REMOVEFROMLIST : 0;
return S_OK;
}