windows-nt/Source/XPSP1/NT/admin/snapin/wsecmgr/edittemp.cpp

988 lines
28 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//+--------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1994 - 2001.
//
// File: edittemp.cpp
//
// Contents: CEditTemplate class to handle editing of SCE's INF files
//
// History:
//
//---------------------------------------------------------------------------
#include "stdafx.h"
#include "resource.h"
#include "edittemp.h"
#include "util.h"
#include "snapmgr.h"
#include <secedit.h>
#include "wrapper.h"
#include "wmihooks.h"
#include <sceattch.h>
#include <locale.h>
//+--------------------------------------------------------------------------
//
// Method: AddService
//
// Synopsis: Adds a service attachment to the template
//
// Arguments: [szService] - [in] the name of the new service
// [pPersistInfo] - [in] A pointer to the service extensions'
// persistance interface
//
// Returns: TRUE if successfull, FALSE if either argument is null
//
// Modifies: m_Services
//
// History:
//
//---------------------------------------------------------------------------
BOOL
CEditTemplate::AddService(LPCTSTR szService, LPSCESVCATTACHMENTPERSISTINFO pPersistInfo) {
if (!szService || !pPersistInfo) {
return FALSE;
}
m_Services.SetAt(szService,pPersistInfo);
return TRUE;
}
//+--------------------------------------------------------------------------
//
// Method: IsDirty
//
// Synopsis: Queries whether or not there is unsaved data in the template
//
// Returns: TRUE if there is unsaved information, FALSE otherwise
//
// Modifies:
//
// History:
//
//---------------------------------------------------------------------------
BOOL
CEditTemplate::IsDirty() {
//
// Some area is dirty
//
if (0 != m_AreaDirty) {
return TRUE;
}
//
// Loop through services until we find one that is dirty
// or there are no more to check.
//
CString strService;
LPSCESVCATTACHMENTPERSISTINFO pAttachPI;
POSITION pos;
pos = m_Services.GetStartPosition();
while (pos) {
m_Services.GetNextAssoc(pos,strService,pAttachPI);
if (pAttachPI && (S_OK == pAttachPI->IsDirty(m_szInfFile))) {
return TRUE;
}
}
//
// We didn't find anything dirty
//
return FALSE;
}
//+--------------------------------------------------------------------------
//
// Method: SetDirty
//
// Synopsis: Notify the template that some data within it has been changed.
//
// Returns: TRUE if successful, FALSE otherwise
//
// Modifies:
//
// History:
//
//---------------------------------------------------------------------------
BOOL
CEditTemplate::SetDirty(AREA_INFORMATION Area) {
DWORD AreaDirtyOld;
AreaDirtyOld = m_AreaDirty;
m_AreaDirty |= Area;
//
// If the template is supposed to immediately save any changes then
// do so.
//
if (QueryWriteThrough() && !m_bLocked) {
SetWriteThroughDirty(TRUE);
if (Save()) {
//
// #204628 - don't call PolicyChanged twiced when writing through
// Call it in SetDirty and then skip it in Save, so we don't call it
// once in SetDirty's call to Save and a second time when Save is called
// on its own
//
// #204779 - call the notification window rather than directly calling
// the IGPEInformation interface
//
if (m_pNotify && QueryPolicy()) {
m_pNotify->RefreshPolicy();
}
} else {
m_AreaDirty = AreaDirtyOld;
return FALSE;
}
}
return TRUE;
}
//+--------------------------------------------------------------------------------------
// CEditTemplate::SetTemplateDefaults
//
// The caller will have to remove all memory objects used by this template if
// this function
// is called. Everything becomes NULL and nothing is freed.
//+--------------------------------------------------------------------------------------
void CEditTemplate::SetTemplateDefaults()
{
//
// Local Policy Changes. Initialize everything to not changed
//
SCE_PROFILE_INFO *ppi = pTemplate;
m_AreaLoaded = 0;
m_AreaDirty = 0;
if(!ppi){
ppi = pTemplate = (PSCE_PROFILE_INFO) LocalAlloc(LPTR,sizeof(SCE_PROFILE_INFO));
if (!pTemplate) {
return;
}
}
//
// Must keep to type of this template.
//
SCETYPE dwType = ppi->Type;
PSCE_KERBEROS_TICKET_INFO pKerberosInfo = ppi->pKerberosInfo;
ZeroMemory( ppi, sizeof(SCE_PROFILE_INFO));
ppi->Type = dwType;
//
// Set defaults to the rest of the template.
//
ppi->MinimumPasswordAge=SCE_NO_VALUE;
ppi->MaximumPasswordAge=SCE_NO_VALUE;
ppi->MinimumPasswordLength=SCE_NO_VALUE;
ppi->PasswordComplexity=SCE_NO_VALUE;
ppi->PasswordHistorySize=SCE_NO_VALUE;
ppi->LockoutBadCount=SCE_NO_VALUE;
ppi->ResetLockoutCount=SCE_NO_VALUE;
ppi->LockoutDuration=SCE_NO_VALUE;
ppi->RequireLogonToChangePassword=SCE_NO_VALUE;
ppi->ForceLogoffWhenHourExpire=SCE_NO_VALUE;
ppi->EnableAdminAccount=SCE_NO_VALUE;
ppi->EnableGuestAccount=SCE_NO_VALUE;
ppi->ClearTextPassword=SCE_NO_VALUE;
ppi->LSAAnonymousNameLookup=SCE_NO_VALUE;
for (int i=0;i<3;i++) {
ppi->MaximumLogSize[i]=SCE_NO_VALUE;
ppi->AuditLogRetentionPeriod[i]=SCE_NO_VALUE;
ppi->RetentionDays[i]=SCE_NO_VALUE;
ppi->RestrictGuestAccess[i]=SCE_NO_VALUE;
}
ppi->AuditSystemEvents=SCE_NO_VALUE;
ppi->AuditLogonEvents=SCE_NO_VALUE;
ppi->AuditObjectAccess=SCE_NO_VALUE;
ppi->AuditPrivilegeUse=SCE_NO_VALUE;
ppi->AuditPolicyChange=SCE_NO_VALUE;
ppi->AuditAccountManage=SCE_NO_VALUE;
ppi->AuditProcessTracking=SCE_NO_VALUE;
ppi->AuditDSAccess=SCE_NO_VALUE;
ppi->AuditAccountLogon=SCE_NO_VALUE;
//
// String values
//
ppi->NewAdministratorName=NULL;
ppi->NewGuestName=NULL;
//
// registry values
//
ppi->RegValueCount= 0;
ppi->aRegValues = NULL;
//
// Kerberos information, if it was created then set the values.
//
if(pKerberosInfo){
pKerberosInfo->MaxTicketAge = SCE_NO_VALUE;
pKerberosInfo->MaxRenewAge = SCE_NO_VALUE;
pKerberosInfo->MaxServiceAge = SCE_NO_VALUE;
pKerberosInfo->MaxClockSkew = SCE_NO_VALUE;
pKerberosInfo->TicketValidateClient = SCE_NO_VALUE;
ppi->pKerberosInfo = pKerberosInfo;
}
}
//+--------------------------------------------------------------------------
//
// Method: Save
//
// Synopsis: Save the template to disk
//
// Arguments: [szName] - [in] [optional] the name of the INF file to save to
//
// Returns: TRUE if the save is successful, False otherwise
//
// Modifies: m_AreaDirty
//
// History:
//
//---------------------------------------------------------------------------
BOOL
CEditTemplate::Save(LPCTSTR szName) {
DWORD AreaDirty;
BOOL bSaveAs = FALSE;
BOOL bSaveDescription = FALSE;
setlocale(LC_ALL, ".OCP");
SCESTATUS status = SCESTATUS_OTHER_ERROR;
PSCE_ERROR_LOG_INFO errBuf = NULL;
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (QueryNoSave()) {
m_AreaDirty = 0;
return TRUE;
}
AreaDirty = m_AreaDirty;
//
// If szName isn't given then default to m_szInfFile
//
if (!szName) {
szName = m_szInfFile;
//
// We should never be able to get into a situation where
// szName still isn't set, but just in case somebody called
// us without szName or m_szInfFile
//
ASSERT(szName);
if (!szName) {
return FALSE;
}
} else {
if (lstrcmp(szName,m_szInfFile) != 0) {
//
// Saving to a different name (Save As)
//
//
// Make sure the path to that filename exists:
//
if (SCESTATUS_SUCCESS != SceCreateDirectory( m_szInfFile, FALSE, NULL )) {
return FALSE;
}
AreaDirty = AREA_ALL|AREA_DESCRIPTION;
bSaveAs = TRUE;
}
}
if (AreaDirty & AREA_DESCRIPTION) {
bSaveDescription = TRUE;
AreaDirty &= ~AREA_DESCRIPTION;
if (!AreaDirty) {
//
// Make sure we have something else to save and
// create the file. AREA_SECURITY_POLICY is cheap.
//
AreaDirty |= AREA_SECURITY_POLICY;
}
//
// Bug 365485 - make sure we only write this to an already
// existing temp file so that we don't accidentally create
// an ansi one instead of unicode. We can easily do this
// by writing the description section last since we can
// depend on the engine getting the rest right
//
}
if (AreaDirty) {
//
// Save the dirty areas of the profile
//
if (lstrcmpi(GT_COMPUTER_TEMPLATE,szName) == 0) {
if (m_hProfile) {
//
// do not update object area
//
status = SceUpdateSecurityProfile(m_hProfile,
AreaDirty & ~(AREA_FILE_SECURITY | AREA_REGISTRY_SECURITY | AREA_DS_OBJECTS),
pTemplate,
0
);
}
ASSERT(m_pCDI);
if (m_pCDI) {
m_pCDI->EngineCommitTransaction();
}
} else if (lstrcmp(GT_LOCAL_POLICY_DELTA,szName) == 0) {
//
// Save Changes only to Local Policy
//
status = SceUpdateSecurityProfile(NULL,
AreaDirty & ~(AREA_FILE_SECURITY | AREA_REGISTRY_SECURITY | AREA_DS_OBJECTS),
pTemplate,
SCE_UPDATE_SYSTEM
);
SetTemplateDefaults();
if (!bSaveAs) {
m_AreaDirty = 0;
m_AreaLoaded = 0;
}
} else if ((lstrcmp(GT_LAST_INSPECTION,szName) != 0) &&
(lstrcmp(GT_RSOP_TEMPLATE,szName) != 0) &&
(lstrcmp(GT_LOCAL_POLICY,szName) != 0) &&
(lstrcmp(GT_EFFECTIVE_POLICY,szName) != 0)) {
status = SceWriteSecurityProfileInfo(szName,
AreaDirty,
pTemplate,
&errBuf);
} else {
//
// No need (or way) to save the last inspection area
//
status = SCESTATUS_SUCCESS;
}
if (SCESTATUS_SUCCESS == status) {
//
// Those areas are no longer dirty.
//
if (!bSaveAs) {
m_AreaDirty = 0;
}
} else {
//
// Save failed; Notify the user & return false
//
CString strTitle,strMsg,strBase;
strTitle.LoadString(IDS_NODENAME);
strBase.LoadString(IDS_SAVE_FAILED);
strBase += GetFriendlyName();
//MyFormatMessage(status, (LPCTSTR)strBase, errBuf,strMsg);
AfxMessageBox(strBase);
return FALSE;
}
}
if (bSaveDescription) {
if (m_szDesc) {
if (WritePrivateProfileSection(
szDescription,
NULL,
szName)) {
WritePrivateProfileString(
szDescription,
L"Description",
m_szDesc,
szName);
}
}
}
//
// Save any dirty services
//
CString strService;
LPSCESVCATTACHMENTPERSISTINFO pAttachPI;
POSITION pos;
SCESVCP_HANDLE *scesvcHandle;
PVOID pvData;
BOOL bOverwriteAll;
pos = m_Services.GetStartPosition();
while (pos) {
m_Services.GetNextAssoc(pos,strService,pAttachPI);
if (S_OK == pAttachPI->IsDirty( (LPTSTR)szName )) {
if (SUCCEEDED(pAttachPI->Save( (LPTSTR)szName,(SCESVC_HANDLE *)&scesvcHandle,&pvData,&bOverwriteAll ))) {
if (scesvcHandle) {
if (lstrcmp(GT_COMPUTER_TEMPLATE,szName) == 0) {
//
// database
//
status = SceSvcUpdateInfo(
m_hProfile,
scesvcHandle->ServiceName,
(PSCESVC_CONFIGURATION_INFO)pvData
);
} else {
//
// inf templates
//
status = SceSvcSetInformationTemplate(scesvcHandle->TemplateName,
scesvcHandle->ServiceName,
bOverwriteAll,
(PSCESVC_CONFIGURATION_INFO)pvData);
}
if (SCESTATUS_SUCCESS != status) {
CString strTitle,strMsg,strBase;
strTitle.LoadString(IDS_NODENAME);
strBase.LoadString(IDS_SAVE_FAILED);
strBase += scesvcHandle->ServiceName; //szName;
MyFormatMessage(status, (LPCTSTR)strBase, errBuf,strMsg);
AfxMessageBox(strMsg);
}
}
}
}
}
return TRUE;
}
//+--------------------------------------------------------------------------
//
// Method: SetInfFile
//
// Synopsis: Set the name of the INF file this template is associated with
//
// Arguments: [szFile] - [in] the name of the INF file to associate with
//
// Returns: TRUE if the filename is set successfully, FALSE otherwise
//
// Modifies: m_szInfFile
//
// History:
//
//---------------------------------------------------------------------------
BOOL
CEditTemplate::SetInfFile(LPCTSTR szFile) {
LPTSTR szInfFile;
if (szFile) {
szInfFile = new TCHAR[lstrlen(szFile)+1];
if (szInfFile) {
lstrcpy(szInfFile,szFile);
if (m_szInfFile) {
delete[] m_szInfFile;
}
m_szInfFile = szInfFile;
} else {
return FALSE;
}
}
return szFile != 0;
}
//+--------------------------------------------------------------------------
//
// Method: SetDescription
//
// Synopsis: Set the description for this template file
//
// Arguments: [szDesc] [in] the description for the template
//
// Returns: TRUE if the description is set successfully, FALSE otherwise
//
// Modifies: m_szDesc
//
// History:
//
//---------------------------------------------------------------------------
BOOL
CEditTemplate::SetDescription(LPCTSTR szDesc) {
LPTSTR szDescription;
if (szDesc) {
szDescription = new TCHAR[lstrlen(szDesc)+1];
if (szDescription) {
lstrcpy(szDescription,szDesc);
if (m_szDesc) {
delete[] m_szDesc;
}
m_szDesc = szDescription;
SetDirty(AREA_DESCRIPTION);
} else {
return FALSE;
}
}
return szDesc != 0;
}
//+--------------------------------------------------------------------------
//
// Method: CEditTemplate
//
// Synopsis: Constructor for CEditTemplate
//
// History:
//
//---------------------------------------------------------------------------
CEditTemplate::CEditTemplate() {
m_AreaDirty = 0;
m_AreaLoaded = 0;
m_bWriteThrough = FALSE;
m_bWriteThroughDirty = FALSE;
m_hProfile = NULL;
m_szInfFile = NULL;
m_pNotify = NULL;
m_pCDI = NULL;
m_bNoSave = FALSE;
m_strFriendlyName.Empty();
m_szDesc = NULL;
m_bWMI = NULL;
m_bPolicy = FALSE;
m_bLocked = FALSE;
pTemplate = NULL;
}
//+--------------------------------------------------------------------------
//
// Method: ~CEditTemplate
//
// Synopsis: Destructor for CEditTemplate
//
// History:
//
//---------------------------------------------------------------------------
CEditTemplate::~CEditTemplate() {
POSITION pos;
CString strKey;
pos = m_Services.GetStartPosition();
LPSCESVCATTACHMENTPERSISTINFO pAttachPI;
while (pos) {
m_Services.GetNextAssoc(pos,strKey,pAttachPI);
delete pAttachPI;
}
if (m_szInfFile) {
delete[] m_szInfFile;
}
if (m_szDesc) {
delete[] m_szDesc;
}
if (pTemplate) {
if (m_bWMI) {
FreeWMI_SCE_PROFILE_INFO((PWMI_SCE_PROFILE_INFO)pTemplate);
} else {
SceFreeProfileMemory(pTemplate);
}
pTemplate = NULL;
}
m_AreaDirty = 0;
}
//+--------------------------------------------------------------------------
//
// Method: RefreshTemplate
//
// Synopsis: Reload the loaded parts of the template
//
// Arguments: [aiArea] - Areas to load even if not previously loaded
//
// Returns: 0 if the template is reloaded successfully, an error code otherwise
//
// Modifies: pTemplate;
//---------------------------------------------------------------------------
DWORD
CEditTemplate::RefreshTemplate(AREA_INFORMATION aiAreaToAdd) {
AREA_INFORMATION aiArea;
PVOID pHandle = NULL;
SCESTATUS rc;
aiArea = m_AreaLoaded | aiAreaToAdd;
if (!m_szInfFile) {
return 1;
}
m_AreaDirty = 0;
if (pTemplate) {
if (m_bWMI) {
FreeWMI_SCE_PROFILE_INFO((PWMI_SCE_PROFILE_INFO)pTemplate);
} else {
SceFreeProfileMemory(pTemplate);
}
pTemplate = NULL;
}
if ((lstrcmpi(GT_COMPUTER_TEMPLATE,m_szInfFile) == 0) ||
(lstrcmpi(GT_LAST_INSPECTION,m_szInfFile) == 0) ||
(lstrcmpi(GT_LOCAL_POLICY, m_szInfFile) == 0) ||
(lstrcmpi(GT_EFFECTIVE_POLICY, m_szInfFile) == 0) ) {
//
// Analysis pane areas from jet database, not INF files
//
SCETYPE sceType;
PSCE_ERROR_LOG_INFO perr = NULL;
if (lstrcmpi(GT_COMPUTER_TEMPLATE,m_szInfFile) == 0) {
sceType = SCE_ENGINE_SMP;
} else if (lstrcmpi(GT_LOCAL_POLICY, m_szInfFile) == 0) {
sceType = SCE_ENGINE_SYSTEM;
if (!IsAdmin()) {
m_hProfile = NULL;
}
} else if (lstrcmpi(GT_EFFECTIVE_POLICY,m_szInfFile) == 0){
sceType = SCE_ENGINE_GPO;
} else {
sceType = SCE_ENGINE_SAP;
}
rc = SceGetSecurityProfileInfo(m_hProfile, // hProfile
sceType, // Profile type
aiArea, // Area
&pTemplate, // SCE_PROFILE_INFO [out]
&perr); // Error List [out]
if (SCESTATUS_SUCCESS != rc) {
if ((SCE_ENGINE_GPO == sceType) &&
(0 == lstrcmpi(GT_EFFECTIVE_POLICY,m_szInfFile))) {
SetTemplateDefaults();
return 0;
} else {
return IDS_ERROR_CANT_GET_PROFILE_INFO;
}
}
} else if (lstrcmpi(GT_RSOP_TEMPLATE, m_szInfFile) == 0) {
if (!m_pCDI) {
return IDS_ERROR_CANT_GET_PROFILE_INFO;
}
m_bWMI = TRUE;
CWMIRsop Rsop(m_pCDI->m_pRSOPInfo);
HRESULT hr;
PWMI_SCE_PROFILE_INFO pProfileInfo;
//
// GetPrecedenceOneRSOPInfo should (but doesn't) support
// getting just the requested area.
//
hr = Rsop.GetPrecedenceOneRSOPInfo(&pProfileInfo);
if (FAILED(hr)) {
return IDS_ERROR_CANT_GET_PROFILE_INFO;
}
pTemplate = pProfileInfo;
//
// Since it doesn't, set all areas not just the ones that
// were asked for
//
AddArea(AREA_ALL);
return 0;
} else {
LPTSTR szInfFile=NULL;
if (lstrcmpi(GT_DEFAULT_TEMPLATE,m_szInfFile) == 0) {
DWORD RegType;
rc = MyRegQueryValue(HKEY_LOCAL_MACHINE,
SCE_REGISTRY_KEY,
SCE_REGISTRY_DEFAULT_TEMPLATE,
(PVOID *)&szInfFile,
&RegType );
if (ERROR_SUCCESS != rc) {
if (szInfFile) {
LocalFree(szInfFile);
szInfFile = NULL;
}
return IDS_ERROR_CANT_GET_PROFILE_INFO;
}
if (EngineOpenProfile(szInfFile,OPEN_PROFILE_CONFIGURE,&pHandle) != SCESTATUS_SUCCESS) {
SetTemplateDefaults();
LocalFree(szInfFile);
szInfFile = NULL;
return 0;
}
LocalFree(szInfFile);
szInfFile = NULL;
} else {
if (EngineOpenProfile(m_szInfFile,OPEN_PROFILE_CONFIGURE,&pHandle) != SCESTATUS_SUCCESS) {
return IDS_ERROR_CANT_OPEN_PROFILE;
}
}
ASSERT(pHandle);
//
// get information from this template
//
PSCE_ERROR_LOG_INFO perr = NULL;
rc = SceGetSecurityProfileInfo(pHandle,
SCE_ENGINE_SCP,
aiArea,
&pTemplate,
&perr //NULL // &ErrBuf do not care errors
);
if (SCESTATUS_SUCCESS != rc) {
// Oops!
}
SceCloseProfile(&pHandle);
pHandle = NULL;
}
/*
if do not care errors, no need to use this buffer
if ( ErrBuf ) {
SceFreeMemory((PVOID)ErrBuf, SCE_STRUCT_ERROR_LOG_INFO);
ErrBuf = NULL;
}
*/
if (rc != SCESTATUS_SUCCESS) {
return IDS_ERROR_CANT_GET_PROFILE_INFO;
}
//
// Set the area in the template
//
AddArea(aiArea);
if ( aiArea & AREA_SECURITY_POLICY && pTemplate ) {
//
// expand registry value section based on registry values list on local machine
//
SceRegEnumAllValues(
&(pTemplate->RegValueCount),
&(pTemplate->aRegValues)
);
}
return 0;
}
//+----------------------------------------------------------------------------------
//Method: UpdatePrivilegeAssignedTo
//
//Synopsis: Updates a priviledge item, depending on the [bRemove] argument.
// if [bRemove] is
// FALSE - A new link is created and the pointer is returned through
// ppaLink
// TRUE - The link is removed from the list.
//
//Arguments: [bRemove] - Weither to remove or add an item.
// [ppaLink] - The link to be removed or added. This paramter is
// set to NULL if remove is successful or a pointer
// to a new SCE_PRIVILEGE_ASSIGNMENT item.
// [pszName] - Only used when adding a new item.
//
//Returns: ERROR_INVALID_PARAMETER - [ppaLink] is NULL or if removing
// [*ppaLink] is NULL.
// if adding then if [pszName] is NULL
// ERROR_RESOURCE_NOT_FOUND - If the link could not be found
// in this template.
// E_POINTER - If [pszName] is a bad pointer or
// [ppaLink] is bad.
// E_OUTOFMEMORY - Not enough resources to complete the
// operation.
// ERROR_SUCCESS - The opration was successful.
//----------------------------------------------------------------------------------+
DWORD
CEditTemplate::UpdatePrivilegeAssignedTo(
BOOL bRemove,
PSCE_PRIVILEGE_ASSIGNMENT *ppaLink,
LPCTSTR pszName
)
{
if(!ppaLink){
return ERROR_INVALID_PARAMETER;
}
PSCE_PRIVILEGE_ASSIGNMENT *pNext = NULL;
PSCE_PRIVILEGE_ASSIGNMENT pCurrent = NULL;
if(bRemove) {
__try {
if(!*ppaLink){
return ERROR_INVALID_PARAMETER;
}
} __except(EXCEPTION_CONTINUE_EXECUTION) {
return (DWORD)E_POINTER;
}
//
// Remove the link from the list.
//
pCurrent = pTemplate->OtherInfo.smp.pPrivilegeAssignedTo;
if(pCurrent == (*ppaLink) ){
pNext = &(pTemplate->OtherInfo.smp.pPrivilegeAssignedTo);
} else if(pCurrent && pCurrent != (PSCE_PRIVILEGE_ASSIGNMENT)ULongToPtr(SCE_NO_VALUE)) {
while( pCurrent->Next ){
if(pCurrent->Next == *ppaLink){
pNext = &(pCurrent->Next);
break;
}
pCurrent = pCurrent->Next;
}
}
if(pNext && pCurrent){
(*pNext) = (*ppaLink)->Next;
if( (*ppaLink)->Name){
LocalFree( (*ppaLink)->Name);
(*ppaLink)->Name = NULL;
}
SceFreeMemory( (*ppaLink)->AssignedTo, SCE_STRUCT_NAME_LIST);
LocalFree( *ppaLink );
*ppaLink = NULL;
} else {
return ERROR_RESOURCE_NOT_FOUND;
}
} else {
int iLen;
if(!pszName){
return ERROR_INVALID_PARAMETER;
}
__try {
iLen = lstrlen( pszName );
} __except(EXCEPTION_CONTINUE_EXECUTION){
return (DWORD)E_POINTER;
}
//
// Create a new link.
//
pCurrent = (PSCE_PRIVILEGE_ASSIGNMENT)LocalAlloc( 0, sizeof(SCE_PRIVILEGE_ASSIGNMENT));
if(!pCurrent){
return (DWORD)E_OUTOFMEMORY;
}
ZeroMemory(pCurrent, sizeof(SCE_PRIVILEGE_ASSIGNMENT));
//
// Allocate space for the name.
//
pCurrent->Name = (LPTSTR)LocalAlloc( 0, sizeof(TCHAR) * (iLen + 1));
if(!pCurrent->Name){
LocalFree(pCurrent);
return (DWORD)E_OUTOFMEMORY;
}
lstrcpy(pCurrent->Name, pszName);
if (*ppaLink) {
pCurrent->Status = (*ppaLink)->Status;
pCurrent->AssignedTo = (*ppaLink)->AssignedTo;
}
//
// Assign it to the link.
//
pCurrent->Next = pTemplate->OtherInfo.smp.pPrivilegeAssignedTo;
pTemplate->OtherInfo.smp.pPrivilegeAssignedTo = pCurrent;
*ppaLink = pCurrent;
}
return ERROR_SUCCESS;
}
DWORD
CEditTemplate::ComputeStatus(
PSCE_PRIVILEGE_ASSIGNMENT pEdit,
PSCE_PRIVILEGE_ASSIGNMENT pAnal
)
{
if (!pEdit || (PSCE_PRIVILEGE_ASSIGNMENT)ULongToPtr(SCE_NO_VALUE) == pEdit) {
return SCE_STATUS_NOT_CONFIGURED;
} else if (pEdit->Status == SCE_STATUS_NOT_CONFIGURED) {
return SCE_STATUS_NOT_CONFIGURED;
} else if (!pAnal || (PSCE_PRIVILEGE_ASSIGNMENT)ULongToPtr(SCE_NO_VALUE) == pAnal) {
return SCE_STATUS_MISMATCH;
} else if (SceCompareNameList(pEdit->AssignedTo, pAnal->AssignedTo)) {
return SCE_STATUS_GOOD;
}
return pAnal->Status;
}
DWORD
CEditTemplate::ComputeStatus(
PSCE_REGISTRY_VALUE_INFO prvEdit,
PSCE_REGISTRY_VALUE_INFO prvAnal
)
{
//
// Calculate information.
//
if(!prvEdit){
return SCE_STATUS_NOT_CONFIGURED;
}
if(!prvAnal || (PSCE_REGISTRY_VALUE_INFO)ULongToPtr(SCE_NO_VALUE) == prvAnal){
return SCE_STATUS_ERROR_NOT_AVAILABLE;
}
//
// Calulate base on other information
//
if ( !(prvEdit->Value) ) {
return SCE_STATUS_NOT_CONFIGURED;
} else if ( (prvAnal->Value == NULL || prvAnal->Value == (LPTSTR)ULongToPtr(SCE_ERROR_VALUE))) {
return prvAnal->Status;
} else if ( _wcsicmp(prvEdit->Value, prvAnal->Value) != 0 ) {
return SCE_STATUS_MISMATCH;
}
return SCE_STATUS_GOOD;
}
void
CEditTemplate::LockWriteThrough() {
ASSERT(!m_bLocked);
m_bLocked = TRUE;
}
void
CEditTemplate::UnLockWriteThrough() {
ASSERT(m_bLocked);
BOOL bSave = m_bLocked;
m_bLocked = FALSE;
//
// Set dirty to save out any still dirty changes that
// would have been written out had we not been locked
//
if ( bSave ) {
SetDirty(0);
SetTemplateDefaults();
}
}
//Bug 212287, Yanggao, 3/20/2001
LPCTSTR CEditTemplate::GetDesc() const
{
return m_szDesc;
}