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.

276 lines
7.0 KiB

  1. //
  2. // server.cpp
  3. //
  4. // COM server exports.
  5. //
  6. #include "globals.h"
  7. #include "case.h"
  8. void FreeGlobalObjects(void);
  9. class CClassFactory;
  10. static CClassFactory *g_ObjectInfo[1] = { NULL };
  11. //+---------------------------------------------------------------------------
  12. //
  13. // DllAddRef
  14. //
  15. //----------------------------------------------------------------------------
  16. void DllAddRef(void)
  17. {
  18. InterlockedIncrement(&g_cRefDll);
  19. }
  20. //+---------------------------------------------------------------------------
  21. //
  22. // DllRelease
  23. //
  24. //----------------------------------------------------------------------------
  25. void DllRelease(void)
  26. {
  27. if (InterlockedDecrement(&g_cRefDll) < 0) // g_cRefDll == -1 with zero refs
  28. {
  29. EnterCriticalSection(&g_cs);
  30. // need to check ref again after grabbing mutex
  31. if (g_ObjectInfo[0] != NULL)
  32. {
  33. FreeGlobalObjects();
  34. }
  35. assert(g_cRefDll == -1);
  36. LeaveCriticalSection(&g_cs);
  37. }
  38. }
  39. //+---------------------------------------------------------------------------
  40. //
  41. // CClassFactory declaration with IClassFactory Interface
  42. //
  43. //----------------------------------------------------------------------------
  44. class CClassFactory : public IClassFactory
  45. {
  46. public:
  47. // IUnknown methods
  48. STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj);
  49. STDMETHODIMP_(ULONG) AddRef(void);
  50. STDMETHODIMP_(ULONG) Release(void);
  51. // IClassFactory methods
  52. STDMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObj);
  53. STDMETHODIMP LockServer(BOOL fLock);
  54. // Constructor
  55. CClassFactory(REFCLSID rclsid, HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, REFIID riid, void **ppvObj))
  56. : _rclsid(rclsid)
  57. {
  58. _pfnCreateInstance = pfnCreateInstance;
  59. }
  60. public:
  61. REFCLSID _rclsid;
  62. HRESULT (*_pfnCreateInstance)(IUnknown *pUnkOuter, REFIID riid, void **ppvObj);
  63. };
  64. //+---------------------------------------------------------------------------
  65. //
  66. // CClassFactory::QueryInterface
  67. //
  68. //----------------------------------------------------------------------------
  69. STDAPI CClassFactory::QueryInterface(REFIID riid, void **ppvObj)
  70. {
  71. if (IsEqualIID(riid, IID_IClassFactory) || IsEqualIID(riid, IID_IUnknown))
  72. {
  73. *ppvObj = this;
  74. DllAddRef();
  75. return NOERROR;
  76. }
  77. *ppvObj = NULL;
  78. return E_NOINTERFACE;
  79. }
  80. //+---------------------------------------------------------------------------
  81. //
  82. // CClassFactory::AddRef
  83. //
  84. //----------------------------------------------------------------------------
  85. STDAPI_(ULONG) CClassFactory::AddRef()
  86. {
  87. DllAddRef();
  88. return g_cRefDll+1; // -1 w/ no refs
  89. }
  90. //+---------------------------------------------------------------------------
  91. //
  92. // CClassFactory::Release
  93. //
  94. //----------------------------------------------------------------------------
  95. STDAPI_(ULONG) CClassFactory::Release()
  96. {
  97. DllRelease();
  98. return g_cRefDll+1; // -1 w/ no refs
  99. }
  100. //+---------------------------------------------------------------------------
  101. //
  102. // CClassFactory::CreateInstance
  103. //
  104. //----------------------------------------------------------------------------
  105. STDAPI CClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObj)
  106. {
  107. return _pfnCreateInstance(pUnkOuter, riid, ppvObj);
  108. }
  109. //+---------------------------------------------------------------------------
  110. //
  111. // CClassFactory::LockServer
  112. //
  113. //----------------------------------------------------------------------------
  114. STDAPI CClassFactory::LockServer(BOOL fLock)
  115. {
  116. if (fLock)
  117. {
  118. DllAddRef();
  119. }
  120. else
  121. {
  122. DllRelease();
  123. }
  124. return S_OK;
  125. }
  126. //+---------------------------------------------------------------------------
  127. //
  128. // BuildGlobalObjects
  129. //
  130. //----------------------------------------------------------------------------
  131. void BuildGlobalObjects(void)
  132. {
  133. // Build CClassFactory Objects
  134. g_ObjectInfo[0] = new CClassFactory(c_clsidCaseTextService, CCaseTextService::CreateInstance);
  135. // You can add more object info here.
  136. // Don't forget to increase number of item for g_ObjectInfo[],
  137. }
  138. //+---------------------------------------------------------------------------
  139. //
  140. // FreeGlobalObjects
  141. //
  142. //----------------------------------------------------------------------------
  143. void FreeGlobalObjects(void)
  144. {
  145. // Free CClassFactory Objects
  146. for (int i = 0; i < ARRAYSIZE(g_ObjectInfo); i++)
  147. {
  148. if (NULL != g_ObjectInfo[i])
  149. {
  150. delete g_ObjectInfo[i];
  151. g_ObjectInfo[i] = NULL;
  152. }
  153. }
  154. }
  155. //+---------------------------------------------------------------------------
  156. //
  157. // DllGetClassObject
  158. //
  159. //----------------------------------------------------------------------------
  160. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppvObj)
  161. {
  162. if (g_ObjectInfo[0] == NULL)
  163. {
  164. EnterCriticalSection(&g_cs);
  165. // need to check ref again after grabbing mutex
  166. if (g_ObjectInfo[0] == NULL)
  167. {
  168. BuildGlobalObjects();
  169. }
  170. LeaveCriticalSection(&g_cs);
  171. }
  172. if (IsEqualIID(riid, IID_IClassFactory) ||
  173. IsEqualIID(riid, IID_IUnknown))
  174. {
  175. for (int i = 0; i < ARRAYSIZE(g_ObjectInfo); i++)
  176. {
  177. if (NULL != g_ObjectInfo[i] &&
  178. IsEqualGUID(rclsid, g_ObjectInfo[i]->_rclsid))
  179. {
  180. *ppvObj = (void *)g_ObjectInfo[i];
  181. DllAddRef(); // class factory holds DLL ref count
  182. return NOERROR;
  183. }
  184. }
  185. }
  186. *ppvObj = NULL;
  187. return CLASS_E_CLASSNOTAVAILABLE;
  188. }
  189. //+---------------------------------------------------------------------------
  190. //
  191. // DllCanUnloadNow
  192. //
  193. //----------------------------------------------------------------------------
  194. STDAPI DllCanUnloadNow(void)
  195. {
  196. if (g_cRefDll >= 0) // -1 with no refs
  197. return S_FALSE;
  198. return S_OK;
  199. }
  200. //+---------------------------------------------------------------------------
  201. //
  202. // DllUnregisterServer
  203. //
  204. //----------------------------------------------------------------------------
  205. STDAPI DllUnregisterServer(void)
  206. {
  207. CCaseTextService::RegisterCategories(FALSE);
  208. CCaseTextService::UnregisterProfiles();
  209. CCaseTextService::UnregisterServer();
  210. return S_OK;
  211. }
  212. //+---------------------------------------------------------------------------
  213. //
  214. // DllRegisterServer
  215. //
  216. //----------------------------------------------------------------------------
  217. STDAPI DllRegisterServer(void)
  218. {
  219. // register this service's profile with the tsf
  220. if (!CCaseTextService::RegisterServer() ||
  221. !CCaseTextService::RegisterProfiles() ||
  222. !CCaseTextService::RegisterCategories(TRUE))
  223. {
  224. DllUnregisterServer(); // cleanup any loose ends
  225. return E_FAIL;
  226. }
  227. return S_OK;
  228. }