/******************************************************************************
 *
 * BigBlockFile
 *
 * This is the implementation of a file that consists of blocks of
 * a predetermined size.
 * This class is used in the Compound File implementation of the
 * IStorage and IStream interfaces. It provides the functionality
 * to read and write any blocks in the file as well as setting and
 * obtaining the size of the file.
 * The blocks are indexed sequentially from the start of the file
 * starting with -1.
 *
 * TODO:
 * - Support for a transacted mode
 *
 * Copyright 1999 Thuy Nguyen
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <assert.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winerror.h"
#include "objbase.h"
#include "ole2.h"

#include "storage32.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(storage);

/***********************************************************
 * Data structures used internally by the BigBlockFile
 * class.
 */

/* We map in PAGE_SIZE-sized chunks. Must be a multiple of 4096. */
#define PAGE_SIZE       131072

#define BLOCKS_PER_PAGE (PAGE_SIZE / BIG_BLOCK_SIZE)

/* We keep a list of recently-discarded pages. This controls the
 * size of that list. */
#define MAX_VICTIM_PAGES 16

/* This structure provides one bit for each block in a page.
 * Use BIGBLOCKFILE_{Test,Set,Clear}Bit to manipulate it. */
typedef struct
{
    unsigned int bits[BLOCKS_PER_PAGE / (CHAR_BIT * sizeof(unsigned int))];
} BlockBits;

/***
 * This structure identifies the paged that are mapped
 * from the file and their position in memory. It is
 * also used to hold a reference count to those pages.
 *
 * page_index identifies which PAGE_SIZE chunk from the
 * file this mapping represents. (The mappings are always
 * PAGE_SIZE-aligned.)
 */
struct MappedPage
{
    MappedPage *next;
    MappedPage *prev;

    DWORD  page_index;
    LPVOID lpBytes;
    LONG   refcnt;

    BlockBits readable_blocks;
    BlockBits writable_blocks;
};

/***********************************************************
 * Prototypes for private methods
 */
static void*     BIGBLOCKFILE_GetMappedView(LPBIGBLOCKFILE This,
                                            DWORD          page_index);
static void      BIGBLOCKFILE_ReleaseMappedPage(LPBIGBLOCKFILE This,
                                                MappedPage *page);
static void      BIGBLOCKFILE_FreeAllMappedPages(LPBIGBLOCKFILE This);
static void      BIGBLOCKFILE_UnmapAllMappedPages(LPBIGBLOCKFILE This);
static void      BIGBLOCKFILE_RemapAllMappedPages(LPBIGBLOCKFILE This);
static void*     BIGBLOCKFILE_GetBigBlockPointer(LPBIGBLOCKFILE This,
                                                 ULONG          index,
                                                 DWORD          desired_access);
static MappedPage* BIGBLOCKFILE_GetPageFromPointer(LPBIGBLOCKFILE This,
						   void*         pBlock);
static MappedPage* BIGBLOCKFILE_CreatePage(LPBIGBLOCKFILE This,
					   ULONG page_index);
static DWORD     BIGBLOCKFILE_GetProtectMode(DWORD openFlags);
static BOOL      BIGBLOCKFILE_FileInit(LPBIGBLOCKFILE This, HANDLE hFile);
static BOOL      BIGBLOCKFILE_MemInit(LPBIGBLOCKFILE This, ILockBytes* plkbyt);

/* Note that this evaluates a and b multiple times, so don't
 * pass expressions with side effects. */
#define ROUND_UP(a, b) ((((a) + (b) - 1)/(b))*(b))

/***********************************************************
 * Blockbits functions.
 */
static inline BOOL BIGBLOCKFILE_TestBit(const BlockBits *bb,
					unsigned int index)
{
    unsigned int array_index = index / (CHAR_BIT * sizeof(unsigned int));
    unsigned int bit_index = index % (CHAR_BIT * sizeof(unsigned int));

    return bb->bits[array_index] & (1 << bit_index);
}

static inline void BIGBLOCKFILE_SetBit(BlockBits *bb, unsigned int index)
{
    unsigned int array_index = index / (CHAR_BIT * sizeof(unsigned int));
    unsigned int bit_index = index % (CHAR_BIT * sizeof(unsigned int));

    bb->bits[array_index] |= (1 << bit_index);
}

