From 1928ee8804b011561f806780cc2fbc31bb8c6576 Mon Sep 17 00:00:00 2001 From: James Hawkins Date: Mon, 31 Oct 2005 14:06:35 +0000 Subject: [PATCH] Implement InternetCreateUrlW and test cases. --- dlls/wininet/internet.c | 278 +++++++++++++++++++++++++++++++++++--- dlls/wininet/tests/http.c | 245 +++++++++++++++++++++++++++++++++ 2 files changed, 505 insertions(+), 18 deletions(-) diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index a43d748169..b0872e31c1 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -3422,6 +3422,142 @@ BOOL WINAPI InternetCombineUrlW(LPCWSTR lpszBaseUrl, LPCWSTR lpszRelativeUrl, return (hr==S_OK); } +/* max port num is 65535 => 5 digits */ +#define MAX_WORD_DIGITS 5 + +/* we can calculate using ansi strings because we're just + * calculating string length, not size + */ +static BOOL calc_url_length(LPURL_COMPONENTSW lpUrlComponents, + LPDWORD lpdwUrlLength, LPDWORD lpdwSchemeLength) +{ + static const WCHAR httpW[] = {'h','t','t','p',0}; + + *lpdwUrlLength = 0; + + switch (lpUrlComponents->nScheme) + { + case INTERNET_SCHEME_FTP: + case INTERNET_SCHEME_RES: + *lpdwSchemeLength = 3; + break; + case INTERNET_SCHEME_HTTP: + case INTERNET_SCHEME_FILE: + case INTERNET_SCHEME_NEWS: + *lpdwSchemeLength = 4; + break; + + default: + *lpdwSchemeLength = 4; + break; + } + + *lpdwUrlLength += *lpdwSchemeLength; + *lpdwUrlLength += strlen("://"); + + if (lpUrlComponents->lpszUserName) + { + *lpdwUrlLength += lpUrlComponents->dwUserNameLength; + *lpdwUrlLength += strlen("@"); + } + else + { + if (lpUrlComponents->lpszPassword) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + else + SetLastError(ERROR_ALREADY_EXISTS); + } + + if (lpUrlComponents->lpszPassword) + { + *lpdwUrlLength += strlen(":"); + *lpdwUrlLength += lpUrlComponents->dwPasswordLength; + } + + *lpdwUrlLength += lpUrlComponents->dwHostNameLength; + + if (lpUrlComponents->nPort != 80 || + (lpUrlComponents->lpszScheme && strncmpW(lpUrlComponents->lpszScheme, httpW, lpUrlComponents->dwSchemeLength))) + { + char szPort[MAX_WORD_DIGITS]; + + sprintf(szPort, "%d", lpUrlComponents->nPort); + *lpdwUrlLength += strlen(szPort); + *lpdwUrlLength += strlen(":"); + } + + *lpdwUrlLength += lpUrlComponents->dwUrlPathLength; + return TRUE; +} + +static void convert_urlcomp_atow(LPURL_COMPONENTSA lpUrlComponents, LPURL_COMPONENTSW urlCompW) +{ + INT len; + + ZeroMemory(urlCompW, sizeof(URL_COMPONENTSW)); + + urlCompW->dwStructSize = sizeof(URL_COMPONENTSW); + urlCompW->dwSchemeLength = lpUrlComponents->dwSchemeLength; + urlCompW->nScheme = lpUrlComponents->nScheme; + urlCompW->dwHostNameLength = lpUrlComponents->dwHostNameLength; + urlCompW->nPort = lpUrlComponents->nPort; + urlCompW->dwUserNameLength = lpUrlComponents->dwUserNameLength; + urlCompW->dwPasswordLength = lpUrlComponents->dwPasswordLength; + urlCompW->dwUrlPathLength = lpUrlComponents->dwUrlPathLength; + urlCompW->dwExtraInfoLength = lpUrlComponents->dwExtraInfoLength; + + if (lpUrlComponents->lpszScheme) + { + len = lpUrlComponents->dwSchemeLength + 1; + urlCompW->lpszScheme = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, lpUrlComponents->lpszScheme, + -1, urlCompW->lpszScheme, len); + } + + if (lpUrlComponents->lpszHostName) + { + len = lpUrlComponents->dwHostNameLength + 1; + urlCompW->lpszHostName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, lpUrlComponents->lpszHostName, + -1, urlCompW->lpszHostName, len); + } + + if (lpUrlComponents->lpszUserName) + { + len = lpUrlComponents->dwUserNameLength + 1; + urlCompW->lpszUserName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, lpUrlComponents->lpszUserName, + -1, urlCompW->lpszUserName, len); + } + + if (lpUrlComponents->lpszPassword) + { + len = lpUrlComponents->dwPasswordLength + 1; + urlCompW->lpszPassword = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, lpUrlComponents->lpszPassword, + -1, urlCompW->lpszPassword, len); + } + + if (lpUrlComponents->lpszUrlPath) + { + len = lpUrlComponents->dwUrlPathLength + 1; + urlCompW->lpszUrlPath = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, lpUrlComponents->lpszUrlPath, + -1, urlCompW->lpszUrlPath, len); + } + + if (lpUrlComponents->lpszExtraInfo) + { + len = lpUrlComponents->dwExtraInfoLength + 1; + urlCompW->lpszExtraInfo = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, lpUrlComponents->lpszExtraInfo, + -1, urlCompW->lpszExtraInfo, len); + } +} + /*********************************************************************** * * InternetCreateUrlA @@ -3434,8 +3570,130 @@ BOOL WINAPI InternetCombineUrlW(LPCWSTR lpszBaseUrl, LPCWSTR lpszRelativeUrl, BOOL WINAPI InternetCreateUrlA(LPURL_COMPONENTSA lpUrlComponents, DWORD dwFlags, LPSTR lpszUrl, LPDWORD lpdwUrlLength) { - FIXME("\n"); - return FALSE; + BOOL ret; + LPWSTR urlW = NULL; + URL_COMPONENTSW urlCompW; + + TRACE("(%p,%ld,%s,%p)\n", lpUrlComponents, dwFlags, debugstr_a(lpszUrl), lpdwUrlLength); + + if (!lpUrlComponents) + return FALSE; + + if (lpUrlComponents->dwStructSize != sizeof(URL_COMPONENTSW) || !lpdwUrlLength) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + convert_urlcomp_atow(lpUrlComponents, &urlCompW); + + if (lpszUrl) + urlW = HeapAlloc(GetProcessHeap(), 0, *lpdwUrlLength * sizeof(WCHAR)); + + ret = InternetCreateUrlW(&urlCompW, dwFlags, urlW, lpdwUrlLength); + + /* on success, lpdwUrlLength points to the size of urlW in WCHARS + * minus one, so add one to leave room for NULL terminator + */ + if (ret) + WideCharToMultiByte(CP_ACP, 0, urlW, -1, lpszUrl, *lpdwUrlLength + 1, NULL, NULL); + + HeapFree(GetProcessHeap(), 0, urlCompW.lpszScheme); + HeapFree(GetProcessHeap(), 0, urlCompW.lpszHostName); + HeapFree(GetProcessHeap(), 0, urlCompW.lpszUserName); + HeapFree(GetProcessHeap(), 0, urlCompW.lpszPassword); + HeapFree(GetProcessHeap(), 0, urlCompW.lpszUrlPath); + HeapFree(GetProcessHeap(), 0, urlCompW.lpszExtraInfo); + HeapFree(GetProcessHeap(), 0, urlW); + + return ret; +} + +/*********************************************************************** + * + * InternetCreateUrlW + * + * RETURNS + * TRUE on success + * FALSE on failure + * + */ +BOOL WINAPI InternetCreateUrlW(LPURL_COMPONENTSW lpUrlComponents, DWORD dwFlags, + LPWSTR lpszUrl, LPDWORD lpdwUrlLength) +{ + DWORD dwLen, dwSchemeLen; + + static const WCHAR colonSlashW[] = {':','/','/',0}; + static const WCHAR httpW[] = {'h','t','t','p',0}; + static const WCHAR colonW[] = {':',0}; + static const WCHAR atW[] = {'@',0}; + static const WCHAR percentD[] = {'%','d',0}; + + TRACE("(%p,%ld,%s,%p)\n", lpUrlComponents, dwFlags, debugstr_w(lpszUrl), lpdwUrlLength); + + if (!lpUrlComponents) + return FALSE; + + if (lpUrlComponents->dwStructSize != sizeof(URL_COMPONENTSW) || !lpdwUrlLength) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if (!calc_url_length(lpUrlComponents, &dwLen, &dwSchemeLen)) + return FALSE; + + if (!lpszUrl || *lpdwUrlLength < dwLen) + { + *lpdwUrlLength = dwLen + 1; /* terminating null */ + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return FALSE; + } + + *lpdwUrlLength = dwLen; + lpszUrl[0] = 0x00; + + if (lpUrlComponents->lpszScheme) + lstrcpynW(lpszUrl, lpUrlComponents->lpszScheme, + min(lpUrlComponents->dwSchemeLength, dwSchemeLen) + 1); + + lstrcatW(lpszUrl, colonSlashW); + + if (lpUrlComponents->lpszUserName) + { + if (!*lpUrlComponents->lpszUserName) + return TRUE; + + lstrcatW(lpszUrl, lpUrlComponents->lpszUserName); + + if (lpUrlComponents->lpszPassword) + { + lstrcatW(lpszUrl, colonW); + + if (!*lpUrlComponents->lpszPassword) + return TRUE; + else + lstrcatW(lpszUrl, lpUrlComponents->lpszPassword); + } + + lstrcatW(lpszUrl, atW); + } + + lstrcatW(lpszUrl, lpUrlComponents->lpszHostName); + + if (lpUrlComponents->nPort != 80 || (lpUrlComponents->lpszScheme && + strncmpW(lpUrlComponents->lpszScheme, httpW, lpUrlComponents->dwSchemeLength))) + { + WCHAR szPort[MAX_WORD_DIGITS]; + + sprintfW(szPort, percentD, lpUrlComponents->nPort); + lstrcatW(lpszUrl, colonW); + lstrcatW(lpszUrl, szPort); + } + + lstrcatW(lpszUrl, lpUrlComponents->lpszUrlPath); + + return TRUE; } DWORD WINAPI InternetConfirmZoneCrossingA( HWND hWnd, LPSTR szUrlPrev, LPSTR szUrlNew, BOOL bPost ) @@ -3579,22 +3837,6 @@ BOOL WINAPI ResumeSuspendedDownload( HINTERNET hInternet, DWORD dwError ) FIXME("(%p, 0x%08lx) stub\n", hInternet, dwError); return FALSE; } - -/*********************************************************************** - * - * InternetCreateUrlW - * - * RETURNS - * TRUE on success - * FALSE on failure - * - */ -BOOL WINAPI InternetCreateUrlW(LPURL_COMPONENTSW lpUrlComponents, DWORD dwFlags, - LPWSTR lpszUrl, LPDWORD lpdwUrlLength) -{ - FIXME("\n"); - return FALSE; -} /*********************************************************************** * dump_INTERNET_FLAGS diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c index 6d2a8c6bcb..f319011a5a 100644 --- a/dlls/wininet/tests/http.c +++ b/dlls/wininet/tests/http.c @@ -39,6 +39,14 @@ #define TEST_URL2_EXTRA "?arg=1" #define TEST_URL3 "file:///C:/Program%20Files/Atmel/AVR%20Tools/STK500/STK500.xml" +#define CREATE_URL1 "http://username:password@www.winehq.org/site/about" +#define CREATE_URL2 "http://username@www.winehq.org/site/about" +#define CREATE_URL3 "http://username:" +#define CREATE_URL4 "http://www.winehq.org/site/about" +#define CREATE_URL5 "http://" +#define CREATE_URL6 "nhtt://username:password@www.winehq.org:80/site/about" +#define CREATE_URL7 "http://username:password@www.winehq.org:42/site/about" + int goon = 0; static VOID WINAPI callback( @@ -590,6 +598,242 @@ static void InternetTimeToSystemTimeW_test(void) ok( ret, "InternetTimeToSystemTimeW failed (%ld)\n", GetLastError() ); } +static void fill_url_components(LPURL_COMPONENTS lpUrlComponents) +{ + lpUrlComponents->dwStructSize = sizeof(URL_COMPONENTS); + lpUrlComponents->lpszScheme = "http"; + lpUrlComponents->dwSchemeLength = strlen(lpUrlComponents->lpszScheme); + lpUrlComponents->nScheme = INTERNET_SCHEME_HTTP; + lpUrlComponents->lpszHostName = "www.winehq.org"; + lpUrlComponents->dwHostNameLength = strlen(lpUrlComponents->lpszHostName); + lpUrlComponents->nPort = 80; + lpUrlComponents->lpszUserName = "username"; + lpUrlComponents->dwUserNameLength = strlen(lpUrlComponents->lpszUserName); + lpUrlComponents->lpszPassword = "password"; + lpUrlComponents->dwPasswordLength = strlen(lpUrlComponents->lpszPassword); + lpUrlComponents->lpszUrlPath = "/site/about"; + lpUrlComponents->dwUrlPathLength = strlen(lpUrlComponents->lpszUrlPath); + lpUrlComponents->lpszExtraInfo = ""; + lpUrlComponents->dwExtraInfoLength = strlen(lpUrlComponents->lpszExtraInfo); +} + +static void InternetCreateUrlA_test() +{ + URL_COMPONENTS urlComp; + LPSTR szUrl; + DWORD len = -1; + BOOL ret; + + /* test NULL lpUrlComponents */ + ret = InternetCreateUrlA(NULL, 0, NULL, &len); + SetLastError(0xdeadbeef); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == 0xdeadbeef, + "Expected 0xdeadbeef, got %ld\n", GetLastError()); + ok(len == -1, "Expected len -1, got %ld\n", len); + + /* test garbage lpUrlComponets */ + ret = InternetCreateUrlA(&urlComp, 0, NULL, &len); + SetLastError(0xdeadbeef); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == 0xdeadbeef, + "Expected 0xdeadbeef, got %ld\n", GetLastError()); + ok(len == -1, "Expected len -1, got %ld\n", len); + + /* test zero'ed lpUrlComponents */ + ZeroMemory(&urlComp, sizeof(URL_COMPONENTS)); + SetLastError(0xdeadbeef); + ret = InternetCreateUrlA(&urlComp, 0, NULL, &len); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); + ok(len == -1, "Expected len -1, got %ld\n", len); + + /* test valid lpUrlComponets, NULL lpdwUrlLength */ + fill_url_components(&urlComp); + SetLastError(0xdeadbeef); + ret = InternetCreateUrlA(&urlComp, 0, NULL, NULL); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); + ok(len == -1, "Expected len -1, got %ld\n", len); + + /* test valid lpUrlComponets, emptry szUrl + * lpdwUrlLength is size of buffer required on exit, including + * the terminating null when GLE == ERROR_INSUFFICIENT_BUFFER + */ + SetLastError(0xdeadbeef); + ret = InternetCreateUrlA(&urlComp, 0, NULL, &len); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); + ok(len == 51, "Expected len 51, got %ld\n", len); + + /* test correct size, NULL szUrl */ + fill_url_components(&urlComp); + SetLastError(0xdeadbeef); + ret = InternetCreateUrlA(&urlComp, 0, NULL, &len); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); + ok(len == 51, "Expected len 51, got %ld\n", len); + + /* test valid lpUrlComponets, alloced szUrl, small size */ + SetLastError(0xdeadbeef); + szUrl = HeapAlloc(GetProcessHeap(), 0, len); + len -= 2; + ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "Expected ERROR_INSUFFICIENT_BUFFER, got %ld\n", GetLastError()); + ok(len == 51, "Expected len 51, got %ld\n", len); + + /* alloced szUrl, NULL lpszScheme + * shows that it uses dwXLength instead of strlen(lpszX) + */ + SetLastError(0xdeadbeef); + urlComp.lpszScheme = NULL; + ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len); + ok(ret, "Expected success\n"); + ok(GetLastError() == 0xdeadbeef, + "Expected 0xdeadbeef, got %ld\n", GetLastError()); + ok(len == 50, "Expected len 50, got %ld\n", len); + + /* alloced szUrl, invalid nScheme + * any nScheme out of range seems ignored + */ + fill_url_components(&urlComp); + SetLastError(0xdeadbeef); + urlComp.nScheme = -3; + len++; + ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len); + ok(ret, "Expected success\n"); + ok(GetLastError() == 0xdeadbeef, + "Expected 0xdeadbeef, got %ld\n", GetLastError()); + ok(len == 50, "Expected len 50, got %ld\n", len); + + /* test valid lpUrlComponets, alloced szUrl */ + fill_url_components(&urlComp); + SetLastError(0xdeadbeef); + len = 51; + ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len); + ok(ret, "Expected success\n"); + ok(GetLastError() == 0xdeadbeef, + "Expected 0xdeadbeef, got %ld\n", GetLastError()); + ok(len == 50, "Expected len 50, got %ld\n", len); + ok(strstr(szUrl, "80") == NULL, "Didn't expect to find 80 in szUrl\n"); + ok(!strcmp(szUrl, CREATE_URL1), "Expected %s, got %s\n", CREATE_URL1, szUrl); + + /* valid username, NULL password */ + fill_url_components(&urlComp); + SetLastError(0xdeadbeef); + urlComp.lpszPassword = NULL; + len = 42; + ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len); + ok(ret, "Expected success\n"); + ok(GetLastError() == 0xdeadbeef, + "Expected 0xdeadbeef, got %ld\n", GetLastError()); + ok(len == 41, "Expected len 41, got %ld\n", len); + ok(!strcmp(szUrl, CREATE_URL2), "Expected %s, got %s\n", CREATE_URL2, szUrl); + + /* valid username, empty password */ + fill_url_components(&urlComp); + SetLastError(0xdeadbeef); + urlComp.lpszPassword = ""; + len = 51; + ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len); + ok(ret, "Expected success\n"); + ok(GetLastError() == 0xdeadbeef, + "Expected 0xdeadbeef, got %ld\n", GetLastError()); + ok(len == 50, "Expected len 50, got %ld\n", len); + ok(!strcmp(szUrl, CREATE_URL3), "Expected %s, got %s\n", CREATE_URL2, szUrl); + + /* valid password, NULL username + * if password is provided, username has to exist + */ + fill_url_components(&urlComp); + SetLastError(0xdeadbeef); + urlComp.lpszUserName = NULL; + len = 42; + ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len); + ok(!ret, "Expected failure\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError()); + ok(len == 42, "Expected len 42, got %ld\n", len); + ok(!strcmp(szUrl, CREATE_URL3), "Expected %s, got %s\n", CREATE_URL2, szUrl); + + /* valid password, empty username + * if password is provided, username has to exist + */ + fill_url_components(&urlComp); + SetLastError(0xdeadbeef); + urlComp.lpszUserName = ""; + len = 51; + ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len); + ok(ret, "Expected success\n"); + ok(GetLastError() == 0xdeadbeef, + "Expected 0xdeadbeef, got %ld\n", GetLastError()); + ok(len == 50, "Expected len 50, got %ld\n", len); + ok(!strcmp(szUrl, CREATE_URL5), "Expected %s, got %s\n", CREATE_URL4, szUrl); + + /* NULL username, NULL password */ + fill_url_components(&urlComp); + SetLastError(0xdeadbeef); + urlComp.lpszUserName = NULL; + urlComp.lpszPassword = NULL; + len = 42; + ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len); + ok(ret, "Expected success\n"); + ok(GetLastError() == ERROR_ALREADY_EXISTS, + "Expected ERROR_ALREADYEXISTS, got %ld\n", GetLastError()); + ok(len == 32, "Expected len 32, got %ld\n", len); + ok(!strcmp(szUrl, CREATE_URL4), "Expected %s, got %s\n", CREATE_URL3, szUrl); + + /* empty username, empty password */ + fill_url_components(&urlComp); + SetLastError(0xdeadbeef); + urlComp.lpszUserName = ""; + urlComp.lpszPassword = ""; + len = 51; + ret = InternetCreateUrlA(&urlComp, 0, szUrl, &len); + ok(ret, "Expected success\n"); + ok(GetLastError() == 0xdeadbeef, + "Expected 0xdeadbeef, got %ld\n", GetLastError()); + ok(len == 50, "Expected len 50, got %ld\n", len); + ok(!strcmp(szUrl, CREATE_URL5), "Expected %s, got %s\n", CREATE_URL4, szUrl); + + /* if lpszScheme != "http" or nPort != 80, display nPort. + * depending on nScheme, displays only first x characters + * of lpszScheme: + * HTTP: x=4 + * FTP: x=3 etc + */ + fill_url_components(&urlComp); + HeapFree(GetProcessHeap(), 0, szUrl); + urlComp.lpszScheme = "nhttp"; + len = 54; + szUrl = HeapAlloc(GetProcessHeap(), 0, len); + ret = InternetCreateUrlA(&urlComp, ICU_ESCAPE, szUrl, &len); + ok(ret, "Expected success\n"); + ok(len == 53, "Expected len 51, got %ld\n", len); + ok(strstr(szUrl, "80") != NULL, "Expected to find 80 in szUrl\n"); + ok(!strncmp(szUrl, "nhtt://", 7), "Expected 'nhtt://'\n"); + ok(!strcmp(szUrl, CREATE_URL6), "Expected %s, got %s\n", CREATE_URL5, szUrl); + + /* if lpszScheme != "http" or nPort != 80, display nPort */ + HeapFree(GetProcessHeap(), 0, szUrl); + urlComp.lpszScheme = "http"; + urlComp.nPort = 42; + szUrl = HeapAlloc(GetProcessHeap(), 0, ++len); + ret = InternetCreateUrlA(&urlComp, ICU_ESCAPE, szUrl, &len); + ok(ret, "Expected success\n"); + ok(len == 53, "Expected len 53, got %ld\n", len); + ok(strstr(szUrl, "42") != NULL, "Expected to find 42 in szUrl\n"); + ok(!strcmp(szUrl, CREATE_URL7), "Expected %s, got %s\n", CREATE_URL6, szUrl); + + HeapFree(GetProcessHeap(), 0, szUrl); +} + START_TEST(http) { winapi_test(0x10000000); @@ -601,4 +845,5 @@ START_TEST(http) InternetTimeFromSystemTimeW_test(); InternetTimeToSystemTimeA_test(); InternetTimeToSystemTimeW_test(); + InternetCreateUrlA_test(); }