reactos/reactos/lib/ws2_32/misc/handle.c

278 lines
6.4 KiB
C
Raw Normal View History

/*
* 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 <ws2_32.h>
#include <handle.h>
#include <catalog.h>
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));
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(MAX_TRACE, ("Handle (0x%X) Provider (0x%X).\n", Handle, Provider));
EnterCriticalSection(&ProviderHandleTableLock);
ProviderHandle = GetProviderByHandle(ProviderHandleTable, Handle);
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;
ZeroMemory(ProviderHandleTable, sizeof(PROVIDER_HANDLE_BLOCK));
InitializeListHead(&ProviderHandleTable->Entry);
InitializeCriticalSection(&ProviderHandleTableLock);
return TRUE;
}
VOID
FreeProviderHandleTable(VOID)
{
DeleteHandleTable(ProviderHandleTable);
DeleteCriticalSection(&ProviderHandleTableLock);
}
/* EOF */