Some work on file caching

Some work on the minix filesystem
Some work on v86 mode support
Implemented NtGetContextThread

svn path=/trunk/; revision=1467
This commit is contained in:
David Welch 2000-12-10 23:42:01 +00:00
parent 4ac4987dd2
commit 488f0ac078
28 changed files with 2053 additions and 1465 deletions

View file

@ -1,45 +1,52 @@
2000-08-30 David Welch <welch@cwcom.net>
2000-12-04 David Welch <welch@cwcom.net>
* 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 <welch@cwcom.net>
* 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 <welch@cwcom.net>
2000-05-27 David Welch <welch@cwcom.net>
* 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 <welch@cwcom.net>
2000-01-26 David Welch <welch@cwcom.net>
* 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 <welch@cwcom.net>
1999-09-06 David Welch <welch@cwcom.net>
* 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 <welch@cwcom.net>
1998-12-08 David Welch <welch@cwcom.net>
* 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.

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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 */

View file

@ -11,7 +11,7 @@
#include <ddk/ntddk.h>
#include <string.h>
#include "../../../ntoskrnl/include/internal/bitops.h"
#include "bitops.h"
#include <ddk/ntifs.h>
#define NDEBUG

View file

@ -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

View file

@ -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/

View file

@ -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

View file

@ -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/

File diff suppressed because it is too large Load diff

View file

@ -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 = \

View file

@ -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 <welch@cwcom.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $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 <ddk/ntddk.h>
#include <ddk/ntifs.h>
@ -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*)&current->MemoryArea);
CHECKPOINT;
current->Valid = FALSE;
current->FileOffset = PAGE_ROUND_DOWN(FileOffset);
current->Bcb = Bcb;
CHECKPOINT;
KeInitializeEvent(&current->Lock, SynchronizationEvent, FALSE);
current->ReferenceCount = 1;
CHECKPOINT;
InsertTailList(&Bcb->CacheSegmentListHead, &current->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);

View file

@ -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 *************************************************/

View file

@ -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);

View file

@ -0,0 +1,76 @@
/*
* ReactOS kernel
* Copyright (C) 2000 David Welch <welch@cwcom.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* FILE: ntoskrnl/ke/i386/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 */

View file

@ -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 <welch@cwcom.net>,
* Philip Susi <phreak@iag.net>,
* Eric Kohl <ekohl@abo.rhein-zeitung.de>
*
* 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
*/

View file

@ -0,0 +1,64 @@
/*
* ReactOS kernel
* Copyright (C) 2000 David Welch <welch@cwcom.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $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 <ddk/status.h>
#include <internal/i386/segment.h>
#include <internal/ps.h>
#include <ddk/defines.h>
/*
*
*/
.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

View file

@ -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

View file

@ -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" \

View file

@ -0,0 +1,246 @@
/*
* ReactOS kernel
* Copyright (C) 2000 David Welch <welch@cwcom.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $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 <ddk/status.h>
#include <internal/i386/segment.h>
#include <internal/ps.h>
#include <ddk/defines.h>
/*
*
*/
.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

View file

@ -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 <welch@cwcom.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $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 <ddk/defines.h>
/*
*
* 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:

View file

@ -0,0 +1,84 @@
/*
* ReactOS kernel
* Copyright (C) 2000 David Welch <welch@cwcom.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* FILE: ntoskrnl/ke/i386/tskswitch.S
* PURPOSE: Microkernel thread support
* PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
* Created 09/10/00
*/
/* INCLUDES ******************************************************************/
#include <internal/i386/segment.h>
#include <internal/ps.h>
/* 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

View file

@ -0,0 +1,142 @@
/*
* ReactOS kernel
* Copyright (C) 2000 David Welch <welch@cwcom.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* FILE: ntoskrnl/ke/i386/vm86_sup.S
* PURPOSE: V86 mode support
* PROGRAMMER: David Welch (welch@cwcom.net)
* UPDATE HISTORY:
* Created 09/10/00
*/
#include <internal/vm86.h>
.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

View file

@ -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
*/

View file

@ -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);
}

268
reactos/ntoskrnl/ps/debug.c Normal file
View file

@ -0,0 +1,268 @@
/*
* ReactOS kernel
* Copyright (C) 2000, 1999, 1998 David Welch <welch@cwcom.net>,
* Philip Susi <phreak@iag.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $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 <ddk/ntddk.h>
#include <internal/ke.h>
#include <internal/ob.h>
#include <string.h>
#include <internal/hal.h>
#include <internal/ps.h>
#include <internal/ob.h>
#define NDEBUG
#include <internal/debug.h>
/* 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 */

View file

@ -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)
/*