Implemented handle table and atom table

svn path=/trunk/; revision=1923
This commit is contained in:
Eric Kohl 2001-05-26 16:52:31 +00:00
parent 4c125c3021
commit f9384f3cf8
10 changed files with 1112 additions and 45 deletions

View file

@ -42,7 +42,7 @@ DEVICE_DRIVERS = vidport vga blue ide null floppy
#INPUT_DRIVERS = keyboard
INPUT_DRIVERS = keyboard mouclass psaux
#FS_DRIVERS = vfat minix ms np ext2 template
#FS_DRIVERS = vfat minix ext2 template
FS_DRIVERS = vfat ms np
#NET_DRIVERS = ndis tdi tcpip tditest wshtcpip afd
@ -58,7 +58,8 @@ NET_DEVICE_DRIVERS = ne2000
SYS_APPS = shell winlogon services
APPS = args hello test cat bench apc shm lpc thread event file gditest \
pteb consume dump_shared_data vmtest regtest alive mstest objdir
pteb consume dump_shared_data vmtest regtest alive mstest nptest \
objdir atomtest
#NET_APPS = ping roshttpd
NET_APPS = ping
@ -268,6 +269,9 @@ $(FS_DRIVERS:%=%_dist): %_dist:
.PHONY: $(FS_DRIVERS) $(FS_DRIVERS:%=%_clean) $(FS_DRIVERS:%=%_install) \
$(FS_DRIVERS:%=%_dist)
#
# Network driver rules
#
$(NET_DRIVERS): %:
make -C services/net/$*

View file

@ -0,0 +1,114 @@
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <ddk/ntddk.h>
#define BUFFER_SIZE 256
int main(int argc, char* argv[])
{
PRTL_ATOM_TABLE AtomTable = NULL;
RTL_ATOM AtomA = -1, AtomB = -1, AtomC = -1;
NTSTATUS Status;
WCHAR Buffer[BUFFER_SIZE];
ULONG NameLength, Data1, Data2;
printf("Atom table test app\n\n");
printf("RtlCreateAtomTable()\n");
Status = RtlCreateAtomTable(37,
&AtomTable);
printf(" Status 0x%08lx\n", Status);
if (NT_SUCCESS(Status))
{
printf(" AtomTable %p\n", AtomTable);
printf("RtlAddAtomToAtomTable()\n");
Status = RtlAddAtomToAtomTable(AtomTable,
L"TestAtomA",
&AtomA);
printf(" Status 0x%08lx\n", Status);
if (NT_SUCCESS(Status))
{
printf(" AtomA 0x%x\n", AtomA);
}
printf("RtlAddAtomToAtomTable()\n");
Status = RtlAddAtomToAtomTable(AtomTable,
L"TestAtomB",
&AtomB);
printf(" Status 0x%08lx\n", Status);
if (NT_SUCCESS(Status))
{
printf(" AtomB 0x%x\n", AtomB);
}
printf("RtlLookupAtomInAtomTable()\n");
Status = RtlLookupAtomInAtomTable(AtomTable,
L"TestAtomA",
&AtomC);
printf(" Status 0x%08lx\n", Status);
if (NT_SUCCESS(Status))
{
printf(" AtomC 0x%x\n", AtomC);
}
printf("RtlPinAtomInAtomTable()\n");
Status = RtlPinAtomInAtomTable(AtomTable,
AtomC);
printf(" Status 0x%08lx\n", Status);
printf("RtlPinAtomInAtomTable()\n");
Status = RtlPinAtomInAtomTable(AtomTable,
AtomC);
printf(" Status 0x%08lx\n", Status);
// printf("RtlDeleteAtomFromAtomTable()\n");
// Status = RtlDeleteAtomFromAtomTable(AtomTable,
// AtomC);
// printf(" Status 0x%08lx\n", Status);
// printf("RtlEmptyAtomTable()\n");
// Status = RtlEmptyAtomTable(AtomTable,
// TRUE);
// printf(" Status 0x%08lx\n", Status);
// printf("RtlLookupAtomInAtomTable()\n");
// Status = RtlLookupAtomInAtomTable(AtomTable,
// L"TestAtomA",
// &AtomC);
// printf(" Status 0x%08lx\n", Status);
printf("RtlQueryAtomInAtomTable()\n");
NameLength = sizeof(WCHAR) * BUFFER_SIZE;
Status = RtlQueryAtomInAtomTable(AtomTable,
AtomC,
&Data1,
&Data2,
Buffer,
&NameLength);
printf(" Status 0x%08lx\n", Status);
if (NT_SUCCESS(Status))
{
printf(" RefCount %ld\n", Data1);
printf(" PinCount %ld\n", Data2);
printf(" NameLength %lu\n", NameLength);
printf(" AtomName: %S\n", Buffer);
}
printf("RtlDestroyAtomTable()\n");
RtlDestroyAtomTable(AtomTable);
printf("Atom table test app finished\n");
}
return(0);
}

View file

