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.

400 lines
9.0 KiB

  1. //
  2. // gcompart.cpp
  3. //
  4. #include "private.h"
  5. #include "globals.h"
  6. #include "gcompart.h"
  7. #include "cregkey.h"
  8. #include "thdutil.h"
  9. #include "regsvr.h"
  10. CGCompartList g_gcomplist;
  11. CSharedBlock *CGCompartList::_psb = NULL;
  12. ULONG CGCompartList::_ulCommitSize = INITIAL_GCOMPART_SIZE;
  13. LONG CGCompartList::_nRef = -1;
  14. BOOL CGCompartList::_fCreate = FALSE;
  15. //////////////////////////////////////////////////////////////////////////////
  16. //
  17. // CGCompartList
  18. //
  19. //////////////////////////////////////////////////////////////////////////////
  20. //--------------------------------------------------------------------------
  21. //
  22. // Init
  23. //
  24. //--------------------------------------------------------------------------
  25. BOOL CGCompartList::Init(SYSTHREAD *psfn)
  26. {
  27. static const char c_szGCompartList[] = "MSCTF.GCompartList";
  28. BOOL bRet = FALSE;
  29. BOOL bAlreadyExist = FALSE;
  30. if (!psfn)
  31. return FALSE;
  32. Assert(!psfn->fInitGlobalCompartment);
  33. CicEnterCriticalSection(g_csInDllMain);
  34. if (++_nRef)
  35. {
  36. bRet = TRUE;
  37. goto Exit;
  38. }
  39. _psb = new CSharedBlockNT(c_szGCompartList, 0, TRUE);
  40. if (!_psb)
  41. {
  42. Assert(0);
  43. goto Exit;
  44. }
  45. HRESULT hr = _psb->Init(NULL, 0x40000, _ulCommitSize, NULL, TRUE, &bAlreadyExist);
  46. if (FAILED(hr))
  47. {
  48. Assert(0);
  49. goto Exit;
  50. }
  51. if (!bAlreadyExist)
  52. {
  53. Start();
  54. }
  55. bRet = TRUE;
  56. Exit:
  57. if (!bRet)
  58. {
  59. _nRef--;
  60. if (_psb)
  61. delete _psb;
  62. _psb = NULL;
  63. }
  64. CicLeaveCriticalSection(g_csInDllMain);
  65. if (bRet)
  66. psfn->fInitGlobalCompartment = TRUE;
  67. return bRet;
  68. }
  69. //--------------------------------------------------------------------------
  70. //
  71. // Start
  72. //
  73. //--------------------------------------------------------------------------
  74. BOOL CGCompartList::Start()
  75. {
  76. GLOBALCOMPARTMENTLIST *pgcl;
  77. if (!_psb)
  78. {
  79. Assert(0);
  80. return FALSE;
  81. }
  82. _fCreate = TRUE;
  83. CMyRegKey key;
  84. CMyRegKey keyLM;
  85. DWORD ulNum = 0;
  86. char szSubKey[MAX_PATH];
  87. pgcl = (GLOBALCOMPARTMENTLIST *)_psb->GetBase();
  88. keyLM.Open(HKEY_LOCAL_MACHINE, c_szCompartKey, KEY_READ);
  89. if (key.Open(HKEY_CURRENT_USER, c_szCompartKey, KEY_READ) == S_OK)
  90. {
  91. DWORD dwIndex = 0;
  92. while (key.EnumKey(dwIndex, szSubKey, ARRAYSIZE(szSubKey)) == S_OK)
  93. {
  94. CMyRegKey subkey;
  95. CMyRegKey subkeyLM;
  96. CLSID clsid;
  97. if (!StringAToCLSID(szSubKey, &clsid))
  98. continue;
  99. DWORD dwReqSize = ((ulNum + 1) * sizeof(GLOBALCOMPARTMENT)) +
  100. sizeof(GLOBALCOMPARTMENTLIST);
  101. if (_ulCommitSize < dwReqSize)
  102. {
  103. dwReqSize *= 2;
  104. if (FAILED(_psb->Commit(dwReqSize)))
  105. goto Exit;
  106. _ulCommitSize = dwReqSize;
  107. }
  108. if (subkey.Open(key, szSubKey, KEY_READ) == S_OK)
  109. {
  110. DWORD dwNonInit = 0;
  111. if ((HKEY)keyLM &&
  112. subkeyLM.Open(keyLM, szSubKey, KEY_READ) == S_OK)
  113. {
  114. if (subkeyLM.QueryValue(dwNonInit, c_szNonInit) != S_OK)
  115. dwNonInit = 0;
  116. }
  117. if (!dwNonInit)
  118. {
  119. GLOBALCOMPARTMENT *pgc = &pgcl->rgGCompart[ulNum];
  120. DWORD dwCount = sizeof(GLOBALCOMPARTMENT);
  121. if (subkey.QueryBinaryValue(pgc,
  122. dwCount,
  123. c_szGlobalCompartment) == S_OK)
  124. ulNum++;
  125. }
  126. }
  127. dwIndex++;
  128. }
  129. }
  130. pgcl->ulNum = ulNum;
  131. Exit:
  132. return TRUE;
  133. }
  134. //--------------------------------------------------------------------------
  135. //
  136. // UnInit
  137. //
  138. //--------------------------------------------------------------------------
  139. BOOL CGCompartList::Uninit(SYSTHREAD *psfn)
  140. {
  141. if (!psfn)
  142. return FALSE;
  143. if (!_psb)
  144. return TRUE;
  145. if (_fCreate)
  146. {
  147. CMyRegKey key;
  148. if (key.Create(HKEY_CURRENT_USER, c_szCompartKey) == S_OK)
  149. {
  150. char szSubKey[MAX_PATH];
  151. ULONG i;
  152. GLOBALCOMPARTMENTLIST *pgcl;
  153. pgcl = (GLOBALCOMPARTMENTLIST *)_psb->GetBase();
  154. for (i = 0; i < pgcl->ulNum; i++)
  155. {
  156. GLOBALCOMPARTMENT *pgc = &pgcl->rgGCompart[i];
  157. CMyRegKey subkey;
  158. CLSIDToStringA(pgc->guid, szSubKey);
  159. if (subkey.Create(key, szSubKey) == S_OK)
  160. {
  161. subkey.SetBinaryValue(pgc,
  162. sizeof(GLOBALCOMPARTMENT),
  163. c_szGlobalCompartment);
  164. }
  165. }
  166. }
  167. }
  168. if (!psfn->fInitGlobalCompartment)
  169. return TRUE;
  170. CicEnterCriticalSection(g_csInDllMain);
  171. if (--_nRef >= 0)
  172. goto Exit;
  173. if (_psb)
  174. delete _psb;
  175. _psb = NULL;
  176. Exit:
  177. CicLeaveCriticalSection(g_csInDllMain);
  178. psfn->fInitGlobalCompartment = FALSE;
  179. return TRUE;
  180. }
  181. //--------------------------------------------------------------------------
  182. //
  183. // SetProperty
  184. //
  185. //--------------------------------------------------------------------------
  186. CGCompartList::GLOBALCOMPARTMENT *CGCompartList::FindProperty(REFGUID guid)
  187. {
  188. GLOBALCOMPARTMENTLIST *pgcl = (GLOBALCOMPARTMENTLIST *)_psb->GetBase();
  189. UINT i;
  190. GLOBALCOMPARTMENT *pgc = NULL;
  191. if (!pgcl)
  192. {
  193. Assert(0);
  194. return NULL;
  195. }
  196. for (i = 0; i < pgcl->ulNum; i++)
  197. {
  198. GLOBALCOMPARTMENT *pgcTemp = &pgcl->rgGCompart[i];
  199. if (IsEqualGUID(pgcTemp->guid, guid))
  200. {
  201. pgc = pgcTemp;
  202. break;
  203. }
  204. }
  205. return pgc;
  206. }
  207. //--------------------------------------------------------------------------
  208. //
  209. // SetProperty
  210. //
  211. //--------------------------------------------------------------------------
  212. DWORD CGCompartList::SetProperty(REFGUID guid, TFPROPERTY *pProp)
  213. {
  214. DWORD dwRet = (DWORD)(-1);
  215. GLOBALCOMPARTMENTLIST *pgcl;
  216. GLOBALCOMPARTMENT *pgc;
  217. if (!Enter())
  218. return dwRet;
  219. pgcl = (GLOBALCOMPARTMENTLIST *)_psb->GetBase();
  220. if (!pgcl)
  221. {
  222. Assert(0);
  223. return dwRet;
  224. }
  225. pgc = FindProperty(guid);
  226. if (!pgc)
  227. {
  228. if (_ulCommitSize < sizeof(GLOBALCOMPARTMENTLIST) + (pgcl->ulNum * sizeof(DWORD)))
  229. {
  230. _ulCommitSize = sizeof(GLOBALCOMPARTMENTLIST) + (pgcl->ulNum * sizeof(DWORD));
  231. _ulCommitSize += INITIAL_GCOMPART_SIZE;
  232. if (FAILED(_psb->Commit(_ulCommitSize)))
  233. {
  234. Assert(0);
  235. goto Exit;
  236. }
  237. }
  238. pgc = &pgcl->rgGCompart[pgcl->ulNum];
  239. pgc->guid = guid;
  240. pgcl->ulNum++;
  241. }
  242. pgc->gprop.type = pProp->type;
  243. switch (pgc->gprop.type)
  244. {
  245. case TF_PT_DWORD:
  246. pgc->gprop.dw = pProp->dw;
  247. break;
  248. case TF_PT_GUID:
  249. MyGetGUID(pProp->guidatom, &pgc->gprop.guid);
  250. break;
  251. case TF_PT_NONE:
  252. break;
  253. default:
  254. Assert(0);
  255. break;
  256. }
  257. dwRet = CALCID(pgc, pgcl);
  258. Exit:
  259. Leave();
  260. return dwRet;
  261. }
  262. //--------------------------------------------------------------------------
  263. //
  264. // GetProperty
  265. //
  266. //--------------------------------------------------------------------------
  267. BOOL CGCompartList::GetProperty(REFGUID guid, TFPROPERTY *pProp)
  268. {
  269. BOOL bRet = FALSE;
  270. GLOBALCOMPARTMENT *pgc;
  271. if (!Enter())
  272. return bRet;
  273. pgc = FindProperty(guid);
  274. if (!pgc)
  275. {
  276. goto Exit;
  277. }
  278. pProp->type = pgc->gprop.type;
  279. switch (pgc->gprop.type)
  280. {
  281. case TF_PT_DWORD:
  282. pProp->dw = pgc->gprop.dw;
  283. break;
  284. case TF_PT_GUID:
  285. MyRegisterGUID(pgc->gprop.guid, &pProp->guidatom);
  286. break;
  287. case TF_PT_NONE:
  288. break;
  289. default:
  290. Assert(0);
  291. break;
  292. }
  293. bRet = TRUE;
  294. Exit:
  295. Leave();
  296. return bRet;
  297. }
  298. //--------------------------------------------------------------------------
  299. //
  300. // GetId
  301. //
  302. //--------------------------------------------------------------------------
  303. DWORD CGCompartList::GetId(REFGUID guid)
  304. {
  305. DWORD dwRet = (DWORD)(-1);
  306. GLOBALCOMPARTMENTLIST *pgcl;
  307. GLOBALCOMPARTMENT *pgc;
  308. if (!Enter())
  309. return dwRet;
  310. pgcl = (GLOBALCOMPARTMENTLIST *)_psb->GetBase();
  311. pgc = FindProperty(guid);
  312. if (pgc)
  313. {
  314. dwRet = CALCID(pgc, pgcl);
  315. }
  316. Leave();
  317. return dwRet;
  318. }