summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
89c3520)
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
svn path=/trunk/; revision=73384
PFILE_OBJECT FileObject;
PMM_SECTION_SEGMENT Segment;
ULONG FileAccess;
PFILE_OBJECT FileObject;
PMM_SECTION_SEGMENT Segment;
ULONG FileAccess;
- IO_STATUS_BLOCK Iosb;
- LARGE_INTEGER Offset;
- CHAR Buffer;
FILE_STANDARD_INFORMATION FileInfo;
ULONG Length;
FILE_STANDARD_INFORMATION FileInfo;
ULONG Length;
sizeof(FILE_STANDARD_INFORMATION),
&FileInfo,
&Length);
sizeof(FILE_STANDARD_INFORMATION),
&FileInfo,
&Length);
- Iosb.Information = Length;
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(Section);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(Section);
if (FileObject->SectionObjectPointer == NULL ||
FileObject->SectionObjectPointer->SharedCacheMap == NULL)
{
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;
if(ImageSectionObject->Segments != NULL)
ExFreePool(ImageSectionObject->Segments);
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);
ExFreePoolWithTag(ImageSectionObject, TAG_MM_SECTION_SEGMENT);
ObDereferenceObject(Section);
ObDereferenceObject(FileObject);
}
Section->ImageSection = ImageSectionObject;
}
Section->ImageSection = ImageSectionObject;
return Status;
}
// Caching is initialized...
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));
+ }
+ }