ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

link.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.