[PATCH 1/2] dlls/ntdll/tests: added tests for pseudo environment variables

Eric Pouech eric.pouech at gmail.com
Tue Mar 1 08:48:16 CST 2022


Signed-off-by: Eric Pouech <eric.pouech at gmail.com>

---
 dlls/ntdll/tests/env.c |  138 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 138 insertions(+)

diff --git a/dlls/ntdll/tests/env.c b/dlls/ntdll/tests/env.c
index 9cfbf9eb435..51fee774b8b 100644
--- a/dlls/ntdll/tests/env.c
+++ b/dlls/ntdll/tests/env.c
@@ -654,6 +654,143 @@ static void test_RtlSetEnvironmentVariable(void)
     ok(!status, "got %#x\n", status);
 }
 
+/* if 'value' is non NULL, returns TRUE iff env var 'name' is present and of value 'value'
+ * if 'value' is NULL, returns TRUE iff env var 'name' is not present present
+ */
+static BOOL check_pseudo_in_peb(const WCHAR* name, const WCHAR* value)
+{
+    WCHAR* envstrings;
+    WCHAR* ptr;
+    size_t len = wcslen(name);
+    BOOL ret = FALSE;
+
+    RtlAcquirePebLock();
+    envstrings = NtCurrentTeb()->Peb->ProcessParameters->Environment;
+    if (envstrings)
+    {
+        for (ptr = envstrings; *ptr; ptr += wcslen(ptr) + 1)
+        {
+            if (!wcsncmp(ptr, name, len) && ptr[len] == L'=')
+            {
+                ret = value && !wcscmp(&ptr[len + 1], value);
+                break;
+            }
+        }
+        if (value == NULL && !*ptr) ret = TRUE;
+    }
+    RtlReleasePebLock();
+    return ret;
+}
+
+static DWORD test_one_pseudo_variable(const WCHAR* pseudo, WCHAR* value, UINT value_len)
+{
+    const WCHAR* dummystr = L"let's land onto the moon";
+    WCHAR value2_buffer[1024];
+    UNICODE_STRING var_string, value_string, value2_string;
+    NTSTATUS status;
+    BOOL ret;
+
+    RtlInitUnicodeString(&var_string, pseudo);
+    value_string.Buffer = value;
+    value_string.MaximumLength = value_len * sizeof(WCHAR);
+
+    status = RtlQueryEnvironmentVariable_U(small_env, &var_string, &value_string);
+    todo_wine
+    ok(!status, "Should have found %ls env var in small_env (%x)\n", pseudo, status);
+
+    status = RtlQueryEnvironmentVariable_U(NULL, &var_string, &value_string);
+    todo_wine
+    ok(!status && value_string.Length >= sizeof(WCHAR), "Couldn't find %ls env var\n", pseudo);
+    ok(value_string.Length == wcslen(value_string.Buffer) * sizeof(WCHAR),
+       "Expecting length of %u but got %u\n",
+       wcslen(value_string.Buffer) * sizeof(WCHAR), value_string.Length);
+
+    if (pRtlQueryEnvironmentVariable)
+    {
+        SIZE_T zzlen;
+        status = pRtlQueryEnvironmentVariable(NULL, (WCHAR*)pseudo, wcslen(pseudo),
+                                              value, value_len / sizeof(WCHAR), &zzlen);
+        todo_wine
+        ok(!status && zzlen >= sizeof(WCHAR), "Couldn't find %ls env var\n", pseudo);
+    }
+    ret = check_pseudo_in_peb(pseudo, NULL);
+    ok(ret, "Pseudo env var %ls shouldn't be present in env strings\n", pseudo);
+
+    status = set_env_var(NULL, pseudo, dummystr);
+    ok(!status, "Should be able to write value for set %ls\n", pseudo);
+
+    value2_string.Buffer = value2_buffer;
+    value2_string.MaximumLength = sizeof(value2_buffer);
+
+    status = RtlQueryEnvironmentVariable_U(NULL, &var_string, &value2_string);
+    ok(!status && value2_string.Length >= sizeof(WCHAR), "Couldn't find %ls env var\n", pseudo);
+    todo_wine
+    ok(!wcscmp(value2_string.Buffer, value_string.Buffer),
+       "Expecting %ls but got %ls for env variable %ls\n",
+       value_string.Buffer, value2_string.Buffer, pseudo);
+
+    ret = check_pseudo_in_peb(pseudo, dummystr);
+    ok(ret, "Pseudo env var %ls should be present in env strings with value %ls\n", pseudo, dummystr);
+
+    status = set_env_var(NULL, pseudo, NULL);
+    ok(!status, "Should be able to remove value for set %ls\n", pseudo);
+
+    status = RtlQueryEnvironmentVariable_U(NULL, &var_string, &value2_string);
+    todo_wine
+    ok(!status && value2_string.Length >= sizeof(WCHAR), "Couldn't find %ls env var\n", pseudo);
+    todo_wine
+    ok(!wcscmp(value, value2_string.Buffer), "Should get back pseudo value for %ls\n", pseudo);
+
+    ret = check_pseudo_in_peb(pseudo, NULL);
+    ok(ret, "Pseudo env var %ls shouldn't be present in env strings\n", pseudo);
+
+    value2_string.Buffer = value2_buffer;
+    value2_string.MaximumLength = wcslen(value) * sizeof(WCHAR); /* missing one wchar */
+    memset(value2_buffer, 0xa5, sizeof(value2_buffer));
+
+    status = RtlQueryEnvironmentVariable_U(NULL, &var_string, &value2_string);
+    todo_wine
+    ok(status == STATUS_BUFFER_TOO_SMALL && value2_string.Length >= sizeof(WCHAR),
+       "Couldn't find %ls env var\n", pseudo);
+    todo_wine
+    ok(!value2_string.Buffer[0], "Expecting empty buffer for env variable %ls\n", pseudo);
+    ok(value2_string.Length == value_string.Length, "Expecting length of %u but got %u\n",
+       value_string.Length, value2_string.Length);
+
+    return value_string.Length / sizeof(WCHAR);
+}
+
+static void test_pseudo_env_variables(void)
+{
+    WCHAR value[1024];
+    WCHAR value2[1024];
+    DWORD size, size2;
+
+    size = test_one_pseudo_variable(L"__APPDIR__", value, ARRAY_SIZE(value));
+    size2 = GetModuleFileNameW(NULL, value2, ARRAY_SIZE(value2));
+    ok(size2 && size2 + 1 < ARRAY_SIZE(value2), "couldn't get app module filename\n");
+    ok(size + 1 < size2, "Mismatch in sizes (%u / %u)\n", size, size2);
+    todo_wine
+    ok(size && !memcmp(value, value2, size * sizeof(WCHAR)) && value[size - 1] == L'\\',
+       "__APPDIR__: got %ls while expecting %ls\\\n", value, value2);
+    todo_wine
+    ok(!wcschr(&value2[size], L'/') && !wcschr(&value2[size], L'\\'),
+       "expecting %ls not to include directories\n", &value2[size]);
+
+    size = test_one_pseudo_variable(L"__CD__", value, ARRAY_SIZE(value));
+    size2 = GetCurrentDirectoryW(ARRAY_SIZE(value2), value2);
+    ok(size2 && size2 + 1 < ARRAY_SIZE(value2), "couldn't get current directory\n");
+    todo_wine
+    ok(size2 + 1 == size, "Mismatch in sizes (%u / %u)\n", size, size2);
+    todo_wine
+    ok(!memcmp(value, value2, size2 * sizeof(WCHAR)) && value[size2] == L'\\',
+       "__CD__: got %ls while expecting %ls\\\n", value, value2);
+    /* FIXME could check changing directories
+     * - that __CD__ changes automatically
+     * - even if an old value still present in env strings
+     */
+}
+
 START_TEST(env)
 {
     HMODULE mod = GetModuleHandleA("ntdll.dll");
@@ -672,4 +809,5 @@ START_TEST(env)
     test_process_params();
     test_RtlSetCurrentEnvironment();
     test_RtlSetEnvironmentVariable();
+    test_pseudo_env_variables();
 }




More information about the wine-devel mailing list