wininet: Moved creation of an object and allocating handles to common function.

Fixes a few leaks.
This commit is contained in:
Jacek Caban 2011-02-02 22:51:13 +01:00 committed by Alexandre Julliard
parent 572c4f7039
commit a073c66f0d
4 changed files with 80 additions and 142 deletions

View File

@ -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;
}

View File

@ -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:
HeapFree(GetProcessHeap(), 0, lpszHostName);
if( lpwhr )
WININET_Release( &lpwhr->hdr );
TRACE("<-- %u (%p)\n", res, lpwhr);
TRACE("<-- %p (%p)\n", handle, lpwhr);
*ret = handle;
return res;
HeapFree(GetProcessHeap(), 0, lpszHostName);
if(res != ERROR_SUCCESS) {
WININET_Release( &lpwhr->hdr );
*ret = NULL;
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;
}

View File

@ -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;
}

View File

@ -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 );