406 lines
6.4 KiB
C
406 lines
6.4 KiB
C
/*
|
|
************************************************************************
|
|
|
|
Copyright (c) 1996-1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
gpcmap.c
|
|
|
|
Abstract:
|
|
|
|
This file contains mapping routines like user handles to
|
|
kernel handles.
|
|
|
|
Author:
|
|
|
|
Ofer Bar - July 14, 1997
|
|
|
|
Environment:
|
|
|
|
Kernel mode
|
|
|
|
Revision History:
|
|
|
|
|
|
************************************************************************
|
|
*/
|
|
|
|
#include "gpcpre.h"
|
|
|
|
|
|
/*
|
|
/////////////////////////////////////////////////////////////////
|
|
//
|
|
// globals
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
*/
|
|
|
|
static MRSW_LOCK HandleLock;
|
|
static HandleFactory *pMapHandles = NULL;
|
|
|
|
/*
|
|
/////////////////////////////////////////////////////////////////
|
|
//
|
|
// prototypes
|
|
//
|
|
/////////////////////////////////////////////////////////////////
|
|
*/
|
|
|
|
|
|
|
|
HANDLE
|
|
AllocateHandle(
|
|
OUT HANDLE *OutHandle,
|
|
IN PVOID Reference
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function creates a handle.
|
|
|
|
Arguments:
|
|
|
|
OutHandle - a pointer to a location to fill in the result handle
|
|
Reference - to associate with the handle
|
|
|
|
Return Value:
|
|
|
|
The handle factory handle, or NULL in case of en error
|
|
|
|
--*/
|
|
{
|
|
HFHandle Handle;
|
|
KIRQL irql;
|
|
|
|
ASSERT(OutHandle);
|
|
|
|
TRACE(MAPHAND, Reference, OutHandle, "AllocateHandle <==");
|
|
|
|
WRITE_LOCK( &HandleLock, &irql );
|
|
|
|
*OutHandle = (HANDLE) UIntToPtr((Handle = assign_HF_handle(pMapHandles, Reference)));
|
|
|
|
WRITE_UNLOCK( &HandleLock, irql );
|
|
|
|
StatInc(InsertedHF);
|
|
|
|
TRACE(MAPHAND, Reference, Handle, "AllocateHandle ==>");
|
|
|
|
return (HANDLE) UIntToPtr(Handle);
|
|
}
|
|
|
|
|
|
VOID
|
|
FreeHandle(
|
|
IN HANDLE Handle
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function frees the handle
|
|
|
|
Arguments:
|
|
|
|
Handle -
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
int r;
|
|
KIRQL irql;
|
|
|
|
TRACE(MAPHAND, Handle, 0, "FreeHandle <==");
|
|
|
|
if (Handle) {
|
|
|
|
WRITE_LOCK( &HandleLock, &irql );
|
|
|
|
r = release_HF_handle(pMapHandles, (HFHandle)(UINT_PTR)Handle);
|
|
|
|
StatInc(RemovedHF);
|
|
|
|
//ASSERT(r == 0);
|
|
|
|
WRITE_UNLOCK( &HandleLock, irql );
|
|
}
|
|
|
|
TRACE(MAPHAND, Handle, r, "FreeHandle ==>");
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
SuspendHandle(
|
|
IN HANDLE Handle
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function suspends the handle
|
|
|
|
Arguments:
|
|
|
|
Handle -
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
int r;
|
|
KIRQL irql;
|
|
|
|
TRACE(MAPHAND, Handle, 0, "SuspendHandle <==");
|
|
|
|
if (Handle) {
|
|
|
|
WRITE_LOCK( &HandleLock, &irql );
|
|
|
|
r = suspend_HF_handle(pMapHandles, (HFHandle)(UINT_PTR)Handle);
|
|
|
|
//ASSERT(r == 0);
|
|
|
|
WRITE_UNLOCK( &HandleLock, irql );
|
|
}
|
|
|
|
TRACE(MAPHAND, Handle, r, "SuspendHandle ==>");
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID
|
|
ResumeHandle(
|
|
IN HANDLE Handle
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function resumess the handle
|
|
|
|
Arguments:
|
|
|
|
Handle -
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
int r;
|
|
KIRQL irql;
|
|
|
|
TRACE(MAPHAND, Handle, 0, "ResumeHandle <==");
|
|
|
|
if (Handle) {
|
|
|
|
WRITE_LOCK( &HandleLock, &irql );
|
|
|
|
r = reinstate_HF_handle(pMapHandles, (HFHandle)(UINT_PTR)Handle);
|
|
|
|
//ASSERT(r == 0);
|
|
|
|
WRITE_UNLOCK( &HandleLock, irql );
|
|
}
|
|
|
|
TRACE(MAPHAND, Handle, r, "ResumeHandle ==>");
|
|
}
|
|
|
|
|
|
|
|
|
|
PVOID
|
|
GetHandleObject(
|
|
IN HANDLE h,
|
|
IN GPC_ENUM_OBJECT_TYPE ObjType
|
|
)
|
|
{
|
|
GPC_ENUM_OBJECT_TYPE *p;
|
|
KIRQL irql;
|
|
|
|
TRACE(MAPHAND, h, ObjType, "GetHandleObject <==");
|
|
|
|
READ_LOCK(&HandleLock, &irql);
|
|
|
|
p = (GPC_ENUM_OBJECT_TYPE *)dereference_HF_handle(pMapHandles,
|
|
(HFHandle)(UINT_PTR)h);
|
|
|
|
if (p != NULL) {
|
|
|
|
//
|
|
// we found a reference for the handle
|
|
// we verify that it's the right object type
|
|
//
|
|
|
|
if (*p != ObjType) {
|
|
|
|
//
|
|
// sorry, wrong type
|
|
//
|
|
|
|
p = NULL;
|
|
}
|
|
|
|
}
|
|
|
|
READ_UNLOCK(&HandleLock, irql);
|
|
|
|
TRACE(MAPHAND, h, p, "GetHandleObject ==>");
|
|
|
|
return (PVOID)p;
|
|
}
|
|
|
|
|
|
|
|
|
|
PVOID
|
|
GetHandleObjectWithRef(
|
|
IN HANDLE h,
|
|
IN GPC_ENUM_OBJECT_TYPE ObjType,
|
|
IN ULONG Ref
|
|
)
|
|
{
|
|
GPC_ENUM_OBJECT_TYPE *p;
|
|
KIRQL irql;
|
|
|
|
TRACE(MAPHAND, h, ObjType, "GetHandleObjectWithRef ==>");
|
|
|
|
READ_LOCK( &HandleLock, &irql );
|
|
|
|
p = dereference_HF_handle(pMapHandles, (HFHandle)(ULONG_PTR)h);
|
|
|
|
if (p != NULL) {
|
|
|
|
//
|
|
// we found a reference for the handle
|
|
// we verify that it's the right object type
|
|
//
|
|
|
|
if (*p != ObjType) {
|
|
|
|
//
|
|
// sorry, wrong type
|
|
//
|
|
|
|
p = NULL;
|
|
}
|
|
|
|
}
|
|
|
|
if (p != NULL) {
|
|
|
|
switch (ObjType) {
|
|
|
|
case GPC_ENUM_CFINFO_TYPE:
|
|
REFADD(&((PBLOB_BLOCK)p)->RefCount, Ref);
|
|
break;
|
|
|
|
case GPC_ENUM_CLIENT_TYPE:
|
|
|
|
REFADD(&((PCLIENT_BLOCK)p)->RefCount, Ref);
|
|
break;
|
|
|
|
case GPC_ENUM_PATTERN_TYPE:
|
|
REFADD(&((PPATTERN_BLOCK)p)->RefCount, Ref);
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0);
|
|
}
|
|
}
|
|
|
|
READ_UNLOCK( &HandleLock, irql );
|
|
|
|
TRACE(MAPHAND, h, p, "GetHandleObjectWithRef <==");
|
|
|
|
return (PVOID)p;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
************************************************************************
|
|
|
|
InitMapHandles -
|
|
|
|
The initialization handle mapping table
|
|
|
|
Arguments
|
|
none
|
|
|
|
Returns
|
|
GPC_STATUS
|
|
|
|
************************************************************************
|
|
*/
|
|
GPC_STATUS
|
|
InitMapHandles(VOID)
|
|
{
|
|
GPC_STATUS Status = GPC_STATUS_SUCCESS;
|
|
|
|
TRACE(INIT, 0, 0, "InitMapping");
|
|
|
|
INIT_LOCK(&HandleLock);
|
|
|
|
NEW_HandleFactory(pMapHandles);
|
|
|
|
if (pMapHandles != NULL ) {
|
|
|
|
if (constructHandleFactory(pMapHandles)) {
|
|
|
|
FreeHandleFactory(pMapHandles);
|
|
|
|
Status = GPC_STATUS_RESOURCES;
|
|
}
|
|
|
|
} else {
|
|
|
|
Status = GPC_STATUS_RESOURCES;
|
|
}
|
|
|
|
TRACE(INIT, pMapHandles, Status, "InitMapping");
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
/*
|
|
************************************************************************
|
|
|
|
UninitMapHandles -
|
|
|
|
release handle mapping table resources
|
|
|
|
Arguments
|
|
none
|
|
|
|
Returns
|
|
void
|
|
|
|
************************************************************************
|
|
*/
|
|
VOID
|
|
UninitMapHandles(VOID)
|
|
{
|
|
GPC_STATUS Status = GPC_STATUS_SUCCESS;
|
|
|
|
TRACE(INIT, 0, 0, "UninitMapHandles");
|
|
|
|
//NdisFreeSpinLock(&HandleLock);
|
|
|
|
destructHandleFactory(pMapHandles);
|
|
|
|
FreeHandleFactory(pMapHandles);
|
|
|
|
TRACE(INIT, pMapHandles, Status, "UninitMapHandles");
|
|
|
|
return;
|
|
}
|
|
|