📄 filemoniker.c
字号:
break;
}
}
}
if (!bWriteWide)
{
res=IStream_Write(pStm,&ZERO,sizeof(DWORD),NULL);
return res;
}
/* write bytes needed for the filepathW (without 0) + 6 */
bytesW = len*sizeof(WCHAR) + 6;
res=IStream_Write(pStm,&bytesW,sizeof(DWORD),NULL);
if (!SUCCEEDED(res)) return res;
/* try again, without the extra 6 */
bytesW -= 6;
res=IStream_Write(pStm,&bytesW,sizeof(DWORD),NULL);
if (!SUCCEEDED(res)) return res;
/* write a WORD 3 */
res=IStream_Write(pStm,&THREE,sizeof(WORD),NULL);
if (!SUCCEEDED(res)) return res;
/* write W string (no 0) */
res=IStream_Write(pStm,filePathW,bytesW,NULL);
return res;
}
/******************************************************************************
* FileMoniker_GetSizeMax
*/
static HRESULT WINAPI
FileMonikerImpl_GetSizeMax(IMoniker* iface, ULARGE_INTEGER* pcbSize)
{
FileMonikerImpl *This = (FileMonikerImpl *)iface;
TRACE("(%p,%p)\n",iface,pcbSize);
if (!pcbSize)
return E_POINTER;
/* We could calculate exactly (see ...::Save()) but instead
* we'll make a quick over-estimate, like Windows (NT4, XP) does.
*/
pcbSize->u.LowPart = 0x38 + 4 * lstrlenW(This->filePathName);
pcbSize->u.HighPart = 0;
return S_OK;
}
/******************************************************************************
* FileMoniker_Destroy (local function)
*******************************************************************************/
HRESULT WINAPI FileMonikerImpl_Destroy(FileMonikerImpl* This)
{
TRACE("(%p)\n",This);
if (This->pMarshal) IUnknown_Release(This->pMarshal);
HeapFree(GetProcessHeap(),0,This->filePathName);
HeapFree(GetProcessHeap(),0,This);
return S_OK;
}
/******************************************************************************
* FileMoniker_BindToObject
*/
static HRESULT WINAPI
FileMonikerImpl_BindToObject(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
REFIID riid, VOID** ppvResult)
{
HRESULT res=E_FAIL;
CLSID clsID;
IUnknown* pObj=0;
IRunningObjectTable *prot=0;
IPersistFile *ppf=0;
IClassFactory *pcf=0;
IClassActivator *pca=0;
FileMonikerImpl *This = (FileMonikerImpl *)iface;
*ppvResult=0;
TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
if(pmkToLeft==NULL){
res=IBindCtx_GetRunningObjectTable(pbc,&prot);
if (SUCCEEDED(res)){
/* if the requested class was loaded before ! we don't need to reload it */
res = IRunningObjectTable_GetObject(prot,iface,&pObj);
if (res==S_FALSE){
/* first activation of this class */
res=GetClassFile(This->filePathName,&clsID);
if (SUCCEEDED(res)){
res=CoCreateInstance(&clsID,NULL,CLSCTX_ALL,&IID_IPersistFile,(void**)&ppf);
if (SUCCEEDED(res)){
res=IPersistFile_Load(ppf,This->filePathName,STGM_READ);
if (SUCCEEDED(res)){
pObj=(IUnknown*)ppf;
IUnknown_AddRef(pObj);
}
}
}
}
}
}
else{
res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IClassFactory,(void**)&pcf);
if (res==E_NOINTERFACE){
res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IClassActivator,(void**)&pca);
if (res==E_NOINTERFACE)
return MK_E_INTERMEDIATEINTERFACENOTSUPPORTED;
}
if (pcf!=NULL){
IClassFactory_CreateInstance(pcf,NULL,&IID_IPersistFile,(void**)&ppf);
res=IPersistFile_Load(ppf,This->filePathName,STGM_READ);
if (SUCCEEDED(res)){
pObj=(IUnknown*)ppf;
IUnknown_AddRef(pObj);
}
}
if (pca!=NULL){
FIXME("()\n");
/*res=GetClassFile(This->filePathName,&clsID);
if (SUCCEEDED(res)){
res=IClassActivator_GetClassObject(pca,&clsID,CLSCTX_ALL,0,&IID_IPersistFile,(void**)&ppf);
if (SUCCEEDED(res)){
pObj=(IUnknown*)ppf;
IUnknown_AddRef(pObj);
}
}*/
}
}
if (pObj!=NULL){
/* get the requested interface from the loaded class */
res= IUnknown_QueryInterface(pObj,riid,ppvResult);
IBindCtx_RegisterObjectBound(pbc,(IUnknown*)*ppvResult);
IUnknown_Release(pObj);
}
if (prot!=NULL)
IRunningObjectTable_Release(prot);
if (ppf!=NULL)
IPersistFile_Release(ppf);
if (pca!=NULL)
IClassActivator_Release(pca);
if (pcf!=NULL)
IClassFactory_Release(pcf);
return res;
}
/******************************************************************************
* FileMoniker_BindToStorage
*/
static HRESULT WINAPI
FileMonikerImpl_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft,
REFIID riid, VOID** ppvObject)
{
LPOLESTR filePath=0;
IStorage *pstg=0;
HRESULT res;
TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvObject);
if (pmkToLeft==NULL){
if (IsEqualIID(&IID_IStorage, riid)){
/* get the file name */
IMoniker_GetDisplayName(iface,pbc,pmkToLeft,&filePath);
/* verifie if the file contains a storage object */
res=StgIsStorageFile(filePath);
if(res==S_OK){
res=StgOpenStorage(filePath,NULL,STGM_READWRITE|STGM_SHARE_DENY_WRITE,NULL,0,&pstg);
if (SUCCEEDED(res)){
*ppvObject=pstg;
IStorage_AddRef(pstg);
return res;
}
}
CoTaskMemFree(filePath);
}
else
if ( (IsEqualIID(&IID_IStream, riid)) || (IsEqualIID(&IID_ILockBytes, riid)) )
return E_FAIL;
else
return E_NOINTERFACE;
}
else {
FIXME("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvObject);
return E_NOTIMPL;
}
return res;
}
/******************************************************************************
* FileMoniker_Reduce
******************************************************************************/
static HRESULT WINAPI
FileMonikerImpl_Reduce(IMoniker* iface, IBindCtx* pbc, DWORD dwReduceHowFar,
IMoniker** ppmkToLeft, IMoniker** ppmkReduced)
{
TRACE("(%p,%p,%d,%p,%p)\n",iface,pbc,dwReduceHowFar,ppmkToLeft,ppmkReduced);
if (ppmkReduced==NULL)
return E_POINTER;
IMoniker_AddRef(iface);
*ppmkReduced=iface;
return MK_S_REDUCED_TO_SELF;
}
/******************************************************************************
* FileMoniker_ComposeWith
*/
static HRESULT WINAPI
FileMonikerImpl_ComposeWith(IMoniker* iface, IMoniker* pmkRight,
BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite)
{
HRESULT res;
LPOLESTR str1=0,str2=0,*strDec1=0,*strDec2=0,newStr=0;
static const WCHAR twoPoint[]={'.','.',0};
static const WCHAR bkSlash[]={'\\',0};
IBindCtx *bind=0;
int i=0,j=0,lastIdx1=0,lastIdx2=0;
DWORD mkSys;
TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite);
if (ppmkComposite==NULL)
return E_POINTER;
if (pmkRight==NULL)
return E_INVALIDARG;
*ppmkComposite=0;
IMoniker_IsSystemMoniker(pmkRight,&mkSys);
/* check if we have two filemonikers to compose or not */
if(mkSys==MKSYS_FILEMONIKER){
CreateBindCtx(0,&bind);
IMoniker_GetDisplayName(iface,bind,NULL,&str1);
IMoniker_GetDisplayName(pmkRight,bind,NULL,&str2);
/* decompose pathnames of the two monikers : (to prepare the path merge operation ) */
lastIdx1=FileMonikerImpl_DecomposePath(str1,&strDec1)-1;
lastIdx2=FileMonikerImpl_DecomposePath(str2,&strDec2)-1;
if ((lastIdx1==-1 && lastIdx2>-1)||(lastIdx1==1 && lstrcmpW(strDec1[0],twoPoint)==0))
return MK_E_SYNTAX;
if(lstrcmpW(strDec1[lastIdx1],bkSlash)==0)
lastIdx1--;
/* for etch "..\" in the left of str2 remove the right element from str1 */
for(i=0; ( (lastIdx1>=0) && (strDec2[i]!=NULL) && (lstrcmpW(strDec2[i],twoPoint)==0) ) ;i+=2){
lastIdx1-=2;
}
/* the length of the composed path string is raised by the sum of the two paths lengths */
newStr=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(lstrlenW(str1)+lstrlenW(str2)+1));
if (newStr==NULL)
return E_OUTOFMEMORY;
/* new path is the concatenation of the rest of str1 and str2 */
for(*newStr=0,j=0;j<=lastIdx1;j++)
strcatW(newStr,strDec1[j]);
if ((strDec2[i]==NULL && lastIdx1>-1 && lastIdx2>-1) || lstrcmpW(strDec2[i],bkSlash)!=0)
strcatW(newStr,bkSlash);
for(j=i;j<=lastIdx2;j++)
strcatW(newStr,strDec2[j]);
/* create a new moniker with the new string */
res=CreateFileMoniker(newStr,ppmkComposite);
/* free all strings space memory used by this function */
HeapFree(GetProcessHeap(),0,newStr);
for(i=0; strDec1[i]!=NULL;i++)
CoTaskMemFree(strDec1[i]);
for(i=0; strDec2[i]!=NULL;i++)
CoTaskMemFree(strDec2[i]);
CoTaskMemFree(strDec1);
CoTaskMemFree(strDec2);
CoTaskMemFree(str1);
CoTaskMemFree(str2);
return res;
}
else if(mkSys==MKSYS_ANTIMONIKER){
*ppmkComposite=NULL;
return S_OK;
}
else if (fOnlyIfNotGeneric){
*ppmkComposite=NULL;
return MK_E_NEEDGENERIC;
}
else
return CreateGenericComposite(iface,pmkRight,ppmkComposite);
}
/******************************************************************************
* FileMoniker_Enum
*/
static HRESULT WINAPI
FileMonikerImpl_Enum(IMoniker* iface,BOOL fForward, IEnumMoniker** ppenumMoniker)
{
TRACE("(%p,%d,%p)\n",iface,fForward,ppenumMoniker);
if (ppenumMoniker == NULL)
return E_POINTER;
*ppenumMoniker = NULL;
return S_OK;
}
/******************************************************************************
* FileMoniker_IsEqual
*/
static HRESULT WINAPI
FileMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker)
{
FileMonikerImpl *This = (FileMonikerImpl *)iface;
CLSID clsid;
LPOLESTR filePath;
IBindCtx* bind;
HRESULT res;
TRACE("(%p,%p)\n",iface,pmkOtherMoniker);
if (pmkOtherMoniker==NULL)
return S_FALSE;
IMoniker_GetClassID(pmkOtherMoniker,&clsid);
if (!IsEqualCLSID(&clsid,&CLSID_FileMoniker))
return S_FALSE;
res = CreateBindCtx(0,&bind);
if (FAILED(res)) return res;
if (SUCCEEDED(IMoniker_GetDisplayName(pmkOtherMoniker,bind,NULL,&filePath))) {
int result = lstrcmpiW(filePath, This->filePathName);
CoTaskMemFree(filePath);
if ( result == 0 ) return S_OK;
}
return S_FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -