From 07a0973e216781eeee4000b23173287808da173f Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Wed, 13 Sep 2006 01:00:50 +0000 Subject: [PATCH] - Remove usercall.c from portable part of Ke and add it to ke\i386. The implementation is slightly arch-specific. - Remove code in userapc.c and move it into usercall.c, since both functions basically deal with user-mode callouts. - Handle STATUS_CALLBACK_POP_STACK and add the status to ntstatus.h - Also handle future support for GDI Batch flushing. svn path=/trunk/; revision=24089 --- reactos/include/ddk/ntstatus.h | 1 + reactos/include/psdk/ntstatus.h | 1 + reactos/ntoskrnl/include/internal/ke.h | 13 + .../ke/i386/{userapc.c => usercall.c} | 100 ++- reactos/ntoskrnl/ntoskrnl.rbuild | 687 +++++++++--------- 5 files changed, 453 insertions(+), 349 deletions(-) rename reactos/ntoskrnl/ke/i386/{userapc.c => usercall.c} (57%) diff --git a/reactos/include/ddk/ntstatus.h b/reactos/include/ddk/ntstatus.h index 61b04fbd858..5e5452a7eac 100644 --- a/reactos/include/ddk/ntstatus.h +++ b/reactos/include/ddk/ntstatus.h @@ -877,6 +877,7 @@ extern "C" { #define STATUS_PKINIT_CLIENT_FAILURE ((NTSTATUS)0xC000038CL) #define STATUS_SMARTCARD_CERT_EXPIRED ((NTSTATUS)0xC000038DL) #define STATUS_DRIVER_FAILED_PRIOR_UNLOAD ((NTSTATUS)0xC000038EL) +#define STATUS_CALLBACK_POP_STACK ((NTSTATUS)0xC0000423L) #define STATUS_WOW_ASSERTION ((NTSTATUS)0xC0009898L) #define RPC_NT_INVALID_STRING_BINDING ((NTSTATUS)0xC0020001L) #define RPC_NT_WRONG_KIND_OF_BINDING ((NTSTATUS)0xC0020002L) diff --git a/reactos/include/psdk/ntstatus.h b/reactos/include/psdk/ntstatus.h index d36f97c007e..97b93a6a010 100644 --- a/reactos/include/psdk/ntstatus.h +++ b/reactos/include/psdk/ntstatus.h @@ -921,6 +921,7 @@ #define STATUS_AUTHENTICATION_FIREWALL_FAILED ((NTSTATUS)0xC0000413) #define STATUS_VDM_DISALLOWED ((NTSTATUS)0xC0000414) #define STATUS_HUNG_DISPLAY_DRIVER_THREAD ((NTSTATUS)0xC0000415) +#define STATUS_CALLBACK_POP_STACK ((NTSTATUS)0xC0000423) #define STATUS_WOW_ASSERTION ((NTSTATUS)0xC0009898) #define RPC_NT_INVALID_STRING_BINDING ((NTSTATUS)0xC0020001) diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index eb14eca4f74..bd67ce1fd4e 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -823,6 +823,19 @@ KiInsertQueueApc( IN KPRIORITY PriorityBoost ); +NTSTATUS +NTAPI +KiCallUserMode( + IN PVOID *OutputBuffer, + IN PULONG OutputLength +); + +PULONG +NTAPI +KiGetUserModeStackAddress( + VOID +); + #include "ke_x.h" #endif /* __NTOSKRNL_INCLUDE_INTERNAL_KE_H */ diff --git a/reactos/ntoskrnl/ke/i386/userapc.c b/reactos/ntoskrnl/ke/i386/usercall.c similarity index 57% rename from reactos/ntoskrnl/ke/i386/userapc.c rename to reactos/ntoskrnl/ke/i386/usercall.c index 13fcf7f0625..722c8e6c487 100644 --- a/reactos/ntoskrnl/ke/i386/userapc.c +++ b/reactos/ntoskrnl/ke/i386/usercall.c @@ -1,16 +1,16 @@ /* * PROJECT: ReactOS Kernel * LICENSE: GPL - See COPYING in the top level directory - * FILE: ntoskrnl/ke/i386/userapc.c - * PURPOSE: Implements User-Mode APC Initialization + * FILE: ntoskrnl/ke/i386/usercall.c + * PURPOSE: User-mode Callout Mechanisms (APC and Win32K Callbacks) * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */ -/* INCLUDES *****************************************************************/ +/* INCLUDES ******************************************************************/ #include #define NDEBUG -#include +#include /* PRIVATE FUNCTIONS *********************************************************/ @@ -56,7 +56,7 @@ _SEH_FILTER(KiCopyInformation2) * *--*/ VOID -STDCALL +NTAPI KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN PKNORMAL_ROUTINE NormalRoutine, @@ -134,3 +134,93 @@ KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame, _SEH_END; } +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @implemented + */ +NTSTATUS +NTAPI +KeUserModeCallback(IN ULONG RoutineIndex, + IN PVOID Argument, + IN ULONG ArgumentLength, + OUT PVOID *Result, + OUT PULONG ResultLength) +{ + ULONG_PTR NewStack, OldStack; + PULONG UserEsp; + NTSTATUS CallbackStatus = STATUS_SUCCESS; + PEXCEPTION_REGISTRATION_RECORD ExceptionList; + PTEB Teb; + ULONG GdiBatchCount = 0; + ASSERT(KeGetCurrentThread()->ApcState.KernelApcInProgress == FALSE); + ASSERT(KeGetPreviousMode() == UserMode); + + /* Get the current user-mode stack */ + UserEsp = KiGetUserModeStackAddress(); + OldStack = *UserEsp; + + /* Enter a SEH Block */ + _SEH_TRY + { + /* Calculate and align the stack size */ + NewStack = (OldStack - ArgumentLength) & ~3; + + /* Make sure it's writable */ + ProbeForWrite((PVOID)(NewStack - 6 * sizeof(ULONG_PTR)), + ArgumentLength + 6 * sizeof(ULONG_PTR), + sizeof(CHAR)); + + /* Copy the buffer into the stack */ + RtlCopyMemory((PVOID)NewStack, Argument, ArgumentLength); + + /* Write the arguments */ + NewStack -= 24; + *(PULONG)NewStack = 0; + *(PULONG)(NewStack + 4) = RoutineIndex; + *(PULONG)(NewStack + 8) = (NewStack + 24); + *(PULONG)(NewStack + 12) = ArgumentLength; + + /* Save the exception list */ + Teb = KeGetCurrentThread()->Teb; + ExceptionList = Teb->Tib.ExceptionList; + + /* Jump to user mode */ + *UserEsp = NewStack; + CallbackStatus = KiCallUserMode(Result, ResultLength); + if (CallbackStatus != STATUS_CALLBACK_POP_STACK) + { + /* Only restore the exception list if we didn't crash in ring 3 */ + Teb->Tib.ExceptionList = ExceptionList; + CallbackStatus = STATUS_SUCCESS; + } + else + { + /* Otherwise, pop the stack */ + OldStack = *UserEsp; + } + + /* Read the GDI Batch count */ + GdiBatchCount = Teb->GdiBatchCount; + } + _SEH_HANDLE + { + /* Get the SEH exception */ + CallbackStatus = _SEH_GetExceptionCode(); + } + _SEH_END; + if (!NT_SUCCESS(CallbackStatus)) return CallbackStatus; + + /* Check if we have GDI Batch operations */ + if (GdiBatchCount) + { + /* Shouldn't happen in ROS yet */ + ASSERT(FALSE); + } + + /* Restore stack and return */ + *UserEsp = OldStack; + return CallbackStatus; +} + +/* EOF */ diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 141fab2e3cc..670bb1dd7e6 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -1,346 +1,345 @@ - - - - - - - - - - - include - . - include - include/reactos/drivers - csq - hal - kjs - pseh - cmlib - rtl - rossym - string - wdmguid - - ntoskrnl.h - - - - - boot.S - abios.c - cpu.c - ctxswitch.S - clock.S - exp.c - - kiinit.c - ldt.c - thread.c - trap.s - usercall_asm.S - userapc.c - v86vdm.c - v86m_sup.S - - - apc.c - bug.c - clock.c - device.c - dpc.c - event.c - exception.c - freeldr.c - gate.c - gmutex.c - ipi.c - kqueue.c - krnlinit.c - mutex.c - process.c - profile.c - queue.c - sem.c - spinlock.c - thrdschd.c - thrdobj.c - timer.c - usercall.c - wait.c - - - irqhand.S - irq.c - - - cacheman.c - copy.c - fs.c - mdl.c - pin.c - view.c - - - import.c - ntfunc.c - regfile.c - registry.c - regobj.c - - - - - - - i386-dis.c - kdb_help.S - longjmp.S - setjmp.S - - - - - - kdb.c - kdb_cli.c - kdb_expr.c - kdb_keyboard.c - kdb_serial.c - kdb_string.c - - - kdb_symbols.c - - - - dbgkutil.c - debug.c - - - - - interlck_asm.S - fastinterlck_asm.S - - - atom.c - callback.c - dbgctrl.c - error.c - efi.c - event.c - evtpair.c - fmutex.c - handle.c - init.c - locale.c - lookas.c - mutant.c - power.c - pushlock.c - profile.c - resource.c - rundown.c - sem.c - sysinfo.c - time.c - timer.c - uuid.c - win32k.c - work.c - zone.c - zw.S - - - context.c - fastio.c - filelock.c - mcb.c - name.c - notify.c - oplock.c - pool.c - tunnel.c - unc.c - util.c - - - inbv.c - - - - adapter.c - arcname.c - bootlog.c - controller.c - device.c - deviface.c - disk.c - driver.c - drvrlist.c - error.c - event.c - file.c - iocomp.c - iofunc.c - iomgr.c - iowork.c - irp.c - irq.c - mdl.c - rawfs.c - remlock.c - resource.c - util.c - symlink.c - timer.c - volume.c - - - plugplay.c - pnpdma.c - pnpmgr.c - pnpnotify.c - pnpreport.c - pnproot.c - - - - - bochs.c - gdbstub.c - - kdinit.c - kdio.c - kdmain.c - - - loader.c - rtl.c - - - close.c - complete.c - connect.c - create.c - listen.c - port.c - query.c - queue.c - receive.c - reply.c - send.c - - - - - memsafe.s - page.c - pfault.c - - - anonmem.c - aspace.c - balance.c - cont.c - drvlck.c - freelist.c - iospace.c - kmap.c - marea.c - mdl.c - mm.c - process.c - mminit.c - mpw.c - ncache.c - npool.c - pagefile.c - pageop.c - pager.c - pagfault.c - paging.c - pe.c - physical.c - pool.c - ppool.c - region.c - rmap.c - section.c - verifier.c - virtual.c - wset.c - elf32.c - elf64.c - - - obdir.c - obinit.c - obhandle.c - obname.c - oblife.c - obref.c - sdcache.c - obsecure.c - symlink.c - obwait.c - - - power.c - events.c - - - debug.c - job.c - kill.c - notify.c - process.c - psmgr.c - query.c - quota.c - security.c - state.c - thread.c - win32.c - - - - - exception.c - seh.s - - - libsupp.c - misc.c - nls.c - regio.c - strtok.c - - - access.c - acl.c - audit.c - lsa.c - luid.c - priv.c - sd.c - semgr.c - sid.c - token.c - - - - vdmmain.c - vdmexec.c - - - - wmi.c - - ntoskrnl.rc - -nostartfiles - -nostdlib - -lgcc + + + + + + + + + + + include + . + include + include/reactos/drivers + csq + hal + kjs + pseh + cmlib + rtl + rossym + string + wdmguid + + ntoskrnl.h + + + + + boot.S + abios.c + cpu.c + ctxswitch.S + clock.S + exp.c + + kiinit.c + ldt.c + thread.c + trap.s + usercall_asm.S + usercall.c + v86vdm.c + v86m_sup.S + + + apc.c + bug.c + clock.c + device.c + dpc.c + event.c + exception.c + freeldr.c + gate.c + gmutex.c + ipi.c + kqueue.c + krnlinit.c + mutex.c + process.c + profile.c + queue.c + sem.c + spinlock.c + thrdschd.c + thrdobj.c + timer.c + wait.c + + + irqhand.S + irq.c + + + cacheman.c + copy.c + fs.c + mdl.c + pin.c + view.c + + + import.c + ntfunc.c + regfile.c + registry.c + regobj.c + + + + + + + i386-dis.c + kdb_help.S + longjmp.S + setjmp.S + + + + + + kdb.c + kdb_cli.c + kdb_expr.c + kdb_keyboard.c + kdb_serial.c + kdb_string.c + + + kdb_symbols.c + + + + dbgkutil.c + debug.c + + + + + interlck_asm.S + fastinterlck_asm.S + + + atom.c + callback.c + dbgctrl.c + error.c + efi.c + event.c + evtpair.c + fmutex.c + handle.c + init.c + locale.c + lookas.c + mutant.c + power.c + pushlock.c + profile.c + resource.c + rundown.c + sem.c + sysinfo.c + time.c + timer.c + uuid.c + win32k.c + work.c + zone.c + zw.S + + + context.c + fastio.c + filelock.c + mcb.c + name.c + notify.c + oplock.c + pool.c + tunnel.c + unc.c + util.c + + + inbv.c + + + + adapter.c + arcname.c + bootlog.c + controller.c + device.c + deviface.c + disk.c + driver.c + drvrlist.c + error.c + event.c + file.c + iocomp.c + iofunc.c + iomgr.c + iowork.c + irp.c + irq.c + mdl.c + rawfs.c + remlock.c + resource.c + util.c + symlink.c + timer.c + volume.c + + + plugplay.c + pnpdma.c + pnpmgr.c + pnpnotify.c + pnpreport.c + pnproot.c + + + + + bochs.c + gdbstub.c + + kdinit.c + kdio.c + kdmain.c + + + loader.c + rtl.c + + + close.c + complete.c + connect.c + create.c + listen.c + port.c + query.c + queue.c + receive.c + reply.c + send.c + + + + + memsafe.s + page.c + pfault.c + + + anonmem.c + aspace.c + balance.c + cont.c + drvlck.c + freelist.c + iospace.c + kmap.c + marea.c + mdl.c + mm.c + process.c + mminit.c + mpw.c + ncache.c + npool.c + pagefile.c + pageop.c + pager.c + pagfault.c + paging.c + pe.c + physical.c + pool.c + ppool.c + region.c + rmap.c + section.c + verifier.c + virtual.c + wset.c + elf32.c + elf64.c + + + obdir.c + obinit.c + obhandle.c + obname.c + oblife.c + obref.c + sdcache.c + obsecure.c + symlink.c + obwait.c + + + power.c + events.c + + + debug.c + job.c + kill.c + notify.c + process.c + psmgr.c + query.c + quota.c + security.c + state.c + thread.c + win32.c + + + + + exception.c + seh.s + + + libsupp.c + misc.c + nls.c + regio.c + strtok.c + + + access.c + acl.c + audit.c + lsa.c + luid.c + priv.c + sd.c + semgr.c + sid.c + token.c + + + + vdmmain.c + vdmexec.c + + + + wmi.c + + ntoskrnl.rc + -nostartfiles + -nostdlib + -lgcc