Nikolay Sivov : opcservices: Keep relationship id.

Alexandre Julliard julliard at winehq.org
Wed Sep 5 16:15:27 CDT 2018


Module: wine
Branch: master
Commit: 2ff3f6892bfcce0b08fe161a09d5e4ddaa210d86
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=2ff3f6892bfcce0b08fe161a09d5e4ddaa210d86

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Wed Sep  5 08:37:25 2018 +0300

opcservices: Keep relationship id.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/opcservices/Makefile.in         |  2 +-
 dlls/opcservices/package.c           | 44 ++++++++++++++++++++++---
 dlls/opcservices/tests/Makefile.in   |  2 +-
 dlls/opcservices/tests/opcservices.c | 64 ++++++++++++++++++++++++++++++++++++
 include/opcbase.idl                  |  2 ++
 include/winerror.h                   |  1 +
 6 files changed, 108 insertions(+), 7 deletions(-)

diff --git a/dlls/opcservices/Makefile.in b/dlls/opcservices/Makefile.in
index 47fbbe4..3e9907f 100644
--- a/dlls/opcservices/Makefile.in
+++ b/dlls/opcservices/Makefile.in
@@ -1,5 +1,5 @@
 MODULE  = opcservices.dll
-IMPORTS = uuid ole32
+IMPORTS = uuid ole32 advapi32
 
 C_SRCS = \
 	factory.c \
diff --git a/dlls/opcservices/package.c b/dlls/opcservices/package.c
index e671685..1970fc4 100644
--- a/dlls/opcservices/package.c
+++ b/dlls/opcservices/package.c
@@ -21,6 +21,7 @@
 #include <stdarg.h>
 #include "windef.h"
 #include "winbase.h"
+#include "ntsecapi.h"
 
 #include "wine/debug.h"
 #include "wine/unicode.h"
@@ -63,6 +64,8 @@ struct opc_relationship
 {
     IOpcRelationship IOpcRelationship_iface;
     LONG refcount;
+
+    WCHAR *id;
 };
 
 struct opc_relationship_set
@@ -392,16 +395,22 @@ static ULONG WINAPI opc_relationship_Release(IOpcRelationship *iface)
     TRACE("%p decreasing refcount to %u.\n", iface, refcount);
 
     if (!refcount)
+    {
+        CoTaskMemFree(relationship->id);
         heap_free(relationship);
+    }
 
     return refcount;
 }
 
 static HRESULT WINAPI opc_relationship_GetId(IOpcRelationship *iface, WCHAR **id)
 {
-    FIXME("iface %p, id %p stub!\n", iface, id);
+    struct opc_relationship *relationship = impl_from_IOpcRelationship(iface);
 
-    return E_NOTIMPL;
+    TRACE("iface %p, id %p.\n", iface, id);
+
+    *id = opc_strdupW(relationship->id);
+    return *id ? S_OK : E_OUTOFMEMORY;
 }
 
 static HRESULT WINAPI opc_relationship_GetRelationshipType(IOpcRelationship *iface, WCHAR **type)
@@ -444,7 +453,7 @@ static const IOpcRelationshipVtbl opc_relationship_vtbl =
     opc_relationship_GetTargetMode,
 };
 
