From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- dlls/msvcrt/tests/environ.c | 170 ++++++++++++++++++++++++------------ 1 file changed, 113 insertions(+), 57 deletions(-)
diff --git a/dlls/msvcrt/tests/environ.c b/dlls/msvcrt/tests/environ.c index 22f697a12ea..dd0765edc55 100644 --- a/dlls/msvcrt/tests/environ.c +++ b/dlls/msvcrt/tests/environ.c @@ -46,6 +46,8 @@ static const char *a_very_long_env_string =
static char ***(__cdecl *p__p__environ)(void); static WCHAR ***(__cdecl *p__p__wenviron)(void); +static char ***(__cdecl *p__p___initenv)(void); +static wchar_t ***(__cdecl *p__p___winitenv)(void); static void (__cdecl *p_get_environ)(char ***); static void (__cdecl *p_get_wenviron)(WCHAR ***); static errno_t (__cdecl *p_putenv_s)(const char*, const char*); @@ -61,6 +63,8 @@ static void init(void)
p__p__environ = (void *)GetProcAddress(hmod, "__p__environ"); p__p__wenviron = (void *)GetProcAddress(hmod, "__p__wenviron"); + p__p___initenv = (void *)GetProcAddress(hmod, "__p___initenv"); + p__p___winitenv = (void *)GetProcAddress(hmod, "__p___winitenv"); p_environ = (void *)GetProcAddress(hmod, "_environ"); p_wenviron = (void *)GetProcAddress(hmod, "_wenviron"); p_get_environ = (void *)GetProcAddress(hmod, "_get_environ"); @@ -79,12 +83,31 @@ static void test_system(void) ok(ret == 0, "Expected system to return 0, got %d\n", ret); }
-static void test__environ(void) +static wchar_t *env_get_valueW( wchar_t **envp, const wchar_t *var ) +{ + unsigned i; + size_t len = wcslen( var ); + + if (!envp) return NULL; + for (i = 0; envp[i] != NULL; i++) + { + wchar_t *ptr; + + if (!(ptr = wcschr( envp[i], L'=' ))) continue; + + if (ptr - envp[i] == len && !memcmp( envp[i], var, len * sizeof(wchar_t) )) + return ptr + 1; + } + return NULL; +} + +static void test__environ(BOOL first_time) { int argc; char **argv, **envp = NULL; - int i, mode = 0; + int mode = 0;
+ winetest_push_context("%s call", first_time ? "first" : "second"); ok( p_environ != NULL, "Expected the pointer to _environ to be non-NULL\n" ); if (p_environ) ok( *p_environ != NULL, "Expected _environ to be initialized on startup\n" ); @@ -92,6 +115,7 @@ static void test__environ(void) if (!p_environ || !*p_environ) { skip( "_environ pointers are not valid\n" ); + winetest_pop_context(); return; }
@@ -110,96 +134,143 @@ static void test__environ(void) else win_skip( "_get_environ() is not available\n" );
- /* Note that msvcrt from Windows versions older than Vista - * expects the mode pointer parameter to be valid.*/ - __getmainargs(&argc, &argv, &envp, 0, &mode); - - ok( envp != NULL, "Expected initial environment block pointer to be non-NULL\n" ); - if (!envp) + if (p__p___initenv) { - skip( "Initial environment block pointer is not valid\n" ); - return; - } + static char **prev_initenv; + char ***retptr = p__p___initenv();
- for (i = 0; ; i++) - { - if ((*p_environ)[i]) + if (first_time) { - ok( envp[i] != NULL, "Expected environment block pointer element to be non-NULL\n" ); - ok( !strcmp((*p_environ)[i], envp[i]), - "Expected _environ and environment block pointer strings (%s vs. %s) to match\n", - (*p_environ)[i], envp[i] ); + todo_wine + ok( *retptr == *p_environ, + "Expected _environ to be equal to initial env\n" ); + prev_initenv = *retptr; } else { - ok( !envp[i], "Expected environment block pointer element to be NULL, got %p\n", envp[i] ); - break; + ok( *retptr != *p_environ, + "Expected _environ[] not to be equal to initial env\n" ); + ok( *retptr == prev_initenv, + "Unexpected modification of initial env\n"); } } + else + skip( "__p___initenv() is not available\n" ); + + /* Note that msvcrt from Windows versions older than Vista + * expects the mode pointer parameter to be valid.*/ + __getmainargs(&argc, &argv, &envp, 0, &mode); + + ok( envp != NULL, + "Expected initial environment block pointer to be non-NULL\n" ); + todo_wine + ok( envp == *p_environ, + "Expected initial environment to be equal to _environ\n"); + winetest_pop_context(); }
-static void test__wenviron(void) +static void test__wenviron(BOOL first_time) { int argc; char **argv, **envp = NULL; WCHAR **wargv, **wenvp = NULL; - int i, mode = 0; + int mode = 0; + static wchar_t **prev_initenv;
+ winetest_push_context("%s call", first_time ? "first" : "second"); ok( p_wenviron != NULL, "Expected the pointer to _wenviron to be non-NULL\n" ); - if (p_wenviron) - ok( *p_wenviron == NULL, "Expected _wenviron to be NULL, got %p\n", *p_wenviron ); + if (first_time) + { + if (!p_wenviron) + { + win_skip( "Pointer to _wenviron is not valid\n" ); + winetest_pop_context(); + return; + } + ok( *p_wenviron == NULL, "Expected _wenviron[] to be NULL, got %p\n", *p_wenviron ); + } else { - win_skip( "Pointer to _wenviron is not valid\n" ); - return; + ok( *p_wenviron != NULL, "Expected _wenviron[] to be non NULL\n" ); }
if (sizeof(void*) != sizeof(int)) ok( !p__p__wenviron, "__p__wenviron() should be 32-bit only\n"); else - ok( *p__p__wenviron() == NULL, "Expected _wenviron pointers to be NULL\n" ); + ok( *p__p__wenviron() == *p_wenviron, "Expected environment pointers to be identical\n" );
if (p_get_wenviron) { WCHAR **retptr; p_get_wenviron(&retptr); - ok( retptr == NULL, - "Expected _wenviron pointers to be NULL\n" ); + ok( retptr == *p_wenviron, "Expected _environ pointers to be identical\n" ); } else win_skip( "_get_wenviron() is not available\n" );
+ if (p__p___winitenv) + { + wchar_t ***retptr = p__p___winitenv(); + if (first_time) + { + todo_wine + ok( *retptr == NULL, + "Expected initial env to be NULL\n" ); + } + } + else + skip( "__p___winitenv() is not available\n" ); + /* __getmainargs doesn't initialize _wenviron. */ __getmainargs(&argc, &argv, &envp, 0, &mode);
- ok( *p_wenviron == NULL, "Expected _wenviron to be NULL, got %p\n", *p_wenviron); + if (first_time) + ok( *p_wenviron == NULL, "Expected _wenviron to be NULL\n"); ok( envp != NULL, "Expected initial environment block pointer to be non-NULL\n" ); if (!envp) { skip( "Initial environment block pointer is not valid\n" ); + winetest_pop_context(); return; }
/* Neither does calling the non-Unicode environment manipulation functions. */ ok( _putenv("cat=dog") == 0, "failed setting cat=dog\n" ); - ok( *p_wenviron == NULL, "Expected _wenviron to be NULL, got %p\n", *p_wenviron); - ok( _putenv("cat=") == 0, "failed deleting cat\n" ); + if (first_time) + ok( *p_wenviron == NULL, "Expected _wenviron to be NULL\n" );
/* _wenviron isn't initialized until __wgetmainargs is called or * one of the Unicode environment manipulation functions is called. */ - ok( _wputenv(L"cat=dog") == 0, "failed setting cat=dog\n" ); + ok( _wputenv(L"cat=dog2") == 0, "failed setting cat=dog\n" ); ok( *p_wenviron != NULL, "Expected _wenviron to be non-NULL\n" ); - ok( _wputenv(L"cat=") == 0, "failed deleting cat\n" );
__wgetmainargs(&argc, &wargv, &wenvp, 0, &mode);
ok( *p_wenviron != NULL, "Expected _wenviron to be non-NULL\n" ); ok( wenvp != NULL, "Expected initial environment block pointer to be non-NULL\n" ); - if (!wenvp) + todo_wine + ok( wenvp == *p_wenviron, "Expected initial environment to be _wenviron[]\n"); + + if (p__p___winitenv) { - skip( "Initial environment block pointer is not valid\n" ); - return; + wchar_t ***retptr = p__p___winitenv(); + wchar_t *value; + + ok( *retptr != NULL, + "Expected *__p___winitenv() to be NULL\n" ); + ok( *retptr != *p_wenviron, + "Expected _wenviron to be different from __p___winitenv() %p %p\n", *retptr, *p_wenviron ); + /* test that w-initial env is derived from current _environ[] and not from ansi initial env */ + value = env_get_valueW( *retptr, L"cat" ); + todo_wine + ok( value && !wcscmp( value, L"dog" ), "Expecting initial env to be derived from current env (got %ls)\n", value); + + if (first_time) + prev_initenv = *retptr; + else + ok (*retptr == prev_initenv, "Unexpected modification of initial env\n"); } + _putenv("cat=");
/* Examine the returned pointer from __p__wenviron(), * if available, after _wenviron is initialized. */ @@ -216,22 +287,7 @@ static void test__wenviron(void) ok( retptr == *p_wenviron, "Expected _wenviron pointers to be identical\n" ); } - - for (i = 0; ; i++) - { - if ((*p_wenviron)[i]) - { - ok( wenvp[i] != NULL, "Expected environment block pointer element to be non-NULL\n" ); - ok( !wcscmp((*p_wenviron)[i], wenvp[i]), - "Expected _wenviron and environment block pointer strings (%s vs. %s) to match\n", - wine_dbgstr_w((*p_wenviron)[i]), wine_dbgstr_w(wenvp[i]) ); - } - else - { - ok( !wenvp[i], "Expected environment block pointer element to be NULL, got %p\n", wenvp[i] ); - break; - } - } + winetest_pop_context(); }
static void test_environment_manipulation(void) @@ -312,10 +368,10 @@ START_TEST(environ) { init();
- /* The environ tests should always be run first, as they assume - * that the process has not manipulated the environment. */ - test__environ(); - test__wenviron(); + test__environ(TRUE); + test__wenviron(TRUE); test_environment_manipulation(); + test__environ(FALSE); + test__wenviron(FALSE); test_system(); }