+captive_shared_cache_map_set_data_invalid()
[captive.git] / src / libcaptive / cc / sharedcachemap.c
index 298d47d..0224e3f 100644 (file)
@@ -74,9 +74,9 @@ CaptiveSharedCacheMapObject_page *page;
                captive_shared_cache_map_object->pin_hash=NULL;
                }
        g_assert(captive_shared_cache_map_object->map==NULL);
-       if (captive_shared_cache_map_object->SectionObjectPointers) {
-               g_assert(captive_shared_cache_map_object==captive_shared_cache_map_object->SectionObjectPointers->SharedCacheMap);
-               captive_shared_cache_map_object->SectionObjectPointers->SharedCacheMap=NULL;
+       if (captive_shared_cache_map_object->SectionObjectPointer) {
+               g_assert(captive_shared_cache_map_object==captive_shared_cache_map_object->SectionObjectPointer->SharedCacheMap);
+               captive_shared_cache_map_object->SectionObjectPointer->SharedCacheMap=NULL;
                }
 
        if (captive_shared_cache_map_object->FileObject) {
@@ -196,7 +196,8 @@ int errint;
                                        NULL,   /* start */
                                        PAGE_SIZE+size_new+PAGE_SIZE,   /* length; leading and trailing boundary check pages */
                                        PROT_READ|PROT_WRITE,   /* prot; read/write must be possible although write is not guaranteed to be flushed yet */
-                                       MAP_PRIVATE|MAP_ANONYMOUS,      /* flags */
+                                       MAP_PRIVATE|MAP_ANONYMOUS       /* flags */
+                                                       |MAP_NORESERVE, /* At least ext2fsd maps the whole disk. */
                                        -1,     /* fd; ignored due to MAP_ANONYMOUS */
                                        0);     /* offset; ignored due to MAP_ANONYMOUS */
                        if (base==MAP_FAILED)
@@ -265,11 +266,11 @@ CaptiveSharedCacheMapObject *captive_shared_cache_map_get_ref(FILE_OBJECT *FileO
 CaptiveSharedCacheMapObject *captive_shared_cache_map_object;
 
        g_return_val_if_fail(FileObject!=NULL,NULL);
-       g_return_val_if_fail(FileObject->SectionObjectPointers!=NULL,NULL);
+       g_return_val_if_fail(FileObject->SectionObjectPointer!=NULL,NULL);
        g_return_val_if_fail(FileSizes!=NULL,NULL);
        g_return_val_if_fail(CallBacks!=NULL,NULL);
 
-       if ((captive_shared_cache_map_object=FileObject->SectionObjectPointers->SharedCacheMap)) {
+       if ((captive_shared_cache_map_object=FileObject->SectionObjectPointer->SharedCacheMap)) {
                captive_shared_cache_map_w32_ref(captive_shared_cache_map_object);
                }
        else {
@@ -286,7 +287,7 @@ CaptiveSharedCacheMapObject *captive_shared_cache_map_object;
                /* W32 references twice. */
                ObReferenceObject(FileObject);
                captive_shared_cache_map_object->FileObject=FileObject;
-               captive_shared_cache_map_object->SectionObjectPointers=FileObject->SectionObjectPointers;
+               captive_shared_cache_map_object->SectionObjectPointer=FileObject->SectionObjectPointer;
                captive_shared_cache_map_object->AllocationSize=0;
                captive_shared_cache_map_object->FileSize=0;
                captive_shared_cache_map_object->ValidDataLength=0;
@@ -294,12 +295,12 @@ CaptiveSharedCacheMapObject *captive_shared_cache_map_object;
                captive_shared_cache_map_object->CallBacks=*CallBacks;
                captive_shared_cache_map_object->LazyWriterContext=LazyWriterContext;
 
-               FileObject->SectionObjectPointers->SharedCacheMap=captive_shared_cache_map_object;
+               FileObject->SectionObjectPointer->SharedCacheMap=captive_shared_cache_map_object;
                }
 
        g_assert(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
        /* FileObject may differ - we can have a different reference to the same FCB. */
-       g_assert(FileObject->SectionObjectPointers==captive_shared_cache_map_object->SectionObjectPointers);
+       g_assert(FileObject->SectionObjectPointer==captive_shared_cache_map_object->SectionObjectPointer);
        g_assert(PinAccess==captive_shared_cache_map_object->PinAccess);
        g_assert(CallBacks->AcquireForLazyWrite==captive_shared_cache_map_object->CallBacks.AcquireForLazyWrite);
        g_assert(CallBacks->ReleaseFromLazyWrite==captive_shared_cache_map_object->CallBacks.ReleaseFromLazyWrite);
@@ -371,7 +372,7 @@ CaptiveSharedCacheMapObject *captive_FileObject_to_SharedCacheMap(FILE_OBJECT *F
 {
        g_return_val_if_fail(FileObject!=NULL,NULL);
 
-       return captive_SectionObjectPointers_to_SharedCacheMap(FileObject->SectionObjectPointers);
+       return captive_SectionObjectPointers_to_SharedCacheMap(FileObject->SectionObjectPointer);
 }
 
 void captive_shared_cache_map_w32_ref(CaptiveSharedCacheMapObject *captive_shared_cache_map_object)
@@ -419,6 +420,7 @@ ULONG got;
                        g_assert(got<=PAGE_SIZE);
                after_eof=(got<PAGE_SIZE);
                captive_shared_cache_map_object->pages[now/PAGE_SIZE].data_valid=TRUE;
+               captive_shared_cache_map_object->pages[now/PAGE_SIZE].dirty=FALSE;
                }
 }
 
@@ -461,6 +463,24 @@ guint64 now;
 
        for (now=start;now<end;now+=PAGE_SIZE) {
                captive_shared_cache_map_object->pages[now/PAGE_SIZE].data_valid=TRUE;
+               /* .dirty is undefined */
+               }
+}
+
+void captive_shared_cache_map_set_data_invalid(CaptiveSharedCacheMapObject *captive_shared_cache_map_object,
+               guint64 start,guint64 end)
+{
+guint64 now;
+
+       g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
+       g_return_if_fail(start<=end);
+       g_return_if_fail(end<=CAPTIVE_ROUND_UP64(captive_shared_cache_map_object->AllocationSize,PAGE_SIZE));
+
+       start=CAPTIVE_ROUND_DOWN64(start,PAGE_SIZE);
+       end=CAPTIVE_ROUND_UP64(end,PAGE_SIZE);
+
+       for (now=start;now<end;now+=PAGE_SIZE) {
+               captive_shared_cache_map_object->pages[now/PAGE_SIZE].data_valid=FALSE;
                }
 }
 
@@ -531,11 +551,18 @@ CaptiveSharedCacheMapObject_page *page;
 
        g_signal_emit(captive_shared_cache_map_object,purge_signal,0);
 
+       /* Needed by fastfat.sys of NT-5.1sp1 during FAT32 unmount
+        * otherwise it fails on: g_assert(!page->dirty);
+        * It corrupts the disk if the buffer is dropped instead.
+        */
+       captive_shared_cache_map_flush(captive_shared_cache_map_object,
+                       0,CAPTIVE_ROUND_UP64(captive_shared_cache_map_object->AllocationSize,PAGE_SIZE));
+
        for (offset=0;offset<CAPTIVE_ROUND_UP64(captive_shared_cache_map_object->AllocationSize,PAGE_SIZE);offset+=PAGE_SIZE) {
                page=captive_shared_cache_map_object->pages+offset/PAGE_SIZE;
                if (!page->data_valid)
                        continue;
-               g_assert(!page->dirty); /* FIXME: Is it allowed by W32? */
+               g_assert(!page->dirty);
                page->data_valid=FALSE;
                }
 }
@@ -590,14 +617,14 @@ CaptiveSharedCacheMapObject_page *page;
        g_return_if_fail(page->dirty);
 
        if (page->lsn_newest) {
-LARGE_INTEGER lsn_newest_LargeInteger;
-
                /* sanity check */
                g_assert(!lsn_last || lsn_last<=page->lsn_newest);
                lsn_last=page->lsn_newest;
 
-               lsn_newest_LargeInteger.QuadPart=page->lsn_newest;
-               (*captive_FlushToLsnRoutine)(captive_LogHandle,lsn_newest_LargeInteger);
+               captive_stdcall_call_12((CaptiveStdCallFunc12)captive_FlushToLsnRoutine,
+                               captive_LogHandle,
+                               (gpointer)(guint32)(page->lsn_newest>> 0U),     /* 'LARGE_INTEGER' argument */
+                               (gpointer)(guint32)(page->lsn_newest>>32U));
                }
 
        offset_LargeInteger.QuadPart=offset;