Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenlink.c
Go to the documentation of this file.
00001 /* 00002 * Implementation of hyperlinking (hlink.dll) 00003 * 00004 * Copyright 2005 Aric Stewart for CodeWeavers 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #include "hlink_private.h" 00022 00023 #include "shellapi.h" 00024 #include "hlguids.h" 00025 00026 #include "wine/debug.h" 00027 00028 WINE_DEFAULT_DEBUG_CHANNEL(hlink); 00029 00030 #define HLINK_SAVE_MAGIC 0x00000002 00031 #define HLINK_SAVE_MONIKER_PRESENT 0x01 00032 #define HLINK_SAVE_MONIKER_IS_ABSOLUTE 0x02 00033 #define HLINK_SAVE_LOCATION_PRESENT 0x08 00034 #define HLINK_SAVE_FRIENDLY_PRESENT 0x10 00035 /* 0x20, 0x40 unknown */ 00036 #define HLINK_SAVE_TARGET_FRAME_PRESENT 0x80 00037 /* known flags */ 00038 #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) 00039 00040 typedef struct 00041 { 00042 IHlink IHlink_iface; 00043 LONG ref; 00044 00045 IPersistStream IPersistStream_iface; 00046 IDataObject IDataObject_iface; 00047 00048 LPWSTR FriendlyName; 00049 LPWSTR Location; 00050 LPWSTR TargetFrameName; 00051 IMoniker *Moniker; 00052 IHlinkSite *Site; 00053 DWORD SiteData; 00054 BOOL absolute; 00055 } HlinkImpl; 00056 00057 static inline HlinkImpl *impl_from_IHlink(IHlink *iface) 00058 { 00059 return CONTAINING_RECORD(iface, HlinkImpl, IHlink_iface); 00060 } 00061 00062 00063 static inline HlinkImpl* impl_from_IPersistStream( IPersistStream* iface) 00064 { 00065 return CONTAINING_RECORD(iface, HlinkImpl, IPersistStream_iface); 00066 } 00067 00068 static inline HlinkImpl* impl_from_IDataObject( IDataObject* iface) 00069 { 00070 return CONTAINING_RECORD(iface, HlinkImpl, IDataObject_iface); 00071 } 00072 00073 static HRESULT __GetMoniker(HlinkImpl* This, IMoniker** moniker, 00074 DWORD ref_type) 00075 { 00076 HRESULT hres; 00077 00078 if (ref_type == HLINKGETREF_DEFAULT) 00079 ref_type = HLINKGETREF_RELATIVE; 00080 00081 if (This->Moniker) 00082 { 00083 DWORD mktype = MKSYS_NONE; 00084 00085 hres = IMoniker_IsSystemMoniker(This->Moniker, &mktype); 00086 if (hres == S_OK && mktype != MKSYS_NONE) 00087 { 00088 *moniker = This->Moniker; 00089 IMoniker_AddRef(*moniker); 00090 return S_OK; 00091 } 00092 } 00093 00094 if (ref_type == HLINKGETREF_ABSOLUTE && This->Site) 00095 { 00096 IMoniker *hls_moniker; 00097 00098 hres = IHlinkSite_GetMoniker(This->Site, This->SiteData, 00099 OLEGETMONIKER_FORCEASSIGN, OLEWHICHMK_CONTAINER, &hls_moniker); 00100 if (FAILED(hres)) 00101 return hres; 00102 00103 if (This->Moniker) 00104 { 00105 hres = IMoniker_ComposeWith(hls_moniker, This->Moniker, FALSE, 00106 moniker); 00107 IMoniker_Release(hls_moniker); 00108 return hres; 00109 } 00110 00111 *moniker = hls_moniker; 00112 return S_OK; 00113 } 00114 00115 *moniker = This->Moniker; 00116 if (*moniker) 00117 IMoniker_AddRef(*moniker); 00118 00119 return S_OK; 00120 } 00121 00122 static HRESULT WINAPI IHlink_fnQueryInterface(IHlink* iface, REFIID riid, 00123 LPVOID *ppvObj) 00124 { 00125 HlinkImpl *This = impl_from_IHlink(iface); 00126 00127 TRACE ("(%p)->(%s,%p)\n", This, debugstr_guid (riid), ppvObj); 00128 00129 *ppvObj = NULL; 00130 00131 if (IsEqualIID(riid, &IID_IUnknown) || (IsEqualIID(riid, &IID_IHlink))) 00132 *ppvObj = This; 00133 else if (IsEqualIID(riid, &IID_IPersistStream)) 00134 *ppvObj = &This->IPersistStream_iface; 00135 else if (IsEqualIID(riid, &IID_IDataObject)) 00136 *ppvObj = &This->IDataObject_iface; 00137 00138 if (*ppvObj) 00139 { 00140 IUnknown_AddRef((IUnknown*)(*ppvObj)); 00141 return S_OK; 00142 } 00143 return E_NOINTERFACE; 00144 } 00145 00146 static ULONG WINAPI IHlink_fnAddRef (IHlink* iface) 00147 { 00148 HlinkImpl *This = impl_from_IHlink(iface); 00149 ULONG refCount = InterlockedIncrement(&This->ref); 00150 00151 TRACE("(%p)->(count=%u)\n", This, refCount - 1); 00152 00153 return refCount; 00154 } 00155 00156 static ULONG WINAPI IHlink_fnRelease (IHlink* iface) 00157 { 00158 HlinkImpl *This = impl_from_IHlink(iface); 00159 ULONG refCount = InterlockedDecrement(&This->ref); 00160 00161 TRACE("(%p)->(count=%u)\n", This, refCount + 1); 00162 if (refCount) 00163 return refCount; 00164 00165 TRACE("-- destroying IHlink (%p)\n", This); 00166 heap_free(This->FriendlyName); 00167 heap_free(This->TargetFrameName); 00168 heap_free(This->Location); 00169 if (This->Moniker) 00170 IMoniker_Release(This->Moniker); 00171 if (This->Site) 00172 IHlinkSite_Release(This->Site); 00173 heap_free(This); 00174 return 0; 00175 } 00176 00177 static HRESULT WINAPI IHlink_fnSetHlinkSite( IHlink* iface, 00178 IHlinkSite* pihlSite, DWORD dwSiteData) 00179 { 00180 HlinkImpl *This = impl_from_IHlink(iface); 00181 00182 TRACE("(%p)->(%p %i)\n", This, pihlSite, dwSiteData); 00183 00184 if (This->Site) 00185 IHlinkSite_Release(This->Site); 00186 00187 This->Site = pihlSite; 00188 if (This->Site) 00189 IHlinkSite_AddRef(This->Site); 00190 00191 This->SiteData = dwSiteData; 00192 00193 return S_OK; 00194 } 00195 00196 static HRESULT WINAPI IHlink_fnGetHlinkSite( IHlink* iface, 00197 IHlinkSite** ppihlSite, DWORD *pdwSiteData) 00198 { 00199 HlinkImpl *This = impl_from_IHlink(iface); 00200 00201 TRACE("(%p)->(%p %p)\n", This, ppihlSite, pdwSiteData); 00202 00203 *ppihlSite = This->Site; 00204 00205 if (This->Site) { 00206 IHlinkSite_AddRef(This->Site); 00207 *pdwSiteData = This->SiteData; 00208 } 00209 00210 return S_OK; 00211 } 00212 00213 static HRESULT WINAPI IHlink_fnSetMonikerReference( IHlink* iface, 00214 DWORD rfHLSETF, IMoniker *pmkTarget, LPCWSTR pwzLocation) 00215 { 00216 HlinkImpl *This = impl_from_IHlink(iface); 00217 00218 TRACE("(%p)->(%i %p %s)\n", This, rfHLSETF, pmkTarget, 00219 debugstr_w(pwzLocation)); 00220 00221 if(rfHLSETF == 0) 00222 return E_INVALIDARG; 00223 if(!(rfHLSETF & (HLINKSETF_TARGET | HLINKSETF_LOCATION))) 00224 return rfHLSETF; 00225 00226 if(rfHLSETF & HLINKSETF_TARGET){ 00227 if (This->Moniker) 00228 IMoniker_Release(This->Moniker); 00229 00230 This->Moniker = pmkTarget; 00231 if (This->Moniker) 00232 { 00233 IBindCtx *pbc; 00234 LPOLESTR display_name; 00235 IMoniker_AddRef(This->Moniker); 00236 CreateBindCtx( 0, &pbc); 00237 IMoniker_GetDisplayName(This->Moniker, pbc, NULL, &display_name); 00238 IBindCtx_Release(pbc); 00239 This->absolute = display_name && strchrW(display_name, ':'); 00240 CoTaskMemFree(display_name); 00241 } 00242 } 00243 00244 if(rfHLSETF & HLINKSETF_LOCATION){ 00245 heap_free(This->Location); 00246 This->Location = hlink_strdupW( pwzLocation ); 00247 } 00248 00249 return S_OK; 00250 } 00251 00252 static HRESULT WINAPI IHlink_fnSetStringReference(IHlink* iface, 00253 DWORD grfHLSETF, LPCWSTR pwzTarget, LPCWSTR pwzLocation) 00254 { 00255 HlinkImpl *This = impl_from_IHlink(iface); 00256 00257 TRACE("(%p)->(%i %s %s)\n", This, grfHLSETF, debugstr_w(pwzTarget), 00258 debugstr_w(pwzLocation)); 00259 00260 if(grfHLSETF > (HLINKSETF_TARGET | HLINKSETF_LOCATION) && 00261 grfHLSETF < -(HLINKSETF_TARGET | HLINKSETF_LOCATION)) 00262 return grfHLSETF; 00263 00264 if (grfHLSETF & HLINKSETF_TARGET) 00265 { 00266 if (This->Moniker) 00267 { 00268 IMoniker_Release(This->Moniker); 00269 This->Moniker = NULL; 00270 } 00271 if (pwzTarget && *pwzTarget) 00272 { 00273 IMoniker *pMon; 00274 IBindCtx *pbc = NULL; 00275 ULONG eaten; 00276 HRESULT r; 00277 00278 r = CreateBindCtx(0, &pbc); 00279 if (FAILED(r)) 00280 return E_OUTOFMEMORY; 00281 00282 r = MkParseDisplayName(pbc, pwzTarget, &eaten, &pMon); 00283 IBindCtx_Release(pbc); 00284 00285 if (FAILED(r)) 00286 { 00287 LPCWSTR p = strchrW(pwzTarget, ':'); 00288 if (p && (p - pwzTarget > 1)) 00289 r = CreateURLMoniker(NULL, pwzTarget, &pMon); 00290 else 00291 r = CreateFileMoniker(pwzTarget, &pMon); 00292 if (FAILED(r)) 00293 { 00294 ERR("couldn't create moniker for %s, failed with error 0x%08x\n", 00295 debugstr_w(pwzTarget), r); 00296 return r; 00297 } 00298 } 00299 00300 IHlink_SetMonikerReference(iface, HLINKSETF_TARGET, pMon, NULL); 00301 IMoniker_Release(pMon); 00302 } 00303 } 00304 00305 if (grfHLSETF & HLINKSETF_LOCATION) 00306 { 00307 heap_free(This->Location); 00308 This->Location = NULL; 00309 if (pwzLocation && *pwzLocation) 00310 This->Location = hlink_strdupW( pwzLocation ); 00311 } 00312 00313 return S_OK; 00314 } 00315 00316 static HRESULT WINAPI IHlink_fnGetMonikerReference(IHlink* iface, 00317 DWORD dwWhichRef, IMoniker **ppimkTarget, LPWSTR *ppwzLocation) 00318 { 00319 HlinkImpl *This = impl_from_IHlink(iface); 00320 00321 TRACE("(%p) -> (%i %p %p)\n", This, dwWhichRef, ppimkTarget, 00322 ppwzLocation); 00323 00324 if (ppimkTarget) 00325 { 00326 HRESULT hres = __GetMoniker(This, ppimkTarget, dwWhichRef); 00327 if (FAILED(hres)) 00328 { 00329 if (ppwzLocation) 00330 *ppwzLocation = NULL; 00331 return hres; 00332 } 00333 } 00334 00335 if (ppwzLocation) 00336 IHlink_GetStringReference(iface, dwWhichRef, NULL, ppwzLocation); 00337 00338 return S_OK; 00339 } 00340 00341 static HRESULT WINAPI IHlink_fnGetStringReference (IHlink* iface, 00342 DWORD dwWhichRef, LPWSTR *ppwzTarget, LPWSTR *ppwzLocation) 00343 { 00344 HlinkImpl *This = impl_from_IHlink(iface); 00345 00346 TRACE("(%p) -> (%i %p %p)\n", This, dwWhichRef, ppwzTarget, ppwzLocation); 00347 00348 if(dwWhichRef != -1 && dwWhichRef & ~(HLINKGETREF_DEFAULT | HLINKGETREF_ABSOLUTE | HLINKGETREF_RELATIVE)) 00349 { 00350 if(ppwzTarget) 00351 *ppwzTarget = NULL; 00352 if(ppwzLocation) 00353 *ppwzLocation = NULL; 00354 return E_INVALIDARG; 00355 } 00356 00357 if (ppwzTarget) 00358 { 00359 IMoniker* mon; 00360 HRESULT hres = __GetMoniker(This, &mon, dwWhichRef); 00361 if (FAILED(hres)) 00362 { 00363 if (ppwzLocation) 00364 *ppwzLocation = NULL; 00365 return hres; 00366 } 00367 if (mon) 00368 { 00369 IBindCtx *pbc; 00370 00371 CreateBindCtx( 0, &pbc); 00372 IMoniker_GetDisplayName(mon, pbc, NULL, ppwzTarget); 00373 IBindCtx_Release(pbc); 00374 IMoniker_Release(mon); 00375 } 00376 else 00377 *ppwzTarget = NULL; 00378 } 00379 if (ppwzLocation) 00380 *ppwzLocation = hlink_co_strdupW( This->Location ); 00381 00382 TRACE("(Target: %s Location: %s)\n", 00383 (ppwzTarget)?debugstr_w(*ppwzTarget):"<NULL>", 00384 (ppwzLocation)?debugstr_w(*ppwzLocation):"<NULL>"); 00385 00386 return S_OK; 00387 } 00388 00389 static HRESULT WINAPI IHlink_fnSetFriendlyName (IHlink *iface, 00390 LPCWSTR pwzFriendlyName) 00391 { 00392 HlinkImpl *This = impl_from_IHlink(iface); 00393 00394 TRACE("(%p) -> (%s)\n", This, debugstr_w(pwzFriendlyName)); 00395 00396 heap_free(This->FriendlyName); 00397 This->FriendlyName = hlink_strdupW( pwzFriendlyName ); 00398 00399 return S_OK; 00400 } 00401 00402 static HRESULT WINAPI IHlink_fnGetFriendlyName (IHlink* iface, 00403 DWORD grfHLFNAMEF, LPWSTR* ppwzFriendlyName) 00404 { 00405 HlinkImpl *This = impl_from_IHlink(iface); 00406 00407 TRACE("(%p) -> (%i %p)\n", This, grfHLFNAMEF, ppwzFriendlyName); 00408 00409 /* FIXME: Only using explicitly set and cached friendly names */ 00410 00411 if (This->FriendlyName) 00412 *ppwzFriendlyName = hlink_co_strdupW( This->FriendlyName ); 00413 else 00414 { 00415 IMoniker *moniker; 00416 HRESULT hres = __GetMoniker(This, &moniker, HLINKGETREF_DEFAULT); 00417 if (FAILED(hres)) 00418 { 00419 *ppwzFriendlyName = NULL; 00420 return hres; 00421 } 00422 if (moniker) 00423 { 00424 IBindCtx *bcxt; 00425 CreateBindCtx(0, &bcxt); 00426 00427 IMoniker_GetDisplayName(moniker, bcxt, NULL, ppwzFriendlyName); 00428 IBindCtx_Release(bcxt); 00429 IMoniker_Release(moniker); 00430 } 00431 else 00432 *ppwzFriendlyName = NULL; 00433 } 00434 00435 return S_OK; 00436 } 00437 00438 static HRESULT WINAPI IHlink_fnSetTargetFrameName(IHlink* iface, 00439 LPCWSTR pwzTargetFramename) 00440 { 00441 HlinkImpl *This = impl_from_IHlink(iface); 00442 TRACE("(%p)->(%s)\n", This, debugstr_w(pwzTargetFramename)); 00443 00444 heap_free(This->TargetFrameName); 00445 This->TargetFrameName = hlink_strdupW( pwzTargetFramename ); 00446 00447 return S_OK; 00448 } 00449 00450 static HRESULT WINAPI IHlink_fnGetTargetFrameName(IHlink* iface, 00451 LPWSTR *ppwzTargetFrameName) 00452 { 00453 HlinkImpl *This = impl_from_IHlink(iface); 00454 00455 TRACE("(%p)->(%p)\n", This, ppwzTargetFrameName); 00456 00457 if(!This->TargetFrameName) { 00458 *ppwzTargetFrameName = NULL; 00459 return S_FALSE; 00460 } 00461 00462 *ppwzTargetFrameName = hlink_co_strdupW( This->TargetFrameName ); 00463 if(!*ppwzTargetFrameName) 00464 return E_OUTOFMEMORY; 00465 00466 return S_OK; 00467 } 00468 00469 static HRESULT WINAPI IHlink_fnGetMiscStatus(IHlink* iface, DWORD* pdwStatus) 00470 { 00471 FIXME("\n"); 00472 return E_NOTIMPL; 00473 } 00474 00475 static HRESULT WINAPI IHlink_fnNavigate(IHlink* iface, DWORD grfHLNF, LPBC pbc, 00476 IBindStatusCallback *pbsc, IHlinkBrowseContext *phbc) 00477 { 00478 HlinkImpl *This = impl_from_IHlink(iface); 00479 IMoniker *mon = NULL; 00480 HRESULT r; 00481 00482 FIXME("Semi-Stub:(%p)->(%i %p %p %p)\n", This, grfHLNF, pbc, pbsc, phbc); 00483 00484 r = __GetMoniker(This, &mon, HLINKGETREF_ABSOLUTE); 00485 TRACE("Moniker %p\n", mon); 00486 00487 if (SUCCEEDED(r)) 00488 { 00489 IBindCtx *bcxt; 00490 IHlinkTarget *target = NULL; 00491 00492 CreateBindCtx(0, &bcxt); 00493 00494 RegisterBindStatusCallback(bcxt, pbsc, NULL, 0); 00495 00496 r = IMoniker_BindToObject(mon, bcxt, NULL, &IID_IHlinkTarget, 00497 (LPVOID*)&target); 00498 TRACE("IHlinkTarget returned 0x%x\n", r); 00499 if (r == S_OK) 00500 { 00501 IHlinkTarget_SetBrowseContext(target, phbc); 00502 IHlinkTarget_Navigate(target, grfHLNF, This->Location); 00503 IHlinkTarget_Release(target); 00504 } 00505 else 00506 { 00507 static const WCHAR szOpen[] = {'o','p','e','n',0}; 00508 LPWSTR target = NULL; 00509 00510 r = IHlink_GetStringReference(iface, HLINKGETREF_DEFAULT, &target, NULL); 00511 if (SUCCEEDED(r) && target) 00512 { 00513 ShellExecuteW(NULL, szOpen, target, NULL, NULL, SW_SHOW); 00514 CoTaskMemFree(target); 00515 } 00516 } 00517 00518 RevokeBindStatusCallback(bcxt, pbsc); 00519 00520 IBindCtx_Release(bcxt); 00521 IMoniker_Release(mon); 00522 } 00523 00524 if (This->Site) 00525 IHlinkSite_OnNavigationComplete(This->Site, This->SiteData, 0, r, NULL); 00526 00527 TRACE("Finished Navigation\n"); 00528 return r; 00529 } 00530 00531 static HRESULT WINAPI IHlink_fnSetAdditonalParams(IHlink* iface, 00532 LPCWSTR pwzAdditionalParams) 00533 { 00534 TRACE("Not implemented in native IHlink\n"); 00535 return E_NOTIMPL; 00536 } 00537 00538 static HRESULT WINAPI IHlink_fnGetAdditionalParams(IHlink* iface, 00539 LPWSTR* ppwzAdditionalParams) 00540 { 00541 TRACE("Not implemented in native IHlink\n"); 00542 return E_NOTIMPL; 00543 } 00544 00545 static const IHlinkVtbl hlvt = 00546 { 00547 IHlink_fnQueryInterface, 00548 IHlink_fnAddRef, 00549 IHlink_fnRelease, 00550 IHlink_fnSetHlinkSite, 00551 IHlink_fnGetHlinkSite, 00552 IHlink_fnSetMonikerReference, 00553 IHlink_fnGetMonikerReference, 00554 IHlink_fnSetStringReference, 00555 IHlink_fnGetStringReference, 00556 IHlink_fnSetFriendlyName, 00557 IHlink_fnGetFriendlyName, 00558 IHlink_fnSetTargetFrameName, 00559 IHlink_fnGetTargetFrameName, 00560 IHlink_fnGetMiscStatus, 00561 IHlink_fnNavigate, 00562 IHlink_fnSetAdditonalParams, 00563 IHlink_fnGetAdditionalParams 00564 }; 00565 00566 static HRESULT WINAPI IDataObject_fnQueryInterface(IDataObject* iface, 00567 REFIID riid, LPVOID *ppvObj) 00568 { 00569 HlinkImpl *This = impl_from_IDataObject(iface); 00570 TRACE("%p\n", This); 00571 return IHlink_QueryInterface(&This->IHlink_iface, riid, ppvObj); 00572 } 00573 00574 static ULONG WINAPI IDataObject_fnAddRef (IDataObject* iface) 00575 { 00576 HlinkImpl *This = impl_from_IDataObject(iface); 00577 TRACE("%p\n", This); 00578 return IHlink_AddRef(&This->IHlink_iface); 00579 } 00580 00581 static ULONG WINAPI IDataObject_fnRelease (IDataObject* iface) 00582 { 00583 HlinkImpl *This = impl_from_IDataObject(iface); 00584 TRACE("%p\n", This); 00585 return IHlink_Release(&This->IHlink_iface); 00586 } 00587 00588 static HRESULT WINAPI IDataObject_fnGetData(IDataObject* iface, 00589 FORMATETC* pformatetcIn, STGMEDIUM* pmedium) 00590 { 00591 FIXME("\n"); 00592 return E_NOTIMPL; 00593 } 00594 00595 static HRESULT WINAPI IDataObject_fnGetDataHere(IDataObject* iface, 00596 FORMATETC* pformatetc, STGMEDIUM* pmedium) 00597 { 00598 FIXME("\n"); 00599 return E_NOTIMPL; 00600 } 00601 00602 static HRESULT WINAPI IDataObject_fnQueryGetData(IDataObject* iface, 00603 FORMATETC* pformatetc) 00604 { 00605 FIXME("\n"); 00606 return E_NOTIMPL; 00607 } 00608 00609 static HRESULT WINAPI IDataObject_fnGetConicalFormatEtc(IDataObject* iface, 00610 FORMATETC* pformatetcIn, FORMATETC* pformatetcOut) 00611 { 00612 FIXME("\n"); 00613 return E_NOTIMPL; 00614 } 00615 00616 static HRESULT WINAPI IDataObject_fnSetData(IDataObject* iface, 00617 FORMATETC* pformatetc, STGMEDIUM* pmedium, BOOL fRelease) 00618 { 00619 FIXME("\n"); 00620 return E_NOTIMPL; 00621 } 00622 00623 static HRESULT WINAPI IDataObject_fnEnumFormatEtc(IDataObject* iface, 00624 DWORD dwDirection, IEnumFORMATETC** ppenumFormatEtc) 00625 { 00626 FIXME("\n"); 00627 return E_NOTIMPL; 00628 } 00629 00630 static HRESULT WINAPI IDataObject_fnDAdvise(IDataObject* iface, 00631 FORMATETC* pformatetc, DWORD advf, IAdviseSink* pAdvSink, 00632 DWORD* pdwConnection) 00633 { 00634 FIXME("\n"); 00635 return E_NOTIMPL; 00636 } 00637 00638 static HRESULT WINAPI IDataObject_fnDUnadvise(IDataObject* iface, 00639 DWORD dwConnection) 00640 { 00641 FIXME("\n"); 00642 return E_NOTIMPL; 00643 } 00644 00645 static HRESULT WINAPI IDataObject_fnEnumDAdvise(IDataObject* iface, 00646 IEnumSTATDATA** ppenumAdvise) 00647 { 00648 FIXME("\n"); 00649 return E_NOTIMPL; 00650 } 00651 00652 static const IDataObjectVtbl dovt = 00653 { 00654 IDataObject_fnQueryInterface, 00655 IDataObject_fnAddRef, 00656 IDataObject_fnRelease, 00657 IDataObject_fnGetData, 00658 IDataObject_fnGetDataHere, 00659 IDataObject_fnQueryGetData, 00660 IDataObject_fnGetConicalFormatEtc, 00661 IDataObject_fnSetData, 00662 IDataObject_fnEnumFormatEtc, 00663 IDataObject_fnDAdvise, 00664 IDataObject_fnDUnadvise, 00665 IDataObject_fnEnumDAdvise 00666 }; 00667 00668 static HRESULT WINAPI IPersistStream_fnQueryInterface(IPersistStream* iface, 00669 REFIID riid, LPVOID *ppvObj) 00670 { 00671 HlinkImpl *This = impl_from_IPersistStream(iface); 00672 TRACE("(%p)\n", This); 00673 return IHlink_QueryInterface(&This->IHlink_iface, riid, ppvObj); 00674 } 00675 00676 static ULONG WINAPI IPersistStream_fnAddRef (IPersistStream* iface) 00677 { 00678 HlinkImpl *This = impl_from_IPersistStream(iface); 00679 TRACE("(%p)\n", This); 00680 return IHlink_AddRef(&This->IHlink_iface); 00681 } 00682 00683 static ULONG WINAPI IPersistStream_fnRelease (IPersistStream* iface) 00684 { 00685 HlinkImpl *This = impl_from_IPersistStream(iface); 00686 TRACE("(%p)\n", This); 00687 return IHlink_Release(&This->IHlink_iface); 00688 } 00689 00690 static HRESULT WINAPI IPersistStream_fnGetClassID(IPersistStream* iface, 00691 CLSID* pClassID) 00692 { 00693 HlinkImpl *This = impl_from_IPersistStream(iface); 00694 TRACE("(%p)\n", This); 00695 *pClassID = CLSID_StdHlink; 00696 return S_OK; 00697 } 00698 00699 static HRESULT WINAPI IPersistStream_fnIsDirty(IPersistStream* iface) 00700 { 00701 FIXME("\n"); 00702 return E_NOTIMPL; 00703 } 00704 00705 static HRESULT write_hlink_string(IStream *pStm, LPCWSTR str) 00706 { 00707 DWORD len; 00708 HRESULT hr; 00709 00710 TRACE("(%p, %s)\n", pStm, debugstr_w(str)); 00711 00712 len = strlenW(str) + 1; 00713 00714 hr = IStream_Write(pStm, &len, sizeof(len), NULL); 00715 if (FAILED(hr)) return hr; 00716 00717 hr = IStream_Write(pStm, str, len * sizeof(WCHAR), NULL); 00718 if (FAILED(hr)) return hr; 00719 00720 return S_OK; 00721 } 00722 00723 static inline ULONG size_hlink_string(LPCWSTR str) 00724 { 00725 return sizeof(DWORD) + (strlenW(str) + 1) * sizeof(WCHAR); 00726 } 00727 00728 static HRESULT read_hlink_string(IStream *pStm, LPWSTR *out_str) 00729 { 00730 LPWSTR str; 00731 DWORD len; 00732 ULONG read; 00733 HRESULT hr; 00734 00735 hr = IStream_Read(pStm, &len, sizeof(len), &read); 00736 if (FAILED(hr)) return hr; 00737 if (read != sizeof(len)) return STG_E_READFAULT; 00738 00739 TRACE("read len %d\n", len); 00740 00741 str = heap_alloc(len * sizeof(WCHAR)); 00742 if (!str) return E_OUTOFMEMORY; 00743 00744 hr = IStream_Read(pStm, str, len * sizeof(WCHAR), &read); 00745 if (FAILED(hr)) 00746 { 00747 heap_free(str); 00748 return hr; 00749 } 00750 if (read != len * sizeof(WCHAR)) 00751 { 00752 heap_free(str); 00753 return STG_E_READFAULT; 00754 } 00755 TRACE("read string %s\n", debugstr_w(str)); 00756 00757 *out_str = str; 00758 return S_OK; 00759 } 00760 00761 static HRESULT WINAPI IPersistStream_fnLoad(IPersistStream* iface, 00762 IStream* pStm) 00763 { 00764 HRESULT r; 00765 DWORD hdr[2]; 00766 DWORD read; 00767 HlinkImpl *This = impl_from_IPersistStream(iface); 00768 00769 r = IStream_Read(pStm, hdr, sizeof(hdr), &read); 00770 if (read != sizeof(hdr) || (hdr[0] != HLINK_SAVE_MAGIC)) 00771 { 00772 r = E_FAIL; 00773 goto end; 00774 } 00775 if (hdr[1] & ~HLINK_SAVE_ALL) 00776 FIXME("unknown flag(s) 0x%x\n", hdr[1] & ~HLINK_SAVE_ALL); 00777 00778 if (hdr[1] & HLINK_SAVE_TARGET_FRAME_PRESENT) 00779 { 00780 TRACE("loading target frame name\n"); 00781 r = read_hlink_string(pStm, &This->TargetFrameName); 00782 if (FAILED(r)) goto end; 00783 } 00784 00785 if (hdr[1] & HLINK_SAVE_FRIENDLY_PRESENT) 00786 { 00787 TRACE("loading target friendly name\n"); 00788 if (!(hdr[1] & 0x4)) 00789 FIXME("0x4 flag not present with friendly name flag - not sure what this means\n"); 00790 r = read_hlink_string(pStm, &This->FriendlyName); 00791 if (FAILED(r)) goto end; 00792 } 00793 00794 if (hdr[1] & HLINK_SAVE_MONIKER_PRESENT) 00795 { 00796 TRACE("loading moniker\n"); 00797 r = OleLoadFromStream(pStm, &IID_IMoniker, (LPVOID*)&(This->Moniker)); 00798 if (FAILED(r)) 00799 goto end; 00800 This->absolute = hdr[1] & HLINK_SAVE_MONIKER_IS_ABSOLUTE ? TRUE : FALSE; 00801 } 00802 00803 if (hdr[1] & HLINK_SAVE_LOCATION_PRESENT) 00804 { 00805 TRACE("loading location\n"); 00806 r = read_hlink_string(pStm, &This->Location); 00807 if (FAILED(r)) goto end; 00808 } 00809 00810 end: 00811 TRACE("Load Result 0x%x (%p)\n", r, This->Moniker); 00812 00813 return r; 00814 } 00815 00816 static HRESULT WINAPI IPersistStream_fnSave(IPersistStream* iface, 00817 IStream* pStm, BOOL fClearDirty) 00818 { 00819 HRESULT r; 00820 HlinkImpl *This = impl_from_IPersistStream(iface); 00821 DWORD hdr[2]; 00822 IMoniker *moniker; 00823 00824 TRACE("(%p) Moniker(%p)\n", This, This->Moniker); 00825 00826 r = __GetMoniker(This, &moniker, HLINKGETREF_DEFAULT); 00827 if (FAILED(r)) 00828 return r; 00829 r = E_FAIL; 00830 00831 hdr[0] = HLINK_SAVE_MAGIC; 00832 hdr[1] = 0; 00833 00834 if (moniker) 00835 hdr[1] |= HLINK_SAVE_MONIKER_PRESENT; 00836 if (This->absolute) 00837 hdr[1] |= HLINK_SAVE_MONIKER_IS_ABSOLUTE; 00838 if (This->Location) 00839 hdr[1] |= HLINK_SAVE_LOCATION_PRESENT; 00840 if (This->FriendlyName) 00841 hdr[1] |= HLINK_SAVE_FRIENDLY_PRESENT | 4 /* FIXME */; 00842 if (This->TargetFrameName) 00843 hdr[1] |= HLINK_SAVE_TARGET_FRAME_PRESENT; 00844 00845 IStream_Write(pStm, hdr, sizeof(hdr), NULL); 00846 00847 if (This->TargetFrameName) 00848 { 00849 r = write_hlink_string(pStm, This->TargetFrameName); 00850 if (FAILED(r)) goto end; 00851 } 00852 00853 if (This->FriendlyName) 00854 { 00855 r = write_hlink_string(pStm, This->FriendlyName); 00856 if (FAILED(r)) goto end; 00857 } 00858 00859 if (moniker) 00860 { 00861 IPersistStream* monstream; 00862 00863 monstream = NULL; 00864 IMoniker_QueryInterface(moniker, &IID_IPersistStream, 00865 (LPVOID*)&monstream); 00866 if (monstream) 00867 { 00868 r = OleSaveToStream(monstream, pStm); 00869 IPersistStream_Release(monstream); 00870 } 00871 if (FAILED(r)) goto end; 00872 } 00873 00874 if (This->Location) 00875 { 00876 r = write_hlink_string(pStm, This->Location); 00877 if (FAILED(r)) goto end; 00878 } 00879 00880 end: 00881 if (moniker) IMoniker_Release(moniker); 00882 TRACE("Save Result 0x%x\n", r); 00883 00884 return r; 00885 } 00886 00887 static HRESULT WINAPI IPersistStream_fnGetSizeMax(IPersistStream* iface, 00888 ULARGE_INTEGER* pcbSize) 00889 { 00890 HRESULT r; 00891 HlinkImpl *This = impl_from_IPersistStream(iface); 00892 IMoniker *moniker; 00893 00894 TRACE("(%p) Moniker(%p)\n", This, This->Moniker); 00895 00896 pcbSize->QuadPart = sizeof(DWORD)*2; 00897 00898 if (This->TargetFrameName) 00899 pcbSize->QuadPart += size_hlink_string(This->TargetFrameName); 00900 00901 if (This->FriendlyName) 00902 pcbSize->QuadPart += size_hlink_string(This->FriendlyName); 00903 00904 r = __GetMoniker(This, &moniker, HLINKGETREF_DEFAULT); 00905 if (FAILED(r)) 00906 return r; 00907 r = E_FAIL; 00908 00909 if (moniker) 00910 { 00911 IPersistStream* monstream = NULL; 00912 IMoniker_QueryInterface(moniker, &IID_IPersistStream, 00913 (LPVOID*)&monstream); 00914 if (monstream) 00915 { 00916 ULARGE_INTEGER mon_size; 00917 r = IPersistStream_GetSizeMax(monstream, &mon_size); 00918 pcbSize->QuadPart += mon_size.QuadPart; 00919 IPersistStream_Release(monstream); 00920 } 00921 IMoniker_Release(moniker); 00922 } 00923 00924 if (This->Location) 00925 pcbSize->QuadPart += size_hlink_string(This->Location); 00926 00927 return r; 00928 } 00929 00930 static const IPersistStreamVtbl psvt = 00931 { 00932 IPersistStream_fnQueryInterface, 00933 IPersistStream_fnAddRef, 00934 IPersistStream_fnRelease, 00935 IPersistStream_fnGetClassID, 00936 IPersistStream_fnIsDirty, 00937 IPersistStream_fnLoad, 00938 IPersistStream_fnSave, 00939 IPersistStream_fnGetSizeMax, 00940 }; 00941 00942 HRESULT HLink_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv) 00943 { 00944 HlinkImpl * hl; 00945 00946 TRACE("unkOut=%p riid=%s\n", pUnkOuter, debugstr_guid(riid)); 00947 *ppv = NULL; 00948 00949 if (pUnkOuter) 00950 return CLASS_E_NOAGGREGATION; 00951 00952 hl = heap_alloc_zero(sizeof(HlinkImpl)); 00953 if (!hl) 00954 return E_OUTOFMEMORY; 00955 00956 hl->ref = 1; 00957 hl->IHlink_iface.lpVtbl = &hlvt; 00958 hl->IPersistStream_iface.lpVtbl = &psvt; 00959 hl->IDataObject_iface.lpVtbl = &dovt; 00960 00961 *ppv = hl; 00962 return S_OK; 00963 } Generated on Sun May 27 2012 04:23:53 for ReactOS by
1.7.6.1
|