ReactOS  0.4.14-dev-115-g4576127
link.c
Go to the documentation of this file.
1 /*
2  * Implementation of hyperlinking (hlink.dll)
3  *
4  * Copyright 2005 Aric Stewart for CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include "hlink_private.h"
22 
23 #include "shellapi.h"
24 #include "hlguids.h"
25 
26 #include "wine/debug.h"
27 
29 
30 #define HLINK_SAVE_MAGIC 0x00000002
31 #define HLINK_SAVE_MONIKER_PRESENT 0x01
32 #define HLINK_SAVE_MONIKER_IS_ABSOLUTE 0x02
33 #define HLINK_SAVE_LOCATION_PRESENT 0x08
34 #define HLINK_SAVE_FRIENDLY_PRESENT 0x10
35 /* 0x20, 0x40 unknown */
36 #define HLINK_SAVE_TARGET_FRAME_PRESENT 0x80
37 /* known flags */
38 #define HLINK_SAVE_ALL (HLINK_SAVE_TARGET_FRAME_PRESENT|HLINK_SAVE_FRIENDLY_PRESENT|HLINK_SAVE_LOCATION_PRESENT|0x04|HLINK_SAVE_MONIKER_IS_ABSOLUTE|HLINK_SAVE_MONIKER_PRESENT)
39 
40 typedef struct
41 {
44 
47 
55 
61 } HlinkImpl;
62 
63 static inline HlinkImpl *impl_from_IHlink(IHlink *iface)
64 {
65  return CONTAINING_RECORD(iface, HlinkImpl, IHlink_iface);
66 }
67 
68 
70 {
71  return CONTAINING_RECORD(iface, HlinkImpl, IPersistStream_iface);
72 }
73 
75 {
76  return CONTAINING_RECORD(iface, HlinkImpl, IDataObject_iface);
77 }
78 
80  DWORD ref_type)
81 {
82  HRESULT hres;
83 
84  if (ref_type == HLINKGETREF_DEFAULT)
85  ref_type = HLINKGETREF_RELATIVE;
86 
87  if (This->Moniker)
88  {
89  DWORD mktype = MKSYS_NONE;
90 
91  hres = IMoniker_IsSystemMoniker(This->Moniker, &mktype);
92  if (hres == S_OK && mktype != MKSYS_NONE)
93  {
94  *moniker = This->Moniker;
95  IMoniker_AddRef(*moniker);
96  return S_OK;
97  }
98  }
99 
100  if (ref_type == HLINKGETREF_ABSOLUTE && This->Site)
101  {
102  IMoniker *hls_moniker;
103 
104  hres = IHlinkSite_GetMoniker(This->Site, This->SiteData,
105  OLEGETMONIKER_FORCEASSIGN, OLEWHICHMK_CONTAINER, &hls_moniker);
106  if (FAILED(hres))
107  return hres;
108 
109  if (This->Moniker)
110  {
111  hres = IMoniker_ComposeWith(hls_moniker, This->Moniker, FALSE,
112  moniker);
113  IMoniker_Release(hls_moniker);
114  return hres;
115  }
116 
117  *moniker = hls_moniker;
118  return S_OK;
119  }
120 
121  *moniker = This->Moniker;
122  if (*moniker)
123  IMoniker_AddRef(*moniker);
124 
125  return S_OK;
126 }
127 
129  LPVOID *ppvObj)
130 {
131  HlinkImpl *This = impl_from_IHlink(iface);
132 
133  TRACE ("(%p)->(%s,%p)\n", This, debugstr_guid (riid), ppvObj);
134 
135  *ppvObj = NULL;
136 
137  if (IsEqualIID(riid, &IID_IUnknown) || (IsEqualIID(riid, &IID_IHlink)))
138  *ppvObj = &This->IHlink_iface;
139  else if (IsEqualIID(riid, &IID_IPersistStream))
140  *ppvObj = &This->IPersistStream_iface;
141  else if (IsEqualIID(riid, &IID_IDataObject))
142  *ppvObj = &This->IDataObject_iface;
143 
144  if (*ppvObj)
145  {
146  IUnknown_AddRef((IUnknown*)(*ppvObj));
147  return S_OK;
148  }
149  return E_NOINTERFACE;
150 }
151 
153 {
154  HlinkImpl *This = impl_from_IHlink(iface);
155  ULONG refCount = InterlockedIncrement(&This->ref);
156 
157  TRACE("(%p)->(count=%u)\n", This, refCount - 1);
158 
159  return refCount;
160 }
161 
163 {
164  HlinkImpl *This = impl_from_IHlink(iface);
165  ULONG refCount = InterlockedDecrement(&This->ref);
166 
167  TRACE("(%p)->(count=%u)\n", This, refCount + 1);
168  if (refCount)
169  return refCount;
170 
171  TRACE("-- destroying IHlink (%p)\n", This);
172  heap_free(This->FriendlyName);
173  heap_free(This->TargetFrameName);
174  heap_free(This->Location);
175  if (This->Moniker)
176  IMoniker_Release(This->Moniker);
177  if (This->Site)
178  IHlinkSite_Release(This->Site);
179  heap_free(This);
180  return 0;
181 }
182 
184  IHlinkSite* pihlSite, DWORD dwSiteData)
185 {
186  HlinkImpl *This = impl_from_IHlink(iface);
187 
188  TRACE("(%p)->(%p %i)\n", This, pihlSite, dwSiteData);
189 
190  if (This->Site)
191  IHlinkSite_Release(This->Site);
192 
193  This->Site = pihlSite;
194  if (This->Site)
195  IHlinkSite_AddRef(This->Site);
196 
197  This->SiteData = dwSiteData;
198 
199  return S_OK;
200 }
201 
203  IHlinkSite** ppihlSite, DWORD *pdwSiteData)
204 {
205  HlinkImpl *This = impl_from_IHlink(iface);
206 
207  TRACE("(%p)->(%p %p)\n", This, ppihlSite, pdwSiteData);
208 
209  *ppihlSite = This->Site;
210 
211  if (This->Site) {
212  IHlinkSite_AddRef(This->Site);
213  *pdwSiteData = This->SiteData;
214  }
215 
216  return S_OK;
217 }
218 
220  DWORD rfHLSETF, IMoniker *pmkTarget, LPCWSTR pwzLocation)
221 {
222  HlinkImpl *This = impl_from_IHlink(iface);
223 
224  TRACE("(%p)->(%i %p %s)\n", This, rfHLSETF, pmkTarget,
225  debugstr_w(pwzLocation));
226 
227  if(rfHLSETF == 0)
228  return E_INVALIDARG;
229  if(!(rfHLSETF & (HLINKSETF_TARGET | HLINKSETF_LOCATION)))
230  return rfHLSETF;
231 
232  if(rfHLSETF & HLINKSETF_TARGET){
233  if (This->Moniker)
234  IMoniker_Release(This->Moniker);
235 
236  This->Moniker = pmkTarget;
237  if (This->Moniker)
238  {
239  IBindCtx *pbc;
240  LPOLESTR display_name;
241  IMoniker_AddRef(This->Moniker);
242  CreateBindCtx( 0, &pbc);
243  IMoniker_GetDisplayName(This->Moniker, pbc, NULL, &display_name);
244  IBindCtx_Release(pbc);
245  This->absolute = display_name && strchrW(display_name, ':');
246  CoTaskMemFree(display_name);
247  }
248  }
249 
250  if(rfHLSETF & HLINKSETF_LOCATION){
251  heap_free(This->Location);
252  This->Location = hlink_strdupW( pwzLocation );
253  }
254 
255  return S_OK;
256 }
257 
259  DWORD grfHLSETF, LPCWSTR pwzTarget, LPCWSTR pwzLocation)
260 {
261  HlinkImpl *This = impl_from_IHlink(iface);
262 
263  TRACE("(%p)->(%i %s %s)\n", This, grfHLSETF, debugstr_w(pwzTarget),
264  debugstr_w(pwzLocation));
265 
266  if(grfHLSETF > (HLINKSETF_TARGET | HLINKSETF_LOCATION) &&
267  grfHLSETF < -(HLINKSETF_TARGET | HLINKSETF_LOCATION))
268  return grfHLSETF;
269 
270  if (grfHLSETF & HLINKSETF_TARGET)
271  {
272  if (This->Moniker)
273  {
274  IMoniker_Release(This->Moniker);
275  This->Moniker = NULL;
276  }
277  if (pwzTarget && *pwzTarget)
278  {
279  IMoniker *pMon;
280  IBindCtx *pbc = NULL;
281  ULONG eaten;
282  HRESULT r;
283 
284  r = CreateBindCtx(0, &pbc);
285  if (FAILED(r))
286  return E_OUTOFMEMORY;
287 
288  r = MkParseDisplayName(pbc, pwzTarget, &eaten, &pMon);
289  IBindCtx_Release(pbc);
290 
291  if (FAILED(r))
292  {
293  LPCWSTR p = strchrW(pwzTarget, ':');
294  if (p && (p - pwzTarget > 1))
295  r = CreateURLMoniker(NULL, pwzTarget, &pMon);
296  else
297  r = CreateFileMoniker(pwzTarget, &pMon);
298  if (FAILED(r))
299  {
300  ERR("couldn't create moniker for %s, failed with error 0x%08x\n",
301  debugstr_w(pwzTarget), r);
302  return r;
303  }
304  }
305 
306  IHlink_SetMonikerReference(iface, HLINKSETF_TARGET, pMon, NULL);
307  IMoniker_Release(pMon);
308  }
309  }
310 
311  if (grfHLSETF & HLINKSETF_LOCATION)
312  {
313  heap_free(This->Location);
314  This->Location = NULL;
315  if (pwzLocation && *pwzLocation)
316  This->Location = hlink_strdupW( pwzLocation );
317  }
318 
319  return S_OK;
320 }
321 
323  DWORD dwWhichRef, IMoniker **ppimkTarget, LPWSTR *ppwzLocation)
324 {
325  HlinkImpl *This = impl_from_IHlink(iface);
326 
327  TRACE("(%p) -> (%i %p %p)\n", This, dwWhichRef, ppimkTarget,
328  ppwzLocation);
329 
330  if (ppimkTarget)
331  {
332  HRESULT hres = __GetMoniker(This, ppimkTarget, dwWhichRef);
333  if (FAILED(hres))
334  {
335  if (ppwzLocation)
336  *ppwzLocation = NULL;
337  return hres;
338  }
339  }
340 
341  if (ppwzLocation)
342  IHlink_GetStringReference(iface, dwWhichRef, NULL, ppwzLocation);
343 
344  return S_OK;
345 }
346 
348  DWORD dwWhichRef, LPWSTR *ppwzTarget, LPWSTR *ppwzLocation)
349 {
350  HlinkImpl *This = impl_from_IHlink(iface);
351 
352  TRACE("(%p) -> (%i %p %p)\n", This, dwWhichRef, ppwzTarget, ppwzLocation);
353 
354  if(dwWhichRef != -1 && dwWhichRef & ~(HLINKGETREF_DEFAULT | HLINKGETREF_ABSOLUTE | HLINKGETREF_RELATIVE))
355  {
356  if(ppwzTarget)
357  *ppwzTarget = NULL;
358  if(ppwzLocation)
359  *ppwzLocation = NULL;
360  return E_INVALIDARG;
361  }
362 
363  if (ppwzTarget)
364  {
365  IMoniker* mon;
366  HRESULT hres = __GetMoniker(This, &mon, dwWhichRef);
367  if (FAILED(hres))
368  {
369  if (ppwzLocation)
370  *ppwzLocation = NULL;
371  return hres;
372  }
373  if (mon)
374  {
375  IBindCtx *pbc;
376 
377  CreateBindCtx( 0, &pbc);
378  IMoniker_GetDisplayName(mon, pbc, NULL, ppwzTarget);
379  IBindCtx_Release(pbc);
380  IMoniker_Release(mon);
381  }
382  else
383  *ppwzTarget = NULL;
384  }
385  if (ppwzLocation)
386  *ppwzLocation = hlink_co_strdupW( This->Location );
387 
388  TRACE("(Target: %s Location: %s)\n",
389  (ppwzTarget)?debugstr_w(*ppwzTarget):"<NULL>",
390  (ppwzLocation)?debugstr_w(*ppwzLocation):"<NULL>");
391 
392  return S_OK;
393 }
394 
396  LPCWSTR pwzFriendlyName)
397 {
398  HlinkImpl *This = impl_from_IHlink(iface);
399 
400  TRACE("(%p) -> (%s)\n", This, debugstr_w(pwzFriendlyName));
401 
402  heap_free(This->FriendlyName);
403  This->FriendlyName = hlink_strdupW( pwzFriendlyName );
404 
405  return S_OK;
406 }
407 
409  DWORD grfHLFNAMEF, LPWSTR* ppwzFriendlyName)
410 {
411  HlinkImpl *This = impl_from_IHlink(iface);
412 
413  TRACE("(%p) -> (%i %p)\n", This, grfHLFNAMEF, ppwzFriendlyName);
414 
415  /* FIXME: Only using explicitly set and cached friendly names */
416 
417  if (This->FriendlyName)
418  *ppwzFriendlyName = hlink_co_strdupW( This->FriendlyName );
419  else
420  {
421  IMoniker *moniker;
422  HRESULT hres = __GetMoniker(This, &moniker, HLINKGETREF_DEFAULT);
423  if (FAILED(hres))
424  {
425  *ppwzFriendlyName = NULL;
426  return hres;
427  }
428  if (moniker)
429  {
430  IBindCtx *bcxt;
431  CreateBindCtx(0, &bcxt);
432 
433  IMoniker_GetDisplayName(moniker, bcxt, NULL, ppwzFriendlyName);
434  IBindCtx_Release(bcxt);
435  IMoniker_Release(moniker);
436  }
437  else
438  *ppwzFriendlyName = NULL;
439  }
440 
441  return S_OK;
442 }
443 
445  LPCWSTR pwzTargetFramename)
446 {
447  HlinkImpl *This = impl_from_IHlink(iface);
448  TRACE("(%p)->(%s)\n", This, debugstr_w(pwzTargetFramename));
449 
450  heap_free(This->TargetFrameName);
451  This->TargetFrameName = hlink_strdupW( pwzTargetFramename );
452 
453  return S_OK;
454 }
455 
457  LPWSTR *ppwzTargetFrameName)
458 {
459  HlinkImpl *This = impl_from_IHlink(iface);
460 
461  TRACE("(%p)->(%p)\n", This, ppwzTargetFrameName);
462 
463  if(!This->TargetFrameName) {
464  *ppwzTargetFrameName = NULL;
465  return S_FALSE;
466  }
467 
468  *ppwzTargetFrameName = hlink_co_strdupW( This->TargetFrameName );
469  if(!*ppwzTargetFrameName)
470  return E_OUTOFMEMORY;
471 
472  return S_OK;
473 }
474 
476 {
477  FIXME("\n");
478  return E_NOTIMPL;
479 }
480 
481 static HRESULT WINAPI IHlink_fnNavigate(IHlink *iface, DWORD flags, IBindCtx *user_bind_ctx,
482  IBindStatusCallback *bind_callback, IHlinkBrowseContext *browse_ctx)
483 {
484  HlinkImpl *This = impl_from_IHlink(iface);
485  IMoniker *mon = NULL;
486  HRESULT r;
487 
488  TRACE("hlink %p, flags %#x, user_bind_ctx %p, bind_callback %p, browse_ctx %p.\n",
489  This, flags, user_bind_ctx, bind_callback, browse_ctx);
490 
491  if (This->async_bind_ctx)
492  return E_UNEXPECTED;
493 
494  r = __GetMoniker(This, &mon, HLINKGETREF_ABSOLUTE);
495  TRACE("Moniker %p\n", mon);
496 
497  if (SUCCEEDED(r))
498  {
499  IBindCtx *bind_ctx = NULL;
500  IUnknown *unk = NULL;
502 
503  if (browse_ctx)
504  {
505  r = IHlinkBrowseContext_GetObject(browse_ctx, mon, TRUE, &unk);
506  if (r != S_OK)
507  {
508  CreateBindCtx(0, &bind_ctx);
509  RegisterBindStatusCallback(bind_ctx, &This->IBindStatusCallback_iface, NULL, 0);
510  This->bind_callback = bind_callback;
511  r = IMoniker_BindToObject(mon, bind_ctx, NULL, &IID_IUnknown, (void**)&unk);
512  if (r == MK_S_ASYNCHRONOUS)
513  {
514  This->async_bind_ctx = bind_ctx;
515  This->async_flags = flags;
516  if (bind_callback)
517  IBindStatusCallback_AddRef(bind_callback);
518  IHlinkBrowseContext_AddRef(This->async_browse_ctx = browse_ctx);
519  IMoniker_Release(mon);
520  return r;
521  }
522  }
523  if (r == S_OK)
524  {
525  r = IUnknown_QueryInterface(unk, &IID_IHlinkTarget, (void **)&target);
526  IUnknown_Release(unk);
527  }
528  if (r == S_OK)
529  {
530  if (bind_ctx) IHlinkTarget_SetBrowseContext(target, browse_ctx);
531  r = IHlinkTarget_Navigate(target, flags, This->Location);
532  IHlinkTarget_Release(target);
533  }
534 
535  RevokeBindStatusCallback(bind_ctx, &This->IBindStatusCallback_iface);
536  if (bind_ctx) IBindCtx_Release(bind_ctx);
537  }
538  else
539  {
540  static const WCHAR szOpen[] = {'o','p','e','n',0};
541  LPWSTR target = NULL;
542 
543  r = IHlink_GetStringReference(iface, HLINKGETREF_DEFAULT, &target, NULL);
544  if (SUCCEEDED(r) && target)
545  {
548  r = DRAGDROP_S_DROP;
549  }
550  }
551  IMoniker_Release(mon);
552  }
553 
554  if (This->Site)
555  IHlinkSite_OnNavigationComplete(This->Site, This->SiteData, 0, r, NULL);
556 
557  TRACE("Finished Navigation\n");
558  return r;
559 }
560 
562  LPCWSTR pwzAdditionalParams)
563 {
564  TRACE("Not implemented in native IHlink\n");
565  return E_NOTIMPL;
566 }
567 
569  LPWSTR* ppwzAdditionalParams)
570 {
571  TRACE("Not implemented in native IHlink\n");
572  return E_NOTIMPL;
573 }
574 
575 static const IHlinkVtbl hlvt =
576 {
594 };
595 
597  REFIID riid, LPVOID *ppvObj)
598 {
600  TRACE("%p\n", This);
601  return IHlink_QueryInterface(&This->IHlink_iface, riid, ppvObj);
602 }
603 
605 {
607  TRACE("%p\n", This);
608  return IHlink_AddRef(&This->IHlink_iface);
609 }
610 
612 {
614  TRACE("%p\n", This);
615  return IHlink_Release(&This->IHlink_iface);
616 }
617 
619  FORMATETC* pformatetcIn, STGMEDIUM* pmedium)
620 {
621  FIXME("\n");
622  return E_NOTIMPL;
623 }
624 
626  FORMATETC* pformatetc, STGMEDIUM* pmedium)
627 {
628  FIXME("\n");
629  return E_NOTIMPL;
630 }
631 
633  FORMATETC* pformatetc)
634 {
635  FIXME("\n");
636  return E_NOTIMPL;
637 }
638 
640  FORMATETC* pformatetcIn, FORMATETC* pformatetcOut)
641 {
642  FIXME("\n");
643  return E_NOTIMPL;
644 }
645 
647  FORMATETC* pformatetc, STGMEDIUM* pmedium, BOOL fRelease)
648 {
649  FIXME("\n");
650  return E_NOTIMPL;
651 }
652 
654  DWORD dwDirection, IEnumFORMATETC** ppenumFormatEtc)
655 {
656  FIXME("\n");
657  return E_NOTIMPL;
658 }
659 
661  FORMATETC* pformatetc, DWORD advf, IAdviseSink* pAdvSink,
662  DWORD* pdwConnection)
663 {
664  FIXME("\n");
665  return E_NOTIMPL;
666 }
667 
669  DWORD dwConnection)
670 {
671  FIXME("\n");
672  return E_NOTIMPL;
673 }
674 
676  IEnumSTATDATA** ppenumAdvise)
677 {
678  FIXME("\n");
679  return E_NOTIMPL;
680 }
681 
682 static const IDataObjectVtbl dovt =
683 {
696 };
697 
699  REFIID riid, LPVOID *ppvObj)
700 {
702  TRACE("(%p)\n", This);
703  return IHlink_QueryInterface(&This->IHlink_iface, riid, ppvObj);
704 }
705 
707 {
709  TRACE("(%p)\n", This);
710  return IHlink_AddRef(&This->IHlink_iface);
711 }
712 
714 {
716  TRACE("(%p)\n", This);
717  return IHlink_Release(&This->IHlink_iface);
718 }
719 
721  CLSID* pClassID)
722 {
724  TRACE("(%p)\n", This);
725  *pClassID = CLSID_StdHlink;
726  return S_OK;
727 }
728 
730 {
731  FIXME("\n");
732  return E_NOTIMPL;
733 }
734 
736 {
737  DWORD len;
738  HRESULT hr;
739 
740  TRACE("(%p, %s)\n", pStm, debugstr_w(str));
741 
742  len = strlenW(str) + 1;
743 
744  hr = IStream_Write(pStm, &len, sizeof(len), NULL);
745  if (FAILED(hr)) return hr;
746 
747  hr = IStream_Write(pStm, str, len * sizeof(WCHAR), NULL);
748  if (FAILED(hr)) return hr;
749 
750  return S_OK;
751 }
752 
754 {
755  return sizeof(DWORD) + (strlenW(str) + 1) * sizeof(WCHAR);
756 }
757 
758 static HRESULT read_hlink_string(IStream *pStm, LPWSTR *out_str)
759 {
760  LPWSTR str;
761  DWORD len;
762  ULONG read;
763  HRESULT hr;
764 
765  hr = IStream_Read(pStm, &len, sizeof(len), &read);
766  if (FAILED(hr)) return hr;
767  if (read != sizeof(len)) return STG_E_READFAULT;
768 
769  TRACE("read len %d\n", len);
770 
771  str = heap_alloc(len * sizeof(WCHAR));
772  if (!str) return E_OUTOFMEMORY;
773 
774  hr = IStream_Read(pStm, str, len * sizeof(WCHAR), &read);
775  if (FAILED(hr))
776  {
777  heap_free(str);
778  return hr;
779  }
780  if (read != len * sizeof(WCHAR))
781  {
782  heap_free(str);
783  return STG_E_READFAULT;
784  }
785  TRACE("read string %s\n", debugstr_w(str));
786 
787  *out_str = str;
788  return S_OK;
789 }
790 
792  IStream* pStm)
793 {
794  HRESULT r;
795  DWORD hdr[2];
796  DWORD read;
798 
799  r = IStream_Read(pStm, hdr, sizeof(hdr), &read);
800  if (read != sizeof(hdr) || (hdr[0] != HLINK_SAVE_MAGIC))
801  {
802  r = E_FAIL;
803  goto end;
804  }
805  if (hdr[1] & ~HLINK_SAVE_ALL)
806  FIXME("unknown flag(s) 0x%x\n", hdr[1] & ~HLINK_SAVE_ALL);
807 
809  {
810  TRACE("loading target frame name\n");
811  r = read_hlink_string(pStm, &This->TargetFrameName);
812  if (FAILED(r)) goto end;
813  }
814 
816  {
817  TRACE("loading target friendly name\n");
818  if (!(hdr[1] & 0x4))
819  FIXME("0x4 flag not present with friendly name flag - not sure what this means\n");
820  r = read_hlink_string(pStm, &This->FriendlyName);
821  if (FAILED(r)) goto end;
822  }
823 
825  {
826  TRACE("loading moniker\n");
827  r = OleLoadFromStream(pStm, &IID_IMoniker, (LPVOID*)&(This->Moniker));
828  if (FAILED(r))
829  goto end;
830  This->absolute = (hdr[1] & HLINK_SAVE_MONIKER_IS_ABSOLUTE) != 0;
831  }
832 
834  {
835  TRACE("loading location\n");
836  r = read_hlink_string(pStm, &This->Location);
837  if (FAILED(r)) goto end;
838  }
839 
840 end:
841  TRACE("Load Result 0x%x (%p)\n", r, This->Moniker);
842 
843  return r;
844 }
845 
847  IStream* pStm, BOOL fClearDirty)
848 {
849  HRESULT r;
851  DWORD hdr[2];
852  IMoniker *moniker;
853 
854  TRACE("(%p) Moniker(%p)\n", This, This->Moniker);
855 
856  r = __GetMoniker(This, &moniker, HLINKGETREF_DEFAULT);
857  if (FAILED(r))
858  return r;
859  r = E_FAIL;
860 
861  hdr[0] = HLINK_SAVE_MAGIC;
862  hdr[1] = 0;
863 
864  if (moniker)
866  if (This->absolute)
868  if (This->Location)
870  if (This->FriendlyName)
871  hdr[1] |= HLINK_SAVE_FRIENDLY_PRESENT | 4 /* FIXME */;
872  if (This->TargetFrameName)
874 
875  IStream_Write(pStm, hdr, sizeof(hdr), NULL);
876 
877  if (This->TargetFrameName)
878  {
879  r = write_hlink_string(pStm, This->TargetFrameName);
880  if (FAILED(r)) goto end;
881  }
882 
883  if (This->FriendlyName)
884  {
885  r = write_hlink_string(pStm, This->FriendlyName);
886  if (FAILED(r)) goto end;
887  }
888 
889  if (moniker)
890  {
891  IPersistStream* monstream;
892 
893  monstream = NULL;
894  IMoniker_QueryInterface(moniker, &IID_IPersistStream,
895  (LPVOID*)&monstream);
896  if (monstream)
897  {
898  r = OleSaveToStream(monstream, pStm);
899  IPersistStream_Release(monstream);
900  }
901  if (FAILED(r)) goto end;
902  }
903 
904  if (This->Location)
905  {
906  r = write_hlink_string(pStm, This->Location);
907  if (FAILED(r)) goto end;
908  }
909 
910 end:
911  if (moniker) IMoniker_Release(moniker);
912  TRACE("Save Result 0x%x\n", r);
913 
914  return r;
915 }
916 
918  ULARGE_INTEGER* pcbSize)
919 {
920  HRESULT r;
922  IMoniker *moniker;
923 
924  TRACE("(%p) Moniker(%p)\n", This, This->Moniker);
925 
926  pcbSize->QuadPart = sizeof(DWORD)*2;
927 
928  if (This->TargetFrameName)
929  pcbSize->QuadPart += size_hlink_string(This->TargetFrameName);
930 
931  if (This->FriendlyName)
932  pcbSize->QuadPart += size_hlink_string(This->FriendlyName);
933 
934  r = __GetMoniker(This, &moniker, HLINKGETREF_DEFAULT);
935  if (FAILED(r))
936  return r;
937  r = E_FAIL;
938 
939  if (moniker)
940  {
941  IPersistStream* monstream = NULL;
942  IMoniker_QueryInterface(moniker, &IID_IPersistStream,
943  (LPVOID*)&monstream);
944  if (monstream)
945  {
946  ULARGE_INTEGER mon_size;
947  r = IPersistStream_GetSizeMax(monstream, &mon_size);
948  pcbSize->QuadPart += mon_size.QuadPart;
949  IPersistStream_Release(monstream);
950  }
951  IMoniker_Release(moniker);
952  }
953 
954  if (This->Location)
955  pcbSize->QuadPart += size_hlink_string(This->Location);
956 
957  return r;
958 }
959 
960 static const IPersistStreamVtbl psvt =
961 {
970 };
971 
973 {
974  return CONTAINING_RECORD(iface, HlinkImpl, IBindStatusCallback_iface);
975 }
976 
978 {
979  if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IBindStatusCallback))
980  {
981  IBindStatusCallback_AddRef(*out = iface);
982  return S_OK;
983  }
984 
985  WARN("No interface for %s.\n", debugstr_guid(iid));
986  return E_NOINTERFACE;
987 }
988 
990 {
992  return IHlink_AddRef(&hlink->IHlink_iface);
993 }
994 
996 {
998  return IHlink_Release(&hlink->IHlink_iface);
999 }
1000 
1002  DWORD reserved, IBinding *binding)
1003 {
1004  HlinkImpl *hlink = impl_from_IBindStatusCallback(iface);
1005 
1006  TRACE("hlink %p, reserved %#x, binding %p.\n", hlink, reserved, binding);
1007 
1008  if (hlink->bind_callback)
1009  return IBindStatusCallback_OnStartBinding(hlink->bind_callback, reserved, binding);
1010  return S_OK;
1011 }
1012 
1014 {
1015  FIXME("iface %p, priority %p, stub!\n", iface, priority);
1016  return E_NOTIMPL;
1017 }
1018 
1020 {
1021  HlinkImpl *hlink = impl_from_IBindStatusCallback(iface);
1022 
1023  TRACE("hlink %p, reserved %#x.\n", hlink, reserved);
1024 
1025  if (hlink->bind_callback)
1026  return IBindStatusCallback_OnLowResource(hlink->bind_callback, reserved);
1027  return S_OK;
1028 }
1029 
1032 {
1033  HlinkImpl *hlink = impl_from_IBindStatusCallback(iface);
1034 
1035  TRACE("hlink %p, progress %u, max %u, status %u, text %s.\n",
1036  hlink, progress, max, status, debugstr_w(text));
1037 
1038  if (hlink->bind_callback)
1039  return IBindStatusCallback_OnProgress(hlink->bind_callback, progress, max, status, text);
1040  return S_OK;
1041 }
1042 
1044  HRESULT hr, const WCHAR *error)
1045 {
1046  HlinkImpl *hlink = impl_from_IBindStatusCallback(iface);
1047 
1048  TRACE("hlink %p, hr %#x, error %s.\n", hlink, hr, debugstr_w(error));
1049 
1050  if (hlink->bind_callback)
1051  IBindStatusCallback_OnStopBinding(hlink->bind_callback, hr, error);
1052 
1053  if (hlink->async_bind_ctx)
1054  {
1055  if (hlink->bind_callback)
1056  IBindStatusCallback_Release(hlink->bind_callback);
1058  IBindCtx_Release(hlink->async_bind_ctx);
1059  IHlinkBrowseContext_Release(hlink->async_browse_ctx);
1060  hlink->async_bind_ctx = NULL;
1061  }
1062  return S_OK;
1063 }
1064 
1066  DWORD *bind_flags, BINDINFO *bind_info)
1067 {
1068  HlinkImpl *hlink = impl_from_IBindStatusCallback(iface);
1069 
1070  TRACE("hlink %p, bind_flags %p, bind_info %p.\n", hlink, bind_flags, bind_info);
1071 
1072  if (hlink->bind_callback)
1073  return IBindStatusCallback_GetBindInfo(hlink->bind_callback, bind_flags, bind_info);
1074  return S_OK;
1075 }
1076 
1078  DWORD flags, DWORD size, FORMATETC *formatetc, STGMEDIUM *stgmed)
1079 {
1080  FIXME("iface %p, flags %#x, size %d, formatetc %p, stgmed %p, stub!\n",
1081  iface, flags, size, formatetc, stgmed);
1082  return E_NOTIMPL;
1083 }
1084 
1086  REFIID iid, IUnknown *unk)
1087 {
1088  HlinkImpl *hlink = impl_from_IBindStatusCallback(iface);
1090  HRESULT hr;
1091 
1092  TRACE("hlink %p, iid %s, unk %p.\n", hlink, debugstr_guid(iid), unk);
1093 
1094  if (hlink->bind_callback)
1095  IBindStatusCallback_OnObjectAvailable(hlink->bind_callback, iid, unk);
1096 
1097  if (hlink->async_bind_ctx)
1098  {
1099  hr = IUnknown_QueryInterface(unk, &IID_IHlinkTarget, (void **)&target);
1100  if (FAILED(hr))
1101  return hr;
1102 
1103  IHlinkTarget_SetBrowseContext(target, hlink->async_browse_ctx);
1104  hr = IHlinkTarget_Navigate(target, hlink->async_flags, hlink->Location);
1105  IHlinkTarget_Release(target);
1106 
1107  if (hlink->Site)
1108  IHlinkSite_OnNavigationComplete(hlink->Site, hlink->SiteData, 0, hr, NULL);
1109 
1110  return hr;
1111  }
1112 
1113  return S_OK;
1114 }
1115 
1116 static const IBindStatusCallbackVtbl bind_callback_vtbl =
1117 {
1129 };
1130 
1132 {
1133  HlinkImpl * hl;
1134 
1135  TRACE("unkOut=%p riid=%s\n", pUnkOuter, debugstr_guid(riid));
1136  *ppv = NULL;
1137 
1138  if (pUnkOuter)
1139  return CLASS_E_NOAGGREGATION;
1140 
1141  hl = heap_alloc_zero(sizeof(HlinkImpl));
1142  if (!hl)
1143  return E_OUTOFMEMORY;
1144 
1145  hl->ref = 1;
1146  hl->IHlink_iface.lpVtbl = &hlvt;
1147  hl->IPersistStream_iface.lpVtbl = &psvt;
1148  hl->IDataObject_iface.lpVtbl = &dovt;
1150 
1151  *ppv = hl;
1152  return S_OK;
1153 }
#define max(a, b)
Definition: svc.c:63
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
char hdr[14]
Definition: iptest.cpp:33
#define E_NOINTERFACE
Definition: winerror.h:2364
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:422
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
HRESULT hr
Definition: shlfolder.c:183
#define error(str)
Definition: mkdosfs.c:1605
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
REFIID riid
Definition: precomp.h:44
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
WINE_UNICODE_INLINE WCHAR * strchrW(const WCHAR *str, WCHAR ch)
Definition: unicode.h:248
const WCHAR * text
Definition: package.c:1827
#define WARN(fmt,...)
Definition: debug.h:111
LPWSTR TargetFrameName
Definition: link.c:50
REFIID LPVOID * ppv
Definition: atlbase.h:39
LPWSTR FriendlyName
Definition: link.c:48
IBindStatusCallback IBindStatusCallback_iface
Definition: link.c:56
const GUID IID_IDataObject
GLuint GLuint end
Definition: gl.h:1545
static LPOLESTR
Definition: stg_prop.c:27
#define E_FAIL
Definition: ddrawi.h:102
#define DWORD
Definition: nt_native.h:44
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
IHlinkBrowseContext * async_browse_ctx
Definition: link.c:60
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
LONG ref
Definition: link.c:43
#define debugstr_w
Definition: kernel32.h:32
#define FIXME(fmt,...)
Definition: debug.h:110
Definition: link.c:40
r reserved
Definition: btrfs.c:2893
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
IPersistStream IPersistStream_iface
Definition: link.c:45
#define SW_SHOW
Definition: winuser.h:769
#define debugstr_guid
Definition: kernel32.h:35
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
HRESULT WINAPI RegisterBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pbsc, IBindStatusCallback **ppbscPrevious, DWORD dwReserved)
Definition: bindctx.c:615
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
HRESULT hres
Definition: protocol.c:465
IBindCtx * async_bind_ctx
Definition: link.c:58
HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC *ppbc)
Definition: bindctx.c:556
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
LPWSTR Location
Definition: link.c:49
HRESULT WINAPI CreateFileMoniker(LPCOLESTR lpszPathName, IMoniker **ppmk)
Definition: filemoniker.c:1415
const GUID IID_IUnknown
#define WINAPI
Definition: msvc.h:8
static FILE * out
Definition: regtests2xml.c:44
unsigned long DWORD
Definition: ntddk_ex.h:95
HRESULT WINAPI OleSaveToStream(IPersistStream *pPStm, IStream *pStm)
Definition: storage32.c:9165
GLbitfield flags
Definition: glext.h:7161
const GUID IID_IPersistStream
Definition: proxy.cpp:13
IHlinkSite * Site
Definition: link.c:52
HRESULT WINAPI RevokeBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pbsc)
Definition: bindctx.c:676
#define InterlockedDecrement
Definition: armddk.h:52
DWORD async_flags
Definition: link.c:59
IHlink IHlink_iface
Definition: link.c:42
GLenum GLsizei len
Definition: glext.h:6722
IBindStatusCallback * bind_callback
Definition: link.c:57
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
DWORD SiteData
Definition: link.c:53
#define ERR(fmt,...)
Definition: debug.h:109
#define S_OK
Definition: intsafe.h:59
#define InterlockedIncrement
Definition: armddk.h:53
#define DRAGDROP_S_DROP
Definition: winerror.h:2646
#define E_NOTIMPL
Definition: ddrawi.h:99
#define STG_E_READFAULT
Definition: winerror.h:2576
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
Definition: main.c:41
cd_progress_ptr progress
Definition: cdjpeg.h:150
BOOL absolute
Definition: link.c:54
#define E_UNEXPECTED
Definition: winerror.h:2456
static IInternetBindInfo bind_info
Definition: mimeole.c:1273
IMoniker * Moniker
Definition: link.c:51
HRESULT WINAPI MkParseDisplayName(LPBC pbc, LPCOLESTR szDisplayName, LPDWORD pchEaten, LPMONIKER *ppmk)
Definition: moniker.c:1133
static const WCHAR szOpen[]
Definition: domdoc.c:1157
HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpVerb, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd)
Definition: shlexec.cpp:2208
unsigned int ULONG
Definition: retypes.h:1
GLenum target
Definition: glext.h:7315
HRESULT WINAPI CreateURLMoniker(IMoniker *pmkContext, LPCWSTR szURL, IMoniker **ppmk)
Definition: umon.c:732
static int priority
Definition: timer.c:163
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
HRESULT WINAPI OleLoadFromStream(IStream *pStm, REFIID iidInterface, void **ppvObj)
Definition: storage32.c:9130
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
IDataObject IDataObject_iface
Definition: link.c:46
Definition: ps.c:97