[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