/****************************************************************************** * ClassMoniker_CommonPrefixWith ******************************************************************************/ static HRESULT WINAPI ClassMoniker_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix) { DWORD mkSys; TRACE("(%p, %p)\n", pmkOther, ppmkPrefix); *ppmkPrefix = NULL; IMoniker_IsSystemMoniker(pmkOther, &mkSys); /* If the other moniker is an class moniker that is equal to this moniker, this method sets *ppmkPrefix */ /* to this moniker and returns MK_S_US */ if (mkSys == MKSYS_CLASSMONIKER) { if (IMoniker_IsEqual(iface, pmkOther) == S_OK) { *ppmkPrefix = iface; IMoniker_AddRef(iface); return MK_S_US; } else return MK_E_NOPREFIX; } else /* otherwise, the method calls the MonikerCommonPrefixWith function. This function correctly handles */ /* the case where the other moniker is a generic composite. */ return MonikerCommonPrefixWith(iface, pmkOther, ppmkPrefix); }
/****************************************************************************** * AntiMoniker_CommonPrefixWith ******************************************************************************/ static HRESULT WINAPI AntiMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix) { DWORD mkSys; IMoniker_IsSystemMoniker(pmkOther,&mkSys); if(mkSys==MKSYS_ANTIMONIKER){ IMoniker_AddRef(iface); *ppmkPrefix=iface; IMoniker_AddRef(iface); return MK_S_US; } else return MonikerCommonPrefixWith(iface,pmkOther,ppmkPrefix); }
/****************************************************************************** * 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_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; }