1323 lines
46 KiB
C
1323 lines
46 KiB
C
/*
|
|
* OPC Services tests
|
|
*
|
|
* Copyright 2018 Nikolay Sivov for CodeWeavers
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
#define COBJMACROS
|
|
|
|
#include "windows.h"
|
|
#include "initguid.h"
|
|
#include "msopc.h"
|
|
#include "urlmon.h"
|
|
|
|
#include "wine/heap.h"
|
|
#include "wine/test.h"
|
|
|
|
static IOpcFactory *create_factory(void)
|
|
{
|
|
IOpcFactory *factory = NULL;
|
|
CoCreateInstance(&CLSID_OpcFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IOpcFactory, (void **)&factory);
|
|
return factory;
|
|
}
|
|
|
|
static void test_package(void)
|
|
{
|
|
static const WCHAR typeW[] = {'t','y','p','e','/','s','u','b','t','y','p','e',0};
|
|
static const WCHAR targetW[] = {'t','a','r','g','e','t',0};
|
|
static const WCHAR uriW[] = {'/','u','r','i',0};
|
|
static const WCHAR rootW[] = {'/',0};
|
|
IOpcRelationshipSet *relset, *relset2;
|
|
IOpcPartUri *part_uri, *part_uri2;
|
|
IOpcPartSet *partset, *partset2;
|
|
OPC_COMPRESSION_OPTIONS options;
|
|
IStream *stream, *stream2;
|
|
IOpcPart *part, *part2;
|
|
IOpcRelationship *rel;
|
|
IOpcFactory *factory;
|
|
IOpcPackage *package;
|
|
LARGE_INTEGER move;
|
|
ULARGE_INTEGER pos;
|
|
IUri *target_uri;
|
|
char buff[16];
|
|
IOpcUri *uri;
|
|
HRESULT hr;
|
|
BSTR str;
|
|
BOOL ret;
|
|
|
|
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))
|
|
{
|
|
IOpcFactory_Release(factory);
|
|
return;
|
|
}
|
|
|
|
hr = IOpcPackage_GetPartSet(package, &partset);
|
|
ok(SUCCEEDED(hr), "Failed to create a part set, hr %#x.\n", hr);
|
|
|
|
hr = IOpcPackage_GetPartSet(package, &partset2);
|
|
ok(SUCCEEDED(hr), "Failed to create a part set, hr %#x.\n", hr);
|
|
ok(partset == partset2, "Expected same part set instance.\n");
|
|
IOpcPartSet_Release(partset2);
|
|
|
|
/* CreatePart */
|
|
hr = IOpcFactory_CreatePartUri(factory, uriW, &part_uri);
|
|
ok(SUCCEEDED(hr), "Failed to create part uri, hr %#x.\n", hr);
|
|
|
|
hr = IOpcFactory_CreatePartUri(factory, uriW, &part_uri2);
|
|
ok(SUCCEEDED(hr), "Failed to create part uri, hr %#x.\n", hr);
|
|
|
|
part = (void *)0xdeadbeef;
|
|
hr = IOpcPartSet_CreatePart(partset, NULL, typeW, OPC_COMPRESSION_NONE, &part);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
ok(part == NULL, "Unexpected pointer %p.\n", part);
|
|
|
|
hr = IOpcPartSet_CreatePart(partset, part_uri, typeW, OPC_COMPRESSION_NONE, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
hr = IOpcPartSet_CreatePart(partset, part_uri, typeW, 0xdeadbeef, &part);
|
|
ok(SUCCEEDED(hr), "Failed to create a part, hr %#x.\n", hr);
|
|
hr = IOpcPart_GetCompressionOptions(part, &options);
|
|
ok(SUCCEEDED(hr), "Failed to get compression options, hr %#x.\n", hr);
|
|
ok(options == 0xdeadbeef, "Unexpected compression options %#x.\n", options);
|
|
|
|
part2 = (void *)0xdeadbeef;
|
|
hr = IOpcPartSet_CreatePart(partset, part_uri, typeW, OPC_COMPRESSION_NONE, &part2);
|
|
ok(hr == OPC_E_DUPLICATE_PART, "Unexpected hr %#x.\n", hr);
|
|
ok(part2 == NULL, "Unexpected instance %p.\n", part2);
|
|
|
|
part2 = (void *)0xdeadbeef;
|
|
hr = IOpcPartSet_CreatePart(partset, part_uri2, typeW, OPC_COMPRESSION_NONE, &part2);
|
|
ok(hr == OPC_E_DUPLICATE_PART, "Unexpected hr %#x.\n", hr);
|
|
ok(part2 == NULL, "Unexpected instance %p.\n", part2);
|
|
IOpcPartUri_Release(part_uri2);
|
|
|
|
hr = IOpcPartSet_GetPart(partset, NULL, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
part2 = (void *)0xdeadbeef;
|
|
hr = IOpcPartSet_GetPart(partset, NULL, &part2);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
ok(part2 == NULL, "Unexpected pointer %p.\n", part2);
|
|
|
|
hr = IOpcPartSet_GetPart(partset, part_uri, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
hr = IOpcPartSet_GetPart(partset, part_uri, &part2);
|
|
ok(SUCCEEDED(hr), "Failed to get part, hr %#x.\n", hr);
|
|
IOpcPart_Release(part2);
|
|
|
|
hr = IOpcFactory_CreatePartUri(factory, targetW, &part_uri2);
|
|
ok(SUCCEEDED(hr), "Failed to create part uri, hr %#x.\n", hr);
|
|
|
|
hr = IOpcPartSet_GetPart(partset, part_uri2, &part2);
|
|
ok(hr == OPC_E_NO_SUCH_PART, "Unexpected hr %#x.\n", hr);
|
|
IOpcPartUri_Release(part_uri2);
|
|
|
|
hr = IOpcPart_GetContentStream(part, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
hr = IOpcPart_GetContentStream(part, &stream);
|
|
ok(SUCCEEDED(hr), "Failed to get content stream, hr %#x.\n", hr);
|
|
|
|
hr = IStream_Write(stream, "abc", 3, NULL);
|
|
ok(hr == S_OK, "Failed to write content, hr %#x.\n", hr);
|
|
|
|
move.QuadPart = 0;
|
|
hr = IStream_Seek(stream, move, STREAM_SEEK_CUR, &pos);
|
|
ok(SUCCEEDED(hr), "Seek failed, hr %#x.\n", hr);
|
|
ok(pos.QuadPart == 3, "Unexpected position.\n");
|
|
|
|
hr = IOpcPart_GetContentStream(part, &stream2);
|
|
ok(SUCCEEDED(hr), "Failed to get content stream, hr %#x.\n", hr);
|
|
ok(stream != stream2, "Unexpected instance.\n");
|
|
|
|
move.QuadPart = 0;
|
|
hr = IStream_Seek(stream2, move, STREAM_SEEK_CUR, &pos);
|
|
ok(SUCCEEDED(hr), "Seek failed, hr %#x.\n", hr);
|
|
ok(pos.QuadPart == 0, "Unexpected position.\n");
|
|
|
|
memset(buff, 0, sizeof(buff));
|
|
hr = IStream_Read(stream2, buff, sizeof(buff), NULL);
|
|
ok(hr == S_OK, "Failed to read content, hr %#x.\n", hr);
|
|
ok(!memcmp(buff, "abc", 3), "Unexpected content.\n");
|
|
|
|
move.QuadPart = 0;
|
|
hr = IStream_Seek(stream2, move, STREAM_SEEK_CUR, &pos);
|
|
ok(SUCCEEDED(hr), "Seek failed, hr %#x.\n", hr);
|
|
ok(pos.QuadPart == 3, "Unexpected position.\n");
|
|
|
|
IStream_Release(stream);
|
|
IStream_Release(stream2);
|
|
|
|
hr = IOpcPart_GetRelationshipSet(part, &relset);
|
|
ok(SUCCEEDED(hr), "Failed to get relationship set, hr %#x.\n", hr);
|
|
|
|
hr = IOpcPart_GetRelationshipSet(part, &relset2);
|
|
ok(SUCCEEDED(hr), "Failed to get relationship set, hr %#x.\n", hr);
|
|
ok(relset == relset2, "Expected same part set instance.\n");
|
|
|
|
hr = CreateUri(targetW, Uri_CREATE_ALLOW_RELATIVE, 0, &target_uri);
|
|
ok(SUCCEEDED(hr), "Failed to create target uri, hr %#x.\n", hr);
|
|
|
|
hr = IOpcRelationshipSet_CreateRelationship(relset, NULL, typeW, target_uri, OPC_URI_TARGET_MODE_INTERNAL, &rel);
|
|
ok(SUCCEEDED(hr), "Failed to create relationship, hr %#x.\n", hr);
|
|
|
|
hr = IOpcRelationship_GetSourceUri(rel, &uri);
|
|
ok(SUCCEEDED(hr), "Failed to get source uri, hr %#x.\n", hr);
|
|
ok(uri == (IOpcUri *)part_uri, "Unexpected source uri.\n");
|
|
|
|
IOpcUri_Release(uri);
|
|
|
|
IOpcRelationship_Release(rel);
|
|
IUri_Release(target_uri);
|
|
|
|
IOpcRelationshipSet_Release(relset);
|
|
IOpcRelationshipSet_Release(relset2);
|
|
|
|
ret = 123;
|
|
hr = IOpcPartSet_PartExists(partset, NULL, &ret);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
ok(ret == 123, "Unexpected return value.\n");
|
|
|
|
hr = IOpcPartSet_PartExists(partset, part_uri, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
ret = FALSE;
|
|
hr = IOpcPartSet_PartExists(partset, part_uri, &ret);
|
|
ok(SUCCEEDED(hr), "Unexpected hr %#x.\n", hr);
|
|
ok(ret, "Expected part to exist.\n");
|
|
|
|
IOpcPartUri_Release(part_uri);
|
|
IOpcPart_Release(part);
|
|
|
|
/* Relationships */
|
|
hr = IOpcPackage_GetRelationshipSet(package, &relset);
|
|
ok(SUCCEEDED(hr), "Failed to get relationship set, hr %#x.\n", hr);
|
|
|
|
hr = IOpcPackage_GetRelationshipSet(package, &relset2);
|
|
ok(SUCCEEDED(hr), "Failed to get relationship set, hr %#x.\n", hr);
|
|
ok(relset == relset2, "Expected same part set instance.\n");
|
|
IOpcRelationshipSet_Release(relset);
|
|
IOpcRelationshipSet_Release(relset2);
|
|
|
|
IOpcPartSet_Release(partset);
|
|
IOpcPackage_Release(package);
|
|
|
|
/* Root uri */
|
|
hr = IOpcFactory_CreatePackageRootUri(factory, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
hr = IOpcFactory_CreatePackageRootUri(factory, &uri);
|
|
ok(SUCCEEDED(hr), "Failed to create root uri, hr %#x.\n", hr);
|
|
hr = IOpcUri_GetRawUri(uri, &str);
|
|
ok(SUCCEEDED(hr), "Failed to get raw uri, hr %#x.\n", hr);
|
|
ok(!lstrcmpW(str, rootW), "Unexpected uri %s.\n", wine_dbgstr_w(str));
|
|
SysFreeString(str);
|
|
IOpcUri_Release(uri);
|
|
|
|
IOpcFactory_Release(factory);
|
|
}
|
|
|
|
#define test_stream_stat(stream, size) test_stream_stat_(__LINE__, stream, size)
|
|
static void test_stream_stat_(unsigned int line, IStream *stream, ULONG size)
|
|
{
|
|
STATSTG statstg;
|
|
HRESULT hr;
|
|
|
|
hr = IStream_Stat(stream, NULL, 0);
|
|
ok_(__FILE__, line)(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
memset(&statstg, 0xff, sizeof(statstg));
|
|
hr = IStream_Stat(stream, &statstg, 0);
|
|
ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get stat info, hr %#x.\n", hr);
|
|
|
|
ok_(__FILE__, line)(statstg.pwcsName == NULL, "Unexpected name %s.\n", wine_dbgstr_w(statstg.pwcsName));
|
|
ok_(__FILE__, line)(statstg.type == STGTY_STREAM, "Unexpected type.\n");
|
|
ok_(__FILE__, line)(statstg.cbSize.QuadPart == size, "Unexpected size %u, expected %u.\n",
|
|
statstg.cbSize.LowPart, size);
|
|
ok_(__FILE__, line)(statstg.grfMode == STGM_READ, "Unexpected mode.\n");
|
|
ok_(__FILE__, line)(statstg.grfLocksSupported == 0, "Unexpected lock mode.\n");
|
|
ok_(__FILE__, line)(statstg.grfStateBits == 0, "Unexpected state bits.\n");
|
|
}
|
|
|
|
static void test_file_stream(void)
|
|
{
|
|
static const WCHAR filereadW[] = {'o','p','c','f','i','l','e','r','e','a','d','.','e','x','t',0};
|
|
WCHAR temppathW[MAX_PATH], pathW[MAX_PATH];
|
|
IOpcFactory *factory;
|
|
LARGE_INTEGER move;
|
|
IStream *stream;
|
|
char buff[64];
|
|
HRESULT hr;
|
|
ULONG size;
|
|
|
|
factory = create_factory();
|
|
|
|
hr = IOpcFactory_CreateStreamOnFile(factory, NULL, OPC_STREAM_IO_READ, NULL, 0, &stream);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
GetTempPathW(ARRAY_SIZE(temppathW), temppathW);
|
|
lstrcpyW(pathW, temppathW);
|
|
lstrcatW(pathW, filereadW);
|
|
DeleteFileW(pathW);
|
|
|
|
hr = IOpcFactory_CreateStreamOnFile(factory, pathW, OPC_STREAM_IO_READ, NULL, 0, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
/* File does not exist */
|
|
hr = IOpcFactory_CreateStreamOnFile(factory, pathW, OPC_STREAM_IO_READ, NULL, 0, &stream);
|
|
ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
|
|
|
|
hr = IOpcFactory_CreateStreamOnFile(factory, pathW, OPC_STREAM_IO_WRITE, NULL, 0, &stream);
|
|
ok(SUCCEEDED(hr), "Failed to create a write stream, hr %#x.\n", hr);
|
|
|
|
test_stream_stat(stream, 0);
|
|
|
|
size = lstrlenW(pathW) * sizeof(WCHAR);
|
|
hr = IStream_Write(stream, pathW, size, NULL);
|
|
ok(hr == S_OK, "Stream write failed, hr %#x.\n", hr);
|
|
|
|
test_stream_stat(stream, size);
|
|
IStream_Release(stream);
|
|
|
|
/* Invalid I/O mode */
|
|
hr = IOpcFactory_CreateStreamOnFile(factory, pathW, 10, NULL, 0, &stream);
|
|
ok(hr == E_INVALIDARG, "Failed to create a write stream, hr %#x.\n", hr);
|
|
|
|
/* Write to read-only stream. */
|
|
hr = IOpcFactory_CreateStreamOnFile(factory, pathW, OPC_STREAM_IO_READ, NULL, 0, &stream);
|
|
ok(SUCCEEDED(hr), "Failed to create a read stream, hr %#x.\n", hr);
|
|
|
|
test_stream_stat(stream, size);
|
|
hr = IStream_Write(stream, pathW, size, NULL);
|
|
ok(hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED), "Stream write failed, hr %#x.\n", hr);
|
|
IStream_Release(stream);
|
|
|
|
/* Read from write-only stream. */
|
|
hr = IOpcFactory_CreateStreamOnFile(factory, pathW, OPC_STREAM_IO_WRITE, NULL, 0, &stream);
|
|
ok(SUCCEEDED(hr), "Failed to create a read stream, hr %#x.\n", hr);
|
|
|
|
test_stream_stat(stream, 0);
|
|
hr = IStream_Write(stream, pathW, size, NULL);
|
|
ok(hr == S_OK, "Stream write failed, hr %#x.\n", hr);
|
|
test_stream_stat(stream, size);
|
|
|
|
move.QuadPart = 0;
|
|
hr = IStream_Seek(stream, move, STREAM_SEEK_SET, NULL);
|
|
ok(SUCCEEDED(hr), "Seek failed, hr %#x.\n", hr);
|
|
|
|
hr = IStream_Read(stream, buff, sizeof(buff), NULL);
|
|
ok(hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED), "Stream read failed, hr %#x.\n", hr);
|
|
|
|
IStream_Release(stream);
|
|
|
|
IOpcFactory_Release(factory);
|
|
DeleteFileW(pathW);
|
|
}
|
|
|
|
static void test_relationship(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};
|
|
static const WCHAR rootW[] = {'/',0};
|
|
IUri *target_uri, *target_uri2, *uri;
|
|
IOpcRelationship *rel, *rel2, *rel3;
|
|
IOpcUri *source_uri, *source_uri2;
|
|
IOpcRelationshipSet *rels;
|
|
IOpcFactory *factory;
|
|
IOpcPackage *package;
|
|
IUnknown *unk;
|
|
DWORD mode;
|
|
HRESULT hr;
|
|
WCHAR *id;
|
|
BOOL ret;
|
|
BSTR str;
|
|
|
|
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))
|
|
{
|
|
IOpcFactory_Release(factory);
|
|
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);
|
|
|
|
rel = (void *)0xdeadbeef;
|
|
hr = IOpcRelationshipSet_CreateRelationship(rels, NULL, NULL, NULL, OPC_URI_TARGET_MODE_INTERNAL, &rel);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
ok(rel == NULL, "Unexpected instance %p.\n", rel);
|
|
|
|
rel = (void *)0xdeadbeef;
|
|
hr = IOpcRelationshipSet_CreateRelationship(rels, NULL, typeW, NULL, OPC_URI_TARGET_MODE_INTERNAL, &rel);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
ok(rel == NULL, "Unexpected instance %p.\n", rel);
|
|
|
|
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 */
|
|
rel = (void *)0xdeadbeef;
|
|
hr = IOpcRelationshipSet_CreateRelationship(rels, NULL, typeW, target_uri2, OPC_URI_TARGET_MODE_INTERNAL, &rel);
|
|
ok(hr == OPC_E_INVALID_RELATIONSHIP_TARGET, "Unexpected hr %#x.\n", hr);
|
|
ok(rel == NULL, "Unexpected instance %p.\n", rel);
|
|
|
|
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));
|
|
|
|
hr = IOpcRelationshipSet_CreateRelationship(rels, id, typeW, target_uri, OPC_URI_TARGET_MODE_INTERNAL, &rel2);
|
|
ok(hr == OPC_E_DUPLICATE_RELATIONSHIP, "Failed to create relationship, hr %#x.\n", hr);
|
|
|
|
hr = IOpcRelationshipSet_CreateRelationship(rels, id, typeW, target_uri2, OPC_URI_TARGET_MODE_INTERNAL, &rel2);
|
|
ok(hr == OPC_E_DUPLICATE_RELATIONSHIP, "Failed to create relationship, hr %#x.\n", hr);
|
|
|
|
hr = IOpcRelationshipSet_CreateRelationship(rels, NULL, typeW, target_uri, OPC_URI_TARGET_MODE_INTERNAL, &rel2);
|
|
ok(SUCCEEDED(hr), "Failed to create relationship, hr %#x.\n", hr);
|
|
|
|
ret = 123;
|
|
hr = IOpcRelationshipSet_RelationshipExists(rels, NULL, &ret);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
ok(ret == 123, "Unexpected result %d.\n", ret);
|
|
|
|
hr = IOpcRelationshipSet_RelationshipExists(rels, id, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
ret = FALSE;
|
|
hr = IOpcRelationshipSet_RelationshipExists(rels, id, &ret);
|
|
ok(SUCCEEDED(hr), "Failed to get relationship, hr %#x.\n", hr);
|
|
ok(ret, "Unexpected result %d.\n", ret);
|
|
|
|
hr = IOpcRelationshipSet_GetRelationship(rels, id, &rel3);
|
|
ok(SUCCEEDED(hr), "Failed to get relationship, hr %#x.\n", hr);
|
|
IOpcRelationship_Release(rel3);
|
|
|
|
hr = IOpcRelationshipSet_GetRelationship(rels, id, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
rel3 = (void *)0xdeadbeef;
|
|
hr = IOpcRelationshipSet_GetRelationship(rels, NULL, &rel3);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
ok(rel3 == NULL, "Expected null pointer.\n");
|
|
|
|
*id = 'r';
|
|
rel3 = (void *)0xdeadbeef;
|
|
hr = IOpcRelationshipSet_GetRelationship(rels, id, &rel3);
|
|
ok(hr == OPC_E_NO_SUCH_RELATIONSHIP, "Unexpected hr %#x.\n", hr);
|
|
ok(rel3 == NULL, "Expected null pointer.\n");
|
|
|
|
ret = TRUE;
|
|
hr = IOpcRelationshipSet_RelationshipExists(rels, id, &ret);
|
|
ok(SUCCEEDED(hr), "Unexpected hr %#x.\n", hr);
|
|
ok(!ret, "Unexpected result %d.\n", ret);
|
|
|
|
CoTaskMemFree(id);
|
|
|
|
hr = IOpcRelationship_GetTargetUri(rel, &uri);
|
|
ok(SUCCEEDED(hr), "Failed to get target uri, hr %#x.\n", hr);
|
|
ok(uri == target_uri, "Unexpected uri.\n");
|
|
IUri_Release(uri);
|
|
|
|
hr = IOpcRelationship_GetTargetMode(rel, &mode);
|
|
ok(SUCCEEDED(hr), "Failed to get target mode, hr %#x.\n", hr);
|
|
ok(mode == OPC_URI_TARGET_MODE_INTERNAL, "Unexpected mode %d.\n", mode);
|
|
|
|
/* Source uri */
|
|
hr = IOpcFactory_CreatePackageRootUri(factory, &source_uri);
|
|
ok(SUCCEEDED(hr), "Failed to create root uri, hr %#x.\n", hr);
|
|
|
|
hr = IOpcFactory_CreatePackageRootUri(factory, &source_uri2);
|
|
ok(SUCCEEDED(hr), "Failed to create root uri, hr %#x.\n", hr);
|
|
ok(source_uri != source_uri2, "Unexpected uri instance.\n");
|
|
|
|
IOpcUri_Release(source_uri);
|
|
IOpcUri_Release(source_uri2);
|
|
|
|
hr = IOpcRelationship_GetSourceUri(rel, &source_uri);
|
|
ok(SUCCEEDED(hr), "Failed to get source uri, hr %#x.\n", hr);
|
|
|
|
hr = IOpcUri_QueryInterface(source_uri, &IID_IOpcPartUri, (void **)&unk);
|
|
ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
|
|
|
|
str = NULL;
|
|
hr = IOpcUri_GetRawUri(source_uri, &str);
|
|
ok(SUCCEEDED(hr), "Failed to get raw uri, hr %#x.\n", hr);
|
|
ok(!lstrcmpW(rootW, str), "Unexpected uri %s.\n", wine_dbgstr_w(str));
|
|
SysFreeString(str);
|
|
|
|
hr = IOpcRelationship_GetSourceUri(rel2, &source_uri2);
|
|
ok(SUCCEEDED(hr), "Failed to get source uri, hr %#x.\n", hr);
|
|
ok(source_uri2 == source_uri, "Unexpected source uri.\n");
|
|
|
|
IOpcUri_Release(source_uri2);
|
|
IOpcUri_Release(source_uri);
|
|
|
|
IOpcRelationship_Release(rel2);
|
|
IOpcRelationship_Release(rel);
|
|
|
|
IOpcRelationshipSet_Release(rels);
|
|
|
|
IUri_Release(target_uri);
|
|
IUri_Release(target_uri2);
|
|
IOpcPackage_Release(package);
|
|
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" },
|
|
{ "/path/uri", "/path/_rels/uri.rels" },
|
|
{ "path/uri", "/path/_rels/uri.rels" },
|
|
{ "../path/uri", "/path/_rels/uri.rels" },
|
|
{ "../../path/uri", "/path/_rels/uri.rels" },
|
|
{ "/uri.ext", "/_rels/uri.ext.rels" },
|
|
{ "/", "/_rels/.rels" },
|
|
{ "uri", "/_rels/uri.rels" },
|
|
{ "/path/../uri", "/_rels/uri.rels" },
|
|
{ "/path/path/../../uri", "/_rels/uri.rels" },
|
|
{ "/_rels/uri.ext.rels", "", OPC_E_NONCONFORMING_URI },
|
|
};
|
|
static const struct
|
|
{
|
|
const char *uri;
|
|
BOOL ret;
|
|
} is_rel_part_tests[] =
|
|
{
|
|
{ "/uri", FALSE },
|
|
{ "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, NULL, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
ret = 123;
|
|
hr = IOpcUri_IsEqual(source_uri, NULL, &ret);
|
|
ok(is_root ? hr == E_POINTER : hr == S_OK, "Unexpected hr %#x.\n", hr);
|
|
ok(is_root ? ret == 123 : !ret, "Unexpected result.\n");
|
|
|
|
ret = FALSE;
|
|
hr = IOpcUri_IsEqual(source_uri, (IUri *)source_uri2, &ret);
|
|
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);
|
|
todo_wine_if(i == 3 || i == 4 || i == 8 || i == 9)
|
|
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);
|
|
}
|
|
|
|
static void test_part_enumerator(void)
|
|
{
|
|
static const WCHAR typeW[] = {'t','y','p','e','/','s','u','b','t','y','p','e',0};
|
|
static const WCHAR uriW[] = {'/','u','r','i',0};
|
|
IOpcPartEnumerator *partenum, *partenum2;
|
|
IOpcPart *part, *part2;
|
|
IOpcPartUri *part_uri;
|
|
IOpcPackage *package;
|
|
IOpcFactory *factory;
|
|
IOpcPartSet *parts;
|
|
HRESULT hr;
|
|
BOOL ret;
|
|
|
|
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))
|
|
{
|
|
IOpcFactory_Release(factory);
|
|
return;
|
|
}
|
|
|
|
hr = IOpcPackage_GetPartSet(package, &parts);
|
|
ok(SUCCEEDED(hr), "Failed to get part set, hr %#x.\n", hr);
|
|
|
|
hr = IOpcPartSet_GetEnumerator(parts, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
hr = IOpcPartSet_GetEnumerator(parts, &partenum);
|
|
ok(SUCCEEDED(hr), "Failed to get enumerator, hr %#x.\n", hr);
|
|
|
|
hr = IOpcPartSet_GetEnumerator(parts, &partenum2);
|
|
ok(SUCCEEDED(hr), "Failed to get enumerator, hr %#x.\n", hr);
|
|
ok(partenum != partenum2, "Unexpected instance.\n");
|
|
IOpcPartEnumerator_Release(partenum2);
|
|
|
|
hr = IOpcPartEnumerator_GetCurrent(partenum, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
hr = IOpcPartEnumerator_GetCurrent(partenum, &part);
|
|
ok(hr == OPC_E_ENUM_INVALID_POSITION, "Unexpected hr %#x.\n", hr);
|
|
|
|
hr = IOpcPartEnumerator_MoveNext(partenum, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
ret = TRUE;
|
|
hr = IOpcPartEnumerator_MoveNext(partenum, &ret);
|
|
ok(hr == S_OK, "Failed to move, hr %#x.\n", hr);
|
|
ok(!ret, "Unexpected result %d.\n", ret);
|
|
|
|
ret = TRUE;
|
|
hr = IOpcPartEnumerator_MovePrevious(partenum, &ret);
|
|
ok(hr == S_OK, "Failed to move, hr %#x.\n", hr);
|
|
ok(!ret, "Unexpected result %d.\n", ret);
|
|
|
|
hr = IOpcFactory_CreatePartUri(factory, uriW, &part_uri);
|
|
ok(SUCCEEDED(hr), "Failed to create part uri, hr %#x.\n", hr);
|
|
|
|
hr = IOpcPartSet_CreatePart(parts, part_uri, typeW, OPC_COMPRESSION_NONE, &part);
|
|
ok(SUCCEEDED(hr), "Failed to create a part, hr %#x.\n", hr);
|
|
IOpcPartUri_Release(part_uri);
|
|
|
|
part2 = (void *)0xdeadbeef;
|
|
hr = IOpcPartEnumerator_GetCurrent(partenum, &part2);
|
|
ok(hr == OPC_E_ENUM_COLLECTION_CHANGED, "Unexpected hr %#x.\n", hr);
|
|
ok(part2 == NULL, "Unexpected instance.\n");
|
|
|
|
hr = IOpcPartEnumerator_MoveNext(partenum, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
ret = 123;
|
|
hr = IOpcPartEnumerator_MoveNext(partenum, &ret);
|
|
ok(hr == OPC_E_ENUM_COLLECTION_CHANGED, "Unexpected hr %#x.\n", hr);
|
|
ok(ret == 123, "Unexpected result %d.\n", ret);
|
|
|
|
hr = IOpcPartEnumerator_MovePrevious(partenum, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
ret = 123;
|
|
hr = IOpcPartEnumerator_MovePrevious(partenum, &ret);
|
|
ok(hr == OPC_E_ENUM_COLLECTION_CHANGED, "Unexpected hr %#x.\n", hr);
|
|
ok(ret == 123, "Unexpected result %d.\n", ret);
|
|
|
|
hr = IOpcPartEnumerator_Clone(partenum, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
partenum2 = (void *)0xdeadbeef;
|
|
hr = IOpcPartEnumerator_Clone(partenum, &partenum2);
|
|
ok(hr == OPC_E_ENUM_COLLECTION_CHANGED, "Unexpected hr %#x.\n", hr);
|
|
ok(partenum2 == NULL, "Unexpected instance.\n");
|
|
|
|
IOpcPartEnumerator_Release(partenum);
|
|
|
|
hr = IOpcPartSet_GetEnumerator(parts, &partenum);
|
|
ok(SUCCEEDED(hr), "Failed to get enumerator, hr %#x.\n", hr);
|
|
|
|
part2 = (void *)0xdeadbeef;
|
|
hr = IOpcPartEnumerator_GetCurrent(partenum, &part2);
|
|
ok(hr == OPC_E_ENUM_INVALID_POSITION, "Unexpected hr %#x.\n", hr);
|
|
ok(part2 == NULL, "Unexpected instance.\n");
|
|
|
|
hr = IOpcPartEnumerator_MoveNext(partenum, &ret);
|
|
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
|
ok(ret, "Unexpected result %d.\n", ret);
|
|
|
|
hr = IOpcPartEnumerator_GetCurrent(partenum, &part2);
|
|
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
|
ok(part2 == part, "Unexpected instance.\n");
|
|
IOpcPart_Release(part2);
|
|
|
|
hr = IOpcPartEnumerator_MoveNext(partenum, &ret);
|
|
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
|
ok(!ret, "Unexpected result %d.\n", ret);
|
|
|
|
part2 = (void *)0xdeadbeef;
|
|
hr = IOpcPartEnumerator_GetCurrent(partenum, &part2);
|
|
ok(hr == OPC_E_ENUM_INVALID_POSITION, "Unexpected hr %#x.\n", hr);
|
|
ok(part2 == NULL, "Unexpected instance.\n");
|
|
|
|
hr = IOpcPartEnumerator_MovePrevious(partenum, &ret);
|
|
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
|
ok(ret, "Unexpected result %d.\n", ret);
|
|
|
|
hr = IOpcPartEnumerator_GetCurrent(partenum, &part2);
|
|
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
|
ok(part2 == part, "Unexpected instance.\n");
|
|
IOpcPart_Release(part2);
|
|
|
|
hr = IOpcPartEnumerator_MovePrevious(partenum, &ret);
|
|
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
|
ok(!ret, "Unexpected result %d.\n", ret);
|
|
|
|
hr = IOpcPartEnumerator_GetCurrent(partenum, &part2);
|
|
ok(hr == OPC_E_ENUM_INVALID_POSITION, "Unexpected hr %#x.\n", hr);
|
|
|
|
hr = IOpcPartEnumerator_Clone(partenum, &partenum2);
|
|
ok(SUCCEEDED(hr), "Clone failed, hr %#x.\n", hr);
|
|
|
|
hr = IOpcPartEnumerator_MoveNext(partenum2, &ret);
|
|
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
|
ok(ret, "Unexpected result %d.\n", ret);
|
|
|
|
hr = IOpcPartEnumerator_GetCurrent(partenum2, &part2);
|
|
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
|
IOpcPart_Release(part2);
|
|
|
|
hr = IOpcPartEnumerator_GetCurrent(partenum, &part2);
|
|
ok(hr == OPC_E_ENUM_INVALID_POSITION, "Unexpected hr %#x.\n", hr);
|
|
|
|
IOpcPartEnumerator_Release(partenum2);
|
|
|
|
IOpcPartEnumerator_Release(partenum);
|
|
|
|
IOpcPart_Release(part);
|
|
|
|
IOpcPartSet_Release(parts);
|
|
|
|
IOpcPackage_Release(package);
|
|
IOpcFactory_Release(factory);
|
|
}
|
|
|
|
static void test_rels_enumerator(void)
|
|
{
|
|
static const WCHAR typeW[] = {'t','y','p','e','/','s','u','b','t','y','p','e',0};
|
|
static const WCHAR targetW[] = {'t','a','r','g','e','t',0};
|
|
IOpcRelationshipEnumerator *relsenum, *relsenum2;
|
|
IOpcRelationship *rel, *rel2;
|
|
IOpcPackage *package;
|
|
IOpcFactory *factory;
|
|
IOpcRelationshipSet *rels;
|
|
IUri *target_uri;
|
|
HRESULT hr;
|
|
BOOL ret;
|
|
|
|
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))
|
|
{
|
|
IOpcFactory_Release(factory);
|
|
return;
|
|
}
|
|
|
|
hr = IOpcPackage_GetRelationshipSet(package, &rels);
|
|
ok(SUCCEEDED(hr), "Failed to get part set, hr %#x.\n", hr);
|
|
|
|
hr = IOpcRelationshipSet_GetEnumerator(rels, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
hr = IOpcRelationshipSet_GetEnumerator(rels, &relsenum);
|
|
ok(SUCCEEDED(hr), "Failed to get enumerator, hr %#x.\n", hr);
|
|
|
|
hr = IOpcRelationshipSet_GetEnumerator(rels, &relsenum2);
|
|
ok(SUCCEEDED(hr), "Failed to get enumerator, hr %#x.\n", hr);
|
|
ok(relsenum != relsenum2, "Unexpected instance.\n");
|
|
IOpcRelationshipEnumerator_Release(relsenum2);
|
|
|
|
hr = IOpcRelationshipEnumerator_GetCurrent(relsenum, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
hr = IOpcRelationshipEnumerator_GetCurrent(relsenum, &rel);
|
|
ok(hr == OPC_E_ENUM_INVALID_POSITION, "Unexpected hr %#x.\n", hr);
|
|
|
|
hr = IOpcRelationshipEnumerator_MoveNext(relsenum, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
ret = TRUE;
|
|
hr = IOpcRelationshipEnumerator_MoveNext(relsenum, &ret);
|
|
ok(hr == S_OK, "Failed to move, hr %#x.\n", hr);
|
|
ok(!ret, "Unexpected result %d.\n", ret);
|
|
|
|
ret = TRUE;
|
|
hr = IOpcRelationshipEnumerator_MovePrevious(relsenum, &ret);
|
|
ok(hr == S_OK, "Failed to move, hr %#x.\n", hr);
|
|
ok(!ret, "Unexpected result %d.\n", ret);
|
|
|
|
hr = CreateUri(targetW, Uri_CREATE_ALLOW_RELATIVE, 0, &target_uri);
|
|
ok(SUCCEEDED(hr), "Failed to create target uri, 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);
|
|
|
|
IUri_Release(target_uri);
|
|
|
|
rel2 = (void *)0xdeadbeef;
|
|
hr = IOpcRelationshipEnumerator_GetCurrent(relsenum, &rel2);
|
|
ok(hr == OPC_E_ENUM_COLLECTION_CHANGED, "Unexpected hr %#x.\n", hr);
|
|
ok(rel2 == NULL, "Unexpected instance.\n");
|
|
|
|
hr = IOpcRelationshipEnumerator_MoveNext(relsenum, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
ret = 123;
|
|
hr = IOpcRelationshipEnumerator_MoveNext(relsenum, &ret);
|
|
ok(hr == OPC_E_ENUM_COLLECTION_CHANGED, "Unexpected hr %#x.\n", hr);
|
|
ok(ret == 123, "Unexpected result %d.\n", ret);
|
|
|
|
hr = IOpcRelationshipEnumerator_MovePrevious(relsenum, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
ret = 123;
|
|
hr = IOpcRelationshipEnumerator_MovePrevious(relsenum, &ret);
|
|
ok(hr == OPC_E_ENUM_COLLECTION_CHANGED, "Unexpected hr %#x.\n", hr);
|
|
ok(ret == 123, "Unexpected result %d.\n", ret);
|
|
|
|
hr = IOpcRelationshipEnumerator_Clone(relsenum, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
relsenum2 = (void *)0xdeadbeef;
|
|
hr = IOpcRelationshipEnumerator_Clone(relsenum, &relsenum2);
|
|
ok(hr == OPC_E_ENUM_COLLECTION_CHANGED, "Unexpected hr %#x.\n", hr);
|
|
ok(relsenum2 == NULL, "Unexpected instance.\n");
|
|
|
|
IOpcRelationshipEnumerator_Release(relsenum);
|
|
|
|
hr = IOpcRelationshipSet_GetEnumerator(rels, &relsenum);
|
|
ok(SUCCEEDED(hr), "Failed to get enumerator, hr %#x.\n", hr);
|
|
|
|
rel2 = (void *)0xdeadbeef;
|
|
hr = IOpcRelationshipEnumerator_GetCurrent(relsenum, &rel2);
|
|
ok(hr == OPC_E_ENUM_INVALID_POSITION, "Unexpected hr %#x.\n", hr);
|
|
ok(rel2 == NULL, "Unexpected instance.\n");
|
|
|
|
hr = IOpcRelationshipEnumerator_MoveNext(relsenum, &ret);
|
|
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
|
ok(ret, "Unexpected result %d.\n", ret);
|
|
|
|
hr = IOpcRelationshipEnumerator_GetCurrent(relsenum, &rel2);
|
|
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
|
ok(rel2 == rel, "Unexpected instance.\n");
|
|
IOpcRelationship_Release(rel2);
|
|
|
|
hr = IOpcRelationshipEnumerator_MoveNext(relsenum, &ret);
|
|
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
|
ok(!ret, "Unexpected result %d.\n", ret);
|
|
|
|
rel2 = (void *)0xdeadbeef;
|
|
hr = IOpcRelationshipEnumerator_GetCurrent(relsenum, &rel2);
|
|
ok(hr == OPC_E_ENUM_INVALID_POSITION, "Unexpected hr %#x.\n", hr);
|
|
ok(rel2 == NULL, "Unexpected instance.\n");
|
|
|
|
hr = IOpcRelationshipEnumerator_MovePrevious(relsenum, &ret);
|
|
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
|
ok(ret, "Unexpected result %d.\n", ret);
|
|
|
|
hr = IOpcRelationshipEnumerator_GetCurrent(relsenum, &rel2);
|
|
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
|
ok(rel2 == rel, "Unexpected instance.\n");
|
|
IOpcRelationship_Release(rel2);
|
|
|
|
hr = IOpcRelationshipEnumerator_MovePrevious(relsenum, &ret);
|
|
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
|
ok(!ret, "Unexpected result %d.\n", ret);
|
|
|
|
hr = IOpcRelationshipEnumerator_GetCurrent(relsenum, &rel2);
|
|
ok(hr == OPC_E_ENUM_INVALID_POSITION, "Unexpected hr %#x.\n", hr);
|
|
|
|
hr = IOpcRelationshipEnumerator_Clone(relsenum, &relsenum2);
|
|
ok(SUCCEEDED(hr), "Clone failed, hr %#x.\n", hr);
|
|
|
|
hr = IOpcRelationshipEnumerator_MoveNext(relsenum2, &ret);
|
|
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
|
ok(ret, "Unexpected result %d.\n", ret);
|
|
|
|
hr = IOpcRelationshipEnumerator_GetCurrent(relsenum2, &rel2);
|
|
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
|
IOpcRelationship_Release(rel2);
|
|
|
|
hr = IOpcRelationshipEnumerator_GetCurrent(relsenum, &rel2);
|
|
ok(hr == OPC_E_ENUM_INVALID_POSITION, "Unexpected hr %#x.\n", hr);
|
|
|
|
IOpcRelationshipEnumerator_Release(relsenum2);
|
|
|
|
IOpcRelationshipEnumerator_Release(relsenum);
|
|
|
|
IOpcRelationship_Release(rel);
|
|
|
|
IOpcRelationshipSet_Release(rels);
|
|
|
|
IOpcPackage_Release(package);
|
|
IOpcFactory_Release(factory);
|
|
}
|
|
|
|
static void test_relative_uri(void)
|
|
{
|
|
static const struct
|
|
{
|
|
const char *part;
|
|
const char *combined;
|
|
const char *relative;
|
|
const char *relative_broken;
|
|
}
|
|
relative_uri_tests[] =
|
|
{
|
|
{ "/", "/path/path2", "path/path2", "/path/path2" },
|
|
{ "/", "/path", "path", "/path" },
|
|
{ "/path/path2", "/path/path2/path3", "path2/path3" },
|
|
{ "/path/path2", "/path3", "../path3" },
|
|
{ "/path", "/path", "" },
|
|
{ "/path", "../path", "" },
|
|
{ "/path2", "/path", "path" },
|
|
{ "../path", "/path", "" },
|
|
{ "../../path", "/path", "" },
|
|
};
|
|
IOpcFactory *factory;
|
|
unsigned int i;
|
|
|
|
factory = create_factory();
|
|
|
|
for (i = 0; i < ARRAY_SIZE(relative_uri_tests); ++i)
|
|
{
|
|
WCHAR *uriW, *combinedW, *relativeW, *relative_broken_W;
|
|
IOpcPartUri *combined_uri;
|
|
IUri *relative_uri;
|
|
IOpcUri *part_uri;
|
|
IUnknown *unk;
|
|
HRESULT hr;
|
|
BSTR str;
|
|
|
|
uriW = strdupAtoW(relative_uri_tests[i].part);
|
|
combinedW = strdupAtoW(relative_uri_tests[i].combined);
|
|
relativeW = strdupAtoW(relative_uri_tests[i].relative);
|
|
relative_broken_W = strdupAtoW(relative_uri_tests[i].relative_broken);
|
|
|
|
if (!strcmp(relative_uri_tests[i].part, "/"))
|
|
hr = IOpcFactory_CreatePackageRootUri(factory, &part_uri);
|
|
else
|
|
hr = IOpcFactory_CreatePartUri(factory, uriW, (IOpcPartUri **)&part_uri);
|
|
ok(SUCCEEDED(hr), "%u: failed to create part uri, hr %#x.\n", i, hr);
|
|
|
|
hr = IOpcFactory_CreatePartUri(factory, combinedW, &combined_uri);
|
|
ok(SUCCEEDED(hr), "%u: failed to create part uri, hr %#x.\n", i, hr);
|
|
|
|
hr = IOpcUri_GetRelativeUri(part_uri, combined_uri, &relative_uri);
|
|
todo_wine
|
|
ok(SUCCEEDED(hr), "%u: failed t oget relative uri, hr %#x.\n", i, hr);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = IUri_QueryInterface(relative_uri, &IID_IOpcUri, (void **)&unk);
|
|
ok(hr == E_NOINTERFACE, "%u: unexpected hr %#x.\n", i, hr);
|
|
|
|
hr = IUri_GetRawUri(relative_uri, &str);
|
|
ok(SUCCEEDED(hr), "%u: failed to get raw uri, hr %#x.\n", i, hr);
|
|
ok(!lstrcmpW(str, relativeW) || broken(relative_broken_W && !lstrcmpW(str, relative_broken_W)),
|
|
"%u: unexpected relative uri %s.\n", i, wine_dbgstr_w(str));
|
|
SysFreeString(str);
|
|
|
|
IUri_Release(relative_uri);
|
|
}
|
|
IOpcUri_Release(part_uri);
|
|
IOpcPartUri_Release(combined_uri);
|
|
|
|
heap_free(uriW);
|
|
heap_free(combinedW);
|
|
heap_free(relativeW);
|
|
heap_free(relative_broken_W);
|
|
}
|
|
|
|
IOpcFactory_Release(factory);
|
|
}
|
|
|
|
static void test_combine_uri(void)
|
|
{
|
|
static const struct
|
|
{
|
|
const char *uri;
|
|
const char *relative;
|
|
const char *combined;
|
|
}
|
|
combine_tests[] =
|
|
{
|
|
{ "/", "path", "/path" },
|
|
{ "/path1", "path2", "/path2" },
|
|
{ "/path1", "../path2", "/path2" },
|
|
{ "/path1/../path2", "path3", "/path3" },
|
|
};
|
|
IOpcFactory *factory;
|
|
unsigned int i;
|
|
|
|
factory = create_factory();
|
|
|
|
for (i = 0; i < ARRAY_SIZE(combine_tests); ++i)
|
|
{
|
|
WCHAR *uriW, *relativeW, *combinedW;
|
|
IOpcPartUri *combined_uri;
|
|
IUri *relative_uri;
|
|
IOpcUri *uri;
|
|
HRESULT hr;
|
|
BSTR str;
|
|
|
|
uriW = strdupAtoW(combine_tests[i].uri);
|
|
relativeW = strdupAtoW(combine_tests[i].relative);
|
|
combinedW = strdupAtoW(combine_tests[i].combined);
|
|
|
|
if (!strcmp(combine_tests[i].uri, "/"))
|
|
hr = IOpcFactory_CreatePackageRootUri(factory, &uri);
|
|
else
|
|
hr = IOpcFactory_CreatePartUri(factory, uriW, (IOpcPartUri **)&uri);
|
|
ok(SUCCEEDED(hr), "%u: failed to create uri, hr %#x.\n", i, hr);
|
|
|
|
hr = CreateUri(relativeW, Uri_CREATE_ALLOW_RELATIVE, 0, &relative_uri);
|
|
ok(SUCCEEDED(hr), "%u: failed to create relative uri, hr %#x.\n", i, hr);
|
|
|
|
combined_uri = (void *)0xdeadbeef;
|
|
hr = IOpcUri_CombinePartUri(uri, NULL, &combined_uri);
|
|
ok(hr == E_POINTER, "%u: failed to combine uris, hr %#x.\n", i, hr);
|
|
ok(!combined_uri, "Unexpected instance.\n");
|
|
|
|
hr = IOpcUri_CombinePartUri(uri, relative_uri, NULL);
|
|
ok(hr == E_POINTER, "%u: failed to combine uris, hr %#x.\n", i, hr);
|
|
|
|
hr = IOpcUri_CombinePartUri(uri, relative_uri, &combined_uri);
|
|
ok(SUCCEEDED(hr), "%u: failed to combine uris, hr %#x.\n", i, hr);
|
|
|
|
hr = IOpcPartUri_GetRawUri(combined_uri, &str);
|
|
ok(SUCCEEDED(hr), "%u: failed to get raw uri, hr %#x.\n", i, hr);
|
|
todo_wine_if(i == 2 || i == 3)
|
|
ok(!lstrcmpW(str, combinedW), "%u: unexpected uri %s.\n", i, wine_dbgstr_w(str));
|
|
SysFreeString(str);
|
|
|
|
IOpcPartUri_Release(combined_uri);
|
|
|
|
heap_free(uriW);
|
|
heap_free(relativeW);
|
|
heap_free(combinedW);
|
|
|
|
IOpcUri_Release(uri);
|
|
IUri_Release(relative_uri);
|
|
}
|
|
|
|
IOpcFactory_Release(factory);
|
|
}
|
|
|
|
static void test_create_part_uri(void)
|
|
{
|
|
static const struct
|
|
{
|
|
const char *input;
|
|
const char *raw_uri;
|
|
}
|
|
create_part_uri_tests[] =
|
|
{
|
|
{ "path", "/path" },
|
|
{ "../path", "/path" },
|
|
{ "../../path", "/path" },
|
|
{ "/path", "/path" },
|
|
{ "/path1/path2/path3/../path4", "/path1/path2/path4" },
|
|
};
|
|
IOpcFactory *factory;
|
|
unsigned int i;
|
|
HRESULT hr;
|
|
|
|
factory = create_factory();
|
|
|
|
for (i = 0; i < ARRAY_SIZE(create_part_uri_tests); ++i)
|
|
{
|
|
IOpcPartUri *part_uri;
|
|
WCHAR *inputW, *rawW;
|
|
IUri *uri;
|
|
BSTR str;
|
|
BOOL ret;
|
|
|
|
inputW = strdupAtoW(create_part_uri_tests[i].input);
|
|
rawW = strdupAtoW(create_part_uri_tests[i].raw_uri);
|
|
|
|
hr = IOpcFactory_CreatePartUri(factory, inputW, &part_uri);
|
|
ok(SUCCEEDED(hr), "%u: failed to create part uri, hr %#x.\n", i, hr);
|
|
|
|
hr = IOpcPartUri_GetRawUri(part_uri, &str);
|
|
ok(SUCCEEDED(hr), "Failed to get raw uri, hr %#x.\n", hr);
|
|
todo_wine_if(i == 1 || i == 2 || i == 4)
|
|
ok(!lstrcmpW(str, rawW), "%u: unexpected raw uri %s.\n", i, wine_dbgstr_w(str));
|
|
SysFreeString(str);
|
|
|
|
hr = CreateUri(rawW, Uri_CREATE_ALLOW_RELATIVE, 0, &uri);
|
|
ok(SUCCEEDED(hr), "Failed to create uri, hr %#x.\n", hr);
|
|
|
|
ret = FALSE;
|
|
hr = IOpcPartUri_IsEqual(part_uri, uri, &ret);
|
|
ok(SUCCEEDED(hr), "IsEqual failed, hr %#x.\n", hr);
|
|
todo_wine_if(i == 1 || i == 2 || i == 4)
|
|
ok(!!ret, "%u: unexpected result %d.\n", i, ret);
|
|
|
|
IOpcPartUri_Release(part_uri);
|
|
IUri_Release(uri);
|
|
|
|
heap_free(inputW);
|
|
heap_free(rawW);
|
|
}
|
|
|
|
IOpcFactory_Release(factory);
|
|
}
|
|
|
|
static HRESULT WINAPI custom_package_QueryInterface(IOpcPackage *iface, REFIID iid, void **out)
|
|
{
|
|
if (IsEqualIID(iid, &IID_IOpcPackage) || IsEqualIID(iid, &IID_IUnknown))
|
|
{
|
|
*out = iface;
|
|
IOpcPackage_AddRef(iface);
|
|
return S_OK;
|
|
}
|
|
|
|
*out = NULL;
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
static ULONG WINAPI custom_package_AddRef(IOpcPackage *iface)
|
|
{
|
|
return 2;
|
|
}
|
|
|
|
static ULONG WINAPI custom_package_Release(IOpcPackage *iface)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
static HRESULT WINAPI custom_package_GetPartSet(IOpcPackage *iface, IOpcPartSet **part_set)
|
|
{
|
|
return 0x80000001;
|
|
}
|
|
|
|
static HRESULT WINAPI custom_package_GetRelationshipSet(IOpcPackage *iface, IOpcRelationshipSet **relationship_set)
|
|
{
|
|
return 0x80000001;
|
|
}
|
|
|
|
static const IOpcPackageVtbl custom_package_vtbl =
|
|
{
|
|
custom_package_QueryInterface,
|
|
custom_package_AddRef,
|
|
custom_package_Release,
|
|
custom_package_GetPartSet,
|
|
custom_package_GetRelationshipSet,
|
|
};
|
|
|
|
static void test_write_package(void)
|
|
{
|
|
IOpcPackage custom_package = { &custom_package_vtbl };
|
|
IOpcFactory *factory;
|
|
IOpcPackage *package;
|
|
IStream *stream;
|
|
HRESULT hr;
|
|
|
|
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))
|
|
{
|
|
IOpcFactory_Release(factory);
|
|
return;
|
|
}
|
|
|
|
hr = IOpcFactory_WritePackageToStream(factory, NULL, OPC_WRITE_FORCE_ZIP32, NULL);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
|
|
ok(SUCCEEDED(hr), "Failed to create a stream, hr %#x.\n", hr);
|
|
|
|
hr = IOpcFactory_WritePackageToStream(factory, NULL, OPC_WRITE_FORCE_ZIP32, stream);
|
|
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
|
|
|
|
hr = IOpcFactory_WritePackageToStream(factory, &custom_package, OPC_WRITE_FORCE_ZIP32, stream);
|
|
ok(hr == 0x80000001, "Unexpected hr %#x.\n", hr);
|
|
|
|
IStream_Release(stream);
|
|
|
|
IOpcFactory_Release(factory);
|
|
IOpcPackage_Release(package);
|
|
}
|
|
|
|
START_TEST(opcservices)
|
|
{
|
|
IOpcFactory *factory;
|
|
HRESULT hr;
|
|
|
|
hr = CoInitialize(NULL);
|
|
ok(SUCCEEDED(hr), "Failed to initialize COM, hr %#x.\n", hr);
|
|
|
|
if (!(factory = create_factory())) {
|
|
win_skip("Failed to create IOpcFactory factory.\n");
|
|
CoUninitialize();
|
|
return;
|
|
}
|
|
|
|
test_package();
|
|
test_file_stream();
|
|
test_relationship();
|
|
test_rel_part_uri();
|
|
test_part_enumerator();
|
|
test_rels_enumerator();
|
|
test_relative_uri();
|
|
test_combine_uri();
|
|
test_create_part_uri();
|
|
test_write_package();
|
|
|
|
IOpcFactory_Release(factory);
|
|
|
|
CoUninitialize();
|
|
}
|