Jacek Caban : wininet: Keep handles invalid but reserved in InternetCloseHandle.
Alexandre Julliard
julliard at winehq.org
Thu Feb 3 12:00:22 CST 2011
Module: wine
Branch: master
Commit: 968ab5fd284b69bcc826d7cd20070112bb32e35d
URL: http://source.winehq.org/git/wine.git/?a=commit;h=968ab5fd284b69bcc826d7cd20070112bb32e35d
Author: Jacek Caban <jacek at codeweavers.com>
Date: Wed Feb 2 22:50:46 2011 +0100
wininet: Keep handles invalid but reserved in InternetCloseHandle.
---
dlls/wininet/internet.c | 80 ++++++++++++++++++++--------------------------
dlls/wininet/internet.h | 1 +
2 files changed, 36 insertions(+), 45 deletions(-)
diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c
index bdaa992..b546867 100644
--- a/dlls/wininet/internet.c
+++ b/dlls/wininet/internet.c
@@ -161,6 +161,7 @@ DWORD alloc_handle( object_header_t *info, HINTERNET *ret )
LeaveCriticalSection( &WININET_cs );
info->hInternet = *ret = (HINTERNET)handle;
+ info->valid_handle = res == ERROR_SUCCESS;
return res;
}
@@ -178,7 +179,7 @@ object_header_t *get_handle_object( HINTERNET hinternet )
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]);
LeaveCriticalSection( &WININET_cs );
@@ -188,12 +189,31 @@ object_header_t *get_handle_object( HINTERNET hinternet )
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 )
{
ULONG refs = InterlockedDecrement(&info->refs);
TRACE( "object %p refcount = %d\n", info, refs );
if( !refs )
{
+ invalidate_handle(info);
if ( info->vtbl->CloseConnection )
{
TRACE( "closing connection %p\n", info);
@@ -211,49 +231,20 @@ BOOL WININET_Release( object_header_t *info )
if ( info->htype != WH_HINIT )
list_remove( &info->entry );
info->vtbl->Destroy( info );
- }
- return TRUE;
-}
-static void invalidate_handle( HINTERNET hinternet )
-{
- UINT_PTR handle = (UINT_PTR) hinternet;
- object_header_t *info = NULL, *child, *next;
+ if(info->hInternet) {
+ UINT_PTR handle = (UINT_PTR)info->hInternet;
- 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;
- }
- }
+ if(next_handle > handle)
+ 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 );
+ LeaveCriticalSection( &WININET_cs );
}
- WININET_Release( info );
}
-
- EnterCriticalSection( &WININET_cs );
-
- if(next_handle > handle && !handle_table[handle])
- next_handle = handle;
-
- LeaveCriticalSection( &WININET_cs );
+ return TRUE;
}
/***********************************************************************
@@ -1277,19 +1268,18 @@ BOOL WINAPI InternetFindNextFileW(HINTERNET hFind, LPVOID lpvFindData)
*/
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 );
- if (NULL == lpwh)
- {
- INTERNET_SetLastError(ERROR_INVALID_HANDLE);
+ obj = get_handle_object( hInternet );
+ if (!obj) {
+ SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
- WININET_Release( lpwh );
- invalidate_handle( hInternet );
+ invalidate_handle(obj);
+ WININET_Release(obj);
return TRUE;
}
diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h
index 8239db2..d6cd1d2 100644
--- a/dlls/wininet/internet.h
+++ b/dlls/wininet/internet.h
@@ -204,6 +204,7 @@ struct _object_header_t
WH_TYPE htype;
const object_vtbl_t *vtbl;
HINTERNET hInternet;
+ BOOL valid_handle;
DWORD dwFlags;
DWORD_PTR dwContext;
DWORD dwError;
More information about the wine-cvs
mailing list