From 38a1364aae29185e8a3d86d14ee8ad150dbdf3f4 Mon Sep 17 00:00:00 2001 From: "KJK::Hyperion" Date: Tue, 29 Apr 2003 02:17:01 +0000 Subject: [PATCH] - new statically linked library ROSRTL, for code to be shared among system DLLs - user-mode thread creation code moved to ROSRTL - user-mode thread context initialization code fixed - LdrInitializeThunk() breakin stub fixed svn path=/trunk/; revision=4615 --- reactos/Makefile | 2 +- reactos/include/napi/i386/floatsave.h | 11 + reactos/include/rosrtl/thread.h | 53 ++++ reactos/lib/kernel32/k32.h | 1 + reactos/lib/kernel32/makefile | 4 +- reactos/lib/kernel32/process/create.c | 63 +++-- reactos/lib/kernel32/thread/thread.c | 80 ++++-- reactos/lib/ntdll/def/ntdll.def | 5 +- reactos/lib/ntdll/def/ntdll.edf | 5 +- reactos/lib/ntdll/ldr/entry.S | 12 +- reactos/lib/ntdll/makefile | 4 +- reactos/lib/ntdll/rtl/thread.c | 368 +------------------------- reactos/lib/rosrtl/makefile | 23 ++ reactos/lib/rosrtl/thread/context.c | 105 ++++++++ reactos/lib/rosrtl/thread/create.c | 260 ++++++++++++++++++ 15 files changed, 584 insertions(+), 412 deletions(-) create mode 100644 reactos/include/napi/i386/floatsave.h create mode 100644 reactos/include/rosrtl/thread.h create mode 100644 reactos/lib/rosrtl/makefile create mode 100644 reactos/lib/rosrtl/thread/context.c create mode 100644 reactos/lib/rosrtl/thread/create.c diff --git a/reactos/Makefile b/reactos/Makefile index 56431ab23f3..3ee13d0980f 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -33,7 +33,7 @@ LIB_FSLIB = vfatlib # User mode libraries # advapi32 crtdll fmifs gdi32 kernel32 libpcap packet msafd msvcrt ntdll ole32 # oleaut32 epsapi psapi rpcrt4 secur32 shell32 user32 version ws2help ws2_32 wsock32 wshirda -DLLS = advapi32 crtdll fmifs freetype gdi32 kernel32 packet msafd msvcrt ntdll \ +DLLS = rosrtl advapi32 crtdll fmifs freetype gdi32 kernel32 packet msafd msvcrt ntdll \ epsapi psapi secur32 user32 version winedbgc ws2help ws2_32 wsock32 wshirda zlib #winmm SUBSYS = smss win32k csrss ntvdm diff --git a/reactos/include/napi/i386/floatsave.h b/reactos/include/napi/i386/floatsave.h new file mode 100644 index 00000000000..1785143937d --- /dev/null +++ b/reactos/include/napi/i386/floatsave.h @@ -0,0 +1,11 @@ +#ifndef __NAPI_I386_FLOATSAVE_H__ +#define __NAPI_I386_FLOATSAVE_H__ + +#define FLOAT_SAVE_CONTROL (0xFFFF037F) +#define FLOAT_SAVE_STATUS (0xFFFF0000) +#define FLOAT_SAVE_TAG (0xFFFFFFFF) +#define FLOAT_SAVE_DATA (0xFFFF0000) + +#endif /* __NAPI_I386_FLOATSAVE_H__ */ + +/* EOF */ diff --git a/reactos/include/rosrtl/thread.h b/reactos/include/rosrtl/thread.h new file mode 100644 index 00000000000..3cca46a3b9c --- /dev/null +++ b/reactos/include/rosrtl/thread.h @@ -0,0 +1,53 @@ +/* $Id: thread.h,v 1.1 2003/04/29 02:17:00 hyperion Exp $ + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +NTSTATUS STDCALL RtlRosCreateUserThreadEx +( + IN HANDLE ProcessHandle, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN BOOLEAN CreateSuspended, + IN LONG StackZeroBits, + IN OUT PULONG StackReserve OPTIONAL, + IN OUT PULONG StackCommit OPTIONAL, + IN PTHREAD_START_ROUTINE StartAddress, + OUT PHANDLE ThreadHandle OPTIONAL, + OUT PCLIENT_ID ClientId OPTIONAL, + IN ULONG ParameterCount, + IN ULONG_PTR * Parameters +); + +NTSTATUS CDECL RtlRosCreateUserThreadVa +( + IN HANDLE ProcessHandle, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN BOOLEAN CreateSuspended, + IN LONG StackZeroBits, + IN OUT PULONG StackReserve OPTIONAL, + IN OUT PULONG StackCommit OPTIONAL, + IN PTHREAD_START_ROUTINE StartAddress, + OUT PHANDLE ThreadHandle OPTIONAL, + OUT PCLIENT_ID ClientId OPTIONAL, + IN ULONG ParameterCount, + ... +); + +NTSTATUS NTAPI RtlRosInitializeContextEx +( + IN HANDLE ProcessHandle, + IN PCONTEXT Context, + IN PTHREAD_START_ROUTINE StartAddress, + IN PUSER_STACK UserStack, + IN ULONG ParameterCount, + IN ULONG_PTR * Parameters +); + +#ifdef __cplusplus +} +#endif + +/* EOF */ diff --git a/reactos/lib/kernel32/k32.h b/reactos/lib/kernel32/k32.h index 018d32af19e..6b400f9582d 100755 --- a/reactos/lib/kernel32/k32.h +++ b/reactos/lib/kernel32/k32.h @@ -24,3 +24,4 @@ #include #include #include +#include diff --git a/reactos/lib/kernel32/makefile b/reactos/lib/kernel32/makefile index 4b9fc02f281..991f6667537 100644 --- a/reactos/lib/kernel32/makefile +++ b/reactos/lib/kernel32/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.63 2003/04/14 01:19:06 hyperion Exp $ +# $Id: makefile,v 1.64 2003/04/29 02:16:59 hyperion Exp $ PATH_TO_TOP = ../.. @@ -10,7 +10,7 @@ TARGET_BASE = 0x77f00000 TARGET_LFLAGS = -nostartfiles -nostdlib -TARGET_SDKLIBS = ntdll.a +TARGET_SDKLIBS = rosrtl.a ntdll.a TARGET_GCCLIBS = gcc diff --git a/reactos/lib/kernel32/process/create.c b/reactos/lib/kernel32/process/create.c index 5ec8980e4ba..045e3116ebe 100644 --- a/reactos/lib/kernel32/process/create.c +++ b/reactos/lib/kernel32/process/create.c @@ -1,4 +1,4 @@ -/* $Id: create.c,v 1.66 2003/04/26 23:13:28 hyperion Exp $ +/* $Id: create.c,v 1.67 2003/04/29 02:16:59 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -93,21 +93,6 @@ VOID STDCALL RtlRosR32AttribsToNativeAttribsNamed } } -NTSTATUS CDECL RtlCreateUserThreadVa -( - HANDLE ProcessHandle, - POBJECT_ATTRIBUTES ObjectAttributes, - BOOLEAN CreateSuspended, - LONG StackZeroBits, - PULONG StackReserve, - PULONG StackCommit, - PTHREAD_START_ROUTINE StartAddress, - PHANDLE ThreadHandle, - PCLIENT_ID ClientId, - ULONG ParameterCount, - ... -); - BOOL STDCALL CreateProcessA ( LPCSTR lpApplicationName, @@ -408,8 +393,39 @@ HANDLE STDCALL KlCreateFirstThread else pTrueStartAddress = (PVOID)RtlBaseProcessStartRoutine; + DPRINT + ( + "RtlRosCreateUserThreadVa\n" + "(\n" + " ProcessHandle %p,\n" + " ObjectAttributes %p,\n" + " CreateSuspended %d,\n" + " StackZeroBits %d,\n" + " StackReserve %lu,\n" + " StackCommit %lu,\n" + " StartAddress %p,\n" + " ThreadHandle %p,\n" + " ClientId %p,\n" + " ParameterCount %u,\n" + " Parameters[0] %p,\n" + " Parameters[1] %p\n" + ")\n", + ProcessHandle, + &oaThreadAttribs, + dwCreationFlags & CREATE_SUSPENDED, + 0, + Sii->StackReserve, + Sii->StackCommit, + pTrueStartAddress, + &hThread, + &cidClientId, + 2, + lpStartAddress, + PEB_BASE + ); + /* create the first thread */ - nErrCode = RtlCreateUserThreadVa + nErrCode = RtlRosCreateUserThreadVa ( ProcessHandle, &oaThreadAttribs, @@ -431,8 +447,21 @@ HANDLE STDCALL KlCreateFirstThread SetLastErrorByStatus(nErrCode); return NULL; } + + DPRINT + ( + "StackReserve %p\n" + "StackCommit %p\n" + "ThreadHandle %p\n" + "ClientId.UniqueThread %p\n", + Sii->StackReserve, + Sii->StackCommit, + hThread, + cidClientId.UniqueThread + ); /* success */ + if(lpThreadId) *lpThreadId = (DWORD)cidClientId.UniqueThread; return hThread; } diff --git a/reactos/lib/kernel32/thread/thread.c b/reactos/lib/kernel32/thread/thread.c index b81ffd6e3bb..cd2eb52b2cb 100644 --- a/reactos/lib/kernel32/thread/thread.c +++ b/reactos/lib/kernel32/thread/thread.c @@ -1,4 +1,4 @@ -/* $Id: thread.c,v 1.37 2003/04/26 23:13:28 hyperion Exp $ +/* $Id: thread.c,v 1.38 2003/04/29 02:16:59 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -22,21 +22,6 @@ /* FUNCTIONS *****************************************************************/ /* FIXME: please put this in some header */ -extern NTSTATUS CDECL RtlCreateUserThreadVa -( - HANDLE ProcessHandle, - POBJECT_ATTRIBUTES ObjectAttributes, - BOOLEAN CreateSuspended, - LONG StackZeroBits, - PULONG StackReserve, - PULONG StackCommit, - PTHREAD_START_ROUTINE StartAddress, - PHANDLE ThreadHandle, - PCLIENT_ID ClientId, - ULONG ParameterCount, - ... -); - static EXCEPTION_DISPOSITION __cdecl _except_handler(EXCEPTION_RECORD *ExceptionRecord, void * EstablisherFrame, @@ -113,6 +98,24 @@ HANDLE STDCALL CreateRemoteThread PIMAGE_NT_HEADERS pinhHeader = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress); + DPRINT + ( + "hProcess %08X\n" + "lpThreadAttributes %08X\n" + "dwStackSize %08X\n" + "lpStartAddress %08X\n" + "lpParameter %08X\n" + "dwCreationFlags %08X\n" + "lpThreadId %08X\n", + hProcess, + lpThreadAttributes, + dwStackSize, + lpStartAddress, + lpParameter, + dwCreationFlags, + lpThreadId + ); + /* FIXME: do more checks - e.g. the image may not have an optional header */ if(pinhHeader == NULL) { @@ -163,8 +166,39 @@ HANDLE STDCALL CreateRemoteThread oaThreadAttribs.SecurityDescriptor = lpThreadAttributes->lpSecurityDescriptor; } + DPRINT + ( + "RtlRosCreateUserThreadVa\n" + "(\n" + " ProcessHandle %p,\n" + " ObjectAttributes %p,\n" + " CreateSuspended %d,\n" + " StackZeroBits %d,\n" + " StackReserve %lu,\n" + " StackCommit %lu,\n" + " StartAddress %p,\n" + " ThreadHandle %p,\n" + " ClientId %p,\n" + " ParameterCount %u,\n" + " Parameters[0] %p,\n" + " Parameters[1] %p\n" + ")\n", + hProcess, + &oaThreadAttribs, + dwCreationFlags & CREATE_SUSPENDED, + 0, + nStackReserve, + nStackCommit, + ThreadStartup, + &hThread, + &cidClientId, + 2, + lpStartAddress, + lpParameter + ); + /* create the thread */ - nErrCode = RtlCreateUserThreadVa + nErrCode = RtlRosCreateUserThreadVa ( hProcess, &oaThreadAttribs, @@ -186,6 +220,18 @@ HANDLE STDCALL CreateRemoteThread SetLastErrorByStatus(nErrCode); return NULL; } + + DPRINT + ( + "StackReserve %p\n" + "StackCommit %p\n" + "ThreadHandle %p\n" + "ClientId.UniqueThread %p\n", + nStackReserve, + nStackCommit, + hThread, + cidClientId.UniqueThread + ); /* success */ if(lpThreadId) *lpThreadId = (DWORD)cidClientId.UniqueThread; diff --git a/reactos/lib/ntdll/def/ntdll.def b/reactos/lib/ntdll/def/ntdll.def index b5466ab6c8c..0951c1742f4 100644 --- a/reactos/lib/ntdll/def/ntdll.def +++ b/reactos/lib/ntdll/def/ntdll.def @@ -1,4 +1,4 @@ -; $Id: ntdll.def,v 1.97 2003/04/26 23:13:29 hyperion Exp $ +; $Id: ntdll.def,v 1.98 2003/04/29 02:16:59 hyperion Exp $ ; ; ReactOS Operating System ; @@ -347,8 +347,6 @@ RtlCreateUnicodeStringFromAsciiz@8 RtlCreateUserProcess@40 ;RtlCreateUserSecurityObject RtlCreateUserThread@40 -RtlCreateUserThread@44 -RtlCreateUserThreadVa RtlCustomCPToUnicodeN@24 ;RtlCutoverTimeToSystemTime RtlDeNormalizeProcessParams@4 @@ -450,7 +448,6 @@ RtlInitUnicodeString@8 ;RtlInitializeAtomPackage RtlInitializeBitMap@12 RtlInitializeContext@20 -RtlInitializeContextEx@24 RtlInitializeCriticalSection@4 ;RtlInitializeGenericTable RtlInitializeHandleTable@12 diff --git a/reactos/lib/ntdll/def/ntdll.edf b/reactos/lib/ntdll/def/ntdll.edf index 8f75ed35310..1ff886186dd 100644 --- a/reactos/lib/ntdll/def/ntdll.edf +++ b/reactos/lib/ntdll/def/ntdll.edf @@ -1,4 +1,4 @@ -; $Id: ntdll.edf,v 1.86 2003/04/26 23:13:29 hyperion Exp $ +; $Id: ntdll.edf,v 1.87 2003/04/29 02:16:59 hyperion Exp $ ; ; ReactOS Operating System ; @@ -347,8 +347,6 @@ RtlCreateUnicodeStringFromAsciiz=RtlCreateUnicodeStringFromAsciiz@8 RtlCreateUserProcess=RtlCreateUserProcess@40 ;RtlCreateUserSecurityObject RtlCreateUserThread=RtlCreateUserThread@40 -RtlCreateUserThreadEx=RtlCreateUserThreadEx@44 -RtlCreateUserThreadVa=RtlCreateUserThreadVa RtlCustomCPToUnicodeN=RtlCustomCPToUnicodeN@24 ;RtlCutoverTimeToSystemTime RtlDeNormalizeProcessParams=RtlDeNormalizeProcessParams@4 @@ -449,7 +447,6 @@ RtlInitUnicodeString=RtlInitUnicodeString@8 ;RtlInitializeAtomPackage RtlInitializeBitMap=RtlInitializeBitMap@12 RtlInitializeContext=RtlInitializeContext@20 -RtlInitializeContextEx=RtlInitializeContextEx@24 RtlInitializeCriticalSection=RtlInitializeCriticalSection@4 ;RtlInitializeGenericTable RtlInitializeHandleTable=RtlInitializeHandleTable@12 diff --git a/reactos/lib/ntdll/ldr/entry.S b/reactos/lib/ntdll/ldr/entry.S index 7e239860013..78d6190238e 100755 --- a/reactos/lib/ntdll/ldr/entry.S +++ b/reactos/lib/ntdll/ldr/entry.S @@ -5,14 +5,14 @@ .globl _LdrInitializeThunk@16 _LdrInitializeThunk@16: #if defined(_M_IX86) - nop /* breakin overwrites this with "int 3" */ - jmp ___true_LdrInitializeThunk@16 + nop /* breakin overwrites this with "int 3" */ + jmp ___true_LdrInitializeThunk@16 #elif defined(_M_ALPHA) - nop /* breakin overwrites this with "call_pal bpt" */ - "br" + nop /* breakin overwrites this with "call_pal bpt" */ + br ___true_LdrInitializeThunk@16 #elif defined(_M_MIPS) - nop /* breakin overwrites this with "break" */ - j ___true_LdrInitializeThunk@16 + nop /* breakin overwrites this with "break" */ + j ___true_LdrInitializeThunk@16 #else #error Unsupported architecture. #endif diff --git a/reactos/lib/ntdll/makefile b/reactos/lib/ntdll/makefile index ffef2e751c5..ed3aaadda99 100644 --- a/reactos/lib/ntdll/makefile +++ b/reactos/lib/ntdll/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.82 2003/04/27 14:45:52 chorns Exp $ +# $Id: makefile,v 1.83 2003/04/29 02:17:00 hyperion Exp $ PATH_TO_TOP = ../.. @@ -16,6 +16,8 @@ TARGET_LFLAGS = -Wl,--file-alignment,0x1000 \ -Wl,--section-alignment,0x1000 \ -nostartfiles +TARGET_SDKLIBS = rosrtl.a + TARGET_GCCLIBS = gcc TARGET_BASE = 0x77f60000 diff --git a/reactos/lib/ntdll/rtl/thread.c b/reactos/lib/ntdll/rtl/thread.c index 232c0bbd95d..fc39ff3e3f1 100644 --- a/reactos/lib/ntdll/rtl/thread.c +++ b/reactos/lib/ntdll/rtl/thread.c @@ -10,292 +10,24 @@ * 25/04/03: Near rewrite. Made code more readable, replaced * INITIAL_TEB with USER_STACK, added support for * fixed-size stacks + * 28/04/03: Moved all code to a new statically linked + * library (ROSRTL) so it can be shared with + * kernel32.dll without exporting non-standard + * functions from ntdll.dll */ /* INCLUDES *****************************************************************/ #include -#include #include #include +#include -//#define NDEBUG +#define NDEBUG #include - /* FUNCTIONS ***************************************************************/ -NTSTATUS STDCALL RtlInitializeContextEx -( - HANDLE ProcessHandle, - PCONTEXT Context, - PTHREAD_START_ROUTINE StartAddress, - PUSER_STACK UserStack, - ULONG ParameterCount, - ULONG_PTR * Parameters -); - -NTSTATUS STDCALL RtlCreateUserThreadEx -( - HANDLE ProcessHandle, - POBJECT_ATTRIBUTES ObjectAttributes, - BOOLEAN CreateSuspended, - LONG StackZeroBits, - PULONG StackReserve, - PULONG StackCommit, - PTHREAD_START_ROUTINE StartAddress, - PHANDLE ThreadHandle, - PCLIENT_ID ClientId, - ULONG ParameterCount, - ULONG_PTR * Parameters -) -{ - USER_STACK usUserStack; - OBJECT_ATTRIBUTES oaThreadAttribs; - /* FIXME: read the defaults from the executable image */ - ULONG_PTR nStackReserve = 0x100000; - /* FIXME: when we finally have exception handling, make this PAGE_SIZE */ - ULONG_PTR nStackCommit = 0x100000; - ULONG_PTR nSize = 0; - PVOID pStackLowest = NULL; - ULONG nDummy; - CONTEXT ctxInitialContext; - NTSTATUS nErrCode; - HANDLE hThread; - CLIENT_ID cidClientId; - - ULONG i; - - DPRINT("blah\n"); - - for(i = 0; i < ParameterCount; ++ i) - DPRINT("parameter %lu = %p\n", i, Parameters[i]); - - DPRINT("doh\n"); - - if(ThreadHandle == NULL) ThreadHandle = &hThread; - if(ClientId == NULL) ClientId = &cidClientId; - - if(StackReserve == NULL) StackReserve = &nStackReserve; - else ROUNDUP(*StackReserve, PAGE_SIZE); - - if(StackCommit == NULL) StackCommit = &nStackCommit; - else ROUNDUP(*StackCommit, PAGE_SIZE); - -#if 0 - /* the stack commit size must be equal to or less than the reserve size */ - if(*StackCommit > *StackReserve) *StackCommit = *StackReserve; -#else - /* FIXME: no SEH, no guard pages */ - *StackCommit = *StackReserve; -#endif - - usUserStack.FixedStackBase = NULL; - usUserStack.FixedStackLimit = NULL; - usUserStack.ExpandableStackBase = NULL; - usUserStack.ExpandableStackLimit = NULL; - usUserStack.ExpandableStackBottom = NULL; - - /* FIXME: this code assumes a stack growing downwards */ - /* fixed stack */ - if(*StackCommit == *StackReserve) - { - DPRINT("Fixed stack\n"); - - usUserStack.FixedStackLimit = NULL; - - /* allocate the stack */ - nErrCode = NtAllocateVirtualMemory - ( - ProcessHandle, - &(usUserStack.FixedStackLimit), - StackZeroBits, - StackReserve, - MEM_RESERVE | MEM_COMMIT, - PAGE_READWRITE - ); - - /* failure */ - if(!NT_SUCCESS(nErrCode)) goto l_Fail; - - /* store the highest (first) address of the stack */ - usUserStack.FixedStackBase = - (PUCHAR)(usUserStack.FixedStackLimit) + *StackReserve; - - *StackCommit = *StackReserve; - - DPRINT("Stack base %p\n", usUserStack.FixedStackBase); - DPRINT("Stack limit %p\n", usUserStack.FixedStackLimit); - } - /* expandable stack */ - else - { - ULONG_PTR nGuardSize = PAGE_SIZE; - PVOID pGuardBase; - - DPRINT("Expandable stack\n"); - - usUserStack.FixedStackLimit = NULL; - usUserStack.FixedStackBase = NULL; - usUserStack.ExpandableStackBottom = NULL; - - /* reserve the stack */ - nErrCode = NtAllocateVirtualMemory - ( - ProcessHandle, - &(usUserStack.ExpandableStackBottom), - StackZeroBits, - StackReserve, - MEM_RESERVE, - PAGE_READWRITE - ); - - /* failure */ - if(!NT_SUCCESS(nErrCode)) goto l_Fail; - - DPRINT("Reserved %08X bytes\n", *StackReserve); - - /* expandable stack base - the highest address of the stack */ - usUserStack.ExpandableStackBase = - (PUCHAR)(usUserStack.ExpandableStackBottom) + *StackReserve; - - /* expandable stack limit - the lowest committed address of the stack */ - usUserStack.ExpandableStackLimit = - (PUCHAR)(usUserStack.ExpandableStackBase) - *StackCommit; - - DPRINT("Stack base %p\n", usUserStack.ExpandableStackBase); - DPRINT("Stack limit %p\n", usUserStack.ExpandableStackLimit); - DPRINT("Stack bottom %p\n", usUserStack.ExpandableStackBottom); - - /* commit as much stack as requested */ - nErrCode = NtAllocateVirtualMemory - ( - ProcessHandle, - &(usUserStack.ExpandableStackLimit), - 0, - StackCommit, - MEM_COMMIT, - PAGE_READWRITE - ); - - /* failure */ - if(!NT_SUCCESS(nErrCode)) goto l_Fail; - - assert((*StackReserve - *StackCommit) >= PAGE_SIZE); - assert((*StackReserve - *StackCommit) % PAGE_SIZE == 0); - - pGuardBase = (PUCHAR)(usUserStack.ExpandableStackLimit) - PAGE_SIZE; - - DPRINT("Guard base %p\n", usUserStack.ExpandableStackBase); - - /* set up the guard page */ - nErrCode = NtAllocateVirtualMemory - ( - ProcessHandle, - &pGuardBase, - 0, - &nGuardSize, - MEM_COMMIT, - PAGE_READWRITE | PAGE_GUARD - ); - - /* failure */ - if(!NT_SUCCESS(nErrCode)) goto l_Fail; - - DPRINT("Guard base %p\n", usUserStack.ExpandableStackBase); - } - - /* initialize the registers and stack for the thread */ - nErrCode = RtlInitializeContextEx - ( - ProcessHandle, - &ctxInitialContext, - StartAddress, - &usUserStack, - ParameterCount, - Parameters - ); - - /* failure */ - if(!NT_SUCCESS(nErrCode)) goto l_Cleanup; - - /* create the thread object */ - nErrCode = NtCreateThread - ( - ThreadHandle, - THREAD_ALL_ACCESS, - ObjectAttributes, - ProcessHandle, - ClientId, - &ctxInitialContext, - &usUserStack, - CreateSuspended - ); - - /* failure */ - if(!NT_SUCCESS(nErrCode)) goto l_Cleanup; - - /* success */ - return STATUS_SUCCESS; - - /* deallocate the stack */ -l_Cleanup: - if(usUserStack.FixedStackLimit) - pStackLowest = usUserStack.FixedStackLimit; - else if(usUserStack.ExpandableStackBottom) - pStackLowest = usUserStack.ExpandableStackBottom; - - /* free the stack, if it was allocated */ - if(pStackLowest != NULL) - NtFreeVirtualMemory(ProcessHandle, &pStackLowest, &nSize, MEM_RELEASE); - - /* failure */ -l_Fail: - assert(!NT_SUCCESS(nErrCode)); - return nErrCode; -} - -NTSTATUS CDECL RtlCreateUserThreadVa -( - HANDLE ProcessHandle, - POBJECT_ATTRIBUTES ObjectAttributes, - BOOLEAN CreateSuspended, - LONG StackZeroBits, - PULONG StackReserve, - PULONG StackCommit, - PTHREAD_START_ROUTINE StartAddress, - PHANDLE ThreadHandle, - PCLIENT_ID ClientId, - ULONG ParameterCount, - ... -) -{ - va_list vaArgs; - NTSTATUS nErrCode; - - va_start(vaArgs, ParameterCount); - - /* FIXME: this code assumes a stack growing downwards */ - nErrCode = RtlCreateUserThreadEx - ( - ProcessHandle, - ObjectAttributes, - CreateSuspended, - StackZeroBits, - StackReserve, - StackCommit, - StartAddress, - ThreadHandle, - ClientId, - ParameterCount, - (ULONG_PTR *)vaArgs - ); - - va_end(vaArgs); - - return nErrCode; -} - NTSTATUS STDCALL RtlCreateUserThread ( HANDLE ProcessHandle, @@ -321,7 +53,7 @@ NTSTATUS STDCALL RtlCreateUserThread SecurityDescriptor ); - return RtlCreateUserThreadEx + return RtlRosCreateUserThreadEx ( ProcessHandle, &oaThreadAttribs, @@ -337,90 +69,6 @@ NTSTATUS STDCALL RtlCreateUserThread ); } -NTSTATUS STDCALL RtlInitializeContextEx -( - HANDLE ProcessHandle, - PCONTEXT Context, - PTHREAD_START_ROUTINE StartAddress, - PUSER_STACK UserStack, - ULONG ParameterCount, - ULONG_PTR * Parameters -) -{ - ULONG nDummy; - PCHAR pStackBase; - PCHAR pStackLimit; - ULONG_PTR nRetAddr = 0xDEADBEEF; - SIZE_T nParamsSize = ParameterCount * sizeof(ULONG_PTR); - NTSTATUS nErrCode; - - if(UserStack->FixedStackBase != NULL && UserStack->FixedStackLimit != NULL) - { - pStackBase = UserStack->FixedStackBase; - pStackLimit = UserStack->FixedStackLimit; - } - else if(UserStack->ExpandableStackBase != NULL) - { - pStackBase = UserStack->ExpandableStackBase; - pStackLimit = UserStack->ExpandableStackLimit; - } - else - return STATUS_BAD_INITIAL_STACK; - - if(pStackBase <= pStackLimit) - return STATUS_BAD_INITIAL_STACK; - - /* too many parameters */ - if((nParamsSize + sizeof(ULONG_PTR)) > (SIZE_T)(pStackBase - pStackLimit)) - return STATUS_STACK_OVERFLOW; - -#if defined(_M_IX86) - memset(Context, 0, sizeof(CONTEXT)); - - Context->ContextFlags = CONTEXT_FULL; - Context->FloatSave.ControlWord = 0xffff037f; - Context->FloatSave.StatusWord = 0xffff0000; - Context->FloatSave.TagWord = 0xffffffff; - Context->FloatSave.DataSelector = 0xffff0000; - Context->Eip = (ULONG_PTR)StartAddress; - Context->SegGs = USER_DS; - Context->SegFs = TEB_SELECTOR; - Context->SegEs = USER_DS; - Context->SegDs = USER_DS; - Context->SegCs = USER_CS; - Context->SegSs = USER_DS; - Context->Esp = (ULONG_PTR)pStackBase - (nParamsSize + sizeof(ULONG_PTR)); - Context->EFlags = ((ULONG_PTR)1 << 1) | ((ULONG_PTR)1 << 9); - - DPRINT("Effective stack base %p\n", Context->Esp); -#else -#error Unsupported architecture -#endif - - /* write the parameters */ - nErrCode = NtWriteVirtualMemory - ( - ProcessHandle, - ((PUCHAR)pStackBase) - nParamsSize, - Parameters, - nParamsSize, - &nDummy - ); - - /* failure */ - if(!NT_SUCCESS(nErrCode)) return nErrCode; - - /* write the return address */ - return NtWriteVirtualMemory - ( - ProcessHandle, - ((PUCHAR)pStackBase) - (nParamsSize + sizeof(ULONG_PTR)), - &nRetAddr, - sizeof(ULONG_PTR), - &nDummy - ); -} - NTSTATUS STDCALL RtlInitializeContext ( HANDLE ProcessHandle, @@ -430,7 +78,7 @@ NTSTATUS STDCALL RtlInitializeContext PUSER_STACK UserStack ) { - return RtlInitializeContextEx + return RtlRosInitializeContextEx ( ProcessHandle, Context, diff --git a/reactos/lib/rosrtl/makefile b/reactos/lib/rosrtl/makefile new file mode 100644 index 00000000000..26ccb6a69b8 --- /dev/null +++ b/reactos/lib/rosrtl/makefile @@ -0,0 +1,23 @@ +# $Id: makefile,v 1.1 2003/04/29 02:17:01 hyperion Exp $ + +PATH_TO_TOP = ../.. + +TARGET_TYPE = library + +TARGET_NAME = rosrtl + +THREAD_OBJECTS = \ + thread/context.o \ + thread/create.o + +TARGET_OBJECTS = $(THREAD_OBJECTS) + +DEP_OBJECTS = $(TARGET_OBJECTS) + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +include $(TOOLS_PATH)/depend.mk + +# EOF diff --git a/reactos/lib/rosrtl/thread/context.c b/reactos/lib/rosrtl/thread/context.c new file mode 100644 index 00000000000..fff85694e87 --- /dev/null +++ b/reactos/lib/rosrtl/thread/context.c @@ -0,0 +1,105 @@ +/* $Id: context.c,v 1.1 2003/04/29 02:17:01 hyperion Exp $ +*/ +/* +*/ + +#include +#include + +#if defined(_M_IX86) +#include +#include +#else +#error Unsupported architecture +#endif + +NTSTATUS NTAPI RtlRosInitializeContextEx +( + IN HANDLE ProcessHandle, + IN PCONTEXT Context, + IN PTHREAD_START_ROUTINE StartAddress, + IN PUSER_STACK UserStack, + IN ULONG ParameterCount, + IN ULONG_PTR * Parameters +) +{ + ULONG nDummy; + PCHAR pStackBase; + PCHAR pStackLimit; + ULONG_PTR nRetAddr = 0xDEADBEEF; + SIZE_T nParamsSize = ParameterCount * sizeof(ULONG_PTR); + NTSTATUS nErrCode; + + /* fixed-size stack */ + if(UserStack->FixedStackBase && UserStack->FixedStackLimit) + { + pStackBase = UserStack->FixedStackBase; + pStackLimit = UserStack->FixedStackLimit; + } + /* expandable stack */ + else if(UserStack->ExpandableStackBase && UserStack->ExpandableStackLimit) + { + pStackBase = UserStack->ExpandableStackBase; + pStackLimit = UserStack->ExpandableStackLimit; + } + /* bad initial stack */ + else + return STATUS_BAD_INITIAL_STACK; + + /* stack base lower than the limit */ + if(pStackBase <= pStackLimit) + return STATUS_BAD_INITIAL_STACK; + +#if defined(_M_IX86) + /* Intel x86: all parameters passed on the stack */ + /* too many parameters */ + if((nParamsSize + sizeof(ULONG_PTR)) > (SIZE_T)(pStackBase - pStackLimit)) + return STATUS_STACK_OVERFLOW; + + memset(Context, 0, sizeof(CONTEXT)); + + /* initialize the context */ + Context->ContextFlags = CONTEXT_FULL; + Context->FloatSave.ControlWord = FLOAT_SAVE_CONTROL; + Context->FloatSave.StatusWord = FLOAT_SAVE_STATUS; + Context->FloatSave.TagWord = FLOAT_SAVE_TAG; + Context->FloatSave.DataSelector = FLOAT_SAVE_DATA; + Context->Eip = (ULONG_PTR)StartAddress; + Context->SegGs = USER_DS; + Context->SegFs = TEB_SELECTOR; + Context->SegEs = USER_DS; + Context->SegDs = USER_DS; + Context->SegCs = USER_CS; + Context->SegSs = USER_DS; + Context->Esp = (ULONG_PTR)pStackBase - (nParamsSize + sizeof(ULONG_PTR)); + Context->EFlags = ((ULONG_PTR)1 << 1) | ((ULONG_PTR)1 << 9); + + /* write the parameters */ + nErrCode = NtWriteVirtualMemory + ( + ProcessHandle, + ((PUCHAR)pStackBase) - nParamsSize, + Parameters, + nParamsSize, + &nDummy + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) return nErrCode; + + /* write the return address */ + return NtWriteVirtualMemory + ( + ProcessHandle, + ((PUCHAR)pStackBase) - (nParamsSize + sizeof(ULONG_PTR)), + &nRetAddr, + sizeof(ULONG_PTR), + &nDummy + ); + +#else +#error Unsupported architecture +#endif +} + +/* EOF */ diff --git a/reactos/lib/rosrtl/thread/create.c b/reactos/lib/rosrtl/thread/create.c new file mode 100644 index 00000000000..af428c7384e --- /dev/null +++ b/reactos/lib/rosrtl/thread/create.c @@ -0,0 +1,260 @@ +/* $Id: create.c,v 1.1 2003/04/29 02:17:01 hyperion Exp $ +*/ +/* +*/ + +#include +#include +#include + +#define NDEBUG +#include + +NTSTATUS STDCALL RtlRosCreateUserThreadEx +( + IN HANDLE ProcessHandle, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN BOOLEAN CreateSuspended, + IN LONG StackZeroBits, + IN OUT PULONG StackReserve OPTIONAL, + IN OUT PULONG StackCommit OPTIONAL, + IN PTHREAD_START_ROUTINE StartAddress, + OUT PHANDLE ThreadHandle OPTIONAL, + OUT PCLIENT_ID ClientId OPTIONAL, + IN ULONG ParameterCount, + IN ULONG_PTR * Parameters +) +{ + USER_STACK usUserStack; + OBJECT_ATTRIBUTES oaThreadAttribs; + /* FIXME: read the defaults from the executable image */ + ULONG_PTR nStackReserve = 0x100000; + /* FIXME: when we finally have exception handling, make this PAGE_SIZE */ + ULONG_PTR nStackCommit = 0x100000; + ULONG_PTR nSize = 0; + PVOID pStackLowest = NULL; + ULONG nDummy; + CONTEXT ctxInitialContext; + NTSTATUS nErrCode; + HANDLE hThread; + CLIENT_ID cidClientId; + + if(ThreadHandle == NULL) ThreadHandle = &hThread; + if(ClientId == NULL) ClientId = &cidClientId; + + if(StackReserve == NULL) StackReserve = &nStackReserve; + else ROUNDUP(*StackReserve, PAGE_SIZE); + + if(StackCommit == NULL) StackCommit = &nStackCommit; + else ROUNDUP(*StackCommit, PAGE_SIZE); + +#if 0 + /* the stack commit size must be equal to or less than the reserve size */ + if(*StackCommit > *StackReserve) *StackCommit = *StackReserve; +#else + /* FIXME: no SEH, no guard pages */ + *StackCommit = *StackReserve; +#endif + + usUserStack.FixedStackBase = NULL; + usUserStack.FixedStackLimit = NULL; + usUserStack.ExpandableStackBase = NULL; + usUserStack.ExpandableStackLimit = NULL; + usUserStack.ExpandableStackBottom = NULL; + + /* FIXME: this code assumes a stack growing downwards */ + /* fixed stack */ + if(*StackCommit == *StackReserve) + { + usUserStack.FixedStackLimit = NULL; + + /* allocate the stack */ + nErrCode = NtAllocateVirtualMemory + ( + ProcessHandle, + &(usUserStack.FixedStackLimit), + StackZeroBits, + StackReserve, + MEM_RESERVE | MEM_COMMIT, + PAGE_READWRITE + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) goto l_Fail; + + /* store the highest (first) address of the stack */ + usUserStack.FixedStackBase = + (PUCHAR)(usUserStack.FixedStackLimit) + *StackReserve; + + *StackCommit = *StackReserve; + } + /* expandable stack */ + else + { + ULONG_PTR nGuardSize = PAGE_SIZE; + PVOID pGuardBase; + + DPRINT("Expandable stack\n"); + + usUserStack.FixedStackLimit = NULL; + usUserStack.FixedStackBase = NULL; + usUserStack.ExpandableStackBottom = NULL; + + /* reserve the stack */ + nErrCode = NtAllocateVirtualMemory + ( + ProcessHandle, + &(usUserStack.ExpandableStackBottom), + StackZeroBits, + StackReserve, + MEM_RESERVE, + PAGE_READWRITE + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) goto l_Fail; + + DPRINT("Reserved %08X bytes\n", *StackReserve); + + /* expandable stack base - the highest address of the stack */ + usUserStack.ExpandableStackBase = + (PUCHAR)(usUserStack.ExpandableStackBottom) + *StackReserve; + + /* expandable stack limit - the lowest committed address of the stack */ + usUserStack.ExpandableStackLimit = + (PUCHAR)(usUserStack.ExpandableStackBase) - *StackCommit; + + DPRINT("Stack base %p\n", usUserStack.ExpandableStackBase); + DPRINT("Stack limit %p\n", usUserStack.ExpandableStackLimit); + DPRINT("Stack bottom %p\n", usUserStack.ExpandableStackBottom); + + /* commit as much stack as requested */ + nErrCode = NtAllocateVirtualMemory + ( + ProcessHandle, + &(usUserStack.ExpandableStackLimit), + 0, + StackCommit, + MEM_COMMIT, + PAGE_READWRITE + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) goto l_Fail; + + assert((*StackReserve - *StackCommit) >= PAGE_SIZE); + assert((*StackReserve - *StackCommit) % PAGE_SIZE == 0); + + pGuardBase = (PUCHAR)(usUserStack.ExpandableStackLimit) - PAGE_SIZE; + + DPRINT("Guard base %p\n", usUserStack.ExpandableStackBase); + + /* set up the guard page */ + nErrCode = NtAllocateVirtualMemory + ( + ProcessHandle, + &pGuardBase, + 0, + &nGuardSize, + MEM_COMMIT, + PAGE_READWRITE | PAGE_GUARD + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) goto l_Fail; + + DPRINT("Guard base %p\n", usUserStack.ExpandableStackBase); + } + + /* initialize the registers and stack for the thread */ + nErrCode = RtlRosInitializeContextEx + ( + ProcessHandle, + &ctxInitialContext, + StartAddress, + &usUserStack, + ParameterCount, + Parameters + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) goto l_Cleanup; + + /* create the thread object */ + nErrCode = NtCreateThread + ( + ThreadHandle, + THREAD_ALL_ACCESS, + ObjectAttributes, + ProcessHandle, + ClientId, + &ctxInitialContext, + &usUserStack, + CreateSuspended + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) goto l_Cleanup; + + /* success */ + return STATUS_SUCCESS; + + /* deallocate the stack */ +l_Cleanup: + if(usUserStack.FixedStackLimit) + pStackLowest = usUserStack.FixedStackLimit; + else if(usUserStack.ExpandableStackBottom) + pStackLowest = usUserStack.ExpandableStackBottom; + + /* free the stack, if it was allocated */ + if(pStackLowest != NULL) + NtFreeVirtualMemory(ProcessHandle, &pStackLowest, &nSize, MEM_RELEASE); + + /* failure */ +l_Fail: + assert(!NT_SUCCESS(nErrCode)); + return nErrCode; +} + +NTSTATUS CDECL RtlRosCreateUserThreadVa +( + IN HANDLE ProcessHandle, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN BOOLEAN CreateSuspended, + IN LONG StackZeroBits, + IN OUT PULONG StackReserve OPTIONAL, + IN OUT PULONG StackCommit OPTIONAL, + IN PTHREAD_START_ROUTINE StartAddress, + OUT PHANDLE ThreadHandle OPTIONAL, + OUT PCLIENT_ID ClientId OPTIONAL, + IN ULONG ParameterCount, + ... +) +{ + va_list vaArgs; + NTSTATUS nErrCode; + + va_start(vaArgs, ParameterCount); + + /* FIXME: this code assumes a stack growing downwards */ + nErrCode = RtlRosCreateUserThreadEx + ( + ProcessHandle, + ObjectAttributes, + CreateSuspended, + StackZeroBits, + StackReserve, + StackCommit, + StartAddress, + ThreadHandle, + ClientId, + ParameterCount, + (ULONG_PTR *)vaArgs + ); + + va_end(vaArgs); + + return nErrCode; +} + +/* EOF */