Implemented NtW32Call and NtCallbackReturn

Updated some .cvsignore files

svn path=/trunk/; revision=2515
This commit is contained in:
David Welch 2002-01-15 02:51:32 +00:00
parent e136b71248
commit 793bbe0455
15 changed files with 255 additions and 14 deletions

View file

@ -0,0 +1 @@
ping.coff

View file

@ -0,0 +1 @@
roshttpd.coff

View file

@ -3,3 +3,4 @@ junk.tmp
temp.exp
vfatfs.coff
vfatfs.sys.unstripped
*.d

View file

@ -1,2 +1,3 @@
oleaut32.coff
oleaut32.dll
oleaut32.nostrip.dll

View file

@ -1,2 +1,3 @@
shell32.coff
shell32.dll
shell32.nostrip.dll

View file

@ -31,7 +31,8 @@ OBJECTS_KE_I386 := \
ke/i386/kernel.o \
ke/i386/fpu.o \
ke/i386/tss.o \
ke/i386/usertrap.o
ke/i386/usertrap.o \
ke/i386/stkswitch.o
OBJECTS_MM_I386 := \
mm/i386/memsafe.o \

View file

@ -207,6 +207,11 @@ VOID
Ki386InitializeLdt(VOID);
ULONG
KiUserTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2);
VOID STDCALL
KePushAndStackSwitchAndSysRet(ULONG A, ULONG B, ULONG C, ULONG D, ULONG E,
ULONG F, PVOID NewStack);
VOID STDCALL
KeStackSwitchAndRet(PVOID NewStack);
#endif /* not __ASM__ */

View file

