diff --git a/dlls/wininet/ftp.c b/dlls/wininet/ftp.c index 8a241b728e8..1cd383a5fc2 100644 --- a/dlls/wininet/ftp.c +++ b/dlls/wininet/ftp.c @@ -1486,7 +1486,8 @@ lend: HINTERNET FTP_Connect(HINTERNET hInternet, LPCWSTR lpszServerName, INTERNET_PORT nServerPort, LPCWSTR lpszUserName, - LPCWSTR lpszPassword, DWORD dwFlags, DWORD dwContext) + LPCWSTR lpszPassword, DWORD dwFlags, DWORD dwContext, + DWORD dwInternalFlags) { struct sockaddr_in socketAddr; struct hostent *phe = NULL; @@ -1567,6 +1568,7 @@ HINTERNET FTP_Connect(HINTERNET hInternet, LPCWSTR lpszServerName, lpwfs->hdr.htype = WH_HFTPSESSION; lpwfs->hdr.dwFlags = dwFlags; lpwfs->hdr.dwContext = dwContext; + lpwfs->hdr.dwInternalFlags = dwInternalFlags; lpwfs->hdr.lpwhparent = (LPWININETHANDLEHEADER)hInternet; lpwfs->sndSocket = nsocket; lpwfs->download_in_progress = NULL; @@ -1587,7 +1589,8 @@ HINTERNET FTP_Connect(HINTERNET hInternet, LPCWSTR lpszServerName, if (FTP_ConnectToHost(lpwfs)) { - if (hIC->lpfnStatusCB) + /* Don't send a handle created callback if this handle was created with InternetOpenUrl */ + if (hIC->lpfnStatusCB && !(lpwfs->hdr.dwInternalFlags & INET_OPENURL)) { INTERNET_ASYNC_RESULT iar; @@ -2499,6 +2502,7 @@ BOOL FTP_CloseFileTransferHandle(LPWININETFILE lpwh) { LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) lpwh->hdr.lpwhparent; INT nResCode; + HINTERNET handle; TRACE("\n"); @@ -2517,7 +2521,15 @@ BOOL FTP_CloseFileTransferHandle(LPWININETFILE lpwh) close(lpwh->nDataSocket); HeapFree(GetProcessHeap(), 0, lpwh); - + + /* If this handle was opened with InternetOpenUrl, we need to close the parent to prevent + a memory leek + */ + if(lpwfs->hdr.dwInternalFlags & INET_OPENURL) + { + handle = WININET_FindHandle( &lpwfs->hdr ); + InternetCloseHandle(handle); + } return TRUE; } diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index 0d31d64ec69..64f87abfaa5 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -1789,7 +1789,8 @@ lend: */ HINTERNET HTTP_Connect(HINTERNET hInternet, LPCWSTR lpszServerName, INTERNET_PORT nServerPort, LPCWSTR lpszUserName, - LPCWSTR lpszPassword, DWORD dwFlags, DWORD dwContext) + LPCWSTR lpszPassword, DWORD dwFlags, DWORD dwContext, + DWORD dwInternalFlags) { BOOL bSuccess = FALSE; LPWININETAPPINFOW hIC = NULL; @@ -1830,6 +1831,7 @@ HINTERNET HTTP_Connect(HINTERNET hInternet, LPCWSTR lpszServerName, lpwhs->hdr.lpwhparent = &hIC->hdr; lpwhs->hdr.dwFlags = dwFlags; lpwhs->hdr.dwContext = dwContext; + lpwhs->hdr.dwInternalFlags = dwInternalFlags; if(hIC->lpszProxy && hIC->dwAccessType == INTERNET_OPEN_TYPE_PROXY) { if(strchrW(hIC->lpszProxy, ' ')) FIXME("Several proxies not implemented.\n"); @@ -1842,7 +1844,8 @@ HINTERNET HTTP_Connect(HINTERNET hInternet, LPCWSTR lpszServerName, lpwhs->lpszUserName = WININET_strdupW(lpszUserName); lpwhs->nServerPort = nServerPort; - if (hIC->lpfnStatusCB) + /* Don't send a handle created callback if this handle was created with InternetOpenUrl */ + if (hIC->lpfnStatusCB && !(lpwhs->hdr.dwInternalFlags & INET_OPENURL)) { INTERNET_ASYNC_RESULT iar; @@ -2408,6 +2411,15 @@ void HTTP_CloseHTTPRequestHandle(LPWININETHTTPREQW lpwhr) HeapFree(GetProcessHeap(), 0, lpwhr->pCustHeaders); HeapFree(GetProcessHeap(), 0, lpwhr); + + /* If this handle was opened with InternetOpenUrl, we need to close the parent to prevent + a memory leek + */ + if(lpwhs->hdr.dwInternalFlags & INET_OPENURL) + { + handle = WININET_FindHandle( &lpwhs->hdr ); + InternetCloseHandle(handle); + } } @@ -2426,10 +2438,14 @@ void HTTP_CloseHTTPSessionHandle(LPWININETHTTPSESSIONW lpwhs) hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent; - handle = WININET_FindHandle( &lpwhs->hdr ); - SendAsyncCallback(hIC, handle, lpwhs->hdr.dwContext, - INTERNET_STATUS_HANDLE_CLOSING, lpwhs, - sizeof(HINTERNET)); + /* Don't send a handle closing callback if this handle was created with InternetOpenUrl */ + if(!(lpwhs->hdr.dwInternalFlags & INET_OPENURL)) + { + handle = WININET_FindHandle( &lpwhs->hdr ); + SendAsyncCallback(hIC, handle, lpwhs->hdr.dwContext, + INTERNET_STATUS_HANDLE_CLOSING, lpwhs, + sizeof(HINTERNET)); + } if (lpwhs->lpszServerName) HeapFree(GetProcessHeap(), 0, lpwhs->lpszServerName); diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index ce9c261acef..62c9dcf6697 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -665,12 +665,12 @@ HINTERNET WINAPI InternetConnectW(HINTERNET hInternet, { case INTERNET_SERVICE_FTP: rc = FTP_Connect(hInternet, lpszServerName, nServerPort, - lpszUserName, lpszPassword, dwFlags, dwContext); + lpszUserName, lpszPassword, dwFlags, dwContext, 0); break; case INTERNET_SERVICE_HTTP: rc = HTTP_Connect(hInternet, lpszServerName, nServerPort, - lpszUserName, lpszPassword, dwFlags, dwContext); + lpszUserName, lpszPassword, dwFlags, dwContext, 0); break; case INTERNET_SERVICE_GOPHER: @@ -2069,8 +2069,8 @@ HINTERNET WINAPI INTERNET_InternetOpenUrlW(HINTERNET hInternet, LPCWSTR lpszUrl, case INTERNET_SCHEME_FTP: if(urlComponents.nPort == 0) urlComponents.nPort = INTERNET_DEFAULT_FTP_PORT; - client = InternetConnectW(hInternet, hostName, urlComponents.nPort, - userName, password, INTERNET_SERVICE_FTP, dwFlags, dwContext); + client = FTP_Connect(hInternet, hostName, urlComponents.nPort, + userName, password, dwFlags, dwContext, INET_OPENURL); client1 = FtpOpenFileW(client, path, GENERIC_READ, dwFlags, dwContext); break; @@ -2084,8 +2084,8 @@ HINTERNET WINAPI INTERNET_InternetOpenUrlW(HINTERNET hInternet, LPCWSTR lpszUrl, else urlComponents.nPort = INTERNET_DEFAULT_HTTPS_PORT; } - client = InternetConnectW(hInternet, hostName, urlComponents.nPort, userName, - password, INTERNET_SERVICE_HTTP, dwFlags, dwContext); + client = HTTP_Connect(hInternet, hostName, urlComponents.nPort, + userName, password, dwFlags, dwContext, INET_OPENURL); if(client == NULL) break; client1 = HttpOpenRequestW(client, NULL, path, NULL, NULL, accept, dwFlags, dwContext); diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h index 3c8b8a29b0a..1b47d86dfdc 100644 --- a/dlls/wininet/internet.h +++ b/dlls/wininet/internet.h @@ -81,12 +81,15 @@ typedef enum WH_HHTTPREQ = INTERNET_HANDLE_TYPE_HTTP_REQUEST, } WH_TYPE; +#define INET_OPENURL 0x0001 + typedef struct _WININETHANDLEHEADER { WH_TYPE htype; DWORD dwFlags; DWORD dwContext; DWORD dwError; + DWORD dwInternalFlags; struct _WININETHANDLEHEADER *lpwhparent; } WININETHANDLEHEADER, *LPWININETHANDLEHEADER; @@ -346,11 +349,13 @@ time_t ConvertTimeString(LPCWSTR asctime); HINTERNET FTP_Connect(HINTERNET hInterent, LPCWSTR lpszServerName, INTERNET_PORT nServerPort, LPCWSTR lpszUserName, - LPCWSTR lpszPassword, DWORD dwFlags, DWORD dwContext); + LPCWSTR lpszPassword, DWORD dwFlags, DWORD dwContext, + DWORD dwInternalFlags); HINTERNET HTTP_Connect(HINTERNET hInterent, LPCWSTR lpszServerName, INTERNET_PORT nServerPort, LPCWSTR lpszUserName, - LPCWSTR lpszPassword, DWORD dwFlags, DWORD dwContext); + LPCWSTR lpszPassword, DWORD dwFlags, DWORD dwContext, + DWORD dwInternalFlags); BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort, struct hostent **phe, struct sockaddr_in *psa);