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
;
37 IClassFactory
*dll_factory
;
40 static inline struct factory
*impl_from_IClassFactory(IClassFactory
*iface
)
42 return CONTAINING_RECORD(iface
, struct factory
, IClassFactory_iface
);
45 static inline struct factory
*impl_from_IMarshal(IMarshal
*iface
)
47 return CONTAINING_RECORD(iface
, struct factory
, IMarshal_iface
);
50 static HRESULT WINAPI
factory_QueryInterface(IClassFactory
*iface
,
51 REFIID iid
, void **ppv
)
53 struct factory
*factory
= impl_from_IClassFactory(iface
);
55 TRACE("(%p,%s,%p)\n", iface
, wine_dbgstr_guid(iid
), ppv
);
57 if (!ppv
) return E_INVALIDARG
;
59 if (IsEqualIID(iid
, &IID_IUnknown
) ||
60 IsEqualIID(iid
, &IID_IClassFactory
))
62 IClassFactory_AddRef(&factory
->IClassFactory_iface
);
63 *ppv
= &factory
->IClassFactory_iface
;
66 else if (IsEqualIID(iid
, &IID_IMarshal
))
68 IClassFactory_AddRef(&factory
->IClassFactory_iface
);
69 *ppv
= &factory
->IMarshal_iface
;
77 static ULONG WINAPI
factory_AddRef(IClassFactory
*iface
)
79 struct factory
*factory
= impl_from_IClassFactory(iface
);
80 ULONG ref
= InterlockedIncrement(&factory
->ref
);
82 TRACE("(%p)->%lu\n", iface
, ref
);
86 static ULONG WINAPI
factory_Release(IClassFactory
*iface
)
88 struct factory
*factory
= impl_from_IClassFactory(iface
);
89 ULONG ref
= InterlockedDecrement(&factory
->ref
);
91 TRACE("(%p)->%lu\n", iface
, ref
);
95 if (factory
->dll_factory
) IClassFactory_Release(factory
->dll_factory
);
96 HeapFree(GetProcessHeap(), 0, factory
);
102 static HRESULT WINAPI
factory_CreateInstance(IClassFactory
*iface
,
103 IUnknown
*punkouter
, REFIID iid
, void **ppv
)
105 FIXME("(%p,%p,%s,%p): stub\n", iface
, punkouter
, wine_dbgstr_guid(iid
), ppv
);
109 static HRESULT WINAPI
factory_LockServer(IClassFactory
*iface
, BOOL lock
)
111 TRACE("(%p,%d)\n", iface
, lock
);
115 static const IClassFactoryVtbl ClassFactory_Vtbl
=
117 factory_QueryInterface
,
120 factory_CreateInstance
,
124 static HRESULT WINAPI
marshal_QueryInterface(IMarshal
*iface
, REFIID iid
, LPVOID
*ppv
)
126 struct factory
*factory
= impl_from_IMarshal(iface
);
128 TRACE("(%p,%s,%p)\n", iface
, wine_dbgstr_guid(iid
), ppv
);
130 return IClassFactory_QueryInterface(&factory
->IClassFactory_iface
, iid
, ppv
);
133 static ULONG WINAPI
marshal_AddRef(IMarshal
*iface
)
135 struct factory
*factory
= impl_from_IMarshal(iface
);
137 TRACE("(%p)\n", iface
);
139 return IClassFactory_AddRef(&factory
->IClassFactory_iface
);
142 static ULONG WINAPI
marshal_Release(IMarshal
*iface
)
144 struct factory
*factory
= impl_from_IMarshal(iface
);
146 TRACE("(%p)\n", iface
);
148 return IClassFactory_Release(&factory
->IClassFactory_iface
);
151 static HRESULT WINAPI
marshal_GetUnmarshalClass(IMarshal
*iface
, REFIID iid
, void *pv
,
152 DWORD dwDestContext
, void *pvDestContext
, DWORD mshlflags
, CLSID
*clsid
)
154 TRACE("(%p,%s,%p,%08lx,%p,%08lx,%p)\n", iface
, wine_dbgstr_guid(iid
), pv
,
155 dwDestContext
, pvDestContext
, mshlflags
, clsid
);
157 *clsid
= CLSID_StdMarshal
;
161 static HRESULT WINAPI
marshal_GetMarshalSizeMax(IMarshal
*iface
, REFIID iid
, void *pv
,
162 DWORD dwDestContext
, void *pvDestContext
, DWORD mshlflags
, DWORD
*size
)
164 FIXME("(%p,%s,%p,%08lx,%p,%08lx,%p): stub\n", iface
, wine_dbgstr_guid(iid
), pv
,
165 dwDestContext
, pvDestContext
, mshlflags
, size
);
169 static HRESULT WINAPI
marshal_MarshalInterface(IMarshal
*iface
, IStream
*stream
, REFIID iid
,
170 void *pv
, DWORD dwDestContext
, void *pvDestContext
, DWORD mshlflags
)
172 struct factory
*factory
= impl_from_IMarshal(iface
);
174 TRACE("(%p,%s,%p,%08lx,%p,%08lx)\n", stream
, wine_dbgstr_guid(iid
), pv
, dwDestContext
, pvDestContext
, mshlflags
);
176 return CoMarshalInterface(stream
, iid
, (IUnknown
*)factory
->dll_factory
, dwDestContext
, pvDestContext
, mshlflags
);
179 static HRESULT WINAPI
marshal_UnmarshalInterface(IMarshal
*iface
, IStream
*stream
,
180 REFIID iid
, void **ppv
)
182 FIXME("(%p,%p,%s,%p): stub\n", iface
, stream
, wine_dbgstr_guid(iid
), ppv
);
186 static HRESULT WINAPI
marshal_ReleaseMarshalData(IMarshal
*iface
, IStream
*stream
)
188 TRACE("(%p,%p)\n", iface
, stream
);
192 static HRESULT WINAPI
marshal_DisconnectObject(IMarshal
*iface
, DWORD reserved
)
194 TRACE("(%p, %08lx)\n", iface
, reserved
);
198 static const IMarshalVtbl Marshal_Vtbl
=
200 marshal_QueryInterface
,
203 marshal_GetUnmarshalClass
,
204 marshal_GetMarshalSizeMax
,
205 marshal_MarshalInterface
,
206 marshal_UnmarshalInterface
,
207 marshal_ReleaseMarshalData
,
208 marshal_DisconnectObject
213 ISurrogate ISurrogate_iface
;
214 IClassFactory
*factory
;
220 static inline struct surrogate
*impl_from_ISurrogate(ISurrogate
*iface
)
222 return CONTAINING_RECORD(iface
, struct surrogate
, ISurrogate_iface
);
225 static HRESULT WINAPI
surrogate_QueryInterface(ISurrogate
*iface
,
226 REFIID iid
, void **ppv
)
228 struct surrogate
*surrogate
= impl_from_ISurrogate(iface
);
230 TRACE("(%p,%s,%p)\n", iface
, wine_dbgstr_guid(iid
), ppv
);
232 if (!ppv
) return E_INVALIDARG
;
234 if (IsEqualIID(iid
, &IID_IUnknown
) ||
235 IsEqualIID(iid
, &IID_ISurrogate
))
237 ISurrogate_AddRef(&surrogate
->ISurrogate_iface
);
238 *ppv
= &surrogate
->ISurrogate_iface
;
243 return E_NOINTERFACE
;
246 static ULONG WINAPI
surrogate_AddRef(ISurrogate
*iface
)
248 TRACE("(%p)\n", iface
);
252 static ULONG WINAPI
surrogate_Release(ISurrogate
*iface
)
254 TRACE("(%p)\n", iface
);
258 static HRESULT WINAPI
surrogate_LoadDllServer(ISurrogate
*iface
, const CLSID
*clsid
)
260 struct surrogate
*surrogate
= impl_from_ISurrogate(iface
);
261 struct factory
*factory
;
264 TRACE("(%p,%s)\n", iface
, wine_dbgstr_guid(clsid
));
266 factory
= HeapAlloc(GetProcessHeap(), 0, sizeof(*factory
));
268 return E_OUTOFMEMORY
;
270 factory
->IClassFactory_iface
.lpVtbl
= &ClassFactory_Vtbl
;
271 factory
->IMarshal_iface
.lpVtbl
= &Marshal_Vtbl
;
272 factory
->clsid
= *clsid
;
274 factory
->dll_factory
= NULL
;
276 hr
= CoGetClassObject(clsid
, CLSCTX_INPROC_SERVER
, NULL
, &IID_IClassFactory
, (void **)&factory
->dll_factory
);
278 hr
= CoRegisterClassObject(clsid
, (IUnknown
*)&factory
->IClassFactory_iface
,
279 CLSCTX_LOCAL_SERVER
, REGCLS_SURROGATE
, &surrogate
->cookie
);
281 IClassFactory_Release(&factory
->IClassFactory_iface
);
284 surrogate
->factory
= &factory
->IClassFactory_iface
;
285 surrogate
->event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
291 static HRESULT WINAPI
surrogate_FreeSurrogate(ISurrogate
*iface
)
293 struct surrogate
*surrogate
= impl_from_ISurrogate(iface
);
295 TRACE("(%p)\n", iface
);
297 if (surrogate
->cookie
)
299 CoRevokeClassObject(surrogate
->cookie
);
300 surrogate
->cookie
= 0;
303 if (surrogate
->factory
)
305 IClassFactory_Release(surrogate
->factory
);
306 surrogate
->factory
= NULL
;
309 SetEvent(surrogate
->event
);
314 static const ISurrogateVtbl Surrogate_Vtbl
=
316 surrogate_QueryInterface
,
319 surrogate_LoadDllServer
,
320 surrogate_FreeSurrogate
323 int WINAPI
wWinMain(HINSTANCE hinst
, HINSTANCE previnst
, LPWSTR cmdline
, int showcmd
)
327 struct surrogate surrogate
;
329 TRACE("Running as %u-bit\n", (int)sizeof(void *) * 8);
331 if (wcsnicmp(cmdline
, L
"/PROCESSID:", 11))
336 surrogate
.ISurrogate_iface
.lpVtbl
= &Surrogate_Vtbl
;
337 surrogate
.factory
= NULL
;
338 surrogate
.cookie
= 0;
339 surrogate
.event
= NULL
;
342 CoInitializeEx(NULL
, COINIT_MULTITHREADED
);
344 hr
= CLSIDFromString(cmdline
, &clsid
);
347 CoRegisterSurrogate(&surrogate
.ISurrogate_iface
);
349 hr
= ISurrogate_LoadDllServer(&surrogate
.ISurrogate_iface
, &clsid
);
352 ERR("Can't create instance of %s\n", wine_dbgstr_guid(&clsid
));
356 while (WaitForSingleObject(surrogate
.event
, 30000) != WAIT_OBJECT_0
)
357 CoFreeUnusedLibraries();