@ -48,6 +48,8 @@ PVOID
LdrpGetSystemDllApcDispatcher(VOID);
PVOID
LdrpGetSystemDllExceptionDispatcher(VOID);
PVOID
LdrpGetSystemDllCallbackDispatcher(VOID);
NTSTATUS
LdrpMapImage (
HANDLE ProcessHandle,

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: ps.h,v 1.27 2001/11/24 14:08:54 jfilby Exp $
/* $Id: ps.h,v 1.28 2002/01/15 02:51:32 dwelch Exp $
*
* FILE: ntoskrnl/ke/kthread.c
* PURPOSE: Process manager definitions
@ -36,6 +36,7 @@
#define KTHREAD_KERNEL_STACK 0x28
#define KTHREAD_PREVIOUS_MODE 0x137
#define KTHREAD_TRAP_FRAME 0x128
#define KTHREAD_CALLBACK_STACK 0x120
#define ETHREAD_THREADS_PROCESS 0x258

View file

@ -0,0 +1,81 @@
/*
* ReactOS kernel
* Copyright (C) 2000 David Welch <welch@cwcom.net>
*
* 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.
*/
/*
* FILE: ntoskrnl/ke/i386/tskswitch.S
* PURPOSE: Microkernel thread support
* PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
* Created 09/10/00
*/
/* INCLUDES ******************************************************************/
#include <internal/i386/segment.h>
#include <internal/ps.h>
#include <ddk/i386/tss.h>
/* FUNCTIONS ****************************************************************/
.globl _KeStackSwitchAndRet@4
_KeStackSwitchAndRet@4:
pushl %ebp
movl %esp, %ebp
cli
movl 8(%ebp), %esp
sti
popl %edi
popl %esi
popl %ebx
popl %ebp
ret $28
.globl _KePushAndStackSwitchAndSysRet@28
_KePushAndStackSwitchAndSysRet@28:
pushl %ebp
movl %esp, %ebp
pushl %ebx
pushl %esi
pushl %edi
cli
pushl 8(%ebp)
pushl 12(%ebp)
pushl 16(%ebp)
pushl 20(%ebp)
pushl 24(%ebp)
pushl 28(%ebp)
movl %ebx, %fs:KPCR_CURRENT_THREAD
movl %esp, KTHREAD_CALLBACK_STACK(%ebx)
movl 32(%ebp), %esp
sti
push $0
call _KeLowerIrql@4
jmp KeReturnFromSystemCall

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: syscall.S,v 1.3 2001/09/24 00:51:17 chorns Exp $
/* $Id: syscall.S,v 1.4 2002/01/15 02:51:32 dwelch Exp $
*
* FILE: ntoskrnl/hal/x86/syscall.s
* PURPOSE: 2E trap handler
@ -33,6 +33,7 @@
/*
*
*/
.globl KeReturnFromSystemCall
.globl _interrupt_handler2e
_interrupt_handler2e:
@ -124,7 +125,7 @@ L3:
cmpl %es:_KeServiceDescriptorTable + 8, %eax
jbe new_serviceInRange
movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
jmp new_done
jmp KeReturnFromSystemCall
new_serviceInRange:
@ -163,7 +164,7 @@ new_serviceInRange:
call _KiAfterSystemCallHook
addl $8,%esp
jmp new_done
jmp KeReturnFromSystemCall
new_useShadowTable:
@ -173,7 +174,7 @@ new_useShadowTable:
cmpl %es:_KeServiceDescriptorTableShadow + 24, %eax
jbe new_shadowServiceInRange
movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
jmp new_done
jmp KeReturnFromSystemCall
new_shadowServiceInRange:
@ -212,7 +213,7 @@ new_shadowServiceInRange:
call _KiAfterSystemCallHook
addl $8,%esp
new_done:
KeReturnFromSystemCall:
/* Restore the user context */
/* Get a pointer to the current thread */

View file

@ -80,7 +80,7 @@ _Ki386ContextSwitch:
/*
* Set the current thread information in the PCR.
*/
movl %ebx, %fs:KPCR_CURRENT_THREAD
movl %ebx, %fs:KPCR_CURRENT_THREAD
/*
* FIXME: Save debugging state.

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.110 2001/12/27 23:56:42 dwelch Exp $
/* $Id: main.c,v 1.111 2002/01/15 02:51:32 dwelch Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/main.c
@ -922,6 +922,7 @@ ExpInitializeExecutive(VOID)
assert(FIELD_OFFSET(KTHREAD, KernelStack) == KTHREAD_KERNEL_STACK);
assert(FIELD_OFFSET(KTHREAD, PreviousMode) == KTHREAD_PREVIOUS_MODE);
assert(FIELD_OFFSET(KTHREAD, TrapFrame) == KTHREAD_TRAP_FRAME);
assert(FIELD_OFFSET(KTHREAD, CallbackStack) == KTHREAD_CALLBACK_STACK);
assert(FIELD_OFFSET(ETHREAD, ThreadsProcess) == ETHREAD_THREADS_PROCESS);
assert(FIELD_OFFSET(KPROCESS, DirectoryTableBase) ==
KPROCESS_DIRECTORY_TABLE_BASE);

View file

@ -1,4 +1,4 @@
/* $Id: thread.c,v 1.86 2002/01/15 01:42:57 phreak Exp $
/* $Id: thread.c,v 1.87 2002/01/15 02:51:32 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -26,6 +26,8 @@
#include <internal/ps.h>
#include <internal/ob.h>
#include <internal/pool.h>
#include <ntos/minmax.h>
#include <internal/ldr.h>
#define NDEBUG
#include <internal/debug.h>
@ -498,9 +500,92 @@ NtCallbackReturn (PVOID Result,
ULONG ResultLength,
NTSTATUS Status)
{
UNIMPLEMENTED;
PULONG OldStack;
PETHREAD Thread;
PNTSTATUS CallbackStatus;
PULONG CallerResultLength;
PVOID* CallerResult;
PVOID InitialStack;
PVOID StackBase;
ULONG StackLimit;
KIRQL oldIrql;
Thread = PsGetCurrentThread();
OldStack = (PULONG)Thread->Tcb.CallbackStack;
Thread->Tcb.CallbackStack = NULL;
CallbackStatus = (PNTSTATUS)OldStack[0];
CallerResultLength = (PULONG)OldStack[1];
CallerResult = (PVOID*)OldStack[2];
InitialStack = (PVOID)OldStack[3];
StackBase = (PVOID)OldStack[4];
StackLimit = OldStack[5];
*CallbackStatus = Status;
if (CallerResult != NULL && CallerResultLength != NULL)
{
if (Result == NULL)
{
*CallerResultLength = 0;
}
else
{
*CallerResultLength = min(ResultLength, *CallerResultLength);
memcpy(*CallerResult, Result, *CallerResultLength);
}
}
KeRaiseIrql(HIGH_LEVEL, &oldIrql);
Thread->Tcb.InitialStack = InitialStack;
Thread->Tcb.StackBase = StackBase;
Thread->Tcb.StackLimit = StackLimit;
KeStackSwitchAndRet((PVOID)(OldStack + 6));
/* Should never return. */
KeBugCheck(0);
return(STATUS_UNSUCCESSFUL);
}
PVOID STATIC
PsAllocateCallbackStack(ULONG StackSize)
{
PVOID KernelStack;
NTSTATUS Status;
PMEMORY_AREA StackArea;
ULONG i;
StackSize = PAGE_ROUND_UP(StackSize);
MmLockAddressSpace(MmGetKernelAddressSpace());
Status = MmCreateMemoryArea(NULL,
MmGetKernelAddressSpace(),
MEMORY_AREA_KERNEL_STACK,
&KernelStack,
StackSize,
0,
&StackArea,
FALSE);
MmUnlockAddressSpace(MmGetKernelAddressSpace());
if (!NT_SUCCESS(Status))
{
DPRINT("Failed to create thread stack\n");
return(NULL);
}
for (i = 0; i < (StackSize / PAGESIZE); i++)
{
PVOID Page;
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page);
if (!NT_SUCCESS(Status))
{
return(NULL);
}
Status = MmCreateVirtualMapping(NULL,
KernelStack + (i * PAGESIZE),
PAGE_EXECUTE_READWRITE,
(ULONG)Page,
TRUE);
}
return(KernelStack);
}
NTSTATUS STDCALL
NtW32Call (IN ULONG RoutineIndex,
@ -509,8 +594,60 @@ NtW32Call (IN ULONG RoutineIndex,
OUT PVOID* Result OPTIONAL,
OUT PULONG ResultLength OPTIONAL)
{
UNIMPLEMENTED;
}
PETHREAD Thread;
PVOID NewStack;
ULONG StackSize;
PKTRAP_FRAME NewFrame;
PULONG UserEsp;
KIRQL oldIrql;
ULONG SavedStackLimit;
PVOID SavedStackBase;
PVOID SavedInitialStack;
NTSTATUS CallbackStatus;
Thread = PsGetCurrentThread();
if (Thread->Tcb.CallbackStack != NULL)
{
return(STATUS_UNSUCCESSFUL);
}
/* Set up the new kernel and user environment. */
StackSize = (ULONG)(Thread->Tcb.StackBase - Thread->Tcb.StackLimit);
NewStack = PsAllocateCallbackStack(StackSize);
memcpy(NewStack + StackSize - sizeof(KTRAP_FRAME), Thread->Tcb.TrapFrame,
sizeof(KTRAP_FRAME));
NewFrame = (PKTRAP_FRAME)(NewStack + StackSize - sizeof(KTRAP_FRAME));
NewFrame->Esp -= (ArgumentLength + (4 * sizeof(ULONG)));
NewFrame->Eip = (ULONG)LdrpGetSystemDllCallbackDispatcher();
UserEsp = (PULONG)NewFrame->Esp;
UserEsp[0] = 0; /* Return address. */
UserEsp[1] = RoutineIndex;
UserEsp[2] = (ULONG)&UserEsp[4];
UserEsp[3] = ArgumentLength;
memcpy((PVOID)&UserEsp[4], Argument, ArgumentLength);
/* Switch to the new environment and return to user-mode. */
KeRaiseIrql(HIGH_LEVEL, &oldIrql);
SavedStackLimit = Thread->Tcb.StackLimit;
SavedStackBase = Thread->Tcb.StackBase;
SavedInitialStack = Thread->Tcb.InitialStack;
Thread->Tcb.InitialStack = Thread->Tcb.StackBase = NewStack + StackSize;
Thread->Tcb.StackLimit = (ULONG)NewStack;
Thread->Tcb.KernelStack = NewStack + StackSize - sizeof(KTRAP_FRAME);
KePushAndStackSwitchAndSysRet(SavedStackLimit,
(ULONG)SavedStackBase,
(ULONG)SavedInitialStack, (ULONG)Result,
(ULONG)ResultLength, (ULONG)&CallbackStatus,
Thread->Tcb.KernelStack);
/*
* The callback return will have already restored most of the state we
* modified.
*/
KeLowerIrql(PASSIVE_LEVEL);
ExFreePool(NewStack);
return(CallbackStatus);
}
NTSTATUS STDCALL
NtContinue(IN PCONTEXT Context,

View file

@ -1 +1,8 @@
*.exe
*.exe
buildno
depends
rcopy
rmkdir
rrmdir
mkconfig
rdel