From 13541861b148a5db000b4edaec52f06aaf2bc08b Mon Sep 17 00:00:00 2001 From: David Welch Date: Mon, 20 Dec 1999 02:14:40 +0000 Subject: [PATCH] Fixed problem with handles not being released Changed page fault handling to take account of the error code Changed handle table locking svn path=/trunk/; revision=894 --- reactos/README | 2 +- reactos/include/internal/mm.h | 4 +- reactos/include/internal/ob.h | 3 +- reactos/lib/ntdll/ldr/utils.c | 189 +++++++++++++-------------- reactos/ntoskrnl/hal/x86/spinlock.c | 6 +- reactos/ntoskrnl/ke/i386/exp.c | 6 +- reactos/ntoskrnl/ke/wait.c | 66 +++++----- reactos/ntoskrnl/mm/freelist.c | 60 +++++---- reactos/ntoskrnl/mm/i386/page.c | 4 +- reactos/ntoskrnl/mm/marea.c | 2 +- reactos/ntoskrnl/mm/mm.c | 13 +- reactos/ntoskrnl/mm/section.c | 9 +- reactos/ntoskrnl/ob/handle.c | 192 ++++++++++++++++++---------- reactos/ntoskrnl/ob/object.c | 13 +- reactos/ntoskrnl/ps/create.c | 6 +- reactos/ntoskrnl/ps/kill.c | 1 + reactos/ntoskrnl/ps/process.c | 4 +- 17 files changed, 337 insertions(+), 243 deletions(-) diff --git a/reactos/README b/reactos/README index 7d8bcabd268..c07458c9e66 100644 --- a/reactos/README +++ b/reactos/README @@ -5,7 +5,7 @@ About Reactos A project aiming to make an approximate clone of Windows NT, compatible with most Windows applications. -The project has a website at http://www.sid-dis.com/reactos +The project has a website at http://www.reactos.com/ 2. Building Reactos diff --git a/reactos/include/internal/mm.h b/reactos/include/internal/mm.h index 995d5a161cd..760795f56e4 100644 --- a/reactos/include/internal/mm.h +++ b/reactos/include/internal/mm.h @@ -94,7 +94,8 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress, ULONG LastKernelBase); PVOID MmAllocPage(VOID); -VOID MmFreePage(PVOID PhysicalAddress, ULONG Nr); +VOID MmDereferencePage(PVOID PhysicalAddress); +VOID MmReferencePage(PVOID PhysicalAddress); VOID MmDeletePageTable(PEPROCESS Process, PVOID Address); NTSTATUS MmCopyMmInfo(PEPROCESS Src, PEPROCESS Dest); NTSTATUS MmReleaseMmInfo(PEPROCESS Process); @@ -117,5 +118,6 @@ PVOID MiTryToSharePageInSection(PSECTION_OBJECT Section, ULONG Offset); NTSTATUS MmSafeCopyFromUser(PVOID Dest, PVOID Src, ULONG NumberOfBytes); NTSTATUS MmSafeCopyToUser(PVOID Dest, PVOID Src, ULONG NumberOfBytes); VOID MmInitPagingFile(VOID); +ULONG MmPageFault(ULONG cs, ULONG eip, ULONG error_code); #endif diff --git a/reactos/include/internal/ob.h b/reactos/include/internal/ob.h index 49b60bf9b3c..e2e33e9ce92 100644 --- a/reactos/include/internal/ob.h +++ b/reactos/include/internal/ob.h @@ -52,7 +52,6 @@ enum BOOL ObAddObjectToNameSpace(PUNICODE_STRING path, POBJECT_HEADER Object); VOID ObRegisterType(CSHORT id, OBJECT_TYPE* type); -VOID ObDeleteHandle(HANDLE Handle); NTSTATUS ObLookupObject(HANDLE rootdir, PWSTR string, PVOID* Object, PWSTR* UnparsedSection, ULONG Attributes); PVOID ObCreateObject(PHANDLE Handle, @@ -113,5 +112,7 @@ NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes, ULONG ObGetReferenceCount(PVOID Object); ULONG ObGetHandleCount(PVOID Object); +VOID ObCloseAllHandles(PEPROCESS Process); +VOID ObDeleteHandleTable(PEPROCESS Process); #endif /* __INCLUDE_INTERNAL_OBJMGR_H */ diff --git a/reactos/lib/ntdll/ldr/utils.c b/reactos/lib/ntdll/ldr/utils.c index 0d2d9e5547d..26d6d4106a3 100644 --- a/reactos/lib/ntdll/ldr/utils.c +++ b/reactos/lib/ntdll/ldr/utils.c @@ -1,4 +1,4 @@ -/* $Id: utils.c,v 1.20 1999/12/13 22:04:34 dwelch Exp $ +/* $Id: utils.c,v 1.21 1999/12/20 02:14:37 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -571,105 +571,99 @@ LdrGetExportByName ( * NOTE * */ -static -NTSTATUS -LdrPerformRelocations ( - PIMAGE_NT_HEADERS NTHeaders, - PVOID ImageBase - ) +static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS NTHeaders, + PVOID ImageBase) { - USHORT NumberOfEntries; - PUSHORT pValue16; - ULONG RelocationRVA; - ULONG Delta32; - ULONG Offset; - PULONG pValue32; - PRELOCATION_DIRECTORY RelocationDir; - PRELOCATION_ENTRY RelocationBlock; - int i; + USHORT NumberOfEntries; + PUSHORT pValue16; + ULONG RelocationRVA; + ULONG Delta32; + ULONG Offset; + PULONG pValue32; + PRELOCATION_DIRECTORY RelocationDir; + PRELOCATION_ENTRY RelocationBlock; + int i; - RelocationRVA = - NTHeaders->OptionalHeader - .DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC] - .VirtualAddress; - if (RelocationRVA) + RelocationRVA = NTHeaders->OptionalHeader + .DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC] + .VirtualAddress; + + if (RelocationRVA) { - RelocationDir = (PRELOCATION_DIRECTORY) - ((PCHAR)ImageBase + RelocationRVA); + RelocationDir = (PRELOCATION_DIRECTORY) + ((PCHAR)ImageBase + RelocationRVA); - while (RelocationDir->SizeOfBlock) - { - Delta32 = (unsigned long) ( + while (RelocationDir->SizeOfBlock) + { + Delta32 = (ULONG)(ImageBase - + NTHeaders->OptionalHeader.ImageBase); + RelocationBlock = (PRELOCATION_ENTRY) ( + RelocationRVA + + ImageBase + + sizeof (RELOCATION_DIRECTORY) + ); + NumberOfEntries = ( + RelocationDir->SizeOfBlock + - sizeof (RELOCATION_DIRECTORY) + ) + / sizeof (RELOCATION_ENTRY); + + for ( i = 0; + (i < NumberOfEntries); + i++ + ) + { + Offset = ( + RelocationBlock[i].TypeOffset + & 0xfff + ) + + RelocationDir->VirtualAddress; + /* + * What kind of relocations should we perform + * for the current entry? + */ + switch (RelocationBlock[i].TypeOffset >> 12) + { + case TYPE_RELOC_ABSOLUTE: + break; + + case TYPE_RELOC_HIGH: + pValue16 = (PUSHORT) (ImageBase + Offset); + *pValue16 += Delta32 >> 16; + break; + + case TYPE_RELOC_LOW: + pValue16 = (PUSHORT)(ImageBase + Offset); + *pValue16 += Delta32 & 0xffff; + break; + + case TYPE_RELOC_HIGHLOW: + pValue32 = (PULONG) (ImageBase + Offset); + *pValue32 += Delta32; + break; + + case TYPE_RELOC_HIGHADJ: + /* FIXME: do the highadjust fixup */ + DPRINT( + "TYPE_RELOC_HIGHADJ fixup not implemented" + ", sorry\n" + ); + return(STATUS_UNSUCCESSFUL); + + default: + DPRINT("unexpected fixup type\n"); + return STATUS_UNSUCCESSFUL; + } + } + RelocationRVA += RelocationDir->SizeOfBlock; + RelocationDir = (PRELOCATION_DIRECTORY) ( ImageBase - - NTHeaders->OptionalHeader.ImageBase - ); - RelocationBlock = (PRELOCATION_ENTRY) ( - RelocationRVA - + ImageBase - + sizeof (RELOCATION_DIRECTORY) - ); - NumberOfEntries = ( - RelocationDir->SizeOfBlock - - sizeof (RELOCATION_DIRECTORY) - ) - / sizeof (RELOCATION_ENTRY); - - for ( i = 0; - (i < NumberOfEntries); - i++ - ) - { - Offset = ( - RelocationBlock[i].TypeOffset - & 0xfff - ) - + RelocationDir->VirtualAddress; - /* - * What kind of relocations should we perform - * for the current entry? - */ - switch (RelocationBlock[i].TypeOffset >> 12) - { - case TYPE_RELOC_ABSOLUTE: - break; - - case TYPE_RELOC_HIGH: - pValue16 = (PUSHORT) (ImageBase + Offset); - *pValue16 += Delta32 >> 16; - break; - - case TYPE_RELOC_LOW: - pValue16 = (PUSHORT)(ImageBase + Offset); - *pValue16 += Delta32 & 0xffff; - break; - - case TYPE_RELOC_HIGHLOW: - pValue32 = (PULONG) (ImageBase + Offset); - *pValue32 += Delta32; - break; - - case TYPE_RELOC_HIGHADJ: - /* FIXME: do the highadjust fixup */ - DPRINT( - "TYPE_RELOC_HIGHADJ fixup not implemented" - ", sorry\n" - ); - return(STATUS_UNSUCCESSFUL); - - default: - DPRINT("unexpected fixup type\n"); - return STATUS_UNSUCCESSFUL; - } - } - RelocationRVA += RelocationDir->SizeOfBlock; - RelocationDir = (PRELOCATION_DIRECTORY) ( - ImageBase - + RelocationRVA - ); - } + + RelocationRVA + ); + } } - return STATUS_SUCCESS; + return STATUS_SUCCESS; } @@ -693,10 +687,10 @@ LdrPerformRelocations ( static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS NTHeaders, PVOID ImageBase) { - PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory; - ULONG Ordinal; - PDLL Module; - NTSTATUS Status; + PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory; + ULONG Ordinal; + PDLL Module; + NTSTATUS Status; DPRINT("LdrFixupImports(NTHeaders %x, ImageBase %x)\n", NTHeaders, ImageBase); @@ -708,6 +702,7 @@ static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS NTHeaders, ImageBase + NTHeaders->OptionalHeader .DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] .VirtualAddress); + DPRINT1("ImportModuleDirectory %x\n", ImportModuleDirectory); DPRINT("ImportModuleDirectory %x\n", ImportModuleDirectory); while (ImportModuleDirectory->dwRVAModuleName) diff --git a/reactos/ntoskrnl/hal/x86/spinlock.c b/reactos/ntoskrnl/hal/x86/spinlock.c index 995a187ac72..05d1c094e32 100644 --- a/reactos/ntoskrnl/hal/x86/spinlock.c +++ b/reactos/ntoskrnl/hal/x86/spinlock.c @@ -67,9 +67,11 @@ VOID KeAcquireSpinLockAtDpcLevel(PKSPIN_LOCK SpinLock) * SpinLock = Spinlock to acquire */ { - while (InterlockedExchange(&SpinLock->Lock, 1) == 1) + ULONG i; + + while ((i = InterlockedExchange(&SpinLock->Lock, 1)) == 1) { - DbgPrint("Spinning on spinlock %x\n", SpinLock); + DbgPrint("Spinning on spinlock %x current value %x\n", SpinLock, i); KeBugCheck(0); } } diff --git a/reactos/ntoskrnl/ke/i386/exp.c b/reactos/ntoskrnl/ke/i386/exp.c index 2394ad27768..70924b93669 100644 --- a/reactos/ntoskrnl/ke/i386/exp.c +++ b/reactos/ntoskrnl/ke/i386/exp.c @@ -17,15 +17,13 @@ #include #include #include +#include #define NDEBUG #include /* GLOBALS *****************************************************************/ -asmlinkage int page_fault_handler(unsigned int cs, - unsigned int eip); - static exception_hook* exception_hooks[256]={NULL,}; #define _STR(x) #x @@ -209,7 +207,7 @@ asmlinkage void exception_handler(unsigned int edi, if (type==14) { - if (page_fault_handler(cs&0xffff,eip)) + if (MmPageFault(cs&0xffff, eip, error_code)) { return; } diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index 4c1ced0da52..3b1e31ed9ed 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -156,7 +156,7 @@ static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr) NTSTATUS Status; DPRINT("KeDispatcherObjectWakeAll(hdr %x)\n",hdr); - + if (IsListEmpty(&hdr->WaitListHead)) { return(FALSE); @@ -171,38 +171,38 @@ static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr) if (current->WaitType == WaitAny) { DPRINT("WaitAny: Remove all wait blocks.\n"); - for( PrevBlock = current->Thread->WaitBlockList; PrevBlock; PrevBlock = PrevBlock->NextWaitBlock ) - if( PrevBlock != current ) - RemoveEntryList( &(PrevBlock->WaitListEntry) ); - current->Thread->WaitBlockList = 0; + for( PrevBlock = current->Thread->WaitBlockList; PrevBlock; PrevBlock = PrevBlock->NextWaitBlock ) + if( PrevBlock != current ) + RemoveEntryList( &(PrevBlock->WaitListEntry) ); + current->Thread->WaitBlockList = 0; } else { - DPRINT("WaitAll: Remove the current wait block only.\n"); - - PrevBlock = current->Thread->WaitBlockList; - if (PrevBlock == current) - { - DPRINT( "WaitAll: Current block is list head.\n" ); - current->Thread->WaitBlockList = current->NextWaitBlock; - } - else - { - DPRINT( "WaitAll: Current block is not list head.\n" ); - while ( PrevBlock && PrevBlock->NextWaitBlock != current) - { - PrevBlock = PrevBlock->NextWaitBlock; - } - if (PrevBlock) - { - PrevBlock->NextWaitBlock = current->NextWaitBlock; - } - } - } + DPRINT("WaitAll: Remove the current wait block only.\n"); + + PrevBlock = current->Thread->WaitBlockList; + if (PrevBlock == current) + { + DPRINT( "WaitAll: Current block is list head.\n" ); + current->Thread->WaitBlockList = current->NextWaitBlock; + } + else + { + DPRINT( "WaitAll: Current block is not list head.\n" ); + while ( PrevBlock && PrevBlock->NextWaitBlock != current) + { + PrevBlock = PrevBlock->NextWaitBlock; + } + if (PrevBlock) + { + PrevBlock->NextWaitBlock = current->NextWaitBlock; + } + } + } KiSideEffectsBeforeWake(hdr); - Status = current->WaitKey; + Status = current->WaitKey; if( current->Thread->WaitBlockList == NULL ) - PsUnfreezeThread( CONTAINING_RECORD( current->Thread,ETHREAD,Tcb ), &Status ); + PsUnfreezeThread( CONTAINING_RECORD( current->Thread,ETHREAD,Tcb ), &Status ); } return(TRUE); } @@ -229,10 +229,10 @@ static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr) if (current->WaitType == WaitAny) { DPRINT("WaitAny: Remove all wait blocks.\n"); - for( PrevBlock = current->Thread->WaitBlockList; PrevBlock; PrevBlock = PrevBlock->NextWaitBlock ) - if( PrevBlock != current ) - RemoveEntryList( &(PrevBlock->WaitListEntry) ); - current->Thread->WaitBlockList = 0; + for( PrevBlock = current->Thread->WaitBlockList; PrevBlock; PrevBlock = PrevBlock->NextWaitBlock ) + if( PrevBlock != current ) + RemoveEntryList( &(PrevBlock->WaitListEntry) ); + current->Thread->WaitBlockList = 0; } else { @@ -255,7 +255,7 @@ static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr) { PrevBlock->NextWaitBlock = current->NextWaitBlock; } - } + } } DPRINT("Waking %x\n",current->Thread); diff --git a/reactos/ntoskrnl/mm/freelist.c b/reactos/ntoskrnl/mm/freelist.c index ae4ddce3f1e..bc7b0b85563 100644 --- a/reactos/ntoskrnl/mm/freelist.c +++ b/reactos/ntoskrnl/mm/freelist.c @@ -32,6 +32,7 @@ typedef struct _PHYSICAL_PAGE { ULONG Flags; LIST_ENTRY ListEntry; + ULONG ReferenceCount; } PHYSICAL_PAGE, *PPHYSICAL_PAGE; /* GLOBALS ****************************************************************/ @@ -39,11 +40,9 @@ typedef struct _PHYSICAL_PAGE static PPHYSICAL_PAGE MmPageArray; static LIST_ENTRY UsedPageListHead; -static KSPIN_LOCK UsedPageListLock; +static KSPIN_LOCK PageListLock; static LIST_ENTRY FreePageListHead; -static KSPIN_LOCK FreePageListLock; static LIST_ENTRY BiosPageListHead; -static KSPIN_LOCK BiosPageListLock; ULONG MiNrFreePages; ULONG MiNrUsedPages; @@ -75,11 +74,9 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress, LastKernelAddress); InitializeListHead(&UsedPageListHead); - KeInitializeSpinLock(&UsedPageListLock); + KeInitializeSpinLock(&PageListLock); InitializeListHead(&FreePageListHead); - KeInitializeSpinLock(&FreePageListLock); InitializeListHead(&BiosPageListHead); - KeInitializeSpinLock(&BiosPageListLock); Reserved = (MemorySizeInPages * sizeof(PHYSICAL_PAGE)) / PAGESIZE; MmPageArray = (PHYSICAL_PAGE *)LastKernelAddress; @@ -97,6 +94,7 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress, for (; i<((ULONG)FirstPhysKernelAddress/PAGESIZE); i++) { MmPageArray[i].Flags = PHYSICAL_PAGE_FREE; + MmPageArray[i].ReferenceCount = 0; InsertTailList(&FreePageListHead, &MmPageArray[i].ListEntry); } @@ -105,12 +103,14 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress, for (; i<(0xa0000 / PAGESIZE); i++) { MmPageArray[i].Flags = PHYSICAL_PAGE_INUSE; + MmPageArray[i].ReferenceCount = 1; InsertTailList(&UsedPageListHead, &MmPageArray[i].ListEntry); } for (; i<(0x100000 / PAGESIZE); i++) { MmPageArray[i].Flags = PHYSICAL_PAGE_BIOS; + MmPageArray[i].ReferenceCount = 1; InsertTailList(&BiosPageListHead, &MmPageArray[i].ListEntry); } @@ -121,12 +121,14 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress, for (; i<(0xa0000 / PAGESIZE); i++) { MmPageArray[i].Flags = PHYSICAL_PAGE_FREE; + MmPageArray[i].ReferenceCount = 0; InsertTailList(&FreePageListHead, &MmPageArray[i].ListEntry); } for (; i<(0x100000 / PAGESIZE); i++) { MmPageArray[i].Flags = PHYSICAL_PAGE_BIOS; + MmPageArray[i].ReferenceCount = 1; InsertTailList(&BiosPageListHead, &MmPageArray[i].ListEntry); } @@ -135,6 +137,7 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress, for (; i<((ULONG)FirstPhysKernelAddress/PAGESIZE); i++) { MmPageArray[i].Flags = PHYSICAL_PAGE_FREE; + MmPageArray[i].ReferenceCount = 0; InsertTailList(&FreePageListHead, &MmPageArray[i].ListEntry); } @@ -143,6 +146,7 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress, for (; i<((ULONG)LastPhysKernelAddress/PAGESIZE); i++) { MmPageArray[i].Flags = PHYSICAL_PAGE_INUSE; + MmPageArray[i].ReferenceCount = 1; InsertTailList(&UsedPageListHead, &MmPageArray[i].ListEntry); } @@ -152,6 +156,7 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress, for (; i 0x400000) { @@ -174,20 +190,19 @@ VOID MmFreePage(PVOID PhysicalAddress, ULONG Nr) KeBugCheck(0); } - MiNrFreePages = MiNrFreePages + Nr; - MiNrUsedPages = MiNrUsedPages - Nr; + KeAcquireSpinLock(&PageListLock, &oldIrql); - for (i=0; iFlags = PHYSICAL_PAGE_INUSE; + PageDescriptor->ReferenceCount = 1; ExInterlockedInsertTailList(&UsedPageListHead, ListEntry, - &UsedPageListLock); + &PageListLock); DPRINT("PageDescriptor %x MmPageArray %x\n", PageDescriptor, MmPageArray); offset = (ULONG)((ULONG)PageDescriptor - (ULONG)MmPageArray); diff --git a/reactos/ntoskrnl/mm/i386/page.c b/reactos/ntoskrnl/mm/i386/page.c index f1e6ef0a979..dd3da5d2db1 100644 --- a/reactos/ntoskrnl/mm/i386/page.c +++ b/reactos/ntoskrnl/mm/i386/page.c @@ -64,7 +64,7 @@ NTSTATUS Mmi386ReleaseMmInfo(PEPROCESS Process) { DPRINT("Mmi386ReleaseMmInfo(Process %x)\n",Process); - MmFreePage(Process->Pcb.PageTableDirectory, 1); + MmDereferencePage(Process->Pcb.PageTableDirectory); Process->Pcb.PageTableDirectory = NULL; DPRINT("Finished Mmi386ReleaseMmInfo()\n"); @@ -181,7 +181,7 @@ VOID MmDeletePageEntry(PEPROCESS Process, PVOID Address, BOOL FreePage) *page_tlb); KeBugCheck(0); } - MmFreePage((PVOID)PAGE_MASK(*page_tlb),1); + MmDereferencePage((PVOID)PAGE_MASK(*page_tlb)); } *page_tlb = 0; if (Process != NULL && Process != CurrentProcess) diff --git a/reactos/ntoskrnl/mm/marea.c b/reactos/ntoskrnl/mm/marea.c index fd77ab36610..fb096ebf00d 100644 --- a/reactos/ntoskrnl/mm/marea.c +++ b/reactos/ntoskrnl/mm/marea.c @@ -438,7 +438,7 @@ NTSTATUS MmFreeMemoryArea(PEPROCESS Process, { PhysicalAddr = MmGetPhysicalAddress(MemoryArea->BaseAddress + (i*PAGESIZE)); - MmFreePage((PVOID)(ULONG)(PhysicalAddr.u.LowPart), 1); + MmDereferencePage((PVOID)(ULONG)(PhysicalAddr.u.LowPart)); } } for (i=0; i<=(MemoryArea->Length/PAGESIZE); i++) diff --git a/reactos/ntoskrnl/mm/mm.c b/reactos/ntoskrnl/mm/mm.c index a842042a533..3914848b9b3 100644 --- a/reactos/ntoskrnl/mm/mm.c +++ b/reactos/ntoskrnl/mm/mm.c @@ -234,8 +234,7 @@ NTSTATUS MmSectionHandleFault(MEMORY_AREA* MemoryArea, return(STATUS_SUCCESS); } -asmlinkage int page_fault_handler(unsigned int cs, - unsigned int eip) +ULONG MmPageFault(ULONG cs, ULONG eip, ULONG error_code) /* * FUNCTION: Handle a page fault */ @@ -249,11 +248,17 @@ asmlinkage int page_fault_handler(unsigned int cs, * Get the address for the page fault */ __asm__("movl %%cr2,%0\n\t" : "=d" (cr2)); - DPRINT("Page fault at address %x with eip %x in process %x\n",cr2,eip, - PsGetCurrentProcess()); +// DbgPrint("Page fault address %x eip %x process %x code %x\n",cr2,eip, +// PsGetCurrentProcess(), error_code); cr2 = PAGE_ROUND_DOWN(cr2); + if (error_code & 0x1) + { + DPRINT1("Page protection fault at %x with eip %x\n", cr2, eip); + return(0); + } + // DbgPrint("(%%"); if (KeGetCurrentIrql() >= DISPATCH_LEVEL) diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index ed0c091117c..d731381b327 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.c @@ -1,4 +1,4 @@ -/* $Id: section.c,v 1.18 1999/11/25 23:37:02 ekohl Exp $ +/* $Id: section.c,v 1.19 1999/12/20 02:14:39 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -56,6 +56,7 @@ PVOID MiTryToSharePageInSection(PSECTION_OBJECT Section, PhysPage = MmGetPhysicalAddressForProcess(current->Process, Address); + MmReferencePage((PVOID)PhysPage); KeReleaseSpinLock(&Section->ViewListLock, oldIrql); return((PVOID)PhysPage); } @@ -204,8 +205,12 @@ NTSTATUS STDCALL NtCreateSection (OUT PHANDLE SectionHandle, NULL); if (Status != STATUS_SUCCESS) { - // Delete section object + /* + * Delete section object + */ DPRINT("NtCreateSection() = %x\n",Status); + ZwClose(SectionHandle); + ObDereferenceObject(Section); return(Status); } } diff --git a/reactos/ntoskrnl/ob/handle.c b/reactos/ntoskrnl/ob/handle.c index cd969e457fe..1946ceba2f2 100644 --- a/reactos/ntoskrnl/ob/handle.c +++ b/reactos/ntoskrnl/ob/handle.c @@ -1,4 +1,5 @@ -/* $Id: handle.c,v 1.14 1999/12/02 20:53:54 dwelch Exp $ + +/* $Id: handle.c,v 1.15 1999/12/20 02:14:40 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -31,12 +32,12 @@ typedef struct { LIST_ENTRY entry; HANDLE_REP handles[HANDLE_BLOCK_ENTRIES]; -} HANDLE_BLOCK; +} HANDLE_BLOCK, *PHANDLE_BLOCK; /* FUNCTIONS ***************************************************************/ -static PHANDLE_REP ObpGetObjectByHandle(PEPROCESS Process, HANDLE h) +static PHANDLE_REP ObpGetObjectByHandle(PHANDLE_TABLE HandleTable, HANDLE h) /* * FUNCTION: Get the data structure for a handle * ARGUMENTS: @@ -54,13 +55,13 @@ static PHANDLE_REP ObpGetObjectByHandle(PEPROCESS Process, HANDLE h) DPRINT("ObpGetObjectByHandle(Process %x, h %x)\n",Process,h); - current = Process->Pcb.HandleTable.ListHead.Flink; + current = HandleTable->ListHead.Flink; DPRINT("current %x\n",current); for (i=0;iFlink; - if (current == (&(Process->Pcb.HandleTable.ListHead))) + if (current == (&(HandleTable->ListHead))) { return(NULL); } @@ -71,17 +72,13 @@ static PHANDLE_REP ObpGetObjectByHandle(PEPROCESS Process, HANDLE h) } -NTSTATUS -STDCALL -NtDuplicateObject ( - IN HANDLE SourceProcessHandle, - IN PHANDLE SourceHandle, - IN HANDLE TargetProcessHandle, - OUT PHANDLE TargetHandle, - IN ACCESS_MASK DesiredAccess, - IN BOOLEAN InheritHandle, - ULONG Options - ) +NTSTATUS STDCALL NtDuplicateObject (IN HANDLE SourceProcessHandle, + IN PHANDLE SourceHandle, + IN HANDLE TargetProcessHandle, + OUT PHANDLE TargetHandle, + IN ACCESS_MASK DesiredAccess, + IN BOOLEAN InheritHandle, + ULONG Options) /* * FUNCTION: Copies a handle from one process space to another * ARGUMENTS: @@ -110,7 +107,9 @@ NtDuplicateObject ( PEPROCESS SourceProcess; PEPROCESS TargetProcess; PHANDLE_REP SourceHandleRep; - + KIRQL oldIrql; + PVOID ObjectBody; + ASSERT_IRQL(PASSIVE_LEVEL); ObReferenceObjectByHandle(SourceProcessHandle, @@ -126,16 +125,26 @@ NtDuplicateObject ( (PVOID*)&TargetProcess, NULL); - SourceHandleRep = ObpGetObjectByHandle(SourceProcess, + KeAcquireSpinLock(&SourceProcess->Pcb.HandleTable.ListLock, &oldIrql); + SourceHandleRep = ObpGetObjectByHandle(&SourceProcess->Pcb.HandleTable, *SourceHandle); + if (SourceHandleRep == NULL) + { + KeReleaseSpinLock(&SourceProcess->Pcb.HandleTable.ListLock, oldIrql); + return(STATUS_INVALID_HANDLE); + } + ObjectBody = SourceHandleRep->ObjectBody; + BODY_TO_HEADER(ObjectBody)->RefCount++; if (Options & DUPLICATE_SAME_ACCESS) { DesiredAccess = SourceHandleRep->GrantedAccess; } + KeReleaseSpinLock(&SourceProcess->Pcb.HandleTable.ListLock, oldIrql); + ObCreateHandle(TargetProcess, - SourceHandleRep->ObjectBody, + ObjectBody, DesiredAccess, InheritHandle, TargetHandle); @@ -147,41 +156,77 @@ NtDuplicateObject ( ObDereferenceObject(TargetProcess); ObDereferenceObject(SourceProcess); + ObDereferenceObject(ObjectBody); return(STATUS_SUCCESS); } +VOID ObCloseAllHandles(PEPROCESS Process) +{ + KIRQL oldIrql; + PHANDLE_TABLE HandleTable; + PLIST_ENTRY current_entry; + PHANDLE_BLOCK current; + ULONG i; + PVOID ObjectBody; + + DPRINT("ObCloseAllHandles(Process %x)\n", Process); + + HandleTable = &Process->Pcb.HandleTable; + + KeAcquireSpinLock(&HandleTable->ListLock, &oldIrql); + + current_entry = HandleTable->ListHead.Flink; + + while (current_entry != &HandleTable->ListHead) + { + current = CONTAINING_RECORD(current_entry, HANDLE_BLOCK, entry); + + for (i = 0; i < HANDLE_BLOCK_ENTRIES; i++) + { + ObjectBody = current->handles[i].ObjectBody; + + if (ObjectBody != NULL) + { + DPRINT("Deleting handle to %x\n", Object); + + BODY_TO_HEADER(ObjectBody)->RefCount++; + BODY_TO_HEADER(ObjectBody)->HandleCount--; + current->handles[i].ObjectBody = NULL; + + KeReleaseSpinLock(&HandleTable->ListLock, oldIrql); + ObDereferenceObject(ObjectBody); + KeAcquireSpinLock(&HandleTable->ListLock, &oldIrql); + current_entry = &HandleTable->ListHead; + break; + } + } + + current_entry = current_entry->Flink; + } + KeReleaseSpinLock(&HandleTable->ListLock, oldIrql); + DPRINT("ObCloseAllHandles() finished\n"); +} -VOID -ObDeleteHandleTable(PEPROCESS Process) +VOID ObDeleteHandleTable(PEPROCESS Process) /* * FUNCTION: Deletes the handle table associated with a process */ { PLIST_ENTRY current = NULL; - ULONG i; PHANDLE_TABLE HandleTable = NULL; + ObCloseAllHandles(Process); + HandleTable = &Process->Pcb.HandleTable; current = RemoveHeadList(&HandleTable->ListHead); - while (current!=NULL) + while (current != &HandleTable->ListHead) { HANDLE_BLOCK* HandleBlock = CONTAINING_RECORD(current, HANDLE_BLOCK, entry); - - /* - * Deference every handle in block - */ - for (i=0;ihandles[i].ObjectBody != NULL) - { - ObDereferenceObject(HandleBlock->handles[i].ObjectBody); - } - } - + DPRINT("Freeing %x\n", HandleBlock); ExFreePool(HandleBlock); current = RemoveHeadList(&HandleTable->ListHead); @@ -254,15 +299,29 @@ VOID ObCreateHandleTable(PEPROCESS Parent, } -VOID ObDeleteHandle(HANDLE Handle) +PVOID ObDeleteHandle(PEPROCESS Process, HANDLE Handle) { PHANDLE_REP Rep; + PVOID ObjectBody; + KIRQL oldIrql; + PHANDLE_TABLE HandleTable; DPRINT("ObDeleteHandle(Handle %x)\n",Handle); - Rep = ObpGetObjectByHandle(PsGetCurrentProcess(),Handle); - Rep->ObjectBody=NULL; + HandleTable = &Process->Pcb.HandleTable; + + KeAcquireSpinLock(&HandleTable->ListLock, &oldIrql); + + Rep = ObpGetObjectByHandle(HandleTable, Handle); + ObjectBody = Rep->ObjectBody; + BODY_TO_HEADER(ObjectBody)->HandleCount--; + BODY_TO_HEADER(ObjectBody)->RefCount++; + Rep->ObjectBody = NULL; + + KeReleaseSpinLock(&HandleTable->ListLock, oldIrql); + DPRINT("Finished ObDeleteHandle()\n"); + return(ObjectBody); } @@ -286,7 +345,12 @@ NTSTATUS ObCreateHandle(PEPROCESS Process, PHANDLE_TABLE HandleTable; KIRQL oldlvl; - DPRINT("ObAddHandle(Process %x, obj %x)\n",Process,ObjectBody); + DPRINT("ObCreateHandle(Process %x, obj %x)\n",Process,ObjectBody); + + if (ObjectBody != NULL) + { + BODY_TO_HEADER(ObjectBody)->HandleCount++; + } HandleTable = &Process->Pcb.HandleTable; @@ -337,8 +401,7 @@ NTSTATUS ObCreateHandle(PEPROCESS Process, } -NTSTATUS -ObReferenceObjectByHandle(HANDLE Handle, +NTSTATUS ObReferenceObjectByHandle(HANDLE Handle, ACCESS_MASK DesiredAccess, POBJECT_TYPE ObjectType, KPROCESSOR_MODE AccessMode, @@ -361,6 +424,9 @@ ObReferenceObjectByHandle(HANDLE Handle, { PHANDLE_REP HandleRep; POBJECT_HEADER ObjectHeader; + KIRQL oldIrql; + PVOID ObjectBody; + ACCESS_MASK GrantedAccess; ASSERT_IRQL(PASSIVE_LEVEL); @@ -369,7 +435,9 @@ ObReferenceObjectByHandle(HANDLE Handle, ObjectType,AccessMode,Object); - + /* + * Handle special handle names + */ if (Handle == NtCurrentProcess() && (ObjectType == PsProcessType || ObjectType == NULL)) { @@ -397,15 +465,23 @@ ObReferenceObjectByHandle(HANDLE Handle, return(STATUS_OBJECT_TYPE_MISMATCH); } - HandleRep = ObpGetObjectByHandle(PsGetCurrentProcess(), + KeAcquireSpinLock(&PsGetCurrentProcess()->Pcb.HandleTable.ListLock, + &oldIrql); + HandleRep = ObpGetObjectByHandle(&PsGetCurrentProcess()->Pcb.HandleTable, Handle); if (HandleRep == NULL || HandleRep->ObjectBody == NULL) { - CHECKPOINT; + KeReleaseSpinLock(&PsGetCurrentProcess()->Pcb.HandleTable.ListLock, + oldIrql); return(STATUS_INVALID_HANDLE); } + ObjectBody = HandleRep->ObjectBody; + BODY_TO_HEADER(ObjectBody)->RefCount++; + GrantedAccess = HandleRep->GrantedAccess; + KeReleaseSpinLock(&PsGetCurrentProcess()->Pcb.HandleTable.ListLock, + oldIrql); - ObjectHeader = BODY_TO_HEADER(HandleRep->ObjectBody); + ObjectHeader = BODY_TO_HEADER(ObjectBody); if (ObjectType != NULL && ObjectType != ObjectHeader->ObjectType) { @@ -413,15 +489,13 @@ ObReferenceObjectByHandle(HANDLE Handle, return(STATUS_OBJECT_TYPE_MISMATCH); } - if (!(HandleRep->GrantedAccess & DesiredAccess)) + if (!(GrantedAccess & DesiredAccess)) { CHECKPOINT; return(STATUS_ACCESS_DENIED); } - ObjectHeader->RefCount++; - - *Object = HandleRep->ObjectBody; + *Object = ObjectBody; CHECKPOINT; return(STATUS_SUCCESS); @@ -446,36 +520,22 @@ NTSTATUS STDCALL NtClose(HANDLE Handle) { PVOID ObjectBody; POBJECT_HEADER Header; - PHANDLE_REP HandleRep; assert_irql(PASSIVE_LEVEL); DPRINT("NtClose(Handle %x)\n",Handle); - HandleRep = ObpGetObjectByHandle(PsGetCurrentProcess(), - Handle); - if (HandleRep == NULL) - { - return STATUS_INVALID_HANDLE; - } - ObjectBody = HandleRep->ObjectBody; - - HandleRep->ObjectBody = NULL; - + ObjectBody = ObDeleteHandle(PsGetCurrentProcess(), Handle); + Header = BODY_TO_HEADER(ObjectBody); - Header->RefCount++; - Header->HandleCount--; - if ((Header->ObjectType != NULL) && (Header->ObjectType->Close != NULL)) { Header->ObjectType->Close(ObjectBody, Header->HandleCount); } - Header->RefCount--; - - ObPerformRetentionChecks(Header); + ObDereferenceObject(ObjectBody); return STATUS_SUCCESS; } diff --git a/reactos/ntoskrnl/ob/object.c b/reactos/ntoskrnl/ob/object.c index 440c21a2aac..75c5c04746e 100644 --- a/reactos/ntoskrnl/ob/object.c +++ b/reactos/ntoskrnl/ob/object.c @@ -34,7 +34,6 @@ VOID ObInitializeObject(POBJECT_HEADER ObjectHeader, RtlInitUnicodeString(&(ObjectHeader->Name),NULL); if (Handle != NULL) { - ObjectHeader->HandleCount = 1; ObCreateHandle(PsGetCurrentProcess(), HEADER_TO_BODY(ObjectHeader), DesiredAccess, @@ -209,10 +208,16 @@ NTSTATUS ObPerformRetentionChecks(POBJECT_HEADER Header) // DPRINT("ObPerformRetentionChecks(Header %x), RefCount %d, HandleCount %d\n", // Header,Header->RefCount,Header->HandleCount); - if (Header->RefCount < 0 || Header->HandleCount < 0) + if (Header->RefCount < 0) { - DbgPrint("Object %x/%x has invalid reference or handle count\n", - Header,HEADER_TO_BODY(Header)); + DbgPrint("Object %x/%x has invalid reference count (%d)\n", + Header, HEADER_TO_BODY(Header), Header->RefCount); + KeBugCheck(0); + } + if (Header->HandleCount < 0) + { + DbgPrint("Object %x/%x has invalid handle count (%d)\n", + Header, HEADER_TO_BODY(Header), Header->HandleCount); KeBugCheck(0); } diff --git a/reactos/ntoskrnl/ps/create.c b/reactos/ntoskrnl/ps/create.c index 519dc5d9bdd..0e2d692f07a 100644 --- a/reactos/ntoskrnl/ps/create.c +++ b/reactos/ntoskrnl/ps/create.c @@ -1,4 +1,4 @@ -/* $Id: create.c,v 1.3 1999/12/18 07:33:53 phreak Exp $ +/* $Id: create.c,v 1.4 1999/12/20 02:14:40 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -72,7 +72,8 @@ VOID PsBeginThread(PKSTART_ROUTINE StartRoutine, PVOID StartContext) VOID PiDeleteThread(PVOID ObjectBody) { KIRQL oldIrql; - DPRINT("PiDeleteThread(ObjectBody %x)\n",ObjectBody); + + DPRINT1("PiDeleteThread(ObjectBody %x)\n",ObjectBody); KeAcquireSpinLock(&PiThreadListLock, &oldIrql); ObDereferenceObject(((PETHREAD)ObjectBody)->ThreadsProcess); @@ -81,6 +82,7 @@ VOID PiDeleteThread(PVOID ObjectBody) RemoveEntryList(&((PETHREAD)ObjectBody)->Tcb.ThreadListEntry); HalReleaseTask((PETHREAD)ObjectBody); KeReleaseSpinLock(&PiThreadListLock, oldIrql); + DPRINT1("PiDeleteThread() finished\n"); } VOID PiCloseThread(PVOID ObjectBody, ULONG HandleCount) diff --git a/reactos/ntoskrnl/ps/kill.c b/reactos/ntoskrnl/ps/kill.c index 129705d4374..77657b15c82 100644 --- a/reactos/ntoskrnl/ps/kill.c +++ b/reactos/ntoskrnl/ps/kill.c @@ -161,6 +161,7 @@ NTSTATUS STDCALL PiTerminateProcess(PEPROCESS Process, Process, ExitStatus); PiTerminateProcessThreads(Process, ExitStatus); + ObCloseAllHandles(Process); KeRaiseIrql(DISPATCH_LEVEL, &oldlvl); Process->Pcb.ProcessState = PROCESS_STATE_TERMINATED; Process->Pcb.DispatcherHeader.SignalState = TRUE; diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index 3068c5c461a..38901f91be8 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -131,11 +131,13 @@ VOID PiDeleteProcess(PVOID ObjectBody) { KIRQL oldIrql; - DPRINT("PiDeleteProcess(ObjectBody %x)\n",ObjectBody); + DPRINT1("PiDeleteProcess(ObjectBody %x)\n",ObjectBody); + KeAcquireSpinLock(&PsProcessListLock, &oldIrql); RemoveEntryList(&((PEPROCESS)ObjectBody)->Pcb.ProcessListEntry); KeReleaseSpinLock(&PsProcessListLock, oldIrql); (VOID)MmReleaseMmInfo((PEPROCESS)ObjectBody); + ObDeleteHandleTable((PEPROCESS)ObjectBody); }