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 temp.exp
vfatfs.coff vfatfs.coff
vfatfs.sys.unstripped vfatfs.sys.unstripped
*.d

View file

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

View file

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

View file

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

View file

@ -207,6 +207,11 @@ VOID
Ki386InitializeLdt(VOID); Ki386InitializeLdt(VOID);
ULONG ULONG
KiUserTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2); 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__ */ #endif /* not __ASM__ */

View file

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

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * FILE: ntoskrnl/ke/kthread.c
* PURPOSE: Process manager definitions * PURPOSE: Process manager definitions
@ -36,6 +36,7 @@
#define KTHREAD_KERNEL_STACK 0x28 #define KTHREAD_KERNEL_STACK 0x28
#define KTHREAD_PREVIOUS_MODE 0x137 #define KTHREAD_PREVIOUS_MODE 0x137
#define KTHREAD_TRAP_FRAME 0x128 #define KTHREAD_TRAP_FRAME 0x128
#define KTHREAD_CALLBACK_STACK 0x120
#define ETHREAD_THREADS_PROCESS 0x258 #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 * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * FILE: ntoskrnl/hal/x86/syscall.s
* PURPOSE: 2E trap handler * PURPOSE: 2E trap handler
@ -33,6 +33,7 @@
/* /*
* *
*/ */
.globl KeReturnFromSystemCall
.globl _interrupt_handler2e .globl _interrupt_handler2e
_interrupt_handler2e: _interrupt_handler2e:
@ -124,7 +125,7 @@ L3:
cmpl %es:_KeServiceDescriptorTable + 8, %eax cmpl %es:_KeServiceDescriptorTable + 8, %eax
jbe new_serviceInRange jbe new_serviceInRange
movl $STATUS_INVALID_SYSTEM_SERVICE, %eax movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
jmp new_done jmp KeReturnFromSystemCall
new_serviceInRange: new_serviceInRange:
@ -163,7 +164,7 @@ new_serviceInRange:
call _KiAfterSystemCallHook call _KiAfterSystemCallHook
addl $8,%esp addl $8,%esp
jmp new_done jmp KeReturnFromSystemCall
new_useShadowTable: new_useShadowTable:
@ -173,7 +174,7 @@ new_useShadowTable:
cmpl %es:_KeServiceDescriptorTableShadow + 24, %eax cmpl %es:_KeServiceDescriptorTableShadow + 24, %eax
jbe new_shadowServiceInRange jbe new_shadowServiceInRange
movl $STATUS_INVALID_SYSTEM_SERVICE, %eax movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
jmp new_done jmp KeReturnFromSystemCall
new_shadowServiceInRange: new_shadowServiceInRange:
@ -212,7 +213,7 @@ new_shadowServiceInRange:
call _KiAfterSystemCallHook call _KiAfterSystemCallHook
addl $8,%esp addl $8,%esp
new_done: KeReturnFromSystemCall:
/* Restore the user context */ /* Restore the user context */
/* Get a pointer to the current thread */ /* Get a pointer to the current thread */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/main.c * FILE: ntoskrnl/ke/main.c
@ -922,6 +922,7 @@ ExpInitializeExecutive(VOID)
assert(FIELD_OFFSET(KTHREAD, KernelStack) == KTHREAD_KERNEL_STACK); assert(FIELD_OFFSET(KTHREAD, KernelStack) == KTHREAD_KERNEL_STACK);
assert(FIELD_OFFSET(KTHREAD, PreviousMode) == KTHREAD_PREVIOUS_MODE); assert(FIELD_OFFSET(KTHREAD, PreviousMode) == KTHREAD_PREVIOUS_MODE);
assert(FIELD_OFFSET(KTHREAD, TrapFrame) == KTHREAD_TRAP_FRAME); 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(ETHREAD, ThreadsProcess) == ETHREAD_THREADS_PROCESS);
assert(FIELD_OFFSET(KPROCESS, DirectoryTableBase) == assert(FIELD_OFFSET(KPROCESS, DirectoryTableBase) ==
KPROCESS_DIRECTORY_TABLE_BASE); 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -26,6 +26,8 @@
#include <internal/ps.h> #include <internal/ps.h>
#include <internal/ob.h> #include <internal/ob.h>
#include <internal/pool.h> #include <internal/pool.h>
#include <ntos/minmax.h>
#include <internal/ldr.h>
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
@ -498,9 +500,92 @@ NtCallbackReturn (PVOID Result,
ULONG ResultLength, ULONG ResultLength,
NTSTATUS Status) 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 NTSTATUS STDCALL
NtW32Call (IN ULONG RoutineIndex, NtW32Call (IN ULONG RoutineIndex,
@ -509,7 +594,59 @@ NtW32Call (IN ULONG RoutineIndex,
OUT PVOID* Result OPTIONAL, OUT PVOID* Result OPTIONAL,
OUT PULONG ResultLength 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 NTSTATUS STDCALL

View file

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