*/
#include <stdarg.h>
-#include <ddk/ntddk.h>
-#include <rosrtl/thread.h>
+#define NTOS_MODE_USER
+#include <ntos.h>
#define NDEBUG
#include <ntdll/ntdll.h>
-NTSTATUS STDCALL RtlRosCreateUserThreadEx
+#include <rosrtl/thread.h>
+
+NTSTATUS STDCALL
+RtlRosCreateUserThread
(
IN HANDLE ProcessHandle,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN LONG StackZeroBits,
IN OUT PULONG StackReserve OPTIONAL,
IN OUT PULONG StackCommit OPTIONAL,
- IN PTHREAD_START_ROUTINE StartAddress,
+ IN PVOID StartAddress,
OUT PHANDLE ThreadHandle OPTIONAL,
OUT PCLIENT_ID ClientId OPTIONAL,
IN ULONG ParameterCount,
)
{
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;
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);
- }
+ /* allocate the stack for the thread */
+ nErrCode = RtlRosCreateStack
+ (
+ ProcessHandle,
+ &usUserStack,
+ StackZeroBits,
+ StackReserve,
+ StackCommit
+ );
+
+ /* failure */
+ if(!NT_SUCCESS(nErrCode)) goto l_Fail;
/* initialize the registers and stack for the thread */
- nErrCode = RtlRosInitializeContextEx
+ nErrCode = RtlRosInitializeContext
(
ProcessHandle,
&ctxInitialContext,
);
/* failure */
- if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;
+ if(!NT_SUCCESS(nErrCode)) goto l_Fail;
/* create the thread object */
nErrCode = NtCreateThread
);
/* failure */
- if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;
+ if(!NT_SUCCESS(nErrCode)) goto l_Fail;
/* 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));
+
+ /* deallocate the stack */
+ RtlRosDeleteStack(ProcessHandle, &usUserStack);
+
return nErrCode;
}
-NTSTATUS CDECL RtlRosCreateUserThreadVa
+NTSTATUS CDECL
+RtlRosCreateUserThreadVa
(
IN HANDLE ProcessHandle,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN LONG StackZeroBits,
IN OUT PULONG StackReserve OPTIONAL,
IN OUT PULONG StackCommit OPTIONAL,
- IN PTHREAD_START_ROUTINE StartAddress,
+ IN PVOID StartAddress,
OUT PHANDLE ThreadHandle OPTIONAL,
OUT PCLIENT_ID ClientId OPTIONAL,
IN ULONG ParameterCount,
va_start(vaArgs, ParameterCount);
- /* FIXME: this code assumes a stack growing downwards */
- nErrCode = RtlRosCreateUserThreadEx
+ /*
+ FIXME: this code makes several non-portable assumptions:
+ - all parameters are passed on the stack
+ - the stack is a contiguous array of cells as large as an ULONG_PTR
+ - the stack grows downwards
+
+ This happens to work on the Intel x86, but is likely to bomb horribly on most
+ other platforms
+ */
+ nErrCode = RtlRosCreateUserThread
(
ProcessHandle,
ObjectAttributes,