Fixed problem with handles not being released
authorDavid Welch <welch@cwcom.net>
Mon, 20 Dec 1999 02:14:40 +0000 (02:14 +0000)
committerDavid Welch <welch@cwcom.net>
Mon, 20 Dec 1999 02:14:40 +0000 (02:14 +0000)
Changed page fault handling to take account of the error code
Changed handle table locking

svn path=/trunk/; revision=894

17 files changed:
reactos/README
reactos/include/internal/mm.h
reactos/include/internal/ob.h
reactos/lib/ntdll/ldr/utils.c
reactos/ntoskrnl/hal/x86/spinlock.c
reactos/ntoskrnl/ke/i386/exp.c
reactos/ntoskrnl/ke/wait.c
reactos/ntoskrnl/mm/freelist.c
reactos/ntoskrnl/mm/i386/page.c
reactos/ntoskrnl/mm/marea.c
reactos/ntoskrnl/mm/mm.c
reactos/ntoskrnl/mm/section.c
reactos/ntoskrnl/ob/handle.c
reactos/ntoskrnl/ob/object.c
reactos/ntoskrnl/ps/create.c
reactos/ntoskrnl/ps/kill.c
reactos/ntoskrnl/ps/process.c

index 7d8bcab..c07458c 100644 (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
 
index 995d5a1..760795f 100644 (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
index 49b60bf..e2e33e9 100644 (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 */
index 0d2d9e5..26d6d41 100644 (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;
-
-
-       RelocationRVA =
-               NTHeaders->OptionalHeader
-                       .DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]
-                               .VirtualAddress;
-       if (RelocationRVA)
+   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)
        {
-               RelocationDir = (PRELOCATION_DIRECTORY)
-                       ((PCHAR)ImageBase + RelocationRVA);
-
-               while (RelocationDir->SizeOfBlock)
-               {
-                       Delta32 = (unsigned long) (
-                               ImageBase
-                               - NTHeaders->OptionalHeader.ImageBase
-                               );
-                       RelocationBlock = (PRELOCATION_ENTRY) (
-                               RelocationRVA
-                               + ImageBase
-                               + sizeof (RELOCATION_DIRECTORY)
-                               );
-                       NumberOfEntries = (
-                               RelocationDir->SizeOfBlock
-                               - sizeof (RELOCATION_DIRECTORY)
-                               )
-                               / sizeof (RELOCATION_ENTRY);
+          RelocationDir = (PRELOCATION_DIRECTORY)
+            ((PCHAR)ImageBase + RelocationRVA);
 
-                       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) (
+          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
-                               + 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)
index 995a187..05d1c09 100644 (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);
      }
 }
index 2394ad2..70924b9 100644 (file)
 #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;
          }
index 4c1ced0..3b1e31e 100644 (file)
@@ -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);
index ae4ddce..bc7b0b8 100644 (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);
+   
+   MiNrFreePages = MiNrFreePages + 1;
+   MiNrUsedPages = MiNrUsedPages - 1;
    
-   for (i=0; i<Nr; i++)
+   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);
index f1e6ef0..dd3da5d 100644 (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)
index fd77ab3..fb096eb 100644 (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++)
index a842042..3914848 100644 (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)
index ed0c091..d731381 100644 (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);
          }
      }
index cd969e4..1946ceb 100644 (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,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;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;
 }
index 440c21a..75c5c04 100644 (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);
      }
    
index 519dc5d..0e2d692 100644 (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)
index 129705d..77657b1 100644 (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;
index 3068c5c..38901f9 100644 (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);
 }