ReactOS 0.4.15-dev-8146-gdc0ed6d
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
40typedef struct
41{
44
47
55
61} HlinkImpl;
62
63static 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{
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{
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;
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{
155 ULONG refCount = InterlockedIncrement(&This->ref);
156
157 TRACE("(%p)->(count=%u)\n", This, refCount - 1);
158
159 return refCount;
160}
161
163{
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);
180 return 0;
181}
182
184 IHlinkSite* pihlSite, DWORD dwSiteData)
185{
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{
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{
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 && wcschr(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{
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 = wcschr(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{
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{
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{
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{
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 {
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{
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{
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
482 IBindStatusCallback *bind_callback, IHlinkBrowseContext *browse_ctx)
483{
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};
542
543 r = IHlink_GetStringReference(iface, HLINKGETREF_DEFAULT, &target, NULL);
544 if (SUCCEEDED(r) && target)
545 {
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
575static 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
682static 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 = lstrlenW(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) + (lstrlenW(str) + 1) * sizeof(WCHAR);
756}
757
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
840end:
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];
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
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
910end:
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;
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
960static 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{
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{
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{
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{
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{
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{
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
1116static 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 read
Definition: acwin.h:96
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
const GUID IID_IUnknown
#define FIXME(fmt,...)
Definition: debug.h:114
#define WARN(fmt,...)
Definition: debug.h:115
#define ERR(fmt,...)
Definition: debug.h:113
cd_progress_ptr progress
Definition: cdjpeg.h:152
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define wcschr
Definition: compat.h:17
#define lstrlenW
Definition: compat.h:750
const WCHAR * text
Definition: package.c:1799
HRESULT WINAPI MkParseDisplayName(LPBC pbc, LPCOLESTR szDisplayName, LPDWORD pchEaten, LPMONIKER *ppmk)
Definition: moniker.c:1129
HRESULT WINAPI OleLoadFromStream(IStream *pStm, REFIID iidInterface, void **ppvObj)
Definition: storage32.c:9129
HRESULT WINAPI OleSaveToStream(IPersistStream *pPStm, IStream *pStm)
Definition: storage32.c:9164
r reserved
Definition: btrfs.c:3006
HRESULT WINAPI CreateFileMoniker(LPCOLESTR lpszPathName, IMoniker **ppmk)
Definition: filemoniker.c:1414
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint end
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizeiptr size
Definition: glext.h:5919
GLbitfield flags
Definition: glext.h:7161
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLenum target
Definition: glext.h:7315
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
char hdr[14]
Definition: iptest.cpp:33
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
#define error(str)
Definition: mkdosfs.c:1605
static IInternetBindInfo bind_info
Definition: mimeole.c:1273
HRESULT hres
Definition: protocol.c:465
static const WCHAR szOpen[]
Definition: domdoc.c:1157
static LPOLESTR
Definition: stg_prop.c:27
static int priority
Definition: timer.c:163
#define DWORD
Definition: nt_native.h:44
HRESULT WINAPI CreateBindCtx(DWORD reserved, LPBC *ppbc)
Definition: bindctx.c:556
const GUID IID_IDataObject
long LONG
Definition: pedump.c:60
const GUID IID_IPersistStream
Definition: proxy.cpp:13
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
static FILE * out
Definition: regtests2xml.c:44
const WCHAR * str
HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpVerb, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd)
Definition: shlexec.cpp:2486
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
Definition: link.c:41
IMoniker * Moniker
Definition: link.c:51
IDataObject IDataObject_iface
Definition: link.c:46
BOOL absolute
Definition: link.c:54
IBindStatusCallback IBindStatusCallback_iface
Definition: link.c:56
DWORD SiteData
Definition: link.c:53
DWORD async_flags
Definition: link.c:59
IHlink IHlink_iface
Definition: link.c:42
IHlinkSite * Site
Definition: link.c:52
IPersistStream IPersistStream_iface
Definition: link.c:45
LONG ref
Definition: link.c:43
LPWSTR TargetFrameName
Definition: link.c:50
IBindStatusCallback * bind_callback
Definition: link.c:57
IHlinkBrowseContext * async_browse_ctx
Definition: link.c:60
LPWSTR Location
Definition: link.c:49
LPWSTR FriendlyName
Definition: link.c:48
IBindCtx * async_bind_ctx
Definition: link.c:58
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
Definition: main.c:40
Definition: ps.c:97
#define max(a, b)
Definition: svc.c:63
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
HRESULT WINAPI CreateURLMoniker(IMoniker *pmkContext, LPCWSTR szURL, IMoniker **ppmk)
Definition: umon.c:732
HRESULT WINAPI RevokeBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pbsc)
Definition: bindctx.c:676
HRESULT WINAPI RegisterBindStatusCallback(IBindCtx *pbc, IBindStatusCallback *pbsc, IBindStatusCallback **ppbscPrevious, DWORD dwReserved)
Definition: bindctx.c:615
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define DRAGDROP_S_DROP
Definition: winerror.h:2646
#define E_NOINTERFACE
Definition: winerror.h:2364
#define STG_E_READFAULT
Definition: winerror.h:2576
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
#define E_UNEXPECTED
Definition: winerror.h:2456
#define SW_SHOW
Definition: winuser.h:775
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185