wininet: Keep handles invalid but reserved in InternetCloseHandle.
This commit is contained in:
parent
f165e25e59
commit
968ab5fd28
@ -161,6 +161,7 @@ DWORD alloc_handle( object_header_t *info, HINTERNET *ret )
|
|||||||
LeaveCriticalSection( &WININET_cs );
|
LeaveCriticalSection( &WININET_cs );
|
||||||
|
|
||||||
info->hInternet = *ret = (HINTERNET)handle;
|
info->hInternet = *ret = (HINTERNET)handle;
|
||||||
|
info->valid_handle = res == ERROR_SUCCESS;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,7 +179,7 @@ object_header_t *get_handle_object( HINTERNET hinternet )
|
|||||||
|
|
||||||
EnterCriticalSection( &WININET_cs );
|
EnterCriticalSection( &WININET_cs );
|
||||||
|
|
||||||
if(handle > 0 && handle < handle_table_size && handle_table[handle])
|
if(handle > 0 && handle < handle_table_size && handle_table[handle] && handle_table[handle]->valid_handle)
|
||||||
info = WININET_AddRef(handle_table[handle]);
|
info = WININET_AddRef(handle_table[handle]);
|
||||||
|
|
||||||
LeaveCriticalSection( &WININET_cs );
|
LeaveCriticalSection( &WININET_cs );
|
||||||
@ -188,12 +189,31 @@ object_header_t *get_handle_object( HINTERNET hinternet )
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void invalidate_handle(object_header_t *info)
|
||||||
|
{
|
||||||
|
object_header_t *child, *next;
|
||||||
|
|
||||||
|
if(!info->valid_handle)
|
||||||
|
return;
|
||||||
|
info->valid_handle = FALSE;
|
||||||
|
|
||||||
|
/* Free all children as native does */
|
||||||
|
LIST_FOR_EACH_ENTRY_SAFE( child, next, &info->children, object_header_t, entry )
|
||||||
|
{
|
||||||
|
TRACE("invalidating child handle %p for parent %p\n", child->hInternet, info);
|
||||||
|
invalidate_handle( child );
|
||||||
|
}
|
||||||
|
|
||||||
|
WININET_Release(info);
|
||||||
|
}
|
||||||
|
|
||||||
BOOL WININET_Release( object_header_t *info )
|
BOOL WININET_Release( object_header_t *info )
|
||||||
{
|
{
|
||||||
ULONG refs = InterlockedDecrement(&info->refs);
|
ULONG refs = InterlockedDecrement(&info->refs);
|
||||||
TRACE( "object %p refcount = %d\n", info, refs );
|
TRACE( "object %p refcount = %d\n", info, refs );
|
||||||
if( !refs )
|
if( !refs )
|
||||||
{
|
{
|
||||||
|
invalidate_handle(info);
|
||||||
if ( info->vtbl->CloseConnection )
|
if ( info->vtbl->CloseConnection )
|
||||||
{
|
{
|
||||||
TRACE( "closing connection %p\n", info);
|
TRACE( "closing connection %p\n", info);
|
||||||
@ -211,50 +231,21 @@ BOOL WININET_Release( object_header_t *info )
|
|||||||
if ( info->htype != WH_HINIT )
|
if ( info->htype != WH_HINIT )
|
||||||
list_remove( &info->entry );
|
list_remove( &info->entry );
|
||||||
info->vtbl->Destroy( info );
|
info->vtbl->Destroy( info );
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void invalidate_handle( HINTERNET hinternet )
|
if(info->hInternet) {
|
||||||
{
|
UINT_PTR handle = (UINT_PTR)info->hInternet;
|
||||||
UINT_PTR handle = (UINT_PTR) hinternet;
|
|
||||||
object_header_t *info = NULL, *child, *next;
|
|
||||||
|
|
||||||
EnterCriticalSection( &WININET_cs );
|
EnterCriticalSection( &WININET_cs );
|
||||||
|
|
||||||
if(handle && handle < handle_table_size)
|
|
||||||
{
|
|
||||||
if(handle_table[handle]) {
|
|
||||||
info = handle_table[handle];
|
|
||||||
TRACE( "destroying handle %ld for object %p\n", handle+1, info);
|
|
||||||
handle_table[handle] = NULL;
|
handle_table[handle] = NULL;
|
||||||
}
|
if(next_handle > handle)
|
||||||
}
|
|
||||||
|
|
||||||
LeaveCriticalSection( &WININET_cs );
|
|
||||||
|
|
||||||
/* As on native when the equivalent of WININET_Release is called, the handle
|
|
||||||
* is already invalid, but if a new handle is created at this time it does
|
|
||||||
* not yet get assigned the freed handle number */
|
|
||||||
if( info )
|
|
||||||
{
|
|
||||||
/* Free all children as native does */
|
|
||||||
LIST_FOR_EACH_ENTRY_SAFE( child, next, &info->children, object_header_t, entry )
|
|
||||||
{
|
|
||||||
TRACE( "freeing child handle %ld for parent handle %ld\n",
|
|
||||||
(UINT_PTR)child->hInternet, handle+1);
|
|
||||||
invalidate_handle( child->hInternet );
|
|
||||||
}
|
|
||||||
WININET_Release( info );
|
|
||||||
}
|
|
||||||
|
|
||||||
EnterCriticalSection( &WININET_cs );
|
|
||||||
|
|
||||||
if(next_handle > handle && !handle_table[handle])
|
|
||||||
next_handle = handle;
|
next_handle = handle;
|
||||||
|
|
||||||
LeaveCriticalSection( &WININET_cs );
|
LeaveCriticalSection( &WININET_cs );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* DllMain [Internal] Initializes the internal 'WININET.DLL'.
|
* DllMain [Internal] Initializes the internal 'WININET.DLL'.
|
||||||
@ -1277,19 +1268,18 @@ BOOL WINAPI InternetFindNextFileW(HINTERNET hFind, LPVOID lpvFindData)
|
|||||||
*/
|
*/
|
||||||
BOOL WINAPI InternetCloseHandle(HINTERNET hInternet)
|
BOOL WINAPI InternetCloseHandle(HINTERNET hInternet)
|
||||||
{
|
{
|
||||||
object_header_t *lpwh;
|
object_header_t *obj;
|
||||||
|
|
||||||
TRACE("%p\n", hInternet);
|
TRACE("%p\n", hInternet);
|
||||||
|
|
||||||
lpwh = get_handle_object( hInternet );
|
obj = get_handle_object( hInternet );
|
||||||
if (NULL == lpwh)
|
if (!obj) {
|
||||||
{
|
SetLastError(ERROR_INVALID_HANDLE);
|
||||||
INTERNET_SetLastError(ERROR_INVALID_HANDLE);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
WININET_Release( lpwh );
|
invalidate_handle(obj);
|
||||||
invalidate_handle( hInternet );
|
WININET_Release(obj);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -204,6 +204,7 @@ struct _object_header_t
|
|||||||
WH_TYPE htype;
|
WH_TYPE htype;
|
||||||
const object_vtbl_t *vtbl;
|
const object_vtbl_t *vtbl;
|
||||||
HINTERNET hInternet;
|
HINTERNET hInternet;
|
||||||
|
BOOL valid_handle;
|
||||||
DWORD dwFlags;
|
DWORD dwFlags;
|
||||||
DWORD_PTR dwContext;
|
DWORD_PTR dwContext;
|
||||||
DWORD dwError;
|
DWORD dwError;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user