Fixed a few bugs in the OLE storage implementation, added a new set of
trace statements for the OLE storage related methods and introduced a
new debug channel for the storage subsystem.
diff --git a/include/debugdefs.h b/include/debugdefs.h
index 8ca1baf..e390062 100644
--- a/include/debugdefs.h
+++ b/include/debugdefs.h
@@ -132,39 +132,40 @@
int dbch_sound = 121;
int dbch_static = 122;
int dbch_statusbar = 123;
-int dbch_stress = 124;
-int dbch_string = 125;
-int dbch_syscolor = 126;
-int dbch_system = 127;
-int dbch_tab = 128;
-int dbch_tapi = 129;
-int dbch_task = 130;
-int dbch_text = 131;
-int dbch_thread = 132;
-int dbch_thunk = 133;
-int dbch_timer = 134;
-int dbch_toolbar = 135;
-int dbch_toolhelp = 136;
-int dbch_tooltips = 137;
-int dbch_trackbar = 138;
-int dbch_treeview = 139;
-int dbch_ttydrv = 140;
-int dbch_tweak = 141;
-int dbch_updown = 142;
-int dbch_ver = 143;
-int dbch_virtual = 144;
-int dbch_vxd = 145;
-int dbch_wave = 146;
-int dbch_win = 147;
-int dbch_win16drv = 148;
-int dbch_win32 = 149;
-int dbch_wing = 150;
-int dbch_winsock = 151;
-int dbch_wnet = 152;
-int dbch_x11 = 153;
-int dbch_x11drv = 154;
+int dbch_storage = 124;
+int dbch_stress = 125;
+int dbch_string = 126;
+int dbch_syscolor = 127;
+int dbch_system = 128;
+int dbch_tab = 129;
+int dbch_tapi = 130;
+int dbch_task = 131;
+int dbch_text = 132;
+int dbch_thread = 133;
+int dbch_thunk = 134;
+int dbch_timer = 135;
+int dbch_toolbar = 136;
+int dbch_toolhelp = 137;
+int dbch_tooltips = 138;
+int dbch_trackbar = 139;
+int dbch_treeview = 140;
+int dbch_ttydrv = 141;
+int dbch_tweak = 142;
+int dbch_updown = 143;
+int dbch_ver = 144;
+int dbch_virtual = 145;
+int dbch_vxd = 146;
+int dbch_wave = 147;
+int dbch_win = 148;
+int dbch_win16drv = 149;
+int dbch_win32 = 150;
+int dbch_wing = 151;
+int dbch_winsock = 152;
+int dbch_wnet = 153;
+int dbch_x11 = 154;
+int dbch_x11drv = 155;
-#define DEBUG_CHANNEL_COUNT 155
+#define DEBUG_CHANNEL_COUNT 156
char debug_msg_enabled[DEBUG_CHANNEL_COUNT][DEBUG_CLASS_COUNT] = {
{1, 1, 0, 0},
@@ -321,6 +322,7 @@
{1, 1, 0, 0},
{1, 1, 0, 0},
{1, 1, 0, 0},
+{1, 1, 0, 0},
{1, 1, 0, 0}
};
@@ -449,6 +451,7 @@
"sound",
"static",
"statusbar",
+"storage",
"stress",
"string",
"syscolor",
diff --git a/ole/hglobalstream.c b/ole/hglobalstream.c
index 03fcb3d..7d8049a 100644
--- a/ole/hglobalstream.c
+++ b/ole/hglobalstream.c
@@ -17,7 +17,7 @@
#include "objbase.h"
-DEFAULT_DEBUG_CHANNEL(ole)
+DEFAULT_DEBUG_CHANNEL(storage)
/****************************************************************************
* HGLOBALStreamImpl definition.
@@ -252,6 +252,8 @@
*/
void HGLOBALStreamImpl_Destroy(HGLOBALStreamImpl* This)
{
+ TRACE(storage, "(%p)\n", This);
+
/*
* Release the HGlobal if the constructor asked for that.
*/
@@ -376,6 +378,9 @@
void* supportBuffer;
ULONG bytesReadBuffer;
ULONG bytesToReadFromBuffer;
+
+ TRACE(storage, "(%p, %p, %ld, %p)\n", iface,
+ pv, cb, pcbRead);
/*
* If the caller is not interested in the nubmer of bytes read,
@@ -444,6 +449,9 @@
void* supportBuffer;
ULARGE_INTEGER newSize;
ULONG bytesWritten = 0;
+
+ TRACE(storage, "(%p, %p, %ld, %p)\n", iface,
+ pv, cb, pcbWritten);
/*
* If the caller is not interested in the number of bytes written,
@@ -468,7 +476,7 @@
if (newSize.LowPart > This->streamSize.LowPart)
{
/* grow stream */
- HGLOBALStreamImpl_SetSize(iface, newSize);
+ IStream_SetSize(iface, newSize);
}
/*
@@ -514,6 +522,9 @@
ULARGE_INTEGER newPosition;
+ TRACE(storage, "(%p, %ld, %ld, %p)\n", iface,
+ dlibMove.LowPart, dwOrigin, plibNewPosition);
+
/*
* The caller is allowed to pass in NULL as the new position return value.
* If it happens, we assign it to a dynamic variable to avoid special cases
@@ -587,6 +598,8 @@
{
HGLOBALStreamImpl* const This=(HGLOBALStreamImpl*)iface;
+ TRACE(storage, "(%p, %ld)\n", iface, libNewSize.LowPart);
+
/*
* As documented.
*/
@@ -628,6 +641,9 @@
ULARGE_INTEGER totalBytesRead;
ULARGE_INTEGER totalBytesWritten;
+ TRACE(storage, "(%p, %p, %ld, %p, %p)\n", iface, pstm,
+ cb.LowPart, pcbRead, pcbWritten);
+
/*
* Sanity check
*/
@@ -649,24 +665,27 @@
else
copySize = cb.LowPart;
- HGLOBALStreamImpl_Read(iface, tmpBuffer, 128, &bytesRead);
+ IStream_Read(iface, tmpBuffer, copySize, &bytesRead);
totalBytesRead.LowPart += bytesRead;
- HGLOBALStreamImpl_Write(pstm, tmpBuffer, bytesRead, &bytesWritten);
+ IStream_Write(pstm, tmpBuffer, bytesRead, &bytesWritten);
totalBytesWritten.LowPart += bytesWritten;
/*
* Check that read & write operations were succesfull
*/
- if ( (bytesRead != copySize) && (bytesWritten != copySize) )
+ if (bytesRead != bytesWritten)
{
hr = STG_E_MEDIUMFULL;
break;
}
- cb.LowPart = cb.LowPart - copySize;
+ if (bytesRead!=copySize)
+ cb.LowPart = 0;
+ else
+ cb.LowPart -= bytesRead;
}
/*
@@ -777,6 +796,6 @@
IStream* iface,
IStream** ppstm) /* [out] */
{
- FIXME(ole, "not implemented!\n");
+ FIXME(storage, "not implemented!\n");
return E_NOTIMPL;
}
diff --git a/ole/stg_stream.c b/ole/stg_stream.c
index 7eba790..2ef6bd2 100644
--- a/ole/stg_stream.c
+++ b/ole/stg_stream.c
@@ -20,7 +20,7 @@
#include "storage32.h"
-DEFAULT_DEBUG_CHANNEL(ole)
+DEFAULT_DEBUG_CHANNEL(storage)
/*
@@ -113,6 +113,8 @@
*/
void StgStreamImpl_Destroy(StgStreamImpl* This)
{
+ TRACE(storage, "(%p)\n", This);
+
/*
* Release the reference we are holding on the parent storage.
*/
@@ -314,7 +316,10 @@
ULONG bytesReadBuffer;
ULONG bytesToReadFromBuffer;
-
+
+ TRACE(storage, "(%p, %p, %ld, %p)\n",
+ iface, pv, cb, pcbRead);
+
/*
* If the caller is not interested in the nubmer of bytes read,
* we use another buffer to avoid "if" statements in the code.
@@ -394,6 +399,9 @@
ULARGE_INTEGER newSize;
ULONG bytesWritten = 0;
+
+ TRACE(storage, "(%p, %p, %ld, %p)\n",
+ iface, pv, cb, pcbWritten);
/*
* If the caller is not interested in the number of bytes written,
@@ -402,6 +410,11 @@
if (pcbWritten == 0)
pcbWritten = &bytesWritten;
+ /*
+ * Initialize the out parameter
+ */
+ *pcbWritten = 0;
+
if (cb == 0)
{
return S_OK;
@@ -418,7 +431,7 @@
if (newSize.LowPart > This->streamSize.LowPart)
{
/* grow stream */
- StgStreamImpl_SetSize(iface, newSize);
+ IStream_SetSize(iface, newSize);
}
/*
@@ -471,6 +484,9 @@
ULARGE_INTEGER newPosition;
+ TRACE(storage, "(%p, %ld, %ld, %p)\n",
+ iface, dlibMove.LowPart, dwOrigin, plibNewPosition);
+
/*
* The caller is allowed to pass in NULL as the new position return value.
* If it happens, we assign it to a dynamic variable to avoid special cases
@@ -547,6 +563,8 @@
StgProperty curProperty;
BOOL Success;
+ TRACE(storage, "(%p, %ld)\n", iface, libNewSize.LowPart);
+
/*
* As documented.
*/
@@ -584,9 +602,9 @@
&curProperty);
/*
* Determine if we have to switch from small to big blocks or vice versa
- */
-
- if (curProperty.size.LowPart < LIMIT_TO_USE_SMALL_BLOCK)
+ */
+ if ( (This->smallBlockChain!=0) &&
+ (curProperty.size.LowPart < LIMIT_TO_USE_SMALL_BLOCK) )
{
if (libNewSize.LowPart >= LIMIT_TO_USE_SMALL_BLOCK)
{
@@ -650,6 +668,9 @@
ULARGE_INTEGER totalBytesRead;
ULARGE_INTEGER totalBytesWritten;
+ TRACE(storage, "(%p, %p, %ld, %p, %p)\n",
+ iface, pstm, cb.LowPart, pcbRead, pcbWritten);
+
/*
* Sanity check
*/
@@ -671,24 +692,27 @@
else
copySize = cb.LowPart;
- StgStreamImpl_Read(iface, tmpBuffer, 128, &bytesRead);
+ IStream_Read(iface, tmpBuffer, copySize, &bytesRead);
totalBytesRead.LowPart += bytesRead;
- StgStreamImpl_Write(pstm, tmpBuffer, bytesRead, &bytesWritten);
+ IStream_Write(pstm, tmpBuffer, bytesRead, &bytesWritten);
totalBytesWritten.LowPart += bytesWritten;
/*
* Check that read & write operations were succesfull
*/
- if ( (bytesRead != copySize) && (bytesWritten != copySize) )
+ if (bytesRead != bytesWritten)
{
hr = STG_E_MEDIUMFULL;
break;
}
- cb.LowPart = cb.LowPart - copySize;
+ if (bytesRead!=copySize)
+ cb.LowPart = 0;
+ else
+ cb.LowPart -= bytesRead;
}
/*
@@ -743,7 +767,7 @@
ULARGE_INTEGER cb, /* [in] */
DWORD dwLockType) /* [in] */
{
- FIXME(ole, "not implemented!\n");
+ FIXME(storage, "not implemented!\n");
return E_NOTIMPL;
}
@@ -753,7 +777,7 @@
ULARGE_INTEGER cb, /* [in] */
DWORD dwLockType) /* [in] */
{
- FIXME(ole, "not implemented!\n");
+ FIXME(storage, "not implemented!\n");
return E_NOTIMPL;
}
@@ -798,6 +822,6 @@
IStream* iface,
IStream** ppstm) /* [out] */
{
- FIXME(ole, "not implemented!\n");
+ FIXME(storage, "not implemented!\n");
return E_NOTIMPL;
}
diff --git a/ole/storage32.c b/ole/storage32.c
index 3b585df..ca5189e 100644
--- a/ole/storage32.c
+++ b/ole/storage32.c
@@ -27,7 +27,7 @@
#include "storage32.h"
#include "ole2.h"
-DEFAULT_DEBUG_CHANNEL(ole)
+DEFAULT_DEBUG_CHANNEL(storage)
#define FILE_BEGIN 0
@@ -270,9 +270,9 @@
HRESULT WINAPI StorageBaseImpl_OpenStream(
IStorage* iface,
const OLECHAR* pwcsName, /* [string][in] */
- void* reserved1, /* [unique][in] */
- DWORD grfMode, /* [in] */
- DWORD reserved2, /* [in] */
+ void* reserved1, /* [unique][in] */
+ DWORD grfMode, /* [in] */
+ DWORD reserved2, /* [in] */
IStream** ppstm) /* [out] */
{
ICOM_THIS(StorageBaseImpl,iface);
@@ -281,6 +281,9 @@
StgProperty currentProperty;
ULONG foundPropertyIndex;
+ TRACE(storage, "(%p, %s, %p, %lx, %ld, %p)\n",
+ iface, debugstr_w(pwcsName), reserved1, grfMode, reserved2, ppstm);
+
/*
* Perform a sanity check on the parameters.
*/
@@ -364,9 +367,9 @@
IStorage* iface,
const OLECHAR* pwcsName, /* [string][unique][in] */
IStorage* pstgPriority, /* [unique][in] */
- DWORD grfMode, /* [in] */
+ DWORD grfMode, /* [in] */
SNB snbExclude, /* [unique][in] */
- DWORD reserved, /* [in] */
+ DWORD reserved, /* [in] */
IStorage** ppstg) /* [out] */
{
ICOM_THIS(StorageBaseImpl,iface);
@@ -374,6 +377,10 @@
IEnumSTATSTGImpl* propertyEnumeration;
StgProperty currentProperty;
ULONG foundPropertyIndex;
+
+ TRACE(storage, "(%p, %s, %p, %lx, %p, %ld, %p)\n",
+ iface, debugstr_w(pwcsName), pstgPriority,
+ grfMode, snbExclude, reserved, ppstg);
/*
* Perform a sanity check on the parameters.
@@ -461,15 +468,18 @@
* See Windows documentation for more details on IStorage methods.
*/
HRESULT WINAPI StorageBaseImpl_EnumElements(
- IStorage* iface,
- DWORD reserved1, /* [in] */
- void* reserved2, /* [size_is][unique][in] */
- DWORD reserved3, /* [in] */
- IEnumSTATSTG** ppenum) /* [out] */
+ IStorage* iface,
+ DWORD reserved1, /* [in] */
+ void* reserved2, /* [size_is][unique][in] */
+ DWORD reserved3, /* [in] */
+ IEnumSTATSTG** ppenum) /* [out] */
{
ICOM_THIS(StorageBaseImpl,iface);
IEnumSTATSTGImpl* newEnum;
+ TRACE(storage, "(%p, %ld, %p, %ld, %p)\n",
+ iface, reserved1, reserved2, reserved3, ppenum);
+
/*
* Perform a sanity check on the parameters.
*/
@@ -508,13 +518,16 @@
*/
HRESULT WINAPI StorageBaseImpl_Stat(
IStorage* iface,
- STATSTG* pstatstg, /* [out] */
- DWORD grfStatFlag) /* [in] */
+ STATSTG* pstatstg, /* [out] */
+ DWORD grfStatFlag) /* [in] */
{
ICOM_THIS(StorageBaseImpl,iface);
StgProperty curProperty;
BOOL readSucessful;
+ TRACE(storage, "(%p, %p, %lx)\n",
+ iface, pstatstg, grfStatFlag);
+
/*
* Perform a sanity check on the parameters.
*/
@@ -563,6 +576,9 @@
StgProperty currentProperty;
ULONG foundPropertyIndex;
+ TRACE(storage, "(%p, %s, %s)\n",
+ iface, debugstr_w(pwcsOldName), debugstr_w(pwcsNewName));
+
/*
* Create a property enumeration to search the properties
*/
@@ -704,9 +720,9 @@
HRESULT WINAPI StorageBaseImpl_CreateStream(
IStorage* iface,
const OLECHAR* pwcsName, /* [string][in] */
- DWORD grfMode, /* [in] */
- DWORD reserved1, /* [in] */
- DWORD reserved2, /* [in] */
+ DWORD grfMode, /* [in] */
+ DWORD reserved1, /* [in] */
+ DWORD reserved2, /* [in] */
IStream** ppstm) /* [out] */
{
ICOM_THIS(StorageBaseImpl,iface);
@@ -715,6 +731,10 @@
StgProperty currentProperty, newStreamProperty;
ULONG foundPropertyIndex, newPropertyIndex;
+ TRACE(storage, "(%p, %s, %lx, %ld, %ld, %p)\n",
+ iface, debugstr_w(pwcsName), grfMode,
+ reserved1, reserved2, ppstm);
+
/*
* Validate parameters
*/
@@ -761,7 +781,9 @@
* An element with this name already exists
*/
if (grfMode & STGM_CREATE)
- StorageImpl_DestroyElement((IStorage*)This->ancestorStorage, pwcsName);
+ {
+ IStorage_DestroyElement(iface, pwcsName);
+ }
else
return STG_E_FILEALREADYEXISTS;
}
@@ -851,12 +873,14 @@
*/
HRESULT WINAPI StorageBaseImpl_SetClass(
IStorage* iface,
- REFCLSID clsid) /* [in] */
+ REFCLSID clsid) /* [in] */
{
ICOM_THIS(StorageBaseImpl,iface);
HRESULT hRes = E_FAIL;
StgProperty curProperty;
BOOL success;
+
+ TRACE(storage, "(%p, %p)\n", iface, clsid);
success = StorageImpl_ReadProperty(This->ancestorStorage,
This->rootPropertySetIndex,
@@ -903,6 +927,9 @@
ULONG newPropertyIndex;
HRESULT hr;
+ TRACE(storage, "(%p, %s, %lx, %ld, %ld, %p)\n",
+ iface, debugstr_w(pwcsName), grfMode,
+ reserved1, reserved2, ppstg);
/*
* Validate parameters
@@ -942,7 +969,7 @@
* An element with this name already exists
*/
if (grfMode & STGM_CREATE)
- StorageImpl_DestroyElement((IStorage*)This->ancestorStorage, pwcsName);
+ IStorage_DestroyElement(iface, pwcsName);
else
return STG_E_FILEALREADYEXISTS;
}
@@ -1001,7 +1028,7 @@
/*
* Open it to get a pointer to return.
*/
- hr = StorageBaseImpl_OpenStorage(
+ hr = IStorage_OpenStorage(
iface,
(OLECHAR*)pwcsName,
0,
@@ -1212,7 +1239,7 @@
found = 1;
}
}
- else
+ else if (diff > 0)
{
if (next != PROPERTY_NULL)
{
@@ -1230,6 +1257,14 @@
found = 1;
}
}
+ else
+ {
+ /*
+ * Trying to insert an item with the same name in the
+ * subtree structure.
+ */
+ assert(FALSE);
+ }
previous = currentProperty.previousProperty;
next = currentProperty.nextProperty;
@@ -1253,10 +1288,10 @@
*/
HRESULT WINAPI StorageImpl_CopyTo(
IStorage* iface,
- DWORD ciidExclude, /* [in] */
- const IID *rgiidExclude,/* [size_is][unique][in] */
+ DWORD ciidExclude, /* [in] */
+ const IID* rgiidExclude, /* [size_is][unique][in] */
SNB snbExclude, /* [unique][in] */
- IStorage *pstgDest) /* [unique][in] */
+ IStorage* pstgDest) /* [unique][in] */
{
IEnumSTATSTG *elements = 0;
STATSTG curElement, strStat;
@@ -1265,7 +1300,11 @@
IStream *pstrTmp, *pstrChild;
if ((ciidExclude != 0) || (rgiidExclude != NULL) || (snbExclude != NULL))
- FIXME( ole, "Exclude option not implemented\n");
+ FIXME( storage, "Exclude option not implemented\n");
+
+ TRACE(storage, "(%p, %ld, %p, %p, %p)\n",
+ iface, ciidExclude, rgiidExclude,
+ snbExclude, pstgDest);
/*
* Perform a sanity check
@@ -1284,7 +1323,7 @@
/*
* set the class ID
*/
- StorageBaseImpl_Stat( iface, &curElement, STATFLAG_NONAME);
+ IStorage_Stat( iface, &curElement, STATFLAG_NONAME);
IStorage_SetClass( pstgDest, &curElement.clsid );
do
@@ -1305,9 +1344,9 @@
/*
* open child source storage
*/
- hr = StorageBaseImpl_OpenStorage( iface, curElement.pwcsName, NULL,
- STGM_READ|STGM_SHARE_EXCLUSIVE,
- NULL, 0, &pstgChild );
+ hr = IStorage_OpenStorage( iface, curElement.pwcsName, NULL,
+ STGM_READ|STGM_SHARE_EXCLUSIVE,
+ NULL, 0, &pstgChild );
if (hr != S_OK)
break;
@@ -1327,7 +1366,8 @@
* create a new storage in destination storage
*/
hr = IStorage_CreateStorage( pstgDest, curElement.pwcsName,
- STGM_FAILIFTHERE|STGM_WRITE, 0, 0,
+ STGM_FAILIFTHERE|STGM_WRITE|STGM_SHARE_EXCLUSIVE,
+ 0, 0,
&pstgTmp );
/*
* if it already exist, don't create a new one use this one
@@ -1368,17 +1408,22 @@
/*
* open child stream storage
*/
- hr = StorageBaseImpl_OpenStream( iface, curElement.pwcsName, NULL,
- STGM_READ|STGM_SHARE_EXCLUSIVE,
- 0, &pstrChild );
+ hr = IStorage_OpenStream( iface, curElement.pwcsName, NULL,
+ STGM_READ|STGM_SHARE_EXCLUSIVE,
+ 0, &pstrChild );
if (hr != S_OK)
break;
/*
- * Get the size of the stream
+ * Get the size of the source stream
*/
IStream_Stat( pstrChild, &strStat, STATFLAG_NONAME );
+
+ /*
+ * Set the size of the destination stream.
+ */
+ IStream_SetSize(pstrTmp, strStat.cbSize);
/*
* do the copy
@@ -1391,7 +1436,7 @@
}
else
{
- WARN(ole, "unknown element type: %ld\n", curElement.type);
+ WARN(storage, "unknown element type: %ld\n", curElement.type);
}
} while (hr == S_OK);
@@ -1414,7 +1459,7 @@
const OLECHAR *pwcsNewName,/* [string][in] */
DWORD grfFlags) /* [in] */
{
- FIXME(ole, "not implemented!\n");
+ FIXME(storage, "not implemented!\n");
return E_NOTIMPL;
}
@@ -1425,7 +1470,7 @@
IStorage* iface,
DWORD grfCommitFlags)/* [in] */
{
- FIXME(ole, "(%ld): stub!\n", grfCommitFlags);
+ FIXME(storage, "(%ld): stub!\n", grfCommitFlags);
return S_OK;
}
@@ -1435,7 +1480,7 @@
HRESULT WINAPI StorageImpl_Revert(
IStorage* iface)
{
- FIXME(ole, "not implemented!\n");
+ FIXME(storage, "not implemented!\n");
return E_NOTIMPL;
}
@@ -1465,6 +1510,9 @@
ULONG typeOfRelation;
ULONG parentPropertyId;
+ TRACE(storage, "(%p, %s)\n",
+ iface, debugstr_w(pwcsName));
+
/*
* Perform a sanity check on the parameters.
*/
@@ -1680,6 +1728,11 @@
return hr;
}
+ /*
+ * Release the stream object.
+ */
+ IStream_Release(pis);
+
/*
* Invalidate the property by zeroing it's name member.
*/
@@ -1689,7 +1742,6 @@
* Here we should re-read the property so we get the updated pointer
* but since we are here to zap it, I don't do it...
*/
-
StorageImpl_WriteProperty(
parentStorage->ancestorStorage,
indexOfPropertyToDelete,
@@ -1952,7 +2004,7 @@
const FILETIME *patime, /* [in] */
const FILETIME *pmtime) /* [in] */
{
- FIXME(ole, "not implemented!\n");
+ FIXME(storage, "not implemented!\n");
return E_NOTIMPL;
}
@@ -1964,7 +2016,7 @@
DWORD grfStateBits,/* [in] */
DWORD grfMask) /* [in] */
{
- FIXME(ole, "not implemented!\n");
+ FIXME(storage, "not implemented!\n");
return E_NOTIMPL;
}
@@ -2159,6 +2211,8 @@
void StorageImpl_Destroy(
StorageImpl* This)
{
+ TRACE(storage, "(%p)\n", This);
+
BlockChainStream_Destroy(This->smallBlockRootChain);
BlockChainStream_Destroy(This->rootBlockChain);
BlockChainStream_Destroy(This->smallBlockDepotChain);
@@ -4004,12 +4058,17 @@
BYTE* bufferWalker;
BYTE* bigBlockBuffer;
- if (This->lastBlockNoInSequence == 0xFFFFFFFF)
- This->lastBlockNoInSequence = blockNoInSequence;
/*
* Find the first block in the stream that contains part of the buffer.
*/
- if (blockNoInSequence > This->lastBlockNoInSequence)
+ if ( (This->lastBlockNoInSequence == 0xFFFFFFFF) ||
+ (This->lastBlockNoInSequenceIndex == BLOCK_END_OF_CHAIN) ||
+ (blockNoInSequence < This->lastBlockNoInSequence) )
+ {
+ blockIndex = BlockChainStream_GetHeadOfChain(This);
+ This->lastBlockNoInSequence = blockNoInSequence;
+ }
+ else
{
ULONG temp = blockNoInSequence;
@@ -4017,11 +4076,6 @@
blockNoInSequence -= This->lastBlockNoInSequence;
This->lastBlockNoInSequence = temp;
}
- else
- {
- blockIndex = BlockChainStream_GetHeadOfChain(This);
- This->lastBlockNoInSequence = blockNoInSequence;
- }
while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN))
{
@@ -4093,13 +4147,17 @@
BYTE* bufferWalker;
BYTE* bigBlockBuffer;
- if (This->lastBlockNoInSequence == 0xFFFFFFFF)
- This->lastBlockNoInSequence = blockNoInSequence;
-
/*
* Find the first block in the stream that contains part of the buffer.
*/
- if (blockNoInSequence > This->lastBlockNoInSequence)
+ if ( (This->lastBlockNoInSequence == 0xFFFFFFFF) ||
+ (This->lastBlockNoInSequenceIndex == BLOCK_END_OF_CHAIN) ||
+ (blockNoInSequence < This->lastBlockNoInSequence) )
+ {
+ blockIndex = BlockChainStream_GetHeadOfChain(This);
+ This->lastBlockNoInSequence = blockNoInSequence;
+ }
+ else
{
ULONG temp = blockNoInSequence;
@@ -4107,11 +4165,6 @@
blockNoInSequence -= This->lastBlockNoInSequence;
This->lastBlockNoInSequence = temp;
}
- else
- {
- blockIndex = BlockChainStream_GetHeadOfChain(This);
- This->lastBlockNoInSequence = blockNoInSequence;
- }
while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN))
{
@@ -4175,6 +4228,12 @@
ULONG count = 1;
/*
+ * Reset the last accessed block cache.
+ */
+ This->lastBlockNoInSequence = 0xFFFFFFFF;
+ This->lastBlockNoInSequenceIndex = BLOCK_END_OF_CHAIN;
+
+ /*
* Figure out how many blocks are needed to contain the new size
*/
numBlocks = newSize.LowPart / This->parentStorage->bigBlockSize;
@@ -4306,27 +4365,30 @@
/*
* Add new blocks to the chain
*/
- while (oldNumBlocks < newNumBlocks)
+ if (oldNumBlocks < newNumBlocks)
{
- blockIndex = StorageImpl_GetNextFreeBigBlock(This->parentStorage);
+ while (oldNumBlocks < newNumBlocks)
+ {
+ blockIndex = StorageImpl_GetNextFreeBigBlock(This->parentStorage);
- StorageImpl_SetNextBlockInChain(
- This->parentStorage,
- currentBlock,
- blockIndex);
+ StorageImpl_SetNextBlockInChain(
+ This->parentStorage,
+ currentBlock,
+ blockIndex);
- StorageImpl_SetNextBlockInChain(
- This->parentStorage,
- blockIndex,
- BLOCK_END_OF_CHAIN);
+ StorageImpl_SetNextBlockInChain(
+ This->parentStorage,
+ blockIndex,
+ BLOCK_END_OF_CHAIN);
- currentBlock = blockIndex;
- oldNumBlocks++;
+ currentBlock = blockIndex;
+ oldNumBlocks++;
+ }
+
+ This->tailIndex = blockIndex;
+ This->numBlocks = newNumBlocks;
}
- This->tailIndex = blockIndex;
- This->numBlocks = newNumBlocks;
-
return TRUE;
}
@@ -4902,7 +4964,7 @@
{
ULONG blockIndex, extraBlock;
ULONG numBlocks;
- ULONG count = 1;
+ ULONG count = 0;
numBlocks = newSize.LowPart / This->parentStorage->smallBlockSize;
@@ -4920,14 +4982,40 @@
count++;
}
- /* Get the next block before marking the new end */
- extraBlock = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex);
+ /*
+ * If the count is 0, we have a special case, the head of the chain was
+ * just freed.
+ */
+ if (count == 0)
+ {
+ StgProperty chainProp;
- /* Mark the new end of chain */
- SmallBlockChainStream_SetNextBlockInChain(
- This,
- blockIndex,
- BLOCK_END_OF_CHAIN);
+ StorageImpl_ReadProperty(This->parentStorage,
+ This->ownerPropertyIndex,
+ &chainProp);
+
+ chainProp.startingBlock = BLOCK_END_OF_CHAIN;
+
+ StorageImpl_WriteProperty(This->parentStorage,
+ This->ownerPropertyIndex,
+ &chainProp);
+
+ /*
+ * We start freeing the chain at the head block.
+ */
+ extraBlock = blockIndex;
+ }
+ else
+ {
+ /* Get the next block before marking the new end */
+ extraBlock = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex);
+
+ /* Mark the new end of chain */
+ SmallBlockChainStream_SetNextBlockInChain(
+ This,
+ blockIndex,
+ BLOCK_END_OF_CHAIN);
+ }
/*
* Mark the extra blocks as free
@@ -4962,6 +5050,7 @@
*/
if (blockIndex == BLOCK_END_OF_CHAIN)
{
+
StgProperty chainProp;
StorageImpl_ReadProperty(This->parentStorage, This->ownerPropertyIndex,
@@ -5108,6 +5197,10 @@
DWORD fileAttributes;
WCHAR tempFileName[MAX_PATH];
+ TRACE(storage, "(%s, %lx, %ld, %p)\n",
+ debugstr_w(pwcsName), grfMode,
+ reserved, ppstgOpen);
+
/*
* Validate the parameters
*/
@@ -5153,7 +5246,7 @@
fileAttributes = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS;
if (grfMode & STGM_TRANSACTED)
- FIXME(ole, "Transacted mode not implemented.\n");
+ FIXME(storage, "Transacted mode not implemented.\n");
/*
* Initialize the "out" parameter.
@@ -5220,6 +5313,10 @@
DWORD shareMode;
DWORD accessMode;
+ TRACE(storage, "(%s, %p, %lx, %p, %ld, %p)\n",
+ debugstr_w(pwcsName), pstgPriority, grfMode,
+ snbExclude, reserved, ppstgOpen);
+
/*
* Perform a sanity check
*/
@@ -5313,7 +5410,7 @@
STATSTG pstatstg;
HRESULT hRes;
- TRACE(ole,"()\n");
+ TRACE(storage,"()\n");
if(pclsid==NULL)
return E_POINTER;
@@ -5338,7 +5435,7 @@
CLSID clsid;
HRESULT res;
- FIXME(ole,"(),stub!\n");
+ FIXME(storage,"(),stub!\n");
res=ReadClassStm(pStm,&clsid);
@@ -5365,7 +5462,7 @@
CLSID clsid;
HRESULT res;
- TRACE(ole,"(%p,%p)\n",pPStm,pStm);
+ TRACE(storage,"(%p,%p)\n",pPStm,pStm);
res=IPersistStream_GetClassID(pPStm,&clsid);
@@ -5555,11 +5652,11 @@
if ( stgm & STGM_CREATE)
return CREATE_ALWAYS;
if (stgm & STGM_CONVERT) {
- FIXME(ole, "STGM_CONVERT not implemented!\n");
+ FIXME(storage, "STGM_CONVERT not implemented!\n");
return CREATE_NEW;
}
/* All other cases */
if (stgm & ~ (STGM_CREATE|STGM_CONVERT))
- FIXME(ole,"unhandled storage mode : 0x%08lx\n",stgm & ~ (STGM_CREATE|STGM_CONVERT));
+ FIXME(storage,"unhandled storage mode : 0x%08lx\n",stgm & ~ (STGM_CREATE|STGM_CONVERT));
return CREATE_NEW;
}