@ -0,0 +1,36 @@
#
#
#
PATH_TO_TOP = ../..
OBJECTS = atomtest.o
PROGS = atomtest.exe
LIBS = ../../lib/crtdll/crtdll.a ../../lib/kernel32/kernel32.a \
../../lib/ntdll/ntdll.a
CLEAN_FILES = atomtest.o atomtest.exe
all: atomtest.exe
clean: $(CLEAN_FILES:%=%_clean)
$(CLEAN_FILES:%=%_clean): %_clean:
- $(RM) $*
.phony: clean $(CLEAN_FILES:%=%_clean)
install: $(PROGS:%=$(FLOPPY_DIR)/apps/%)
$(PROGS:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: %
$(CP) $* $(FLOPPY_DIR)/apps/$*
dist: $(PROGS:%=../../$(DIST_DIR)/apps/%)
$(PROGS:%=../../$(DIST_DIR)/apps/%): ../../$(DIST_DIR)/apps/%: %
$(CP) $* ../../$(DIST_DIR)/apps/$*
atomtest.exe: $(OBJECTS) $(LIBS)
$(CC) $(OBJECTS) $(LIBS) -o atomtest.exe
$(NM) --numeric-sort atomtest.exe > atomtest.sym
include ../../rules.mak

View file

@ -1,4 +1,4 @@
/* $Id: rtl.h,v 1.49 2001/05/07 22:03:26 chorns Exp $
/* $Id: rtl.h,v 1.50 2001/05/26 16:48:36 ekohl Exp $
*
*/
@ -81,8 +81,10 @@ typedef USHORT RTL_ATOM, *PRTL_ATOM;
typedef struct _RTL_ATOM_TABLE
{
ULONG Dummy;
ULONG TableSize;
PVOID Lock; /* fast mutex (kernel mode)/ critical section (user mode) */
PVOID HandleTable;
LIST_ENTRY Slot[0];
} RTL_ATOM_TABLE, *PRTL_ATOM_TABLE;
struct _LB_RANGE
@ -108,6 +110,21 @@ typedef struct _RTL_NLS_DATA
} RTL_NLS_DATA, *PRTL_NLS_DATA;
typedef struct _RTL_GENERIC_TABLE
{
PVOID RootElement;
ULONG Unknown2;
ULONG Unknown3;
ULONG Unknown4;
ULONG Unknown5;
ULONG ElementCount;
PVOID CompareRoutine;
PVOID AllocateRoutine;
PVOID FreeRoutine;
ULONG UserParameter;
} RTL_GENERIC_TABLE, *PRTL_GENERIC_TABLE;
/*
* PURPOSE: Flags for RtlQueryRegistryValues
*/
@ -818,7 +835,7 @@ NTSTATUS
STDCALL
RtlEmptyAtomTable (
IN PRTL_ATOM_TABLE AtomTable,
ULONG Unknown2
IN BOOLEAN DeletePinned
);
LARGE_INTEGER
@ -1074,6 +1091,25 @@ RtlInitializeContext (
IN OUT PINITIAL_TEB InitialTeb
);
VOID
STDCALL
RtlInitializeGenericTable (
IN OUT PRTL_GENERIC_TABLE Table,
IN PVOID CompareRoutine,
IN PVOID AllocateRoutine,
IN PVOID FreeRoutine,
IN ULONG UserParameter
);
PVOID
STDCALL
RtlInsertElementGenericTable (
IN OUT PRTL_GENERIC_TABLE Table,
IN PVOID Element,
IN ULONG ElementSize,
IN ULONG Unknown4
);
NTSTATUS
STDCALL
RtlIntegerToChar (
@ -1091,6 +1127,12 @@ RtlIntegerToUnicodeString (
IN OUT PUNICODE_STRING String
);
BOOLEAN
STDCALL
RtlIsGenericTableEmpty (
IN PRTL_GENERIC_TABLE Table
);
BOOLEAN
STDCALL
RtlIsNameLegalDOS8Dot3 (
@ -1297,7 +1339,7 @@ NTSTATUS
STDCALL
RtlLookupAtomInAtomTable (
IN PRTL_ATOM_TABLE AtomTable,
IN PUNICODE_STRING AtomName,
IN PWSTR AtomName,
OUT PRTL_ATOM Atom
);
@ -1340,6 +1382,12 @@ RtlNtStatusToPsxErrno (
NTSTATUS StatusCode
);
ULONG
STDCALL
RtlNumberGenericTableElements (
IN PRTL_GENERIC_TABLE Table
);
ULONG
STDCALL
RtlNumberOfClearBits (
@ -1386,7 +1434,7 @@ RtlOpenCurrentUser (
NTSTATUS STDCALL
RtlPinAtomInAtomTable (
IN PRTL_ATOM_TABLE AtomTable,
IN PRTL_ATOM Atom
IN RTL_ATOM Atom
);
BOOLEAN
@ -1409,11 +1457,11 @@ NTSTATUS
STDCALL
RtlQueryAtomInAtomTable (
IN PRTL_ATOM_TABLE AtomTable,
IN PRTL_ATOM Atom,
IN ULONG Unknown3,
IN ULONG Unknown4,
IN OUT PVOID Buffer,
IN OUT PULONG ReturnLength
IN RTL_ATOM Atom,
IN OUT PULONG RefCount OPTIONAL,
IN OUT PULONG PinCount OPTIONAL,
IN OUT PWSTR AtomName OPTIONAL,
IN OUT PULONG NameLength OPTIONAL
);
NTSTATUS

View file

@ -21,6 +21,7 @@ copy loaders\dos\loadros.com %ROS_INSTALL%
copy ntoskrnl\ntoskrnl.exe %ROS_INSTALL%
copy services\fs\vfat\vfatfs.sys %ROS_INSTALL%
copy services\fs\ms\msfs.sys %ROS_INSTALL%\system32\drivers
copy services\fs\np\npfs.sys %ROS_INSTALL%\system32\drivers
copy services\bus\acpi\acpi.sys %ROS_INSTALL%
copy services\bus\isapnp\isapnp.sys %ROS_INSTALL%
copy services\dd\ide\ide.sys %ROS_INSTALL%
@ -63,5 +64,8 @@ copy apps\vmtest\vmtest.exe %ROS_INSTALL%\bin
copy apps\gditest\gditest.exe %ROS_INSTALL%\bin
copy apps\mstest\msserver.exe %ROS_INSTALL%\bin
copy apps\mstest\msclient.exe %ROS_INSTALL%\bin
copy apps\nptest\npserver.exe %ROS_INSTALL%\bin
copy apps\nptest\npclient.exe %ROS_INSTALL%\bin
copy apps\atomtest\atomtest.exe %ROS_INSTALL%\bin
copy media\fonts\helb____.ttf %ROS_INSTALL%\media\fonts
copy media\fonts\timr____.ttf %ROS_INSTALL%\media\fonts

View file

@ -1,4 +1,4 @@
; $Id: ntdll.def,v 1.71 2001/05/24 11:28:18 ekohl Exp $
; $Id: ntdll.def,v 1.72 2001/05/26 16:49:09 ekohl Exp $
;
; ReactOS Operating System
;
@ -277,13 +277,13 @@ RtlAddAccessAllowedAce@16
RtlAddAccessDeniedAce@16
RtlAddAce@20
;RtlAddActionToRXact
;RtlAtomToAtomTable
RtlAddAtomToAtomTable@12
;RtlAddAttributeActionToRXact
RtlAddAuditAccessAce@24
;RtlAddCompoundAce
;RtlAdjustPrivilege
RtlAllocateAndInitializeSid@44
;RtlAllocateHandle
RtlAllocateHandle@8
RtlAllocateHeap@12
RtlAnsiCharToUnicodeChar@4
RtlAnsiStringToUnicodeSize@4
@ -327,7 +327,7 @@ RtlCopyString@8
RtlCopyUnicodeString@8
RtlCreateAcl@12
;RtlCreateAndSetSD
;RtlCreateAtomTable
RtlCreateAtomTable@8
RtlCreateEnvironment@8
RtlCreateHeap@24
RtlCreateProcessParameters@40
@ -348,16 +348,16 @@ RtlDeNormalizeProcessParams@4
;RtlDecompressFragment
;RtlDelete
RtlDeleteAce@8
;RtlDeleteAtomFromAtomTable
RtlDeleteAtomFromAtomTable@8
RtlDeleteCriticalSection@4
;RtlDeleteElementGenericTable
;RtlDeleteNoSplay
RtlDeleteRegistryValue@12
RtlDeleteResource@4
;RtlDeleteSecurityObject
;RtlDestroyAtomTable
RtlDestroyAtomTable@4
RtlDestroyEnvironment@4
;RtlDestroyHandleTable
RtlDestroyHandleTable@4
RtlDestroyHeap@4
RtlDestroyProcessParameters@4
;RtlDestroyQueryDebugBuffer
@ -367,7 +367,7 @@ RtlDosPathNameToNtPathName_U@16
RtlDosSearchPath_U@24
RtlDowncaseUnicodeString@12
RtlDumpResource@4
;RtlEmptyAtomTable
RtlEmptyAtomTable@8
RtlEnlargedIntegerMultiply@8
RtlEnlargedUnsignedDivide@16
RtlEnlargedUnsignedMultiply@8
@ -403,7 +403,7 @@ RtlFirstFreeAce@8
RtlFormatCurrentUserKeyPath@4
;RtlFormatMessage@36
RtlFreeAnsiString@4
;RtlFreeHandle
RtlFreeHandle@8
RtlFreeHeap@12
RtlFreeOemString@4
RtlFreeSid@4
@ -444,7 +444,7 @@ RtlInitializeBitMap@12
RtlInitializeContext@20
RtlInitializeCriticalSection@4
;RtlInitializeGenericTable
;RtlInitializeHandleTable
RtlInitializeHandleTable@12
;RtlInitializeRXact
RtlInitializeResource@4
RtlInitializeSid@12
@ -455,8 +455,8 @@ RtlIsDosDeviceName_U@4
;RtlIsGenericTableEmpty
RtlIsNameLegalDOS8Dot3@12
;RtlIsTextUnicode
;RtlIsValidHandle
;RtlIsValidIndexHandle
RtlIsValidHandle@8
RtlIsValidIndexHandle@12
RtlLargeIntegerAdd@16
RtlLargeIntegerArithmeticShift@12
RtlLargeIntegerDivide@20
@ -471,7 +471,7 @@ RtlLengthSecurityDescriptor@4
RtlLengthSid@4
RtlLocalTimeToSystemTime@8
RtlLockHeap@4
;RtlLookupAtomInAtomTable
RtlLookupAtomInAtomTable@12
;RtlLookupElementGenericTable
RtlMakeSelfRelativeSD@12
RtlMapGenericMask@8
@ -492,12 +492,12 @@ RtlOemStringToUnicodeString@12
RtlOemToUnicodeN@20
;RtlOpenCurrentUser
;RtlPcToFileHeader
;RtlPinAtomInAtomTable
RtlPinAtomInAtomTable@8
RtlPrefixString@12
RtlPrefixUnicodeString@12
;RtlPropertySetNameToGuid
;RtlProtectHeap
;RtlQueryAtomInAtomTable
RtlQueryAtomInAtomTable@24
RtlQueryEnvironmentVariable_U@12
RtlQueryInformationAcl@16
;RtlQueryProcessBackTraceInformation

View file

@ -1,4 +1,4 @@
; $Id: ntdll.edf,v 1.60 2001/05/24 11:28:18 ekohl Exp $
; $Id: ntdll.edf,v 1.61 2001/05/26 16:49:09 ekohl Exp $
;
; ReactOS Operating System
;
@ -277,13 +277,13 @@ RtlAddAccessAllowedAce=RtlAddAccessAllowedAce@16
RtlAddAccessDeniedAce=RtlAddAccessDeniedAce@16
RtlAddAce=RtlAddAce@20
;RtlAddActionToRXact
;RtlAtomToAtomTable
RtlAddAtomToAtomTable=RtlAddAtomToAtomTable@12
;RtlAddAttributeActionToRXact
RtlAddAuditAccessAce=RtlAddAuditAccessAce@24
;RtlAddCompoundAce
;RtlAdjustPrivilege
RtlAllocateAndInitializeSid=RtlAllocateAndInitializeSid@44
;RtlAllocateHandle
RtlAllocateHandle=RtlAllocateHandle@8
RtlAllocateHeap=RtlAllocateHeap@12
RtlAnsiCharToUnicodeChar=RtlAnsiCharToUnicodeChar@4
RtlAnsiStringToUnicodeSize=RtlAnsiStringToUnicodeSize@4
@ -327,7 +327,7 @@ RtlCopyString=RtlCopyString@8
RtlCopyUnicodeString=RtlCopyUnicodeString@8
RtlCreateAcl=RtlCreateAcl@12
;RtlCreateAndSetSD
;RtlCreateAtomTable
RtlCreateAtomTable=RtlCreateAtomTable@8
RtlCreateEnvironment=RtlCreateEnvironment@8
RtlCreateHeap=RtlCreateHeap@24
RtlCreateProcessParameters=RtlCreateProcessParameters@40
@ -348,16 +348,16 @@ RtlDeNormalizeProcessParams=RtlDeNormalizeProcessParams@4
;RtlDecompressFragment
;RtlDelete
RtlDeleteAce=RtlDeleteAce@8
;RtlDeleteAtomFromAtomTable
RtlDeleteAtomFromAtomTable=RtlDeleteAtomFromAtomTable@8
RtlDeleteCriticalSection=RtlDeleteCriticalSection@4
;RtlDeleteElementGenericTable
;RtlDeleteNoSplay
RtlDeleteRegistryValue=RtlDeleteRegistryValue@12
RtlDeleteResource=RtlDeleteResource@4
;RtlDeleteSecurityObject
;RtlDestroyAtomTable
RtlDestroyAtomTable=RtlDestroyAtomTable@4
RtlDestroyEnvironment=RtlDestroyEnvironment@4
;RtlDestroyHandleTable
RtlDestroyHandleTable=RtlDestroyHandleTable@4
RtlDestroyHeap=RtlDestroyHeap@4
RtlDestroyProcessParameters=RtlDestroyProcessParameters@4
;RtlDestroyQueryDebugBuffer
@ -367,7 +367,7 @@ RtlDosPathNameToNtPathName_U=RtlDosPathNameToNtPathName_U@16
RtlDosSearchPath_U=RtlDosSearchPath_U@24
RtlDowncaseUnicodeString=RtlDowncaseUnicodeString@12
RtlDumpResource=RtlDumpResource@4
;RtlEmptyAtomTable
RtlEmptyAtomTable=RtlEmptyAtomTable@8
RtlEnlargedIntegerMultiply=RtlEnlargedIntegerMultiply@8
RtlEnlargedUnsignedDivide=RtlEnlargedUnsignedDivide@16
RtlEnlargedUnsignedMultiply=RtlEnlargedUnsignedMultiply@8
@ -403,7 +403,7 @@ RtlFindSetBitsAndClear=RtlFindSetBitsAndClear@12
RtlFormatCurrentUserKeyPath=RtlFormatCurrentUserKeyPath@4
;RtlFormatMessage
RtlFreeAnsiString=RtlFreeAnsiString@4
;RtlFreeHandle
RtlFreeHandle=RtlFreeHandle@8
RtlFreeHeap=RtlFreeHeap@12
RtlFreeSid=RtlFreeSid@4
RtlFreeUnicodeString=RtlFreeUnicodeString@4
@ -443,7 +443,7 @@ RtlInitializeBitMap=RtlInitializeBitMap@12
RtlInitializeContext=RtlInitializeContext@20
RtlInitializeCriticalSection=RtlInitializeCriticalSection@4
;RtlInitializeGenericTable
;RtlInitializeHandleTable
RtlInitializeHandleTable=RtlInitializeHandleTable@12
;RtlInitializeRXact
RtlInitializeResource=RtlInitializeResource@4
RtlInitializeSid=RtlInitializeSid@12
@ -454,8 +454,8 @@ RtlIsDosDeviceName_U=RtlIsDosDeviceName_U@4
;RtlIsGenericTableEmpty
RtlIsNameLegalDOS8Dot3=RtlIsNameLegalDOS8Dot3@12
;RtlIsTextUnicode
;RtlIsValidHandle
;RtlIsValidIndexHandle
RtlIsValidHandle=RtlIsValidHandle@8
RtlIsValidIndexHandle=RtlIsValidIndexHandle@12
RtlLargeIntegerAdd=RtlLargeIntegerAdd@16
RtlLargeIntegerArithmeticShift=RtlLargeIntegerArithmeticShift@12
RtlLargeIntegerDivide=RtlLargeIntegerDivide@20
@ -470,7 +470,7 @@ RtlLengthSecurityDescriptor=RtlLengthSecurityDescriptor@4
RtlLengthSid=RtlLengthSid@4
RtlLocalTimeToSystemTime=RtlLocalTimeToSystemTime@8
RtlLockHeap=RtlLockHeap@4
;RtlLookupAtomInAtomTable
RtlLookupAtomInAtomTable=RtlLookupAtomInAtomTable@12
;RtlLookupElementGenericTable
RtlMakeSelfRelativeSD=RtlMakeSelfRelativeSD@12
RtlMapGenericMask=RtlMapGenericMask@8
@ -491,12 +491,12 @@ RtlOemStringToUnicodeString=RtlOemStringToUnicodeString@12
RtlOemToUnicodeN=RtlOemToUnicodeN@20
;RtlOpenCurrentUser
;RtlPcToFileHeader
;RtlPinAtomInAtomTable
RtlPinAtomInAtomTable=RtlPinAtomInAtomTable@8
RtlPrefixString=RtlPrefixString@12
RtlPrefixUnicodeString=RtlPrefixUnicodeString@12
;RtlPropertySetNameToGuid
;RtlProtectHeap
;RtlQueryAtomInAtomTable
RtlQueryAtomInAtomTable=RtlQueryAtomInAtomTable@24
RtlQueryEnvironmentVariable_U=RtlQueryEnvironmentVariable_U@12
RtlQueryInformationAcl=RtlQueryInformationAcl@16
;RtlQueryProcessBackTraceInformation

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.59 2001/05/24 11:28:54 ekohl Exp $
# $Id: makefile,v 1.60 2001/05/26 16:48:52 ekohl Exp $
#
# ReactOS Operating System
#
@ -24,7 +24,8 @@ RTL_OBJECTS = rtl/critical.o rtl/error.o rtl/heap.o rtl/largeint.o \
rtl/thread.o rtl/unicode.o rtl/env.o rtl/path.o rtl/ppb.o \
rtl/bitmap.o rtl/time.o rtl/acl.o rtl/sid.o rtl/image.o \
rtl/access.o rtl/apc.o rtl/callback.o rtl/luid.o rtl/misc.o \
rtl/registry.o rtl/exception.o rtl/intrlck.o rtl/resource.o
rtl/registry.o rtl/exception.o rtl/intrlck.o rtl/resource.o \
rtl/handle.o rtl/atom.o
STDIO_OBJECTS = stdio/sprintf.o stdio/swprintf.o

View file

@ -0,0 +1,692 @@
/* $Id: atom.c,v 1.1 2001/05/26 16:49:51 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: lib/ntdll/rtl/atom.c
* PURPOSE: Atom managment
* PROGRAMMER: Nobody
* UPDATE HISTORY:
* Created 22/05/98
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <ntdll/rtl.h>
#include <ntos/heap.h>
#define NDEBUG
#include <ntdll/ntdll.h>
/* LOCAL TYPES ***************************************************************/
typedef struct _RTL_ATOM_ENTRY
{
LIST_ENTRY List;
UNICODE_STRING Name;
ULONG RefCount;
BOOLEAN Locked;
ULONG Index;
PRTL_HANDLE Handle;
} RTL_ATOM_ENTRY, *PRTL_ATOM_ENTRY;
typedef struct _RTL_ATOM_HANDLE
{
RTL_HANDLE Handle;
PRTL_ATOM_ENTRY Entry;
} RTL_ATOM_HANDLE, *PRTL_ATOM_HANDLE;
/* PROTOTYPES ****************************************************************/
static ULONG RtlpHashAtomName(ULONG TableSize, PWSTR AtomName);
static BOOLEAN RtlpCheckIntegerAtom(PWSTR AtomName, PUSHORT AtomValue);
static NTSTATUS RtlpInitAtomTableLock(PRTL_ATOM_TABLE AtomTable);
static VOID RtlpDestroyAtomTableLock(PRTL_ATOM_TABLE AtomTable);
static BOOLEAN RtlpLockAtomTable(PRTL_ATOM_TABLE AtomTable);
static VOID RtlpUnlockAtomTable(PRTL_ATOM_TABLE AtomTable);
static BOOLEAN RtlpCreateAtomHandleTable(PRTL_ATOM_TABLE AtomTable);
static VOID RtlpDestroyAtomHandleTable(PRTL_ATOM_TABLE AtomTable);
/* FUNCTIONS *****************************************************************/
NTSTATUS STDCALL
RtlCreateAtomTable(ULONG TableSize,
PRTL_ATOM_TABLE *AtomTable)
{
PRTL_ATOM_TABLE Table;
ULONG i;
NTSTATUS Status;
DPRINT("RtlCreateAtomTable(TableSize %lu AtomTable %p)\n",
TableSize, AtomTable);
if (*AtomTable != NULL)
{
return STATUS_SUCCESS;
}
/* allocate atom table */
Table = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
TableSize * sizeof(LIST_ENTRY) +
sizeof(RTL_ATOM_TABLE));
if (Table == NULL)
{
return STATUS_NO_MEMORY;
}
/* initialize atom table */
Table->TableSize = TableSize;
for (i = 0; i < TableSize; i++)
{
InitializeListHead(&Table->Slot[i]);
}
Status = RtlpInitAtomTableLock(Table);
if (!NT_SUCCESS(Status))
{
RtlFreeHeap(RtlGetProcessHeap(),
0,
Table);
return Status;
}
if (RtlpCreateAtomHandleTable(Table) == FALSE)
{
RtlpDestroyAtomTableLock(Table);
RtlFreeHeap(RtlGetProcessHeap(),
0,
Table);
return STATUS_NO_MEMORY;
}
*AtomTable = Table;
return STATUS_SUCCESS;
}
NTSTATUS STDCALL
RtlDestroyAtomTable(IN PRTL_ATOM_TABLE AtomTable)
{
PLIST_ENTRY Current;
PRTL_ATOM_ENTRY AtomEntry;
ULONG i;
if (RtlpLockAtomTable(AtomTable) == FALSE)
{
return (STATUS_INVALID_PARAMETER);
}
/* delete all atoms */
for (i = 0; i < AtomTable->TableSize; i++)
{
Current = AtomTable->Slot[i].Flink;
while (Current != &AtomTable->Slot[i])
{
AtomEntry = (PRTL_ATOM_ENTRY)Current;
RtlFreeUnicodeString(&AtomEntry->Name);
RemoveEntryList(&AtomEntry->List);
RtlFreeHeap(RtlGetProcessHeap(),
0,
AtomEntry);
Current = AtomTable->Slot[i].Flink;
}
}
RtlpDestroyAtomHandleTable(AtomTable);
RtlpUnlockAtomTable(AtomTable);
RtlpDestroyAtomTableLock(AtomTable);
RtlFreeHeap(RtlGetProcessHeap(),
0,
AtomTable);
return STATUS_SUCCESS;
}
NTSTATUS STDCALL
RtlEmptyAtomTable(PRTL_ATOM_TABLE AtomTable,
BOOLEAN DeletePinned)
{
PLIST_ENTRY Current, Next;
PRTL_ATOM_ENTRY AtomEntry;
ULONG i;
DPRINT("RtlEmptyAtomTable (AtomTable %p DeletePinned %x)\n",
AtomTable, DeletePinned);
if (RtlpLockAtomTable(AtomTable) == FALSE)
{
return (STATUS_INVALID_PARAMETER);
}
/* delete all atoms */
for (i = 0; i < AtomTable->TableSize; i++)
{
Current = AtomTable->Slot[i].Flink;
while (Current != &AtomTable->Slot[i])
{
Next = Current->Flink;
AtomEntry = (PRTL_ATOM_ENTRY)Current;
if ((AtomEntry->Locked == FALSE) ||
((AtomEntry->Locked == TRUE) && (DeletePinned == TRUE)))
{
RtlFreeUnicodeString(&AtomEntry->Name);
RtlFreeHandle(AtomTable->HandleTable,
AtomEntry->Handle);
RemoveEntryList(&AtomEntry->List);
RtlFreeHeap(RtlGetProcessHeap(),
0,
AtomEntry);
}
Current = Next;
}
}
RtlpUnlockAtomTable(AtomTable);
return STATUS_SUCCESS;
}
NTSTATUS STDCALL
RtlAddAtomToAtomTable(IN PRTL_ATOM_TABLE AtomTable,
IN PWSTR AtomName,
OUT PRTL_ATOM Atom)
{
ULONG Hash;
PLIST_ENTRY Current;
PRTL_ATOM_ENTRY Entry;
USHORT AtomValue;
NTSTATUS Status;
PRTL_ATOM_HANDLE AtomHandle;
ULONG AtomIndex;
DPRINT("RtlAddAtomToAtomTable (AtomTable %p AtomName %S Atom %p)\n",
AtomTable, AtomName, Atom);
if (RtlpCheckIntegerAtom (AtomName, &AtomValue))
{
/* integer atom */
if (AtomValue >= 0xC000)
{
AtomValue = 0;
Status = STATUS_INVALID_PARAMETER;
}
else
{
Status = STATUS_SUCCESS;
}
if (Atom)
*Atom = (RTL_ATOM)AtomValue;
return Status;
}
RtlpLockAtomTable(AtomTable);
/* string atom */
Hash = RtlpHashAtomName(AtomTable->TableSize, AtomName);
/* search for existing atom */
Current = AtomTable->Slot[Hash].Flink;
while (Current != &AtomTable->Slot[Hash])
{
Entry = (PRTL_ATOM_ENTRY)Current;
DPRINT("Comparing %S and %S\n", Entry->Name.Buffer, AtomName);
if (_wcsicmp(Entry->Name.Buffer, AtomName) == 0)
{
Entry->RefCount++;
if (Atom)
*Atom = (RTL_ATOM)(Entry->Index + 0xC000);
RtlpUnlockAtomTable(AtomTable);
return STATUS_SUCCESS;
}
Current = Current->Flink;
}
/* insert new atom */
Entry = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(RTL_ATOM_ENTRY));
if (Entry == NULL)
{
RtlpUnlockAtomTable(AtomTable);
return STATUS_NO_MEMORY;
}
InsertTailList(&AtomTable->Slot[Hash], &Entry->List)
RtlCreateUnicodeString (&Entry->Name,
AtomName);
Entry->RefCount = 1;
Entry->Locked = FALSE;
/* FIXME: use general function instead !! */
AtomHandle = (PRTL_ATOM_HANDLE)RtlAllocateHandle(AtomTable->HandleTable,
&AtomIndex);
DPRINT("AtomHandle %p AtomIndex %x\n", AtomHandle, AtomIndex);
AtomHandle->Entry = Entry;
Entry->Index = AtomIndex;
Entry->Handle = (PRTL_HANDLE)AtomHandle;
if (Atom)
*Atom = (RTL_ATOM)(AtomIndex + 0xC000);
RtlpUnlockAtomTable(AtomTable);
return STATUS_SUCCESS;
}
NTSTATUS STDCALL
RtlDeleteAtomFromAtomTable(IN PRTL_ATOM_TABLE AtomTable,
IN RTL_ATOM Atom)
{
PRTL_ATOM_HANDLE AtomHandle;
PRTL_ATOM_ENTRY AtomEntry;
DPRINT("RtlDeleteAtomFromAtomTable (AtomTable %p Atom %x)\n",
AtomTable, Atom);
if (Atom < 0xC000)
{
return STATUS_SUCCESS;
}
RtlpLockAtomTable(AtomTable);
/* FIXME: use general function instead !! */
if (!RtlIsValidIndexHandle(AtomTable->HandleTable,
(PRTL_HANDLE *)&AtomHandle,
(ULONG)Atom - 0xC000))
{
RtlpUnlockAtomTable(AtomTable);
return STATUS_INVALID_HANDLE;
}
DPRINT("AtomHandle %x\n", AtomHandle);
DPRINT("AtomHandle->Entry %x\n", AtomHandle->Entry);
AtomEntry = AtomHandle->Entry;
DPRINT("Atom name: %wZ\n", &AtomEntry->Name);
AtomEntry->RefCount--;
if (AtomEntry->RefCount == 0)
{
if (AtomEntry->Locked == TRUE)
{
DPRINT("Atom %wZ is locked!\n", &AtomEntry->Name);
RtlpUnlockAtomTable(AtomTable);
return STATUS_WAS_LOCKED;
}
DPRINT("Removing atom: %wZ\n", &AtomEntry->Name);
RtlFreeUnicodeString(&AtomEntry->Name);
RemoveEntryList(&AtomEntry->List);
RtlFreeHeap(RtlGetProcessHeap(),
0,
AtomEntry);
RtlFreeHandle(AtomTable->HandleTable,
(PRTL_HANDLE)AtomHandle);
}
RtlpUnlockAtomTable(AtomTable);
return STATUS_SUCCESS;
}
NTSTATUS STDCALL
RtlLookupAtomInAtomTable(IN PRTL_ATOM_TABLE AtomTable,
IN PWSTR AtomName,
OUT PRTL_ATOM Atom)
{
ULONG Hash;
PLIST_ENTRY Current;
PRTL_ATOM_ENTRY Entry;
USHORT AtomValue;
NTSTATUS Status;
DPRINT("RtlLookupAtomInAtomTable (AtomTable %p AtomName %S Atom %p)\n",
AtomTable, AtomName, Atom);
if (RtlpCheckIntegerAtom (AtomName, &AtomValue))
{
/* integer atom */
if (AtomValue >= 0xC000)
{
AtomValue = 0;
Status = STATUS_INVALID_PARAMETER;
}
else
{
Status = STATUS_SUCCESS;
}
if (Atom)
*Atom = (RTL_ATOM)AtomValue;
return Status;
}
RtlpLockAtomTable(AtomTable);
/* string atom */
Hash = RtlpHashAtomName(AtomTable->TableSize, AtomName);
/* search for existing atom */
Current = AtomTable->Slot[Hash].Flink;
while (Current != &AtomTable->Slot[Hash])
{
Entry = (PRTL_ATOM_ENTRY)Current;
DPRINT("Comparing %S and %S\n", Entry->Name.Buffer, AtomName);
if (_wcsicmp(Entry->Name.Buffer, AtomName) == 0)
{
if (Atom)
*Atom = (RTL_ATOM)(Entry->Index + 0xC000);
RtlpUnlockAtomTable(AtomTable);
return STATUS_SUCCESS;
}
Current = Current->Flink;
}
return STATUS_OBJECT_NAME_NOT_FOUND;
}
NTSTATUS STDCALL
RtlPinAtomInAtomTable(IN PRTL_ATOM_TABLE AtomTable,
IN RTL_ATOM Atom)
{
PRTL_ATOM_HANDLE AtomHandle;
PRTL_ATOM_ENTRY AtomEntry;
DPRINT("RtlPinAtomInAtomTable (AtomTable %p Atom %x)\n",
AtomTable, Atom);
if (Atom < 0xC000)
{
return STATUS_SUCCESS;
}
RtlpLockAtomTable(AtomTable);
/* FIXME: use general function instead !! */
if (!RtlIsValidIndexHandle(AtomTable->HandleTable,
(PRTL_HANDLE *)&AtomHandle,
(ULONG)Atom - 0xC000))
{
RtlpUnlockAtomTable(AtomTable);
return STATUS_INVALID_HANDLE;
}
DPRINT("AtomHandle %x\n", AtomHandle);
DPRINT("AtomHandle->Entry %x\n", AtomHandle->Entry);
AtomEntry = AtomHandle->Entry;
DPRINT("Atom name: %wZ\n", &AtomEntry->Name);
AtomEntry->Locked = TRUE;
RtlpUnlockAtomTable(AtomTable);
return STATUS_SUCCESS;
}
NTSTATUS STDCALL
RtlQueryAtomInAtomTable(PRTL_ATOM_TABLE AtomTable,
RTL_ATOM Atom,
PULONG RefCount,
PULONG PinCount,
PWSTR AtomName,
PULONG NameLength)
{
ULONG Length;
PRTL_ATOM_HANDLE AtomHandle;
PRTL_ATOM_ENTRY AtomEntry;
if (Atom < 0xC000)
{
if (RefCount != NULL)
{
*RefCount = 1;
}
if (PinCount != NULL)
{
*PinCount = 1;
}
if ((AtomName != NULL) && (NameLength != NULL) && (NameLength > 0))
{
Length = swprintf(AtomName, L"#%lu", (ULONG)Atom);
*NameLength = Length * sizeof(WCHAR);
}
return STATUS_SUCCESS;
}
RtlpLockAtomTable(AtomTable);
/* FIXME: use general function instead !! */
if (!RtlIsValidIndexHandle(AtomTable->HandleTable,
(PRTL_HANDLE *)&AtomHandle,
(ULONG)Atom - 0xC000))
{
RtlpUnlockAtomTable(AtomTable);
return STATUS_INVALID_HANDLE;
}
DPRINT("AtomHandle %x\n", AtomHandle);
DPRINT("AtomHandle->Entry %x\n", AtomHandle->Entry);
AtomEntry = AtomHandle->Entry;
DPRINT("Atom name: %wZ\n", &AtomEntry->Name);
AtomEntry->Locked = TRUE;
if (RefCount != NULL)
{
*RefCount = AtomEntry->RefCount;
}
if (PinCount != NULL)
{
*PinCount = (ULONG)AtomEntry->Locked;
}
if ((AtomName != NULL) && (NameLength != NULL))
{
if (*NameLength < AtomEntry->Name.Length)
{
*NameLength = AtomEntry->Name.Length;
RtlpUnlockAtomTable(AtomTable);
return STATUS_BUFFER_TOO_SMALL;
}
Length = swprintf(AtomName, L"%s", AtomEntry->Name.Buffer);
*NameLength = Length * sizeof(WCHAR);
}
RtlpUnlockAtomTable(AtomTable);
return STATUS_SUCCESS;
}
/* INTERNAL FUNCTIONS ********************************************************/
static ULONG
RtlpHashAtomName(ULONG TableSize,
PWSTR AtomName)
{
ULONG q = 0;
PWCHAR p;
DPRINT("RtlpHashAtomName(TableSize %ld AtomName '%S')\n",
TableSize, AtomName);
/* convert the string to an internal representation */
p = AtomName;
while (*p != 0)
{
q += (ULONG)towupper(*p);
p++;
}
DPRINT("q %lu Hash %lu\n", q, q % TableSize);
return (q % TableSize);
}
static BOOLEAN
RtlpCheckIntegerAtom(PWSTR AtomName,
PUSHORT AtomValue)
{
USHORT LoValue;
PWCHAR p;
DPRINT("RtlpCheckIntegerAtom(AtomName '%S' AtomValue %p)\n",
AtomName, AtomValue);
if (!((ULONG)AtomName & 0xFFFF0000))
{
LoValue = (USHORT)((ULONG)AtomName & 0xFFFF);
if (LoValue >= 0xC000)
return FALSE;
if (LoValue == 0)
LoValue = 0xC000;
if (AtomValue != NULL)
*AtomValue = LoValue;
return TRUE;
}
if (*AtomName != L'#')
return FALSE;
p = AtomName;
p++;
while (*p)
{
if ((*p < L'0') || (*p > L'9'))
return FALSE;
p++;
}
return TRUE;
}
/* lock functions */
static NTSTATUS
RtlpInitAtomTableLock(PRTL_ATOM_TABLE AtomTable)
{
AtomTable->Lock = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(CRITICAL_SECTION));
if (AtomTable->Lock == NULL)
return STATUS_NO_MEMORY;
RtlInitializeCriticalSection((PCRITICAL_SECTION)AtomTable->Lock);
return STATUS_SUCCESS;
}
static VOID
RtlpDestroyAtomTableLock(PRTL_ATOM_TABLE AtomTable)
{
if (AtomTable->Lock)
{
RtlDeleteCriticalSection((PCRITICAL_SECTION)AtomTable->Lock);
RtlFreeHeap(RtlGetProcessHeap(),
0,
AtomTable->Lock);
AtomTable->Lock = NULL;
}
}
static BOOLEAN
RtlpLockAtomTable(PRTL_ATOM_TABLE AtomTable)
{
RtlEnterCriticalSection((PCRITICAL_SECTION)AtomTable->Lock);
return TRUE;
}
static VOID
RtlpUnlockAtomTable(PRTL_ATOM_TABLE AtomTable)
{
RtlLeaveCriticalSection((PCRITICAL_SECTION)AtomTable->Lock);
}
/* handle functions */
static BOOLEAN
RtlpCreateAtomHandleTable(PRTL_ATOM_TABLE AtomTable)
{
AtomTable->HandleTable = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(RTL_HANDLE_TABLE));
if (AtomTable->HandleTable == NULL)
return FALSE;
RtlInitializeHandleTable(0xCFFF,
sizeof(RTL_ATOM_HANDLE),
(PRTL_HANDLE_TABLE)AtomTable->HandleTable);
return TRUE;
}
static VOID
RtlpDestroyAtomHandleTable(PRTL_ATOM_TABLE AtomTable)
{
if (AtomTable->HandleTable)
{
RtlDestroyHandleTable((PRTL_HANDLE_TABLE)AtomTable->HandleTable);
RtlFreeHeap(RtlGetProcessHeap(),
0,
AtomTable->HandleTable);
AtomTable->HandleTable = NULL;
}
}
/* EOF */

