opcservices: Implement relationships parts uri support.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
6a3d2cb2f3
commit
390847214b
|
@ -1,5 +1,5 @@
|
||||||
MODULE = opcservices.dll
|
MODULE = opcservices.dll
|
||||||
IMPORTS = uuid ole32 advapi32 urlmon xmllite
|
IMPORTS = uuid ole32 advapi32 urlmon xmllite oleaut32
|
||||||
EXTRALIBS = $(Z_LIBS)
|
EXTRALIBS = $(Z_LIBS)
|
||||||
|
|
||||||
C_SRCS = \
|
C_SRCS = \
|
||||||
|
|
|
@ -310,18 +310,25 @@ static ULONG WINAPI opc_factory_Release(IOpcFactory *iface)
|
||||||
|
|
||||||
static HRESULT WINAPI opc_factory_CreatePackageRootUri(IOpcFactory *iface, IOpcUri **uri)
|
static HRESULT WINAPI opc_factory_CreatePackageRootUri(IOpcFactory *iface, IOpcUri **uri)
|
||||||
{
|
{
|
||||||
static const WCHAR rootW[] = {'/',0};
|
|
||||||
|
|
||||||
TRACE("iface %p, uri %p.\n", iface, uri);
|
TRACE("iface %p, uri %p.\n", iface, uri);
|
||||||
|
|
||||||
return opc_uri_create(rootW, uri);
|
return opc_root_uri_create(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI opc_factory_CreatePartUri(IOpcFactory *iface, LPCWSTR uri, IOpcPartUri **part_uri)
|
static HRESULT WINAPI opc_factory_CreatePartUri(IOpcFactory *iface, LPCWSTR uri, IOpcPartUri **out)
|
||||||
{
|
{
|
||||||
TRACE("iface %p, uri %s, part_uri %p.\n", iface, debugstr_w(uri), part_uri);
|
IUri *part_uri;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
return opc_part_uri_create(uri, part_uri);
|
TRACE("iface %p, uri %s, out %p.\n", iface, debugstr_w(uri), out);
|
||||||
|
|
||||||
|
if (FAILED(hr = CreateUri(uri, Uri_CREATE_ALLOW_RELATIVE, 0, &part_uri)))
|
||||||
|
{
|
||||||
|
WARN("Failed to create uri, hr %#x.\n", hr);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return opc_part_uri_create(part_uri, NULL, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI opc_factory_CreateStreamOnFile(IOpcFactory *iface, LPCWSTR filename,
|
static HRESULT WINAPI opc_factory_CreateStreamOnFile(IOpcFactory *iface, LPCWSTR filename,
|
||||||
|
|
|
@ -45,9 +45,20 @@ static inline BOOL opc_array_reserve(void **elements, size_t *capacity, size_t c
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct opc_uri
|
||||||
|
{
|
||||||
|
IOpcPartUri IOpcPartUri_iface;
|
||||||
|
LONG refcount;
|
||||||
|
BOOL is_part_uri;
|
||||||
|
|
||||||
|
IUri *uri;
|
||||||
|
IUri *rels_part_uri;
|
||||||
|
struct opc_uri *source_uri;
|
||||||
|
};
|
||||||
|
|
||||||
extern HRESULT opc_package_create(IOpcFactory *factory, IOpcPackage **package) DECLSPEC_HIDDEN;
|
extern HRESULT opc_package_create(IOpcFactory *factory, IOpcPackage **package) DECLSPEC_HIDDEN;
|
||||||
extern HRESULT opc_part_uri_create(const WCHAR *uri, IOpcPartUri **part_uri) DECLSPEC_HIDDEN;
|
extern HRESULT opc_part_uri_create(IUri *uri, struct opc_uri *source_uri, IOpcPartUri **part_uri) DECLSPEC_HIDDEN;
|
||||||
extern HRESULT opc_uri_create(const WCHAR *uri, IOpcUri **opc_uri) DECLSPEC_HIDDEN;
|
extern HRESULT opc_root_uri_create(IOpcUri **opc_uri) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
extern HRESULT opc_package_write(IOpcPackage *package, OPC_WRITE_FLAGS flags, IStream *stream) DECLSPEC_HIDDEN;
|
extern HRESULT opc_package_write(IOpcPackage *package, OPC_WRITE_FLAGS flags, IStream *stream) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "msopc.h"
|
#include "msopc.h"
|
||||||
#include "urlmon.h"
|
#include "urlmon.h"
|
||||||
|
|
||||||
|
#include "wine/heap.h"
|
||||||
#include "wine/test.h"
|
#include "wine/test.h"
|
||||||
|
|
||||||
static IOpcFactory *create_factory(void)
|
static IOpcFactory *create_factory(void)
|
||||||
|
@ -373,6 +374,171 @@ todo_wine
|
||||||
IOpcFactory_Release(factory);
|
IOpcFactory_Release(factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static WCHAR *strdupAtoW(const char *str)
|
||||||
|
{
|
||||||
|
WCHAR *ret = NULL;
|
||||||
|
DWORD len;
|
||||||
|
|
||||||
|
if (!str) return ret;
|
||||||
|
len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
|
||||||
|
ret = heap_alloc(len * sizeof(WCHAR));
|
||||||
|
if (ret)
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_rel_part_uri(void)
|
||||||
|
{
|
||||||
|
static const struct
|
||||||
|
{
|
||||||
|
const char *uri;
|
||||||
|
const char *rel_uri;
|
||||||
|
HRESULT hr;
|
||||||
|
} rel_part_uri_tests[] =
|
||||||
|
{
|
||||||
|
{ "/uri", "/_rels/uri.rels" },
|
||||||
|
{ "/uri.ext", "/_rels/uri.ext.rels" },
|
||||||
|
{ "/", "/_rels/.rels" },
|
||||||
|
{ "/_rels/uri.ext.rels", "", OPC_E_NONCONFORMING_URI },
|
||||||
|
};
|
||||||
|
static const struct
|
||||||
|
{
|
||||||
|
const char *uri;
|
||||||
|
BOOL ret;
|
||||||
|
} is_rel_part_tests[] =
|
||||||
|
{
|
||||||
|
{ "/uri", FALSE },
|
||||||
|
{ "/_rels/uri", FALSE },
|
||||||
|
{ "/_rels/uri/uri", FALSE },
|
||||||
|
{ "/_rels/uri/uri.rels", FALSE },
|
||||||
|
{ "/uri/uri.rels", FALSE },
|
||||||
|
{ "/uri/_rels/uri.rels", TRUE },
|
||||||
|
{ "/_rels/.rels", TRUE },
|
||||||
|
};
|
||||||
|
static const WCHAR testuriW[] = {'/','u','r','i',0};
|
||||||
|
IOpcPartUri *part_uri;
|
||||||
|
IOpcFactory *factory;
|
||||||
|
IOpcUri *source_uri;
|
||||||
|
unsigned int i;
|
||||||
|
WCHAR *uriW;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
factory = create_factory();
|
||||||
|
|
||||||
|
hr = IOpcFactory_CreatePartUri(factory, testuriW, &part_uri);
|
||||||
|
ok(SUCCEEDED(hr), "Failed to create part uri, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = IOpcPartUri_GetRelationshipsPartUri(part_uri, NULL);
|
||||||
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = IOpcPartUri_IsRelationshipsPartUri(part_uri, NULL);
|
||||||
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
|
hr = IOpcPartUri_GetSourceUri(part_uri, NULL);
|
||||||
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
||||||
|
|
||||||
|
source_uri = (void *)0xdeadbeef;
|
||||||
|
hr = IOpcPartUri_GetSourceUri(part_uri, &source_uri);
|
||||||
|
ok(hr == OPC_E_RELATIONSHIP_URI_REQUIRED, "Unexpected hr %#x.\n", hr);
|
||||||
|
ok(source_uri == NULL, "Expected null uri.\n");
|
||||||
|
|
||||||
|
IOpcPartUri_Release(part_uri);
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(rel_part_uri_tests); ++i)
|
||||||
|
{
|
||||||
|
BOOL is_root = FALSE;
|
||||||
|
IOpcPartUri *rel_uri;
|
||||||
|
IOpcUri *part_uri;
|
||||||
|
WCHAR *rel_uriW;
|
||||||
|
|
||||||
|
uriW = strdupAtoW(rel_part_uri_tests[i].uri);
|
||||||
|
rel_uriW = strdupAtoW(rel_part_uri_tests[i].rel_uri);
|
||||||
|
|
||||||
|
if (!strcmp(rel_part_uri_tests[i].uri, "/"))
|
||||||
|
{
|
||||||
|
hr = IOpcFactory_CreatePackageRootUri(factory, &part_uri);
|
||||||
|
is_root = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
hr = IOpcFactory_CreatePartUri(factory, uriW, (IOpcPartUri **)&part_uri);
|
||||||
|
ok(SUCCEEDED(hr), "Failed to create part uri, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
rel_uri = (void *)0xdeadbeef;
|
||||||
|
hr = IOpcUri_GetRelationshipsPartUri(part_uri, &rel_uri);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
IOpcPartUri *rel_uri2;
|
||||||
|
IOpcUri *source_uri2;
|
||||||
|
IUnknown *unk = NULL;
|
||||||
|
BOOL ret;
|
||||||
|
BSTR str;
|
||||||
|
|
||||||
|
hr = IOpcPartUri_GetSourceUri(rel_uri, &source_uri);
|
||||||
|
ok(SUCCEEDED(hr), "Failed to get source uri, hr %#x.\n", hr);
|
||||||
|
hr = IOpcPartUri_GetSourceUri(rel_uri, &source_uri2);
|
||||||
|
ok(SUCCEEDED(hr), "Failed to get source uri, hr %#x.\n", hr);
|
||||||
|
ok(source_uri != source_uri2, "Unexpected instance.\n");
|
||||||
|
hr = IOpcUri_IsEqual(source_uri, (IUri *)source_uri2, &ret);
|
||||||
|
todo_wine {
|
||||||
|
ok(SUCCEEDED(hr), "IsEqual failed, hr %#x.\n", hr);
|
||||||
|
ok(ret, "Expected equal uris.\n");
|
||||||
|
}
|
||||||
|
hr = IOpcUri_QueryInterface(source_uri, &IID_IOpcPartUri, (void **)&unk);
|
||||||
|
ok(hr == (is_root ? E_NOINTERFACE : S_OK), "Unexpected hr %#x, %s.\n", hr, rel_part_uri_tests[i].uri);
|
||||||
|
if (unk)
|
||||||
|
IUnknown_Release(unk);
|
||||||
|
|
||||||
|
IOpcUri_Release(source_uri2);
|
||||||
|
IOpcUri_Release(source_uri);
|
||||||
|
|
||||||
|
hr = IOpcUri_GetRelationshipsPartUri(part_uri, &rel_uri2);
|
||||||
|
ok(SUCCEEDED(hr), "Failed to get rels part uri, hr %#x.\n", hr);
|
||||||
|
ok(rel_uri2 != rel_uri, "Unexpected instance.\n");
|
||||||
|
IOpcPartUri_Release(rel_uri2);
|
||||||
|
|
||||||
|
hr = IOpcPartUri_GetRawUri(rel_uri, &str);
|
||||||
|
ok(SUCCEEDED(hr), "Failed to get rel uri, hr %#x.\n", hr);
|
||||||
|
ok(!lstrcmpW(str, rel_uriW), "%u: unexpected rel uri %s, expected %s.\n", i, wine_dbgstr_w(str),
|
||||||
|
wine_dbgstr_w(rel_uriW));
|
||||||
|
SysFreeString(str);
|
||||||
|
|
||||||
|
IOpcPartUri_Release(rel_uri);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ok(hr == rel_part_uri_tests[i].hr, "%u: unexpected hr %#x.\n", i, hr);
|
||||||
|
ok(rel_uri == NULL, "%u: unexpected out pointer.\n", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
heap_free(uriW);
|
||||||
|
heap_free(rel_uriW);
|
||||||
|
|
||||||
|
IOpcUri_Release(part_uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(is_rel_part_tests); ++i)
|
||||||
|
{
|
||||||
|
IOpcPartUri *part_uri;
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
uriW = strdupAtoW(is_rel_part_tests[i].uri);
|
||||||
|
|
||||||
|
hr = IOpcFactory_CreatePartUri(factory, uriW, &part_uri);
|
||||||
|
ok(SUCCEEDED(hr), "Failed to create part uri, hr %#x.\n", hr);
|
||||||
|
|
||||||
|
ret = 123;
|
||||||
|
hr = IOpcPartUri_IsRelationshipsPartUri(part_uri, &ret);
|
||||||
|
ok(SUCCEEDED(hr), "Unexpected hr %#x.\n", hr);
|
||||||
|
ok(ret == is_rel_part_tests[i].ret, "%u: unexpected result %d.\n", i, ret);
|
||||||
|
|
||||||
|
heap_free(uriW);
|
||||||
|
|
||||||
|
IOpcPartUri_Release(part_uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
IOpcFactory_Release(factory);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(opcservices)
|
START_TEST(opcservices)
|
||||||
{
|
{
|
||||||
IOpcFactory *factory;
|
IOpcFactory *factory;
|
||||||
|
@ -390,6 +556,7 @@ START_TEST(opcservices)
|
||||||
test_package();
|
test_package();
|
||||||
test_file_stream();
|
test_file_stream();
|
||||||
test_relationship();
|
test_relationship();
|
||||||
|
test_rel_part_uri();
|
||||||
|
|
||||||
IOpcFactory_Release(factory);
|
IOpcFactory_Release(factory);
|
||||||
|
|
||||||
|
|
|
@ -23,25 +23,19 @@
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
#include "wine/unicode.h"
|
||||||
|
|
||||||
#include "opc_private.h"
|
#include "opc_private.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(msopc);
|
WINE_DEFAULT_DEBUG_CHANNEL(msopc);
|
||||||
|
|
||||||
struct opc_uri
|
|
||||||
{
|
|
||||||
IOpcPartUri IOpcPartUri_iface;
|
|
||||||
LONG refcount;
|
|
||||||
BOOL is_part_uri;
|
|
||||||
|
|
||||||
IUri *uri;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline struct opc_uri *impl_from_IOpcPartUri(IOpcPartUri *iface)
|
static inline struct opc_uri *impl_from_IOpcPartUri(IOpcPartUri *iface)
|
||||||
{
|
{
|
||||||
return CONTAINING_RECORD(iface, struct opc_uri, IOpcPartUri_iface);
|
return CONTAINING_RECORD(iface, struct opc_uri, IOpcPartUri_iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT opc_source_uri_create(struct opc_uri *uri, IOpcUri **out);
|
||||||
|
|
||||||
static HRESULT WINAPI opc_uri_QueryInterface(IOpcPartUri *iface, REFIID iid, void **out)
|
static HRESULT WINAPI opc_uri_QueryInterface(IOpcPartUri *iface, REFIID iid, void **out)
|
||||||
{
|
{
|
||||||
struct opc_uri *uri = impl_from_IOpcPartUri(iface);
|
struct opc_uri *uri = impl_from_IOpcPartUri(iface);
|
||||||
|
@ -81,6 +75,10 @@ static ULONG WINAPI opc_uri_Release(IOpcPartUri *iface)
|
||||||
|
|
||||||
if (!refcount)
|
if (!refcount)
|
||||||
{
|
{
|
||||||
|
if (uri->rels_part_uri)
|
||||||
|
IUri_Release(uri->rels_part_uri);
|
||||||
|
if (uri->source_uri)
|
||||||
|
IOpcPartUri_Release(&uri->source_uri->IOpcPartUri_iface);
|
||||||
IUri_Release(uri->uri);
|
IUri_Release(uri->uri);
|
||||||
heap_free(uri);
|
heap_free(uri);
|
||||||
}
|
}
|
||||||
|
@ -319,9 +317,20 @@ static HRESULT WINAPI opc_uri_IsEqual(IOpcPartUri *iface, IUri *comparand, BOOL
|
||||||
|
|
||||||
static HRESULT WINAPI opc_uri_GetRelationshipsPartUri(IOpcPartUri *iface, IOpcPartUri **part_uri)
|
static HRESULT WINAPI opc_uri_GetRelationshipsPartUri(IOpcPartUri *iface, IOpcPartUri **part_uri)
|
||||||
{
|
{
|
||||||
FIXME("iface %p, part_uri %p stub!\n", iface, part_uri);
|
struct opc_uri *uri = impl_from_IOpcPartUri(iface);
|
||||||
|
|
||||||
return E_NOTIMPL;
|
TRACE("iface %p, part_uri %p.\n", iface, part_uri);
|
||||||
|
|
||||||
|
if (!part_uri)
|
||||||
|
return E_POINTER;
|
||||||
|
|
||||||
|
if (!uri->rels_part_uri)
|
||||||
|
{
|
||||||
|
*part_uri = NULL;
|
||||||
|
return OPC_E_NONCONFORMING_URI;
|
||||||
|
}
|
||||||
|
|
||||||
|
return opc_part_uri_create(uri->rels_part_uri, uri, part_uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI opc_uri_GetRelativeUri(IOpcPartUri *iface, IOpcPartUri *part_uri,
|
static HRESULT WINAPI opc_uri_GetRelativeUri(IOpcPartUri *iface, IOpcPartUri *part_uri,
|
||||||
|
@ -349,16 +358,25 @@ static HRESULT WINAPI opc_uri_ComparePartUri(IOpcPartUri *iface, IOpcPartUri *pa
|
||||||
|
|
||||||
static HRESULT WINAPI opc_uri_GetSourceUri(IOpcPartUri *iface, IOpcUri **source_uri)
|
static HRESULT WINAPI opc_uri_GetSourceUri(IOpcPartUri *iface, IOpcUri **source_uri)
|
||||||
{
|
{
|
||||||
FIXME("iface %p, source_uri %p stub!\n", iface, source_uri);
|
struct opc_uri *uri = impl_from_IOpcPartUri(iface);
|
||||||
|
|
||||||
return E_NOTIMPL;
|
TRACE("iface %p, source_uri %p.\n", iface, source_uri);
|
||||||
|
|
||||||
|
return opc_source_uri_create(uri, source_uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI opc_uri_IsRelationshipsPartUri(IOpcPartUri *iface, BOOL *result)
|
static HRESULT WINAPI opc_uri_IsRelationshipsPartUri(IOpcPartUri *iface, BOOL *result)
|
||||||
{
|
{
|
||||||
FIXME("iface %p, result %p stub!\n", iface, result);
|
struct opc_uri *uri = impl_from_IOpcPartUri(iface);
|
||||||
|
|
||||||
return E_NOTIMPL;
|
TRACE("iface %p, result %p.\n", iface, result);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
return E_POINTER;
|
||||||
|
|
||||||
|
*result = !uri->rels_part_uri;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const IOpcPartUriVtbl opc_part_uri_vtbl =
|
static const IOpcPartUriVtbl opc_part_uri_vtbl =
|
||||||
|
@ -399,56 +417,161 @@ static const IOpcPartUriVtbl opc_part_uri_vtbl =
|
||||||
opc_uri_IsRelationshipsPartUri,
|
opc_uri_IsRelationshipsPartUri,
|
||||||
};
|
};
|
||||||
|
|
||||||
static HRESULT opc_part_uri_init(struct opc_uri *object, BOOL is_part_uri, const WCHAR *uri)
|
static IUri *opc_part_uri_get_rels_uri(IUri *uri)
|
||||||
{
|
{
|
||||||
|
static const WCHAR relsdirW[] = {'/','_','r','e','l','s',0};
|
||||||
|
static const WCHAR relsextW[] = {'.','r','e','l','s',0};
|
||||||
|
WCHAR *start = NULL, *end, *ret;
|
||||||
|
IUri *rels_uri;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
DWORD len;
|
||||||
|
BSTR path;
|
||||||
|
|
||||||
|
if (FAILED(IUri_GetPath(uri, &path)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (FAILED(IUri_GetPropertyLength(uri, Uri_PROPERTY_PATH, &len, 0)))
|
||||||
|
{
|
||||||
|
SysFreeString(path);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
end = strrchrW(path, '/');
|
||||||
|
if (end && end >= path + ARRAY_SIZE(relsdirW) - 1)
|
||||||
|
start = end - ARRAY_SIZE(relsdirW) + 1;
|
||||||
|
if (!start)
|
||||||
|
start = end;
|
||||||
|
|
||||||
|
/* Test if it's already relationships uri. */
|
||||||
|
if (len > ARRAY_SIZE(relsextW))
|
||||||
|
{
|
||||||
|
if (!strcmpW(path + len - ARRAY_SIZE(relsextW) + 1, relsextW))
|
||||||
|
{
|
||||||
|
if (start && !memcmp(start, relsdirW, ARRAY_SIZE(relsdirW) - sizeof(WCHAR)))
|
||||||
|
{
|
||||||
|
SysFreeString(path);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = heap_alloc((len + ARRAY_SIZE(relsextW) + ARRAY_SIZE(relsdirW)) * sizeof(WCHAR));
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
SysFreeString(path);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ret[0] = 0;
|
||||||
|
|
||||||
|
if (start != path)
|
||||||
|
{
|
||||||
|
memcpy(ret, path, (start - path) * sizeof(WCHAR));
|
||||||
|
ret[start - path] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcatW(ret, relsdirW);
|
||||||
|
strcatW(ret, end);
|
||||||
|
strcatW(ret, relsextW);
|
||||||
|
|
||||||
|
if (FAILED(hr = CreateUri(ret, Uri_CREATE_ALLOW_RELATIVE, 0, &rels_uri)))
|
||||||
|
WARN("Failed to create rels uri, hr %#x.\n", hr);
|
||||||
|
heap_free(ret);
|
||||||
|
|
||||||
|
return rels_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT opc_part_uri_init(struct opc_uri *object, struct opc_uri *source_uri, BOOL is_part_uri, IUri *uri)
|
||||||
|
{
|
||||||
object->IOpcPartUri_iface.lpVtbl = &opc_part_uri_vtbl;
|
object->IOpcPartUri_iface.lpVtbl = &opc_part_uri_vtbl;
|
||||||
object->refcount = 1;
|
object->refcount = 1;
|
||||||
object->is_part_uri = is_part_uri;
|
object->is_part_uri = is_part_uri;
|
||||||
|
object->uri = uri;
|
||||||
if (FAILED(hr = CreateUri(uri, Uri_CREATE_ALLOW_RELATIVE, 0, &object->uri)))
|
IUri_AddRef(object->uri);
|
||||||
return hr;
|
object->rels_part_uri = opc_part_uri_get_rels_uri(object->uri);
|
||||||
|
object->source_uri = source_uri;
|
||||||
|
if (object->source_uri)
|
||||||
|
IOpcPartUri_AddRef(&object->source_uri->IOpcPartUri_iface);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT opc_part_uri_create(const WCHAR *str, IOpcPartUri **out)
|
static HRESULT opc_source_uri_create(struct opc_uri *uri, IOpcUri **out)
|
||||||
{
|
{
|
||||||
struct opc_uri *uri;
|
struct opc_uri *obj;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
if (!(uri = heap_alloc_zero(sizeof(*uri))))
|
if (!out)
|
||||||
|
return E_POINTER;
|
||||||
|
|
||||||
|
*out = NULL;
|
||||||
|
|
||||||
|
if (!uri->source_uri)
|
||||||
|
return OPC_E_RELATIONSHIP_URI_REQUIRED;
|
||||||
|
|
||||||
|
if (!(obj = heap_alloc_zero(sizeof(*obj))))
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
if (FAILED(hr = opc_part_uri_init(uri, TRUE, str)))
|
if (FAILED(hr = opc_part_uri_init(obj, NULL, uri->source_uri->is_part_uri, uri->source_uri->uri)))
|
||||||
{
|
{
|
||||||
WARN("Failed to init part uri, hr %#x.\n", hr);
|
WARN("Failed to init part uri, hr %#x.\n", hr);
|
||||||
heap_free(uri);
|
heap_free(obj);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
*out = &uri->IOpcPartUri_iface;
|
*out = (IOpcUri *)&obj->IOpcPartUri_iface;
|
||||||
|
|
||||||
|
TRACE("Created source uri %p.\n", *out);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT opc_part_uri_create(IUri *uri, struct opc_uri *source_uri, IOpcPartUri **out)
|
||||||
|
{
|
||||||
|
struct opc_uri *obj;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (!(obj = heap_alloc_zero(sizeof(*obj))))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
if (FAILED(hr = opc_part_uri_init(obj, source_uri, TRUE, uri)))
|
||||||
|
{
|
||||||
|
WARN("Failed to init part uri, hr %#x.\n", hr);
|
||||||
|
heap_free(obj);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out = &obj->IOpcPartUri_iface;
|
||||||
TRACE("Created part uri %p.\n", *out);
|
TRACE("Created part uri %p.\n", *out);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT opc_uri_create(const WCHAR *str, IOpcUri **out)
|
HRESULT opc_root_uri_create(IOpcUri **out)
|
||||||
{
|
{
|
||||||
struct opc_uri *uri;
|
static const WCHAR rootW[] = {'/',0};
|
||||||
|
struct opc_uri *obj;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
IUri *uri;
|
||||||
|
|
||||||
if (!(uri = heap_alloc_zero(sizeof(*uri))))
|
if (!(obj = heap_alloc_zero(sizeof(*obj))))
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
if (FAILED(hr = opc_part_uri_init(uri, FALSE, str)))
|
if (FAILED(hr = CreateUri(rootW, Uri_CREATE_ALLOW_RELATIVE, 0, &uri)))
|
||||||
|
{
|
||||||
|
WARN("Failed to create rels uri, hr %#x.\n", hr);
|
||||||
|
heap_free(obj);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = opc_part_uri_init(obj, NULL, FALSE, uri);
|
||||||
|
IUri_Release(uri);
|
||||||
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
WARN("Failed to init uri, hr %#x.\n", hr);
|
WARN("Failed to init uri, hr %#x.\n", hr);
|
||||||
heap_free(uri);
|
heap_free(uri);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
*out = (IOpcUri *)&uri->IOpcPartUri_iface;
|
*out = (IOpcUri *)&obj->IOpcPartUri_iface;
|
||||||
TRACE("Created part uri %p.\n", *out);
|
TRACE("Created part uri %p.\n", *out);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,5 +41,7 @@ typedef [v1_enum] enum
|
||||||
OPC_URI_TARGET_MODE_EXTERNAL = 1,
|
OPC_URI_TARGET_MODE_EXTERNAL = 1,
|
||||||
} OPC_URI_TARGET_MODE;
|
} OPC_URI_TARGET_MODE;
|
||||||
|
|
||||||
|
cpp_quote("#define OPC_E_NONCONFORMING_URI MAKE_HRESULT(SEVERITY_ERROR, FACILITY_OPC, 0x1)")
|
||||||
|
cpp_quote("#define OPC_E_RELATIONSHIP_URI_REQUIRED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_OPC, 0x3)")
|
||||||
cpp_quote("#define OPC_E_INVALID_RELATIONSHIP_TARGET MAKE_HRESULT(SEVERITY_ERROR, FACILITY_OPC, 0x12)")
|
cpp_quote("#define OPC_E_INVALID_RELATIONSHIP_TARGET MAKE_HRESULT(SEVERITY_ERROR, FACILITY_OPC, 0x12)")
|
||||||
cpp_quote("#define OPC_E_NO_SUCH_RELATIONSHIP MAKE_HRESULT(SEVERITY_ERROR, FACILITY_OPC, 0x48)")
|
cpp_quote("#define OPC_E_NO_SUCH_RELATIONSHIP MAKE_HRESULT(SEVERITY_ERROR, FACILITY_OPC, 0x48)")
|
||||||
|
|
Loading…
Reference in New Issue