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.

443 lines
10 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1999, 2000 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: dllmain.cpp
  6. * Content: This file contains all of the DLL exports except for DllGetClass / DllCanUnload
  7. * History:
  8. * Date By Reason
  9. * ==== == ======
  10. * 07/05/00 rodtoll Created
  11. * 08/23/2000 rodtoll DllCanUnloadNow always returning TRUE!
  12. * 08/28/2000 masonb Voice Merge: Removed OSAL_* and dvosal.h
  13. * 10/05/2000 rodtoll Bug #46541 - DPVOICE: A/V linking to dpvoice.lib could cause application to fail init and crash
  14. * 01/11/2001 rmt MANBUG #48487 - DPLAY: Crashes if CoCreate() isn't called.
  15. * 03/14/2001 rmt WINBUG #342420 - Restore COM emulation layer to operation.
  16. *
  17. ***************************************************************************/
  18. #include "dxvoicepch.h"
  19. #ifdef DPLAY_LOADANDCHECKTRUE
  20. HRESULT InitializeRedirectFunctionTable()
  21. HRESULT FreeRedirectFunctionTable()
  22. #endif
  23. DNCRITICAL_SECTION g_csObjectInitGuard;
  24. LONG lInitCount = 0;
  25. // # of objects active in the system
  26. volatile LONG g_lNumObjects = 0;
  27. LONG g_lNumLocks = 0;
  28. #undef DPF_MODNAME
  29. #define DPF_MODNAME "RegisterDefaultSettings"
  30. //
  31. // RegisterDefaultSettings
  32. //
  33. // This function registers the default settings for this module.
  34. //
  35. // For DPVOICE.DLL this is making sure the compression provider sub-key is created.
  36. //
  37. HRESULT RegisterDefaultSettings()
  38. {
  39. CRegistry creg;
  40. if( !creg.Open( HKEY_LOCAL_MACHINE, DPVOICE_REGISTRY_BASE DPVOICE_REGISTRY_CP, FALSE, TRUE ) )
  41. {
  42. return DVERR_GENERIC;
  43. }
  44. else
  45. {
  46. return DV_OK;
  47. }
  48. }
  49. #undef DPF_MODNAME
  50. #define DPF_MODNAME "UnRegisterDefaultSettings"
  51. //
  52. // UnRegisterDefaultSettings
  53. //
  54. // This function registers the default settings for this module.
  55. //
  56. // For DPVOICE.DLL this is making sure the compression provider sub-key is created.
  57. //
  58. HRESULT UnRegisterDefaultSettings()
  59. {
  60. CRegistry creg;
  61. if( !creg.Open( HKEY_LOCAL_MACHINE, DPVOICE_REGISTRY_BASE, FALSE, TRUE ) )
  62. {
  63. DPFERR( "Cannot remove compression provider, does not exist" );
  64. }
  65. else
  66. {
  67. if( !creg.DeleteSubKey( &(DPVOICE_REGISTRY_CP)[1] ) )
  68. {
  69. DPFERR( "Cannot remove cp sub-key, could have elements" );
  70. }
  71. }
  72. return DV_OK;
  73. }
  74. #undef DPF_MODNAME
  75. #define DPF_MODNAME "DllRegisterServer"
  76. HRESULT WINAPI DllRegisterServer()
  77. {
  78. HRESULT hr = S_OK;
  79. BOOL fFailed = FALSE;
  80. if( !CRegistry::Register( L"DirectPlayVoice.Compat.1", L"DirectPlayVoice Object",
  81. L"dpvoice.dll", CLSID_DIRECTPLAYVOICE, L"DirectPlayVoice.Compat") )
  82. {
  83. DPFERR( "Could not register compat object" );
  84. fFailed = TRUE;
  85. }
  86. if( !CRegistry::Register( L"DirectPlayVoice.Server.1", L"DirectPlayVoice Server Object",
  87. L"dpvoice.dll", CLSID_DirectPlayVoiceServer, L"DirectPlayVoice.Server") )
  88. {
  89. DPFERR( "Could not register server object" );
  90. fFailed = TRUE;
  91. }
  92. if( !CRegistry::Register( L"DirectPlayVoice.Client.1", L"DirectPlayVoice Client Object",
  93. L"dpvoice.dll", CLSID_DirectPlayVoiceClient,
  94. L"DirectPlayVoice.Client") )
  95. {
  96. DPFERR( "Could not register client object" );
  97. fFailed = TRUE;
  98. }
  99. if( !CRegistry::Register( L"DirectPlayVoice.Test.1", L"DirectPlayVoice Test Object",
  100. L"dpvoice.dll", CLSID_DirectPlayVoiceTest,
  101. L"DirectPlayVoice.Test") )
  102. {
  103. DPFERR( "Could not register test object" );
  104. fFailed = TRUE;
  105. }
  106. if( FAILED( hr = RegisterDefaultSettings() ) )
  107. {
  108. DPFX(DPFPREP, 0, "Could not register default settings hr = 0x%x", hr );
  109. fFailed = TRUE;
  110. }
  111. if( fFailed )
  112. {
  113. return E_FAIL;
  114. }
  115. else
  116. {
  117. return S_OK;
  118. }
  119. }
  120. #undef DPF_MODNAME
  121. #define DPF_MODNAME "DllUnregisterServer"
  122. STDAPI DllUnregisterServer()
  123. {
  124. HRESULT hr = S_OK;
  125. BOOL fFailed = FALSE;
  126. if( !CRegistry::UnRegister(CLSID_DirectPlayVoiceServer) )
  127. {
  128. DPFX(DPFPREP, DVF_ERRORLEVEL, "Failed to unregister server object" );
  129. fFailed = TRUE;
  130. }
  131. if( !CRegistry::UnRegister(CLSID_DIRECTPLAYVOICE) )
  132. {
  133. DPFX(DPFPREP, DVF_ERRORLEVEL, "Failed to unregister compat object" );
  134. fFailed = TRUE;
  135. }
  136. if( !CRegistry::UnRegister(CLSID_DirectPlayVoiceClient) )
  137. {
  138. DPFX(DPFPREP, DVF_ERRORLEVEL, "Failed to unregister client object" );
  139. fFailed = TRUE;
  140. }
  141. if( !CRegistry::UnRegister(CLSID_DirectPlayVoiceTest) )
  142. {
  143. DPFX(DPFPREP, DVF_ERRORLEVEL, "Failed to unregister test object" );
  144. fFailed = TRUE;
  145. }
  146. if( FAILED( hr = UnRegisterDefaultSettings() ) )
  147. {
  148. DPFX(DPFPREP, DVF_ERRORLEVEL, "Failed to remove default settings hr=0x%x", hr );
  149. }
  150. if( fFailed )
  151. {
  152. return E_FAIL;
  153. }
  154. else
  155. {
  156. return S_OK;
  157. }
  158. }
  159. #undef DPF_MODNAME
  160. #define DPF_MODNAME "DirectPlayVoiceCreate"
  161. HRESULT WINAPI DirectPlayVoiceCreate( const GUID * pcIID, void **ppvInterface, IUnknown *pUnknown)
  162. {
  163. GUID clsid;
  164. if( pcIID == NULL ||
  165. !DNVALID_READPTR( pcIID, sizeof( GUID ) ) )
  166. {
  167. DPFX(DPFPREP, 0, "Invalid pointer specified for interface GUID" );
  168. return DVERR_INVALIDPOINTER;
  169. }
  170. if( *pcIID != IID_IDirectPlayVoiceClient &&
  171. *pcIID != IID_IDirectPlayVoiceServer &&
  172. *pcIID != IID_IDirectPlayVoiceTest )
  173. {
  174. DPFX(DPFPREP, 0, "Interface ID is not recognized" );
  175. return DVERR_INVALIDPARAM;
  176. }
  177. if( ppvInterface == NULL || !DNVALID_WRITEPTR( ppvInterface, sizeof( void * ) ) )
  178. {
  179. DPFX(DPFPREP, 0, "Invalid pointer specified to receive interface" );
  180. return DVERR_INVALIDPOINTER;
  181. }
  182. if( pUnknown != NULL )
  183. {
  184. DPFX(DPFPREP, 0, "Aggregation is not supported by this object yet" );
  185. return DVERR_INVALIDPARAM;
  186. }
  187. if( *pcIID == IID_IDirectPlayVoiceClient )
  188. {
  189. clsid = CLSID_DirectPlayVoiceClient;
  190. }
  191. else if( *pcIID == IID_IDirectPlayVoiceServer )
  192. {
  193. clsid = CLSID_DirectPlayVoiceServer;
  194. }
  195. else if( *pcIID == IID_IDirectPlayVoiceTest )
  196. {
  197. clsid = CLSID_DirectPlayVoiceTest;
  198. }
  199. else
  200. {
  201. DPFERR( "Invalid IID specified" );
  202. return E_NOINTERFACE;
  203. }
  204. return COM_CoCreateInstance( clsid, NULL, CLSCTX_INPROC_SERVER, *pcIID, ppvInterface, TRUE );
  205. }
  206. #undef DPF_MODNAME
  207. #define DPF_MODNAME "DllMain"
  208. BOOL WINAPI DllMain(
  209. HINSTANCE hDllInst,
  210. DWORD fdwReason,
  211. LPVOID lpvReserved)
  212. {
  213. if( fdwReason == DLL_PROCESS_ATTACH )
  214. {
  215. if( !lInitCount )
  216. {
  217. #ifndef WIN95
  218. SHFusionInitializeFromModule(hDllInst);
  219. #endif
  220. if (!DNOSIndirectionInit())
  221. {
  222. return FALSE;
  223. }
  224. if (!DNInitializeCriticalSection(&g_csObjectInitGuard))
  225. {
  226. DPFX(DPFPREP, 0, "Failed to create CS" );
  227. DNOSIndirectionDeinit();
  228. return FALSE;
  229. }
  230. if (FAILED(COM_Init()))
  231. {
  232. DPFX(DPFPREP, 0, "Failed to Init COM layer" );
  233. DNDeleteCriticalSection(&g_csObjectInitGuard);
  234. DNOSIndirectionDeinit();
  235. return FALSE;
  236. }
  237. if (!DSERRTRACK_Init())
  238. {
  239. DPFX(DPFPREP, 0, "Failed to Init DS error tracking" );
  240. COM_Free();
  241. DNDeleteCriticalSection(&g_csObjectInitGuard);
  242. DNOSIndirectionDeinit();
  243. return FALSE;
  244. }
  245. #if defined(DEBUG) || defined(DBG)
  246. Instrument_Core_Init();
  247. #endif
  248. #ifdef DPLAY_LOADANDCHECKTRUE
  249. InitializeRedirectFunctionTable();
  250. #endif
  251. InterlockedIncrement( &lInitCount );
  252. PERF_Initialize();
  253. }
  254. }
  255. else if( fdwReason == DLL_PROCESS_DETACH )
  256. {
  257. InterlockedDecrement( &lInitCount );
  258. if( lInitCount == 0 )
  259. {
  260. DSERRTRACK_UnInit();
  261. DPFX(DPFPREP, DVF_INFOLEVEL, ">>>>>>>>>>>>>>>> DPF UNINITED <<<<<<<<<<<<<<<" );
  262. #ifdef DPLAY_LOADANDCHECKTRUE
  263. FreeRedirectFunctionTable();
  264. #endif
  265. COM_Free();
  266. PERF_DeInitialize();
  267. DNDeleteCriticalSection(&g_csObjectInitGuard);
  268. // This must be called after all DNDeleteCriticalSection calls are done
  269. DNOSIndirectionDeinit();
  270. // Check to ensure we're not being unloaded with objects active
  271. if( g_lNumObjects != 0 || g_lNumLocks != 0 )
  272. {
  273. DPFX(DPFPREP, DVF_ERRORLEVEL, "=========================================================================" );
  274. DPFX(DPFPREP, DVF_ERRORLEVEL, "DPVOICE.DLL is unloading with %i objects and %i locks still open. This is an ERROR. ", g_lNumObjects, g_lNumLocks );
  275. DPFX(DPFPREP, DVF_ERRORLEVEL, "You must release all DirectPlayVoice objects before exiting your process." );
  276. DPFX(DPFPREP, DVF_ERRORLEVEL, "=========================================================================" );
  277. DNASSERT( FALSE );
  278. }
  279. #ifndef WIN95
  280. SHFusionUninitialize();
  281. #endif
  282. }
  283. }
  284. return TRUE;
  285. }
  286. ////////////////////////////////////////////////////////////////////////
  287. //
  288. // SUPPORT FUNCTIONS FOR STANDALONE DLL
  289. #ifdef DPLAY_LOADANDCHECKTRUE
  290. typedef HRESULT (WINAPI *PFN_DLLGETCLASSOBJECT)(REFCLSID rclsid,REFIID riid,LPVOID *ppvObj );
  291. typedef HRESULT (WINAPI *PFN_DLLCANUNLOADNOW)(void);
  292. extern "C" {
  293. HMODULE ghRedirect = NULL;
  294. PFN_DLLGETCLASSOBJECT pfnGetClassObject = NULL;
  295. PFN_DLLCANUNLOADNOW pfnDllCanUnLoadNow = NULL;
  296. };
  297. #undef DPF_MODNAME
  298. #define DPF_MODNAME "CheckForPrivateBit"
  299. BOOL CheckForPrivateBit( DWORD dwBit )
  300. {
  301. CRegistry creg;
  302. DWORD dwValue;
  303. if( !creg.Open( DPLAY_LOADTREE_REGTREE, DPLAY_LOADTRUE_REGPATH, TRUE, FALSE ) )
  304. {
  305. return FALSE;
  306. }
  307. if( !creg.ReadDWORD( DPLAY_LOADTRUE_REGKEY, dwValue ) )
  308. {
  309. return FALSE;
  310. }
  311. if( dwValue & dwBit )
  312. {
  313. return TRUE;
  314. }
  315. else
  316. {
  317. return FALSE;
  318. }
  319. }
  320. HRESULT InitializeRedirectFunctionTable()
  321. {
  322. LONG lLastError;
  323. if( CheckForPrivateBit( DPLAY_LOADTRUE_BIT ) )
  324. {
  325. ghRedirect = LoadLibrary( "dpvoice.dll" );
  326. if( ghRedirect == NULL )
  327. {
  328. lLastError = GetLastError();
  329. DPFX(DPFPREP, 0, "Could not load dplayx.dll error = 0x%x", lLastError );
  330. return DPERR_GENERIC;
  331. }
  332. pfnGetClassObject = (PFN_DLLGETCLASSOBJECT) GetProcAddress( ghRedirect, "DllGetClassObject" );
  333. pfnDllCanUnLoadNow = (PFN_DLLCANUNLOADNOW) GetProcAddress( ghRedirect, "DllCanUnloadNow" );
  334. }
  335. return DP_OK;
  336. }
  337. HRESULT FreeRedirectFunctionTable()
  338. {
  339. if( ghRedirect != NULL )
  340. FreeLibrary( ghRedirect );
  341. return DP_OK;
  342. }
  343. #endif
  344. LONG DecrementObjectCount()
  345. {
  346. LONG lNewValue;
  347. DNEnterCriticalSection( &g_csObjectInitGuard );
  348. g_lNumObjects--;
  349. lNewValue = g_lNumObjects;
  350. if( g_lNumObjects == 0 )
  351. {
  352. CDirectVoiceEngine::Shutdown();
  353. }
  354. DNLeaveCriticalSection( &g_csObjectInitGuard );
  355. return lNewValue;
  356. }
  357. LONG IncrementObjectCount()
  358. {
  359. LONG lNewValue;
  360. DNEnterCriticalSection( &g_csObjectInitGuard );
  361. g_lNumObjects++;
  362. lNewValue = g_lNumObjects;
  363. if( g_lNumObjects == 1 )
  364. {
  365. CDirectVoiceEngine::Startup(DPVOICE_REGISTRY_BASE);
  366. }
  367. DNLeaveCriticalSection( &g_csObjectInitGuard );
  368. return lNewValue;
  369. }