windows-nt/Source/XPSP1/NT/net/qos/pclass/gpc/gpcmap.c
2020-09-26 16:20:57 +08:00

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;
}