diff --git a/reactos/Makefile b/reactos/Makefile index 95e4fe59541..b3e58052954 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -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/$* diff --git a/reactos/apps/tests/atomtest/atomtest.c b/reactos/apps/tests/atomtest/atomtest.c new file mode 100644 index 00000000000..f71253dde7c --- /dev/null +++ b/reactos/apps/tests/atomtest/atomtest.c @@ -0,0 +1,114 @@ +#include +#include +#include +#include + +#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); +} diff --git a/reactos/apps/tests/atomtest/makefile b/reactos/apps/tests/atomtest/makefile new file mode 100644 index 00000000000..2acc5833918 --- /dev/null +++ b/reactos/apps/tests/atomtest/makefile @@ -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 diff --git a/reactos/include/ddk/rtl.h b/reactos/include/ddk/rtl.h index 2a2f98709ac..3bcb134e5a6 100644 --- a/reactos/include/ddk/rtl.h +++ b/reactos/include/ddk/rtl.h @@ -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 diff --git a/reactos/install.bat b/reactos/install.bat index fa11a1ca16d..afe34264b73 100644 --- a/reactos/install.bat +++ b/reactos/install.bat @@ -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 diff --git a/reactos/lib/ntdll/def/ntdll.def b/reactos/lib/ntdll/def/ntdll.def index c50b4eafa5a..a827e95936b 100644 --- a/reactos/lib/ntdll/def/ntdll.def +++ b/reactos/lib/ntdll/def/ntdll.def @@ -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 diff --git a/reactos/lib/ntdll/def/ntdll.edf b/reactos/lib/ntdll/def/ntdll.edf index 0b6c2a4b2de..e1f8bcb97ad 100644 --- a/reactos/lib/ntdll/def/ntdll.edf +++ b/reactos/lib/ntdll/def/ntdll.edf @@ -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 diff --git a/reactos/lib/ntdll/makefile b/reactos/lib/ntdll/makefile index 1e5aa63f986..a3762e77032 100644 --- a/reactos/lib/ntdll/makefile +++ b/reactos/lib/ntdll/makefile @@ -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 diff --git a/reactos/lib/ntdll/rtl/atom.c b/reactos/lib/ntdll/rtl/atom.c new file mode 100644 index 00000000000..1d1944f4fc8 --- /dev/null +++ b/reactos/lib/ntdll/rtl/atom.c @@ -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 +#include +#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 *****************************************************************/ + + +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 */ diff --git a/reactos/lib/ntdll/rtl/handle.c b/reactos/lib/ntdll/rtl/handle.c new file mode 100644 index 00000000000..6e3d6dad296 --- /dev/null +++ b/reactos/lib/ntdll/rtl/handle.c @@ -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 + */ + +/* INCLUDES ******************************************************************/ + +#include +#include + +#define NDEBUG +#include + +/* 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 */