windows-nt/Source/XPSP1/NT/admin/snapin/wsecmgr/command.cpp
2020-09-26 16:20:57 +08:00

1455 lines
40 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation 1996-2001.
//
// File: command.cpp
//
// Contents: implementation of CComponentDataImpl
//
//----------------------------------------------------------------------------
#include "stdafx.h"
#include "wrapper.h"
#include "snapmgr.h"
#include "asgncnfg.h"
#include "util.h"
#include <io.h>
static BOOL RecursiveCreateDirectory(
IN LPCTSTR pszDir
)
{
DWORD dwAttr;
DWORD dwErr;
LPCTSTR psz;
DWORD cch;
WCHAR wch;
LPTSTR pszParent = NULL;
BOOL fResult = FALSE;
dwAttr = GetFileAttributes(pszDir);
if (0xFFFFFFFF != dwAttr)
{
if (FILE_ATTRIBUTE_DIRECTORY & dwAttr)
fResult = TRUE;
goto CommonReturn;
}
dwErr = GetLastError();
if (!(ERROR_PATH_NOT_FOUND == dwErr || ERROR_FILE_NOT_FOUND == dwErr))
return FALSE;
if (CreateDirectory(pszDir, NULL)) // lpSecurityAttributes
{
fResult = TRUE;
goto CommonReturn;
}
dwErr = GetLastError();
if (!(ERROR_PATH_NOT_FOUND == dwErr || ERROR_FILE_NOT_FOUND == dwErr))
goto CommonReturn;
// Peal off the last path name component
cch = _tcslen(pszDir);
psz = pszDir + cch;
while (TEXT('\\') != *psz)
{
if (psz == pszDir)
// Path didn't have a \.
goto CommonReturn;
psz--;
}
cch = (DWORD)(psz - pszDir);
if (0 == cch)
// Detected leading \Path
goto CommonReturn;
// Check for leading \\ or x:\.
wch = *(psz - 1);
if ((1 == cch && TEXT('\\') == wch) || (2 == cch && TEXT(':') == wch))
goto CommonReturn;
if (NULL == (pszParent = (LPWSTR) LocalAlloc(0, (cch + 1) * sizeof(WCHAR))))
goto CommonReturn;
memcpy(pszParent, pszDir, cch * sizeof(TCHAR));
pszParent[cch] = TEXT('\0');
if (!RecursiveCreateDirectory(pszParent))
goto CommonReturn;
if (!CreateDirectory(pszDir, NULL)) // lpSecurityAttributes
{
dwErr = GetLastError();
goto CommonReturn;
}
fResult = TRUE;
CommonReturn:
if (pszParent != NULL)
LocalFree(pszParent);
return fResult;
}
//+------------------------------------------------------------------------------------
// CComponentDataImpl::GetWorkingDir
//
// Gets the default or last set directory used for the uIDDir.
// Some defaults defined by this function are.
//
// %windir%\security\database - ANALYSIS
// %windir%\security\Templates - Default profile location.
//
// Arguments: [uIDDir] - The ID of the working directory to set or retrieve.
// [pStr] - Either the source or the return value. When the
// function returns this value will be set to a directory
// location.
//
// [bSet] - TRUE if [pStr] is to be set as the new working directory.
// [bFile] - [pStr] contains a file name.
//
// Returns: TRUE - If the function succees.
// FALSE - if something went wrong.
// We don't really need to much granularity because this is not a critical
// function.
//+------------------------------------------------------------------------------------
BOOL
CComponentDataImpl::GetWorkingDir(
GWD_TYPES uIDDir,
LPTSTR *pStr,
BOOL bSet,
BOOL bFile
)
{
BOOL fRet = FALSE;
if(!pStr)
{
return FALSE;
}
LPTSTR szLocationValue = NULL;
switch(uIDDir)
{
case GWD_CONFIGURE_LOG:
szLocationValue = CONFIGURE_LOG_LOCATIONS_KEY;
break;
case GWD_ANALYSIS_LOG:
szLocationValue = ANALYSIS_LOG_LOCATIONS_KEY;
break;
case GWD_OPEN_DATABASE:
szLocationValue = OPEN_DATABASE_LOCATIONS_KEY;
break;
case GWD_IMPORT_TEMPLATE:
szLocationValue = IMPORT_TEMPLATE_LOCATIONS_KEY;
break;
case GWD_EXPORT_TEMPLATE:
szLocationValue = IMPORT_TEMPLATE_LOCATIONS_KEY; //104152, yanggao, 3/21/2001
break;
}
LPTSTR pszPath = NULL;
int i = 0;
if( bSet )
{
if(!pStr || !(*pStr))
return FALSE;
i = lstrlen( *pStr );
if(bFile)
{
//
// Remove the file from the end of the string.
//
while(i && (*pStr)[i] != '\\')
i--;
}
//
// Create space for the new path and copy what we want.
//
pszPath = (LPTSTR)LocalAlloc( 0, (i + 1) * sizeof(TCHAR));
if(!pszPath)
return FALSE;
memcpy(pszPath, *pStr, (i * sizeof(TCHAR)));
pszPath[i] = 0;
MyRegSetValue(HKEY_CURRENT_USER,
DEFAULT_LOCATIONS_KEY,
szLocationValue,
(BYTE*)pszPath,
(i+1)*sizeof(TCHAR),
REG_SZ);
LocalFree(pszPath);
return TRUE;
}
DWORD dwType = REG_SZ;
if (MyRegQueryValue(HKEY_CURRENT_USER,
DEFAULT_LOCATIONS_KEY,
szLocationValue,
(PVOID*)&pszPath,
&dwType) == ERROR_SUCCESS)
{
*pStr = pszPath;
return TRUE;
}
CString sAppend;
DWORD dwRet;
pszPath = NULL;
switch ( uIDDir )
{
case GWD_CONFIGURE_LOG:
case GWD_ANALYSIS_LOG:
sAppend.LoadString(IDS_LOGFILE_DEFAULT);
// fall through
case GWD_OPEN_DATABASE:
//
// Used for open DB.
//
if (sAppend.IsEmpty())
{
sAppend.LoadString( IDS_DB_DEFAULT );
} // else fell through
//
// Default directory for analysis.
//
pszPath = (LPTSTR)LocalAlloc( 0, (MAX_PATH + sAppend.GetLength() + 1) * sizeof(TCHAR));
if (pszPath == NULL)
return FALSE;
if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, pszPath)))
{
lstrcpy( &(pszPath[lstrlen(pszPath)]), sAppend );
//
// Check to see if the directory does not exist, it may need
// to be created if this is the first time this user has
// opened a database.
//
TCHAR szTempFile[MAX_PATH];
CString str;
str.LoadString(IDS_TEMP_FILENAME);
if (!GetTempFileName(pszPath,str,0,szTempFile))
{
if ((GetLastError() == ERROR_DIRECTORY) && (RecursiveCreateDirectory(pszPath)))
{
fRet = TRUE;
}
else
{
LocalFree(pszPath);
fRet = FALSE;
}
}
else
{
DeleteFile(szTempFile);
fRet = TRUE;
}
}
else
{
LocalFree(pszPath);
pszPath = NULL;
}
break;
case GWD_IMPORT_TEMPLATE:
case GWD_EXPORT_TEMPLATE:
sAppend.LoadString( IDS_DEFAULT_TEMPLATE_DIR );
//
// Default directory for analysis.
//
dwRet = GetSystemWindowsDirectory( NULL, 0);
if (dwRet)
{
pszPath = (LPTSTR)LocalAlloc( 0, (dwRet + sAppend.GetLength() + 1) * sizeof(TCHAR));
if (!pszPath)
return FALSE;
GetSystemWindowsDirectory( pszPath, dwRet + 1);
lstrcpy( &(pszPath[lstrlen(pszPath)]), sAppend );
i = lstrlen(pszPath);
//
// Make sure the user can write to this directory:
//
TCHAR szTempFile[MAX_PATH];
HANDLE hTempFile=NULL;
CString str;
str.LoadString(IDS_TEMP_FILENAME);
szTempFile[0] = L'\0';
if (GetTempFileName(pszPath,str,0,szTempFile))
{
hTempFile = ExpandAndCreateFile(szTempFile,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
CREATE_NEW,
FILE_ATTRIBUTE_TEMPORARY,
NULL);
}
if (hTempFile)
{
//
// We have write access to this directory
//
::CloseHandle(hTempFile);
DeleteFile(szTempFile);
fRet = TRUE;
}
else
{
//
// We don't have write access to this directory. Find another
// or we can't get a temp file name
//
LPTSTR szPath;
LPITEMIDLIST pidl;
LPMALLOC pMalloc;
//
// For some reason this won't compile with SHGetFolderPath()
// Therefore go the long way around and deal with the pidl.
//
if (NOERROR == SHGetSpecialFolderLocation(m_hwndParent,CSIDL_PERSONAL,&pidl))
{
if (SHGetPathFromIDList(pidl,szTempFile))
{
szPath = (LPTSTR)LocalAlloc(LPTR, (lstrlen(szTempFile)+ 1) * sizeof(TCHAR));
if (szPath)
{
//
// If we can't create a new path then use the old one so the user
// at least has a starting place to browse from
//
lstrcpy(szPath,szTempFile);
LocalFree(pszPath);
pszPath = szPath;
fRet = TRUE;
}
}
if (SUCCEEDED(SHGetMalloc(&pMalloc)))
{
pMalloc->Free(pidl);
pMalloc->Release();
}
}
//
// If we can't write here the user will have to browse for something
//
}
}
break;
}
*pStr = pszPath;
return fRet;
}
UINT_PTR CALLBACK OFNHookProc(
HWND hdlg, // handle to child dialog box
UINT uiMsg, // message identifier
WPARAM wParam, // message parameter
LPARAM lParam // message parameter
)
{
if ( WM_NOTIFY == uiMsg )
{
OFNOTIFY* pOFNotify = (OFNOTIFY*) lParam;
if ( pOFNotify && CDN_FILEOK == pOFNotify->hdr.code )
{
//
// Don't accept filenames with DBCS characters that are greater then 255 in them
//
//Raid #263854, 4/3/2001
BOOL ferr = TRUE;
CString strErr;
if(WideCharToMultiByte(CP_ACP, 0, pOFNotify->lpOFN->lpstrFile,
-1, NULL, 0, NULL, &ferr))
{
return 0;
}
strErr.LoadString(IDS_NO_DBCS);
strErr += L"\r\n\r\n";
strErr += pOFNotify->lpOFN->lpstrFile;
AfxMessageBox(strErr);
::SetWindowLongPtr(hdlg, DWLP_MSGRESULT, TRUE);
return 1;
}
}
return 0;
}
//+--------------------------------------------------------------------------
//
// Method: OnOpenDataBase()
//
// Synopsis: Picks a new database for SAV to work on
//
//---------------------------------------------------------------------------
HRESULT
CComponentDataImpl::OnOpenDataBase()
{
//
// Find the desired new database
//
CString strDefExtension;
CString strFilter;
CString strOfnTitle;
CString strDir;
strDefExtension.LoadString(IDS_DEFAULT_DB_EXTENSION);
strFilter.LoadString(IDS_DB_FILTER);
strOfnTitle.LoadString(IDS_OPEN_DB_OFN_TITLE);
LPTSTR pszDir = NULL;
//
// Build a working directory for this object,
//
if (GetWorkingDir( GWD_OPEN_DATABASE, &pszDir ) )
{
strDir = pszDir;
LocalFree(pszDir);
pszDir = NULL;
}
WCHAR szFile[MAX_PATH];
::ZeroMemory (szFile, MAX_PATH * sizeof(WCHAR));
OPENFILENAME ofn;
::ZeroMemory (&ofn, sizeof (OPENFILENAME));
ofn.lStructSize = sizeof (OPENFILENAME);
ofn.hwndOwner = m_hwndParent;
//HINSTANCE hInstance;
// Translate filter into commdlg format (lots of \0)
LPTSTR szFilter = strFilter.GetBuffer(0); // modify the buffer in place
// MFC delimits with '|' not '\0'
LPTSTR pch = szFilter;
while ((pch = _tcschr(pch, '|')) != NULL)
*pch++ = '\0';
// do not call ReleaseBuffer() since the string contains '\0' characters
ofn.lpstrFilter = szFilter;
ofn.lpstrFile = szFile;
ofn.nMaxFile = MAX_PATH * sizeof(WCHAR);
ofn.lpstrInitialDir = (PCWSTR) strDir;
ofn.lpstrTitle = strOfnTitle;
ofn.Flags = OFN_HIDEREADONLY| // Don't show the read only prompt
OFN_SHAREAWARE|
OFN_NOREADONLYRETURN|
OFN_EXPLORER | // Explorer style dialog;
OFN_DONTADDTORECENT|
OFN_ENABLEHOOK;
ofn.lpstrDefExt = (PCWSTR) strDefExtension;
ofn.lpfnHook = OFNHookProc;
if ( GetOpenFileName (&ofn) )
{
//
// Set the working directory of the database.
//
pszDir = szFile;
GetWorkingDir( GWD_OPEN_DATABASE, &pszDir, TRUE, TRUE );
if( IsSystemDatabase( ofn.lpstrFile /*fo.GetPathName()*/) )
{
AfxMessageBox( IDS_CANT_OPEN_SYSTEM_DB, MB_OK);
return S_FALSE;
}
SadName = ofn.lpstrFile; //fo.GetPathName();
SetErroredLogFile(NULL);
//
// If new database doesn't exist then ask for a configuration to import
//
DWORD dwAttr = GetFileAttributes(SadName);
if (0xFFFFFFFF == dwAttr)
{
SCESTATUS sceStatus = SCESTATUS_SUCCESS;
//
// New database, so assign a configuration
//
if( OnAssignConfiguration( &sceStatus ) == S_FALSE)
{
//
// If the user decides to cancel the import of a configuration, then,
// we need to unload the sad information and display the correct
// error message. Set the sad errored to PROFILE_NOT_FOUND so error,
// is correct. There is no need to call LoadSadinfo.
//
UnloadSadInfo();
if( sceStatus != SCESTATUS_SUCCESS )
SadErrored = sceStatus;
else
SadErrored = SCESTATUS_PROFILE_NOT_FOUND;
if(m_AnalFolder)
{
m_pConsole->SelectScopeItem(m_AnalFolder->GetScopeItem()->ID);
}
return S_OK;
}
}
//
// Invalidiate currently open database
//
RefreshSadInfo();
return S_OK;
}
else
{
DWORD dwErr = CommDlgExtendedError();
}
return S_FALSE;
}
//+--------------------------------------------------------------------------
//
// Method: OnNewDataBase()
//
// Synopsis: Picks a new database for SAV to work on
//
//---------------------------------------------------------------------------
HRESULT
CComponentDataImpl::OnNewDatabase()
{
//
// Find the desired new database
//
CString strDefExtension;
CString strFilter;
CString strOfnTitle;
CWnd cwndParent;
strDefExtension.LoadString(IDS_DEFAULT_DB_EXTENSION);
strFilter.LoadString(IDS_DB_FILTER);
strOfnTitle.LoadString(IDS_NEW_DB_OFN_TITLE);
// Translate filter into commdlg format (lots of \0)
LPTSTR szFilter = strFilter.GetBuffer(0); // modify the buffer in place
LPTSTR pch = szFilter;
// MFC delimits with '|' not '\0'
while ((pch = _tcschr(pch, '|')) != NULL)
*pch++ = '\0';
// do not call ReleaseBuffer() since the string contains '\0' characters
OPENFILENAME ofn;
::ZeroMemory (&ofn, sizeof (OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.lpstrFilter = szFilter;
ofn.lpstrFile = SadName.GetBuffer(MAX_PATH);
ofn.nMaxFile = MAX_PATH;
ofn.lpstrDefExt = strDefExtension,
ofn.hwndOwner = m_hwndParent;
ofn.Flags = OFN_HIDEREADONLY |
OFN_SHAREAWARE |
OFN_EXPLORER |
OFN_DONTADDTORECENT;
ofn.lpstrTitle = strOfnTitle;
if (GetOpenFileName(&ofn))
{
PVOID pHandle = NULL;
SadName.ReleaseBuffer();
//
// If new database doesn't exist then ask for a configuration to import
//
DWORD dwAttr = GetFileAttributes(SadName);
if (0xFFFFFFFF == dwAttr)
{
//
// New database, so assign a configuration
//
SCESTATUS sceStatus;
OnAssignConfiguration(&sceStatus);
}
//
// Invalidiate currently open database
//
SetErroredLogFile(NULL);
RefreshSadInfo();
return S_OK;
}
return S_FALSE;
}
//+--------------------------------------------------------------------------
//
// Method: OnAssignConfiguration()
//
// Synopsis: Assigns a configuration template to SAV's currently selected
// database
//
//---------------------------------------------------------------------------
HRESULT
CComponentDataImpl::OnAssignConfiguration( SCESTATUS *pSceStatus )
{
//
//Currently pSceStatus is only used for passing back the error
//when user presses cancel on select template diaglog.
//
// Find the desired new database
//
CString strDefExtension; // Default extension
CString strCurFile;
CString strFilter; // Extension filter
CString strOfnTitle;
CWnd cwndParent;
BOOL bIncremental;
SCESTATUS status;
HKEY hKey; // HKEY of TemplateUsed.
DWORD dwBufSize = 0; // Size of szTemplateUsed in bytes
DWORD dwType = 0; // Type of registry item, return by query
DWORD dwStatus;
*pSceStatus = 0;
//
// Display a warning and give a chance to cancel
// if they try to configure a non-system database
//
if (IsSystemDatabase(SadName))
{
BOOL bImportAnyway;
bImportAnyway = AfxMessageBox(IDS_IMPORT_WARNING,MB_OKCANCEL);
if (IDCANCEL == bImportAnyway)
{
return S_FALSE;
}
}
strDefExtension.LoadString(IDS_PROFILE_DEF_EXT);
strFilter.LoadString(IDS_PROFILE_FILTER);
strOfnTitle.LoadString(IDS_ASSIGN_CONFIG_OFN_TITLE);
//
// Get the last directory used by templates.
//
LPTSTR pszDir = NULL;
if(strCurFile.IsEmpty())
{
if (GetWorkingDir( GWD_EXPORT_TEMPLATE, &pszDir ) )
{
strCurFile = pszDir;
LocalFree(pszDir);
pszDir = NULL;
}
}
strCurFile += TEXT("\\*.");
strCurFile += strDefExtension;
cwndParent.Attach(m_hwndParent);
CAssignConfiguration ac(TRUE, // File Open, not file save
strDefExtension, // Default Extension
strCurFile, // Initial File Name == current DB
OFN_HIDEREADONLY| // Don't show the read only prompt
OFN_EXPLORER| // Explorer style dialog
OFN_ENABLETEMPLATE| // custom template
OFN_SHAREAWARE| // We're not going to need exclusive
OFN_DONTADDTORECENT|
OFN_PATHMUSTEXIST, // The Template must exist for us to assign it.
strFilter, // Filter for allowed extensions
&cwndParent); // Dialog's Parent window
cwndParent.Detach();
ac.m_ofn.lpstrTitle = strOfnTitle.GetBuffer(1);
ac.m_ofn.lpTemplateName = MAKEINTRESOURCE(IDD_ASSIGN_CONFIG_CHECK);
if (IDOK == ac.DoModal())
{
CThemeContextActivator activator;
strCurFile = ac.GetPathName();
bIncremental = ac.m_bIncremental;
//
// Set the working dir to this file.
//
pszDir = strCurFile.GetBuffer(0);
GetWorkingDir( GWD_IMPORT_TEMPLATE, &pszDir, TRUE, TRUE);
strCurFile.ReleaseBuffer();
CWaitCursor wc;
//
// Unload the sad info before we choose to do an import.
//
UnloadSadInfo();
status = AssignTemplate(
strCurFile.IsEmpty() ? NULL:(LPCTSTR)strCurFile,
SadName,
bIncremental
);
if (SCESTATUS_SUCCESS != status)
{
CString strErr;
MyFormatResMessage(status,IDS_IMPORT_FAILED,NULL,strErr);
AfxMessageBox(strErr);
//
// We don't know if the database is still OK to read so open it anyways.
//
LoadSadInfo(TRUE);
if( SCESTATUS_SPECIAL_ACCOUNT == SadErrored ) //Raid #589139,XPSP1 DCR, yanggao, 4/12/2002.
*pSceStatus = SadErrored;
return S_FALSE;
}
RefreshSadInfo();
return S_OK;
}
*pSceStatus = SCESTATUS_NO_TEMPLATE_GIVEN;
return S_FALSE;
}
//+--------------------------------------------------------------------------
//
// Method: OnSecureWizard()
//
// Synopsis: Launch the secure wizard (registered)
//
//---------------------------------------------------------------------------
HRESULT
CComponentDataImpl::OnSecureWizard()
{
HRESULT hr=S_FALSE;
PWSTR pstrWizardName=NULL;
if ( GetSecureWizardName(&pstrWizardName, NULL) )
{
PROCESS_INFORMATION ProcInfo;
STARTUPINFO StartInfo;
BOOL fOk;
RtlZeroMemory(&StartInfo,sizeof(StartInfo));
StartInfo.cb = sizeof(StartInfo);
StartInfo.dwFlags = STARTF_USESHOWWINDOW;
StartInfo.wShowWindow = (WORD)SW_SHOWNORMAL;
fOk = CreateProcess(pstrWizardName, NULL,
NULL, NULL, FALSE,
0,
NULL,
NULL,
&StartInfo,
&ProcInfo
);
if ( fOk )
{
::CloseHandle(ProcInfo.hProcess);
::CloseHandle(ProcInfo.hThread);
hr = S_OK;
}
LocalFree(pstrWizardName);
}
return hr;
}
//+--------------------------------------------------------------------------
//
// Method: OnSaveConfiguration()
//
// Synopsis: Saves the assigned computer template to an INF file
//
//---------------------------------------------------------------------------
HRESULT
CComponentDataImpl::OnSaveConfiguration()
{
//
// Find the desired new database
//
CString strDefExtension;
CString strFilter;
CWnd cwndParent;
CString strDefName;
CString strName;
SCESTATUS status = SCESTATUS_SUCCESS;
CString strOfnTitle;
strDefExtension.LoadString(IDS_PROFILE_DEF_EXT);
strFilter.LoadString(IDS_PROFILE_FILTER);
strOfnTitle.LoadString(IDS_EXPORT_CONFIG_OFN_TITLE);
//
// Get the working directory for INF files.
//
LPTSTR pszDir = NULL;
if( GetWorkingDir( GWD_EXPORT_TEMPLATE, &pszDir ) )
{
strDefName = pszDir;
LocalFree(pszDir);
pszDir = NULL;
}
strDefName += TEXT("\\*.");
strDefName += strDefExtension;
// Translate filter into commdlg format (lots of \0)
LPTSTR szFilter = strFilter.GetBuffer(0); // modify the buffer in place
LPTSTR pch = szFilter;
// MFC delimits with '|' not '\0'
while ((pch = _tcschr(pch, '|')) != NULL)
*pch++ = '\0';
// do not call ReleaseBuffer() since the string contains '\0' characters
OPENFILENAME ofn;
::ZeroMemory (&ofn, sizeof (OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.lpstrFilter = szFilter;
ofn.lpstrFile = strDefName.GetBuffer(MAX_PATH),
ofn.nMaxFile = MAX_PATH;
ofn.lpstrDefExt = strDefExtension,
ofn.hwndOwner = m_hwndParent;
ofn.Flags = OFN_HIDEREADONLY |
OFN_SHAREAWARE |
OFN_EXPLORER |
OFN_DONTADDTORECENT;
ofn.lpstrTitle = strOfnTitle;
if (GetSaveFileName(&ofn))
{
strDefName.ReleaseBuffer();
strName = ofn.lpstrFile;
//
// Set the working directory for inf files.
//
pszDir = strName.GetBuffer(0);
GetWorkingDir( GWD_EXPORT_TEMPLATE, &pszDir, TRUE, TRUE );
strName.ReleaseBuffer();
//
// Generate new inf file
//
status = SceCopyBaseProfile(GetSadHandle(),
SCE_ENGINE_SCP,
(LPTSTR)(LPCTSTR)strName,
AREA_ALL,
NULL );
if (SCESTATUS_SUCCESS != status)
{
CString str;
CString strErr;
GetSceStatusString(status, &strErr);
AfxFormatString2(str,IDS_EXPORT_FAILED,strName,strErr);
AfxMessageBox(str);
return S_FALSE;
}
return S_OK;
}
return S_FALSE;
}
//+--------------------------------------------------------------------------
//
// Method: OnExportPolicy()
//
// Synopsis: This function exports either the effective or local table
// from the system security database to a file.
//
// The function asks the user for a file through the CFileOpen
// class, then writes out the contents of either the effective
// or local policy table in the system database.
//
// Arguments: [bEffective] - Either to export the effect or local table.
//
// Returns: S_OK - if everything went well.
// S_FALSE - something failed.
//---------------------------------------------------------------------------
HRESULT
CComponentDataImpl::OnExportPolicy( BOOL bEffective )
{
CString strDefExtension;
CString strFilter;
CString strOfnTitle;
CString strDefName;
CString strName;
DWORD dwErr = 0;
BOOL bCopySuccess = FALSE;
strDefExtension.LoadString(IDS_PROFILE_DEF_EXT);
strFilter.LoadString(IDS_PROFILE_FILTER);
strOfnTitle.LoadString(IDS_EXPORT_POLICY_OFN_TITLE);
//
// Get the working directory for locations.
//
LPTSTR pszDir = NULL;
if( GetWorkingDir( GWD_EXPORT_TEMPLATE, &pszDir ) )
{
strDefName = pszDir;
LocalFree(pszDir);
pszDir = NULL;
}
strDefName += TEXT("\\*.");
strDefName += strDefExtension;
// Translate filter into commdlg format (lots of \0)
LPTSTR szFilter = strFilter.GetBuffer(0); // modify the buffer in place
LPTSTR pch = szFilter;
// MFC delimits with '|' not '\0'
while ((pch = _tcschr(pch, '|')) != NULL)
*pch++ = '\0';
// do not call ReleaseBuffer() since the string contains '\0' characters
OPENFILENAME ofn;
::ZeroMemory (&ofn, sizeof (OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.lpstrFilter = szFilter;
ofn.lpstrFile = strDefName.GetBuffer(MAX_PATH),
ofn.nMaxFile = MAX_PATH;
ofn.lpstrDefExt = strDefExtension,
ofn.hwndOwner = m_hwndParent;
ofn.Flags = OFN_HIDEREADONLY |
OFN_SHAREAWARE |
OFN_EXPLORER |
OFN_DONTADDTORECENT;
ofn.lpstrTitle = strOfnTitle;
if (GetSaveFileName(&ofn))
{
strDefName.ReleaseBuffer();
strName = ofn.lpstrFile;
//
// Set the working directory for locations.
//
pszDir = strName.GetBuffer(0);
GetWorkingDir( GWD_EXPORT_TEMPLATE, &pszDir, TRUE, TRUE );
strName.ReleaseBuffer();
//
// Make sure we can make the file.
//
DWORD dwErr = FileCreateError( strName, 0 );
if(dwErr == IDNO)
{
return S_FALSE;
}
//
// Generate the template
//
SCESTATUS sceStatus;
CWaitCursor wc;
sceStatus = SceSetupGenerateTemplate(
NULL, // Computer name
NULL, // The system database
bEffective, // For right now just the Local Pol table.
strName.GetBuffer(0),
NULL,
AREA_ALL
);
strName.ReleaseBuffer();
if(sceStatus != SCESTATUS_SUCCESS)
{
//
// Display the error message
//
DWORD dwError = SceStatusToDosError( sceStatus );
CString strErr;
MyFormatMessage( sceStatus, NULL, NULL, strErr );
strErr += strName;
AfxMessageBox( strErr, MB_ICONEXCLAMATION | MB_OK );
return S_FALSE;
}
return S_OK;
}
return S_FALSE;
}
//+--------------------------------------------------------------------------------------------
// CComponentDataImpl::OnImportPolicy
//
// Import policy opens a file open dialog box in which the user is allowed to choose
// a security configuration INF file to import into security policy.
//
//
// Arguments: [pDataObject] - The data object associated with the folder calling
// this function.
// Returns: S_OK - Import was successful.
// S_FALSE - Something went wrong.
//---------------------------------------------------------------------------------------------
HRESULT
CComponentDataImpl::OnImportPolicy(LPDATAOBJECT pDataObject)
{
CEditTemplate *pet = NULL;
CString strDefExtension;
CString strFilter;
CString strOfnTitle;
CWnd cwndParent;
CString strDefName;
CString strName;
strDefExtension.LoadString(IDS_PROFILE_DEF_EXT);
strFilter.LoadString(IDS_PROFILE_FILTER);
strOfnTitle.LoadString(IDS_IMPORT_POLICY_OFN_TITLE);
LPTSTR pszDir = NULL;
if( GetWorkingDir( GWD_IMPORT_TEMPLATE, &pszDir ) )
{
strDefName = pszDir;
LocalFree(pszDir);
pszDir = NULL;
}
strDefName += TEXT("\\*.");
strDefName += strDefExtension;
cwndParent.Attach(m_hwndParent);
CAssignConfiguration fo(TRUE, // File open
strDefExtension, // Default Extension
strDefName, // Initial File Name == current DB
OFN_HIDEREADONLY| // Don't show the read only prompt
OFN_SHAREAWARE|
OFN_EXPLORER| // Explorer style dialog
OFN_ENABLETEMPLATE| // custom template
OFN_DONTADDTORECENT|
OFN_PATHMUSTEXIST, // The Template must exist for us to assign it.
strFilter, // Filter for allowed extensions
&cwndParent); // Dialog's Parent window
cwndParent.Detach();
fo.m_ofn.lpstrTitle = strOfnTitle.GetBuffer(1);
fo.m_ofn.lpTemplateName = MAKEINTRESOURCE(IDD_ASSIGN_CONFIG_CHECK);
CThemeContextActivator activator;
if (IDOK == fo.DoModal())
{
PVOID pHandle = NULL;
BOOL bIncremental = fo.m_bIncremental;
strName = fo.GetPathName();
pszDir = strName.GetBuffer(0);
GetWorkingDir( GWD_IMPORT_TEMPLATE, &pszDir, TRUE, TRUE );
strName.ReleaseBuffer();
CWaitCursor wc;
CEditTemplate *pet;
//
// pet will be freed in m_Templates in DeleteTemplate
//
pet = GetTemplate(strName,AREA_ALL);
CString strErr;
CString strSCE;
int ret=0;
if ( pet == NULL )
{
//
// this is an invalid template or something is wrong reading the data out
//
strSCE.LoadString(IDS_EXTENSION_NAME);
strErr.Format(IDS_IMPORT_POLICY_INVALID,strName);
m_pConsole->MessageBox(strErr,strSCE,MB_OK,&ret);
return S_FALSE;
}
else
{
if ( ( bIncremental &&
(SCESTATUS_SUCCESS != SceAppendSecurityProfileInfo(m_szSingleTemplateName,
AREA_ALL,
pet->pTemplate,
NULL))) ||
(!bIncremental && !CopyFile(strName,m_szSingleTemplateName,FALSE) ) )
{
//
// Import Failed
//
strSCE.LoadString(IDS_EXTENSION_NAME);
strErr.Format(IDS_IMPORT_POLICY_FAIL,strName);
m_pConsole->MessageBox(strErr,strSCE,MB_OK,&ret);
DeleteTemplate(strName);
return S_FALSE;
}
DeleteTemplate(strName);
}
DeleteTemplate(m_szSingleTemplateName);
//
// Update the window.
//
pet = GetTemplate(m_szSingleTemplateName);
if(pet)
{
DWORD dwErr = pet->RefreshTemplate();
if ( 0 != dwErr )
{
CString strErr;
MyFormatResMessage (SCESTATUS_SUCCESS, dwErr, NULL, strErr);
AfxMessageBox(strErr);
return S_FALSE;
}
}
RefreshAllFolders();
return S_OK;
}
return S_FALSE;
}
//+--------------------------------------------------------------------------------------------
// CComponentDataImpl::OnImportLocalPolicy
//
// Import policy opens a file open dialog box in which the user is allowed to choose
// a security configuration INF file to import into local policy.
//
// The function asks for the file name then calls SceConfigureSystem() with the
// SCE_NO_CONFIG option. This imports the specifide file into the local policy
// database.
//
// After the database is updated, we refresh the local policy template held in memory.
//
// Arguments: [pDataObject] - The data object associated with the folder calling
// this function.
// Returns: S_OK - Import was successful.
// S_FALSE - Something went wrong.
//---------------------------------------------------------------------------------------------
HRESULT
CComponentDataImpl::OnImportLocalPolicy(LPDATAOBJECT pDataObject)
{
CString strDefExtension;
CString strFilter;
CString strOfnTitle;
CString strDefName;
CString strName;
DWORD dwErr = 0;
SCESTATUS sceStatus = SCESTATUS_SUCCESS;
CString strErr;
CString strY;
strDefExtension.LoadString(IDS_PROFILE_DEF_EXT);
strFilter.LoadString(IDS_PROFILE_FILTER);
strOfnTitle.LoadString(IDS_IMPORT_POLICY_OFN_TITLE);
// Translate filter into commdlg format (lots of \0)
LPTSTR szFilter = strFilter.GetBuffer(0); // modify the buffer in place
LPTSTR pch = szFilter;
// MFC delimits with '|' not '\0'
while ((pch = _tcschr(pch, TEXT('|'))) != NULL)
*pch++ = TEXT('\0');
// do not call ReleaseBuffer() since the string contains '\0' characters
LPTSTR pszDir = NULL;
if( GetWorkingDir( GWD_IMPORT_TEMPLATE, &pszDir ) )
{
strDefName = pszDir;
LocalFree(pszDir);
pszDir = NULL;
}
strDefName += TEXT("\\*.");
strDefName += strDefExtension;
OPENFILENAME ofn;
::ZeroMemory (&ofn, sizeof (OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.lpstrFilter = szFilter;
ofn.lpstrFile = strDefName.GetBuffer(MAX_PATH),
ofn.nMaxFile = MAX_PATH;
ofn.lpstrDefExt = strDefExtension,
ofn.hwndOwner = m_hwndParent;
ofn.Flags = OFN_HIDEREADONLY |
OFN_SHAREAWARE |
OFN_EXPLORER |
OFN_DONTADDTORECENT;
ofn.lpstrTitle = strOfnTitle;
if (GetOpenFileName(&ofn))
{
PVOID pHandle = NULL;
strName = ofn.lpstrFile;
pszDir = strName.GetBuffer(0);
GetWorkingDir( GWD_IMPORT_TEMPLATE, &pszDir, TRUE, TRUE );
strName.ReleaseBuffer();
CWaitCursor wc;
CEditTemplate *pet;
pet = GetTemplate(strName,AREA_SECURITY_POLICY|AREA_PRIVILEGES);
if (!pet)
{
goto ret_error;
}
//
// We're going to alter this one so make sure it doesn't save out
//
pet->SetNoSave(TRUE);
//
// Remove entries that are set by domain policy since they'll be overwritten
// anyway and we don't allow setting things that'll be overwritten.
//
RemovePolicyEntries(pet);
//
// 120502 - SceUpdateSecurityProfile doesn't work with SCE_STRUCT_INF,
// but the AREA_SECURITY_POLICY and AREA_PRIVILEGES sections are
// compatable so we can call it SCE_ENGINE_SYSTEM, which will work.
//
SCETYPE origType = pet->pTemplate->Type;
pet->pTemplate->Type = SCE_ENGINE_SYSTEM;
sceStatus = SceUpdateSecurityProfile(NULL,
AREA_SECURITY_POLICY|AREA_PRIVILEGES,
pet->pTemplate,
SCE_UPDATE_SYSTEM
);
//
// Set the type back so the engine knows how to delete it properly
//
pet->pTemplate->Type = origType;
if (SCESTATUS_SUCCESS != sceStatus)
{
goto ret_error;
}
//
// Update the window.
//
pet = GetTemplate(GT_LOCAL_POLICY);
if(pet)
{
DWORD dwErr = pet->RefreshTemplate();
if ( 0 != dwErr )
{
CString strErr;
MyFormatResMessage (SCESTATUS_SUCCESS, dwErr, NULL, strErr);
AfxMessageBox(strErr);
return S_FALSE;
}
}
RefreshAllFolders();
return S_OK;
}
strDefName.ReleaseBuffer();
return S_FALSE;
ret_error:
strDefName.ReleaseBuffer();
MyFormatMessage( sceStatus, NULL, NULL, strErr);
strErr += strName;
strErr += L"\n";
strErr += strY;
AfxMessageBox( strErr, MB_OK);
return S_FALSE;
}
HRESULT
CComponentDataImpl::OnAnalyze()
{
PEDITTEMPLATE pet;
//
// If the computer template has been changed then save it before
// we can inspect against it
//
pet = GetTemplate(GT_COMPUTER_TEMPLATE);
if (pet && pet->IsDirty())
{
pet->Save();
}
m_pUIThread->PostThreadMessage(SCEM_ANALYZE_PROFILE,(WPARAM)(LPCTSTR)SadName,(LPARAM)this);
return S_OK;
}
BOOL
CComponentDataImpl::RemovePolicyEntries(PEDITTEMPLATE pet)
{
PEDITTEMPLATE petPol = GetTemplate(GT_EFFECTIVE_POLICY);
if (!petPol)
{
return FALSE;
}
#define CD(X) if (petPol->pTemplate->X != SCE_NO_VALUE) { pet->pTemplate->X = SCE_NO_VALUE; };
CD(MinimumPasswordAge);
CD(MaximumPasswordAge);
CD(MinimumPasswordLength);
CD(PasswordComplexity);
CD(PasswordHistorySize);
CD(LockoutBadCount);
CD(ResetLockoutCount);
CD(LockoutDuration);
CD(RequireLogonToChangePassword);
CD(ForceLogoffWhenHourExpire);
CD(EnableAdminAccount);
CD(EnableGuestAccount);
// These members aren't declared in NT4
CD(ClearTextPassword);
CD(AuditDSAccess);
CD(AuditAccountLogon);
CD(LSAAnonymousNameLookup);
CD(MaximumLogSize[0]);
CD(MaximumLogSize[1]);
CD(MaximumLogSize[2]);
CD(AuditLogRetentionPeriod[0]);
CD(AuditLogRetentionPeriod[1]);
CD(AuditLogRetentionPeriod[2]);
CD(RetentionDays[0]);
CD(RetentionDays[1]);
CD(RetentionDays[2]);
CD(RestrictGuestAccess[0]);
CD(RestrictGuestAccess[1]);
CD(RestrictGuestAccess[2]);
CD(AuditSystemEvents);
CD(AuditLogonEvents);
CD(AuditObjectAccess);
CD(AuditPrivilegeUse);
CD(AuditPolicyChange);
CD(AuditAccountManage);
CD(AuditProcessTracking);
//
// These two are strings rather than DWORDs
//
if (petPol->pTemplate->NewAdministratorName && pet->pTemplate->NewAdministratorName)
{
LocalFree(pet->pTemplate->NewAdministratorName);
pet->pTemplate->NewAdministratorName = NULL;
}
if (petPol->pTemplate->NewGuestName && pet->pTemplate->NewGuestName)
{
LocalFree(pet->pTemplate->NewGuestName);
pet->pTemplate->NewGuestName = NULL;
}
#undef CD
//
// Clear privileges set in PetPol out of pet
//
SCE_PRIVILEGE_ASSIGNMENT *ppaPet = pet->pTemplate->OtherInfo.smp.pPrivilegeAssignedTo;
SCE_PRIVILEGE_ASSIGNMENT *ppaPol = petPol->pTemplate->OtherInfo.smp.pPrivilegeAssignedTo;
SCE_PRIVILEGE_ASSIGNMENT *ppaLast = NULL;
for(SCE_PRIVILEGE_ASSIGNMENT *ppa = ppaPol; ppa != NULL ; ppa = ppa->Next)
{
for (SCE_PRIVILEGE_ASSIGNMENT *ppa2 = ppaPet;
ppa2 != NULL;
ppaLast = ppa2, ppa2 = ppa2->Next) {
if (0 == lstrcmpi(ppa->Name,ppa2->Name))
{
if (ppaLast)
{
ppaLast->Next = ppa2->Next;
}
else
{
// Front of list
ppaPet = ppa2->Next;
}
ppa2->Next = NULL;
SceFreeMemory(ppa2,SCE_STRUCT_PRIVILEGE);
ppa2 = ppaLast;
//
// Found it, so don't bother checking the rest
//
break;
}
}
}
//
// Clear reg values set in PetPol out of pet
//
SCE_REGISTRY_VALUE_INFO *rvPet = pet->pTemplate->aRegValues;
SCE_REGISTRY_VALUE_INFO *rvPol = petPol->pTemplate->aRegValues;
for(DWORD i=0;i< petPol->pTemplate->RegValueCount;i++)
{
for (DWORD j=0;j<pet->pTemplate->RegValueCount;j++)
{
if (0 == lstrcmpi(rvPol[i].FullValueName,rvPet[j].FullValueName))
{
// Match. Delete Value from pet
if (rvPet[j].Value)
{
LocalFree(rvPet[j].Value);
rvPet[j].Value = NULL;
}
//
// Found it, so don't bother checking rest
//
break;
}
}
}
return TRUE;
}