mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
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:
parent
dfa5f04c63
commit
13541861b1
17 changed files with 337 additions and 243 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,12 +571,8 @@ LdrGetExportByName (
|
|||
* NOTE
|
||||
*
|
||||
*/
|
||||
static
|
||||
NTSTATUS
|
||||
LdrPerformRelocations (
|
||||
PIMAGE_NT_HEADERS NTHeaders,
|
||||
PVOID ImageBase
|
||||
)
|
||||
static NTSTATUS LdrPerformRelocations (PIMAGE_NT_HEADERS NTHeaders,
|
||||
PVOID ImageBase)
|
||||
{
|
||||
USHORT NumberOfEntries;
|
||||
PUSHORT pValue16;
|
||||
|
@ -589,10 +585,10 @@ LdrPerformRelocations (
|
|||
int i;
|
||||
|
||||
|
||||
RelocationRVA =
|
||||
NTHeaders->OptionalHeader
|
||||
RelocationRVA = NTHeaders->OptionalHeader
|
||||
.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]
|
||||
.VirtualAddress;
|
||||
|
||||
if (RelocationRVA)
|
||||
{
|
||||
RelocationDir = (PRELOCATION_DIRECTORY)
|
||||
|
@ -600,10 +596,8 @@ LdrPerformRelocations (
|
|||
|
||||
while (RelocationDir->SizeOfBlock)
|
||||
{
|
||||
Delta32 = (unsigned long) (
|
||||
ImageBase
|
||||
- NTHeaders->OptionalHeader.ImageBase
|
||||
);
|
||||
Delta32 = (ULONG)(ImageBase -
|
||||
NTHeaders->OptionalHeader.ImageBase);
|
||||
RelocationBlock = (PRELOCATION_ENTRY) (
|
||||
RelocationRVA
|
||||
+ 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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
NTSTATUS STDCALL NtDuplicateObject (IN HANDLE SourceProcessHandle,
|
||||
IN PHANDLE SourceHandle,
|
||||
IN HANDLE TargetProcessHandle,
|
||||
OUT PHANDLE TargetHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN BOOLEAN InheritHandle,
|
||||
ULONG Options
|
||||
)
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue