// // gcompart.cpp // #include "private.h" #include "globals.h" #include "gcompart.h" #include "cregkey.h" #include "thdutil.h" #include "regsvr.h" CGCompartList g_gcomplist; CSharedBlock *CGCompartList::_psb = NULL; ULONG CGCompartList::_ulCommitSize = INITIAL_GCOMPART_SIZE; LONG CGCompartList::_nRef = -1; BOOL CGCompartList::_fCreate = FALSE; ////////////////////////////////////////////////////////////////////////////// // // CGCompartList // ////////////////////////////////////////////////////////////////////////////// //-------------------------------------------------------------------------- // // Init // //-------------------------------------------------------------------------- BOOL CGCompartList::Init(SYSTHREAD *psfn) { static const char c_szGCompartList[] = "MSCTF.GCompartList"; BOOL bRet = FALSE; BOOL bAlreadyExist = FALSE; if (!psfn) return FALSE; Assert(!psfn->fInitGlobalCompartment); CicEnterCriticalSection(g_csInDllMain); if (++_nRef) { bRet = TRUE; goto Exit; } _psb = new CSharedBlockNT(c_szGCompartList, 0, TRUE); if (!_psb) { Assert(0); goto Exit; } HRESULT hr = _psb->Init(NULL, 0x40000, _ulCommitSize, NULL, TRUE, &bAlreadyExist); if (FAILED(hr)) { Assert(0); goto Exit; } if (!bAlreadyExist) { Start(); } bRet = TRUE; Exit: if (!bRet) { _nRef--; if (_psb) delete _psb; _psb = NULL; } CicLeaveCriticalSection(g_csInDllMain); if (bRet) psfn->fInitGlobalCompartment = TRUE; return bRet; } //-------------------------------------------------------------------------- // // Start // //-------------------------------------------------------------------------- BOOL CGCompartList::Start() { GLOBALCOMPARTMENTLIST *pgcl; if (!_psb) { Assert(0); return FALSE; } _fCreate = TRUE; CMyRegKey key; CMyRegKey keyLM; DWORD ulNum = 0; char szSubKey[MAX_PATH]; pgcl = (GLOBALCOMPARTMENTLIST *)_psb->GetBase(); keyLM.Open(HKEY_LOCAL_MACHINE, c_szCompartKey, KEY_READ); if (key.Open(HKEY_CURRENT_USER, c_szCompartKey, KEY_READ) == S_OK) { DWORD dwIndex = 0; while (key.EnumKey(dwIndex, szSubKey, ARRAYSIZE(szSubKey)) == S_OK) { CMyRegKey subkey; CMyRegKey subkeyLM; CLSID clsid; if (!StringAToCLSID(szSubKey, &clsid)) continue; DWORD dwReqSize = ((ulNum + 1) * sizeof(GLOBALCOMPARTMENT)) + sizeof(GLOBALCOMPARTMENTLIST); if (_ulCommitSize < dwReqSize) { dwReqSize *= 2; if (FAILED(_psb->Commit(dwReqSize))) goto Exit; _ulCommitSize = dwReqSize; } if (subkey.Open(key, szSubKey, KEY_READ) == S_OK) { DWORD dwNonInit = 0; if ((HKEY)keyLM && subkeyLM.Open(keyLM, szSubKey, KEY_READ) == S_OK) { if (subkeyLM.QueryValue(dwNonInit, c_szNonInit) != S_OK) dwNonInit = 0; } if (!dwNonInit) { GLOBALCOMPARTMENT *pgc = &pgcl->rgGCompart[ulNum]; DWORD dwCount = sizeof(GLOBALCOMPARTMENT); if (subkey.QueryBinaryValue(pgc, dwCount, c_szGlobalCompartment) == S_OK) ulNum++; } } dwIndex++; } } pgcl->ulNum = ulNum; Exit: return TRUE; } //-------------------------------------------------------------------------- // // UnInit // //-------------------------------------------------------------------------- BOOL CGCompartList::Uninit(SYSTHREAD *psfn) { if (!psfn) return FALSE; if (!_psb) return TRUE; if (_fCreate) { CMyRegKey key; if (key.Create(HKEY_CURRENT_USER, c_szCompartKey) == S_OK) { char szSubKey[MAX_PATH]; ULONG i; GLOBALCOMPARTMENTLIST *pgcl; pgcl = (GLOBALCOMPARTMENTLIST *)_psb->GetBase(); for (i = 0; i < pgcl->ulNum; i++) { GLOBALCOMPARTMENT *pgc = &pgcl->rgGCompart[i]; CMyRegKey subkey; CLSIDToStringA(pgc->guid, szSubKey); if (subkey.Create(key, szSubKey) == S_OK) { subkey.SetBinaryValue(pgc, sizeof(GLOBALCOMPARTMENT), c_szGlobalCompartment); } } } } if (!psfn->fInitGlobalCompartment) return TRUE; CicEnterCriticalSection(g_csInDllMain); if (--_nRef >= 0) goto Exit; if (_psb) delete _psb; _psb = NULL; Exit: CicLeaveCriticalSection(g_csInDllMain); psfn->fInitGlobalCompartment = FALSE; return TRUE; } //-------------------------------------------------------------------------- // // SetProperty // //-------------------------------------------------------------------------- CGCompartList::GLOBALCOMPARTMENT *CGCompartList::FindProperty(REFGUID guid) { GLOBALCOMPARTMENTLIST *pgcl = (GLOBALCOMPARTMENTLIST *)_psb->GetBase(); UINT i; GLOBALCOMPARTMENT *pgc = NULL; if (!pgcl) { Assert(0); return NULL; } for (i = 0; i < pgcl->ulNum; i++) { GLOBALCOMPARTMENT *pgcTemp = &pgcl->rgGCompart[i]; if (IsEqualGUID(pgcTemp->guid, guid)) { pgc = pgcTemp; break; } } return pgc; } //-------------------------------------------------------------------------- // // SetProperty // //-------------------------------------------------------------------------- DWORD CGCompartList::SetProperty(REFGUID guid, TFPROPERTY *pProp) { DWORD dwRet = (DWORD)(-1); GLOBALCOMPARTMENTLIST *pgcl; GLOBALCOMPARTMENT *pgc; if (!Enter()) return dwRet; pgcl = (GLOBALCOMPARTMENTLIST *)_psb->GetBase(); if (!pgcl) { Assert(0); return dwRet; } pgc = FindProperty(guid); if (!pgc) { if (_ulCommitSize < sizeof(GLOBALCOMPARTMENTLIST) + (pgcl->ulNum * sizeof(DWORD))) { _ulCommitSize = sizeof(GLOBALCOMPARTMENTLIST) + (pgcl->ulNum * sizeof(DWORD)); _ulCommitSize += INITIAL_GCOMPART_SIZE; if (FAILED(_psb->Commit(_ulCommitSize))) { Assert(0); goto Exit; } } pgc = &pgcl->rgGCompart[pgcl->ulNum]; pgc->guid = guid; pgcl->ulNum++; } pgc->gprop.type = pProp->type; switch (pgc->gprop.type) { case TF_PT_DWORD: pgc->gprop.dw = pProp->dw; break; case TF_PT_GUID: MyGetGUID(pProp->guidatom, &pgc->gprop.guid); break; case TF_PT_NONE: break; default: Assert(0); break; } dwRet = CALCID(pgc, pgcl); Exit: Leave(); return dwRet; } //-------------------------------------------------------------------------- // // GetProperty // //-------------------------------------------------------------------------- BOOL CGCompartList::GetProperty(REFGUID guid, TFPROPERTY *pProp) { BOOL bRet = FALSE; GLOBALCOMPARTMENT *pgc; if (!Enter()) return bRet; pgc = FindProperty(guid); if (!pgc) { goto Exit; } pProp->type = pgc->gprop.type; switch (pgc->gprop.type) { case TF_PT_DWORD: pProp->dw = pgc->gprop.dw; break; case TF_PT_GUID: MyRegisterGUID(pgc->gprop.guid, &pProp->guidatom); break; case TF_PT_NONE: break; default: Assert(0); break; } bRet = TRUE; Exit: Leave(); return bRet; } //-------------------------------------------------------------------------- // // GetId // //-------------------------------------------------------------------------- DWORD CGCompartList::GetId(REFGUID guid) { DWORD dwRet = (DWORD)(-1); GLOBALCOMPARTMENTLIST *pgcl; GLOBALCOMPARTMENT *pgc; if (!Enter()) return dwRet; pgcl = (GLOBALCOMPARTMENTLIST *)_psb->GetBase(); pgc = FindProperty(guid); if (pgc) { dwRet = CALCID(pgc, pgcl); } Leave(); return dwRet; }