We can't return the unicode string size, this returns sizes to small for multi-byte characters.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54295
-- v10: userenv: Fix GetProfilesDirectoryA return value kernel32: Rework ExpandEnvironmentStringsA to return ansi size and fix corner cases. kernel32: Rework ExpandEnvironmentStringsW error handling. ntdll: Rework RtlExpandEnvironmentStrings/_U to account for corner cases. kernel32: Add ExpandEnvironmentStringsA tests for japanese. kernel32: Add more tests for ExpandEnvironmentStringsA. kernel32: Add tests for ExpandEnvironmentStringsW. ntdll: Add more tests for RtlExpandEnvironmentStrings/_U. userenv: Add another test for GetProfilesDirectoryA
From: Fabian Maurer dark.shadow4@web.de
--- dlls/userenv/tests/userenv.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/dlls/userenv/tests/userenv.c b/dlls/userenv/tests/userenv.c index a440f538723..3ddb893c18c 100644 --- a/dlls/userenv/tests/userenv.c +++ b/dlls/userenv/tests/userenv.c @@ -296,6 +296,9 @@ static void test_get_profiles_dir(void) */ ok(profiles_len - 1 == r, "expected %ld, got %d\n", profiles_len - 1, r); ok(!strcmp(buf, profiles_dir), "expected %s, got %s\n", profiles_dir, buf); + ok(strlen(buf) + 1 == cch, "String length is %Iu, but cch is %lu\n", strlen(buf), cch); + todo_wine + ok(strlen(buf) + 1 == r, "String length is %Iu, but returned count is %u\n", strlen(buf), r);
HeapFree(GetProcessHeap(), 0, buf); HeapFree(GetProcessHeap(), 0, profiles_dir);
From: Fabian Maurer dark.shadow4@web.de
--- dlls/ntdll/tests/env.c | 113 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+)
diff --git a/dlls/ntdll/tests/env.c b/dlls/ntdll/tests/env.c index 450ee37db1f..ad653afa439 100644 --- a/dlls/ntdll/tests/env.c +++ b/dlls/ntdll/tests/env.c @@ -32,6 +32,7 @@ static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)( LPWSTR dst, DWORD dstlen, LPD LPCSTR src, DWORD srclen ); static NTSTATUS (WINAPI *pRtlQueryEnvironmentVariable_U)(PWSTR, PUNICODE_STRING, PUNICODE_STRING); static NTSTATUS (WINAPI* pRtlQueryEnvironmentVariable)(WCHAR*, WCHAR*, SIZE_T, WCHAR*, SIZE_T, SIZE_T*); +static NTSTATUS (WINAPI *pRtlExpandEnvironmentStrings)(WCHAR*, WCHAR*, SIZE_T, WCHAR*, SIZE_T, SIZE_T*); static NTSTATUS (WINAPI *pRtlExpandEnvironmentStrings_U)(LPWSTR, PUNICODE_STRING, PUNICODE_STRING, PULONG); static NTSTATUS (WINAPI *pRtlCreateProcessParameters)(RTL_USER_PROCESS_PARAMETERS**, const UNICODE_STRING*, const UNICODE_STRING*, @@ -243,6 +244,116 @@ static void testExpand(void)
}
+static void test_RtlExpandEnvironmentStrings(void) +{ + int i; + WCHAR buf[256]; + HRESULT status; + UNICODE_STRING us_src, us_dst, us_name, us_value; + static const struct test_info + { + const WCHAR *input; + const WCHAR *expected_str; + int count_in; + int expected_count_out; + BOOL todo_str; + } tests[] = + { + /* 0 */ { L"Long long value", L"abcdefghijklmnopqrstuv", 0, 16 }, + /* 1 */ { L"Long long value", L"abcdefghijklmnopqrstuv", 1, 16, TRUE }, + /* 2 */ { L"Long long value", L"Lbcdefghijklmnopqrstuv", 2, 16, TRUE }, + /* 3 */ { L"Long long value", L"Locdefghijklmnopqrstuv", 3, 16, TRUE }, + /* 4 */ { L"Long long value", L"Long long valuopqrstuv", 15, 16, TRUE }, + /* 5 */ { L"Long long value", L"Long long value", 16, 16 }, + /* 6 */ { L"Long long value", L"Long long value", 17, 16 }, + /* 7 */ { L"%TVAR% long long", L"abcdefghijklmnopqrstuv", 0, 15 }, + /* 8 */ { L"%TVAR% long long", L"", 1, 15, TRUE }, + /* 9 */ { L"%TVAR% long long", L"", 2, 15, TRUE }, + /* 10 */ { L"%TVAR% long long", L"", 4, 15, TRUE }, + /* 11 */ { L"%TVAR% long long", L"WINE", 5, 15, TRUE }, + /* 12 */ { L"%TVAR% long long", L"WINE fghijklmnopqrstuv", 6, 15, TRUE }, + /* 13 */ { L"%TVAR% long long", L"WINE lghijklmnopqrstuv", 7, 15, TRUE }, + /* 14 */ { L"%TVAR% long long", L"WINE long long", 15, 15 }, + /* 15 */ { L"%TVAR% long long", L"WINE long long", 16, 15 }, + /* 16 */ { L"%TVAR%%TVAR% long", L"", 4, 14, TRUE }, + /* 17 */ { L"%TVAR%%TVAR% long", L"WINE", 5, 14, TRUE }, + /* 18 */ { L"%TVAR%%TVAR% long", L"WINE", 6, 14, TRUE }, + /* 19 */ { L"%TVAR%%TVAR% long", L"WINE", 8, 14, TRUE }, + /* 20 */ { L"%TVAR%%TVAR% long", L"WINEWINE", 9, 14, TRUE }, + /* 21 */ { L"%TVAR%%TVAR% long", L"WINEWINE jklmnopqrstuv", 10, 14, TRUE }, + /* 22 */ { L"%TVAR%%TVAR% long", L"WINEWINE long", 14, 14 }, + /* 23 */ { L"%TVAR%%TVAR% long", L"WINEWINE long", 15, 14 }, + /* 24 */ { L"%TVAR% %TVAR% long", L"WINE", 5, 15, TRUE }, + /* 25 */ { L"%TVAR% %TVAR% long", L"WINE ", 6, 15, TRUE }, + /* 26 */ { L"%TVAR% %TVAR% long", L"WINE ", 8, 15, TRUE }, + /* 27 */ { L"%TVAR% %TVAR% long", L"WINE ", 9, 15, TRUE }, + /* 28 */ { L"%TVAR% %TVAR% long", L"WINE WINE", 10, 15, TRUE }, + /* 29 */ { L"%TVAR% %TVAR% long", L"WINE WINE klmnopqrstuv", 11, 15, TRUE }, + /* 30 */ { L"%TVAR% %TVAR% long", L"WINE WINE llmnopqrstuv", 12, 15, TRUE }, + /* 31 */ { L"%TVAR% %TVAR% long", L"WINE WINE lonnopqrstuv", 14, 15, TRUE }, + /* 32 */ { L"%TVAR% %TVAR% long", L"WINE WINE long", 15, 15 }, + /* 33 */ { L"%TVAR% %TVAR% long", L"WINE WINE long", 16, 15 }, + /* 34 */ { L"%TVAR2% long long", L"abcdefghijklmnopqrstuv", 1, 18, TRUE }, + /* 35 */ { L"%TVAR2% long long", L"%bcdefghijklmnopqrstuv", 2, 18, TRUE }, + /* 36 */ { L"%TVAR2% long long", L"%TVdefghijklmnopqrstuv", 4, 18, TRUE }, + /* 37 */ { L"%TVAR2% long long", L"%TVAR2ghijklmnopqrstuv", 7, 18, TRUE }, + /* 38 */ { L"%TVAR2% long long", L"%TVAR2%hijklmnopqrstuv", 8, 18, TRUE }, + /* 39 */ { L"%TVAR2% long long", L"%TVAR2% ijklmnopqrstuv", 9, 18, TRUE }, + /* 40 */ { L"%TVAR2% long long", L"%TVAR2% ljklmnopqrstuv", 10, 18, TRUE }, + /* 41 */ { L"%TVAR2% long long", L"%TVAR2% long long", 18, 18 }, + /* 42 */ { L"%TVAR2% long long", L"%TVAR2% long long", 19, 18 }, + /* 43 */ { L"%TVAR long long", L"abcdefghijklmnopqrstuv", 1, 16, TRUE }, + /* 44 */ { L"%TVAR long long", L"%bcdefghijklmnopqrstuv", 2, 16, TRUE }, + /* 45 */ { L"%TVAR long long", L"%Tcdefghijklmnopqrstuv", 3, 16, TRUE }, + /* 46 */ { L"%TVAR long long", L"%TVAR long lonopqrstuv", 15, 16, TRUE }, + /* 47 */ { L"%TVAR long long", L"%TVAR long long", 16, 16 }, + /* 48 */ { L"%TVAR long long", L"%TVAR long long", 17, 16 }, + }; + + RtlInitUnicodeString(&us_name, L"TVAR"); + RtlInitUnicodeString(&us_value, L"WINE"); + status = RtlSetEnvironmentVariable(NULL, &us_name, &us_value); + ok(status == STATUS_SUCCESS, "RtlSetEnvironmentVariable failed with %lx\n", status); + + for (i = 0; i < ARRAY_SIZE(tests); i++) + { + const struct test_info *test = &tests[i]; + SIZE_T out_len; + HRESULT expected_status = test->count_in >= test->expected_count_out ? STATUS_SUCCESS : STATUS_BUFFER_TOO_SMALL; + + wcscpy(buf, L"abcdefghijklmnopqrstuv"); + status = pRtlExpandEnvironmentStrings(NULL, (WCHAR*)test->input, wcslen(test->input), buf, test->count_in, &out_len); + ok(out_len == test->expected_count_out, "Test %d: got %Iu\n", i, out_len); + ok(status == expected_status, "Test %d: Expected status %lx, got %lx\n", i, expected_status, status); + todo_wine_if(test->todo_str) + ok(!wcscmp(buf, test->expected_str), "Test %d: got %s\n", i, debugstr_w(buf)); + } + + for (i = 0; i < ARRAY_SIZE(tests); i++) + { + const struct test_info *test = &tests[i]; + DWORD out_len; + HRESULT expected_status = test->count_in >= test->expected_count_out ? STATUS_SUCCESS : STATUS_BUFFER_TOO_SMALL; + + us_src.Length = wcslen(test->input) * sizeof(WCHAR); + us_src.MaximumLength = us_src.Length; + us_src.Buffer = (WCHAR*)test->input; + + us_dst.Length = test->count_in * sizeof(WCHAR); + us_dst.MaximumLength = us_dst.Length; + us_dst.Buffer = buf; + + wcscpy(buf, L"abcdefghijklmnopqrstuv"); + status = pRtlExpandEnvironmentStrings_U(NULL, &us_src, &us_dst, &out_len); + ok(out_len / sizeof(WCHAR) == test->expected_count_out, "Test %d: got %Iu\n", i, out_len / sizeof(WCHAR)); + ok(status == expected_status, "Test %d: Expected status %lx, got %lx\n", i, expected_status, status); + todo_wine_if(test->todo_str) + ok(!wcscmp(buf, test->expected_str), "Test %d: got %s\n", i, debugstr_w(buf)); + } + status = RtlSetEnvironmentVariable(NULL, &us_name, NULL); + ok(status == STATUS_SUCCESS, "RtlSetEnvironmentVariable failed with %lx\n", status); +} + static WCHAR *get_params_string( RTL_USER_PROCESS_PARAMETERS *params, UNICODE_STRING *str ) { if (params->Flags & PROCESS_PARAMS_FLAG_NORMALIZED) return str->Buffer; @@ -621,6 +732,7 @@ START_TEST(env) pRtlMultiByteToUnicodeN = (void *)GetProcAddress(mod,"RtlMultiByteToUnicodeN"); pRtlQueryEnvironmentVariable_U = (void*)GetProcAddress(mod, "RtlQueryEnvironmentVariable_U"); pRtlQueryEnvironmentVariable = (void*)GetProcAddress(mod, "RtlQueryEnvironmentVariable"); + pRtlExpandEnvironmentStrings = (void*)GetProcAddress(mod, "RtlExpandEnvironmentStrings"); pRtlExpandEnvironmentStrings_U = (void*)GetProcAddress(mod, "RtlExpandEnvironmentStrings_U"); pRtlCreateProcessParameters = (void*)GetProcAddress(mod, "RtlCreateProcessParameters"); pRtlDestroyProcessParameters = (void*)GetProcAddress(mod, "RtlDestroyProcessParameters"); @@ -630,4 +742,5 @@ START_TEST(env) test_process_params(); test_RtlSetCurrentEnvironment(); test_RtlSetEnvironmentVariable(); + test_RtlExpandEnvironmentStrings(); }
From: Fabian Maurer dark.shadow4@web.de
--- dlls/kernel32/tests/environ.c | 95 +++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+)
diff --git a/dlls/kernel32/tests/environ.c b/dlls/kernel32/tests/environ.c index c1a49e175be..36cedcdeaf5 100644 --- a/dlls/kernel32/tests/environ.c +++ b/dlls/kernel32/tests/environ.c @@ -379,6 +379,100 @@ static void test_GetSetEnvironmentVariableAW(void) ok(lstrcmpW(bufW, valueW) == 0, "expected %s, got %s\n", debugstr_w(valueW), debugstr_w(bufW)); }
+static void test_ExpandEnvironmentStringsW(void) +{ + int i; + WCHAR buf[256]; + DWORD ret; + BOOL success; + static const struct test_info + { + const WCHAR *input; + const WCHAR *expected_str; + int count_in; + int expected_count_out; + BOOL todo_status; + BOOL todo_str; + } tests[] = + { + /* 0 */ { L"Long long value", L"abcdefghijklmnopqrstuv", 0, 16, TRUE }, + /* 1 */ { L"Long long value", L"abcdefghijklmnopqrstuv", 1, 16, TRUE, TRUE }, + /* 2 */ { L"Long long value", L"Lbcdefghijklmnopqrstuv", 2, 16, TRUE, TRUE }, + /* 3 */ { L"Long long value", L"Locdefghijklmnopqrstuv", 3, 16, TRUE, TRUE }, + /* 4 */ { L"Long long value", L"Long long valuopqrstuv", 15, 16, TRUE, TRUE }, + /* 5 */ { L"Long long value", L"Long long value", 16, 16 }, + /* 6 */ { L"Long long value", L"Long long value", 17, 16 }, + /* 7 */ { L"%TVAR% long long", L"abcdefghijklmnopqrstuv", 0, 15, TRUE }, + /* 8 */ { L"%TVAR% long long", L"", 1, 15, TRUE }, + /* 9 */ { L"%TVAR% long long", L"", 2, 15, TRUE, TRUE }, + /* 10 */ { L"%TVAR% long long", L"", 4, 15, TRUE, TRUE }, + /* 11 */ { L"%TVAR% long long", L"WINE", 5, 15, TRUE }, + /* 12 */ { L"%TVAR% long long", L"WINE fghijklmnopqrstuv", 6, 15, TRUE, TRUE }, + /* 13 */ { L"%TVAR% long long", L"WINE lghijklmnopqrstuv", 7, 15, TRUE, TRUE }, + /* 14 */ { L"%TVAR% long long", L"WINE long long", 15, 15 }, + /* 15 */ { L"%TVAR% long long", L"WINE long long", 16, 15 }, + /* 16 */ { L"%TVAR%%TVAR% long", L"", 4, 14, TRUE, TRUE }, + /* 17 */ { L"%TVAR%%TVAR% long", L"WINE", 5, 14, TRUE }, + /* 18 */ { L"%TVAR%%TVAR% long", L"WINE", 6, 14, TRUE, TRUE }, + /* 19 */ { L"%TVAR%%TVAR% long", L"WINE", 8, 14, TRUE, TRUE }, + /* 20 */ { L"%TVAR%%TVAR% long", L"WINEWINE", 9, 14, TRUE }, + /* 21 */ { L"%TVAR%%TVAR% long", L"WINEWINE jklmnopqrstuv", 10, 14, TRUE, TRUE }, + /* 22 */ { L"%TVAR%%TVAR% long", L"WINEWINE long", 14, 14 }, + /* 23 */ { L"%TVAR%%TVAR% long", L"WINEWINE long", 15, 14 }, + /* 24 */ { L"%TVAR% %TVAR% long", L"WINE", 5, 15, TRUE }, + /* 25 */ { L"%TVAR% %TVAR% long", L"WINE ", 6, 15, TRUE }, + /* 26 */ { L"%TVAR% %TVAR% long", L"WINE ", 8, 15, TRUE, TRUE }, + /* 27 */ { L"%TVAR% %TVAR% long", L"WINE ", 9, 15, TRUE, TRUE }, + /* 28 */ { L"%TVAR% %TVAR% long", L"WINE WINE", 10, 15, TRUE }, + /* 29 */ { L"%TVAR% %TVAR% long", L"WINE WINE klmnopqrstuv", 11, 15, TRUE, TRUE }, + /* 30 */ { L"%TVAR% %TVAR% long", L"WINE WINE llmnopqrstuv", 12, 15, TRUE, TRUE }, + /* 31 */ { L"%TVAR% %TVAR% long", L"WINE WINE lonnopqrstuv", 14, 15, TRUE, TRUE }, + /* 32 */ { L"%TVAR% %TVAR% long", L"WINE WINE long", 15, 15 }, + /* 33 */ { L"%TVAR% %TVAR% long", L"WINE WINE long", 16, 15 }, + /* 34 */ { L"%TVAR2% long long", L"abcdefghijklmnopqrstuv", 1, 18, TRUE, TRUE }, + /* 35 */ { L"%TVAR2% long long", L"%bcdefghijklmnopqrstuv", 2, 18, TRUE, TRUE }, + /* 36 */ { L"%TVAR2% long long", L"%TVdefghijklmnopqrstuv", 4, 18, TRUE, TRUE }, + /* 37 */ { L"%TVAR2% long long", L"%TVAR2ghijklmnopqrstuv", 7, 18, TRUE, TRUE }, + /* 38 */ { L"%TVAR2% long long", L"%TVAR2%hijklmnopqrstuv", 8, 18, TRUE, TRUE }, + /* 39 */ { L"%TVAR2% long long", L"%TVAR2% ijklmnopqrstuv", 9, 18, TRUE, TRUE }, + /* 40 */ { L"%TVAR2% long long", L"%TVAR2% ljklmnopqrstuv", 10, 18, TRUE, TRUE }, + /* 41 */ { L"%TVAR2% long long", L"%TVAR2% long long", 18, 18 }, + /* 42 */ { L"%TVAR2% long long", L"%TVAR2% long long", 19, 18 }, + /* 43 */ { L"%TVAR long long", L"abcdefghijklmnopqrstuv", 1, 16, TRUE, TRUE }, + /* 44 */ { L"%TVAR long long", L"%bcdefghijklmnopqrstuv", 2, 16, TRUE, TRUE }, + /* 45 */ { L"%TVAR long long", L"%Tcdefghijklmnopqrstuv", 3, 16, TRUE, TRUE }, + /* 46 */ { L"%TVAR long long", L"%TVAR long lonopqrstuv", 15, 16, TRUE, TRUE }, + /* 47 */ { L"%TVAR long long", L"%TVAR long long", 16, 16 }, + /* 48 */ { L"%TVAR long long", L"%TVAR long long", 17, 16 }, + }; + + success = SetEnvironmentVariableW(L"TVAR", L"WINE"); + ok(success, "SetEnvironmentVariableW failed with %ld\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = ExpandEnvironmentStringsW(L"Long long value", NULL, 0); + ok(ret == 16, "got %lu\n", ret); + todo_wine + ok(GetLastError() == 0xdeadbeef, "got last error %ld\n", GetLastError()); + + for (i = 0; i < ARRAY_SIZE(tests); i++) + { + const struct test_info *test = &tests[i]; + + SetLastError(0xdeadbeef); + wcscpy(buf, L"abcdefghijklmnopqrstuv"); + ret = ExpandEnvironmentStringsW(test->input, buf, test->count_in); + ok(ret == test->expected_count_out, "Test %d: got %lu\n", i, ret); + todo_wine_if(test->todo_status) + ok(GetLastError() == 0xdeadbeef, "Test %d: got last error %ld\n", i, GetLastError()); + todo_wine_if(test->todo_str) + ok(!wcscmp(buf, test->expected_str), "Test %d: got %s\n", i, debugstr_w(buf)); + } + + success = SetEnvironmentVariableW(L"TVAR", NULL); + ok(success, "SetEnvironmentVariableW failed with %ld\n", GetLastError()); +} + static void test_ExpandEnvironmentStringsA(void) { const char* value="Long long value"; @@ -780,6 +874,7 @@ START_TEST(environ) test_GetSetEnvironmentVariableA(); test_GetSetEnvironmentVariableW(); test_GetSetEnvironmentVariableAW(); + test_ExpandEnvironmentStringsW(); test_ExpandEnvironmentStringsA(); test_GetComputerName(); test_GetComputerNameExA();
From: Fabian Maurer dark.shadow4@web.de
--- dlls/kernel32/tests/environ.c | 91 +++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+)
diff --git a/dlls/kernel32/tests/environ.c b/dlls/kernel32/tests/environ.c index 36cedcdeaf5..22a73bb8dde 100644 --- a/dlls/kernel32/tests/environ.c +++ b/dlls/kernel32/tests/environ.c @@ -479,6 +479,70 @@ static void test_ExpandEnvironmentStringsA(void) const char* not_an_env_var="%NotAnEnvVar%"; char buf[256], buf1[256], buf2[0x8000]; DWORD ret_size, ret_size1; + int i; + DWORD ret; + BOOL success; + static const struct test_info + { + const char *input; + const char *expected_str; + int count_in; + int expected_count_out; + BOOL todo_status; + BOOL todo_str; + BOOL todo_len; + } tests[] = + { + /* 0 */ { "Long long value", "", 0, 17, TRUE, TRUE, TRUE }, + /* 1 */ { "Long long value", "", 1, 17, TRUE, FALSE, TRUE }, + /* 2 */ { "Long long value", "", 2, 17, TRUE, TRUE, TRUE }, + /* 3 */ { "Long long value", "", 3, 17, TRUE, TRUE, TRUE }, + /* 4 */ { "Long long value", "", 15, 17, TRUE, TRUE, TRUE }, + /* 5 */ { "Long long value", "", 16, 17, FALSE, TRUE, TRUE }, + /* 6 */ { "Long long value", "Long long value", 17, 16 }, + /* 7 */ { "%TVAR% long long", "", 0, 16, TRUE, TRUE, TRUE }, + /* 8 */ { "%TVAR% long long", "", 1, 16, TRUE, FALSE, TRUE }, + /* 9 */ { "%TVAR% long long", "", 2, 16, TRUE, TRUE, TRUE }, + /* 10 */ { "%TVAR% long long", "", 4, 16, TRUE, TRUE, TRUE }, + /* 11 */ { "%TVAR% long long", "", 5, 16, TRUE, TRUE, TRUE }, + /* 12 */ { "%TVAR% long long", "", 6, 16, TRUE, TRUE, TRUE }, + /* 13 */ { "%TVAR% long long", "", 7, 16, TRUE, TRUE, TRUE }, + /* 14 */ { "%TVAR% long long", "", 15, 16, FALSE, TRUE, TRUE }, + /* 15 */ { "%TVAR% long long", "WINE long long", 16, 15 }, + /* 16 */ { "%TVAR%%TVAR% long", "", 4, 15, TRUE, TRUE, TRUE }, + /* 17 */ { "%TVAR%%TVAR% long", "", 5, 15, TRUE, TRUE, TRUE }, + /* 18 */ { "%TVAR%%TVAR% long", "", 6, 15, TRUE, TRUE, TRUE }, + /* 19 */ { "%TVAR%%TVAR% long", "", 8, 15, TRUE, TRUE, TRUE }, + /* 20 */ { "%TVAR%%TVAR% long", "", 9, 15, TRUE, TRUE, TRUE }, + /* 21 */ { "%TVAR%%TVAR% long", "", 10, 15, TRUE, TRUE, TRUE }, + /* 22 */ { "%TVAR%%TVAR% long", "", 14, 15, FALSE, TRUE, TRUE }, + /* 23 */ { "%TVAR%%TVAR% long", "WINEWINE long", 15, 14 }, + /* 24 */ { "%TVAR% %TVAR% long", "", 5, 16, TRUE, TRUE, TRUE }, + /* 25 */ { "%TVAR% %TVAR% long", "", 6, 16, TRUE, TRUE, TRUE }, + /* 26 */ { "%TVAR% %TVAR% long", "", 8, 16, TRUE, TRUE, TRUE }, + /* 27 */ { "%TVAR% %TVAR% long", "", 9, 16, TRUE, TRUE, TRUE }, + /* 28 */ { "%TVAR% %TVAR% long", "", 10, 16, TRUE, TRUE, TRUE }, + /* 29 */ { "%TVAR% %TVAR% long", "", 11, 16, TRUE, TRUE, TRUE }, + /* 30 */ { "%TVAR% %TVAR% long", "", 12, 16, TRUE, TRUE, TRUE }, + /* 31 */ { "%TVAR% %TVAR% long", "", 14, 16, TRUE, TRUE, TRUE }, + /* 32 */ { "%TVAR% %TVAR% long", "", 15, 16, FALSE, TRUE, TRUE }, + /* 33 */ { "%TVAR% %TVAR% long", "WINE WINE long", 16, 15 }, + /* 34 */ { "%TVAR2% long long", "", 1, 19, TRUE, FALSE, TRUE }, + /* 35 */ { "%TVAR2% long long", "", 2, 19, TRUE, TRUE, TRUE }, + /* 36 */ { "%TVAR2% long long", "", 4, 19, TRUE, TRUE, TRUE }, + /* 37 */ { "%TVAR2% long long", "", 7, 19, TRUE, TRUE, TRUE }, + /* 38 */ { "%TVAR2% long long", "", 8, 19, TRUE, TRUE, TRUE }, + /* 39 */ { "%TVAR2% long long", "", 9, 19, TRUE, TRUE, TRUE }, + /* 40 */ { "%TVAR2% long long", "", 10, 19, TRUE, TRUE, TRUE }, + /* 41 */ { "%TVAR2% long long", "", 18, 19, FALSE, TRUE, TRUE }, + /* 42 */ { "%TVAR2% long long", "%TVAR2% long long", 19, 18 }, + /* 43 */ { "%TVAR long long", "", 1, 17, TRUE, FALSE, TRUE }, + /* 44 */ { "%TVAR long long", "", 2, 17, TRUE, TRUE, TRUE }, + /* 45 */ { "%TVAR long long", "", 3, 17, TRUE, TRUE, TRUE }, + /* 46 */ { "%TVAR long long", "", 15, 17, TRUE, TRUE, TRUE }, + /* 47 */ { "%TVAR long long", "", 16, 17, FALSE, TRUE, TRUE }, + /* 48 */ { "%TVAR long long", "%TVAR long long", 17, 16 }, + };
SetEnvironmentVariableA("EnvVar", value);
@@ -555,6 +619,33 @@ static void test_ExpandEnvironmentStringsA(void) SetEnvironmentVariableA("IndirectVar", NULL);
SetEnvironmentVariableA("EnvVar", NULL); + + success = SetEnvironmentVariableA("TVAR", "WINE"); + ok(success, "SetEnvironmentVariableA failed with %ld\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = ExpandEnvironmentStringsW(L"Long long value", NULL, 0); + ok(ret == 16, "got %lu\n", ret); + todo_wine + ok(GetLastError() == 0xdeadbeef, "got last error %ld\n", GetLastError()); + + for (i = 0; i < ARRAY_SIZE(tests); i++) + { + const struct test_info *test = &tests[i]; + + SetLastError(0xdeadbeef); + strcpy(buf, "abcdefghijklmnopqrstuv"); + ret = ExpandEnvironmentStringsA(test->input, buf, test->count_in); + todo_wine_if(test->todo_len) + ok(ret == test->expected_count_out, "Test %d: got %lu\n", i, ret); + todo_wine_if(test->todo_status) + ok(GetLastError() == 0xdeadbeef, "Test %d: got last error %ld\n", i, GetLastError()); + todo_wine_if(test->todo_str) + ok(!strcmp(buf, test->expected_str), "Test %d: got %s\n", i, debugstr_a(buf)); + } + + success = SetEnvironmentVariableA("TVAR", NULL); + ok(success, "SetEnvironmentVariableA failed with %ld\n", GetLastError()); }
static void test_GetComputerName(void)
From: Fabian Maurer dark.shadow4@web.de
--- dlls/kernel32/tests/environ.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+)
diff --git a/dlls/kernel32/tests/environ.c b/dlls/kernel32/tests/environ.c index 22a73bb8dde..6a7844480cc 100644 --- a/dlls/kernel32/tests/environ.c +++ b/dlls/kernel32/tests/environ.c @@ -646,6 +646,39 @@ static void test_ExpandEnvironmentStringsA(void)
success = SetEnvironmentVariableA("TVAR", NULL); ok(success, "SetEnvironmentVariableA failed with %ld\n", GetLastError()); + + if (GetACP() == 932) /* shift-jis */ + { + const char *japanese_test = "\x88\xEA\x93\xF1\x8E\x4F\x8E\x6C\x8C\xDC\x98\x5A\x8E\xB5\x94\xAA\x8B\xE3"; /* Japanese Kanji for "one" to "nine", in shift-jis */ + int japanese_len = strlen(japanese_test); + + SetLastError(0xdeadbeef); + ret_size = ExpandEnvironmentStringsA(japanese_test, NULL, 0); + todo_wine + ok(GetLastError() == 0xdeadbeef, "got last error %ld\n", GetLastError()); + todo_wine + ok(ret_size >= japanese_len, "Needed at least %d, got %lu\n", japanese_len, ret_size); + + SetLastError(0xdeadbeef); + ret_size = ExpandEnvironmentStringsA(japanese_test, buf, ret_size); + todo_wine + ok(GetLastError() == 0xdeadbeef, "got last error %ld\n", GetLastError()); + todo_wine + ok(ret_size >= japanese_len, "Needed at least %d, got %lu\n", japanese_len, ret_size); + todo_wine + ok(!strcmp(buf, japanese_test), "Got %s\n", debugstr_a(buf)); + + SetLastError(0xdeadbeef); + ret_size = ExpandEnvironmentStringsA(japanese_test, buf, japanese_len / 2); /* Buffer too small */ + todo_wine + ok(GetLastError() == 0xdeadbeef, "got last error %ld\n", GetLastError()); + todo_wine + ok(ret_size >= japanese_len, "Needed at least %d, got %lu\n", japanese_len, ret_size); + } + else + { + skip("Skipping japanese language tests\n"); + } }
static void test_GetComputerName(void)
From: Fabian Maurer dark.shadow4@web.de
--- dlls/kernel32/tests/environ.c | 20 +++++----- dlls/ntdll/env.c | 15 ++++++-- dlls/ntdll/tests/env.c | 70 +++++++++++++++++------------------ dlls/shcore/tests/shcore.c | 3 -- dlls/shlwapi/tests/shreg.c | 7 +--- 5 files changed, 59 insertions(+), 56 deletions(-)
diff --git a/dlls/kernel32/tests/environ.c b/dlls/kernel32/tests/environ.c index 6a7844480cc..ec5842c4a9e 100644 --- a/dlls/kernel32/tests/environ.c +++ b/dlls/kernel32/tests/environ.c @@ -404,25 +404,25 @@ static void test_ExpandEnvironmentStringsW(void) /* 6 */ { L"Long long value", L"Long long value", 17, 16 }, /* 7 */ { L"%TVAR% long long", L"abcdefghijklmnopqrstuv", 0, 15, TRUE }, /* 8 */ { L"%TVAR% long long", L"", 1, 15, TRUE }, - /* 9 */ { L"%TVAR% long long", L"", 2, 15, TRUE, TRUE }, - /* 10 */ { L"%TVAR% long long", L"", 4, 15, TRUE, TRUE }, + /* 9 */ { L"%TVAR% long long", L"", 2, 15, TRUE }, + /* 10 */ { L"%TVAR% long long", L"", 4, 15, TRUE }, /* 11 */ { L"%TVAR% long long", L"WINE", 5, 15, TRUE }, /* 12 */ { L"%TVAR% long long", L"WINE fghijklmnopqrstuv", 6, 15, TRUE, TRUE }, /* 13 */ { L"%TVAR% long long", L"WINE lghijklmnopqrstuv", 7, 15, TRUE, TRUE }, /* 14 */ { L"%TVAR% long long", L"WINE long long", 15, 15 }, /* 15 */ { L"%TVAR% long long", L"WINE long long", 16, 15 }, - /* 16 */ { L"%TVAR%%TVAR% long", L"", 4, 14, TRUE, TRUE }, + /* 16 */ { L"%TVAR%%TVAR% long", L"", 4, 14, TRUE }, /* 17 */ { L"%TVAR%%TVAR% long", L"WINE", 5, 14, TRUE }, - /* 18 */ { L"%TVAR%%TVAR% long", L"WINE", 6, 14, TRUE, TRUE }, - /* 19 */ { L"%TVAR%%TVAR% long", L"WINE", 8, 14, TRUE, TRUE }, + /* 18 */ { L"%TVAR%%TVAR% long", L"WINE", 6, 14, TRUE }, + /* 19 */ { L"%TVAR%%TVAR% long", L"WINE", 8, 14, TRUE }, /* 20 */ { L"%TVAR%%TVAR% long", L"WINEWINE", 9, 14, TRUE }, /* 21 */ { L"%TVAR%%TVAR% long", L"WINEWINE jklmnopqrstuv", 10, 14, TRUE, TRUE }, /* 22 */ { L"%TVAR%%TVAR% long", L"WINEWINE long", 14, 14 }, /* 23 */ { L"%TVAR%%TVAR% long", L"WINEWINE long", 15, 14 }, /* 24 */ { L"%TVAR% %TVAR% long", L"WINE", 5, 15, TRUE }, /* 25 */ { L"%TVAR% %TVAR% long", L"WINE ", 6, 15, TRUE }, - /* 26 */ { L"%TVAR% %TVAR% long", L"WINE ", 8, 15, TRUE, TRUE }, - /* 27 */ { L"%TVAR% %TVAR% long", L"WINE ", 9, 15, TRUE, TRUE }, + /* 26 */ { L"%TVAR% %TVAR% long", L"WINE ", 8, 15, TRUE }, + /* 27 */ { L"%TVAR% %TVAR% long", L"WINE ", 9, 15, TRUE }, /* 28 */ { L"%TVAR% %TVAR% long", L"WINE WINE", 10, 15, TRUE }, /* 29 */ { L"%TVAR% %TVAR% long", L"WINE WINE klmnopqrstuv", 11, 15, TRUE, TRUE }, /* 30 */ { L"%TVAR% %TVAR% long", L"WINE WINE llmnopqrstuv", 12, 15, TRUE, TRUE }, @@ -502,14 +502,14 @@ static void test_ExpandEnvironmentStringsA(void) /* 6 */ { "Long long value", "Long long value", 17, 16 }, /* 7 */ { "%TVAR% long long", "", 0, 16, TRUE, TRUE, TRUE }, /* 8 */ { "%TVAR% long long", "", 1, 16, TRUE, FALSE, TRUE }, - /* 9 */ { "%TVAR% long long", "", 2, 16, TRUE, TRUE, TRUE }, - /* 10 */ { "%TVAR% long long", "", 4, 16, TRUE, TRUE, TRUE }, + /* 9 */ { "%TVAR% long long", "", 2, 16, TRUE, FALSE, TRUE }, + /* 10 */ { "%TVAR% long long", "", 4, 16, TRUE, FALSE, TRUE }, /* 11 */ { "%TVAR% long long", "", 5, 16, TRUE, TRUE, TRUE }, /* 12 */ { "%TVAR% long long", "", 6, 16, TRUE, TRUE, TRUE }, /* 13 */ { "%TVAR% long long", "", 7, 16, TRUE, TRUE, TRUE }, /* 14 */ { "%TVAR% long long", "", 15, 16, FALSE, TRUE, TRUE }, /* 15 */ { "%TVAR% long long", "WINE long long", 16, 15 }, - /* 16 */ { "%TVAR%%TVAR% long", "", 4, 15, TRUE, TRUE, TRUE }, + /* 16 */ { "%TVAR%%TVAR% long", "", 4, 15, TRUE, FALSE, TRUE }, /* 17 */ { "%TVAR%%TVAR% long", "", 5, 15, TRUE, TRUE, TRUE }, /* 18 */ { "%TVAR%%TVAR% long", "", 6, 15, TRUE, TRUE, TRUE }, /* 19 */ { "%TVAR%%TVAR% long", "", 8, 15, TRUE, TRUE, TRUE }, diff --git a/dlls/ntdll/env.c b/dlls/ntdll/env.c index 720597dcaf9..58bfdbb9fe8 100644 --- a/dlls/ntdll/env.c +++ b/dlls/ntdll/env.c @@ -384,7 +384,7 @@ done: NTSTATUS WINAPI RtlExpandEnvironmentStrings( const WCHAR *renv, WCHAR *src, SIZE_T src_len, WCHAR *dst, SIZE_T count, SIZE_T *plen ) { - SIZE_T len, total_size = 1; /* 1 for terminating '\0' */ + SIZE_T len, copy, total_size = 1; /* 1 for terminating '\0' */ LPCWSTR env, var;
if (!renv) @@ -402,6 +402,7 @@ NTSTATUS WINAPI RtlExpandEnvironmentStrings( const WCHAR *renv, WCHAR *src, SIZE var = src; src += len; src_len -= len; + copy = len; } else /* we are at the start of a variable */ { @@ -413,6 +414,11 @@ NTSTATUS WINAPI RtlExpandEnvironmentStrings( const WCHAR *renv, WCHAR *src, SIZE src += len + 1; /* Skip the variable name */ src_len -= len + 1; len = wcslen(var); + copy = len; + if (count <= copy) /* Either copy the entire value, or nothing at all */ + copy = 0; + if (dst && count) /* When the variable is the last thing that fits into dst, the string is null terminated */ + dst[copy] = 0; /* Either right after, or if it doesn't fit, where it would start */ } else { @@ -420,6 +426,7 @@ NTSTATUS WINAPI RtlExpandEnvironmentStrings( const WCHAR *renv, WCHAR *src, SIZE len++; src += len; src_len -= len; + copy = len; } } else /* unfinished variable name, ignore it */ @@ -427,15 +434,17 @@ NTSTATUS WINAPI RtlExpandEnvironmentStrings( const WCHAR *renv, WCHAR *src, SIZE var = src; src += len; src_len = 0; + copy = len; } } total_size += len; if (dst) { if (count < len) len = count; - memcpy(dst, var, len * sizeof(WCHAR)); + if (count <= copy) copy = count ? count - 1 : 0; /* If the buffer is too small, we copy one character less */ + memcpy(dst, var, copy * sizeof(WCHAR)); count -= len; - dst += len; + dst += copy; } }
diff --git a/dlls/ntdll/tests/env.c b/dlls/ntdll/tests/env.c index ad653afa439..1760501a434 100644 --- a/dlls/ntdll/tests/env.c +++ b/dlls/ntdll/tests/env.c @@ -260,52 +260,52 @@ static void test_RtlExpandEnvironmentStrings(void) } tests[] = { /* 0 */ { L"Long long value", L"abcdefghijklmnopqrstuv", 0, 16 }, - /* 1 */ { L"Long long value", L"abcdefghijklmnopqrstuv", 1, 16, TRUE }, - /* 2 */ { L"Long long value", L"Lbcdefghijklmnopqrstuv", 2, 16, TRUE }, - /* 3 */ { L"Long long value", L"Locdefghijklmnopqrstuv", 3, 16, TRUE }, - /* 4 */ { L"Long long value", L"Long long valuopqrstuv", 15, 16, TRUE }, + /* 1 */ { L"Long long value", L"abcdefghijklmnopqrstuv", 1, 16 }, + /* 2 */ { L"Long long value", L"Lbcdefghijklmnopqrstuv", 2, 16 }, + /* 3 */ { L"Long long value", L"Locdefghijklmnopqrstuv", 3, 16 }, + /* 4 */ { L"Long long value", L"Long long valuopqrstuv", 15, 16 }, /* 5 */ { L"Long long value", L"Long long value", 16, 16 }, /* 6 */ { L"Long long value", L"Long long value", 17, 16 }, /* 7 */ { L"%TVAR% long long", L"abcdefghijklmnopqrstuv", 0, 15 }, - /* 8 */ { L"%TVAR% long long", L"", 1, 15, TRUE }, - /* 9 */ { L"%TVAR% long long", L"", 2, 15, TRUE }, - /* 10 */ { L"%TVAR% long long", L"", 4, 15, TRUE }, - /* 11 */ { L"%TVAR% long long", L"WINE", 5, 15, TRUE }, - /* 12 */ { L"%TVAR% long long", L"WINE fghijklmnopqrstuv", 6, 15, TRUE }, - /* 13 */ { L"%TVAR% long long", L"WINE lghijklmnopqrstuv", 7, 15, TRUE }, + /* 8 */ { L"%TVAR% long long", L"", 1, 15 }, + /* 9 */ { L"%TVAR% long long", L"", 2, 15 }, + /* 10 */ { L"%TVAR% long long", L"", 4, 15 }, + /* 11 */ { L"%TVAR% long long", L"WINE", 5, 15 }, + /* 12 */ { L"%TVAR% long long", L"WINE fghijklmnopqrstuv", 6, 15 }, + /* 13 */ { L"%TVAR% long long", L"WINE lghijklmnopqrstuv", 7, 15 }, /* 14 */ { L"%TVAR% long long", L"WINE long long", 15, 15 }, /* 15 */ { L"%TVAR% long long", L"WINE long long", 16, 15 }, - /* 16 */ { L"%TVAR%%TVAR% long", L"", 4, 14, TRUE }, - /* 17 */ { L"%TVAR%%TVAR% long", L"WINE", 5, 14, TRUE }, - /* 18 */ { L"%TVAR%%TVAR% long", L"WINE", 6, 14, TRUE }, - /* 19 */ { L"%TVAR%%TVAR% long", L"WINE", 8, 14, TRUE }, - /* 20 */ { L"%TVAR%%TVAR% long", L"WINEWINE", 9, 14, TRUE }, - /* 21 */ { L"%TVAR%%TVAR% long", L"WINEWINE jklmnopqrstuv", 10, 14, TRUE }, + /* 16 */ { L"%TVAR%%TVAR% long", L"", 4, 14 }, + /* 17 */ { L"%TVAR%%TVAR% long", L"WINE", 5, 14 }, + /* 18 */ { L"%TVAR%%TVAR% long", L"WINE", 6, 14 }, + /* 19 */ { L"%TVAR%%TVAR% long", L"WINE", 8, 14 }, + /* 20 */ { L"%TVAR%%TVAR% long", L"WINEWINE", 9, 14 }, + /* 21 */ { L"%TVAR%%TVAR% long", L"WINEWINE jklmnopqrstuv", 10, 14 }, /* 22 */ { L"%TVAR%%TVAR% long", L"WINEWINE long", 14, 14 }, /* 23 */ { L"%TVAR%%TVAR% long", L"WINEWINE long", 15, 14 }, - /* 24 */ { L"%TVAR% %TVAR% long", L"WINE", 5, 15, TRUE }, - /* 25 */ { L"%TVAR% %TVAR% long", L"WINE ", 6, 15, TRUE }, - /* 26 */ { L"%TVAR% %TVAR% long", L"WINE ", 8, 15, TRUE }, - /* 27 */ { L"%TVAR% %TVAR% long", L"WINE ", 9, 15, TRUE }, - /* 28 */ { L"%TVAR% %TVAR% long", L"WINE WINE", 10, 15, TRUE }, - /* 29 */ { L"%TVAR% %TVAR% long", L"WINE WINE klmnopqrstuv", 11, 15, TRUE }, - /* 30 */ { L"%TVAR% %TVAR% long", L"WINE WINE llmnopqrstuv", 12, 15, TRUE }, - /* 31 */ { L"%TVAR% %TVAR% long", L"WINE WINE lonnopqrstuv", 14, 15, TRUE }, + /* 24 */ { L"%TVAR% %TVAR% long", L"WINE", 5, 15 }, + /* 25 */ { L"%TVAR% %TVAR% long", L"WINE ", 6, 15 }, + /* 26 */ { L"%TVAR% %TVAR% long", L"WINE ", 8, 15 }, + /* 27 */ { L"%TVAR% %TVAR% long", L"WINE ", 9, 15 }, + /* 28 */ { L"%TVAR% %TVAR% long", L"WINE WINE", 10, 15 }, + /* 29 */ { L"%TVAR% %TVAR% long", L"WINE WINE klmnopqrstuv", 11, 15 }, + /* 30 */ { L"%TVAR% %TVAR% long", L"WINE WINE llmnopqrstuv", 12, 15 }, + /* 31 */ { L"%TVAR% %TVAR% long", L"WINE WINE lonnopqrstuv", 14, 15 }, /* 32 */ { L"%TVAR% %TVAR% long", L"WINE WINE long", 15, 15 }, /* 33 */ { L"%TVAR% %TVAR% long", L"WINE WINE long", 16, 15 }, - /* 34 */ { L"%TVAR2% long long", L"abcdefghijklmnopqrstuv", 1, 18, TRUE }, - /* 35 */ { L"%TVAR2% long long", L"%bcdefghijklmnopqrstuv", 2, 18, TRUE }, - /* 36 */ { L"%TVAR2% long long", L"%TVdefghijklmnopqrstuv", 4, 18, TRUE }, - /* 37 */ { L"%TVAR2% long long", L"%TVAR2ghijklmnopqrstuv", 7, 18, TRUE }, - /* 38 */ { L"%TVAR2% long long", L"%TVAR2%hijklmnopqrstuv", 8, 18, TRUE }, - /* 39 */ { L"%TVAR2% long long", L"%TVAR2% ijklmnopqrstuv", 9, 18, TRUE }, - /* 40 */ { L"%TVAR2% long long", L"%TVAR2% ljklmnopqrstuv", 10, 18, TRUE }, + /* 34 */ { L"%TVAR2% long long", L"abcdefghijklmnopqrstuv", 1, 18 }, + /* 35 */ { L"%TVAR2% long long", L"%bcdefghijklmnopqrstuv", 2, 18 }, + /* 36 */ { L"%TVAR2% long long", L"%TVdefghijklmnopqrstuv", 4, 18 }, + /* 37 */ { L"%TVAR2% long long", L"%TVAR2ghijklmnopqrstuv", 7, 18 }, + /* 38 */ { L"%TVAR2% long long", L"%TVAR2%hijklmnopqrstuv", 8, 18 }, + /* 39 */ { L"%TVAR2% long long", L"%TVAR2% ijklmnopqrstuv", 9, 18 }, + /* 40 */ { L"%TVAR2% long long", L"%TVAR2% ljklmnopqrstuv", 10, 18 }, /* 41 */ { L"%TVAR2% long long", L"%TVAR2% long long", 18, 18 }, /* 42 */ { L"%TVAR2% long long", L"%TVAR2% long long", 19, 18 }, - /* 43 */ { L"%TVAR long long", L"abcdefghijklmnopqrstuv", 1, 16, TRUE }, - /* 44 */ { L"%TVAR long long", L"%bcdefghijklmnopqrstuv", 2, 16, TRUE }, - /* 45 */ { L"%TVAR long long", L"%Tcdefghijklmnopqrstuv", 3, 16, TRUE }, - /* 46 */ { L"%TVAR long long", L"%TVAR long lonopqrstuv", 15, 16, TRUE }, + /* 43 */ { L"%TVAR long long", L"abcdefghijklmnopqrstuv", 1, 16 }, + /* 44 */ { L"%TVAR long long", L"%bcdefghijklmnopqrstuv", 2, 16 }, + /* 45 */ { L"%TVAR long long", L"%Tcdefghijklmnopqrstuv", 3, 16 }, + /* 46 */ { L"%TVAR long long", L"%TVAR long lonopqrstuv", 15, 16 }, /* 47 */ { L"%TVAR long long", L"%TVAR long long", 16, 16 }, /* 48 */ { L"%TVAR long long", L"%TVAR long long", 17, 16 }, }; diff --git a/dlls/shcore/tests/shcore.c b/dlls/shcore/tests/shcore.c index af6b3b392f3..731fa340e8b 100644 --- a/dlls/shcore/tests/shcore.c +++ b/dlls/shcore/tests/shcore.c @@ -567,10 +567,7 @@ static void test_SHQueryValueEx(void) ret = pSHQueryValueExA(hKey, "Test3", NULL, &type, buf, &size); ok(ret == ERROR_MORE_DATA, "Unexpected retval %ld.\n", ret);
- todo_wine - { ok(!strcmp("", buf), "Unexpanded string %s.\n", buf); - }
ok(size >= buffer_len2, "Buffer size %lu should be >= %lu.\n", size, buffer_len2); ok(type == REG_SZ, "Unexpected type %ld.\n", type); diff --git a/dlls/shlwapi/tests/shreg.c b/dlls/shlwapi/tests/shreg.c index bc411779c8f..75d4dfae7eb 100644 --- a/dlls/shlwapi/tests/shreg.c +++ b/dlls/shlwapi/tests/shreg.c @@ -290,11 +290,8 @@ static void test_SHQueryValueEx(void) broken(ERROR_SUCCESS == dwRet), /* < IE5.5*/ "Expected ERROR_MORE_DATA, got (%lu)\n", dwRet);
- todo_wine - { - ok( (0 == strcmp("", buf)) || (0 == strcmp(sTestpath2, buf)), - "Expected empty or unexpanded string (win98), got (%s)\n", buf); - } + ok( (0 == strcmp("", buf)) || (0 == strcmp(sTestpath2, buf)), + "Expected empty or unexpanded string (win98), got (%s)\n", buf);
ok( dwSize >= nUsedBuffer2 || broken(dwSize == (strlen("") + 1)), /* < IE 5.5 */
From: Fabian Maurer dark.shadow4@web.de
--- dlls/kernel32/tests/environ.c | 87 +++++++++++++++++------------------ dlls/kernelbase/process.c | 6 +-- 2 files changed, 45 insertions(+), 48 deletions(-)
diff --git a/dlls/kernel32/tests/environ.c b/dlls/kernel32/tests/environ.c index ec5842c4a9e..ec765758369 100644 --- a/dlls/kernel32/tests/environ.c +++ b/dlls/kernel32/tests/environ.c @@ -395,53 +395,53 @@ static void test_ExpandEnvironmentStringsW(void) BOOL todo_str; } tests[] = { - /* 0 */ { L"Long long value", L"abcdefghijklmnopqrstuv", 0, 16, TRUE }, - /* 1 */ { L"Long long value", L"abcdefghijklmnopqrstuv", 1, 16, TRUE, TRUE }, - /* 2 */ { L"Long long value", L"Lbcdefghijklmnopqrstuv", 2, 16, TRUE, TRUE }, - /* 3 */ { L"Long long value", L"Locdefghijklmnopqrstuv", 3, 16, TRUE, TRUE }, - /* 4 */ { L"Long long value", L"Long long valuopqrstuv", 15, 16, TRUE, TRUE }, + /* 0 */ { L"Long long value", L"abcdefghijklmnopqrstuv", 0, 16 }, + /* 1 */ { L"Long long value", L"abcdefghijklmnopqrstuv", 1, 16 }, + /* 2 */ { L"Long long value", L"Lbcdefghijklmnopqrstuv", 2, 16 }, + /* 3 */ { L"Long long value", L"Locdefghijklmnopqrstuv", 3, 16 }, + /* 4 */ { L"Long long value", L"Long long valuopqrstuv", 15, 16 }, /* 5 */ { L"Long long value", L"Long long value", 16, 16 }, /* 6 */ { L"Long long value", L"Long long value", 17, 16 }, - /* 7 */ { L"%TVAR% long long", L"abcdefghijklmnopqrstuv", 0, 15, TRUE }, - /* 8 */ { L"%TVAR% long long", L"", 1, 15, TRUE }, - /* 9 */ { L"%TVAR% long long", L"", 2, 15, TRUE }, - /* 10 */ { L"%TVAR% long long", L"", 4, 15, TRUE }, - /* 11 */ { L"%TVAR% long long", L"WINE", 5, 15, TRUE }, - /* 12 */ { L"%TVAR% long long", L"WINE fghijklmnopqrstuv", 6, 15, TRUE, TRUE }, - /* 13 */ { L"%TVAR% long long", L"WINE lghijklmnopqrstuv", 7, 15, TRUE, TRUE }, + /* 7 */ { L"%TVAR% long long", L"abcdefghijklmnopqrstuv", 0, 15 }, + /* 8 */ { L"%TVAR% long long", L"", 1, 15 }, + /* 9 */ { L"%TVAR% long long", L"", 2, 15 }, + /* 10 */ { L"%TVAR% long long", L"", 4, 15 }, + /* 11 */ { L"%TVAR% long long", L"WINE", 5, 15 }, + /* 12 */ { L"%TVAR% long long", L"WINE fghijklmnopqrstuv", 6, 15 }, + /* 13 */ { L"%TVAR% long long", L"WINE lghijklmnopqrstuv", 7, 15 }, /* 14 */ { L"%TVAR% long long", L"WINE long long", 15, 15 }, /* 15 */ { L"%TVAR% long long", L"WINE long long", 16, 15 }, - /* 16 */ { L"%TVAR%%TVAR% long", L"", 4, 14, TRUE }, - /* 17 */ { L"%TVAR%%TVAR% long", L"WINE", 5, 14, TRUE }, - /* 18 */ { L"%TVAR%%TVAR% long", L"WINE", 6, 14, TRUE }, - /* 19 */ { L"%TVAR%%TVAR% long", L"WINE", 8, 14, TRUE }, - /* 20 */ { L"%TVAR%%TVAR% long", L"WINEWINE", 9, 14, TRUE }, - /* 21 */ { L"%TVAR%%TVAR% long", L"WINEWINE jklmnopqrstuv", 10, 14, TRUE, TRUE }, + /* 16 */ { L"%TVAR%%TVAR% long", L"", 4, 14 }, + /* 17 */ { L"%TVAR%%TVAR% long", L"WINE", 5, 14 }, + /* 18 */ { L"%TVAR%%TVAR% long", L"WINE", 6, 14 }, + /* 19 */ { L"%TVAR%%TVAR% long", L"WINE", 8, 14 }, + /* 20 */ { L"%TVAR%%TVAR% long", L"WINEWINE", 9, 14 }, + /* 21 */ { L"%TVAR%%TVAR% long", L"WINEWINE jklmnopqrstuv", 10, 14 }, /* 22 */ { L"%TVAR%%TVAR% long", L"WINEWINE long", 14, 14 }, /* 23 */ { L"%TVAR%%TVAR% long", L"WINEWINE long", 15, 14 }, - /* 24 */ { L"%TVAR% %TVAR% long", L"WINE", 5, 15, TRUE }, - /* 25 */ { L"%TVAR% %TVAR% long", L"WINE ", 6, 15, TRUE }, - /* 26 */ { L"%TVAR% %TVAR% long", L"WINE ", 8, 15, TRUE }, - /* 27 */ { L"%TVAR% %TVAR% long", L"WINE ", 9, 15, TRUE }, - /* 28 */ { L"%TVAR% %TVAR% long", L"WINE WINE", 10, 15, TRUE }, - /* 29 */ { L"%TVAR% %TVAR% long", L"WINE WINE klmnopqrstuv", 11, 15, TRUE, TRUE }, - /* 30 */ { L"%TVAR% %TVAR% long", L"WINE WINE llmnopqrstuv", 12, 15, TRUE, TRUE }, - /* 31 */ { L"%TVAR% %TVAR% long", L"WINE WINE lonnopqrstuv", 14, 15, TRUE, TRUE }, + /* 24 */ { L"%TVAR% %TVAR% long", L"WINE", 5, 15 }, + /* 25 */ { L"%TVAR% %TVAR% long", L"WINE ", 6, 15 }, + /* 26 */ { L"%TVAR% %TVAR% long", L"WINE ", 8, 15 }, + /* 27 */ { L"%TVAR% %TVAR% long", L"WINE ", 9, 15 }, + /* 28 */ { L"%TVAR% %TVAR% long", L"WINE WINE", 10, 15 }, + /* 29 */ { L"%TVAR% %TVAR% long", L"WINE WINE klmnopqrstuv", 11, 15 }, + /* 30 */ { L"%TVAR% %TVAR% long", L"WINE WINE llmnopqrstuv", 12, 15 }, + /* 31 */ { L"%TVAR% %TVAR% long", L"WINE WINE lonnopqrstuv", 14, 15 }, /* 32 */ { L"%TVAR% %TVAR% long", L"WINE WINE long", 15, 15 }, /* 33 */ { L"%TVAR% %TVAR% long", L"WINE WINE long", 16, 15 }, - /* 34 */ { L"%TVAR2% long long", L"abcdefghijklmnopqrstuv", 1, 18, TRUE, TRUE }, - /* 35 */ { L"%TVAR2% long long", L"%bcdefghijklmnopqrstuv", 2, 18, TRUE, TRUE }, - /* 36 */ { L"%TVAR2% long long", L"%TVdefghijklmnopqrstuv", 4, 18, TRUE, TRUE }, - /* 37 */ { L"%TVAR2% long long", L"%TVAR2ghijklmnopqrstuv", 7, 18, TRUE, TRUE }, - /* 38 */ { L"%TVAR2% long long", L"%TVAR2%hijklmnopqrstuv", 8, 18, TRUE, TRUE }, - /* 39 */ { L"%TVAR2% long long", L"%TVAR2% ijklmnopqrstuv", 9, 18, TRUE, TRUE }, - /* 40 */ { L"%TVAR2% long long", L"%TVAR2% ljklmnopqrstuv", 10, 18, TRUE, TRUE }, + /* 34 */ { L"%TVAR2% long long", L"abcdefghijklmnopqrstuv", 1, 18 }, + /* 35 */ { L"%TVAR2% long long", L"%bcdefghijklmnopqrstuv", 2, 18 }, + /* 36 */ { L"%TVAR2% long long", L"%TVdefghijklmnopqrstuv", 4, 18 }, + /* 37 */ { L"%TVAR2% long long", L"%TVAR2ghijklmnopqrstuv", 7, 18 }, + /* 38 */ { L"%TVAR2% long long", L"%TVAR2%hijklmnopqrstuv", 8, 18 }, + /* 39 */ { L"%TVAR2% long long", L"%TVAR2% ijklmnopqrstuv", 9, 18 }, + /* 40 */ { L"%TVAR2% long long", L"%TVAR2% ljklmnopqrstuv", 10, 18 }, /* 41 */ { L"%TVAR2% long long", L"%TVAR2% long long", 18, 18 }, /* 42 */ { L"%TVAR2% long long", L"%TVAR2% long long", 19, 18 }, - /* 43 */ { L"%TVAR long long", L"abcdefghijklmnopqrstuv", 1, 16, TRUE, TRUE }, - /* 44 */ { L"%TVAR long long", L"%bcdefghijklmnopqrstuv", 2, 16, TRUE, TRUE }, - /* 45 */ { L"%TVAR long long", L"%Tcdefghijklmnopqrstuv", 3, 16, TRUE, TRUE }, - /* 46 */ { L"%TVAR long long", L"%TVAR long lonopqrstuv", 15, 16, TRUE, TRUE }, + /* 43 */ { L"%TVAR long long", L"abcdefghijklmnopqrstuv", 1, 16 }, + /* 44 */ { L"%TVAR long long", L"%bcdefghijklmnopqrstuv", 2, 16 }, + /* 45 */ { L"%TVAR long long", L"%Tcdefghijklmnopqrstuv", 3, 16 }, + /* 46 */ { L"%TVAR long long", L"%TVAR long lonopqrstuv", 15, 16 }, /* 47 */ { L"%TVAR long long", L"%TVAR long long", 16, 16 }, /* 48 */ { L"%TVAR long long", L"%TVAR long long", 17, 16 }, }; @@ -452,7 +452,6 @@ static void test_ExpandEnvironmentStringsW(void) SetLastError(0xdeadbeef); ret = ExpandEnvironmentStringsW(L"Long long value", NULL, 0); ok(ret == 16, "got %lu\n", ret); - todo_wine ok(GetLastError() == 0xdeadbeef, "got last error %ld\n", GetLastError());
for (i = 0; i < ARRAY_SIZE(tests); i++) @@ -493,14 +492,14 @@ static void test_ExpandEnvironmentStringsA(void) BOOL todo_len; } tests[] = { - /* 0 */ { "Long long value", "", 0, 17, TRUE, TRUE, TRUE }, - /* 1 */ { "Long long value", "", 1, 17, TRUE, FALSE, TRUE }, + /* 0 */ { "Long long value", "", 0, 17, FALSE, TRUE, TRUE }, + /* 1 */ { "Long long value", "", 1, 17, TRUE, TRUE, TRUE }, /* 2 */ { "Long long value", "", 2, 17, TRUE, TRUE, TRUE }, /* 3 */ { "Long long value", "", 3, 17, TRUE, TRUE, TRUE }, /* 4 */ { "Long long value", "", 15, 17, TRUE, TRUE, TRUE }, /* 5 */ { "Long long value", "", 16, 17, FALSE, TRUE, TRUE }, /* 6 */ { "Long long value", "Long long value", 17, 16 }, - /* 7 */ { "%TVAR% long long", "", 0, 16, TRUE, TRUE, TRUE }, + /* 7 */ { "%TVAR% long long", "", 0, 16, FALSE, TRUE, TRUE }, /* 8 */ { "%TVAR% long long", "", 1, 16, TRUE, FALSE, TRUE }, /* 9 */ { "%TVAR% long long", "", 2, 16, TRUE, FALSE, TRUE }, /* 10 */ { "%TVAR% long long", "", 4, 16, TRUE, FALSE, TRUE }, @@ -527,7 +526,7 @@ static void test_ExpandEnvironmentStringsA(void) /* 31 */ { "%TVAR% %TVAR% long", "", 14, 16, TRUE, TRUE, TRUE }, /* 32 */ { "%TVAR% %TVAR% long", "", 15, 16, FALSE, TRUE, TRUE }, /* 33 */ { "%TVAR% %TVAR% long", "WINE WINE long", 16, 15 }, - /* 34 */ { "%TVAR2% long long", "", 1, 19, TRUE, FALSE, TRUE }, + /* 34 */ { "%TVAR2% long long", "", 1, 19, TRUE, TRUE, TRUE }, /* 35 */ { "%TVAR2% long long", "", 2, 19, TRUE, TRUE, TRUE }, /* 36 */ { "%TVAR2% long long", "", 4, 19, TRUE, TRUE, TRUE }, /* 37 */ { "%TVAR2% long long", "", 7, 19, TRUE, TRUE, TRUE }, @@ -536,7 +535,7 @@ static void test_ExpandEnvironmentStringsA(void) /* 40 */ { "%TVAR2% long long", "", 10, 19, TRUE, TRUE, TRUE }, /* 41 */ { "%TVAR2% long long", "", 18, 19, FALSE, TRUE, TRUE }, /* 42 */ { "%TVAR2% long long", "%TVAR2% long long", 19, 18 }, - /* 43 */ { "%TVAR long long", "", 1, 17, TRUE, FALSE, TRUE }, + /* 43 */ { "%TVAR long long", "", 1, 17, TRUE, TRUE, TRUE }, /* 44 */ { "%TVAR long long", "", 2, 17, TRUE, TRUE, TRUE }, /* 45 */ { "%TVAR long long", "", 3, 17, TRUE, TRUE, TRUE }, /* 46 */ { "%TVAR long long", "", 15, 17, TRUE, TRUE, TRUE }, @@ -626,7 +625,6 @@ static void test_ExpandEnvironmentStringsA(void) SetLastError(0xdeadbeef); ret = ExpandEnvironmentStringsW(L"Long long value", NULL, 0); ok(ret == 16, "got %lu\n", ret); - todo_wine ok(GetLastError() == 0xdeadbeef, "got last error %ld\n", GetLastError());
for (i = 0; i < ARRAY_SIZE(tests); i++) @@ -654,7 +652,6 @@ static void test_ExpandEnvironmentStringsA(void)
SetLastError(0xdeadbeef); ret_size = ExpandEnvironmentStringsA(japanese_test, NULL, 0); - todo_wine ok(GetLastError() == 0xdeadbeef, "got last error %ld\n", GetLastError()); todo_wine ok(ret_size >= japanese_len, "Needed at least %d, got %lu\n", japanese_len, ret_size); diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c index 2d08481cd35..c6f2f30b2d8 100644 --- a/dlls/kernelbase/process.c +++ b/dlls/kernelbase/process.c @@ -1487,10 +1487,10 @@ DWORD WINAPI DECLSPEC_HOTPATCH ExpandEnvironmentStringsW( LPCWSTR src, LPWSTR ds res = 0; status = RtlExpandEnvironmentStrings_U( NULL, &us_src, &us_dst, &res ); res /= sizeof(WCHAR); - if (!set_ntstatus( status )) + if (status != STATUS_BUFFER_TOO_SMALL) { - if (status != STATUS_BUFFER_TOO_SMALL) return 0; - if (len && dst) dst[len - 1] = 0; + if(!set_ntstatus( status )) + return 0; } return res; }
From: Fabian Maurer dark.shadow4@web.de
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54295 --- dlls/advapi32/tests/registry.c | 2 +- dlls/kernel32/tests/environ.c | 92 ++++++++++++++++------------------ dlls/kernelbase/process.c | 30 +++++++---- dlls/shcore/tests/shcore.c | 3 -- dlls/shlwapi/tests/shreg.c | 9 ++-- dlls/userenv/tests/userenv.c | 1 + 6 files changed, 69 insertions(+), 68 deletions(-)
diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c index 0f77b2fa066..2e4195e723f 100644 --- a/dlls/advapi32/tests/registry.c +++ b/dlls/advapi32/tests/registry.c @@ -934,7 +934,7 @@ static void test_get_value(void) size = 0; ret = pRegGetValueA(hkey_main, NULL, "TP2_EXP_SZ", RRF_RT_REG_SZ, NULL, NULL, &size); ok(ret == ERROR_SUCCESS, "ret=%ld\n", ret); - todo_wine ok(size == strlen(expanded2)+2, + ok(size == strlen(expanded2)+2, "strlen(expanded2)=%d, strlen(sTestpath2)=%d, size=%ld\n", lstrlenA(expanded2), lstrlenA(sTestpath2), size);
/* Query REG_EXPAND_SZ using RRF_RT_REG_SZ (ok, expands) */ diff --git a/dlls/kernel32/tests/environ.c b/dlls/kernel32/tests/environ.c index ec765758369..bd088d1670f 100644 --- a/dlls/kernel32/tests/environ.c +++ b/dlls/kernel32/tests/environ.c @@ -492,54 +492,54 @@ static void test_ExpandEnvironmentStringsA(void) BOOL todo_len; } tests[] = { - /* 0 */ { "Long long value", "", 0, 17, FALSE, TRUE, TRUE }, - /* 1 */ { "Long long value", "", 1, 17, TRUE, TRUE, TRUE }, - /* 2 */ { "Long long value", "", 2, 17, TRUE, TRUE, TRUE }, - /* 3 */ { "Long long value", "", 3, 17, TRUE, TRUE, TRUE }, - /* 4 */ { "Long long value", "", 15, 17, TRUE, TRUE, TRUE }, - /* 5 */ { "Long long value", "", 16, 17, FALSE, TRUE, TRUE }, + /* 0 */ { "Long long value", "", 0, 17 }, + /* 1 */ { "Long long value", "", 1, 17 }, + /* 2 */ { "Long long value", "", 2, 17 }, + /* 3 */ { "Long long value", "", 3, 17 }, + /* 4 */ { "Long long value", "", 15, 17 }, + /* 5 */ { "Long long value", "", 16, 17 }, /* 6 */ { "Long long value", "Long long value", 17, 16 }, - /* 7 */ { "%TVAR% long long", "", 0, 16, FALSE, TRUE, TRUE }, - /* 8 */ { "%TVAR% long long", "", 1, 16, TRUE, FALSE, TRUE }, - /* 9 */ { "%TVAR% long long", "", 2, 16, TRUE, FALSE, TRUE }, - /* 10 */ { "%TVAR% long long", "", 4, 16, TRUE, FALSE, TRUE }, - /* 11 */ { "%TVAR% long long", "", 5, 16, TRUE, TRUE, TRUE }, - /* 12 */ { "%TVAR% long long", "", 6, 16, TRUE, TRUE, TRUE }, - /* 13 */ { "%TVAR% long long", "", 7, 16, TRUE, TRUE, TRUE }, - /* 14 */ { "%TVAR% long long", "", 15, 16, FALSE, TRUE, TRUE }, + /* 7 */ { "%TVAR% long long", "", 0, 16 }, + /* 8 */ { "%TVAR% long long", "", 1, 16 }, + /* 9 */ { "%TVAR% long long", "", 2, 16 }, + /* 10 */ { "%TVAR% long long", "", 4, 16 }, + /* 11 */ { "%TVAR% long long", "", 5, 16 }, + /* 12 */ { "%TVAR% long long", "", 6, 16 }, + /* 13 */ { "%TVAR% long long", "", 7, 16 }, + /* 14 */ { "%TVAR% long long", "", 15, 16 }, /* 15 */ { "%TVAR% long long", "WINE long long", 16, 15 }, - /* 16 */ { "%TVAR%%TVAR% long", "", 4, 15, TRUE, FALSE, TRUE }, - /* 17 */ { "%TVAR%%TVAR% long", "", 5, 15, TRUE, TRUE, TRUE }, - /* 18 */ { "%TVAR%%TVAR% long", "", 6, 15, TRUE, TRUE, TRUE }, - /* 19 */ { "%TVAR%%TVAR% long", "", 8, 15, TRUE, TRUE, TRUE }, - /* 20 */ { "%TVAR%%TVAR% long", "", 9, 15, TRUE, TRUE, TRUE }, - /* 21 */ { "%TVAR%%TVAR% long", "", 10, 15, TRUE, TRUE, TRUE }, - /* 22 */ { "%TVAR%%TVAR% long", "", 14, 15, FALSE, TRUE, TRUE }, + /* 16 */ { "%TVAR%%TVAR% long", "", 4, 15 }, + /* 17 */ { "%TVAR%%TVAR% long", "", 5, 15 }, + /* 18 */ { "%TVAR%%TVAR% long", "", 6, 15 }, + /* 19 */ { "%TVAR%%TVAR% long", "", 8, 15 }, + /* 20 */ { "%TVAR%%TVAR% long", "", 9, 15 }, + /* 21 */ { "%TVAR%%TVAR% long", "", 10, 15 }, + /* 22 */ { "%TVAR%%TVAR% long", "", 14, 15 }, /* 23 */ { "%TVAR%%TVAR% long", "WINEWINE long", 15, 14 }, - /* 24 */ { "%TVAR% %TVAR% long", "", 5, 16, TRUE, TRUE, TRUE }, - /* 25 */ { "%TVAR% %TVAR% long", "", 6, 16, TRUE, TRUE, TRUE }, - /* 26 */ { "%TVAR% %TVAR% long", "", 8, 16, TRUE, TRUE, TRUE }, - /* 27 */ { "%TVAR% %TVAR% long", "", 9, 16, TRUE, TRUE, TRUE }, - /* 28 */ { "%TVAR% %TVAR% long", "", 10, 16, TRUE, TRUE, TRUE }, - /* 29 */ { "%TVAR% %TVAR% long", "", 11, 16, TRUE, TRUE, TRUE }, - /* 30 */ { "%TVAR% %TVAR% long", "", 12, 16, TRUE, TRUE, TRUE }, - /* 31 */ { "%TVAR% %TVAR% long", "", 14, 16, TRUE, TRUE, TRUE }, - /* 32 */ { "%TVAR% %TVAR% long", "", 15, 16, FALSE, TRUE, TRUE }, + /* 24 */ { "%TVAR% %TVAR% long", "", 5, 16 }, + /* 25 */ { "%TVAR% %TVAR% long", "", 6, 16 }, + /* 26 */ { "%TVAR% %TVAR% long", "", 8, 16 }, + /* 27 */ { "%TVAR% %TVAR% long", "", 9, 16 }, + /* 28 */ { "%TVAR% %TVAR% long", "", 10, 16 }, + /* 29 */ { "%TVAR% %TVAR% long", "", 11, 16 }, + /* 30 */ { "%TVAR% %TVAR% long", "", 12, 16 }, + /* 31 */ { "%TVAR% %TVAR% long", "", 14, 16 }, + /* 32 */ { "%TVAR% %TVAR% long", "", 15, 16 }, /* 33 */ { "%TVAR% %TVAR% long", "WINE WINE long", 16, 15 }, - /* 34 */ { "%TVAR2% long long", "", 1, 19, TRUE, TRUE, TRUE }, - /* 35 */ { "%TVAR2% long long", "", 2, 19, TRUE, TRUE, TRUE }, - /* 36 */ { "%TVAR2% long long", "", 4, 19, TRUE, TRUE, TRUE }, - /* 37 */ { "%TVAR2% long long", "", 7, 19, TRUE, TRUE, TRUE }, - /* 38 */ { "%TVAR2% long long", "", 8, 19, TRUE, TRUE, TRUE }, - /* 39 */ { "%TVAR2% long long", "", 9, 19, TRUE, TRUE, TRUE }, - /* 40 */ { "%TVAR2% long long", "", 10, 19, TRUE, TRUE, TRUE }, - /* 41 */ { "%TVAR2% long long", "", 18, 19, FALSE, TRUE, TRUE }, + /* 34 */ { "%TVAR2% long long", "", 1, 19 }, + /* 35 */ { "%TVAR2% long long", "", 2, 19 }, + /* 36 */ { "%TVAR2% long long", "", 4, 19 }, + /* 37 */ { "%TVAR2% long long", "", 7, 19 }, + /* 38 */ { "%TVAR2% long long", "", 8, 19 }, + /* 39 */ { "%TVAR2% long long", "", 9, 19 }, + /* 40 */ { "%TVAR2% long long", "", 10, 19 }, + /* 41 */ { "%TVAR2% long long", "", 18, 19 }, /* 42 */ { "%TVAR2% long long", "%TVAR2% long long", 19, 18 }, - /* 43 */ { "%TVAR long long", "", 1, 17, TRUE, TRUE, TRUE }, - /* 44 */ { "%TVAR long long", "", 2, 17, TRUE, TRUE, TRUE }, - /* 45 */ { "%TVAR long long", "", 3, 17, TRUE, TRUE, TRUE }, - /* 46 */ { "%TVAR long long", "", 15, 17, TRUE, TRUE, TRUE }, - /* 47 */ { "%TVAR long long", "", 16, 17, FALSE, TRUE, TRUE }, + /* 43 */ { "%TVAR long long", "", 1, 17 }, + /* 44 */ { "%TVAR long long", "", 2, 17 }, + /* 45 */ { "%TVAR long long", "", 3, 17 }, + /* 46 */ { "%TVAR long long", "", 15, 17 }, + /* 47 */ { "%TVAR long long", "", 16, 17 }, /* 48 */ { "%TVAR long long", "%TVAR long long", 17, 16 }, };
@@ -653,23 +653,17 @@ static void test_ExpandEnvironmentStringsA(void) SetLastError(0xdeadbeef); ret_size = ExpandEnvironmentStringsA(japanese_test, NULL, 0); ok(GetLastError() == 0xdeadbeef, "got last error %ld\n", GetLastError()); - todo_wine ok(ret_size >= japanese_len, "Needed at least %d, got %lu\n", japanese_len, ret_size);
SetLastError(0xdeadbeef); ret_size = ExpandEnvironmentStringsA(japanese_test, buf, ret_size); - todo_wine ok(GetLastError() == 0xdeadbeef, "got last error %ld\n", GetLastError()); - todo_wine ok(ret_size >= japanese_len, "Needed at least %d, got %lu\n", japanese_len, ret_size); - todo_wine ok(!strcmp(buf, japanese_test), "Got %s\n", debugstr_a(buf));
SetLastError(0xdeadbeef); ret_size = ExpandEnvironmentStringsA(japanese_test, buf, japanese_len / 2); /* Buffer too small */ - todo_wine ok(GetLastError() == 0xdeadbeef, "got last error %ld\n", GetLastError()); - todo_wine ok(ret_size >= japanese_len, "Needed at least %d, got %lu\n", japanese_len, ret_size); } else diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c index c6f2f30b2d8..09e6547245d 100644 --- a/dlls/kernelbase/process.c +++ b/dlls/kernelbase/process.c @@ -1447,20 +1447,32 @@ DWORD WINAPI DECLSPEC_HOTPATCH ExpandEnvironmentStringsA( LPCSTR src, LPSTR dst, { UNICODE_STRING us_src; PWSTR dstW = NULL; - DWORD ret; + DWORD count_neededW; + DWORD count_neededA = 0;
RtlCreateUnicodeStringFromAsciiz( &us_src, src ); - if (count) - { - if (!(dstW = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR)))) return 0; - ret = ExpandEnvironmentStringsW( us_src.Buffer, dstW, count); - if (ret) WideCharToMultiByte( CP_ACP, 0, dstW, ret, dst, count, NULL, NULL ); - } - else ret = ExpandEnvironmentStringsW( us_src.Buffer, NULL, 0 );
+ /* We always need to call ExpandEnvironmentStringsW, since we need the result to calculate the needed buffer size */ + count_neededW = ExpandEnvironmentStringsW( us_src.Buffer, NULL, 0 ); + if (!(dstW = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, count_neededW * sizeof(WCHAR) ))) goto cleanup; + count_neededW = ExpandEnvironmentStringsW( us_src.Buffer, dstW, count_neededW ); + + /* Calculate needed buffer */ + count_neededA = WideCharToMultiByte( CP_ACP, 0, dstW, count_neededW, NULL, 0, NULL, NULL ); + + /* If provided buffer is enough, do actual conversion */ + if (count > count_neededA) + count_neededA = WideCharToMultiByte( CP_ACP, 0, dstW, count_neededW, dst, count, NULL, NULL ); + else if(dst) + *dst = 0; + +cleanup: RtlFreeUnicodeString( &us_src ); HeapFree( GetProcessHeap(), 0, dstW ); - return ret; + + if (count_neededA >= count) /* When the buffer is too small, native over-reports by one byte */ + return count_neededA + 1; + return count_neededA; }
diff --git a/dlls/shcore/tests/shcore.c b/dlls/shcore/tests/shcore.c index 731fa340e8b..3e621c8b950 100644 --- a/dlls/shcore/tests/shcore.c +++ b/dlls/shcore/tests/shcore.c @@ -584,11 +584,8 @@ static void test_SHQueryValueEx(void) ret = pSHQueryValueExA( hKey, "Test3", NULL, &type, buf, &size); ok(ret == ERROR_MORE_DATA, "Unexpected retval %ld.\n", ret);
- todo_wine - { ok( (0 == strcmp("", buf)) || (0 == strcmp(test_envvar2, buf)), "Expected empty or first part of the string "%s", got "%s"\n", test_envvar2, buf); - }
ok(size >= buffer_len2, "Buffer size %lu should be >= %lu.\n", size, buffer_len2); ok(type == REG_SZ, "Unexpected type %ld.\n", type); diff --git a/dlls/shlwapi/tests/shreg.c b/dlls/shlwapi/tests/shreg.c index 75d4dfae7eb..72ca470856e 100644 --- a/dlls/shlwapi/tests/shreg.c +++ b/dlls/shlwapi/tests/shreg.c @@ -313,12 +313,9 @@ static void test_SHQueryValueEx(void) broken(ERROR_SUCCESS == dwRet), /* < IE5.5 */ "Expected ERROR_MORE_DATA, got (%lu)\n", dwRet);
- todo_wine - { - ok( (0 == strcmp("", buf)) || (0 == strcmp(sEnvvar2, buf)) || - broken(0 == strcmp(sTestpath2, buf)), /* IE 5.5 */ - "Expected empty or first part of the string "%s", got "%s"\n", sEnvvar2, buf); - } + ok( (0 == strcmp("", buf)) || (0 == strcmp(sEnvvar2, buf)) || + broken(0 == strcmp(sTestpath2, buf)), /* IE 5.5 */ + "Expected empty or first part of the string "%s", got "%s"\n", sEnvvar2, buf);
ok( dwSize >= nUsedBuffer2 || broken(dwSize == (strlen(sEnvvar2) + 1)) || /* IE4.01 SP1 (W98) and IE5 (W98SE) */ diff --git a/dlls/userenv/tests/userenv.c b/dlls/userenv/tests/userenv.c index 3ddb893c18c..7f69a329c36 100644 --- a/dlls/userenv/tests/userenv.c +++ b/dlls/userenv/tests/userenv.c @@ -294,6 +294,7 @@ static void test_get_profiles_dir(void) /* Rather than a BOOL, the return value is also the number of characters * stored in the buffer. */ + todo_wine ok(profiles_len - 1 == r, "expected %ld, got %d\n", profiles_len - 1, r); ok(!strcmp(buf, profiles_dir), "expected %s, got %s\n", profiles_dir, buf); ok(strlen(buf) + 1 == cch, "String length is %Iu, but cch is %lu\n", strlen(buf), cch);
From: Fabian Maurer dark.shadow4@web.de
This is now handled by ExpandEnvironmentStringsA, as should be --- dlls/userenv/tests/userenv.c | 2 -- dlls/userenv/userenv_main.c | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/dlls/userenv/tests/userenv.c b/dlls/userenv/tests/userenv.c index 7f69a329c36..d62d5330efa 100644 --- a/dlls/userenv/tests/userenv.c +++ b/dlls/userenv/tests/userenv.c @@ -294,11 +294,9 @@ static void test_get_profiles_dir(void) /* Rather than a BOOL, the return value is also the number of characters * stored in the buffer. */ - todo_wine ok(profiles_len - 1 == r, "expected %ld, got %d\n", profiles_len - 1, r); ok(!strcmp(buf, profiles_dir), "expected %s, got %s\n", profiles_dir, buf); ok(strlen(buf) + 1 == cch, "String length is %Iu, but cch is %lu\n", strlen(buf), cch); - todo_wine ok(strlen(buf) + 1 == r, "String length is %Iu, but returned count is %u\n", strlen(buf), r);
HeapFree(GetProcessHeap(), 0, buf); diff --git a/dlls/userenv/userenv_main.c b/dlls/userenv/userenv_main.c index dd04c40446e..de79156df3c 100644 --- a/dlls/userenv/userenv_main.c +++ b/dlls/userenv/userenv_main.c @@ -512,8 +512,7 @@ BOOL WINAPI GetProfilesDirectoryA( LPSTR lpProfilesDir, LPDWORD lpcchSize ) } *lpcchSize = expanded_len - 1; /* The return value is also the expected length. */ - ret = ExpandEnvironmentStringsA(unexpanded_profiles_dir, lpProfilesDir, - expanded_len) - 1; + ret = ExpandEnvironmentStringsA(unexpanded_profiles_dir, lpProfilesDir, expanded_len); end: HeapFree(GetProcessHeap(), 0, unexpanded_profiles_dir); RegCloseKey(key);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=147387
Your paranoid android.
=== debian11b (64 bit WoW report) ===
user32: input.c:4305: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 0000000001A000CA, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032
@nsivov Would you mind taking another look, please?
@huw Sorry for the direct ping, but I've been waiting so long, would you mind taking a look?