2 * Copyright 2022 Dmitry Timoshkov
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(dllhost
);
33 IClassFactory IClassFactory_iface
;
34 IMarshal IMarshal_iface
;
39 static inline struct factory
*impl_from_IClassFactory(IClassFactory
*iface
)
41 return CONTAINING_RECORD(iface
, struct factory
, IClassFactory_iface
);
44 static inline struct factory
*impl_from_IMarshal(IMarshal
*iface
)
46 return CONTAINING_RECORD(iface
, struct factory
, IMarshal_iface
);
49 static HRESULT WINAPI
factory_QueryInterface(IClassFactory
*iface
,
50 REFIID iid
, void **ppv
)
52 struct factory
*factory
= impl_from_IClassFactory(iface
);
54 TRACE("(%p,%s,%p)\n", iface
, wine_dbgstr_guid(iid
), ppv
);
56 if (!ppv
) return E_INVALIDARG
;
58 if (IsEqualIID(iid
, &IID_IUnknown
) ||
59 IsEqualIID(iid
, &IID_IClassFactory
))
61 IClassFactory_AddRef(&factory
->IClassFactory_iface
);
62 *ppv
= &factory
->IClassFactory_iface
;
65 else if (IsEqualIID(iid
, &IID_IMarshal
))
67 IClassFactory_AddRef(&factory
->IClassFactory_iface
);
68 *ppv
= &factory
->IMarshal_iface
;
76 static ULONG WINAPI
factory_AddRef(IClassFactory
*iface
)
78 struct factory
*factory
= impl_from_IClassFactory(iface
);
79 ULONG ref
= InterlockedIncrement(&factory
->ref
);
81 TRACE("(%p)->%lu\n", iface
, ref
);
85 static ULONG WINAPI
factory_Release(IClassFactory
*iface
)
87 struct factory
*factory
= impl_from_IClassFactory(iface
);
88 ULONG ref
= InterlockedDecrement(&factory
->ref
);
90 TRACE("(%p)->%lu\n", iface
, ref
);
93 HeapFree(GetProcessHeap(), 0, factory
);
98 static HRESULT WINAPI
factory_CreateInstance(IClassFactory
*iface
,
99 IUnknown
*punkouter
, REFIID iid
, void **ppv
)
101 FIXME("(%p,%p,%s,%p): stub\n", iface
, punkouter
, wine_dbgstr_guid(iid
), ppv
);
105 static HRESULT WINAPI
factory_LockServer(IClassFactory
*iface
, BOOL lock
)
107 TRACE("(%p,%d)\n", iface
, lock
);
111 static const IClassFactoryVtbl ClassFactory_Vtbl
=
113 factory_QueryInterface
,
116 factory_CreateInstance
,
120 static HRESULT WINAPI
marshal_QueryInterface(IMarshal
*iface
, REFIID iid
, LPVOID
*ppv
)
122 struct factory
*factory
= impl_from_IMarshal(iface
);
124 TRACE("(%p,%s,%p)\n", iface
, wine_dbgstr_guid(iid
), ppv
);
126 return IClassFactory_QueryInterface(&factory
->IClassFactory_iface
, iid
, ppv
);
129 static ULONG WINAPI
marshal_AddRef(IMarshal
*iface
)
131 struct factory
*factory
= impl_from_IMarshal(iface
);
133 TRACE("(%p)\n", iface
);
135 return IClassFactory_AddRef(&factory
->IClassFactory_iface
);
138 static ULONG WINAPI
marshal_Release(IMarshal
*iface
)
140 struct factory
*factory
= impl_from_IMarshal(iface
);
142 TRACE("(%p)\n", iface
);
144 return IClassFactory_Release(&factory
->IClassFactory_iface
);
147 static HRESULT WINAPI
marshal_GetUnmarshalClass(IMarshal
*iface
, REFIID iid
, void *pv
,
148 DWORD dwDestContext
, void *pvDestContext
, DWORD mshlflags
, CLSID
*clsid
)
150 TRACE("(%p,%s,%p,%08lx,%p,%08lx,%p)\n", iface
, wine_dbgstr_guid(iid
), pv
,
151 dwDestContext
, pvDestContext
, mshlflags
, clsid
);
153 *clsid
= CLSID_StdMarshal
;
157 static HRESULT WINAPI
marshal_GetMarshalSizeMax(IMarshal
*iface
, REFIID iid
, void *pv
,
158 DWORD dwDestContext
, void *pvDestContext
, DWORD mshlflags
, DWORD
*size
)
160 FIXME("(%p,%s,%p,%08lx,%p,%08lx,%p): stub\n", iface
, wine_dbgstr_guid(iid
), pv
,
161 dwDestContext
, pvDestContext
, mshlflags
, size
);
165 static HRESULT WINAPI
marshal_MarshalInterface(IMarshal
*iface
, IStream
*stream
, REFIID iid
,
166 void *pv
, DWORD dwDestContext
, void *pvDestContext
, DWORD mshlflags
)
168 struct factory
*factory
= impl_from_IMarshal(iface
);
172 TRACE("(%p,%s,%p,%08lx,%p,%08lx)\n", stream
, wine_dbgstr_guid(iid
), pv
, dwDestContext
, pvDestContext
, mshlflags
);
174 hr
= CoGetClassObject(&factory
->clsid
, CLSCTX_INPROC_SERVER
, NULL
, iid
, (void **)&object
);
177 hr
= CoMarshalInterface(stream
, iid
, object
, dwDestContext
, pvDestContext
, mshlflags
);
178 IUnknown_Release(object
);
183 static HRESULT WINAPI
marshal_UnmarshalInterface(IMarshal
*iface
, IStream
*stream
,
184 REFIID iid
, void **ppv
)
186 FIXME("(%p,%p,%s,%p): stub\n", iface
, stream
, wine_dbgstr_guid(iid
), ppv
);
190 static HRESULT WINAPI
marshal_ReleaseMarshalData(IMarshal
*iface
, IStream
*stream
)
192 TRACE("(%p,%p)\n", iface
, stream
);
196 static HRESULT WINAPI
marshal_DisconnectObject(IMarshal
*iface
, DWORD reserved
)
198 TRACE("(%p, %08lx)\n", iface
, reserved
);
202 static const IMarshalVtbl Marshal_Vtbl
=
204 marshal_QueryInterface
,
207 marshal_GetUnmarshalClass
,
208 marshal_GetMarshalSizeMax
,
209 marshal_MarshalInterface
,
210 marshal_UnmarshalInterface
,
211 marshal_ReleaseMarshalData
,
212 marshal_DisconnectObject
217 ISurrogate ISurrogate_iface
;
218 IClassFactory
*factory
;
224 static inline struct surrogate
*impl_from_ISurrogate(ISurrogate
*iface
)
226 return CONTAINING_RECORD(iface
, struct surrogate
, ISurrogate_iface
);
229 static HRESULT WINAPI
surrogate_QueryInterface(ISurrogate
*iface
,
230 REFIID iid
, void **ppv
)
232 struct surrogate
*surrogate
= impl_from_ISurrogate(iface
);
234 TRACE("(%p,%s,%p)\n", iface
, wine_dbgstr_guid(iid
), ppv
);
236 if (!ppv
) return E_INVALIDARG
;
238 if (IsEqualIID(iid
, &IID_IUnknown
) ||
239 IsEqualIID(iid
, &IID_ISurrogate
))
241 ISurrogate_AddRef(&surrogate
->ISurrogate_iface
);
242 *ppv
= &surrogate
->ISurrogate_iface
;
247 return E_NOINTERFACE
;
250 static ULONG WINAPI
surrogate_AddRef(ISurrogate
*iface
)
252 TRACE("(%p)\n", iface
);
256 static ULONG WINAPI
surrogate_Release(ISurrogate
*iface
)
258 TRACE("(%p)\n", iface
);
262 static HRESULT WINAPI
surrogate_LoadDllServer(ISurrogate
*iface
, const CLSID
*clsid
)
264 struct surrogate
*surrogate
= impl_from_ISurrogate(iface
);
265 struct factory
*factory
;
268 TRACE("(%p,%s)\n", iface
, wine_dbgstr_guid(clsid
));
270 factory
= HeapAlloc(GetProcessHeap(), 0, sizeof(*factory
));
272 return E_OUTOFMEMORY
;
274 factory
->IClassFactory_iface
.lpVtbl
= &ClassFactory_Vtbl
;
275 factory
->IMarshal_iface
.lpVtbl
= &Marshal_Vtbl
;
276 factory
->clsid
= *clsid
;
279 hr
= CoRegisterClassObject(clsid
, (IUnknown
*)&factory
->IClassFactory_iface
,
280 CLSCTX_LOCAL_SERVER
, REGCLS_SURROGATE
, &surrogate
->cookie
);
282 IClassFactory_Release(&factory
->IClassFactory_iface
);
285 surrogate
->factory
= &factory
->IClassFactory_iface
;
286 surrogate
->event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
292 static HRESULT WINAPI
surrogate_FreeSurrogate(ISurrogate
*iface
)
294 struct surrogate
*surrogate
= impl_from_ISurrogate(iface
);
296 TRACE("(%p)\n", iface
);
298 if (surrogate
->cookie
)
300 CoRevokeClassObject(surrogate
->cookie
);
301 surrogate
->cookie
= 0;
304 if (surrogate
->factory
)
306 IClassFactory_Release(surrogate
->factory
);
307 surrogate
->factory
= NULL
;
310 SetEvent(surrogate
->event
);
315 static const ISurrogateVtbl Surrogate_Vtbl
=
317 surrogate_QueryInterface
,
320 surrogate_LoadDllServer
,
321 surrogate_FreeSurrogate
324 int WINAPI
wWinMain(HINSTANCE hinst
, HINSTANCE previnst
, LPWSTR cmdline
, int showcmd
)
328 struct surrogate surrogate
;
330 TRACE("Running as %u-bit\n", (int)sizeof(void *) * 8);
332 if (wcsnicmp(cmdline
, L
"/PROCESSID:", 11))
337 surrogate
.ISurrogate_iface
.lpVtbl
= &Surrogate_Vtbl
;
338 surrogate
.factory
= NULL
;
339 surrogate
.cookie
= 0;
340 surrogate
.event
= NULL
;
343 CoInitializeEx(NULL
, COINIT_MULTITHREADED
);
345 hr
= CLSIDFromString(cmdline
, &clsid
);
348 CoRegisterSurrogate(&surrogate
.ISurrogate_iface
);
350 hr
= ISurrogate_LoadDllServer(&surrogate
.ISurrogate_iface
, &clsid
);
353 ERR("Can't create instance of %s\n", wine_dbgstr_guid(&clsid
));
357 while (WaitForSingleObject(surrogate
.event
, 30000) != WAIT_OBJECT_0
)
358 CoFreeUnusedLibraries();