#include "stdafx.h"
#include "cleanup_interface.h"
#include <string> // Delete_DesktopRunHistory()
#include <wininet.h> // DeleteUrlCacheEntry etc
#include <UrlHist.h> // IUrlHistoryStg2
#include "shlobj.h" // CLSID_CUrlHistory, SHAddToRecentDocs
#include "shellapi.h" // SHEmptyRecycleBin
#include "tchar.h" // _T macro
using namespace std;
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call,
LPVOID lpReserved)
{
return TRUE;
}
__declspec( dllexport ) BOOL Delete_IECache(BOOL bDeleteCache,
BOOL bDeleteCacheIndex)
{
TCHAR szUserProfile[200];
TCHAR szFilePath[200];
HANDLE hCacheEnumHandle = NULL;
LPINTERNET_CACHE_ENTRY_INFO lpCacheEntry = NULL;
DWORD dwSize = 4096; // initial buffer size
// Delete index.dat if requested. Be sure that index.dat is not locked.
if(bDeleteCacheIndex)
{
// Retrieve from environment user profile path.
ExpandEnvironmentStrings("%userprofile%", szUserProfile,
sizeof(szUserProfile));
wsprintf(szFilePath, "%s%s", szUserProfile,
"\\Local Settings\\Temporary Internet Files\\Content.IE5\\index.dat");
DeleteFile(szFilePath);
if(!bDeleteCache) return TRUE;
}
// Enable initial buffer size for cache entry structure.
lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) new char[dwSize];
lpCacheEntry->dwStructSize = dwSize;
// URL search pattern (1st parameter) options are: NULL ("*.*"), "cookie:",
// or "visited:".
hCacheEnumHandle = FindFirstUrlCacheEntry(NULL /* in */,
lpCacheEntry /* out */, &dwSize /* in, out */);
// First, obtain handle to internet cache with FindFirstUrlCacheEntry
// for later use with FindNextUrlCacheEntry.
if(hCacheEnumHandle != NULL)
{
// When cache entry is not a cookie, delete entry.
if (!(lpCacheEntry->CacheEntryType & COOKIE_CACHE_ENTRY))
{
DeleteUrlCacheEntry(lpCacheEntry->lpszSourceUrlName);
}
}
else
{
switch(GetLastError())
{
case ERROR_INSUFFICIENT_BUFFER:
lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) new char[dwSize];
lpCacheEntry->dwStructSize = dwSize;
// Repeat first step search with adjusted buffer, exit if not
// found again (in practice one buffer's size adustment is
// always OK).
hCacheEnumHandle = FindFirstUrlCacheEntry(NULL, lpCacheEntry,
&dwSize);
if(hCacheEnumHandle != NULL)
{
// When cache entry is not a cookie, delete entry.
if (!(lpCacheEntry->CacheEntryType & COOKIE_CACHE_ENTRY))
{
DeleteUrlCacheEntry(lpCacheEntry->lpszSourceUrlName);
}
break;
}
else
{
// FindFirstUrlCacheEntry fails again, return.
return FALSE;
}
default:
FindCloseUrlCache(hCacheEnumHandle);
return FALSE;
}
}
// Next, use hCacheEnumHandle obtained from the previous step to delete
// subsequent items of the cache.
do
{
// Notice that return values of FindNextUrlCacheEntry (BOOL) and
// FindFirstUrlCacheEntry (HANDLE) are different.
if(FindNextUrlCacheEntry(hCacheEnumHandle, lpCacheEntry, &dwSize))
{
// When cache entry is not a cookie, delete entry.
if (!(lpCacheEntry->CacheEntryType & COOKIE_CACHE_ENTRY))
{
DeleteUrlCacheEntry(lpCacheEntry->lpszSourceUrlName);
}
}
else
{
switch(GetLastError())
{
case ERROR_INSUFFICIENT_BUFFER:
lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO)
new char[dwSize];
lpCacheEntry->dwStructSize = dwSize;
// Repeat next step search with adjusted buffer, exit if
// error comes up again ((in practice one buffer's size
// adustment is always OK).
if(FindNextUrlCacheEntry(hCacheEnumHandle, lpCacheEntry,
&dwSize))
{
// When cache entry is not a cookie, delete entry.
if (!(lpCacheEntry->CacheEntryType & COOKIE_CACHE_ENTRY))
{
DeleteUrlCacheEntry(lpCacheEntry->lpszSourceUrlName);
}
break;
}
else
{
// FindFirstUrlCacheEntry fails again, return.
FindCloseUrlCache(hCacheEnumHandle);
return FALSE;
}
break;
case ERROR_NO_MORE_ITEMS:
FindCloseUrlCache(hCacheEnumHandle);
return TRUE;
default:
FindCloseUrlCache(hCacheEnumHandle);
return FALSE;
}
}
} while (TRUE);
return FALSE; // never here
}
__declspec( dllexport ) BOOL Delete_IECookies(BOOL bDeleteCookies,
BOOL bDeleteCookiesIndex)
{
TCHAR szUserProfile[200];
TCHAR szFilePath[200];
HANDLE hCacheEnumHandle = NULL;
LPINTERNET_CACHE_ENTRY_INFO lpCacheEntry = NULL;
DWORD dwSize = 4096; // initial buffer size
// Delete index.dat if requested. Be sure that index.dat is not locked.
if(bDeleteCookiesIndex)
{
// Retrieve from environment user profile path.
ExpandEnvironmentStrings("%userprofile%", szUserProfile,
sizeof(szUserProfile));
wsprintf(szFilePath, "%s%s", szUserProfile, "\\Cookies\\index.dat");
DeleteFile(szFilePath);
if(!bDeleteCookies) return TRUE;
}
// Enable initial buffer size for cache entry structure.
lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) new char[dwSize];
lpCacheEntry->dwStructSize = dwSize;
// URL search pattern (1st parameter) options are: "cookie:", "visited:",
// or NULL ("*.*").
hCacheEnumHandle = FindFirstUrlCacheEntry(_T("cookie:") /* in */,
lpCacheEntry /* out */, &dwSize /* in, out */);
// First, obtain handle to internet cache with FindFirstUrlCacheEntry
// for late use with FindNextUrlCacheEntry.
if(hCacheEnumHandle != NULL)
{
DeleteUrlCacheEntry(lpCacheEntry->lpszSourceUrlName);
}
else
{
switch(GetLastError())
{
case ERROR_INSUFFICIENT_BUFFER:
lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO) new char[dwSize];
lpCacheEntry->dwStructSize = dwSize;
// Repeat first step search with adjusted buffer, exit if not
// found again (in practice one buffer's size adustment is
// always OK).
hCacheEnumHandle = FindFirstUrlCacheEntry(NULL, lpCacheEntry,
&dwSize);
if(hCacheEnumHandle != NULL)
{
DeleteUrlCacheEntry(lpCacheEntry->lpszSourceUrlName);
break;
}
else
{
// FindFirstUrlCacheEntry fails again, return.
return FALSE;
}
default:
FindCloseUrlCache(hCacheEnumHandle);
return FALSE;
}
}
// Next, use hCacheEnumHandle obtained from the previous step to delete
// subsequent items of cache.
do
{
// Notice that return values of FindNextUrlCacheEntry (BOOL) and
// FindFirstUrlCacheEntry (HANDLE) are different.
if(FindNextUrlCacheEntry(hCacheEnumHandle, lpCacheEntry, &dwSize))
{
DeleteUrlCacheEntry(lpCacheEntry->lpszSourceUrlName);
}
else
{
switch(GetLastError())
{
case ERROR_INSUFFICIENT_BUFFER:
lpCacheEntry = (LPINTERNET_CACHE_ENTRY_INFO)
new char[dwSize];
lpCacheEntry->dwStructSize = dwSize;
// Repeat next step search with adjusted buffer, exit if
// error comes up again ((in practice one buffer's size
// adustment is always OK).
if(FindNextUrlCacheEntry(hCacheEnumHandle, lpCacheEntry,
&dwSize))
{
DeleteUrlCacheEntry(lpCacheEntry->lpszSourceUrlName);
break;
}
else
{
// FindFirstUrlCacheEntry fails again, return.
FindCloseUrlCache(hCacheEnumHandle);
return FALSE;
}
break;
case ERROR_NO_MORE_ITEMS:
FindCloseUrlCache(hCacheEnumHandle);
return TRUE;
default:
FindCloseUrlCache(hCacheEnumHandle);
return FALSE;
}
}
} while (TRUE);
return FALSE; // never here
}
__declspec( dllexport ) HRESULT Delete_IEHistory(BOOL bDeleteHistory,
BOOL bDeleteHistoryIndex)
{
TCHAR szUserProfile[200];
TCHAR szFilePath[200];
HRESULT hr;
// Delete index.dat if requested. Be sure that index.dat is not locked.
if(bDeleteHistoryIndex)
{
// Retrieve from environment user profile path.
ExpandEnvironmentStrings("%userprofile%", szUserProfile,
sizeof(szUserProfile));
wsprintf(szFilePath, "%s%s", szUserProfile,
"\\Local Settings\\History\\History.IE5\\index.dat");
DeleteFile(szFilePath);
if (!bDeleteHistory) return S_OK;
}
CoInitialize(NULL);
IUrlHistoryStg2* pUrlHistoryStg2 = NULL;
hr = CoCreateInstance(CLSID_CUrlHistory, NULL, CLSCTX_INPROC,
IID_IUrlHistoryStg2, (void**)&pUrlHistoryStg2);
if (SUCCEEDED(hr))
{
hr = pUrlHistoryStg2->ClearHistory();
pUrlHistoryStg2->Release();
}
CoUninitialize();
return hr;
}
__declspec( dllexport ) void Delete_IEAddressBarHistory()
{
HKEY hKey;
DWORD dwResult;
TCHAR szValueName[10];
// Open TypedURLs key.
dwResult = RegOpenKey(HKEY_CURRENT_USER,
"Software\\Microsoft\\Internet Explorer\\TypedURLs", &hKey);
int i = 1; wsprintf(szValueName, "url%d", i);
while(RegDeleteValue(hKey, szValueName) == ERROR_SUCCESS)
{
i++; wsprintf(szValueName, "url%d", i);
}
RegCloseKey(hKey);
}
__declspec( dllexport ) void Delete_DesktopRecentDocsHistory()
{
SHAddToRecentDocs(SHARD_PATH, NULL /* NULL clears history */);
}
// Note: actually, effect of running Delete_DesktopRunHistory is
// visible after reboot.
__declspec( dllexport ) void Delete_DesktopRunHistory()
{
HKEY hKey;
DWORD dwResult;
TCHAR szValueName[10];
string c, s;
s = "abcdefghijklmnopqrstuvwxyz";
int i;
// Open RunMRU key.
dwResult = RegOpenKey(HKEY_CURRENT_USER,
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU",
&hKey );
// Traverse all possible values and delete. This guarantees deletion
// even if the sequence in broken.
for(i = 0; i < 26 /* z */; i++)
{
c = s.at(i); wsprintf(szValueName, "%s", c.c_str());
RegDeleteValue(hKey, szValueName);
}
RegDeleteValue(hKey, _T("MRUList"));
RegCloseKey(hKey);
}
__declspec( dllexport ) void Delete_DesktopRecycleBinContents()
{
SHEmptyRecycleBin(NULL, NULL,
SHERB_NOCONFIRMATION | SHERB_NOPROGRESSUI | SHERB_NOSOUND);
}