static HRESULT WINAPI URLMonikerImpl_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvObject) { URLMonikerImpl *This = (URLMonikerImpl*)iface; WCHAR schema[64]; BOOL bret; URL_COMPONENTSW url = {sizeof(URL_COMPONENTSW), schema, sizeof(schema)/sizeof(WCHAR), 0, NULL, 0, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0}; if(pmkToLeft) FIXME("Unsupported pmkToLeft\n"); bret = InternetCrackUrlW(This->URLName, 0, ICU_ESCAPE, &url); if(!bret) { ERR("InternetCrackUrl failed: %u\n", GetLastError()); return E_FAIL; } if(IsEqualGUID(&IID_IStream, riid) && ( url.nScheme == INTERNET_SCHEME_FTP || url.nScheme == INTERNET_SCHEME_GOPHER)) return URLMonikerImpl_BindToStorage_hack(This->URLName, pbc, ppvObject); TRACE("(%p)->(%p %p %s %p)\n", This, pbc, pmkToLeft, debugstr_guid(riid), ppvObject); return bind_to_storage(This->URLName, pbc, riid, ppvObject); }
inet_url_parts inet_crack_url(const wstring& url) { wstring url2=inet_canonicalize_url(url); inet_url_parts parts; URL_COMPONENTS url_components; memset(&url_components,0,sizeof(url_components)); url_components.dwStructSize=sizeof(url_components); url_components.dwSchemeLength=1; url_components.dwHostNameLength=1; url_components.dwUserNameLength=1; url_components.dwPasswordLength=1; url_components.dwUrlPathLength=1; url_components.dwExtraInfoLength=1; if(!InternetCrackUrlW(url2.c_str(),0,0,&url_components)) return parts; parts.scheme_str=wstring(url_components.lpszScheme,url_components.dwSchemeLength); parts.hostname=wstring(url_components.lpszHostName,url_components.dwHostNameLength); parts.username=wstring(url_components.lpszUserName,url_components.dwUserNameLength); parts.password=wstring(url_components.lpszPassword,url_components.dwPasswordLength); parts.url_path=wstring(url_components.lpszUrlPath,url_components.dwUrlPathLength); parts.extra_info=wstring(url_components.lpszExtraInfo,url_components.dwExtraInfoLength); parts.scheme=url_components.nScheme; parts.port=url_components.nPort; return parts; }
static void _get_host(SG_context* pCtx, const char* szRepoSpec, SG_string** ppstrHost) { LPWSTR pwszRepoSpec = NULL; SG_uint32 len = 0; URL_COMPONENTSW UrlComponents; SG_string* pstrHost = NULL; WCHAR buf[260]; SG_zero(UrlComponents); UrlComponents.dwStructSize = sizeof(URL_COMPONENTS); UrlComponents.dwHostNameLength = sizeof(buf); UrlComponents.lpszHostName = buf; SG_ERR_CHECK( SG_utf8__extern_to_os_buffer__wchar(pCtx, szRepoSpec, &pwszRepoSpec, &len) ); if ( !InternetCrackUrlW(pwszRepoSpec, len, ICU_DECODE, &UrlComponents) ) SG_ERR_THROW2( SG_ERR_GETLASTERROR(GetLastError()), (pCtx, "unable to parse host from URL") ); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstrHost) ); SG_ERR_CHECK( SG_utf8__intern_from_os_buffer__wchar(pCtx, pstrHost, UrlComponents.lpszHostName) ); SG_RETURN_AND_NULL(pstrHost, ppstrHost); /* fall through */ fail: SG_NULLFREE(pCtx, pwszRepoSpec); SG_STRING_NULLFREE(pCtx, pstrHost); }
BOOL DownloadWebPagePostW(std::string& page, HINTERNET hInternet, LPCWSTR url, LPCSTR postData) { TRACEST(_T("DownloadWebPagePostW"), CW2CT(url)); BOOL bRet = FALSE; URL_COMPONENTSW comp; memset(&comp, 0, sizeof(URL_COMPONENTSW)); comp.dwStructSize = sizeof(URL_COMPONENTSW); WCHAR hostName[100], URI[100]; comp.dwHostNameLength = comp.dwUrlPathLength = 100; comp.lpszHostName = hostName; comp.lpszUrlPath = URI; if (InternetCrackUrlW(url, 0, ICU_ESCAPE, &comp)) { HINTERNET hConnection = InternetConnectW(hInternet, comp.lpszHostName, comp.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_CACHE_WRITE, 0); if (hConnection) { LPCTSTR sAcceptTypes[] = {L"*/*",NULL}; HINTERNET hRequest=::HttpOpenRequestW(hConnection, L"POST", // HTTP Verb comp.lpszUrlPath, // Object Name HTTP_VERSION, // Version NULL, // Reference sAcceptTypes, // Accept Type INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_FORMS_SUBMIT, 0); // context call-back point if(hRequest) { static LPCWSTR sHttpAccept = L"Accept: */*\r\n"; ::HttpAddRequestHeadersW(hRequest, sHttpAccept, (DWORD)wcslen(sHttpAccept), HTTP_ADDREQ_FLAG_ADD_IF_NEW); static LPCWSTR szContentType = L"Content-Type: application/x-www-form-urlencoded\r\n"; if(::HttpSendRequestW(hRequest, szContentType, (DWORD)wcslen(szContentType), (LPVOID)postData, (DWORD)strlen(postData))) bRet = ReadInternetFile2StringW(hRequest, page); else HandleInternetError(_T("DownloadWebPagePostW. HttpSendRequestW")); InternetCloseHandle(hRequest); } else HandleInternetError(_T("DownloadWebPagePostW. InternetConnectW")); InternetCloseHandle(hConnection); } else HandleInternetError(_T("DownloadWebPagePostW. InternetConnectW")); } else HandleInternetError(_T("DownloadWebPagePostW. InternetCrackUrlW")); return bRet; }
void InetInsertCookies(HTTP_REQUEST_HANDLE *lpReq) { if ((lpReq) && (lpReq->dwType == HTTP_REQUEST)) { EnterSafeCriticalSection(&lpReq->lpUrl->lpSession->csSession); { WCHAR *lpUrl=NULL, *lpPath=NULL, *lpHost=NULL; do { DWORD dwLen=INTERNET_MAX_URL_LENGTH*sizeof(WCHAR); lpUrl=(WCHAR*)MemQuickAlloc(dwLen); if (!lpUrl) break; if (!InternetQueryOptionW(lpReq->hReq,INTERNET_OPTION_URL,lpUrl,&dwLen)) break; lpPath=WCHAR_QuickAlloc(INTERNET_MAX_PATH_LENGTH); if (!lpPath) break; lpHost=WCHAR_QuickAlloc(INTERNET_MAX_HOST_NAME_LENGTH); if (!lpHost) break; URL_COMPONENTSW url={0}; url.dwStructSize=sizeof(url); url.lpszHostName=lpHost; url.dwHostNameLength=INTERNET_MAX_HOST_NAME_LENGTH; url.lpszUrlPath=lpPath; url.dwUrlPathLength=INTERNET_MAX_PATH_LENGTH; if (!InternetCrackUrlW(lpUrl,NULL,0,&url)) break; WCHAR *lpCookies=NULL; if (Cookie_Get(lpReq->lpUrl->lpSession,lpHost,lpPath,&lpCookies,(url.nScheme == INTERNET_SCHEME_HTTPS),url.nPort)) { HttpAddRequestHeadersW(lpReq->hReq,lpCookies,-1,HTTP_ADDREQ_FLAG_ADD); MemFree(lpCookies); } } while (false); MemFree(lpUrl); MemFree(lpPath); MemFree(lpHost); } LeaveSafeCriticalSection(&lpReq->lpUrl->lpSession->csSession); } return; }
static HRESULT get_url_components(HTMLLocation *This, URL_COMPONENTSW *url) { const WCHAR *doc_url; HRESULT hres; hres = get_url(This, &doc_url); if(FAILED(hres)) return hres; if(!InternetCrackUrlW(doc_url, 0, 0, url)) { FIXME("InternetCrackUrlW failed: 0x%08x\n", GetLastError()); SetLastError(0); return E_FAIL; } return S_OK; }
static DWORD WINAPI ThreadFunc(LPVOID Context) { CComPtr<IBindStatusCallback> dl; WCHAR path[MAX_PATH]; LPWSTR p; HWND Dlg = (HWND) Context; ULONG dwContentLen, dwBytesWritten, dwBytesRead, dwStatus; ULONG dwCurrentBytesRead = 0; ULONG dwStatusLen = sizeof(dwStatus); BOOL bCancelled = FALSE; BOOL bTempfile = FALSE; BOOL bCab = FALSE; HINTERNET hOpen = NULL; HINTERNET hFile = NULL; HANDLE hOut = INVALID_HANDLE_VALUE; unsigned char lpBuffer[4096]; PCWSTR lpszAgent = L"RApps/1.0"; URL_COMPONENTS urlComponents; size_t urlLength; /* built the path for the download */ p = wcsrchr(AppInfo->szUrlDownload, L'/'); if (!p) goto end; if (wcscmp(AppInfo->szUrlDownload, APPLICATION_DATABASE_URL) == 0) { bCab = TRUE; if (!GetStorageDirectory(path, sizeof(path) / sizeof(path[0]))) goto end; } else { if (FAILED(StringCbCopyW(path, sizeof(path), SettingsInfo.szDownloadDir))) goto end; } if (GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES) { if (!CreateDirectoryW(path, NULL)) goto end; } if (FAILED(StringCbCatW(path, sizeof(path), L"\\"))) goto end; if (FAILED(StringCbCatW(path, sizeof(path), p + 1))) goto end; /* download it */ bTempfile = TRUE; CDownloadDialog_Constructor(Dlg, &bCancelled, IID_PPV_ARG(IBindStatusCallback, &dl)); if (dl == NULL) goto end; switch(SettingsInfo.Proxy) { case 0: /* preconfig */ hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); break; case 1: /* direct (no proxy) */ hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); break; case 2: /* use proxy */ hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_PROXY, SettingsInfo.szProxyServer, SettingsInfo.szNoProxyFor, 0); break; default: /* preconfig */ hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); break; } if (!hOpen) goto end; hFile = InternetOpenUrlW(hOpen, AppInfo->szUrlDownload, NULL, 0, INTERNET_FLAG_PRAGMA_NOCACHE|INTERNET_FLAG_KEEP_CONNECTION, 0); if (!hFile) goto end; if (!HttpQueryInfoW(hFile, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwStatusLen, NULL)) goto end; if(dwStatus != HTTP_STATUS_OK) { WCHAR szMsgText[MAX_STR_LEN]; if (!LoadStringW(hInst, IDS_UNABLE_TO_DOWNLOAD, szMsgText, sizeof(szMsgText) / sizeof(WCHAR))) goto end; MessageBoxW(hMainWnd, szMsgText, NULL, MB_OK | MB_ICONERROR); goto end; } dwStatusLen = sizeof(dwStatus); memset(&urlComponents, 0, sizeof(urlComponents)); urlComponents.dwStructSize = sizeof(urlComponents); if(FAILED(StringCbLengthW(AppInfo->szUrlDownload, sizeof(AppInfo->szUrlDownload), &urlLength))) goto end; urlComponents.dwSchemeLength = urlLength*sizeof(WCHAR); urlComponents.lpszScheme = (PWSTR)malloc(urlComponents.dwSchemeLength); if(!InternetCrackUrlW(AppInfo->szUrlDownload, urlLength+1, ICU_DECODE | ICU_ESCAPE, &urlComponents)) goto end; if(urlComponents.nScheme == INTERNET_SCHEME_HTTP || urlComponents.nScheme == INTERNET_SCHEME_HTTPS) HttpQueryInfo(hFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &dwContentLen, &dwStatus, 0); if(urlComponents.nScheme == INTERNET_SCHEME_FTP) dwContentLen = FtpGetFileSize(hFile, &dwStatus); free(urlComponents.lpszScheme); hOut = CreateFileW(path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL); if (hOut == INVALID_HANDLE_VALUE) goto end; do { if (!InternetReadFile(hFile, lpBuffer, _countof(lpBuffer), &dwBytesRead)) goto end; if (!WriteFile(hOut, &lpBuffer[0], dwBytesRead, &dwBytesWritten, NULL)) goto end; dwCurrentBytesRead += dwBytesRead; dl->OnProgress(dwCurrentBytesRead, dwContentLen, 0, AppInfo->szUrlDownload); } while (dwBytesRead); CloseHandle(hOut); hOut = INVALID_HANDLE_VALUE; if (bCancelled) goto end; ShowWindow(Dlg, SW_HIDE); /* run it */ if (!bCab) ShellExecuteW( NULL, L"open", path, NULL, NULL, SW_SHOWNORMAL ); end: if (hOut != INVALID_HANDLE_VALUE) CloseHandle(hOut); InternetCloseHandle(hFile); InternetCloseHandle(hOpen); if (bTempfile) { if (bCancelled || (SettingsInfo.bDelInstaller && !bCab)) DeleteFileW(path); } EndDialog(Dlg, 0); return 0; }
static void InternetCrackUrlW_test(void) { WCHAR url[] = { 'h','t','t','p',':','/','/','1','9','2','.','1','6','8','.','0','.','2','2','/', 'C','F','I','D','E','/','m','a','i','n','.','c','f','m','?','C','F','S','V','R', '=','I','D','E','&','A','C','T','I','O','N','=','I','D','E','_','D','E','F','A', 'U','L','T', 0 }; static const WCHAR url2[] = { '.','.','/','R','i','t','z','.','x','m','l',0 }; static const WCHAR url3[] = { 'h','t','t','p',':','/','/','x','.','o','r','g',0 }; URL_COMPONENTSW comp; WCHAR scheme[20], host[20], user[20], pwd[20], urlpart[50], extra[50]; DWORD error; BOOL r; urlpart[0]=0; scheme[0]=0; extra[0]=0; host[0]=0; user[0]=0; pwd[0]=0; memset(&comp, 0, sizeof comp); comp.dwStructSize = sizeof(comp); comp.lpszScheme = scheme; comp.dwSchemeLength = sizeof(scheme)/sizeof(scheme[0]); comp.lpszHostName = host; comp.dwHostNameLength = sizeof(host)/sizeof(host[0]); comp.lpszUserName = user; comp.dwUserNameLength = sizeof(user)/sizeof(user[0]); comp.lpszPassword = pwd; comp.dwPasswordLength = sizeof(pwd)/sizeof(pwd[0]); comp.lpszUrlPath = urlpart; comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]); comp.lpszExtraInfo = extra; comp.dwExtraInfoLength = sizeof(extra)/sizeof(extra[0]); SetLastError(0xdeadbeef); r = InternetCrackUrlW(NULL, 0, 0, &comp ); error = GetLastError(); if (!r && error == ERROR_CALL_NOT_IMPLEMENTED) { win_skip("InternetCrackUrlW is not implemented\n"); return; } ok( !r, "InternetCrackUrlW succeeded unexpectedly\n"); ok( error == ERROR_INVALID_PARAMETER || broken(error == ERROR_INTERNET_UNRECOGNIZED_SCHEME), /* IE5 */ "expected ERROR_INVALID_PARAMETER got %u\n", error); if (error == ERROR_INVALID_PARAMETER) { /* Crashes on IE5 */ SetLastError(0xdeadbeef); r = InternetCrackUrlW(url, 0, 0, NULL ); error = GetLastError(); ok( !r, "InternetCrackUrlW succeeded unexpectedly\n"); ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error); } r = InternetCrackUrlW(url, 0, 0, &comp ); ok( r, "failed to crack url\n"); ok( comp.dwSchemeLength == 4, "scheme length wrong\n"); ok( comp.dwHostNameLength == 12, "host length wrong\n"); ok( comp.dwUserNameLength == 0, "user length wrong\n"); ok( comp.dwPasswordLength == 0, "password length wrong\n"); ok( comp.dwUrlPathLength == 15, "url length wrong\n"); ok( comp.dwExtraInfoLength == 29, "extra length wrong\n"); urlpart[0]=0; scheme[0]=0; extra[0]=0; host[0]=0; user[0]=0; pwd[0]=0; memset(&comp, 0, sizeof comp); comp.dwStructSize = sizeof comp; comp.lpszHostName = host; comp.dwHostNameLength = sizeof(host)/sizeof(host[0]); comp.lpszUrlPath = urlpart; comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]); r = InternetCrackUrlW(url, 0, 0, &comp ); ok( r, "failed to crack url\n"); ok( comp.dwSchemeLength == 0, "scheme length wrong\n"); ok( comp.dwHostNameLength == 12, "host length wrong\n"); ok( comp.dwUserNameLength == 0, "user length wrong\n"); ok( comp.dwPasswordLength == 0, "password length wrong\n"); ok( comp.dwUrlPathLength == 44, "url length wrong\n"); ok( comp.dwExtraInfoLength == 0, "extra length wrong\n"); urlpart[0]=0; scheme[0]=0; extra[0]=0; host[0]=0; user[0]=0; pwd[0]=0; memset(&comp, 0, sizeof comp); comp.dwStructSize = sizeof comp; comp.lpszHostName = host; comp.dwHostNameLength = sizeof(host)/sizeof(host[0]); comp.lpszUrlPath = urlpart; comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]); comp.lpszExtraInfo = NULL; comp.dwExtraInfoLength = sizeof(extra)/sizeof(extra[0]); r = InternetCrackUrlW(url, 0, 0, &comp ); ok( r, "failed to crack url\n"); ok( comp.dwSchemeLength == 0, "scheme length wrong\n"); ok( comp.dwHostNameLength == 12, "host length wrong\n"); ok( comp.dwUserNameLength == 0, "user length wrong\n"); ok( comp.dwPasswordLength == 0, "password length wrong\n"); ok( comp.dwUrlPathLength == 15, "url length wrong\n"); ok( comp.dwExtraInfoLength == 29, "extra length wrong\n"); urlpart[0]=0; scheme[0]=0; extra[0]=0; host[0]=0; user[0]=0; pwd[0]=0; memset(&comp, 0, sizeof(comp)); comp.dwStructSize = sizeof(comp); comp.lpszScheme = scheme; comp.dwSchemeLength = sizeof(scheme)/sizeof(scheme[0]); comp.lpszHostName = host; comp.dwHostNameLength = sizeof(host)/sizeof(host[0]); comp.lpszUserName = user; comp.dwUserNameLength = sizeof(user)/sizeof(user[0]); comp.lpszPassword = pwd; comp.dwPasswordLength = sizeof(pwd)/sizeof(pwd[0]); comp.lpszUrlPath = urlpart; comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]); comp.lpszExtraInfo = extra; comp.dwExtraInfoLength = sizeof(extra)/sizeof(extra[0]); r = InternetCrackUrlW(url2, 0, 0, &comp); todo_wine { ok(!r, "InternetCrackUrl should have failed\n"); ok(GetLastError() == ERROR_INTERNET_UNRECOGNIZED_SCHEME, "InternetCrackUrl should have failed with error ERROR_INTERNET_UNRECOGNIZED_SCHEME instead of error %d\n", GetLastError()); } /* Test to see whether cracking a URL without a filename initializes urlpart */ urlpart[0]=0xba; scheme[0]=0; extra[0]=0; host[0]=0; user[0]=0; pwd[0]=0; memset(&comp, 0, sizeof comp); comp.dwStructSize = sizeof comp; comp.lpszScheme = scheme; comp.dwSchemeLength = sizeof(scheme)/sizeof(scheme[0]); comp.lpszHostName = host; comp.dwHostNameLength = sizeof(host)/sizeof(host[0]); comp.lpszUserName = user; comp.dwUserNameLength = sizeof(user)/sizeof(user[0]); comp.lpszPassword = pwd; comp.dwPasswordLength = sizeof(pwd)/sizeof(pwd[0]); comp.lpszUrlPath = urlpart; comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]); comp.lpszExtraInfo = extra; comp.dwExtraInfoLength = sizeof(extra)/sizeof(extra[0]); r = InternetCrackUrlW(url3, 0, 0, &comp ); ok( r, "InternetCrackUrlW failed unexpectedly\n"); ok( host[0] == 'x', "host should be x.org\n"); ok( urlpart[0] == 0, "urlpart should be empty\n"); }
static void test_crack_url(const crack_url_test_t *test) { WCHAR buf[INTERNET_MAX_URL_LENGTH]; URL_COMPONENTSW urlw; URL_COMPONENTSA url; BOOL b; zero_compsA(&url, 1, 1, 1, 1, 1, 1); b = InternetCrackUrlA(test->url, strlen(test->url), 0, &url); ok(b, "InternetCrackUrl failed with error %d\n", GetLastError()); if(test->scheme_off == -1) ok(!url.lpszScheme, "[%s] url.lpszScheme = %p, expected NULL\n", test->url, url.lpszScheme); else ok(url.lpszScheme == test->url+test->scheme_off, "[%s] url.lpszScheme = %p, expected %p\n", test->url, url.lpszScheme, test->url+test->scheme_off); ok(url.dwSchemeLength == test->scheme_len, "[%s] url.lpszSchemeLength = %d, expected %d\n", test->url, url.dwSchemeLength, test->scheme_len); ok(url.nScheme == test->scheme, "[%s] url.nScheme = %d, expected %d\n", test->url, url.nScheme, test->scheme); if(test->host_off == -1) ok(!url.lpszHostName, "[%s] url.lpszHostName = %p, expected NULL\n", test->url, url.lpszHostName); else ok(url.lpszHostName == test->url+test->host_off, "[%s] url.lpszHostName = %p, expected %p\n", test->url, url.lpszHostName, test->url+test->host_off); if(test->host_skip_broken != -1 && url.dwHostNameLength == test->host_skip_broken) { win_skip("skipping broken dwHostNameLength result\n"); return; } ok(url.dwHostNameLength == test->host_len, "[%s] url.lpszHostNameLength = %d, expected %d\n", test->url, url.dwHostNameLength, test->host_len); ok(url.nPort == test->port, "[%s] nPort = %d, expected %d\n", test->url, url.nPort, test->port); if(test->user_off == -1) ok(!url.lpszUserName, "[%s] url.lpszUserName = %p\n", test->url, url.lpszUserName); else ok(url.lpszUserName == test->url+test->user_off, "[%s] url.lpszUserName = %p, expected %p\n", test->url, url.lpszUserName, test->url+test->user_off); ok(url.dwUserNameLength == test->user_len, "[%s] url.lpszUserNameLength = %d, expected %d\n", test->url, url.dwUserNameLength, test->user_len); if(test->pass_off == -1) ok(!url.lpszPassword, "[%s] url.lpszPassword = %p\n", test->url, url.lpszPassword); else ok(url.lpszPassword == test->url+test->pass_off, "[%s] url.lpszPassword = %p, expected %p\n", test->url, url.lpszPassword, test->url+test->pass_off); ok(url.dwPasswordLength == test->pass_len, "[%s] url.lpszPasswordLength = %d, expected %d\n", test->url, url.dwPasswordLength, test->pass_len); if(test->path_off == -1) ok(!url.lpszUrlPath, "[%s] url.lpszPath = %p, expected NULL\n", test->url, url.lpszUrlPath); else ok(url.lpszUrlPath == test->url+test->path_off, "[%s] url.lpszPath = %p, expected %p\n", test->url, url.lpszUrlPath, test->url+test->path_off); ok(url.dwUrlPathLength == test->path_len, "[%s] url.lpszUrlPathLength = %d, expected %d\n", test->url, url.dwUrlPathLength, test->path_len); if(test->extra_off == -1) ok(!url.lpszExtraInfo, "[%s] url.lpszExtraInfo = %p, expected NULL\n", test->url, url.lpszExtraInfo); else ok(url.lpszExtraInfo == test->url+test->extra_off, "[%s] url.lpszExtraInfo = %p, expected %p\n", test->url, url.lpszExtraInfo, test->url+test->extra_off); ok(url.dwExtraInfoLength == test->extra_len, "[%s] url.lpszExtraInfoLength = %d, expected %d\n", test->url, url.dwExtraInfoLength, test->extra_len); memset(&urlw, 0, sizeof(URL_COMPONENTSW)); urlw.dwStructSize = sizeof(URL_COMPONENTSW); urlw.dwSchemeLength = 1; urlw.dwHostNameLength = 1; urlw.dwUserNameLength = 1; urlw.dwPasswordLength = 1; urlw.dwUrlPathLength = 1; urlw.dwExtraInfoLength = 1; MultiByteToWideChar(CP_ACP, 0, test->url, -1, buf, sizeof(buf)/sizeof(buf[0])); b = InternetCrackUrlW(buf, lstrlenW(buf), 0, &urlw); if(!b && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { win_skip("InternetCrackUrlW is not implemented\n"); return; } ok(b, "InternetCrackUrl failed with error %d\n", GetLastError()); if(test->scheme_off == -1) ok(!urlw.lpszScheme, "[%s] urlw.lpszScheme = %p, expected NULL\n", test->url, urlw.lpszScheme); else ok(urlw.lpszScheme == buf+test->scheme_off, "[%s] urlw.lpszScheme = %p, expected %p\n", test->url, urlw.lpszScheme, buf+test->scheme_off); ok(urlw.dwSchemeLength == test->scheme_len, "[%s] urlw.lpszSchemeLength = %d, expected %d\n", test->url, urlw.dwSchemeLength, test->scheme_len); ok(urlw.nScheme == test->scheme, "[%s] urlw.nScheme = %d, expected %d\n", test->url, urlw.nScheme, test->scheme); if(test->host_off == -1) { ok(!urlw.lpszHostName, "[%s] urlw.lpszHostName = %p, expected NULL\n", test->url, urlw.lpszHostName); ok(urlw.dwHostNameLength == 0 || broken(urlw.dwHostNameLength == 1), "[%s] urlw.lpszHostNameLength = %d, expected %d\n", test->url, urlw.dwHostNameLength, test->host_len); }else { ok(urlw.lpszHostName == buf+test->host_off, "[%s] urlw.lpszHostName = %p, expected %p\n", test->url, urlw.lpszHostName, test->url+test->host_off); ok(urlw.dwHostNameLength == test->host_len, "[%s] urlw.lpszHostNameLength = %d, expected %d\n", test->url, urlw.dwHostNameLength, test->host_len); } ok(urlw.nPort == test->port, "[%s] nPort = %d, expected %d\n", test->url, urlw.nPort, test->port); if(test->user_off == -1) { ok(!urlw.lpszUserName, "[%s] urlw.lpszUserName = %p\n", test->url, urlw.lpszUserName); ok(urlw.dwUserNameLength == 0 || broken(urlw.dwUserNameLength == 1), "[%s] urlw.lpszUserNameLength = %d, expected %d\n", test->url, urlw.dwUserNameLength, test->user_len); }else { ok(urlw.lpszUserName == buf+test->user_off, "[%s] urlw.lpszUserName = %p, expected %p\n", test->url, urlw.lpszUserName, buf+test->user_off); ok(urlw.dwUserNameLength == test->user_len, "[%s] urlw.lpszUserNameLength = %d, expected %d\n", test->url, urlw.dwUserNameLength, test->user_len); } if(test->pass_off == -1) { ok(!urlw.lpszPassword, "[%s] urlw.lpszPassword = %p\n", test->url, urlw.lpszPassword); ok(urlw.dwPasswordLength == 0 || broken(urlw.dwPasswordLength), "[%s] urlw.lpszPasswordLength = %d, expected %d\n", test->url, urlw.dwPasswordLength, test->pass_len); }else { ok(urlw.lpszPassword == buf+test->pass_off, "[%s] urlw.lpszPassword = %p, expected %p\n", test->url, urlw.lpszPassword, buf+test->pass_off); ok(urlw.dwPasswordLength == test->pass_len, "[%s] urlw.lpszPasswordLength = %d, expected %d\n", test->url, urlw.dwPasswordLength, test->pass_len); } if(test->path_off == -1) ok(!urlw.lpszUrlPath, "[%s] urlw.lpszPath = %p, expected NULL\n", test->url, urlw.lpszUrlPath); else ok(urlw.lpszUrlPath == buf+test->path_off, "[%s] urlw.lpszPath = %p, expected %p\n", test->url, urlw.lpszUrlPath, buf+test->path_off); ok(urlw.dwUrlPathLength == test->path_len, "[%s] urlw.lpszUrlPathLength = %d, expected %d\n", test->url, urlw.dwUrlPathLength, test->path_len); if(test->extra_off == -1) { ok(!urlw.lpszExtraInfo, "[%s] url.lpszExtraInfo = %p, expected NULL\n", test->url, urlw.lpszExtraInfo); ok(urlw.dwExtraInfoLength == 0 || broken(urlw.dwExtraInfoLength == 1), "[%s] urlw.lpszExtraInfoLength = %d, expected %d\n", test->url, urlw.dwExtraInfoLength, test->extra_len); }else { ok(urlw.lpszExtraInfo == buf+test->extra_off, "[%s] urlw.lpszExtraInfo = %p, expected %p\n", test->url, urlw.lpszExtraInfo, buf+test->extra_off); ok(urlw.dwExtraInfoLength == test->extra_len, "[%s] urlw.lpszExtraInfoLength = %d, expected %d\n", test->url, urlw.dwExtraInfoLength, test->extra_len); } }
void InetProcessCookies(HTTP_REQUEST_HANDLE *lpReq) { if ((lpReq) && (lpReq->dwType == HTTP_REQUEST)) { EnterSafeCriticalSection(&lpReq->lpUrl->lpSession->csSession); { WCHAR *lpUrl=NULL, *lpPath=NULL, *lpHost=NULL; do { DWORD dwLen=INTERNET_MAX_URL_LENGTH*sizeof(WCHAR); lpUrl=(WCHAR*)MemQuickAlloc(dwLen); if (!lpUrl) break; if (!InternetQueryOptionW(lpReq->hReq,INTERNET_OPTION_URL,lpUrl,&dwLen)) break; lpPath=WCHAR_QuickAlloc(INTERNET_MAX_PATH_LENGTH); if (!lpPath) break; lpHost=WCHAR_QuickAlloc(INTERNET_MAX_HOST_NAME_LENGTH); if (!lpHost) break; URL_COMPONENTSW url={0}; url.dwStructSize=sizeof(url); url.lpszHostName=lpHost; url.dwHostNameLength=INTERNET_MAX_HOST_NAME_LENGTH; url.lpszUrlPath=lpPath; url.dwUrlPathLength=INTERNET_MAX_PATH_LENGTH; if (!InternetCrackUrlW(lpUrl,NULL,0,&url)) break; DWORD i=0; while (true) { WCHAR *lpCookie=NULL,szTmp[1]; DWORD dwSize=0; if ((HttpQueryInfoW(lpReq->hReq,HTTP_QUERY_SET_COOKIE,szTmp,&dwSize,&i)) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) break; dwSize+=2; lpCookie=(WCHAR*)MemQuickAlloc(dwSize); if (!lpCookie) break; if (HttpQueryInfoW(lpReq->hReq,HTTP_QUERY_SET_COOKIE,lpCookie,&dwSize,&i)) { WCHAR *lpData=StrChrW(lpCookie,L'='); if (lpData) { *lpData++=0; Cookie_Parse(lpReq->lpUrl->lpSession,lpHost,lpPath,lpCookie,lpData); } } MemFree(lpCookie); } } while (false); MemFree(lpUrl); MemFree(lpPath); MemFree(lpHost); } LeaveSafeCriticalSection(&lpReq->lpUrl->lpSession->csSession); } return; }
static void InternetCrackUrlW_test(void) { WCHAR url[] = { 'h','t','t','p',':','/','/','1','9','2','.','1','6','8','.','0','.','2','2','/', 'C','F','I','D','E','/','m','a','i','n','.','c','f','m','?','C','F','S','V','R', '=','I','D','E','&','A','C','T','I','O','N','=','I','D','E','_','D','E','F','A', 'U','L','T', 0 }; static const WCHAR url2[] = { '.','.','/','R','i','t','z','.','x','m','l',0 }; URL_COMPONENTSW comp; WCHAR scheme[20], host[20], user[20], pwd[20], urlpart[50], extra[50]; DWORD error; BOOL r; urlpart[0]=0; scheme[0]=0; extra[0]=0; host[0]=0; user[0]=0; pwd[0]=0; memset(&comp, 0, sizeof comp); comp.dwStructSize = sizeof comp; comp.lpszScheme = scheme; comp.dwSchemeLength = sizeof scheme; comp.lpszHostName = host; comp.dwHostNameLength = sizeof host; comp.lpszUserName = user; comp.dwUserNameLength = sizeof user; comp.lpszPassword = pwd; comp.dwPasswordLength = sizeof pwd; comp.lpszUrlPath = urlpart; comp.dwUrlPathLength = sizeof urlpart; comp.lpszExtraInfo = extra; comp.dwExtraInfoLength = sizeof extra; SetLastError(0xdeadbeef); r = InternetCrackUrlW(NULL, 0, 0, &comp ); error = GetLastError(); ok( !r, "InternetCrackUrlW succeeded unexpectedly\n"); ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error); SetLastError(0xdeadbeef); r = InternetCrackUrlW(url, 0, 0, NULL ); error = GetLastError(); ok( !r, "InternetCrackUrlW succeeded unexpectedly\n"); ok( error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error); r = InternetCrackUrlW(url, 0, 0, &comp ); ok( r, "failed to crack url\n"); ok( comp.dwSchemeLength == 4, "scheme length wrong\n"); ok( comp.dwHostNameLength == 12, "host length wrong\n"); ok( comp.dwUserNameLength == 0, "user length wrong\n"); ok( comp.dwPasswordLength == 0, "password length wrong\n"); ok( comp.dwUrlPathLength == 15, "url length wrong\n"); ok( comp.dwExtraInfoLength == 29, "extra length wrong\n"); urlpart[0]=0; scheme[0]=0; extra[0]=0; host[0]=0; user[0]=0; pwd[0]=0; memset(&comp, 0, sizeof comp); comp.dwStructSize = sizeof comp; comp.lpszHostName = host; comp.dwHostNameLength = sizeof host; comp.lpszUrlPath = urlpart; comp.dwUrlPathLength = sizeof urlpart; r = InternetCrackUrlW(url, 0, 0, &comp ); ok( r, "failed to crack url\n"); ok( comp.dwSchemeLength == 0, "scheme length wrong\n"); ok( comp.dwHostNameLength == 12, "host length wrong\n"); ok( comp.dwUserNameLength == 0, "user length wrong\n"); ok( comp.dwPasswordLength == 0, "password length wrong\n"); ok( comp.dwUrlPathLength == 44, "url length wrong\n"); ok( comp.dwExtraInfoLength == 0, "extra length wrong\n"); urlpart[0]=0; scheme[0]=0; extra[0]=0; host[0]=0; user[0]=0; pwd[0]=0; memset(&comp, 0, sizeof comp); comp.dwStructSize = sizeof comp; comp.lpszHostName = host; comp.dwHostNameLength = sizeof host; comp.lpszUrlPath = urlpart; comp.dwUrlPathLength = sizeof urlpart; comp.lpszExtraInfo = NULL; comp.dwExtraInfoLength = sizeof extra; r = InternetCrackUrlW(url, 0, 0, &comp ); ok( r, "failed to crack url\n"); ok( comp.dwSchemeLength == 0, "scheme length wrong\n"); ok( comp.dwHostNameLength == 12, "host length wrong\n"); ok( comp.dwUserNameLength == 0, "user length wrong\n"); ok( comp.dwPasswordLength == 0, "password length wrong\n"); ok( comp.dwUrlPathLength == 15, "url length wrong\n"); ok( comp.dwExtraInfoLength == 29, "extra length wrong\n"); urlpart[0]=0; scheme[0]=0; extra[0]=0; host[0]=0; user[0]=0; pwd[0]=0; memset(&comp, 0, sizeof(comp)); comp.dwStructSize = sizeof(comp); comp.lpszScheme = scheme; comp.dwSchemeLength = sizeof(scheme)/sizeof(scheme[0]); comp.lpszHostName = host; comp.dwHostNameLength = sizeof(host)/sizeof(host[0]); comp.lpszUserName = user; comp.dwUserNameLength = sizeof(user)/sizeof(user[0]); comp.lpszPassword = pwd; comp.dwPasswordLength = sizeof(pwd)/sizeof(pwd[0]); comp.lpszUrlPath = urlpart; comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]); comp.lpszExtraInfo = extra; comp.dwExtraInfoLength = sizeof(extra)/sizeof(extra[0]); r = InternetCrackUrlW(url2, 0, 0, &comp); todo_wine { ok(!r, "InternetCrackUrl should have failed\n"); ok(GetLastError() == ERROR_INTERNET_UNRECOGNIZED_SCHEME, "InternetCrackUrl should have failed with error ERROR_INTERNET_UNRECOGNIZED_SCHEME instead of error %d\n", GetLastError()); } }
static HRESULT HttpProtocol_open_request(Protocol *prot, LPCWSTR url, DWORD request_flags, HINTERNET internet_session, IInternetBindInfo *bind_info) { HttpProtocol *This = ASYNCPROTOCOL_THIS(prot); LPWSTR addl_header = NULL, post_cookie = NULL, optional = NULL; IServiceProvider *service_provider = NULL; IHttpNegotiate2 *http_negotiate2 = NULL; LPWSTR host, user, pass, path; LPOLESTR accept_mimes[257]; URL_COMPONENTSW url_comp; BYTE security_id[512]; DWORD len = 0; ULONG num; BOOL res, b; HRESULT hres; static const WCHAR wszBindVerb[BINDVERB_CUSTOM][5] = {{'G','E','T',0}, {'P','O','S','T',0}, {'P','U','T',0}}; memset(&url_comp, 0, sizeof(url_comp)); url_comp.dwStructSize = sizeof(url_comp); url_comp.dwSchemeLength = url_comp.dwHostNameLength = url_comp.dwUrlPathLength = url_comp.dwExtraInfoLength = url_comp.dwUserNameLength = url_comp.dwPasswordLength = 1; if (!InternetCrackUrlW(url, 0, 0, &url_comp)) return MK_E_SYNTAX; if(!url_comp.nPort) url_comp.nPort = This->https ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT; host = heap_strndupW(url_comp.lpszHostName, url_comp.dwHostNameLength); user = heap_strndupW(url_comp.lpszUserName, url_comp.dwUserNameLength); pass = heap_strndupW(url_comp.lpszPassword, url_comp.dwPasswordLength); This->base.connection = InternetConnectW(internet_session, host, url_comp.nPort, user, pass, INTERNET_SERVICE_HTTP, This->https ? INTERNET_FLAG_SECURE : 0, (DWORD_PTR)&This->base); heap_free(pass); heap_free(user); heap_free(host); if(!This->base.connection) { WARN("InternetConnect failed: %d\n", GetLastError()); return INET_E_CANNOT_CONNECT; } num = sizeof(accept_mimes)/sizeof(accept_mimes[0])-1; hres = IInternetBindInfo_GetBindString(bind_info, BINDSTRING_ACCEPT_MIMES, accept_mimes, num, &num); if(hres != S_OK) { WARN("GetBindString BINDSTRING_ACCEPT_MIMES failed: %08x\n", hres); return INET_E_NO_VALID_MEDIA; } accept_mimes[num] = 0; path = heap_alloc((url_comp.dwUrlPathLength+url_comp.dwExtraInfoLength+1)*sizeof(WCHAR)); if(url_comp.dwUrlPathLength) memcpy(path, url_comp.lpszUrlPath, url_comp.dwUrlPathLength*sizeof(WCHAR)); if(url_comp.dwExtraInfoLength) memcpy(path+url_comp.dwUrlPathLength, url_comp.lpszExtraInfo, url_comp.dwExtraInfoLength*sizeof(WCHAR)); path[url_comp.dwUrlPathLength+url_comp.dwExtraInfoLength] = 0; if(This->https) request_flags |= INTERNET_FLAG_SECURE; This->base.request = HttpOpenRequestW(This->base.connection, This->base.bind_info.dwBindVerb < BINDVERB_CUSTOM ? wszBindVerb[This->base.bind_info.dwBindVerb] : This->base.bind_info.szCustomVerb, path, NULL, NULL, (LPCWSTR *)accept_mimes, request_flags, (DWORD_PTR)&This->base); heap_free(path); while(num--) CoTaskMemFree(accept_mimes[num]); if (!This->base.request) { WARN("HttpOpenRequest failed: %d\n", GetLastError()); return INET_E_RESOURCE_NOT_FOUND; } hres = IInternetProtocolSink_QueryInterface(This->base.protocol_sink, &IID_IServiceProvider, (void **)&service_provider); if (hres != S_OK) { WARN("IInternetProtocolSink_QueryInterface IID_IServiceProvider failed: %08x\n", hres); return hres; } hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate, &IID_IHttpNegotiate, (void **)&This->http_negotiate); if (hres != S_OK) { WARN("IServiceProvider_QueryService IID_IHttpNegotiate failed: %08x\n", hres); return hres; } hres = IHttpNegotiate_BeginningTransaction(This->http_negotiate, url, wszHeaders, 0, &addl_header); if(hres != S_OK) { WARN("IHttpNegotiate_BeginningTransaction failed: %08x\n", hres); IServiceProvider_Release(service_provider); return hres; } if(addl_header) { int len_addl_header = strlenW(addl_header); This->full_header = heap_alloc(len_addl_header*sizeof(WCHAR)+sizeof(wszHeaders)); lstrcpyW(This->full_header, addl_header); lstrcpyW(&This->full_header[len_addl_header], wszHeaders); CoTaskMemFree(addl_header); }else { This->full_header = (LPWSTR)wszHeaders; } hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2, &IID_IHttpNegotiate2, (void **)&http_negotiate2); IServiceProvider_Release(service_provider); if(hres != S_OK) { WARN("IServiceProvider_QueryService IID_IHttpNegotiate2 failed: %08x\n", hres); /* No goto done as per native */ }else { len = sizeof(security_id)/sizeof(security_id[0]); hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, security_id, &len, 0); IHttpNegotiate2_Release(http_negotiate2); if (hres != S_OK) WARN("IHttpNegotiate2_GetRootSecurityId failed: %08x\n", hres); } /* FIXME: Handle security_id. Native calls undocumented function IsHostInProxyBypassList. */ if(This->base.bind_info.dwBindVerb == BINDVERB_POST) { num = 0; hres = IInternetBindInfo_GetBindString(bind_info, BINDSTRING_POST_COOKIE, &post_cookie, 1, &num); if(hres == S_OK && num) { if(!InternetSetOptionW(This->base.request, INTERNET_OPTION_SECONDARY_CACHE_KEY, post_cookie, lstrlenW(post_cookie))) WARN("InternetSetOption INTERNET_OPTION_SECONDARY_CACHE_KEY failed: %d\n", GetLastError()); CoTaskMemFree(post_cookie); } } if(This->base.bind_info.dwBindVerb != BINDVERB_GET) { /* Native does not use GlobalLock/GlobalUnlock, so we won't either */ if (This->base.bind_info.stgmedData.tymed != TYMED_HGLOBAL) WARN("Expected This->base.bind_info.stgmedData.tymed to be TYMED_HGLOBAL, not %d\n", This->base.bind_info.stgmedData.tymed); else optional = (LPWSTR)This->base.bind_info.stgmedData.u.hGlobal; } b = TRUE; res = InternetSetOptionW(This->base.request, INTERNET_OPTION_HTTP_DECODING, &b, sizeof(b)); if(!res) WARN("InternetSetOption(INTERNET_OPTION_HTTP_DECODING) failed: %08x\n", GetLastError()); res = HttpSendRequestW(This->base.request, This->full_header, lstrlenW(This->full_header), optional, optional ? This->base.bind_info.cbstgmedData : 0); if(!res && GetLastError() != ERROR_IO_PENDING) { WARN("HttpSendRequest failed: %d\n", GetLastError()); return INET_E_DOWNLOAD_FAILURE; } return S_OK; }
static void test_crack_url(const crack_url_test_t *test) { WCHAR buf[INTERNET_MAX_URL_LENGTH]; URL_COMPONENTSW urlw; URL_COMPONENTSA url; char scheme[32], hostname[1024], username[1024]; char password[1024], extrainfo[1024], urlpath[1024]; BOOL b; /* test InternetCrackUrlA with NULL buffers */ zero_compsA(&url, 1, 1, 1, 1, 1, 1); b = InternetCrackUrlA(test->url, strlen(test->url), 0, &url); ok(b, "InternetCrackUrl failed with error %d\n", GetLastError()); if(test->scheme_off == -1) ok(!url.lpszScheme, "[%s] url.lpszScheme = %p, expected NULL\n", test->url, url.lpszScheme); else ok(url.lpszScheme == test->url+test->scheme_off, "[%s] url.lpszScheme = %p, expected %p\n", test->url, url.lpszScheme, test->url+test->scheme_off); ok(url.dwSchemeLength == test->scheme_len, "[%s] url.lpszSchemeLength = %d, expected %d\n", test->url, url.dwSchemeLength, test->scheme_len); ok(url.nScheme == test->scheme, "[%s] url.nScheme = %d, expected %d\n", test->url, url.nScheme, test->scheme); if(test->host_off == -1) ok(!url.lpszHostName, "[%s] url.lpszHostName = %p, expected NULL\n", test->url, url.lpszHostName); else ok(url.lpszHostName == test->url+test->host_off, "[%s] url.lpszHostName = %p, expected %p\n", test->url, url.lpszHostName, test->url+test->host_off); if(test->host_skip_broken != -1 && url.dwHostNameLength == test->host_skip_broken) { win_skip("skipping broken dwHostNameLength result\n"); return; } ok(url.dwHostNameLength == test->host_len, "[%s] url.lpszHostNameLength = %d, expected %d\n", test->url, url.dwHostNameLength, test->host_len); ok(url.nPort == test->port, "[%s] nPort = %d, expected %d\n", test->url, url.nPort, test->port); if(test->user_off == -1) ok(!url.lpszUserName, "[%s] url.lpszUserName = %p\n", test->url, url.lpszUserName); else ok(url.lpszUserName == test->url+test->user_off, "[%s] url.lpszUserName = %p, expected %p\n", test->url, url.lpszUserName, test->url+test->user_off); ok(url.dwUserNameLength == test->user_len, "[%s] url.lpszUserNameLength = %d, expected %d\n", test->url, url.dwUserNameLength, test->user_len); if(test->pass_off == -1) ok(!url.lpszPassword, "[%s] url.lpszPassword = %p\n", test->url, url.lpszPassword); else ok(url.lpszPassword == test->url+test->pass_off, "[%s] url.lpszPassword = %p, expected %p\n", test->url, url.lpszPassword, test->url+test->pass_off); ok(url.dwPasswordLength == test->pass_len, "[%s] url.lpszPasswordLength = %d, expected %d\n", test->url, url.dwPasswordLength, test->pass_len); if(test->path_off == -1) ok(!url.lpszUrlPath, "[%s] url.lpszPath = %p, expected NULL\n", test->url, url.lpszUrlPath); else ok(url.lpszUrlPath == test->url+test->path_off, "[%s] url.lpszPath = %p, expected %p\n", test->url, url.lpszUrlPath, test->url+test->path_off); ok(url.dwUrlPathLength == test->path_len, "[%s] url.lpszUrlPathLength = %d, expected %d\n", test->url, url.dwUrlPathLength, test->path_len); if(test->extra_off == -1) ok(!url.lpszExtraInfo, "[%s] url.lpszExtraInfo = %p, expected NULL\n", test->url, url.lpszExtraInfo); else ok(url.lpszExtraInfo == test->url+test->extra_off, "[%s] url.lpszExtraInfo = %p, expected %p\n", test->url, url.lpszExtraInfo, test->url+test->extra_off); ok(url.dwExtraInfoLength == test->extra_len, "[%s] url.lpszExtraInfoLength = %d, expected %d\n", test->url, url.dwExtraInfoLength, test->extra_len); /* test InternetCrackUrlW with NULL buffers */ memset(&urlw, 0, sizeof(URL_COMPONENTSW)); urlw.dwStructSize = sizeof(URL_COMPONENTSW); urlw.dwSchemeLength = 1; urlw.dwHostNameLength = 1; urlw.dwUserNameLength = 1; urlw.dwPasswordLength = 1; urlw.dwUrlPathLength = 1; urlw.dwExtraInfoLength = 1; MultiByteToWideChar(CP_ACP, 0, test->url, -1, buf, sizeof(buf)/sizeof(buf[0])); b = InternetCrackUrlW(buf, lstrlenW(buf), 0, &urlw); if(!b && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { win_skip("InternetCrackUrlW is not implemented\n"); return; } ok(b, "InternetCrackUrl failed with error %d\n", GetLastError()); if(test->scheme_off == -1) ok(!urlw.lpszScheme, "[%s] urlw.lpszScheme = %p, expected NULL\n", test->url, urlw.lpszScheme); else ok(urlw.lpszScheme == buf+test->scheme_off, "[%s] urlw.lpszScheme = %p, expected %p\n", test->url, urlw.lpszScheme, buf+test->scheme_off); ok(urlw.dwSchemeLength == test->scheme_len, "[%s] urlw.lpszSchemeLength = %d, expected %d\n", test->url, urlw.dwSchemeLength, test->scheme_len); ok(urlw.nScheme == test->scheme, "[%s] urlw.nScheme = %d, expected %d\n", test->url, urlw.nScheme, test->scheme); if(test->host_off == -1) { ok(!urlw.lpszHostName, "[%s] urlw.lpszHostName = %p, expected NULL\n", test->url, urlw.lpszHostName); ok(urlw.dwHostNameLength == 0 || broken(urlw.dwHostNameLength == 1), "[%s] urlw.lpszHostNameLength = %d, expected %d\n", test->url, urlw.dwHostNameLength, test->host_len); }else { ok(urlw.lpszHostName == buf+test->host_off, "[%s] urlw.lpszHostName = %p, expected %p\n", test->url, urlw.lpszHostName, test->url+test->host_off); ok(urlw.dwHostNameLength == test->host_len, "[%s] urlw.lpszHostNameLength = %d, expected %d\n", test->url, urlw.dwHostNameLength, test->host_len); } ok(urlw.nPort == test->port, "[%s] nPort = %d, expected %d\n", test->url, urlw.nPort, test->port); if(test->user_off == -1) { ok(!urlw.lpszUserName, "[%s] urlw.lpszUserName = %p\n", test->url, urlw.lpszUserName); ok(urlw.dwUserNameLength == 0 || broken(urlw.dwUserNameLength == 1), "[%s] urlw.lpszUserNameLength = %d, expected %d\n", test->url, urlw.dwUserNameLength, test->user_len); }else { ok(urlw.lpszUserName == buf+test->user_off, "[%s] urlw.lpszUserName = %p, expected %p\n", test->url, urlw.lpszUserName, buf+test->user_off); ok(urlw.dwUserNameLength == test->user_len, "[%s] urlw.lpszUserNameLength = %d, expected %d\n", test->url, urlw.dwUserNameLength, test->user_len); } if(test->pass_off == -1) { ok(!urlw.lpszPassword, "[%s] urlw.lpszPassword = %p\n", test->url, urlw.lpszPassword); ok(urlw.dwPasswordLength == 0 || broken(urlw.dwPasswordLength), "[%s] urlw.lpszPasswordLength = %d, expected %d\n", test->url, urlw.dwPasswordLength, test->pass_len); }else { ok(urlw.lpszPassword == buf+test->pass_off, "[%s] urlw.lpszPassword = %p, expected %p\n", test->url, urlw.lpszPassword, buf+test->pass_off); ok(urlw.dwPasswordLength == test->pass_len, "[%s] urlw.lpszPasswordLength = %d, expected %d\n", test->url, urlw.dwPasswordLength, test->pass_len); } if(test->path_off == -1) ok(!urlw.lpszUrlPath, "[%s] urlw.lpszPath = %p, expected NULL\n", test->url, urlw.lpszUrlPath); else ok(urlw.lpszUrlPath == buf+test->path_off, "[%s] urlw.lpszPath = %p, expected %p\n", test->url, urlw.lpszUrlPath, buf+test->path_off); ok(urlw.dwUrlPathLength == test->path_len, "[%s] urlw.lpszUrlPathLength = %d, expected %d\n", test->url, urlw.dwUrlPathLength, test->path_len); if(test->extra_off == -1) { ok(!urlw.lpszExtraInfo, "[%s] url.lpszExtraInfo = %p, expected NULL\n", test->url, urlw.lpszExtraInfo); ok(urlw.dwExtraInfoLength == 0 || broken(urlw.dwExtraInfoLength == 1), "[%s] urlw.lpszExtraInfoLength = %d, expected %d\n", test->url, urlw.dwExtraInfoLength, test->extra_len); }else { ok(urlw.lpszExtraInfo == buf+test->extra_off, "[%s] urlw.lpszExtraInfo = %p, expected %p\n", test->url, urlw.lpszExtraInfo, buf+test->extra_off); ok(urlw.dwExtraInfoLength == test->extra_len, "[%s] urlw.lpszExtraInfoLength = %d, expected %d\n", test->url, urlw.dwExtraInfoLength, test->extra_len); } /* test InternetCrackUrlA with valid buffers */ memset(&url, 0, sizeof(URL_COMPONENTSA)); url.dwStructSize = sizeof(URL_COMPONENTSA); url.lpszScheme = scheme; url.dwSchemeLength = sizeof(scheme); url.lpszHostName = hostname; url.dwHostNameLength = sizeof(hostname); url.lpszUserName = username; url.dwUserNameLength = sizeof(username); url.lpszPassword = password; url.dwPasswordLength = sizeof(password); url.lpszUrlPath = urlpath; url.dwUrlPathLength = sizeof(urlpath); url.lpszExtraInfo = extrainfo; url.dwExtraInfoLength = sizeof(extrainfo); b = InternetCrackUrlA(test->url, strlen(test->url), 0, &url); ok(b, "InternetCrackUrlA failed with error %d\n", GetLastError()); ok(url.dwSchemeLength == strlen(test->exp_scheme), "[%s] Got wrong scheme length: %d\n", test->url, url.dwSchemeLength); ok(!strcmp(scheme, test->exp_scheme), "[%s] Got wrong scheme, expected: %s, got: %s\n", test->url, test->exp_scheme, scheme); ok(url.nScheme == test->scheme, "[%s] Got wrong nScheme, expected: %d, got: %d\n", test->url, test->scheme, url.nScheme); ok(url.dwHostNameLength == strlen(test->exp_hostname), "[%s] Got wrong hostname length: %d\n", test->url, url.dwHostNameLength); ok(!strcmp(hostname, test->exp_hostname), "[%s] Got wrong hostname, expected: %s, got: %s\n", test->url, test->exp_hostname, hostname); ok(url.nPort == test->port, "[%s] Got wrong port, expected: %d, got: %d\n", test->url, test->port, url.nPort); ok(url.dwUserNameLength == strlen(test->exp_username), "[%s] Got wrong username length: %d\n", test->url, url.dwUserNameLength); ok(!strcmp(username, test->exp_username), "[%s] Got wrong username, expected: %s, got: %s\n", test->url, test->exp_username, username); ok(url.dwPasswordLength == strlen(test->exp_password), "[%s] Got wrong password length: %d\n", test->url, url.dwPasswordLength); ok(!strcmp(password, test->exp_password), "[%s] Got wrong password, expected: %s, got: %s\n", test->url, test->exp_password, password); ok(url.dwUrlPathLength == strlen(test->exp_urlpath), "[%s] Got wrong urlpath length: %d\n", test->url, url.dwUrlPathLength); ok(!strcmp(urlpath, test->exp_urlpath), "[%s] Got wrong urlpath, expected: %s, got: %s\n", test->url, test->exp_urlpath, urlpath); ok(url.dwExtraInfoLength == strlen(test->exp_extrainfo), "[%s] Got wrong extrainfo length: %d\n", test->url, url.dwExtraInfoLength); ok(!strcmp(extrainfo, test->exp_extrainfo), "[%s] Got wrong extrainfo, expected: %s, got: %s\n", test->url, test->exp_extrainfo, extrainfo); /* test InternetCrackUrlW with valid buffers */ memset(&urlw, 0, sizeof(URL_COMPONENTSW)); urlw.dwStructSize = sizeof(URL_COMPONENTSW); urlw.lpszScheme = (WCHAR*)scheme; urlw.dwSchemeLength = sizeof(scheme) / sizeof(WCHAR); urlw.lpszHostName = (WCHAR*)hostname; urlw.dwHostNameLength = sizeof(hostname) / sizeof(WCHAR); urlw.lpszUserName = (WCHAR*)username; urlw.dwUserNameLength = sizeof(username) / sizeof(WCHAR); urlw.lpszPassword = (WCHAR*)password; urlw.dwPasswordLength = sizeof(password) / sizeof(WCHAR); urlw.lpszUrlPath = (WCHAR*)urlpath; urlw.dwUrlPathLength = sizeof(urlpath) / sizeof(WCHAR); urlw.lpszExtraInfo = (WCHAR*)extrainfo; urlw.dwExtraInfoLength = sizeof(extrainfo) / sizeof(WCHAR); b = InternetCrackUrlW(buf, lstrlenW(buf), 0, &urlw); ok(b, "InternetCrackUrlW failed with error %d\n", GetLastError()); ok(urlw.dwSchemeLength == strlen(test->exp_scheme), "[%s] Got wrong scheme length: %d\n", test->url, urlw.dwSchemeLength); ok(!lstrcmpW((WCHAR*)scheme, w_str_of(test->exp_scheme)), "[%s] Got wrong scheme, expected: %s, got: %s\n", test->url, test->exp_scheme, wine_dbgstr_w((WCHAR*)scheme)); ok(urlw.nScheme == test->scheme, "[%s] Got wrong nScheme, expected: %d, got: %d\n", test->url, test->scheme, urlw.nScheme); ok(urlw.dwHostNameLength == strlen(test->exp_hostname), "[%s] Got wrong hostname length: %d\n", test->url, urlw.dwHostNameLength); ok(!lstrcmpW((WCHAR*)hostname, w_str_of(test->exp_hostname)), "[%s] Got wrong hostname, expected: %s, got: %s\n", test->url, test->exp_hostname, wine_dbgstr_w((WCHAR*)hostname)); ok(urlw.nPort == test->port, "[%s] Got wrong port, expected: %d, got: %d\n", test->url, test->port, urlw.nPort); ok(urlw.dwUserNameLength == strlen(test->exp_username), "[%s] Got wrong username length: %d\n", test->url, urlw.dwUserNameLength); ok(!lstrcmpW((WCHAR*)username, w_str_of(test->exp_username)), "[%s] Got wrong username, expected: %s, got: %s\n", test->url, test->exp_username, wine_dbgstr_w((WCHAR*)username)); ok(urlw.dwPasswordLength == strlen(test->exp_password), "[%s] Got wrong password length: %d\n", test->url, urlw.dwPasswordLength); ok(!lstrcmpW((WCHAR*)password, w_str_of(test->exp_password)), "[%s] Got wrong password, expected: %s, got: %s\n", test->url, test->exp_password, wine_dbgstr_w((WCHAR*)password)); ok(urlw.dwUrlPathLength == strlen(test->exp_urlpath), "[%s] Got wrong urlpath length: %d\n", test->url, urlw.dwUrlPathLength); ok(!lstrcmpW((WCHAR*)urlpath, w_str_of(test->exp_urlpath)), "[%s] Got wrong urlpath, expected: %s, got: %s\n", test->url, test->exp_urlpath, wine_dbgstr_w((WCHAR*)urlpath)); ok(urlw.dwExtraInfoLength == strlen(test->exp_extrainfo), "[%s] Got wrong extrainfo length: %d\n", test->url, urlw.dwExtraInfoLength); ok(!lstrcmpW((WCHAR*)extrainfo, w_str_of(test->exp_extrainfo)), "[%s] Got wrong extrainfo, expected: %s, got: %s\n", test->url, test->exp_extrainfo, wine_dbgstr_w((WCHAR*)extrainfo)); }
/****************************************************************************** * URLMoniker_BindToStorage ******************************************************************************/ static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName, IBindCtx* pbc, VOID** ppvObject) { HRESULT hres; BINDINFO bi; DWORD bindf; WCHAR szFileName[MAX_PATH + 1]; Binding *bind; int len; WARN("(%s %p %p)\n", debugstr_w(URLName), pbc, ppvObject); bind = heap_alloc_zero(sizeof(Binding)); bind->lpVtbl = &BindingVtbl; bind->ref = 1; URLMON_LockModule(); len = lstrlenW(URLName)+1; bind->URLName = heap_alloc(len*sizeof(WCHAR)); memcpy(bind->URLName, URLName, len*sizeof(WCHAR)); hres = UMCreateStreamOnCacheFile(bind->URLName, 0, szFileName, &bind->hCacheFile, &bind->pstrCache); if(SUCCEEDED(hres)) { TRACE("Created stream...\n"); *ppvObject = (void *) bind->pstrCache; IStream_AddRef((IStream *) bind->pstrCache); hres = IBindCtx_GetObjectParam(pbc, BSCBHolder, (IUnknown**)&bind->pbscb); if(SUCCEEDED(hres)) { TRACE("Got IBindStatusCallback...\n"); memset(&bi, 0, sizeof(bi)); bi.cbSize = sizeof(bi); bindf = 0; hres = IBindStatusCallback_GetBindInfo(bind->pbscb, &bindf, &bi); if(SUCCEEDED(hres)) { URL_COMPONENTSW url; WCHAR *host, *path, *user, *pass; DWORD dwService = 0; BOOL bSuccess; TRACE("got bindinfo. bindf = %08x extrainfo = %s bindinfof = %08x bindverb = %08x iid %s\n", bindf, debugstr_w(bi.szExtraInfo), bi.grfBindInfoF, bi.dwBindVerb, debugstr_guid(&bi.iid)); hres = IBindStatusCallback_OnStartBinding(bind->pbscb, 0, (IBinding*)bind); TRACE("OnStartBinding rets %08x\n", hres); bind->expected_size = 0; bind->total_read = 0; memset(&url, 0, sizeof(url)); url.dwStructSize = sizeof(url); url.dwSchemeLength = url.dwHostNameLength = url.dwUrlPathLength = url.dwUserNameLength = url.dwPasswordLength = 1; InternetCrackUrlW(URLName, 0, ICU_ESCAPE, &url); host = heap_alloc((url.dwHostNameLength + 1) * sizeof(WCHAR)); memcpy(host, url.lpszHostName, url.dwHostNameLength * sizeof(WCHAR)); host[url.dwHostNameLength] = '\0'; path = heap_alloc((url.dwUrlPathLength + 1) * sizeof(WCHAR)); memcpy(path, url.lpszUrlPath, url.dwUrlPathLength * sizeof(WCHAR)); path[url.dwUrlPathLength] = '\0'; if (url.dwUserNameLength) { user = heap_alloc(((url.dwUserNameLength + 1) * sizeof(WCHAR))); memcpy(user, url.lpszUserName, url.dwUserNameLength * sizeof(WCHAR)); user[url.dwUserNameLength] = 0; } else { user = 0; } if (url.dwPasswordLength) { pass = heap_alloc(((url.dwPasswordLength + 1) * sizeof(WCHAR))); memcpy(pass, url.lpszPassword, url.dwPasswordLength * sizeof(WCHAR)); pass[url.dwPasswordLength] = 0; } else { pass = 0; } do { bind->hinternet = InternetOpenA("User Agent", 0, NULL, NULL, 0); if (!bind->hinternet) { hres = HRESULT_FROM_WIN32(GetLastError()); break; } switch ((DWORD) url.nScheme) { case INTERNET_SCHEME_FTP: if (!url.nPort) url.nPort = INTERNET_DEFAULT_FTP_PORT; dwService = INTERNET_SERVICE_FTP; break; case INTERNET_SCHEME_GOPHER: if (!url.nPort) url.nPort = INTERNET_DEFAULT_GOPHER_PORT; dwService = INTERNET_SERVICE_GOPHER; break; } bind->hconnect = InternetConnectW(bind->hinternet, host, url.nPort, user, pass, dwService, 0, (DWORD_PTR)bind); if (!bind->hconnect) { hres = HRESULT_FROM_WIN32(GetLastError()); CloseHandle(bind->hinternet); break; } hres = IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, 0x22, NULL); hres = IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, BINDSTATUS_FINDINGRESOURCE, NULL); hres = IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, BINDSTATUS_CONNECTING, NULL); hres = IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, BINDSTATUS_SENDINGREQUEST, NULL); bSuccess = FALSE; switch (dwService) { case INTERNET_SERVICE_GOPHER: bind->hrequest = GopherOpenFileW(bind->hconnect, path, 0, INTERNET_FLAG_RELOAD, 0); if (bind->hrequest) bSuccess = TRUE; else hres = HRESULT_FROM_WIN32(GetLastError()); break; case INTERNET_SERVICE_FTP: bind->hrequest = FtpOpenFileW(bind->hconnect, path, GENERIC_READ, FTP_TRANSFER_TYPE_BINARY | INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_RELOAD, 0); if (bind->hrequest) bSuccess = TRUE; else hres = HRESULT_FROM_WIN32(GetLastError()); break; } if(bSuccess) { TRACE("res = %d gle = %u url len = %d\n", hres, GetLastError(), bind->expected_size); IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, BINDSTATUS_CACHEFILENAMEAVAILABLE, szFileName); while(1) { char buf[4096]; DWORD bufread; if(InternetReadFile(bind->hrequest, buf, sizeof(buf), &bufread)) { TRACE("read %d bytes %s...\n", bufread, debugstr_an(buf, 10)); if(bufread == 0) break; hres = Binding_MoreCacheData(bind, buf, bufread); } else break; } InternetCloseHandle(bind->hrequest); hres = S_OK; } InternetCloseHandle(bind->hconnect); InternetCloseHandle(bind->hinternet); } while(0); Binding_FinishedDownload(bind, hres); Binding_CloseCacheDownload(bind); heap_free(user); heap_free(pass); heap_free(path); heap_free(host); } } } IBinding_Release((IBinding*)bind); return hres; }
static DWORD WINAPI ThreadFunc(LPVOID Context) { CComPtr<IBindStatusCallback> dl; WCHAR path[MAX_PATH]; PWSTR p, q; HWND Dlg = (HWND) Context; ULONG dwContentLen, dwBytesWritten, dwBytesRead, dwStatus; ULONG dwCurrentBytesRead = 0; ULONG dwStatusLen = sizeof(dwStatus); BOOL bCancelled = FALSE; BOOL bTempfile = FALSE; BOOL bCab = FALSE; HINTERNET hOpen = NULL; HINTERNET hFile = NULL; HANDLE hOut = INVALID_HANDLE_VALUE; unsigned char lpBuffer[4096]; PCWSTR lpszAgent = L"RApps/1.0"; URL_COMPONENTS urlComponents; size_t urlLength, filenameLength; /* build the path for the download */ p = wcsrchr(AppInfo->szUrlDownload, L'/'); q = wcsrchr(AppInfo->szUrlDownload, L'?'); /* do we have a final slash separator? */ if (!p) goto end; /* prepare the tentative length of the filename, maybe we've to remove part of it later on */ filenameLength = wcslen(p) * sizeof(WCHAR); /* do we have query arguments in the target URL after the filename? account for them (e.g. https://example.org/myfile.exe?no_adware_plz) */ if (q && q > p && (q - p) > 0) filenameLength -= wcslen(q - 1) * sizeof(WCHAR); /* is this URL an update package for RAPPS? if so store it in a different place */ if (wcscmp(AppInfo->szUrlDownload, APPLICATION_DATABASE_URL) == 0) { bCab = TRUE; if (!GetStorageDirectory(path, _countof(path))) goto end; } else { if (FAILED(StringCbCopyW(path, sizeof(path), SettingsInfo.szDownloadDir))) goto end; } /* is the path valid? can we access it? */ if (GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES) { if (!CreateDirectoryW(path, NULL)) goto end; } /* append a \ to the provided file system path, and the filename portion from the URL after that */ if (FAILED(StringCbCatW(path, sizeof(path), L"\\"))) goto end; if (FAILED(StringCbCatNW(path, sizeof(path), p + 1, filenameLength))) goto end; if (!bCab && AppInfo->szSHA1[0] != 0 && GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES) { /* only open it in case of total correctness */ if (VerifyInteg(AppInfo->szSHA1, path)) goto run; } /* download it */ bTempfile = TRUE; CDownloadDialog_Constructor(Dlg, &bCancelled, IID_PPV_ARG(IBindStatusCallback, &dl)); if (dl == NULL) goto end; /* FIXME: this should just be using the system-wide proxy settings */ switch(SettingsInfo.Proxy) { case 0: /* preconfig */ hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); break; case 1: /* direct (no proxy) */ hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); break; case 2: /* use proxy */ hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_PROXY, SettingsInfo.szProxyServer, SettingsInfo.szNoProxyFor, 0); break; default: /* preconfig */ hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); break; } if (!hOpen) goto end; hFile = InternetOpenUrlW(hOpen, AppInfo->szUrlDownload, NULL, 0, INTERNET_FLAG_PRAGMA_NOCACHE|INTERNET_FLAG_KEEP_CONNECTION, 0); if (!hFile) goto end; if (!HttpQueryInfoW(hFile, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwStatus, &dwStatusLen, NULL)) goto end; if(dwStatus != HTTP_STATUS_OK) { WCHAR szMsgText[MAX_STR_LEN]; if (!LoadStringW(hInst, IDS_UNABLE_TO_DOWNLOAD, szMsgText, sizeof(szMsgText) / sizeof(WCHAR))) goto end; MessageBoxW(hMainWnd, szMsgText, NULL, MB_OK | MB_ICONERROR); goto end; } dwStatusLen = sizeof(dwStatus); memset(&urlComponents, 0, sizeof(urlComponents)); urlComponents.dwStructSize = sizeof(urlComponents); if(FAILED(StringCbLengthW(AppInfo->szUrlDownload, sizeof(AppInfo->szUrlDownload), &urlLength))) goto end; urlLength /= sizeof(WCHAR); urlComponents.dwSchemeLength = urlLength + 1; urlComponents.lpszScheme = (LPWSTR)malloc(urlComponents.dwSchemeLength * sizeof(WCHAR)); urlComponents.dwHostNameLength = urlLength + 1; urlComponents.lpszHostName = (LPWSTR)malloc(urlComponents.dwHostNameLength * sizeof(WCHAR)); if(!InternetCrackUrlW(AppInfo->szUrlDownload, urlLength+1, ICU_DECODE | ICU_ESCAPE, &urlComponents)) goto end; if(urlComponents.nScheme == INTERNET_SCHEME_HTTP || urlComponents.nScheme == INTERNET_SCHEME_HTTPS) HttpQueryInfo(hFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &dwContentLen, &dwStatus, 0); if(urlComponents.nScheme == INTERNET_SCHEME_FTP) dwContentLen = FtpGetFileSize(hFile, &dwStatus); #ifdef USE_CERT_PINNING /* are we using HTTPS to download the RAPPS update package? check if the certificate is original */ if ((urlComponents.nScheme == INTERNET_SCHEME_HTTPS) && (wcscmp(AppInfo->szUrlDownload, APPLICATION_DATABASE_URL) == 0) && (!CertIsValid(hOpen, urlComponents.lpszHostName))) { WCHAR szMsgText[MAX_STR_LEN]; if (!LoadStringW(hInst, IDS_CERT_DOES_NOT_MATCH, szMsgText, sizeof(szMsgText) / sizeof(WCHAR))) goto end; MessageBoxW(Dlg, szMsgText, NULL, MB_OK | MB_ICONERROR); goto end; } #endif free(urlComponents.lpszScheme); free(urlComponents.lpszHostName); hOut = CreateFileW(path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL); if (hOut == INVALID_HANDLE_VALUE) goto end; do { if (!InternetReadFile(hFile, lpBuffer, _countof(lpBuffer), &dwBytesRead)) { WCHAR szMsgText[MAX_STR_LEN]; if (!LoadStringW(hInst, IDS_INTERRUPTED_DOWNLOAD, szMsgText, _countof(szMsgText))) goto end; MessageBoxW(hMainWnd, szMsgText, NULL, MB_OK | MB_ICONERROR); goto end; } if (!WriteFile(hOut, &lpBuffer[0], dwBytesRead, &dwBytesWritten, NULL)) { WCHAR szMsgText[MAX_STR_LEN]; if (!LoadStringW(hInst, IDS_UNABLE_TO_WRITE, szMsgText, _countof(szMsgText))) goto end; MessageBoxW(hMainWnd, szMsgText, NULL, MB_OK | MB_ICONERROR); goto end; } dwCurrentBytesRead += dwBytesRead; dl->OnProgress(dwCurrentBytesRead, dwContentLen, 0, AppInfo->szUrlDownload); } while (dwBytesRead && !bCancelled); CloseHandle(hOut); hOut = INVALID_HANDLE_VALUE; if (bCancelled) goto end; /* if this thing isn't a RAPPS update and it has a SHA-1 checksum verify its integrity by using the native advapi32.A_SHA1 functions */ if (!bCab && AppInfo->szSHA1[0] != 0) { WCHAR szMsgText[MAX_STR_LEN]; /* change a few strings in the download dialog to reflect the verification process */ LoadStringW(hInst, IDS_INTEG_CHECK_TITLE, szMsgText, _countof(szMsgText)); SetWindowText(Dlg, szMsgText); SendMessageW(GetDlgItem(Dlg, IDC_DOWNLOAD_STATUS), WM_SETTEXT, 0, (LPARAM)path); /* this may take a while, depending on the file size */ if (!VerifyInteg(AppInfo->szSHA1, path)) { if (!LoadStringW(hInst, IDS_INTEG_CHECK_FAIL, szMsgText, _countof(szMsgText))) goto end; MessageBoxW(Dlg, szMsgText, NULL, MB_OK | MB_ICONERROR); goto end; } } ShowWindow(Dlg, SW_HIDE); run: /* run it */ if (!bCab) ShellExecuteW( NULL, L"open", path, NULL, NULL, SW_SHOWNORMAL ); end: if (hOut != INVALID_HANDLE_VALUE) CloseHandle(hOut); InternetCloseHandle(hFile); InternetCloseHandle(hOpen); if (bTempfile) { if (bCancelled || (SettingsInfo.bDelInstaller && !bCab)) DeleteFileW(path); } EndDialog(Dlg, 0); return 0; }
/*! * @brief Initialise the HTTP(S) connection. * @param remote Pointer to the remote instance with the HTTP(S) transport details wired in. * @param sock Reference to the original socket FD passed to metsrv (ignored); * @return Indication of success or failure. */ static BOOL server_init_wininet(Transport* transport) { URL_COMPONENTS bits; wchar_t tmpHostName[URL_SIZE]; wchar_t tmpUrlPath[URL_SIZE]; HttpTransportContext* ctx = (HttpTransportContext*)transport->ctx; dprintf("[WININET] Initialising ..."); // configure proxy if (ctx->proxy) { dprintf("[DISPATCH] Configuring with proxy: %S", ctx->proxy); ctx->internet = InternetOpenW(ctx->ua, INTERNET_OPEN_TYPE_PROXY, ctx->proxy, NULL, 0); } else { ctx->internet = InternetOpenW(ctx->ua, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); } if (!ctx->internet) { dprintf("[DISPATCH] Failed InternetOpenW: %d", GetLastError()); return FALSE; } dprintf("[DISPATCH] Configured hInternet: 0x%.8x", ctx->internet); // The InternetCrackUrl method was poorly designed... ZeroMemory(tmpHostName, sizeof(tmpHostName)); ZeroMemory(tmpUrlPath, sizeof(tmpUrlPath)); ZeroMemory(&bits, sizeof(bits)); bits.dwStructSize = sizeof(bits); bits.dwHostNameLength = URL_SIZE - 1; bits.lpszHostName = tmpHostName; bits.dwUrlPathLength = URL_SIZE - 1; bits.lpszUrlPath = tmpUrlPath; dprintf("[DISPATCH] About to crack URL: %S", transport->url); InternetCrackUrlW(transport->url, 0, 0, &bits); SAFE_FREE(ctx->uri); ctx->uri = _wcsdup(tmpUrlPath); transport->comms_last_packet = current_unix_timestamp(); dprintf("[DISPATCH] Configured URI: %S", ctx->uri); dprintf("[DISPATCH] Host: %S Port: %u", tmpHostName, bits.nPort); // Allocate the connection handle ctx->connection = InternetConnectW(ctx->internet, tmpHostName, bits.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); if (!ctx->connection) { dprintf("[DISPATCH] Failed InternetConnect: %d", GetLastError()); return FALSE; } if (ctx->proxy) { if (ctx->proxy_user) { InternetSetOptionW(ctx->connection, INTERNET_OPTION_PROXY_USERNAME, ctx->proxy_user, (DWORD)wcslen(ctx->proxy_user)); } if (ctx->proxy_pass) { InternetSetOptionW(ctx->connection, INTERNET_OPTION_PROXY_PASSWORD, ctx->proxy_pass, (DWORD)wcslen(ctx->proxy_pass)); } } dprintf("[DISPATCH] Configured hConnection: 0x%.8x", ctx->connection); return TRUE; }