Initial original import from: fuse-2.4.2-2.fc4
[captive.git] / src / libcaptive / cc / bcbpin.c
index 739ebea..c9420dc 100644 (file)
@@ -70,6 +70,10 @@ BOOLEAN CcPinMappedData
 {
 CaptiveSharedCacheMapObject *SharedCacheMap;
 CaptivePrivateBcbPinObject *captive_private_bcb_pin_object;
+BOOLEAN r;
+
+       g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"enter: CcPinMappedData: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX,Flags=0x%lX",
+                       (long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length,Flags);
 
        g_return_val_if_fail(FileObject!=NULL,FALSE);
        g_return_val_if_fail(FileOffset!=NULL,FALSE);
@@ -78,21 +82,26 @@ CaptivePrivateBcbPinObject *captive_private_bcb_pin_object;
        g_return_val_if_fail(Flags==PIN_WAIT,FALSE);    /* FIXME */
        g_return_val_if_fail(Bcb!=NULL,FALSE);
 
-       g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"%s: FileObject=%p,FileOffset=0x%llX,Length=0x%lX,Flags=0x%lX",G_STRLOC,
-                       FileObject,(guint64)FileOffset->QuadPart,(gulong)Length,(gulong)Flags);
-
        g_assert(Length<=PAGE_SIZE);
        /* Check PAGE_SIZE crossing */
        g_assert((FileOffset->QuadPart&~(PAGE_SIZE-1))==((FileOffset->QuadPart+Length-1)&~(PAGE_SIZE-1)));
 
        SharedCacheMap=captive_FileObject_to_SharedCacheMap(FileObject);
-       captive_private_bcb_pin_object=captive_private_bcb_pin_object_get_ref(SharedCacheMap,FileOffset->QuadPart);
+       /* Do not invalide 'map'ped data otherwise ntfs.sys of NT-5.1sp1 mount crashes.
+        */
+       captive_private_bcb_pin_object=captive_private_bcb_pin_object_get_ref(SharedCacheMap,
+                       CAPTIVE_ROUND_DOWN64(FileOffset->QuadPart,PAGE_SIZE),
+                       FALSE); /* invalidate_new */
 
        captive_shared_cache_map_data_validate_noread(SharedCacheMap,FileOffset->QuadPart,FileOffset->QuadPart+Length);
 
        *Bcb=captive_private_bcb_object_get_PublicBcb(CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_pin_object));
+       r=TRUE;
 
-       return TRUE;
+       g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"leave: CcPinMappedData: r=%d,Bcb=0x%lX",
+                       r,(!Bcb ? -1 : (long)*Bcb));
+
+       return r;
 }
 
 
@@ -134,31 +143,52 @@ BOOLEAN CcPinRead(IN PFILE_OBJECT FileObject,
 {
 CaptiveSharedCacheMapObject *SharedCacheMap;
 CaptivePrivateBcbPinObject *captive_private_bcb_pin_object;
+BOOLEAN r;
+
+       g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"enter: CcPinRead: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX,Flags=0x%lX",
+                       (long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length,Flags);
 
        g_return_val_if_fail(FileObject!=NULL,FALSE);
        g_return_val_if_fail(FileOffset!=NULL,FALSE);
        g_return_val_if_fail(FileOffset->QuadPart>=0,FALSE);
        g_return_val_if_fail(Length>0,FALSE);   /* FIXME: not handled below; 0 should be allowed */
-       g_return_val_if_fail(Flags==PIN_WAIT,FALSE);    /* FIXME */
+       g_return_val_if_fail((Flags&~PIN_IF_BCB)==PIN_WAIT,FALSE);      /* FIXME */
        g_return_val_if_fail(Bcb!=NULL,FALSE);
        g_return_val_if_fail(Buffer!=NULL,FALSE);
 
-       g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"%s: FileObject=%p,FileOffset=0x%llX,Length=0x%lX,Flags=0x%lX",G_STRLOC,
-                       FileObject,(guint64)FileOffset->QuadPart,(gulong)Length,(gulong)Flags);
-
        g_assert(Length<=PAGE_SIZE);
        /* Check PAGE_SIZE crossing */
        g_assert((FileOffset->QuadPart&~(PAGE_SIZE-1))==((FileOffset->QuadPart+Length-1)&~(PAGE_SIZE-1)));
 
        SharedCacheMap=captive_FileObject_to_SharedCacheMap(FileObject);
-       captive_private_bcb_pin_object=captive_private_bcb_pin_object_get_ref(SharedCacheMap,FileOffset->QuadPart);
-
-       captive_shared_cache_map_data_validate_read(SharedCacheMap,FileObject,FileOffset->QuadPart,FileOffset->QuadPart+Length);
 
-       *Bcb=captive_private_bcb_object_get_PublicBcb(CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_pin_object));
+       if (Flags&PIN_IF_BCB) {
+               if ((captive_private_bcb_pin_object=captive_private_bcb_pin_object_get(SharedCacheMap,
+                               CAPTIVE_ROUND_DOWN64(FileOffset->QuadPart,PAGE_SIZE))))
+                       g_object_ref(captive_private_bcb_pin_object);
+               }
+       else {
+               /* Invalide possibly only 'map'ped data as we need to re-read them on CcPinRead().
+                * Otherwise any file written by fastfat.sys of NT-5.1sp1 will corrupt
+                * the code+55AA of DOS boot sector (disk offset 0x0).
+                */
+               captive_private_bcb_pin_object=captive_private_bcb_pin_object_get_ref(SharedCacheMap,
+                               CAPTIVE_ROUND_DOWN64(FileOffset->QuadPart,PAGE_SIZE),
+                               TRUE);  /* invalidate_new */
+               }
+
+       if (captive_private_bcb_pin_object) {
+               captive_shared_cache_map_data_validate_read(SharedCacheMap,FileObject,FileOffset->QuadPart,FileOffset->QuadPart+Length);
+
+               *Bcb=captive_private_bcb_object_get_PublicBcb(CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_pin_object));
+               }
        *Buffer=captive_shared_cache_map_get_buffer(SharedCacheMap)+FileOffset->QuadPart;
