From 488f0ac07879089b7bf5a69305513b1aaaea9ab2 Mon Sep 17 00:00:00 2001 From: David Welch Date: Sun, 10 Dec 2000 23:42:01 +0000 Subject: [PATCH] Some work on file caching Some work on the minix filesystem Some work on v86 mode support Implemented NtGetContextThread svn path=/trunk/; revision=1467 --- reactos/ChangeLog | 61 +- reactos/Makefile | 3 +- reactos/drivers/fs/minix/Makefile | 41 + reactos/drivers/fs/minix/bitops.c | 203 ++++ reactos/drivers/fs/minix/bitops.h | 30 + reactos/drivers/fs/minix/inode.c | 2 +- reactos/drivers/fs/minix/makefile_rex | 101 -- reactos/install-system.sh | 1 + reactos/install.bochs | 5 +- reactos/install.sh | 4 +- reactos/lib/user32/user32.def | 1116 +++++++++++----------- reactos/ntoskrnl/Makefile | 9 +- reactos/ntoskrnl/cc/view.c | 101 +- reactos/ntoskrnl/include/internal/ke.h | 4 + reactos/ntoskrnl/include/internal/ps.h | 26 +- reactos/ntoskrnl/include/internal/vm86.h | 76 ++ reactos/ntoskrnl/ke/dpc.c | 91 +- reactos/ntoskrnl/ke/i386/bthread.S | 64 ++ reactos/ntoskrnl/ke/i386/irq.c | 36 +- reactos/ntoskrnl/ke/i386/irqhand.c | 6 +- reactos/ntoskrnl/ke/i386/syscall.S | 246 +++++ reactos/ntoskrnl/ke/i386/trap.s | 478 +-------- reactos/ntoskrnl/ke/i386/tskswitch.S | 84 ++ reactos/ntoskrnl/ke/i386/vm86_sup.S | 142 +++ reactos/ntoskrnl/ke/kthread.c | 3 +- reactos/ntoskrnl/lpc/close.c | 84 +- reactos/ntoskrnl/ps/debug.c | 268 ++++++ reactos/ntoskrnl/ps/thread.c | 233 +---- 28 files changed, 2053 insertions(+), 1465 deletions(-) create mode 100644 reactos/drivers/fs/minix/Makefile create mode 100644 reactos/drivers/fs/minix/bitops.c create mode 100644 reactos/drivers/fs/minix/bitops.h delete mode 100644 reactos/drivers/fs/minix/makefile_rex create mode 100644 reactos/ntoskrnl/include/internal/vm86.h create mode 100644 reactos/ntoskrnl/ke/i386/bthread.S create mode 100644 reactos/ntoskrnl/ke/i386/syscall.S create mode 100644 reactos/ntoskrnl/ke/i386/tskswitch.S create mode 100644 reactos/ntoskrnl/ke/i386/vm86_sup.S create mode 100644 reactos/ntoskrnl/ps/debug.c diff --git a/reactos/ChangeLog b/reactos/ChangeLog index 92fa2d8da0b..f803a18c02f 100644 --- a/reactos/ChangeLog +++ b/reactos/ChangeLog @@ -1,45 +1,52 @@ -2000-08-30 David Welch +2000-12-04 David Welch - * Added calibration of KeStallExecutionProcessor timing - (code from linux 2.2.16). + * ntoskrnl/ke/i386/irq.c (KiInterruptDispatch): Record the last PC + value for a rescheduled thread. + * ntoskrnl/ke/i386/irqhand.s: Construct a primitive trap frame + in interrupt handlers. + +2000-08-30 David Welch + + * Added calibration of KeStallExecutionProcessor timing + (code from linux 2.2.16). - * Corrected compilation bugs in user32 library. + * Corrected compilation bugs in user32 library. - * Corrected compilation bugs related to anonymous structs - in ndis code. + * Corrected compilation bugs related to anonymous structs + in ndis code. - * Pass command line to kernel from loadros. + * Pass command line to kernel from loadros. - * Corrected PIC mask calculation. + * Corrected PIC mask calculation. -2000-05-27 David Welch +2000-05-27 David Welch - * Fixed issue with closing non-existent or already closed - handle. + * Fixed issue with closing non-existent or already closed + handle. -2000-01-26 David Welch +2000-01-26 David Welch - * ZwCreateProcess now maps ntdll rather than the user-mode - code. + * ZwCreateProcess now maps ntdll rather than the user-mode + code. -1999-09-06 David Welch +1999-09-06 David Welch - * Implemented ZwOpenProcess. + * Implemented ZwOpenProcess. - * Partially implemented killing other threads (possible memory - leaks). + * Partially implemented killing other threads (possible memory + leaks). - * Made a start on a proper implemention of APCs (based on - article in NT insider). + * Made a start on a proper implemention of APCs (based on + article in NT insider). -1998-12-08 David Welch +1998-12-08 David Welch - * Corrected bug in shell (Read two keypresses and assumed they - where the key going up and down respectively). + * Corrected bug in shell (Read two keypresses and assumed they + where the key going up and down respectively). - * Corrected race in dpc handling. + * Corrected race in dpc handling. - * Took out cleanup sections in ZwReadFile (now handled by the - APC). + * Took out cleanup sections in ZwReadFile (now handled by the + APC). - * Disabled broken code in kernel32. + * Disabled broken code in kernel32. diff --git a/reactos/Makefile b/reactos/Makefile index 462e5d3225c..f20fcdf14d9 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -37,7 +37,7 @@ DEVICE_DRIVERS = vidport vga blue ide null floppy INPUT_DRIVERS = keyboard -FS_DRIVERS = vfat +FS_DRIVERS = vfat minix # FS_DRIVERS = minix ext2 template # ndis tdi tcpip tditest wshtcpip @@ -53,6 +53,7 @@ SYS_APPS = shell winlogon services APPS = args hello test cat bench apc shm lpc thread event file gditest \ pteb consume dump_shared_data vmtest regtest + # objdir # ping diff --git a/reactos/drivers/fs/minix/Makefile b/reactos/drivers/fs/minix/Makefile new file mode 100644 index 00000000000..91133611ea5 --- /dev/null +++ b/reactos/drivers/fs/minix/Makefile @@ -0,0 +1,41 @@ +# $Id: Makefile,v 1.1 2000/12/10 23:42:01 dwelch Exp $ +# +# +PATH_TO_TOP = ../../.. + +TARGET = minixfs + +BASE_CFLAGS = -I../../../include + +OBJECTS = block.o rw.o inode.o dir.o mount.o blockdev.o cache.o bitops.o \ + $(TARGET).coff ../../../ntoskrnl/ntoskrnl.a + +all: $(TARGET).sys $(TARGET).sys.unstripped + +.phony: all + +clean: + - $(RM) $(TARGET).o + - $(RM) $(TARGET).coff + - $(RM) junk.tmp + - $(RM) base.tmp + - $(RM) temp.exp + - $(RM) $(TARGET).sys + - $(RM) $(TARGET).sys.unstripped + +.phony: clean + +install: $(FLOPPY_DIR)/drivers/$(TARGET).sys + +$(FLOPPY_DIR)/drivers/$(TARGET).sys: $(TARGET).sys + $(CP) $(TARGET).sys $(FLOPPY_DIR)/drivers/$(TARGET).sys + +dist: ../../../$(DIST_DIR)/drivers/$(TARGET).sys + +../../../$(DIST_DIR)/drivers/$(TARGET).sys: $(TARGET).sys + $(CP) $(TARGET).sys ../../../$(DIST_DIR)/drivers/$(TARGET).sys + +$(TARGET).sys $(TARGET).sys.unstripped: $(OBJECTS) + +WARNINGS_ARE_ERRORS = yes +include ../../../rules.mak diff --git a/reactos/drivers/fs/minix/bitops.c b/reactos/drivers/fs/minix/bitops.c new file mode 100644 index 00000000000..7f2b3356e5d --- /dev/null +++ b/reactos/drivers/fs/minix/bitops.c @@ -0,0 +1,203 @@ +/* + * ReactOS kernel + * + * 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. + */ +/* + * Copyright 1992, Linus Torvalds. + */ +/* + * These have to be done with inline assembly: that way the bit-setting + * is guaranteed to be atomic. All bit operations return 0 if the bit + * was cleared before the operation and != 0 if it was not. + * + * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). + */ + +#ifdef __SMP__ +#define LOCK_PREFIX "lock ; " +#else +#define LOCK_PREFIX "" +#endif + +/* + * Function prototypes to keep gcc -Wall happy + */ +extern void set_bit(int nr, volatile void * addr); +extern void clear_bit(int nr, volatile void * addr); +extern void change_bit(int nr, volatile void * addr); +extern int test_and_set_bit(int nr, volatile void * addr); +extern int test_and_clear_bit(int nr, volatile void * addr); +extern int test_and_change_bit(int nr, volatile void * addr); +extern int __constant_test_bit(int nr, const volatile void * addr); +extern int __test_bit(int nr, volatile void * addr); +extern int find_first_zero_bit(void * addr, unsigned size); +extern int find_next_zero_bit (void * addr, int size, int offset); +extern unsigned long ffz(unsigned long word); + +/* + * Some hacks to defeat gcc over-optimizations.. + */ +struct __dummy { unsigned long a[100]; }; +#define ADDR (*(volatile struct __dummy *) addr) +#define CONST_ADDR (*(volatile const struct __dummy *) addr) + +void set_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btsl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +void clear_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btrl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +void change_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btcl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +int test_and_set_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( LOCK_PREFIX + "btsl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr)); + return oldbit; +} + +int test_and_clear_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( LOCK_PREFIX + "btrl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr)); + return oldbit; +} + +int test_and_change_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( LOCK_PREFIX + "btcl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr)); + return oldbit; +} + +/* + * This routine doesn't need to be atomic. + */ +int __constant_test_bit(int nr, const volatile void * addr) +{ + return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; +} + +int test_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( + "btl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit) + :"m" (ADDR),"Ir" (nr)); + return oldbit; +} + +#if 0 +#define test_bit(nr,addr) \ +(__builtin_constant_p(nr) ? \ + __constant_test_bit((nr),(addr)) : \ + __test_bit((nr),(addr))) +#endif + +/* + * Find-bit routines.. + */ +int find_first_zero_bit(void * addr, unsigned size) +{ + int d0, d1, d2; + int res; + + if (!size) + return 0; + __asm__("cld\n\t" + "movl $-1,%%eax\n\t" + "xorl %%edx,%%edx\n\t" + "repe; scasl\n\t" + "je 1f\n\t" + "xorl -4(%%edi),%%eax\n\t" + "subl $4,%%edi\n\t" + "bsfl %%eax,%%edx\n" + "1:\tsubl %%ebx,%%edi\n\t" + "shll $3,%%edi\n\t" + "addl %%edi,%%edx" + :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2) + :"1" ((size + 31) >> 5), "2" (addr), "b" (addr)); + return res; +} + +int find_next_zero_bit (void * addr, int size, int offset) +{ + unsigned long * p = ((unsigned long *) addr) + (offset >> 5); + int set = 0, bit = offset & 31, res; + + if (bit) { + /* + * Look for zero in first byte + */ + __asm__("bsfl %1,%0\n\t" + "jne 1f\n\t" + "movl $32, %0\n" + "1:" + : "=r" (set) + : "r" (~(*p >> bit))); + if (set < (32 - bit)) + return set + offset; + set = 32 - bit; + p++; + } + /* + * No zero yet, search remaining full bytes for a zero + */ + res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); + return (offset + set + res); +} + +/* + * ffz = Find First Zero in word. Undefined if no zero exists, + * so code should check against ~0UL first.. + */ +unsigned long ffz(unsigned long word) +{ + __asm__("bsfl %1,%0" + :"=r" (word) + :"r" (~word)); + return word; +} diff --git a/reactos/drivers/fs/minix/bitops.h b/reactos/drivers/fs/minix/bitops.h new file mode 100644 index 00000000000..7c0123bbd3a --- /dev/null +++ b/reactos/drivers/fs/minix/bitops.h @@ -0,0 +1,30 @@ +#ifndef _I386_BITOPS_H +#define _I386_BITOPS_H + +/* + * Copyright 1992, Linus Torvalds. + */ + +/* + * These have to be done with inline assembly: that way the bit-setting + * is guaranteed to be atomic. All bit operations return 0 if the bit + * was cleared before the operation and != 0 if it was not. + * + * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). + */ + +/* + * Function prototypes to keep gcc -Wall happy + */ +extern void set_bit(int nr, volatile void * addr); +extern void clear_bit(int nr, volatile void * addr); +extern void change_bit(int nr, volatile void * addr); +extern int test_and_set_bit(int nr, volatile void * addr); +extern int test_and_clear_bit(int nr, volatile void * addr); +extern int test_and_change_bit(int nr, volatile void * addr); +extern int test_bit(int nr, volatile void * addr); +extern int find_first_zero_bit(void * addr, unsigned size); +extern int find_next_zero_bit (void * addr, int size, int offset); +extern unsigned long ffz(unsigned long word); + +#endif /* _I386_BITOPS_H */ diff --git a/reactos/drivers/fs/minix/inode.c b/reactos/drivers/fs/minix/inode.c index 37fce616160..8f6d9f2adc7 100644 --- a/reactos/drivers/fs/minix/inode.c +++ b/reactos/drivers/fs/minix/inode.c @@ -11,7 +11,7 @@ #include #include -#include "../../../ntoskrnl/include/internal/bitops.h" +#include "bitops.h" #include #define NDEBUG diff --git a/reactos/drivers/fs/minix/makefile_rex b/reactos/drivers/fs/minix/makefile_rex deleted file mode 100644 index 55d2194366c..00000000000 --- a/reactos/drivers/fs/minix/makefile_rex +++ /dev/null @@ -1,101 +0,0 @@ -# $Id: makefile_rex,v 1.13 2000/11/20 19:59:11 ekohl Exp $ -# -# Minix IFS Driver makefile -# -BASE_CFLAGS = -I../../../include - -TARGETNAME=minixfs - -all: $(TARGETNAME).sys - -OBJECTS = block.o rw.o inode.o dir.o mount.o blockdev.o cache.o \ - minix.coff ../../../ntoskrnl/ntoskrnl.a - -.phony: all - -clean: - - $(RM) *.o - - $(RM) junk.tmp - - $(RM) base.tmp - - $(RM) temp.exp - - $(RM) cache.o - - $(RM) minix.coff - - $(RM) $(TARGETNAME).sys - -.phony: clean - -minix.o: $(OBJECTS) - $(LD) -r $(OBJECTS) -o minix.o - -minixfs.nostrip.sys: $(OBJECTS) - $(CC) \ - -specs=../../svc_specs \ - -mdll \ - -o junk.tmp \ - -Wl,--defsym,_end=end \ - -Wl,--defsym,_edata=__data_end__ \ - -Wl,--defsym,_etext=etext \ - -Wl,--base-file,base.tmp \ - $(OBJECTS) - - $(RM) junk.tmp - $(DLLTOOL) \ - --dllname $(TARGETNAME).sys \ - --base-file base.tmp \ - --output-exp temp.exp - - $(RM) base.tmp - $(CC) \ - --verbose \ - -Wl,--image-base,0x10000 \ - -Wl,-e,_DriverEntry@8 \ - -specs=../../svc_specs \ - -mdll \ - -o $(TARGETNAME).nostrip.sys \ - $(OBJECTS) \ - -Wl,temp.exp - - $(RM) temp.exp - -minixfs.sys: $(OBJECTS) - $(STRIP) --strip-debug $(OBJECTS) - $(CC) \ - -specs=../../svc_specs \ - -mdll \ - -o junk.tmp \ - -Wl,--defsym,_end=end \ - -Wl,--defsym,_edata=__data_end__ \ - -Wl,--defsym,_etext=etext \ - -Wl,--base-file,base.tmp \ - $(OBJECTS) - - $(RM) junk.tmp - $(DLLTOOL) \ - --dllname $(TARGETNAME).sys \ - --base-file base.tmp \ - --output-exp temp.exp - - $(RM) base.tmp - $(CC) \ - --verbose \ - -Wl,--image-base,0x10000 \ - -Wl,-e,_DriverEntry@8 \ - -specs=../../svc_specs \ - -mdll \ - -o $(TARGETNAME).sys \ - $(OBJECTS) \ - -Wl,temp.exp - - $(RM) temp.exp - -minix.coff: ../../../include/reactos/buildno.h minix.rc - -install: $(FLOPPY_DIR)/drivers/$(TARGETNAME).sys - -$(FLOPPY_DIR)/drivers/$(TARGETNAME).sys: $(TARGETNAME).sys - $(CP) $(TARGETNAME).sys $(FLOPPY_DIR)/drivers/$(TARGETNAME).sys - -dist: ../../../$(DIST_DIR)/drivers/$(TARGETNAME).sys - -../../../$(DIST_DIR)/drivers/$(TARGETNAME).sys: $(TARGETNAME).sys - $(CP) $(TARGETNAME).sys ../../../$(DIST_DIR)/drivers/$(TARGETNAME).sys - -WIN32_LEAN_AND_MEAN = yes -WARNINGS_ARE_ERRORS = yes -WITH_DEBUGGING = yes -include ../../../rules.mak -# EOF diff --git a/reactos/install-system.sh b/reactos/install-system.sh index d70bb3570b5..dc10123d08e 100644 --- a/reactos/install-system.sh +++ b/reactos/install-system.sh @@ -8,6 +8,7 @@ cp loaders/dos/loadros.com $1 cp ntoskrnl/ntoskrnl.exe $1 cp services/fs/vfat/vfatfs.sys $1 cp services/dd/ide/ide.sys $1 +cp services/fs/minix/minixfs.sys $1 #cp services/dd/floppy/floppy.sys $1 #cp ntoskrnl/ntoskrnl.exe $1/reactos/system32/ #cp services/fs/vfat/vfatfs.sys $1/reactos/system32/drivers/ diff --git a/reactos/install.bochs b/reactos/install.bochs index 3bbd94461f9..3f69e2b3648 100644 --- a/reactos/install.bochs +++ b/reactos/install.bochs @@ -5,6 +5,9 @@ mount -t vfat /bochs/1.44a /mnt/floppy -o loop,rw umount /mnt/floppy echo "Installing to disk." mount -t vfat /bochs/10M.vga.dos /mnt/floppy -o loop,offset=8704,rw -#mount -t minix /bochs/10M.vga.dos /mnt/floppy -o loop,offset=8704,rw +./install.sh /mnt/floppy +umount /mnt/floppy +echo "Installing to minix disk." +mount -t minix /bochs/10M.vga.minix /mnt/floppy -o loop,offset=8704,rw ./install.sh /mnt/floppy umount /mnt/floppy diff --git a/reactos/install.sh b/reactos/install.sh index 1a3e959a2c1..a575ebfa8d3 100644 --- a/reactos/install.sh +++ b/reactos/install.sh @@ -4,7 +4,7 @@ mkdir -p $1/reactos/system32/drivers mkdir -p $1/reactos/bin ./install-system.sh $1 cp services/dd/floppy/floppy.sys $1/reactos/system32/drivers/ -cp services/dd/keyboard/keyboard.sys $1/reactos/system32/drivers +cp services/input/keyboard/keyboard.sys $1/reactos/system32/drivers cp services/dd/blue/blue.sys $1/reactos/system32/drivers cp services/dd/vga/miniport/vgamp.sys $1/reactos/system32/drivers cp services/dd/vga/display/vgaddi.dll $1/reactos/system32/drivers @@ -37,3 +37,5 @@ cp apps/consume/consume.exe $1/reactos/bin cp apps/float/float.exe $1/reactos/bin cp apps/dump_shared_data/dump_shared_data.exe $1/reactos/bin cp apps/vmtest/vmtest.exe $1/reactos/bin +cp apps/uitest/uitest.exe $1/reactos/bin/ +cp apps/gditest/gditest.exe $1/reactos/bin/ diff --git a/reactos/lib/user32/user32.def b/reactos/lib/user32/user32.def index 7ee83d70e07..cfac5a984f8 100644 --- a/reactos/lib/user32/user32.def +++ b/reactos/lib/user32/user32.def @@ -1,562 +1,562 @@ LIBRARY user32.dll EXPORTS -ActivateKeyboardLayout@8 -AdjustWindowRect@12 -AdjustWindowRectEx@16 -AnyPopup@0 -AppendMenuA@16 -AppendMenuW@16 -ArrangeIconicWindows@4 -AttachThreadInput@12 -BeginDeferWindowPos@4 -BeginPaint@8 -BringWindowToTop@4 -BroadcastSystemMessage@20 -CalcChildScroll@8 -CallMsgFilter@8 -CallMsgFilterA@8 -CallMsgFilterW@8 -CallNextHookEx@16 -CallWindowProcA@20 -CallWindowProcW@20 -CascadeChildWindows@8 -CascadeWindows@20 -ChangeClipboardChain@8 -ChangeDisplaySettingsA@8 -ChangeDisplaySettingsW@8 -ChangeMenuA@20 -ChangeMenuW@20 -CharLowerA@4 -CharLowerBuffA@8 -CharLowerBuffW@8 -CharLowerW@4 -CharNextA@4 -CharNextExA@12 -CharNextW@4 -CharPrevA@8 -CharPrevExA@16 -CharPrevW@8 -CharToOemA@8 -CharToOemBuffA@12 -CharToOemBuffW@12 -CharToOemW@8 -CharUpperA@4 -CharUpperBuffA@8 -CharUpperBuffW@8 -CharUpperW@4 -CheckDlgButton@12 -CheckMenuItem@12 -CheckMenuRadioItem@20 -CheckRadioButton@16 -ChildWindowFromPoint@12 -ChildWindowFromPointEx@16 -ClientToScreen@8 -ClipCursor@4 -CloseClipboard@0 -CloseDesktop@4 -CloseWindow@4 -CloseWindowStation@4 -CopyAcceleratorTableA@12 -CopyAcceleratorTableW@12 -CopyIcon@4 -CopyImage@20 -CopyRect@8 -CountClipboardFormats@0 -CreateAcceleratorTableA@8 -CreateAcceleratorTableW@8 -CreateCaret@16 -CreateCursor@28 -CreateDesktopA@24 -CreateDesktopW@24 -CreateDialogIndirectParamA@20 -CreateDialogIndirectParamW@20 -CreateDialogParamA@20 -CreateDialogParamW@20 -CreateIcon@28 -CreateIconFromResource@16 -CreateIconFromResourceEx@28 -CreateIconIndirect@4 -CreateMDIWindowA@40 -CreateMDIWindowW@40 -CreateMenu@0 -CreatePopupMenu@0 -CreateWindowExA@48 -CreateWindowExW@48 -CreateWindowStationA@16 -CreateWindowStationW@16 -DdeAbandonTransaction@12 -DdeAccessData@8 -DdeAddData@16 -DdeClientTransaction@32 -DdeCmpStringHandles@8 -DdeConnect@16 -DdeConnectList@20 -DdeCreateDataHandle@28 -DdeCreateStringHandleA@12 -DdeCreateStringHandleW@12 -DdeDisconnect@4 -DdeDisconnectList@4 -DdeEnableCallback@12 -DdeFreeDataHandle@4 -DdeFreeStringHandle@8 -DdeGetData@16 -DdeGetLastError@4 -DdeGetQualityOfService@12 -DdeImpersonateClient@4 -DdeInitializeA@16 -DdeInitializeW@16 -DdeKeepStringHandle@8 -DdeNameService@16 -DdePostAdvise@12 -DdeQueryConvInfo@12 -DdeQueryNextServer@8 -DdeQueryStringA@20 -DdeQueryStringW@20 -DdeReconnect@4 -DdeSetQualityOfService@12 -DdeSetUserHandle@12 -DdeUnaccessData@4 -DdeUninitialize@4 -DefDlgProcA@16 -DefDlgProcW@16 -DefFrameProcA@20 -DefFrameProcW@20 -DefMDIChildProcA@16 -DefMDIChildProcW@16 -DefWindowProcA@16 -DefWindowProcW@16 -DeferWindowPos@32 -DeleteMenu@12 -DestroyAcceleratorTable@4 -DestroyCaret@0 -DestroyCursor@4 -DestroyIcon@4 -DestroyMenu@4 -DestroyWindow@4 -DialogBoxIndirectParamA@20 -DialogBoxIndirectParamW@20 -DialogBoxParamA@20 -DialogBoxParamW@20 -DispatchMessageA@4 -DispatchMessageW@4 -DlgDirListA@20 -DlgDirListComboBoxA@20 -DlgDirListComboBoxW@20 -DlgDirListW@20 -DlgDirSelectComboBoxExA@16 -DlgDirSelectComboBoxExW@16 -DlgDirSelectExA@16 -DlgDirSelectExW@16 -DragDetect@12 -DragObject@20 -DrawAnimatedRects@16 -DrawCaption@16 -DrawEdge@16 -DrawFocusRect@8 -DrawFrame@16 -DrawFrameControl@16 -DrawIcon@16 -DrawIconEx@36 -DrawMenuBar@4 -DrawStateA@40 -DrawStateW@40 -DrawTextA@20 -DrawTextExA@24 -DrawTextExW@24 -DrawTextW@20 -EditWndProc@16 -EmptyClipboard@0 -EnableMenuItem@12 -EnableScrollBar@12 -EnableWindow@8 -EndDeferWindowPos@4 -EndDialog@8 -EndPaint@8 -EnumChildWindows@12 -EnumClipboardFormats@4 -EnumDesktopWindows@12 -EnumDesktopsA@12 -EnumDesktopsW@12 -EnumDisplaySettingsA@12 -EnumDisplaySettingsW@12 -EnumPropsA@8 -EnumPropsExA@12 -EnumPropsExW@12 -EnumPropsW@8 -EnumThreadWindows@12 -EnumWindowStationsA@8 -EnumWindowStationsW@8 -EnumWindows@8 -EqualRect@8 -ExcludeUpdateRgn@8 -ExitWindowsEx@8 -FillRect@12 -FindWindowA@8 -FindWindowExA@16 -FindWindowExW@16 -FindWindowW@8 -FlashWindow@8 -FrameRect@12 -FreeDDElParam@8 -GetActiveWindow@0 -GetAsyncKeyState@4 -GetCapture@0 -GetCaretBlinkTime@0 -GetCaretPos@4 -GetClassInfoA@12 -GetClassInfoExA@12 -GetClassInfoExW@12 -GetClassInfoW@12 -GetClassLongA@8 -GetClassLongW@8 -GetClassNameA@12 -GetClassNameW@12 -GetClassWord@8 -GetClientRect@8 -GetClipCursor@4 -GetClipboardData@4 -GetClipboardFormatNameA@12 -GetClipboardFormatNameW@12 -GetClipboardOwner@0 -GetClipboardViewer@0 -GetCursor@0 -GetCursorPos@4 -GetDC@4 -GetDCEx@12 -GetDesktopWindow@0 -GetDialogBaseUnits@0 -GetDlgCtrlID@4 -GetDlgItem@8 -GetDlgItemInt@16 -GetDlgItemTextA@16 -GetDlgItemTextW@16 -GetDoubleClickTime@0 -GetFocus@0 -GetForegroundWindow@0 -GetIconInfo@8 -GetInputDesktop@0 -GetInputState@0 -GetKBCodePage@0 -GetKeyNameTextA@12 -GetKeyNameTextW@12 -GetKeyState@4 -GetKeyboardLayout@4 -GetKeyboardLayoutList@8 -GetKeyboardLayoutNameA@4 -GetKeyboardLayoutNameW@4 -GetKeyboardState@4 -GetKeyboardType@4 -GetLastActivePopup@4 -GetMenu@4 -GetMenuCheckMarkDimensions@0 -GetMenuContextHelpId@4 -_imp__GetMenuContextHelpId@4 -GetMenuDefaultItem@12 -GetMenuItemCount@4 -GetMenuItemID@8 -GetMenuItemInfoA@16 -GetMenuItemInfoW@16 -GetMenuItemRect@16 -GetMenuState@12 -GetMenuStringA@20 -GetMenuStringW@20 -GetMessageA@16 -GetMessageExtraInfo@0 -GetMessagePos@0 -GetMessageTime@0 -GetMessageW@16 -GetNextDlgGroupItem@12 -GetNextDlgTabItem@12 -GetOpenClipboardWindow@0 -GetParent@4 -GetPriorityClipboardFormat@8 -GetProcessWindowStation@0 -GetPropA@8 -GetPropW@8 -GetQueueStatus@4 -GetScrollInfo@12 -GetScrollPos@8 -GetScrollRange@16 -GetShellWindow@0 -GetSubMenu@8 -GetSysColor@4 -GetSysColorBrush@4 -GetSystemMenu@8 -GetSystemMetrics@4 -GetTabbedTextExtentA@20 -GetTabbedTextExtentW@20 -GetThreadDesktop@4 -GetTopWindow@4 -GetUpdateRect@12 -GetUpdateRgn@12 -GetUserObjectInformationA@20 -GetUserObjectInformationW@20 -GetUserObjectSecurity@20 -GetWindow@8 -GetWindowContextHelpId@4 -_imp__GetWindowContextHelpId@4 -GetWindowDC@4 -GetWindowLongA@8 -GetWindowLongW@8 -GetWindowPlacement@8 -GetWindowRect@8 -GetWindowRgn@8 -GetWindowTextA@12 -GetWindowTextLengthA@4 -GetWindowTextLengthW@4 -GetWindowTextW@12 -GetWindowThreadProcessId@8 -GetWindowWord@8 -GrayStringA@36 -GrayStringW@36 -HideCaret@4 -HiliteMenuItem@16 -ImpersonateDdeClientWindow@8 -InSendMessage@0 -InflateRect@12 -InsertMenuA@20 -InsertMenuItemA@16 -InsertMenuItemW@16 -InsertMenuW@20 -IntersectRect@12 -InvalidateRect@12 -InvalidateRgn@12 -InvertRect@8 -IsCharAlphaA@4 -IsCharAlphaNumericA@4 -IsCharAlphaNumericW@4 -IsCharAlphaW@4 -IsCharLowerA@4 -IsCharLowerW@4 -IsCharUpperA@4 -IsCharUpperW@4 -IsChild@8 -IsClipboardFormatAvailable@4 -IsDialogMessage@8 -IsDialogMessageA@8 -IsDialogMessageW@8 -IsDlgButtonChecked@8 -IsIconic@4 -IsMenu@4 -IsRectEmpty@4 -IsWindow@4 -IsWindowEnabled@4 -IsWindowUnicode@4 -IsWindowVisible@4 -IsZoomed@4 -KillSystemTimer@8 -KillTimer@8 -LoadAcceleratorsA@8 -LoadAcceleratorsW@8 -LoadBitmapA@8 -LoadBitmapW@8 -LoadCursorA@8 -LoadCursorFromFileA@4 -LoadCursorFromFileW@4 -LoadCursorW@8 -LoadIconA@8 -LoadIconW@8 -LoadImageA@24 -LoadImageW@24 -LoadKeyboardLayoutA@8 -LoadKeyboardLayoutW@8 -LoadMenuA@8 -LoadMenuIndirectA@4 -LoadMenuIndirectW@4 -LoadMenuW@8 -LoadStringA@16 -LoadStringW@16 -LockWindowUpdate@4 -LookupIconIdFromDirectory@8 -LookupIconIdFromDirectoryEx@20 -MapDialogRect@8 -MapVirtualKeyA@8 -MapVirtualKeyExA@12 -MapVirtualKeyExW@12 -MapVirtualKeyW@8 -MapWindowPoints@16 -MenuItemFromPoint@16 -MessageBeep@4 -MessageBoxA@16 -MessageBoxExA@20 -MessageBoxExW@20 -MessageBoxIndirectA@4 -MessageBoxIndirectW@4 -MessageBoxW@16 -ModifyMenuA@20 -ModifyMenuW@20 -MoveWindow@24 -MsgWaitForMultipleObjects@20 -MsgWaitForMultipleObjectsEx@20 -OemKeyScan@4 -OemToCharA@8 -OemToCharBuffA@12 -OemToCharBuffW@12 -OemToCharW@8 -OffsetRect@12 -OpenClipboard@4 -OpenDesktopA@16 -OpenDesktopW@16 -OpenIcon@4 -OpenInputDesktop@12 -OpenWindowStationA@12 -OpenWindowStationW@12 -PackDDElParam@12 -PaintDesktop@4 -PeekMessageA@20 -PeekMessageW@20 -PostMessageA@16 -PostMessageW@16 -PostQuitMessage@4 -PostThreadMessageA@16 -PostThreadMessageW@16 -PtInRect@12 -RedrawWindow@16 -RegisterClassA@4 -RegisterClassExA@4 -RegisterClassExW@4 -RegisterClassW@4 -RegisterClipboardFormatA@4 -RegisterClipboardFormatW@4 -RegisterHotKey@16 -RegisterWindowMessageA@4 -RegisterWindowMessageW@4 -ReleaseCapture@0 -ReleaseDC@8 -RemoveMenu@12 -RemovePropA@8 -RemovePropW@8 -ReplyMessage@4 -ReuseDDElParam@20 -ScreenToClient@8 -ScrollChildren@12 -ScrollDC@28 -ScrollWindow@20 -ScrollWindowEx@32 -SendDlgItemMessageA@20 -SendDlgItemMessageW@20 -SendMessageA@16 -SendMessageCallbackA@24 -SendMessageCallbackW@24 -SendMessageTimeoutA@28 -SendMessageTimeoutW@28 -SendMessageW@16 -SendNotifyMessageA@16 -SendNotifyMessageW@16 -SetActiveWindow@4 -SetCapture@4 -SetCaretBlinkTime@4 -SetCaretPos@8 -SetClassLongA@12 -SetClassLongW@12 -SetClassWord@12 -SetClipboardData@8 -SetClipboardViewer@4 -SetCursor@4 -SetCursorPos@8 -SetDebugErrorLevel@4 -SetDeskWallpaper@4 -SetDlgItemInt@16 -SetDlgItemTextA@12 -SetDlgItemTextW@12 -SetDoubleClickTime@4 -SetFocus@4 -SetForegroundWindow@4 -SetKeyboardState@4 -SetLastErrorEx@8 -SetMenu@8 -SetMenuContextHelpId@8 -_imp__SetMenuContextHelpId@8 -SetMenuDefaultItem@12 -SetMenuItemBitmaps@20 -SetMenuItemInfoA@16 -SetMenuItemInfoW@16 -SetMessageExtraInfo@4 -SetMessageQueue@4 -SetParent@8 -SetProcessWindowStation@4 -SetPropA@12 -SetPropW@12 -SetRect@20 -SetRectEmpty@4 -SetScrollInfo@16 -SetScrollPos@16 -SetScrollRange@20 -SetShellWindow@4 -SetSysColors@12 -SetSystemCursor@8 -SetSystemMenu@8 -SetSystemTimer@16 -SetThreadDesktop@4 -SetTimer@16 -SetUserObjectInformationA@16 -SetUserObjectInformationW@16 -SetUserObjectSecurity@12 -SetWindowContextHelpId@8 -_imp__SetWindowContextHelpId@8 -SetWindowLongA@12 -SetWindowLongW@12 -SetWindowPlacement@8 -SetWindowPos@28 -SetWindowRgn@12 -SetWindowTextA@8 -SetWindowTextW@8 -SetWindowWord@12 -SetWindowsHookA@8 -SetWindowsHookExA@16 -SetWindowsHookExW@16 -SetWindowsHookW@8 -ShowCaret@4 -ShowCursor@4 -ShowOwnedPopups@8 -ShowScrollBar@12 -ShowWindow@8 -ShowWindowAsync@8 -SubtractRect@12 -SwapMouseButton@4 -SwitchDesktop@4 -SystemParametersInfoA@16 -SystemParametersInfoW@16 -TabbedTextOutA@32 -TabbedTextOutW@32 -TileChildWindows@8 -TileWindows@20 -ToAscii@20 -ToAsciiEx@24 -ToUnicode@24 -ToUnicodeEx@28 -TrackMouseEvent@4 -TrackPopupMenu@28 -TrackPopupMenuEx@24 -TranslateAccelerator@12 -TranslateAcceleratorA@12 -TranslateAcceleratorW@12 -TranslateMDISysAccel@8 -TranslateMessage@4 -UnhookWindowsHook@8 -UnhookWindowsHookEx@4 -UnionRect@12 -UnloadKeyboardLayout@4 -UnpackDDElParam@16 -UnregisterClassA@8 -UnregisterClassW@8 -UnregisterHotKey@8 -UpdateWindow@4 -ValidateRect@8 -ValidateRgn@8 -VkKeyScanA@4 -VkKeyScanExA@8 -VkKeyScanExW@8 -VkKeyScanW@4 -WaitForInputIdle@8 -WaitMessage@0 -WinHelpA@16 -WinHelpW@16 -WindowFromDC@4 -WindowFromPoint@8 -keybd_event@16 -mouse_event@20 +ActivateKeyboardLayout +AdjustWindowRect +AdjustWindowRectEx +AnyPopup +AppendMenuA +AppendMenuW +ArrangeIconicWindows +AttachThreadInput +BeginDeferWindowPos +BeginPaint +BringWindowToTop +BroadcastSystemMessage +CalcChildScroll +CallMsgFilter +CallMsgFilterA +CallMsgFilterW +CallNextHookEx +CallWindowProcA +CallWindowProcW +CascadeChildWindows +CascadeWindows +ChangeClipboardChain +ChangeDisplaySettingsA +ChangeDisplaySettingsW +ChangeMenuA +ChangeMenuW +CharLowerA +CharLowerBuffA +CharLowerBuffW +CharLowerW +CharNextA +CharNextExA +CharNextW +CharPrevA +CharPrevExA +CharPrevW +CharToOemA +CharToOemBuffA +CharToOemBuffW +CharToOemW +CharUpperA +CharUpperBuffA +CharUpperBuffW +CharUpperW +CheckDlgButton +CheckMenuItem +CheckMenuRadioItem +CheckRadioButton +ChildWindowFromPoint +ChildWindowFromPointEx +ClientToScreen +ClipCursor +CloseClipboard +CloseDesktop +CloseWindow +CloseWindowStation +CopyAcceleratorTableA +CopyAcceleratorTableW +CopyIcon +CopyImage +CopyRect +CountClipboardFormats +CreateAcceleratorTableA +CreateAcceleratorTableW +CreateCaret +CreateCursor +CreateDesktopA +CreateDesktopW +CreateDialogIndirectParamA +CreateDialogIndirectParamW +CreateDialogParamA +CreateDialogParamW +CreateIcon +CreateIconFromResource +CreateIconFromResourceEx +CreateIconIndirect +CreateMDIWindowA +CreateMDIWindowW +CreateMenu +CreatePopupMenu +CreateWindowExA +CreateWindowExW +CreateWindowStationA +CreateWindowStationW +DdeAbandonTransaction +DdeAccessData +DdeAddData +DdeClientTransaction +DdeCmpStringHandles +DdeConnect +DdeConnectList +DdeCreateDataHandle +DdeCreateStringHandleA +DdeCreateStringHandleW +DdeDisconnect +DdeDisconnectList +DdeEnableCallback +DdeFreeDataHandle +DdeFreeStringHandle +DdeGetData +DdeGetLastError +DdeGetQualityOfService +DdeImpersonateClient +DdeInitializeA +DdeInitializeW +DdeKeepStringHandle +DdeNameService +DdePostAdvise +DdeQueryConvInfo +DdeQueryNextServer +DdeQueryStringA +DdeQueryStringW +DdeReconnect +DdeSetQualityOfService +DdeSetUserHandle +DdeUnaccessData +DdeUninitialize +DefDlgProcA +DefDlgProcW +DefFrameProcA +DefFrameProcW +DefMDIChildProcA +DefMDIChildProcW +DefWindowProcA +DefWindowProcW +DeferWindowPos +DeleteMenu +DestroyAcceleratorTable +DestroyCaret +DestroyCursor +DestroyIcon +DestroyMenu +DestroyWindow +DialogBoxIndirectParamA +DialogBoxIndirectParamW +DialogBoxParamA +DialogBoxParamW +DispatchMessageA +DispatchMessageW +DlgDirListA +DlgDirListComboBoxA +DlgDirListComboBoxW +DlgDirListW +DlgDirSelectComboBoxExA +DlgDirSelectComboBoxExW +DlgDirSelectExA +DlgDirSelectExW +DragDetect +DragObject +DrawAnimatedRects +DrawCaption +DrawEdge +DrawFocusRect +DrawFrame +DrawFrameControl +DrawIcon +DrawIconEx +DrawMenuBar +DrawStateA +DrawStateW +DrawTextA +DrawTextExA +DrawTextExW +DrawTextW +EditWndProc +EmptyClipboard +EnableMenuItem +EnableScrollBar +EnableWindow +EndDeferWindowPos +EndDialog +EndPaint +EnumChildWindows +EnumClipboardFormats +EnumDesktopWindows +EnumDesktopsA +EnumDesktopsW +EnumDisplaySettingsA +EnumDisplaySettingsW +EnumPropsA +EnumPropsExA +EnumPropsExW +EnumPropsW +EnumThreadWindows +EnumWindowStationsA +EnumWindowStationsW +EnumWindows +EqualRect +ExcludeUpdateRgn +ExitWindowsEx +FillRect +FindWindowA +FindWindowExA +FindWindowExW +FindWindowW +FlashWindow +FrameRect +FreeDDElParam +GetActiveWindow +GetAsyncKeyState +GetCapture +GetCaretBlinkTime +GetCaretPos +GetClassInfoA +GetClassInfoExA +GetClassInfoExW +GetClassInfoW +GetClassLongA +GetClassLongW +GetClassNameA +GetClassNameW +GetClassWord +GetClientRect +GetClipCursor +GetClipboardData +GetClipboardFormatNameA +GetClipboardFormatNameW +GetClipboardOwner +GetClipboardViewer +GetCursor +GetCursorPos +GetDC +GetDCEx +GetDesktopWindow +GetDialogBaseUnits +GetDlgCtrlID +GetDlgItem +GetDlgItemInt +GetDlgItemTextA +GetDlgItemTextW +GetDoubleClickTime +GetFocus +GetForegroundWindow +GetIconInfo +GetInputDesktop +GetInputState +GetKBCodePage +GetKeyNameTextA +GetKeyNameTextW +GetKeyState +GetKeyboardLayout +GetKeyboardLayoutList +GetKeyboardLayoutNameA +GetKeyboardLayoutNameW +GetKeyboardState +GetKeyboardType +GetLastActivePopup +GetMenu +GetMenuCheckMarkDimensions +GetMenuContextHelpId +_imp__GetMenuContextHelpId +GetMenuDefaultItem +GetMenuItemCount +GetMenuItemID +GetMenuItemInfoA +GetMenuItemInfoW +GetMenuItemRect +GetMenuState +GetMenuStringA +GetMenuStringW +GetMessageA +GetMessageExtraInfo +GetMessagePos +GetMessageTime +GetMessageW +GetNextDlgGroupItem +GetNextDlgTabItem +GetOpenClipboardWindow +GetParent +GetPriorityClipboardFormat +GetProcessWindowStation +GetPropA +GetPropW +GetQueueStatus +GetScrollInfo +GetScrollPos +GetScrollRange +GetShellWindow +GetSubMenu +GetSysColor +GetSysColorBrush +GetSystemMenu +GetSystemMetrics +GetTabbedTextExtentA +GetTabbedTextExtentW +GetThreadDesktop +GetTopWindow +GetUpdateRect +GetUpdateRgn +GetUserObjectInformationA +GetUserObjectInformationW +GetUserObjectSecurity +GetWindow +GetWindowContextHelpId +_imp__GetWindowContextHelpId +GetWindowDC +GetWindowLongA +GetWindowLongW +GetWindowPlacement +GetWindowRect +GetWindowRgn +GetWindowTextA +GetWindowTextLengthA +GetWindowTextLengthW +GetWindowTextW +GetWindowThreadProcessId +GetWindowWord +GrayStringA +GrayStringW +HideCaret +HiliteMenuItem +ImpersonateDdeClientWindow +InSendMessage +InflateRect +InsertMenuA +InsertMenuItemA +InsertMenuItemW +InsertMenuW +IntersectRect +InvalidateRect +InvalidateRgn +InvertRect +IsCharAlphaA +IsCharAlphaNumericA +IsCharAlphaNumericW +IsCharAlphaW +IsCharLowerA +IsCharLowerW +IsCharUpperA +IsCharUpperW +IsChild +IsClipboardFormatAvailable +IsDialogMessage +IsDialogMessageA +IsDialogMessageW +IsDlgButtonChecked +IsIconic +IsMenu +IsRectEmpty +IsWindow +IsWindowEnabled +IsWindowUnicode +IsWindowVisible +IsZoomed +KillSystemTimer +KillTimer +LoadAcceleratorsA +LoadAcceleratorsW +LoadBitmapA +LoadBitmapW +LoadCursorA +LoadCursorFromFileA +LoadCursorFromFileW +LoadCursorW +LoadIconA +LoadIconW +LoadImageA +LoadImageW +LoadKeyboardLayoutA +LoadKeyboardLayoutW +LoadMenuA +LoadMenuIndirectA +LoadMenuIndirectW +LoadMenuW +LoadStringA +LoadStringW +LockWindowUpdate +LookupIconIdFromDirectory +LookupIconIdFromDirectoryEx +MapDialogRect +MapVirtualKeyA +MapVirtualKeyExA +MapVirtualKeyExW +MapVirtualKeyW +MapWindowPoints +MenuItemFromPoint +MessageBeep +MessageBoxA +MessageBoxExA +MessageBoxExW +MessageBoxIndirectA +MessageBoxIndirectW +MessageBoxW +ModifyMenuA +ModifyMenuW +MoveWindow +MsgWaitForMultipleObjects +MsgWaitForMultipleObjectsEx +OemKeyScan +OemToCharA +OemToCharBuffA +OemToCharBuffW +OemToCharW +OffsetRect +OpenClipboard +OpenDesktopA +OpenDesktopW +OpenIcon +OpenInputDesktop +OpenWindowStationA +OpenWindowStationW +PackDDElParam +PaintDesktop +PeekMessageA +PeekMessageW +PostMessageA +PostMessageW +PostQuitMessage +PostThreadMessageA +PostThreadMessageW +PtInRect +RedrawWindow +RegisterClassA +RegisterClassExA +RegisterClassExW +RegisterClassW +RegisterClipboardFormatA +RegisterClipboardFormatW +RegisterHotKey +RegisterWindowMessageA +RegisterWindowMessageW +ReleaseCapture +ReleaseDC +RemoveMenu +RemovePropA +RemovePropW +ReplyMessage +ReuseDDElParam +ScreenToClient +ScrollChildren +ScrollDC +ScrollWindow +ScrollWindowEx +SendDlgItemMessageA +SendDlgItemMessageW +SendMessageA +SendMessageCallbackA +SendMessageCallbackW +SendMessageTimeoutA +SendMessageTimeoutW +SendMessageW +SendNotifyMessageA +SendNotifyMessageW +SetActiveWindow +SetCapture +SetCaretBlinkTime +SetCaretPos +SetClassLongA +SetClassLongW +SetClassWord +SetClipboardData +SetClipboardViewer +SetCursor +SetCursorPos +SetDebugErrorLevel +SetDeskWallpaper +SetDlgItemInt +SetDlgItemTextA +SetDlgItemTextW +SetDoubleClickTime +SetFocus +SetForegroundWindow +SetKeyboardState +SetLastErrorEx +SetMenu +SetMenuContextHelpId +_imp__SetMenuContextHelpId +SetMenuDefaultItem +SetMenuItemBitmaps +SetMenuItemInfoA +SetMenuItemInfoW +SetMessageExtraInfo +SetMessageQueue +SetParent +SetProcessWindowStation +SetPropA +SetPropW +SetRect +SetRectEmpty +SetScrollInfo +SetScrollPos +SetScrollRange +SetShellWindow +SetSysColors +SetSystemCursor +SetSystemMenu +SetSystemTimer +SetThreadDesktop +SetTimer +SetUserObjectInformationA +SetUserObjectInformationW +SetUserObjectSecurity +SetWindowContextHelpId +_imp__SetWindowContextHelpId +SetWindowLongA +SetWindowLongW +SetWindowPlacement +SetWindowPos +SetWindowRgn +SetWindowTextA +SetWindowTextW +SetWindowWord +SetWindowsHookA +SetWindowsHookExA +SetWindowsHookExW +SetWindowsHookW +ShowCaret +ShowCursor +ShowOwnedPopups +ShowScrollBar +ShowWindow +ShowWindowAsync +SubtractRect +SwapMouseButton +SwitchDesktop +SystemParametersInfoA +SystemParametersInfoW +TabbedTextOutA +TabbedTextOutW +TileChildWindows +TileWindows +ToAscii +ToAsciiEx +ToUnicode +ToUnicodeEx +TrackMouseEvent +TrackPopupMenu +TrackPopupMenuEx +TranslateAccelerator +TranslateAcceleratorA +TranslateAcceleratorW +TranslateMDISysAccel +TranslateMessage +UnhookWindowsHook +UnhookWindowsHookEx +UnionRect +UnloadKeyboardLayout +UnpackDDElParam +UnregisterClassA +UnregisterClassW +UnregisterHotKey +UpdateWindow +ValidateRect +ValidateRgn +VkKeyScanA +VkKeyScanExA +VkKeyScanExW +VkKeyScanW +WaitForInputIdle +WaitMessage +WinHelpA +WinHelpW +WindowFromDC +WindowFromPoint +keybd_event +mouse_event wsprintfA wsprintfW -wvsprintfA@12 -wvsprintfW@12 +wvsprintfA +wvsprintfW diff --git a/reactos/ntoskrnl/Makefile b/reactos/ntoskrnl/Makefile index a58115f92b9..ed22e7a046e 100644 --- a/reactos/ntoskrnl/Makefile +++ b/reactos/ntoskrnl/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.3 2000/10/22 16:36:48 ekohl Exp $ +# $Id: Makefile,v 1.4 2000/12/10 23:41:59 dwelch Exp $ # # ReactOS Operating System # @@ -92,7 +92,9 @@ OBJECTS_KE_I386 = \ ke/i386/irqhand.o \ ke/i386/thread.o \ ke/i386/usercall.o \ - ke/i386/trap.o + ke/i386/trap.o \ + ke/i386/bthread.o \ + ke/i386/syscall.o # Memory Manager (Mm) OBJECTS_MM = \ @@ -178,7 +180,8 @@ OBJECTS_PS = \ ps/process.o \ ps/psmgr.o \ ps/thread.o \ - ps/tinfo.o + ps/tinfo.o \ + ps/debug.o # Executive Subsystem (Ex) OBJECTS_EX = \ diff --git a/reactos/ntoskrnl/cc/view.c b/reactos/ntoskrnl/cc/view.c index 1cbc953afa4..cc5b048bccb 100644 --- a/reactos/ntoskrnl/cc/view.c +++ b/reactos/ntoskrnl/cc/view.c @@ -1,4 +1,22 @@ -/* $Id: view.c,v 1.10 2000/08/20 17:02:07 dwelch Exp $ +/* + * ReactOS kernel + * Copyright (C) 2000, 1999, 1998 David Welch + * + * 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. + */ +/* $Id: view.c,v 1.11 2000/12/10 23:42:00 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -9,7 +27,29 @@ * Created 22/05/98 */ -/* INCLUDES *****************************************************************/ +/* NOTES ********************************************************************** + * + * This is not the NT implementation of a file cache nor anything much like + * it. + * + * The general procedure for a filesystem to implement a read or write + * dispatch routine is as follows + * + * (1) If caching for the FCB hasn't been initiated then so do by calling + * CcInitializeFileCache. + * + * (2) For each 4k region which is being read or written obtain a cache page + * by calling CcRequestCachePage. + * + * (3) If either the page is being read or not completely written, and it is + * not up to date then read its data from the underlying medium. If the read + * fails then call CcReleaseCachePage with VALID as FALSE and return a error. + * + * (4) Copy the data into or out of the page as necessary. + * + * (5) Release the cache page + */ +/* INCLUDES ******************************************************************/ #include #include @@ -21,7 +61,8 @@ /* FUNCTIONS *****************************************************************/ -NTSTATUS STDCALL CcFlushCachePage(PCACHE_SEGMENT CacheSeg) +NTSTATUS STDCALL +CcFlushCachePage(PCACHE_SEGMENT CacheSeg) /* * FUNCTION: Asks the FSD to flush the contents of the page back to disk */ @@ -36,9 +77,10 @@ NTSTATUS STDCALL CcFlushCachePage(PCACHE_SEGMENT CacheSeg) return(STATUS_NOT_IMPLEMENTED); } -NTSTATUS STDCALL CcReleaseCachePage(PBCB Bcb, - PCACHE_SEGMENT CacheSeg, - BOOLEAN Valid) +NTSTATUS STDCALL +CcReleaseCachePage(PBCB Bcb, + PCACHE_SEGMENT CacheSeg, + BOOLEAN Valid) { DPRINT("CcReleaseCachePage(Bcb %x, CacheSeg %x, Valid %d)\n", Bcb, CacheSeg, Valid); @@ -52,11 +94,15 @@ NTSTATUS STDCALL CcReleaseCachePage(PBCB Bcb, return(STATUS_SUCCESS); } -NTSTATUS STDCALL CcRequestCachePage(PBCB Bcb, - ULONG FileOffset, - PVOID* BaseAddress, - PBOOLEAN UptoDate, - PCACHE_SEGMENT* CacheSeg) +NTSTATUS STDCALL +CcRequestCachePage(PBCB Bcb, + ULONG FileOffset, + PVOID* BaseAddress, + PBOOLEAN UptoDate, + PCACHE_SEGMENT* CacheSeg) +/* + * FUNCTION: Request a page mapping for a BCB + */ { KIRQL oldirql; PLIST_ENTRY current_entry; @@ -105,20 +151,15 @@ NTSTATUS STDCALL CcRequestCachePage(PBCB Bcb, CACHE_SEGMENT_SIZE, PAGE_READWRITE, (PMEMORY_AREA*)¤t->MemoryArea); - CHECKPOINT; current->Valid = FALSE; current->FileOffset = PAGE_ROUND_DOWN(FileOffset); current->Bcb = Bcb; - CHECKPOINT; KeInitializeEvent(¤t->Lock, SynchronizationEvent, FALSE); current->ReferenceCount = 1; - CHECKPOINT; InsertTailList(&Bcb->CacheSegmentListHead, ¤t->ListEntry); - CHECKPOINT; *UptoDate = current->Valid; *BaseAddress = current->BaseAddress; *CacheSeg = current; - CHECKPOINT; MmCreateVirtualMapping(NULL, current->BaseAddress, PAGE_READWRITE, @@ -130,9 +171,12 @@ NTSTATUS STDCALL CcRequestCachePage(PBCB Bcb, return(STATUS_SUCCESS); } -NTSTATUS STDCALL CcFreeCacheSegment(PFILE_OBJECT FileObject, - PBCB Bcb, - PCACHE_SEGMENT CacheSeg) +NTSTATUS STDCALL +CcFreeCacheSegment(PBCB Bcb, + PCACHE_SEGMENT CacheSeg) +/* + * FUNCTION: Releases a cache segment associated with a BCB + */ { MmFreeMemoryArea(NULL, CacheSeg->BaseAddress, @@ -142,8 +186,12 @@ NTSTATUS STDCALL CcFreeCacheSegment(PFILE_OBJECT FileObject, return(STATUS_SUCCESS); } -NTSTATUS STDCALL CcReleaseFileCache(PFILE_OBJECT FileObject, - PBCB Bcb) +NTSTATUS STDCALL +CcReleaseFileCache(PFILE_OBJECT FileObject, + PBCB Bcb) +/* + * FUNCTION: Releases the BCB associated with a file object + */ { PLIST_ENTRY current_entry; PCACHE_SEGMENT current; @@ -156,8 +204,7 @@ NTSTATUS STDCALL CcReleaseFileCache(PFILE_OBJECT FileObject, { current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, ListEntry); current_entry = current_entry->Flink; - CcFreeCacheSegment(FileObject, - Bcb, + CcFreeCacheSegment(Bcb, current); } @@ -168,8 +215,12 @@ NTSTATUS STDCALL CcReleaseFileCache(PFILE_OBJECT FileObject, return(STATUS_SUCCESS); } -NTSTATUS STDCALL CcInitializeFileCache(PFILE_OBJECT FileObject, - PBCB* Bcb) +NTSTATUS STDCALL +CcInitializeFileCache(PFILE_OBJECT FileObject, + PBCB* Bcb) +/* + * FUNCTION: Initializes a BCB for a file object + */ { DPRINT("CcInitializeFileCache(FileObject %x)\n",FileObject); diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index b56babccc20..b89e986398c 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -69,7 +69,9 @@ VOID KeAcquireDispatcherDatabaseLock(BOOLEAN Wait); VOID KeReleaseDispatcherDatabaseLock(BOOLEAN Wait); BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr); +#if 0 VOID KiInterruptDispatch(ULONG irq); +#endif VOID KeExpireTimers(VOID); NTSTATUS KeAddThreadTimeout(struct _KTHREAD* Thread, PLARGE_INTEGER Interval); @@ -82,6 +84,8 @@ VOID KeFreeGdtSelector(ULONG Entry); BOOLEAN KiTestAlert(VOID); VOID KeRemoveAllWaitsThread(struct _ETHREAD* Thread, NTSTATUS WaitStatus); PULONG KeGetStackTopThread(struct _ETHREAD* Thread); +VOID KeContextToTrapFrame(PCONTEXT Context, + PKTRAP_FRAME TrapFrame); /* INITIALIZATION FUNCTIONS *************************************************/ diff --git a/reactos/ntoskrnl/include/internal/ps.h b/reactos/ntoskrnl/include/internal/ps.h index cfd478bb64f..bfa5a58a9ec 100644 --- a/reactos/ntoskrnl/include/internal/ps.h +++ b/reactos/ntoskrnl/include/internal/ps.h @@ -78,14 +78,23 @@ typedef struct _KAPC_STATE typedef struct _KTHREAD { + /* For waiting on thread exit */ DISPATCHER_HEADER DispatcherHeader; /* 00 */ + + /* List of mutants owned by the thread */ LIST_ENTRY MutantListHead; /* 10 */ PVOID InitialStack; /* 18 */ ULONG StackLimit; /* 1C */ + + /* Pointer to the thread's environment block in user memory */ NT_TEB* Teb; /* 20 */ - PVOID TlsArray; /* 24 */ + + /* Pointer to the thread's TLS array */ + PVOID TlsArray; /* 24 */ PVOID KernelStack; /* 28 */ UCHAR DebugActive; /* 2C */ + + /* Thread state (one of THREAD_STATE_xxx constants below) */ UCHAR State; /* 2D */ UCHAR Alerted[2]; /* 2E */ UCHAR Iopl; /* 30 */ @@ -150,12 +159,16 @@ typedef struct _KTHREAD */ /* Added by Phillip Susi for list of threads in a process */ - LIST_ENTRY ProcessThreadListEntry; + LIST_ENTRY ProcessThreadListEntry; + /* Provisionally added by David Welch */ hal_thread_state Context; /* Added by Phillip Susi for internal KeAddThreadTimeout() implementation */ - KDPC TimerDpc; + + KDPC TimerDpc; + /* Record the last EIP value when the thread is suspended */ + ULONG LastEip; } __attribute__((packed)) KTHREAD, *PKTHREAD; // According to documentation the stack should have a commited [ 1 page ] and @@ -400,12 +413,11 @@ ULONG PsResumeThread(PETHREAD Thread, * Functions the HAL must provide */ -VOID -KeInitializeThread(PKPROCESS Process, PKTHREAD Thread); +VOID KeInitializeThread(PKPROCESS Process, PKTHREAD Thread); -void HalInitFirstTask(PETHREAD thread); +VOID HalInitFirstTask(PETHREAD thread); NTSTATUS HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext); -void HalTaskSwitch(PKTHREAD thread); +VOID HalTaskSwitch(PKTHREAD thread); NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context); NTSTATUS HalReleaseTask(PETHREAD Thread); VOID PiDeleteProcess(PVOID ObjectBody); diff --git a/reactos/ntoskrnl/include/internal/vm86.h b/reactos/ntoskrnl/include/internal/vm86.h new file mode 100644 index 00000000000..fda9150623b --- /dev/null +++ b/reactos/ntoskrnl/include/internal/vm86.h @@ -0,0 +1,76 @@ +/* + * ReactOS kernel + * Copyright (C) 2000 David Welch + * + * 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/vm86_sup.S + * PURPOSE: V86 mode support + * PROGRAMMER: David Welch (welch@cwcom.net) + * UPDATE HISTORY: + * Created 10/12/00 + */ + +#ifndef __NTOSKRNL_INCLUDE_INTERNAL_VM86_H +#define __NTOSKRNL_INCLUDE_INTERNAL_VM86_H + +#ifndef ASSEMBLER + +typedef struct +{ + ULONG Ebp; + ULONG Edi; + ULONG Esi; + ULONG Edx; + ULONG Ecx; + ULONG Ebx; + ULONG Eax; + ULONG Ds; + ULONG Es; + ULONG Fs; + ULONG Gs; + ULONG Eip; + ULONG Cs; + ULONG Eflags; + ULONG Esp; + ULONG Ss; +} KV86M_REGISTERS; + +#else + +/* + * Definitions for the offsets of members in the KV86M_REGISTERS + */ +#define KV86M_REGISTERS_EBP (0x0) +#define KV86M_REGISTERS_EDI (0x4) +#define KV86M_REGISTERS_ESI (0x8) +#define KV86M_REGISTERS_EDX (0xC) +#define KV86M_REGISTERS_ECX (0x10) +#define KV86M_REGISTERS_EBX (0x14) +#define KV86M_REGISTERS_EAX (0x18) +#define KV86M_REGISTERS_DS (0x1C) +#define KV86M_REGISTERS_ES (0x20) +#define KV86M_REGISTERS_FS (0x24) +#define KV86M_REGISTERS_GS (0x28) +#define KV86M_REGISTERS_EIP (0x2C) +#define KV86M_REGISTERS_CS (0x30) +#define KV86M_REGISTERS_EFLAGS (0x34) +#define KV86M_REGISTERS_ESP (0x38) +#define KV86M_REGISTERS_SS (0x3C) + +#endif /* ASSEMBLER */ + +#endif /* __NTOSKRNL_INCLUDE_INTERNAL_VM86_H */ diff --git a/reactos/ntoskrnl/ke/dpc.c b/reactos/ntoskrnl/ke/dpc.c index 90f877fc8b6..3ba8e7a6f32 100644 --- a/reactos/ntoskrnl/ke/dpc.c +++ b/reactos/ntoskrnl/ke/dpc.c @@ -1,4 +1,24 @@ -/* $Id: dpc.c,v 1.18 2000/07/10 21:54:19 ekohl Exp $ +/* + * ReactOS kernel + * Copyright (C) 2000, 1999, 1998 David Welch , + * Philip Susi , + * Eric Kohl + * + * 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. + */ +/* $Id: dpc.c,v 1.19 2000/12/10 23:42:00 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -26,15 +46,21 @@ /* GLOBALS ******************************************************************/ -static LIST_ENTRY DpcQueueHead; -static KSPIN_LOCK DpcQueueLock; -ULONG DpcQueueSize = 0; +static LIST_ENTRY DpcQueueHead; /* Head of the list of pending DPCs */ +static KSPIN_LOCK DpcQueueLock; /* Lock for the above list */ +/* + * Number of pending DPCs. This is inspected by + * the idle thread to determine if the queue needs to + * be run down + */ +ULONG DpcQueueSize = 0; /* FUNCTIONS ****************************************************************/ -VOID STDCALL KeInitializeDpc (PKDPC Dpc, - PKDEFERRED_ROUTINE DeferredRoutine, - PVOID DeferredContext) +VOID STDCALL +KeInitializeDpc (PKDPC Dpc, + PKDEFERRED_ROUTINE DeferredRoutine, + PVOID DeferredContext) /* * FUNCTION: Initalizes a DPC * ARGUMENTS: @@ -44,13 +70,14 @@ VOID STDCALL KeInitializeDpc (PKDPC Dpc, * NOTE: Callers must be running at IRQL PASSIVE_LEVEL */ { - Dpc->Type=0; - Dpc->DeferredRoutine=DeferredRoutine; - Dpc->DeferredContext=DeferredContext; - Dpc->Lock=0; + Dpc->Type = 0; + Dpc->DeferredRoutine = DeferredRoutine; + Dpc->DeferredContext = DeferredContext; + Dpc->Lock = 0; } -VOID STDCALL KiDispatchInterrupt(VOID) +VOID STDCALL +KiDispatchInterrupt(VOID) /* * FUNCTION: Called to execute queued dpcs */ @@ -65,38 +92,32 @@ VOID STDCALL KiDispatchInterrupt(VOID) { return; } - DPRINT("KiDispatchInterrupt()\n"); KeRaiseIrql(HIGH_LEVEL, &oldlvl); KeAcquireSpinLockAtDpcLevel(&DpcQueueLock); current_entry = RemoveHeadList(&DpcQueueHead); + DpcQueueSize--; KeReleaseSpinLockFromDpcLevel(&DpcQueueLock); KeLowerIrql(oldlvl); current = CONTAINING_RECORD(current_entry,KDPC,DpcListEntry); while (current_entry!=(&DpcQueueHead)) { - CHECKPOINT; - DPRINT("DpcQueueSize %d current %x current->DeferredContext %x\n", - DpcQueueSize, current, current->DeferredContext); - DPRINT("current->Flink %x\n", current->DpcListEntry.Flink); current->DeferredRoutine(current,current->DeferredContext, current->SystemArgument1, current->SystemArgument2); - CHECKPOINT; current->Lock=FALSE; KeRaiseIrql(HIGH_LEVEL, &oldlvl); KeAcquireSpinLockAtDpcLevel(&DpcQueueLock); current_entry = RemoveHeadList(&DpcQueueHead); - DPRINT("current_entry %x\n", current_entry); DpcQueueSize--; KeReleaseSpinLockFromDpcLevel(&DpcQueueLock); KeLowerIrql(oldlvl); current = CONTAINING_RECORD(current_entry,KDPC,DpcListEntry); - DPRINT("current %x\n", current); } } -BOOLEAN STDCALL KeRemoveQueueDpc (PKDPC Dpc) +BOOLEAN STDCALL +KeRemoveQueueDpc (PKDPC Dpc) /* * FUNCTION: Removes DPC object from the system dpc queue * ARGUMENTS: @@ -121,9 +142,10 @@ BOOLEAN STDCALL KeRemoveQueueDpc (PKDPC Dpc) return(TRUE); } -BOOLEAN STDCALL KeInsertQueueDpc (PKDPC Dpc, - PVOID SystemArgument1, - PVOID SystemArgument2) +BOOLEAN STDCALL +KeInsertQueueDpc (PKDPC Dpc, + PVOID SystemArgument1, + PVOID SystemArgument2) /* * FUNCTION: Queues a DPC for execution when the IRQL of a processor * drops below DISPATCH_LEVEL @@ -167,12 +189,9 @@ BOOLEAN STDCALL KeInsertQueueDpc (PKDPC Dpc, * Importance = DPC importance * RETURNS: None */ -VOID -STDCALL -KeSetImportanceDpc ( - IN PKDPC Dpc, - IN KDPC_IMPORTANCE Importance - ) +VOID STDCALL +KeSetImportanceDpc (IN PKDPC Dpc, + IN KDPC_IMPORTANCE Importance) { Dpc->Importance = Importance; } @@ -184,17 +203,15 @@ KeSetImportanceDpc ( * Number = Processor number * RETURNS: None */ -VOID -STDCALL -KeSetTargetProcessorDpc ( - IN PKDPC Dpc, - IN CCHAR Number - ) +VOID STDCALL +KeSetTargetProcessorDpc (IN PKDPC Dpc, + IN CCHAR Number) { UNIMPLEMENTED; } -VOID KeInitDpc(VOID) +VOID +KeInitDpc(VOID) /* * FUNCTION: Initialize DPC handling */ diff --git a/reactos/ntoskrnl/ke/i386/bthread.S b/reactos/ntoskrnl/ke/i386/bthread.S new file mode 100644 index 00000000000..0d43b9db256 --- /dev/null +++ b/reactos/ntoskrnl/ke/i386/bthread.S @@ -0,0 +1,64 @@ +/* + * ReactOS kernel + * Copyright (C) 2000 David Welch + * + * 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. + */ +/* $Id: bthread.S,v 1.1 2000/12/10 23:42:00 dwelch Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/hal/x86/bthread.s + * PURPOSE: Trap handlers + * PROGRAMMER: David Welch (david.welch@seh.ox.ac.uk) + * UPDATE HISTORY: + * ??? + */ + +#include +#include +#include +#include + +/* + * + */ + +.globl _PsBeginThreadWithContextInternal + +_PsBeginThreadWithContextInternal: + call _PiBeforeBeginThread + popl %eax + popl %eax + popl %eax + popl %eax + popl %eax + popl %eax + popl %eax + addl $112,%esp + popl %gs +; popl %fs + movl $TEB_SELECTOR, %ax + movl %ax, %fs + popl %es + popl %ds + popl %edi + popl %esi + popl %ebx + popl %edx + popl %ecx + popl %eax + popl %ebp + iret diff --git a/reactos/ntoskrnl/ke/i386/irq.c b/reactos/ntoskrnl/ke/i386/irq.c index e1a9a53cd43..4fe924e20cd 100644 --- a/reactos/ntoskrnl/ke/i386/irq.c +++ b/reactos/ntoskrnl/ke/i386/irq.c @@ -1,4 +1,4 @@ -/* $Id: irq.c,v 1.2 2000/07/24 23:51:46 ekohl Exp $ +/* $Id: irq.c,v 1.3 2000/12/10 23:42:00 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -103,8 +103,27 @@ VOID KeInitInterrupts (VOID) } } +typedef struct _KIRQ_TRAPFRAME +{ + ULONG Magic; + ULONG Fs; + ULONG Es; + ULONG Ds; + ULONG Eax; + ULONG Ecx; + ULONG Edx; + ULONG Ebx; + ULONG Esp; + ULONG Ebp; + ULONG Esi; + ULONG Edi; + ULONG Eip; + ULONG Cs; + ULONG Eflags; +} KIRQ_TRAPFRAME, *PKIRQ_TRAPFRAME; -VOID KiInterruptDispatch (ULONG irq) +VOID +KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe) /* * FUNCTION: Calls the irq specific handler for an irq * ARGUMENTS: @@ -175,6 +194,10 @@ VOID KiInterruptDispatch (ULONG irq) { KeExpireTimers(); } + if (KeGetCurrentThread() != NULL) + { + KeGetCurrentThread()->LastEip = Trapframe->Eip; + } KiDispatchInterrupt(); PsDispatchThread(THREAD_STATE_RUNNABLE); } @@ -188,7 +211,8 @@ VOID KiInterruptDispatch (ULONG irq) } -static VOID KeDumpIrqList(VOID) +static VOID +KeDumpIrqList(VOID) { PKINTERRUPT current; PLIST_ENTRY current_entry; @@ -210,8 +234,7 @@ static VOID KeDumpIrqList(VOID) } -NTSTATUS -STDCALL +NTSTATUS STDCALL KeConnectInterrupt(PKINTERRUPT InterruptObject) { KIRQL oldlvl; @@ -266,8 +289,7 @@ KeConnectInterrupt(PKINTERRUPT InterruptObject) } -VOID -STDCALL +VOID STDCALL KeDisconnectInterrupt(PKINTERRUPT InterruptObject) /* * FUNCTION: Releases a drivers isr diff --git a/reactos/ntoskrnl/ke/i386/irqhand.c b/reactos/ntoskrnl/ke/i386/irqhand.c index 58582b459d9..7417cf0be0b 100644 --- a/reactos/ntoskrnl/ke/i386/irqhand.c +++ b/reactos/ntoskrnl/ke/i386/irqhand.c @@ -23,11 +23,13 @@ "movw %ax,%es\n\t" \ "inb $0x21,%al\n\t" \ "orb $1<<"##x",%al\n\t" \ - "outb %al,$0x21\n\t" \ + "outb %al,$0x21\n\t" \ + "pushl %esp\n\t" \ "pushl $"##x"\n\t" \ "call _KiInterruptDispatch\n\t"\ "popl %eax\n\t" \ "popl %eax\n\t" \ + "popl %eax\n\t" \ "popl %fs\n\t" \ "popl %es\n\t" \ "popl %ds\n\t" \ @@ -49,10 +51,12 @@ "inb $0xa1,%al\n\t" \ "orb $1<<("##x"-8),%al\n\t" \ "outb %al,$0xa1\n\t" \ + "pushl %esp\n\t" \ "pushl $"##x"\n\t" \ "call _KiInterruptDispatch\n\t"\ "popl %eax\n\t" \ "popl %eax\n\t" \ + "popl %eax\n\t" \ "popl %fs\n\t" \ "popl %es\n\t" \ "popl %ds\n\t" \ diff --git a/reactos/ntoskrnl/ke/i386/syscall.S b/reactos/ntoskrnl/ke/i386/syscall.S new file mode 100644 index 00000000000..362dcf515b0 --- /dev/null +++ b/reactos/ntoskrnl/ke/i386/syscall.S @@ -0,0 +1,246 @@ +/* + * ReactOS kernel + * Copyright (C) 2000 David Welch + * + * 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. + */ +/* $Id: syscall.S,v 1.1 2000/12/10 23:42:00 dwelch Exp $ + * + * FILE: ntoskrnl/hal/x86/syscall.s + * PURPOSE: 2E trap handler + * PROGRAMMER: David Welch (david.welch@seh.ox.ac.uk) + * UPDATE HISTORY: + * ??? + */ + +#include +#include +#include +#include + +/* + * + */ +.globl _interrupt_handler2e +_interrupt_handler2e: + + /* Construct a trap frame on the stack */ + + /* Error code */ + pushl $0 + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + pushl %fs + /* Load PCR selector into fs */ + movl $PCR_SELECTOR, %ebx + movl %ebx, %fs + + /* Save the old exception list */ + movl %fs:KPCR_EXCEPTION_LIST, %ebx + pushl %ebx + /* Put the exception handler chain terminator */ + movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST + /* Get a pointer to the current thread */ + movl %fs:KPCR_CURRENT_THREAD, %esi + /* Save the old previous mode */ + movl $0, %ebx + movb %ss:KTHREAD_PREVIOUS_MODE(%esi), %bl + pushl %ebx + /* Set the new previous mode based on the saved CS selector */ + movl 0x24(%esp), %ebx + cmpl $KERNEL_CS, %ebx + jne L1 + movb $KernelMode, %ss:KTHREAD_PREVIOUS_MODE(%esi) + jmp L3 +L1: + movb $UserMode, %ss:KTHREAD_PREVIOUS_MODE(%esi) +L3: + + /* Save other registers */ + pushl %eax + pushl %ecx + pushl %edx + pushl %ds + pushl %es + pushl %gs + pushl $0 /* DR7 */ + pushl $0 /* DR6 */ + pushl $0 /* DR3 */ + pushl $0 /* DR2 */ + pushl $0 /* DR1 */ + pushl $0 /* DR0 */ + pushl $0 /* XXX: TempESP */ + pushl $0 /* XXX: TempCS */ + pushl $0 /* XXX: DebugPointer */ + pushl $0 /* XXX: DebugArgMark */ + pushl $0 /* XXX: DebugEIP */ + pushl $0 /* XXX: DebugEBP */ + + /* Load the segment registers */ + movl $KERNEL_DS, %ebx + movl %ebx, %ds + movl %ebx, %es + movl %ebx, %gs + + /* Save the old trap frame pointer (over the EDX register??) */ + movl KTHREAD_TRAP_FRAME(%esi), %ebx + movl %ebx, 0x3C(%esp) + + /* Save a pointer to the trap frame in the TCB */ + movl %esp, KTHREAD_TRAP_FRAME(%esi) + + /* Set ES to kernel segment */ + movw $KERNEL_DS,%bx + movw %bx,%es + + /* Allocate new Kernel stack frame */ + movl %esp,%ebp + + /* Users's current stack frame pointer is source */ + movl %edx,%esi + + /* Determine system service table to use */ + cmpl $0x0fff, %eax + ja new_useShadowTable + + /* Check to see if EAX is valid/inrange */ + cmpl %es:_KeServiceDescriptorTable + 8, %eax + jbe new_serviceInRange + movl $STATUS_INVALID_SYSTEM_SERVICE, %eax + jmp new_done + +new_serviceInRange: + + /* Allocate room for argument list from kernel stack */ + movl %es:_KeServiceDescriptorTable + 12, %ecx + movl %es:(%ecx, %eax, 4), %ecx + subl %ecx, %esp + + /* Copy the arguments from the user stack to the kernel stack */ + movl %esp,%edi + rep movsb + + /* DS is now also kernel segment */ + movw %bx, %ds + + /* Call system call hook */ + pushl %eax + call _KiSystemCallHook + popl %eax + + /* Make the system service call */ + movl %es:_KeServiceDescriptorTable, %ecx + movl %es:(%ecx, %eax, 4), %eax + call *%eax + +#if CHECKED + /* Bump Service Counter */ +#endif + + /* Deallocate the kernel stack frame */ + movl %ebp,%esp + + /* Call the post system call hook and deliver any pending APCs */ + pushl %ebp + pushl %eax + call _KiAfterSystemCallHook + addl $8,%esp + + jmp new_done + +new_useShadowTable: + + subl $0x1000, %eax + + /* Check to see if EAX is valid/inrange */ + cmpl %es:_KeServiceDescriptorTableShadow + 24, %eax + jbe new_shadowServiceInRange + movl $STATUS_INVALID_SYSTEM_SERVICE, %eax + jmp new_done + +new_shadowServiceInRange: + + /* Allocate room for argument list from kernel stack */ + movl %es:_KeServiceDescriptorTableShadow + 28, %ecx + movl %es:(%ecx, %eax, 4), %ecx + subl %ecx, %esp + + /* Copy the arguments from the user stack to the kernel stack */ + movl %esp,%edi + rep movsb + + /* DS is now also kernel segment */ + movw %bx,%ds + + /* Call system call hook */ + pushl %eax + call _KiSystemCallHook + popl %eax + + /* Make the system service call */ + movl %es:_KeServiceDescriptorTableShadow + 16, %ecx + movl %es:(%ecx, %eax, 4), %eax + call *%eax + +#if CHECKED + /* Bump Service Counter */ +#endif + + /* Deallocate the kernel stack frame */ + movl %ebp,%esp + + /* Call the post system call hook and deliver any pending APCs */ + pushl %esp + pushl %eax + call _KiAfterSystemCallHook + addl $8,%esp + +new_done: + + /* Restore the user context */ + /* Get a pointer to the current thread */ + movl %fs:0x124, %esi + + /* Restore the old trap frame pointer */ + movl 0x3c(%esp), %ebx + movl %ebx, KTHREAD_TRAP_FRAME(%esi) + + /* Skip debug information and unsaved registers */ + addl $0x30, %esp + popl %gs + popl %es + popl %ds + popl %edx + popl %ecx + addl $0x4, %esp /* Don't restore eax */ + + /* Restore the old previous mode */ + popl %ebx + movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi) + + /* Restore the old exception handler list */ + popl %ebx + movl %ebx, %fs:KPCR_EXCEPTION_LIST + + popl %fs + popl %edi + popl %esi + popl %ebx + popl %ebp + addl $0x4, %esp /* Ignore error code */ + + iret diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index d700a986c33..af00c698dbb 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -1,9 +1,27 @@ -/* $Id: trap.s,v 1.4 2000/10/11 20:50:34 dwelch Exp $ +/* + * ReactOS kernel + * Copyright (C) 2000 David Welch + * + * 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. + */ +/* $Id: trap.s,v 1.5 2000/12/10 23:42:00 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: ntoskrnl/hal/x86/trap.s - * PURPOSE: 2E trap handler + * PURPOSE: Exception handlers * PROGRAMMER: David Welch (david.welch@seh.ox.ac.uk) * UPDATE HISTORY: * ??? @@ -15,440 +33,34 @@ #include /* - * + * Epilog for exception handlers */ - -.globl _PsBeginThreadWithContextInternal - -_PsBeginThreadWithContextInternal: - call _PiBeforeBeginThread - popl %eax - popl %eax - popl %eax - popl %eax - popl %eax - popl %eax - popl %eax - addl $112,%esp - popl %gs -; popl %fs - movl $TEB_SELECTOR, %ax - movl %ax, %fs - popl %es - popl %ds - popl %edi - popl %esi - popl %ebx - popl %edx - popl %ecx - popl %eax - popl %ebp - iret - -/* - * - */ -.globl _interrupt_handler2e -_interrupt_handler2e: - - /* Construct a trap frame on the stack */ - - /* Error code */ - pushl $0 - pushl %ebp - pushl %ebx - pushl %esi - pushl %edi - pushl %fs - /* Load PCR selector into fs */ - movl $PCR_SELECTOR, %ebx - movl %ebx, %fs - - /* Save the old exception list */ - movl %fs:KPCR_EXCEPTION_LIST, %ebx - pushl %ebx - /* Put the exception handler chain terminator */ - movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST - /* Get a pointer to the current thread */ - movl %fs:KPCR_CURRENT_THREAD, %esi - /* Save the old previous mode */ - movl $0, %ebx - movb %ss:KTHREAD_PREVIOUS_MODE(%esi), %bl - pushl %ebx - /* Set the new previous mode based on the saved CS selector */ - movl 0x24(%esp), %ebx - cmpl $KERNEL_CS, %ebx - jne L1 - movb $KernelMode, %ss:KTHREAD_PREVIOUS_MODE(%esi) - jmp L3 -L1: - movb $UserMode, %ss:KTHREAD_PREVIOUS_MODE(%esi) -L3: - - /* Save other registers */ - pushl %eax - pushl %ecx - pushl %edx - pushl %ds - pushl %es - pushl %gs - pushl $0 /* DR7 */ - pushl $0 /* DR6 */ - pushl $0 /* DR3 */ - pushl $0 /* DR2 */ - pushl $0 /* DR1 */ - pushl $0 /* DR0 */ - pushl $0 /* XXX: TempESP */ - pushl $0 /* XXX: TempCS */ - pushl $0 /* XXX: DebugPointer */ - pushl $0 /* XXX: DebugArgMark */ - pushl $0 /* XXX: DebugEIP */ - pushl $0 /* XXX: DebugEBP */ - - /* Load the segment registers */ - movl $KERNEL_DS, %ebx - movl %ebx, %ds - movl %ebx, %es - movl %ebx, %gs - - /* Save the old trap frame pointer (over the EDX register??) */ - movl KTHREAD_TRAP_FRAME(%esi), %ebx - movl %ebx, 0x3C(%esp) - - /* Save a pointer to the trap frame in the TCB */ - movl %esp, KTHREAD_TRAP_FRAME(%esi) - - /* Set ES to kernel segment */ - movw $KERNEL_DS,%bx - movw %bx,%es - - /* Allocate new Kernel stack frame */ - movl %esp,%ebp - - /* Users's current stack frame pointer is source */ - movl %edx,%esi - - /* Determine system service table to use */ - cmpl $0x0fff, %eax - ja new_useShadowTable - - /* Check to see if EAX is valid/inrange */ - cmpl %es:_KeServiceDescriptorTable + 8, %eax - jbe new_serviceInRange - movl $STATUS_INVALID_SYSTEM_SERVICE, %eax - jmp new_done - -new_serviceInRange: - - /* Allocate room for argument list from kernel stack */ - movl %es:_KeServiceDescriptorTable + 12, %ecx - movl %es:(%ecx, %eax, 4), %ecx - subl %ecx, %esp - - /* Copy the arguments from the user stack to the kernel stack */ - movl %esp,%edi - rep movsb - - /* DS is now also kernel segment */ - movw %bx, %ds - - /* Call system call hook */ - pushl %eax - call _KiSystemCallHook - popl %eax - - /* Make the system service call */ - movl %es:_KeServiceDescriptorTable, %ecx - movl %es:(%ecx, %eax, 4), %eax - call *%eax - -#if CHECKED - /* Bump Service Counter */ -#endif - - /* Deallocate the kernel stack frame */ - movl %ebp,%esp - - /* Call the post system call hook and deliver any pending APCs */ - pushl %ebp - pushl %eax - call _KiAfterSystemCallHook - addl $8,%esp - - jmp new_done - -new_useShadowTable: - - subl $0x1000, %eax - - /* Check to see if EAX is valid/inrange */ - cmpl %es:_KeServiceDescriptorTableShadow + 24, %eax - jbe new_shadowServiceInRange - movl $STATUS_INVALID_SYSTEM_SERVICE, %eax - jmp new_done - -new_shadowServiceInRange: - - /* Allocate room for argument list from kernel stack */ - movl %es:_KeServiceDescriptorTableShadow + 28, %ecx - movl %es:(%ecx, %eax, 4), %ecx - subl %ecx, %esp - - /* Copy the arguments from the user stack to the kernel stack */ - movl %esp,%edi - rep movsb - - /* DS is now also kernel segment */ - movw %bx,%ds - - /* Call system call hook */ - pushl %eax - call _KiSystemCallHook - popl %eax - - /* Make the system service call */ - movl %es:_KeServiceDescriptorTableShadow + 16, %ecx - movl %es:(%ecx, %eax, 4), %eax - call *%eax - -#if CHECKED - /* Bump Service Counter */ -#endif - - /* Deallocate the kernel stack frame */ - movl %ebp,%esp - - /* Call the post system call hook and deliver any pending APCs */ - pushl %esp - pushl %eax - call _KiAfterSystemCallHook - addl $8,%esp - -new_done: - - /* Restore the user context */ - /* Get a pointer to the current thread */ - movl %fs:0x124, %esi - - /* Restore the old trap frame pointer */ - movl 0x3c(%esp), %ebx - movl %ebx, KTHREAD_TRAP_FRAME(%esi) - - /* Skip debug information and unsaved registers */ - addl $0x30, %esp - popl %gs - popl %es - popl %ds - popl %edx - popl %ecx - addl $0x4, %esp /* Don't restore eax */ - - /* Restore the old previous mode */ - popl %ebx - movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi) - - /* Restore the old exception handler list */ - popl %ebx - movl %ebx, %fs:KPCR_EXCEPTION_LIST - - popl %fs - popl %edi - popl %esi - popl %ebx - popl %ebp - addl $0x4, %esp /* Ignore error code */ - - iret - -/* - * - */ -.globl _old_interrupt_handler2e -_old_interrupt_handler2e: - - /* Save the user context */ - pushl %ebp /* Ebp */ - - pushl %eax /* Eax */ - pushl %ecx /* Ecx */ - pushl %edx /* Edx */ - pushl %ebx /* Ebx */ - pushl %esi /* Esi */ - pushl %edi /* Edi */ - - pushl %ds /* SegDs */ - pushl %es /* SegEs */ - pushl %fs /* SegFs */ - pushl %gs /* SegGs */ - - subl $112,%esp /* FloatSave */ - - pushl $0 /* Dr7 */ - pushl $0 /* Dr6 */ - pushl $0 /* Dr3 */ - pushl $0 /* Dr2 */ - pushl $0 /* Dr1 */ - pushl $0 /* Dr0 */ - - pushl $0 /* ContextFlags */ - - /* Set ES to kernel segment */ - movw $KERNEL_DS,%bx - movw %bx,%es - - /* Save pointer to user context as argument to system call */ - pushl %esp - - /* Allocate new Kernel stack frame */ - movl %esp,%ebp - - /* Users's current stack frame pointer is source */ - movl %edx,%esi - - /* Determine system service table to use */ - cmpl $0x0fff, %eax - ja useShadowTable - - /* Check to see if EAX is valid/inrange */ - cmpl %es:_KeServiceDescriptorTable + 8, %eax - jbe serviceInRange - movl $STATUS_INVALID_SYSTEM_SERVICE, %eax - jmp done - -serviceInRange: - - /* Allocate room for argument list from kernel stack */ - movl %es:_KeServiceDescriptorTable + 12, %ecx - movl %es:(%ecx, %eax, 4), %ecx - subl %ecx, %esp - - /* Copy the arguments from the user stack to the kernel stack */ - movl %esp,%edi - rep movsb - - /* DS is now also kernel segment */ - movw %bx, %ds - - /* Call system call hook */ - pushl %eax - call _KiSystemCallHook - popl %eax - - /* Make the system service call */ - movl %es:_KeServiceDescriptorTable, %ecx - movl %es:(%ecx, %eax, 4), %eax - call *%eax - -#if CHECKED - /* Bump Service Counter */ -#endif - - /* Deallocate the kernel stack frame */ - movl %ebp,%esp - - /* Call the post system call hook and deliver any pending APCs */ - pushl %eax - call _KiAfterSystemCallHook - addl $8,%esp - - jmp done - -useShadowTable: - - subl $0x1000, %eax - - /* Check to see if EAX is valid/inrange */ - cmpl %es:_KeServiceDescriptorTableShadow + 24, %eax - jbe shadowServiceInRange - movl $STATUS_INVALID_SYSTEM_SERVICE, %eax - jmp done - -shadowServiceInRange: - - /* Allocate room for argument list from kernel stack */ - movl %es:_KeServiceDescriptorTableShadow + 28, %ecx - movl %es:(%ecx, %eax, 4), %ecx - subl %ecx, %esp - - /* Copy the arguments from the user stack to the kernel stack */ - movl %esp,%edi - rep movsb - - /* DS is now also kernel segment */ - movw %bx,%ds - - /* Call system call hook */ - pushl %eax - call _KiSystemCallHook - popl %eax - - /* Make the system service call */ - movl %es:_KeServiceDescriptorTableShadow + 16, %ecx - movl %es:(%ecx, %eax, 4), %eax - call *%eax - -#if CHECKED - /* Bump Service Counter */ -#endif - - /* Deallocate the kernel stack frame */ - movl %ebp,%esp - - /* Call the post system call hook and deliver any pending APCs */ - pushl %eax - call _KiAfterSystemCallHook - addl $8,%esp - -done: - - /* Restore the user context */ - addl $4,%esp /* UserContext */ - addl $24,%esp /* Dr[0-3,6-7] */ - addl $112,%esp /* FloatingSave */ - popl %gs /* SegGs */ - popl %fs /* SegFs */ - popl %es /* SegEs */ - popl %ds /* SegDs */ - - popl %edi /* Edi */ - popl %esi /* Esi */ - popl %ebx /* Ebx */ - popl %edx /* Edx */ - popl %ecx /* Ecx */ - addl $4,%esp /* Eax (Not restored) */ - - popl %ebp /* Ebp */ - - iret - - -/* - * - */ - +_exception_handler_epilog: + popa + addl $4, %esp + popl %ds + popl %es + popl %fs + popl %gs + addl $4, %esp + iret + .globl _exception_handler0 _exception_handler0: - pushl $0 - pushl %gs - pushl %fs - pushl %es - pushl %ds - pushl $0 - pusha - movw $KERNEL_DS,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - call _exception_handler - popa - addl $4,%esp - popl %ds - popl %es - popl %fs - popl %gs - addl $4,%esp - iret + pushl $0 + pushl %gs + pushl %fs + pushl %es + pushl %ds + pushl $0 + pusha + movw $KERNEL_DS,%ax + movw %ax,%ds + movw %ax,%es + movw %ax,%fs + movw %ax,%gs + call _exception_handler + jmp _exception_handler_epilog .globl _exception_handler1 _exception_handler1: diff --git a/reactos/ntoskrnl/ke/i386/tskswitch.S b/reactos/ntoskrnl/ke/i386/tskswitch.S new file mode 100644 index 00000000000..ae107ee76fb --- /dev/null +++ b/reactos/ntoskrnl/ke/i386/tskswitch.S @@ -0,0 +1,84 @@ +/* + * ReactOS kernel + * Copyright (C) 2000 David Welch + * + * 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 +#include + +/* FUNCTIONS ****************************************************************/ + +.globl _Ki386ContextSwitch +_Ki386ContextSwitch: +/* + * FUNCTIONS: Switches to another thread's context + * ARGUMENTS: + * Thread = Thread to switch to + * OldThread = Thread to switch from + */ + pushl %ebp + movl %esp, %ebp + + /* + * Save callee save register + */ + pushl %ebx + pushl %esi + pushl %edi + + /* + * FIXME: Save debugging state + */ + + /* + * FIXME: Save floating point state + */ + + /* + * Switch stacks + */ + movl 12(%ebp), %ebx + movl %esp, KTHREAD_KERNEL_STACK(%ebx) + movl 8(%ebp), %ebx + movl KTHREAD_KERNEL_STACK(%ebx), %esp + + /* + * FIXME: Restore floating point state + */ + + /* + * FIXME: Restore debugging state + */ + + /* + * Restore the saved register and exit + */ + popl %edi + popl %esi + popl %ebx + movl %ebp, %esp + popl %esp + ret diff --git a/reactos/ntoskrnl/ke/i386/vm86_sup.S b/reactos/ntoskrnl/ke/i386/vm86_sup.S new file mode 100644 index 00000000000..89b3f415419 --- /dev/null +++ b/reactos/ntoskrnl/ke/i386/vm86_sup.S @@ -0,0 +1,142 @@ +/* + * ReactOS kernel + * Copyright (C) 2000 David Welch + * + * 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/vm86_sup.S + * PURPOSE: V86 mode support + * PROGRAMMER: David Welch (welch@cwcom.net) + * UPDATE HISTORY: + * Created 09/10/00 + */ + +#include + +.globl _Ki386RetToV86Mode + + /* + * NTSTATUS Ki386RetToV86Mode(KV86M_REGISTERS* in_regs, + * KV86M_REGISTERS* out_regs); + * + * Starts in v86 mode with the registers set to the + * specified values. + */ +_Ki386RetToV86Mode: + /* + * Setup a stack frame + */ + pushl %ebp + movl %esp, %ebp + + /* + * Save registers + */ + pusha + + /* + * Get a pointer to IN_REGS + */ + movl 8(%ebp), %ebx + + /* + * Save ebp + */ + pushl %ebp + + /* + * The stack used for handling exceptions from v86 mode in this thread + * will be the current stack adjusted so we don't overwrite the + * existing stack frames + */ + movl %esp, TSS_ESP0(%esi) + + /* + * Create the stack frame for an iret to v86 mode + */ + pushl GS(%ebx) + pushl FS(%ebx) + pushl DS(%ebx) + pushl ES(%ebx) + pushl SS(%ebx) + pushl ESP(%ebx) + pushl EFLAGS(%ebx) + pushl CS(%ebx) + pushl EIP(%ebx) + + /* + * Setup the CPU registers + */ + movl EAX(%ebx), %eax + movl ECX(%ebx), %ecx + movl EDX(%ebx), %edx + movl ESI(%ebx), %esi + movl EDI(%ebx), %edi + movl EBP(%ebx), %ebp + movl EBX(%ebx), %ebx + + /* + * Go to v86 mode + */ + iret + + /* + * Handle the completion of a vm86 routine. We are called from + * an exception handler with the registers at the point of the + * exception on the stack. + */ +_vm86_complete: + addl $4, %esp /* Ignore pointer to registers */ + addl $4, %esp /* Ignore exception number */ + + /* Get a pointer to the vm86_registers structure */ + movl _vm86_old_ebp, %ebp + movl 8(%ebp), %ebx + + /* Save the vm86 registers into the vm86_registers structure */ + popl EBP(%ebx) + popl EDI(%ebx) + popl ESI(%ebx) + popl EDX(%ebx) + popl ECX(%ebx) + popl EBX(%ebx) + popl EAX(%ebx) + addl $16, %esp /* Ignore 32-bit segment registers */ + addl $4, %esp /* Ignore error code */ + + popl EIP(%ebx) + popl CS(%ebx) + popl EFLAGS(%ebx) + popl ESP(%ebx) + popl SS(%ebx) + popl ES(%ebx) + popl DS(%ebx) + popl FS(%ebx) + popl GS(%ebx) + + /* Swap back to the stack */ + cli + movl _vm86_old_esp, %esp + sti + movl _vm86_old_ebp, %ebp + + /* Return to caller */ + popa + movl %ebp, %esp + popl %ebp + ret + + diff --git a/reactos/ntoskrnl/ke/kthread.c b/reactos/ntoskrnl/ke/kthread.c index a8f7512c7db..b8306c1d268 100644 --- a/reactos/ntoskrnl/ke/kthread.c +++ b/reactos/ntoskrnl/ke/kthread.c @@ -149,7 +149,8 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread) Thread->ProcessThreadListEntry.Blink = NULL; KeInitializeDpc(&Thread->TimerDpc, (PKDEFERRED_ROUTINE)PiTimeoutThread, Thread); - + Thread->LastEip = 0; + /* * Do x86 specific part */ diff --git a/reactos/ntoskrnl/lpc/close.c b/reactos/ntoskrnl/lpc/close.c index cdbfb621a51..2715e15ae75 100644 --- a/reactos/ntoskrnl/lpc/close.c +++ b/reactos/ntoskrnl/lpc/close.c @@ -1,4 +1,4 @@ -/* $Id: close.c,v 1.2 2000/10/22 16:36:51 ekohl Exp $ +/* $Id: close.c,v 1.3 2000/12/10 23:42:00 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -33,54 +33,46 @@ * */ VOID -NiClosePort ( - PVOID ObjectBody, - ULONG HandleCount - ) +NiClosePort (PVOID ObjectBody, + ULONG HandleCount) { - PEPORT Port = (PEPORT) ObjectBody; - LPC_MESSAGE Message; + PEPORT Port = (PEPORT) ObjectBody; + LPC_MESSAGE Message; -// DPRINT1("NiClosePort(ObjectBody %x, HandleCount %d) RefCount %d\n", -// ObjectBody, HandleCount, ObGetReferenceCount(Port)); + // DPRINT1("NiClosePort(ObjectBody %x, HandleCount %d) RefCount %d\n", + // ObjectBody, HandleCount, ObGetReferenceCount(Port)); - if ( (HandleCount == 0) - && (Port->State == EPORT_CONNECTED_CLIENT) - && (ObGetReferenceCount(Port) == 2) - ) - { -// DPRINT1("All handles closed to client port\n"); + if ((HandleCount == 0) && + (Port->State == EPORT_CONNECTED_CLIENT) && + (ObGetReferenceCount(Port) == 2)) + { + // DPRINT1("All handles closed to client port\n"); - Message.MessageSize = sizeof(LPC_MESSAGE); - Message.DataSize = 0; + Message.MessageSize = sizeof(LPC_MESSAGE); + Message.DataSize = 0; - EiReplyOrRequestPort ( - Port->OtherPort, - & Message, - LPC_PORT_CLOSED, - Port - ); - KeSetEvent ( - & Port->OtherPort->Event, - IO_NO_INCREMENT, - FALSE - ); + EiReplyOrRequestPort (Port->OtherPort, + &Message, + LPC_PORT_CLOSED, + Port); + KeSetEvent (&Port->OtherPort->Event, + IO_NO_INCREMENT, + FALSE); - Port->OtherPort->OtherPort = NULL; - Port->OtherPort->State = EPORT_DISCONNECTED; - ObDereferenceObject (Port); - } - if ( (HandleCount == 0) - && (Port->State == EPORT_CONNECTED_SERVER) - && (ObGetReferenceCount(Port) == 2) - ) - { -// DPRINT("All handles closed to server\n"); + Port->OtherPort->OtherPort = NULL; + Port->OtherPort->State = EPORT_DISCONNECTED; + ObDereferenceObject (Port); + } + if ((HandleCount == 0) && + (Port->State == EPORT_CONNECTED_SERVER) && + (ObGetReferenceCount(Port) == 2)) + { + // DPRINT("All handles closed to server\n"); - Port->OtherPort->OtherPort = NULL; - Port->OtherPort->State = EPORT_DISCONNECTED; - ObDereferenceObject(Port->OtherPort); - } + Port->OtherPort->OtherPort = NULL; + Port->OtherPort->State = EPORT_DISCONNECTED; + ObDereferenceObject(Port->OtherPort); + } } @@ -97,13 +89,11 @@ NiClosePort ( * */ VOID -NiDeletePort ( - PVOID ObjectBody - ) +NiDeletePort (PVOID ObjectBody) { -// PEPORT Port = (PEPORT)ObjectBody; + // PEPORT Port = (PEPORT)ObjectBody; -// DPRINT1("Deleting port %x\n", Port); + // DPRINT1("Deleting port %x\n", Port); } diff --git a/reactos/ntoskrnl/ps/debug.c b/reactos/ntoskrnl/ps/debug.c new file mode 100644 index 00000000000..a751514bfba --- /dev/null +++ b/reactos/ntoskrnl/ps/debug.c @@ -0,0 +1,268 @@ +/* + * ReactOS kernel + * Copyright (C) 2000, 1999, 1998 David Welch , + * Philip Susi + * + * 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. + */ +/* $Id: debug.c,v 1.1 2000/12/10 23:42:01 dwelch Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/ps/debug.c + * PURPOSE: Thread managment + * PROGRAMMER: David Welch (welch@mcmail.com) + * REVISION HISTORY: + * 23/06/98: Created + * 12/10/99: Phillip Susi: Thread priorities, and APC work + */ + +/* + * NOTE: + * + * All of the routines that manipulate the thread queue synchronize on + * a single spinlock + * + */ + +/* INCLUDES ****************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#define NDEBUG +#include + +/* FUNCTIONS ***************************************************************/ + +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) +/* + * FUNCTION: This routine is called by an APC sent by NtGetContextThread to + * copy the context of a thread into a buffer. + */ +{ + 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; +} + +/* EOF */ diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index 887543959d4..78ad8ef1be3 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -1,4 +1,4 @@ -/* $Id: thread.c,v 1.59 2000/10/22 16:36:53 ekohl Exp $ +/* $Id: thread.c,v 1.60 2000/12/10 23:42:01 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -53,11 +53,25 @@ static PETHREAD CurrentThread = NULL; PKTHREAD STDCALL KeGetCurrentThread(VOID) { +#if 0 + if (CurrentThread != NULL) + { + DbgPrint("KeGetCurrentThread() called before initialization\n"); + KeBugCheck(0); + } +#endif return(&(CurrentThread->Tcb)); } PETHREAD STDCALL PsGetCurrentThread(VOID) { +#if 0 + if (CurrentThread != NULL) + { + DbgPrint("PsGetCurrentThread() called before initialization\n"); + KeBugCheck(0); + } +#endif return(CurrentThread); } @@ -106,11 +120,11 @@ VOID PsDumpThreads(VOID) DbgPrint("Too many threads on list\n"); return; } - DbgPrint("current %x current->Tcb.State %d eip %x ", + DbgPrint("current %x current->Tcb.State %d eip %x/%x ", current, current->Tcb.State, - current->Tcb.Context.eip); - KeDumpStackFrames((PVOID)current->Tcb.Context.esp0, - 16); + current->Tcb.Context.eip, current->Tcb.LastEip); +// KeDumpStackFrames((PVOID)current->Tcb.Context.esp0, +// 16); DbgPrint("PID %d ", current->ThreadsProcess->UniqueProcessId); DbgPrint("\n"); @@ -427,215 +441,6 @@ 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) /*