Prevent memory leak and superfluous status notifications.
diff --git a/dlls/wininet/ftp.c b/dlls/wininet/ftp.c index 8a241b7..1cd383a 100644 --- a/dlls/wininet/ftp.c +++ b/dlls/wininet/ftp.c
@@ -1486,7 +1486,8 @@ 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 @@ 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 @@ 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 @@ { LPWININETFTPSESSIONA lpwfs = (LPWININETFTPSESSIONA) lpwh->hdr.lpwhparent; INT nResCode; + HINTERNET handle; TRACE("\n"); @@ -2517,7 +2521,15 @@ 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 0d31d64..64f87ab 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c
@@ -1789,7 +1789,8 @@ */ 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 @@ 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 @@ 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 @@ 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 @@ 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 ce9c261..62c9dcf 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c
@@ -665,12 +665,12 @@ { 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 @@ 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 @@ 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 3c8b8a2..1b47d86 100644 --- a/dlls/wininet/internet.h +++ b/dlls/wininet/internet.h
@@ -81,12 +81,15 @@ 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 @@ 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);