ReactOS 0.4.17-dev-804-g023d8af
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=%lu)\n", This, refCount - 1);
158
159 return refCount;
160}
161
163{
165 ULONG refCount = InterlockedDecrement(&This->ref);
166
167 TRACE("(%p)->(count=%lu)\n", This, refCount + 1);
168 if (refCount)
169 return refCount;
170
171 TRACE("-- destroying IHlink (%p)\n", This);
172 free(This->FriendlyName);
173 free(This->TargetFrameName);
174 free(This->Location);
175 if (This->Moniker)
176 IMoniker_Release(This->Moniker);
177 if (This->Site)
178 IHlinkSite_Release(This->Site);
179 free(This);
180 return 0;
181}
182
184 IHlinkSite* pihlSite, DWORD dwSiteData)
185{
187
188 TRACE("(%p)->(%p %li)\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)->(%li %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 free(This->Location);
252 This->Location = wcsdup( pwzLocation );
253 }
254
255 return S_OK;
256}
257
259 DWORD grfHLSETF, LPCWSTR pwzTarget, LPCWSTR pwzLocation)
260{
262
263 TRACE("(%p)->(%li %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%08lx\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 free(This->Location);
314 This->Location = NULL;
315 if (pwzLocation && *pwzLocation)
316 This->Location = wcsdup( pwzLocation );
317 }
318
319 return S_OK;
320}
321
323 DWORD dwWhichRef, IMoniker **ppimkTarget, LPWSTR *ppwzLocation)
324{
326
327 TRACE("(%p) -> (%li %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) -> (%li %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 free(This->FriendlyName);
403 This->FriendlyName = wcsdup( pwzFriendlyName );
404
405 return S_OK;
406}
407
409 DWORD grfHLFNAMEF, LPWSTR* ppwzFriendlyName)
410{
412
413 TRACE("(%p) -> (%li %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 free(This->TargetFrameName);
451 This->TargetFrameName = wcsdup( 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 %#lx, 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 {
541
542 r = IHlink_GetStringReference(iface, HLINKGETREF_DEFAULT, &target, NULL);
543 if (SUCCEEDED(r) && target)
544 {
548 }
549 }
550 IMoniker_Release(mon);
551 }
552
553 if (This->Site)
554 IHlinkSite_OnNavigationComplete(This->Site, This->SiteData, 0, r, NULL);
555
556 TRACE("Finished Navigation\n");
557 return r;
558}
559
561 LPCWSTR pwzAdditionalParams)
562{
563 TRACE("Not implemented in native IHlink\n");
564 return E_NOTIMPL;
565}
566
568 LPWSTR* ppwzAdditionalParams)
569{
570 TRACE("Not implemented in native IHlink\n");
571 return E_NOTIMPL;
572}
573
574static const IHlinkVtbl hlvt =
575{
593};
594
596 REFIID riid, LPVOID *ppvObj)
597{
599 TRACE("%p\n", This);
600 return IHlink_QueryInterface(&This->IHlink_iface, riid, ppvObj);
601}
602
604{
606 TRACE("%p\n", This);
607 return IHlink_AddRef(&This->IHlink_iface);
608}
609
611{
613 TRACE("%p\n", This);
614 return IHlink_Release(&This->IHlink_iface);
615}
616
618 FORMATETC* pformatetcIn, STGMEDIUM* pmedium)
619{
620 FIXME("\n");
621 return E_NOTIMPL;
622}
623
625 FORMATETC* pformatetc, STGMEDIUM* pmedium)
626{
627 FIXME("\n");
628 return E_NOTIMPL;
629}
630
632 FORMATETC* pformatetc)
633{
634 FIXME("\n");
635 return E_NOTIMPL;
636}
637
639 FORMATETC* pformatetcIn, FORMATETC* pformatetcOut)
640{
641 FIXME("\n");
642 return E_NOTIMPL;
643}
644
646 FORMATETC* pformatetc, STGMEDIUM* pmedium, BOOL fRelease)
647{
648 FIXME("\n");
649 return E_NOTIMPL;
650}
651
653 DWORD dwDirection, IEnumFORMATETC** ppenumFormatEtc)
654{
655 FIXME("\n");
656 return E_NOTIMPL;
657}
658
660 FORMATETC* pformatetc, DWORD advf, IAdviseSink* pAdvSink,
661 DWORD* pdwConnection)
662{
663 FIXME("\n");
664 return E_NOTIMPL;
665}
666
668 DWORD dwConnection)
669{
670 FIXME("\n");
671 return E_NOTIMPL;
672}
673
675 IEnumSTATDATA** ppenumAdvise)
676{
677 FIXME("\n");
678 return E_NOTIMPL;
679}
680
681static const IDataObjectVtbl dovt =
682{
695};
696
698 REFIID riid, LPVOID *ppvObj)
699{
701 TRACE("(%p)\n", This);
702 return IHlink_QueryInterface(&This->IHlink_iface, riid, ppvObj);
703}
704
706{
708 TRACE("(%p)\n", This);
709 return IHlink_AddRef(&This->IHlink_iface);
710}
711
713{
715 TRACE("(%p)\n", This);
716 return IHlink_Release(&This->IHlink_iface);
717}
718
720 CLSID* pClassID)
721{
723 TRACE("(%p)\n", This);
724 *pClassID = CLSID_StdHlink;
725 return S_OK;
726}
727
729{
730 FIXME("\n");
731 return E_NOTIMPL;
732}
733
735{
736 DWORD len;
737 HRESULT hr;
738
739 TRACE("(%p, %s)\n", pStm, debugstr_w(str));
740
741 len = lstrlenW(str) + 1;
742
743 hr = IStream_Write(pStm, &len, sizeof(len), NULL);
744 if (FAILED(hr)) return hr;
745
746 hr = IStream_Write(pStm, str, len * sizeof(WCHAR), NULL);
747 if (FAILED(hr)) return hr;
748
749 return S_OK;
750}
751
753{
754 return sizeof(DWORD) + (lstrlenW(str) + 1) * sizeof(WCHAR);
755}
756
758{
759 LPWSTR str;
760 DWORD len;
761 ULONG read;
762 HRESULT hr;
763
764 hr = IStream_Read(pStm, &len, sizeof(len), &read);
765 if (FAILED(hr)) return hr;
766 if (read != sizeof(len)) return STG_E_READFAULT;
767
768 TRACE("read len %ld\n", len);
769
770 str = malloc(len * sizeof(WCHAR));
771 if (!str) return E_OUTOFMEMORY;
772
773 hr = IStream_Read(pStm, str, len * sizeof(WCHAR), &read);
774 if (FAILED(hr))
775 {
776 free(str);
777 return hr;
778 }
779 if (read != len * sizeof(WCHAR))
780 {
781 free(str);
782 return STG_E_READFAULT;
783 }
784 TRACE("read string %s\n", debugstr_w(str));
785
786 *out_str = str;
787 return S_OK;
788}
789
791 IStream* pStm)
792{
793 HRESULT r;
794 DWORD hdr[2];
795 DWORD read;
797
798 r = IStream_Read(pStm, hdr, sizeof(hdr), &read);
799 if (read != sizeof(hdr) || (hdr[0] != HLINK_SAVE_MAGIC))
800 {
801 r = E_FAIL;
802 goto end;
803 }
804 if (hdr[1] & ~HLINK_SAVE_ALL)
805 FIXME("unknown flag(s) 0x%lx\n", hdr[1] & ~HLINK_SAVE_ALL);
806
808 {
809 TRACE("loading target frame name\n");
810 r = read_hlink_string(pStm, &This->TargetFrameName);
811 if (FAILED(r)) goto end;
812 }
813
815 {
816 TRACE("loading target friendly name\n");
817 if (!(hdr[1] & 0x4))
818 FIXME("0x4 flag not present with friendly name flag - not sure what this means\n");
819 r = read_hlink_string(pStm, &This->FriendlyName);
820 if (FAILED(r)) goto end;
821 }
822
824 {
825 TRACE("loading moniker\n");
826 r = OleLoadFromStream(pStm, &IID_IMoniker, (LPVOID*)&(This->Moniker));
827 if (FAILED(r))
828 goto end;
829 This->absolute = (hdr[1] & HLINK_SAVE_MONIKER_IS_ABSOLUTE) != 0;
830 }
831
833 {
834 TRACE("loading location\n");
835 r = read_hlink_string(pStm, &This->Location);
836 if (FAILED(r)) goto end;
837 }
838
839end:
840 TRACE("Load Result 0x%lx (%p)\n", r, This->Moniker);
841
842 return r;
843}
844
846 IStream* pStm, BOOL fClearDirty)
847{
848 HRESULT r;
850 DWORD hdr[2];
852
853 TRACE("(%p) Moniker(%p)\n", This, This->Moniker);
854
855 r = __GetMoniker(This, &moniker, HLINKGETREF_DEFAULT);
856 if (FAILED(r))
857 return r;
858 r = E_FAIL;
859
861 hdr[1] = 0;
862
863 if (moniker)
865 if (This->absolute)
867 if (This->Location)
869 if (This->FriendlyName)
870 hdr[1] |= HLINK_SAVE_FRIENDLY_PRESENT | 4 /* FIXME */;
871 if (This->TargetFrameName)
873
874 IStream_Write(pStm, hdr, sizeof(hdr), NULL);
875
876 if (This->TargetFrameName)
877 {
878 r = write_hlink_string(pStm, This->TargetFrameName);
879 if (FAILED(r)) goto end;
880 }
881
882 if (This->FriendlyName)
883 {
884 r = write_hlink_string(pStm, This->FriendlyName);
885 if (FAILED(r)) goto end;
886 }
887
888 if (moniker)
889 {
890 IPersistStream* monstream;
891
892 monstream = NULL;
893 IMoniker_QueryInterface(moniker, &IID_IPersistStream,
894 (LPVOID*)&monstream);
895 if (monstream)
896 {
897 r = OleSaveToStream(monstream, pStm);
898 IPersistStream_Release(monstream);
899 }
900 if (FAILED(r)) goto end;
901 }
902
903 if (This->Location)
904 {
905 r = write_hlink_string(pStm, This->Location);
906 if (FAILED(r)) goto end;
907 }
908
909end:
910 if (moniker) IMoniker_Release(moniker);
911 TRACE("Save Result 0x%lx\n", r);
912
913 return r;
914}
915
917 ULARGE_INTEGER* pcbSize)
918{
919 HRESULT r;
922
923 TRACE("(%p) Moniker(%p)\n", This, This->Moniker);
924
925 pcbSize->QuadPart = sizeof(DWORD)*2;
926
927 if (This->TargetFrameName)
928 pcbSize->QuadPart += size_hlink_string(This->TargetFrameName);
929
930 if (This->FriendlyName)
931 pcbSize->QuadPart += size_hlink_string(This->FriendlyName);
932
933 r = __GetMoniker(This, &moniker, HLINKGETREF_DEFAULT);
934 if (FAILED(r))
935 return r;
936 r = E_FAIL;
937
938 if (moniker)
939 {
940 IPersistStream* monstream = NULL;
941 IMoniker_QueryInterface(moniker, &IID_IPersistStream,
942 (LPVOID*)&monstream);
943 if (monstream)
944 {
945 ULARGE_INTEGER mon_size;
946 r = IPersistStream_GetSizeMax(monstream, &mon_size);
947 pcbSize->QuadPart += mon_size.QuadPart;
948 IPersistStream_Release(monstream);
949 }
950 IMoniker_Release(moniker);
951 }
952
953 if (This->Location)
954 pcbSize->QuadPart += size_hlink_string(This->Location);
955
956 return r;
957}
958
959static const IPersistStreamVtbl psvt =
960{
969};
970
972{
973 return CONTAINING_RECORD(iface, HlinkImpl, IBindStatusCallback_iface);
974}
975
977{
978 if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IBindStatusCallback))
979 {
980 IBindStatusCallback_AddRef(*out = iface);
981 return S_OK;
982 }
983
984 WARN("No interface for %s.\n", debugstr_guid(iid));
985 return E_NOINTERFACE;
986}
987
989{
991 return IHlink_AddRef(&hlink->IHlink_iface);
992}
993
995{
997 return IHlink_Release(&hlink->IHlink_iface);
998}
999
1002{
1004
1005 TRACE("hlink %p, reserved %#lx, binding %p.\n", hlink, reserved, binding);
1006
1007 if (hlink->bind_callback)
1008 return IBindStatusCallback_OnStartBinding(hlink->bind_callback, reserved, binding);
1009 return S_OK;
1010}
1011
1013{
1014 FIXME("iface %p, priority %p, stub!\n", iface, priority);
1015 return E_NOTIMPL;
1016}
1017
1019{
1021
1022 TRACE("hlink %p, reserved %#lx.\n", hlink, reserved);
1023
1024 if (hlink->bind_callback)
1025 return IBindStatusCallback_OnLowResource(hlink->bind_callback, reserved);
1026 return S_OK;
1027}
1028
1031{
1033
1034 TRACE("hlink %p, progress %lu, max %lu, status %lu, text %s.\n",
1035 hlink, progress, max, status, debugstr_w(text));
1036
1037 if (hlink->bind_callback)
1038 return IBindStatusCallback_OnProgress(hlink->bind_callback, progress, max, status, text);
1039 return S_OK;
1040}
1041
1043 HRESULT hr, const WCHAR *error)
1044{
1046
1047 TRACE("hlink %p, hr %#lx, error %s.\n", hlink, hr, debugstr_w(error));
1048
1049 if (hlink->bind_callback)
1050 IBindStatusCallback_OnStopBinding(hlink->bind_callback, hr, error);
1051
1052 if (hlink->async_bind_ctx)
1053 {
1054 if (hlink->bind_callback)
1055 IBindStatusCallback_Release(hlink->bind_callback);
1057 IBindCtx_Release(hlink->async_bind_ctx);
1058 IHlinkBrowseContext_Release(hlink->async_browse_ctx);
1059 hlink->async_bind_ctx = NULL;
1060 }
1061 return S_OK;
1062}
1063
1065 DWORD *bind_flags, BINDINFO *bind_info)
1066{
1068
1069 TRACE("hlink %p, bind_flags %p, bind_info %p.\n", hlink, bind_flags, bind_info);
1070
1071 if (hlink->bind_callback)
1072 return IBindStatusCallback_GetBindInfo(hlink->bind_callback, bind_flags, bind_info);
1073 return S_OK;
1074}
1075
1077 DWORD flags, DWORD size, FORMATETC *formatetc, STGMEDIUM *stgmed)
1078{
1079 FIXME("iface %p, flags %#lx, size %ld, formatetc %p, stgmed %p, stub!\n",
1080 iface, flags, size, formatetc, stgmed);
1081 return E_NOTIMPL;
1082}
1083
1085 REFIID iid, IUnknown *unk)
1086{
1089 HRESULT hr;
1090
1091 TRACE("hlink %p, iid %s, unk %p.\n", hlink, debugstr_guid(iid), unk);
1092
1093 if (hlink->bind_callback)
1094 IBindStatusCallback_OnObjectAvailable(hlink->bind_callback, iid, unk);
1095
1096 if (hlink->async_bind_ctx)
1097 {
1098 hr = IUnknown_QueryInterface(unk, &IID_IHlinkTarget, (void **)&target);
1099 if (FAILED(hr))
1100 return hr;
1101
1102 IHlinkTarget_SetBrowseContext(target, hlink->async_browse_ctx);
1103 hr = IHlinkTarget_Navigate(target, hlink->async_flags, hlink->Location);
1104 IHlinkTarget_Release(target);
1105
1106 if (hlink->Site)
1107 IHlinkSite_OnNavigationComplete(hlink->Site, hlink->SiteData, 0, hr, NULL);
1108
1109 return hr;
1110 }
1111
1112 return S_OK;
1113}
1114
1115static const IBindStatusCallbackVtbl bind_callback_vtbl =
1116{
1128};
1129
1131{
1132 HlinkImpl * hl;
1133 HRESULT hr;
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 if (!(hl = calloc(1, sizeof(*hl))))
1142 return E_OUTOFMEMORY;
1143
1144 hl->ref = 1;
1145 hl->IHlink_iface.lpVtbl = &hlvt;
1146 hl->IPersistStream_iface.lpVtbl = &psvt;
1147 hl->IDataObject_iface.lpVtbl = &dovt;
1149
1150 hr = IHlink_QueryInterface(&hl->IHlink_iface, riid, ppv);
1151 IHlink_Release(&hl->IHlink_iface);
1152
1153 return hr;
1154}
#define read
Definition: acwin.h:97
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
const GUID IID_IUnknown
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 free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
void WINAPI CoTaskMemFree(void *ptr)
Definition: malloc.c:389
#define wcschr
Definition: compat.h:17
#define lstrlenW
Definition: compat.h:750
const WCHAR * text
Definition: package.c:1794
static wchar_t * wcsdup(const wchar_t *str)
Definition: string.h:94
HRESULT WINAPI MkParseDisplayName(LPBC pbc, LPCOLESTR szDisplayName, LPDWORD pchEaten, LPMONIKER *ppmk)
Definition: moniker.c:838
HRESULT WINAPI OleLoadFromStream(IStream *pStm, REFIID iidInterface, void **ppvObj)
Definition: storage32.c:9001
HRESULT WINAPI OleSaveToStream(IPersistStream *pPStm, IStream *pStm)
Definition: storage32.c:9036
#define L(x)
Definition: resources.c:13
r reserved
Definition: btrfs.c:3006
HRESULT WINAPI CreateFileMoniker(LPCOLESTR lpszPathName, IMoniker **ppmk)
Definition: filemoniker.c:1360
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
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:1246
HRESULT hres
Definition: protocol.c:465
static RPC_BINDING_HANDLE binding
Definition: server.c:166
static int priority
Definition: timer.c:163
#define DWORD
Definition: nt_native.h:44
HRESULT WINAPI CreateBindCtx(DWORD reserved, IBindCtx **bind_context)
Definition: bindctx.c:491
const GUID IID_IDataObject
short WCHAR
Definition: pedump.c:58
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
#define calloc
Definition: rosglue.h:14
const WCHAR * str
HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpVerb, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd)
Definition: shlexec.cpp:2787
#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
Definition: tools.h:99
#define max(a, b)
Definition: svc.c:63
const uint16_t * LPCWSTR
Definition: typedefs.h:57
uint16_t * LPWSTR
Definition: typedefs.h:56
#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:747
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
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
#define DRAGDROP_S_DROP
Definition: winerror.h:3758
#define E_NOINTERFACE
Definition: winerror.h:3479
#define STG_E_READFAULT
Definition: winerror.h:3671
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:3771
#define E_UNEXPECTED
Definition: winerror.h:3528
#define SW_SHOW
Definition: winuser.h:786