mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
- 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:
parent
6247d82cc7
commit
38a1364aae
15 changed files with 584 additions and 412 deletions
|
@ -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
|
||||||
|
|
11
reactos/include/napi/i386/floatsave.h
Normal file
11
reactos/include/napi/i386/floatsave.h
Normal 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 */
|
53
reactos/include/rosrtl/thread.h
Normal file
53
reactos/include/rosrtl/thread.h
Normal 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 */
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
23
reactos/lib/rosrtl/makefile
Normal file
23
reactos/lib/rosrtl/makefile
Normal 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
|
105
reactos/lib/rosrtl/thread/context.c
Normal file
105
reactos/lib/rosrtl/thread/context.c
Normal 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 */
|
260
reactos/lib/rosrtl/thread/create.c
Normal file
260
reactos/lib/rosrtl/thread/create.c
Normal 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 */
|
Loading…
Reference in a new issue