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
This commit is contained in:
David Welch 1999-12-20 02:14:40 +00:00
parent dfa5f04c63
commit 13541861b1
17 changed files with 337 additions and 243 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -17,15 +17,13 @@
#include <internal/i386/segment.h>
#include <internal/mmhal.h>
#include <internal/module.h>
#include <internal/mm.h>
#define NDEBUG
#include <internal/debug.h>
/* 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;
}

View file

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

View file

@ -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<MemorySizeInPages; i++)
{
MmPageArray[i].Flags = PHYSICAL_PAGE_FREE;
MmPageArray[i].ReferenceCount = 0;
InsertTailList(&FreePageListHead,
&MmPageArray[i].ListEntry);
}
@ -160,13 +165,24 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
return((PVOID)(LastKernelAddress + Reserved * PAGESIZE));
}
VOID MmFreePage(PVOID PhysicalAddress, ULONG Nr)
VOID MmReferencePage(PVOID PhysicalAddress)
{
ULONG i;
ULONG Start = (ULONG)PhysicalAddress / PAGESIZE;
KIRQL oldIrql;
DPRINT("MmFreePage(PhysicalAddress %x, Nr %x)\n", PhysicalAddress, Nr);
DPRINT("MmReferencePage(PhysicalAddress %x)\n", PhysicalAddress);
KeAcquireSpinLock(&PageListLock, &oldIrql);
MmPageArray[Start].ReferenceCount++;
KeReleaseSpinLock(&PageListLock, oldIrql);
}
VOID MmDereferencePage(PVOID PhysicalAddress)
{
ULONG Start = (ULONG)PhysicalAddress / PAGESIZE;
KIRQL oldIrql;
DPRINT("MmDereferencePage(PhysicalAddress %x)\n", PhysicalAddress);
if (((ULONG)PhysicalAddress) > 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; i<Nr; i++)
MiNrFreePages = MiNrFreePages + 1;
MiNrUsedPages = MiNrUsedPages - 1;
MmPageArray[Start].ReferenceCount--;
if (MmPageArray[Start].ReferenceCount == 0)
{
KeAcquireSpinLock(&UsedPageListLock, &oldIrql);
RemoveEntryList(&MmPageArray[Start + i].ListEntry);
MmPageArray[Start + i].Flags = PHYSICAL_PAGE_FREE;
KeReleaseSpinLock(&UsedPageListLock, oldIrql);
ExInterlockedInsertTailList(&FreePageListHead,
&MmPageArray[Start + i].ListEntry,
&FreePageListLock);
RemoveEntryList(&MmPageArray[Start].ListEntry);
MmPageArray[Start].Flags = PHYSICAL_PAGE_FREE;
InsertTailList(&FreePageListHead, &MmPageArray[Start].ListEntry);
}
KeReleaseSpinLock(&PageListLock, oldIrql);
}
@ -200,7 +215,7 @@ PVOID MmAllocPage(VOID)
DPRINT("MmAllocPage()\n");
ListEntry = ExInterlockedRemoveHeadList(&FreePageListHead,
&FreePageListLock);
&PageListLock);
DPRINT("ListEntry %x\n",ListEntry);
if (ListEntry == NULL)
{
@ -210,8 +225,9 @@ PVOID MmAllocPage(VOID)
PageDescriptor = CONTAINING_RECORD(ListEntry, PHYSICAL_PAGE, ListEntry);
DPRINT("PageDescriptor %x\n",PageDescriptor);
PageDescriptor->Flags = 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);

View file

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

View file

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

View file

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

View file

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

View file

@ -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;i<count;i++)
{
current = current->Flink;
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,6 +107,8 @@ NtDuplicateObject (
PEPROCESS SourceProcess;
PEPROCESS TargetProcess;
PHANDLE_REP SourceHandleRep;
KIRQL oldIrql;
PVOID ObjectBody;
ASSERT_IRQL(PASSIVE_LEVEL);
@ -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;
VOID
ObDeleteHandleTable(PEPROCESS Process)
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)
/*
* 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;i<HANDLE_BLOCK_ENTRIES;i++)
{
if (HandleBlock->handles[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;
}

View file

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

View file

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

View file

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

View file

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