static inline void BIGBLOCKFILE_ClearBit(BlockBits *bb, unsigned int index)
{
    unsigned int array_index = index / (CHAR_BIT * sizeof(unsigned int));
    unsigned int bit_index = index % (CHAR_BIT * sizeof(unsigned int));

    bb->bits[array_index] &= ~(1 << bit_index);
}

static inline void BIGBLOCKFILE_Zero(BlockBits *bb)
{
    memset(bb->bits, 0, sizeof(bb->bits));
}

/******************************************************************************
 *      BIGBLOCKFILE_Construct
 *
 * Construct a big block file. Create the file mapping object.
 * Create the read only mapped pages list, the writable mapped page list
 * and the blocks in use list.
 */
BigBlockFile * BIGBLOCKFILE_Construct(
  HANDLE   hFile,
  ILockBytes* pLkByt,
  DWORD    openFlags,
  ULONG    blocksize,
  BOOL     fileBased)
{
  LPBIGBLOCKFILE This;

  This = (LPBIGBLOCKFILE)HeapAlloc(GetProcessHeap(), 0, sizeof(BigBlockFile));

  if (This == NULL)
    return NULL;

  This->fileBased = fileBased;

  This->flProtect = BIGBLOCKFILE_GetProtectMode(openFlags);

  This->blocksize = blocksize;

  This->maplist = NULL;
  This->victimhead = NULL;
  This->victimtail = NULL;
  This->num_victim_pages = 0;

  if (This->fileBased)
  {
    if (!BIGBLOCKFILE_FileInit(This, hFile))
    {
      HeapFree(GetProcessHeap(), 0, This);
      return NULL;
    }
  }
  else
  {
    if (!BIGBLOCKFILE_MemInit(This, pLkByt))
    {
      HeapFree(GetProcessHeap(), 0, This);
      return NULL;
    }
  }

  return This;
}

/******************************************************************************
 *      BIGBLOCKFILE_FileInit
 *
 * Initialize a big block object supported by a file.
 */
static BOOL BIGBLOCKFILE_FileInit(LPBIGBLOCKFILE This, HANDLE hFile)
{
  This->pLkbyt     = NULL;
  This->hbytearray = 0;
  This->pbytearray = NULL;

  This->hfile = hFile;

  if (This->hfile == INVALID_HANDLE_VALUE)
    return FALSE;

  This->filesize.u.LowPart = GetFileSize(This->hfile,
					 &This->filesize.u.HighPart);

  if( This->filesize.u.LowPart || This->filesize.u.HighPart )
  {
    /* create the file mapping object
     */
    This->hfilemap = CreateFileMappingA(This->hfile,
                                        NULL,
                                        This->flProtect,
                                        0, 0,
                                        NULL);

    if (!This->hfilemap)
    {
      CloseHandle(This->hfile);
      return FALSE;
    }
  }
  else
    This->hfilemap = NULL;

  This->maplist = NULL;

  TRACE("file len %lu\n", This->filesize.u.LowPart);

  return TRUE;
}

/******************************************************************************
 *      BIGBLOCKFILE_MemInit
 *
 * Initialize a big block object supported by an ILockBytes on HGLOABL.
 */
static BOOL BIGBLOCKFILE_MemInit(LPBIGBLOCKFILE This, ILockBytes* plkbyt)
{
  This->hfile       = 0;
  This->hfilemap    = 0;

  /*
   * Retrieve the handle to the byte array from the LockByte object.
   */
  if (GetHGlobalFromILockBytes(plkbyt, &(This->hbytearray)) != S_OK)
  {
    FIXME("May not be an ILockBytes on HGLOBAL\n");
    return FALSE;
  }

  This->pLkbyt = plkbyt;

  /*
   * Increment the reference count of the ILockByte object since
   * we're keeping a reference to it.
   */
  ILockBytes_AddRef(This->pLkbyt);

  This->filesize.u.LowPart = GlobalSize(This->hbytearray);
  This->filesize.u.HighPart = 0;

  This->pbytearray = GlobalLock(This->hbytearray);

  TRACE("mem on %p len %lu\n", This->pbytearray, This->filesize.u.LowPart);

  return TRUE;
}

