From 3a10bf58906d5ceeea07c08664aa8f1fa16d91dc Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Thu, 8 May 2003 03:47:24 +0000 Subject: [PATCH] Added environment tests. --- dlls/ntdll/tests/.cvsignore | 1 + dlls/ntdll/tests/Makefile.in | 1 + dlls/ntdll/tests/env.c | 209 +++++++++++++++++++++++++++++++++++ 3 files changed, 211 insertions(+) create mode 100644 dlls/ntdll/tests/env.c diff --git a/dlls/ntdll/tests/.cvsignore b/dlls/ntdll/tests/.cvsignore index ce2607c848c..60e19cee6c7 100644 --- a/dlls/ntdll/tests/.cvsignore +++ b/dlls/ntdll/tests/.cvsignore @@ -1,4 +1,5 @@ Makefile +env.ok error.ok generated.ok large_int.ok diff --git a/dlls/ntdll/tests/Makefile.in b/dlls/ntdll/tests/Makefile.in index e226ac7e705..362a61e497f 100644 --- a/dlls/ntdll/tests/Makefile.in +++ b/dlls/ntdll/tests/Makefile.in @@ -6,6 +6,7 @@ TESTDLL = ntdll.dll IMPORTS = ntdll CTESTS = \ + env.c \ error.c \ generated.c \ large_int.c \ diff --git a/dlls/ntdll/tests/env.c b/dlls/ntdll/tests/env.c new file mode 100644 index 00000000000..25b89031c1c --- /dev/null +++ b/dlls/ntdll/tests/env.c @@ -0,0 +1,209 @@ +/* + * Unit test suite for ntdll path functions + * + * Copyright 2003 Eric Pouech + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include "wine/test.h" +#include "winnt.h" +#include "winternl.h" +#include "wine/unicode.h" + +static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)( LPWSTR dst, DWORD dstlen, LPDWORD reslen, + LPCSTR src, DWORD srclen ); +static NTSTATUS (WINAPI *pRtlCreateEnvironment)(BOOLEAN, PWSTR*); +static NTSTATUS (WINAPI *pRtlDestroyEnvironment)(PWSTR); +static NTSTATUS (WINAPI *pRtlQueryEnvironmentVariable_U)(PWSTR, PUNICODE_STRING, PUNICODE_STRING); +static void (WINAPI *pRtlSetCurrentEnvironment)(PWSTR, PWSTR*); +static NTSTATUS (WINAPI *pRtlSetEnvironmentVariable)(PWSTR*, PUNICODE_STRING, PUNICODE_STRING); + +static WCHAR small_env[] = {'f','o','o','=','t','o','t','o',0, + 'f','o','=','t','i','t','i',0, + 'f','o','o','o','=','t','u','t','u',0, + 's','r','=','a','n','=','o','u','o',0, + 'g','=','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', + 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', + 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', + 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', + 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', + 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', + 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', + 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', + 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', + 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',0, + '=','o','O','H','=','I','I','I',0, + 0}; + +static void testQuery(void) +{ + struct test + { + const char *var; + int len; + NTSTATUS status; + const char *val; + }; + + static const struct test tests[] = + { + {"foo", 256, STATUS_SUCCESS, "toto"}, + {"FoO", 256, STATUS_SUCCESS, "toto"}, + {"foo=", 256, STATUS_VARIABLE_NOT_FOUND, NULL}, + {"foo ", 256, STATUS_VARIABLE_NOT_FOUND, NULL}, + {"foo", 1, STATUS_BUFFER_TOO_SMALL, "toto"}, + {"foo", 3, STATUS_BUFFER_TOO_SMALL, "toto"}, + {"foo", 4, STATUS_SUCCESS, "toto"}, + {"fooo", 256, STATUS_SUCCESS, "tutu"}, + {"f", 256, STATUS_VARIABLE_NOT_FOUND, NULL}, + {"g", 256, STATUS_SUCCESS, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, + {"sr=an", 256, STATUS_VARIABLE_NOT_FOUND, NULL}, + {"sr", 256, STATUS_SUCCESS, "an=ouo"}, + {"=oOH", 256, STATUS_SUCCESS, "III"}, + {"", 256, STATUS_VARIABLE_NOT_FOUND, NULL}, + {NULL, 0, 0, NULL} + }; + + WCHAR bn[256]; + WCHAR bv[256]; + UNICODE_STRING name; + UNICODE_STRING value; + const struct test* test; + NTSTATUS nts; + + for (test = tests; test->var; test++) + { + name.Length = strlen(test->var) * 2; + name.MaximumLength = name.Length + 2; + name.Buffer = bn; + value.Length = 0; + value.MaximumLength = test->len * 2; + value.Buffer = bv; + + pRtlMultiByteToUnicodeN( bn, sizeof(bn), NULL, test->var, strlen(test->var)+1 ); + nts = pRtlQueryEnvironmentVariable_U(small_env, &name, &value); + ok( nts == test->status, "[%d]: Wrong status for '%s', expecting %lx got %lx", + test - tests, test->var, test->status, nts ); + if (nts == test->status) switch (nts) + { + case STATUS_SUCCESS: + pRtlMultiByteToUnicodeN( bn, sizeof(bn), NULL, test->val, strlen(test->val)+1 ); + ok( value.Length == strlen(test->val) * sizeof(WCHAR), "Wrong length %d/%d for %s", + value.Length, strlen(test->val) * sizeof(WCHAR), test->var ); + ok( strcmpW(bv, bn) == 0, "Wrong result for %s", test->var ); + break; + case STATUS_BUFFER_TOO_SMALL: + ok( value.Length == strlen(test->val) * sizeof(WCHAR), + "Wrong returned length %d/%d (too small buffer) for %s", + value.Length, strlen(test->val) * sizeof(WCHAR), test->var ); + break; + } + } +} + +static void testSetHelper(LPWSTR* env, const char* var, const char* val, NTSTATUS ret) +{ + WCHAR bvar[256], bval1[256], bval2[256]; + UNICODE_STRING uvar; + UNICODE_STRING uval; + NTSTATUS nts; + + uvar.Length = strlen(var) * sizeof(WCHAR); + uvar.MaximumLength = uvar.Length + sizeof(WCHAR); + uvar.Buffer = bvar; + pRtlMultiByteToUnicodeN( bvar, sizeof(bvar), NULL, var, strlen(var)+1 ); + if (val) + { + uval.Length = strlen(val) * sizeof(WCHAR); + uval.MaximumLength = uval.Length + sizeof(WCHAR); + uval.Buffer = bval1; + pRtlMultiByteToUnicodeN( bval1, sizeof(bval1), NULL, val, strlen(val)+1 ); + } + nts = pRtlSetEnvironmentVariable(env, &uvar, val ? &uval : NULL); + ok(nts == ret, "Setting var %s=%s (%lx/%lx)", var, val, nts, ret); + if (nts == STATUS_SUCCESS) + { + uval.Length = 0; + uval.MaximumLength = sizeof(bval2); + uval.Buffer = bval2; + nts = pRtlQueryEnvironmentVariable_U(*env, &uvar, &uval); + switch (nts) + { + case STATUS_SUCCESS: + ok(strcmpW(bval1, bval2) == 0, "Cannot get value written to environment"); + break; + case STATUS_VARIABLE_NOT_FOUND: + ok(val == NULL, "Couldn't find variable, but didn't delete it"); + break; + default: + ok(0, "Wrong ret %lu for %s", nts, var); + break; + } + } +} + +static void testSet(void) +{ + LPWSTR env; + char tmp[16]; + int i; + + ok(pRtlCreateEnvironment(FALSE, &env) == STATUS_SUCCESS, "Creating environment"); + memmove(env, small_env, sizeof(small_env)); + + testSetHelper(&env, "cat", "dog", STATUS_SUCCESS); + testSetHelper(&env, "cat", "horse", STATUS_SUCCESS); + testSetHelper(&env, "cat", "zz", STATUS_SUCCESS); + testSetHelper(&env, "cat", NULL, STATUS_SUCCESS); + testSetHelper(&env, "cat", NULL, STATUS_VARIABLE_NOT_FOUND); + testSetHelper(&env, "foo", "meouw", STATUS_SUCCESS); + testSetHelper(&env, "me=too", "also", STATUS_INVALID_PARAMETER); + testSetHelper(&env, "me", "too=also", STATUS_SUCCESS); + testSetHelper(&env, "=too", "also", STATUS_SUCCESS); + testSetHelper(&env, "=", "also", STATUS_SUCCESS); + + for (i = 0; i < 128; i++) + { + sprintf(tmp, "zork%03d", i); + testSetHelper(&env, tmp, "is alive", STATUS_SUCCESS); + } + + for (i = 0; i < 128; i++) + { + sprintf(tmp, "zork%03d", i); + testSetHelper(&env, tmp, NULL, STATUS_SUCCESS); + } + testSetHelper(&env, "fOo", NULL, STATUS_SUCCESS); + + ok(pRtlDestroyEnvironment(env) == STATUS_SUCCESS, "Destroying environment"); +} + +START_TEST(env) +{ + HMODULE mod = GetModuleHandleA("ntdll.dll"); + + pRtlMultiByteToUnicodeN = (void *)GetProcAddress(mod,"RtlMultiByteToUnicodeN"); + pRtlCreateEnvironment = (void*)GetProcAddress(mod, "RtlCreateEnvironment"); + pRtlDestroyEnvironment = (void*)GetProcAddress(mod, "RtlDestroyEnvironment"); + pRtlQueryEnvironmentVariable_U = (void*)GetProcAddress(mod, "RtlQueryEnvironmentVariable_U"); + pRtlSetCurrentEnvironment = (void*)GetProcAddress(mod, "RtlSetCurrentEnvironment"); + pRtlSetEnvironmentVariable = (void*)GetProcAddress(mod, "RtlSetEnvironmentVariable"); + + testQuery(); + testSet(); +}