static HRESULT WINAPI IHlinkBC_Register(IHlinkBrowseContext* iface, DWORD dwReserved, IUnknown *piunk, IMoniker *pimk, DWORD *pdwRegister) { static const WCHAR szIdent[] = {'W','I','N','E','H','L','I','N','K',0}; HlinkBCImpl *This = impl_from_IHlinkBrowseContext(iface); IMoniker *mon; IMoniker *composite; IRunningObjectTable *ROT; HRESULT hr; FIXME("(%p)->(%i %p %p %p)\n", This, dwReserved, piunk, pimk, pdwRegister); hr = CreateItemMoniker(NULL, szIdent, &mon); if (FAILED(hr)) return hr; CreateGenericComposite(mon, pimk, &composite); GetRunningObjectTable(0, &ROT); IRunningObjectTable_Register(ROT, 0, piunk, composite, pdwRegister); IRunningObjectTable_Release(ROT); IMoniker_Release(composite); IMoniker_Release(mon); return S_OK; }
/****************************************************************************** * AntiMoniker_ComposeWith ******************************************************************************/ static HRESULT WINAPI AntiMonikerImpl_ComposeWith(IMoniker* iface, IMoniker* pmkRight, BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite) { TRACE("(%p,%p,%d,%p)\n",iface,pmkRight,fOnlyIfNotGeneric,ppmkComposite); if ((ppmkComposite==NULL)||(pmkRight==NULL)) return E_POINTER; *ppmkComposite=0; if (fOnlyIfNotGeneric) return MK_E_NEEDGENERIC; else return CreateGenericComposite(iface,pmkRight,ppmkComposite); }
/****************************************************************************** * ItemMoniker_GetTimeOfLastChange ******************************************************************************/ static HRESULT WINAPI ItemMonikerImpl_GetTimeOfLastChange(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, FILETIME* pItemTime) { IRunningObjectTable* rot; HRESULT res; IMoniker *compositeMk; TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pItemTime); if (pItemTime==NULL) return E_INVALIDARG; /* If pmkToLeft is NULL, this method returns MK_E_NOTBINDABLE */ if (pmkToLeft==NULL) return MK_E_NOTBINDABLE; else { /* Otherwise, the method creates a composite of pmkToLeft and this moniker and uses the ROT to access */ /* the time of last change. If the object is not in the ROT, the method calls */ /* IMoniker::GetTimeOfLastChange on the pmkToLeft parameter. */ res=CreateGenericComposite(pmkToLeft,iface,&compositeMk); if (FAILED(res)) return res; res=IBindCtx_GetRunningObjectTable(pbc,&rot); if (FAILED(res)) { IMoniker_Release(compositeMk); return res; } if (IRunningObjectTable_GetTimeOfLastChange(rot,compositeMk,pItemTime)!=S_OK) res=IMoniker_GetTimeOfLastChange(pmkToLeft,pbc,NULL,pItemTime); IMoniker_Release(compositeMk); } return res; }
/****************************************************************************** * ClassMoniker_ComposeWith ******************************************************************************/ static HRESULT WINAPI ClassMoniker_ComposeWith(IMoniker* iface, IMoniker* pmkRight, BOOL fOnlyIfNotGeneric, IMoniker** ppmkComposite) { HRESULT res=S_OK; DWORD mkSys,mkSys2; IEnumMoniker* penumMk=0; IMoniker *pmostLeftMk=0; IMoniker* tempMkComposite=0; TRACE("(%p,%d,%p)\n", pmkRight, fOnlyIfNotGeneric, ppmkComposite); if ((ppmkComposite==NULL)||(pmkRight==NULL)) return E_POINTER; *ppmkComposite=0; IMoniker_IsSystemMoniker(pmkRight,&mkSys); /* If pmkRight is an anti-moniker, the returned moniker is NULL */ if(mkSys==MKSYS_ANTIMONIKER) return res; else /* if pmkRight is a composite whose leftmost component is an anti-moniker, */ /* the returned moniker is the composite after the leftmost anti-moniker is removed. */ if(mkSys==MKSYS_GENERICCOMPOSITE){ res=IMoniker_Enum(pmkRight,TRUE,&penumMk); if (FAILED(res)) return res; res=IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL); IMoniker_IsSystemMoniker(pmostLeftMk,&mkSys2); if(mkSys2==MKSYS_ANTIMONIKER){ IMoniker_Release(pmostLeftMk); tempMkComposite=iface; IMoniker_AddRef(iface); while(IEnumMoniker_Next(penumMk,1,&pmostLeftMk,NULL)==S_OK){ res=CreateGenericComposite(tempMkComposite,pmostLeftMk,ppmkComposite); IMoniker_Release(tempMkComposite); IMoniker_Release(pmostLeftMk); tempMkComposite=*ppmkComposite; IMoniker_AddRef(tempMkComposite); } return res; } else return CreateGenericComposite(iface,pmkRight,ppmkComposite); } /* If pmkRight is not an anti-moniker, the method combines the two monikers into a generic composite if fOnlyIfNotGeneric is FALSE; if fOnlyIfNotGeneric is TRUE, the method returns a NULL moniker and a return value of MK_E_NEEDGENERIC */ else if (!fOnlyIfNotGeneric) return CreateGenericComposite(iface,pmkRight,ppmkComposite); else return MK_E_NEEDGENERIC; }
STDMETHODIMP COleUILinkInfo::SetLinkSource( DWORD dwLink, LPTSTR lpszDisplayName, ULONG lenFileName, ULONG* pchEaten, BOOL fValidateSource) { USES_CONVERSION; COleClientItem* pItem = (COleClientItem*)dwLink; ASSERT_VALID(pItem); ASSERT_KINDOF(COleClientItem, pItem); ASSERT(pItem->GetType() == OT_LINK); LPOLEOBJECT lpObject = NULL; CLSID clsid; // parse the portion known to be a file name into a file moniker TCHAR szName[_MAX_PATH]; lstrcpyn(szName, lpszDisplayName, (int)lenFileName + 1); LPMONIKER lpmk = NULL; SCODE sc = CreateFileMoniker(T2COLE(szName), &lpmk); if (lpmk == NULL) return sc; LPBC lpbc = NULL; if (fValidateSource) { sc = CreateBindCtx(0, &lpbc); if (sc != S_OK) { lpmk->Release(); return sc; } } // nUneaten is the number of chars left to parse UINT nUneaten = lstrlen(lpszDisplayName) - lenFileName; // lpszRemainder is the left over display name LPTSTR lpszRemainder = lpszDisplayName + lenFileName; *pchEaten = lenFileName; // parse the rest of the display name while (nUneaten > 0) { // attempt to parse next moniker ULONG nEaten = 0; LPMONIKER lpmkNext = NULL; sc = _AfxParseDisplayName(lpmk, lpbc, lpszRemainder, &nEaten, &lpmkNext); if (sc != S_OK) { lpmk->Release(); lpbc->Release(); return sc; } // advance through the display name nUneaten -= nEaten; *pchEaten += nEaten; lpszRemainder += nEaten; if (lpmkNext != NULL) { // create composite out of current and next LPMONIKER lpmkTemp = NULL; sc = CreateGenericComposite(lpmk, lpmkNext, &lpmkTemp); if (FAILED(sc)) { lpmk->Release(); lpmkNext->Release(); lpbc->Release(); return sc; } // make current = next lpmkNext->Release(); lpmk->Release(); lpmk = lpmkTemp; } } if (fValidateSource) { // attempt to bind the the object sc = lpmk->BindToObject(lpbc, NULL, IID_IOleObject, (LPLP)&lpObject); if (FAILED(sc)) { pItem->m_bLinkUnavail = TRUE; lpbc->Release(); lpmk->Release(); RELEASE(lpObject); return sc; } ASSERT(lpObject != NULL); // call GetUserClassID while bound so default handler updates lpObject->GetUserClassID(&clsid); pItem->m_bLinkUnavail = FALSE; } // get IOleLink interface LPOLELINK lpOleLink = QUERYINTERFACE(pItem->m_lpObject, IOleLink); ASSERT(lpOleLink != NULL); // set source from moniker sc = lpOleLink->SetSourceMoniker(lpmk, clsid); // update the cache if object was successfully bound if (lpObject != NULL) { lpObject->Update(); lpObject->Release(); } // cleanup lpOleLink->Release(); RELEASE(lpmk); RELEASE(lpbc); return sc; }
/****************************************************************************** * 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) { /* 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); } else res = E_OUTOFMEMORY; free_stringtable(strDec1); free_stringtable(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); }