Leaked source code of windows server 2003
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.

364 lines
9.4 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. * 02/28/2002 rodtoll WINBUG #550124 - SECURITY: DPVOICE: Shared memory region with NULL DACL
  17. * - Remove performance statistics dumping to shared memory
  18. *
  19. ***************************************************************************/
  20. #include "dxvoicepch.h"
  21. DNCRITICAL_SECTION g_csObjectInitGuard;
  22. LONG lInitCount = 0;
  23. // # of objects active in the system
  24. volatile LONG g_lNumObjects = 0;
  25. LONG g_lNumLocks = 0;
  26. #undef DPF_MODNAME
  27. #define DPF_MODNAME "RegisterDefaultSettings"
  28. //
  29. // RegisterDefaultSettings
  30. //
  31. // This function registers the default settings for this module.
  32. //
  33. // For DPVOICE.DLL this is making sure the compression provider sub-key is created.
  34. //
  35. HRESULT RegisterDefaultSettings()
  36. {
  37. CRegistry creg;
  38. if( !creg.Open( HKEY_LOCAL_MACHINE, DPVOICE_REGISTRY_BASE DPVOICE_REGISTRY_CP, FALSE, TRUE ) )
  39. {
  40. return DVERR_GENERIC;
  41. }
  42. else
  43. {
  44. return DV_OK;
  45. }
  46. }
  47. #undef DPF_MODNAME
  48. #define DPF_MODNAME "UnRegisterDefaultSettings"
  49. //
  50. // UnRegisterDefaultSettings
  51. //
  52. // This function registers the default settings for this module.
  53. //
  54. // For DPVOICE.DLL this is making sure the compression provider sub-key is created.
  55. //
  56. HRESULT UnRegisterDefaultSettings()
  57. {
  58. CRegistry creg;
  59. if( !creg.Open( HKEY_LOCAL_MACHINE, DPVOICE_REGISTRY_BASE, FALSE, TRUE ) )
  60. {
  61. DPFERR( "Cannot remove compression provider, does not exist" );
  62. }
  63. else
  64. {
  65. if( !creg.DeleteSubKey( &(DPVOICE_REGISTRY_CP)[1] ) )
  66. {
  67. DPFERR( "Cannot remove cp sub-key, could have elements" );
  68. }
  69. }
  70. return DV_OK;
  71. }
  72. #undef DPF_MODNAME
  73. #define DPF_MODNAME "DllRegisterServer"
  74. HRESULT WINAPI DllRegisterServer()
  75. {
  76. HRESULT hr = S_OK;
  77. BOOL fFailed = FALSE;
  78. #if !defined(DBG) || !defined( DIRECTX_REDIST )
  79. #define DPVOICE_FILENAME_DPVOICE L"dpvoice.dll"
  80. #else
  81. // For redist debug builds we append a 'd' to the name to allow both debug and retail to be installed on the system
  82. #define DPVOICE_FILENAME_DPVOICE L"dpvoiced.dll"
  83. #endif // !defined(DBG) || !defined( DIRECTX_REDIST )
  84. if( !CRegistry::Register( L"DirectPlayVoice.Compat.1", L"DirectPlayVoice Object",
  85. DPVOICE_FILENAME_DPVOICE, &CLSID_DIRECTPLAYVOICE, L"DirectPlayVoice.Compat") )
  86. {
  87. DPFERR( "Could not register compat object" );
  88. fFailed = TRUE;
  89. }
  90. if( !CRegistry::Register( L"DirectPlayVoice.Server.1", L"DirectPlayVoice Server Object",
  91. DPVOICE_FILENAME_DPVOICE, &CLSID_DirectPlayVoiceServer, L"DirectPlayVoice.Server") )
  92. {
  93. DPFERR( "Could not register server object" );
  94. fFailed = TRUE;
  95. }
  96. if( !CRegistry::Register( L"DirectPlayVoice.Client.1", L"DirectPlayVoice Client Object",
  97. DPVOICE_FILENAME_DPVOICE, &CLSID_DirectPlayVoiceClient,
  98. L"DirectPlayVoice.Client") )
  99. {
  100. DPFERR( "Could not register client object" );
  101. fFailed = TRUE;
  102. }
  103. if( !CRegistry::Register( L"DirectPlayVoice.Test.1", L"DirectPlayVoice Test Object",
  104. DPVOICE_FILENAME_DPVOICE, &CLSID_DirectPlayVoiceTest,
  105. L"DirectPlayVoice.Test") )
  106. {
  107. DPFERR( "Could not register test object" );
  108. fFailed = TRUE;
  109. }
  110. if( FAILED( hr = RegisterDefaultSettings() ) )
  111. {
  112. DPFX(DPFPREP, 0, "Could not register default settings hr = 0x%x", hr );
  113. fFailed = TRUE;
  114. }
  115. if( fFailed )
  116. {
  117. return E_FAIL;
  118. }
  119. else
  120. {
  121. return S_OK;
  122. }
  123. }
  124. #undef DPF_MODNAME
  125. #define DPF_MODNAME "DllUnregisterServer"
  126. STDAPI DllUnregisterServer()
  127. {
  128. HRESULT hr = S_OK;
  129. BOOL fFailed = FALSE;
  130. if( !CRegistry::UnRegister(&CLSID_DirectPlayVoiceServer) )
  131. {
  132. DPFX(DPFPREP, DVF_ERRORLEVEL, "Failed to unregister server object" );
  133. fFailed = TRUE;
  134. }
  135. if( !CRegistry::UnRegister(&CLSID_DIRECTPLAYVOICE) )
  136. {
  137. DPFX(DPFPREP, DVF_ERRORLEVEL, "Failed to unregister compat object" );
  138. fFailed = TRUE;
  139. }
  140. if( !CRegistry::UnRegister(&CLSID_DirectPlayVoiceClient) )
  141. {
  142. DPFX(DPFPREP, DVF_ERRORLEVEL, "Failed to unregister client object" );
  143. fFailed = TRUE;
  144. }
  145. if( !CRegistry::UnRegister(&CLSID_DirectPlayVoiceTest) )
  146. {
  147. DPFX(DPFPREP, DVF_ERRORLEVEL, "Failed to unregister test object" );
  148. fFailed = TRUE;
  149. }
  150. if( FAILED( hr = UnRegisterDefaultSettings() ) )
  151. {
  152. DPFX(DPFPREP, DVF_ERRORLEVEL, "Failed to remove default settings hr=0x%x", hr );
  153. }
  154. if( fFailed )
  155. {
  156. return E_FAIL;
  157. }
  158. else
  159. {
  160. return S_OK;
  161. }
  162. }
  163. #undef DPF_MODNAME
  164. #define DPF_MODNAME "DirectPlayVoiceCreate"
  165. HRESULT WINAPI DirectPlayVoiceCreate( const GUID * pcIID, void **ppvInterface, IUnknown *pUnknown)
  166. {
  167. GUID clsid;
  168. if( pcIID == NULL ||
  169. !DNVALID_READPTR( pcIID, sizeof( GUID ) ) )
  170. {
  171. DPFX(DPFPREP, 0, "Invalid pointer specified for interface GUID" );
  172. return DVERR_INVALIDPOINTER;
  173. }
  174. if( *pcIID != IID_IDirectPlayVoiceClient &&
  175. *pcIID != IID_IDirectPlayVoiceServer &&
  176. *pcIID != IID_IDirectPlayVoiceTest )
  177. {
  178. DPFX(DPFPREP, 0, "Interface ID is not recognized" );
  179. return DVERR_INVALIDPARAM;
  180. }
  181. if( ppvInterface == NULL || !DNVALID_WRITEPTR( ppvInterface, sizeof( void * ) ) )
  182. {
  183. DPFX(DPFPREP, 0, "Invalid pointer specified to receive interface" );
  184. return DVERR_INVALIDPOINTER;
  185. }
  186. if( pUnknown != NULL )
  187. {
  188. DPFX(DPFPREP, 0, "Aggregation is not supported by this object yet" );
  189. return DVERR_INVALIDPARAM;
  190. }
  191. if( *pcIID == IID_IDirectPlayVoiceClient )
  192. {
  193. clsid = CLSID_DirectPlayVoiceClient;
  194. }
  195. else if( *pcIID == IID_IDirectPlayVoiceServer )
  196. {
  197. clsid = CLSID_DirectPlayVoiceServer;
  198. }
  199. else if( *pcIID == IID_IDirectPlayVoiceTest )
  200. {
  201. clsid = CLSID_DirectPlayVoiceTest;
  202. }
  203. else
  204. {
  205. DPFERR( "Invalid IID specified" );
  206. return E_NOINTERFACE;
  207. }
  208. return COM_CoCreateInstance( clsid, NULL, CLSCTX_INPROC_SERVER, *pcIID, ppvInterface, TRUE );
  209. }
  210. #undef DPF_MODNAME
  211. #define DPF_MODNAME "DllMain"
  212. BOOL WINAPI DllMain(
  213. HINSTANCE hDllInst,
  214. DWORD fdwReason,
  215. LPVOID lpvReserved)
  216. {
  217. if( fdwReason == DLL_PROCESS_ATTACH )
  218. {
  219. if( !lInitCount )
  220. {
  221. #ifndef WIN95
  222. SHFusionInitializeFromModule(hDllInst);
  223. #endif
  224. if (!DNOSIndirectionInit(0))
  225. {
  226. return FALSE;
  227. }
  228. if (!DNInitializeCriticalSection(&g_csObjectInitGuard))
  229. {
  230. DPFX(DPFPREP, 0, "Failed to create CS" );
  231. DNOSIndirectionDeinit();
  232. return FALSE;
  233. }
  234. if (FAILED(COM_Init()))
  235. {
  236. DPFX(DPFPREP, 0, "Failed to Init COM layer" );
  237. DNDeleteCriticalSection(&g_csObjectInitGuard);
  238. DNOSIndirectionDeinit();
  239. return FALSE;
  240. }
  241. if (!DSERRTRACK_Init())
  242. {
  243. DPFX(DPFPREP, 0, "Failed to Init DS error tracking" );
  244. COM_Free();
  245. DNDeleteCriticalSection(&g_csObjectInitGuard);
  246. DNOSIndirectionDeinit();
  247. return FALSE;
  248. }
  249. #if defined(DEBUG) || defined(DBG)
  250. Instrument_Core_Init();
  251. #endif
  252. InterlockedIncrement( &lInitCount );
  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. COM_Free();
  263. DNDeleteCriticalSection(&g_csObjectInitGuard);
  264. // This must be called after all DNDeleteCriticalSection calls are done
  265. DNOSIndirectionDeinit();
  266. // Check to ensure we're not being unloaded with objects active
  267. if( g_lNumObjects != 0 || g_lNumLocks != 0 )
  268. {
  269. DPFX(DPFPREP, DVF_ERRORLEVEL, "=========================================================================" );
  270. DPFX(DPFPREP, DVF_ERRORLEVEL, "DPVOICE.DLL is unloading with %i objects and %i locks still open. This is an ERROR. ", g_lNumObjects, g_lNumLocks );
  271. DPFX(DPFPREP, DVF_ERRORLEVEL, "You must release all DirectPlayVoice objects before exiting your process." );
  272. DPFX(DPFPREP, DVF_ERRORLEVEL, "=========================================================================" );
  273. DNASSERT( FALSE );
  274. }
  275. #ifndef WIN95
  276. SHFusionUninitialize();
  277. #endif
  278. }
  279. }
  280. return TRUE;
  281. }
  282. LONG DecrementObjectCount()
  283. {
  284. LONG lNewValue;
  285. DNEnterCriticalSection( &g_csObjectInitGuard );
  286. g_lNumObjects--;
  287. lNewValue = g_lNumObjects;
  288. if( g_lNumObjects == 0 )
  289. {
  290. CDirectVoiceEngine::Shutdown();
  291. }
  292. DNLeaveCriticalSection( &g_csObjectInitGuard );
  293. return lNewValue;
  294. }
  295. LONG IncrementObjectCount()
  296. {
  297. LONG lNewValue;
  298. DNEnterCriticalSection( &g_csObjectInitGuard );
  299. g_lNumObjects++;
  300. lNewValue = g_lNumObjects;
  301. if( g_lNumObjects == 1 )
  302. {
  303. CDirectVoiceEngine::Startup(DPVOICE_REGISTRY_BASE);
  304. }
  305. DNLeaveCriticalSection( &g_csObjectInitGuard );
  306. return lNewValue;
  307. }