📄 storage32.c
字号:
else if ( propertyToDelete.propertyType == PROPTYPE_STREAM )
{
hr = deleteStreamProperty(
This,
foundPropertyIndexToDelete,
propertyToDelete);
}
if (hr!=S_OK)
return hr;
/*
* Adjust the property chain
*/
hr = adjustPropertyChain(
This,
propertyToDelete,
parentProperty,
parentPropertyId,
typeOfRelation);
return hr;
}
/************************************************************************
* StorageImpl_Stat (IStorage)
*
* This method will retrieve information about this storage object.
*
* See Windows documentation for more details on IStorage methods.
*/
static HRESULT WINAPI StorageImpl_Stat( IStorage* iface,
STATSTG* pstatstg, /* [out] */
DWORD grfStatFlag) /* [in] */
{
StorageImpl* const This = (StorageImpl*)iface;
HRESULT result = StorageBaseImpl_Stat( iface, pstatstg, grfStatFlag );
if ( !FAILED(result) && ((grfStatFlag & STATFLAG_NONAME) == 0) && This->pwcsName )
{
CoTaskMemFree(pstatstg->pwcsName);
pstatstg->pwcsName = CoTaskMemAlloc((lstrlenW(This->pwcsName)+1)*sizeof(WCHAR));
strcpyW(pstatstg->pwcsName, This->pwcsName);
}
return result;
}
/******************************************************************************
* Internal stream list handlers
*/
void StorageBaseImpl_AddStream(StorageBaseImpl * stg, StgStreamImpl * strm)
{
TRACE("Stream added (stg=%p strm=%p)\n", stg, strm);
list_add_tail(&stg->strmHead,&strm->StrmListEntry);
}
void StorageBaseImpl_RemoveStream(StorageBaseImpl * stg, StgStreamImpl * strm)
{
TRACE("Stream removed (stg=%p strm=%p)\n", stg,strm);
list_remove(&(strm->StrmListEntry));
}
static void StorageBaseImpl_DeleteAll(StorageBaseImpl * stg)
{
struct list *cur, *cur2;
StgStreamImpl *strm=NULL;
LIST_FOR_EACH_SAFE(cur, cur2, &stg->strmHead) {
strm = LIST_ENTRY(cur,StgStreamImpl,StrmListEntry);
TRACE("Streams deleted (stg=%p strm=%p next=%p prev=%p)\n", stg,strm,cur->next,cur->prev);
strm->parentStorage = NULL;
list_remove(cur);
}
}
/*********************************************************************
*
* Internal Method
*
* Perform the deletion of a complete storage node
*
*/
static HRESULT deleteStorageProperty(
StorageImpl *parentStorage,
ULONG indexOfPropertyToDelete,
StgProperty propertyToDelete)
{
IEnumSTATSTG *elements = 0;
IStorage *childStorage = 0;
STATSTG currentElement;
HRESULT hr;
HRESULT destroyHr = S_OK;
/*
* Open the storage and enumerate it
*/
hr = StorageBaseImpl_OpenStorage(
(IStorage*)parentStorage,
propertyToDelete.name,
0,
STGM_WRITE | STGM_SHARE_EXCLUSIVE,
0,
0,
&childStorage);
if (hr != S_OK)
{
return hr;
}
/*
* Enumerate the elements
*/
IStorage_EnumElements( childStorage, 0, 0, 0, &elements);
do
{
/*
* Obtain the next element
*/
hr = IEnumSTATSTG_Next(elements, 1, ¤tElement, NULL);
if (hr==S_OK)
{
destroyHr = StorageImpl_DestroyElement(
(IStorage*)childStorage,
(OLECHAR*)currentElement.pwcsName);
CoTaskMemFree(currentElement.pwcsName);
}
/*
* We need to Reset the enumeration every time because we delete elements
* and the enumeration could be invalid
*/
IEnumSTATSTG_Reset(elements);
} while ((hr == S_OK) && (destroyHr == S_OK));
/*
* Invalidate the property by zeroing its name member.
*/
propertyToDelete.sizeOfNameString = 0;
StorageImpl_WriteProperty(parentStorage->base.ancestorStorage,
indexOfPropertyToDelete,
&propertyToDelete);
IStorage_Release(childStorage);
IEnumSTATSTG_Release(elements);
return destroyHr;
}
/*********************************************************************
*
* Internal Method
*
* Perform the deletion of a stream node
*
*/
static HRESULT deleteStreamProperty(
StorageImpl *parentStorage,
ULONG indexOfPropertyToDelete,
StgProperty propertyToDelete)
{
IStream *pis;
HRESULT hr;
ULARGE_INTEGER size;
size.u.HighPart = 0;
size.u.LowPart = 0;
hr = StorageBaseImpl_OpenStream(
(IStorage*)parentStorage,
(OLECHAR*)propertyToDelete.name,
NULL,
STGM_WRITE | STGM_SHARE_EXCLUSIVE,
0,
&pis);
if (hr!=S_OK)
{
return(hr);
}
/*
* Zap the stream
*/
hr = IStream_SetSize(pis, size);
if(hr != S_OK)
{
return hr;
}
/*
* Release the stream object.
*/
IStream_Release(pis);
/*
* Invalidate the property by zeroing its name member.
*/
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;
}
/************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -