From 879b1f5754a4051fcc3c65e9f50f139f983fcf6d Mon Sep 17 00:00:00 2001 From: "KJK::Hyperion" Date: Sat, 26 Apr 2003 23:13:33 +0000 Subject: [PATCH] My biggest commit so far (everything compiles and apparently runs fine): - replaced DWORD with ULONG in a couple of places - replaced some ULONGs with LONGs in the KD GDB stub - replaced INITIAL_TEB with USER_STACK, as per Nebbet's book, to support both fixed size and expandable stacks - added InterlockedExchangePointer - added the ASM_BREAKPOINT macro as the architecture-dependent assembler code to raise a breakpoint exception - corrected definitions of INT, LONG, DWORD, UINT, ULONG and ULONG32 - corrected IoSetCancelRoutine to use InterlockedExchangePointer - corrected definition of NtCurrentTeb and NtCurrentPeb - corrected DbgBreakPoint and DbgUserBreakPoint not to set up a stack frame (temporary fix with inline assembler - why doesn't GCC understand __declspec(naked)?) - corrected various calls to Interlocked* functions to cast OUT operands to LONG * - corrected various printf format strings - corrected DbgUiIssueRemoteBreakin to use the smallest possible stack (this is what started everything) - removed a DPRINT that accessed pageable memory at non-PASSIVE_LEVEL IRQL - beautified CreateProcessA (another temporary fix - all the new functions will be isolated in the upcoming stand-alone RTL) - prefixed LdrInitializeThunk with a nop that can be overwritten with a breakpoint for debugging purposes (temporary debugging aid until we have user-mode debugger support). Will add support for this to the breakin utility soon - thread creation code rewritten from scratch (some glitches documented inline, but works fine) - thread creation code now duplicated just twice, as opposed to five times (temporary fix - three new, non standard functions have been exported from NTDLL.DLL, will fix later) svn path=/trunk/; revision=4595 --- reactos/include/basetsd.h | 2 +- reactos/include/ddk/exfuncs.h | 3 + reactos/include/ddk/fsfuncs.h | 4 +- reactos/include/ddk/iofuncs.h | 6 +- reactos/include/debug.h | 10 + reactos/include/napi/teb.h | 47 +- reactos/include/ntos/rtl.h | 4 +- reactos/include/ntos/rtltypes.h | 16 +- reactos/include/ntos/types.h | 18 +- reactos/include/ntos/zw.h | 6 +- reactos/lib/kernel32/process/create.c | 661 ++++++++++++++------------ reactos/lib/kernel32/process/proc.c | 6 +- reactos/lib/kernel32/thread/thread.c | 286 +++++------ reactos/lib/ntdll/dbg/brkpoint.c | 33 +- reactos/lib/ntdll/dbg/debug.c | 7 +- reactos/lib/ntdll/def/ntdll.def | 5 +- reactos/lib/ntdll/def/ntdll.edf | 5 +- reactos/lib/ntdll/ldr/startup.c | 41 +- reactos/lib/ntdll/rtl/process.c | 179 +------ reactos/lib/ntdll/rtl/thread.c | 651 ++++++++++++++++--------- reactos/ntoskrnl/ex/fmutex.c | 6 +- reactos/ntoskrnl/io/arcname.c | 6 +- reactos/ntoskrnl/kd/gdbstub.c | 10 +- reactos/ntoskrnl/ke/i386/kernel.c | 2 +- reactos/ntoskrnl/ke/main.c | 9 +- reactos/ntoskrnl/ke/spinlock.c | 6 +- reactos/ntoskrnl/ldr/init.c | 269 +++++++---- reactos/ntoskrnl/ldr/loader.c | 4 +- reactos/ntoskrnl/lpc/reply.c | 4 +- reactos/ntoskrnl/mm/anonmem.c | 4 +- reactos/ntoskrnl/mm/balance.c | 20 +- reactos/ntoskrnl/mm/pageop.c | 6 +- reactos/ntoskrnl/mm/section.c | 8 +- reactos/ntoskrnl/ps/create.c | 36 +- reactos/ntoskrnl/ps/process.c | 6 +- 35 files changed, 1331 insertions(+), 1055 deletions(-) diff --git a/reactos/include/basetsd.h b/reactos/include/basetsd.h index d9c375dd9a5..65eec25e3f2 100644 --- a/reactos/include/basetsd.h +++ b/reactos/include/basetsd.h @@ -51,7 +51,7 @@ typedef int LONG32, *PLONG32; #ifndef XFree86Server typedef int INT32, *PINT32; #endif /* ndef XFree86Server */ -typedef unsigned int ULONG32, *PULONG32; +typedef unsigned long ULONG32, *PULONG32; typedef unsigned int DWORD32, *PDWORD32; typedef unsigned int UINT32, *PUINT32; diff --git a/reactos/include/ddk/exfuncs.h b/reactos/include/ddk/exfuncs.h index d0b6e7deff5..026f90c801a 100644 --- a/reactos/include/ddk/exfuncs.h +++ b/reactos/include/ddk/exfuncs.h @@ -801,6 +801,9 @@ InterlockedIncrement ( PLONG Addend ); +#define InterlockedExchangePointer(__T__, __V__) \ + (PVOID)InterlockedExchange((PLONG)(__T__), (LONG)(__V__)) + /*---*/ typedef diff --git a/reactos/include/ddk/fsfuncs.h b/reactos/include/ddk/fsfuncs.h index 13038aa4d07..e0b58ea45e6 100644 --- a/reactos/include/ddk/fsfuncs.h +++ b/reactos/include/ddk/fsfuncs.h @@ -1,6 +1,6 @@ #ifndef __INCLUDE_DDK_FSFUNCS_H #define __INCLUDE_DDK_FSFUNCS_H -/* $Id: fsfuncs.h,v 1.18 2003/04/19 17:17:10 ea Exp $ */ +/* $Id: fsfuncs.h,v 1.19 2003/04/26 23:13:26 hyperion Exp $ */ #define FlagOn(x,f) ((x) & (f)) VOID @@ -202,7 +202,7 @@ FsRtlFastUnlockAllByKey ( IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PEPROCESS Process, - IN DWORD Key, + IN ULONG Key, IN PVOID Context OPTIONAL ); NTSTATUS diff --git a/reactos/include/ddk/iofuncs.h b/reactos/include/ddk/iofuncs.h index 49dfdbb0e25..d4bbeb5b2ea 100644 --- a/reactos/include/ddk/iofuncs.h +++ b/reactos/include/ddk/iofuncs.h @@ -1,6 +1,6 @@ #ifndef _INCLUDE_DDK_IOFUNCS_H #define _INCLUDE_DDK_IOFUNCS_H -/* $Id: iofuncs.h,v 1.36 2003/01/25 16:01:49 hbirr Exp $ */ +/* $Id: iofuncs.h,v 1.37 2003/04/26 23:13:26 hyperion Exp $ */ /* --- EXPORTED BY NTOSKRNL --- */ @@ -936,8 +936,8 @@ IoReportResourceUsage ( (KeInsertQueueDpc(&(DeviceObject)->Dpc,(Irp),(Context))) #define IoSetCancelRoutine(Irp,NewCancelRoutine) \ - ((PDRIVER_CANCEL)InterlockedExchange((PULONG)&(Irp)->CancelRoutine, \ - (ULONG)(NewCancelRoutine))) + ((PDRIVER_CANCEL)InterlockedExchangePointer(&(Irp)->CancelRoutine, \ + NewCancelRoutine)) #define IoSetCompletionRoutine(Irp,Routine,Context,Success,Error,Cancel) \ { \ diff --git a/reactos/include/debug.h b/reactos/include/debug.h index 73b3e5264e7..acc6db0dcc0 100644 --- a/reactos/include/debug.h +++ b/reactos/include/debug.h @@ -51,5 +51,15 @@ #define ASSERT_IRQL(x) assert(KeGetCurrentIrql()<=(x)) #define assert_irql(x) assert(KeGetCurrentIrql()<=(x)) +/* Macros expanding to the appropriate inline assembly to raise a breakpoint */ +#if defined(_M_IX86) +#define ASM_BREAKPOINT "\nint $3\n" +#elif defined(_M_ALPHA) +#define ASM_BREAKPOINT "\ncall_pal bpt\n" +#elif defined(_M_MIPS) +#define ASM_BREAKPOINT "\nbreak\n" +#else +#error Unsupported architecture. +#endif #endif /* __INTERNAL_DEBUG */ diff --git a/reactos/include/napi/teb.h b/reactos/include/napi/teb.h index 477d7c069ea..0cf8beb4898 100644 --- a/reactos/include/napi/teb.h +++ b/reactos/include/napi/teb.h @@ -228,15 +228,19 @@ typedef struct _TEB PVOID WineDebugInfo; // Needed for WINE DLL's } TEB, *PTEB; +/* FIXME: at least NtCurrentTeb should be defined in winnt.h */ + +#ifndef NtCurrentTeb + #if defined(_M_IX86) /* on the x86, the TEB is contained in the FS segment */ /* FIXME: GCC should allow defining a variable that directly maps to a register. It could make for even faster code */ -static inline PTEB NtCurrentTeb(void) +static inline struct _TEB * NtCurrentTeb(void) { - PTEB pTeb; + struct _TEB * pTeb; /* FIXME: instead of hardcoded offsets, use offsetof() - if possible */ __asm__ __volatile__ @@ -248,34 +252,40 @@ static inline PTEB NtCurrentTeb(void) return pTeb; } +#define NtCurrentTeb NtCurrentTeb #elif defined(_M_ALPHA) -/* on the Alpha AXP, we call the rdteb PAL to retrieve the address of the TEB */ -/* - FIXME? I have no first-hand experience with Alpha development, but I think this - is a good guess -*/ - -#define NtCurrentTeb() ((PTEB)__rdteb()) void * __rdteb(void); #pragma intrinsic(__rdteb) -#elif defined(_M_MIPS) -/* on the MIPS R4000, the TEB is loaded at a fixed address (?) */ -/* FIXME: not terribly sure about this */ -#define NtCurrentTeb() ((PTEB)0x7FFFF4A8) +/* on the Alpha AXP, we call the rdteb PAL to retrieve the address of the TEB */ +#define NtCurrentTeb() ((struct _TEB *)__rdteb()) + +#elif defined(_M_MIPS) + +/* on the MIPS R4000, the TEB is loaded at a fixed address */ +#define NtCurrentTeb() ((struct _TEB *)0x7FFFF4A8) + +#elif defined(_M_PPC) + +unsigned __gregister_get(unsigned const regnum); +#pragma intrinsic(__gregister_get) + +/* on the PowerPC, the TEB is pointed to by GPR 13 */ +#define NtCurrentTeb() ((struct _TEB *)__gregister_get(13)) -/* #elif defined(_M_PPC) */ -/* FIXME: sorry, I couldn't disassemble the PPC ntdll.dll */ #else #error Unsupported architecture or no architecture specified. #endif +#endif + #ifdef _M_IX86 -static inline PPEB NtCurrentPeb(void) + +static inline struct _PEB * NtCurrentPeb(void) { - PPEB pPeb; + struct _PEB * pPeb; __asm__ __volatile__ ( @@ -286,9 +296,10 @@ static inline PPEB NtCurrentPeb(void) return pPeb; } + #else /* generic NtCurrentPeb() */ -static inline PPEB NtCurrentPeb(void) { return NtCurrentTeb()->Peb; } +#define NtCurrentPeb() (NtCurrentTeb()->Peb) #endif #endif /* __INCLUDE_INTERNAL_TEB */ diff --git a/reactos/include/ntos/rtl.h b/reactos/include/ntos/rtl.h index 682e5cfd677..70a7b20f177 100755 --- a/reactos/include/ntos/rtl.h +++ b/reactos/include/ntos/rtl.h @@ -1,4 +1,4 @@ -/* $Id: rtl.h,v 1.6 2003/03/26 15:10:29 ekohl Exp $ +/* $Id: rtl.h,v 1.7 2003/04/26 23:13:27 hyperion Exp $ * */ @@ -1237,7 +1237,7 @@ RtlInitializeContext ( IN PCONTEXT Context, IN PVOID Parameter, IN PTHREAD_START_ROUTINE StartAddress, - IN OUT PINITIAL_TEB InitialTeb + IN OUT PUSER_STACK UserStack ); VOID diff --git a/reactos/include/ntos/rtltypes.h b/reactos/include/ntos/rtltypes.h index 3fa93333feb..ecf7e5d9974 100755 --- a/reactos/include/ntos/rtltypes.h +++ b/reactos/include/ntos/rtltypes.h @@ -1,4 +1,4 @@ -/* $Id: rtltypes.h,v 1.4 2003/03/16 14:16:54 chorns Exp $ +/* $Id: rtltypes.h,v 1.5 2003/04/26 23:13:27 hyperion Exp $ * */ @@ -129,14 +129,14 @@ typedef struct _RTL_SPLAY_LINKS #endif /* __USE_W32API */ -typedef struct _INITIAL_TEB +typedef struct _USER_STACK { - ULONG StackCommit; - ULONG StackReserve; - PVOID StackBase; - PVOID StackLimit; - PVOID StackAllocate; -} INITIAL_TEB, *PINITIAL_TEB; + PVOID FixedStackBase; + PVOID FixedStackLimit; + PVOID ExpandableStackBase; + PVOID ExpandableStackLimit; + PVOID ExpandableStackBottom; +} USER_STACK, *PUSER_STACK; typedef struct _RTL_HEAP_DEFINITION { diff --git a/reactos/include/ntos/types.h b/reactos/include/ntos/types.h index 1987799eb90..e7739afe63f 100644 --- a/reactos/include/ntos/types.h +++ b/reactos/include/ntos/types.h @@ -61,28 +61,12 @@ typedef short SHORT; #endif /*i386*/ -#ifdef _WIN64 - -/* 64-bit architecture */ - -typedef INT64 INT, *PINT; -typedef LONG64 LONG, *PLONG; -typedef DWORD64 DWORD, *PDWORD; -typedef UINT64 UINT, *PUINT; -typedef ULONG64 ULONG, *PULONG; - -#else /* _WIN64 */ - -/* 32-bit architecture */ - typedef INT32 INT, *PINT; typedef LONG32 LONG, *PLONG; -typedef DWORD32 DWORD, *PDWORD; +typedef ULONG32 DWORD, *PDWORD; typedef UINT32 UINT, *PUINT; typedef ULONG32 ULONG, *PULONG; -#endif /* _WIN64 */ - #ifndef _WCHAR_T_ #define _WCHAR_T_ #define _WCHAR_T diff --git a/reactos/include/ntos/zw.h b/reactos/include/ntos/zw.h index d9212afa201..d893f401d48 100755 --- a/reactos/include/ntos/zw.h +++ b/reactos/include/ntos/zw.h @@ -1,5 +1,5 @@ -/* $Id: zw.h,v 1.10 2003/03/22 11:25:33 ekohl Exp $ +/* $Id: zw.h,v 1.11 2003/04/26 23:13:27 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -4514,7 +4514,7 @@ NtCreateThread( IN HANDLE ProcessHandle, OUT PCLIENT_ID ClientId, IN PCONTEXT ThreadContext, - IN PINITIAL_TEB InitialTeb, + IN PUSER_STACK UserStack, IN BOOLEAN CreateSuspended ); @@ -4527,7 +4527,7 @@ ZwCreateThread( IN HANDLE ProcessHandle, OUT PCLIENT_ID ClientId, IN PCONTEXT ThreadContext, - IN PINITIAL_TEB InitialTeb, + IN PUSER_STACK UserStack, IN BOOLEAN CreateSuspended ); diff --git a/reactos/lib/kernel32/process/create.c b/reactos/lib/kernel32/process/create.c index 4ce65fa8a25..5ec8980e4ba 100644 --- a/reactos/lib/kernel32/process/create.c +++ b/reactos/lib/kernel32/process/create.c @@ -1,4 +1,4 @@ -/* $Id: create.c,v 1.65 2003/04/07 23:10:07 gvg Exp $ +/* $Id: create.c,v 1.66 2003/04/26 23:13:28 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -21,17 +21,106 @@ __declspec(dllimport) PRTL_BASE_PROCESS_START_ROUTINE RtlBaseProcessStartRoutine; -WINBOOL STDCALL -CreateProcessA (LPCSTR lpApplicationName, - LPSTR lpCommandLine, - LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - WINBOOL bInheritHandles, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCSTR lpCurrentDirectory, - LPSTARTUPINFOA lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation) +typedef NTSTATUS STDCALL (K32_MBSTR_TO_WCSTR) +( + UNICODE_STRING *, + ANSI_STRING *, + BOOLEAN +); + +NTSTATUS STDCALL K32MbStrToWcStr +( + IN K32_MBSTR_TO_WCSTR * True, + UNICODE_STRING * DestStr, + ANSI_STRING * SourceStr, + BOOLEAN Allocate +) +{ + if(SourceStr->Buffer == NULL) + { + DestStr->Length = DestStr->MaximumLength = 0; + DestStr->Buffer = NULL; + return STATUS_SUCCESS; + } + + return True(DestStr, SourceStr, Allocate); +} + +VOID STDCALL RtlRosR32AttribsToNativeAttribs +( + OUT OBJECT_ATTRIBUTES * NativeAttribs, + IN SECURITY_ATTRIBUTES * Ros32Attribs OPTIONAL +) +{ + NativeAttribs->Length = sizeof(*NativeAttribs); + NativeAttribs->ObjectName = NULL; + NativeAttribs->RootDirectory = NULL; + NativeAttribs->Attributes = 0; + NativeAttribs->SecurityQualityOfService = NULL; + + + if(Ros32Attribs != NULL && Ros32Attribs->nLength >= sizeof(*Ros32Attribs)) + { + NativeAttribs->SecurityDescriptor = Ros32Attribs->lpSecurityDescriptor; + + if(Ros32Attribs->bInheritHandle) + NativeAttribs->Attributes |= OBJ_INHERIT; + } + else + NativeAttribs->SecurityDescriptor = NULL; +} + +VOID STDCALL RtlRosR32AttribsToNativeAttribsNamed +( + OUT OBJECT_ATTRIBUTES * NativeAttribs, + IN SECURITY_ATTRIBUTES * Ros32Attribs OPTIONAL, + OUT UNICODE_STRING * NativeName OPTIONAL, + IN WCHAR * Ros32Name OPTIONAL, + IN HANDLE Ros32NameRoot OPTIONAL +) +{ + if(!NativeAttribs) return; + + RtlRosR32AttribsToNativeAttribs(NativeAttribs, Ros32Attribs); + + if(Ros32Name != NULL && NativeName != NULL) + { + RtlInitUnicodeString(NativeName, Ros32Name); + + NativeAttribs->ObjectName = NativeName; + NativeAttribs->RootDirectory = Ros32NameRoot; + NativeAttribs->Attributes |= OBJ_CASE_INSENSITIVE; + } +} + +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, + LPSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + BOOL bInheritHandles, + DWORD dwCreationFlags, + LPVOID lpEnvironment, + LPCSTR lpCurrentDirectory, + LPSTARTUPINFOA lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation +) /* * FUNCTION: The CreateProcess function creates a new process and its * primary thread. The new process executes the specified executable file @@ -49,112 +138,185 @@ CreateProcessA (LPCSTR lpApplicationName, * lpProcessInformation = Pointer to process information */ { - PWCHAR lpEnvironmentW = NULL; - UNICODE_STRING ApplicationNameU; - UNICODE_STRING CurrentDirectoryU; - UNICODE_STRING CommandLineU; - ANSI_STRING ApplicationName; - ANSI_STRING CurrentDirectory; - ANSI_STRING CommandLine; - WINBOOL Result; - CHAR TempCurrentDirectoryA[256]; + PWCHAR pwcEnv = NULL; + UNICODE_STRING wstrApplicationName; + UNICODE_STRING wstrCurrentDirectory; + UNICODE_STRING wstrCommandLine; + UNICODE_STRING wstrReserved; + UNICODE_STRING wstrDesktop; + UNICODE_STRING wstrTitle; + ANSI_STRING strApplicationName; + ANSI_STRING strCurrentDirectory; + ANSI_STRING strCommandLine; + ANSI_STRING strReserved; + ANSI_STRING strDesktop; + ANSI_STRING strTitle; + BOOL bRetVal; + STARTUPINFOW wsiStartupInfo; - DPRINT("CreateProcessA(%s)\n", lpApplicationName); - DPRINT("dwCreationFlags %x, lpEnvironment %x, lpCurrentDirectory %x, " - "lpStartupInfo %x, lpProcessInformation %x\n", dwCreationFlags, - lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation); + NTSTATUS STDCALL (*pTrue) + ( + UNICODE_STRING *, + ANSI_STRING *, + BOOLEAN + ); - if (lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT)) - { - PCHAR ptr = lpEnvironment; - ULONG len = 0; - UNICODE_STRING EnvironmentU; - ANSI_STRING EnvironmentA; - while (*ptr) - { - RtlInitAnsiString(&EnvironmentA, ptr); - if (bIsFileApiAnsi) - len += RtlAnsiStringToUnicodeSize(&EnvironmentA) + sizeof(WCHAR); - else - len += RtlOemStringToUnicodeSize(&EnvironmentA) + sizeof(WCHAR); - ptr += EnvironmentA.MaximumLength; - } - len += sizeof(WCHAR); - lpEnvironmentW = (PWCHAR)RtlAllocateHeap(GetProcessHeap(), - HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY, - len); - if (lpEnvironmentW == NULL) - { - return FALSE; - } - ptr = lpEnvironment; - EnvironmentU.Buffer = lpEnvironmentW; - EnvironmentU.Length = 0; - EnvironmentU.MaximumLength = len; - while (*ptr) - { - RtlInitAnsiString(&EnvironmentA, ptr); - if (bIsFileApiAnsi) - RtlAnsiStringToUnicodeString(&EnvironmentU, &EnvironmentA, FALSE); - else - RtlOemStringToUnicodeString(&EnvironmentU, &EnvironmentA, FALSE); - ptr += EnvironmentA.MaximumLength; - EnvironmentU.Buffer += (EnvironmentU.Length / sizeof(WCHAR) + 1); - EnvironmentU.MaximumLength -= (EnvironmentU.Length + sizeof(WCHAR)); - EnvironmentU.Length = 0; - } + ULONG STDCALL (*pRtlMbStringToUnicodeSize)(ANSI_STRING *); - EnvironmentU.Buffer[0] = 0; - } - - RtlInitAnsiString (&CommandLine, - lpCommandLine); - RtlInitAnsiString (&ApplicationName, - (LPSTR)lpApplicationName); - if (lpCurrentDirectory != NULL) - { - RtlInitAnsiString (&CurrentDirectory, - (LPSTR)lpCurrentDirectory); - } + DPRINT("CreateProcessA(%s)\n", lpApplicationName); - /* convert ansi (or oem) strings to unicode */ - if (bIsFileApiAnsi) - { - RtlAnsiStringToUnicodeString (&CommandLineU, &CommandLine, TRUE); - RtlAnsiStringToUnicodeString (&ApplicationNameU, &ApplicationName, TRUE); - if (lpCurrentDirectory != NULL) - RtlAnsiStringToUnicodeString (&CurrentDirectoryU, &CurrentDirectory, TRUE); - } - else - { - RtlOemStringToUnicodeString (&CommandLineU, &CommandLine, TRUE); - RtlOemStringToUnicodeString (&ApplicationNameU, &ApplicationName, TRUE); - if (lpCurrentDirectory != NULL) - RtlOemStringToUnicodeString (&CurrentDirectoryU, &CurrentDirectory, TRUE); - } + DPRINT + ( + "dwCreationFlags %x, lpEnvironment %x, lpCurrentDirectory %x, " + "lpStartupInfo %x, lpProcessInformation %x\n", + dwCreationFlags, + lpEnvironment, + lpCurrentDirectory, + lpStartupInfo, + lpProcessInformation + ); - Result = CreateProcessW (ApplicationNameU.Buffer, - CommandLineU.Buffer, - lpProcessAttributes, - lpThreadAttributes, - bInheritHandles, - dwCreationFlags, - dwCreationFlags & CREATE_UNICODE_ENVIRONMENT ? lpEnvironment : lpEnvironmentW, - (lpCurrentDirectory == NULL) ? NULL : CurrentDirectoryU.Buffer, - (LPSTARTUPINFOW)lpStartupInfo, - lpProcessInformation); + /* invalid parameter */ + if(lpStartupInfo == NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } - RtlFreeUnicodeString (&ApplicationNameU); - RtlFreeUnicodeString (&CommandLineU); - if (lpCurrentDirectory != NULL) - RtlFreeUnicodeString (&CurrentDirectoryU); + /* multibyte strings are ANSI */ + if(bIsFileApiAnsi) + { + pTrue = RtlAnsiStringToUnicodeString; + pRtlMbStringToUnicodeSize = RtlAnsiStringToUnicodeSize; + } + /* multibyte strings are OEM */ + else + { + pTrue = RtlOemStringToUnicodeString; + pRtlMbStringToUnicodeSize = RtlOemStringToUnicodeSize; + } - if (lpEnvironmentW) - { - RtlFreeHeap(GetProcessHeap(), 0, lpEnvironmentW); - } + /* convert the environment */ + if(lpEnvironment && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT)) + { + PCHAR pcScan; + SIZE_T nEnvLen = 0; + UNICODE_STRING wstrEnvVar; + ANSI_STRING strEnvVar; - return Result; + /* scan the environment to calculate its Unicode size */ + for(pcScan = lpEnvironment; *pcScan; pcScan += strEnvVar.MaximumLength) + { + /* add the size of the current variable */ + RtlInitAnsiString(&strEnvVar, pcScan); + nEnvLen += pRtlMbStringToUnicodeSize(&strEnvVar) + sizeof(WCHAR); + } + + /* add the size of the final NUL character */ + nEnvLen += sizeof(WCHAR); + + /* environment too large */ + if(nEnvLen > ~((USHORT)0)) + { + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + + /* allocate the Unicode environment */ + pwcEnv = (PWCHAR)RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, nEnvLen); + + /* failure */ + if(pwcEnv == NULL) + { + SetLastError(ERROR_OUTOFMEMORY); + return FALSE; + } + + wstrEnvVar.Buffer = pwcEnv; + wstrEnvVar.Length = 0; + wstrEnvVar.MaximumLength = nEnvLen; + + /* scan the environment to convert it */ + for(pcScan = lpEnvironment; *pcScan; pcScan += strEnvVar.MaximumLength) + { + /* convert the current variable */ + RtlInitAnsiString(&strEnvVar, pcScan); + K32MbStrToWcStr(pTrue, &wstrEnvVar, &strEnvVar, FALSE); + + /* advance the buffer to the next variable */ + wstrEnvVar.Buffer += (wstrEnvVar.Length / sizeof(WCHAR) + 1); + wstrEnvVar.MaximumLength -= (wstrEnvVar.Length + sizeof(WCHAR)); + wstrEnvVar.Length = 0; + } + + /* final NUL character */ + wstrEnvVar.Buffer[0] = 0; + } + + /* convert the strings */ + RtlInitAnsiString(&strCommandLine, lpCommandLine); + RtlInitAnsiString(&strApplicationName, (LPSTR)lpApplicationName); + RtlInitAnsiString(&strCurrentDirectory, (LPSTR)lpCurrentDirectory); + RtlInitAnsiString(&strReserved, (LPSTR)lpStartupInfo->lpReserved); + RtlInitAnsiString(&strDesktop, (LPSTR)lpStartupInfo->lpDesktop); + RtlInitAnsiString(&strTitle, (LPSTR)lpStartupInfo->lpTitle); + + K32MbStrToWcStr(pTrue, &wstrCommandLine, &strCommandLine, TRUE); + K32MbStrToWcStr(pTrue, &wstrApplicationName, &strApplicationName, TRUE); + K32MbStrToWcStr(pTrue, &wstrCurrentDirectory, &strCurrentDirectory, TRUE); + K32MbStrToWcStr(pTrue, &wstrReserved, &strReserved, TRUE); + K32MbStrToWcStr(pTrue, &wstrDesktop, &strDesktop, TRUE); + K32MbStrToWcStr(pTrue, &wstrTitle, &strTitle, TRUE); + + /* convert the startup information */ + memcpy(&wsiStartupInfo, lpStartupInfo, sizeof(wsiStartupInfo)); + + wsiStartupInfo.lpReserved = wstrReserved.Buffer; + wsiStartupInfo.lpDesktop = wstrDesktop.Buffer; + wsiStartupInfo.lpTitle = wstrTitle.Buffer; + + DPRINT("wstrApplicationName %wZ\n", &wstrApplicationName); + DPRINT("wstrCommandLine %wZ\n", &wstrCommandLine); + DPRINT("wstrCurrentDirectory %wZ\n", &wstrCurrentDirectory); + DPRINT("wstrReserved %wZ\n", &wstrReserved); + DPRINT("wstrDesktop %wZ\n", &wstrDesktop); + DPRINT("wstrTitle %wZ\n", &wstrTitle); + + DPRINT("wstrApplicationName.Buffer %p\n", wstrApplicationName.Buffer); + DPRINT("wstrCommandLine.Buffer %p\n", wstrCommandLine.Buffer); + DPRINT("wstrCurrentDirectory.Buffer %p\n", wstrCurrentDirectory.Buffer); + DPRINT("wstrReserved.Buffer %p\n", wstrReserved.Buffer); + DPRINT("wstrDesktop.Buffer %p\n", wstrDesktop.Buffer); + DPRINT("wstrTitle.Buffer %p\n", wstrTitle.Buffer); + + DPRINT("sizeof(STARTUPINFOA) %lu\n", sizeof(STARTUPINFOA)); + DPRINT("sizeof(STARTUPINFOW) %lu\n", sizeof(STARTUPINFOW)); + + /* call the Unicode function */ + bRetVal = CreateProcessW + ( + wstrApplicationName.Buffer, + wstrCommandLine.Buffer, + lpProcessAttributes, + lpThreadAttributes, + bInheritHandles, + dwCreationFlags, + dwCreationFlags & CREATE_UNICODE_ENVIRONMENT ? lpEnvironment : pwcEnv, + wstrCurrentDirectory.Buffer, + &wsiStartupInfo, + lpProcessInformation + ); + + RtlFreeUnicodeString(&wstrApplicationName); + RtlFreeUnicodeString(&wstrCommandLine); + RtlFreeUnicodeString(&wstrCurrentDirectory); + RtlFreeUnicodeString(&wstrReserved); + RtlFreeUnicodeString(&wstrDesktop); + RtlFreeUnicodeString(&wstrTitle); + + RtlFreeHeap(GetProcessHeap(), 0, pwcEnv); + + return bRetVal; } static int _except_recursion_trap = 0; @@ -171,9 +333,9 @@ _except_handler( struct _CONTEXT *ContextRecord, void * DispatcherContext ) { - DPRINT1("Process terminated abnormally due to unhandled exception\n"); + DPRINT1("Process terminated abnormally due to unhandled exception\n"); - if (3 < ++_except_recursion_trap) + if (3 < ++_except_recursion_trap) { DPRINT1("_except_handler(...) appears to be recursing.\n"); DPRINT1("Process HALTED.\n"); @@ -220,188 +382,61 @@ BaseProcessStart(LPTHREAD_START_ROUTINE lpStartAddress, } -HANDLE STDCALL -KlCreateFirstThread(HANDLE ProcessHandle, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - PSECTION_IMAGE_INFORMATION Sii, - LPTHREAD_START_ROUTINE lpStartAddress, - DWORD dwCreationFlags, - LPDWORD lpThreadId) +HANDLE STDCALL KlCreateFirstThread +( + HANDLE ProcessHandle, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + PSECTION_IMAGE_INFORMATION Sii, + LPTHREAD_START_ROUTINE lpStartAddress, + DWORD dwCreationFlags, + LPDWORD lpThreadId +) { - NTSTATUS Status; - HANDLE ThreadHandle; - OBJECT_ATTRIBUTES ObjectAttributes; - CLIENT_ID ClientId; - CONTEXT ThreadContext; - INITIAL_TEB InitialTeb; - BOOLEAN CreateSuspended = FALSE; - ULONG OldPageProtection; - ULONG ResultLength; - ULONG ThreadStartAddress; - ULONG InitialStack[6]; + OBJECT_ATTRIBUTES oaThreadAttribs; + CLIENT_ID cidClientId; + PVOID pTrueStartAddress; + NTSTATUS nErrCode; + HANDLE hThread; - ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); - ObjectAttributes.RootDirectory = NULL; - ObjectAttributes.ObjectName = NULL; - ObjectAttributes.Attributes = 0; - if (lpThreadAttributes != NULL) - { - if (lpThreadAttributes->bInheritHandle) - ObjectAttributes.Attributes = OBJ_INHERIT; - ObjectAttributes.SecurityDescriptor = - lpThreadAttributes->lpSecurityDescriptor; - } - ObjectAttributes.SecurityQualityOfService = NULL; + /* convert the thread attributes */ + RtlRosR32AttribsToNativeAttribs(&oaThreadAttribs, lpThreadAttributes); - if ((dwCreationFlags & CREATE_SUSPENDED) == CREATE_SUSPENDED) - CreateSuspended = TRUE; - else - CreateSuspended = FALSE; + /* native image */ + if(Sii->Subsystem != IMAGE_SUBSYSTEM_NATIVE) + pTrueStartAddress = (PVOID)BaseProcessStart; + /* Win32 image */ + else + pTrueStartAddress = (PVOID)RtlBaseProcessStartRoutine; - InitialTeb.StackReserve = (Sii->StackReserve < 0x100000) ? 0x100000 : Sii->StackReserve; - /* FIXME: use correct commit size */ -#if 0 - InitialTeb.StackCommit = (Sii->StackCommit < PAGE_SIZE) ? PAGE_SIZE : Sii->StackCommit; -#endif - InitialTeb.StackCommit = InitialTeb.StackReserve - PAGE_SIZE; + /* create the first thread */ + nErrCode = RtlCreateUserThreadVa + ( + ProcessHandle, + &oaThreadAttribs, + dwCreationFlags & CREATE_SUSPENDED, + 0, + &(Sii->StackReserve), + &(Sii->StackCommit), + pTrueStartAddress, + &hThread, + &cidClientId, + 2, + (ULONG_PTR)lpStartAddress, + (ULONG_PTR)PEB_BASE + ); - /* size of guard page */ - InitialTeb.StackCommit += PAGE_SIZE; + /* failure */ + if(!NT_SUCCESS(nErrCode)) + { + SetLastErrorByStatus(nErrCode); + return NULL; + } - /* Reserve stack */ - InitialTeb.StackAllocate = NULL; - Status = NtAllocateVirtualMemory(ProcessHandle, - &InitialTeb.StackAllocate, - 0, - &InitialTeb.StackReserve, - MEM_RESERVE, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - DPRINT("Error reserving stack space!\n"); - SetLastErrorByStatus(Status); - return(INVALID_HANDLE_VALUE); - } - - DPRINT("StackAllocate: %p ReserveSize: 0x%lX\n", - InitialTeb.StackAllocate, InitialTeb.StackReserve); - - InitialTeb.StackBase = (PVOID)((ULONG)InitialTeb.StackAllocate + InitialTeb.StackReserve); - InitialTeb.StackLimit = (PVOID)((ULONG)InitialTeb.StackBase - InitialTeb.StackCommit); - - DPRINT("StackBase: %p StackCommit: %p\n", - InitialTeb.StackBase, InitialTeb.StackCommit); - - /* Commit stack page(s) */ - Status = NtAllocateVirtualMemory(ProcessHandle, - &InitialTeb.StackLimit, - 0, - &InitialTeb.StackCommit, - MEM_COMMIT, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - /* release the stack space */ - NtFreeVirtualMemory(ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); - - DPRINT("Error comitting stack page(s)!\n"); - SetLastErrorByStatus(Status); - return(INVALID_HANDLE_VALUE); - } - - DPRINT("StackLimit: %p\n", - InitialTeb.StackLimit); - - /* Protect guard page */ - Status = NtProtectVirtualMemory(ProcessHandle, - InitialTeb.StackLimit, - PAGE_SIZE, - PAGE_GUARD | PAGE_READWRITE, - &OldPageProtection); - if (!NT_SUCCESS(Status)) - { - /* release the stack space */ - NtFreeVirtualMemory(ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); - - DPRINT("Error comitting guard page!\n"); - SetLastErrorByStatus(Status); - return(INVALID_HANDLE_VALUE); - } - - if (Sii->Subsystem != IMAGE_SUBSYSTEM_NATIVE) - { - ThreadStartAddress = (ULONG) BaseProcessStart; - } - else - { - ThreadStartAddress = (ULONG) RtlBaseProcessStartRoutine; - } - - memset(&ThreadContext,0,sizeof(CONTEXT)); - ThreadContext.Eip = ThreadStartAddress; - ThreadContext.SegGs = USER_DS; - ThreadContext.SegFs = USER_DS; - ThreadContext.SegEs = USER_DS; - ThreadContext.SegDs = USER_DS; - ThreadContext.SegCs = USER_CS; - ThreadContext.SegSs = USER_DS; - ThreadContext.Esp = (ULONG)InitialTeb.StackBase - 6*4; - ThreadContext.EFlags = (1<<1) + (1<<9); - - DPRINT("ThreadContext.Eip %x\n",ThreadContext.Eip); - - /* - * Write in the initial stack. - */ - InitialStack[0] = 0; - InitialStack[1] = (DWORD)lpStartAddress; - InitialStack[2] = PEB_BASE; - - Status = ZwWriteVirtualMemory(ProcessHandle, - (PVOID)ThreadContext.Esp, - InitialStack, - sizeof(InitialStack), - &ResultLength); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to write initial stack.\n"); - return(INVALID_HANDLE_VALUE); - } - - Status = NtCreateThread(&ThreadHandle, - THREAD_ALL_ACCESS, - &ObjectAttributes, - ProcessHandle, - &ClientId, - &ThreadContext, - &InitialTeb, - CreateSuspended); - if (!NT_SUCCESS(Status)) - { - NtFreeVirtualMemory(ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); - SetLastErrorByStatus(Status); - return(INVALID_HANDLE_VALUE); - } - - if (lpThreadId != NULL) - { - memcpy(lpThreadId, &ClientId.UniqueThread,sizeof(ULONG)); - } - - return(ThreadHandle); + /* success */ + return hThread; } -HANDLE -KlMapFile(LPCWSTR lpApplicationName) +HANDLE KlMapFile(LPCWSTR lpApplicationName) { HANDLE hFile; IO_STATUS_BLOCK IoStatusBlock; @@ -470,20 +505,22 @@ KlMapFile(LPCWSTR lpApplicationName) return(hSection); } -static NTSTATUS -KlInitPeb (HANDLE ProcessHandle, - PRTL_USER_PROCESS_PARAMETERS Ppb, - PVOID* ImageBaseAddress) +static NTSTATUS KlInitPeb +( + HANDLE ProcessHandle, + PRTL_USER_PROCESS_PARAMETERS Ppb, + PVOID * ImageBaseAddress +) { - NTSTATUS Status; - PVOID PpbBase; - ULONG PpbSize; - ULONG BytesWritten; - ULONG Offset; - PVOID ParentEnv = NULL; - PVOID EnvPtr = NULL; - PWCHAR ptr; - ULONG EnvSize = 0, EnvSize1 = 0; + NTSTATUS Status; + PVOID PpbBase; + ULONG PpbSize; + ULONG BytesWritten; + ULONG Offset; + PVOID ParentEnv = NULL; + PVOID EnvPtr = NULL; + PWCHAR ptr; + ULONG EnvSize = 0, EnvSize1 = 0; /* create the Environment */ if (Ppb->Environment != NULL) @@ -588,16 +625,19 @@ KlInitPeb (HANDLE ProcessHandle, WINBOOL STDCALL -CreateProcessW(LPCWSTR lpApplicationName, - LPWSTR lpCommandLine, - LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - WINBOOL bInheritHandles, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCWSTR lpCurrentDirectory, - LPSTARTUPINFOW lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation) +CreateProcessW +( + LPCWSTR lpApplicationName, + LPWSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + WINBOOL bInheritHandles, + DWORD dwCreationFlags, + LPVOID lpEnvironment, + LPCWSTR lpCurrentDirectory, + LPSTARTUPINFOW lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation +) { HANDLE hSection, hProcess, hThread; NTSTATUS Status; @@ -687,6 +727,9 @@ CreateProcessW(LPCWSTR lpApplicationName, return FALSE; } + DPRINT("CreateProcessW(lpApplicationName '%S', lpCommandLine '%S')\n", + lpApplicationName, lpCommandLine); + if (!SearchPathW(NULL, TempApplicationNameW, NULL, sizeof(ImagePathName)/sizeof(WCHAR), ImagePathName, &s)) { return FALSE; diff --git a/reactos/lib/kernel32/process/proc.c b/reactos/lib/kernel32/process/proc.c index a8122079c00..782041c5845 100644 --- a/reactos/lib/kernel32/process/proc.c +++ b/reactos/lib/kernel32/process/proc.c @@ -1,4 +1,4 @@ -/* $Id: proc.c,v 1.52 2003/03/06 15:05:29 ekohl Exp $ +/* $Id: proc.c,v 1.53 2003/04/26 23:13:28 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -564,6 +564,10 @@ ExitProcess(UINT uExitCode) NtTerminateProcess (NtCurrentProcess (), uExitCode); + + /* should never get here */ + assert(0); + while(1); } diff --git a/reactos/lib/kernel32/thread/thread.c b/reactos/lib/kernel32/thread/thread.c index 59e7b817714..b81ffd6e3bb 100644 --- a/reactos/lib/kernel32/thread/thread.c +++ b/reactos/lib/kernel32/thread/thread.c @@ -1,4 +1,4 @@ -/* $Id: thread.c,v 1.36 2003/02/17 16:30:17 ekohl Exp $ +/* $Id: thread.c,v 1.37 2003/04/26 23:13:28 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -17,11 +17,26 @@ #define NDEBUG #include - //static VOID ThreadAttachDlls (VOID); /* 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, @@ -54,184 +69,129 @@ ThreadStartup(LPTHREAD_START_ROUTINE lpStartAddress, } -HANDLE STDCALL -CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, - DWORD dwStackSize, - LPTHREAD_START_ROUTINE lpStartAddress, - LPVOID lpParameter, - DWORD dwCreationFlags, - LPDWORD lpThreadId) +HANDLE STDCALL CreateThread +( + LPSECURITY_ATTRIBUTES lpThreadAttributes, + DWORD dwStackSize, + LPTHREAD_START_ROUTINE lpStartAddress, + LPVOID lpParameter, + DWORD dwCreationFlags, + LPDWORD lpThreadId +) { - return(CreateRemoteThread(NtCurrentProcess(), - lpThreadAttributes, - dwStackSize, - lpStartAddress, - lpParameter, - dwCreationFlags, - lpThreadId)); + return CreateRemoteThread + ( + NtCurrentProcess(), + lpThreadAttributes, + dwStackSize, + lpStartAddress, + lpParameter, + dwCreationFlags, + lpThreadId + ); } -HANDLE STDCALL -CreateRemoteThread(HANDLE hProcess, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - DWORD dwStackSize, - LPTHREAD_START_ROUTINE lpStartAddress, - LPVOID lpParameter, - DWORD dwCreationFlags, - LPDWORD lpThreadId) +HANDLE STDCALL CreateRemoteThread +( + HANDLE hProcess, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + DWORD dwStackSize, + LPTHREAD_START_ROUTINE lpStartAddress, + LPVOID lpParameter, + DWORD dwCreationFlags, + LPDWORD lpThreadId +) { - HANDLE ThreadHandle; - OBJECT_ATTRIBUTES ObjectAttributes; - CLIENT_ID ClientId; - CONTEXT ThreadContext; - INITIAL_TEB InitialTeb; - BOOLEAN CreateSuspended = FALSE; - PVOID BaseAddress; - ULONG OldPageProtection; - NTSTATUS Status; + PSECURITY_DESCRIPTOR pSD = NULL; + HANDLE hThread; + CLIENT_ID cidClientId; + NTSTATUS nErrCode; + ULONG_PTR nStackReserve; + ULONG_PTR nStackCommit; + OBJECT_ATTRIBUTES oaThreadAttribs; + PIMAGE_NT_HEADERS pinhHeader = + RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress); - ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); - ObjectAttributes.RootDirectory = NULL; - ObjectAttributes.ObjectName = NULL; - ObjectAttributes.Attributes = 0; - if (lpThreadAttributes != NULL) - { - if (lpThreadAttributes->bInheritHandle) - ObjectAttributes.Attributes = OBJ_INHERIT; - ObjectAttributes.SecurityDescriptor = - lpThreadAttributes->lpSecurityDescriptor; - } - ObjectAttributes.SecurityQualityOfService = NULL; + /* FIXME: do more checks - e.g. the image may not have an optional header */ + if(pinhHeader == NULL) + { + nStackReserve = 0x100000; + nStackCommit = PAGE_SIZE; + } + else + { + nStackReserve = pinhHeader->OptionalHeader.SizeOfStackReserve; + nStackCommit = pinhHeader->OptionalHeader.SizeOfStackCommit; + } - if ((dwCreationFlags & CREATE_SUSPENDED) == CREATE_SUSPENDED) - CreateSuspended = TRUE; - else - CreateSuspended = FALSE; - - InitialTeb.StackReserve = 0x100000; /* 1MByte */ - /* FIXME: use correct commit size */ -#if 0 - InitialTeb.StackCommit = (dwStackSize == 0) ? PAGE_SIZE : dwStackSize; + /* FIXME: this should be defined in winbase.h */ +#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION +#define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000 #endif - InitialTeb.StackCommit = InitialTeb.StackReserve - PAGE_SIZE; - /* size of guard page */ - InitialTeb.StackCommit += PAGE_SIZE; + /* use defaults */ + if(dwStackSize == 0); + /* dwStackSize specifies the size to reserve */ + else if(dwCreationFlags & STACK_SIZE_PARAM_IS_A_RESERVATION) + nStackReserve = dwStackSize; + /* dwStackSize specifies the size to commit */ + else + nStackCommit = dwStackSize; - /* Reserve stack */ - InitialTeb.StackAllocate = NULL; - Status = NtAllocateVirtualMemory(hProcess, - &InitialTeb.StackAllocate, - 0, - &InitialTeb.StackReserve, - MEM_RESERVE, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - DPRINT("Error reserving stack space!\n"); - SetLastErrorByStatus(Status); - return(NULL); - } + /* fix the stack reserve size */ + if(nStackCommit > nStackReserve) + nStackReserve = ROUNDUP(nStackCommit, 0x100000); - DPRINT("StackDeallocation: %p ReserveSize: 0x%lX\n", - InitialTeb.StackDeallocation, InitialTeb.StackReserve); + /* initialize the attributes for the thread object */ + InitializeObjectAttributes + ( + &oaThreadAttribs, + NULL, + 0, + NULL, + NULL + ); + + if(lpThreadAttributes) + { + /* make the handle inheritable */ + if(lpThreadAttributes->bInheritHandle) + oaThreadAttribs.Attributes |= OBJ_INHERIT; - InitialTeb.StackBase = (PVOID)((ULONG)InitialTeb.StackAllocate + InitialTeb.StackReserve); - InitialTeb.StackLimit = (PVOID)((ULONG)InitialTeb.StackBase - InitialTeb.StackCommit); + /* user-defined security descriptor */ + oaThreadAttribs.SecurityDescriptor = lpThreadAttributes->lpSecurityDescriptor; + } - DPRINT("StackBase: %p\nStackCommit: 0x%lX\n", - InitialTeb.StackBase, - InitialTeb.StackCommit); + /* create the thread */ + nErrCode = RtlCreateUserThreadVa + ( + hProcess, + &oaThreadAttribs, + dwCreationFlags & CREATE_SUSPENDED, + 0, + &nStackReserve, + &nStackCommit, + (PTHREAD_START_ROUTINE)ThreadStartup, + &hThread, + &cidClientId, + 2, + lpStartAddress, + lpParameter + ); - /* Commit stack pages */ - Status = NtAllocateVirtualMemory(hProcess, - &InitialTeb.StackLimit, - 0, - &InitialTeb.StackCommit, - MEM_COMMIT, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - /* release the stack space */ - NtFreeVirtualMemory(hProcess, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); + /* failure */ + if(!NT_SUCCESS(nErrCode)) + { + SetLastErrorByStatus(nErrCode); + return NULL; + } - DPRINT("Error comitting stack page(s)!\n"); - SetLastErrorByStatus(Status); - return(NULL); - } - - DPRINT("StackLimit: %p\n", - InitialTeb.StackLimit); - - /* Protect guard page */ - Status = NtProtectVirtualMemory(hProcess, - InitialTeb.StackLimit, - PAGE_SIZE, - PAGE_GUARD | PAGE_READWRITE, - &OldPageProtection); - if (!NT_SUCCESS(Status)) - { - /* release the stack space */ - NtFreeVirtualMemory(hProcess, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); - - DPRINT("Error comitting guard page!\n"); - SetLastErrorByStatus(Status); - return(NULL); - } - - memset(&ThreadContext,0,sizeof(CONTEXT)); - ThreadContext.Eip = (LONG)ThreadStartup; - ThreadContext.SegGs = USER_DS; - ThreadContext.SegFs = TEB_SELECTOR; - ThreadContext.SegEs = USER_DS; - ThreadContext.SegDs = USER_DS; - ThreadContext.SegCs = USER_CS; - ThreadContext.SegSs = USER_DS; - ThreadContext.Esp = (ULONG)InitialTeb.StackBase - 12; - ThreadContext.EFlags = (1<<1) + (1<<9); - - /* initialize call stack */ - *((PULONG)((ULONG)InitialTeb.StackBase - 4)) = (ULONG)lpParameter; - *((PULONG)((ULONG)InitialTeb.StackBase - 8)) = (ULONG)lpStartAddress; - *((PULONG)((ULONG)InitialTeb.StackBase - 12)) = 0xdeadbeef; - - DPRINT("Esp: %p\n", ThreadContext.Esp); - DPRINT("Eip: %p\n", ThreadContext.Eip); - - Status = NtCreateThread(&ThreadHandle, - THREAD_ALL_ACCESS, - &ObjectAttributes, - hProcess, - &ClientId, - &ThreadContext, - &InitialTeb, - CreateSuspended); - if (!NT_SUCCESS(Status)) - { - NtFreeVirtualMemory(hProcess, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); - - DPRINT("NtCreateThread() failed!\n"); - SetLastErrorByStatus(Status); - return(NULL); - } - - if (lpThreadId != NULL) - memcpy(lpThreadId, &ClientId.UniqueThread,sizeof(ULONG)); - - return(ThreadHandle); + /* success */ + if(lpThreadId) *lpThreadId = (DWORD)cidClientId.UniqueThread; + return hThread; } - PTEB GetTeb(VOID) { diff --git a/reactos/lib/ntdll/dbg/brkpoint.c b/reactos/lib/ntdll/dbg/brkpoint.c index 1c142dde0ac..bf09b213ce8 100644 --- a/reactos/lib/ntdll/dbg/brkpoint.c +++ b/reactos/lib/ntdll/dbg/brkpoint.c @@ -1,4 +1,4 @@ -/* $Id: brkpoint.c,v 1.4 2002/09/08 10:23:03 chorns Exp $ +/* $Id: brkpoint.c,v 1.5 2003/04/26 23:13:28 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -12,18 +12,33 @@ /* INCLUDES *****************************************************************/ #include - +#include /* FUNCTIONS *****************************************************************/ -VOID STDCALL DbgBreakPoint(VOID) -{ - __asm__("int $3\n\t"); -} +#if 0 +/* + FIXME: DbgBreakPoint must not have a stack frame, but GCC doesn't support + __declspec(naked) yet +*/ +__declspec(naked) VOID STDCALL DbgBreakPoint(VOID) +{ __asm__(ASM_BREAKPOINT_STR); } VOID STDCALL DbgUserBreakPoint(VOID) -{ - __asm__("int $3\n\t"); -} +{ __asm__(ASM_BREAKPOINT_STR); } +#else +#define DBG_BP_FUNC(__NAME__) \ +__asm__ \ +( \ + "\n" \ + ".global _" #__NAME__ "@0\n" \ + "_" #__NAME__ "@0:\n" \ + ASM_BREAKPOINT \ + "ret $0\n" \ +) + +DBG_BP_FUNC(DbgBreakPoint); +DBG_BP_FUNC(DbgUserBreakPoint); +#endif /* EOF */ diff --git a/reactos/lib/ntdll/dbg/debug.c b/reactos/lib/ntdll/dbg/debug.c index 8d3577fadb5..e7b15fdb4e2 100644 --- a/reactos/lib/ntdll/dbg/debug.c +++ b/reactos/lib/ntdll/dbg/debug.c @@ -1,4 +1,4 @@ -/* $Id: debug.c,v 1.8 2003/03/31 22:32:18 hyperion Exp $ +/* $Id: debug.c,v 1.9 2003/04/26 23:13:28 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -183,6 +183,7 @@ NTSTATUS STDCALL DbgUiIssueRemoteBreakin(HANDLE Process) HANDLE hThread; CLIENT_ID cidClientId; NTSTATUS nErrCode; + ULONG nStackSize = PAGE_SIZE; nErrCode = RtlCreateUserThread ( @@ -190,8 +191,8 @@ NTSTATUS STDCALL DbgUiIssueRemoteBreakin(HANDLE Process) NULL, FALSE, 0, - NULL, - NULL, + &nStackSize, + &nStackSize, (PTHREAD_START_ROUTINE)DbgUiRemoteBreakin, NULL, &hThread, diff --git a/reactos/lib/ntdll/def/ntdll.def b/reactos/lib/ntdll/def/ntdll.def index bc18bebd871..b5466ab6c8c 100644 --- a/reactos/lib/ntdll/def/ntdll.def +++ b/reactos/lib/ntdll/def/ntdll.def @@ -1,4 +1,4 @@ -; $Id: ntdll.def,v 1.96 2003/04/02 00:06:00 hyperion Exp $ +; $Id: ntdll.def,v 1.97 2003/04/26 23:13:29 hyperion Exp $ ; ; ReactOS Operating System ; @@ -347,6 +347,8 @@ RtlCreateUnicodeStringFromAsciiz@8 RtlCreateUserProcess@40 ;RtlCreateUserSecurityObject RtlCreateUserThread@40 +RtlCreateUserThread@44 +RtlCreateUserThreadVa RtlCustomCPToUnicodeN@24 ;RtlCutoverTimeToSystemTime RtlDeNormalizeProcessParams@4 @@ -448,6 +450,7 @@ RtlInitUnicodeString@8 ;RtlInitializeAtomPackage RtlInitializeBitMap@12 RtlInitializeContext@20 +RtlInitializeContextEx@24 RtlInitializeCriticalSection@4 ;RtlInitializeGenericTable RtlInitializeHandleTable@12 diff --git a/reactos/lib/ntdll/def/ntdll.edf b/reactos/lib/ntdll/def/ntdll.edf index d6fbcc622a1..8f75ed35310 100644 --- a/reactos/lib/ntdll/def/ntdll.edf +++ b/reactos/lib/ntdll/def/ntdll.edf @@ -1,4 +1,4 @@ -; $Id: ntdll.edf,v 1.85 2003/04/02 00:06:00 hyperion Exp $ +; $Id: ntdll.edf,v 1.86 2003/04/26 23:13:29 hyperion Exp $ ; ; ReactOS Operating System ; @@ -347,6 +347,8 @@ RtlCreateUnicodeStringFromAsciiz=RtlCreateUnicodeStringFromAsciiz@8 RtlCreateUserProcess=RtlCreateUserProcess@40 ;RtlCreateUserSecurityObject RtlCreateUserThread=RtlCreateUserThread@40 +RtlCreateUserThreadEx=RtlCreateUserThreadEx@44 +RtlCreateUserThreadVa=RtlCreateUserThreadVa RtlCustomCPToUnicodeN=RtlCustomCPToUnicodeN@24 ;RtlCutoverTimeToSystemTime RtlDeNormalizeProcessParams=RtlDeNormalizeProcessParams@4 @@ -447,6 +449,7 @@ RtlInitUnicodeString=RtlInitUnicodeString@8 ;RtlInitializeAtomPackage RtlInitializeBitMap=RtlInitializeBitMap@12 RtlInitializeContext=RtlInitializeContext@20 +RtlInitializeContextEx=RtlInitializeContextEx@24 RtlInitializeCriticalSection=RtlInitializeCriticalSection@4 ;RtlInitializeGenericTable RtlInitializeHandleTable=RtlInitializeHandleTable@12 diff --git a/reactos/lib/ntdll/ldr/startup.c b/reactos/lib/ntdll/ldr/startup.c index d98cb22fa42..7365a437b3e 100644 --- a/reactos/lib/ntdll/ldr/startup.c +++ b/reactos/lib/ntdll/ldr/startup.c @@ -1,4 +1,4 @@ -/* $Id: startup.c,v 1.48 2003/04/18 08:29:35 gvg Exp $ +/* $Id: startup.c,v 1.49 2003/04/26 23:13:29 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -38,9 +38,46 @@ ULONG NtGlobalFlag = 0; /* FUNCTIONS *****************************************************************/ +#if 0 +/* FIXME: why doesn't gcc recognize __declspec(naked)? */ +__declspec(naked) VOID STDCALL LdrInitializeThunk +( + ULONG Unknown1, + ULONG Unknown2, + ULONG Unknown3, + ULONG Unknown4 +) +{ + __asm__ + ( +#else + __asm__ + ( + "\n" + ".global _LdrInitializeThunk@16\n" + "_LdrInitializeThunk@16:\n" +#endif + +#if defined(_M_IX86) + "nop\n" /* breakin overwrites this with "int 3" */ + "jmp" +#elif defined(_M_ALPHA) + "nop\n" /* breakin overwrites this with "call_pal bpt" */ + "br" +#elif defined(_M_MIPS) + "nop\n" /* breakin overwrites this with "break" */ + "j" +#else +#error Unsupported architecture. +#endif + " ___true_LdrInitializeThunk@16\n" + ); +#if 0 +} +#endif VOID STDCALL -LdrInitializeThunk (ULONG Unknown1, +__true_LdrInitializeThunk (ULONG Unknown1, ULONG Unknown2, ULONG Unknown3, ULONG Unknown4) diff --git a/reactos/lib/ntdll/rtl/process.c b/reactos/lib/ntdll/rtl/process.c index 97c7a7c89be..b76f0bbcb15 100644 --- a/reactos/lib/ntdll/rtl/process.c +++ b/reactos/lib/ntdll/rtl/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.32 2002/10/20 11:56:00 chorns Exp $ +/* $Id: process.c,v 1.33 2003/04/26 23:13:29 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -22,160 +22,29 @@ /* FUNCTIONS ****************************************************************/ -static NTSTATUS -RtlpCreateFirstThread(HANDLE ProcessHandle, - ULONG StackReserve, - ULONG StackCommit, - LPTHREAD_START_ROUTINE lpStartAddress, - PCLIENT_ID ClientId, - PHANDLE ThreadHandle) +static NTSTATUS RtlpCreateFirstThread +( + HANDLE ProcessHandle, + ULONG StackReserve, + ULONG StackCommit, + LPTHREAD_START_ROUTINE lpStartAddress, + PCLIENT_ID ClientId, + PHANDLE ThreadHandle +) { - NTSTATUS Status; - OBJECT_ATTRIBUTES ObjectAttributes; - CONTEXT ThreadContext; - INITIAL_TEB InitialTeb; - ULONG OldPageProtection; - CLIENT_ID Cid; - ULONG InitialStack[5]; - ULONG ResultLength; - - ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); - ObjectAttributes.RootDirectory = NULL; - ObjectAttributes.ObjectName = NULL; - ObjectAttributes.Attributes = 0; - ObjectAttributes.SecurityQualityOfService = NULL; - - if (StackReserve > 0x100000) - InitialTeb.StackReserve = StackReserve; - else - InitialTeb.StackReserve = 0x100000; /* 1MByte */ - - /* FIXME */ -#if 0 - if (StackCommit > PAGE_SIZE) - InitialTeb.StackCommit = StackCommit; - else - InitialTeb.StackCommit = PAGE_SIZE; -#endif - InitialTeb.StackCommit = InitialTeb.StackReserve - PAGE_SIZE; - - /* add guard page size */ - InitialTeb.StackCommit += PAGE_SIZE; - - /* Reserve stack */ - InitialTeb.StackAllocate = NULL; - Status = NtAllocateVirtualMemory(ProcessHandle, - &InitialTeb.StackAllocate, - 0, - &InitialTeb.StackReserve, - MEM_RESERVE, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - DPRINT("Error reserving stack space!\n"); - return(Status); - } - - DPRINT("StackAllocate: %p ReserveSize: 0x%lX\n", - InitialTeb.StackAllocate, InitialTeb.StackReserve); - - InitialTeb.StackBase = (PVOID)((ULONG)InitialTeb.StackAllocate + InitialTeb.StackReserve); - InitialTeb.StackLimit = (PVOID)((ULONG)InitialTeb.StackBase - InitialTeb.StackCommit); - - DPRINT("StackBase: %p StackCommit: 0x%lX\n", - InitialTeb.StackBase, InitialTeb.StackCommit); - - /* Commit stack */ - Status = NtAllocateVirtualMemory(ProcessHandle, - &InitialTeb.StackLimit, - 0, - &InitialTeb.StackCommit, - MEM_COMMIT, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - /* release the stack space */ - NtFreeVirtualMemory(ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); - - DPRINT("Error comitting stack page(s)!\n"); - return(Status); - } - - DPRINT("StackLimit: %p\n", InitialTeb.StackLimit); - - /* Protect guard page */ - Status = NtProtectVirtualMemory(ProcessHandle, - InitialTeb.StackLimit, - PAGE_SIZE, - PAGE_GUARD | PAGE_READWRITE, - &OldPageProtection); - if (!NT_SUCCESS(Status)) - { - /* release the stack space */ - NtFreeVirtualMemory(ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); - - DPRINT("Error comitting guard page!\n"); - return(Status); - } - - memset(&ThreadContext,0,sizeof(CONTEXT)); - ThreadContext.Eip = (ULONG)lpStartAddress; - ThreadContext.SegGs = USER_DS; - ThreadContext.SegFs = TEB_SELECTOR; - ThreadContext.SegEs = USER_DS; - ThreadContext.SegDs = USER_DS; - ThreadContext.SegCs = USER_CS; - ThreadContext.SegSs = USER_DS; - ThreadContext.Esp = (ULONG)InitialTeb.StackBase - 20; - ThreadContext.EFlags = (1<<1) + (1<<9); - - DPRINT("ThreadContext.Eip %x\n",ThreadContext.Eip); - - /* - * Write in the initial stack. - */ - InitialStack[0] = 0; - InitialStack[1] = PEB_BASE; - Status = ZwWriteVirtualMemory(ProcessHandle, - (PVOID)ThreadContext.Esp, - InitialStack, - sizeof(InitialStack), - &ResultLength); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to write initial stack.\n"); - return(Status); - } - - Status = NtCreateThread(ThreadHandle, - THREAD_ALL_ACCESS, - &ObjectAttributes, - ProcessHandle, - &Cid, - &ThreadContext, - &InitialTeb, - FALSE); - if (!NT_SUCCESS(Status)) - { - NtFreeVirtualMemory(ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); - return(Status); - } - - if (ClientId != NULL) - { - memcpy(&ClientId->UniqueThread, &Cid.UniqueThread, sizeof(ULONG)); - } - - return(STATUS_SUCCESS); + return RtlCreateUserThread + ( + ProcessHandle, + NULL, + FALSE, + 0, + &StackReserve, + &StackCommit, + lpStartAddress, + (PVOID)PEB_BASE, + ThreadHandle, + ClientId + ); } static NTSTATUS @@ -335,7 +204,7 @@ static NTSTATUS KlInitPeb (HANDLE ProcessHandle, return(Status); } - DPRINT("Ppb->MaximumLength %x\n", Ppb->MaximumLength); + DPRINT("Ppb->MaximumLength %x\n", Ppb->AllocationSize); /* write process parameters block*/ RtlDeNormalizeProcessParams (Ppb); diff --git a/reactos/lib/ntdll/rtl/thread.c b/reactos/lib/ntdll/rtl/thread.c index 90a882bea13..0157bc680c7 100644 --- a/reactos/lib/ntdll/rtl/thread.c +++ b/reactos/lib/ntdll/rtl/thread.c @@ -7,6 +7,9 @@ * REVISION HISTORY: * 09/07/99: Created * 09/10/99: Cleanup and full stack support. + * 25/04/03: Near rewrite. Made code more readable, replaced + * INITIAL_TEB with USER_STACK, added support for + * fixed-size stacks */ /* INCLUDES *****************************************************************/ @@ -16,263 +19,477 @@ #include #include -#define NDEBUG +//#define NDEBUG #include /* FUNCTIONS ***************************************************************/ +NTSTATUS STDCALL RtlInitializeContextEx +( + HANDLE ProcessHandle, + PCONTEXT Context, + PTHREAD_START_ROUTINE StartAddress, + PUSER_STACK UserStack, + ULONG ParameterCount, + ULONG_PTR * Parameters +); -NTSTATUS STDCALL -RtlCreateUserThread(HANDLE ProcessHandle, - PSECURITY_DESCRIPTOR SecurityDescriptor, - BOOLEAN CreateSuspended, - LONG StackZeroBits, - PULONG StackReserve, - PULONG StackCommit, - PTHREAD_START_ROUTINE StartAddress, - PVOID Parameter, - PHANDLE ThreadHandle, - PCLIENT_ID ClientId) +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 +) { - HANDLE LocalThreadHandle; - CLIENT_ID LocalClientId; - OBJECT_ATTRIBUTES ObjectAttributes; - INITIAL_TEB InitialTeb; - CONTEXT ThreadContext; - ULONG OldPageProtection; - NTSTATUS Status; + 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; - /* initialize initial teb */ - if ((StackReserve != NULL) && (*StackReserve > 0x100000)) - InitialTeb.StackReserve = *StackReserve; - else - InitialTeb.StackReserve = 0x100000; /* 1MByte */ + 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); - /* FIXME: use correct commit size */ #if 0 - if ((StackCommit != NULL) && (*StackCommit > PAGE_SIZE)) - InitialTeb.StackCommit = *StackCommit; - else - InitialTeb.StackCommit = PAGE_SIZE; + /* 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 - InitialTeb.StackCommit = InitialTeb.StackReserve - PAGE_SIZE; - /* add size of guard page */ - InitialTeb.StackCommit += PAGE_SIZE; + usUserStack.FixedStackBase = NULL; + usUserStack.FixedStackLimit = NULL; + usUserStack.ExpandableStackBase = NULL; + usUserStack.ExpandableStackLimit = NULL; + usUserStack.ExpandableStackBottom = NULL; - /* Reserve stack */ - InitialTeb.StackAllocate = NULL; - Status = NtAllocateVirtualMemory(ProcessHandle, - &InitialTeb.StackAllocate, - 0, - &InitialTeb.StackReserve, - MEM_RESERVE, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - DPRINT("Error reserving stack space!\n"); - return(Status); - } + /* FIXME: this code assumes a stack growing downwards */ + /* fixed stack */ + if(*StackCommit == *StackReserve) + { + DPRINT("Fixed stack\n"); - DPRINT("StackAllocate: %p ReserveSize: 0x%lX\n", - InitialTeb.StackAllocate, InitialTeb.StackReserve); + usUserStack.FixedStackLimit = NULL; - InitialTeb.StackBase = (PVOID)((ULONG)InitialTeb.StackAllocate + InitialTeb.StackReserve); - InitialTeb.StackLimit = (PVOID)((ULONG)InitialTeb.StackBase - InitialTeb.StackCommit); + /* allocate the stack */ + nErrCode = NtAllocateVirtualMemory + ( + ProcessHandle, + &(usUserStack.FixedStackLimit), + StackZeroBits, + StackReserve, + MEM_RESERVE | MEM_COMMIT, + PAGE_READWRITE + ); - DPRINT("StackBase: %p StackCommit: 0x%lX\n", - InitialTeb.StackBase, InitialTeb.StackCommit); + /* failure */ + if(!NT_SUCCESS(nErrCode)) goto l_Fail; - /* Commit stack */ - Status = NtAllocateVirtualMemory(ProcessHandle, - &InitialTeb.StackLimit, - 0, - &InitialTeb.StackCommit, - MEM_COMMIT, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - /* release the stack space */ - NtFreeVirtualMemory(ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); + /* store the highest (first) address of the stack */ + usUserStack.FixedStackBase = + (PUCHAR)(usUserStack.FixedStackLimit) + *StackReserve; - DPRINT("Error comitting stack page!\n"); - return(Status); - } + *StackCommit = *StackReserve; - DPRINT("StackLimit: %p\nStackCommit: 0x%lX\n", - InitialTeb.StackLimit, - InitialTeb.StackCommit); + DPRINT("Stack base %p\n", usUserStack.FixedStackBase); + DPRINT("Stack limit %p\n", usUserStack.FixedStackLimit); + } + /* expandable stack */ + else + { + ULONG_PTR nGuardSize = PAGE_SIZE; + PVOID pGuardBase; - /* Protect guard page */ - Status = NtProtectVirtualMemory(ProcessHandle, - InitialTeb.StackLimit, - PAGE_SIZE, - PAGE_GUARD | PAGE_READWRITE, - &OldPageProtection); - if (!NT_SUCCESS(Status)) - { - /* release the stack space */ - NtFreeVirtualMemory(ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); + DPRINT("Expandable stack\n"); - DPRINT("Error protecting guard page!\n"); - return(Status); - } + usUserStack.FixedStackLimit = NULL; + usUserStack.FixedStackBase = NULL; + usUserStack.ExpandableStackBottom = NULL; - /* initialize thread context */ - RtlInitializeContext(ProcessHandle, - &ThreadContext, - Parameter, - StartAddress, - &InitialTeb); + /* reserve the stack */ + nErrCode = NtAllocateVirtualMemory + ( + ProcessHandle, + &(usUserStack.ExpandableStackBottom), + StackZeroBits, + StackReserve, + MEM_RESERVE, + PAGE_READWRITE + ); - /* create the thread */ - ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES); - ObjectAttributes.RootDirectory = NULL; - ObjectAttributes.ObjectName = NULL; - ObjectAttributes.Attributes = OBJ_INHERIT; - ObjectAttributes.SecurityDescriptor = SecurityDescriptor; - ObjectAttributes.SecurityQualityOfService = NULL; + /* failure */ + if(!NT_SUCCESS(nErrCode)) goto l_Fail; - Status = NtCreateThread(&LocalThreadHandle, - THREAD_ALL_ACCESS, - &ObjectAttributes, - ProcessHandle, - &LocalClientId, - &ThreadContext, - &InitialTeb, - CreateSuspended); - if (!NT_SUCCESS(Status)) - { - /* release the stack space */ - NtFreeVirtualMemory(ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, - MEM_RELEASE); + DPRINT("Reserved %08X bytes\n", *StackReserve); - DPRINT("Error creating thread!\n"); - return(Status); - } + /* expandable stack base - the highest address of the stack */ + usUserStack.ExpandableStackBase = + (PUCHAR)(usUserStack.ExpandableStackBottom) + *StackReserve; - /* return committed stack size */ - if (StackCommit) - *StackCommit = InitialTeb.StackCommit; + /* expandable stack limit - the lowest committed address of the stack */ + usUserStack.ExpandableStackLimit = + (PUCHAR)(usUserStack.ExpandableStackBase) - *StackCommit; - /* return reserved stack size */ - if (StackReserve) - *StackReserve = InitialTeb.StackReserve; + DPRINT("Stack base %p\n", usUserStack.ExpandableStackBase); + DPRINT("Stack limit %p\n", usUserStack.ExpandableStackLimit); + DPRINT("Stack bottom %p\n", usUserStack.ExpandableStackBottom); - /* return thread handle */ - if (ThreadHandle) - *ThreadHandle = LocalThreadHandle; + /* commit as much stack as requested */ + nErrCode = NtAllocateVirtualMemory + ( + ProcessHandle, + &(usUserStack.ExpandableStackLimit), + 0, + StackCommit, + MEM_COMMIT, + PAGE_READWRITE + ); - /* return client id */ - if (ClientId) - { - ClientId->UniqueProcess = LocalClientId.UniqueProcess; - ClientId->UniqueThread = LocalClientId.UniqueThread; - } + /* failure */ + if(!NT_SUCCESS(nErrCode)) goto l_Fail; - return(STATUS_SUCCESS); + 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 STDCALL -RtlInitializeContext(HANDLE ProcessHandle, - PCONTEXT Context, - PVOID Parameter, - PTHREAD_START_ROUTINE StartAddress, - PINITIAL_TEB InitialTeb) +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, + ... +) { - ULONG Buffer[2]; - ULONG BytesWritten; - NTSTATUS Status; + 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 + ); - memset (Context, 0, sizeof(CONTEXT)); - Context->Eip = (LONG)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)InitialTeb->StackBase - 8; - Context->EFlags = (1<<1) + (1<<9); - - /* prepare the thread stack for execution */ - if (ProcessHandle == NtCurrentProcess()) - { - *((PULONG)(InitialTeb->StackBase - 4)) = (ULONG)Parameter; - *((PULONG)(InitialTeb->StackBase - 8)) = 0xdeadbeef; - } - else - { - Buffer[0] = (ULONG)Parameter; - Buffer[1] = 0xdeadbeef; - - Status = NtWriteVirtualMemory(ProcessHandle, - (PVOID)((ULONG)InitialTeb->StackBase - 8), - Buffer, - 2 * sizeof(ULONG), - &BytesWritten); - return Status; - } - - return STATUS_SUCCESS; + va_end(vaArgs); + + return nErrCode; } - -NTSTATUS STDCALL -RtlFreeUserThreadStack(HANDLE ProcessHandle, - HANDLE ThreadHandle) +NTSTATUS STDCALL RtlCreateUserThread +( + HANDLE ProcessHandle, + PSECURITY_DESCRIPTOR SecurityDescriptor, + BOOLEAN CreateSuspended, + LONG StackZeroBits, + PULONG StackReserve, + PULONG StackCommit, + PTHREAD_START_ROUTINE StartAddress, + PVOID Parameter, + PHANDLE ThreadHandle, + PCLIENT_ID ClientId +) { - THREAD_BASIC_INFORMATION ThreadInfo; - NTSTATUS Status; - ULONG BytesRead; - ULONG RegionSize; - PVOID StackBase; - PTEB Teb; - - Status = NtQueryInformationThread(ThreadHandle, - ThreadBasicInformation, - &ThreadInfo, - sizeof(THREAD_BASIC_INFORMATION), - NULL); - if (!NT_SUCCESS(Status)) - return(Status); - - if (ThreadInfo.TebBaseAddress == NULL) - return(Status); - - Teb = (PTEB)ThreadInfo.TebBaseAddress; - Status = NtReadVirtualMemory(ProcessHandle, - &Teb->DeallocationStack, - &StackBase, - sizeof(PVOID), - &BytesRead); - if (!NT_SUCCESS(Status)) - return(Status); - - if (StackBase == NULL) - return(Status); - - RegionSize = 0; - Status = NtFreeVirtualMemory(ProcessHandle, - StackBase, - &RegionSize, - MEM_RELEASE); - return(Status); + OBJECT_ATTRIBUTES oaThreadAttribs; + + InitializeObjectAttributes + ( + &oaThreadAttribs, + NULL, + 0, + NULL, + SecurityDescriptor + ); + + return RtlCreateUserThreadEx + ( + ProcessHandle, + &oaThreadAttribs, + CreateSuspended, + StackZeroBits, + StackReserve, + StackCommit, + StartAddress, + ThreadHandle, + ClientId, + 1, + (ULONG_PTR *)&Parameter + ); } -NTSTATUS STDCALL RtlExitUserThread(NTSTATUS Status) +NTSTATUS STDCALL RtlInitializeContextEx +( + HANDLE ProcessHandle, + PCONTEXT Context, + PTHREAD_START_ROUTINE StartAddress, + PUSER_STACK UserStack, + ULONG ParameterCount, + ULONG_PTR * Parameters +) { - return NtTerminateThread(NtCurrentThread(), Status); + 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->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, + PCONTEXT Context, + PVOID Parameter, + PTHREAD_START_ROUTINE StartAddress, + PUSER_STACK UserStack +) +{ + return RtlInitializeContextEx + ( + ProcessHandle, + Context, + StartAddress, + UserStack, + 1, + (ULONG_PTR *)&Parameter + ); +} + +NTSTATUS STDCALL RtlFreeUserThreadStack +( + HANDLE ProcessHandle, + HANDLE ThreadHandle +) +{ + THREAD_BASIC_INFORMATION tbiInfo; + NTSTATUS nErrCode; + ULONG nDummy; + ULONG nSize = 0; + PVOID pStackBase; + PTEB pTeb; + + /* query basic information about the thread */ + nErrCode = NtQueryInformationThread + ( + ThreadHandle, + ThreadBasicInformation, + &tbiInfo, + sizeof(tbiInfo), + NULL + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) return nErrCode; + if(tbiInfo.TebBaseAddress == NULL) return STATUS_ACCESS_VIOLATION; + + pTeb = (PTEB)tbiInfo.TebBaseAddress; + + /* read the base address of the stack to be deallocated */ + nErrCode = NtReadVirtualMemory + ( + ProcessHandle, + &pTeb->DeallocationStack, + &pStackBase, + sizeof(pStackBase), + &nDummy + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) return nErrCode; + if(pStackBase == NULL) return STATUS_ACCESS_VIOLATION; + + /* deallocate the stack */ + nErrCode = NtFreeVirtualMemory(ProcessHandle, pStackBase, &nSize, MEM_RELEASE); + + return nErrCode; +} + +NTSTATUS STDCALL RtlExitUserThread(NTSTATUS nErrCode) +{ + return NtTerminateThread(NtCurrentThread(), nErrCode); } /* EOF */ diff --git a/reactos/ntoskrnl/ex/fmutex.c b/reactos/ntoskrnl/ex/fmutex.c index c24cd393dd8..0e511e6bb16 100644 --- a/reactos/ntoskrnl/ex/fmutex.c +++ b/reactos/ntoskrnl/ex/fmutex.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: fmutex.c,v 1.17 2002/09/08 10:23:19 chorns Exp $ +/* $Id: fmutex.c,v 1.18 2003/04/26 23:13:29 hyperion Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/ex/fmutex.c @@ -39,7 +39,7 @@ VOID FASTCALL ExAcquireFastMutexUnsafe(PFAST_MUTEX FastMutex) { assert(FastMutex->Owner != KeGetCurrentThread()); - InterlockedIncrement(&FastMutex->Contention); + InterlockedIncrement((LONG *)&FastMutex->Contention); while (InterlockedExchange(&FastMutex->Count, 0) == 0) { KeWaitForSingleObject(&FastMutex->Event, @@ -48,7 +48,7 @@ ExAcquireFastMutexUnsafe(PFAST_MUTEX FastMutex) FALSE, NULL); } - InterlockedDecrement(&FastMutex->Contention); + InterlockedDecrement((LONG *)&FastMutex->Contention); FastMutex->Owner = KeGetCurrentThread(); } diff --git a/reactos/ntoskrnl/io/arcname.c b/reactos/ntoskrnl/io/arcname.c index 2295175154f..96c0dd9f9f6 100644 --- a/reactos/ntoskrnl/io/arcname.c +++ b/reactos/ntoskrnl/io/arcname.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: arcname.c,v 1.10 2002/11/14 18:21:07 chorns Exp $ +/* $Id: arcname.c,v 1.11 2003/04/26 23:13:30 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -296,7 +296,7 @@ IoCreateSystemRootLink(PCHAR ParameterLine) return(Status); } - sprintf(p, "cdrom(%u)", DeviceNumber); + sprintf(p, "cdrom(%lu)", DeviceNumber); DPRINT("New ARC name: %s\n", ParamBuffer); @@ -313,7 +313,7 @@ IoCreateSystemRootLink(PCHAR ParameterLine) q++; strcpy(temp, q); - sprintf(p, "cdrom(%u)", DeviceNumber); + sprintf(p, "cdrom(%lu)", DeviceNumber); strcat(p, temp); } } diff --git a/reactos/ntoskrnl/kd/gdbstub.c b/reactos/ntoskrnl/kd/gdbstub.c index ef8294aabd1..2c8e461ca72 100644 --- a/reactos/ntoskrnl/kd/gdbstub.c +++ b/reactos/ntoskrnl/kd/gdbstub.c @@ -1204,10 +1204,10 @@ GspSetSingleRegisterInTrapFrame (ptr, Register, Context, TrapFrame); case 'Y': { - ULONG Number; - ULONG Length; - ULONG Type; - ULONG Address; + LONG Number; + LONG Length; + LONG Type; + LONG Address; ptr = &GspOutBuffer[1]; GspHex2Long (&ptr, &Number); @@ -1231,7 +1231,7 @@ GspSetSingleRegisterInTrapFrame (ptr, Register, Context, TrapFrame); /* Remove hardware breakpoint */ case 'y': { - ULONG Number; + LONG Number; ptr = &GspOutBuffer[1]; GspHex2Long(&ptr, &Number); diff --git a/reactos/ntoskrnl/ke/i386/kernel.c b/reactos/ntoskrnl/ke/i386/kernel.c index 2d049ee6164..2ca1f3fef33 100644 --- a/reactos/ntoskrnl/ke/i386/kernel.c +++ b/reactos/ntoskrnl/ke/i386/kernel.c @@ -60,7 +60,7 @@ KeApplicationProcessorInit(VOID) /* * Create a PCR for this processor */ - Offset = InterlockedIncrement(&PcrsAllocated) - 1; + Offset = InterlockedIncrement((LONG *)&PcrsAllocated) - 1; KPCR = (PKPCR)(KPCR_BASE + (Offset * PAGE_SIZE)); MmCreateVirtualMappingForKernel((PVOID)KPCR, PAGE_READWRITE, diff --git a/reactos/ntoskrnl/ke/main.c b/reactos/ntoskrnl/ke/main.c index 7439d1845f7..91c4c4ba06d 100644 --- a/reactos/ntoskrnl/ke/main.c +++ b/reactos/ntoskrnl/ke/main.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: main.c,v 1.151 2003/04/17 11:07:47 ekohl Exp $ +/* $Id: main.c,v 1.152 2003/04/26 23:13:30 hyperion Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/main.c @@ -401,14 +401,14 @@ ExpInitializeExecutive(VOID) if (KeNumberProcessors > 1) { sprintf(str, - "Found %d system processors. [%u MB Memory]\n", + "Found %d system processors. [%lu MB Memory]\n", KeNumberProcessors, (KeLoaderBlock.MemHigher + 1088)/ 1024); } else { sprintf(str, - "Found 1 system processor. [%u MB Memory]\n", + "Found 1 system processor. [%lu MB Memory]\n", (KeLoaderBlock.MemHigher + 1088)/ 1024); } HalDisplayString(str); @@ -627,7 +627,6 @@ ExpInitializeExecutive(VOID) { KeBugCheckEx(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0); } - /* * Crash the system if the initial process terminates within 5 seconds. */ @@ -735,7 +734,7 @@ _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock) } } sprintf(KeLoaderCommandLine, - "multi(0)disk(0)rdisk(%d)partition(%d)%s %s", + "multi(0)disk(0)rdisk(%lu)partition(%lu)%s %s", DiskNumber, PartNumber + 1, Temp, options); p = KeLoaderCommandLine; diff --git a/reactos/ntoskrnl/ke/spinlock.c b/reactos/ntoskrnl/ke/spinlock.c index 9756f19127a..a648b085c3b 100644 --- a/reactos/ntoskrnl/ke/spinlock.c +++ b/reactos/ntoskrnl/ke/spinlock.c @@ -1,4 +1,4 @@ -/* $Id: spinlock.c,v 1.13 2002/09/08 10:23:29 chorns Exp $ +/* $Id: spinlock.c,v 1.14 2003/04/26 23:13:31 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -84,7 +84,7 @@ KeAcquireSpinLockAtDpcLevel (PKSPIN_LOCK SpinLock) KeBugCheck(0); } - while ((i = InterlockedExchange(&SpinLock->Lock, 1)) == 1) + while ((i = InterlockedExchange((LONG *)&SpinLock->Lock, 1)) == 1) { #ifndef MP DbgPrint("Spinning on spinlock %x current value %x\n", SpinLock, i); @@ -109,7 +109,7 @@ KeReleaseSpinLockFromDpcLevel (PKSPIN_LOCK SpinLock) DbgPrint("Releasing unacquired spinlock %x\n", SpinLock); KeBugCheck(0); } - (void)InterlockedExchange(&SpinLock->Lock, 0); + (void)InterlockedExchange((LONG *)&SpinLock->Lock, 0); } /* EOF */ diff --git a/reactos/ntoskrnl/ldr/init.c b/reactos/ntoskrnl/ldr/init.c index 9dba6d3dc22..ccbf045bac2 100644 --- a/reactos/ntoskrnl/ldr/init.c +++ b/reactos/ntoskrnl/ldr/init.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: init.c,v 1.38 2002/11/15 22:04:51 ekohl Exp $ +/* $Id: init.c,v 1.39 2003/04/26 23:13:31 hyperion Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/ldr/init.c @@ -224,79 +224,156 @@ LdrpCreateProcessEnvironment(HANDLE ProcessHandle, return(STATUS_SUCCESS); } - -static NTSTATUS -LdrpCreateStack(HANDLE ProcessHandle, - PINITIAL_TEB InitialTeb) +/* + FIXME: this sucks. Sucks sucks sucks. This code was duplicated, if you can + believe it, in four different places - excluding this, and twice in the two + DLLs that contained it (kernel32.dll and ntdll.dll). As much as I'd like to + rip the whole RTL out of ntdll.dll and ntoskrnl.exe and into its own static + library, ntoskrnl.exe is built separatedly from the rest of ReactOS, coming + with its own linker scripts and specifications, and, save for changes and fixes + to make it at least compile, I'm not going to touch any of it. If you feel + brave enough, you're welcome [KJK::Hyperion] +*/ +static NTSTATUS LdrpCreateStack +( + HANDLE ProcessHandle, + PUSER_STACK UserStack, + PULONG_PTR StackReserve, + PULONG_PTR StackCommit +) { - ULONG OldPageProtection; - NTSTATUS Status; + PVOID pStackLowest = NULL; + ULONG_PTR nSize = 0; + NTSTATUS nErrCode; - InitialTeb->StackAllocate = NULL; + if(StackReserve == NULL || StackCommit == NULL) + return STATUS_INVALID_PARAMETER; - /* Allocate the reserved stack space */ - Status = NtAllocateVirtualMemory(ProcessHandle, - &InitialTeb->StackAllocate, - 0, - &InitialTeb->StackReserve, - MEM_RESERVE, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - DPRINT("Stack allocation failed (Status %x)", Status); - return(Status); - } + /* FIXME: no SEH, no guard pages */ + *StackCommit = *StackReserve; - DPRINT("StackAllocate: %p ReserveSize: 0x%lX\n", - InitialTeb->StackAllocate, InitialTeb->StackReserve); + UserStack->FixedStackBase = NULL; + UserStack->FixedStackLimit = NULL; + UserStack->ExpandableStackBase = NULL; + UserStack->ExpandableStackLimit = NULL; + UserStack->ExpandableStackBottom = NULL; - InitialTeb->StackBase = (PVOID)((ULONG)InitialTeb->StackAllocate + InitialTeb->StackReserve); - InitialTeb->StackLimit = (PVOID)((ULONG)InitialTeb->StackBase - InitialTeb->StackCommit); + /* FIXME: this code assumes a stack growing downwards */ + /* fixed stack */ + if(*StackCommit == *StackReserve) + { + DPRINT("Fixed stack\n"); - DPRINT("StackBase: %p StackCommit: 0x%lX\n", - InitialTeb->StackBase, InitialTeb->StackCommit); + UserStack->FixedStackLimit = NULL; - /* Commit stack */ - Status = NtAllocateVirtualMemory(ProcessHandle, - &InitialTeb->StackLimit, - 0, - &InitialTeb->StackCommit, - MEM_COMMIT, - PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - DPRINT("Error comitting stack page!\n"); - /* release the stack space */ - NtFreeVirtualMemory(ProcessHandle, - InitialTeb->StackAllocate, - &InitialTeb->StackReserve, - MEM_RELEASE); - return(Status); - } + /* allocate the stack */ + nErrCode = NtAllocateVirtualMemory + ( + ProcessHandle, + &(UserStack->FixedStackLimit), + 0, + StackReserve, + MEM_RESERVE | MEM_COMMIT, + PAGE_READWRITE + ); - DPRINT("StackLimit: %p\nStackCommit: 0x%lX\n", - InitialTeb->StackLimit, - InitialTeb->StackCommit); + /* failure */ + if(!NT_SUCCESS(nErrCode)) return nErrCode; - /* Protect guard page */ - Status = NtProtectVirtualMemory(ProcessHandle, - InitialTeb->StackLimit, - PAGE_SIZE, - PAGE_GUARD | PAGE_READWRITE, - &OldPageProtection); - if (!NT_SUCCESS(Status)) - { - DPRINT("Error protecting guard page!\n"); + /* store the highest (first) address of the stack */ + UserStack->FixedStackBase = + (PUCHAR)(UserStack->FixedStackLimit) + *StackReserve; + } + /* expandable stack */ + else + { + ULONG_PTR nGuardSize = PAGE_SIZE; + PVOID pGuardBase; - /* release the stack space */ - NtFreeVirtualMemory(ProcessHandle, - InitialTeb->StackAllocate, - &InitialTeb->StackReserve, - MEM_RELEASE); - return(Status); - } + DPRINT("Expandable stack\n"); - return(STATUS_SUCCESS); + UserStack->FixedStackLimit = NULL; + UserStack->FixedStackBase = NULL; + UserStack->ExpandableStackBottom = NULL; + + /* reserve the stack */ + nErrCode = NtAllocateVirtualMemory + ( + ProcessHandle, + &(UserStack->ExpandableStackBottom), + 0, + StackReserve, + MEM_RESERVE, + PAGE_READWRITE + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) return nErrCode; + + DPRINT("Reserved %08X bytes\n", *StackReserve); + + /* expandable stack base - the highest address of the stack */ + UserStack->ExpandableStackBase = + (PUCHAR)(UserStack->ExpandableStackBottom) + *StackReserve; + + /* expandable stack limit - the lowest committed address of the stack */ + UserStack->ExpandableStackLimit = + (PUCHAR)(UserStack->ExpandableStackBase) - *StackCommit; + + DPRINT("Stack base %p\n", UserStack->ExpandableStackBase); + DPRINT("Stack limit %p\n", UserStack->ExpandableStackLimit); + + /* commit as much stack as requested */ + nErrCode = NtAllocateVirtualMemory + ( + ProcessHandle, + &(UserStack->ExpandableStackLimit), + 0, + StackCommit, + MEM_COMMIT, + PAGE_READWRITE + ); + + /* failure */ + if(!NT_SUCCESS(nErrCode)) goto l_Cleanup; + + DPRINT("Stack limit %p\n", UserStack->ExpandableStackLimit); + + pGuardBase = (PUCHAR)(UserStack->ExpandableStackLimit) - PAGE_SIZE; + + DPRINT("Guard base %p\n", UserStack->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_Cleanup; + + DPRINT("Guard base %p\n", UserStack->ExpandableStackBase); + } + + return STATUS_SUCCESS; + + /* cleanup in case of failure */ +l_Cleanup: + if(UserStack->FixedStackLimit) + pStackLowest = UserStack->FixedStackLimit; + else if(UserStack->ExpandableStackBottom) + pStackLowest = UserStack->ExpandableStackBottom; + + /* free the stack, if it was allocated */ + if(pStackLowest != NULL) + NtFreeVirtualMemory(ProcessHandle, &pStackLowest, &nSize, MEM_RELEASE); + + return nErrCode; } @@ -308,7 +385,11 @@ LdrLoadInitialProcess(PHANDLE ProcessHandle, UNICODE_STRING ImagePath; HANDLE SectionHandle; CONTEXT Context; - INITIAL_TEB InitialTeb; + USER_STACK UserStack; + ULONG_PTR nStackReserve = 0; + ULONG_PTR nStackCommit = 0; + PVOID pStackLowest; + PVOID pStackBase; ULONG ResultLength; PVOID ImageBaseAddress; ULONG InitialStack[5]; @@ -373,28 +454,32 @@ LdrLoadInitialProcess(PHANDLE ProcessHandle, /* Calculate initial stack sizes */ if (Sii.StackReserve > 0x100000) - InitialTeb.StackReserve = Sii.StackReserve; + nStackReserve = Sii.StackReserve; else - InitialTeb.StackReserve = 0x100000; /* 1MByte */ + nStackReserve = 0x100000; /* 1MByte */ /* FIXME */ #if 0 if (Sii.StackCommit > PAGE_SIZE) - InitialTeb.StackCommit = Sii.StackCommit; + nStackCommit = Sii.StackCommit; else - InitialTeb.StackCommit = PAGE_SIZE; + nStackCommit = PAGE_SIZE; #endif - InitialTeb.StackCommit = InitialTeb.StackReserve - PAGE_SIZE; + nStackCommit = nStackReserve - PAGE_SIZE; - /* add guard page size */ - InitialTeb.StackCommit += PAGE_SIZE; DPRINT("StackReserve 0x%lX StackCommit 0x%lX\n", - InitialTeb.StackReserve, InitialTeb.StackCommit); + nStackReserve, nStackCommit); /* Create the process stack */ - Status = LdrpCreateStack(*ProcessHandle, - &InitialTeb); + Status = LdrpCreateStack + ( + *ProcessHandle, + &UserStack, + &nStackReserve, + &nStackCommit + ); + if (!NT_SUCCESS(Status)) { DPRINT("Failed to write initial stack.\n"); @@ -402,12 +487,27 @@ LdrLoadInitialProcess(PHANDLE ProcessHandle, return(Status); } + if(UserStack.FixedStackBase && UserStack.FixedStackLimit) + { + pStackBase = UserStack.FixedStackBase; + pStackLowest = UserStack.FixedStackLimit; + } + else + { + pStackBase = UserStack.ExpandableStackBase; + pStackLowest = UserStack.ExpandableStackBottom; + } + + DPRINT("pStackBase = %p\n", pStackBase); + DPRINT("pStackLowest = %p\n", pStackLowest); /* * Initialize context to point to LdrStartup */ +#if defined(_M_IX86) memset(&Context,0,sizeof(CONTEXT)); - Context.Eip = (ULONG)(ImageBaseAddress + (ULONG)Sii.EntryPoint); + Context.ContextFlags = CONTEXT_FULL; + Context.Eip = (ULONG_PTR)(ImageBaseAddress + (ULONG_PTR)Sii.EntryPoint); Context.SegCs = USER_CS; Context.SegDs = USER_DS; Context.SegEs = USER_DS; @@ -415,7 +515,10 @@ LdrLoadInitialProcess(PHANDLE ProcessHandle, Context.SegGs = USER_DS; Context.SegSs = USER_DS; Context.EFlags = 0x202; - Context.Esp = (ULONG)InitialTeb.StackBase - 20; + Context.Esp = (ULONG_PTR)pStackBase - 20; +#else +#error Unsupported architecture +#endif /* * Write in the initial stack. @@ -429,11 +532,13 @@ LdrLoadInitialProcess(PHANDLE ProcessHandle, &ResultLength); if (!NT_SUCCESS(Status)) { + ULONG_PTR nSize = 0; + DPRINT("Failed to write initial stack.\n"); NtFreeVirtualMemory(*ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, + pStackLowest, + &nSize, MEM_RELEASE); NtClose(*ProcessHandle); return(Status); @@ -447,15 +552,17 @@ LdrLoadInitialProcess(PHANDLE ProcessHandle, *ProcessHandle, NULL, &Context, - &InitialTeb, + &UserStack, FALSE); if (!NT_SUCCESS(Status)) { + ULONG_PTR nSize = 0; + DPRINT("NtCreateThread() failed (Status %lx)\n", Status); NtFreeVirtualMemory(*ProcessHandle, - InitialTeb.StackAllocate, - &InitialTeb.StackReserve, + pStackLowest, + &nSize, MEM_RELEASE); NtClose(*ProcessHandle); diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index 8a96f36f27b..3c4c29c41b4 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -1,4 +1,4 @@ -/* $Id: loader.c,v 1.129 2003/04/03 00:06:24 hyperion Exp $ +/* $Id: loader.c,v 1.130 2003/04/26 23:13:31 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -1394,7 +1394,7 @@ LdrSafePEProcessModule(PVOID ModuleLoadBase, { ULONG Offset; ULONG Type; - PDWORD RelocItem; + PULONG RelocItem; Offset = RelocEntry[Idx].TypeOffset & 0xfff; Type = (RelocEntry[Idx].TypeOffset >> 12) & 0xf; diff --git a/reactos/ntoskrnl/lpc/reply.c b/reactos/ntoskrnl/lpc/reply.c index f06ef3eb43f..e7a1698e84b 100644 --- a/reactos/ntoskrnl/lpc/reply.c +++ b/reactos/ntoskrnl/lpc/reply.c @@ -1,4 +1,4 @@ -/* $Id: reply.c,v 1.12 2002/11/03 20:01:06 chorns Exp $ +/* $Id: reply.c,v 1.13 2003/04/26 23:13:32 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -65,7 +65,7 @@ EiReplyOrRequestPort (IN PEPORT Port, MessageReply->Message.Cid.UniqueProcess = PsGetCurrentProcessId(); MessageReply->Message.Cid.UniqueThread = PsGetCurrentThreadId(); MessageReply->Message.MessageType = MessageType; - MessageReply->Message.MessageId = InterlockedIncrement(&EiNextLpcMessageId); + MessageReply->Message.MessageId = InterlockedIncrement((LONG *)&EiNextLpcMessageId); KeAcquireSpinLock(&Port->Lock, &oldIrql); EiEnqueueMessagePort(Port, MessageReply); diff --git a/reactos/ntoskrnl/mm/anonmem.c b/reactos/ntoskrnl/mm/anonmem.c index 2bbcc404259..47806195202 100644 --- a/reactos/ntoskrnl/mm/anonmem.c +++ b/reactos/ntoskrnl/mm/anonmem.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: anonmem.c,v 1.10 2003/01/11 15:45:55 hbirr Exp $ +/* $Id: anonmem.c,v 1.11 2003/04/26 23:13:32 hyperion Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/mm/anonmem.c @@ -201,7 +201,7 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace, * Write the page to the pagefile */ Mdl = MmCreateMdl(NULL, NULL, PAGE_SIZE); - MmBuildMdlFromPages(Mdl, &PhysicalAddress.u.LowPart); + MmBuildMdlFromPages(Mdl, (ULONG *)&PhysicalAddress.u.LowPart); Status = MmWriteToSwapPage(SwapEntry, Mdl); if (!NT_SUCCESS(Status)) { diff --git a/reactos/ntoskrnl/mm/balance.c b/reactos/ntoskrnl/mm/balance.c index 14378d9007d..de6aea5d5ef 100644 --- a/reactos/ntoskrnl/mm/balance.c +++ b/reactos/ntoskrnl/mm/balance.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: balance.c,v 1.14 2002/11/10 18:17:42 chorns Exp $ +/* $Id: balance.c,v 1.15 2003/04/26 23:13:32 hyperion Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/mm/balance.c @@ -117,9 +117,9 @@ MmReleasePageMemoryConsumer(ULONG Consumer, PHYSICAL_ADDRESS Page) KeAcquireSpinLock(&AllocationListLock, &oldIrql); if (MmGetReferenceCountPage(Page) == 1) { - InterlockedDecrement(&MiMemoryConsumers[Consumer].PagesUsed); - InterlockedIncrement(&MiNrAvailablePages); - InterlockedDecrement(&MiPagesRequired); + InterlockedDecrement((LONG *)&MiMemoryConsumers[Consumer].PagesUsed); + InterlockedIncrement((LONG *)&MiNrAvailablePages); + InterlockedDecrement((LONG *)&MiPagesRequired); if (IsListEmpty(&AllocationListHead)) { KeReleaseSpinLock(&AllocationListLock, oldIrql); @@ -203,13 +203,13 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, /* * Make sure we don't exceed our individual target. */ - OldUsed = InterlockedIncrement(&MiMemoryConsumers[Consumer].PagesUsed); + OldUsed = InterlockedIncrement((LONG *)&MiMemoryConsumers[Consumer].PagesUsed); if (OldUsed >= (MiMemoryConsumers[Consumer].PagesTarget - 1) && WorkerThreadId != PsGetCurrentThreadId()) { if (!CanWait) { - InterlockedDecrement(&MiMemoryConsumers[Consumer].PagesUsed); + InterlockedDecrement((LONG *)&MiMemoryConsumers[Consumer].PagesUsed); return(STATUS_NO_MEMORY); } MiTrimMemoryConsumer(Consumer); @@ -218,22 +218,22 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, /* * Make sure we don't exceed global targets. */ - OldAvailable = InterlockedDecrement(&MiNrAvailablePages); + OldAvailable = InterlockedDecrement((LONG *)&MiNrAvailablePages); if (OldAvailable < MiMinimumAvailablePages) { MM_ALLOCATION_REQUEST Request; if (!CanWait) { - InterlockedIncrement(&MiNrAvailablePages); - InterlockedDecrement(&MiMemoryConsumers[Consumer].PagesUsed); + InterlockedIncrement((LONG *)&MiNrAvailablePages); + InterlockedDecrement((LONG *)&MiMemoryConsumers[Consumer].PagesUsed); return(STATUS_NO_MEMORY); } /* Insert an allocation request. */ Request.Page.QuadPart = 0LL; KeInitializeEvent(&Request.Event, NotificationEvent, FALSE); - InterlockedIncrement(&MiPagesRequired); + InterlockedIncrement((LONG *)&MiPagesRequired); KeAcquireSpinLock(&AllocationListLock, &oldIrql); if (NrWorkingThreads == 0) diff --git a/reactos/ntoskrnl/mm/pageop.c b/reactos/ntoskrnl/mm/pageop.c index 88ee1ffc9a6..4c7e2304add 100644 --- a/reactos/ntoskrnl/mm/pageop.c +++ b/reactos/ntoskrnl/mm/pageop.c @@ -1,4 +1,4 @@ -/* $Id: pageop.c,v 1.15 2003/01/11 15:26:59 hbirr Exp $ +/* $Id: pageop.c,v 1.16 2003/04/26 23:13:32 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -46,7 +46,7 @@ MmReleasePageOp(PMM_PAGEOP PageOp) KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); return; } - InterlockedDecrement(&PageOp->MArea->PageOpCount); + InterlockedDecrement((LONG *)&PageOp->MArea->PageOpCount); PrevPageOp = MmPageOpHashTable[PageOp->Hash]; if (PrevPageOp == PageOp) { @@ -226,7 +226,7 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address, PageOp->MArea = MArea; KeInitializeEvent(&PageOp->CompletionEvent, NotificationEvent, FALSE); MmPageOpHashTable[Hash] = PageOp; - InterlockedIncrement(&MArea->PageOpCount); + InterlockedIncrement((LONG *)&MArea->PageOpCount); KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); return(PageOp); diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index 9eb39cb06da..d8eba00010a 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: section.c,v 1.107 2003/04/06 12:48:33 gvg Exp $ +/* $Id: section.c,v 1.108 2003/04/26 23:13:32 hyperion Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/mm/section.c @@ -1838,12 +1838,12 @@ MmpDeleteSection(PVOID ObjectBody) for (i = 0; i < Section->NrSegments; i++) { - InterlockedDecrement(&Section->Segments[i].ReferenceCount); + InterlockedDecrement((LONG *)&Section->Segments[i].ReferenceCount); } } else { - InterlockedDecrement(&Section->Segments->ReferenceCount); + InterlockedDecrement((LONG *)&Section->Segments->ReferenceCount); } if (Section->FileObject != NULL) { @@ -2684,7 +2684,7 @@ MmCreateImageSection(PHANDLE SectionHandle, */ for (i = 0; i < NrSegments; i++) { - InterlockedIncrement(&SectionSegments[i].ReferenceCount); + InterlockedIncrement((LONG *)&SectionSegments[i].ReferenceCount); } } diff --git a/reactos/ntoskrnl/ps/create.c b/reactos/ntoskrnl/ps/create.c index 03ef0693f6a..998fd450c8a 100644 --- a/reactos/ntoskrnl/ps/create.c +++ b/reactos/ntoskrnl/ps/create.c @@ -1,4 +1,4 @@ -/* $Id: create.c,v 1.56 2002/10/26 00:32:19 chorns Exp $ +/* $Id: create.c,v 1.57 2003/04/26 23:13:33 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -269,7 +269,6 @@ PsReferenceImpersonationToken(PETHREAD Thread, VOID PiBeforeBeginThread(CONTEXT c) { - DPRINT("PiBeforeBeginThread(Eip %x)\n", c.Eip); KeLowerIrql(PASSIVE_LEVEL); } @@ -370,7 +369,7 @@ PsInitializeThread(HANDLE ProcessHandle, KeInitializeSpinLock(&Thread->ActiveTimerListLock); InitializeListHead(&Thread->IrpList); Thread->Cid.UniqueThread = (HANDLE)InterlockedIncrement( - &PiNextThreadUniqueId); + (LONG *)&PiNextThreadUniqueId); Thread->Cid.UniqueProcess = (HANDLE)Thread->ThreadsProcess->UniqueProcessId; Thread->DeadThread = 0; Thread->Win32Thread = 0; @@ -400,7 +399,7 @@ static NTSTATUS PsCreateTeb(HANDLE ProcessHandle, PTEB *TebPtr, PETHREAD Thread, - PINITIAL_TEB InitialTeb) + PUSER_STACK UserStack) { MEMORY_BASIC_INFORMATION Info; NTSTATUS Status; @@ -456,13 +455,24 @@ PsCreateTeb(HANDLE ProcessHandle, } DPRINT("Teb.Peb %x\n", Teb.Peb); - /* store stack information from InitialTeb */ - if (InitialTeb != NULL) - { - Teb.Tib.StackBase = InitialTeb->StackBase; - Teb.Tib.StackLimit = InitialTeb->StackLimit; - Teb.DeallocationStack = InitialTeb->StackAllocate; - } + /* store stack information from UserStack */ + if(UserStack != NULL) + { + /* fixed-size stack */ + if(UserStack->FixedStackBase && UserStack->FixedStackLimit) + { + Teb.Tib.StackBase = UserStack->FixedStackBase; + Teb.Tib.StackLimit = UserStack->FixedStackLimit; + Teb.DeallocationStack = UserStack->FixedStackLimit; + } + /* expandable stack */ + else + { + Teb.Tib.StackBase = UserStack->ExpandableStackBase; + Teb.Tib.StackLimit = UserStack->ExpandableStackLimit; + Teb.DeallocationStack = UserStack->ExpandableStackBottom; + } + } /* more initialization */ Teb.Cid.UniqueThread = Thread->Cid.UniqueThread; @@ -528,7 +538,7 @@ NtCreateThread(PHANDLE ThreadHandle, HANDLE ProcessHandle, PCLIENT_ID Client, PCONTEXT ThreadContext, - PINITIAL_TEB InitialTeb, + PUSER_STACK UserStack, BOOLEAN CreateSuspended) { PETHREAD Thread; @@ -559,7 +569,7 @@ NtCreateThread(PHANDLE ThreadHandle, Status = PsCreateTeb(ProcessHandle, &TebBase, Thread, - InitialTeb); + UserStack); if (!NT_SUCCESS(Status)) { return(Status); diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index 2ec5ee1d4db..a7398f9a4e1 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.96 2003/04/10 23:14:47 hyperion Exp $ +/* $Id: process.c,v 1.97 2003/04/26 23:13:33 hyperion Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -257,7 +257,7 @@ PsInitProcessManagment(VOID) KProcess->DirectoryTableBase = (LARGE_INTEGER)(LONGLONG)(ULONG)MmGetPageDirectory(); PsInitialSystemProcess->UniqueProcessId = - InterlockedIncrement(&PiNextProcessUniqueId); + InterlockedIncrement((LONG *)&PiNextProcessUniqueId); PsInitialSystemProcess->Win32WindowStation = (HANDLE)0; PsInitialSystemProcess->Win32Desktop = (HANDLE)0; @@ -477,7 +477,7 @@ NtCreateProcess(OUT PHANDLE ProcessHandle, KProcess->BasePriority = PROCESS_PRIO_NORMAL; MmInitializeAddressSpace(Process, &Process->AddressSpace); - Process->UniqueProcessId = InterlockedIncrement(&PiNextProcessUniqueId); + Process->UniqueProcessId = InterlockedIncrement((LONG *)&PiNextProcessUniqueId); Process->InheritedFromUniqueProcessId = (HANDLE)ParentProcess->UniqueProcessId; ObCreateHandleTable(ParentProcess,