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.

343 lines
9.5 KiB

  1. /****************************************************************************
  2. SERVER.CPP : COM server functionality
  3. History:
  4. 15-NOV-1999 CSLim Created
  5. ****************************************************************************/
  6. #include "private.h"
  7. #include "korimx.h"
  8. #include "regsvr.h"
  9. #include "regimx.h"
  10. #include "init.h"
  11. #include "gdata.h"
  12. #include "catutil.h"
  13. #include "insert.h"
  14. #include "immxutil.h"
  15. #include "hanja.h"
  16. #if !defined(NOCLIB) && defined(_M_IX86)
  17. extern "C" BOOL WINAPI _CRT_INIT(HINSTANCE, DWORD, LPVOID);
  18. #endif
  19. #ifdef DEBUG
  20. DWORD g_dwThreadDllMain = 0;
  21. #endif
  22. void DllAddRef(void);
  23. void DllRelease(void);
  24. LONG g_cRefDll = 0;
  25. //
  26. // CClassFactory declaration with IClassFactory Interface
  27. //
  28. class CClassFactory : public IClassFactory
  29. {
  30. public:
  31. // IUnknown methods
  32. virtual STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj);
  33. virtual STDMETHODIMP_(ULONG) AddRef(void);
  34. virtual STDMETHODIMP_(ULONG) Release(void);
  35. // IClassFactory methods
  36. virtual STDMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObj);
  37. virtual STDMETHODIMP LockServer(BOOL fLock);
  38. // Constructor & Destructor
  39. CClassFactory(REFCLSID rclsid, HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, REFIID riid, void **ppvObj));
  40. ~CClassFactory();
  41. public:
  42. REFCLSID _rclsid;
  43. HRESULT (*_pfnCreateInstance)(IUnknown *pUnkOuter, REFIID riid, void **ppvObj);
  44. };
  45. CClassFactory::CClassFactory(REFCLSID rclsid, HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, REFIID riid, void **ppvObj))
  46. : _rclsid( rclsid ), _pfnCreateInstance( pfnCreateInstance )
  47. {
  48. DebugMsg(DM_TRACE, TEXT("constructor of CClassFactory 0x%08x"), this);
  49. }
  50. CClassFactory::~CClassFactory()
  51. {
  52. DebugMsg(DM_TRACE, TEXT("destructor of CClassFactory 0x%08x"), this);
  53. }
  54. STDAPI CClassFactory::QueryInterface(REFIID riid, void **ppvObj)
  55. {
  56. DebugMsg(DM_TRACE, TEXT("CClassFactory::QueryInterface called."));
  57. if (IsEqualIID(riid, IID_IClassFactory) || IsEqualIID(riid, IID_IUnknown))
  58. {
  59. *ppvObj = SAFECAST(this, IClassFactory*);
  60. DllAddRef();
  61. return NOERROR;
  62. }
  63. *ppvObj = NULL;
  64. return E_NOINTERFACE;
  65. }
  66. STDAPI_(ULONG) CClassFactory::AddRef()
  67. {
  68. DllAddRef();
  69. DebugMsg(DM_TRACE, TEXT("CClassFactory::AddRef called. g_cRefDll=%d"), g_cRefDll);
  70. return g_cRefDll;
  71. }
  72. STDAPI_(ULONG) CClassFactory::Release()
  73. {
  74. DllRelease();
  75. DebugMsg(DM_TRACE, TEXT("CClassFactory::Release called. g_cRefDll=%d"), g_cRefDll);
  76. return g_cRefDll;
  77. }
  78. STDAPI CClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObj)
  79. {
  80. DebugMsg(DM_TRACE, TEXT("CClassFactory::CreateInstance called."));
  81. return this->_pfnCreateInstance(pUnkOuter, riid, ppvObj);
  82. }
  83. STDAPI CClassFactory::LockServer(BOOL fLock)
  84. {
  85. if (fLock)
  86. DllAddRef();
  87. else
  88. DllRelease();
  89. DebugMsg(DM_TRACE, TEXT("CClassFactory::LockServer(%s) to %d"), fLock ? TEXT("LOCK") : TEXT("UNLOCK"), g_cRefDll);
  90. return S_OK;
  91. }
  92. //
  93. // Build Global Objects
  94. //
  95. CClassFactory *g_ObjectInfo[1] = { NULL };
  96. void BuildGlobalObjects(void)
  97. {
  98. DebugMsg(DM_TRACE, TEXT("BuildGlobalObjects called."));
  99. // Build CClassFactory Objects
  100. g_ObjectInfo[0] = new CClassFactory(CLSID_KorIMX, CKorIMX::CreateInstance);
  101. // You can add more object info here.
  102. // Don't forget to increase number of item for g_ObjectInfo[],
  103. // and add function prototype to private.h
  104. }
  105. void FreeGlobalObjects(void)
  106. {
  107. DebugMsg(DM_TRACE, TEXT("FreeGlobalObjects called."));
  108. // Free CClassFactory Objects
  109. for (int i = 0; i < ARRAYSIZE(g_ObjectInfo); i++)
  110. {
  111. if (NULL != g_ObjectInfo[i])
  112. {
  113. delete g_ObjectInfo[i];
  114. g_ObjectInfo[i] = NULL;
  115. }
  116. }
  117. }
  118. /*---------------------------------------------------------------------------
  119. DllMain
  120. ---------------------------------------------------------------------------*/
  121. STDAPI_(BOOL) DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID pvReserved)
  122. {
  123. WNDCLASSEX wndclass;
  124. #if DEBUG
  125. g_dwThreadDllMain = GetCurrentThreadId();
  126. #endif
  127. switch (dwReason)
  128. {
  129. case DLL_PROCESS_ATTACH:
  130. #if !defined(NOCLIB) && defined(_M_IX86)
  131. _CRT_INIT(hInstance, dwReason, pvReserved);
  132. #endif
  133. CcshellGetDebugFlags();
  134. Dbg_MemInit(TEXT("KORIMX"), NULL);
  135. g_hInst = hInstance;
  136. g_cs.Init();
  137. ZeroMemory(&wndclass, sizeof(wndclass));
  138. wndclass.cbSize = sizeof(wndclass);
  139. wndclass.style = CS_HREDRAW | CS_VREDRAW ;
  140. wndclass.hInstance = hInstance;
  141. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  142. wndclass.lpfnWndProc = CKorIMX::_OwnerWndProc;
  143. wndclass.lpszClassName = c_szOwnerWndClass;
  144. RegisterClassEx(&wndclass);
  145. // Initialize Shared memory
  146. CIMEData::InitSharedData();
  147. break;
  148. case DLL_THREAD_ATTACH:
  149. break;
  150. case DLL_PROCESS_DETACH:
  151. UnregisterClass(c_szOwnerWndClass, g_hInst);
  152. g_cs.Delete();
  153. #if !defined(NOCLIB) && defined(_M_IX86)
  154. _CRT_INIT(hInstance, dwReason, pvReserved);
  155. #endif
  156. // Close lex file if has opened ever.
  157. CloseLex();
  158. // Close shared memory
  159. CIMEData::CloseSharedMemory();
  160. // This should be last.
  161. Dbg_MemUninit();
  162. break;
  163. case DLL_THREAD_DETACH:
  164. break;
  165. }
  166. #if DEBUG
  167. g_dwThreadDllMain = 0;
  168. #endif
  169. return TRUE;
  170. }
  171. /*---------------------------------------------------------------------------
  172. DllAddRef
  173. ---------------------------------------------------------------------------*/
  174. void DllAddRef(void)
  175. {
  176. InterlockedIncrement(&g_cRefDll);
  177. ASSERT(1000 > g_cRefDll); // reasonable upper limit
  178. DllInit();
  179. }
  180. /*---------------------------------------------------------------------------
  181. DllRelease
  182. ---------------------------------------------------------------------------*/
  183. void DllRelease(void)
  184. {
  185. InterlockedDecrement(&g_cRefDll);
  186. if (0 == g_cRefDll)
  187. FreeGlobalObjects();
  188. ASSERT(0 <= g_cRefDll); // don't underflow
  189. DllUninit();
  190. }
  191. /*---------------------------------------------------------------------------
  192. DllGetClassObject
  193. ---------------------------------------------------------------------------*/
  194. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppvObj)
  195. {
  196. DebugMsg(DM_TRACE, TEXT("DllGetClassObject called."));
  197. if (0 == g_cRefDll)
  198. BuildGlobalObjects();
  199. if (IsEqualIID(riid, IID_IClassFactory) || IsEqualIID(riid, IID_IUnknown))
  200. {
  201. for (int i = 0; i < ARRAYSIZE(g_ObjectInfo); i++)
  202. {
  203. if (NULL != g_ObjectInfo[i] && IsEqualGUID(rclsid, g_ObjectInfo[i]->_rclsid))
  204. {
  205. *ppvObj = (void *)g_ObjectInfo[i];
  206. DllAddRef(); // class factory holds DLL ref count
  207. return NOERROR;
  208. }
  209. }
  210. }
  211. *ppvObj = NULL;
  212. return CLASS_E_CLASSNOTAVAILABLE;
  213. }
  214. /*---------------------------------------------------------------------------
  215. DllCanUnloadNow
  216. ---------------------------------------------------------------------------*/
  217. STDAPI DllCanUnloadNow(void)
  218. {
  219. if (0 < g_cRefDll)
  220. return S_FALSE;
  221. DebugMsg(DM_TRACE, TEXT("DllCanUnloadNow returning S_OK"));
  222. return S_OK;
  223. }
  224. // TIP Categories to be added
  225. const REGISTERCAT c_rgRegCat[] =
  226. {
  227. {&GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER, &CLSID_KorIMX},
  228. {&GUID_TFCAT_TIP_KEYBOARD, &CLSID_KorIMX},
  229. {&GUID_TFCAT_PROPSTYLE_CUSTOM, &GUID_PROP_OVERTYPE},
  230. {NULL, NULL}
  231. };
  232. // TIP Profile name
  233. const REGTIPLANGPROFILE c_rgProf[] =
  234. {
  235. { MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT), &GUID_Profile, SZ_TIPDISPNAME, SZ_TIPMODULENAME, (IDI_UNIKOR-IDI_ICONBASE), IDS_PROFILEDESC },
  236. {0, &GUID_NULL, L"", L"", 0, 0}
  237. };
  238. BOOL FIsAvailable( REFCLSID refclsid, BOOL fLocalSvr );
  239. /*---------------------------------------------------------------------------
  240. DllRegisterServer
  241. ---------------------------------------------------------------------------*/
  242. STDAPI DllRegisterServer(void)
  243. {
  244. TCHAR achPath[MAX_PATH+1];
  245. HRESULT hr = E_FAIL;
  246. TFInitLib();
  247. if (GetModuleFileName(g_hInst, achPath, ARRAYSIZE(achPath)) == 0)
  248. goto Exit;
  249. if (!RegisterServer(CLSID_KorIMX, SZ_TIPSERVERNAME, achPath, TEXT("Apartment"), NULL))
  250. goto Exit;
  251. if (!RegisterTIP(g_hInst, CLSID_KorIMX, SZ_TIPNAME, c_rgProf))
  252. goto Exit;
  253. if (FAILED(RegisterCategories(CLSID_KorIMX, c_rgRegCat)))
  254. goto Exit;
  255. hr = S_OK;
  256. Exit:
  257. TFUninitLib();
  258. return hr;
  259. }
  260. /*---------------------------------------------------------------------------
  261. DllUnregisterServer
  262. ---------------------------------------------------------------------------*/
  263. STDAPI DllUnregisterServer(void)
  264. {
  265. HRESULT hr = E_FAIL;
  266. TFInitLib();
  267. if (FAILED(hr = RegisterServer(CLSID_KorIMX, NULL, NULL, NULL, NULL) ? S_OK : E_FAIL))
  268. goto Exit;
  269. if (FAILED(UnregisterCategories(CLSID_KorIMX, c_rgRegCat)))
  270. goto Exit;
  271. if (!UnregisterTIP(CLSID_KorIMX))
  272. goto Exit;
  273. hr = S_OK;
  274. Exit:
  275. TFUninitLib();
  276. return hr;
  277. }