+2002-08-08 David Welch <welch@computer2.darkstar.org>
+
+ * ntoskrnl/mm/section (NtQuerySection): Return the
+ right result length.
+
+2002-08-08 David Welch <welch@computer2.darkstar.org>
+
+ * ntoskrnl/ke/usertrap.c (print_user_address): Check for
+ a NULL LDR structure in the PEB; copy the LDR pointer in
+ safely.
+
+2002-08-08 David Welch <welch@computer2.darkstar.org>
+
+ * ntoskrnl/ke/apc.c (KiDeliverUserApc): Deliver all present
+ APCs; release the APC spinlock while acccessing user memory.
+
+2002-08-08 David Welch <welch@computer2.darkstar.org>
+
+ * include/internal/ps.h: Adjusted offsets into the ETHREAD
+ structure.
+ * include/internal/ps.h: Removed redundant members from the
+ KTHREAD structure.
+ * ntoskrnl/ke/kthread.c (KeInitializeThread): Removed
+ redundant members from the KTHREAD structure.
+
+2002-08-08 David Welch <welch@computer2.darkstar.org>
+
+ * ntoskrnl/dbg/kdb.c (KdbEnterDebuggerException): New
+ function to enter the debugger on an exception.
+ * ntoskrnl/kd/kdebug.c (KdInitSystem): Initialize the
+ local kernel debugger if enabled.
+ * ntoskrnl/ke/catch.c (KiDispatchException): Enter the
+ local kernel debugger on an exception.
+
+2002-08-08 David Welch <welch@computer2.darkstar.org>
+
+ * include/ntdll/ldr.h: Added definition for a DLL entrypoint.
+ * lib/kernel32/process/create.c (KlCreateFirstThread): Put
+ the argument to the NtProcessStartup function on the stack.
+ * lib/kernel32/process/create.c (KlInitPeb): Read the
+ base address of the new image from the PEB.
+ * lib/kernel32/process/create.c (CreateProcessW): Start the
+ first thread at the entrypoint of the new image.
+ * lib/ntdll/ldr/startup.c (LdrInitializeThunk): If the
+ function is called after the initial startup then just call the
+ entrypoints for the loaded DLLs with DLL_THREAD_ATTACH. Don't
+ call the entrypoint of the image.
+ * lib/ntdll/rtl/process.c (RtlpCreateFirstThread): Put the
+ argument to the NtProcessStartup function on the stack.
+ * lib/ntdll/rtl/process.c (KlInitPeb): Read the base address of
+ the new image from the PEB.
+ * lib/ntdll/rtl/process.c (RtlCreateUserProcess): Start the
+ first thread at the entrypoint of the new image.
+ * ntoskrnl/ke/i386/bthread.S (PsBeginThreadWithContextInternal):
+ Use the system call path to begin a usermode thread.
+ * ntoskrnl/ke/i386/thread.c (Ke386InitThreadWithContext): Convert
+ the supplied context into a trap frame.
+ * ntoskrnl/ldr/init.c (LdrLoadInitialProcess): Put the PEB argument
+ to the NtProcessStartup function on the new stack; start the
+ first thread at the entrypoint of the image.
+ * ntoskrnl/ps/create.c (NtCreateThread): Create an APC to call
+ LdrInitializeThunk in the context of a new thread before its
+ entrypoint.
+
+2002-08-08 David Welch <welch@computer2.darkstar.org>
+
+ * drivers/fs/vfat/cleanup.c (VfatCleanupFile): Uninitialise
+ the cache on file cleanup.
+ * drivers/fs/vfat/fcb.c (vfatReleaseFcb): Don't uninitialise
+ the cache on file close.
+ * ntoskrnl/cc/copy.c: Renamed zero page global variable.
+ * ntoskrnl/cc/view.c: Added cache delete function.
+
2002-07-13 Casper S. Hornstrup <chorns@users.sourceforge.net>
* rules.mak (RSYM): Define.
base.tmp
junk.tmp
temp.exp
-
+beep.coff
-/* $Id: cleanup.c,v 1.5 2002/06/10 21:15:58 hbirr Exp $
+/* $Id: cleanup.c,v 1.6 2002/08/08 17:54:12 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FUNCTION: Cleans up after a file has been closed.
*/
{
- PVFATCCB pCcb;
- PVFATFCB pFcb;
-
- DPRINT("VfatCleanupFile(DeviceExt %x, FileObject %x)\n",
+ PVFATCCB pCcb;
+ PVFATFCB pFcb;
+
+ DPRINT("VfatCleanupFile(DeviceExt %x, FileObject %x)\n",
DeviceExt, FileObject);
-
- /* FIXME: handle file/directory deletion here */
- pCcb = (PVFATCCB) (FileObject->FsContext2);
- if (pCcb == NULL)
- {
+
+ /* FIXME: handle file/directory deletion here */
+ pCcb = (PVFATCCB) (FileObject->FsContext2);
+ if (pCcb == NULL)
+ {
return STATUS_SUCCESS;
- }
- pFcb = pCcb->pFcb;
- if (FileObject->FileName.Buffer)
- {
+ }
+ pFcb = pCcb->pFcb;
+
+ if (FileObject->FileName.Buffer)
+ {
if (pFcb->Flags & FCB_UPDATE_DIRENTRY)
- {
- updEntry (DeviceExt, FileObject);
- pFcb->Flags &= ~FCB_UPDATE_DIRENTRY;
- }
- }
+ {
+ updEntry (DeviceExt, FileObject);
+ pFcb->Flags &= ~FCB_UPDATE_DIRENTRY;
+ }
+ }
+ /* Uninitialize the file cache. */
+ CcRosReleaseFileCache (FileObject, pFcb->RFCB.Bcb);
+
return STATUS_SUCCESS;
}
-/* $Id: fcb.c,v 1.15 2002/06/26 18:36:41 hbirr Exp $
+/* $Id: fcb.c,v 1.16 2002/08/08 17:54:12 dwelch Exp $
*
*
* FILE: fcb.c
pFCB->RefCount--;
if (pFCB->RefCount <= 0 && (!vfatFCBIsDirectory (pVCB, pFCB) || pFCB->Flags & FCB_DELETE_PENDING))
{
- RemoveEntryList (&pFCB->FcbListEntry);
- CcRosReleaseFileCache (NULL, pFCB->RFCB.Bcb);
+ RemoveEntryList (&pFCB->FcbListEntry);
vfatDestroyFCB (pFCB);
}
KeReleaseSpinLock (&pVCB->FcbListLock, oldIrql);
typedef NTSTATUS STDCALL (*PEPFUNC)(PPEB);
+/* Type for a DLL's entry point */
+typedef BOOL STDCALL
+(* PDLLMAIN_FUNC)(HANDLE hInst,
+ ULONG ul_reason_for_call,
+ LPVOID lpReserved);
+
typedef struct _LDR_MODULE
{
LIST_ENTRY InLoadOrderModuleList;
-/* $Id: create.c,v 1.46 2002/05/07 22:25:40 hbirr Exp $
+/* $Id: create.c,v 1.47 2002/08/08 17:54:12 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
INITIAL_TEB InitialTeb;
BOOLEAN CreateSuspended = FALSE;
ULONG OldPageProtection;
+ ULONG ResultLength;
+ ULONG InitialStack[5];
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
ObjectAttributes.RootDirectory = NULL;
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,
static NTSTATUS
KlInitPeb (HANDLE ProcessHandle,
- PRTL_USER_PROCESS_PARAMETERS Ppb)
+ PRTL_USER_PROCESS_PARAMETERS Ppb,
+ PVOID* ImageBaseAddress)
{
NTSTATUS Status;
PVOID PpbBase;
sizeof(PpbBase),
&BytesWritten);
+ /* Read image base address. */
+ Offset = FIELD_OFFSET(PEB, ImageBaseAddress);
+ NtReadVirtualMemory(ProcessHandle,
+ (PVOID)(PEB_BASE + Offset),
+ ImageBaseAddress,
+ sizeof(PVOID),
+ &BytesWritten);
+
return(STATUS_SUCCESS);
}
WCHAR TempApplicationNameW[256];
WCHAR TempCommandLineNameW[256];
UNICODE_STRING RuntimeInfo_U;
+ PVOID ImageBaseAddress;
DPRINT("CreateProcessW(lpApplicationName '%S', lpCommandLine '%S')\n",
lpApplicationName, lpCommandLine);
*/
DPRINT("Creating peb\n");
- KlInitPeb(hProcess, Ppb);
+ KlInitPeb(hProcess, Ppb, &ImageBaseAddress);
RtlDestroyProcessParameters (Ppb);
ProcessImageFileName,
ImageFileName,
8);
- /*
- * Retrieve the start address
- */
- DPRINT("Retrieving entry point address\n");
- RtlInitAnsiString (&ProcedureName, "LdrInitializeThunk");
- Status = LdrGetProcedureAddress ((PVOID)NTDLL_BASE,
- &ProcedureName,
- 0,
- (PVOID*)&lpStartAddress);
- if (!NT_SUCCESS(Status))
- {
- DbgPrint ("LdrGetProcedureAddress failed (Status %x)\n", Status);
- return FALSE;
- }
- DPRINT("lpStartAddress 0x%08lx\n", (ULONG)lpStartAddress);
-
/*
* Create the thread for the kernel
*/
DPRINT("Creating thread for process\n");
hThread = KlCreateFirstThread(hProcess,
lpThreadAttributes,
- //Sii.StackReserve,
- 0x200000,
- //Sii.StackCommit,
- 0x1000,
- lpStartAddress,
+ Sii.StackReserve,
+ Sii.StackCommit,
+ ImageBaseAddress + (ULONG)Sii.EntryPoint,
dwCreationFlags,
&lpProcessInformation->dwThreadId);
if (hThread == NULL)
-/* $Id: startup.c,v 1.38 2002/07/13 12:44:06 chorns Exp $
+/* $Id: startup.c,v 1.39 2002/08/08 17:54:13 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
WCHAR FullNtDllPath[MAX_PATH];
DPRINT("LdrInitializeThunk()\n");
+ if (NtCurrentPeb()->Ldr != NULL && NtCurrentPeb()->Ldr->Initialized == TRUE)
+ {
+ PLIST_ENTRY current_entry;
+ PDLLMAIN_FUNC Entrypoint;
+ PLDR_MODULE current;
+
+ current_entry = NtCurrentPeb()->Ldr->InLoadOrderModuleList.Flink;
+ while (current_entry != &NtCurrentPeb()->Ldr->InLoadOrderModuleList)
+ {
+ current = CONTAINING_RECORD(current_entry, LDR_MODULE,
+ InLoadOrderModuleList);
+ Entrypoint = (PDLLMAIN_FUNC)current->EntryPoint;
+ if (Entrypoint != NULL &&
+ current->BaseAddress != NtCurrentPeb()->ImageBaseAddress)
+ {
+ (VOID)Entrypoint(current->BaseAddress, DLL_THREAD_ATTACH, NULL);
+ }
+ current_entry = current_entry->Flink;
+ }
+ return;
+ }
Peb = (PPEB)(PEB_BASE);
DPRINT("Peb %x\n", Peb);
/* all required dlls are loaded now */
Peb->Ldr->Initialized = TRUE;
+ /* Check before returning that we can run the image safely. */
if (EntryPoint == NULL)
{
DbgPrint("Failed to initialize image\n");
ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
}
-
- Status = EntryPoint(Peb);
- ZwTerminateProcess(NtCurrentProcess(),Status);
}
/* EOF */
-/* $Id: utils.c,v 1.51 2002/07/13 12:44:06 chorns Exp $
+/* $Id: utils.c,v 1.52 2002/08/08 17:54:13 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
/* PROTOTYPES ****************************************************************/
-
-/* Type for a DLL's entry point */
-typedef WINBOOL STDCALL
-(* PDLLMAIN_FUNC)(HANDLE hInst,
- ULONG ul_reason_for_call,
- LPVOID lpReserved);
-
static NTSTATUS LdrFindEntryForName(PUNICODE_STRING Name, PLDR_MODULE *Module);
static PVOID LdrFixupForward(PCHAR ForwardName);
static PVOID LdrGetExportByName(PVOID BaseAddress, PUCHAR SymbolName, USHORT Hint);
-/* $Id: process.c,v 1.27 2001/08/07 14:10:42 ekohl Exp $
+/* $Id: process.c,v 1.28 2002/08/08 17:54:13 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
INITIAL_TEB InitialTeb;
ULONG OldPageProtection;
CLIENT_ID Cid;
+ ULONG InitialStack[5];
+ ULONG ResultLength;
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
ObjectAttributes.RootDirectory = NULL;
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,
}
static NTSTATUS KlInitPeb (HANDLE ProcessHandle,
- PRTL_USER_PROCESS_PARAMETERS Ppb)
+ PRTL_USER_PROCESS_PARAMETERS Ppb,
+ PVOID* ImageBaseAddress)
{
NTSTATUS Status;
PVOID PpbBase;
sizeof(PpbBase),
&BytesWritten);
+ /* Read image base address. */
+ Offset = FIELD_OFFSET(PEB, ImageBaseAddress);
+ NtReadVirtualMemory(ProcessHandle,
+ (PVOID)(PEB_BASE + Offset),
+ ImageBaseAddress,
+ sizeof(PVOID),
+ &BytesWritten);
+
return(STATUS_SUCCESS);
}
ULONG retlen;
CHAR FileName[8];
ANSI_STRING ProcedureName;
+ SECTION_IMAGE_INFORMATION Sii;
+ ULONG ResultLength;
+ PVOID ImageBaseAddress;
DPRINT("RtlCreateUserProcess\n");
*/
DPRINT("Creating peb\n");
KlInitPeb(ProcessInfo->ProcessHandle,
- ProcessParameters);
-
- DPRINT("Retrieving entry point address\n");
- RtlInitAnsiString (&ProcedureName, "LdrInitializeThunk");
- Status = LdrGetProcedureAddress ((PVOID)NTDLL_BASE,
- &ProcedureName,
- 0,
- (PVOID*)&lpStartAddress);
- if (!NT_SUCCESS(Status))
+ ProcessParameters,
+ &ImageBaseAddress);
+
+ Status = NtQuerySection(hSection,
+ SectionImageInformation,
+ &Sii,
+ sizeof(Sii),
+ &ResultLength);
+ if (!NT_SUCCESS(Status) || ResultLength != sizeof(Sii))
{
- DbgPrint ("LdrGetProcedureAddress failed (Status %x)\n", Status);
- NtClose(hSection);
- return (Status);
+ DPRINT("Failed to get section image information.\n");
+ NtClose(hSection);
+ return(Status);
}
- DPRINT("lpStartAddress 0x%08lx\n", (ULONG)lpStartAddress);
DPRINT("Creating thread for process\n");
Status = RtlpCreateFirstThread(ProcessInfo->ProcessHandle,
-// Headers.OptionalHeader.SizeOfStackReserve,
- 0x200000,
-// Headers.OptionalHeader.SizeOfStackCommit,
- 0x1000,
- lpStartAddress,
+ Sii.StackReserve,
+ Sii.StackCommit,
+ ImageBaseAddress + (ULONG)Sii.EntryPoint,
&ProcessInfo->ClientId,
&ProcessInfo->ThreadHandle);
if (!NT_SUCCESS(Status))
NtClose(hSection);
return(Status);
}
+ NtClose(hSection);
return(STATUS_SUCCESS);
}
ntoskrnl.dbg
bugcodes.rc
msg*.bin
-
+ntoskrnl.map
-/* $Id: copy.c,v 1.7 2002/07/17 21:04:55 dwelch Exp $
+/* $Id: copy.c,v 1.8 2002/08/08 17:54:13 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
/* FUNCTIONS *****************************************************************/
VOID
-InitCacheZeroPage(VOID)
+CcInitCacheZeroPage(VOID)
{
NTSTATUS Status;
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: view.c,v 1.44 2002/07/17 21:04:55 dwelch Exp $
+/* $Id: view.c,v 1.45 2002/08/08 17:54:13 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
}
NTSTATUS STDCALL
-CcRosReleaseFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
+CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
/*
* FUNCTION: Releases the BCB associated with a file object
*/
return(STATUS_SUCCESS);
}
+NTSTATUS STDCALL
+CcRosReleaseFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
+/*
+ * FUNCTION: Called by the file system when a handle to a file object
+ * has been closed.
+ */
+{
+ return(STATUS_SUCCESS);
+}
+
NTSTATUS STDCALL
CcRosInitializeFileCache(PFILE_OBJECT FileObject,
- PBCB* Bcb,
- ULONG CacheSegmentSize)
+ PBCB* Bcb,
+ ULONG CacheSegmentSize)
/*
* FUNCTION: Initializes a BCB for a file object
*/
InitializeListHead(&CacheSegmentLRUListHead);
ExInitializeFastMutex(&ViewLock);
MmInitializeMemoryConsumer(MC_CACHE, CcRosTrimCache);
- InitCacheZeroPage();
+ CcInitCacheZeroPage();
}
/* EOF */
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: kdb.c,v 1.7 2002/07/18 00:25:30 dwelch Exp $
+/* $Id: kdb.c,v 1.8 2002/08/08 17:54:14 dwelch Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/dbg/kdb.c
__asm__ __volatile__("sti\n\t");
}
+KD_CONTINUE_TYPE
+KdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
+ PCONTEXT Context,
+ PKTRAP_FRAME TrapFrame)
+{
+ DbgPrint("Entered debugger on exception number %d.\n",
+ TrapFrame->DebugArgMark);
+ KdbInternalEnter(TrapFrame);
+ return(kdHandleException);
+}
#ifndef __INCLUDE_INTERNAL_CC_H
#define __INCLUDE_INTERNAL_CC_H
-/* $Id: cc.h,v 1.11 2002/06/10 21:11:56 hbirr Exp $ */
+/* $Id: cc.h,v 1.12 2002/08/08 17:54:14 dwelch Exp $ */
#include <ddk/ntifs.h>
typedef struct _BCB
ULONG FileOffset,
ULONG Length,
PCACHE_SEGMENT* CacheSeg);
-VOID InitCacheZeroPage(VOID);
+VOID CcInitCacheZeroPage(VOID);
#endif
-/* $Id: kd.h,v 1.13 2002/07/19 03:56:47 ei Exp $
+/* $Id: kd.h,v 1.14 2002/08/08 17:54:14 dwelch Exp $
*
* kernel debugger prototypes
*/
#define KD_DEBUG_BOCHS 0x10
#define KD_DEBUG_FILELOG 0x20
#define KD_DEBUG_MDA 0x40
+#define KD_DEBUG_KDB 0x80
extern ULONG KdDebugState;
KdbFreeSymbolsProcess(PPEB Peb);
BOOLEAN
KdbPrintAddress(PVOID address);
+KD_CONTINUE_TYPE
+KdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
+ PCONTEXT Context,
+ PKTRAP_FRAME TrapFrame);
#endif /* __INCLUDE_INTERNAL_KERNEL_DEBUGGER_H */
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: ps.h,v 1.36 2002/07/10 15:11:46 ekohl Exp $
+/* $Id: ps.h,v 1.37 2002/08/08 17:54:14 dwelch Exp $
*
* FILE: ntoskrnl/ke/kthread.c
* PURPOSE: Process manager definitions
#define KTHREAD_TRAP_FRAME 0x128
#define KTHREAD_CALLBACK_STACK 0x120
-#define ETHREAD_THREADS_PROCESS 0x258
+#define ETHREAD_THREADS_PROCESS 0x234
#define KPROCESS_DIRECTORY_TABLE_BASE 0x18
/* Added by Phillip Susi for list of threads in a process */
LIST_ENTRY ProcessThreadListEntry; /* 1B0 */
-
- /* Added by Phillip Susi for internal KeAddThreadTimeout() implementation */
- KDPC TimerDpc; /* 1B8 */
-
- /* Record the last EIP value when the thread is suspended */
- ULONG LastEip; /* 1D8 */
} __attribute__((packed)) KTHREAD, *PKTHREAD;
// According to documentation the stack should have a commited [ 1 page ] and
typedef struct _ETHREAD
{
KTHREAD Tcb; /* 000 */
- TIME CreateTime; /* 1B0/1DC */
+ TIME CreateTime; /* 1B0/1B8 */
union
{
TIME ExitTime; /* 1B8/1E4 */
*/
KD_CONTINUE_TYPE
KdEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
- PCONTEXT Context,
- PKTRAP_FRAME TrapFrame)
+ PCONTEXT Context,
+ PKTRAP_FRAME TrapFrame)
{
BOOLEAN Stepping;
LONG Address;
-/* $Id: kdebug.c,v 1.37 2002/07/04 19:56:35 dwelch Exp $
+/* $Id: kdebug.c,v 1.38 2002/08/08 17:54:14 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
DbgRDebugInit();
#endif
+#ifdef KDBG
+ /* Initialize the local kernel debugger. */
+ KdDebuggerEnabled = TRUE;
+ KdDebugState |= KD_DEBUG_KDB;
+#endif
+
/* Set debug port default values */
PortInfo.ComPort = DEFAULT_DEBUG_PORT;
PortInfo.BaudRate = DEFAULT_DEBUG_BAUD_RATE;
DbgPrint("KiDeliverUserApc called but no APC was pending\n");
return(FALSE);
}
-
- current_entry = RemoveHeadList(&Thread->ApcState.ApcListHead[1]);
- Apc = CONTAINING_RECORD(current_entry, KAPC, ApcListEntry);
-
- /*
- * Save the thread's current context (in other words the registers
- * that will be restored when it returns to user mode) so the
- * APC dispatcher can restore them later
- */
- Context = (PCONTEXT)(((PUCHAR)TrapFrame->Esp) - sizeof(CONTEXT));
- memset(Context, 0, sizeof(CONTEXT));
- Context->ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER |
- CONTEXT_SEGMENTS | CONTEXT_i386;
- Context->SegGs = TrapFrame->Gs;
- Context->SegFs = TrapFrame->Fs;
- Context->SegEs = TrapFrame->Es;
- Context->SegDs = TrapFrame->Ds;
- Context->Edi = TrapFrame->Edi;
- Context->Esi = TrapFrame->Esi;
- Context->Ebx = TrapFrame->Ebx;
- Context->Edx = TrapFrame->Edx;
- Context->Ecx = TrapFrame->Ecx;
- Context->Eax = TrapFrame->Eax;
- Context->Ebp = TrapFrame->Ebp;
- Context->Eip = TrapFrame->Eip;
- Context->SegCs = TrapFrame->Cs;
- Context->EFlags = TrapFrame->Eflags;
- Context->Esp = TrapFrame->Esp;
- Context->SegSs = TrapFrame->Ss;
-
- /*
- * Setup the trap frame so the thread will start executing at the
- * APC Dispatcher when it returns to user-mode
- */
- Esp = (PULONG)(((PUCHAR)TrapFrame->Esp) -
- (sizeof(CONTEXT) + (6 * sizeof(ULONG))));
-
- Esp[0] = 0xdeadbeef;
- Esp[1] = (ULONG)Apc->NormalRoutine;
- Esp[2] = (ULONG)Apc->NormalContext;
- Esp[3] = (ULONG)Apc->SystemArgument1;
- Esp[4] = (ULONG)Apc->SystemArgument2;
- Esp[5] = (ULONG)Context;
- TrapFrame->Eip = (ULONG)LdrpGetSystemDllApcDispatcher();
- TrapFrame->Esp = (ULONG)Esp;
-
- /*
- * We've dealt with one pending user-mode APC
- */
- Thread->ApcState.UserApcPending--;
-
- /*
- * FIXME: Give some justification for this
- */
- KeReleaseSpinLock(&PiApcLock, oldlvl);
+
+ while (!IsListEmpty(&Thread->ApcState.ApcListHead[1]))
+ {
+ current_entry = RemoveHeadList(&Thread->ApcState.ApcListHead[1]);
+ KeReleaseSpinLock(&PiApcLock, oldlvl);
+ Apc = CONTAINING_RECORD(current_entry, KAPC, ApcListEntry);
- /*
- * Now call for the kernel routine for the APC, which will free
- * the APC data structure, we can't do this ourselves because
- * the APC may be embedded in some larger structure e.g. an IRP
- * We also give the kernel routine a last chance to modify the arguments to
- * the user APC routine.
- */
- Apc->KernelRoutine(Apc,
- (PKNORMAL_ROUTINE*)&Esp[1],
- (PVOID*)&Esp[2],
- (PVOID*)&Esp[3],
- (PVOID*)&Esp[4]);
-
+ /*
+ * Save the thread's current context (in other words the registers
+ * that will be restored when it returns to user mode) so the
+ * APC dispatcher can restore them later
+ */
+ Context = (PCONTEXT)(((PUCHAR)TrapFrame->Esp) - sizeof(CONTEXT));
+ memset(Context, 0, sizeof(CONTEXT));
+ Context->ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER |
+ CONTEXT_SEGMENTS | CONTEXT_i386;
+ Context->SegGs = TrapFrame->Gs;
+ Context->SegFs = TrapFrame->Fs;
+ Context->SegEs = TrapFrame->Es;
+ Context->SegDs = TrapFrame->Ds;
+ Context->Edi = TrapFrame->Edi;
+ Context->Esi = TrapFrame->Esi;
+ Context->Ebx = TrapFrame->Ebx;
+ Context->Edx = TrapFrame->Edx;
+ Context->Ecx = TrapFrame->Ecx;
+ Context->Eax = TrapFrame->Eax;
+ Context->Ebp = TrapFrame->Ebp;
+ Context->Eip = TrapFrame->Eip;
+ Context->SegCs = TrapFrame->Cs;
+ Context->EFlags = TrapFrame->Eflags;
+ Context->Esp = TrapFrame->Esp;
+ Context->SegSs = TrapFrame->Ss;
+
+ /*
+ * Setup the trap frame so the thread will start executing at the
+ * APC Dispatcher when it returns to user-mode
+ */
+ Esp = (PULONG)(((PUCHAR)TrapFrame->Esp) -
+ (sizeof(CONTEXT) + (6 * sizeof(ULONG))));
+
+ Esp[0] = 0xdeadbeef;
+ Esp[1] = (ULONG)Apc->NormalRoutine;
+ Esp[2] = (ULONG)Apc->NormalContext;
+ Esp[3] = (ULONG)Apc->SystemArgument1;
+ Esp[4] = (ULONG)Apc->SystemArgument2;
+ Esp[5] = (ULONG)Context;
+ TrapFrame->Eip = (ULONG)LdrpGetSystemDllApcDispatcher();
+ TrapFrame->Esp = (ULONG)Esp;
+
+ /*
+ * We've dealt with one pending user-mode APC
+ */
+ Thread->ApcState.UserApcPending--;
+
+ /*
+ * Now call for the kernel routine for the APC, which will free
+ * the APC data structure, we can't do this ourselves because
+ * the APC may be embedded in some larger structure e.g. an IRP
+ * We also give the kernel routine a last chance to modify the
+ * arguments to the user APC routine.
+ */
+ Apc->KernelRoutine(Apc,
+ (PKNORMAL_ROUTINE*)&Esp[1],
+ (PVOID*)&Esp[2],
+ (PVOID*)&Esp[3],
+ (PVOID*)&Esp[4]);
+
+ KeAcquireSpinLock(&PiApcLock, &oldlvl);
+ }
Thread->Alerted[0] = 0;
+ KeReleaseSpinLock(&PiApcLock, oldlvl);
+
return(TRUE);
}
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: bug.c,v 1.24 2002/07/17 21:04:55 dwelch Exp $
+/* $Id: bug.c,v 1.25 2002/08/08 17:54:14 dwelch Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/bug.c
DbgBreakPoint();
}
- for(;;)
- {
- /* PJS: use HLT instruction, rather than busy wait */
- __asm__("hlt\n\t");
- }
+ for(;;);
}
VOID STDCALL
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: catch.c,v 1.21 2002/07/18 00:25:30 dwelch Exp $
+/* $Id: catch.c,v 1.22 2002/08/08 17:54:14 dwelch Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/catch.c
/* PreviousMode == KernelMode */
- if ((!KdDebuggerEnabled) || (!(KdDebugState & KD_DEBUG_GDB)))
- {
- /* FIXME: Get ExceptionNr and CR2 */
+ if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_GDB)
+ {
+ Action = KdEnterDebuggerException (ExceptionRecord, Context, Tf);
+ }
+#ifdef KDBG
+ else if (KdDebuggerEnable && KdDebugState & KD_DEBUG_KDB)
+ {
+ Action = KdbEnterDebuggerException (ExceptionRecord, Context, Tf);
+ }
+#endif /* KDBG */
+ else
+ {
KeBugCheckWithTf (KMODE_EXCEPTION_NOT_HANDLED, 0, 0, 0, 0, Tf);
}
-
- Action = KdEnterDebuggerException (ExceptionRecord, Context, Tf);
if (Action != kdHandleException)
{
Value = RtlpDispatchException (ExceptionRecord, Context);
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: bthread.S,v 1.2 2000/12/23 02:37:40 dwelch Exp $
+/* $Id: bthread.S,v 1.3 2002/08/08 17:54:15 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
*/
call _PiBeforeBeginThread
- /*
- * Jump to the desired context
- */
- popl %eax /* ContextFlags */
+ /* FIXME: Don't ignore the debugging registers. */
popl %eax /* Dr0 */
popl %eax /* Dr1 */
popl %eax /* Dr2 */
popl %eax /* Dr3 */
popl %eax /* Dr6 */
popl %eax /* Dr7 */
+
+ /* FIXME: Don't ignore the floating point registers. */
addl $112,%esp /* FloatSave */
- popl %gs
- addl $4, %esp /* Ignore SegFs */
- movl $TEB_SELECTOR, %eax /* Set the FS selector */
- movl %eax, %fs
- popl %es
- popl %ds
- popl %edi
- popl %esi
- popl %ebx
- popl %edx
- popl %ecx
- popl %eax
- popl %ebp
- iret
+
+ /* Load the rest of the thread's user mode context. */
+ movl $0,%eax
+ jmp KeReturnFromSystemCallWithHook
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: syscall.S,v 1.6 2002/07/04 19:56:36 dwelch Exp $
+/* $Id: syscall.S,v 1.7 2002/08/08 17:54:15 dwelch Exp $
*
* FILE: ntoskrnl/hal/x86/syscall.s
* PURPOSE: 2E trap handler
/*
*
*/
-.globl KeReturnFromSystemCall
+.globl KeReturnFromSystemCall
+.globl KeReturnFromSystemCallWithHook
.globl _interrupt_handler2e
_interrupt_handler2e:
/* Deallocate the kernel stack frame */
movl %ebp,%esp
+KeReturnFromSystemCallWithHook:
/* Call the post system call hook and deliver any pending APCs */
pushl %esp
pushl %eax
addl $8,%esp
KeReturnFromSystemCall:
-
+
/* Restore the user context */
/* Get a pointer to the current thread */
movl %fs:0x124, %esi
NTSTATUS
Ke386InitThreadWithContext(PKTHREAD Thread, PCONTEXT Context)
{
- PULONG KernelStack;
+ PULONG KernelStack;
+ ULONG InitSize;
+ PKTRAP_FRAME TrapFrame;
/*
* Setup a stack frame for exit from the task switching routine
*/
- KernelStack = (PULONG)(Thread->KernelStack - ((4 * 5) + sizeof(CONTEXT)));
- /* FIXME: Add initial floating point information */
- /* FIXME: Add initial debugging information */
+ InitSize = 5 * sizeof(DWORD) + 6 * sizeof(DWORD) +
+ sizeof(FLOATING_SAVE_AREA) + sizeof(KTRAP_FRAME);
+ KernelStack = (PULONG)(Thread->KernelStack - InitSize);
+
+ /* Set up the initial frame for the return from the dispatcher. */
KernelStack[0] = 0; /* EDI */
KernelStack[1] = 0; /* ESI */
KernelStack[2] = 0; /* EBX */
KernelStack[3] = 0; /* EBP */
KernelStack[4] = (ULONG)PsBeginThreadWithContextInternal; /* EIP */
- memcpy((PVOID)&KernelStack[5], (PVOID)Context, sizeof(CONTEXT));
+
+ /* Set up the initial values of the debugging registers. */
+ KernelStack[5] = Context->Dr0;
+ KernelStack[6] = Context->Dr1;
+ KernelStack[7] = Context->Dr2;
+ KernelStack[8] = Context->Dr3;
+ KernelStack[9] = Context->Dr6;
+ KernelStack[10] = Context->Dr7;
+
+ /* Set up the initial floating point state. */
+ memcpy((PVOID)&KernelStack[11], (PVOID)&Context->FloatSave,
+ sizeof(FLOATING_SAVE_AREA));
+
+ /* Set up a trap frame from the context. */
+ TrapFrame = (PKTRAP_FRAME)
+ ((PBYTE)KernelStack + 11 * sizeof(DWORD) + sizeof(FLOATING_SAVE_AREA));
+ TrapFrame->DebugEbp = (PVOID)Context->Ebp;
+ TrapFrame->DebugEip = (PVOID)Context->Eip;
+ TrapFrame->DebugArgMark = 0;
+ TrapFrame->DebugPointer = 0;
+ TrapFrame->TempCs = 0;
+ TrapFrame->TempEip = 0;
+ TrapFrame->Gs = Context->SegGs;
+ TrapFrame->Es = Context->SegEs;
+ TrapFrame->Ds = Context->SegDs;
+ TrapFrame->Edx = Context->Ebx;
+ TrapFrame->Ecx = Context->Ecx;
+ TrapFrame->Eax = Context->Eax;
+ TrapFrame->PreviousMode = UserMode;
+ TrapFrame->ExceptionList = (PVOID)0xFFFFFFFF;
+ TrapFrame->Fs = TEB_SELECTOR;
+ TrapFrame->Edi = Context->Edi;
+ TrapFrame->Esi = Context->Esi;
+ TrapFrame->Ebx = Context->Ebx;
+ TrapFrame->Ebp = Context->Ebp;
+ TrapFrame->ErrorCode = 0;
+ TrapFrame->Cs = Context->SegCs;
+ TrapFrame->Eip = Context->Eip;
+ TrapFrame->Esp = Context->Esp;
+ TrapFrame->Ss = Context->SegSs;
+ /* FIXME: Should check for a v86 mode context here. */
+
+ /* Save back the new value of the kernel stack. */
Thread->KernelStack = (PVOID)KernelStack;
return(STATUS_SUCCESS);
PEPROCESS CurrentProcess;
PPEB Peb = NULL;
ULONG_PTR RelativeAddress;
+ PPEB_LDR_DATA Ldr;
+ NTSTATUS Status;
CurrentProcess = PsGetCurrentProcess();
if (NULL != CurrentProcess)
- {
- Peb = CurrentProcess->Peb;
- }
-
+ {
+ Peb = CurrentProcess->Peb;
+ }
+
if (NULL == Peb)
- {
+ {
DbgPrint("<%x>", address);
return(TRUE);
}
- current_entry = Peb->Ldr->InLoadOrderModuleList.Flink;
+ Status = MmSafeCopyFromUser(&Ldr, Peb->Ldr, sizeof(PPEB_LDR_DATA));
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("<%x>", address);
+ return(TRUE);
+ }
+ current_entry = Ldr->InLoadOrderModuleList.Flink;
- while (current_entry != &Peb->Ldr->InLoadOrderModuleList &&
+ while (current_entry != &Ldr->InLoadOrderModuleList &&
current_entry != NULL)
{
current =
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: kthread.c,v 1.29 2002/07/17 21:04:55 dwelch Exp $
+/* $Id: kthread.c,v 1.30 2002/08/08 17:54:14 dwelch Exp $
*
* FILE: ntoskrnl/ke/kthread.c
* PURPOSE: Microkernel thread support
*/
Thread->ProcessThreadListEntry.Flink = NULL;
Thread->ProcessThreadListEntry.Blink = NULL;
- KeInitializeDpc(&Thread->TimerDpc,
- (PKDEFERRED_ROUTINE)PiTimeoutThread,
- Thread);
- Thread->LastEip = 0;
/*
* Do x86 specific part
/*
- * COPYRIGHT: See COPYING in the top level directory
+ * ReactOS kernel
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 ReactOS Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
* PROJECT: ReactOS kernel
- * FILE: ntoskrnl/ldr/loader.c
+ * FILE: ntoskrnl/ldr/init.c
* PURPOSE: Loaders for PE executables
* PROGRAMMERS: Jean Michault
* Rex Jolliff (rex@lvcablemodem.com)
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE FileHandle;
HANDLE SectionHandle;
- PVOID LdrStartupAddr;
PIMAGE_NT_HEADERS NTHeaders;
- PPEB Peb;
PEPROCESS Process;
CONTEXT Context;
HANDLE ThreadHandle;
INITIAL_TEB InitialTeb;
ULONG OldPageProtection;
+ SECTION_IMAGE_INFORMATION Sii;
+ ULONG ResultLength;
+ PVOID ImageBaseAddress;
+ ULONG InitialStack[5];
/*
* Get the absolute path to smss.exe using the
return(Status);
}
ZwClose(FileHandle);
+
+ /*
+ * Get information about the process image.
+ */
+ Status = ZwQuerySection(SectionHandle,
+ SectionImageInformation,
+ &Sii,
+ sizeof(Sii),
+ &ResultLength);
+ if (!NT_SUCCESS(Status) || ResultLength != sizeof(Sii))
+ {
+ DPRINT("ZwQuerySection failed (Status %X)\n", Status);
+ ZwClose(SectionHandle);
+ return(Status);
+ }
DPRINT("Creating process\n");
Status = ZwCreateProcess(&ProcessHandle,
* Create initial stack and thread
*/
- /*
- * Aargh!
- */
- LdrStartupAddr = (PVOID)LdrpGetSystemDllEntryPoint();
- DPRINT("LdrStartupAddr %x\n", LdrStartupAddr);
-
/*
* Create page backed section for stack
*/
DPRINT("Attaching to process\n");
KeAttachProcess(Process);
- Peb = (PPEB)PEB_BASE;
- DPRINT("Peb %x\n", Peb);
- DPRINT("CurrentProcess %x Peb->ImageBaseAddress %x\n",
- PsGetCurrentProcess(),
- Peb->ImageBaseAddress);
- NTHeaders = RtlImageNtHeader(Peb->ImageBaseAddress);
+ ImageBaseAddress = Process->Peb->ImageBaseAddress;
+ NTHeaders = RtlImageNtHeader(ImageBaseAddress);
DPRINT("NTHeaders %x\n", NTHeaders);
InitialTeb.StackReserve = NTHeaders->OptionalHeader.SizeOfStackReserve;
/* FIXME: use correct commit size */
InitialTeb.StackCommit = NTHeaders->OptionalHeader.SizeOfStackReserve - PAGESIZE;
-// InitialTeb.StackCommit = NTHeaders->OptionalHeader.SizeOfStackCommit;
+ // InitialTeb.StackCommit = NTHeaders->OptionalHeader.SizeOfStackCommit;
/* add guard page size */
InitialTeb.StackCommit += PAGESIZE;
DPRINT("StackReserve 0x%lX StackCommit 0x%lX\n",
DPRINT("Dereferencing process\n");
ObDereferenceObject(Process);
- DPRINT("Allocating stack\n");
- InitialTeb.StackAllocate = NULL;
- 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);
- }
-
- 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!\n");
- return(Status);
- }
-
- DPRINT("StackLimit: %p\nStackCommit: 0x%lX\n",
- InitialTeb.StackLimit,
- InitialTeb.StackCommit);
-
- /* Protect guard page */
- Status = NtProtectVirtualMemory(ProcessHandle,
- InitialTeb.StackLimit,
- PAGESIZE,
- PAGE_GUARD | PAGE_READWRITE,
- &OldPageProtection);
- if (!NT_SUCCESS(Status))
- {
- /* release the stack space */
- NtFreeVirtualMemory(ProcessHandle,
- InitialTeb.StackAllocate,
- &InitialTeb.StackReserve,
- MEM_RELEASE);
-
- DPRINT("Error protecting guard page!\n");
- return(Status);
- }
-
- DPRINT("Attaching to process\n");
- KeAttachProcess(Process);
- Peb = (PPEB)PEB_BASE;
- DPRINT("Peb %x\n", Peb);
- DPRINT("CurrentProcess %x Peb->ImageBaseAddress %x\n",
- PsGetCurrentProcess(),
- Peb->ImageBaseAddress);
- KeDetachProcess();
+ DPRINT("Allocating stack\n");
+ InitialTeb.StackAllocate = NULL;
+ 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);
+ }
+
+ 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!\n");
+ return(Status);
+ }
+
+ DPRINT("StackLimit: %p\nStackCommit: 0x%lX\n",
+ InitialTeb.StackLimit,
+ InitialTeb.StackCommit);
+
+ /* Protect guard page */
+ Status = NtProtectVirtualMemory(ProcessHandle,
+ InitialTeb.StackLimit,
+ PAGESIZE,
+ PAGE_GUARD | PAGE_READWRITE,
+ &OldPageProtection);
+ if (!NT_SUCCESS(Status))
+ {
+ /* release the stack space */
+ NtFreeVirtualMemory(ProcessHandle,
+ InitialTeb.StackAllocate,
+ &InitialTeb.StackReserve,
+ MEM_RELEASE);
- /*
- * Initialize context to point to LdrStartup
- */
- memset(&Context,0,sizeof(CONTEXT));
- Context.Eip = (ULONG)LdrStartupAddr;
- Context.SegCs = USER_CS;
- Context.SegDs = USER_DS;
- Context.SegEs = USER_DS;
- Context.SegFs = TEB_SELECTOR;
- Context.SegGs = USER_DS;
- Context.SegSs = USER_DS;
- Context.EFlags = 0x202;
- Context.Esp = (ULONG)InitialTeb.StackBase - 20;
+ DPRINT("Error protecting guard page!\n");
+ return(Status);
+ }
+
+ /*
+ * Initialize context to point to LdrStartup
+ */
+ memset(&Context,0,sizeof(CONTEXT));
+ Context.Eip = (ULONG)(ImageBaseAddress + (ULONG)Sii.EntryPoint);
+ Context.SegCs = USER_CS;
+ Context.SegDs = USER_DS;
+ Context.SegEs = USER_DS;
+ Context.SegFs = TEB_SELECTOR;
+ Context.SegGs = USER_DS;
+ Context.SegSs = USER_DS;
+ Context.EFlags = 0x202;
+ Context.Esp = (ULONG)InitialTeb.StackBase - 20;
- DPRINT("LdrStartupAddr %x\n",LdrStartupAddr);
-
- /*
- * FIXME: Create process and let 'er rip
- */
- DPRINT("Creating thread for initial process\n");
- Status = ZwCreateThread(&ThreadHandle,
- THREAD_ALL_ACCESS,
- NULL,
- ProcessHandle,
- NULL,
- &Context,
- &InitialTeb,
- FALSE);
+ /*
+ * Write in the initial stack.
+ */
+ InitialStack[0] = 0;
+ InitialStack[1] = PEB_BASE;
+ Status = ZwWriteVirtualMemory(ProcessHandle,
+ (PVOID)Context.Esp,
+ InitialStack,
+ sizeof(InitialStack),
+ &ResultLength);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to write initial stack.\n");
+ return(Status);
+ }
+
+ /*
+ * FIXME: Create process and let 'er rip
+ */
+ DPRINT("Creating thread for initial process\n");
+ Status = ZwCreateThread(&ThreadHandle,
+ THREAD_ALL_ACCESS,
+ NULL,
+ ProcessHandle,
+ NULL,
+ &Context,
+ &InitialTeb,
+ FALSE);
if (!NT_SUCCESS(Status))
{
DPRINT("Thread creation failed (Status %x)\n", Status);
-
+
NtFreeVirtualMemory(ProcessHandle,
InitialTeb.StackAllocate,
&InitialTeb.StackReserve,
/* FIXME: unmap the section here */
/* FIXME: destroy the section here */
+ /* FIXME: Kill the process here */
return(Status);
}
- DPRINT("Attaching to process\n");
- KeAttachProcess(Process);
- Peb = (PPEB)PEB_BASE;
- DPRINT("Peb %x\n", Peb);
- DPRINT("CurrentProcess %x Peb->ImageBaseAddress %x\n",
- PsGetCurrentProcess(),
- Peb->ImageBaseAddress);
- KeDetachProcess();
-
return(STATUS_SUCCESS);
}
* 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.86 2002/06/10 21:34:37 hbirr Exp $
+/* $Id: section.c,v 1.87 2002/08/08 17:54:15 dwelch Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/section.c
Sbi->Attributes = 0;
Sbi->Size.QuadPart = 0;
+ *ResultLength = sizeof(SECTION_BASIC_INFORMATION);
Status = STATUS_SUCCESS;
-
break;
}
Sii->Unknown4[0] = 0;
Sii->Unknown4[1] = 0;
Sii->Unknown4[2] = 0;
-
+
+ *ResultLength = sizeof(SECTION_IMAGE_INFORMATION);
Status = STATUS_SUCCESS;
break;
}
default:
+ *ResultLength = 0;
Status = STATUS_INVALID_INFO_CLASS;
}
ObDereferenceObject(Section);
-/* $Id: create.c,v 1.47 2002/07/10 15:17:34 ekohl Exp $
+/* $Id: create.c,v 1.48 2002/08/08 17:54:16 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
#include <internal/se.h>
#include <internal/id.h>
#include <internal/dbg.h>
+#include <internal/ldr.h>
#define NDEBUG
#include <internal/debug.h>
PVOID arg1,
PVOID arg2)
{
- // wake up the thread, and tell it it timed out
- NTSTATUS Status = STATUS_TIMEOUT;
+ /* Wake up the thread, and tell it it timed out */
+ NTSTATUS Status = STATUS_TIMEOUT;
- DPRINT("PiTimeoutThread()\n");
-
- KeRemoveAllWaitsThread((PETHREAD)Context, Status);
+ DPRINT("PiTimeoutThread()\n");
+
+ KeRemoveAllWaitsThread((PETHREAD)Context, Status);
}
VOID
PiBeforeBeginThread(CONTEXT c)
{
DPRINT("PiBeforeBeginThread(Eip %x)\n", c.Eip);
- //KeReleaseSpinLock(&PiThreadListLock, PASSIVE_LEVEL);
- KeLowerIrql(PASSIVE_LEVEL);
-}
-
-#if 0
-VOID
-PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext)
-{
- NTSTATUS Ret;
-
- // KeReleaseSpinLock(&PiThreadListLock,PASSIVE_LEVEL);
KeLowerIrql(PASSIVE_LEVEL);
- Ret = StartRoutine(StartContext);
- PsTerminateSystemThread(Ret);
- KeBugCheck(0);
}
-#endif
VOID STDCALL
PiDeleteThread(PVOID ObjectBody)
return Status;
}
+VOID STDCALL
+LdrInitApcRundownRoutine(PKAPC Apc)
+{
+ ExFreePool(Apc);
+}
+
+VOID STDCALL
+LdrInitApcKernelRoutine(PKAPC Apc,
+ PKNORMAL_ROUTINE* NormalRoutine,
+ PVOID* NormalContext,
+ PVOID* SystemArgument1,
+ PVOID* SystemArgument2)
+{
+ ExFreePool(Apc);
+}
NTSTATUS STDCALL
NtCreateThread(PHANDLE ThreadHandle,
PETHREAD Thread;
PTEB TebBase;
NTSTATUS Status;
+ PKAPC LdrInitApc;
DPRINT("NtCreateThread(ThreadHandle %x, PCONTEXT %x)\n",
ThreadHandle,ThreadContext);
DbgkCreateThread((PVOID)ThreadContext->Eip);
/*
- * Start the thread running
+ * First, force the thread to be non-alertable for user-mode alerts.
*/
- if (!CreateSuspended)
- {
- DPRINT("Not creating suspended\n");
- PsUnblockThread(Thread, NULL);
- }
- else
- {
- DPRINT("Creating suspended\n");
-
- /*
- * Simulate a call to NtWaitForSingleObject() upon thread startup
- */
-
- /* Increment the suspend counter */
- Thread->Tcb.SuspendCount++;
-
- /* Add one wait-block for suspend semaphore */
- Thread->Tcb.WaitStatus = STATUS_UNSUCCESSFUL;
- Thread->Tcb.WaitBlockList = &Thread->Tcb.WaitBlock[0];
- Thread->Tcb.WaitBlock[0].Object = (POBJECT)&Thread->Tcb.SuspendSemaphore;
- Thread->Tcb.WaitBlock[0].Thread = &Thread->Tcb;
- Thread->Tcb.WaitBlock[0].WaitKey = STATUS_WAIT_0;
- Thread->Tcb.WaitBlock[0].WaitType = WaitAny;
- Thread->Tcb.WaitBlock[0].NextWaitBlock = NULL;
- InsertTailList(&Thread->Tcb.SuspendSemaphore.Header.WaitListHead,
- &Thread->Tcb.WaitBlock[0].WaitListEntry);
- }
+ Thread->Tcb.Alertable = FALSE;
+
+ /*
+ * If the thread is to be created suspended then queue an APC to
+ * do the suspend before we run any userspace code.
+ */
+
+ /*
+ * Queue an APC to the thread that will execute the ntdll startup
+ * routine.
+ */
+ LdrInitApc = ExAllocatePool(NonPagedPool, sizeof(KAPC));
+ KeInitializeApc(LdrInitApc, &Thread->Tcb, 0, LdrInitApcKernelRoutine,
+ LdrInitApcRundownRoutine, LdrpGetSystemDllEntryPoint(),
+ UserMode, NULL);
+ KeInsertQueueApc(LdrInitApc, NULL, NULL, UserMode);
+
+ /*
+ * Start the thread running and force it to execute the APC(s) we just
+ * queued before it runs anything else in user-mode.
+ */
+ Thread->Tcb.Alertable = TRUE;
+ Thread->Tcb.Alerted[0] = 1;
+ PsUnblockThread(Thread, NULL);
return(STATUS_SUCCESS);
}
-/* $Id: thread.c,v 1.99 2002/07/10 15:15:00 ekohl Exp $
+/* $Id: thread.c,v 1.100 2002/08/08 17:54:16 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
if (KThread->ApcState.KernelApcPending)
{
if (!DispatcherLock)
- {
- KeAcquireDispatcherDatabaseLock(FALSE);
- }
+ {
+ KeAcquireDispatcherDatabaseLock(FALSE);
+ }
WaitBlock = (PKWAIT_BLOCK)Thread->Tcb.WaitBlockList;
while (WaitBlock)
- {
- RemoveEntryList (&WaitBlock->WaitListEntry);
- WaitBlock = WaitBlock->NextWaitBlock;
- }
+ {
+ RemoveEntryList (&WaitBlock->WaitListEntry);
+ WaitBlock = WaitBlock->NextWaitBlock;
+ }
Thread->Tcb.WaitBlockList = NULL;
KeReleaseDispatcherDatabaseLockAtDpcLevel(FALSE);
PsDispatchThreadNoLock (THREAD_STATE_READY);
if (Status != NULL)
- {
- *Status = STATUS_KERNEL_APC;
- }
+ {
+ *Status = STATUS_KERNEL_APC;
+ }
}
else
- {
- if (DispatcherLock)
{
- KeReleaseDispatcherDatabaseLockAtDpcLevel(FALSE);
- }
- Thread->Tcb.Alertable = Alertable;
- Thread->Tcb.WaitMode = WaitMode;
- Thread->Tcb.WaitIrql = WaitIrql;
- PsDispatchThreadNoLock(THREAD_STATE_BLOCKED);
- if (Status != NULL)
- {
- *Status = Thread->Tcb.WaitStatus;
+ if (DispatcherLock)
+ {
+ KeReleaseDispatcherDatabaseLockAtDpcLevel(FALSE);
+ }
+ Thread->Tcb.Alertable = Alertable;
+ Thread->Tcb.WaitMode = WaitMode;
+ Thread->Tcb.WaitIrql = WaitIrql;
+ PsDispatchThreadNoLock(THREAD_STATE_BLOCKED);
+ if (Status != NULL)
+ {
+ *Status = Thread->Tcb.WaitStatus;
+ }
}
- }
KeLowerIrql(WaitIrql);
}