static void test_SHCreateQueryCancelAutoPlayMoniker(void) { IBindCtx *ctxt; IMoniker *mon; IUnknown *unk; CLSID clsid; HRESULT hr; DWORD sys; if (!pSHCreateQueryCancelAutoPlayMoniker) { win_skip("SHCreateQueryCancelAutoPlayMoniker is not available, skipping tests.\n"); return; } hr = pSHCreateQueryCancelAutoPlayMoniker(NULL); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); hr = pSHCreateQueryCancelAutoPlayMoniker(&mon); ok(hr == S_OK, "got 0x%08x\n", hr); sys = -1; hr = IMoniker_IsSystemMoniker(mon, &sys); ok(hr == S_OK, "got 0x%08x\n", hr); ok(sys == MKSYS_CLASSMONIKER, "got %d\n", sys); memset(&clsid, 0, sizeof(clsid)); hr = IMoniker_GetClassID(mon, &clsid); ok(hr == S_OK, "got 0x%08x\n", hr); ok(IsEqualGUID(&clsid, &CLSID_ClassMoniker), "got %s\n", wine_dbgstr_guid(&clsid)); /* extract used CLSID that implements this hook */ SET_EXPECT(autoplay_BindToObject); SET_EXPECT(autoplay_GetClassObject); CreateBindCtx(0, &ctxt); hr = IMoniker_BindToObject(mon, ctxt, &test_moniker, &IID_IQueryCancelAutoPlay, (void**)&unk); ok(hr == E_NOTIMPL, "got 0x%08x\n", hr); IBindCtx_Release(ctxt); CHECK_CALLED(autoplay_BindToObject); CHECK_CALLED(autoplay_GetClassObject); IMoniker_Release(mon); }
/****************************************************************************** * 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); }
/****************************************************************************** * PointerMoniker_IsEqual ******************************************************************************/ static HRESULT WINAPI PointerMonikerImpl_IsEqual(IMoniker* iface,IMoniker* pmkOtherMoniker) { PointerMonikerImpl *This = impl_from_IMoniker(iface); DWORD mkSys; TRACE("(%p,%p)\n",iface,pmkOtherMoniker); if (pmkOtherMoniker==NULL) return S_FALSE; IMoniker_IsSystemMoniker(pmkOtherMoniker,&mkSys); if (mkSys==MKSYS_POINTERMONIKER) { PointerMonikerImpl *pOtherMoniker = impl_from_IMoniker(pmkOtherMoniker); return This->pObject == pOtherMoniker->pObject ? S_OK : S_FALSE; } else return S_FALSE; }
/****************************************************************************** * ItemMoniker_CommonPrefixWith ******************************************************************************/ static HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix) { DWORD mkSys; TRACE("(%p,%p)\n", pmkOther, ppmkPrefix); IMoniker_IsSystemMoniker(pmkOther,&mkSys); /* If the other moniker is an item moniker that is equal to this moniker, this method sets *ppmkPrefix */ /* to this moniker and returns MK_S_US */ if((mkSys==MKSYS_ITEMMONIKER) && (IMoniker_IsEqual(iface,pmkOther)==S_OK) ){ *ppmkPrefix=iface; IMoniker_AddRef(iface); return MK_S_US; } 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); }
/****************************************************************************** * 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; }
/****************************************************************************** * 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); }
/****************************************************************************** * 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; }
static void test_HlinkParseDisplayName(void) { IMoniker *mon = NULL; LPWSTR name; DWORD issys; ULONG eaten = 0; IBindCtx *bctx; HRESULT hres; static const WCHAR winehq_urlW[] = { 'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g', '/','s','i','t','e','/','a','b','o','u','t',0 }; static const WCHAR invalid_urlW[] = {'t','e','s','t',':','1','2','3','a','b','c',0}; static const WCHAR clsid_nameW[] = {'c','l','s','i','d',':', '2','0','D','0','4','F','E','0','-','3','A','E','A','-','1','0','6','9','-','A','2','D','8', '-','0','8','0','0','2','B','3','0','3','0','9','D',':',0 }; CreateBindCtx(0, &bctx); hres = HlinkParseDisplayName(bctx, winehq_urlW, FALSE, &eaten, &mon); ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres); ok(eaten == sizeof(winehq_urlW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten); ok(mon != NULL, "mon == NULL\n"); hres = IMoniker_GetDisplayName(mon, bctx, 0, &name); ok(hres == S_OK, "GetDiasplayName failed: %08x\n", hres); ok(!lstrcmpW(name, winehq_urlW), "wrong display name %s\n", debugstr_w(name)); CoTaskMemFree(name); hres = IMoniker_IsSystemMoniker(mon, &issys); ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres); ok(issys == MKSYS_URLMONIKER, "issys=%x\n", issys); IMoniker_Release(mon); hres = HlinkParseDisplayName(bctx, clsid_nameW, FALSE, &eaten, &mon); ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres); ok(eaten == sizeof(clsid_nameW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten); ok(mon != NULL, "mon == NULL\n"); hres = IMoniker_IsSystemMoniker(mon, &issys); ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres); ok(issys == MKSYS_CLASSMONIKER, "issys=%x\n", issys); IMoniker_Release(mon); hres = HlinkParseDisplayName(bctx, invalid_urlW, FALSE, &eaten, &mon); ok(hres == S_OK, "HlinkParseDisplayName failed: %08x\n", hres); ok(eaten == sizeof(invalid_urlW)/sizeof(WCHAR)-1, "eaten=%d\n", eaten); ok(mon != NULL, "mon == NULL\n"); hres = IMoniker_GetDisplayName(mon, bctx, 0, &name); ok(hres == S_OK, "GetDiasplayName failed: %08x\n", hres); ok(!lstrcmpW(name, invalid_urlW), "wrong display name %s\n", debugstr_w(name)); CoTaskMemFree(name); hres = IMoniker_IsSystemMoniker(mon, &issys); ok(hres == S_OK, "IsSystemMoniker failed: %08x\n", hres); ok(issys == MKSYS_FILEMONIKER, "issys=%x\n", issys); IBindCtx_Release(bctx); }