ole32: Remove the BigBlockFile abstraction and always use an ILockBytes.
This commit is contained in:
parent
4171499411
commit
14f8f9d5b5
|
@ -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 \
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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(
|
||||||
|
|
Loading…
Reference in New Issue