DeleteRegKey /ifempty now also checks for values

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@7166 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2020-04-12 18:25:21 +00:00
parent 2fa5cd37b8
commit 821b4d6a18
8 changed files with 41 additions and 21 deletions

View file

@ -176,33 +176,42 @@ static HKEY NSISCALL RegCreateScriptKey(int RootKey, LPCTSTR SubKey, REGSAM RS)
// RegDeleteKeyEx on 32-bit Windows accepts but ignores the KEY_WOW64_xxKEY flags and always uses the
// one and only native key. Our RegKeyOpen will intentionally fail if a incompatible WoW64 flag is used.
#define DRTF_ONLYIFNOSUBKEYS DELREGKEY_ONLYIFNOSUBKEYS
#define DRTF_ONLYIFNOVALUES DELREGKEY_ONLYIFNOVALUES
static LONG NSISCALL DeleteRegTree(HKEY hThisKey, LPCTSTR SubKey, REGSAM SamviewAndFlags)
{
HKEY hKey;
UINT onlyifempty = SamviewAndFlags & DRTF_ONLYIFNOSUBKEYS;
UINT onlyifnosubkeys = SamviewAndFlags & DRTF_ONLYIFNOSUBKEYS;
UINT onlyifnovalues = SamviewAndFlags & DRTF_ONLYIFNOVALUES, valuesexistcheckinsubkeys = TRUE;
REGSAM samview = SamviewAndFlags & (KEY_WOW64_32KEY|KEY_WOW64_64KEY);
LONG retval = RegKeyOpen(hThisKey, SubKey, KEY_ENUMERATE_SUB_KEYS|samview, &hKey);
LONG retval = RegKeyOpen(hThisKey, SubKey, KEY_ENUMERATE_SUB_KEYS|KEY_QUERY_VALUE|samview, &hKey);
if (retval == ERROR_SUCCESS)
{
TCHAR child[MAX_PATH+1]; // NB - don't change this to static (recursive function)
if (onlyifnovalues)
{
DWORD cchName = 0;
retval = RegEnumValue(hKey, 0, child, &cchName, NULL, NULL, NULL, NULL);
if (retval != ERROR_NO_MORE_ITEMS) goto notempty;
if (!valuesexistcheckinsubkeys) SamviewAndFlags &= ~DRTF_ONLYIFNOVALUES;
}
while (RegEnumKey(hKey, 0, child, COUNTOF(child)) == ERROR_SUCCESS)
{
if (onlyifempty) return (RegCloseKey(hKey), ERROR_CAN_NOT_COMPLETE);
if (onlyifnosubkeys) notempty: return (RegCloseKey(hKey), ERROR_CAN_NOT_COMPLETE);
if ((retval = DeleteRegTree(hKey, child, SamviewAndFlags)) != ERROR_SUCCESS) break;
}
RegCloseKey(hKey);
{
typedef LONG (WINAPI * RegDeleteKeyExPtr)(HKEY, LPCTSTR, REGSAM, DWORD);
RegDeleteKeyExPtr RDKE = (RegDeleteKeyExPtr)
#ifdef _WIN64
RegDeleteKeyEx;
#else
typedef LONG (WINAPI * RegDeleteKeyExType)(HKEY, LPCTSTR, REGSAM, DWORD);
RegDeleteKeyExType RDKE = (RegDeleteKeyExType)
#if !defined(_WIN64) || defined(_M_IA64)
myGetProcAddress(MGA_RegDeleteKeyEx);
#endif
if (RDKE)
retval = RDKE(hThisKey, SubKey, samview, 0);
else
if (!RDKE)
retval = RegDeleteKey(hThisKey, SubKey);
else
#else
RegDeleteKeyEx;
#endif
retval = RDKE(hThisKey, SubKey, samview, 0);
}
}
return retval;

View file

@ -550,8 +550,9 @@ typedef struct {
#define HKLMANY MAKEREGROOTVIEW(HKEY_LOCAL_MACHINE, REGROOTVIEW32|REGROOTVIEW64)
#define DELREG_VALUE 0 // TOK_DELETEREGVALUE
#define DELREG_KEY 1 // TOK_DELETEREGKEY
#define DELREGKEY_ONLYIFNOSUBKEYS 1 // Shifted and stored as 2 in the binary for compatibility with <= 3.1
#define DELREGKEYFLAGSSHIFT 1 // parm4 is shifted so exehead can remove the DELREG_KEY bit
#define DELREGKEY_ONLYIFNOSUBKEYS 0x01 // Note: Shifted (stored as 2 in the binary) for compatibility with <= v3.1
#define DELREGKEY_ONLYIFNOVALUES 0x02
#define DELREGKEYFLAGSSHIFT 1 // exehead removes the DELREG_KEY bit in parm4 by shifting. After shifting the bits are DELREGKEY_*.
#ifdef NSIS_SUPPORT_CREATESHORTCUT

View file

@ -1166,6 +1166,8 @@ struct MGA_FUNC MGA_FUNCS[] = {
#ifndef _WIN64
{"KERNEL32", "GetDiskFreeSpaceExW"},
{"KERNEL32", "GetUserDefaultUILanguage"},
#endif
#if !defined(_WIN64) || defined(_M_IA64)
{"ADVAPI32", "RegDeleteKeyExW"},
#endif
{"ADVAPI32", "InitiateShutdownW"},

View file

@ -164,6 +164,8 @@ enum myGetProcAddressFunctions {
#ifndef _WIN64
MGA_GetDiskFreeSpaceEx,
MGA_GetUserDefaultUILanguage,
#endif
#if !defined(_WIN64) || defined(_M_IA64)
MGA_RegDeleteKeyEx,
#endif
MGA_InitiateShutdown,