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.
632 lines
24 KiB
632 lines
24 KiB
//+---------------------------------------------------------------------------
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1997-2002.
|
|
//
|
|
// File: ComponentDataRSOP.cpp
|
|
//
|
|
// Contents: Implementation of RSOP portions CCertMgrComponentData
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include <gpedit.h>
|
|
#include "compdata.h"
|
|
#include "dataobj.h"
|
|
#include "cookie.h"
|
|
#include "Certifct.h"
|
|
#pragma warning(push, 3)
|
|
#include <wintrust.h>
|
|
#include <cryptui.h>
|
|
#include <sceattch.h>
|
|
#pragma warning(pop)
|
|
#include "StoreRSOP.h"
|
|
|
|
#ifdef _DEBUG
|
|
#ifndef ALPHA
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
//
|
|
// CCertMgrComponentData
|
|
//
|
|
|
|
|
|
HRESULT CCertMgrComponentData::BuildWMIList (LPDATAOBJECT pDataObject, bool bIsComputer)
|
|
{
|
|
_TRACE (1, L"Entering CCertMgrComponentData::BuildWMIList (%s)\n", bIsComputer ? L"computer" : L"user");
|
|
HRESULT hr = S_OK;
|
|
|
|
#if DBG
|
|
if ( bIsComputer )
|
|
{
|
|
_TRACE (0, L"m_rsopObjectArrayComputer contains %d objects\n",
|
|
m_rsopObjectArrayComputer.GetUpperBound ());
|
|
}
|
|
else
|
|
{
|
|
_TRACE (0, L"m_rsopObjectArrayUser contains %d objects\n",
|
|
m_rsopObjectArrayUser.GetUpperBound ());
|
|
}
|
|
#endif
|
|
int nIndex = 0;
|
|
if ( bIsComputer )
|
|
{
|
|
INT_PTR nUpperBound = m_rsopObjectArrayComputer.GetUpperBound ();
|
|
while ( nUpperBound >= nIndex )
|
|
{
|
|
CRSOPObject* pCurrObject = m_rsopObjectArrayComputer.GetAt (nIndex);
|
|
if ( pCurrObject )
|
|
{
|
|
delete pCurrObject;
|
|
}
|
|
nIndex++;
|
|
}
|
|
m_rsopObjectArrayComputer.RemoveAll ();
|
|
}
|
|
else
|
|
{
|
|
INT_PTR nUpperBound = m_rsopObjectArrayUser.GetUpperBound ();
|
|
while ( nUpperBound >= nIndex )
|
|
{
|
|
CRSOPObject* pCurrObject = m_rsopObjectArrayUser.GetAt (nIndex);
|
|
if ( pCurrObject )
|
|
{
|
|
delete pCurrObject;
|
|
}
|
|
nIndex++;
|
|
}
|
|
m_rsopObjectArrayUser.RemoveAll ();
|
|
}
|
|
|
|
if ( ((bIsComputer && !m_pRSOPInformationComputer) ||
|
|
(!bIsComputer && !m_pRSOPInformationUser) )
|
|
&& pDataObject )
|
|
{
|
|
IUnknown* pIUnknown = 0;
|
|
|
|
hr = ExtractData (pDataObject,
|
|
CCertMgrDataObject::m_CFSCE_RSOPUnknown,
|
|
&pIUnknown, sizeof (IUnknown*));
|
|
ASSERT (SUCCEEDED (hr));
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
if ( bIsComputer )
|
|
{
|
|
hr = pIUnknown->QueryInterface (
|
|
IID_PPV_ARG (IRSOPInformation, &m_pRSOPInformationComputer));
|
|
}
|
|
else
|
|
{
|
|
hr = pIUnknown->QueryInterface (
|
|
IID_PPV_ARG (IRSOPInformation, &m_pRSOPInformationUser));
|
|
}
|
|
ASSERT (SUCCEEDED (hr));
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
if ( bIsComputer )
|
|
{
|
|
hr = m_pRSOPInformationComputer->GetFlags (&m_dwRSOPFlagsComputer);
|
|
}
|
|
else
|
|
{
|
|
hr = m_pRSOPInformationUser->GetFlags (&m_dwRSOPFlagsUser);
|
|
}
|
|
ASSERT (SUCCEEDED (hr));
|
|
|
|
int cchMaxLength = 512;
|
|
LPOLESTR pszNameSpace = (LPOLESTR) LocalAlloc (LPTR, cchMaxLength * sizeof (WCHAR));
|
|
if ( pszNameSpace )
|
|
{
|
|
DWORD dwSection = 0;
|
|
|
|
switch (m_dwSCEMode)
|
|
{
|
|
case SCE_MODE_LOCAL_USER:
|
|
case SCE_MODE_DOMAIN_USER:
|
|
case SCE_MODE_OU_USER:
|
|
case SCE_MODE_REMOTE_USER:
|
|
case SCE_MODE_RSOP_USER:
|
|
dwSection = GPO_SECTION_USER;
|
|
break;
|
|
|
|
case SCE_MODE_LOCAL_COMPUTER:
|
|
case SCE_MODE_DOMAIN_COMPUTER:
|
|
case SCE_MODE_OU_COMPUTER:
|
|
case SCE_MODE_RSOP_COMPUTER:
|
|
case SCE_MODE_REMOTE_COMPUTER:
|
|
dwSection = GPO_SECTION_MACHINE;
|
|
break;
|
|
|
|
default:
|
|
ASSERT (0);
|
|
return E_UNEXPECTED;
|
|
}
|
|
if ( bIsComputer )
|
|
{
|
|
hr = m_pRSOPInformationComputer->GetNamespace (
|
|
dwSection,
|
|
pszNameSpace,
|
|
cchMaxLength);
|
|
}
|
|
else
|
|
{
|
|
hr = m_pRSOPInformationUser->GetNamespace (
|
|
dwSection,
|
|
pszNameSpace,
|
|
cchMaxLength);
|
|
}
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
IWbemLocator *pIWbemLocator = 0;
|
|
// ISSUE
|
|
// NTRAID 544154 TRACKING: PKP GrpPol: Verify that WMI communication with the store can be secured
|
|
hr = ::CoCreateInstance (CLSID_WbemLocator,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_PPV_ARG(IWbemLocator, &pIWbemLocator));
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
BSTR bstrNameSpace = SysAllocString (pszNameSpace);
|
|
if ( bstrNameSpace )
|
|
{
|
|
if ( bIsComputer )
|
|
{
|
|
hr = pIWbemLocator->ConnectServer (bstrNameSpace,
|
|
NULL, NULL, 0, 0, NULL, NULL,
|
|
&m_pIWbemServicesComputer);
|
|
}
|
|
else
|
|
{
|
|
hr = pIWbemLocator->ConnectServer (bstrNameSpace,
|
|
NULL, NULL, 0, 0, NULL, NULL,
|
|
&m_pIWbemServicesUser);
|
|
}
|
|
if ( FAILED (hr) )
|
|
{
|
|
_TRACE (0, L"IWbemLocator::ConnectServer (%s) failed: 0x%x(%s)\n",
|
|
bstrNameSpace, hr, (PCWSTR) GetSystemMessage (hr));
|
|
}
|
|
SysFreeString (bstrNameSpace);
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
pIWbemLocator->Release ();
|
|
}
|
|
}
|
|
LocalFree (pszNameSpace);
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( SUCCEEDED (hr) && ((bIsComputer && m_pIWbemServicesComputer) ||
|
|
(!bIsComputer && m_pIWbemServicesUser)) )
|
|
{
|
|
IEnumWbemClassObject * pEnum = 0;
|
|
IWbemClassObject *pObject = 0;
|
|
ULONG ulRet = 0;
|
|
|
|
|
|
//
|
|
// Execute the query
|
|
//
|
|
if ( bIsComputer )
|
|
{
|
|
hr = m_pIWbemServicesComputer->ExecQuery (m_pbstrLanguage, m_pbstrQuery,
|
|
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
|
|
NULL, &pEnum);
|
|
}
|
|
else
|
|
{
|
|
hr = m_pIWbemServicesUser->ExecQuery (m_pbstrLanguage, m_pbstrQuery,
|
|
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
|
|
NULL, &pEnum);
|
|
}
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
//
|
|
// Loop through the results retrieving the registry key and value names
|
|
//
|
|
while ( (hr = pEnum->Next(WBEM_INFINITE, 1, &pObject, &ulRet)) == WBEM_S_NO_ERROR )
|
|
{
|
|
hr = GetValuesAndInsertInRSOPObjectList (pObject,
|
|
bIsComputer ? m_rsopObjectArrayComputer : m_rsopObjectArrayUser,
|
|
bIsComputer);
|
|
|
|
pObject->Release ();
|
|
|
|
if ( FAILED (hr) )
|
|
break;
|
|
}
|
|
|
|
pEnum->Release();
|
|
|
|
#if DBG
|
|
int nSpewIndex = 0;
|
|
INT_PTR nUpperBound = 0;
|
|
|
|
if ( bIsComputer )
|
|
nUpperBound = m_rsopObjectArrayComputer.GetUpperBound ();
|
|
else
|
|
nUpperBound = m_rsopObjectArrayUser.GetUpperBound ();
|
|
|
|
while ( nUpperBound >= nSpewIndex )
|
|
{
|
|
CRSOPObject* pCurrObject = 0;
|
|
if ( bIsComputer )
|
|
pCurrObject = m_rsopObjectArrayComputer.GetAt (nSpewIndex);
|
|
else
|
|
pCurrObject = m_rsopObjectArrayUser.GetAt (nSpewIndex);
|
|
if ( !pCurrObject )
|
|
break;
|
|
_TRACE (0, L"\t%d\t%s\t%s\t%s\n", pCurrObject->GetPrecedence (),
|
|
(PCWSTR) pCurrObject->GetRegistryKey (),
|
|
(PCWSTR) pCurrObject->GetValueName (),
|
|
(PCWSTR) pCurrObject->GetPolicyName ());
|
|
nSpewIndex++;
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
_TRACE (-1, L"Leaving CCertMgrComponentData::BuildWMIList (): 0x%x\n", hr);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CCertMgrComponentData::GetValuesAndInsertInRSOPObjectList (
|
|
IWbemClassObject* pObject,
|
|
CRSOPObjectArray& rRsopObjectArray,
|
|
bool bIsComputer)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if ( !pObject )
|
|
return E_POINTER;
|
|
|
|
//
|
|
// Check if the allocations succeeded
|
|
//
|
|
|
|
if ( m_pbstrLanguage && m_pbstrQuery && m_pbstrRegistryKey &&
|
|
m_pbstrValueName && m_pbstrValue &&
|
|
m_pbstrPrecedence && m_pbstrGPOid )
|
|
{
|
|
COleVariant varRegistryKey;
|
|
COleVariant varValueName;
|
|
COleVariant varValue;
|
|
COleVariant varPrecedence;
|
|
COleVariant varGPOid;
|
|
hr = pObject->Get (m_pbstrRegistryKey, 0, &varRegistryKey, NULL, NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pObject->Get (m_pbstrValueName, 0, &varValueName, NULL, NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pObject->Get (m_pbstrValue, 0, &varValue, NULL, NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//#ifndef DBG
|
|
// only include objects that have a value name
|
|
if ( varValueName.bstrVal[0] )
|
|
//#endif
|
|
{
|
|
//#ifndef DBG
|
|
// Only include those objects that are in the system store registry
|
|
// path or in the cryptography\autoenrollment path
|
|
if ( FoundInRSOPFilter (varRegistryKey.bstrVal) )
|
|
//#endif
|
|
{
|
|
hr = pObject->Get (m_pbstrPrecedence, 0, &varPrecedence, NULL, NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pObject->Get (m_pbstrGPOid, 0, &varGPOid, NULL, NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
PWSTR lpGPOName = 0;
|
|
|
|
hr = GetGPOFriendlyName (
|
|
varGPOid.bstrVal,
|
|
&lpGPOName,
|
|
bIsComputer);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
|
|
CRSOPObject* pRSOPObject = new CRSOPObject (
|
|
varRegistryKey.bstrVal,
|
|
varValueName.bstrVal,
|
|
lpGPOName,
|
|
varPrecedence.uintVal,
|
|
varValue,
|
|
varGPOid.bstrVal);
|
|
if ( pRSOPObject )
|
|
{
|
|
CRSOPObject* pCurrObject = 0;
|
|
int nIndex = 0;
|
|
bool bInserted = false;
|
|
INT_PTR nUpperBound = rRsopObjectArray.GetUpperBound ();
|
|
|
|
while ( nUpperBound >= nIndex )
|
|
{
|
|
pCurrObject = rRsopObjectArray.GetAt (nIndex);
|
|
if ( !pCurrObject )
|
|
break;
|
|
|
|
// Sort first by registry key name,
|
|
// then by value name, then by
|
|
// precedence
|
|
// security review 2/22/2002 BryanWal ok
|
|
int nCmpVal = wcscmp (pCurrObject->GetRegistryKey (),
|
|
pRSOPObject->GetRegistryKey ());
|
|
if ( nCmpVal > 0 )
|
|
{
|
|
rRsopObjectArray.InsertAt (nIndex, pRSOPObject);
|
|
bInserted = true;
|
|
break;
|
|
}
|
|
else if ( nCmpVal == 0 )
|
|
{
|
|
// Sort by value name
|
|
// security review 2/22/2002 BryanWal ok
|
|
nCmpVal = wcscmp (pCurrObject->GetValueName (),
|
|
pRSOPObject->GetValueName ());
|
|
if ( nCmpVal > 0 )
|
|
{
|
|
rRsopObjectArray.InsertAt (nIndex, pRSOPObject);
|
|
bInserted = true;
|
|
break;
|
|
}
|
|
else if ( nCmpVal == 0 )
|
|
{
|
|
// Sort by precedence
|
|
if ( pCurrObject->GetPrecedence () >
|
|
pRSOPObject->GetPrecedence () )
|
|
{
|
|
rRsopObjectArray.InsertAt (nIndex, pRSOPObject);
|
|
bInserted = true;
|
|
break;
|
|
}
|
|
else if ( pCurrObject->GetPrecedence () ==
|
|
pRSOPObject->GetPrecedence () )
|
|
{
|
|
// The registry key, value name and precedence
|
|
// are the same - this is a duplicate. Pretend
|
|
// we've added it and move on.
|
|
bInserted = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
nIndex++;
|
|
}
|
|
if ( !bInserted )
|
|
rRsopObjectArray.Add (pRSOPObject);
|
|
}
|
|
|
|
LocalFree (lpGPOName);
|
|
}
|
|
varGPOid.Clear ();
|
|
}
|
|
|
|
varPrecedence.Clear ();
|
|
}
|
|
}
|
|
}
|
|
varValue.Clear ();
|
|
}
|
|
|
|
varValueName.Clear ();
|
|
}
|
|
|
|
varRegistryKey.Clear ();
|
|
}
|
|
}
|
|
else
|
|
hr = E_OUTOFMEMORY;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CCertMgrComponentData::GetGPOFriendlyName (PCWSTR pwszOID, PWSTR *ppwszGPOName, bool bIsComputer)
|
|
{
|
|
ASSERT (pwszOID);
|
|
if ( !pwszOID )
|
|
return E_POINTER;
|
|
|
|
ASSERT (ppwszGPOName);
|
|
if ( !ppwszGPOName )
|
|
return E_POINTER;
|
|
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
//
|
|
// Set the default
|
|
//
|
|
|
|
*ppwszGPOName = NULL;
|
|
|
|
|
|
//
|
|
// Build the query
|
|
//
|
|
PCWSTR pwszQueryFormat = L"SELECT name, id FROM RSOP_GPO where id=\"%s\"";
|
|
// security review 2/22/2002 BryanWal ok
|
|
PWSTR pwszQuery = (PWSTR) ::LocalAlloc (LPTR, ((wcslen(pwszOID) + wcslen (pwszQueryFormat) + 1) * sizeof(WCHAR)));
|
|
if ( pwszQuery )
|
|
{
|
|
// security review 2/22/2002 BryanWal ok
|
|
wsprintf (pwszQuery, pwszQueryFormat, pwszOID);
|
|
|
|
|
|
BSTR bstrQuery = SysAllocString (pwszQuery);
|
|
if (bstrQuery)
|
|
{
|
|
//
|
|
// Allocate BSTRs for the property names we want to retreive
|
|
//
|
|
|
|
BSTR bstrName = SysAllocString (TEXT("name"));
|
|
if (bstrName)
|
|
{
|
|
//
|
|
// Execute the query
|
|
//
|
|
|
|
IEnumWbemClassObject* pEnum = 0;
|
|
if ( bIsComputer )
|
|
{
|
|
hr = m_pIWbemServicesComputer->ExecQuery (m_pbstrLanguage, bstrQuery,
|
|
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
|
|
NULL, &pEnum);
|
|
}
|
|
else
|
|
{
|
|
hr = m_pIWbemServicesUser->ExecQuery (m_pbstrLanguage, bstrQuery,
|
|
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
|
|
NULL, &pEnum);
|
|
}
|
|
|
|
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
//
|
|
// Loop through the results
|
|
//
|
|
IWbemClassObject* pObjects[2] = {0, 0};
|
|
ULONG ulRet = 0;
|
|
hr = pEnum->Next(WBEM_INFINITE, 1, pObjects, &ulRet);
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
//
|
|
// Check for the "data not available case"
|
|
//
|
|
|
|
if (ulRet != 0)
|
|
{
|
|
//
|
|
// Get the name
|
|
//
|
|
VARIANT varGPOName;
|
|
hr = pObjects[0]->Get (bstrName, 0, &varGPOName, NULL, NULL);
|
|
if ( SUCCEEDED (hr) )
|
|
{
|
|
//
|
|
// Save the name
|
|
//
|
|
|
|
// security review 2/22/2002 BryanWal ok
|
|
*ppwszGPOName = (PWSTR) ::LocalAlloc (LPTR, (wcslen (varGPOName.bstrVal) + 1) * sizeof(WCHAR));
|
|
|
|
if ( *ppwszGPOName )
|
|
{
|
|
// security review 2/22/2002 BryanWal ok
|
|
wcscpy (*ppwszGPOName, varGPOName.bstrVal);
|
|
|
|
VariantClear (&varGPOName);
|
|
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
_TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to allocate memory for GPO Name");
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to get gponame in query results for %s with 0x%x\n",
|
|
bstrQuery, hr);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to get first item in query results for %s with 0x%x\n",
|
|
bstrQuery, hr);
|
|
}
|
|
|
|
pEnum->Release ();
|
|
}
|
|
else
|
|
{
|
|
_TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to query for %s with 0x%x\n",
|
|
bstrQuery, hr);
|
|
}
|
|
|
|
SysFreeString (bstrName);
|
|
}
|
|
else
|
|
{
|
|
_TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to allocate memory for name");
|
|
hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
|
|
}
|
|
|
|
SysFreeString (bstrQuery);
|
|
}
|
|
else
|
|
{
|
|
_TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to allocate memory for query");
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
::LocalFree (pwszQuery);
|
|
}
|
|
else
|
|
{
|
|
_TRACE (0, L"CCertMgrComponentData::GetGPOFriendlyName: Failed to allocate memory for unicode query");
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
bool CCertMgrPKPolExtension::FoundInRSOPFilter (BSTR bstrKey) const
|
|
{
|
|
ASSERT (bstrKey);
|
|
if ( !bstrKey )
|
|
return false;
|
|
|
|
// security review 2/22/2002 BryanWal ok for all
|
|
static size_t nRegPathLen = wcslen (CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH);
|
|
static size_t nTrustedPublisherKeyLen =
|
|
wcslen (CERT_TRUST_PUB_SAFER_GROUP_POLICY_TRUSTED_PUBLISHER_STORE_REGPATH);
|
|
static size_t nDisallowedKeyLen =
|
|
wcslen (CERT_TRUST_PUB_SAFER_GROUP_POLICY_DISALLOWED_STORE_REGPATH);
|
|
static size_t nSaferKeyLen = wcslen (SAFER_HKLM_REGBASE);
|
|
static size_t nEFSKeyLen = wcslen (EFS_SETTINGS_REGPATH);
|
|
|
|
|
|
//Include group policy system stores but not trusted publisher or disallowed
|
|
// security review 2/22/2002 BryanWal ok for all
|
|
if ( !_wcsnicmp (CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH, bstrKey, nRegPathLen) &&
|
|
(_wcsnicmp (CERT_TRUST_PUB_SAFER_GROUP_POLICY_TRUSTED_PUBLISHER_STORE_REGPATH,
|
|
bstrKey, nTrustedPublisherKeyLen) &&
|
|
_wcsnicmp (CERT_TRUST_PUB_SAFER_GROUP_POLICY_DISALLOWED_STORE_REGPATH,
|
|
bstrKey, nDisallowedKeyLen)) )
|
|
{
|
|
return true;
|
|
}
|
|
else if ( !_wcsnicmp (SAFER_HKLM_REGBASE, bstrKey, nSaferKeyLen) ||
|
|
!_wcsnicmp (EFS_SETTINGS_REGPATH, bstrKey, nEFSKeyLen) ||
|
|
!_wcsicmp (AUTO_ENROLLMENT_KEY, bstrKey) )
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|