diff --git a/reactos/include/ddk/kedef.h b/reactos/include/ddk/kedef.h index 9afe3e58816..19d00f87502 100644 --- a/reactos/include/ddk/kedef.h +++ b/reactos/include/ddk/kedef.h @@ -9,6 +9,7 @@ typedef enum _EVENT_TYPE NotificationEvent, SynchronizationEvent, SemaphoreType, + ProcessType, } EVENT_TYPE; typedef enum _KWAIT_REASON diff --git a/reactos/include/ddk/ketypes.h b/reactos/include/ddk/ketypes.h index 49f0cfe824f..f013283bb1e 100644 --- a/reactos/include/ddk/ketypes.h +++ b/reactos/include/ddk/ketypes.h @@ -173,32 +173,15 @@ typedef struct _KDPC * PURPOSE: Defines a delayed procedure call object */ { - /* - * PURPOSE: Magic value to check this is the current object type - */ SHORT Type; - - /* - * PURPOSE: Target processor or zero if untargetted - */ UCHAR Number; - - /* - * PURPOSE: Indication of desired latency before exection - */ - UCHAR Importance; - + UCHAR Importance; LIST_ENTRY DpcListEntry; PKDEFERRED_ROUTINE DeferredRoutine; PVOID DeferredContext; PVOID SystemArgument1; PVOID SystemArgument2; - - /* - * PURPOSE: If non-zero then already in queue - */ PULONG Lock; - } KDPC, *PKDPC; diff --git a/reactos/include/ddk/pstypes.h b/reactos/include/ddk/pstypes.h index 73f6f931a7f..5672454b7b6 100644 --- a/reactos/include/ddk/pstypes.h +++ b/reactos/include/ddk/pstypes.h @@ -233,6 +233,13 @@ typedef struct _ETHREAD { LPTHREAD_START_ROUTINE Win32StartAddress; // Should Specify a win32 start func UCHAR LpcExitThreadCalled; UCHAR HardErrorsAreDisabled; + + + /* + * Added by David Welch (welch@cwcom.net) + */ + struct _EPROCESS* OldProcess; + } ETHREAD, *PETHREAD; diff --git a/reactos/include/internal/hal/page.h b/reactos/include/internal/hal/page.h index 2976b47434a..68388c4962c 100644 --- a/reactos/include/internal/hal/page.h +++ b/reactos/include/internal/hal/page.h @@ -57,14 +57,6 @@ extern inline unsigned int linear_to_physical(unsigned int x) #define FLUSH_TLB __asm__("movl %cr3,%eax\n\tmovl %eax,%cr3\n\t") -extern inline unsigned int* get_page_directory(void) -{ - unsigned int page_dir=0; - __asm__("movl %%cr3,%0\n\t" - : "=r" (page_dir)); - return((unsigned int *)physical_to_linear(page_dir)); -} - /* * Amount of memory that can be mapped by a page table diff --git a/reactos/include/internal/i386/mmhal.h b/reactos/include/internal/i386/mmhal.h index 54ecbfde08c..a2d615e5a4e 100644 --- a/reactos/include/internal/i386/mmhal.h +++ b/reactos/include/internal/i386/mmhal.h @@ -9,7 +9,7 @@ #define PAGESIZE (4096) -PULONG MmGetPageEntry(PEPROCESS Process, PVOID Address); +PULONG MmGetPageEntry(PVOID Address); /* @@ -48,12 +48,12 @@ extern inline unsigned int linear_to_physical(unsigned int x) #define FLUSH_TLB __asm__("movl %cr3,%eax\n\tmovl %eax,%cr3\n\t") -extern inline unsigned int* get_page_directory(void) +extern inline PULONG get_page_directory(void) { unsigned int page_dir=0; __asm__("movl %%cr3,%0\n\t" : "=r" (page_dir)); - return((unsigned int *)physical_to_linear(page_dir)); + return((PULONG)page_dir); } diff --git a/reactos/include/internal/ke.h b/reactos/include/internal/ke.h index b7e453d486a..246faf8f3fe 100644 --- a/reactos/include/internal/ke.h +++ b/reactos/include/internal/ke.h @@ -17,8 +17,7 @@ VOID KeAcquireDispatcherDatabaseLock(BOOLEAN Wait); VOID KeReleaseDispatcherDatabaseLock(BOOLEAN Wait); -VOID KeDispatcherObjectWake(DISPATCHER_HEADER* hdr); -VOID KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr); +BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr); VOID KiInterruptDispatch(ULONG irq); VOID KiDispatchInterrupt(ULONG irq); diff --git a/reactos/include/internal/ps.h b/reactos/include/internal/ps.h index f02a098d26b..dc8ef29d85b 100644 --- a/reactos/include/internal/ps.h +++ b/reactos/include/internal/ps.h @@ -53,7 +53,7 @@ enum */ void HalInitFirstTask(PETHREAD thread); -BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext); +NTSTATUS HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext); void HalTaskSwitch(PKTHREAD thread); NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context); NTSTATUS HalReleaseTask(PETHREAD Thread); diff --git a/reactos/lib/ntdll/ldr/startup.c b/reactos/lib/ntdll/ldr/startup.c index fc6055e935a..8e850c57656 100644 --- a/reactos/lib/ntdll/ldr/startup.c +++ b/reactos/lib/ntdll/ldr/startup.c @@ -82,8 +82,8 @@ VOID LdrStartup(HANDLE SectionHandle, NTSTATUS Status; PIMAGE_NT_HEADERS NTHeaders; - DPRINT("LdrStartup(ImageBase %x, SectionHandle %x, " - "NTDllSectionHandle %x)\n",ImageBase, + dprintf("LdrStartup(ImageBase %x, SectionHandle %x, " + "NTDllSectionHandle %x)\n",ImageBase, SectionHandle, NTDllSectionHandle); LdrDllListHead.BaseAddress = (PVOID)&_image_base__; diff --git a/reactos/loaders/dos/loadros.asm b/reactos/loaders/dos/loadros.asm index 14376f84e51..d83f7bcb0a2 100644 --- a/reactos/loaders/dos/loadros.asm +++ b/reactos/loaders/dos/loadros.asm @@ -538,7 +538,14 @@ l10: add eax,07h mov [fs:di],eax mov [fs:di+(0xd0000000/(1024*1024))],eax - + + ; + ; Map the page tables from the page table + ; + mov eax,[kernel_page_directory_base] + add eax,07h + mov [fs:di+(0xf0000000/(1024*1024))],eax + ; ; Map in the kernel page table ; diff --git a/reactos/ntoskrnl/ex/resource.c b/reactos/ntoskrnl/ex/resource.c index de0a0db277f..f05eb4e210c 100644 --- a/reactos/ntoskrnl/ex/resource.c +++ b/reactos/ntoskrnl/ex/resource.c @@ -31,6 +31,8 @@ /* INCLUDES *****************************************************************/ #include +#include +#include #include diff --git a/reactos/ntoskrnl/hal/x86/exp.c b/reactos/ntoskrnl/hal/x86/exp.c index f6387d8649f..ef873a8924c 100644 --- a/reactos/ntoskrnl/hal/x86/exp.c +++ b/reactos/ntoskrnl/hal/x86/exp.c @@ -210,9 +210,12 @@ asmlinkage void exception_handler(unsigned int edi, { DbgPrint("Exception: %d(%x)\n",type,error_code&0xffff); } - DbgPrint("Process: %x\n",PsGetCurrentThread()->Cid.UniqueProcess); - DbgPrint("Thread: %x\n",PsGetCurrentThread()->Cid.UniqueThread); DbgPrint("CS:EIP %x:%x\n",cs&0xffff,eip); + __asm__("movl %%cr2,%0\n\t" + : "=d" (cr2)); + DbgPrint("cr2 %x\n",cr2); + DbgPrint("Process: %x\n",PsGetCurrentProcess()); + DbgPrint("Thread: %x\n",PsGetCurrentThread()->Cid.UniqueThread); DbgPrint("DS %x ES %x FS %x GS %x\n",ds&0xffff,es&0xffff,fs&0xffff, gs&0xfff); // for(;;); @@ -228,9 +231,6 @@ asmlinkage void exception_handler(unsigned int edi, DbgPrint("ESP %.8x\n",esp); } - __asm__("movl %%cr2,%0\n\t" - : "=d" (cr2)); - DbgPrint("cr2 %x\n",cr2); if ((cs&0xffff)==KERNEL_CS) { @@ -241,8 +241,8 @@ asmlinkage void exception_handler(unsigned int edi, printk("Stack:\n"); for (i=0;i<16;i=i+4) { - printk("%.8x %.8x %.8x %.8x\n",stack[i],stack[i+1],stack[i+2], - stack[i+3]); + DbgPrint("%.8x %.8x %.8x %.8x\n",stack[i],stack[i+1],stack[i+2], + stack[i+3]); } printk("Frames:\n"); for (i=0;i<32;i++) @@ -259,20 +259,20 @@ asmlinkage void exception_handler(unsigned int edi, sym = j; } } - printk(" %.8x (%s+%d)", - stack[i], - symbol_table[sym].name, - stack[i] - symbol_table[sym].value); + DbgPrint(" %.8x (%s+%d)", + stack[i], + symbol_table[sym].name, + stack[i] - symbol_table[sym].value); } } // #endif } else { - printk("SS:ESP %x:%x\n",ss0,esp0); + DbgPrint("SS:ESP %x:%x\n",ss0,esp0); stack=(unsigned int *)(esp0); - printk("Stack:\n"); + DbgPrint("Stack:\n"); for (i=0; i<16; i++) { if (MmIsPagePresent(NULL,&stack[i])) diff --git a/reactos/ntoskrnl/hal/x86/halinit.c b/reactos/ntoskrnl/hal/x86/halinit.c index 3176ea6d86a..3704d80c213 100644 --- a/reactos/ntoskrnl/hal/x86/halinit.c +++ b/reactos/ntoskrnl/hal/x86/halinit.c @@ -3,7 +3,7 @@ * PROJECT: ReactOS kernel * FILE: ntoskrnl/hal/x86/halinit.c * PURPOSE: Initalize the uniprocessor, x86 hal - * PROGRAMMER: David Welch (welch@mcmail.com) + * PROGRAMMER: David Welch (welch@cwcom.net) * UPDATE HISTORY: * 11/06/98: Created */ @@ -20,8 +20,7 @@ /* FUNCTIONS ***************************************************************/ VOID HalInit(boot_param* bp) -{ - +{ KeInitExceptions(); KeInitIRQ(); KeLowerIrql(DISPATCH_LEVEL); diff --git a/reactos/ntoskrnl/hal/x86/head.s b/reactos/ntoskrnl/hal/x86/head.s index ef6ea17d421..dfd2bb771e9 100644 --- a/reactos/ntoskrnl/hal/x86/head.s +++ b/reactos/ntoskrnl/hal/x86/head.s @@ -66,7 +66,6 @@ _idt_descr: .long _idt _gdt_descr: -/* .word ((6+128)*8)-1 */ .word ((6+NR_TASKS)*8)-1 .long _gdt diff --git a/reactos/ntoskrnl/hal/x86/page.c b/reactos/ntoskrnl/hal/x86/page.c index 6ac418ce396..0757c49c578 100644 --- a/reactos/ntoskrnl/hal/x86/page.c +++ b/reactos/ntoskrnl/hal/x86/page.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top directory * PROJECT: ReactOS kernel - * FILE: ntoskrnl/hal/x86/page.c + * FILE: ntoskrnl/mm/i386/page.c * PURPOSE: low level memory managment manipulation * PROGRAMER: David Welch (welch@cwcom.net) * UPDATE HISTORY: @@ -28,6 +28,9 @@ #define PA_PRESENT (1<Pcb.PageTableDirectory; +// (*page_dir) = get_free_page() | (PA_READ | PA_WRITE); + (*page_dir) = get_free_page() | 0x7; + FLUSH_TLB; } - else - { - page_dir = (PULONG)get_page_directory(); - } - - DPRINT("page_dir %x\n",page_dir); - page_tlb = (PULONG)physical_to_linear( - PAGE_MASK(page_dir[VADDR_TO_PD_OFFSET(Address)])); + page_tlb = ADDR_TO_PTE(Address); DPRINT("page_tlb %x\n",page_tlb); - - if (PAGE_MASK(page_dir[VADDR_TO_PD_OFFSET(Address)])==0) - { - DPRINT("Creating new page directory\n",0); - page_table = get_free_page(); // Returns a physical address - page_tlb=(PULONG)physical_to_linear(page_table); - memset(page_tlb,0,PAGESIZE); - page_dir[VADDR_TO_PD_OFFSET(Address)]=page_table+0x7; - - } - DPRINT("Returning %x\n",page_tlb[VADDR_TO_PT_OFFSET(Address)/4]); - return(&page_tlb[VADDR_TO_PT_OFFSET(Address)/4]); + return(page_tlb); } BOOLEAN MmIsPagePresent(PEPROCESS Process, PVOID Address) { - return((*MmGetPageEntry(Process, Address)) & PA_PRESENT); + return((MmGetPageEntryForProcess(Process, Address)) & PA_PRESENT); } VOID MmSetPage(PEPROCESS Process, @@ -99,10 +110,22 @@ VOID MmSetPage(PEPROCESS Process, ULONG Attributes = 0; + DPRINT("MmSetPage(Process %x, Address %x, flProtect %x, " + "PhysicalAddress %x)\n",Process,Address,flProtect, + PhysicalAddress); + Attributes = ProtectToPTE(flProtect); - (*MmGetPageEntry(Process, Address)) = PhysicalAddress | Attributes; + if (Process != NULL && Process != PsGetCurrentProcess()) + { + KeAttachProcess(Process); + } + (*MmGetPageEntry(Address)) = PhysicalAddress | Attributes; FLUSH_TLB; + if (Process != NULL && Process != PsGetCurrentProcess()) + { + KeDetachProcess(); + } } VOID MmSetPageProtect(PEPROCESS Process, @@ -113,10 +136,18 @@ VOID MmSetPageProtect(PEPROCESS Process, PULONG PageEntry; Attributes = ProtectToPTE(flProtect); - - PageEntry = MmGetPageEntry(Process,Address); + + if (Process != PsGetCurrentProcess()) + { + KeAttachProcess(Process); + } + PageEntry = MmGetPageEntry(Address); (*PageEntry) = PAGE_MASK(*PageEntry) | Attributes; FLUSH_TLB; + if (Process != PsGetCurrentProcess()) + { + KeDetachProcess(); + } } PHYSICAL_ADDRESS MmGetPhysicalAddress(PVOID vaddr) @@ -129,7 +160,7 @@ PHYSICAL_ADDRESS MmGetPhysicalAddress(PVOID vaddr) DPRINT("MmGetPhysicalAddress(vaddr %x)\n", vaddr); SET_LARGE_INTEGER_HIGH_PART(p, 0); - SET_LARGE_INTEGER_LOW_PART(p, PAGE_MASK(*MmGetPageEntry(NULL,vaddr))); + SET_LARGE_INTEGER_LOW_PART(p, PAGE_MASK(*MmGetPageEntry(vaddr))); return p; } diff --git a/reactos/ntoskrnl/hal/x86/thread.c b/reactos/ntoskrnl/hal/x86/thread.c index dda07d2bdb4..050f9819ae3 100644 --- a/reactos/ntoskrnl/hal/x86/thread.c +++ b/reactos/ntoskrnl/hal/x86/thread.c @@ -24,6 +24,8 @@ /* GLOBALS ***************************************************************/ +#define NR_TASKS 128 + VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext); VOID PsBeginThreadWithContextInternal(VOID); @@ -93,7 +95,7 @@ static unsigned int allocate_tss_descriptor(void) */ { unsigned int i; - for (i=0;i<16;i++) + for (i=0;iTcb.Context.nr/8].a=0; gdt[Thread->Tcb.Context.nr/8].b=0; ExFreePool(Thread->Tcb.Context.KernelStackBase); if (Thread->Tcb.Context.SavedKernelStackBase != NULL) { - ExFreePool(Thread->Tcb.Context.KernelStackBase); + ExFreePool(Thread->Tcb.Context.SavedKernelStackBase); } return(STATUS_SUCCESS); } @@ -227,8 +234,8 @@ NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context) Thread->Tcb.Context.cs = KERNEL_CS; Thread->Tcb.Context.eip = (ULONG)PsBeginThreadWithContextInternal; Thread->Tcb.Context.io_bitmap[0] = 0xff; - Thread->Tcb.Context.cr3 = (ULONG)MmGetPhysicalAddress( - Thread->ThreadsProcess->Pcb.PageTableDirectory); + Thread->Tcb.Context.cr3 = (ULONG) + Thread->ThreadsProcess->Pcb.PageTableDirectory; Thread->Tcb.Context.ds = KERNEL_DS; Thread->Tcb.Context.es = KERNEL_DS; Thread->Tcb.Context.fs = KERNEL_DS; @@ -242,7 +249,7 @@ NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context) return(STATUS_SUCCESS); } -BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext) +NTSTATUS HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext) /* * FUNCTION: Initializes the HAL portion of a thread object * ARGUMENTS: @@ -252,7 +259,7 @@ BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext) * RETURNS: True if the function succeeded */ { - unsigned int desc = allocate_tss_descriptor(); + unsigned int desc; unsigned int length = sizeof(hal_thread_state) - 1; unsigned int base = (unsigned int)(&(thread->Tcb.Context)); PULONG kernel_stack = ExAllocatePool(NonPagedPool,4096); @@ -266,6 +273,12 @@ BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext) */ assert(sizeof(hal_thread_state)>=0x68); + desc = allocate_tss_descriptor(); + if (desc == 0) + { + return(STATUS_UNSUCCESSFUL); + } + /* * Setup a TSS descriptor */ @@ -302,8 +315,8 @@ BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext) thread->Tcb.Context.cs = KERNEL_CS; thread->Tcb.Context.eip = (unsigned long)PsBeginThread; thread->Tcb.Context.io_bitmap[0] = 0xff; - thread->Tcb.Context.cr3 = - MmGetPhysicalAddress(thread->ThreadsProcess->Pcb.PageTableDirectory); + thread->Tcb.Context.cr3 = (ULONG) + thread->ThreadsProcess->Pcb.PageTableDirectory; thread->Tcb.Context.ds = KERNEL_DS; thread->Tcb.Context.es = KERNEL_DS; thread->Tcb.Context.fs = KERNEL_DS; @@ -314,8 +327,7 @@ BOOLEAN HalInitTask(PETHREAD thread, PKSTART_ROUTINE fn, PVOID StartContext) thread->Tcb.Context.SavedKernelStackBase = NULL; DPRINT("Allocated %x\n",desc*8); - - return(TRUE); + return(STATUS_SUCCESS); } void HalInitFirstTask(PETHREAD thread) diff --git a/reactos/ntoskrnl/ke/ldt.c b/reactos/ntoskrnl/ke/ldt.c index 827f89b77c3..c301e5bd935 100644 --- a/reactos/ntoskrnl/ke/ldt.c +++ b/reactos/ntoskrnl/ke/ldt.c @@ -1,8 +1,8 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ke/bug.c - * PURPOSE: Graceful system shutdown if a bug is detected + * FILE: ntoskrnl/ke/ldt.c + * PURPOSE: LDT managment * PROGRAMMER: David Welch (welch@mcmail.com) * UPDATE HISTORY: * Created 22/05/98 diff --git a/reactos/ntoskrnl/ke/main.c b/reactos/ntoskrnl/ke/main.c index ffb0cc5b263..aefc1e14fa6 100644 --- a/reactos/ntoskrnl/ke/main.c +++ b/reactos/ntoskrnl/ke/main.c @@ -3,7 +3,7 @@ * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/main.c * PURPOSE: Initalizes the kernel - * PROGRAMMER: David Welch (welch@mcmail.com) + * PROGRAMMER: David Welch (welch@cwcom.net) * UPDATE HISTORY: * 28/05/98: Created */ @@ -105,6 +105,7 @@ void set_breakpoint(unsigned int i, unsigned int addr, unsigned int type, extern int edata; extern int end; + asmlinkage void _main(boot_param* _bp) /* * FUNCTION: Called by the boot loader to start the kernel @@ -173,7 +174,8 @@ asmlinkage void _main(boot_param* _bp) * Load Auto configured drivers */ LdrLoadAutoConfigDrivers(); - + + /* * Launch initial process */ diff --git a/reactos/ntoskrnl/ke/process.c b/reactos/ntoskrnl/ke/process.c new file mode 100644 index 00000000000..5b358d13372 --- /dev/null +++ b/reactos/ntoskrnl/ke/process.c @@ -0,0 +1,78 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/ke/process.c + * PURPOSE: Microkernel process management + * PROGRAMMER: David Welch (welch@cwcom.net) + * UPDATE HISTORY: + * Created 22/05/98 + */ + +/* INCLUDES *****************************************************************/ + +#include +#include +#include + +#include + +/* FUNCTIONS *****************************************************************/ + +VOID KeAttachProcess(PEPROCESS Process) +{ + KIRQL oldlvl; + PETHREAD CurrentThread; + ULONG PageDir; + + DPRINT("KeAttachProcess(Process %x)\n",Process); + + CurrentThread = PsGetCurrentThread(); + + if (CurrentThread->OldProcess != NULL) + { + DbgPrint("Invalid attach (thread is already attached)\n"); + KeBugCheck(0); + } + + KeRaiseIrql(DISPATCH_LEVEL, &oldlvl); + + CurrentThread->OldProcess = PsGetCurrentProcess(); + CurrentThread->ThreadsProcess = Process; + PageDir = (ULONG)CurrentThread->ThreadsProcess->Pcb.PageTableDirectory; + CurrentThread->Tcb.Context.cr3 = PageDir; + __asm__("movl %0,%%cr3\n\t" + : /* no inputs */ + : "r" (PageDir)); + + + KeLowerIrql(oldlvl); +} + +VOID KeDetachProcess(VOID) +{ + KIRQL oldlvl; + PETHREAD CurrentThread; + ULONG PageDir; + + DPRINT("KeDetachProcess()\n"); + + CurrentThread = PsGetCurrentThread(); + + if (CurrentThread->OldProcess == NULL) + { + DbgPrint("Invalid detach (thread was not attached)\n"); + KeBugCheck(0); + } + + KeRaiseIrql(DISPATCH_LEVEL, &oldlvl); + + CurrentThread->ThreadsProcess = CurrentThread->OldProcess; + CurrentThread->OldProcess = NULL; + PageDir = (ULONG)CurrentThread->ThreadsProcess->Pcb.PageTableDirectory; + CurrentThread->Tcb.Context.cr3 = PageDir; + __asm__("movl %0,%%cr3\n\t" + : /* no inputs */ + : "r" (PageDir)); + + KeLowerIrql(oldlvl); +} diff --git a/reactos/ntoskrnl/ke/sem.c b/reactos/ntoskrnl/ke/sem.c index c51575cb331..d2f78e9b807 100644 --- a/reactos/ntoskrnl/ke/sem.c +++ b/reactos/ntoskrnl/ke/sem.c @@ -24,7 +24,7 @@ VOID KeInitializeSemaphore(PKSEMAPHORE Semaphore, KeInitializeDispatcherHeader(&Semaphore->Header,SemaphoreType, sizeof(KSEMAPHORE)/sizeof(ULONG), Count); - Semaphore->Limit=Limit; + Semaphore->Limit = Limit; } LONG KeReadStateSemaphore(PKSEMAPHORE Semaphore) @@ -37,23 +37,26 @@ LONG KeReleaseSemaphore(PKSEMAPHORE Semaphore, LONG Adjustment, BOOLEAN Wait) { -long initState=Semaphore->Header.SignalState; - if(Semaphore->Limit < initState+Adjustment + ULONG initState = Semaphore->Header.SignalState; + + KeAcquireDispatcherDatabaseLock(Wait); + + if(Semaphore->Limit < initState+Adjustment || initState > initState+Adjustment) - ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED); - Semaphore->Header.SignalState+=Adjustment; - if((initState == 0) - && (Semaphore->Header.WaitListHead.Flink != &Semaphore->Header.WaitListHead)) - { - // wake up SignalState waiters - while(Semaphore->Header.SignalState > 0 - && KeDispatcherObjectWakeOne(Semaphore->Header) ) ; - } - if (Wait) - { - // FIXME(2) : in this case, we must store somewhere that we have been here - // and the functions KeWaitxxx must take care of this - } - return initState; + { + ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED); + } + + Semaphore->Header.SignalState += Adjustment; + if (initState == 0) + { + // wake up SignalState waiters + while(Semaphore->Header.SignalState > 0 + && KeDispatcherObjectWake(&Semaphore->Header)) ; + } + + KeReleaseDispatcherDatabaseLock(Wait); + + return initState; } diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index 1a2a22eccad..9573898910b 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -48,7 +48,7 @@ VOID KeAcquireDispatcherDatabaseLock(BOOLEAN Wait) * PURPOSE: Acquires the dispatcher database lock for the caller */ { - DPRINT("KeAcquireDispatcherDatabaseLock(Wait %x)\n",Wait); +// DPRINT("KeAcquireDispatcherDatabaseLock(Wait %x)\n",Wait); if (WaitSet && Owner == KeGetCurrentThread()) { return; @@ -60,7 +60,7 @@ VOID KeAcquireDispatcherDatabaseLock(BOOLEAN Wait) VOID KeReleaseDispatcherDatabaseLock(BOOLEAN Wait) { - DPRINT("KeReleaseDispatcherDatabaseLock(Wait %x)\n",Wait); +// DPRINT("KeReleaseDispatcherDatabaseLock(Wait %x)\n",Wait); assert(Wait==WaitSet); if (!Wait) { @@ -69,11 +69,16 @@ VOID KeReleaseDispatcherDatabaseLock(BOOLEAN Wait) } } -VOID KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr) +static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr) { PKWAIT_BLOCK current; PLIST_ENTRY current_entry; + if (IsListEmpty(&hdr->WaitListHead)) + { + return(FALSE); + } + while (!IsListEmpty(&(hdr->WaitListHead))) { current_entry = RemoveHeadList(&hdr->WaitListHead); @@ -82,9 +87,10 @@ VOID KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr) DPRINT("Waking %x\n",current->Thread); PsResumeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb)); }; + return(TRUE); } -BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr) +static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr) { PKWAIT_BLOCK current; PLIST_ENTRY current_entry; @@ -101,29 +107,48 @@ BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr) WaitListEntry); DPRINT("current_entry %x current %x\n",current_entry,current); DPRINT("Waking %x\n",current->Thread); - if (hdr->Type == SemaphoreType) - hdr->SignalState--; PsResumeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb)); return(TRUE); } -VOID KeDispatcherObjectWake(DISPATCHER_HEADER* hdr) +BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr) +/* + * FUNCTION: Wake threads waiting on a dispatcher object + * NOTE: The exact semantics of waking are dependant on the type of object + */ { + BOOL Ret; DPRINT("Entering KeDispatcherObjectWake(hdr %x)\n",hdr); // DPRINT("hdr->WaitListHead %x hdr->WaitListHead.Flink %x\n", // &hdr->WaitListHead,hdr->WaitListHead.Flink); - if (hdr->Type==NotificationEvent) + switch (hdr->Type) { - KeDispatcherObjectWakeAll(hdr); - } - if (hdr->Type==SynchronizationEvent) - { - if (KeDispatcherObjectWakeOne(hdr)) - { - hdr->SignalState=FALSE; - } + case NotificationEvent: + return(KeDispatcherObjectWakeAll(hdr)); + + case SynchronizationEvent: + Ret = KeDispatcherObjectWakeOne(hdr); + if (Ret) + { + hdr->SignalState = FALSE; + } + return(Ret); + + case SemaphoreType: + Ret = KeDispatcherObjectWakeOne(hdr); + if (Ret) + { + hdr->SignalState--; + } + return(Ret); + + case ProcessType: + return(KeDispatcherObjectWakeAll(hdr)); } + DbgPrint("Dispatcher object has unknown type\n"); + KeBugCheck(0); + return(FALSE); } @@ -149,20 +174,25 @@ NTSTATUS KeWaitForSingleObject(PVOID Object, DISPATCHER_HEADER* hdr = (DISPATCHER_HEADER *)Object; KWAIT_BLOCK blk; - DPRINT("Entering KeWaitForSingleObject(Object %x)\n",Object); - // FIXME : if KeReleaseSemaphore called with wait just before KeWaitxxx - // we must do something special. + DPRINT("Entering KeWaitForSingleObject(Object %x) " + "PsGetCurrentThread() %x\n",Object,PsGetCurrentThread()); KeAcquireDispatcherDatabaseLock(FALSE); - + + DPRINT("hdr->SignalState %d\n", hdr->SignalState); + if (hdr->SignalState > 0) { - if (hdr->Type == SynchronizationEvent) - { - hdr->SignalState=FALSE; - } - else if (hdr->Type == SemaphoreType) - hdr->SignalState--; + switch (hdr->Type) + { + case SynchronizationEvent: + hdr->SignalState = FALSE; + break; + + case SemaphoreType: + hdr->SignalState--; + break; + } KeReleaseDispatcherDatabaseLock(FALSE); return(STATUS_SUCCESS); } @@ -187,6 +217,7 @@ NTSTATUS KeWaitForSingleObject(PVOID Object, { KeCancelTimer(&KeGetCurrentThread()->TimerBlock); } + DPRINT("Returning from KeWaitForSingleObject()\n"); return(STATUS_SUCCESS); } diff --git a/reactos/ntoskrnl/makefile_rex b/reactos/ntoskrnl/makefile_rex index 128ae34372c..be98e9ef9c8 100644 --- a/reactos/ntoskrnl/makefile_rex +++ b/reactos/ntoskrnl/makefile_rex @@ -17,7 +17,8 @@ RTL_OBJECTS = rtl/vsprintf.o rtl/lookas.o rtl/unicode.o rtl/strtok.o \ KE_OBJECTS = ke/main.o ke/timer.o ke/error.o ke/catch.o ke/exports.o \ ke/dpc.o ke/wait.o ke/kqueue.o ke/dispatch.o \ ke/sem.o ke/critical.o ke/event.o ke/apc.o ke/bug.o \ - ke/mutex.o ke/kernel.o ke/ldt.o ke/apchelp.o + ke/mutex.o ke/kernel.o ke/ldt.o ke/apchelp.o \ + ke/process.o MM_OBJECTS = mm/mm.o mm/freelist.o mm/pool.o mm/virtual.o \ mm/mdl.o mm/zone.o mm/special.o mm/paging.o \ diff --git a/reactos/ntoskrnl/mm/marea.c b/reactos/ntoskrnl/mm/marea.c index 1dc64aa3a14..8db3273eba6 100644 --- a/reactos/ntoskrnl/mm/marea.c +++ b/reactos/ntoskrnl/mm/marea.c @@ -417,6 +417,13 @@ NTSTATUS MmFreeMemoryArea(PEPROCESS Process, 1); } } + for (i=0; i<=(MemoryArea->Length/PAGESIZE); i++) + { + MmSetPage(NULL, + MemoryArea->BaseAddress + (i*PAGESIZE), + 0, + 0); + } RemoveEntryList(&(MemoryArea->Entry)); ExFreePool(MemoryArea); diff --git a/reactos/ntoskrnl/mm/mdl.c b/reactos/ntoskrnl/mm/mdl.c index 8d4c85d3d6c..c347ea980e4 100644 --- a/reactos/ntoskrnl/mm/mdl.c +++ b/reactos/ntoskrnl/mm/mdl.c @@ -3,7 +3,7 @@ * PROJECT: ReactOS kernel * FILE: ntoskrnl/mm/mdl.c * PURPOSE: Manipulates MDLs - * PROGRAMMER: David Welch (welch@mcmail.com) + * PROGRAMMER: David Welch (welch@cwcom.net) * UPDATE HISTORY: * 27/05/98: Created */ diff --git a/reactos/ntoskrnl/mm/mm.c b/reactos/ntoskrnl/mm/mm.c index fb4d616f313..058ab0d065e 100644 --- a/reactos/ntoskrnl/mm/mm.c +++ b/reactos/ntoskrnl/mm/mm.c @@ -58,6 +58,8 @@ void MmInitialize(boot_param* bp) unsigned int first_krnl_phys_addr; unsigned int last_krnl_phys_addr; int i; + PULONG page_directory = (PULONG)physical_to_linear( + (ULONG)get_page_directory()); DPRINT("InitalizeMM()\n"); @@ -65,7 +67,7 @@ void MmInitialize(boot_param* bp) /* * Unmap low memory */ - (get_page_directory())[0]=0; + page_directory[0]=0; FLUSH_TLB; CHECKPOINT; @@ -122,12 +124,8 @@ void MmInitialize(boot_param* bp) PAGE_NOACCESS, 0); } - MmSetPage(NULL, - 0, - PAGE_NOACCESS, - 0); FLUSH_TLB; - CHECKPOINT; + /* * Intialize memory areas */ diff --git a/reactos/ntoskrnl/mm/npool.c b/reactos/ntoskrnl/mm/npool.c index c1611b9d0ca..b2dc4203c96 100644 --- a/reactos/ntoskrnl/mm/npool.c +++ b/reactos/ntoskrnl/mm/npool.c @@ -79,15 +79,41 @@ ULONG EiNrUsedBlocks = 0; * If set then the page is used by a kmalloc block */ static unsigned int alloc_map[ALLOC_MAP_SIZE/32]={0,}; +static KSPIN_LOCK AllocMapLock; unsigned int EiFreeNonPagedPool = 0; unsigned int EiUsedNonPagedPool = 0; /* FUNCTIONS ***************************************************************/ +PVOID ExAllocatePage(VOID) +{ + KIRQL oldlvl; + ULONG addr; + ULONG i; + + KeAcquireSpinLock(&AllocMapLock, &oldlvl); + for (i=1; i #include #include +#include +#include #define NDEBUG #include @@ -106,7 +108,7 @@ NTSTATUS MmSectionHandleFault(MEMORY_AREA* MemoryArea, PVOID Address) IO_STATUS_BLOCK IoStatus; DPRINT("MmSectionHandleFault(MemoryArea %x, Address %x)\n", - MemoryArea,Address); + MemoryArea,Address); MmSetPage(NULL, Address, @@ -150,18 +152,19 @@ asmlinkage int page_fault_handler(unsigned int cs, */ unsigned int cr2; __asm__("movl %%cr2,%0\n\t" : "=d" (cr2)); - DPRINT("Page fault at address %x with eip %x\n",cr2,eip); + DPRINT("Page fault at address %x with eip %x in process %x\n",cr2,eip, + PsGetCurrentProcess()); cr2 = PAGE_ROUND_DOWN(cr2); - if (KeGetCurrentIrql()!=PASSIVE_LEVEL) + if (KeGetCurrentIrql() != PASSIVE_LEVEL) { DbgPrint("Page fault at high IRQL\n"); return(0); // KeBugCheck(0); } - KeRaiseIrql(DISPATCH_LEVEL,&oldlvl); + KeRaiseIrql(DISPATCH_LEVEL, &oldlvl); /* * Find the memory area for the faulting address @@ -171,7 +174,7 @@ asmlinkage int page_fault_handler(unsigned int cs, /* * Check permissions */ - if (cs!=KERNEL_CS) + if (cs != KERNEL_CS) { printk("%s:%d\n",__FILE__,__LINE__); return(0); @@ -184,7 +187,7 @@ asmlinkage int page_fault_handler(unsigned int cs, } MemoryArea = MmOpenMemoryAreaByAddress(PsGetCurrentProcess(),(PVOID)cr2); - if (MemoryArea==NULL) + if (MemoryArea == NULL) { printk("%s:%d\n",__FILE__,__LINE__); return(0); @@ -199,7 +202,7 @@ asmlinkage int page_fault_handler(unsigned int cs, case MEMORY_AREA_SECTION_VIEW_COMMIT: if (MmSectionHandleFault(MemoryArea, (PVOID)cr2)==STATUS_SUCCESS) { - stat=1; + stat = 1; } else { @@ -631,6 +634,16 @@ NTSTATUS STDCALL NtReadVirtualMemory(IN HANDLE ProcessHandle, NumberOfBytesRead)); } +NTSTATUS STDCALL ZwReadVirtualMemory(IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + OUT PVOID Buffer, + IN ULONG NumberOfBytesToRead, + OUT PULONG NumberOfBytesRead) +{ + UNIMPLEMENTED; +} + +#if 0 NTSTATUS STDCALL ZwReadVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, OUT PVOID Buffer, @@ -678,6 +691,7 @@ NTSTATUS STDCALL ZwReadVirtualMemory(IN HANDLE ProcessHandle, } return(STATUS_SUCCESS); } +#endif NTSTATUS STDCALL NtUnlockVirtualMemory(HANDLE ProcessHandle, PVOID BaseAddress, @@ -717,11 +731,10 @@ NTSTATUS STDCALL ZwWriteVirtualMemory(IN HANDLE ProcessHandle, IN ULONG NumberOfBytesToWrite, OUT PULONG NumberOfBytesWritten) { - PEPROCESS Process; - PMEMORY_AREA OutMemoryArea; - ULONG i; NTSTATUS Status; - PULONG CurrentEntry; + PMDL Mdl; + PVOID SystemAddress; + PEPROCESS Process; DPRINT("ZwWriteVirtualMemory(ProcessHandle %x, BaseAddress %x, " "Buffer %x, NumberOfBytesToWrite %d)\n",ProcessHandle,BaseAddress, @@ -737,56 +750,22 @@ NTSTATUS STDCALL ZwWriteVirtualMemory(IN HANDLE ProcessHandle, { return(Status); } - - OutMemoryArea = MmOpenMemoryAreaByAddress(Process,BaseAddress); - if (OutMemoryArea == NULL) - { - return(STATUS_UNSUCCESSFUL); - } - + + Mdl = MmCreateMdl(NULL, + Buffer, + NumberOfBytesToWrite); + MmProbeAndLockPages(Mdl, + UserMode, + IoReadAccess); + + KeAttachProcess(Process); + + SystemAddress = MmGetSystemAddressForMdl(Mdl); + memcpy(BaseAddress, SystemAddress, NumberOfBytesToWrite); + + KeDetachProcess(); + *NumberOfBytesWritten = NumberOfBytesToWrite; - - DPRINT("*Buffer %x\n",((PULONG)Buffer)[0]); - - for (i=0; i<(PAGE_ROUND_DOWN(NumberOfBytesToWrite)/PAGESIZE); i++) - { - if (!MmIsPagePresent(Process, BaseAddress + (i*PAGESIZE))) - { - DPRINT("OutMemoryArea->Attributes %x\n", - OutMemoryArea->Attributes); - MmSetPage(Process, - BaseAddress + (i*PAGESIZE), - OutMemoryArea->Attributes, - get_free_page()); - } - CurrentEntry = MmGetPageEntry(Process, - (PVOID)((DWORD)BaseAddress + - (i*PAGESIZE))); - RtlCopyMemory((PVOID)physical_to_linear(PAGE_MASK(*CurrentEntry)) + - (((DWORD)BaseAddress)%PAGESIZE), - Buffer + (i*PAGESIZE), - PAGESIZE); - } - if ((NumberOfBytesToWrite % PAGESIZE) != 0) - { - if (!MmIsPagePresent(Process, BaseAddress + (i*PAGESIZE))) - { - MmSetPage(Process, - BaseAddress + (i*PAGESIZE), - OutMemoryArea->Attributes, - get_free_page()); - } - CurrentEntry = MmGetPageEntry(Process, - BaseAddress + (i*PAGESIZE)); - DPRINT("addr %x\n", - physical_to_linear(PAGE_MASK(*CurrentEntry)) + - (((DWORD)BaseAddress)%PAGESIZE)); - RtlCopyMemory((PVOID)physical_to_linear(PAGE_MASK(*CurrentEntry)) + - (((DWORD)BaseAddress)%PAGESIZE), - Buffer + (i*PAGESIZE), - NumberOfBytesToWrite % PAGESIZE); - } return(STATUS_SUCCESS); } - diff --git a/reactos/ntoskrnl/ps/kill.c b/reactos/ntoskrnl/ps/kill.c index b2e83312bcb..27e0559b745 100644 --- a/reactos/ntoskrnl/ps/kill.c +++ b/reactos/ntoskrnl/ps/kill.c @@ -80,7 +80,7 @@ NTSTATUS STDCALL ZwTerminateProcess(IN HANDLE ProcessHandle, PiTerminateProcessThreads(Process, ExitStatus); KeRaiseIrql(DISPATCH_LEVEL, &oldlvl); - KeDispatcherObjectWakeAll(&Process->Pcb.DispatcherHeader); + KeDispatcherObjectWake(&Process->Pcb.DispatcherHeader); Process->Pcb.ProcessState = PROCESS_STATE_TERMINATED; if (PsGetCurrentThread()->ThreadsProcess == Process) { diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index be44869a915..bd4d265c45f 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -163,6 +163,7 @@ NTSTATUS STDCALL ZwCreateProcess( ULONG i; PKPROCESS KProcess; NTSTATUS Status; + PULONG PhysicalPageDirectory; DPRINT("ZwCreateProcess(ObjectAttributes %x)\n",ObjectAttributes); @@ -184,7 +185,7 @@ NTSTATUS STDCALL ZwCreateProcess( ObjectAttributes, PsProcessType); KeInitializeDispatcherHeader(&Process->Pcb.DispatcherHeader, - 0, + ProcessType, sizeof(EPROCESS), FALSE); KProcess = &(Process->Pcb); @@ -194,16 +195,20 @@ NTSTATUS STDCALL ZwCreateProcess( InheritObjectTable, Process); - PageDirectory = (PULONG)physical_to_linear((ULONG)get_free_page()); - KProcess->PageTableDirectory = PageDirectory; + PhysicalPageDirectory = (PULONG)get_free_page(); + PageDirectory = (PULONG)physical_to_linear((ULONG)PhysicalPageDirectory); + KProcess->PageTableDirectory = PhysicalPageDirectory; - CurrentPageDirectory = (PULONG)get_page_directory(); + CurrentPageDirectory = (PULONG)physical_to_linear( + (ULONG)get_page_directory()); memset(PageDirectory,0,PAGESIZE); - for (i=768;i<1024;i++) + for (i=768; i<896; i++) { - PageDirectory[i]=CurrentPageDirectory[i]; + PageDirectory[i] = CurrentPageDirectory[i]; } + PageDirectory[0xf0000000 / (4*1024*1024)] + = (ULONG)PhysicalPageDirectory | 0x7; /* * FIXME: I don't what I'm supposed to know with a section handle diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index 5b541ef79fa..d666c1048d0 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -273,12 +273,8 @@ NTSTATUS PsInitializeThread(HANDLE ProcessHandle, VOID PsResumeThread(PETHREAD Thread) { DPRINT("PsResumeThread(Thread %x)\n",Thread); - Thread->Tcb.SuspendCount--; - DPRINT("Thread->Tcb.SuspendCount %d\n",Thread->Tcb.SuspendCount); - DPRINT("Thread->Tcb.ThreadState %d THREAD_STATE_RUNNING %d\n", - Thread->Tcb.ThreadState,THREAD_STATE_RUNNING); - if (Thread->Tcb.SuspendCount <= 0 && + if (Thread->Tcb.SuspendCount <= 0 && Thread->Tcb.ThreadState != THREAD_STATE_RUNNING) { DPRINT("Setting thread to runnable\n"); @@ -386,12 +382,16 @@ NTSTATUS ZwCreateThread(PHANDLE ThreadHandle, Status = PsInitializeThread(ProcessHandle,&Thread,ThreadHandle, DesiredAccess,ObjectAttributes); - if (Status != STATUS_SUCCESS) + if (!NT_SUCCESS(Status)) { return(Status); } - HalInitTaskWithContext(Thread,ThreadContext); + Status = HalInitTaskWithContext(Thread,ThreadContext); + if (!NT_SUCCESS(Status)) + { + return(Status); + } Thread->StartAddress=NULL; if (Client!=NULL) @@ -440,13 +440,17 @@ NTSTATUS PsCreateSystemThread(PHANDLE ThreadHandle, Status = PsInitializeThread(ProcessHandle,&Thread,ThreadHandle, DesiredAccess,ObjectAttributes); - if (Status != STATUS_SUCCESS) + if (!NT_SUCCESS(Status)) { return(Status); } Thread->StartAddress=StartRoutine; - HalInitTask(Thread,StartRoutine,StartContext); + Status = HalInitTask(Thread,StartRoutine,StartContext); + if (!NT_SUCCESS(Status)) + { + return(Status); + } if (ClientId!=NULL) {