Author: pschweitzer Date: Sat Nov 26 22:39:08 2016 New Revision: 73384
URL: http://svn.reactos.org/svn/reactos?rev=73384&view=rev Log: [NTOSKRNL] A hack has gained enough XP and levels up! Congratulations to the MmCreateSection() in charge of forcing file cache initialization. As show by kmtest:NtCreateSection tests and real world FSD (starting with MS FastFAT and Ext2Fsd), caching of a file can be initialized rather late (ie, on first effective read/write). That means that our current hack is totally opless on newly created files with 0-size where the IRP_MJ_READ is most of the time opless too. The hack, thanks to its level up, can now force a write (1-byte) in case read was unsuccessful and end of file. In other words, this is the hack of a hack (and a hack v2). It fixes a few failing kmtests. Thomas, Peter, please retry the FSDs on which you are currently working on and report. Thanks :-)
CORE-11819 CORE-12475
Modified: trunk/reactos/ntoskrnl/mm/section.c
Modified: trunk/reactos/ntoskrnl/mm/section.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/section.c?rev=7... ============================================================================== --- trunk/reactos/ntoskrnl/mm/section.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/section.c [iso-8859-1] Sat Nov 26 22:39:08 2016 @@ -2909,9 +2909,6 @@ PFILE_OBJECT FileObject; PMM_SECTION_SEGMENT Segment; ULONG FileAccess; - IO_STATUS_BLOCK Iosb; - LARGE_INTEGER Offset; - CHAR Buffer; FILE_STANDARD_INFORMATION FileInfo; ULONG Length;
@@ -2967,7 +2964,6 @@ sizeof(FILE_STANDARD_INFORMATION), &FileInfo, &Length); - Iosb.Information = Length; if (!NT_SUCCESS(Status)) { ObDereferenceObject(Section); @@ -3012,35 +3008,9 @@ if (FileObject->SectionObjectPointer == NULL || FileObject->SectionObjectPointer->SharedCacheMap == NULL) { - /* - * Read a bit so caching is initiated for the file object. - * This is only needed because MiReadPage currently cannot - * handle non-cached streams. - */ - Offset.QuadPart = 0; - Status = ZwReadFile(FileHandle, - NULL, - NULL, - NULL, - &Iosb, - &Buffer, - sizeof (Buffer), - &Offset, - 0); - if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE)) - { - ObDereferenceObject(Section); - ObDereferenceObject(FileObject); - return(Status); - } - if (FileObject->SectionObjectPointer == NULL || - FileObject->SectionObjectPointer->SharedCacheMap == NULL) - { - /* FIXME: handle this situation */ - ObDereferenceObject(Section); - ObDereferenceObject(FileObject); - return STATUS_INVALID_FILE_FOR_SECTION; - } + ObDereferenceObject(Section); + ObDereferenceObject(FileObject); + return STATUS_INVALID_FILE_FOR_SECTION; }
/* @@ -3836,10 +3806,19 @@ if(ImageSectionObject->Segments != NULL) ExFreePool(ImageSectionObject->Segments);
+ /* + * If image file is empty, then return that the file is invalid for section + */ + Status = StatusExeFmt; + if (StatusExeFmt == STATUS_END_OF_FILE) + { + Status = STATUS_INVALID_FILE_FOR_SECTION; + } + ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT); ObDereferenceObject(Section); ObDereferenceObject(FileObject); - return(StatusExeFmt); + return(Status); }
Section->ImageSection = ImageSectionObject; @@ -5101,6 +5080,33 @@ return Status; } // Caching is initialized... + + // Hack of the hack: actually, it might not be initialized if FSD init on effective right and if file is null-size + // In such case, force cache by initiating a write IRP + if (Status == STATUS_END_OF_FILE && !(AllocationAttributes & SEC_IMAGE) && FileObject != NULL && + (FileObject->SectionObjectPointer == NULL || FileObject->SectionObjectPointer->SharedCacheMap == NULL)) + { + Status = ZwWriteFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + &Buffer, + sizeof(Buffer), + &ByteOffset, + NULL); + if (NT_SUCCESS(Status)) + { + LARGE_INTEGER Zero; + Zero.QuadPart = 0LL; + + Status = IoSetInformation(FileObject, + FileEndOfFileInformation, + sizeof(LARGE_INTEGER), + &Zero); + ASSERT(NT_SUCCESS(Status)); + } + } } #endif