[PATCH v3 2/4] kernelbase: Preserve last error when GetEnvironmentVariableA succeeds.

Vladimir Panteleev git at vladimir.panteleev.md
Thu Jan 23 09:05:42 CST 2020


Do not clobber last error with NO_ERROR when GetEnvironmentVariableA
succeeds, matching the behavior of GetEnvironmentVariableW and
Windows.

Signed-off-by: Vladimir Panteleev <git at vladimir.panteleev.md>
---

Since v2: New patch (fix test as suggested, and fix Wine to pass the test).

 dlls/kernel32/tests/environ.c |  8 ++++----
 dlls/kernelbase/process.c     | 10 ++++++++--
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/dlls/kernel32/tests/environ.c b/dlls/kernel32/tests/environ.c
index 128a5fdbe5..561fc71c4c 100644
--- a/dlls/kernel32/tests/environ.c
+++ b/dlls/kernel32/tests/environ.c
@@ -155,10 +155,10 @@ static void test_GetSetEnvironmentVariableA(void)
        "should not fail with empty value but GetLastError=%d\n", GetLastError());
 
     lstrcpyA(buf, "foo");
-    SetLastError(0);
+    SetLastError(0xdeadbeef);
     ret_size = GetEnvironmentVariableA(name, buf, lstrlenA(value) + 1);
     ok(ret_size == 0 &&
-       ((GetLastError() == 0 && lstrcmpA(buf, "") == 0) ||
+       ((GetLastError() == 0xdeadbeef && lstrcmpA(buf, "") == 0) ||
         (GetLastError() == ERROR_ENVVAR_NOT_FOUND)),
        "%s should be set to \"\" (NT) or removed (Win9x) but ret_size=%d GetLastError=%d and buf=%s\n",
        name, ret_size, GetLastError(), buf);
@@ -260,10 +260,10 @@ static void test_GetSetEnvironmentVariableW(void)
     ok(ret == TRUE, "should not fail with empty value but GetLastError=%d\n", GetLastError());
 
     lstrcpyW(buf, fooW);
-    SetLastError(0);
+    SetLastError(0xdeadbeef);
     ret_size = GetEnvironmentVariableW(name, buf, lstrlenW(value) + 1);
     ok(ret_size == 0 &&
-       ((GetLastError() == 0 && lstrcmpW(buf, empty_strW) == 0) ||
+       ((GetLastError() == 0xdeadbeef && lstrcmpW(buf, empty_strW) == 0) ||
         (GetLastError() == ERROR_ENVVAR_NOT_FOUND)),
        "should be set to \"\" (NT) or removed (Win9x) but ret_size=%d GetLastError=%d\n",
        ret_size, GetLastError());
diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c
index a07dddb1fc..8fe5b6f495 100644
--- a/dlls/kernelbase/process.c
+++ b/dlls/kernelbase/process.c
@@ -1234,7 +1234,9 @@ DWORD WINAPI DECLSPEC_HOTPATCH GetEnvironmentVariableA( LPCSTR name, LPSTR value
 {
     UNICODE_STRING us_name;
     PWSTR valueW;
-    DWORD ret;
+    DWORD ret, last_err;
+
+    last_err = GetLastError();
 
     /* limit the size to sane values */
     size = min( size, 32767 );
@@ -1249,7 +1251,11 @@ DWORD WINAPI DECLSPEC_HOTPATCH GetEnvironmentVariableA( LPCSTR name, LPSTR value
      * - an error (GetLastError() != 0)
      * - returning an empty string (in this case, we need to update the buffer)
      */
-    if (ret == 0 && size && GetLastError() == 0) value[0] = 0;
+    if (GetLastError() == 0)
+    {
+        SetLastError(last_err);
+        if (ret == 0 && size) value[0] = 0;
+    }
     RtlFreeUnicodeString( &us_name );
     HeapFree( GetProcessHeap(), 0, valueW );
     return ret;
-- 
2.25.0




More information about the wine-devel mailing list