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 \ dictionary.c \
enumx.c \ enumx.c \
errorinfo.c \ errorinfo.c \
filelockbytes.c \
filemoniker.c \ filemoniker.c \
ftmarshal.c \ ftmarshal.c \
git.c \ git.c \
@ -39,7 +40,6 @@ C_SRCS = \
pointermoniker.c \ pointermoniker.c \
regsvr.c \ regsvr.c \
rpc.c \ rpc.c \
stg_bigblockfile.c \
stg_prop.c \ stg_prop.c \
stg_stream.c \ stg_stream.c \
storage32.c \ storage32.c \

View File

@ -1,20 +1,9 @@
/****************************************************************************** /******************************************************************************
* *
* BigBlockFile * File-based ILockBytes implementation
*
* 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 * Copyright 1999 Thuy Nguyen
* Copyright 2010 Vincent Povirk for CodeWeavers
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -55,19 +44,16 @@
WINE_DEFAULT_DEBUG_CHANNEL(storage); WINE_DEFAULT_DEBUG_CHANNEL(storage);
/*********************************************************** typedef struct FileLockBytesImpl
* Data structures used internally by the BigBlockFile
* class.
*/
struct BigBlockFile
{ {
BOOL fileBased; const ILockBytesVtbl *lpVtbl;
LONG ref;
ULARGE_INTEGER filesize; ULARGE_INTEGER filesize;
HANDLE hfile; HANDLE hfile;
DWORD flProtect; DWORD flProtect;
ILockBytes *pLkbyt; } FileLockBytesImpl;
};
static const ILockBytesVtbl FileLockBytesImpl_Vtbl;
/*********************************************************** /***********************************************************
* Prototypes for private methods * Prototypes for private methods
@ -77,52 +63,13 @@ struct BigBlockFile
* pass expressions with side effects. */ * pass expressions with side effects. */
#define ROUND_UP(a, b) ((((a) + (b) - 1)/(b))*(b)) #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 * This function will return a protection mode flag for a file-mapping object
* from the open flags of a file. * from the open flags of a file.
*/ */
static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags) static DWORD GetProtectMode(DWORD openFlags)
{ {
switch(STGM_ACCESS_MODE(openFlags)) switch(STGM_ACCESS_MODE(openFlags))
{ {
@ -133,9 +80,77 @@ static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags)
return PAGE_READONLY; 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 */ /* 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. * 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. * See the documentation of ILockBytes for more info.
*/ */
static HRESULT ImplBIGBLOCKFILE_ReadAt( static HRESULT WINAPI FileLockBytesImpl_ReadAt(
BigBlockFile* const This, ILockBytes* iface,
ULARGE_INTEGER ulOffset, /* [in] */ ULARGE_INTEGER ulOffset, /* [in] */
void* pv, /* [length_is][size_is][out] */ void* pv, /* [length_is][size_is][out] */
ULONG cb, /* [in] */ ULONG cb, /* [in] */
ULONG* pcbRead) /* [out] */ ULONG* pcbRead) /* [out] */
{ {
FileLockBytesImpl* This = (FileLockBytesImpl*)iface;
ULONG bytes_left = cb; ULONG bytes_left = cb;
LPBYTE readPtr = pv; LPBYTE readPtr = pv;
BOOL ret; BOOL ret;
@ -198,13 +214,14 @@ static HRESULT ImplBIGBLOCKFILE_ReadAt(
* *
* See the documentation of ILockBytes for more info. * See the documentation of ILockBytes for more info.
*/ */
static HRESULT ImplBIGBLOCKFILE_WriteAt( static HRESULT WINAPI FileLockBytesImpl_WriteAt(
BigBlockFile* const This, ILockBytes* iface,
ULARGE_INTEGER ulOffset, /* [in] */ ULARGE_INTEGER ulOffset, /* [in] */
const void* pv, /* [size_is][in] */ const void* pv, /* [size_is][in] */
ULONG cb, /* [in] */ ULONG cb, /* [in] */
ULONG* pcbWritten) /* [out] */ ULONG* pcbWritten) /* [out] */
{ {
FileLockBytesImpl* This = (FileLockBytesImpl*)iface;
ULONG size_needed = ulOffset.u.LowPart + cb; ULONG size_needed = ulOffset.u.LowPart + cb;
ULONG bytes_left = cb; ULONG bytes_left = cb;
const BYTE *writePtr = pv; const BYTE *writePtr = pv;
@ -228,7 +245,7 @@ static HRESULT ImplBIGBLOCKFILE_WriteAt(
ULARGE_INTEGER newSize; ULARGE_INTEGER newSize;
newSize.u.HighPart = 0; newSize.u.HighPart = 0;
newSize.u.LowPart = size_needed; newSize.u.LowPart = size_needed;
BIGBLOCKFILE_SetSize(This, newSize); ILockBytes_SetSize(iface, newSize);
} }
offset.QuadPart = ulOffset.QuadPart; offset.QuadPart = ulOffset.QuadPart;
@ -256,103 +273,23 @@ static HRESULT ImplBIGBLOCKFILE_WriteAt(
return S_OK; return S_OK;
} }
/****************************************************************************** static HRESULT WINAPI FileLockBytesImpl_Flush(ILockBytes* iface)
* 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)
{ {
BigBlockFile *This; return S_OK;
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;
} }
/****************************************************************************** /******************************************************************************
* BIGBLOCKFILE_Destructor * ILockBytes_SetSize
*
* 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
* *
* Sets the size of the file. * 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; HRESULT hr = S_OK;
LARGE_INTEGER newpos; LARGE_INTEGER newpos;
if (!This->fileBased)
return ILockBytes_SetSize(This->pLkbyt, newSize);
if (This->filesize.u.LowPart == newSize.u.LowPart) if (This->filesize.u.LowPart == newSize.u.LowPart)
return hr; return hr;
@ -368,40 +305,47 @@ HRESULT BIGBLOCKFILE_SetSize(BigBlockFile *This, ULARGE_INTEGER newSize)
return hr; return hr;
} }
/****************************************************************************** static HRESULT WINAPI FileLockBytesImpl_LockRegion(ILockBytes* iface,
* BIGBLOCKFILE_GetSize ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
*
* Gets the size of the file.
*
*/
static HRESULT BIGBLOCKFILE_GetSize(BigBlockFile *This, ULARGE_INTEGER *size)
{ {
HRESULT hr = S_OK; FIXME("stub\n");
if(This->fileBased) return E_NOTIMPL;
*size = This->filesize; }
else
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; FIXME("reading filename not supported\n");
hr = ILockBytes_Stat(This->pLkbyt, &stat, STATFLAG_NONAME);
if(SUCCEEDED(hr)) *size = stat.cbSize;
} }
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;
} }
/****************************************************************************** static const ILockBytesVtbl FileLockBytesImpl_Vtbl = {
* BIGBLOCKFILE_Expand FileLockBytesImpl_QueryInterface,
* FileLockBytesImpl_AddRef,
* Grows the file to the specified size if necessary. FileLockBytesImpl_Release,
*/ FileLockBytesImpl_ReadAt,
HRESULT BIGBLOCKFILE_Expand(BigBlockFile *This, ULARGE_INTEGER newSize) FileLockBytesImpl_WriteAt,
{ FileLockBytesImpl_Flush,
ULARGE_INTEGER size; FileLockBytesImpl_SetSize,
HRESULT hr; FileLockBytesImpl_LockRegion,
FileLockBytesImpl_UnlockRegion,
hr = BIGBLOCKFILE_GetSize(This, &size); FileLockBytesImpl_Stat
if(FAILED(hr)) return hr; };
if (newSize.QuadPart > size.QuadPart)
hr = BIGBLOCKFILE_SetSize(This, newSize);
return hr;
}

View File

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

View File

@ -11,6 +11,7 @@
* *
* Copyright 1998,1999 Francis Beaudet * Copyright 1998,1999 Francis Beaudet
* Copyright 1998,1999 Thuy Nguyen * Copyright 1998,1999 Thuy Nguyen
* Copyright 2010 Vincent Povirk for CodeWeavers
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -153,31 +154,7 @@ struct DirEntry
ULARGE_INTEGER size; ULARGE_INTEGER size;
}; };
/************************************************************************* HRESULT FileLockBytesImpl_Construct(HANDLE hFile, DWORD openFlags, ILockBytes **pLockBytes);
* 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);
/************************************************************************* /*************************************************************************
* Ole Convert support * Ole Convert support
@ -395,10 +372,7 @@ struct StorageImpl
BlockChainStream* blockChainCache[BLOCKCHAIN_CACHE_SIZE]; BlockChainStream* blockChainCache[BLOCKCHAIN_CACHE_SIZE];
UINT blockChainToEvict; UINT blockChainToEvict;
/* ILockBytes* lockBytes;
* Pointer to the big block file abstraction
*/
BigBlockFile* bigBlockFile;
}; };
HRESULT StorageImpl_ReadRawDirEntry( HRESULT StorageImpl_ReadRawDirEntry(