- 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
This commit is contained in:
KJK::Hyperion 2003-04-29 02:17:01 +00:00
parent 6247d82cc7
commit 38a1364aae
15 changed files with 584 additions and 412 deletions

View file

@ -33,7 +33,7 @@ LIB_FSLIB = vfatlib
# User mode libraries # User mode libraries
# advapi32 crtdll fmifs gdi32 kernel32 libpcap packet msafd msvcrt ntdll ole32 # advapi32 crtdll fmifs gdi32 kernel32 libpcap packet msafd msvcrt ntdll ole32
# oleaut32 epsapi psapi rpcrt4 secur32 shell32 user32 version ws2help ws2_32 wsock32 wshirda # 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 epsapi psapi secur32 user32 version winedbgc ws2help ws2_32 wsock32 wshirda zlib #winmm
SUBSYS = smss win32k csrss ntvdm SUBSYS = smss win32k csrss ntvdm

View file

@ -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 */

View file

@ -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 */

View file

@ -24,3 +24,4 @@
#include <ntos/minmax.h> #include <ntos/minmax.h>
#include <csrss/csrss.h> #include <csrss/csrss.h>
#include <reactos/buildno.h> #include <reactos/buildno.h>
#include <rosrtl/thread.h>

View file

@ -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 = ../.. PATH_TO_TOP = ../..
@ -10,7 +10,7 @@ TARGET_BASE = 0x77f00000
TARGET_LFLAGS = -nostartfiles -nostdlib TARGET_LFLAGS = -nostartfiles -nostdlib
TARGET_SDKLIBS = ntdll.a TARGET_SDKLIBS = rosrtl.a ntdll.a
TARGET_GCCLIBS = gcc TARGET_GCCLIBS = gcc

View file

@ -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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * 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 BOOL STDCALL CreateProcessA
( (
LPCSTR lpApplicationName, LPCSTR lpApplicationName,
@ -408,8 +393,39 @@ HANDLE STDCALL KlCreateFirstThread
else else
pTrueStartAddress = (PVOID)RtlBaseProcessStartRoutine; 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 */ /* create the first thread */
nErrCode = RtlCreateUserThreadVa nErrCode = RtlRosCreateUserThreadVa
( (
ProcessHandle, ProcessHandle,
&oaThreadAttribs, &oaThreadAttribs,
@ -431,8 +447,21 @@ HANDLE STDCALL KlCreateFirstThread
SetLastErrorByStatus(nErrCode); SetLastErrorByStatus(nErrCode);
return NULL; return NULL;
} }
DPRINT
(
"StackReserve %p\n"
"StackCommit %p\n"
"ThreadHandle %p\n"
"ClientId.UniqueThread %p\n",
Sii->StackReserve,
Sii->StackCommit,
hThread,
cidClientId.UniqueThread
);
/* success */ /* success */
if(lpThreadId) *lpThreadId = (DWORD)cidClientId.UniqueThread;
return hThread; return hThread;
} }

View file

