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.

484 lines
13 KiB

  1. //
  2. // dll.cpp
  3. //
  4. // Copyright (c) 1999 Microsoft Corporation. All rights reserved.
  5. //
  6. // Note: Dll entry points as well as class factory implementations.
  7. //
  8. // READ THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!
  9. //
  10. // 4530: C++ exception handler used, but unwind semantics are not enabled. Specify -GX
  11. //
  12. // We disable this because we use exceptions and do *not* specify -GX (USE_NATIVE_EH in
  13. // sources).
  14. //
  15. // The one place we use exceptions is around construction of objects that call
  16. // InitializeCriticalSection. We guarantee that it is safe to use in this case with
  17. // the restriction given by not using -GX (automatic objects in the call chain between
  18. // throw and handler are not destructed). Turning on -GX buys us nothing but +10% to code
  19. // size because of the unwind code.
  20. //
  21. // Any other use of exceptions must follow these restrictions or -GX must be turned on.
  22. //
  23. // READ THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!
  24. //
  25. #pragma warning(disable:4530)
  26. #include "stdinc.h"
  27. #include "oledll.h"
  28. #include "dll.h"
  29. #include "dmscript.h"
  30. #include "track.h"
  31. #include "engine.h"
  32. #include "autperformance.h"
  33. #include "autsegment.h"
  34. #include "autsong.h"
  35. #include "autsegmentstate.h"
  36. #include "autaudiopathconfig.h"
  37. #include "autaudiopath.h"
  38. #include "dmscriptautguids.h"
  39. #include "sourcetext.h"
  40. #include "scriptthread.h"
  41. //////////////////////////////////////////////////////////////////////
  42. // Globals
  43. // Dll's hModule
  44. //
  45. HMODULE g_hModule = NULL;
  46. // Count of active components and class factory server locks
  47. //
  48. long g_cLock = 0;
  49. // Version information for our class
  50. //
  51. char g_szDMScriptFriendlyName[] = "DirectMusic Script Object";
  52. char g_szDMScriptVerIndProgID[] = "Microsoft.DirectMusicScript";
  53. char g_szDMScriptProgID[] = "Microsoft.DirectMusicScript.1";
  54. char g_szScriptTrackFriendlyName[] = "DirectMusicScriptTrack";
  55. char g_szScriptTrackVerIndProgID[] = "Microsoft.DirectMusicScriptTrack";
  56. char g_szScriptTrackProgID[] = "Microsoft.DirectMusicScriptTrack.1";
  57. char g_szAudioVBScriptFriendlyName[] = "DirectMusic Audio VB Script Language";
  58. char g_szAudioVBScriptVerIndProgID[] = "AudioVBScript";
  59. char g_szAudioVBScriptVerIndProgID_DMScript[] = "AudioVBScript\\DMScript";
  60. char g_szAudioVBScriptProgID[] = "AudioVBScript.1";
  61. char g_szAudioVBScriptProgID_DMScript[] = "AudioVBScript.1\\DMScript";
  62. char g_szDMScriptSourceTextFriendlyName[] = "DirectMusic Script Source Code Loader";
  63. char g_szDMScriptSourceTextVerIndProgID[] = "Microsoft.DirectMusicScripSourceCodeLoader";
  64. char g_szDMScriptSourceTextProgID[] = "Microsoft.DirectMusicScripSourceCodeLoader.1";
  65. char g_szDMScriptAutPerformanceFriendlyName[] = "DirectMusic Script AutoImp Performance";
  66. char g_szDMScriptAutPerformanceVerIndProgID[] = "Microsoft.DirectMusicScriptAutoImpPerformance";
  67. char g_szDMScriptAutPerformanceProgID[] = "Microsoft.DirectMusicScriptAutoImpPerformance.1";
  68. char g_szDMScriptAutSegmentFriendlyName[] = "DirectMusic Script AutoImp Segment";
  69. char g_szDMScriptAutSegmentVerIndProgID[] = "Microsoft.DirectMusicScriptAutoImpSegment";
  70. char g_szDMScriptAutSegmentProgID[] = "Microsoft.DirectMusicScriptAutoImpSegment.1";
  71. char g_szDMScriptAutSongFriendlyName[] = "DirectMusic Script AutoImp Song";
  72. char g_szDMScriptAutSongVerIndProgID[] = "Microsoft.DirectMusicScriptAutoImpSong";
  73. char g_szDMScriptAutSongProgID[] = "Microsoft.DirectMusicScriptAutoImpSong.1";
  74. char g_szDMScriptAutSegmentStateFriendlyName[] = "DirectMusic Script AutoImp SegmentState";
  75. char g_szDMScriptAutSegmentStateVerIndProgID[] = "Microsoft.DirectMusicScriptAutoImpSegmentState";
  76. char g_szDMScriptAutSegmentStateProgID[] = "Microsoft.DirectMusicScriptAutoImpSegmentState.1";
  77. char g_szDMScriptAutAudioPathConfigFriendlyName[] = "DirectMusic Script AutoImp AudioPathConfig";
  78. char g_szDMScriptAutAudioPathConfigVerIndProgID[] = "Microsoft.DirectMusicScriptAutoImpAudioPathConfig";
  79. char g_szDMScriptAutAudioPathConfigProgID[] = "Microsoft.DirectMusicScriptAutoImpAudioPathConfig.1";
  80. char g_szDMScriptAutAudioPathFriendlyName[] = "DirectMusic Script AutoImp AudioPath";
  81. char g_szDMScriptAutAudioPathVerIndProgID[] = "Microsoft.DirectMusicScriptAutoImpAudioPath";
  82. char g_szDMScriptAutAudioPathProgID[] = "Microsoft.DirectMusicScriptAutoImpAudioPath.1";
  83. //////////////////////////////////////////////////////////////////////
  84. // CDMScriptingFactory IUnknown methods
  85. HRESULT __stdcall
  86. CDMScriptingFactory::QueryInterface(const IID &iid, void **ppv)
  87. {
  88. V_INAME(CDMScriptingFactory::QueryInterface);
  89. V_PTRPTR_WRITE(ppv);
  90. V_REFGUID(iid);
  91. if (iid == IID_IUnknown || iid == IID_IClassFactory)
  92. *ppv = static_cast<IClassFactory*>(this);
  93. else
  94. {
  95. *ppv = NULL;
  96. return E_NOINTERFACE;
  97. }
  98. reinterpret_cast<IUnknown*>(*ppv)->AddRef();
  99. return S_OK;
  100. }
  101. ULONG __stdcall
  102. CDMScriptingFactory::AddRef()
  103. {
  104. return InterlockedIncrement(&m_cRef);
  105. }
  106. ULONG __stdcall
  107. CDMScriptingFactory::Release()
  108. {
  109. if (!InterlockedDecrement(&m_cRef))
  110. {
  111. delete this;
  112. return 0;
  113. }
  114. return m_cRef;
  115. }
  116. //////////////////////////////////////////////////////////////////////
  117. // CDMScriptingFactory IClassFactory methods
  118. HRESULT __stdcall
  119. CDMScriptingFactory::CreateInstance(IUnknown* pUnknownOuter,
  120. const IID& iid,
  121. void** ppv)
  122. {
  123. V_INAME(CDMScriptingFactory::CreateInstance);
  124. V_INTERFACE_OPT(pUnknownOuter);
  125. V_PTR_WRITE(ppv, void*);
  126. try
  127. {
  128. return m_pfnCreate(pUnknownOuter, iid, ppv);
  129. }
  130. catch( ... )
  131. {
  132. return E_OUTOFMEMORY;
  133. }
  134. return E_NOINTERFACE;
  135. }
  136. HRESULT __stdcall
  137. CDMScriptingFactory::LockServer(BOOL bLock)
  138. {
  139. LockModule(!!bLock);
  140. return S_OK;
  141. }
  142. //////////////////////////////////////////////////////////////////////
  143. // Dll entry points
  144. STDAPI DllCanUnloadNow()
  145. {
  146. if (g_cLock)
  147. return S_FALSE;
  148. return S_OK;
  149. }
  150. STDAPI DllGetClassObject
  151. (
  152. const CLSID& clsid,
  153. const IID& iid,
  154. void** ppv
  155. )
  156. {
  157. IUnknown* pIUnknown = NULL;
  158. PFN_CreateInstance *pfnCreate = NULL;
  159. if (clsid == CLSID_DirectMusicScript)
  160. {
  161. pfnCreate = CDirectMusicScript::CreateInstance;
  162. }
  163. else if (clsid == CLSID_DirectMusicScriptTrack)
  164. {
  165. // I couldn't get it to compile if I just used TrackHelpCreateInstance<CDirectMusicScriptTrack>
  166. // for the function pointer so I created this function that calls it.
  167. struct LocalNonTemplateDeclaration
  168. {
  169. static HRESULT CreateInstance(IUnknown* pUnknownOuter, const IID& iid, void** ppv)
  170. {
  171. return TrackHelpCreateInstance<CDirectMusicScriptTrack>(pUnknownOuter, iid, ppv);
  172. }
  173. };
  174. pfnCreate = LocalNonTemplateDeclaration::CreateInstance;
  175. }
  176. else if (clsid == CLSID_DirectMusicAudioVBScript)
  177. {
  178. pfnCreate = CAudioVBScriptEngine::CreateInstance;
  179. }
  180. else if (clsid == CLSID_DirectMusicSourceText)
  181. {
  182. pfnCreate = CSourceText::CreateInstance;
  183. }
  184. else if (clsid == CLSID_AutDirectMusicPerformance)
  185. {
  186. pfnCreate = CAutDirectMusicPerformance::CreateInstance;
  187. }
  188. else if (clsid == CLSID_AutDirectMusicSegment)
  189. {
  190. pfnCreate = CAutDirectMusicSegment::CreateInstance;
  191. }
  192. else if (clsid == CLSID_AutDirectMusicSong)
  193. {
  194. pfnCreate = CAutDirectMusicSong::CreateInstance;
  195. }
  196. else if (clsid == CLSID_AutDirectMusicSegmentState)
  197. {
  198. pfnCreate = CAutDirectMusicSegmentState::CreateInstance;
  199. }
  200. else if (clsid == CLSID_AutDirectMusicAudioPathConfig)
  201. {
  202. pfnCreate = CAutDirectMusicAudioPathConfig::CreateInstance;
  203. }
  204. else if (clsid == CLSID_AutDirectMusicAudioPath)
  205. {
  206. pfnCreate = CAutDirectMusicAudioPath::CreateInstance;
  207. }
  208. if (pfnCreate)
  209. {
  210. pIUnknown = static_cast<IUnknown*>(new CDMScriptingFactory(pfnCreate));
  211. if(!pIUnknown)
  212. return E_OUTOFMEMORY;
  213. }
  214. else
  215. {
  216. return CLASS_E_CLASSNOTAVAILABLE;
  217. }
  218. return pIUnknown->QueryInterface(iid, ppv);
  219. }
  220. STDAPI DllUnregisterServer()
  221. {
  222. UnregisterServer(
  223. CLSID_DirectMusicScript,
  224. g_szDMScriptFriendlyName,
  225. g_szDMScriptVerIndProgID,
  226. g_szDMScriptProgID);
  227. UnregisterServer(CLSID_DirectMusicScriptTrack,
  228. g_szScriptTrackFriendlyName,
  229. g_szScriptTrackVerIndProgID,
  230. g_szScriptTrackProgID);
  231. UnregisterServer(CLSID_DirectMusicAudioVBScript,
  232. g_szAudioVBScriptFriendlyName,
  233. g_szAudioVBScriptVerIndProgID,
  234. g_szAudioVBScriptProgID);
  235. UnregisterServer(
  236. CLSID_DirectMusicSourceText,
  237. g_szDMScriptSourceTextFriendlyName,
  238. g_szDMScriptSourceTextVerIndProgID,
  239. g_szDMScriptSourceTextProgID);
  240. UnregisterServer(CLSID_AutDirectMusicPerformance,
  241. g_szDMScriptAutPerformanceFriendlyName,
  242. g_szDMScriptAutPerformanceVerIndProgID,
  243. g_szDMScriptAutPerformanceProgID);
  244. UnregisterServer(CLSID_AutDirectMusicSegment,
  245. g_szDMScriptAutSegmentFriendlyName,
  246. g_szDMScriptAutSegmentVerIndProgID,
  247. g_szDMScriptAutSegmentProgID);
  248. UnregisterServer(CLSID_AutDirectMusicSong,
  249. g_szDMScriptAutSongFriendlyName,
  250. g_szDMScriptAutSongVerIndProgID,
  251. g_szDMScriptAutSongProgID);
  252. UnregisterServer(CLSID_AutDirectMusicSegmentState,
  253. g_szDMScriptAutSegmentStateFriendlyName,
  254. g_szDMScriptAutSegmentStateVerIndProgID,
  255. g_szDMScriptAutSegmentStateProgID);
  256. UnregisterServer(CLSID_AutDirectMusicAudioPathConfig,
  257. g_szDMScriptAutAudioPathConfigFriendlyName,
  258. g_szDMScriptAutAudioPathConfigVerIndProgID,
  259. g_szDMScriptAutAudioPathConfigProgID);
  260. UnregisterServer(CLSID_AutDirectMusicAudioPath,
  261. g_szDMScriptAutAudioPathFriendlyName,
  262. g_szDMScriptAutAudioPathVerIndProgID,
  263. g_szDMScriptAutAudioPathProgID);
  264. return S_OK;
  265. }
  266. STDAPI DllRegisterServer()
  267. {
  268. RegisterServer(
  269. g_hModule,
  270. CLSID_DirectMusicScript,
  271. g_szDMScriptFriendlyName,
  272. g_szDMScriptVerIndProgID,
  273. g_szDMScriptProgID);
  274. RegisterServer(
  275. g_hModule,
  276. CLSID_DirectMusicScriptTrack,
  277. g_szScriptTrackFriendlyName,
  278. g_szScriptTrackVerIndProgID,
  279. g_szScriptTrackProgID);
  280. RegisterServer(
  281. g_hModule,
  282. CLSID_DirectMusicSourceText,
  283. g_szDMScriptSourceTextFriendlyName,
  284. g_szDMScriptSourceTextVerIndProgID,
  285. g_szDMScriptSourceTextProgID);
  286. RegisterServer(
  287. g_hModule,
  288. CLSID_AutDirectMusicPerformance,
  289. g_szDMScriptAutPerformanceFriendlyName,
  290. g_szDMScriptAutPerformanceVerIndProgID,
  291. g_szDMScriptAutPerformanceProgID);
  292. RegisterServer(
  293. g_hModule,
  294. CLSID_AutDirectMusicSegment,
  295. g_szDMScriptAutSegmentFriendlyName,
  296. g_szDMScriptAutSegmentVerIndProgID,
  297. g_szDMScriptAutSegmentProgID);
  298. RegisterServer(
  299. g_hModule,
  300. CLSID_AutDirectMusicSong,
  301. g_szDMScriptAutSongFriendlyName,
  302. g_szDMScriptAutSongVerIndProgID,
  303. g_szDMScriptAutSongProgID);
  304. RegisterServer(
  305. g_hModule,
  306. CLSID_AutDirectMusicSegmentState,
  307. g_szDMScriptAutSegmentStateFriendlyName,
  308. g_szDMScriptAutSegmentStateVerIndProgID,
  309. g_szDMScriptAutSegmentStateProgID);
  310. RegisterServer(
  311. g_hModule,
  312. CLSID_AutDirectMusicAudioPathConfig,
  313. g_szDMScriptAutAudioPathConfigFriendlyName,
  314. g_szDMScriptAutAudioPathConfigVerIndProgID,
  315. g_szDMScriptAutAudioPathConfigProgID);
  316. RegisterServer(
  317. g_hModule,
  318. CLSID_AutDirectMusicAudioPath,
  319. g_szDMScriptAutAudioPathFriendlyName,
  320. g_szDMScriptAutAudioPathVerIndProgID,
  321. g_szDMScriptAutAudioPathProgID);
  322. RegisterServer(
  323. g_hModule,
  324. CLSID_DirectMusicAudioVBScript,
  325. g_szAudioVBScriptFriendlyName,
  326. g_szAudioVBScriptVerIndProgID,
  327. g_szAudioVBScriptProgID);
  328. // AudioVBScript also needs an additional DMScript key set to mark it as a custom scripting engine.
  329. HKEY hk;
  330. if (ERROR_SUCCESS == RegCreateKeyEx(
  331. HKEY_CLASSES_ROOT,
  332. g_szAudioVBScriptVerIndProgID_DMScript,
  333. 0,
  334. NULL,
  335. 0,
  336. KEY_ALL_ACCESS,
  337. NULL,
  338. &hk,
  339. NULL))
  340. RegCloseKey(hk);
  341. if (ERROR_SUCCESS == RegCreateKeyEx(
  342. HKEY_CLASSES_ROOT,
  343. g_szAudioVBScriptProgID_DMScript,
  344. 0,
  345. NULL,
  346. 0,
  347. KEY_ALL_ACCESS,
  348. NULL,
  349. &hk,
  350. NULL))
  351. RegCloseKey(hk);
  352. return S_OK;
  353. }
  354. #ifdef DBG
  355. static char* aszReasons[] =
  356. {
  357. "DLL_PROCESS_DETACH",
  358. "DLL_PROCESS_ATTACH",
  359. "DLL_THREAD_ATTACH",
  360. "DLL_THREAD_DETACH"
  361. };
  362. const DWORD nReasons = (sizeof(aszReasons) / sizeof(char*));
  363. #endif
  364. BOOL APIENTRY
  365. DllMain
  366. (
  367. HINSTANCE hModule,
  368. DWORD dwReason,
  369. void *lpReserved
  370. )
  371. {
  372. static int nReferenceCount = 0;
  373. #ifdef DBG
  374. if (dwReason < nReasons)
  375. {
  376. Trace(1, "DllMain: %s\n", (LPSTR)aszReasons[dwReason]);
  377. }
  378. else
  379. {
  380. Trace(1, "DllMain: Unknown dwReason <%u>\n", dwReason);
  381. }
  382. #endif
  383. switch (dwReason)
  384. {
  385. case DLL_PROCESS_ATTACH:
  386. if (++nReferenceCount == 1)
  387. {
  388. #ifdef DBG
  389. DebugInit();
  390. #endif
  391. if (!DisableThreadLibraryCalls(hModule))
  392. {
  393. Trace(1, "DisableThreadLibraryCalls failed.\n");
  394. }
  395. g_hModule = hModule;
  396. }
  397. break;
  398. case DLL_PROCESS_DETACH:
  399. if (--nReferenceCount == 0)
  400. {
  401. Trace(1, "Unloading\n");
  402. // Assert if we still have some objects hanging around
  403. assert(g_cLock == 0);
  404. }
  405. break;
  406. }
  407. return TRUE;
  408. }
  409. //////////////////////////////////////////////////////////////////////
  410. // Global Functions
  411. void
  412. LockModule(bool fLock)
  413. {
  414. if (fLock)
  415. {
  416. InterlockedIncrement(&g_cLock);
  417. }
  418. else
  419. {
  420. if (!InterlockedDecrement(&g_cLock))
  421. {
  422. // Clean up the shared thread used to talk to VBScript. Needs to be done before the .dll could be unloaded,
  423. // which otherwise would make for problems because the thread could keep running while the .dll's address
  424. // space becomes invalid.
  425. CSingleThreadedScriptManager::TerminateThread();
  426. }
  427. }
  428. }
  429. long *GetModuleLockCounter()
  430. {
  431. return &g_cLock;
  432. }