/*++ 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); }