304 lines
5.6 KiB
C
304 lines
5.6 KiB
C
/*++
|
|
Copyright (c) 1992-1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
rsvphndls.c
|
|
|
|
Abstract:
|
|
|
|
This file contains the code to create and release handles
|
|
|
|
Author:
|
|
|
|
Jim Stewart (JStew) June 10, 1996
|
|
|
|
Environment:
|
|
|
|
|
|
Revision History:
|
|
|
|
Ofer Bar (oferbar) Oct 1, 1997 - Revision II
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
|
|
PVOID
|
|
GetHandleObject(
|
|
IN HANDLE h,
|
|
IN ENUM_OBJECT_TYPE ObjType
|
|
)
|
|
{
|
|
ENUM_OBJECT_TYPE *p;
|
|
|
|
GetLock(pGlobals->Lock);
|
|
p = (ENUM_OBJECT_TYPE *)dereference_HF_handle(pGlobals->pHandleTbl,
|
|
PtrToUlong(h));
|
|
|
|
if (p != NULL) {
|
|
|
|
//
|
|
// we found a reference for the handle
|
|
// we verify that it's the right object type
|
|
//
|
|
|
|
if ((*p & ObjType) == 0) {
|
|
|
|
//
|
|
// sorry, wrong type
|
|
//
|
|
|
|
p = NULL;
|
|
}
|
|
} else {
|
|
|
|
IF_DEBUG(HANDLES) {
|
|
WSPRINT(("The handle (%x) is invalid\n", h));
|
|
DEBUGBREAK();
|
|
}
|
|
|
|
}
|
|
|
|
FreeLock(pGlobals->Lock);
|
|
|
|
return (PVOID)p;
|
|
|
|
}
|
|
|
|
|
|
PVOID
|
|
GetHandleObjectWithRef(
|
|
IN HANDLE h,
|
|
IN ENUM_OBJECT_TYPE ObjType,
|
|
IN ULONG RefType
|
|
)
|
|
{
|
|
ENUM_OBJECT_TYPE *p, *p1;
|
|
PCLIENT_STRUC pClient;
|
|
PFILTER_STRUC pFilter;
|
|
PFLOW_STRUC pFlow;
|
|
PINTERFACE_STRUC pInterface;
|
|
|
|
GetLock(pGlobals->Lock);
|
|
|
|
p = (ENUM_OBJECT_TYPE *) dereference_HF_handle(pGlobals->pHandleTbl,
|
|
PtrToUlong(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) {
|
|
|
|
p1 = p;
|
|
|
|
switch (ObjType) {
|
|
|
|
case ENUM_CLIENT_TYPE:
|
|
|
|
pClient = (PCLIENT_STRUC)p;
|
|
|
|
GetLock(pClient->Lock);
|
|
if (QUERY_STATE(pClient->State) == OPEN) {
|
|
REFADD(&pClient->RefCount, RefType);
|
|
} else {
|
|
p = NULL; // we can deref a struct that is not open for business
|
|
}
|
|
FreeLock(pClient->Lock);
|
|
|
|
break;
|
|
|
|
case ENUM_FILTER_TYPE:
|
|
|
|
pFilter = (PFILTER_STRUC)p;
|
|
|
|
GetLock(pFilter->Lock);
|
|
if (QUERY_STATE(pFilter->State) == OPEN) {
|
|
REFADD(&pFilter->RefCount, RefType);
|
|
} else {
|
|
p = NULL;
|
|
}
|
|
FreeLock(pFilter->Lock);
|
|
|
|
break;
|
|
|
|
case ENUM_INTERFACE_TYPE:
|
|
|
|
pInterface = (PINTERFACE_STRUC)p;
|
|
|
|
GetLock(pInterface->Lock);
|
|
if (QUERY_STATE(pInterface->State) == OPEN) {
|
|
REFADD(&pInterface->RefCount, RefType);
|
|
} else {
|
|
p = NULL;
|
|
}
|
|
FreeLock(pInterface->Lock);
|
|
|
|
break;
|
|
|
|
case ENUM_GEN_FLOW_TYPE:
|
|
|
|
pFlow = (PFLOW_STRUC)p;
|
|
|
|
GetLock(pFlow->Lock);
|
|
|
|
// Return a HANDLE only if it is in OPEN state
|
|
// Otherwise return INVALID_HANDLE_VALUE so the
|
|
// caller will know that the Flow is not in the
|
|
// correct state
|
|
if (QUERY_STATE(pFlow->State) == OPEN)
|
|
{
|
|
REFADD(&pFlow->RefCount, RefType);
|
|
} else
|
|
{
|
|
p = INVALID_HANDLE_VALUE;
|
|
}
|
|
FreeLock(pFlow->Lock);
|
|
|
|
break;
|
|
|
|
case ENUM_CLASS_MAP_FLOW_TYPE:
|
|
|
|
pFlow = (PFLOW_STRUC)p;
|
|
|
|
GetLock(pFlow->Lock);
|
|
if (QUERY_STATE(pFlow->State) == OPEN) {
|
|
REFADD(&pFlow->RefCount, RefType);
|
|
} else {
|
|
p = NULL;
|
|
}
|
|
FreeLock(pFlow->Lock);
|
|
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0);
|
|
|
|
}
|
|
|
|
|
|
//
|
|
// random debug code - please delete
|
|
//
|
|
IF_DEBUG(HANDLES) {
|
|
if (p1 != p) {
|
|
WSPRINT(("The object being derefed is NOT in OPEN state p1=%x and p=%x\n", p1, p));
|
|
DEBUGBREAK();
|
|
}
|
|
}
|
|
|
|
} else {
|
|
|
|
IF_DEBUG(HANDLES) {
|
|
WSPRINT(("The handle (%x) is invalid\n", h));
|
|
DEBUGBREAK();
|
|
}
|
|
|
|
}
|
|
|
|
FreeLock(pGlobals->Lock);
|
|
|
|
return (PVOID)p;
|
|
}
|
|
|
|
|
|
HANDLE
|
|
AllocateHandle(
|
|
IN PVOID Context
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function creates a handle.
|
|
|
|
Arguments:
|
|
|
|
Context - the context value to store with the handle
|
|
|
|
Return Value:
|
|
|
|
The handle factory handle, or NULL in case of en error
|
|
|
|
--*/
|
|
{
|
|
HFHandle Handle;
|
|
PVOID VerifyCtx;
|
|
|
|
GetLock( pGlobals->Lock );
|
|
|
|
Handle = assign_HF_handle(pGlobals->pHandleTbl, Context);
|
|
|
|
//
|
|
// verify the handle is valid
|
|
//
|
|
|
|
VerifyCtx = dereference_HF_handle(pGlobals->pHandleTbl, Handle);
|
|
ASSERT(VerifyCtx == Context);
|
|
|
|
IF_DEBUG(HANDLES) {
|
|
WSPRINT(("AllocHandle: (%x) being allocated\n", Handle ));
|
|
}
|
|
|
|
FreeLock(pGlobals->Lock);
|
|
|
|
return UlongToPtr(Handle);
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
FreeHandle(
|
|
IN HANDLE Handle
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function frees the handle
|
|
|
|
Arguments:
|
|
|
|
Handle -
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
int r;
|
|
|
|
GetLock( pGlobals->Lock );
|
|
|
|
IF_DEBUG(HANDLES) {
|
|
WSPRINT(("FreeHandle (%x) being freed\n", PtrToUlong(Handle) ));
|
|
}
|
|
|
|
r = release_HF_handle(pGlobals->pHandleTbl, PtrToUlong(Handle));
|
|
|
|
ASSERT(r == 0);
|
|
|
|
FreeLock(pGlobals->Lock);
|
|
}
|
|
|
|
|
|
|
|
|