Index: base/setup/usetup/interface/usetup.c =================================================================== --- base/setup/usetup/interface/usetup.c (revision 72835) +++ base/setup/usetup/interface/usetup.c (working copy) @@ -3866,8 +3866,11 @@ CopyContext->CompletedOperations++; /* SYSREG checkpoint */ - if (CopyContext->TotalOperations >> 1 == CopyContext->CompletedOperations) - DPRINT1("CHECKPOINT:HALF_COPIED\n"); + if (CopyContext->CompletedOperations >= CopyContext->TotalOperations / 2 && + CopyContext->CompletedOperations % 4 == 0) + { + DPRINT1("CHECKPOINT: Copy progress %lu / %lu\n", CopyContext->CompletedOperations, CopyContext->TotalOperations); + } ProgressNextStep(CopyContext->ProgressBar); SetupUpdateMemoryInfo(CopyContext, FALSE); Index: boot/bootdata/CMakeLists.txt =================================================================== --- boot/bootdata/CMakeLists.txt (revision 72835) +++ boot/bootdata/CMakeLists.txt (working copy) @@ -5,8 +5,13 @@ add_cd_file(FILE ${CMAKE_CURRENT_SOURCE_DIR}/txtsetup.sif DESTINATION reactos NO_CAB FOR bootcd regtest) +add_custom_target(converted_caroots_inf DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/caroots.inf) +add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/caroots.inf + COMMAND native-utf16le "${CMAKE_CURRENT_SOURCE_DIR}/caroots.inf" "${CMAKE_CURRENT_BINARY_DIR}/caroots.inf" + DEPENDS native-utf16le ${CMAKE_CURRENT_SOURCE_DIR}/caroots.inf) +add_cd_file(TARGET converted_caroots_inf FILE ${CMAKE_CURRENT_BINARY_DIR}/caroots.inf DESTINATION reactos NO_CAB FOR all) + add_registry_inf( - caroots.inf hivecls.inf hivedef.inf hivesft.inf Index: boot/bootdata/txtsetup.sif =================================================================== --- boot/bootdata/txtsetup.sif (revision 72835) +++ boot/bootdata/txtsetup.sif (working copy) @@ -522,6 +522,7 @@ 00000455 = kbdbur.dll [HiveInfs.Install] +AddReg=caroots.inf,AddReg AddReg=registry.inf,AddReg ; EOF Index: ntoskrnl/mm/ARM3/pfnlist.c =================================================================== --- ntoskrnl/mm/ARM3/pfnlist.c (revision 72835) +++ ntoskrnl/mm/ARM3/pfnlist.c (working copy) @@ -695,7 +695,6 @@ if ((ListHead->Total >= 8) && !(MmZeroingPageThreadActive)) { /* Set the event */ - MmZeroingPageThreadActive = TRUE; KeSetEvent(&MmZeroingPageEvent, IO_NO_INCREMENT, FALSE); } Index: ntoskrnl/mm/ARM3/zeropage.c =================================================================== --- ntoskrnl/mm/ARM3/zeropage.c (revision 72835) +++ ntoskrnl/mm/ARM3/zeropage.c (working copy) @@ -68,6 +68,8 @@ NULL, NULL); OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + MmZeroingPageThreadActive = TRUE; + while (TRUE) { if (!MmFreePageListHead.Total) Index: ntoskrnl/mm/pagefile.c =================================================================== --- ntoskrnl/mm/pagefile.c (revision 72835) +++ ntoskrnl/mm/pagefile.c (working copy) @@ -279,7 +279,7 @@ NTAPI MmReadFromSwapPage(SWAPENTRY SwapEntry, PFN_NUMBER Page) { - return MiReadPageFile(Page, FILE_FROM_ENTRY(SwapEntry), OFFSET_FROM_ENTRY(SwapEntry)); + return MiReadPageFile(Page, FILE_FROM_ENTRY(SwapEntry), OFFSET_FROM_ENTRY(SwapEntry) - 1); } NTSTATUS @@ -450,7 +450,7 @@ MiFreeSwapPages--; KeReleaseSpinLock(&PagingFileListLock, oldIrql); - entry = ENTRY_FROM_FILE_OFFSET(i, off); + entry = ENTRY_FROM_FILE_OFFSET(i, off + 1); return(entry); } } Index: ntoskrnl/mm/section.c =================================================================== --- ntoskrnl/mm/section.c (revision 72835) +++ ntoskrnl/mm/section.c (working copy) @@ -1536,15 +1536,9 @@ return(Status); } - /* - * Mark the offset within the section as having valid, in-memory - * data - */ + /* Lock both segment and process address space while we proceed. */ MmLockAddressSpace(AddressSpace); MmLockSectionSegment(Segment); - Entry = MAKE_SSE(Page << PAGE_SHIFT, 1); - MmSetPageEntrySectionSegment(Segment, &Offset, Entry); - MmUnlockSectionSegment(Segment); MmDeletePageFileMapping(Process, PAddress, &FakeSwapEntry); DPRINT("CreateVirtualMapping Page %x Process %p PAddress %p Attributes %x\n", @@ -1562,6 +1556,11 @@ ASSERT(MmIsPagePresent(Process, PAddress)); MmInsertRmap(Page, Process, Address); + /* Set this section offset has being backed by our new page. */ + Entry = MAKE_SSE(Page << PAGE_SHIFT, 1); + MmSetPageEntrySectionSegment(Segment, &Offset, Entry); + MmUnlockSectionSegment(Segment); + MiSetPageEvent(Process, Address); DPRINT("Address 0x%p\n", Address); return(STATUS_SUCCESS); @@ -1572,6 +1571,16 @@ SwapEntry = SWAPENTRY_FROM_SSE(Entry); + /* See if a page op is running on this segment. */ + if (SwapEntry == MM_WAIT_ENTRY) + { + MmUnlockSectionSegment(Segment); + MmUnlockAddressSpace(AddressSpace); + MiWaitForPageEvent(NULL, NULL); + MmLockAddressSpace(AddressSpace); + return STATUS_MM_RESTART_OPERATION; + } + /* * Release all our locks and read in the page from disk */ @@ -1611,17 +1620,11 @@ } /* - * Mark the offset within the section as having valid, in-memory - * data - */ - Entry = MAKE_SSE(Page << PAGE_SHIFT, 1); - MmSetPageEntrySectionSegment(Segment, &Offset, Entry); - MmUnlockSectionSegment(Segment); - - /* * Save the swap entry. */ MmSetSavedSwapEntryPage(Page, SwapEntry); + + /* Map the page into the process address space */ Status = MmCreateVirtualMapping(Process, PAddress, Region->Protect, @@ -1633,6 +1636,15 @@ KeBugCheck(MEMORY_MANAGEMENT); } MmInsertRmap(Page, Process, Address); + + /* + * Mark the offset within the section as having valid, in-memory + * data + */ + Entry = MAKE_SSE(Page << PAGE_SHIFT, 1); + MmSetPageEntrySectionSegment(Segment, &Offset, Entry); + MmUnlockSectionSegment(Segment); + MiSetPageEvent(Process, Address); DPRINT("Address 0x%p\n", Address); return(STATUS_SUCCESS); @@ -1639,16 +1651,9 @@ } else { - /* - * If the section offset is already in-memory and valid then just - * take another reference to the page - */ - + /* We already have a page on this section offset. Map it into the process address space. */ Page = PFN_FROM_SSE(Entry); - MmSharePageEntrySectionSegment(Segment, &Offset); - MmUnlockSectionSegment(Segment); - Status = MmCreateVirtualMapping(Process, PAddress, Attributes, @@ -1660,6 +1665,11 @@ KeBugCheck(MEMORY_MANAGEMENT); } MmInsertRmap(Page, Process, Address); + + /* Take a reference on it */ + MmSharePageEntrySectionSegment(Segment, &Offset); + MmUnlockSectionSegment(Segment); + MiSetPageEvent(Process, Address); DPRINT("Address 0x%p\n", Address); return(STATUS_SUCCESS); @@ -1682,10 +1692,17 @@ PMM_REGION Region; ULONG_PTR Entry; PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace); - SWAPENTRY SwapEntry; DPRINT("MmAccessFaultSectionView(%p, %p, %p)\n", AddressSpace, MemoryArea, Address); + /* Make sure we have a page mapping for this address. */ + Status = MmNotPresentFaultSectionView(AddressSpace, MemoryArea, Address, TRUE); + if (!NT_SUCCESS(Status)) + { + /* This is invalid access ! */ + return Status; + } + /* * Check if the page has already been set readwrite */ @@ -1708,16 +1725,7 @@ &MemoryArea->Data.SectionData.RegionListHead, Address, NULL); ASSERT(Region != NULL); - /* - * Lock the segment - */ - MmLockSectionSegment(Segment); - OldPage = MmGetPfnForProcess(Process, Address); - Entry = MmGetPageEntrySectionSegment(Segment, &Offset); - - MmUnlockSectionSegment(Segment); - /* * Check if we are doing COW */ @@ -1729,50 +1737,25 @@ return(STATUS_ACCESS_VIOLATION); } + /* Get the page mapping this section offset. */ + MmLockSectionSegment(Segment); + Entry = MmGetPageEntrySectionSegment(Segment, &Offset); + + /* Get the current page mapping for the process */ + ASSERT(MmIsPagePresent(Process, PAddress)); + OldPage = MmGetPfnForProcess(Process, PAddress); + ASSERT(OldPage != 0); + if (IS_SWAP_FROM_SSE(Entry) || PFN_FROM_SSE(Entry) != OldPage) { + MmUnlockSectionSegment(Segment); /* This is a private page. We must only change the page protection. */ - MmSetPageProtect(Process, Address, Region->Protect); + MmSetPageProtect(Process, PAddress, Region->Protect); return(STATUS_SUCCESS); } - if(OldPage == 0) - DPRINT("OldPage == 0!\n"); - /* - * Get or create a pageop - */ - MmLockSectionSegment(Segment); - Entry = MmGetPageEntrySectionSegment(Segment, &Offset); - - /* - * Wait for any other operations to complete - */ - if (Entry == SWAPENTRY_FROM_SSE(MM_WAIT_ENTRY)) - { - MmUnlockSectionSegment(Segment); - MmUnlockAddressSpace(AddressSpace); - MiWaitForPageEvent(NULL, NULL); - /* - * Restart the operation - */ - MmLockAddressSpace(AddressSpace); - DPRINT("Address 0x%p\n", Address); - return(STATUS_MM_RESTART_OPERATION); - } - - MmDeleteRmap(OldPage, Process, PAddress); - MmDeleteVirtualMapping(Process, PAddress, NULL, NULL); - MmCreatePageFileMapping(Process, PAddress, MM_WAIT_ENTRY); - - /* - * Release locks now we have the pageop - */ - MmUnlockSectionSegment(Segment); - MmUnlockAddressSpace(AddressSpace); - - /* * Allocate a page */ MI_SET_USAGE(MI_USAGE_SECTION); @@ -1789,12 +1772,18 @@ */ MiCopyFromUserPage(NewPage, OldPage); - MmLockAddressSpace(AddressSpace); + /* + * Unshare the old page. + */ + DPRINT("Swapping page (Old %x New %x)\n", OldPage, NewPage); + MmDeleteVirtualMapping(Process, PAddress, NULL, NULL); + MmDeleteRmap(OldPage, Process, PAddress); + MmUnsharePageEntrySectionSegment(Section, Segment, &Offset, FALSE, FALSE, NULL); + MmUnlockSectionSegment(Segment); /* * Set the PTE to point to the new page */ - MmDeletePageFileMapping(Process, PAddress, &SwapEntry); Status = MmCreateVirtualMapping(Process, PAddress, Region->Protect, @@ -1806,15 +1795,7 @@ KeBugCheck(MEMORY_MANAGEMENT); return(Status); } - - /* - * Unshare the old page. - */ - DPRINT("Swapping page (Old %x New %x)\n", OldPage, NewPage); MmInsertRmap(NewPage, Process, PAddress); - MmLockSectionSegment(Segment); - MmUnsharePageEntrySectionSegment(Section, Segment, &Offset, FALSE, FALSE, NULL); - MmUnlockSectionSegment(Segment); MiSetPageEvent(Process, Address); DPRINT("Address 0x%p\n", Address); @@ -1966,7 +1947,7 @@ */ MmUnlockSectionSegment(Context.Segment); Context.WasDirty = FALSE; - if (Context.Segment->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA || + if (/* Context.Segment->Image.Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA || */ IS_SWAP_FROM_SSE(Entry) || PFN_FROM_SSE(Entry) != Page) { @@ -2147,6 +2128,9 @@ else { ULONG_PTR OldEntry; + + MmLockSectionSegment(Context.Segment); + /* * For non-private pages if the page wasn't direct mapped then * set it back into the section segment entry so we don't loose @@ -2163,7 +2147,6 @@ Address); // If we got here, the previous entry should have been a wait Entry = MAKE_SSE(Page << PAGE_SHIFT, 1); - MmLockSectionSegment(Context.Segment); OldEntry = MmGetPageEntrySectionSegment(Context.Segment, &Context.Offset); ASSERT(OldEntry == 0 || OldEntry == MAKE_SWAP_SSE(MM_WAIT_ENTRY)); MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry); @@ -2202,6 +2185,7 @@ } else { + MmLockSectionSegment(Context.Segment); Status = MmCreateVirtualMapping(Process, Address, MemoryArea->Protect, @@ -2213,6 +2197,7 @@ Address); Entry = MAKE_SSE(Page << PAGE_SHIFT, 1); MmSetPageEntrySectionSegment(Context.Segment, &Context.Offset, Entry); + MmUnlockSectionSegment(Context.Segment); } MmUnlockAddressSpace(AddressSpace); MiSetPageEvent(NULL, NULL); Index: sdk/lib/rtl/heap.c =================================================================== --- sdk/lib/rtl/heap.c (revision 72835) +++ sdk/lib/rtl/heap.c (working copy) @@ -1236,6 +1236,8 @@ NTSTATUS Status; ULONG MaxBlockSize; + RtlpPageHeapEnabled = TRUE; + /* Check for a special heap */ if (RtlpPageHeapEnabled && !Addr && !Lock) { @@ -1256,6 +1258,8 @@ Flags &= HEAP_CREATE_VALID_MASK; } + if (!Addr) Flags |= HEAP_FLAG_PAGE_ALLOCS; + /* Capture parameters */ if (Parameters) { Index: sdk/lib/rtl/heappage.c =================================================================== --- sdk/lib/rtl/heappage.c (revision 72835) +++ sdk/lib/rtl/heappage.c (working copy) @@ -781,6 +781,11 @@ FreeAllocations--; if (FreeAllocations < LeaveOnFreeList) break; + if (FreeAllocations - LeaveOnFreeList > 0x1000 && FreeAllocations % 0x1000 == 0) + { + DPRINT1("Coalesce... %lu\n", FreeAllocations - LeaveOnFreeList); + } + /* Get the next pointer, because it may be changed after following two calls */ Next = Node->pNextAlloc;