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.
1321 lines
37 KiB
1321 lines
37 KiB
// File: regzone.cxx
|
|
//
|
|
// Contents: Registry management for a single zone.
|
|
//
|
|
// Classes: CRegZone
|
|
//
|
|
// Functions:
|
|
//
|
|
// History:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "zonepch.h"
|
|
|
|
// Max # of chars to the root of the zones tree (SZZONES, SZTEMPLATE,...)
|
|
|
|
#define MAX_REGZONE_ROOT 100
|
|
|
|
// Value names in the registry
|
|
#define SZZONEINDEX __TEXT("ZoneIndex")
|
|
#define SZTEMPLATEINDEX __TEXT("TemplateIndex")
|
|
#define SZDISPLAYNAME __TEXT("DisplayName")
|
|
#define SZICON __TEXT("Icon")
|
|
#define SZDESCRIPTION __TEXT("Description")
|
|
#define SZFLAGS __TEXT("Flags")
|
|
|
|
// Registry key names for the template policies
|
|
|
|
|
|
#define SZLOW __TEXT("Low")
|
|
#define SZMEDLOW __TEXT("MedLow")
|
|
#define SZMEDIUM __TEXT("Medium")
|
|
#define SZHIGH __TEXT("High")
|
|
|
|
|
|
CRegZone::CRegZoneCache CRegZone::s_rzcache;
|
|
HANDLE CRegZone::CRegZoneCache::s_hMutexCounter;
|
|
|
|
// Array of Value Names corresponding to zone attributes.
|
|
// These values will not be copied when doing a mass copy
|
|
// from a template zone (HIGH, MED, LOW) to a zone.
|
|
static LPCTSTR rgszAttributeNames [ ] =
|
|
{
|
|
__TEXT(""), // The default value is excluded as well.
|
|
SZZONEINDEX,
|
|
SZTEMPLATEINDEX,
|
|
SZDISPLAYNAME,
|
|
SZDESCRIPTION,
|
|
SZICON,
|
|
SZFLAGS,
|
|
SZMINLEVEL,
|
|
SZRECLEVEL,
|
|
SZCURRLEVEL,
|
|
};
|
|
|
|
struct templateNameIdxMap
|
|
{
|
|
URLTEMPLATE index;
|
|
LPCTSTR pszName;
|
|
};
|
|
|
|
static templateNameIdxMap
|
|
TemplateNameIdxMap [ ] =
|
|
{
|
|
{ URLTEMPLATE_LOW, SZLOW },
|
|
{ URLTEMPLATE_MEDLOW, SZMEDLOW},
|
|
{ URLTEMPLATE_MEDIUM, SZMEDIUM},
|
|
{ URLTEMPLATE_HIGH, SZHIGH}
|
|
};
|
|
|
|
|
|
|
|
|
|
// CRegZone implementation.
|
|
|
|
CRegZone::CRegZone()
|
|
{
|
|
// defaults
|
|
m_dwZoneId = ZONEID_INVALID;
|
|
m_dwZoneFlags = ZAFLAGS_ADD_SITES; // BUGBUG: what is the right default here.
|
|
m_lpZoneName = NULL;
|
|
m_lpZonePath = NULL;
|
|
|
|
m_bStandard = TRUE;
|
|
m_bZoneLockOut = FALSE;
|
|
m_bHKLMOnly = TRUE;
|
|
}
|
|
|
|
CRegZone::~CRegZone()
|
|
{
|
|
LocalFree((HLOCAL)m_lpZoneName);
|
|
LocalFree((HLOCAL)m_lpZonePath);
|
|
}
|
|
|
|
// Sets up the CRegZone object a given string.
|
|
// If the setting is in the Zones key the string passed in is the actual
|
|
// zone index. Otherwise it is one of the "High", "Medium", "Low" strings which indicates
|
|
// a template policy.
|
|
|
|
BOOL CRegZone::Init(LPCWSTR lpwStr, BOOL bUseHKLMOnly, REGZONEUSE regZoneUse, BOOL bCreate /*=TRUE*/)
|
|
{
|
|
TransAssert(lpwStr != NULL);
|
|
if (lpwStr == NULL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
m_bHKLMOnly = bUseHKLMOnly;
|
|
m_regZoneUse = regZoneUse;
|
|
|
|
TCHAR szTemp[MAX_REGZONE_ROOT + MAX_ZONE_NAME];
|
|
|
|
StrCpyW(szTemp, (regZoneUse == REGZONEUSEZONES? SZZONES : SZTEMPLATE));
|
|
StrCatW(szTemp, lpwStr);
|
|
|
|
m_lpZonePath = StrDup(szTemp);
|
|
if(!m_lpZonePath)
|
|
{
|
|
return FALSE;
|
|
}
|
|
m_lpZoneName = StrDup(lpwStr);
|
|
if(!m_lpZoneName)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
CRegKey regKey(bUseHKLMOnly);
|
|
|
|
if (regKey.Open(NULL, m_lpZonePath, KEY_READ) != ERROR_SUCCESS)
|
|
{
|
|
// BUGBUG:: We have to be able to deal with this. situation and not just bail.
|
|
// Possibilities: Setup defaults here if we can create and write to the key
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
// Add code here to
|
|
DWORD dwZoneId = ZONEID_INVALID;
|
|
|
|
// Get the Zone Index.
|
|
if ( regZoneUse == REGZONEUSEZONES )
|
|
{
|
|
// The Zone Id for the string is the same as the key name.
|
|
// Just convert the string
|
|
m_dwZoneId = StrToInt(m_lpZoneName);
|
|
}
|
|
else if (regZoneUse == REGZONEUSETEMPLATE )
|
|
{
|
|
if (regKey.QueryValue(&dwZoneId, SZTEMPLATEINDEX) == ERROR_SUCCESS)
|
|
m_dwZoneId = dwZoneId;
|
|
else
|
|
{
|
|
// Could happen if the registry is messed up.
|
|
TransAssert(FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TransAssert(FALSE);
|
|
}
|
|
|
|
// Get the zone flags
|
|
if (regKey.QueryValue(&m_dwZoneFlags, SZFLAGS) != ERROR_SUCCESS)
|
|
{
|
|
m_dwZoneFlags = ZAFLAGS_ADD_SITES; // What is the right value here.
|
|
}
|
|
else
|
|
{
|
|
// return value from UpdateZoneMapFlags ignored.
|
|
UpdateZoneMapFlags( );
|
|
}
|
|
// Check and make sure the zone Id's are within range.
|
|
// Assert that the zone ID's are in the appropriate user or standard range.
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// This updates the flags in the ZoneMap part of the registry which correspond to the
|
|
// ZAFLAGS_. For convenience the UI will only update the ZAFLAGS.
|
|
|
|
|
|
BOOL CRegZone::UpdateZoneMapFlags( )
|
|
{
|
|
// ProxyByPass is current controlled by the ProxyByPass flag, not the zoneAttrib.
|
|
if (m_dwZoneId == URLZONE_INTRANET)
|
|
{
|
|
// If we are updating zonemap flags we have to invalidate any url to zone caches
|
|
CSecurityManager::IncrementGlobalCounter( );
|
|
|
|
CRegKey regZoneMap;
|
|
if (ERROR_SUCCESS == regZoneMap.Open(NULL, SZZONEMAP, KEY_READ | KEY_WRITE))
|
|
{
|
|
if (m_dwZoneFlags & ZAFLAGS_INCLUDE_PROXY_OVERRIDE)
|
|
{
|
|
// We will succeed even if this fails.
|
|
regZoneMap.SetValue(m_dwZoneId, SZPROXYBYPASS);
|
|
}
|
|
else
|
|
{
|
|
regZoneMap.DeleteValue(SZPROXYBYPASS);
|
|
}
|
|
|
|
if (m_dwZoneFlags & ZAFLAGS_INCLUDE_INTRANET_SITES)
|
|
{
|
|
// We will succeed even if this fails.
|
|
regZoneMap.SetValue(m_dwZoneId, SZINTRANETNAME);
|
|
}
|
|
else
|
|
{
|
|
regZoneMap.DeleteValue(SZINTRANETNAME);
|
|
}
|
|
|
|
DWORD dwUncAsIntranet = (m_dwZoneFlags & ZAFLAGS_UNC_AS_INTRANET) ? 1 : 0 ;
|
|
regZoneMap.SetValue(dwUncAsIntranet, SZUNCASINTRANET);
|
|
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
// Static functions.
|
|
|
|
VOID
|
|
CRegZone::IncrementGlobalCounter( )
|
|
{
|
|
CRegZone::CRegZoneCache::IncrementGlobalCounter( );
|
|
}
|
|
|
|
BOOL CRegZone::IsAttributeName(LPCTSTR psz)
|
|
{
|
|
DWORD dwMaxIndex = sizeof(rgszAttributeNames)/sizeof(rgszAttributeNames[0]);
|
|
|
|
for ( DWORD dwIndex = 0 ; dwIndex < dwMaxIndex ; dwIndex++ )
|
|
{
|
|
#ifndef UNIX
|
|
if (0 == StrCmpW(psz, rgszAttributeNames[dwIndex]))
|
|
#else
|
|
if (0 == lstrcmpi(psz, rgszAttributeNames[dwIndex]))
|
|
#endif
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
LPCTSTR CRegZone::GetTemplateNameFromIndex(URLTEMPLATE urlTemplateIndex)
|
|
{
|
|
DWORD dwMaxIndex = sizeof(TemplateNameIdxMap) / sizeof(TemplateNameIdxMap[0]);
|
|
|
|
for (DWORD dwIndex = 0 ; dwIndex < dwMaxIndex ; dwIndex++ )
|
|
{
|
|
if (TemplateNameIdxMap[dwIndex].index == urlTemplateIndex)
|
|
return TemplateNameIdxMap[dwIndex].pszName;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
// These are static functions to deal with aggregate policies.
|
|
|
|
// Because of the discrepancy between the UI and the actions defined,
|
|
// there are cases where the security manager munges the policies for certain actions.
|
|
|
|
inline void CRegZone::KludgeMapAggregatePolicy(DWORD dwAction, LPDWORD pdwPolicy)
|
|
{
|
|
TransAssert(pdwPolicy != NULL);
|
|
|
|
switch (dwAction)
|
|
{
|
|
case URLACTION_ACTIVEX_OVERRIDE_DATA_SAFETY:
|
|
case URLACTION_ACTIVEX_OVERRIDE_SCRIPT_SAFETY:
|
|
case URLACTION_SCRIPT_OVERRIDE_SAFETY:
|
|
{
|
|
if (GetUrlPolicyPermissions(*pdwPolicy) == URLPOLICY_QUERY)
|
|
SetUrlPolicyPermissions(*pdwPolicy, URLPOLICY_DISALLOW);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Call this function to determine if an action is aggregated by some
|
|
// other action.
|
|
// RETURNS : TRUE if there is an aggregate action corr to dwAction.
|
|
// also returns the action in pdwAggregate.
|
|
// FALSE: if this action is not aggregated by some other action.
|
|
// pdwAggregate is unchanged in this case.
|
|
|
|
inline BOOL CRegZone::GetAggregateAction(DWORD dwAction, LPDWORD pdwAggregate)
|
|
{
|
|
DWORD dwAggregate = 0;
|
|
BOOL bReturn = FALSE;
|
|
|
|
TransAssert(dwAction >= URLACTION_MIN);
|
|
|
|
switch(dwAction)
|
|
{
|
|
case URLACTION_ACTIVEX_OVERRIDE_DATA_SAFETY:
|
|
case URLACTION_ACTIVEX_OVERRIDE_SCRIPT_SAFETY:
|
|
case URLACTION_ACTIVEX_CONFIRM_NOOBJECTSAFETY:
|
|
case URLACTION_SCRIPT_OVERRIDE_SAFETY:
|
|
bReturn = TRUE;
|
|
dwAggregate = URLACTION_ACTIVEX_OVERRIDE_OBJECT_SAFETY;
|
|
break;
|
|
case URLACTION_HTML_SUBMIT_FORMS_FROM:
|
|
case URLACTION_HTML_SUBMIT_FORMS_TO:
|
|
bReturn = TRUE;
|
|
dwAggregate = URLACTION_HTML_SUBMIT_FORMS;
|
|
break;
|
|
}
|
|
|
|
if (bReturn && pdwAggregate)
|
|
*pdwAggregate = dwAggregate;
|
|
|
|
return bReturn;
|
|
}
|
|
|
|
|
|
// Functions corresponding to IInternetZoneManager functionality.
|
|
STDMETHODIMP CRegZone::GetZoneAttributes(ZONEATTRIBUTES& zoneAttrib)
|
|
{
|
|
if (!IsValid())
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
CRegKey regKey(m_bHKLMOnly);
|
|
|
|
if (regKey.Open(NULL, m_lpZonePath, KEY_READ) != ERROR_SUCCESS)
|
|
{
|
|
// BUGBUG:: We have to be able to deal with this. situation and not just bail.
|
|
// Possibilities: Setup defaults here if we can create and write to the key
|
|
return E_FAIL;
|
|
}
|
|
|
|
// Since this is the first rev, we should have enough memory
|
|
// to fill in the ZONEATTRIBUTES structure. If we need to extend
|
|
// the structure this code will have to be modified.
|
|
TransAssert(zoneAttrib.cbSize >= sizeof(ZONEATTRIBUTES));
|
|
|
|
// Amount of information we will copy.
|
|
zoneAttrib.cbSize = sizeof(ZONEATTRIBUTES);
|
|
|
|
TransAssert(regKey!= NULL);
|
|
|
|
DWORD dwCount;
|
|
LONG lRet;
|
|
|
|
// BUGBUG deal with values exceeding size limit.
|
|
// We would have to allocate memory ourself and
|
|
// truncate the resulting string down.
|
|
|
|
// Read DisplayName.
|
|
dwCount = sizeof(zoneAttrib.szDisplayName);
|
|
lRet = regKey.QueryValue(zoneAttrib.szDisplayName, SZDISPLAYNAME, &dwCount);
|
|
TransAssert(ERROR_MORE_DATA != lRet);
|
|
|
|
if (NO_ERROR != lRet)
|
|
zoneAttrib.szDisplayName[0] = __TEXT('\0');
|
|
|
|
// Read Description
|
|
dwCount = sizeof(zoneAttrib.szDescription);
|
|
regKey.QueryValue(zoneAttrib.szDescription, SZDESCRIPTION, &dwCount);
|
|
TransAssert(ERROR_MORE_DATA != lRet);
|
|
|
|
if (NO_ERROR != lRet)
|
|
zoneAttrib.szDescription[0] = __TEXT('\0');
|
|
|
|
// Read Icon.
|
|
dwCount = sizeof(zoneAttrib.szIconPath);
|
|
regKey.QueryValue(zoneAttrib.szIconPath, SZICON, &dwCount);
|
|
TransAssert(ERROR_MORE_DATA != lRet);
|
|
|
|
if (NO_ERROR != lRet)
|
|
zoneAttrib.szIconPath[0] = __TEXT('\0');
|
|
|
|
// Read Current, Recommended and Min Settings.
|
|
QueryTemplatePolicyIndex(regKey, SZMINLEVEL, &zoneAttrib.dwTemplateMinLevel);
|
|
QueryTemplatePolicyIndex(regKey, SZRECLEVEL, &zoneAttrib.dwTemplateRecommended);
|
|
QueryTemplatePolicyIndex(regKey, SZCURRLEVEL, &zoneAttrib.dwTemplateCurrentLevel);
|
|
|
|
// Re-read the flags in case someone else updated it in an independent process.
|
|
DWORD dwZoneFlags;
|
|
if (regKey.QueryValue(&dwZoneFlags, SZFLAGS) == ERROR_SUCCESS)
|
|
{
|
|
m_dwZoneFlags = dwZoneFlags;
|
|
UpdateZoneMapFlags();
|
|
}
|
|
|
|
zoneAttrib.dwFlags = m_dwZoneFlags;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CRegZone::SetZoneAttributes(const ZONEATTRIBUTES& zoneAttrib)
|
|
{
|
|
if (!IsValid())
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
// Check if the attributes we are trying to set are valid.
|
|
|
|
if (!IsValidTemplateIndex(zoneAttrib.dwTemplateMinLevel) ||
|
|
!IsValidTemplateIndex(zoneAttrib.dwTemplateCurrentLevel) ||
|
|
!IsValidTemplateIndex(zoneAttrib.dwTemplateRecommended))
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
CRegKey regKey(m_bHKLMOnly);
|
|
|
|
if (regKey.Open(NULL, m_lpZonePath, KEY_WRITE | KEY_READ) != ERROR_SUCCESS)
|
|
{
|
|
// BUGBUG:: We have to be able to deal with this. situation and not just bail.
|
|
// Possibilities: Setup defaults here if we can create and write to the key
|
|
return E_FAIL;
|
|
}
|
|
|
|
|
|
// Write the descriptive strings.
|
|
// These should almost never be changed by this call.
|
|
if (zoneAttrib.szDisplayName[0] != TEXT('\0'))
|
|
regKey.SetValue(zoneAttrib.szDisplayName, SZDISPLAYNAME);
|
|
|
|
if (zoneAttrib.szDescription[0] != TEXT('\0'))
|
|
regKey.SetValue(zoneAttrib.szDescription, SZDESCRIPTION);
|
|
|
|
if (zoneAttrib.szIconPath[0] != TEXT('\0'))
|
|
regKey.SetValue(zoneAttrib.szIconPath, SZICON);
|
|
|
|
// Write the Template Indicies.
|
|
SetTemplatePolicyIndex(regKey, SZMINLEVEL, zoneAttrib.dwTemplateMinLevel);
|
|
SetTemplatePolicyIndex(regKey, SZRECLEVEL, zoneAttrib.dwTemplateRecommended);
|
|
|
|
DWORD dwTemplateCurrentLevel;
|
|
|
|
// When the caller is setting the "CurrentLevel" to "Custom" it is assumed
|
|
// that the caller has already changed the underlying policies.
|
|
if (zoneAttrib.dwTemplateCurrentLevel == URLTEMPLATE_CUSTOM)
|
|
{
|
|
SetTemplatePolicyIndex(regKey, SZCURRLEVEL, zoneAttrib.dwTemplateCurrentLevel);
|
|
}
|
|
else
|
|
{
|
|
CopyTemplatePolicies(zoneAttrib.dwTemplateCurrentLevel);
|
|
}
|
|
|
|
|
|
// Finally write the flags value.
|
|
regKey.SetValue(zoneAttrib.dwFlags, SZFLAGS);
|
|
m_dwZoneFlags = zoneAttrib.dwFlags;
|
|
UpdateZoneMapFlags();
|
|
|
|
IncrementGlobalCounter(); // increment the count to invalidate the zone policy cache
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CRegZone::GetActionPolicy(DWORD dwAction, URLZONEREG urlZoneReg, DWORD& dwPolicy) const
|
|
{
|
|
if (!IsValid())
|
|
return E_FAIL;
|
|
|
|
DWORD dwActionUse;
|
|
|
|
// If the action is aggregated by some other action, then we should
|
|
// actually check the policy for the aggregate action. If the function
|
|
if (!GetAggregateAction(dwAction, &dwActionUse))
|
|
dwActionUse = dwAction;
|
|
|
|
// If it is a hard-coded zone get the policy from internal tables.
|
|
// Don't look up the registry for these.
|
|
if (IsHardCodedZone() && GetHardCodedZonePolicy(dwActionUse, dwPolicy))
|
|
{
|
|
// dwPolicy should have the policy now.
|
|
}
|
|
else
|
|
{
|
|
if(!s_rzcache.Lookup(m_dwZoneId, m_lpZonePath, dwActionUse, UseHKLM(urlZoneReg), &dwPolicy))
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
// For some special aggregate policies we have to modify the policy value.
|
|
KludgeMapAggregatePolicy(dwAction, &dwPolicy);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CRegZone::SetActionPolicy(DWORD dwAction, URLZONEREG urlZoneReg, DWORD dwPolicy)
|
|
{
|
|
if (!IsValid())
|
|
return E_FAIL;
|
|
|
|
CRegKey regKey(UseHKLM(urlZoneReg));
|
|
|
|
if (regKey.Open(NULL, m_lpZonePath, KEY_WRITE) != ERROR_SUCCESS)
|
|
{
|
|
// BUGBUG:: We have to be able to deal with this. situation and not just bail.
|
|
// Possibilities: Setup defaults here if we can create and write to the key
|
|
return E_FAIL;
|
|
}
|
|
|
|
// Policies cannot be set on Actions that are aggregate's.
|
|
// They can be only be set on the aggregator policy.
|
|
|
|
if (IsHardCodedZone())
|
|
{
|
|
TransAssert(FALSE);
|
|
return E_FAIL;
|
|
}
|
|
|
|
DWORD dwActionUse;
|
|
|
|
// If the action is aggregated by some other action, then we should
|
|
// actually use the policy for the aggregate action.
|
|
if (!GetAggregateAction(dwAction, &dwActionUse))
|
|
dwActionUse = dwAction;
|
|
|
|
// Convert the Action to a string.
|
|
#ifndef unix
|
|
TCHAR wsz[9]; // FFFFFFFF\0
|
|
#else
|
|
TCHAR wsz[(sizeof(DWORD)+1)*sizeof(WCHAR)];
|
|
#endif /* unix */
|
|
if (!DwToWchar(dwActionUse, wsz, 16))
|
|
{
|
|
TransAssert(FALSE);
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
DWORD dwPolicyOld;
|
|
if(!s_rzcache.Lookup(m_dwZoneId, m_lpZonePath, dwActionUse, UseHKLM(urlZoneReg), &dwPolicyOld) || dwPolicyOld != dwPolicy)
|
|
{
|
|
regKey.SetValue(dwPolicy, wsz);
|
|
|
|
s_rzcache.Add(m_dwZoneId, dwActionUse, UseHKLM(urlZoneReg), dwPolicy, URLZONE_FINDCACHEENTRY);
|
|
// We have to reset the "CurrentLevel" to "Custom" because we have changed an underlying policy:
|
|
SetTemplatePolicyIndex(regKey, SZCURRLEVEL, URLTEMPLATE_CUSTOM);
|
|
}
|
|
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CRegZone::GetCustomPolicy (REFGUID guid, URLZONEREG urlZoneReg, BYTE** ppByte, DWORD *pcb) const
|
|
{
|
|
if (!IsValid())
|
|
return E_FAIL;
|
|
|
|
|
|
CRegKey regKey(UseHKLM(urlZoneReg));
|
|
|
|
if (regKey.Open(NULL, m_lpZonePath, KEY_READ) != ERROR_SUCCESS)
|
|
{
|
|
// BUGBUG:: We have to be able to deal with this. situation and not just bail.
|
|
// Possibilities: Setup defaults here if we can create and write to the key
|
|
return E_FAIL;
|
|
}
|
|
|
|
// Convert the Action to a string.
|
|
TCHAR sz[40]; // {8CC49940-3146-11CF-97A1-00AA00424A9F}\0
|
|
|
|
SHStringFromGUID(guid, sz, sizeof(sz));
|
|
|
|
*pcb = 0;
|
|
// First figure out the amount of memory required.
|
|
if (regKey.QueryBinaryValue(NULL, sz, pcb) != ERROR_SUCCESS)
|
|
{
|
|
return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
|
|
}
|
|
|
|
// Memory will be freed by caller.
|
|
*ppByte = (BYTE *)CoTaskMemAlloc(*pcb);
|
|
|
|
if ( *ppByte == NULL)
|
|
{
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
// Actually query the registry for the value.
|
|
if (regKey.QueryBinaryValue(*ppByte, sz, pcb) != ERROR_SUCCESS)
|
|
{
|
|
return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CRegZone::SetCustomPolicy (REFGUID guid, URLZONEREG urlZoneReg, BYTE* pByte, DWORD cb)
|
|
{
|
|
if (!IsValid())
|
|
return E_FAIL;
|
|
|
|
CRegKey regKey(UseHKLM(urlZoneReg));
|
|
|
|
if (regKey.Open(NULL, m_lpZonePath, KEY_WRITE) != ERROR_SUCCESS)
|
|
{
|
|
// BUGBUG:: We have to be able to deal with this. situation and not just bail.
|
|
// Possibilities: Setup defaults here if we can create and write to the key
|
|
return E_FAIL;
|
|
}
|
|
|
|
// Convert the Action to a string.
|
|
TCHAR sz[40]; // {8CC49940-3146-11CF-97A1-00AA00424A9F}\0
|
|
|
|
SHStringFromGUID(guid, sz, sizeof(sz));
|
|
|
|
DWORD dwError = ERROR_SUCCESS;
|
|
if ((dwError = regKey.SetBinaryValue(pByte, sz, cb)) != ERROR_SUCCESS)
|
|
{
|
|
return HRESULT_FROM_WIN32(dwError);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CRegZone::CopyTemplatePolicies(DWORD dwTemplate)
|
|
// Copy the policies from a predefined template into the current zone
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
// First check if we can get a name back for the template.
|
|
LPCTSTR szTemplateName = GetTemplateNameFromIndex((URLTEMPLATE)dwTemplate);
|
|
|
|
if (NULL == szTemplateName )
|
|
return E_INVALIDARG;
|
|
|
|
// Create a CRegZone for the template.
|
|
CRegZone regTemplate;
|
|
|
|
|
|
if (regTemplate.Init(szTemplateName, TRUE /* templates are stored in HKLM only */, REGZONEUSETEMPLATE))
|
|
{
|
|
CRegKey regZoneKey(m_bHKLMOnly);
|
|
CRegKey regTemplateKey(TRUE);
|
|
|
|
if ((NO_ERROR == regTemplateKey.Open(NULL, regTemplate.m_lpZonePath, KEY_READ)) &&
|
|
(NO_ERROR == regZoneKey.Open(NULL, m_lpZonePath, KEY_WRITE)))
|
|
{
|
|
TCHAR szValueName[MAX_VALUE_NAME];
|
|
DWORD dwNameLen = sizeof(szValueName)/sizeof(TCHAR);
|
|
DWORD dwBufLen = 2048;
|
|
DWORD dwActualLen = 2048;
|
|
BYTE * buffer = new BYTE[dwBufLen];
|
|
DWORD dwEnumIndex = 0;
|
|
DWORD dwType;
|
|
LONG lRet;
|
|
|
|
while ((lRet = regTemplateKey.EnumValue (dwEnumIndex, szValueName, &dwNameLen, &dwType, buffer, &dwActualLen))
|
|
!= ERROR_NO_MORE_ITEMS)
|
|
{
|
|
// Need more memory, allocate and re-try.
|
|
if (lRet == ERROR_MORE_DATA && dwActualLen > dwBufLen)
|
|
{
|
|
dwBufLen = dwActualLen;
|
|
delete [] buffer;
|
|
buffer = new BYTE[dwBufLen];
|
|
|
|
dwNameLen = sizeof(szValueName)/sizeof(TCHAR);
|
|
|
|
// Try with the bigger buffer.
|
|
lRet = regTemplateKey.EnumValue(dwEnumIndex, szValueName, &dwNameLen, &dwType, buffer, &dwActualLen);
|
|
}
|
|
|
|
// dwActualLen contains the actual size of the data to be written.
|
|
if (lRet == NO_ERROR && !IsAttributeName(szValueName))
|
|
{
|
|
// Copy the value over.
|
|
regZoneKey.SetValueOfType(buffer, szValueName, dwActualLen, dwType);
|
|
}
|
|
|
|
dwEnumIndex++;
|
|
dwActualLen = dwBufLen;
|
|
dwNameLen = sizeof(szValueName)/sizeof(TCHAR);
|
|
}
|
|
|
|
// Set the "CurrentLevel" value to the Template Index.
|
|
if (regZoneKey.SetValue(dwTemplate, SZCURRLEVEL) == NO_ERROR)
|
|
hr = S_OK;
|
|
|
|
delete [] buffer;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
// CRegZoneContainer methods.
|
|
|
|
|
|
CRegZoneContainer::CRegZoneContainer()
|
|
{
|
|
m_ppRegZones = NULL;
|
|
m_cZones = 0;
|
|
m_bHKLMOnly = FALSE;
|
|
|
|
m_pZoneEnumList = NULL;
|
|
m_dwNextEnum = 0;
|
|
InitializeCriticalSection(&m_csect);
|
|
}
|
|
|
|
CRegZoneContainer::~CRegZoneContainer()
|
|
{
|
|
Detach();
|
|
DeleteCriticalSection(&m_csect);
|
|
};
|
|
|
|
// This functions goes through the registry and creates the CRegZone objects corresponding
|
|
// to the zones currently in the registry.
|
|
|
|
|
|
BOOL CRegZoneContainer::Attach(BOOL bUseHKLM, REGZONEUSE regZoneUse /* = REGZONEUSEZONES */)
|
|
{
|
|
// If this assert fires you probably forgot to call Detach.
|
|
TransAssert(m_cZones == 0);
|
|
TransAssert(m_ppRegZones == NULL);
|
|
// recover if we are messed up.
|
|
Detach();
|
|
|
|
m_bHKLMOnly = bUseHKLM ;
|
|
|
|
|
|
TCHAR sz[MAX_REGZONE_ROOT];
|
|
StrCpyW(sz, (regZoneUse == REGZONEUSEZONES ? SZZONES : SZTEMPLATE ));
|
|
|
|
// Make sure we have the minimal set of zones required and we self-heal if there is a problem.
|
|
// even if self-heal fails we ignore the error code and try to initialize the zones anyway.
|
|
if (regZoneUse == REGZONEUSEZONES )
|
|
SelfHeal(bUseHKLM);
|
|
|
|
|
|
CRegKey regKey(m_bHKLMOnly);
|
|
|
|
if (regKey.Open(NULL, sz, KEY_READ) != ERROR_SUCCESS)
|
|
{
|
|
// Hosed setup right defaults here.
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
TransAssert(regKey.m_hKey != NULL);
|
|
|
|
// For each entry in the registry
|
|
DWORD dwIndex = 0;
|
|
DWORD dwCount = 0;
|
|
DWORD lRes;
|
|
TCHAR szZoneName[MAX_ZONE_NAME];
|
|
DWORD dwSize = MAX_ZONE_NAME;
|
|
|
|
CRegListElem *pElemStart = NULL;
|
|
|
|
for (; (lRes = regKey.EnumKey(dwIndex, szZoneName, &dwSize)) != ERROR_NO_MORE_ITEMS; dwIndex++)
|
|
{
|
|
if (lRes != ERROR_SUCCESS)
|
|
{
|
|
break;
|
|
}
|
|
|
|
dwSize = MAX_ZONE_NAME;
|
|
|
|
CRegZone *pRegZone = new CRegZone();
|
|
|
|
if (pRegZone == NULL)
|
|
{
|
|
m_cZones = 0;
|
|
// Out of memory -- change all error codes to return HRESULT's
|
|
break;
|
|
}
|
|
|
|
if (!pRegZone->Init(szZoneName, m_bHKLMOnly))
|
|
{
|
|
continue; // can't create the zone for some reason.
|
|
}
|
|
|
|
m_cZones++;
|
|
|
|
CRegListElem * pRegListElem = new CRegListElem();
|
|
if ( pRegListElem == NULL)
|
|
{
|
|
m_cZones = 0;
|
|
break; // Out of memory.
|
|
}
|
|
|
|
pRegListElem->pRegZone = pRegZone;
|
|
pRegListElem->dwZoneIndex = pRegZone->GetZoneId();
|
|
|
|
// Insert list into sorted position.
|
|
if (pElemStart == NULL)
|
|
{
|
|
pElemStart = pRegListElem;
|
|
pRegListElem->next = NULL;
|
|
}
|
|
else if (pElemStart->dwZoneIndex > pRegListElem->dwZoneIndex)
|
|
{
|
|
// Insert to the head of the list.
|
|
pRegListElem->next = pElemStart;
|
|
pElemStart = pRegListElem;
|
|
}
|
|
else
|
|
{
|
|
// Insert in the correct position.
|
|
CRegListElem *pElemCurr = pElemStart;
|
|
|
|
while (pElemCurr->next != NULL &&
|
|
pElemCurr->next->dwZoneIndex < pRegListElem->dwZoneIndex )
|
|
{
|
|
pElemCurr = pElemCurr->next;
|
|
}
|
|
|
|
TransAssert(pElemCurr != NULL);
|
|
pRegListElem->next = pElemCurr->next;
|
|
pElemCurr->next = pRegListElem;
|
|
}
|
|
}
|
|
|
|
// Now that we have all the RegZones collected we will just store them in
|
|
// sorted order in an array.
|
|
|
|
if (m_cZones)
|
|
m_ppRegZones = new LPREGZONE[m_cZones];
|
|
else
|
|
m_ppRegZones = NULL;
|
|
|
|
if (m_ppRegZones == NULL)
|
|
{
|
|
// Out of memory
|
|
m_cZones = 0;
|
|
return FALSE;
|
|
}
|
|
|
|
for (dwIndex = 0; dwIndex < m_cZones ; dwIndex++)
|
|
{
|
|
TransAssert(pElemStart != NULL);
|
|
|
|
m_ppRegZones[dwIndex] = pElemStart->pRegZone;
|
|
CRegListElem * pElemDelete = pElemStart;
|
|
pElemStart = pElemStart->next;
|
|
delete pElemDelete;
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
BOOL CRegZoneContainer::Detach()
|
|
{
|
|
// First free all the CRegZone entries we are holding on to.
|
|
DWORD dwIndex = 0;
|
|
|
|
for (; dwIndex < m_cZones; dwIndex++)
|
|
{
|
|
delete m_ppRegZones[dwIndex];
|
|
}
|
|
|
|
delete [] m_ppRegZones;
|
|
m_ppRegZones = NULL;
|
|
m_cZones = 0;
|
|
m_bHKLMOnly = TRUE;
|
|
|
|
// Zone enumerator cleanup.
|
|
// This ASSERT will fire if you forget to call DestroyZoneEnumerator before
|
|
// freeing the object.
|
|
TransAssert(m_pZoneEnumList == NULL);
|
|
CZoneEnumList * pNextEnum = m_pZoneEnumList;
|
|
while (pNextEnum != NULL)
|
|
{
|
|
CZoneEnumList * pEnumListDelete = pNextEnum;
|
|
pNextEnum = pNextEnum->next;
|
|
delete pEnumListDelete;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// This function makes sure that the minimal set of zones are in the registry If things are missing
|
|
// it calls the self-registration entry point and re-creates the zone key.
|
|
|
|
#define WIN2KSETUP TEXT("System\\Setup")
|
|
#define INPROGRESS TEXT("SystemSetupInProgress")
|
|
|
|
BOOL CRegZoneContainer::SelfHeal(BOOL bUseHKLM)
|
|
{
|
|
|
|
HKEY hKeyZones = NULL;
|
|
|
|
if (IsInGUIModeSetup())
|
|
{
|
|
// ignore SelfHeal if we're in GUI-mode setup
|
|
return TRUE;
|
|
}
|
|
|
|
if (RegOpenKeyEx((bUseHKLM ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER), SZZONES, 0, KEY_READ, &hKeyZones)
|
|
== ERROR_SUCCESS)
|
|
{
|
|
|
|
// Strings corresponding to the five pre-defined zones.
|
|
TCHAR * rgszZones[] = { TEXT("0"), TEXT("1"), TEXT("2"), TEXT("3"), TEXT("4") };
|
|
|
|
int i;
|
|
for (i = 0 ; i < ARRAYSIZE(rgszZones) ; i++ )
|
|
{
|
|
HKEY hKey;
|
|
|
|
DWORD dwError = RegOpenKeyEx(hKeyZones, rgszZones[i], 0, KEY_READ, &hKey);
|
|
|
|
if (dwError != ERROR_SUCCESS)
|
|
break;
|
|
else
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
RegCloseKey(hKeyZones);
|
|
|
|
// If we succesfully opened all the zones.
|
|
if (i == ARRAYSIZE(rgszZones))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// If we reached here we were not able to open atleast one of the keys.
|
|
// Note that we use L"" because ZonesDllInstall takes a LPCWSTR
|
|
BOOL bRet;
|
|
HRESULT hr = ZonesDllInstall(TRUE, bUseHKLM ? L"HKLM" : L"HKCU");
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CRegKey regKey(bUseHKLM);
|
|
|
|
// Keep track of how many times we self heal for diagnostic purposes..
|
|
DWORD dwSelfHealCount;
|
|
TCHAR *pszSelfHealCount = TEXT("SelfHealCount");
|
|
|
|
if (regKey.Open(NULL, SZZONES, KEY_READ | KEY_WRITE) == ERROR_SUCCESS)
|
|
{
|
|
if (regKey.QueryValue(&dwSelfHealCount, pszSelfHealCount) != ERROR_SUCCESS)
|
|
dwSelfHealCount = 0;
|
|
|
|
dwSelfHealCount++;
|
|
regKey.SetValue(dwSelfHealCount, pszSelfHealCount);
|
|
}
|
|
|
|
bRet = TRUE;
|
|
}
|
|
else
|
|
bRet = FALSE;
|
|
|
|
return bRet;
|
|
}
|
|
|
|
CRegZone * CRegZoneContainer::GetRegZoneByName(LPCTSTR lpName) const
|
|
{
|
|
DWORD dwIndex = 0;
|
|
CRegZone *pRegZone = NULL;
|
|
|
|
for ( ; dwIndex < m_cZones; dwIndex++ )
|
|
{
|
|
pRegZone = m_ppRegZones[dwIndex] ;
|
|
|
|
if (pRegZone && StrCmpIW(pRegZone->GetZoneName(), lpName) == 0)
|
|
break;
|
|
}
|
|
|
|
return pRegZone;
|
|
}
|
|
|
|
CRegZone * CRegZoneContainer::GetRegZoneById(DWORD dwZoneId) const
|
|
{
|
|
DWORD dwIndex = 0;
|
|
CRegZone * pReturnZone = NULL;
|
|
|
|
for (; dwIndex < m_cZones ; dwIndex++ )
|
|
{
|
|
CRegZone * pRegZone = m_ppRegZones[dwIndex];
|
|
|
|
|
|
if (pRegZone == NULL)
|
|
{
|
|
// This shouldn't happen but a safety check doesn't hurt.
|
|
break;
|
|
}
|
|
else if (pRegZone->GetZoneId() == dwZoneId)
|
|
{
|
|
pReturnZone = pRegZone;
|
|
break; // Got it
|
|
}
|
|
else if (pRegZone->GetZoneId() > dwZoneId)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
return pReturnZone;
|
|
}
|
|
|
|
// Zone Enumeration functions.
|
|
BOOL CRegZoneContainer::VerifyZoneEnum(DWORD dwEnum ) const
|
|
{
|
|
BOOL bFound = FALSE;
|
|
|
|
CZoneEnumList *pNext = m_pZoneEnumList;
|
|
while (pNext)
|
|
{
|
|
if (pNext->dwEnum == dwEnum)
|
|
{
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
|
|
pNext = pNext->next;
|
|
}
|
|
|
|
return bFound;
|
|
}
|
|
|
|
|
|
|
|
STDMETHODIMP CRegZoneContainer::CreateZoneEnumerator(DWORD* pdwEnum, DWORD *pdwCount)
|
|
{
|
|
if (pdwEnum == NULL || pdwCount == NULL)
|
|
return E_INVALIDARG;
|
|
|
|
if (m_cZones == 0)
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
CZoneEnumList *pEnumListElem = new CZoneEnumList;
|
|
if (pEnumListElem == NULL)
|
|
return E_OUTOFMEMORY;
|
|
|
|
pEnumListElem->dwEnum = m_dwNextEnum++;
|
|
|
|
EnterCriticalSection(&m_csect);
|
|
|
|
if (m_pZoneEnumList == NULL)
|
|
{
|
|
pEnumListElem->next = NULL;
|
|
m_pZoneEnumList = pEnumListElem;
|
|
}
|
|
else
|
|
{
|
|
pEnumListElem->next = m_pZoneEnumList;
|
|
m_pZoneEnumList = pEnumListElem;
|
|
}
|
|
|
|
*pdwEnum = m_pZoneEnumList->dwEnum;
|
|
*pdwCount = m_cZones;
|
|
|
|
TransAssert(VerifyZoneEnum(*pdwEnum));
|
|
|
|
LeaveCriticalSection(&m_csect);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CRegZoneContainer::GetZoneAt(DWORD dwEnum, DWORD dwIndex, DWORD *pdwZone)
|
|
{
|
|
if (!VerifyZoneEnum(dwEnum) || dwIndex >= m_cZones)
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
if (m_ppRegZones && m_ppRegZones[dwIndex])
|
|
{
|
|
*pdwZone = m_ppRegZones[dwIndex]->GetZoneId();
|
|
return S_OK;
|
|
}
|
|
else
|
|
{
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
|
|
STDMETHODIMP CRegZoneContainer::DestroyZoneEnumerator(DWORD dwEnum)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CZoneEnumList *pDelete = NULL;
|
|
|
|
EnterCriticalSection(&m_csect);
|
|
if (m_pZoneEnumList == NULL)
|
|
{
|
|
}
|
|
else if (m_pZoneEnumList->dwEnum == dwEnum)
|
|
{
|
|
pDelete = m_pZoneEnumList;
|
|
m_pZoneEnumList = pDelete->next;
|
|
}
|
|
else {
|
|
CZoneEnumList *pCurr = m_pZoneEnumList;
|
|
|
|
while (pCurr != NULL)
|
|
{
|
|
if (pCurr->next && pCurr->next->dwEnum == dwEnum)
|
|
{
|
|
pDelete = pCurr->next;
|
|
pCurr->next = pDelete->next;
|
|
break;
|
|
}
|
|
pCurr = pCurr->next;
|
|
}
|
|
}
|
|
|
|
if (pDelete == NULL)
|
|
{
|
|
// Didn't find the entry must be an invalid Enumerator.
|
|
hr = E_INVALIDARG;
|
|
}
|
|
else
|
|
{
|
|
delete pDelete;
|
|
hr = S_OK;
|
|
}
|
|
LeaveCriticalSection(&m_csect);
|
|
return hr;
|
|
}
|
|
|
|
//=============================================================================
|
|
// CRegZoneCache methods
|
|
//=============================================================================
|
|
CRegZone::CRegZoneCache::CRegZoneCache(void)
|
|
{
|
|
InitializeCriticalSection(&m_csectZoneCache);
|
|
|
|
// single static object, so this only gets inited once per
|
|
// process.
|
|
s_hMutexCounter = CreateMutexA(NULL, FALSE, "ZonesCacheCounterMutex");
|
|
m_iAdd = 0;
|
|
}
|
|
|
|
CRegZone::CRegZoneCache::~CRegZoneCache(void)
|
|
{
|
|
Flush();
|
|
DeleteCriticalSection(&m_csectZoneCache) ;
|
|
|
|
CloseHandle(s_hMutexCounter);
|
|
}
|
|
|
|
BOOL
|
|
CRegZone::CRegZoneCache::Lookup(DWORD dwZone, LPTSTR lpZonePath, DWORD dwAction, BOOL fUseHKLM, DWORD *pdwPolicy)
|
|
{
|
|
BOOL fFound = FALSE;
|
|
int iEntry = URLZONE_FINDCACHEENTRY;
|
|
|
|
TransAssert(iEntry < MAX_REG_ZONE_CACHE);
|
|
|
|
EnterCriticalSection(&m_csectZoneCache);
|
|
|
|
if ( !IsCounterEqual() )
|
|
Flush();
|
|
|
|
fFound = FindCacheEntry(dwZone, dwAction, fUseHKLM, iEntry );
|
|
if (fFound)
|
|
{
|
|
if (pdwPolicy)
|
|
{
|
|
*pdwPolicy = m_arzce[iEntry].m_dwPolicy;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Convert the Action to a string.
|
|
#ifndef unix
|
|
TCHAR wsz[9]; // FFFFFFFF\0
|
|
#else
|
|
TCHAR wsz[(sizeof(DWORD)+1)*sizeof(WCHAR)];
|
|
#endif /* unix */
|
|
|
|
if (DwToWchar(dwAction, wsz, 16))
|
|
{
|
|
CRegKey regKey(fUseHKLM);
|
|
|
|
if (regKey.Open(NULL, lpZonePath, KEY_READ) == ERROR_SUCCESS)
|
|
{
|
|
if (regKey.QueryValue(pdwPolicy, wsz) == ERROR_SUCCESS)
|
|
{
|
|
fFound = TRUE;
|
|
Add(dwZone, dwAction, fUseHKLM, *pdwPolicy, iEntry);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// BUGBUG:: We have to be able to deal with this situation and not just bail.
|
|
// Possibilities: Setup defaults here if we can create and write to the key
|
|
TransAssert(FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TransAssert(FALSE);
|
|
}
|
|
}
|
|
|
|
LeaveCriticalSection(&m_csectZoneCache);
|
|
|
|
return fFound;
|
|
}
|
|
|
|
void
|
|
CRegZone::CRegZoneCache::Add(DWORD dwZone, DWORD dwAction, BOOL fUseHKLM, DWORD dwPolicy, int iEntry)
|
|
{
|
|
BOOL fFound;
|
|
|
|
TransAssert(iEntry < MAX_REG_ZONE_CACHE);
|
|
|
|
EnterCriticalSection(&m_csectZoneCache);
|
|
|
|
if ( !IsCounterEqual() )
|
|
Flush();
|
|
|
|
if(iEntry == URLZONE_FINDCACHEENTRY) // using optional param that indicates the entry we want to add so don't bother doing a find.
|
|
fFound = FindCacheEntry(dwZone, dwAction, fUseHKLM, iEntry ); // found or not, iEntry will be the right place to set it.
|
|
|
|
m_arzce[iEntry].Set(dwZone, dwAction, fUseHKLM, dwPolicy);
|
|
|
|
SetToCurrentCounter(); // validate this cache.
|
|
|
|
LeaveCriticalSection(&m_csectZoneCache);
|
|
}
|
|
|
|
void
|
|
CRegZone::CRegZoneCache::Flush(void)
|
|
{
|
|
int i;
|
|
|
|
EnterCriticalSection(&m_csectZoneCache);
|
|
|
|
for ( i = 0; i < MAX_REG_ZONE_CACHE; i++ )
|
|
m_arzce[i].Flush();
|
|
|
|
m_iAdd = 0;
|
|
|
|
LeaveCriticalSection(&m_csectZoneCache);
|
|
}
|
|
|
|
// Is the counter we saved with the cache entry, equal to the current counter.
|
|
BOOL
|
|
CRegZone::CRegZoneCache::IsCounterEqual( ) const
|
|
{
|
|
CExclusiveLock lock(s_hMutexCounter);
|
|
LPDWORD lpdwCounter = (LPDWORD)g_SharedMem.GetPtr(SM_REGZONECHANGE_COUNTER);
|
|
// If we couldn't create the shared memory for some reason, we just assume our cache is up to date.
|
|
if (lpdwCounter == NULL)
|
|
return TRUE;
|
|
|
|
return (m_dwPrevCounter == *lpdwCounter);
|
|
}
|
|
|
|
VOID
|
|
CRegZone::CRegZoneCache::SetToCurrentCounter( )
|
|
{
|
|
CExclusiveLock lock(s_hMutexCounter);
|
|
LPDWORD lpdwCounter = (LPDWORD)g_SharedMem.GetPtr(SM_REGZONECHANGE_COUNTER);
|
|
if (lpdwCounter == NULL)
|
|
return;
|
|
|
|
m_dwPrevCounter = *lpdwCounter;
|
|
}
|
|
|
|
VOID
|
|
CRegZone::CRegZoneCache::IncrementGlobalCounter( )
|
|
{
|
|
CExclusiveLock lock(s_hMutexCounter);
|
|
LPDWORD lpdwCounter = (LPDWORD)g_SharedMem.GetPtr(SM_REGZONECHANGE_COUNTER);
|
|
if (lpdwCounter == NULL)
|
|
return;
|
|
|
|
(*lpdwCounter)++;
|
|
}
|
|
|
|
BOOL
|
|
CRegZone::CRegZoneCache::FindCacheEntry(DWORD dwZone, DWORD dwAction, BOOL fUseHKLM, int& riEntry )
|
|
{
|
|
BOOL fFound = FALSE;
|
|
|
|
for ( riEntry = 0; (m_arzce[riEntry].m_dwZone != ZONEID_INVALID) && (riEntry < MAX_REG_ZONE_CACHE); riEntry++ )
|
|
{
|
|
if ( m_arzce[riEntry].m_dwZone == dwZone &&
|
|
m_arzce[riEntry].m_dwAction == dwAction &&
|
|
m_arzce[riEntry].m_fUseHKLM == fUseHKLM )
|
|
{
|
|
fFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(!fFound)
|
|
{
|
|
riEntry = m_iAdd;
|
|
m_iAdd = (m_iAdd + 1) % MAX_REG_ZONE_CACHE; // next index to add an entry that's not found
|
|
}
|
|
|
|
return fFound;
|
|
}
|
|
|
|
void
|
|
CRegZone::CRegZoneCache::CRegZoneCacheEntry::Set(DWORD dwZone, DWORD dwAction, BOOL fUseHKLM, DWORD dwPolicy)
|
|
{
|
|
m_dwZone = dwZone;
|
|
m_dwAction = dwAction;
|
|
m_fUseHKLM = fUseHKLM;
|
|
m_dwPolicy = dwPolicy;
|
|
}
|
|
|
|
void
|
|
CRegZone::CRegZoneCache::CRegZoneCacheEntry::Flush(void)
|
|
{
|
|
m_dwZone = ZONEID_INVALID;
|
|
}
|
|
|
|
|