Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

498 lines
14 KiB

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
shandle.c
Abstract:
This module contains the semaphore handle primitives shared by
the OS/2 Client and Server.
Author:
Steve Wood (stevewo) 07-Nov-1989
Revision History:
--*/
#include "os2ssrtl.h"
CCHAR ByteLog2Table[256] = {
1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, // 00
4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 10
5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 20
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 30
6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 40
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 50
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 60
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 70
7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 80
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 90
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // A0
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // B0
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // C0
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // D0
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // E0
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}; // F0
ULONG
RtlLog2(
IN ULONG Value
)
{
if (Value & 0xFF000000) {
return( 24 + ByteLog2Table[ Value >> 24 ] );
}
else
if (Value & 0x00FF0000) {
return( 16 + ByteLog2Table[ Value >> 16 ] );
}
else
if (Value & 0x0000FF00) {
return( 8 + ByteLog2Table[ Value >> 8 ] );
}
else {
return( ByteLog2Table[ Value ] );
}
}
POR2_HANDLE_TABLE
Or2CreateHandleTable(
IN PVOID Heap,
IN ULONG SizeOfEntry,
IN ULONG CountFixedEntries
)
{
POR2_HANDLE_TABLE HandleTable;
ULONG LogSizeOfEntry;
PVOID HandleEntries;
NTSTATUS Status;
LogSizeOfEntry = RtlLog2( (UCHAR)SizeOfEntry );
SizeOfEntry = 1 << LogSizeOfEntry;
HandleTable = RtlAllocateHeap( Heap, 0,
sizeof( *HandleTable ) +
(CountFixedEntries * SizeOfEntry)
);
if (HandleTable == NULL) {
return( NULL );
}
HandleEntries = (PVOID)(HandleTable+1);
if (CountFixedEntries != 0) {
RtlZeroMemory( HandleEntries, CountFixedEntries * SizeOfEntry );
}
Status = RtlInitializeCriticalSection( &HandleTable->Lock );
ASSERT( NT_SUCCESS( Status ) );
if (!NT_SUCCESS( Status )) {
RtlFreeHeap( Heap, 0,
HandleTable
);
return( NULL );
}
HandleTable->Length = sizeof( *HandleTable );
HandleTable->Heap = Heap;
HandleTable->LogEntrySize = LogSizeOfEntry;
HandleTable->CountEntries = CountFixedEntries;
HandleTable->CountFixedEntries = CountFixedEntries;
HandleTable->CountFreeEntries = CountFixedEntries;
HandleTable->FixedEntries = HandleEntries;
HandleTable->Entries = 0;
return( HandleTable );
}
BOOLEAN
Or2DestroyHandleTable(
IN POR2_HANDLE_TABLE HandleTable,
IN OR2_DESTROY_HANDLE_ROUTINE DestroyHandleProcedure
)
{
PULONG HandleTableEntry;
ULONG SizeOfEntry;
ULONG CurrentHandle;
SizeOfEntry = 1 << HandleTable->LogEntrySize;
CurrentHandle = 0;
HandleTableEntry = HandleTable->FixedEntries;
while (CurrentHandle < HandleTable->CountFixedEntries) {
if (*HandleTableEntry) {
(*DestroyHandleProcedure)( HandleTableEntry, CurrentHandle );
}
HandleTableEntry = (PVOID)((PCH)HandleTableEntry + SizeOfEntry);
CurrentHandle++;
}
if ((HandleTableEntry = HandleTable->Entries) != NULL) {
while (CurrentHandle < HandleTable->CountEntries) {
if (*HandleTableEntry) {
(*DestroyHandleProcedure)( HandleTableEntry, CurrentHandle );
}
HandleTableEntry = (PVOID)((PCH)HandleTableEntry + SizeOfEntry);
CurrentHandle++;
}
RtlFreeHeap( HandleTable->Heap, 0,
HandleTable->Entries
);
}
RtlDeleteCriticalSection( &HandleTable->Lock );
RtlFreeHeap( HandleTable->Heap, 0,
HandleTable
);
return( TRUE );
}
BOOLEAN
Or2CreateHandle(
IN POR2_HANDLE_TABLE HandleTable,
IN OUT PULONG Handle,
IN PVOID Value
)
{
PVOID HandleEntries;
PULONG HandleTableEntry;
ULONG NewHandle;
ULONG CountOldEntries;
ULONG CountNewEntries;
ULONG SizeOfEntry;
ULONG cbOldEntries;
ULONG cbNewEntries;
BOOLEAN Result;
NewHandle = *Handle;
AcquireHandleTableLock( HandleTable );
SizeOfEntry = 1 << HandleTable->LogEntrySize;
if ((NewHandle == -1 && HandleTable->CountFreeEntries == 0) ||
(NewHandle != -1 && NewHandle >= HandleTable->CountEntries)
) {
CountOldEntries = HandleTable->CountEntries -
HandleTable->CountFixedEntries;
if (NewHandle == -1) {
NewHandle = HandleTable->CountEntries;
if (CountOldEntries) {
CountNewEntries = CountOldEntries << 1;
}
else {
CountNewEntries = 16;
}
}
else {
CountNewEntries = NewHandle -
HandleTable->CountFixedEntries + 1;
}
cbNewEntries = CountNewEntries << HandleTable->LogEntrySize;
cbOldEntries = CountOldEntries << HandleTable->LogEntrySize;
HandleEntries = RtlAllocateHeap( HandleTable->Heap, 0,
cbNewEntries
);
if (HandleEntries == NULL) {
ReleaseHandleTableLock( HandleTable );
return( FALSE );
}
RtlZeroMemory( (PCH)HandleEntries + cbOldEntries,
cbNewEntries - cbOldEntries
);
if (cbOldEntries) {
RtlMoveMemory( HandleEntries,
HandleTable->Entries,
cbOldEntries
);
RtlFreeHeap( HandleTable->Heap, 0,
HandleTable->Entries
);
}
HandleTable->Entries = HandleEntries;
HandleTable->CountEntries =
CountNewEntries + HandleTable->CountFixedEntries;
HandleTable->CountFreeEntries += CountNewEntries -
CountOldEntries;
HandleTableEntry = (PVOID)((PCH)HandleEntries +
((NewHandle - HandleTable->CountFixedEntries)
<< HandleTable->LogEntrySize) );
}
else {
if (NewHandle == -1) {
NewHandle = 0;
HandleTableEntry = HandleTable->FixedEntries;
while (NewHandle < HandleTable->CountFixedEntries) {
if (*(PULONG)HandleTableEntry == 0) {
break;
}
else {
HandleTableEntry = (PVOID)((PCH)HandleTableEntry + SizeOfEntry);
NewHandle++;
}
}
if (NewHandle == HandleTable->CountFixedEntries) {
HandleTableEntry = HandleTable->Entries;
while (NewHandle < HandleTable->CountEntries) {
if (*(PULONG)HandleTableEntry == 0) {
break;
}
else {
HandleTableEntry = (PVOID)((PCH)HandleTableEntry + SizeOfEntry);
NewHandle++;
}
}
}
}
else {
if (NewHandle < HandleTable->CountFixedEntries) {
HandleTableEntry =
(PVOID)((PCH)HandleTable->FixedEntries +
(SizeOfEntry * NewHandle)
);
}
else
if (NewHandle < HandleTable->CountEntries) {
HandleTableEntry =
(PVOID)((PCH)HandleTable->Entries +
(SizeOfEntry * (NewHandle -
HandleTable->CountFixedEntries
)
)
);
}
else {
HandleTableEntry = NULL;
}
}
}
if (HandleTableEntry != NULL && *(PULONG)HandleTableEntry == 0) {
if (*Handle != -1 && *Handle != NewHandle) {
Result = FALSE;
}
else {
RtlMoveMemory( HandleTableEntry, Value, SizeOfEntry );
HandleTable->CountFreeEntries -= 1;
*Handle = NewHandle;
Result = TRUE;
}
}
else {
Result = FALSE;
}
ReleaseHandleTableLock( HandleTable );
return( Result );
}
PVOID
Or2MapHandle(
IN POR2_HANDLE_TABLE HandleTable,
IN ULONG Handle,
IN BOOLEAN TableLocked
)
{
PVOID HandleTableEntry;
if (!TableLocked) {
AcquireHandleTableLock( HandleTable );
}
if (Handle < HandleTable->CountFixedEntries) {
HandleTableEntry = (PVOID)((PCH)HandleTable->FixedEntries +
(Handle << HandleTable->LogEntrySize));
}
else
if (Handle < HandleTable->CountEntries) {
Handle -= HandleTable->CountFixedEntries;
HandleTableEntry = (PVOID)((PCH)HandleTable->Entries +
(Handle << HandleTable->LogEntrySize)
);
}
else {
if (!TableLocked) {
ReleaseHandleTableLock( HandleTable );
}
HandleTableEntry = NULL;
}
return( HandleTableEntry );
}
BOOLEAN
Or2DestroyHandle(
IN POR2_HANDLE_TABLE HandleTable,
IN ULONG Handle
)
{
BOOLEAN Result;
PULONG HandleTableEntry;
if (Handle < HandleTable->CountFixedEntries) {
HandleTableEntry = (PULONG)((PCH)HandleTable->FixedEntries +
(Handle << HandleTable->LogEntrySize));
}
else
if (Handle < HandleTable->CountEntries) {
Handle -= HandleTable->CountFixedEntries;
HandleTableEntry = (PULONG)((PCH)HandleTable->Entries +
(Handle << HandleTable->LogEntrySize)
);
}
else {
HandleTableEntry = NULL;
}
if (HandleTableEntry != NULL) {
RtlZeroMemory( HandleTableEntry,
1 << HandleTable->LogEntrySize
);
HandleTable->CountFreeEntries++;
Result = TRUE;
}
else {
Result = FALSE;
}
ReleaseHandleTableLock( HandleTable );
return( Result );
}
BOOLEAN
Or2EnumHandleTable(
IN POR2_HANDLE_TABLE HandleTable,
IN OR2_ENUMERATE_HANDLE_ROUTINE EnumHandleProcedure,
IN PVOID EnumParameter,
OUT PULONG Handle OPTIONAL
)
{
PULONG HandleTableEntry;
ULONG SizeOfEntry;
ULONG CurrentHandle;
BOOLEAN Result;
AcquireHandleTableLock( HandleTable );
Result = FALSE;
SizeOfEntry = 1 << HandleTable->LogEntrySize;
CurrentHandle = 0;
HandleTableEntry = HandleTable->FixedEntries;
while (CurrentHandle < HandleTable->CountFixedEntries) {
if ((*EnumHandleProcedure)( HandleTableEntry,
EnumParameter ? EnumParameter :
(PVOID)CurrentHandle
)
) {
if (ARGUMENT_PRESENT( Handle )) {
*Handle = CurrentHandle;
}
Result = TRUE;
break;
}
else {
HandleTableEntry = (PVOID)((PCH)HandleTableEntry + SizeOfEntry);
CurrentHandle++;
}
}
if (!Result && CurrentHandle == HandleTable->CountFixedEntries) {
HandleTableEntry = HandleTable->Entries;
while (CurrentHandle < HandleTable->CountEntries) {
if ((*EnumHandleProcedure)( HandleTableEntry,
EnumParameter ? EnumParameter :
(PVOID)CurrentHandle
)
) {
if (ARGUMENT_PRESENT( Handle )) {
*Handle = CurrentHandle;
}
Result = TRUE;
break;
}
else {
HandleTableEntry = (PVOID)((PCH)HandleTableEntry + SizeOfEntry);
CurrentHandle++;
}
}
}
ReleaseHandleTableLock( HandleTable );
return( Result );
}
#if DBG
ULONG
Or2DumpHandleTable(
IN POR2_HANDLE_TABLE HandleTable,
IN OR2_DUMP_HANDLE_ROUTINE DumpHandleProcedure,
IN PVOID DumpParameter
)
{
PULONG HandleTableEntry;
ULONG SizeOfEntry;
ULONG CurrentHandle;
ULONG NumberOfHandles = 0;
SizeOfEntry = 1 << HandleTable->LogEntrySize;
CurrentHandle = 0;
HandleTableEntry = HandleTable->FixedEntries;
while (CurrentHandle < HandleTable->CountFixedEntries) {
if (*HandleTableEntry) {
(*DumpHandleProcedure)( HandleTableEntry,
CurrentHandle,
DumpParameter
);
NumberOfHandles++;
}
HandleTableEntry = (PVOID)((PCH)HandleTableEntry + SizeOfEntry);
CurrentHandle++;
}
if ((HandleTableEntry = HandleTable->Entries) != NULL) {
while (CurrentHandle < HandleTable->CountEntries) {
if (*HandleTableEntry) {
(*DumpHandleProcedure)( HandleTableEntry,
CurrentHandle,
DumpParameter
);
NumberOfHandles++;
}
HandleTableEntry = (PVOID)((PCH)HandleTableEntry + SizeOfEntry);
CurrentHandle++;
}
}
return( NumberOfHandles );
}
#endif // DBG