-static HRESULT opc_relationship_create(struct opc_relationship_set *set, IOpcRelationship **out)
+static HRESULT opc_relationship_create(struct opc_relationship_set *set, const WCHAR *id, IOpcRelationship **out)
 {
     struct opc_relationship *relationship;
 
@@ -457,6 +466,28 @@ static HRESULT opc_relationship_create(struct opc_relationship_set *set, IOpcRel
     relationship->IOpcRelationship_iface.lpVtbl = &opc_relationship_vtbl;
     relationship->refcount = 1;
 
+    /* FIXME: test that id is unique */
+    if (id)
+        relationship->id = opc_strdupW(id);
+    else
+    {
+        relationship->id = CoTaskMemAlloc(10 * sizeof(WCHAR));
+        if (relationship->id)
+        {
+            static const WCHAR fmtW[] = {'R','%','0','8','X',0};
+            DWORD generated;
+
+            RtlGenRandom(&generated, sizeof(generated));
+            sprintfW(relationship->id, fmtW, generated);
+        }
+    }
+
+    if (!relationship->id)
+    {
+        heap_free(relationship);
+        return E_OUTOFMEMORY;
+    }
+
     set->relationships[set->count++] = relationship;
     IOpcRelationship_AddRef(&relationship->IOpcRelationship_iface);
 
@@ -524,10 +555,13 @@ static HRESULT WINAPI opc_relationship_set_CreateRelationship(IOpcRelationshipSe
 {
     struct opc_relationship_set *relationship_set = impl_from_IOpcRelationshipSet(iface);
 
-    FIXME("iface %p, id %s, type %s, target_uri %p, target_mode %d, relationship %p stub!\n", iface, debugstr_w(id),
+    TRACE("iface %p, id %s, type %s, target_uri %p, target_mode %d, relationship %p.\n", iface, debugstr_w(id),
             debugstr_w(type), target_uri, target_mode, relationship);
 
-    return opc_relationship_create(relationship_set, relationship);
+    if (!type || !target_uri)
+        return E_POINTER;
+
+    return opc_relationship_create(relationship_set, id, relationship);
 }
 
 static HRESULT WINAPI opc_relationship_set_DeleteRelationship(IOpcRelationshipSet *iface, const WCHAR *id)
diff --git a/dlls/opcservices/tests/Makefile.in b/dlls/opcservices/tests/Makefile.in
index 7c0963c..202bf87 100644
--- a/dlls/opcservices/tests/Makefile.in
+++ b/dlls/opcservices/tests/Makefile.in
@@ -1,5 +1,5 @@
 TESTDLL = opcservices.dll
-IMPORTS = ole32
+IMPORTS = ole32 urlmon
 
 C_SRCS = \
 	opcservices.c
diff --git a/dlls/opcservices/tests/opcservices.c b/dlls/opcservices/tests/opcservices.c
index 5dc0d8c..8232a7e 100644
--- a/dlls/opcservices/tests/opcservices.c
+++ b/dlls/opcservices/tests/opcservices.c
@@ -24,6 +24,7 @@
 #include "windows.h"
 #include "initguid.h"
 #include "msopc.h"
+#include "urlmon.h"
 
 #include "wine/test.h"
 
@@ -204,6 +205,68 @@ static void test_file_stream(void)
     DeleteFileW(pathW);
 }
 
+static void test_relationship_id(void)
+{
+    static const WCHAR absoluteW[] = {'f','i','l','e',':','/','/','h','o','s','t','/','f','i','l','e','.','t','x','t',0};
+    static const WCHAR targetW[] = {'t','a','r','g','e','t',0};
+    static const WCHAR typeW[] = {'t','y','p','e',0};
+    IUri *target_uri, *target_uri2;
+    IOpcRelationshipSet *rels;
+    IOpcRelationship *rel;
+    IOpcFactory *factory;
+    IOpcPackage *package;
+    HRESULT hr;
+    WCHAR *id;
+
+    factory = create_factory();
+
+    hr = IOpcFactory_CreatePackage(factory, &package);
+    ok(SUCCEEDED(hr) || broken(hr == E_NOTIMPL) /* Vista */, "Failed to create a package, hr %#x.\n", hr);
+    if (FAILED(hr))
+        return;
+
+    hr = CreateUri(targetW, Uri_CREATE_ALLOW_RELATIVE, 0, &target_uri);
+    ok(SUCCEEDED(hr), "Failed to create target uri, hr %#x.\n", hr);
+
+    hr = CreateUri(absoluteW, 0, 0, &target_uri2);
+    ok(SUCCEEDED(hr), "Failed to create target uri, hr %#x.\n", hr);
+
+    hr = IOpcPackage_GetRelationshipSet(package, &rels);
+    ok(SUCCEEDED(hr), "Failed to get part set, hr %#x.\n", hr);
+
+    hr = IOpcRelationshipSet_CreateRelationship(rels, NULL, NULL, NULL, OPC_URI_TARGET_MODE_INTERNAL, &rel);
+    ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
+
+    hr = IOpcRelationshipSet_CreateRelationship(rels, NULL, typeW, NULL, OPC_URI_TARGET_MODE_INTERNAL, &rel);
+    ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
+
+    hr = IOpcRelationshipSet_CreateRelationship(rels, NULL, NULL, target_uri, OPC_URI_TARGET_MODE_INTERNAL, &rel);
+    ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
+
+    /* Absolute target uri with internal mode */
+    hr = IOpcRelationshipSet_CreateRelationship(rels, NULL, typeW, target_uri2, OPC_URI_TARGET_MODE_INTERNAL, &rel);
+todo_wine
+    ok(hr == OPC_E_INVALID_RELATIONSHIP_TARGET, "Unexpected hr %#x.\n", hr);
+
+    hr = IOpcRelationshipSet_CreateRelationship(rels, NULL, typeW, target_uri, OPC_URI_TARGET_MODE_INTERNAL, &rel);
+    ok(SUCCEEDED(hr), "Failed to create relationship, hr %#x.\n", hr);
+
+    /* Autogenerated relationship id */
+    hr = IOpcRelationship_GetId(rel, &id);
+    ok(SUCCEEDED(hr), "Failed to get id, hr %#x.\n", hr);
+    ok(lstrlenW(id) == 9 && *id == 'R', "Unexpected relationship id %s.\n", wine_dbgstr_w(id));
+    CoTaskMemFree(id);
+
+    IOpcRelationship_Release(rel);
+
+    IOpcRelationshipSet_Release(rels);
+
+    IUri_Release(target_uri);
+    IUri_Release(target_uri2);
+    IOpcPackage_Release(package);
+    IOpcFactory_Release(factory);
+}
+
 START_TEST(opcservices)
 {
     IOpcFactory *factory;
@@ -220,6 +283,7 @@ START_TEST(opcservices)
 
     test_package();
     test_file_stream();
+    test_relationship_id();
 
     IOpcFactory_Release(factory);
 
diff --git a/include/opcbase.idl b/include/opcbase.idl
index 33f56ac..80f459f 100644
--- a/include/opcbase.idl
+++ b/include/opcbase.idl
@@ -40,3 +40,5 @@ typedef [v1_enum] enum
     OPC_URI_TARGET_MODE_INTERNAL = 0,
     OPC_URI_TARGET_MODE_EXTERNAL = 1,
 } OPC_URI_TARGET_MODE;
+
+cpp_quote("#define OPC_E_INVALID_RELATIONSHIP_TARGET MAKE_HRESULT(SEVERITY_ERROR, FACILITY_OPC, 0x12)")
diff --git a/include/winerror.h b/include/winerror.h
index 6193c24..d78c91e 100644
--- a/include/winerror.h
+++ b/include/winerror.h
@@ -59,6 +59,7 @@
 #define FACILITY_PLA                         48
 #define FACILITY_FVE                         49
 #define FACILITY_WINDOWS_DEFENDER            80
+#define FACILITY_OPC                         81
 #define FACILITY_DIRECT3D11                  0x87c
 #define FACILITY_AUDCLNT                     0x889
 




More information about the wine-cvs mailing list