int BookServerTest::createFileMoniker() { ComPtr<IMoniker> moniker; auto hr = CreateFileMoniker(kFileName, &moniker); if (FAILED(hr)) { return -1; } IBindCtx* pbc; CreateBindCtx(0, &pbc); ComPtr<IBook> book; hr = moniker->BindToObject(pbc, NULL, IID_IBook, (void**)&book); if (FAILED(hr)) { return -1; } ComPtr<IStorage> pStorage; ComPtr<IStream> pStream; hr = StgCreateStorageEx(kMonikerFileName, STGM_WRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, STGFMT_STORAGE, 0, NULL, 0, IID_IStorage, (void**)&pStorage); if (FAILED(hr)) return hr; hr = pStorage->CreateStream(kStreamName, STGM_WRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, &pStream); if (FAILED(hr)) return hr; OleSaveToStream(moniker, pStream); return 0; }
int PolylineTest::writeFileMoniker() { ComPtr<IMoniker> moniker; auto hr = CreateFileMoniker(kFileName, &moniker); if (FAILED(hr)) { return -1; } IBindCtx* pbc; CreateBindCtx(0, &pbc); ComPtr<IPolyline> polyline; hr = moniker->BindToObject(pbc, NULL, IID_IPolyline, (void**)&polyline); if (FAILED(hr)) { return -1; } polyline->put_Color(RGB(0xff, 0x00, 0x00)); COLORREF value; polyline->get_Color(&value); assert(value == RGB(0xff, 0x00, 0x00)); ComPtr<IStorage> pStorage; ComPtr<IStream> pStream; hr = StgCreateStorageEx(kMonikerFileName, STGM_WRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, STGFMT_STORAGE, 0, NULL, 0, IID_IStorage, (void**)&pStorage); if (FAILED(hr)) return hr; hr = pStorage->CreateStream(kStreamName, STGM_WRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, &pStream); if (FAILED(hr)) return hr; OleSaveToStream(moniker, pStream); return 0; }
///////////////////////////////////////////////////////////////////////////// // Description: Creates a relative path name, if possible. // // Parameters: // bBeginWithDot - Prepends the relative path with the a period and // backslash. While possibly rendundant, this may be useful for some contexts // of relative pathnames. If a relative path cannot be resolved, this // parameter is ignored. // bool TCMakeRelativePath(LPCTSTR pszPath, LPCTSTR pszFrom, LPTSTR pszDest, int cchMaxDest, bool bBeginWithDot) { // Ensure that input paths are absolute TCHAR szPathCopy[_MAX_PATH], szFromCopy[_MAX_PATH]; if (!_tfullpath(szPathCopy, pszPath, sizeofArray(szPathCopy))) return false; if (!_tfullpath(szFromCopy, pszFrom, sizeofArray(szFromCopy))) return false; // Replace (in-place) forward slashes with backslashes in input paths TCReplaceText(szPathCopy, TEXT("/"), TEXT("\\"), szPathCopy, -1); TCReplaceText(szFromCopy, TEXT("/"), TEXT("\\"), szFromCopy, -1); // The From path MUST be a directory, not a filename, so append backslash if (TEXT('\\') != szFromCopy[_tcslen(szFromCopy) - 1]) _tcscat(szFromCopy, TEXT("\\")); // Use COM monikers to create a relative path HRESULT hr; IBindCtxPtr pbc; IMonikerPtr pmkFrom, pmkPath, pmkRelative; LPOLESTR pszRelative = NULL; if (SUCCEEDED(hr = CreateFileMoniker(_bstr_t(szFromCopy), &pmkFrom)) && SUCCEEDED(hr = CreateFileMoniker(_bstr_t(szPathCopy), &pmkPath)) && S_OK == (hr = pmkFrom->RelativePathTo(pmkPath, &pmkRelative)) && SUCCEEDED(hr = CreateBindCtx(0, &pbc)) && SUCCEEDED(hr = pmkRelative->GetDisplayName(pbc, NULL, &pszRelative))) { if (bBeginWithDot) { TC_tcscpyn(pszDest, TEXT(".\\"), cchMaxDest); cchMaxDest -= 2; pszDest += 2; } TC_tcscpyn(pszDest, _bstr_t(pszRelative), cchMaxDest); CoTaskMemFree(pszRelative); return true; } // Could not make a relative path, copy the absolute path TC_tcscpyn(pszDest, szPathCopy, cchMaxDest); return false; }
LPMONIKER COleLinkingDoc::GetMoniker(OLEGETMONIKER nAssign) { ASSERT_VALID(this); // use base class implementation if no registered moniker if (m_strMoniker.IsEmpty()) return COleDocument::GetMoniker(nAssign); // return file moniker based on current path name LPMONIKER lpMoniker; CreateFileMoniker(CStringW(m_strMoniker), &lpMoniker); return lpMoniker; }
IFileIsInUse* CreateIFileIsInUse(const string& File) { IFileIsInUse *pfiu = nullptr; IRunningObjectTable *prot; if (SUCCEEDED(GetRunningObjectTable(0, &prot))) { IMoniker *pmkFile; if (SUCCEEDED(CreateFileMoniker(File.data(), &pmkFile))) { IEnumMoniker *penumMk; if (SUCCEEDED(prot->EnumRunning(&penumMk))) { HRESULT hr = E_FAIL; ULONG celt; IMoniker *pmk; while (FAILED(hr) && (penumMk->Next(1, &pmk, &celt) == S_OK)) { DWORD dwType; if (SUCCEEDED(pmk->IsSystemMoniker(&dwType)) && dwType == MKSYS_FILEMONIKER) { IMoniker *pmkPrefix; if (SUCCEEDED(pmkFile->CommonPrefixWith(pmk, &pmkPrefix))) { if (pmkFile->IsEqual(pmkPrefix) == S_OK) { IUnknown *punk; if (prot->GetObject(pmk, &punk) == S_OK) { hr = punk->QueryInterface( #ifdef __GNUC__ IID_IFileIsInUse, IID_PPV_ARGS_Helper(&pfiu) #else IID_PPV_ARGS(&pfiu) #endif ); punk->Release(); } } pmkPrefix->Release(); } } pmk->Release(); } penumMk->Release(); } pmkFile->Release(); } prot->Release(); } return pfiu; }
LPMONIKER COleDocument::GetMoniker(OLEGETMONIKER /*nAssign*/) { ASSERT_VALID(this); // no moniker for untitled documents if (m_strPathName.IsEmpty()) return NULL; // return file moniker based on current path name const CStringW strPathNameW(m_strPathName); LPMONIKER lpMoniker; CreateFileMoniker(strPathNameW.GetString(), &lpMoniker); return lpMoniker; }
static HRESULT BuildMoniker( const char *name, LPMONIKER *ppmk) { LPMONIKER pmkClass = NULL; HRESULT hr = CreateFileMoniker(TKWINSEND_REGISTRATION_BASE, &pmkClass); if (SUCCEEDED(hr)) { LPMONIKER pmkItem = NULL; Tcl_DString dString; Tcl_DStringInit(&dString); Tcl_UtfToUniCharDString(name, -1, &dString); hr = CreateFileMoniker((LPOLESTR)Tcl_DStringValue(&dString), &pmkItem); Tcl_DStringFree(&dString); if (SUCCEEDED(hr)) { hr = pmkClass->lpVtbl->ComposeWith(pmkClass, pmkItem, FALSE, ppmk); pmkItem->lpVtbl->Release(pmkItem); } pmkClass->lpVtbl->Release(pmkClass); } return hr; }
LPMONIKER COleDocument::GetMoniker(OLEGETMONIKER /*nAssign*/) { USES_CONVERSION; ASSERT_VALID(this); // no moniker for untitled documents if (m_strPathName.IsEmpty()) return NULL; // return file moniker based on current path name LPMONIKER lpMoniker; CreateFileMoniker(T2COLE(m_strPathName), &lpMoniker); return lpMoniker; }
/*********************************************************************** * HlinkParseDisplayName (HLINK.@) */ HRESULT WINAPI HlinkParseDisplayName(LPBC pibc, LPCWSTR pwzDisplayName, BOOL fNoForceAbs, ULONG *pcchEaten, IMoniker **ppimk) { static const WCHAR file_colonW[] = {'f','i','l','e',':'}; ULONG eaten = 0; HRESULT hres; TRACE("(%p %s %x %p %p)\n", pibc, debugstr_w(pwzDisplayName), fNoForceAbs, pcchEaten, ppimk); if(fNoForceAbs) FIXME("Unsupported fNoForceAbs\n"); if(!strncmpiW(pwzDisplayName, file_colonW, sizeof(file_colonW)/sizeof(WCHAR))) { pwzDisplayName += sizeof(file_colonW)/sizeof(WCHAR); eaten += sizeof(file_colonW)/sizeof(WCHAR); while(*pwzDisplayName == '/') { pwzDisplayName++; eaten++; } }else { hres = MkParseDisplayNameEx(pibc, pwzDisplayName, pcchEaten, ppimk); if(SUCCEEDED(hres)) return hres; hres = MkParseDisplayName(pibc, pwzDisplayName, pcchEaten, ppimk); if(SUCCEEDED(hres)) return hres; } hres = CreateFileMoniker(pwzDisplayName, ppimk); if(SUCCEEDED(hres)) *pcchEaten = eaten + strlenW(pwzDisplayName); return hres; }
/*********************************************************************** * HlinkParseDisplayName (HLINK.@) */ HRESULT WINAPI HlinkParseDisplayName(LPBC pibc, LPCWSTR pwzDisplayName, BOOL fNoForceAbs, ULONG *pcchEaten, IMoniker **ppimk) { HRESULT hres; TRACE("(%p %s %x %p %p)\n", pibc, debugstr_w(pwzDisplayName), fNoForceAbs, pcchEaten, ppimk); if(fNoForceAbs) FIXME("Unsupported fNoForceAbs\n"); hres = MkParseDisplayNameEx(pibc, pwzDisplayName, pcchEaten, ppimk); if(SUCCEEDED(hres)) return hres; hres = MkParseDisplayName(pibc, pwzDisplayName, pcchEaten, ppimk); if(SUCCEEDED(hres)) return hres; hres = CreateFileMoniker(pwzDisplayName, ppimk); if(SUCCEEDED(hres)) *pcchEaten = strlenW(pwzDisplayName); return hres; }
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; }
static HRESULT WINAPI IHlink_fnSetStringReference(IHlink* iface, DWORD grfHLSETF, LPCWSTR pwzTarget, LPCWSTR pwzLocation) { HlinkImpl *This = impl_from_IHlink(iface); TRACE("(%p)->(%i %s %s)\n", This, grfHLSETF, debugstr_w(pwzTarget), debugstr_w(pwzLocation)); if(grfHLSETF > (HLINKSETF_TARGET | HLINKSETF_LOCATION) && grfHLSETF < -(HLINKSETF_TARGET | HLINKSETF_LOCATION)) return grfHLSETF; if (grfHLSETF & HLINKSETF_TARGET) { if (This->Moniker) { IMoniker_Release(This->Moniker); This->Moniker = NULL; } if (pwzTarget && *pwzTarget) { IMoniker *pMon; IBindCtx *pbc = NULL; ULONG eaten; HRESULT r; r = CreateBindCtx(0, &pbc); if (FAILED(r)) return E_OUTOFMEMORY; r = MkParseDisplayName(pbc, pwzTarget, &eaten, &pMon); IBindCtx_Release(pbc); if (FAILED(r)) { LPCWSTR p = strchrW(pwzTarget, ':'); if (p && (p - pwzTarget > 1)) r = CreateURLMoniker(NULL, pwzTarget, &pMon); else r = CreateFileMoniker(pwzTarget, &pMon); if (FAILED(r)) { ERR("couldn't create moniker for %s, failed with error 0x%08x\n", debugstr_w(pwzTarget), r); return r; } } IHlink_SetMonikerReference(iface, HLINKSETF_TARGET, pMon, NULL); IMoniker_Release(pMon); } } if (grfHLSETF & HLINKSETF_LOCATION) { heap_free(This->Location); This->Location = NULL; if (pwzLocation && *pwzLocation) This->Location = hlink_strdupW( pwzLocation ); } return S_OK; }
/****************************************************************************** * FileMoniker_CommonPrefixWith */ static HRESULT WINAPI FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix) { LPOLESTR pathThis,pathOther,*stringTable1,*stringTable2,commonPath; IBindCtx *pbind; DWORD mkSys; ULONG nb1,nb2,i,sameIdx; BOOL machineNameCase = FALSE; if (ppmkPrefix==NULL) return E_POINTER; if (pmkOther==NULL) return E_INVALIDARG; *ppmkPrefix=0; /* check if we have the same type of moniker */ IMoniker_IsSystemMoniker(pmkOther,&mkSys); if(mkSys==MKSYS_FILEMONIKER){ HRESULT ret; ret = CreateBindCtx(0,&pbind); if (FAILED(ret)) return ret; /* create a string based on common part of the two paths */ ret = IMoniker_GetDisplayName(iface,pbind,NULL,&pathThis); if (FAILED(ret)) return ret; ret = IMoniker_GetDisplayName(pmkOther,pbind,NULL,&pathOther); if (FAILED(ret)) return ret; nb1=FileMonikerImpl_DecomposePath(pathThis,&stringTable1); if (FAILED(nb1)) return nb1; nb2=FileMonikerImpl_DecomposePath(pathOther,&stringTable2); if (FAILED(nb2)) { free_stringtable(stringTable1); return nb2; } if (nb1==0 || nb2==0) { free_stringtable(stringTable1); free_stringtable(stringTable2); return MK_E_NOPREFIX; } commonPath=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(min(lstrlenW(pathThis),lstrlenW(pathOther))+1)); if (!commonPath) return E_OUTOFMEMORY; *commonPath=0; for(sameIdx=0; ( (stringTable1[sameIdx]!=NULL) && (stringTable2[sameIdx]!=NULL) && (lstrcmpiW(stringTable1[sameIdx],stringTable2[sameIdx])==0)); sameIdx++); if (sameIdx > 1 && *stringTable1[0]=='\\' && *stringTable2[1]=='\\'){ machineNameCase = TRUE; for(i=2;i<sameIdx;i++) if( (*stringTable1[i]=='\\') && (i+1 < sameIdx) && (*stringTable1[i+1]=='\\') ){ machineNameCase = FALSE; break; } } if (machineNameCase && *stringTable1[sameIdx-1]=='\\') sameIdx--; if (machineNameCase && (sameIdx<=3) && (nb1 > 3 || nb2 > 3) ) ret = MK_E_NOPREFIX; else { for(i=0;i<sameIdx;i++) strcatW(commonPath,stringTable1[i]); free_stringtable(stringTable1); free_stringtable(stringTable2); ret = CreateFileMoniker(commonPath,ppmkPrefix); } HeapFree(GetProcessHeap(),0,commonPath); return ret; } else return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix); }
/****************************************************************************** * 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); }
HRESULT FileMoniker_CreateFromDisplayName(LPBC pbc, LPCOLESTR szDisplayName, LPDWORD pchEaten, IMoniker **ppmk) { LPCWSTR end; static const WCHAR wszSeparators[] = {':','\\','/','!',0}; for (end = szDisplayName + strlenW(szDisplayName); end && (end != szDisplayName); end = memrpbrkW(szDisplayName, end - szDisplayName, wszSeparators)) { HRESULT hr; IRunningObjectTable *rot; IMoniker *file_moniker; LPWSTR file_display_name; LPWSTR full_path_name; DWORD full_path_name_len; int len = end - szDisplayName; file_display_name = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR)); if (!file_display_name) return E_OUTOFMEMORY; memcpy(file_display_name, szDisplayName, len * sizeof(WCHAR)); file_display_name[len] = '\0'; hr = CreateFileMoniker(file_display_name, &file_moniker); if (FAILED(hr)) { HeapFree(GetProcessHeap(), 0, file_display_name); return hr; } hr = IBindCtx_GetRunningObjectTable(pbc, &rot); if (FAILED(hr)) { HeapFree(GetProcessHeap(), 0, file_display_name); IMoniker_Release(file_moniker); return hr; } hr = IRunningObjectTable_IsRunning(rot, file_moniker); IRunningObjectTable_Release(rot); if (FAILED(hr)) { HeapFree(GetProcessHeap(), 0, file_display_name); IMoniker_Release(file_moniker); return hr; } if (hr == S_OK) { TRACE("found running file moniker for %s\n", debugstr_w(file_display_name)); *pchEaten = len; *ppmk = file_moniker; HeapFree(GetProcessHeap(), 0, file_display_name); return S_OK; } full_path_name_len = GetFullPathNameW(file_display_name, 0, NULL, NULL); if (!full_path_name_len) { HeapFree(GetProcessHeap(), 0, file_display_name); IMoniker_Release(file_moniker); return MK_E_SYNTAX; } full_path_name = HeapAlloc(GetProcessHeap(), 0, full_path_name_len * sizeof(WCHAR)); if (!full_path_name) { HeapFree(GetProcessHeap(), 0, file_display_name); IMoniker_Release(file_moniker); return E_OUTOFMEMORY; } GetFullPathNameW(file_display_name, full_path_name_len, full_path_name, NULL); if (GetFileAttributesW(full_path_name) == INVALID_FILE_ATTRIBUTES) TRACE("couldn't open file %s\n", debugstr_w(full_path_name)); else { TRACE("got file moniker for %s\n", debugstr_w(szDisplayName)); *pchEaten = len; *ppmk = file_moniker; HeapFree(GetProcessHeap(), 0, file_display_name); HeapFree(GetProcessHeap(), 0, full_path_name); return S_OK; } HeapFree(GetProcessHeap(), 0, file_display_name); HeapFree(GetProcessHeap(), 0, full_path_name); IMoniker_Release(file_moniker); } return MK_E_CANTOPENFILE; }
/****************************************************************************** * FileMoniker_RelativePathTo */ static HRESULT WINAPI FileMonikerImpl_RelativePathTo(IMoniker* iface,IMoniker* pmOther, IMoniker** ppmkRelPath) { IBindCtx *bind; HRESULT res; LPOLESTR str1=0,str2=0,*tabStr1=0,*tabStr2=0,relPath=0; DWORD len1=0,len2=0,sameIdx=0,j=0; static const WCHAR back[] ={'.','.','\\',0}; TRACE("(%p,%p,%p)\n",iface,pmOther,ppmkRelPath); if (ppmkRelPath==NULL) return E_POINTER; if (pmOther==NULL) return E_INVALIDARG; res=CreateBindCtx(0,&bind); if (FAILED(res)) return res; res=IMoniker_GetDisplayName(iface,bind,NULL,&str1); if (FAILED(res)) return res; res=IMoniker_GetDisplayName(pmOther,bind,NULL,&str2); if (FAILED(res)) return res; len1=FileMonikerImpl_DecomposePath(str1,&tabStr1); if (FAILED(len1)) return E_OUTOFMEMORY; len2=FileMonikerImpl_DecomposePath(str2,&tabStr2); if (FAILED(len2)) { free_stringtable(tabStr1); return E_OUTOFMEMORY; } /* count the number of similar items from the begin of the two paths */ for(sameIdx=0; ( (tabStr1[sameIdx]!=NULL) && (tabStr2[sameIdx]!=NULL) && (lstrcmpiW(tabStr1[sameIdx],tabStr2[sameIdx])==0)); sameIdx++); /* begin the construction of relativePath */ /* if the two paths have a consecutive similar item from the begin ! the relativePath will be composed */ /* by "..\\" in the begin */ relPath=HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(1+lstrlenW(str1)+lstrlenW(str2))); *relPath=0; if (len2>0 && !(len1==1 && len2==1 && sameIdx==0)) for(j=sameIdx;(tabStr1[j] != NULL); j++) if (*tabStr1[j]!='\\') strcatW(relPath,back); /* add items of the second path (similar items with the first path are not included) to the relativePath */ for(j=sameIdx;tabStr2[j]!=NULL;j++) strcatW(relPath,tabStr2[j]); res=CreateFileMoniker(relPath,ppmkRelPath); free_stringtable(tabStr1); free_stringtable(tabStr2); CoTaskMemFree(str1); CoTaskMemFree(str2); HeapFree(GetProcessHeap(),0,relPath); if (len1==0 || len2==0 || (len1==1 && len2==1 && sameIdx==0)) return MK_S_HIM; return res; }
/****************************************************************************** * FileMoniker_CommonPrefixWith */ static HRESULT WINAPI FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix) { LPOLESTR pathThis = NULL, pathOther = NULL, *stringTable1 = NULL; LPOLESTR *stringTable2 = NULL, commonPath = NULL; IBindCtx *bindctx; DWORD mkSys; ULONG nb1,nb2,i,sameIdx; BOOL machineNameCase = FALSE; HRESULT ret; if (ppmkPrefix==NULL) return E_POINTER; if (pmkOther==NULL) return E_INVALIDARG; *ppmkPrefix=0; /* check if we have the same type of moniker */ IMoniker_IsSystemMoniker(pmkOther,&mkSys); if (mkSys != MKSYS_FILEMONIKER) return MonikerCommonPrefixWith(iface, pmkOther, ppmkPrefix); ret = CreateBindCtx(0, &bindctx); if (FAILED(ret)) return ret; /* create a string based on common part of the two paths */ ret = IMoniker_GetDisplayName(iface, bindctx, NULL, &pathThis); if (FAILED(ret)) goto failed; ret = IMoniker_GetDisplayName(pmkOther, bindctx, NULL, &pathOther); if (FAILED(ret)) goto failed; nb1 = FileMonikerImpl_DecomposePath(pathThis, &stringTable1); if (FAILED(nb1)) { ret = nb1; goto failed; } nb2 = FileMonikerImpl_DecomposePath(pathOther, &stringTable2); if (FAILED(nb2)) { ret = nb2; goto failed; } if (nb1 == 0 || nb2 == 0) { ret = MK_E_NOPREFIX; goto failed; } commonPath = CoTaskMemAlloc(sizeof(WCHAR)*(min(lstrlenW(pathThis),lstrlenW(pathOther))+1)); if (!commonPath) { ret = E_OUTOFMEMORY; goto failed; } *commonPath = 0; for(sameIdx=0; ( (stringTable1[sameIdx]!=NULL) && (stringTable2[sameIdx]!=NULL) && (lstrcmpiW(stringTable1[sameIdx],stringTable2[sameIdx])==0)); sameIdx++); if (sameIdx > 1 && *stringTable1[0]=='\\' && *stringTable2[1]=='\\'){ machineNameCase = TRUE; for(i=2;i<sameIdx;i++) if( (*stringTable1[i]=='\\') && (i+1 < sameIdx) && (*stringTable1[i+1]=='\\') ){ machineNameCase = FALSE; break; } } if (machineNameCase && *stringTable1[sameIdx-1]=='\\') sameIdx--; if (machineNameCase && (sameIdx<=3) && (nb1 > 3 || nb2 > 3) ) ret = MK_E_NOPREFIX; else { for (i = 0; i < sameIdx; i++) strcatW(commonPath,stringTable1[i]); ret = CreateFileMoniker(commonPath, ppmkPrefix); } failed: IBindCtx_Release(bindctx); CoTaskMemFree(pathThis); CoTaskMemFree(pathOther); CoTaskMemFree(commonPath); if (stringTable1) free_stringtable(stringTable1); if (stringTable2) free_stringtable(stringTable2); return ret; }
BOOL COleLinkingDoc::Register(COleObjectFactory* pFactory, LPCTSTR lpszPathName) { ASSERT_VALID(this); ASSERT(pFactory == NULL || AfxIsValidAddress(pFactory, sizeof(COleObjectFactory))); ASSERT(lpszPathName == NULL || AfxIsValidString(lpszPathName)); ASSERT(m_dwRegister == 0); // attach the document to the server ASSERT(m_pFactory == NULL || m_pFactory == pFactory); m_pFactory = pFactory; BOOL bResult = TRUE; // create file moniker based on path name RELEASE(m_lpMonikerROT); m_strMoniker.Empty(); if (lpszPathName != NULL) { if (CreateFileMoniker(CStringW(lpszPathName), &m_lpMonikerROT) != S_OK) bResult = FALSE; } // register file moniker as running if (m_lpMonikerROT != NULL) { // see if the object is already running in the ROT LPRUNNINGOBJECTTABLE lpROT = NULL; VERIFY(GetRunningObjectTable(0, &lpROT) == S_OK); ASSERT(lpROT != NULL); LPUNKNOWN lpUnk; if (lpROT->GetObject(m_lpMonikerROT, &lpUnk) == S_OK) { // fatal error -- can't register same moniker twice! lpUnk->Release(); RELEASE(m_lpMonikerROT); return FALSE; } // not already running -- so ok to attempt registration SCODE sc = lpROT->Register(NULL, (LPUNKNOWN) GetInterface(&IID_IUnknown), m_lpMonikerROT, &m_dwRegister); lpROT->Release(); m_strMoniker = lpszPathName; if (sc != S_OK) bResult = FALSE; } // update all objects with new moniker POSITION pos = GetStartPosition(); COleClientItem* pItem; while ((pItem = GetNextClientItem(pos)) != NULL) { if (pItem->m_bMoniker) { ASSERT(pItem->m_lpObject != NULL); pItem->m_lpObject->SetMoniker(OLEWHICHMK_CONTAINER, m_lpMonikerROT); } } return bResult; }