/******************************************************************************
 *      BIGBLOCKFILE_Destructor
 *
 * Destructor. Clean up, free memory.
 */
void BIGBLOCKFILE_Destructor(
  LPBIGBLOCKFILE This)
{
  BIGBLOCKFILE_FreeAllMappedPages(This);

  if (This->fileBased)
  {
    CloseHandle(This->hfilemap);
    CloseHandle(This->hfile);
  }
  else
  {
    GlobalUnlock(This->hbytearray);
    ILockBytes_Release(This->pLkbyt);
  }

  /* destroy this
   */
  HeapFree(GetProcessHeap(), 0, This);
}

/******************************************************************************
 *      BIGBLOCKFILE_GetROBigBlock
 *
 * Returns the specified block in read only mode.
 * Will return NULL if the block doesn't exists.
 */
void* BIGBLOCKFILE_GetROBigBlock(
  LPBIGBLOCKFILE This,
  ULONG          index)
{
  /*
   * block index starts at -1
   * translate to zero based index
   */
  if (index == 0xffffffff)
    index = 0;
  else
    index++;

  /*
   * validate the block index
   *
   */
  if (This->blocksize * (index + 1)
      > ROUND_UP(This->filesize.u.LowPart, This->blocksize))
  {
    TRACE("out of range %lu vs %lu\n", This->blocksize * (index + 1),
	  This->filesize.u.LowPart);
    return NULL;
  }

  return BIGBLOCKFILE_GetBigBlockPointer(This, index, FILE_MAP_READ);
}

/******************************************************************************
 *      BIGBLOCKFILE_GetBigBlock
 *
 * Returns the specified block.
 * Will grow the file if necessary.
 */
void* BIGBLOCKFILE_GetBigBlock(LPBIGBLOCKFILE This, ULONG index)
{
  /*
   * block index starts at -1
   * translate to zero based index
   */
  if (index == 0xffffffff)
    index = 0;
  else
    index++;

  /*
   * make sure that the block physically exists
   */
  if ((This->blocksize * (index + 1)) > This->filesize.u.LowPart)
  {
    ULARGE_INTEGER newSize;

    newSize.u.HighPart = 0;
    newSize.u.LowPart = This->blocksize * (index + 1);

    BIGBLOCKFILE_SetSize(This, newSize);
  }

  return BIGBLOCKFILE_GetBigBlockPointer(This, index, FILE_MAP_WRITE);
}

/******************************************************************************
 *      BIGBLOCKFILE_ReleaseBigBlock
 *
 * Releases the specified block.
 */
void BIGBLOCKFILE_ReleaseBigBlock(LPBIGBLOCKFILE This, void *pBlock)
{
    MappedPage *page;

    if (pBlock == NULL)
	return;

    page = BIGBLOCKFILE_GetPageFromPointer(This, pBlock);

    if (page == NULL)
	return;

    BIGBLOCKFILE_ReleaseMappedPage(This, page);
}

/******************************************************************************
 *      BIGBLOCKFILE_SetSize
 *
 * Sets the size of the file.
 *
 */
void BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize)
{
  if (This->filesize.u.LowPart == newSize.u.LowPart)
    return;

  TRACE("from %lu to %lu\n", This->filesize.u.LowPart, newSize.u.LowPart);
  /*
   * unmap all views, must be done before call to SetEndFile
   */
  BIGBLOCKFILE_UnmapAllMappedPages(This);

  if (This->fileBased)
  {
    char buf[10];

    /*
     * close file-mapping object, must be done before call to SetEndFile
     */
    if( This->hfilemap )
      CloseHandle(This->hfilemap);
    This->hfilemap = 0;

    /*
     * BEGIN HACK
     * This fixes a bug when saving through smbfs.
     * smbmount a Windows shared directory, save a structured storage file
     * to that dir: crash.
     *
     * The problem is that the SetFilePointer-SetEndOfFile combo below
     * doesn't always succeed. The file is not grown. It seems like the
     * operation is cached. By doing the WriteFile, the file is actually
     * grown on disk.
     * This hack is only needed when saving to smbfs.
     */
    memset(buf, '0', 10);
    SetFilePointer(This->hfile, newSize.u.LowPart, NULL, FILE_BEGIN);
    WriteFile(This->hfile, buf, 10, NULL, NULL);
    /*
     * END HACK
     */

    /*
     * set the new end of file
     */
    SetFilePointer(This->hfile, newSize.u.LowPart, NULL, FILE_BEGIN);
    SetEndOfFile(This->hfile);

    /*
     * re-create the file mapping object
     */
    This->hfilemap = CreateFileMappingA(This->hfile,
                                        NULL,
                                        This->flProtect,
                                        0, 0,
                                        NULL);
  }
  else
  {
    GlobalUnlock(This->hbytearray);

    /*
     * Resize the byte array object.
     */
    ILockBytes_SetSize(This->pLkbyt, newSize);

    /*
     * Re-acquire the handle, it may have changed.
     */
    GetHGlobalFromILockBytes(This->pLkbyt, &This->hbytearray);
    This->pbytearray = GlobalLock(This->hbytearray);
  }

  This->filesize.u.LowPart = newSize.u.LowPart;
  This->filesize.u.HighPart = newSize.u.HighPart;

  BIGBLOCKFILE_RemapAllMappedPages(This);
}

