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