[PATCH 6/6] hlink: Improve the loading of hlinks.

Robert Shearman rob at codeweavers.com
Wed May 23 13:07:29 CDT 2007


---
  dlls/hlink/link.c |  114 
++++++++++++++++++++++++++++++++++++++++++++---------
  1 files changed, 94 insertions(+), 20 deletions(-)
-------------- next part --------------
diff --git a/dlls/hlink/link.c b/dlls/hlink/link.c
index cda5fef..58ce370 100644
--- a/dlls/hlink/link.c
+++ b/dlls/hlink/link.c
@@ -46,6 +46,8 @@ #define HLINK_SAVE_LOCATION_PRESENT     
 #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_fnI
     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(IStrea
     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(LP
     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_fnS
             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_fnS
     }
 
 end:
+    if (moniker) IMoniker_Release(moniker);
     TRACE("Save Result 0x%x\n", r);
 
     return r;


More information about the wine-patches mailing list