This commit was manufactured by cvs2svn to create branch 'captive'.
[captive.git] / src / libcaptive / cc / sharedcachemap.c
diff --git a/src/libcaptive/cc/sharedcachemap.c b/src/libcaptive/cc/sharedcachemap.c
deleted file mode 100644 (file)
index c8ecba4..0000000
+++ /dev/null
@@ -1,837 +0,0 @@
-/* $Id$
- * reactos Cache Manager (Cc*) SharedCacheMap structure of libcaptive
- * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
- * 
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; exactly version 2 of June 1991 is required
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "config.h"
-
-#include "sharedcachemap.h"    /* self */
-#include "sharedcachemap-priv.h"       /* self */
-#include "io.h"
-#include "marshallers.h"
-#include <glib-object.h>
-#include "privatebcbpin.h"
-#include "captive/macros.h"
-#include <sys/mman.h>
-#include "reactos/ddk/obfuncs.h"
-
-
-static GHashTable *CaptiveSharedCacheMapObject_hash;
-
-static void CaptiveSharedCacheMapObject_hash_init(void)
-{
-       if (CaptiveSharedCacheMapObject_hash)
-               return;
-       CaptiveSharedCacheMapObject_hash=g_hash_table_new(
-                       g_direct_hash,  /* hash_func */
-                       g_direct_equal);        /* key_equal_func */
-}
-
-
-static gpointer captive_shared_cache_map_object_parent_class=NULL;
-
-
-static void captive_shared_cache_map_object_finalize(CaptiveSharedCacheMapObject *captive_shared_cache_map_object)
-{
-static const CC_FILE_SIZES FileSizes_zero;
-gboolean errbool;
-guint64 offset;
-CaptiveSharedCacheMapObject_page *page;
-
-       g_return_if_fail(captive_shared_cache_map_object!=NULL);
-
-       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? */
-               }
-
-       CaptiveSharedCacheMapObject_hash_init();
-       errbool=g_hash_table_remove(CaptiveSharedCacheMapObject_hash,captive_shared_cache_map_object);
-       g_assert(errbool==TRUE);
-
-       captive_shared_cache_map_FileSizes_set(captive_shared_cache_map_object,&FileSizes_zero);
-       g_assert(captive_shared_cache_map_object->buffer==NULL);
-       g_assert(captive_shared_cache_map_object->pages==NULL);
-
-       if (captive_shared_cache_map_object->pin_hash) {
-               captive_private_bcb_pin_object_hash_destroy(captive_shared_cache_map_object->pin_hash);
-               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->FileObject) {
-               /* W32 dereferences twice. */
-               ObDereferenceObject(captive_shared_cache_map_object->FileObject);
-               captive_shared_cache_map_object->FileObject=NULL;
-               }
-
-       G_OBJECT_CLASS(captive_shared_cache_map_object_parent_class)->finalize((GObject *)captive_shared_cache_map_object);
-}
-
-static guint FileSizes_changed_signal;
-static guint purge_signal;
-
-static void captive_shared_cache_map_object_FileSizes_changed(CaptiveSharedCacheMapObject *captive_shared_cache_map_object,
-               guint64 AllocationSize,guint64 FileSize,guint64 ValidDataLength);
-static void captive_shared_cache_map_object_purge(CaptiveSharedCacheMapObject *captive_shared_cache_map_object);
-
-static void captive_shared_cache_map_object_class_init(CaptiveSharedCacheMapObjectClass *class)
-{
-GObjectClass *gobject_class=G_OBJECT_CLASS(class);
-
-       captive_shared_cache_map_object_parent_class=g_type_class_ref(G_TYPE_OBJECT);
-       gobject_class->finalize=(void (*)(GObject *object))captive_shared_cache_map_object_finalize;
-
-       class->FileSizes_changed=captive_shared_cache_map_object_FileSizes_changed;
-       class->purge=captive_shared_cache_map_object_purge;
-
-       FileSizes_changed_signal=g_signal_new("FileSizes_changed",
-                       G_TYPE_FROM_CLASS(gobject_class),
-                       G_SIGNAL_RUN_LAST,
-                       G_STRUCT_OFFSET(CaptiveSharedCacheMapObjectClass,FileSizes_changed),
-                       NULL,NULL,
-                       captive_cc_VOID__UINT64_UINT64_UINT64,
-                       G_TYPE_NONE,3,G_TYPE_UINT64,G_TYPE_UINT64,G_TYPE_UINT64);
-       purge_signal=g_signal_new("purge",
-                       G_TYPE_FROM_CLASS(gobject_class),
-                       G_SIGNAL_RUN_LAST,
-                       G_STRUCT_OFFSET(CaptiveSharedCacheMapObjectClass,purge),
-                       NULL,NULL,
-                       captive_cc_VOID__VOID,
-                       G_TYPE_NONE,0);
-}
-
-
-static void captive_shared_cache_map_object_init(CaptiveSharedCacheMapObject *captive_shared_cache_map_object)
-{
-       captive_shared_cache_map_object->pin_hash=captive_private_bcb_pin_object_hash_new();
-
-       captive_shared_cache_map_w32_ref(captive_shared_cache_map_object);
-       g_object_unref(captive_shared_cache_map_object);        /* ==sink */
-
-       CaptiveSharedCacheMapObject_hash_init();
-       g_hash_table_insert(CaptiveSharedCacheMapObject_hash,
-                       captive_shared_cache_map_object,captive_shared_cache_map_object);
-}
-
-
-GType captive_shared_cache_map_object_get_type(void)
-{
-static GType captive_shared_cache_map_object_type=0;
-
-       if (!captive_shared_cache_map_object_type) {
-static const GTypeInfo captive_shared_cache_map_object_info={
-                               sizeof(CaptiveSharedCacheMapObjectClass),
-                               NULL,   /* base_init */
-                               NULL,   /* base_finalize */
-                               (GClassInitFunc)captive_shared_cache_map_object_class_init,
-                               NULL,   /* class_finalize */
-                               NULL,   /* class_data */
-                               sizeof(CaptiveSharedCacheMapObject),
-                               5,      /* n_preallocs */
-                               (GInstanceInitFunc)captive_shared_cache_map_object_init,
-                               };
-
-               captive_shared_cache_map_object_type=g_type_register_static(G_TYPE_OBJECT,
-                               "CaptiveSharedCacheMapObject",&captive_shared_cache_map_object_info,0);
-               }
-
-       return captive_shared_cache_map_object_type;
-}
-
-static void captive_shared_cache_map_object_FileSizes_changed(CaptiveSharedCacheMapObject *captive_shared_cache_map_object,
-               guint64 AllocationSize,guint64 FileSize,guint64 ValidDataLength)
-{
-size_t size_old,size_new;
-guint64 size64_old,size64_new;
-
-       g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
-
-       g_assert((!captive_shared_cache_map_object->buffer)==(!captive_shared_cache_map_object->AllocationSize));
-       g_assert((!captive_shared_cache_map_object->pages)==(!captive_shared_cache_map_object->AllocationSize));
-
-       size64_old=CAPTIVE_ROUND_UP64(captive_shared_cache_map_object->AllocationSize,PAGE_SIZE);       
-       size_old=size64_old;
-       g_assert(size_old==size64_old);
-       size64_new=CAPTIVE_ROUND_UP64(AllocationSize,PAGE_SIZE);        
-       size_new=size64_new;
-       g_assert(size_new==size64_new);
-
-       if (size_old!=size_new) {
-gpointer buffer_new;
-
-               /* These two assertions should be already catched by pin/map signal handlers. */
-               g_assert(!captive_shared_cache_map_object->map);
-               g_assert(!g_hash_table_size(captive_shared_cache_map_object->pin_hash));
-
-               if (AllocationSize) {
-gpointer base;
-int errint;
-
-                       base=mmap(
-                                       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 */
-                                       -1,     /* fd; ignored due to MAP_ANONYMOUS */
-                                       0);     /* offset; ignored due to MAP_ANONYMOUS */
-                       g_assert(base!=NULL);
-
-                       base+=PAGE_SIZE;
-                       errint=munmap(base-PAGE_SIZE,PAGE_SIZE);        /* unmap leading boundary check page */
-                       g_assert(errint==0);
-                       errint=munmap(base+size_new,PAGE_SIZE); /* unmap trailing boundary check page */
-                       g_assert(errint==0);
-
-                       buffer_new=base;
-                       }
-               else
-                       buffer_new=NULL;
-
-               memcpy(buffer_new,captive_shared_cache_map_object->buffer,
-                               MIN(AllocationSize,captive_shared_cache_map_object->AllocationSize));
-
-               if (captive_shared_cache_map_object->AllocationSize) {
-int errint;
-
-                       errint=munmap(captive_shared_cache_map_object->buffer,size_old);
-                       g_assert(errint==0);
-                       }
-
-               captive_shared_cache_map_object->buffer=buffer_new;
-
-#if 0  /* It appears it is valid to squeeze out 'dirty' blocks. FIXME: Flush them? */
-               if (size_old>size_new) {
-guint64 now;
-
-                       for (now=size_new;now<size_old;now+=PAGE_SIZE) {
-                               if (!captive_shared_cache_map_object->pages[now/PAGE_SIZE].data_valid)
-                                       continue;
-                               g_assert(!captive_shared_cache_map_object->pages[now/PAGE_SIZE].dirty);
-                               }
-                       }
-#endif
-               captive_shared_cache_map_object->pages=g_realloc(captive_shared_cache_map_object->pages,
-                               size_new/PAGE_SIZE*sizeof(*captive_shared_cache_map_object->pages));
-               if (size_new>size_old)  /* prevent 'size_new-size_old' as it is unsigned! */
-                       memset(captive_shared_cache_map_object->pages+(size_old/PAGE_SIZE),0,
-                                       (size_new-size_old)/PAGE_SIZE*sizeof(*captive_shared_cache_map_object->pages));
-               }
-
-       captive_shared_cache_map_object->AllocationSize=AllocationSize;
-       captive_shared_cache_map_object->FileSize=FileSize;
-       captive_shared_cache_map_object->ValidDataLength=ValidDataLength;
-
-       g_assert((!captive_shared_cache_map_object->buffer)==(!captive_shared_cache_map_object->AllocationSize));
-       g_assert((!captive_shared_cache_map_object->pages)==(!captive_shared_cache_map_object->AllocationSize));
-}
-
-static void captive_shared_cache_map_object_purge(CaptiveSharedCacheMapObject *captive_shared_cache_map_object)
-{
-       g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
-
-       /* NOP; just to provide slot for checking by Bcbs */
-}
-
-CaptiveSharedCacheMapObject *captive_shared_cache_map_get_ref(FILE_OBJECT *FileObject,
-               const CC_FILE_SIZES *FileSizes,BOOLEAN PinAccess,CACHE_MANAGER_CALLBACKS *CallBacks,VOID *LazyWriterContext)
-{
-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(FileSizes!=NULL,NULL);
-       g_return_val_if_fail(CallBacks!=NULL,NULL);
-
-       if ((captive_shared_cache_map_object=FileObject->SectionObjectPointers->SharedCacheMap)) {
-               captive_shared_cache_map_w32_ref(captive_shared_cache_map_object);
-               }
-       else {
-               captive_shared_cache_map_object=g_object_new(
-                               CAPTIVE_SHARED_CACHE_MAP_TYPE_OBJECT,   /* object_type */
-                               NULL);  /* first_property_name; FIXME: support properties */
-
-               /* 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->AllocationSize=0;
-               captive_shared_cache_map_object->FileSize=0;
-               captive_shared_cache_map_object->ValidDataLength=0;
-               captive_shared_cache_map_object->PinAccess=PinAccess;
-               captive_shared_cache_map_object->CallBacks=*CallBacks;
-               captive_shared_cache_map_object->LazyWriterContext=LazyWriterContext;
-
-               FileObject->SectionObjectPointers->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(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);
-       g_assert(CallBacks->AcquireForReadAhead==captive_shared_cache_map_object->CallBacks.AcquireForReadAhead);
-       g_assert(CallBacks->ReleaseFromReadAhead==captive_shared_cache_map_object->CallBacks.ReleaseFromReadAhead);
-       g_assert(LazyWriterContext==captive_shared_cache_map_object->LazyWriterContext);
-
-       captive_shared_cache_map_FileSizes_set(captive_shared_cache_map_object,FileSizes);
-
-       return captive_shared_cache_map_object;
-}
-
-void captive_shared_cache_map_FileSizes_set(CaptiveSharedCacheMapObject *captive_shared_cache_map_object,
-               const CC_FILE_SIZES *FileSizes)
-{
-guint64 AllocationSize,FileSize,ValidDataLength;
-
-       g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
-       g_return_if_fail(FileSizes!=NULL);
-
-       AllocationSize=FileSizes->AllocationSize.QuadPart;
-       FileSize=FileSizes->FileSize.QuadPart;
-       ValidDataLength=FileSizes->ValidDataLength.QuadPart;
-
-       if (ValidDataLength==G_MAXINT64)
-               ValidDataLength=FileSize;
-
-       g_assert(AllocationSize>=0);
-       g_assert(FileSize>=0);
-       g_assert(ValidDataLength>=0);
-
-       g_assert(ValidDataLength<=FileSize);
-       /* Do not: g_assert(0==(AllocationSize%0x200));
-        * as it is true for ntfs.sys of NT-5.1sp1 but it fails for fastfat.sys of NT-5.1sp1.
-        */
-       /* AllocationSize can be much higher: */
-       g_assert(FileSize<=AllocationSize);
-
-       /* Prevent signalling if not needed as signal is forbidden in captive_shared_cache_map_object_finalize() */
-       if (0
-                       || captive_shared_cache_map_object->AllocationSize!=AllocationSize
-                       || captive_shared_cache_map_object->FileSize!=FileSize
-                       || captive_shared_cache_map_object->ValidDataLength!=ValidDataLength)
-               g_signal_emit(captive_shared_cache_map_object,FileSizes_changed_signal,0,
-                               AllocationSize,FileSize,ValidDataLength);
-
-       g_assert(captive_shared_cache_map_object->AllocationSize==AllocationSize);
-       g_assert(captive_shared_cache_map_object->FileSize==FileSize);
-       g_assert(captive_shared_cache_map_object->ValidDataLength==ValidDataLength);
-}
-
-CaptiveSharedCacheMapObject *captive_SectionObjectPointers_to_SharedCacheMap(SECTION_OBJECT_POINTERS *SectionObjectPointers)
-{
-       g_return_val_if_fail(SectionObjectPointers!=NULL,NULL);
-       g_return_val_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(SectionObjectPointers->SharedCacheMap),NULL);
-
-       return SectionObjectPointers->SharedCacheMap;
-}
-
-CaptiveSharedCacheMapObject *captive_FileObject_to_SharedCacheMap(FILE_OBJECT *FileObject)
-{
-       g_return_val_if_fail(FileObject!=NULL,NULL);
-
-       return captive_SectionObjectPointers_to_SharedCacheMap(FileObject->SectionObjectPointers);
-}
-
-void captive_shared_cache_map_w32_ref(CaptiveSharedCacheMapObject *captive_shared_cache_map_object)
-{
-       g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
-
-       g_object_ref(captive_shared_cache_map_object);
-       captive_shared_cache_map_object->w32_ref_count++;
-}
-
-void captive_shared_cache_map_w32_unref(CaptiveSharedCacheMapObject *captive_shared_cache_map_object)
-{
-       g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
-       g_return_if_fail(G_OBJECT(captive_shared_cache_map_object)->ref_count>0);
-
-       if (captive_shared_cache_map_object->w32_ref_count==1) {
-static const CC_FILE_SIZES FileSizes_zero;
-
-               g_assert(G_OBJECT(captive_shared_cache_map_object)->ref_count==1);
-
-               /* Prevent such truncation in captive_shared_cache_map_object_finalize()
-                * as it would do forbidden g_object_ref() there.
-                */
-               captive_shared_cache_map_FileSizes_set(captive_shared_cache_map_object,&FileSizes_zero);
-               g_assert(captive_shared_cache_map_object->buffer==NULL);
-               g_assert(captive_shared_cache_map_object->pages==NULL);
-               }
-
-       captive_shared_cache_map_object->w32_ref_count--;
-       g_object_unref(captive_shared_cache_map_object);
-}
-
-void captive_shared_cache_map_data_validate_read(CaptiveSharedCacheMapObject *captive_shared_cache_map_object,
-               FILE_OBJECT *FileObject,guint64 start,guint64 end)
-{
-guint64 now;
-gboolean after_eof=FALSE;      /* Did we reached the end of file already? */
-
-       g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
-       g_return_if_fail(captive_shared_cache_map_object==captive_FileObject_to_SharedCacheMap(FileObject));
-       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) {
-LARGE_INTEGER now_LargeInteger;
-ULONG got;
-
-               if (captive_shared_cache_map_object->pages[now/PAGE_SIZE].data_valid)
-                       continue;
-               now_LargeInteger.QuadPart=now;
-               got=captive_Cc_IoPageRead(FileObject,captive_shared_cache_map_object->buffer+now,PAGE_SIZE,&now_LargeInteger);
-               if (after_eof)
-                       g_assert(got==0);
-               else
-                       g_assert(got<=PAGE_SIZE);
-               after_eof=(got<PAGE_SIZE);
-               captive_shared_cache_map_object->pages[now/PAGE_SIZE].data_valid=TRUE;
-               }
-}
-
-void captive_shared_cache_map_data_validate_noread(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) {
-               g_assert(captive_shared_cache_map_object->pages[now/PAGE_SIZE].data_valid);
-               }
-}
-
-void captive_shared_cache_map_set_data_valid(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_UP64(start,PAGE_SIZE);
-       end=CAPTIVE_ROUND_DOWN64(end,PAGE_SIZE);
-       /* We may get end<start here - it is valid to not to validate anything. */
-
-       for (now=start;now<end;now+=PAGE_SIZE) {
-               captive_shared_cache_map_object->pages[now/PAGE_SIZE].data_valid=TRUE;
-               }
-}
-
-void captive_shared_cache_map_set_dirty(CaptiveSharedCacheMapObject *captive_shared_cache_map_object,
-               guint64 start,guint64 end)
-{
-guint64 now;
-CaptiveSharedCacheMapObject_page *page;
-
-       g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
-       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) {
-               page=captive_shared_cache_map_object->pages+now/PAGE_SIZE;
-               g_assert(page->data_valid);
-               if (!page->dirty) {
-                       page->dirty=TRUE;
-                       page->lsn_oldest=0;
-                       page->lsn_newest=0;
-                       }
-               }
-}
-
-gboolean captive_shared_cache_map_is_page_dirty(CaptiveSharedCacheMapObject *captive_shared_cache_map_object,
-               guint64 offset)
-{
-CaptiveSharedCacheMapObject_page *page;
-
-       g_return_val_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object),FALSE);
-       g_return_val_if_fail(offset<CAPTIVE_ROUND_UP64(captive_shared_cache_map_object->AllocationSize,PAGE_SIZE),FALSE);
-       g_return_val_if_fail(0==CAPTIVE_ROUND_DOWN_EXCEEDING64(offset,PAGE_SIZE),FALSE);
-       page=captive_shared_cache_map_object->pages+offset/PAGE_SIZE;
-       g_return_val_if_fail(page->data_valid,FALSE);
-
-       return page->dirty;
-}
-
-void captive_shared_cache_map_page_set_lsn(CaptiveSharedCacheMapObject *captive_shared_cache_map_object,
-               guint64 offset,gint64 lsn)
-{
-CaptiveSharedCacheMapObject_page *page;
-
-       g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
-       g_return_if_fail(offset<=CAPTIVE_ROUND_UP64(captive_shared_cache_map_object->AllocationSize,PAGE_SIZE));
-       g_return_if_fail(0==CAPTIVE_ROUND_DOWN_EXCEEDING64(offset,PAGE_SIZE));
-       page=captive_shared_cache_map_object->pages+offset/PAGE_SIZE;
-       g_return_if_fail(page->data_valid);
-       g_return_if_fail(page->dirty);
-       g_return_if_fail(page->lsn_oldest<=page->lsn_newest);
-       g_return_if_fail(!page->lsn_newest || lsn>=page->lsn_newest);
-       g_return_if_fail(captive_shared_cache_map_object->LogHandle_set);
-       g_return_if_fail(captive_shared_cache_map_object->FlushToLsnRoutine_set);
-
-       if (!page->lsn_oldest)
-               page->lsn_oldest=lsn;
-       page->lsn_newest=lsn;
-}
-
-void captive_shared_cache_map_purge(CaptiveSharedCacheMapObject *captive_shared_cache_map_object)
-{
-guint64 offset;
-CaptiveSharedCacheMapObject_page *page;
-
-       g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
-
-       g_signal_emit(captive_shared_cache_map_object,purge_signal,0);
-
-       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? */
-               page->data_valid=FALSE;
-               }
-}
-
-static VOID *captive_LogHandle;
-static PFLUSH_TO_LSN captive_FlushToLsnRoutine;
-
-void captive_shared_cache_map_set_LogHandle(CaptiveSharedCacheMapObject *captive_shared_cache_map_object,VOID *LogHandle)
-{
-       g_return_if_fail(!captive_shared_cache_map_object || CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
-       /* FIXME: 'captive_shared_cache_map_object->LogHandle_set' may be set.
-        * Does it mean 'LogHandle_set' is 'FileObject'-based instead of 'SharedCacheMap'-based?
-        */
-
-       if (!LogHandle)
-               return;
-       g_assert(!captive_LogHandle || captive_LogHandle==LogHandle);
-       captive_LogHandle=LogHandle;
-       if (LogHandle && captive_shared_cache_map_object)
-               captive_shared_cache_map_object->LogHandle_set=TRUE;
-}
-
-void captive_shared_cache_map_set_FlushToLsnRoutine
-               (CaptiveSharedCacheMapObject *captive_shared_cache_map_object,PFLUSH_TO_LSN FlushToLsnRoutine)
-{
-       g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
-       /* FIXME: 'captive_shared_cache_map_object->FlushToLsnRoutine_set' may be set.
-        * Does it mean 'FlushToLsnRoutine_set' is 'FileObject'-based instead of 'SharedCacheMap'-based?
-        */
-
-       if (!FlushToLsnRoutine)
-               return;
-       g_assert(!captive_FlushToLsnRoutine || captive_FlushToLsnRoutine==FlushToLsnRoutine);
-       captive_FlushToLsnRoutine=FlushToLsnRoutine;
-       if (FlushToLsnRoutine)
-               captive_shared_cache_map_object->FlushToLsnRoutine_set=TRUE;
-}
-
-static void captive_shared_cache_map_page_write(CaptiveSharedCacheMapObject *captive_shared_cache_map_object,
-               guint64 offset)
-{
-LARGE_INTEGER offset_LargeInteger;
-static gint64 lsn_last;
-CaptiveSharedCacheMapObject_page *page;
-
-       g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
-       g_return_if_fail(captive_shared_cache_map_object->FileObject!=NULL);
-       g_return_if_fail(offset<=CAPTIVE_ROUND_UP64(captive_shared_cache_map_object->AllocationSize,PAGE_SIZE));
-       g_return_if_fail(0==CAPTIVE_ROUND_DOWN_EXCEEDING64(offset,PAGE_SIZE));
-       page=captive_shared_cache_map_object->pages+offset/PAGE_SIZE;
-       g_return_if_fail(page->data_valid);
-       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);
-               }
-
-       offset_LargeInteger.QuadPart=offset;
-       captive_Cc_IoPageWrite(captive_shared_cache_map_object->FileObject,
-                       captive_shared_cache_map_object->buffer+offset,PAGE_SIZE,&offset_LargeInteger);
-
-       page->dirty=FALSE;
-       page->lsn_oldest=0;
-       page->lsn_newest=0;
-}
-
-typedef struct _captive_shared_cache_map_page_write_lsn_foreach_param captive_shared_cache_map_page_write_lsn_foreach_param;
-struct _captive_shared_cache_map_page_write_lsn_foreach_param {
-       gint64 lsn_target;
-       gint64 lsn_best;
-       CaptiveSharedCacheMapObject *captive_shared_cache_map_object_best;
-       guint64 offset_best;
-       };
-
-static void captive_shared_cache_map_page_write_lsn_foreach(
-               CaptiveSharedCacheMapObject *captive_shared_cache_map_object,  /* key */
-               CaptiveSharedCacheMapObject *captive_shared_cache_map_object_value,  /* value */
-               captive_shared_cache_map_page_write_lsn_foreach_param *param)   /* user_data */
-{
-guint64 now;
-CaptiveSharedCacheMapObject_page *page;
-
-       g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
-       g_return_if_fail(captive_shared_cache_map_object==captive_shared_cache_map_object_value);
-       g_return_if_fail(param!=NULL);
-
-       for (now=0;now<captive_shared_cache_map_object->AllocationSize;now+=PAGE_SIZE) {
-               page=captive_shared_cache_map_object->pages+now/PAGE_SIZE;
-               if (!page->data_valid)
-                       continue;
-               if (!page->dirty)
-                       continue;
-               if (!page->lsn_newest)
-                       continue;
-               if (page->lsn_newest>=param->lsn_target)
-                       continue;
-               if (param->lsn_best && page->lsn_newest>param->lsn_best)
-                       continue;
-               param->lsn_best=page->lsn_newest;
-               param->captive_shared_cache_map_object_best=captive_shared_cache_map_object;
-               param->offset_best=now;
-               }
-}
-
-static void captive_shared_cache_map_page_write_lsn(CaptiveSharedCacheMapObject *captive_shared_cache_map_object,
-               guint64 offset)
-{
-CaptiveSharedCacheMapObject_page *page;
-
-       g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
-       g_return_if_fail(captive_shared_cache_map_object->FileObject!=NULL);
-       g_return_if_fail(offset<CAPTIVE_ROUND_UP64(captive_shared_cache_map_object->AllocationSize,PAGE_SIZE));
-       g_return_if_fail(0==CAPTIVE_ROUND_DOWN_EXCEEDING64(offset,PAGE_SIZE));
-       page=captive_shared_cache_map_object->pages+offset/PAGE_SIZE;
-       g_return_if_fail(page->data_valid);
-       g_return_if_fail(page->dirty);
-
-       if (page->lsn_newest) {
-               CaptiveSharedCacheMapObject_hash_init();
-               for (;;) {
-captive_shared_cache_map_page_write_lsn_foreach_param param;
-
-                       param.lsn_target=page->lsn_newest;
-                       param.lsn_best=0;
-                       g_hash_table_foreach(
-                                       CaptiveSharedCacheMapObject_hash,       /* hash_table */
-                                       (GHFunc)captive_shared_cache_map_page_write_lsn_foreach,        /* func */
-                                       &param);        /* user_data */
-                       if (!param.lsn_best)
-                               break;
-                       captive_shared_cache_map_page_write(param.captive_shared_cache_map_object_best,param.offset_best);
-                       }
-               }
-
-       captive_shared_cache_map_page_write(captive_shared_cache_map_object,offset);
-}
-
-guint64 captive_shared_cache_map_flush(CaptiveSharedCacheMapObject *captive_shared_cache_map_object,
-               guint64 start,guint64 end)
-{
-guint64 flushed;
-guint64 now;
-
-       g_return_val_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object),0);
-       g_return_val_if_fail(start<=end,0);
-
-       end=MIN(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);
-
-       flushed=0;
-       for (now=start;now<end;now+=PAGE_SIZE) {
-               if (!captive_shared_cache_map_object->pages[now/PAGE_SIZE].data_valid)
-                       continue;
-               if (!captive_shared_cache_map_object->pages[now/PAGE_SIZE].dirty)
-                       continue;
-               captive_shared_cache_map_page_write_lsn(captive_shared_cache_map_object,now);
-               flushed+=PAGE_SIZE;
-               }
-
-       /* We were calling W32 code - recheck our task completion. */
-       for (now=start;now<end;now+=PAGE_SIZE) {
-               if (!captive_shared_cache_map_object->pages[now/PAGE_SIZE].data_valid)
-                       continue;
-               g_assert(!captive_shared_cache_map_object->pages[now/PAGE_SIZE].dirty);
-               }
-
-       return flushed;
-}
-
-static void captive_shared_cache_map_is_any_dirty_foreach(
-               CaptiveSharedCacheMapObject *captive_shared_cache_map_object,  /* key */
-               CaptiveSharedCacheMapObject *captive_shared_cache_map_object_value,  /* value */
-               gboolean *dirty_foundp) /* user_data */
-{
-guint64 now;
-
-       g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
-       g_return_if_fail(captive_shared_cache_map_object==captive_shared_cache_map_object_value);
-       g_return_if_fail(dirty_foundp!=NULL);
-
-       for (now=0;now<captive_shared_cache_map_object->AllocationSize;now+=PAGE_SIZE) {
-               if (!captive_shared_cache_map_object->pages[now/PAGE_SIZE].data_valid)
-                       continue;
-               if (!captive_shared_cache_map_object->pages[now/PAGE_SIZE].dirty)
-                       continue;
-               *dirty_foundp=TRUE;     /* FIXME: stop the traversal. */
-               break;
-               }
-}
-
-
-gboolean captive_shared_cache_map_is_any_dirty(void)
-{
-gboolean dirty_found;
-
-       CaptiveSharedCacheMapObject_hash_init();
-       dirty_found=FALSE;
-       g_hash_table_foreach(
-                       CaptiveSharedCacheMapObject_hash,       /* hash_table */
-                       (GHFunc)captive_shared_cache_map_is_any_dirty_foreach,  /* func */
-                       &dirty_found);  /* user_data */
-
-       return dirty_found;
-}
-
-
-typedef struct _captive_shared_cache_map_CcGetDirtyPages_foreach_param captive_shared_cache_map_CcGetDirtyPages_foreach_param;
-struct _captive_shared_cache_map_CcGetDirtyPages_foreach_param {
-       PDIRTY_PAGE_ROUTINE DirtyPageRoutine;
-       VOID *Context1;
-       VOID *Context2;
-       gint64 result;
-       };
-
-static void captive_shared_cache_map_CcGetDirtyPages_foreach(
-               CaptiveSharedCacheMapObject *captive_shared_cache_map_object,  /* key */
-               CaptiveSharedCacheMapObject *captive_shared_cache_map_object_value,  /* value */
-               captive_shared_cache_map_CcGetDirtyPages_foreach_param *param)  /* user_data */
-{
-gint64 now;
-CaptiveSharedCacheMapObject_page *page;
-
-       g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
-       g_return_if_fail(captive_shared_cache_map_object->FileObject!=NULL);
-       g_return_if_fail(captive_shared_cache_map_object==captive_shared_cache_map_object_value);
-       g_return_if_fail(param!=NULL);
-
-       for (now=CAPTIVE_ROUND_DOWN64(captive_shared_cache_map_object->AllocationSize-1,PAGE_SIZE);now>=0;now-=PAGE_SIZE) {
-LARGE_INTEGER now_LargeInteger,lsn_oldest_LargeInteger,lsn_newest_LargeInteger;
-
-               page=captive_shared_cache_map_object->pages+now/PAGE_SIZE;
-               if (!page->data_valid)
-                       continue;
-               if (!page->dirty)
-                       continue;
-               if (page->lsn_oldest && (!param->result || param->result>page->lsn_oldest))
-                       param->result=page->lsn_oldest;
-
-               now_LargeInteger.QuadPart=now;
-               lsn_oldest_LargeInteger.QuadPart=page->lsn_oldest;
-               lsn_newest_LargeInteger.QuadPart=page->lsn_newest;
-               (*param->DirtyPageRoutine)(
-                               captive_shared_cache_map_object->FileObject,    /* FileObject */
-                               &now_LargeInteger,      /* FileOffset */
-                               PAGE_SIZE,      /* Length */
-                               &lsn_oldest_LargeInteger,       /* OldestLsn */
-                               &lsn_newest_LargeInteger,       /* NewestLsn */
-                               param->Context1,        /* Context1 */
-                               param->Context2);       /* Context2 */
-               }
-}
-
-gint64 captive_shared_cache_map_CcGetDirtyPages(PDIRTY_PAGE_ROUTINE DirtyPageRoutine,VOID *Context1,VOID *Context2)
-{
-captive_shared_cache_map_CcGetDirtyPages_foreach_param param;
-
-       g_return_val_if_fail(DirtyPageRoutine!=NULL,0);
-
-       param.DirtyPageRoutine=DirtyPageRoutine;
-       param.Context1=Context1;
-       param.Context2=Context2;
-       param.result=0;
-
-       CaptiveSharedCacheMapObject_hash_init();
-       g_hash_table_foreach(
-                       CaptiveSharedCacheMapObject_hash,       /* hash_table */
-                       (GHFunc)captive_shared_cache_map_CcGetDirtyPages_foreach,       /* func */
-                       &param);        /* user_data */
-
-       return param.result;
-}
-
-gpointer captive_shared_cache_map_get_buffer(CaptiveSharedCacheMapObject *captive_shared_cache_map_object)
-{
-       g_return_val_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object),NULL);
-       g_return_val_if_fail(captive_shared_cache_map_object->buffer!=NULL,NULL);
-
-       return captive_shared_cache_map_object->buffer;
-}
-
-static void captive_cc_FileObject_delete_foreach(
-               CaptiveSharedCacheMapObject *captive_shared_cache_map_object,  /* key */
-               CaptiveSharedCacheMapObject *captive_shared_cache_map_object_value,  /* value */
-               FILE_OBJECT *FileObject)        /* user_data */
-{
-       g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
-       g_return_if_fail(captive_shared_cache_map_object==captive_shared_cache_map_object_value);
-       g_return_if_fail(FileObject!=NULL);
-
-       g_assert(FileObject!=captive_shared_cache_map_object->FileObject);
-}
-
-BOOLEAN captive_cc_FileObject_delete(FILE_OBJECT *FileObject)
-{
-       g_return_val_if_fail(FileObject!=NULL,FALSE);
-
-       CaptiveSharedCacheMapObject_hash_init();
-       g_hash_table_foreach(
-                       CaptiveSharedCacheMapObject_hash,       /* hash_table */
-                       (GHFunc)captive_cc_FileObject_delete_foreach,   /* func */
-                       FileObject);    /* user_data */
-
-       return FALSE;   /* FIXME: remove useless return code. */
-}