}
+struct CcSetFileSizes_param {
+ PFILE_OBJECT FileObject;
+ PCC_FILE_SIZES FileSizes;
+ };
+
+/* map: (PUBLIC_BCB *)PublicBcb -> (struct private_bcb *)privbcb */
+static void CcSetFileSizes_private_bcb_hash_foreach(
+ PUBLIC_BCB *PublicBcb, /* key */
+ struct private_bcb *privbcb, /* value */
+ struct CcSetFileSizes_param *CcSetFileSizes_param) /* user_data */
+{
+ g_return_if_fail(PublicBcb!=NULL);
+ g_return_if_fail(privbcb!=NULL);
+ g_return_if_fail(CcSetFileSizes_param!=NULL);
+
+ if (privbcb->FileObject!=CcSetFileSizes_param->FileObject)
+ return;
+
+ /* size changes behind our cached range? */
+ if (1
+ && CcSetFileSizes_param->FileSizes->AllocationSize .QuadPart>=privbcb->MappedFileOffset.QuadPart+privbcb->MappedLength
+ && CcSetFileSizes_param->FileSizes->FileSize .QuadPart>=privbcb->MappedFileOffset.QuadPart+privbcb->MappedLength
+ && CcSetFileSizes_param->FileSizes->ValidDataLength.QuadPart>=privbcb->MappedFileOffset.QuadPart+privbcb->MappedLength)
+ return;
+
+ /* FIXME: check BCB && 'struct page_position' invalidities */
+ g_assert_not_reached(); /* NOT IMPLEMENTED YET */
+}
+
/**
* CcSetFileSizes:
* @FileObject: Initialized open #FileObject to update file sizes of.
*/
VOID CcSetFileSizes(IN PFILE_OBJECT FileObject,IN PCC_FILE_SIZES FileSizes)
{
+struct CcSetFileSizes_param CcSetFileSizes_param;
+
g_return_if_fail(FileObject!=NULL);
g_return_if_fail(FileSizes!=NULL);
FileObject,(guint64)FileSizes->AllocationSize.QuadPart,(guint64)FileSizes->FileSize.QuadPart,
(guint64)FileSizes->ValidDataLength.QuadPart);
- /* FIXME: check BCB && 'struct page_position' invalidities */
+ CcSetFileSizes_param.FileObject=FileObject;
+ CcSetFileSizes_param.FileSizes=FileSizes;
+ g_hash_table_foreach(
+ private_bcb_hash, /* hash_table */
+ (GHFunc)CcSetFileSizes_private_bcb_hash_foreach, /* func */
+ &CcSetFileSizes_param); /* user_data */
}
SectionObjectPointer,PublicBcb,privbcb,privbcb->FileObject,
(guint64)(!FileOffset ? -1 : FileOffset->QuadPart),(gulong)Length,(gint)UninitializeCacheMaps);
+ g_assert_not_reached();
+
privbcb->dirty=FALSE; /* purge it */
return TRUE;
}
-static gboolean captive_FileObject_ZeroData(PFILE_OBJECT FileObject,guint64 window_bottom,guint64 window_top)
-{
-MDL *Mdl;
-KEVENT Event;
-gpointer zerobuffer;
-LARGE_INTEGER window_bottom_LargeInteger;
-NTSTATUS err;
-IO_STATUS_BLOCK IoStatus;
-
- g_return_val_if_fail(FileObject!=NULL,FALSE);
- g_return_val_if_fail(window_bottom<=window_top,FALSE);
-
- if (window_bottom==window_top) /* trivia */
- return TRUE;
-
- g_return_val_if_fail(FileObject->DeviceObject!=NULL,FALSE);
-
- /* Such requirement is W32 documented for CcZeroData()
- * and it is really a requirement at least for the underlying fastfat.sys.
- */
- g_assert(0==CAPTIVE_ROUND_DOWN_EXCEEDING64(window_bottom,FileObject->DeviceObject->SectorSize));
- g_assert(0==CAPTIVE_ROUND_DOWN_EXCEEDING64(window_top ,FileObject->DeviceObject->SectorSize));
-
- zerobuffer=g_malloc0(window_top-window_bottom);
- window_bottom_LargeInteger.QuadPart=window_bottom;
-
- Mdl=MmCreateMdl(NULL,zerobuffer,window_top-window_bottom);
- g_assert(Mdl!=NULL);
-
- KeInitializeEvent(&Event,NotificationEvent,FALSE);
-
- /* FIXME: Notify logging subsystem by LSNs? */
-
- /* Use rather IoSynchronousPageWrite() than IoPageWrite() to prevent STATUS_PENDING. */
- err=IoSynchronousPageWrite(FileObject,Mdl,&window_bottom_LargeInteger,&Event,&IoStatus);
- g_assert(NT_SUCCESS(err));
- g_assert(NT_SUCCESS(IoStatus.Status));
- /* We should write up to the last sector touched by the range although we
- * do not need to successfuly write the whole aligned amount.
- * FIXME: Also we can get just value 0 if the write is considered 'not dirty'
- * during FAT write by fastfat.sys.
- */
- g_assert(IoStatus.Information==0
- || (window_top-window_bottom)==CAPTIVE_ROUND_UP(IoStatus.Information,FileObject->DeviceObject->SectorSize));
- g_assert(IoStatus.Information<=window_top-window_bottom); /* redundant */
-
- g_free(zerobuffer);
-
- return TRUE;
-}
-
-
BOOLEAN CcZeroData(IN PFILE_OBJECT FileObject,IN PLARGE_INTEGER StartOffset,IN PLARGE_INTEGER EndOffset,IN BOOLEAN Wait)
{
-guint64 window_lower_bottom,window_lower_top;
-guint64 window_higher_bottom,window_higher_top;
+SECTION_OBJECT_POINTERS *SectionObjectPointers_orig;
+PVOID Bcb;
+PVOID Buffer;
+BOOLEAN errboolean;
g_return_val_if_fail(FileObject!=NULL,FALSE);
g_return_val_if_fail(StartOffset!=NULL,FALSE);
g_return_val_if_fail(EndOffset!=NULL,FALSE);
g_return_val_if_fail(StartOffset->QuadPart<=EndOffset->QuadPart,FALSE);
+ g_return_val_if_fail((EndOffset->QuadPart-StartOffset->QuadPart)
+ ==(ULONG)(EndOffset->QuadPart-StartOffset->QuadPart),FALSE);
- g_return_val_if_fail(FileObject->SectionObjectPointers!=NULL,FALSE);
-
- window_lower_bottom=StartOffset->QuadPart;
- window_lower_top=EndOffset->QuadPart;
- window_higher_bottom=window_higher_top=0;
-
- if (FileObject->SectionObjectPointers->SharedCacheMap!=NULL) {
-PUBLIC_BCB *PublicBcb;
-struct private_bcb *privbcb;
-guint64 window_cached_bottom,window_cached_top;
-
- PublicBcb=FileObject->SectionObjectPointers->SharedCacheMap;
- g_return_val_if_fail(validate_Bcb(PublicBcb),FALSE);
+ SectionObjectPointers_orig=FileObject->SectionObjectPointers;
- private_bcb_hash_init();
+ errboolean=CcPreparePinWrite(
+ FileObject, /* FileObject */
+ StartOffset, /* FileOffset */
+ EndOffset->QuadPart-StartOffset->QuadPart, /* Length */
+ TRUE, /* Zero */
+ PIN_WAIT|PIN_NO_READ, /* Flags */
+ &Bcb, /* Bcb */
+ &Buffer); /* Buffer */
+ g_assert(errboolean==TRUE);
- privbcb=g_hash_table_lookup(private_bcb_hash,PublicBcb);
- g_return_val_if_fail(privbcb!=NULL,FALSE);
-
- window_cached_bottom=MAX(StartOffset->QuadPart,privbcb->MappedFileOffset.QuadPart);
- window_cached_top=MIN(EndOffset->QuadPart,privbcb->MappedFileOffset.QuadPart+privbcb->MappedLength);
+ CcUnpinData(Bcb);
- if (window_cached_bottom<window_cached_top) {
- memset(((char *)privbcb->base)+window_cached_bottom-privbcb->MappedFileOffset.QuadPart,0,window_cached_top-window_cached_bottom);
- privbcb->dirty=TRUE;
- window_higher_top=window_lower_top;
- window_lower_top=window_cached_bottom;
- window_higher_bottom=window_cached_top;
- }
- }
- if (window_lower_bottom<window_lower_top) {
- g_return_val_if_fail(Wait==TRUE,FALSE);
- if (!captive_FileObject_ZeroData(FileObject,window_lower_bottom,window_lower_top))
- g_return_val_if_reached(FALSE);
- }
- if (window_higher_bottom<window_higher_top) {
- g_return_val_if_fail(Wait==TRUE,FALSE);
- if (!captive_FileObject_ZeroData(FileObject,window_higher_bottom,window_higher_top))
- g_return_val_if_reached(FALSE);
- }
+ FileObject->SectionObjectPointers=SectionObjectPointers_orig;
return TRUE;
}
return TRUE;
}
+
+
+VOID FsRtlIncrementCcFastReadNoWait(VOID)
+{
+ /* FIXME: {{%fs:[0]}+0x4E0}:LONG++ */
+}