# 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
--- /dev/null
+#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 */
--- /dev/null
+/* $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 */
#include <ntos/minmax.h>
#include <csrss/csrss.h>
#include <reactos/buildno.h>
+#include <rosrtl/thread.h>
-# $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 = ../..
TARGET_LFLAGS = -nostartfiles -nostdlib
-TARGET_SDKLIBS = ntdll.a
+TARGET_SDKLIBS = rosrtl.a ntdll.a
TARGET_GCCLIBS = gcc
-/* $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
}
}
-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,
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,
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;
}
-/* $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
/* 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,
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)
{
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,
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;
-; $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
;
RtlCreateUserProcess@40
;RtlCreateUserSecurityObject
RtlCreateUserThread@40
-RtlCreateUserThread@44
-RtlCreateUserThreadVa
RtlCustomCPToUnicodeN@24
;RtlCutoverTimeToSystemTime
RtlDeNormalizeProcessParams@4
;RtlInitializeAtomPackage
RtlInitializeBitMap@12
RtlInitializeContext@20
-RtlInitializeContextEx@24
RtlInitializeCriticalSection@4
;RtlInitializeGenericTable
RtlInitializeHandleTable@12
-; $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
;
RtlCreateUserProcess=RtlCreateUserProcess@40
;RtlCreateUserSecurityObject
RtlCreateUserThread=RtlCreateUserThread@40
-RtlCreateUserThreadEx=RtlCreateUserThreadEx@44
-RtlCreateUserThreadVa=RtlCreateUserThreadVa
RtlCustomCPToUnicodeN=RtlCustomCPToUnicodeN@24
;RtlCutoverTimeToSystemTime
RtlDeNormalizeProcessParams=RtlDeNormalizeProcessParams@4
;RtlInitializeAtomPackage
RtlInitializeBitMap=RtlInitializeBitMap@12
RtlInitializeContext=RtlInitializeContext@20
-RtlInitializeContextEx=RtlInitializeContextEx@24
RtlInitializeCriticalSection=RtlInitializeCriticalSection@4
;RtlInitializeGenericTable
RtlInitializeHandleTable=RtlInitializeHandleTable@12
.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
-# $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 = ../..
-Wl,--section-alignment,0x1000 \
-nostartfiles
+TARGET_SDKLIBS = rosrtl.a
+
TARGET_GCCLIBS = gcc
TARGET_BASE = 0x77f60000
* 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 <ddk/ntddk.h>
-#include <napi/i386/segment.h>
#include <napi/teb.h>
#include <ntdll/rtl.h>
+#include <rosrtl/thread.h>
-//#define NDEBUG
+#define NDEBUG
#include <ntdll/ntdll.h>
-
/* 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,
SecurityDescriptor
);
- return RtlCreateUserThreadEx
+ return RtlRosCreateUserThreadEx
(
ProcessHandle,
&oaThreadAttribs,
);
}
-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,
PUSER_STACK UserStack
)
{
- return RtlInitializeContextEx
+ return RtlRosInitializeContextEx
(
ProcessHandle,
Context,
--- /dev/null
+# $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
--- /dev/null
+/* $Id: context.c,v 1.1 2003/04/29 02:17:01 hyperion Exp $
+*/
+/*
+*/
+
+#include <ddk/ntddk.h>
+#include <rosrtl/thread.h>
+
+#if defined(_M_IX86)
+#include <napi/i386/segment.h>
+#include <napi/i386/floatsave.h>
+#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 */
--- /dev/null
+/* $Id: create.c,v 1.1 2003/04/29 02:17:01 hyperion Exp $
+*/
+/*
+*/
+
+#include <stdarg.h>
+#include <ddk/ntddk.h>
+#include <rosrtl/thread.h>
+
+#define NDEBUG
+#include <ntdll/ntdll.h>
+
+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 */