summaryrefslogtreecommitdiffstats
path: root/private/urtl
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/urtl
downloadNT4.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/makefile6
-rw-r--r--private/urtl/sources38
-rw-r--r--private/urtl/startup.c136
-rw-r--r--private/urtl/turtl.c134
-rw-r--r--private/urtl/turtl1.c50
-rw-r--r--private/urtl/uheap.c346
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;
+}