/******************************************************************************
 *      BIGBLOCKFILE_GetSize
 *
 * Returns the size of the file.
 *
 */
ULARGE_INTEGER BIGBLOCKFILE_GetSize(LPBIGBLOCKFILE This)
{
  return This->filesize;
}

/******************************************************************************
 *      BIGBLOCKFILE_AccessCheck     [PRIVATE]
 *
 * block_index is the index within the page.
 */
static BOOL BIGBLOCKFILE_AccessCheck(MappedPage *page, ULONG block_index,
				     DWORD desired_access)
{
    assert(block_index < BLOCKS_PER_PAGE);

    if (desired_access == FILE_MAP_READ)
    {
	if (BIGBLOCKFILE_TestBit(&page->writable_blocks, block_index))
	    return FALSE;

	BIGBLOCKFILE_SetBit(&page->readable_blocks, block_index);
    }
    else
    {
	assert(desired_access == FILE_MAP_WRITE);

	if (BIGBLOCKFILE_TestBit(&page->readable_blocks, block_index))
	    return FALSE;

	BIGBLOCKFILE_SetBit(&page->writable_blocks, block_index);
    }

    return TRUE;
}

/******************************************************************************
 *      BIGBLOCKFILE_GetBigBlockPointer     [PRIVATE]
 *
 * Returns a pointer to the specified block.
 */
static void* BIGBLOCKFILE_GetBigBlockPointer(
  LPBIGBLOCKFILE This,
  ULONG          block_index,
  DWORD          desired_access)
{
    DWORD page_index = block_index / BLOCKS_PER_PAGE;
    DWORD block_on_page = block_index % BLOCKS_PER_PAGE;

    MappedPage *page = BIGBLOCKFILE_GetMappedView(This, page_index);
    if (!page || !page->lpBytes) return NULL;

    if (!BIGBLOCKFILE_AccessCheck(page, block_on_page, desired_access))
    {
	BIGBLOCKFILE_ReleaseMappedPage(This, page);
	return NULL;
    }

    return (LPBYTE)page->lpBytes + (block_on_page * This->blocksize);
}

/******************************************************************************
 *      BIGBLOCKFILE_GetMappedPageFromPointer     [PRIVATE]
 *
 * pBlock is a pointer to a block on a page.
 * The page has to be on the in-use list. (As oppsed to the victim list.)
 *
 * Does not increment the usage count.
 */
static MappedPage *BIGBLOCKFILE_GetPageFromPointer(LPBIGBLOCKFILE This,
						   void *pBlock)
{
    MappedPage *page;

    for (page = This->maplist; page != NULL; page = page->next)
    {
	if ((LPBYTE)pBlock >= (LPBYTE)page->lpBytes
	    && (LPBYTE)pBlock <= (LPBYTE)page->lpBytes + PAGE_SIZE)
	    break;

    }

    return page;
}

/******************************************************************************
 *      BIGBLOCKFILE_FindPageInList      [PRIVATE]
 *
 */
