mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +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
|
||||
# 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
|
||||
|
|
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 <csrss/csrss.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 = ../..
|
||||
|
||||
|
@ -10,7 +10,7 @@ TARGET_BASE = 0x77f00000
|
|||
|
||||
TARGET_LFLAGS = -nostartfiles -nostdlib
|
||||
|
||||
TARGET_SDKLIBS = ntdll.a
|
||||
TARGET_SDKLIBS = rosrtl.a ntdll.a
|
||||
|
||||
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
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -93,21 +93,6 @@ VOID STDCALL RtlRosR32AttribsToNativeAttribsNamed
|
|||
}
|
||||
}
|
||||
|
||||
NTSTATUS CDECL RtlCreateUserThreadVa
|
||||
(
|
||||
HANDLE ProcessHandle,
|
||||
POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
BOOLEAN CreateSuspended,
|
||||
LONG StackZeroBits,
|
||||
PULONG StackReserve,
|
||||
PULONG StackCommit,
|
||||
PTHREAD_START_ROUTINE StartAddress,
|
||||
PHANDLE ThreadHandle,
|
||||
PCLIENT_ID ClientId,
|
||||
ULONG ParameterCount,
|
||||
...
|
||||
);
|
||||
|
||||
BOOL STDCALL CreateProcessA
|
||||
(
|
||||
LPCSTR lpApplicationName,
|
||||
|
@ -408,8 +393,39 @@ HANDLE STDCALL KlCreateFirstThread
|
|||
else
|
||||
pTrueStartAddress = (PVOID)RtlBaseProcessStartRoutine;
|
||||
|
||||
DPRINT
|
||||
(
|
||||
"RtlRosCreateUserThreadVa\n"
|
||||
"(\n"
|
||||
" ProcessHandle %p,\n"
|
||||
" ObjectAttributes %p,\n"
|
||||
" CreateSuspended %d,\n"
|
||||
" StackZeroBits %d,\n"
|
||||
" StackReserve %lu,\n"
|
||||
" StackCommit %lu,\n"
|
||||
" StartAddress %p,\n"
|
||||
" ThreadHandle %p,\n"
|
||||
" ClientId %p,\n"
|
||||
" ParameterCount %u,\n"
|
||||
" Parameters[0] %p,\n"
|
||||
" Parameters[1] %p\n"
|
||||
")\n",
|
||||
ProcessHandle,
|
||||
&oaThreadAttribs,
|
||||
dwCreationFlags & CREATE_SUSPENDED,
|
||||
0,
|
||||
Sii->StackReserve,
|
||||
Sii->StackCommit,
|
||||
pTrueStartAddress,
|
||||
&hThread,
|
||||
&cidClientId,
|
||||
2,
|
||||
lpStartAddress,
|
||||
PEB_BASE
|
||||
);
|
||||
|
||||
/* create the first thread */
|
||||
nErrCode = RtlCreateUserThreadVa
|
||||
nErrCode = RtlRosCreateUserThreadVa
|
||||
(
|
||||
ProcessHandle,
|
||||
&oaThreadAttribs,
|
||||
|
@ -431,8 +447,21 @@ HANDLE STDCALL KlCreateFirstThread
|
|||
SetLastErrorByStatus(nErrCode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DPRINT
|
||||
(
|
||||
"StackReserve %p\n"
|
||||
"StackCommit %p\n"
|
||||
"ThreadHandle %p\n"
|
||||
"ClientId.UniqueThread %p\n",
|
||||
Sii->StackReserve,
|
||||
Sii->StackCommit,
|
||||
hThread,
|
||||
cidClientId.UniqueThread
|
||||
);
|
||||
|
||||
/* success */
|
||||
if(lpThreadId) *lpThreadId = (DWORD)cidClientId.UniqueThread;
|
||||
return hThread;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: thread.c,v 1.37 2003/04/26 23:13:28 hyperion Exp $
|
||||
/* $Id: thread.c,v 1.38 2003/04/29 02:16:59 hyperion Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -22,21 +22,6 @@
|
|||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/* FIXME: please put this in some header */
|
||||
extern NTSTATUS CDECL RtlCreateUserThreadVa
|
||||
(
|
||||
HANDLE ProcessHandle,
|
||||
POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
BOOLEAN CreateSuspended,
|
||||
LONG StackZeroBits,
|
||||
PULONG StackReserve,
|
||||
PULONG StackCommit,
|
||||
PTHREAD_START_ROUTINE StartAddress,
|
||||
PHANDLE ThreadHandle,
|
||||
PCLIENT_ID ClientId,
|
||||
ULONG ParameterCount,
|
||||
...
|
||||
);
|
||||
|
||||
static EXCEPTION_DISPOSITION __cdecl
|
||||
_except_handler(EXCEPTION_RECORD *ExceptionRecord,
|
||||
void * EstablisherFrame,
|
||||
|
@ -113,6 +98,24 @@ HANDLE STDCALL CreateRemoteThread
|
|||
PIMAGE_NT_HEADERS pinhHeader =
|
||||
RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress);
|
||||
|
||||
DPRINT
|
||||
(
|
||||
"hProcess %08X\n"
|
||||
"lpThreadAttributes %08X\n"
|
||||
"dwStackSize %08X\n"
|
||||
"lpStartAddress %08X\n"
|
||||
"lpParameter %08X\n"
|
||||
"dwCreationFlags %08X\n"
|
||||
"lpThreadId %08X\n",
|
||||
hProcess,
|
||||
lpThreadAttributes,
|
||||
dwStackSize,
|
||||
lpStartAddress,
|
||||
lpParameter,
|
||||
dwCreationFlags,
|
||||
lpThreadId
|
||||
);
|
||||
|
||||
/* FIXME: do more checks - e.g. the image may not have an optional header */
|
||||
if(pinhHeader == NULL)
|
||||
{
|
||||
|
@ -163,8 +166,39 @@ HANDLE STDCALL CreateRemoteThread
|
|||
oaThreadAttribs.SecurityDescriptor = lpThreadAttributes->lpSecurityDescriptor;
|
||||
}
|
||||
|
||||
DPRINT
|
||||
(
|
||||
"RtlRosCreateUserThreadVa\n"
|
||||
"(\n"
|
||||
" ProcessHandle %p,\n"
|
||||
" ObjectAttributes %p,\n"
|
||||
" CreateSuspended %d,\n"
|
||||
" StackZeroBits %d,\n"
|
||||
" StackReserve %lu,\n"
|
||||
" StackCommit %lu,\n"
|
||||
" StartAddress %p,\n"
|
||||
" ThreadHandle %p,\n"
|
||||
" ClientId %p,\n"
|
||||
" ParameterCount %u,\n"
|
||||
" Parameters[0] %p,\n"
|
||||
" Parameters[1] %p\n"
|
||||
")\n",
|
||||
hProcess,
|
||||
&oaThreadAttribs,
|
||||
dwCreationFlags & CREATE_SUSPENDED,
|
||||
0,
|
||||
nStackReserve,
|
||||
nStackCommit,
|
||||
ThreadStartup,
|
||||
&hThread,
|
||||
&cidClientId,
|
||||
2,
|
||||
lpStartAddress,
|
||||
lpParameter
|
||||
);
|
||||
|
||||
/* create the thread */
|
||||
nErrCode = RtlCreateUserThreadVa
|
||||
nErrCode = RtlRosCreateUserThreadVa
|
||||
(
|
||||
hProcess,
|
||||
&oaThreadAttribs,
|
||||
|
@ -186,6 +220,18 @@ HANDLE STDCALL CreateRemoteThread
|
|||
SetLastErrorByStatus(nErrCode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DPRINT
|
||||
(
|
||||
"StackReserve %p\n"
|
||||
"StackCommit %p\n"
|
||||
"ThreadHandle %p\n"
|
||||
"ClientId.UniqueThread %p\n",
|
||||
nStackReserve,
|
||||
nStackCommit,
|
||||
hThread,
|
||||
cidClientId.UniqueThread
|
||||
);
|
||||
|
||||
/* success */
|
||||
if(lpThreadId) *lpThreadId = (DWORD)cidClientId.UniqueThread;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; $Id: ntdll.def,v 1.97 2003/04/26 23:13:29 hyperion Exp $
|
||||
; $Id: ntdll.def,v 1.98 2003/04/29 02:16:59 hyperion Exp $
|
||||
;
|
||||
; ReactOS Operating System
|
||||
;
|
||||
|
@ -347,8 +347,6 @@ RtlCreateUnicodeStringFromAsciiz@8
|
|||
RtlCreateUserProcess@40
|
||||
;RtlCreateUserSecurityObject
|
||||
RtlCreateUserThread@40
|
||||
RtlCreateUserThread@44
|
||||
RtlCreateUserThreadVa
|
||||
RtlCustomCPToUnicodeN@24
|
||||
;RtlCutoverTimeToSystemTime
|
||||
RtlDeNormalizeProcessParams@4
|
||||
|
@ -450,7 +448,6 @@ RtlInitUnicodeString@8
|
|||
;RtlInitializeAtomPackage
|
||||
RtlInitializeBitMap@12
|
||||
RtlInitializeContext@20
|
||||
RtlInitializeContextEx@24
|
||||
RtlInitializeCriticalSection@4
|
||||
;RtlInitializeGenericTable
|
||||
RtlInitializeHandleTable@12
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; $Id: ntdll.edf,v 1.86 2003/04/26 23:13:29 hyperion Exp $
|
||||
; $Id: ntdll.edf,v 1.87 2003/04/29 02:16:59 hyperion Exp $
|
||||
;
|
||||
; ReactOS Operating System
|
||||
;
|
||||
|
@ -347,8 +347,6 @@ RtlCreateUnicodeStringFromAsciiz=RtlCreateUnicodeStringFromAsciiz@8
|
|||
RtlCreateUserProcess=RtlCreateUserProcess@40
|
||||
;RtlCreateUserSecurityObject
|
||||
RtlCreateUserThread=RtlCreateUserThread@40
|
||||
RtlCreateUserThreadEx=RtlCreateUserThreadEx@44
|
||||
RtlCreateUserThreadVa=RtlCreateUserThreadVa
|
||||
RtlCustomCPToUnicodeN=RtlCustomCPToUnicodeN@24
|
||||
;RtlCutoverTimeToSystemTime
|
||||
RtlDeNormalizeProcessParams=RtlDeNormalizeProcessParams@4
|
||||
|
@ -449,7 +447,6 @@ RtlInitUnicodeString=RtlInitUnicodeString@8
|
|||
;RtlInitializeAtomPackage
|
||||
RtlInitializeBitMap=RtlInitializeBitMap@12
|
||||
RtlInitializeContext=RtlInitializeContext@20
|
||||
RtlInitializeContextEx=RtlInitializeContextEx@24
|
||||
RtlInitializeCriticalSection=RtlInitializeCriticalSection@4
|
||||
;RtlInitializeGenericTable
|
||||
RtlInitializeHandleTable=RtlInitializeHandleTable@12
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
.globl _LdrInitializeThunk@16
|
||||
_LdrInitializeThunk@16:
|
||||
#if defined(_M_IX86)
|
||||
nop /* breakin overwrites this with "int 3" */
|
||||
jmp ___true_LdrInitializeThunk@16
|
||||
nop /* breakin overwrites this with "int 3" */
|
||||
jmp ___true_LdrInitializeThunk@16
|
||||
#elif defined(_M_ALPHA)
|
||||
nop /* breakin overwrites this with "call_pal bpt" */
|
||||
"br"
|
||||
nop /* breakin overwrites this with "call_pal bpt" */
|
||||
br ___true_LdrInitializeThunk@16
|
||||
#elif defined(_M_MIPS)
|
||||
nop /* breakin overwrites this with "break" */
|
||||
j ___true_LdrInitializeThunk@16
|
||||
nop /* breakin overwrites this with "break" */
|
||||
j ___true_LdrInitializeThunk@16
|
||||
#else
|
||||
#error Unsupported architecture.
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: makefile,v 1.82 2003/04/27 14:45:52 chorns Exp $
|
||||
# $Id: makefile,v 1.83 2003/04/29 02:17:00 hyperion Exp $
|
||||
|
||||
PATH_TO_TOP = ../..
|
||||
|
||||
|
@ -16,6 +16,8 @@ TARGET_LFLAGS = -Wl,--file-alignment,0x1000 \
|
|||
-Wl,--section-alignment,0x1000 \
|
||||
-nostartfiles
|
||||
|
||||
TARGET_SDKLIBS = rosrtl.a
|
||||
|
||||
TARGET_GCCLIBS = gcc
|
||||
|
||||
TARGET_BASE = 0x77f60000
|
||||
|
|
|
@ -10,292 +10,24 @@
|
|||
* 25/04/03: Near rewrite. Made code more readable, replaced
|
||||
* INITIAL_TEB with USER_STACK, added support for
|
||||
* fixed-size stacks
|
||||
* 28/04/03: Moved all code to a new statically linked
|
||||
* library (ROSRTL) so it can be shared with
|
||||
* kernel32.dll without exporting non-standard
|
||||
* functions from ntdll.dll
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <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,
|
||||
|
@ -321,7 +53,7 @@ NTSTATUS STDCALL RtlCreateUserThread
|
|||
SecurityDescriptor
|
||||
);
|
||||
|
||||
return RtlCreateUserThreadEx
|
||||
return RtlRosCreateUserThreadEx
|
||||
(
|
||||
ProcessHandle,
|
||||
&oaThreadAttribs,
|
||||
|
@ -337,90 +69,6 @@ NTSTATUS STDCALL RtlCreateUserThread
|
|||
);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL RtlInitializeContextEx
|
||||
(
|
||||
HANDLE ProcessHandle,
|
||||
PCONTEXT Context,
|
||||
PTHREAD_START_ROUTINE StartAddress,
|
||||
PUSER_STACK UserStack,
|
||||
ULONG ParameterCount,
|
||||
ULONG_PTR * Parameters
|
||||
)
|
||||
{
|
||||
ULONG nDummy;
|
||||
PCHAR pStackBase;
|
||||
PCHAR pStackLimit;
|
||||
ULONG_PTR nRetAddr = 0xDEADBEEF;
|
||||
SIZE_T nParamsSize = ParameterCount * sizeof(ULONG_PTR);
|
||||
NTSTATUS nErrCode;
|
||||
|
||||
if(UserStack->FixedStackBase != NULL && UserStack->FixedStackLimit != NULL)
|
||||
{
|
||||
pStackBase = UserStack->FixedStackBase;
|
||||
pStackLimit = UserStack->FixedStackLimit;
|
||||
}
|
||||
else if(UserStack->ExpandableStackBase != NULL)
|
||||
{
|
||||
pStackBase = UserStack->ExpandableStackBase;
|
||||
pStackLimit = UserStack->ExpandableStackLimit;
|
||||
}
|
||||
else
|
||||
return STATUS_BAD_INITIAL_STACK;
|
||||
|
||||
if(pStackBase <= pStackLimit)
|
||||
return STATUS_BAD_INITIAL_STACK;
|
||||
|
||||
/* too many parameters */
|
||||
if((nParamsSize + sizeof(ULONG_PTR)) > (SIZE_T)(pStackBase - pStackLimit))
|
||||
return STATUS_STACK_OVERFLOW;
|
||||
|
||||
#if defined(_M_IX86)
|
||||
memset(Context, 0, sizeof(CONTEXT));
|
||||
|
||||
Context->ContextFlags = CONTEXT_FULL;
|
||||
Context->FloatSave.ControlWord = 0xffff037f;
|
||||
Context->FloatSave.StatusWord = 0xffff0000;
|
||||
Context->FloatSave.TagWord = 0xffffffff;
|
||||
Context->FloatSave.DataSelector = 0xffff0000;
|
||||
Context->Eip = (ULONG_PTR)StartAddress;
|
||||
Context->SegGs = USER_DS;
|
||||
Context->SegFs = TEB_SELECTOR;
|
||||
Context->SegEs = USER_DS;
|
||||
Context->SegDs = USER_DS;
|
||||
Context->SegCs = USER_CS;
|
||||
Context->SegSs = USER_DS;
|
||||
Context->Esp = (ULONG_PTR)pStackBase - (nParamsSize + sizeof(ULONG_PTR));
|
||||
Context->EFlags = ((ULONG_PTR)1 << 1) | ((ULONG_PTR)1 << 9);
|
||||
|
||||
DPRINT("Effective stack base %p\n", Context->Esp);
|
||||
#else
|
||||
#error Unsupported architecture
|
||||
#endif
|
||||
|
||||
/* write the parameters */
|
||||
nErrCode = NtWriteVirtualMemory
|
||||
(
|
||||
ProcessHandle,
|
||||
((PUCHAR)pStackBase) - nParamsSize,
|
||||
Parameters,
|
||||
nParamsSize,
|
||||
&nDummy
|
||||
);
|
||||
|
||||
/* failure */
|
||||
if(!NT_SUCCESS(nErrCode)) return nErrCode;
|
||||
|
||||
/* write the return address */
|
||||
return NtWriteVirtualMemory
|
||||
(
|
||||
ProcessHandle,
|
||||
((PUCHAR)pStackBase) - (nParamsSize + sizeof(ULONG_PTR)),
|
||||
&nRetAddr,
|
||||
sizeof(ULONG_PTR),
|
||||
&nDummy
|
||||
);
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL RtlInitializeContext
|
||||
(
|
||||
HANDLE ProcessHandle,
|
||||
|
@ -430,7 +78,7 @@ NTSTATUS STDCALL RtlInitializeContext
|
|||
PUSER_STACK UserStack
|
||||
)
|
||||
{
|
||||
return RtlInitializeContextEx
|
||||
return RtlRosInitializeContextEx
|
||||
(
|
||||
ProcessHandle,
|
||||
Context,
|
||||
|
|
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