📄 storage32.c
字号:
*/
propertyEnumeration = IEnumSTATSTGImpl_Construct(
This->ancestorStorage,
This->rootPropertySetIndex);
/*
* Search the enumeration for the property with the given name
*/
foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(
propertyEnumeration,
pwcsName,
¤tProperty);
/*
* Delete the property enumeration since we don't need it anymore
*/
IEnumSTATSTGImpl_Destroy(propertyEnumeration);
/*
* If it was found, construct the stream object and return a pointer to it.
*/
if ( (foundPropertyIndex!=PROPERTY_NULL) &&
(currentProperty.propertyType==PROPTYPE_STREAM) )
{
newStream = StgStreamImpl_Construct(This, grfMode, foundPropertyIndex);
if (newStream!=0)
{
newStream->grfMode = grfMode;
*ppstm = (IStream*)newStream;
/*
* Since we are returning a pointer to the interface, we have to
* nail down the reference.
*/
IStream_AddRef(*ppstm);
res = S_OK;
goto end;
}
res = E_OUTOFMEMORY;
goto end;
}
res = STG_E_FILENOTFOUND;
end:
if (res == S_OK)
TRACE("<-- IStream %p\n", *ppstm);
TRACE("<-- %08x\n", res);
return res;
}
/************************************************************************
* Storage32BaseImpl_OpenStorage (IStorage)
*
* This method will open a new storage object from the current storage.
*
* See Windows documentation for more details on IStorage methods.
*/
static HRESULT WINAPI StorageBaseImpl_OpenStorage(
IStorage* iface,
const OLECHAR* pwcsName, /* [string][unique][in] */
IStorage* pstgPriority, /* [unique][in] */
DWORD grfMode, /* [in] */
SNB snbExclude, /* [unique][in] */
DWORD reserved, /* [in] */
IStorage** ppstg) /* [out] */
{
StorageBaseImpl *This = (StorageBaseImpl *)iface;
StorageInternalImpl* newStorage;
IEnumSTATSTGImpl* propertyEnumeration;
StgProperty currentProperty;
ULONG foundPropertyIndex;
HRESULT res = STG_E_UNKNOWN;
TRACE("(%p, %s, %p, %x, %p, %d, %p)\n",
iface, debugstr_w(pwcsName), pstgPriority,
grfMode, snbExclude, reserved, ppstg);
/*
* Perform a sanity check on the parameters.
*/
if ( (This==0) || (pwcsName==NULL) || (ppstg==0) )
{
res = E_INVALIDARG;
goto end;
}
/* as documented */
if (snbExclude != NULL)
{
res = STG_E_INVALIDPARAMETER;
goto end;
}
/*
* Validate the STGM flags
*/
if ( FAILED( validateSTGM(grfMode) ))
{
res = STG_E_INVALIDFLAG;
goto end;
}
/*
* As documented.
*/
if ( STGM_SHARE_MODE(grfMode) != STGM_SHARE_EXCLUSIVE ||
(grfMode & STGM_DELETEONRELEASE) ||
(grfMode & STGM_PRIORITY) )
{
res = STG_E_INVALIDFUNCTION;
goto end;
}
/*
* Check that we're compatible with the parent's storage mode,
* but only if we are not transacted
*/
if(!(This->ancestorStorage->base.openFlags & STGM_TRANSACTED)) {
if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( This->openFlags ) )
{
res = STG_E_ACCESSDENIED;
goto end;
}
}
/*
* Initialize the out parameter
*/
*ppstg = NULL;
/*
* Create a property enumeration to search the properties
*/
propertyEnumeration = IEnumSTATSTGImpl_Construct(
This->ancestorStorage,
This->rootPropertySetIndex);
/*
* Search the enumeration for the property with the given name
*/
foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(
propertyEnumeration,
pwcsName,
¤tProperty);
/*
* Delete the property enumeration since we don't need it anymore
*/
IEnumSTATSTGImpl_Destroy(propertyEnumeration);
/*
* If it was found, construct the stream object and return a pointer to it.
*/
if ( (foundPropertyIndex!=PROPERTY_NULL) &&
(currentProperty.propertyType==PROPTYPE_STORAGE) )
{
/*
* Construct a new Storage object
*/
newStorage = StorageInternalImpl_Construct(
This->ancestorStorage,
grfMode,
foundPropertyIndex);
if (newStorage != 0)
{
*ppstg = (IStorage*)newStorage;
/*
* Since we are returning a pointer to the interface,
* we have to nail down the reference.
*/
StorageBaseImpl_AddRef(*ppstg);
res = S_OK;
goto end;
}
res = STG_E_INSUFFICIENTMEMORY;
goto end;
}
res = STG_E_FILENOTFOUND;
end:
TRACE("<-- %08x\n", res);
return res;
}
/************************************************************************
* Storage32BaseImpl_EnumElements (IStorage)
*
* This method will create an enumerator object that can be used to
* retrieve informatino about all the properties in the storage object.
*
* See Windows documentation for more details on IStorage methods.
*/
static HRESULT WINAPI StorageBaseImpl_EnumElements(
IStorage* iface,
DWORD reserved1, /* [in] */
void* reserved2, /* [size_is][unique][in] */
DWORD reserved3, /* [in] */
IEnumSTATSTG** ppenum) /* [out] */
{
StorageBaseImpl *This = (StorageBaseImpl *)iface;
IEnumSTATSTGImpl* newEnum;
TRACE("(%p, %d, %p, %d, %p)\n",
iface, reserved1, reserved2, reserved3, ppenum);
/*
* Perform a sanity check on the parameters.
*/
if ( (This==0) || (ppenum==0))
return E_INVALIDARG;
/*
* Construct the enumerator.
*/
newEnum = IEnumSTATSTGImpl_Construct(
This->ancestorStorage,
This->rootPropertySetIndex);
if (newEnum!=0)
{
*ppenum = (IEnumSTATSTG*)newEnum;
/*
* Don't forget to nail down a reference to the new object before
* returning it.
*/
IEnumSTATSTG_AddRef(*ppenum);
return S_OK;
}
return E_OUTOFMEMORY;
}
/************************************************************************
* Storage32BaseImpl_Stat (IStorage)
*
* This method will retrieve information about this storage object.
*
* See Windows documentation for more details on IStorage methods.
*/
static HRESULT WINAPI StorageBaseImpl_Stat(
IStorage* iface,
STATSTG* pstatstg, /* [out] */
DWORD grfStatFlag) /* [in] */
{
StorageBaseImpl *This = (StorageBaseImpl *)iface;
StgProperty curProperty;
BOOL readSuccessful;
HRESULT res = STG_E_UNKNOWN;
TRACE("(%p, %p, %x)\n",
iface, pstatstg, grfStatFlag);
/*
* Perform a sanity check on the parameters.
*/
if ( (This==0) || (pstatstg==0))
{
res = E_INVALIDARG;
goto end;
}
/*
* Read the information from the property.
*/
readSuccessful = StorageImpl_ReadProperty(
This->ancestorStorage,
This->rootPropertySetIndex,
&curProperty);
if (readSuccessful)
{
StorageUtl_CopyPropertyToSTATSTG(
pstatstg,
&curProperty,
grfStatFlag);
pstatstg->grfMode = This->openFlags;
pstatstg->grfStateBits = This->stateBits;
res = S_OK;
goto end;
}
res = E_FAIL;
end:
if (res == S_OK)
{
TRACE("<-- STATSTG: pwcsName: %s, type: %d, cbSize.Low/High: %d/%d, grfMode: %08x, grfLocksSupported: %d, grfStateBits: %08x\n", debugstr_w(pstatstg->pwcsName), pstatstg->type, pstatstg->cbSize.u.LowPart, pstatstg->cbSize.u.HighPart, pstatstg->grfMode, pstatstg->grfLocksSupported, pstatstg->grfStateBits);
}
TRACE("<-- %08x\n", res);
return res;
}
/************************************************************************
* Storage32BaseImpl_RenameElement (IStorage)
*
* This method will rename the specified element.
*
* See Windows documentation for more details on IStorage methods.
*
* Implementation notes: The method used to rename consists of creating a clone
* of the deleted StgProperty object setting it with the new name and to
* perform a DestroyElement of the old StgProperty.
*/
static HRESULT WINAPI StorageBaseImpl_RenameElement(
IStorage* iface,
const OLECHAR* pwcsOldName, /* [in] */
const OLECHAR* pwcsNewName) /* [in] */
{
StorageBaseImpl *This = (StorageBaseImpl *)iface;
IEnumSTATSTGImpl* propertyEnumeration;
StgProperty currentProperty;
ULONG foundPropertyIndex;
TRACE("(%p, %s, %s)\n",
iface, debugstr_w(pwcsOldName), debugstr_w(pwcsNewName));
/*
* Create a property enumeration to search the properties
*/
propertyEnumeration = IEnumSTATSTGImpl_Construct(This->ancestorStorage,
This->rootPropertySetIndex);
/*
* Search the enumeration for the new property name
*/
foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(propertyEnumeration,
pwcsNewName,
¤tProperty);
if (foundPropertyIndex != PROPERTY_NULL)
{
/*
* There is already a property with the new name
*/
IEnumSTATSTGImpl_Destroy(propertyEnumeration);
return STG_E_FILEALREADYEXISTS;
}
IEnumSTATSTG_Reset((IEnumSTATSTG*)propertyEnumeration);
/*
* Search the enumeration for the old property name
*/
foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(propertyEnumeration,
pwcsOldName,
¤tProperty);
/*
* Delete the property enumeration since we don't need it anymore
*/
IEnumSTATSTGImpl_Destroy(propertyEnumeration);
if (foundPropertyIndex != PROPERTY_NULL)
{
StgProperty renamedProperty;
ULONG renamedPropertyIndex;
/*
* Setup a new property for the renamed property
*/
renamedProperty.sizeOfNameString =
( lstrlenW(pwcsNewName)+1 ) * sizeof(WCHAR);
if (renamedProperty.sizeOfNameString > PROPERTY_NAME_BUFFER_LEN)
return STG_E_INVALIDNAME;
strcpyW(renamedProperty.name, pwcsNewName);
renamedProperty.propertyType = currentProperty.propertyType;
renamedProperty.startingBlock = currentProperty.startingBlock;
renamedProperty.size.u.LowPart = currentProperty.size.u.LowPart;
renamedProperty.size.u.HighPart = currentProperty.size.u.HighPart;
renamedProperty.previousProperty = PROPERTY_NULL;
renamedProperty.nextProperty = PROPERTY_NULL;
/*
* Bring the dirProperty link in case it is a storage and in which
* case the renamed storage elements don't require to be reorganized.
*/
renamedProperty.dirProperty = currentProperty.dirProperty;
/* call CoFileTime to get the current time
renamedProperty.timeStampS1
renamedProperty.timeStampD1
renamedProperty.timeStampS2
renamedProperty.timeStampD2
renamedProperty.propertyUniqueID
*/
/*
* Obtain a free property in the property chain
*/
renamedPropertyIndex = getFreeProperty(This->ancestorStorage);
/*
* Save the new property into the new property spot
*/
StorageImpl_WriteProperty(
This->ancestorStorage,
renamedPropertyIndex,
&renamedProperty);
/*
* Find a spot in the property chain for our newly created property.
*/
updatePropertyChain(
(StorageImpl*)This,
renamedPropertyIndex,
renamedProperty);
/*
* At this point the renamed property has been inserted in the tree,
* now, before Destroying the old property we must zero its dirProperty
* otherwise the DestroyProperty below will zap it all and we do not want
* this to happen.
* Also, we fake that the old property is a storage so the DestroyProperty
* will not do a SetSize(0) on the stream data.
*
* This means that we need to tweak the StgProperty if it is a stream or a
* non empty storage.
*/
StorageImpl_ReadProperty(This->ancestorStorage,
foundPropertyIndex,
¤tProperty);
currentProperty.dirProperty = PROPERTY_NULL;
currentProperty.propertyType = PROPTYPE_STORAGE;
StorageImpl_WriteProperty(
This->ancestorStorage,
foundPropertyIndex,
¤tProperty);
/*
* Invoke Destroy to get rid of the ole property and automatically redo
* the linking of its previous and next members...
*/
IStorage_DestroyElement((IStorage*)This->ancestorStorage, pwcsOldName);
}
else
{
/*
* There is no property with the old name
*/
return STG_E_FILENOTFOUND;
}
return S_OK;
}
/************************************************************************
* Storage32BaseImpl_CreateStream (IStorage)
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -