Close section handle after NtCreateProces in KERNEL32.CreateProcess

Cleanup after file object dereference
Cleanup after section object dereference

svn path=/trunk/; revision=1678
This commit is contained in:
David Welch 2001-03-09 14:40:28 +00:00
parent 6e9d388644
commit d520a12907
6 changed files with 283 additions and 160 deletions

View file

@ -1,4 +1,4 @@
/* $Id: close.c,v 1.4 2001/01/16 09:55:02 dwelch Exp $
/* $Id: close.c,v 1.5 2001/03/09 14:40:28 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -31,7 +31,7 @@ VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
DPRINT ("VfatCloseFile(DeviceExt %x, FileObject %x)\n",
DeviceExt, FileObject);
//FIXME : update entry in directory ?
/* FIXME : update entry in directory? */
pCcb = (PVFATCCB) (FileObject->FsContext2);
DPRINT ("pCcb %x\n", pCcb);
@ -45,6 +45,7 @@ VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
pFcb->RefCount--;
if (pFcb->RefCount <= 0)
{
CcReleaseFileCache(FileObject, pFcb->RFCB.Bcb);
KeAcquireSpinLock (&DeviceExt->FcbListLock, &oldIrql);
RemoveEntryList (&pFcb->FcbListEntry);
KeReleaseSpinLock (&DeviceExt->FcbListLock, oldIrql);

View file

@ -1,4 +1,4 @@
/* $Id: create.c,v 1.35 2001/02/10 22:51:08 dwelch Exp $
/* $Id: create.c,v 1.36 2001/03/09 14:40:27 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@ -31,10 +31,8 @@
/* FUNCTIONS ****************************************************************/
WINBOOL
STDCALL
CreateProcessA (
LPCSTR lpApplicationName,
WINBOOL STDCALL
CreateProcessA (LPCSTR lpApplicationName,
LPSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
@ -43,8 +41,7 @@ CreateProcessA (
LPVOID lpEnvironment,
LPCSTR lpCurrentDirectory,
LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
)
LPPROCESS_INFORMATION lpProcessInformation)
/*
* FUNCTION: The CreateProcess function creates a new process and its
* primary thread. The new process executes the specified executable file
@ -124,7 +121,8 @@ CreateProcessA (
}
HANDLE STDCALL KlCreateFirstThread(HANDLE ProcessHandle,
HANDLE STDCALL
KlCreateFirstThread(HANDLE ProcessHandle,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
@ -200,7 +198,8 @@ HANDLE STDCALL KlCreateFirstThread(HANDLE ProcessHandle,
return(ThreadHandle);
}
HANDLE KlMapFile(LPCWSTR lpApplicationName,
HANDLE
KlMapFile(LPCWSTR lpApplicationName,
LPCWSTR lpCommandLine)
{
HANDLE hFile;
@ -270,7 +269,8 @@ HANDLE KlMapFile(LPCWSTR lpApplicationName,
return(hSection);
}
static NTSTATUS KlInitPeb (HANDLE ProcessHandle,
static NTSTATUS
KlInitPeb (HANDLE ProcessHandle,
PRTL_USER_PROCESS_PARAMETERS Ppb)
{
NTSTATUS Status;
@ -368,7 +368,8 @@ static NTSTATUS KlInitPeb (HANDLE ProcessHandle,
}
WINBOOL STDCALL CreateProcessW(LPCWSTR lpApplicationName,
WINBOOL STDCALL
CreateProcessW(LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
@ -490,6 +491,11 @@ WINBOOL STDCALL CreateProcessW(LPCWSTR lpApplicationName,
NULL,
NULL);
/*
* Close the section
*/
NtClose(hSection);
/*
* Get some information about the process
*/

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: view.c,v 1.17 2001/03/08 22:06:01 dwelch Exp $
/* $Id: view.c,v 1.18 2001/03/09 14:40:27 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -190,8 +190,8 @@ CcRequestCacheSegment(PBCB Bcb,
return(STATUS_SUCCESS);
}
static
VOID CcFreeCachePage(PVOID Context, PVOID Address, ULONG PhysAddr)
STATIC VOID
CcFreeCachePage(PVOID Context, PVOID Address, ULONG PhysAddr)
{
if (PhysAddr != 0)
{
@ -200,13 +200,13 @@ VOID CcFreeCachePage(PVOID Context, PVOID Address, ULONG PhysAddr)
}
NTSTATUS STDCALL
CcFreeCacheSegment(PBCB Bcb,
PCACHE_SEGMENT CacheSeg)
CcFreeCacheSegment(PBCB Bcb, PCACHE_SEGMENT CacheSeg)
/*
* FUNCTION: Releases a cache segment associated with a BCB
*/
{
MmFreeMemoryArea(NULL,
DPRINT("Freeing cache segment %x\n", CacheSeg);
MmFreeMemoryArea(MmGetKernelAddressSpace(),
CacheSeg->BaseAddress,
Bcb->CacheSegmentSize,
CcFreeCachePage,
@ -216,8 +216,7 @@ CcFreeCacheSegment(PBCB Bcb,
}
NTSTATUS STDCALL
CcReleaseFileCache(PFILE_OBJECT FileObject,
PBCB Bcb)
CcReleaseFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
/*
* FUNCTION: Releases the BCB associated with a file object
*/
@ -225,16 +224,16 @@ CcReleaseFileCache(PFILE_OBJECT FileObject,
PLIST_ENTRY current_entry;
PCACHE_SEGMENT current;
DPRINT("CcReleaseFileCache(FileObject %x, Bcb %x)\n",
FileObject, Bcb);
DPRINT("CcReleaseFileCache(FileObject %x, Bcb %x)\n", FileObject, Bcb);
MmFreeSectionSegments(FileObject);
current_entry = Bcb->CacheSegmentListHead.Flink;
while (current_entry != (&Bcb->CacheSegmentListHead))
while (current_entry != &Bcb->CacheSegmentListHead)
{
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, ListEntry);
current_entry = current_entry->Flink;
CcFreeCacheSegment(Bcb,
current);
CcFreeCacheSegment(Bcb, current);
}
ExFreePool(Bcb);

View file

@ -421,5 +421,13 @@ VOID
MmMarkPageMapped(PVOID PhysicalAddress);
VOID
MmMarkPageUnmapped(PVOID PhysicalAddress);
VOID
MmFreeSectionSegments(PFILE_OBJECT FileObject);
typedef struct _MM_IMAGE_SECTION_OBJECT
{
ULONG NrSegments;
MM_SECTION_SEGMENT Segments[0];
} MM_IMAGE_SECTION_OBJECT, *PMM_IMAGE_SECTION_OBJECT;
#endif

View file

@ -1,4 +1,4 @@
/* $Id: npool.c,v 1.36 2001/03/07 16:48:43 dwelch Exp $
/* $Id: npool.c,v 1.37 2001/03/09 14:40:28 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -50,8 +50,7 @@ typedef struct _BLOCK_HDR
{
ULONG magic;
ULONG size;
struct _BLOCK_HDR* previous;
struct _BLOCK_HDR* next;
LIST_ENTRY ListEntry;
ULONG Tag;
PVOID Caller;
struct _BLOCK_HDR* tag_next;
@ -68,8 +67,8 @@ static unsigned int kernel_pool_base = 0;
/*
* Pointer to the first block in the free list
*/
static BLOCK_HDR* free_list_head = NULL;
static BLOCK_HDR* used_list_head = NULL;
static LIST_ENTRY FreeBlockListHead;
static LIST_ENTRY UsedBlockListHead;
static ULONG nr_free_blocks;
ULONG EiNrUsedBlocks = 0;
@ -168,6 +167,8 @@ VOID ExInitNonPagedPool(ULONG BaseAddress)
KeInitializeSpinLock(&MmNpoolLock);
MmInitKernelMap((PVOID)BaseAddress);
memset(tag_hash_table, 0, sizeof(tag_hash_table));
InitializeListHead(&FreeBlockListHead);
InitializeListHead(&UsedBlockListHead);
}
VOID static
@ -202,8 +203,12 @@ MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly)
ULONG CurrentTag;
ULONG CurrentNrBlocks;
ULONG CurrentSize;
ULONG TotalBlocks;
ULONG TotalSize;
DbgPrint("******* Dumping non paging pool stats ******\n");
TotalBlocks = 0;
TotalSize = 0;
for (i = 0; i < TAG_HASH_TABLE_SIZE; i++)
{
CurrentTag = 0;
@ -226,7 +231,9 @@ MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly)
if (!NewOnly || !current->Dumped)
{
CurrentNrBlocks++;
TotalBlocks++;
CurrentSize = CurrentSize + current->size;
TotalSize = TotalSize + current->size;
current->Dumped = TRUE;
}
current = current->tag_next;
@ -236,20 +243,33 @@ MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly)
MiDumpTagStats(CurrentTag, CurrentNrBlocks, CurrentSize);
}
}
if (TotalBlocks != 0)
{
DbgPrint("TotalBlocks %d TotalSize %d AverageSize %d\n",
TotalBlocks, TotalSize, TotalSize / TotalBlocks);
}
else
{
DbgPrint("TotalBlocks %d TotalSize %d\n",
TotalBlocks, TotalSize);
}
DbgPrint("***************** Dump Complete ***************\n");
}
VOID
MiDebugDumpNonPagedPool(BOOLEAN NewOnly)
{
BLOCK_HDR* current = used_list_head;
BLOCK_HDR* current;
PLIST_ENTRY current_entry;
KIRQL oldIrql;
KeAcquireSpinLock(&MmNpoolLock, &oldIrql);
DbgPrint("******* Dumping non paging pool contents ******\n");
while (current != NULL)
current_entry = UsedBlockListHead.Flink;
while (current_entry != &UsedBlockListHead)
{
current = CONTAINING_RECORD(current_entry, BLOCK_HDR, ListEntry);
if (!NewOnly || !current->Dumped)
{
CHAR c1, c2, c3, c4;
@ -272,7 +292,7 @@ MiDebugDumpNonPagedPool(BOOLEAN NewOnly)
}
current->Dumped = TRUE;
}
current=current->next;
current_entry = current_entry->Flink;
}
DbgPrint("***************** Dump Complete ***************\n");
KeReleaseSpinLock(&MmNpoolLock, oldIrql);
@ -449,19 +469,86 @@ static void validate_kernel_pool(void)
}
#endif
static void add_to_free_list(BLOCK_HDR* blk)
#if 0
STATIC VOID
free_pages(BLOCK_HDR* blk)
{
if (PAGE_ROUND_UP(((unsigned int)blk)) !=
PAGE_ROUND_DOWN(((unsigned int)blk + blk->size)))
{
}
}
#endif
#if 0
STATIC VOID
merge_free_block(BLOCK_HDR* blk)
{
PLIST_ENTRY next_entry;
BLOCK_HDR* next;
PLIST_ENTRY previous_entry;
BLOCK_HDR* previous;
next_entry = blk->ListEntry.Flink;
if (next_entry != &FreeBlockListHead)
{
next = CONTAINING_RECORD(next_entry, BLOCK_HDR, ListEntry);
if (((unsigned int)blk + blk->size) == (unsigned int)next)
{
RemoveEntryList(&next->ListEntry);
blk->size = blk->size + sizeof(BLOCK_HDR) + next->size;
}
}
previous_entry = blk->ListEntry.Blink;
if (previous_entry != &FreeBlockListHead)
{
previous = CONTAINING_RECORD(previous_entry, BLOCK_HDR, ListEntry);
if (((unsigned int)previous + previous->size) == (unsigned int)blk)
{
RemoveEntryList(&blk->ListEntry);
previous->size = previous->size + sizeof(BLOCK_HDR) + blk->size;
}
}
}
#endif
STATIC VOID
add_to_free_list(BLOCK_HDR* blk)
/*
* FUNCTION: add the block to the free list (internal)
*/
{
blk->next=free_list_head;
blk->previous=NULL;
if (free_list_head!=NULL)
#if 0
PLIST_ENTRY current_entry;
PLIST_ENTRY next_entry;
BLOCK_HDR* current;
BLOCK_HDR* next;
current_entry = FreeBlockListHead.Flink;
next_entry = FreeBlockListHead.Flink->Flink;
while (current_entry != &FreeBlockListHead &&
next_entry != &FreeBlockListHead)
{
free_list_head->previous=blk;
current = CONTAINING_RECORD(current_entry, BLOCK_HDR, ListEntry);
next = CONTAINING_RECORD(next_entry, BLOCK_HDR, ListEntry);
if ((unsigned int)current < (unsigned int)blk &&
(unsigned int)next > (unsigned int)blk)
{
InsertHeadList(current_entry, &blk->ListEntry);
return;
}
free_list_head=blk;
current_entry = current_entry->Flink;
next_entry = next_entry->Flink;
}
InsertTailList(&FreeBlockListHead, &blk->ListEntry);
nr_free_blocks++;
#else
InsertHeadList(&FreeBlockListHead, &blk->ListEntry);
nr_free_blocks++;
#endif
}
static void add_to_used_list(BLOCK_HDR* blk)
@ -469,70 +556,21 @@ static void add_to_used_list(BLOCK_HDR* blk)
* FUNCTION: add the block to the used list (internal)
*/
{
blk->next=used_list_head;
blk->previous=NULL;
if (used_list_head!=NULL)
{
used_list_head->previous=blk;
}
used_list_head=blk;
InsertHeadList(&UsedBlockListHead, &blk->ListEntry);
EiNrUsedBlocks++;
}
static void remove_from_free_list(BLOCK_HDR* current)
{
if (current->next==NULL&&current->previous==NULL)
{
free_list_head=NULL;
}
else
{
if (current->next==NULL)
{
current->previous->next=NULL;
}
else if (current->previous==NULL)
{
current->next->previous=NULL;
free_list_head=current->next;
}
else
{
current->next->previous=current->previous;
current->previous->next=current->next;
}
}
RemoveEntryList(&current->ListEntry);
nr_free_blocks--;
}
static void remove_from_used_list(BLOCK_HDR* current)
{
if (current->next==NULL&&current->previous==NULL)
{
used_list_head=NULL;
}
else
{
if (current->previous==NULL)
{
current->next->previous=NULL;
used_list_head=current->next;
}
else
{
current->previous->next=current->next;
}
if (current->next!=NULL)
{
current->next->previous=current->previous;
}
else
{
current->previous->next=NULL;
}
}
RemoveEntryList(&current->ListEntry);
EiNrUsedBlocks--;
}
@ -646,24 +684,13 @@ static void* take_block(BLOCK_HDR* current, unsigned int size,
free_blk = (BLOCK_HDR *)(((int)current)
+ sizeof(BLOCK_HDR) + size);
free_blk->magic = BLOCK_HDR_FREE_MAGIC;
free_blk->next = current->next;
free_blk->previous = current->previous;
if (current->next)
{
current->next->previous = free_blk;
}
if (current->previous)
{
current->previous->next = free_blk;
}
InsertHeadList(&current->ListEntry, &free_blk->ListEntry);
free_blk->size = current->size - (sizeof(BLOCK_HDR) + size);
if (current==free_list_head)
{
free_list_head=free_blk;
}
current->size=size;
add_to_used_list(current);
RemoveEntryList(&current->ListEntry);
InsertHeadList(&UsedBlockListHead, &current->ListEntry);
EiNrUsedBlocks++;
current->magic = BLOCK_HDR_USED_MAGIC;
current->Tag = Tag;
current->Caller = Caller;
@ -746,6 +773,7 @@ PVOID STDCALL ExAllocateNonPagedPoolWithTag(ULONG Type,
PVOID Caller)
{
BLOCK_HDR* current = NULL;
PLIST_ENTRY current_entry;
PVOID block;
BLOCK_HDR* best = NULL;
KIRQL oldIrql;
@ -770,21 +798,18 @@ PVOID STDCALL ExAllocateNonPagedPoolWithTag(ULONG Type,
/*
* Look for an already created block of sufficent size
*/
current=free_list_head;
// defrag_free_list();
while (current!=NULL)
current_entry = FreeBlockListHead.Flink;
while (current_entry != &FreeBlockListHead)
{
OLD_DPRINT("current %x size %x next %x\n",current,current->size,
current->next);
current = CONTAINING_RECORD(current_entry, BLOCK_HDR, ListEntry);
if (current->size >= Size &&
(best == NULL ||
current->size < best->size))
(best == NULL || current->size < best->size))
{
best = current;
}
current=current->next;
current_entry = current_entry->Flink;
}
if (best != NULL)
{

View file

@ -1,4 +1,4 @@
/* $Id: section.c,v 1.49 2001/03/08 22:06:02 dwelch Exp $
/* $Id: section.c,v 1.50 2001/03/09 14:40:28 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -38,6 +38,63 @@ static GENERIC_MAPPING MmpSectionMapping = {
/* FUNCTIONS *****************************************************************/
VOID
MmFreePageTablesSectionSegment(PMM_SECTION_SEGMENT Segment)
{
ULONG i;
for (i = 0; i < NR_SECTION_PAGE_TABLES; i++)
{
if (Segment->PageDirectory.PageTables[i] != NULL)
{
ExFreePool(Segment->PageDirectory.PageTables[i]);
}
}
}
VOID
MmFreeSectionSegments(PFILE_OBJECT FileObject)
{
if (FileObject->SectionObjectPointers->ImageSectionObject != NULL)
{
PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
ULONG i;
ImageSectionObject =
(PMM_IMAGE_SECTION_OBJECT)FileObject->SectionObjectPointers->
ImageSectionObject;
for (i = 0; i < ImageSectionObject->NrSegments; i++)
{
if (ImageSectionObject->Segments[i].ReferenceCount != 0)
{
DPRINT1("Image segment %d still referenced (was %d)\n", i,
ImageSectionObject->Segments[i].ReferenceCount);
KeBugCheck(0);
}
MmFreePageTablesSectionSegment(&ImageSectionObject->Segments[i]);
}
ExFreePool(ImageSectionObject);
FileObject->SectionObjectPointers->ImageSectionObject = NULL;
}
if (FileObject->SectionObjectPointers->DataSectionObject != NULL)
{
PMM_SECTION_SEGMENT Segment;
Segment = (PMM_SECTION_SEGMENT)FileObject->SectionObjectPointers->
DataSectionObject;
if (Segment->ReferenceCount != 0)
{
DPRINT1("Data segment still referenced\n");
KeBugCheck(0);
}
MmFreePageTablesSectionSegment(Segment);
ExFreePool(Segment);
FileObject->SectionObjectPointers->DataSectionObject = NULL;
}
}
NTSTATUS
MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
PMEMORY_AREA MArea,
@ -78,6 +135,8 @@ MmUnlockSectionSegment(PMM_SECTION_SEGMENT Segment)
KeReleaseMutex(&Segment->Lock, FALSE);
}
VOID
MmSetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
ULONG Offset,
@ -662,7 +721,27 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
VOID
MmpDeleteSection(PVOID ObjectBody)
{
PSECTION_OBJECT Section = (PSECTION_OBJECT)ObjectBody;
DPRINT("MmpDeleteSection(ObjectBody %x)\n", ObjectBody);
if (Section->Flags & MM_IMAGE_SECTION)
{
ULONG i;
for (i = 0; i < Section->NrSegments; i++)
{
InterlockedDecrement(&Section->Segments[i].ReferenceCount);
}
}
else
{
InterlockedDecrement(&Section->Segments->ReferenceCount);
}
if (Section->FileObject != NULL)
{
ObDereferenceObject(Section->FileObject);
Section->FileObject = NULL;
}
}
VOID
@ -1104,6 +1183,7 @@ MmCreateImageSection(PHANDLE SectionHandle,
PIMAGE_SECTION_HEADER ImageSections;
PMM_SECTION_SEGMENT SectionSegments;
ULONG NrSegments;
PMM_IMAGE_SECTION_OBJECT ImageSectionObject;
/*
* Check the protection
@ -1316,12 +1396,13 @@ MmCreateImageSection(PHANDLE SectionHandle,
if (FileObject->SectionObjectPointers->ImageSectionObject == NULL)
{
ULONG i;
ULONG Size;
SectionSegments =
ExAllocatePoolWithTag(NonPagedPool,
sizeof(MM_SECTION_SEGMENT) * NrSegments,
TAG_MM_SECTION_SEGMENT);
if (SectionSegments == NULL)
Size = sizeof(MM_IMAGE_SECTION_OBJECT) +
(sizeof(MM_SECTION_SEGMENT) * NrSegments);
ImageSectionObject =
ExAllocatePoolWithTag(NonPagedPool, Size, TAG_MM_SECTION_SEGMENT);
if (ImageSectionObject == NULL)
{
KeSetEvent((PVOID)&FileObject->Lock, IO_NO_INCREMENT, FALSE);
ZwClose(*SectionHandle);
@ -1330,6 +1411,8 @@ MmCreateImageSection(PHANDLE SectionHandle,
ExFreePool(ImageSections);
return(STATUS_NO_MEMORY);
}
ImageSectionObject->NrSegments = NrSegments;
SectionSegments = ImageSectionObject->Segments;
Section->Segments = SectionSegments;
SectionSegments[0].FileOffset = 0;
@ -1338,7 +1421,7 @@ MmCreateImageSection(PHANDLE SectionHandle,
SectionSegments[0].RawLength = PAGESIZE;
SectionSegments[0].Length = PAGESIZE;
SectionSegments[0].Flags = 0;
SectionSegments[0].ReferenceCount = 0;
SectionSegments[0].ReferenceCount = 1;
SectionSegments[0].VirtualAddress = 0;
KeInitializeMutex(&SectionSegments[0].Lock, 0);
@ -1375,15 +1458,16 @@ MmCreateImageSection(PHANDLE SectionHandle,
}
FileObject->SectionObjectPointers->ImageSectionObject =
(PVOID)SectionSegments;
(PVOID)ImageSectionObject;
ExFreePool(ImageSections);
}
else
{
ULONG i;
SectionSegments = (PMM_SECTION_SEGMENT)
ImageSectionObject = (PMM_IMAGE_SECTION_OBJECT)
FileObject->SectionObjectPointers->ImageSectionObject;
SectionSegments = ImageSectionObject->Segments;
Section->Segments = SectionSegments;
/*