mirror of
https://github.com/reactos/reactos.git
synced 2024-10-31 20:02:55 +00:00
4f0b8d3db0
svn path=/branches/ntvdm/; revision=59241
297 lines
7.6 KiB
C
297 lines
7.6 KiB
C
/*
|
|
* 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"
|
|
|
|
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 */
|