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.

279 lines
7.1 KiB

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