From 39434ec5d2d93680b0c57611841c1c8b9f71030c Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Sat, 17 Jul 2010 11:56:17 -0500 Subject: [PATCH 2/5] ole32: Remove the BigBlockFile abstraction and always use an ILockBytes. --- dlls/ole32/Makefile.in | 2 +- dlls/ole32/filelockbytes.c | 351 +++++++++++++++++++++++++++++++++++ dlls/ole32/stg_bigblockfile.c | 407 ----------------------------------------- dlls/ole32/storage32.c | 33 ++-- dlls/ole32/storage32.h | 32 +--- 5 files changed, 374 insertions(+), 451 deletions(-) create mode 100644 dlls/ole32/filelockbytes.c delete mode 100644 dlls/ole32/stg_bigblockfile.c diff --git a/dlls/ole32/Makefile.in b/dlls/ole32/Makefile.in index 755a2b8..430ec92 100644 --- a/dlls/ole32/Makefile.in +++ b/dlls/ole32/Makefile.in @@ -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 \ diff --git a/dlls/ole32/filelockbytes.c b/dlls/ole32/filelockbytes.c new file mode 100644 index 0000000..2491a82 --- /dev/null +++ b/dlls/ole32/filelockbytes.c @@ -0,0 +1,351 @@ +/****************************************************************************** + * + * 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 + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include +#include + +#define COBJMACROS +#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); + +typedef struct FileLockBytesImpl +{ + const ILockBytesVtbl *lpVtbl; + LONG ref; + ULARGE_INTEGER filesize; + HANDLE hfile; + DWORD flProtect; +} FileLockBytesImpl; + +static const ILockBytesVtbl FileLockBytesImpl_Vtbl; + +/*********************************************************** + * Prototypes for private methods + */ + +/* 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)) + +/**************************************************************************** + * GetProtectMode + * + * This function will return a protection mode flag for a file-mapping object + * from the open flags of a file. + */ +static DWORD GetProtectMode(DWORD openFlags) +{ + switch(STGM_ACCESS_MODE(openFlags)) + { + case STGM_WRITE: + case STGM_READWRITE: + return PAGE_READWRITE; + } + 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. + * + * It reads a block of information from the byte array at the specified + * offset. + * + * See the documentation of ILockBytes for more info. + */ +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; + LARGE_INTEGER offset; + ULONG cbRead; + + TRACE("(%p)-> %i %p %i %p\n",This, ulOffset.u.LowPart, pv, cb, pcbRead); + + /* verify a sane environment */ + if (!This) return E_FAIL; + + if (pcbRead) + *pcbRead = 0; + + offset.QuadPart = ulOffset.QuadPart; + + ret = SetFilePointerEx(This->hfile, offset, NULL, FILE_BEGIN); + + if (!ret) + return STG_E_READFAULT; + + while (bytes_left) + { + ret = ReadFile(This->hfile, readPtr, bytes_left, &cbRead, NULL); + + if (!ret || cbRead == 0) + return STG_E_READFAULT; + + if (pcbRead) + *pcbRead += cbRead; + + bytes_left -= cbRead; + readPtr += cbRead; + } + + TRACE("finished\n"); + return S_OK; +} + +/****************************************************************************** + * This method is part of the ILockBytes interface. + * + * It writes the specified bytes at the specified offset. + * position. If the file is too small, it will be resized. + * + * See the documentation of ILockBytes for more info. + */ +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; + BOOL ret; + LARGE_INTEGER offset; + ULONG cbWritten; + + TRACE("(%p)-> %i %p %i %p\n",This, ulOffset.u.LowPart, pv, cb, pcbWritten); + + /* verify a sane environment */ + if (!This) return E_FAIL; + + if (This->flProtect != PAGE_READWRITE) + return STG_E_ACCESSDENIED; + + if (pcbWritten) + *pcbWritten = 0; + + if (size_needed > This->filesize.u.LowPart) + { + ULARGE_INTEGER newSize; + newSize.u.HighPart = 0; + newSize.u.LowPart = size_needed; + ILockBytes_SetSize(iface, newSize); + } + + offset.QuadPart = ulOffset.QuadPart; + + ret = SetFilePointerEx(This->hfile, offset, NULL, FILE_BEGIN); + + if (!ret) + return STG_E_READFAULT; + + while (bytes_left) + { + ret = WriteFile(This->hfile, writePtr, bytes_left, &cbWritten, NULL); + + if (!ret) + return STG_E_READFAULT; + + if (pcbWritten) + *pcbWritten += cbWritten; + + bytes_left -= cbWritten; + writePtr += cbWritten; + } + + TRACE("finished\n"); + return S_OK; +} + +static HRESULT WINAPI FileLockBytesImpl_Flush(ILockBytes* iface) +{ + return S_OK; +} + +/****************************************************************************** + * ILockBytes_SetSize + * + * Sets the size of the file. + * + */ +static HRESULT WINAPI FileLockBytesImpl_SetSize(ILockBytes* iface, ULARGE_INTEGER newSize) +{ + FileLockBytesImpl* This = (FileLockBytesImpl*)iface; + HRESULT hr = S_OK; + LARGE_INTEGER newpos; + + if (This->filesize.u.LowPart == newSize.u.LowPart) + return hr; + + TRACE("from %u to %u\n", This->filesize.u.LowPart, newSize.u.LowPart); + + newpos.QuadPart = newSize.QuadPart; + if (SetFilePointerEx(This->hfile, newpos, NULL, FILE_BEGIN)) + { + SetEndOfFile(This->hfile); + } + + This->filesize = newSize; + return hr; +} + +static HRESULT WINAPI FileLockBytesImpl_LockRegion(ILockBytes* iface, + ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) +{ + 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)) + { + FIXME("reading filename not supported\n"); + } + + 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 = { + FileLockBytesImpl_QueryInterface, + FileLockBytesImpl_AddRef, + FileLockBytesImpl_Release, + FileLockBytesImpl_ReadAt, + FileLockBytesImpl_WriteAt, + FileLockBytesImpl_Flush, + FileLockBytesImpl_SetSize, + FileLockBytesImpl_LockRegion, + FileLockBytesImpl_UnlockRegion, + FileLockBytesImpl_Stat +}; diff --git a/dlls/ole32/stg_bigblockfile.c b/dlls/ole32/stg_bigblockfile.c deleted file mode 100644 index 7a98c14..0000000 --- a/dlls/ole32/stg_bigblockfile.c +++ /dev/null @@ -1,407 +0,0 @@ -/****************************************************************************** - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include -#include -#include -#include -#include -#include - -#define COBJMACROS -#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. - */ - -struct BigBlockFile -{ - BOOL fileBased; - ULARGE_INTEGER filesize; - HANDLE hfile; - DWORD flProtect; - ILockBytes *pLkbyt; -}; - -/*********************************************************** - * Prototypes for private methods - */ - -/* 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)) - -/****************************************************************************** - * 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 - * - * 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) -{ - switch(STGM_ACCESS_MODE(openFlags)) - { - case STGM_WRITE: - case STGM_READWRITE: - return PAGE_READWRITE; - } - return PAGE_READONLY; -} - - -/* ILockByte Interfaces */ - -/****************************************************************************** - * This method is part of the ILockBytes interface. - * - * It reads a block of information from the byte array at the specified - * offset. - * - * See the documentation of ILockBytes for more info. - */ -static HRESULT ImplBIGBLOCKFILE_ReadAt( - BigBlockFile* const This, - ULARGE_INTEGER ulOffset, /* [in] */ - void* pv, /* [length_is][size_is][out] */ - ULONG cb, /* [in] */ - ULONG* pcbRead) /* [out] */ -{ - ULONG bytes_left = cb; - LPBYTE readPtr = pv; - BOOL ret; - LARGE_INTEGER offset; - ULONG cbRead; - - TRACE("(%p)-> %i %p %i %p\n",This, ulOffset.u.LowPart, pv, cb, pcbRead); - - /* verify a sane environment */ - if (!This) return E_FAIL; - - if (pcbRead) - *pcbRead = 0; - - offset.QuadPart = ulOffset.QuadPart; - - ret = SetFilePointerEx(This->hfile, offset, NULL, FILE_BEGIN); - - if (!ret) - return STG_E_READFAULT; - - while (bytes_left) - { - ret = ReadFile(This->hfile, readPtr, bytes_left, &cbRead, NULL); - - if (!ret || cbRead == 0) - return STG_E_READFAULT; - - if (pcbRead) - *pcbRead += cbRead; - - bytes_left -= cbRead; - readPtr += cbRead; - } - - TRACE("finished\n"); - return S_OK; -} - -/****************************************************************************** - * This method is part of the ILockBytes interface. - * - * It writes the specified bytes at the specified offset. - * position. If the file is too small, it will be resized. - * - * See the documentation of ILockBytes for more info. - */ -static HRESULT ImplBIGBLOCKFILE_WriteAt( - BigBlockFile* const This, - ULARGE_INTEGER ulOffset, /* [in] */ - const void* pv, /* [size_is][in] */ - ULONG cb, /* [in] */ - ULONG* pcbWritten) /* [out] */ -{ - ULONG size_needed = ulOffset.u.LowPart + cb; - ULONG bytes_left = cb; - const BYTE *writePtr = pv; - BOOL ret; - LARGE_INTEGER offset; - ULONG cbWritten; - - TRACE("(%p)-> %i %p %i %p\n",This, ulOffset.u.LowPart, pv, cb, pcbWritten); - - /* verify a sane environment */ - if (!This) return E_FAIL; - - if (This->flProtect != PAGE_READWRITE) - return STG_E_ACCESSDENIED; - - if (pcbWritten) - *pcbWritten = 0; - - if (size_needed > This->filesize.u.LowPart) - { - ULARGE_INTEGER newSize; - newSize.u.HighPart = 0; - newSize.u.LowPart = size_needed; - BIGBLOCKFILE_SetSize(This, newSize); - } - - offset.QuadPart = ulOffset.QuadPart; - - ret = SetFilePointerEx(This->hfile, offset, NULL, FILE_BEGIN); - - if (!ret) - return STG_E_READFAULT; - - while (bytes_left) - { - ret = WriteFile(This->hfile, writePtr, bytes_left, &cbWritten, NULL); - - if (!ret) - return STG_E_READFAULT; - - if (pcbWritten) - *pcbWritten += cbWritten; - - bytes_left -= cbWritten; - writePtr += cbWritten; - } - - TRACE("finished\n"); - 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) -{ - 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; -} - -/****************************************************************************** - * 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 - * - * Sets the size of the file. - * - */ -HRESULT BIGBLOCKFILE_SetSize(BigBlockFile *This, ULARGE_INTEGER newSize) -{ - 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; - - TRACE("from %u to %u\n", This->filesize.u.LowPart, newSize.u.LowPart); - - newpos.QuadPart = newSize.QuadPart; - if (SetFilePointerEx(This->hfile, newpos, NULL, FILE_BEGIN)) - { - SetEndOfFile(This->hfile); - } - - This->filesize = newSize; - return hr; -} - -/****************************************************************************** - * BIGBLOCKFILE_GetSize - * - * Gets the size of the file. - * - */ -static HRESULT BIGBLOCKFILE_GetSize(BigBlockFile *This, ULARGE_INTEGER *size) -{ - HRESULT hr = S_OK; - if(This->fileBased) - *size = This->filesize; - else - { - STATSTG stat; - hr = ILockBytes_Stat(This->pLkbyt, &stat, STATFLAG_NONAME); - if(SUCCEEDED(hr)) *size = stat.cbSize; - } - return hr; -} - -/****************************************************************************** - * 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; -} diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c index 15fe143..860f130 100644 --- a/dlls/ole32/storage32.c +++ b/dlls/ole32/storage32.c @@ -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; iblockChainCache[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; diff --git a/dlls/ole32/storage32.h b/dlls/ole32/storage32.h index 524ff7d..335b4bc 100644 --- a/dlls/ole32/storage32.h +++ b/dlls/ole32/storage32.h @@ -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( -- 1.6.3.3