Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- include/opcbase.idl | 15 ++++ include/opcobjectmodel.idl | 174 +++++++++++++++++++++++++++++++++++++ 2 files changed, 189 insertions(+)
diff --git a/include/opcbase.idl b/include/opcbase.idl index fc92675420..33f56ac077 100644 --- a/include/opcbase.idl +++ b/include/opcbase.idl @@ -25,3 +25,18 @@ typedef [v1_enum] enum OPC_STREAM_IO_READ = 1, OPC_STREAM_IO_WRITE = 2, } OPC_STREAM_IO_MODE; + +typedef [v1_enum] enum +{ + OPC_COMPRESSION_NONE = -1, + OPC_COMPRESSION_NORMAL = 0, + OPC_COMPRESSION_MAXIMUM = 1, + OPC_COMPRESSION_FAST = 2, + OPC_COMPRESSION_SUPERFAST = 3, +} OPC_COMPRESSION_OPTIONS; + +typedef [v1_enum] enum +{ + OPC_URI_TARGET_MODE_INTERNAL = 0, + OPC_URI_TARGET_MODE_EXTERNAL = 1, +} OPC_URI_TARGET_MODE; diff --git a/include/opcobjectmodel.idl b/include/opcobjectmodel.idl index e5370d2e54..45bc8aa4a5 100644 --- a/include/opcobjectmodel.idl +++ b/include/opcobjectmodel.idl @@ -20,6 +20,11 @@ #pragma makedep install #endif
+interface IOpcPart; +interface IOpcPartUri; +interface IOpcUri; +interface IOpcRelationship; + typedef [v1_enum] enum { OPC_READ_DEFAULT = 0, @@ -32,3 +37,172 @@ typedef [v1_enum] enum OPC_WRITE_DEFAULT = 0, OPC_WRITE_FORCE_ZIP32 = 1, } OPC_WRITE_FLAGS; + +[ + object, + uuid(42195949-3b79-4fc8-89c6-fc7fb979ee75), + pointer_default(ref) +] +interface IOpcPartEnumerator : IUnknown +{ + HRESULT MoveNext( + [out, retval] BOOL *has_next + ); + + HRESULT MovePrevious( + [out, retval] BOOL *has_previous + ); + + HRESULT GetCurrent( + [out, retval] IOpcPart **part + ); + + HRESULT Clone( + [out, retval] IOpcPartEnumerator **enumerator + ); +} + +[ + object, + uuid(42195949-3b79-4fc8-89c6-fc7fb979ee76), + pointer_default(ref) +] +interface IOpcRelationshipEnumerator : IUnknown +{ + HRESULT MoveNext( + [out, retval] BOOL *has_next + ); + + HRESULT MovePrevious( + [out, retval] BOOL *has_previous + ); + + HRESULT GetCurrent( + [out, retval] IOpcRelationship **relationship + ); + + HRESULT Clone( + [out, retval] IOpcRelationshipEnumerator **enumerator + ); +} + +[ + object, + uuid(42195949-3b79-4fc8-89c6-fc7fb979ee73), + pointer_default(ref) +] +interface IOpcPartSet : IUnknown +{ + HRESULT GetPart( + [in] IOpcPartUri *name, + [out, retval] IOpcPart **part + ); + + HRESULT CreatePart( + [in] IOpcPartUri *name, + [in, string] LPCWSTR content_type, + [in] OPC_COMPRESSION_OPTIONS compression_options, + [out, retval] IOpcPart **part + ); + + HRESULT DeletePart( + [in] IOpcPartUri *name + ); + + HRESULT PartExists( + [in] IOpcPartUri *name, + [out, retval] BOOL *exists + ); + + HRESULT GetEnumerator( + [out, retval] IOpcPartEnumerator **enumerator + ); +} + +[ + object, + uuid(42195949-3b79-4fc8-89c6-fc7fb979ee72), + pointer_default(ref) +] +interface IOpcRelationship : IUnknown +{ + HRESULT GetId( + [out, string, retval] LPWSTR *id + ); + + HRESULT GetRelationshipType( + [out, string, retval] LPWSTR *type + ); + + HRESULT GetSourceUri( + [out, retval] IOpcUri **uri + ); + + HRESULT GetTargetUri( + [out, retval] IUri **target + ); + + HRESULT GetTargetMode( + [out, retval] OPC_URI_TARGET_MODE *target_mode + ); +} + + +[ + object, + uuid(42195949-3b79-4fc8-89c6-fc7fb979ee74), + pointer_default(ref) +] +interface IOpcRelationshipSet : IUnknown +{ + HRESULT GetRelationship( + [in, string] LPCWSTR id, + [out, retval] IOpcRelationship **relationship + ); + + HRESULT CreateRelationship( + [in, string, unique] LPCWSTR id, + [in, string] LPCWSTR type, + [in] IUri *target_uri, + [in] OPC_URI_TARGET_MODE target_mode, + [out, retval] IOpcRelationship **relationship + ); + + HRESULT DeleteRelationship( + [in, string] LPCWSTR id + ); + + HRESULT RelationshipExists( + [in, string] LPCWSTR id, + [out, retval] BOOL *exists + ); + + HRESULT GetEnumerator( + [out, retval] IOpcRelationshipEnumerator **enumerator + ); + + HRESULT GetEnumeratorForType( + [in, string] LPCWSTR type, + [out, retval] IOpcRelationshipEnumerator **enumerator + ); + + HRESULT GetRelationshipsContentStream( + [out, retval] IStream **stream + ); +} + +[ + object, + uuid(42195949-3b79-4fc8-89c6-fc7fb979ee70), + pointer_default(ref) +] +interface IOpcPackage : IUnknown +{ + HRESULT GetPartSet( + [out, retval] IOpcPartSet **part_set + ); + + HRESULT GetRelationshipSet( + [out, retval] IOpcRelationshipSet **relationship_set + ); +}
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/opcservices/Makefile.in | 3 +- dlls/opcservices/factory.c | 6 +- dlls/opcservices/opc_private.h | 22 +++++++ dlls/opcservices/package.c | 117 +++++++++++++++++++++++++++++++++ 4 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 dlls/opcservices/opc_private.h create mode 100644 dlls/opcservices/package.c
diff --git a/dlls/opcservices/Makefile.in b/dlls/opcservices/Makefile.in index 20d8eb5262..4a2d2945ae 100644 --- a/dlls/opcservices/Makefile.in +++ b/dlls/opcservices/Makefile.in @@ -2,7 +2,8 @@ MODULE = opcservices.dll IMPORTS = uuid
C_SRCS = \ - factory.c + factory.c \ + package.c
IDL_SRCS = \ opcservices.idl diff --git a/dlls/opcservices/factory.c b/dlls/opcservices/factory.c index dd6556db8a..b2a57c42ec 100644 --- a/dlls/opcservices/factory.c +++ b/dlls/opcservices/factory.c @@ -29,6 +29,8 @@
#include "wine/debug.h"
+#include "opc_private.h" + WINE_DEFAULT_DEBUG_CHANNEL(msopc);
static HRESULT WINAPI opc_factory_QueryInterface(IOpcFactory *iface, REFIID iid, void **out) @@ -82,9 +84,9 @@ static HRESULT WINAPI opc_factory_CreateStreamOnFile(IOpcFactory *iface, LPCWSTR
static HRESULT WINAPI opc_factory_CreatePackage(IOpcFactory *iface, IOpcPackage **package) { - FIXME("iface %p, package %p.\n", iface, package); + TRACE("iface %p, package %p.\n", iface, package);
- return E_NOTIMPL; + return opc_package_create(package); }
static HRESULT WINAPI opc_factory_ReadPackageFromStream(IOpcFactory *iface, IStream *stream, diff --git a/dlls/opcservices/opc_private.h b/dlls/opcservices/opc_private.h new file mode 100644 index 0000000000..492ec91280 --- /dev/null +++ b/dlls/opcservices/opc_private.h @@ -0,0 +1,22 @@ +/* + * 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 + */ + +#include "msopc.h" +#include "wine/heap.h" + +extern HRESULT opc_package_create(IOpcPackage **package) DECLSPEC_HIDDEN; diff --git a/dlls/opcservices/package.c b/dlls/opcservices/package.c new file mode 100644 index 0000000000..527bf949e5 --- /dev/null +++ b/dlls/opcservices/package.c @@ -0,0 +1,117 @@ +/* + * 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 <stdarg.h> +#include "windef.h" +#include "winbase.h" + +#include "wine/debug.h" + +#include "opc_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msopc); + +struct opc_package +{ + IOpcPackage IOpcPackage_iface; + LONG refcount; +}; + +static inline struct opc_package *impl_from_IOpcPackage(IOpcPackage *iface) +{ + return CONTAINING_RECORD(iface, struct opc_package, IOpcPackage_iface); +} + +static HRESULT WINAPI opc_package_QueryInterface(IOpcPackage *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualIID(iid, &IID_IOpcPackage) || + IsEqualIID(iid, &IID_IUnknown)) + { + *out = iface; + IOpcPackage_AddRef(iface); + return S_OK; + } + + WARN("Unsupported interface %s.\n", debugstr_guid(iid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI opc_package_AddRef(IOpcPackage *iface) +{ + struct opc_package *package = impl_from_IOpcPackage(iface); + ULONG refcount = InterlockedIncrement(&package->refcount); + + TRACE("%p increasing refcount to %u.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI opc_package_Release(IOpcPackage *iface) +{ + struct opc_package *package = impl_from_IOpcPackage(iface); + ULONG refcount = InterlockedDecrement(&package->refcount); + + TRACE("%p decreasing refcount to %u.\n", iface, refcount); + + if (!refcount) + heap_free(package); + + return refcount; +} + +static HRESULT WINAPI opc_package_GetPartSet(IOpcPackage *iface, IOpcPartSet **part_set) +{ + FIXME("iface %p, part_set %p stub!\n", iface, part_set); + + return E_NOTIMPL; +} + +static HRESULT WINAPI opc_package_GetRelationshipSet(IOpcPackage *iface, IOpcRelationshipSet **relationship_set) +{ + FIXME("iface %p, relationship_set %p stub!\n", iface, relationship_set); + + return E_NOTIMPL; +} + +static const IOpcPackageVtbl opc_package_vtbl = +{ + opc_package_QueryInterface, + opc_package_AddRef, + opc_package_Release, + opc_package_GetPartSet, + opc_package_GetRelationshipSet, +}; + +HRESULT opc_package_create(IOpcPackage **out) +{ + struct opc_package *package; + + if (!(package = heap_alloc(sizeof(*package)))) + return E_OUTOFMEMORY; + + package->IOpcPackage_iface.lpVtbl = &opc_package_vtbl; + package->refcount = 1; + + *out = &package->IOpcPackage_iface; + TRACE("Created package %p.\n", *out); + return S_OK; +}
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/opcservices/package.c | 128 ++++++++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 3 deletions(-)
diff --git a/dlls/opcservices/package.c b/dlls/opcservices/package.c index 527bf949e5..c49c980e65 100644 --- a/dlls/opcservices/package.c +++ b/dlls/opcservices/package.c @@ -32,6 +32,14 @@ struct opc_package { IOpcPackage IOpcPackage_iface; LONG refcount; + + IOpcPartSet *part_set; +}; + +struct opc_part_set +{ + IOpcPartSet IOpcPartSet_iface; + LONG refcount; };
static inline struct opc_package *impl_from_IOpcPackage(IOpcPackage *iface) @@ -39,6 +47,99 @@ static inline struct opc_package *impl_from_IOpcPackage(IOpcPackage *iface) return CONTAINING_RECORD(iface, struct opc_package, IOpcPackage_iface); }
+static inline struct opc_part_set *impl_from_IOpcPartSet(IOpcPartSet *iface) +{ + return CONTAINING_RECORD(iface, struct opc_part_set, IOpcPartSet_iface); +} + +static HRESULT WINAPI opc_part_set_QueryInterface(IOpcPartSet *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualIID(iid, &IID_IOpcPartSet) || + IsEqualIID(iid, &IID_IUnknown)) + { + *out = iface; + IOpcPartSet_AddRef(iface); + return S_OK; + } + + WARN("Unsupported interface %s.\n", debugstr_guid(iid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI opc_part_set_AddRef(IOpcPartSet *iface) +{ + struct opc_part_set *part_set = impl_from_IOpcPartSet(iface); + ULONG refcount = InterlockedIncrement(&part_set->refcount); + + TRACE("%p increasing refcount to %u.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI opc_part_set_Release(IOpcPartSet *iface) +{ + struct opc_part_set *part_set = impl_from_IOpcPartSet(iface); + ULONG refcount = InterlockedDecrement(&part_set->refcount); + + TRACE("%p decreasing refcount to %u.\n", iface, refcount); + + if (!refcount) + heap_free(part_set); + + return refcount; +} + +static HRESULT WINAPI opc_part_set_GetPart(IOpcPartSet *iface, IOpcPartUri *name, IOpcPart **part) +{ + FIXME("iface %p, name %p, part %p stub!\n", iface, name, part); + + return E_NOTIMPL; +} + +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, + debugstr_w(content_type), compression_options, part); + + return E_NOTIMPL; +} + +static HRESULT WINAPI opc_part_set_DeletePart(IOpcPartSet *iface, IOpcPartUri *name) +{ + FIXME("iface %p, name %p stub!\n", iface, name); + + return E_NOTIMPL; +} + +static HRESULT WINAPI opc_part_set_PartExists(IOpcPartSet *iface, IOpcPartUri *name, BOOL *exists) +{ + FIXME("iface %p, name %p, exists %p stub!\n", iface, name, exists); + + return E_NOTIMPL; +} + +static HRESULT WINAPI opc_part_set_GtEnumerator(IOpcPartSet *iface, IOpcPartEnumerator **enumerator) +{ + FIXME("iface %p, enumerator %p stub!\n", iface, enumerator); + + return E_NOTIMPL; +} + +static const IOpcPartSetVtbl opc_part_set_vtbl = +{ + opc_part_set_QueryInterface, + opc_part_set_AddRef, + opc_part_set_Release, + opc_part_set_GetPart, + opc_part_set_CreatePart, + opc_part_set_DeletePart, + opc_part_set_PartExists, + opc_part_set_GtEnumerator, +}; + static HRESULT WINAPI opc_package_QueryInterface(IOpcPackage *iface, REFIID iid, void **out) { TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); @@ -73,16 +174,37 @@ static ULONG WINAPI opc_package_Release(IOpcPackage *iface) TRACE("%p decreasing refcount to %u.\n", iface, refcount);
if (!refcount) + { + if (package->part_set) + IOpcPartSet_Release(package->part_set); heap_free(package); + }
return refcount; }
static HRESULT WINAPI opc_package_GetPartSet(IOpcPackage *iface, IOpcPartSet **part_set) { - FIXME("iface %p, part_set %p stub!\n", iface, part_set); + struct opc_package *package = impl_from_IOpcPackage(iface);
- return E_NOTIMPL; + TRACE("iface %p, part_set %p.\n", iface, part_set); + + if (!package->part_set) + { + struct opc_part_set *part_set = heap_alloc_zero(sizeof(*part_set)); + if (!part_set) + return E_OUTOFMEMORY; + + part_set->IOpcPartSet_iface.lpVtbl = &opc_part_set_vtbl; + part_set->refcount = 1; + + package->part_set = &part_set->IOpcPartSet_iface; + } + + *part_set = package->part_set; + IOpcPartSet_AddRef(*part_set); + + return S_OK; }
static HRESULT WINAPI opc_package_GetRelationshipSet(IOpcPackage *iface, IOpcRelationshipSet **relationship_set) @@ -105,7 +227,7 @@ HRESULT opc_package_create(IOpcPackage **out) { struct opc_package *package;
- if (!(package = heap_alloc(sizeof(*package)))) + if (!(package = heap_alloc_zero(sizeof(*package)))) return E_OUTOFMEMORY;
package->IOpcPackage_iface.lpVtbl = &opc_package_vtbl;