static MappedPage *BIGBLOCKFILE_FindPageInList(MappedPage *head,
					       ULONG page_index)
{
    for (; head != NULL; head = head->next)
    {
	if (head->page_index == page_index)
	{
	    InterlockedIncrement(&head->refcnt);
	    break;
	}
    }

    return head;

}

static void BIGBLOCKFILE_UnlinkPage(MappedPage *page)
{
    if (page->next) page->next->prev = page->prev;
    if (page->prev) page->prev->next = page->next;
}

static void BIGBLOCKFILE_LinkHeadPage(MappedPage **head, MappedPage *page)
{
    if (*head) (*head)->prev = page;
    page->next = *head;
    page->prev = NULL;
    *head = page;
}

/******************************************************************************
 *      BIGBLOCKFILE_GetMappedView      [PRIVATE]
 *
 * Gets the page requested if it is already mapped.
 * If it's not already mapped, this method will map it
 */
static void * BIGBLOCKFILE_GetMappedView(
  LPBIGBLOCKFILE This,
  DWORD          page_index)
{
    MappedPage *page;

    page = BIGBLOCKFILE_FindPageInList(This->maplist, page_index);
    if (!page)
    {
	page = BIGBLOCKFILE_FindPageInList(This->victimhead, page_index);
	if (page)
	{
	    This->num_victim_pages--;

	    BIGBLOCKFILE_Zero(&page->readable_blocks);
	    BIGBLOCKFILE_Zero(&page->writable_blocks);
	}
    }

    if (page)
    {
	/* If the page is not already at the head of the list, move
	 * it there. (Also moves pages from victim to main list.) */
	if (This->maplist != page)
	{
	    if (This->victimhead == page) This->victimhead = page->next;
	    if (This->victimtail == page) This->victimtail = page->prev;

	    BIGBLOCKFILE_UnlinkPage(page);

	    BIGBLOCKFILE_LinkHeadPage(&This->maplist, page);
	}

	return page;
    }

    page = BIGBLOCKFILE_CreatePage(This, page_index);
    if (!page) return NULL;

    BIGBLOCKFILE_LinkHeadPage(&This->maplist, page);

    return page;
}

static BOOL BIGBLOCKFILE_MapPage(LPBIGBLOCKFILE This, MappedPage *page)
{
    DWORD lowoffset = PAGE_SIZE * page->page_index;

    if (This->fileBased)
    {
	DWORD numBytesToMap;
	DWORD desired_access;

        if( !This->hfilemap )
            return FALSE;

	if (lowoffset + PAGE_SIZE > This->filesize.u.LowPart)
	    numBytesToMap = This->filesize.u.LowPart - lowoffset;
	else
	    numBytesToMap = PAGE_SIZE;

	if (This->flProtect == PAGE_READONLY)
	    desired_access = FILE_MAP_READ;
	else
	    desired_access = FILE_MAP_WRITE;

	page->lpBytes = MapViewOfFile(This->hfilemap, desired_access, 0,
				      lowoffset, numBytesToMap);
    }
    else
    {
	page->lpBytes = (LPBYTE)This->pbytearray + lowoffset;
    }

    TRACE("mapped page %lu to %p\n", page->page_index, page->lpBytes);

    return page->lpBytes != NULL;
}

static MappedPage *BIGBLOCKFILE_CreatePage(LPBIGBLOCKFILE This,
					   ULONG page_index)
{
    MappedPage *page;

    page = HeapAlloc(GetProcessHeap(), 0, sizeof(MappedPage));
    if (page == NULL)
      return NULL;

    page->page_index = page_index;
    page->refcnt = 1;

    page->next = NULL;
    page->prev = NULL;

    BIGBLOCKFILE_MapPage(This, page);

    BIGBLOCKFILE_Zero(&page->readable_blocks);
    BIGBLOCKFILE_Zero(&page->writable_blocks);

    return page;
}

static void BIGBLOCKFILE_UnmapPage(LPBIGBLOCKFILE This, MappedPage *page)
{
    TRACE("%ld at %p\n", page->page_index, page->lpBytes);
    if (page->refcnt > 0)
	ERR("unmapping inuse page %p\n", page->lpBytes);

    if (This->fileBased && page->lpBytes)
	UnmapViewOfFile(page->lpBytes);

    page->lpBytes = NULL;
}

