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…
==============================================================================
--- 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?…
==============================================================================
--- 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.rbui…
==============================================================================
--- 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…
==============================================================================
--- 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…
==============================================================================
--- 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_priv…
==============================================================================
--- 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…
==============================================================================
--- 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