ole32: Remove the BigBlockFile abstraction and always use an ILockBytes.

This commit is contained in:
Vincent Povirk 2010-07-17 11:56:17 -05:00 committed by Alexandre Julliard
parent 4171499411
commit 14f8f9d5b5
4 changed files with 152 additions and 229 deletions

View File

@ -21,6 +21,7 @@ C_SRCS = \
dictionary.c \
enumx.c \
errorinfo.c \
filelockbytes.c \
filemoniker.c \
ftmarshal.c \
git.c \
@ -39,7 +40,6 @@ C_SRCS = \
pointermoniker.c \
regsvr.c \
rpc.c \
stg_bigblockfile.c \
stg_prop.c \
stg_stream.c \
storage32.c \

View File

@ -1,20 +1,9 @@
/******************************************************************************
*
* 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
* File-based ILockBytes implementation
*
* Copyright 1999 Thuy Nguyen
* Copyright 2010 Vincent Povirk for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -55,19 +44,16 @@
WINE_DEFAULT_DEBUG_CHANNEL(storage);
/***********************************************************
* Data structures used internally by the BigBlockFile
* class.
*/
struct BigBlockFile
typedef struct FileLockBytesImpl
{
BOOL fileBased;
const ILockBytesVtbl *lpVtbl;
LONG ref;
ULARGE_INTEGER filesize;
HANDLE hfile;
DWORD flProtect;
ILockBytes *pLkbyt;
};
} FileLockBytesImpl;
static const ILockBytesVtbl FileLockBytesImpl_Vtbl;
/***********************************************************
* Prototypes for private methods
@ -77,52 +63,13 @@ struct BigBlockFile
* pass expressions with side effects. */
#define ROUND_UP(a, b) ((((a) + (b) - 1)/(b))*(b))
/******************************************************************************
* BIGBLOCKFILE_FileInit
*
* Initialize a big block object supported by a file.
*/
static BOOL BIGBLOCKFILE_FileInit(LPBIGBLOCKFILE This, HANDLE hFile)
{
This->pLkbyt = NULL;
This->hfile = hFile;
if (This->hfile == INVALID_HANDLE_VALUE)
return FALSE;
This->filesize.u.LowPart = GetFileSize(This->hfile,
&This->filesize.u.HighPart);
TRACE("file len %u\n", This->filesize.u.LowPart);
return TRUE;
}
/******************************************************************************
* BIGBLOCKFILE_LockBytesInit
*
* Initialize a big block object supported by an ILockBytes.
*/
static BOOL BIGBLOCKFILE_LockBytesInit(LPBIGBLOCKFILE This, ILockBytes* plkbyt)
{
This->hfile = 0;
This->pLkbyt = plkbyt;
ILockBytes_AddRef(This->pLkbyt);
/* We'll get the size directly with ILockBytes_Stat */
This->filesize.QuadPart = 0;
TRACE("ILockBytes %p\n", This->pLkbyt);
return TRUE;
}
/****************************************************************************
* BIGBLOCKFILE_GetProtectMode
* 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)
static DWORD GetProtectMode(DWORD openFlags)
{
switch(STGM_ACCESS_MODE(openFlags))
{
@ -133,9 +80,77 @@ static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags)
return PAGE_READONLY;
}
/******************************************************************************
* FileLockBytesImpl_Construct
*
* Initialize a big block object supported by a file.
*/
HRESULT FileLockBytesImpl_Construct(HANDLE hFile, DWORD openFlags, ILockBytes **pLockBytes)
{
FileLockBytesImpl *This;
if (hFile == INVALID_HANDLE_VALUE)
return E_FAIL;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(FileLockBytesImpl));
if (!This)
return E_OUTOFMEMORY;
This->lpVtbl = &FileLockBytesImpl_Vtbl;
This->ref = 1;
This->hfile = hFile;
This->filesize.u.LowPart = GetFileSize(This->hfile,
&This->filesize.u.HighPart);
This->flProtect = GetProtectMode(openFlags);
TRACE("file len %u\n", This->filesize.u.LowPart);
*pLockBytes = (ILockBytes*)This;
return S_OK;
}
/* ILockByte Interfaces */
static HRESULT WINAPI FileLockBytesImpl_QueryInterface(ILockBytes *iface, REFIID riid,
void **ppvObject)
{
if (IsEqualIID(riid, &IID_ILockBytes) || IsEqualIID(riid, &IID_ILockBytes))
*ppvObject = iface;
else
{
*ppvObject = NULL;
return E_NOINTERFACE;
}
IUnknown_AddRef((IUnknown*)*ppvObject);
return S_OK;
}
static ULONG WINAPI FileLockBytesImpl_AddRef(ILockBytes *iface)
{
FileLockBytesImpl* This = (FileLockBytesImpl*)iface;
return InterlockedIncrement(&This->ref);
}
static ULONG WINAPI FileLockBytesImpl_Release(ILockBytes *iface)
{
FileLockBytesImpl* This = (FileLockBytesImpl*)iface;
ULONG ref;
ref = InterlockedDecrement(&This->ref);
if (ref == 0)
{
CloseHandle(This->hfile);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
/******************************************************************************
* This method is part of the ILockBytes interface.
*
@ -144,13 +159,14 @@ static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags)
*
* See the documentation of ILockBytes for more info.
*/
static HRESULT ImplBIGBLOCKFILE_ReadAt(
BigBlockFile* const This,
static HRESULT WINAPI FileLockBytesImpl_ReadAt(
ILockBytes* iface,
ULARGE_INTEGER ulOffset, /* [in] */
void* pv, /* [length_is][size_is][out] */
ULONG cb, /* [in] */
ULONG* pcbRead) /* [out] */
{
FileLockBytesImpl* This = (FileLockBytesImpl*)iface;
ULONG bytes_left = cb;
LPBYTE readPtr = pv;
BOOL ret;
@ -198,13 +214,14 @@ static HRESULT ImplBIGBLOCKFILE_ReadAt(
*
* See the documentation of ILockBytes for more info.
*/
static HRESULT ImplBIGBLOCKFILE_WriteAt(
BigBlockFile* const This,
static HRESULT WINAPI FileLockBytesImpl_WriteAt(
ILockBytes* iface,
ULARGE_INTEGER ulOffset, /* [in] */
const void* pv, /* [size_is][in] */
ULONG cb, /* [in] */
ULONG* pcbWritten) /* [out] */
{
FileLockBytesImpl* This = (FileLockBytesImpl*)iface;
ULONG size_needed = ulOffset.u.LowPart + cb;
ULONG bytes_left = cb;
const BYTE *writePtr = pv;
@ -228,7 +245,7 @@ static HRESULT ImplBIGBLOCKFILE_WriteAt(
ULARGE_INTEGER newSize;
newSize.u.HighPart = 0;
newSize.u.LowPart = size_needed;
BIGBLOCKFILE_SetSize(This, newSize);
ILockBytes_SetSize(iface, newSize);
}
offset.QuadPart = ulOffset.QuadPart;
@ -256,103 +273,23 @@ static HRESULT ImplBIGBLOCKFILE_WriteAt(
return S_OK;
}
/******************************************************************************
* 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,
BOOL fileBased)
static HRESULT WINAPI FileLockBytesImpl_Flush(ILockBytes* iface)
{
BigBlockFile *This;
This = HeapAlloc(GetProcessHeap(), 0, sizeof(BigBlockFile));
if (This == NULL)
return NULL;
This->fileBased = fileBased;
This->flProtect = BIGBLOCKFILE_GetProtectMode(openFlags);
if (This->fileBased)
{
if (!BIGBLOCKFILE_FileInit(This, hFile))
{
HeapFree(GetProcessHeap(), 0, This);
return NULL;
}
}
else
{
if (!BIGBLOCKFILE_LockBytesInit(This, pLkByt))
{
HeapFree(GetProcessHeap(), 0, This);
return NULL;
}
}
return This;
return S_OK;
}
/******************************************************************************
* BIGBLOCKFILE_Destructor
*
* Destructor. Clean up, free memory.
*/
void BIGBLOCKFILE_Destructor(BigBlockFile *This)
{
if (This->fileBased)
{
CloseHandle(This->hfile);
}
else
{
ILockBytes_Release(This->pLkbyt);
}
HeapFree(GetProcessHeap(), 0, This);
}
/******************************************************************************
* BIGBLOCKFILE_ReadAt
*/
HRESULT BIGBLOCKFILE_ReadAt(BigBlockFile *This, ULARGE_INTEGER offset,
void* buffer, ULONG size, ULONG* bytesRead)
{
if (This->fileBased)
return ImplBIGBLOCKFILE_ReadAt(This,offset,buffer,size,bytesRead);
else
return ILockBytes_ReadAt(This->pLkbyt,offset,buffer,size,bytesRead);
}
/******************************************************************************
* BIGBLOCKFILE_WriteAt
*/
HRESULT BIGBLOCKFILE_WriteAt(BigBlockFile *This, ULARGE_INTEGER offset,
const void* buffer, ULONG size, ULONG* bytesRead)
{
if (This->fileBased)
return ImplBIGBLOCKFILE_WriteAt(This,offset,buffer,size,bytesRead);
else
return ILockBytes_WriteAt(This->pLkbyt,offset,buffer,size,bytesRead);
}
/******************************************************************************
* BIGBLOCKFILE_SetSize
* ILockBytes_SetSize
*
* Sets the size of the file.
*
*/
HRESULT BIGBLOCKFILE_SetSize(BigBlockFile *This, ULARGE_INTEGER newSize)
static HRESULT WINAPI FileLockBytesImpl_SetSize(ILockBytes* iface, ULARGE_INTEGER newSize)
{
FileLockBytesImpl* This = (FileLockBytesImpl*)iface;
HRESULT hr = S_OK;
LARGE_INTEGER newpos;
if (!This->fileBased)
return ILockBytes_SetSize(This->pLkbyt, newSize);
if (This->filesize.u.LowPart == newSize.u.LowPart)
return hr;
@ -368,40 +305,47 @@ HRESULT BIGBLOCKFILE_SetSize(BigBlockFile *This, ULARGE_INTEGER newSize)
return hr;
}
/******************************************************************************
* BIGBLOCKFILE_GetSize
*
* Gets the size of the file.
*
*/
static HRESULT BIGBLOCKFILE_GetSize(BigBlockFile *This, ULARGE_INTEGER *size)
static HRESULT WINAPI FileLockBytesImpl_LockRegion(ILockBytes* iface,
ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
HRESULT hr = S_OK;
if(This->fileBased)
*size = This->filesize;
else
FIXME("stub\n");
return E_NOTIMPL;
}
static HRESULT WINAPI FileLockBytesImpl_UnlockRegion(ILockBytes* iface,
ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
{
FIXME("stub\n");
return E_NOTIMPL;
}
static HRESULT WINAPI FileLockBytesImpl_Stat(ILockBytes* iface,
STATSTG *pstatstg, DWORD grfStatFlag)
{
FileLockBytesImpl* This = (FileLockBytesImpl*)iface;
if (!(STATFLAG_NONAME & grfStatFlag))
{
STATSTG stat;
hr = ILockBytes_Stat(This->pLkbyt, &stat, STATFLAG_NONAME);
if(SUCCEEDED(hr)) *size = stat.cbSize;
FIXME("reading filename not supported\n");
}
return hr;
pstatstg->pwcsName = NULL;
pstatstg->type = STGTY_LOCKBYTES;
pstatstg->cbSize = This->filesize;
/* FIXME: If the implementation is exported, we'll need to set other fields. */
return S_OK;
}
/******************************************************************************
* BIGBLOCKFILE_Expand
*
* Grows the file to the specified size if necessary.
*/
HRESULT BIGBLOCKFILE_Expand(BigBlockFile *This, ULARGE_INTEGER newSize)
{
ULARGE_INTEGER size;
HRESULT hr;
hr = BIGBLOCKFILE_GetSize(This, &size);
if(FAILED(hr)) return hr;
if (newSize.QuadPart > size.QuadPart)
hr = BIGBLOCKFILE_SetSize(This, newSize);
return hr;
}
static const ILockBytesVtbl FileLockBytesImpl_Vtbl = {
FileLockBytesImpl_QueryInterface,
FileLockBytesImpl_AddRef,
FileLockBytesImpl_Release,
FileLockBytesImpl_ReadAt,
FileLockBytesImpl_WriteAt,
FileLockBytesImpl_Flush,
FileLockBytesImpl_SetSize,
FileLockBytesImpl_LockRegion,
FileLockBytesImpl_UnlockRegion,
FileLockBytesImpl_Stat
};

View File

@ -327,7 +327,7 @@ static HRESULT StorageImpl_ReadAt(StorageImpl* This,
ULONG size,
ULONG* bytesRead)
{
return BIGBLOCKFILE_ReadAt(This->bigBlockFile,offset,buffer,size,bytesRead);
return ILockBytes_ReadAt(This->lockBytes,offset,buffer,size,bytesRead);
}
static HRESULT StorageImpl_WriteAt(StorageImpl* This,
@ -336,7 +336,7 @@ static HRESULT StorageImpl_WriteAt(StorageImpl* This,
const ULONG size,
ULONG* bytesWritten)
{
return BIGBLOCKFILE_WriteAt(This->bigBlockFile,offset,buffer,size,bytesWritten);
return ILockBytes_WriteAt(This->lockBytes,offset,buffer,size,bytesWritten);
}
/************************************************************************
@ -2683,17 +2683,17 @@ static HRESULT StorageImpl_Construct(
*/
This->bigBlockSize = sector_size;
This->smallBlockSize = DEF_SMALL_BLOCK_SIZE;
This->bigBlockFile = BIGBLOCKFILE_Construct(hFile,
pLkbyt,
openFlags,
fileBased);
if (This->bigBlockFile == 0)
if (hFile)
hr = FileLockBytesImpl_Construct(hFile, openFlags, &This->lockBytes);
else
{
hr = E_FAIL;
goto end;
This->lockBytes = pLkbyt;
ILockBytes_AddRef(pLkbyt);
}
if (FAILED(hr))
goto end;
if (create)
{
ULARGE_INTEGER size;
@ -2729,7 +2729,7 @@ static HRESULT StorageImpl_Construct(
*/
size.u.HighPart = 0;
size.u.LowPart = This->bigBlockSize * 3;
BIGBLOCKFILE_SetSize(This->bigBlockFile, size);
ILockBytes_SetSize(This->lockBytes, size);
/*
* Initialize the big block depot
@ -2884,8 +2884,8 @@ static void StorageImpl_Destroy(StorageBaseImpl* iface)
for (i=0; i<BLOCKCHAIN_CACHE_SIZE; i++)
BlockChainStream_Destroy(This->blockChainCache[i]);
if (This->bigBlockFile)
BIGBLOCKFILE_Destructor(This->bigBlockFile);
if (This->lockBytes)
ILockBytes_Release(This->lockBytes);
HeapFree(GetProcessHeap(), 0, This);
}
@ -2908,6 +2908,7 @@ static ULONG StorageImpl_GetNextFreeBigBlock(
int depotIndex = 0;
ULONG freeBlock = BLOCK_UNUSED;
ULARGE_INTEGER neededSize;
STATSTG statstg;
depotIndex = This->prevFreeBlock / blocksPerDepot;
depotBlockOffset = (This->prevFreeBlock % blocksPerDepot) * sizeof(ULONG);
@ -3022,7 +3023,11 @@ static ULONG StorageImpl_GetNextFreeBigBlock(
* make sure that the block physically exists before using it
*/
neededSize.QuadPart = StorageImpl_GetBigBlockOffset(This, freeBlock)+This->bigBlockSize;
BIGBLOCKFILE_Expand(This->bigBlockFile, neededSize);
ILockBytes_Stat(This->lockBytes, &statstg, STATFLAG_NONAME);
if (neededSize.QuadPart > statstg.cbSize.QuadPart)
ILockBytes_SetSize(This->lockBytes, neededSize);
This->prevFreeBlock = freeBlock;

View File

@ -11,6 +11,7 @@
*
* Copyright 1998,1999 Francis Beaudet
* Copyright 1998,1999 Thuy Nguyen
* Copyright 2010 Vincent Povirk for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -153,31 +154,7 @@ struct DirEntry
ULARGE_INTEGER size;
};
/*************************************************************************
* Big Block File support
*
* The big block file is an abstraction of a flat file separated in
* same sized blocks. The implementation for the methods described in
* this section appear in stg_bigblockfile.c
*/
typedef struct BigBlockFile BigBlockFile,*LPBIGBLOCKFILE;
/*
* Declaration of the functions used to manipulate the BigBlockFile
* data structure.
*/
BigBlockFile* BIGBLOCKFILE_Construct(HANDLE hFile,
ILockBytes* pLkByt,
DWORD openFlags,
BOOL fileBased);
void BIGBLOCKFILE_Destructor(LPBIGBLOCKFILE This);
HRESULT BIGBLOCKFILE_Expand(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize);
HRESULT BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize);
HRESULT BIGBLOCKFILE_ReadAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
void* buffer, ULONG size, ULONG* bytesRead);
HRESULT BIGBLOCKFILE_WriteAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
const void* buffer, ULONG size, ULONG* bytesRead);
HRESULT FileLockBytesImpl_Construct(HANDLE hFile, DWORD openFlags, ILockBytes **pLockBytes);
/*************************************************************************
* Ole Convert support
@ -395,10 +372,7 @@ struct StorageImpl
BlockChainStream* blockChainCache[BLOCKCHAIN_CACHE_SIZE];
UINT blockChainToEvict;
/*
* Pointer to the big block file abstraction
*/
BigBlockFile* bigBlockFile;
ILockBytes* lockBytes;
};
HRESULT StorageImpl_ReadRawDirEntry(