📄 storage32.c
字号:
propertyToDelete.sizeOfNameString = 0;
/*
* 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->base.ancestorStorage,
indexOfPropertyToDelete,
&propertyToDelete);
return S_OK;
}
/*********************************************************************
*
* Internal Method
*
* Finds a placeholder for the StgProperty within the Storage
*
*/
static HRESULT findPlaceholder(
StorageImpl *storage,
ULONG propertyIndexToStore,
ULONG storePropertyIndex,
INT typeOfRelation)
{
StgProperty storeProperty;
HRESULT hr = S_OK;
BOOL res = TRUE;
/*
* Read the storage property
*/
res = StorageImpl_ReadProperty(
storage->base.ancestorStorage,
storePropertyIndex,
&storeProperty);
if(! res)
{
return E_FAIL;
}
if (typeOfRelation == PROPERTY_RELATION_PREVIOUS)
{
if (storeProperty.previousProperty != PROPERTY_NULL)
{
return findPlaceholder(
storage,
propertyIndexToStore,
storeProperty.previousProperty,
typeOfRelation);
}
else
{
storeProperty.previousProperty = propertyIndexToStore;
}
}
else if (typeOfRelation == PROPERTY_RELATION_NEXT)
{
if (storeProperty.nextProperty != PROPERTY_NULL)
{
return findPlaceholder(
storage,
propertyIndexToStore,
storeProperty.nextProperty,
typeOfRelation);
}
else
{
storeProperty.nextProperty = propertyIndexToStore;
}
}
else if (typeOfRelation == PROPERTY_RELATION_DIR)
{
if (storeProperty.dirProperty != PROPERTY_NULL)
{
return findPlaceholder(
storage,
propertyIndexToStore,
storeProperty.dirProperty,
typeOfRelation);
}
else
{
storeProperty.dirProperty = propertyIndexToStore;
}
}
hr = StorageImpl_WriteProperty(
storage->base.ancestorStorage,
storePropertyIndex,
&storeProperty);
if(! hr)
{
return E_FAIL;
}
return S_OK;
}
/*************************************************************************
*
* Internal Method
*
* This method takes the previous and the next property link of a property
* to be deleted and find them a place in the Storage.
*/
static HRESULT adjustPropertyChain(
StorageImpl *This,
StgProperty propertyToDelete,
StgProperty parentProperty,
ULONG parentPropertyId,
INT typeOfRelation)
{
ULONG newLinkProperty = PROPERTY_NULL;
BOOL needToFindAPlaceholder = FALSE;
ULONG storeNode = PROPERTY_NULL;
ULONG toStoreNode = PROPERTY_NULL;
INT relationType = 0;
HRESULT hr = S_OK;
BOOL res = TRUE;
if (typeOfRelation == PROPERTY_RELATION_PREVIOUS)
{
if (propertyToDelete.previousProperty != PROPERTY_NULL)
{
/*
* Set the parent previous to the property to delete previous
*/
newLinkProperty = propertyToDelete.previousProperty;
if (propertyToDelete.nextProperty != PROPERTY_NULL)
{
/*
* We also need to find a storage for the other link, setup variables
* to do this at the end...
*/
needToFindAPlaceholder = TRUE;
storeNode = propertyToDelete.previousProperty;
toStoreNode = propertyToDelete.nextProperty;
relationType = PROPERTY_RELATION_NEXT;
}
}
else if (propertyToDelete.nextProperty != PROPERTY_NULL)
{
/*
* Set the parent previous to the property to delete next
*/
newLinkProperty = propertyToDelete.nextProperty;
}
/*
* Link it for real...
*/
parentProperty.previousProperty = newLinkProperty;
}
else if (typeOfRelation == PROPERTY_RELATION_NEXT)
{
if (propertyToDelete.previousProperty != PROPERTY_NULL)
{
/*
* Set the parent next to the property to delete next previous
*/
newLinkProperty = propertyToDelete.previousProperty;
if (propertyToDelete.nextProperty != PROPERTY_NULL)
{
/*
* We also need to find a storage for the other link, setup variables
* to do this at the end...
*/
needToFindAPlaceholder = TRUE;
storeNode = propertyToDelete.previousProperty;
toStoreNode = propertyToDelete.nextProperty;
relationType = PROPERTY_RELATION_NEXT;
}
}
else if (propertyToDelete.nextProperty != PROPERTY_NULL)
{
/*
* Set the parent next to the property to delete next
*/
newLinkProperty = propertyToDelete.nextProperty;
}
/*
* Link it for real...
*/
parentProperty.nextProperty = newLinkProperty;
}
else /* (typeOfRelation == PROPERTY_RELATION_DIR) */
{
if (propertyToDelete.previousProperty != PROPERTY_NULL)
{
/*
* Set the parent dir to the property to delete previous
*/
newLinkProperty = propertyToDelete.previousProperty;
if (propertyToDelete.nextProperty != PROPERTY_NULL)
{
/*
* We also need to find a storage for the other link, setup variables
* to do this at the end...
*/
needToFindAPlaceholder = TRUE;
storeNode = propertyToDelete.previousProperty;
toStoreNode = propertyToDelete.nextProperty;
relationType = PROPERTY_RELATION_NEXT;
}
}
else if (propertyToDelete.nextProperty != PROPERTY_NULL)
{
/*
* Set the parent dir to the property to delete next
*/
newLinkProperty = propertyToDelete.nextProperty;
}
/*
* Link it for real...
*/
parentProperty.dirProperty = newLinkProperty;
}
/*
* Write back the parent property
*/
res = StorageImpl_WriteProperty(
This->base.ancestorStorage,
parentPropertyId,
&parentProperty);
if(! res)
{
return E_FAIL;
}
/*
* If a placeholder is required for the other link, then, find one and
* get out of here...
*/
if (needToFindAPlaceholder)
{
hr = findPlaceholder(
This,
toStoreNode,
storeNode,
relationType);
}
return hr;
}
/******************************************************************************
* SetElementTimes (IStorage)
*/
HRESULT WINAPI StorageImpl_SetElementTimes(
IStorage* iface,
const OLECHAR *pwcsName,/* [string][in] */
const FILETIME *pctime, /* [in] */
const FILETIME *patime, /* [in] */
const FILETIME *pmtime) /* [in] */
{
FIXME("(%s,...), stub!\n",debugstr_w(pwcsName));
return S_OK;
}
/******************************************************************************
* SetStateBits (IStorage)
*/
HRESULT WINAPI StorageImpl_SetStateBits(
IStorage* iface,
DWORD grfStateBits,/* [in] */
DWORD grfMask) /* [in] */
{
FIXME("not implemented!\n");
return E_NOTIMPL;
}
/*
* Virtual function table for the IStorage32Impl class.
*/
static const IStorageVtbl Storage32Impl_Vtbl =
{
StorageBaseImpl_QueryInterface,
StorageBaseImpl_AddRef,
StorageBaseImpl_Release,
StorageBaseImpl_CreateStream,
StorageBaseImpl_OpenStream,
StorageImpl_CreateStorage,
StorageBaseImpl_OpenStorage,
StorageImpl_CopyTo,
StorageImpl_MoveElementTo,
StorageImpl_Commit,
StorageImpl_Revert,
StorageBaseImpl_EnumElements,
StorageImpl_DestroyElement,
StorageBaseImpl_RenameElement,
StorageImpl_SetElementTimes,
StorageBaseImpl_SetClass,
StorageImpl_SetStateBits,
StorageImpl_Stat
};
HRESULT StorageImpl_Construct(
StorageImpl* This,
HANDLE hFile,
LPCOLESTR pwcsName,
ILockBytes* pLkbyt,
DWORD openFlags,
BOOL fileBased,
BOOL fileCreate)
{
HRESULT hr = S_OK;
StgProperty currentProperty;
BOOL readSuccessful;
ULONG currentPropertyIndex;
if ( FAILED( validateSTGM(openFlags) ))
return STG_E_INVALIDFLAG;
memset(This, 0, sizeof(StorageImpl));
/*
* Initialize the virtual function table.
*/
This->base.lpVtbl = &Storage32Impl_Vtbl;
This->base.pssVtbl = &IPropertySetStorage_Vtbl;
This->base.v_destructor = &StorageImpl_Destroy;
This->base.openFlags = openFlags;
/*
* This is the top-level storage so initialize the ancestor pointer
* to this.
*/
This->base.ancestorStorage = This;
/*
* Initialize the physical support of the storage.
*/
This->hFile = hFile;
/*
* Store copy of file path.
*/
if(pwcsName) {
This->pwcsName = HeapAlloc(GetProcessHeap(), 0,
(lstrlenW(pwcsName)+1)*sizeof(WCHAR));
if (!This->pwcsName)
return STG_E_INSUFFICIENTMEMORY;
strcpyW(This->pwcsName, pwcsName);
}
/*
* Initialize the big block cache.
*/
This->bigBlockSize = DEF_BIG_BLOCK_SIZE;
This->smallBlockSize = DEF_SMALL_BLOCK_SIZE;
This->bigBlockFile = BIGBLOCKFILE_Construct(hFile,
pLkbyt,
openFlags,
This->bigBlockSize,
fileBased);
if (This->bigBlockFile == 0)
return E_FAIL;
if (fileCreate)
{
ULARGE_INTEGER size;
BYTE* bigBlockBuffer;
/*
* Initialize all header variables:
* - The big block depot consists of one block and it is at block 0
* - The properties start at block 1
* - There is no small block depot
*/
memset( This->bigBlockDepotStart,
BLOCK_UNUSED,
sizeof(This->bigBlockDepotStart));
This->bigBlockDepotCount = 1;
This->bigBlockDepotStart[0] = 0;
This->rootStartBlock = 1;
This->smallBlockDepotStart = BLOCK_END_OF_CHAIN;
This->bigBlockSizeBits = DEF_BIG_BLOCK_SIZE_BITS;
This->smallBlockSizeBits = DEF_SMALL_BLOCK_SIZE_BITS;
This->extBigBlockDepotStart = BLOCK_END_OF_CHAIN;
This->extBigBlockDepotCount = 0;
StorageImpl_SaveFileHeader(This);
/*
* Add one block for the big block depot and one block for the properties
*/
size.u.HighPart = 0;
size.u.LowPart = This->bigBlockSize * 3;
BIGBLOCKFILE_SetSize(This->bigBlockFile, size);
/*
* Initialize the big block depot
*/
bigBlockBuffer = StorageImpl_GetBigBlock(This, 0);
memset(bigBlockBuffer, BLOCK_UNUSED, This->bigBlockSize);
StorageUtl_WriteDWord(bigBlockBuffer, 0, BLOCK_SPECIAL);
StorageUtl_WriteDWord(bigBlockBuffer, sizeof(ULONG), BLOCK_END_OF_CHAIN);
StorageImpl_ReleaseBigBlock(This, bigBlockBuffer);
}
else
{
/*
* Load the header for the file.
*/
hr = StorageImpl_LoadFileHeader(This);
if (FAILED(hr))
{
BIGBLOCKFILE_Destructor(This->bigBlockFile);
return hr;
}
}
/*
* There is no block depot cached yet.
*/
This->indexBlockDepotCached = 0xFFFFFFFF;
/*
* Start searching for free blocks with block 0.
*/
This->prevFreeBlock = 0;
/*
* Create the block chain abstractions.
*/
if(!(This->rootBlockChain =
BlockChainStream_Construct(This, &This->rootStartBlock, PROPERTY_NULL)))
return STG_E_READFAULT;
if(!(This->smallBlockDepotChain =
BlockChainStream_Construct(This, &This->smallBlockDepotStart,
PROPERTY_NULL)))
return STG_E_READFAULT;
/*
* Write the root property
*/
if (fileCreate)
{
StgProperty rootProp;
/*
* Initialize the property chain
*/
memset(&rootProp, 0, sizeof(rootProp));
MultiByteToWideChar( CP_ACP, 0, rootPropertyName, -1, rootProp.name,
sizeof(rootProp.name)/sizeof(WCHAR) );
rootProp.sizeOfNameString = (strlenW(rootProp.name)+1) * sizeof(WCHAR);
rootProp.propertyType = PROPTYPE_ROOT;
rootProp.previousProperty = PROPERTY_NULL;
rootProp.nextProperty = PROPERTY_NULL;
rootProp.dirProperty = PROPERTY_NULL;
rootProp.startingBlock = BLOCK_END_OF_CHAIN;
rootProp.size.u.HighPart = 0;
rootProp.size.u.LowPart = 0;
StorageImpl_WriteProperty(This, 0, &rootProp);
}
/*
* Find the ID of t
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -