Use pointers internally and refcount all objects.

This commit is contained in:
Mike McCormack 2004-07-19 21:49:39 +00:00 committed by Alexandre Julliard
parent 4104c622af
commit 3a1391b8dd
5 changed files with 542 additions and 517 deletions

File diff suppressed because it is too large Load Diff

View File

@ -40,6 +40,7 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <assert.h>
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
@ -81,6 +82,8 @@ static const WCHAR g_szUserAgent[] = {'U','s','e','r','-','A','g','e','n','t',0}
#define HTTP_ADDHDR_FLAG_REQ 0x02000000 #define HTTP_ADDHDR_FLAG_REQ 0x02000000
static void HTTP_CloseHTTPRequestHandle(LPWININETHANDLEHEADER hdr);
static void HTTP_CloseHTTPSessionHandle(LPWININETHANDLEHEADER hdr);
BOOL HTTP_OpenConnection(LPWININETHTTPREQW lpwhr); BOOL HTTP_OpenConnection(LPWININETHTTPREQW lpwhr);
int HTTP_WriteDataToStream(LPWININETHTTPREQW lpwhr, int HTTP_WriteDataToStream(LPWININETHTTPREQW lpwhr,
void *Buffer, int BytesToWrite); void *Buffer, int BytesToWrite);
@ -230,9 +233,12 @@ BOOL WINAPI HttpAddRequestHeadersW(HINTERNET hHttpRequest,
if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ) if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ)
{ {
INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
return bSuccess; goto lend;
} }
bSuccess = HTTP_HttpAddRequestHeadersW( lpwhr, lpszHeader, dwHeaderLength, dwModifier ); bSuccess = HTTP_HttpAddRequestHeadersW( lpwhr, lpszHeader, dwHeaderLength, dwModifier );
lend:
if( lpwhr )
WININET_Release( &lpwhr->hdr );
return bSuccess; return bSuccess;
} }
@ -338,7 +344,7 @@ HINTERNET WINAPI HttpOpenRequestW(HINTERNET hHttpSession,
if (NULL == lpwhs || lpwhs->hdr.htype != WH_HHTTPSESSION) if (NULL == lpwhs || lpwhs->hdr.htype != WH_HHTTPSESSION)
{ {
INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
return NULL; goto lend;
} }
hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent; hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent;
@ -348,40 +354,13 @@ HINTERNET WINAPI HttpOpenRequestW(HINTERNET hHttpSession,
* if this call was asynchronous then how would you get the * if this call was asynchronous then how would you get the
* necessary HINTERNET pointer returned by this function. * necessary HINTERNET pointer returned by this function.
* *
* I am leaving this here just in case I am wrong
*
* if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
*/ */
if (0) handle = HTTP_HttpOpenRequestW(lpwhs, lpszVerb, lpszObjectName,
{
WORKREQUEST workRequest;
struct WORKREQ_HTTPOPENREQUESTW *req;
workRequest.asyncall = HTTPOPENREQUESTW;
workRequest.handle = hHttpSession;
req = &workRequest.u.HttpOpenRequestW;
req->lpszVerb = WININET_strdupW(lpszVerb);
req->lpszObjectName = WININET_strdupW(lpszObjectName);
if (lpszVersion)
req->lpszVersion = WININET_strdupW(lpszVersion);
else
req->lpszVersion = 0;
if (lpszReferrer)
req->lpszReferrer = WININET_strdupW(lpszReferrer);
else
req->lpszReferrer = 0;
req->lpszAcceptTypes = lpszAcceptTypes;
req->dwFlags = dwFlags;
req->dwContext = dwContext;
INTERNET_AsyncCall(&workRequest);
}
else
{
handle = HTTP_HttpOpenRequestW(hHttpSession, lpszVerb, lpszObjectName,
lpszVersion, lpszReferrer, lpszAcceptTypes, lpszVersion, lpszReferrer, lpszAcceptTypes,
dwFlags, dwContext); dwFlags, dwContext);
} lend:
if( lpwhs )
WININET_Release( &lpwhs->hdr );
TRACE("returning %p\n", handle); TRACE("returning %p\n", handle);
return handle; return handle;
} }
@ -671,50 +650,45 @@ static BOOL HTTP_DealWithProxy( LPWININETAPPINFOW hIC,
* NULL on failure * NULL on failure
* *
*/ */
HINTERNET WINAPI HTTP_HttpOpenRequestW(HINTERNET hHttpSession, HINTERNET WINAPI HTTP_HttpOpenRequestW(LPWININETHTTPSESSIONW lpwhs,
LPCWSTR lpszVerb, LPCWSTR lpszObjectName, LPCWSTR lpszVersion, LPCWSTR lpszVerb, LPCWSTR lpszObjectName, LPCWSTR lpszVersion,
LPCWSTR lpszReferrer , LPCWSTR *lpszAcceptTypes, LPCWSTR lpszReferrer , LPCWSTR *lpszAcceptTypes,
DWORD dwFlags, DWORD dwContext) DWORD dwFlags, DWORD dwContext)
{ {
LPWININETHTTPSESSIONW lpwhs;
LPWININETAPPINFOW hIC = NULL; LPWININETAPPINFOW hIC = NULL;
LPWININETHTTPREQW lpwhr; LPWININETHTTPREQW lpwhr;
LPWSTR lpszCookies; LPWSTR lpszCookies;
LPWSTR lpszUrl = NULL; LPWSTR lpszUrl = NULL;
DWORD nCookieSize; DWORD nCookieSize;
HINTERNET handle; HINTERNET handle = NULL;
static const WCHAR szUrlForm[] = {'h','t','t','p',':','/','/','%','s',0}; static const WCHAR szUrlForm[] = {'h','t','t','p',':','/','/','%','s',0};
DWORD len; DWORD len;
TRACE("--> \n"); TRACE("--> \n");
lpwhs = (LPWININETHTTPSESSIONW) WININET_GetObject( hHttpSession ); assert( lpwhs->hdr.htype == WH_HHTTPSESSION );
if (NULL == lpwhs || lpwhs->hdr.htype != WH_HHTTPSESSION)
{
INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
return NULL;
}
hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent; hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent;
lpwhr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WININETHTTPREQW)); lpwhr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WININETHTTPREQW));
if (NULL == lpwhr) if (NULL == lpwhr)
{ {
INTERNET_SetLastError(ERROR_OUTOFMEMORY); INTERNET_SetLastError(ERROR_OUTOFMEMORY);
return NULL; goto lend;
} }
lpwhr->hdr.htype = WH_HHTTPREQ;
lpwhr->hdr.lpwhparent = WININET_AddRef( &lpwhs->hdr );
lpwhr->hdr.dwFlags = dwFlags;
lpwhr->hdr.dwContext = dwContext;
lpwhr->hdr.dwRefCount = 1;
lpwhr->hdr.destroy = HTTP_CloseHTTPRequestHandle;
handle = WININET_AllocHandle( &lpwhr->hdr ); handle = WININET_AllocHandle( &lpwhr->hdr );
if (NULL == handle) if (NULL == handle)
{ {
INTERNET_SetLastError(ERROR_OUTOFMEMORY); INTERNET_SetLastError(ERROR_OUTOFMEMORY);
HeapFree( GetProcessHeap(), 0, lpwhr ); goto lend;
return NULL;
} }
lpwhr->hdr.htype = WH_HHTTPREQ;
lpwhr->hdr.lpwhparent = &lpwhs->hdr;
lpwhr->hdr.dwFlags = dwFlags;
lpwhr->hdr.dwContext = dwContext;
NETCON_init(&lpwhr->netConnection, dwFlags & INTERNET_FLAG_SECURE); NETCON_init(&lpwhr->netConnection, dwFlags & INTERNET_FLAG_SECURE);
if (NULL != lpszObjectName && strlenW(lpszObjectName)) { if (NULL != lpszObjectName && strlenW(lpszObjectName)) {
@ -817,7 +791,7 @@ HINTERNET WINAPI HTTP_HttpOpenRequestW(HINTERNET hHttpSession,
iar.dwResult = (DWORD)handle; iar.dwResult = (DWORD)handle;
iar.dwError = ERROR_SUCCESS; iar.dwError = ERROR_SUCCESS;
SendAsyncCallback(hIC, hHttpSession, dwContext, SendAsyncCallback(hIC, &lpwhs->hdr, dwContext,
INTERNET_STATUS_HANDLE_CREATED, &iar, INTERNET_STATUS_HANDLE_CREATED, &iar,
sizeof(INTERNET_ASYNC_RESULT)); sizeof(INTERNET_ASYNC_RESULT));
} }
@ -829,7 +803,7 @@ HINTERNET WINAPI HTTP_HttpOpenRequestW(HINTERNET hHttpSession,
/* /*
* According to my tests. The name is not resolved until a request is Opened * According to my tests. The name is not resolved until a request is Opened
*/ */
SendAsyncCallback(hIC, hHttpSession, dwContext, SendAsyncCallback(hIC, &lpwhs->hdr, dwContext,
INTERNET_STATUS_RESOLVING_NAME, INTERNET_STATUS_RESOLVING_NAME,
lpwhs->lpszServerName, lpwhs->lpszServerName,
strlenW(lpwhs->lpszServerName)+1); strlenW(lpwhs->lpszServerName)+1);
@ -837,15 +811,21 @@ HINTERNET WINAPI HTTP_HttpOpenRequestW(HINTERNET hHttpSession,
&lpwhs->phostent, &lpwhs->socketAddress)) &lpwhs->phostent, &lpwhs->socketAddress))
{ {
INTERNET_SetLastError(ERROR_INTERNET_NAME_NOT_RESOLVED); INTERNET_SetLastError(ERROR_INTERNET_NAME_NOT_RESOLVED);
return NULL; InternetCloseHandle( handle );
handle = NULL;
goto lend;
} }
SendAsyncCallback(hIC, hHttpSession, lpwhr->hdr.dwContext, SendAsyncCallback(hIC, &lpwhs->hdr, lpwhr->hdr.dwContext,
INTERNET_STATUS_NAME_RESOLVED, INTERNET_STATUS_NAME_RESOLVED,
&(lpwhs->socketAddress), &(lpwhs->socketAddress),
sizeof(struct sockaddr_in)); sizeof(struct sockaddr_in));
TRACE("<-- %p\n", handle); lend:
if( lpwhr )
WININET_Release( &lpwhr->hdr );
TRACE("<-- %p (%p)\n", handle, lpwhr);
return handle; return handle;
} }
@ -1136,12 +1116,16 @@ BOOL WINAPI HttpQueryInfoW(HINTERNET hHttpRequest, DWORD dwInfoLevel,
if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ) if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ)
{ {
INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
return FALSE; goto lend;
} }
bSuccess = HTTP_HttpQueryInfoW( lpwhr, dwInfoLevel, bSuccess = HTTP_HttpQueryInfoW( lpwhr, dwInfoLevel,
lpBuffer, lpdwBufferLength, lpdwIndex); lpBuffer, lpdwBufferLength, lpdwIndex);
lend:
if( lpwhr )
WININET_Release( &lpwhr->hdr );
TRACE("%d <--\n", bSuccess); TRACE("%d <--\n", bSuccess);
return bSuccess; return bSuccess;
} }
@ -1217,6 +1201,7 @@ BOOL WINAPI HttpSendRequestW(HINTERNET hHttpRequest, LPCWSTR lpszHeaders,
LPWININETHTTPREQW lpwhr; LPWININETHTTPREQW lpwhr;
LPWININETHTTPSESSIONW lpwhs = NULL; LPWININETHTTPSESSIONW lpwhs = NULL;
LPWININETAPPINFOW hIC = NULL; LPWININETAPPINFOW hIC = NULL;
BOOL r;
TRACE("%p, %p (%s), %li, %p, %li)\n", hHttpRequest, TRACE("%p, %p (%s), %li, %p, %li)\n", hHttpRequest,
lpszHeaders, debugstr_w(lpszHeaders), dwHeaderLength, lpOptional, dwOptionalLength); lpszHeaders, debugstr_w(lpszHeaders), dwHeaderLength, lpOptional, dwOptionalLength);
@ -1225,21 +1210,24 @@ BOOL WINAPI HttpSendRequestW(HINTERNET hHttpRequest, LPCWSTR lpszHeaders,
if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ) if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ)
{ {
INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
return FALSE; r = FALSE;
goto lend;
} }
lpwhs = (LPWININETHTTPSESSIONW) lpwhr->hdr.lpwhparent; lpwhs = (LPWININETHTTPSESSIONW) lpwhr->hdr.lpwhparent;
if (NULL == lpwhs || lpwhs->hdr.htype != WH_HHTTPSESSION) if (NULL == lpwhs || lpwhs->hdr.htype != WH_HHTTPSESSION)
{ {
INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
return FALSE; r = FALSE;
goto lend;
} }
hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent; hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent;
if (NULL == hIC || hIC->hdr.htype != WH_HINIT) if (NULL == hIC || hIC->hdr.htype != WH_HINIT)
{ {
INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
return FALSE; r = FALSE;
goto lend;
} }
if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC) if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC)
@ -1248,7 +1236,7 @@ BOOL WINAPI HttpSendRequestW(HINTERNET hHttpRequest, LPCWSTR lpszHeaders,
struct WORKREQ_HTTPSENDREQUESTW *req; struct WORKREQ_HTTPSENDREQUESTW *req;
workRequest.asyncall = HTTPSENDREQUESTW; workRequest.asyncall = HTTPSENDREQUESTW;
workRequest.handle = hHttpRequest; workRequest.hdr = WININET_AddRef( &lpwhr->hdr );
req = &workRequest.u.HttpSendRequestW; req = &workRequest.u.HttpSendRequestW;
if (lpszHeaders) if (lpszHeaders)
req->lpszHeader = WININET_strdupW(lpszHeaders); req->lpszHeader = WININET_strdupW(lpszHeaders);
@ -1263,13 +1251,17 @@ BOOL WINAPI HttpSendRequestW(HINTERNET hHttpRequest, LPCWSTR lpszHeaders,
* This is from windows. * This is from windows.
*/ */
SetLastError(ERROR_IO_PENDING); SetLastError(ERROR_IO_PENDING);
return 0; r = FALSE;
} }
else else
{ {
return HTTP_HttpSendRequestW(hHttpRequest, lpszHeaders, r = HTTP_HttpSendRequestW(lpwhr, lpszHeaders,
dwHeaderLength, lpOptional, dwOptionalLength); dwHeaderLength, lpOptional, dwOptionalLength);
} }
lend:
if( lpwhr )
WININET_Release( &lpwhr->hdr );
return r;
} }
/*********************************************************************** /***********************************************************************
@ -1309,7 +1301,6 @@ static BOOL HTTP_HandleRedirect(LPWININETHTTPREQW lpwhr, LPCWSTR lpszUrl, LPCWST
LPWININETHTTPSESSIONW lpwhs = (LPWININETHTTPSESSIONW) lpwhr->hdr.lpwhparent; LPWININETHTTPSESSIONW lpwhs = (LPWININETHTTPSESSIONW) lpwhr->hdr.lpwhparent;
LPWININETAPPINFOW hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent; LPWININETAPPINFOW hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent;
WCHAR path[2048]; WCHAR path[2048];
HINTERNET handle;
if(lpszUrl[0]=='/') if(lpszUrl[0]=='/')
{ {
@ -1374,7 +1365,7 @@ static BOOL HTTP_HandleRedirect(LPWININETHTTPREQW lpwhr, LPCWSTR lpszUrl, LPCWST
HeapFree(GetProcessHeap(), 0, lpwhr->lpszHostName); HeapFree(GetProcessHeap(), 0, lpwhr->lpszHostName);
lpwhr->lpszHostName=WININET_strdupW(hostName); lpwhr->lpszHostName=WININET_strdupW(hostName);
SendAsyncCallback(hIC, lpwhs, lpwhr->hdr.dwContext, SendAsyncCallback(hIC, &lpwhs->hdr, lpwhr->hdr.dwContext,
INTERNET_STATUS_RESOLVING_NAME, INTERNET_STATUS_RESOLVING_NAME,
lpwhs->lpszServerName, lpwhs->lpszServerName,
strlenW(lpwhs->lpszServerName)+1); strlenW(lpwhs->lpszServerName)+1);
@ -1386,7 +1377,7 @@ static BOOL HTTP_HandleRedirect(LPWININETHTTPREQW lpwhr, LPCWSTR lpszUrl, LPCWST
return FALSE; return FALSE;
} }
SendAsyncCallback(hIC, lpwhs, lpwhr->hdr.dwContext, SendAsyncCallback(hIC, &lpwhs->hdr, lpwhr->hdr.dwContext,
INTERNET_STATUS_NAME_RESOLVED, INTERNET_STATUS_NAME_RESOLVED,
&(lpwhs->socketAddress), &(lpwhs->socketAddress),
sizeof(struct sockaddr_in)); sizeof(struct sockaddr_in));
@ -1414,8 +1405,7 @@ static BOOL HTTP_HandleRedirect(LPWININETHTTPREQW lpwhr, LPCWSTR lpszUrl, LPCWST
} }
} }
handle = WININET_FindHandle( &lpwhr->hdr ); return HTTP_HttpSendRequestW(lpwhr, lpszHeaders, dwHeaderLength, lpOptional, dwOptionalLength);
return HttpSendRequestW(handle, lpszHeaders, dwHeaderLength, lpOptional, dwOptionalLength);
} }
/*********************************************************************** /***********************************************************************
@ -1451,7 +1441,7 @@ static LPWSTR HTTP_build_req( LPCWSTR *list, int len )
* FALSE on failure * FALSE on failure
* *
*/ */
BOOL WINAPI HTTP_HttpSendRequestW(HINTERNET hHttpRequest, LPCWSTR lpszHeaders, BOOL WINAPI HTTP_HttpSendRequestW(LPWININETHTTPREQW lpwhr, LPCWSTR lpszHeaders,
DWORD dwHeaderLength, LPVOID lpOptional ,DWORD dwOptionalLength) DWORD dwHeaderLength, LPVOID lpOptional ,DWORD dwOptionalLength)
{ {
INT cnt; INT cnt;
@ -1459,21 +1449,14 @@ BOOL WINAPI HTTP_HttpSendRequestW(HINTERNET hHttpRequest, LPCWSTR lpszHeaders,
BOOL bSuccess = FALSE; BOOL bSuccess = FALSE;
LPWSTR requestString = NULL; LPWSTR requestString = NULL;
INT responseLen; INT responseLen;
LPWININETHTTPREQW lpwhr;
LPWININETHTTPSESSIONW lpwhs = NULL; LPWININETHTTPSESSIONW lpwhs = NULL;
LPWININETAPPINFOW hIC = NULL; LPWININETAPPINFOW hIC = NULL;
BOOL loop_next = FALSE; BOOL loop_next = FALSE;
int CustHeaderIndex; int CustHeaderIndex;
TRACE("--> 0x%08lx\n", (ULONG)hHttpRequest); TRACE("--> %p\n", lpwhr);
/* Verify our tree of internet handles */ assert(lpwhr->hdr.htype == WH_HHTTPREQ);
lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hHttpRequest );
if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ)
{
INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
return FALSE;
}
lpwhs = (LPWININETHTTPSESSIONW) lpwhr->hdr.lpwhparent; lpwhs = (LPWININETHTTPSESSIONW) lpwhr->hdr.lpwhparent;
if (NULL == lpwhs || lpwhs->hdr.htype != WH_HHTTPSESSION) if (NULL == lpwhs || lpwhs->hdr.htype != WH_HHTTPSESSION)
@ -1613,7 +1596,7 @@ BOOL WINAPI HTTP_HttpSendRequestW(HINTERNET hHttpRequest, LPCWSTR lpszHeaders,
if (!HTTP_OpenConnection(lpwhr)) if (!HTTP_OpenConnection(lpwhr))
goto lend; goto lend;
SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext, SendAsyncCallback(hIC, &lpwhr->hdr, lpwhr->hdr.dwContext,
INTERNET_STATUS_SENDING_REQUEST, NULL, 0); INTERNET_STATUS_SENDING_REQUEST, NULL, 0);
/* send the request as ASCII, tack on the optional data */ /* send the request as ASCII, tack on the optional data */
@ -1630,11 +1613,11 @@ BOOL WINAPI HTTP_HttpSendRequestW(HINTERNET hHttpRequest, LPCWSTR lpszHeaders,
NETCON_send(&lpwhr->netConnection, ascii_req, len, 0, &cnt); NETCON_send(&lpwhr->netConnection, ascii_req, len, 0, &cnt);
HeapFree( GetProcessHeap(), 0, ascii_req ); HeapFree( GetProcessHeap(), 0, ascii_req );
SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext, SendAsyncCallback(hIC, &lpwhr->hdr, lpwhr->hdr.dwContext,
INTERNET_STATUS_REQUEST_SENT, INTERNET_STATUS_REQUEST_SENT,
&len,sizeof(DWORD)); &len,sizeof(DWORD));
SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext, SendAsyncCallback(hIC, &lpwhr->hdr, lpwhr->hdr.dwContext,
INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0); INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
if (cnt < 0) if (cnt < 0)
@ -1644,7 +1627,7 @@ BOOL WINAPI HTTP_HttpSendRequestW(HINTERNET hHttpRequest, LPCWSTR lpszHeaders,
if (responseLen) if (responseLen)
bSuccess = TRUE; bSuccess = TRUE;
SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext, SendAsyncCallback(hIC, &lpwhr->hdr, lpwhr->hdr.dwContext,
INTERNET_STATUS_RESPONSE_RECEIVED, &responseLen, INTERNET_STATUS_RESPONSE_RECEIVED, &responseLen,
sizeof(DWORD)); sizeof(DWORD));
@ -1744,7 +1727,7 @@ lend:
dwIndex=0; dwIndex=0;
if(HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_LOCATION,szNewLocation,&dwBufferSize,&dwIndex)) if(HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_LOCATION,szNewLocation,&dwBufferSize,&dwIndex))
{ {
SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext, SendAsyncCallback(hIC, &lpwhr->hdr, lpwhr->hdr.dwContext,
INTERNET_STATUS_REDIRECT, szNewLocation, INTERNET_STATUS_REDIRECT, szNewLocation,
dwBufferSize); dwBufferSize);
return HTTP_HandleRedirect(lpwhr, szNewLocation, lpszHeaders, return HTTP_HandleRedirect(lpwhr, szNewLocation, lpszHeaders,
@ -1760,7 +1743,7 @@ lend:
iar.dwResult = (DWORD)bSuccess; iar.dwResult = (DWORD)bSuccess;
iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError(); iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError();
SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext, SendAsyncCallback(hIC, &lpwhr->hdr, lpwhr->hdr.dwContext,
INTERNET_STATUS_REQUEST_COMPLETE, &iar, INTERNET_STATUS_REQUEST_COMPLETE, &iar,
sizeof(INTERNET_ASYNC_RESULT)); sizeof(INTERNET_ASYNC_RESULT));
} }
@ -1780,21 +1763,18 @@ lend:
* NULL on failure * NULL on failure
* *
*/ */
HINTERNET HTTP_Connect(HINTERNET hInternet, LPCWSTR lpszServerName, HINTERNET HTTP_Connect(LPWININETAPPINFOW hIC, LPCWSTR lpszServerName,
INTERNET_PORT nServerPort, LPCWSTR lpszUserName, INTERNET_PORT nServerPort, LPCWSTR lpszUserName,
LPCWSTR lpszPassword, DWORD dwFlags, DWORD dwContext, LPCWSTR lpszPassword, DWORD dwFlags, DWORD dwContext,
DWORD dwInternalFlags) DWORD dwInternalFlags)
{ {
BOOL bSuccess = FALSE; BOOL bSuccess = FALSE;
LPWININETAPPINFOW hIC = NULL;
LPWININETHTTPSESSIONW lpwhs = NULL; LPWININETHTTPSESSIONW lpwhs = NULL;
HINTERNET handle = NULL; HINTERNET handle = NULL;
TRACE("-->\n"); TRACE("-->\n");
hIC = (LPWININETAPPINFOW) WININET_GetObject( hInternet ); assert( hIC->hdr.htype == WH_HINIT );
if( (hIC == NULL) || (hIC->hdr.htype != WH_HINIT) )
goto lerror;
hIC->hdr.dwContext = dwContext; hIC->hdr.dwContext = dwContext;
@ -1805,14 +1785,6 @@ HINTERNET HTTP_Connect(HINTERNET hInternet, LPCWSTR lpszServerName,
goto lerror; goto lerror;
} }
handle = WININET_AllocHandle( &lpwhs->hdr );
if (NULL == handle)
{
ERR("Failed to alloc handle\n");
INTERNET_SetLastError(ERROR_OUTOFMEMORY);
goto lerror;
}
/* /*
* According to my tests. The name is not resolved until a request is sent * According to my tests. The name is not resolved until a request is sent
*/ */
@ -1821,10 +1793,21 @@ HINTERNET HTTP_Connect(HINTERNET hInternet, LPCWSTR lpszServerName,
nServerPort = INTERNET_DEFAULT_HTTP_PORT; nServerPort = INTERNET_DEFAULT_HTTP_PORT;
lpwhs->hdr.htype = WH_HHTTPSESSION; lpwhs->hdr.htype = WH_HHTTPSESSION;
lpwhs->hdr.lpwhparent = &hIC->hdr; lpwhs->hdr.lpwhparent = WININET_AddRef( &hIC->hdr );
lpwhs->hdr.dwFlags = dwFlags; lpwhs->hdr.dwFlags = dwFlags;
lpwhs->hdr.dwContext = dwContext; lpwhs->hdr.dwContext = dwContext;
lpwhs->hdr.dwInternalFlags = dwInternalFlags; lpwhs->hdr.dwInternalFlags = dwInternalFlags;
lpwhs->hdr.dwRefCount = 1;
lpwhs->hdr.destroy = HTTP_CloseHTTPSessionHandle;
handle = WININET_AllocHandle( &lpwhs->hdr );
if (NULL == handle)
{
ERR("Failed to alloc handle\n");
INTERNET_SetLastError(ERROR_OUTOFMEMORY);
goto lerror;
}
if(hIC->lpszProxy && hIC->dwAccessType == INTERNET_OPEN_TYPE_PROXY) { if(hIC->lpszProxy && hIC->dwAccessType == INTERNET_OPEN_TYPE_PROXY) {
if(strchrW(hIC->lpszProxy, ' ')) if(strchrW(hIC->lpszProxy, ' '))
FIXME("Several proxies not implemented.\n"); FIXME("Several proxies not implemented.\n");
@ -1845,7 +1828,7 @@ HINTERNET HTTP_Connect(HINTERNET hInternet, LPCWSTR lpszServerName,
iar.dwResult = (DWORD)handle; iar.dwResult = (DWORD)handle;
iar.dwError = ERROR_SUCCESS; iar.dwError = ERROR_SUCCESS;
SendAsyncCallback(hIC, hInternet, dwContext, SendAsyncCallback(hIC, &hIC->hdr, dwContext,
INTERNET_STATUS_HANDLE_CREATED, &iar, INTERNET_STATUS_HANDLE_CREATED, &iar,
sizeof(INTERNET_ASYNC_RESULT)); sizeof(INTERNET_ASYNC_RESULT));
} }
@ -1853,19 +1836,15 @@ HINTERNET HTTP_Connect(HINTERNET hInternet, LPCWSTR lpszServerName,
bSuccess = TRUE; bSuccess = TRUE;
lerror: lerror:
if (!bSuccess && lpwhs) if( lpwhs )
{ WININET_Release( &lpwhs->hdr );
HeapFree(GetProcessHeap(), 0, lpwhs);
WININET_FreeHandle( handle );
lpwhs = NULL;
}
/* /*
* a INTERNET_STATUS_REQUEST_COMPLETE is NOT sent here as per my tests on * a INTERNET_STATUS_REQUEST_COMPLETE is NOT sent here as per my tests on
* windows * windows
*/ */
TRACE("%p --> %p\n", hInternet, handle); TRACE("%p --> %p (%p)\n", hIC, handle, lpwhs);
return handle; return handle;
} }
@ -1898,7 +1877,7 @@ BOOL HTTP_OpenConnection(LPWININETHTTPREQW lpwhr)
lpwhs = (LPWININETHTTPSESSIONW)lpwhr->hdr.lpwhparent; lpwhs = (LPWININETHTTPSESSIONW)lpwhr->hdr.lpwhparent;
hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent; hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent;
SendAsyncCallback(hIC, lpwhr, lpwhr->hdr.dwContext, SendAsyncCallback(hIC, &lpwhr->hdr, lpwhr->hdr.dwContext,
INTERNET_STATUS_CONNECTING_TO_SERVER, INTERNET_STATUS_CONNECTING_TO_SERVER,
&(lpwhs->socketAddress), &(lpwhs->socketAddress),
sizeof(struct sockaddr_in)); sizeof(struct sockaddr_in));
@ -1917,7 +1896,7 @@ BOOL HTTP_OpenConnection(LPWININETHTTPREQW lpwhr)
goto lend; goto lend;
} }
SendAsyncCallback(hIC, lpwhr, lpwhr->hdr.dwContext, SendAsyncCallback(hIC, &lpwhr->hdr, lpwhr->hdr.dwContext,
INTERNET_STATUS_CONNECTED_TO_SERVER, INTERNET_STATUS_CONNECTED_TO_SERVER,
&(lpwhs->socketAddress), &(lpwhs->socketAddress),
sizeof(struct sockaddr_in)); sizeof(struct sockaddr_in));
@ -2100,7 +2079,7 @@ lend:
* TRUE on success * TRUE on success
* FALSE on error * FALSE on error
*/ */
INT stripSpaces(LPCWSTR lpszSrc, LPWSTR lpszStart, INT *len) static INT stripSpaces(LPCWSTR lpszSrc, LPWSTR lpszStart, INT *len)
{ {
LPCWSTR lpsztmp; LPCWSTR lpsztmp;
INT srclen; INT srclen;
@ -2411,19 +2390,15 @@ BOOL HTTP_ProcessHeader(LPWININETHTTPREQW lpwhr, LPCWSTR field, LPCWSTR value, D
*/ */
VOID HTTP_CloseConnection(LPWININETHTTPREQW lpwhr) VOID HTTP_CloseConnection(LPWININETHTTPREQW lpwhr)
{ {
LPWININETHTTPSESSIONW lpwhs = NULL; LPWININETHTTPSESSIONW lpwhs = NULL;
LPWININETAPPINFOW hIC = NULL; LPWININETAPPINFOW hIC = NULL;
HINTERNET handle;
TRACE("%p\n",lpwhr); TRACE("%p\n",lpwhr);
handle = WININET_FindHandle( &lpwhr->hdr );
lpwhs = (LPWININETHTTPSESSIONW) lpwhr->hdr.lpwhparent; lpwhs = (LPWININETHTTPSESSIONW) lpwhr->hdr.lpwhparent;
hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent; hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent;
SendAsyncCallback(hIC, lpwhr, lpwhr->hdr.dwContext, SendAsyncCallback(hIC, &lpwhr->hdr, lpwhr->hdr.dwContext,
INTERNET_STATUS_CLOSING_CONNECTION, 0, 0); INTERNET_STATUS_CLOSING_CONNECTION, 0, 0);
if (NETCON_connected(&lpwhr->netConnection)) if (NETCON_connected(&lpwhr->netConnection))
@ -2431,7 +2406,7 @@ VOID HTTP_CloseConnection(LPWININETHTTPREQW lpwhr)
NETCON_close(&lpwhr->netConnection); NETCON_close(&lpwhr->netConnection);
} }
SendAsyncCallback(hIC, lpwhr, lpwhr->hdr.dwContext, SendAsyncCallback(hIC, &lpwhr->hdr, lpwhr->hdr.dwContext,
INTERNET_STATUS_CONNECTION_CLOSED, 0, 0); INTERNET_STATUS_CONNECTION_CLOSED, 0, 0);
} }
@ -2442,26 +2417,16 @@ VOID HTTP_CloseConnection(LPWININETHTTPREQW lpwhr)
* Deallocate request handle * Deallocate request handle
* *
*/ */
void HTTP_CloseHTTPRequestHandle(LPWININETHTTPREQW lpwhr) static void HTTP_CloseHTTPRequestHandle(LPWININETHANDLEHEADER hdr)
{ {
int i; int i;
LPWININETHTTPSESSIONW lpwhs = NULL; LPWININETHTTPREQW lpwhr = (LPWININETHTTPREQW) hdr;
LPWININETAPPINFOW hIC = NULL;
HINTERNET handle;
TRACE("\n"); TRACE("\n");
if (NETCON_connected(&lpwhr->netConnection)) if (NETCON_connected(&lpwhr->netConnection))
HTTP_CloseConnection(lpwhr); HTTP_CloseConnection(lpwhr);
handle = WININET_FindHandle( &lpwhr->hdr );
lpwhs = (LPWININETHTTPSESSIONW) lpwhr->hdr.lpwhparent;
hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent;
SendAsyncCallback(hIC, handle, lpwhr->hdr.dwContext,
INTERNET_STATUS_HANDLE_CLOSING, lpwhr,
sizeof(HINTERNET));
if (lpwhr->lpszPath) if (lpwhr->lpszPath)
HeapFree(GetProcessHeap(), 0, lpwhr->lpszPath); HeapFree(GetProcessHeap(), 0, lpwhr->lpszPath);
if (lpwhr->lpszVerb) if (lpwhr->lpszVerb)
@ -2489,15 +2454,6 @@ void HTTP_CloseHTTPRequestHandle(LPWININETHTTPREQW lpwhr)
HeapFree(GetProcessHeap(), 0, lpwhr->pCustHeaders); HeapFree(GetProcessHeap(), 0, lpwhr->pCustHeaders);
HeapFree(GetProcessHeap(), 0, lpwhr); 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);
}
} }
@ -2507,24 +2463,12 @@ void HTTP_CloseHTTPRequestHandle(LPWININETHTTPREQW lpwhr)
* Deallocate session handle * Deallocate session handle
* *
*/ */
void HTTP_CloseHTTPSessionHandle(LPWININETHTTPSESSIONW lpwhs) void HTTP_CloseHTTPSessionHandle(LPWININETHANDLEHEADER hdr)
{ {
LPWININETAPPINFOW hIC = NULL; LPWININETHTTPSESSIONW lpwhs = (LPWININETHTTPSESSIONW) hdr;
HINTERNET handle;
TRACE("%p\n", lpwhs); TRACE("%p\n", lpwhs);
hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent;
/* 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) if (lpwhs->lpszServerName)
HeapFree(GetProcessHeap(), 0, lpwhs->lpszServerName); HeapFree(GetProcessHeap(), 0, lpwhs->lpszServerName);
if (lpwhs->lpszUserName) if (lpwhs->lpszUserName)

View File

@ -46,6 +46,7 @@
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
# include <unistd.h> # include <unistd.h>
#endif #endif
#include <assert.h>
#include "ntstatus.h" #include "ntstatus.h"
#include "windef.h" #include "windef.h"
@ -81,10 +82,11 @@ typedef struct
CHAR response[MAX_REPLY_LEN]; CHAR response[MAX_REPLY_LEN];
} WITHREADERROR, *LPWITHREADERROR; } WITHREADERROR, *LPWITHREADERROR;
BOOL WINAPI INTERNET_FindNextFileW(HINTERNET hFind, LPVOID lpvFindData); static VOID INTERNET_CloseHandle(LPWININETHANDLEHEADER hdr);
HINTERNET WINAPI INTERNET_InternetOpenUrlW(HINTERNET hInternet, LPCWSTR lpszUrl, BOOL WINAPI INTERNET_FindNextFileW(LPWININETFINDNEXTW lpwh, LPVOID lpvFindData);
HINTERNET WINAPI INTERNET_InternetOpenUrlW(LPWININETAPPINFOW hIC, LPCWSTR lpszUrl,
LPCWSTR lpszHeaders, DWORD dwHeadersLength, DWORD dwFlags, DWORD dwContext); LPCWSTR lpszHeaders, DWORD dwHeadersLength, DWORD dwFlags, DWORD dwContext);
VOID INTERNET_ExecuteWork(); static VOID INTERNET_ExecuteWork();
DWORD g_dwTlsErrIndex = TLS_OUT_OF_INDEXES; DWORD g_dwTlsErrIndex = TLS_OUT_OF_INDEXES;
DWORD dwNumThreads; DWORD dwNumThreads;
@ -145,7 +147,7 @@ HINTERNET WININET_AllocHandle( LPWININETHANDLEHEADER info )
handle = WININET_dwNextHandle; handle = WININET_dwNextHandle;
if( WININET_Handles[handle] ) if( WININET_Handles[handle] )
ERR("handle isn't free but should be\n"); ERR("handle isn't free but should be\n");
WININET_Handles[handle] = info; WININET_Handles[handle] = WININET_AddRef( info );
while( WININET_Handles[WININET_dwNextHandle] && while( WININET_Handles[WININET_dwNextHandle] &&
(WININET_dwNextHandle < WININET_dwMaxHandles ) ) (WININET_dwNextHandle < WININET_dwMaxHandles ) )
@ -166,6 +168,7 @@ HINTERNET WININET_FindHandle( LPWININETHANDLEHEADER info )
{ {
if( info == WININET_Handles[i] ) if( info == WININET_Handles[i] )
{ {
WININET_AddRef( info );
handle = i+1; handle = i+1;
break; break;
} }
@ -175,6 +178,13 @@ HINTERNET WININET_FindHandle( LPWININETHANDLEHEADER info )
return (HINTERNET) handle; return (HINTERNET) handle;
} }
LPWININETHANDLEHEADER WININET_AddRef( LPWININETHANDLEHEADER info )
{
info->dwRefCount++;
TRACE("%p -> refcount = %ld\n", info, info->dwRefCount );
return info;
}
LPWININETHANDLEHEADER WININET_GetObject( HINTERNET hinternet ) LPWININETHANDLEHEADER WININET_GetObject( HINTERNET hinternet )
{ {
LPWININETHANDLEHEADER info = NULL; LPWININETHANDLEHEADER info = NULL;
@ -183,7 +193,7 @@ LPWININETHANDLEHEADER WININET_GetObject( HINTERNET hinternet )
EnterCriticalSection( &WININET_cs ); EnterCriticalSection( &WININET_cs );
if( (handle > 0) && ( handle <= WININET_dwMaxHandles ) ) if( (handle > 0) && ( handle <= WININET_dwMaxHandles ) )
info = WININET_Handles[handle-1]; info = WININET_AddRef( WININET_Handles[handle-1] );
LeaveCriticalSection( &WININET_cs ); LeaveCriticalSection( &WININET_cs );
@ -192,18 +202,33 @@ LPWININETHANDLEHEADER WININET_GetObject( HINTERNET hinternet )
return info; return info;
} }
BOOL WININET_Release( LPWININETHANDLEHEADER info )
{
info->dwRefCount--;
TRACE( "object %p refcount = %ld\n", info, info->dwRefCount );
if( !info->dwRefCount )
{
TRACE( "destroying object %p\n", info);
info->destroy( info );
}
return TRUE;
}
BOOL WININET_FreeHandle( HINTERNET hinternet ) BOOL WININET_FreeHandle( HINTERNET hinternet )
{ {
BOOL ret = FALSE; BOOL ret = FALSE;
UINT handle = (UINT) hinternet; UINT handle = (UINT) hinternet;
LPWININETHANDLEHEADER info = NULL;
EnterCriticalSection( &WININET_cs ); EnterCriticalSection( &WININET_cs );
if( (handle > 1) && ( handle < WININET_dwMaxHandles ) ) if( (handle > 0) && ( handle <= WININET_dwMaxHandles ) )
{ {
handle--; handle--;
if( WININET_Handles[handle] ) if( WININET_Handles[handle] )
{ {
info = WININET_Handles[handle];
TRACE( "destroying handle %d for object %p\n", handle+1, info);
WININET_Handles[handle] = NULL; WININET_Handles[handle] = NULL;
ret = TRUE; ret = TRUE;
if( WININET_dwNextHandle > handle ) if( WININET_dwNextHandle > handle )
@ -213,6 +238,9 @@ BOOL WININET_FreeHandle( HINTERNET hinternet )
LeaveCriticalSection( &WININET_cs ); LeaveCriticalSection( &WININET_cs );
if( info )
WININET_Release( info );
return ret; return ret;
} }
@ -461,6 +489,8 @@ HINTERNET WINAPI InternetOpenW(LPCWSTR lpszAgent, DWORD dwAccessType,
lpwai->hdr.htype = WH_HINIT; lpwai->hdr.htype = WH_HINIT;
lpwai->hdr.lpwhparent = NULL; lpwai->hdr.lpwhparent = NULL;
lpwai->hdr.dwFlags = dwFlags; lpwai->hdr.dwFlags = dwFlags;
lpwai->hdr.dwRefCount = 1;
lpwai->hdr.destroy = INTERNET_CloseHandle;
lpwai->dwAccessType = dwAccessType; lpwai->dwAccessType = dwAccessType;
lpwai->lpszProxyUsername = NULL; lpwai->lpszProxyUsername = NULL;
lpwai->lpszProxyPassword = NULL; lpwai->lpszProxyPassword = NULL;
@ -498,8 +528,11 @@ HINTERNET WINAPI InternetOpenW(LPCWSTR lpszAgent, DWORD dwAccessType,
lstrcpyW( lpwai->lpszProxyBypass, lpszProxyBypass ); lstrcpyW( lpwai->lpszProxyBypass, lpszProxyBypass );
} }
lend: lend:
TRACE("returning %p\n", (HINTERNET)lpwai); if( lpwai )
WININET_Release( &lpwai->hdr );
TRACE("returning %p\n", lpwai);
return handle; return handle;
} }
@ -652,6 +685,7 @@ HINTERNET WINAPI InternetConnectW(HINTERNET hInternet,
LPCWSTR lpszUserName, LPCWSTR lpszPassword, LPCWSTR lpszUserName, LPCWSTR lpszPassword,
DWORD dwService, DWORD dwFlags, DWORD dwContext) DWORD dwService, DWORD dwFlags, DWORD dwContext)
{ {
LPWININETAPPINFOW hIC;
HINTERNET rc = (HINTERNET) NULL; HINTERNET rc = (HINTERNET) NULL;
TRACE("(%p, %s, %i, %s, %s, %li, %li, %li)\n", hInternet, debugstr_w(lpszServerName), TRACE("(%p, %s, %i, %s, %s, %li, %li, %li)\n", hInternet, debugstr_w(lpszServerName),
@ -660,16 +694,19 @@ HINTERNET WINAPI InternetConnectW(HINTERNET hInternet,
/* Clear any error information */ /* Clear any error information */
INTERNET_SetLastError(0); INTERNET_SetLastError(0);
hIC = (LPWININETAPPINFOW) WININET_GetObject( hInternet );
if ( (hIC == NULL) || (hIC->hdr.htype != WH_HINIT) )
goto lend;
switch (dwService) switch (dwService)
{ {
case INTERNET_SERVICE_FTP: case INTERNET_SERVICE_FTP:
rc = FTP_Connect(hInternet, lpszServerName, nServerPort, rc = FTP_Connect(hIC, lpszServerName, nServerPort,
lpszUserName, lpszPassword, dwFlags, dwContext, 0); lpszUserName, lpszPassword, dwFlags, dwContext, 0);
break; break;
case INTERNET_SERVICE_HTTP: case INTERNET_SERVICE_HTTP:
rc = HTTP_Connect(hInternet, lpszServerName, nServerPort, rc = HTTP_Connect(hIC, lpszServerName, nServerPort,
lpszUserName, lpszPassword, dwFlags, dwContext, 0); lpszUserName, lpszPassword, dwFlags, dwContext, 0);
break; break;
@ -677,6 +714,9 @@ HINTERNET WINAPI InternetConnectW(HINTERNET hInternet,
default: default:
break; break;
} }
lend:
if( hIC )
WININET_Release( &hIC->hdr );
TRACE("returning %p\n", rc); TRACE("returning %p\n", rc);
return rc; return rc;
@ -769,15 +809,15 @@ BOOL WINAPI InternetFindNextFileW(HINTERNET hFind, LPVOID lpvFindData)
{ {
LPWININETAPPINFOW hIC = NULL; LPWININETAPPINFOW hIC = NULL;
LPWININETFINDNEXTW lpwh; LPWININETFINDNEXTW lpwh;
BOOL bSuccess = FALSE;
TRACE("\n"); TRACE("\n");
lpwh = (LPWININETFINDNEXTW) WININET_GetObject( hFind ); lpwh = (LPWININETFINDNEXTW) WININET_GetObject( hFind );
if (NULL == lpwh || lpwh->hdr.htype != WH_HFINDNEXT) if (NULL == lpwh || lpwh->hdr.htype != WH_HFINDNEXT)
{ {
INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
return FALSE; goto lend;
} }
hIC = GET_HWININET_FROM_LPWININETFINDNEXT(lpwh); hIC = GET_HWININET_FROM_LPWININETFINDNEXT(lpwh);
@ -787,16 +827,20 @@ BOOL WINAPI InternetFindNextFileW(HINTERNET hFind, LPVOID lpvFindData)
struct WORKREQ_INTERNETFINDNEXTW *req; struct WORKREQ_INTERNETFINDNEXTW *req;
workRequest.asyncall = INTERNETFINDNEXTW; workRequest.asyncall = INTERNETFINDNEXTW;
workRequest.handle = hFind; workRequest.hdr = WININET_AddRef( &lpwh->hdr );
req = &workRequest.u.InternetFindNextW; req = &workRequest.u.InternetFindNextW;
req->lpFindFileData = lpvFindData; req->lpFindFileData = lpvFindData;
return INTERNET_AsyncCall(&workRequest); bSuccess = INTERNET_AsyncCall(&workRequest);
} }
else else
{ {
return INTERNET_FindNextFileW(hFind, lpvFindData); bSuccess = INTERNET_FindNextFileW(lpwh, lpvFindData);
} }
lend:
if( lpwh )
WININET_Release( &lpwh->hdr );
return bSuccess;
} }
/*********************************************************************** /***********************************************************************
@ -809,21 +853,15 @@ BOOL WINAPI InternetFindNextFileW(HINTERNET hFind, LPVOID lpvFindData)
* FALSE on failure * FALSE on failure
* *
*/ */
BOOL WINAPI INTERNET_FindNextFileW(HINTERNET hFind, LPVOID lpvFindData) BOOL WINAPI INTERNET_FindNextFileW(LPWININETFINDNEXTW lpwh, LPVOID lpvFindData)
{ {
BOOL bSuccess = TRUE; BOOL bSuccess = TRUE;
LPWININETAPPINFOW hIC = NULL; LPWININETAPPINFOW hIC = NULL;
LPWIN32_FIND_DATAW lpFindFileData; LPWIN32_FIND_DATAW lpFindFileData;
LPWININETFINDNEXTW lpwh;
TRACE("\n"); TRACE("\n");
lpwh = (LPWININETFINDNEXTW) WININET_GetObject( hFind ); assert (lpwh->hdr.htype == WH_HFINDNEXT);
if (NULL == lpwh || lpwh->hdr.htype != WH_HFINDNEXT)
{
INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
return FALSE;
}
/* Clear any error information */ /* Clear any error information */
INTERNET_SetLastError(0); INTERNET_SetLastError(0);
@ -863,7 +901,7 @@ lend:
iar.dwError = iar.dwError = bSuccess ? ERROR_SUCCESS : iar.dwError = iar.dwError = bSuccess ? ERROR_SUCCESS :
INTERNET_GetLastError(); INTERNET_GetLastError();
SendAsyncCallback(hIC, hFind, lpwh->hdr.dwContext, SendAsyncCallback(hIC, &lpwh->hdr, lpwh->hdr.dwContext,
INTERNET_STATUS_REQUEST_COMPLETE, &iar, INTERNET_STATUS_REQUEST_COMPLETE, &iar,
sizeof(INTERNET_ASYNC_RESULT)); sizeof(INTERNET_ASYNC_RESULT));
} }
@ -881,13 +919,11 @@ lend:
* Void * Void
* *
*/ */
VOID INTERNET_CloseHandle(LPWININETAPPINFOW lpwai) static VOID INTERNET_CloseHandle(LPWININETHANDLEHEADER hdr)
{ {
TRACE("%p\n",lpwai); LPWININETAPPINFOW lpwai = (LPWININETAPPINFOW) hdr;
SendAsyncCallback(lpwai, lpwai, lpwai->hdr.dwContext, TRACE("%p\n",lpwai);
INTERNET_STATUS_HANDLE_CLOSING, lpwai,
sizeof(HINTERNET));
if (lpwai->lpszAgent) if (lpwai->lpszAgent)
HeapFree(GetProcessHeap(), 0, lpwai->lpszAgent); HeapFree(GetProcessHeap(), 0, lpwai->lpszAgent);
@ -920,8 +956,8 @@ VOID INTERNET_CloseHandle(LPWININETAPPINFOW lpwai)
*/ */
BOOL WINAPI InternetCloseHandle(HINTERNET hInternet) BOOL WINAPI InternetCloseHandle(HINTERNET hInternet)
{ {
BOOL retval; LPWININETHANDLEHEADER lpwh, parent;
LPWININETHANDLEHEADER lpwh; LPWININETAPPINFOW hIC;
TRACE("%p\n",hInternet); TRACE("%p\n",hInternet);
@ -932,46 +968,21 @@ BOOL WINAPI InternetCloseHandle(HINTERNET hInternet)
return FALSE; return FALSE;
} }
/* Clear any error information */ parent = lpwh;
INTERNET_SetLastError(0); while( parent && (parent->htype != WH_HINIT ) )
retval = FALSE; parent = parent->lpwhparent;
switch (lpwh->htype) hIC = (LPWININETAPPINFOW) parent;
{ SendAsyncCallback(hIC, lpwh, lpwh->dwContext,
case WH_HINIT: INTERNET_STATUS_HANDLE_CLOSING, hInternet,
INTERNET_CloseHandle((LPWININETAPPINFOW) lpwh); sizeof(HINTERNET));
retval = TRUE;
break;
case WH_HHTTPSESSION: if( lpwh->lpwhparent )
HTTP_CloseHTTPSessionHandle((LPWININETHTTPSESSIONW) lpwh); WININET_Release( lpwh->lpwhparent );
retval = TRUE;
break;
case WH_HHTTPREQ:
HTTP_CloseHTTPRequestHandle((LPWININETHTTPREQW) lpwh);
retval = TRUE;
break;
case WH_HFTPSESSION:
retval = FTP_CloseSessionHandle((LPWININETFTPSESSIONW) lpwh);
break;
case WH_HFINDNEXT:
retval = FTP_CloseFindNextHandle((LPWININETFINDNEXTW) lpwh);
break;
case WH_HFILE:
retval = FTP_CloseFileTransferHandle((LPWININETFILE) lpwh);
break;
default:
break;
}
if( retval )
WININET_FreeHandle( hInternet ); WININET_FreeHandle( hInternet );
WININET_Release( lpwh );
return retval; return TRUE;
} }
@ -1480,21 +1491,22 @@ BOOL WINAPI InternetCanonicalizeUrlW(LPCWSTR lpszUrl, LPWSTR lpszBuffer,
INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallbackA( INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallbackA(
HINTERNET hInternet ,INTERNET_STATUS_CALLBACK lpfnIntCB) HINTERNET hInternet ,INTERNET_STATUS_CALLBACK lpfnIntCB)
{ {
INTERNET_STATUS_CALLBACK retVal; INTERNET_STATUS_CALLBACK retVal = INTERNET_INVALID_STATUS_CALLBACK;
LPWININETAPPINFOW lpwai; LPWININETAPPINFOW lpwai;
TRACE("0x%08lx\n", (ULONG)hInternet); TRACE("0x%08lx\n", (ULONG)hInternet);
lpwai = (LPWININETAPPINFOW)WININET_GetObject(hInternet); lpwai = (LPWININETAPPINFOW)WININET_GetObject(hInternet);
if (!lpwai) if (!lpwai)
return NULL; return retVal;
if (lpwai->hdr.htype != WH_HINIT)
return INTERNET_INVALID_STATUS_CALLBACK;
if (lpwai->hdr.htype == WH_HINIT)
{
lpwai->hdr.dwInternalFlags &= ~INET_CALLBACKW; lpwai->hdr.dwInternalFlags &= ~INET_CALLBACKW;
retVal = lpwai->lpfnStatusCB; retVal = lpwai->lpfnStatusCB;
lpwai->lpfnStatusCB = lpfnIntCB; lpwai->lpfnStatusCB = lpfnIntCB;
}
WININET_Release( &lpwai->hdr );
return retVal; return retVal;
} }
@ -1513,21 +1525,23 @@ INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallbackA(
INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallbackW( INTERNET_STATUS_CALLBACK WINAPI InternetSetStatusCallbackW(
HINTERNET hInternet ,INTERNET_STATUS_CALLBACK lpfnIntCB) HINTERNET hInternet ,INTERNET_STATUS_CALLBACK lpfnIntCB)
{ {
INTERNET_STATUS_CALLBACK retVal; INTERNET_STATUS_CALLBACK retVal = INTERNET_INVALID_STATUS_CALLBACK;
LPWININETAPPINFOW lpwai; LPWININETAPPINFOW lpwai;
TRACE("0x%08lx\n", (ULONG)hInternet); TRACE("0x%08lx\n", (ULONG)hInternet);
lpwai = (LPWININETAPPINFOW)WININET_GetObject(hInternet); lpwai = (LPWININETAPPINFOW)WININET_GetObject(hInternet);
if (!lpwai) if (!lpwai)
return NULL; return retVal;
if (lpwai->hdr.htype != WH_HINIT)
return INTERNET_INVALID_STATUS_CALLBACK;
if (lpwai->hdr.htype == WH_HINIT)
{
lpwai->hdr.dwInternalFlags |= INET_CALLBACKW; lpwai->hdr.dwInternalFlags |= INET_CALLBACKW;
retVal = lpwai->lpfnStatusCB; retVal = lpwai->lpfnStatusCB;
lpwai->lpfnStatusCB = lpfnIntCB; lpwai->lpfnStatusCB = lpfnIntCB;
}
WININET_Release( &lpwai->hdr );
return retVal; return retVal;
} }
@ -1586,6 +1600,7 @@ BOOL WINAPI InternetWriteFile(HINTERNET hFile, LPCVOID lpBuffer ,
retval = (res >= 0); retval = (res >= 0);
*lpdwNumOfBytesWritten = retval ? res : 0; *lpdwNumOfBytesWritten = retval ? res : 0;
} }
WININET_Release( lpwh );
return retval; return retval;
} }
@ -1608,7 +1623,7 @@ BOOL WINAPI InternetReadFile(HINTERNET hFile, LPVOID lpBuffer,
int nSocket = -1; int nSocket = -1;
LPWININETHANDLEHEADER lpwh; LPWININETHANDLEHEADER lpwh;
TRACE("\n"); TRACE("%p %p %ld %p\n", hFile, lpBuffer, dwNumOfBytesToRead, dwNumOfBytesRead);
lpwh = (LPWININETHANDLEHEADER) WININET_GetObject( hFile ); lpwh = (LPWININETHANDLEHEADER) WININET_GetObject( hFile );
if (NULL == lpwh) if (NULL == lpwh)
@ -1642,6 +1657,7 @@ BOOL WINAPI InternetReadFile(HINTERNET hFile, LPVOID lpBuffer,
default: default:
break; break;
} }
WININET_Release( lpwh );
return retval; return retval;
} }
@ -1778,6 +1794,7 @@ static BOOL INET_QueryOptionHelper(BOOL bIsUnicode, HINTERNET hInternet, DWORD d
FIXME("Stub! %ld \n",dwOption); FIXME("Stub! %ld \n",dwOption);
break; break;
} }
WININET_Release( lpwhh );
return bSuccess; return bSuccess;
} }
@ -1829,6 +1846,7 @@ BOOL WINAPI InternetSetOptionW(HINTERNET hInternet, DWORD dwOption,
LPVOID lpBuffer, DWORD dwBufferLength) LPVOID lpBuffer, DWORD dwBufferLength)
{ {
LPWININETHANDLEHEADER lpwhh; LPWININETHANDLEHEADER lpwhh;
BOOL ret = TRUE;
TRACE("0x%08lx\n", dwOption); TRACE("0x%08lx\n", dwOption);
@ -1886,8 +1904,10 @@ BOOL WINAPI InternetSetOptionW(HINTERNET hInternet, DWORD dwOption,
default: default:
FIXME("Option %ld STUB\n",dwOption); FIXME("Option %ld STUB\n",dwOption);
INTERNET_SetLastError(ERROR_INVALID_PARAMETER); INTERNET_SetLastError(ERROR_INVALID_PARAMETER);
return FALSE; ret = FALSE;
break;
} }
WININET_Release( lpwhh );
return TRUE; return TRUE;
} }
@ -2097,7 +2117,7 @@ BOOL WINAPI InternetCheckConnectionW(LPCWSTR lpszUrl, DWORD dwFlags, DWORD dwRes
* RETURNS * RETURNS
* handle of connection or NULL on failure * handle of connection or NULL on failure
*/ */
HINTERNET WINAPI INTERNET_InternetOpenUrlW(HINTERNET hInternet, LPCWSTR lpszUrl, HINTERNET WINAPI INTERNET_InternetOpenUrlW(LPWININETAPPINFOW hIC, LPCWSTR lpszUrl,
LPCWSTR lpszHeaders, DWORD dwHeadersLength, DWORD dwFlags, DWORD dwContext) LPCWSTR lpszHeaders, DWORD dwHeadersLength, DWORD dwFlags, DWORD dwContext)
{ {
URL_COMPONENTSW urlComponents; URL_COMPONENTSW urlComponents;
@ -2105,7 +2125,7 @@ HINTERNET WINAPI INTERNET_InternetOpenUrlW(HINTERNET hInternet, LPCWSTR lpszUrl,
WCHAR password[1024], path[2048], extra[1024]; WCHAR password[1024], path[2048], extra[1024];
HINTERNET client = NULL, client1 = NULL; HINTERNET client = NULL, client1 = NULL;
TRACE("(%p, %s, %s, %08lx, %08lx, %08lx\n", hInternet, debugstr_w(lpszUrl), debugstr_w(lpszHeaders), TRACE("(%p, %s, %s, %08lx, %08lx, %08lx\n", hIC, debugstr_w(lpszUrl), debugstr_w(lpszHeaders),
dwHeadersLength, dwFlags, dwContext); dwHeadersLength, dwFlags, dwContext);
urlComponents.dwStructSize = sizeof(URL_COMPONENTSW); urlComponents.dwStructSize = sizeof(URL_COMPONENTSW);
@ -2127,7 +2147,7 @@ HINTERNET WINAPI INTERNET_InternetOpenUrlW(HINTERNET hInternet, LPCWSTR lpszUrl,
case INTERNET_SCHEME_FTP: case INTERNET_SCHEME_FTP:
if(urlComponents.nPort == 0) if(urlComponents.nPort == 0)
urlComponents.nPort = INTERNET_DEFAULT_FTP_PORT; urlComponents.nPort = INTERNET_DEFAULT_FTP_PORT;
client = FTP_Connect(hInternet, hostName, urlComponents.nPort, client = FTP_Connect(hIC, hostName, urlComponents.nPort,
userName, password, dwFlags, dwContext, INET_OPENURL); userName, password, dwFlags, dwContext, INET_OPENURL);
if(client == NULL) if(client == NULL)
break; break;
@ -2148,7 +2168,8 @@ HINTERNET WINAPI INTERNET_InternetOpenUrlW(HINTERNET hInternet, LPCWSTR lpszUrl,
else else
urlComponents.nPort = INTERNET_DEFAULT_HTTPS_PORT; urlComponents.nPort = INTERNET_DEFAULT_HTTPS_PORT;
} }
client = HTTP_Connect(hInternet, hostName, urlComponents.nPort, /* FIXME: should use pointers, not handles, as handles are not thread-safe */
client = HTTP_Connect(hIC, hostName, urlComponents.nPort,
userName, password, dwFlags, dwContext, INET_OPENURL); userName, password, dwFlags, dwContext, INET_OPENURL);
if(client == NULL) if(client == NULL)
break; break;
@ -2158,7 +2179,7 @@ HINTERNET WINAPI INTERNET_InternetOpenUrlW(HINTERNET hInternet, LPCWSTR lpszUrl,
break; break;
} }
HttpAddRequestHeadersW(client1, lpszHeaders, dwHeadersLength, HTTP_ADDREQ_FLAG_ADD); HttpAddRequestHeadersW(client1, lpszHeaders, dwHeadersLength, HTTP_ADDREQ_FLAG_ADD);
if (!HTTP_HttpSendRequestW(client1, NULL, 0, NULL, 0)) { if (!HttpSendRequestW(client1, NULL, 0, NULL, 0)) {
InternetCloseHandle(client1); InternetCloseHandle(client1);
client1 = NULL; client1 = NULL;
break; break;
@ -2204,7 +2225,7 @@ HINTERNET WINAPI InternetOpenUrlW(HINTERNET hInternet, LPCWSTR lpszUrl,
struct WORKREQ_INTERNETOPENURLW *req; struct WORKREQ_INTERNETOPENURLW *req;
workRequest.asyncall = INTERNETOPENURLW; workRequest.asyncall = INTERNETOPENURLW;
workRequest.handle = hInternet; workRequest.hdr = WININET_AddRef( &hIC->hdr );
req = &workRequest.u.InternetOpenUrlW; req = &workRequest.u.InternetOpenUrlW;
if (lpszUrl) if (lpszUrl)
req->lpszUrl = WININET_strdupW(lpszUrl); req->lpszUrl = WININET_strdupW(lpszUrl);
@ -2224,10 +2245,12 @@ HINTERNET WINAPI InternetOpenUrlW(HINTERNET hInternet, LPCWSTR lpszUrl,
*/ */
SetLastError(ERROR_IO_PENDING); SetLastError(ERROR_IO_PENDING);
} else { } else {
ret = INTERNET_InternetOpenUrlW(hInternet, lpszUrl, lpszHeaders, dwHeadersLength, dwFlags, dwContext); ret = INTERNET_InternetOpenUrlW(hIC, lpszUrl, lpszHeaders, dwHeadersLength, dwFlags, dwContext);
} }
lend: lend:
if( hIC )
WININET_Release( &hIC->hdr );
TRACE(" %p <--\n", ret); TRACE(" %p <--\n", ret);
return ret; return ret;
@ -2476,7 +2499,7 @@ lerror:
* RETURNS * RETURNS
* *
*/ */
VOID INTERNET_ExecuteWork() static VOID INTERNET_ExecuteWork()
{ {
WORKREQUEST workRequest; WORKREQUEST workRequest;
@ -2485,45 +2508,16 @@ VOID INTERNET_ExecuteWork()
if (!INTERNET_GetWorkRequest(&workRequest)) if (!INTERNET_GetWorkRequest(&workRequest))
return; return;
if (TRACE_ON(wininet)) {
static const wininet_flag_info work_request_types[] = {
#define FE(x) { x, #x }
FE(FTPPUTFILEW),
FE(FTPSETCURRENTDIRECTORYW),
FE(FTPCREATEDIRECTORYW),
FE(FTPFINDFIRSTFILEW),
FE(FTPGETCURRENTDIRECTORYW),
FE(FTPOPENFILEW),
FE(FTPGETFILEW),
FE(FTPDELETEFILEW),
FE(FTPREMOVEDIRECTORYW),
FE(FTPRENAMEFILEW),
FE(INTERNETFINDNEXTW),
FE(HTTPSENDREQUESTW),
FE(HTTPOPENREQUESTW),
FE(SENDCALLBACK),
FE(INTERNETOPENURLW)
#undef FE
};
int i;
const char *val = "Unknown";
for (i = 0; i < (sizeof(work_request_types) / sizeof(work_request_types[0])); i++) {
if (work_request_types[i].val == workRequest.asyncall) {
val = work_request_types[i].name;
break;
}
}
TRACE("Got work %d (%s)\n", workRequest.asyncall, val);
}
switch (workRequest.asyncall) switch (workRequest.asyncall)
{ {
case FTPPUTFILEW: case FTPPUTFILEW:
{ {
struct WORKREQ_FTPPUTFILEW *req = &workRequest.u.FtpPutFileW; struct WORKREQ_FTPPUTFILEW *req = &workRequest.u.FtpPutFileW;
LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest.hdr;
FTP_FtpPutFileW(workRequest.handle, req->lpszLocalFile, TRACE("FTPPUTFILEW %p\n", lpwfs);
FTP_FtpPutFileW(lpwfs, req->lpszLocalFile,
req->lpszNewRemoteFile, req->dwFlags, req->dwContext); req->lpszNewRemoteFile, req->dwFlags, req->dwContext);
HeapFree(GetProcessHeap(), 0, req->lpszLocalFile); HeapFree(GetProcessHeap(), 0, req->lpszLocalFile);
@ -2534,9 +2528,12 @@ VOID INTERNET_ExecuteWork()
case FTPSETCURRENTDIRECTORYW: case FTPSETCURRENTDIRECTORYW:
{ {
struct WORKREQ_FTPSETCURRENTDIRECTORYW *req; struct WORKREQ_FTPSETCURRENTDIRECTORYW *req;
LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest.hdr;
TRACE("FTPSETCURRENTDIRECTORYW %p\n", lpwfs);
req = &workRequest.u.FtpSetCurrentDirectoryW; req = &workRequest.u.FtpSetCurrentDirectoryW;
FTP_FtpSetCurrentDirectoryW(workRequest.handle, req->lpszDirectory); FTP_FtpSetCurrentDirectoryW(lpwfs, req->lpszDirectory);
HeapFree(GetProcessHeap(), 0, req->lpszDirectory); HeapFree(GetProcessHeap(), 0, req->lpszDirectory);
} }
break; break;
@ -2544,9 +2541,12 @@ VOID INTERNET_ExecuteWork()
case FTPCREATEDIRECTORYW: case FTPCREATEDIRECTORYW:
{ {
struct WORKREQ_FTPCREATEDIRECTORYW *req; struct WORKREQ_FTPCREATEDIRECTORYW *req;
LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest.hdr;
TRACE("FTPCREATEDIRECTORYW %p\n", lpwfs);
req = &workRequest.u.FtpCreateDirectoryW; req = &workRequest.u.FtpCreateDirectoryW;
FTP_FtpCreateDirectoryW(workRequest.handle, req->lpszDirectory); FTP_FtpCreateDirectoryW(lpwfs, req->lpszDirectory);
HeapFree(GetProcessHeap(), 0, req->lpszDirectory); HeapFree(GetProcessHeap(), 0, req->lpszDirectory);
} }
break; break;
@ -2554,9 +2554,12 @@ VOID INTERNET_ExecuteWork()
case FTPFINDFIRSTFILEW: case FTPFINDFIRSTFILEW:
{ {
struct WORKREQ_FTPFINDFIRSTFILEW *req; struct WORKREQ_FTPFINDFIRSTFILEW *req;
LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest.hdr;
TRACE("FTPFINDFIRSTFILEW %p\n", lpwfs);
req = &workRequest.u.FtpFindFirstFileW; req = &workRequest.u.FtpFindFirstFileW;
FTP_FtpFindFirstFileW(workRequest.handle, req->lpszSearchFile, FTP_FtpFindFirstFileW(lpwfs, req->lpszSearchFile,
req->lpFindFileData, req->dwFlags, req->dwContext); req->lpFindFileData, req->dwFlags, req->dwContext);
if (req->lpszSearchFile != NULL) if (req->lpszSearchFile != NULL)
HeapFree(GetProcessHeap(), 0, req->lpszSearchFile); HeapFree(GetProcessHeap(), 0, req->lpszSearchFile);
@ -2566,9 +2569,12 @@ VOID INTERNET_ExecuteWork()
case FTPGETCURRENTDIRECTORYW: case FTPGETCURRENTDIRECTORYW:
{ {
struct WORKREQ_FTPGETCURRENTDIRECTORYW *req; struct WORKREQ_FTPGETCURRENTDIRECTORYW *req;
LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest.hdr;
TRACE("FTPGETCURRENTDIRECTORYW %p\n", lpwfs);
req = &workRequest.u.FtpGetCurrentDirectoryW; req = &workRequest.u.FtpGetCurrentDirectoryW;
FTP_FtpGetCurrentDirectoryW(workRequest.handle, FTP_FtpGetCurrentDirectoryW(lpwfs,
req->lpszDirectory, req->lpdwDirectory); req->lpszDirectory, req->lpdwDirectory);
} }
break; break;
@ -2576,8 +2582,11 @@ VOID INTERNET_ExecuteWork()
case FTPOPENFILEW: case FTPOPENFILEW:
{ {
struct WORKREQ_FTPOPENFILEW *req = &workRequest.u.FtpOpenFileW; struct WORKREQ_FTPOPENFILEW *req = &workRequest.u.FtpOpenFileW;
LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest.hdr;
FTP_FtpOpenFileW(workRequest.handle, req->lpszFilename, TRACE("FTPOPENFILEW %p\n", lpwfs);
FTP_FtpOpenFileW(lpwfs, req->lpszFilename,
req->dwAccess, req->dwFlags, req->dwContext); req->dwAccess, req->dwFlags, req->dwContext);
HeapFree(GetProcessHeap(), 0, req->lpszFilename); HeapFree(GetProcessHeap(), 0, req->lpszFilename);
} }
@ -2586,8 +2595,11 @@ VOID INTERNET_ExecuteWork()
case FTPGETFILEW: case FTPGETFILEW:
{ {
struct WORKREQ_FTPGETFILEW *req = &workRequest.u.FtpGetFileW; struct WORKREQ_FTPGETFILEW *req = &workRequest.u.FtpGetFileW;
LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest.hdr;
FTP_FtpGetFileW(workRequest.handle, req->lpszRemoteFile, TRACE("FTPGETFILEW %p\n", lpwfs);
FTP_FtpGetFileW(lpwfs, req->lpszRemoteFile,
req->lpszNewFile, req->fFailIfExists, req->lpszNewFile, req->fFailIfExists,
req->dwLocalFlagsAttribute, req->dwFlags, req->dwContext); req->dwLocalFlagsAttribute, req->dwFlags, req->dwContext);
HeapFree(GetProcessHeap(), 0, req->lpszRemoteFile); HeapFree(GetProcessHeap(), 0, req->lpszRemoteFile);
@ -2598,8 +2610,11 @@ VOID INTERNET_ExecuteWork()
case FTPDELETEFILEW: case FTPDELETEFILEW:
{ {
struct WORKREQ_FTPDELETEFILEW *req = &workRequest.u.FtpDeleteFileW; struct WORKREQ_FTPDELETEFILEW *req = &workRequest.u.FtpDeleteFileW;
LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest.hdr;
FTP_FtpDeleteFileW(workRequest.handle, req->lpszFilename); TRACE("FTPDELETEFILEW %p\n", lpwfs);
FTP_FtpDeleteFileW(lpwfs, req->lpszFilename);
HeapFree(GetProcessHeap(), 0, req->lpszFilename); HeapFree(GetProcessHeap(), 0, req->lpszFilename);
} }
break; break;
@ -2607,9 +2622,12 @@ VOID INTERNET_ExecuteWork()
case FTPREMOVEDIRECTORYW: case FTPREMOVEDIRECTORYW:
{ {
struct WORKREQ_FTPREMOVEDIRECTORYW *req; struct WORKREQ_FTPREMOVEDIRECTORYW *req;
LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest.hdr;
TRACE("FTPREMOVEDIRECTORYW %p\n", lpwfs);
req = &workRequest.u.FtpRemoveDirectoryW; req = &workRequest.u.FtpRemoveDirectoryW;
FTP_FtpRemoveDirectoryW(workRequest.handle, req->lpszDirectory); FTP_FtpRemoveDirectoryW(lpwfs, req->lpszDirectory);
HeapFree(GetProcessHeap(), 0, req->lpszDirectory); HeapFree(GetProcessHeap(), 0, req->lpszDirectory);
} }
break; break;
@ -2617,8 +2635,11 @@ VOID INTERNET_ExecuteWork()
case FTPRENAMEFILEW: case FTPRENAMEFILEW:
{ {
struct WORKREQ_FTPRENAMEFILEW *req = &workRequest.u.FtpRenameFileW; struct WORKREQ_FTPRENAMEFILEW *req = &workRequest.u.FtpRenameFileW;
LPWININETFTPSESSIONW lpwfs = (LPWININETFTPSESSIONW) workRequest.hdr;
FTP_FtpRenameFileW(workRequest.handle, req->lpszSrcFile, req->lpszDestFile); TRACE("FTPRENAMEFILEW %p\n", lpwfs);
FTP_FtpRenameFileW(lpwfs, req->lpszSrcFile, req->lpszDestFile);
HeapFree(GetProcessHeap(), 0, req->lpszSrcFile); HeapFree(GetProcessHeap(), 0, req->lpszSrcFile);
HeapFree(GetProcessHeap(), 0, req->lpszDestFile); HeapFree(GetProcessHeap(), 0, req->lpszDestFile);
} }
@ -2627,17 +2648,23 @@ VOID INTERNET_ExecuteWork()
case INTERNETFINDNEXTW: case INTERNETFINDNEXTW:
{ {
struct WORKREQ_INTERNETFINDNEXTW *req; struct WORKREQ_INTERNETFINDNEXTW *req;
LPWININETFINDNEXTW lpwh = (LPWININETFINDNEXTW) workRequest.hdr;
TRACE("INTERNETFINDNEXTW %p\n", lpwh);
req = &workRequest.u.InternetFindNextW; req = &workRequest.u.InternetFindNextW;
INTERNET_FindNextFileW(workRequest.handle, req->lpFindFileData); INTERNET_FindNextFileW(lpwh, req->lpFindFileData);
} }
break; break;
case HTTPSENDREQUESTW: case HTTPSENDREQUESTW:
{ {
struct WORKREQ_HTTPSENDREQUESTW *req = &workRequest.u.HttpSendRequestW; struct WORKREQ_HTTPSENDREQUESTW *req = &workRequest.u.HttpSendRequestW;
LPWININETHTTPREQW lpwhr = (LPWININETHTTPREQW) workRequest.hdr;
HTTP_HttpSendRequestW(workRequest.handle, req->lpszHeader, TRACE("HTTPSENDREQUESTW %p\n", lpwhr);
HTTP_HttpSendRequestW(lpwhr, req->lpszHeader,
req->dwHeaderLength, req->lpOptional, req->dwOptionalLength); req->dwHeaderLength, req->lpOptional, req->dwOptionalLength);
HeapFree(GetProcessHeap(), 0, req->lpszHeader); HeapFree(GetProcessHeap(), 0, req->lpszHeader);
@ -2647,8 +2674,11 @@ VOID INTERNET_ExecuteWork()
case HTTPOPENREQUESTW: case HTTPOPENREQUESTW:
{ {
struct WORKREQ_HTTPOPENREQUESTW *req = &workRequest.u.HttpOpenRequestW; struct WORKREQ_HTTPOPENREQUESTW *req = &workRequest.u.HttpOpenRequestW;
LPWININETHTTPSESSIONW lpwhs = (LPWININETHTTPSESSIONW) workRequest.hdr;
HTTP_HttpOpenRequestW(workRequest.handle, req->lpszVerb, TRACE("HTTPOPENREQUESTW %p\n", lpwhs);
HTTP_HttpOpenRequestW(lpwhs, req->lpszVerb,
req->lpszObjectName, req->lpszVersion, req->lpszReferrer, req->lpszObjectName, req->lpszVersion, req->lpszReferrer,
req->lpszAcceptTypes, req->dwFlags, req->dwContext); req->lpszAcceptTypes, req->dwFlags, req->dwContext);
@ -2662,8 +2692,11 @@ VOID INTERNET_ExecuteWork()
case SENDCALLBACK: case SENDCALLBACK:
{ {
struct WORKREQ_SENDCALLBACK *req = &workRequest.u.SendCallback; struct WORKREQ_SENDCALLBACK *req = &workRequest.u.SendCallback;
LPWININETAPPINFOW hIC = (LPWININETAPPINFOW) workRequest.hdr;
SendAsyncCallbackInt(workRequest.handle, req->hHttpSession, TRACE("SENDCALLBACK %p\n", hIC);
SendAsyncCallbackInt(hIC, req->hdr,
req->dwContext, req->dwInternetStatus, req->lpvStatusInfo, req->dwContext, req->dwInternetStatus, req->lpvStatusInfo,
req->dwStatusInfoLength); req->dwStatusInfoLength);
} }
@ -2672,14 +2705,18 @@ VOID INTERNET_ExecuteWork()
case INTERNETOPENURLW: case INTERNETOPENURLW:
{ {
struct WORKREQ_INTERNETOPENURLW *req = &workRequest.u.InternetOpenUrlW; struct WORKREQ_INTERNETOPENURLW *req = &workRequest.u.InternetOpenUrlW;
LPWININETAPPINFOW hIC = (LPWININETAPPINFOW) workRequest.hdr;
INTERNET_InternetOpenUrlW(workRequest.handle, req->lpszUrl, TRACE("INTERNETOPENURLW %p\n", hIC);
INTERNET_InternetOpenUrlW(hIC, req->lpszUrl,
req->lpszHeaders, req->dwHeadersLength, req->dwFlags, req->dwContext); req->lpszHeaders, req->dwHeadersLength, req->dwFlags, req->dwContext);
HeapFree(GetProcessHeap(), 0, req->lpszUrl); HeapFree(GetProcessHeap(), 0, req->lpszUrl);
HeapFree(GetProcessHeap(), 0, req->lpszHeaders); HeapFree(GetProcessHeap(), 0, req->lpszHeaders);
} }
break; break;
} }
WININET_Release( workRequest.hdr );
} }
@ -2772,7 +2809,6 @@ BOOL WINAPI InternetQueryDataAvailable( HINTERNET hFile,
INT retval = -1; INT retval = -1;
char buffer[4048]; char buffer[4048];
lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hFile ); lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hFile );
if (NULL == lpwhr) if (NULL == lpwhr)
{ {
@ -2799,6 +2835,7 @@ BOOL WINAPI InternetQueryDataAvailable( HINTERNET hFile,
FIXME("unsupported file type\n"); FIXME("unsupported file type\n");
break; break;
} }
WININET_Release( &lpwhr->hdr );
TRACE("<-- %i\n",retval); TRACE("<-- %i\n",retval);
return (retval+1); return (retval+1);

View File

@ -120,15 +120,22 @@ typedef enum
#define INET_OPENURL 0x0001 #define INET_OPENURL 0x0001
#define INET_CALLBACKW 0x0002 #define INET_CALLBACKW 0x0002
typedef struct _WININETHANDLEHEADER struct _WININETHANDLEHEADER;
typedef struct _WININETHANDLEHEADER WININETHANDLEHEADER, *LPWININETHANDLEHEADER;
typedef void (*WININET_object_destructor)( LPWININETHANDLEHEADER );
struct _WININETHANDLEHEADER
{ {
WH_TYPE htype; WH_TYPE htype;
DWORD dwFlags; DWORD dwFlags;
DWORD dwContext; DWORD dwContext;
DWORD dwError; DWORD dwError;
DWORD dwInternalFlags; DWORD dwInternalFlags;
DWORD dwRefCount;
WININET_object_destructor destroy;
struct _WININETHANDLEHEADER *lpwhparent; struct _WININETHANDLEHEADER *lpwhparent;
} WININETHANDLEHEADER, *LPWININETHANDLEHEADER; };
typedef struct typedef struct
@ -333,7 +340,7 @@ struct WORKREQ_HTTPSENDREQUESTW
struct WORKREQ_SENDCALLBACK struct WORKREQ_SENDCALLBACK
{ {
HINTERNET hHttpSession; WININETHANDLEHEADER *hdr;
DWORD dwContext; DWORD dwContext;
DWORD dwInternetStatus; DWORD dwInternetStatus;
LPVOID lpvStatusInfo; LPVOID lpvStatusInfo;
@ -353,7 +360,7 @@ struct WORKREQ_INTERNETOPENURLW
typedef struct WORKREQ typedef struct WORKREQ
{ {
ASYNC_FUNC asyncall; ASYNC_FUNC asyncall;
HINTERNET handle; WININETHANDLEHEADER *hdr;
union { union {
struct WORKREQ_FTPPUTFILEW FtpPutFileW; struct WORKREQ_FTPPUTFILEW FtpPutFileW;
@ -380,17 +387,19 @@ typedef struct WORKREQ
HINTERNET WININET_AllocHandle( LPWININETHANDLEHEADER info ); HINTERNET WININET_AllocHandle( LPWININETHANDLEHEADER info );
LPWININETHANDLEHEADER WININET_GetObject( HINTERNET hinternet ); LPWININETHANDLEHEADER WININET_GetObject( HINTERNET hinternet );
LPWININETHANDLEHEADER WININET_AddRef( LPWININETHANDLEHEADER info );
BOOL WININET_Release( LPWININETHANDLEHEADER info );
BOOL WININET_FreeHandle( HINTERNET hinternet ); BOOL WININET_FreeHandle( HINTERNET hinternet );
HINTERNET WININET_FindHandle( LPWININETHANDLEHEADER info ); HINTERNET WININET_FindHandle( LPWININETHANDLEHEADER info );
time_t ConvertTimeString(LPCWSTR asctime); time_t ConvertTimeString(LPCWSTR asctime);
HINTERNET FTP_Connect(HINTERNET hInterent, LPCWSTR lpszServerName, HINTERNET FTP_Connect(LPWININETAPPINFOW hIC, LPCWSTR lpszServerName,
INTERNET_PORT nServerPort, LPCWSTR lpszUserName, INTERNET_PORT nServerPort, LPCWSTR lpszUserName,
LPCWSTR lpszPassword, DWORD dwFlags, DWORD dwContext, LPCWSTR lpszPassword, DWORD dwFlags, DWORD dwContext,
DWORD dwInternalFlags); DWORD dwInternalFlags);
HINTERNET HTTP_Connect(HINTERNET hInterent, LPCWSTR lpszServerName, HINTERNET HTTP_Connect(LPWININETAPPINFOW hIC, LPCWSTR lpszServerName,
INTERNET_PORT nServerPort, LPCWSTR lpszUserName, INTERNET_PORT nServerPort, LPCWSTR lpszUserName,
LPCWSTR lpszPassword, DWORD dwFlags, DWORD dwContext, LPCWSTR lpszPassword, DWORD dwFlags, DWORD dwContext,
DWORD dwInternalFlags); DWORD dwInternalFlags);
@ -404,41 +413,36 @@ BOOL INTERNET_AsyncCall(LPWORKREQUEST lpWorkRequest);
LPSTR INTERNET_GetResponseBuffer(); LPSTR INTERNET_GetResponseBuffer();
LPSTR INTERNET_GetNextLine(INT nSocket, LPDWORD dwLen); LPSTR INTERNET_GetNextLine(INT nSocket, LPDWORD dwLen);
BOOL FTP_CloseSessionHandle(LPWININETFTPSESSIONW lpwfs); BOOLAPI FTP_FtpPutFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszLocalFile,
BOOL FTP_CloseFindNextHandle(LPWININETFINDNEXTW lpwfn);
BOOL FTP_CloseFileTransferHandle(LPWININETFILE lpwfn);
BOOLAPI FTP_FtpPutFileW(HINTERNET hConnect, LPCWSTR lpszLocalFile,
LPCWSTR lpszNewRemoteFile, DWORD dwFlags, DWORD dwContext); LPCWSTR lpszNewRemoteFile, DWORD dwFlags, DWORD dwContext);
BOOLAPI FTP_FtpSetCurrentDirectoryW(HINTERNET hConnect, LPCWSTR lpszDirectory); BOOLAPI FTP_FtpSetCurrentDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory);
BOOLAPI FTP_FtpCreateDirectoryW(HINTERNET hConnect, LPCWSTR lpszDirectory); BOOLAPI FTP_FtpCreateDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory);
INTERNETAPI HINTERNET WINAPI FTP_FtpFindFirstFileW(HINTERNET hConnect, INTERNETAPI HINTERNET WINAPI FTP_FtpFindFirstFileW(LPWININETFTPSESSIONW lpwfs,
LPCWSTR lpszSearchFile, LPWIN32_FIND_DATAW lpFindFileData, DWORD dwFlags, DWORD dwContext); LPCWSTR lpszSearchFile, LPWIN32_FIND_DATAW lpFindFileData, DWORD dwFlags, DWORD dwContext);
BOOLAPI FTP_FtpGetCurrentDirectoryW(HINTERNET hFtpSession, LPWSTR lpszCurrentDirectory, BOOLAPI FTP_FtpGetCurrentDirectoryW(LPWININETFTPSESSIONW lpwfs, LPWSTR lpszCurrentDirectory,
LPDWORD lpdwCurrentDirectory); LPDWORD lpdwCurrentDirectory);
BOOL FTP_ConvertFileProp(LPFILEPROPERTIESW lpafp, LPWIN32_FIND_DATAW lpFindFileData); BOOL FTP_ConvertFileProp(LPFILEPROPERTIESW lpafp, LPWIN32_FIND_DATAW lpFindFileData);
BOOL FTP_FtpRenameFileW(HINTERNET hFtpSession, LPCWSTR lpszSrc, LPCWSTR lpszDest); BOOL FTP_FtpRenameFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszSrc, LPCWSTR lpszDest);
BOOL FTP_FtpRemoveDirectoryW(HINTERNET hFtpSession, LPCWSTR lpszDirectory); BOOL FTP_FtpRemoveDirectoryW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszDirectory);
BOOL FTP_FtpDeleteFileW(HINTERNET hFtpSession, LPCWSTR lpszFileName); BOOL FTP_FtpDeleteFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszFileName);
HINTERNET FTP_FtpOpenFileW(HINTERNET hFtpSession, LPCWSTR lpszFileName, HINTERNET FTP_FtpOpenFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszFileName,
DWORD fdwAccess, DWORD dwFlags, DWORD dwContext); DWORD fdwAccess, DWORD dwFlags, DWORD dwContext);
BOOLAPI FTP_FtpGetFileW(HINTERNET hInternet, LPCWSTR lpszRemoteFile, LPCWSTR lpszNewFile, BOOLAPI FTP_FtpGetFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszRemoteFile, LPCWSTR lpszNewFile,
BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags, BOOL fFailIfExists, DWORD dwLocalFlagsAttribute, DWORD dwInternetFlags,
DWORD dwContext); DWORD dwContext);
BOOLAPI HTTP_HttpSendRequestW(HINTERNET hHttpRequest, LPCWSTR lpszHeaders, BOOLAPI HTTP_HttpSendRequestW(LPWININETHTTPREQW lpwhr, LPCWSTR lpszHeaders,
DWORD dwHeaderLength, LPVOID lpOptional ,DWORD dwOptionalLength); DWORD dwHeaderLength, LPVOID lpOptional ,DWORD dwOptionalLength);
INTERNETAPI HINTERNET WINAPI HTTP_HttpOpenRequestW(HINTERNET hHttpSession, INTERNETAPI HINTERNET WINAPI HTTP_HttpOpenRequestW(LPWININETHTTPSESSIONW lpwhs,
LPCWSTR lpszVerb, LPCWSTR lpszObjectName, LPCWSTR lpszVersion, LPCWSTR lpszVerb, LPCWSTR lpszObjectName, LPCWSTR lpszVersion,
LPCWSTR lpszReferrer , LPCWSTR *lpszAcceptTypes, LPCWSTR lpszReferrer , LPCWSTR *lpszAcceptTypes,
DWORD dwFlags, DWORD dwContext); DWORD dwFlags, DWORD dwContext);
void HTTP_CloseHTTPSessionHandle(LPWININETHTTPSESSIONW lpwhs);
void HTTP_CloseHTTPRequestHandle(LPWININETHTTPREQW lpwhr);
VOID SendAsyncCallback(LPWININETAPPINFOW hIC, HINTERNET hHttpSession, VOID SendAsyncCallback(LPWININETAPPINFOW hIC, LPWININETHANDLEHEADER hdr,
DWORD dwContext, DWORD dwInternetStatus, LPVOID DWORD dwContext, DWORD dwInternetStatus, LPVOID
lpvStatusInfo , DWORD dwStatusInfoLength); lpvStatusInfo , DWORD dwStatusInfoLength);
VOID SendAsyncCallbackInt(LPWININETAPPINFOW hIC, HINTERNET hHttpSession, VOID SendAsyncCallbackInt(LPWININETAPPINFOW hIC, LPWININETHANDLEHEADER hdr,
DWORD dwContext, DWORD dwInternetStatus, LPVOID DWORD dwContext, DWORD dwInternetStatus, LPVOID
lpvStatusInfo , DWORD dwStatusInfoLength); lpvStatusInfo , DWORD dwStatusInfoLength);

View File

@ -215,12 +215,14 @@ static const char *get_callback_name(DWORD dwInternetStatus) {
return "Unknown"; return "Unknown";
} }
VOID SendAsyncCallbackInt(LPWININETAPPINFOW hIC, HINTERNET hHttpSession, VOID SendAsyncCallbackInt(LPWININETAPPINFOW hIC, LPWININETHANDLEHEADER hdr,
DWORD dwContext, DWORD dwInternetStatus, LPVOID DWORD dwContext, DWORD dwInternetStatus, LPVOID
lpvStatusInfo, DWORD dwStatusInfoLength) lpvStatusInfo, DWORD dwStatusInfoLength)
{ {
HINTERNET hHttpSession;
LPVOID lpvNewInfo = NULL; LPVOID lpvNewInfo = NULL;
if (! (hIC->lpfnStatusCB))
if( !hIC->lpfnStatusCB )
return; return;
/* the IE5 version of wininet does not /* the IE5 version of wininet does not
@ -230,6 +232,10 @@ VOID SendAsyncCallbackInt(LPWININETAPPINFOW hIC, HINTERNET hHttpSession,
TRACE("--> Callback %ld (%s)\n",dwInternetStatus, get_callback_name(dwInternetStatus)); TRACE("--> Callback %ld (%s)\n",dwInternetStatus, get_callback_name(dwInternetStatus));
hHttpSession = WININET_FindHandle( hdr );
if( !hHttpSession )
return;
lpvNewInfo = lpvStatusInfo; lpvNewInfo = lpvStatusInfo;
if(!(hIC->hdr.dwInternalFlags & INET_CALLBACKW)) { if(!(hIC->hdr.dwInternalFlags & INET_CALLBACKW)) {
switch(dwInternetStatus) switch(dwInternetStatus)
@ -245,11 +251,13 @@ VOID SendAsyncCallbackInt(LPWININETAPPINFOW hIC, HINTERNET hHttpSession,
HeapFree(GetProcessHeap(), 0, lpvNewInfo); HeapFree(GetProcessHeap(), 0, lpvNewInfo);
TRACE("<-- Callback %ld (%s)\n",dwInternetStatus, get_callback_name(dwInternetStatus)); TRACE("<-- Callback %ld (%s)\n",dwInternetStatus, get_callback_name(dwInternetStatus));
WININET_Release( hdr );
} }
VOID SendAsyncCallback(LPWININETAPPINFOW hIC, HINTERNET hHttpSession, VOID SendAsyncCallback(LPWININETAPPINFOW hIC, LPWININETHANDLEHEADER hdr,
DWORD dwContext, DWORD dwInternetStatus, LPVOID DWORD dwContext, DWORD dwInternetStatus, LPVOID
lpvStatusInfo, DWORD dwStatusInfoLength) lpvStatusInfo, DWORD dwStatusInfoLength)
{ {
@ -263,9 +271,9 @@ VOID SendAsyncCallback(LPWININETAPPINFOW hIC, HINTERNET hHttpSession,
struct WORKREQ_SENDCALLBACK *req; struct WORKREQ_SENDCALLBACK *req;
workRequest.asyncall = SENDCALLBACK; workRequest.asyncall = SENDCALLBACK;
workRequest.handle = hIC; workRequest.hdr = WININET_AddRef( &hIC->hdr );
req = &workRequest.u.SendCallback; req = &workRequest.u.SendCallback;
req->hHttpSession = hHttpSession; req->hdr = hdr;
req->dwContext = dwContext; req->dwContext = dwContext;
req->dwInternetStatus = dwInternetStatus; req->dwInternetStatus = dwInternetStatus;
req->lpvStatusInfo = lpvStatusInfo; req->lpvStatusInfo = lpvStatusInfo;
@ -274,6 +282,6 @@ VOID SendAsyncCallback(LPWININETAPPINFOW hIC, HINTERNET hHttpSession,
INTERNET_AsyncCall(&workRequest); INTERNET_AsyncCall(&workRequest);
} }
else else
SendAsyncCallbackInt(hIC, hHttpSession, dwContext, dwInternetStatus, SendAsyncCallbackInt(hIC, hdr, dwContext, dwInternetStatus,
lpvStatusInfo, dwStatusInfoLength); lpvStatusInfo, dwStatusInfoLength);
} }