//+-------------------------------------------------------------------------- // // 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 #include "wrapper.h" #include "wmihooks.h" #include #include //+-------------------------------------------------------------------------- // // 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 (_wcsicmp(GT_COMPUTER_TEMPLATE,szName) == 0) { //Prefast warning 400: Yields unexpected results in non-English locales. Comments: It is not localizable. 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 strMsg,strBase; strBase.LoadString(IDS_SAVE_FAILED); //Raid #485372, yanggao, 11/28/2001 strBase += GetFriendlyName(); strBase += L"."; MyFormatMessage(status, (LPCTSTR)strBase, NULL, strMsg); AfxMessageBox(strMsg); 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) { //This is a safe usage. 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 szDescriptionLoc; //Raid #prefast if (szDesc) { szDescriptionLoc = new TCHAR[lstrlen(szDesc)+1]; if (szDescriptionLoc) { //This is a safe usage. lstrcpy(szDescriptionLoc,szDesc); if (m_szDesc) { delete[] m_szDesc; } m_szDesc = szDescriptionLoc; 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; } //Prefast warning 400: Yields unexpected results in non-English locales. Comments: They are not localizable. if ((_wcsicmp(GT_COMPUTER_TEMPLATE,m_szInfFile) == 0) || (_wcsicmp(GT_LAST_INSPECTION,m_szInfFile) == 0) || (_wcsicmp(GT_LOCAL_POLICY, m_szInfFile) == 0) || (_wcsicmp(GT_EFFECTIVE_POLICY, m_szInfFile) == 0) ) { // // Analysis pane areas from jet database, not INF files // SCETYPE sceType; PSCE_ERROR_LOG_INFO perr = NULL; if (_wcsicmp(GT_COMPUTER_TEMPLATE,m_szInfFile) == 0) { //Prefast warning 400: Yields unexpected results in non-English locales. Comments: It is not localizable. sceType = SCE_ENGINE_SMP; } else if (_wcsicmp(GT_LOCAL_POLICY, m_szInfFile) == 0) { sceType = SCE_ENGINE_SYSTEM; if (!IsAdmin()) { m_hProfile = NULL; } } else if (_wcsicmp(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 == _wcsicmp(GT_EFFECTIVE_POLICY,m_szInfFile))) { SetTemplateDefaults(); return 0; } else { return IDS_ERROR_CANT_GET_PROFILE_INFO; } } } else if (_wcsicmp(GT_RSOP_TEMPLATE, m_szInfFile) == 0) { //Prefast warning 400: Yields unexpected results in non-English locales. Comments: It is not localizable. 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 (_wcsicmp(GT_DEFAULT_TEMPLATE,m_szInfFile) == 0) { //Prefast warning 400: Yields unexpected results in non-English locales. Comments: It is not localizable. 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); //Check the pHandle and return IDS_ERROR_CANT_GET_PROFILE_INFO if it fails. // // get information from this template // PSCE_ERROR_LOG_INFO perr = NULL; if( pHandle ) //Raid #550912, yanggao. { rc = SceGetSecurityProfileInfo(pHandle, SCE_ENGINE_SCP, aiArea, &pTemplate, &perr //NULL // &ErrBuf do not care errors ); if (SCESTATUS_SUCCESS != rc) { // Oops! } SceCloseProfile(&pHandle); pHandle = NULL; } else { return IDS_ERROR_CANT_OPEN_PROFILE; } } /* 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_EXECUTE_HANDLER) { //Raid #630245, yanggao, 6/05/2002. 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; } //This may not be a safe usage. pCurrent->Name is PWSTR. Consider fix. 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; }