From 469c016da3ccfb5d63bad786953e1be58bb6be6c Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Fri, 24 Jun 2005 18:11:16 +0000 Subject: [PATCH] - Moved ntdll's atom table implementation to rtl, rewrote it to use proper structures and share the generic implementation between ntoskrnl and ntdll - Updated the rtl handle table implementation to use proper structures. Reserved handles are not yet supported correctly. svn path=/trunk/; revision=16257 --- reactos/include/ndk/extypes.h | 2 +- reactos/include/ndk/rtlfuncs.h | 20 +- reactos/include/ndk/rtltypes.h | 63 +- reactos/include/ndk/umtypes.h | 4 + reactos/include/ntdll/rtl.h | 28 +- reactos/include/ntos/rtltypes.h | 47 +- reactos/lib/ntdll/ntdll.xml | 1 - reactos/lib/ntdll/rtl/atom.c | 722 ------------------- reactos/lib/ntdll/rtl/handle.c | 86 ++- reactos/lib/ntdll/rtl/libsupp.c | 156 ++++ reactos/lib/rtl/atom.c | 732 +++++++++++++++++++ reactos/lib/rtl/rtl.xml | 1 + reactos/ntoskrnl/include/internal/handle.h | 26 - reactos/ntoskrnl/include/ntoskrnl.h | 1 - reactos/ntoskrnl/ntoskrnl.xml | 1 - reactos/ntoskrnl/rtl/atom.c | 782 +-------------------- reactos/ntoskrnl/rtl/handle.c | 180 ----- reactos/ntoskrnl/rtl/libsupp.c | 155 ++++ 18 files changed, 1243 insertions(+), 1764 deletions(-) delete mode 100644 reactos/lib/ntdll/rtl/atom.c create mode 100644 reactos/lib/rtl/atom.c delete mode 100644 reactos/ntoskrnl/include/internal/handle.h delete mode 100644 reactos/ntoskrnl/rtl/handle.c diff --git a/reactos/include/ndk/extypes.h b/reactos/include/ndk/extypes.h index 9c2f34df525..6bfee7ad4bd 100644 --- a/reactos/include/ndk/extypes.h +++ b/reactos/include/ndk/extypes.h @@ -86,7 +86,7 @@ typedef struct _HANDLE_TABLE ERESOURCE HandleTableLock; LIST_ENTRY HandleTableList; KEVENT HandleContentionEvent; -} HANDLE_TABLE; +} HANDLE_TABLE, *PHANDLE_TABLE; #endif diff --git a/reactos/include/ndk/rtlfuncs.h b/reactos/include/ndk/rtlfuncs.h index 4fb670c1ce4..2cefa1f0db1 100644 --- a/reactos/include/ndk/rtlfuncs.h +++ b/reactos/include/ndk/rtlfuncs.h @@ -859,6 +859,14 @@ RtlUnicodeStringToInteger( PULONG Value ); +NTSTATUS +STDCALL +RtlHashUnicodeString( + IN CONST UNICODE_STRING *String, + IN BOOLEAN CaseInSensitive, + IN ULONG HashAlgorithm, + OUT PULONG HashValue); + /* * Ansi String Functions */ @@ -1333,7 +1341,7 @@ DbgBreakPoint(VOID); /* * Handle Table Functions */ -PRTL_HANDLE +PRTL_HANDLE_TABLE_ENTRY STDCALL RtlAllocateHandle ( IN PRTL_HANDLE_TABLE HandleTable, @@ -1348,7 +1356,7 @@ BOOLEAN STDCALL RtlFreeHandle ( IN PRTL_HANDLE_TABLE HandleTable, - IN PRTL_HANDLE Handle + IN PRTL_HANDLE_TABLE_ENTRY Handle ); VOID @@ -1363,15 +1371,15 @@ BOOLEAN STDCALL RtlIsValidHandle ( IN PRTL_HANDLE_TABLE HandleTable, - IN PRTL_HANDLE Handle + IN PRTL_HANDLE_TABLE_ENTRY Handle ); BOOLEAN STDCALL RtlIsValidIndexHandle ( - IN PRTL_HANDLE_TABLE HandleTable, - IN OUT PRTL_HANDLE *Handle, - IN ULONG Index + IN PRTL_HANDLE_TABLE HandleTable, + IN OUT PRTL_HANDLE_TABLE_ENTRY *Handle, + IN ULONG Index ); /* diff --git a/reactos/include/ndk/rtltypes.h b/reactos/include/ndk/rtltypes.h index 144272d2357..2472854b6ed 100644 --- a/reactos/include/ndk/rtltypes.h +++ b/reactos/include/ndk/rtltypes.h @@ -50,6 +50,13 @@ #define PDI_HEAP_TAGS 0x08 /* The heap tags */ #define PDI_HEAP_BLOCKS 0x10 /* The heap blocks */ #define PDI_LOCKS 0x20 /* The locks created by the process */ + +/* RTL Handle Flags */ +#define RTL_HANDLE_VALID 0x1 + +/* RTL Atom Flags */ +#define RTL_ATOM_IS_PINNED 0x1 + /* ENUMERATIONS **************************************************************/ typedef enum @@ -173,20 +180,23 @@ typedef struct _DEBUG_LOCK_INFORMATION ULONG NumberOfSharedWaiters; ULONG NumberOfExclusiveWaiters; } DEBUG_LOCK_INFORMATION, *PDEBUG_LOCK_INFORMATION; -typedef struct _RTL_HANDLE -{ - struct _RTL_HANDLE *Next; /* pointer to next free handle */ -} RTL_HANDLE, *PRTL_HANDLE; +typedef struct _RTL_HANDLE_TABLE_ENTRY +{ + ULONG Flags; + struct _RTL_HANDLE_TABLE_ENTRY *NextFree; +} RTL_HANDLE_TABLE_ENTRY, *PRTL_HANDLE_TABLE_ENTRY; typedef struct _RTL_HANDLE_TABLE { - ULONG TableSize; /* maximum number of handles */ - ULONG HandleSize; /* size of handle in bytes */ - PRTL_HANDLE Handles; /* pointer to handle array */ - PRTL_HANDLE Limit; /* limit of pointers */ - PRTL_HANDLE FirstFree; /* pointer to first free handle */ - PRTL_HANDLE LastUsed; /* pointer to last allocated handle */ + ULONG MaximumNumberOfHandles; + ULONG SizeOfHandleTableEntry; + ULONG Reserved[2]; + PRTL_HANDLE_TABLE_ENTRY FreeHandles; + PRTL_HANDLE_TABLE_ENTRY CommittedHandles; + PRTL_HANDLE_TABLE_ENTRY UnCommittedHandles; + PRTL_HANDLE_TABLE_ENTRY MaxReservedHandles; } RTL_HANDLE_TABLE, *PRTL_HANDLE_TABLE; + typedef struct _LOCK_INFORMATION { ULONG LockCount; @@ -346,15 +356,32 @@ typedef struct _RTL_PROCESS_INFO SECTION_IMAGE_INFORMATION ImageInfo; } RTL_PROCESS_INFO, *PRTL_PROCESS_INFO; -/* FIXME: This is a Windows Type which which we are not implementing properly - The type below however is our own implementation. We will eventually use Windows' */ -typedef struct _RTL_ATOM_TABLE +typedef struct _RTL_ATOM_TABLE_ENTRY { - ULONG TableSize; - ULONG NumberOfAtoms; - PVOID Lock; /* fast mutex (kernel mode)/ critical section (user mode) */ - PVOID HandleTable; - LIST_ENTRY Slot[0]; + struct _RTL_ATOM_TABLE_ENTRY *HashLink; + USHORT HandleIndex; + USHORT Atom; + USHORT ReferenceCount; + UCHAR Flags; + UCHAR NameLength; + WCHAR Name[1]; +} RTL_ATOM_TABLE_ENTRY, *PRTL_ATOM_TABLE_ENTRY; + +typedef struct _RTL_ATOM_TABLE +{ + ULONG Signature; + union + { + RTL_CRITICAL_SECTION CriticalSection; + FAST_MUTEX FastMutex; + }; + union + { + RTL_HANDLE_TABLE RtlHandleTable; + PHANDLE_TABLE ExHandleTable; + }; + ULONG NumberOfBuckets; + PRTL_ATOM_TABLE_ENTRY Buckets[1]; } RTL_ATOM_TABLE, *PRTL_ATOM_TABLE; /* Let Kernel Drivers use this */ diff --git a/reactos/include/ndk/umtypes.h b/reactos/include/ndk/umtypes.h index 297ea2e7aa1..ceac0255ddc 100644 --- a/reactos/include/ndk/umtypes.h +++ b/reactos/include/ndk/umtypes.h @@ -1382,6 +1382,10 @@ typedef struct _UNICODE_PREFIX_TABLE PUNICODE_PREFIX_TABLE_ENTRY LastNextEntry; } UNICODE_PREFIX_TABLE, *PUNICODE_PREFIX_TABLE; +/* FIXME - need FAST_MUTEX and PHANDLE_TABLE for RTL_ATOM_TABLE in umode! */ +typedef void *FAST_MUTEX; +typedef void *PHANDLE_TABLE; + typedef OSVERSIONINFOW RTL_OSVERSIONINFOW; typedef LPOSVERSIONINFOW PRTL_OSVERSIONINFOW; typedef OSVERSIONINFOEXW RTL_OSVERSIONINFOEXW; diff --git a/reactos/include/ntdll/rtl.h b/reactos/include/ntdll/rtl.h index 237a80f9f5d..dc53a64c7e0 100644 --- a/reactos/include/ntdll/rtl.h +++ b/reactos/include/ntdll/rtl.h @@ -132,19 +132,21 @@ typedef struct _RTL_RESOURCE PVOID DebugInfo; /* ?? */ } RTL_RESOURCE, *PRTL_RESOURCE; -typedef struct _RTL_HANDLE +typedef struct _RTL_HANDLE_TABLE_ENTRY { - struct _RTL_HANDLE *Next; /* pointer to next free handle */ -} RTL_HANDLE, *PRTL_HANDLE; + ULONG Flags; + struct _RTL_HANDLE_TABLE_ENTRY *NextFree; +} RTL_HANDLE_TABLE_ENTRY, *PRTL_HANDLE_TABLE_ENTRY; typedef struct _RTL_HANDLE_TABLE { - ULONG TableSize; /* maximum number of handles */ - ULONG HandleSize; /* size of handle in bytes */ - PRTL_HANDLE Handles; /* pointer to handle array */ - PRTL_HANDLE Limit; /* limit of pointers */ - PRTL_HANDLE FirstFree; /* pointer to first free handle */ - PRTL_HANDLE LastUsed; /* pointer to last allocated handle */ + ULONG MaximumNumberOfHandles; + ULONG SizeOfHandleTableEntry; + ULONG Reserved[2]; + PRTL_HANDLE_TABLE_ENTRY FreeHandles; + PRTL_HANDLE_TABLE_ENTRY CommittedHandles; + PRTL_HANDLE_TABLE_ENTRY UnCommittedHandles; + PRTL_HANDLE_TABLE_ENTRY MaxReservedHandles; } RTL_HANDLE_TABLE, *PRTL_HANDLE_TABLE; @@ -594,7 +596,7 @@ RtlReleaseResource ( /* handle table functions */ -PRTL_HANDLE +PRTL_HANDLE_TABLE_ENTRY STDCALL RtlAllocateHandle ( IN PRTL_HANDLE_TABLE HandleTable, @@ -611,7 +613,7 @@ BOOLEAN STDCALL RtlFreeHandle ( IN PRTL_HANDLE_TABLE HandleTable, - IN PRTL_HANDLE Handle + IN PRTL_HANDLE_TABLE_ENTRY Handle ); VOID @@ -626,14 +628,14 @@ BOOLEAN STDCALL RtlIsValidHandle ( IN PRTL_HANDLE_TABLE HandleTable, - IN PRTL_HANDLE Handle + IN PRTL_HANDLE_TABLE_ENTRY Handle ); BOOLEAN STDCALL RtlIsValidIndexHandle ( IN PRTL_HANDLE_TABLE HandleTable, - IN OUT PRTL_HANDLE *Handle, + IN OUT PRTL_HANDLE_TABLE_ENTRY *Handle, IN ULONG Index ); diff --git a/reactos/include/ntos/rtltypes.h b/reactos/include/ntos/rtltypes.h index d46a21adec3..62ea03c953f 100755 --- a/reactos/include/ntos/rtltypes.h +++ b/reactos/include/ntos/rtltypes.h @@ -227,18 +227,51 @@ typedef struct _RTL_HEAP_DEFINITION ULONG Unknown[11]; } RTL_HEAP_DEFINITION, *PRTL_HEAP_DEFINITION; +typedef struct _RTL_HANDLE_TABLE_ENTRY +{ + ULONG Flags; + struct _RTL_HANDLE_TABLE_ENTRY *NextFree; +} RTL_HANDLE_TABLE_ENTRY, *PRTL_HANDLE_TABLE_ENTRY; +typedef struct _RTL_HANDLE_TABLE +{ + ULONG MaximumNumberOfHandles; + ULONG SizeOfHandleTableEntry; + ULONG Reserved[2]; + PRTL_HANDLE_TABLE_ENTRY FreeHandles; + PRTL_HANDLE_TABLE_ENTRY CommittedHandles; + PRTL_HANDLE_TABLE_ENTRY UnCommittedHandles; + PRTL_HANDLE_TABLE_ENTRY MaxReservedHandles; +} RTL_HANDLE_TABLE, *PRTL_HANDLE_TABLE; + +typedef struct _RTL_ATOM_TABLE_ENTRY +{ + struct _RTL_ATOM_TABLE_ENTRY *HashLink; + USHORT HandleIndex; + USHORT Atom; + USHORT ReferenceCount; + UCHAR Flags; + UCHAR NameLength; + WCHAR Name[1]; +} RTL_ATOM_TABLE_ENTRY, *PRTL_ATOM_TABLE_ENTRY; + typedef struct _RTL_ATOM_TABLE { - ULONG TableSize; - ULONG NumberOfAtoms; - PVOID Lock; /* fast mutex (kernel mode)/ critical section (user mode) */ - PVOID HandleTable; - LIST_ENTRY Slot[0]; + ULONG Signature; + union + { + RTL_CRITICAL_SECTION CriticalSection; + FAST_MUTEX FastMutex; + }; + union + { + RTL_HANDLE_TABLE RtlHandleTable; + PHANDLE_TABLE ExHandleTable; + }; + ULONG NumberOfBuckets; + PRTL_ATOM_TABLE_ENTRY Buckets[1]; } RTL_ATOM_TABLE, *PRTL_ATOM_TABLE; - - #include typedef struct _NLS_FILE_HEADER diff --git a/reactos/lib/ntdll/ntdll.xml b/reactos/lib/ntdll/ntdll.xml index d2ac48d2d0a..20af2990b0c 100644 --- a/reactos/lib/ntdll/ntdll.xml +++ b/reactos/lib/ntdll/ntdll.xml @@ -36,7 +36,6 @@ ftol.c apc.c - atom.c callback.c crc32.c critical.c diff --git a/reactos/lib/ntdll/rtl/atom.c b/reactos/lib/ntdll/rtl/atom.c deleted file mode 100644 index 27e67da3dac..00000000000 --- a/reactos/lib/ntdll/rtl/atom.c +++ /dev/null @@ -1,722 +0,0 @@ -/* $Id$ - * - * 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 -#define NDEBUG -#include - -/* 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 *****************************************************************/ - - -/* - * @implemented - */ -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; -} - - -/* - * @implemented - */ -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; -} - - -/* - * @implemented - */ -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; -} - - -/* - * @implemented - */ -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; -} - - -/* - * @implemented - */ -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; -} - - -/* - * @implemented - */ -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; - } - - RtlpUnlockAtomTable(AtomTable); - - return STATUS_OBJECT_NAME_NOT_FOUND; -} - - -/* - * @implemented - */ -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; -} - - -/* - * @implemented - */ -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); - - 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) -{ - UNICODE_STRING AtomString; - USHORT LoValue; - ULONG LongValue; - 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++; - } - - p = AtomName; - p++; - RtlInitUnicodeString(&AtomString, - p); - - RtlUnicodeStringToInteger(&AtomString,10, &LongValue); - - *AtomValue = (USHORT)(LongValue & 0x0000FFFF); - - return TRUE; -} - - -/* lock functions */ - -static NTSTATUS -RtlpInitAtomTableLock(PRTL_ATOM_TABLE AtomTable) -{ - AtomTable->Lock = RtlAllocateHeap(RtlGetProcessHeap(), - HEAP_ZERO_MEMORY, - sizeof(RTL_CRITICAL_SECTION)); - if (AtomTable->Lock == NULL) - return STATUS_NO_MEMORY; - - RtlInitializeCriticalSection((PRTL_CRITICAL_SECTION)AtomTable->Lock); - - return STATUS_SUCCESS; -} - - -static VOID -RtlpDestroyAtomTableLock(PRTL_ATOM_TABLE AtomTable) -{ - if (AtomTable->Lock) - { - RtlDeleteCriticalSection((PRTL_CRITICAL_SECTION)AtomTable->Lock); - RtlFreeHeap(RtlGetProcessHeap(), - 0, - AtomTable->Lock); - AtomTable->Lock = NULL; - } -} - - -static BOOLEAN -RtlpLockAtomTable(PRTL_ATOM_TABLE AtomTable) -{ - RtlEnterCriticalSection((PRTL_CRITICAL_SECTION)AtomTable->Lock); - return TRUE; -} - - -static VOID -RtlpUnlockAtomTable(PRTL_ATOM_TABLE AtomTable) -{ - RtlLeaveCriticalSection((PRTL_CRITICAL_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 */ diff --git a/reactos/lib/ntdll/rtl/handle.c b/reactos/lib/ntdll/rtl/handle.c index d3ddc34de08..878ca9a20aa 100644 --- a/reactos/lib/ntdll/rtl/handle.c +++ b/reactos/lib/ntdll/rtl/handle.c @@ -24,8 +24,8 @@ RtlInitializeHandleTable(ULONG TableSize, memset(HandleTable, 0, sizeof(RTL_HANDLE_TABLE)); - HandleTable->TableSize = TableSize; - HandleTable->HandleSize = HandleSize; + HandleTable->MaximumNumberOfHandles = TableSize; + HandleTable->SizeOfHandleTableEntry = HandleSize; } @@ -39,38 +39,43 @@ RtlDestroyHandleTable(PRTL_HANDLE_TABLE HandleTable) ULONG ArraySize; /* free handle array */ - ArrayPointer = (PVOID)HandleTable->Handles; - ArraySize = (ULONG)HandleTable->Limit - (ULONG)HandleTable->Handles; - NtFreeVirtualMemory(NtCurrentProcess(), - &ArrayPointer, - &ArraySize, - MEM_RELEASE); + if (HandleTable->CommittedHandles) + { + ArrayPointer = (PVOID)HandleTable->CommittedHandles; + ArraySize = HandleTable->SizeOfHandleTableEntry * HandleTable->MaximumNumberOfHandles; + NtFreeVirtualMemory(NtCurrentProcess(), + &ArrayPointer, + &ArraySize, + MEM_RELEASE); + } } /* * @implemented */ -PRTL_HANDLE STDCALL +PRTL_HANDLE_TABLE_ENTRY STDCALL RtlAllocateHandle(PRTL_HANDLE_TABLE HandleTable, PULONG Index) { - RTL_HANDLE **pp_new,**pph,*ph; + PRTL_HANDLE_TABLE_ENTRY *pp_new, *pph, ph; NTSTATUS Status; - PRTL_HANDLE retval; + PRTL_HANDLE_TABLE_ENTRY retval; PVOID ArrayPointer; ULONG ArraySize; - pp_new = &HandleTable->FirstFree; + pp_new = &HandleTable->FreeHandles; - if (HandleTable->FirstFree == NULL) + if (HandleTable->FreeHandles == NULL) { /* no free handle available */ - if (HandleTable->LastUsed == NULL) + if (HandleTable->UnCommittedHandles == NULL) { /* allocate handle array */ - ArraySize = HandleTable->HandleSize * HandleTable->TableSize; + ArraySize = HandleTable->SizeOfHandleTableEntry * HandleTable->MaximumNumberOfHandles; ArrayPointer = NULL; + + /* FIXME - only reserve handles here! */ Status = NtAllocateVirtualMemory(NtCurrentProcess(), (PVOID*)&ArrayPointer, 0, @@ -81,30 +86,34 @@ RtlAllocateHandle(PRTL_HANDLE_TABLE HandleTable, return NULL; /* update handle array pointers */ - HandleTable->Handles = (PRTL_HANDLE)ArrayPointer; - HandleTable->Limit = (PRTL_HANDLE)(ArrayPointer + ArraySize); - HandleTable->LastUsed = (PRTL_HANDLE)ArrayPointer; + HandleTable->FreeHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer; + HandleTable->MaxReservedHandles = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)ArrayPointer + ArraySize); + HandleTable->CommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer; + HandleTable->UnCommittedHandles = (PRTL_HANDLE_TABLE_ENTRY)ArrayPointer; } + /* FIXME - should check if handles need to be committed */ + /* build free list in handle array */ - ph = HandleTable->LastUsed; + ph = HandleTable->FreeHandles; pph = pp_new; - while (ph < HandleTable->Limit) + while (ph < HandleTable->MaxReservedHandles) { *pph = ph; - pph = &ph->Next; - ph = (PRTL_HANDLE)((ULONG)ph + HandleTable->HandleSize); + pph = &ph->NextFree; + ph = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)ph + HandleTable->SizeOfHandleTableEntry); } *pph = 0; } /* remove handle from free list */ retval = *pp_new; - *pp_new = retval->Next; - retval->Next = NULL; + *pp_new = retval->NextFree; + retval->NextFree = NULL; if (Index) - *Index = ((ULONG)retval - (ULONG)HandleTable->Handles) / HandleTable->HandleSize; + *Index = ((ULONG)((ULONG_PTR)retval - (ULONG_PTR)HandleTable->CommittedHandles) / + HandleTable->SizeOfHandleTableEntry); return retval; } @@ -115,18 +124,18 @@ RtlAllocateHandle(PRTL_HANDLE_TABLE HandleTable, */ BOOLEAN STDCALL RtlFreeHandle(PRTL_HANDLE_TABLE HandleTable, - PRTL_HANDLE Handle) + PRTL_HANDLE_TABLE_ENTRY Handle) { /* check if handle is valid */ if (RtlIsValidHandle(HandleTable, Handle)) return FALSE; /* clear handle */ - memset(Handle, 0, HandleTable->HandleSize); + memset(Handle, 0, HandleTable->SizeOfHandleTableEntry); /* add handle to free list */ - Handle->Next = HandleTable->FirstFree; - HandleTable->FirstFree = Handle; + Handle->NextFree = HandleTable->FreeHandles; + HandleTable->FreeHandles = Handle; return TRUE; } @@ -137,12 +146,12 @@ RtlFreeHandle(PRTL_HANDLE_TABLE HandleTable, */ BOOLEAN STDCALL RtlIsValidHandle(PRTL_HANDLE_TABLE HandleTable, - PRTL_HANDLE Handle) + PRTL_HANDLE_TABLE_ENTRY Handle) { if ((HandleTable != NULL) - && (Handle != NULL) - && (Handle >= HandleTable->Handles) - && (Handle < HandleTable->Limit)) + && (Handle >= HandleTable->CommittedHandles) + && (Handle < HandleTable->MaxReservedHandles) + && (Handle->Flags & RTL_HANDLE_VALID)) return TRUE; return FALSE; } @@ -153,10 +162,10 @@ RtlIsValidHandle(PRTL_HANDLE_TABLE HandleTable, */ BOOLEAN STDCALL RtlIsValidIndexHandle(PRTL_HANDLE_TABLE HandleTable, - PRTL_HANDLE *Handle, + PRTL_HANDLE_TABLE_ENTRY *Handle, ULONG Index) { - PRTL_HANDLE InternalHandle; + PRTL_HANDLE_TABLE_ENTRY InternalHandle; DPRINT("RtlIsValidIndexHandle(HandleTable %p Handle %p Index %x)\n", HandleTable, Handle, Index); @@ -164,10 +173,11 @@ RtlIsValidIndexHandle(PRTL_HANDLE_TABLE HandleTable, return FALSE; DPRINT("Handles %p HandleSize %x\n", - HandleTable->Handles, HandleTable->HandleSize); + HandleTable->CommittedHandles, HandleTable->SizeOfHandleTableEntry); - InternalHandle = (PRTL_HANDLE)((ULONG)HandleTable->Handles + (HandleTable->HandleSize * Index)); - if (RtlIsValidHandle(HandleTable, InternalHandle) == FALSE) + InternalHandle = (PRTL_HANDLE_TABLE_ENTRY)((ULONG_PTR)HandleTable->CommittedHandles + + (HandleTable->SizeOfHandleTableEntry * Index)); + if (!RtlIsValidHandle(HandleTable, InternalHandle)) return FALSE; DPRINT("InternalHandle %p\n", InternalHandle); diff --git a/reactos/lib/ntdll/rtl/libsupp.c b/reactos/lib/ntdll/rtl/libsupp.c index b9b64057f5b..6f25ca4dd02 100644 --- a/reactos/lib/ntdll/rtl/libsupp.c +++ b/reactos/lib/ntdll/rtl/libsupp.c @@ -77,3 +77,159 @@ CHECK_PAGED_CODE_RTL(char *file, int line) /* meaningless in user mode */ } #endif + +/* RTL Atom Tables ************************************************************/ + +typedef struct _RTL_ATOM_HANDLE +{ + RTL_HANDLE_TABLE_ENTRY Handle; + PRTL_ATOM_TABLE_ENTRY AtomEntry; +} RTL_ATOM_HANDLE, *PRTL_ATOM_HANDLE; + +NTSTATUS +RtlpInitAtomTableLock(PRTL_ATOM_TABLE AtomTable) +{ + RtlInitializeCriticalSection(&AtomTable->CriticalSection); + return STATUS_SUCCESS; +} + + +VOID +RtlpDestroyAtomTableLock(PRTL_ATOM_TABLE AtomTable) +{ + RtlDeleteCriticalSection(&AtomTable->CriticalSection); +} + + +BOOLEAN +RtlpLockAtomTable(PRTL_ATOM_TABLE AtomTable) +{ + RtlEnterCriticalSection(&AtomTable->CriticalSection); + return TRUE; +} + + +VOID +RtlpUnlockAtomTable(PRTL_ATOM_TABLE AtomTable) +{ + RtlLeaveCriticalSection(&AtomTable->CriticalSection); +} + + +/* handle functions */ + +BOOLEAN +RtlpCreateAtomHandleTable(PRTL_ATOM_TABLE AtomTable) +{ + RtlInitializeHandleTable(0xCFFF, + sizeof(RTL_ATOM_HANDLE), + &AtomTable->RtlHandleTable); + + return TRUE; +} + +VOID +RtlpDestroyAtomHandleTable(PRTL_ATOM_TABLE AtomTable) +{ + RtlDestroyHandleTable(&AtomTable->RtlHandleTable); +} + +PRTL_ATOM_TABLE +RtlpAllocAtomTable(ULONG Size) +{ + return (PRTL_ATOM_TABLE)RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + Size); +} + +VOID +RtlpFreeAtomTable(PRTL_ATOM_TABLE AtomTable) +{ + RtlFreeHeap(RtlGetProcessHeap(), + 0, + AtomTable); +} + +PRTL_ATOM_TABLE_ENTRY +RtlpAllocAtomTableEntry(ULONG Size) +{ + return (PRTL_ATOM_TABLE_ENTRY)RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + Size); +} + +VOID +RtlpFreeAtomTableEntry(PRTL_ATOM_TABLE_ENTRY Entry) +{ + RtlFreeHeap(RtlGetProcessHeap(), + 0, + Entry); +} + +VOID +RtlpFreeAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry) +{ + PRTL_HANDLE_TABLE_ENTRY RtlHandleEntry; + + if (RtlIsValidIndexHandle(&AtomTable->RtlHandleTable, + &RtlHandleEntry, + (ULONG)Entry->HandleIndex)) + { + RtlFreeHandle(&AtomTable->RtlHandleTable, + RtlHandleEntry); + } +} + +BOOLEAN +RtlpCreateAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry) +{ + ULONG HandleIndex; + PRTL_HANDLE_TABLE_ENTRY RtlHandle; + + RtlHandle = RtlAllocateHandle(&AtomTable->RtlHandleTable, + &HandleIndex); + if (RtlHandle != NULL) + { + PRTL_ATOM_HANDLE AtomHandle = (PRTL_ATOM_HANDLE)RtlHandle; + + /* FIXME - Handle Indexes >= 0xC000 ?! */ + if (HandleIndex < 0xC000) + { + Entry->HandleIndex = (USHORT)HandleIndex; + Entry->Atom = 0xC000 + (USHORT)HandleIndex; + + AtomHandle->AtomEntry = Entry; + AtomHandle->Handle.Flags = RTL_HANDLE_VALID; + + return TRUE; + } + else + { + /* set the valid flag, otherwise RtlFreeHandle will fail! */ + AtomHandle->Handle.Flags = RTL_HANDLE_VALID; + + RtlFreeHandle(&AtomTable->RtlHandleTable, + RtlHandle); + } + } + + return FALSE; +} + +PRTL_ATOM_TABLE_ENTRY +RtlpGetAtomEntry(PRTL_ATOM_TABLE AtomTable, ULONG Index) +{ + PRTL_HANDLE_TABLE_ENTRY RtlHandle; + + if (RtlIsValidIndexHandle(&AtomTable->RtlHandleTable, + &RtlHandle, + Index)) + { + PRTL_ATOM_HANDLE AtomHandle = (PRTL_ATOM_HANDLE)RtlHandle; + + return AtomHandle->AtomEntry; + } + + return NULL; +} + diff --git a/reactos/lib/rtl/atom.c b/reactos/lib/rtl/atom.c new file mode 100644 index 00000000000..f073de9fb46 --- /dev/null +++ b/reactos/lib/rtl/atom.c @@ -0,0 +1,732 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: lib/rtl/atom.c + * PURPOSE: Atom managment + * PROGRAMMER: Nobody + * UPDATE HISTORY: + * Created 22/05/98 + */ + +/* INCLUDES *****************************************************************/ + +#include "rtl.h" + +#define NDEBUG +#include + +/* PROTOTYPES ****************************************************************/ + +extern NTSTATUS RtlpInitAtomTableLock(PRTL_ATOM_TABLE AtomTable); +extern VOID RtlpDestroyAtomTableLock(PRTL_ATOM_TABLE AtomTable); +extern BOOLEAN RtlpLockAtomTable(PRTL_ATOM_TABLE AtomTable); +extern VOID RtlpUnlockAtomTable(PRTL_ATOM_TABLE AtomTable); + +extern BOOLEAN RtlpCreateAtomHandleTable(PRTL_ATOM_TABLE AtomTable); +extern VOID RtlpDestroyAtomHandleTable(PRTL_ATOM_TABLE AtomTable); + +extern PRTL_ATOM_TABLE RtlpAllocAtomTable(ULONG Size); +extern VOID RtlpFreeAtomTable(PRTL_ATOM_TABLE AtomTable); +extern PRTL_ATOM_TABLE_ENTRY RtlpAllocAtomTableEntry(ULONG Size); +extern VOID RtlpFreeAtomTableEntry(PRTL_ATOM_TABLE_ENTRY Entry); + +extern BOOLEAN RtlpCreateAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry); +extern VOID RtlpFreeAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry); +extern PRTL_ATOM_TABLE_ENTRY RtlpGetAtomEntry(PRTL_ATOM_TABLE AtomTable, ULONG Index); + +/* FUNCTIONS *****************************************************************/ + +static PRTL_ATOM_TABLE_ENTRY +RtlpHashAtomName(IN PRTL_ATOM_TABLE AtomTable, + IN PWSTR AtomName, + OUT PRTL_ATOM_TABLE_ENTRY **HashLink) +{ + UNICODE_STRING Name; + ULONG Hash; + + RtlInitUnicodeString(&Name, + AtomName); + + if (Name.Length != 0 && + NT_SUCCESS(RtlHashUnicodeString(&Name, + TRUE, + HASH_STRING_ALGORITHM_X65599, + &Hash))) + { + PRTL_ATOM_TABLE_ENTRY Current; + PRTL_ATOM_TABLE_ENTRY *Link; + + Link = &AtomTable->Buckets[Hash % AtomTable->NumberOfBuckets]; + + /* search for an existing entry */ + Current = *Link; + while (Current != NULL) + { + if (Current->NameLength == Name.Length / sizeof(WCHAR) && + !_wcsicmp(Current->Name, Name.Buffer)) + { + *HashLink = Link; + return Current; + } + Link = &Current->HashLink; + Current = Current->HashLink; + } + + /* no matching atom found, return the hash link */ + *HashLink = Link; + } + else + *HashLink = NULL; + + return NULL; +} + +static BOOLEAN +RtlpCheckIntegerAtom(PWSTR AtomName, + PUSHORT AtomValue) +{ + UNICODE_STRING AtomString; + ULONG LongValue; + 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++; + } + + p = AtomName; + p++; + RtlInitUnicodeString(&AtomString, + p); + + DPRINT("AtomString: %wZ\n", &AtomString); + + RtlUnicodeStringToInteger(&AtomString,10, &LongValue); + + DPRINT("LongValue: %lu\n", LongValue); + + *AtomValue = (USHORT)(LongValue & 0x0000FFFF); + + return TRUE; +} + + +/* + * @implemented + */ +NTSTATUS STDCALL +RtlCreateAtomTable(IN ULONG TableSize, + IN OUT PRTL_ATOM_TABLE *AtomTable) +{ + PRTL_ATOM_TABLE Table; + NTSTATUS Status; + + DPRINT("RtlCreateAtomTable(TableSize %lu AtomTable %p)\n", + TableSize, AtomTable); + + if (*AtomTable != NULL) + { + return STATUS_SUCCESS; + } + + /* allocate atom table */ + Table = RtlpAllocAtomTable(((TableSize - 1) * sizeof(PRTL_ATOM_TABLE_ENTRY)) + + sizeof(RTL_ATOM_TABLE)); + if (Table == NULL) + { + return STATUS_NO_MEMORY; + } + + /* initialize atom table */ + Table->NumberOfBuckets = TableSize; + + Status = RtlpInitAtomTableLock(Table); + if (!NT_SUCCESS(Status)) + { + RtlpFreeAtomTable(Table); + return Status; + } + + if (!RtlpCreateAtomHandleTable(Table)) + { + RtlpDestroyAtomTableLock(Table); + RtlpFreeAtomTable(Table); + return STATUS_NO_MEMORY; + } + + *AtomTable = Table; + return STATUS_SUCCESS; +} + + +/* + * @implemented + */ +NTSTATUS STDCALL +RtlDestroyAtomTable(IN PRTL_ATOM_TABLE AtomTable) +{ + PRTL_ATOM_TABLE_ENTRY *CurrentBucket, *LastBucket; + PRTL_ATOM_TABLE_ENTRY CurrentEntry, NextEntry; + + DPRINT("RtlDestroyAtomTable (AtomTable %p)\n", AtomTable); + + if (!RtlpLockAtomTable(AtomTable)) + { + return (STATUS_INVALID_PARAMETER); + } + + /* delete all atoms */ + LastBucket = AtomTable->Buckets + AtomTable->NumberOfBuckets; + for (CurrentBucket = AtomTable->Buckets; + CurrentBucket != LastBucket; + CurrentBucket++) + { + NextEntry = *CurrentBucket; + *CurrentBucket = NULL; + + while (NextEntry != NULL) + { + CurrentEntry = NextEntry; + NextEntry = NextEntry->HashLink; + + /* no need to delete the atom handle, the handles will all be freed + up when destroying the atom handle table! */ + + RtlpFreeAtomTableEntry(CurrentEntry); + } + } + + RtlpDestroyAtomHandleTable(AtomTable); + + RtlpUnlockAtomTable(AtomTable); + + RtlpDestroyAtomTableLock(AtomTable); + + RtlpFreeAtomTable(AtomTable); + + return STATUS_SUCCESS; +} + + +/* + * @implemented + */ +NTSTATUS STDCALL +RtlEmptyAtomTable(PRTL_ATOM_TABLE AtomTable, + BOOLEAN DeletePinned) +{ + PRTL_ATOM_TABLE_ENTRY *CurrentBucket, *LastBucket; + PRTL_ATOM_TABLE_ENTRY CurrentEntry, NextEntry; + + DPRINT("RtlEmptyAtomTable (AtomTable %p DeletePinned %x)\n", + AtomTable, DeletePinned); + + if (RtlpLockAtomTable(AtomTable) == FALSE) + { + return (STATUS_INVALID_PARAMETER); + } + + /* delete all atoms */ + LastBucket = AtomTable->Buckets + AtomTable->NumberOfBuckets; + for (CurrentBucket = AtomTable->Buckets; + CurrentBucket != LastBucket; + CurrentBucket++) + { + NextEntry = *CurrentBucket; + *CurrentBucket = NULL; + + while (NextEntry != NULL) + { + CurrentEntry = NextEntry; + NextEntry = NextEntry->HashLink; + + RtlpFreeAtomHandle(AtomTable, + CurrentEntry); + + RtlpFreeAtomTableEntry(CurrentEntry); + } + } + + RtlpUnlockAtomTable(AtomTable); + + return STATUS_SUCCESS; +} + + +/* + * @implemented + */ +NTSTATUS STDCALL +RtlAddAtomToAtomTable(IN PRTL_ATOM_TABLE AtomTable, + IN PWSTR AtomName, + OUT PRTL_ATOM Atom) +{ + USHORT AtomValue; + PRTL_ATOM_TABLE_ENTRY *HashLink; + PRTL_ATOM_TABLE_ENTRY Entry = NULL; + NTSTATUS Status = STATUS_SUCCESS; + + DPRINT("RtlAddAtomToAtomTable (AtomTable %p AtomName %S Atom %p)\n", + AtomTable, AtomName, Atom); + + if (RtlpCheckIntegerAtom (AtomName, &AtomValue)) + { + /* integer atom */ + if (AtomValue >= 0xC000) + { + Status = STATUS_INVALID_PARAMETER; + } + else if (Atom != NULL) + { + *Atom = (RTL_ATOM)AtomValue; + } + + return Status; + } + + RtlpLockAtomTable(AtomTable); + + /* string atom, hash it and try to find an existing atom with the same name */ + Entry = RtlpHashAtomName(AtomTable, + AtomName, + &HashLink); + + if (Entry != NULL) + { + /* found another atom, increment the reference counter unless it's pinned */ + + if (!(Entry->Flags & RTL_ATOM_IS_PINNED)) + { + if (++Entry->ReferenceCount == 0) + { + /* FIXME - references overflowed, pin the atom? */ + Entry->Flags |= RTL_ATOM_IS_PINNED; + } + } + + if (Atom != NULL) + { + *Atom = (RTL_ATOM)Entry->Atom; + } + } + else + { + /* couldn't find an existing atom, HashLink now points to either the + HashLink pointer of the previous atom or to the bucket so we can + simply add it to the list */ + if (HashLink != NULL) + { + ULONG AtomNameLen = wcslen(AtomName); + + Entry = RtlpAllocAtomTableEntry(sizeof(RTL_ATOM_TABLE_ENTRY) - + sizeof(Entry->Name) + + (AtomNameLen + 1) * sizeof(WCHAR)); + if (Entry != NULL) + { + Entry->HashLink = NULL; + Entry->ReferenceCount = 0; + Entry->Flags = 0x0; + + Entry->NameLength = AtomNameLen; + RtlCopyMemory(Entry->Name, + AtomName, + (AtomNameLen + 1) * sizeof(WCHAR)); + + if (RtlpCreateAtomHandle(AtomTable, + Entry)) + { + /* append the atom to the list */ + *HashLink = Entry; + + if (Atom != NULL) + { + *Atom = (RTL_ATOM)Entry->Atom; + } + } + else + { + RtlpFreeAtomTableEntry(Entry); + Status = STATUS_NO_MEMORY; + } + } + else + { + Status = STATUS_NO_MEMORY; + } + } + else + { + /* The caller supplied an empty atom name! */ + Status = STATUS_INVALID_PARAMETER; + } + } + + RtlpUnlockAtomTable(AtomTable); + + return Status; +} + + +/* + * @implemented + */ +NTSTATUS STDCALL +RtlDeleteAtomFromAtomTable(IN PRTL_ATOM_TABLE AtomTable, + IN RTL_ATOM Atom) +{ + PRTL_ATOM_TABLE_ENTRY Entry; + NTSTATUS Status = STATUS_SUCCESS; + + DPRINT("RtlDeleteAtomFromAtomTable (AtomTable %p Atom %x)\n", + AtomTable, Atom); + + if (Atom >= 0xC000) + { + RtlpLockAtomTable(AtomTable); + + Entry = RtlpGetAtomEntry(AtomTable, + (ULONG)((USHORT)Atom - 0xC000)); + + if (Entry != NULL && Entry->Atom == (USHORT)Atom) + { + if (!(Entry->Flags & RTL_ATOM_IS_PINNED)) + { + if (--Entry->ReferenceCount == 0) + { + PRTL_ATOM_TABLE_ENTRY *HashLink; + + /* it's time to delete the atom. we need to unlink it from + the list. The easiest way is to take the atom name and + hash it again, this way we get the pointer to either + the hash bucket or the previous atom that links to the + one we want to delete. This way we can easily bypass + this item. */ + if (RtlpHashAtomName(AtomTable, + Entry->Name, + &HashLink) != NULL) + { + /* bypass this atom */ + *HashLink = Entry->HashLink; + + RtlpFreeAtomHandle(AtomTable, + Entry); + + RtlpFreeAtomTableEntry(Entry); + } + else + { + /* WTF?! This should never happen!!! */ + ASSERT(FALSE); + } + } + } + else + { + /* tried to delete a pinned atom, do nothing and return + STATUS_WAS_LOCKED, which is NOT a failure code! */ + Status = STATUS_WAS_LOCKED; + } + } + else + { + Status = STATUS_INVALID_HANDLE; + } + + RtlpUnlockAtomTable(AtomTable); + } + + return Status; +} + + +/* + * @implemented + */ +NTSTATUS STDCALL +RtlLookupAtomInAtomTable(IN PRTL_ATOM_TABLE AtomTable, + IN PWSTR AtomName, + OUT PRTL_ATOM Atom) +{ + PRTL_ATOM_TABLE_ENTRY Entry, *HashLink; + USHORT AtomValue; + RTL_ATOM FoundAtom = 0; + NTSTATUS Status = STATUS_SUCCESS; + + DPRINT("RtlLookupAtomInAtomTable (AtomTable %p AtomName %S Atom %p)\n", + AtomTable, AtomName, Atom); + + if (RtlpCheckIntegerAtom (AtomName, &AtomValue)) + { + /* integer atom */ + if (AtomValue >= 0xC000) + { + Status = STATUS_INVALID_PARAMETER; + } + else if (Atom != NULL) + { + *Atom = (RTL_ATOM)AtomValue; + } + + return Status; + } + + RtlpLockAtomTable(AtomTable); + + Status = STATUS_OBJECT_NAME_NOT_FOUND; + + /* string atom */ + Entry = RtlpHashAtomName(AtomTable, + AtomName, + &HashLink); + + if (Entry != NULL) + { + Status = STATUS_SUCCESS; + FoundAtom = (RTL_ATOM)Entry->Atom; + } + + RtlpUnlockAtomTable(AtomTable); + + if (NT_SUCCESS(Status) && Atom != NULL) + { + *Atom = FoundAtom; + } + + return Status; +} + + +/* + * @implemented + */ +NTSTATUS STDCALL +RtlPinAtomInAtomTable(IN PRTL_ATOM_TABLE AtomTable, + IN RTL_ATOM Atom) +{ + NTSTATUS Status = STATUS_SUCCESS; + + DPRINT("RtlPinAtomInAtomTable (AtomTable %p Atom %x)\n", + AtomTable, Atom); + + if (Atom >= 0xC000) + { + PRTL_ATOM_TABLE_ENTRY Entry; + + RtlpLockAtomTable(AtomTable); + + Entry = RtlpGetAtomEntry(AtomTable, + (ULONG)((USHORT)Atom - 0xC000)); + + if (Entry != NULL && Entry->Atom == (USHORT)Atom) + { + Entry->Flags |= RTL_ATOM_IS_PINNED; + } + else + { + Status = STATUS_INVALID_HANDLE; + } + + RtlpUnlockAtomTable(AtomTable); + } + + RtlpLockAtomTable(AtomTable); + + return Status; +} + + +/* + * @implemented + */ +NTSTATUS STDCALL +RtlQueryAtomInAtomTable(PRTL_ATOM_TABLE AtomTable, + RTL_ATOM Atom, + PULONG RefCount, + PULONG PinCount, + PWSTR AtomName, + PULONG NameLength) +{ + ULONG Length; + PRTL_ATOM_TABLE_ENTRY Entry; + NTSTATUS Status = STATUS_SUCCESS; + + if (Atom < 0xC000) + { + if (RefCount != NULL) + { + *RefCount = 1; + } + + if (PinCount != NULL) + { + *PinCount = 1; + } + + if ((AtomName != NULL) && (NameLength != NULL) && (NameLength > 0)) + { + WCHAR NameString[12]; + + Length = swprintf(NameString, L"#%lu", (ULONG)Atom) * sizeof(WCHAR); + + if (*NameLength < Length + sizeof(WCHAR)) + { + /* prevent underflow! */ + if (*NameLength >= sizeof(WCHAR)) + { + Length = *NameLength - sizeof(WCHAR); + } + else + { + Length = 0; + Status = STATUS_BUFFER_TOO_SMALL; + } + } + + if (Length) + { + RtlCopyMemory(AtomName, + NameString, + Length); + AtomName[Length / sizeof(WCHAR)] = L'\0'; + *NameLength = Length; + } + } + + return Status; + } + + RtlpLockAtomTable(AtomTable); + + Entry = RtlpGetAtomEntry(AtomTable, + (ULONG)((USHORT)Atom - 0xC000)); + + if (Entry != NULL && Entry->Atom == (USHORT)Atom) + { + DPRINT("Atom name: %wZ\n", &Entry->Name); + + if (RefCount != NULL) + { + *RefCount = Entry->ReferenceCount; + } + + if (PinCount != NULL) + { + *PinCount = ((Entry->Flags & RTL_ATOM_IS_PINNED) != 0); + } + + if ((AtomName != NULL) && (NameLength != NULL)) + { + Length = Entry->NameLength * sizeof(WCHAR); + + if (*NameLength < Length + sizeof(WCHAR)) + { + /* prevent underflow! */ + if (*NameLength >= sizeof(WCHAR)) + { + Length = *NameLength - sizeof(WCHAR); + } + else + { + Length = 0; + Status = STATUS_BUFFER_TOO_SMALL; + } + } + + if (Length) + { + RtlCopyMemory(AtomName, + Entry->Name, + Length); + AtomName[Length / sizeof(WCHAR)] = L'\0'; + *NameLength = Length; + } + } + } + else + { + Status = STATUS_INVALID_HANDLE; + } + + RtlpUnlockAtomTable(AtomTable); + + return Status; +} + + +/* + * @private - only used by NtQueryInformationAtom + */ +NTSTATUS STDCALL +RtlQueryAtomListInAtomTable(IN PRTL_ATOM_TABLE AtomTable, + IN ULONG MaxAtomCount, + OUT ULONG *AtomCount, + OUT RTL_ATOM *AtomList) +{ + PRTL_ATOM_TABLE_ENTRY *CurrentBucket, *LastBucket; + PRTL_ATOM_TABLE_ENTRY CurrentEntry; + ULONG Atoms = 0; + NTSTATUS Status = STATUS_SUCCESS; + + RtlpLockAtomTable(AtomTable); + + LastBucket = AtomTable->Buckets + AtomTable->NumberOfBuckets; + for (CurrentBucket = AtomTable->Buckets; + CurrentBucket != LastBucket; + CurrentBucket++) + { + CurrentEntry = *CurrentBucket; + + while (CurrentEntry != NULL) + { + if (MaxAtomCount > 0) + { + *(AtomList++) = (RTL_ATOM)CurrentEntry->Atom; + MaxAtomCount--; + } + else + { + /* buffer too small, but don't bail. we need to determine the + total number of atoms in the table! */ + Status = STATUS_INFO_LENGTH_MISMATCH; + } + + Atoms++; + CurrentEntry = CurrentEntry->HashLink; + } + } + + *AtomCount = Atoms; + + RtlpUnlockAtomTable(AtomTable); + + return Status; +} + diff --git a/reactos/lib/rtl/rtl.xml b/reactos/lib/rtl/rtl.xml index 7dcea0d77e0..e18522277e4 100644 --- a/reactos/lib/rtl/rtl.xml +++ b/reactos/lib/rtl/rtl.xml @@ -17,6 +17,7 @@ access.c acl.c + atom.c bit.c bitmap.c bootdata.c diff --git a/reactos/ntoskrnl/include/internal/handle.h b/reactos/ntoskrnl/include/internal/handle.h deleted file mode 100644 index 8d1f4363e3f..00000000000 --- a/reactos/ntoskrnl/include/internal/handle.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef __INTERNAL_HANDLE_H -#define __INTERNAL_HANDLE_H - - -typedef struct _RTL_HANDLE -{ - struct _RTL_HANDLE *Next; /* pointer to next free handle */ - PVOID Object; /* pointer to object */ -} RTL_HANDLE, *PRTL_HANDLE; - -typedef struct _RTL_HANDLE_TABLE -{ - ULONG TableSize; /* maximum number of handles */ - PRTL_HANDLE Handles; /* pointer to handle array */ - PRTL_HANDLE Limit; /* limit of pointers */ - PRTL_HANDLE FirstFree; /* pointer to first free handle */ - PRTL_HANDLE LastUsed; /* pointer to last allocated handle */ -} RTL_HANDLE_TABLE, *PRTL_HANDLE_TABLE; - -VOID RtlpInitializeHandleTable(ULONG TableSize, PRTL_HANDLE_TABLE HandleTable); -VOID RtlpDestroyHandleTable(PRTL_HANDLE_TABLE HandleTable); -BOOLEAN RtlpAllocateHandle(PRTL_HANDLE_TABLE HandleTable, PVOID Object, PULONG Index); -BOOLEAN RtlpFreeHandle(PRTL_HANDLE_TABLE HandleTable, ULONG Index); -PVOID RtlpMapHandleToPointer(PRTL_HANDLE_TABLE HandleTable, ULONG Index); - -#endif /* __INTERNAL_HANDLE_H */ diff --git a/reactos/ntoskrnl/include/ntoskrnl.h b/reactos/ntoskrnl/include/ntoskrnl.h index e7f89530257..2e09ea5bf09 100755 --- a/reactos/ntoskrnl/include/ntoskrnl.h +++ b/reactos/ntoskrnl/include/ntoskrnl.h @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include diff --git a/reactos/ntoskrnl/ntoskrnl.xml b/reactos/ntoskrnl/ntoskrnl.xml index 45e2d422f58..340aff7a088 100644 --- a/reactos/ntoskrnl/ntoskrnl.xml +++ b/reactos/ntoskrnl/ntoskrnl.xml @@ -322,7 +322,6 @@ capture.c ctype.c debug.c - handle.c libsupp.c message.c misc.c diff --git a/reactos/ntoskrnl/rtl/atom.c b/reactos/ntoskrnl/rtl/atom.c index 00500c58cbe..ed9d3bd6ec3 100644 --- a/reactos/ntoskrnl/rtl/atom.c +++ b/reactos/ntoskrnl/rtl/atom.c @@ -14,43 +14,27 @@ #define NDEBUG #include -typedef struct _RTL_ATOM_ENTRY -{ - LIST_ENTRY List; - UNICODE_STRING Name; - ULONG RefCount; - BOOLEAN Locked; - ULONG Index; -} RTL_ATOM_ENTRY, *PRTL_ATOM_ENTRY; - - /* PROTOTYPES ****************************************************************/ static PRTL_ATOM_TABLE RtlpGetGlobalAtomTable(VOID); +static NTSTATUS +RtlpQueryAtomInformation(PRTL_ATOM_TABLE AtomTable, + RTL_ATOM Atom, + PATOM_BASIC_INFORMATION AtomInformation, + ULONG AtomInformationLength, + PULONG ReturnLength); +static NTSTATUS +RtlpQueryAtomTableInformation(PRTL_ATOM_TABLE AtomTable, + RTL_ATOM Atom, + PATOM_TABLE_INFORMATION AtomInformation, + ULONG AtomInformationLength, + PULONG ReturnLength); -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); - -static NTSTATUS RtlpQueryAtomInformation(PRTL_ATOM_TABLE AtomTable, - RTL_ATOM Atom, - PATOM_BASIC_INFORMATION AtomInformation, - ULONG AtomInformationLength, - PULONG ReturnLength); - -static NTSTATUS RtlpQueryAtomTableInformation(PRTL_ATOM_TABLE AtomTable, - RTL_ATOM Atom, - PATOM_TABLE_INFORMATION AtomInformation, - ULONG AtomInformationLength, - PULONG ReturnLength); - +extern NTSTATUS STDCALL +RtlQueryAtomListInAtomTable(IN PRTL_ATOM_TABLE AtomTable, + IN ULONG MaxAtomCount, + OUT ULONG *AtomCount, + OUT RTL_ATOM *AtomList); /* GLOBALS *******************************************************************/ @@ -158,505 +142,6 @@ NtQueryInformationAtom(RTL_ATOM Atom, } -/* - * @implemented - */ -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 = ExAllocatePool(NonPagedPool, - TableSize * sizeof(RTL_ATOM_ENTRY) + - sizeof(RTL_ATOM_TABLE)); - if (Table == NULL) - return STATUS_NO_MEMORY; - - /* initialize atom table */ - Table->TableSize = TableSize; - Table->NumberOfAtoms = 0; - - for (i = 0; i < TableSize; i++) - { - InitializeListHead(&Table->Slot[i]); - } - - Status = RtlpInitAtomTableLock(Table); - if (!NT_SUCCESS(Status)) - { - ExFreePool(Table); - return Status; - } - - if (RtlpCreateAtomHandleTable(Table) == FALSE) - { - RtlpDestroyAtomTableLock(Table); - ExFreePool(Table); - return STATUS_NO_MEMORY; - } - - *AtomTable = Table; - return STATUS_SUCCESS; -} - - -/* - * @implemented - */ -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); - ExFreePool(AtomEntry); - Current = AtomTable->Slot[i].Flink; - } - - } - - RtlpDestroyAtomHandleTable(AtomTable); - - RtlpUnlockAtomTable(AtomTable); - - RtlpDestroyAtomTableLock(AtomTable); - - ExFreePool(AtomTable); - - return STATUS_SUCCESS; -} - - -/* - * @implemented - */ -NTSTATUS STDCALL -RtlEmptyAtomTable(IN PRTL_ATOM_TABLE AtomTable, - IN 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); - - RtlpFreeHandle(AtomTable->HandleTable, - AtomEntry->Index); - - RemoveEntryList(&AtomEntry->List); - ExFreePool(AtomEntry); - } - Current = Next; - } - - } - - AtomTable->NumberOfAtoms = 0; - - RtlpUnlockAtomTable(AtomTable); - - return STATUS_SUCCESS; -} - - -/* - * @implemented - */ -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; - 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 = ExAllocatePool(NonPagedPool, - sizeof(RTL_ATOM_ENTRY)); - if (Entry == NULL) - { - RtlpUnlockAtomTable(AtomTable); - return STATUS_NO_MEMORY; - } - - InsertTailList(&AtomTable->Slot[Hash], &Entry->List); - RtlpCreateUnicodeString (&Entry->Name, - AtomName, NonPagedPool); - Entry->RefCount = 1; - Entry->Locked = FALSE; - - /* FIXME: use general function instead !! */ - RtlpAllocateHandle(AtomTable->HandleTable, - (PVOID)Entry, - &AtomIndex); - - DPRINT("AtomIndex %x\n", AtomIndex); - - Entry->Index = AtomIndex; - AtomTable->NumberOfAtoms++; - - if (Atom) - *Atom = (RTL_ATOM)(AtomIndex + 0xC000); - - RtlpUnlockAtomTable(AtomTable); - - return STATUS_SUCCESS; -} - - -/* - * @implemented - */ -NTSTATUS STDCALL -RtlDeleteAtomFromAtomTable(IN PRTL_ATOM_TABLE AtomTable, - IN RTL_ATOM Atom) -{ - 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 !! */ - AtomEntry = (PRTL_ATOM_ENTRY)RtlpMapHandleToPointer(AtomTable->HandleTable, - (ULONG)Atom - 0xC000); - if (AtomEntry == NULL) - { - RtlpUnlockAtomTable(AtomTable); - return STATUS_INVALID_HANDLE; - } - - DPRINT("AtomEntry %x\n", AtomEntry); - 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); - ExFreePool(AtomEntry); - RtlpFreeHandle(AtomTable->HandleTable, - (ULONG)Atom - 0xC000); - AtomTable->NumberOfAtoms++; - } - - RtlpUnlockAtomTable(AtomTable); - - return STATUS_SUCCESS; -} - - -/* - * @implemented - */ -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; -} - - -/* - * @unimplemented - */ -NTSTATUS STDCALL -RtlPinAtomInAtomTable(IN PRTL_ATOM_TABLE AtomTable, - IN RTL_ATOM Atom) -{ - 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 !! */ - AtomEntry = (PRTL_ATOM_ENTRY)RtlpMapHandleToPointer(AtomTable->HandleTable, - (ULONG)Atom - 0xC000); - if (AtomEntry == NULL) - { - RtlpUnlockAtomTable(AtomTable); - return STATUS_INVALID_HANDLE; - } - - DPRINT("AtomEntry %x\n", AtomEntry); - DPRINT("Atom name: %wZ\n", &AtomEntry->Name); - - AtomEntry->Locked = TRUE; - - RtlpUnlockAtomTable(AtomTable); - - return STATUS_SUCCESS; -} - - -/* - * @implemented - */ -NTSTATUS STDCALL -RtlQueryAtomInAtomTable(IN PRTL_ATOM_TABLE AtomTable, - IN RTL_ATOM Atom, - IN OUT PULONG RefCount, - IN OUT PULONG PinCount, - IN OUT PWSTR AtomName, - IN OUT PULONG NameLength) -{ - ULONG Length; - PRTL_ATOM_ENTRY AtomEntry; - WCHAR TempAtomName[12]; - - if (Atom == 0) - { - return STATUS_INVALID_HANDLE; - } - - if (Atom < 0xC000) - { - if (RefCount != NULL) - { - *RefCount = 1; - } - - if (PinCount != NULL) - { - *PinCount = 1; - } - - Length = swprintf(TempAtomName, L"#%lu", (ULONG)Atom); - - if (NameLength != NULL) - { - *NameLength = Length * sizeof(WCHAR); - if (AtomName != NULL && *NameLength >= Length) - { - wcscpy(AtomName, TempAtomName); - } - else - { - return STATUS_BUFFER_TOO_SMALL; - } - } - - return STATUS_SUCCESS; - } - - RtlpLockAtomTable(AtomTable); - - /* FIXME: use general function instead !! */ - AtomEntry = (PRTL_ATOM_ENTRY)RtlpMapHandleToPointer(AtomTable->HandleTable, - (ULONG)Atom - 0xC000); - if (AtomEntry == NULL) - { - RtlpUnlockAtomTable(AtomTable); - return STATUS_INVALID_HANDLE; - } - - DPRINT("AtomEntry %x\n", AtomEntry); - DPRINT("Atom name: %wZ\n", &AtomEntry->Name); - - if (RefCount != NULL) - { - *RefCount = AtomEntry->RefCount; - } - - if (PinCount != NULL) - { - *PinCount = (ULONG)AtomEntry->Locked; - } - - if (NameLength != NULL) - { - if (AtomName != NULL && *NameLength >= AtomEntry->Name.Length) - { - *NameLength = AtomEntry->Name.Length; - memcpy(AtomName, AtomEntry->Name.Buffer, AtomEntry->Name.Length); - } - else - { - *NameLength = AtomEntry->Name.Length; - RtlpUnlockAtomTable(AtomTable); - return STATUS_BUFFER_TOO_SMALL; - } - } - - RtlpUnlockAtomTable(AtomTable); - - return STATUS_SUCCESS; -} - - /* INTERNAL FUNCTIONS ********************************************************/ static PRTL_ATOM_TABLE @@ -674,199 +159,6 @@ RtlpGetGlobalAtomTable(VOID) return GlobalAtomTable; } - -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) -{ - UNICODE_STRING AtomString; - ULONG LongValue; - 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++; - } - - p = AtomName; - p++; - RtlInitUnicodeString(&AtomString, - p); - - DPRINT("AtomString: %wZ\n", &AtomString); - - RtlUnicodeStringToInteger(&AtomString,10, &LongValue); - - DPRINT("LongValue: %lu\n", LongValue); - - *AtomValue = (USHORT)(LongValue & 0x0000FFFF); - - return TRUE; -} - - -/* lock functions */ - -static NTSTATUS -RtlpInitAtomTableLock(PRTL_ATOM_TABLE AtomTable) -{ - AtomTable->Lock = ExAllocatePool(NonPagedPool, - sizeof(FAST_MUTEX)); - if (AtomTable->Lock == NULL) - return STATUS_NO_MEMORY; - - ExInitializeFastMutex((PFAST_MUTEX)AtomTable->Lock); - - return STATUS_SUCCESS; -} - - -static VOID -RtlpDestroyAtomTableLock(PRTL_ATOM_TABLE AtomTable) -{ - if (AtomTable->Lock) - ExFreePool(AtomTable->Lock); -} - - -static BOOLEAN -RtlpLockAtomTable(PRTL_ATOM_TABLE AtomTable) -{ -// ExAcquireFastMutex((PFAST_MUTEX)AtomTable->Lock); - return TRUE; -} - -static VOID -RtlpUnlockAtomTable(PRTL_ATOM_TABLE AtomTable) -{ -// ExReleaseFastMutex((PFAST_MUTEX)AtomTable->Lock); -} - -#if 0 -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); -} -#endif - -/* handle functions */ - -static BOOLEAN -RtlpCreateAtomHandleTable(PRTL_ATOM_TABLE AtomTable) -{ - AtomTable->HandleTable = ExAllocatePool(NonPagedPool, - sizeof(RTL_HANDLE_TABLE)); - if (AtomTable->HandleTable == NULL) - return FALSE; - - RtlpInitializeHandleTable(0xCFFF, - (PRTL_HANDLE_TABLE)AtomTable->HandleTable); - - return TRUE; -} - - -static VOID -RtlpDestroyAtomHandleTable(PRTL_ATOM_TABLE AtomTable) -{ - if (AtomTable->HandleTable) - { - RtlpDestroyHandleTable((PRTL_HANDLE_TABLE)AtomTable->HandleTable); - ExFreePool(AtomTable->HandleTable); - AtomTable->HandleTable = NULL; - } -} - - static NTSTATUS RtlpQueryAtomInformation(PRTL_ATOM_TABLE AtomTable, RTL_ATOM Atom, @@ -901,7 +193,7 @@ RtlpQueryAtomInformation(PRTL_ATOM_TABLE AtomTable, if (NameLength + sizeof(ATOM_BASIC_INFORMATION) > AtomInformationLength) { - return STATUS_BUFFER_TOO_SMALL; + return STATUS_INFO_LENGTH_MISMATCH; } AtomInformation->UsageCount = (USHORT)UsageCount; @@ -919,16 +211,10 @@ RtlpQueryAtomTableInformation(PRTL_ATOM_TABLE AtomTable, ULONG AtomInformationLength, PULONG ReturnLength) { - PLIST_ENTRY Current, Next; - PRTL_ATOM_ENTRY AtomEntry; ULONG Length; - ULONG i, j; + NTSTATUS Status; Length = sizeof(ATOM_TABLE_INFORMATION); - if (AtomTable->NumberOfAtoms > 1) - { - Length += ((AtomTable->NumberOfAtoms - 1)* sizeof(RTL_ATOM)); - } DPRINT("RequiredLength: %lu\n", Length); @@ -939,28 +225,24 @@ RtlpQueryAtomTableInformation(PRTL_ATOM_TABLE AtomTable, if (Length > AtomInformationLength) { - return STATUS_BUFFER_TOO_SMALL; + return STATUS_INFO_LENGTH_MISMATCH; } - AtomInformation->NumberOfAtoms = AtomTable->NumberOfAtoms; - - j = 0; - for (i = 0; i < AtomTable->TableSize; i++) + Status = RtlQueryAtomListInAtomTable(AtomTable, + (AtomInformationLength - Length) / sizeof(RTL_ATOM), + &AtomInformation->NumberOfAtoms, + AtomInformation->Atoms); + if (NT_SUCCESS(Status)) { - Current = AtomTable->Slot[i].Flink; - while (Current != &AtomTable->Slot[i]) - { - Next = Current->Flink; - AtomEntry = (PRTL_ATOM_ENTRY)Current; - - AtomInformation->Atoms[j] = AtomEntry->Index + 0xC000; - j++; - - Current = Next; - } + ReturnLength += AtomInformation->NumberOfAtoms * sizeof(RTL_ATOM); + + if (ReturnLength != NULL) + { + *ReturnLength = Length; + } } - return STATUS_SUCCESS; + return Status; } /* EOF */ diff --git a/reactos/ntoskrnl/rtl/handle.c b/reactos/ntoskrnl/rtl/handle.c deleted file mode 100644 index 90a1befe941..00000000000 --- a/reactos/ntoskrnl/rtl/handle.c +++ /dev/null @@ -1,180 +0,0 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/rtl/handle.c - * PURPOSE: Handle table - * - * PROGRAMMERS: Eric Kohl - */ - -/* INCLUDES ******************************************************************/ - -#include -#define NDEBUG -#include - -static BOOLEAN -RtlpIsValidHandle(PRTL_HANDLE_TABLE HandleTable, PRTL_HANDLE Handle); -static BOOLEAN -RtlpIsValidIndexHandle(PRTL_HANDLE_TABLE HandleTable, PRTL_HANDLE *Handle, ULONG Index); - - -/* FUNCTIONS *****************************************************************/ - -VOID -RtlpInitializeHandleTable(ULONG TableSize, - PRTL_HANDLE_TABLE HandleTable) -{ - /* initialize handle table */ - memset(HandleTable, - 0, - sizeof(RTL_HANDLE_TABLE)); - HandleTable->TableSize = TableSize; -} - - -VOID -RtlpDestroyHandleTable(PRTL_HANDLE_TABLE HandleTable) -{ - ExFreePool((PVOID)HandleTable->Handles); -} - - -BOOLEAN -RtlpAllocateHandle(PRTL_HANDLE_TABLE HandleTable, - PVOID Object, - PULONG Index) -{ - RTL_HANDLE **pp_new,**pph,*ph; - PRTL_HANDLE retval; - PVOID ArrayPointer; - ULONG ArraySize; - - if (Index == NULL) - return FALSE; - - pp_new = &HandleTable->FirstFree; - - if (HandleTable->FirstFree == NULL) - { - /* no free handle available */ - if (HandleTable->LastUsed == NULL) - { - /* allocate handle array */ - ArraySize = sizeof(RTL_HANDLE) * HandleTable->TableSize; - ArrayPointer = ExAllocatePoolWithTag(PagedPool, - ArraySize, - TAG_HDTB); - if (ArrayPointer == NULL) - return FALSE; - - /* update handle array pointers */ - HandleTable->Handles = (PRTL_HANDLE)ArrayPointer; - HandleTable->Limit = (PRTL_HANDLE)((char*)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 + sizeof(RTL_HANDLE)); - } - *pph = 0; - } - - /* remove handle from free list */ - retval = *pp_new; - *pp_new = retval->Next; - retval->Next = NULL; - retval->Object = Object; - - *Index = ((ULONG)retval - (ULONG)HandleTable->Handles) / sizeof(RTL_HANDLE); - - return TRUE; -} - - -BOOLEAN -RtlpFreeHandle(PRTL_HANDLE_TABLE HandleTable, - ULONG Index) -{ - PRTL_HANDLE Handle; - - /* check if handle is valid */ - if (! RtlpIsValidIndexHandle(HandleTable, - &Handle, - Index)) - return FALSE; - - /* clear handle */ - memset(Handle, 0, sizeof(RTL_HANDLE)); - - /* add handle to free list */ - Handle->Next = HandleTable->FirstFree; - HandleTable->FirstFree = Handle; - - return TRUE; -} - - -static BOOLEAN -RtlpIsValidHandle(PRTL_HANDLE_TABLE HandleTable, - PRTL_HANDLE Handle) -{ - if ((HandleTable != NULL) - && (Handle != NULL) - && (Handle >= HandleTable->Handles) - && (Handle < HandleTable->Limit)) - return TRUE; - return FALSE; -} - - -static BOOLEAN -RtlpIsValidIndexHandle(PRTL_HANDLE_TABLE HandleTable, - PRTL_HANDLE *Handle, - ULONG Index) -{ - PRTL_HANDLE InternalHandle; - - DPRINT("RtlpIsValidIndexHandle(HandleTable %p Handle %p Index %x)\n", HandleTable, Handle, Index); - - if (HandleTable == NULL) - return FALSE; - - DPRINT("Handles %p\n", HandleTable->Handles); - - InternalHandle = (PRTL_HANDLE)((ULONG)HandleTable->Handles + sizeof(RTL_HANDLE) * Index); - if (RtlpIsValidHandle(HandleTable, InternalHandle) == FALSE) - return FALSE; - - DPRINT("InternalHandle %p\n", InternalHandle); - - if (Handle != NULL) - *Handle = InternalHandle; - - return TRUE; -} - -PVOID -RtlpMapHandleToPointer(PRTL_HANDLE_TABLE HandleTable, - ULONG Index) -{ - PRTL_HANDLE Handle; - - if (!RtlpIsValidIndexHandle(HandleTable, - &Handle, - Index)) - { - return NULL; - } - - return Handle->Object; -} - -/* EOF */ diff --git a/reactos/ntoskrnl/rtl/libsupp.c b/reactos/ntoskrnl/rtl/libsupp.c index 9256456c087..944a1a54fd2 100644 --- a/reactos/ntoskrnl/rtl/libsupp.c +++ b/reactos/ntoskrnl/rtl/libsupp.c @@ -130,4 +130,159 @@ CHECK_PAGED_CODE_RTL(char *file, int line) } #endif +/* RTL Atom Tables ************************************************************/ + +NTSTATUS +RtlpInitAtomTableLock(PRTL_ATOM_TABLE AtomTable) +{ + ExInitializeFastMutex(&AtomTable->FastMutex); + + return STATUS_SUCCESS; +} + + +VOID +RtlpDestroyAtomTableLock(PRTL_ATOM_TABLE AtomTable) +{ +} + + +BOOLEAN +RtlpLockAtomTable(PRTL_ATOM_TABLE AtomTable) +{ + ExAcquireFastMutex(&AtomTable->FastMutex); + return TRUE; +} + +VOID +RtlpUnlockAtomTable(PRTL_ATOM_TABLE AtomTable) +{ + ExReleaseFastMutex(&AtomTable->FastMutex); +} + +BOOLEAN +RtlpCreateAtomHandleTable(PRTL_ATOM_TABLE AtomTable) +{ + AtomTable->ExHandleTable = ExCreateHandleTable(NULL); + return (AtomTable->ExHandleTable != NULL); +} + +static VOID STDCALL +AtomDeleteHandleCallback(PHANDLE_TABLE HandleTable, + PVOID Object, + ULONG GrantedAccess, + PVOID Context) +{ + return; +} + +VOID +RtlpDestroyAtomHandleTable(PRTL_ATOM_TABLE AtomTable) +{ + if (AtomTable->ExHandleTable) + { + ExDestroyHandleTable(AtomTable->ExHandleTable, + AtomDeleteHandleCallback, + AtomTable); + AtomTable->ExHandleTable = NULL; + } +} + +PRTL_ATOM_TABLE +RtlpAllocAtomTable(ULONG Size) +{ + PRTL_ATOM_TABLE Table = ExAllocatePool(NonPagedPool, + Size); + if (Table != NULL) + { + RtlZeroMemory(Table, + Size); + } + + return Table; +} + +VOID +RtlpFreeAtomTable(PRTL_ATOM_TABLE AtomTable) +{ + ExFreePool(AtomTable); +} + +PRTL_ATOM_TABLE_ENTRY +RtlpAllocAtomTableEntry(ULONG Size) +{ + PRTL_ATOM_TABLE_ENTRY Entry = ExAllocatePool(NonPagedPool, + Size); + if (Entry != NULL) + { + RtlZeroMemory(Entry, + Size); + } + + return Entry; +} + +VOID +RtlpFreeAtomTableEntry(PRTL_ATOM_TABLE_ENTRY Entry) +{ + ExFreePool(Entry); +} + +VOID +RtlpFreeAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry) +{ + ExDestroyHandle(AtomTable->ExHandleTable, + (LONG)Entry->HandleIndex); +} + +BOOLEAN +RtlpCreateAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry) +{ + HANDLE_TABLE_ENTRY ExEntry; + LONG HandleIndex; + + ExEntry.u1.Object = Entry; + ExEntry.u2.GrantedAccess = 0x1; /* FIXME - valid handle */ + + HandleIndex = ExCreateHandle(AtomTable->ExHandleTable, + &ExEntry); + if (HandleIndex != 0) + { + /* FIXME - Handle Indexes >= 0xC000 ?! */ + if (HandleIndex < 0xC000) + { + Entry->HandleIndex = (USHORT)HandleIndex; + Entry->Atom = 0xC000 + (USHORT)HandleIndex; + + return TRUE; + } + else + ExDestroyHandle(AtomTable->ExHandleTable, + HandleIndex); + } + + return FALSE; +} + +PRTL_ATOM_TABLE_ENTRY +RtlpGetAtomEntry(PRTL_ATOM_TABLE AtomTable, ULONG Index) +{ + PHANDLE_TABLE_ENTRY ExEntry; + + ExEntry = ExMapHandleToPointer(AtomTable->ExHandleTable, + (LONG)Index); + if (ExEntry != NULL) + { + PRTL_ATOM_TABLE_ENTRY Entry; + + Entry = ExEntry->u1.Object; + + ExUnlockHandleTableEntry(AtomTable->ExHandleTable, + ExEntry); + return Entry; + } + + return NULL; +} + /* EOF */