diff --git a/dlls/opcservices/Makefile.in b/dlls/opcservices/Makefile.in index 651cb411d73..47fbbe4cca6 100644 --- a/dlls/opcservices/Makefile.in +++ b/dlls/opcservices/Makefile.in @@ -1,5 +1,5 @@ MODULE = opcservices.dll -IMPORTS = uuid +IMPORTS = uuid ole32 C_SRCS = \ factory.c \ diff --git a/dlls/opcservices/package.c b/dlls/opcservices/package.c index a3a2fabce76..e673f0c892b 100644 --- a/dlls/opcservices/package.c +++ b/dlls/opcservices/package.c @@ -23,6 +23,7 @@ #include "winbase.h" #include "wine/debug.h" +#include "wine/unicode.h" #include "opc_private.h" @@ -40,6 +41,10 @@ struct opc_part { IOpcPart IOpcPart_iface; LONG refcount; + + IOpcPartUri *name; + WCHAR *content_type; + DWORD compression_options; }; struct opc_part_set @@ -63,6 +68,24 @@ static inline struct opc_part *impl_from_IOpcPart(IOpcPart *iface) return CONTAINING_RECORD(iface, struct opc_part, IOpcPart_iface); } +static WCHAR *opc_strdupW(const WCHAR *str) +{ + WCHAR *ret = NULL; + + if (str) + { + size_t size; + + size = (strlenW(str) + 1) * sizeof(WCHAR); + ret = CoTaskMemAlloc(size); + if (ret) + memcpy(ret, str, size); + } + + return ret; +} + + static HRESULT WINAPI opc_part_QueryInterface(IOpcPart *iface, REFIID iid, void **out) { TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); @@ -97,7 +120,11 @@ static ULONG WINAPI opc_part_Release(IOpcPart *iface) TRACE("%p decreasing refcount to %u.\n", iface, refcount); if (!refcount) + { + IOpcPartUri_Release(part->name); + CoTaskMemFree(part->content_type); heap_free(part); + } return refcount; } @@ -118,16 +145,24 @@ static HRESULT WINAPI opc_part_GetContentStream(IOpcPart *iface, IStream **strea static HRESULT WINAPI opc_part_GetName(IOpcPart *iface, IOpcPartUri **name) { - FIXME("iface %p, name %p stub!\n", iface, name); + struct opc_part *part = impl_from_IOpcPart(iface); - return E_NOTIMPL; + TRACE("iface %p, name %p.\n", iface, name); + + *name = part->name; + IOpcPartUri_AddRef(*name); + + return S_OK; } static HRESULT WINAPI opc_part_GetContentType(IOpcPart *iface, LPWSTR *type) { - FIXME("iface %p, type %p stub!\n", iface, type); + struct opc_part *part = impl_from_IOpcPart(iface); - return E_NOTIMPL; + TRACE("iface %p, type %p.\n", iface, type); + + *type = opc_strdupW(part->content_type); + return *type ? S_OK : E_OUTOFMEMORY; } static HRESULT WINAPI opc_part_GetCompressionOptions(IOpcPart *iface, OPC_COMPRESSION_OPTIONS *options) @@ -149,15 +184,27 @@ static const IOpcPartVtbl opc_part_vtbl = opc_part_GetCompressionOptions, }; -static HRESULT opc_part_create(IOpcPart **out) +static HRESULT opc_part_create(IOpcPartUri *name, const WCHAR *content_type, + DWORD compression_options, IOpcPart **out) { struct opc_part *part; + if (!name) + return E_POINTER; + if (!(part = heap_alloc_zero(sizeof(*part)))) return E_OUTOFMEMORY; part->IOpcPart_iface.lpVtbl = &opc_part_vtbl; part->refcount = 1; + part->name = name; + IOpcPartUri_AddRef(name); + part->compression_options = compression_options; + if (!(part->content_type = opc_strdupW(content_type))) + { + IOpcPart_Release(&part->IOpcPart_iface); + return E_OUTOFMEMORY; + } *out = &part->IOpcPart_iface; TRACE("Created part %p.\n", *out); @@ -213,10 +260,10 @@ static HRESULT WINAPI opc_part_set_GetPart(IOpcPartSet *iface, IOpcPartUri *name static HRESULT WINAPI opc_part_set_CreatePart(IOpcPartSet *iface, IOpcPartUri *name, LPCWSTR content_type, OPC_COMPRESSION_OPTIONS compression_options, IOpcPart **part) { - FIXME("iface %p, name %p, content_type %s, compression_options %#x, part %p stub!\n", iface, name, + TRACE("iface %p, name %p, content_type %s, compression_options %#x, part %p.\n", iface, name, debugstr_w(content_type), compression_options, part); - return opc_part_create(part); + return opc_part_create(name, content_type, compression_options, part); } static HRESULT WINAPI opc_part_set_DeletePart(IOpcPartSet *iface, IOpcPartUri *name) diff --git a/dlls/opcservices/tests/opcservices.c b/dlls/opcservices/tests/opcservices.c index e257c6ea2c8..9ef44e6cc30 100644 --- a/dlls/opcservices/tests/opcservices.c +++ b/dlls/opcservices/tests/opcservices.c @@ -36,10 +36,15 @@ static IOpcFactory *create_factory(void) static void test_package(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}; IOpcPartSet *partset, *partset2; + IOpcPartUri *part_uri; IOpcFactory *factory; IOpcPackage *package; + IOpcPart *part; HRESULT hr; + BOOL ret; factory = create_factory(); @@ -58,6 +63,25 @@ static void test_package(void) ok(SUCCEEDED(hr), "Failed to create a part set, hr %#x.\n", hr); ok(partset == partset2, "Expected same part set instance.\n"); + /* CreatePart */ + hr = IOpcFactory_CreatePartUri(factory, uriW, &part_uri); + ok(SUCCEEDED(hr), "Failed to create part uri, hr %#x.\n", hr); + + hr = IOpcPartSet_CreatePart(partset, NULL, typeW, OPC_COMPRESSION_NONE, &part); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + hr = IOpcPartSet_CreatePart(partset, part_uri, typeW, OPC_COMPRESSION_NONE, &part); + ok(SUCCEEDED(hr), "Failed to create a part, hr %#x.\n", hr); + + ret = FALSE; + hr = IOpcPartSet_PartExists(partset, part_uri, &ret); +todo_wine { + ok(SUCCEEDED(hr), "Unexpected hr %#x.\n", hr); + ok(ret, "Expected part to exist.\n"); +} + IOpcPartUri_Release(part_uri); + IOpcPart_Release(part); + IOpcPackage_Release(package); IOpcFactory_Release(factory);