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:
parent
2fa5cd37b8
commit
821b4d6a18
8 changed files with 41 additions and 21 deletions
|
@ -12,6 +12,8 @@ Released on ? ?th, 2020
|
||||||
|
|
||||||
\S2{} Major Changes
|
\S2{} Major Changes
|
||||||
|
|
||||||
|
\b \cw{DeleteRegKey /ifempty} now also checks for values, not just subkeys. Use \cw{/ifnosubkeys} for the old behavior.
|
||||||
|
|
||||||
\b Added \R{getknownfolderpath}{GetKnownFolderPath}
|
\b Added \R{getknownfolderpath}{GetKnownFolderPath}
|
||||||
|
|
||||||
\S2{} Minor Changes
|
\S2{} Minor Changes
|
||||||
|
|
|
@ -29,9 +29,9 @@ Deletes the string str_name from section [section_name] from ini_filename. If th
|
||||||
|
|
||||||
\S2{deleteregkey} DeleteRegKey
|
\S2{deleteregkey} DeleteRegKey
|
||||||
|
|
||||||
\c [/ifempty] root_key subkey
|
\c [/ifempty | /ifnosubkeys | /ifnovalues] root_key subkey
|
||||||
|
|
||||||
Deletes a registry key. If /ifempty is specified, the registry key will only be deleted if it has no subkeys (otherwise, the whole registry tree will be removed). Valid values for root_key are listed under \R{writeregstr}{WriteRegStr}. The error flag is set if the key could not be removed from the registry (or if it didn't exist to begin with).
|
Deletes a registry key. If /ifempty is specified, the registry key will only be deleted if it has no subkeys and no values (otherwise, the whole registry tree will be removed). Valid values for root_key are listed under \R{writeregstr}{WriteRegStr}. The error flag is set if the key could not be removed from the registry (or if it didn't exist to begin with).
|
||||||
|
|
||||||
\c DeleteRegKey HKLM "Software\My Company\My Software"
|
\c DeleteRegKey HKLM "Software\My Company\My Software"
|
||||||
\c DeleteRegKey /ifempty HKLM "Software\A key that might have subkeys"
|
\c DeleteRegKey /ifempty HKLM "Software\A key that might have subkeys"
|
||||||
|
|
|
@ -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
|
// 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.
|
// one and only native key. Our RegKeyOpen will intentionally fail if a incompatible WoW64 flag is used.
|
||||||
#define DRTF_ONLYIFNOSUBKEYS DELREGKEY_ONLYIFNOSUBKEYS
|
#define DRTF_ONLYIFNOSUBKEYS DELREGKEY_ONLYIFNOSUBKEYS
|
||||||
|
#define DRTF_ONLYIFNOVALUES DELREGKEY_ONLYIFNOVALUES
|
||||||
static LONG NSISCALL DeleteRegTree(HKEY hThisKey, LPCTSTR SubKey, REGSAM SamviewAndFlags)
|
static LONG NSISCALL DeleteRegTree(HKEY hThisKey, LPCTSTR SubKey, REGSAM SamviewAndFlags)
|
||||||
{
|
{
|
||||||
HKEY hKey;
|
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);
|
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)
|
if (retval == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
TCHAR child[MAX_PATH+1]; // NB - don't change this to static (recursive function)
|
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)
|
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;
|
if ((retval = DeleteRegTree(hKey, child, SamviewAndFlags)) != ERROR_SUCCESS) break;
|
||||||
}
|
}
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
{
|
{
|
||||||
typedef LONG (WINAPI * RegDeleteKeyExPtr)(HKEY, LPCTSTR, REGSAM, DWORD);
|
typedef LONG (WINAPI * RegDeleteKeyExType)(HKEY, LPCTSTR, REGSAM, DWORD);
|
||||||
RegDeleteKeyExPtr RDKE = (RegDeleteKeyExPtr)
|
RegDeleteKeyExType RDKE = (RegDeleteKeyExType)
|
||||||
#ifdef _WIN64
|
#if !defined(_WIN64) || defined(_M_IA64)
|
||||||
RegDeleteKeyEx;
|
|
||||||
#else
|
|
||||||
myGetProcAddress(MGA_RegDeleteKeyEx);
|
myGetProcAddress(MGA_RegDeleteKeyEx);
|
||||||
#endif
|
if (!RDKE)
|
||||||
if (RDKE)
|
|
||||||
retval = RDKE(hThisKey, SubKey, samview, 0);
|
|
||||||
else
|
|
||||||
retval = RegDeleteKey(hThisKey, SubKey);
|
retval = RegDeleteKey(hThisKey, SubKey);
|
||||||
|
else
|
||||||
|
#else
|
||||||
|
RegDeleteKeyEx;
|
||||||
|
#endif
|
||||||
|
retval = RDKE(hThisKey, SubKey, samview, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
@ -550,8 +550,9 @@ typedef struct {
|
||||||
#define HKLMANY MAKEREGROOTVIEW(HKEY_LOCAL_MACHINE, REGROOTVIEW32|REGROOTVIEW64)
|
#define HKLMANY MAKEREGROOTVIEW(HKEY_LOCAL_MACHINE, REGROOTVIEW32|REGROOTVIEW64)
|
||||||
#define DELREG_VALUE 0 // TOK_DELETEREGVALUE
|
#define DELREG_VALUE 0 // TOK_DELETEREGVALUE
|
||||||
#define DELREG_KEY 1 // TOK_DELETEREGKEY
|
#define DELREG_KEY 1 // TOK_DELETEREGKEY
|
||||||
#define DELREGKEY_ONLYIFNOSUBKEYS 1 // Shifted and stored as 2 in the binary for compatibility with <= 3.1
|
#define DELREGKEY_ONLYIFNOSUBKEYS 0x01 // Note: Shifted (stored as 2 in the binary) for compatibility with <= v3.1
|
||||||
#define DELREGKEYFLAGSSHIFT 1 // parm4 is shifted so exehead can remove the DELREG_KEY bit
|
#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
|
#ifdef NSIS_SUPPORT_CREATESHORTCUT
|
||||||
|
|
|
@ -1166,6 +1166,8 @@ struct MGA_FUNC MGA_FUNCS[] = {
|
||||||
#ifndef _WIN64
|
#ifndef _WIN64
|
||||||
{"KERNEL32", "GetDiskFreeSpaceExW"},
|
{"KERNEL32", "GetDiskFreeSpaceExW"},
|
||||||
{"KERNEL32", "GetUserDefaultUILanguage"},
|
{"KERNEL32", "GetUserDefaultUILanguage"},
|
||||||
|
#endif
|
||||||
|
#if !defined(_WIN64) || defined(_M_IA64)
|
||||||
{"ADVAPI32", "RegDeleteKeyExW"},
|
{"ADVAPI32", "RegDeleteKeyExW"},
|
||||||
#endif
|
#endif
|
||||||
{"ADVAPI32", "InitiateShutdownW"},
|
{"ADVAPI32", "InitiateShutdownW"},
|
||||||
|
|
|
@ -164,6 +164,8 @@ enum myGetProcAddressFunctions {
|
||||||
#ifndef _WIN64
|
#ifndef _WIN64
|
||||||
MGA_GetDiskFreeSpaceEx,
|
MGA_GetDiskFreeSpaceEx,
|
||||||
MGA_GetUserDefaultUILanguage,
|
MGA_GetUserDefaultUILanguage,
|
||||||
|
#endif
|
||||||
|
#if !defined(_WIN64) || defined(_M_IA64)
|
||||||
MGA_RegDeleteKeyEx,
|
MGA_RegDeleteKeyEx,
|
||||||
#endif
|
#endif
|
||||||
MGA_InitiateShutdown,
|
MGA_InitiateShutdown,
|
||||||
|
|
|
@ -4319,11 +4319,15 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
|
||||||
int a=1, iskeyop;
|
int a=1, iskeyop;
|
||||||
if ((iskeyop = which_token == TOK_DELETEREGKEY))
|
if ((iskeyop = which_token == TOK_DELETEREGKEY))
|
||||||
{
|
{
|
||||||
TCHAR *s=line.gettoken_str(a);
|
for (;; ++a)
|
||||||
if (s[0] == _T('/'))
|
|
||||||
{
|
{
|
||||||
if (_tcsicmp(s,_T("/ifempty"))) PRINTHELP()
|
switch(line.gettoken_enum(a,_T("/ifempty\0/ifnosubkeys\0/ifnovalues\0")))
|
||||||
a++, ent.offsets[4]|=(DELREGKEY_ONLYIFNOSUBKEYS<<DELREGKEYFLAGSSHIFT);
|
{
|
||||||
|
case 0: ent.offsets[4]|=((DELREGKEY_ONLYIFNOSUBKEYS|DELREGKEY_ONLYIFNOVALUES)<<DELREGKEYFLAGSSHIFT); continue;
|
||||||
|
case 1: ent.offsets[4]|=((DELREGKEY_ONLYIFNOSUBKEYS )<<DELREGKEYFLAGSSHIFT); continue;
|
||||||
|
case 2: ent.offsets[4]|=(( DELREGKEY_ONLYIFNOVALUES)<<DELREGKEYFLAGSSHIFT); continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (line.gettoken_str(a+2)[0]) PRINTHELP()
|
if (line.gettoken_str(a+2)[0]) PRINTHELP()
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ static tokenType tokenlist[TOK__LAST] =
|
||||||
{TOK_DBOPTIMIZE,_T("SetDatablockOptimize"),1,0,_T("(off|on)"),TP_ALL},
|
{TOK_DBOPTIMIZE,_T("SetDatablockOptimize"),1,0,_T("(off|on)"),TP_ALL},
|
||||||
{TOK_DELETEINISEC,_T("DeleteINISec"),2,0,_T("ini_file section_name"),TP_CODE},
|
{TOK_DELETEINISEC,_T("DeleteINISec"),2,0,_T("ini_file section_name"),TP_CODE},
|
||||||
{TOK_DELETEINISTR,_T("DeleteINIStr"),3,0,_T("ini_file section_name entry_name"),TP_CODE},
|
{TOK_DELETEINISTR,_T("DeleteINIStr"),3,0,_T("ini_file section_name entry_name"),TP_CODE},
|
||||||
{TOK_DELETEREGKEY,_T("DeleteRegKey"),2,1,_T("[/ifempty] root_key subkey\n root_key=(HKCR[32|64]|HKLM[32|64]|HKCU[32|64]|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
|
{TOK_DELETEREGKEY,_T("DeleteRegKey"),2,-1,_T("[/ifempty | /ifnosubkeys | /ifnovalues] root_key subkey\n root_key=(HKCR[32|64]|HKLM[32|64]|HKCU[32|64]|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
|
||||||
{TOK_DELETEREGVALUE,_T("DeleteRegValue"),3,0,_T("root_key subkey entry_name\n root_key=(HKCR[32|64]|HKLM[32|64]|HKCU[32|64]|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
|
{TOK_DELETEREGVALUE,_T("DeleteRegValue"),3,0,_T("root_key subkey entry_name\n root_key=(HKCR[32|64]|HKLM[32|64]|HKCU[32|64]|HKU|HKCC|HKDD|HKPD|SHCTX)"),TP_CODE},
|
||||||
{TOK_DELETE,_T("Delete"),1,1,_T("[/REBOOTOK] filespec"),TP_CODE},
|
{TOK_DELETE,_T("Delete"),1,1,_T("[/REBOOTOK] filespec"),TP_CODE},
|
||||||
{TOK_DETAILPRINT,_T("DetailPrint"),1,0,_T("message"),TP_CODE},
|
{TOK_DETAILPRINT,_T("DetailPrint"),1,0,_T("message"),TP_CODE},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue