Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

287 lines
6.5 KiB

/*++
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