From 773206851a54318fc27519ea575e478250fcc960 Mon Sep 17 00:00:00 2001 From: "Carl J. Bialorucki" Date: Wed, 29 Oct 2025 14:10:07 -0500 Subject: [PATCH] [SHLWAPI_WINETEST] Sync to wine-10.0 (#8303) - [SHLWAPI_WINETEST] Sync to wine-10.0 --- .../rostests/winetests/shlwapi/CMakeLists.txt | 20 +- modules/rostests/winetests/shlwapi/assoc.c | 365 +- modules/rostests/winetests/shlwapi/clist.c | 273 +- modules/rostests/winetests/shlwapi/clsid.c | 37 +- .../rostests/winetests/shlwapi/generated.c | 12 +- modules/rostests/winetests/shlwapi/istream.c | 307 +- modules/rostests/winetests/shlwapi/ordinal.c | 460 +-- modules/rostests/winetests/shlwapi/path.c | 265 +- modules/rostests/winetests/shlwapi/shreg.c | 120 +- modules/rostests/winetests/shlwapi/string.c | 438 ++- modules/rostests/winetests/shlwapi/thread.c | 34 +- modules/rostests/winetests/shlwapi/url.c | 2925 +++++++++++------ 12 files changed, 3186 insertions(+), 2070 deletions(-) diff --git a/modules/rostests/winetests/shlwapi/CMakeLists.txt b/modules/rostests/winetests/shlwapi/CMakeLists.txt index 279add260a2..6239afbb163 100644 --- a/modules/rostests/winetests/shlwapi/CMakeLists.txt +++ b/modules/rostests/winetests/shlwapi/CMakeLists.txt @@ -1,8 +1,12 @@ -add_definitions(-D__ROS_LONG64__) +include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/wine) +remove_definitions(-DWINVER=0x502 -D_WIN32_WINNT=0x502) +add_definitions(-DWINVER=0x0600 -D_WIN32_WINNT=0x0600 -DNTDDI_VERSION=0x06000100) + add_definitions( -DUSE_WINE_TODOS - -DWINETEST_USE_DBGSTR_LONGLONG) + -DWINETEST_USE_DBGSTR_LONGLONG + -Dstrdup=_strdup) list(APPEND SOURCE assoc.c @@ -30,6 +34,18 @@ add_importlibs(shlwapi_winetest shlwapi shell32 mlang oleaut32 ole32 user32 adva if(MSVC) add_importlibs(shlwapi_winetest ntdll) + target_compile_options(shlwapi_winetest PRIVATE + /wd4113 + /wd4028 + /utf-8) +endif() + +if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR + CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_compile_options(shlwapi_winetest PRIVATE + -Wno-format + -Wno-discarded-qualifiers + -Wno-incompatible-pointer-types) endif() add_pch(shlwapi_winetest precomp.h "${PCH_SKIP_SOURCE}") diff --git a/modules/rostests/winetests/shlwapi/assoc.c b/modules/rostests/winetests/shlwapi/assoc.c index c4234de047a..93e0d140518 100644 --- a/modules/rostests/winetests/shlwapi/assoc.c +++ b/modules/rostests/winetests/shlwapi/assoc.c @@ -23,20 +23,14 @@ #include "shlwapi.h" #include "shlguid.h" -#define expect(expected, got) ok( (expected) == (got), "Expected %d, got %d\n", (expected), (got)) -#define expect_hr(expected, got) ok( (expected) == (got), "Expected %08x, got %08x\n", (expected), (got)) +#define expect(expected, got) ok ( expected == got, "Expected %ld, got %ld\n", expected, got) +#define expect_hr(expected, got) ok ( expected == got, "Expected %08lx, got %08lx\n", expected, got) static HRESULT (WINAPI *pAssocQueryStringA)(ASSOCF,ASSOCSTR,LPCSTR,LPCSTR,LPSTR,LPDWORD) = NULL; static HRESULT (WINAPI *pAssocQueryStringW)(ASSOCF,ASSOCSTR,LPCWSTR,LPCWSTR,LPWSTR,LPDWORD) = NULL; static HRESULT (WINAPI *pAssocCreate)(CLSID, REFIID, void **) = NULL; -static HRESULT (WINAPI *pAssocGetPerceivedType)(LPCWSTR, PERCEIVED *, INT *, LPWSTR *) = NULL; -/* Every version of Windows with IE should have this association? */ -static const WCHAR dotHtml[] = { '.','h','t','m','l',0 }; -static const WCHAR badBad[] = { 'b','a','d','b','a','d',0 }; -static const WCHAR dotBad[] = { '.','b','a','d',0 }; -static const WCHAR open[] = { 'o','p','e','n',0 }; -static const WCHAR invalid[] = { 'i','n','v','a','l','i','d',0 }; +/* Should every version of Windows with IE have .html association? */ static void test_getstring_bad(void) { @@ -52,75 +46,75 @@ static void test_getstring_bad(void) } len = 0xdeadbeef; - hr = pAssocQueryStringW(0, ASSOCSTR_EXECUTABLE, NULL, open, NULL, &len); + hr = pAssocQueryStringW(0, ASSOCSTR_EXECUTABLE, NULL, L"open", NULL, &len); expect_hr(E_INVALIDARG, hr); - ok(len == 0xdeadbeef, "got %u\n", len); + ok(len == 0xdeadbeef, "got %lu\n", len); len = 0xdeadbeef; - hr = pAssocQueryStringW(0, ASSOCSTR_EXECUTABLE, badBad, open, NULL, &len); + hr = pAssocQueryStringW(0, ASSOCSTR_EXECUTABLE, L"badbad", L"open", NULL, &len); ok(hr == E_FAIL || hr == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION), /* Win9x/WinMe/NT4/W2K/Vista/W2K8 */ - "Unexpected result : %08x\n", hr); - ok(len == 0xdeadbeef, "got %u\n", len); + "Unexpected result : %08lx\n", hr); + ok(len == 0xdeadbeef, "got %lu\n", len); len = ARRAY_SIZE(buf); - hr = pAssocQueryStringW(0, ASSOCSTR_EXECUTABLE, dotBad, open, buf, &len); + hr = pAssocQueryStringW(0, ASSOCSTR_EXECUTABLE, L".bad", L"open", buf, &len); ok(hr == E_FAIL || hr == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION) /* Win9x/WinMe/NT4/W2K/Vista/W2K8 */ || hr == S_OK /* Win8 */, - "Unexpected result : %08x\n", hr); + "Unexpected result : %08lx\n", hr); if (hr == S_OK) { - ok(len < ARRAY_SIZE(buf), "got %u\n", len); + ok(len < ARRAY_SIZE(buf), "got %lu\n", len); ok(!lstrcmpiW(buf + len - ARRAY_SIZE(openwith), openwith), "wrong data\n"); } len = 0xdeadbeef; - hr = pAssocQueryStringW(0, ASSOCSTR_EXECUTABLE, dotHtml, invalid, NULL, &len); + hr = pAssocQueryStringW(0, ASSOCSTR_EXECUTABLE, L".html", L"invalid", NULL, &len); ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) || hr == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION), /* Win9x/WinMe/NT4/W2K/Vista/W2K8 */ - "Unexpected result : %08x\n", hr); - ok(len == 0xdeadbeef, "got %u\n", len); + "Unexpected result : %08lx\n", hr); + ok(len == 0xdeadbeef, "got %lu\n", len); - hr = pAssocQueryStringW(0, ASSOCSTR_EXECUTABLE, dotHtml, open, NULL, NULL); + hr = pAssocQueryStringW(0, ASSOCSTR_EXECUTABLE, L".html", L"open", NULL, NULL); ok(hr == E_UNEXPECTED || hr == E_INVALIDARG, /* Win9x/WinMe/NT4/W2K/Vista/W2K8 */ - "Unexpected result : %08x\n", hr); + "Unexpected result : %08lx\n", hr); len = 0xdeadbeef; - hr = pAssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, NULL, open, NULL, &len); + hr = pAssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, NULL, L"open", NULL, &len); expect_hr(E_INVALIDARG, hr); - ok(len == 0xdeadbeef, "got %u\n", len); + ok(len == 0xdeadbeef, "got %lu\n", len); len = 0xdeadbeef; - hr = pAssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, badBad, open, NULL, &len); + hr = pAssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, L"badbad", L"open", NULL, &len); ok(hr == E_FAIL || hr == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION), /* Win9x/WinMe/NT4/W2K/Vista/W2K8 */ - "Unexpected result : %08x\n", hr); - ok(len == 0xdeadbeef, "got %u\n", len); + "Unexpected result : %08lx\n", hr); + ok(len == 0xdeadbeef, "got %lu\n", len); len = 0xdeadbeef; - hr = pAssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, dotBad, open, NULL, &len); + hr = pAssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, L".bad", L"open", NULL, &len); ok(hr == E_FAIL || hr == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION) /* Win9x/WinMe/NT4/W2K/Vista/W2K8 */ || hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND) /* Win8 */ || hr == S_FALSE, /* Win10 */ - "Unexpected result : %08x\n", hr); + "Unexpected result : %08lx\n", hr); ok((hr == S_FALSE && len < ARRAY_SIZE(buf)) || len == 0xdeadbeef, - "got hr=%08x and len=%u\n", hr, len); + "got hr=%08lx and len=%lu\n", hr, len); len = 0xdeadbeef; - hr = pAssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, dotHtml, invalid, NULL, &len); + hr = pAssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, L".html", L"invalid", NULL, &len); ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) || hr == HRESULT_FROM_WIN32(ERROR_NO_ASSOCIATION) || /* W2K/Vista/W2K8 */ hr == E_FAIL, /* Win9x/WinMe/NT4 */ - "Unexpected result : %08x\n", hr); - ok(len == 0xdeadbeef, "got %u\n", len); + "Unexpected result : %08lx\n", hr); + ok(len == 0xdeadbeef, "got %lu\n", len); - hr = pAssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, dotHtml, open, NULL, NULL); + hr = pAssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, L".html", L"open", NULL, NULL); ok(hr == E_UNEXPECTED || hr == E_INVALIDARG, /* Win9x/WinMe/NT4/W2K/Vista/W2K8 */ - "Unexpected result : %08x\n", hr); + "Unexpected result : %08lx\n", hr); } static void test_getstring_basic(void) @@ -136,7 +130,7 @@ static void test_getstring_basic(void) return; } - hr = pAssocQueryStringW(0, ASSOCSTR_EXECUTABLE, dotHtml, open, NULL, &len); + hr = pAssocQueryStringW(0, ASSOCSTR_EXECUTABLE, L".html", L"open", NULL, &len); expect_hr(S_FALSE, hr); if (hr != S_FALSE) { @@ -153,19 +147,19 @@ static void test_getstring_basic(void) } len2 = len; - hr = pAssocQueryStringW(0, ASSOCSTR_EXECUTABLE, dotHtml, open, + hr = pAssocQueryStringW(0, ASSOCSTR_EXECUTABLE, L".html", L"open", executableName, &len2); expect_hr(S_OK, hr); slen = lstrlenW(executableName) + 1; expect(len, len2); expect(len, slen); - hr = pAssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, dotHtml, open, NULL, + hr = pAssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, L".html", L"open", NULL, &len); ok(hr == S_FALSE || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) /* Win9x/NT4 */ || hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), /* Win8 */ - "Unexpected result : %08x\n", hr); + "Unexpected result : %08lx\n", hr); if (hr != S_FALSE) { HeapFree(GetProcessHeap(), 0, executableName); @@ -183,7 +177,7 @@ static void test_getstring_basic(void) } len2 = len; - hr = pAssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, dotHtml, open, + hr = pAssocQueryStringW(0, ASSOCSTR_FRIENDLYAPPNAME, L".html", L"open", friendlyName, &len2); expect_hr(S_OK, hr); slen = lstrlenW(friendlyName) + 1; @@ -256,7 +250,7 @@ static void test_getstring_no_extra(void) hr = pAssocQueryStringA(0, ASSOCSTR_EXECUTABLE, dotWinetest, NULL, buf, &len); ok(hr == S_OK || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), /* XP and W2K3 */ - "Unexpected result : %08x\n", hr); + "Unexpected result : %08lx\n", hr); hr = pAssocQueryStringA(0, ASSOCSTR_EXECUTABLE, dotWinetest, "foo", buf, &len); expect_hr(S_OK, hr); ok(strstr(buf, action) != NULL, @@ -280,19 +274,19 @@ static void test_assoc_create(void) } hr = pAssocCreate(IID_NULL, &IID_NULL, NULL); - ok(hr == E_INVALIDARG, "Unexpected result : %08x\n", hr); + ok(hr == E_INVALIDARG, "Unexpected result : %08lx\n", hr); hr = pAssocCreate(CLSID_QueryAssociations, &IID_NULL, (LPVOID*)&pqa); ok(hr == CLASS_E_CLASSNOTAVAILABLE || hr == E_NOTIMPL || hr == E_NOINTERFACE - , "Unexpected result : %08x\n", hr); + , "Unexpected result : %08lx\n", hr); hr = pAssocCreate(IID_NULL, &IID_IQueryAssociations, (LPVOID*)&pqa); ok(hr == CLASS_E_CLASSNOTAVAILABLE || hr == E_NOTIMPL || hr == E_INVALIDARG - , "Unexpected result : %08x\n", hr); + , "Unexpected result : %08lx\n", hr); hr = pAssocCreate(CLSID_QueryAssociations, &IID_IQueryAssociations, (LPVOID*)&pqa); ok(hr == S_OK || hr == E_NOTIMPL /* win98 */ - , "Unexpected result : %08x\n", hr); + , "Unexpected result : %08lx\n", hr); if(hr == S_OK) { IQueryAssociations_Release(pqa); @@ -300,290 +294,13 @@ static void test_assoc_create(void) hr = pAssocCreate(CLSID_QueryAssociations, &IID_IUnknown, (LPVOID*)&pqa); ok(hr == S_OK || hr == E_NOTIMPL /* win98 */ - , "Unexpected result : %08x\n", hr); + , "Unexpected result : %08lx\n", hr); if(hr == S_OK) { IQueryAssociations_Release(pqa); } } -/* Based on http://www.geoffchappell.com/studies/windows/shell/shlwapi/api/assocapi/getperceivedtype.htm */ -struct assoc_test_struct -{ - PCSTR extension; - PERCEIVED perceived; - INT flags; - PCSTR type; - DWORD minversion; - HRESULT hr; -}; - -#define HARDCODED_NATIVE_WMSDK (PERCEIVEDFLAG_HARDCODED | PERCEIVEDFLAG_NATIVESUPPORT | PERCEIVEDFLAG_WMSDK) -#define HARDCODED_NATIVE_GDIPLUS (PERCEIVEDFLAG_HARDCODED | PERCEIVEDFLAG_NATIVESUPPORT | PERCEIVEDFLAG_GDIPLUS) -#define HARDCODED_NATIVE_ZIPFLDR (PERCEIVEDFLAG_HARDCODED | PERCEIVEDFLAG_NATIVESUPPORT | PERCEIVEDFLAG_ZIPFOLDER) -#define SOFTCODED_NATIVESUPPORT (PERCEIVEDFLAG_SOFTCODED | PERCEIVEDFLAG_NATIVESUPPORT) - -static const struct assoc_test_struct assoc_perceived_types[] = -{ - /* builtins */ - { ".aif", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, - { ".aifc", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, - { ".aiff", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, - { ".asf", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, - { ".asx", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, - { ".au", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, - { ".avi", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, - { ".bas", PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, "application" }, - { ".bat", PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, "application" }, - { ".bmp", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, - { ".cmd", PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, "application" }, - { ".com", PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, "application" }, - { ".cpl", PERCEIVED_TYPE_SYSTEM, PERCEIVEDFLAG_HARDCODED, "system", 0x600 }, - { ".dib", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, - { ".dvr-ms", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, - { ".emf", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, - { ".exe", PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, "application" }, - { ".gif", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, - { ".hta", PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, "application" }, - /* htm & html are PERCEIVED_TYPE_TEXT, PERCEIVEDFLAG_NATIVESUPPORT | PERCEIVEDFLAG_SOFTCODED in w2k3 */ - { ".htm", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_HARDCODED, "document", 0x600 }, - { ".html", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_HARDCODED, "document", 0x600 }, - { ".ico", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, - { ".IVF", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, - { ".jfif", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, - { ".jpe", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, - { ".jpeg", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, - { ".jpg", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, - { ".lnk", PERCEIVED_TYPE_UNSPECIFIED, PERCEIVEDFLAG_HARDCODED, NULL, 0x600, E_FAIL }, - { ".m1v", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, - { ".m3u", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, - { ".mht", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_HARDCODED, "document", 0x600 }, - { ".mid", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, - { ".midi", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, - { ".msi", PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, "application" }, - /* below win8 this is defined to be video */ - { ".mp2", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio", 0x602 }, - { ".mp2v", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, - { ".mp3", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, - { ".mpa", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, - { ".mpe", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, - { ".mpeg", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, - { ".mpg", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, - { ".mpv2", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, - { ".pif", PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, "application" }, - { ".png", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, - { ".reg", PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, "application" }, - { ".rle", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, - { ".rmi", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, - { ".scr", PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, "application" }, - { ".search-ms", PERCEIVED_TYPE_UNSPECIFIED, PERCEIVEDFLAG_HARDCODED, NULL, 0x600, E_FAIL }, - { ".snd", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, - { ".tif", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, - { ".tiff", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, - { ".vb", PERCEIVED_TYPE_APPLICATION, PERCEIVEDFLAG_HARDCODED, "application" }, - { ".wav", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, - { ".wax", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, - { ".wm", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, - { ".wma", PERCEIVED_TYPE_AUDIO, HARDCODED_NATIVE_WMSDK, "audio" }, - { ".wmf", PERCEIVED_TYPE_IMAGE, HARDCODED_NATIVE_GDIPLUS, "image" }, - { ".wmv", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, - { ".wmx", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, - { ".wvx", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }, - { ".zip", PERCEIVED_TYPE_COMPRESSED, HARDCODED_NATIVE_ZIPFLDR, "compressed" }, - /* found in the registry under HKEY_CLASSES_ROOT on a new Win7 VM */ - { ".386", PERCEIVED_TYPE_SYSTEM, PERCEIVEDFLAG_SOFTCODED, "system" }, - { ".3g2", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, - { ".3gp", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, - { ".3gp2", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, - { ".3gpp", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, - { ".AAC", PERCEIVED_TYPE_AUDIO, PERCEIVEDFLAG_SOFTCODED, "audio", 0x601 }, - { ".ADT", PERCEIVED_TYPE_AUDIO, PERCEIVEDFLAG_SOFTCODED, "audio", 0x601 }, - { ".ADTS", PERCEIVED_TYPE_AUDIO, PERCEIVEDFLAG_SOFTCODED, "audio", 0x601 }, - { ".asm", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".asmx", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".aspx", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".c", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".cab", PERCEIVED_TYPE_COMPRESSED, PERCEIVEDFLAG_SOFTCODED, "compressed", 0x600 }, - { ".chk", PERCEIVED_TYPE_SYSTEM, PERCEIVEDFLAG_SOFTCODED, "system" }, - { ".cpp", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".css", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".cxx", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".def", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".diz", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".docx", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x601 }, - { ".drv", PERCEIVED_TYPE_SYSTEM, PERCEIVEDFLAG_SOFTCODED, "system", 0x600 }, - { ".gz", PERCEIVED_TYPE_COMPRESSED, PERCEIVEDFLAG_SOFTCODED, "compressed" }, - { ".h", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".hpp", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".hxx", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".inc", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".ini", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text", 0x600 }, - { ".java", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".local", PERCEIVED_TYPE_SYSTEM, PERCEIVEDFLAG_SOFTCODED, "system" }, - { ".M2T", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, - { ".M2TS", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, - { ".M2V", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, - { ".m4a", PERCEIVED_TYPE_AUDIO, PERCEIVEDFLAG_SOFTCODED, "audio", 0x601 }, - { ".m4b", PERCEIVED_TYPE_AUDIO, PERCEIVEDFLAG_SOFTCODED, "audio", 0x601 }, - { ".m4p", PERCEIVED_TYPE_AUDIO, PERCEIVEDFLAG_SOFTCODED, "audio", 0x601 }, - { ".m4v", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, - { ".manifest", PERCEIVED_TYPE_SYSTEM, PERCEIVEDFLAG_SOFTCODED, "system" }, - { ".MOD", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, - { ".mov", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, - { ".mp4", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, - { ".mp4v", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, - { ".MTS", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, - { ".nvr", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".ocx", PERCEIVED_TYPE_SYSTEM, PERCEIVEDFLAG_SOFTCODED, "system" }, - { ".odt", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x601 }, - { ".php3", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".pl", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".plg", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".ps1xml", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "Text" }, - { ".rtf", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x600 }, - { ".sed", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".shtml", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".sql", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".sys", PERCEIVED_TYPE_SYSTEM, PERCEIVEDFLAG_SOFTCODED, "system", 0x600 }, - { ".tar", PERCEIVED_TYPE_COMPRESSED, PERCEIVEDFLAG_SOFTCODED, "compressed" }, - { ".text", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".tgz", PERCEIVED_TYPE_COMPRESSED, PERCEIVEDFLAG_SOFTCODED, "compressed" }, - { ".TS", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, - { ".tsv", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".TTS", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, - { ".txt", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".vob", PERCEIVED_TYPE_VIDEO, PERCEIVEDFLAG_SOFTCODED, "video", 0x601 }, - { ".vxd", PERCEIVED_TYPE_SYSTEM, PERCEIVEDFLAG_SOFTCODED, "system" }, - { ".wdp", PERCEIVED_TYPE_IMAGE, PERCEIVEDFLAG_SOFTCODED, "image" }, - { ".wmz", PERCEIVED_TYPE_COMPRESSED, PERCEIVEDFLAG_SOFTCODED, "compressed" }, - { ".wpl", PERCEIVED_TYPE_AUDIO, PERCEIVEDFLAG_SOFTCODED, "audio", 0x601 }, - { ".wsz", PERCEIVED_TYPE_COMPRESSED, PERCEIVEDFLAG_SOFTCODED, "compressed" }, - { ".x", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text" }, - { ".xml", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text", 0x601 }, - { ".xsl", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text", 0x601 }, - { ".z", PERCEIVED_TYPE_COMPRESSED, PERCEIVEDFLAG_SOFTCODED, "compressed" }, - /* found in the registry under HKEY_CLASSES_ROOT\PerceivedType */ - { ".doc", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x600 }, - { ".dot", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x600 }, - { ".mhtml", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x600 }, - { ".pot", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x600 }, - { ".ppt", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x600 }, - { ".rtf", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x600 }, - { ".wri", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x600 }, - { ".xls", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x600 }, - { ".xlt", PERCEIVED_TYPE_DOCUMENT, PERCEIVEDFLAG_SOFTCODED, "document", 0x600 }, - -}; - -static void test_assoc_one(const struct assoc_test_struct* test) -{ - LPWSTR extension, type_expected, type_returned; - PERCEIVED perceived; - HRESULT hr; - INT flags; - - /* if SHStrDupA receives a nullptr as input, it will null the output */ - SHStrDupA(test->extension, &extension); - SHStrDupA(test->type, &type_expected); - - perceived = 0xdeadbeef; - flags = 0xdeadbeef; - - hr = pAssocGetPerceivedType(extension, &perceived, &flags, NULL); - expect_hr(type_expected ? S_OK : test->hr, hr); - ok(perceived == test->perceived, "%s: got perceived 0x%x, expected 0x%x\n", - test->extension, perceived, test->perceived); - ok(flags == test->flags, "%s: got flags 0x%x, expected 0x%x\n", - test->extension, flags, test->flags); - - type_returned = (void *)0xdeadbeef; - perceived = 0xdeadbeef; - flags = 0xdeadbeef; - - hr = pAssocGetPerceivedType(extension, &perceived, &flags, &type_returned); - expect_hr(type_expected ? S_OK : test->hr, hr); - ok(perceived == test->perceived, "%s: got perceived 0x%x, expected 0x%x\n", - test->extension, perceived, test->perceived); - ok(flags == test->flags, "%s: got flags 0x%x, expected 0x%x\n", - test->extension, flags, test->flags); - - if (!type_expected) - { - ok(type_returned == (void *)0xdeadbeef || broken(type_returned == NULL) /* Win 8 */, - "%s: got type %p, expected 0xdeadbeef\n", test->extension, type_returned); - } - else if (type_returned == (void *)0xdeadbeef) - { - ok(type_returned != (void *)0xdeadbeef, "%s: got type %p, expected '%s'\n", - test->extension, type_returned, test->type); - } - else - { - ok(StrCmpIW(type_expected, type_returned) == 0, "%s: got type %s, expected '%s'\n", - test->extension, wine_dbgstr_w(type_returned), test->type); - } - - CoTaskMemFree(type_returned); - CoTaskMemFree(extension); - CoTaskMemFree(type_expected); -} - -static void test_assoc_perceived(void) -{ - static const struct assoc_test_struct should_not_exist = - { ".should_not_exist", PERCEIVED_TYPE_UNSPECIFIED, PERCEIVEDFLAG_UNDEFINED, NULL, 0, 0x80070002 }; - static const struct assoc_test_struct htm[] = - { - { ".htm", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text", 0x600 }, - { ".html", PERCEIVED_TYPE_TEXT, SOFTCODED_NATIVESUPPORT, "text", 0x600 }, - }; - static const struct assoc_test_struct mp2 = - { ".mp2", PERCEIVED_TYPE_VIDEO, HARDCODED_NATIVE_WMSDK, "video" }; - - OSVERSIONINFOEXW osvi; - DWORD version; - size_t i; - - if (!pAssocGetPerceivedType) - { - win_skip("AssocGetPerceivedType() is missing\n"); - return; - } - - memset(&osvi, 0, sizeof(osvi)); - osvi.dwOSVersionInfoSize = sizeof(osvi); - GetVersionExW((LPOSVERSIONINFOW)&osvi); - version = (osvi.dwMajorVersion << 8) | osvi.dwMinorVersion; - - /* invalid entry results in HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) */ - test_assoc_one(&should_not_exist); - - for (i = 0; i < sizeof(assoc_perceived_types) / sizeof(assoc_perceived_types[0]); ++i) - { - if (assoc_perceived_types[i].minversion && assoc_perceived_types[i].minversion > version) - continue; - if (!(assoc_perceived_types[i].flags & PERCEIVEDFLAG_HARDCODED)) - todo_wine test_assoc_one(&assoc_perceived_types[i]); - else - test_assoc_one(&assoc_perceived_types[i]); - } - - /* below Vista */ - if (version < 0x600) - { - todo_wine - test_assoc_one(&htm[0]); - todo_wine - test_assoc_one(&htm[1]); - } - - /* below Win8 */ - if (version < 0x602) - { - test_assoc_one(&mp2); - } -} - START_TEST(assoc) { HMODULE hshlwapi; @@ -591,11 +308,9 @@ START_TEST(assoc) pAssocQueryStringA = (void*)GetProcAddress(hshlwapi, "AssocQueryStringA"); pAssocQueryStringW = (void*)GetProcAddress(hshlwapi, "AssocQueryStringW"); pAssocCreate = (void*)GetProcAddress(hshlwapi, "AssocCreate"); - pAssocGetPerceivedType = (void*)GetProcAddress(hshlwapi, "AssocGetPerceivedType"); test_getstring_bad(); test_getstring_basic(); test_getstring_no_extra(); test_assoc_create(); - test_assoc_perceived(); } diff --git a/modules/rostests/winetests/shlwapi/clist.c b/modules/rostests/winetests/shlwapi/clist.c index b9082352714..54bff21ae8d 100644 --- a/modules/rostests/winetests/shlwapi/clist.c +++ b/modules/rostests/winetests/shlwapi/clist.c @@ -24,17 +24,10 @@ #include "windef.h" #include "winbase.h" #include "objbase.h" - -typedef struct tagSHLWAPI_CLIST -{ - ULONG ulSize; - ULONG ulId; -} SHLWAPI_CLIST, *LPSHLWAPI_CLIST; - -typedef const SHLWAPI_CLIST* LPCSHLWAPI_CLIST; +#include "shlobj.h" /* Items to add */ -static const SHLWAPI_CLIST SHLWAPI_CLIST_items[] = +static const DATABLOCK_HEADER clist_items[] = { {4, 1}, {8, 3}, @@ -66,7 +59,7 @@ struct dummystream int seekcalls; int statcalls; BOOL failstatcall; - LPCSHLWAPI_CLIST item; + const DATABLOCK_HEADER *item; ULARGE_INTEGER pos; }; @@ -126,7 +119,7 @@ static HRESULT WINAPI Read(IStream *iface, void *lpMem, ULONG ulSize, ULONG *lpR if (ulSize == sizeof(ULONG)) { /* Read size of item */ - *((ULONG*)lpMem) = This->item->ulSize ? This->item->ulSize + sizeof(SHLWAPI_CLIST) : 0; + *((ULONG*)lpMem) = This->item->cbSize ? This->item->cbSize + sizeof(DATABLOCK_HEADER) : 0; *lpRead = ulSize; } else @@ -135,16 +128,16 @@ static HRESULT WINAPI Read(IStream *iface, void *lpMem, ULONG ulSize, ULONG *lpR char* buff = lpMem; /* Read item data */ - if (!This->item->ulSize) + if (!This->item->cbSize) { This->readbeyondend = TRUE; *lpRead = 0; return E_FAIL; /* Should never happen */ } - *((ULONG*)lpMem) = This->item->ulId; + *((ULONG *)lpMem) = This->item->dwSignature; *lpRead = ulSize; - for (i = 0; i < This->item->ulSize; i++) + for (i = 0; i < This->item->cbSize; i++) buff[4+i] = i*2; This->item++; @@ -217,18 +210,18 @@ static IStreamVtbl iclvt = /* Function ptrs for ordinal calls */ static HMODULE SHLWAPI_hshlwapi = 0; -static VOID (WINAPI *pSHLWAPI_19)(LPSHLWAPI_CLIST); -static BOOL (WINAPI *pSHLWAPI_20)(LPSHLWAPI_CLIST*,LPCSHLWAPI_CLIST); -static BOOL (WINAPI *pSHLWAPI_21)(LPSHLWAPI_CLIST*,ULONG); -static LPSHLWAPI_CLIST (WINAPI *pSHLWAPI_22)(LPSHLWAPI_CLIST,ULONG); -static HRESULT (WINAPI *pSHLWAPI_17)(IStream*, SHLWAPI_CLIST*); -static HRESULT (WINAPI *pSHLWAPI_18)(IStream*, SHLWAPI_CLIST**); +static void (WINAPI *pSHFreeDataBlockList)(DATABLOCK_HEADER *); +static HRESULT (WINAPI *pSHAddDataBlock)(DATABLOCK_HEADER **, DATABLOCK_HEADER *); +static BOOL (WINAPI *pSHRemoveDataBlock)(DATABLOCK_HEADER **,ULONG); +static DATABLOCK_HEADER *(WINAPI *pSHFindDataBlock)(DATABLOCK_HEADER *,ULONG); +static HRESULT (WINAPI *pSHWriteDataBlockList)(IStream *, DATABLOCK_HEADER *); +static HRESULT (WINAPI *pSHReadDataBlockList)(IStream *, DATABLOCK_HEADER **); -static BOOL (WINAPI *pSHLWAPI_166)(IStream*); -static HRESULT (WINAPI *pSHLWAPI_184)(IStream*, void*, ULONG); -static HRESULT (WINAPI *pSHLWAPI_212)(IStream*, const void*, ULONG); -static HRESULT (WINAPI *pSHLWAPI_213)(IStream*); -static HRESULT (WINAPI *pSHLWAPI_214)(IStream*, ULARGE_INTEGER*); +static BOOL (WINAPI *pSHIsEmptyStream)(IStream *); +static HRESULT (WINAPI *pIStream_Read)(IStream *, void *, ULONG); +static HRESULT (WINAPI *pIStream_Write)(IStream *, const void *, ULONG); +static HRESULT (WINAPI *pIStream_Reset)(IStream *); +static HRESULT (WINAPI *pIStream_Size)(IStream *, ULARGE_INTEGER *); static BOOL InitFunctionPtrs(void) @@ -241,28 +234,28 @@ static BOOL InitFunctionPtrs(void) return FALSE; } - pSHLWAPI_17 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)17); - ok(pSHLWAPI_17 != 0, "No Ordinal 17\n"); - pSHLWAPI_18 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)18); - ok(pSHLWAPI_18 != 0, "No Ordinal 18\n"); - pSHLWAPI_19 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)19); - ok(pSHLWAPI_19 != 0, "No Ordinal 19\n"); - pSHLWAPI_20 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)20); - ok(pSHLWAPI_20 != 0, "No Ordinal 20\n"); - pSHLWAPI_21 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)21); - ok(pSHLWAPI_21 != 0, "No Ordinal 21\n"); - pSHLWAPI_22 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)22); - ok(pSHLWAPI_22 != 0, "No Ordinal 22\n"); - pSHLWAPI_166 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)166); - ok(pSHLWAPI_166 != 0, "No Ordinal 166\n"); - pSHLWAPI_184 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)184); - ok(pSHLWAPI_184 != 0, "No Ordinal 184\n"); - pSHLWAPI_212 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)212); - ok(pSHLWAPI_212 != 0, "No Ordinal 212\n"); - pSHLWAPI_213 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)213); - ok(pSHLWAPI_213 != 0, "No Ordinal 213\n"); - pSHLWAPI_214 = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)214); - ok(pSHLWAPI_214 != 0, "No Ordinal 214\n"); + pSHWriteDataBlockList = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)17); + ok(pSHWriteDataBlockList != 0, "No Ordinal 17\n"); + pSHReadDataBlockList = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)18); + ok(pSHReadDataBlockList != 0, "No Ordinal 18\n"); + pSHFreeDataBlockList = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)19); + ok(pSHFreeDataBlockList != 0, "No Ordinal 19\n"); + pSHAddDataBlock = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)20); + ok(pSHAddDataBlock != 0, "No Ordinal 20\n"); + pSHRemoveDataBlock = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)21); + ok(pSHRemoveDataBlock != 0, "No Ordinal 21\n"); + pSHFindDataBlock = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)22); + ok(pSHFindDataBlock != 0, "No Ordinal 22\n"); + pSHIsEmptyStream = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)166); + ok(pSHIsEmptyStream != 0, "No Ordinal 166\n"); + pIStream_Read = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)184); + ok(pIStream_Read != 0, "No Ordinal 184\n"); + pIStream_Write = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)212); + ok(pIStream_Write != 0, "No Ordinal 212\n"); + pIStream_Reset = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)213); + ok(pIStream_Reset != 0, "No Ordinal 213\n"); + pIStream_Size = (void *)GetProcAddress( SHLWAPI_hshlwapi, (LPSTR)214); + ok(pIStream_Size != 0, "No Ordinal 214\n"); return TRUE; } @@ -282,7 +275,7 @@ static void InitDummyStream(struct dummystream *obj) obj->seekcalls = 0; obj->statcalls = 0; obj->failstatcall = FALSE; - obj->item = SHLWAPI_CLIST_items; + obj->item = clist_items; obj->pos.QuadPart = 0; } @@ -290,67 +283,65 @@ static void InitDummyStream(struct dummystream *obj) static void test_CList(void) { struct dummystream streamobj; - LPSHLWAPI_CLIST list = NULL; - LPCSHLWAPI_CLIST item = SHLWAPI_CLIST_items; - BOOL bRet; + DATABLOCK_HEADER *list = NULL; + const DATABLOCK_HEADER *item = clist_items; HRESULT hRet; - LPSHLWAPI_CLIST inserted; + DATABLOCK_HEADER *inserted; BYTE buff[64]; unsigned int i; + BOOL ret; - if (!pSHLWAPI_17 || !pSHLWAPI_18 || !pSHLWAPI_19 || !pSHLWAPI_20 || - !pSHLWAPI_21 || !pSHLWAPI_22) + if (!pSHWriteDataBlockList || !pSHReadDataBlockList || !pSHFreeDataBlockList || !pSHAddDataBlock || + !pSHRemoveDataBlock || !pSHFindDataBlock) return; /* Populate a list and test the items are added correctly */ - while (item->ulSize) + while (item->cbSize) { /* Create item and fill with data */ - inserted = (LPSHLWAPI_CLIST)buff; - inserted->ulSize = item->ulSize + sizeof(SHLWAPI_CLIST); - inserted->ulId = item->ulId; - for (i = 0; i < item->ulSize; i++) - buff[sizeof(SHLWAPI_CLIST)+i] = i*2; + inserted = (DATABLOCK_HEADER *)buff; + inserted->cbSize = item->cbSize + sizeof(DATABLOCK_HEADER); + inserted->dwSignature = item->dwSignature; + for (i = 0; i < item->cbSize; i++) + buff[sizeof(DATABLOCK_HEADER) + i] = i * 2; - /* Add it */ - bRet = pSHLWAPI_20(&list, inserted); - ok(bRet == TRUE, "failed list add\n"); + ret = pSHAddDataBlock(&list, inserted); + ok(ret == TRUE, "got %d\n", ret); - if (bRet == TRUE) + if (ret == TRUE) { - ok(list && list->ulSize, "item not added\n"); + ok(list && list->cbSize, "item not added\n"); - /* Find it */ - inserted = pSHLWAPI_22(list, item->ulId); + inserted = pSHFindDataBlock(list, item->dwSignature); ok(inserted != NULL, "lost after adding\n"); - ok(!inserted || inserted->ulId != ~0U, "find returned a container\n"); + ok(!inserted || inserted->dwSignature != ~0U, "find returned a container\n"); /* Check size */ - if (inserted && inserted->ulSize & 0x3) + if (inserted && (inserted->cbSize & 0x3)) { /* Contained */ - ok(inserted[-1].ulId == ~0U, "invalid size is not countained\n"); - ok(inserted[-1].ulSize > inserted->ulSize+sizeof(SHLWAPI_CLIST), + ok(inserted[-1].dwSignature == ~0U, "invalid size is not countained\n"); + ok(inserted[-1].cbSize > inserted->cbSize + sizeof(DATABLOCK_HEADER), "container too small\n"); } else if (inserted) { - ok(inserted->ulSize==item->ulSize+sizeof(SHLWAPI_CLIST), - "id %d wrong size %d\n", inserted->ulId, inserted->ulSize); + ok(inserted->cbSize == item->cbSize + sizeof(DATABLOCK_HEADER), + "id %ld wrong size %ld\n", inserted->dwSignature, inserted->cbSize); } if (inserted) { BOOL bDataOK = TRUE; LPBYTE bufftest = (LPBYTE)inserted; - for (i = 0; i < inserted->ulSize - sizeof(SHLWAPI_CLIST); i++) - if (bufftest[sizeof(SHLWAPI_CLIST)+i] != i*2) + for (i = 0; i < inserted->cbSize - sizeof(DATABLOCK_HEADER); i++) + if (bufftest[sizeof(DATABLOCK_HEADER) + i] != i * 2) bDataOK = FALSE; ok(bDataOK == TRUE, "data corrupted on insert\n"); } - ok(!inserted || inserted->ulId==item->ulId, "find got wrong item\n"); + ok(!inserted || inserted->dwSignature == item->dwSignature, "find got wrong item\n"); } item++; } @@ -358,12 +349,12 @@ static void test_CList(void) /* Write the list */ InitDummyStream(&streamobj); - hRet = pSHLWAPI_17(&streamobj.IStream_iface, list); + hRet = pSHWriteDataBlockList(&streamobj.IStream_iface, list); ok(hRet == S_OK, "write failed\n"); if (hRet == S_OK) { /* 1 call for each element, + 1 for OK (use our null element for this) */ - ok(streamobj.writecalls == ARRAY_SIZE(SHLWAPI_CLIST_items), "wrong call count\n"); + ok(streamobj.writecalls == ARRAY_SIZE(clist_items), "wrong call count\n"); ok(streamobj.readcalls == 0,"called Read() in write\n"); ok(streamobj.seekcalls == 0,"called Seek() in write\n"); } @@ -371,7 +362,7 @@ static void test_CList(void) /* Failure cases for writing */ InitDummyStream(&streamobj); streamobj.failwritecall = TRUE; - hRet = pSHLWAPI_17(&streamobj.IStream_iface, list); + hRet = pSHWriteDataBlockList(&streamobj.IStream_iface, list); ok(hRet == STG_E_ACCESSDENIED, "changed object failure return\n"); ok(streamobj.writecalls == 1, "called object after failure\n"); ok(streamobj.readcalls == 0,"called Read() after failure\n"); @@ -379,7 +370,7 @@ static void test_CList(void) InitDummyStream(&streamobj); streamobj.failwritesize = TRUE; - hRet = pSHLWAPI_17(&streamobj.IStream_iface, list); + hRet = pSHWriteDataBlockList(&streamobj.IStream_iface, list); ok(hRet == STG_E_MEDIUMFULL || broken(hRet == E_FAIL) /* Win7 */, "changed size failure return\n"); ok(streamobj.writecalls == 1, "called object after size failure\n"); @@ -387,83 +378,87 @@ static void test_CList(void) ok(streamobj.seekcalls == 0,"called Seek() after failure\n"); /* Invalid inputs for adding */ - inserted = (LPSHLWAPI_CLIST)buff; - inserted->ulSize = sizeof(SHLWAPI_CLIST) -1; - inserted->ulId = 33; - bRet = pSHLWAPI_20(&list, inserted); - ok(bRet == FALSE, "Expected failure\n"); + inserted = (DATABLOCK_HEADER *)buff; + inserted->cbSize = sizeof(DATABLOCK_HEADER) - 1; + inserted->dwSignature = 33; - inserted = pSHLWAPI_22(list, 33); + ret = pSHAddDataBlock(NULL, inserted); + ok(!ret, "got %d\n", ret); + + ret = pSHAddDataBlock(&list, inserted); + ok(!ret, "got %d\n", ret); + + inserted = pSHFindDataBlock(list, 33); ok(inserted == NULL, "inserted bad element size\n"); - inserted = (LPSHLWAPI_CLIST)buff; - inserted->ulSize = 44; - inserted->ulId = ~0U; - bRet = pSHLWAPI_20(&list, inserted); - ok(bRet == FALSE, "Expected failure\n"); + inserted = (DATABLOCK_HEADER *)buff; + inserted->cbSize = 44; + inserted->dwSignature = ~0U; - item = SHLWAPI_CLIST_items; + ret = pSHAddDataBlock(&list, inserted); + ok(!ret, "got %d\n", ret); + + item = clist_items; /* Look for nonexistent item in populated list */ - inserted = pSHLWAPI_22(list, 99999999); + inserted = pSHFindDataBlock(list, 99999999); ok(inserted == NULL, "found a nonexistent item\n"); - while (item->ulSize) + while (item->cbSize) { - /* Delete items */ - BOOL bRet = pSHLWAPI_21(&list, item->ulId); + BOOL bRet = pSHRemoveDataBlock(&list, item->dwSignature); ok(bRet == TRUE, "couldn't find item to delete\n"); item++; } /* Look for nonexistent item in empty list */ - inserted = pSHLWAPI_22(list, 99999999); + inserted = pSHFindDataBlock(list, 99999999); ok(inserted == NULL, "found an item in empty list\n"); /* Create a list by reading in data */ InitDummyStream(&streamobj); - hRet = pSHLWAPI_18(&streamobj.IStream_iface, &list); + hRet = pSHReadDataBlockList(&streamobj.IStream_iface, &list); ok(hRet == S_OK, "failed create from Read()\n"); if (hRet == S_OK) { ok(streamobj.readbeyondend == FALSE, "read beyond end\n"); /* 2 calls per item, but only 1 for the terminator */ - ok(streamobj.readcalls == ARRAY_SIZE(SHLWAPI_CLIST_items) * 2 - 1, "wrong call count\n"); + ok(streamobj.readcalls == ARRAY_SIZE(clist_items) * 2 - 1, "wrong call count\n"); ok(streamobj.writecalls == 0, "called Write() from create\n"); ok(streamobj.seekcalls == 0,"called Seek() from create\n"); - item = SHLWAPI_CLIST_items; + item = clist_items; /* Check the items were added correctly */ - while (item->ulSize) + while (item->cbSize) { - inserted = pSHLWAPI_22(list, item->ulId); + inserted = pSHFindDataBlock(list, item->dwSignature); ok(inserted != NULL, "lost after adding\n"); - ok(!inserted || inserted->ulId != ~0U, "find returned a container\n"); + ok(!inserted || inserted->dwSignature != ~0U, "find returned a container\n"); /* Check size */ - if (inserted && inserted->ulSize & 0x3) + if (inserted && inserted->cbSize & 0x3) { /* Contained */ - ok(inserted[-1].ulId == ~0U, "invalid size is not countained\n"); - ok(inserted[-1].ulSize > inserted->ulSize+sizeof(SHLWAPI_CLIST), + ok(inserted[-1].dwSignature == ~0U, "invalid size is not countained\n"); + ok(inserted[-1].cbSize > inserted->cbSize + sizeof(DATABLOCK_HEADER), "container too small\n"); } else if (inserted) { - ok(inserted->ulSize==item->ulSize+sizeof(SHLWAPI_CLIST), - "id %d wrong size %d\n", inserted->ulId, inserted->ulSize); + ok(inserted->cbSize == item->cbSize + sizeof(DATABLOCK_HEADER), + "id %ld wrong size %ld\n", inserted->dwSignature, inserted->cbSize); } - ok(!inserted || inserted->ulId==item->ulId, "find got wrong item\n"); + ok(!inserted || inserted->dwSignature == item->dwSignature, "find got wrong item\n"); if (inserted) { BOOL bDataOK = TRUE; LPBYTE bufftest = (LPBYTE)inserted; - for (i = 0; i < inserted->ulSize - sizeof(SHLWAPI_CLIST); i++) - if (bufftest[sizeof(SHLWAPI_CLIST)+i] != i*2) + for (i = 0; i < inserted->cbSize - sizeof(DATABLOCK_HEADER); i++) + if (bufftest[sizeof(DATABLOCK_HEADER) + i] != i * 2) bDataOK = FALSE; ok(bDataOK == TRUE, "data corrupted on insert\n"); @@ -475,7 +470,7 @@ static void test_CList(void) /* Failure cases for reading */ InitDummyStream(&streamobj); streamobj.failreadcall = TRUE; - hRet = pSHLWAPI_18(&streamobj.IStream_iface, &list); + hRet = pSHReadDataBlockList(&streamobj.IStream_iface, &list); ok(hRet == STG_E_ACCESSDENIED, "changed object failure return\n"); ok(streamobj.readbeyondend == FALSE, "read beyond end\n"); ok(streamobj.readcalls == 1, "called object after read failure\n"); @@ -485,26 +480,26 @@ static void test_CList(void) /* Read returns large object */ InitDummyStream(&streamobj); streamobj.readreturnlarge = TRUE; - hRet = pSHLWAPI_18(&streamobj.IStream_iface, &list); + hRet = pSHReadDataBlockList(&streamobj.IStream_iface, &list); ok(hRet == S_OK, "failed create from Read() with large item\n"); ok(streamobj.readbeyondend == FALSE, "read beyond end\n"); ok(streamobj.readcalls == 1,"wrong call count\n"); ok(streamobj.writecalls == 0,"called Write() after read failure\n"); ok(streamobj.seekcalls == 2,"wrong Seek() call count (%d)\n", streamobj.seekcalls); - pSHLWAPI_19(list); + pSHFreeDataBlockList(list); } -static BOOL test_SHLWAPI_166(void) +static BOOL test_SHIsEmptyStream(void) { struct dummystream streamobj; BOOL bRet; - if (!pSHLWAPI_166) + if (!pSHIsEmptyStream) return FALSE; InitDummyStream(&streamobj); - bRet = pSHLWAPI_166(&streamobj.IStream_iface); + bRet = pSHIsEmptyStream(&streamobj.IStream_iface); if (bRet != TRUE) return FALSE; /* This version doesn't support stream ops on clists */ @@ -517,7 +512,7 @@ static BOOL test_SHLWAPI_166(void) streamobj.statcalls = 0; streamobj.pos.QuadPart = 50001; - bRet = pSHLWAPI_166(&streamobj.IStream_iface); + bRet = pSHIsEmptyStream(&streamobj.IStream_iface); ok(bRet == FALSE, "failed after seek adjusted\n"); ok(streamobj.readcalls == 0, "called Read()\n"); @@ -529,7 +524,7 @@ static BOOL test_SHLWAPI_166(void) InitDummyStream(&streamobj); streamobj.pos.QuadPart = 50001; streamobj.failstatcall = TRUE; /* 1: Stat() Bad, Read() OK */ - bRet = pSHLWAPI_166(&streamobj.IStream_iface); + bRet = pSHIsEmptyStream(&streamobj.IStream_iface); ok(bRet == FALSE, "should be FALSE after read is OK\n"); ok(streamobj.readcalls == 1, "wrong call count\n"); ok(streamobj.writecalls == 0, "called Write()\n"); @@ -541,7 +536,7 @@ static BOOL test_SHLWAPI_166(void) streamobj.pos.QuadPart = 50001; streamobj.failstatcall = TRUE; streamobj.failreadcall = TRUE; /* 2: Stat() Bad, Read() Bad Also */ - bRet = pSHLWAPI_166(&streamobj.IStream_iface); + bRet = pSHIsEmptyStream(&streamobj.IStream_iface); ok(bRet == TRUE, "Should be true after read fails\n"); ok(streamobj.readcalls == 1, "wrong call count\n"); ok(streamobj.writecalls == 0, "called Write()\n"); @@ -551,17 +546,17 @@ static BOOL test_SHLWAPI_166(void) return TRUE; } -static void test_SHLWAPI_184(void) +static void test_IStream_Read(void) { struct dummystream streamobj; char buff[256]; HRESULT hRet; - if (!pSHLWAPI_184) + if (!pIStream_Read) return; InitDummyStream(&streamobj); - hRet = pSHLWAPI_184(&streamobj.IStream_iface, buff, sizeof(buff)); + hRet = pIStream_Read(&streamobj.IStream_iface, buff, sizeof(buff)); ok(hRet == S_OK, "failed Read()\n"); ok(streamobj.readcalls == 1, "wrong call count\n"); @@ -569,17 +564,17 @@ static void test_SHLWAPI_184(void) ok(streamobj.seekcalls == 0, "called Seek()\n"); } -static void test_SHLWAPI_212(void) +static void test_IStream_Write(void) { struct dummystream streamobj; - char buff[256]; + char buff[256] = {0}; HRESULT hRet; - if (!pSHLWAPI_212) + if (!pIStream_Write) return; InitDummyStream(&streamobj); - hRet = pSHLWAPI_212(&streamobj.IStream_iface, buff, sizeof(buff)); + hRet = pIStream_Write(&streamobj.IStream_iface, buff, sizeof(buff)); ok(hRet == S_OK, "failed Write()\n"); ok(streamobj.readcalls == 0, "called Read()\n"); @@ -587,14 +582,14 @@ static void test_SHLWAPI_212(void) ok(streamobj.seekcalls == 0, "called Seek()\n"); } -static void test_SHLWAPI_213(void) +static void test_IStream_Reset(void) { struct dummystream streamobj; ULARGE_INTEGER ul; LARGE_INTEGER ll; HRESULT hRet; - if (!pSHLWAPI_213 || !pSHLWAPI_214) + if (!pIStream_Reset || !pIStream_Size) return; InitDummyStream(&streamobj); @@ -602,26 +597,26 @@ static void test_SHLWAPI_213(void) Seek(&streamobj.IStream_iface, ll, 0, NULL); /* Seek to 5000l */ streamobj.seekcalls = 0; - pSHLWAPI_213(&streamobj.IStream_iface); /* Should rewind */ + pIStream_Reset(&streamobj.IStream_iface); ok(streamobj.statcalls == 0, "called Stat()\n"); ok(streamobj.readcalls == 0, "called Read()\n"); ok(streamobj.writecalls == 0, "called Write()\n"); ok(streamobj.seekcalls == 1, "wrong call count\n"); ul.QuadPart = 50001; - hRet = pSHLWAPI_214(&streamobj.IStream_iface, &ul); + hRet = pIStream_Size(&streamobj.IStream_iface, &ul); ok(hRet == S_OK, "failed Stat()\n"); ok(ul.QuadPart == 0, "213 didn't rewind stream\n"); } -static void test_SHLWAPI_214(void) +static void test_IStream_Size(void) { struct dummystream streamobj; ULARGE_INTEGER ul; LARGE_INTEGER ll; HRESULT hRet; - if (!pSHLWAPI_214) + if (!pIStream_Size) return; InitDummyStream(&streamobj); @@ -629,7 +624,7 @@ static void test_SHLWAPI_214(void) Seek(&streamobj.IStream_iface, ll, 0, NULL); ul.QuadPart = 0; streamobj.seekcalls = 0; - hRet = pSHLWAPI_214(&streamobj.IStream_iface, &ul); + hRet = pIStream_Size(&streamobj.IStream_iface, &ul); ok(hRet == S_OK, "failed Stat()\n"); ok(streamobj.statcalls == 1, "wrong call count\n"); @@ -647,11 +642,11 @@ START_TEST(clist) test_CList(); /* Test streaming if this version supports it */ - if (test_SHLWAPI_166()) + if (test_SHIsEmptyStream()) { - test_SHLWAPI_184(); - test_SHLWAPI_212(); - test_SHLWAPI_213(); - test_SHLWAPI_214(); + test_IStream_Read(); + test_IStream_Write(); + test_IStream_Reset(); + test_IStream_Size(); } } diff --git a/modules/rostests/winetests/shlwapi/clsid.c b/modules/rostests/winetests/shlwapi/clsid.c index e664f63cf76..46b2a0b0185 100644 --- a/modules/rostests/winetests/shlwapi/clsid.c +++ b/modules/rostests/winetests/shlwapi/clsid.c @@ -36,8 +36,8 @@ DEFINE_OLEGUID(WINE_IID_IDelayedRelease, 0x000214EDL, 0, 0); /* Function ptrs for ordinal calls */ static HMODULE hShlwapi = 0; -static BOOL (WINAPI *pSHLWAPI_269)(LPCSTR, CLSID *) = 0; -static DWORD (WINAPI *pSHLWAPI_23)(REFGUID, LPSTR, INT) = 0; +static BOOL (WINAPI *pGUIDFromStringA)(LPCSTR, CLSID *) = 0; +static DWORD (WINAPI *pSHStringFromGUIDA)(REFGUID, LPSTR, INT) = 0; /* GUIDs to test */ static const GUID * TEST_guids[] = { @@ -109,16 +109,16 @@ static void test_ClassIDs(void) int i = 0; BOOL is_vista = FALSE; - if (!pSHLWAPI_269 || !pSHLWAPI_23) + if (!pGUIDFromStringA || !pSHStringFromGUIDA) return; while (*guids) { - dwLen = pSHLWAPI_23(*guids, szBuff, 256); + dwLen = pSHStringFromGUIDA(*guids, szBuff, 256); if (!i && dwLen == S_OK) is_vista = TRUE; /* seems to return an HRESULT on vista */ - ok(dwLen == (is_vista ? S_OK : 39), "wrong size %u for id %d\n", dwLen, i); + ok(dwLen == (is_vista ? S_OK : 39), "wrong size %lu for id %d\n", dwLen, i); - bRet = pSHLWAPI_269(szBuff, &guid); + bRet = pGUIDFromStringA(szBuff, &guid); ok(bRet != FALSE, "created invalid string '%s'\n", szBuff); if (bRet) @@ -129,34 +129,33 @@ static void test_ClassIDs(void) } /* Test endianness */ - dwLen = pSHLWAPI_23(&IID_Endianness, szBuff, 256); - ok(dwLen == (is_vista ? S_OK : 39), "wrong size %u for IID_Endianness\n", dwLen); + dwLen = pSHStringFromGUIDA(&IID_Endianness, szBuff, 256); + ok(dwLen == (is_vista ? S_OK : 39), "wrong size %lu for IID_Endianness\n", dwLen); ok(!strcmp(szBuff, "{01020304-0506-0708-090A-0B0C0D0E0F0A}"), "Endianness Broken, got '%s'\n", szBuff); /* test lengths */ szBuff[0] = ':'; - dwLen = pSHLWAPI_23(&IID_Endianness, szBuff, 0); + dwLen = pSHStringFromGUIDA(&IID_Endianness, szBuff, 0); ok(dwLen == (is_vista ? E_FAIL : 0), "accepted bad length\n"); ok(szBuff[0] == ':', "wrote to buffer with no length\n"); szBuff[0] = ':'; - dwLen = pSHLWAPI_23(&IID_Endianness, szBuff, 38); + dwLen = pSHStringFromGUIDA(&IID_Endianness, szBuff, 38); ok(dwLen == (is_vista ? E_FAIL : 0), "accepted bad length\n"); ok(szBuff[0] == ':', "wrote to buffer with no length\n"); szBuff[0] = ':'; - dwLen = pSHLWAPI_23(&IID_Endianness, szBuff, 39); + dwLen = pSHStringFromGUIDA(&IID_Endianness, szBuff, 39); ok(dwLen == (is_vista ? S_OK : 39), "rejected ok length\n"); ok(szBuff[0] == '{', "Didn't write to buffer with ok length\n"); - /* Test string */ strcpy(szBuff, "{xxx-"); - bRet = pSHLWAPI_269(szBuff, &guid); + bRet = pGUIDFromStringA(szBuff, &guid); ok(bRet == FALSE, "accepted invalid string\n"); - dwLen = pSHLWAPI_23(&IID_Endianness, szBuff, 39); + dwLen = pSHStringFromGUIDA(&IID_Endianness, szBuff, 39); ok(dwLen == (is_vista ? S_OK : 39), "rejected ok length\n"); ok(szBuff[0] == '{', "Didn't write to buffer with ok length\n"); } @@ -172,14 +171,14 @@ static void test_CLSIDFromProgIDWrap(void) pCLSIDFromProgIDWrap = (void*)GetProcAddress(hShlwapi,(char*)435); hres = pCLSIDFromProgIDWrap(wszStdPicture, &clsid); - ok(hres == S_OK, "CLSIDFromProgIDWrap failed: %08x\n", hres); + ok(hres == S_OK, "CLSIDFromProgIDWrap failed: %08lx\n", hres); ok(IsEqualGUID(&CLSID_StdPicture, &clsid), "wrong clsid\n"); hres = pCLSIDFromProgIDWrap(NULL, &clsid); - ok(hres == E_INVALIDARG, "CLSIDFromProgIDWrap failed: %08x, expected E_INVALIDARG\n", hres); + ok(hres == E_INVALIDARG, "CLSIDFromProgIDWrap failed: %08lx, expected E_INVALIDARG\n", hres); hres = pCLSIDFromProgIDWrap(wszStdPicture, NULL); - ok(hres == E_INVALIDARG, "CLSIDFromProgIDWrap failed: %08x, expected E_INVALIDARG\n", hres); + ok(hres == E_INVALIDARG, "CLSIDFromProgIDWrap failed: %08lx, expected E_INVALIDARG\n", hres); } START_TEST(clsid) @@ -192,8 +191,8 @@ START_TEST(clsid) return; } - pSHLWAPI_269 = (void*)GetProcAddress(hShlwapi, (LPSTR)269); - pSHLWAPI_23 = (void*)GetProcAddress(hShlwapi, (LPSTR)23); + pGUIDFromStringA = (void*)GetProcAddress(hShlwapi, (LPSTR)269); + pSHStringFromGUIDA = (void*)GetProcAddress(hShlwapi, (LPSTR)23); test_ClassIDs(); test_CLSIDFromProgIDWrap(); diff --git a/modules/rostests/winetests/shlwapi/generated.c b/modules/rostests/winetests/shlwapi/generated.c index 3a8e4269fc7..8465bf34475 100644 --- a/modules/rostests/winetests/shlwapi/generated.c +++ b/modules/rostests/winetests/shlwapi/generated.c @@ -30,7 +30,7 @@ #if defined(_MSC_VER) && (_MSC_VER >= 1300) && defined(__cplusplus) # define _TYPE_ALIGNMENT(type) __alignof(type) -#elif defined(__GNUC__) +#elif defined(__GNUC__) || defined(__clang__) # define _TYPE_ALIGNMENT(type) __alignof__(type) #else /* @@ -52,23 +52,23 @@ * Test helper macros */ -#define TEST_TYPE_SIZE(type, size) C_ASSERT(sizeof(type) == size); +#define TEST_TYPE_SIZE(type, size) C_ASSERT(sizeof(type) == size); #ifdef TYPE_ALIGNMENT -# define TEST_TYPE_ALIGN(type, align) C_ASSERT(TYPE_ALIGNMENT(type) == align); +# define TEST_TYPE_ALIGN(type, align) C_ASSERT(TYPE_ALIGNMENT(type) == align); #else # define TEST_TYPE_ALIGN(type, align) #endif #ifdef _TYPE_ALIGNMENT -# define TEST_TARGET_ALIGN(type, align) C_ASSERT(_TYPE_ALIGNMENT(*(type)0) == align); -# define TEST_FIELD_ALIGN(type, field, align) C_ASSERT(_TYPE_ALIGNMENT(((type*)0)->field) == align); +# define TEST_TARGET_ALIGN(type, align) C_ASSERT(_TYPE_ALIGNMENT(*(type)0) == align); +# define TEST_FIELD_ALIGN(type, field, align) C_ASSERT(_TYPE_ALIGNMENT(((type*)0)->field) == align); #else # define TEST_TARGET_ALIGN(type, align) # define TEST_FIELD_ALIGN(type, field, align) #endif -#define TEST_FIELD_OFFSET(type, field, offset) C_ASSERT(FIELD_OFFSET(type, field) == offset); +#define TEST_FIELD_OFFSET(type, field, offset) C_ASSERT(FIELD_OFFSET(type, field) == offset); #define TEST_TARGET_SIZE(type, size) TEST_TYPE_SIZE(*(type)0, size) #define TEST_FIELD_SIZE(type, field, size) TEST_TYPE_SIZE((((type*)0)->field), size) diff --git a/modules/rostests/winetests/shlwapi/istream.c b/modules/rostests/winetests/shlwapi/istream.c index 560a822e2c2..91ba98aa5c1 100644 --- a/modules/rostests/winetests/shlwapi/istream.c +++ b/modules/rostests/winetests/shlwapi/istream.c @@ -39,28 +39,28 @@ static void test_IStream_invalid_operations(IStream * stream, DWORD mode) ULONG count; char data[256]; - U(uzero).HighPart = 0; - U(uzero).LowPart = 0; - U(uret).HighPart = 0; - U(uret).LowPart = 0; - U(zero).HighPart = 0; - U(zero).LowPart = 0; + uzero.HighPart = 0; + uzero.LowPart = 0; + uret.HighPart = 0; + uret.LowPart = 0; + zero.HighPart = 0; + zero.LowPart = 0; /* IStream::Read */ /* IStream_Read from the COBJMACROS is undefined by shlwapi.h, replaced by the IStream_Read helper function. */ ret = stream->lpVtbl->Read(stream, NULL, 0, &count); - ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "expected S_OK, got 0x%08lx\n", ret); ret = stream->lpVtbl->Read(stream, data, 5, NULL); - ok(ret == S_FALSE || ret == S_OK, "expected S_FALSE or S_OK, got 0x%08x\n", ret); + ok(ret == S_FALSE || ret == S_OK, "expected S_FALSE or S_OK, got 0x%08lx\n", ret); ret = stream->lpVtbl->Read(stream, data, 0, NULL); - ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "expected S_OK, got 0x%08lx\n", ret); ret = stream->lpVtbl->Read(stream, data, 3, &count); - ok(ret == S_FALSE || ret == S_OK, "expected S_FALSE or S_OK, got 0x%08x\n", ret); + ok(ret == S_FALSE || ret == S_OK, "expected S_FALSE or S_OK, got 0x%08lx\n", ret); /* IStream::Write */ @@ -70,104 +70,104 @@ static void test_IStream_invalid_operations(IStream * stream, DWORD mode) if (mode == STGM_READ) { ok(ret == STG_E_ACCESSDENIED /* XP */ || broken(ret == S_OK) /* Win2000 + IE5 */, - "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret); + "expected STG_E_ACCESSDENIED, got 0x%08lx\n", ret); } else - ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "expected S_OK, got 0x%08lx\n", ret); strcpy(data, "Hello"); ret = stream->lpVtbl->Write(stream, data, 5, NULL); if (mode == STGM_READ) ok(ret == STG_E_ACCESSDENIED, - "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret); + "expected STG_E_ACCESSDENIED, got 0x%08lx\n", ret); else - ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "expected S_OK, got 0x%08lx\n", ret); strcpy(data, "Hello"); ret = stream->lpVtbl->Write(stream, data, 0, NULL); if (mode == STGM_READ) ok(ret == STG_E_ACCESSDENIED, - "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret); + "expected STG_E_ACCESSDENIED, got 0x%08lx\n", ret); else - ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "expected S_OK, got 0x%08lx\n", ret); strcpy(data, "Hello"); ret = stream->lpVtbl->Write(stream, data, 0, &count); if (mode == STGM_READ) ok(ret == STG_E_ACCESSDENIED, - "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret); + "expected STG_E_ACCESSDENIED, got 0x%08lx\n", ret); else - ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "expected S_OK, got 0x%08lx\n", ret); strcpy(data, "Hello"); ret = stream->lpVtbl->Write(stream, data, 3, &count); if (mode == STGM_READ) ok(ret == STG_E_ACCESSDENIED, - "expected STG_E_ACCESSDENIED, got 0x%08x\n", ret); + "expected STG_E_ACCESSDENIED, got 0x%08lx\n", ret); else - ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "expected S_OK, got 0x%08lx\n", ret); /* IStream::Seek */ ret = IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL); - ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "expected S_OK, got 0x%08lx\n", ret); ret = IStream_Seek(stream, zero, 20, NULL); ok(ret == E_INVALIDARG, - "expected E_INVALIDARG, got 0x%08x\n", ret); + "expected E_INVALIDARG, got 0x%08lx\n", ret); /* IStream::CopyTo */ ret = IStream_CopyTo(stream, NULL, uzero, &uret, &uret); - ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "expected S_OK, got 0x%08lx\n", ret); clone = NULL; ret = IStream_CopyTo(stream, clone, uzero, &uret, &uret); - ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "expected S_OK, got 0x%08lx\n", ret); ret = IStream_CopyTo(stream, stream, uzero, &uret, &uret); - ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "expected S_OK, got 0x%08lx\n", ret); ret = IStream_CopyTo(stream, stream, uzero, &uret, NULL); - ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "expected S_OK, got 0x%08lx\n", ret); ret = IStream_CopyTo(stream, stream, uzero, NULL, &uret); - ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "expected S_OK, got 0x%08lx\n", ret); /* IStream::Commit */ ret = IStream_Commit(stream, STGC_DEFAULT); - ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "expected S_OK, got 0x%08lx\n", ret); /* IStream::Revert */ ret = IStream_Revert(stream); - ok(ret == E_NOTIMPL, "expected E_NOTIMPL, got 0x%08x\n", ret); + ok(ret == E_NOTIMPL, "expected E_NOTIMPL, got 0x%08lx\n", ret); /* IStream::LockRegion */ ret = IStream_LockRegion(stream, uzero, uzero, 0); ok(ret == E_NOTIMPL /* XP */ || ret == S_OK /* Vista */, - "expected E_NOTIMPL or S_OK, got 0x%08x\n", ret); + "expected E_NOTIMPL or S_OK, got 0x%08lx\n", ret); /* IStream::UnlockRegion */ if (ret == E_NOTIMPL) /* XP */ { ret = IStream_UnlockRegion(stream, uzero, uzero, 0); - ok(ret == E_NOTIMPL, "expected E_NOTIMPL, got 0x%08x\n", ret); + ok(ret == E_NOTIMPL, "expected E_NOTIMPL, got 0x%08lx\n", ret); } else /* Vista */ { ret = IStream_UnlockRegion(stream, uzero, uzero, 0); - ok(ret == S_OK, "expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "expected S_OK, got 0x%08lx\n", ret); ret = IStream_UnlockRegion(stream, uzero, uzero, 0); - ok(ret == STG_E_LOCKVIOLATION, "expected STG_E_LOCKVIOLATION, got 0x%08x\n", ret); + ok(ret == STG_E_LOCKVIOLATION, "expected STG_E_LOCKVIOLATION, got 0x%08lx\n", ret); } /* IStream::Stat */ ret = IStream_Stat(stream, NULL, 0); ok(ret == STG_E_INVALIDPOINTER, - "expected STG_E_INVALIDPOINTER or E_NOTIMPL, got 0x%08x\n", ret); + "expected STG_E_INVALIDPOINTER or E_NOTIMPL, got 0x%08lx\n", ret); /* IStream::Clone */ @@ -175,12 +175,12 @@ static void test_IStream_invalid_operations(IStream * stream, DWORD mode) clone = NULL; ret = IStream_Clone(stream, &clone); - ok(ret == E_NOTIMPL, "expected E_NOTIMPL, got 0x%08x\n", ret); + ok(ret == E_NOTIMPL, "expected E_NOTIMPL, got 0x%08lx\n", ret); ok(clone == NULL, "expected a NULL IStream object, got %p\n", stream); if (clone) { refcount = IStream_Release(clone); - ok(refcount == 0, "expected 0, got %d\n", refcount); + ok(refcount == 0, "expected 0, got %ld\n", refcount); } } @@ -199,63 +199,63 @@ static void test_stream_read_write(IStream *stream, DWORD mode) ret = stream->lpVtbl->Write(stream, "\x5e\xa7", 2, &written); if (mode == STGM_WRITE || mode == STGM_READWRITE) { - ok(ret == S_OK, "IStream_Write error %#x (access %#x)\n", ret, mode); - ok(written == 2, "expected 2, got %u\n", written); + ok(ret == S_OK, "IStream_Write error %#lx (access %#lx)\n", ret, mode); + ok(written == 2, "expected 2, got %lu\n", written); } else { - ok(ret == STG_E_ACCESSDENIED || broken(ret == S_OK) /* win2000 */, "expected STG_E_ACCESSDENIED, got %#x (access %#x)\n", ret, mode); - ok(written == 0xdeadbeaf || broken(written == 2) /* win2000 */, "expected 0xdeadbeaf, got %#x\n", written); + ok(ret == STG_E_ACCESSDENIED || broken(ret == S_OK) /* win2000 */, "expected STG_E_ACCESSDENIED, got %#lx (access %#lx)\n", ret, mode); + ok(written == 0xdeadbeaf || broken(written == 2) /* win2000 */, "expected 0xdeadbeaf, got %#lx\n", written); written = 0; if (ret == S_OK) return; /* no point in further testing */ } ret = stream->lpVtbl->Seek(stream, start, STREAM_SEEK_SET, NULL); - ok(ret == S_OK, "Seek error %#x\n", ret); + ok(ret == S_OK, "Seek error %#lx\n", ret); count = 0xdeadbeaf; ret = stream->lpVtbl->Read(stream, buf, 2, &count); if (written != 0) { - ok(ret == S_OK || broken(ret == S_FALSE) /* win2000 */, "IStream_Read error %#x (access %#x, written %u)\n", ret, mode, written); + ok(ret == S_OK || broken(ret == S_FALSE) /* win2000 */, "IStream_Read error %#lx (access %#lx, written %lu)\n", ret, mode, written); if (ret == S_OK && (mode == STGM_WRITE || mode == STGM_READWRITE)) { - ok(count == 2, "expected 2, got %u\n", count); + ok(count == 2, "expected 2, got %lu\n", count); ok(buf[0] == 0x5e && buf[1] == 0xa7, "expected 5ea7, got %02x%02x\n", buf[0], buf[1]); } else - ok(count == 0, "expected 0, got %u\n", count); + ok(count == 0, "expected 0, got %lu\n", count); } else { - ok(ret == S_FALSE, "expected S_FALSE, got %#x (access %#x, written %u)\n", ret, mode, written); - ok(count == 0, "expected 0, got %u\n", count); + ok(ret == S_FALSE, "expected S_FALSE, got %#lx (access %#lx, written %lu)\n", ret, mode, written); + ok(count == 0, "expected 0, got %lu\n", count); } ret = stream->lpVtbl->Seek(stream, start, STREAM_SEEK_SET, NULL); - ok(ret == S_OK, "Seek error %#x\n", ret); + ok(ret == S_OK, "Seek error %#lx\n", ret); count = 0xdeadbeaf; ret = stream->lpVtbl->Read(stream, buf, 0, &count); - ok(ret == S_OK, "IStream_Read error %#x (access %#x, written %u)\n", ret, mode, written); - ok(count == 0, "expected 0, got %u\n", count); + ok(ret == S_OK, "IStream_Read error %#lx (access %#lx, written %lu)\n", ret, mode, written); + ok(count == 0, "expected 0, got %lu\n", count); count = 0xdeadbeaf; ret = stream->lpVtbl->Read(stream, buf, sizeof(buf), &count); - ok(ret == S_FALSE, "expected S_FALSE, got %#x (access %#x, written %u)\n", ret, mode, written); - ok(count == written, "expected %u, got %u\n", written, count); + ok(ret == S_FALSE, "expected S_FALSE, got %#lx (access %#lx, written %lu)\n", ret, mode, written); + ok(count == written, "expected %lu, got %lu\n", written, count); if (count) ok(buf[0] == 0x5e && buf[1] == 0xa7, "expected 5ea7, got %02x%02x\n", buf[0], buf[1]); memset(&statstg, 0xff, sizeof(statstg)); ret = IStream_Stat(stream, &statstg, 0); - ok(ret == S_OK, "Stat failed, hr %#x.\n", ret); + ok(ret == S_OK, "Stat failed, hr %#lx.\n", ret); ok(statstg.pwcsName != NULL, "Unexpected name %s.\n", wine_dbgstr_w(statstg.pwcsName)); CoTaskMemFree(statstg.pwcsName); memset(&statstg, 0xff, sizeof(statstg)); ret = IStream_Stat(stream, &statstg, STATFLAG_NONAME); - ok(ret == S_OK, "Stat failed, hr %#x.\n", ret); + ok(ret == S_OK, "Stat failed, hr %#lx.\n", ret); ok(statstg.pwcsName == NULL, "Unexpected name %s.\n", wine_dbgstr_w(statstg.pwcsName)); } @@ -265,18 +265,17 @@ static void test_stream_qi(IStream *stream) HRESULT hr; hr = IStream_QueryInterface(stream, &IID_IStream, (void **)&unk); - ok(SUCCEEDED(hr), "Failed to get IStream interface, hr %#x.\n", hr); + ok(SUCCEEDED(hr), "Failed to get IStream interface, hr %#lx.\n", hr); IUnknown_Release(unk); unk = NULL; hr = IStream_QueryInterface(stream, &IID_ISequentialStream, (void **)&unk); -todo_wine - ok(SUCCEEDED(hr) || broken(hr == E_NOINTERFACE) /* XP */, "Failed to get ISequentialStream interface, hr %#x.\n", hr); + ok(SUCCEEDED(hr) || broken(hr == E_NOINTERFACE) /* XP */, "Failed to get ISequentialStream interface, hr %#lx.\n", hr); if (unk) IUnknown_Release(unk); hr = IStream_QueryInterface(stream, &IID_IUnknown, (void **)&unk); - ok(SUCCEEDED(hr), "Failed to get IUnknown interface, hr %#x.\n", hr); + ok(SUCCEEDED(hr), "Failed to get IUnknown interface, hr %#lx.\n", hr); IUnknown_Release(unk); } @@ -288,7 +287,7 @@ static void test_SHCreateStreamOnFileA(DWORD mode, DWORD stgm) char test_file[MAX_PATH]; static const CHAR testA_txt[] = "\\testA.txt"; - trace("SHCreateStreamOnFileA: testing mode %d, STGM flags %08x\n", mode, stgm); + trace("SHCreateStreamOnFileA: testing mode %ld, STGM flags %08lx\n", mode, stgm); /* Don't used a fixed path for the testA.txt file */ GetTempPathA(MAX_PATH, test_file); @@ -306,40 +305,40 @@ static void test_SHCreateStreamOnFileA(DWORD mode, DWORD stgm) ok(ret == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) /* NT */ || ret == HRESULT_FROM_WIN32(ERROR_BAD_PATHNAME) /* 9x */, "SHCreateStreamOnFileA: expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) " - "or HRESULT_FROM_WIN32(ERROR_BAD_PATHNAME), got 0x%08x\n", ret); + "or HRESULT_FROM_WIN32(ERROR_BAD_PATHNAME), got 0x%08lx\n", ret); ok(stream == NULL, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream); if (0) /* This test crashes on WinXP SP2 */ { ret = SHCreateStreamOnFileA(test_file, mode | stgm, NULL); - ok(ret == E_INVALIDARG, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08x\n", ret); + ok(ret == E_INVALIDARG, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08lx\n", ret); } stream = NULL; ret = SHCreateStreamOnFileA(test_file, mode | STGM_CONVERT | stgm, &stream); - ok(ret == E_INVALIDARG, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08x\n", ret); + ok(ret == E_INVALIDARG, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08lx\n", ret); ok(stream == NULL, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream); stream = NULL; ret = SHCreateStreamOnFileA(test_file, mode | STGM_DELETEONRELEASE | stgm, &stream); - ok(ret == E_INVALIDARG, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08x\n", ret); + ok(ret == E_INVALIDARG, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08lx\n", ret); ok(stream == NULL, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream); stream = NULL; ret = SHCreateStreamOnFileA(test_file, mode | STGM_TRANSACTED | stgm, &stream); - ok(ret == E_INVALIDARG, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08x\n", ret); + ok(ret == E_INVALIDARG, "SHCreateStreamOnFileA: expected E_INVALIDARG, got 0x%08lx\n", ret); ok(stream == NULL, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream); /* file does not exist */ stream = NULL; ret = SHCreateStreamOnFileA(test_file, mode | STGM_FAILIFTHERE | stgm, &stream); - ok(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "SHCreateStreamOnFileA: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08x\n", ret); + ok(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "SHCreateStreamOnFileA: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08lx\n", ret); ok(stream == NULL, "SHCreateStreamOnFileA: expected a NULL IStream object, got %p\n", stream); stream = NULL; ret = SHCreateStreamOnFileA(test_file, mode | STGM_CREATE | stgm, &stream); - ok(ret == S_OK, "SHCreateStreamOnFileA: expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "SHCreateStreamOnFileA: expected S_OK, got 0x%08lx\n", ret); ok(stream != NULL, "SHCreateStreamOnFileA: expected a valid IStream object, got NULL\n"); if (stream) { @@ -347,7 +346,7 @@ if (0) /* This test crashes on WinXP SP2 */ test_IStream_invalid_operations(stream, mode); refcount = IStream_Release(stream); - ok(refcount == 0, "SHCreateStreamOnFileA: expected 0, got %d\n", refcount); + ok(refcount == 0, "SHCreateStreamOnFileA: expected 0, got %ld\n", refcount); } /* NOTE: don't delete the file, as it will be used for the file exists tests. */ @@ -356,19 +355,19 @@ if (0) /* This test crashes on WinXP SP2 */ stream = NULL; ret = SHCreateStreamOnFileA(test_file, mode | STGM_FAILIFTHERE | stgm, &stream); - ok(ret == S_OK, "SHCreateStreamOnFileA: expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "SHCreateStreamOnFileA: expected S_OK, got 0x%08lx\n", ret); ok(stream != NULL, "SHCreateStreamOnFileA: expected a valid IStream object, got NULL\n"); if (stream) { test_IStream_invalid_operations(stream, mode); refcount = IStream_Release(stream); - ok(refcount == 0, "SHCreateStreamOnFileA: expected 0, got %d\n", refcount); + ok(refcount == 0, "SHCreateStreamOnFileA: expected 0, got %ld\n", refcount); } stream = NULL; ret = SHCreateStreamOnFileA(test_file, mode | STGM_CREATE | stgm, &stream); - ok(ret == S_OK, "SHCreateStreamOnFileA: expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "SHCreateStreamOnFileA: expected S_OK, got 0x%08lx\n", ret); ok(stream != NULL, "SHCreateStreamOnFileA: expected a valid IStream object, got NULL\n"); if (stream) { @@ -378,10 +377,10 @@ if (0) /* This test crashes on WinXP SP2 */ test_IStream_invalid_operations(stream, mode); refcount = IStream_Release(stream); - ok(refcount == 0, "SHCreateStreamOnFileA: expected 0, got %d\n", refcount); + ok(refcount == 0, "SHCreateStreamOnFileA: expected 0, got %ld\n", refcount); delret = DeleteFileA(test_file); - ok(delret, "SHCreateStreamOnFileA: could not delete file '%s', got error %d\n", + ok(delret, "SHCreateStreamOnFileA: could not delete file '%s', got error %ld\n", test_file, GetLastError()); } } @@ -396,7 +395,7 @@ static void test_SHCreateStreamOnFileW(DWORD mode, DWORD stgm) CHAR test_fileA[MAX_PATH]; static const CHAR testW_txt[] = "\\testW.txt"; - trace("SHCreateStreamOnFileW: testing mode %d, STGM flags %08x\n", mode, stgm); + trace("SHCreateStreamOnFileW: testing mode %ld, STGM flags %08lx\n", mode, stgm); /* Don't used a fixed path for the testW.txt file */ GetTempPathA(MAX_PATH, test_fileA); @@ -412,7 +411,7 @@ static void test_SHCreateStreamOnFileW(DWORD mode, DWORD stgm) ret = SHCreateStreamOnFileW(NULL, mode | stgm, &stream); ok(ret == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || /* XP */ ret == E_INVALIDARG /* Vista */, - "SHCreateStreamOnFileW: expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) or E_INVALIDARG, got 0x%08x\n", ret); + "SHCreateStreamOnFileW: expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) or E_INVALIDARG, got 0x%08lx\n", ret); ok(stream == NULL, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream); } @@ -420,22 +419,22 @@ static void test_SHCreateStreamOnFileW(DWORD mode, DWORD stgm) { /* This test crashes on WinXP SP2 */ ret = SHCreateStreamOnFileW(test_file, mode | stgm, NULL); - ok(ret == E_INVALIDARG, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08x\n", ret); + ok(ret == E_INVALIDARG, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08lx\n", ret); } stream = NULL; ret = SHCreateStreamOnFileW(test_file, mode | STGM_CONVERT | stgm, &stream); - ok(ret == E_INVALIDARG, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08x\n", ret); + ok(ret == E_INVALIDARG, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08lx\n", ret); ok(stream == NULL, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream); stream = NULL; ret = SHCreateStreamOnFileW(test_file, mode | STGM_DELETEONRELEASE | stgm, &stream); - ok(ret == E_INVALIDARG, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08x\n", ret); + ok(ret == E_INVALIDARG, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08lx\n", ret); ok(stream == NULL, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream); stream = NULL; ret = SHCreateStreamOnFileW(test_file, mode | STGM_TRANSACTED | stgm, &stream); - ok(ret == E_INVALIDARG, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08x\n", ret); + ok(ret == E_INVALIDARG, "SHCreateStreamOnFileW: expected E_INVALIDARG, got 0x%08lx\n", ret); ok(stream == NULL, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream); /* file does not exist */ @@ -447,12 +446,12 @@ static void test_SHCreateStreamOnFileW(DWORD mode, DWORD stgm) return; } - ok(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "SHCreateStreamOnFileW: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08x\n", ret); + ok(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "SHCreateStreamOnFileW: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08lx\n", ret); ok(stream == NULL, "SHCreateStreamOnFileW: expected a NULL IStream object, got %p\n", stream); stream = NULL; ret = SHCreateStreamOnFileW(test_file, mode | STGM_CREATE | stgm, &stream); - ok(ret == S_OK, "SHCreateStreamOnFileW: expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "SHCreateStreamOnFileW: expected S_OK, got 0x%08lx\n", ret); ok(stream != NULL, "SHCreateStreamOnFileW: expected a valid IStream object, got NULL\n"); if (stream) { @@ -460,7 +459,7 @@ static void test_SHCreateStreamOnFileW(DWORD mode, DWORD stgm) test_IStream_invalid_operations(stream, mode); refcount = IStream_Release(stream); - ok(refcount == 0, "SHCreateStreamOnFileW: expected 0, got %d\n", refcount); + ok(refcount == 0, "SHCreateStreamOnFileW: expected 0, got %ld\n", refcount); } /* NOTE: don't delete the file, as it will be used for the file exists tests. */ @@ -469,19 +468,19 @@ static void test_SHCreateStreamOnFileW(DWORD mode, DWORD stgm) stream = NULL; ret = SHCreateStreamOnFileW(test_file, mode | STGM_FAILIFTHERE | stgm, &stream); - ok(ret == S_OK, "SHCreateStreamOnFileW: expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "SHCreateStreamOnFileW: expected S_OK, got 0x%08lx\n", ret); ok(stream != NULL, "SHCreateStreamOnFileW: expected a valid IStream object, got NULL\n"); if (stream) { test_IStream_invalid_operations(stream, mode); refcount = IStream_Release(stream); - ok(refcount == 0, "SHCreateStreamOnFileW: expected 0, got %d\n", refcount); + ok(refcount == 0, "SHCreateStreamOnFileW: expected 0, got %ld\n", refcount); } stream = NULL; ret = SHCreateStreamOnFileW(test_file, mode | STGM_CREATE | stgm, &stream); - ok(ret == S_OK, "SHCreateStreamOnFileW: expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "SHCreateStreamOnFileW: expected S_OK, got 0x%08lx\n", ret); ok(stream != NULL, "SHCreateStreamOnFileW: expected a valid IStream object, got NULL\n"); if (stream) { @@ -491,10 +490,10 @@ static void test_SHCreateStreamOnFileW(DWORD mode, DWORD stgm) test_IStream_invalid_operations(stream, mode); refcount = IStream_Release(stream); - ok(refcount == 0, "SHCreateStreamOnFileW: expected 0, got %d\n", refcount); + ok(refcount == 0, "SHCreateStreamOnFileW: expected 0, got %ld\n", refcount); delret = DeleteFileA(test_fileA); - ok(delret, "SHCreateStreamOnFileW: could not delete the test file, got error %d\n", + ok(delret, "SHCreateStreamOnFileW: could not delete the test file, got error %ld\n", GetLastError()); } } @@ -512,7 +511,7 @@ static void test_SHCreateStreamOnFileEx(DWORD mode, DWORD stgm) BOOL delret; if (winetest_debug > 1) - trace("SHCreateStreamOnFileEx: testing mode %d, STGM flags %08x\n", mode, stgm); + trace("SHCreateStreamOnFileEx: testing mode %ld, STGM flags %08lx\n", mode, stgm); /* Don't used a fixed path for the testEx.txt file */ GetTempPathA(MAX_PATH, test_fileA); @@ -528,7 +527,7 @@ static void test_SHCreateStreamOnFileEx(DWORD mode, DWORD stgm) ret = SHCreateStreamOnFileEx(NULL, mode, 0, FALSE, NULL, &stream); ok(ret == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) || /* XP */ ret == E_INVALIDARG /* Vista */, - "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) or E_INVALIDARG, got 0x%08x\n", ret); + "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) or E_INVALIDARG, got 0x%08lx\n", ret); ok(stream == NULL, "SHCreateStreamOnFileEx: expected a NULL IStream object, got %p\n", stream); } @@ -542,7 +541,7 @@ static void test_SHCreateStreamOnFileEx(DWORD mode, DWORD stgm) ok( ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) || ret == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) or " - "HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got 0x%08x\n", ret); + "HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got 0x%08lx\n", ret); ok(stream == NULL, "SHCreateStreamOnFileEx: expected a NULL IStream object, got %p\n", stream); @@ -550,7 +549,7 @@ static void test_SHCreateStreamOnFileEx(DWORD mode, DWORD stgm) { /* This test crashes on WinXP SP2 */ ret = SHCreateStreamOnFileEx(test_file, mode, 0, FALSE, NULL, NULL); - ok(ret == E_INVALIDARG, "SHCreateStreamOnFileEx: expected E_INVALIDARG, got 0x%08x\n", ret); + ok(ret == E_INVALIDARG, "SHCreateStreamOnFileEx: expected E_INVALIDARG, got 0x%08lx\n", ret); } /* file does not exist */ @@ -559,7 +558,7 @@ static void test_SHCreateStreamOnFileEx(DWORD mode, DWORD stgm) ret = SHCreateStreamOnFileEx(test_file, mode | STGM_FAILIFTHERE | stgm, 0, FALSE, NULL, &stream); if ((stgm & STGM_TRANSACTED) == STGM_TRANSACTED && mode == STGM_READ) { ok(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) /* XP */ || ret == E_INVALIDARG /* Vista */, - "SHCreateStreamOnFileEx: expected E_INVALIDARG or HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08x\n", ret); + "SHCreateStreamOnFileEx: expected E_INVALIDARG or HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), got 0x%08lx\n", ret); if (ret == E_INVALIDARG) { skip("SHCreateStreamOnFileEx: STGM_TRANSACTED not supported in this configuration.\n"); @@ -569,7 +568,7 @@ static void test_SHCreateStreamOnFileEx(DWORD mode, DWORD stgm) ok( ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) || ret == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) or " - "HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got 0x%08x\n", ret); + "HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), got 0x%08lx\n", ret); } ok(stream == NULL, "SHCreateStreamOnFileEx: expected a NULL IStream object, got %p\n", stream); @@ -582,7 +581,7 @@ static void test_SHCreateStreamOnFileEx(DWORD mode, DWORD stgm) return; } - ok(ret == S_OK, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08lx\n", ret); ok(stream != NULL, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n"); if (stream) { @@ -590,10 +589,10 @@ static void test_SHCreateStreamOnFileEx(DWORD mode, DWORD stgm) test_IStream_invalid_operations(stream, mode); refcount = IStream_Release(stream); - ok(refcount == 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount); + ok(refcount == 0, "SHCreateStreamOnFileEx: expected 0, got %ld\n", refcount); delret = DeleteFileA(test_fileA); - ok(delret, "SHCreateStreamOnFileEx: could not delete the test file, got error %d\n", + ok(delret, "SHCreateStreamOnFileEx: could not delete the test file, got error %ld\n", GetLastError()); } @@ -604,17 +603,17 @@ static void test_SHCreateStreamOnFileEx(DWORD mode, DWORD stgm) Sleep(1000); ret = SHCreateStreamOnFileEx(test_file, mode | STGM_CREATE | stgm, 0, FALSE, NULL, &stream); } - ok(ret == S_OK, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08lx\n", ret); ok(stream != NULL, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n"); if (stream) { test_IStream_invalid_operations(stream, mode); refcount = IStream_Release(stream); - ok(refcount == 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount); + ok(refcount == 0, "SHCreateStreamOnFileEx: expected 0, got %ld\n", refcount); delret = DeleteFileA(test_fileA); - ok(delret, "SHCreateStreamOnFileEx: could not delete the test file, got error %d\n", + ok(delret, "SHCreateStreamOnFileEx: could not delete the test file, got error %ld\n", GetLastError()); } @@ -625,14 +624,14 @@ static void test_SHCreateStreamOnFileEx(DWORD mode, DWORD stgm) Sleep(1000); ret = SHCreateStreamOnFileEx(test_file, mode | STGM_CREATE | stgm, 0, TRUE, NULL, &stream); } - ok(ret == S_OK, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08lx\n", ret); ok(stream != NULL, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n"); if (stream) { test_IStream_invalid_operations(stream, mode); refcount = IStream_Release(stream); - ok(refcount == 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount); + ok(refcount == 0, "SHCreateStreamOnFileEx: expected 0, got %ld\n", refcount); } /* NOTE: don't delete the file, as it will be used for the file exists tests. */ @@ -641,47 +640,47 @@ static void test_SHCreateStreamOnFileEx(DWORD mode, DWORD stgm) stream = NULL; ret = SHCreateStreamOnFileEx(test_file, mode | STGM_FAILIFTHERE | stgm, 0, FALSE, NULL, &stream); - ok(ret == S_OK, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08lx\n", ret); ok(stream != NULL, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n"); if (stream) { test_IStream_invalid_operations(stream, mode); refcount = IStream_Release(stream); - ok(refcount == 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount); + ok(refcount == 0, "SHCreateStreamOnFileEx: expected 0, got %ld\n", refcount); } stream = NULL; ret = SHCreateStreamOnFileEx(test_file, mode | STGM_FAILIFTHERE | stgm, 0, TRUE, NULL, &stream); - ok(ret == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), got 0x%08x\n", ret); + ok(ret == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "SHCreateStreamOnFileEx: expected HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), got 0x%08lx\n", ret); ok(stream == NULL, "SHCreateStreamOnFileEx: expected a NULL IStream object, got %p\n", stream); stream = NULL; ret = SHCreateStreamOnFileEx(test_file, mode | STGM_CREATE | stgm, 0, FALSE, NULL, &stream); - ok(ret == S_OK, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08lx\n", ret); ok(stream != NULL, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n"); if (stream) { test_IStream_invalid_operations(stream, mode); refcount = IStream_Release(stream); - ok(refcount == 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount); + ok(refcount == 0, "SHCreateStreamOnFileEx: expected 0, got %ld\n", refcount); } stream = NULL; ret = SHCreateStreamOnFileEx(test_file, mode | STGM_CREATE | stgm, 0, TRUE, NULL, &stream); - ok(ret == S_OK, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08x\n", ret); + ok(ret == S_OK, "SHCreateStreamOnFileEx: expected S_OK, got 0x%08lx\n", ret); ok(stream != NULL, "SHCreateStreamOnFileEx: expected a valid IStream object, got NULL\n"); if (stream) { test_IStream_invalid_operations(stream, mode); refcount = IStream_Release(stream); - ok(refcount == 0, "SHCreateStreamOnFileEx: expected 0, got %d\n", refcount); + ok(refcount == 0, "SHCreateStreamOnFileEx: expected 0, got %ld\n", refcount); } delret = DeleteFileA(test_fileA); - ok(delret, "SHCreateStreamOnFileEx: could not delete the test file, got error %d\n", + ok(delret, "SHCreateStreamOnFileEx: could not delete the test file, got error %ld\n", GetLastError()); } @@ -700,32 +699,32 @@ static void test_SHCreateStreamOnFileEx_CopyTo(void) GetTempPathW(MAX_PATH, tmpPath); ret = GetTempFileNameW(tmpPath, prefix, 0, srcFileName); - ok(ret != 0, "GetTempFileName failed, got error %d\n", GetLastError()); + ok(ret != 0, "GetTempFileName failed, got error %ld\n", GetLastError()); ret = GetTempFileNameW(tmpPath, prefix, 0, dstFileName); - ok(ret != 0, "GetTempFileName failed, got error %d\n", GetLastError()); + ok(ret != 0, "GetTempFileName failed, got error %ld\n", GetLastError()); ret = SHCreateStreamOnFileEx(srcFileName, STGM_CREATE | STGM_READWRITE | STGM_DELETEONRELEASE, FILE_ATTRIBUTE_TEMPORARY, FALSE, NULL, &src); - ok(SUCCEEDED(ret), "SHCreateStreamOnFileEx failed with ret=0x%08x\n", ret); + ok(SUCCEEDED(ret), "SHCreateStreamOnFileEx failed with ret=0x%08lx\n", ret); written.QuadPart = 0; - ret = IStream_Write(src, srcContents, sizeof(srcContents), &U(written).LowPart); - ok(SUCCEEDED(ret), "ISequentialStream_Write failed with ret=0x%08x\n", ret); + ret = IStream_Write(src, srcContents, sizeof(srcContents), &written.LowPart); + ok(SUCCEEDED(ret), "ISequentialStream_Write failed with ret=0x%08lx\n", ret); distance.QuadPart = 0; ret = IStream_Seek(src, distance, STREAM_SEEK_SET, &written); - ok(SUCCEEDED(ret), "ISequentialStream_Seek failed with ret=0x%08x\n", ret); + ok(SUCCEEDED(ret), "ISequentialStream_Seek failed with ret=0x%08lx\n", ret); ret = SHCreateStreamOnFileEx(dstFileName, STGM_CREATE | STGM_READWRITE | STGM_DELETEONRELEASE, FILE_ATTRIBUTE_TEMPORARY, FALSE, NULL, &dst); - ok(SUCCEEDED(ret), "SHCreateStreamOnFileEx failed with ret=0x%08x\n", ret); + ok(SUCCEEDED(ret), "SHCreateStreamOnFileEx failed with ret=0x%08lx\n", ret); /* Test using a count larger than the source file, so that the Read operation will fall short */ count.QuadPart = 2; ret = IStream_CopyTo(src, dst, count, &read, &written); - ok(SUCCEEDED(ret), "CopyTo failed with ret=0x%08x\n", ret); + ok(SUCCEEDED(ret), "CopyTo failed with ret=0x%08lx\n", ret); - ok(read.QuadPart == 1, "read does not match size: %d != 1\n", U(read).LowPart); - ok(written.QuadPart == 1, "written does not match size: %d != 1\n", U(written).LowPart); + ok(read.QuadPart == 1, "read does not match size: %ld != 1\n", read.LowPart); + ok(written.QuadPart == 1, "written does not match size: %ld != 1\n", written.LowPart); IStream_Release(dst); IStream_Release(src); @@ -737,8 +736,10 @@ static void test_SHCreateMemStream(void) { static const BYTE initial[10]; IStream *stream, *stream2; + LARGE_INTEGER off; IUnknown *unk; char buff[10]; + ULONG i, num; HRESULT hr; stream = SHCreateMemStream(initial, 0); @@ -753,18 +754,76 @@ static void test_SHCreateMemStream(void) ok(stream != NULL, "Failed to create a stream.\n"); hr = IStream_QueryInterface(stream, &IID_ISequentialStream, (void **)&unk); -todo_wine - ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* WinXP */, "Failed to QI, hr %#x.\n", hr); + ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* WinXP */, "Failed to QI, hr %#lx.\n", hr); if (unk) IUnknown_Release(unk); - hr = IStream_Read(stream, buff, sizeof(buff), NULL); -todo_wine - ok(hr == S_FALSE || broken(hr == S_OK) /* WinXP */, "Unexpected hr %#x.\n", hr); + num = ~0; + hr = IStream_Read(stream, buff, sizeof(buff), &num); +#ifdef __REACTOS__ + ok(hr == S_FALSE || broken(hr == S_OK) /* WS03 */, "Unexpected hr %#lx.\n", hr); +#else + ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr); +#endif + ok(num == 0, "expected 0, got 0x%08lx\n", num); + + num = ~0; + memset(buff, 0x55, sizeof(buff)); + hr = IStream_Write(stream, buff, sizeof(buff), &num); + ok(hr == S_OK, "Failed to write, hr %#lx.\n", hr); + ok(num == sizeof(buff), "expected %Iu, got %lu\n", sizeof(buff), num); + + off.QuadPart = 0; + hr = IStream_Seek(stream, off, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "Failed to seek, hr %#lx.\n", hr); + + num = ~0; + memset(buff, 0, sizeof(buff)); + hr = IStream_Read(stream, buff, sizeof(buff), &num); + ok(hr == S_OK, "Failed to read, hr %#lx.\n", hr); + ok(num == sizeof(buff), "expected %Iu, got %lu\n", sizeof(buff), num); + for (i = 0; i < ARRAY_SIZE(buff); i++) + ok(buff[i] == 0x55, "expected 0x55, got 0x%02x at %lu\n", buff[i], i); + + num = ~0; + hr = IStream_Read(stream, buff, sizeof(buff), &num); +#ifdef __REACTOS__ + ok(hr == S_FALSE || broken(hr == S_OK) /* WS03 */, "Unexpected hr %#lx.\n", hr); +#else + ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr); +#endif + ok(num == 0, "expected 0, got 0x%08lx\n", num); + + num = ~0; + memset(buff, 0x11, sizeof(buff)); + hr = IStream_Write(stream, buff, sizeof(buff), &num); + ok(hr == S_OK, "Failed to write, hr %#lx.\n", hr); + ok(num == sizeof(buff), "expected %Iu, got %lu\n", sizeof(buff), num); + + off.QuadPart = -sizeof(buff); + hr = IStream_Seek(stream, off, STREAM_SEEK_CUR, NULL); + ok(hr == S_OK, "Failed to seek, hr %#lx.\n", hr); + + num = ~0; + memset(buff, 0, sizeof(buff)); + hr = IStream_Read(stream, buff, sizeof(buff), &num); + ok(hr == S_OK, "Failed to read, hr %#lx.\n", hr); + ok(num == sizeof(buff), "expected %Iu, got %lu\n", sizeof(buff), num); + for (i = 0; i < ARRAY_SIZE(buff); i++) + ok(buff[i] == 0x11, "expected 0x11, got 0x%02x at %lu\n", buff[i], i); + + num = ~0; + hr = IStream_Read(stream, buff, sizeof(buff), &num); +#ifdef __REACTOS__ + ok(hr == S_FALSE || broken(hr == S_OK) /* WS03 */, "Unexpected hr %#lx.\n", hr); +#else + ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr); +#endif + ok(num == 0, "expected 0, got 0x%08lx\n", num); hr = IStream_Clone(stream, &stream2); -todo_wine - ok(hr == S_OK || broken(hr == E_NOTIMPL) /* < Win8 */, "Failed to clone a stream, hr %#x.\n", hr); + todo_wine + ok(hr == S_OK || broken(hr == E_NOTIMPL) /* < Win8 */, "Failed to clone a stream, hr %#lx.\n", hr); if (hr == S_OK) IStream_Release(stream2); diff --git a/modules/rostests/winetests/shlwapi/ordinal.c b/modules/rostests/winetests/shlwapi/ordinal.c index f4ea269f2ce..474c447686d 100644 --- a/modules/rostests/winetests/shlwapi/ordinal.c +++ b/modules/rostests/winetests/shlwapi/ordinal.c @@ -33,9 +33,6 @@ #include "docobj.h" #include "shobjidl.h" #include "shlobj.h" -#ifdef __REACTOS__ - #include -#endif /* Function ptrs for ordinal calls */ static HMODULE hShlwapi; @@ -54,8 +51,8 @@ static HRESULT(WINAPI *pIConnectionPoint_InvokeWithCancel)(IConnectionPoint*,DIS static HRESULT(WINAPI *pConnectToConnectionPoint)(IUnknown*,REFIID,BOOL,IUnknown*, LPDWORD,IConnectionPoint **); static HRESULT(WINAPI *pSHPropertyBag_ReadLONG)(IPropertyBag *,LPCWSTR,LPLONG); static LONG (WINAPI *pSHSetWindowBits)(HWND, INT, UINT, UINT); -static INT (WINAPI *pSHFormatDateTimeA)(const FILETIME UNALIGNED*, DWORD*, LPSTR, UINT); -static INT (WINAPI *pSHFormatDateTimeW)(const FILETIME UNALIGNED*, DWORD*, LPWSTR, UINT); +static INT (WINAPI *pSHFormatDateTimeA)(const FILETIME*, DWORD*, LPSTR, UINT); +static INT (WINAPI *pSHFormatDateTimeW)(const FILETIME*, DWORD*, LPWSTR, UINT); static DWORD (WINAPI *pSHGetObjectCompatFlags)(IUnknown*, const CLSID*); static BOOL (WINAPI *pGUIDFromStringA)(LPSTR, CLSID *); static HRESULT (WINAPI *pIUnknown_QueryServiceExec)(IUnknown*, REFIID, const GUID*, DWORD, DWORD, VARIANT*, VARIANT*); @@ -98,13 +95,6 @@ static const CHAR ie_international[] = { static const CHAR acceptlanguage[] = { 'A','c','c','e','p','t','L','a','n','g','u','a','g','e',0}; -static int strcmp_wa(LPCWSTR strw, const char *stra) -{ - CHAR buf[512]; - WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL); - return lstrcmpA(stra, buf); -} - typedef struct { int id; const void *args[5]; @@ -207,7 +197,7 @@ static void test_GetAcceptLanguagesA(void) /* Get the original Value */ lres = RegOpenKeyA(HKEY_CURRENT_USER, ie_international, &hroot); if (lres) { - skip("RegOpenKey(%s) failed: %d\n", ie_international, lres); + skip("RegOpenKey(%s) failed: %ld\n", ie_international, lres); return; } len = sizeof(original); @@ -240,7 +230,7 @@ static void test_GetAcceptLanguagesA(void) hr = pGetAcceptLanguagesA( buffer, &len); if (hr != S_OK) { - win_skip("GetAcceptLanguagesA failed with 0x%x\n", hr); + win_skip("GetAcceptLanguagesA failed with 0x%lx\n", hr); goto restore_original; } @@ -248,7 +238,7 @@ static void test_GetAcceptLanguagesA(void) /* some windows versions use "lang" or "lang-country" as default */ language[0] = 0; hr = LcidToRfc1766A(lcid, language, sizeof(language)); - ok(hr == S_OK, "LcidToRfc1766A returned 0x%x and %s\n", hr, language); + ok(hr == S_OK, "LcidToRfc1766A returned 0x%lx and %s\n", hr, language); } ok(!lstrcmpA(buffer, language), @@ -265,7 +255,7 @@ static void test_GetAcceptLanguagesA(void) exactsize = lstrlenA(entry); lres = RegSetValueExA(hroot, acceptlanguage, 0, REG_SZ, (const BYTE *) entry, exactsize + 1); - ok(!lres, "got %d for RegSetValueExA: %s\n", lres, entry); + ok(!lres, "got %ld for RegSetValueExA: %s\n", lres, entry); /* len includes space for the terminating 0 before vista/w2k8 */ len = exactsize + 2; @@ -276,7 +266,7 @@ static void test_GetAcceptLanguagesA(void) (SUCCEEDED(hr) && ((len == exactsize) || (len == exactsize+1)) && !lstrcmpA(buffer, entry)), - "+2_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer); + "+2_#%d: got 0x%lx with %ld and %s\n", i, hr, len, buffer); len = exactsize + 1; memset(buffer, '#', maxlen); @@ -286,7 +276,7 @@ static void test_GetAcceptLanguagesA(void) (SUCCEEDED(hr) && ((len == exactsize) || (len == exactsize+1)) && !lstrcmpA(buffer, entry)), - "+1_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer); + "+1_#%d: got 0x%lx with %ld and %s\n", i, hr, len, buffer); len = exactsize; memset(buffer, '#', maxlen); @@ -306,7 +296,7 @@ static void test_GetAcceptLanguagesA(void) ((hr == S_OK) && !memcmp(buffer, language, len)) || ((hr == E_NOT_SUFFICIENT_BUFFER) && !len) || ((hr == __HRESULT_FROM_WIN32(ERROR_MORE_DATA)) && len == exactsize)), - "==_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer); + "==_#%d: got 0x%lx with %ld and %s\n", i, hr, len, buffer); if (exactsize > 1) { len = exactsize - 1; @@ -318,7 +308,7 @@ static void test_GetAcceptLanguagesA(void) ((hr == S_OK) && !memcmp(buffer, language, len)) || ((hr == E_NOT_SUFFICIENT_BUFFER) && !len) || ((hr == __HRESULT_FROM_WIN32(ERROR_MORE_DATA)) && len == exactsize - 1)), - "-1_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer); + "-1_#%d: got 0x%lx with %ld and %s\n", i, hr, len, buffer); } len = 1; @@ -330,7 +320,7 @@ static void test_GetAcceptLanguagesA(void) ((hr == S_OK) && !memcmp(buffer, language, len)) || ((hr == E_NOT_SUFFICIENT_BUFFER) && !len) || ((hr == __HRESULT_FROM_WIN32(ERROR_MORE_DATA)) && len == 1)), - "=1_#%d: got 0x%x with %d and %s\n", i, hr, len, buffer); + "=1_#%d: got 0x%lx with %ld and %s\n", i, hr, len, buffer); len = maxlen; hr = pGetAcceptLanguagesA( NULL, &len); @@ -339,7 +329,7 @@ static void test_GetAcceptLanguagesA(void) since w2k8: S_OK and needed size (excluding 0), win8 S_OK and size including 0. */ ok( ((hr == S_OK) && ((len == exactsize) || (len == exactsize + 1))) || ((hr == E_FAIL) && (len == maxlen)), - "NULL,max #%d: got 0x%x with %d and %s\n", i, hr, len, buffer); + "NULL,max #%d: got 0x%lx with %ld and %s\n", i, hr, len, buffer); i++; } @@ -352,7 +342,7 @@ static void test_GetAcceptLanguagesA(void) buffer[maxlen] = 0; hr = pGetAcceptLanguagesA( buffer, &len); ok( ((hr == S_OK) && (len == lstrlenA(language))), - "max: got 0x%x with %d and %s (expected S_OK with %d and '%s'\n", + "max: got 0x%lx with %ld and %s (expected S_OK with %d and '%s'\n", hr, len, buffer, lstrlenA(language), language); len = 2; @@ -362,7 +352,7 @@ static void test_GetAcceptLanguagesA(void) ok( (((hr == S_OK) || (hr == E_INVALIDARG)) && !memcmp(buffer, language, len)) || ((hr == E_NOT_SUFFICIENT_BUFFER) && !len) || ((hr == __HRESULT_FROM_WIN32(ERROR_CANNOT_COPY)) && !len), - "=2: got 0x%x with %d and %s\n", hr, len, buffer); + "=2: got 0x%lx with %ld and %s\n", hr, len, buffer); len = 1; memset(buffer, '#', maxlen); @@ -375,7 +365,7 @@ static void test_GetAcceptLanguagesA(void) ok( (((hr == S_OK) || (hr == E_INVALIDARG)) && !memcmp(buffer, language, len)) || ((hr == E_NOT_SUFFICIENT_BUFFER) && !len) || ((hr == __HRESULT_FROM_WIN32(ERROR_CANNOT_COPY)) && !len), - "=1: got 0x%x with %d and %s\n", hr, len, buffer); + "=1: got 0x%lx with %ld and %s\n", hr, len, buffer); len = 0; memset(buffer, '#', maxlen); @@ -383,26 +373,26 @@ static void test_GetAcceptLanguagesA(void) hr = pGetAcceptLanguagesA( buffer, &len); /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG, win8 ERROR_CANNOT_COPY */ ok((hr == E_FAIL) || (hr == E_INVALIDARG) || (hr == __HRESULT_FROM_WIN32(ERROR_CANNOT_COPY)), - "got 0x%x\n", hr); + "got 0x%lx\n", hr); memset(buffer, '#', maxlen); buffer[maxlen] = 0; hr = pGetAcceptLanguagesA( buffer, NULL); /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG */ ok((hr == E_FAIL) || (hr == E_INVALIDARG), - "got 0x%x (expected E_FAIL or E_INVALIDARG)\n", hr); + "got 0x%lx (expected E_FAIL or E_INVALIDARG)\n", hr); hr = pGetAcceptLanguagesA( NULL, NULL); /* w2k3 and below: E_FAIL, since w2k8: E_INVALIDARG */ ok((hr == E_FAIL) || (hr == E_INVALIDARG), - "got 0x%x (expected E_FAIL or E_INVALIDARG)\n", hr); + "got 0x%lx (expected E_FAIL or E_INVALIDARG)\n", hr); restore_original: if (!res_query) { len = lstrlenA(original); lres = RegSetValueExA(hroot, acceptlanguage, 0, REG_SZ, (const BYTE *) original, len ? len + 1: 0); - ok(!lres, "RegSetValueEx(%s) failed: %d\n", original, lres); + ok(!lres, "RegSetValueEx(%s) failed: %ld\n", original, lres); } else { @@ -470,63 +460,63 @@ static void test_alloc_shared(int argc, char **argv) procid=GetCurrentProcessId(); hmem=pSHAllocShared(NULL,10,procid); - ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %u\n", GetLastError()); + ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %lu\n", GetLastError()); ret = pSHFreeShared(hmem, procid); - ok( ret, "SHFreeShared failed: %u\n", GetLastError()); + ok( ret, "SHFreeShared failed: %lu\n", GetLastError()); val.value = 0x12345678; val.handle = 0; hmem = pSHAllocShared(&val, sizeof(val), procid); - ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %u\n", GetLastError()); + ok(hmem!=NULL,"SHAllocShared(NULL...) failed: %lu\n", GetLastError()); p=pSHLockShared(hmem,procid); - ok(p!=NULL,"SHLockShared failed: %u\n", GetLastError()); + ok(p!=NULL,"SHLockShared failed: %lu\n", GetLastError()); if (p!=NULL) - ok(p->value == 0x12345678, "Wrong value in shared memory: %d instead of %d\n", p->value, 0x12345678); + ok(p->value == 0x12345678, "Wrong value in shared memory: %ld instead of %d\n", p->value, 0x12345678); ret = pSHUnlockShared(p); - ok( ret, "SHUnlockShared failed: %u\n", GetLastError()); + ok( ret, "SHUnlockShared failed: %lu\n", GetLastError()); - sprintf(cmdline, "%s %s %d %p", argv[0], argv[1], procid, hmem); + sprintf(cmdline, "%s %s %ld %p", argv[0], argv[1], procid, hmem); ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); - ok(ret, "could not create child process error: %u\n", GetLastError()); + ok(ret, "could not create child process error: %lu\n", GetLastError()); if (ret) { - winetest_wait_child_process(pi.hProcess); + wait_child_process(pi.hProcess); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); p = pSHLockShared(hmem, procid); - ok(p != NULL,"SHLockShared failed: %u\n", GetLastError()); + ok(p != NULL,"SHLockShared failed: %lu\n", GetLastError()); if (p != NULL && p->value != 0x12345678) { - ok(p->value == 0x12345679, "Wrong value in shared memory: %d instead of %d\n", p->value, 0x12345679); + ok(p->value == 0x12345679, "Wrong value in shared memory: %ld instead of %d\n", p->value, 0x12345679); hmem2 = p->handle; ok(hmem2 != NULL, "Expected handle in shared memory\n"); } ret = pSHUnlockShared(p); - ok(ret, "SHUnlockShared failed: %u\n", GetLastError()); + ok(ret, "SHUnlockShared failed: %lu\n", GetLastError()); } ret = pSHFreeShared(hmem, procid); - ok( ret, "SHFreeShared failed: %u\n", GetLastError()); + ok( ret, "SHFreeShared failed: %lu\n", GetLastError()); if (hmem2) { p = pSHLockShared(hmem2, procid); - ok(p != NULL,"SHLockShared failed: %u\n", GetLastError()); + ok(p != NULL,"SHLockShared failed: %lu\n", GetLastError()); if (p != NULL) - ok(p->value == 0xDEADBEEF, "Wrong value in shared memory: %d instead of %d\n", p->value, 0xDEADBEEF); + ok(p->value == 0xDEADBEEF, "Wrong value in shared memory: %ld instead of %d\n", p->value, 0xDEADBEEF); ret = pSHUnlockShared(p); - ok(ret, "SHUnlockShared failed: %u\n", GetLastError()); + ok(ret, "SHUnlockShared failed: %lu\n", GetLastError()); ret = pSHFreeShared(hmem2, procid); - ok(ret, "SHFreeShared failed: %u\n", GetLastError()); + ok(ret, "SHFreeShared failed: %lu\n", GetLastError()); } SetLastError(0xdeadbeef); ret = pSHFreeShared(NULL, procid); - ok(ret, "SHFreeShared failed: %u\n", GetLastError()); - ok(GetLastError() == 0xdeadbeef, "last error should not have changed, got %u\n", GetLastError()); + ok(ret, "SHFreeShared failed: %lu\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "last error should not have changed, got %lu\n", GetLastError()); } static void test_alloc_shared_remote(DWORD procid, HANDLE hmem) @@ -537,36 +527,36 @@ static void test_alloc_shared_remote(DWORD procid, HANDLE hmem) /* test directly accessing shared memory of a remote process */ p = pSHLockShared(hmem, procid); - ok(p != NULL || broken(p == NULL) /* Windows 7/8 */, "SHLockShared failed: %u\n", GetLastError()); + ok(p != NULL || broken(p == NULL) /* Windows 7/8 */, "SHLockShared failed: %lu\n", GetLastError()); if (p == NULL) { win_skip("Subprocess failed to modify shared memory, skipping test\n"); return; } - ok(p->value == 0x12345678, "Wrong value in shared memory: %d instead of %d\n", p->value, 0x12345678); + ok(p->value == 0x12345678, "Wrong value in shared memory: %ld instead of %d\n", p->value, 0x12345678); p->value++; val.value = 0xDEADBEEF; val.handle = 0; p->handle = pSHAllocShared(&val, sizeof(val), procid); - ok(p->handle != NULL, "SHAllocShared failed: %u\n", GetLastError()); + ok(p->handle != NULL, "SHAllocShared failed: %lu\n", GetLastError()); ret = pSHUnlockShared(p); - ok(ret, "SHUnlockShared failed: %u\n", GetLastError()); + ok(ret, "SHUnlockShared failed: %lu\n", GetLastError()); /* test SHMapHandle */ SetLastError(0xdeadbeef); hmem2 = pSHMapHandle(NULL, procid, GetCurrentProcessId(), 0, 0); ok(hmem2 == NULL, "expected NULL, got new handle\n"); - ok(GetLastError() == 0xdeadbeef, "last error should not have changed, got %u\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "last error should not have changed, got %lu\n", GetLastError()); hmem2 = pSHMapHandle(hmem, procid, GetCurrentProcessId(), 0, 0); /* It seems like Windows Vista/2008 uses a different internal implementation * for shared memory, and calling SHMapHandle fails. */ ok(hmem2 != NULL || broken(hmem2 == NULL), - "SHMapHandle failed: %u\n", GetLastError()); + "SHMapHandle failed: %lu\n", GetLastError()); if (hmem2 == NULL) { win_skip("Subprocess failed to map shared memory, skipping test\n"); @@ -574,16 +564,16 @@ static void test_alloc_shared_remote(DWORD procid, HANDLE hmem) } p = pSHLockShared(hmem2, GetCurrentProcessId()); - ok(p != NULL, "SHLockShared failed: %u\n", GetLastError()); + ok(p != NULL, "SHLockShared failed: %lu\n", GetLastError()); if (p != NULL) - ok(p->value == 0x12345679, "Wrong value in shared memory: %d instead of %d\n", p->value, 0x12345679); + ok(p->value == 0x12345679, "Wrong value in shared memory: %ld instead of %d\n", p->value, 0x12345679); ret = pSHUnlockShared(p); - ok(ret, "SHUnlockShared failed: %u\n", GetLastError()); + ok(ret, "SHUnlockShared failed: %lu\n", GetLastError()); ret = pSHFreeShared(hmem2, GetCurrentProcessId()); - ok(ret, "SHFreeShared failed: %u\n", GetLastError()); + ok(ret, "SHFreeShared failed: %lu\n", GetLastError()); } static void test_fdsa(void) @@ -618,52 +608,52 @@ static void test_fdsa(void) memset(&info, 0, sizeof(info)); ok(pFDSA_Initialize(block_size, inc, &info, mem, init_blocks), "FDSA_Initialize rets FALSE\n"); - ok(info.num_items == 0, "num_items = %d\n", info.num_items); + ok(info.num_items == 0, "num_items = %ld\n", info.num_items); ok(info.mem == mem, "mem = %p\n", info.mem); - ok(info.blocks_alloced == init_blocks, "blocks_alloced = %d\n", info.blocks_alloced); + ok(info.blocks_alloced == init_blocks, "blocks_alloced = %ld\n", info.blocks_alloced); ok(info.inc == inc, "inc = %d\n", info.inc); ok(info.block_size == block_size, "block_size = %d\n", info.block_size); ok(info.flags == 0, "flags = %d\n", info.flags); ret = pFDSA_InsertItem(&info, 1234, "1234567890"); - ok(ret == 0, "ret = %d\n", ret); - ok(info.num_items == 1, "num_items = %d\n", info.num_items); + ok(ret == 0, "ret = %ld\n", ret); + ok(info.num_items == 1, "num_items = %ld\n", info.num_items); ok(info.mem == mem, "mem = %p\n", info.mem); - ok(info.blocks_alloced == init_blocks, "blocks_alloced = %d\n", info.blocks_alloced); + ok(info.blocks_alloced == init_blocks, "blocks_alloced = %ld\n", info.blocks_alloced); ok(info.inc == inc, "inc = %d\n", info.inc); ok(info.block_size == block_size, "block_size = %d\n", info.block_size); ok(info.flags == 0, "flags = %d\n", info.flags); ret = pFDSA_InsertItem(&info, 1234, "abcdefghij"); - ok(ret == 1, "ret = %d\n", ret); + ok(ret == 1, "ret = %ld\n", ret); ret = pFDSA_InsertItem(&info, 1, "klmnopqrst"); - ok(ret == 1, "ret = %d\n", ret); + ok(ret == 1, "ret = %ld\n", ret); ret = pFDSA_InsertItem(&info, 0, "uvwxyzABCD"); - ok(ret == 0, "ret = %d\n", ret); + ok(ret == 0, "ret = %ld\n", ret); ok(info.mem == mem, "mem = %p\n", info.mem); ok(info.flags == 0, "flags = %d\n", info.flags); /* This next InsertItem will cause shlwapi to allocate its own mem buffer */ ret = pFDSA_InsertItem(&info, 0, "EFGHIJKLMN"); - ok(ret == 0, "ret = %d\n", ret); + ok(ret == 0, "ret = %ld\n", ret); ok(info.mem != mem, "mem = %p\n", info.mem); - ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced); + ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %ld\n", info.blocks_alloced); ok(info.flags == 0x1, "flags = %d\n", info.flags); ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCD1234567890klmnopqrstabcdefghij", 50), "mem %s\n", (char*)info.mem); ok(pFDSA_DeleteItem(&info, 2), "rets FALSE\n"); ok(info.mem != mem, "mem = %p\n", info.mem); - ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced); + ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %ld\n", info.blocks_alloced); ok(info.flags == 0x1, "flags = %d\n", info.flags); ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCDklmnopqrstabcdefghij", 40), "mem %s\n", (char*)info.mem); ok(pFDSA_DeleteItem(&info, 3), "rets FALSE\n"); ok(info.mem != mem, "mem = %p\n", info.mem); - ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %d\n", info.blocks_alloced); + ok(info.blocks_alloced == init_blocks + inc, "blocks_alloced = %ld\n", info.blocks_alloced); ok(info.flags == 0x1, "flags = %d\n", info.flags); ok(!memcmp(info.mem, "EFGHIJKLMNuvwxyzABCDklmnopqrst", 30), "mem %s\n", (char*)info.mem); @@ -726,11 +716,11 @@ static void test_GetShellSecurityDescriptor(void) ok(IsValidSecurityDescriptor(psd), "returned value is not valid SD\n"); ret = GetSecurityDescriptorControl(psd, &control, &dwRev); - ok(ret, "GetSecurityDescriptorControl failed with error %u\n", GetLastError()); + ok(ret, "GetSecurityDescriptorControl failed with error %lu\n", GetLastError()); ok(0 == (control & SE_SELF_RELATIVE), "SD should be absolute\n"); ret = GetSecurityDescriptorDacl(psd, &bHasDacl, &pAcl, &bDefaulted); - ok(ret, "GetSecurityDescriptorDacl failed with error %u\n", GetLastError()); + ok(ret, "GetSecurityDescriptorDacl failed with error %lu\n", GetLastError()); ok(bHasDacl, "SD has no DACL\n"); if (bHasDacl) @@ -745,36 +735,36 @@ static void test_GetShellSecurityDescriptor(void) ok(IsValidAcl(pAcl), "DACL is not valid\n"); ret = GetAclInformation(pAcl, &asiSize, sizeof(asiSize), AclSizeInformation); - ok(ret, "GetAclInformation failed with error %u\n", GetLastError()); + ok(ret, "GetAclInformation failed with error %lu\n", GetLastError()); - ok(asiSize.AceCount == 3, "Incorrect number of ACEs: %d entries\n", asiSize.AceCount); + ok(asiSize.AceCount == 3, "Incorrect number of ACEs: %ld entries\n", asiSize.AceCount); if (asiSize.AceCount == 3) { ACCESS_ALLOWED_ACE *paaa; /* will use for DENIED too */ ret = GetAce(pAcl, 0, (LPVOID*)&paaa); - ok(ret, "GetAce failed with error %u\n", GetLastError()); + ok(ret, "GetAce failed with error %lu\n", GetLastError()); ok(paaa->Header.AceType == ACCESS_ALLOWED_ACE_TYPE, "Invalid ACE type %d\n", paaa->Header.AceType); ok(paaa->Header.AceFlags == 0, "Invalid ACE flags %x\n", paaa->Header.AceFlags); - ok(paaa->Mask == GENERIC_ALL, "Invalid ACE mask %x\n", paaa->Mask); + ok(paaa->Mask == GENERIC_ALL, "Invalid ACE mask %lx\n", paaa->Mask); ret = GetAce(pAcl, 1, (LPVOID*)&paaa); - ok(ret, "GetAce failed with error %u\n", GetLastError()); + ok(ret, "GetAce failed with error %lu\n", GetLastError()); ok(paaa->Header.AceType == ACCESS_DENIED_ACE_TYPE, "Invalid ACE type %d\n", paaa->Header.AceType); /* first one of two ACEs generated from inheritable entry - without inheritance */ ok(paaa->Header.AceFlags == 0, "Invalid ACE flags %x\n", paaa->Header.AceFlags); - ok(paaa->Mask == GENERIC_WRITE, "Invalid ACE mask %x\n", paaa->Mask); + ok(paaa->Mask == GENERIC_WRITE, "Invalid ACE mask %lx\n", paaa->Mask); ret = GetAce(pAcl, 2, (LPVOID*)&paaa); - ok(ret, "GetAce failed with error %u\n", GetLastError()); + ok(ret, "GetAce failed with error %lu\n", GetLastError()); ok(paaa->Header.AceType == ACCESS_DENIED_ACE_TYPE, "Invalid ACE type %d\n", paaa->Header.AceType); /* second ACE - with inheritance */ ok(paaa->Header.AceFlags == MY_INHERITANCE, "Invalid ACE flags %x\n", paaa->Header.AceFlags); - ok(paaa->Mask == GENERIC_READ, "Invalid ACE mask %x\n", paaa->Mask); + ok(paaa->Mask == GENERIC_READ, "Invalid ACE mask %lx\n", paaa->Mask); } } } @@ -792,17 +782,17 @@ static void test_SHPackDispParams(void) memset(¶ms, 0xc0, sizeof(params)); memset(vars, 0xc0, sizeof(vars)); hres = pSHPackDispParams(¶ms, vars, 1, VT_I4, 0xdeadbeef); - ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres); + ok(hres == S_OK, "SHPackDispParams failed: %08lx\n", hres); ok(params.cArgs == 1, "params.cArgs = %d\n", params.cArgs); ok(params.cNamedArgs == 0, "params.cNamedArgs = %d\n", params.cArgs); ok(params.rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", params.rgdispidNamedArgs); ok(params.rgvarg == vars, "params.rgvarg = %p\n", params.rgvarg); ok(V_VT(vars) == VT_I4, "V_VT(var) = %d\n", V_VT(vars)); - ok(V_I4(vars) == 0xdeadbeef, "failed %x\n", V_I4(vars)); + ok(V_I4(vars) == 0xdeadbeef, "failed %lx\n", V_I4(vars)); memset(¶ms, 0xc0, sizeof(params)); hres = pSHPackDispParams(¶ms, NULL, 0, 0); - ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres); + ok(hres == S_OK, "SHPackDispParams failed: %08lx\n", hres); ok(params.cArgs == 0, "params.cArgs = %d\n", params.cArgs); ok(params.cNamedArgs == 0, "params.cNamedArgs = %d\n", params.cArgs); ok(params.rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", params.rgdispidNamedArgs); @@ -812,17 +802,17 @@ static void test_SHPackDispParams(void) memset(¶ms, 0xc0, sizeof(params)); hres = pSHPackDispParams(¶ms, vars, 4, VT_BSTR, (void*)0xdeadbeef, VT_EMPTY, 10, VT_I4, 100, VT_DISPATCH, (void*)0xdeadbeef); - ok(hres == S_OK, "SHPackDispParams failed: %08x\n", hres); + ok(hres == S_OK, "SHPackDispParams failed: %08lx\n", hres); ok(params.cArgs == 4, "params.cArgs = %d\n", params.cArgs); ok(params.cNamedArgs == 0, "params.cNamedArgs = %d\n", params.cArgs); ok(params.rgdispidNamedArgs == NULL, "params.rgdispidNamedArgs = %p\n", params.rgdispidNamedArgs); ok(params.rgvarg == vars, "params.rgvarg = %p\n", params.rgvarg); ok(V_VT(vars) == VT_DISPATCH, "V_VT(vars[0]) = %x\n", V_VT(vars)); - ok(V_I4(vars) == 0xdeadbeef, "V_I4(vars[0]) = %x\n", V_I4(vars)); + ok(V_I4(vars) == 0xdeadbeef, "V_I4(vars[0]) = %lx\n", V_I4(vars)); ok(V_VT(vars+1) == VT_I4, "V_VT(vars[1]) = %d\n", V_VT(vars+1)); - ok(V_I4(vars+1) == 100, "V_I4(vars[1]) = %x\n", V_I4(vars+1)); + ok(V_I4(vars+1) == 100, "V_I4(vars[1]) = %lx\n", V_I4(vars+1)); ok(V_VT(vars+2) == VT_I4, "V_VT(vars[2]) = %d\n", V_VT(vars+2)); - ok(V_I4(vars+2) == 10, "V_I4(vars[2]) = %x\n", V_I4(vars+2)); + ok(V_I4(vars+2) == 10, "V_I4(vars[2]) = %lx\n", V_I4(vars+2)); ok(V_VT(vars+3) == VT_BSTR, "V_VT(vars[3]) = %d\n", V_VT(vars+3)); ok(V_BSTR(vars+3) == (void*)0xdeadbeef, "V_BSTR(vars[3]) = %p\n", V_BSTR(vars+3)); } @@ -974,13 +964,13 @@ static HRESULT WINAPI Disp_Invoke( EXCEPINFO *pExcepInfo, UINT *puArgErr) { - trace("%p %x %s %x %x %p %p %p %p\n", This, dispIdMember, wine_dbgstr_guid(riid), lcid, wFlags, + trace("%p %lx %s %lx %x %p %p %p %p\n", This, dispIdMember, wine_dbgstr_guid(riid), lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); ok(dispIdMember == 0xa0 || dispIdMember == 0xa1, "Unknown dispIdMember\n"); ok(pDispParams != NULL, "Invoked with NULL pDispParams\n"); ok(wFlags == DISPATCH_METHOD, "Wrong flags %x\n",wFlags); - ok(lcid == 0,"Wrong lcid %x\n",lcid); + ok(lcid == 0,"Wrong lcid %lx\n",lcid); if (dispIdMember == 0xa0) { ok(pDispParams->cArgs == 0, "params.cArgs = %d\n", pDispParams->cArgs); @@ -996,7 +986,7 @@ static HRESULT WINAPI Disp_Invoke( ok(V_VT(pDispParams->rgvarg) == VT_BSTR, "V_VT(var) = %d\n", V_VT(pDispParams->rgvarg)); ok(V_I4(pDispParams->rgvarg) == 0xdeadcafe , "failed %p\n", V_BSTR(pDispParams->rgvarg)); ok(V_VT(pDispParams->rgvarg+1) == VT_I4, "V_VT(var) = %d\n", V_VT(pDispParams->rgvarg+1)); - ok(V_I4(pDispParams->rgvarg+1) == 0xdeadbeef, "failed %x\n", V_I4(pDispParams->rgvarg+1)); + ok(V_I4(pDispParams->rgvarg+1) == 0xdeadbeef, "failed %lx\n", V_I4(pDispParams->rgvarg+1)); } return ERROR_SUCCESS; @@ -1433,7 +1423,7 @@ static HRESULT WINAPI Contain_FindConnectionPoint( else { *ppCP = iface->pt[0]; - IUnknown_AddRef((IUnknown*)*ppCP); + IConnectionPoint_AddRef(*ppCP); } return S_OK; @@ -1469,32 +1459,34 @@ static void test_IConnectionPoint(void) dispatch->IDispatch_iface.lpVtbl = &disp_vtbl; dispatch->refCount = 1; - rc = pConnectToConnectionPoint((IUnknown*)dispatch, &IID_NULL, TRUE, (IUnknown*)container, &cookie, &point); - ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc); + rc = pConnectToConnectionPoint((IUnknown*)&dispatch->IDispatch_iface, &IID_NULL, TRUE, + (IUnknown*)&container->IConnectionPointContainer_iface, &cookie, &point); + ok(rc == S_OK, "pConnectToConnectionPoint failed with %lx\n",rc); ok(point != NULL, "returned ConnectionPoint is NULL\n"); ok(cookie != 0xffffffff, "invalid cookie returned\n"); rc = pIConnectionPoint_SimpleInvoke(point,0xa0,NULL); - ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc); + ok(rc == S_OK, "pConnectToConnectionPoint failed with %lx\n",rc); memset(¶ms, 0xc0, sizeof(params)); memset(vars, 0xc0, sizeof(vars)); rc = pSHPackDispParams(¶ms, vars, 2, VT_I4, 0xdeadbeef, VT_BSTR, 0xdeadcafe); - ok(rc == S_OK, "SHPackDispParams failed: %08x\n", rc); + ok(rc == S_OK, "SHPackDispParams failed: %08lx\n", rc); rc = pIConnectionPoint_SimpleInvoke(point,0xa1,¶ms); - ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc); + ok(rc == S_OK, "pConnectToConnectionPoint failed with %lx\n",rc); - rc = pConnectToConnectionPoint(NULL, &IID_NULL, FALSE, (IUnknown*)container, &cookie, NULL); - ok(rc == S_OK, "pConnectToConnectionPoint failed with %x\n",rc); + rc = pConnectToConnectionPoint(NULL, &IID_NULL, FALSE, + (IUnknown*)&container->IConnectionPointContainer_iface, &cookie, NULL); + ok(rc == S_OK, "pConnectToConnectionPoint failed with %lx\n",rc); -/* MSDN says this should be required but it crashs on XP +/* MSDN says this should be required but it crashes on XP IUnknown_Release(point); */ - ref = IUnknown_Release((IUnknown*)container); - ok(ref == 0, "leftover IConnectionPointContainer reference %i\n",ref); - ref = IUnknown_Release((IUnknown*)dispatch); - ok(ref == 0, "leftover IDispatch reference %i\n",ref); + ref = IConnectionPointContainer_Release(&container->IConnectionPointContainer_iface); + ok(ref == 0, "leftover IConnectionPointContainer reference %li\n",ref); + ref = IDispatch_Release(&dispatch->IDispatch_iface); + ok(ref == 0, "leftover IDispatch reference %li\n",ref); } typedef struct _propbag @@ -1593,17 +1585,17 @@ static void test_SHPropertyBag_ReadLONG(void) out = 0xfeedface; rc = pSHPropertyBag_ReadLONG(NULL, szName1, &out); - ok(rc == E_INVALIDARG || broken(rc == S_OK), "incorrect return %x\n",rc); + ok(rc == E_INVALIDARG || broken(rc == S_OK), "incorrect return %lx\n",rc); ok(out == 0xfeedface, "value should not have changed\n"); rc = pSHPropertyBag_ReadLONG(&pb->IPropertyBag_iface, NULL, &out); - ok(rc == E_INVALIDARG || broken(rc == S_OK) || broken(rc == S_FALSE), "incorrect return %x\n",rc); + ok(rc == E_INVALIDARG || broken(rc == S_OK) || broken(rc == S_FALSE), "incorrect return %lx\n",rc); ok(out == 0xfeedface, "value should not have changed\n"); rc = pSHPropertyBag_ReadLONG(&pb->IPropertyBag_iface, szName1, NULL); - ok(rc == E_INVALIDARG || broken(rc == S_OK) || broken(rc == S_FALSE), "incorrect return %x\n",rc); + ok(rc == E_INVALIDARG || broken(rc == S_OK) || broken(rc == S_FALSE), "incorrect return %lx\n",rc); rc = pSHPropertyBag_ReadLONG(&pb->IPropertyBag_iface, szName1, &out); - ok(rc == DISP_E_BADVARTYPE || broken(rc == S_OK) || broken(rc == S_FALSE), "incorrect return %x\n",rc); - ok(out == 0xfeedface || broken(out == 0xfeedfa00), "value should not have changed %x\n",out); - IUnknown_Release((IUnknown*)pb); + ok(rc == DISP_E_BADVARTYPE || broken(rc == S_OK) || broken(rc == S_FALSE), "incorrect return %lx\n",rc); + ok(out == 0xfeedface || broken(out == 0xfeedfa00), "value should not have changed %lx\n",out); + IPropertyBag_Release(&pb->IPropertyBag_iface); } static void test_SHSetWindowBits(void) @@ -1631,9 +1623,9 @@ static void test_SHSetWindowBits(void) /* null window */ SetLastError(0xdeadbeef); style = pSHSetWindowBits(NULL, GWL_STYLE, 0, 0); - ok(style == 0, "expected 0 retval, got %d\n", style); + ok(style == 0, "expected 0 retval, got %ld\n", style); ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE, - "expected ERROR_INVALID_WINDOW_HANDLE, got %d\n", GetLastError()); + "expected ERROR_INVALID_WINDOW_HANDLE, got %ld\n", GetLastError()); /* zero mask, zero flags */ styleold = GetWindowLongA(hwnd, GWL_STYLE); @@ -1646,19 +1638,19 @@ static void test_SHSetWindowBits(void) ok(styleold & WS_VISIBLE, "expected WS_VISIBLE\n"); style = pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, 0); - ok(style == styleold, "expected previous style, got %x\n", style); + ok(style == styleold, "expected previous style, got %lx\n", style); ok((GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE) == 0, "expected updated style\n"); /* test mask, unset style bit used */ styleold = GetWindowLongA(hwnd, GWL_STYLE); style = pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, 0); - ok(style == styleold, "expected previous style, got %x\n", style); + ok(style == styleold, "expected previous style, got %lx\n", style); ok(styleold == GetWindowLongA(hwnd, GWL_STYLE), "expected to keep old style\n"); /* set back with flags */ styleold = GetWindowLongA(hwnd, GWL_STYLE); style = pSHSetWindowBits(hwnd, GWL_STYLE, WS_VISIBLE, WS_VISIBLE); - ok(style == styleold, "expected previous style, got %x\n", style); + ok(style == styleold, "expected previous style, got %lx\n", style); ok(GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE, "expected updated style\n"); /* reset and try to set without a mask */ @@ -1666,7 +1658,7 @@ static void test_SHSetWindowBits(void) ok((GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE) == 0, "expected updated style\n"); styleold = GetWindowLongA(hwnd, GWL_STYLE); style = pSHSetWindowBits(hwnd, GWL_STYLE, 0, WS_VISIBLE); - ok(style == styleold, "expected previous style, got %x\n", style); + ok(style == styleold, "expected previous style, got %lx\n", style); ok((GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE) == 0, "expected updated style\n"); DestroyWindow(hwnd); @@ -1674,37 +1666,34 @@ static void test_SHSetWindowBits(void) UnregisterClassA("Shlwapi test class", GetModuleHandleA(NULL)); } -static void test_SHFormatDateTimeA(void) +static void test_SHFormatDateTimeA(const SYSTEMTIME *st) { - FILETIME UNALIGNED filetime; + FILETIME filetime; + FILETIME filetimeCheck; + SYSTEMTIME universalSystemTime; CHAR buff[100], buff2[100], buff3[100]; - SYSTEMTIME st; + BOOL dstMatch; DWORD flags; INT ret; -if (0) -{ - /* crashes on native */ - pSHFormatDateTimeA(NULL, NULL, NULL, 0); -} - - GetLocalTime(&st); - SystemTimeToFileTime(&st, &filetime); /* SHFormatDateTime expects input as utc */ - LocalFileTimeToFileTime(&filetime, &filetime); + TzSpecificLocalTimeToSystemTime(NULL, st, &universalSystemTime); + SystemTimeToFileTime(&universalSystemTime, &filetime); + + SystemTimeToFileTime(st, &filetimeCheck); + LocalFileTimeToFileTime(&filetimeCheck, &filetimeCheck); + dstMatch = (filetime.dwHighDateTime == filetimeCheck.dwHighDateTime) && + (filetime.dwLowDateTime == filetimeCheck.dwLowDateTime); /* no way to get required buffer length here */ - SetLastError(0xdeadbeef); ret = pSHFormatDateTimeA(&filetime, NULL, NULL, 0); ok(ret == 0, "got %d\n", ret); - ok(GetLastError() == 0xdeadbeef || broken(GetLastError() == ERROR_SUCCESS /* Win7 */), - "expected 0xdeadbeef, got %d\n", GetLastError()); SetLastError(0xdeadbeef); buff[0] = 'a'; buff[1] = 0; ret = pSHFormatDateTimeA(&filetime, NULL, buff, 0); ok(ret == 0, "got %d\n", ret); - ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %ld\n", GetLastError()); ok(buff[0] == 'a', "expected same string, got %s\n", buff); /* flags needs to have FDTF_NOAUTOREADINGORDER for these tests to succeed on Vista+ */ @@ -1714,55 +1703,73 @@ if (0) SetLastError(0xdeadbeef); ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); ok(ret == lstrlenA(buff)+1, "got %d\n", ret); - ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %ld\n", GetLastError()); flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTDATE | FDTF_LONGDATE; SetLastError(0xdeadbeef); ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); ok(ret == lstrlenA(buff)+1, "got %d\n", ret); - ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %ld\n", GetLastError()); flags = FDTF_SHORTDATE | FDTF_LTRDATE | FDTF_RTLDATE; SetLastError(0xdeadbeef); ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); ok(ret == lstrlenA(buff)+1, "got %d\n", ret); ok(GetLastError() == 0xdeadbeef, - "expected 0xdeadbeef, got %d\n", GetLastError()); + "expected 0xdeadbeef, got %ld\n", GetLastError()); + + flags = FDTF_DEFAULT; + ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); + ok(ret == lstrlenA(buff)+1, "got %d\n", ret); + + buff2[0] = '\0'; + flags = FDTF_SHORTDATE | FDTF_SHORTTIME; + ret = pSHFormatDateTimeA(&filetime, &flags, buff2, sizeof(buff2)); + ok(ret == lstrlenA(buff2)+1, "got %d\n", ret); + ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff, buff2); + + buff2[0] = '\0'; + ret = pSHFormatDateTimeA(&filetime, NULL, buff2, sizeof(buff2)); + ok(ret == lstrlenA(buff2)+1, "got %d\n", ret); + ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff, buff2); /* now check returned strings */ flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTTIME; ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); ok(ret == lstrlenA(buff)+1, "got %d\n", ret); - ret = GetTimeFormatA(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff2, sizeof(buff2)); + ret = GetTimeFormatA(LOCALE_USER_DEFAULT, TIME_NOSECONDS | LOCALE_USE_CP_ACP, st, NULL, buff2, sizeof(buff2)); ok(ret == lstrlenA(buff2)+1, "got %d\n", ret); - ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff); + ok(lstrcmpA(buff, buff2) == 0 || broken(!dstMatch) /* pre Windows 7 */, + "expected (%s), got (%s)\n", buff2, buff); flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGTIME; ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); ok(ret == lstrlenA(buff)+1, "got %d\n", ret); - ret = GetTimeFormatA(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2)); + ret = GetTimeFormatA(LOCALE_USER_DEFAULT, LOCALE_USE_CP_ACP, st, NULL, buff2, sizeof(buff2)); ok(ret == lstrlenA(buff2)+1, "got %d\n", ret); - ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff); + ok(lstrcmpA(buff, buff2) == 0 || broken(!dstMatch) /* pre Windows 7 */, + "expected (%s), got (%s)\n", buff2, buff); /* both time flags */ flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGTIME | FDTF_SHORTTIME; ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); ok(ret == lstrlenA(buff)+1, "got %d\n", ret); - ret = GetTimeFormatA(LOCALE_USER_DEFAULT, 0, &st, NULL, buff2, sizeof(buff2)); + ret = GetTimeFormatA(LOCALE_USER_DEFAULT, LOCALE_USE_CP_ACP, st, NULL, buff2, sizeof(buff2)); ok(ret == lstrlenA(buff2)+1, "got %d\n", ret); - ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff); + ok(lstrcmpA(buff, buff2) == 0 || broken(!dstMatch) /* pre Windows 7 */, + "expected (%s), got (%s)\n", buff2, buff); flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTDATE; ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); ok(ret == lstrlenA(buff)+1, "got %d\n", ret); - ret = GetDateFormatA(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)); + ret = GetDateFormatA(LOCALE_USER_DEFAULT, DATE_SHORTDATE | LOCALE_USE_CP_ACP, st, NULL, buff2, sizeof(buff2)); ok(ret == lstrlenA(buff2)+1, "got %d\n", ret); ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff); flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGDATE; ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); ok(ret == lstrlenA(buff)+1, "got %d\n", ret); - ret = GetDateFormatA(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)); + ret = GetDateFormatA(LOCALE_USER_DEFAULT, DATE_LONGDATE | LOCALE_USE_CP_ACP, st, NULL, buff2, sizeof(buff2)); ok(ret == lstrlenA(buff2)+1, "got %d\n", ret); ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff); @@ -1770,7 +1777,7 @@ if (0) flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGDATE | FDTF_SHORTDATE; ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); ok(ret == lstrlenA(buff)+1, "got %d\n", ret); - ret = GetDateFormatA(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)); + ret = GetDateFormatA(LOCALE_USER_DEFAULT, DATE_LONGDATE | LOCALE_USE_CP_ACP, st, NULL, buff2, sizeof(buff2)); ok(ret == lstrlenA(buff2)+1, "got %d\n", ret); ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff); @@ -1778,12 +1785,12 @@ if (0) flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGDATE | FDTF_SHORTTIME; ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); ok(ret == lstrlenA(buff)+1, "got %d, length %d\n", ret, lstrlenA(buff)+1); - ret = GetTimeFormatA(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3)); + ret = GetTimeFormatA(LOCALE_USER_DEFAULT, TIME_NOSECONDS | LOCALE_USE_CP_ACP, st, NULL, buff3, sizeof(buff3)); ok(ret == lstrlenA(buff3)+1, "got %d\n", ret); - ok(lstrcmpA(buff3, buff + lstrlenA(buff) - lstrlenA(buff3)) == 0, + ok(lstrcmpA(buff3, buff + lstrlenA(buff) - lstrlenA(buff3)) == 0 || broken(!dstMatch) /* pre Windows 7 */, "expected (%s), got (%s) for time part\n", buff3, buff + lstrlenA(buff) - lstrlenA(buff3)); - ret = GetDateFormatA(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)); + ret = GetDateFormatA(LOCALE_USER_DEFAULT, DATE_LONGDATE | LOCALE_USE_CP_ACP, st, NULL, buff2, sizeof(buff2)); ok(ret == lstrlenA(buff2)+1, "got %d\n", ret); buff[lstrlenA(buff2)] = '\0'; ok(lstrcmpA(buff2, buff) == 0, "expected (%s) got (%s) for date part\n", @@ -1792,12 +1799,12 @@ if (0) flags = FDTF_NOAUTOREADINGORDER | FDTF_LONGDATE | FDTF_LONGTIME; ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); ok(ret == lstrlenA(buff)+1, "got %d\n", ret); - ret = GetTimeFormatA(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3)); + ret = GetTimeFormatA(LOCALE_USER_DEFAULT, LOCALE_USE_CP_ACP, st, NULL, buff3, sizeof(buff3)); ok(ret == lstrlenA(buff3)+1, "got %d\n", ret); - ok(lstrcmpA(buff3, buff + lstrlenA(buff) - lstrlenA(buff3)) == 0, + ok(lstrcmpA(buff3, buff + lstrlenA(buff) - lstrlenA(buff3)) == 0 || broken(!dstMatch) /* pre Windows 7 */, "expected (%s), got (%s) for time part\n", buff3, buff + lstrlenA(buff) - lstrlenA(buff3)); - ret = GetDateFormatA(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL, buff2, sizeof(buff2)); + ret = GetDateFormatA(LOCALE_USER_DEFAULT, DATE_LONGDATE | LOCALE_USE_CP_ACP, st, NULL, buff2, sizeof(buff2)); ok(ret == lstrlenA(buff2)+1, "got %d\n", ret); buff[lstrlenA(buff2)] = '\0'; ok(lstrcmpA(buff2, buff) == 0, "expected (%s) got (%s) for date part\n", @@ -1806,29 +1813,32 @@ if (0) flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTDATE | FDTF_SHORTTIME; ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); ok(ret == lstrlenA(buff)+1, "got %d\n", ret); - ret = GetDateFormatA(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)); + ret = GetDateFormatA(LOCALE_USER_DEFAULT, DATE_SHORTDATE | LOCALE_USE_CP_ACP, st, NULL, buff2, sizeof(buff2)); ok(ret == lstrlenA(buff2)+1, "got %d\n", ret); strcat(buff2, " "); - ret = GetTimeFormatA(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, buff3, sizeof(buff3)); + ret = GetTimeFormatA(LOCALE_USER_DEFAULT, TIME_NOSECONDS | LOCALE_USE_CP_ACP, st, NULL, buff3, sizeof(buff3)); ok(ret == lstrlenA(buff3)+1, "got %d\n", ret); strcat(buff2, buff3); - ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff); + ok(lstrcmpA(buff, buff2) == 0 || broken(!dstMatch) /* pre Windows 7 */, + "expected (%s), got (%s)\n", buff2, buff); flags = FDTF_NOAUTOREADINGORDER | FDTF_SHORTDATE | FDTF_LONGTIME; ret = pSHFormatDateTimeA(&filetime, &flags, buff, sizeof(buff)); ok(ret == lstrlenA(buff)+1, "got %d\n", ret); - ret = GetDateFormatA(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, buff2, sizeof(buff2)); + ret = GetDateFormatA(LOCALE_USER_DEFAULT, DATE_SHORTDATE | LOCALE_USE_CP_ACP, st, NULL, buff2, sizeof(buff2)); ok(ret == lstrlenA(buff2)+1, "got %d\n", ret); strcat(buff2, " "); - ret = GetTimeFormatA(LOCALE_USER_DEFAULT, 0, &st, NULL, buff3, sizeof(buff3)); + ret = GetTimeFormatA(LOCALE_USER_DEFAULT, LOCALE_USE_CP_ACP, st, NULL, buff3, sizeof(buff3)); ok(ret == lstrlenA(buff3)+1, "got %d\n", ret); strcat(buff2, buff3); - ok(lstrcmpA(buff, buff2) == 0, "expected (%s), got (%s)\n", buff2, buff); + ok(lstrcmpA(buff, buff2) == 0 || broken(!dstMatch) /* pre Windows 7 */, + "expected (%s), got (%s)\n", buff2, buff); } static void test_SHFormatDateTimeW(void) { - FILETIME UNALIGNED filetime; + FILETIME filetime; + SYSTEMTIME universalSystemTime; WCHAR buff[100], buff2[100], buff3[100], *p1, *p2; SYSTEMTIME st; DWORD flags; @@ -1844,21 +1854,21 @@ if (0) } GetLocalTime(&st); - SystemTimeToFileTime(&st, &filetime); /* SHFormatDateTime expects input as utc */ - LocalFileTimeToFileTime(&filetime, &filetime); + TzSpecificLocalTimeToSystemTime(NULL, &st, &universalSystemTime); + SystemTimeToFileTime(&universalSystemTime, &filetime); /* no way to get required buffer length here */ SetLastError(0xdeadbeef); ret = pSHFormatDateTimeW(&filetime, NULL, NULL, 0); ok(ret == 0, "expected 0, got %d\n", ret); - ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %ld\n", GetLastError()); SetLastError(0xdeadbeef); buff[0] = 'a'; buff[1] = 0; ret = pSHFormatDateTimeW(&filetime, NULL, buff, 0); ok(ret == 0, "expected 0, got %d\n", ret); - ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %ld\n", GetLastError()); ok(buff[0] == 'a', "expected same string\n"); /* all combinations documented as invalid succeeded */ @@ -1867,14 +1877,14 @@ if (0) ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff)); ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff), "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret); - ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %ld\n", GetLastError()); flags = FDTF_SHORTDATE | FDTF_LONGDATE; SetLastError(0xdeadbeef); ret = pSHFormatDateTimeW(&filetime, &flags, buff, ARRAY_SIZE(buff)); ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff), "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret); - ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %ld\n", GetLastError()); flags = FDTF_SHORTDATE | FDTF_LTRDATE | FDTF_RTLDATE; SetLastError(0xdeadbeef); @@ -1883,7 +1893,7 @@ if (0) ok(ret == lstrlenW(buff)+1 || ret == lstrlenW(buff), "expected %d or %d, got %d\n", lstrlenW(buff)+1, lstrlenW(buff), ret); ok(GetLastError() == 0xdeadbeef, - "expected 0xdeadbeef, got %d\n", GetLastError()); + "expected 0xdeadbeef, got %ld\n", GetLastError()); /* now check returned strings */ flags = FDTF_SHORTTIME; @@ -2046,7 +2056,7 @@ static void test_SHGetObjectCompatFlags(void) /* null args */ ret = pSHGetObjectCompatFlags(NULL, NULL); - ok(ret == 0, "got %d\n", ret); + ok(ret == 0, "got %ld\n", ret); ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, compat_path, &root); if (ret != ERROR_SUCCESS) @@ -2082,7 +2092,7 @@ static void test_SHGetObjectCompatFlags(void) pGUIDFromStringA(keyA, &clsid); got = pSHGetObjectCompatFlags(NULL, &clsid); - ok(got == expected, "got 0x%08x, expected 0x%08x. Key %s\n", got, expected, keyA); + ok(got == expected, "got 0x%08lx, expected 0x%08lx. Key %s\n", got, expected, keyA); RegCloseKey(clsid_key); } @@ -2306,7 +2316,7 @@ static void test_IUnknown_QueryServiceExec(void) hr = pIUnknown_QueryServiceExec(NULL, &dummy_serviceid, &dummy_groupid, 0, 0, 0, 0); ok(hr == E_FAIL || hr == E_NOTIMPL, /* win 8 */ - "got 0x%08x\n", hr); + "got 0x%08lx\n", hr); /* expected trace: IUnknown_QueryServiceExec( ptr1, serviceid, groupid, arg1, arg2, arg3, arg4); @@ -2322,7 +2332,7 @@ static void test_IUnknown_QueryServiceExec(void) init_call_trace(&trace_got); hr = pIUnknown_QueryServiceExec((IUnknown*)provider, &dummy_serviceid, &dummy_groupid, 0x1, 0x2, (void*)0x3, (void*)0x4); - ok(hr == S_OK, "got 0x%08x\n", hr); + ok(hr == S_OK, "got 0x%08lx\n", hr); ok_trace(&trace_expected, &trace_got); @@ -2416,7 +2426,7 @@ static void test_IUnknown_ProfferService(void) hr = pIUnknown_ProfferService(NULL, &dummy_serviceid, 0, 0); ok(hr == E_FAIL || hr == E_NOTIMPL, /* win 8 */ - "got 0x%08x\n", hr); + "got 0x%08lx\n", hr); /* expected trace: IUnknown_ProfferService( ptr1, serviceid, arg1, arg2); @@ -2437,8 +2447,8 @@ static void test_IUnknown_ProfferService(void) init_call_trace(&trace_got); cookie = 0; hr = pIUnknown_ProfferService((IUnknown*)proff, &dummy_serviceid, provider, &cookie); - ok(hr == S_OK, "got 0x%08x\n", hr); - ok(cookie == 0xdeadbeef, "got %x\n", cookie); + ok(hr == S_OK, "got 0x%08lx\n", hr); + ok(cookie == 0xdeadbeef, "got %lx\n", cookie); ok_trace(&trace_expected, &trace_got); free_call_trace(&trace_got); @@ -2452,10 +2462,10 @@ static void test_IUnknown_ProfferService(void) add_call(&trace_expected, 4, (void*)(DWORD_PTR)cookie, 0, 0, 0, 0); init_call_trace(&trace_got); - ok(cookie != 0, "got %x\n", cookie); + ok(cookie != 0, "got %lx\n", cookie); hr = pIUnknown_ProfferService((IUnknown*)proff, &dummy_serviceid, 0, &cookie); - ok(hr == S_OK, "got 0x%08x\n", hr); - ok(cookie == 0, "got %x\n", cookie); + ok(hr == S_OK, "got 0x%08lx\n", hr); + ok(cookie == 0, "got %lx\n", cookie); ok_trace(&trace_expected, &trace_got); free_call_trace(&trace_got); free_call_trace(&trace_expected); @@ -2479,7 +2489,7 @@ static void test_SHCreateWorkerWindowA(void) ok(lstrcmpA(classA, "WorkerA") == 0, "expected WorkerA class, got %s\n", classA); ret = GetWindowLongPtrA(hwnd, 0); - ok(ret == 0, "got %ld\n", ret); + ok(ret == 0, "got %Id\n", ret); /* class info */ memset(&cliA, 0, sizeof(cliA)); @@ -2500,19 +2510,19 @@ static void test_SHCreateWorkerWindowA(void) ok(lstrcmpA(classA, "WorkerA") == 0, "expected WorkerA class, got %s\n", classA); ret = GetWindowLongPtrA(hwnd, 0); - ok(ret == 0xdeadbeef, "got %ld\n", ret); + ok(ret == 0xdeadbeef, "got %Id\n", ret); /* test exstyle */ ret = GetWindowLongA(hwnd, GWL_EXSTYLE); ok(ret == WS_EX_WINDOWEDGE || - ret == (WS_EX_WINDOWEDGE|WS_EX_LAYOUTRTL) /* systems with RTL locale */, "0x%08lx\n", ret); + ret == (WS_EX_WINDOWEDGE|WS_EX_LAYOUTRTL) /* systems with RTL locale */, "0x%08Ix\n", ret); DestroyWindow(hwnd); hwnd = pSHCreateWorkerWindowA(0, NULL, WS_EX_TOOLWINDOW, 0, 0, 0); ret = GetWindowLongA(hwnd, GWL_EXSTYLE); ok(ret == (WS_EX_WINDOWEDGE|WS_EX_TOOLWINDOW) || - ret == (WS_EX_WINDOWEDGE|WS_EX_TOOLWINDOW|WS_EX_LAYOUTRTL) /* systems with RTL locale */, "0x%08lx\n", ret); + ret == (WS_EX_WINDOWEDGE|WS_EX_TOOLWINDOW|WS_EX_LAYOUTRTL) /* systems with RTL locale */, "0x%08Ix\n", ret); DestroyWindow(hwnd); } @@ -2579,22 +2589,14 @@ static HRESULT WINAPI SF_CreateViewObject(IShellFolder *iface, } static HRESULT WINAPI SF_GetAttributesOf(IShellFolder *iface, -#ifdef __REACTOS__ - UINT cidl, PCUITEMID_CHILD_ARRAY idl, SFGAOF *inOut) -#else UINT cidl, LPCITEMIDLIST *idl, SFGAOF *inOut) -#endif { ok(0, "Didn't expect GetAttributesOf\n"); return E_NOTIMPL; } static HRESULT WINAPI SF_GetUIObjectOf(IShellFolder *iface, -#ifdef __REACTOS__ - HWND owner, UINT cidl, PCUITEMID_CHILD_ARRAY idls, REFIID riid, UINT *inOut, -#else HWND owner, UINT cidl, LPCITEMIDLIST *idls, REFIID riid, UINT *inOut, -#endif void **out) { ok(0, "Didn't expect GetUIObjectOf\n"); @@ -2653,16 +2655,16 @@ static void test_SHIShellFolder_EnumObjects(void) /* SHIShellFolder_EnumObjects doesn't QI the object for IShellFolder */ enm = (IEnumIDList*)0xdeadbeef; hres = pSHIShellFolder_EnumObjects(&ShellFolder, NULL, 0, &enm); - ok(hres == S_OK, "SHIShellFolder_EnumObjects failed: 0x%08x\n", hres); + ok(hres == S_OK, "SHIShellFolder_EnumObjects failed: 0x%08lx\n", hres); ok(enm == (IEnumIDList*)0xcafebabe, "Didn't get expected enumerator location, instead: %p\n", enm); /* SHIShellFolder_EnumObjects isn't strict about the IShellFolder object */ hres = SHGetDesktopFolder(&folder); - ok(hres == S_OK, "SHGetDesktopFolder failed: 0x%08x\n", hres); + ok(hres == S_OK, "SHGetDesktopFolder failed: 0x%08lx\n", hres); enm = NULL; hres = pSHIShellFolder_EnumObjects(folder, NULL, 0, &enm); - ok(hres == S_OK, "SHIShellFolder_EnumObjects failed: 0x%08x\n", hres); + ok(hres == S_OK, "SHIShellFolder_EnumObjects failed: 0x%08lx\n", hres); ok(enm != NULL, "Didn't get an enumerator\n"); if(enm) IEnumIDList_Release(enm); @@ -2739,27 +2741,27 @@ static void test_SHGetIniString(void) } ret = pSHGetIniStringW(TestAppW, AKeyW, out, 0, pathW); - ok(ret == 0, "SHGetIniStringW should have given 0, instead: %d\n", ret); + ok(ret == 0, "SHGetIniStringW should have given 0, instead: %ld\n", ret); /* valid arguments */ out[0] = 0; SetLastError(0xdeadbeef); ret = pSHGetIniStringW(TestAppW, NULL, out, ARRAY_SIZE(out), pathW); - ok(ret == 4, "SHGetIniStringW should have given 4, instead: %d\n", ret); - ok(!lstrcmpW(out, AKeyW), "Expected %s, got: %s, %d\n", + ok(ret == 4, "SHGetIniStringW should have given 4, instead: %ld\n", ret); + ok(!lstrcmpW(out, AKeyW), "Expected %s, got: %s, %ld\n", wine_dbgstr_w(AKeyW), wine_dbgstr_w(out), GetLastError()); ret = pSHGetIniStringW(TestAppW, AKeyW, out, ARRAY_SIZE(out), pathW); - ok(ret == 1, "SHGetIniStringW should have given 1, instead: %d\n", ret); - ok(!strcmp_wa(out, "1"), "Expected L\"1\", got: %s\n", wine_dbgstr_w(out)); + ok(ret == 1, "SHGetIniStringW should have given 1, instead: %ld\n", ret); + ok(!lstrcmpW(out, L"1"), "Expected L\"1\", got: %s\n", wine_dbgstr_w(out)); ret = pSHGetIniStringW(TestAppW, AnotherKeyW, out, ARRAY_SIZE(out), pathW); - ok(ret == 4, "SHGetIniStringW should have given 4, instead: %d\n", ret); - ok(!strcmp_wa(out, "asdf"), "Expected L\"asdf\", got: %s\n", wine_dbgstr_w(out)); + ok(ret == 4, "SHGetIniStringW should have given 4, instead: %ld\n", ret); + ok(!lstrcmpW(out, L"asdf"), "Expected L\"asdf\", got: %s\n", wine_dbgstr_w(out)); out[0] = 1; ret = pSHGetIniStringW(TestAppW, JunkKeyW, out, ARRAY_SIZE(out), pathW); - ok(ret == 0, "SHGetIniStringW should have given 0, instead: %d\n", ret); + ok(ret == 0, "SHGetIniStringW should have given 0, instead: %ld\n", ret); ok(*out == 0, "Expected L\"\", got: %s\n", wine_dbgstr_w(out)); DeleteFileW(pathW); @@ -2799,7 +2801,6 @@ static void test_SHSetIniString(void) DeleteFileW(TestIniW); } -#ifndef __REACTOS__ enum _shellkey_flags { SHKEY_Root_HKCU = 0x1, SHKEY_Root_HKLM = 0x2, @@ -2815,7 +2816,6 @@ enum _shellkey_flags { SHKEY_Subkey_MUICache = 0x5000, SHKEY_Subkey_FileExts = 0x6000 }; -#endif static void test_SHGetShellKey(void) { @@ -2866,40 +2866,40 @@ static void test_SHGetShellKey(void) size = sizeof(data); hres = pSKGetValueW(SHKEY_Root_HKLM, WineTestW, NULL, NULL, &data, &size); - ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "hres = %x\n", hres); + ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "hres = %lx\n", hres); data = 1234; hres = pSKSetValueW(SHKEY_Root_HKLM, WineTestW, NULL, REG_DWORD, &data, sizeof(DWORD)); - ok(hres == S_OK, "hres = %x\n", hres); + ok(hres == S_OK, "hres = %lx\n", hres); size = 1; hres = pSKGetValueW(SHKEY_Root_HKLM, WineTestW, NULL, NULL, NULL, &size); - ok(hres == S_OK, "hres = %x\n", hres); - ok(size == sizeof(DWORD), "size = %d\n", size); + ok(hres == S_OK, "hres = %lx\n", hres); + ok(size == sizeof(DWORD), "size = %ld\n", size); data = 0xdeadbeef; hres = pSKGetValueW(SHKEY_Root_HKLM, WineTestW, NULL, NULL, &data, &size); - ok(hres == S_OK, "hres = %x\n", hres); - ok(size == sizeof(DWORD), "size = %d\n", size); - ok(data == 1234, "data = %d\n", data); + ok(hres == S_OK, "hres = %lx\n", hres); + ok(size == sizeof(DWORD), "size = %ld\n", size); + ok(data == 1234, "data = %ld\n", data); hres = pSKAllocValueW(SHKEY_Root_HKLM, WineTestW, NULL, NULL, (void**)&alloc_data, &size); - ok(hres == S_OK, "hres= %x\n", hres); - ok(size == sizeof(DWORD), "size = %d\n", size); + ok(hres == S_OK, "hres= %lx\n", hres); + ok(size == sizeof(DWORD), "size = %ld\n", size); if (SUCCEEDED(hres)) { - ok(*alloc_data == 1234, "*alloc_data = %d\n", *alloc_data); + ok(*alloc_data == 1234, "*alloc_data = %ld\n", *alloc_data); LocalFree(alloc_data); } hres = pSKDeleteValueW(SHKEY_Root_HKLM, WineTestW, NULL); - ok(hres == S_OK, "hres = %x\n", hres); + ok(hres == S_OK, "hres = %lx\n", hres); hres = pSKDeleteValueW(SHKEY_Root_HKLM, WineTestW, NULL); - ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "hres = %x\n", hres); + ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "hres = %lx\n", hres); hres = pSKGetValueW(SHKEY_Root_HKLM, WineTestW, NULL, NULL, &data, &size); - ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "hres = %x\n", hres); + ok(hres == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "hres = %lx\n", hres); hkey = pSHGetShellKey(SHKEY_Root_HKLM, NULL, FALSE); ok(hkey != NULL, "Can't create key\n"); @@ -2965,21 +2965,21 @@ static void test_SHSetParentHwnd(void) ret = GetParent(hwnd); ok(ret == NULL, "got %p\n", ret); style = GetWindowLongA(hwnd, GWL_STYLE); - ok((style & (WS_POPUP|WS_CHILD)) == 0, "got style 0x%08x\n", style); + ok((style & (WS_POPUP|WS_CHILD)) == 0, "got style 0x%08lx\n", style); ret = pSHSetParentHwnd(hwnd, NULL); ok(ret == NULL, "got %p\n", ret); style = GetWindowLongA(hwnd, GWL_STYLE); - ok((style & (WS_POPUP|WS_CHILD)) == 0, "got style 0x%08x\n", style); + ok((style & (WS_POPUP|WS_CHILD)) == 0, "got style 0x%08lx\n", style); /* reset to null parent from not null */ ret = GetParent(hwnd2); ok(ret == hwnd, "got %p\n", ret); style = GetWindowLongA(hwnd2, GWL_STYLE); - ok((style & (WS_POPUP|WS_CHILD)) == WS_CHILD, "got style 0x%08x\n", style); + ok((style & (WS_POPUP|WS_CHILD)) == WS_CHILD, "got style 0x%08lx\n", style); ret = pSHSetParentHwnd(hwnd2, NULL); ok(ret == NULL, "got %p\n", ret); style = GetWindowLongA(hwnd2, GWL_STYLE); - ok((style & (WS_POPUP|WS_CHILD)) == WS_POPUP, "got style 0x%08x\n", style); + ok((style & (WS_POPUP|WS_CHILD)) == WS_POPUP, "got style 0x%08lx\n", style); ret = GetParent(hwnd2); ok(ret == NULL, "got %p\n", ret); @@ -2987,13 +2987,13 @@ static void test_SHSetParentHwnd(void) style = GetWindowLongA(hwnd2, GWL_STYLE); SetWindowLongA(hwnd2, GWL_STYLE, style & ~(WS_CHILD|WS_POPUP)); style = GetWindowLongA(hwnd2, GWL_STYLE); - ok((style & (WS_CHILD|WS_POPUP)) == 0, "got 0x%08x\n", style); + ok((style & (WS_CHILD|WS_POPUP)) == 0, "got 0x%08lx\n", style); ret = pSHSetParentHwnd(hwnd2, hwnd); todo_wine ok(ret == NULL, "got %p\n", ret); style = GetWindowLongA(hwnd2, GWL_STYLE); - ok((style & (WS_POPUP|WS_CHILD)) == WS_CHILD, "got style 0x%08x\n", style); + ok((style & (WS_POPUP|WS_CHILD)) == WS_CHILD, "got style 0x%08lx\n", style); ret = GetParent(hwnd2); ok(ret == hwnd, "got %p\n", ret); @@ -3004,7 +3004,7 @@ static void test_SHSetParentHwnd(void) ret = pSHSetParentHwnd(hwnd2, hwnd); todo_wine ok(ret == NULL, "got %p\n", ret); style = GetWindowLongA(hwnd2, GWL_STYLE); - ok((style & (WS_CHILD|WS_POPUP)) == WS_CHILD, "got 0x%08x\n", style); + ok((style & (WS_CHILD|WS_POPUP)) == WS_CHILD, "got 0x%08lx\n", style); ret = GetParent(hwnd2); ok(ret == hwnd, "got %p\n", ret); @@ -3014,7 +3014,7 @@ static void test_SHSetParentHwnd(void) ret = pSHSetParentHwnd(hwnd2, hwnd); todo_wine ok(ret == hwnd, "got %p\n", ret); style = GetWindowLongA(hwnd2, GWL_STYLE); - ok((style & (WS_CHILD|WS_POPUP)) == WS_CHILD, "got 0x%08x\n", style); + ok((style & (WS_CHILD|WS_POPUP)) == WS_CHILD, "got 0x%08lx\n", style); ret = GetParent(hwnd2); ok(ret == hwnd, "got %p\n", ret); @@ -3090,14 +3090,14 @@ static void test_IUnknown_GetClassID(void) memset(&clsid, 0xcc, sizeof(clsid)); memset(&clsid3, 0xcc, sizeof(clsid3)); hr = pIUnknown_GetClassID(NULL, &clsid); - ok(hr == E_FAIL, "got 0x%08x\n", hr); + ok(hr == E_FAIL, "got 0x%08lx\n", hr); ok(IsEqualCLSID(&clsid, &CLSID_NULL) || broken(IsEqualCLSID(&clsid, &clsid3)) /* win2k, winxp, win2k3 */, "got wrong clsid %s\n", wine_dbgstr_guid(&clsid)); memset(&clsid, 0xcc, sizeof(clsid)); memset(&clsid2, 0xab, sizeof(clsid2)); hr = pIUnknown_GetClassID((IUnknown*)&testpersist, &clsid); - ok(hr == 0x8fff2222, "got 0x%08x\n", hr); + ok(hr == 0x8fff2222, "got 0x%08lx\n", hr); ok(IsEqualCLSID(&clsid, &clsid2) || broken(IsEqualCLSID(&clsid, &clsid3)) /* win2k3 */, "got wrong clsid %s\n", wine_dbgstr_guid(&clsid)); @@ -3106,7 +3106,7 @@ static void test_IUnknown_GetClassID(void) memset(&clsid2, 0xab, sizeof(clsid2)); memset(&clsid3, 0xcc, sizeof(clsid3)); hr = pIUnknown_GetClassID((IUnknown*)&testpersist2, &clsid); - ok(hr == 0x8fff2222, "got 0x%08x\n", hr); + ok(hr == 0x8fff2222, "got 0x%08lx\n", hr); ok(IsEqualCLSID(&clsid, &clsid2) || broken(IsEqualCLSID(&clsid, &clsid3)) /* win2k3 */, "got wrong clsid %s\n", wine_dbgstr_guid(&clsid)); } @@ -3116,11 +3116,13 @@ static void test_DllGetVersion(void) HRESULT hr; hr = pDllGetVersion(NULL); - ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + ok(hr == E_INVALIDARG, "got 0x%08lx\n", hr); } START_TEST(ordinal) { + SYSTEMTIME st; + static const SYSTEMTIME february = {2023, 2, 2, 14, 12, 0, 0, 0}; char **argv; int argc; @@ -3133,7 +3135,7 @@ START_TEST(ordinal) { DWORD procid; HANDLE hmem; - sscanf(argv[2], "%d", &procid); + sscanf(argv[2], "%ld", &procid); sscanf(argv[3], "%p", &hmem); test_alloc_shared_remote(procid, hmem); return; @@ -3148,7 +3150,15 @@ START_TEST(ordinal) test_IConnectionPoint(); test_SHPropertyBag_ReadLONG(); test_SHSetWindowBits(); - test_SHFormatDateTimeA(); + + GetLocalTime(&st); + test_SHFormatDateTimeA(&st); + /* Test how the locale and code page interact for date formatting by + * repeating the tests with a February date which in French contains an + * e-acute that can only be represented in some code pages. + */ + test_SHFormatDateTimeA(&february); + test_SHFormatDateTimeW(); test_SHGetObjectCompatFlags(); test_IUnknown_QueryServiceExec(); diff --git a/modules/rostests/winetests/shlwapi/path.c b/modules/rostests/winetests/shlwapi/path.c index e9f08a902b0..fb8d3f1b9c1 100644 --- a/modules/rostests/winetests/shlwapi/path.c +++ b/modules/rostests/winetests/shlwapi/path.c @@ -190,27 +190,13 @@ static LPWSTR GetWideString(const char *src) if (!src) return NULL; - ret = HeapAlloc(GetProcessHeap(), 0, (2*INTERNET_MAX_URL_LENGTH) * sizeof(WCHAR)); + ret = malloc(2 * INTERNET_MAX_URL_LENGTH * sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, src, -1, ret, INTERNET_MAX_URL_LENGTH); return ret; } -static void FreeWideString(LPWSTR wszString) -{ - HeapFree(GetProcessHeap(), 0, wszString); -} - -static LPSTR strdupA(LPCSTR p) -{ - LPSTR ret; - DWORD len = (strlen(p) + 1); - ret = HeapAlloc(GetProcessHeap(), 0, len); - memcpy(ret, p, len); - return ret; -} - /* ################ */ static void test_PathSearchAndQualify(void) @@ -279,19 +265,19 @@ static void test_PathCreateFromUrl(void) /* Won't say how much is needed without a buffer */ len = 0xdeca; ret = pPathCreateFromUrlA("file://foo", NULL, &len, 0); - ok(ret == E_INVALIDARG, "got 0x%08x expected E_INVALIDARG\n", ret); - ok(len == 0xdeca, "got %x expected 0xdeca\n", len); + ok(ret == E_INVALIDARG, "got 0x%08lx expected E_INVALIDARG\n", ret); + ok(len == 0xdeca, "got %lx expected 0xdeca\n", len); /* Test the decoding itself */ for (i = 0; i < ARRAY_SIZE(TEST_PATHFROMURL); i++) { len = INTERNET_MAX_URL_LENGTH; ret = pPathCreateFromUrlA(TEST_PATHFROMURL[i].url, ret_path, &len, 0); todo_wine_if (TEST_PATHFROMURL[i].todo & 0x1) - ok(ret == TEST_PATHFROMURL[i].ret, "ret %08x from url %s\n", ret, TEST_PATHFROMURL[i].url); + ok(ret == TEST_PATHFROMURL[i].ret, "ret %08lx from url %s\n", ret, TEST_PATHFROMURL[i].url); if(SUCCEEDED(ret) && TEST_PATHFROMURL[i].path) { if(!(TEST_PATHFROMURL[i].todo & 0x2)) { ok(!lstrcmpiA(ret_path, TEST_PATHFROMURL[i].path), "got %s expected %s from url %s\n", ret_path, TEST_PATHFROMURL[i].path, TEST_PATHFROMURL[i].url); - ok(len == strlen(ret_path), "ret len %d from url %s\n", len, TEST_PATHFROMURL[i].url); + ok(len == strlen(ret_path), "ret len %ld from url %s\n", len, TEST_PATHFROMURL[i].url); } else todo_wine /* Wrong string, don't bother checking the length */ ok(!lstrcmpiA(ret_path, TEST_PATHFROMURL[i].path), "got %s expected %s from url %s\n", ret_path, TEST_PATHFROMURL[i].path, TEST_PATHFROMURL[i].url); @@ -304,12 +290,12 @@ static void test_PathCreateFromUrl(void) ret = pPathCreateFromUrlW(urlW, ret_pathW, &len, 0); WideCharToMultiByte(CP_ACP, 0, ret_pathW, -1, ret_path, sizeof(ret_path),NULL,NULL); todo_wine_if (TEST_PATHFROMURL[i].todo & 0x1) - ok(ret == TEST_PATHFROMURL[i].ret, "ret %08x from url L\"%s\"\n", ret, TEST_PATHFROMURL[i].url); + ok(ret == TEST_PATHFROMURL[i].ret, "ret %08lx from url L\"%s\"\n", ret, TEST_PATHFROMURL[i].url); if(SUCCEEDED(ret) && TEST_PATHFROMURL[i].path) { if(!(TEST_PATHFROMURL[i].todo & 0x2)) { ok(!lstrcmpiW(ret_pathW, pathW), "got %s expected %s from url L\"%s\"\n", ret_path, TEST_PATHFROMURL[i].path, TEST_PATHFROMURL[i].url); - ok(len == lstrlenW(ret_pathW), "ret len %d from url L\"%s\"\n", len, TEST_PATHFROMURL[i].url); + ok(len == lstrlenW(ret_pathW), "ret len %ld from url L\"%s\"\n", len, TEST_PATHFROMURL[i].url); } else todo_wine /* Wrong string, don't bother checking the length */ ok(!lstrcmpiW(ret_pathW, pathW), "got %s expected %s from url L\"%s\"\n", @@ -321,13 +307,13 @@ static void test_PathCreateFromUrl(void) /* Check what happens if the buffer is too small */ len2 = 2; ret = pPathCreateFromUrlW(urlW, ret_pathW, &len2, 0); - ok(ret == E_POINTER, "ret %08x, expected E_POINTER from url %s\n", ret, TEST_PATHFROMURL[i].url); + ok(ret == E_POINTER, "ret %08lx, expected E_POINTER from url %s\n", ret, TEST_PATHFROMURL[i].url); todo_wine_if (TEST_PATHFROMURL[i].todo & 0x4) - ok(len2 == len + 1, "got len = %d expected %d from url %s\n", len2, len + 1, TEST_PATHFROMURL[i].url); + ok(len2 == len + 1, "got len = %ld expected %ld from url %s\n", len2, len + 1, TEST_PATHFROMURL[i].url); } - FreeWideString(urlW); - FreeWideString(pathW); + free(urlW); + free(pathW); } } @@ -338,9 +324,9 @@ static void test_PathCreateFromUrl(void) pathW = NULL; ret = pPathCreateFromUrlAlloc(fileW, &pathW, 0); - ok(ret == S_OK, "got 0x%08x expected S_OK\n", ret); + ok(ret == S_OK, "got 0x%08lx expected S_OK\n", ret); ok(lstrcmpiW(pathW, fooW) == 0, "got %s expected %s\n", wine_dbgstr_w(pathW), wine_dbgstr_w(fooW)); - HeapFree(GetProcessHeap(), 0, pathW); + LocalFree(pathW); } } @@ -513,7 +499,7 @@ static void test_PathCombineW(void) return; } - wszString2 = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR)); + wszString2 = malloc(MAX_PATH * sizeof(WCHAR)); /* NULL test */ wszString = pPathCombineW(NULL, NULL, NULL); @@ -529,7 +515,7 @@ static void test_PathCombineW(void) broken(wszString2[0] == 'a'), /* Win95 and some W2K */ "Destination string not empty\n"); - HeapFree(GetProcessHeap(), 0, wszString2); + free(wszString2); /* overflow test */ wstr2[0] = wstr2[1] = wstr2[2] = 'A'; @@ -566,19 +552,19 @@ static void test_PathCombineA(void) SetLastError(0xdeadbeef); str = PathCombineA(NULL, "C:\\", "one\\two\\three"); ok(str == NULL, "Expected NULL, got %p\n", str); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try NULL dest and NULL directory */ SetLastError(0xdeadbeef); str = PathCombineA(NULL, NULL, "one\\two\\three"); ok(str == NULL, "Expected NULL, got %p\n", str); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try all NULL*/ SetLastError(0xdeadbeef); str = PathCombineA(NULL, NULL, NULL); ok(str == NULL, "Expected NULL, got %p\n", str); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try NULL file part */ SetLastError(0xdeadbeef); @@ -586,7 +572,7 @@ static void test_PathCombineA(void) str = PathCombineA(dest, "C:\\", NULL); ok(str == dest, "Expected str == dest, got %p\n", str); ok(!lstrcmpA(str, "C:\\"), "Expected C:\\, got %s\n", str); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try empty file part */ SetLastError(0xdeadbeef); @@ -594,7 +580,7 @@ static void test_PathCombineA(void) str = PathCombineA(dest, "C:\\", ""); ok(str == dest, "Expected str == dest, got %p\n", str); ok(!lstrcmpA(str, "C:\\"), "Expected C:\\, got %s\n", str); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try empty directory and file part */ SetLastError(0xdeadbeef); @@ -604,7 +590,7 @@ static void test_PathCombineA(void) ok(!lstrcmpA(str, "\\") || broken(!lstrcmpA(str, "control")), /* Win95 and some W2K */ "Expected \\, got %s\n", str); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try NULL directory */ SetLastError(0xdeadbeef); @@ -612,7 +598,7 @@ static void test_PathCombineA(void) str = PathCombineA(dest, NULL, "one\\two\\three"); ok(str == dest, "Expected str == dest, got %p\n", str); ok(!lstrcmpA(str, "one\\two\\three"), "Expected one\\two\\three, got %s\n", str); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try NULL directory and empty file part */ SetLastError(0xdeadbeef); @@ -624,7 +610,7 @@ static void test_PathCombineA(void) "Expected \\, got %s\n", str); ok(GetLastError() == 0xdeadbeef || broken(GetLastError() == ERROR_INVALID_PARAMETER), /* Win95 */ - "Expected 0xdeadbeef, got %d\n", GetLastError()); + "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try NULL directory and file part */ SetLastError(0xdeadbeef); @@ -635,7 +621,7 @@ static void test_PathCombineA(void) "Expected str == NULL, got %p\n", str); ok(!dest[0] || broken(!lstrcmpA(dest, "control")), /* Win95 and some W2K */ "Expected 0 length, got %i\n", lstrlenA(dest)); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try directory without backslash */ SetLastError(0xdeadbeef); @@ -643,7 +629,7 @@ static void test_PathCombineA(void) str = PathCombineA(dest, "C:", "one\\two\\three"); ok(str == dest, "Expected str == dest, got %p\n", str); ok(!lstrcmpA(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try directory with backslash */ SetLastError(0xdeadbeef); @@ -651,7 +637,7 @@ static void test_PathCombineA(void) str = PathCombineA(dest, "C:\\", "one\\two\\three"); ok(str == dest, "Expected str == dest, got %p\n", str); ok(!lstrcmpA(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try directory with backslash and file with prepended backslash */ SetLastError(0xdeadbeef); @@ -659,7 +645,7 @@ static void test_PathCombineA(void) str = PathCombineA(dest, "C:\\", "\\one\\two\\three"); ok(str == dest, "Expected str == dest, got %p\n", str); ok(!lstrcmpA(str, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", str); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try previous test, with backslash appended as well */ SetLastError(0xdeadbeef); @@ -667,13 +653,13 @@ static void test_PathCombineA(void) str = PathCombineA(dest, "C:\\", "\\one\\two\\three\\"); ok(str == dest, "Expected str == dest, got %p\n", str); ok(!lstrcmpA(str, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try a relative directory */ SetLastError(0xdeadbeef); lstrcpyA(dest, "control"); str = PathCombineA(dest, "relative\\dir", "\\one\\two\\three\\"); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* Vista fails which probably makes sense as PathCombineA expects an absolute dir */ if (str) { @@ -687,7 +673,7 @@ static void test_PathCombineA(void) str = PathCombineA(dest, "C:\\", "one/two/three\\"); ok(str == dest, "Expected str == dest, got %p\n", str); ok(!lstrcmpA(str, "C:\\one/two/three\\"), "Expected one/two/three\\, got %s\n", str); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try a really weird directory */ SetLastError(0xdeadbeef); @@ -695,7 +681,7 @@ static void test_PathCombineA(void) str = PathCombineA(dest, "C:\\/\\/", "\\one\\two\\three\\"); ok(str == dest, "Expected str == dest, got %p\n", str); ok(!lstrcmpA(str, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", str); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try periods */ SetLastError(0xdeadbeef); @@ -703,7 +689,7 @@ static void test_PathCombineA(void) str = PathCombineA(dest, "C:\\", "one\\..\\two\\.\\three"); ok(str == dest, "Expected str == dest, got %p\n", str); ok(!lstrcmpA(str, "C:\\two\\three"), "Expected C:\\two\\three, got %s\n", str); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try .. as file */ /* try forward slashes */ @@ -712,7 +698,16 @@ static void test_PathCombineA(void) str = PathCombineA(dest, "C:\\", ".."); ok(str == dest, "Expected str == dest, got %p\n", str); ok(!lstrcmpA(str, "C:\\"), "Expected C:\\, got %s\n", str); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); + + /* try relative paths */ + /* try forward slashes */ + SetLastError(0xdeadbeef); + lstrcpyA(dest, "control"); + str = PathCombineA(dest, "../../../one/two/", "*"); + ok(str == dest, "Expected str == dest, got %p\n", str); + ok(!lstrcmpA(str, "../../../one/two/\\*"), "Expected ../../../one/two/\\*, got %s\n", str); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); memset(too_long, 'a', LONG_LEN); too_long[LONG_LEN - 1] = '\0'; @@ -724,7 +719,7 @@ static void test_PathCombineA(void) ok(str == NULL, "Expected str == NULL, got %p\n", str); ok(!dest[0] || broken(!lstrcmpA(dest, "control")), /* Win95 and some W2K */ "Expected 0 length, got %i\n", lstrlenA(dest)); - todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try a directory longer than MAX_PATH */ SetLastError(0xdeadbeef); @@ -733,7 +728,7 @@ static void test_PathCombineA(void) ok(str == NULL, "Expected str == NULL, got %p\n", str); ok(!dest[0] || broken(!lstrcmpA(dest, "control")), /* Win95 and some W2K */ "Expected 0 length, got %i\n", lstrlenA(dest)); - todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); memset(one, 'b', HALF_LEN); memset(two, 'c', HALF_LEN); @@ -747,7 +742,7 @@ static void test_PathCombineA(void) ok(str == NULL, "Expected str == NULL, got %p\n", str); ok(!dest[0] || broken(!lstrcmpA(dest, "control")), /* Win95 and some W2K */ "Expected 0 length, got %i\n", lstrlenA(dest)); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); } static void test_PathAddBackslash(void) @@ -760,7 +755,7 @@ static void test_PathAddBackslash(void) SetLastError(0xdeadbeef); str = PathAddBackslashA(NULL); ok(str == NULL, "Expected str == NULL, got %p\n", str); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try an empty path */ path[0] = '\0'; @@ -768,7 +763,7 @@ static void test_PathAddBackslash(void) str = PathAddBackslashA(path); ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str); ok(!path[0], "Expected empty string, got %i\n", lstrlenA(path)); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try a relative path */ lstrcpyA(path, "one\\two"); @@ -776,7 +771,7 @@ static void test_PathAddBackslash(void) str = PathAddBackslashA(path); ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str); ok(!lstrcmpA(path, "one\\two\\"), "Expected one\\two\\, got %s\n", path); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try periods */ lstrcpyA(path, "one\\..\\two"); @@ -784,7 +779,7 @@ static void test_PathAddBackslash(void) str = PathAddBackslashA(path); ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str); ok(!lstrcmpA(path, "one\\..\\two\\"), "Expected one\\..\\two\\, got %s\n", path); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try just a space */ lstrcpyA(path, " "); @@ -792,7 +787,7 @@ static void test_PathAddBackslash(void) str = PathAddBackslashA(path); ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str); ok(!lstrcmpA(path, " \\"), "Expected \\, got %s\n", path); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* path already has backslash */ lstrcpyA(path, "C:\\one\\"); @@ -800,7 +795,7 @@ static void test_PathAddBackslash(void) str = PathAddBackslashA(path); ok(str == (path + lstrlenA(path)), "Expected str to point to end of path, got %p\n", str); ok(!lstrcmpA(path, "C:\\one\\"), "Expected C:\\one\\, got %s\n", path); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); memset(too_long, 'a', LONG_LEN); too_long[LONG_LEN - 1] = '\0'; @@ -809,7 +804,7 @@ static void test_PathAddBackslash(void) SetLastError(0xdeadbeef); str = PathAddBackslashA(too_long); ok(str == NULL, "Expected str == NULL, got %p\n", str); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); } static void test_PathAppendA(void) @@ -825,28 +820,28 @@ static void test_PathAppendA(void) SetLastError(0xdeadbeef); res = PathAppendA(path, NULL); ok(!res, "Expected failure\n"); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!lstrcmpA(path, "C:\\one"), "Expected C:\\one, got %s\n", path); /* try empty pszMore */ SetLastError(0xdeadbeef); res = PathAppendA(path, ""); ok(res, "Expected success\n"); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!lstrcmpA(path, "C:\\one"), "Expected C:\\one, got %s\n", path); /* try NULL pszPath */ SetLastError(0xdeadbeef); res = PathAppendA(NULL, "two\\three"); ok(!res, "Expected failure\n"); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try empty pszPath */ path[0] = '\0'; SetLastError(0xdeadbeef); res = PathAppendA(path, "two\\three"); ok(res, "Expected success\n"); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!lstrcmpA(path, "two\\three"), "Expected \\two\\three, got %s\n", path); /* try empty pszPath and empty pszMore */ @@ -854,7 +849,7 @@ static void test_PathAppendA(void) SetLastError(0xdeadbeef); res = PathAppendA(path, ""); ok(res, "Expected success\n"); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!lstrcmpA(path, "\\"), "Expected \\, got %s\n", path); /* try legit params */ @@ -862,7 +857,7 @@ static void test_PathAppendA(void) SetLastError(0xdeadbeef); res = PathAppendA(path, "two\\three"); ok(res, "Expected success\n"); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!lstrcmpA(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path); /* try pszPath with backslash after it */ @@ -870,7 +865,7 @@ static void test_PathAppendA(void) SetLastError(0xdeadbeef); res = PathAppendA(path, "two\\three"); ok(res, "Expected success\n"); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!lstrcmpA(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path); /* try pszMore with backslash before it */ @@ -878,7 +873,7 @@ static void test_PathAppendA(void) SetLastError(0xdeadbeef); res = PathAppendA(path, "\\two\\three"); ok(res, "Expected success\n"); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!lstrcmpA(path, "C:\\one\\two\\three"), "Expected C:\\one\\two\\three, got %s\n", path); /* try pszMore with backslash after it */ @@ -886,7 +881,7 @@ static void test_PathAppendA(void) SetLastError(0xdeadbeef); res = PathAppendA(path, "two\\three\\"); ok(res, "Expected success\n"); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!lstrcmpA(path, "C:\\one\\two\\three\\"), "Expected C:\\one\\two\\three\\, got %s\n", path); /* try spaces in pszPath */ @@ -894,7 +889,7 @@ static void test_PathAppendA(void) SetLastError(0xdeadbeef); res = PathAppendA(path, "two\\three"); ok(res, "Expected success\n"); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!lstrcmpA(path, "C: \\ one \\two\\three"), "Expected C: \\ one \\two\\three, got %s\n", path); /* try spaces in pszMore */ @@ -902,7 +897,7 @@ static void test_PathAppendA(void) SetLastError(0xdeadbeef); res = PathAppendA(path, " two \\ three "); ok(res, "Expected success\n"); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!lstrcmpA(path, "C:\\one\\ two \\ three "), "Expected 'C:\\one\\ two \\ three ', got %s\n", path); /* pszPath is too long */ @@ -911,7 +906,7 @@ static void test_PathAppendA(void) SetLastError(0xdeadbeef); res = PathAppendA(too_long, "two\\three"); ok(!res, "Expected failure\n"); - todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!too_long[0] || broken(lstrlenA(too_long) == (LONG_LEN - 1)), /* Win95 and some W2K */ "Expected length of too_long to be zero, got %i\n", lstrlenA(too_long)); @@ -922,7 +917,7 @@ static void test_PathAppendA(void) SetLastError(0xdeadbeef); res = PathAppendA(path, too_long); ok(!res, "Expected failure\n"); - todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + todo_wine ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!path[0] || broken(!lstrcmpA(path, "C:\\one")), /* Win95 and some W2K */ "Expected length of path to be zero, got %i\n", lstrlenA(path)); @@ -936,7 +931,7 @@ static void test_PathAppendA(void) ok(!res, "Expected failure\n"); ok(!path[0] || broken(lstrlenA(path) == (HALF_LEN - 1)), /* Win95 and some W2K */ "Expected length of path to be zero, got %i\n", lstrlenA(path)); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); } static void test_PathCanonicalizeA(void) @@ -951,7 +946,7 @@ static void test_PathCanonicalizeA(void) res = PathCanonicalizeA(dest, NULL); ok(!res, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); ok(dest[0] == 0 || !lstrcmpA(dest, "test"), "Expected either an empty string (Vista) or test, got %s\n", dest); @@ -960,7 +955,7 @@ static void test_PathCanonicalizeA(void) SetLastError(0xdeadbeef); res = PathCanonicalizeA(dest, ""); ok(res, "Expected success\n"); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!lstrcmpA(dest, "\\") || broken(!lstrcmpA(dest, "test")), /* Win95 and some W2K */ "Expected \\, got %s\n", dest); @@ -970,14 +965,14 @@ static void test_PathCanonicalizeA(void) res = PathCanonicalizeA(NULL, "C:\\"); ok(!res, "Expected failure\n"); ok(GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); /* try empty dest */ dest[0] = '\0'; SetLastError(0xdeadbeef); res = PathCanonicalizeA(dest, "C:\\"); ok(res, "Expected success\n"); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!lstrcmpA(dest, "C:\\"), "Expected C:\\, got %s\n", dest); /* try non-empty dest */ @@ -985,7 +980,7 @@ static void test_PathCanonicalizeA(void) SetLastError(0xdeadbeef); res = PathCanonicalizeA(dest, "C:\\"); ok(res, "Expected success\n"); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!lstrcmpA(dest, "C:\\"), "Expected C:\\, got %s\n", dest); /* try a space for source */ @@ -993,7 +988,7 @@ static void test_PathCanonicalizeA(void) SetLastError(0xdeadbeef); res = PathCanonicalizeA(dest, " "); ok(res, "Expected success\n"); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!lstrcmpA(dest, " "), "Expected ' ', got %s\n", dest); /* try a relative path */ @@ -1001,7 +996,7 @@ static void test_PathCanonicalizeA(void) SetLastError(0xdeadbeef); res = PathCanonicalizeA(dest, "one\\two"); ok(res, "Expected success\n"); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!lstrcmpA(dest, "one\\two"), "Expected one\\two, got %s\n", dest); /* try current dir and previous dir */ @@ -1009,7 +1004,7 @@ static void test_PathCanonicalizeA(void) SetLastError(0xdeadbeef); res = PathCanonicalizeA(dest, "C:\\one\\.\\..\\two\\three\\.."); ok(res, "Expected success\n"); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!lstrcmpA(dest, "C:\\two"), "Expected C:\\two, got %s\n", dest); /* try simple forward slashes */ @@ -1017,7 +1012,7 @@ static void test_PathCanonicalizeA(void) SetLastError(0xdeadbeef); res = PathCanonicalizeA(dest, "C:\\one/two/three\\four/five\\six"); ok(res, "Expected success\n"); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!lstrcmpA(dest, "C:\\one/two/three\\four/five\\six"), "Expected C:\\one/two/three\\four/five\\six, got %s\n", dest); @@ -1026,7 +1021,7 @@ static void test_PathCanonicalizeA(void) SetLastError(0xdeadbeef); res = PathCanonicalizeA(dest, "C:\\one/.\\two"); ok(res, "Expected success\n"); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!lstrcmpA(dest, "C:\\one/.\\two"), "Expected C:\\one/.\\two, got %s\n", dest); /* try simple forward slashes with change dir */ @@ -1034,11 +1029,27 @@ static void test_PathCanonicalizeA(void) SetLastError(0xdeadbeef); res = PathCanonicalizeA(dest, "C:\\one/.\\two\\.."); ok(res, "Expected success\n"); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!lstrcmpA(dest, "C:\\one/.") || !lstrcmpA(dest, "C:\\one/"), /* Vista */ "Expected \"C:\\one/.\" or \"C:\\one/\", got \"%s\"\n", dest); + /* try relative forward slashes */ + lstrcpyA(dest, "test"); + SetLastError(0xdeadbeef); + res = PathCanonicalizeA(dest, "../../one/two/"); + ok(res, "Expected success\n"); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); + ok(!lstrcmpA(dest, "../../one/two/"), "Expected ../../one/two/, got %s\n", dest); + + /* try relative forward slashes */ + lstrcpyA(dest, "test"); + SetLastError(0xdeadbeef); + res = PathCanonicalizeA(dest, "../../one/two/\\*"); + ok(res, "Expected success\n"); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); + ok(!lstrcmpA(dest, "../../one/two/\\*"), "Expected ../../one/two/\\*, got %s\n", dest); + /* try forward slashes with change dirs * NOTE: if there is a forward slash in between two backslashes, * everything in between the two backslashes is considered on dir @@ -1047,7 +1058,7 @@ static void test_PathCanonicalizeA(void) SetLastError(0xdeadbeef); res = PathCanonicalizeA(dest, "C:\\one/.\\..\\two/three\\..\\four/.five"); ok(res, "Expected success\n"); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); ok(!lstrcmpA(dest, "C:\\four/.five"), "Expected C:\\four/.five, got %s\n", dest); /* try src is too long */ @@ -1062,7 +1073,7 @@ static void test_PathCanonicalizeA(void) todo_wine { ok(GetLastError() == 0xdeadbeef || GetLastError() == ERROR_FILENAME_EXCED_RANGE /* Vista */, - "Expected 0xdeadbeef or ERROR_FILENAME_EXCED_RANGE, got %d\n", GetLastError()); + "Expected 0xdeadbeef or ERROR_FILENAME_EXCED_RANGE, got %ld\n", GetLastError()); } ok(lstrlenA(too_long) == LONG_LEN - 1, "Expected length LONG_LEN - 1, got %i\n", lstrlenA(too_long)); } @@ -1077,7 +1088,7 @@ static void test_PathFindExtensionA(void) SetLastError(0xdeadbeef); ext = PathFindExtensionA(NULL); ok(ext == NULL, "Expected NULL, got %p\n", ext); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try an empty path */ path[0] = '\0'; @@ -1085,7 +1096,7 @@ static void test_PathFindExtensionA(void) ext = PathFindExtensionA(path); ok(ext == path, "Expected ext == path, got %p\n", ext); ok(!ext[0], "Expected length 0, got %i\n", lstrlenA(ext)); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try a path without an extension */ lstrcpyA(path, "file"); @@ -1093,7 +1104,7 @@ static void test_PathFindExtensionA(void) ext = PathFindExtensionA(path); ok(ext == path + lstrlenA(path), "Expected ext == path, got %p\n", ext); ok(!ext[0], "Expected length 0, got %i\n", lstrlenA(ext)); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try a path with an extension */ lstrcpyA(path, "file.txt"); @@ -1102,7 +1113,7 @@ static void test_PathFindExtensionA(void) ok(ext == path + lstrlenA("file"), "Expected ext == path + lstrlenA(\"file\"), got %p\n", ext); ok(!lstrcmpA(ext, ".txt"), "Expected .txt, got %s\n", ext); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try a path with two extensions */ lstrcpyA(path, "file.txt.doc"); @@ -1111,7 +1122,7 @@ static void test_PathFindExtensionA(void) ok(ext == path + lstrlenA("file.txt"), "Expected ext == path + lstrlenA(\"file.txt\"), got %p\n", ext); ok(!lstrcmpA(ext, ".doc"), "Expected .txt, got %s\n", ext); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try a path longer than MAX_PATH without an extension*/ memset(too_long, 'a', LONG_LEN); @@ -1119,7 +1130,7 @@ static void test_PathFindExtensionA(void) SetLastError(0xdeadbeef); ext = PathFindExtensionA(too_long); ok(ext == too_long + LONG_LEN - 1, "Expected ext == too_long + LONG_LEN - 1, got %p\n", ext); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try a path longer than MAX_PATH with an extension*/ memset(too_long, 'a', LONG_LEN); @@ -1130,7 +1141,7 @@ static void test_PathFindExtensionA(void) ext = PathFindExtensionA(too_long); ok(ext == too_long + 300, "Expected ext == too_long + 300, got %p\n", ext); ok(lstrlenA(ext) == LONG_LEN - 301, "Expected LONG_LEN - 301, got %i\n", lstrlenA(ext)); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); } static void test_PathBuildRootA(void) @@ -1153,7 +1164,7 @@ static void test_PathBuildRootA(void) root = PathBuildRootA(path, j); ok(root == path, "Expected root == path, got %p\n", root); ok(!lstrcmpA(root, root_expected[j]), "Expected %s, got %s\n", root_expected[j], root); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); } /* test a negative drive number */ @@ -1163,7 +1174,7 @@ static void test_PathBuildRootA(void) ok(root == path, "Expected root == path, got %p\n", root); ok(!lstrcmpA(path, "aaaaaaaaa") || !path[0], /* Vista */ "Expected aaaaaaaaa or empty string, got %s\n", path); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* test a drive number greater than 25 */ SetLastError(0xdeadbeef); @@ -1172,7 +1183,7 @@ static void test_PathBuildRootA(void) ok(root == path, "Expected root == path, got %p\n", root); ok(!lstrcmpA(path, "aaaaaaaaa") || !path[0], /* Vista */ "Expected aaaaaaaaa or empty string, got %s\n", path); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* length of path is less than 4 */ SetLastError(0xdeadbeef); @@ -1180,13 +1191,13 @@ static void test_PathBuildRootA(void) root = PathBuildRootA(path, 0); ok(root == path, "Expected root == path, got %p\n", root); ok(!lstrcmpA(path, "A:\\"), "Expected A:\\, got %s\n", path); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* path is NULL */ SetLastError(0xdeadbeef); root = PathBuildRootA(NULL, 0); ok(root == NULL, "Expected root == NULL, got %p\n", root); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); } static void test_PathCommonPrefixA(void) @@ -1206,7 +1217,7 @@ static void test_PathCommonPrefixA(void) ok(!lstrcmpA(out, "aaa"), "Expected aaa, got %s\n", out); } ok(!lstrcmpA(path2, "C:\\"), "Expected C:\\, got %s\n", path2); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* test NULL path2 */ SetLastError(0xdeadbeef); @@ -1219,7 +1230,7 @@ static void test_PathCommonPrefixA(void) ok(!lstrcmpA(out, "aaa"), "Expected aaa, got %s\n", out); } ok(!lstrcmpA(path1, "C:\\"), "Expected C:\\, got %s\n", path1); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* test empty path1 */ SetLastError(0xdeadbeef); @@ -1231,7 +1242,7 @@ static void test_PathCommonPrefixA(void) ok(!out[0], "Expected 0 length out, got %i\n", lstrlenA(out)); ok(!path1[0], "Expected 0 length path1, got %i\n", lstrlenA(path1)); ok(!lstrcmpA(path2, "C:\\"), "Expected C:\\, got %s\n", path2); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* test empty path1 */ SetLastError(0xdeadbeef); @@ -1243,7 +1254,7 @@ static void test_PathCommonPrefixA(void) ok(!out[0], "Expected 0 length out, got %i\n", lstrlenA(out)); ok(!path2[0], "Expected 0 length path2, got %i\n", lstrlenA(path2)); ok(!lstrcmpA(path1, "C:\\"), "Expected C:\\, got %s\n", path1); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* paths are legit, out is NULL */ SetLastError(0xdeadbeef); @@ -1253,7 +1264,7 @@ static void test_PathCommonPrefixA(void) ok(count == 3, "Expected 3, got %i\n", count); ok(!lstrcmpA(path1, "C:\\"), "Expected C:\\, got %s\n", path1); ok(!lstrcmpA(path2, "C:\\"), "Expected C:\\, got %s\n", path2); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* all parameters legit */ SetLastError(0xdeadbeef); @@ -1265,7 +1276,7 @@ static void test_PathCommonPrefixA(void) ok(!lstrcmpA(path1, "C:\\"), "Expected C:\\, got %s\n", path1); ok(!lstrcmpA(path2, "C:\\"), "Expected C:\\, got %s\n", path2); ok(!lstrcmpA(out, "C:\\"), "Expected C:\\, got %s\n", out); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* path1 and path2 not the same, but common prefix */ SetLastError(0xdeadbeef); @@ -1277,7 +1288,7 @@ static void test_PathCommonPrefixA(void) ok(!lstrcmpA(path1, "C:\\one\\two"), "Expected C:\\one\\two, got %s\n", path1); ok(!lstrcmpA(path2, "C:\\one\\three"), "Expected C:\\one\\three, got %s\n", path2); ok(!lstrcmpA(out, "C:\\one"), "Expected C:\\one, got %s\n", out); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try . prefix */ SetLastError(0xdeadbeef); @@ -1289,7 +1300,7 @@ static void test_PathCommonPrefixA(void) ok(!lstrcmpA(path1, "one\\.two"), "Expected one\\.two, got %s\n", path1); ok(!lstrcmpA(path2, "one\\.three"), "Expected one\\.three, got %s\n", path2); ok(!lstrcmpA(out, "one"), "Expected one, got %s\n", out); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try .. prefix */ SetLastError(0xdeadbeef); @@ -1301,7 +1312,7 @@ static void test_PathCommonPrefixA(void) ok(!lstrcmpA(path1, "one\\..two"), "Expected one\\..two, got %s\n", path1); ok(!lstrcmpA(path2, "one\\..three"), "Expected one\\..three, got %s\n", path2); ok(!lstrcmpA(out, "one"), "Expected one, got %s\n", out); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try ... prefix */ SetLastError(0xdeadbeef); @@ -1313,7 +1324,7 @@ static void test_PathCommonPrefixA(void) ok(!lstrcmpA(path1, "one\\...two"), "Expected one\\...two, got %s\n", path1); ok(!lstrcmpA(path2, "one\\...three"), "Expected one\\...three, got %s\n", path2); ok(!lstrcmpA(out, "one"), "Expected one, got %s\n", out); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try .\ prefix */ SetLastError(0xdeadbeef); @@ -1325,7 +1336,7 @@ static void test_PathCommonPrefixA(void) ok(!lstrcmpA(path1, "one\\.\\two"), "Expected one\\.\\two, got %s\n", path1); ok(!lstrcmpA(path2, "one\\.\\three"), "Expected one\\.\\three, got %s\n", path2); ok(!lstrcmpA(out, "one\\."), "Expected one\\., got %s\n", out); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try ..\ prefix */ SetLastError(0xdeadbeef); @@ -1337,7 +1348,7 @@ static void test_PathCommonPrefixA(void) ok(!lstrcmpA(path1, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1); ok(!lstrcmpA(path2, "one\\..\\three"), "Expected one\\..\\three, got %s\n", path2); ok(!lstrcmpA(out, "one\\.."), "Expected one\\.., got %s\n", out); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try ...\\ prefix */ SetLastError(0xdeadbeef); @@ -1349,7 +1360,7 @@ static void test_PathCommonPrefixA(void) ok(!lstrcmpA(path1, "one\\...\\two"), "Expected one\\...\\two, got %s\n", path1); ok(!lstrcmpA(path2, "one\\...\\three"), "Expected one\\...\\three, got %s\n", path2); ok(!lstrcmpA(out, "one\\..."), "Expected one\\..., got %s\n", out); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try prefix that is not an msdn labeled prefix type */ SetLastError(0xdeadbeef); @@ -1361,7 +1372,7 @@ static void test_PathCommonPrefixA(void) ok(!lstrcmpA(path1, "same"), "Expected same, got %s\n", path1); ok(!lstrcmpA(path2, "same"), "Expected same, got %s\n", path2); ok(!lstrcmpA(out, "same"), "Expected same, got %s\n", out); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try . after directory */ SetLastError(0xdeadbeef); @@ -1373,7 +1384,7 @@ static void test_PathCommonPrefixA(void) ok(!lstrcmpA(path1, "one\\mid.\\two"), "Expected one\\mid.\\two, got %s\n", path1); ok(!lstrcmpA(path2, "one\\mid.\\three"), "Expected one\\mid.\\three, got %s\n", path2); ok(!lstrcmpA(out, "one\\mid."), "Expected one\\mid., got %s\n", out); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try . in the middle of a directory */ SetLastError(0xdeadbeef); @@ -1385,7 +1396,7 @@ static void test_PathCommonPrefixA(void) ok(!lstrcmpA(path1, "one\\mid.end\\two"), "Expected one\\mid.end\\two, got %s\n", path1); ok(!lstrcmpA(path2, "one\\mid.end\\three"), "Expected one\\mid.end\\three, got %s\n", path2); ok(!lstrcmpA(out, "one\\mid.end"), "Expected one\\mid.end, got %s\n", out); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); /* try comparing a .. with the expanded path */ SetLastError(0xdeadbeef); @@ -1397,7 +1408,7 @@ static void test_PathCommonPrefixA(void) ok(!lstrcmpA(path1, "one\\..\\two"), "Expected one\\..\\two, got %s\n", path1); ok(!lstrcmpA(path2, "two"), "Expected two, got %s\n", path2); ok(!out[0], "Expected 0 length out, got %i\n", lstrlenA(out)); - ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\n", GetLastError()); } static void test_PathUnquoteSpaces(void) @@ -1405,7 +1416,7 @@ static void test_PathUnquoteSpaces(void) int i; for (i = 0; i < ARRAY_SIZE(TEST_PATH_UNQUOTE_SPACES); i++) { - char *path = strdupA(TEST_PATH_UNQUOTE_SPACES[i].path); + char *path = strdup(TEST_PATH_UNQUOTE_SPACES[i].path); WCHAR *pathW = GetWideString(TEST_PATH_UNQUOTE_SPACES[i].path); WCHAR *resultW = GetWideString(TEST_PATH_UNQUOTE_SPACES[i].result); @@ -1417,9 +1428,9 @@ static void test_PathUnquoteSpaces(void) PathUnquoteSpacesW(pathW); ok(!lstrcmpW(pathW, resultW), "%s (W): strings differ\n", TEST_PATH_UNQUOTE_SPACES[i].path); - FreeWideString(pathW); - FreeWideString(resultW); - HeapFree(GetProcessHeap(), 0, path); + free(pathW); + free(resultW); + free(path); } } @@ -1439,7 +1450,7 @@ static void test_PathGetDriveNumber(void) SetLastError(0xdeadbeef); ret = PathGetDriveNumberA(NULL); ok(ret == -1, "got %d\n", ret); - ok(GetLastError() == 0xdeadbeef, "got %d\n", GetLastError()); + ok(GetLastError() == 0xdeadbeef, "got %ld\n", GetLastError()); ret = PathGetDriveNumberA(test1A); ok(ret == 0, "got %d\n", ret); @@ -1482,20 +1493,20 @@ static void test_PathUnExpandEnvStrings(void) ok(ret, "got %d\n", ret); SetLastError(0xdeadbeef); ret = pPathUnExpandEnvStringsA(envvarA, buff, sizeof(buff)); - ok(!ret && GetLastError() == 0xdeadbeef, "got %d, error %d\n", ret, GetLastError()); + ok(!ret && GetLastError() == 0xdeadbeef, "got %d, error %ld\n", ret, GetLastError()); ret = GetEnvironmentVariableW(computernameW, envvarW, ARRAY_SIZE(envvarW)); ok(ret, "got %d\n", ret); SetLastError(0xdeadbeef); ret = pPathUnExpandEnvStringsW(envvarW, buffW, ARRAY_SIZE(buffW)); - ok(!ret && GetLastError() == 0xdeadbeef, "got %d, error %d\n", ret, GetLastError()); + ok(!ret && GetLastError() == 0xdeadbeef, "got %d, error %ld\n", ret, GetLastError()); /* something that can't be represented with env var */ strcpy(path, "somepath_name"); strcpy(buff, "xx"); SetLastError(0xdeadbeef); ret = pPathUnExpandEnvStringsA(path, buff, sizeof(buff)); - ok(!ret && GetLastError() == 0xdeadbeef, "got %d, error %d\n", ret, GetLastError()); + ok(!ret && GetLastError() == 0xdeadbeef, "got %d, error %ld\n", ret, GetLastError()); ok(buff[0] == 'x', "wrong return string %s\n", buff); len = GetSystemDirectoryA(path, MAX_PATH); @@ -1515,7 +1526,7 @@ static void test_PathUnExpandEnvStrings(void) strcpy(buff, "xx"); SetLastError(0xdeadbeef); ret = pPathUnExpandEnvStringsA(path, buff, sizeof(sysrootA)); - ok(!ret && GetLastError() == 0xdeadbeef, "got %d, error %d\n", ret, GetLastError()); + ok(!ret && GetLastError() == 0xdeadbeef, "got %d, error %ld\n", ret, GetLastError()); ok(buff[0] == 'x', "wrong return string %s\n", buff); /* enough size */ @@ -1548,7 +1559,7 @@ static void test_PathUnExpandEnvStrings(void) strcat(path, sysdrvA); SetLastError(0xdeadbeef); ret = pPathUnExpandEnvStringsA(path, buff, sizeof(buff)); - ok(!ret && GetLastError() == 0xdeadbeef, "got %d, error %d\n", ret, GetLastError()); + ok(!ret && GetLastError() == 0xdeadbeef, "got %d, error %ld\n", ret, GetLastError()); ret = SetEnvironmentVariableA("SystemDrive", envvarA); ok(ret, "got %d\n", ret); @@ -1560,7 +1571,7 @@ static void test_PathUnExpandEnvStrings(void) buffW[0] = 'x'; buffW[1] = 0; SetLastError(0xdeadbeef); ret = pPathUnExpandEnvStringsW(pathW, buffW, ARRAY_SIZE(buffW)); - ok(!ret && GetLastError() == 0xdeadbeef, "got %d, error %d\n", ret, GetLastError()); + ok(!ret && GetLastError() == 0xdeadbeef, "got %d, error %ld\n", ret, GetLastError()); ok(buffW[0] == 'x', "wrong return string %s\n", wine_dbgstr_w(buffW)); len = GetSystemDirectoryW(pathW, MAX_PATH); @@ -1574,14 +1585,14 @@ static void test_PathUnExpandEnvStrings(void) buffW[0] = 'x'; buffW[1] = 0; SetLastError(0xdeadbeef); ret = pPathUnExpandEnvStringsW(pathW, buffW, 5); - ok(!ret && GetLastError() == 0xdeadbeef, "got %d, error %d\n", ret, GetLastError()); + ok(!ret && GetLastError() == 0xdeadbeef, "got %d, error %ld\n", ret, GetLastError()); ok(buffW[0] == 'x', "wrong return string %s\n", wine_dbgstr_w(buffW)); /* buffer size is enough to hold variable name only */ buffW[0] = 'x'; buffW[1] = 0; SetLastError(0xdeadbeef); ret = pPathUnExpandEnvStringsW(pathW, buffW, ARRAY_SIZE(sysrootW)); - ok(!ret && GetLastError() == 0xdeadbeef, "got %d, error %d\n", ret, GetLastError()); + ok(!ret && GetLastError() == 0xdeadbeef, "got %d, error %ld\n", ret, GetLastError()); ok(buffW[0] == 'x', "wrong return string %s\n", wine_dbgstr_w(buffW)); /* enough size */ @@ -1655,7 +1666,7 @@ static void test_PathIsRelativeW(void) "PathIsRelativeW(\"%s\") expects %d, got %d.\n", test_path_is_relative[i].path, test_path_is_relative[i].expect, ret); - FreeWideString(path); + free(path); } } diff --git a/modules/rostests/winetests/shlwapi/shreg.c b/modules/rostests/winetests/shlwapi/shreg.c index ca7fbad289e..73da49c4930 100644 --- a/modules/rostests/winetests/shlwapi/shreg.c +++ b/modules/rostests/winetests/shlwapi/shreg.c @@ -83,7 +83,7 @@ static HKEY create_test_entries(void) SetEnvironmentVariableA("FOO", sEnvvar2); ret = RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_KEY, &hKey); - ok( ERROR_SUCCESS == ret, "RegCreateKeyA failed, ret=%u\n", ret); + ok( ERROR_SUCCESS == ret, "RegCreateKeyA failed, ret=%lu\n", ret); if (hKey) { @@ -98,13 +98,13 @@ static HKEY create_test_entries(void) nExpectedLen1 = strlen(sTestpath1) - strlen("%LONGSYSTEMVAR%") + strlen(sEnvvar1) + 1; nExpectedLen2 = strlen(sTestpath2) - strlen("%FOO%") + strlen(sEnvvar2) + 1; /* ExpandEnvironmentStringsA on NT4 returns 2x the correct result */ - trace("sExplen1 = (%d)\n", nExpLen1); + trace("sExplen1 = (%ld)\n", nExpLen1); if (nExpectedLen1 != nExpLen1) - trace( "Expanding %s failed (expected %d) - known bug in NT4\n", sTestpath1, nExpectedLen1 ); + trace( "Expanding %s failed (expected %ld) - known bug in NT4\n", sTestpath1, nExpectedLen1 ); - trace("sExplen2 = (%d)\n", nExpLen2); + trace("sExplen2 = (%ld)\n", nExpLen2); if (nExpectedLen2 != nExpLen2) - trace( "Expanding %s failed (expected %d) - known bug in NT4\n", sTestpath2, nExpectedLen2 ); + trace( "Expanding %s failed (expected %ld) - known bug in NT4\n", sTestpath2, nExpectedLen2 ); /* Make sure we carry on with correct values */ nExpLen1 = nExpectedLen1; @@ -123,21 +123,21 @@ static void test_SHGetValue(void) dwSize = MAX_PATH; dwType = -1; dwRet = SHGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test1", &dwType, buf, &dwSize); - ok( ERROR_SUCCESS == dwRet, "SHGetValueA failed, ret=%u\n", dwRet); + ok( ERROR_SUCCESS == dwRet, "SHGetValueA failed, ret=%lu\n", dwRet); ok( 0 == strcmp(sExpTestpath1, buf) || broken(0 == strcmp(sTestpath1, buf)), /* IE4.x */ "Comparing of (%s) with (%s) failed\n", buf, sExpTestpath1); ok( REG_SZ == dwType || broken(REG_EXPAND_SZ == dwType), /* IE4.x */ - "Expected REG_SZ, got (%u)\n", dwType); + "Expected REG_SZ, got (%lu)\n", dwType); strcpy(buf, sEmptyBuffer); dwSize = MAX_PATH; dwType = -1; dwRet = SHGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test2", &dwType, buf, &dwSize); - ok( ERROR_SUCCESS == dwRet, "SHGetValueA failed, ret=%u\n", dwRet); + ok( ERROR_SUCCESS == dwRet, "SHGetValueA failed, ret=%lu\n", dwRet); ok( 0 == strcmp(sTestpath1, buf) , "Comparing of (%s) with (%s) failed\n", buf, sTestpath1); - ok( REG_SZ == dwType , "Expected REG_SZ, got (%u)\n", dwType); + ok( REG_SZ == dwType , "Expected REG_SZ, got (%lu)\n", dwType); } static void test_SHRegGetValue(void) @@ -151,31 +151,31 @@ static void test_SHRegGetValue(void) size = MAX_PATH; ret = pSHRegGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test1", SRRF_RT_REG_EXPAND_SZ, &type, data, &size); - ok(ret == ERROR_INVALID_PARAMETER, "SHRegGetValue failed, ret=%u\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "SHRegGetValue failed, ret=%lu\n", ret); size = MAX_PATH; ret = pSHRegGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test1", SRRF_RT_REG_SZ, &type, data, &size); - ok(ret == ERROR_SUCCESS, "SHRegGetValue failed, ret=%u\n", ret); + ok(ret == ERROR_SUCCESS, "SHRegGetValue failed, ret=%lu\n", ret); ok(!strcmp(data, sExpTestpath1), "data = %s, expected %s\n", data, sExpTestpath1); - ok(type == REG_SZ, "type = %d, expected REG_SZ\n", type); + ok(type == REG_SZ, "type = %ld, expected REG_SZ\n", type); size = MAX_PATH; ret = pSHRegGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test1", SRRF_RT_REG_DWORD, &type, data, &size); - ok(ret == ERROR_UNSUPPORTED_TYPE, "SHRegGetValue failed, ret=%u\n", ret); + ok(ret == ERROR_UNSUPPORTED_TYPE, "SHRegGetValue failed, ret=%lu\n", ret); size = MAX_PATH; ret = pSHRegGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test2", SRRF_RT_REG_EXPAND_SZ, &type, data, &size); - ok(ret == ERROR_INVALID_PARAMETER, "SHRegGetValue failed, ret=%u\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "SHRegGetValue failed, ret=%lu\n", ret); size = MAX_PATH; ret = pSHRegGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test2", SRRF_RT_REG_SZ, &type, data, &size); - ok(ret == ERROR_SUCCESS, "SHRegGetValue failed, ret=%u\n", ret); + ok(ret == ERROR_SUCCESS, "SHRegGetValue failed, ret=%lu\n", ret); ok(!strcmp(data, sTestpath1), "data = %s, expected %s\n", data, sTestpath1); - ok(type == REG_SZ, "type = %d, expected REG_SZ\n", type); + ok(type == REG_SZ, "type = %ld, expected REG_SZ\n", type); size = MAX_PATH; ret = pSHRegGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test2", SRRF_RT_REG_QWORD, &type, data, &size); - ok(ret == ERROR_UNSUPPORTED_TYPE, "SHRegGetValue failed, ret=%u\n", ret); + ok(ret == ERROR_UNSUPPORTED_TYPE, "SHRegGetValue failed, ret=%lu\n", ret); } static void test_SHGetRegPath(void) @@ -188,7 +188,7 @@ static void test_SHGetRegPath(void) strcpy(buf, sEmptyBuffer); dwRet = (*pSHRegGetPathA)(HKEY_CURRENT_USER, REG_TEST_KEY, "Test1", buf, 0); - ok( ERROR_SUCCESS == dwRet, "SHRegGetPathA failed, ret=%u\n", dwRet); + ok( ERROR_SUCCESS == dwRet, "SHRegGetPathA failed, ret=%lu\n", dwRet); ok( 0 == strcmp(sExpTestpath1, buf) , "Comparing (%s) with (%s) failed\n", buf, sExpTestpath1); } @@ -204,7 +204,7 @@ static void test_SHQueryValueEx(void) sTestedFunction = "RegOpenKeyExA"; dwRet = RegOpenKeyExA(HKEY_CURRENT_USER, REG_TEST_KEY, 0, KEY_QUERY_VALUE, &hKey); - ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%u\n", sTestedFunction, dwRet); + ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%lu\n", sTestedFunction, dwRet); /****** SHQueryValueExA ******/ @@ -215,15 +215,15 @@ static void test_SHQueryValueEx(void) * Case 1.1 All arguments are NULL */ dwRet = SHQueryValueExA( hKey, "Test1", NULL, NULL, NULL, NULL); - ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%u\n", sTestedFunction, dwRet); + ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%lu\n", sTestedFunction, dwRet); /* * Case 1.2 dwType is set */ dwType = -1; dwRet = SHQueryValueExA( hKey, "Test1", NULL, &dwType, NULL, NULL); - ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%u\n", sTestedFunction, dwRet); - ok( REG_SZ == dwType , "Expected REG_SZ, got (%u)\n", dwType); + ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%lu\n", sTestedFunction, dwRet); + ok( REG_SZ == dwType , "Expected REG_SZ, got (%lu)\n", dwType); /* * dwSize is set @@ -231,18 +231,18 @@ static void test_SHQueryValueEx(void) */ dwSize = 6; dwRet = SHQueryValueExA( hKey, "Test1", NULL, NULL, NULL, &dwSize); - ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%u\n", sTestedFunction, dwRet); - ok( dwSize == nUsedBuffer1, "Buffer sizes (%u) and (%u) are not equal\n", dwSize, nUsedBuffer1); + ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%lu\n", sTestedFunction, dwRet); + ok( dwSize == nUsedBuffer1, "Buffer sizes (%lu) and (%lu) are not equal\n", dwSize, nUsedBuffer1); /* * dwExpanded > dwUnExpanded */ dwSize = 6; dwRet = SHQueryValueExA( hKey, "Test3", NULL, NULL, NULL, &dwSize); - ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%u\n", sTestedFunction, dwRet); + ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%lu\n", sTestedFunction, dwRet); ok( dwSize >= nUsedBuffer2 || broken(dwSize == (strlen(sTestpath2) + 1)), /* < IE4.x */ - "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2); + "Buffer size (%lu) should be >= (%lu)\n", dwSize, nUsedBuffer2); /* * Case 1 string shrinks during expanding @@ -251,12 +251,12 @@ static void test_SHQueryValueEx(void) dwSize = 6; dwType = -1; dwRet = SHQueryValueExA( hKey, "Test1", NULL, &dwType, buf, &dwSize); - ok( ERROR_MORE_DATA == dwRet, "Expected ERROR_MORE_DATA, got (%u)\n", dwRet); + ok( ERROR_MORE_DATA == dwRet, "Expected ERROR_MORE_DATA, got (%lu)\n", dwRet); ok( 0 == strcmp(sEmptyBuffer, buf) , "Comparing (%s) with (%s) failed\n", buf, sEmptyBuffer); - ok( dwSize == nUsedBuffer1, "Buffer sizes (%u) and (%u) are not equal\n", dwSize, nUsedBuffer1); + ok( dwSize == nUsedBuffer1, "Buffer sizes (%lu) and (%lu) are not equal\n", dwSize, nUsedBuffer1); ok( REG_SZ == dwType || broken(REG_EXPAND_SZ == dwType), /* < IE6 */ - "Expected REG_SZ, got (%u)\n", dwType); + "Expected REG_SZ, got (%lu)\n", dwType); /* * string grows during expanding @@ -266,14 +266,14 @@ static void test_SHQueryValueEx(void) dwSize = 6; dwType = -1; dwRet = SHQueryValueExA( hKey, "Test3", NULL, &dwType, buf, &dwSize); - ok( ERROR_MORE_DATA == dwRet, "Expected ERROR_MORE_DATA, got (%u)\n", dwRet); + ok( ERROR_MORE_DATA == dwRet, "Expected ERROR_MORE_DATA, got (%lu)\n", dwRet); ok( 0 == strcmp(sEmptyBuffer, buf) , "Comparing (%s) with (%s) failed\n", buf, sEmptyBuffer); ok( dwSize >= nUsedBuffer2 || broken(dwSize == (strlen(sTestpath2) + 1)), /* < IE6 */ - "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2); + "Buffer size (%lu) should be >= (%lu)\n", dwSize, nUsedBuffer2); ok( REG_SZ == dwType || broken(REG_EXPAND_SZ == dwType), /* < IE6 */ - "Expected REG_SZ, got (%u)\n", dwType); + "Expected REG_SZ, got (%lu)\n", dwType); /* * string grows during expanding @@ -288,18 +288,15 @@ static void test_SHQueryValueEx(void) ok( ERROR_MORE_DATA == dwRet || broken(ERROR_ENVVAR_NOT_FOUND == dwRet) || /* IE5.5 */ broken(ERROR_SUCCESS == dwRet), /* < IE5.5*/ - "Expected ERROR_MORE_DATA, got (%u)\n", dwRet); + "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( !strcmp("", buf) || !strcmp(sTestpath2, buf), + "Expected empty or unexpanded string (win98), got (%s)\n", buf); ok( dwSize >= nUsedBuffer2 || broken(dwSize == (strlen("") + 1)), /* < IE 5.5 */ - "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2); - ok( REG_SZ == dwType , "Expected REG_SZ, got (%u)\n", dwType); + "Buffer size (%lu) should be >= (%lu)\n", dwSize, nUsedBuffer2); + ok( REG_SZ == dwType , "Expected REG_SZ, got (%lu)\n", dwType); /* * string grows during expanding @@ -314,20 +311,17 @@ static void test_SHQueryValueEx(void) ok( ERROR_MORE_DATA == dwRet || broken(ERROR_ENVVAR_NOT_FOUND == dwRet) || /* IE5.5 */ broken(ERROR_SUCCESS == dwRet), /* < IE5.5 */ - "Expected ERROR_MORE_DATA, got (%u)\n", dwRet); + "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( !strcmp("", buf) || !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) */ broken(dwSize == (strlen("") + 1)), /* IE4.01 (NT4) and IE5.x (W2K) */ - "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2); - ok( REG_SZ == dwType , "Expected REG_SZ, got (%u)\n", dwType); + "Buffer size (%lu) should be >= (%lu)\n", dwSize, nUsedBuffer2); + ok( REG_SZ == dwType , "Expected REG_SZ, got (%lu)\n", dwType); /* * The buffer is NULL but the size is set @@ -336,11 +330,11 @@ static void test_SHQueryValueEx(void) dwSize = 6; dwType = -1; dwRet = SHQueryValueExA( hKey, "Test3", NULL, &dwType, NULL, &dwSize); - ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%u\n", sTestedFunction, dwRet); + ok( ERROR_SUCCESS == dwRet, "%s failed, ret=%lu\n", sTestedFunction, dwRet); ok( dwSize >= nUsedBuffer2 || broken(dwSize == (strlen(sTestpath2) + 1)), /* IE4.01 SP1 (Win98) */ - "Buffer size (%u) should be >= (%u)\n", dwSize, nUsedBuffer2); - ok( REG_SZ == dwType , "Expected REG_SZ, got (%u)\n", dwType); + "Buffer size (%lu) should be >= (%lu)\n", dwSize, nUsedBuffer2); + ok( REG_SZ == dwType , "Expected REG_SZ, got (%lu)\n", dwType); RegCloseKey(hKey); } @@ -368,7 +362,7 @@ static void test_SHCopyKey(void) dwRet = RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_KEY "\\CopyDestination", &hKeyDst); if (dwRet || !hKeyDst) { - ok( 0, "Destination couldn't be created, RegCreateKeyA returned (%u)\n", dwRet); + ok( 0, "Destination couldn't be created, RegCreateKeyA returned (%lu)\n", dwRet); return; } @@ -376,13 +370,13 @@ static void test_SHCopyKey(void) dwRet = RegOpenKeyA(HKEY_LOCAL_MACHINE, REG_CURRENT_VERSION, &hKeySrc); if (dwRet || !hKeySrc) { - ok( 0, "Source couldn't be opened, RegOpenKeyA returned (%u)\n", dwRet); + ok( 0, "Source couldn't be opened, RegOpenKeyA returned (%lu)\n", dwRet); RegCloseKey(hKeyDst); return; } dwRet = (*pSHCopyKeyA)(hKeySrc, NULL, hKeyDst, 0); - ok ( ERROR_SUCCESS == dwRet, "Copy failed, ret=(%u)\n", dwRet); + ok ( ERROR_SUCCESS == dwRet, "Copy failed, ret=(%lu)\n", dwRet); RegCloseKey(hKeySrc); RegCloseKey(hKeyDst); @@ -392,7 +386,7 @@ static void test_SHCopyKey(void) dwRet = RegOpenKeyA(HKEY_CURRENT_USER, REG_TEST_KEY "\\CopyDestination\\Shell Folders", &hKeyDst); if (dwRet || !hKeyDst) { - ok ( 0, "Copy couldn't be opened, RegOpenKeyA returned (%u)\n", dwRet); + ok ( 0, "Copy couldn't be opened, RegOpenKeyA returned (%lu)\n", dwRet); return; } @@ -433,7 +427,7 @@ static void test_SHDeleteKey(void) { dwRet = SHDeleteKeyA(HKEY_CURRENT_USER, REG_TEST_KEY "\\ODBC"); - ok ( ERROR_SUCCESS == dwRet, "SHDeleteKey failed, ret=(%u)\n", dwRet); + ok ( ERROR_SUCCESS == dwRet, "SHDeleteKey failed, ret=(%lu)\n", dwRet); dwRet = RegOpenKeyA(HKEY_CURRENT_USER, REG_TEST_KEY "\\ODBC", &hKeyS); ok ( ERROR_FILE_NOT_FOUND == dwRet, "SHDeleteKey did not delete\n"); @@ -457,7 +451,7 @@ static void test_SHRegCreateUSKeyW(void) } ret = pSHRegCreateUSKeyW(subkeyW, KEY_ALL_ACCESS, NULL, NULL, SHREGSET_FORCE_HKCU); - ok(ret == ERROR_INVALID_PARAMETER, "got %d\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "got %ld\n", ret); } static void test_SHRegCloseUSKey(void) @@ -473,20 +467,20 @@ static void test_SHRegCloseUSKey(void) } ret = pSHRegCloseUSKey(NULL); - ok(ret == ERROR_INVALID_PARAMETER, "got %d\n", ret); + ok(ret == ERROR_INVALID_PARAMETER, "got %ld\n", ret); ret = pSHRegOpenUSKeyW(localW, KEY_ALL_ACCESS, NULL, &key, FALSE); - ok(ret == ERROR_SUCCESS, "got %d\n", ret); + ok(ret == ERROR_SUCCESS, "got %ld\n", ret); ret = pSHRegCloseUSKey(key); - ok(ret == ERROR_SUCCESS, "got %d\n", ret); + ok(ret == ERROR_SUCCESS, "got %ld\n", ret); /* Test with limited rights, specially without KEY_SET_VALUE */ ret = pSHRegOpenUSKeyW(localW, KEY_QUERY_VALUE, NULL, &key, FALSE); - ok(ret == ERROR_SUCCESS, "got %d\n", ret); + ok(ret == ERROR_SUCCESS, "got %ld\n", ret); ret = pSHRegCloseUSKey(key); - ok(ret == ERROR_SUCCESS, "got %d\n", ret); + ok(ret == ERROR_SUCCESS, "got %ld\n", ret); } START_TEST(shreg) diff --git a/modules/rostests/winetests/shlwapi/string.c b/modules/rostests/winetests/shlwapi/string.c index 9114ad88e13..9cb111a646d 100644 --- a/modules/rostests/winetests/shlwapi/string.c +++ b/modules/rostests/winetests/shlwapi/string.c @@ -52,6 +52,7 @@ static DWORD (WINAPI *pStrCatChainW)(LPWSTR,DWORD,DWORD,LPCWSTR); static LPSTR (WINAPI *pStrCpyNXA)(LPSTR,LPCSTR,int); static LPWSTR (WINAPI *pStrCpyNXW)(LPWSTR,LPCWSTR,int); static LPSTR (WINAPI *pStrFormatByteSize64A)(LONGLONG,LPSTR,UINT); +static HRESULT (WINAPI *pStrFormatByteSizeEx)(LONGLONG,SFBS_FLAGS,LPWSTR,UINT); static LPSTR (WINAPI *pStrFormatKBSizeA)(LONGLONG,LPSTR,UINT); static LPWSTR (WINAPI *pStrFormatKBSizeW)(LONGLONG,LPWSTR,UINT); static BOOL (WINAPI *pStrIsIntlEqualA)(BOOL,LPCSTR,LPCSTR,int); @@ -69,12 +70,6 @@ static LPWSTR (WINAPI *pStrChrNW)(LPCWSTR,WCHAR,UINT); static BOOL (WINAPI *pStrToInt64ExA)(LPCSTR,DWORD,LONGLONG*); static BOOL (WINAPI *pStrToInt64ExW)(LPCWSTR,DWORD,LONGLONG*); -static int strcmpW(const WCHAR *str1, const WCHAR *str2) -{ - while (*str1 && (*str1 == *str2)) { str1++; str2++; } - return *str1 - *str2; -} - /* StrToInt/StrToIntEx results */ typedef struct tagStrToIntResult { @@ -82,6 +77,7 @@ typedef struct tagStrToIntResult int str_to_int; LONGLONG str_to_int64_ex; LONGLONG str_to_int64_hex; + BOOL failure; } StrToIntResult; static const StrToIntResult StrToInt_results[] = { @@ -95,11 +91,12 @@ static const StrToIntResult StrToInt_results[] = { { "0x2bdc546291f4b1", 0, 0, ((LONGLONG)0x2bdc54 << 32) | 0x6291f4b1 }, { "+0x44f4", 0, 0, 0x44f4 }, { "-0x44fd", 0, 0, 0x44fd }, - { "+ 88987", 0, 0, 0 }, - { "- 55", 0, 0, 0 }, - { "- 0", 0, 0, 0 }, - { "+ 0x44f4", 0, 0, 0 }, - { "--0x44fd", 0, 0, 0 }, + { "+ 88987", 0, 0, 0, TRUE }, + + { "- 55", 0, 0, 0, TRUE }, + { "- 0", 0, 0, 0, TRUE }, + { "+ 0x44f4", 0, 0, 0, TRUE }, + { "--0x44fd", 0, 0, 0, TRUE }, { " 1999", 0, 1999, 1999 }, { " +88987", 0, 88987, 88987 }, { " 012", 0, 12, 12 }, @@ -107,6 +104,10 @@ static const StrToIntResult StrToInt_results[] = { { " 0x44ff", 0, 0, 0x44ff }, { " +0x44f4", 0, 0, 0x44f4 }, { " -0x44fd", 0, 0, 0x44fd }, + { "\t\n +3", 0, 3, 3 }, + { "\v+4", 0, 0, 0, TRUE }, + { "\f+5", 0, 0, 0, TRUE }, + { "\r+6", 0, 0, 0, TRUE }, { NULL, 0, 0, 0 } }; @@ -494,8 +495,10 @@ static void test_StrToIntExA(void) { return_val = -1; bRet = StrToIntExA(result->string,0,&return_val); - ok(!bRet || return_val != -1, "No result returned from '%s'\n", - result->string); + if (result->failure) + ok(!bRet, "Got %d instead of failure for '%s'\n", return_val, result->string); + else + ok(bRet, "Failed for '%s'\n", result->string); if (bRet) ok(return_val == (int)result->str_to_int64_ex, "converted '%s' wrong (%d)\n", result->string, return_val); @@ -507,8 +510,10 @@ static void test_StrToIntExA(void) { return_val = -1; bRet = StrToIntExA(result->string,STIF_SUPPORT_HEX,&return_val); - ok(!bRet || return_val != -1, "No result returned from '%s'\n", - result->string); + if (result->failure) + ok(!bRet, "Got %d instead of failure for '%s'\n", return_val, result->string); + else + ok(bRet, "Failed for '%s'\n", result->string); if (bRet) ok(return_val == (int)result->str_to_int64_hex, "converted '%s' wrong (%d)\n", result->string, return_val); @@ -528,8 +533,10 @@ static void test_StrToIntExW(void) return_val = -1; MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff)); bRet = StrToIntExW(szBuff, 0, &return_val); - ok(!bRet || return_val != -1, "No result returned from '%s'\n", - result->string); + if (result->failure) + ok(!bRet, "Got %d instead of failure for '%s'\n", return_val, result->string); + else + ok(bRet, "Failed for '%s'\n", result->string); if (bRet) ok(return_val == (int)result->str_to_int64_ex, "converted '%s' wrong (%d)\n", result->string, return_val); @@ -542,13 +549,23 @@ static void test_StrToIntExW(void) return_val = -1; MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff)); bRet = StrToIntExW(szBuff, STIF_SUPPORT_HEX, &return_val); - ok(!bRet || return_val != -1, "No result returned from '%s'\n", - result->string); + if (result->failure) + ok(!bRet, "Got %d instead of failure for '%s'\n", return_val, result->string); + else + ok(bRet, "Failed for '%s'\n", result->string); if (bRet) ok(return_val == (int)result->str_to_int64_hex, "converted '%s' wrong (%d)\n", result->string, return_val); result++; } + + return_val = -1; + bRet = StrToIntExW(L"\x0661\x0662", 0, &return_val); + ok( !bRet, "Returned %d for Unicode digits\n", return_val ); + bRet = StrToIntExW(L"\x07c3\x07c4", 0, &return_val); + ok( !bRet, "Returned %d for Unicode digits\n", return_val ); + bRet = StrToIntExW(L"\xa0-2", 0, &return_val); + ok( !bRet, "Returned %d for Unicode space\n", return_val ); } static void test_StrToInt64ExA(void) @@ -567,8 +584,11 @@ static void test_StrToInt64ExA(void) { return_val = -1; bRet = pStrToInt64ExA(result->string,0,&return_val); - ok(!bRet || return_val != -1, "No result returned from '%s'\n", - result->string); + if (result->failure) + ok(!bRet, "Got %s instead of failure for '%s'\n", + wine_dbgstr_longlong(return_val), result->string); + else + ok(bRet, "Failed for '%s'\n", result->string); if (bRet) ok(return_val == result->str_to_int64_ex, "converted '%s' wrong (%s)\n", result->string, wine_dbgstr_longlong(return_val)); @@ -580,8 +600,11 @@ static void test_StrToInt64ExA(void) { return_val = -1; bRet = pStrToInt64ExA(result->string,STIF_SUPPORT_HEX,&return_val); - ok(!bRet || return_val != -1, "No result returned from '%s'\n", - result->string); + if (result->failure) + ok(!bRet, "Got %s instead of failure for '%s'\n", + wine_dbgstr_longlong(return_val), result->string); + else + ok(bRet, "Failed for '%s'\n", result->string); if (bRet) ok(return_val == result->str_to_int64_hex, "converted '%s' wrong (%s)\n", result->string, wine_dbgstr_longlong(return_val)); @@ -607,8 +630,11 @@ static void test_StrToInt64ExW(void) return_val = -1; MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff)); bRet = pStrToInt64ExW(szBuff, 0, &return_val); - ok(!bRet || return_val != -1, "No result returned from '%s'\n", - result->string); + if (result->failure) + ok(!bRet, "Got %s instead of failure for '%s'\n", + wine_dbgstr_longlong(return_val), result->string); + else + ok(bRet, "Failed for '%s'\n", result->string); if (bRet) ok(return_val == result->str_to_int64_ex, "converted '%s' wrong (%s)\n", result->string, wine_dbgstr_longlong(return_val)); @@ -621,13 +647,24 @@ static void test_StrToInt64ExW(void) return_val = -1; MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff)); bRet = pStrToInt64ExW(szBuff, STIF_SUPPORT_HEX, &return_val); - ok(!bRet || return_val != -1, "No result returned from '%s'\n", - result->string); + if (result->failure) + ok(!bRet, "Got %s instead of failure for '%s'\n", + wine_dbgstr_longlong(return_val), result->string); + else + ok(bRet, "Failed for '%s'\n", result->string); if (bRet) ok(return_val == result->str_to_int64_hex, "converted '%s' wrong (%s)\n", result->string, wine_dbgstr_longlong(return_val)); result++; } + + return_val = -1; + bRet = pStrToInt64ExW(L"\x0661\x0662", 0, &return_val); + ok( !bRet, "Returned %s for Unicode digits\n", wine_dbgstr_longlong(return_val) ); + bRet = pStrToInt64ExW(L"\x07c3\x07c4", 0, &return_val); + ok( !bRet, "Returned %s for Unicode digits\n", wine_dbgstr_longlong(return_val) ); + bRet = pStrToInt64ExW(L"\xa0-2", 0, &return_val); + ok( !bRet, "Returned %s for Unicode space\n", wine_dbgstr_longlong(return_val) ); } static void test_StrDupA(void) @@ -679,6 +716,38 @@ static void test_StrFormatByteSize64A(void) } } +static void test_StrFormatByteSizeEx(void) +{ + WCHAR szBuff[256]; + HRESULT hr; + LONGLONG test_value = 2147483647; + + if (!pStrFormatByteSizeEx) + { + win_skip("StrFormatByteSizeEx is not available \n"); + return; + } + + hr = pStrFormatByteSizeEx(0xdeadbeef, + SFBS_FLAGS_TRUNCATE_UNDISPLAYED_DECIMAL_DIGITS, szBuff, 0); + ok(hr == E_INVALIDARG, "Unexpected hr: %#lx expected: %#lx\n", hr, E_INVALIDARG); + + hr = pStrFormatByteSizeEx(0xdeadbeef, 10, szBuff, 256); + ok(hr == E_INVALIDARG, "Unexpected hr: %#lx expected: %#lx\n", hr, E_INVALIDARG); + + hr = pStrFormatByteSizeEx(test_value, SFBS_FLAGS_ROUND_TO_NEAREST_DISPLAYED_DIGIT, + szBuff, 256); + ok(hr == S_OK, "Invalid arguments \n"); + ok(!wcscmp(szBuff, L"2.00 GB"), "Formatted %s wrong: got %ls, expected 2.00 GB\n", + wine_dbgstr_longlong(test_value), szBuff); + + hr = pStrFormatByteSizeEx(test_value, SFBS_FLAGS_TRUNCATE_UNDISPLAYED_DECIMAL_DIGITS, + szBuff, 256); + ok(hr == S_OK, "Invalid arguments \n"); + ok(!wcscmp(szBuff, L"1.99 GB"), "Formatted %s wrong: got %ls, expected 1.99 GB\n", + wine_dbgstr_longlong(test_value), szBuff); +} + static void test_StrFormatKBSizeW(void) { WCHAR szBuffW[256]; @@ -736,7 +805,7 @@ static void test_StrFromTimeIntervalA(void) { StrFromTimeIntervalA(szBuff, 256, result->ms, result->digits); - ok(!strcmp(result->time_interval, szBuff), "Formatted %d %d wrong: %s\n", + ok(!strcmp(result->time_interval, szBuff), "Formatted %ld %d wrong: %s\n", result->ms, result->digits, szBuff); result++; } @@ -827,26 +896,26 @@ static void test_StrRetToBSTR(void) } strret.uType = STRRET_WSTR; - U(strret).pOleStr = CoDupStrW("Test"); + strret.pOleStr = CoDupStrW("Test"); bstr = 0; ret = pStrRetToBSTR(&strret, NULL, &bstr); - ok(ret == S_OK && bstr && !strcmpW(bstr, szTestW), - "STRRET_WSTR: dup failed, ret=0x%08x, bstr %p\n", ret, bstr); + ok(ret == S_OK && bstr && !wcscmp(bstr, szTestW), + "STRRET_WSTR: dup failed, ret=0x%08lx, bstr %p\n", ret, bstr); SysFreeString(bstr); strret.uType = STRRET_CSTR; - lstrcpyA(U(strret).cStr, "Test"); + lstrcpyA(strret.cStr, "Test"); ret = pStrRetToBSTR(&strret, NULL, &bstr); - ok(ret == S_OK && bstr && !strcmpW(bstr, szTestW), - "STRRET_CSTR: dup failed, ret=0x%08x, bstr %p\n", ret, bstr); + ok(ret == S_OK && bstr && !wcscmp(bstr, szTestW), + "STRRET_CSTR: dup failed, ret=0x%08lx, bstr %p\n", ret, bstr); SysFreeString(bstr); strret.uType = STRRET_OFFSET; - U(strret).uOffset = 1; + strret.uOffset = 1; strcpy((char*)&iidl, " Test"); ret = pStrRetToBSTR(&strret, iidl, &bstr); - ok(ret == S_OK && bstr && !strcmpW(bstr, szTestW), - "STRRET_OFFSET: dup failed, ret=0x%08x, bstr %p\n", ret, bstr); + ok(ret == S_OK && bstr && !wcscmp(bstr, szTestW), + "STRRET_OFFSET: dup failed, ret=0x%08lx, bstr %p\n", ret, bstr); SysFreeString(bstr); /* Native crashes if str is NULL */ @@ -951,7 +1020,7 @@ static void test_SHAnsiToAnsi(void) memset(dest, '\n', sizeof(dest)); dwRet = pSHAnsiToAnsi("hello", dest, ARRAY_SIZE(dest)); ok(dwRet == 6 && !memcmp(dest, "hello\0\n\n", sizeof(dest)), - "SHAnsiToAnsi: expected 6, \"hello\\0\\n\\n\", got %d, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n", + "SHAnsiToAnsi: expected 6, \"hello\\0\\n\\n\", got %ld, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n", dwRet, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); } @@ -978,7 +1047,7 @@ static void test_SHUnicodeToUnicode(void) memcpy(dest, lpInit, sizeof(lpInit)); dwRet = pSHUnicodeToUnicode(lpSrc, dest, ARRAY_SIZE(dest)); ok(dwRet == 6 && !memcmp(dest, lpRes, sizeof(dest)), - "SHUnicodeToUnicode: expected 6, \"hello\\0\\n\\n\", got %d, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n", + "SHUnicodeToUnicode: expected 6, \"hello\\0\\n\\n\", got %ld, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n", dwRet, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); } @@ -1059,10 +1128,10 @@ if (0) { memset(wbuf, 0xbf, sizeof(wbuf)); strret.uType = STRRET_WSTR; - U(strret).pOleStr = StrDupW(wstr1); + strret.pOleStr = StrDupW(wstr1); hres = pStrRetToBufW(&strret, NULL, wbuf, 10); ok(hres == E_NOT_SUFFICIENT_BUFFER || broken(hres == S_OK) /* winxp */, - "StrRetToBufW returned %08x\n", hres); + "StrRetToBufW returned %08lx\n", hres); if (hres == E_NOT_SUFFICIENT_BUFFER) expect_eq(wbuf[0], 0, WCHAR, "%x"); expect_eq(wbuf[9], 0, WCHAR, "%x"); @@ -1070,16 +1139,16 @@ if (0) memset(wbuf, 0xbf, sizeof(wbuf)); strret.uType = STRRET_CSTR; - StrCpyNA(U(strret).cStr, str1, MAX_PATH); + StrCpyNA(strret.cStr, str1, MAX_PATH); hres = pStrRetToBufW(&strret, NULL, wbuf, 10); - ok(hres == S_OK, "StrRetToBufW returned %08x\n", hres); + ok(hres == S_OK, "StrRetToBufW returned %08lx\n", hres); ok(!memcmp(wbuf, wstr1, 9*sizeof(WCHAR)) && !wbuf[9], "StrRetToBuf returned %s\n", wine_dbgstr_w(wbuf)); memset(wbuf, 0xbf, sizeof(wbuf)); strret.uType = STRRET_WSTR; - U(strret).pOleStr = NULL; + strret.pOleStr = NULL; hres = pStrRetToBufW(&strret, NULL, wbuf, 10); - ok(hres == E_FAIL, "StrRetToBufW returned %08x\n", hres); + ok(hres == E_FAIL, "StrRetToBufW returned %08lx\n", hres); ok(!wbuf[0], "StrRetToBuf returned %s\n", wine_dbgstr_w(wbuf)); } else @@ -1089,8 +1158,8 @@ if (0) { memset(buf, 0xbf, sizeof(buf)); strret.uType = STRRET_CSTR; - StrCpyNA(U(strret).cStr, str1, MAX_PATH); - expect_eq2(pStrRetToBufA(&strret, NULL, buf, 10), S_OK, E_NOT_SUFFICIENT_BUFFER /* Vista */, HRESULT, "%x"); + StrCpyNA(strret.cStr, str1, MAX_PATH); + expect_eq2(pStrRetToBufA(&strret, NULL, buf, 10), S_OK, E_NOT_SUFFICIENT_BUFFER /* Vista */, HRESULT, "%lx"); expect_eq(buf[9], 0, CHAR, "%x"); expect_eq(buf[10], (CHAR)0xbf, CHAR, "%x"); } @@ -1104,6 +1173,37 @@ if (0) ok(broken(ret == 9) || ret == -1 /* Vista */, "Unexpected wnsprintfA return %d, expected 9 or -1\n", ret); expect_eq(buf[9], 0, CHAR, "%x"); expect_eq(buf[10], (CHAR)0xbf, CHAR, "%x"); + + memset(buf, 0xbf, sizeof(buf)); + ret = pwnsprintfA(buf + 1, -1, "%s", str1); +#ifdef __REACTOS__ + ok(ret == -1 || broken(ret == 0) /* WS03 */, "got %d.\n", ret); +#else + ok(ret == -1, "got %d.\n", ret); +#endif + expect_eq(buf[0], (CHAR)0xbf, CHAR, "%x"); + if (!broken(1)) + { + /* This is 0xbf before Win8. */ + expect_eq(buf[1], 0, CHAR, "%x"); + } + expect_eq(buf[2], (CHAR)0xbf, CHAR, "%x"); + + memset(buf, 0xbf, sizeof(buf)); + ret = pwnsprintfA(buf + 1, 0, "%s", str1); +#ifdef __REACTOS__ + ok(ret == -1 || broken(ret == 0) /* WS03 */, "got %d.\n", ret); +#else + ok(ret == -1, "got %d.\n", ret); +#endif + expect_eq(buf[0], (CHAR)0xbf, CHAR, "%x"); + expect_eq(buf[1], (CHAR)0xbf, CHAR, "%x"); + + memset(buf, 0xbf, sizeof(buf)); + ret = pwnsprintfA(buf, 1, ""); + ok(!ret, "got %d.\n", ret); + expect_eq(buf[0], 0, CHAR, "%x"); + expect_eq(buf[1], (CHAR)0xbf, CHAR, "%x"); } else win_skip("wnsprintfA() is not available\n"); @@ -1115,6 +1215,37 @@ if (0) ok(broken(ret == 9) || ret == -1 /* Vista */, "Unexpected wnsprintfW return %d, expected 9 or -1\n", ret); expect_eq(wbuf[9], 0, WCHAR, "%x"); expect_eq(wbuf[10], (WCHAR)0xbfbf, WCHAR, "%x"); + + memset(wbuf, 0xbf, sizeof(wbuf)); + ret = pwnsprintfW(wbuf + 1, -1, fmt, wstr1); +#ifdef __REACTOS__ + ok(ret == -1 || broken(ret == 0) /* WS03 */, "got %d.\n", ret); +#else + ok(ret == -1, "got %d.\n", ret); +#endif + expect_eq(wbuf[0], (WCHAR)0xbfbf, WCHAR, "%x"); + if (!broken(1)) + { + /* This is 0xbfbf before Win8. */ + expect_eq(wbuf[1], 0, WCHAR, "%x"); + } + expect_eq(wbuf[2], (WCHAR)0xbfbf, WCHAR, "%x"); + + memset(wbuf, 0xbf, sizeof(wbuf)); + ret = pwnsprintfW(wbuf + 1, 0, fmt, wstr1); +#ifdef __REACTOS__ + ok(ret == -1 || broken(ret == 0) /* WS03 */, "got %d.\n", ret); +#else + ok(ret == -1, "got %d.\n", ret); +#endif + expect_eq(wbuf[0], (WCHAR)0xbfbf, WCHAR, "%x"); + expect_eq(wbuf[1], (WCHAR)0xbfbf, WCHAR, "%x"); + + memset(wbuf, 0xbf, sizeof(wbuf)); + ret = pwnsprintfW(wbuf, 1, L""); + ok(!ret, "got %d.\n", ret); + expect_eq(wbuf[0], 0, WCHAR, "%x"); + expect_eq(wbuf[1], (WCHAR)0xbfbf, WCHAR, "%x"); } else win_skip("wnsprintfW() is not available\n"); @@ -1518,43 +1649,43 @@ static void test_StrCatChainW(void) /* Test with NULL buffer */ ret = pStrCatChainW(NULL, 0, 0, beefW); - ok(ret == 0, "Expected StrCatChainW to return 0, got %u\n", ret); + ok(ret == 0, "Expected StrCatChainW to return 0, got %lu\n", ret); /* Test with empty buffer */ memset(buf, 0x11, sizeof(buf)); ret = pStrCatChainW(buf, 0, 0, beefW); - ok(ret == 0, "Expected StrCatChainW to return 0, got %u\n", ret); + ok(ret == 0, "Expected StrCatChainW to return 0, got %lu\n", ret); ok(buf[0] == 0x1111, "Expected buf[0] = 0x1111, got %x\n", buf[0]); memcpy(buf, deadbeefW, sizeof(deadbeefW)); ret = pStrCatChainW(buf, 0, -1, beefW); - ok(ret == 8, "Expected StrCatChainW to return 8, got %u\n", ret); + ok(ret == 8, "Expected StrCatChainW to return 8, got %lu\n", ret); ok(!memcmp(buf, deadbeefW, sizeof(deadbeefW)), "Buffer contains wrong data\n"); /* Append data to existing string with offset = -1 */ memset(buf, 0x11, sizeof(buf)); ret = pStrCatChainW(buf, 32, 0, deadW); - ok(ret == 4, "Expected StrCatChainW to return 4, got %u\n", ret); + ok(ret == 4, "Expected StrCatChainW to return 4, got %lu\n", ret); ok(!memcmp(buf, deadW, sizeof(deadW)), "Buffer contains wrong data\n"); ret = pStrCatChainW(buf, 32, -1, beefW); - ok(ret == 8, "Expected StrCatChainW to return 8, got %u\n", ret); + ok(ret == 8, "Expected StrCatChainW to return 8, got %lu\n", ret); ok(!memcmp(buf, deadbeefW, sizeof(deadbeefW)), "Buffer contains wrong data\n"); /* Append data at a fixed offset */ memset(buf, 0x11, sizeof(buf)); ret = pStrCatChainW(buf, 32, 0, deadW); - ok(ret == 4, "Expected StrCatChainW to return 4, got %u\n", ret); + ok(ret == 4, "Expected StrCatChainW to return 4, got %lu\n", ret); ok(!memcmp(buf, deadW, sizeof(deadW)), "Buffer contains wrong data\n"); ret = pStrCatChainW(buf, 32, 4, beefW); - ok(ret == 8, "Expected StrCatChainW to return 8, got %u\n", ret); + ok(ret == 8, "Expected StrCatChainW to return 8, got %lu\n", ret); ok(!memcmp(buf, deadbeefW, sizeof(deadbeefW)), "Buffer contains wrong data\n"); /* Buffer exactly sufficient for string + terminating null */ memset(buf, 0x11, sizeof(buf)); ret = pStrCatChainW(buf, 5, 0, deadW); - ok(ret == 4, "Expected StrCatChainW to return 4, got %u\n", ret); + ok(ret == 4, "Expected StrCatChainW to return 4, got %lu\n", ret); ok(!memcmp(buf, deadW, sizeof(deadW)), "Buffer contains wrong data\n"); /* Buffer too small, string will be truncated */ @@ -1568,14 +1699,14 @@ static void test_StrCatChainW(void) win_skip("Windows2000/XP behaviour detected for StrCatChainW, skipping tests\n"); return; } - ok(ret == 3, "Expected StrCatChainW to return 3, got %u\n", ret); + ok(ret == 3, "Expected StrCatChainW to return 3, got %lu\n", ret); ok(!memcmp(buf, deadW, 3 * sizeof(WCHAR)), "Buffer contains wrong data\n"); ok(!buf[3], "String is not nullterminated\n"); ok(buf[4] == 0x1111, "Expected buf[4] = 0x1111, got %x\n", buf[4]); /* Overwrite part of an existing string */ ret = pStrCatChainW(buf, 4, 1, beefW); - ok(ret == 3, "Expected StrCatChainW to return 3, got %u\n", ret); + ok(ret == 3, "Expected StrCatChainW to return 3, got %lu\n", ret); ok(buf[0] == 'D', "Expected buf[0] = 'D', got %x\n", buf[0]); ok(buf[1] == 'B', "Expected buf[1] = 'B', got %x\n", buf[1]); ok(buf[2] == 'e', "Expected buf[2] = 'e', got %x\n", buf[2]); @@ -1587,39 +1718,217 @@ static void test_StrCatChainW(void) memcpy(buf, deadbeefW, sizeof(deadbeefW)); memcpy(buf + 9, deadW, sizeof(deadW)); ret = pStrCatChainW(buf, 9, 8, beefW); - ok(ret == 8, "Expected StrCatChainW to return 8, got %u\n", ret); + ok(ret == 8, "Expected StrCatChainW to return 8, got %lu\n", ret); ok(!memcmp(buf, deadbeefW, sizeof(deadbeefW)), "Buffer contains wrong data\n"); ok(!memcmp(buf + 9, deadW, sizeof(deadW)), "Buffer contains wrong data\n"); /* Offset points at the end of the buffer */ ret = pStrCatChainW(buf, 9, 9, beefW); - ok(ret == 8, "Expected StrCatChainW to return 8, got %u\n", ret); + ok(ret == 8, "Expected StrCatChainW to return 8, got %lu\n", ret); ok(!memcmp(buf, deadbeefW, sizeof(deadbeefW)), "Buffer contains wrong data\n"); ok(!memcmp(buf + 9, deadW, sizeof(deadW)), "Buffer contains wrong data\n"); /* Offset points outside of the buffer */ ret = pStrCatChainW(buf, 9, 10, beefW); - ok(ret == 10, "Expected StrCatChainW to return 10, got %u\n", ret); + ok(ret == 10, "Expected StrCatChainW to return 10, got %lu\n", ret); ok(!memcmp(buf, deadbeefW, sizeof(deadbeefW)), "Buffer contains wrong data\n"); ok(!memcmp(buf + 9, deadW, sizeof(deadW)), "Buffer contains wrong data\n"); /* The same but without nullterminated string */ memcpy(buf, deadbeefW, sizeof(deadbeefW)); ret = pStrCatChainW(buf, 5, -1, deadW); - ok(ret == 8, "Expected StrCatChainW to return 8, got %u\n", ret); + ok(ret == 8, "Expected StrCatChainW to return 8, got %lu\n", ret); ok(!memcmp(buf, deadbeefW, sizeof(deadbeefW)), "Buffer contains wrong data\n"); ret = pStrCatChainW(buf, 5, 5, deadW); - ok(ret == 4, "Expected StrCatChainW to return 4, got %u\n", ret); + ok(ret == 4, "Expected StrCatChainW to return 4, got %lu\n", ret); ok(!memcmp(buf, deadW, sizeof(deadW)), "Buffer contains wrong data\n"); ok(buf[5] == 'e', "Expected buf[5] = 'e', got %x\n", buf[5]); ret = pStrCatChainW(buf, 5, 6, deadW); - ok(ret == 6, "Expected StrCatChainW to return 6, got %u\n", ret); + ok(ret == 6, "Expected StrCatChainW to return 6, got %lu\n", ret); ok(!memcmp(buf, deadW, sizeof(deadW)), "Buffer contains wrong data\n"); ok(buf[5] == 'e', "Expected buf[5] = 'e', got %x\n", buf[5]); } +static void test_printf_format(void) +{ + const struct + { + const char *spec; + unsigned int arg_size; + ULONG64 arg; + const void *argw; + } + tests[] = + { + { "%qu", 0, 10 }, + { "%ll", 0, 10 }, + { "%lu", sizeof(ULONG), 65537 }, + { "%llu", sizeof(ULONG64), 10 }, + { "%lllllllu", sizeof(ULONG64), 10 }, + { "%#lx", sizeof(ULONG), 10 }, + { "%#llx", sizeof(ULONG64), 0x1000000000 }, + { "%#lllx", sizeof(ULONG64), 0x1000000000 }, + { "%hu", sizeof(ULONG), 65537 }, + { "%hlu", sizeof(ULONG), 65537 }, + { "%hllx", sizeof(ULONG64), 0x100000010 }, + { "%hlllx", sizeof(ULONG64), 0x100000010 }, + { "%llhx", sizeof(ULONG64), 0x100000010 }, + { "%lllhx", sizeof(ULONG64), 0x100000010 }, + { "%lhu", sizeof(ULONG), 65537 }, + { "%hhu", sizeof(ULONG), 65537 }, + { "%hwu", sizeof(ULONG), 65537 }, + { "%whu", sizeof(ULONG), 65537 }, + { "%##lhllwlx", sizeof(ULONG64), 0x1000000010 }, + { "%##lhlwlx", sizeof(ULONG), 0x1000000010 }, + { "%04lhlwllx", sizeof(ULONG64), 0x1000000010 }, + { "%s", sizeof(ULONG_PTR), (ULONG_PTR)"str", L"str" }, + { "%S", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" }, + { "%ls", sizeof(ULONG_PTR), (ULONG_PTR)L"str" }, + { "%lS", sizeof(ULONG_PTR), (ULONG_PTR)L"str" }, + { "%lls", sizeof(ULONG_PTR), (ULONG_PTR)"str", L"str" }, + { "%llS", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" }, + { "%llls", sizeof(ULONG_PTR), (ULONG_PTR)L"str" }, + { "%lllS", sizeof(ULONG_PTR), (ULONG_PTR)L"str" }, + { "%lllls", sizeof(ULONG_PTR), (ULONG_PTR)"str", L"str" }, + { "%llllS", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" }, + { "%hs", sizeof(ULONG_PTR), (ULONG_PTR)"str" }, + { "%hS", sizeof(ULONG_PTR), (ULONG_PTR)"str" }, + { "%ws", sizeof(ULONG_PTR), (ULONG_PTR)L"str" }, + { "%wS", sizeof(ULONG_PTR), (ULONG_PTR)L"str" }, + { "%hhs", sizeof(ULONG_PTR), (ULONG_PTR)"str" }, + { "%hhS", sizeof(ULONG_PTR), (ULONG_PTR)"str" }, + { "%wws", sizeof(ULONG_PTR), (ULONG_PTR)L"str" }, + { "%wwS", sizeof(ULONG_PTR), (ULONG_PTR)L"str" }, + { "%wwws", sizeof(ULONG_PTR), (ULONG_PTR)L"str" }, + { "%wwwS", sizeof(ULONG_PTR), (ULONG_PTR)L"str" }, + { "%hws", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" }, + { "%hwS", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" }, + { "%whs", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" }, + { "%whS", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" }, + { "%hwls", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" }, + { "%hwlls", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" }, + { "%hwlS", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" }, + { "%hwllS", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" }, + { "%lhws", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" }, + { "%llhws", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" }, + { "%lhwS", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" }, + { "%llhwS", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" }, + { "%c", sizeof(SHORT), 0x95c8 }, + { "%lc", sizeof(SHORT), 0x95c8 }, + { "%llc", sizeof(SHORT), 0x95c8 }, + { "%lllc", sizeof(SHORT), 0x95c8 }, + { "%llllc", sizeof(SHORT), 0x95c8 }, + { "%lllllc", sizeof(SHORT), 0x95c8 }, + { "%C", sizeof(SHORT), 0x95c8 }, + { "%lC", sizeof(SHORT), 0x95c8 }, + { "%llC", sizeof(SHORT), 0x95c8 }, + { "%lllC", sizeof(SHORT), 0x95c8 }, + { "%llllC", sizeof(SHORT), 0x95c8 }, + { "%lllllC", sizeof(SHORT), 0x95c8 }, + { "%hc", sizeof(BYTE), 0x95c8 }, + { "%hhc", sizeof(BYTE), 0x95c8 }, + { "%hhhc", sizeof(BYTE), 0x95c8 }, + { "%wc", sizeof(BYTE), 0x95c8 }, + { "%wC", sizeof(BYTE), 0x95c8 }, + { "%hwc", sizeof(BYTE), 0x95c8 }, + { "%whc", sizeof(BYTE), 0x95c8 }, + { "%hwC", sizeof(BYTE), 0x95c8 }, + { "%whC", sizeof(BYTE), 0x95c8 }, + { "%I64u", sizeof(ULONG64), 10 }, + { "%llI64u", sizeof(ULONG64), 10 }, + { "%I64llu", sizeof(ULONG64), 10 }, + { "%I64s", sizeof(ULONG_PTR), (ULONG_PTR)"str", L"str" }, + { "%q%u", sizeof(ULONG), 10 }, + { "%lhw%u", 0, 10 }, + { "%u% ", sizeof(ULONG), 10 }, + { "%u% %u", sizeof(ULONG), 10 }, + { "% ll u", 0, 10 }, + { "% llu", sizeof(ULONG64), 10 }, + { "%# llx", sizeof(ULONG64), 10 }, + { "% #llx", sizeof(ULONG64), 10 }, + }; + int (WINAPIV *ntdll__snprintf)(char *str, size_t len, const char *format, ...); + int (WINAPIV *ntdll__snwprintf)( WCHAR *str, size_t len, const WCHAR *format, ... ); + WCHAR ws[256], expectedw[256], specw[256]; + unsigned int i, j; + char expected[256], spec[256], s[256]; + int len_a, len_w = 0, expected_len_a, expected_len_w = 0; + HANDLE hntdll = GetModuleHandleW(L"ntdll.dll"); + + ntdll__snprintf = (void *)GetProcAddress(hntdll, "_snprintf"); + ok(!!ntdll__snprintf, "_snprintf not found.\n"); + ntdll__snwprintf = (void *)GetProcAddress(hntdll, "_snwprintf"); + ok(!!ntdll__snwprintf, "_snwprintf not found.\n"); +#ifdef __REACTOS__ + DWORD _ntVersion = GetVersion(); + BYTE _ntMajor = LOBYTE(LOWORD(_ntVersion)); + BYTE _ntMinor = HIBYTE(LOWORD(_ntVersion)); + + if (_ntMajor < 6 || (_ntMajor == 6 && _ntMinor == 0)) { + skip("These tests are broken on WS03 and Vista.\n"); + return; + } +#endif + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + strcpy(spec, tests[i].spec); + winetest_push_context("%s", spec); + strcat(spec,"|%s"); + *s = 0; + *ws = 0; + j = 0; + do + specw[j] = spec[j]; + while (specw[j++]); + if (tests[i].argw) + { + len_w = pwnsprintfW(ws, ARRAY_SIZE(ws), specw, tests[i].argw, L"end"); + expected_len_w = ntdll__snwprintf(expectedw, ARRAY_SIZE(expectedw), specw, tests[i].argw, L"end"); + } + switch (tests[i].arg_size) + { + case 0: + len_a = pwnsprintfA(s, ARRAY_SIZE(s), spec, "end"); + expected_len_a = ntdll__snprintf(expected, ARRAY_SIZE(expected), spec, "end"); + len_w = pwnsprintfW(ws, ARRAY_SIZE(ws), specw, L"end"); + expected_len_w = ntdll__snwprintf(expectedw, ARRAY_SIZE(expectedw), specw, L"end"); + break; + case 1: + case 2: + case 4: + len_a = pwnsprintfA(s, ARRAY_SIZE(s), spec, (ULONG)tests[i].arg, "end"); + expected_len_a = ntdll__snprintf(expected, ARRAY_SIZE(expected), spec, (ULONG)tests[i].arg, "end"); + if (!tests[i].argw) + { + len_w = pwnsprintfW(ws, ARRAY_SIZE(ws), specw, (ULONG)tests[i].arg, L"end"); + expected_len_w = ntdll__snwprintf(expectedw, ARRAY_SIZE(expectedw), specw, (ULONG)tests[i].arg, L"end"); + } + break; + case 8: + len_a = pwnsprintfA(s, ARRAY_SIZE(s), spec, (ULONG64)tests[i].arg, "end"); + expected_len_a = ntdll__snprintf(expected, ARRAY_SIZE(s), spec, (ULONG64)tests[i].arg, "end"); + if (!tests[i].argw) + { + len_w = pwnsprintfW(ws, ARRAY_SIZE(ws), specw, (ULONG64)tests[i].arg, L"end"); + expected_len_w = ntdll__snwprintf(expectedw, ARRAY_SIZE(expectedw), specw, (ULONG64)tests[i].arg, L"end"); + } + break; + default: + len_a = len_w = expected_len_a = expected_len_w = 0; + ok(0, "unknown length %u.\n", tests[i].arg_size); + break; + } + ok(len_a == expected_len_a, "got len %d, expected %d.\n", len_a, expected_len_a); + ok(!strcmp(s, expected), "got %s, expected %s.\n", debugstr_a(s), debugstr_a(expected)); + ok(len_w == expected_len_w, "got len %d, expected %d.\n", len_a, expected_len_a); + ok(!wcscmp(ws, expectedw), "got %s, expected %s.\n", debugstr_w(ws), debugstr_w(expectedw)); + winetest_pop_context(); + } +} + START_TEST(string) { HMODULE hShlwapi; @@ -1644,6 +1953,7 @@ START_TEST(string) pStrCpyNXW = (void *)GetProcAddress(hShlwapi, (LPSTR)400); pStrChrNW = (void *)GetProcAddress(hShlwapi, "StrChrNW"); pStrFormatByteSize64A = (void *)GetProcAddress(hShlwapi, "StrFormatByteSize64A"); + pStrFormatByteSizeEx = (void *)GetProcAddress(hShlwapi, "StrFormatByteSizeEx"); pStrFormatKBSizeA = (void *)GetProcAddress(hShlwapi, "StrFormatKBSizeA"); pStrFormatKBSizeW = (void *)GetProcAddress(hShlwapi, "StrFormatKBSizeW"); pStrIsIntlEqualA = (void *)GetProcAddress(hShlwapi, "StrIsIntlEqualA"); @@ -1680,6 +1990,7 @@ START_TEST(string) if (is_lang_english() && is_locale_english()) { test_StrFormatByteSize64A(); + test_StrFormatByteSizeEx(); test_StrFormatKBSizeA(); test_StrFormatKBSizeW(); } @@ -1706,6 +2017,7 @@ START_TEST(string) test_StrStrNW(); test_StrStrNIW(); test_StrCatChainW(); + test_printf_format(); CoUninitialize(); } diff --git a/modules/rostests/winetests/shlwapi/thread.c b/modules/rostests/winetests/shlwapi/thread.c index 34eb98ca607..65a13a3ef49 100644 --- a/modules/rostests/winetests/shlwapi/thread.c +++ b/modules/rostests/winetests/shlwapi/thread.c @@ -104,44 +104,44 @@ static void test_SHCreateThreadRef(void) /* start with a clean state */ hr = pSHSetThreadRef(NULL); - ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr); + ok(hr == S_OK, "got 0x%lx (expected S_OK)\n", hr); pobj = NULL; refcount = 0xdeadbeef; hr = pSHCreateThreadRef(&refcount, &pobj); ok((hr == S_OK) && pobj && (refcount == 1), - "got 0x%x and %p with %d (expected S_OK and '!= NULL' with 1)\n", + "got 0x%lx and %p with %ld (expected S_OK and '!= NULL' with 1)\n", hr, pobj, refcount); /* the object is not automatic set as ThreadRef */ punk = NULL; hr = pSHGetThreadRef(&punk); ok( (hr == E_NOINTERFACE) && (punk == NULL), - "got 0x%x and %p (expected E_NOINTERFACE and NULL)\n", hr, punk); + "got 0x%lx and %p (expected E_NOINTERFACE and NULL)\n", hr, punk); /* set the object */ hr = pSHSetThreadRef(pobj); - ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr); + ok(hr == S_OK, "got 0x%lx (expected S_OK)\n", hr); /* read back */ punk = NULL; hr = pSHGetThreadRef(&punk); ok( (hr == S_OK) && (punk == pobj) && (refcount == 2), - "got 0x%x and %p with %d (expected S_OK and %p with 2)\n", + "got 0x%lx and %p with %ld (expected S_OK and %p with 2)\n", hr, punk, refcount, pobj); /* free the ref from SHGetThreadRef */ if (SUCCEEDED(hr)) { hr = IUnknown_Release(pobj); ok((hr == 1) && (hr == refcount), - "got %d with %d (expected 1 with 1)\n", hr, refcount); + "got %ld with %ld (expected 1 with 1)\n", hr, refcount); } /* free the object */ if (pobj) { hr = IUnknown_Release(pobj); ok((hr == 0) && (hr == refcount), - "got %d with %d (expected 0 with 0)\n", hr, refcount); + "got %ld with %ld (expected 0 with 0)\n", hr, refcount); } if (0) { @@ -149,25 +149,25 @@ static void test_SHCreateThreadRef(void) but the object no longer exist after the *_Release */ punk = NULL; hr = pSHGetThreadRef(&punk); - trace("got 0x%x and %p with %d\n", hr, punk, refcount); + trace("got 0x%lx and %p with %ld\n", hr, punk, refcount); } /* remove the dead object pointer */ hr = pSHSetThreadRef(NULL); - ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr); + ok(hr == S_OK, "got 0x%lx (expected S_OK)\n", hr); /* parameter check */ if (0) { /* vista: E_INVALIDARG, XP: crash */ pobj = NULL; hr = pSHCreateThreadRef(NULL, &pobj); - ok(hr == E_INVALIDARG, "got 0x%x (expected E_INVALIDARG)\n", hr); + ok(hr == E_INVALIDARG, "got 0x%lx (expected E_INVALIDARG)\n", hr); refcount = 0xdeadbeef; /* vista: E_INVALIDARG, XP: crash */ hr = pSHCreateThreadRef(&refcount, NULL); ok( (hr == E_INVALIDARG) && (refcount == 0xdeadbeef), - "got 0x%x with 0x%x (expected E_INVALIDARG and oxdeadbeef)\n", + "got 0x%lx with 0x%lx (expected E_INVALIDARG and oxdeadbeef)\n", hr, refcount); } } @@ -187,7 +187,7 @@ static void test_SHGetThreadRef(void) punk = NULL; hr = pSHGetThreadRef(&punk); ok( (hr == E_NOINTERFACE) && (punk == NULL), - "got 0x%x and %p (expected E_NOINTERFACE and NULL)\n", hr, punk); + "got 0x%lx and %p (expected E_NOINTERFACE and NULL)\n", hr, punk); if (0) { /* this crash on Windows */ @@ -210,7 +210,7 @@ static void test_SHSetThreadRef(void) /* start with a clean state */ hr = pSHSetThreadRef(NULL); - ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr); + ok(hr == S_OK, "got 0x%lx (expected S_OK)\n", hr); /* build and set out object */ init_threadref(&ref, &refcount); @@ -218,7 +218,7 @@ static void test_SHSetThreadRef(void) refcount = 1; hr = pSHSetThreadRef(&ref.IUnknown_iface); ok( (hr == S_OK) && (refcount == 1) && (!AddRef_called), - "got 0x%x with %d, %d (expected S_OK with 1, 0)\n", + "got 0x%lx with %ld, %ld (expected S_OK with 1, 0)\n", hr, refcount, AddRef_called); /* read back our object */ @@ -227,17 +227,17 @@ static void test_SHSetThreadRef(void) punk = NULL; hr = pSHGetThreadRef(&punk); ok( (hr == S_OK) && (punk == &ref.IUnknown_iface) && (refcount == 2) && (AddRef_called == 1), - "got 0x%x and %p with %d, %d (expected S_OK and %p with 2, 1)\n", + "got 0x%lx and %p with %ld, %ld (expected S_OK and %p with 2, 1)\n", hr, punk, refcount, AddRef_called, &ref); /* clear the object pointer */ hr = pSHSetThreadRef(NULL); - ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr); + ok(hr == S_OK, "got 0x%lx (expected S_OK)\n", hr); /* verify, that our object is no longer known as ThreadRef */ hr = pSHGetThreadRef(&punk); ok( (hr == E_NOINTERFACE) && (punk == NULL), - "got 0x%x and %p (expected E_NOINTERFACE and NULL)\n", hr, punk); + "got 0x%lx and %p (expected E_NOINTERFACE and NULL)\n", hr, punk); } diff --git a/modules/rostests/winetests/shlwapi/url.c b/modules/rostests/winetests/shlwapi/url.c index 14473f624f3..501aa63e8d5 100644 --- a/modules/rostests/winetests/shlwapi/url.c +++ b/modules/rostests/winetests/shlwapi/url.c @@ -28,338 +28,163 @@ #include "shlwapi.h" #include "wininet.h" #include "intshcut.h" - -/* ################ */ -static HMODULE hShlwapi; -static HRESULT (WINAPI *pUrlUnescapeA)(LPSTR,LPSTR,LPDWORD,DWORD); -static HRESULT (WINAPI *pUrlUnescapeW)(LPWSTR,LPWSTR,LPDWORD,DWORD); -static BOOL (WINAPI *pUrlIsA)(LPCSTR,URLIS); -static BOOL (WINAPI *pUrlIsW)(LPCWSTR,URLIS); -static HRESULT (WINAPI *pUrlHashA)(LPCSTR,LPBYTE,DWORD); -static HRESULT (WINAPI *pUrlHashW)(LPCWSTR,LPBYTE,DWORD); -static HRESULT (WINAPI *pUrlGetPartA)(LPCSTR,LPSTR,LPDWORD,DWORD,DWORD); -static HRESULT (WINAPI *pUrlGetPartW)(LPCWSTR,LPWSTR,LPDWORD,DWORD,DWORD); -static HRESULT (WINAPI *pUrlEscapeA)(LPCSTR,LPSTR,LPDWORD,DWORD); -static HRESULT (WINAPI *pUrlEscapeW)(LPCWSTR,LPWSTR,LPDWORD,DWORD); -static HRESULT (WINAPI *pUrlCreateFromPathA)(LPCSTR,LPSTR,LPDWORD,DWORD); -static HRESULT (WINAPI *pUrlCreateFromPathW)(LPCWSTR,LPWSTR,LPDWORD,DWORD); -static HRESULT (WINAPI *pUrlCombineA)(LPCSTR,LPCSTR,LPSTR,LPDWORD,DWORD); -static HRESULT (WINAPI *pUrlCombineW)(LPCWSTR,LPCWSTR,LPWSTR,LPDWORD,DWORD); -static HRESULT (WINAPI *pUrlCanonicalizeA)(LPCSTR, LPSTR, LPDWORD, DWORD); -static HRESULT (WINAPI *pUrlCanonicalizeW)(LPCWSTR, LPWSTR, LPDWORD, DWORD); -static HRESULT (WINAPI *pUrlApplySchemeA)(LPCSTR,LPSTR,LPDWORD,DWORD); -static HRESULT (WINAPI *pUrlApplySchemeW)(LPCWSTR,LPWSTR,LPDWORD,DWORD); -static HRESULT (WINAPI *pParseURLA)(LPCSTR,PARSEDURLA*); -static HRESULT (WINAPI *pParseURLW)(LPCWSTR,PARSEDURLW*); -static HRESULT (WINAPI *pHashData)(LPBYTE, DWORD, LPBYTE, DWORD); +#include "winternl.h" static const char* TEST_URL_1 = "http://www.winehq.org/tests?date=10/10/1923"; static const char* TEST_URL_2 = "http://localhost:8080/tests%2e.html?date=Mon%2010/10/1923"; static const char* TEST_URL_3 = "http://foo:bar@localhost:21/internal.php?query=x&return=y"; -static const char* TEST_URL_4 = "http://foo:bar@google.*.com:21/internal.php?query=x&return=y"; - -static const WCHAR winehqW[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g','/',0}; -static const CHAR winehqA[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g','/',0}; - -/* ################ */ +static const WCHAR winehqW[] = L"http://www.winehq.org/"; +static const char winehqA[] = "http://www.winehq.org/"; static const CHAR untouchedA[] = "untouched"; -#define TEST_APPLY_MAX_LENGTH INTERNET_MAX_URL_LENGTH - typedef struct _TEST_URL_APPLY { const char * url; DWORD flags; HRESULT res; - DWORD newlen; const char * newurl; } TEST_URL_APPLY; static const TEST_URL_APPLY TEST_APPLY[] = { - {"www.winehq.org", URL_APPLY_GUESSSCHEME | URL_APPLY_DEFAULT, S_OK, 21, "http://www.winehq.org"}, - {"www.winehq.org", URL_APPLY_GUESSSCHEME, S_OK, 21, "http://www.winehq.org"}, - {"www.winehq.org", URL_APPLY_DEFAULT, S_OK, 21, "http://www.winehq.org"}, - {"ftp.winehq.org", URL_APPLY_GUESSSCHEME | URL_APPLY_DEFAULT, S_OK, 20, "ftp://ftp.winehq.org"}, - {"ftp.winehq.org", URL_APPLY_GUESSSCHEME, S_OK, 20, "ftp://ftp.winehq.org"}, - {"ftp.winehq.org", URL_APPLY_DEFAULT, S_OK, 21, "http://ftp.winehq.org"}, - {"winehq.org", URL_APPLY_GUESSSCHEME | URL_APPLY_DEFAULT, S_OK, 17, "http://winehq.org"}, - {"winehq.org", URL_APPLY_GUESSSCHEME, S_FALSE, TEST_APPLY_MAX_LENGTH, untouchedA}, - {"winehq.org", URL_APPLY_DEFAULT, S_OK, 17, "http://winehq.org"}, - {"http://www.winehq.org", URL_APPLY_GUESSSCHEME , S_FALSE, TEST_APPLY_MAX_LENGTH, untouchedA}, - {"http://www.winehq.org", URL_APPLY_GUESSSCHEME | URL_APPLY_FORCEAPPLY, S_FALSE, TEST_APPLY_MAX_LENGTH, untouchedA}, - {"http://www.winehq.org", URL_APPLY_GUESSSCHEME | URL_APPLY_FORCEAPPLY | URL_APPLY_DEFAULT, S_OK, 28, "http://http://www.winehq.org"}, - {"http://www.winehq.org", URL_APPLY_GUESSSCHEME | URL_APPLY_DEFAULT, S_FALSE, TEST_APPLY_MAX_LENGTH, untouchedA}, - {"", URL_APPLY_GUESSSCHEME | URL_APPLY_DEFAULT, S_OK, 7, "http://"}, - {"", URL_APPLY_GUESSSCHEME, S_FALSE, TEST_APPLY_MAX_LENGTH, untouchedA}, - {"", URL_APPLY_DEFAULT, S_OK, 7, "http://"}, - {"u:\\windows", URL_APPLY_GUESSFILE | URL_APPLY_DEFAULT, S_OK, 18, "file:///u:/windows"}, - {"u:\\windows", URL_APPLY_GUESSFILE, S_OK, 18, "file:///u:/windows"}, - {"u:\\windows", URL_APPLY_DEFAULT, S_OK, 17, "http://u:\\windows"}, - {"file:///c:/windows", URL_APPLY_GUESSFILE , S_FALSE, TEST_APPLY_MAX_LENGTH, untouchedA}, - {"aa:\\windows", URL_APPLY_GUESSFILE , S_FALSE, TEST_APPLY_MAX_LENGTH, untouchedA}, + {"www.winehq.org", URL_APPLY_GUESSSCHEME | URL_APPLY_DEFAULT, S_OK, "http://www.winehq.org"}, + {"www.winehq.org", URL_APPLY_GUESSSCHEME, S_OK, "http://www.winehq.org"}, + {"www.winehq.org", URL_APPLY_DEFAULT, S_OK, "http://www.winehq.org"}, + {"ftp.winehq.org", URL_APPLY_GUESSSCHEME | URL_APPLY_DEFAULT, S_OK, "ftp://ftp.winehq.org"}, + {"ftp.winehq.org", URL_APPLY_GUESSSCHEME, S_OK, "ftp://ftp.winehq.org"}, + {"ftp.winehq.org", URL_APPLY_DEFAULT, S_OK, "http://ftp.winehq.org"}, + {"winehq.org", URL_APPLY_GUESSSCHEME | URL_APPLY_DEFAULT, S_OK, "http://winehq.org"}, + {"winehq.org", URL_APPLY_GUESSSCHEME, S_FALSE}, + {"winehq.org", URL_APPLY_DEFAULT, S_OK, "http://winehq.org"}, + {"http://www.winehq.org", URL_APPLY_GUESSSCHEME, S_FALSE}, + {"http://www.winehq.org", URL_APPLY_GUESSSCHEME | URL_APPLY_FORCEAPPLY, S_FALSE}, + {"http://www.winehq.org", URL_APPLY_GUESSSCHEME | URL_APPLY_FORCEAPPLY | URL_APPLY_DEFAULT, S_OK, "http://http://www.winehq.org"}, + {"http://www.winehq.org", URL_APPLY_GUESSSCHEME | URL_APPLY_DEFAULT, S_FALSE}, + {"", URL_APPLY_GUESSSCHEME | URL_APPLY_DEFAULT, S_OK, "http://"}, + {"", URL_APPLY_GUESSSCHEME, S_FALSE}, + {"", URL_APPLY_DEFAULT, S_OK, "http://"}, + {"u:\\windows", URL_APPLY_GUESSFILE | URL_APPLY_DEFAULT, S_OK, "file:///u:/windows"}, + {"u:\\windows", URL_APPLY_GUESSFILE, S_OK, "file:///u:/windows"}, + {"u:\\windows", URL_APPLY_DEFAULT, S_OK, "http://u:\\windows"}, + {"file:///c:/windows", URL_APPLY_GUESSFILE, S_FALSE}, + {"aa:\\windows", URL_APPLY_GUESSFILE, S_FALSE}, + {"\\\\server\\share", URL_APPLY_DEFAULT, S_OK, "http://\\\\server\\share"}, + {"\\\\server\\share", URL_APPLY_GUESSFILE, S_OK, "file://server/share"}, + {"\\\\server\\share", URL_APPLY_GUESSSCHEME, S_FALSE}, + {"file://server/share", URL_APPLY_GUESSFILE, S_FALSE}, + {"file://server/share", URL_APPLY_GUESSSCHEME, S_FALSE}, }; -/* ################ */ - -typedef struct _TEST_URL_CANONICALIZE { - const char *url; - DWORD flags; - HRESULT expectret; - const char *expecturl; - BOOL todo; -} TEST_URL_CANONICALIZE; - -static const TEST_URL_CANONICALIZE TEST_CANONICALIZE[] = { - {"http://www.winehq.org/tests/../tests/../..", 0, S_OK, "http://www.winehq.org/", TRUE}, - {"http://www.winehq.org/..", 0, S_OK, "http://www.winehq.org/..", FALSE}, - {"http://www.winehq.org/tests/tests2/../../tests", 0, S_OK, "http://www.winehq.org/tests", FALSE}, - {"http://www.winehq.org/tests/../tests", 0, S_OK, "http://www.winehq.org/tests", FALSE}, - {"http://www.winehq.org/tests\n", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, S_OK, "http://www.winehq.org/tests", FALSE}, - {"http://www.winehq.org/tests\r", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, S_OK, "http://www.winehq.org/tests", FALSE}, - {"http://www.winehq.org/tests\r", 0, S_OK, "http://www.winehq.org/tests", FALSE}, - {"http://www.winehq.org/tests\r", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests", FALSE}, - {"http://www.winehq.org/tests/../tests/", 0, S_OK, "http://www.winehq.org/tests/", FALSE}, - {"http://www.winehq.org/tests/../tests/..", 0, S_OK, "http://www.winehq.org/", FALSE}, - {"http://www.winehq.org/tests/../tests/../", 0, S_OK, "http://www.winehq.org/", FALSE}, - {"http://www.winehq.org/tests/..", 0, S_OK, "http://www.winehq.org/", FALSE}, - {"http://www.winehq.org/tests/../", 0, S_OK, "http://www.winehq.org/", FALSE}, - {"http://www.winehq.org/tests/..?query=x&return=y", 0, S_OK, "http://www.winehq.org/?query=x&return=y", FALSE}, - {"http://www.winehq.org/tests/../?query=x&return=y", 0, S_OK, "http://www.winehq.org/?query=x&return=y", FALSE}, - {"\tht\ttp\t://www\t.w\tineh\t\tq.or\tg\t/\ttests/..\t?\tquer\ty=x\t\t&re\tturn=y\t\t", 0, S_OK, "http://www.winehq.org/?query=x&return=y", FALSE}, - {"http://www.winehq.org/tests/..#example", 0, S_OK, "http://www.winehq.org/#example", FALSE}, - {"http://www.winehq.org/tests/../#example", 0, S_OK, "http://www.winehq.org/#example", FALSE}, - {"http://www.winehq.org/tests\\../#example", 0, S_OK, "http://www.winehq.org/#example", FALSE}, - {"http://www.winehq.org/tests/..\\#example", 0, S_OK, "http://www.winehq.org/#example", FALSE}, - {"http://www.winehq.org\\tests/../#example", 0, S_OK, "http://www.winehq.org/#example", FALSE}, - {"http://www.winehq.org/tests/../#example", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests/../#example", FALSE}, - {"http://www.winehq.org/tests/foo bar", URL_ESCAPE_SPACES_ONLY| URL_DONT_ESCAPE_EXTRA_INFO , S_OK, "http://www.winehq.org/tests/foo%20bar", FALSE}, - {"http://www.winehq.org/tests/foo%20bar", URL_UNESCAPE , S_OK, "http://www.winehq.org/tests/foo bar", FALSE}, - {"http://www.winehq.org", 0, S_OK, "http://www.winehq.org/", FALSE}, - {"http:///www.winehq.org", 0, S_OK, "http:///www.winehq.org", FALSE}, - {"http:////www.winehq.org", 0, S_OK, "http:////www.winehq.org", FALSE}, - {"file:///c:/tests/foo%20bar", URL_UNESCAPE , S_OK, "file:///c:/tests/foo bar", FALSE}, - {"file:///c:/tests\\foo%20bar", URL_UNESCAPE , S_OK, "file:///c:/tests/foo bar", FALSE}, - {"file:///c:/tests/foo%20bar", 0, S_OK, "file:///c:/tests/foo%20bar", FALSE}, - {"file:///c:/tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar", FALSE}, - {"file://localhost/c:/tests/../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar", FALSE}, - {"file://localhost\\c:/tests/../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar", FALSE}, - {"file://localhost\\\\c:/tests/../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar", FALSE}, - {"file://localhost\\c:\\tests/../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar", FALSE}, - {"file://c:/tests/../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar", FALSE}, - {"file://c:/tests\\../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar", FALSE}, - {"file://c:/tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar", FALSE}, - {"file:///c://tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\\\tests\\foo bar", FALSE}, - {"file:///c:\\tests\\foo bar", 0, S_OK, "file:///c:/tests/foo bar", FALSE}, - {"file:///c:\\tests\\foo bar", URL_DONT_SIMPLIFY, S_OK, "file:///c:/tests/foo bar", FALSE}, - {"file:///c:\\tests\\foobar", 0, S_OK, "file:///c:/tests/foobar", FALSE}, - {"file:///c:\\tests\\foobar", URL_WININET_COMPATIBILITY, S_OK, "file://c:\\tests\\foobar", FALSE}, - {"file://home/user/file", 0, S_OK, "file://home/user/file", FALSE}, - {"file:///home/user/file", 0, S_OK, "file:///home/user/file", FALSE}, - {"file:////home/user/file", 0, S_OK, "file://home/user/file", FALSE}, - {"file://home/user/file", URL_WININET_COMPATIBILITY, S_OK, "file://\\\\home\\user\\file", FALSE}, - {"file:///home/user/file", URL_WININET_COMPATIBILITY, S_OK, "file://\\home\\user\\file", FALSE}, - {"file:////home/user/file", URL_WININET_COMPATIBILITY, S_OK, "file://\\\\home\\user\\file", FALSE}, - {"file://///home/user/file", URL_WININET_COMPATIBILITY, S_OK, "file://\\\\home\\user\\file", FALSE}, - {"file://C:/user/file", 0, S_OK, "file:///C:/user/file", FALSE}, - {"file://C:/user/file/../asdf", 0, S_OK, "file:///C:/user/asdf", FALSE}, - {"file:///C:/user/file", 0, S_OK, "file:///C:/user/file", FALSE}, - {"file:////C:/user/file", 0, S_OK, "file:///C:/user/file", FALSE}, - {"file://C:/user/file", URL_WININET_COMPATIBILITY, S_OK, "file://C:\\user\\file", FALSE}, - {"file:///C:/user/file", URL_WININET_COMPATIBILITY, S_OK, "file://C:\\user\\file", FALSE}, - {"file:////C:/user/file", URL_WININET_COMPATIBILITY, S_OK, "file://C:\\user\\file", FALSE}, - {"http:///www.winehq.org", 0, S_OK, "http:///www.winehq.org", FALSE}, - {"http:///www.winehq.org", URL_WININET_COMPATIBILITY, S_OK, "http:///www.winehq.org", FALSE}, - {"http://www.winehq.org/site/about", URL_FILE_USE_PATHURL, S_OK, "http://www.winehq.org/site/about", FALSE}, - {"file_://www.winehq.org/site/about", URL_FILE_USE_PATHURL, S_OK, "file_://www.winehq.org/site/about", FALSE}, - {"c:\\dir\\file", 0, S_OK, "file:///c:/dir/file", FALSE}, - {"file:///c:\\dir\\file", 0, S_OK, "file:///c:/dir/file", FALSE}, - {"c:dir\\file", 0, S_OK, "file:///c:dir/file", FALSE}, - {"c:\\tests\\foo bar", URL_FILE_USE_PATHURL, S_OK, "file://c:\\tests\\foo bar", FALSE}, - {"c:\\tests\\foo bar", 0, S_OK, "file:///c:/tests/foo%20bar", FALSE}, - {"c\t:\t\\te\tsts\\fo\to \tbar\t", 0, S_OK, "file:///c:/tests/foo%20bar", FALSE}, - {"res://file", 0, S_OK, "res://file/", FALSE}, - {"res://file", URL_FILE_USE_PATHURL, S_OK, "res://file/", FALSE}, - {"res:///c:/tests/foo%20bar", URL_UNESCAPE , S_OK, "res:///c:/tests/foo bar", FALSE}, - {"res:///c:/tests\\foo%20bar", URL_UNESCAPE , S_OK, "res:///c:/tests\\foo bar", FALSE}, - {"res:///c:/tests/foo%20bar", 0, S_OK, "res:///c:/tests/foo%20bar", FALSE}, - {"res:///c:/tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "res:///c:/tests/foo%20bar", FALSE}, - {"res://c:/tests/../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "res://c:/tests/foo%20bar", FALSE}, - {"res://c:/tests\\../tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "res://c:/tests/foo%20bar", FALSE}, - {"res://c:/tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "res://c:/tests/foo%20bar", FALSE}, - {"res:///c://tests/foo%20bar", URL_FILE_USE_PATHURL, S_OK, "res:///c://tests/foo%20bar", FALSE}, - {"res:///c:\\tests\\foo bar", 0, S_OK, "res:///c:\\tests\\foo bar", FALSE}, - {"res:///c:\\tests\\foo bar", URL_DONT_SIMPLIFY, S_OK, "res:///c:\\tests\\foo bar", FALSE}, - {"res://c:\\tests\\foo bar/res", URL_FILE_USE_PATHURL, S_OK, "res://c:\\tests\\foo bar/res", FALSE}, - {"res://c:\\tests/res\\foo%20bar/strange\\sth", 0, S_OK, "res://c:\\tests/res\\foo%20bar/strange\\sth", FALSE}, - {"res://c:\\tests/res\\foo%20bar/strange\\sth", URL_FILE_USE_PATHURL, S_OK, "res://c:\\tests/res\\foo%20bar/strange\\sth", FALSE}, - {"res://c:\\tests/res\\foo%20bar/strange\\sth", URL_UNESCAPE, S_OK, "res://c:\\tests/res\\foo bar/strange\\sth", FALSE}, - {"/A/../B/./C/../../test_remove_dot_segments", 0, S_OK, "/test_remove_dot_segments", FALSE}, - {"/A/../B/./C/../../test_remove_dot_segments", URL_FILE_USE_PATHURL, S_OK, "/test_remove_dot_segments", FALSE}, - {"/A/../B/./C/../../test_remove_dot_segments", URL_WININET_COMPATIBILITY, S_OK, "/test_remove_dot_segments", FALSE}, - {"/A/B\\C/D\\E", 0, S_OK, "/A/B\\C/D\\E", FALSE}, - {"/A/B\\C/D\\E", URL_FILE_USE_PATHURL, S_OK, "/A/B\\C/D\\E", FALSE}, - {"/A/B\\C/D\\E", URL_WININET_COMPATIBILITY, S_OK, "/A/B\\C/D\\E", FALSE}, - {"///A/../B", 0, S_OK, "///B", FALSE}, - {"///A/../B", URL_FILE_USE_PATHURL, S_OK, "///B", FALSE}, - {"///A/../B", URL_WININET_COMPATIBILITY, S_OK, "///B", FALSE}, - {"A", 0, S_OK, "A", FALSE}, - {"../A", 0, S_OK, "../A", FALSE}, - {"./A", 0, S_OK, "A", FALSE}, - {"./A/./B", 0, S_OK, "A/B", FALSE}, - {"./A", URL_DONT_SIMPLIFY, S_OK, "./A", FALSE}, - {"A/./B", 0, S_OK, "A/B", TRUE}, - {"A/../B", 0, S_OK, "B", TRUE}, - {"A/../B/./../C", 0, S_OK, "C", TRUE}, - {"A/../B/./../C", URL_DONT_SIMPLIFY, S_OK, "A/../B/./../C", FALSE}, - {".\\A", 0, S_OK, ".\\A", FALSE}, - {"A\\.\\B", 0, S_OK, "A\\.\\B", FALSE}, - {".", 0, S_OK, "/", TRUE}, - {"./A", 0, S_OK, "A", TRUE}, - {"A/./B", 0, S_OK, "A/B", TRUE}, - {"/:test\\", 0, S_OK, "/:test\\", TRUE}, - {"/uri-res/N2R?urn:sha1:B3K", URL_DONT_ESCAPE_EXTRA_INFO | URL_WININET_COMPATIBILITY /*0x82000000*/, S_OK, "/uri-res/N2R?urn:sha1:B3K", FALSE} /*LimeWire online installer calls this*/, - {"http:www.winehq.org/dir/../index.html", 0, S_OK, "http:www.winehq.org/index.html"}, - {"http://localhost/test.html", URL_FILE_USE_PATHURL, S_OK, "http://localhost/test.html"}, - {"http://localhost/te%20st.html", URL_FILE_USE_PATHURL, S_OK, "http://localhost/te%20st.html"}, - {"http://www.winehq.org/%E6%A1%9C.html", URL_FILE_USE_PATHURL, S_OK, "http://www.winehq.org/%E6%A1%9C.html"}, - {"mk:@MSITStore:C:\\Program Files/AutoCAD 2008\\Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm", 0, S_OK, "mk:@MSITStore:C:\\Program Files/AutoCAD 2008\\Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm"}, - {"ftp:@MSITStore:C:\\Program Files/AutoCAD 2008\\Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm", 0, S_OK, "ftp:@MSITStore:C:\\Program Files/AutoCAD 2008\\Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm"}, - {"file:@MSITStore:C:\\Program Files/AutoCAD 2008\\Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm", 0, S_OK, "file:@MSITStore:C:/Program Files/AutoCAD 2008/Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm"}, - {"http:@MSITStore:C:\\Program Files/AutoCAD 2008\\Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm", 0, S_OK, "http:@MSITStore:C:/Program Files/AutoCAD 2008/Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm"}, - {"http:@MSITStore:C:\\Program Files/AutoCAD 2008\\Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm", URL_FILE_USE_PATHURL, S_OK, "http:@MSITStore:C:/Program Files/AutoCAD 2008/Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm"}, - {"mk:@MSITStore:C:\\Program Files/AutoCAD 2008\\Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm", URL_FILE_USE_PATHURL, S_OK, "mk:@MSITStore:C:\\Program Files/AutoCAD 2008\\Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm"}, -}; - -/* ################ */ - typedef struct _TEST_URL_ESCAPE { const char *url; DWORD flags; - DWORD expectescaped; - HRESULT expectret; const char *expecturl; } TEST_URL_ESCAPE; static const TEST_URL_ESCAPE TEST_ESCAPE[] = { - {"http://www.winehq.org/tests0", 0, 0, S_OK, "http://www.winehq.org/tests0"}, - {"http://www.winehq.org/tests1\n", 0, 0, S_OK, "http://www.winehq.org/tests1%0A"}, - {"http://www.winehq.org/tests2\r", 0, 0, S_OK, "http://www.winehq.org/tests2%0D"}, - {"http://www.winehq.org/tests3\r", URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, 0, S_OK, "http://www.winehq.org/tests3\r"}, - {"http://www.winehq.org/tests4\r", URL_ESCAPE_SPACES_ONLY, 0, S_OK, "http://www.winehq.org/tests4\r"}, - {"http://www.winehq.org/tests5\r", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY, 0, S_OK, "http://www.winehq.org/tests5\r"}, - {"/direct/swhelp/series6/6.2i_latestservicepack.dat\r", URL_ESCAPE_SPACES_ONLY, 0, S_OK, "/direct/swhelp/series6/6.2i_latestservicepack.dat\r"}, + {"http://www.winehq.org/tests0", 0, "http://www.winehq.org/tests0"}, + {"http://www.winehq.org/tests1\n", 0, "http://www.winehq.org/tests1%0A"}, + {"http://www.winehq.org/tests2\r", 0, "http://www.winehq.org/tests2%0D"}, + {"http://www.winehq.org/tests3\r", URL_ESCAPE_SPACES_ONLY|URL_ESCAPE_UNSAFE, "http://www.winehq.org/tests3\r"}, + {"http://www.winehq.org/tests4\r", URL_ESCAPE_SPACES_ONLY, "http://www.winehq.org/tests4\r"}, + {"http://www.winehq.org/tests5\r", URL_WININET_COMPATIBILITY|URL_ESCAPE_SPACES_ONLY, "http://www.winehq.org/tests5\r"}, + {"/direct/swhelp/series6/6.2i_latestservicepack.dat\r", URL_ESCAPE_SPACES_ONLY, "/direct/swhelp/series6/6.2i_latestservicepack.dat\r"}, - {"file://////foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"}, - {"file://///foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"}, - {"file:////foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"}, - {"file:///localhost/foo/bar\\baz", 0, 0, S_OK, "file:///localhost/foo/bar/baz"}, - {"file:///foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"}, - {"file://loCalHost/foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"}, - {"file://foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"}, - {"file:/localhost/foo/bar\\baz", 0, 0, S_OK, "file:///localhost/foo/bar/baz"}, - {"file:/foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"}, - {"file:foo/bar\\baz", 0, 0, S_OK, "file:foo/bar/baz"}, - {"file:\\foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"}, - {"file:\\\\foo/bar\\baz", 0, 0, S_OK, "file://foo/bar/baz"}, - {"file:\\\\\\foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"}, - {"file:\\\\localhost\\foo/bar\\baz", 0, 0, S_OK, "file:///foo/bar/baz"}, - {"file:///f oo/b?a r\\baz", 0, 0, S_OK, "file:///f%20oo/b?a r\\baz"}, - {"file:///foo/b#a r\\baz", 0, 0, S_OK, "file:///foo/b%23a%20r/baz"}, - {"file:///f o^&`{}|][\"<>\\%o/b#a r\\baz", 0, 0, S_OK, "file:///f%20o%5E%26%60%7B%7D%7C%5D%5B%22%3C%3E/%o/b%23a%20r/baz"}, - {"file:///f o%o/b?a r\\b%az", URL_ESCAPE_PERCENT, 0, S_OK, "file:///f%20o%25o/b?a r\\b%az"}, - {"file:/foo/bar\\baz", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "file:%2Ffoo%2Fbar%5Cbaz"}, + {"file://////foo/bar\\baz", 0, "file://foo/bar/baz"}, + {"file://///foo/bar\\baz", 0, "file://foo/bar/baz"}, + {"file:////foo/bar\\baz", 0, "file://foo/bar/baz"}, + {"file:///localhost/foo/bar\\baz", 0, "file:///localhost/foo/bar/baz"}, + {"file:///foo/bar\\baz", 0, "file:///foo/bar/baz"}, + {"file://loCalHost/foo/bar\\baz", 0, "file:///foo/bar/baz"}, + {"file://foo/bar\\baz", 0, "file://foo/bar/baz"}, + {"file:/localhost/foo/bar\\baz", 0, "file:///localhost/foo/bar/baz"}, + {"file:/foo/bar\\baz", 0, "file:///foo/bar/baz"}, + {"file:foo/bar\\baz", 0, "file:foo/bar/baz"}, + {"file:\\foo/bar\\baz", 0, "file:///foo/bar/baz"}, + {"file:\\\\foo/bar\\baz", 0, "file://foo/bar/baz"}, + {"file:\\\\\\foo/bar\\baz", 0, "file:///foo/bar/baz"}, + {"file:\\\\localhost\\foo/bar\\baz", 0, "file:///foo/bar/baz"}, + {"file:///f oo/b?a r\\baz", 0, "file:///f%20oo/b?a r\\baz"}, + {"file:///foo/b#a r\\baz", 0, "file:///foo/b%23a%20r/baz"}, + {"file:///f o^&`{}|][\"<>\\%o/b#a r\\baz", 0, "file:///f%20o%5E%26%60%7B%7D%7C%5D%5B%22%3C%3E/%o/b%23a%20r/baz"}, + {"file:///f o%o/b?a r\\b%az", URL_ESCAPE_PERCENT, "file:///f%20o%25o/b?a r\\b%az"}, + {"file:/foo/bar\\baz", URL_ESCAPE_SEGMENT_ONLY, "file:%2Ffoo%2Fbar%5Cbaz"}, - {"foo/b%ar\\ba?z\\", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "foo%2Fb%ar%5Cba%3Fz%5C"}, - {"foo/b%ar\\ba?z\\", URL_ESCAPE_PERCENT | URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "foo%2Fb%25ar%5Cba%3Fz%5C"}, - {"foo/bar\\ba?z\\", 0, 0, S_OK, "foo/bar%5Cba?z\\"}, - {"/foo/bar\\ba?z\\", 0, 0, S_OK, "/foo/bar%5Cba?z\\"}, - {"/foo/bar\\ba#z\\", 0, 0, S_OK, "/foo/bar%5Cba#z\\"}, - {"/foo/%5C", 0, 0, S_OK, "/foo/%5C"}, - {"/foo/%5C", URL_ESCAPE_PERCENT, 0, S_OK, "/foo/%255C"}, + {"foo/b%ar\\ba?z\\", URL_ESCAPE_SEGMENT_ONLY, "foo%2Fb%ar%5Cba%3Fz%5C"}, + {"foo/b%ar\\ba?z\\", URL_ESCAPE_PERCENT | URL_ESCAPE_SEGMENT_ONLY, "foo%2Fb%25ar%5Cba%3Fz%5C"}, + {"foo/bar\\ba?z\\", 0, "foo/bar%5Cba?z\\"}, + {"/foo/bar\\ba?z\\", 0, "/foo/bar%5Cba?z\\"}, + {"/foo/bar\\ba#z\\", 0, "/foo/bar%5Cba#z\\"}, + {"/foo/%5C", 0, "/foo/%5C"}, + {"/foo/%5C", URL_ESCAPE_PERCENT, "/foo/%255C"}, - {"http://////foo/bar\\baz", 0, 0, S_OK, "http://////foo/bar/baz"}, - {"http://///foo/bar\\baz", 0, 0, S_OK, "http://///foo/bar/baz"}, - {"http:////foo/bar\\baz", 0, 0, S_OK, "http:////foo/bar/baz"}, - {"http:///foo/bar\\baz", 0, 0, S_OK, "http:///foo/bar/baz"}, - {"http://localhost/foo/bar\\baz", 0, 0, S_OK, "http://localhost/foo/bar/baz"}, - {"http://foo/bar\\baz", 0, 0, S_OK, "http://foo/bar/baz"}, - {"http:/foo/bar\\baz", 0, 0, S_OK, "http:/foo/bar/baz"}, - {"http:foo/bar\\ba?z\\", 0, 0, S_OK, "http:foo%2Fbar%2Fba?z\\"}, - {"http:foo/bar\\ba#z\\", 0, 0, S_OK, "http:foo%2Fbar%2Fba#z\\"}, - {"http:\\foo/bar\\baz", 0, 0, S_OK, "http:/foo/bar/baz"}, - {"http:\\\\foo/bar\\baz", 0, 0, S_OK, "http://foo/bar/baz"}, - {"http:\\\\\\foo/bar\\baz", 0, 0, S_OK, "http:///foo/bar/baz"}, - {"http:\\\\\\\\foo/bar\\baz", 0, 0, S_OK, "http:////foo/bar/baz"}, - {"http:/fo ?o/b ar\\baz", 0, 0, S_OK, "http:/fo%20?o/b ar\\baz"}, - {"http:fo ?o/b ar\\baz", 0, 0, S_OK, "http:fo%20?o/b ar\\baz"}, - {"http:/foo/bar\\baz", URL_ESCAPE_SEGMENT_ONLY, 0, S_OK, "http:%2Ffoo%2Fbar%5Cbaz"}, + {"http://////foo/bar\\baz", 0, "http://////foo/bar/baz"}, + {"http://///foo/bar\\baz", 0, "http://///foo/bar/baz"}, + {"http:////foo/bar\\baz", 0, "http:////foo/bar/baz"}, + {"http:///foo/bar\\baz", 0, "http:///foo/bar/baz"}, + {"http://localhost/foo/bar\\baz", 0, "http://localhost/foo/bar/baz"}, + {"http://foo/bar\\baz", 0, "http://foo/bar/baz"}, + {"http:/foo/bar\\baz", 0, "http:/foo/bar/baz"}, + {"http:foo/bar\\ba?z\\", 0, "http:foo%2Fbar%2Fba?z\\"}, + {"http:foo/bar\\ba#z\\", 0, "http:foo%2Fbar%2Fba#z\\"}, + {"http:\\foo/bar\\baz", 0, "http:/foo/bar/baz"}, + {"http:\\\\foo/bar\\baz", 0, "http://foo/bar/baz"}, + {"http:\\\\\\foo/bar\\baz", 0, "http:///foo/bar/baz"}, + {"http:\\\\\\\\foo/bar\\baz", 0, "http:////foo/bar/baz"}, + {"http:/fo ?o/b ar\\baz", 0, "http:/fo%20?o/b ar\\baz"}, + {"http:fo ?o/b ar\\baz", 0, "http:fo%20?o/b ar\\baz"}, + {"http:/foo/bar\\baz", URL_ESCAPE_SEGMENT_ONLY, "http:%2Ffoo%2Fbar%5Cbaz"}, - {"https://foo/bar\\baz", 0, 0, S_OK, "https://foo/bar/baz"}, - {"https:/foo/bar\\baz", 0, 0, S_OK, "https:/foo/bar/baz"}, - {"https:\\foo/bar\\baz", 0, 0, S_OK, "https:/foo/bar/baz"}, + {"https://foo/bar\\baz", 0, "https://foo/bar/baz"}, + {"https:/foo/bar\\baz", 0, "https:/foo/bar/baz"}, + {"https:\\foo/bar\\baz", 0, "https:/foo/bar/baz"}, - {"foo:////foo/bar\\baz", 0, 0, S_OK, "foo:////foo/bar%5Cbaz"}, - {"foo:///foo/bar\\baz", 0, 0, S_OK, "foo:///foo/bar%5Cbaz"}, - {"foo://localhost/foo/bar\\baz", 0, 0, S_OK, "foo://localhost/foo/bar%5Cbaz"}, - {"foo://foo/bar\\baz", 0, 0, S_OK, "foo://foo/bar%5Cbaz"}, - {"foo:/foo/bar\\baz", 0, 0, S_OK, "foo:/foo/bar%5Cbaz"}, - {"foo:foo/bar\\baz", 0, 0, S_OK, "foo:foo%2Fbar%5Cbaz"}, - {"foo:\\foo/bar\\baz", 0, 0, S_OK, "foo:%5Cfoo%2Fbar%5Cbaz"}, - {"foo:/foo/bar\\ba?\\z", 0, 0, S_OK, "foo:/foo/bar%5Cba?\\z"}, - {"foo:/foo/bar\\ba#\\z", 0, 0, S_OK, "foo:/foo/bar%5Cba#\\z"}, + {"foo:////foo/bar\\baz", 0, "foo:////foo/bar%5Cbaz"}, + {"foo:///foo/bar\\baz", 0, "foo:///foo/bar%5Cbaz"}, + {"foo://localhost/foo/bar\\baz", 0, "foo://localhost/foo/bar%5Cbaz"}, + {"foo://foo/bar\\baz", 0, "foo://foo/bar%5Cbaz"}, + {"foo:/foo/bar\\baz", 0, "foo:/foo/bar%5Cbaz"}, + {"foo:foo/bar\\baz", 0, "foo:foo%2Fbar%5Cbaz"}, + {"foo:\\foo/bar\\baz", 0, "foo:%5Cfoo%2Fbar%5Cbaz"}, + {"foo:/foo/bar\\ba?\\z", 0, "foo:/foo/bar%5Cba?\\z"}, + {"foo:/foo/bar\\ba#\\z", 0, "foo:/foo/bar%5Cba#\\z"}, - {"mailto:/fo/o@b\\%a?\\r.b#\\az", 0, 0, S_OK, "mailto:%2Ffo%2Fo@b%5C%a%3F%5Cr.b%23%5Caz"}, - {"mailto:fo/o@b\\%a?\\r.b#\\az", 0, 0, S_OK, "mailto:fo%2Fo@b%5C%a%3F%5Cr.b%23%5Caz"}, - {"mailto:fo/o@b\\%a?\\r.b#\\az", URL_ESCAPE_PERCENT, 0, S_OK, "mailto:fo%2Fo@b%5C%25a%3F%5Cr.b%23%5Caz"}, + {"mailto:/fo/o@b\\%a?\\r.b#\\az", 0, "mailto:%2Ffo%2Fo@b%5C%a%3F%5Cr.b%23%5Caz"}, + {"mailto:fo/o@b\\%a?\\r.b#\\az", 0, "mailto:fo%2Fo@b%5C%a%3F%5Cr.b%23%5Caz"}, + {"mailto:fo/o@b\\%a?\\r.b#\\az", URL_ESCAPE_PERCENT, "mailto:fo%2Fo@b%5C%25a%3F%5Cr.b%23%5Caz"}, - {"ftp:fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:fo%2Fo@bar.baz%2Ffoo%2Fbar"}, - {"ftp:/fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:/fo/o@bar.baz/foo/bar"}, - {"ftp://fo/o@bar.baz/fo?o\\bar", 0, 0, S_OK, "ftp://fo/o@bar.baz/fo?o\\bar"}, - {"ftp://fo/o@bar.baz/fo#o\\bar", 0, 0, S_OK, "ftp://fo/o@bar.baz/fo#o\\bar"}, - {"ftp://localhost/o@bar.baz/fo#o\\bar", 0, 0, S_OK, "ftp://localhost/o@bar.baz/fo#o\\bar"}, - {"ftp:///fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:///fo/o@bar.baz/foo/bar"}, - {"ftp:////fo/o@bar.baz/foo/bar", 0, 0, S_OK, "ftp:////fo/o@bar.baz/foo/bar"}, + {"ftp:fo/o@bar.baz/foo/bar", 0, "ftp:fo%2Fo@bar.baz%2Ffoo%2Fbar"}, + {"ftp:/fo/o@bar.baz/foo/bar", 0, "ftp:/fo/o@bar.baz/foo/bar"}, + {"ftp://fo/o@bar.baz/fo?o\\bar", 0, "ftp://fo/o@bar.baz/fo?o\\bar"}, + {"ftp://fo/o@bar.baz/fo#o\\bar", 0, "ftp://fo/o@bar.baz/fo#o\\bar"}, + {"ftp://localhost/o@bar.baz/fo#o\\bar", 0, "ftp://localhost/o@bar.baz/fo#o\\bar"}, + {"ftp:///fo/o@bar.baz/foo/bar", 0, "ftp:///fo/o@bar.baz/foo/bar"}, + {"ftp:////fo/o@bar.baz/foo/bar", 0, "ftp:////fo/o@bar.baz/foo/bar"}, - {"ftp\x1f\1end/", 0, 0, S_OK, "ftp%1F%01end/"} + {"ftp\x1f\1end/", 0, "ftp%1F%01end/"} }; typedef struct _TEST_URL_ESCAPEW { const WCHAR url[INTERNET_MAX_URL_LENGTH]; DWORD flags; - HRESULT expectret; const WCHAR expecturl[INTERNET_MAX_URL_LENGTH]; const WCHAR win7url[INTERNET_MAX_URL_LENGTH]; /* <= Win7 */ - const WCHAR vistaurl[INTERNET_MAX_URL_LENGTH]; /* <= Vista/2k8 */ } TEST_URL_ESCAPEW; static const TEST_URL_ESCAPEW TEST_ESCAPEW[] = { - {{' ','<','>','"',0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','2','0','%','3','C','%','3','E','%','2','2',0}}, - {{'{','}','|','\\',0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','7','B','%','7','D','%','7','C','%','5','C',0}}, - {{'^',']','[','`',0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','5','E','%','5','D','%','5','B','%','6','0',0}}, - {{'&','/','?','#',0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','2','6','/','?','#',0}}, - {{'M','a','s','s',0}, URL_ESCAPE_AS_UTF8, S_OK, {'M','a','s','s',0}}, + {L" <>\"", URL_ESCAPE_AS_UTF8, L"%20%3C%3E%22"}, + {L"{}|\\", URL_ESCAPE_AS_UTF8, L"%7B%7D%7C%5C"}, + {L"^][`", URL_ESCAPE_AS_UTF8, L"%5E%5D%5B%60"}, + {L"&/?#", URL_ESCAPE_AS_UTF8, L"%26/?#"}, + {L"Mass", URL_ESCAPE_AS_UTF8, L"Mass"}, /* broken < Win8/10 */ - - {{'M','a',0xdf,0}, URL_ESCAPE_AS_UTF8, S_OK, {'M','a','%','C','3','%','9','F',0}, - {'M','a','%','D','F',0}}, - /* 0x2070E */ - {{0xd841,0xdf0e,0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','F','0','%','A','0','%','9','C','%','8','E',0}, - {'%','E','F','%','B','F','%','B','D','%','E','F','%','B','F','%','B','D',0}, - {0xd841,0xdf0e,0}}, - /* 0x27A3E */ - {{0xd85e,0xde3e,0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','F','0','%','A','7','%','A','8','%','B','E',0}, - {'%','E','F','%','B','F','%','B','D','%','E','F','%','B','F','%','B','D',0}, - {0xd85e,0xde3e,0}}, - - {{0xd85e,0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','E','F','%','B','F','%','B','D',0}, - {0xd85e,0}}, - {{0xd85e,0x41}, URL_ESCAPE_AS_UTF8, S_OK, {'%','E','F','%','B','F','%','B','D','A',0}, - {0xd85e,'A',0}}, - {{0xdc00,0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','E','F','%','B','F','%','B','D',0}, - {0xdc00,0}}, - {{0xffff,0}, URL_ESCAPE_AS_UTF8, S_OK, {'%','E','F','%','B','F','%','B','F',0}, - {0xffff,0}}, + {L"Ma\xdf", URL_ESCAPE_AS_UTF8, L"Ma%C3%9F", L"Ma%DF"}, + {L"\xd841\xdf0e", URL_ESCAPE_AS_UTF8, L"%F0%A0%9C%8E", L"%EF%BF%BD%EF%BF%BD"}, /* 0x2070E */ + {L"\xd85e\xde3e", URL_ESCAPE_AS_UTF8, L"%F0%A7%A8%BE", L"%EF%BF%BD%EF%BF%BD"}, /* 0x27A3E */ + {L"\xd85e", URL_ESCAPE_AS_UTF8, L"%EF%BF%BD", L"\xd85e"}, + {L"\xd85eQ", URL_ESCAPE_AS_UTF8, L"%EF%BF%BDQ", L"\xd85eQ"}, + {L"\xdc00", URL_ESCAPE_AS_UTF8, L"%EF%BF%BD", L"\xdc00"}, + {L"\xffff", URL_ESCAPE_AS_UTF8, L"%EF%BF%BF", L"\xffff"}, }; /* ################ */ @@ -368,80 +193,72 @@ typedef struct _TEST_URL_COMBINE { const char *url1; const char *url2; DWORD flags; - HRESULT expectret; const char *expecturl; - BOOL todo; } TEST_URL_COMBINE; static const TEST_URL_COMBINE TEST_COMBINE[] = { - {"http://www.winehq.org/tests", "tests1", 0, S_OK, "http://www.winehq.org/tests1"}, - {"http://www.%77inehq.org/tests", "tests1", 0, S_OK, "http://www.%77inehq.org/tests1"}, - /*FIXME {"http://www.winehq.org/tests", "../tests2", 0, S_OK, "http://www.winehq.org/tests2"},*/ - {"http://www.winehq.org/tests/", "../tests3", 0, S_OK, "http://www.winehq.org/tests3"}, - {"http://www.winehq.org/tests/test1", "test2", 0, S_OK, "http://www.winehq.org/tests/test2"}, - {"http://www.winehq.org/tests/../tests", "tests4", 0, S_OK, "http://www.winehq.org/tests4"}, - {"http://www.winehq.org/tests/../tests/", "tests5", 0, S_OK, "http://www.winehq.org/tests/tests5"}, - {"http://www.winehq.org/tests/../tests/", "/tests6/..", 0, S_OK, "http://www.winehq.org/"}, - {"http://www.winehq.org/tests/../tests/..", "tests7/..", 0, S_OK, "http://www.winehq.org/"}, - {"http://www.winehq.org/tests/?query=x&return=y", "tests8", 0, S_OK, "http://www.winehq.org/tests/tests8"}, - {"http://www.winehq.org/tests/#example", "tests9", 0, S_OK, "http://www.winehq.org/tests/tests9"}, - {"http://www.winehq.org/tests/../tests/", "/tests10/..", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests10/.."}, - {"http://www.winehq.org/tests/../", "tests11", URL_DONT_SIMPLIFY, S_OK, "http://www.winehq.org/tests/../tests11"}, - {"http://www.winehq.org/test12", "#", 0, S_OK, "http://www.winehq.org/test12#"}, - {"http://www.winehq.org/test13#aaa", "#bbb", 0, S_OK, "http://www.winehq.org/test13#bbb"}, - {"http://www.winehq.org/test14#aaa/bbb#ccc", "#", 0, S_OK, "http://www.winehq.org/test14#"}, - {"http://www.winehq.org/tests/?query=x/y/z", "tests15", 0, S_OK, "http://www.winehq.org/tests/tests15"}, - {"http://www.winehq.org/tests/?query=x/y/z#example", "tests16", 0, S_OK, "http://www.winehq.org/tests/tests16"}, - {"http://www.winehq.org/tests17", ".", 0, S_OK, "http://www.winehq.org/"}, - {"http://www.winehq.org/tests18/test", ".", 0, S_OK, "http://www.winehq.org/tests18/"}, - {"http://www.winehq.org/tests19/test", "./", 0, S_OK, "http://www.winehq.org/tests19/", FALSE}, - {"http://www.winehq.org/tests20/test", "/", 0, S_OK, "http://www.winehq.org/", FALSE}, - {"http://www.winehq.org/tests/test", "./test21", 0, S_OK, "http://www.winehq.org/tests/test21", FALSE}, - {"http://www.winehq.org/tests/test", "./test22/../test", 0, S_OK, "http://www.winehq.org/tests/test", FALSE}, - {"http://www.winehq.org/tests/", "http://www.winehq.org:80/tests23", 0, S_OK, "http://www.winehq.org/tests23", TRUE}, - {"http://www.winehq.org/tests/", "tests24/./test/../test", 0, S_OK, "http://www.winehq.org/tests/tests24/test", FALSE}, - {"http://www.winehq.org/tests/./tests25", "./", 0, S_OK, "http://www.winehq.org/tests/", FALSE}, - {"file:///C:\\dir\\file.txt", "test.txt", 0, S_OK, "file:///C:/dir/test.txt"}, - {"file:///C:\\dir\\file.txt#hash\\hash", "test.txt", 0, S_OK, "file:///C:/dir/file.txt#hash/test.txt"}, - {"file:///C:\\dir\\file.html#hash\\hash", "test.html", 0, S_OK, "file:///C:/dir/test.html"}, - {"file:///C:\\dir\\file.htm#hash\\hash", "test.htm", 0, S_OK, "file:///C:/dir/test.htm"}, - {"file:///C:\\dir\\file.hTmL#hash\\hash", "test.hTmL", 0, S_OK, "file:///C:/dir/test.hTmL"}, - {"file:///C:\\dir.html\\file.txt#hash\\hash", "test.txt", 0, S_OK, "file:///C:/dir.html/file.txt#hash/test.txt"}, - {"C:\\winehq\\winehq.txt", "C:\\Test\\test.txt", 0, S_OK, "file:///C:/Test/test.txt"}, - {"http://www.winehq.org/test/", "test%20file.txt", 0, S_OK, "http://www.winehq.org/test/test%20file.txt"}, - {"http://www.winehq.org/test/", "test%20file.txt", URL_FILE_USE_PATHURL, S_OK, "http://www.winehq.org/test/test%20file.txt"}, - {"http://www.winehq.org%2ftest/", "test%20file.txt", URL_FILE_USE_PATHURL, S_OK, "http://www.winehq.org%2ftest/test%20file.txt"}, - {"xxx:@MSITStore:file.chm/file.html", "dir/file", 0, S_OK, "xxx:dir/file"}, - {"mk:@MSITStore:file.chm::/file.html", "/dir/file", 0, S_OK, "mk:@MSITStore:file.chm::/dir/file"}, - {"mk:@MSITStore:file.chm::/file.html", "mk:@MSITStore:file.chm::/dir/file", 0, S_OK, "mk:@MSITStore:file.chm::/dir/file"}, - {"foo:today", "foo:calendar", 0, S_OK, "foo:calendar"}, - {"foo:today", "bar:calendar", 0, S_OK, "bar:calendar"}, - {"foo:/today", "foo:calendar", 0, S_OK, "foo:/calendar"}, - {"Foo:/today/", "fOo:calendar", 0, S_OK, "foo:/today/calendar"}, - {"mk:@MSITStore:dir/test.chm::dir/index.html", "image.jpg", 0, S_OK, "mk:@MSITStore:dir/test.chm::dir/image.jpg"}, - {"mk:@MSITStore:dir/test.chm::dir/dir2/index.html", "../image.jpg", 0, S_OK, "mk:@MSITStore:dir/test.chm::dir/image.jpg"}, + {"http://www.winehq.org/tests", "tests1", 0, "http://www.winehq.org/tests1"}, + {"http://www.%77inehq.org/tests", "tests1", 0, "http://www.%77inehq.org/tests1"}, + /*FIXME {"http://www.winehq.org/tests", "../tests2", 0, "http://www.winehq.org/tests2"},*/ + {"http://www.winehq.org/tests/", "../tests3", 0, "http://www.winehq.org/tests3"}, + {"http://www.winehq.org/tests/test1", "test2", 0, "http://www.winehq.org/tests/test2"}, + {"http://www.winehq.org/tests/../tests", "tests4", 0, "http://www.winehq.org/tests4"}, + {"http://www.winehq.org/tests/../tests/", "tests5", 0, "http://www.winehq.org/tests/tests5"}, + {"http://www.winehq.org/tests/../tests/", "/tests6/..", 0, "http://www.winehq.org/"}, + {"http://www.winehq.org/tests/../tests/", "\\tests6\\..", 0, "http://www.winehq.org/"}, + {"http://www.winehq.org/tests/../tests/..", "tests7/..", 0, "http://www.winehq.org/"}, + {"http://www.winehq.org/tests/?query=x&return=y", "tests8", 0, "http://www.winehq.org/tests/tests8"}, + {"http://www.winehq.org/tests/#example", "tests9", 0, "http://www.winehq.org/tests/tests9"}, + {"http://www.winehq.org/tests/../tests/", "/tests10/..", URL_DONT_SIMPLIFY, "http://www.winehq.org/tests10/.."}, + {"http://www.winehq.org/tests/../", "tests11", URL_DONT_SIMPLIFY, "http://www.winehq.org/tests/../tests11"}, + {"http://www.winehq.org/test12", "#", 0, "http://www.winehq.org/test12#"}, + {"http://www.winehq.org/test13#aaa", "#bbb", 0, "http://www.winehq.org/test13#bbb"}, + {"http://www.winehq.org/test14#aaa/bbb#ccc", "#", 0, "http://www.winehq.org/test14#"}, + {"http://www.winehq.org/tests/?query=x/y/z", "tests15", 0, "http://www.winehq.org/tests/tests15"}, + {"http://www.winehq.org/tests/?query=x/y/z#example", "tests16", 0, "http://www.winehq.org/tests/tests16"}, + {"file:///C:\\dir\\file.txt", "test.txt", 0, "file:///C:/dir/test.txt"}, + {"file:///C:\\dir\\file.txt#hash\\hash", "test.txt", 0, "file:///C:/dir/file.txt#hash/test.txt"}, + {"file:///C:\\dir\\file.html#hash\\hash", "test.html", 0, "file:///C:/dir/test.html"}, + {"file:///C:\\dir\\file.htm#hash\\hash", "test.htm", 0, "file:///C:/dir/test.htm"}, + {"file:///C:\\dir\\file.hTmL#hash\\hash", "test.hTmL", 0, "file:///C:/dir/test.hTmL"}, + {"file:///C:\\dir.html\\file.txt#hash\\hash", "test.txt", 0, "file:///C:/dir.html/file.txt#hash/test.txt"}, + {"C:\\winehq\\winehq.txt", "C:\\Test\\test.txt", 0, "file:///C:/Test/test.txt"}, + {"http://www.winehq.org/test/", "test%20file.txt", 0, "http://www.winehq.org/test/test%20file.txt"}, + {"http://www.winehq.org/test/", "test%20file.txt", URL_FILE_USE_PATHURL, "http://www.winehq.org/test/test%20file.txt"}, + {"http://www.winehq.org%2ftest/", "test%20file.txt", URL_FILE_USE_PATHURL, "http://www.winehq.org%2ftest/test%20file.txt"}, + {"xxx:@MSITStore:file.chm/file.html", "dir/file", 0, "xxx:dir/file"}, + {"mk:@MSITStore:file.chm::/file.html", "/dir/file", 0, "mk:@MSITStore:file.chm::/dir/file"}, + {"mk:@MSITStore:file.chm::/file.html", "mk:@MSITStore:file.chm::/dir/file", 0, "mk:@MSITStore:file.chm::/dir/file"}, + {"foo:today", "foo:calendar", 0, "foo:calendar"}, + {"foo:today", "bar:calendar", 0, "bar:calendar"}, + {"foo:/today", "foo:calendar", 0, "foo:/calendar"}, + {"Foo:/today/", "fOo:calendar", 0, "foo:/today/calendar"}, + {"mk:@MSITStore:dir/test.chm::dir/index.html", "image.jpg", 0, "mk:@MSITStore:dir/test.chm::dir/image.jpg"}, + {"mk:@MSITStore:dir/test.chm::dir/dir2/index.html", "../image.jpg", 0, "mk:@MSITStore:dir/test.chm::dir/image.jpg"}, + {"c:\\test\\", "//share/file.txt", 0, "file://share/file.txt"}, + {"c:\\test\\", "\\\\share\\file.txt", 0, "file://share/file.txt"}, /* UrlCombine case 2 tests. Schemes do not match */ - {"outbind://xxxxxxxxx","http://wine1/dir",0, S_OK,"http://wine1/dir"}, - {"xxxx://xxxxxxxxx","http://wine2/dir",0, S_OK,"http://wine2/dir"}, - {"ftp://xxxxxxxxx/","http://wine3/dir",0, S_OK,"http://wine3/dir"}, - {"outbind://xxxxxxxxx","http://wine4/dir",URL_PLUGGABLE_PROTOCOL, S_OK,"http://wine4/dir"}, - {"xxx://xxxxxxxxx","http://wine5/dir",URL_PLUGGABLE_PROTOCOL, S_OK,"http://wine5/dir"}, - {"ftp://xxxxxxxxx/","http://wine6/dir",URL_PLUGGABLE_PROTOCOL, S_OK,"http://wine6/dir"}, - {"http://xxxxxxxxx","outbind://wine7/dir",0, S_OK,"outbind://wine7/dir"}, - {"xxx://xxxxxxxxx","ftp://wine8/dir",0, S_OK,"ftp://wine8/dir"}, - {"ftp://xxxxxxxxx/","xxx://wine9/dir",0, S_OK,"xxx://wine9/dir"}, - {"http://xxxxxxxxx","outbind://wine10/dir",URL_PLUGGABLE_PROTOCOL, S_OK,"outbind://wine10/dir"}, - {"xxx://xxxxxxxxx","ftp://wine11/dir",URL_PLUGGABLE_PROTOCOL, S_OK,"ftp://wine11/dir"}, - {"ftp://xxxxxxxxx/","xxx://wine12/dir",URL_PLUGGABLE_PROTOCOL, S_OK,"xxx://wine12/dir"}, - {"http://xxxxxxxxx","outbind:wine13/dir",0, S_OK,"outbind:wine13/dir"}, - {"xxx://xxxxxxxxx","ftp:wine14/dir",0, S_OK,"ftp:wine14/dir"}, - {"ftp://xxxxxxxxx/","xxx:wine15/dir",0, S_OK,"xxx:wine15/dir"}, - {"outbind://xxxxxxxxx/","http:wine16/dir",0, S_OK,"http:wine16/dir"}, - {"http://xxxxxxxxx","outbind:wine17/dir",URL_PLUGGABLE_PROTOCOL, S_OK,"outbind:wine17/dir"}, - {"xxx://xxxxxxxxx","ftp:wine18/dir",URL_PLUGGABLE_PROTOCOL, S_OK,"ftp:wine18/dir"}, - {"ftp://xxxxxxxxx/","xXx:wine19/dir",URL_PLUGGABLE_PROTOCOL, S_OK,"xxx:wine19/dir"}, - {"outbind://xxxxxxxxx/","http:wine20/dir",URL_PLUGGABLE_PROTOCOL, S_OK,"http:wine20/dir"}, - {"file:///c:/dir/file.txt","index.html?test=c:/abc",URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO,S_OK,"file:///c:/dir/index.html?test=c:/abc"} + {"outbind://xxxxxxxxx", "http://wine1/dir", 0, "http://wine1/dir"}, + {"xxxx://xxxxxxxxx", "http://wine2/dir", 0, "http://wine2/dir"}, + {"ftp://xxxxxxxxx/", "http://wine3/dir", 0, "http://wine3/dir"}, + {"outbind://xxxxxxxxx", "http://wine4/dir", URL_PLUGGABLE_PROTOCOL, "http://wine4/dir"}, + {"xxx://xxxxxxxxx", "http://wine5/dir", URL_PLUGGABLE_PROTOCOL, "http://wine5/dir"}, + {"ftp://xxxxxxxxx/", "http://wine6/dir", URL_PLUGGABLE_PROTOCOL, "http://wine6/dir"}, + {"http://xxxxxxxxx", "outbind://wine7/dir", 0, "outbind://wine7/dir"}, + {"xxx://xxxxxxxxx", "ftp://wine8/dir", 0, "ftp://wine8/dir"}, + {"ftp://xxxxxxxxx/", "xxx://wine9/dir", 0, "xxx://wine9/dir"}, + {"http://xxxxxxxxx", "outbind://wine10/dir", URL_PLUGGABLE_PROTOCOL, "outbind://wine10/dir"}, + {"xxx://xxxxxxxxx", "ftp://wine11/dir", URL_PLUGGABLE_PROTOCOL, "ftp://wine11/dir"}, + {"ftp://xxxxxxxxx/", "xxx://wine12/dir", URL_PLUGGABLE_PROTOCOL, "xxx://wine12/dir"}, + {"http://xxxxxxxxx", "outbind:wine13/dir", 0, "outbind:wine13/dir"}, + {"xxx://xxxxxxxxx", "ftp:wine14/dir", 0, "ftp:wine14/dir"}, + {"ftp://xxxxxxxxx/", "xxx:wine15/dir", 0, "xxx:wine15/dir"}, + {"outbind://xxxxxxxxx/", "http:wine16/dir", 0, "http:wine16/dir"}, + {"http://xxxxxxxxx", "outbind:wine17/dir", URL_PLUGGABLE_PROTOCOL, "outbind:wine17/dir"}, + {"xxx://xxxxxxxxx", "ftp:wine18/dir", URL_PLUGGABLE_PROTOCOL, "ftp:wine18/dir"}, + {"ftp://xxxxxxxxx/", "xXx:wine19/dir", URL_PLUGGABLE_PROTOCOL, "xxx:wine19/dir"}, + {"outbind://xxxxxxxxx/", "http:wine20/dir", URL_PLUGGABLE_PROTOCOL, "http:wine20/dir"}, + {"file:///c:/dir/file.txt", "index.html?test=c:/abc", URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO, "file:///c:/dir/index.html?test=c:/abc"} }; /* ################ */ @@ -459,12 +276,7 @@ static const struct { {"c:\\foo/b a%r", "file:///c:/foo/b%20a%25r", S_OK}, {"c:\\foo\\foo bar", "file:///c:/foo/foo%20bar", S_OK}, {"file:///c:/foo/bar", "file:///c:/foo/bar", S_FALSE}, -#if 0 - /* The following test fails on native shlwapi as distributed with Win95/98. - * Wine matches the behaviour of later versions. - */ {"xx:c:\\foo\\bar", "xx:c:\\foo\\bar", S_FALSE} -#endif }; /* ################ */ @@ -478,7 +290,38 @@ static struct { {"file://%24%25foobar", "file://$%foobar"} }; -/* ################ */ +static struct +{ + const WCHAR *url; + const WCHAR *expect; + DWORD flags; +} TEST_URL_UNESCAPEW[] = +{ + { L"file://foo/bar", L"file://foo/bar" }, + { L"file://fo%20o%5Ca/bar", L"file://fo o\\a/bar" }, + { L"file://%24%25foobar", L"file://$%foobar" }, + { L"file:///C:/Program Files", L"file:///C:/Program Files" }, + { L"file:///C:/Program Files", L"file:///C:/Program Files", URL_UNESCAPE_AS_UTF8 }, + { L"file:///C:/Program%20Files", L"file:///C:/Program Files" }, + { L"file:///C:/Program%20Files", L"file:///C:/Program Files", URL_UNESCAPE_AS_UTF8 }, + { L"file://foo/%E4%B8%AD%E6%96%87/bar", L"file://foo/\xe4\xb8\xad\xe6\x96\x87/bar" }, /* with 3 btyes utf-8 */ + { L"file://foo/%E4%B8%AD%E6%96%87/bar", L"file://foo/\x4e2d\x6587/bar", URL_UNESCAPE_AS_UTF8 }, + /* mix corrupt and good utf-8 */ + { L"file://foo/%E4%AD%E6%96%87/bar", L"file://foo/\xfffd\x6587/bar", URL_UNESCAPE_AS_UTF8 }, + { L"file://foo/%F0%9F%8D%B7/bar", L"file://foo/\xf0\x9f\x8d\xb7/bar" }, /* with 4 btyes utf-8 */ + { L"file://foo/%F0%9F%8D%B7/bar", L"file://foo/\xd83c\xdf77/bar", URL_UNESCAPE_AS_UTF8 }, + /* non-escaped chars between multi-byte escaped chars */ +#if defined(__REACTOS__) && defined(_MSC_VER) + { L"file://foo/%E4%B8%ADabc%E6%96%87/bar", L"file://foo/\x4e2d""abc""\u6587/bar", URL_UNESCAPE_AS_UTF8 }, + { L"file://foo/%E4B8%AD/bar", L"file://foo/\ufffd""B8\ufffd/bar", URL_UNESCAPE_AS_UTF8 }, + { L"file://foo/%E4%G8%AD/bar", L"file://foo/\ufffd""%G8\ufffd/bar", URL_UNESCAPE_AS_UTF8 }, +#else + { L"file://foo/%E4%B8%ADabc%E6%96%87/bar", L"file://foo/\x4e2d""abc""\x6587/bar", URL_UNESCAPE_AS_UTF8 }, + { L"file://foo/%E4B8%AD/bar", L"file://foo/\xfffd""B8\xfffd/bar", URL_UNESCAPE_AS_UTF8 }, + { L"file://foo/%E4%G8%AD/bar", L"file://foo/\xfffd""%G8\xfffd/bar", URL_UNESCAPE_AS_UTF8 }, +#endif + { L"file://foo/%G4%B8%AD/bar", L"file://foo/%G4\xfffd\xfffd/bar", URL_UNESCAPE_AS_UTF8 }, +}; static const struct { const char *path; @@ -549,76 +392,78 @@ static void FreeWideString(LPWSTR wszString) static void test_UrlApplyScheme(void) { - CHAR newurl[TEST_APPLY_MAX_LENGTH]; - WCHAR urlW[TEST_APPLY_MAX_LENGTH]; - WCHAR newurlW[TEST_APPLY_MAX_LENGTH]; + WCHAR urlW[INTERNET_MAX_URL_LENGTH], newurlW[INTERNET_MAX_URL_LENGTH], expectW[INTERNET_MAX_URL_LENGTH]; + char newurl[INTERNET_MAX_URL_LENGTH]; HRESULT res; DWORD len; DWORD i; - if (!pUrlApplySchemeA) { - win_skip("UrlApplySchemeA not found\n"); - return; - } - for (i = 0; i < ARRAY_SIZE(TEST_APPLY); i++) { - len = TEST_APPLY_MAX_LENGTH; - lstrcpyA(newurl, untouchedA); - res = pUrlApplySchemeA(TEST_APPLY[i].url, newurl, &len, TEST_APPLY[i].flags); + len = ARRAY_SIZE(newurl); + strcpy(newurl, "untouched"); + res = UrlApplySchemeA(TEST_APPLY[i].url, newurl, &len, TEST_APPLY[i].flags); ok( res == TEST_APPLY[i].res, - "#%dA: got HRESULT 0x%x (expected 0x%x)\n", i, res, TEST_APPLY[i].res); - - ok( len == TEST_APPLY[i].newlen, - "#%dA: got len %d (expected %d)\n", i, len, TEST_APPLY[i].newlen); - - ok( !lstrcmpA(newurl, TEST_APPLY[i].newurl), - "#%dA: got '%s' (expected '%s')\n", i, newurl, TEST_APPLY[i].newurl); + "#%ldA: got HRESULT 0x%lx (expected 0x%lx)\n", i, res, TEST_APPLY[i].res); + if (res == S_OK) + { + ok(len == strlen(newurl), "Test %lu: Expected length %Iu, got %lu.\n", i, strlen(newurl), len); + ok(!strcmp(newurl, TEST_APPLY[i].newurl), "Test %lu: Expected %s, got %s.\n", + i, debugstr_a(TEST_APPLY[i].newurl), debugstr_a(newurl)); + } + else + { + ok(len == ARRAY_SIZE(newurl), "Test %lu: Got length %lu.\n", i, len); + ok(!strcmp(newurl, "untouched"), "Test %lu: Got %s.\n", i, debugstr_a(newurl)); + } /* returned length is in character */ - len = TEST_APPLY_MAX_LENGTH; - lstrcpyA(newurl, untouchedA); - MultiByteToWideChar(CP_ACP, 0, newurl, -1, newurlW, len); - MultiByteToWideChar(CP_ACP, 0, TEST_APPLY[i].url, -1, urlW, len); + MultiByteToWideChar(CP_ACP, 0, TEST_APPLY[i].url, -1, urlW, ARRAY_SIZE(urlW)); + MultiByteToWideChar(CP_ACP, 0, TEST_APPLY[i].newurl, -1, expectW, ARRAY_SIZE(expectW)); - res = pUrlApplySchemeW(urlW, newurlW, &len, TEST_APPLY[i].flags); - WideCharToMultiByte(CP_ACP, 0, newurlW, -1, newurl, TEST_APPLY_MAX_LENGTH, NULL, NULL); + len = ARRAY_SIZE(newurlW); + wcscpy(newurlW, L"untouched"); + res = UrlApplySchemeW(urlW, newurlW, &len, TEST_APPLY[i].flags); ok( res == TEST_APPLY[i].res, - "#%dW: got HRESULT 0x%x (expected 0x%x)\n", i, res, TEST_APPLY[i].res); - - ok( len == TEST_APPLY[i].newlen, - "#%dW: got len %d (expected %d)\n", i, len, TEST_APPLY[i].newlen); - - ok( !lstrcmpA(newurl, TEST_APPLY[i].newurl), - "#%dW: got '%s' (expected '%s')\n", i, newurl, TEST_APPLY[i].newurl); - + "#%ldW: got HRESULT 0x%lx (expected 0x%lx)\n", i, res, TEST_APPLY[i].res); + if (res == S_OK) + { + ok(len == wcslen(newurlW), "Test %lu: Expected length %Iu, got %lu.\n", i, wcslen(newurlW), len); + ok(!wcscmp(newurlW, expectW), "Test %lu: Expected %s, got %s.\n", + i, debugstr_w(expectW), debugstr_w(newurlW)); + } + else + { + ok(len == ARRAY_SIZE(newurlW), "Test %lu: Got length %lu.\n", i, len); + ok(!wcscmp(newurlW, L"untouched"), "Test %lu: Got %s.\n", i, debugstr_w(newurlW)); + } } /* buffer too small */ lstrcpyA(newurl, untouchedA); len = lstrlenA(TEST_APPLY[0].newurl); - res = pUrlApplySchemeA(TEST_APPLY[0].url, newurl, &len, TEST_APPLY[0].flags); - ok(res == E_POINTER, "got HRESULT 0x%x (expected E_POINTER)\n", res); + res = UrlApplySchemeA(TEST_APPLY[0].url, newurl, &len, TEST_APPLY[0].flags); + ok(res == E_POINTER, "got HRESULT 0x%lx (expected E_POINTER)\n", res); /* The returned length include the space for the terminating 0 */ i = lstrlenA(TEST_APPLY[0].newurl)+1; - ok(len == i, "got len %d (expected %d)\n", len, i); + ok(len == i, "got len %ld (expected %ld)\n", len, i); ok(!lstrcmpA(newurl, untouchedA), "got '%s' (expected '%s')\n", newurl, untouchedA); /* NULL as parameter. The length and the buffer are not modified */ lstrcpyA(newurl, untouchedA); - len = TEST_APPLY_MAX_LENGTH; - res = pUrlApplySchemeA(NULL, newurl, &len, TEST_APPLY[0].flags); - ok(res == E_INVALIDARG, "got HRESULT 0x%x (expected E_INVALIDARG)\n", res); - ok(len == TEST_APPLY_MAX_LENGTH, "got len %d\n", len); + len = ARRAY_SIZE(newurl); + res = UrlApplySchemeA(NULL, newurl, &len, TEST_APPLY[0].flags); + ok(res == E_INVALIDARG, "got HRESULT 0x%lx (expected E_INVALIDARG)\n", res); + ok(len == ARRAY_SIZE(newurl), "got len %ld\n", len); ok(!lstrcmpA(newurl, untouchedA), "got '%s' (expected '%s')\n", newurl, untouchedA); - len = TEST_APPLY_MAX_LENGTH; - res = pUrlApplySchemeA(TEST_APPLY[0].url, NULL, &len, TEST_APPLY[0].flags); - ok(res == E_INVALIDARG, "got HRESULT 0x%x (expected E_INVALIDARG)\n", res); - ok(len == TEST_APPLY_MAX_LENGTH, "got len %d\n", len); + len = ARRAY_SIZE(newurl); + res = UrlApplySchemeA(TEST_APPLY[0].url, NULL, &len, TEST_APPLY[0].flags); + ok(res == E_INVALIDARG, "got HRESULT 0x%lx (expected E_INVALIDARG)\n", res); + ok(len == ARRAY_SIZE(newurl), "got len %ld\n", len); lstrcpyA(newurl, untouchedA); - res = pUrlApplySchemeA(TEST_APPLY[0].url, newurl, NULL, TEST_APPLY[0].flags); - ok(res == E_INVALIDARG, "got HRESULT 0x%x (expected E_INVALIDARG)\n", res); + res = UrlApplySchemeA(TEST_APPLY[0].url, newurl, NULL, TEST_APPLY[0].flags); + ok(res == E_INVALIDARG, "got HRESULT 0x%lx (expected E_INVALIDARG)\n", res); ok(!lstrcmpA(newurl, untouchedA), "got '%s' (expected '%s')\n", newurl, untouchedA); } @@ -633,261 +478,349 @@ static void hash_url(const char* szUrl) DWORD cbSize = sizeof(DWORD); DWORD dwHash1, dwHash2; - res = pUrlHashA(szTestUrl, (LPBYTE)&dwHash1, cbSize); - ok(res == S_OK, "UrlHashA returned 0x%x (expected S_OK) for %s\n", res, szUrl); - if (pUrlHashW) { - res = pUrlHashW(wszTestUrl, (LPBYTE)&dwHash2, cbSize); - ok(res == S_OK, "UrlHashW returned 0x%x (expected S_OK) for %s\n", res, szUrl); - ok(dwHash1 == dwHash2, - "Hashes didn't match (A: 0x%x, W: 0x%x) for %s\n", dwHash1, dwHash2, szUrl); - } - FreeWideString(wszTestUrl); + res = UrlHashA(szTestUrl, (LPBYTE)&dwHash1, cbSize); + ok(res == S_OK, "UrlHashA returned 0x%lx (expected S_OK) for %s\n", res, szUrl); + res = UrlHashW(wszTestUrl, (LPBYTE)&dwHash2, cbSize); + ok(res == S_OK, "UrlHashW returned 0x%lx (expected S_OK) for %s\n", res, szUrl); + ok(dwHash1 == dwHash2, + "Hashes didn't match (A: 0x%lx, W: 0x%lx) for %s\n", dwHash1, dwHash2, szUrl); + FreeWideString(wszTestUrl); } static void test_UrlHash(void) { - if (!pUrlHashA) { - win_skip("UrlHashA not found\n"); - return; - } - hash_url(TEST_URL_1); hash_url(TEST_URL_2); hash_url(TEST_URL_3); } -/* ########################### */ - -static void test_url_part(const char* szUrl, DWORD dwPart, DWORD dwFlags, const char* szExpected) -{ - CHAR szPart[INTERNET_MAX_URL_LENGTH]; - WCHAR wszPart[INTERNET_MAX_URL_LENGTH]; - LPWSTR wszUrl = GetWideString(szUrl); - LPWSTR wszConvertedPart; - HRESULT res; - DWORD dwSize; - - dwSize = 1; - res = pUrlGetPartA(szUrl, szPart, &dwSize, dwPart, dwFlags); - ok(res == E_POINTER, "UrlGetPart for \"%s\" gave: 0x%08x\n", szUrl, res); - ok(dwSize == strlen(szExpected)+1 || - (*szExpected == '?' && dwSize == strlen(szExpected)), - "UrlGetPart for \"%s\" gave size: %u\n", szUrl, dwSize); - - dwSize = INTERNET_MAX_URL_LENGTH; - res = pUrlGetPartA(szUrl, szPart, &dwSize, dwPart, dwFlags); - ok(res == S_OK, - "UrlGetPartA for \"%s\" part 0x%08x returned 0x%x and \"%s\"\n", - szUrl, dwPart, res, szPart); - if (pUrlGetPartW) { - dwSize = INTERNET_MAX_URL_LENGTH; - res = pUrlGetPartW(wszUrl, wszPart, &dwSize, dwPart, dwFlags); - ok(res == S_OK, - "UrlGetPartW for \"%s\" part 0x%08x returned 0x%x\n", - szUrl, dwPart, res); - - wszConvertedPart = GetWideString(szPart); - - ok(lstrcmpW(wszPart,wszConvertedPart)==0, - "Strings didn't match between ascii and unicode UrlGetPart!\n"); - - FreeWideString(wszConvertedPart); - } - FreeWideString(wszUrl); - - /* Note that v6.0 and later don't return '?' with the query */ - ok(strcmp(szPart,szExpected)==0 || - (*szExpected=='?' && !strcmp(szPart,szExpected+1)), - "Expected %s, but got %s\n", szExpected, szPart); -} - -/* ########################### */ - static void test_UrlGetPart(void) { - const char* file_url = "file://h o s t/c:/windows/file"; - const char* http_url = "http://user:pass 123@www.wine hq.org"; - const char* res_url = "res://some.dll/find.dlg"; - const char* about_url = "about:blank"; - const char* excid_url = "x-excid://36C00000/guid:{048B4E89-2E92-496F-A837-33BA02FF6D32}/Message.htm"; - const char* foo_url = "foo://bar-url/test"; - const char* short_url = "ascheme:"; + WCHAR bufferW[200]; + char buffer[200]; + unsigned int i; + HRESULT hr; + DWORD size; - CHAR szPart[INTERNET_MAX_URL_LENGTH]; - DWORD dwSize; - HRESULT res; + static const struct + { + const char *url; + DWORD part; + DWORD flags; + HRESULT hr; + const char *expect; + } + tests[] = + { + {"hi", URL_PART_SCHEME, 0, S_FALSE, ""}, + {"hi", URL_PART_USERNAME, 0, E_FAIL}, + {"hi", URL_PART_PASSWORD, 0, E_FAIL}, + {"hi", URL_PART_HOSTNAME, 0, E_FAIL}, + {"hi", URL_PART_PORT, 0, E_FAIL}, + {"hi", URL_PART_QUERY, 0, S_FALSE, ""}, - if (!pUrlGetPartA) { - win_skip("UrlGetPartA not found\n"); - return; - } + {"http://foo:bar@localhost:21/internal.php?query=x&return=y", URL_PART_SCHEME, 0, S_OK, "http"}, + {"http://foo:bar@localhost:21/internal.php?query=x&return=y", URL_PART_USERNAME, 0, S_OK, "foo"}, + {"http://foo:bar@localhost:21/internal.php?query=x&return=y", URL_PART_PASSWORD, 0, S_OK, "bar"}, + {"http://foo:bar@localhost:21/internal.php?query=x&return=y", URL_PART_HOSTNAME, 0, S_OK, "localhost"}, + {"http://foo:bar@localhost:21/internal.php?query=x&return=y", URL_PART_PORT, 0, S_OK, "21"}, + {"http://foo:bar@localhost:21/internal.php?query=x&return=y", URL_PART_QUERY, 0, S_OK, "query=x&return=y"}, + {"http://foo:bar@localhost:21/internal.php#anchor", URL_PART_QUERY, 0, S_FALSE, ""}, + {"http://foo:bar@localhost:21/internal.php?query=x&return=y", URL_PART_SCHEME, URL_PARTFLAG_KEEPSCHEME, S_OK, "http"}, + {"http://foo:bar@localhost:21/internal.php?query=x&return=y", URL_PART_USERNAME, URL_PARTFLAG_KEEPSCHEME, S_OK, "http:foo"}, + {"http://foo:bar@localhost:21/internal.php?query=x&return=y", URL_PART_PASSWORD, URL_PARTFLAG_KEEPSCHEME, S_OK, "http:bar"}, + {"http://foo:bar@localhost:21/internal.php?query=x&return=y", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, S_OK, "http:localhost"}, + {"http://foo:bar@localhost:21/internal.php?query=x&return=y", URL_PART_PORT, URL_PARTFLAG_KEEPSCHEME, S_OK, "http:21"}, + {"http://foo:bar@localhost:21/internal.php?query=x&return=y", URL_PART_QUERY, URL_PARTFLAG_KEEPSCHEME, S_OK, "query=x&return=y"}, - res = pUrlGetPartA(NULL, NULL, NULL, URL_PART_SCHEME, 0); - ok(res == E_INVALIDARG, "null params gave: 0x%08x\n", res); + {"http://localhost/", URL_PART_USERNAME, 0, E_INVALIDARG}, + {"http://localhost/", URL_PART_PASSWORD, 0, E_INVALIDARG}, + {"http://localhost/", URL_PART_HOSTNAME, 0, S_OK, "localhost"}, + {"http://localhost/", URL_PART_PORT, 0, E_INVALIDARG}, + {"http://localhost/", URL_PART_QUERY, 0, S_FALSE, ""}, - res = pUrlGetPartA(NULL, szPart, &dwSize, URL_PART_SCHEME, 0); - ok(res == E_INVALIDARG, "null URL gave: 0x%08x\n", res); + {"http://localhost:port/", URL_PART_USERNAME, 0, E_INVALIDARG}, + {"http://localhost:port/", URL_PART_PASSWORD, 0, E_INVALIDARG}, + {"http://localhost:port/", URL_PART_HOSTNAME, 0, S_OK, "localhost"}, + {"http://localhost:port/", URL_PART_PORT, 0, S_OK, "port"}, + {"http://:", URL_PART_HOSTNAME, 0, S_FALSE, ""}, + {"http://:", URL_PART_PORT, 0, S_FALSE, ""}, - res = pUrlGetPartA(res_url, NULL, &dwSize, URL_PART_SCHEME, 0); - ok(res == E_INVALIDARG, "null szPart gave: 0x%08x\n", res); + {"http://user@localhost", URL_PART_USERNAME, 0, S_OK, "user"}, + {"http://user@localhost", URL_PART_PASSWORD, 0, E_INVALIDARG}, + {"http://user@localhost", URL_PART_HOSTNAME, 0, S_OK, "localhost"}, + {"http://user@localhost", URL_PART_PORT, 0, E_INVALIDARG}, + {"http://@", URL_PART_USERNAME, 0, S_FALSE, ""}, + {"http://@", URL_PART_PASSWORD, 0, E_INVALIDARG}, + {"http://@", URL_PART_HOSTNAME, 0, S_FALSE, ""}, - res = pUrlGetPartA(res_url, szPart, NULL, URL_PART_SCHEME, 0); - ok(res == E_INVALIDARG, "null URL gave: 0x%08x\n", res); + {"http://user:pass@localhost", URL_PART_USERNAME, 0, S_OK, "user"}, + {"http://user:pass@localhost", URL_PART_PASSWORD, 0, S_OK, "pass"}, + {"http://user:pass@localhost", URL_PART_HOSTNAME, 0, S_OK, "localhost"}, + {"http://user:pass@localhost", URL_PART_PORT, 0, E_INVALIDARG}, + {"http://:@", URL_PART_USERNAME, 0, S_FALSE, ""}, + {"http://:@", URL_PART_PASSWORD, 0, S_FALSE, ""}, + {"http://:@", URL_PART_HOSTNAME, 0, S_FALSE, ""}, - dwSize = 0; - szPart[0]='x'; szPart[1]=0; - res = pUrlGetPartA("hi", szPart, &dwSize, URL_PART_SCHEME, 0); - ok(res == E_INVALIDARG, "UrlGetPartA(*pcchOut = 0) returned %08X\n", res); - ok(szPart[0] == 'x' && szPart[1] == 0, "UrlGetPartA(*pcchOut = 0) modified szPart: \"%s\"\n", szPart); - ok(dwSize == 0, "dwSize = %d\n", dwSize); + {"http://host:port:q", URL_PART_HOSTNAME, 0, S_OK, "host"}, + {"http://host:port:q", URL_PART_PORT, 0, S_OK, "port:q"}, + {"http://user:pass:q@host", URL_PART_USERNAME, 0, S_OK, "user"}, + {"http://user:pass:q@host", URL_PART_PASSWORD, 0, S_OK, "pass:q"}, + {"http://user@host@q", URL_PART_USERNAME, 0, S_OK, "user"}, + {"http://user@host@q", URL_PART_HOSTNAME, 0, S_OK, "host@q"}, - dwSize = sizeof szPart; - szPart[0]='x'; szPart[1]=0; - res = pUrlGetPartA("hi", szPart, &dwSize, URL_PART_SCHEME, 0); - ok (res==S_FALSE, "UrlGetPartA(\"hi\") returned %08X\n", res); - ok(szPart[0]==0, "UrlGetPartA(\"hi\") return \"%s\" instead of \"\"\n", szPart); - ok(dwSize == 0, "dwSize = %d\n", dwSize); + {"http:localhost/index.html", URL_PART_HOSTNAME, 0, E_FAIL}, + {"http:/localhost/index.html", URL_PART_HOSTNAME, 0, E_FAIL}, - if(pUrlGetPartW) - { - const WCHAR hiW[] = {'h','i',0}; - WCHAR bufW[5]; + {"http://localhost\\index.html", URL_PART_HOSTNAME, 0, S_OK, "localhost"}, + {"http:/\\localhost/index.html", URL_PART_HOSTNAME, 0, S_OK, "localhost"}, + {"http:\\/localhost/index.html", URL_PART_HOSTNAME, 0, S_OK, "localhost"}, - /* UrlGetPartW returns S_OK instead of S_FALSE */ - dwSize = sizeof szPart; - bufW[0]='x'; bufW[1]=0; - res = pUrlGetPartW(hiW, bufW, &dwSize, URL_PART_SCHEME, 0); - todo_wine ok(res==S_OK, "UrlGetPartW(\"hi\") returned %08X\n", res); - ok(bufW[0] == 0, "UrlGetPartW(\"hi\") return \"%c\"\n", bufW[0]); - ok(dwSize == 0, "dwSize = %d\n", dwSize); - } + {"ftp://localhost\\index.html", URL_PART_HOSTNAME, 0, S_OK, "localhost"}, + {"ftp:/\\localhost/index.html", URL_PART_HOSTNAME, 0, S_OK, "localhost"}, + {"ftp:\\/localhost/index.html", URL_PART_HOSTNAME, 0, S_OK, "localhost"}, - dwSize = sizeof szPart; - szPart[0]='x'; szPart[1]=0; - res = pUrlGetPartA("hi", szPart, &dwSize, URL_PART_QUERY, 0); - ok (res==S_FALSE, "UrlGetPartA(\"hi\") returned %08X\n", res); - ok(szPart[0]==0, "UrlGetPartA(\"hi\") return \"%s\" instead of \"\"\n", szPart); - ok(dwSize == 0, "dwSize = %d\n", dwSize); + {"http://host?a:b@c:d", URL_PART_HOSTNAME, 0, S_OK, "host"}, + {"http://host?a:b@c:d", URL_PART_QUERY, 0, S_OK, "a:b@c:d"}, + {"http://host#a:b@c:d", URL_PART_HOSTNAME, 0, S_OK, "host"}, + {"http://host#a:b@c:d", URL_PART_QUERY, 0, S_FALSE, ""}, - test_url_part(TEST_URL_3, URL_PART_HOSTNAME, 0, "localhost"); - test_url_part(TEST_URL_3, URL_PART_PORT, 0, "21"); - test_url_part(TEST_URL_3, URL_PART_USERNAME, 0, "foo"); - test_url_part(TEST_URL_3, URL_PART_PASSWORD, 0, "bar"); - test_url_part(TEST_URL_3, URL_PART_SCHEME, 0, "http"); - test_url_part(TEST_URL_3, URL_PART_QUERY, 0, "?query=x&return=y"); + /* All characters, other than those with special meaning, are allowed. */ + {"http://foo:bar@google.*.com:21/internal.php?query=x&return=y", URL_PART_HOSTNAME, 0, S_OK, "google.*.com"}, + {"http:// !\"$%&'()*+,-.;<=>[]^_`{|~}:pass@host", URL_PART_USERNAME, 0, S_OK, " !\"$%&'()*+,-.;<=>[]^_`{|~}"}, + {"http://user: !\"$%&'()*+,-.;<=>[]^_`{|~}@host", URL_PART_PASSWORD, 0, S_OK, " !\"$%&'()*+,-.;<=>[]^_`{|~}"}, + {"http:// !\"$%&'()*+,-.;<=>[]^_`{|~}", URL_PART_HOSTNAME, 0, S_OK, " !\"$%&'()*+,-.;<=>[]^_`{|~}"}, + {"http://host: !\"$%&'()*+,-.;<=>[]^_`{|~}", URL_PART_PORT, 0, S_OK, " !\"$%&'()*+,-.;<=>[]^_`{|~}"}, - test_url_part(TEST_URL_4, URL_PART_HOSTNAME, 0, "google.*.com"); + {"http:///index.html", URL_PART_HOSTNAME, 0, S_FALSE, ""}, + {"http:///index.html", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, S_OK, "http:"}, + {"file://h o s t/c:/windows/file", URL_PART_HOSTNAME, 0, S_OK, "h o s t"}, + {"file://h o s t/c:/windows/file", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, S_OK, "h o s t"}, + {"file://foo:bar@localhost:21/file?query=x", URL_PART_USERNAME, 0, E_FAIL}, + {"file://foo:bar@localhost:21/file?query=x", URL_PART_PASSWORD, 0, E_FAIL}, + {"file://foo:bar@localhost:21/file?query=x", URL_PART_HOSTNAME, 0, S_OK, "foo:bar@localhost:21"}, + {"file://foo:bar@localhost:21/file?query=x", URL_PART_PORT, 0, E_FAIL}, + {"file://foo:bar@localhost:21/file?query=x", URL_PART_QUERY, 0, S_OK, "query=x"}, + {"http://user:pass 123@www.wine hq.org", URL_PART_HOSTNAME, 0, S_OK, "www.wine hq.org"}, + {"http://user:pass 123@www.wine hq.org", URL_PART_PASSWORD, 0, S_OK, "pass 123"}, + {"about:blank", URL_PART_SCHEME, 0, S_OK, "about"}, + {"about:blank", URL_PART_HOSTNAME, 0, E_FAIL}, + {"x-excid://36C00000/guid:{048B4E89-2E92-496F-A837-33BA02FF6D32}/Message.htm", URL_PART_SCHEME, 0, S_OK, "x-excid"}, + {"x-excid://36C00000/guid:{048B4E89-2E92-496F-A837-33BA02FF6D32}/Message.htm", URL_PART_HOSTNAME, 0, E_FAIL}, + {"x-excid://36C00000/guid:{048B4E89-2E92-496F-A837-33BA02FF6D32}/Message.htm", URL_PART_QUERY, 0, S_FALSE, ""}, + {"foo://bar-url/test", URL_PART_SCHEME, 0, S_OK, "foo"}, + {"foo://bar-url/test", URL_PART_HOSTNAME, 0, E_FAIL}, + {"foo://bar-url/test", URL_PART_QUERY, 0, S_FALSE, ""}, + {"ascheme:", URL_PART_SCHEME, 0, S_OK, "ascheme"}, + {"res://some.dll/find.dlg", URL_PART_SCHEME, 0, S_OK, "res"}, + {"res://some.dll/find.dlg", URL_PART_QUERY, 0, S_FALSE, ""}, + {"http://www.winehq.org", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, S_OK, "http:www.winehq.org"}, + {"file:///index.html", URL_PART_HOSTNAME, 0, S_FALSE, ""}, + {"file:///index.html", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, S_FALSE, ""}, + {"file://c:\\index.htm", URL_PART_HOSTNAME, 0, S_FALSE, ""}, + {"file://c:\\index.htm", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, S_FALSE, ""}, + {"file:some text", URL_PART_HOSTNAME, 0, S_FALSE, ""}, + {"index.htm", URL_PART_HOSTNAME, 0, E_FAIL}, + {"sChEmE-.+:", URL_PART_SCHEME, 0, S_OK, "scheme-.+"}, + {"scheme_:", URL_PART_SCHEME, 0, S_FALSE, ""}, + {"scheme :", URL_PART_SCHEME, 0, S_FALSE, ""}, + {"sch eme:", URL_PART_SCHEME, 0, S_FALSE, ""}, + {":", URL_PART_SCHEME, 0, S_FALSE, ""}, + {"a:", URL_PART_SCHEME, 0, S_FALSE, ""}, + {"0:", URL_PART_SCHEME, 0, S_FALSE, ""}, + {"ab:", URL_PART_SCHEME, 0, S_OK, "ab"}, - test_url_part(file_url, URL_PART_HOSTNAME, 0, "h o s t"); + {"about://hostname/", URL_PART_HOSTNAME, 0, E_FAIL}, + {"file://hostname/", URL_PART_HOSTNAME, 0, S_OK, "hostname"}, + {"ftp://hostname/", URL_PART_HOSTNAME, 0, S_OK, "hostname"}, + {"gopher://hostname/", URL_PART_HOSTNAME, 0, S_OK, "hostname"}, + {"http://hostname/", URL_PART_HOSTNAME, 0, S_OK, "hostname"}, + {"https://hostname/", URL_PART_HOSTNAME, 0, S_OK, "hostname"}, + {"javascript://hostname/", URL_PART_HOSTNAME, 0, E_FAIL}, + {"local://hostname/", URL_PART_HOSTNAME, 0, E_FAIL}, + {"mailto://hostname/", URL_PART_HOSTNAME, 0, E_FAIL}, + {"mk://hostname/", URL_PART_HOSTNAME, 0, E_FAIL}, + {"news://hostname/", URL_PART_HOSTNAME, 0, S_OK, "hostname"}, + {"nntp://hostname/", URL_PART_HOSTNAME, 0, S_OK, "hostname"}, + {"res://hostname/", URL_PART_HOSTNAME, 0, E_FAIL}, + {"shell://hostname/", URL_PART_HOSTNAME, 0, E_FAIL}, + {"snews://hostname/", URL_PART_HOSTNAME, 0, S_OK, "hostname"}, + {"telnet://hostname/", URL_PART_HOSTNAME, 0, S_OK, "hostname"}, + {"vbscript://hostname/", URL_PART_HOSTNAME, 0, E_FAIL}, + {"wais://hostname/", URL_PART_HOSTNAME, 0, E_FAIL}, - test_url_part(http_url, URL_PART_HOSTNAME, 0, "www.wine hq.org"); - test_url_part(http_url, URL_PART_PASSWORD, 0, "pass 123"); + {"file://hostname/", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, S_OK, "hostname"}, + {"ftp://hostname/", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, S_OK, "ftp:hostname"}, + {"gopher://hostname/", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, S_OK, "gopher:hostname"}, + {"http://hostname/", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, S_OK, "http:hostname"}, + {"https://hostname/", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, S_OK, "https:hostname"}, + {"news://hostname/", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, S_OK, "news:hostname"}, + {"nntp://hostname/", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, S_OK, "nntp:hostname"}, + {"snews://hostname/", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, S_OK, "snews:hostname"}, + {"telnet://hostname/", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, S_OK, "telnet:hostname"}, + }; - test_url_part(about_url, URL_PART_SCHEME, 0, "about"); + hr = UrlGetPartA(NULL, NULL, NULL, URL_PART_SCHEME, 0); + ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr); - test_url_part(excid_url, URL_PART_SCHEME, 0, "x-excid"); - test_url_part(foo_url, URL_PART_SCHEME, 0, "foo"); - test_url_part(short_url, URL_PART_SCHEME, 0, "ascheme"); + hr = UrlGetPartA(NULL, buffer, &size, URL_PART_SCHEME, 0); + ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr); - dwSize = sizeof(szPart); - res = pUrlGetPartA(about_url, szPart, &dwSize, URL_PART_HOSTNAME, 0); - ok(res==E_FAIL, "returned %08x\n", res); + hr = UrlGetPartA("res://some.dll/find.dlg", NULL, &size, URL_PART_SCHEME, 0); + ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr); - test_url_part(res_url, URL_PART_SCHEME, 0, "res"); - test_url_part("http://www.winehq.org", URL_PART_HOSTNAME, URL_PARTFLAG_KEEPSCHEME, "http:www.winehq.org"); + hr = UrlGetPartA("res://some.dll/find.dlg", buffer, NULL, URL_PART_SCHEME, 0); + ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr); - dwSize = sizeof szPart; - szPart[0]='x'; szPart[1]=0; - res = pUrlGetPartA(res_url, szPart, &dwSize, URL_PART_QUERY, 0); - ok(res==S_FALSE, "UrlGetPartA returned %08X\n", res); - ok(szPart[0]==0, "UrlGetPartA gave \"%s\" instead of \"\"\n", szPart); - ok(dwSize == 0, "dwSize = %d\n", dwSize); + size = 0; + strcpy(buffer, "x"); + hr = UrlGetPartA("hi", buffer, &size, URL_PART_SCHEME, 0); + ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr); + ok(!strcmp(buffer, "x"), "Got result %s.\n", debugstr_a(buffer)); + ok(!size, "Got size %lu.\n", size); +#ifdef __REACTOS__ + if (LOBYTE(LOWORD(GetVersion())) < 6) { + skip("UrlGetPart test list broken on WS03.\n"); + goto skip_UrlGetPartTestList; + } +#endif - dwSize = sizeof(szPart); - res = pUrlGetPartA("file://c:\\index.htm", szPart, &dwSize, URL_PART_HOSTNAME, 0); - ok(res==S_FALSE, "returned %08x\n", res); - ok(dwSize == 0, "dwSize = %d\n", dwSize); + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + WCHAR urlW[200], expectW[200]; + const char *expect = tests[i].expect; + const char *url = tests[i].url; + DWORD flags = tests[i].flags; + DWORD part = tests[i].part; - dwSize = sizeof(szPart); - szPart[0] = 'x'; szPart[1] = '\0'; - res = pUrlGetPartA("file:some text", szPart, &dwSize, URL_PART_HOSTNAME, 0); - ok(res==S_FALSE, "returned %08x\n", res); - ok(szPart[0] == '\0', "szPart[0] = %c\n", szPart[0]); - ok(dwSize == 0, "dwSize = %d\n", dwSize); + winetest_push_context("URL %s, part %#lx, flags %#lx", debugstr_a(url), part, flags); - dwSize = sizeof(szPart); - szPart[0] = 'x'; szPart[1] = '\0'; - res = pUrlGetPartA("index.htm", szPart, &dwSize, URL_PART_HOSTNAME, 0); - ok(res==E_FAIL, "returned %08x\n", res); + size = 1; + strcpy(buffer, "x"); + hr = UrlGetPartA(url, buffer, &size, part, flags); + if (tests[i].hr == S_OK) + ok(hr == E_POINTER, "Got hr %#lx.\n", hr); + else + ok(hr == tests[i].hr, "Got hr %#lx.\n", hr); - dwSize = sizeof(szPart); - szPart[0] = 'x'; szPart[1] = '\0'; - res = pUrlGetPartA(excid_url, szPart, &dwSize, URL_PART_HOSTNAME, 0); - ok(res==E_FAIL, "returned %08x\n", res); - ok(szPart[0] == 'x', "szPart[0] = %c\n", szPart[0]); - ok(dwSize == sizeof(szPart), "dwSize = %d\n", dwSize); + if (hr == S_FALSE) + { + ok(!size, "Got size %lu.\n", size); + ok(!buffer[0], "Got result %s.\n", debugstr_a(buffer)); + } + else + { + if (hr == E_POINTER) + ok(size == strlen(expect) + 1, "Got size %lu.\n", size); + else + ok(size == 1, "Got size %lu.\n", size); + ok(!strcmp(buffer, "x"), "Got result %s.\n", debugstr_a(buffer)); + } - dwSize = sizeof(szPart); - szPart[0] = 'x'; szPart[1] = '\0'; - res = pUrlGetPartA(excid_url, szPart, &dwSize, URL_PART_QUERY, 0); - ok(res==S_FALSE, "returned %08x\n", res); - ok(szPart[0] == 0, "szPart[0] = %c\n", szPart[0]); - ok(dwSize == 0, "dwSize = %d\n", dwSize); + size = sizeof(buffer); + strcpy(buffer, "x"); + hr = UrlGetPartA(url, buffer, &size, part, flags); + ok(hr == tests[i].hr, "Got hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + ok(size == strlen(buffer), "Got size %lu.\n", size); + ok(!strcmp(buffer, expect), "Got result %s.\n", debugstr_a(buffer)); + } + else + { + ok(size == sizeof(buffer), "Got size %lu.\n", size); + ok(!strcmp(buffer, "x"), "Got result %s.\n", debugstr_a(buffer)); + } - dwSize = sizeof(szPart); - szPart[0] = 'x'; szPart[1] = '\0'; - res = pUrlGetPartA(foo_url, szPart, &dwSize, URL_PART_HOSTNAME, 0); - ok(res==E_FAIL, "returned %08x\n", res); - ok(szPart[0] == 'x', "szPart[0] = %c\n", szPart[0]); - ok(dwSize == sizeof(szPart), "dwSize = %d\n", dwSize); + MultiByteToWideChar(CP_ACP, 0, url, -1, urlW, ARRAY_SIZE(urlW)); - dwSize = sizeof(szPart); - szPart[0] = 'x'; szPart[1] = '\0'; - res = pUrlGetPartA(foo_url, szPart, &dwSize, URL_PART_QUERY, 0); - ok(res==S_FALSE, "returned %08x\n", res); - ok(szPart[0] == 0, "szPart[0] = %c\n", szPart[0]); - ok(dwSize == 0, "dwSize = %d\n", dwSize); + size = 1; + wcscpy(bufferW, L"x"); + hr = UrlGetPartW(urlW, bufferW, &size, part, flags); + if (tests[i].hr == S_OK) + ok(hr == E_POINTER, "Got hr %#lx.\n", hr); + else + ok(hr == (tests[i].hr == S_FALSE ? S_OK : tests[i].hr), "Got hr %#lx.\n", hr); + + if (SUCCEEDED(hr)) + { + ok(!size, "Got size %lu.\n", size); + ok(!buffer[0], "Got result %s.\n", debugstr_a(buffer)); + } + else + { + if (hr == E_POINTER) + ok(size == strlen(expect) + 1, "Got size %lu.\n", size); + else + ok(size == 1, "Got size %lu.\n", size); + ok(!wcscmp(bufferW, L"x"), "Got result %s.\n", debugstr_w(bufferW)); + } + + size = ARRAY_SIZE(bufferW); + wcscpy(bufferW, L"x"); + hr = UrlGetPartW(urlW, bufferW, &size, part, flags); + ok(hr == (tests[i].hr == S_FALSE ? S_OK : tests[i].hr), "Got hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + ok(size == wcslen(bufferW), "Got size %lu.\n", size); + MultiByteToWideChar(CP_ACP, 0, buffer, -1, expectW, ARRAY_SIZE(expectW)); + ok(!wcscmp(bufferW, expectW), "Got result %s.\n", debugstr_w(bufferW)); + } + else + { + ok(size == ARRAY_SIZE(bufferW), "Got size %lu.\n", size); + ok(!wcscmp(bufferW, L"x"), "Got result %s.\n", debugstr_w(bufferW)); + } + + winetest_pop_context(); + } + + /* Test non-ASCII characters. */ +#ifdef __REACTOS__ +skip_UrlGetPartTestList: +#endif + + size = ARRAY_SIZE(bufferW); + wcscpy(bufferW, L"x"); + hr = UrlGetPartW(L"http://\x01\x7f\x80\xff:pass@host", bufferW, &size, URL_PART_USERNAME, 0); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(size == wcslen(bufferW), "Got size %lu.\n", size); + ok(!wcscmp(bufferW, L"\x01\x7f\x80\xff"), "Got result %s.\n", debugstr_w(bufferW)); } /* ########################### */ -static void test_url_canonicalize(int index, const char *szUrl, DWORD dwFlags, HRESULT dwExpectReturn, HRESULT dwExpectReturnAlt, const char *szExpectUrl, BOOL todo) +static void check_url_canonicalize(const char *url, DWORD flags, const char *expect) { - CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH]; - WCHAR wszReturnUrl[INTERNET_MAX_URL_LENGTH]; - LPWSTR wszUrl = GetWideString(szUrl); - LPWSTR wszExpectUrl = GetWideString(szExpectUrl); - LPWSTR wszConvertedUrl; - HRESULT ret; + char output[INTERNET_MAX_URL_LENGTH]; + WCHAR outputW[INTERNET_MAX_URL_LENGTH]; + WCHAR *urlW = GetWideString(url); + WCHAR *expectW; + HRESULT hr; + DWORD size; - DWORD dwSize; + winetest_push_context("URL %s, flags %#lx", debugstr_a(url), flags); - dwSize = INTERNET_MAX_URL_LENGTH; - ret = pUrlCanonicalizeA(szUrl, NULL, &dwSize, dwFlags); - ok(ret != dwExpectReturn, "got 0s%x: Unexpected return for NULL buffer, index %d\n", ret, index); - ret = pUrlCanonicalizeA(szUrl, szReturnUrl, &dwSize, dwFlags); - ok(ret == dwExpectReturn || ret == dwExpectReturnAlt, - "UrlCanonicalizeA failed: expected=0x%08x or 0x%08x, got=0x%08x, index %d\n", - dwExpectReturn, dwExpectReturnAlt, ret, index); - todo_wine_if (todo) - ok(strcmp(szReturnUrl,szExpectUrl)==0, "UrlCanonicalizeA dwFlags 0x%08x url '%s' Expected \"%s\", but got \"%s\", index %d\n", dwFlags, szUrl, szExpectUrl, szReturnUrl, index); + size = INTERNET_MAX_URL_LENGTH; + hr = UrlCanonicalizeA(url, NULL, &size, flags); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + hr = UrlCanonicalizeA(url, output, &size, flags); + ok(hr == S_OK || (!url[0] && hr == S_FALSE) /* Vista+ */, "Got unexpected hr %#lx.\n", hr); + ok(!strcmp(output, expect), "Expected %s, got %s.\n", debugstr_a(expect), debugstr_a(output)); - if (pUrlCanonicalizeW) { - dwSize = INTERNET_MAX_URL_LENGTH; - ret = pUrlCanonicalizeW(wszUrl, NULL, &dwSize, dwFlags); - ok(ret != dwExpectReturn, "got 0x%x: Unexpected return for NULL buffer, index %d\n", ret, index); - ret = pUrlCanonicalizeW(wszUrl, wszReturnUrl, &dwSize, dwFlags); - ok(ret == dwExpectReturn, "UrlCanonicalizeW failed: expected 0x%08x, got 0x%x, index %d\n", - dwExpectReturn, ret, index); + size = INTERNET_MAX_URL_LENGTH; + hr = UrlCanonicalizeW(urlW, NULL, &size, flags); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + hr = UrlCanonicalizeW(urlW, outputW, &size, flags); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); - wszConvertedUrl = GetWideString(szReturnUrl); - ok(lstrcmpW(wszReturnUrl, wszConvertedUrl)==0, - "Strings didn't match between ascii and unicode UrlCanonicalize, index %d!\n", index); - FreeWideString(wszConvertedUrl); - } + expectW = GetWideString(output); + ok(!wcscmp(outputW, expectW), "Expected %s, got %s.\n", debugstr_w(expectW), debugstr_w(outputW)); + FreeWideString(expectW); - FreeWideString(wszUrl); - FreeWideString(wszExpectUrl); + FreeWideString(urlW); + + winetest_pop_context(); } @@ -898,53 +831,50 @@ static void test_UrlEscapeA(void) unsigned int i; char empty_string[] = ""; - if (!pUrlEscapeA) { - win_skip("UrlEscapeA not found\n"); - return; - } - - ret = pUrlEscapeA("/woningplan/woonkamer basis.swf", NULL, &size, URL_ESCAPE_SPACES_ONLY); - ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG); - ok(size == 0, "got %d, expected %d\n", size, 0); + ret = UrlEscapeA("/woningplan/woonkamer basis.swf", NULL, &size, URL_ESCAPE_SPACES_ONLY); + ok(ret == E_INVALIDARG, "got %lx, expected %lx\n", ret, E_INVALIDARG); + ok(size == 0, "got %ld, expected %d\n", size, 0); size = 0; - ret = pUrlEscapeA("/woningplan/woonkamer basis.swf", empty_string, &size, URL_ESCAPE_SPACES_ONLY); - ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG); - ok(size == 0, "got %d, expected %d\n", size, 0); + ret = UrlEscapeA("/woningplan/woonkamer basis.swf", empty_string, &size, URL_ESCAPE_SPACES_ONLY); + ok(ret == E_INVALIDARG, "got %lx, expected %lx\n", ret, E_INVALIDARG); + ok(size == 0, "got %ld, expected %d\n", size, 0); size = 1; - ret = pUrlEscapeA("/woningplan/woonkamer basis.swf", NULL, &size, URL_ESCAPE_SPACES_ONLY); - ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG); - ok(size == 1, "got %d, expected %d\n", size, 1); + ret = UrlEscapeA("/woningplan/woonkamer basis.swf", NULL, &size, URL_ESCAPE_SPACES_ONLY); + ok(ret == E_INVALIDARG, "got %lx, expected %lx\n", ret, E_INVALIDARG); + ok(size == 1, "got %ld, expected %d\n", size, 1); size = 1; - ret = pUrlEscapeA("/woningplan/woonkamer basis.swf", empty_string, NULL, URL_ESCAPE_SPACES_ONLY); - ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG); - ok(size == 1, "got %d, expected %d\n", size, 1); + ret = UrlEscapeA("/woningplan/woonkamer basis.swf", empty_string, NULL, URL_ESCAPE_SPACES_ONLY); + ok(ret == E_INVALIDARG, "got %lx, expected %lx\n", ret, E_INVALIDARG); + ok(size == 1, "got %ld, expected %d\n", size, 1); size = 1; empty_string[0] = 127; - ret = pUrlEscapeA("/woningplan/woonkamer basis.swf", empty_string, &size, URL_ESCAPE_SPACES_ONLY); - ok(ret == E_POINTER, "got %x, expected %x\n", ret, E_POINTER); - ok(size == 34, "got %d, expected %d\n", size, 34); + ret = UrlEscapeA("/woningplan/woonkamer basis.swf", empty_string, &size, URL_ESCAPE_SPACES_ONLY); + ok(ret == E_POINTER, "got %lx, expected %lx\n", ret, E_POINTER); + ok(size == 34, "got %ld, expected %d\n", size, 34); ok(empty_string[0] == 127, "String has changed, empty_string[0] = %d\n", empty_string[0]); size = 1; empty_string[0] = 127; - ret = pUrlEscapeA("/woningplan/woonkamer basis.swf", empty_string, &size, URL_ESCAPE_AS_UTF8); - ok(ret == E_NOTIMPL || broken(ret == E_POINTER), /* < Win7/Win2k8 */ - "got %x, expected %x\n", ret, E_NOTIMPL); - ok(size == 1 || broken(size == 34), /* < Win7/Win2k8 */ - "got %d, expected %d\n", size, 1); + ret = UrlEscapeA("/woningplan/woonkamer basis.swf", empty_string, &size, URL_ESCAPE_AS_UTF8); +#ifdef __REACTOS__ + ok(ret == E_NOTIMPL || broken(ret == E_POINTER) /* Vista */, "Got unexpected hr %#lx.\n", ret); + ok(size == 1 || broken(size == 34) /* Vista */, "Got unexpected size %lu.\n", size); +#else + ok(ret == E_NOTIMPL, "Got unexpected hr %#lx.\n", ret); + ok(size == 1, "Got unexpected size %lu.\n", size); +#endif ok(empty_string[0] == 127, "String has changed, empty_string[0] = %d\n", empty_string[0]); for (i = 0; i < ARRAY_SIZE(TEST_ESCAPE); i++) { CHAR ret_url[INTERNET_MAX_URL_LENGTH]; size = INTERNET_MAX_URL_LENGTH; - ret = pUrlEscapeA(TEST_ESCAPE[i].url, ret_url, &size, TEST_ESCAPE[i].flags); - ok(ret == TEST_ESCAPE[i].expectret, "UrlEscapeA returned 0x%08x instead of 0x%08x for \"%s\"\n", - ret, TEST_ESCAPE[i].expectret, TEST_ESCAPE[i].url); + ret = UrlEscapeA(TEST_ESCAPE[i].url, ret_url, &size, TEST_ESCAPE[i].flags); + ok(ret == S_OK, "Got unexpected hr %#lx for %s.\n", ret, debugstr_a(TEST_ESCAPE[i].url)); ok(!strcmp(ret_url, TEST_ESCAPE[i].expecturl), "Expected \"%s\", but got \"%s\" for \"%s\"\n", TEST_ESCAPE[i].expecturl, ret_url, TEST_ESCAPE[i].url); } @@ -952,77 +882,73 @@ static void test_UrlEscapeA(void) static void test_UrlEscapeW(void) { - static const WCHAR path_test[] = {'/','t','e','s','t',0}; - static const WCHAR naW[] = {'f','t','p',31,255,250,0x2122,'e','n','d','/',0}; - static const WCHAR naescapedW[] = {'f','t','p','%','1','F','%','F','F','%','F','A',0x2122,'e','n','d','/',0}; - static const WCHAR out[] = {'f','o','o','%','2','0','b','a','r',0}; - WCHAR overwrite[] = {'f','o','o',' ','b','a','r',0,0,0}; WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH]; + WCHAR overwrite[10] = L"foo bar"; WCHAR empty_string[] = {0}; DWORD size; HRESULT ret; WCHAR wc; int i; - - if (!pUrlEscapeW) { - win_skip("UrlEscapeW not found\n"); - return; - } +#ifdef __REACTOS__ + DWORD _ntVersion = GetVersion(); + BYTE _ntMajor = LOBYTE(LOWORD(_ntVersion)); + BYTE _ntMinor = HIBYTE(LOWORD(_ntVersion)); +#endif /* Check error paths */ - ret = UrlEscapeW(path_test, NULL, NULL, URL_ESCAPE_SPACES_ONLY); - ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG); + ret = UrlEscapeW(L"/test", NULL, NULL, URL_ESCAPE_SPACES_ONLY); + ok(ret == E_INVALIDARG, "got %lx, expected %lx\n", ret, E_INVALIDARG); size = 0; - ret = UrlEscapeW(path_test, NULL, &size, URL_ESCAPE_SPACES_ONLY); - ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG); - ok(size == 0, "got %d, expected %d\n", size, 0); + ret = UrlEscapeW(L"/test", NULL, &size, URL_ESCAPE_SPACES_ONLY); + ok(ret == E_INVALIDARG, "got %lx, expected %lx\n", ret, E_INVALIDARG); + ok(size == 0, "got %ld, expected %d\n", size, 0); - ret = UrlEscapeW(path_test, empty_string, NULL, URL_ESCAPE_SPACES_ONLY); - ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG); + ret = UrlEscapeW(L"/test", empty_string, NULL, URL_ESCAPE_SPACES_ONLY); + ok(ret == E_INVALIDARG, "got %lx, expected %lx\n", ret, E_INVALIDARG); size = 0; - ret = UrlEscapeW(path_test, empty_string, &size, URL_ESCAPE_SPACES_ONLY); - ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG); - ok(size == 0, "got %d, expected %d\n", size, 0); + ret = UrlEscapeW(L"/test", empty_string, &size, URL_ESCAPE_SPACES_ONLY); + ok(ret == E_INVALIDARG, "got %lx, expected %lx\n", ret, E_INVALIDARG); + ok(size == 0, "got %ld, expected %d\n", size, 0); - ret = UrlEscapeW(path_test, NULL, NULL, URL_ESCAPE_SPACES_ONLY); - ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG); + ret = UrlEscapeW(L"/test", NULL, NULL, URL_ESCAPE_SPACES_ONLY); + ok(ret == E_INVALIDARG, "got %lx, expected %lx\n", ret, E_INVALIDARG); size = 1; - ret = UrlEscapeW(path_test, NULL, &size, URL_ESCAPE_SPACES_ONLY); - ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG); - ok(size == 1, "got %d, expected %d\n", size, 1); + ret = UrlEscapeW(L"/test", NULL, &size, URL_ESCAPE_SPACES_ONLY); + ok(ret == E_INVALIDARG, "got %lx, expected %lx\n", ret, E_INVALIDARG); + ok(size == 1, "got %ld, expected %d\n", size, 1); - ret = UrlEscapeW(path_test, empty_string, NULL, URL_ESCAPE_SPACES_ONLY); - ok(ret == E_INVALIDARG, "got %x, expected %x\n", ret, E_INVALIDARG); + ret = UrlEscapeW(L"/test", empty_string, NULL, URL_ESCAPE_SPACES_ONLY); + ok(ret == E_INVALIDARG, "got %lx, expected %lx\n", ret, E_INVALIDARG); size = 1; - ret = UrlEscapeW(path_test, empty_string, &size, URL_ESCAPE_SPACES_ONLY); - ok(ret == E_POINTER, "got %x, expected %x\n", ret, E_POINTER); - ok(size == 6, "got %d, expected %d\n", size, 6); + ret = UrlEscapeW(L"/test", empty_string, &size, URL_ESCAPE_SPACES_ONLY); + ok(ret == E_POINTER, "got %lx, expected %lx\n", ret, E_POINTER); + ok(size == 6, "got %ld, expected %d\n", size, 6); /* Check actual escaping */ size = ARRAY_SIZE(overwrite); - ret = pUrlEscapeW(overwrite, overwrite, &size, URL_ESCAPE_SPACES_ONLY); - ok(ret == S_OK, "got %x, expected S_OK\n", ret); - ok(size == 9, "got %d, expected 9\n", size); - ok(!lstrcmpW(overwrite, out), "got %s, expected %s\n", wine_dbgstr_w(overwrite), wine_dbgstr_w(out)); + ret = UrlEscapeW(overwrite, overwrite, &size, URL_ESCAPE_SPACES_ONLY); + ok(ret == S_OK, "got %lx, expected S_OK\n", ret); + ok(size == 9, "got %ld, expected 9\n", size); + ok(!wcscmp(overwrite, L"foo%20bar"), "Got unexpected string %s.\n", debugstr_w(overwrite)); size = 1; wc = 127; - ret = pUrlEscapeW(overwrite, &wc, &size, URL_ESCAPE_SPACES_ONLY); - ok(ret == E_POINTER, "got %x, expected %x\n", ret, E_POINTER); - ok(size == 10, "got %d, expected 10\n", size); + ret = UrlEscapeW(overwrite, &wc, &size, URL_ESCAPE_SPACES_ONLY); + ok(ret == E_POINTER, "got %lx, expected %lx\n", ret, E_POINTER); + ok(size == 10, "got %ld, expected 10\n", size); ok(wc == 127, "String has changed, wc = %d\n", wc); /* non-ASCII range */ size = ARRAY_SIZE(ret_urlW); - ret = pUrlEscapeW(naW, ret_urlW, &size, 0); - ok(ret == S_OK, "got %x, expected S_OK\n", ret); - ok(!lstrcmpW(naescapedW, ret_urlW), "got %s, expected %s\n", wine_dbgstr_w(ret_urlW), wine_dbgstr_w(naescapedW)); + ret = UrlEscapeW(L"ftp\x1f\xff\xfa\x2122q/", ret_urlW, &size, 0); + ok(ret == S_OK, "got %lx, expected S_OK\n", ret); + ok(!wcscmp(ret_urlW, L"ftp%1F%FF%FA\x2122q/"), "Got unexpected string %s.\n", debugstr_w(ret_urlW)); for (i = 0; i < ARRAY_SIZE(TEST_ESCAPE); i++) { @@ -1031,10 +957,9 @@ static void test_UrlEscapeW(void) size = INTERNET_MAX_URL_LENGTH; urlW = GetWideString(TEST_ESCAPE[i].url); expected_urlW = GetWideString(TEST_ESCAPE[i].expecturl); - ret = pUrlEscapeW(urlW, ret_urlW, &size, TEST_ESCAPE[i].flags); - ok(ret == TEST_ESCAPE[i].expectret, "UrlEscapeW returned 0x%08x instead of 0x%08x for %s\n", - ret, TEST_ESCAPE[i].expectret, wine_dbgstr_w(urlW)); - ok(!lstrcmpW(ret_urlW, expected_urlW), "Expected %s, but got %s for %s flags %08x\n", + ret = UrlEscapeW(urlW, ret_urlW, &size, TEST_ESCAPE[i].flags); + ok(ret == S_OK, "Got unexpected hr %#lx for %s.\n", ret, debugstr_w(urlW)); + ok(!lstrcmpW(ret_urlW, expected_urlW), "Expected %s, but got %s for %s flags %08lx\n", wine_dbgstr_w(expected_urlW), wine_dbgstr_w(ret_urlW), wine_dbgstr_w(urlW), TEST_ESCAPE[i].flags); FreeWideString(urlW); FreeWideString(expected_urlW); @@ -1043,45 +968,1105 @@ static void test_UrlEscapeW(void) for (i = 0; i < ARRAY_SIZE(TEST_ESCAPEW); i++) { WCHAR ret_url[INTERNET_MAX_URL_LENGTH]; +#ifdef __REACTOS__ + /* TEST_ESCAPEW[6, 7] is incorrect for WS03, Vista. */ + if ((i == 6 || i == 7) && (_ntMajor < 6 || (_ntMajor == 6 && _ntMinor == 0))) + continue; +#endif size = INTERNET_MAX_URL_LENGTH; - ret = pUrlEscapeW(TEST_ESCAPEW[i].url, ret_url, &size, TEST_ESCAPEW[i].flags); - ok(ret == TEST_ESCAPEW[i].expectret, "UrlEscapeW returned 0x%08x instead of 0x%08x for \"%s\"\n", - ret, TEST_ESCAPEW[i].expectret, wine_dbgstr_w(TEST_ESCAPEW[i].url)); - ok(!lstrcmpW(ret_url, TEST_ESCAPEW[i].expecturl) || - broken(!lstrcmpW(ret_url, TEST_ESCAPEW[i].vistaurl)) || - broken(!lstrcmpW(ret_url, TEST_ESCAPEW[i].win7url)), - "Expected \"%s\" or \"%s\" or \"%s\", but got \"%s\" for \"%s\"\n", - wine_dbgstr_w(TEST_ESCAPEW[i].expecturl), wine_dbgstr_w(TEST_ESCAPEW[i].vistaurl), - wine_dbgstr_w(TEST_ESCAPEW[i].win7url), wine_dbgstr_w(ret_url), wine_dbgstr_w(TEST_ESCAPEW[i].url)); + ret = UrlEscapeW(TEST_ESCAPEW[i].url, ret_url, &size, TEST_ESCAPEW[i].flags); + ok(ret == S_OK, "Got unexpected hr %#lx for %s.\n", ret, debugstr_w(TEST_ESCAPEW[i].url)); + ok(!wcscmp(ret_url, TEST_ESCAPEW[i].expecturl) + || broken(!wcscmp(ret_url, TEST_ESCAPEW[i].win7url)), + "Expected %s, but got %s for %s.\n", debugstr_w(TEST_ESCAPEW[i].expecturl), + debugstr_w(ret_url), debugstr_w(TEST_ESCAPEW[i].url)); } } -/* ########################### */ +struct canonicalize_test +{ + const char *url; + DWORD flags; + const char *expect; +}; static void test_UrlCanonicalizeA(void) { - unsigned int i; CHAR szReturnUrl[4*INTERNET_MAX_URL_LENGTH]; CHAR longurl[4*INTERNET_MAX_URL_LENGTH]; + char url[200], expect[200]; + unsigned int f, i, j; DWORD dwSize; DWORD urllen; HRESULT hr; - if (!pUrlCanonicalizeA) { - win_skip("UrlCanonicalizeA not found\n"); - return; + static const struct canonicalize_test unk_scheme_tests[] = + { + /* Single and double dots behave as one would expect, with the following + * notable rules: + * + * (1) A single or double dot as the first element (the "hostname") is + * always emitted as-is. + * + * (2) If a double dot would undo the hostname, it is emitted as-is + * instead. + * + * (3) If a single or double dot is the last element (either because of + * the above rule or because of URL_DONT_SIMPLIFY), a trailing + * backslash is appended. + * + * A trailing backslash is always appended after the hostname. + */ + + {"//", 0, "///"}, + {"//a", 0, "//a/"}, + {"//a/", 0, "//a/"}, + {"//a/b", 0, "//a/b"}, + {"//a/b/", 0, "//a/b/"}, + {"//.", 0, "//./"}, + {"//./", 0, "//./"}, + {"//./a", 0, "//./a"}, + {"//././a", 0, "//./a"}, + {"//a/.", 0, "//a/"}, + {"//a/./", 0, "//a/"}, + {"//a/./b", 0, "//a/b"}, + {"///./a", 0, "///a"}, + {"//a/.b/", 0, "//a/.b/"}, + {"//a/b./", 0, "//a/b./"}, + + {"//..", 0, "//../"}, + {"//../", 0, "//../"}, + {"//../a", 0, "//../a"}, + {"//../a/..", 0, "//../"}, + {"//.././..", 0, "//../../"}, + {"//../a/../..", 0, "//../../"}, + {"//./a/../..", 0, "//./../"}, + {"//a/..", 0, "//a/../"}, + {"//a/../../b/./c/..", 0, "//a/../../b/"}, + {"//a/b/..", 0, "//a/"}, + {"//a/b/...", 0, "//a/b/..."}, + {"//a/b/../", 0, "//a/"}, + {"//a/b/../c", 0, "//a/c"}, + {"//a/b/../c/..", 0, "//a/"}, + {"//a/b/../c/../..", 0, "//a/../"}, + {"//a/b/../../../c", 0, "//a/../../c"}, + {"///..", 0, "///../"}, + {"////..", 0, "///"}, + {"//a/..b/", 0, "//a/..b/"}, + {"//a/b../", 0, "//a/b../"}, + {"//A/B", 0, "//A/B"}, + + {"//././a", URL_DONT_SIMPLIFY, "//././a"}, + {"//a/.", URL_DONT_SIMPLIFY, "//a/./"}, + {"//a/./", URL_DONT_SIMPLIFY, "//a/./"}, + {"//a/./b", URL_DONT_SIMPLIFY, "//a/./b"}, + {"///./a", URL_DONT_SIMPLIFY, "///./a"}, + + {"//..", URL_DONT_SIMPLIFY, "//../"}, + {"//../", URL_DONT_SIMPLIFY, "//../"}, + {"//../a", URL_DONT_SIMPLIFY, "//../a"}, + {"//../a/..", URL_DONT_SIMPLIFY, "//../a/../"}, + {"//../a/...", URL_DONT_SIMPLIFY, "//../a/..."}, + {"//.././..", URL_DONT_SIMPLIFY, "//.././../"}, + {"//../a/../..", URL_DONT_SIMPLIFY, "//../a/../../"}, + {"//./a/../..", URL_DONT_SIMPLIFY, "//./a/../../"}, + {"//a/..", URL_DONT_SIMPLIFY, "//a/../"}, + {"//a/../../b/./c/..", URL_DONT_SIMPLIFY, "//a/../../b/./c/../"}, + {"//a/b/..", URL_DONT_SIMPLIFY, "//a/b/../"}, + {"//a/b/../", URL_DONT_SIMPLIFY, "//a/b/../"}, + {"//a/b/../c", URL_DONT_SIMPLIFY, "//a/b/../c"}, + {"//a/b/../c/..", URL_DONT_SIMPLIFY, "//a/b/../c/../"}, + {"//a/b/../c/../..", URL_DONT_SIMPLIFY, "//a/b/../c/../../"}, + {"///..", URL_DONT_SIMPLIFY, "///../"}, + {"////..", URL_DONT_SIMPLIFY, "////../"}, + + /* After ? or #, dots are not simplified. */ + {"//a/b?c/./d", 0, "//a/b?c/./d"}, + {"//a/b#c/./d", 0, "//a/b#c/./d"}, + {"//a/b#c/.", 0, "//a/b#c/."}, + /* ? and # can also be considered a boundary for trailing dots. */ + {"//a/b/.?", 0, "//a/b/?"}, + {"//a/b/..?", 0, "//a/?"}, + {"//a/b/..?", URL_DONT_SIMPLIFY, "//a/b/../?"}, + {"//a/b/.#", 0, "//a/b/#"}, + {"//a/b/..#", 0, "//a/#"}, + {"//a/b/..#", URL_DONT_SIMPLIFY, "//a/b/../#"}, + {"//a/..?", 0, "//a/../?"}, + {"//a/..#", 0, "//a/../#"}, + {"//..?", 0, "//../?"}, + {"//..#", 0, "//../#"}, + {"//?/a/./", 0, "///?/a/./"}, + {"//#/a/./", 0, "///#/a/./"}, + /* The first ? is reordered before the first #. */ + {"//a/b#c?d", 0, "//a/b?d#c"}, + {"//a/b?c#d?e", 0, "//a/b?c#d?e"}, + {"//a/b#c?d#e", 0, "//a/b?d#e#c"}, + {"//a/b#c#d?e", 0, "//a/b?e#c#d"}, + {"//a/b#c?d?e", 0, "//a/b?d?e#c"}, + + /* Backslashes are not treated as path separators. */ + {"//a/b\\c/../.\\", 0, "//a/.\\"}, + {"//a\\b/../", 0, "//a\\b/../"}, + {"//a/b\\../", 0, "//a/b\\../"}, + {"//a/b/..\\", 0, "//a/b/..\\"}, + + /* Whitespace and unsafe characters are not (by default) escaped. */ + {"//a/b &c", 0, "//a/b &c"}, + + /* If one slash is omitted, the rules are much the same, except that + * there is no "hostname". Single dots are always collapsed; double dots + * are collapsed unless they would undo the "scheme". */ + + {"/a", 0, "/a"}, + {"/a/", 0, "/a/"}, + {"/.", 0, "/"}, + {"/./", 0, "/"}, + {"/././a", 0, "/a"}, + {"/a/.", 0, "/a/"}, + {"/a/./", 0, "/a/"}, + {"/a/./b", 0, "/a/b"}, + + {"/..", 0, "/../"}, + {"/../", 0, "/../"}, + {"/../a", 0, "/../a"}, + {"/../a/..", 0, "/../"}, + {"/a/..", 0, "/"}, + {"/a/../..", 0, "/../"}, + {"/a/b/..", 0, "/a/"}, + {"/a/b/../", 0, "/a/"}, + {"/a/b/../c", 0, "/a/c"}, + {"/a/b/../c/..", 0, "/a/"}, + {"/a/b/../c/../..", 0, "/"}, + + {"/a/b?c/./d", 0, "/a/b?c/./d"}, + {"/a/b#c/./d", 0, "/a/b#c/./d"}, + {"/a/b#c?d", 0, "/a/b?d#c"}, + + /* Just as above, backslashes are not treated as path separators. */ + {"/a/b\\c/../.\\", 0, "/a/.\\"}, + {"/a/b\\/c", 0, "/a/b\\/c"}, + {"/a/b\\.c", 0, "/a/b\\.c"}, + /* If the first character after the slash is a backslash, it is skipped. + * It is not interpreted as a forward slash. + * The tests above show that this is not due to the backslash being + * interpreted as an escape character. */ + {"/\\././a", 0, "/a"}, + /* The sequence /\/ does not result in use of the double-slash rules. + * Rather, the resulting // is treated as an empty path element. */ + {"/\\/././a", 0, "//a"}, + {"/\\/././a/", 0, "//a/"}, + {"/\\/..", 0, "/"}, + {"//a/\\b", 0, "//a/\\b"}, + + {"/a/b &c", 0, "/a/b &c"}, + + {"//a/b%20%26c", URL_UNESCAPE, "//a/b &c"}, + }; + + static const struct + { + const char *url; + DWORD flags; + const char *expect; + const char *expect_ftp; } + http_tests[] = + { + /* A set of schemes including http differs from the "default" behaviour + * in the following ways: + * + * (1) If a double dot would undo the hostname, it is dropped instead. + * + * (2) If the first element after the hostname is a single or double + * dot, no further dots are simplified. + * + * (3) Trailing backslashes are not automatically appended after dots. + */ + + {"//", 0, "///"}, + {"//a", 0, "//a/"}, + {"//a/", 0, "//a/"}, + {"//a/b", 0, "//a/b"}, + {"//a/b/", 0, "//a/b/"}, + {"//.", 0, "//./"}, + {"//./", 0, "//./"}, + {"//././a/.", 0, "//././a/."}, + {"//a/.", 0, "//a/."}, + {"//a/./b/./../", 0, "//a/./b/./../"}, + {"//a/b/.", 0, "//a/b/"}, + {"//a/b/.", URL_DONT_SIMPLIFY, "//a/b/."}, + {"//a/b/./", 0, "//a/b/"}, + {"//a/b/./c", 0, "//a/b/c"}, + {"///./a", 0, "///./a"}, + {"////./a", 0, "////a"}, + + {"//..", 0, "//../"}, + {"//../", 0, "//../"}, + {"//../a", 0, "//../a"}, + {"//../a/..", 0, "//../"}, + {"//../a/../..", 0, "//../"}, + {"//./a/../..", 0, "//./"}, + {"//a/../", 0, "//a/../"}, + {"//a/../../b/./../", 0, "//a/../../b/./../"}, + {"//a/.././", 0, "//a/.././"}, + {"//a/b/..", 0, "//a/"}, + {"//a/b/..", URL_DONT_SIMPLIFY, "//a/b/.."}, + {"//a/b/../", 0, "//a/"}, + {"//a/b/.././", 0, "//a/"}, + {"//a/b/../c", 0, "//a/c"}, + {"//a/b/../c/..", 0, "//a/"}, + {"//a/b/../c/../..", 0, "//a/"}, + {"//a/b/../../../c", 0, "//a/c"}, + {"///a/.", 0, "///a/"}, + {"///..", 0, "///.."}, + {"////..", 0, "///"}, + {"//a//../../..", 0, "//a/"}, + + {"//a/b?c/./d", 0, "//a/b?c/./d"}, + {"//a/b#c/./d", 0, "//a/b#c/./d"}, + {"//a/b#c?d", 0, "//a/b#c?d"}, + {"//a/b?c#d", 0, "//a/b?c#d"}, + + {"//localhost/b", 0, "//localhost/b"}, + + /* Most of these schemes translates backslashes to forward slashes, + * including the initial pair, and interpret them appropriately. + * + * A few schemes, including ftp, don't translate backslashes to forward + * slashes, but still interpret them as path separators, with the + * exception that the hostname must end in a forward slash. */ + + {"//a/b\\", 0, "//a/b/", "//a/b\\"}, + {"//a/b\\./c", 0, "//a/b/c", "//a/b\\c"}, + {"//a/b/.\\c", 0, "//a/b/c"}, + {"//a/b\\c/../.\\", 0, "//a/b/", "//a/b\\"}, + {"//a\\b", 0, "//a/b", "//a\\b/"}, + {"//a\\b/..", 0, "//a/", "//a\\b/.."}, + {"//a/b\\c", 0, "//a/b/c", "//a/b\\c"}, + {"/\\a\\..", 0, "//a/..", "/\\a\\../"}, + {"\\/a\\..", 0, "//a/..", "\\/a\\../"}, + + {"//a/b &c", 0, "//a/b &c"}, + + /* If one or both slashes is missing, the portion after the colon is + * treated like a normal path, without a hostname. Single and double + * dots are always collapsed, and double dots which would rewind past + * the scheme are dropped instead. */ + + {"a", 0, "a"}, + {"a/", 0, "a/"}, + {"a/.", 0, "a/"}, + {"a/..", 0, ""}, + {"a/../..", 0, ""}, + {"a/../..", URL_DONT_SIMPLIFY, "a/../.."}, + {"", 0, ""}, + {"/", 0, "/"}, + {"/.", 0, "/"}, + {"/..", 0, ""}, + {"/../..", 0, ""}, + {".", 0, ""}, + {"..", 0, ""}, + {"./", 0, ""}, + {"../", 0, ""}, + + {"a/b?c/.\\d", 0, "a/b?c/.\\d"}, + {"a/b#c/.\\d", 0, "a/b#c/.\\d"}, + + {"a\\b\\", 0, "a/b/", "a\\b\\"}, + + {"a/b &c", 0, "a/b &c"}, + + {"/foo/bar/baz", URL_ESCAPE_SEGMENT_ONLY, "/foo/bar/baz"}, + {"/foo/bar/baz?a#b", URL_ESCAPE_SEGMENT_ONLY, "/foo/bar/baz?a#b"}, + + {"//www.winehq.org/tests\n", URL_ESCAPE_SPACES_ONLY | URL_ESCAPE_UNSAFE, "//www.winehq.org/tests"}, + {"//www.winehq.org/tests\r", URL_ESCAPE_SPACES_ONLY | URL_ESCAPE_UNSAFE, "//www.winehq.org/tests"}, + {"//www.winehq.org/tests/foo bar", URL_ESCAPE_SPACES_ONLY | URL_DONT_ESCAPE_EXTRA_INFO, "//www.winehq.org/tests/foo%20bar"}, + {"//www.winehq.org/tests/foo%20bar", 0, "//www.winehq.org/tests/foo%20bar"}, + {"//www.winehq.org/tests/foo%20bar", URL_UNESCAPE, "//www.winehq.org/tests/foo bar"}, + {"//www.winehq.org/%E6%A1%9C.html", 0, "//www.winehq.org/%E6%A1%9C.html"}, + }; + + static const struct canonicalize_test opaque_tests[] = + { + /* Opaque protocols, predictably, do not modify the portion after the + * scheme. */ + {"//a/b/./c/../d\\e", 0, "//a/b/./c/../d\\e"}, + {"/a/b/./c/../d\\e", 0, "/a/b/./c/../d\\e"}, + {"a/b/./c/../d\\e", 0, "a/b/./c/../d\\e"}, + {"", 0, ""}, + {"//a/b &c", 0, "//a/b &c"}, + {"//a/b%20%26c", URL_UNESCAPE, "//a/b &c"}, + }; + + static const struct canonicalize_test file_tests[] = + { + /* file:// is almost identical to http://, except that a URL beginning + * with file://// (four or more slashes) is stripped down to two + * slashes. The first non-empty element is interpreted as a hostname; + * and the rest follows the usual rules. + * + * The intent here is probably to detect UNC paths, although it's + * unclear why an arbitrary number of slashes are skipped in that case. + */ + + {"file://", 0, "file:///"}, + {"file://a", 0, "file://a/"}, + {"file://a/", 0, "file://a/"}, + {"file://a//", 0, "file://a//"}, + {"file://a/b", 0, "file://a/b"}, + {"file://a/b/", 0, "file://a/b/"}, + {"file://.", 0, "file://./"}, + {"file://./", 0, "file://./"}, + {"file://././a/.", 0, "file://././a/."}, + {"file://a/.", 0, "file://a/."}, + {"file://a/./b/./../", 0, "file://a/./b/./../"}, + {"file://a/b/.", 0, "file://a/b/"}, + {"file://a/b/.", URL_DONT_SIMPLIFY, "file://a/b/."}, + {"file://a/b/./", 0, "file://a/b/"}, + {"file://a/b/./c", 0, "file://a/b/c"}, + {"file:///./a", 0, "file:///./a"}, + {"file:////./a", 0, "file://./a"}, + + {"file://..", 0, "file://../"}, + {"file://../", 0, "file://../"}, + {"file://../a", 0, "file://../a"}, + {"file://../a/..", 0, "file://../"}, + {"file://../a/../..", 0, "file://../"}, + {"file://./a/../..", 0, "file://./"}, + {"file://a/../", 0, "file://a/../"}, + {"file://a/../../b/./../", 0, "file://a/../../b/./../"}, + {"file://a/.././", 0, "file://a/.././"}, + {"file://a/b/..", 0, "file://a/"}, + {"file://a/b/../", 0, "file://a/"}, + {"file://a/b/.././", 0, "file://a/"}, + {"file://a/b/../c", 0, "file://a/c"}, + {"file://a/b/../c/..", 0, "file://a/"}, + {"file://a/b/../c/../..", 0, "file://a/"}, + {"file://a/b/../../../c", 0, "file://a/c"}, + {"file:///.", 0, "file:///."}, + {"file:///..", 0, "file:///.."}, + {"file:///a/.", 0, "file:///a/"}, + + {"file:////", 0, "file:///"}, + {"file:////a/./b/../c", 0, "file://a/./b/../c"}, + {"file://///a/./b/../c", 0, "file://a/./b/../c"}, + {"file://////a/./b/../c", 0, "file://a/./b/../c"}, + {"file:////a/b/./../c", 0, "file://a/c"}, + {"file:////a/b/./../..", 0, "file://a/"}, + {"file://///a/b/./../c", 0, "file://a/c"}, + {"file://////a/b/./../c", 0, "file://a/c"}, + {"file:////.", 0, "file://./"}, + {"file:////..", 0, "file://../"}, + {"file:////./b/./../c", 0, "file://./c"}, + {"file:////./b/./../..", 0, "file://./"}, + {"file://///./b/./../c", 0, "file://./c"}, + {"file://////./b/./../c", 0, "file://./c"}, + + /* Drive-like paths get an extra slash (i.e. an empty hostname, to + * signal that the host is the local machine). The drive letter is + * treated as the path root. */ + {"file://a:", 0, "file:///a:"}, + {"file://a:/b", 0, "file:///a:/b"}, + {"file://a:/b/../..", 0, "file:///a:/"}, + {"file://a:/./../..", 0, "file:///a:/./../.."}, + {"file://a|/b", 0, "file:///a|/b"}, + {"file://ab:/c", 0, "file://ab:/c"}, + {"file:///a:", 0, "file:///a:"}, + {"file:////a:", 0, "file:///a:"}, + {"file://///a:", 0, "file:///a:"}, + {"file://host/a:/b/../..", 0, "file://host/a:/"}, + + /* URL_FILE_USE_PATHURL (and URL_WININET_COMPATIBILITY) have their own + * set of rules: + * + * (1) Dot processing works exactly like the "unknown scheme" rules, + * instead of the file/http rules demonstrated above. + * + * (2) Some number of backslashes is appended after the two forward + * slashes. The number basically corresponds to the detected path + * type (two for a remote path, one for a local path, none for a + * local drive path). A local path is one where the hostname is + * empty or "localhost". If all path elements are empty then no + * backslashes are appended. + */ + + {"file://", URL_FILE_USE_PATHURL, "file://"}, + {"file://a", URL_FILE_USE_PATHURL, "file://\\\\a"}, + {"file://a/", URL_FILE_USE_PATHURL, "file://\\\\a"}, + {"file://a//", URL_FILE_USE_PATHURL, "file://\\\\a\\\\"}, + {"file://a/b", URL_FILE_USE_PATHURL, "file://\\\\a\\b"}, + {"file://a//b", URL_FILE_USE_PATHURL, "file://\\\\a\\\\b"}, + {"file://a/.", URL_FILE_USE_PATHURL, "file://\\\\a\\"}, + {"file://a/../../b/./c/..", URL_FILE_USE_PATHURL, "file://\\\\a\\..\\..\\b\\"}, + {"file://./../../b/./c/..", URL_FILE_USE_PATHURL, "file://\\\\.\\..\\..\\b\\"}, + {"file://../../../b/./c/..", URL_FILE_USE_PATHURL, "file://\\\\..\\..\\..\\b\\"}, + {"file://a/b/.", URL_FILE_USE_PATHURL, "file://\\\\a\\b\\"}, + {"file://a/b/.", URL_FILE_USE_PATHURL | URL_DONT_SIMPLIFY, "file://\\\\a\\b\\.\\"}, + {"file://a/b/../../../c", URL_FILE_USE_PATHURL, "file://\\\\a\\..\\..\\c"}, + + {"file:///", URL_FILE_USE_PATHURL, "file://"}, + {"file:///.", URL_FILE_USE_PATHURL, "file://\\"}, + {"file:///..", URL_FILE_USE_PATHURL, "file://\\..\\"}, + {"file:///../../b/./c/..", URL_FILE_USE_PATHURL, "file://\\..\\..\\b\\"}, + {"file:///a/b/./c/..", URL_FILE_USE_PATHURL, "file://\\a\\b\\"}, + + {"file:////", URL_FILE_USE_PATHURL, "file://"}, + {"file:////.", URL_FILE_USE_PATHURL, "file://\\\\."}, + {"file:////a/./b/../c", URL_FILE_USE_PATHURL, "file://\\\\a\\c"}, + {"file://///", URL_FILE_USE_PATHURL, "file://"}, + {"file://///a/./b/../c", URL_FILE_USE_PATHURL, "file://\\\\a\\c"}, + + {"file://a:", URL_FILE_USE_PATHURL, "file://a:"}, + {"file://a:/", URL_FILE_USE_PATHURL, "file://a:\\"}, + {"file://a:/b", URL_FILE_USE_PATHURL, "file://a:\\b"}, + {"file://a:/b/../..", URL_FILE_USE_PATHURL, "file://a:\\..\\"}, + {"file://a|/b", URL_FILE_USE_PATHURL, "file://a|\\b"}, + {"file:///a:", URL_FILE_USE_PATHURL, "file://a:"}, + {"file:////a:", URL_FILE_USE_PATHURL, "file://a:"}, + + /* URL_WININET_COMPATIBILITY is almost identical, but ensures a trailing + * backslash in two cases: + * + * (1) if all path elements are empty, + * + * (2) if the path consists of just the hostname. + */ + + {"file://", URL_WININET_COMPATIBILITY, "file://\\"}, + {"file://a", URL_WININET_COMPATIBILITY, "file://\\\\a\\"}, + {"file://a/", URL_WININET_COMPATIBILITY, "file://\\\\a\\"}, + {"file://a//", URL_WININET_COMPATIBILITY, "file://\\\\a\\\\"}, + {"file://a/b", URL_WININET_COMPATIBILITY, "file://\\\\a\\b"}, + {"file://a//b", URL_WININET_COMPATIBILITY, "file://\\\\a\\\\b"}, + {"file://a/.", URL_WININET_COMPATIBILITY, "file://\\\\a\\"}, + {"file://a/../../b/./c/..", URL_WININET_COMPATIBILITY, "file://\\\\a\\..\\..\\b\\"}, + {"file://./../../b/./c/..", URL_WININET_COMPATIBILITY, "file://\\\\.\\..\\..\\b\\"}, + {"file://../../../b/./c/..", URL_WININET_COMPATIBILITY, "file://\\\\..\\..\\..\\b\\"}, + {"file://a/b/../../../c", URL_WININET_COMPATIBILITY, "file://\\\\a\\..\\..\\c"}, + + {"file:///", URL_WININET_COMPATIBILITY, "file://\\"}, + {"file:///.", URL_WININET_COMPATIBILITY, "file://\\"}, + {"file:///..", URL_WININET_COMPATIBILITY, "file://\\..\\"}, + {"file:///../../b/./c/..", URL_WININET_COMPATIBILITY, "file://\\..\\..\\b\\"}, + {"file:///a/b/./c/..", URL_WININET_COMPATIBILITY, "file://\\a\\b\\"}, + + {"file:////", URL_WININET_COMPATIBILITY, "file://\\"}, + {"file:////.", URL_WININET_COMPATIBILITY, "file://\\\\.\\"}, + {"file:////a/./b/../c", URL_WININET_COMPATIBILITY, "file://\\\\a\\c"}, + {"file://///", URL_WININET_COMPATIBILITY, "file://\\"}, + {"file://///a/./b/../c", URL_WININET_COMPATIBILITY, "file://\\\\a\\c"}, + + {"file://a:", URL_WININET_COMPATIBILITY, "file://a:"}, + + {"file://", URL_FILE_USE_PATHURL | URL_WININET_COMPATIBILITY, "file://"}, + + {"file://localhost/a", 0, "file://localhost/a"}, + {"file://localhost//a", 0, "file://localhost//a"}, + {"file://localhost/a:", 0, "file://localhost/a:"}, + {"file://localhost/a:/b/../..", 0, "file://localhost/a:/"}, + {"file://localhost/a:/./../..", 0, "file://localhost/a:/./../.."}, + {"file://localhost", URL_FILE_USE_PATHURL, "file://"}, + {"file://localhost/", URL_FILE_USE_PATHURL, "file://"}, + {"file://localhost/b", URL_FILE_USE_PATHURL, "file://\\b"}, + {"file://127.0.0.1/b", URL_FILE_USE_PATHURL, "file://\\\\127.0.0.1\\b"}, + {"file://localhost//b", URL_FILE_USE_PATHURL, "file://\\b"}, + {"file://localhost///b", URL_FILE_USE_PATHURL, "file://\\\\b"}, + {"file:///localhost/b", URL_FILE_USE_PATHURL, "file://\\localhost\\b"}, + {"file:////localhost/b", URL_FILE_USE_PATHURL, "file://\\b"}, + {"file://///localhost/b", URL_FILE_USE_PATHURL, "file://\\b"}, + {"file://localhost/a:", URL_FILE_USE_PATHURL, "file://a:"}, + {"file://localhost/a:/b/../..", URL_FILE_USE_PATHURL, "file://a:\\..\\"}, + {"file://localhost?a/b", URL_FILE_USE_PATHURL, "file://"}, + {"file://localhost#a/b", URL_FILE_USE_PATHURL, "file://\\\\localhost#a/b"}, + {"file://localhostq", URL_FILE_USE_PATHURL, "file://\\\\localhostq"}, + + {"file://localhost", URL_WININET_COMPATIBILITY, "file://\\"}, + {"file://localhost/", URL_WININET_COMPATIBILITY, "file://\\"}, + {"file://localhost/b", URL_WININET_COMPATIBILITY, "file://\\b"}, + {"file://localhost//b", URL_WININET_COMPATIBILITY, "file://\\b"}, + {"file://127.0.0.1/b", URL_WININET_COMPATIBILITY, "file://\\\\127.0.0.1\\b"}, + {"file://localhost/a:", URL_WININET_COMPATIBILITY, "file://a:"}, + {"file://localhost?a/b", URL_WININET_COMPATIBILITY, "file://\\?a/b"}, + {"file://localhost#a/b", URL_WININET_COMPATIBILITY, "file://\\\\localhost#a/b"}, + + /* # has some weird behaviour: + * + * - Dot processing happens normally after it, including rewinding past + * the #. It's not treated as a path separator for the purposes of + * rewinding. + * + * - However, if neither file flag is used, and the first character + * after the hostname (plus an optional slash) is a hash, no dot + * processing takes place. + * + * - If the previous path segment ends in .htm or .html, the rest of + * the URL is emitted verbatim (no dot or slash canonicalization). + * This does not apply to the hostname. If URL_FILE_USE_PATHURL is + * used, though, the rest of the URL including the # is omitted. + * + * - It is treated as a path terminator for dots, but only if neither + * file flag is used. It does not begin a path element. + * + * - If there is a # anywhere in the output string (and the string + * doesn't fall under the .html exception), all subsequent slashes + * are converted to forward slashes instead of backslashes. + * This means that rewinding past the hash will revert to backslashes. + * (This of course only affects the case where file flags are used; + * if no file flags are used then slashes are converted to forward + * slashes anyway.) + */ + {"file://a/b#c/../d\\e", 0, "file://a/d/e"}, + {"file://a/b#c/./d\\e", 0, "file://a/b#c/d/e"}, + {"file://a/b.htm#c/../d\\e", 0, "file://a/b.htm#c/../d\\e"}, + {"file://a/b.html#c/../d\\e", 0, "file://a/b.html#c/../d\\e"}, + {"file://a/b.hTmL#c/../d\\e", 0, "file://a/b.hTmL#c/../d\\e"}, + {"file://a/b.xhtml#c/../d\\e", 0, "file://a/d/e"}, + {"file://a/b.php#c/../d\\e", 0, "file://a/d/e"}, + {"file://a/b.asp#c/../d\\e", 0, "file://a/d/e"}, + {"file://a/b.aspx#c/../d\\e", 0, "file://a/d/e"}, + {"file://a/b.ht#c/../d\\e", 0, "file://a/d/e"}, + {"file://a/b.txt#c/../d\\e", 0, "file://a/d/e"}, + {"file://a/b.htmlq#c/../d\\e", 0, "file://a/d/e"}, + {"file://a/b.html/q#c/../d\\e", 0, "file://a/b.html/d/e"}, + {"file://a/.html#c/../d\\e", 0, "file://a/.html#c/../d\\e"}, + {"file://a/html#c/../d\\e", 0, "file://a/d/e"}, + {"file://a/b#c/./d.html#e/../f", 0, "file://a/b#c/d.html#e/../f"}, + {"file://a.html#/b/../c", 0, "file://a.html#/c"}, + {"file://a/b#c/../d/e", URL_FILE_USE_PATHURL, "file://\\\\a\\d\\e"}, + {"file://a/b#c/./d/e", URL_FILE_USE_PATHURL, "file://\\\\a\\b#c/d/e"}, + {"file://a/b.html#c/../d\\e", URL_FILE_USE_PATHURL, "file://\\\\a\\b.html"}, + {"file://a/b.html#c/../d\\e", URL_FILE_USE_PATHURL | URL_WININET_COMPATIBILITY, "file://\\\\a\\b.html"}, + {"file://a/b#c/../d/e", URL_WININET_COMPATIBILITY, "file://\\\\a\\d\\e"}, + {"file://a/b#c/./d/e", URL_WININET_COMPATIBILITY, "file://\\\\a\\b#c/d/e"}, + {"file://a/b.html#c/../d\\e", URL_WININET_COMPATIBILITY, "file://\\\\a\\b.html#c/../d\\e"}, + {"file://a/c#/../d", 0, "file://a/d"}, + {"file://a/c#/../d", URL_FILE_USE_PATHURL, "file://\\\\a\\d"}, + {"file://a/c#/../d", URL_WININET_COMPATIBILITY, "file://\\\\a\\d"}, + {"file://a/#c/../d\\e", 0, "file://a/#c/../d\\e"}, + {"file://a/#c/../d/e", URL_FILE_USE_PATHURL, "file://\\\\a\\d\\e"}, + {"file://a/#c/../d/e", URL_WININET_COMPATIBILITY, "file://\\\\a\\d\\e"}, + {"file://a//#c/../d", 0, "file://a//#c/../d"}, + {"file://a//#c/../d", URL_FILE_USE_PATHURL, "file://\\\\a\\\\d"}, + {"file://a//#c/../d", URL_WININET_COMPATIBILITY, "file://\\\\a\\\\d"}, + {"file://a/\\#c/../d", 0, "file://a//#c/../d"}, + {"file://a///#c/../d", 0, "file://a///d"}, + {"file://a/b/#c/../d", 0, "file://a/b/d"}, + {"file://a/b/.#c", 0, "file://a/b/#c"}, + {"file://a/b/..#c", 0, "file://a/#c"}, + {"file://a/b/.#c", URL_FILE_USE_PATHURL, "file://\\\\a\\b\\.#c"}, + {"file://a/b/..#c", URL_FILE_USE_PATHURL, "file://\\\\a\\b\\..#c"}, + {"file://a/b/.#c", URL_WININET_COMPATIBILITY, "file://\\\\a\\b\\.#c"}, + {"file://a/b/..#c", URL_WININET_COMPATIBILITY, "file://\\\\a\\b\\..#c"}, + {"file://a/b#../c", 0, "file://a/b#../c"}, + {"file://a/b/#../c", 0, "file://a/b/#../c"}, + {"file://a/b#../c", URL_FILE_USE_PATHURL, "file://\\\\a\\b#../c"}, + {"file://a/b#../c", URL_WININET_COMPATIBILITY, "file://\\\\a\\b#../c"}, + {"file://#/b\\./", 0, "file://#/b/"}, + {"file://#/./b\\./", 0, "file://#/./b/./"}, + {"file://#/b\\./", URL_FILE_USE_PATHURL, "file://\\\\#/b/"}, + {"file://#/b\\./", URL_WININET_COMPATIBILITY, "file://\\\\#/b/"}, + {"file://a#/b\\./", 0, "file://a#/b/"}, + {"file://a#/./b\\./", 0, "file://a#/./b/./"}, + {"file://a#/b\\./", URL_FILE_USE_PATHURL, "file://\\\\a#/b/"}, + {"file://a#/b\\./", URL_WININET_COMPATIBILITY, "file://\\\\a#/b/"}, + {"file://a#/b\\./", URL_FILE_USE_PATHURL | URL_DONT_SIMPLIFY, "file://\\\\a#/b/./"}, + {"file://a#/b\\.", URL_FILE_USE_PATHURL | URL_DONT_SIMPLIFY, "file://\\\\a#/b/./"}, + {"file://a#/b/../../", 0, "file://a#/"}, + + /* ? is similar, with the following exceptions: + * + * - URLs ending in .htm(l) are not treated specially. + * + * - With URL_FILE_USE_PATHURL, the rest of the URL including the ? is + * just omitted (much like the .html case above). + * + * - With URL_WININET_COMPATIBILITY, the rest of the URL is always + * emitted verbatim (completely opaque, like other schemes). + */ + + {"file://a/b?c/../d\\e", 0, "file://a/d/e"}, + {"file://a/b.html?c/../d\\e", 0, "file://a/d/e"}, + {"file://a/b?c/../d\\e", URL_FILE_USE_PATHURL, "file://\\\\a\\b"}, + {"file://a/b.html?c/../d\\e", URL_FILE_USE_PATHURL, "file://\\\\a\\b.html"}, + {"file://a/b?c/../d\\e", URL_WININET_COMPATIBILITY, "file://\\\\a\\b?c/../d\\e"}, + {"file://a/b.html?c/../d\\e", URL_WININET_COMPATIBILITY, "file://\\\\a\\b.html?c/../d\\e"}, + {"file://a/b?c/../d", URL_FILE_USE_PATHURL | URL_WININET_COMPATIBILITY, "file://\\\\a\\b"}, + {"file://a/?c/../d", 0, "file://a/?c/../d"}, + {"file://a/?c/../d", URL_FILE_USE_PATHURL, "file://\\\\a"}, + {"file://a/?c/../d", URL_WININET_COMPATIBILITY, "file://\\\\a\\?c/../d"}, + {"file://a//?c/../d", 0, "file://a//?c/../d"}, + {"file://a//?c/../d", URL_FILE_USE_PATHURL, "file://\\\\a\\\\"}, + {"file://a//?c/../d", URL_WININET_COMPATIBILITY, "file://\\\\a\\\\?c/../d"}, + {"file://a/\\?c/../d", 0, "file://a//?c/../d"}, + {"file://a///?c/../d", 0, "file://a///d"}, + {"file://a/b/?c/../d", 0, "file://a/b/d"}, + {"file://a/b/.?c", 0, "file://a/b/?c"}, + {"file://a/b/..?c", 0, "file://a/?c"}, + {"file://a/b/.?c", URL_FILE_USE_PATHURL, "file://\\\\a\\b\\"}, + {"file://a/b/..?c", URL_FILE_USE_PATHURL, "file://\\\\a\\"}, + {"file://a/b/.?c", URL_WININET_COMPATIBILITY, "file://\\\\a\\b\\?c"}, + {"file://a/b/..?c", URL_WININET_COMPATIBILITY, "file://\\\\a\\?c"}, + {"file://?/a\\./", 0, "file://?/a/"}, + {"file://?/./a\\./", 0, "file://?/./a/./"}, + {"file://?/a\\./", URL_FILE_USE_PATHURL, "file://"}, + {"file://?/a\\./", URL_WININET_COMPATIBILITY, "file://\\?/a\\./"}, + {"file://a?/a\\./", 0, "file://a?/a/"}, + {"file://a?/./a\\./", 0, "file://a?/./a/./"}, + {"file://a?/a\\./", URL_FILE_USE_PATHURL, "file://\\\\a"}, + {"file://a?/a\\./", URL_WININET_COMPATIBILITY, "file://\\\\a\\?/a\\./"}, + + {"file://a/b.html?c#d/..", 0, "file://a/"}, + {"file://a/b.html?c.html#d/..", 0, "file://a/b.html?c.html#d/.."}, + {"file://a/b?\\#c\\d", 0, "file://a/b?/#c/d"}, + {"file://a/b?\\#c\\d", URL_WININET_COMPATIBILITY, "file://\\\\a\\b?\\#c\\d"}, + {"file://a/b?\\#c\\d", URL_FILE_USE_PATHURL, "file://\\\\a\\b"}, + {"file://a/b#\\?c\\d", 0, "file://a/b#/?c/d"}, + {"file://a/b#\\?c\\d", URL_WININET_COMPATIBILITY, "file://\\\\a\\b#/?c\\d"}, + {"file://a/b#\\?c\\d", URL_FILE_USE_PATHURL, "file://\\\\a\\b#/"}, + {"file://a/b.html#c?d", URL_WININET_COMPATIBILITY, "file://\\\\a\\b.html?d#c"}, + + /* file: treats backslashes like forward slashes, including the + * initial pair. */ + {"file://a/b\\", 0, "file://a/b/"}, + {"file://a/b\\c/../.\\", 0, "file://a/b/"}, + {"file://a\\b", 0, "file://a/b"}, + {"file:/\\a\\..", 0, "file://a/.."}, + {"file:\\/a\\..", 0, "file://a/.."}, + {"file:\\\\a\\b", URL_FILE_USE_PATHURL, "file://\\\\a\\b"}, + {"file:\\\\a\\b", URL_WININET_COMPATIBILITY, "file://\\\\a\\b"}, + {"file:\\///a/./b/../c", 0, "file://a/./b/../c"}, + {"file:/\\//a/./b/../c", 0, "file://a/./b/../c"}, + {"file://\\/a/./b/../c", 0, "file://a/./b/../c"}, + {"file:///\\a/./b/../c", 0, "file://a/./b/../c"}, + + {"file://a/b &c", 0, "file://a/b &c"}, + {"file://a/b &c", URL_FILE_USE_PATHURL, "file://\\\\a\\b &c"}, + {"file://a/b &c", URL_WININET_COMPATIBILITY, "file://\\\\a\\b &c"}, + {"file://a/b !\"$%&'()*+,-:;<=>@[]^_`{|}~c", URL_ESCAPE_UNSAFE, "file://a/b%20!%22$%%26'()*+,-:;%3C=%3E@%5B%5D%5E_%60%7B%7C%7D~c"}, + {"file://a/b%20%26c", 0, "file://a/b%20%26c"}, + {"file://a/b%20%26c", URL_FILE_USE_PATHURL, "file://\\\\a\\b &c"}, + {"file://a/b%20%26c", URL_WININET_COMPATIBILITY, "file://\\\\a\\b%20%26c"}, + + /* Omitting one slash behaves as if the URL had been written with an + * empty hostname, and the output adds two slashes as such. */ + + {"file:/", 0, "file:///"}, + {"file:/a", 0, "file:///a"}, + {"file:/./a", 0, "file:///./a"}, + {"file:/../a/..", 0, "file:///../a/.."}, + {"file:/./..", 0, "file:///./.."}, + {"file:/a/.", 0, "file:///a/"}, + {"file:/a/../..", 0, "file:///"}, + {"file:/a:", 0, "file:///a:"}, + {"file:/a:/b/../..", 0, "file:///a:/"}, + + /* The same applies to the flags. */ + + {"file:/", URL_FILE_USE_PATHURL, "file://"}, + {"file:/a", URL_FILE_USE_PATHURL, "file://\\a"}, + {"file:/.", URL_FILE_USE_PATHURL, "file://\\"}, + {"file:/./a", URL_FILE_USE_PATHURL, "file://\\a"}, + {"file:/../a", URL_FILE_USE_PATHURL, "file://\\..\\a"}, + {"file:/a/../..", URL_FILE_USE_PATHURL, "file://\\..\\"}, + {"file:/a/.", URL_FILE_USE_PATHURL | URL_DONT_SIMPLIFY, "file://\\a\\.\\"}, + {"file:/a:", URL_FILE_USE_PATHURL, "file://a:"}, + {"file:/a:/b/../..", URL_FILE_USE_PATHURL, "file://a:\\..\\"}, + + {"file:/", URL_WININET_COMPATIBILITY, "file://\\"}, + {"file:/a", URL_WININET_COMPATIBILITY, "file://\\a"}, + {"file:/.", URL_WININET_COMPATIBILITY, "file://\\"}, + {"file:/a:", URL_WININET_COMPATIBILITY, "file://a:"}, + + {"file:/a/b#c/../d", 0, "file:///a/d"}, + {"file:/a/b?c/../d", 0, "file:///a/d"}, + + {"file:/a\\b\\", 0, "file:///a/b/"}, + {"file:\\a/b/", 0, "file:///a/b/"}, + {"file:\\a\\b", URL_FILE_USE_PATHURL, "file://\\a\\b"}, + {"file:\\a\\b", URL_WININET_COMPATIBILITY, "file://\\a\\b"}, + + {"file:/a/b &c", 0, "file:///a/b &c"}, + + /* Omitting both slashes causes all dots to be collapsed, in the same + * way as bare http. */ + + {"file:a", 0, "file:a"}, + {"file:a/", 0, "file:a/"}, + {"file:a/.", 0, "file:a/"}, + {"file:a/..", 0, "file:"}, + {"file:a/../..", 0, "file:"}, + {"file:", 0, "file:"}, + {"file:.", 0, "file:"}, + {"file:..", 0, "file:"}, + {"file:./", 0, "file:"}, + {"file:../", 0, "file:"}, + + {"file:a:", 0, "file:///a:"}, + + /* URL_FILE_USE_PATHURL treats everything here as a local (relative?) + * path. In the case that the path resolves to the current directory + * a single backslash is emitted. */ + {"file:", URL_FILE_USE_PATHURL, "file://"}, + {"file:a", URL_FILE_USE_PATHURL, "file://a"}, + {"file:a/.", URL_FILE_USE_PATHURL, "file://a\\"}, + {"file:a/../..", URL_FILE_USE_PATHURL, "file://..\\"}, + {"file:./a", URL_FILE_USE_PATHURL, "file://a"}, + {"file:../a", URL_FILE_USE_PATHURL, "file://..\\a"}, + {"file:a/.", URL_FILE_USE_PATHURL | URL_DONT_SIMPLIFY, "file://a\\.\\"}, + {"file:a:", URL_FILE_USE_PATHURL, "file://a:"}, + + /* URL_WININET_COMPATIBILITY doesn't emit a double slash. */ + {"file:", URL_WININET_COMPATIBILITY, "file:"}, + {"file:a", URL_WININET_COMPATIBILITY, "file:a"}, + {"file:./a", URL_WININET_COMPATIBILITY, "file:a"}, + {"file:../a", URL_WININET_COMPATIBILITY, "file:..\\a"}, + {"file:../b/./c/../d", URL_WININET_COMPATIBILITY | URL_DONT_SIMPLIFY, "file:..\\b\\.\\c\\..\\d"}, + {"file:a:", URL_WININET_COMPATIBILITY, "file://a:"}, + + {"file:a/b?c/../d", 0, "file:a/d"}, + {"file:a/b#c/../d", 0, "file:a/d"}, + + {"file:a\\b\\", 0, "file:a/b/"}, + + {"file:a/b &c", 0, "file:a/b &c"}, + + {"fIlE://A/B", 0, "file://A/B"}, + {"fIlE://A/B", URL_FILE_USE_PATHURL, "file://\\\\A\\B"}, + {"fIlE://A/B", URL_WININET_COMPATIBILITY, "file://\\\\A\\B"}, + {"fIlE:A:/B", 0, "file:///A:/B"}, + {"fIlE:A:/B", URL_FILE_USE_PATHURL, "file://A:\\B"}, + {"fIlE:A:/B", URL_WININET_COMPATIBILITY, "file://A:\\B"}, + {"fIlE://lOcAlHoSt/B", 0, "file://lOcAlHoSt/B"}, + {"fIlE://lOcAlHoSt/B", URL_FILE_USE_PATHURL, "file://\\B"}, + + /* Drive paths are automatically converted to file paths. Dots are + * collapsed unless the first segment after q: or q:/ is a dot. */ + + {"q:a", 0, "file:///q:a"}, + {"q:a/.", 0, "file:///q:a/"}, + {"q:a/..", 0, "file:///q:"}, + {"q:a/../..", 0, "file:///q:"}, + {"q:./a/..", 0, "file:///q:./a/.."}, + {"q:../a/..", 0, "file:///q:../a/.."}, + {"q:/", 0, "file:///q:/"}, + {"q:/a", 0, "file:///q:/a"}, + {"q:/a/.", 0, "file:///q:/a/"}, + {"q:/a/..", 0, "file:///q:/"}, + {"q:/./a/..", 0, "file:///q:/./a/.."}, + {"q:/../a/..", 0, "file:///q:/../a/.."}, + {"q://./a", 0, "file:///q://a"}, + {"q://../a", 0, "file:///q:/a"}, + + /* File flags use the "unknown scheme" rules, and the root of the path + * is the first slash. */ + + {"q:/a", URL_FILE_USE_PATHURL, "file://q:\\a"}, + {"q:/a/../..", URL_FILE_USE_PATHURL, "file://q:\\..\\"}, + {"q:a/../../b/..", URL_FILE_USE_PATHURL, "file://q:a\\..\\..\\"}, + {"q:./../../b/..", URL_FILE_USE_PATHURL, "file://q:.\\..\\..\\"}, + {"q:/a", URL_WININET_COMPATIBILITY, "file://q:\\a"}, + {"q:/a/../..", URL_WININET_COMPATIBILITY, "file://q:\\..\\"}, + {"q:a/../../b/..", URL_WININET_COMPATIBILITY, "file://q:a\\..\\..\\"}, + {"q:./../../b/..", URL_WININET_COMPATIBILITY, "file://q:.\\..\\..\\"}, + + {"q:/a/b?c/../d", 0, "file:///q:/a/d"}, + {"q:/a/b#c/../d", 0, "file:///q:/a/d"}, + {"q:a?b", URL_FILE_USE_PATHURL, "file://q:a"}, + + {"q:a\\b\\", 0, "file:///q:a/b/"}, + {"q:\\a/b", 0, "file:///q:/a/b"}, + + /* Drive paths are also unique in that unsafe characters (and spaces) + * are automatically escaped—but not if the file flags are used. */ + + {"q:/a/b !\"$%&'()*+,-:;<=>@[]^_`{|}~c", 0, "file:///q:/a/b%20!%22$%25%26'()*+,-:;%3C=%3E@%5B%5D%5E_%60%7B%7C%7D~c"}, + {"q:/a/b &c", URL_FILE_USE_PATHURL, "file://q:\\a\\b &c"}, + {"q:/a/b &c", URL_WININET_COMPATIBILITY, "file://q:\\a\\b &c"}, + + {"q:/a/b%20%26c", 0, "file:///q:/a/b%2520%2526c"}, + {"q:/a/b%20%26c", URL_UNESCAPE, "file:///q:/a/b &c"}, + {"q:/a/b%20%26c", URL_UNESCAPE | URL_ESCAPE_UNSAFE, "file:///q:/a/b%20%26c"}, + {"q:/a/b%20%26c", URL_FILE_USE_PATHURL, "file://q:\\a\\b &c"}, + {"q:/a/b%20%26c", URL_FILE_USE_PATHURL | URL_UNESCAPE, "file://q:\\a\\b &c"}, + {"q:/a/b%20%26c", URL_WININET_COMPATIBILITY, "file://q:\\a\\b%20%26c"}, + {"q:/a/b%20%26c", URL_WININET_COMPATIBILITY | URL_UNESCAPE, "file://q:\\a\\b &c"}, + + {"q|a", 0, "file:///q%7Ca"}, + {"-:a", 0, "-:a"}, + {"Q:A", 0, "file:///Q:A"}, + + /* A double initial backslash is also converted to a file path. The same + * rules for hostnames apply. */ + + {"\\\\", 0, "file:///"}, + {"\\\\a", 0, "file://a/"}, + {"\\\\../a\\b/..\\c/.\\", 0, "file://../a/c/"}, + {"\\\\a/./b/../c", 0, "file://a/./b/../c"}, + /* And, of course, four or more slashes gets collapsed... */ + {"\\\\//./b/./../c", 0, "file://./c"}, + {"\\\\///./b/./../c", 0, "file://./c"}, + + {"\\\\a/b?c/../d", 0, "file://a/d"}, + {"\\\\a/b#c/../d", 0, "file://a/d"}, + + /* Drive paths are "recognized" too, though. The following isn't + * actually a local path, but UrlCanonicalize() doesn't seem to realize + * that. */ + {"\\\\a:/b", 0, "file:///a:/b"}, + + {"\\\\", URL_FILE_USE_PATHURL, "file://"}, + {"\\\\a", URL_FILE_USE_PATHURL, "file://\\\\a"}, + {"\\\\a/./..", URL_FILE_USE_PATHURL, "file://\\\\a\\..\\"}, + {"\\\\a:/b", URL_FILE_USE_PATHURL, "file://a:\\b"}, + {"\\\\", URL_WININET_COMPATIBILITY, "file://\\"}, + {"\\\\a", URL_WININET_COMPATIBILITY, "file://\\\\a\\"}, + {"\\\\a/./..", URL_WININET_COMPATIBILITY, "file://\\\\a\\..\\"}, + {"\\\\a:/b", URL_WININET_COMPATIBILITY, "file://a:\\b"}, + + /* And, as with drive paths, unsafe characters are escaped. */ + {"\\\\a/b !\"$%&'()*+,-:;<=>@[]^_`{|}~c", 0, "file://a/b%20!%22$%25%26'()*+,-:;%3C=%3E@%5B%5D%5E_%60%7B%7C%7D~c"}, + {"\\\\a/b &c", URL_FILE_USE_PATHURL, "file://\\\\a\\b &c"}, + {"\\\\a/b &c", URL_WININET_COMPATIBILITY, "file://\\\\a\\b &c"}, + + {"\\\\/b", 0, "file:///b"}, + {"\\\\/b", URL_FILE_USE_PATHURL, "file://\\b"}, + {"\\\\localhost/b", URL_FILE_USE_PATHURL, "file://\\b"}, + {"\\\\127.0.0.1/b", URL_FILE_USE_PATHURL, "file://\\\\127.0.0.1\\b"}, + {"\\\\localhost/b", URL_WININET_COMPATIBILITY, "file://\\b"}, + {"\\\\127.0.0.1/b", URL_WININET_COMPATIBILITY, "file://\\\\127.0.0.1\\b"}, + + {"\\\\A/B", 0, "file://A/B"}, + + {"file:///c:/tests/foo%20bar", URL_UNESCAPE, "file:///c:/tests/foo bar"}, + {"file:///c:/tests\\foo%20bar", URL_UNESCAPE, "file:///c:/tests/foo bar"}, + {"file:///c:/tests/foo%20bar", 0, "file:///c:/tests/foo%20bar"}, + {"file:///c:/tests/foo%20bar", URL_FILE_USE_PATHURL, "file://c:\\tests\\foo bar"}, + {"file://localhost/c:/tests/../tests/foo%20bar", URL_FILE_USE_PATHURL, "file://c:\\tests\\foo bar"}, + {"file://localhost\\c:/tests/../tests/foo%20bar", URL_FILE_USE_PATHURL, "file://c:\\tests\\foo bar"}, + {"file://localhost\\\\c:/tests/../tests/foo%20bar", URL_FILE_USE_PATHURL, "file://c:\\tests\\foo bar"}, + {"file://localhost\\c:\\tests/../tests/foo%20bar", URL_FILE_USE_PATHURL, "file://c:\\tests\\foo bar"}, + {"file://c:/tests/../tests/foo%20bar", URL_FILE_USE_PATHURL, "file://c:\\tests\\foo bar"}, + {"file://c:/tests\\../tests/foo%20bar", URL_FILE_USE_PATHURL, "file://c:\\tests\\foo bar"}, + {"file://c:/tests/foo%20bar", URL_FILE_USE_PATHURL, "file://c:\\tests\\foo bar"}, + {"file:///c://tests/foo%20bar", URL_FILE_USE_PATHURL, "file://c:\\\\tests\\foo bar"}, + {"file:///c:\\tests\\foo bar", 0, "file:///c:/tests/foo bar"}, + {"file:///c:\\tests\\foo bar", URL_DONT_SIMPLIFY, "file:///c:/tests/foo bar"}, + {"file:///c:\\tests\\foobar", 0, "file:///c:/tests/foobar"}, + {"file:///c:\\tests\\foobar", URL_WININET_COMPATIBILITY, "file://c:\\tests\\foobar"}, + {"file://home/user/file", 0, "file://home/user/file"}, + {"file:///home/user/file", 0, "file:///home/user/file"}, + {"file:////home/user/file", 0, "file://home/user/file"}, + {"file://home/user/file", URL_WININET_COMPATIBILITY, "file://\\\\home\\user\\file"}, + {"file:///home/user/file", URL_WININET_COMPATIBILITY, "file://\\home\\user\\file"}, + {"file:////home/user/file", URL_WININET_COMPATIBILITY, "file://\\\\home\\user\\file"}, + {"file://///home/user/file", URL_WININET_COMPATIBILITY, "file://\\\\home\\user\\file"}, + {"file://C:/user/file", 0, "file:///C:/user/file"}, + {"file://C:/user/file/../asdf", 0, "file:///C:/user/asdf"}, + {"file:///C:/user/file", 0, "file:///C:/user/file"}, + {"file:////C:/user/file", 0, "file:///C:/user/file"}, + {"file://C:/user/file", URL_WININET_COMPATIBILITY, "file://C:\\user\\file"}, + {"file:///C:/user/file", URL_WININET_COMPATIBILITY, "file://C:\\user\\file"}, + {"file:////C:/user/file", URL_WININET_COMPATIBILITY, "file://C:\\user\\file"}, + }; + + static const struct canonicalize_test misc_tests[] = + { + {"", 0, ""}, + + /* If both slashes are omitted, everything afterwards is replicated + * as-is, with the exception that the final period is dropped from + * "scheme:." */ + + {"wine:.", 0, "wine:"}, + {"wine:.", URL_DONT_SIMPLIFY, "wine:."}, + {"wine:./", 0, "wine:./"}, + {"wine:..", 0, "wine:.."}, + {"wine:../", 0, "wine:../"}, + {"wine:a", 0, "wine:a"}, + {"wine:a/", 0, "wine:a/"}, + {"wine:a/b/./../c", 0, "wine:a/b/./../c"}, + + {"wine:a/b?c/./d", 0, "wine:a/b?c/./d"}, + {"wine:a/b#c/./d", 0, "wine:a/b#c/./d"}, + {"wine:a/b#c?d", 0, "wine:a/b?d#c"}, + {"wine:.#c?d", 0, "wine:?d#c"}, + + /* A backslash directly after the colon is not treated specially. */ + {"wine:\\././a", 0, "wine:\\././a"}, + + {"wine:a/b &c", 0, "wine:a/b &c"}, + + /* If there's no scheme or hostname, things mostly follow the "unknown + * scheme" rules, except that a would-be empty string results in a + * single slash instead. */ + + {"a", 0, "a"}, + {"a/", 0, "a/"}, + {".", 0, "/"}, + {".", URL_DONT_SIMPLIFY, "./"}, + {"./", 0, "/"}, + {"./.", 0, "/"}, + {"././a", 0, "a"}, + {"a/.", 0, "a/"}, + {"a/./", 0, "a/"}, + {"a/./b", 0, "a/b"}, + + {"..", 0, "../"}, + {"../", 0, "../"}, + {"../a", 0, "../a"}, + {"../a/..", 0, "../"}, + {"a/..", 0, "/"}, + {"a/../..", 0, "../"}, + {"a/b/..", 0, "a/"}, + {"a/b/../", 0, "a/"}, + {"a/b/../c", 0, "a/c"}, + {"a/b/../c/..", 0, "a/"}, + {"a/b/../c/../..", 0, "/"}, + + {"a/b?c/./d", 0, "a/b?c/./d"}, + {"a/b#c/./d", 0, "a/b#c/./d"}, + {"a/b#c?d", 0, "a/b?d#c"}, + {"?c", 0, "?c"}, + {".?c", 0, "/?c"}, + + {"?c/./d", 0, "?c/./d"}, + {"#c/./d", 0, "#c/./d"}, + + {"a\\b/..", 0, "/"}, + + {"a/b &c", 0, "a/b &c"}, + + /* A colon by itself is not interpreted as any sort of scheme. */ + {"://../../a", 0, "a"}, + + /* mk: is another idiosyncratic scheme, although thankfully it behaves + * rather simply. It has no concept of a hostname; if two slashes follow + * the scheme it simply treats them as two empty path elements. */ + {"mk:", 0, "mk:"}, + {"mk:.", 0, "mk:"}, + {"mk:..", 0, "mk:"}, + {"mk:/", 0, "mk:/"}, + {"mk:/.", 0, "mk:/"}, + {"mk:/..", 0, "mk:"}, + {"mk:a", 0, "mk:a"}, + {"mk:a:", 0, "mk:a:"}, + {"mk://", 0, "mk://"}, + {"mk://.", 0, "mk://"}, + {"mk://..", 0, "mk:/"}, + {"mk://../..", 0, "mk:"}, + {"mk://../..", URL_DONT_SIMPLIFY, "mk://../.."}, + {"mk://../../..", 0, "mk:"}, + + /* Backslashes are not translated into forward slashes. They are treated + * as path separators, but in a somewhat buggy manner: only dots before + * a forward slash are collapsed, and a double dot rewinds to the + * previous forward slash. */ + {"mk:a/.\\", 0, "mk:a/.\\"}, + {"mk:a/.\\b", 0, "mk:a/.\\b"}, + {"mk:a\\.\\b", 0, "mk:a\\.\\b"}, + {"mk:a\\./b", 0, "mk:a\\b"}, + {"mk:a./b", 0, "mk:a./b"}, + {"mk:a\\b/..\\c", 0, "mk:a\\b/..\\c"}, + {"mk:a\\b\\..\\c", 0, "mk:a\\b\\..\\c"}, + {"mk:a/b\\../c", 0, "mk:a/c"}, + {"mk:a\\b../c", 0, "mk:a\\b../c"}, + + /* Progids get a forward slash appended if there isn't one already, and + * dots don't rewind past them. Despite the fact that progids are + * supposed to end with a colon, UrlCanonicalize() considers them to + * end with the slash. + * + * If the first path segment is a dot or double dot, it's treated as + * a relative path, like http, but only before a forward slash. */ + + {"mk:@", 0, "mk:@/"}, + {"mk:@progid", 0, "mk:@progid/"}, + {"mk:@progid:a", 0, "mk:@progid:a/"}, + {"mk:@progid:a/b", 0, "mk:@progid:a/b"}, + {"mk:@Progid:a/b/../..", 0, "mk:@Progid:a/"}, + {"mk:@progid/a", 0, "mk:@progid/a"}, + {"mk:@progid\\a", 0, "mk:@progid\\a/"}, + {"mk:@progid/a/../..", 0, "mk:@progid/"}, + {"mk:@progid/.", 0, "mk:@progid/."}, + {"mk:@progid/.?", 0, "mk:@progid/.?"}, + {"mk:@progid/./..", 0, "mk:@progid/./.."}, + {"mk:@progid/../..", 0, "mk:@progid/../.."}, + {"mk:@progid/a\\.\\b", 0, "mk:@progid/a\\.\\b"}, + {"mk:@progid/a\\..\\b", 0, "mk:@progid/a\\..\\b"}, + {"mk:@progid/.\\..", 0, "mk:@progid/"}, + + {"mk:a/b?c/../d", 0, "mk:a/b?c/../d"}, + {"mk:a/b#c/../d", 0, "mk:a/b#c/../d"}, + {"mk:a/b#c?d", 0, "mk:a/b#c?d"}, + {"mk:@progid/a/b?c/../d", 0, "mk:@progid/a/b?c/../d"}, + {"mk:@progid?c/d/..", 0, "mk:@progid?c/"}, + + {"mk:a/b &c", 0, "mk:a/b &c"}, + + {"mk:@MSITStore:dir/test.chm::/file.html/..", 0, "mk:@MSITStore:dir/test.chm::/"}, + {"mk:@MSITStore:dir/test.chm::/file.html/../..", 0, "mk:@MSITStore:dir/"}, + + /* Whitespace except for plain spaces are stripped before parsing. */ + {" \t\n\rwi\t\n\rne\t\n\r:\t\n\r/\t\n\r/\t\n\r./../a/.\t\n\r./ \t\n\r", 0, "wine://./../"}, + /* Initial and final spaces and C0 control characters are also stripped, + * but not 007F or C1 control characters. */ + {" \a\t\x01 wine://./.. \x1f\n\v ", 0, "wine://./../"}, + {" wine ://./..", 0, "wine :/"}, + {" wine: //a/../b", 0, "wine: //a/../b"}, + {" wine://a/b c/.. ", 0, "wine://a/"}, + {"\x7f/\a/\v/\x01/\x1f/\x80", 0, "\x7f/\a/\v/\x01/\x1f/\x80"}, + + /* Schemes are not case-sensitive, but are flattened to lowercase. + * The hostname for http-like schemes is also flattened to lowercase + * (but not for file; see above). */ + {"wInE://A/B", 0, "wine://A/B"}, + {"hTtP://A/b/../../C", 0, "http://a/C"}, + {"fTP://A/B\\./C", 0, "ftp://a/B\\C"}, + {"aBoUT://A/B/./", 0, "about://A/B/./"}, + {"mK://..", 0, "mk:/"}, + + /* Characters allowed in a scheme are alphanumeric, hyphen, plus, period. */ + {"0Aa+-.://./..", 0, "0aa+-.://./../"}, + {"a_://./..", 0, "a_:/"}, + {"a,://./..", 0, "a,:/"}, + + {"/uri-res/N2R?urn:sha1:B3K", URL_DONT_ESCAPE_EXTRA_INFO | URL_WININET_COMPATIBILITY, "/uri-res/N2R?urn:sha1:B3K"} /* LimeWire online installer calls this */, + {"mk:@MSITStore:C:\\Program Files/AutoCAD 2008\\Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm", 0, + "mk:@MSITStore:C:\\Program Files/AutoCAD 2008\\Help/acad_acg.chm::/WSfacf1429558a55de1a7524c1004e616f8b-322b.htm"}, + }; + + static const DWORD file_flags[] = {0, URL_FILE_USE_PATHURL, URL_WININET_COMPATIBILITY}; urllen = lstrlenA(winehqA); + /* Parameter checks */ + dwSize = ARRAY_SIZE(szReturnUrl); + hr = UrlCanonicalizeA(NULL, szReturnUrl, &dwSize, URL_UNESCAPE); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + ok(dwSize == ARRAY_SIZE(szReturnUrl), "got size %lu\n", dwSize); + + dwSize = ARRAY_SIZE(szReturnUrl); + hr = UrlCanonicalizeA(winehqA, NULL, &dwSize, URL_UNESCAPE); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + ok(dwSize == ARRAY_SIZE(szReturnUrl), "got size %lu\n", dwSize); + + hr = UrlCanonicalizeA(winehqA, szReturnUrl, NULL, URL_UNESCAPE); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + + dwSize = 0; + hr = UrlCanonicalizeA(winehqA, szReturnUrl, &dwSize, URL_UNESCAPE); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + ok(!dwSize, "got size %lu\n", dwSize); + /* buffer has no space for the result */ dwSize=urllen-1; memset(szReturnUrl, '#', urllen+4); szReturnUrl[urllen+4] = '\0'; SetLastError(0xdeadbeef); - hr = pUrlCanonicalizeA(winehqA, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE); + hr = UrlCanonicalizeA(winehqA, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE); ok( (hr == E_POINTER) && (dwSize == (urllen + 1)), - "got 0x%x with %u and size %u for '%s' and %u (expected 'E_POINTER' and size %u)\n", + "got 0x%lx with %lu and size %lu for '%s' and %u (expected 'E_POINTER' and size %lu)\n", hr, GetLastError(), dwSize, szReturnUrl, lstrlenA(szReturnUrl), urllen+1); /* buffer has no space for the terminating '\0' */ @@ -1089,9 +2074,9 @@ static void test_UrlCanonicalizeA(void) memset(szReturnUrl, '#', urllen+4); szReturnUrl[urllen+4] = '\0'; SetLastError(0xdeadbeef); - hr = pUrlCanonicalizeA(winehqA, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE); + hr = UrlCanonicalizeA(winehqA, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE); ok( (hr == E_POINTER) && (dwSize == (urllen + 1)), - "got 0x%x with %u and size %u for '%s' and %u (expected 'E_POINTER' and size %u)\n", + "got 0x%lx with %lu and size %lu for '%s' and %u (expected 'E_POINTER' and size %lu)\n", hr, GetLastError(), dwSize, szReturnUrl, lstrlenA(szReturnUrl), urllen+1); /* buffer has the required size */ @@ -1099,9 +2084,9 @@ static void test_UrlCanonicalizeA(void) memset(szReturnUrl, '#', urllen+4); szReturnUrl[urllen+4] = '\0'; SetLastError(0xdeadbeef); - hr = pUrlCanonicalizeA(winehqA, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE); + hr = UrlCanonicalizeA(winehqA, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE); ok( (hr == S_OK) && (dwSize == urllen), - "got 0x%x with %u and size %u for '%s' and %u (expected 'S_OK' and size %u)\n", + "got 0x%lx with %lu and size %lu for '%s' and %u (expected 'S_OK' and size %lu)\n", hr, GetLastError(), dwSize, szReturnUrl, lstrlenA(szReturnUrl), urllen); /* buffer is larger as the required size */ @@ -1109,9 +2094,9 @@ static void test_UrlCanonicalizeA(void) memset(szReturnUrl, '#', urllen+4); szReturnUrl[urllen+4] = '\0'; SetLastError(0xdeadbeef); - hr = pUrlCanonicalizeA(winehqA, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE); + hr = UrlCanonicalizeA(winehqA, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE); ok( (hr == S_OK) && (dwSize == urllen), - "got 0x%x with %u and size %u for '%s' and %u (expected 'S_OK' and size %u)\n", + "got 0x%lx with %lu and size %lu for '%s' and %u (expected 'S_OK' and size %lu)\n", hr, GetLastError(), dwSize, szReturnUrl, lstrlenA(szReturnUrl), urllen); /* length is set to 0 */ @@ -1119,9 +2104,9 @@ static void test_UrlCanonicalizeA(void) memset(szReturnUrl, '#', urllen+4); szReturnUrl[urllen+4] = '\0'; SetLastError(0xdeadbeef); - hr = pUrlCanonicalizeA(winehqA, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE); + hr = UrlCanonicalizeA(winehqA, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE); ok( (hr == E_INVALIDARG) && (dwSize == 0), - "got 0x%x with %u and size %u for '%s' and %u (expected 'E_INVALIDARG' and size %u)\n", + "got 0x%lx with %lu and size %lu for '%s' and %u (expected 'E_INVALIDARG' and size %u)\n", hr, GetLastError(), dwSize, szReturnUrl, lstrlenA(szReturnUrl), 0); /* url length > INTERNET_MAX_URL_SIZE */ @@ -1129,17 +2114,73 @@ static void test_UrlCanonicalizeA(void) memset(longurl, 'a', sizeof(longurl)); memcpy(longurl, winehqA, sizeof(winehqA)-1); longurl[sizeof(longurl)-1] = '\0'; - hr = pUrlCanonicalizeA(longurl, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE); - ok(hr == S_OK, "hr = %x\n", hr); + hr = UrlCanonicalizeA(longurl, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE); + ok(hr == S_OK, "hr = %lx\n", hr); + ok(dwSize == strlen(szReturnUrl), "got size %lu\n", dwSize); - test_url_canonicalize(-1, "", 0, S_OK, S_FALSE /* Vista/win2k8 */, "", FALSE); + for (f = 0; f < ARRAY_SIZE(file_flags); ++f) + { + for (i = 0; i < ARRAY_SIZE(unk_scheme_tests); ++i) + { + check_url_canonicalize(unk_scheme_tests[i].url, + unk_scheme_tests[i].flags | file_flags[f], unk_scheme_tests[i].expect); + sprintf(url, "wine:%s", unk_scheme_tests[i].url); + sprintf(expect, "wine:%s", unk_scheme_tests[i].expect); + check_url_canonicalize(url, unk_scheme_tests[i].flags | file_flags[f], expect); + } - /* test url-modification */ - for (i = 0; i < ARRAY_SIZE(TEST_CANONICALIZE); i++) { - test_url_canonicalize(i, TEST_CANONICALIZE[i].url, TEST_CANONICALIZE[i].flags, - TEST_CANONICALIZE[i].expectret, TEST_CANONICALIZE[i].expectret, TEST_CANONICALIZE[i].expecturl, - TEST_CANONICALIZE[i].todo); + for (i = 0; i < ARRAY_SIZE(http_tests); ++i) + { + static const struct + { + const char *prefix; + BOOL ftp_like; + } + prefixes[] = + { + {"ftp", TRUE}, + {"gopher"}, + {"http"}, + {"https"}, + {"local", TRUE}, + {"news"}, + {"nntp"}, + {"res", TRUE}, + {"snews"}, + {"telnet"}, + {"wais", TRUE}, + }; + + for (j = 0; j < ARRAY_SIZE(prefixes); ++j) + { + sprintf(url, "%s:%s", prefixes[j].prefix, http_tests[i].url); + if (prefixes[j].ftp_like && http_tests[i].expect_ftp) + sprintf(expect, "%s:%s", prefixes[j].prefix, http_tests[i].expect_ftp); + else + sprintf(expect, "%s:%s", prefixes[j].prefix, http_tests[i].expect); + + check_url_canonicalize(url, http_tests[i].flags | file_flags[f], expect); + } + } + + for (i = 0; i < ARRAY_SIZE(opaque_tests); ++i) + { + static const char *const prefixes[] = {"about", "javascript", "mailto", "shell", "vbscript"}; + + for (j = 0; j < ARRAY_SIZE(prefixes); ++j) + { + sprintf(url, "%s:%s", prefixes[j], opaque_tests[i].url); + sprintf(expect, "%s:%s", prefixes[j], opaque_tests[i].expect); + check_url_canonicalize(url, opaque_tests[i].flags | file_flags[f], expect); + } + } + + for (i = 0; i < ARRAY_SIZE(misc_tests); i++) + check_url_canonicalize(misc_tests[i].url, misc_tests[i].flags | file_flags[f], misc_tests[i].expect); } + + for (i = 0; i < ARRAY_SIZE(file_tests); i++) + check_url_canonicalize(file_tests[i].url, file_tests[i].flags, file_tests[i].expect); } /* ########################### */ @@ -1152,21 +2193,35 @@ static void test_UrlCanonicalizeW(void) HRESULT hr; int i; - - if (!pUrlCanonicalizeW) { - win_skip("UrlCanonicalizeW not found\n"); - return; - } urllen = lstrlenW(winehqW); + /* Parameter checks */ + dwSize = ARRAY_SIZE(szReturnUrl); + hr = UrlCanonicalizeW(NULL, szReturnUrl, &dwSize, URL_UNESCAPE); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + ok(dwSize == ARRAY_SIZE(szReturnUrl), "got size %lu\n", dwSize); + + dwSize = ARRAY_SIZE(szReturnUrl); + hr = UrlCanonicalizeW(winehqW, NULL, &dwSize, URL_UNESCAPE); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + ok(dwSize == ARRAY_SIZE(szReturnUrl), "got size %lu\n", dwSize); + + hr = UrlCanonicalizeW(winehqW, szReturnUrl, NULL, URL_UNESCAPE); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + + dwSize = 0; + hr = UrlCanonicalizeW(winehqW, szReturnUrl, &dwSize, URL_UNESCAPE); + ok(hr == E_INVALIDARG, "Got unexpected hr %#lx.\n", hr); + ok(!dwSize, "got size %lu\n", dwSize); + /* buffer has no space for the result */ dwSize = (urllen-1); memset(szReturnUrl, '#', (urllen+4) * sizeof(WCHAR)); szReturnUrl[urllen+4] = '\0'; SetLastError(0xdeadbeef); - hr = pUrlCanonicalizeW(winehqW, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE); + hr = UrlCanonicalizeW(winehqW, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE); ok( (hr == E_POINTER) && (dwSize == (urllen + 1)), - "got 0x%x with %u and size %u for %u (expected 'E_POINTER' and size %u)\n", + "got 0x%lx with %lu and size %lu for %u (expected 'E_POINTER' and size %lu)\n", hr, GetLastError(), dwSize, lstrlenW(szReturnUrl), urllen+1); @@ -1175,9 +2230,9 @@ static void test_UrlCanonicalizeW(void) memset(szReturnUrl, '#', (urllen+4) * sizeof(WCHAR)); szReturnUrl[urllen+4] = '\0'; SetLastError(0xdeadbeef); - hr = pUrlCanonicalizeW(winehqW, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE); + hr = UrlCanonicalizeW(winehqW, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE); ok( (hr == E_POINTER) && (dwSize == (urllen + 1)), - "got 0x%x with %u and size %u for %u (expected 'E_POINTER' and size %u)\n", + "got 0x%lx with %lu and size %lu for %u (expected 'E_POINTER' and size %lu)\n", hr, GetLastError(), dwSize, lstrlenW(szReturnUrl), urllen+1); /* buffer has the required size */ @@ -1185,9 +2240,9 @@ static void test_UrlCanonicalizeW(void) memset(szReturnUrl, '#', (urllen+4) * sizeof(WCHAR)); szReturnUrl[urllen+4] = '\0'; SetLastError(0xdeadbeef); - hr = pUrlCanonicalizeW(winehqW, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE); + hr = UrlCanonicalizeW(winehqW, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE); ok( (hr == S_OK) && (dwSize == urllen), - "got 0x%x with %u and size %u for %u (expected 'S_OK' and size %u)\n", + "got 0x%lx with %lu and size %lu for %u (expected 'S_OK' and size %lu)\n", hr, GetLastError(), dwSize, lstrlenW(szReturnUrl), urllen); /* buffer is larger as the required size */ @@ -1195,11 +2250,18 @@ static void test_UrlCanonicalizeW(void) memset(szReturnUrl, '#', (urllen+4) * sizeof(WCHAR)); szReturnUrl[urllen+4] = '\0'; SetLastError(0xdeadbeef); - hr = pUrlCanonicalizeW(winehqW, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE); + hr = UrlCanonicalizeW(winehqW, szReturnUrl, &dwSize, URL_WININET_COMPATIBILITY | URL_ESCAPE_UNSAFE); ok( (hr == S_OK) && (dwSize == urllen), - "got 0x%x with %u and size %u for %u (expected 'S_OK' and size %u)\n", + "got 0x%lx with %lu and size %lu for %u (expected 'S_OK' and size %lu)\n", hr, GetLastError(), dwSize, lstrlenW(szReturnUrl), urllen); + /* Only ASCII alphanumeric characters are allowed in a scheme. */ + dwSize = ARRAY_SIZE(szReturnUrl); + hr = UrlCanonicalizeW(L"f\xe8ve://./..", szReturnUrl, &dwSize, 0); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(!wcscmp(szReturnUrl, L"f\xe8ve:/"), "Got URL %s.\n", debugstr_w(szReturnUrl)); + ok(dwSize == wcslen(szReturnUrl), "got size %lu\n", dwSize); + /* check that the characters 1..32 are chopped from the end of the string */ for (i = 1; i < 65536; i++) { @@ -1207,11 +2269,11 @@ static void test_UrlCanonicalizeW(void) BOOL choped; int pos; - MultiByteToWideChar(CP_ACP, 0, "http://www.winehq.org/X", -1, szUrl, ARRAY_SIZE(szUrl)); + wcscpy(szUrl, L"http://www.winehq.org/X"); pos = lstrlenW(szUrl) - 1; szUrl[pos] = i; urllen = INTERNET_MAX_URL_LENGTH; - pUrlCanonicalizeW(szUrl, szReturnUrl, &urllen, 0); + UrlCanonicalizeW(szUrl, szReturnUrl, &urllen, 0); choped = lstrlenW(szReturnUrl) < lstrlenW(szUrl); ok(choped == (i <= 32), "Incorrect char chopping for char %d\n", i); } @@ -1219,7 +2281,7 @@ static void test_UrlCanonicalizeW(void) /* ########################### */ -static void test_url_combine(const char *szUrl1, const char *szUrl2, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl, BOOL todo) +static void check_url_combine(const char *szUrl1, const char *szUrl2, DWORD dwFlags, const char *szExpectUrl) { HRESULT hr; CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH]; @@ -1229,63 +2291,24 @@ static void test_url_combine(const char *szUrl1, const char *szUrl2, DWORD dwFla DWORD dwSize; DWORD dwExpectLen = lstrlenA(szExpectUrl); - if (!pUrlCombineA) { - win_skip("UrlCombineA not found\n"); - return; - } - wszUrl1 = GetWideString(szUrl1); wszUrl2 = GetWideString(szUrl2); wszExpectUrl = GetWideString(szExpectUrl); - hr = pUrlCombineA(szUrl1, szUrl2, NULL, NULL, dwFlags); - ok(hr == E_INVALIDARG, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr, E_INVALIDARG); + dwSize = ARRAY_SIZE(szReturnUrl); + hr = UrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(dwSize == dwExpectLen, "Got length %ld, expected %ld\n", dwSize, dwExpectLen); + ok(!strcmp(szReturnUrl, szExpectUrl), "Expected %s, got %s.\n", szExpectUrl, szReturnUrl); - dwSize = 0; - hr = pUrlCombineA(szUrl1, szUrl2, NULL, &dwSize, dwFlags); - ok(hr == E_POINTER, "Checking length of string, return was 0x%08x, expected 0x%08x\n", hr, E_POINTER); - ok(todo || dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1); - - dwSize--; - hr = pUrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags); - ok(hr == E_POINTER, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr, E_POINTER); - ok(todo || dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1); - - hr = pUrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags); - ok(hr == dwExpectReturn, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr, dwExpectReturn); - - if (todo) - { - todo_wine ok(dwSize == dwExpectLen && (FAILED(hr) || strcmp(szReturnUrl, szExpectUrl)==0), - "Expected %s (len=%d), but got %s (len=%d)\n", szExpectUrl, dwExpectLen, SUCCEEDED(hr) ? szReturnUrl : "(null)", dwSize); - } - else - { - ok(dwSize == dwExpectLen, "Got length %d, expected %d\n", dwSize, dwExpectLen); - if (SUCCEEDED(hr)) - ok(strcmp(szReturnUrl, szExpectUrl)==0, "Expected %s, but got %s\n", szExpectUrl, szReturnUrl); - } - - if (pUrlCombineW) { - dwSize = 0; - hr = pUrlCombineW(wszUrl1, wszUrl2, NULL, &dwSize, dwFlags); - ok(hr == E_POINTER, "Checking length of string, return was 0x%08x, expected 0x%08x\n", hr, E_POINTER); - ok(todo || dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1); - - dwSize--; - hr = pUrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags); - ok(hr == E_POINTER, "UrlCombineW returned 0x%08x, expected 0x%08x\n", hr, E_POINTER); - ok(todo || dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1); - - hr = pUrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags); - ok(hr == dwExpectReturn, "UrlCombineW returned 0x%08x, expected 0x%08x\n", hr, dwExpectReturn); - ok(todo || dwSize == dwExpectLen, "Got length %d, expected %d\n", dwSize, dwExpectLen); - if(SUCCEEDED(hr)) { - wszConvertedUrl = GetWideString(szReturnUrl); - ok(lstrcmpW(wszReturnUrl, wszConvertedUrl)==0, "Strings didn't match between ascii and unicode UrlCombine!\n"); - FreeWideString(wszConvertedUrl); - } - } + dwSize = ARRAY_SIZE(wszReturnUrl); + hr = UrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(dwSize == dwExpectLen, "Got length %ld, expected %ld\n", dwSize, dwExpectLen); + wszConvertedUrl = GetWideString(szReturnUrl); + ok(!wcscmp(wszReturnUrl, wszConvertedUrl), "Expected %s, got %s.\n", + debugstr_w(wszConvertedUrl), debugstr_w(wszReturnUrl)); + FreeWideString(wszConvertedUrl); FreeWideString(wszUrl1); FreeWideString(wszUrl2); @@ -1296,10 +2319,56 @@ static void test_url_combine(const char *szUrl1, const char *szUrl2, DWORD dwFla static void test_UrlCombine(void) { + WCHAR bufferW[30]; + char buffer[30]; unsigned int i; + HRESULT hr; + DWORD size; + + hr = UrlCombineA("http://base/", "relative", NULL, NULL, 0); + ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr); + + size = 0; + hr = UrlCombineA("http://base/", "relative", NULL, &size, 0); + ok(hr == E_POINTER, "Got hr %#lx.\n", hr); + ok(size == strlen("http://base/relative") + 1, "Got size %lu.\n", size); + + --size; + strcpy(buffer, "x"); + hr = UrlCombineA("http://base/", "relative", buffer, &size, 0); + ok(hr == E_POINTER, "Got hr %#lx.\n", hr); + ok(size == strlen("http://base/relative") + 1, "Got size %lu.\n", size); + ok(!strcmp(buffer, "x"), "Got buffer contents %s.\n", debugstr_a(buffer)); + + strcpy(buffer, "x"); + hr = UrlCombineA("http://base/", "relative", buffer, &size, 0); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(size == strlen("http://base/relative"), "Got size %lu.\n", size); + ok(!strcmp(buffer, "http://base/relative"), "Got buffer contents %s.\n", debugstr_a(buffer)); + + hr = UrlCombineW(L"http://base/", L"relative", NULL, NULL, 0); + ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr); + + size = 0; + hr = UrlCombineW(L"http://base/", L"relative", NULL, &size, 0); + ok(hr == E_POINTER, "Got hr %#lx.\n", hr); + ok(size == strlen("http://base/relative") + 1, "Got size %lu.\n", size); + + --size; + wcscpy(bufferW, L"x"); + hr = UrlCombineW(L"http://base/", L"relative", bufferW, &size, 0); + ok(hr == E_POINTER, "Got hr %#lx.\n", hr); + ok(size == strlen("http://base/relative") + 1, "Got size %lu.\n", size); + ok(!wcscmp(bufferW, L"x"), "Got buffer contents %s.\n", debugstr_a(buffer)); + + wcscpy(bufferW, L"x"); + hr = UrlCombineW(L"http://base/", L"relative", bufferW, &size, 0); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(size == strlen("http://base/relative"), "Got size %lu.\n", size); + ok(!wcscmp(bufferW, L"http://base/relative"), "Got buffer contents %s.\n", debugstr_w(bufferW)); + for (i = 0; i < ARRAY_SIZE(TEST_COMBINE); i++) { - test_url_combine(TEST_COMBINE[i].url1, TEST_COMBINE[i].url2, TEST_COMBINE[i].flags, - TEST_COMBINE[i].expectret, TEST_COMBINE[i].expecturl, TEST_COMBINE[i].todo); + check_url_combine(TEST_COMBINE[i].url1, TEST_COMBINE[i].url2, TEST_COMBINE[i].flags, TEST_COMBINE[i].expecturl); } } @@ -1313,32 +2382,25 @@ static void test_UrlCreateFromPath(void) WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH]; WCHAR *pathW, *urlW; - if (!pUrlCreateFromPathA) { - win_skip("UrlCreateFromPathA not found\n"); - return; - } - for (i = 0; i < ARRAY_SIZE(TEST_URLFROMPATH); i++) { len = INTERNET_MAX_URL_LENGTH; - ret = pUrlCreateFromPathA(TEST_URLFROMPATH[i].path, ret_url, &len, 0); - ok(ret == TEST_URLFROMPATH[i].ret, "ret %08x from path %s\n", ret, TEST_URLFROMPATH[i].path); + ret = UrlCreateFromPathA(TEST_URLFROMPATH[i].path, ret_url, &len, 0); + ok(ret == TEST_URLFROMPATH[i].ret, "ret %08lx from path %s\n", ret, TEST_URLFROMPATH[i].path); ok(!lstrcmpiA(ret_url, TEST_URLFROMPATH[i].url), "url %s from path %s\n", ret_url, TEST_URLFROMPATH[i].path); - ok(len == strlen(ret_url), "ret len %d from path %s\n", len, TEST_URLFROMPATH[i].path); + ok(len == strlen(ret_url), "ret len %ld from path %s\n", len, TEST_URLFROMPATH[i].path); - if (pUrlCreateFromPathW) { - len = INTERNET_MAX_URL_LENGTH; - pathW = GetWideString(TEST_URLFROMPATH[i].path); - urlW = GetWideString(TEST_URLFROMPATH[i].url); - ret = pUrlCreateFromPathW(pathW, ret_urlW, &len, 0); - WideCharToMultiByte(CP_ACP, 0, ret_urlW, -1, ret_url, sizeof(ret_url),0,0); - ok(ret == TEST_URLFROMPATH[i].ret, "ret %08x from path L\"%s\", expected %08x\n", - ret, TEST_URLFROMPATH[i].path, TEST_URLFROMPATH[i].ret); - ok(!lstrcmpiW(ret_urlW, urlW), "got %s expected %s from path L\"%s\"\n", - ret_url, TEST_URLFROMPATH[i].url, TEST_URLFROMPATH[i].path); - ok(len == lstrlenW(ret_urlW), "ret len %d from path L\"%s\"\n", len, TEST_URLFROMPATH[i].path); - FreeWideString(urlW); - FreeWideString(pathW); - } + len = INTERNET_MAX_URL_LENGTH; + pathW = GetWideString(TEST_URLFROMPATH[i].path); + urlW = GetWideString(TEST_URLFROMPATH[i].url); + ret = UrlCreateFromPathW(pathW, ret_urlW, &len, 0); + WideCharToMultiByte(CP_ACP, 0, ret_urlW, -1, ret_url, sizeof(ret_url),0,0); + ok(ret == TEST_URLFROMPATH[i].ret, "ret %08lx from path L\"%s\", expected %08lx\n", + ret, TEST_URLFROMPATH[i].path, TEST_URLFROMPATH[i].ret); + ok(!lstrcmpiW(ret_urlW, urlW), "got %s expected %s from path L\"%s\"\n", + ret_url, TEST_URLFROMPATH[i].url, TEST_URLFROMPATH[i].path); + ok(len == lstrlenW(ret_urlW), "ret len %ld from path L\"%s\"\n", len, TEST_URLFROMPATH[i].path); + FreeWideString(urlW); + FreeWideString(pathW); } } @@ -1347,10 +2409,10 @@ static void test_UrlCreateFromPath(void) static void test_UrlIs_null(DWORD flag) { BOOL ret; - ret = pUrlIsA(NULL, flag); - ok(ret == FALSE, "pUrlIsA(NULL, %d) failed\n", flag); - ret = pUrlIsW(NULL, flag); - ok(ret == FALSE, "pUrlIsW(NULL, %d) failed\n", flag); + ret = UrlIsA(NULL, flag); + ok(ret == FALSE, "pUrlIsA(NULL, %ld) failed\n", flag); + ret = UrlIsW(NULL, flag); + ok(ret == FALSE, "pUrlIsW(NULL, %ld) failed\n", flag); } static void test_UrlIs(void) @@ -1359,11 +2421,6 @@ static void test_UrlIs(void) size_t i; WCHAR wurl[80]; - if (!pUrlIsA) { - win_skip("UrlIsA not found\n"); - return; - } - test_UrlIs_null(URLIS_APPLIABLE); test_UrlIs_null(URLIS_DIRECTORY); test_UrlIs_null(URLIS_FILEURL); @@ -1375,40 +2432,36 @@ static void test_UrlIs(void) for (i = 0; i < ARRAY_SIZE(TEST_PATH_IS_URL); i++) { MultiByteToWideChar(CP_ACP, 0, TEST_PATH_IS_URL[i].path, -1, wurl, ARRAY_SIZE(wurl)); - ret = pUrlIsA( TEST_PATH_IS_URL[i].path, URLIS_URL ); + ret = UrlIsA( TEST_PATH_IS_URL[i].path, URLIS_URL ); ok( ret == TEST_PATH_IS_URL[i].expect, "returned %d from path %s, expected %d\n", ret, TEST_PATH_IS_URL[i].path, TEST_PATH_IS_URL[i].expect ); - if (pUrlIsW) { - ret = pUrlIsW( wurl, URLIS_URL ); - ok( ret == TEST_PATH_IS_URL[i].expect, - "returned %d from path (UrlIsW) %s, expected %d\n", ret, - TEST_PATH_IS_URL[i].path, TEST_PATH_IS_URL[i].expect ); - } + ret = UrlIsW( wurl, URLIS_URL ); + ok( ret == TEST_PATH_IS_URL[i].expect, + "returned %d from path (UrlIsW) %s, expected %d\n", ret, + TEST_PATH_IS_URL[i].path, TEST_PATH_IS_URL[i].expect ); } for (i = 0; i < ARRAY_SIZE(TEST_URLIS_ATTRIBS); i++) { MultiByteToWideChar(CP_ACP, 0, TEST_URLIS_ATTRIBS[i].url, -1, wurl, ARRAY_SIZE(wurl)); - ret = pUrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_OPAQUE); + ret = UrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_OPAQUE); ok( ret == TEST_URLIS_ATTRIBS[i].expectOpaque, "returned %d for URLIS_OPAQUE, url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url, TEST_URLIS_ATTRIBS[i].expectOpaque ); - ret = pUrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_FILEURL); + ret = UrlIsA( TEST_URLIS_ATTRIBS[i].url, URLIS_FILEURL); ok( ret == TEST_URLIS_ATTRIBS[i].expectFile, "returned %d for URLIS_FILEURL, url \"%s\", expected %d\n", ret, TEST_URLIS_ATTRIBS[i].url, TEST_URLIS_ATTRIBS[i].expectFile ); - if (pUrlIsW) { - ret = pUrlIsW( wurl, URLIS_OPAQUE); - ok( ret == TEST_URLIS_ATTRIBS[i].expectOpaque, - "returned %d for URLIS_OPAQUE (UrlIsW), url \"%s\", expected %d\n", - ret, TEST_URLIS_ATTRIBS[i].url, TEST_URLIS_ATTRIBS[i].expectOpaque ); - ret = pUrlIsW( wurl, URLIS_FILEURL); - ok( ret == TEST_URLIS_ATTRIBS[i].expectFile, - "returned %d for URLIS_FILEURL (UrlIsW), url \"%s\", expected %d\n", - ret, TEST_URLIS_ATTRIBS[i].url, TEST_URLIS_ATTRIBS[i].expectFile ); - } + ret = UrlIsW( wurl, URLIS_OPAQUE); + ok( ret == TEST_URLIS_ATTRIBS[i].expectOpaque, + "returned %d for URLIS_OPAQUE (UrlIsW), url \"%s\", expected %d\n", + ret, TEST_URLIS_ATTRIBS[i].url, TEST_URLIS_ATTRIBS[i].expectOpaque ); + ret = UrlIsW( wurl, URLIS_FILEURL); + ok( ret == TEST_URLIS_ATTRIBS[i].expectFile, + "returned %d for URLIS_FILEURL (UrlIsW), url \"%s\", expected %d\n", + ret, TEST_URLIS_ATTRIBS[i].url, TEST_URLIS_ATTRIBS[i].expectFile ); } } @@ -1416,80 +2469,80 @@ static void test_UrlIs(void) static void test_UrlUnescape(void) { + WCHAR urlW[INTERNET_MAX_URL_LENGTH], bufferW[INTERNET_MAX_URL_LENGTH]; CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH]; - WCHAR ret_urlW[INTERNET_MAX_URL_LENGTH]; - WCHAR *urlW, *expected_urlW; - DWORD dwEscaped; - size_t i; + DWORD dwEscaped, unescaped; + BOOL utf8_support = TRUE; static char inplace[] = "file:///C:/Program%20Files"; static char another_inplace[] = "file:///C:/Program%20Files"; static const char expected[] = "file:///C:/Program Files"; - static WCHAR inplaceW[] = {'f','i','l','e',':','/','/','/','C',':','/','P','r','o','g','r','a','m',' ','F','i','l','e','s',0}; - static WCHAR another_inplaceW[] ={'f','i','l','e',':','/','/','/', - 'C',':','/','P','r','o','g','r','a','m','%','2','0','F','i','l','e','s',0}; HRESULT res; + int i; - if (!pUrlUnescapeA) { - win_skip("UrlUnescapeA not found\n"); - return; - } for (i = 0; i < ARRAY_SIZE(TEST_URL_UNESCAPE); i++) { dwEscaped=INTERNET_MAX_URL_LENGTH; - res = pUrlUnescapeA(TEST_URL_UNESCAPE[i].url, szReturnUrl, &dwEscaped, 0); + res = UrlUnescapeA(TEST_URL_UNESCAPE[i].url, szReturnUrl, &dwEscaped, 0); ok(res == S_OK, - "UrlUnescapeA returned 0x%x (expected S_OK) for \"%s\"\n", + "UrlUnescapeA returned 0x%lx (expected S_OK) for \"%s\"\n", res, TEST_URL_UNESCAPE[i].url); ok(strcmp(szReturnUrl,TEST_URL_UNESCAPE[i].expect)==0, "Expected \"%s\", but got \"%s\" from \"%s\"\n", TEST_URL_UNESCAPE[i].expect, szReturnUrl, TEST_URL_UNESCAPE[i].url); ZeroMemory(szReturnUrl, sizeof(szReturnUrl)); /* if we set the buffer pointer to NULL here, UrlUnescape fails and the string is not converted */ - res = pUrlUnescapeA(TEST_URL_UNESCAPE[i].url, szReturnUrl, NULL, 0); + res = UrlUnescapeA(TEST_URL_UNESCAPE[i].url, szReturnUrl, NULL, 0); ok(res == E_INVALIDARG, - "UrlUnescapeA returned 0x%x (expected E_INVALIDARG) for \"%s\"\n", + "UrlUnescapeA returned 0x%lx (expected E_INVALIDARG) for \"%s\"\n", res, TEST_URL_UNESCAPE[i].url); ok(strcmp(szReturnUrl,"")==0, "Expected empty string\n"); + } - if (pUrlUnescapeW) { - dwEscaped = INTERNET_MAX_URL_LENGTH; - urlW = GetWideString(TEST_URL_UNESCAPE[i].url); - expected_urlW = GetWideString(TEST_URL_UNESCAPE[i].expect); - res = pUrlUnescapeW(urlW, ret_urlW, &dwEscaped, 0); - ok(res == S_OK, - "UrlUnescapeW returned 0x%x (expected S_OK) for \"%s\"\n", - res, TEST_URL_UNESCAPE[i].url); + unescaped = INTERNET_MAX_URL_LENGTH; + lstrcpyW(urlW, L"%F0%9F%8D%B7"); + res = UrlUnescapeW(urlW, NULL, &unescaped, URL_UNESCAPE_AS_UTF8 | URL_UNESCAPE_INPLACE); + ok(res == S_OK, "Got %#lx.\n", res); + if (!wcscmp(urlW, L"\xf0\x9f\x8d\xb7")) + { + utf8_support = FALSE; + win_skip("Skip URL_UNESCAPE_AS_UTF8 tests for pre-win7 systems.\n"); + } - WideCharToMultiByte(CP_ACP,0,ret_urlW,-1,szReturnUrl,INTERNET_MAX_URL_LENGTH,0,0); - ok(lstrcmpW(ret_urlW, expected_urlW)==0, - "Expected \"%s\", but got \"%s\" from \"%s\" flags %08lx\n", - TEST_URL_UNESCAPE[i].expect, szReturnUrl, TEST_URL_UNESCAPE[i].url, 0L); - FreeWideString(urlW); - FreeWideString(expected_urlW); - } + for (i = 0; i < ARRAYSIZE(TEST_URL_UNESCAPEW); i++) + { + if (TEST_URL_UNESCAPEW[i].flags & URL_UNESCAPE_AS_UTF8 && !utf8_support) + continue; + + lstrcpyW(urlW, TEST_URL_UNESCAPEW[i].url); + + memset(bufferW, 0xff, sizeof(bufferW)); + unescaped = INTERNET_MAX_URL_LENGTH; + res = UrlUnescapeW(urlW, bufferW, &unescaped, TEST_URL_UNESCAPEW[i].flags); + ok(res == S_OK, "[%d]: returned %#lx.\n", i, res); + ok(unescaped == wcslen(TEST_URL_UNESCAPEW[i].expect), "[%d]: got unescaped %ld.\n", i, unescaped); + ok(!wcscmp(bufferW, TEST_URL_UNESCAPEW[i].expect), "[%d]: got result %s.\n", i, debugstr_w(bufferW)); + + /* Test with URL_UNESCAPE_INPLACE */ + unescaped = INTERNET_MAX_URL_LENGTH; + res = UrlUnescapeW(urlW, NULL, &unescaped, TEST_URL_UNESCAPEW[i].flags | URL_UNESCAPE_INPLACE); + ok(res == S_OK, "[%d]: returned %#lx.\n", i, res); + ok(unescaped == INTERNET_MAX_URL_LENGTH, "[%d]: got unescaped %ld.\n", i, unescaped); + ok(!wcscmp(urlW, TEST_URL_UNESCAPEW[i].expect), "[%d]: got result %s.\n", i, debugstr_w(urlW)); + + lstrcpyW(urlW, TEST_URL_UNESCAPEW[i].url); + unescaped = wcslen(TEST_URL_UNESCAPEW[i].expect) - 1; + res = UrlUnescapeW(urlW, bufferW, &unescaped, TEST_URL_UNESCAPEW[i].flags); + ok(res == E_POINTER, "[%d]: returned %#lx.\n", i, res); } dwEscaped = sizeof(inplace); - res = pUrlUnescapeA(inplace, NULL, &dwEscaped, URL_UNESCAPE_INPLACE); - ok(res == S_OK, "UrlUnescapeA returned 0x%x (expected S_OK)\n", res); + res = UrlUnescapeA(inplace, NULL, &dwEscaped, URL_UNESCAPE_INPLACE); + ok(res == S_OK, "UrlUnescapeA returned 0x%lx (expected S_OK)\n", res); ok(!strcmp(inplace, expected), "got %s expected %s\n", inplace, expected); - ok(dwEscaped == 27, "got %d expected 27\n", dwEscaped); + ok(dwEscaped == 27, "got %ld expected 27\n", dwEscaped); /* if we set the buffer pointer to NULL, the string apparently still gets converted (Google Lively does this) */ - res = pUrlUnescapeA(another_inplace, NULL, NULL, URL_UNESCAPE_INPLACE); - ok(res == S_OK, "UrlUnescapeA returned 0x%x (expected S_OK)\n", res); + res = UrlUnescapeA(another_inplace, NULL, NULL, URL_UNESCAPE_INPLACE); + ok(res == S_OK, "UrlUnescapeA returned 0x%lx (expected S_OK)\n", res); ok(!strcmp(another_inplace, expected), "got %s expected %s\n", another_inplace, expected); - - if (pUrlUnescapeW) { - dwEscaped = sizeof(inplaceW); - res = pUrlUnescapeW(inplaceW, NULL, &dwEscaped, URL_UNESCAPE_INPLACE); - ok(res == S_OK, "UrlUnescapeW returned 0x%x (expected S_OK)\n", res); - ok(dwEscaped == 50, "got %d expected 50\n", dwEscaped); - - /* if we set the buffer pointer to NULL, the string apparently still gets converted (Google Lively does this) */ - res = pUrlUnescapeW(another_inplaceW, NULL, NULL, URL_UNESCAPE_INPLACE); - ok(res == S_OK, "UrlUnescapeW returned 0x%x (expected S_OK)\n", res); - - ok(lstrlenW(another_inplaceW) == 24, "got %d expected 24\n", lstrlenW(another_inplaceW)); - } } static const struct parse_url_test_t { @@ -1527,8 +2580,8 @@ static void test_ParseURL(void) for (test = parse_url_tests; test < parse_url_tests + ARRAY_SIZE(parse_url_tests); test++) { memset(&parseda, 0xd0, sizeof(parseda)); parseda.cbSize = sizeof(parseda); - hres = pParseURLA(test->url, &parseda); - ok(hres == test->hres, "ParseURL failed: %08x, expected %08x\n", hres, test->hres); + hres = ParseURLA(test->url, &parseda); + ok(hres == test->hres, "ParseURL failed: %08lx, expected %08lx\n", hres, test->hres); if(hres == S_OK) { ok(parseda.pszProtocol == test->url, "parseda.pszProtocol = %s, expected %s\n", parseda.pszProtocol, test->url); @@ -1550,8 +2603,8 @@ static void test_ParseURL(void) memset(&parsedw, 0xd0, sizeof(parsedw)); parsedw.cbSize = sizeof(parsedw); - hres = pParseURLW(url, &parsedw); - ok(hres == test->hres, "ParseURL failed: %08x, expected %08x\n", hres, test->hres); + hres = ParseURLW(url, &parsedw); + ok(hres == test->hres, "ParseURL failed: %08lx, expected %08lx\n", hres, test->hres); if(hres == S_OK) { ok(parsedw.pszProtocol == url, "parsedw.pszProtocol = %s, expected %s\n", wine_dbgstr_w(parsedw.pszProtocol), wine_dbgstr_w(url)); @@ -1591,38 +2644,29 @@ static void test_HashData(void) int i; /* Test hashing with identically sized input/output buffers. */ - res = pHashData(input, 16, output, 16); - ok(res == S_OK, "Expected HashData to return S_OK, got 0x%08x\n", res); - if(res == S_OK) - ok(!memcmp(output, expected, sizeof(expected)), - "Output buffer did not match expected contents\n"); + res = HashData(input, 16, output, 16); + ok(res == S_OK, "Expected HashData to return S_OK, got 0x%08lx\n", res); + ok(!memcmp(output, expected, sizeof(expected)), "data didn't match\n"); /* Test hashing with larger output buffer. */ - res = pHashData(input, 16, output, 32); - ok(res == S_OK, "Expected HashData to return S_OK, got 0x%08x\n", res); - if(res == S_OK) - ok(!memcmp(output, expected2, sizeof(expected2)), - "Output buffer did not match expected contents\n"); + res = HashData(input, 16, output, 32); + ok(res == S_OK, "Expected HashData to return S_OK, got 0x%08lx\n", res); + ok(!memcmp(output, expected2, sizeof(expected2)), "data didn't match\n"); /* Test hashing with smaller input buffer. */ - res = pHashData(input, 8, output, 16); - ok(res == S_OK, "Expected HashData to return S_OK, got 0x%08x\n", res); - if(res == S_OK) - ok(!memcmp(output, expected3, sizeof(expected3)), - "Output buffer did not match expected contents\n"); + res = HashData(input, 8, output, 16); + ok(res == S_OK, "Expected HashData to return S_OK, got 0x%08lx\n", res); + ok(!memcmp(output, expected3, sizeof(expected3)), "data didn't match\n"); /* Test passing NULL pointers for input/output parameters. */ - res = pHashData(NULL, 0, NULL, 0); - ok(res == E_INVALIDARG || broken(res == S_OK), /* Windows 2000 */ - "Expected HashData to return E_INVALIDARG, got 0x%08x\n", res); + res = HashData(NULL, 0, NULL, 0); + ok(res == E_INVALIDARG, "Got unexpected hr %#lx.\n", res); - res = pHashData(input, 0, NULL, 0); - ok(res == E_INVALIDARG || broken(res == S_OK), /* Windows 2000 */ - "Expected HashData to return E_INVALIDARG, got 0x%08x\n", res); + res = HashData(input, 0, NULL, 0); + ok(res == E_INVALIDARG, "Got unexpected hr %#lx.\n", res); - res = pHashData(NULL, 0, output, 0); - ok(res == E_INVALIDARG || broken(res == S_OK), /* Windows 2000 */ - "Expected HashData to return E_INVALIDARG, got 0x%08x\n", res); + res = HashData(NULL, 0, output, 0); + ok(res == E_INVALIDARG, "Got unexpected hr %#lx.\n", res); /* Test passing valid pointers with sizes of zero. */ for (i = 0; i < ARRAY_SIZE(input); i++) @@ -1631,30 +2675,24 @@ static void test_HashData(void) for (i = 0; i < ARRAY_SIZE(output); i++) output[i] = 0xFF; - res = pHashData(input, 0, output, 0); - ok(res == S_OK, "Expected HashData to return S_OK, got 0x%08x\n", res); + res = HashData(input, 0, output, 0); + ok(res == S_OK, "Expected HashData to return S_OK, got 0x%08lx\n", res); /* The buffers should be unchanged. */ for (i = 0; i < ARRAY_SIZE(input); i++) - { ok(input[i] == 0x00, "Expected the input buffer to be unchanged\n"); - if(input[i] != 0x00) break; - } for (i = 0; i < ARRAY_SIZE(output); i++) - { ok(output[i] == 0xFF, "Expected the output buffer to be unchanged\n"); - if(output[i] != 0xFF) break; - } /* Input/output parameters are not validated. */ - res = pHashData((BYTE *)0xdeadbeef, 0, (BYTE *)0xdeadbeef, 0); - ok(res == S_OK, "Expected HashData to return S_OK, got 0x%08x\n", res); + res = HashData((BYTE *)0xdeadbeef, 0, (BYTE *)0xdeadbeef, 0); + ok(res == S_OK, "Expected HashData to return S_OK, got 0x%08lx\n", res); if (0) { - res = pHashData((BYTE *)0xdeadbeef, 1, (BYTE *)0xdeadbeef, 1); - trace("HashData returned 0x%08x\n", res); + res = HashData((BYTE *)0xdeadbeef, 1, (BYTE *)0xdeadbeef, 1); + trace("HashData returned 0x%08lx\n", res); } } @@ -1662,39 +2700,6 @@ static void test_HashData(void) START_TEST(url) { - char *pFunc; - - hShlwapi = GetModuleHandleA("shlwapi.dll"); - - /* SHCreateStreamOnFileEx was introduced in shlwapi v6.0 */ - pFunc = (void*)GetProcAddress(hShlwapi, "SHCreateStreamOnFileEx"); - if(!pFunc){ - win_skip("Too old shlwapi version\n"); - return; - } - - pUrlUnescapeA = (void *) GetProcAddress(hShlwapi, "UrlUnescapeA"); - pUrlUnescapeW = (void *) GetProcAddress(hShlwapi, "UrlUnescapeW"); - pUrlIsA = (void *) GetProcAddress(hShlwapi, "UrlIsA"); - pUrlIsW = (void *) GetProcAddress(hShlwapi, "UrlIsW"); - pUrlHashA = (void *) GetProcAddress(hShlwapi, "UrlHashA"); - pUrlHashW = (void *) GetProcAddress(hShlwapi, "UrlHashW"); - pUrlGetPartA = (void *) GetProcAddress(hShlwapi, "UrlGetPartA"); - pUrlGetPartW = (void *) GetProcAddress(hShlwapi, "UrlGetPartW"); - pUrlEscapeA = (void *) GetProcAddress(hShlwapi, "UrlEscapeA"); - pUrlEscapeW = (void *) GetProcAddress(hShlwapi, "UrlEscapeW"); - pUrlCreateFromPathA = (void *) GetProcAddress(hShlwapi, "UrlCreateFromPathA"); - pUrlCreateFromPathW = (void *) GetProcAddress(hShlwapi, "UrlCreateFromPathW"); - pUrlCombineA = (void *) GetProcAddress(hShlwapi, "UrlCombineA"); - pUrlCombineW = (void *) GetProcAddress(hShlwapi, "UrlCombineW"); - pUrlCanonicalizeA = (void *) GetProcAddress(hShlwapi, "UrlCanonicalizeA"); - pUrlCanonicalizeW = (void *) GetProcAddress(hShlwapi, "UrlCanonicalizeW"); - pUrlApplySchemeA = (void *) GetProcAddress(hShlwapi, "UrlApplySchemeA"); - pUrlApplySchemeW = (void *) GetProcAddress(hShlwapi, "UrlApplySchemeW"); - pParseURLA = (void*)GetProcAddress(hShlwapi, (LPCSTR)1); - pParseURLW = (void*)GetProcAddress(hShlwapi, (LPCSTR)2); - pHashData = (void*)GetProcAddress(hShlwapi, "HashData"); - test_UrlApplyScheme(); test_UrlHash(); test_UrlGetPart();