Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

506 lines
20 KiB

  1. //
  2. // dllmain.cpp
  3. //
  4. // Copyright (c) 1997-2001 Microsoft Corporation
  5. //
  6. #pragma warning(disable:4530)
  7. #include <objbase.h>
  8. #include "debug.h"
  9. #include "oledll.h"
  10. #include "dsdmo.h"
  11. #include "chorusp.h"
  12. #include "compressp.h"
  13. #include "distortp.h"
  14. #include "echop.h"
  15. #include "flangerp.h"
  16. #include "parameqp.h"
  17. #include "garglep.h"
  18. #include "sverbp.h"
  19. #include "map.h"
  20. #include "aecp.h"
  21. #include "nsp.h"
  22. #include "agcp.h"
  23. #include "reghlp.h"
  24. // These are linked in
  25. class CDirectSoundI3DL2ReverbDMO;
  26. EXT_STD_CREATE(I3DL2Reverb);
  27. //class CDirectSoundI3DL2SourceDMO;
  28. //EXT_STD_CREATE(I3DL2Source);
  29. DWORD g_amPlatform;
  30. int g_cActiveObjects = 0;
  31. //
  32. // this is a temporary place holder only! the dmocom.cpp base class requires this global to be defined
  33. // so we're putting something in it for now. Class factory templates aren't used currently, but eventually
  34. // we should use the template structure to create all dmo objects.
  35. //
  36. struct CComClassTemplate g_ComClassTemplates[] =
  37. {
  38. {&GUID_DSFX_STANDARD_GARGLE, CreateCDirectSoundGargleDMO}
  39. };
  40. int g_cComClassTemplates = 0;
  41. #define DefineClassFactory(x) \
  42. class x ## Factory : public IClassFactory \
  43. { \
  44. public: \
  45. virtual STDMETHODIMP QueryInterface(const IID &iid, void **ppv); \
  46. virtual STDMETHODIMP_(ULONG) AddRef(); \
  47. virtual STDMETHODIMP_(ULONG) Release(); \
  48. \
  49. virtual STDMETHODIMP CreateInstance(IUnknown* pUnknownOuter, \
  50. const IID& iid, void** ppv); \
  51. virtual STDMETHODIMP LockServer(BOOL bLock); \
  52. \
  53. x ## Factory() : m_cRef(1) {} \
  54. \
  55. ~ x ## Factory() {} \
  56. \
  57. private: \
  58. long m_cRef; \
  59. }; \
  60. STDMETHODIMP x ## Factory::QueryInterface( \
  61. const IID &iid, void **ppv) \
  62. { \
  63. if(iid == IID_IUnknown || iid == IID_IClassFactory) \
  64. { \
  65. *ppv = static_cast<IClassFactory*>(this); \
  66. } \
  67. else \
  68. { \
  69. *ppv = NULL; \
  70. return E_NOINTERFACE; \
  71. } \
  72. \
  73. reinterpret_cast<IUnknown*>(*ppv)->AddRef(); \
  74. \
  75. return S_OK; \
  76. } \
  77. STDMETHODIMP_(ULONG) x ## Factory::AddRef() \
  78. { \
  79. return InterlockedIncrement(&m_cRef); \
  80. } \
  81. \
  82. STDMETHODIMP_(ULONG) x ## Factory::Release() \
  83. { \
  84. if(!InterlockedDecrement(&m_cRef)) \
  85. { \
  86. delete this; \
  87. return 0; \
  88. } \
  89. \
  90. return m_cRef; \
  91. } \
  92. \
  93. STDMETHODIMP x ## Factory::CreateInstance( \
  94. IUnknown* pUnknownOuter, const IID& riid, void** ppv) \
  95. { \
  96. Trace(DM_DEBUG_STATUS, "Create " #x "\n"); \
  97. if (ppv == NULL) \
  98. { \
  99. return E_POINTER; \
  100. } \
  101. \
  102. if (pUnknownOuter != NULL) { \
  103. if (IsEqualIID(riid,IID_IUnknown) == FALSE) { \
  104. return ResultFromScode(E_NOINTERFACE); \
  105. } \
  106. } \
  107. \
  108. HRESULT hr = S_OK; \
  109. CComBase *p = Create ## x(pUnknownOuter, &hr); \
  110. if (SUCCEEDED(hr)) \
  111. { \
  112. p->NDAddRef(); \
  113. hr = p->NDQueryInterface(riid, ppv); \
  114. p->NDRelease(); \
  115. } \
  116. \
  117. return hr; \
  118. } \
  119. STDMETHODIMP x ## Factory::LockServer(BOOL bLock) \
  120. { \
  121. if(bLock) \
  122. { \
  123. InterlockedIncrement(&g_cLock); \
  124. } \
  125. else \
  126. { \
  127. InterlockedDecrement(&g_cLock); \
  128. } \
  129. \
  130. return S_OK; \
  131. }
  132. #define DefineDMOClassFactory(x) DefineClassFactory(CDirectSound ## x ## DMO)
  133. #define DefineDMOCaptureClassFactory(x) DefineClassFactory(CDirectSoundCapture ## x ## DMO)
  134. //////////////////////////////////////////////////////////////////////
  135. // Globals
  136. //
  137. // Registry Info
  138. //
  139. #define DefineNames(x) \
  140. TCHAR g_sz## x ##FriendlyName[] = TEXT("DirectSound" #x "DMO"); \
  141. TCHAR g_sz## x ##VerIndProgID[] = TEXT("Microsoft.DirectSound" #x "DMO"); \
  142. TCHAR g_sz## x ##ProgID[] = TEXT("Microsoft.DirectSound" #x "DMO.1"); \
  143. #define DefineCaptureNames(x) \
  144. TCHAR g_sz## x ##FriendlyName[] = TEXT("DirectSoundCapture" #x "DMO"); \
  145. TCHAR g_sz## x ##VerIndProgID[] = TEXT("Microsoft.DirectSoundCapture" #x "DMO"); \
  146. TCHAR g_sz## x ##ProgID[] = TEXT("Microsoft.DirectSoundCapture" #x "DMO.1"); \
  147. DefineNames(Chorus)
  148. DefineNames(Compressor)
  149. DefineNames(Distortion)
  150. DefineNames(Echo)
  151. DefineNames(Flanger)
  152. DefineNames(ParamEq)
  153. DefineNames(Gargle)
  154. DefineNames(WavesReverb)
  155. DefineNames(I3DL2Reverb)
  156. //DefineNames(I3DL2Source)
  157. //DefineCaptureNames(MicArray)
  158. DefineCaptureNames(Aec)
  159. DefineCaptureNames(NoiseSuppress)
  160. DefineCaptureNames(Agc)
  161. // Dll's hModule
  162. HMODULE g_hModule = NULL;
  163. // Count of class factory server locks
  164. long g_cLock = 0;
  165. DefineDMOClassFactory(Chorus)
  166. DefineDMOClassFactory(Compressor)
  167. DefineDMOClassFactory(Distortion)
  168. DefineDMOClassFactory(Echo)
  169. DefineDMOClassFactory(Flanger)
  170. DefineDMOClassFactory(ParamEq)
  171. DefineDMOClassFactory(I3DL2Reverb)
  172. //DefineDMOClassFactory(I3DL2Source)
  173. DefineDMOClassFactory(Gargle)
  174. DefineDMOClassFactory(WavesReverb)
  175. // Capture FXs
  176. //DefineDMOCaptureClassFactory(MicArray)
  177. DefineDMOCaptureClassFactory(Aec)
  178. DefineDMOCaptureClassFactory(NoiseSuppress)
  179. DefineDMOCaptureClassFactory(Agc)
  180. //////////////////////////////////////////////////////////////////////
  181. // Standard calls needed to be an inproc server
  182. //////////////////////////////////////////////////////////////////////
  183. // DllCanUnloadNow
  184. STDAPI DllCanUnloadNow()
  185. {
  186. if (g_cActiveObjects || g_cLock)
  187. {
  188. return S_FALSE;
  189. }
  190. return S_OK;
  191. }
  192. // Hack to make these macros continue to work:
  193. #define GUID_DSFX_STANDARD_Chorus GUID_DSFX_STANDARD_CHORUS
  194. #define GUID_DSFX_STANDARD_Compressor GUID_DSFX_STANDARD_COMPRESSOR
  195. #define GUID_DSFX_STANDARD_Distortion GUID_DSFX_STANDARD_DISTORTION
  196. #define GUID_DSFX_STANDARD_Echo GUID_DSFX_STANDARD_ECHO
  197. #define GUID_DSFX_STANDARD_Flanger GUID_DSFX_STANDARD_FLANGER
  198. #define GUID_DSFX_STANDARD_ParamEq GUID_DSFX_STANDARD_PARAMEQ
  199. #define GUID_DSFX_STANDARD_Gargle GUID_DSFX_STANDARD_GARGLE
  200. #define GUID_DSFX_STANDARD_WavesReverb GUID_DSFX_WAVES_REVERB
  201. #define GUID_DSFX_STANDARD_I3DL2Reverb GUID_DSFX_STANDARD_I3DL2REVERB
  202. #define GUID_DSFX_STANDARD_I3DL2Source GUID_DSFX_STANDARD_I3DL2SOURCE
  203. // Capture
  204. #define GUID_DSCFX_MS_Aec GUID_DSCFX_MS_AEC
  205. #define GUID_DSCFX_MS_NoiseSuppress GUID_DSCFX_MS_NS
  206. #define GUID_DSCFX_MS_Agc GUID_DSCFX_MS_AGC
  207. #define GUID_DSCFX_SYSTEM_MicArray GUID_DSCFX_SYSTEM_MA
  208. #define GUID_DSCFX_SYSTEM_Aec GUID_DSCFX_SYSTEM_AEC
  209. #define GUID_DSCFX_SYSTEM_NoiseSuppress GUID_DSCFX_SYSTEM_NS
  210. #define GUID_DSCFX_SYSTEM_Agc GUID_DSCFX_SYSTEM_AGC
  211. #define GetClassObjectCase(x,t) \
  212. if (clsid == x) { \
  213. p = static_cast<IUnknown*> ((IClassFactory*) (new t)); \
  214. } else
  215. #define GetClassObjectCaseEnd \
  216. { return CLASS_E_CLASSNOTAVAILABLE; }
  217. #define GetClassObjectCaseFX(x) \
  218. GetClassObjectCase(GUID_DSFX_STANDARD_ ## x, CDirectSound ## x ## DMOFactory)
  219. #define GetClassObjectCaseCaptureFX(w,x) \
  220. GetClassObjectCase(GUID_DSCFX_## w ##_ ## x, CDirectSoundCapture ## x ## DMOFactory)
  221. //////////////////////////////////////////////////////////////////////
  222. // DllGetClassObject
  223. STDAPI DllGetClassObject(const CLSID& clsid,
  224. const IID& iid,
  225. void** ppv)
  226. {
  227. if (ppv == NULL)
  228. {
  229. return E_POINTER;
  230. }
  231. IUnknown* p = NULL;
  232. // Render FX
  233. GetClassObjectCaseFX(Chorus)
  234. GetClassObjectCaseFX(Compressor)
  235. GetClassObjectCaseFX(Distortion)
  236. GetClassObjectCaseFX(Echo)
  237. GetClassObjectCaseFX(Flanger)
  238. GetClassObjectCaseFX(ParamEq)
  239. GetClassObjectCaseFX(I3DL2Reverb)
  240. // GetClassObjectCaseFX(I3DL2Source)
  241. GetClassObjectCaseFX(Gargle)
  242. GetClassObjectCaseFX(WavesReverb)
  243. // Capture FX
  244. GetClassObjectCaseCaptureFX(MS, Aec)
  245. GetClassObjectCaseCaptureFX(MS, NoiseSuppress)
  246. GetClassObjectCaseCaptureFX(MS, Agc)
  247. // GetClassObjectCaseCaptureFX(SYSTEM, MicArray)
  248. GetClassObjectCaseCaptureFX(SYSTEM, Aec)
  249. GetClassObjectCaseCaptureFX(SYSTEM, NoiseSuppress)
  250. GetClassObjectCaseCaptureFX(SYSTEM, Agc)
  251. GetClassObjectCaseEnd
  252. if(!p)
  253. {
  254. return E_OUTOFMEMORY;
  255. }
  256. HRESULT hr = p->QueryInterface(iid, ppv);
  257. p->Release();
  258. return hr;
  259. }
  260. #define DoUnregister(x) \
  261. UnregisterServer(GUID_DSFX_STANDARD_ ## x, \
  262. g_sz ## x ## FriendlyName, \
  263. g_sz ## x ## VerIndProgID, \
  264. g_sz ## x ## ProgID)
  265. #define DoRegister(x) \
  266. RegisterServer(g_hModule, \
  267. GUID_DSFX_STANDARD_ ## x, \
  268. g_sz ## x ## FriendlyName, \
  269. g_sz ## x ## VerIndProgID, \
  270. g_sz ## x ## ProgID)
  271. #define DoDMORegister(x) \
  272. DMORegister(L#x, \
  273. GUID_DSFX_STANDARD_ ## x, \
  274. DMOCATEGORY_AUDIO_EFFECT, \
  275. 0, 1, &mt, 1, &mt)
  276. #define DoDMOUnregister(x) \
  277. DMOUnregister(GUID_DSFX_STANDARD_ ## x, \
  278. DMOCATEGORY_AUDIO_EFFECT)
  279. #define Unregister(x) \
  280. if (SUCCEEDED(hr)) hr = DoDMOUnregister(x); \
  281. if (SUCCEEDED(hr)) hr = DoUnregister(x);
  282. #define Register(x) \
  283. if (SUCCEEDED(hr)) hr = DoRegister(x); \
  284. if (SUCCEEDED(hr)) hr = DoDMORegister(x);
  285. // Capture Defines
  286. #define DoCaptureUnregister(w,x) \
  287. UnregisterServer(GUID_DSCFX_## w ##_ ## x, \
  288. g_sz ## x ## FriendlyName, \
  289. g_sz ## x ## VerIndProgID, \
  290. g_sz ## x ## ProgID)
  291. #define DoCaptureRegister(w,x) \
  292. RegisterServer(g_hModule, \
  293. GUID_DSCFX_## w ##_ ## x, \
  294. g_sz ## x ## FriendlyName, \
  295. g_sz ## x ## VerIndProgID, \
  296. g_sz ## x ## ProgID)
  297. #define DoDMOCaptureRegister(t,w,x,y) \
  298. DMORegister(L#t, \
  299. GUID_DSCFX_## w ##_ ## x, \
  300. y, \
  301. 0, 1, &mt, 1, &mt)
  302. #define DoDMOCaptureRegisterCpuResources(w,x,z) \
  303. DMORegisterCpuResources( \
  304. GUID_DSCFX_## w ##_ ## x, \
  305. z)
  306. #define DoDMOCaptureUnregister(w,x,y) \
  307. DMOUnregister(GUID_DSCFX_## w ##_ ## x, \
  308. y)
  309. #define CaptureUnregister(w,x,y) \
  310. if (SUCCEEDED(hr)) hr = DoDMOCaptureUnregister(w,x,y); \
  311. if (SUCCEEDED(hr)) hr = DoCaptureUnregister(w,x);
  312. #define CaptureRegister(t,w,x,y,z) \
  313. if (SUCCEEDED(hr)) hr = DoCaptureRegister(w,x); \
  314. if (SUCCEEDED(hr)) hr = DoDMOCaptureRegister(t,w,x,y); \
  315. if (SUCCEEDED(hr)) hr = DoDMOCaptureRegisterCpuResources(w,x,z);
  316. //////////////////////////////////////////////////////////////////////
  317. // DllUnregisterServer
  318. STDAPI DllUnregisterServer()
  319. {
  320. HRESULT hr = S_OK;
  321. Unregister(Chorus);
  322. Unregister(Compressor);
  323. Unregister(Distortion);
  324. Unregister(Echo);
  325. Unregister(Flanger);
  326. Unregister(ParamEq);
  327. Unregister(I3DL2Reverb);
  328. // Unregister(I3DL2Source);
  329. Unregister(Gargle);
  330. Unregister(WavesReverb);
  331. // Capture FXs
  332. CaptureUnregister(MS,Aec,DMOCATEGORY_ACOUSTIC_ECHO_CANCEL);
  333. CaptureUnregister(MS,NoiseSuppress,DMOCATEGORY_AUDIO_NOISE_SUPPRESS);
  334. CaptureUnregister(MS,Agc,DMOCATEGORY_AGC);
  335. // CaptureUnregister(SYSTEM,MicArray,DMOCATEGORY_MICROPHONE_ARRAY_PROCESSOR);
  336. CaptureUnregister(SYSTEM,Aec,DMOCATEGORY_ACOUSTIC_ECHO_CANCEL);
  337. CaptureUnregister(SYSTEM,NoiseSuppress,DMOCATEGORY_AUDIO_NOISE_SUPPRESS);
  338. CaptureUnregister(SYSTEM,Agc,DMOCATEGORY_AGC);
  339. return hr;
  340. }
  341. //////////////////////////////////////////////////////////////////////
  342. // DllRegisterServer
  343. STDAPI DllRegisterServer()
  344. {
  345. HRESULT hr = S_OK;
  346. DMO_PARTIAL_MEDIATYPE mt;
  347. mt.type = MEDIATYPE_Audio;
  348. mt.subtype = MEDIASUBTYPE_PCM;
  349. Register(Chorus);
  350. Register(Compressor);
  351. Register(Distortion);
  352. Register(Echo);
  353. Register(Flanger);
  354. Register(ParamEq);
  355. Register(I3DL2Reverb);
  356. // Register(I3DL2Source);
  357. Register(Gargle);
  358. Register(WavesReverb);
  359. // Capture FXs
  360. CaptureRegister(Microsoft AEC,MS,Aec,DMOCATEGORY_ACOUSTIC_ECHO_CANCEL,DS_SYSTEM_RESOURCES_ALL_HOST_RESOURCES);
  361. CaptureRegister(Microsoft Noise Suppression,MS,NoiseSuppress,DMOCATEGORY_AUDIO_NOISE_SUPPRESS,DS_SYSTEM_RESOURCES_ALL_HOST_RESOURCES);
  362. CaptureRegister(Microsoft AGC,MS,Agc,DMOCATEGORY_AGC,DS_SYSTEM_RESOURCES_ALL_HOST_RESOURCES);
  363. // CaptureRegister(System Microphone Array,SYSTEM,MicArray,DMOCATEGORY_MICROPHONE_ARRAY_PROCESSOR,DS_SYSTEM_RESOURCES_UNDEFINED);
  364. CaptureRegister(System AEC,SYSTEM,Aec,DMOCATEGORY_ACOUSTIC_ECHO_CANCEL,DS_SYSTEM_RESOURCES_UNDEFINED);
  365. CaptureRegister(System Noise Suppression,SYSTEM,NoiseSuppress,DMOCATEGORY_AUDIO_NOISE_SUPPRESS,DS_SYSTEM_RESOURCES_UNDEFINED);
  366. CaptureRegister(System AGC,SYSTEM,Agc,DMOCATEGORY_AGC,DS_SYSTEM_RESOURCES_UNDEFINED);
  367. return hr;
  368. }
  369. //////////////////////////////////////////////////////////////////////
  370. // Standard Win32 DllMain
  371. //////////////////////////////////////////////////////////////////////
  372. // DllMain
  373. #ifdef DBG
  374. static char* aszReasons[] =
  375. {
  376. "DLL_PROCESS_DETACH",
  377. "DLL_PROCESS_ATTACH",
  378. "DLL_THREAD_ATTACH",
  379. "DLL_THREAD_DETACH"
  380. };
  381. const DWORD nReasons = (sizeof(aszReasons) / sizeof(char*));
  382. #endif
  383. BOOL APIENTRY DllMain(HINSTANCE hModule,
  384. DWORD dwReason,
  385. void *lpReserved)
  386. {
  387. #ifdef DBG
  388. if(dwReason < nReasons)
  389. {
  390. Trace(DM_DEBUG_STATUS, "DllMain: %s\n", (LPSTR)aszReasons[dwReason]);
  391. }
  392. else
  393. {
  394. Trace(DM_DEBUG_STATUS, "DllMain: Unknown dwReason <%u>\n", dwReason);
  395. }
  396. #endif
  397. switch(dwReason)
  398. {
  399. case DLL_PROCESS_ATTACH:
  400. if(++g_cActiveObjects == 1)
  401. {
  402. #ifdef DBG
  403. DebugInit();
  404. #endif
  405. if(!DisableThreadLibraryCalls(hModule))
  406. {
  407. Trace(DM_DEBUG_STATUS, "DisableThreadLibraryCalls failed.\n");
  408. }
  409. g_hModule = hModule;
  410. g_amPlatform = VER_PLATFORM_WIN32_WINDOWS; // win95 assumed in case GetVersionEx fails
  411. OSVERSIONINFO osInfo;
  412. osInfo.dwOSVersionInfoSize = sizeof(osInfo);
  413. if (GetVersionEx(&osInfo))
  414. {
  415. g_amPlatform = osInfo.dwPlatformId;
  416. }
  417. }
  418. break;
  419. case DLL_PROCESS_DETACH:
  420. if(--g_cActiveObjects == 0)
  421. {
  422. Trace(DM_DEBUG_STATUS, "Unloading\n");
  423. }
  424. break;
  425. }
  426. return TRUE;
  427. }