/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS WinSock 2 DLL * FILE: misc/handle.c * PURPOSE: Provider handle management * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) * REVISIONS: * CSH 01/09-2000 Created */ #include #include #include PPROVIDER_HANDLE_BLOCK ProviderHandleTable; CRITICAL_SECTION ProviderHandleTableLock; PPROVIDER_HANDLE GetProviderByHandle(PPROVIDER_HANDLE_BLOCK HandleTable, HANDLE Handle) /* * FUNCTION: Get the data structure for a handle * ARGUMENTS: * HandleTable = Pointer to handle table * Handle = Handle to get data structure for * RETURNS: * Pointer to the data structure identified by the handle on success, * NULL on failure */ { PPROVIDER_HANDLE_BLOCK Current; PLIST_ENTRY CurrentEntry; ULONG i; WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X) Handle (0x%X).\n", HandleTable, Handle)); CurrentEntry = HandleTable->Entry.Flink; while (CurrentEntry != &HandleTable->Entry) { Current = CONTAINING_RECORD(CurrentEntry, PROVIDER_HANDLE_BLOCK, Entry); for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++) { if ((Current->Handles[i].Provider != NULL) && (Current->Handles[i].Handle == Handle)) { return &Current->Handles[i]; } } CurrentEntry = CurrentEntry->Flink; } return NULL; } VOID CloseAllHandles(PPROVIDER_HANDLE_BLOCK HandleTable) { PPROVIDER_HANDLE_BLOCK Current; PLIST_ENTRY CurrentEntry; PCATALOG_ENTRY Provider; ULONG i; WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X).\n", HandleTable)); CurrentEntry = HandleTable->Entry.Flink; while (CurrentEntry != &HandleTable->Entry) { Current = CONTAINING_RECORD(CurrentEntry, PROVIDER_HANDLE_BLOCK, Entry); for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++) { Provider = Current->Handles[i].Provider; if (Provider != NULL) { DereferenceProviderByPointer(Provider); Current->Handles[i].Handle = (HANDLE)0; Current->Handles[i].Provider = NULL; } } CurrentEntry = CurrentEntry->Flink; } } VOID DeleteHandleTable(PPROVIDER_HANDLE_BLOCK HandleTable) { PPROVIDER_HANDLE_BLOCK Current; PLIST_ENTRY CurrentEntry; CloseAllHandles(HandleTable); CurrentEntry = RemoveHeadList(&HandleTable->Entry); while (CurrentEntry != &HandleTable->Entry) { Current = CONTAINING_RECORD(CurrentEntry, PROVIDER_HANDLE_BLOCK, Entry); HeapFree(GlobalHeap, 0, Current); CurrentEntry = RemoveHeadList(&HandleTable->Entry); } } PCATALOG_ENTRY DeleteProviderHandle(PPROVIDER_HANDLE_BLOCK HandleTable, HANDLE Handle) { PPROVIDER_HANDLE Entry; PCATALOG_ENTRY Provider; WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X) Handle (0x%X).\n", HandleTable, Handle)); Entry = GetProviderByHandle(HandleTable, Handle); if (!Entry) return NULL; Provider = Entry->Provider; Entry->Handle = (HANDLE)0; Entry->Provider = NULL; return Provider; } HANDLE CreateProviderHandleTable(PPROVIDER_HANDLE_BLOCK HandleTable, HANDLE Handle, PCATALOG_ENTRY Provider) { PPROVIDER_HANDLE_BLOCK NewBlock; PLIST_ENTRY CurrentEntry; ULONG i; WS_DbgPrint(MAX_TRACE, ("HandleTable (0x%X) Handle (0x%X) Provider (0x%X).\n", HandleTable, Handle, Provider)); /* Scan through the currently allocated handle blocks looking for a free slot */ CurrentEntry = HandleTable->Entry.Flink; while (CurrentEntry != &HandleTable->Entry) { PPROVIDER_HANDLE_BLOCK Block = CONTAINING_RECORD(CurrentEntry, PROVIDER_HANDLE_BLOCK, Entry); for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++) { WS_DbgPrint(MAX_TRACE, ("Considering slot %ld containing 0x%X.\n", i, Block->Handles[i].Provider)); if (Block->Handles[i].Provider == NULL) { Block->Handles[i].Handle = Handle; Block->Handles[i].Provider = Provider; return Handle; } } CurrentEntry = CurrentEntry->Flink; } /* Add a new handle block to the end of the list */ NewBlock = (PPROVIDER_HANDLE_BLOCK)HeapAlloc(GlobalHeap, 0, sizeof(PROVIDER_HANDLE_BLOCK)); WS_DbgPrint(MID_TRACE,("using table entry %x\n", NewBlock)); if (!NewBlock) return (HANDLE)0; ZeroMemory(NewBlock, sizeof(PROVIDER_HANDLE_BLOCK)); InsertTailList(&HandleTable->Entry, &NewBlock->Entry); NewBlock->Handles[0].Handle = Handle; NewBlock->Handles[0].Provider = Provider; return Handle; } HANDLE CreateProviderHandle(HANDLE Handle, PCATALOG_ENTRY Provider) { HANDLE h; EnterCriticalSection(&ProviderHandleTableLock); h = CreateProviderHandleTable(ProviderHandleTable, Handle, Provider); LeaveCriticalSection(&ProviderHandleTableLock); if (h != NULL) ReferenceProviderByPointer(Provider); return h; } BOOL ReferenceProviderByHandle(HANDLE Handle, PCATALOG_ENTRY* Provider) /* * FUNCTION: Increments the reference count for a provider and returns a pointer to it * ARGUMENTS: * Handle = Handle for the provider * Provider = Address of buffer to place pointer to provider * RETURNS: * TRUE if handle was valid, FALSE if not */ { PPROVIDER_HANDLE ProviderHandle; WS_DbgPrint(MID_TRACE, ("Handle (0x%X) Provider (0x%X).\n", Handle, Provider)); EnterCriticalSection(&ProviderHandleTableLock); ProviderHandle = GetProviderByHandle(ProviderHandleTable, Handle); WS_DbgPrint(MID_TRACE, ("ProviderHandle is %x\n", ProviderHandle)); LeaveCriticalSection(&ProviderHandleTableLock); if (ProviderHandle) { ReferenceProviderByPointer(ProviderHandle->Provider); *Provider = ProviderHandle->Provider; } return (ProviderHandle != NULL); } BOOL CloseProviderHandle(HANDLE Handle) { PCATALOG_ENTRY Provider; WS_DbgPrint(MAX_TRACE, ("Handle (0x%X).\n", Handle)); EnterCriticalSection(&ProviderHandleTableLock); Provider = DeleteProviderHandle(ProviderHandleTable, Handle); if (!Provider) return FALSE; LeaveCriticalSection(&ProviderHandleTableLock); DereferenceProviderByPointer(Provider); return TRUE; } BOOL InitProviderHandleTable(VOID) { ProviderHandleTable = (PPROVIDER_HANDLE_BLOCK)HeapAlloc(GlobalHeap, 0, sizeof(PROVIDER_HANDLE_BLOCK)); if (!ProviderHandleTable) return FALSE; WS_DbgPrint(MID_TRACE,("Called\n")); ZeroMemory(ProviderHandleTable, sizeof(PROVIDER_HANDLE_BLOCK)); InitializeListHead(&ProviderHandleTable->Entry); InitializeCriticalSection(&ProviderHandleTableLock); return TRUE; } VOID FreeProviderHandleTable(VOID) { DeleteHandleTable(ProviderHandleTable); DeleteCriticalSection(&ProviderHandleTableLock); } /* EOF */