4 * Copyright 2018 Nikolay Sivov for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "wine/heap.h"
29 #include "wine/test.h"
31 static IOpcFactory
*create_factory(void)
33 IOpcFactory
*factory
= NULL
;
34 CoCreateInstance(&CLSID_OpcFactory
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IOpcFactory
, (void **)&factory
);
38 static void test_package(void)
40 static const WCHAR typeW
[] = {'t','y','p','e','/','s','u','b','t','y','p','e',0};
41 static const WCHAR targetW
[] = {'t','a','r','g','e','t',0};
42 static const WCHAR uriW
[] = {'/','u','r','i',0};
43 static const WCHAR rootW
[] = {'/',0};
44 IOpcRelationshipSet
*relset
, *relset2
;
45 IOpcPartUri
*part_uri
, *part_uri2
;
46 IOpcPartSet
*partset
, *partset2
;
47 OPC_COMPRESSION_OPTIONS options
;
48 IStream
*stream
, *stream2
;
49 IOpcPart
*part
, *part2
;
50 IOpcRelationship
*rel
;
62 factory
= create_factory();
64 hr
= IOpcFactory_CreatePackage(factory
, &package
);
65 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
) /* Vista */, "Failed to create a package, hr %#x.\n", hr
);
68 IOpcFactory_Release(factory
);
72 hr
= IOpcPackage_GetPartSet(package
, &partset
);
73 ok(SUCCEEDED(hr
), "Failed to create a part set, hr %#x.\n", hr
);
75 hr
= IOpcPackage_GetPartSet(package
, &partset2
);
76 ok(SUCCEEDED(hr
), "Failed to create a part set, hr %#x.\n", hr
);
77 ok(partset
== partset2
, "Expected same part set instance.\n");
78 IOpcPartSet_Release(partset2
);
81 hr
= IOpcFactory_CreatePartUri(factory
, uriW
, &part_uri
);
82 ok(SUCCEEDED(hr
), "Failed to create part uri, hr %#x.\n", hr
);
84 hr
= IOpcFactory_CreatePartUri(factory
, uriW
, &part_uri2
);
85 ok(SUCCEEDED(hr
), "Failed to create part uri, hr %#x.\n", hr
);
87 part
= (void *)0xdeadbeef;
88 hr
= IOpcPartSet_CreatePart(partset
, NULL
, typeW
, OPC_COMPRESSION_NONE
, &part
);
89 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
90 ok(part
== NULL
, "Unexpected pointer %p.\n", part
);
92 hr
= IOpcPartSet_CreatePart(partset
, part_uri
, typeW
, OPC_COMPRESSION_NONE
, NULL
);
93 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
95 hr
= IOpcPartSet_CreatePart(partset
, part_uri
, typeW
, 0xdeadbeef, &part
);
96 ok(SUCCEEDED(hr
), "Failed to create a part, hr %#x.\n", hr
);
97 hr
= IOpcPart_GetCompressionOptions(part
, &options
);
98 ok(SUCCEEDED(hr
), "Failed to get compression options, hr %#x.\n", hr
);
99 ok(options
== 0xdeadbeef, "Unexpected compression options %#x.\n", options
);
101 part2
= (void *)0xdeadbeef;
102 hr
= IOpcPartSet_CreatePart(partset
, part_uri
, typeW
, OPC_COMPRESSION_NONE
, &part2
);
103 ok(hr
== OPC_E_DUPLICATE_PART
, "Unexpected hr %#x.\n", hr
);
104 ok(part2
== NULL
, "Unexpected instance %p.\n", part2
);
106 part2
= (void *)0xdeadbeef;
107 hr
= IOpcPartSet_CreatePart(partset
, part_uri2
, typeW
, OPC_COMPRESSION_NONE
, &part2
);
108 ok(hr
== OPC_E_DUPLICATE_PART
, "Unexpected hr %#x.\n", hr
);
109 ok(part2
== NULL
, "Unexpected instance %p.\n", part2
);
110 IOpcPartUri_Release(part_uri2
);
112 hr
= IOpcPartSet_GetPart(partset
, NULL
, NULL
);
113 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
115 part2
= (void *)0xdeadbeef;
116 hr
= IOpcPartSet_GetPart(partset
, NULL
, &part2
);
117 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
118 ok(part2
== NULL
, "Unexpected pointer %p.\n", part2
);
120 hr
= IOpcPartSet_GetPart(partset
, part_uri
, NULL
);
121 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
123 hr
= IOpcPartSet_GetPart(partset
, part_uri
, &part2
);
124 ok(SUCCEEDED(hr
), "Failed to get part, hr %#x.\n", hr
);
125 IOpcPart_Release(part2
);
127 hr
= IOpcFactory_CreatePartUri(factory
, targetW
, &part_uri2
);
128 ok(SUCCEEDED(hr
), "Failed to create part uri, hr %#x.\n", hr
);
130 hr
= IOpcPartSet_GetPart(partset
, part_uri2
, &part2
);
131 ok(hr
== OPC_E_NO_SUCH_PART
, "Unexpected hr %#x.\n", hr
);
132 IOpcPartUri_Release(part_uri2
);
134 hr
= IOpcPart_GetContentStream(part
, NULL
);
135 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
137 hr
= IOpcPart_GetContentStream(part
, &stream
);
138 ok(SUCCEEDED(hr
), "Failed to get content stream, hr %#x.\n", hr
);
140 hr
= IStream_Write(stream
, "abc", 3, NULL
);
141 ok(hr
== S_OK
, "Failed to write content, hr %#x.\n", hr
);
144 hr
= IStream_Seek(stream
, move
, STREAM_SEEK_CUR
, &pos
);
145 ok(SUCCEEDED(hr
), "Seek failed, hr %#x.\n", hr
);
146 ok(pos
.QuadPart
== 3, "Unexpected position.\n");
148 hr
= IOpcPart_GetContentStream(part
, &stream2
);
149 ok(SUCCEEDED(hr
), "Failed to get content stream, hr %#x.\n", hr
);
150 ok(stream
!= stream2
, "Unexpected instance.\n");
153 hr
= IStream_Seek(stream2
, move
, STREAM_SEEK_CUR
, &pos
);
154 ok(SUCCEEDED(hr
), "Seek failed, hr %#x.\n", hr
);
155 ok(pos
.QuadPart
== 0, "Unexpected position.\n");
157 memset(buff
, 0, sizeof(buff
));
158 hr
= IStream_Read(stream2
, buff
, sizeof(buff
), NULL
);
159 ok(hr
== S_OK
, "Failed to read content, hr %#x.\n", hr
);
160 ok(!memcmp(buff
, "abc", 3), "Unexpected content.\n");
163 hr
= IStream_Seek(stream2
, move
, STREAM_SEEK_CUR
, &pos
);
164 ok(SUCCEEDED(hr
), "Seek failed, hr %#x.\n", hr
);
165 ok(pos
.QuadPart
== 3, "Unexpected position.\n");
167 IStream_Release(stream
);
168 IStream_Release(stream2
);
170 hr
= IOpcPart_GetRelationshipSet(part
, &relset
);
171 ok(SUCCEEDED(hr
), "Failed to get relationship set, hr %#x.\n", hr
);
173 hr
= IOpcPart_GetRelationshipSet(part
, &relset2
);
174 ok(SUCCEEDED(hr
), "Failed to get relationship set, hr %#x.\n", hr
);
175 ok(relset
== relset2
, "Expected same part set instance.\n");
177 hr
= CreateUri(targetW
, Uri_CREATE_ALLOW_RELATIVE
, 0, &target_uri
);
178 ok(SUCCEEDED(hr
), "Failed to create target uri, hr %#x.\n", hr
);
180 hr
= IOpcRelationshipSet_CreateRelationship(relset
, NULL
, typeW
, target_uri
, OPC_URI_TARGET_MODE_INTERNAL
, &rel
);
181 ok(SUCCEEDED(hr
), "Failed to create relationship, hr %#x.\n", hr
);
183 hr
= IOpcRelationship_GetSourceUri(rel
, &uri
);
184 ok(SUCCEEDED(hr
), "Failed to get source uri, hr %#x.\n", hr
);
185 ok(uri
== (IOpcUri
*)part_uri
, "Unexpected source uri.\n");
187 IOpcUri_Release(uri
);
189 IOpcRelationship_Release(rel
);
190 IUri_Release(target_uri
);
192 IOpcRelationshipSet_Release(relset
);
193 IOpcRelationshipSet_Release(relset2
);
196 hr
= IOpcPartSet_PartExists(partset
, NULL
, &ret
);
197 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
198 ok(ret
== 123, "Unexpected return value.\n");
200 hr
= IOpcPartSet_PartExists(partset
, part_uri
, NULL
);
201 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
204 hr
= IOpcPartSet_PartExists(partset
, part_uri
, &ret
);
205 ok(SUCCEEDED(hr
), "Unexpected hr %#x.\n", hr
);
206 ok(ret
, "Expected part to exist.\n");
208 IOpcPartUri_Release(part_uri
);
209 IOpcPart_Release(part
);
212 hr
= IOpcPackage_GetRelationshipSet(package
, &relset
);
213 ok(SUCCEEDED(hr
), "Failed to get relationship set, hr %#x.\n", hr
);
215 hr
= IOpcPackage_GetRelationshipSet(package
, &relset2
);
216 ok(SUCCEEDED(hr
), "Failed to get relationship set, hr %#x.\n", hr
);
217 ok(relset
== relset2
, "Expected same part set instance.\n");
218 IOpcRelationshipSet_Release(relset
);
219 IOpcRelationshipSet_Release(relset2
);
221 IOpcPartSet_Release(partset
);
222 IOpcPackage_Release(package
);
225 hr
= IOpcFactory_CreatePackageRootUri(factory
, NULL
);
226 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
227 hr
= IOpcFactory_CreatePackageRootUri(factory
, &uri
);
228 ok(SUCCEEDED(hr
), "Failed to create root uri, hr %#x.\n", hr
);
229 hr
= IOpcUri_GetRawUri(uri
, &str
);
230 ok(SUCCEEDED(hr
), "Failed to get raw uri, hr %#x.\n", hr
);
231 ok(!lstrcmpW(str
, rootW
), "Unexpected uri %s.\n", wine_dbgstr_w(str
));
233 IOpcUri_Release(uri
);
235 IOpcFactory_Release(factory
);
238 #define test_stream_stat(stream, size) test_stream_stat_(__LINE__, stream, size)
239 static void test_stream_stat_(unsigned int line
, IStream
*stream
, ULONG size
)
244 hr
= IStream_Stat(stream
, NULL
, 0);
245 ok_(__FILE__
, line
)(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
247 memset(&statstg
, 0xff, sizeof(statstg
));
248 hr
= IStream_Stat(stream
, &statstg
, 0);
249 ok_(__FILE__
, line
)(SUCCEEDED(hr
), "Failed to get stat info, hr %#x.\n", hr
);
251 ok_(__FILE__
, line
)(statstg
.pwcsName
== NULL
, "Unexpected name %s.\n", wine_dbgstr_w(statstg
.pwcsName
));
252 ok_(__FILE__
, line
)(statstg
.type
== STGTY_STREAM
, "Unexpected type.\n");
253 ok_(__FILE__
, line
)(statstg
.cbSize
.QuadPart
== size
, "Unexpected size %u, expected %u.\n",
254 statstg
.cbSize
.LowPart
, size
);
255 ok_(__FILE__
, line
)(statstg
.grfMode
== STGM_READ
, "Unexpected mode.\n");
256 ok_(__FILE__
, line
)(statstg
.grfLocksSupported
== 0, "Unexpected lock mode.\n");
257 ok_(__FILE__
, line
)(statstg
.grfStateBits
== 0, "Unexpected state bits.\n");
260 static void test_file_stream(void)
262 static const WCHAR filereadW
[] = {'o','p','c','f','i','l','e','r','e','a','d','.','e','x','t',0};
263 WCHAR temppathW
[MAX_PATH
], pathW
[MAX_PATH
];
264 IOpcFactory
*factory
;
271 factory
= create_factory();
273 hr
= IOpcFactory_CreateStreamOnFile(factory
, NULL
, OPC_STREAM_IO_READ
, NULL
, 0, &stream
);
274 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
276 GetTempPathW(ARRAY_SIZE(temppathW
), temppathW
);
277 lstrcpyW(pathW
, temppathW
);
278 lstrcatW(pathW
, filereadW
);
281 hr
= IOpcFactory_CreateStreamOnFile(factory
, pathW
, OPC_STREAM_IO_READ
, NULL
, 0, NULL
);
282 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
284 /* File does not exist */
285 hr
= IOpcFactory_CreateStreamOnFile(factory
, pathW
, OPC_STREAM_IO_READ
, NULL
, 0, &stream
);
286 ok(FAILED(hr
), "Unexpected hr %#x.\n", hr
);
288 hr
= IOpcFactory_CreateStreamOnFile(factory
, pathW
, OPC_STREAM_IO_WRITE
, NULL
, 0, &stream
);
289 ok(SUCCEEDED(hr
), "Failed to create a write stream, hr %#x.\n", hr
);
291 test_stream_stat(stream
, 0);
293 size
= lstrlenW(pathW
) * sizeof(WCHAR
);
294 hr
= IStream_Write(stream
, pathW
, size
, NULL
);
295 ok(hr
== S_OK
, "Stream write failed, hr %#x.\n", hr
);
297 test_stream_stat(stream
, size
);
298 IStream_Release(stream
);
300 /* Invalid I/O mode */
301 hr
= IOpcFactory_CreateStreamOnFile(factory
, pathW
, 10, NULL
, 0, &stream
);
302 ok(hr
== E_INVALIDARG
, "Failed to create a write stream, hr %#x.\n", hr
);
304 /* Write to read-only stream. */
305 hr
= IOpcFactory_CreateStreamOnFile(factory
, pathW
, OPC_STREAM_IO_READ
, NULL
, 0, &stream
);
306 ok(SUCCEEDED(hr
), "Failed to create a read stream, hr %#x.\n", hr
);
308 test_stream_stat(stream
, size
);
309 hr
= IStream_Write(stream
, pathW
, size
, NULL
);
310 ok(hr
== HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED
), "Stream write failed, hr %#x.\n", hr
);
311 IStream_Release(stream
);
313 /* Read from write-only stream. */
314 hr
= IOpcFactory_CreateStreamOnFile(factory
, pathW
, OPC_STREAM_IO_WRITE
, NULL
, 0, &stream
);
315 ok(SUCCEEDED(hr
), "Failed to create a read stream, hr %#x.\n", hr
);
317 test_stream_stat(stream
, 0);
318 hr
= IStream_Write(stream
, pathW
, size
, NULL
);
319 ok(hr
== S_OK
, "Stream write failed, hr %#x.\n", hr
);
320 test_stream_stat(stream
, size
);
323 hr
= IStream_Seek(stream
, move
, STREAM_SEEK_SET
, NULL
);
324 ok(SUCCEEDED(hr
), "Seek failed, hr %#x.\n", hr
);
326 hr
= IStream_Read(stream
, buff
, sizeof(buff
), NULL
);
327 ok(hr
== HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED
), "Stream read failed, hr %#x.\n", hr
);
329 IStream_Release(stream
);
331 IOpcFactory_Release(factory
);
335 static void test_relationship(void)
337 static const WCHAR absoluteW
[] = {'f','i','l','e',':','/','/','h','o','s','t','/','f','i','l','e','.','t','x','t',0};
338 static const WCHAR targetW
[] = {'t','a','r','g','e','t',0};
339 static const WCHAR typeW
[] = {'t','y','p','e',0};
340 static const WCHAR rootW
[] = {'/',0};
341 IUri
*target_uri
, *target_uri2
, *uri
;
342 IOpcRelationship
*rel
, *rel2
, *rel3
;
343 IOpcUri
*source_uri
, *source_uri2
;
344 IOpcRelationshipSet
*rels
;
345 IOpcFactory
*factory
;
346 IOpcPackage
*package
;
354 factory
= create_factory();
356 hr
= IOpcFactory_CreatePackage(factory
, &package
);
357 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
) /* Vista */, "Failed to create a package, hr %#x.\n", hr
);
360 IOpcFactory_Release(factory
);
364 hr
= CreateUri(targetW
, Uri_CREATE_ALLOW_RELATIVE
, 0, &target_uri
);
365 ok(SUCCEEDED(hr
), "Failed to create target uri, hr %#x.\n", hr
);
367 hr
= CreateUri(absoluteW
, 0, 0, &target_uri2
);
368 ok(SUCCEEDED(hr
), "Failed to create target uri, hr %#x.\n", hr
);
370 hr
= IOpcPackage_GetRelationshipSet(package
, &rels
);
371 ok(SUCCEEDED(hr
), "Failed to get part set, hr %#x.\n", hr
);
373 rel
= (void *)0xdeadbeef;
374 hr
= IOpcRelationshipSet_CreateRelationship(rels
, NULL
, NULL
, NULL
, OPC_URI_TARGET_MODE_INTERNAL
, &rel
);
375 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
376 ok(rel
== NULL
, "Unexpected instance %p.\n", rel
);
378 rel
= (void *)0xdeadbeef;
379 hr
= IOpcRelationshipSet_CreateRelationship(rels
, NULL
, typeW
, NULL
, OPC_URI_TARGET_MODE_INTERNAL
, &rel
);
380 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
381 ok(rel
== NULL
, "Unexpected instance %p.\n", rel
);
383 hr
= IOpcRelationshipSet_CreateRelationship(rels
, NULL
, NULL
, target_uri
, OPC_URI_TARGET_MODE_INTERNAL
, &rel
);
384 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
386 /* Absolute target uri with internal mode */
387 rel
= (void *)0xdeadbeef;
388 hr
= IOpcRelationshipSet_CreateRelationship(rels
, NULL
, typeW
, target_uri2
, OPC_URI_TARGET_MODE_INTERNAL
, &rel
);
389 ok(hr
== OPC_E_INVALID_RELATIONSHIP_TARGET
, "Unexpected hr %#x.\n", hr
);
390 ok(rel
== NULL
, "Unexpected instance %p.\n", rel
);
392 hr
= IOpcRelationshipSet_CreateRelationship(rels
, NULL
, typeW
, target_uri
, OPC_URI_TARGET_MODE_INTERNAL
, &rel
);
393 ok(SUCCEEDED(hr
), "Failed to create relationship, hr %#x.\n", hr
);
395 /* Autogenerated relationship id */
396 hr
= IOpcRelationship_GetId(rel
, &id
);
397 ok(SUCCEEDED(hr
), "Failed to get id, hr %#x.\n", hr
);
398 ok(lstrlenW(id
) == 9 && *id
== 'R', "Unexpected relationship id %s.\n", wine_dbgstr_w(id
));
400 hr
= IOpcRelationshipSet_CreateRelationship(rels
, id
, typeW
, target_uri
, OPC_URI_TARGET_MODE_INTERNAL
, &rel2
);
401 ok(hr
== OPC_E_DUPLICATE_RELATIONSHIP
, "Failed to create relationship, hr %#x.\n", hr
);
403 hr
= IOpcRelationshipSet_CreateRelationship(rels
, id
, typeW
, target_uri2
, OPC_URI_TARGET_MODE_INTERNAL
, &rel2
);
404 ok(hr
== OPC_E_DUPLICATE_RELATIONSHIP
, "Failed to create relationship, hr %#x.\n", hr
);
406 hr
= IOpcRelationshipSet_CreateRelationship(rels
, NULL
, typeW
, target_uri
, OPC_URI_TARGET_MODE_INTERNAL
, &rel2
);
407 ok(SUCCEEDED(hr
), "Failed to create relationship, hr %#x.\n", hr
);
410 hr
= IOpcRelationshipSet_RelationshipExists(rels
, NULL
, &ret
);
411 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
412 ok(ret
== 123, "Unexpected result %d.\n", ret
);
414 hr
= IOpcRelationshipSet_RelationshipExists(rels
, id
, NULL
);
415 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
418 hr
= IOpcRelationshipSet_RelationshipExists(rels
, id
, &ret
);
419 ok(SUCCEEDED(hr
), "Failed to get relationship, hr %#x.\n", hr
);
420 ok(ret
, "Unexpected result %d.\n", ret
);
422 hr
= IOpcRelationshipSet_GetRelationship(rels
, id
, &rel3
);
423 ok(SUCCEEDED(hr
), "Failed to get relationship, hr %#x.\n", hr
);
424 IOpcRelationship_Release(rel3
);
426 hr
= IOpcRelationshipSet_GetRelationship(rels
, id
, NULL
);
427 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
429 rel3
= (void *)0xdeadbeef;
430 hr
= IOpcRelationshipSet_GetRelationship(rels
, NULL
, &rel3
);
431 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
432 ok(rel3
== NULL
, "Expected null pointer.\n");
435 rel3
= (void *)0xdeadbeef;
436 hr
= IOpcRelationshipSet_GetRelationship(rels
, id
, &rel3
);
437 ok(hr
== OPC_E_NO_SUCH_RELATIONSHIP
, "Unexpected hr %#x.\n", hr
);
438 ok(rel3
== NULL
, "Expected null pointer.\n");
441 hr
= IOpcRelationshipSet_RelationshipExists(rels
, id
, &ret
);
442 ok(SUCCEEDED(hr
), "Unexpected hr %#x.\n", hr
);
443 ok(!ret
, "Unexpected result %d.\n", ret
);
447 hr
= IOpcRelationship_GetTargetUri(rel
, &uri
);
448 ok(SUCCEEDED(hr
), "Failed to get target uri, hr %#x.\n", hr
);
449 ok(uri
== target_uri
, "Unexpected uri.\n");
452 hr
= IOpcRelationship_GetTargetMode(rel
, &mode
);
453 ok(SUCCEEDED(hr
), "Failed to get target mode, hr %#x.\n", hr
);
454 ok(mode
== OPC_URI_TARGET_MODE_INTERNAL
, "Unexpected mode %d.\n", mode
);
457 hr
= IOpcFactory_CreatePackageRootUri(factory
, &source_uri
);
458 ok(SUCCEEDED(hr
), "Failed to create root uri, hr %#x.\n", hr
);
460 hr
= IOpcFactory_CreatePackageRootUri(factory
, &source_uri2
);
461 ok(SUCCEEDED(hr
), "Failed to create root uri, hr %#x.\n", hr
);
462 ok(source_uri
!= source_uri2
, "Unexpected uri instance.\n");
464 IOpcUri_Release(source_uri
);
465 IOpcUri_Release(source_uri2
);
467 hr
= IOpcRelationship_GetSourceUri(rel
, &source_uri
);
468 ok(SUCCEEDED(hr
), "Failed to get source uri, hr %#x.\n", hr
);
470 hr
= IOpcUri_QueryInterface(source_uri
, &IID_IOpcPartUri
, (void **)&unk
);
471 ok(hr
== E_NOINTERFACE
, "Unexpected hr %#x.\n", hr
);
474 hr
= IOpcUri_GetRawUri(source_uri
, &str
);
475 ok(SUCCEEDED(hr
), "Failed to get raw uri, hr %#x.\n", hr
);
476 ok(!lstrcmpW(rootW
, str
), "Unexpected uri %s.\n", wine_dbgstr_w(str
));
479 hr
= IOpcRelationship_GetSourceUri(rel2
, &source_uri2
);
480 ok(SUCCEEDED(hr
), "Failed to get source uri, hr %#x.\n", hr
);
481 ok(source_uri2
== source_uri
, "Unexpected source uri.\n");
483 IOpcUri_Release(source_uri2
);
484 IOpcUri_Release(source_uri
);
486 IOpcRelationship_Release(rel2
);
487 IOpcRelationship_Release(rel
);
489 IOpcRelationshipSet_Release(rels
);
491 IUri_Release(target_uri
);
492 IUri_Release(target_uri2
);
493 IOpcPackage_Release(package
);
494 IOpcFactory_Release(factory
);
497 static WCHAR
*strdupAtoW(const char *str
)
502 if (!str
) return ret
;
503 len
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
504 ret
= heap_alloc(len
* sizeof(WCHAR
));
506 MultiByteToWideChar(CP_ACP
, 0, str
, -1, ret
, len
);
510 static void test_rel_part_uri(void)
517 } rel_part_uri_tests
[] =
519 { "/uri", "/_rels/uri.rels" },
520 { "/path/uri", "/path/_rels/uri.rels" },
521 { "path/uri", "/path/_rels/uri.rels" },
522 { "../path/uri", "/path/_rels/uri.rels" },
523 { "../../path/uri", "/path/_rels/uri.rels" },
524 { "/uri.ext", "/_rels/uri.ext.rels" },
525 { "/", "/_rels/.rels" },
526 { "uri", "/_rels/uri.rels" },
527 { "/path/../uri", "/_rels/uri.rels" },
528 { "/path/path/../../uri", "/_rels/uri.rels" },
529 { "/_rels/uri.ext.rels", "", OPC_E_NONCONFORMING_URI
},
535 } is_rel_part_tests
[] =
539 { "/_rels/uri", FALSE
},
540 { "/_rels/uri/uri", FALSE
},
541 { "/_rels/uri/uri.rels", FALSE
},
542 { "/uri/uri.rels", FALSE
},
543 { "/uri/_rels/uri.rels", TRUE
},
544 { "/_rels/.rels", TRUE
},
546 static const WCHAR testuriW
[] = {'/','u','r','i',0};
547 IOpcPartUri
*part_uri
;
548 IOpcFactory
*factory
;
554 factory
= create_factory();
556 hr
= IOpcFactory_CreatePartUri(factory
, testuriW
, &part_uri
);
557 ok(SUCCEEDED(hr
), "Failed to create part uri, hr %#x.\n", hr
);
559 hr
= IOpcPartUri_GetRelationshipsPartUri(part_uri
, NULL
);
560 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
562 hr
= IOpcPartUri_IsRelationshipsPartUri(part_uri
, NULL
);
563 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
565 hr
= IOpcPartUri_GetSourceUri(part_uri
, NULL
);
566 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
568 source_uri
= (void *)0xdeadbeef;
569 hr
= IOpcPartUri_GetSourceUri(part_uri
, &source_uri
);
570 ok(hr
== OPC_E_RELATIONSHIP_URI_REQUIRED
, "Unexpected hr %#x.\n", hr
);
571 ok(source_uri
== NULL
, "Expected null uri.\n");
573 IOpcPartUri_Release(part_uri
);
575 for (i
= 0; i
< ARRAY_SIZE(rel_part_uri_tests
); ++i
)
577 BOOL is_root
= FALSE
;
578 IOpcPartUri
*rel_uri
;
582 uriW
= strdupAtoW(rel_part_uri_tests
[i
].uri
);
583 rel_uriW
= strdupAtoW(rel_part_uri_tests
[i
].rel_uri
);
585 if (!strcmp(rel_part_uri_tests
[i
].uri
, "/"))
587 hr
= IOpcFactory_CreatePackageRootUri(factory
, &part_uri
);
591 hr
= IOpcFactory_CreatePartUri(factory
, uriW
, (IOpcPartUri
**)&part_uri
);
592 ok(SUCCEEDED(hr
), "Failed to create part uri, hr %#x.\n", hr
);
594 rel_uri
= (void *)0xdeadbeef;
595 hr
= IOpcUri_GetRelationshipsPartUri(part_uri
, &rel_uri
);
598 IOpcPartUri
*rel_uri2
;
599 IOpcUri
*source_uri2
;
600 IUnknown
*unk
= NULL
;
604 hr
= IOpcPartUri_GetSourceUri(rel_uri
, &source_uri
);
605 ok(SUCCEEDED(hr
), "Failed to get source uri, hr %#x.\n", hr
);
606 hr
= IOpcPartUri_GetSourceUri(rel_uri
, &source_uri2
);
607 ok(SUCCEEDED(hr
), "Failed to get source uri, hr %#x.\n", hr
);
608 ok(source_uri
!= source_uri2
, "Unexpected instance.\n");
610 hr
= IOpcUri_IsEqual(source_uri
, NULL
, NULL
);
611 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
614 hr
= IOpcUri_IsEqual(source_uri
, NULL
, &ret
);
615 ok(is_root
? hr
== E_POINTER
: hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
616 ok(is_root
? ret
== 123 : !ret
, "Unexpected result.\n");
619 hr
= IOpcUri_IsEqual(source_uri
, (IUri
*)source_uri2
, &ret
);
620 ok(SUCCEEDED(hr
), "IsEqual failed, hr %#x.\n", hr
);
621 ok(ret
, "Expected equal uris.\n");
623 hr
= IOpcUri_QueryInterface(source_uri
, &IID_IOpcPartUri
, (void **)&unk
);
624 ok(hr
== (is_root
? E_NOINTERFACE
: S_OK
), "Unexpected hr %#x, %s.\n", hr
, rel_part_uri_tests
[i
].uri
);
626 IUnknown_Release(unk
);
628 IOpcUri_Release(source_uri2
);
629 IOpcUri_Release(source_uri
);
631 hr
= IOpcUri_GetRelationshipsPartUri(part_uri
, &rel_uri2
);
632 ok(SUCCEEDED(hr
), "Failed to get rels part uri, hr %#x.\n", hr
);
633 ok(rel_uri2
!= rel_uri
, "Unexpected instance.\n");
634 IOpcPartUri_Release(rel_uri2
);
636 hr
= IOpcPartUri_GetRawUri(rel_uri
, &str
);
637 ok(SUCCEEDED(hr
), "Failed to get rel uri, hr %#x.\n", hr
);
638 todo_wine_if(i
== 3 || i
== 4 || i
== 8 || i
== 9)
639 ok(!lstrcmpW(str
, rel_uriW
), "%u: unexpected rel uri %s, expected %s.\n", i
, wine_dbgstr_w(str
),
640 wine_dbgstr_w(rel_uriW
));
643 IOpcPartUri_Release(rel_uri
);
647 ok(hr
== rel_part_uri_tests
[i
].hr
, "%u: unexpected hr %#x.\n", i
, hr
);
648 ok(rel_uri
== NULL
, "%u: unexpected out pointer.\n", i
);
654 IOpcUri_Release(part_uri
);
657 for (i
= 0; i
< ARRAY_SIZE(is_rel_part_tests
); ++i
)
659 IOpcPartUri
*part_uri
;
662 uriW
= strdupAtoW(is_rel_part_tests
[i
].uri
);
664 hr
= IOpcFactory_CreatePartUri(factory
, uriW
, &part_uri
);
665 ok(SUCCEEDED(hr
), "Failed to create part uri, hr %#x.\n", hr
);
668 hr
= IOpcPartUri_IsRelationshipsPartUri(part_uri
, &ret
);
669 ok(SUCCEEDED(hr
), "Unexpected hr %#x.\n", hr
);
670 ok(ret
== is_rel_part_tests
[i
].ret
, "%u: unexpected result %d.\n", i
, ret
);
674 IOpcPartUri_Release(part_uri
);
677 IOpcFactory_Release(factory
);
680 static void test_part_enumerator(void)
682 static const WCHAR typeW
[] = {'t','y','p','e','/','s','u','b','t','y','p','e',0};
683 static const WCHAR uriW
[] = {'/','u','r','i',0};
684 IOpcPartEnumerator
*partenum
, *partenum2
;
685 IOpcPart
*part
, *part2
;
686 IOpcPartUri
*part_uri
;
687 IOpcPackage
*package
;
688 IOpcFactory
*factory
;
693 factory
= create_factory();
695 hr
= IOpcFactory_CreatePackage(factory
, &package
);
696 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
) /* Vista */, "Failed to create a package, hr %#x.\n", hr
);
699 IOpcFactory_Release(factory
);
703 hr
= IOpcPackage_GetPartSet(package
, &parts
);
704 ok(SUCCEEDED(hr
), "Failed to get part set, hr %#x.\n", hr
);
706 hr
= IOpcPartSet_GetEnumerator(parts
, NULL
);
707 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
709 hr
= IOpcPartSet_GetEnumerator(parts
, &partenum
);
710 ok(SUCCEEDED(hr
), "Failed to get enumerator, hr %#x.\n", hr
);
712 hr
= IOpcPartSet_GetEnumerator(parts
, &partenum2
);
713 ok(SUCCEEDED(hr
), "Failed to get enumerator, hr %#x.\n", hr
);
714 ok(partenum
!= partenum2
, "Unexpected instance.\n");
715 IOpcPartEnumerator_Release(partenum2
);
717 hr
= IOpcPartEnumerator_GetCurrent(partenum
, NULL
);
718 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
720 hr
= IOpcPartEnumerator_GetCurrent(partenum
, &part
);
721 ok(hr
== OPC_E_ENUM_INVALID_POSITION
, "Unexpected hr %#x.\n", hr
);
723 hr
= IOpcPartEnumerator_MoveNext(partenum
, NULL
);
724 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
727 hr
= IOpcPartEnumerator_MoveNext(partenum
, &ret
);
728 ok(hr
== S_OK
, "Failed to move, hr %#x.\n", hr
);
729 ok(!ret
, "Unexpected result %d.\n", ret
);
732 hr
= IOpcPartEnumerator_MovePrevious(partenum
, &ret
);
733 ok(hr
== S_OK
, "Failed to move, hr %#x.\n", hr
);
734 ok(!ret
, "Unexpected result %d.\n", ret
);
736 hr
= IOpcFactory_CreatePartUri(factory
, uriW
, &part_uri
);
737 ok(SUCCEEDED(hr
), "Failed to create part uri, hr %#x.\n", hr
);
739 hr
= IOpcPartSet_CreatePart(parts
, part_uri
, typeW
, OPC_COMPRESSION_NONE
, &part
);
740 ok(SUCCEEDED(hr
), "Failed to create a part, hr %#x.\n", hr
);
741 IOpcPartUri_Release(part_uri
);
743 part2
= (void *)0xdeadbeef;
744 hr
= IOpcPartEnumerator_GetCurrent(partenum
, &part2
);
745 ok(hr
== OPC_E_ENUM_COLLECTION_CHANGED
, "Unexpected hr %#x.\n", hr
);
746 ok(part2
== NULL
, "Unexpected instance.\n");
748 hr
= IOpcPartEnumerator_MoveNext(partenum
, NULL
);
749 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
752 hr
= IOpcPartEnumerator_MoveNext(partenum
, &ret
);
753 ok(hr
== OPC_E_ENUM_COLLECTION_CHANGED
, "Unexpected hr %#x.\n", hr
);
754 ok(ret
== 123, "Unexpected result %d.\n", ret
);
756 hr
= IOpcPartEnumerator_MovePrevious(partenum
, NULL
);
757 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
760 hr
= IOpcPartEnumerator_MovePrevious(partenum
, &ret
);
761 ok(hr
== OPC_E_ENUM_COLLECTION_CHANGED
, "Unexpected hr %#x.\n", hr
);
762 ok(ret
== 123, "Unexpected result %d.\n", ret
);
764 hr
= IOpcPartEnumerator_Clone(partenum
, NULL
);
765 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
767 partenum2
= (void *)0xdeadbeef;
768 hr
= IOpcPartEnumerator_Clone(partenum
, &partenum2
);
769 ok(hr
== OPC_E_ENUM_COLLECTION_CHANGED
, "Unexpected hr %#x.\n", hr
);
770 ok(partenum2
== NULL
, "Unexpected instance.\n");
772 IOpcPartEnumerator_Release(partenum
);
774 hr
= IOpcPartSet_GetEnumerator(parts
, &partenum
);
775 ok(SUCCEEDED(hr
), "Failed to get enumerator, hr %#x.\n", hr
);
777 part2
= (void *)0xdeadbeef;
778 hr
= IOpcPartEnumerator_GetCurrent(partenum
, &part2
);
779 ok(hr
== OPC_E_ENUM_INVALID_POSITION
, "Unexpected hr %#x.\n", hr
);
780 ok(part2
== NULL
, "Unexpected instance.\n");
782 hr
= IOpcPartEnumerator_MoveNext(partenum
, &ret
);
783 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
784 ok(ret
, "Unexpected result %d.\n", ret
);
786 hr
= IOpcPartEnumerator_GetCurrent(partenum
, &part2
);
787 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
788 ok(part2
== part
, "Unexpected instance.\n");
789 IOpcPart_Release(part2
);
791 hr
= IOpcPartEnumerator_MoveNext(partenum
, &ret
);
792 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
793 ok(!ret
, "Unexpected result %d.\n", ret
);
795 part2
= (void *)0xdeadbeef;
796 hr
= IOpcPartEnumerator_GetCurrent(partenum
, &part2
);
797 ok(hr
== OPC_E_ENUM_INVALID_POSITION
, "Unexpected hr %#x.\n", hr
);
798 ok(part2
== NULL
, "Unexpected instance.\n");
800 hr
= IOpcPartEnumerator_MovePrevious(partenum
, &ret
);
801 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
802 ok(ret
, "Unexpected result %d.\n", ret
);
804 hr
= IOpcPartEnumerator_GetCurrent(partenum
, &part2
);
805 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
806 ok(part2
== part
, "Unexpected instance.\n");
807 IOpcPart_Release(part2
);
809 hr
= IOpcPartEnumerator_MovePrevious(partenum
, &ret
);
810 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
811 ok(!ret
, "Unexpected result %d.\n", ret
);
813 hr
= IOpcPartEnumerator_GetCurrent(partenum
, &part2
);
814 ok(hr
== OPC_E_ENUM_INVALID_POSITION
, "Unexpected hr %#x.\n", hr
);
816 hr
= IOpcPartEnumerator_Clone(partenum
, &partenum2
);
817 ok(SUCCEEDED(hr
), "Clone failed, hr %#x.\n", hr
);
819 hr
= IOpcPartEnumerator_MoveNext(partenum2
, &ret
);
820 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
821 ok(ret
, "Unexpected result %d.\n", ret
);
823 hr
= IOpcPartEnumerator_GetCurrent(partenum2
, &part2
);
824 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
825 IOpcPart_Release(part2
);
827 hr
= IOpcPartEnumerator_GetCurrent(partenum
, &part2
);
828 ok(hr
== OPC_E_ENUM_INVALID_POSITION
, "Unexpected hr %#x.\n", hr
);
830 IOpcPartEnumerator_Release(partenum2
);
832 IOpcPartEnumerator_Release(partenum
);
834 IOpcPart_Release(part
);
836 IOpcPartSet_Release(parts
);
838 IOpcPackage_Release(package
);
839 IOpcFactory_Release(factory
);
842 static void test_rels_enumerator(void)
844 static const WCHAR typeW
[] = {'t','y','p','e','/','s','u','b','t','y','p','e',0};
845 static const WCHAR targetW
[] = {'t','a','r','g','e','t',0};
846 IOpcRelationshipEnumerator
*relsenum
, *relsenum2
;
847 IOpcRelationship
*rel
, *rel2
;
848 IOpcPackage
*package
;
849 IOpcFactory
*factory
;
850 IOpcRelationshipSet
*rels
;
855 factory
= create_factory();
857 hr
= IOpcFactory_CreatePackage(factory
, &package
);
858 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
) /* Vista */, "Failed to create a package, hr %#x.\n", hr
);
861 IOpcFactory_Release(factory
);
865 hr
= IOpcPackage_GetRelationshipSet(package
, &rels
);
866 ok(SUCCEEDED(hr
), "Failed to get part set, hr %#x.\n", hr
);
868 hr
= IOpcRelationshipSet_GetEnumerator(rels
, NULL
);
869 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
871 hr
= IOpcRelationshipSet_GetEnumerator(rels
, &relsenum
);
872 ok(SUCCEEDED(hr
), "Failed to get enumerator, hr %#x.\n", hr
);
874 hr
= IOpcRelationshipSet_GetEnumerator(rels
, &relsenum2
);
875 ok(SUCCEEDED(hr
), "Failed to get enumerator, hr %#x.\n", hr
);
876 ok(relsenum
!= relsenum2
, "Unexpected instance.\n");
877 IOpcRelationshipEnumerator_Release(relsenum2
);
879 hr
= IOpcRelationshipEnumerator_GetCurrent(relsenum
, NULL
);
880 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
882 hr
= IOpcRelationshipEnumerator_GetCurrent(relsenum
, &rel
);
883 ok(hr
== OPC_E_ENUM_INVALID_POSITION
, "Unexpected hr %#x.\n", hr
);
885 hr
= IOpcRelationshipEnumerator_MoveNext(relsenum
, NULL
);
886 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
889 hr
= IOpcRelationshipEnumerator_MoveNext(relsenum
, &ret
);
890 ok(hr
== S_OK
, "Failed to move, hr %#x.\n", hr
);
891 ok(!ret
, "Unexpected result %d.\n", ret
);
894 hr
= IOpcRelationshipEnumerator_MovePrevious(relsenum
, &ret
);
895 ok(hr
== S_OK
, "Failed to move, hr %#x.\n", hr
);
896 ok(!ret
, "Unexpected result %d.\n", ret
);
898 hr
= CreateUri(targetW
, Uri_CREATE_ALLOW_RELATIVE
, 0, &target_uri
);
899 ok(SUCCEEDED(hr
), "Failed to create target uri, hr %#x.\n", hr
);
901 hr
= IOpcRelationshipSet_CreateRelationship(rels
, NULL
, typeW
, target_uri
, OPC_URI_TARGET_MODE_INTERNAL
, &rel
);
902 ok(SUCCEEDED(hr
), "Failed to create relationship, hr %#x.\n", hr
);
904 IUri_Release(target_uri
);
906 rel2
= (void *)0xdeadbeef;
907 hr
= IOpcRelationshipEnumerator_GetCurrent(relsenum
, &rel2
);
908 ok(hr
== OPC_E_ENUM_COLLECTION_CHANGED
, "Unexpected hr %#x.\n", hr
);
909 ok(rel2
== NULL
, "Unexpected instance.\n");
911 hr
= IOpcRelationshipEnumerator_MoveNext(relsenum
, NULL
);
912 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
915 hr
= IOpcRelationshipEnumerator_MoveNext(relsenum
, &ret
);
916 ok(hr
== OPC_E_ENUM_COLLECTION_CHANGED
, "Unexpected hr %#x.\n", hr
);
917 ok(ret
== 123, "Unexpected result %d.\n", ret
);
919 hr
= IOpcRelationshipEnumerator_MovePrevious(relsenum
, NULL
);
920 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
923 hr
= IOpcRelationshipEnumerator_MovePrevious(relsenum
, &ret
);
924 ok(hr
== OPC_E_ENUM_COLLECTION_CHANGED
, "Unexpected hr %#x.\n", hr
);
925 ok(ret
== 123, "Unexpected result %d.\n", ret
);
927 hr
= IOpcRelationshipEnumerator_Clone(relsenum
, NULL
);
928 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
930 relsenum2
= (void *)0xdeadbeef;
931 hr
= IOpcRelationshipEnumerator_Clone(relsenum
, &relsenum2
);
932 ok(hr
== OPC_E_ENUM_COLLECTION_CHANGED
, "Unexpected hr %#x.\n", hr
);
933 ok(relsenum2
== NULL
, "Unexpected instance.\n");
935 IOpcRelationshipEnumerator_Release(relsenum
);
937 hr
= IOpcRelationshipSet_GetEnumerator(rels
, &relsenum
);
938 ok(SUCCEEDED(hr
), "Failed to get enumerator, hr %#x.\n", hr
);
940 rel2
= (void *)0xdeadbeef;
941 hr
= IOpcRelationshipEnumerator_GetCurrent(relsenum
, &rel2
);
942 ok(hr
== OPC_E_ENUM_INVALID_POSITION
, "Unexpected hr %#x.\n", hr
);
943 ok(rel2
== NULL
, "Unexpected instance.\n");
945 hr
= IOpcRelationshipEnumerator_MoveNext(relsenum
, &ret
);
946 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
947 ok(ret
, "Unexpected result %d.\n", ret
);
949 hr
= IOpcRelationshipEnumerator_GetCurrent(relsenum
, &rel2
);
950 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
951 ok(rel2
== rel
, "Unexpected instance.\n");
952 IOpcRelationship_Release(rel2
);
954 hr
= IOpcRelationshipEnumerator_MoveNext(relsenum
, &ret
);
955 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
956 ok(!ret
, "Unexpected result %d.\n", ret
);
958 rel2
= (void *)0xdeadbeef;
959 hr
= IOpcRelationshipEnumerator_GetCurrent(relsenum
, &rel2
);
960 ok(hr
== OPC_E_ENUM_INVALID_POSITION
, "Unexpected hr %#x.\n", hr
);
961 ok(rel2
== NULL
, "Unexpected instance.\n");
963 hr
= IOpcRelationshipEnumerator_MovePrevious(relsenum
, &ret
);
964 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
965 ok(ret
, "Unexpected result %d.\n", ret
);
967 hr
= IOpcRelationshipEnumerator_GetCurrent(relsenum
, &rel2
);
968 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
969 ok(rel2
== rel
, "Unexpected instance.\n");
970 IOpcRelationship_Release(rel2
);
972 hr
= IOpcRelationshipEnumerator_MovePrevious(relsenum
, &ret
);
973 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
974 ok(!ret
, "Unexpected result %d.\n", ret
);
976 hr
= IOpcRelationshipEnumerator_GetCurrent(relsenum
, &rel2
);
977 ok(hr
== OPC_E_ENUM_INVALID_POSITION
, "Unexpected hr %#x.\n", hr
);
979 hr
= IOpcRelationshipEnumerator_Clone(relsenum
, &relsenum2
);
980 ok(SUCCEEDED(hr
), "Clone failed, hr %#x.\n", hr
);
982 hr
= IOpcRelationshipEnumerator_MoveNext(relsenum2
, &ret
);
983 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
984 ok(ret
, "Unexpected result %d.\n", ret
);
986 hr
= IOpcRelationshipEnumerator_GetCurrent(relsenum2
, &rel2
);
987 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
988 IOpcRelationship_Release(rel2
);
990 hr
= IOpcRelationshipEnumerator_GetCurrent(relsenum
, &rel2
);
991 ok(hr
== OPC_E_ENUM_INVALID_POSITION
, "Unexpected hr %#x.\n", hr
);
993 IOpcRelationshipEnumerator_Release(relsenum2
);
995 IOpcRelationshipEnumerator_Release(relsenum
);
997 IOpcRelationship_Release(rel
);
999 IOpcRelationshipSet_Release(rels
);
1001 IOpcPackage_Release(package
);
1002 IOpcFactory_Release(factory
);
1005 static void test_relative_uri(void)
1010 const char *combined
;
1011 const char *relative
;
1012 const char *relative_broken
;
1014 relative_uri_tests
[] =
1016 { "/", "/path/path2", "path/path2", "/path/path2" },
1017 { "/", "/path", "path", "/path" },
1018 { "/path/path2", "/path/path2/path3", "path2/path3" },
1019 { "/path/path2", "/path3", "../path3" },
1020 { "/path", "/path", "" },
1021 { "/path", "../path", "" },
1022 { "/path2", "/path", "path" },
1023 { "../path", "/path", "" },
1024 { "../../path", "/path", "" },
1026 IOpcFactory
*factory
;
1029 factory
= create_factory();
1031 for (i
= 0; i
< ARRAY_SIZE(relative_uri_tests
); ++i
)
1033 WCHAR
*uriW
, *combinedW
, *relativeW
, *relative_broken_W
;
1034 IOpcPartUri
*combined_uri
;
1041 uriW
= strdupAtoW(relative_uri_tests
[i
].part
);
1042 combinedW
= strdupAtoW(relative_uri_tests
[i
].combined
);
1043 relativeW
= strdupAtoW(relative_uri_tests
[i
].relative
);
1044 relative_broken_W
= strdupAtoW(relative_uri_tests
[i
].relative_broken
);
1046 if (!strcmp(relative_uri_tests
[i
].part
, "/"))
1047 hr
= IOpcFactory_CreatePackageRootUri(factory
, &part_uri
);
1049 hr
= IOpcFactory_CreatePartUri(factory
, uriW
, (IOpcPartUri
**)&part_uri
);
1050 ok(SUCCEEDED(hr
), "%u: failed to create part uri, hr %#x.\n", i
, hr
);
1052 hr
= IOpcFactory_CreatePartUri(factory
, combinedW
, &combined_uri
);
1053 ok(SUCCEEDED(hr
), "%u: failed to create part uri, hr %#x.\n", i
, hr
);
1055 hr
= IOpcUri_GetRelativeUri(part_uri
, combined_uri
, &relative_uri
);
1057 ok(SUCCEEDED(hr
), "%u: failed t oget relative uri, hr %#x.\n", i
, hr
);
1061 hr
= IUri_QueryInterface(relative_uri
, &IID_IOpcUri
, (void **)&unk
);
1062 ok(hr
== E_NOINTERFACE
, "%u: unexpected hr %#x.\n", i
, hr
);
1064 hr
= IUri_GetRawUri(relative_uri
, &str
);
1065 ok(SUCCEEDED(hr
), "%u: failed to get raw uri, hr %#x.\n", i
, hr
);
1066 ok(!lstrcmpW(str
, relativeW
) || broken(relative_broken_W
&& !lstrcmpW(str
, relative_broken_W
)),
1067 "%u: unexpected relative uri %s.\n", i
, wine_dbgstr_w(str
));
1070 IUri_Release(relative_uri
);
1072 IOpcUri_Release(part_uri
);
1073 IOpcPartUri_Release(combined_uri
);
1076 heap_free(combinedW
);
1077 heap_free(relativeW
);
1078 heap_free(relative_broken_W
);
1081 IOpcFactory_Release(factory
);
1084 static void test_combine_uri(void)
1089 const char *relative
;
1090 const char *combined
;
1094 { "/", "path", "/path" },
1095 { "/path1", "path2", "/path2" },
1096 { "/path1", "../path2", "/path2" },
1097 { "/path1/../path2", "path3", "/path3" },
1099 IOpcFactory
*factory
;
1102 factory
= create_factory();
1104 for (i
= 0; i
< ARRAY_SIZE(combine_tests
); ++i
)
1106 WCHAR
*uriW
, *relativeW
, *combinedW
;
1107 IOpcPartUri
*combined_uri
;
1113 uriW
= strdupAtoW(combine_tests
[i
].uri
);
1114 relativeW
= strdupAtoW(combine_tests
[i
].relative
);
1115 combinedW
= strdupAtoW(combine_tests
[i
].combined
);
1117 if (!strcmp(combine_tests
[i
].uri
, "/"))
1118 hr
= IOpcFactory_CreatePackageRootUri(factory
, &uri
);
1120 hr
= IOpcFactory_CreatePartUri(factory
, uriW
, (IOpcPartUri
**)&uri
);
1121 ok(SUCCEEDED(hr
), "%u: failed to create uri, hr %#x.\n", i
, hr
);
1123 hr
= CreateUri(relativeW
, Uri_CREATE_ALLOW_RELATIVE
, 0, &relative_uri
);
1124 ok(SUCCEEDED(hr
), "%u: failed to create relative uri, hr %#x.\n", i
, hr
);
1126 combined_uri
= (void *)0xdeadbeef;
1127 hr
= IOpcUri_CombinePartUri(uri
, NULL
, &combined_uri
);
1128 ok(hr
== E_POINTER
, "%u: failed to combine uris, hr %#x.\n", i
, hr
);
1129 ok(!combined_uri
, "Unexpected instance.\n");
1131 hr
= IOpcUri_CombinePartUri(uri
, relative_uri
, NULL
);
1132 ok(hr
== E_POINTER
, "%u: failed to combine uris, hr %#x.\n", i
, hr
);
1134 hr
= IOpcUri_CombinePartUri(uri
, relative_uri
, &combined_uri
);
1135 ok(SUCCEEDED(hr
), "%u: failed to combine uris, hr %#x.\n", i
, hr
);
1137 hr
= IOpcPartUri_GetRawUri(combined_uri
, &str
);
1138 ok(SUCCEEDED(hr
), "%u: failed to get raw uri, hr %#x.\n", i
, hr
);
1139 todo_wine_if(i
== 2 || i
== 3)
1140 ok(!lstrcmpW(str
, combinedW
), "%u: unexpected uri %s.\n", i
, wine_dbgstr_w(str
));
1143 IOpcPartUri_Release(combined_uri
);
1146 heap_free(relativeW
);
1147 heap_free(combinedW
);
1149 IOpcUri_Release(uri
);
1150 IUri_Release(relative_uri
);
1153 IOpcFactory_Release(factory
);
1156 static void test_create_part_uri(void)
1161 const char *raw_uri
;
1163 create_part_uri_tests
[] =
1165 { "path", "/path" },
1166 { "../path", "/path" },
1167 { "../../path", "/path" },
1168 { "/path", "/path" },
1169 { "/path1/path2/path3/../path4", "/path1/path2/path4" },
1171 IOpcFactory
*factory
;
1175 factory
= create_factory();
1177 for (i
= 0; i
< ARRAY_SIZE(create_part_uri_tests
); ++i
)
1179 IOpcPartUri
*part_uri
;
1180 WCHAR
*inputW
, *rawW
;
1185 inputW
= strdupAtoW(create_part_uri_tests
[i
].input
);
1186 rawW
= strdupAtoW(create_part_uri_tests
[i
].raw_uri
);
1188 hr
= IOpcFactory_CreatePartUri(factory
, inputW
, &part_uri
);
1189 ok(SUCCEEDED(hr
), "%u: failed to create part uri, hr %#x.\n", i
, hr
);
1191 hr
= IOpcPartUri_GetRawUri(part_uri
, &str
);
1192 ok(SUCCEEDED(hr
), "Failed to get raw uri, hr %#x.\n", hr
);
1193 todo_wine_if(i
== 1 || i
== 2 || i
== 4)
1194 ok(!lstrcmpW(str
, rawW
), "%u: unexpected raw uri %s.\n", i
, wine_dbgstr_w(str
));
1197 hr
= CreateUri(rawW
, Uri_CREATE_ALLOW_RELATIVE
, 0, &uri
);
1198 ok(SUCCEEDED(hr
), "Failed to create uri, hr %#x.\n", hr
);
1201 hr
= IOpcPartUri_IsEqual(part_uri
, uri
, &ret
);
1202 ok(SUCCEEDED(hr
), "IsEqual failed, hr %#x.\n", hr
);
1203 todo_wine_if(i
== 1 || i
== 2 || i
== 4)
1204 ok(!!ret
, "%u: unexpected result %d.\n", i
, ret
);
1206 IOpcPartUri_Release(part_uri
);
1213 IOpcFactory_Release(factory
);
1216 static HRESULT WINAPI
custom_package_QueryInterface(IOpcPackage
*iface
, REFIID iid
, void **out
)
1218 if (IsEqualIID(iid
, &IID_IOpcPackage
) || IsEqualIID(iid
, &IID_IUnknown
))
1221 IOpcPackage_AddRef(iface
);
1226 return E_NOINTERFACE
;
1229 static ULONG WINAPI
custom_package_AddRef(IOpcPackage
*iface
)
1234 static ULONG WINAPI
custom_package_Release(IOpcPackage
*iface
)
1239 static HRESULT WINAPI
custom_package_GetPartSet(IOpcPackage
*iface
, IOpcPartSet
**part_set
)
1244 static HRESULT WINAPI
custom_package_GetRelationshipSet(IOpcPackage
*iface
, IOpcRelationshipSet
**relationship_set
)
1249 static const IOpcPackageVtbl custom_package_vtbl
=
1251 custom_package_QueryInterface
,
1252 custom_package_AddRef
,
1253 custom_package_Release
,
1254 custom_package_GetPartSet
,
1255 custom_package_GetRelationshipSet
,
1258 static void test_write_package(void)
1260 IOpcPackage custom_package
= { &custom_package_vtbl
};
1261 IOpcFactory
*factory
;
1262 IOpcPackage
*package
;
1266 factory
= create_factory();
1268 hr
= IOpcFactory_CreatePackage(factory
, &package
);
1269 ok(SUCCEEDED(hr
) || broken(hr
== E_NOTIMPL
) /* Vista */, "Failed to create a package, hr %#x.\n", hr
);
1272 IOpcFactory_Release(factory
);
1276 hr
= IOpcFactory_WritePackageToStream(factory
, NULL
, OPC_WRITE_FORCE_ZIP32
, NULL
);
1277 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
1279 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
1280 ok(SUCCEEDED(hr
), "Failed to create a stream, hr %#x.\n", hr
);
1282 hr
= IOpcFactory_WritePackageToStream(factory
, NULL
, OPC_WRITE_FORCE_ZIP32
, stream
);
1283 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
1285 hr
= IOpcFactory_WritePackageToStream(factory
, &custom_package
, OPC_WRITE_FORCE_ZIP32
, stream
);
1286 ok(hr
== 0x80000001, "Unexpected hr %#x.\n", hr
);
1288 IStream_Release(stream
);
1290 IOpcFactory_Release(factory
);
1291 IOpcPackage_Release(package
);
1294 START_TEST(opcservices
)
1296 IOpcFactory
*factory
;
1299 hr
= CoInitialize(NULL
);
1300 ok(SUCCEEDED(hr
), "Failed to initialize COM, hr %#x.\n", hr
);
1302 if (!(factory
= create_factory())) {
1303 win_skip("Failed to create IOpcFactory factory.\n");
1310 test_relationship();
1311 test_rel_part_uri();
1312 test_part_enumerator();
1313 test_rels_enumerator();
1314 test_relative_uri();
1316 test_create_part_uri();
1317 test_write_package();
1319 IOpcFactory_Release(factory
);