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.

361 lines
7.7 KiB

  1. //
  2. // dmbdll.cpp
  3. //
  4. // Copyright (c) 1997-1999 Microsoft Corporation
  5. //
  6. // Note: Dll entry points as well IDirectMusicBandFactory &
  7. // IDirectMusicBandTrkFactory implementations.
  8. // Originally written by Robert K. Amenn with significant parts
  9. // stolen from code written by Jim Geist
  10. //
  11. // READ THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!
  12. //
  13. // 4530: C++ exception handler used, but unwind semantics are not enabled. Specify -GX
  14. //
  15. // We disable this because we use exceptions and do *not* specify -GX (USE_NATIVE_EH in
  16. // sources).
  17. //
  18. // The one place we use exceptions is around construction of objects that call
  19. // InitializeCriticalSection. We guarantee that it is safe to use in this case with
  20. // the restriction given by not using -GX (automatic objects in the call chain between
  21. // throw and handler are not destructed). Turning on -GX buys us nothing but +10% to code
  22. // size because of the unwind code.
  23. //
  24. // Any other use of exceptions must follow these restrictions or -GX must be turned on.
  25. //
  26. // READ THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!
  27. //
  28. #pragma warning(disable:4530)
  29. #include <objbase.h>
  30. #include "debug.h"
  31. #include "debug.h"
  32. #include "..\shared\oledll.h"
  33. #include "dmbandp.h"
  34. #include "bandtrk.h"
  35. //////////////////////////////////////////////////////////////////////
  36. // Globals
  37. // Registry Info (band)
  38. TCHAR g_szBandFriendlyName[] = TEXT("DirectMusicBand");
  39. TCHAR g_szBandVerIndProgID[] = TEXT("Microsoft.DirectMusicBand");
  40. TCHAR g_szBandProgID[] = TEXT("Microsoft.DirectMusicBand.1");
  41. // Registry Info (band track)
  42. TCHAR g_szBandTrackFriendlyName[] = TEXT("DirectMusicBandTrack");
  43. TCHAR g_szBandTrackVerIndProgID[] = TEXT("Microsoft.DirectMusicBandTrack");
  44. TCHAR g_szBandTrackProgID[] = TEXT("Microsoft.DirectMusicBandTrack.1");
  45. // Dll's hModule
  46. HMODULE g_hModule = NULL;
  47. // Count of active components and class factory server locks
  48. long g_cComponent = 0;
  49. long g_cLock = 0;
  50. //////////////////////////////////////////////////////////////////////
  51. // Standard calls needed to be an inproc server
  52. //////////////////////////////////////////////////////////////////////
  53. // DllCanUnloadNow
  54. STDAPI DllCanUnloadNow()
  55. {
  56. if(g_cComponent || g_cLock)
  57. {
  58. return S_FALSE;
  59. }
  60. return S_OK;
  61. }
  62. //////////////////////////////////////////////////////////////////////
  63. // DllGetClassObject
  64. STDAPI DllGetClassObject(const CLSID& clsid,
  65. const IID& iid,
  66. void** ppv)
  67. {
  68. IUnknown* pIUnknown = NULL;
  69. DWORD dwTypeID = 0;
  70. if(clsid == CLSID_DirectMusicBand)
  71. {
  72. dwTypeID = CLASS_BAND;
  73. }
  74. else if(clsid == CLSID_DirectMusicBandTrack)
  75. {
  76. dwTypeID = CLASS_BANDTRACK;
  77. }
  78. else
  79. {
  80. return CLASS_E_CLASSNOTAVAILABLE;
  81. }
  82. pIUnknown = static_cast<IUnknown*> (new CClassFactory(dwTypeID));
  83. if(pIUnknown)
  84. {
  85. HRESULT hr = pIUnknown->QueryInterface(iid, ppv);
  86. pIUnknown->Release();
  87. return hr;
  88. }
  89. return E_OUTOFMEMORY;
  90. }
  91. //////////////////////////////////////////////////////////////////////
  92. // DllUnregisterServer
  93. STDAPI DllUnregisterServer()
  94. {
  95. HRESULT hr = UnregisterServer(CLSID_DirectMusicBand,
  96. g_szBandFriendlyName,
  97. g_szBandVerIndProgID,
  98. g_szBandProgID);
  99. if(SUCCEEDED(hr))
  100. {
  101. hr = UnregisterServer(CLSID_DirectMusicBandTrack,
  102. g_szBandTrackFriendlyName,
  103. g_szBandTrackVerIndProgID,
  104. g_szBandTrackProgID);
  105. }
  106. return hr;
  107. }
  108. //////////////////////////////////////////////////////////////////////
  109. // DllRegisterServer
  110. STDAPI DllRegisterServer()
  111. {
  112. HRESULT hr = RegisterServer(g_hModule,
  113. CLSID_DirectMusicBand,
  114. g_szBandFriendlyName,
  115. g_szBandVerIndProgID,
  116. g_szBandProgID);
  117. if(SUCCEEDED(hr))
  118. {
  119. hr = RegisterServer(g_hModule,
  120. CLSID_DirectMusicBandTrack,
  121. g_szBandTrackFriendlyName,
  122. g_szBandTrackVerIndProgID,
  123. g_szBandTrackProgID);
  124. }
  125. return hr;
  126. }
  127. //////////////////////////////////////////////////////////////////////
  128. // Standard Win32 DllMain
  129. //////////////////////////////////////////////////////////////////////
  130. // DllMain
  131. #ifdef DBG
  132. static char* aszReasons[] =
  133. {
  134. "DLL_PROCESS_DETACH",
  135. "DLL_PROCESS_ATTACH",
  136. "DLL_THREAD_ATTACH",
  137. "DLL_THREAD_DETACH"
  138. };
  139. const DWORD nReasons = (sizeof(aszReasons) / sizeof(char*));
  140. #endif
  141. BOOL APIENTRY DllMain(HINSTANCE hModule,
  142. DWORD dwReason,
  143. void *lpReserved)
  144. {
  145. static int nReferenceCount = 0;
  146. #ifdef DBG
  147. if(dwReason < nReasons)
  148. {
  149. Trace(DM_DEBUG_STATUS, "DllMain: %s\n", (LPSTR)aszReasons[dwReason]);
  150. }
  151. else
  152. {
  153. Trace(DM_DEBUG_STATUS, "DllMain: Unknown dwReason <%u>\n", dwReason);
  154. }
  155. #endif
  156. switch(dwReason)
  157. {
  158. case DLL_PROCESS_ATTACH:
  159. if(++nReferenceCount == 1)
  160. {
  161. #ifdef DBG
  162. DebugInit();
  163. #endif
  164. if(!DisableThreadLibraryCalls(hModule))
  165. {
  166. Trace(DM_DEBUG_STATUS, "DisableThreadLibraryCalls failed.\n");
  167. }
  168. g_hModule = hModule;
  169. }
  170. break;
  171. #ifdef DBG
  172. case DLL_PROCESS_DETACH:
  173. if(--nReferenceCount == 0)
  174. {
  175. TraceI(-1, "Unloading g_cLock %d g_cComponent %d\n", g_cLock, g_cComponent);
  176. // Assert if we still have some objects hanging around
  177. assert(g_cComponent == 0);
  178. assert(g_cLock == 0);
  179. }
  180. break;
  181. #endif
  182. }
  183. return TRUE;
  184. }
  185. // CClassFactory::QueryInterface
  186. //
  187. HRESULT __stdcall
  188. CClassFactory::QueryInterface(const IID &iid,
  189. void **ppv)
  190. {
  191. if (iid == IID_IUnknown || iid == IID_IClassFactory) {
  192. *ppv = static_cast<IClassFactory*>(this);
  193. } else {
  194. *ppv = NULL;
  195. return E_NOINTERFACE;
  196. }
  197. reinterpret_cast<IUnknown*>(*ppv)->AddRef();
  198. return S_OK;
  199. }
  200. CClassFactory::CClassFactory(DWORD dwClassType)
  201. {
  202. m_cRef = 1;
  203. m_dwClassType = dwClassType;
  204. InterlockedIncrement(&g_cLock);
  205. }
  206. CClassFactory::~CClassFactory()
  207. {
  208. InterlockedDecrement(&g_cLock);
  209. }
  210. // CClassFactory::AddRef
  211. //
  212. ULONG __stdcall
  213. CClassFactory::AddRef()
  214. {
  215. return InterlockedIncrement(&m_cRef);
  216. }
  217. // CClassFactory::Release
  218. //
  219. ULONG __stdcall
  220. CClassFactory::Release()
  221. {
  222. if (!InterlockedDecrement(&m_cRef)) {
  223. delete this;
  224. return 0;
  225. }
  226. return m_cRef;
  227. }
  228. // CClassFactory::CreateInstance
  229. //
  230. //
  231. HRESULT __stdcall
  232. CClassFactory::CreateInstance(IUnknown* pUnknownOuter,
  233. const IID& iid,
  234. void** ppv)
  235. {
  236. HRESULT hr;
  237. if (pUnknownOuter)
  238. {
  239. return CLASS_E_NOAGGREGATION;
  240. }
  241. if(ppv == NULL)
  242. {
  243. return E_POINTER;
  244. }
  245. switch (m_dwClassType)
  246. {
  247. case CLASS_BAND:
  248. {
  249. CBand *pDMB;
  250. try
  251. {
  252. pDMB = new CBand;
  253. }
  254. catch( ... )
  255. {
  256. hr = E_OUTOFMEMORY;
  257. break;
  258. }
  259. if(pDMB == NULL)
  260. {
  261. hr = E_OUTOFMEMORY;
  262. break;
  263. }
  264. hr = pDMB->QueryInterface(iid, ppv);
  265. pDMB->Release();
  266. }
  267. break;
  268. case CLASS_BANDTRACK:
  269. {
  270. CBandTrk *pDMBT;
  271. try
  272. {
  273. pDMBT = new CBandTrk;
  274. }
  275. catch( ... )
  276. {
  277. hr = E_OUTOFMEMORY;
  278. break;
  279. }
  280. if(pDMBT == NULL)
  281. {
  282. hr = E_OUTOFMEMORY;
  283. break;
  284. }
  285. hr = pDMBT->QueryInterface(iid, ppv);
  286. pDMBT->Release();
  287. }
  288. break;
  289. }
  290. return hr;
  291. }
  292. // CClassFactory::LockServer
  293. //
  294. HRESULT __stdcall
  295. CClassFactory::LockServer(BOOL bLock)
  296. {
  297. if (bLock) {
  298. InterlockedIncrement(&g_cLock);
  299. } else {
  300. InterlockedDecrement(&g_cLock);
  301. }
  302. return S_OK;
  303. }