diff --git a/rostests/winetests/urlmon/CMakeLists.txt b/rostests/winetests/urlmon/CMakeLists.txt index 609a9aae811..540a7c71ea2 100644 --- a/rostests/winetests/urlmon/CMakeLists.txt +++ b/rostests/winetests/urlmon/CMakeLists.txt @@ -1,9 +1,7 @@ remove_definitions(-DWINVER=0x502 -D_WIN32_IE=0x600 -D_WIN32_WINNT=0x502) -add_definitions( - -D__ROS_LONG64__ - -D_DLL -D__USE_CRTIMP) +add_definitions(-D__ROS_LONG64__) list(APPEND SOURCE generated.c @@ -18,5 +16,5 @@ list(APPEND SOURCE add_executable(urlmon_winetest ${SOURCE}) target_link_libraries(urlmon_winetest wine uuid) set_module_type(urlmon_winetest win32cui) -add_importlibs(urlmon_winetest urlmon ole32 oleaut32 user32 advapi32 msvcrt kernel32 ntdll) +add_importlibs(urlmon_winetest urlmon wininet ole32 oleaut32 user32 advapi32 msvcrt kernel32 ntdll) add_cd_file(TARGET urlmon_winetest DESTINATION reactos/bin FOR all) diff --git a/rostests/winetests/urlmon/generated.c b/rostests/winetests/urlmon/generated.c index 63e892bc543..138935072ef 100644 --- a/rostests/winetests/urlmon/generated.c +++ b/rostests/winetests/urlmon/generated.c @@ -5,6 +5,10 @@ * Unit tests for data structure packing */ +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + #define WINVER 0x0501 #define _WIN32_IE 0x0501 #define _WIN32_WINNT 0x0501 @@ -12,11 +16,12 @@ #define WINE_NOWINSOCK #include -#include "windef.h" -#include "winbase.h" -#include "urlmon.h" +#include +#include +#include +#include -#include "wine/test.h" +#include /*********************************************************************** * Compatibility macros diff --git a/rostests/winetests/urlmon/misc.c b/rostests/winetests/urlmon/misc.c index e4dc20094d4..04a7de066ef 100644 --- a/rostests/winetests/urlmon/misc.c +++ b/rostests/winetests/urlmon/misc.c @@ -16,20 +16,25 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + #define COBJMACROS #define CONST_VTABLE #define NONAMELESSUNION #include -#include -#include +//#include +//#include -#include "windef.h" -#include "winbase.h" -#include "ole2.h" -#include "urlmon.h" +//#include "windef.h" +//#include "winbase.h" +#include +#include +//#include "urlmon.h" -#include "initguid.h" +#include DEFINE_GUID(CLSID_AboutProtocol, 0x3050F406, 0x98B5, 0x11CF, 0xBB,0x82, 0x00,0xAA,0x00,0xBD,0xCE,0x0B); @@ -69,6 +74,7 @@ static HRESULT (WINAPI *pCoInternetGetSession)(DWORD, IInternetSession **, DWORD static HRESULT (WINAPI *pCoInternetParseUrl)(LPCWSTR, PARSEACTION, DWORD, LPWSTR, DWORD, DWORD *, DWORD); static HRESULT (WINAPI *pCoInternetQueryInfo)(LPCWSTR, QUERYOPTION, DWORD, LPVOID, DWORD, DWORD *, DWORD); static HRESULT (WINAPI *pCopyStgMedium)(const STGMEDIUM *, STGMEDIUM *); +static HRESULT (WINAPI *pCopyBindInfo)(const BINDINFO *, BINDINFO *); static HRESULT (WINAPI *pFindMimeFromData)(LPBC, LPCWSTR, LPVOID, DWORD, LPCWSTR, DWORD, LPWSTR*, DWORD); static HRESULT (WINAPI *pObtainUserAgentString)(DWORD, LPSTR, DWORD*); @@ -439,6 +445,7 @@ static void test_CoInternetQueryInfo(void) static const WCHAR mimeTextHtml[] = {'t','e','x','t','/','h','t','m','l',0}; static const WCHAR mimeTextPlain[] = {'t','e','x','t','/','p','l','a','i','n',0}; static const WCHAR mimeTextRichtext[] = {'t','e','x','t','/','r','i','c','h','t','e','x','t',0}; +static const WCHAR mimeTextXml[] = {'t','e','x','t','/','x','m','l',0}; static const WCHAR mimeAppOctetStream[] = {'a','p','p','l','i','c','a','t','i','o','n','/', 'o','c','t','e','t','-','s','t','r','e','a','m',0}; static const WCHAR mimeImagePjpeg[] = {'i','m','a','g','e','/','p','j','p','e','g',0}; @@ -515,7 +522,7 @@ static BYTE data35[] = {0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,'x','x','x','x',0}; static BYTE data36[] = {0x89,'P','N','G',0x0d,0x0a,0x1a,'x','x'}; static BYTE data37[] = {0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,'<','h','t','m','l','>'}; static BYTE data38[] = {0x00,0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,'x'}; -static BYTE data39[] = {0x4d,0x4d,0x00,0x2a}; +static BYTE data39[] = {0x4d,0x4d,0x00,0x2a,0xff}; static BYTE data40[] = {0x4d,0x4d,0x00,0x2a,'<','h','t','m','l','>',0}; static BYTE data41[] = {0x4d,0x4d,0xff}; static BYTE data42[] = {0x4d,0x4d}; @@ -562,103 +569,126 @@ static BYTE data82[] = {'.','s','n','d',0}; static BYTE data83[] = {'.','s','n','d'}; static BYTE data84[] = {'.','s','n','d',0,'<','h','t','m','l','>',1,1}; static BYTE data85[] = {'.','S','N','D',0}; +static BYTE data86[] = {0x49,0x49,0x2a,0xff}; +static BYTE data87[] = {' ','<','h','e','a','d'}; +static BYTE data88[] = {' ','<','h','e','a','d','>'}; +static BYTE data89[] = {'\t','\r','<','h','e','a','d','>'}; +static BYTE data90[] = {'<','H','e','A','d',' '}; +static BYTE data91[] = {'<','?','x','m','l',' ',0}; +static BYTE data92[] = {'a','b','c','<','?','x','m','l',' ',' '}; +static BYTE data93[] = {'<','?','x','m','l',' ',' ','<','h','t','m','l','>'}; +static BYTE data94[] = {'<','h','t','m','l','>','<','?','x','m','l',' ',' '}; +static BYTE data95[] = {'{','\\','r','t','f','<','?','x','m','l',' ',' '}; +static BYTE data96[] = {'<','?','x','m','l',' '}; static const struct { BYTE *data; DWORD size; - LPCWSTR mime, mime_alt; + LPCWSTR mime, mime_pjpeg, broken_mime; } mime_tests2[] = { - {data1, sizeof(data1), mimeTextPlain}, - {data2, sizeof(data2), mimeAppOctetStream}, - {data3, sizeof(data3), mimeAppOctetStream}, - {data4, sizeof(data4), mimeAppOctetStream}, - {data5, sizeof(data5), mimeTextPlain}, - {data6, sizeof(data6), mimeTextPlain}, - {data7, sizeof(data7), mimeTextHtml, mimeTextPlain /* IE8 */}, - {data8, sizeof(data8), mimeTextHtml, mimeTextPlain /* IE8 */}, - {data9, sizeof(data9), mimeTextHtml, mimeImagePjpeg /* IE8 */}, - {data10, sizeof(data10), mimeTextHtml, mimeTextPlain /* IE8 */}, - {data11, sizeof(data11), mimeTextHtml, mimeTextPlain /* IE8 */}, - {data12, sizeof(data12), mimeTextHtml, mimeTextPlain /* IE8 */}, - {data13, sizeof(data13), mimeTextPlain}, - {data14, sizeof(data14), mimeTextPlain}, - {data15, sizeof(data15), mimeTextPlain}, - {data16, sizeof(data16), mimeImagePjpeg}, - {data17, sizeof(data17), mimeAppOctetStream}, - {data18, sizeof(data18), mimeTextHtml}, - {data19, sizeof(data19), mimeImageGif}, - {data20, sizeof(data20), mimeImageGif}, - {data21, sizeof(data21), mimeTextPlain}, - {data22, sizeof(data22), mimeImageGif}, - {data23, sizeof(data23), mimeTextPlain}, - {data24, sizeof(data24), mimeImageGif}, - {data25, sizeof(data25), mimeImageGif}, - {data26, sizeof(data26), mimeTextHtml, mimeImageGif /* IE8 */}, - {data27, sizeof(data27), mimeTextPlain}, - {data28, sizeof(data28), mimeImageBmp}, - {data29, sizeof(data29), mimeImageBmp}, - {data30, sizeof(data30), mimeAppOctetStream}, - {data31, sizeof(data31), mimeTextHtml, mimeImageBmp /* IE8 */}, - {data32, sizeof(data32), mimeAppOctetStream}, - {data33, sizeof(data33), mimeAppOctetStream}, - {data34, sizeof(data34), mimeImageXPng}, - {data35, sizeof(data35), mimeImageXPng}, - {data36, sizeof(data36), mimeAppOctetStream}, - {data37, sizeof(data37), mimeTextHtml, mimeImageXPng /* IE8 */}, - {data38, sizeof(data38), mimeAppOctetStream}, - {data39, sizeof(data39), mimeImageTiff}, - {data40, sizeof(data40), mimeTextHtml, mimeImageTiff /* IE8 */}, - {data41, sizeof(data41), mimeImageTiff}, - {data42, sizeof(data42), mimeTextPlain}, - {data43, sizeof(data43), mimeAppOctetStream}, - {data44, sizeof(data44), mimeVideoAvi}, - {data45, sizeof(data45), mimeTextPlain}, - {data46, sizeof(data46), mimeTextPlain}, - {data47, sizeof(data47), mimeTextPlain}, - {data48, sizeof(data48), mimeTextHtml, mimeVideoAvi /* IE8 */}, - {data49, sizeof(data49), mimeVideoAvi}, - {data50, sizeof(data50), mimeVideoMpeg}, - {data51, sizeof(data51), mimeVideoMpeg}, - {data52, sizeof(data52), mimeAppOctetStream}, - {data53, sizeof(data53), mimeAppOctetStream}, - {data54, sizeof(data54), mimeTextHtml, mimeVideoMpeg /* IE8 */}, - {data55, sizeof(data55), mimeAppXGzip}, - {data56, sizeof(data56), mimeTextPlain}, - {data57, sizeof(data57), mimeTextHtml, mimeAppXGzip /* IE8 */}, - {data58, sizeof(data58), mimeAppOctetStream}, - {data59, sizeof(data59), mimeAppXZip}, - {data60, sizeof(data60), mimeTextPlain}, - {data61, sizeof(data61), mimeTextHtml, mimeAppXZip /* IE8 */}, - {data62, sizeof(data62), mimeAppJava}, - {data63, sizeof(data63), mimeTextPlain}, - {data64, sizeof(data64), mimeTextHtml, mimeAppJava /* IE8 */}, - {data65, sizeof(data65), mimeAppPdf}, - {data66, sizeof(data66), mimeTextPlain}, - {data67, sizeof(data67), mimeTextHtml, mimeAppPdf /* IE8 */}, - {data68, sizeof(data68), mimeAppXMSDownload}, - {data69, sizeof(data69), mimeTextPlain}, - {data70, sizeof(data70), mimeTextHtml, mimeAppXMSDownload /* IE8 */}, - {data71, sizeof(data71), mimeTextRichtext}, - {data72, sizeof(data72), mimeTextPlain}, - {data73, sizeof(data73), mimeTextPlain}, - {data74, sizeof(data74), mimeTextHtml, mimeTextRichtext /* IE8 */}, - {data75, sizeof(data75), mimeAudioWav}, - {data76, sizeof(data76), mimeTextPlain}, - {data77, sizeof(data77), mimeTextPlain}, - {data78, sizeof(data78), mimeTextHtml, mimeTextPlain /* IE8 */}, - {data79, sizeof(data79), mimeAppPostscript}, - {data80, sizeof(data80), mimeTextPlain}, - {data81, sizeof(data81), mimeTextHtml, mimeAppPostscript /* IE8 */}, - {data82, sizeof(data82), mimeAudioBasic}, - {data83, sizeof(data83), mimeTextPlain}, - {data84, sizeof(data84), mimeTextHtml, mimeAudioBasic /* IE8 */}, - {data85, sizeof(data85), mimeTextPlain} + {data1, sizeof(data1), mimeTextPlain, mimeTextPlain}, + {data2, sizeof(data2), mimeAppOctetStream, mimeImagePjpeg}, + {data3, sizeof(data3), mimeAppOctetStream, mimeImagePjpeg}, + {data4, sizeof(data4), mimeAppOctetStream, mimeImagePjpeg}, + {data5, sizeof(data5), mimeTextPlain, mimeTextPlain}, + {data6, sizeof(data6), mimeTextPlain, mimeTextPlain}, + {data7, sizeof(data7), mimeTextHtml, mimeTextPlain}, + {data8, sizeof(data8), mimeTextHtml, mimeTextPlain}, + {data9, sizeof(data9), mimeTextHtml, mimeImagePjpeg}, + {data10, sizeof(data10), mimeTextHtml, mimeTextPlain}, + {data11, sizeof(data11), mimeTextHtml, mimeTextPlain}, + {data12, sizeof(data12), mimeTextHtml, mimeTextPlain}, + {data13, sizeof(data13), mimeTextPlain, mimeTextPlain}, + {data14, sizeof(data14), mimeTextPlain, mimeTextPlain}, + {data15, sizeof(data15), mimeTextPlain, mimeTextPlain}, + {data16, sizeof(data16), mimeImagePjpeg, mimeImagePjpeg}, + {data17, sizeof(data17), mimeAppOctetStream, mimeImagePjpeg}, + {data18, sizeof(data18), mimeTextHtml, mimeImagePjpeg}, + {data19, sizeof(data19), mimeImageGif, mimeImageGif}, + {data20, sizeof(data20), mimeImageGif, mimeImageGif}, + {data21, sizeof(data21), mimeTextPlain, mimeTextPlain}, + {data22, sizeof(data22), mimeImageGif, mimeImageGif}, + {data23, sizeof(data23), mimeTextPlain, mimeTextPlain}, + {data24, sizeof(data24), mimeImageGif, mimeImageGif}, + {data25, sizeof(data25), mimeImageGif, mimeImageGif}, + {data26, sizeof(data26), mimeTextHtml, mimeImageGif}, + {data27, sizeof(data27), mimeTextPlain, mimeTextPlain}, + {data28, sizeof(data28), mimeImageBmp, mimeImageBmp}, + {data29, sizeof(data29), mimeImageBmp, mimeImageBmp}, + {data30, sizeof(data30), mimeAppOctetStream, mimeImagePjpeg}, + {data31, sizeof(data31), mimeTextHtml, mimeImageBmp}, + {data32, sizeof(data32), mimeAppOctetStream, mimeImagePjpeg}, + {data33, sizeof(data33), mimeAppOctetStream, mimeImagePjpeg}, + {data34, sizeof(data34), mimeImageXPng, mimeImageXPng}, + {data35, sizeof(data35), mimeImageXPng, mimeImageXPng}, + {data36, sizeof(data36), mimeAppOctetStream, mimeImagePjpeg}, + {data37, sizeof(data37), mimeTextHtml, mimeImageXPng}, + {data38, sizeof(data38), mimeAppOctetStream, mimeImagePjpeg}, + {data39, sizeof(data39), mimeImageTiff, mimeImageTiff}, + {data40, sizeof(data40), mimeTextHtml, mimeImageTiff}, + {data41, sizeof(data41), mimeTextPlain, mimeTextPlain, mimeImageTiff}, + {data42, sizeof(data42), mimeTextPlain, mimeTextPlain}, + {data43, sizeof(data43), mimeAppOctetStream, mimeImagePjpeg}, + {data44, sizeof(data44), mimeVideoAvi, mimeVideoAvi}, + {data45, sizeof(data45), mimeTextPlain, mimeTextPlain}, + {data46, sizeof(data46), mimeTextPlain, mimeTextPlain}, + {data47, sizeof(data47), mimeTextPlain, mimeTextPlain}, + {data48, sizeof(data48), mimeTextHtml, mimeVideoAvi}, + {data49, sizeof(data49), mimeVideoAvi, mimeVideoAvi}, + {data50, sizeof(data50), mimeVideoMpeg, mimeVideoMpeg}, + {data51, sizeof(data51), mimeVideoMpeg, mimeVideoMpeg}, + {data52, sizeof(data52), mimeAppOctetStream, mimeImagePjpeg}, + {data53, sizeof(data53), mimeAppOctetStream, mimeImagePjpeg}, + {data54, sizeof(data54), mimeTextHtml, mimeVideoMpeg}, + {data55, sizeof(data55), mimeAppXGzip, mimeAppXGzip}, + {data56, sizeof(data56), mimeTextPlain, mimeTextPlain}, + {data57, sizeof(data57), mimeTextHtml, mimeAppXGzip}, + {data58, sizeof(data58), mimeAppOctetStream, mimeImagePjpeg}, + {data59, sizeof(data59), mimeAppXZip, mimeAppXZip}, + {data60, sizeof(data60), mimeTextPlain, mimeTextPlain}, + {data61, sizeof(data61), mimeTextHtml, mimeAppXZip}, + {data62, sizeof(data62), mimeAppJava, mimeAppJava}, + {data63, sizeof(data63), mimeTextPlain, mimeTextPlain}, + {data64, sizeof(data64), mimeTextHtml, mimeAppJava}, + {data65, sizeof(data65), mimeAppPdf, mimeAppPdf}, + {data66, sizeof(data66), mimeTextPlain, mimeTextPlain}, + {data67, sizeof(data67), mimeTextHtml, mimeAppPdf}, + {data68, sizeof(data68), mimeAppXMSDownload, mimeAppXMSDownload}, + {data69, sizeof(data69), mimeTextPlain, mimeTextPlain}, + {data70, sizeof(data70), mimeTextHtml, mimeAppXMSDownload}, + {data71, sizeof(data71), mimeTextRichtext, mimeTextRichtext}, + {data72, sizeof(data72), mimeTextPlain, mimeTextPlain}, + {data73, sizeof(data73), mimeTextPlain, mimeTextPlain}, + {data74, sizeof(data74), mimeTextHtml, mimeTextRichtext}, + {data75, sizeof(data75), mimeAudioWav, mimeAudioWav}, + {data76, sizeof(data76), mimeTextPlain, mimeTextPlain}, + {data77, sizeof(data77), mimeTextPlain, mimeTextPlain}, + {data78, sizeof(data78), mimeTextHtml, mimeTextPlain}, + {data79, sizeof(data79), mimeAppPostscript, mimeAppPostscript}, + {data80, sizeof(data80), mimeTextPlain, mimeTextPlain}, + {data81, sizeof(data81), mimeTextHtml, mimeAppPostscript}, + {data82, sizeof(data82), mimeAudioBasic, mimeAudioBasic}, + {data83, sizeof(data83), mimeTextPlain, mimeTextPlain}, + {data84, sizeof(data84), mimeTextHtml, mimeAudioBasic}, + {data85, sizeof(data85), mimeTextPlain, mimeTextPlain}, + {data86, sizeof(data86), mimeImageTiff, mimeImageTiff, mimeTextPlain}, + {data87, sizeof(data87), mimeTextPlain, mimeTextPlain}, + {data88, sizeof(data88), mimeTextHtml, mimeTextPlain}, + {data89, sizeof(data89), mimeTextHtml, mimeTextPlain}, + {data90, sizeof(data90), mimeTextHtml, mimeTextPlain}, + {data91, sizeof(data91), mimeTextXml, mimeTextPlain}, + {data92, sizeof(data92), mimeTextXml, mimeTextPlain}, + {data93, sizeof(data93), mimeTextXml, mimeTextPlain}, + {data94, sizeof(data94), mimeTextHtml, mimeTextPlain}, + {data95, sizeof(data95), mimeTextXml, mimeTextRichtext}, + {data96, sizeof(data96), mimeTextPlain, mimeTextPlain} }; static void test_FindMimeFromData(void) { HRESULT hres; LPWSTR mime; + BYTE b; int i; for(i=0; i -#include +//#include #include -#include "windef.h" -#include "winbase.h" -#include "ole2.h" -#include "urlmon.h" -#include "wininet.h" +//#include "windef.h" +//#include "winbase.h" +#include +#include +//#include "urlmon.h" +#include static HRESULT (WINAPI *pCoInternetGetSession)(DWORD, IInternetSession **, DWORD); static HRESULT (WINAPI *pReleaseBindInfo)(BINDINFO*); @@ -112,7 +117,6 @@ DEFINE_EXPECT(UnlockRequest); DEFINE_EXPECT(Abort); DEFINE_EXPECT(MimeFilter_CreateInstance); DEFINE_EXPECT(MimeFilter_Start); -DEFINE_EXPECT(MimeFilter_ReportProgress); DEFINE_EXPECT(MimeFilter_ReportData); DEFINE_EXPECT(MimeFilter_ReportResult); DEFINE_EXPECT(MimeFilter_Terminate); @@ -134,7 +138,8 @@ static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0}; static const WCHAR hostW[] = {'w','w','w','.','w','i','n','e','h','q','.','o','r','g',0}; static const WCHAR winehq_ipW[] = {'2','0','9','.','4','6','.','2','5','.','1','3','4',0}; static const WCHAR emptyW[] = {0}; -static const WCHAR gzipW[] = {'g','z','i','p',0}; +static const WCHAR pjpegW[] = {'i','m','a','g','e','/','p','j','p','e','g',0}; +static const WCHAR gifW[] = {'i','m','a','g','e','/','g','i','f',0}; static HRESULT expect_hrResult; static LPCWSTR file_name, http_url, expect_wsz; @@ -149,9 +154,10 @@ static void *expect_pv; static HANDLE event_complete, event_complete2, event_continue, event_continue_done; static BOOL binding_test; static PROTOCOLDATA protocoldata, *pdata, continue_protdata; -static DWORD prot_read, pi, filter_state, http_post_test, thread_id; +static DWORD prot_read, filter_state, http_post_test, thread_id; static BOOL security_problem, test_async_req, impl_protex; static BOOL async_read_pending, mimefilter_test, direct_read, wait_for_switch, emulate_prot, short_read, test_abort; +static BOOL empty_file, no_mime, bind_from_cache; enum { STATE_CONNECTING, @@ -200,7 +206,7 @@ static const char *debugstr_guid(REFIID riid) { static char buf[50]; - sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", + sprintf(buf, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", riid->Data1, riid->Data2, riid->Data3, riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7]); @@ -215,6 +221,13 @@ static int strcmp_wa(LPCWSTR strw, const char *stra) return lstrcmpA(stra, buf); } +static const char *w2a(LPCWSTR str) +{ + static char buf[INTERNET_MAX_URL_LENGTH]; + WideCharToMultiByte(CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL); + return buf; +} + static HRESULT WINAPI HttpSecurity_QueryInterface(IHttpSecurity *iface, REFIID riid, void **ppv) { if(IsEqualGUID(&IID_IUnknown, riid) @@ -567,8 +580,6 @@ static void call_continue(PROTOCOLDATA *protocol_data) HRESULT hres; if(state == STATE_CONNECTING) { - if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) - CLEAR_CALLED(ReportProgress_COOKIE_SENT); if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST || tested_protocol == FTP_TEST) { if (http_is_first){ CLEAR_CALLED(ReportProgress_FINDINGRESOURCE); @@ -593,8 +604,9 @@ static void call_continue(PROTOCOLDATA *protocol_data) case STATE_STARTDOWNLOADING: if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) { SET_EXPECT(OnResponse); - if(tested_protocol == HTTPS_TEST || test_redirect || test_abort) + if(tested_protocol == HTTPS_TEST || test_redirect || test_abort || empty_file) SET_EXPECT(ReportProgress_ACCEPTRANGES); + SET_EXPECT(ReportProgress_ENCODING); SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE); if(bindf & BINDF_NEEDFILE) SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE); @@ -624,10 +636,11 @@ static void call_continue(PROTOCOLDATA *protocol_data) state = STATE_DOWNLOADING; if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) { CHECK_CALLED(OnResponse); - if(tested_protocol == HTTPS_TEST) + if(tested_protocol == HTTPS_TEST || empty_file) CHECK_CALLED(ReportProgress_ACCEPTRANGES); - else if(test_redirect) + else if(test_redirect || test_abort) CLEAR_CALLED(ReportProgress_ACCEPTRANGES); + CLEAR_CALLED(ReportProgress_ENCODING); CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE); if(bindf & BINDF_NEEDFILE) CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE); @@ -667,12 +680,12 @@ static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOL if(binding_test) { SetEvent(event_complete); - WaitForSingleObject(event_complete2, INFINITE); + ok( WaitForSingleObject(event_complete2, 90000) == WAIT_OBJECT_0, "wait timed out\n" ); return S_OK; }if(direct_read) { continue_protdata = *pProtocolData; SetEvent(event_continue); - WaitForSingleObject(event_continue_done, INFINITE); + ok( WaitForSingleObject(event_continue_done, 90000) == WAIT_OBJECT_0, "wait timed out\n" ); }else { call_continue(pProtocolData); SetEvent(event_complete); @@ -681,6 +694,63 @@ static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOL return S_OK; } +static const char *status_names[] = +{ + "0", + "FINDINGRESOURCE", + "CONNECTING", + "REDIRECTING", + "BEGINDOWNLOADDATA", + "DOWNLOADINGDATA", + "ENDDOWNLOADDATA", + "BEGINDOWNLOADCOMPONENTS", + "INSTALLINGCOMPONENTS", + "ENDDOWNLOADCOMPONENTS", + "USINGCACHEDCOPY", + "SENDINGREQUEST", + "CLASSIDAVAILABLE", + "MIMETYPEAVAILABLE", + "CACHEFILENAMEAVAILABLE", + "BEGINSYNCOPERATION", + "ENDSYNCOPERATION", + "BEGINUPLOADDATA", + "UPLOADINGDATA", + "ENDUPLOADINGDATA", + "PROTOCOLCLASSID", + "ENCODING", + "VERIFIEDMIMETYPEAVAILABLE", + "CLASSINSTALLLOCATION", + "DECODING", + "LOADINGMIMEHANDLER", + "CONTENTDISPOSITIONATTACH", + "FILTERREPORTMIMETYPE", + "CLSIDCANINSTANTIATE", + "IUNKNOWNAVAILABLE", + "DIRECTBIND", + "RAWMIMETYPE", + "PROXYDETECTING", + "ACCEPTRANGES", + "COOKIE_SENT", + "COMPACT_POLICY_RECEIVED", + "COOKIE_SUPPRESSED", + "COOKIE_STATE_UNKNOWN", + "COOKIE_STATE_ACCEPT", + "COOKIE_STATE_REJECT", + "COOKIE_STATE_PROMPT", + "COOKIE_STATE_LEASH", + "COOKIE_STATE_DOWNGRADE", + "POLICY_HREF", + "P3P_HEADER", + "SESSION_COOKIE_RECEIVED", + "PERSISTENT_COOKIE_RECEIVED", + "SESSION_COOKIES_ALLOWED", + "CACHECONTROL", + "CONTENTDISPOSITIONFILENAME", + "MIMETEXTPLAINMISMATCH", + "PUBLISHERAVAILABLE", + "DISPLAYNAMEAVAILABLE" +}; + static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode, LPCWSTR szStatusText) { @@ -688,9 +758,14 @@ static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, '0','0','0','0','-','0','0','0','0','-','0','0','0','0','0','0','0','0','0','0','0','0','}',0}; static const WCHAR text_plain[] = {'t','e','x','t','/','p','l','a','i','n',0}; + if (ulStatusCode < sizeof(status_names)/sizeof(status_names[0])) + trace( "progress: %s %s\n", status_names[ulStatusCode], wine_dbgstr_w(szStatusText) ); + else + trace( "progress: %u %s\n", ulStatusCode, wine_dbgstr_w(szStatusText) ); + switch(ulStatusCode) { case BINDSTATUS_MIMETYPEAVAILABLE: - CHECK_EXPECT(ReportProgress_MIMETYPEAVAILABLE); + CHECK_EXPECT2(ReportProgress_MIMETYPEAVAILABLE); if(tested_protocol != FILE_TEST && tested_protocol != ITS_TEST && !mimefilter_test && (pi & PI_MIMEVERIFICATION)) { if(!short_read || !direct_read) CHECK_CALLED(Read); /* set in Continue */ @@ -700,11 +775,18 @@ static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, ok(szStatusText != NULL, "szStatusText == NULL\n"); if(szStatusText) { if(tested_protocol == BIND_TEST) - ok(szStatusText == expect_wsz, "unexpected szStatusText\n"); + ok(!lstrcmpW(szStatusText, expect_wsz), "unexpected szStatusText %s\n", wine_dbgstr_w(szStatusText)); else if (http_post_test) ok(lstrlenW(text_plain) <= lstrlenW(szStatusText) && !memcmp(szStatusText, text_plain, lstrlenW(text_plain)*sizeof(WCHAR)), "szStatusText != text/plain\n"); + else if(empty_file) + ok(!strcmp_wa(szStatusText, "application/javascript"), "szStatusText = %s\n", wine_dbgstr_w(szStatusText)); + else if((pi & PI_MIMEVERIFICATION) && emulate_prot && !mimefilter_test + && tested_protocol==HTTP_TEST && !short_read) + ok(lstrlenW(gifW) <= lstrlenW(szStatusText) && + !memcmp(szStatusText, gifW, lstrlenW(gifW)*sizeof(WCHAR)), + "szStatusText != image/gif\n"); else if(!mimefilter_test) ok(lstrlenW(text_htmlW) <= lstrlenW(szStatusText) && !memcmp(szStatusText, text_htmlW, lstrlenW(text_htmlW)*sizeof(WCHAR)), @@ -755,7 +837,7 @@ static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, CHECK_EXPECT(ReportProgress_VERIFIEDMIMETYPEAVAILABLE); ok(szStatusText != NULL, "szStatusText == NULL\n"); if(szStatusText) - ok(!lstrcmpW(szStatusText, text_htmlW), "szStatusText != text/html\n"); + ok(!strcmp_wa(szStatusText, "text/html"), "szStatusText != text/html\n"); break; case BINDSTATUS_PROTOCOLCLASSID: CHECK_EXPECT(ReportProgress_PROTOCOLCLASSID); @@ -763,7 +845,7 @@ static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, ok(!lstrcmpW(szStatusText, null_guid), "unexpected classid %s\n", wine_dbgstr_w(szStatusText)); break; case BINDSTATUS_COOKIE_SENT: - CHECK_EXPECT(ReportProgress_COOKIE_SENT); + CHECK_EXPECT2(ReportProgress_COOKIE_SENT); ok(szStatusText == NULL, "szStatusText != NULL\n"); break; case BINDSTATUS_REDIRECTING: @@ -782,8 +864,9 @@ static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText)); break; case BINDSTATUS_PROXYDETECTING: - CHECK_EXPECT(ReportProgress_PROXYDETECTING); - SET_EXPECT(ReportProgress_CONNECTING); + if(!called_ReportProgress_PROXYDETECTING) + SET_EXPECT(ReportProgress_CONNECTING); + CHECK_EXPECT2(ReportProgress_PROXYDETECTING); ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText)); break; case BINDSTATUS_LOADINGMIMEHANDLER: @@ -792,7 +875,7 @@ static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, break; case BINDSTATUS_DECODING: CHECK_EXPECT(ReportProgress_DECODING); - ok(!lstrcmpW(szStatusText, gzipW), "szStatusText = %s\n", wine_dbgstr_w(szStatusText)); + ok(!lstrcmpW(szStatusText, pjpegW), "szStatusText = %s\n", wine_dbgstr_w(szStatusText)); break; default: ok(0, "Unexpected status %d\n", ulStatusCode); @@ -822,6 +905,12 @@ static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWOR "grcfBSCF = %08x\n", grfBSCF); else ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE), "grcfBSCF = %08x\n", grfBSCF); + }else if(bind_from_cache) { + CHECK_EXPECT(ReportData); + + ok(grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE), "grcfBSCF = %08x\n", grfBSCF); + ok(ulProgress == 1000, "ulProgress = %u\n", ulProgress); + ok(!ulProgressMax, "ulProgressMax = %u\n", ulProgressMax); }else if(direct_read) { BYTE buf[14096]; ULONG read; @@ -870,7 +959,6 @@ static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWOR if(!emulate_prot) CHECK_CALLED(ReportData2); CHECK_CALLED(ReportResult); - ok(hres == S_OK, "Read failed: %08x\n", hres); reported_all_data = TRUE; }else { if(!emulate_prot) @@ -896,14 +984,25 @@ static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWOR } }else if(!binding_test && (tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST || tested_protocol == FTP_TEST)) { - if(!(grfBSCF & BSCF_LASTDATANOTIFICATION) || (grfBSCF & BSCF_DATAFULLYAVAILABLE)) + if(empty_file) + CHECK_EXPECT2(ReportData); + else if(!(grfBSCF & BSCF_LASTDATANOTIFICATION) || (grfBSCF & BSCF_DATAFULLYAVAILABLE)) CHECK_EXPECT(ReportData); else if (http_post_test) ok(ulProgress == 13, "Read %u bytes instead of 13\n", ulProgress); - ok(ulProgress, "ulProgress == 0\n"); + if(empty_file) { + ok(!ulProgress, "ulProgress = %d\n", ulProgress); + ok(!ulProgressMax, "ulProgressMax = %d\n", ulProgressMax); + }else { + ok(ulProgress, "ulProgress == 0\n"); + } - if(first_data_notif) { + if(empty_file) { + ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION), + "grcfBSCF = %08x\n", grfBSCF); + first_data_notif = FALSE; + }else if(first_data_notif) { ok(grfBSCF == BSCF_FIRSTDATANOTIFICATION || grfBSCF == (BSCF_LASTDATANOTIFICATION|BSCF_DATAFULLYAVAILABLE), "grcfBSCF = %08x\n", grfBSCF); @@ -1028,7 +1127,20 @@ static HRESULT WINAPI MimeProtocolSink_Switch(IInternetProtocolSink *iface, PROT static HRESULT WINAPI MimeProtocolSink_ReportProgress(IInternetProtocolSink *iface, ULONG ulStatusCode, LPCWSTR szStatusText) { - CHECK_EXPECT(MimeFilter_ReportProgress); + switch(ulStatusCode) { + case BINDSTATUS_LOADINGMIMEHANDLER: + /* + * IE9 for some reason (bug?) calls this on mime handler's protocol sink instead of the + * main protocol sink. We check ReportProgress_LOADINGMIMEHANDLER both here and in + * ProtocolSink_ReportProgress to workaround it. + */ + CHECK_EXPECT(ReportProgress_LOADINGMIMEHANDLER); + ok(!szStatusText, "szStatusText = %s\n", wine_dbgstr_w(szStatusText)); + break; + default: + ok(0, "Unexpected status code %d\n", ulStatusCode); + } + return S_OK; } @@ -1038,10 +1150,11 @@ static HRESULT WINAPI MimeProtocolSink_ReportData(IInternetProtocolSink *iface, DWORD read = 0; BYTE buf[8192]; HRESULT hres; + BOOL report_mime = FALSE; CHECK_EXPECT(MimeFilter_ReportData); - if(!filter_state) { + if(!filter_state && !no_mime) { SET_EXPECT(Read); hres = IInternetProtocol_Read(filtered_protocol, buf, sizeof(buf), &read); if(tested_protocol == HTTP_TEST) @@ -1055,15 +1168,34 @@ static HRESULT WINAPI MimeProtocolSink_ReportData(IInternetProtocolSink *iface, ok(hres == S_OK, "ReportProgress failed: %08x\n", hres); CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE); + SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE); + hres = IInternetProtocolSink_ReportProgress(filtered_sink, BINDSTATUS_MIMETYPEAVAILABLE, text_htmlW); + ok(hres == S_OK, "ReportProgress failed: %08x\n", hres); + CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE); + /* FIXME: test BINDSTATUS_CACHEFILENAMEAVAILABLE */ } - if(!read_report_data) + if(no_mime && prot_read<200) { + SET_EXPECT(Read); + }else if(no_mime && prot_read<300) { + report_mime = TRUE; + SET_EXPECT(Read); + SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE); SET_EXPECT(ReportData); + }else if(!read_report_data) { + SET_EXPECT(ReportData); + } hres = IInternetProtocolSink_ReportData(filtered_sink, grfBSCF, ulProgress, ulProgressMax); ok(hres == S_OK, "ReportData failed: %08x\n", hres); - if(!read_report_data) + if(no_mime && prot_read<=200) { + CHECK_CALLED(Read); + }else if(report_mime) { + CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE); CHECK_CALLED(ReportData); + }else if(!read_report_data) { + CHECK_CALLED(ReportData); + } if(!filter_state) filter_state = 1; @@ -1352,6 +1484,8 @@ static HRESULT WINAPI Protocol_Seek(IInternetProtocolEx *iface, static HRESULT WINAPI ProtocolEmul_QueryInterface(IInternetProtocolEx *iface, REFIID riid, void **ppv) { + static const IID unknown_iid = {0x7daf9908,0x8415,0x4005,{0x95,0xae, 0xbd,0x27,0xf6,0xe3,0xdc,0x00}}; + if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IInternetProtocol, riid)) { *ppv = iface; return S_OK; @@ -1383,7 +1517,8 @@ static HRESULT WINAPI ProtocolEmul_QueryInterface(IInternetProtocolEx *iface, RE return E_NOINTERFACE; } - ok(0, "unexpected riid %s\n", debugstr_guid(riid)); + if(!IsEqualGUID(riid, &unknown_iid)) /* IE10 */ + ok(0, "unexpected riid %s\n", debugstr_guid(riid)); *ppv = NULL; return E_NOINTERFACE; } @@ -1583,14 +1718,14 @@ static void protocol_start(IInternetProtocolSink *pOIProtSink, IInternetBindInfo } SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE); hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE, - mimefilter_test ? gzipW : (expect_wsz = text_htmlW)); + mimefilter_test ? pjpegW : (expect_wsz = text_htmlW)); ok(hres == S_OK, "ReportProgress(BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE) failed: %08x\n", hres); if(mimefilter_test) { CHECK_CALLED(MimeFilter_CreateInstance); CHECK_CALLED(MimeFilter_Start); CHECK_CALLED(ReportProgress_LOADINGMIMEHANDLER); - todo_wine CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE); + CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE); }else { CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE); } @@ -1698,7 +1833,7 @@ static HRESULT WINAPI ProtocolEmul_Continue(IInternetProtocolEx *iface, SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE); } hres = IInternetProtocolSink_ReportProgress(binding_sink, - BINDSTATUS_MIMETYPEAVAILABLE, mimefilter_test ? gzipW : text_htmlW); + BINDSTATUS_MIMETYPEAVAILABLE, mimefilter_test ? pjpegW : text_htmlW); if(mimefilter_test) { CHECK_CALLED(MimeFilter_CreateInstance); CHECK_CALLED(MimeFilter_Start); @@ -1719,14 +1854,15 @@ static HRESULT WINAPI ProtocolEmul_Continue(IInternetProtocolEx *iface, } pr = prot_read; - if(mimefilter_test) { + if(mimefilter_test) SET_EXPECT(MimeFilter_ReportData); - }else if(pi & PI_MIMEVERIFICATION) { + if((!mimefilter_test || no_mime) && (pi & PI_MIMEVERIFICATION)) { if(pr < 200) SET_EXPECT(Read); /* checked in ReportData for short_read */ if(pr == 200) { if(!mimefilter_test) SET_EXPECT(Read); /* checked in BINDSTATUS_MIMETYPEAVAILABLE or ReportData */ + SET_EXPECT(GetBindInfo); SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE); } if(pr >= 200) @@ -1744,6 +1880,7 @@ static HRESULT WINAPI ProtocolEmul_Continue(IInternetProtocolEx *iface, if(!short_read && pr < 200) CHECK_CALLED(Read); if(pr == 200) { + CLEAR_CALLED(GetBindInfo); /* IE9 */ CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE); } }else { @@ -1801,6 +1938,7 @@ static HRESULT WINAPI ProtocolEmul_Read(IInternetProtocolEx *iface, void *pv, prot_state = 4; if(short_read) { SET_EXPECT(Read2); /* checked in BINDSTATUS_MIMETYPEAVAILABLE */ + SET_EXPECT(GetBindInfo); SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE); } if(mimefilter_test) @@ -1812,8 +1950,10 @@ static HRESULT WINAPI ProtocolEmul_Read(IInternetProtocolEx *iface, void *pv, BSCF_LASTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION, 0, 0); read_report_data--; ok(hres == S_OK, "ReportData failed: %08x\n", hres); - if(short_read) + if(short_read) { + CLEAR_CALLED(GetBindInfo); /* IE9 */ CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE); + } if(mimefilter_test) CHECK_CALLED(MimeFilter_ReportData); else if(direct_read) @@ -1830,8 +1970,12 @@ static HRESULT WINAPI ProtocolEmul_Read(IInternetProtocolEx *iface, void *pv, else CHECK_CALLED(ReportResult); - memset(pv, 'x', 100); - prot_read += *pcbRead = 100; + if(cb > 100) + cb = 100; + memset(pv, 'x', cb); + if(cb>6) + memcpy(pv, "gif87a", 6); + prot_read += *pcbRead = cb; return S_OK; }if(prot_state == 4) { *pcbRead = 0; @@ -1843,8 +1987,12 @@ static HRESULT WINAPI ProtocolEmul_Read(IInternetProtocolEx *iface, void *pv, return tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST ? E_PENDING : S_FALSE; } - memset(pv, 'x', 100); - prot_read += *pcbRead = 100; + if(cb > 100) + cb = 100; + memset(pv, 'x', cb); + if(cb>6) + memcpy(pv, "gif87a", 6); + prot_read += *pcbRead = cb; return S_OK; } @@ -1920,7 +2068,7 @@ static HRESULT WINAPI MimeProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szU CHECK_EXPECT(MimeFilter_Start); - ok(!lstrcmpW(szUrl, gzipW), "wrong url %s\n", wine_dbgstr_w(szUrl)); + ok(!lstrcmpW(szUrl, pjpegW), "wrong url %s\n", wine_dbgstr_w(szUrl)); ok(grfPI == (PI_FILTER_MODE|PI_FORCE_ASYNC), "grfPI=%x, expected PI_FILTER_MODE|PI_FORCE_ASYNC\n", grfPI); ok(dwReserved, "dwReserved == 0\n"); ok(pOIProtSink != NULL, "pOIProtSink == NULL\n"); @@ -1964,7 +2112,7 @@ static HRESULT WINAPI MimeProtocol_Start(IInternetProtocolEx *iface, LPCWSTR szU filtered_sink = pOIProtSink; SET_EXPECT(ReportProgress_DECODING); - hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DECODING, gzipW); + hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_DECODING, pjpegW); ok(hres == S_OK, "ReportProgress(BINDSTATUS_DECODING) failed: %08x\n", hres); CHECK_CALLED(ReportProgress_DECODING); @@ -2169,22 +2317,27 @@ static IClassFactory mimefilter_cf = { &MimeFilterCFVtbl }; #define TEST_ASYNCREQ 0x0200 #define TEST_USEIURI 0x0400 #define TEST_IMPLPROTEX 0x0800 +#define TEST_EMPTY 0x1000 +#define TEST_NOMIME 0x2000 +#define TEST_FROMCACHE 0x4000 static void register_filter(BOOL do_register) { IInternetSession *session; HRESULT hres; - static const WCHAR gzipW[] = {'g','z','i','p',0}; - hres = pCoInternetGetSession(0, &session, 0); ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres); if(do_register) { - hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, gzipW); + hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, pjpegW); + ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres); + hres = IInternetSession_RegisterMimeFilter(session, &mimefilter_cf, &IID_IInternetProtocol, gifW); ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres); }else { - hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, gzipW); + hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, pjpegW); + ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres); + hres = IInternetSession_UnregisterMimeFilter(session, &mimefilter_cf, gifW); ok(hres == S_OK, "RegisterMimeFilter failed: %08x\n", hres); } @@ -2200,6 +2353,7 @@ static void init_test(int prot, DWORD flags) prot_state = 0; async_read_pending = TRUE; mimefilter_test = (flags & TEST_FILTER) != 0; + no_mime = (flags & TEST_NOMIME) != 0; filter_state = 0; post_stream_read = 0; ResetEvent(event_complete); @@ -2220,6 +2374,8 @@ static void init_test(int prot, DWORD flags) test_redirect = (flags & TEST_REDIRECT) != 0; test_abort = (flags & TEST_ABORT) != 0; impl_protex = (flags & TEST_IMPLPROTEX) != 0; + empty_file = (flags & TEST_EMPTY) != 0; + bind_from_cache = (flags & TEST_FROMCACHE) != 0; register_filter(mimefilter_test); } @@ -2304,7 +2460,7 @@ static BOOL file_protocol_start(IInternetProtocol *protocol, LPCWSTR url, CHECK_CALLED(GetBindInfo); if(!(bindf & BINDF_FROMURLMON)) - CHECK_CALLED(ReportProgress_DIRECTBIND); + CLEAR_CALLED(ReportProgress_DIRECTBIND); /* Not called by IE10 */ if(is_first) { CHECK_CALLED(ReportProgress_SENDINGREQUEST); CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE); @@ -2431,6 +2587,24 @@ static void test_file_protocol_url(LPCWSTR url) IUri_Release(uri); IInternetProtocolEx_Release(protocolex); + + hres = pCreateUri(url, 0, 0, &uri); + ok(hres == S_OK, "CreateUri failed: %08x\n", hres); + + hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocolEx, (void**)&protocolex); + ok(hres == S_OK, "Could not get IInternetProtocolEx: %08x\n", hres); + + if(file_protocol_start(NULL, NULL, protocolex, uri, TRUE)) { + hres = IInternetProtocolEx_Read(protocolex, buf, 2, &cb); + ok(hres == S_OK, "Read failed: %08x\n", hres); + hres = IInternetProtocolEx_LockRequest(protocolex, 0); + ok(hres == S_OK, "LockRequest failed: %08x\n", hres); + hres = IInternetProtocolEx_UnlockRequest(protocolex); + ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres); + } + + IUri_Release(uri); + IInternetProtocolEx_Release(protocolex); }else { win_skip("Skipping file protocol StartEx tests\n"); } @@ -2604,6 +2778,51 @@ static void test_file_protocol(void) { test_file_protocol_fail(); } +static void create_cache_entry(const WCHAR *urlw) +{ + FILETIME now, tomorrow, yesterday; + char file_path[MAX_PATH]; + BYTE content[1000]; + ULARGE_INTEGER li; + const char *url; + HANDLE file; + DWORD size; + unsigned i; + BOOL res; + + BYTE cache_headers[] = "HTTP/1.1 200 OK\r\n\r\n"; + + trace("Testing cache read...\n"); + + url = w2a(urlw); + + for(i = 0; i < sizeof(content); i++) + content[i] = '0' + (i%10); + + GetSystemTimeAsFileTime(&now); + li.u.HighPart = now.dwHighDateTime; + li.u.LowPart = now.dwLowDateTime; + li.QuadPart += (LONGLONG)10000000 * 3600 * 24; + tomorrow.dwHighDateTime = li.u.HighPart; + tomorrow.dwLowDateTime = li.u.LowPart; + li.QuadPart -= (LONGLONG)10000000 * 3600 * 24 * 2; + yesterday.dwHighDateTime = li.u.HighPart; + yesterday.dwLowDateTime = li.u.LowPart; + + res = CreateUrlCacheEntryA(url, sizeof(content), "", file_path, 0); + ok(res, "CreateUrlCacheEntryA failed: %u\n", GetLastError()); + + file = CreateFileA(file_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n"); + + WriteFile(file, content, sizeof(content), &size, NULL); + CloseHandle(file); + + res = CommitUrlCacheEntryA(url, file_path, tomorrow, yesterday, NORMAL_CACHE_ENTRY, + cache_headers, sizeof(cache_headers)-1, "", 0); + ok(res, "CommitUrlCacheEntryA failed: %u\n", GetLastError()); +} + static BOOL http_protocol_start(LPCWSTR url, BOOL use_iuri) { static BOOL got_user_agent = FALSE; @@ -2629,6 +2848,11 @@ static BOOL http_protocol_start(LPCWSTR url, BOOL use_iuri) if(http_post_test == TYMED_ISTREAM) SET_EXPECT(Stream_Seek); } + if(bind_from_cache) { + SET_EXPECT(OnResponse); + SET_EXPECT(ReportProgress_MIMETYPEAVAILABLE); + SET_EXPECT(ReportData); + } if(uri) { IInternetProtocolEx *protocolex; @@ -2666,6 +2890,11 @@ static BOOL http_protocol_start(LPCWSTR url, BOOL use_iuri) if(http_post_test == TYMED_ISTREAM) CHECK_CALLED(Stream_Seek); } + if(bind_from_cache) { + CHECK_CALLED(OnResponse); + CHECK_CALLED(ReportProgress_MIMETYPEAVAILABLE); + CHECK_CALLED(ReportData); + } return TRUE; } @@ -2725,6 +2954,9 @@ static void test_http_protocol_url(LPCWSTR url, int prot, DWORD flags, DWORD tym http_url = url; http_post_test = tymed; + if(flags & TEST_FROMCACHE) + create_cache_entry(url); + hres = CoGetClassObject(prot == HTTPS_TEST ? &CLSID_HttpSProtocol : &CLSID_HttpProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk); ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres); @@ -2774,27 +3006,43 @@ static void test_http_protocol_url(LPCWSTR url, int prot, DWORD flags, DWORD tym SET_EXPECT(Switch); } - if(!http_protocol_start(url, (flags & TEST_USEIURI) != 0)) + if(!http_protocol_start(url, (flags & TEST_USEIURI) != 0)) { + IInternetProtocol_Abort(async_protocol, E_ABORT, 0); + IInternetProtocol_Release(async_protocol); return; + } - if(!direct_read && !test_abort) + if(!direct_read && !test_abort && !bind_from_cache) SET_EXPECT(ReportResult); expect_hrResult = test_abort ? E_ABORT : S_OK; if(direct_read) { SET_EXPECT(Switch); while(wait_for_switch) { - WaitForSingleObject(event_continue, INFINITE); + ok( WaitForSingleObject(event_continue, 90000) == WAIT_OBJECT_0, "wait timed out\n" ); CHECK_CALLED(Switch); /* Set in ReportData */ call_continue(&continue_protdata); SetEvent(event_continue_done); } + }else if(bind_from_cache) { + BYTE buf[1500]; + + hres = IInternetProtocol_Read(async_protocol, buf, 100, &cb); + ok(hres == S_OK && cb == 100, "Read failed: %08x (%d bytes)\n", hres, cb); + + SET_EXPECT(ReportResult); + hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb); + ok(hres == S_OK && cb == 900, "Read failed: %08x (%d bytes)\n", hres, cb); + CHECK_CALLED(ReportResult); + + hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb); + ok(hres == S_FALSE && !cb, "Read failed: %08x (%d bytes)\n", hres, cb); }else { hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb); ok((hres == E_PENDING && cb==0) || (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb); - WaitForSingleObject(event_complete, INFINITE); + ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" ); if(bindf & BINDF_FROMURLMON) CHECK_CALLED(Switch); else @@ -2812,7 +3060,7 @@ static void test_http_protocol_url(LPCWSTR url, int prot, DWORD flags, DWORD tym hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb); ok((hres == E_PENDING && cb==0) || (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb); - WaitForSingleObject(event_complete, INFINITE); + ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" ); if(bindf & BINDF_FROMURLMON) CHECK_CALLED(Switch); else @@ -2846,6 +3094,9 @@ static void test_http_protocol_url(LPCWSTR url, int prot, DWORD flags, DWORD tym if(prot == HTTPS_TEST) CLEAR_CALLED(ReportProgress_SENDINGREQUEST); + if (prot == HTTP_TEST || prot == HTTPS_TEST) + CLEAR_CALLED(ReportProgress_COOKIE_SENT); + hres = IInternetProtocol_Abort(async_protocol, E_ABORT, 0); ok(hres == INET_E_RESULT_DISPATCHED, "Abort failed: %08x\n", hres); @@ -2859,6 +3110,13 @@ static void test_http_protocol_url(LPCWSTR url, int prot, DWORD flags, DWORD tym } IClassFactory_Release(factory); + + if(flags & TEST_FROMCACHE) { + BOOL res; + + res = DeleteUrlCacheEntryW(url); + ok(res, "DeleteUrlCacheEntryA failed: %u\n", GetLastError()); + } } static void test_http_protocol(void) @@ -2872,6 +3130,13 @@ static void test_http_protocol(void) static const WCHAR winetest_url[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/', 't','e','s','t','s','/','d','a','t','a','.','p','h','p',0}; + static const WCHAR empty_url[] = + {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/', + 't','e','s','t','s','/','e','m','p','t','y','.','j','s',0}; + static const WCHAR cache_only_url[] = + {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/', + 't','e','s','t','s','/','c','a','c','h','e','-','o','n','l','y',0}; + trace("Testing http protocol (not from urlmon)...\n"); bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA; @@ -2897,10 +3162,26 @@ static void test_http_protocol(void) test_http_protocol_url(winetest_url, HTTP_TEST, TEST_DIRECT_READ|TEST_USEIURI, TYMED_NULL); trace("Testing http protocol (redirected)...\n"); - bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON; + bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE; test_http_protocol_url(redirect_url, HTTP_TEST, TEST_REDIRECT, TYMED_NULL); + trace("Testing http protocol empty file...\n"); + bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE; + test_http_protocol_url(empty_url, HTTP_TEST, TEST_EMPTY, TYMED_NULL); + + /* This is a bit ugly. We unconditionally disable this test on Wine. This won't work until we have + * support for reading from cache via HTTP layer in wininet. Until then, Wine will fail badly, affecting + * other, unrelated, tests. Working around it is not worth the trouble, we may simply make sure those + * tests work on Windows and have them around for the future. + */ + if(broken(1)) { + trace("Testing http protocol (from cache)...\n"); + bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON; + test_http_protocol_url(cache_only_url, HTTP_TEST, TEST_FROMCACHE, TYMED_NULL); + } + trace("Testing http protocol abort...\n"); + bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE; test_http_protocol_url(winetest_url, HTTP_TEST, TEST_ABORT, TYMED_NULL); test_early_abort(&CLSID_HttpProtocol); @@ -2935,10 +3216,10 @@ static void test_ftp_protocol(void) trace("Testing ftp protocol...\n"); + init_test(FTP_TEST, 0); + bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE; state = STATE_STARTDOWNLOADING; - tested_protocol = FTP_TEST; - first_data_notif = TRUE; expect_hrResult = E_PENDING; hres = CoGetClassObject(&CLSID_FtpProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk); @@ -2979,12 +3260,16 @@ static void test_ftp_protocol(void) ok((hres == E_PENDING && cb==0) || (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb); - WaitForSingleObject(event_complete, INFINITE); + ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" ); while(1) { hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb); if(hres == E_PENDING) - WaitForSingleObject(event_complete, INFINITE); + { + DWORD ret = WaitForSingleObject(event_complete, 90000); + ok( ret == WAIT_OBJECT_0, "wait timed out\n" ); + if (ret != WAIT_OBJECT_0) break; + } else if(cb == 0) break; } @@ -3362,7 +3647,7 @@ static void test_binding(int prot, DWORD grf_pi, DWORD test_flags) if(prot == HTTP_TEST || prot == HTTPS_TEST) { while(prot_state < 4) { - WaitForSingleObject(event_complete, INFINITE); + ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" ); if(mimefilter_test && filtered_protocol) { SET_EXPECT(Continue); IInternetProtocol_Continue(filtered_protocol, pdata); @@ -3387,7 +3672,7 @@ static void test_binding(int prot, DWORD grf_pi, DWORD test_flags) } if(direct_read) CHECK_CALLED(ReportData); /* Set in ReportResult */ - WaitForSingleObject(event_complete, INFINITE); + ok( WaitForSingleObject(event_complete, 90000) == WAIT_OBJECT_0, "wait timed out\n" ); }else { if(mimefilter_test) SET_EXPECT(MimeFilter_LockRequest); @@ -3471,7 +3756,10 @@ START_TEST(protocol) test_file_protocol(); test_http_protocol(); - test_https_protocol(); + if(pCreateUri) + test_https_protocol(); + else + win_skip("Skipping https tests on too old platform\n"); test_ftp_protocol(); test_gopher_protocol(); test_mk_protocol(); @@ -3490,6 +3778,8 @@ START_TEST(protocol) test_binding(FILE_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER); trace("Testing http binding (mime verification, emulate prot, mime filter)...\n"); test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER); + trace("Testing http binding (mime verification, emulate prot, mime filter, no mime)...\n"); + test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_FILTER|TEST_NOMIME); trace("Testing http binding (mime verification, emulate prot, direct read)...\n"); test_binding(HTTP_TEST, PI_MIMEVERIFICATION, TEST_EMULATEPROT|TEST_DIRECT_READ); trace("Testing http binding (mime verification, emulate prot, abort)...\n"); diff --git a/rostests/winetests/urlmon/sec_mgr.c b/rostests/winetests/urlmon/sec_mgr.c index c64dfe40f01..c82e91e1139 100644 --- a/rostests/winetests/urlmon/sec_mgr.c +++ b/rostests/winetests/urlmon/sec_mgr.c @@ -18,6 +18,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + #define COBJMACROS #define CONST_VTABLE #define NONAMELESSUNION @@ -26,16 +30,18 @@ #define _WIN32_IE 0x0700 #include -#include -#include +//#include +//#include #include -#include "windef.h" -#include "winbase.h" -#include "ole2.h" -#include "urlmon.h" +//#include "windef.h" +//#include "winbase.h" +#include +#include +#include +//#include "urlmon.h" -#include "initguid.h" +//#include "initguid.h" #define URLZONE_CUSTOM URLZONE_USER_MIN+1 #define URLZONE_CUSTOM2 URLZONE_CUSTOM+1 @@ -70,6 +76,7 @@ DEFINE_EXPECT(ParseUrl_SECURITY_URL_input2); DEFINE_EXPECT(ParseUrl_SECURITY_URL_expected); DEFINE_EXPECT(ParseUrl_SECURITY_URL_http); DEFINE_EXPECT(ParseUrl_SECURITY_DOMAIN_expected); +DEFINE_EXPECT(ProcessUrlAction); static HRESULT (WINAPI *pCoInternetCreateSecurityManager)(IServiceProvider *, IInternetSecurityManager**, DWORD); static HRESULT (WINAPI *pCoInternetCreateZoneManager)(IServiceProvider *, IInternetZoneManager**, DWORD); @@ -77,6 +84,9 @@ static HRESULT (WINAPI *pCoInternetGetSecurityUrl)(LPCWSTR, LPWSTR*, PSUACTION, static HRESULT (WINAPI *pCoInternetGetSecurityUrlEx)(IUri*, IUri**, PSUACTION, DWORD_PTR); static HRESULT (WINAPI *pCreateUri)(LPCWSTR, DWORD, DWORD_PTR, IUri**); static HRESULT (WINAPI *pCoInternetGetSession)(DWORD, IInternetSession**, DWORD); +static HRESULT (WINAPI *pCoInternetIsFeatureEnabled)(INTERNETFEATURELIST, DWORD); +static HRESULT (WINAPI *pCoInternetIsFeatureEnabledForUrl)(INTERNETFEATURELIST, DWORD, LPCWSTR, IInternetSecurityManager*); +static HRESULT (WINAPI *pCoInternetIsFeatureZoneElevationEnabled)(LPCWSTR, LPCWSTR, IInternetSecurityManager*, DWORD); static const WCHAR url1[] = {'r','e','s',':','/','/','m','s','h','t','m','l','.','d','l','l', '/','b','l','a','n','k','.','h','t','m',0}; @@ -94,6 +104,14 @@ static const WCHAR url9[] = {'h','t','t','p',':','/','/','w','w','w','.','z','o' '.','w','i','n','e','t','e','s','t', '/','s','i','t','e','/','a','b','o','u','t',0}; static const WCHAR url10[] = {'f','i','l','e',':','/','/','s','o','m','e','%','2','0','f','i','l','e', '.','j','p','g',0}; +static const WCHAR url11[] = {'f','i','l','e',':','/','/','c',':','/','I','n','d','e','x','.','h','t','m',0}; +static const WCHAR url12[] = {'f','i','l','e',':','/','/','/','c',':','/','I','n','d','e','x','.','h','t','m',0}; +static const WCHAR url13[] = {'h','t','t','p',':','g','o','o','g','l','e','.','c','o','m',0}; +static const WCHAR url14[] = {'z','i','p',':','t','e','s','t','i','n','g','.','c','o','m','/','t','e','s','t','i','n','g',0}; +static const WCHAR url15[] = {'h','t','t','p',':','/','/','g','o','o','g','l','e','.','c','o','m','.','u','k',0}; +static const WCHAR url16[] = {'f','i','l','e',':','/','/','/','c',':',0}; +static const WCHAR url17[] = {'f','i','l','e',':','/','/','/','c',':','c','\\',0}; +static const WCHAR url18[] = {'c',':','\\','t','e','s','t','.','h','t','m',0}; static const WCHAR url4e[] = {'f','i','l','e',':','s','o','m','e',' ','f','i','l','e', '.','j','p','g',0}; @@ -108,6 +126,7 @@ static const char *szZoneMapDomainsKey = "Software\\Microsoft\\Windows\\CurrentV static const char *szInternetSettingsKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"; static const BYTE secid1[] = {'f','i','l','e',':',0,0,0,0}; +static const BYTE secid2[] = {'*',':','i','n','d','e','x','.','h','t','m',3,0,0,0}; static const BYTE secid5[] = {'h','t','t','p',':','w','w','w','.','z','o','n','e','3', '.','w','i','n','e','t','e','s','t',3,0,0,0}; static const BYTE secid6[] = {'a','b','o','u','t',':','b','l','a','n','k',3,0,0,0}; @@ -115,8 +134,12 @@ static const BYTE secid7[] = {'f','t','p',':','z','o','n','e','3', '.','w','i','n','e','t','e','s','t',3,0,0,0}; static const BYTE secid10[] = {'f','i','l','e',':','s','o','m','e','%','2','0','f','i','l','e','.','j','p','g',3,0,0,0}; +static const BYTE secid14[] = + {'z','i','p',':','t','e','s','t','i','n','g','.','c','o','m','/','t','e','s','t','i','n','g',3,0,0,0}; static const BYTE secid10_2[] = {'f','i','l','e',':','s','o','m','e',' ','f','i','l','e','.','j','p','g',3,0,0,0}; +static const BYTE secid13[] = {'h','t','t','p',':','c','o','m','.','u','k',3,0,0,0}; +static const BYTE secid13_2[] = {'h','t','t','p',':','g','o','o','g','l','e','.','c','o','m','.','u','k',3,0,0,0}; static const GUID CLSID_TestActiveX = {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x06,0x46}}; @@ -126,6 +149,7 @@ const GUID GUID_CUSTOM_CONFIRMOBJECTSAFETY = {0x10200490,0xfa38,0x11d0,{0xac,0x0e,0x00,0xa0,0xc9,0xf,0xff,0xc0}}; static int called_securl_http; +static DWORD ProcessUrlAction_policy; static struct secmgr_test { LPCWSTR url; @@ -140,7 +164,12 @@ static struct secmgr_test { {url3, 0, S_OK, sizeof(secid1), secid1, S_OK}, {url5, 3, S_OK, sizeof(secid5), secid5, S_OK}, {url6, 3, S_OK, sizeof(secid6), secid6, S_OK}, - {url7, 3, S_OK, sizeof(secid7), secid7, S_OK} + {url7, 3, S_OK, sizeof(secid7), secid7, S_OK}, + {url11,0, S_OK, sizeof(secid1), secid1, S_OK}, + {url12,0, S_OK, sizeof(secid1), secid1, S_OK}, + {url16,0, S_OK, sizeof(secid1), secid1, S_OK}, + {url17,0, S_OK, sizeof(secid1), secid1, S_OK}, + {url18,0, S_OK, sizeof(secid1), secid1, S_OK} }; static int strcmp_w(const WCHAR *str1, const WCHAR *str2) @@ -244,6 +273,103 @@ cleanup: return ret; } +static HRESULT WINAPI SecurityManager_QueryInterface(IInternetSecurityManager* This, + REFIID riid, void **ppvObject) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static ULONG WINAPI SecurityManager_AddRef(IInternetSecurityManager* This) +{ + return 2; +} + +static ULONG WINAPI SecurityManager_Release(IInternetSecurityManager* This) +{ + return 1; +} + +static HRESULT WINAPI SecurityManager_SetSecuritySite(IInternetSecurityManager* This, + IInternetSecurityMgrSite *pSite) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI SecurityManager_GetSecuritySite(IInternetSecurityManager* This, + IInternetSecurityMgrSite **ppSite) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI SecurityManager_MapUrlToZone(IInternetSecurityManager* This, + LPCWSTR pwszUrl, DWORD *pdwZone, DWORD dwFlags) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI SecurityManager_GetSecurityId(IInternetSecurityManager* This, + LPCWSTR pwszUrl, BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI SecurityManager_ProcessUrlAction(IInternetSecurityManager* This, + LPCWSTR pwszUrl, DWORD dwAction, BYTE *pPolicy, DWORD cbPolicy, + BYTE *pContext, DWORD cbContext, DWORD dwFlags, DWORD dwReserved) +{ + CHECK_EXPECT(ProcessUrlAction); + ok(dwAction == URLACTION_FEATURE_ZONE_ELEVATION, "dwAction = %x\n", dwAction); + ok(cbPolicy == sizeof(DWORD), "cbPolicy = %d\n", cbPolicy); + ok(!pContext, "pContext != NULL\n"); + ok(dwFlags == PUAF_NOUI, "dwFlags = %x\n", dwFlags); + ok(dwReserved == 0, "dwReserved = %x\n", dwReserved); + + *pPolicy = ProcessUrlAction_policy; + return ProcessUrlAction_policy==URLPOLICY_ALLOW ? S_OK : S_FALSE; +} + +static HRESULT WINAPI SecurityManager_QueryCustomPolicy(IInternetSecurityManager* This, + LPCWSTR pwszUrl, REFGUID guidKey, BYTE **ppPolicy, DWORD *pcbPolicy, + BYTE *pContext, DWORD cbContext, DWORD dwReserved) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI SecurityManager_SetZoneMapping(IInternetSecurityManager* This, + DWORD dwZone, LPCWSTR lpszPattern, DWORD dwFlags) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI SecurityManager_GetZoneMappings(IInternetSecurityManager* This, + DWORD dwZone, IEnumString **ppenumString, DWORD dwFlags) +{ + ok(0, "unexpected call\n"); + return E_NOTIMPL; +} + +static const IInternetSecurityManagerVtbl SecurityManagerVtbl = { + SecurityManager_QueryInterface, + SecurityManager_AddRef, + SecurityManager_Release, + SecurityManager_SetSecuritySite, + SecurityManager_GetSecuritySite, + SecurityManager_MapUrlToZone, + SecurityManager_GetSecurityId, + SecurityManager_ProcessUrlAction, + SecurityManager_QueryCustomPolicy, + SecurityManager_SetZoneMapping, + SecurityManager_GetZoneMappings +}; + +static IInternetSecurityManager security_manager = { &SecurityManagerVtbl }; static void test_SecurityManager(void) { @@ -305,10 +431,32 @@ static void test_SecurityManager(void) ok(size == sizeof(secid10) || size == sizeof(secid10_2), /* win2k3 */ "size=%d\n", size); - ok(!memcmp(buf, secid10, size) || - !memcmp(buf, secid10_2, size), /* win2k3 */ + ok(!memcmp(buf, secid10, sizeof(secid10)) || + !memcmp(buf, secid10_2, sizeof(secid10_2)), /* win2k3 */ "wrong secid\n"); + zone = 100; + hres = IInternetSecurityManager_MapUrlToZone(secmgr, url13, &zone, 0); + ok(hres == S_OK, "MapUrlToZone failed: %08x\n", hres); + ok(zone == URLZONE_INVALID || broken(zone == URLZONE_INTERNET), "zone=%d\n", zone); + + size = sizeof(buf); + memset(buf, 0xf0, sizeof(buf)); + hres = IInternetSecurityManager_GetSecurityId(secmgr, url13, buf, &size, 0); + ok(hres == E_INVALIDARG || broken(hres == S_OK), "GetSecurityId failed: %08x\n", hres); + + zone = 100; + hres = IInternetSecurityManager_MapUrlToZone(secmgr, url14, &zone, 0); + ok(hres == S_OK, "MapUrlToZone failed: %08x, expected S_OK\n", hres); + ok(zone == URLZONE_INTERNET, "zone=%d\n", zone); + + size = sizeof(buf); + memset(buf, 0xf0, sizeof(buf)); + hres = IInternetSecurityManager_GetSecurityId(secmgr, url14, buf, &size, 0); + ok(hres == S_OK, "GetSecurityId failed: %08x, expected S_OK\n", hres); + ok(size == sizeof(secid14), "size=%d\n", size); + ok(!memcmp(buf, secid14, size), "wrong secid\n"); + zone = 100; hres = IInternetSecurityManager_MapUrlToZone(secmgr, NULL, &zone, 0); ok(hres == E_INVALIDARG, "MapUrlToZone failed: %08x, expected E_INVALIDARG\n", hres); @@ -600,7 +748,8 @@ static const zone_domain_mapping zone_domain_mappings[] = { {"www.testing.com",NULL,"http",URLZONE_CUSTOM}, {"www.testing.com","testing","http",URLZONE_CUSTOM2}, {"org",NULL,"http",URLZONE_CUSTOM}, - {"org","testing","http",URLZONE_CUSTOM2} + {"org","testing","http",URLZONE_CUSTOM2}, + {"wine.testing",NULL,"*",URLZONE_CUSTOM2} }; static void register_zone_domains(void) @@ -747,7 +896,10 @@ static const zone_mapping_test zone_mapping_tests[] = { /* Tests for "org" zone mappings. */ {"http://google.org/",URLZONE_INTERNET,FALSE,URLZONE_CUSTOM}, {"http://org/",URLZONE_CUSTOM}, - {"http://testing.org/",URLZONE_CUSTOM2} + {"http://testing.org/",URLZONE_CUSTOM2}, + /* Tests for "wine.testing" mapping */ + {"*:wine.testing/test",URLZONE_CUSTOM2}, + {"http://wine.testing/testing",URLZONE_CUSTOM2} }; static void test_zone_domain_mappings(void) @@ -1135,7 +1287,7 @@ static void test_SetZoneAttributes(void) /* The key for the zone must be present, when calling SetZoneAttributes */ myRegDeleteTreeA(HKEY_CURRENT_USER, regpath); - /* E_FAIL is returned from IE6 here, which is resonable. + /* E_FAIL is returned from IE6 here, which is reasonable. All newer IE return S_OK without saving the zone attributes to the registry. This is a Windows bug, but we have to accept that as standard */ hr = IInternetZoneManager_SetZoneAttributes(zonemgr, URLZONE_CUSTOM, pZA); @@ -1553,7 +1705,7 @@ static void test_InternetGetSecurityUrlEx_Pluggable(void) HRESULT hr; IUri *uri = NULL, *result; - trace("testing CoInternetGetSecurityUrlEx for plugable protocols...\n"); + trace("testing CoInternetGetSecurityUrlEx for pluggable protocols...\n"); hr = pCreateUri(security_urlW, 0, 0, &uri); ok(hr == S_OK, "CreateUri returned 0x%08x\n", hr); @@ -1609,6 +1761,236 @@ static void test_InternetGetSecurityUrlEx_Pluggable(void) if(uri) IUri_Release(uri); } +static const BYTE secidex2_1[] = {'z','i','p',':','/','/','t','e','s','t','i','n','g','.','c','o','m','/',3,0,0,0}; +static const BYTE secidex2_2[] = {'z','i','p',':','t','e','s','t','i','n','g','.','c','o','m',3,0,0,0}; +static const BYTE secidex2_3[] = {'*',':','t','e','s','t','i','n','g','.','c','o','m',3,0,0,0}; + +static const struct { + const char *uri; + DWORD create_flags; + HRESULT map_hres; + DWORD zone; + BOOL map_todo; + const BYTE *secid; + DWORD secid_size; + HRESULT secid_hres; + BOOL secid_todo; +} sec_mgr_ex2_tests[] = { + {"res://mshtml.dll/blank.htm",0,S_OK,URLZONE_LOCAL_MACHINE,FALSE,secid1,sizeof(secid1),S_OK}, + {"index.htm",Uri_CREATE_ALLOW_RELATIVE,0,URLZONE_INTERNET,FALSE,secid2,sizeof(secid2),S_OK}, + {"file://c:\\Index.html",0,0,URLZONE_LOCAL_MACHINE,FALSE,secid1,sizeof(secid1),S_OK}, + {"http://www.zone3.winetest/",0,0,URLZONE_INTERNET,FALSE,secid5,sizeof(secid5),S_OK}, + {"about:blank",0,0,URLZONE_INTERNET,FALSE,secid6,sizeof(secid6),S_OK}, + {"ftp://zone3.winetest/file.test",0,0,URLZONE_INTERNET,FALSE,secid7,sizeof(secid7),S_OK}, + {"/file/testing/test.test",Uri_CREATE_ALLOW_RELATIVE,0,URLZONE_INTERNET,FALSE,NULL,0,E_INVALIDARG}, + {"zip://testing.com/",0,0,URLZONE_INTERNET,FALSE,secidex2_1,sizeof(secidex2_1),S_OK}, + {"zip:testing.com",0,0,URLZONE_INTERNET,FALSE,secidex2_2,sizeof(secidex2_2),S_OK}, + {"http:google.com",0,S_OK,URLZONE_INVALID,FALSE,NULL,0,E_INVALIDARG}, + {"http:/google.com",0,S_OK,URLZONE_INVALID,FALSE,NULL,0,E_INVALIDARG}, + {"*:/testing",0,S_OK,URLZONE_INTERNET,FALSE,NULL,0,E_INVALIDARG}, + {"*://testing.com",0,S_OK,URLZONE_INTERNET,FALSE,secidex2_3,sizeof(secidex2_3),S_OK} +}; + +static void test_SecurityManagerEx2(void) +{ + HRESULT hres; + DWORD i, zone; + BYTE buf[512]; + DWORD buf_size = sizeof(buf); + IInternetSecurityManager *sec_mgr; + IInternetSecurityManagerEx2 *sec_mgr2; + IUri *uri = NULL; + + static const WCHAR domainW[] = {'c','o','m','.','u','k',0}; + + if(!pCreateUri) { + win_skip("Skipping SecurityManagerEx2, IE is too old\n"); + return; + } + + trace("Testing SecurityManagerEx2...\n"); + + hres = pCoInternetCreateSecurityManager(NULL, &sec_mgr, 0); + ok(hres == S_OK, "CoInternetCreateSecurityManager failed: %08x\n", hres); + + hres = IInternetSecurityManager_QueryInterface(sec_mgr, &IID_IInternetSecurityManagerEx2, (void**)&sec_mgr2); + ok(hres == S_OK, "QueryInterface(IID_IInternetSecurityManagerEx2) failed: %08x\n", hres); + + zone = 0xdeadbeef; + + hres = IInternetSecurityManagerEx2_MapUrlToZoneEx2(sec_mgr2, NULL, &zone, 0, NULL, NULL); + ok(hres == E_INVALIDARG, "MapUrlToZoneEx2 returned %08x, expected E_INVALIDARG\n", hres); + ok(zone == URLZONE_INVALID, "zone was %d\n", zone); + + hres = IInternetSecurityManagerEx2_GetSecurityIdEx2(sec_mgr2, NULL, buf, &buf_size, 0); + ok(hres == E_INVALIDARG, "GetSecurityIdEx2 returned %08x, expected E_INVALIDARG\n", hres); + ok(buf_size == sizeof(buf), "buf_size was %d\n", buf_size); + + hres = pCreateUri(url5, 0, 0, &uri); + ok(hres == S_OK, "CreateUri failed: %08x\n", hres); + + hres = IInternetSecurityManagerEx2_MapUrlToZoneEx2(sec_mgr2, uri, NULL, 0, NULL, NULL); + ok(hres == E_INVALIDARG, "MapToUrlZoneEx2 returned %08x, expected E_INVALIDARG\n", hres); + + buf_size = sizeof(buf); + hres = IInternetSecurityManagerEx2_GetSecurityIdEx2(sec_mgr2, uri, NULL, &buf_size, 0); + ok(hres == E_INVALIDARG || broken(hres == S_OK), "GetSecurityIdEx2 failed: %08x\n", hres); + ok(buf_size == sizeof(buf), "bug_size was %d\n", buf_size); + + hres = IInternetSecurityManagerEx2_GetSecurityIdEx2(sec_mgr2, uri, buf, NULL, 0); + ok(hres == E_INVALIDARG, "GetSecurityIdEx2 returned %08x, expected E_INVALIDARG\n", hres); + + IUri_Release(uri); + + for(i = 0; i < sizeof(sec_mgr_ex2_tests)/sizeof(sec_mgr_ex2_tests[0]); ++i) { + LPWSTR uriW = a2w(sec_mgr_ex2_tests[i].uri); + + uri = NULL; + zone = URLZONE_INVALID; + + hres = pCreateUri(uriW, sec_mgr_ex2_tests[i].create_flags, 0, &uri); + ok(hres == S_OK, "CreateUri returned %08x for '%s'\n", hres, sec_mgr_ex2_tests[i].uri); + + hres = IInternetSecurityManagerEx2_MapUrlToZoneEx2(sec_mgr2, uri, &zone, 0, NULL, NULL); + if(sec_mgr_ex2_tests[i].map_todo) { + todo_wine + ok(hres == sec_mgr_ex2_tests[i].map_hres, "MapUrlZoneToEx2 returned %08x, expected %08x for '%s'\n", + hres, sec_mgr_ex2_tests[i].map_hres, sec_mgr_ex2_tests[i].uri); + todo_wine + ok(zone == sec_mgr_ex2_tests[i].zone, "Expected zone %d, but got %d for '%s'\n", sec_mgr_ex2_tests[i].zone, + zone, sec_mgr_ex2_tests[i].uri); + } else { + ok(hres == sec_mgr_ex2_tests[i].map_hres, "MapUrlToZoneEx2 returned %08x, expected %08x for '%s'\n", + hres, sec_mgr_ex2_tests[i].map_hres, sec_mgr_ex2_tests[i].uri); + ok(zone == sec_mgr_ex2_tests[i].zone, "Expected zone %d, but got %d for '%s'\n", sec_mgr_ex2_tests[i].zone, + zone, sec_mgr_ex2_tests[i].uri); + } + + buf_size = sizeof(buf); + memset(buf, 0xf0, buf_size); + + hres = IInternetSecurityManagerEx2_GetSecurityIdEx2(sec_mgr2, uri, buf, &buf_size, 0); + if(sec_mgr_ex2_tests[i].secid_todo) { + todo_wine + ok(hres == sec_mgr_ex2_tests[i].secid_hres, "GetSecurityIdEx2 returned %08x, expected %08x on test '%s'\n", + hres, sec_mgr_ex2_tests[i].secid_hres, sec_mgr_ex2_tests[i].uri); + if(sec_mgr_ex2_tests[i].secid) { + todo_wine { + ok(buf_size == sec_mgr_ex2_tests[i].secid_size, "Got wrong security id size=%d, expected %d on test '%s'\n", + buf_size, sec_mgr_ex2_tests[i].secid_size, sec_mgr_ex2_tests[i].uri); + ok(!memcmp(buf, sec_mgr_ex2_tests[i].secid, sec_mgr_ex2_tests[i].secid_size), "Got wrong security id on test '%s'\n", + sec_mgr_ex2_tests[i].uri); + } + } + } else { + ok(hres == sec_mgr_ex2_tests[i].secid_hres, "GetSecurityIdEx2 returned %08x, expected %08x on test '%s'\n", + hres, sec_mgr_ex2_tests[i].secid_hres, sec_mgr_ex2_tests[i].uri); + if(sec_mgr_ex2_tests[i].secid) { + ok(buf_size == sec_mgr_ex2_tests[i].secid_size, "Got wrong security id size=%d, expected %d on test '%s'\n", + buf_size, sec_mgr_ex2_tests[i].secid_size, sec_mgr_ex2_tests[i].uri); + ok(!memcmp(buf, sec_mgr_ex2_tests[i].secid, sec_mgr_ex2_tests[i].secid_size), "Got wrong security id on test '%s'\n", + sec_mgr_ex2_tests[i].uri); + } + } + + heap_free(uriW); + IUri_Release(uri); + } + + hres = pCreateUri(url15, 0, 0, &uri); + ok(hres == S_OK, "CreateUri failed: %08x\n", hres); + + buf_size = sizeof(buf); + memset(buf, 0xf0, buf_size); + + hres = IInternetSecurityManagerEx2_GetSecurityIdEx2(sec_mgr2, uri, buf, &buf_size, (DWORD_PTR)domainW); + ok(hres == S_OK, "GetSecurityIdEx2 failed: %08x\n", hres); + todo_wine ok(buf_size == sizeof(secid13), "buf_size was %d\n", buf_size); + todo_wine ok(!memcmp(buf, secid13, sizeof(secid13)), "Got wrong secid\n"); + + buf_size = sizeof(buf); + memset(buf, 0xf0, buf_size); + + hres = IInternetSecurityManagerEx2_GetSecurityIdEx2(sec_mgr2, uri, buf, &buf_size, 0); + ok(hres == S_OK, "GetSecurityIdEx2 failed: %08x\n", hres); + ok(buf_size == sizeof(secid13_2), "buf_size was %d\n", buf_size); + ok(!memcmp(buf, secid13_2, sizeof(secid13_2)), "Got wrong secid\n"); + + IUri_Release(uri); + + IInternetSecurityManagerEx2_Release(sec_mgr2); + IInternetSecurityManager_Release(sec_mgr); +} + +static void test_CoInternetIsFeatureZoneElevationEnabled(void) +{ + struct { + const char *url_from; + const char *url_to; + DWORD flags; + HRESULT hres; + DWORD policy_flags; + } testcases[] = { + /* 0 */ { "http://www.winehq.org", "http://www.winehq.org", 0, S_FALSE, URLPOLICY_ALLOW }, + /* 1 */ { "http://www.winehq.org", "http://www.winehq.org", 0, S_OK, URLPOLICY_DISALLOW }, + /* 2 */ { "http://www.winehq.org", "http://www.codeweavers.com", 0, S_FALSE, URLPOLICY_ALLOW }, + /* 3 */ { "http://www.winehq.org", "http://www.codeweavers.com", 0, S_OK, URLPOLICY_DISALLOW }, + /* 4 */ { "http://www.winehq.org", "http://www.winehq.org", GET_FEATURE_FROM_PROCESS, S_FALSE, -1 }, + /* 5 */ { "http://www.winehq.org", "http://www.winehq.org/dir", GET_FEATURE_FROM_PROCESS, S_FALSE, -1 }, + /* 6 */ { "http://www.winehq.org", "http://www.codeweavers.com", GET_FEATURE_FROM_PROCESS, S_FALSE, -1 }, + /* 7 */ { "http://www.winehq.org", "ftp://winehq.org", GET_FEATURE_FROM_PROCESS, S_FALSE, -1 }, + /* 8 */ { "http://www.winehq.org", "ftp://winehq.org", GET_FEATURE_FROM_PROCESS|0x100, S_FALSE, URLPOLICY_ALLOW }, + /* 9 */ { "http://www.winehq.org", "ftp://winehq.org", GET_FEATURE_FROM_REGISTRY, S_FALSE, URLPOLICY_ALLOW }, + }; + + WCHAR *url_from, *url_to; + int i; + HRESULT hres; + + if(!pCoInternetIsFeatureZoneElevationEnabled || !pCoInternetIsFeatureEnabled + || !pCoInternetIsFeatureEnabledForUrl) { + win_skip("Skipping CoInternetIsFeatureZoneElevationEnabled tests\n"); + return; + } + + + hres = pCoInternetIsFeatureEnabled(FEATURE_ZONE_ELEVATION, GET_FEATURE_FROM_PROCESS); + ok(SUCCEEDED(hres), "CoInternetIsFeatureEnabled returned %x\n", hres); + + trace("Testing CoInternetIsFeatureZoneElevationEnabled... (%x)\n", hres); + + for(i=0; i -#include -#include +//#include +//#include -#include "windef.h" -#include "winbase.h" -#include "ole2.h" -#include "urlmon.h" -#include "wininet.h" +//#include "windef.h" +//#include "winbase.h" +#include +#include +//#include "urlmon.h" +#include #define DEFINE_EXPECT(func) \ static BOOL expect_ ## func = FALSE, called_ ## func = FALSE diff --git a/rostests/winetests/urlmon/testlist.c b/rostests/winetests/urlmon/testlist.c index c6709e8adea..b7b9c1dab3b 100644 --- a/rostests/winetests/urlmon/testlist.c +++ b/rostests/winetests/urlmon/testlist.c @@ -1,10 +1,7 @@ /* Automatically generated file; DO NOT EDIT!! */ -#define WIN32_LEAN_AND_MEAN -#include - #define STANDALONE -#include "wine/test.h" +#include extern void func_generated(void); extern void func_misc(void); diff --git a/rostests/winetests/urlmon/uri.c b/rostests/winetests/urlmon/uri.c index 930622a8131..856decb792b 100644 --- a/rostests/winetests/urlmon/uri.c +++ b/rostests/winetests/urlmon/uri.c @@ -18,19 +18,30 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + #include -#include -#include +//#include +//#include #define COBJMACROS #define CONST_VTABLE +#define WIN32_LEAN_AND_MEAN -#include "windef.h" -#include "winbase.h" -#include "urlmon.h" -#include "shlwapi.h" -#include "wininet.h" -#include "strsafe.h" +//#include "windef.h" +//#include "winbase.h" +#include +#include +#include +//#include "urlmon.h" +#include +#include +#include +#include + +DEFINE_GUID(CLSID_CUri, 0xDF2FCE13, 0x25EC, 0x45BB, 0x9D,0x4C, 0xCE,0xCD,0x47,0xC2,0x43,0x0C); #define URI_STR_PROPERTY_COUNT Uri_PROPERTY_STRING_LAST+1 #define URI_DWORD_PROPERTY_COUNT (Uri_PROPERTY_DWORD_LAST - Uri_PROPERTY_DWORD_START)+1 @@ -71,6 +82,8 @@ static HRESULT (WINAPI *pCoInternetCombineIUri)(IUri*,IUri*,DWORD,IUri**,DWORD_P static HRESULT (WINAPI *pCoInternetGetSession)(DWORD,IInternetSession**,DWORD); static HRESULT (WINAPI *pCoInternetCombineUrlEx)(IUri*,LPCWSTR,DWORD,IUri**,DWORD_PTR); static HRESULT (WINAPI *pCoInternetParseIUri)(IUri*,PARSEACTION,DWORD,LPWSTR,DWORD,DWORD*,DWORD_PTR); +static HRESULT (WINAPI *pCreateURLMonikerEx)(IMoniker*,LPCWSTR,IMoniker**,DWORD); +static HRESULT (WINAPI *pCreateURLMonikerEx2)(IMoniker*,IUri*,IMoniker**,DWORD); static const WCHAR http_urlW[] = { 'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q', '.','o','r','g','/',0}; @@ -115,6 +128,7 @@ typedef struct _uri_dword_property { DWORD value; HRESULT expected; BOOL todo; + BOOL broken_combine_hres; } uri_dword_property; typedef struct _uri_properties { @@ -203,6 +217,31 @@ static const uri_properties uri_tests[] = { {URLZONE_INVALID,E_NOTIMPL,FALSE}, } }, + { "HtTpS://www.winehq.org/tests/..?query=x&return=y", 0, S_OK, FALSE, + { + {"https://www.winehq.org/?query=x&return=y",S_OK,FALSE}, + {"www.winehq.org",S_OK,FALSE}, + {"https://www.winehq.org/?query=x&return=y",S_OK,FALSE}, + {"winehq.org",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE}, + {"www.winehq.org",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"/",S_OK,FALSE}, + {"/?query=x&return=y",S_OK,FALSE}, + {"?query=x&return=y",S_OK,FALSE}, + {"HtTpS://www.winehq.org/tests/..?query=x&return=y",S_OK,FALSE}, + {"https",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE} + }, + { + {Uri_HOST_DNS,S_OK,FALSE}, + {443,S_OK,FALSE}, + {URL_SCHEME_HTTPS,S_OK,FALSE}, + {URLZONE_INVALID,E_NOTIMPL,FALSE}, + } + }, { "hTTp://us%45r%3Ainfo@examp%4CE.com:80/path/a/b/./c/../%2E%2E/Forbidden'<|> Characters", 0, S_OK, FALSE, { {"http://usEr%3Ainfo@example.com/path/a/Forbidden'%3C%7C%3E%20Characters",S_OK,FALSE}, @@ -278,6 +317,31 @@ static const uri_properties uri_tests[] = { {URLZONE_INVALID,E_NOTIMPL,FALSE} } }, + { "file://c:\\tests\\../tests/foo%20bar.mp3", Uri_CREATE_NO_CANONICALIZE, S_OK, FALSE, + { + {"file:///c:/tests/../tests/foo%2520bar.mp3",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"file:///c:/tests/../tests/foo%2520bar.mp3",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {".mp3",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE}, + {"/c:/tests/../tests/foo%2520bar.mp3",S_OK,FALSE}, + {"/c:/tests/../tests/foo%2520bar.mp3",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"file://c:\\tests\\../tests/foo%20bar.mp3",S_OK,FALSE}, + {"file",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE} + }, + { + {Uri_HOST_UNKNOWN,S_OK,FALSE}, + {0,S_FALSE,FALSE}, + {URL_SCHEME_FILE,S_OK,FALSE}, + {URLZONE_INVALID,E_NOTIMPL,FALSE} + } + }, { "FILE://localhost/test dir\\../tests/test%20file.README.txt", 0, S_OK, FALSE, { {"file:///tests/test%20file.README.txt",S_OK,FALSE}, @@ -840,7 +904,7 @@ static const uri_properties uri_tests[] = { {URLZONE_INVALID,E_NOTIMPL,FALSE} } }, - /* Unreserved, percent encoded characters aren't decoded in the userinfo becuase the scheme + /* Unreserved, percent encoded characters aren't decoded in the userinfo because the scheme * isn't known. */ { "zip://%2E:%52%53ord@winehq.org/", 0, S_OK, FALSE, @@ -995,6 +1059,31 @@ static const uri_properties uri_tests[] = { {URLZONE_INVALID,E_NOTIMPL,FALSE} } }, + { "http://127.0.0.1:8000", 0, S_OK, FALSE, + { + {"http://127.0.0.1:8000/",S_OK}, + {"127.0.0.1:8000",S_OK}, + {"http://127.0.0.1:8000/",S_OK}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + {"127.0.0.1",S_OK}, + {"",S_FALSE}, + {"/",S_OK}, + {"/",S_OK}, + {"",S_FALSE}, + {"http://127.0.0.1:8000",S_OK}, + {"http",S_OK}, + {"",S_FALSE}, + {"",S_FALSE} + }, + { + {Uri_HOST_IPV4,S_OK,FALSE}, + {8000,S_OK,FALSE}, + {URL_SCHEME_HTTP,S_OK,FALSE}, + {URLZONE_INVALID,E_NOTIMPL,FALSE} + } + }, /* Make sure it normalizes partial IPv4 addresses correctly. */ { "http://127.0/", 0, S_OK, FALSE, { @@ -1409,7 +1498,7 @@ static const uri_properties uri_tests[] = { {URLZONE_INVALID,E_NOTIMPL,FALSE} } }, - /* Hostname get's lower cased for known scheme types. */ + /* Hostname gets lower-cased for known scheme types. */ { "http://WWW.GOOGLE.com/", 0, S_OK, FALSE, { {"http://www.google.com/",S_OK,FALSE}, @@ -4139,6 +4228,281 @@ static const uri_properties uri_tests[] = { {URL_SCHEME_MK,S_OK,FALSE}, {URLZONE_INVALID,E_NOTIMPL,FALSE} } + }, + { "", Uri_CREATE_ALLOW_RELATIVE, S_OK, FALSE, + { + {"",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_OK,FALSE}, + {"",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE} + }, + { + {Uri_HOST_UNKNOWN,S_OK,FALSE}, + {0,S_FALSE,FALSE}, + {URL_SCHEME_UNKNOWN,S_OK,FALSE}, + {URLZONE_INVALID,E_NOTIMPL,FALSE} + } + }, + { " \t ", Uri_CREATE_ALLOW_RELATIVE, S_OK, FALSE, + { + {"",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_OK,FALSE}, + {"",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE} + }, + { + {Uri_HOST_UNKNOWN,S_OK,FALSE}, + {0,S_FALSE,FALSE}, + {URL_SCHEME_UNKNOWN,S_OK,FALSE}, + {URLZONE_INVALID,E_NOTIMPL,FALSE} + } + }, + { "javascript:void", 0, S_OK, FALSE, + { + {"javascript:void",S_OK}, + {"",S_FALSE}, + {"javascript:void",S_OK}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + {"void",S_OK}, + {"void",S_OK}, + {"",S_FALSE}, + {"javascript:void",S_OK}, + {"javascript",S_OK}, + {"",S_FALSE}, + {"",S_FALSE} + }, + { + {Uri_HOST_UNKNOWN,S_OK}, + {0,S_FALSE}, + {URL_SCHEME_JAVASCRIPT,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } + }, + { "javascript://undefined", 0, S_OK, FALSE, + { + {"javascript://undefined",S_OK}, + {"",S_FALSE}, + {"javascript://undefined",S_OK}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + {"//undefined",S_OK}, + {"//undefined",S_OK}, + {"",S_FALSE}, + {"javascript://undefined",S_OK}, + {"javascript",S_OK}, + {"",S_FALSE}, + {"",S_FALSE} + }, + { + {Uri_HOST_UNKNOWN,S_OK}, + {0,S_FALSE}, + {URL_SCHEME_JAVASCRIPT,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } + }, + { "JavaSCript:escape('/\\?#?')", 0, S_OK, FALSE, + { + {"javascript:escape('/\\?#?')",S_OK}, + {"",S_FALSE}, + {"javascript:escape('/\\?#?')",S_OK}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + {"escape('/\\?#?')",S_OK}, + {"escape('/\\?#?')",S_OK}, + {"",S_FALSE}, + {"JavaSCript:escape('/\\?#?')",S_OK}, + {"javascript",S_OK}, + {"",S_FALSE}, + {"",S_FALSE} + }, + { + {Uri_HOST_UNKNOWN,S_OK}, + {0,S_FALSE}, + {URL_SCHEME_JAVASCRIPT,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } + }, + { "*://google.com", 0, S_OK, FALSE, + { + {"*:google.com/",S_OK,FALSE}, + {"google.com",S_OK}, + {"*:google.com/",S_OK,FALSE}, + {"google.com",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE}, + {"google.com",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"/",S_OK,FALSE}, + {"/",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"*://google.com",S_OK,FALSE}, + {"*",S_OK,FALSE}, + {"",S_FALSE,FALSE}, + {"",S_FALSE,FALSE} + }, + { + {Uri_HOST_DNS,S_OK,FALSE}, + {0,S_FALSE,FALSE}, + {URL_SCHEME_WILDCARD,S_OK,FALSE}, + {URLZONE_INVALID,E_NOTIMPL,FALSE} + } + }, + { "mk:@MSITSTORE:C:\\Some\\Bogus\\Path.chm::/subdir/file.txt",0,S_OK,FALSE, + { + {"mk:@MSITSTORE:C:\\Some\\Bogus\\Path.chm::/subdir/file.txt",S_OK}, + {"",S_FALSE}, + {"mk:@MSITSTORE:C:\\Some\\Bogus\\Path.chm::/subdir/file.txt",S_OK}, + {"",S_FALSE}, + {".txt",S_OK}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + {"@MSITSTORE:C:\\Some\\Bogus\\Path.chm::/subdir/file.txt",S_OK}, + {"@MSITSTORE:C:\\Some\\Bogus\\Path.chm::/subdir/file.txt",S_OK}, + {"",S_FALSE}, + {"mk:@MSITSTORE:C:\\Some\\Bogus\\Path.chm::/subdir/file.txt",S_OK}, + {"mk",S_OK}, + {"",S_FALSE}, + {"",S_FALSE} + }, + { + {Uri_HOST_UNKNOWN,S_OK}, + {0,S_FALSE}, + {URL_SCHEME_MK,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } + }, + { "gopher://test.winehq.org:151/file.txt",0,S_OK,FALSE, + { + {"gopher://test.winehq.org:151/file.txt",S_OK}, + {"test.winehq.org:151",S_OK}, + {"gopher://test.winehq.org:151/file.txt",S_OK}, + {"winehq.org",S_OK}, + {".txt",S_OK}, + {"",S_FALSE}, + {"test.winehq.org",S_OK}, + {"",S_FALSE}, + {"/file.txt",S_OK}, + {"/file.txt",S_OK}, + {"",S_FALSE}, + {"gopher://test.winehq.org:151/file.txt",S_OK}, + {"gopher",S_OK}, + {"",S_FALSE}, + {"",S_FALSE} + }, + { + {Uri_HOST_DNS,S_OK}, + {151,S_OK}, + {URL_SCHEME_GOPHER,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } + }, + { "//host.com/path/file.txt?query", Uri_CREATE_ALLOW_RELATIVE, S_OK, FALSE, + { + {"//host.com/path/file.txt?query",S_OK}, + {"host.com",S_OK}, + {"//host.com/path/file.txt?query",S_OK}, + {"host.com",S_OK}, + {".txt",S_OK}, + {"",S_FALSE}, + {"host.com",S_OK}, + {"",S_FALSE}, + {"/path/file.txt",S_OK}, + {"/path/file.txt?query",S_OK}, + {"?query",S_OK}, + {"//host.com/path/file.txt?query",S_OK}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + }, + { + {Uri_HOST_DNS,S_OK}, + {0,S_FALSE}, + {URL_SCHEME_UNKNOWN,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } + }, + { "//host/path/file.txt?query", Uri_CREATE_ALLOW_RELATIVE, S_OK, FALSE, + { + {"//host/path/file.txt?query",S_OK}, + {"host",S_OK}, + {"//host/path/file.txt?query",S_OK}, + {"",S_FALSE}, + {".txt",S_OK}, + {"",S_FALSE}, + {"host",S_OK}, + {"",S_FALSE}, + {"/path/file.txt",S_OK}, + {"/path/file.txt?query",S_OK}, + {"?query",S_OK}, + {"//host/path/file.txt?query",S_OK}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + }, + { + {Uri_HOST_DNS,S_OK}, + {0,S_FALSE}, + {URL_SCHEME_UNKNOWN,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } + }, + { "//host", Uri_CREATE_ALLOW_RELATIVE, S_OK, FALSE, + { + {"//host/",S_OK}, + {"host",S_OK}, + {"//host/",S_OK}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + {"host",S_OK}, + {"",S_FALSE}, + {"/",S_OK}, + {"/",S_OK}, + {"",S_FALSE}, + {"//host",S_OK}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + }, + { + {Uri_HOST_DNS,S_OK}, + {0,S_FALSE}, + {URL_SCHEME_UNKNOWN,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } } }; @@ -4216,91 +4580,140 @@ static const invalid_uri invalid_uri_tests[] = { typedef struct _uri_equality { const char* a; DWORD create_flags_a; - BOOL create_todo_a; const char* b; DWORD create_flags_b; - BOOL create_todo_b; BOOL equal; BOOL todo; } uri_equality; static const uri_equality equality_tests[] = { { - "HTTP://www.winehq.org/test dir/./",0,FALSE, - "http://www.winehq.org/test dir/../test dir/",0,FALSE, - TRUE, FALSE + "HTTP://www.winehq.org/test dir/./",0, + "http://www.winehq.org/test dir/../test dir/",0, + TRUE }, { /* http://www.winehq.org/test%20dir */ - "http://%77%77%77%2E%77%69%6E%65%68%71%2E%6F%72%67/%74%65%73%74%20%64%69%72",0,FALSE, - "http://www.winehq.org/test dir",0,FALSE, - TRUE, FALSE + "http://%77%77%77%2E%77%69%6E%65%68%71%2E%6F%72%67/%74%65%73%74%20%64%69%72",0, + "http://www.winehq.org/test dir",0, + TRUE }, { - "c:\\test.mp3",Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME,FALSE, - "file:///c:/test.mp3",0,FALSE, - TRUE, FALSE + "c:\\test.mp3",Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, + "file:///c:/test.mp3",0, + TRUE }, { - "ftp://ftp.winehq.org/",0,FALSE, - "ftp://ftp.winehq.org",0,FALSE, - TRUE, FALSE + "ftp://ftp.winehq.org/",0, + "ftp://ftp.winehq.org",0, + TRUE }, { - "ftp://ftp.winehq.org/test/test2/../../testB/",0,FALSE, - "ftp://ftp.winehq.org/t%45stB/",0,FALSE, - FALSE, FALSE + "ftp://ftp.winehq.org/test/test2/../../testB/",0, + "ftp://ftp.winehq.org/t%45stB/",0, + FALSE }, { - "http://google.com/TEST",0,FALSE, - "http://google.com/test",0,FALSE, - FALSE, FALSE + "http://google.com/TEST",0, + "http://google.com/test",0, + FALSE }, { - "http://GOOGLE.com/",0,FALSE, - "http://google.com/",0,FALSE, - TRUE, FALSE + "http://GOOGLE.com/",0, + "http://google.com/",0, + TRUE }, /* Performs case insensitive compare of host names (for known scheme types). */ { - "ftp://GOOGLE.com/",Uri_CREATE_NO_CANONICALIZE,FALSE, - "ftp://google.com/",0,FALSE, - TRUE, FALSE + "ftp://GOOGLE.com/",Uri_CREATE_NO_CANONICALIZE, + "ftp://google.com/",0, + TRUE }, { - "zip://GOOGLE.com/",0,FALSE, - "zip://google.com/",0,FALSE, - FALSE, FALSE + "zip://GOOGLE.com/",0, + "zip://google.com/",0, + FALSE }, { - "file:///c:/TEST/TeST/",0,FALSE, - "file:///c:/test/test/",0,FALSE, - TRUE, FALSE + "file:///c:/TEST/TeST/",0, + "file:///c:/test/test/",0, + TRUE }, { - "file:///server/TEST",0,FALSE, - "file:///SERVER/TEST",0,FALSE, - TRUE, FALSE + "file:///server/TEST",0, + "file:///SERVER/TEST",0, + TRUE }, { - "http://google.com",Uri_CREATE_NO_CANONICALIZE,FALSE, - "http://google.com/",0,FALSE, - TRUE, FALSE + "http://google.com",Uri_CREATE_NO_CANONICALIZE, + "http://google.com/",0, + TRUE }, { - "ftp://google.com:21/",0,FALSE, - "ftp://google.com/",0,FALSE, - TRUE, FALSE + "ftp://google.com:21/",0, + "ftp://google.com/",0, + TRUE }, { - "http://google.com:80/",Uri_CREATE_NO_CANONICALIZE,FALSE, - "http://google.com/",0,FALSE, - TRUE, FALSE + "http://google.com:80/",Uri_CREATE_NO_CANONICALIZE, + "http://google.com/",0, + TRUE }, { - "http://google.com:70/",0,FALSE, - "http://google.com:71/",0,FALSE, - FALSE, FALSE + "http://google.com:70/",0, + "http://google.com:71/",0, + FALSE + }, + { + "file:///c:/dir/file.txt", 0, + "file:///c:/dir/file.txt", Uri_CREATE_FILE_USE_DOS_PATH, + TRUE + }, + { + "file:///c:/dir/file.txt", 0, + "file:///c:\\dir\\file.txt", Uri_CREATE_NO_CANONICALIZE, + TRUE + }, + { + "file:///c:/dir/file.txt", 0, + "file:///c:\\dir2\\..\\dir\\file.txt", Uri_CREATE_NO_CANONICALIZE, + TRUE + }, + { + "file:///c:\\dir2\\..\\ dir\\file.txt", Uri_CREATE_NO_CANONICALIZE, + "file:///c:/%20dir/file.txt", 0, + TRUE + }, + { + "file:///c:/Dir/file.txt", 0, + "file:///C:/dir/file.TXT", Uri_CREATE_FILE_USE_DOS_PATH, + TRUE + }, + { + "file:///c:/dir/file.txt", 0, + "file:///c:\\dir\\file.txt", Uri_CREATE_FILE_USE_DOS_PATH, + TRUE + }, + { + "file:///c:/dir/file.txt#a", 0, + "file:///c:\\dir\\file.txt#b", Uri_CREATE_FILE_USE_DOS_PATH, + FALSE + }, + /* Tests of an empty hash/fragment part */ + { + "http://google.com/test",0, + "http://google.com/test#",0, + FALSE + }, + { + "ftp://ftp.winehq.org/",0, + "ftp://ftp.winehq.org/#",0, + FALSE + }, + { + "file:///c:/dir/file.txt#", 0, + "file:///c:\\dir\\file.txt", Uri_CREATE_FILE_USE_DOS_PATH, + FALSE } }; @@ -5325,6 +5738,70 @@ static const uri_builder_test uri_builder_tests[] = { 0,INET_E_INVALID_URL,FALSE, 0,INET_E_INVALID_URL,FALSE, 0,0,0,INET_E_INVALID_URL,FALSE + }, + { "file:///c:/dir/file.html",0,S_OK,FALSE, + { + {TRUE,NULL,NULL,Uri_PROPERTY_FRAGMENT,S_OK}, + }, + {FALSE}, + 0,S_OK,FALSE, + 0,S_OK,FALSE, + 0,0,0,S_OK,FALSE, + { + {"file:///c:/dir/file.html",S_OK}, + {"",S_FALSE}, + {"file:///c:/dir/file.html",S_OK}, + {"",S_FALSE}, + {".html",S_OK}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + {"/c:/dir/file.html",S_OK}, + {"/c:/dir/file.html",S_OK}, + {"",S_FALSE}, + {"file:///c:/dir/file.html",S_OK}, + {"file",S_OK}, + {"",S_FALSE}, + {"",S_FALSE} + }, + { + {Uri_HOST_UNKNOWN,S_OK}, + {0,S_FALSE}, + {URL_SCHEME_FILE,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } + }, + { "file:///c:/dir/file.html",0,S_OK,FALSE, + { + {TRUE,"#",NULL,Uri_PROPERTY_FRAGMENT,S_OK}, + }, + {FALSE}, + 0,S_OK,FALSE, + 0,S_OK,FALSE, + 0,0,0,S_OK,FALSE, + { + {"file:///c:/dir/file.html#",S_OK}, + {"",S_FALSE}, + {"file:///c:/dir/file.html#",S_OK}, + {"",S_FALSE}, + {".html",S_OK}, + {"#",S_OK}, + {"",S_FALSE}, + {"",S_FALSE}, + {"/c:/dir/file.html",S_OK}, + {"/c:/dir/file.html",S_OK}, + {"",S_FALSE}, + {"file:///c:/dir/file.html#",S_OK}, + {"file",S_OK}, + {"",S_FALSE}, + {"",S_FALSE} + }, + { + {Uri_HOST_UNKNOWN,S_OK}, + {0,S_FALSE}, + {URL_SCHEME_FILE,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } } }; @@ -6159,6 +6636,303 @@ static const uri_combine_test uri_combine_tests[] = { {URL_SCHEME_HTTP,S_OK}, {URLZONE_INVALID,E_NOTIMPL} } + }, + { "mk:@MSITSTORE:C:\\Some\\Bogus\\Path.chm::/subdir\\file.txt",0, + "relative/path.txt",Uri_CREATE_ALLOW_RELATIVE, + 0,S_OK,FALSE, + { + {"mk:@MSITSTORE:C:\\Some\\Bogus\\Path.chm::/subdir/relative/path.txt",S_OK}, + {"",S_FALSE}, + {"mk:@MSITSTORE:C:\\Some\\Bogus\\Path.chm::/subdir/relative/path.txt",S_OK}, + {"",S_FALSE}, + {".txt",S_OK}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + {"@MSITSTORE:C:\\Some\\Bogus\\Path.chm::/subdir/relative/path.txt",S_OK}, + {"@MSITSTORE:C:\\Some\\Bogus\\Path.chm::/subdir/relative/path.txt",S_OK}, + {"",S_FALSE}, + {"mk:@MSITSTORE:C:\\Some\\Bogus\\Path.chm::/subdir/relative/path.txt",S_OK}, + {"mk",S_OK}, + {"",S_FALSE}, + {"",S_FALSE} + }, + { + {Uri_HOST_UNKNOWN,S_OK}, + {0,S_FALSE}, + {URL_SCHEME_MK,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } + }, + { "mk:@MSITSTORE:C:\\Some\\Bogus\\Path.chm::\\subdir\\file.txt",0, + "relative/path.txt",Uri_CREATE_ALLOW_RELATIVE, + 0,S_OK,FALSE, + { + {"mk:@MSITSTORE:C:\\Some\\Bogus\\Path.chm::/subdir/relative/path.txt",S_OK}, + {"",S_FALSE}, + {"mk:@MSITSTORE:C:\\Some\\Bogus\\Path.chm::/subdir/relative/path.txt",S_OK}, + {"",S_FALSE}, + {".txt",S_OK}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + {"@MSITSTORE:C:\\Some\\Bogus\\Path.chm::/subdir/relative/path.txt",S_OK}, + {"@MSITSTORE:C:\\Some\\Bogus\\Path.chm::/subdir/relative/path.txt",S_OK}, + {"",S_FALSE}, + {"mk:@MSITSTORE:C:\\Some\\Bogus\\Path.chm::/subdir/relative/path.txt",S_OK}, + {"mk",S_OK}, + {"",S_FALSE}, + {"",S_FALSE} + }, + { + {Uri_HOST_UNKNOWN,S_OK}, + {0,S_FALSE}, + {URL_SCHEME_MK,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } + }, + { "mk:@MSITSTORE:C:/Some\\Bogus/Path.chm::/subdir\\file.txt",0, + "relative\\path.txt",Uri_CREATE_ALLOW_RELATIVE, + 0,S_OK,FALSE, + { + {"mk:@MSITSTORE:C:/Some\\Bogus/Path.chm::/subdir/relative/path.txt",S_OK}, + {"",S_FALSE}, + {"mk:@MSITSTORE:C:/Some\\Bogus/Path.chm::/subdir/relative/path.txt",S_OK}, + {"",S_FALSE}, + {".txt",S_OK}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + {"@MSITSTORE:C:/Some\\Bogus/Path.chm::/subdir/relative/path.txt",S_OK}, + {"@MSITSTORE:C:/Some\\Bogus/Path.chm::/subdir/relative/path.txt",S_OK}, + {"",S_FALSE}, + {"mk:@MSITSTORE:C:/Some\\Bogus/Path.chm::/subdir/relative/path.txt",S_OK}, + {"mk",S_OK}, + {"",S_FALSE}, + {"",S_FALSE} + }, + { + {Uri_HOST_UNKNOWN,S_OK}, + {0,S_FALSE}, + {URL_SCHEME_MK,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } + }, + { "mk:@MSITSTORE:C:\\dir\\file.chm::/subdir/file.txt",0, + "/relative/path.txt",Uri_CREATE_ALLOW_RELATIVE, + 0,S_OK,FALSE, + { + {"mk:@MSITSTORE:C:\\dir\\file.chm::/relative/path.txt",S_OK}, + {"",S_FALSE}, + {"mk:@MSITSTORE:C:\\dir\\file.chm::/relative/path.txt",S_OK}, + {"",S_FALSE}, + {".txt",S_OK}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + {"@MSITSTORE:C:\\dir\\file.chm::/relative/path.txt",S_OK}, + {"@MSITSTORE:C:\\dir\\file.chm::/relative/path.txt",S_OK}, + {"",S_FALSE}, + {"mk:@MSITSTORE:C:\\dir\\file.chm::/relative/path.txt",S_OK}, + {"mk",S_OK}, + {"",S_FALSE}, + {"",S_FALSE} + }, + { + {Uri_HOST_UNKNOWN,S_OK}, + {0,S_FALSE}, + {URL_SCHEME_MK,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } + }, + { "mk:MSITSTORE:C:\\dir\\file.chm::/subdir/file.txt",0, + "/relative/path.txt",Uri_CREATE_ALLOW_RELATIVE, + 0,S_OK,FALSE, + { + {"mk:MSITSTORE:C:\\dir\\file.chm::/relative/path.txt",S_OK}, + {"",S_FALSE}, + {"mk:MSITSTORE:C:\\dir\\file.chm::/relative/path.txt",S_OK}, + {"",S_FALSE}, + {".txt",S_OK}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + {"MSITSTORE:C:\\dir\\file.chm::/relative/path.txt",S_OK}, + {"MSITSTORE:C:\\dir\\file.chm::/relative/path.txt",S_OK}, + {"",S_FALSE}, + {"mk:MSITSTORE:C:\\dir\\file.chm::/relative/path.txt",S_OK}, + {"mk",S_OK}, + {"",S_FALSE}, + {"",S_FALSE} + }, + { + {Uri_HOST_UNKNOWN,S_OK}, + {0,S_FALSE}, + {URL_SCHEME_MK,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } + }, + { "mk:@MSITSTORE:C:\\dir\\file.chm::/subdir/../../file.txt",0, + "/relative/path.txt",Uri_CREATE_ALLOW_RELATIVE, + 0,S_OK,FALSE, + { + {"mk:@MSITSTORE:/relative/path.txt",S_OK}, + {"",S_FALSE}, + {"mk:@MSITSTORE:/relative/path.txt",S_OK}, + {"",S_FALSE}, + {".txt",S_OK}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + {"@MSITSTORE:/relative/path.txt",S_OK}, + {"@MSITSTORE:/relative/path.txt",S_OK}, + {"",S_FALSE}, + {"mk:@MSITSTORE:/relative/path.txt",S_OK}, + {"mk",S_OK}, + {"",S_FALSE}, + {"",S_FALSE} + }, + { + {Uri_HOST_UNKNOWN,S_OK}, + {0,S_FALSE}, + {URL_SCHEME_MK,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } + }, + { "mk:@xxx:C:\\dir\\file.chm::/subdir/../../file.txt",0, + "/relative/path.txt",Uri_CREATE_ALLOW_RELATIVE, + 0,S_OK,FALSE, + { + {"mk:@xxx:/relative/path.txt",S_OK}, + {"",S_FALSE}, + {"mk:@xxx:/relative/path.txt",S_OK}, + {"",S_FALSE}, + {".txt",S_OK}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + {"@xxx:/relative/path.txt",S_OK}, + {"@xxx:/relative/path.txt",S_OK}, + {"",S_FALSE}, + {"mk:@xxx:/relative/path.txt",S_OK}, + {"mk",S_OK}, + {"",S_FALSE}, + {"",S_FALSE} + }, + { + {Uri_HOST_UNKNOWN,S_OK}, + {0,S_FALSE}, + {URL_SCHEME_MK,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } + }, + { "mk:xxx:C:\\dir\\file.chm::/subdir/../../file.txt",0, + "/relative/path.txt",Uri_CREATE_ALLOW_RELATIVE, + 0,S_OK,FALSE, + { + {"mk:/relative/path.txt",S_OK}, + {"",S_FALSE}, + {"mk:/relative/path.txt",S_OK}, + {"",S_FALSE}, + {".txt",S_OK}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + {"/relative/path.txt",S_OK}, + {"/relative/path.txt",S_OK}, + {"",S_FALSE}, + {"mk:/relative/path.txt",S_OK}, + {"mk",S_OK}, + {"",S_FALSE}, + {"",S_FALSE} + }, + { + {Uri_HOST_UNKNOWN,S_OK}, + {0,S_FALSE}, + {URL_SCHEME_MK,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } + }, + { "ml:@MSITSTORE:C:\\dir\\file.chm::/subdir/file.txt",0, + "/relative/path.txt",Uri_CREATE_ALLOW_RELATIVE, + 0,S_OK,FALSE, + { + {"ml:/relative/path.txt",S_OK}, + {"",S_FALSE}, + {"ml:/relative/path.txt",S_OK}, + {"",S_FALSE}, + {".txt",S_OK}, + {"",S_FALSE}, + {"",S_FALSE}, + {"",S_FALSE}, + {"/relative/path.txt",S_OK}, + {"/relative/path.txt",S_OK}, + {"",S_FALSE}, + {"ml:/relative/path.txt",S_OK}, + {"ml",S_OK}, + {"",S_FALSE}, + {"",S_FALSE} + }, + { + {Uri_HOST_UNKNOWN,S_OK}, + {0,S_FALSE}, + {URL_SCHEME_UNKNOWN,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } + }, + { "http://winehq.org/dir/test?querystring",0, + "//winehq.com/#hash",Uri_CREATE_ALLOW_RELATIVE, + 0,S_OK,FALSE, + { + {"http://winehq.com/#hash",S_OK}, + {"winehq.com",S_OK}, + {"http://winehq.com/#hash",S_OK}, + {"winehq.com",S_OK}, + {"",S_FALSE}, + {"#hash",S_OK}, + {"winehq.com",S_OK}, + {"",S_FALSE}, + {"/",S_OK}, + {"/",S_OK}, + {"",S_FALSE}, + {"http://winehq.com/#hash",S_OK}, + {"http",S_OK}, + {"",S_FALSE}, + {"",S_FALSE} + }, + { + {Uri_HOST_DNS,S_OK}, + {80,S_OK,FALSE,TRUE}, + {URL_SCHEME_HTTP,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } + }, + { "http://winehq.org/dir/test?querystring",0, + "//winehq.com/dir2/../dir/file.txt?query#hash",Uri_CREATE_ALLOW_RELATIVE, + 0,S_OK,FALSE, + { + {"http://winehq.com/dir/file.txt?query#hash",S_OK}, + {"winehq.com",S_OK}, + {"http://winehq.com/dir/file.txt?query#hash",S_OK}, + {"winehq.com",S_OK}, + {".txt",S_OK}, + {"#hash",S_OK}, + {"winehq.com",S_OK}, + {"",S_FALSE}, + {"/dir/file.txt",S_OK}, + {"/dir/file.txt?query",S_OK}, + {"?query",S_OK}, + {"http://winehq.com/dir/file.txt?query#hash",S_OK}, + {"http",S_OK}, + {"",S_FALSE}, + {"",S_FALSE} + }, + { + {Uri_HOST_DNS,S_OK}, + {80,S_OK,FALSE,TRUE}, + {URL_SCHEME_HTTP,S_OK}, + {URLZONE_INVALID,E_NOTIMPL} + } } }; @@ -7342,27 +8116,28 @@ static void test_IUri_HasProperty(void) { static void test_IUri_IsEqual(void) { IUri *uriA, *uriB; - HRESULT hrA, hrB; + BOOL equal; + HRESULT hres; DWORD i; uriA = uriB = NULL; /* Make sure IsEqual handles invalid args correctly. */ - hrA = pCreateUri(http_urlW, 0, 0, &uriA); - hrB = pCreateUri(http_urlW, 0, 0, &uriB); - ok(hrA == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hrA, S_OK); - ok(hrB == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hrB, S_OK); - if(SUCCEEDED(hrA) && SUCCEEDED(hrB)) { - BOOL equal = -1; - hrA = IUri_IsEqual(uriA, NULL, &equal); - ok(hrA == S_OK, "Error: IsEqual returned 0x%08x, expected 0x%08x.\n", hrA, S_OK); - ok(equal == FALSE, "Error: Expected equal to be FALSE, but was %d instead.\n", equal); + hres = pCreateUri(http_urlW, 0, 0, &uriA); + ok(hres == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hres, S_OK); + hres = pCreateUri(http_urlW, 0, 0, &uriB); + ok(hres == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x.\n", hres, S_OK); - hrA = IUri_IsEqual(uriA, uriB, NULL); - ok(hrA == E_POINTER, "Error: IsEqual returned 0x%08x, expected 0x%08x.\n", hrA, E_POINTER); - } - if(uriA) IUri_Release(uriA); - if(uriB) IUri_Release(uriB); + equal = -1; + hres = IUri_IsEqual(uriA, NULL, &equal); + ok(hres == S_OK, "Error: IsEqual returned 0x%08x, expected 0x%08x.\n", hres, S_OK); + ok(!equal, "Error: Expected equal to be FALSE, but was %d instead.\n", equal); + + hres = IUri_IsEqual(uriA, uriB, NULL); + ok(hres == E_POINTER, "Error: IsEqual returned 0x%08x, expected 0x%08x.\n", hres, E_POINTER); + + IUri_Release(uriA); + IUri_Release(uriB); for(i = 0; i < sizeof(equality_tests)/sizeof(equality_tests[0]); ++i) { uri_equality test = equality_tests[i]; @@ -7373,44 +8148,20 @@ static void test_IUri_IsEqual(void) { uriA_W = a2w(test.a); uriB_W = a2w(test.b); - hrA = pCreateUri(uriA_W, test.create_flags_a, 0, &uriA); - if(test.create_todo_a) { - todo_wine { - ok(hrA == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x on equality_tests[%d].a\n", - hrA, S_OK, i); - } + hres = pCreateUri(uriA_W, test.create_flags_a, 0, &uriA); + ok(hres == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x on equality_tests[%d].a\n", hres, S_OK, i); + + hres = pCreateUri(uriB_W, test.create_flags_b, 0, &uriB); + ok(hres == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x on equality_tests[%d].b\n", hres, S_OK, i); + + equal = -1; + hres = IUri_IsEqual(uriA, uriB, &equal); + if(test.todo) todo_wine { + ok(hres == S_OK, "Error: IsEqual returned 0x%08x, expected 0x%08x on equality_tests[%d].\n", hres, S_OK, i); + ok(equal == test.equal, "Error: Expected the comparison to be %d on equality_tests[%d].\n", test.equal, i); } else { - ok(hrA == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x on equality_tests[%d].a\n", - hrA, S_OK, i); - } - - hrB = pCreateUri(uriB_W, test.create_flags_b, 0, &uriB); - if(test.create_todo_b) { - todo_wine { - ok(hrB == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x on equality_tests[%d].b\n", - hrB, S_OK, i); - } - } else { - ok(hrB == S_OK, "Error: CreateUri returned 0x%08x, expected 0x%08x on equality_tests[%d].b\n", - hrB, S_OK, i); - } - - if(SUCCEEDED(hrA) && SUCCEEDED(hrB)) { - BOOL equal = -1; - - hrA = IUri_IsEqual(uriA, uriB, &equal); - if(test.todo) { - todo_wine { - ok(hrA == S_OK, "Error: IsEqual returned 0x%08x, expected 0x%08x on equality_tests[%d].\n", - hrA, S_OK, i); - } - todo_wine { - ok(equal == test.equal, "Error: Expected the comparison to be %d on equality_tests[%d].\n", test.equal, i); - } - } else { - ok(hrA == S_OK, "Error: IsEqual returned 0x%08x, expected 0x%08x on equality_tests[%d].\n", hrA, S_OK, i); - ok(equal == test.equal, "Error: Expected the comparison to be %d on equality_tests[%d].\n", test.equal, i); - } + ok(hres == S_OK, "Error: IsEqual returned 0x%08x, expected 0x%08x on equality_tests[%d].\n", hres, S_OK, i); + ok(equal == test.equal, "Error: Expected the comparison to be %d on equality_tests[%d].\n", test.equal, i); } if(uriA) IUri_Release(uriA); if(uriB) IUri_Release(uriB); @@ -9524,11 +10275,12 @@ static void test_CoInternetCombineIUri(void) { prop.value, received, i, j); } } else { - ok(hr == prop.expected, + ok(hr == prop.expected || broken(prop.broken_combine_hres && hr == S_FALSE), "Error: IUri_GetPropertyDWORD returned 0x%08x, expected 0x%08x on uri_combine_tests[%d].dword_props[%d].\n", hr, prop.expected, i, j); - ok(prop.value == received, "Error: Expected %d, but got %d instead on uri_combine_tests[%d].dword_props[%d].\n", - prop.value, received, i, j); + if(!prop.broken_combine_hres || hr != S_FALSE) + ok(prop.value == received, "Error: Expected %d, but got %d instead on uri_combine_tests[%d].dword_props[%d].\n", + prop.value, received, i, j); } } } @@ -9840,11 +10592,12 @@ static void test_CoInternetCombineUrlEx(void) { prop.value, received, i, j); } } else { - ok(hr == prop.expected, + ok(hr == prop.expected || broken(prop.broken_combine_hres && hr == S_FALSE), "Error: IUri_GetPropertyDWORD returned 0x%08x, expected 0x%08x on uri_combine_tests[%d].dword_props[%d].\n", hr, prop.expected, i, j); - ok(prop.value == received, "Error: Expected %d, but got %d instead on uri_combine_tests[%d].dword_props[%d].\n", - prop.value, received, i, j); + if(!prop.broken_combine_hres || hr != S_FALSE) + ok(prop.value == received, "Error: Expected %d, but got %d instead on uri_combine_tests[%d].dword_props[%d].\n", + prop.value, received, i, j); } } } @@ -10027,6 +10780,535 @@ static void test_CoInternetParseIUri_Pluggable(void) { if(uri) IUri_Release(uri); } +typedef struct { + const char *url; + DWORD uri_flags; + const char *base_url; + DWORD base_uri_flags; + const char *legacy_url; + const char *uniform_url; + const char *no_canon_url; + const char *uri_url; +} create_urlmon_test_t; + +static const create_urlmon_test_t create_urlmon_tests[] = { + { + "http://www.winehq.org",Uri_CREATE_NO_CANONICALIZE, + NULL,0, + "http://www.winehq.org/", + "http://www.winehq.org/", + "http://www.winehq.org", + "http://www.winehq.org" + }, + { + "file://c:\\dir\\file.txt",Uri_CREATE_NO_CANONICALIZE, + NULL,0, + "file://c:\\dir\\file.txt", + "file:///c:/dir/file.txt", + "file:///c:/dir/file.txt", + "file:///c:/dir/file.txt" + }, + { + "file://c:\\dir\\file.txt",Uri_CREATE_FILE_USE_DOS_PATH, + NULL,0, + "file://c:\\dir\\file.txt", + "file:///c:/dir/file.txt", + "file:///c:/dir/file.txt", + "file://c:\\dir\\file.txt" + }, + { + "dat%61",Uri_CREATE_ALLOW_RELATIVE, + "http://www.winehq.org",0, + "http://www.winehq.org/data", + "http://www.winehq.org/data", + "http://www.winehq.org:80/data", + }, + { + "file.txt",Uri_CREATE_ALLOW_RELATIVE, + "file://c:\\dir\\x.txt",Uri_CREATE_NO_CANONICALIZE, + "file://c:\\dir\\file.txt", + "file:///c:/dir/file.txt", + "file:///c:/dir/file.txt", + }, + { + "",Uri_CREATE_ALLOW_RELATIVE, + NULL,0, + "", + "", + "", + "" + }, + { + "test",Uri_CREATE_ALLOW_RELATIVE, + NULL,0, + "test", + "test", + "test", + "test" + }, + { + "c:\\dir\\file.txt",Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, + NULL,0, + "file://c:\\dir\\file.txt", + "file:///c:/dir/file.txt", + "file:///c:/dir/file.txt", + "file:///c:/dir/file.txt", + } +}; + +#define test_urlmon_display_name(a,b) _test_urlmon_display_name(__LINE__,a,b) +static void _test_urlmon_display_name(unsigned line, IMoniker *mon, const char *exurl) +{ + WCHAR *display_name; + HRESULT hres; + + hres = IMoniker_GetDisplayName(mon, NULL, NULL, &display_name); + ok_(__FILE__,line)(hres == S_OK, "GetDisplayName failed: %08x\n", hres); + ok_(__FILE__,line)(!strcmp_aw(exurl, display_name), "unexpected display name: %s, expected %s\n", + wine_dbgstr_w(display_name), exurl); + + CoTaskMemFree(display_name); +} + +#define test_display_uri(a,b) _test_display_uri(__LINE__,a,b) +static void _test_display_uri(unsigned line, IMoniker *mon, const char *exurl) +{ + IUriContainer *uri_container; + IUri *uri; + BSTR display_uri; + HRESULT hres; + + hres = IMoniker_QueryInterface(mon, &IID_IUriContainer, (void**)&uri_container); + ok(hres == S_OK, "Could not get IUriContainer iface: %08x\n", hres); + + uri = NULL; + hres = IUriContainer_GetIUri(uri_container, &uri); + IUriContainer_Release(uri_container); + ok(hres == S_OK, "GetIUri failed: %08x\n", hres); + ok(uri != NULL, "uri == NULL\n"); + + hres = IUri_GetDisplayUri(uri, &display_uri); + IUri_Release(uri); + ok(hres == S_OK, "GetDisplayUri failed: %08x\n", hres); + ok_(__FILE__,line)(!strcmp_aw(exurl, display_uri), "unexpected display uri: %s, expected %s\n", + wine_dbgstr_w(display_uri), exurl); + SysFreeString(display_uri); +} + +static void test_CreateURLMoniker(void) +{ + const create_urlmon_test_t *test; + IMoniker *mon, *base_mon; + WCHAR *url, *base_url; + IUri *uri, *base_uri; + HRESULT hres; + + for(test = create_urlmon_tests; test < create_urlmon_tests + sizeof(create_urlmon_tests)/sizeof(*create_urlmon_tests); test++) { + url = a2w(test->url); + base_url = a2w(test->base_url); + + if(base_url) { + hres = pCreateUri(base_url, test->base_uri_flags, 0, &base_uri); + ok(hres == S_OK, "CreateUri failed: %08x\n", hres); + + hres = pCreateURLMonikerEx2(NULL, base_uri, &base_mon, URL_MK_NO_CANONICALIZE); + ok(hres == S_OK, "CreateURLMonikerEx2 failed: %08x\n", hres); + }else { + base_uri = NULL; + base_mon = NULL; + } + + hres = CreateURLMoniker(base_mon, url, &mon); + ok(hres == S_OK, "CreateURLMoniker failed: %08x\n", hres); + test_urlmon_display_name(mon, test->legacy_url); + test_display_uri(mon, test->legacy_url); + IMoniker_Release(mon); + + hres = pCreateURLMonikerEx(base_mon, url, &mon, URL_MK_LEGACY); + ok(hres == S_OK, "CreateURLMoniker failed: %08x\n", hres); + test_urlmon_display_name(mon, test->legacy_url); + test_display_uri(mon, test->legacy_url); + IMoniker_Release(mon); + + hres = pCreateURLMonikerEx(base_mon, url, &mon, URL_MK_UNIFORM); + ok(hres == S_OK, "CreateURLMoniker failed: %08x\n", hres); + test_urlmon_display_name(mon, test->uniform_url); + test_display_uri(mon, test->uniform_url); + IMoniker_Release(mon); + + hres = pCreateURLMonikerEx(base_mon, url, &mon, URL_MK_NO_CANONICALIZE); + ok(hres == S_OK, "CreateURLMoniker failed: %08x\n", hres); + test_urlmon_display_name(mon, test->no_canon_url); + test_display_uri(mon, test->no_canon_url); + IMoniker_Release(mon); + + hres = pCreateUri(url, test->uri_flags, 0, &uri); + ok(hres == S_OK, "CreateUri failed: %08x\n", hres); + + hres = pCreateURLMonikerEx2(base_mon, uri, &mon, URL_MK_LEGACY); + ok(hres == S_OK, "CreateURLMonikerEx2 failed: %08x\n", hres); + test_urlmon_display_name(mon, base_url ? test->legacy_url : test->uri_url); + test_display_uri(mon, base_url ? test->legacy_url : test->uri_url); + IMoniker_Release(mon); + + hres = pCreateURLMonikerEx2(base_mon, uri, &mon, URL_MK_UNIFORM); + ok(hres == S_OK, "CreateURLMonikerEx2 failed: %08x\n", hres); + test_urlmon_display_name(mon, base_url ? test->uniform_url : test->uri_url); + test_display_uri(mon, base_url ? test->uniform_url : test->uri_url); + IMoniker_Release(mon); + + hres = pCreateURLMonikerEx2(base_mon, uri, &mon, URL_MK_NO_CANONICALIZE); + ok(hres == S_OK, "CreateURLMonikerEx2 failed: %08x\n", hres); + test_urlmon_display_name(mon, base_url ? test->no_canon_url : test->uri_url); + test_display_uri(mon, base_url ? test->no_canon_url : test->uri_url); + IMoniker_Release(mon); + + IUri_Release(uri); + heap_free(url); + heap_free(base_url); + if(base_uri) + IUri_Release(base_uri); + if(base_mon) + IMoniker_Release(base_mon); + } +} + +static int add_default_flags(DWORD flags) { + if(!(flags & Uri_CREATE_NO_CANONICALIZE)) + flags |= Uri_CREATE_CANONICALIZE; + if(!(flags & Uri_CREATE_NO_DECODE_EXTRA_INFO)) + flags |= Uri_CREATE_DECODE_EXTRA_INFO; + if(!(flags & Uri_CREATE_NO_CRACK_UNKNOWN_SCHEMES)) + flags |= Uri_CREATE_CRACK_UNKNOWN_SCHEMES; + if(!(flags & Uri_CREATE_NO_PRE_PROCESS_HTML_URI)) + flags |= Uri_CREATE_PRE_PROCESS_HTML_URI; + if(!(flags & Uri_CREATE_IE_SETTINGS)) + flags |= Uri_CREATE_NO_IE_SETTINGS; + + return flags; +} + +static void test_IPersistStream(void) +{ + int i, props_order[Uri_PROPERTY_DWORD_LAST+1] = { 0 }; + + props_order[Uri_PROPERTY_RAW_URI] = 1; + props_order[Uri_PROPERTY_FRAGMENT] = 2; + props_order[Uri_PROPERTY_HOST] = 3; + props_order[Uri_PROPERTY_PASSWORD] = 4; + props_order[Uri_PROPERTY_PATH] = 5; + props_order[Uri_PROPERTY_PORT] = 6; + props_order[Uri_PROPERTY_QUERY] = 7; + props_order[Uri_PROPERTY_SCHEME_NAME] = 8; + props_order[Uri_PROPERTY_USER_NAME] = 9; + + for(i=0; icreate_todo || test->create_expected!=S_OK) + continue; + + uriW = a2w(test->uri); + hr = pCreateUri(uriW, test->create_flags, 0, &uri); + ok(hr == S_OK, "%d) CreateUri failed 0x%08x, expected S_OK..\n", i, hr); + + hr = IUri_QueryInterface(uri, &IID_IPersistStream, (void**)&persist_stream); + ok(hr == S_OK, "%d) QueryInterface failed 0x%08x, expected S_OK.\n", i, hr); + + hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); + ok(hr == S_OK, "CreateStreamOnHGlobal failed 0x%08x.\n", hr); + hr = IPersistStream_IsDirty(persist_stream); + ok(hr == S_FALSE, "%d) IsDirty returned 0x%08x, expected S_FALSE.\n", i, hr); + hr = IPersistStream_Save(persist_stream, stream, FALSE); + ok(hr == S_OK, "%d) Save failed 0x%08x, expected S_OK.\n", i, hr); + hr = IPersistStream_IsDirty(persist_stream); + ok(hr == S_FALSE, "%d) IsDirty returned 0x%08x, expected S_FALSE.\n", i, hr); + no_off.QuadPart = 0; + hr = IStream_Seek(stream, no_off, STREAM_SEEK_CUR, &size); + ok(hr == S_OK, "%d) Seek failed 0x%08x, expected S_OK.\n", i, hr); + hr = IStream_Seek(stream, no_off, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "%d) Seek failed 0x%08x, expected S_OK.\n", i, hr); + hr = IPersistStream_GetSizeMax(persist_stream, &max_size); + ok(hr == S_OK, "%d) GetSizeMax failed 0x%08x, expected S_OK.\n", i, hr); + ok(U(size).LowPart+2 == U(max_size).LowPart, + "%d) Written data size is %d, max_size %d.\n", + i, U(size).LowPart, U(max_size).LowPart); + + hr = IStream_Read(stream, (void*)dw_data, sizeof(DWORD), NULL); + ok(hr == S_OK, "%d) Read failed 0x%08x, expected S_OK.\n", i, hr); + ok(dw_data[0]-2 == U(size).LowPart, "%d) Structure size is %d, expected %d\n", + i, dw_data[0]-2, U(size).LowPart); + hr = IStream_Read(stream, (void*)dw_data, 6*sizeof(DWORD), NULL); + ok(hr == S_OK, "%d) Read failed 0x%08x, expected S_OK.\n", i, hr); + ok(dw_data[0] == 0, "%d) Incorrect value %x, expected 0 (unknown).\n", i, dw_data[0]); + ok(dw_data[1] == 0, "%d) Incorrect value %x, expected 0 (unknown).\n", i, dw_data[1]); + ok(dw_data[2] == add_default_flags(test->create_flags), + "%d) Incorrect value %x, expected %x (creation flags).\n", + i, dw_data[2], add_default_flags(test->create_flags)); + ok(dw_data[3] == 0, "%d) Incorrect value %x, expected 0 (unknown).\n", i, dw_data[3]); + ok(dw_data[4] == 0, "%d) Incorrect value %x, expected 0 (unknown).\n", i, dw_data[4]); + ok(dw_data[5] == 0, "%d) Incorrect value %x, expected 0 (unknown).\n", i, dw_data[5]); + + props_no = 0; + for(props=0; props<=Uri_PROPERTY_DWORD_LAST; props++) { + if(!props_order[props]) + continue; + + if(props <= Uri_PROPERTY_STRING_LAST) { + if(test->str_props[props].expected == S_OK) + props_no++; + } else { + if(test->dword_props[props-Uri_PROPERTY_DWORD_START].expected == S_OK) + props_no++; + } + } + if(test->dword_props[Uri_PROPERTY_SCHEME-Uri_PROPERTY_DWORD_START].value != URL_SCHEME_HTTP + && test->dword_props[Uri_PROPERTY_SCHEME-Uri_PROPERTY_DWORD_START].value != URL_SCHEME_FTP + && test->dword_props[Uri_PROPERTY_SCHEME-Uri_PROPERTY_DWORD_START].value != URL_SCHEME_HTTPS) + props_no = 1; + + hr = IStream_Read(stream, (void*)&props, sizeof(DWORD), NULL); + ok(hr == S_OK, "%d) Read failed 0x%08x, expected S_OK.\n", i, hr); + ok(props == props_no, "%d) Properties no is %d, expected %d.\n", i, props, props_no); + + dw_data[2] = 0; + dw_data[3] = -1; + while(props) { + hr = IStream_Read(stream, (void*)dw_data, 2*sizeof(DWORD), NULL); + ok(hr == S_OK, "%d) Read failed 0x%08x, expected S_OK.\n", i, hr); + props--; + ok(dw_data[2]str_props+dw_data[0]; + hr = IStream_Read(stream, (void*)str_data, dw_data[1], NULL); + ok(hr == S_OK, "%d) Read failed 0x%08x, expected S_OK.\n", i, hr); + ok(!strcmp_aw(prop->value, str_data) || broken(prop->broken_value && !strcmp_aw(prop->broken_value, str_data)), + "%d) Expected %s but got %s (%d).\n", i, prop->value, wine_dbgstr_w(str_data), dw_data[0]); + } else if(dw_data[0]>=Uri_PROPERTY_DWORD_START && dw_data[0]<=Uri_PROPERTY_DWORD_LAST) { + const uri_dword_property *prop = test->dword_props+dw_data[0]-Uri_PROPERTY_DWORD_START; + ok(dw_data[1] == sizeof(DWORD), "%d) Size of dword property is %d (%d)\n", i, dw_data[1], dw_data[0]); + hr = IStream_Read(stream, (void*)&dw_data[1], sizeof(DWORD), NULL); + ok(hr == S_OK, "%d) Read failed 0x%08x, expected S_OK.\n", i, hr); + ok(prop->value == dw_data[1], "%d) Expected %d but got %d (%d).\n", i, prop->value, dw_data[1], dw_data[0]); + } else { + ok(FALSE, "%d) Incorrect property type (%d)\n", i, dw_data[0]); + break; + } + } + ok(props == 0, "%d) Not all properties were processed %d. Next property type: %d\n", + i, props, dw_data[0]); + + IPersistStream_Release(persist_stream); + IUri_Release(uri); + + hr = IStream_Seek(stream, no_off, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "%d) Seek failed 0x%08x, expected S_OK.\n", i, hr); + hr = IPersistStream_GetClassID(persist_stream, &curi); + ok(hr == S_OK, "%d) GetClassID failed 0x%08x, expected S_OK.\n", i, hr); + ok(IsEqualCLSID(&curi, &CLSID_CUri), "%d) GetClassID returned incorrect CLSID.\n", i); + hr = CoCreateInstance(&curi, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, + &IID_IUri, (void**)&uri); + ok(hr == S_OK, "%d) Error creating uninitialized Uri: 0x%08x.\n", i, hr); + hr = IUri_QueryInterface(uri, &IID_IPersistStream, (void**)&persist_stream); + ok(hr == S_OK, "%d) QueryInterface failed 0x%08x, expected S_OK.\n", i, hr); + hr = IPersistStream_Load(persist_stream, stream); + ok(hr == S_OK, "%d) Load failed 0x%08x, expected S_OK.\n", i, hr); + hr = IUri_GetRawUri(uri, &raw_uri); + ok(hr == S_OK, "%d) GetRawUri failed 0x%08x, expected S_OK.\n", i, hr); + ok(!strcmp_aw(test->str_props[Uri_PROPERTY_RAW_URI].value, raw_uri) + || broken(test->str_props[Uri_PROPERTY_RAW_URI].broken_value + && !strcmp_aw(test->str_props[Uri_PROPERTY_RAW_URI].broken_value, raw_uri)), + "%d) Expected %s but got %s.\n", i, test->str_props[Uri_PROPERTY_RAW_URI].value, + wine_dbgstr_w(raw_uri)); + SysFreeString(raw_uri); + + hr = IUri_QueryInterface(uri, &IID_IMarshal, (void**)&marshal); + ok(hr == S_OK, "%d) QueryInterface(IID_IMarshal) failed 0x%08x, expected S_OK.\n", i, hr); + hr = IStream_Seek(stream, no_off, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "%d) Seek failed 0x%08x, expected S_OK.\n", i, hr); + hr = IMarshal_MarshalInterface(marshal, stream, &IID_IUri, (void*)uri, + MSHCTX_DIFFERENTMACHINE, NULL, MSHLFLAGS_NORMAL); + ok(hr == E_INVALIDARG, "%d) MarshalInterface returned 0x%08x, expected E_INVALIDARG.\n", i, hr); + hr = IMarshal_MarshalInterface(marshal, stream, &IID_IUri, (void*)uri, + MSHCTX_CROSSCTX, NULL, MSHLFLAGS_NORMAL); + ok(hr == E_INVALIDARG, "%d) MarshalInterface returned 0x%08x, expected E_INVALIDARG.\n", i, hr); + hr = IMarshal_MarshalInterface(marshal, stream, &IID_IUri, (void*)uri, + MSHCTX_LOCAL, NULL, MSHLFLAGS_TABLESTRONG); + ok(hr == E_INVALIDARG, "%d) MarshalInterface returned 0x%08x, expected E_INVALIDARG.\n", i, hr); + hr = IMarshal_MarshalInterface(marshal, stream, &IID_IUri, (void*)uri, + MSHCTX_LOCAL, NULL, MSHLFLAGS_TABLEWEAK); + ok(hr == E_INVALIDARG, "%d) MarshalInterface returned 0x%08x, expected E_INVALIDARG.\n", i, hr); + hr = IMarshal_MarshalInterface(marshal, stream, &IID_IUri, (void*)uri, + MSHCTX_LOCAL, NULL, MSHLFLAGS_NOPING); + ok(hr == E_INVALIDARG, "%d) MarshalInterface returned 0x%08x, expected E_INVALIDARG.\n", i, hr); + hr = IMarshal_MarshalInterface(marshal, stream, &IID_IUri, (void*)uri, + MSHCTX_LOCAL, NULL, MSHLFLAGS_NORMAL); + ok(hr == S_OK, "%d) MarshalInterface failed 0x%08x, expected S_OK.\n", i, hr); + hr = IMarshal_GetUnmarshalClass(marshal, &IID_IUri, (void*)uri, + MSHCTX_CROSSCTX, NULL, MSHLFLAGS_NORMAL, &curi); + ok(hr == E_INVALIDARG, "%d) GetUnmarshalClass returned 0x%08x, expected E_INVALIDARG.\n", i, hr); + hr = IMarshal_GetUnmarshalClass(marshal, &IID_IUri, (void*)uri, + MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL, &curi); + ok(hr == S_OK, "%d) GetUnmarshalClass failed 0x%08x, expected S_OK.\n", i, hr); + ok(IsEqualCLSID(&curi, &CLSID_CUri), "%d) GetUnmarshalClass returned incorrect CLSID.\n", i); + + hr = IStream_Seek(stream, no_off, STREAM_SEEK_CUR, &size); + ok(hr == S_OK, "%d) Seek failed 0x%08x, expected S_OK.\n", i, hr); + hr = IStream_Seek(stream, no_off, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "%d) Seek failed 0x%08x, expected S_OK.\n", i, hr); + hr = IStream_Read(stream, (void*)dw_data, 3*sizeof(DWORD), NULL); + ok(hr == S_OK, "%d) Read failed 0x%08x, expected S_OK.\n", i, hr); + ok(dw_data[0]-2 == U(size).LowPart, "%d) Structure size is %d, expected %d\n", + i, dw_data[0]-2, U(size).LowPart); + ok(dw_data[1] == MSHCTX_LOCAL, "%d) Incorrect value %d, expected MSHCTX_LOCAL.\n", + i, dw_data[1]); + ok(dw_data[2] == dw_data[0]-8, "%d) Incorrect value %d, expected %d (PersistStream size).\n", + i, dw_data[2], dw_data[0]-8); + if(!test->str_props[Uri_PROPERTY_PATH].value[0] && + (test->dword_props[Uri_PROPERTY_SCHEME-Uri_PROPERTY_DWORD_START].value == URL_SCHEME_HTTP + || test->dword_props[Uri_PROPERTY_SCHEME-Uri_PROPERTY_DWORD_START].value == URL_SCHEME_FTP + || test->dword_props[Uri_PROPERTY_SCHEME-Uri_PROPERTY_DWORD_START].value == URL_SCHEME_HTTPS)) + U(max_size).LowPart += 3*sizeof(DWORD); + ok(dw_data[2] == U(max_size).LowPart, "%d) Incorrect value %d, expected %d (PersistStream size).\n", + i, dw_data[2], U(max_size).LowPart); + IMarshal_Release(marshal); + IUri_Release(uri); + + hr = IStream_Seek(stream, no_off, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "%d) Seek failed 0x%08x, expected S_OK.\n", i, hr); + hr = CoCreateInstance(&curi, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, + &IID_IUri, (void**)&uri); + ok(hr == S_OK, "%d) Error creating uninitialized Uri: 0x%08x.\n", i, hr); + hr = IUri_QueryInterface(uri, &IID_IMarshal, (void**)&marshal); + ok(hr == S_OK, "%d) QueryInterface failed 0x%08x, expected S_OK.\n", i, hr); + hr = IMarshal_UnmarshalInterface(marshal, stream, &IID_IUri, (void**)&uri); + ok(hr == S_OK, "%d) UnmarshalInterface failed 0x%08x, expected S_OK.\n", i, hr); + hr = IUri_GetRawUri(uri, &raw_uri); + ok(hr == S_OK, "%d) GetRawUri failed 0x%08x, expected S_OK.\n", i, hr); + ok(!strcmp_aw(test->str_props[Uri_PROPERTY_RAW_URI].value, raw_uri) + || broken(test->str_props[Uri_PROPERTY_RAW_URI].broken_value + && !strcmp_aw(test->str_props[Uri_PROPERTY_RAW_URI].broken_value, raw_uri)), + "%d) Expected %s but got %s.\n", i, test->str_props[Uri_PROPERTY_RAW_URI].value, + wine_dbgstr_w(raw_uri)); + SysFreeString(raw_uri); + + IMarshal_Release(marshal); + IStream_Release(stream); + IPersistStream_Release(persist_stream); + IUri_Release(uri); + heap_free(uriW); + } +} + +static void test_UninitializedUri(void) +{ + IUri *uri; + IUriBuilderFactory *ubf; + IPersistStream *ps; + IUriBuilder *ub; + BSTR bstr; + DWORD dword; + BOOL eq; + ULARGE_INTEGER ui; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_CUri, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, + &IID_IUri, (void**)&uri); + if(FAILED(hr)) { + win_skip("Skipping uninitialized Uri tests.\n"); + return; + } + + hr = IUri_QueryInterface(uri, &IID_IUriBuilderFactory, (void**)&ubf); + ok(hr == S_OK, "QueryInterface(IID_IUriBuillderFactory) failed: %x.\n", hr); + hr = IUri_QueryInterface(uri, &IID_IPersistStream, (void**)&ps); + ok(hr == S_OK, "QueryInterface(IID_IPersistStream) failed: %x.\n", hr); + + hr = IUri_GetAbsoluteUri(uri, NULL); + ok(hr == E_UNEXPECTED, "GetAbsoluteUri returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetAbsoluteUri(uri, &bstr); + ok(hr == E_UNEXPECTED, "GetAbsoluteUri returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetAuthority(uri, &bstr); + ok(hr == E_UNEXPECTED, "GetAuthority returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetDisplayUri(uri, &bstr); + ok(hr == E_UNEXPECTED, "GetDisplayUri returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetDomain(uri, &bstr); + ok(hr == E_UNEXPECTED, "GetDomain returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetExtension(uri, &bstr); + ok(hr == E_UNEXPECTED, "GetExtension returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetFragment(uri, &bstr); + ok(hr == E_UNEXPECTED, "GetFragment returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetHost(uri, &bstr); + ok(hr == E_UNEXPECTED, "GetHost returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetHostType(uri, &dword); + ok(hr == E_UNEXPECTED, "GetHostType returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetPassword(uri, &bstr); + ok(hr == E_UNEXPECTED, "GetPassword returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetPassword(uri, &bstr); + ok(hr == E_UNEXPECTED, "GetPassword returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetPathAndQuery(uri, &bstr); + ok(hr == E_UNEXPECTED, "GetPathAndQuery returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetPort(uri, &dword); + ok(hr == E_UNEXPECTED, "GetPort returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetProperties(uri, &dword); + ok(hr == E_UNEXPECTED, "GetProperties returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetPropertyBSTR(uri, Uri_PROPERTY_RAW_URI, &bstr, 0); + ok(hr == E_UNEXPECTED, "GetPropertyBSTR returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetPropertyDWORD(uri, Uri_PROPERTY_PORT, &dword, 0); + ok(hr == E_UNEXPECTED, "GetPropertyDWORD returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetPropertyLength(uri, Uri_PROPERTY_RAW_URI, &dword, 0); + ok(hr == E_UNEXPECTED, "GetPropertyLength returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetQuery(uri, &bstr); + ok(hr == E_UNEXPECTED, "GetQuery returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetRawUri(uri, &bstr); + ok(hr == E_UNEXPECTED, "GetRawUri returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetScheme(uri, &dword); + ok(hr == E_UNEXPECTED, "GetScheme returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetSchemeName(uri, &bstr); + ok(hr == E_UNEXPECTED, "GetSchemeName returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetUserInfo(uri, &bstr); + ok(hr == E_UNEXPECTED, "GetUserInfo returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetUserName(uri, &bstr); + ok(hr == E_UNEXPECTED, "GetUserName returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_GetZone(uri, &dword); + ok(hr == E_UNEXPECTED, "GetZone returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUri_IsEqual(uri, uri, &eq); + ok(hr == E_UNEXPECTED, "IsEqual returned %x, expected E_UNEXPECTED.\n", hr); + + hr = IUriBuilderFactory_CreateInitializedIUriBuilder(ubf, 0, 0, &ub); + ok(hr == E_UNEXPECTED, "CreateInitializedIUriBuilder returned %x, expected E_UNEXPECTED.\n", hr); + hr = IUriBuilderFactory_CreateIUriBuilder(ubf, 0, 0, &ub); + ok(hr == S_OK, "CreateIUriBuilder returned %x, expected S_OK.\n", hr); + IUriBuilder_Release(ub); + + hr = IPersistStream_GetSizeMax(ps, &ui); + ok(hr == S_OK, "GetSizeMax returned %x, expected S_OK.\n", hr); + ok(ui.u.LowPart == 34, "ui.LowPart = %d, expected 34.\n", ui.u.LowPart); + hr = IPersistStream_IsDirty(ps); + ok(hr == S_FALSE, "IsDirty returned %x, expected S_FALSE.\n", hr); + + IPersistStream_Release(ps); + IUriBuilderFactory_Release(ubf); + IUri_Release(uri); +} + START_TEST(uri) { HMODULE hurlmon; @@ -10038,6 +11320,8 @@ START_TEST(uri) { pCoInternetCombineIUri = (void*) GetProcAddress(hurlmon, "CoInternetCombineIUri"); pCoInternetCombineUrlEx = (void*) GetProcAddress(hurlmon, "CoInternetCombineUrlEx"); pCoInternetParseIUri = (void*) GetProcAddress(hurlmon, "CoInternetParseIUri"); + pCreateURLMonikerEx = (void*) GetProcAddress(hurlmon, "CreateURLMonikerEx"); + pCreateURLMonikerEx2 = (void*) GetProcAddress(hurlmon, "CreateURLMonikerEx2"); if(!pCreateUri) { win_skip("CreateUri is not present, skipping tests.\n"); @@ -10136,5 +11420,17 @@ START_TEST(uri) { trace("test CoInternetParseIUri pluggable...\n"); test_CoInternetParseIUri_Pluggable(); + trace("test CreateURLMoniker...\n"); + test_CreateURLMoniker(); + + CoInitialize(NULL); + + trace("test IPersistStream...\n"); + test_IPersistStream(); + + trace("test uninitialized Uri...\n"); + test_UninitializedUri(); + + CoUninitialize(); unregister_protocols(); } diff --git a/rostests/winetests/urlmon/url.c b/rostests/winetests/urlmon/url.c index eb4d31625a5..5a4a52007b5 100644 --- a/rostests/winetests/urlmon/url.c +++ b/rostests/winetests/urlmon/url.c @@ -19,21 +19,29 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +//#include #include #define COBJMACROS #define NONAMELESSUNION #define CONST_VTABLE -#include "windef.h" -#include "winbase.h" -#include "initguid.h" -#include "urlmon.h" -#include "wininet.h" -#include "mshtml.h" +#include +#include +#include +#include +#include +#include +//#include "initguid.h" +//#include "urlmon.h" +#include +#include -#include "wine/test.h" +#include static HRESULT (WINAPI *pCreateAsyncBindCtxEx)(IBindCtx *, DWORD, IBindStatusCallback *, IEnumFORMATETC *, IBindCtx **, DWORD); @@ -42,6 +50,7 @@ static HRESULT (WINAPI *pCreateUri)(LPCWSTR, DWORD, DWORD_PTR, IUri**); DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); DEFINE_GUID(CLSID_IdentityUnmarshal,0x0000001b,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); DEFINE_GUID(IID_IBindStatusCallbackHolder,0x79eac9cc,0xbaf9,0x11ce,0x8c,0x82,0x00,0xaa,0x00,0x4b,0xa9,0x0b); +extern CLSID CLSID_AboutProtocol; #define DEFINE_EXPECT(func) \ static BOOL expect_ ## func = FALSE, called_ ## func = FALSE @@ -149,29 +158,7 @@ DEFINE_EXPECT(OnSecurityProblem); static const WCHAR winetest_data_urlW[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/', 't','e','s','t','s','/','d','a','t','a','.','p','h','p',0}; - -static const WCHAR TEST_PART_URL_1[] = {'/','t','e','s','t','s','/','d','a','t','a','.','p','h','p','\0'}; - -static const WCHAR winetest_post_urlW[] = - {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/', - 't','e','s','t','s','/','p','o','s','t','.','p','h','p',0}; -static const WCHAR ABOUT_BLANK[] = {'a','b','o','u','t',':','b','l','a','n','k',0}; -static WCHAR INDEX_HTML[MAX_PATH]; -static const WCHAR ITS_URL[] = - {'i','t','s',':','t','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0}; -static const WCHAR MK_URL[] = {'m','k',':','@','M','S','I','T','S','t','o','r','e',':', - 't','e','s','t','.','c','h','m',':',':','/','b','l','a','n','k','.','h','t','m','l',0}; -static const WCHAR https_urlW[] = - {'h','t','t','p','s',':','/','/','w','w','w','.','c','o','d','e','w','e','a','v','e','r','s','.','c','o','m', - '/','t','e','s','t','.','h','t','m','l',0}; -static const WCHAR https_invalid_cn_urlW[] = - {'h','t','t','p','s',':','/','/','2','0','9','.','4','6','.','2','5','.','1','3','2', - '/','t','e','s','t','.','h','t','m','l',0}; -static const WCHAR ftp_urlW[] = {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g', - '/','p','u','b','/','o','t','h','e','r','/', - 'w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0}; -static const WCHAR winetest_urlW[] = {'w','i','n','e','t','e','s','t',':','t','e','s','t',0}; - +static const WCHAR about_blankW[] = {'a','b','o','u','t',':','b','l','a','n','k',0}; static const WCHAR wszTextHtml[] = {'t','e','x','t','/','h','t','m','l',0}; @@ -190,8 +177,9 @@ static const CHAR test_txtA[] = "test.txt"; static const WCHAR emptyW[] = {0}; static BOOL stopped_binding = FALSE, stopped_obj_binding = FALSE, emulate_protocol = FALSE, - data_available = FALSE, http_is_first = TRUE, bind_to_object = FALSE, filedwl_api; + data_available = FALSE, http_is_first = TRUE, bind_to_object = FALSE, filedwl_api, post_test; static DWORD read = 0, bindf = 0, prot_state = 0, thread_id, tymed, security_problem; +static const WCHAR *reported_url; static CHAR mime_type[512]; static IInternetProtocolSink *protocol_sink = NULL; static IBinding *current_binding; @@ -206,19 +194,9 @@ static BOOL only_check_prot_args = FALSE; static BOOL invalid_cn_accepted = FALSE; static BOOL abort_start = FALSE; static BOOL abort_progress = FALSE; +static BOOL async_switch = FALSE; -static LPCWSTR urls[] = { - winetest_data_urlW, - ABOUT_BLANK, - INDEX_HTML, - ITS_URL, - MK_URL, - https_urlW, - ftp_urlW, - winetest_urlW -}; - -static WCHAR file_url[INTERNET_MAX_URL_LENGTH]; +static WCHAR file_url[INTERNET_MAX_URL_LENGTH], current_url[INTERNET_MAX_URL_LENGTH]; static enum { HTTP_TEST, @@ -228,7 +206,8 @@ static enum { MK_TEST, HTTPS_TEST, FTP_TEST, - WINETEST_TEST + WINETEST_TEST, + WINETEST_SYNC_TEST } test_protocol; static enum { @@ -317,6 +296,8 @@ static void test_create(void) IBindCtx *bctx; HRESULT hr; + static const WCHAR TEST_PART_URL_1[] = {'/','t','e','s','t','s','/','d','a','t','a','.','p','h','p',0}; + test_CreateURLMoniker(winetest_data_urlW, TEST_PART_URL_1); mon = (void*)0xdeadbeef; @@ -324,6 +305,7 @@ static void test_create(void) ok(hr == S_OK, "got 0x%08x\n", hr); hr = CreateBindCtx(0, &bctx); + ok(hr == S_OK, "got 0x%08x\n", hr); stream = (void*)0xdeadbeef; hr = IMoniker_BindToStorage(mon, bctx, NULL, &IID_IStream, (void**)&stream); @@ -434,7 +416,7 @@ static ULONG WINAPI Protocol_Release(IInternetProtocol *iface) static void test_switch_fail(void) { IInternetProtocolSink *binding_sink; - PROTOCOLDATA protocoldata; + PROTOCOLDATA protocoldata = {0}; HRESULT hres; static BOOL tested_switch_fail; @@ -455,7 +437,7 @@ static void test_switch_fail(void) static DWORD WINAPI thread_proc(PVOID arg) { - PROTOCOLDATA protocoldata; + PROTOCOLDATA protocoldata = {0}; HRESULT hres; if(!no_callback) { @@ -468,7 +450,7 @@ static DWORD WINAPI thread_proc(PVOID arg) BINDSTATUS_FINDINGRESOURCE, wszWineHQSite); ok(hres == S_OK, "ReportProgress failed: %08x\n", hres); if(!no_callback) { - WaitForSingleObject(complete_event, INFINITE); + ok( WaitForSingleObject(complete_event, 90000) == WAIT_OBJECT_0, "wait timed out\n" ); if(bind_to_object) CHECK_CALLED(Obj_OnProgress_FINDINGRESOURCE); else @@ -485,7 +467,7 @@ static DWORD WINAPI thread_proc(PVOID arg) BINDSTATUS_CONNECTING, wszWineHQIP); ok(hres == S_OK, "ReportProgress failed: %08x\n", hres); if(!no_callback) { - WaitForSingleObject(complete_event, INFINITE); + ok( WaitForSingleObject(complete_event, 90000) == WAIT_OBJECT_0, "wait timed out\n" ); if(bind_to_object) CHECK_CALLED(Obj_OnProgress_CONNECTING); else @@ -502,7 +484,7 @@ static DWORD WINAPI thread_proc(PVOID arg) BINDSTATUS_SENDINGREQUEST, NULL); ok(hres == S_OK, "ReportProgress failed: %08x\n", hres); if(!no_callback) { - WaitForSingleObject(complete_event, INFINITE); + ok( WaitForSingleObject(complete_event, 90000) == WAIT_OBJECT_0, "wait timed out\n" ); if(bind_to_object) CHECK_CALLED(Obj_OnProgress_SENDINGREQUEST); else @@ -516,7 +498,7 @@ static DWORD WINAPI thread_proc(PVOID arg) SET_EXPECT(OnProgress_REDIRECTING); hres = IInternetProtocolSink_ReportProgress(protocol_sink, BINDSTATUS_REDIRECTING, winetest_data_urlW); ok(hres == S_OK, "ReportProgress(BINDSTATUS_REFIRECTING) failed: %08x\n", hres); - WaitForSingleObject(complete_event, INFINITE); + ok( WaitForSingleObject(complete_event, 90000) == WAIT_OBJECT_0, "wait timed out\n" ); if(bind_to_object) CHECK_CALLED(Obj_OnProgress_REDIRECTING); else @@ -529,7 +511,7 @@ static DWORD WINAPI thread_proc(PVOID arg) prot_state = 1; hres = IInternetProtocolSink_Switch(protocol_sink, &protocoldata); ok(hres == S_OK, "Switch failed: %08x\n", hres); - WaitForSingleObject(complete_event, INFINITE); + ok( WaitForSingleObject(complete_event, 90000) == WAIT_OBJECT_0, "wait timed out\n" ); CHECK_CALLED(Continue); CHECK_CALLED(Read); @@ -557,7 +539,7 @@ static DWORD WINAPI thread_proc(PVOID arg) prot_state = 2; hres = IInternetProtocolSink_Switch(protocol_sink, &protocoldata); ok(hres == S_OK, "Switch failed: %08x\n", hres); - WaitForSingleObject(complete_event, INFINITE); + ok( WaitForSingleObject(complete_event, 90000) == WAIT_OBJECT_0, "wait timed out\n" ); CHECK_CALLED(Continue); if(test_abort) { CHECK_CALLED(OnProgress_DOWNLOADINGDATA); @@ -576,7 +558,7 @@ static DWORD WINAPI thread_proc(PVOID arg) prot_state = 2; hres = IInternetProtocolSink_Switch(protocol_sink, &protocoldata); ok(hres == S_OK, "Switch failed: %08x\n", hres); - WaitForSingleObject(complete_event, INFINITE); + ok( WaitForSingleObject(complete_event, 90000) == WAIT_OBJECT_0, "wait timed out\n" ); CHECK_CALLED(Continue); CHECK_CALLED(Read); if(!no_callback) { @@ -588,7 +570,7 @@ static DWORD WINAPI thread_proc(PVOID arg) prot_state = 3; hres = IInternetProtocolSink_Switch(protocol_sink, &protocoldata); ok(hres == S_OK, "Switch failed: %08x\n", hres); - WaitForSingleObject(complete_event, INFINITE); + ok( WaitForSingleObject(complete_event, 90000) == WAIT_OBJECT_0, "wait timed out\n" ); CHECK_CALLED(Continue); CHECK_CALLED(Read); if(!no_callback) { @@ -618,8 +600,9 @@ static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, read = 0; + reported_url = szUrl; if(!filedwl_api) /* FIXME */ - ok(szUrl && !lstrcmpW(szUrl, urls[test_protocol]), "wrong url %s\n", wine_dbgstr_w(szUrl)); + ok(szUrl && !lstrcmpW(szUrl, current_url), "wrong url %s\n", wine_dbgstr_w(szUrl)); ok(pOIProtSink != NULL, "pOIProtSink == NULL\n"); ok(pOIBindInfo != NULL, "pOIBindInfo == NULL\n"); ok(grfPI == 0, "grfPI=%d, expected 0\n", grfPI); @@ -636,6 +619,11 @@ static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, return S_OK; } + memset(&bindinfo, 0, sizeof(bindinfo)); + bindinfo.cbSize = 0; + hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &bind_info, &bindinfo); + ok(hres == E_INVALIDARG, "GetBindInfo returned: %08x, expected E_INVALIDARG\n", hres); + memset(&bindinfo, 0, sizeof(bindinfo)); bindinfo.cbSize = sizeof(bindinfo); hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &bind_info, &bindinfo); @@ -695,6 +683,9 @@ static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, CHECK_CALLED(Obj_OnProgress_SENDINGREQUEST); else CHECK_CALLED(OnProgress_SENDINGREQUEST); + case WINETEST_SYNC_TEST: + IInternetProtocolSink_AddRef(pOIProtSink); + protocol_sink = pOIProtSink; default: break; } @@ -756,7 +747,7 @@ static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, SET_EXPECT(BeginningTransaction); SET_EXPECT(QueryInterface_IHttpNegotiate); } - hres = IHttpNegotiate_BeginningTransaction(http_negotiate, urls[test_protocol], + hres = IHttpNegotiate_BeginningTransaction(http_negotiate, current_url, NULL, 0, &additional_headers); if(!no_callback) { CHECK_CALLED_BROKEN(QueryInterface_IHttpNegotiate); @@ -802,14 +793,27 @@ static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, IInternetProtocolSink_AddRef(pOIProtSink); protocol_sink = pOIProtSink; - CreateThread(NULL, 0, thread_proc, NULL, 0, &tid); - return S_OK; + if(async_switch) { + PROTOCOLDATA data; + + memset(&data, 0, sizeof(data)); + data.grfFlags = PI_FORCE_ASYNC; + prot_state = 0; + hres = IInternetProtocolSink_Switch(pOIProtSink, &data); + ok(hres == S_OK, "Switch failed: %08x\n", hres); + SET_EXPECT(Continue); + SetEvent(complete_event2); + return E_PENDING; + } else { + CreateThread(NULL, 0, thread_proc, NULL, 0, &tid); + return S_OK; + } } if(test_protocol == FILE_TEST) { hres = IInternetProtocolSink_ReportProgress(pOIProtSink, - BINDSTATUS_CACHEFILENAMEAVAILABLE, file_url+8); + BINDSTATUS_CACHEFILENAMEAVAILABLE, file_url+7); ok(hres == S_OK, "ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE) failed: %08x\n", hres); @@ -825,9 +829,14 @@ static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, CHECK_CALLED(Obj_OnProgress_MIMETYPEAVAILABLE); else CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE); + }else if(test_protocol == WINETEST_SYNC_TEST) { + SET_EXPECT(OnProgress_MIMETYPEAVAILABLE); + hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE, wszTextHtml); + ok(hres == S_OK, + "ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres); + CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE); }else { - hres = IInternetProtocolSink_ReportProgress(pOIProtSink, - BINDSTATUS_MIMETYPEAVAILABLE, wszTextHtml); + hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_MIMETYPEAVAILABLE, wszTextHtml); ok(hres == S_OK, "ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres); } @@ -839,7 +848,7 @@ static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, SET_EXPECT(Read); if(bind_to_object) { - if(test_protocol != FILE_TEST && test_protocol != MK_TEST) + if(test_protocol != FILE_TEST && test_protocol != MK_TEST && test_protocol != WINETEST_SYNC_TEST) SET_EXPECT(Obj_OnProgress_MIMETYPEAVAILABLE); SET_EXPECT(Obj_OnProgress_BEGINDOWNLOADDATA); if(test_protocol == FILE_TEST) @@ -864,7 +873,8 @@ static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, SET_EXPECT(LockRequest); if(!filedwl_api) SET_EXPECT(OnDataAvailable); - SET_EXPECT(OnStopBinding); + if(test_protocol != WINETEST_SYNC_TEST) /* Set in Read after ReportResult call */ + SET_EXPECT(OnStopBinding); } hres = IInternetProtocolSink_ReportData(pOIProtSink, bscf, 13, 13); @@ -888,7 +898,7 @@ static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, CHECK_CALLED(OnObjectAvailable); CHECK_CALLED(Obj_OnStopBinding); }else { - if(test_protocol != FILE_TEST && test_protocol != MK_TEST) + if(test_protocol != FILE_TEST && test_protocol != MK_TEST && test_protocol != WINETEST_SYNC_TEST) CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE); CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA); if(test_protocol == FILE_TEST) @@ -905,17 +915,19 @@ static HRESULT WINAPI Protocol_Start(IInternetProtocol *iface, LPCWSTR szUrl, hres = IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_BEGINDOWNLOADDATA, NULL); ok(hres == S_OK, "ReportProgress(BINDSTATUS_BEGINDOWNLOADDATA) failed: %08x\n", hres); CHECK_CALLED(Read); - }else if(!bind_to_object && test_protocol == ABOUT_TEST) { + }else if(!bind_to_object && test_protocol == FILE_TEST) { SET_EXPECT(Read); hres = IInternetProtocolSink_ReportData(pOIProtSink, bscf, 13, 13); ok(hres == S_OK, "ReportData failed: %08x\n", hres); CHECK_CALLED(Read); } - SET_EXPECT(Terminate); - hres = IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL); - ok(hres == S_OK, "ReportResult failed: %08x\n", hres); - CHECK_CALLED(Terminate); + if(test_protocol != WINETEST_SYNC_TEST) { + SET_EXPECT(Terminate); + hres = IInternetProtocolSink_ReportResult(pOIProtSink, S_OK, 0, NULL); + ok(hres == S_OK, "ReportResult failed: %08x\n", hres); + CHECK_CALLED(Terminate); + } return S_OK; } @@ -930,11 +942,26 @@ static HRESULT WINAPI Protocol_Continue(IInternetProtocol *iface, ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId()); + if(!bind_to_object) + ok(reported_url && !lstrcmpW(reported_url, current_url), "wrong url %s\n", wine_dbgstr_w(reported_url)); + ok(pProtocolData != NULL, "pProtocolData == NULL\n"); if(!pProtocolData) return S_OK; switch(prot_state) { + case 0: + hres = IInternetProtocolSink_ReportProgress(protocol_sink, + BINDSTATUS_SENDINGREQUEST, NULL); + ok(hres == S_OK, "ReportProgress failed: %08x\n", hres); + + hres = IInternetProtocolSink_ReportProgress(protocol_sink, + BINDSTATUS_MIMETYPEAVAILABLE, wszTextHtml); + ok(hres == S_OK, + "ReportProgress(BINDSTATUS_MIMETYPEAVAILABLE) failed: %08x\n", hres); + + bscf |= BSCF_FIRSTDATANOTIFICATION|BSCF_INTERMEDIATEDATANOTIFICATION; + break; case 1: { IServiceProvider *service_provider; IHttpNegotiate *http_negotiate; @@ -989,6 +1016,15 @@ static HRESULT WINAPI Protocol_Continue(IInternetProtocol *iface, if(prot_state != 2 || !test_abort) SET_EXPECT(Read); switch(prot_state) { + case 0: + hres = IInternetProtocolSink_ReportResult(protocol_sink, S_OK, 0, NULL); + ok(hres == S_OK, "ReportResult failed: %08x\n", hres); + SET_EXPECT(OnProgress_SENDINGREQUEST); + SET_EXPECT(OnProgress_MIMETYPEAVAILABLE); + SET_EXPECT(OnProgress_BEGINDOWNLOADDATA); + SET_EXPECT(LockRequest); + SET_EXPECT(OnStopBinding); + break; case 1: if(bind_to_object) { SET_EXPECT(Obj_OnProgress_MIMETYPEAVAILABLE); @@ -1074,6 +1110,8 @@ static HRESULT WINAPI Protocol_Resume(IInternetProtocol *iface) static HRESULT WINAPI Protocol_Read(IInternetProtocol *iface, void *pv, ULONG cb, ULONG *pcbRead) { + HRESULT hres; + static const char data[] = ""; CHECK_EXPECT2(Read); @@ -1082,9 +1120,18 @@ static HRESULT WINAPI Protocol_Read(IInternetProtocol *iface, void *pv, ok(cb != 0, "cb == 0\n"); ok(pcbRead != NULL, "pcbRead == NULL\n"); - if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST) { - HRESULT hres; + if(async_switch) { + if(prot_state++ > 1) { + *pcbRead = 0; + return S_FALSE; + } else { + memset(pv, '?', cb); + *pcbRead = cb; + return S_OK; + } + } + if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST) { static int pending = TRUE; pending = !pending; @@ -1128,6 +1175,13 @@ static HRESULT WINAPI Protocol_Read(IInternetProtocol *iface, void *pv, return S_FALSE; } + if(test_protocol == WINETEST_SYNC_TEST) { + hres = IInternetProtocolSink_ReportResult(protocol_sink, S_OK, 0, NULL); + ok(hres == S_OK, "ReportResult failed: %08x\n", hres); + + SET_EXPECT(OnStopBinding); + } + ok(*pcbRead == 0, "*pcbRead=%d, expected 0\n", *pcbRead); read += *pcbRead = sizeof(data)-1; memcpy(pv, data, sizeof(data)); @@ -1206,7 +1260,7 @@ static HRESULT WINAPI HttpNegotiate_BeginningTransaction(IHttpNegotiate2 *iface, ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId()); - ok(!lstrcmpW(szURL, urls[test_protocol]), "szURL != urls[test_protocol]\n"); + ok(!lstrcmpW(szURL, current_url), "szURL != current_url\n"); ok(!dwReserved, "dwReserved=%d, expected 0\n", dwReserved); ok(pszAdditionalHeaders != NULL, "pszAdditionalHeaders == NULL\n"); if(pszAdditionalHeaders) @@ -1419,12 +1473,13 @@ static void test_WinInetHttpInfo(IWinInetHttpInfo *http_info, DWORD progress) size = sizeof(DWORD); hres = IWinInetHttpInfo_QueryInfo(http_info, HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL, NULL); - ok(hres == expect, "hres = %x, expected %x\n", hres, expect); + ok(hres == expect || ((progress == BINDSTATUS_COOKIE_SENT || progress == BINDSTATUS_PROXYDETECTING) && hres == S_FALSE), + "progress %u: hres = %x, expected %x\n", progress, hres, expect); if(hres == S_OK) { - if(download_state==BEFORE_DOWNLOAD && progress!=BINDSTATUS_MIMETYPEAVAILABLE) - ok(status == 0, "status = %d\n", status); + if(download_state == BEFORE_DOWNLOAD && progress != BINDSTATUS_MIMETYPEAVAILABLE && progress != BINDSTATUS_DECODING) + ok(status == 0, "progress %u: status = %d\n", progress, status); else - ok(status == HTTP_STATUS_OK, "status = %d\n", status); + ok(status == HTTP_STATUS_OK, "progress %u: status = %d\n", progress, status); ok(size == sizeof(DWORD), "size = %d\n", size); } @@ -1538,6 +1593,9 @@ static HRESULT WINAPI statusclb_OnStartBinding(IBindStatusCallbackEx *iface, DWO IWinInetHttpInfo *http_info; HRESULT hres; IMoniker *mon; + DWORD res; + CLSID clsid; + LPOLESTR res_str; if(iface == &objbsc) CHECK_EXPECT(Obj_OnStartBinding); @@ -1562,6 +1620,23 @@ static HRESULT WINAPI statusclb_OnStartBinding(IBindStatusCallbackEx *iface, DWO hres = IBinding_QueryInterface(pib, &IID_IWinInetHttpInfo, (void**)&http_info); ok(hres == E_NOINTERFACE, "Could not get IID_IWinInetHttpInfo: %08x\n", hres); + if(0) { /* crashes with native urlmon */ + hres = IBinding_GetBindResult(pib, NULL, &res, &res_str, NULL); + ok(hres == E_INVALIDARG, "GetBindResult failed: %08x\n", hres); + } + hres = IBinding_GetBindResult(pib, &clsid, NULL, &res_str, NULL); + ok(hres == E_INVALIDARG, "GetBindResult failed: %08x\n", hres); + hres = IBinding_GetBindResult(pib, &clsid, &res, NULL, NULL); + ok(hres == E_INVALIDARG, "GetBindResult failed: %08x\n", hres); + hres = IBinding_GetBindResult(pib, &clsid, &res, &res_str, (void*)0xdeadbeef); + ok(hres == E_INVALIDARG, "GetBindResult failed: %08x\n", hres); + + hres = IBinding_GetBindResult(pib, &clsid, &res, &res_str, NULL); + ok(hres == S_OK, "GetBindResult failed: %08x, expected S_OK\n", hres); + ok(IsEqualCLSID(&clsid, &CLSID_NULL), "incorrect clsid: %s\n", debugstr_guid(&clsid)); + ok(!res, "incorrect res: %x\n", res); + ok(!res_str, "incorrect res_str: %s\n", wine_dbgstr_w(res_str)); + if(abort_start) { binding_hres = abort_hres; return abort_hres; @@ -1658,7 +1733,7 @@ static HRESULT WINAPI statusclb_OnProgress(IBindStatusCallbackEx *iface, ULONG u if(filedwl_api) { /* FIXME */ }else { - ok(!lstrcmpW(szStatusText, urls[test_protocol]), "wrong szStatusText %s\n", wine_dbgstr_w(szStatusText)); + ok(!lstrcmpW(szStatusText, current_url), "wrong szStatusText %s\n", wine_dbgstr_w(szStatusText)); } } if(!bind_to_object) @@ -1695,7 +1770,7 @@ static HRESULT WINAPI statusclb_OnProgress(IBindStatusCallbackEx *iface, ULONG u if(filedwl_api) { /* FIXME */ }else { - ok(!lstrcmpW(szStatusText, urls[test_protocol]), "wrong szStatusText %s\n", wine_dbgstr_w(szStatusText)); + ok(!lstrcmpW(szStatusText, current_url), "wrong szStatusText %s\n", wine_dbgstr_w(szStatusText)); } } ok(download_state == DOWNLOADING, "Download state was %d, expected DOWNLOADING\n", @@ -1715,7 +1790,7 @@ static HRESULT WINAPI statusclb_OnProgress(IBindStatusCallbackEx *iface, ULONG u ok(szStatusText != NULL, "szStatusText == NULL\n"); if(szStatusText && test_protocol == FILE_TEST) - ok(!lstrcmpW(file_url+8, szStatusText), "wrong szStatusText %s\n", wine_dbgstr_w(szStatusText)); + ok(!lstrcmpW(file_url+7, szStatusText), "wrong szStatusText %s\n", wine_dbgstr_w(szStatusText)); break; case BINDSTATUS_CLASSIDAVAILABLE: { @@ -1749,6 +1824,9 @@ static HRESULT WINAPI statusclb_OnProgress(IBindStatusCallbackEx *iface, ULONG u case BINDSTATUS_COOKIE_SENT: trace("BINDSTATUS_COOKIE_SENT\n"); break; + case BINDSTATUS_DECODING: + trace("BINDSTATUS_DECODING\n"); + break; default: ok(0, "unexpected code %d\n", ulStatusCode); }; @@ -1803,10 +1881,54 @@ static HRESULT WINAPI statusclb_OnStopBinding(IBindStatusCallbackEx *iface, HRES ok(hresult == binding_hres, "binding failed: %08x, expected %08x\n", hresult, binding_hres); ok(szError == NULL, "szError should be NULL\n"); + if(current_binding) { + CLSID clsid; + DWORD res; + LPOLESTR res_str; + HRESULT hres; + + hres = IBinding_GetBindResult(current_binding, &clsid, &res, &res_str, NULL); + ok(hres == S_OK, "GetBindResult failed: %08x, expected S_OK\n", hres); + ok(res == hresult, "res = %08x, expected %08x\n", res, binding_hres); + ok(!res_str, "incorrect res_str = %s\n", wine_dbgstr_w(res_str)); + + if(hresult==S_OK || (abort_start && hresult!=S_FALSE)) { + ok(IsEqualCLSID(&clsid, &CLSID_NULL), + "incorrect protocol CLSID: %s, expected CLSID_NULL\n", + debugstr_guid(&clsid)); + }else if(emulate_protocol) { + todo_wine ok(IsEqualCLSID(&clsid, &CLSID_FtpProtocol), + "incorrect protocol CLSID: %s, expected CLSID_FtpProtocol\n", + debugstr_guid(&clsid)); + }else if(test_protocol == FTP_TEST) { + ok(IsEqualCLSID(&clsid, &CLSID_FtpProtocol), + "incorrect protocol CLSID: %s, expected CLSID_FtpProtocol\n", + debugstr_guid(&clsid)); + }else if(test_protocol == FILE_TEST) { + ok(IsEqualCLSID(&clsid, &CLSID_FileProtocol), + "incorrect protocol CLSID: %s, expected CLSID_FileProtocol\n", + debugstr_guid(&clsid)); + }else if(test_protocol == HTTP_TEST) { + ok(IsEqualCLSID(&clsid, &CLSID_HttpProtocol), + "incorrect protocol CLSID: %s, expected CLSID_HttpProtocol\n", + debugstr_guid(&clsid)); + }else if(test_protocol == HTTPS_TEST) { + ok(IsEqualCLSID(&clsid, &CLSID_HttpSProtocol), + "incorrect protocol CLSID: %s, expected CLSID_HttpSProtocol\n", + debugstr_guid(&clsid)); + }else if(test_protocol == ABOUT_TEST) { + ok(IsEqualCLSID(&clsid, &CLSID_AboutProtocol), + "incorrect protocol CLSID: %s, expected CLSID_AboutProtocol\n", + debugstr_guid(&clsid)); + }else { + ok(0, "unexpected (%d)\n", test_protocol); + } + } + if((test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST) && emulate_protocol) { SetEvent(complete_event); if(iface != &objbsc) - WaitForSingleObject(complete_event2, INFINITE); + ok( WaitForSingleObject(complete_event2, 90000) == WAIT_OBJECT_0, "wait timed out\n" ); } return S_OK; @@ -1929,7 +2051,7 @@ static HRESULT WINAPI statusclb_OnDataAvailable(IBindStatusCallbackEx *iface, DW case TYMED_FILE: if(test_protocol == FILE_TEST) - ok(!lstrcmpW(pstgmed->u.lpszFileName, INDEX_HTML+7), + ok(!lstrcmpW(pstgmed->u.lpszFileName, file_url+7), "unexpected file name %s\n", wine_dbgstr_w(pstgmed->u.lpszFileName)); else if(emulate_protocol) ok(!lstrcmpW(pstgmed->u.lpszFileName, cache_fileW), @@ -2084,9 +2206,9 @@ static HRESULT WINAPI PersistMoniker_Load(IPersistMoniker *iface, BOOL fFullyAva ok(GetCurrentThreadId() == thread_id, "wrong thread %d\n", GetCurrentThreadId()); if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST) - ok(!fFullyAvailable, "fFulyAvailable = %x\n", fFullyAvailable); + ok(!fFullyAvailable, "fFullyAvailable = %x\n", fFullyAvailable); else - ok(fFullyAvailable, "fFulyAvailable = %x\n", fFullyAvailable); + ok(fFullyAvailable, "fFullyAvailable = %x\n", fFullyAvailable); ok(pimkName != NULL, "pimkName == NULL\n"); ok(pibc != NULL, "pibc == NULL\n"); ok(grfMode == 0x12, "grfMode = %x\n", grfMode); @@ -2485,7 +2607,7 @@ static BOOL test_bscholder(IBindStatusCallback *holder) wstr = (void*)0xdeadbeef; SET_EXPECT(QueryInterface_IHttpNegotiate); SET_EXPECT(BeginningTransaction); - hres = IHttpNegotiate_BeginningTransaction(http_negotiate_serv, urls[test_protocol], emptyW, 0, &wstr); + hres = IHttpNegotiate_BeginningTransaction(http_negotiate_serv, current_url, emptyW, 0, &wstr); CHECK_CALLED_BROKEN(QueryInterface_IHttpNegotiate); /* IE8 */ CHECK_CALLED(BeginningTransaction); ok(hres == S_OK, "BeginningTransaction failed: %08x\n", hres); @@ -2517,8 +2639,8 @@ static BOOL test_bscholder(IBindStatusCallback *holder) CHECK_CALLED_BROKEN(QueryInterface_IHttpNegotiate2); /* IE8 */ CHECK_CALLED(GetRootSecurityId); - IHttpNegotiate_Release(http_negotiate2_serv); - IHttpNegotiate_Release(http_negotiate2); + IHttpNegotiate2_Release(http_negotiate2_serv); + IHttpNegotiate2_Release(http_negotiate2); }else { skip("Could not get IHttpNegotiate2\n"); ret = FALSE; @@ -2686,9 +2808,12 @@ static BOOL test_RegisterBindStatusCallback(void) #define BINDTEST_INVALID_CN 0x0200 #define BINDTEST_ABORT_START 0x0400 #define BINDTEST_ABORT_PROGRESS 0x0800 +#define BINDTEST_ASYNC_SWITCH 0x1000 static void init_bind_test(int protocol, DWORD flags, DWORD t) { + const char *url_a = NULL; + test_protocol = protocol; emulate_protocol = (flags & BINDTEST_EMULATE) != 0; download_state = BEFORE_DOWNLOAD; @@ -2700,14 +2825,40 @@ static void init_bind_test(int protocol, DWORD flags, DWORD t) bind_to_object = (flags & BINDTEST_TOOBJECT) != 0; tymed = t; filedwl_api = (flags & BINDTEST_FILEDWLAPI) != 0; - if(flags & BINDTEST_HTTPRESPONSE) - urls[HTTP_TEST] = winetest_post_urlW; - else - urls[HTTP_TEST] = winetest_data_urlW; - if(flags & BINDTEST_INVALID_CN) - urls[HTTPS_TEST] = https_invalid_cn_urlW; - else - urls[HTTPS_TEST] = https_urlW; + post_test = (flags & BINDTEST_HTTPRESPONSE) != 0; + + switch(protocol) { + case HTTP_TEST: + if(post_test) + url_a = "http://test.winehq.org/tests/post.php"; + else + lstrcpyW(current_url, winetest_data_urlW); + break; + case ABOUT_TEST: + url_a = "about:blank"; + break; + case FILE_TEST: + lstrcpyW(current_url, file_url); + break; + case MK_TEST: + url_a = "mk:@MSITStore:test.chm::/blank.html"; + break; + case ITS_TEST: + url_a = "its:test.chm::/blank.html"; + break; + case HTTPS_TEST: + url_a = (flags & BINDTEST_INVALID_CN) ? "https://209.46.25.132/test.html" : "https://www.codeweavers.com/test.html"; + break; + case FTP_TEST: + url_a = "ftp://ftp.winehq.org/pub/other/winelogo.xcf.tar.bz2"; + break; + default: + url_a = "winetest:test"; + } + + if(url_a) + MultiByteToWideChar(CP_ACP, 0, url_a, -1, current_url, sizeof(current_url)/sizeof(*current_url)); + test_redirect = (flags & BINDTEST_REDIRECT) != 0; use_cache_file = (flags & BINDTEST_USE_CACHE) != 0; callback_read = !(flags & BINDTEST_NO_CALLBACK_READ); @@ -2715,7 +2866,12 @@ static void init_bind_test(int protocol, DWORD flags, DWORD t) test_abort = (flags & BINDTEST_ABORT) != 0; abort_start = (flags & BINDTEST_ABORT_START) != 0; abort_progress = (flags & BINDTEST_ABORT_PROGRESS) != 0; + async_switch = (flags & BINDTEST_ASYNC_SWITCH) != 0; is_async_prot = protocol == HTTP_TEST || protocol == HTTPS_TEST || protocol == FTP_TEST || protocol == WINETEST_TEST; + prot_state = 0; + ResetEvent(complete_event); + + trace("URL: %s\n", wine_dbgstr_w(current_url)); } static void test_BindToStorage(int protocol, DWORD flags, DWORD t) @@ -2751,7 +2907,7 @@ static void test_BindToStorage(int protocol, DWORD flags, DWORD t) IBindStatusCallback_Release(previousclb); } - hres = CreateURLMoniker(NULL, test_protocol == FILE_TEST ? file_url : urls[test_protocol], &mon); + hres = CreateURLMoniker(NULL, current_url, &mon); ok(hres == S_OK, "failed to create moniker: %08x\n", hres); if(FAILED(hres)) return; @@ -2763,8 +2919,8 @@ static void test_BindToStorage(int protocol, DWORD flags, DWORD t) hres = IMoniker_GetDisplayName(mon, bctx, NULL, &display_name); ok(hres == S_OK, "GetDisplayName failed %08x\n", hres); - ok(!lstrcmpW(display_name, urls[test_protocol]), - "GetDisplayName got wrong name %s\n", wine_dbgstr_w(display_name)); + ok(!lstrcmpW(display_name, current_url), "GetDisplayName got wrong name %s, expected %s\n", + wine_dbgstr_w(display_name), wine_dbgstr_w(current_url)); CoTaskMemFree(display_name); if(tymed == TYMED_FILE && (test_protocol == ABOUT_TEST || test_protocol == ITS_TEST)) @@ -2792,7 +2948,8 @@ static void test_BindToStorage(int protocol, DWORD flags, DWORD t) if(is_urlmon_protocol(test_protocol)) SET_EXPECT(SetPriority); SET_EXPECT(Start); - if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST) + if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST + || test_protocol == WINETEST_SYNC_TEST) SET_EXPECT(Terminate); if(tymed != TYMED_FILE || (test_protocol != ABOUT_TEST && test_protocol != ITS_TEST)) SET_EXPECT(UnlockRequest); @@ -2862,7 +3019,7 @@ static void test_BindToStorage(int protocol, DWORD flags, DWORD t) ok(hres == MK_S_ASYNCHRONOUS, "IMoniker_BindToStorage failed: %08x\n", hres); else if(no_callback) { if(emulate_protocol) - WaitForSingleObject(complete_event2, INFINITE); + ok( WaitForSingleObject(complete_event2, 90000) == WAIT_OBJECT_0, "wait timed out\n" ); ok(hres == S_OK, "IMoniker_BindToStorage failed: %08x\n", hres); ok(unk != NULL, "unk == NULL\n"); }else if(!(bindf & BINDF_ASYNCHRONOUS) && tymed == TYMED_FILE) { @@ -2906,6 +3063,13 @@ static void test_BindToStorage(int protocol, DWORD flags, DWORD t) } } + if(async_switch) { + CHECK_CALLED(OnProgress_SENDINGREQUEST); + CHECK_CALLED(OnProgress_MIMETYPEAVAILABLE); + CHECK_CALLED(OnProgress_BEGINDOWNLOADDATA); + CHECK_CALLED(LockRequest); + CHECK_CALLED(OnStopBinding); + } if(!no_callback) { CLEAR_CALLED(QueryInterface_IBindStatusCallbackEx); /* IE 8 */ CHECK_CALLED(GetBindInfo); @@ -2925,7 +3089,8 @@ static void test_BindToStorage(int protocol, DWORD flags, DWORD t) if(is_urlmon_protocol(test_protocol)) CHECK_CALLED(SetPriority); CHECK_CALLED(Start); - if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST) { + if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == WINETEST_TEST + || test_protocol == WINETEST_SYNC_TEST) { if(tymed == TYMED_FILE) CLEAR_CALLED(Read); CHECK_CALLED(Terminate); @@ -3064,7 +3229,7 @@ static void test_BindToObject(int protocol, DWORD flags) if(FAILED(hres)) return; - hres = CreateURLMoniker(NULL, test_protocol == FILE_TEST ? file_url : urls[test_protocol], &mon); + hres = CreateURLMoniker(NULL, current_url, &mon); ok(hres == S_OK, "failed to create moniker: %08x\n", hres); if(FAILED(hres)) { IBindCtx_Release(bctx); @@ -3078,7 +3243,7 @@ static void test_BindToObject(int protocol, DWORD flags) hres = IMoniker_GetDisplayName(mon, bctx, NULL, &display_name); ok(hres == S_OK, "GetDisplayName failed %08x\n", hres); - ok(!lstrcmpW(display_name, urls[test_protocol]), "GetDisplayName got wrong name\n"); + ok(!lstrcmpW(display_name, current_url), "GetDisplayName got wrong name\n"); CoTaskMemFree(display_name); SET_EXPECT(QueryInterface_IBindStatusCallbackEx); @@ -3195,7 +3360,7 @@ static void test_BindToObject(int protocol, DWORD flags) CLEAR_CALLED(GetWindow_IWindowForBindingUI); } if(test_protocol == HTTP_TEST || test_protocol == HTTPS_TEST || test_protocol == FILE_TEST) { - if(urls[test_protocol] == winetest_post_urlW) + if(post_test) CLEAR_CALLED(Obj_OnProgress_SENDINGREQUEST); else CHECK_CALLED(Obj_OnProgress_SENDINGREQUEST); @@ -3275,8 +3440,7 @@ static void test_URLDownloadToFile(DWORD prot, BOOL emul) SET_EXPECT(OnStopBinding); } - hres = URLDownloadToFileW(NULL, test_protocol == FILE_TEST ? file_url : urls[test_protocol], - dwl_htmlW, 0, (IBindStatusCallback*)&bsc); + hres = URLDownloadToFileW(NULL, current_url, dwl_htmlW, 0, (IBindStatusCallback*)&bsc); ok(hres == S_OK, "URLDownloadToFile failed: %08x\n", hres); CHECK_CALLED(GetBindInfo); @@ -3327,7 +3491,7 @@ static void test_URLDownloadToFile(DWORD prot, BOOL emul) if(prot != FILE_TEST || emul) return; - hres = URLDownloadToFileW(NULL, urls[test_protocol], dwl_htmlW, 0, NULL); + hres = URLDownloadToFileW(NULL, current_url, dwl_htmlW, 0, NULL); ok(hres == S_OK, "URLDownloadToFile failed: %08x\n", hres); res = DeleteFileA(dwl_htmlA); @@ -3354,7 +3518,7 @@ static void test_URLDownloadToFile_abort(void) SET_EXPECT(OnProgress_SENDINGREQUEST); SET_EXPECT(OnStopBinding); - hres = URLDownloadToFileW(NULL, urls[HTTP_TEST], dwl_htmlW, 0, (IBindStatusCallback*)&bsc); + hres = URLDownloadToFileW(NULL, current_url, dwl_htmlW, 0, (IBindStatusCallback*)&bsc); ok(hres == E_ABORT, "URLDownloadToFile failed: %08x, expected E_ABORT\n", hres); CHECK_CALLED(GetBindInfo); @@ -3381,7 +3545,7 @@ static void test_URLDownloadToFile_abort(void) SET_EXPECT(OnStopBinding); abort_hres = E_ABORT; - hres = URLDownloadToFileW(NULL, urls[HTTP_TEST], dwl_htmlW, 0, (IBindStatusCallback*)&bsc); + hres = URLDownloadToFileW(NULL, current_url, dwl_htmlW, 0, (IBindStatusCallback*)&bsc); ok(hres == E_ABORT, "URLDownloadToFile failed: %08x, expected E_ABORT\n", hres); CHECK_CALLED(GetBindInfo); @@ -3416,7 +3580,7 @@ static void test_URLDownloadToFile_abort(void) * IBindStatusCallback's OnStartBinding function. */ abort_hres = E_NOTIMPL; - hres = URLDownloadToFileW(NULL, urls[HTTP_TEST], dwl_htmlW, 0, (IBindStatusCallback*)&bsc); + hres = URLDownloadToFileW(NULL, current_url, dwl_htmlW, 0, (IBindStatusCallback*)&bsc); ok(hres == S_OK, "URLDownloadToFile failed: %08x\n", hres); CHECK_CALLED(GetBindInfo); @@ -3444,15 +3608,10 @@ static void test_URLDownloadToFile_abort(void) static void set_file_url(char *path) { CHAR file_urlA[INTERNET_MAX_URL_LENGTH]; - CHAR INDEX_HTMLA[MAX_PATH]; - lstrcpyA(file_urlA, "file:///"); + lstrcpyA(file_urlA, "file://"); lstrcatA(file_urlA, path); MultiByteToWideChar(CP_ACP, 0, file_urlA, -1, file_url, INTERNET_MAX_URL_LENGTH); - - lstrcpyA(INDEX_HTMLA, "file://"); - lstrcatA(INDEX_HTMLA, path); - MultiByteToWideChar(CP_ACP, 0, INDEX_HTMLA, -1, INDEX_HTML, MAX_PATH); } static void create_file(void) @@ -3512,7 +3671,7 @@ static void test_ReportResult(HRESULT exhres) init_bind_test(ABOUT_TEST, BINDTEST_EMULATE, TYMED_ISTREAM); binding_hres = exhres; - hres = CreateURLMoniker(NULL, ABOUT_BLANK, &mon); + hres = CreateURLMoniker(NULL, about_blankW, &mon); ok(hres == S_OK, "CreateURLMoniker failed: %08x\n", hres); SET_EXPECT(QueryInterface_IServiceProvider); @@ -3556,7 +3715,7 @@ static void test_BindToStorage_fail(void) IUnknown *unk; HRESULT hres; - hres = CreateURLMoniker(NULL, ABOUT_BLANK, &mon); + hres = CreateURLMoniker(NULL, about_blankW, &mon); ok(hres == S_OK, "CreateURLMoniker failed: %08x\n", hres); if(FAILED(hres)) return; @@ -3582,6 +3741,8 @@ static void test_StdURLMoniker(void) { IMoniker *mon, *async_mon; LPOLESTR display_name; + IBindCtx *bctx; + IUnknown *unk; HRESULT hres; hres = CoCreateInstance(&IID_IInternet, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, @@ -3603,7 +3764,7 @@ static void test_StdURLMoniker(void) IUri *uri; hres = IMoniker_QueryInterface(mon, &IID_IUriContainer, (void**)&uri_container); - ok(hres == S_OK, "Coud not get IUriMoniker iface: %08x\n", hres); + ok(hres == S_OK, "Could not get IUriMoniker iface: %08x\n", hres); uri = (void*)0xdeadbeef; @@ -3614,6 +3775,23 @@ static void test_StdURLMoniker(void) IUriContainer_Release(uri_container); } + SET_EXPECT(QueryInterface_IServiceProvider); + hres = CreateAsyncBindCtx(0, (IBindStatusCallback*)&bsc, NULL, &bctx); + ok(hres == S_OK, "CreateAsyncBindCtx failed: %08x\n\n", hres); + CHECK_CALLED(QueryInterface_IServiceProvider); + + if(pCreateUri) { /* Skip these tests on old IEs */ + unk = (void*)0xdeadbeef; + hres = IMoniker_BindToStorage(mon, bctx, NULL, &IID_IStream, (void**)&unk); + ok(hres == MK_E_SYNTAX, "BindToStorage failed: %08x, expected MK_E_SYNTAX\n", hres); + ok(!unk, "unk = %p\n", unk); + + unk = (void*)0xdeadbeef; + hres = IMoniker_BindToObject(mon, bctx, NULL, &IID_IUnknown, (void**)&unk); + ok(hres == MK_E_SYNTAX, "BindToStorage failed: %08x, expected MK_E_SYNTAX\n", hres); + ok(!unk, "unk = %p\n", unk); + } + IMoniker_Release(mon); } @@ -3730,6 +3908,9 @@ START_TEST(url) bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA; + trace("winetest test (async switch)...\n"); + test_BindToStorage(WINETEST_TEST, BINDTEST_EMULATE|BINDTEST_ASYNC_SWITCH, TYMED_ISTREAM); + trace("about test (no read)...\n"); test_BindToStorage(ABOUT_TEST, BINDTEST_NO_CALLBACK_READ, TYMED_ISTREAM); @@ -3805,6 +3986,9 @@ START_TEST(url) trace("emulated about test (to object)...\n"); test_BindToObject(ABOUT_TEST, BINDTEST_EMULATE); + trace("emulalated test reporting result in read...\n"); + test_BindToStorage(WINETEST_SYNC_TEST, BINDTEST_EMULATE, TYMED_ISTREAM); + trace("file test...\n"); test_BindToStorage(FILE_TEST, 0, TYMED_ISTREAM);