4 * Copyright (C) 2003 Dominik Strasser
5 * Copyright (C) 2005 Rolf Kalbermatter
6 * Copyright (C) 2019 Zebediah Figura
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "qcap_private.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(qcap
);
28 static HINSTANCE qcap_instance
;
30 static LONG objects_ref
= 0;
34 IClassFactory IClassFactory_iface
;
35 HRESULT (*create_instance
)(IUnknown
*outer
, IUnknown
**out
);
38 static inline struct class_factory
*impl_from_IClassFactory(IClassFactory
*iface
)
40 return CONTAINING_RECORD(iface
, struct class_factory
, IClassFactory_iface
);
43 static HRESULT WINAPI
class_factory_QueryInterface(IClassFactory
*iface
, REFIID iid
, void **out
)
45 TRACE("iface %p, iid %s, out %p.\n", iface
, debugstr_guid(iid
), out
);
47 if (IsEqualGUID(iid
, &IID_IUnknown
) || IsEqualGUID(iid
, &IID_IClassFactory
))
50 IClassFactory_AddRef(iface
);
55 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid
));
59 static ULONG WINAPI
class_factory_AddRef(IClassFactory
*iface
)
64 static ULONG WINAPI
class_factory_Release(IClassFactory
*iface
)
69 static HRESULT WINAPI
class_factory_CreateInstance(IClassFactory
*iface
, IUnknown
*outer
, REFIID iid
, void **out
)
71 struct class_factory
*factory
= impl_from_IClassFactory(iface
);
75 TRACE("iface %p, outer %p, iid %s, out %p.\n", iface
, outer
, debugstr_guid(iid
), out
);
77 if (outer
&& !IsEqualGUID(iid
, &IID_IUnknown
))
81 if (SUCCEEDED(hr
= factory
->create_instance(outer
, &unk
)))
83 hr
= IUnknown_QueryInterface(unk
, iid
, out
);
84 IUnknown_Release(unk
);
89 static HRESULT WINAPI
class_factory_LockServer(IClassFactory
*iface
, BOOL lock
)
91 TRACE("iface %p, lock %d.\n", iface
, lock
);
94 InterlockedIncrement(&objects_ref
);
96 InterlockedDecrement(&objects_ref
);
100 static const IClassFactoryVtbl class_factory_vtbl
=
102 class_factory_QueryInterface
,
103 class_factory_AddRef
,
104 class_factory_Release
,
105 class_factory_CreateInstance
,
106 class_factory_LockServer
,
109 static struct class_factory audio_record_cf
= {{&class_factory_vtbl
}, audio_record_create
};
110 static struct class_factory avi_compressor_cf
= {{&class_factory_vtbl
}, avi_compressor_create
};
111 static struct class_factory avi_mux_cf
= {{&class_factory_vtbl
}, avi_mux_create
};
112 static struct class_factory capture_graph_cf
= {{&class_factory_vtbl
}, capture_graph_create
};
113 static struct class_factory file_writer_cf
= {{&class_factory_vtbl
}, file_writer_create
};
114 static struct class_factory smart_tee_cf
= {{&class_factory_vtbl
}, smart_tee_create
};
115 static struct class_factory vfw_capture_cf
= {{&class_factory_vtbl
}, vfw_capture_create
};
117 BOOL WINAPI
DllMain(HINSTANCE instance
, DWORD reason
, void *reserved
)
119 if (reason
== DLL_PROCESS_ATTACH
)
121 qcap_instance
= instance
;
122 DisableThreadLibraryCalls(instance
);
127 HRESULT WINAPI
DllGetClassObject(REFCLSID clsid
, REFIID iid
, void **out
)
129 struct class_factory
*factory
;
131 TRACE("clsid %s, iid %s, out %p.\n", debugstr_guid(clsid
), debugstr_guid(iid
), out
);
133 if (IsEqualGUID(clsid
, &CLSID_AudioRecord
))
134 factory
= &audio_record_cf
;
135 else if (IsEqualGUID(clsid
, &CLSID_AVICo
))
136 factory
= &avi_compressor_cf
;
137 else if (IsEqualGUID(clsid
, &CLSID_AviDest
))
138 factory
= &avi_mux_cf
;
139 else if (IsEqualGUID(clsid
, &CLSID_CaptureGraphBuilder
))
140 factory
= &capture_graph_cf
;
141 else if (IsEqualGUID(clsid
, &CLSID_CaptureGraphBuilder2
))
142 factory
= &capture_graph_cf
;
143 else if (IsEqualGUID(clsid
, &CLSID_FileWriter
))
144 factory
= &file_writer_cf
;
145 else if (IsEqualGUID(clsid
, &CLSID_SmartTee
))
146 factory
= &smart_tee_cf
;
147 else if (IsEqualGUID(clsid
, &CLSID_VfwCapture
))
148 factory
= &vfw_capture_cf
;
151 FIXME("%s not implemented, returning CLASS_E_CLASSNOTAVAILABLE.\n", debugstr_guid(clsid
));
152 return CLASS_E_CLASSNOTAVAILABLE
;
155 return IClassFactory_QueryInterface(&factory
->IClassFactory_iface
, iid
, out
);
158 static const REGPINTYPES reg_avi_mux_sink_mt
= {&MEDIATYPE_Stream
, &MEDIASUBTYPE_Avi
};
160 static const REGFILTERPINS2 reg_avi_mux_pins
[1] =
165 .lpMediaType
= ®_avi_mux_sink_mt
,
169 static const REGFILTER2 reg_avi_mux
=
172 .dwMerit
= MERIT_DO_NOT_USE
,
174 .u
.s2
.rgPins2
= reg_avi_mux_pins
,
177 static const REGPINTYPES reg_video_mt
= {&MEDIATYPE_Video
, &GUID_NULL
};
179 static const REGFILTERPINS2 reg_smart_tee_pins
[3] =
184 .lpMediaType
= ®_video_mt
,
187 .dwFlags
= REG_PINFLAG_B_OUTPUT
,
190 .lpMediaType
= ®_video_mt
,
193 .dwFlags
= REG_PINFLAG_B_OUTPUT
,
196 .lpMediaType
= ®_video_mt
,
200 static const REGFILTER2 reg_smart_tee
=
203 .dwMerit
= MERIT_DO_NOT_USE
,
205 .u
.s2
.rgPins2
= reg_smart_tee_pins
,
208 static const REGPINTYPES reg_file_writer_sink_mt
= {&GUID_NULL
, &GUID_NULL
};
210 static const REGFILTERPINS2 reg_file_writer_pins
[1] =
215 .lpMediaType
= ®_file_writer_sink_mt
,
219 static const REGFILTER2 reg_file_writer
=
222 .dwMerit
= MERIT_DO_NOT_USE
,
224 .u
.s2
.rgPins2
= reg_file_writer_pins
,
227 /***********************************************************************
228 * DllRegisterServer (QCAP.@)
230 HRESULT WINAPI
DllRegisterServer(void)
232 static const WCHAR avi_muxW
[] = {'A','V','I',' ','M','u','x',0};
233 static const WCHAR file_writerW
[] = {'F','i','l','e',' ','w','r','i','t','e','r',0};
234 static const WCHAR smart_teeW
[] = {'S','m','a','r','t',' ','T','e','e',0};
235 IFilterMapper2
*mapper
;
238 if (FAILED(hr
= __wine_register_resources( qcap_instance
)))
241 if (FAILED(hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
,
242 &IID_IFilterMapper2
, (void **)&mapper
)))
245 IFilterMapper2_RegisterFilter(mapper
, &CLSID_AviDest
, avi_muxW
,
246 NULL
, NULL
, NULL
, ®_avi_mux
);
247 IFilterMapper2_RegisterFilter(mapper
, &CLSID_FileWriter
, file_writerW
,
248 NULL
, NULL
, NULL
, ®_file_writer
);
249 IFilterMapper2_RegisterFilter(mapper
, &CLSID_SmartTee
, smart_teeW
,
250 NULL
, NULL
, NULL
, ®_smart_tee
);
252 IFilterMapper2_Release(mapper
);
256 /***********************************************************************
257 * DllUnregisterServer (QCAP.@)
259 HRESULT WINAPI
DllUnregisterServer(void)
261 IFilterMapper2
*mapper
;
264 if (FAILED(hr
= __wine_unregister_resources( qcap_instance
)))
267 if (FAILED(hr
= CoCreateInstance(&CLSID_FilterMapper2
, NULL
, CLSCTX_INPROC_SERVER
,
268 &IID_IFilterMapper2
, (void **)&mapper
)))
271 IFilterMapper2_UnregisterFilter(mapper
, NULL
, NULL
, &CLSID_AviDest
);
272 IFilterMapper2_UnregisterFilter(mapper
, NULL
, NULL
, &CLSID_FileWriter
);
273 IFilterMapper2_UnregisterFilter(mapper
, NULL
, NULL
, &CLSID_SmartTee
);
275 IFilterMapper2_Release(mapper
);
279 /***********************************************************************
280 * DllCanUnloadNow (QCAP.@)
282 HRESULT WINAPI
DllCanUnloadNow(void)
286 return objects_ref
? S_FALSE
: S_OK
;
289 DWORD
ObjectRefCount(BOOL increment
)
292 return InterlockedIncrement(&objects_ref
);
293 return InterlockedDecrement(&objects_ref
);