@ -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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries
@ -22,21 +22,6 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
/* FIXME: please put this in some header */ /* 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 static EXCEPTION_DISPOSITION __cdecl
_except_handler(EXCEPTION_RECORD *ExceptionRecord, _except_handler(EXCEPTION_RECORD *ExceptionRecord,
void * EstablisherFrame, void * EstablisherFrame,
@ -113,6 +98,24 @@ HANDLE STDCALL CreateRemoteThread
PIMAGE_NT_HEADERS pinhHeader = PIMAGE_NT_HEADERS pinhHeader =
RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress); 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 */ /* FIXME: do more checks - e.g. the image may not have an optional header */
if(pinhHeader == NULL) if(pinhHeader == NULL)
{ {
@ -163,8 +166,39 @@ HANDLE STDCALL CreateRemoteThread
oaThreadAttribs.SecurityDescriptor = lpThreadAttributes->lpSecurityDescriptor; 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 */ /* create the thread */
nErrCode = RtlCreateUserThreadVa nErrCode = RtlRosCreateUserThreadVa
( (
hProcess, hProcess,
&oaThreadAttribs, &oaThreadAttribs,
@ -186,6 +220,18 @@ HANDLE STDCALL CreateRemoteThread
SetLastErrorByStatus(nErrCode); SetLastErrorByStatus(nErrCode);
return NULL; return NULL;
} }
DPRINT
(
"StackReserve %p\n"
"StackCommit %p\n"
"ThreadHandle %p\n"
"ClientId.UniqueThread %p\n",
nStackReserve,
nStackCommit,
hThread,
cidClientId.UniqueThread
);
/* success */ /* success */
if(lpThreadId) *lpThreadId = (DWORD)cidClientId.UniqueThread; if(lpThreadId) *lpThreadId = (DWORD)cidClientId.UniqueThread;

View file

@ -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 ; ReactOS Operating System
; ;
@ -347,8 +347,6 @@ RtlCreateUnicodeStringFromAsciiz@8
RtlCreateUserProcess@40 RtlCreateUserProcess@40
;RtlCreateUserSecurityObject ;RtlCreateUserSecurityObject
RtlCreateUserThread@40 RtlCreateUserThread@40
RtlCreateUserThread@44
RtlCreateUserThreadVa
RtlCustomCPToUnicodeN@24 RtlCustomCPToUnicodeN@24
;RtlCutoverTimeToSystemTime ;RtlCutoverTimeToSystemTime
RtlDeNormalizeProcessParams@4 RtlDeNormalizeProcessParams@4
@ -450,7 +448,6 @@ RtlInitUnicodeString@8
;RtlInitializeAtomPackage ;RtlInitializeAtomPackage
RtlInitializeBitMap@12 RtlInitializeBitMap@12
RtlInitializeContext@20 RtlInitializeContext@20
RtlInitializeContextEx@24
RtlInitializeCriticalSection@4 RtlInitializeCriticalSection@4
;RtlInitializeGenericTable ;RtlInitializeGenericTable
RtlInitializeHandleTable@12 RtlInitializeHandleTable@12

View file

@ -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 ; ReactOS Operating System
; ;
@ -347,8 +347,6 @@ RtlCreateUnicodeStringFromAsciiz=RtlCreateUnicodeStringFromAsciiz@8
RtlCreateUserProcess=RtlCreateUserProcess@40 RtlCreateUserProcess=RtlCreateUserProcess@40
;RtlCreateUserSecurityObject ;RtlCreateUserSecurityObject
RtlCreateUserThread=RtlCreateUserThread@40 RtlCreateUserThread=RtlCreateUserThread@40
RtlCreateUserThreadEx=RtlCreateUserThreadEx@44
RtlCreateUserThreadVa=RtlCreateUserThreadVa
RtlCustomCPToUnicodeN=RtlCustomCPToUnicodeN@24 RtlCustomCPToUnicodeN=RtlCustomCPToUnicodeN@24
;RtlCutoverTimeToSystemTime ;RtlCutoverTimeToSystemTime
RtlDeNormalizeProcessParams=RtlDeNormalizeProcessParams@4 RtlDeNormalizeProcessParams=RtlDeNormalizeProcessParams@4
@ -449,7 +447,6 @@ RtlInitUnicodeString=RtlInitUnicodeString@8
;RtlInitializeAtomPackage ;RtlInitializeAtomPackage
RtlInitializeBitMap=RtlInitializeBitMap@12 RtlInitializeBitMap=RtlInitializeBitMap@12
RtlInitializeContext=RtlInitializeContext@20 RtlInitializeContext=RtlInitializeContext@20
RtlInitializeContextEx=RtlInitializeContextEx@24
RtlInitializeCriticalSection=RtlInitializeCriticalSection@4 RtlInitializeCriticalSection=RtlInitializeCriticalSection@4
;RtlInitializeGenericTable ;RtlInitializeGenericTable
RtlInitializeHandleTable=RtlInitializeHandleTable@12 RtlInitializeHandleTable=RtlInitializeHandleTable@12

View file

@ -5,14 +5,14 @@
.globl _LdrInitializeThunk@16 .globl _LdrInitializeThunk@16
_LdrInitializeThunk@16: _LdrInitializeThunk@16:
#if defined(_M_IX86) #if defined(_M_IX86)
nop /* breakin overwrites this with "int 3" */ nop /* breakin overwrites this with "int 3" */
jmp ___true_LdrInitializeThunk@16 jmp ___true_LdrInitializeThunk@16
#elif defined(_M_ALPHA) #elif defined(_M_ALPHA)
nop /* breakin overwrites this with "call_pal bpt" */ nop /* breakin overwrites this with "call_pal bpt" */
"br" br ___true_LdrInitializeThunk@16
#elif defined(_M_MIPS) #elif defined(_M_MIPS)
nop /* breakin overwrites this with "break" */ nop /* breakin overwrites this with "break" */
j ___true_LdrInitializeThunk@16 j ___true_LdrInitializeThunk@16
#else #else
#error Unsupported architecture. #error Unsupported architecture.
#endif #endif

View file

@ -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 = ../.. PATH_TO_TOP = ../..
@ -16,6 +16,8 @@ TARGET_LFLAGS = -Wl,--file-alignment,0x1000 \
-Wl,--section-alignment,0x1000 \ -Wl,--section-alignment,0x1000 \
-nostartfiles -nostartfiles
TARGET_SDKLIBS = rosrtl.a
TARGET_GCCLIBS = gcc TARGET_GCCLIBS = gcc
TARGET_BASE = 0x77f60000 TARGET_BASE = 0x77f60000

View file

@ -10,292 +10,24 @@
* 25/04/03: Near rewrite. Made code more readable, replaced * 25/04/03: Near rewrite. Made code more readable, replaced
* INITIAL_TEB with USER_STACK, added support for * INITIAL_TEB with USER_STACK, added support for
* fixed-size stacks * 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 *****************************************************************/ /* INCLUDES *****************************************************************/
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <napi/i386/segment.h>
#include <napi/teb.h> #include <napi/teb.h>
#include <ntdll/rtl.h> #include <ntdll/rtl.h>
#include <rosrtl/thread.h>
//#define NDEBUG #define NDEBUG
#include <ntdll/ntdll.h> #include <ntdll/ntdll.h>
/* FUNCTIONS ***************************************************************/ /* 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 NTSTATUS STDCALL RtlCreateUserThread
( (
HANDLE ProcessHandle, HANDLE ProcessHandle,
@ -321,7 +53,7 @@ NTSTATUS STDCALL RtlCreateUserThread
SecurityDescriptor SecurityDescriptor
); );
return RtlCreateUserThreadEx return RtlRosCreateUserThreadEx
( (
ProcessHandle, ProcessHandle,
&oaThreadAttribs, &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 NTSTATUS STDCALL RtlInitializeContext
( (
HANDLE ProcessHandle, HANDLE ProcessHandle,
@ -430,7 +78,7 @@ NTSTATUS STDCALL RtlInitializeContext
PUSER_STACK UserStack PUSER_STACK UserStack
) )
{ {
return RtlInitializeContextEx return RtlRosInitializeContextEx
( (
ProcessHandle, ProcessHandle,
Context, Context,

View file

@ -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

View file

@ -0,0 +1,105 @@
/* $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 */

View file

@ -0,0 +1,260 @@
/* $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 */