https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b62948ef774538fb5066e…
commit b62948ef774538fb5066e88c3b92ce2010bd842c
Author: Oleg Dubinskiy <oleg.dubinskij2013(a)yandex.ua>
AuthorDate: Wed Sep 16 17:54:20 2020 +0300
Commit: Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Sun Sep 20 19:23:06 2020 +0200
[RAPPS] Use `RegDeleteKeyExW` for deleting the apps strings from registry only if it is available in advapi32
Otherwise, use `RegDeleteKeyW` instead, on Windows versions whose don't have the Ex function (XP SP3 x32, Server 2003 SP0 and earlier).
It will fix regression with Rapps startup there, due to that missing function.
CORE-17264
---
base/applications/rapps/installed.cpp | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/base/applications/rapps/installed.cpp b/base/applications/rapps/installed.cpp
index 4179334a60a..5296c3fc6ae 100644
--- a/base/applications/rapps/installed.cpp
+++ b/base/applications/rapps/installed.cpp
@@ -141,16 +141,34 @@ BOOL CInstalledApplicationInfo::UninstallApplication(BOOL bModify)
return StartProcess(bModify ? szModifyPath : szUninstallString, TRUE);
}
+typedef LSTATUS (WINAPI *RegDeleteKeyExWProc)(HKEY, LPCWSTR, REGSAM, DWORD);
+
LSTATUS CInstalledApplicationInfo::RemoveFromRegistry()
{
ATL::CStringW szFullName = L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + szKeyName;
+ HMODULE hMod = GetModuleHandleW(L"advapi32.dll");
+ RegDeleteKeyExWProc pRegDeleteKeyExW;
- // TODO: if there are subkeys inside, simply RegDeleteKeyExW will fail
+ // TODO: if there are subkeys inside, simply RegDeleteKeyExW
+ // (or RegDeleteKeyW on Server 2003 SP0 and earlier) will fail
// we don't have RegDeleteTree for ReactOS now. (It's a WinVista API)
// write a function to delete all subkeys recursively to solve this
// or consider letting ReactOS having this API
- return RegDeleteKeyExW(IsUserKey ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, szFullName, WowKey, 0);
+ /* Load RegDeleteKeyExW from advapi32.dll if available */
+ if (hMod)
+ {
+ pRegDeleteKeyExW = (RegDeleteKeyExWProc)GetProcAddress(hMod, "RegDeleteKeyExW");
+
+ if (pRegDeleteKeyExW)
+ {
+ /* Return it */
+ return pRegDeleteKeyExW(IsUserKey ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, szFullName, WowKey, 0);
+ }
+ }
+
+ /* Otherwise, return non-Ex function */
+ return RegDeleteKeyW(IsUserKey ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, szFullName);
}
BOOL CInstalledApps::Enum(INT EnumType, APPENUMPROC lpEnumProc, PVOID param)
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5d5a1a455c9e8b158e4c6…
commit 5d5a1a455c9e8b158e4c6f4c51a1ee20e0da95f0
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sat Jul 4 22:22:07 2020 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sat Sep 19 19:44:56 2020 +0200
[CMD] FOR: Fix a bug when parsing the "delims=" option in FOR loops.
Suppose the following FOR-loop command, to be run from the command-line
(if using a batch file, double each percent '%' sign):
FOR %l IN ("a,b,c,d,e" "f,g,h,i,j") DO (
FOR /F "delims=, tokens=1-3*" %a IN (%l) DO @echo %a-%b-%c-%d
)
The outermost FOR-loop enumerates the two strings "a,b,c,d,e" and
"f,g,h,i,j" (placed in %l), and parse each of these in turn, splitting
them at each specified delimiter (here only one character) ',' and storing
the results in consecutive tokens %a, %b, %c, %d, with the last token %d
containing all the remaining string (non-split).
The expected result is:
a-b-c-d,e
f-g-h-i,j
However, due to the way the delimiters string specified by the "delims="
option is stored (no stack/heap duplication of the FOR-option substring,
but reading from it directly), during the first run of the innermost
FOR-loop, the option string "delims=, tokens=1-3*" was truncated to just
after the ',' due to the erroneous "delims=" parsing, so that when this
FOR-loop ran for a second time (to deal with the second string), the option
string was already erroneously truncated, without the "tokens=..." part,
so that the parsing results were not stored in the tokens and resulting in:
a-b-c-d,e
f-%b-%c-%d
instead. The solution is to save where the "delims=" string needs to be
cut, but wait until running the actual FOR-loop to terminate it (and
saving the original character too), run the FOR-loop body, and then
restore the original character where termination took place. This allows
having the FOR-loop option string valid for the next execution of the
FOR-loop.
---
base/shell/cmd/for.c | 30 +++++++++++++++++++++++++++---
1 file changed, 27 insertions(+), 3 deletions(-)
diff --git a/base/shell/cmd/for.c b/base/shell/cmd/for.c
index 67a9240c787..300588bed31 100644
--- a/base/shell/cmd/for.c
+++ b/base/shell/cmd/for.c
@@ -121,6 +121,8 @@ static LPTSTR ReadFileContents(FILE *InputFile, TCHAR *Buffer)
static INT ForF(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer)
{
LPTSTR Delims = _T(" \t");
+ LPTSTR DelimsEndPtr = NULL;
+ TCHAR DelimsEndChr = _T('\0');
TCHAR Eol = _T(';');
INT SkipLines = 0;
DWORD Tokens = (1 << 1);
@@ -148,8 +150,13 @@ static INT ForF(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer)
else if (_tcsnicmp(Param, _T("delims="), 7) == 0)
{
Param += 7;
- /* delims=xxx: Specifies the list of characters that separate tokens */
+ /*
+ * delims=xxx: Specifies the list of characters that separate tokens.
+ * This option does not cumulate: only the latest 'delims=' specification
+ * is taken into account.
+ */
Delims = Param;
+ DelimsEndPtr = NULL;
while (*Param && *Param != Quote)
{
if (*Param == _T(' '))
@@ -158,13 +165,19 @@ static INT ForF(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer)
Param += _tcsspn(Param, _T(" "));
/* Exclude trailing spaces if this is not the last parameter */
if (*Param && *Param != Quote)
- *FirstSpace = _T('\0');
+ {
+ /* Save where the delimiters specification string ends */
+ DelimsEndPtr = FirstSpace;
+ }
break;
}
Param++;
}
if (*Param == Quote)
- *Param++ = _T('\0');
+ {
+ /* Save where the delimiters specification string ends */
+ DelimsEndPtr = Param++;
+ }
}
else if (_tcsnicmp(Param, _T("eol="), 4) == 0)
{
@@ -301,6 +314,13 @@ static INT ForF(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer)
return 1;
}
+ /* Patch the delimiters string */
+ if (DelimsEndPtr)
+ {
+ DelimsEndChr = *DelimsEndPtr;
+ *DelimsEndPtr = _T('\0');
+ }
+
/* Loop over the input line by line */
for (In = FullInput, Skip = SkipLines;
!ExitingOrGoto(Cmd) && (In != NULL);
@@ -343,6 +363,10 @@ static INT ForF(PARSED_COMMAND *Cmd, LPTSTR List, TCHAR *Buffer)
Ret = RunInstance(Cmd);
}
+ /* Restore the delimiters string */
+ if (DelimsEndPtr)
+ *DelimsEndPtr = DelimsEndChr;
+
cmd_free(FullInput);
}