+       r=!!captive_private_bcb_pin_object;
+
+       g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"leave: CcPinRead: r=%d,Bcb=0x%lX,Buffer=0x%lX",
+                       r,(!Bcb ? -1 : (long)*Bcb),(!Buffer ? -1 : (long)*Buffer));
 
-       return TRUE;
+       return r;
 }
 
 
@@ -178,6 +208,9 @@ VOID CcSetDirtyPinnedData(IN PVOID Bcb,IN PLARGE_INTEGER Lsn OPTIONAL)
 {
 CaptivePrivateBcbPinObject *captive_private_bcb_pin_object;
 
+       g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"enter: CcSetDirtyPinnedData: BcbVoid=0x%lX,Lsn=0x%lX",
+                       (long)Bcb,(!Lsn ? -1 : (long)Lsn->QuadPart));
+
        g_return_if_fail(Bcb!=NULL);
 
        captive_private_bcb_pin_object=CAPTIVE_PRIVATE_BCB_PIN_OBJECT(captive_PublicBcb_to_PrivateBcbObject(Bcb));
@@ -185,6 +218,8 @@ CaptivePrivateBcbPinObject *captive_private_bcb_pin_object;
        captive_private_bcb_pin_object_set_dirty(captive_private_bcb_pin_object);
        if (Lsn)
                captive_private_bcb_pin_object_set_lsn(captive_private_bcb_pin_object,Lsn->QuadPart);
+
+       g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"leave: CcSetDirtyPinnedData");
 }
 
 
@@ -222,6 +257,10 @@ BOOLEAN CcPreparePinWrite(IN PFILE_OBJECT FileObject,
 {
 CaptiveSharedCacheMapObject *SharedCacheMap;
 CaptivePrivateBcbPinObject *captive_private_bcb_pin_object;
+BOOLEAN r;
+
+       g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"enter: CcPreparePinWrite: FileObject=0x%lX,FileOffset=0x%lX,Length=0x%lX,Zero=%d,Flags=0x%lX",
+                       (long)FileObject,(!FileOffset ? -1 : (long)FileOffset->QuadPart),Length,Zero,Flags);
 
        g_return_val_if_fail(FileObject!=NULL,FALSE);
        g_return_val_if_fail(FileOffset!=NULL,FALSE);
@@ -235,7 +274,9 @@ CaptivePrivateBcbPinObject *captive_private_bcb_pin_object;
        g_assert(Length==PAGE_SIZE);    /* NOT YET IMPLEMENTED */
 
        SharedCacheMap=captive_FileObject_to_SharedCacheMap(FileObject);
-       captive_private_bcb_pin_object=captive_private_bcb_pin_object_get_ref(SharedCacheMap,FileOffset->QuadPart);
+       captive_private_bcb_pin_object=captive_private_bcb_pin_object_get_ref(SharedCacheMap,
+                       CAPTIVE_ROUND_DOWN64(FileOffset->QuadPart,PAGE_SIZE),
+                       FALSE); /* invalidate_new: FIXME: Is it compatible? */
 
        captive_shared_cache_map_set_data_valid(SharedCacheMap,FileOffset->QuadPart,FileOffset->QuadPart+Length);
        if (Zero)
@@ -244,6 +285,10 @@ CaptivePrivateBcbPinObject *captive_private_bcb_pin_object;
 
        *Bcb=captive_private_bcb_object_get_PublicBcb(CAPTIVE_PRIVATE_BCB_OBJECT(captive_private_bcb_pin_object));
        *Buffer=captive_shared_cache_map_get_buffer(SharedCacheMap)+FileOffset->QuadPart;
+       r=TRUE;
+
+       g_log(G_LOG_DOMAIN,G_LOG_LEVEL_DEBUG,"leave: CcPreparePinWrite: r=%d,Bcb=0x%lX,Buffer=0x%lX",
+                       r,(!Bcb ? -1 : (long)*Bcb),(!Buffer ? -1 : (long)*Buffer));
 
-       return TRUE;
+       return r;
 }