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
400 lines
9.0 KiB
//
|
|
// 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;
|
|
}
|