diff --git a/reactos/apps/tests/consume/consume.c b/reactos/apps/tests/consume/consume.c index 05123742574..bc8333a028d 100644 --- a/reactos/apps/tests/consume/consume.c +++ b/reactos/apps/tests/consume/consume.c @@ -2,7 +2,9 @@ #include #include -ULONG x[(4 * 1024 * 1024) / 4096]; +#define SIZE (128*1024*1024) + +ULONG x[SIZE / 4096]; int main() { @@ -10,7 +12,7 @@ int main() PUCHAR BaseAddress; BaseAddress = VirtualAlloc(NULL, - 4 * 1024 * 1024, + SIZE, MEM_COMMIT, PAGE_READONLY); if (BaseAddress == NULL) @@ -19,9 +21,9 @@ int main() return(1); } printf("BaseAddress %p\n", BaseAddress); - for (i = 0; i < ((4 * 1024 * 1024) / 4096); i++) + for (i = 0; i < (SIZE / 4096); i++) { - printf("%.6x, ", i*4096); + printf("%.8x ", i*4096); x[i] = BaseAddress[i*4096]; } diff --git a/reactos/drivers/fs/vfat/create.c b/reactos/drivers/fs/vfat/create.c index 8ca6b0e0b4d..a1896c81bb6 100644 --- a/reactos/drivers/fs/vfat/create.c +++ b/reactos/drivers/fs/vfat/create.c @@ -1,4 +1,4 @@ -/* $Id: create.c,v 1.34 2001/11/02 22:44:34 hbirr Exp $ +/* $Id: create.c,v 1.35 2002/01/08 00:49:01 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -579,12 +579,14 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) PVFATCCB pCcb; PVFATFCB pFcb; PWCHAR c; + BOOLEAN PagingFileCreate = FALSE; Stack = IoGetCurrentIrpStackLocation (Irp); assert (Stack); RequestedDisposition = ((Stack->Parameters.Create.Options >> 24) & 0xff); RequestedOptions = Stack->Parameters.Create.Options & FILE_VALID_OPTION_FLAGS; + PagingFileCreate = (Stack->Flags & SL_OPEN_PAGING_FILE) ? TRUE : FALSE; if ((RequestedOptions & FILE_DIRECTORY_FILE) && RequestedDisposition == FILE_SUPERSEDE) return STATUS_INVALID_PARAMETER; @@ -694,6 +696,42 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp) } } + /* + * If this create was for a paging file then make sure all the + * information needed to manipulate it is locked in memory. + */ + if (PagingFileCreate) + { + ULONG CurrentCluster, NextCluster, i; + + pFcb->Flags |= FCB_IS_PAGE_FILE; + pFcb->FatChainSize = + ((pFcb->entry.FileSize / DeviceExt->BytesPerCluster) + 2); + pFcb->FatChain = ExAllocatePool(NonPagedPool, + pFcb->FatChainSize * sizeof(ULONG)); + + if (DeviceExt->FatType == FAT32) + { + CurrentCluster = pFcb->entry.FirstCluster + + pFcb->entry.FirstClusterHigh * 65536; + } + else + { + CurrentCluster = pFcb->entry.FirstCluster; + } + + i = 0; + while (CurrentCluster != 0xffffffff) + { + Status = GetNextCluster (DeviceExt, CurrentCluster, &NextCluster, + FALSE); + pFcb->FatChain[i] = NextCluster; + i++; + CurrentCluster = NextCluster; + } + pFcb->FatChain[i] = 0xFFFFFFFF; + } + /* * Check the file has the requested attributes */ diff --git a/reactos/drivers/fs/vfat/dirwr.c b/reactos/drivers/fs/vfat/dirwr.c index 3376858ba5d..5d5a183a69d 100644 --- a/reactos/drivers/fs/vfat/dirwr.c +++ b/reactos/drivers/fs/vfat/dirwr.c @@ -1,4 +1,4 @@ -/* $Id: dirwr.c,v 1.22 2001/10/10 22:15:51 hbirr Exp $ +/* $Id: dirwr.c,v 1.23 2002/01/08 00:49:01 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -403,7 +403,7 @@ addEntry (PDEVICE_EXTENSION DeviceExt, if (RequestedOptions & FILE_DIRECTORY_FILE) { CurrentCluster = 0xffffffff; - status = NextCluster (DeviceExt, 0, &CurrentCluster, TRUE); + status = NextCluster (DeviceExt, NULL, 0, &CurrentCluster, TRUE); if (CurrentCluster == 0xffffffff || !NT_SUCCESS(status)) { vfatReleaseFCB(DeviceExt, pDirFcb); diff --git a/reactos/drivers/fs/vfat/fcb.c b/reactos/drivers/fs/vfat/fcb.c index 48594942a3c..b3ff4b04c8b 100644 --- a/reactos/drivers/fs/vfat/fcb.c +++ b/reactos/drivers/fs/vfat/fcb.c @@ -1,4 +1,4 @@ -/* $Id: fcb.c,v 1.11 2001/11/02 22:40:50 hbirr Exp $ +/* $Id: fcb.c,v 1.12 2002/01/08 00:49:01 dwelch Exp $ * * * FILE: fcb.c @@ -218,7 +218,7 @@ vfatMakeRootFCB(PDEVICE_EXTENSION pVCB) while (CurrentCluster != 0xffffffff && NT_SUCCESS(Status)) { Size += pVCB->BytesPerCluster; - Status = NextCluster (pVCB, FirstCluster, &CurrentCluster, FALSE); + Status = NextCluster (pVCB, NULL, FirstCluster, &CurrentCluster, FALSE); } } else @@ -304,7 +304,7 @@ vfatMakeFCBFromDirEntry(PVCB vcb, while (CurrentCluster != 0xffffffff) { Size += vcb->BytesPerCluster; - Status = NextCluster (vcb, FirstCluster, &CurrentCluster, FALSE); + Status = NextCluster (vcb, NULL, FirstCluster, &CurrentCluster, FALSE); } } } diff --git a/reactos/drivers/fs/vfat/makefile b/reactos/drivers/fs/vfat/makefile index c36c04b6852..8031aa30bac 100644 --- a/reactos/drivers/fs/vfat/makefile +++ b/reactos/drivers/fs/vfat/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.36 2001/11/02 22:47:36 hbirr Exp $ +# $Id: makefile,v 1.37 2002/01/08 00:49:01 dwelch Exp $ PATH_TO_TOP = ../../.. @@ -26,6 +26,8 @@ TARGET_OBJECTS = \ DEP_OBJECTS = $(TARGET_OBJECTS) +TARGET_CFLAGS = -g + include $(PATH_TO_TOP)/rules.mak include $(TOOLS_PATH)/helper.mk diff --git a/reactos/drivers/fs/vfat/rw.c b/reactos/drivers/fs/vfat/rw.c index 15ad7ab3e12..1ed7984b695 100644 --- a/reactos/drivers/fs/vfat/rw.c +++ b/reactos/drivers/fs/vfat/rw.c @@ -1,5 +1,5 @@ -/* $Id: rw.c,v 1.34 2001/11/02 22:47:36 hbirr Exp $ +/* $Id: rw.c,v 1.35 2002/01/08 00:49:01 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -29,6 +29,7 @@ NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt, + PVFATFCB Fcb, ULONG FirstCluster, PULONG CurrentCluster, BOOLEAN Extend) @@ -37,33 +38,46 @@ NextCluster(PDEVICE_EXTENSION DeviceExt, * necessary */ { + if (Fcb != NULL && Fcb->Flags & FCB_IS_PAGE_FILE) + { + ULONG NextCluster; + NextCluster = Fcb->FatChain[(*CurrentCluster)]; + (*CurrentCluster) = NextCluster; + return(STATUS_SUCCESS); + } if (FirstCluster == 1) - { - (*CurrentCluster) += DeviceExt->Boot->SectorsPerCluster; + { + (*CurrentCluster) += DeviceExt->Boot->SectorsPerCluster; return(STATUS_SUCCESS); } else - /* CN: FIXME: Real bug here or in dirwr, where CurrentCluster isn't initialized when 0*/ - if (FirstCluster == 0) { - NTSTATUS Status; - - Status = GetNextCluster(DeviceExt, 0, CurrentCluster, - Extend); - return(Status); - } - else - { - NTSTATUS Status; - - Status = GetNextCluster(DeviceExt, (*CurrentCluster), CurrentCluster, - Extend); - return(Status); + /* + * CN: FIXME: Real bug here or in dirwr, where CurrentCluster isn't + * initialized when 0 + */ + if (FirstCluster == 0) + { + NTSTATUS Status; + + Status = GetNextCluster(DeviceExt, 0, CurrentCluster, + Extend); + return(Status); + } + else + { + NTSTATUS Status; + + Status = GetNextCluster(DeviceExt, (*CurrentCluster), CurrentCluster, + Extend); + return(Status); + } } } NTSTATUS OffsetToCluster(PDEVICE_EXTENSION DeviceExt, + PVFATFCB Fcb, ULONG FirstCluster, ULONG FileOffset, PULONG Cluster, @@ -77,6 +91,20 @@ OffsetToCluster(PDEVICE_EXTENSION DeviceExt, ULONG i; NTSTATUS Status; + if (Fcb != NULL && Fcb->Flags & FCB_IS_PAGE_FILE) + { + ULONG NCluster; + ULONG Offset = FileOffset / DeviceExt->BytesPerCluster; + if (Offset == 0) + { + (*Cluster) = FirstCluster; + } + else + { + (*Cluster) = Fcb->FatChain[Offset - 1]; + } + return(STATUS_SUCCESS); + } if (FirstCluster == 1) { /* root of FAT16 or FAT12 */ @@ -103,6 +131,7 @@ OffsetToCluster(PDEVICE_EXTENSION DeviceExt, NTSTATUS VfatReadCluster(PDEVICE_EXTENSION DeviceExt, + PVFATFCB Fcb, ULONG FirstCluster, PULONG CurrentCluster, PVOID Destination, @@ -133,7 +162,7 @@ VfatReadCluster(PDEVICE_EXTENSION DeviceExt, { return(Status); } - Status = NextCluster(DeviceExt, FirstCluster, CurrentCluster, FALSE); + Status = NextCluster(DeviceExt, Fcb, FirstCluster, CurrentCluster, FALSE); return(Status); } @@ -248,6 +277,7 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, CurrentCluster = Ccb->LastCluster; } Status = OffsetToCluster(DeviceExt, + Fcb, FirstCluster, ROUND_DOWN(ReadOffset, DeviceExt->BytesPerCluster), &CurrentCluster, @@ -265,8 +295,9 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, TempLength = min (Length, DeviceExt->BytesPerCluster - (ReadOffset % DeviceExt->BytesPerCluster)); Ccb->LastCluster = CurrentCluster; Ccb->LastOffset = ROUND_DOWN(ReadOffset, DeviceExt->BytesPerCluster); - Status = VfatReadCluster(DeviceExt, FirstCluster, &CurrentCluster, Buffer, - ReadOffset % DeviceExt->BytesPerCluster, TempLength); + Status = VfatReadCluster(DeviceExt, Fcb, FirstCluster, &CurrentCluster, + Buffer, ReadOffset % DeviceExt->BytesPerCluster, + TempLength); if (NT_SUCCESS(Status)) { (*LengthRead) = (*LengthRead) + TempLength; @@ -284,7 +315,7 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, do { ClusterCount++; - Status = NextCluster(DeviceExt, FirstCluster, &CurrentCluster, FALSE); + Status = NextCluster(DeviceExt, Fcb, FirstCluster, &CurrentCluster, FALSE); } while (StartCluster + ClusterCount == CurrentCluster && NT_SUCCESS(Status) && Length - ClusterCount * DeviceExt->BytesPerCluster >= DeviceExt->BytesPerCluster); @@ -311,7 +342,7 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, Ccb->LastCluster = CurrentCluster; Ccb->LastOffset = ReadOffset + DeviceExt->BytesPerCluster; - Status = VfatReadCluster(DeviceExt, FirstCluster, &CurrentCluster, + Status = VfatReadCluster(DeviceExt, Fcb, FirstCluster, &CurrentCluster, Buffer, 0, Length); if (NT_SUCCESS(Status)) { @@ -323,6 +354,7 @@ VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, NTSTATUS VfatWriteCluster(PDEVICE_EXTENSION DeviceExt, + PVFATFCB Fcb, ULONG StartOffset, ULONG FirstCluster, PULONG CurrentCluster, @@ -376,7 +408,7 @@ VfatWriteCluster(PDEVICE_EXTENSION DeviceExt, { return Status; } - Status = NextCluster(DeviceExt, FirstCluster, CurrentCluster, FALSE); + Status = NextCluster(DeviceExt, Fcb, FirstCluster, CurrentCluster, FALSE); return(Status); } @@ -485,6 +517,7 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, CurrentCluster = pCcb->LastCluster; } Status = OffsetToCluster(DeviceExt, + Fcb, FirstCluster, ROUND_DOWN(WriteOffset, DeviceExt->BytesPerCluster), &CurrentCluster, @@ -506,6 +539,7 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, { TempLength = min (Length, DeviceExt->BytesPerCluster - (WriteOffset % DeviceExt->BytesPerCluster)); Status = VfatWriteCluster(DeviceExt, + Fcb, ROUND_DOWN(WriteOffset, DeviceExt->BytesPerCluster), FirstCluster, &CurrentCluster, @@ -528,7 +562,7 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, do { Count++; - Status = NextCluster(DeviceExt, FirstCluster, &CurrentCluster, FALSE); + Status = NextCluster(DeviceExt, Fcb, FirstCluster, &CurrentCluster, FALSE); } while (StartCluster + Count == CurrentCluster && NT_SUCCESS(Status) && Length - Count * DeviceExt->BytesPerCluster >= DeviceExt->BytesPerCluster); @@ -550,6 +584,7 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject, if (Length > 0 && CurrentCluster != 0xffffffff && NT_SUCCESS(Status)) { Status = VfatWriteCluster(DeviceExt, + Fcb, WriteOffset, FirstCluster, &CurrentCluster, @@ -626,7 +661,7 @@ NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject if (FirstCluster == 0) { // file of size zero - Status = NextCluster (pDeviceExt, FirstCluster, &CurrentCluster, TRUE); + Status = NextCluster (pDeviceExt, pFcb, FirstCluster, &CurrentCluster, TRUE); if (!NT_SUCCESS(Status)) { DPRINT1("NextCluster failed, Status %x\n", Status); @@ -636,7 +671,7 @@ NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject } else { - Status = OffsetToCluster(pDeviceExt, FirstCluster, + Status = OffsetToCluster(pDeviceExt, pFcb, FirstCluster, pFcb->RFCB.AllocationSize.QuadPart - pDeviceExt->BytesPerCluster, &CurrentCluster, FALSE); if (!NT_SUCCESS(Status)) @@ -651,14 +686,14 @@ NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject } // CurrentCluster zeigt jetzt auf den letzten Cluster in der Kette NewCluster = CurrentCluster; - Status = NextCluster(pDeviceExt, FirstCluster, &NewCluster, FALSE); + Status = NextCluster(pDeviceExt, pFcb, FirstCluster, &NewCluster, FALSE); if (NewCluster != 0xffffffff) { DPRINT1("Difference between size from direntry and the FAT.\n"); } } - Status = OffsetToCluster(pDeviceExt, FirstCluster, + Status = OffsetToCluster(pDeviceExt, pFcb, FirstCluster, ROUND_DOWN(NewSize-1, pDeviceExt->BytesPerCluster), &NewCluster, TRUE); if (!NT_SUCCESS(Status) || NewCluster == 0xffffffff) @@ -668,7 +703,7 @@ NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject { NewCluster = CurrentCluster; // FIXME: check status - NextCluster(pDeviceExt, FirstCluster, &NewCluster, FALSE); + NextCluster(pDeviceExt, pFcb, FirstCluster, &NewCluster, FALSE); WriteCluster(pDeviceExt, CurrentCluster, 0xffffffff); } // free the allocated space @@ -676,7 +711,7 @@ NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject { CurrentCluster = NewCluster; // FIXME: check status - NextCluster (pDeviceExt, FirstCluster, &NewCluster, FALSE); + NextCluster (pDeviceExt, pFcb, FirstCluster, &NewCluster, FALSE); WriteCluster (pDeviceExt, CurrentCluster, 0); } return STATUS_DISK_FULL; diff --git a/reactos/drivers/fs/vfat/vfat.h b/reactos/drivers/fs/vfat/vfat.h index 6861eea02d7..0195f8aa465 100644 --- a/reactos/drivers/fs/vfat/vfat.h +++ b/reactos/drivers/fs/vfat/vfat.h @@ -1,4 +1,4 @@ -/* $Id: vfat.h,v 1.37 2001/11/02 22:57:14 hbirr Exp $ */ +/* $Id: vfat.h,v 1.38 2002/01/08 00:49:01 dwelch Exp $ */ #include @@ -137,6 +137,10 @@ typedef struct _VFATFCB ULONG dirIndex; ERESOURCE PagingIoResource; ERESOURCE MainResource; + + /* Structure members used only for paging files. */ + ULONG FatChainSize; + PULONG FatChain; } VFATFCB, *PVFATFCB; typedef struct _VFATCCB @@ -212,6 +216,7 @@ NTSTATUS VfatSetVolumeInformation (PVFAT_IRP_CONTEXT); NTSTATUS NextCluster(PDEVICE_EXTENSION DeviceExt, + PVFATFCB Fcb, ULONG FirstCluster, PULONG CurrentCluster, BOOLEAN Extend); @@ -294,6 +299,7 @@ BOOL vfatIsFileNameValid (PWCHAR pFileName); */ NTSTATUS OffsetToCluster(PDEVICE_EXTENSION DeviceExt, + PVFATFCB Fcb, ULONG FirstCluster, ULONG FileOffset, PULONG Cluster, diff --git a/reactos/ntoskrnl/cc/view.c b/reactos/ntoskrnl/cc/view.c index c76bef29964..be229f590f1 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.34 2002/01/01 00:21:55 dwelch Exp $ +/* $Id: view.c,v 1.35 2002/01/08 00:49:00 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -105,13 +105,15 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed) { continue; } - if (current->MappedCount > 0 || current->Dirty || current->ReferenceCount > 0) + if (current->MappedCount > 0 || current->Dirty || + current->ReferenceCount > 0) { ExReleaseFastMutex(¤t->Lock); continue; } ExReleaseFastMutex(¤t->Lock); - DPRINT("current->Bcb->CacheSegmentSize %d\n", current->Bcb->CacheSegmentSize); + DPRINT("current->Bcb->CacheSegmentSize %d\n", + current->Bcb->CacheSegmentSize); PagesPerSegment = current->Bcb->CacheSegmentSize / PAGESIZE; CcRosInternalFreeCacheSegment(current->Bcb, current); DPRINT("CcRosTrimCache(): Freed %d\n", PagesPerSegment); @@ -143,7 +145,8 @@ CcRosReleaseCacheSegment(PBCB Bcb, ExReleaseFastMutex(&CacheSeg->Lock); ExAcquireFastMutex(&ViewLock); RemoveEntryList(&CacheSeg->CacheSegmentLRUListEntry); - InsertTailList(&CacheSegmentLRUListHead, &CacheSeg->CacheSegmentLRUListEntry); + InsertTailList(&CacheSegmentLRUListHead, + &CacheSeg->CacheSegmentLRUListEntry); ExReleaseFastMutex(&ViewLock); InterlockedDecrement(&CacheSeg->ReferenceCount); diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index 2ce48638022..93259ca4719 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -39,10 +39,6 @@ typedef ULONG SWAPENTRY; #define NR_SECTION_PAGE_TABLES (1024) #define NR_SECTION_PAGE_ENTRIES (1024) -/* - * Flags for section objects - */ -#define SO_PHYSICAL_MEMORY (0x1) /* * Additional flags for protection attributes @@ -72,6 +68,10 @@ typedef struct #define MM_PAGEFILE_SECTION (0x1) #define MM_IMAGE_SECTION (0x2) +/* + * Flags for section objects + */ +#define SO_PHYSICAL_MEMORY (0x4) #define MM_SECTION_SEGMENT_BSS (0x1) @@ -506,5 +506,8 @@ MmCreatePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY SwapEntry); BOOLEAN MmIsPageSwapEntry(PEPROCESS Process, PVOID Address); +VOID +MmTransferOwnershipPage(PVOID PhysicalAddress, ULONG NewConsumer); +VOID MmSetDirtyPage(PEPROCESS Process, PVOID Address); #endif diff --git a/reactos/ntoskrnl/io/create.c b/reactos/ntoskrnl/io/create.c index b0f26b1a327..6ce97406028 100644 --- a/reactos/ntoskrnl/io/create.c +++ b/reactos/ntoskrnl/io/create.c @@ -1,4 +1,4 @@ -/* $Id: create.c,v 1.51 2001/12/05 12:11:55 ekohl Exp $ +/* $Id: create.c,v 1.52 2002/01/08 00:49:00 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -294,21 +294,20 @@ IoCreateStreamFileObject(PFILE_OBJECT FileObject, * */ NTSTATUS STDCALL -IoCreateFile( - OUT PHANDLE FileHandle, - IN ACCESS_MASK DesiredAccess, - IN POBJECT_ATTRIBUTES ObjectAttributes, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN PLARGE_INTEGER AllocationSize OPTIONAL, - IN ULONG FileAttributes, - IN ULONG ShareAccess, - IN ULONG CreateDisposition, - IN ULONG CreateOptions, - IN PVOID EaBuffer OPTIONAL, - IN ULONG EaLength, - IN CREATE_FILE_TYPE CreateFileType, - IN PVOID ExtraCreateParameters OPTIONAL, - IN ULONG Options) +IoCreateFile(OUT PHANDLE FileHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PLARGE_INTEGER AllocationSize OPTIONAL, + IN ULONG FileAttributes, + IN ULONG ShareAccess, + IN ULONG CreateDisposition, + IN ULONG CreateOptions, + IN PVOID EaBuffer OPTIONAL, + IN ULONG EaLength, + IN CREATE_FILE_TYPE CreateFileType, + IN PVOID ExtraCreateParameters OPTIONAL, + IN ULONG Options) { PFILE_OBJECT FileObject; NTSTATUS Status; @@ -395,7 +394,7 @@ IoCreateFile( break; } StackLoc->MinorFunction = 0; - StackLoc->Flags = 0; + StackLoc->Flags = Options; StackLoc->Control = 0; StackLoc->DeviceObject = FileObject->DeviceObject; StackLoc->FileObject = FileObject; diff --git a/reactos/ntoskrnl/io/page.c b/reactos/ntoskrnl/io/page.c index 7137070d136..e9bd89f7c23 100644 --- a/reactos/ntoskrnl/io/page.c +++ b/reactos/ntoskrnl/io/page.c @@ -1,4 +1,4 @@ -/* $Id: page.c,v 1.13 2001/10/10 21:56:59 hbirr Exp $ +/* $Id: page.c,v 1.14 2002/01/08 00:49:00 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -89,7 +89,7 @@ IoPageRead(PFILE_OBJECT FileObject, IoFileObjectType, UserMode); - KeInitializeEvent(&Event,NotificationEvent,FALSE); + KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = IoBuildSynchronousFsdRequestWithMdl(IRP_MJ_READ, FileObject->DeviceObject, Mdl, @@ -100,7 +100,7 @@ IoPageRead(PFILE_OBJECT FileObject, StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr->FileObject = FileObject; DPRINT("Before IoCallDriver\n"); - Status = IoCallDriver(FileObject->DeviceObject,Irp); + Status = IoCallDriver(FileObject->DeviceObject, Irp); DPRINT("Status %d STATUS_PENDING %d\n",Status,STATUS_PENDING); if (Status==STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO)) { diff --git a/reactos/ntoskrnl/mm/balance.c b/reactos/ntoskrnl/mm/balance.c index 29c3cd20314..7a2bbd0fce3 100644 --- a/reactos/ntoskrnl/mm/balance.c +++ b/reactos/ntoskrnl/mm/balance.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: balance.c,v 1.4 2002/01/01 00:21:55 dwelch Exp $ +/* $Id: balance.c,v 1.5 2002/01/08 00:49:00 dwelch Exp $ * * COPYRIGHT: See COPYING in the top directory * PROJECT: ReactOS kernel @@ -130,7 +130,8 @@ MiTrimMemoryConsumer(ULONG Consumer) { LONG Target; - Target = MiMemoryConsumers[Consumer].PagesUsed - MiMemoryConsumers[Consumer].PagesTarget; + Target = MiMemoryConsumers[Consumer].PagesUsed - + MiMemoryConsumers[Consumer].PagesTarget; if (Target < 0) { Target = 1; @@ -254,6 +255,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, PVOID* AllocatedPag { KeBugCheck(0); } + MmTransferOwnershipPage(Page, Consumer); *AllocatedPage = Page; return(STATUS_SUCCESS); } diff --git a/reactos/ntoskrnl/mm/freelist.c b/reactos/ntoskrnl/mm/freelist.c index 519f337ee6d..71613868035 100644 --- a/reactos/ntoskrnl/mm/freelist.c +++ b/reactos/ntoskrnl/mm/freelist.c @@ -49,6 +49,19 @@ static LIST_ENTRY BiosPageListHead; /* FUNCTIONS *************************************************************/ +VOID +MmTransferOwnershipPage(PVOID PhysicalAddress, ULONG NewConsumer) +{ + ULONG Start = (ULONG)PhysicalAddress / PAGESIZE; + KIRQL oldIrql; + + KeAcquireSpinLock(&PageListLock, &oldIrql); + RemoveEntryList(&MmPageArray[Start].ListEntry); + InsertTailList(&UsedPageListHeads[NewConsumer], + &MmPageArray[Start].ListEntry); + KeReleaseSpinLock(&PageListLock, oldIrql); +} + PVOID MmGetLRUFirstUserPage(VOID) { @@ -159,7 +172,8 @@ MmGetContinuousPages(ULONG NumberOfBytes, MmPageArray[i].LockCount = 0; MmPageArray[i].MapCount = 0; MmPageArray[i].SavedSwapEntry = 0; - InsertTailList(&UsedPageListHeads[MC_NPPOOL], &MmPageArray[i].ListEntry); + InsertTailList(&UsedPageListHeads[MC_NPPOOL], + &MmPageArray[i].ListEntry); } KeReleaseSpinLock(&PageListLock, oldIrql); return((PVOID)(start * 4096)); @@ -509,7 +523,7 @@ VOID MmSetSavedSwapEntryPage(PVOID PhysicalAddress, { ULONG Start = (ULONG)PhysicalAddress / PAGESIZE; KIRQL oldIrql; - + KeAcquireSpinLock(&PageListLock, &oldIrql); MmPageArray[Start].SavedSwapEntry = SavedSwapEntry; KeReleaseSpinLock(&PageListLock, oldIrql); @@ -525,7 +539,7 @@ MmGetSavedSwapEntryPage(PVOID PhysicalAddress) KeAcquireSpinLock(&PageListLock, &oldIrql); SavedSwapEntry = MmPageArray[Start].SavedSwapEntry; KeReleaseSpinLock(&PageListLock, oldIrql); - + return(SavedSwapEntry); } @@ -646,6 +660,11 @@ VOID MmDereferencePage(PVOID PhysicalAddress) DbgPrint("Freeing locked page\n"); KeBugCheck(0); } + if (MmPageArray[Start].SavedSwapEntry != 0) + { + DbgPrint("Freeing page with swap entry.\n"); + KeBugCheck(0); + } if (MmPageArray[Start].Flags != MM_PHYSICAL_PAGE_USED) { DbgPrint("Freeing page with flags %x\n", @@ -653,7 +672,8 @@ VOID MmDereferencePage(PVOID PhysicalAddress) KeBugCheck(0); } MmPageArray[Start].Flags = MM_PHYSICAL_PAGE_FREE; - InsertTailList(&FreeUnzeroedPageListHead, &MmPageArray[Start].ListEntry); + InsertTailList(&FreeUnzeroedPageListHead, + &MmPageArray[Start].ListEntry); } KeReleaseSpinLock(&PageListLock, oldIrql); } @@ -743,6 +763,11 @@ MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry) KIRQL oldIrql; BOOLEAN NeedClear = FALSE; + if (SavedSwapEntry == 0x17) + { + KeBugCheck(0); + } + DPRINT("MmAllocPage()\n"); KeAcquireSpinLock(&PageListLock, &oldIrql); @@ -779,7 +804,8 @@ MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry) PageDescriptor->LockCount = 0; PageDescriptor->MapCount = 0; PageDescriptor->SavedSwapEntry = SavedSwapEntry; - ExInterlockedInsertTailList(&UsedPageListHeads[Consumer], ListEntry, &PageListLock); + ExInterlockedInsertTailList(&UsedPageListHeads[Consumer], ListEntry, + &PageListLock); MmStats.NrSystemPages++; MmStats.NrFreePages--; diff --git a/reactos/ntoskrnl/mm/i386/page.c b/reactos/ntoskrnl/mm/i386/page.c index 5f888319f2f..f4334c2c36b 100644 --- a/reactos/ntoskrnl/mm/i386/page.c +++ b/reactos/ntoskrnl/mm/i386/page.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: page.c,v 1.33 2002/01/01 03:29:15 dwelch Exp $ +/* $Id: page.c,v 1.34 2002/01/08 00:49:01 dwelch Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/mm/i386/page.c @@ -239,7 +239,7 @@ NTSTATUS MmGetPageEntry2(PVOID PAddress, PULONG* Pte, BOOLEAN MayWait) if (Address >= KERNEL_BASE && MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] != 0) { - (*Pde) = MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)]; + (*Pde) = MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)]; FLUSH_TLB; } else @@ -505,7 +505,14 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage, */ if (WasDirty != NULL) { - *WasDirty = Pte & PA_DIRTY; + if (Pte & PA_DIRTY) + { + *WasDirty = TRUE; + } + else + { + *WasDirty = FALSE; + } } if (PhysicalAddr != NULL) { @@ -514,7 +521,8 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage, } VOID -MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY* SwapEntry) +MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, + SWAPENTRY* SwapEntry) /* * FUNCTION: Delete a virtual mapping */ @@ -741,6 +749,24 @@ VOID MmSetCleanPage(PEPROCESS Process, PVOID Address) } } +VOID MmSetDirtyPage(PEPROCESS Process, PVOID Address) +{ + PULONG PageEntry; + PEPROCESS CurrentProcess = PsGetCurrentProcess(); + + if (Process != CurrentProcess) + { + KeAttachProcess(Process); + } + PageEntry = MmGetPageEntry(Address); + (*PageEntry) = (*PageEntry) | PA_DIRTY; + FLUSH_TLB; + if (Process != CurrentProcess) + { + KeDetachProcess(); + } +} + VOID MmEnableVirtualMapping(PEPROCESS Process, PVOID Address) { PULONG PageEntry; @@ -850,10 +876,10 @@ MmCreatePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY SwapEntry) { - PEPROCESS CurrentProcess; - PULONG Pte; - NTSTATUS Status; - + PEPROCESS CurrentProcess; + PULONG Pte; + NTSTATUS Status; + if (Process != NULL) { CurrentProcess = PsGetCurrentProcess(); @@ -951,8 +977,9 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process, Attributes = ProtectToPTE(flProtect); if (!(Attributes & PA_PRESENT) && PhysicalAddress != 0) { - DPRINT1("Setting physical address but not allowing access at address 0x%.8X " - "with attributes %x/%x.\n", Address, Attributes, flProtect); + DPRINT1("Setting physical address but not allowing access at address " + "0x%.8X with attributes %x/%x.\n", + Address, Attributes, flProtect); KeBugCheck(0); } diff --git a/reactos/ntoskrnl/mm/pagefile.c b/reactos/ntoskrnl/mm/pagefile.c index 3540fc39298..5e7ea13d645 100644 --- a/reactos/ntoskrnl/mm/pagefile.c +++ b/reactos/ntoskrnl/mm/pagefile.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: pagefile.c,v 1.14 2001/12/31 19:06:47 dwelch Exp $ +/* $Id: pagefile.c,v 1.15 2002/01/08 00:49:00 dwelch Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/mm/pagefile.c @@ -80,7 +80,7 @@ static ULONG MiReservedSwapPages; /* * Number of pages that can be used for potentially swapable memory without - * pagefile space being reserved. The intention is that is allows smss + * pagefile space being reserved. The intention is that this allows smss * to start up and create page files while ordinarily having a commit * ratio of one. */ @@ -115,6 +115,18 @@ NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl) i = FILE_FROM_ENTRY(SwapEntry); offset = OFFSET_FROM_ENTRY(SwapEntry); + + if (i > MAX_PAGING_FILES) + { + DPRINT1("Bad swap entry 0x%.8X\n", SwapEntry); + KeBugCheck(0); + } + if (PagingFileList[i]->FileObject == NULL || + PagingFileList[i]->FileObject->DeviceObject == NULL) + { + DPRINT1("Bad paging file 0x%.8X\n", SwapEntry); + KeBugCheck(0); + } file_offset.QuadPart = offset * 4096; @@ -141,6 +153,18 @@ NTSTATUS MmReadFromSwapPage(SWAPENTRY SwapEntry, PMDL Mdl) i = FILE_FROM_ENTRY(SwapEntry); offset = OFFSET_FROM_ENTRY(SwapEntry); + + if (i > MAX_PAGING_FILES) + { + DPRINT1("Bad swap entry 0x%.8X\n", SwapEntry); + KeBugCheck(0); + } + if (PagingFileList[i]->FileObject == NULL || + PagingFileList[i]->FileObject->DeviceObject == NULL) + { + DPRINT1("Bad paging file 0x%.8X\n", SwapEntry); + KeBugCheck(0); + } file_offset.QuadPart = offset * 4096; @@ -204,7 +228,6 @@ MiAllocPageFromPagingFile(PPAGINGFILE PagingFile) { KIRQL oldIrql; ULONG i, j; - static BOOLEAN SwapSpaceMessage = FALSE; KeAcquireSpinLock(&PagingFile->AllocMapLock, &oldIrql); @@ -229,11 +252,6 @@ MiAllocPageFromPagingFile(PPAGINGFILE PagingFile) } KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql); - if (!SwapSpaceMessage) - { - DPRINT1("MM: Out of swap space.\n"); - SwapSpaceMessage = TRUE; - } return(0xFFFFFFFF); } @@ -273,12 +291,18 @@ MmAllocSwapPage(VOID) ULONG i; ULONG off; SWAPENTRY entry; + static BOOLEAN SwapSpaceMessage = FALSE; KeAcquireSpinLock(&PagingFileListLock, &oldIrql); if (MiFreeSwapPages == 0) { KeReleaseSpinLock(&PagingFileListLock, oldIrql); + if (!SwapSpaceMessage) + { + DPRINT1("MM: Out of swap space.\n"); + SwapSpaceMessage = TRUE; + } return(0); } @@ -303,7 +327,12 @@ MmAllocSwapPage(VOID) } } - KeReleaseSpinLock(&PagingFileListLock, oldIrql); + KeReleaseSpinLock(&PagingFileListLock, oldIrql); + if (!SwapSpaceMessage) + { + DPRINT1("MM: Out of swap space.\n"); + SwapSpaceMessage = TRUE; + } return(0); } @@ -355,7 +384,8 @@ NtCreatePagingFile(IN PUNICODE_STRING PageFileName, 0, NULL, NULL); - Status = NtCreateFile(&FileHandle, + + Status = IoCreateFile(&FileHandle, FILE_ALL_ACCESS, &ObjectAttributes, &IoStatus, @@ -365,7 +395,10 @@ NtCreatePagingFile(IN PUNICODE_STRING PageFileName, FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, - 0); + 0, + CreateFileTypeNone, + NULL, + SL_OPEN_PAGING_FILE); if (!NT_SUCCESS(Status)) { return(Status); diff --git a/reactos/ntoskrnl/mm/rmap.c b/reactos/ntoskrnl/mm/rmap.c index dcf6b4c987e..8f7fc2627ec 100644 --- a/reactos/ntoskrnl/mm/rmap.c +++ b/reactos/ntoskrnl/mm/rmap.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: rmap.c,v 1.2 2002/01/01 03:29:15 dwelch Exp $ +/* $Id: rmap.c,v 1.3 2002/01/08 00:49:00 dwelch Exp $ * * COPYRIGHT: See COPYING in the top directory * PROJECT: ReactOS kernel @@ -94,7 +94,8 @@ MmPageOutPhysicalAddress(PVOID PhysicalAddress) /* * Get or create a pageop */ - PageOp = MmGetPageOp(MemoryArea, 0, 0, MemoryArea->Data.SectionData.Segment, + PageOp = MmGetPageOp(MemoryArea, 0, 0, + MemoryArea->Data.SectionData.Segment, Offset.u.LowPart, MM_PAGEOP_PAGEOUT); if (PageOp == NULL) { @@ -119,7 +120,8 @@ MmPageOutPhysicalAddress(PVOID PhysicalAddress) /* * Do the actual page out work. */ - Status = MmPageOutSectionView(&Process->AddressSpace, MemoryArea, Address, PageOp); + Status = MmPageOutSectionView(&Process->AddressSpace, MemoryArea, + Address, PageOp); } else if (Type == MEMORY_AREA_VIRTUAL_MEMORY) { @@ -142,7 +144,8 @@ MmPageOutPhysicalAddress(PVOID PhysicalAddress) /* * Do the actual page out work. */ - Status = MmPageOutVirtualMemory(&Process->AddressSpace, MemoryArea, Address, PageOp); + Status = MmPageOutVirtualMemory(&Process->AddressSpace, MemoryArea, + Address, PageOp); } else { @@ -157,6 +160,8 @@ MmInsertRmap(PVOID PhysicalAddress, PEPROCESS Process, PVOID Address) PMM_RMAP_ENTRY current_entry; PMM_RMAP_ENTRY new_entry; + Address = (PVOID)PAGE_ROUND_DOWN(Address); + new_entry = ExAllocatePool(NonPagedPool, sizeof(MM_RMAP_ENTRY)); if (new_entry == NULL) { @@ -165,11 +170,13 @@ MmInsertRmap(PVOID PhysicalAddress, PEPROCESS Process, PVOID Address) new_entry->Address = Address; new_entry->Process = Process; - if (MmGetPhysicalAddressForProcess(Process, Address)!= (ULONG)PhysicalAddress) + if (MmGetPhysicalAddressForProcess(Process, Address) != + (ULONG)PhysicalAddress) { - DPRINT1("Insert rmap (%d, 0x%.8X) 0x%.8X which doesn't match physical address 0x%.8X\n", - Process->UniqueProcessId, Address, - MmGetPhysicalAddressForProcess(Process, Address), PhysicalAddress) + DPRINT1("Insert rmap (%d, 0x%.8X) 0x%.8X which doesn't match physical " + "address 0x%.8X\n", Process->UniqueProcessId, Address, + MmGetPhysicalAddressForProcess(Process, Address), + PhysicalAddress) KeBugCheck(0); } @@ -182,20 +189,27 @@ MmInsertRmap(PVOID PhysicalAddress, PEPROCESS Process, PVOID Address) VOID MmDeleteAllRmaps(PVOID PhysicalAddress, PVOID Context, - VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process, PVOID Address)) + VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process, + PVOID Address)) { PMM_RMAP_ENTRY current_entry; PMM_RMAP_ENTRY previous_entry; ExAcquireFastMutex(&RmapListLock); current_entry = MmGetRmapListHeadPage(PhysicalAddress); + if (current_entry == NULL) + { + DPRINT1("MmDeleteAllRmaps: No rmaps.\n"); + KeBugCheck(0); + } while (current_entry != NULL) { previous_entry = current_entry; current_entry = current_entry->Next; if (DeleteMapping) { - DeleteMapping(Context, previous_entry->Process, previous_entry->Address); + DeleteMapping(Context, previous_entry->Process, + previous_entry->Address); } ExFreePool(previous_entry); } @@ -213,7 +227,8 @@ MmDeleteRmap(PVOID PhysicalAddress, PEPROCESS Process, PVOID Address) current_entry = MmGetRmapListHeadPage(PhysicalAddress); while (current_entry != NULL) { - if (current_entry->Process == Process && current_entry->Address == Address) + if (current_entry->Process == Process && + current_entry->Address == Address) { if (previous_entry == NULL) { diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index a559a002065..2836bb49a65 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.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: section.c,v 1.74 2002/01/01 05:09:50 dwelch Exp $ +/* $Id: section.c,v 1.75 2002/01/08 00:49:00 dwelch Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/mm/section.c @@ -271,8 +271,8 @@ MmUnsharePageEntrySectionSegment(PSECTION_OBJECT Section, } Entry = MAKE_SSE(PAGE_FROM_SSE(Entry), SHARE_COUNT_FROM_SSE(Entry) - 1); /* - * If we reducing the share count of this entry to zero then set the entry to zero and - * tell the cache the page is no longer mapped. + * If we reducing the share count of this entry to zero then set the entry + * to zero and tell the cache the page is no longer mapped. */ if (SHARE_COUNT_FROM_SSE(Entry) == 0) { @@ -372,7 +372,8 @@ MiReadPage(PMEMORY_AREA MemoryArea, TRUE); if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE) { - CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, FALSE, FALSE, FALSE); + CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, FALSE, FALSE, + FALSE); return(Status); } } @@ -411,7 +412,7 @@ MiReadPage(PMEMORY_AREA MemoryArea, Mdl, Offset, &IoStatus, - FALSE); + TRUE); return(Status); } } @@ -432,7 +433,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, ULONG Entry1; ULONG Attributes; PMM_PAGEOP PageOp; - + /* * There is a window between taking the page fault and locking the * address space when another thread could load the page so we check @@ -541,7 +542,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, DbgPrint("Unable to create virtual mapping\n"); KeBugCheck(0); } - MmInsertRmap(Page, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address)); + MmInsertRmap(Page, PsGetCurrentProcess(), + (PVOID)PAGE_ROUND_DOWN(Address)); } if (Locked) { @@ -564,8 +566,10 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, MmUnlockSectionSegment(Segment); MmUnlockSection(Section); + + MmDeletePageFileMapping(NULL, (PVOID)PAddress, &SwapEntry); - Status = MmRequestPageMemoryConsumer(MC_USER, FALSE, &Page); + Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page); if (!NT_SUCCESS(Status)) { KeBugCheck(0); @@ -600,11 +604,17 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, KeBugCheck(0); return(Status); } + + /* + * Store the swap entry for later use. + */ + MmSetSavedSwapEntryPage(Page, SwapEntry); /* * Add the page to the process's working set */ - MmInsertRmap(Page, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address)); + MmInsertRmap(Page, PsGetCurrentProcess(), + (PVOID)PAGE_ROUND_DOWN(Address)); /* * Finish the operation @@ -633,7 +643,10 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, MemoryArea->Attributes, Offset.QuadPart, FALSE); - /* Don't add an rmap entry since the page mapped could be for anything. */ + /* + * Don't add an rmap entry since the page mapped could be for + * anything. + */ if (Locked) { MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address)); @@ -673,7 +686,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, MemoryArea->Attributes, (ULONG)Page, FALSE); - MmInsertRmap(Page, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address)); + MmInsertRmap(Page, PsGetCurrentProcess(), + (PVOID)PAGE_ROUND_DOWN(Address)); if (Locked) { MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address)); @@ -798,7 +812,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, MmLockSection(Section); MmLockSectionSegment(Segment); } - MmInsertRmap(Page, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address)); + MmInsertRmap(Page, PsGetCurrentProcess(), + (PVOID)PAGE_ROUND_DOWN(Address)); if (!NT_SUCCESS(Status)) { DbgPrint("Unable to create virtual mapping\n"); @@ -869,13 +884,19 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, Entry = (ULONG)Page; MmSetPageEntrySectionSegment(Segment, Offset.QuadPart, Entry); MmSharePageEntrySectionSegment(Segment, Offset.QuadPart); + + /* + * Save the swap entry. + */ + MmSetSavedSwapEntryPage(Page, SwapEntry); Status = MmCreateVirtualMapping(PsGetCurrentProcess(), Address, Attributes, (ULONG)Page, FALSE); - MmInsertRmap(Page, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address)); + MmInsertRmap(Page, PsGetCurrentProcess(), + (PVOID)PAGE_ROUND_DOWN(Address)); if (!NT_SUCCESS(Status)) { DbgPrint("Unable to create virtual mapping\n"); @@ -909,7 +930,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, Attributes, (ULONG)Page, FALSE); - MmInsertRmap(Page, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address)); + MmInsertRmap(Page, PsGetCurrentProcess(), + (PVOID)PAGE_ROUND_DOWN(Address)); if (!NT_SUCCESS(Status)) { DbgPrint("Unable to create virtual mapping\n"); @@ -1069,7 +1091,8 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace, MemoryArea->Attributes, (ULONG)NewPage, FALSE); - MmInsertRmap(NewPage, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address)); + MmInsertRmap(NewPage, PsGetCurrentProcess(), + (PVOID)PAGE_ROUND_DOWN(Address)); if (!NT_SUCCESS(Status)) { DbgPrint("Unable to create virtual mapping\n"); @@ -1084,7 +1107,8 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace, * Unshare the old page. */ MmUnsharePageEntrySectionSegment(Section, Segment, Offset.QuadPart, FALSE); - MmDeleteRmap((PVOID)OldPage, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address)); + MmDeleteRmap((PVOID)OldPage, PsGetCurrentProcess(), + (PVOID)PAGE_ROUND_DOWN(Address)); MmDereferencePage((PVOID)OldPage); PageOp->Status = STATUS_SUCCESS; @@ -1106,7 +1130,10 @@ MmPageOutDeleteMapping(PVOID Context, PEPROCESS Process, PVOID Address) FALSE, &WasDirty, (PULONG)&PhysicalAddress); - PageOutContext->WasDirty = PageOutContext->WasDirty || WasDirty; + if (WasDirty) + { + PageOutContext->WasDirty = TRUE; + } if (!PageOutContext->Private) { MmUnsharePageEntrySectionSegment(PageOutContext->Section, @@ -1137,10 +1164,6 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace, PREACTOS_COMMON_FCB_HEADER Fcb; BOOLEAN DirectMapped; - DPRINT("MmPageOutSection(Process %d, Address 0x%.8X)\n", - AddressSpace->Process->UniqueProcessId, - Address); - Address = (PVOID)PAGE_ROUND_DOWN(Address); Offset.QuadPart = (ULONG)(Address - (ULONG)MemoryArea->BaseAddress) + @@ -1171,11 +1194,13 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace, Section = MemoryArea->Data.SectionData.Section; /* - * This should never happen even mapping of the physical memory are never + * This should never happen since mappings of physical memory are never * placed in the rmap lists. */ - if (Segment->Flags & SO_PHYSICAL_MEMORY) + if (Section->Flags & SO_PHYSICAL_MEMORY) { + DPRINT1("Trying to page out from physical memory section address 0x%X " + "process %d\n", Address, AddressSpace->Process->UniqueProcessId); KeBugCheck(0); } @@ -1183,8 +1208,16 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace, * Get the section segment entry and the physical address. */ Entry = MmGetPageEntrySectionSegment(Segment, Offset.QuadPart); - PhysicalAddress = (PVOID)MmGetPhysicalAddressForProcess(AddressSpace->Process, - Address); + if (!MmIsPagePresent(AddressSpace->Process, Address)) + { + DPRINT1("Trying to page out not-present page at (%d,0x%.8X).\n", + AddressSpace->Process->UniqueProcessId, Address); + KeBugCheck(0); + } + PhysicalAddress = + (PVOID)MmGetPhysicalAddressForProcess(AddressSpace->Process, + Address); + SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress); /* * Prepare the context structure for the rmap delete call. @@ -1193,7 +1226,15 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace, Context.Segment = Segment; Context.Offset = Offset; Context.WasDirty = FALSE; - Context.Private = Private = ((PVOID)(Entry & 0xFFFFF000) != PhysicalAddress); + if (IS_SWAP_FROM_SSE(Entry) || + (PVOID)(PAGE_FROM_SSE(Entry)) != PhysicalAddress) + { + Context.Private = Private = TRUE; + } + else + { + Context.Private = Private = FALSE; + } /* * Take an additional reference to the page. @@ -1201,23 +1242,44 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace, MmReferencePage(PhysicalAddress); /* - * Paging only data mapped read-only is easy. + * Paging out data mapped read-only is easy. */ if (MemoryArea->Attributes & PAGE_READONLY || MemoryArea->Attributes & PAGE_EXECUTE_READ) { + /* + * Read-only data should never be in the swapfile. + */ + if (SwapEntry != 0) + { + DPRINT1("SwapEntry != 0 was 0x%.8X at address 0x%.8X, " + "paddress 0x%.8X\n", SwapEntry, Address, + PhysicalAddress); + KeBugCheck(0); + } + + /* + * Read-only data should never be COWed + */ + if (Private) + { + DPRINT1("Had private copy of read-only page.\n"); + KeBugCheck(0); + } + /* * Delete all mappings of this page. */ - MmDeleteAllRmaps(PhysicalAddress, (PVOID)&Context, MmPageOutDeleteMapping); + MmDeleteAllRmaps(PhysicalAddress, (PVOID)&Context, + MmPageOutDeleteMapping); if (Context.WasDirty) { KeBugCheck(0); } /* - * If this page wasn't direct mapped then we have a private copy so release - * back to the system; otherwise the cache manager will have handled freeing - * the cache segment which we mapped from. + * If this page wasn't direct mapped then we have a private copy so + * release back to the system; otherwise the cache manager will have + * handled freeing the cache segment which we mapped from. */ if (!DirectMapped) { @@ -1251,10 +1313,31 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace, */ if (!Context.WasDirty) { - if (!DirectMapped) + if (!DirectMapped || Private) { MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress); } + if (Private) + { + if (SwapEntry == 0) + { + DPRINT1("Private page, non-dirty but not swapped out " + "process %d address 0x%.8X\n", + AddressSpace->Process->UniqueProcessId, + Address); + KeBugCheck(0); + } + else + { + Status = MmCreatePageFileMapping(AddressSpace->Process, + Address, + SwapEntry); + if (!NT_SUCCESS(Status)) + { + KeBugCheck(0); + } + } + } PageOp->Status = STATUS_SUCCESS; KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); @@ -1266,8 +1349,9 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace, * If this page was direct mapped from the cache then the cache manager * will already have taken care of writing it back. */ - if (DirectMapped) + if (DirectMapped && !Private) { + assert(SwapEntry == 0); MmDereferencePage((PVOID)PhysicalAddress); PageOp->Status = STATUS_SUCCESS; KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); @@ -1294,6 +1378,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace, MemoryArea->Attributes, (ULONG)PhysicalAddress, FALSE); + MmSetDirtyPage(MemoryArea->Process, Address); MmInsertRmap(PhysicalAddress, MemoryArea->Process, Address); @@ -1302,15 +1387,17 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace, { /* * For non-private pages if the page wasn't direct mapped then - * set it back into section segment entry so we don't loose our - * copy. Otherwise it will be handled by the cache manager. + * set it back into the section segment entry so we don't loose + * our copy. Otherwise it will be handled by the cache manager. */ Status = MmCreateVirtualMapping(MemoryArea->Process, Address, MemoryArea->Attributes, (ULONG)PhysicalAddress, FALSE); - MmSetPageEntrySectionSegment(Segment, Offset.QuadPart, (ULONG)PhysicalAddress); + MmSetDirtyPage(MemoryArea->Process, Address); + MmSetPageEntrySectionSegment(Segment, Offset.QuadPart, + (ULONG)PhysicalAddress); MmSharePageEntrySectionSegment(Segment, Offset.QuadPart); } PageOp->Status = STATUS_UNSUCCESSFUL; @@ -1328,7 +1415,8 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace, Status = MmWriteToSwapPage(SwapEntry, Mdl); if (!NT_SUCCESS(Status)) { - DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", Status); + DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", + Status); /* * As above: undo our actions. * FIXME: Also free the swap page. @@ -1340,6 +1428,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace, MemoryArea->Attributes, (ULONG)PhysicalAddress, FALSE); + MmSetDirtyPage(MemoryArea->Process, Address); MmInsertRmap(PhysicalAddress, MemoryArea->Process, Address); @@ -1351,7 +1440,9 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace, MemoryArea->Attributes, (ULONG)PhysicalAddress, FALSE); - MmSetPageEntrySectionSegment(Segment, Offset.QuadPart, (ULONG)PhysicalAddress); + MmSetDirtyPage(MemoryArea->Process, Address); + MmSetPageEntrySectionSegment(Segment, Offset.QuadPart, + (ULONG)PhysicalAddress); MmSharePageEntrySectionSegment(Segment, Offset.QuadPart); } PageOp->Status = STATUS_UNSUCCESSFUL; @@ -1364,6 +1455,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace, * Otherwise we have succeeded. */ DPRINT("MM: Wrote section page 0x%.8X to swap!\n", PhysicalAddress); + MmSetSavedSwapEntryPage(PhysicalAddress, 0); MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress); if (Private) diff --git a/reactos/ntoskrnl/mm/virtual.c b/reactos/ntoskrnl/mm/virtual.c index 7d7f31a32bb..c6d447a8350 100644 --- a/reactos/ntoskrnl/mm/virtual.c +++ b/reactos/ntoskrnl/mm/virtual.c @@ -1,4 +1,4 @@ -/* $Id: virtual.c,v 1.53 2002/01/01 00:21:56 dwelch Exp $ +/* $Id: virtual.c,v 1.54 2002/01/08 00:49:01 dwelch Exp $ * * COPYRIGHT: See COPYING in the top directory * PROJECT: ReactOS kernel @@ -172,7 +172,8 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace, Status = MmWriteToSwapPage(SwapEntry, Mdl); if (!NT_SUCCESS(Status)) { - DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", Status); + DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", + Status); MmEnableVirtualMapping(MemoryArea->Process, Address); PageOp->Status = STATUS_UNSUCCESSFUL; KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); @@ -187,6 +188,7 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace, MmDeleteVirtualMapping(MemoryArea->Process, Address, FALSE, NULL, NULL); MmCreatePageFileMapping(MemoryArea->Process, Address, SwapEntry); MmDeleteAllRmaps(PhysicalAddress, NULL, NULL); + MmSetSavedSwapEntryPage(PhysicalAddress, 0); MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress); PageOp->Status = STATUS_SUCCESS; KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); @@ -331,6 +333,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace, { KeBugCheck(0); } + MmSetSavedSwapEntryPage(Page, SwapEntry); } /* diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index 1e045893f89..c8836cb857e 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -1,4 +1,4 @@ -/* $Id: thread.c,v 1.82 2002/01/03 14:03:05 ekohl Exp $ +/* $Id: thread.c,v 1.83 2002/01/08 00:49:01 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -108,9 +108,11 @@ VOID PsDumpThreads(BOOLEAN IncludeSystem) } if (IncludeSystem || current->ThreadsProcess->UniqueProcessId >= 6) { - DbgPrint("current->Tcb.State %d PID.TID %d.%d Name %.8s\n", - current->Tcb.State, current->ThreadsProcess->UniqueProcessId, - current->Cid.UniqueThread, current->ThreadsProcess->ImageFileName); + DbgPrint("current->Tcb.State %d PID.TID %d.%d Name %.8s Stack: \n", + current->Tcb.State, + current->ThreadsProcess->UniqueProcessId, + current->Cid.UniqueThread, + current->ThreadsProcess->ImageFileName); if (current->Tcb.State == THREAD_STATE_RUNNABLE || current->Tcb.State == THREAD_STATE_SUSPENDED || current->Tcb.State == THREAD_STATE_BLOCKED) @@ -121,11 +123,12 @@ VOID PsDumpThreads(BOOLEAN IncludeSystem) i = 0; while (Ebp != 0 && Ebp >= (PULONG)current->Tcb.StackLimit) { - DbgPrint("Frame: 0x%.8X Eip: 0x%.8X%s", Ebp[0], Ebp[1], - (i % 2) == 1 ? "\n" : ""); + DbgPrint("%.8X%s", Ebp[0], Ebp[1], + (i % 8) == 7 ? "\n" : " "); Ebp = (PULONG)Ebp[0]; + i++; } - if ((i % 2) == 0) + if ((i % 8) != 7) { DbgPrint("\n"); } diff --git a/reactos/tools/helper.mk b/reactos/tools/helper.mk index 3da55ec7072..33979c6732c 100644 --- a/reactos/tools/helper.mk +++ b/reactos/tools/helper.mk @@ -1,4 +1,4 @@ -# $Id: helper.mk,v 1.9 2001/12/11 06:00:07 phreak Exp $ +# $Id: helper.mk,v 1.10 2002/01/08 00:49:02 dwelch Exp $ # # Helper makefile for ReactOS modules # Variables this makefile accepts: @@ -398,6 +398,7 @@ MK_NOSTRIPNAME := $(MK_BASENAME).nostrip$(MK_EXT) # We don't want to link header files MK_OBJECTS := $(filter-out %.h,$(TARGET_OBJECTS)) +MK_STRIPPED_OBJECT := $(MK_BASENAME).stripped.o ifeq ($(MK_IMPLIBONLY),yes) @@ -415,7 +416,7 @@ $(MK_IMPLIBPATH)/$(MK_IMPLIB_FULLNAME): $(TARGET_OBJECTS) else # MK_IMPLIBONLY -all: $(MK_FULLNAME) +all: $(MK_FULLNAME) $(MK_NOSTRIPNAME) ifeq ($(MK_IMPLIB),yes) @@ -453,6 +454,11 @@ endif $(MK_FULLRES) $(MK_OBJECTS) $(MK_LIBS) $(MK_GCCLIBS) - $(RM) temp.exp - $(NM) --numeric-sort $(MK_NOSTRIPNAME) > $(MK_BASENAME).sym + +$(MK_FULLNAME): $(MK_NOSTRIPNAME) + $(CP) $(MK_NOSTRIPNAME) $(MK_FULLNAME) +# $(STRIP) --strip-debug $(MK_FULLNAME) + endif # KM_MODE # Kernel mode targets @@ -489,11 +495,33 @@ $(MK_NOSTRIPNAME): $(MK_FULLRES) $(TARGET_OBJECTS) $(MK_LIBS) - $(RM) temp.exp - $(NM) --numeric-sort $(MK_NOSTRIPNAME) > $(MK_BASENAME).sym -endif # MK_MODE +$(MK_FULLNAME): $(MK_FULLRES) $(TARGET_OBJECTS) $(MK_LIBS) + $(LD) -r -o $(MK_STRIPPED_OBJECT) $(MK_OBJECTS) + $(STRIP) --strip-debug $(MK_STRIPPED_OBJECT) + $(CC) -Wl,--base-file,base.tmp \ + -Wl,--entry,$(TARGET_ENTRY) \ + $(TARGET_LFLAGS) \ + -nostartfiles -nostdlib \ + -o junk.tmp \ + $(MK_FULLRES) $(MK_STRIPPED_OBJECT) $(MK_LIBS) $(MK_GCCLIBS) + - $(RM) junk.tmp + $(DLLTOOL) --dllname $(MK_FULLNAME) \ + --base-file base.tmp \ + --output-exp temp.exp $(MK_EXTRACMD) + - $(RM) base.tmp + $(CC) $(TARGET_LFLAGS) \ + -Wl,--subsystem,native \ + -Wl,--image-base,$(TARGET_BASE) \ + -Wl,--file-alignment,0x1000 \ + -Wl,--section-alignment,0x1000 \ + -Wl,--entry,$(TARGET_ENTRY) \ + -Wl,temp.exp \ + -mdll -nostartfiles -nostdlib \ + -o $(MK_FULLNAME) \ + $(MK_FULLRES) $(MK_STRIPPED_OBJECT) $(MK_LIBS) $(MK_GCCLIBS) + - $(RM) temp.exp -$(MK_FULLNAME): $(MK_NOSTRIPNAME) - $(CP) $(MK_NOSTRIPNAME) $(MK_FULLNAME) -# $(STRIP) --strip-debug $(MK_FULLNAME) +endif # MK_MODE endif # MK_IMPLIBONLY diff --git a/reactos/tools/wmc/windows.h b/reactos/tools/wmc/windows.h index 48d43b76245..0c8a7d4b6f8 100644 --- a/reactos/tools/wmc/windows.h +++ b/reactos/tools/wmc/windows.h @@ -10,7 +10,11 @@ typedef const CHAR *LPCSTR; typedef const WCHAR *LPCWSTR; typedef unsigned int *LPBOOL; +#ifndef __unix__ #define STDCALL __attribute__((stdcall)) +#else +#define STDCALL +#endif int STDCALL MultiByteToWideChar( UINT CodePage,