diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/urtl | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/urtl')
-rw-r--r-- | private/urtl/makefile | 6 | ||||
-rw-r--r-- | private/urtl/sources | 38 | ||||
-rw-r--r-- | private/urtl/startup.c | 136 | ||||
-rw-r--r-- | private/urtl/turtl.c | 134 | ||||
-rw-r--r-- | private/urtl/turtl1.c | 50 | ||||
-rw-r--r-- | private/urtl/uheap.c | 346 |
6 files changed, 710 insertions, 0 deletions
diff --git a/private/urtl/makefile b/private/urtl/makefile new file mode 100644 index 000000000..6ee4f43fa --- /dev/null +++ b/private/urtl/makefile @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/urtl/sources b/private/urtl/sources new file mode 100644 index 000000000..d781b2f57 --- /dev/null +++ b/private/urtl/sources @@ -0,0 +1,38 @@ +!IF 0 + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + + +Author: + + Steve Wood (stevewo) 12-Apr-1990 + +NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl + +!ENDIF + +MAJORCOMP=urtl +MINORCOMP=_ + +TARGETNAME=nt +TARGETPATH=\nt\public\sdk\lib +TARGETTYPE=LIBRARY + +INCLUDES=..\inc + +SOURCES=startup.c + +UMTYPE=nt +UMTEST= +OPTIONAL_UMTEST=uheap diff --git a/private/urtl/startup.c b/private/urtl/startup.c new file mode 100644 index 000000000..0881b8dd3 --- /dev/null +++ b/private/urtl/startup.c @@ -0,0 +1,136 @@ +/*++ + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + startup.c + +Abstract: + + This module contains the startup code for an NT Application + +Author: + + Steve Wood (stevewo) 22-Aug-1989 + +Environment: + + User Mode only + +Revision History: + +--*/ + +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> + +// +// User mode process entry point. +// + +NTSTATUS +_CRTAPI1 +main( + int argc, + char *argv[], + char *envp[], + ULONG DebugParameter OPTIONAL + ); + +VOID +NtProcessStartup( + PPEB Peb + ) +{ + int argc; + char **argv; + char **envp; + char **dst; + char *nullPtr = NULL; + PCH s, d; + ULONG n, DebugParameter; + PULONG BadPointer; + PRTL_USER_PROCESS_PARAMETERS ProcessParameters; + PUNICODE_STRING p; + ANSI_STRING AnsiString; + + ASSERT( Peb != NULL ); + ProcessParameters = RtlNormalizeProcessParams( Peb->ProcessParameters ); + + DebugParameter = 0; + argc = 0; + argv = &nullPtr; + envp = &nullPtr; + + if (ARGUMENT_PRESENT( ProcessParameters )) { + DebugParameter = ProcessParameters->DebugFlags; + + dst = RtlAllocateHeap( Peb->ProcessHeap, 0, 512 * sizeof( PCH ) ); + argv = dst; + *dst = NULL; + + // + // Now extract the arguments from the process command line. + // using whitespace as separator characters. + // + + p = &ProcessParameters->CommandLine; + if (p->Buffer == NULL || p->Length == 0) { + p = &ProcessParameters->ImagePathName; + } + RtlUnicodeStringToAnsiString( &AnsiString, p, TRUE ); + s = AnsiString.Buffer; + n = AnsiString.Length; + if (s != NULL) { + d = RtlAllocateHeap( Peb->ProcessHeap, 0, n+2 ); + while (*s) { + // + // Skip over any white space. + // + + while (*s && *s <= ' ') { + s++; + } + + // + // Copy token to next white space separator and null terminate + // + + if (*s) { + *dst++ = d; + argc++; + while (*s > ' ') { + *d++ = *s++; + } + *d++ = '\0'; + } + } + } + *dst++ = NULL; + + envp = dst; + s = ProcessParameters->Environment; + if (s != NULL) { + while (*s) { + *dst++ = s; + while (*s++) { + ; + } + } + } + *dst++ = NULL; + } + + if (DebugParameter != 0) { + DbgBreakPoint(); + } + + NtTerminateProcess( NtCurrentProcess(), + main( argc, argv, envp, DebugParameter ) + ); + + BadPointer = (PULONG)1; + *BadPointer = 0; +} diff --git a/private/urtl/turtl.c b/private/urtl/turtl.c new file mode 100644 index 000000000..6d0fa7af5 --- /dev/null +++ b/private/urtl/turtl.c @@ -0,0 +1,134 @@ +/*++ + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + turtl.c + +Abstract: + + Test program for the NT OS User Mode Runtime Library (URTL) + +Author: + + Steve Wood (stevewo) 18-Aug-1989 + +Revision History: + +--*/ + +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> + +NTSTATUS +main( + int argc, + char *argv[], + char *envp[] + ) +{ + NTSTATUS Status; + STRING ImagePathName; + CHAR ImageNameBuffer[ 128 ]; + RTL_USER_PROCESS_INFORMATION ProcessInformation; + PRTL_USER_PROCESS_PARAMETERS ProcessParameters; + ULONG i, CountBytes, envc, Bogus; + PSTRING DstString; + PCH Src, Dst; + +#if DBG + DbgPrint( "Entering URTL User Mode Test Program\n" ); + DbgPrint( "argc = %ld\n", argc ); + for (i=0; i<=argc; i++) { + DbgPrint( "argv[ %ld ]: %s\n", + i, + argv[ i ] ? argv[ i ] : "<NULL>" + ); + } + DbgPrint( "\n" ); + for (i=0; envp[i]; i++) { + DbgPrint( "envp[ %ld ]: %s\n", i, envp[ i ] ); + } +#endif + envc = 0; + for (i=0; envp[i]; i++) { + envc++; + } + if (envc > argc) { + envc = argc; + } + CountBytes = sizeof( *ProcessParameters ) + + argc * sizeof( STRING ) + envc * sizeof( STRING ); + for (i=0; i<argc; i++) { + CountBytes += strlen( argv[ i ] ); + } + for (i=0; i<envc; i++) { + CountBytes += strlen( envp[ i ] ); + } + ProcessParameters = (PRTL_USER_PROCESS_PARAMETERS)RtlAllocate( CountBytes ); + DstString = (PSTRING)((PCH)ProcessParameters + + sizeof( *ProcessParameters )); + ProcessParameters->TotalLength = CountBytes; + ProcessParameters->ArgumentCount = argc; + ProcessParameters->Arguments = DstString; + DstString += argc; + ProcessParameters->VariableCount = envc; + ProcessParameters->Variables = DstString; + DstString += envc; + Dst = (PCH)DstString; + DstString = ProcessParameters->Arguments; + for (i=0; i<argc; i++) { + DstString->Buffer = Dst; + Src = argv[ i ]; + while (*Dst++ = *Src++) { + DstString->Length++; + } + DstString->MaximumLength = DstString->Length + 1; + DstString++; + } + for (i=0; i<envc; i++) { + DstString->Buffer = Dst; + Src = envp[ i ]; + while (*Dst++ = *Src++) { + DstString->Length++; + } + DstString->MaximumLength = DstString->Length + 1; + DstString++; + } + RtlDeNormalizeProcessParameters( ProcessParameters ); + + ImagePathName.Buffer = ImageNameBuffer; + ImagePathName.Length = 0; + ImagePathName.MaximumLength = sizeof( ImageNameBuffer ); + if (RtlResolveImageName( "TURTL1.SIM", &ImagePathName )) { + Status = RtlCreateUserProcess( &ImagePathName, + NULL, + NULL, + NULL, + TRUE, + ProcessParameters, + &ProcessInformation, + NULL + ); + if (NT_SUCCESS( Status )) { + Status = NtResumeThread( ProcessInformation.Thread, &Bogus ); + if (NT_SUCCESS( Status )) { +#if DBG + DbgPrint( "URTL waiting for URTL1...\n" ); +#endif + Status = NtWaitForSingleObject( ProcessInformation.Process, + TRUE, + NULL + ); + } + } + } + +#if DBG + DbgPrint( "Leaving URTL User Mode Test Program\n" ); +#endif + + return( Status ); +} diff --git a/private/urtl/turtl1.c b/private/urtl/turtl1.c new file mode 100644 index 000000000..9e8f8f90f --- /dev/null +++ b/private/urtl/turtl1.c @@ -0,0 +1,50 @@ +/*++ + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + turtl1.c + +Abstract: + + Sub-Test program for the NT OS User Mode Runtime Library (URTL) + +Author: + + Steve Wood (stevewo) 18-Aug-1989 + +Revision History: + +--*/ + +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> + +NTSTATUS +main( + int argc, + char *argv[], + char *envp[] + ) +{ + ULONG i; + + DbgPrint( "Entering URTL1 User Mode Test Program\n" ); + DbgPrint( "argc = %ld\n", argc ); + for (i=0; i<=argc; i++) { + DbgPrint( "argv[ %ld ]: %s\n", + i, + argv[ i ] ? argv[ i ] : "<NULL>" + ); + } + DbgPrint( "\n" ); + for (i=0; envp[i]; i++) { + DbgPrint( "envp[ %ld ]: %s\n", i, envp[ i ] ); + } + + DbgPrint( "Leaving URTL1 User Mode Test Program\n" ); + + return( STATUS_SUCCESS ); +} diff --git a/private/urtl/uheap.c b/private/urtl/uheap.c new file mode 100644 index 000000000..1cbe7c36b --- /dev/null +++ b/private/urtl/uheap.c @@ -0,0 +1,346 @@ +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> + +#include <stdlib.h> + +BOOLEAN DebugFlag; + +PVOID HeapHandle; + +PVOID +TestAlloc( + IN ULONG Size + ) +{ + PVOID a; + + if ((a = RtlAllocateHeap( HeapHandle, 0, Size )) == NULL) { + RtlValidateHeap( HeapHandle, TRUE ); + DbgPrint( "\nUHEAP: RtlAllocateHeap( %lx ) failed\n", Size ); + DbgBreakPoint(); + NtTerminateProcess( NtCurrentProcess(), STATUS_UNSUCCESSFUL ); + } + + if (DebugFlag) { + DbgPrint( "\n" ); + DbgPrint( "\nRtlAllocateHeap( %lx ) => %lx\n", Size, a ); + } + + if (!RtlValidateHeap( HeapHandle, DebugFlag )) { + NtTerminateProcess( NtCurrentProcess(), STATUS_UNSUCCESSFUL ); + } + + return( a ); +} + + +PVOID +TestFree( + IN PVOID BaseAddress, + IN ULONG Size + ) +{ + PVOID a; + + if ((a = RtlFreeHeap( HeapHandle, 0, BaseAddress )) != NULL) { + DbgPrint( "\nUHEAP: RtlFreeHeap( %lx ) failed\n", BaseAddress ); + RtlValidateHeap( HeapHandle, TRUE ); + DbgBreakPoint(); + NtTerminateProcess( NtCurrentProcess(), STATUS_UNSUCCESSFUL ); + } + + if (DebugFlag) { + DbgPrint( "\n" ); + DbgPrint( "\nRtlFreeHeap( %lx ) => %lx\n", BaseAddress, a ); + } + + if (!RtlValidateHeap( HeapHandle, DebugFlag )) { + NtTerminateProcess( NtCurrentProcess(), STATUS_UNSUCCESSFUL ); + } + return( a ); +} + + +BOOLEAN +TestHeap( + IN PVOID UserHeapBase, + IN BOOLEAN Serialize, + IN BOOLEAN Sparse, + IN ULONG GrowthThreshold, + IN ULONG InitialSize + ) +{ + PVOID a1,a2,a3,a4; + DWORD Flags; + + Flags = 0; + if (!Serialize) { + Flags |= HEAP_NO_SERIALIZE; + } + + if (!Sparse) { + Flags |= HEAP_GROWABLE; + } + + HeapHandle = RtlCreateHeap( Flags, + UserHeapBase, + InitialSize, + 0, + 0, + GrowthThreshold + ); + if ( HeapHandle == NULL ) { + DbgPrint( "UHEAP: RtlCreateHeap failed\n" ); + DbgBreakPoint(); + goto exit; + } + if (!RtlValidateHeap( HeapHandle, DebugFlag )) { + NtTerminateProcess( NtCurrentProcess(), STATUS_UNSUCCESSFUL ); + } + + + // + // TEST 0: + // Allocate and free a large chunk of memory so that the following + // tests are valid. + // + + DbgPrint( "UHEAP: Test #0\n" ); + a1 = TestAlloc( 4096-16 ); + TestFree( a1, 0 ); + + + // + // TEST 1: + // Allocate three chunks, deallocate the middle one, and reallocate it. + // + + DbgPrint( "UHEAP: Test #1\n" ); + a1 = TestAlloc( 16 ); + a2 = TestAlloc( 32 ); + a3 = TestAlloc( 112 ); + TestFree( a2, 32 ); + a4 = TestAlloc( 32 ); + + + // + // TEST 2: + // Deallocate first chunk and reallocate it. + // + + DbgPrint( "UHEAP: Test #2\n" ); + TestFree( a1, 16 ); + a4 = TestAlloc( 16 ); + + + // + // TEST 3: + // Deallocate last chunk and reallocate it. + // + + DbgPrint( "UHEAP: Test #3\n" ); + TestFree( a3, 112 ); + a4 = TestAlloc( 112 ); + + + // + // TEST 4: + // Deallocate last chunk and reallocate larger one. + // + + DbgPrint( "UHEAP: Test #4\n" ); + TestFree( a4, 112 ); + a4 = TestAlloc( 112+64 ); + + + // + // TEST 5: + // Deallocate first two chunks and reallocate combined one. + // + + DbgPrint( "UHEAP: Test #5\n" ); + TestFree( a1, 16 ); + TestFree( a2, 32 ); + a4 = TestAlloc( 16+32-4 ); + + + // + // TEST 6: + // There should be room between blocks 2 and 3 for a small allocation. + // Make sure zero byte allocations work. + // + + DbgPrint( "UHEAP: Test #6\n" ); + a4 = TestAlloc( 0 ); + + + // + // TEST 7: + // Deallocate last two chunks and reallocate one. Address should change. + // + + DbgPrint( "UHEAP: Test #7\n" ); + TestFree( a3, 112+64 ); + TestFree( a4, 0 ); + a3 = TestAlloc( 112 ); + + + // + // TEST 8: + // Deallocate everything and make sure it can be reallocated. + // + + DbgPrint( "UHEAP: Test #8\n" ); + TestFree( a1, 16+32-4 ); + TestFree( a3, 112 ); + a2 = TestAlloc( 200 ); + + + // + // TEST 9: + // Allocate more than is committed. + // + + DbgPrint( "UHEAP: Test #9\n" ); + a1 = TestAlloc( 100000 ); + TestFree( a2, 200 ); + TestFree( a1, 100000 ); + + + // + // TEST 10: + // Allocate more than maximum size of heap + // + + DbgPrint( "UHEAP: Test #10\n" ); + a3 = TestAlloc( 100000 ); + TestFree( a3, 100000 ); + + + // + // TEST 11: + // Destroy the heap + // + + DbgPrint( "UHEAP: Test #11\n" ); + HeapHandle = RtlDestroyHeap( HeapHandle ); + if ( HeapHandle != NULL ) { + DbgPrint( "UHEAP: RtlDestroyHeap failed\n" ); + DbgBreakPoint(); + goto exit; + } + + return( TRUE ); + +exit: + if (HeapHandle != NULL) { + HeapHandle = RtlDestroyHeap( HeapHandle ); + } + + return( FALSE ); +} + + +VOID +Usage( VOID ) +{ + DbgPrint( "Usage: UHEAP [-s ReserveSize] | [-g InitialSize GrowthThreshold]\n" ); + + (VOID)NtTerminateProcess( NtCurrentProcess(), STATUS_UNSUCCESSFUL ); +} + +NTSTATUS +main( + int argc, + char *argv[], + char *envp[], + ULONG DebugParameter OPTIONAL + ) +{ + NTSTATUS Status; + PCH s; + PVOID UserHeapBase = NULL; + BOOLEAN Serialize = FALSE; + BOOLEAN Sparse = FALSE; + ULONG GrowthThreshold = 0; + ULONG InitialSize = 0x8000; + + DebugFlag = DebugParameter; + + DbgPrint( "** Start of User Mode Test of RtlAllocateHeap/RtlFreeHeap **\n" ); + + while (--argc) { + s = *++argv; + if (*s == '-') { + switch( *++s ) { + case 'x': + case 'X': + Serialize = TRUE; + break; + + case 's': + case 'S': + Sparse = TRUE; + if (--argc) { + InitialSize = atoi( *++argv ); + Status = NtAllocateVirtualMemory( NtCurrentProcess(), + (PVOID *)&UserHeapBase, + 0, + &InitialSize, + MEM_RESERVE, + PAGE_READWRITE + ); + if (!NT_SUCCESS( Status )) { + DbgPrint( "UHEAP: Unable to allocate heap - 0x%lx bytes\n", + InitialSize + ); + Usage(); + } + } + else { + Usage(); + } + break; + + case 'g': + case 'G': + if (argc >= 2) { + argc -= 2; + InitialSize = atoi( *++argv ); + GrowthThreshold = atoi( *++argv ); + } + else { + Usage(); + } + break; + + default: + Usage(); + } + } + else { + Usage(); + } + } + + TestHeap( UserHeapBase, + Serialize, + Sparse, + GrowthThreshold, + InitialSize + ); + + if (UserHeapBase != NULL) { + Status = NtFreeVirtualMemory( NtCurrentProcess(), + (PVOID *)&UserHeapBase, + &InitialSize, + MEM_RELEASE + ); + } + + DbgPrint( "** End of User Mode Test of RtlAllocateHeap/RtlFreeHeap **\n" ); + + (VOID)NtTerminateProcess( NtCurrentProcess(), STATUS_SUCCESS ); + return STATUS_SUCCESS; +} |