|
|
/*++
Copyright (c) 1994 Microsoft Corporation
Module Name:
handle.cxx
Abstract:
Contains functions to allocate and deallocate handle values
Contents: HandleInitialize HandleTerminate AllocateHandle FreeHandle MapHandleToAddress DereferenceObject
Author:
Richard L Firth (rfirth) 31-Oct-1994
Revision History:
12-Mar-2001 rajeevd Gutted
11-Jan-1996 rfirth Use fixed memory instead of moveable (Win95 has a bug w/ LocalUnlock)
31-Oct-1994 rfirth Created --*/
#include <wininetp.h>
//
// private prototypes
//
DEBUG_ONLY (PRIVATE void LogHandleClassSizes(); )
//
// functions
//
DWORD HandleInitialize (VOID) { DEBUG_ONLY (LogHandleClassSizes(); ) return ERROR_SUCCESS; }
VOID HandleTerminate(VOID) { // nothing to do
}
DWORD AllocateHandle (IN LPVOID Address,OUT LPHINTERNET lpHandle) { HINTERNET Handle = (HINTERNET) Address; *lpHandle = Handle; return ERROR_SUCCESS; }
DWORD FreeHandle(IN HINTERNET Handle) { return ERROR_SUCCESS; }
DWORD MapHandleToAddress( IN HINTERNET Handle, OUT LPVOID * lpAddress, IN BOOL Invalidate )
/*++
Routine Description:
The handle object represented by Handle is referenced
Assumes: 1. only HINTERNETs visible at the API are presented to this function. Arguments:
Handle - handle value generated by AllocateHandle()
lpAddress - place to store mapped address. If the handle has been closed and unmapped, NULL is returned. If the handle is still mapped, even though it has been invalidated, its address will be returned, and its reference count incremented
Invalidate - TRUE if we are invalidating this handle
Return Value:
LPVOID Success - ERROR_SUCCESS
Failure - ERROR_INVALID_HANDLE if *lpAddress == NULL then the handle has been closed and unmapped, else it is still mapped, but invalidated. In this case, we incremented the reference count
--*/
{ DEBUG_ENTER((DBG_HANDLE, Dword, "MapHandleToAddress", "%#x, %#x, %B", Handle, lpAddress, Invalidate ));
DWORD error;
// Cast the handle to an address and validate
LPVOID address = (LPVOID) Handle; if (address) { error = ((HANDLE_OBJECT *)address)->IsValid(TypeWildHandle); } else { error = ERROR_INVALID_HANDLE; } if (error != ERROR_SUCCESS) { DEBUG_PRINT(HANDLE, ERROR, ("invalid handle object: %#x [%#x]\n", Handle, address )); error = ERROR_INVALID_HANDLE; address = NULL; goto quit; }
// Attempt to increment the reference count on the handle.
error = ((HANDLE_OBJECT *)address)->Reference(); DEBUG_PRINT(HANDLE, ERROR, ("Reference() returns %d\n", error)); switch (error) { case ERROR_SUCCESS: // handle was refcounted but is not tombstoned
if (Invalidate) { // we were called from a handle close API.
// Subsequent API calls will discover that the
// handle is already invalidated and will quit
((HANDLE_OBJECT *)address)->Invalidate(); } break;
case ERROR_INVALID_HANDLE: // handle was refcounted but was tombstoned.
break;
default: INET_ASSERT (false);
// intentional fall through
case ERROR_ACCESS_DENIED: // handle is being destroyed
DEBUG_PRINT(HANDLE, ERROR, ("Reference() failed - handle %#x [%#x] about to be deleted\n", Handle, address )); error = ERROR_INVALID_HANDLE; address = NULL; break; }
quit: *lpAddress = address; DEBUG_LEAVE(error); return error; }
DWORD DereferenceObject( IN LPVOID lpObject )
/*++
Routine Description:
Undoes the reference added to the handle object by MapHandleToAddress(). May result in the handle object being deleted
Arguments:
lpObject - address of object to dereference. This MUST be the mapped object address as returned by MapHandleToAddress()
Return Value:
DWORD Success - ERROR_SUCCESS The handle object was destroyed
Failure - ERROR_INVALID_HANDLE The object was not a valid handle
--*/
{ DEBUG_ENTER((DBG_HANDLE, Dword, "DereferenceObject", "%#x", lpObject ));
INET_ASSERT(lpObject != NULL);
HANDLE_OBJECT * object = (HANDLE_OBJECT *)lpObject; DWORD error = object->IsValid(TypeWildHandle);
// Serialize with MapHandleToAddress
if (error == ERROR_SUCCESS) { object->Dereference(); } else { //
// IsValid() should never return an error if the reference counts
// are correct
//
INET_ASSERT(FALSE); }
DEBUG_LEAVE(error);
return error; }
#if INET_DEBUG
PRIVATE void LogHandleClassSizes() { DEBUG_PRINT(HANDLE, INFO, ("sizeof(HANDLE_OBJECT) = %d bytes\n", sizeof(HANDLE_OBJECT) )); DEBUG_PRINT(HANDLE, INFO, ("sizeof(INTERNET_HANDLE_OBJECT) = %d bytes\n", sizeof(INTERNET_HANDLE_OBJECT) )); DEBUG_PRINT(HANDLE, INFO, ("sizeof(INTERNET_CONNECT_HANDLE_OBJECT) = %d bytes\n", sizeof(INTERNET_CONNECT_HANDLE_OBJECT) )); DEBUG_PRINT(HANDLE, INFO, ("sizeof(HTTP_REQUEST_HANDLE_OBJECT) = %d bytes\n", sizeof(HTTP_REQUEST_HANDLE_OBJECT) )); } #endif
|