View file

@ -0,0 +1,168 @@
/* $Id: handle.c,v 1.1 2001/05/26 16:49:51 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Handle table
* FILE: lib/ntdll/rtl/handle.c
* PROGRAMER: Eric Kohl <ekohl@rz-online.de>
*/
/* INCLUDES ******************************************************************/
#include <ddk/ntddk.h>
#include <ntdll/rtl.h>
#define NDEBUG
#include <ntdll/ntdll.h>
/* FUNCTIONS *****************************************************************/
VOID STDCALL
RtlInitializeHandleTable(ULONG TableSize,
ULONG HandleSize,
PRTL_HANDLE_TABLE HandleTable)
{
/* initialize handle table */
memset(HandleTable,
0,
sizeof(RTL_HANDLE_TABLE));
HandleTable->TableSize = TableSize;
HandleTable->HandleSize = HandleSize;
}
VOID STDCALL
RtlDestroyHandleTable(PRTL_HANDLE_TABLE HandleTable)
{
PVOID ArrayPointer;
ULONG ArraySize;
/* free handle array */
ArrayPointer = (PVOID)HandleTable->Handles;
ArraySize = (ULONG)HandleTable->Limit - (ULONG)HandleTable->Handles;
NtFreeVirtualMemory(NtCurrentProcess(),
&ArrayPointer,
&ArraySize,
MEM_RELEASE);
}
PRTL_HANDLE STDCALL
RtlAllocateHandle(PRTL_HANDLE_TABLE HandleTable,
PULONG Index)
{
RTL_HANDLE **pp_new,**pph,*ph;
NTSTATUS Status;
PRTL_HANDLE retval;
PVOID ArrayPointer;
ULONG ArraySize;
pp_new = &HandleTable->FirstFree;
if (HandleTable->FirstFree == NULL)
{
/* no free handle available */
if (HandleTable->LastUsed == NULL)
{
/* allocate handle array */
ArraySize = HandleTable->HandleSize * HandleTable->TableSize;
ArrayPointer = NULL;
Status = NtAllocateVirtualMemory(NtCurrentProcess(),
(PVOID*)&ArrayPointer,
0,
&ArraySize,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
return NULL;
/* update handle array pointers */
HandleTable->Handles = (PRTL_HANDLE)ArrayPointer;
HandleTable->Limit = (PRTL_HANDLE)(ArrayPointer + ArraySize);
HandleTable->LastUsed = (PRTL_HANDLE)ArrayPointer;
}
/* build free list in handle array */
ph = HandleTable->LastUsed;
pph = pp_new;
while (ph < HandleTable->Limit)
{
*pph = ph;
pph = &ph->Next;
ph = (PRTL_HANDLE)((ULONG)ph + HandleTable->HandleSize);
}
*pph = 0;
}
/* remove handle from free list */
retval = *pp_new;
*pp_new = retval->Next;
retval->Next = NULL;
if (Index)
*Index = ((ULONG)retval - (ULONG)HandleTable->Handles) / HandleTable->HandleSize;
return retval;
}
BOOLEAN STDCALL
RtlFreeHandle(PRTL_HANDLE_TABLE HandleTable,
PRTL_HANDLE Handle)
{
/* check if handle is valid */
if (RtlIsValidHandle(HandleTable, Handle))
return FALSE;
/* clear handle */
memset(Handle, 0, HandleTable->HandleSize);
/* add handle to free list */
Handle->Next = HandleTable->FirstFree;
HandleTable->FirstFree = Handle;
return TRUE;
}
BOOLEAN STDCALL
RtlIsValidHandle(PRTL_HANDLE_TABLE HandleTable,
PRTL_HANDLE Handle)
{
if ((HandleTable != NULL)
&& (Handle != NULL)
&& (Handle >= HandleTable->Handles)
&& (Handle < HandleTable->Limit))
return TRUE;
return FALSE;
}
BOOLEAN STDCALL
RtlIsValidIndexHandle(PRTL_HANDLE_TABLE HandleTable,
PRTL_HANDLE *Handle,
ULONG Index)
{
PRTL_HANDLE InternalHandle;
DPRINT("RtlIsValidIndexHandle(HandleTable %p Handle %p Index %x)\n", HandleTable, Handle, Index);
if (HandleTable == NULL)
return FALSE;
DPRINT("Handles %p HandleSize %x\n",
HandleTable->Handles, HandleTable->HandleSize);
InternalHandle = (PRTL_HANDLE)((ULONG)HandleTable->Handles + (HandleTable->HandleSize * Index));
if (RtlIsValidHandle(HandleTable, InternalHandle) == FALSE)
return FALSE;
DPRINT("InternalHandle %p\n", InternalHandle);
if (Handle != NULL)
*Handle = InternalHandle;
return TRUE;
}
/* EOF */