Authors: Mike Hearn <mh@codeweavers.com>, Robert Shearman <rob@codeweavers.com>
Change stub manager to track the number of normal marshals instead of
using the state machine so that multiple marshals of the same object
and interface work correctly.
diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h
index 04231e3..88d251b 100644
--- a/dlls/ole32/compobj_private.h
+++ b/dlls/ole32/compobj_private.h
@@ -71,6 +71,7 @@
IID iid; /* RO */
IPID ipid; /* RO */
IUnknown *iface; /* RO */
+ MSHLFLAGS flags; /* so we can enforce process-local marshalling rules (RO) */
};
@@ -87,7 +88,14 @@
OID oid; /* apartment-scoped unique identifier (RO) */
IUnknown *object; /* the object we are managing the stub for (RO) */
ULONG next_ipid; /* currently unused (LOCK) */
- STUB_STATE state; /* state machine (CS lock) */
+
+ /* We need to keep a count of the outstanding marshals, so we can enforce the
+ * marshalling rules (ie, you can only unmarshal normal marshals once). Note
+ * that these counts do NOT include unmarshalled interfaces, once a stream is
+ * unmarshalled and a proxy set up, this count is decremented.
+ */
+
+ ULONG norm_refs; /* refcount of normal marshals (CS lock) */
};
/* imported interface proxy */
@@ -170,15 +178,16 @@
ULONG stub_manager_int_addref(struct stub_manager *This);
ULONG stub_manager_int_release(struct stub_manager *This);
-struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object, MSHLFLAGS mshlflags);
+struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object);
ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs);
ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs);
-struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, IUnknown *iptr, REFIID iid);
+struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, IUnknown *iptr, REFIID iid, MSHLFLAGS flags);
+struct ifstub *stub_manager_find_ifstub(struct stub_manager *m, REFIID iid, MSHLFLAGS flags);
struct stub_manager *get_stub_manager(APARTMENT *apt, OID oid);
struct stub_manager *get_stub_manager_from_object(APARTMENT *apt, void *object);
-BOOL stub_manager_notify_unmarshal(struct stub_manager *m);
-BOOL stub_manager_is_table_marshaled(struct stub_manager *m);
-void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs);
+BOOL stub_manager_notify_unmarshal(struct stub_manager *m, const IPID *ipid);
+BOOL stub_manager_is_table_marshaled(struct stub_manager *m, const IPID *ipid);
+void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const IPID *ipid);
HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub_manager **stubmgr_ret);
IRpcStubBuffer *ipid_to_apt_and_stubbuffer(const IPID *ipid, APARTMENT **stub_apt);
HRESULT start_apartment_remote_unknown(void);