diff --git a/reactos/drivers/fs/vfat/close.c b/reactos/drivers/fs/vfat/close.c index 367e2be289c..5d8c8f86630 100644 --- a/reactos/drivers/fs/vfat/close.c +++ b/reactos/drivers/fs/vfat/close.c @@ -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); diff --git a/reactos/lib/kernel32/process/create.c b/reactos/lib/kernel32/process/create.c index e1ec4eeeb95..cea638e9476 100644 --- a/reactos/lib/kernel32/process/create.c +++ b/reactos/lib/kernel32/process/create.c @@ -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,20 +31,17 @@ /* FUNCTIONS ****************************************************************/ -WINBOOL -STDCALL -CreateProcessA ( - LPCSTR lpApplicationName, - LPSTR lpCommandLine, - LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - WINBOOL bInheritHandles, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCSTR lpCurrentDirectory, - LPSTARTUPINFOA lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation - ) +WINBOOL STDCALL +CreateProcessA (LPCSTR lpApplicationName, + LPSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + WINBOOL bInheritHandles, + DWORD dwCreationFlags, + LPVOID lpEnvironment, + LPCSTR lpCurrentDirectory, + LPSTARTUPINFOA lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation) /* * FUNCTION: The CreateProcess function creates a new process and its * primary thread. The new process executes the specified executable file @@ -124,12 +121,13 @@ CreateProcessA ( } -HANDLE STDCALL KlCreateFirstThread(HANDLE ProcessHandle, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - DWORD dwStackSize, - LPTHREAD_START_ROUTINE lpStartAddress, - DWORD dwCreationFlags, - LPDWORD lpThreadId) +HANDLE STDCALL +KlCreateFirstThread(HANDLE ProcessHandle, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + DWORD dwStackSize, + LPTHREAD_START_ROUTINE lpStartAddress, + DWORD dwCreationFlags, + LPDWORD lpThreadId) { NTSTATUS Status; HANDLE ThreadHandle; @@ -200,8 +198,9 @@ HANDLE STDCALL KlCreateFirstThread(HANDLE ProcessHandle, return(ThreadHandle); } -HANDLE KlMapFile(LPCWSTR lpApplicationName, - LPCWSTR lpCommandLine) +HANDLE +KlMapFile(LPCWSTR lpApplicationName, + LPCWSTR lpCommandLine) { HANDLE hFile; IO_STATUS_BLOCK IoStatusBlock; @@ -270,8 +269,9 @@ HANDLE KlMapFile(LPCWSTR lpApplicationName, return(hSection); } -static NTSTATUS KlInitPeb (HANDLE ProcessHandle, - PRTL_USER_PROCESS_PARAMETERS Ppb) +static NTSTATUS +KlInitPeb (HANDLE ProcessHandle, + PRTL_USER_PROCESS_PARAMETERS Ppb) { NTSTATUS Status; PVOID PpbBase; @@ -368,16 +368,17 @@ static NTSTATUS KlInitPeb (HANDLE ProcessHandle, } -WINBOOL STDCALL CreateProcessW(LPCWSTR lpApplicationName, - LPWSTR lpCommandLine, - LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, - WINBOOL bInheritHandles, - DWORD dwCreationFlags, - LPVOID lpEnvironment, - LPCWSTR lpCurrentDirectory, - LPSTARTUPINFOW lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation) +WINBOOL STDCALL +CreateProcessW(LPCWSTR lpApplicationName, + LPWSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + WINBOOL bInheritHandles, + DWORD dwCreationFlags, + LPVOID lpEnvironment, + LPCWSTR lpCurrentDirectory, + LPSTARTUPINFOW lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation) { HANDLE hSection, hProcess, hThread; NTSTATUS Status; @@ -490,6 +491,11 @@ WINBOOL STDCALL CreateProcessW(LPCWSTR lpApplicationName, NULL, NULL); + /* + * Close the section + */ + NtClose(hSection); + /* * Get some information about the process */ diff --git a/reactos/ntoskrnl/cc/view.c b/reactos/ntoskrnl/cc/view.c index f5c8956b577..be08c80b303 100644 --- a/reactos/ntoskrnl/cc/view.c +++ b/reactos/ntoskrnl/cc/view.c @@ -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,24 +200,23 @@ 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, - CacheSeg->BaseAddress, - Bcb->CacheSegmentSize, - CcFreeCachePage, - NULL); - ExFreePool(CacheSeg); - return(STATUS_SUCCESS); + DPRINT("Freeing cache segment %x\n", CacheSeg); + MmFreeMemoryArea(MmGetKernelAddressSpace(), + CacheSeg->BaseAddress, + Bcb->CacheSegmentSize, + CcFreeCachePage, + NULL); + ExFreePool(CacheSeg); + return(STATUS_SUCCESS); } 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); diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index 859dbb767bb..7739791432f 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -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 diff --git a/reactos/ntoskrnl/mm/npool.c b/reactos/ntoskrnl/mm/npool.c index 329df031918..58f37a69975 100644 --- a/reactos/ntoskrnl/mm/npool.c +++ b/reactos/ntoskrnl/mm/npool.c @@ -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); } } - DbgPrint("***************** Dump Complete ***************\n"); + 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; + } + + current_entry = current_entry->Flink; + next_entry = next_entry->Flink; } - free_list_head=blk; + 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,71 +556,22 @@ 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&¤t->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(¤t->ListEntry); nr_free_blocks--; } static void remove_from_used_list(BLOCK_HDR* current) { - if (current->next==NULL&¤t->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; - } - } - EiNrUsedBlocks--; + RemoveEntryList(¤t->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(¤t->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(¤t->ListEntry); + InsertHeadList(&UsedBlockListHead, ¤t->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); - if (current->size>=Size && - (best == NULL || - current->size < best->size)) + current = CONTAINING_RECORD(current_entry, BLOCK_HDR, ListEntry); + if (current->size >= Size && + (best == NULL || current->size < best->size)) { - best = current; + best = current; } - current=current->next; + current_entry = current_entry->Flink; } if (best != NULL) { diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index 91fb6c14cee..e257d7757c7 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.c @@ -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) { - DPRINT("MmpDeleteSection(ObjectBody %x)\n", 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; - - SectionSegments = - ExAllocatePoolWithTag(NonPagedPool, - sizeof(MM_SECTION_SEGMENT) * NrSegments, - TAG_MM_SECTION_SEGMENT); - if (SectionSegments == NULL) + ULONG Size; + + 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; /*