7 Zip Uninstall
7 Zip Uninstall
c - 7-Zip Uninstaller
2022-07-15 : Igor Pavlov : Public domain */
#include "Precomp.h"
#ifdef _MSC_VER
#pragma warning(disable : 4201) // nonstandard extension used : nameless
struct/union
#pragma warning(disable : 4011) // vs2010: identifier truncated to
_CRT_SECURE_CPP_OVERLOAD_SECURE
#endif
#include <windows.h>
#include <ShlObj.h>
#include "../../7zVersion.h"
#include "resource.h"
// #define _64BIT_INSTALLER 1
#ifdef _WIN64
#define _64BIT_INSTALLER 1
#endif
#ifdef _64BIT_INSTALLER
// #define USE_7ZIP_32_DLL
#ifdef _WIN64
#define k_Reg_WOW_Flag_32 KEY_WOW64_32KEY
#else
#define k_Reg_WOW_Flag_32 0
#endif
// WINADVAPI
typedef LONG (APIENTRY *Func_RegDeleteKeyExW)(HKEY hKey, LPCWSTR lpSubKey, REGSAM
samDesired, DWORD Reserved);
static Func_RegDeleteKeyExW func_RegDeleteKeyExW;
#define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) -= 0x20 : (c)))
#ifdef USE_7ZIP_32_DLL
#endif
RegCloseKey(key);
// MyRegistry_DeleteKey(parentKey, k_Reg_Software_7zip);
}
}
if (SUCCEEDED(hres))
{
IPersistFile *pf;
if (SUCCEEDED(hres))
{
WCHAR s[MAX_PATH + 10];
hres = pf->lpVtbl->Load(pf, srcPath, TRUE);
pf->lpVtbl->Release(pf);
if (SUCCEEDED(hres))
{
hres = sl->lpVtbl->GetPath(sl, s, MAX_PATH, NULL, 0); // SLGP_RAWPATH
if (!AreStringsEqual_NoCase(s, targetPath))
hres = S_FALSE;
}
}
sl->lpVtbl->Release(sl);
}
return hres;
}
UNUSED_VAR(hwndOwner)
#else
unsigned i = (g_AllUsers ? 1 : 2);
link[0] = 0;
if (SHGetFolderPathW(hwndOwner,
i == 1 ? CSIDL_COMMON_PROGRAMS : CSIDL_PROGRAMS,
NULL, SHGFP_TYPE_CURRENT, link) != S_OK)
continue;
NormalizePrefix(link);
CatAscii(link, "7-Zip\\");
{
const size_t baseLen = wcslen(link);
unsigned k;
BoolInt needDelete = False;
if (needDelete)
{
link[baseLen] = 0;
RemoveDirectoryW(link);
}
}
}
#endif
}
{
unsigned i;
for (i = 0; i < ARRAY_SIZE(k_ShellEx_Items); i++)
{
WCHAR destPath[MAX_PATH];
CpyAscii(destPath, k_ShellEx_Items[i]);
CatAscii(destPath, "\\7-Zip");
MyRegistry_DeleteKey(HKEY_CLASSES_ROOT, destPath);
}
}
{
HKEY destKey = 0;
LONG res = MyRegistry_OpenKey_ReadWrite(HKEY_LOCAL_MACHINE,
k_Shell_Approved, &destKey);
if (res == ERROR_SUCCESS)
{
RegDeleteValueW(destKey, k_7zip_CLSID);
/* res = */ RegCloseKey(destKey);
}
}
}
}
#ifdef USE_7ZIP_32_DLL
{
unsigned i;
for (i = 0; i < ARRAY_SIZE(k_ShellEx_Items); i++)
{
WCHAR destPath[MAX_PATH];
CpyAscii(destPath, k_ShellEx_Items[i]);
CatAscii(destPath, "\\7-Zip");
MyRegistry_DeleteKey_32(HKEY_CLASSES_ROOT, destPath);
}
}
{
HKEY destKey = 0;
LONG res = MyRegistry_OpenKey_ReadWrite_32(HKEY_LOCAL_MACHINE,
k_Shell_Approved, &destKey);
if (res == ERROR_SUCCESS)
{
RegDeleteValueW(destKey, k_7zip_CLSID);
/* res = */ RegCloseKey(destKey);
}
}
}
}
#endif
if (MyRegistry_QueryString2(HKEY_LOCAL_MACHINE, k_Uninstall_7zip,
L"UninstallString", s))
{
RemoveQuotes(s);
if (AreEqual_Path_PrefixName(s, path, kUninstallExe))
MyRegistry_DeleteKey(HKEY_LOCAL_MACHINE, k_Uninstall_7zip);
}
}
/*
static void RemoveQuotes(wchar_t *s)
{
const wchar_t *src = s;
for (;;)
{
wchar_t c = *src++;
if (c == '\"')
continue;
*s++ = c;
if (c == 0)
return;
}
}
*/
#ifdef USE_7ZIP_32_DLL
#define NUM_EXTRA_FILES_64BIT 1
#else
#define NUM_EXTRA_FILES_64BIT 0
#endif
if (!g_SilentMode)
{
ShowWindow(g_Progress_HWND, SW_SHOW);
ShowWindow(g_InfoLine_HWND, SW_SHOW);
SendMessage(g_Progress_HWND, PBM_SETRANGE32, 0, NUM_FILES);
}
{
unsigned i;
const char *curName = k_Names;
if (!g_SilentMode)
{
MSG msg;
// g_HWND
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (!IsDialogMessage(g_HWND, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (!g_HWND)
return 1;
}
// Sleep(1);
SendMessage(g_Progress_HWND, PBM_SETPOS, i, 0);
}
path[pathLen] = 0;
temp = path + pathLen;
if (i <= NUM_LANG_TXT_FILES)
CpyAscii(temp, k_Lang "\\");
{
WCHAR *dest = temp + wcslen(temp);
for (;;)
{
char c = *curName;
if (c == 0)
break;
curName++;
if (c == ' ')
break;
*dest++ = (Byte)c;
}
*dest = 0;
}
if (i < NUM_LANG_TXT_FILES)
CatAscii(temp, ".txt");
if (!g_SilentMode)
SetWindowTextW(g_InfoLine_HWND, temp);
{
DWORD attrib = GetFileAttributesW(path);
if (attrib == INVALID_FILE_ATTRIBUTES)
continue;
if (attrib & FILE_ATTRIBUTE_READONLY)
SetFileAttributesW(path, 0);
if (!DeleteFileW(path))
{
if (!RemoveFileAfterReboot())
{
winRes = GetLastError();
}
/*
else
needReboot = True;
*/
}
}
}
path[pathLen] = 0;
RemoveDir();
if (!g_SilentMode)
SendMessage(g_Progress_HWND, PBM_SETPOS, i, 0);
if (*curName == 0)
{
SetRegKey_Path();
WriteCLSID();
SetShellProgramsGroup(g_HWND);
if (!g_SilentMode)
SetWindowTextW(g_InfoLine_HWND, k_7zip_with_Ver L" is uninstalled");
}
}
if (winRes != 0)
res = SZ_ERROR_FAIL;
if (res == SZ_OK)
{
// if (!g_SilentMode && needReboot);
return 0;
}
if (!g_SilentMode)
{
WCHAR m[MAX_PATH + 100];
m[0] = 0;
if (winRes == 0 || !GetErrorMessage(winRes, m))
CpyAscii(m, "ERROR");
PrintErrorMessage("System ERROR:", m);
}
return 1;
}
static INT_PTR CALLBACK MyDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
UNUSED_VAR(lParam)
switch (message)
{
case WM_INITDIALOG:
g_Path_HWND = GetDlgItem(hwnd, IDE_EXTRACT_PATH);
g_InfoLine_HWND = GetDlgItem(hwnd, IDT_CUR_FILE);
g_Progress_HWND = GetDlgItem(hwnd, IDC_PROGRESS);
SetWindowTextW(hwnd, k_7zip_with_Ver_Uninstall);
SetDlgItemTextW(hwnd, IDE_EXTRACT_PATH, path);
ShowWindow(g_Progress_HWND, SW_HIDE);
ShowWindow(g_InfoLine_HWND, SW_HIDE);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
{
if (g_Finished)
{
OnClose();
break;
}
if (!g_Install_was_Pressed)
{
SendMessage(hwnd, WM_NEXTDLGCTL, (WPARAM)(void *)GetDlgItem(hwnd,
IDCANCEL), TRUE);
EnableWindow(g_Path_HWND, FALSE);
EnableWindow(GetDlgItem(hwnd, IDOK), FALSE);
g_Install_was_Pressed = True;
return TRUE;
}
break;
}
case IDCANCEL:
{
OnClose();
break;
}
case WM_CLOSE:
OnClose();
break;
/*
case WM_DESTROY:
PostQuitMessage(0);
return TRUE;
*/
default:
return FALSE;
}
return TRUE;
}
UNUSED_VAR(hPrevInstance)
UNUSED_VAR(lpCmdLine)
UNUSED_VAR(nCmdShow)
#ifndef UNDER_CE
CoInitialize(NULL);
#endif
#ifndef UNDER_CE
func_RegDeleteKeyExW = (Func_RegDeleteKeyExW)
GetProcAddress(GetModuleHandleW(L"advapi32.dll"), "RegDeleteKeyExW");
#endif
{
const wchar_t *s = GetCommandLineW();
#ifndef UNDER_CE
s = GetCmdParam(s);
#endif
cmdParams = s;
for (;;)
{
{
wchar_t c = *s;
if (c == 0)
break;
if (c == ' ')
{
s++;
continue;
}
}
{
const wchar_t *s2 = GetCmdParam(s);
BoolInt error = True;
if (cmd[0] == '/')
{
if (cmd[1] == 'S')
{
if (cmd[2] == 0)
{
g_SilentMode = True;
error = False;
}
}
else if (cmd[1] == 'N')
{
if (cmd[2] == 0)
{
useTemp = False;
error = False;
}
}
else if (cmd[1] == 'D' && cmd[2] == '=')
{
wcscpy(workDir, cmd + 3);
// RemoveQuotes(workDir);
useTemp = False;
error = False;
}
}
s = s2;
if (error && cmdError[0] == 0)
wcscpy(cmdError, cmd);
}
}
if (cmdError[0] != 0)
{
if (!g_SilentMode)
PrintErrorMessage("Unsupported command:", cmdError);
return 1;
}
}
{
wchar_t *name;
DWORD len = GetModuleFileNameW(NULL, modulePath, MAX_PATH);
if (len == 0 || len > MAX_PATH)
return 1;
name = NULL;
wcscpy(modulePrefix, modulePath);
{
wchar_t *s = modulePrefix;
for (;;)
{
wchar_t c = *s++;
if (c == 0)
break;
if (c == WCHAR_PATH_SEPARATOR)
name = s;
}
}
if (!name)
return 1;
if (!AreStringsEqual_NoCase(name, kUninstallExe))
useTemp = False;
if (useTemp)
{
DWORD winRes = GetTempPathW(MAX_PATH, path);
{
wchar_t *s = path + wcslen(path);
UInt32 value = d;
unsigned k;
for (k = 0; k < 8; k++)
{
unsigned t = value & 0xF;
value >>= 4;
s[7 - k] = (wchar_t)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
}
s[k] = 0;
}
if (DoesFileOrDirExist())
continue;
if (CreateDirectoryW(path, NULL))
{
CatAscii(path, STRING_PATH_SEPARATOR);
wcscpy(tempPath, path);
break;
}
if (GetLastError() != ERROR_ALREADY_EXISTS)
break;
}
if (tempPath[0] != 0)
{
wcscpy(copyPath, tempPath);
CatAscii(copyPath, "Uninst.exe"); // we need not "Uninstall.exe" here
{
STARTUPINFOW si;
PROCESS_INFORMATION pi;
cmdLine[0] = 0;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
wcscpy(path, modulePrefix);
if (workDir[0] != 0)
{
wcscpy(path, workDir);
NormalizePrefix(path);
}
/*
if (path[0] == 0)
{
HKEY key = 0;
BoolInt ok = False;
LONG res = RegOpenKeyExW(HKEY_CURRENT_USER, k_Reg_Software_7zip, 0, KEY_READ |
k_Reg_WOW_Flag, &key);
if (res == ERROR_SUCCESS)
{
ok = MyRegistry_QueryString(key, k_Reg_Path32, path);
// ok = MyRegistry_QueryString(key, k_Reg_Path, path);
RegCloseKey(key);
}
}
*/
if (g_SilentMode)
return Install();
{
int retCode = 1;
g_HWND = CreateDialog(
hInstance,
// GetModuleHandle(NULL),
MAKEINTRESOURCE(IDD_INSTALL), NULL, MyDlgProc);
if (!g_HWND)
return 1;
{
HICON hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON));
// SendMessage(g_HWND, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)hIcon);
SendMessage(g_HWND, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)hIcon);
}
{
BOOL bRet;
MSG msg;
if (!IsDialogMessage(g_HWND, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (!g_HWND)
return retCode;
if (g_HWND)
{
DestroyWindow(g_HWND);
g_HWND = NULL;
}
}
return retCode;
}
}