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.

413 lines
8.9 KiB

  1. // Copyright (c) 1998-1999 Microsoft Corporation
  2. // loader dll.cpp
  3. //
  4. // Dll entry points and CLoaderFactory, CContainerFactory implementation
  5. //
  6. // READ THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!
  7. //
  8. // 4530: C++ exception handler used, but unwind semantics are not enabled. Specify -GX
  9. //
  10. // We disable this because we use exceptions and do *not* specify -GX (USE_NATIVE_EH in
  11. // sources).
  12. //
  13. // The one place we use exceptions is around construction of objects that call
  14. // InitializeCriticalSection. We guarantee that it is safe to use in this case with
  15. // the restriction given by not using -GX (automatic objects in the call chain between
  16. // throw and handler are not destructed). Turning on -GX buys us nothing but +10% to code
  17. // size because of the unwind code.
  18. //
  19. // Any other use of exceptions must follow these restrictions or -GX must be turned on.
  20. //
  21. // READ THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!
  22. //
  23. #pragma warning(disable:4530)
  24. #include <objbase.h>
  25. #include "debug.h"
  26. #include "oledll.h"
  27. #include "debug.h"
  28. #include "dmusicc.h"
  29. #include "dmusici.h"
  30. #include "loader.h"
  31. #include "container.h"
  32. #ifndef UNDER_CE
  33. #include <regstr.h>
  34. #endif
  35. // Globals
  36. //
  37. // Version information for our class
  38. //
  39. TCHAR g_szFriendlyName[] = TEXT("DirectMusicLoader");
  40. TCHAR g_szVerIndProgID[] = TEXT("Microsoft.DirectMusicLoader");
  41. TCHAR g_szProgID[] = TEXT("Microsoft.DirectMusicLoader.1");
  42. TCHAR g_szContFriendlyName[] = TEXT("DirectMusicContainer");
  43. TCHAR g_szContVerIndProgID[] = TEXT("Microsoft.DirectMusicContainer");
  44. TCHAR g_szContProgID[] = TEXT("Microsoft.DirectMusicContainer.1");
  45. // Dll's hModule
  46. //
  47. HMODULE g_hModule = NULL;
  48. #ifndef UNDER_CE
  49. // Track whether running on Unicode machine.
  50. BOOL g_fIsUnicode = FALSE;
  51. #endif
  52. // Count of active components and class factory server locks
  53. //
  54. long g_cComponent = 0;
  55. long g_cLock = 0;
  56. // CLoaderFactory::QueryInterface
  57. //
  58. HRESULT __stdcall
  59. CLoaderFactory::QueryInterface(const IID &iid,
  60. void **ppv)
  61. {
  62. if (iid == IID_IUnknown || iid == IID_IClassFactory) {
  63. *ppv = static_cast<IClassFactory*>(this);
  64. } else {
  65. *ppv = NULL;
  66. return E_NOINTERFACE;
  67. }
  68. reinterpret_cast<IUnknown*>(*ppv)->AddRef();
  69. return S_OK;
  70. }
  71. CLoaderFactory::CLoaderFactory()
  72. {
  73. m_cRef = 1;
  74. InterlockedIncrement(&g_cLock);
  75. }
  76. CLoaderFactory::~CLoaderFactory()
  77. {
  78. InterlockedDecrement(&g_cLock);
  79. }
  80. // CLoaderFactory::AddRef
  81. //
  82. ULONG __stdcall
  83. CLoaderFactory::AddRef()
  84. {
  85. return InterlockedIncrement(&m_cRef);
  86. }
  87. // CLoaderFactory::Release
  88. //
  89. ULONG __stdcall
  90. CLoaderFactory::Release()
  91. {
  92. if (!InterlockedDecrement(&m_cRef)) {
  93. delete this;
  94. return 0;
  95. }
  96. return m_cRef;
  97. }
  98. // CLoaderFactory::CreateInstance
  99. //
  100. //
  101. HRESULT __stdcall
  102. CLoaderFactory::CreateInstance(IUnknown* pUnknownOuter,
  103. const IID& iid,
  104. void** ppv)
  105. {
  106. HRESULT hr;
  107. if (pUnknownOuter) {
  108. return CLASS_E_NOAGGREGATION;
  109. }
  110. CLoader *pLoader;
  111. try
  112. {
  113. pLoader = new CLoader;
  114. }
  115. catch( ... )
  116. {
  117. return E_OUTOFMEMORY;
  118. }
  119. if (pLoader == NULL) {
  120. return E_OUTOFMEMORY;
  121. }
  122. // Do initialiazation
  123. //
  124. hr = pLoader->Init();
  125. if (!SUCCEEDED(hr)) {
  126. delete pLoader;
  127. return hr;
  128. }
  129. hr = pLoader->QueryInterface(iid, ppv);
  130. pLoader->Release();
  131. return hr;
  132. }
  133. // CLoaderFactory::LockServer
  134. //
  135. HRESULT __stdcall
  136. CLoaderFactory::LockServer(BOOL bLock)
  137. {
  138. if (bLock) {
  139. InterlockedIncrement(&g_cLock);
  140. } else {
  141. InterlockedDecrement(&g_cLock);
  142. }
  143. return S_OK;
  144. }
  145. // CContainerFactory::QueryInterface
  146. //
  147. HRESULT __stdcall
  148. CContainerFactory::QueryInterface(const IID &iid,
  149. void **ppv)
  150. {
  151. if (iid == IID_IUnknown || iid == IID_IClassFactory) {
  152. *ppv = static_cast<IClassFactory*>(this);
  153. } else {
  154. *ppv = NULL;
  155. return E_NOINTERFACE;
  156. }
  157. reinterpret_cast<IUnknown*>(*ppv)->AddRef();
  158. return S_OK;
  159. }
  160. CContainerFactory::CContainerFactory()
  161. {
  162. m_cRef = 1;
  163. InterlockedIncrement(&g_cLock);
  164. }
  165. CContainerFactory::~CContainerFactory()
  166. {
  167. InterlockedDecrement(&g_cLock);
  168. }
  169. // CContainerFactory::AddRef
  170. //
  171. ULONG __stdcall
  172. CContainerFactory::AddRef()
  173. {
  174. return InterlockedIncrement(&m_cRef);
  175. }
  176. // CContainerFactory::Release
  177. //
  178. ULONG __stdcall
  179. CContainerFactory::Release()
  180. {
  181. if (!InterlockedDecrement(&m_cRef)) {
  182. delete this;
  183. return 0;
  184. }
  185. return m_cRef;
  186. }
  187. // CContainerFactory::CreateInstance
  188. //
  189. //
  190. HRESULT __stdcall
  191. CContainerFactory::CreateInstance(IUnknown* pUnknownOuter,
  192. const IID& iid,
  193. void** ppv)
  194. {
  195. HRESULT hr;
  196. if (pUnknownOuter) {
  197. return CLASS_E_NOAGGREGATION;
  198. }
  199. CContainer *pContainer;
  200. try
  201. {
  202. pContainer = new CContainer;
  203. }
  204. catch( ... )
  205. {
  206. return E_OUTOFMEMORY;
  207. }
  208. if (pContainer == NULL) {
  209. return E_OUTOFMEMORY;
  210. }
  211. hr = pContainer->QueryInterface(iid, ppv);
  212. pContainer->Release();
  213. return hr;
  214. }
  215. // CContainerFactory::LockServer
  216. //
  217. HRESULT __stdcall
  218. CContainerFactory::LockServer(BOOL bLock)
  219. {
  220. if (bLock) {
  221. InterlockedIncrement(&g_cLock);
  222. } else {
  223. InterlockedDecrement(&g_cLock);
  224. }
  225. return S_OK;
  226. }
  227. // Standard calls needed to be an inproc server
  228. //
  229. STDAPI DllCanUnloadNow()
  230. {
  231. if (g_cComponent || g_cLock) {
  232. return S_FALSE;
  233. }
  234. return S_OK;
  235. }
  236. STDAPI DllGetClassObject(const CLSID& clsid,
  237. const IID& iid,
  238. void** ppv)
  239. {
  240. IUnknown* pIUnknown = NULL;
  241. if(clsid == CLSID_DirectMusicLoader)
  242. {
  243. pIUnknown = static_cast<IUnknown*> (new CLoaderFactory);
  244. if(!pIUnknown)
  245. {
  246. return E_OUTOFMEMORY;
  247. }
  248. }
  249. else if(clsid == CLSID_DirectMusicContainer)
  250. {
  251. pIUnknown = static_cast<IUnknown*> (new CContainerFactory);
  252. if(!pIUnknown)
  253. {
  254. return E_OUTOFMEMORY;
  255. }
  256. }
  257. else
  258. {
  259. return CLASS_E_CLASSNOTAVAILABLE;
  260. }
  261. HRESULT hr = pIUnknown->QueryInterface(iid, ppv);
  262. pIUnknown->Release();
  263. return hr;
  264. }
  265. STDAPI DllUnregisterServer()
  266. {
  267. UnregisterServer(CLSID_DirectMusicLoader,
  268. g_szFriendlyName,
  269. g_szVerIndProgID,
  270. g_szProgID);
  271. UnregisterServer(CLSID_DirectMusicContainer,
  272. g_szContFriendlyName,
  273. g_szContVerIndProgID,
  274. g_szContProgID);
  275. return S_OK;
  276. }
  277. STDAPI DllRegisterServer()
  278. {
  279. RegisterServer(g_hModule,
  280. CLSID_DirectMusicLoader,
  281. g_szFriendlyName,
  282. g_szVerIndProgID,
  283. g_szProgID);
  284. RegisterServer(g_hModule,
  285. CLSID_DirectMusicContainer,
  286. g_szContFriendlyName,
  287. g_szContVerIndProgID,
  288. g_szContProgID);
  289. return S_OK;
  290. }
  291. extern void DebugInit();
  292. // Standard Win32 DllMain
  293. //
  294. #ifdef DBG
  295. static char* aszReasons[] =
  296. {
  297. "DLL_PROCESS_DETACH",
  298. "DLL_PROCESS_ATTACH",
  299. "DLL_THREAD_ATTACH",
  300. "DLL_THREAD_DETACH"
  301. };
  302. const DWORD nReasons = (sizeof(aszReasons) / sizeof(char*));
  303. #endif
  304. BOOL APIENTRY DllMain(HINSTANCE hModule,
  305. DWORD dwReason,
  306. void *lpReserved)
  307. {
  308. static int nReferenceCount = 0;
  309. #ifdef DBG
  310. if (dwReason < nReasons)
  311. {
  312. DebugTrace(0, "DllMain: %s\n", (LPSTR)aszReasons[dwReason]);
  313. }
  314. else
  315. {
  316. DebugTrace(0, "DllMain: Unknown dwReason <%u>\n", dwReason);
  317. }
  318. #endif
  319. if (dwReason == DLL_PROCESS_ATTACH) {
  320. if (++nReferenceCount == 1)
  321. {
  322. g_hModule = (HMODULE)hModule;
  323. #ifndef UNDER_CE
  324. OSVERSIONINFO osvi;
  325. DisableThreadLibraryCalls(hModule);
  326. osvi.dwOSVersionInfoSize = sizeof(osvi);
  327. GetVersionEx(&osvi);
  328. g_fIsUnicode =
  329. (osvi.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS);
  330. #endif
  331. #ifdef DBG
  332. DebugInit();
  333. #endif
  334. }
  335. }
  336. #ifdef DBG
  337. else if(dwReason == DLL_PROCESS_DETACH) {
  338. if (--nReferenceCount == 0)
  339. {
  340. TraceI(-1, "Unloading DMLoader : g_cLock = %d, g_cComponent = %d", g_cLock, g_cComponent);
  341. // Assert if we still have some objects hanging around
  342. assert(g_cComponent == 0);
  343. assert(g_cLock == 0);
  344. }
  345. }
  346. #endif
  347. return TRUE;
  348. }