[ros-diffs] [hpoussin] 31597: Autosyncing with Wine HEAD

hpoussin at svn.reactos.org hpoussin at svn.reactos.org
Fri Jan 4 22:53:35 CET 2008


Author: hpoussin
Date: Sat Jan  5 00:53:35 2008
New Revision: 31597

URL: http://svn.reactos.org/svn/reactos?rev=31597&view=rev
Log:
Autosyncing with Wine HEAD

Added:
    trunk/reactos/dll/win32/hlink/
    trunk/reactos/dll/win32/hlink/browse_ctx.c   (with props)
    trunk/reactos/dll/win32/hlink/extserv.c   (with props)
    trunk/reactos/dll/win32/hlink/hlink.rbuild   (with props)
    trunk/reactos/dll/win32/hlink/hlink.spec   (with props)
    trunk/reactos/dll/win32/hlink/hlink_main.c   (with props)
    trunk/reactos/dll/win32/hlink/hlink_private.h   (with props)
    trunk/reactos/dll/win32/hlink/link.c   (with props)

Added: trunk/reactos/dll/win32/hlink/browse_ctx.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/hlink/browse_ctx.c?rev=31597&view=auto
==============================================================================
--- trunk/reactos/dll/win32/hlink/browse_ctx.c (added)
+++ trunk/reactos/dll/win32/hlink/browse_ctx.c Sat Jan  5 00:53:35 2008
@@ -1,0 +1,270 @@
+/*
+ * Implementation of hyperlinking (hlink.dll)
+ *
+ * Copyright 2005 Aric Stewart for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "hlink_private.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(hlink);
+
+static const IHlinkBrowseContextVtbl hlvt;
+
+typedef struct
+{
+    const IHlinkBrowseContextVtbl    *lpVtbl;
+    LONG        ref;
+    HLBWINFO*   BrowseWindowInfo;
+    IHlink*     CurrentPage;
+} HlinkBCImpl;
+
+
+HRESULT WINAPI HLinkBrowseContext_Constructor(IUnknown *pUnkOuter, REFIID riid,
+        LPVOID *ppv)
+{
+    HlinkBCImpl * hl;
+
+    TRACE("unkOut=%p riid=%s\n", pUnkOuter, debugstr_guid(riid));
+    *ppv = NULL;
+
+    if (pUnkOuter)
+        return CLASS_E_NOAGGREGATION;
+
+    hl = heap_alloc_zero(sizeof(HlinkBCImpl));
+    if (!hl)
+        return E_OUTOFMEMORY;
+
+    hl->ref = 1;
+    hl->lpVtbl = &hlvt;
+
+    *ppv = hl;
+    return S_OK;
+}
+
+static HRESULT WINAPI IHlinkBC_fnQueryInterface( IHlinkBrowseContext *iface,
+        REFIID riid, LPVOID* ppvObj)
+{
+    HlinkBCImpl  *This = (HlinkBCImpl*)iface;
+    TRACE ("(%p)->(%s,%p)\n", This, debugstr_guid (riid), ppvObj);
+
+    if (IsEqualIID(riid, &IID_IUnknown) ||
+        IsEqualIID(riid, &IID_IHlinkBrowseContext))
+        *ppvObj = This;
+
+    if (*ppvObj)
+    {
+        IUnknown_AddRef((IUnknown*)(*ppvObj));
+        return S_OK;
+    }
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI IHlinkBC_fnAddRef (IHlinkBrowseContext* iface)
+{
+    HlinkBCImpl  *This = (HlinkBCImpl*)iface;
+    ULONG refCount = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p)->(count=%u)\n", This, refCount - 1);
+
+    return refCount;
+}
+
+static ULONG WINAPI IHlinkBC_fnRelease (IHlinkBrowseContext* iface)
+{
+    HlinkBCImpl  *This = (HlinkBCImpl*)iface;
+    ULONG refCount = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p)->(count=%u)\n", This, refCount + 1);
+    if (refCount)
+        return refCount;
+
+    TRACE("-- destroying IHlinkBrowseContext (%p)\n", This);
+    heap_free(This->BrowseWindowInfo);
+    if (This->CurrentPage)
+        IHlink_Release(This->CurrentPage);
+    heap_free(This);
+    return 0;
+}
+
+static HRESULT WINAPI IHlinkBC_Register(IHlinkBrowseContext* iface,
+        DWORD dwReserved, IUnknown *piunk, IMoniker *pimk, DWORD *pdwRegister)
+{
+    static const WCHAR szIdent[] = {'W','I','N','E','H','L','I','N','K',0};
+    HlinkBCImpl  *This = (HlinkBCImpl*)iface;
+    IMoniker *mon;
+    IMoniker *composite;
+    IRunningObjectTable *ROT;
+
+    FIXME("(%p)->(%i %p %p %p)\n", This, dwReserved, piunk, pimk, pdwRegister);
+
+    CreateItemMoniker(NULL, szIdent, &mon);
+    CreateGenericComposite(mon, pimk, &composite);
+
+    GetRunningObjectTable(0, &ROT);
+    IRunningObjectTable_Register(ROT, 0, piunk, composite, pdwRegister);
+
+    IRunningObjectTable_Release(ROT);
+    IMoniker_Release(composite);
+    IMoniker_Release(mon);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI IHlinkBC_GetObject(IHlinkBrowseContext* face,
+        IMoniker *pimk, BOOL fBindifRootRegistered, IUnknown **ppiunk)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IHlinkBC_Revoke(IHlinkBrowseContext* iface,
+        DWORD dwRegister)
+{
+    HRESULT r = S_OK;
+    IRunningObjectTable *ROT;
+    HlinkBCImpl  *This = (HlinkBCImpl*)iface;
+
+    FIXME("(%p)->(%i)\n", This, dwRegister);
+
+    GetRunningObjectTable(0, &ROT);
+    r = IRunningObjectTable_Revoke(ROT, dwRegister);
+    IRunningObjectTable_Release(ROT);
+
+    return r;
+}
+
+static HRESULT WINAPI IHlinkBC_SetBrowseWindowInfo(IHlinkBrowseContext* iface,
+        HLBWINFO *phlbwi)
+{
+    HlinkBCImpl  *This = (HlinkBCImpl*)iface;
+    TRACE("(%p)->(%p)\n", This, phlbwi);
+
+    heap_free(This->BrowseWindowInfo);
+    This->BrowseWindowInfo = heap_alloc(phlbwi->cbSize);
+    memcpy(This->BrowseWindowInfo, phlbwi, phlbwi->cbSize);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI IHlinkBC_GetBrowseWindowInfo(IHlinkBrowseContext* iface,
+        HLBWINFO *phlbwi)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IHlinkBC_SetInitialHlink(IHlinkBrowseContext* iface,
+        IMoniker *pimkTarget, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName)
+{
+    HlinkBCImpl  *This = (HlinkBCImpl*)iface;
+
+    FIXME("(%p)->(%p %s %s)\n", This, pimkTarget,
+            debugstr_w(pwzLocation), debugstr_w(pwzFriendlyName));
+
+    if (This->CurrentPage)
+        IHlink_Release(This->CurrentPage);
+
+    HlinkCreateFromMoniker(pimkTarget, pwzLocation, pwzFriendlyName, NULL,
+            0, NULL, &IID_IHlink, (LPVOID*) &This->CurrentPage);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI IHlinkBC_OnNavigateHlink(IHlinkBrowseContext *iface,
+        DWORD grfHLNF, IMoniker* pmkTarget, LPCWSTR pwzLocation, LPCWSTR
+        pwzFriendlyName, ULONG *puHLID)
+{
+    HlinkBCImpl  *This = (HlinkBCImpl*)iface;
+
+    FIXME("(%p)->(%i %p %s %s %p)\n", This, grfHLNF, pmkTarget,
+            debugstr_w(pwzLocation), debugstr_w(pwzFriendlyName), puHLID);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI IHlinkBC_UpdateHlink(IHlinkBrowseContext* iface,
+        ULONG uHLID, IMoniker* pimkTarget, LPCWSTR pwzLocation,
+        LPCWSTR pwzFriendlyName)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IHlinkBC_EnumNavigationStack( IHlinkBrowseContext *iface,
+        DWORD dwReserved, DWORD grfHLFNAMEF, IEnumHLITEM** ppienumhlitem)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IHlinkBC_QueryHlink( IHlinkBrowseContext* iface,
+        DWORD grfHLONG, ULONG uHLID)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IHlinkBC_GetHlink( IHlinkBrowseContext* iface,
+        ULONG uHLID, IHlink** ppihl)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IHlinkBC_SetCurrentHlink( IHlinkBrowseContext* iface,
+        ULONG uHLID)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IHlinkBC_Clone( IHlinkBrowseContext* iface,
+        IUnknown* piunkOuter, REFIID riid, IUnknown** ppiunkOjb)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IHlinkBC_Close(IHlinkBrowseContext* iface,
+        DWORD reserverd)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static const IHlinkBrowseContextVtbl hlvt =
+{
+    IHlinkBC_fnQueryInterface,
+    IHlinkBC_fnAddRef,
+    IHlinkBC_fnRelease,
+    IHlinkBC_Register,
+    IHlinkBC_GetObject,
+    IHlinkBC_Revoke,
+    IHlinkBC_SetBrowseWindowInfo,
+    IHlinkBC_GetBrowseWindowInfo,
+    IHlinkBC_SetInitialHlink,
+    IHlinkBC_OnNavigateHlink,
+    IHlinkBC_UpdateHlink,
+    IHlinkBC_EnumNavigationStack,
+    IHlinkBC_QueryHlink,
+    IHlinkBC_GetHlink,
+    IHlinkBC_SetCurrentHlink,
+    IHlinkBC_Clone,
+    IHlinkBC_Close
+};

Propchange: trunk/reactos/dll/win32/hlink/browse_ctx.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/dll/win32/hlink/extserv.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/hlink/extserv.c?rev=31597&view=auto
==============================================================================
--- trunk/reactos/dll/win32/hlink/extserv.c (added)
+++ trunk/reactos/dll/win32/hlink/extserv.c Sat Jan  5 00:53:35 2008
@@ -1,0 +1,259 @@
+/*
+ * Copyright 2007 Jacek Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "hlink_private.h"
+
+#include "wine/debug.h"
+#include "wine/unicode.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(hlink);
+
+#define DEFINE_THIS(cls,ifc,iface) ((cls*)((BYTE*)(iface)-offsetof(cls,lp ## ifc ## Vtbl)))
+
+typedef struct {
+    const IUnknownVtbl        *lpIUnknownVtbl;
+    const IAuthenticateVtbl   *lpIAuthenticateVtbl;
+    const IHttpNegotiateVtbl  *lpIHttpNegotiateVtbl;
+
+    LONG ref;
+    IUnknown *outer;
+
+    HWND hwnd;
+    LPWSTR username;
+    LPWSTR password;
+    LPWSTR headers;
+} ExtensionService;
+
+#define EXTSERVUNK(x)    ((IUnknown*)       &(x)->lpIUnknownVtbl)
+#define AUTHENTICATE(x)  ((IAuthenticate*)  &(x)->lpIAuthenticateVtbl)
+#define HTTPNEGOTIATE(x) ((IHttpNegotiate*) &(x)->lpIHttpNegotiateVtbl)
+
+#define EXTSERVUNK_THIS(iface)  DEFINE_THIS(ExtensionService, IUnknown, iface)
+
+static HRESULT WINAPI ExtServUnk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
+{
+    ExtensionService *This = EXTSERVUNK_THIS(iface);
+
+    *ppv = NULL;
+
+    if(IsEqualGUID(&IID_IUnknown, riid)) {
+        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
+        *ppv = EXTSERVUNK(This);
+    }else if(IsEqualGUID(&IID_IAuthenticate, riid)) {
+        TRACE("(%p)->(IID_IAuthenticate %p)\n", This, ppv);
+        *ppv = AUTHENTICATE(This);
+    }else if(IsEqualGUID(&IID_IHttpNegotiate, riid)) {
+        TRACE("(%p)->(IID_IHttpNegotiate %p)\n", This, ppv);
+        *ppv = HTTPNEGOTIATE(This);
+    }
+
+    if(*ppv) {
+        IUnknown_AddRef(EXTSERVUNK(This));
+        return S_OK;
+    }
+
+    FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ExtServUnk_AddRef(IUnknown *iface)
+{
+    ExtensionService *This = EXTSERVUNK_THIS(iface);
+    LONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    return ref;
+}
+
+static ULONG WINAPI ExtServUnk_Release(IUnknown *iface)
+{
+    ExtensionService *This = EXTSERVUNK_THIS(iface);
+    LONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    if(!ref) {
+        heap_free(This->username);
+        heap_free(This->password);
+        heap_free(This->headers);
+        heap_free(This);
+    }
+
+    return ref;
+}
+
+#undef EXTSERVUNK_THIS
+
+static const IUnknownVtbl ExtServUnkVtbl = {
+    ExtServUnk_QueryInterface,
+    ExtServUnk_AddRef,
+    ExtServUnk_Release
+};
+
+#define AUTHENTICATE_THIS(iface) DEFINE_THIS(ExtensionService, IAuthenticate, iface)
+
+static HRESULT WINAPI Authenticate_QueryInterface(IAuthenticate *iface, REFIID riid, void **ppv)
+{
+    ExtensionService *This = AUTHENTICATE_THIS(iface);
+    return IUnknown_QueryInterface(This->outer, riid, ppv);
+}
+
+static ULONG WINAPI Authenticate_AddRef(IAuthenticate *iface)
+{
+    ExtensionService *This = AUTHENTICATE_THIS(iface);
+    return IUnknown_AddRef(This->outer);
+}
+
+static ULONG WINAPI Authenticate_Release(IAuthenticate *iface)
+{
+    ExtensionService *This = AUTHENTICATE_THIS(iface);
+    return IUnknown_Release(This->outer);
+}
+
+static HRESULT WINAPI Authenticate_Authenticate(IAuthenticate *iface,
+        HWND *phwnd, LPWSTR *pszUsername, LPWSTR *pszPassword)
+{
+    ExtensionService *This = AUTHENTICATE_THIS(iface);
+
+    TRACE("(%p)->(%p %p %p)\n", This, phwnd, pszUsername, pszPassword);
+
+    if(!phwnd || !pszUsername || !pszPassword)
+        return E_INVALIDARG;
+
+    *phwnd = This->hwnd;
+    *pszUsername = hlink_co_strdupW(This->username);
+    *pszPassword = hlink_co_strdupW(This->password);
+
+    return S_OK;
+}
+
+#undef AUTHENTICATE_THIS
+
+static const IAuthenticateVtbl AuthenticateVtbl = {
+    Authenticate_QueryInterface,
+    Authenticate_AddRef,
+    Authenticate_Release,
+    Authenticate_Authenticate
+};
+
+#define HTTPNEGOTIATE_THIS(iface) DEFINE_THIS(ExtensionService, IHttpNegotiate, iface)
+
+static HRESULT WINAPI HttpNegotiate_QueryInterface(IHttpNegotiate *iface, REFIID riid, void **ppv)
+{
+    ExtensionService *This = HTTPNEGOTIATE_THIS(iface);
+    return IUnknown_QueryInterface(This->outer, riid, ppv);
+}
+
+static ULONG WINAPI HttpNegotiate_AddRef(IHttpNegotiate *iface)
+{
+    ExtensionService *This = HTTPNEGOTIATE_THIS(iface);
+    return IUnknown_AddRef(This->outer);
+}
+
+static ULONG WINAPI HttpNegotiate_Release(IHttpNegotiate *iface)
+{
+    ExtensionService *This = HTTPNEGOTIATE_THIS(iface);
+    return IUnknown_Release(This->outer);
+}
+
+static HRESULT WINAPI HttpNegotiate_BeginningTransaction(IHttpNegotiate *iface,
+        LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
+{
+    ExtensionService *This = HTTPNEGOTIATE_THIS(iface);
+
+    TRACE("(%p)->(%s %s %x %p)\n", This, debugstr_w(szURL), debugstr_w(szHeaders), dwReserved,
+          pszAdditionalHeaders);
+
+    if(!pszAdditionalHeaders)
+        return E_INVALIDARG;
+
+    *pszAdditionalHeaders = hlink_co_strdupW(This->headers);
+    return S_OK;
+}
+
+static HRESULT WINAPI HttpNegotiate_OnResponse(IHttpNegotiate *iface, DWORD dwResponseCode,
+        LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders, LPWSTR *pszAdditionalRequestHeaders)
+{
+    ExtensionService *This = HTTPNEGOTIATE_THIS(iface);
+
+    TRACE("(%p)->(%d %s %s %p)\n", This, dwResponseCode, debugstr_w(szResponseHeaders),
+          debugstr_w(szRequestHeaders), pszAdditionalRequestHeaders);
+
+    *pszAdditionalRequestHeaders = NULL;
+    return S_OK;
+}
+
+#undef HTTPNEGOTIATE_THIS
+
+static const IHttpNegotiateVtbl HttpNegotiateVtbl = {
+    HttpNegotiate_QueryInterface,
+    HttpNegotiate_AddRef,
+    HttpNegotiate_Release,
+    HttpNegotiate_BeginningTransaction,
+    HttpNegotiate_OnResponse
+};
+
+HRESULT WINAPI HlinkCreateExtensionServices(LPCWSTR pwzAdditionalHeaders,
+        HWND phwnd, LPCWSTR pszUsername, LPCWSTR pszPassword,
+        IUnknown *punkOuter, REFIID riid, void** ppv)
+{
+    ExtensionService *ret;
+    int len = 0;
+    HRESULT hres = S_OK;
+
+    TRACE("%s %p %s %s %p %s %p\n",debugstr_w(pwzAdditionalHeaders),
+            phwnd, debugstr_w(pszUsername), debugstr_w(pszPassword),
+            punkOuter, debugstr_guid(riid), ppv);
+
+    ret = heap_alloc(sizeof(*ret));
+
+    ret->lpIUnknownVtbl = &ExtServUnkVtbl;
+    ret->lpIAuthenticateVtbl = &AuthenticateVtbl;
+    ret->lpIHttpNegotiateVtbl = &HttpNegotiateVtbl;
+    ret->ref = 1;
+    ret->hwnd = phwnd;
+    ret->username = hlink_strdupW(pszUsername);
+    ret->password = hlink_strdupW(pszPassword);
+
+    if(pwzAdditionalHeaders)
+        len = strlenW(pwzAdditionalHeaders);
+
+    if(len && pwzAdditionalHeaders[len-1] != '\n' && pwzAdditionalHeaders[len-1] != '\r') {
+        static const WCHAR endlW[] = {'\r','\n',0};
+        ret->headers = heap_alloc(len*sizeof(WCHAR) + sizeof(endlW));
+        memcpy(ret->headers, pwzAdditionalHeaders, len*sizeof(WCHAR));
+        memcpy(ret->headers+len, endlW, sizeof(endlW));
+    }else {
+        ret->headers = hlink_strdupW(pwzAdditionalHeaders);
+    }
+
+    if(!punkOuter) {
+        ret->outer = EXTSERVUNK(ret);
+        hres = IUnknown_QueryInterface(EXTSERVUNK(ret), riid, ppv);
+        IUnknown_Release(EXTSERVUNK(ret));
+    }else if(IsEqualGUID(&IID_IUnknown, riid)) {
+        ret->outer = punkOuter;
+        *ppv = EXTSERVUNK(ret);
+    }else {
+        IUnknown_Release(EXTSERVUNK(ret));
+        hres = E_INVALIDARG;
+    }
+
+    return hres;
+}

Propchange: trunk/reactos/dll/win32/hlink/extserv.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/dll/win32/hlink/hlink.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/hlink/hlink.rbuild?rev=31597&view=auto
==============================================================================
--- trunk/reactos/dll/win32/hlink/hlink.rbuild (added)
+++ trunk/reactos/dll/win32/hlink/hlink.rbuild Sat Jan  5 00:53:35 2008
@@ -1,0 +1,24 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
+<module name="hlink" type="win32dll" baseaddress="${BASEADDRESS_HLINK}" installbase="system32" installname="hlink.dll" allowwarnings="true">
+	<autoregister infsection="OleControlDlls" type="DllRegisterServer" />
+	<importlibrary definition="hlink.spec.def" />
+	<include base="hlink">.</include>
+	<include base="ReactOS">include/reactos/wine</include>
+	<define name="__WINESRC__" />
+	<define name="WINVER">0x600</define>
+	<define name="_WIN32_WINNT">0x600</define>
+	<library>wine</library>
+	<library>shell32</library>
+	<library>ole32</library>
+	<library>advapi32</library>
+	<library>kernel32</library>
+	<library>urlmon</library>
+	<library>uuid</library>
+	<library>ntdll</library>
+	<file>browse_ctx.c</file>
+	<file>extserv.c</file>
+	<file>hlink_main.c</file>
+	<file>link.c</file>
+	<file>hlink.spec</file>
+</module>

Propchange: trunk/reactos/dll/win32/hlink/hlink.rbuild
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/dll/win32/hlink/hlink.spec
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/hlink/hlink.spec?rev=31597&view=auto
==============================================================================
--- trunk/reactos/dll/win32/hlink/hlink.spec (added)
+++ trunk/reactos/dll/win32/hlink/hlink.spec Sat Jan  5 00:53:35 2008
@@ -1,0 +1,33 @@
+3 stdcall HlinkCreateFromMoniker(ptr wstr wstr ptr long ptr ptr ptr)
+4 stdcall HlinkCreateFromString(wstr wstr wstr ptr long ptr ptr ptr)
+5 stdcall HlinkCreateFromData(ptr ptr long ptr ptr ptr)
+6 stdcall HlinkCreateBrowseContext(ptr ptr ptr)
+7 stub HlinkClone
+8 stdcall HlinkNavigateToStringReference(wstr wstr ptr long ptr long ptr ptr ptr)
+9 stdcall HlinkOnNavigate(ptr ptr long ptr wstr wstr ptr)
+10 stdcall HlinkNavigate(ptr ptr long ptr ptr ptr)
+11 stdcall HlinkUpdateStackItem(ptr ptr long ptr wstr wstr)
+12 stub HlinkOnRenameDocument
+14 stub HlinkResolveMonikerForData
+15 stub HlinkResolveStringForData
+16 stub OleSaveToStreamEx
+18 stub HlinkParseDisplayName
+20 stdcall HlinkQueryCreateFromData(ptr)
+21 stub HlinkSetSpecialReference
+22 stdcall HlinkGetSpecialReference(long ptr)
+23 stub HlinkCreateShortcut
+24 stub HlinkResolveShortcut
+25 stdcall HlinkIsShortcut(wstr)
+26 stub HlinkResolveShortcutToString
+27 stub HlinkCreateShortcutFromString
+28 stub HlinkGetValueFromParams
+29 stub HlinkCreateShortcutFromMoniker
+30 stub HlinkResolveShortcutToMoniker
+31 stdcall HlinkTranslateURL(wstr long ptr)
+32 stdcall HlinkCreateExtensionServices(wstr long wstr wstr ptr ptr ptr)
+33 stub HlinkPreprocessMoniker
+
+@ stdcall -private DllCanUnloadNow()
+@ stdcall -private DllGetClassObject(ptr ptr ptr)
+@ stdcall -private DllRegisterServer()
+# @ stub -private DllUnregisterServer

Propchange: trunk/reactos/dll/win32/hlink/hlink.spec
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/dll/win32/hlink/hlink_main.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/hlink/hlink_main.c?rev=31597&view=auto
==============================================================================
--- trunk/reactos/dll/win32/hlink/hlink_main.c (added)
+++ trunk/reactos/dll/win32/hlink/hlink_main.c Sat Jan  5 00:53:35 2008
@@ -1,0 +1,447 @@
+/*
+ * Implementation of hyperlinking (hlink.dll)
+ *
+ * Copyright 2005 Aric Stewart for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "hlink_private.h"
+
+#include "winreg.h"
+#include "hlguids.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(hlink);
+
+typedef HRESULT (CALLBACK *LPFNCREATEINSTANCE)(IUnknown*, REFIID, LPVOID*);
+
+typedef struct
+{
+    const IClassFactoryVtbl *lpVtbl;
+    LPFNCREATEINSTANCE      lpfnCI;
+} CFImpl;
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+    TRACE("%p %d %p\n", hinstDLL, fdwReason, lpvReserved);
+
+    switch (fdwReason)
+    {
+    case DLL_WINE_PREATTACH:
+        return FALSE;  /* prefer native version */
+    case DLL_PROCESS_ATTACH:
+        DisableThreadLibraryCalls(hinstDLL);
+        break;
+    case DLL_PROCESS_DETACH:
+        break;
+    }
+    return TRUE;
+}
+
+HRESULT WINAPI DllCanUnloadNow( void )
+{
+    FIXME("\n");
+    return S_OK;
+}
+
+HRESULT WINAPI HlinkCreateFromMoniker( IMoniker *pimkTrgt, LPCWSTR pwzLocation,
+        LPCWSTR pwzFriendlyName, IHlinkSite* pihlsite, DWORD dwSiteData,
+        IUnknown* piunkOuter, REFIID riid, void** ppvObj)
+{
+    IHlink *hl = NULL;
+    HRESULT r = S_OK;
+
+    TRACE("%p %s %s %p %i %p %s %p\n", pimkTrgt, debugstr_w(pwzLocation),
+            debugstr_w(pwzFriendlyName), pihlsite, dwSiteData, piunkOuter,
+            debugstr_guid(riid), ppvObj);
+
+    r = CoCreateInstance(&CLSID_StdHlink, piunkOuter, CLSCTX_INPROC_SERVER, riid, (LPVOID*)&hl);
+    if (FAILED(r))
+        return r;
+
+    if (pwzLocation)
+        IHlink_SetStringReference(hl, HLINKSETF_LOCATION, NULL, pwzLocation);
+    if (pwzFriendlyName)
+        IHlink_SetFriendlyName(hl, pwzFriendlyName);
+    if (pihlsite)
+        IHlink_SetHlinkSite(hl, pihlsite, dwSiteData);
+    if (pimkTrgt)
+        IHlink_SetMonikerReference(hl, 0, pimkTrgt, pwzLocation);
+
+    *ppvObj = hl;
+
+    TRACE("Returning %i\n",r);
+
+    return r;
+}
+
+HRESULT WINAPI HlinkCreateFromString( LPCWSTR pwzTarget, LPCWSTR pwzLocation,
+        LPCWSTR pwzFriendlyName, IHlinkSite* pihlsite, DWORD dwSiteData,
+        IUnknown* piunkOuter, REFIID riid, void** ppvObj)
+{
+    IHlink *hl = NULL;
+    HRESULT r = S_OK;
+
+    TRACE("%s %s %s %p %i %p %s %p\n", debugstr_w(pwzTarget),
+            debugstr_w(pwzLocation), debugstr_w(pwzFriendlyName), pihlsite,
+            dwSiteData, piunkOuter, debugstr_guid(riid), ppvObj);
+
+    r = CoCreateInstance(&CLSID_StdHlink, piunkOuter, CLSCTX_INPROC_SERVER, riid, (LPVOID*)&hl);
+    if (FAILED(r))
+        return r;
+
+    if (pwzLocation)
+        IHlink_SetStringReference(hl, HLINKSETF_LOCATION, NULL, pwzLocation);
+
+    if (pwzTarget)
+    {
+        IMoniker *pTgtMk = NULL;
+        IBindCtx *pbc = NULL;
+        ULONG eaten;
+
+        CreateBindCtx(0, &pbc);
+        r = MkParseDisplayName(pbc, pwzTarget, &eaten, &pTgtMk);
+        IBindCtx_Release(pbc);
+
+        if (FAILED(r))
+        {
+            LPCWSTR p = strchrW(pwzTarget, ':');
+            if (p && (p - pwzTarget > 1))
+                r = CreateURLMoniker(NULL, pwzTarget, &pTgtMk);
+            else
+                r = CreateFileMoniker(pwzTarget,&pTgtMk);
+        }
+
+        if (FAILED(r))
+        {
+            ERR("couldn't create moniker for %s, failed with error 0x%08x\n",
+                debugstr_w(pwzTarget), r);
+            return r;
+        }
+
+        IHlink_SetMonikerReference(hl, 0, pTgtMk, pwzLocation);
+        IMoniker_Release(pTgtMk);
+
+        IHlink_SetStringReference(hl, HLINKSETF_TARGET, pwzTarget, NULL);
+    }
+
+    if (pwzFriendlyName)
+        IHlink_SetFriendlyName(hl, pwzFriendlyName);
+    if (pihlsite)
+        IHlink_SetHlinkSite(hl, pihlsite, dwSiteData);
+
+    TRACE("Returning %i\n",r);
+    *ppvObj = hl;
+
+    return r;
+}
+
+
+HRESULT WINAPI HlinkCreateBrowseContext( IUnknown* piunkOuter, REFIID riid, void** ppvObj)
+{
+    HRESULT r = S_OK;
+
+    TRACE("%p %s %p\n", piunkOuter, debugstr_guid(riid), ppvObj);
+
+    r = CoCreateInstance(&CLSID_StdHlinkBrowseContext, piunkOuter, CLSCTX_INPROC_SERVER, riid, ppvObj);
+
+    TRACE("returning %i\n",r);
+
+    return r;
+}
+
+HRESULT WINAPI HlinkNavigate(IHlink *phl, IHlinkFrame *phlFrame,
+        DWORD grfHLNF, LPBC pbc, IBindStatusCallback *pbsc,
+        IHlinkBrowseContext *phlbc)
+{
+    HRESULT r = S_OK;
+
+    TRACE("%p %p %i %p %p %p\n", phl, phlFrame, grfHLNF, pbc, pbsc, phlbc);
+
+    if (phlFrame)
+        r = IHlinkFrame_Navigate(phlFrame, grfHLNF, pbc, pbsc, phl);
+    else if (phl)
+        r = IHlink_Navigate(phl, grfHLNF, pbc, pbsc, phlbc);
+
+    return r;
+}
+
+HRESULT WINAPI HlinkOnNavigate( IHlinkFrame *phlFrame,
+        IHlinkBrowseContext* phlbc, DWORD grfHLNF, IMoniker *pmkTarget,
+        LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName, ULONG* puHLID)
+{
+    HRESULT r = S_OK;
+
+    TRACE("%p %p %i %p %s %s %p\n",phlFrame, phlbc, grfHLNF, pmkTarget,
+            debugstr_w(pwzLocation), debugstr_w(pwzFriendlyName), puHLID);
+
+    r = IHlinkBrowseContext_OnNavigateHlink(phlbc, grfHLNF, pmkTarget,
+            pwzLocation, pwzFriendlyName, puHLID);
+
+    if (phlFrame)
+        r = IHlinkFrame_OnNavigate(phlFrame,grfHLNF,pmkTarget, pwzLocation,
+                pwzFriendlyName, 0);
+
+    return r;
+}
+
+HRESULT WINAPI HlinkCreateFromData(IDataObject *piDataObj,
+        IHlinkSite *pihlsite, DWORD dwSiteData, IUnknown *piunkOuter,
+        REFIID riid, void **ppvObj)
+{
+    FIXME("%p %p %d %p %p %p\n",
+          piDataObj, pihlsite, dwSiteData, piunkOuter, riid, ppvObj);
+    *ppvObj = NULL;
+    return E_NOTIMPL;
+}
+
+HRESULT WINAPI HlinkQueryCreateFromData(IDataObject* piDataObj)
+{
+    FIXME("%p\n", piDataObj);
+    return E_NOTIMPL;
+}
+
+HRESULT WINAPI HlinkNavigateToStringReference( LPCWSTR pwzTarget,
+        LPCWSTR pwzLocation, IHlinkSite *pihlsite, DWORD dwSiteData,
+        IHlinkFrame *pihlframe, DWORD grfHLNF, LPBC pibc,
+        IBindStatusCallback *pibsc, IHlinkBrowseContext *pihlbc)
+{
+    HRESULT r;
+    IHlink *hlink = NULL;
+
+    FIXME("%s %s %p %08x %p %08x %p %p %p\n",
+          debugstr_w(pwzTarget), debugstr_w(pwzLocation), pihlsite,
+          dwSiteData, pihlframe, grfHLNF, pibc, pibsc, pihlbc);
+
+    r = HlinkCreateFromString( pwzTarget, pwzLocation, NULL, pihlsite,
+                               dwSiteData, NULL, &IID_IHlink, (LPVOID*) &hlink );
+    if (SUCCEEDED(r))
+        r = HlinkNavigate(hlink, pihlframe, grfHLNF, pibc, pibsc, pihlbc);
+
+    return r;
+}
+
+HRESULT WINAPI HlinkIsShortcut(LPCWSTR pwzFileName)
+{
+    int len;
+
+    static const WCHAR url_ext[] = {'.','u','r','l',0};
+
+    TRACE("(%s)\n", debugstr_w(pwzFileName));
+
+    if(!pwzFileName)
+        return E_INVALIDARG;
+
+    len = strlenW(pwzFileName)-4;
+    if(len < 0)
+        return S_FALSE;
+
+    return strcmpiW(pwzFileName+len, url_ext) ? S_FALSE : S_OK;
+}
+
+HRESULT WINAPI HlinkGetSpecialReference(ULONG uReference, LPWSTR *ppwzReference)
+{
+    DWORD res, type, size = 100;
+    LPCWSTR value_name;
+    WCHAR *buf;
+    HKEY hkey;
+
+    static const WCHAR start_pageW[] = {'S','t','a','r','t',' ','P','a','g','e',0};
+    static const WCHAR search_pageW[] = {'S','e','a','r','c','h',' ','P','a','g','e',0};
+
+    static const WCHAR ie_main_keyW[] =
+        {'S','o','f','t','w','a','r','e',
+         '\\','M','i','c','r','o','s','o','f','t','\\',
+         'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r',
+         '\\','M','a','i','n',0};
+
+    TRACE("(%u %p)\n", uReference, ppwzReference);
+
+    *ppwzReference = NULL;
+
+    switch(uReference) {
+    case HLSR_HOME:
+        value_name = start_pageW;
+        break;
+    case HLSR_SEARCHPAGE:
+        value_name = search_pageW;
+        break;
+    case HLSR_HISTORYFOLDER:
+        return E_NOTIMPL;
+    default:
+        return E_INVALIDARG;
+    }
+
+    res = RegOpenKeyW(HKEY_CURRENT_USER, ie_main_keyW, &hkey);
+    if(res != ERROR_SUCCESS) {
+        WARN("Could not open key: %u\n", res);
+        return HRESULT_FROM_WIN32(res);
+    }
+
+    buf = CoTaskMemAlloc(size);
+    res = RegQueryValueExW(hkey, value_name, NULL, &type, (PBYTE)buf, &size);
+    buf = CoTaskMemRealloc(buf, size);
+    if(res == ERROR_MORE_DATA)
+        res = RegQueryValueExW(hkey, value_name, NULL, &type, (PBYTE)buf, &size);
+    RegCloseKey(hkey);
+    if(res != ERROR_SUCCESS) {
+        WARN("Could not query value %s: %u\n", debugstr_w(value_name), res);
+        CoTaskMemFree(buf);
+        return HRESULT_FROM_WIN32(res);
+    }
+
+    *ppwzReference = buf;
+    return S_OK;
+}
+
+HRESULT WINAPI HlinkTranslateURL(LPCWSTR pwzURL, DWORD grfFlags, LPWSTR *ppwzTranslatedURL)
+{
+    FIXME("(%s %08x %p)\n", debugstr_w(pwzURL), grfFlags, ppwzTranslatedURL);
+    return E_NOTIMPL;
+}
+
+HRESULT WINAPI HlinkUpdateStackItem(IHlinkFrame *pihlframe, IHlinkBrowseContext *pihlbc,
+        ULONG uHLID, IMoniker *pimkTrgt, LPCWSTR pwzLocation, LPCWSTR pwzFriendlyName)
+{
+    FIXME("(%p %p %u %p %s %s)\n", pihlframe, pihlbc, uHLID, pimkTrgt, debugstr_w(pwzLocation),
+          debugstr_w(pwzFriendlyName));
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI HLinkCF_fnQueryInterface ( LPCLASSFACTORY iface,
+        REFIID riid, LPVOID *ppvObj)
+{
+    CFImpl *This = (CFImpl *)iface;
+
+    TRACE("(%p)->(%s)\n",This,debugstr_guid(riid));
+
+    *ppvObj = NULL;
+
+    if (IsEqualIID(riid, &IID_IUnknown) ||
+        IsEqualIID(riid, &IID_IClassFactory))
+    {
+        *ppvObj = This;
+        return S_OK;
+    }
+
+    TRACE("-- E_NOINTERFACE\n");
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI HLinkCF_fnAddRef (LPCLASSFACTORY iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI HLinkCF_fnRelease(LPCLASSFACTORY iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI HLinkCF_fnCreateInstance( LPCLASSFACTORY iface,
+        LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObject)
+{
+    CFImpl *This = (CFImpl *)iface;
+
+    TRACE("%p->(%p,%s,%p)\n", This, pUnkOuter, debugstr_guid(riid), ppvObject);
+
+    *ppvObject = NULL;
+
+    return This->lpfnCI(pUnkOuter, riid, ppvObject);
+}
+
+static HRESULT WINAPI HLinkCF_fnLockServer(LPCLASSFACTORY iface, BOOL fLock)
+{
+    FIXME("%p %d\n", iface, fLock);
+    return E_NOTIMPL;
+}
+
+static const IClassFactoryVtbl hlcfvt =
+{
+    HLinkCF_fnQueryInterface,
+    HLinkCF_fnAddRef,
+    HLinkCF_fnRelease,
+    HLinkCF_fnCreateInstance,
+    HLinkCF_fnLockServer
+};
+
+static CFImpl HLink_cf = { &hlcfvt, &HLink_Constructor };
+static CFImpl HLinkBrowseContext_cf = { &hlcfvt, &HLinkBrowseContext_Constructor };
+
+/***********************************************************************
+ *             DllGetClassObject (HLINK.@)
+ */
+HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
+{
+    IClassFactory   *pcf = NULL;
+
+    TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv);
+
+    if (!ppv)
+        return E_INVALIDARG;
+    *ppv = NULL;
+
+    if (IsEqualIID(rclsid, &CLSID_StdHlink))
+        pcf = (IClassFactory*) &HLink_cf;
+    else if (IsEqualIID(rclsid, &CLSID_StdHlinkBrowseContext))
+        pcf = (IClassFactory*) &HLinkBrowseContext_cf;
+    else
+        return CLASS_E_CLASSNOTAVAILABLE;
+
+    return IClassFactory_QueryInterface(pcf, iid, ppv);
+}
+
+static HRESULT register_clsid(LPCGUID guid)
+{
+    static const WCHAR clsid[] =
+        {'C','L','S','I','D','\\',0};
+    static const WCHAR ips[] =
+        {'\\','I','n','p','r','o','c','S','e','r','v','e','r','3','2',0};
+    static const WCHAR hlink[] =
+        {'h','l','i','n','k','.','d','l','l',0};
+    static const WCHAR threading_model[] =
+        {'T','h','r','e','a','d','i','n','g','M','o','d','e','l',0};
+    static const WCHAR apartment[] =
+        {'A','p','a','r','t','m','e','n','t',0};
+    WCHAR path[80];
+    HKEY key = NULL;
+    LONG r;
+
+    lstrcpyW(path, clsid);
+    StringFromGUID2(guid, &path[6], 80);
+    lstrcatW(path, ips);
+    r = RegCreateKeyW(HKEY_CLASSES_ROOT, path, &key);
+    if (r != ERROR_SUCCESS)
+        return E_FAIL;
+
+    RegSetValueExW(key, NULL, 0, REG_SZ, (const BYTE *)hlink, sizeof hlink);
+    RegSetValueExW(key, threading_model, 0, REG_SZ, (const BYTE *)apartment, sizeof apartment);
+    RegCloseKey(key);
+
+    return S_OK;
+}
+
+HRESULT WINAPI DllRegisterServer(void)
+{
+    HRESULT r;
+
+    r = register_clsid(&CLSID_StdHlink);
+    if (SUCCEEDED(r))
+        r = register_clsid(&CLSID_StdHlinkBrowseContext);
+
+    return S_OK;
+}

Propchange: trunk/reactos/dll/win32/hlink/hlink_main.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/dll/win32/hlink/hlink_private.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/hlink/hlink_private.h?rev=31597&view=auto
==============================================================================
--- trunk/reactos/dll/win32/hlink/hlink_private.h (added)
+++ trunk/reactos/dll/win32/hlink/hlink_private.h Sat Jan  5 00:53:35 2008
@@ -1,0 +1,78 @@
+/*
+ * Copyright 2007 Jacek Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+
+#include "winerror.h"
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "ole2.h"
+#include "hlink.h"
+
+#include "wine/unicode.h"
+
+extern HRESULT WINAPI HLink_Constructor(IUnknown*,REFIID,void**);
+extern HRESULT WINAPI HLinkBrowseContext_Constructor(IUnknown*,REFIID,void**);
+
+static inline void *heap_alloc(size_t len)
+{
+    return HeapAlloc(GetProcessHeap(), 0, len);
+}
+
+static inline void *heap_alloc_zero(size_t len)
+{
+    return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
+}
+
+static inline BOOL heap_free(void *mem)
+{
+    return HeapFree(GetProcessHeap(), 0, mem);
+}
+
+static inline LPWSTR hlink_strdupW(LPCWSTR str)
+{
+    LPWSTR ret = NULL;
+
+    if(str) {
+        DWORD size;
+
+        size = (strlenW(str)+1)*sizeof(WCHAR);
+        ret = heap_alloc(size);
+        memcpy(ret, str, size);
+    }
+
+    return ret;
+}
+
+static inline LPWSTR hlink_co_strdupW(LPCWSTR str)
+{
+    LPWSTR ret = NULL;
+
+    if(str) {
+        DWORD size;
+
+        size = (strlenW(str)+1)*sizeof(WCHAR);
+        ret = CoTaskMemAlloc(size);
+        memcpy(ret, str, size);
+    }
+
+    return ret;
+}

Propchange: trunk/reactos/dll/win32/hlink/hlink_private.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: trunk/reactos/dll/win32/hlink/link.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/hlink/link.c?rev=31597&view=auto
==============================================================================
--- trunk/reactos/dll/win32/hlink/link.c (added)
+++ trunk/reactos/dll/win32/hlink/link.c Sat Jan  5 00:53:35 2008
@@ -1,0 +1,843 @@
+/*
+ * Implementation of hyperlinking (hlink.dll)
+ *
+ * Copyright 2005 Aric Stewart for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "hlink_private.h"
+
+#include "shellapi.h"
+#include "hlguids.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(hlink);
+
+#define HLINK_SAVE_MAGIC    0x00000002
+#define HLINK_SAVE_MONIKER_PRESENT      0x01
+#define HLINK_SAVE_MONIKER_IS_ABSOLUTE  0x02
+#define HLINK_SAVE_LOCATION_PRESENT     0x08
+#define HLINK_SAVE_FRIENDLY_PRESENT     0x10
+/* 0x20, 0x40 unknown */
+#define HLINK_SAVE_TARGET_FRAME_PRESENT 0x80
+/* known flags */
+#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)
+
+static const IHlinkVtbl              hlvt;
+static const IPersistStreamVtbl      psvt;
+static const IDataObjectVtbl         dovt;
+
+typedef struct
+{
+    const IHlinkVtbl    *lpVtbl;
+    LONG                ref;
+
+    const IPersistStreamVtbl    *lpPSVtbl;
+    const IDataObjectVtbl       *lpDOVtbl;
+
+    LPWSTR              FriendlyName;
+    LPWSTR              Location;
+    LPWSTR              Target;
+    LPWSTR              TargetFrameName;
+    IMoniker            *Moniker;
+    IHlinkSite          *Site;
+    DWORD               SiteData;
+    BOOL                absolute;
+} HlinkImpl;
+
+
+static inline HlinkImpl* HlinkImpl_from_IPersistStream( IPersistStream* iface)
+{
+    return (HlinkImpl*) ((CHAR*)iface - FIELD_OFFSET(HlinkImpl, lpPSVtbl));
+}
+
+static inline HlinkImpl* HlinkImpl_from_IDataObject( IDataObject* iface)
+{
+    return (HlinkImpl*) ((CHAR*)iface - FIELD_OFFSET(HlinkImpl, lpDOVtbl));
+}
+
+static inline void __GetMoniker(HlinkImpl* This, IMoniker** moniker)
+{
+    *moniker = NULL;
+    if (This->Moniker)
+    {
+        *moniker = This->Moniker;
+        if (*moniker)
+            IMoniker_AddRef(*moniker);
+    }
+    else if (This->Site)
+    {
+        IHlinkSite_GetMoniker(This->Site, This->SiteData,
+                OLEGETMONIKER_FORCEASSIGN, OLEWHICHMK_CONTAINER,
+                (LPVOID)moniker);
+    }
+}
+
+HRESULT WINAPI HLink_Constructor(IUnknown *pUnkOuter, REFIID riid,
+        LPVOID *ppv)
+{
+    HlinkImpl * hl;
+
+    TRACE("unkOut=%p riid=%s\n", pUnkOuter, debugstr_guid(riid));
+    *ppv = NULL;
+
+    if (pUnkOuter)
+        return CLASS_E_NOAGGREGATION;
+
+    hl = heap_alloc_zero(sizeof(HlinkImpl));
+    if (!hl)
+        return E_OUTOFMEMORY;
+
+    hl->ref = 1;
+    hl->lpVtbl = &hlvt;
+    hl->lpPSVtbl = &psvt;
+    hl->lpDOVtbl = &dovt;
+
+    *ppv = hl;
+    return S_OK;
+}
+
+static HRESULT WINAPI IHlink_fnQueryInterface(IHlink* iface, REFIID riid,
+        LPVOID *ppvObj)
+{
+    HlinkImpl  *This = (HlinkImpl*)iface;
+
+    TRACE ("(%p)->(%s,%p)\n", This, debugstr_guid (riid), ppvObj);
+
+    *ppvObj = NULL;
+
+    if (IsEqualIID(riid, &IID_IUnknown) || (IsEqualIID(riid, &IID_IHlink)))
+        *ppvObj = This;
+    else if (IsEqualIID(riid, &IID_IPersistStream))
+        *ppvObj = (LPVOID*)&(This->lpPSVtbl);
+    else if (IsEqualIID(riid, &IID_IDataObject))
+        *ppvObj = (LPVOID*)&(This->lpDOVtbl);
+
+    if (*ppvObj)
+    {
+        IUnknown_AddRef((IUnknown*)(*ppvObj));
+        return S_OK;
+    }
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI IHlink_fnAddRef (IHlink* iface)
+{
+    HlinkImpl  *This = (HlinkImpl*)iface;
+    ULONG refCount = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p)->(count=%u)\n", This, refCount - 1);
+
+    return refCount;
+}
+
+static ULONG WINAPI IHlink_fnRelease (IHlink* iface)
+{
+    HlinkImpl  *This = (HlinkImpl*)iface;
+    ULONG refCount = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p)->(count=%u)\n", This, refCount + 1);
+    if (refCount)
+        return refCount;
+
+    TRACE("-- destroying IHlink (%p)\n", This);
+    heap_free(This->FriendlyName);
+    heap_free(This->Target);
+    heap_free(This->TargetFrameName);
+    heap_free(This->Location);
+    if (This->Moniker)
+        IMoniker_Release(This->Moniker);
+    if (This->Site)
+        IHlinkSite_Release(This->Site);
+    heap_free(This);
+    return 0;
+}
+
+static HRESULT WINAPI IHlink_fnSetHlinkSite( IHlink* iface,
+        IHlinkSite* pihlSite, DWORD dwSiteData)
+{
+    HlinkImpl  *This = (HlinkImpl*)iface;
+
+    TRACE("(%p)->(%p %i)\n", This, pihlSite, dwSiteData);
+
+    if (This->Site)
+        IHlinkSite_Release(This->Site);
+
+    This->Site = pihlSite;
+    if (This->Site)
+        IHlinkSite_AddRef(This->Site);
+
+    This->SiteData = dwSiteData;
+
+    return S_OK;
+}
+
+static HRESULT WINAPI IHlink_fnGetHlinkSite( IHlink* iface,
+        IHlinkSite** ppihlSite, DWORD *pdwSiteData)
+{
+    HlinkImpl  *This = (HlinkImpl*)iface;
+
+    TRACE("(%p)->(%p %p)\n", This, ppihlSite, pdwSiteData);
+
+    *ppihlSite = This->Site;
+    *pdwSiteData = This->SiteData;
+
+    if (This->Site)
+        IHlinkSite_AddRef(This->Site);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI IHlink_fnSetMonikerReference( IHlink* iface,
+        DWORD rfHLSETF, IMoniker *pmkTarget, LPCWSTR pwzLocation)
+{
+    HlinkImpl  *This = (HlinkImpl*)iface;
+
+    FIXME("(%p)->(%i %p %s)\n", This, rfHLSETF, pmkTarget,
+            debugstr_w(pwzLocation));
+
+    if (This->Moniker)
+        IMoniker_Release(This->Moniker);
+
+    This->Moniker = pmkTarget;
+    if (This->Moniker)
+    {
+        LPOLESTR display_name;
+        IMoniker_AddRef(This->Moniker);
+        IMoniker_GetDisplayName(This->Moniker, NULL, NULL, &display_name);
+        This->absolute = display_name && strchrW(display_name, ':');
+        CoTaskMemFree(display_name);
+    }
+
+    heap_free(This->Location);
+    This->Location = hlink_strdupW( pwzLocation );
+
+    return S_OK;
+}
+
+static HRESULT WINAPI IHlink_fnSetStringReference(IHlink* iface,
+        DWORD grfHLSETF, LPCWSTR pwzTarget, LPCWSTR pwzLocation)
+{
+    HlinkImpl  *This = (HlinkImpl*)iface;
+
+    TRACE("(%p)->(%i %s %s)\n", This, grfHLSETF, debugstr_w(pwzTarget),
+            debugstr_w(pwzLocation));
+
+    if (grfHLSETF & HLINKSETF_TARGET)
+    {
+        heap_free(This->Target);
+        This->Target = hlink_strdupW( pwzTarget );
+    }
+    if (grfHLSETF & HLINKSETF_LOCATION)
+    {
+        heap_free(This->Location);
+        This->Location = hlink_strdupW( pwzLocation );
+    }
+
+    return S_OK;
+}
+
+static HRESULT WINAPI IHlink_fnGetMonikerReference(IHlink* iface,
+        DWORD dwWhichRef, IMoniker **ppimkTarget, LPWSTR *ppwzLocation)
+{
+    HlinkImpl  *This = (HlinkImpl*)iface;
+
+    TRACE("(%p) -> (%i %p %p)\n", This, dwWhichRef, ppimkTarget,
+            ppwzLocation);
+
+    if(ppimkTarget)
+        __GetMoniker(This, ppimkTarget);
+
+    if (ppwzLocation)
+        IHlink_GetStringReference(iface, dwWhichRef, NULL, ppwzLocation);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI IHlink_fnGetStringReference (IHlink* iface,
+        DWORD dwWhichRef, LPWSTR *ppwzTarget, LPWSTR *ppwzLocation)
+{
+    HlinkImpl  *This = (HlinkImpl*)iface;
+
+    FIXME("(%p) -> (%i %p %p)\n", This, dwWhichRef, ppwzTarget, ppwzLocation);
+
+    if (ppwzTarget)
+    {
+        *ppwzTarget = hlink_co_strdupW( This->Target );
+
+        if (!This->Target)
+        {
+            IMoniker* mon;
+            __GetMoniker(This, &mon);
+            if (mon)
+            {
+                IBindCtx *pbc;
+
+                CreateBindCtx( 0, &pbc);
+                IMoniker_GetDisplayName(mon, pbc, NULL, ppwzTarget);
+                IBindCtx_Release(pbc);
+                IMoniker_Release(mon);
+            }
+            else
+                FIXME("Unhandled case, no set Target and no moniker\n");
+        }
+    }
+    if (ppwzLocation)
+        *ppwzLocation = hlink_co_strdupW( This->Location );
+
+    TRACE("(Target: %s Location: %s)\n",
+            (ppwzTarget)?debugstr_w(*ppwzTarget):"<NULL>",
+            (ppwzLocation)?debugstr_w(*ppwzLocation):"<NULL>");
+
+    return S_OK;
+}
+
+static HRESULT WINAPI IHlink_fnSetFriendlyName (IHlink *iface,
+        LPCWSTR pwzFriendlyName)
+{
+    HlinkImpl  *This = (HlinkImpl*)iface;
+
+    TRACE("(%p) -> (%s)\n", This, debugstr_w(pwzFriendlyName));
+
+    heap_free(This->FriendlyName);
+    This->FriendlyName = hlink_strdupW( pwzFriendlyName );
+
+    return S_OK;
+}
+
+static HRESULT WINAPI IHlink_fnGetFriendlyName (IHlink* iface,
+        DWORD grfHLFNAMEF, LPWSTR* ppwzFriendlyName)
+{
+    HlinkImpl  *This = (HlinkImpl*)iface;
+
+    TRACE("(%p) -> (%i %p)\n", This, grfHLFNAMEF, ppwzFriendlyName);
+
+    /* FIXME: Only using explicitly set and cached friendly names */
+
+    if (This->FriendlyName)
+        *ppwzFriendlyName = hlink_co_strdupW( This->FriendlyName );
+    else
+    {
+        IMoniker *moniker;
+        __GetMoniker(This, &moniker);
+        if (moniker)
+        {
+            IBindCtx *bcxt;
+            CreateBindCtx(0, &bcxt);
+
+            IMoniker_GetDisplayName(moniker, bcxt, NULL, ppwzFriendlyName);
+            IBindCtx_Release(bcxt);
+            IMoniker_Release(moniker);
+        }
+        else
+            *ppwzFriendlyName = NULL;
+    }
+
+    return S_OK;
+}
+
+static HRESULT WINAPI IHlink_fnSetTargetFrameName(IHlink* iface,
+        LPCWSTR pwzTargetFramename)
+{
+    HlinkImpl  *This = (HlinkImpl*)iface;
+    TRACE("(%p)->(%s)\n", This, debugstr_w(pwzTargetFramename));
+
+    heap_free(This->TargetFrameName);
+    This->TargetFrameName = hlink_strdupW( pwzTargetFramename );
+
+    return S_OK;
+}
+
+static HRESULT WINAPI IHlink_fnGetTargetFrameName(IHlink* iface,
+        LPWSTR *ppwzTargetFrameName)
+{
+    HlinkImpl  *This = (HlinkImpl*)iface;
+
+    TRACE("(%p)->(%p)\n", This, ppwzTargetFrameName);
+    *ppwzTargetFrameName = hlink_co_strdupW( This->TargetFrameName );
+
+    return S_OK;
+}
+
+static HRESULT WINAPI IHlink_fnGetMiscStatus(IHlink* iface, DWORD* pdwStatus)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IHlink_fnNavigate(IHlink* iface, DWORD grfHLNF, LPBC pbc,
+        IBindStatusCallback *pbsc, IHlinkBrowseContext *phbc)
+{
+    HlinkImpl  *This = (HlinkImpl*)iface;
+    IMoniker *mon = NULL;
+
+    FIXME("Semi-Stub:(%p)->(%i %p %p %p)\n", This, grfHLNF, pbc, pbsc, phbc);
+
+    if (This->Site)
+        IHlinkSite_ReadyToNavigate(This->Site, This->SiteData, 0);
+
+    __GetMoniker(This, &mon);
+    TRACE("Moniker %p\n", mon);
+
+    if (mon)
+    {
+        IBindCtx *bcxt;
+        IHlinkTarget *target = NULL;
+        HRESULT r = S_OK;
+
+        CreateBindCtx(0, &bcxt);
+
+        RegisterBindStatusCallback(bcxt, pbsc, NULL, 0);
+
+        r = IMoniker_BindToObject(mon, bcxt, NULL, &IID_IHlinkTarget,
+                (LPVOID*)&target);
+        TRACE("IHlinkTarget returned 0x%x\n", r);
+        if (r == S_OK)
+        {
+            IHlinkTarget_SetBrowseContext(target, phbc);
+            IHlinkTarget_Navigate(target, grfHLNF, This->Location);
+            IHlinkTarget_Release(target);
+        }
+        else
+        {
+            static const WCHAR szOpen[] = {'o','p','e','n',0};
+            LPWSTR target = NULL;
+
+            r = IHlink_GetStringReference(iface, HLINKGETREF_DEFAULT, &target, NULL);
+            if (SUCCEEDED(r) && target)
+            {
+                ShellExecuteW(NULL, szOpen, target, NULL, NULL, SW_SHOW);
+                CoTaskMemFree(target);
+            }
+        }
+
+        RevokeBindStatusCallback(bcxt, pbsc);
+
+        IBindCtx_Release(bcxt);
+        IMoniker_Release(mon);
+    }
+
+    if (This->Site)
+        IHlinkSite_OnNavigationComplete(This->Site, This->SiteData, 0, 0, NULL);
+
+    TRACE("Finished Navigation\n");
+    return S_OK;
+}
+
+static HRESULT WINAPI IHlink_fnSetAdditonalParams(IHlink* iface,
+        LPCWSTR pwzAdditionalParams)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IHlink_fnGetAdditionalParams(IHlink* iface,
+        LPWSTR* ppwzAdditionalParams)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static const IHlinkVtbl hlvt =
+{
+    IHlink_fnQueryInterface,
+    IHlink_fnAddRef,
+    IHlink_fnRelease,
+    IHlink_fnSetHlinkSite,
+    IHlink_fnGetHlinkSite,
+    IHlink_fnSetMonikerReference,
+    IHlink_fnGetMonikerReference,
+    IHlink_fnSetStringReference,
+    IHlink_fnGetStringReference,
+    IHlink_fnSetFriendlyName,
+    IHlink_fnGetFriendlyName,
+    IHlink_fnSetTargetFrameName,
+    IHlink_fnGetTargetFrameName,
+    IHlink_fnGetMiscStatus,
+    IHlink_fnNavigate,
+    IHlink_fnSetAdditonalParams,
+    IHlink_fnGetAdditionalParams
+};
+
+static HRESULT WINAPI IDataObject_fnQueryInterface(IDataObject* iface,
+        REFIID riid, LPVOID *ppvObj)
+{
+    HlinkImpl *This = HlinkImpl_from_IDataObject(iface);
+    TRACE("%p\n", This);
+    return IHlink_QueryInterface((IHlink*)This, riid, ppvObj);
+}
+
+static ULONG WINAPI IDataObject_fnAddRef (IDataObject* iface)
+{
+    HlinkImpl *This = HlinkImpl_from_IDataObject(iface);
+    TRACE("%p\n", This);
+    return IHlink_AddRef((IHlink*)This);
+}
+
+static ULONG WINAPI IDataObject_fnRelease (IDataObject* iface)
+{
+    HlinkImpl *This = HlinkImpl_from_IDataObject(iface);
+    TRACE("%p\n", This);
+    return IHlink_Release((IHlink*)This);
+}
+
+static HRESULT WINAPI IDataObject_fnGetData(IDataObject* iface,
+        FORMATETC* pformatetcIn, STGMEDIUM* pmedium)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IDataObject_fnGetDataHere(IDataObject* iface,
+        FORMATETC* pformatetc, STGMEDIUM* pmedium)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IDataObject_fnQueryGetData(IDataObject* iface,
+        FORMATETC* pformatetc)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IDataObject_fnGetConicalFormatEtc(IDataObject* iface,
+        FORMATETC* pformatetcIn, FORMATETC* pformatetcOut)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IDataObject_fnSetData(IDataObject* iface,
+        FORMATETC* pformatetc, STGMEDIUM* pmedium, BOOL fRelease)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IDataObject_fnEnumFormatEtc(IDataObject* iface,
+        DWORD dwDirection, IEnumFORMATETC** ppenumFormatEtc)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IDataObject_fnDAdvise(IDataObject* iface,
+        FORMATETC* pformatetc, DWORD advf, IAdviseSink* pAdvSink,
+        DWORD* pdwConnection)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IDataObject_fnDUnadvise(IDataObject* iface,
+        DWORD dwConnection)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IDataObject_fnEnumDAdvise(IDataObject* iface,
+        IEnumSTATDATA** ppenumAdvise)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static const IDataObjectVtbl dovt =
+{
+    IDataObject_fnQueryInterface,
+    IDataObject_fnAddRef,
+    IDataObject_fnRelease,
+    IDataObject_fnGetData,
+    IDataObject_fnGetDataHere,
+    IDataObject_fnQueryGetData,
+    IDataObject_fnGetConicalFormatEtc,
+    IDataObject_fnSetData,
+    IDataObject_fnEnumFormatEtc,
+    IDataObject_fnDAdvise,
+    IDataObject_fnDUnadvise,
+    IDataObject_fnEnumDAdvise
+};
+
+static HRESULT WINAPI IPersistStream_fnQueryInterface(IPersistStream* iface,
+        REFIID riid, LPVOID *ppvObj)
+{
+    HlinkImpl *This = HlinkImpl_from_IPersistStream(iface);
+    TRACE("(%p)\n", This);
+    return IHlink_QueryInterface((IHlink*)This, riid, ppvObj);
+}
+
+static ULONG WINAPI IPersistStream_fnAddRef (IPersistStream* iface)
+{
+    HlinkImpl *This = HlinkImpl_from_IPersistStream(iface);
+    TRACE("(%p)\n", This);
+    return IHlink_AddRef((IHlink*)This);
+}
+
+static ULONG WINAPI IPersistStream_fnRelease (IPersistStream* iface)
+{
+    HlinkImpl *This = HlinkImpl_from_IPersistStream(iface);
+    TRACE("(%p)\n", This);
+    return IHlink_Release((IHlink*)This);
+}
+
+static HRESULT WINAPI IPersistStream_fnGetClassID(IPersistStream* iface,
+        CLSID* pClassID)
+{
+    HlinkImpl *This = HlinkImpl_from_IPersistStream(iface);
+    TRACE("(%p)\n", This);
+    memcpy(pClassID, &CLSID_StdHlink, sizeof(CLSID));
+    return S_OK;
+}
+
+static HRESULT WINAPI IPersistStream_fnIsDirty(IPersistStream* iface)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT write_hlink_string(IStream *pStm, LPCWSTR str)
+{
+    DWORD len;
+    HRESULT hr;
+
+    TRACE("(%p, %s)\n", pStm, debugstr_w(str));
+
+    len = strlenW(str) + 1;
+
+    hr = IStream_Write(pStm, &len, sizeof(len), NULL);
+    if (FAILED(hr)) return hr;
+
+    hr = IStream_Write(pStm, str, len * sizeof(WCHAR), NULL);
+    if (FAILED(hr)) return hr;
+
+    return S_OK;
+}
+
+static inline ULONG size_hlink_string(LPCWSTR str)
+{
+    return sizeof(DWORD) + (strlenW(str) + 1) * sizeof(WCHAR);
+}
+
+static HRESULT read_hlink_string(IStream *pStm, LPWSTR *out_str)
+{
+    LPWSTR str;
+    DWORD len;
+    ULONG read;
+    HRESULT hr;
+
+    hr = IStream_Read(pStm, &len, sizeof(len), &read);
+    if (FAILED(hr)) return hr;
+    if (read != sizeof(len)) return STG_E_READFAULT;
+
+    TRACE("read len %d\n", len);
+
+    str = heap_alloc(len * sizeof(WCHAR));
+    if (!str) return E_OUTOFMEMORY;
+
+    hr = IStream_Read(pStm, str, len * sizeof(WCHAR), &read);
+    if (FAILED(hr))
+    {
+        heap_free(str);
+        return hr;
+    }
+    if (read != len * sizeof(WCHAR))
+    {
+        heap_free(str);
+        return STG_E_READFAULT;
+    }
+    TRACE("read string %s\n", debugstr_w(str));
+
+    *out_str = str;
+    return S_OK;
+}
+
+static HRESULT WINAPI IPersistStream_fnLoad(IPersistStream* iface,
+        IStream* pStm)
+{
+    HRESULT r;
+    DWORD hdr[2];
+    DWORD read;
+    HlinkImpl *This = HlinkImpl_from_IPersistStream(iface);
+
+    r = IStream_Read(pStm, &hdr, sizeof(hdr), &read);
+    if (read != sizeof(hdr) || (hdr[0] != HLINK_SAVE_MAGIC))
+    {
+        r = E_FAIL;
+        goto end;
+    }
+    if (hdr[1] & ~HLINK_SAVE_ALL)
+        FIXME("unknown flag(s) 0x%x\n", hdr[1] & ~HLINK_SAVE_ALL);
+
+    if (hdr[1] & HLINK_SAVE_TARGET_FRAME_PRESENT)
+    {
+        TRACE("loading target frame name\n");
+        r = read_hlink_string(pStm, &This->TargetFrameName);
+        if (FAILED(r)) goto end;
+    }
+
+    if (hdr[1] & HLINK_SAVE_FRIENDLY_PRESENT)
+    {
+        TRACE("loading target friendly name\n");
+        if (!(hdr[1] & 0x4))
+            FIXME("0x4 flag not present with friendly name flag - not sure what this means\n");
+        r = read_hlink_string(pStm, &This->FriendlyName);
+        if (FAILED(r)) goto end;
+    }
+
+    if (hdr[1] & HLINK_SAVE_MONIKER_PRESENT)
+    {
+        TRACE("loading moniker\n");
+        r = OleLoadFromStream(pStm, &IID_IMoniker, (LPVOID*)&(This->Moniker));
+        if (FAILED(r))
+            goto end;
+        This->absolute = hdr[1] & HLINK_SAVE_MONIKER_IS_ABSOLUTE ? TRUE : FALSE;
+    }
+
+    if (hdr[1] & HLINK_SAVE_LOCATION_PRESENT)
+    {
+        TRACE("loading location\n");
+        r = read_hlink_string(pStm, &This->Location);
+        if (FAILED(r)) goto end;
+    }
+
+end:
+    TRACE("Load Result 0x%x (%p)\n", r, This->Moniker);
+
+    return r;
+}
+
+static HRESULT WINAPI IPersistStream_fnSave(IPersistStream* iface,
+        IStream* pStm, BOOL fClearDirty)
+{
+    HRESULT r = E_FAIL;
+    HlinkImpl *This = HlinkImpl_from_IPersistStream(iface);
+    DWORD hdr[2];
+    IMoniker *moniker;
+
+    TRACE("(%p) Moniker(%p)\n", This, This->Moniker);
+
+    __GetMoniker(This, &moniker);
+
+    hdr[0] = HLINK_SAVE_MAGIC;
+    hdr[1] = 0;
+
+    if (moniker)
+        hdr[1] |= HLINK_SAVE_MONIKER_PRESENT;
+    if (This->absolute)
+        hdr[1] |= HLINK_SAVE_MONIKER_IS_ABSOLUTE;
+    if (This->Location)
+        hdr[1] |= HLINK_SAVE_LOCATION_PRESENT;
+    if (This->FriendlyName)
+        hdr[1] |= HLINK_SAVE_FRIENDLY_PRESENT | 4 /* FIXME */;
+    if (This->TargetFrameName)
+        hdr[1] |= HLINK_SAVE_TARGET_FRAME_PRESENT;
+
+    IStream_Write(pStm, &hdr, sizeof(hdr), NULL);
+
+    if (This->TargetFrameName)
+    {
+        r = write_hlink_string(pStm, This->TargetFrameName);
+        if (FAILED(r)) goto end;
+    }
+
+    if (This->FriendlyName)
+    {
+        r = write_hlink_string(pStm, This->FriendlyName);
+        if (FAILED(r)) goto end;
+    }
+
+    if (moniker)
+    {
+        IPersistStream* monstream;
+
+        monstream = NULL;
+        IMoniker_QueryInterface(moniker, &IID_IPersistStream,
+                (LPVOID*)&monstream);
+        if (monstream)
+        {
+            r = OleSaveToStream(monstream, pStm);
+            IPersistStream_Release(monstream);
+        }
+        if (FAILED(r)) goto end;
+    }
+
+    if (This->Location)
+    {
+        r = write_hlink_string(pStm, This->Location);
+        if (FAILED(r)) goto end;
+    }
+
+end:
+    if (moniker) IMoniker_Release(moniker);
+    TRACE("Save Result 0x%x\n", r);
+
+    return r;
+}
+
+static HRESULT WINAPI IPersistStream_fnGetSizeMax(IPersistStream* iface,
+        ULARGE_INTEGER* pcbSize)
+{
+    HRESULT r = E_FAIL;
+    HlinkImpl *This = HlinkImpl_from_IPersistStream(iface);
+    IMoniker *moniker;
+
+    TRACE("(%p) Moniker(%p)\n", This, This->Moniker);
+
+    pcbSize->QuadPart = sizeof(DWORD)*2;
+
+    if (This->TargetFrameName)
+        pcbSize->QuadPart += size_hlink_string(This->TargetFrameName);
+
+    if (This->FriendlyName)
+        pcbSize->QuadPart += size_hlink_string(This->FriendlyName);
+
+    __GetMoniker(This, &moniker);
+    if (moniker)
+    {
+        IPersistStream* monstream = NULL;
+        IMoniker_QueryInterface(moniker, &IID_IPersistStream,
+                (LPVOID*)&monstream);
+        if (monstream)
+        {
+            ULARGE_INTEGER mon_size;
+            r = IPersistStream_GetSizeMax(monstream, &mon_size);
+            pcbSize->QuadPart += mon_size.QuadPart;
+            IPersistStream_Release(monstream);
+        }
+        IMoniker_Release(moniker);
+    }
+
+    if (This->Location)
+        pcbSize->QuadPart += size_hlink_string(This->Location);
+
+    return r;
+}
+
+static const IPersistStreamVtbl psvt =
+{
+    IPersistStream_fnQueryInterface,
+    IPersistStream_fnAddRef,
+    IPersistStream_fnRelease,
+    IPersistStream_fnGetClassID,
+    IPersistStream_fnIsDirty,
+    IPersistStream_fnLoad,
+    IPersistStream_fnSave,
+    IPersistStream_fnGetSizeMax,
+};

Propchange: trunk/reactos/dll/win32/hlink/link.c
------------------------------------------------------------------------------
    svn:eol-style = native




More information about the Ros-diffs mailing list