diff --git a/reactos/.gdbinit b/reactos/.gdbinit index 57774eaa1e0..8acbe5f0ab2 100644 --- a/reactos/.gdbinit +++ b/reactos/.gdbinit @@ -1,5 +1,5 @@ file ntoskrnl/ntoskrnl.nostrip.exe add-symbol-file lib/ntdll/ntdll.dll 0x77f61000 -add-symbol-file subsys/smss/smss.exe 0x401000 +add-symbol-file apps/apc/apc.exe 0x401000 #add-symbol-file subsys/csrss/csrss.exe 0x401000 break exp.c:156 diff --git a/reactos/apps/tests/apc/apc.c b/reactos/apps/tests/apc/apc.c index b9297ac9978..6bbcfbafba4 100644 --- a/reactos/apps/tests/apc/apc.c +++ b/reactos/apps/tests/apc/apc.c @@ -92,7 +92,6 @@ int main(int argc, char* argv[]) printf("Returned from wait\n"); ZwClose(FileHandle); printf("Program finished\n"); - for(;;); return 0; } diff --git a/reactos/apps/tests/apc/makefile b/reactos/apps/tests/apc/makefile index a662ec002d1..773cfb1e675 100644 --- a/reactos/apps/tests/apc/makefile +++ b/reactos/apps/tests/apc/makefile @@ -3,6 +3,8 @@ # PATH_TO_TOP = ../.. +CFLAGS = -g + OBJECTS= ../common/crt0.o apc.o PROGS= apc.exe diff --git a/reactos/include/ddk/ketypes.h b/reactos/include/ddk/ketypes.h index 332052ea16f..9825017d9ab 100644 --- a/reactos/include/ddk/ketypes.h +++ b/reactos/include/ddk/ketypes.h @@ -98,9 +98,9 @@ typedef BOOLEAN (*PKSYNCHRONIZE_ROUTINE)(PVOID SynchronizeContext); struct _KAPC; -typedef VOID (*PKNORMAL_ROUTINE)(PVOID NormalContext, - PVOID SystemArgument1, - PVOID SystemArgument2); +typedef VOID STDCALL (*PKNORMAL_ROUTINE)(PVOID NormalContext, + PVOID SystemArgument1, + PVOID SystemArgument2); typedef VOID (*PKKERNEL_ROUTINE)(struct _KAPC* Apc, PKNORMAL_ROUTINE* NormalRoutine, PVOID* NormalContext, diff --git a/reactos/include/ntos/types.h b/reactos/include/ntos/types.h index 70df4deac2c..04515bc7480 100644 --- a/reactos/include/ntos/types.h +++ b/reactos/include/ntos/types.h @@ -68,11 +68,13 @@ typedef union _LARGE_INTEGER DWORD LowPart; LONG HighPart; } u; +#ifdef ANONYMOUSUNIONS struct { DWORD LowPart; LONG HighPart; }; +#endif /* ANONYMOUSUNIONS */ LONGLONG QuadPart; } LARGE_INTEGER, *PLARGE_INTEGER; @@ -83,11 +85,13 @@ typedef union _ULARGE_INTEGER DWORD LowPart; DWORD HighPart; } u; +#ifdef ANONYMOUSUNIONS struct { DWORD LowPart; DWORD HighPart; }; +#endif /* ANONYMOUSUNIONS */ ULONGLONG QuadPart; } ULARGE_INTEGER, *PULARGE_INTEGER; @@ -119,6 +123,34 @@ typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE; typedef unsigned short *PWCHAR; +#ifdef __PPC__ +#define CONTEXT_CONTROL 1L +#define CONTEXT_FLOATING_POINT 2L +#define CONTEXT_INTEGER 4L +#define CONTEXT_DEBUG_REGISTERS 8L + +#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER) +#define CONTEXT_DEBUGGER (CONTEXT_FULL) + +#else /* x86 */ +/* The doc refered me to winnt.h, so I had to look... */ +#define SIZE_OF_80387_REGISTERS 80 + +/* Values for contextflags */ +#define CONTEXT_i386 0x10000 +#define CONTEXT_CONTROL (CONTEXT_i386 | 1) +#define CONTEXT_INTEGER (CONTEXT_i386 | 2) +#define CONTEXT_SEGMENTS (CONTEXT_i386 | 4) +#define CONTEXT_FLOATING_POINT (CONTEXT_i386 | 8) +#define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386 | 0x10) +#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS) + +/* our own invention */ +#define FLAG_TRACE_BIT 0x100 +#define CONTEXT_DEBUGGER (CONTEXT_FULL | CONTEXT_FLOATING_POINT) + +#endif + #ifdef __i386__ typedef struct _FLOATING_SAVE_AREA { diff --git a/reactos/lib/kernel32/file/rw.c b/reactos/lib/kernel32/file/rw.c index 5ff63ca4a44..f7f8d26416a 100644 --- a/reactos/lib/kernel32/file/rw.c +++ b/reactos/lib/kernel32/file/rw.c @@ -1,4 +1,4 @@ -/* $Id: rw.c,v 1.13 2000/06/03 14:47:32 ea Exp $ +/* $Id: rw.c,v 1.14 2000/10/11 20:50:31 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -165,12 +165,12 @@ VOID ApcRoutine(PVOID ApcContext, } -WINBOOL STDCALL WriteFileEx (HANDLE hFile, - LPCVOID lpBuffer, - DWORD nNumberOfBytesToWrite, - LPOVERLAPPED lpOverLapped, - LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine - ) +WINBOOL STDCALL +WriteFileEx (HANDLE hFile, + LPCVOID lpBuffer, + DWORD nNumberOfBytesToWrite, + LPOVERLAPPED lpOverLapped, + LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) { LARGE_INTEGER Offset; diff --git a/reactos/lib/kernel32/thread/thread.c b/reactos/lib/kernel32/thread/thread.c index 905393e48db..9fd64f0a3df 100644 --- a/reactos/lib/kernel32/thread/thread.c +++ b/reactos/lib/kernel32/thread/thread.c @@ -1,4 +1,4 @@ -/* $Id: thread.c,v 1.21 2000/10/08 16:32:52 dwelch Exp $ +/* $Id: thread.c,v 1.22 2000/10/11 20:50:32 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -344,12 +344,9 @@ DWORD STDCALL ResumeThread(HANDLE hThread) } -WINBOOL -STDCALL -TerminateThread ( - HANDLE hThread, - DWORD dwExitCode - ) +WINBOOL STDCALL +TerminateThread (HANDLE hThread, + DWORD dwExitCode) { NTSTATUS errCode; diff --git a/reactos/lib/ntdll/def/ntdll.def b/reactos/lib/ntdll/def/ntdll.def index ddcca286f7e..4034fe2bf66 100644 --- a/reactos/lib/ntdll/def/ntdll.def +++ b/reactos/lib/ntdll/def/ntdll.def @@ -1,4 +1,4 @@ -; $Id: ntdll.def,v 1.64 2000/09/01 17:04:47 ekohl Exp $ +; $Id: ntdll.def,v 1.65 2000/10/11 20:50:32 dwelch Exp $ ; ; ReactOS Operating System ; @@ -29,7 +29,7 @@ DbgUiContinue@8 DbgUiWaitStateChange@8 DbgUserBreakPoint@0 ;KiRaiseUserExceptionDispatcher -;KiUserApcDispatcher +KiUserApcDispatcher ;KiUserCallbackDispatcher ;KiUserExceptionDispatcher LdrAccessResource@16 diff --git a/reactos/lib/ntdll/def/ntdll.edf b/reactos/lib/ntdll/def/ntdll.edf index 9e5387206cc..2a543cd0d7f 100644 --- a/reactos/lib/ntdll/def/ntdll.edf +++ b/reactos/lib/ntdll/def/ntdll.edf @@ -1,4 +1,4 @@ -; $Id: ntdll.edf,v 1.53 2000/09/01 17:04:47 ekohl Exp $ +; $Id: ntdll.edf,v 1.54 2000/10/11 20:50:32 dwelch Exp $ ; ; ReactOS Operating System ; @@ -29,7 +29,7 @@ DbgUiContinue=DbgUiContinue@8 DbgUiWaitStateChange=DbgUiWaitStateChange@8 DbgUserBreakPoint=DbgUserBreakPoint@0 ;KiRaiseUserExceptionDispatcher -;KiUserApcDispatcher +KiUserApcDispatcher=KiUserApcDispatcher@20 ;KiUserCallbackDispatcher ;KiUserExceptionDispatcher LdrAccessResource=LdrAccessResource@16 diff --git a/reactos/lib/ntdll/rtl/apc.c b/reactos/lib/ntdll/rtl/apc.c index 99ef246c165..d909cfd9ebc 100644 --- a/reactos/lib/ntdll/rtl/apc.c +++ b/reactos/lib/ntdll/rtl/apc.c @@ -1,4 +1,4 @@ -/* $Id: apc.c,v 1.3 2000/06/29 23:35:29 dwelch Exp $ +/* $Id: apc.c,v 1.4 2000/10/11 20:50:32 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -20,9 +20,14 @@ VOID STDCALL KiUserApcDispatcher(PIO_APC_ROUTINE ApcRoutine, ULONG Reserved, PCONTEXT Context) { + DbgPrint("KiUserApcDispatcher(ApcRoutine %x, ApcContext %x, Context %x)\n", + ApcRoutine, ApcContext, Context); ApcRoutine(ApcContext, Iosb, - Reserved);; + Reserved); + DbgPrint("Done ApcRoutine, Context %x, Context->Eip %x\n", + Context, Context->Eip); NtContinue(Context, 1); + DbgPrint("Returned from NtContinue, aargh\n"); } diff --git a/reactos/lib/rpcrt4/clnt/binding.c b/reactos/lib/rpcrt4/clnt/binding.c deleted file mode 100644 index 17bc18152c7..00000000000 --- a/reactos/lib/rpcrt4/clnt/binding.c +++ /dev/null @@ -1,10 +0,0 @@ -RPC_STATUS RpcBindingFromStringBindingW(PWCHAR Binding, - handle_t* BindingHandle) -{ - -} - -RPC_STATUS RpcBindingFromStringBindingA(PUCHAR Binding, - handle_t BindingHandle) -{ -} diff --git a/reactos/lib/rpcrt4/clnt/string.c b/reactos/lib/rpcrt4/clnt/string.c deleted file mode 100644 index 31091a8baf5..00000000000 --- a/reactos/lib/rpcrt4/clnt/string.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - */ - -RPC_STATUS RpcStringBindingComposeA(PUCHAR Uuid, - PUCHAR Protocol, - PUCHAR Address, - PUCHAR Endpoint, - PUCHAR Options, - PUCHAR* Binding) -{ - ULONG Len; - - - Len = strlen(Protocol) + 1 + strlen(Address) + - 1 + strlen(Endpoint) + 1 + 1; - (*Binding) = HeapAlloc(GetProcessHeap(), - HEAP_ZERO_MEMORY, - Len); - strcpy(*Binding, Protocol); - strcat(*Binding, ":"); - strcat(*Binding, Address); - strcat(*Binding, "["); - strcat(*Binding, Endpoint); - strcat(*Binding, "]"); - - return(STATUS_SUCCESS); -} - -RPC_STATUS RpcStringBindingComposeW(PWCHAR Uuid, - PWCHAR Protocol, - PWCHAR Address, - PWCHAR Endpoint, - WCHAR Options, - PWCHAR* Binding) -{ - ULONG Len; - - - Len = wcslen(Protocol) + 1 + wcslen(Address) + - 1 + wcslen(Endpoint) + 1 + 1; - (*Binding) = HeapAlloc(GetProcessHeap(), - HEAP_ZERO_MEMORY, - Len * 2); - wcscpy(*Binding, Protocol); - wcscat(*Binding, ":"); - wcscat(*Binding, Address); - wcscat(*Binding, "["); - wcscat(*Binding, Endpoint); - wcscat(*Binding, "]"); - - return(STATUS_SUCCESS); -} diff --git a/reactos/lib/rpcrt4/midl/Makefile b/reactos/lib/rpcrt4/midl/Makefile index ad5cf6eec67..067d5ca93d8 100644 --- a/reactos/lib/rpcrt4/midl/Makefile +++ b/reactos/lib/rpcrt4/midl/Makefile @@ -1,12 +1,10 @@ -# $Id: Makefile,v 1.1 2000/03/26 22:00:08 dwelch Exp $ +# $Id: Makefile,v 1.2 2000/10/11 20:50:33 dwelch Exp $ # # ReactOS Operating System # TARGET=midl -BASE_CFLAGS = -I../../include - -CFLAGS = $(CFLAGS) +CFLAGS = all: midl$(EXE_POSTFIX) diff --git a/reactos/lib/rpcrt4/srv/ep.c b/reactos/lib/rpcrt4/srv/ep.c deleted file mode 100644 index fd2c3272bdc..00000000000 --- a/reactos/lib/rpcrt4/srv/ep.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * - */ - -/* INCLUDES ******************************************************************/ - -#include - -/* FUNCTIONS *****************************************************************/ - -RPC_STATUS RpcServerUseProtseqA(unsigned char* Protseq, - unsigned int MaxCalls, - void* SecurityDescriptor) -{ - return(RpcServerUseProtseqEpA(Protseq, - MaxCalls, - SecuritDescriptor)); -} - -RPC_STATUS RpcServerUseProtseqW(unsigned wchar_t* Protseq, - unsigned int MaxCalls, - void* SecurityDescriptor) -{ - return(RpcServerUseProtseqEpW(Protseq, - MaxCalls, - SecuritDescriptor)); -} - -RPC_STATUS RpcServerUseProtseqEpA(unsigned char* Protseq, - unsigned int MaxCalls, - unsigned char* Endpoint, - void* SecurityDescriptor) -{ - unsigned wchar_t* ProtseqW; - UNICODE_STRING ProtseqU; - ANSI_STRING ProtseqA; - unsigned wchar_t* EndpointW; - UNICODE_STRING EndpointU; - ANSI_STRING EndpointA; - RPC_STATUS Status; - - if (Protseq != NULL) - { - RtlInitAnsiString(&ProtseqA, Protseq); - RtlAnsiStringToUnicodeString(&ProtseqU, &ProtseqA, TRUE); - ProtseqW = ProtseqU.Buffer; - } - else - { - ProtseqW = NULL; - } - if (Endpoint != NULL) - { - RtlInitAnsiString(&EndpointA, Endpoint); - RtlAnsiStringToUnicodeString(&EndpointU, &EndpointA, TRUE); - EndpointW = EndpointU.Buffer; - } - else - { - EndpointW = NULL; - } - - Status = RpcServerUseProtseqEpW(ProtseqW, - MaxCalls, - EndpointW, - SecurityDescriptor); - - RtlFreeUnicodeString(&EndpointU); - RtlFreeUnicodeString(&ProtseqU); - return(Status); -} - -RPC_STATUS RpcServerUseProtseqEpW(unsigned wchar_t* Protseq, - unsigned int MaxCalls, - unsigned wchar_t* Endpoint, - void* SecurityDescriptor) -{ -} - -RPC_STATUS RpcServerRegisterIf(RPC_IF_HANDLE IfSpec, - UUID* MgrTypeUuid, - RPC_MGR_EPV* MgrEpv) -{ - -} - - diff --git a/reactos/lib/rpcrt4/srv/impersonate.c b/reactos/lib/rpcrt4/srv/impersonate.c deleted file mode 100644 index cb2843e1422..00000000000 --- a/reactos/lib/rpcrt4/srv/impersonate.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * - */ - -/* INCLUDES ******************************************************************/ - -#include - -/* FUNCTIONS *****************************************************************/ - -RPC_STATUS RpcImpersonateClient(RPC_BINDING_HANDLE BindingHandle) -{ -} - -RPC_STATUS RpcRevertToSelfEx(RPC_BINDING_HANDLE BindingHandle) -{ -} - -RPC_STATUS RpcRevertToSelf() -{ -} diff --git a/reactos/lib/rpcrt4/srv/listen.c b/reactos/lib/rpcrt4/srv/listen.c deleted file mode 100644 index a1b551d318f..00000000000 --- a/reactos/lib/rpcrt4/srv/listen.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: DCE/RPC for Reactos - * FILE: lib/rpcrt4/srv/listen.c - * PURPOSE: Listener functions - * PROGRAMMER: David Welch - */ - -/* INCLUDES ******************************************************************/ - -/* TYPES *********************************************************************/ - -typedef struct -{ -} listener_socket; - -/* GLOBALS *******************************************************************/ - -#define NR_MAX_LISTENERS (255) - -static HANDLE ListenerMutex; -static ULONG InServerListen; - -/* FUNCTIONS *****************************************************************/ - -static DWORD RpcListenerThread(PVOID Param) -{ - -} - -BOOL RpcInitListenModule(VOID) -{ - ListenerMutex = CreateMutex(NULL, - FALSE, - NULL); - if (ListenMutex == NULL) - { - return(FALSE); - } - - InServerListen = 0; -} - -RPC_STATUS RpcServerListen(unsigned int MinimumCallThreads, - unsigned int MaxCalls, - unsigned int DontWait) -{ -} diff --git a/reactos/ntoskrnl/hal/x86/udelay.c b/reactos/ntoskrnl/hal/x86/udelay.c index 60b1523f02d..b60cb716708 100644 --- a/reactos/ntoskrnl/hal/x86/udelay.c +++ b/reactos/ntoskrnl/hal/x86/udelay.c @@ -1,11 +1,8 @@ -/* $Id: udelay.c,v 1.3 2000/10/07 13:41:50 dwelch Exp $ - * - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/hal/x86/udelay.c - * PURPOSE: Busy waiting - * PROGRAMMER: David Welch (david.welch@seh.ox.ac.uk) - * UPDATE HISTORY: - * 06/11/99 Created +/* + * ReactOS kernel + * Copyright (C) 2000 David Welch + * Copyright (C) 1999 Gareth Owen , Ramon von Handel + * Copyright (C) 1991, 1992 Linus Torvalds * * This software is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -23,6 +20,15 @@ * MA 02139, USA. * */ +/* $Id: udelay.c,v 1.4 2000/10/11 20:50:33 dwelch Exp $ + * + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/hal/x86/udelay.c + * PURPOSE: Busy waiting + * PROGRAMMER: David Welch (david.welch@seh.ox.ac.uk) + * UPDATE HISTORY: + * 06/11/99 Created + */ /* INCLUDES ***************************************************************/ diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 3f03ace125f..b56babccc20 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -20,6 +20,7 @@ typedef struct _KTRAP_FRAME PVOID DebugEbp; PVOID DebugEip; PVOID DebugArgMark; + PVOID DebugPointer; PVOID TempCs; PVOID TempEip; PVOID Dr0; diff --git a/reactos/ntoskrnl/include/internal/ldr.h b/reactos/ntoskrnl/include/internal/ldr.h index b8d5225c727..b67355e4264 100644 --- a/reactos/ntoskrnl/include/internal/ldr.h +++ b/reactos/ntoskrnl/include/internal/ldr.h @@ -36,9 +36,9 @@ LdrpMapSystemDll ( PVOID * LdrStartupAddress ); PVOID -LdrpGetSystemDllEntryPoint ( - VOID - ); +LdrpGetSystemDllEntryPoint (VOID); +PVOID +LdrpGetSystemDllApcDispatcher(VOID); NTSTATUS LdrpMapImage ( HANDLE ProcessHandle, diff --git a/reactos/ntoskrnl/include/internal/ps.h b/reactos/ntoskrnl/include/internal/ps.h index bd2ff4e8308..12907ebbcbd 100644 --- a/reactos/ntoskrnl/include/internal/ps.h +++ b/reactos/ntoskrnl/include/internal/ps.h @@ -30,6 +30,7 @@ /* * Defines for accessing KPCR and KTHREAD structure members */ +#define KTHREAD_KERNEL_STACK 0x28 #define KTHREAD_PREVIOUS_MODE 0x137 #define KTHREAD_TRAP_FRAME 0x128 diff --git a/reactos/ntoskrnl/io/cleanup.c b/reactos/ntoskrnl/io/cleanup.c index a02e01f9d37..4ed2c41c11c 100644 --- a/reactos/ntoskrnl/io/cleanup.c +++ b/reactos/ntoskrnl/io/cleanup.c @@ -30,13 +30,38 @@ VOID IopCompleteRequest1(struct _KAPC* Apc, PVOID* SystemArgument2) { PIRP Irp; + CCHAR PriorityBoost; + PIO_STACK_LOCATION IoStack; + PFILE_OBJECT FileObject; DPRINT("IopCompleteRequest1()\n"); Irp = (PIRP)(*SystemArgument1); + PriorityBoost = (CCHAR)(LONG)(*SystemArgument2); + + IoStack = IoGetCurrentIrpStackLocation(Irp); + (*SystemArgument1) = (PVOID)Irp->UserIosb; (*SystemArgument2) = (PVOID)Irp->IoStatus.Information; - IoFreeIrp((PIRP)(*SystemArgument1)); + + if (Irp->UserIosb!=NULL) + { + *Irp->UserIosb=Irp->IoStatus; + } + if (Irp->UserEvent!=NULL) + { + KeSetEvent(Irp->UserEvent,PriorityBoost,FALSE); + } + + FileObject = IoStack->FileObject; + + if (FileObject != NULL && IoStack->MajorFunction != IRP_MJ_CLOSE) + { + ObDereferenceObject(FileObject); + } + + IoFreeIrp(Irp); + } VOID IoDeviceControlCompletion(PDEVICE_OBJECT DeviceObject, @@ -196,7 +221,7 @@ VOID IoSecondStageCompletion(PIRP Irp, CCHAR PriorityBoost) UserApcRoutine = (PKNORMAL_ROUTINE) Irp->Overlay.AsynchronousParameters.UserApcRoutine; UserApcContext = (PVOID) - Irp->Overlay.AsynchronousParameters.UserApcRoutine; + Irp->Overlay.AsynchronousParameters.UserApcContext; KeInitializeApc(&Irp->Tail.Apc, Thread, 0, @@ -207,7 +232,7 @@ VOID IoSecondStageCompletion(PIRP Irp, CCHAR PriorityBoost) UserApcContext); KeInsertQueueApc(&Irp->Tail.Apc, Irp, - NULL, + (PVOID)(LONG)PriorityBoost, KernelMode); return; } diff --git a/reactos/ntoskrnl/io/irp.c b/reactos/ntoskrnl/io/irp.c index 2d3d46c09b6..63218463e04 100644 --- a/reactos/ntoskrnl/io/irp.c +++ b/reactos/ntoskrnl/io/irp.c @@ -1,4 +1,4 @@ -/* $Id: irp.c,v 1.29 2000/07/04 08:52:38 dwelch Exp $ +/* $Id: irp.c,v 1.30 2000/10/11 20:50:34 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -40,8 +40,7 @@ /* FUNCTIONS ****************************************************************/ -PDEVICE_OBJECT -STDCALL +PDEVICE_OBJECT STDCALL IoGetDeviceToVerify (PETHREAD Thread) /* * FUNCTION: Returns a pointer to the device, representing a removable-media @@ -52,8 +51,7 @@ IoGetDeviceToVerify (PETHREAD Thread) } -VOID -STDCALL +VOID STDCALL IoFreeIrp (PIRP Irp) /* * FUNCTION: Releases a caller allocated irp @@ -65,8 +63,7 @@ IoFreeIrp (PIRP Irp) } -PIRP -STDCALL +PIRP STDCALL IoMakeAssociatedIrp (PIRP Irp, CCHAR StackSize) /* * FUNCTION: Allocates and initializes an irp to associated with a master irp @@ -83,8 +80,7 @@ IoMakeAssociatedIrp (PIRP Irp, CCHAR StackSize) } -VOID -STDCALL +VOID STDCALL IoInitializeIrp (PIRP Irp, USHORT PacketSize, CCHAR StackSize) /* * FUNCTION: Initalizes an irp allocated by the caller @@ -104,8 +100,7 @@ IoInitializeIrp (PIRP Irp, USHORT PacketSize, CCHAR StackSize) } -NTSTATUS -FASTCALL +NTSTATUS FASTCALL IofCallDriver (PDEVICE_OBJECT DeviceObject, PIRP Irp) /* * FUNCTION: Sends an IRP to the next lower driver @@ -248,10 +243,9 @@ IofCompleteRequest (PIRP Irp, CCHAR PriorityBoost) IopCompleteRequest, NULL, (PKNORMAL_ROUTINE) - Irp->Overlay.AsynchronousParameters.UserApcRoutine, - UserMode, - (PVOID) - Irp->Overlay.AsynchronousParameters.UserApcContext); + NULL, + KernelMode, + NULL); KeInsertQueueApc(&Irp->Tail.Apc, (PVOID)Irp, (PVOID)(ULONG)PriorityBoost, diff --git a/reactos/ntoskrnl/io/rw.c b/reactos/ntoskrnl/io/rw.c index 7bb5b67e09c..3390372996e 100644 --- a/reactos/ntoskrnl/io/rw.c +++ b/reactos/ntoskrnl/io/rw.c @@ -1,4 +1,4 @@ -/* $Id: rw.c,v 1.31 2000/07/07 00:42:58 phreak Exp $ +/* $Id: rw.c,v 1.32 2000/10/11 20:50:34 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -88,16 +88,21 @@ NTSTATUS STDCALL NtReadFile(HANDLE FileHandle, NULL); if (!NT_SUCCESS(Status)) { + ObDereferenceObject(FileObject); return Status; } } - else - { + else if (FileObject->Flags & FO_SYNCHRONOUS_IO) + { KeInitializeEvent(&Event, NotificationEvent, FALSE); ptrEvent = &Event; } + else + { + ptrEvent = NULL; + } Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, FileObject->DeviceObject, @@ -126,10 +131,21 @@ NTSTATUS STDCALL NtReadFile(HANDLE FileHandle, if ((Status == STATUS_PENDING) && (FileObject->Flags & FO_SYNCHRONOUS_IO)) { + BOOLEAN Alertable; + + if (FileObject->Flags & FO_ALERTABLE_IO) + { + Alertable = TRUE; + } + else + { + Alertable = FALSE; + } + KeWaitForSingleObject(&Event, Executive, KernelMode, - FALSE, + Alertable, NULL); Status = IoStatusBlock->Status; } @@ -166,6 +182,7 @@ NTSTATUS STDCALL NtWriteFile(HANDLE FileHandle, PIRP Irp; PIO_STACK_LOCATION StackPtr; KEVENT Event; + PKEVENT ptrEvent; DPRINT("NtWriteFile(FileHandle %x, Buffer %x, Length %d)\n", FileHandle, Buffer, Length); @@ -185,7 +202,33 @@ NTSTATUS STDCALL NtWriteFile(HANDLE FileHandle, { ByteOffset = &FileObject->CurrentByteOffset; } - + + if (EventHandle != NULL) + { + Status = ObReferenceObjectByHandle(EventHandle, + SYNCHRONIZE, + ExEventObjectType, + UserMode, + (PVOID*)&ptrEvent, + NULL); + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(FileObject); + return(Status); + } + } + else if (FileObject->Flags & FO_SYNCHRONOUS_IO) + { + KeInitializeEvent(&Event, + NotificationEvent, + FALSE); + ptrEvent = &Event; + } + else + { + ptrEvent = NULL; + } + KeInitializeEvent(&Event, NotificationEvent, FALSE); @@ -194,7 +237,7 @@ NTSTATUS STDCALL NtWriteFile(HANDLE FileHandle, Buffer, Length, ByteOffset, - &Event, + ptrEvent, IoStatusBlock); Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine; diff --git a/reactos/ntoskrnl/ke/apc.c b/reactos/ntoskrnl/ke/apc.c index 9b1a7423fbe..32e66f07a40 100644 --- a/reactos/ntoskrnl/ke/apc.c +++ b/reactos/ntoskrnl/ke/apc.c @@ -17,10 +17,15 @@ #include #include #include +#include #define NDEBUG #include +/* NOTES *********************************************************************/ + + + /* GLOBALS *******************************************************************/ KSPIN_LOCK PiApcLock; @@ -45,9 +50,16 @@ VOID KeCallKernelRoutineApc(PKAPC Apc) DPRINT("Finished KeCallKernelRoutineApc()\n"); } +VOID KiRundownThread(VOID) +/* + * FUNCTION: + */ +{ +} + BOOLEAN KiTestAlert(VOID) /* - * FUNCTION: Tests whether there are any pending APCs for the curren thread + * FUNCTION: Tests whether there are any pending APCs for the current thread * and if so the APCs will be delivered on exit from kernel mode */ { @@ -73,61 +85,98 @@ BOOLEAN KiDeliverUserApc(PKTRAP_FRAME TrapFrame) * UserContext = The user context saved on entry to kernel mode */ { -#if 0 PLIST_ENTRY current_entry; PKAPC Apc; PULONG Esp; + PCONTEXT Context; KIRQL oldlvl; - CONTEXT SavedContext; - ULONG Top; - BOOL ret = FALSE; - PETHREAD EThread; PKTHREAD Thread; - DPRINT("KiDeliverUserApc(TrapFrame %x)\n", TrapFrame); + DPRINT("KiDeliverUserApc(TrapFrame %x/%x)\n", TrapFrame, + KeGetCurrentThread()->TrapFrame); Thread = KeGetCurrentThread(); - while(1) + KeAcquireSpinLock(&PiApcLock, &oldlvl); + current_entry = Thread->ApcState.ApcListHead[1].Flink; + + /* + * Shouldn't happen but check anyway. + */ + if (current_entry == &Thread->ApcState.ApcListHead[1]) { - KeAcquireSpinLock(&PiApcLock, &oldlvl); - current_entry = Thread->ApcState.ApcListHead[1].Flink; - - if (current_entry == &Thread->ApcState.ApcListHead[1]) - { - KeReleaseSpinLock(&PiApcLock, oldlvl); - break; - } - ret = TRUE; - current_entry = RemoveHeadList(&Thread->ApcState.ApcListHead[1]); - Apc = CONTAINING_RECORD(current_entry, KAPC, ApcListEntry); - - DPRINT("Esp %x\n", Esp); - DPRINT("Apc->NormalContext %x\n", Apc->NormalContext); - DPRINT("Apc->SystemArgument1 %x\n", Apc->SystemArgument1); - DPRINT("Apc->SystemArgument2 %x\n", Apc->SystemArgument2); - DPRINT("UserContext->Eip %x\n", UserContext->Eip); - - Esp = (PULONG)UserContext->Esp; - - memcpy(&SavedContext, UserContext, sizeof(CONTEXT)); - - Esp = Esp - (sizeof(CONTEXT) + (5 * sizeof(ULONG))); - memcpy(Esp, &SavedContext, sizeof(CONTEXT)); - Top = sizeof(CONTEXT) / 4; - Esp[Top] = (ULONG)Apc->NormalRoutine; - Esp[Top + 1] = (ULONG)Apc->NormalContext; - Esp[Top + 2] = (ULONG)Apc->SystemArgument1; - Esp[Top + 3] = (ULONG)Apc->SystemArgument2; - Esp[Top + 4] = (ULONG)Esp - sizeof(CONTEXT); - UserContext->Eip = 0; // KiUserApcDispatcher - - KeReleaseSpinLock(&PiApcLock, oldlvl); - - /* - * Now call for the kernel routine for the APC, which will free - * the APC data structure - */ - KeCallKernelRoutineApc(Apc); + KeReleaseSpinLock(&PiApcLock, oldlvl); + 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); + + /* + * 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]); + +#if 0 KeAcquireSpinLock(&PiThreadListLock, &oldlvl); EThread = CONTAINING_RECORD(Thread, ETHREAD, Tcb); if (EThread->DeadThread) @@ -147,6 +196,14 @@ BOOLEAN KiDeliverUserApc(PKTRAP_FRAME TrapFrame) VOID STDCALL KiDeliverApc(ULONG Unknown1, ULONG Unknown2, ULONG Unknown3) +/* + * FUNCTION: Deliver an APC to the current thread. + * NOTES: This is called from the IRQL switching code if the current thread + * is returning from an IRQL greater than or equal to APC_LEVEL to + * PASSIVE_LEVEL and there are kernel-mode APCs pending. This means any + * pending APCs will be delivered after a thread gets a new quantum and + * after it wakes from a wait. + */ { PETHREAD Thread = PsGetCurrentThread(); PLIST_ENTRY current; @@ -217,8 +274,6 @@ VOID STDCALL KeInsertQueueApc (PKAPC Apc, { InsertTailList(&TargetThread->ApcState.ApcListHead[1], &Apc->ApcListEntry); - TargetThread->ApcState.KernelApcPending++; - TargetThread->ApcState.UserApcPending++; } Apc->Inserted = TRUE; @@ -235,6 +290,7 @@ VOID STDCALL KeInsertQueueApc (PKAPC Apc, DPRINT("Resuming thread for user APC\n"); + TargetThread->ApcState.UserApcPending++; Status = STATUS_USER_APC; KeRemoveAllWaitsThread(CONTAINING_RECORD(TargetThread, ETHREAD, Tcb), STATUS_USER_APC); @@ -289,6 +345,19 @@ KeInitializeApc (PKAPC Apc, } } +VOID NtQueueApcRundownRoutine(PKAPC Apc) +{ + ExFreePool(Apc); +} + +VOID NtQueueApcKernelRoutine(PKAPC Apc, + PKNORMAL_ROUTINE* NormalRoutine, + PVOID* NormalContext, + PVOID* SystemArgument1, + PVOID* SystemArgument2) +{ + ExFreePool(Apc); +} NTSTATUS STDCALL NtQueueApcThread(HANDLE ThreadHandle, PKNORMAL_ROUTINE ApcRoutine, @@ -321,8 +390,8 @@ NTSTATUS STDCALL NtQueueApcThread(HANDLE ThreadHandle, KeInitializeApc(Apc, &Thread->Tcb, 0, - NULL, - NULL, + NtQueueApcKernelRoutine, + NtQueueApcRundownRoutine, ApcRoutine, UserMode, NormalContext); diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index 47c3654a9ee..d700a986c33 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -1,4 +1,4 @@ -/* $Id: trap.s,v 1.3 2000/10/07 13:41:52 dwelch Exp $ +/* $Id: trap.s,v 1.4 2000/10/11 20:50:34 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -170,7 +170,7 @@ new_serviceInRange: movl %ebp,%esp /* Call the post system call hook and deliver any pending APCs */ - pushl %esp + pushl %ebp pushl %eax call _KiAfterSystemCallHook addl $8,%esp @@ -251,9 +251,7 @@ new_done: popl %ebx movl %ebx, %fs:KPCR_EXCEPTION_LIST - popl %ebx - movl %ebx, %fs -/* popl %fs */ + popl %fs popl %edi popl %esi popl %ebx diff --git a/reactos/ntoskrnl/ke/i386/usercall.c b/reactos/ntoskrnl/ke/i386/usercall.c index f74178ce8e0..6cdaaf3d77a 100644 --- a/reactos/ntoskrnl/ke/i386/usercall.c +++ b/reactos/ntoskrnl/ke/i386/usercall.c @@ -1,4 +1,4 @@ -/* $Id: usercall.c,v 1.15 2000/10/07 13:41:52 dwelch Exp $ +/* $Id: usercall.c,v 1.16 2000/10/11 20:50:34 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -44,7 +44,8 @@ VOID KiSystemCallHook(ULONG Nr, ...) ULONG KiAfterSystemCallHook(ULONG NtStatus, PKTRAP_FRAME TrapFrame) { - if (KeGetCurrentThread()->ApcState.UserApcPending == 0) + if (KeGetCurrentThread()->ApcState.UserApcPending == 0 || + TrapFrame->Cs == KERNEL_CS) { return(NtStatus); } diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index 33a42424d52..ec09986892c 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -397,6 +397,7 @@ NTSTATUS STDCALL KeWaitForSingleObject (PVOID Object, if (Alertable && !IsListEmpty(&CurrentThread->ApcState.ApcListHead[1])) { DPRINT("Thread is alertable and user APCs are pending\n"); + KiTestAlert(); return(STATUS_USER_APC); } @@ -445,6 +446,10 @@ NTSTATUS STDCALL KeWaitForSingleObject (PVOID Object, { KeCancelTimer(&KeGetCurrentThread()->Timer); } + if (Status == STATUS_USER_APC) + { + KiTestAlert(); + } DPRINT("Returning from KeWaitForSingleObject()\n"); return Status; diff --git a/reactos/ntoskrnl/ldr/sysdll.c b/reactos/ntoskrnl/ldr/sysdll.c index bda0264843f..b29e8595e3c 100644 --- a/reactos/ntoskrnl/ldr/sysdll.c +++ b/reactos/ntoskrnl/ldr/sysdll.c @@ -246,13 +246,12 @@ NTSTATUS LdrpMapSystemDll(HANDLE ProcessHandle, /* * FIXME: retrieve the offset of the APC dispatcher from NTDLL */ -/* RtlInitAnsiString (&ProcedureName, "KiUserApcDispatcher"); Status = LdrGetProcedureAddress ((PVOID)ImageBase, &ProcedureName, 0, - (PULONG)&SystemDllApcDispatcher); + &SystemDllApcDispatcher); if (!NT_SUCCESS(Status)) { DbgPrint ("LdrGetProcedureAddress failed (Status %x)\n", Status); @@ -261,8 +260,6 @@ NTSTATUS LdrpMapSystemDll(HANDLE ProcessHandle, ZwClose(NTDllSectionHandle); return (Status); } -*/ - SystemDllApcDispatcher = NULL; KeDetachProcess(); ObDereferenceObject(Process); diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index 2a115c70ad4..124f326c3e2 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -1,4 +1,4 @@ -/* $Id: thread.c,v 1.57 2000/10/08 16:32:53 dwelch Exp $ +/* $Id: thread.c,v 1.58 2000/10/11 20:50:35 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -53,56 +53,6 @@ static PETHREAD CurrentThread = NULL; /* FUNCTIONS ***************************************************************/ -VOID PsFreezeProcessThreads(PEPROCESS Process) -{ - KIRQL oldIrql; - PLIST_ENTRY current_entry; - PETHREAD current; - - KeAcquireSpinLock(&PiThreadListLock, &oldIrql); - current_entry = PiThreadListHead.Flink; - - while (current_entry != &PiThreadListHead) - { - current = CONTAINING_RECORD(current_entry, ETHREAD, - Tcb.ThreadListEntry); - - current_entry = current_entry->Flink; - - if (current->ThreadsProcess == Process && - current != PsGetCurrentThread()) - { - PsFreezeOtherThread(current); - } - } - KeReleaseSpinLock(&PiThreadListLock, oldIrql); -} - -VOID PsUnfreezeProcessThreads(PEPROCESS Process) -{ - KIRQL oldIrql; - PLIST_ENTRY current_entry; - PETHREAD current; - - KeAcquireSpinLock(&PiThreadListLock, &oldIrql); - current_entry = PiThreadListHead.Flink; - - while (current_entry != &PiThreadListHead) - { - current = CONTAINING_RECORD(current_entry, ETHREAD, - Tcb.ThreadListEntry); - - current_entry = current_entry->Flink; - - if (current->ThreadsProcess == Process && - current != PsGetCurrentThread()) - { - PsUnfreezeOtherThread(current); - } - } - KeReleaseSpinLock(&PiThreadListLock, oldIrql); -} - PKTHREAD STDCALL KeGetCurrentThread(VOID) { return(&(CurrentThread->Tcb)); @@ -300,25 +250,6 @@ VOID PsUnfreezeOtherThread(PETHREAD Thread) } } -VOID PsFreezeOtherThread(PETHREAD Thread) -{ - ULONG r; - - Thread->Tcb.FreezeCount++; - r = Thread->Tcb.FreezeCount; - - if (r == 0) - { - return; - } - - if (Thread->Tcb.State == THREAD_STATE_RUNNABLE) - { - RemoveEntryList(&Thread->Tcb.QueueListEntry); - } - Thread->Tcb.State = THREAD_STATE_FROZEN; -} - ULONG PsFreezeThread(PETHREAD Thread, PNTSTATUS Status, UCHAR Alertable, @@ -346,13 +277,8 @@ ULONG PsFreezeThread(PETHREAD Thread, if (PsGetCurrentThread() != Thread) { - DPRINT("Suspending other\n"); - if (Thread->Tcb.State == THREAD_STATE_RUNNABLE) - { - RemoveEntryList(&Thread->Tcb.QueueListEntry); - } - Thread->Tcb.State = THREAD_STATE_FROZEN; - KeReleaseSpinLock(&PiThreadListLock, oldIrql); + DbgPrint("Suspending other\n"); + KeBugCheck(0); } else { @@ -495,14 +421,6 @@ NTSTATUS STDCALL NtAlertThread (IN HANDLE ThreadHandle) return(STATUS_SUCCESS); } - -NTSTATUS STDCALL NtGetContextThread (IN HANDLE ThreadHandle, - OUT PCONTEXT Context) -{ - UNIMPLEMENTED; -} - - NTSTATUS STDCALL NtOpenThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, @@ -511,6 +429,214 @@ NTSTATUS STDCALL NtOpenThread(OUT PHANDLE ThreadHandle, UNIMPLEMENTED; } +VOID KeContextToTrapFrame(PCONTEXT Context, + PKTRAP_FRAME TrapFrame) +{ + if (Context->ContextFlags & CONTEXT_CONTROL) + { + TrapFrame->Esp = Context->Esp; + TrapFrame->Ss = Context->SegSs; + TrapFrame->Cs = Context->SegCs; + TrapFrame->Eip = Context->Eip; + TrapFrame->Eflags = Context->EFlags; + TrapFrame->Ebp = Context->Ebp; + } + if (Context->ContextFlags & CONTEXT_INTEGER) + { + TrapFrame->Eax = Context->Eax; + TrapFrame->Ebx = Context->Ebx; + TrapFrame->Ecx = Context->Ecx; + /* + * Edx is used in the TrapFrame to hold the old trap frame pointer + * so we don't want to overwrite it here + */ +/* TrapFrame->Edx = Context->Edx; */ + TrapFrame->Esi = Context->Esi; + TrapFrame->Edx = Context->Edi; + } + if (Context->ContextFlags & CONTEXT_SEGMENTS) + { + TrapFrame->Ds = Context->SegDs; + TrapFrame->Es = Context->SegEs; + TrapFrame->Fs = Context->SegFs; + TrapFrame->Gs = Context->SegGs; + } + if (Context->ContextFlags & CONTEXT_FLOATING_POINT) + { + /* + * Not handled + */ + } + if (Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) + { + /* + * Not handled + */ + } +} + +VOID KeTrapFrameToContext(PKTRAP_FRAME TrapFrame, + PCONTEXT Context) +{ + if (Context->ContextFlags & CONTEXT_CONTROL) + { + Context->SegSs = TrapFrame->Ss; + Context->Esp = TrapFrame->Esp; + Context->SegCs = TrapFrame->Cs; + Context->Eip = TrapFrame->Eip; + Context->EFlags = TrapFrame->Eflags; + Context->Ebp = TrapFrame->Ebp; + } + if (Context->ContextFlags & CONTEXT_INTEGER) + { + Context->Eax = TrapFrame->Eax; + Context->Ebx = TrapFrame->Ebx; + Context->Ecx = TrapFrame->Ecx; + /* + * NOTE: In the trap frame which is built on entry to a system + * call TrapFrame->Edx will actually hold the address of the + * previous TrapFrame. I don't believe leaking this information + * has security implications + */ + Context->Edx = TrapFrame->Edx; + Context->Esi = TrapFrame->Esi; + Context->Edi = TrapFrame->Edi; + } + if (Context->ContextFlags & CONTEXT_SEGMENTS) + { + Context->SegDs = TrapFrame->Ds; + Context->SegEs = TrapFrame->Es; + Context->SegFs = TrapFrame->Fs; + Context->SegGs = TrapFrame->Gs; + } + if (Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) + { + /* + * FIXME: Implement this case + */ + } + if (Context->ContextFlags & CONTEXT_FLOATING_POINT) + { + /* + * FIXME: Implement this case + */ + } +#if 0 + if (Context->ContextFlags & CONTEXT_EXTENDED_REGISTERS) + { + /* + * FIXME: Investigate this + */ + } +#endif +} + +VOID KeGetContextRundownRoutine(PKAPC Apc) +{ + PKEVENT Event; + PNTSTATUS Status; + + Event = (PKEVENT)Apc->SystemArgument1; + Status = (PNTSTATUS)Apc->SystemArgument2; + (*Status) = STATUS_THREAD_IS_TERMINATING; + KeSetEvent(Event, IO_NO_INCREMENT, FALSE); +} + +VOID KeGetContextKernelRoutine(PKAPC Apc, + PKNORMAL_ROUTINE* NormalRoutine, + PVOID* NormalContext, + PVOID* SystemArgument1, + PVOID* SystemArgument2) +{ + PKEVENT Event; + PCONTEXT Context; + PNTSTATUS Status; + + Context = (PCONTEXT)(*NormalContext); + Event = (PKEVENT)(*SystemArgument1); + Status = (PNTSTATUS)(*SystemArgument2); + + KeTrapFrameToContext(KeGetCurrentThread()->TrapFrame, Context); + + *Status = STATUS_SUCCESS; + KeSetEvent(Event, IO_NO_INCREMENT, FALSE); +} + +NTSTATUS STDCALL NtGetContextThread (IN HANDLE ThreadHandle, + OUT PCONTEXT Context) +{ + PETHREAD Thread; + NTSTATUS Status; + + Status = ObReferenceObjectByHandle(ThreadHandle, + THREAD_GET_CONTEXT, + PsThreadType, + UserMode, + (PVOID*)&Thread, + NULL); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + if (Thread == PsGetCurrentThread()) + { + /* + * I don't know if trying to get your own context makes much + * sense but we can handle it more efficently. + */ + + KeTrapFrameToContext(Thread->Tcb.TrapFrame, Context); + ObDereferenceObject(Thread); + return(STATUS_SUCCESS); + } + else + { + KAPC Apc; + KEVENT Event; + NTSTATUS AStatus; + CONTEXT KContext; + + KContext.ContextFlags = Context->ContextFlags; + KeInitializeEvent(&Event, + NotificationEvent, + FALSE); + AStatus = STATUS_SUCCESS; + + KeInitializeApc(&Apc, + &Thread->Tcb, + 0, + KeGetContextKernelRoutine, + KeGetContextRundownRoutine, + NULL, + KernelMode, + (PVOID)&KContext); + KeInsertQueueApc(&Apc, + (PVOID)&Event, + (PVOID)&AStatus, + 0); + Status = KeWaitForSingleObject(&Event, + 0, + UserMode, + FALSE, + NULL); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + if (!NT_SUCCESS(AStatus)) + { + return(AStatus); + } + memcpy(Context, &KContext, sizeof(CONTEXT)); + return(STATUS_SUCCESS); + } +} + +NTSTATUS STDCALL NtSetContextThread (IN HANDLE ThreadHandle, + IN PCONTEXT Context) +{ + UNIMPLEMENTED; +} NTSTATUS STDCALL NtResumeThread (IN HANDLE ThreadHandle, IN PULONG SuspendCount) @@ -530,13 +656,6 @@ NTSTATUS STDCALL NtResumeThread (IN HANDLE ThreadHandle, } -NTSTATUS STDCALL NtSetContextThread (IN HANDLE ThreadHandle, - IN PCONTEXT Context) -{ - UNIMPLEMENTED; -} - - NTSTATUS STDCALL NtSuspendThread (IN HANDLE ThreadHandle, IN PULONG PreviousSuspendCount) /* @@ -561,12 +680,15 @@ NTSTATUS STDCALL NtSuspendThread (IN HANDLE ThreadHandle, NTSTATUS STDCALL NtContinue(IN PCONTEXT Context, IN BOOLEAN TestAlert) { - PULONG StackTop; - - StackTop = KeGetStackTopThread(PsGetCurrentThread()); - - memcpy(StackTop, Context, sizeof(CONTEXT)); + PKTRAP_FRAME TrapFrame; + TrapFrame = KeGetCurrentThread()->TrapFrame; + if (TrapFrame == NULL) + { + DbgPrint("NtContinue called but TrapFrame was NULL\n"); + KeBugCheck(0); + } + KeContextToTrapFrame(Context, TrapFrame); return(STATUS_SUCCESS); }