From: Vibhav Pant vibhavp@gmail.com
--- dlls/opcservices/tests/opcservices.c | 178 +++++++++++++++++++++++++++ include/opcbase.idl | 1 + 2 files changed, 179 insertions(+)
diff --git a/dlls/opcservices/tests/opcservices.c b/dlls/opcservices/tests/opcservices.c index 3fa9c732e42..34ef87ad80b 100644 --- a/dlls/opcservices/tests/opcservices.c +++ b/dlls/opcservices/tests/opcservices.c @@ -1242,6 +1242,183 @@ static void test_write_package(void) IOpcPackage_Release(package); }
+static void test_read_package(void) +{ + static struct { + const WCHAR *type; + const WCHAR *uri; + OPC_COMPRESSION_OPTIONS opt; + BOOL found; + } parts[] = { + {L"type1/subtype1", L"/entry1.11", OPC_COMPRESSION_NONE}, + {L"type1/subtype2", L"/entry2.12", OPC_COMPRESSION_NORMAL}, + {L"type2/subtype1", L"/entry3.21", OPC_COMPRESSION_MAXIMUM}, + {L"type2/subtype2", L"/entry4.22", OPC_COMPRESSION_FAST}, + {L"type1/subtype1", L"/entry5.11", OPC_COMPRESSION_SUPERFAST}, + {L"type1/subtype2", L"/entry6.12", OPC_COMPRESSION_NONE}, + {L"type2/subtype1", L"/entry7.21", OPC_COMPRESSION_NORMAL}, + {L"type2/subtype2", L"/entry8.22", OPC_COMPRESSION_MAXIMUM}, + {L"type1/subtype1", L"/dir1/entry1.11", OPC_COMPRESSION_FAST} + }; + IOpcPartEnumerator *partenum; + LARGE_INTEGER start = {0}; + IOpcFactory *factory; + IOpcPackage *package; + IOpcPartSet *partset; + IOpcPartUri *uri; + IStream *stream; + IOpcPart *part; + BYTE buf[256]; + HRESULT hr; + BOOL next; + int i; + + factory = create_factory(); + hr = IOpcFactory_CreatePackage(factory, &package); + ok(hr == S_OK || broken(hr == E_NOTIMPL) /* Vista */, "Failed to create a package, hr %#lx.\n", hr); + if (FAILED(hr)) goto done; + + hr = IOpcPackage_GetPartSet(package, &partset); + ok(hr == S_OK, "Failed to create a part set, hr %#lx.\n", hr); + + for (i = 0; i < ARRAY_SIZE(parts); i++) + { + ULONG read = 0; + + memset(buf, i, sizeof(buf)); + winetest_push_context("parts[%d]", i); + + hr = IOpcFactory_CreatePartUri(factory, parts[i].uri, &uri); + ok(hr == S_OK, "Failed to create part uri, hr %#lx.\n", hr); + hr = IOpcPartSet_CreatePart(partset, uri, parts[i].type, parts[i].opt, &part); + IOpcPartUri_Release(uri); + ok(hr == S_OK, "Failed to create a part, hr %#lx.\n", hr); + hr = IOpcPart_GetContentStream(part, &stream); + IOpcPart_Release(part); + ok(hr == S_OK, "Failed to get content stream, hr %#lx.\n", hr); + hr = IStream_Write(stream, buf, sizeof(buf), &read); + ok(hr == S_OK, "Failed to write to stream, hr %#lx.\n", hr); + ok(read == sizeof(buf), "Got read %lu != %Iu\n", read, sizeof(buf)); + IStream_Release(stream); + + winetest_pop_context(); + } + + hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); + ok(hr == S_OK, "Failed to create a stream, hr %#lx.\n", hr); + hr = IOpcFactory_WritePackageToStream(factory, package, OPC_WRITE_FORCE_ZIP32, stream); + ok(hr == S_OK, "Failed to write package, hr %#lx.\n", hr); + IOpcPackage_Release(package); + hr = IStream_Seek(stream, start, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "Failed to seek stream, hr %#lx.\n", hr); + + hr = IOpcFactory_ReadPackageFromStream(factory, stream, OPC_READ_DEFAULT, &package); + todo_wine ok(hr == S_OK, "Failed to read package, hr %#lx.\n", hr); + IStream_Release(stream); + if (FAILED(hr)) + { + IOpcPackage_Release(package); + goto done; + } + hr = IOpcPackage_GetPartSet(package, &partset); + ok(hr == S_OK, "Failed to get part set, hr %#lx.\n", hr); + + for (i = 0; i < ARRAY_SIZE(parts); i++) + { + OPC_COMPRESSION_OPTIONS opt = 0xdeadbeef; + WCHAR *type = NULL; + ULONG read = 0; + + winetest_push_context("parts[%d]", i); + + hr = IOpcFactory_CreatePartUri(factory, parts[i].uri, &uri); + ok(hr == S_OK, "Failed to create part uri, hr %#lx.\n", hr); + hr = IOpcPartSet_GetPart(partset, uri, &part); + IOpcPartUri_Release(uri); + todo_wine ok(hr == S_OK, "Failed to get part, hr %#lx.\n", hr); + if (FAILED(hr)) continue; + hr = IOpcPart_GetContentType(part, &type); + todo_wine ok(hr == S_OK, "Failed to get content type, hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + ok(!wcscmp(type, parts[i].type), "got type %s != %s.\n", debugstr_w(type), debugstr_w(parts[i].type)); + CoTaskMemFree(type); + } + hr = IOpcPart_GetCompressionOptions(part, &opt); + todo_wine ok(hr == S_OK, "Failed to get compression options, hr %#lx.\n", hr); + todo_wine ok(opt == parts[i].opt, "Got opt %d != %d.\n", opt, parts[i].opt); + hr = IOpcPart_GetContentStream(part, &stream); + IOpcPart_Release(part); + todo_wine ok(hr == S_OK, "Failed to get content stream, hr %#lx.\n", hr); + if (SUCCEEDED(hr)) + { + BYTE exp_buf[256]; + + memset(buf, 0, sizeof(buf)); + memset(exp_buf, i, sizeof(exp_buf)); + hr = IStream_Read(stream, buf, sizeof(buf), &read); + ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr); + ok(read == sizeof(buf), "Got read %lu != %Iu.\n", read, sizeof(buf)); + ok(!memcmp(buf, exp_buf, read), "Got mismatching data.\n"); + IStream_Release(stream); + } + + winetest_pop_context(); + } + + hr = IOpcPartSet_GetEnumerator(partset, &partenum); + todo_wine ok(hr == S_OK, "Failed to get part enumerator, hr %#lx.\n", hr); + if (FAILED(hr)) + { + IOpcPartSet_Release(partset); + IOpcPackage_Release(package); + goto done; + } + + hr = IOpcPartEnumerator_GetCurrent(partenum, &part); + ok(hr == OPC_E_ENUM_INVALID_POSITION, "Unexpected hr %#lx.\n", hr); + for(;;) + { + BSTR str; + + hr = IOpcPartEnumerator_MoveNext(partenum, &next); + ok(hr == S_OK, "MoveNext failed, hr %#lx.\n", hr); + if (!next) break; + hr = IOpcPartEnumerator_GetCurrent(partenum, &part); + ok(hr == S_OK, "GetCurrent failed, hr %#lx.\n", hr); + hr = IOpcPart_GetName(part, &uri); + IOpcPart_Release(part); + ok(hr == S_OK, "GetName failed, hr %#lx.\n", hr); + hr = IOpcPartUri_GetAbsoluteUri(uri, &str); + IOpcPartUri_Release(uri); + ok(hr == S_OK, "GetAbsoluteUri failed, hr %#lx.\n", hr); + for (i = 0; i < ARRAY_SIZE(parts); i++) + { + if (!wcscmp(parts[i].uri, str)) + { + ok(!parts[i].found, "Unexpected duplicate part %s.\n", debugstr_w(str)); + parts[i].found = TRUE; + break; + } + } + SysFreeString(str); + } + + hr = IOpcPartEnumerator_GetCurrent(partenum, &part); + ok(hr == OPC_E_ENUM_INVALID_POSITION, "Unexpected hr %#lx.\n", hr); + hr = IOpcPartEnumerator_MoveNext(partenum, &next); + ok(hr == OPC_E_ENUM_CANNOT_MOVE_NEXT, "Unexpected hr %#lx.\n", hr); + + for (i = 0; i < ARRAY_SIZE(parts); i++) + ok(parts[i].found, "Package does not contain part %s.\n", debugstr_w(parts[i].uri)); + + IOpcPartEnumerator_Release(partenum); + IOpcPartSet_Release(partset); + IOpcPackage_Release(package); +done: + IOpcFactory_Release(factory); +} + START_TEST(opcservices) { IOpcFactory *factory; @@ -1266,6 +1443,7 @@ START_TEST(opcservices) test_combine_uri(); test_create_part_uri(); test_write_package(); + test_read_package();
IOpcFactory_Release(factory);
diff --git a/include/opcbase.idl b/include/opcbase.idl index 3df2df80635..fcf641481e2 100644 --- a/include/opcbase.idl +++ b/include/opcbase.idl @@ -49,4 +49,5 @@ cpp_quote("#define OPC_E_DUPLICATE_RELATIONSHIP MAKE_HRESULT(SEVERITY_ERROR, FAC cpp_quote("#define OPC_E_NO_SUCH_PART MAKE_HRESULT(SEVERITY_ERROR, FACILITY_OPC, 0x18)") cpp_quote("#define OPC_E_NO_SUCH_RELATIONSHIP MAKE_HRESULT(SEVERITY_ERROR, FACILITY_OPC, 0x48)") cpp_quote("#define OPC_E_ENUM_COLLECTION_CHANGED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_OPC, 0x50)") +cpp_quote("#define OPC_E_ENUM_CANNOT_MOVE_NEXT MAKE_HRESULT(SEVERITY_ERROR, FACILITY_OPC, 0x51)") cpp_quote("#define OPC_E_ENUM_INVALID_POSITION MAKE_HRESULT(SEVERITY_ERROR, FACILITY_OPC, 0x53)")