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
This commit is contained in:
KJK::Hyperion 2003-04-26 23:13:33 +00:00
parent f2c91805a0
commit 879b1f5754
35 changed files with 1331 additions and 1055 deletions

View file

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

View file

@ -801,6 +801,9 @@ InterlockedIncrement (
PLONG Addend
);
#define InterlockedExchangePointer(__T__, __V__) \
(PVOID)InterlockedExchange((PLONG)(__T__), (LONG)(__V__))
/*---*/
typedef

View file

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

View file

@ -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) \
{ \

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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);
}

View file

@ -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 <kernel32/kernel32.h>
//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)
{

View file

@ -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 <ddk/ntddk.h>
#include <debug.h>
/* 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 */

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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 <napi/teb.h>
#include <ntdll/rtl.h>
#define NDEBUG
//#define NDEBUG
#include <ntdll/ntdll.h>
/* FUNCTIONS ***************************************************************/
NTSTATUS STDCALL RtlInitializeContextEx
(
HANDLE ProcessHandle,
PCONTEXT Context,
PTHREAD_START_ROUTINE StartAddress,
PUSER_STACK UserStack,
ULONG ParameterCount,
ULONG_PTR * Parameters
);
NTSTATUS STDCALL
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 */

View file

@ -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();
}

View file

@ -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);
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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);
}
}

View file

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

View file

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