From a073c66f0d36ed52d03dafce41aef7ea1694bc0b Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Wed, 2 Feb 2011 22:51:13 +0100 Subject: [PATCH] wininet: Moved creation of an object and allocating handles to common function. Fixes a few leaks. --- dlls/wininet/ftp.c | 76 +++++++++++++------------------------------------ dlls/wininet/http.c | 71 ++++++++++++++------------------------------- dlls/wininet/internet.c | 69 ++++++++++++++++++++++---------------------- dlls/wininet/internet.h | 2 +- 4 files changed, 78 insertions(+), 140 deletions(-) diff --git a/dlls/wininet/ftp.c b/dlls/wininet/ftp.c index bc382123878..41537b8a9d3 100644 --- a/dlls/wininet/ftp.c +++ b/dlls/wininet/ftp.c @@ -1326,8 +1326,6 @@ static HINTERNET FTP_FtpOpenFileW(ftp_session_t *lpwfs, BOOL bSuccess = FALSE; ftp_file_t *lpwh = NULL; appinfo_t *hIC = NULL; - HINTERNET handle = NULL; - DWORD res = ERROR_SUCCESS; TRACE("\n"); @@ -1348,14 +1346,10 @@ static HINTERNET FTP_FtpOpenFileW(ftp_session_t *lpwfs, /* Get data socket to server */ if (bSuccess && FTP_GetDataSocket(lpwfs, &nDataSocket)) { - lpwh = HeapAlloc(GetProcessHeap(), 0, sizeof(ftp_file_t)); + lpwh = alloc_object(&lpwfs->hdr, &FTPFILEVtbl, sizeof(ftp_file_t)); lpwh->hdr.htype = WH_HFILE; - lpwh->hdr.vtbl = &FTPFILEVtbl; lpwh->hdr.dwFlags = dwFlags; lpwh->hdr.dwContext = dwContext; - lpwh->hdr.dwInternalFlags = 0; - lpwh->hdr.refs = 1; - lpwh->hdr.lpfnStatusCB = lpwfs->hdr.lpfnStatusCB; lpwh->nDataSocket = nDataSocket; lpwh->cache_file = NULL; lpwh->cache_file_handle = INVALID_HANDLE_VALUE; @@ -1365,10 +1359,6 @@ static HINTERNET FTP_FtpOpenFileW(ftp_session_t *lpwfs, lpwh->lpFtpSession = lpwfs; list_add_head( &lpwfs->hdr.children, &lpwh->hdr.entry ); - res = alloc_handle(&lpwh->hdr, &handle); - if (res != ERROR_SUCCESS) - goto lend; - /* Indicate that a download is currently in progress */ lpwfs->download_in_progress = lpwh; } @@ -1421,7 +1411,7 @@ static HINTERNET FTP_FtpOpenFileW(ftp_session_t *lpwfs, if (lpwh) { - iar.dwResult = (DWORD_PTR)handle; + iar.dwResult = (DWORD_PTR)lpwh->hdr.hInternet; iar.dwError = ERROR_SUCCESS; SendAsyncCallback(&lpwfs->hdr, lpwfs->hdr.dwContext, INTERNET_STATUS_HANDLE_CREATED, &iar, sizeof(INTERNET_ASYNC_RESULT)); @@ -1437,13 +1427,13 @@ static HINTERNET FTP_FtpOpenFileW(ftp_session_t *lpwfs, } } -lend: - if( lpwh ) - WININET_Release( &lpwh->hdr ); + if(!bSuccess) { + if(lpwh) + WININET_Release( &lpwh->hdr ); + return FALSE; + } - if(res != ERROR_SUCCESS) - INTERNET_SetLastError(res); - return handle; + return lpwh->hdr.hInternet; } @@ -2452,9 +2442,7 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, UINT sock_namelen; BOOL bSuccess = FALSE; ftp_session_t *lpwfs = NULL; - HINTERNET handle = NULL; char szaddr[INET_ADDRSTRLEN]; - DWORD res; TRACE("%p Server(%s) Port(%d) User(%s) Paswd(%s)\n", hIC, debugstr_w(lpszServerName), @@ -2465,14 +2453,14 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, if ((!lpszUserName || !*lpszUserName) && lpszPassword && *lpszPassword) { INTERNET_SetLastError(ERROR_INVALID_PARAMETER); - goto lerror; + return NULL; } - lpwfs = HeapAlloc(GetProcessHeap(), 0, sizeof(ftp_session_t)); + lpwfs = alloc_object(&hIC->hdr, &FTPSESSIONVtbl, sizeof(ftp_session_t)); if (NULL == lpwfs) { INTERNET_SetLastError(ERROR_OUTOFMEMORY); - goto lerror; + return NULL; } if (nServerPort == INTERNET_INVALID_PORT_NUMBER) @@ -2481,12 +2469,9 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, lpwfs->serverport = nServerPort; lpwfs->hdr.htype = WH_HFTPSESSION; - lpwfs->hdr.vtbl = &FTPSESSIONVtbl; lpwfs->hdr.dwFlags = dwFlags; lpwfs->hdr.dwContext = dwContext; - lpwfs->hdr.dwInternalFlags = dwInternalFlags; - lpwfs->hdr.refs = 1; - lpwfs->hdr.lpfnStatusCB = hIC->hdr.lpfnStatusCB; + lpwfs->hdr.dwInternalFlags |= dwInternalFlags; lpwfs->download_in_progress = NULL; lpwfs->sndSocket = -1; lpwfs->lstnSocket = -1; @@ -2496,14 +2481,6 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, lpwfs->lpAppInfo = hIC; list_add_head( &hIC->hdr.children, &lpwfs->hdr.entry ); - res = alloc_handle(&lpwfs->hdr, &handle); - if(res != ERROR_SUCCESS) - { - ERR("Failed to alloc handle\n"); - INTERNET_SetLastError(res); - goto lerror; - } - if(hIC->lpszProxy && hIC->dwAccessType == INTERNET_OPEN_TYPE_PROXY) { if(strchrW(hIC->lpszProxy, ' ')) FIXME("Several proxies not implemented.\n"); @@ -2541,7 +2518,7 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, { INTERNET_ASYNC_RESULT iar; - iar.dwResult = (DWORD_PTR)handle; + iar.dwResult = (DWORD_PTR)lpwfs->hdr.hInternet; iar.dwError = ERROR_SUCCESS; SendAsyncCallback(&hIC->hdr, dwContext, @@ -2604,15 +2581,14 @@ HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, } lerror: - if (lpwfs) WININET_Release( &lpwfs->hdr ); - - if (!bSuccess && handle) + if (!bSuccess) { - InternetCloseHandle(handle); - handle = NULL; + if(lpwfs) + WININET_Release( &lpwfs->hdr ); + return NULL; } - return handle; + return lpwfs->hdr.hInternet; } @@ -3534,8 +3510,6 @@ static HINTERNET FTP_ReceiveFileList(ftp_session_t *lpwfs, INT nSocket, LPCWSTR DWORD dwSize = 0; LPFILEPROPERTIESW lpafp = NULL; LPWININETFTPFINDNEXTW lpwfn = NULL; - HINTERNET handle = 0; - DWORD res; TRACE("(%p,%d,%s,%p,%08lx)\n", lpwfs, nSocket, debugstr_w(lpszSearchFile), lpFindFileData, dwContext); @@ -3544,14 +3518,11 @@ static HINTERNET FTP_ReceiveFileList(ftp_session_t *lpwfs, INT nSocket, LPCWSTR if(lpFindFileData) FTP_ConvertFileProp(lpafp, lpFindFileData); - lpwfn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WININETFTPFINDNEXTW)); + lpwfn = alloc_object(&lpwfs->hdr, &FTPFINDNEXTVtbl, sizeof(WININETFTPFINDNEXTW)); if (lpwfn) { lpwfn->hdr.htype = WH_HFTPFINDNEXT; - lpwfn->hdr.vtbl = &FTPFINDNEXTVtbl; lpwfn->hdr.dwContext = dwContext; - lpwfn->hdr.refs = 1; - lpwfn->hdr.lpfnStatusCB = lpwfs->hdr.lpfnStatusCB; lpwfn->index = 1; /* Next index is 1 since we return index 0 */ lpwfn->size = dwSize; lpwfn->lpafp = lpafp; @@ -3559,18 +3530,11 @@ static HINTERNET FTP_ReceiveFileList(ftp_session_t *lpwfs, INT nSocket, LPCWSTR WININET_AddRef( &lpwfs->hdr ); lpwfn->lpFtpSession = lpwfs; list_add_head( &lpwfs->hdr.children, &lpwfn->hdr.entry ); - - res = alloc_handle(&lpwfn->hdr, &handle); - if(res != ERROR_SUCCESS) - SetLastError(res); } } - if( lpwfn ) - WININET_Release( &lpwfn->hdr ); - TRACE("Matched %d files\n", dwSize); - return handle; + return lpwfn ? lpwfn->hdr.hInternet : NULL; } diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index d656debfc76..9215c348b4b 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -2567,7 +2567,6 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *lpwhs, appinfo_t *hIC = NULL; http_request_t *lpwhr; LPWSTR lpszHostName = NULL; - HINTERNET handle = NULL; static const WCHAR szHostForm[] = {'%','s',':','%','u',0}; DWORD len, res; @@ -2576,20 +2575,15 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *lpwhs, assert( lpwhs->hdr.htype == WH_HHTTPSESSION ); hIC = lpwhs->lpAppInfo; - lpwhr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(http_request_t)); - if (NULL == lpwhr) - { - res = ERROR_OUTOFMEMORY; - goto lend; - } + lpwhr = alloc_object(&lpwhs->hdr, &HTTPREQVtbl, sizeof(http_request_t)); + if(!lpwhr) + return ERROR_OUTOFMEMORY; + lpwhr->hdr.htype = WH_HHTTPREQ; - lpwhr->hdr.vtbl = &HTTPREQVtbl; lpwhr->hdr.dwFlags = dwFlags; lpwhr->hdr.dwContext = dwContext; - lpwhr->hdr.refs = 1; - lpwhr->hdr.lpfnStatusCB = lpwhs->hdr.lpfnStatusCB; - lpwhr->hdr.dwInternalFlags = lpwhs->hdr.dwInternalFlags & INET_CALLBACKW; lpwhr->dwContentLength = ~0u; + InitializeCriticalSection( &lpwhr->read_section ); WININET_AddRef( &lpwhs->hdr ); @@ -2604,16 +2598,8 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *lpwhs, goto lend; } - res = alloc_handle(&lpwhr->hdr, &handle); - if (res != ERROR_SUCCESS) - goto lend; - if ((res = NETCON_init(&lpwhr->netConnection, dwFlags & INTERNET_FLAG_SECURE)) != ERROR_SUCCESS) - { - InternetCloseHandle( handle ); - handle = NULL; goto lend; - } if (lpszObjectName && *lpszObjectName) { HRESULT rc; @@ -2681,17 +2667,21 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *lpwhs, HTTP_DealWithProxy( hIC, lpwhs, lpwhr ); INTERNET_SendCallback(&lpwhs->hdr, dwContext, - INTERNET_STATUS_HANDLE_CREATED, &handle, - sizeof(handle)); + INTERNET_STATUS_HANDLE_CREATED, &lpwhr->hdr.hInternet, + sizeof(HINTERNET)); lend: + TRACE("<-- %u (%p)\n", res, lpwhr); + HeapFree(GetProcessHeap(), 0, lpszHostName); - if( lpwhr ) + if(res != ERROR_SUCCESS) { WININET_Release( &lpwhr->hdr ); + *ret = NULL; + return res; + } - TRACE("<-- %p (%p)\n", handle, lpwhr); - *ret = handle; - return res; + *ret = lpwhr->hdr.hInternet; + return ERROR_SUCCESS; } /*********************************************************************** @@ -4440,8 +4430,6 @@ DWORD HTTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, DWORD dwInternalFlags, HINTERNET *ret) { http_session_t *lpwhs = NULL; - HINTERNET handle = NULL; - DWORD res; TRACE("-->\n"); @@ -4450,7 +4438,7 @@ DWORD HTTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, assert( hIC->hdr.htype == WH_HINIT ); - lpwhs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(http_session_t)); + lpwhs = alloc_object(&hIC->hdr, &HTTPSESSIONVtbl, sizeof(http_session_t)); if (!lpwhs) return ERROR_OUTOFMEMORY; @@ -4459,24 +4447,14 @@ DWORD HTTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, */ lpwhs->hdr.htype = WH_HHTTPSESSION; - lpwhs->hdr.vtbl = &HTTPSESSIONVtbl; lpwhs->hdr.dwFlags = dwFlags; lpwhs->hdr.dwContext = dwContext; - lpwhs->hdr.dwInternalFlags = dwInternalFlags | (hIC->hdr.dwInternalFlags & INET_CALLBACKW); - lpwhs->hdr.refs = 1; - lpwhs->hdr.lpfnStatusCB = hIC->hdr.lpfnStatusCB; + lpwhs->hdr.dwInternalFlags |= dwInternalFlags; WININET_AddRef( &hIC->hdr ); lpwhs->lpAppInfo = hIC; list_add_head( &hIC->hdr.children, &lpwhs->hdr.entry ); - res = alloc_handle(&lpwhs->hdr, &handle); - if (res != ERROR_SUCCESS) - { - ERR("Failed to alloc handle\n"); - goto lerror; - } - if(hIC->lpszProxy && hIC->dwAccessType == INTERNET_OPEN_TYPE_PROXY) { if(hIC->lpszProxyBypass) FIXME("Proxy bypass is ignored.\n"); @@ -4494,24 +4472,19 @@ DWORD HTTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, if (!(lpwhs->hdr.dwInternalFlags & INET_OPENURL)) { INTERNET_SendCallback(&hIC->hdr, dwContext, - INTERNET_STATUS_HANDLE_CREATED, &handle, - sizeof(handle)); + INTERNET_STATUS_HANDLE_CREATED, &lpwhs->hdr.hInternet, + sizeof(HINTERNET)); } -lerror: - if( lpwhs ) - WININET_Release( &lpwhs->hdr ); - /* * an INTERNET_STATUS_REQUEST_COMPLETE is NOT sent here as per my tests on * windows */ - TRACE("%p --> %p (%p)\n", hIC, handle, lpwhs); + TRACE("%p --> %p\n", hIC, lpwhs); - if(res == ERROR_SUCCESS) - *ret = handle; - return res; + *ret = lpwhs->hdr.hInternet; + return ERROR_SUCCESS; } diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c index b5468675b10..0df56a600ea 100644 --- a/dlls/wininet/internet.c +++ b/dlls/wininet/internet.c @@ -117,13 +117,18 @@ static const WCHAR szInternetSettings[] = static const WCHAR szProxyServer[] = { 'P','r','o','x','y','S','e','r','v','e','r', 0 }; static const WCHAR szProxyEnable[] = { 'P','r','o','x','y','E','n','a','b','l','e', 0 }; -DWORD alloc_handle( object_header_t *info, HINTERNET *ret ) +void *alloc_object(object_header_t *parent, const object_vtbl_t *vtbl, size_t size) { - object_header_t **p; UINT_PTR handle = 0, num; - DWORD res = ERROR_SUCCESS; + object_header_t *ret; + object_header_t **p; + BOOL res = TRUE; - list_init( &info->children ); + ret = heap_alloc_zero(size); + if(!ret) + return NULL; + + list_init(&ret->children); EnterCriticalSection( &WININET_cs ); @@ -135,7 +140,7 @@ DWORD alloc_handle( object_header_t *info, HINTERNET *ret ) handle_table_size = num; next_handle = 1; }else { - res = ERROR_OUTOFMEMORY; + res = FALSE; } }else if(next_handle == handle_table_size) { num = handle_table_size * 2; @@ -144,25 +149,38 @@ DWORD alloc_handle( object_header_t *info, HINTERNET *ret ) handle_table = p; handle_table_size = num; }else { - res = ERROR_OUTOFMEMORY; + res = FALSE; } } - if(res == ERROR_SUCCESS) { + if(res) { handle = next_handle; if(handle_table[handle]) ERR("handle isn't free but should be\n"); - handle_table[handle] = WININET_AddRef( info ); + handle_table[handle] = ret; + ret->valid_handle = TRUE; while(handle_table[next_handle] && next_handle < handle_table_size) next_handle++; } - + LeaveCriticalSection( &WININET_cs ); - info->hInternet = *ret = (HINTERNET)handle; - info->valid_handle = res == ERROR_SUCCESS; - return res; + if(!res) { + heap_free(ret); + return NULL; + } + + ret->vtbl = vtbl; + ret->refs = 1; + ret->hInternet = (HINTERNET)handle; + + if(parent) { + ret->lpfnStatusCB = parent->lpfnStatusCB; + ret->dwInternalFlags = parent->dwInternalFlags & INET_CALLBACKW; + } + + return ret; } object_header_t *WININET_AddRef( object_header_t *info ) @@ -827,8 +845,6 @@ HINTERNET WINAPI InternetOpenW(LPCWSTR lpszAgent, DWORD dwAccessType, LPCWSTR lpszProxy, LPCWSTR lpszProxyBypass, DWORD dwFlags) { appinfo_t *lpwai = NULL; - HINTERNET handle = NULL; - DWORD res; if (TRACE_ON(wininet)) { #define FE(x) { x, #x } @@ -858,29 +874,18 @@ HINTERNET WINAPI InternetOpenW(LPCWSTR lpszAgent, DWORD dwAccessType, /* Clear any error information */ INTERNET_SetLastError(0); - lpwai = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(appinfo_t)); - if (NULL == lpwai) - { - INTERNET_SetLastError(ERROR_OUTOFMEMORY); - goto lend; + lpwai = alloc_object(NULL, &APPINFOVtbl, sizeof(appinfo_t)); + if (!lpwai) { + SetLastError(ERROR_OUTOFMEMORY); + return NULL; } lpwai->hdr.htype = WH_HINIT; - lpwai->hdr.vtbl = &APPINFOVtbl; lpwai->hdr.dwFlags = dwFlags; - lpwai->hdr.refs = 1; lpwai->dwAccessType = dwAccessType; lpwai->lpszProxyUsername = NULL; lpwai->lpszProxyPassword = NULL; - res = alloc_handle(&lpwai->hdr, &handle); - if(res != ERROR_SUCCESS) - { - HeapFree( GetProcessHeap(), 0, lpwai ); - INTERNET_SetLastError(res); - goto lend; - } - lpwai->lpszAgent = heap_strdupW(lpszAgent); if(dwAccessType == INTERNET_OPEN_TYPE_PRECONFIG) INTERNET_ConfigureProxy( lpwai ); @@ -888,13 +893,9 @@ HINTERNET WINAPI InternetOpenW(LPCWSTR lpszAgent, DWORD dwAccessType, lpwai->lpszProxy = heap_strdupW(lpszProxy); lpwai->lpszProxyBypass = heap_strdupW(lpszProxyBypass); -lend: - if( lpwai ) - WININET_Release( &lpwai->hdr ); - TRACE("returning %p\n", lpwai); - return handle; + return lpwai->hdr.hInternet; } diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h index d6cd1d2241e..d9fa71604f6 100644 --- a/dlls/wininet/internet.h +++ b/dlls/wininet/internet.h @@ -435,7 +435,7 @@ typedef struct WORKREQ } WORKREQUEST, *LPWORKREQUEST; -DWORD alloc_handle( object_header_t*, HINTERNET*); +void *alloc_object(object_header_t*,const object_vtbl_t*,size_t); object_header_t *get_handle_object( HINTERNET hinternet ); object_header_t *WININET_AddRef( object_header_t *info ); BOOL WININET_Release( object_header_t *info ); -- 2.11.4.GIT