static void BIGBLOCKFILE_DeletePage(LPBIGBLOCKFILE This, MappedPage *page)
{
    BIGBLOCKFILE_UnmapPage(This, page);

    HeapFree(GetProcessHeap(), 0, page);
}

/******************************************************************************
 *      BIGBLOCKFILE_ReleaseMappedPage      [PRIVATE]
 *
 * Decrements the reference count of the mapped page.
 */
static void BIGBLOCKFILE_ReleaseMappedPage(
  LPBIGBLOCKFILE This,
  MappedPage    *page)
{
    assert(This != NULL);
    assert(page != NULL);

    /* If the page is no longer refenced, move it to the victim list.
     * If the victim list is too long, kick somebody off. */
    if (!InterlockedDecrement(&page->refcnt))
    {
	if (This->maplist == page) This->maplist = page->next;

	BIGBLOCKFILE_UnlinkPage(page);

	if (MAX_VICTIM_PAGES > 0)
	{
	    if (This->num_victim_pages >= MAX_VICTIM_PAGES)
	    {
		MappedPage *victim = This->victimtail;
		if (victim)
		{
		    This->victimtail = victim->prev;
		    if (This->victimhead == victim)
			This->victimhead = victim->next;

		    BIGBLOCKFILE_UnlinkPage(victim);
		    BIGBLOCKFILE_DeletePage(This, victim);
		}
	    }
	    else This->num_victim_pages++;

	    BIGBLOCKFILE_LinkHeadPage(&This->victimhead, page);
	    if (This->victimtail == NULL) This->victimtail = page;
	}
	else
	    BIGBLOCKFILE_DeletePage(This, page);
    }
}

static void BIGBLOCKFILE_DeleteList(LPBIGBLOCKFILE This, MappedPage *list)
{
    while (list != NULL)
    {
	MappedPage *next = list->next;

	BIGBLOCKFILE_DeletePage(This, list);

	list = next;
    }
}

/******************************************************************************
 *      BIGBLOCKFILE_FreeAllMappedPages     [PRIVATE]
 *
 * Unmap all currently mapped pages.
 * Empty mapped pages list.
 */
static void BIGBLOCKFILE_FreeAllMappedPages(
  LPBIGBLOCKFILE This)
{
    BIGBLOCKFILE_DeleteList(This, This->maplist);
    BIGBLOCKFILE_DeleteList(This, This->victimhead);

    This->maplist = NULL;
    This->victimhead = NULL;
    This->victimtail = NULL;
    This->num_victim_pages = 0;
}

static void BIGBLOCKFILE_UnmapList(LPBIGBLOCKFILE This, MappedPage *list)
{
    for (; list != NULL; list = list->next)
    {
	BIGBLOCKFILE_UnmapPage(This, list);
    }
}

static void BIGBLOCKFILE_UnmapAllMappedPages(LPBIGBLOCKFILE This)
{
    BIGBLOCKFILE_UnmapList(This, This->maplist);
    BIGBLOCKFILE_UnmapList(This, This->victimhead);
}

static void BIGBLOCKFILE_RemapList(LPBIGBLOCKFILE This, MappedPage *list)
{
    while (list != NULL)
    {
	MappedPage *next = list->next;

	if (list->page_index * PAGE_SIZE > This->filesize.u.LowPart)
	{
	    TRACE("discarding %lu\n", list->page_index);

	    /* page is entirely outside of the file, delete it */
	    BIGBLOCKFILE_UnlinkPage(list);
	    BIGBLOCKFILE_DeletePage(This, list);
	}
	else
	{
	    /* otherwise, remap it */
	    BIGBLOCKFILE_MapPage(This, list);
	}

	list = next;
    }
}

static void BIGBLOCKFILE_RemapAllMappedPages(LPBIGBLOCKFILE This)
{
    BIGBLOCKFILE_RemapList(This, This->maplist);
    BIGBLOCKFILE_RemapList(This, This->victimhead);
}

/****************************************************************************
 *      BIGBLOCKFILE_GetProtectMode
 *
 * This function will return a protection mode flag for a file-mapping object
 * from the open flags of a file.
 */
static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags)
{
    if (openFlags & (STGM_WRITE | STGM_READWRITE))
	return PAGE_READWRITE;
    else
	return PAGE_READONLY;
}
