+CcZeroData()
authorshort <>
Mon, 3 Feb 2003 10:48:09 +0000 (10:48 +0000)
committershort <>
Mon, 3 Feb 2003 10:48:09 +0000 (10:48 +0000)
src/libcaptive/cc/map.c
src/libcaptive/ke/exports.captivesym

index 63b0801..22df5ef 100644 (file)
@@ -1115,3 +1115,108 @@ struct private_bcb *privbcb;
                IoStatus->Information=(FileOffset && Length ? MIN(privbcb->MappedLength,Length) : privbcb->MappedLength);
                }
 }
+
+
+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);
+
+       /* 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;
+
+       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(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);
+
+               private_bcb_hash_init();
+
+               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);
+
+               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);
+               }
+
+       return TRUE;
+}
index fd52270..d2cd426 100644 (file)
@@ -241,7 +241,7 @@ ntoskrnl.exe        MmCanFileBeTruncated    undef
 ntoskrnl.exe   IoDeleteSymbolicLink    undef
 ntoskrnl.exe   IoCreateSymbolicLink    undef
 ntoskrnl.exe   FsRtlCopyWrite  undef
-ntoskrnl.exe   CcZeroData      undef
+ntoskrnl.exe   CcZeroData
 ntoskrnl.exe   CcPreparePinWrite       undef
 ntoskrnl.exe   CcPrepareMdlWrite       undef
 ntoskrnl.exe   CcCopyWrite