Rob Shearman : hlink: Improve the loading of hlinks.

Alexandre Julliard julliard at wine.codeweavers.com
Fri May 25 14:43:23 CDT 2007


Module: wine
Branch: master
Commit: 7b2e7cb81a24abee2e802734f36f3c9a1ad3e97f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=7b2e7cb81a24abee2e802734f36f3c9a1ad3e97f

Author: Rob Shearman <rob at codeweavers.com>
Date:   Wed May 23 19:07:29 2007 +0100

hlink: Improve the loading of hlinks.

---

 dlls/hlink/link.c |  114 +++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 94 insertions(+), 20 deletions(-)

diff --git a/dlls/hlink/link.c b/dlls/hlink/link.c
index 9601a33..c450951 100644
--- a/dlls/hlink/link.c
+++ b/dlls/hlink/link.c
@@ -46,6 +46,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(hlink);
 #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;
@@ -650,23 +652,6 @@ static HRESULT WINAPI IPersistStream_fnIsDirty(IPersistStream* iface)
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI IPersistStream_fnLoad(IPersistStream* iface,
-        IStream* pStm)
-{
-    HRESULT r = E_NOTIMPL;
-    DWORD hdr[2];
-    DWORD read;
-    HlinkImpl *This = HlinkImpl_from_IPersistStream(iface);
-
-    IStream_Read(pStm, &hdr, sizeof(hdr), &read);
-    /* FIXME: unknown header values */
-
-    r = OleLoadFromStream(pStm, &IID_IMoniker, (LPVOID*)&(This->Moniker));
-    TRACE("Load Result 0x%x (%p)\n", r, This->Moniker);
-
-    return r;
-}
-
 static HRESULT write_hlink_string(IStream *pStm, LPCWSTR str)
 {
     DWORD len;
@@ -677,10 +662,10 @@ static HRESULT write_hlink_string(IStream *pStm, LPCWSTR str)
     len = strlenW(str) + 1;
 
     hr = IStream_Write(pStm, &len, sizeof(len), NULL);
-    /* FIXME: error checking */
+    if (FAILED(hr)) return hr;
 
     hr = IStream_Write(pStm, str, len * sizeof(WCHAR), NULL);
-    /* FIXME: error checking */
+    if (FAILED(hr)) return hr;
 
     return S_OK;
 }
@@ -690,6 +675,94 @@ 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 = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+    if (!str) return E_OUTOFMEMORY;
+
+    hr = IStream_Read(pStm, str, len * sizeof(WCHAR), &read);
+    if (FAILED(hr))
+    {
+        HeapFree(GetProcessHeap(), 0, str);
+        return hr;
+    }
+    if (read != len * sizeof(WCHAR))
+    {
+        HeapFree(GetProcessHeap(), 0, 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)
 {
@@ -742,7 +815,7 @@ static HRESULT WINAPI IPersistStream_fnSave(IPersistStream* iface,
             r = OleSaveToStream(monstream, pStm);
             IPersistStream_Release(monstream);
         }
-        IMoniker_Release(moniker);
+        if (FAILED(r)) goto end;
     }
 
     if (This->Location)
@@ -752,6 +825,7 @@ static HRESULT WINAPI IPersistStream_fnSave(IPersistStream* iface,
     }
 
 end:
+    if (moniker) IMoniker_Release(moniker);
     TRACE("Save Result 0x%x\n", r);
 
     return r;




More information about the wine-cvs mailing list