|
|
//+--------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 1998.
//
// File: util.cpp
//
// Contents: Miscellaneous utility functions
//
// History:
//
//---------------------------------------------------------------------------
#include "stdafx.h"
#include "util.h"
#include "wrapper.h"
#include "defvals.h"
#include "resource.h"
#include <io.h>
#include "snapmgr.h"
extern "C" { #include "getuser.h"
}
#define ILLEGAL_FILENAME_CHARS L"\"+,;<=>"
#define ILLEGAL_FILENAME_CHARS1 L"\\\\ \\/ // /\\"
#define ILLEGAL_FILENAME_CHARS2 L"\\ /"
//////////////////////////////////////////////////////////////////////////////////////////
// CWriteHmtlFile body.
//
//+-------------------------------------------------------------------------------------------
// CWriteHtmlFile::CWriteHtmlFile
//
// Initialize the class.
//
//--------------------------------------------------------------------------------------------
CWriteHtmlFile::CWriteHtmlFile() { m_hFileHandle = INVALID_HANDLE_VALUE; m_bErrored = FALSE; }
//+-------------------------------------------------------------------------------------------
// CWriteHtmlFile::~CWriteHtmlFile
//
// Write the end of the html file and close the handle.
//
//--------------------------------------------------------------------------------------------
CWriteHtmlFile::~CWriteHtmlFile() { //
// Close the file handle, but don't delete the HTML file, unless there was an
// error during some write proccess.
//
Close(m_bErrored); }
//+-------------------------------------------------------------------------------------------
// CWriteHtmlFile::Close
//
// Closes the HTML file handle, if [bDelete] is true then the file is deleted.
//
// Arguments: [bDelete] - Close and delete the file.
//
// Returns: ERROR_SUCCESS;
//--------------------------------------------------------------------------------------------
DWORD CWriteHtmlFile::Close( BOOL bDelete ) { if(m_hFileHandle == INVALID_HANDLE_VALUE){ return ERROR_SUCCESS; }
if(bDelete){ CloseHandle(m_hFileHandle); DeleteFile(m_strFileName ); } else { Write( IDS_HTMLERR_END ); CloseHandle( m_hFileHandle ); }
m_hFileHandle = INVALID_HANDLE_VALUE; return ERROR_SUCCESS; }
//+-------------------------------------------------------------------------------------------
// CWriteHtmlFile::GetFileName
//
// Copies the file name associated with this class to [pstrFileName].
//
// Arguments: [pstrFileName] - A CString object which will contain the file name
// on return.
//
// Returns: 0 - If Create has not been called, or the HTML file is invalid for
// some reason. This could be caused by a bad write.
// The size in characters of the file name.
//
//--------------------------------------------------------------------------------------------
int CWriteHtmlFile::GetFileName( LPTSTR pszFileName, UINT nSize ) { if(m_strFileName.IsEmpty() || m_hFileHandle == INVALID_HANDLE_VALUE || m_bErrored){ return 0; }
if(pszFileName && (int)nSize > m_strFileName.GetLength()){ //This is a safe usage.
lstrcpy(pszFileName, m_strFileName); }
return m_strFileName.GetLength(); }
//+-------------------------------------------------------------------------------------------
// CWriteHtmlFile::Write
//
// Writes a string resource to the html file at the current file position.
//
// Arguments: [uRes] - The String resource to load and write to the html.
//
// Returns: If the string can't be loaded then an error will be returned.
// See CWriteHtmlFile::Write( LPCTSTR ) for other errors.
//--------------------------------------------------------------------------------------------
DWORD CWriteHtmlFile::Write( UINT uRes ) { AFX_MANAGE_STATE(AfxGetStaticModuleState());
CString str; if( !str.LoadString(uRes) ){ return GetLastError(); }
#if defined(UNICODE) || defined(_UNICODE)
if ( uRes == IDS_HTMLERR_HEADER ){ WCHAR wszByteOrderMark[2] = {0xFEFF, 0x0000}; CString strByteOrderMark = wszByteOrderMark; return Write( strByteOrderMark + str ); } else #endif
return Write( str ); }
//+-------------------------------------------------------------------------------------------
// CWriteHtmlFile::Write
//
// Writes a string to an html file.
//
// Arguments: [pszString] - The string to write.
//
// Returns: ERROR_NOT_READ - if Create has not been called, or the file could not
// not be created.
// Other errors returned by WriteFile();
//--------------------------------------------------------------------------------------------
DWORD CWriteHtmlFile::Write(LPCTSTR pszString, ... ) { if(m_hFileHandle == INVALID_HANDLE_VALUE) { return ERROR_NOT_READY; }
CString szWrite;
va_list marker; va_start(marker, pszString);
//This is not a safe usage. Avoid using vswprintf(). Raid #555867. Yanggao.
szWrite.FormatV(pszString, marker);
va_end(marker);
DWORD dwRight; if( !WriteFile( m_hFileHandle, szWrite, sizeof(TCHAR) * szWrite.GetLength(), &dwRight, NULL) ) { //
// Check the error state of the right. Set m_bErrored if there was something wrong
// with the write.
//
dwRight = GetLastError(); if(dwRight != ERROR_SUCCESS) { m_bErrored = TRUE; } } else { dwRight = ERROR_SUCCESS; }
return dwRight; }
DWORD CWriteHtmlFile::CopyTextFile( LPCTSTR pszFile, DWORD dwPosLow, BOOL bInterpret ) { HANDLE handle;
//
// Try to open the file for reading.
//
handle = ExpandAndCreateFile( pszFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL ); if(handle == INVALID_HANDLE_VALUE) { return GetLastError(); }
LONG dwPosHigh = 0; WCHAR szText[256]; char szRead[256];
BOOL IsMulti; DWORD isUnicode;
//
// Determine if the file is a unicode text file.
//
if( ReadFile(handle, szText, 100 * sizeof(WCHAR), (DWORD *)&dwPosHigh, NULL ) == 0 ) //Raid #prefast
{ CloseHandle(handle ); return GetLastError(); } if(dwPosHigh ) { isUnicode = IsTextUnicode( szText, dwPosHigh, NULL ); }
//
// Set the pos we want to start from
//
dwPosHigh = 0; SetFilePointer( handle, dwPosLow, &dwPosHigh, FILE_BEGIN ); if( GetLastError() != ERROR_SUCCESS ) { CloseHandle(handle ); return GetLastError(); }
DWORD dwErr = ERROR_SUCCESS; do { start: //
// Read 254 total bytes from the file. We don't care about the error returned
// by read, as long as read does not set dwPosHigh to something.
//
dwPosHigh = 0; if( ReadFile( handle, szRead, 254, (DWORD *)&dwPosHigh, NULL ) == 0 || dwPosHigh == 0) //Raid #prefast
{ CloseHandle(handle ); return GetLastError(); }
//
// If the file is not considered unicode then convert it to a unicode file.
//
ZeroMemory(szText, sizeof(WCHAR) * 256); if(!isUnicode) { //This is a safe usage.
dwPosHigh = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szRead, dwPosHigh, szText, 255 ); } else { //
// Just copy the text to the szText buffer and get the number of UNICODE
// characters.
//
//This is a safe usage.
memcpy(szText, szRead, dwPosHigh); dwPosHigh = wcslen(szText); }
PWSTR pszWrite = szText; LONG i = 0; if( bInterpret ) { //
// Write out line breaks.
//
for(;i < dwPosHigh; i++) { //Bug 141526, Yanggao, 3/20/2001
if( L'<' == szText[i] ) { szText[i] = 0; Write(pszWrite); Write(L"<"); pszWrite = &(szText[i + 1]); } if( L'%' == szText[i] ) //Raid #624384,Yanggao
{ szText[i] = 0; Write(pszWrite); Write(L"%%"); pszWrite = &(szText[i + 1]); }
if( L'\r' == szText[i] || L'\n' == szText[i] ) { if( i + 1 >= dwPosHigh ) { szText[i] = 0; Write(pszWrite);
SetFilePointer( handle, -(isUnicode ? 2:1), NULL, FILE_CURRENT); //
// Read once again.
//
goto start; }
//
// Check to see if this is a valid line break
//
i++; if( L'\r' == szText[i] || L'\n' == szText[i] && szText[i] != szText[i - 1] ) { szText[i - 1] = 0;
dwErr = Write( pszWrite ); if( dwErr != ERROR_SUCCESS) { break; } dwErr = Write( L"<BR>" ); if( dwErr != ERROR_SUCCESS) { break; }
pszWrite = &(szText[i + 1]); } else { //
// This is not a valid line break, contintue with check with next character
//
i--; } } } }
//
// Write the rest of the text.
//
if(dwErr == ERROR_SUCCESS) { Write( pszWrite ); } else { break; }
} while( dwPosHigh );
CloseHandle(handle ); return ERROR_SUCCESS; }
//+-------------------------------------------------------------------------------------------
// CWriteHtmlFile::Create
//
// Creates an html file, and starts the write proccess. If [pszFile] is null, then
// this function creates a temporary file in the GetTempPath() directory with a name
// like SCE###.HTM
//
// Arguments: [pszFile] - Optional parameter for file name
//
// returns: ERROR_SUCCESS - If creating the file was successful.
// If the file exists then ERROR_FILE_EXISTS is returned.
//
//--------------------------------------------------------------------------------------------
DWORD CWriteHtmlFile::Create(LPCTSTR pszFile ) { if(!pszFile){ //
// Create a temporary file name.
//
DWORD dwSize = GetTempPath(0, NULL); if(dwSize){ TCHAR szTempFile[512];
//
// Get the temp path.
//
LPTSTR pszPath = (LPTSTR)LocalAlloc( 0, (dwSize + 1) * sizeof(TCHAR)); if(!pszPath){ return ERROR_OUTOFMEMORY; } GetTempPath( dwSize + 1, pszPath );
pszPath[dwSize - 1] = 0; if( GetTempFileName( pszPath, TEXT("SCE"), 0, szTempFile) ){ //This is not safe usage. Raid #555912, yanggao.
LocalFree(pszPath);
//
// Create the temporary file.
//
DeleteFile( szTempFile ); int i = lstrlen(szTempFile); while(i--){ if( szTempFile[i] == L'.' ){ break; } }
if(i + 3 >= lstrlen(szTempFile)){ return ERROR_OUTOFMEMORY; }
//
// We want to create an html file.
//
i++; szTempFile[i] = L'h'; szTempFile[i + 1] = L't'; szTempFile[i + 2] = L'm';
m_strFileName = szTempFile; } else { LocalFree(pszPath); } } } else { m_strFileName = pszFile; }
if(m_strFileName.IsEmpty()){ return ERROR_FILE_NOT_FOUND; }
//
// Open the file for writing
//
m_hFileHandle = ExpandAndCreateFile( m_strFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL ); if(m_hFileHandle == INVALID_HANDLE_VALUE){ return GetLastError(); }
//
// Write HTML header
//
return Write( IDS_HTMLERR_HEADER ); }
//+--------------------------------------------------------------------------
//
// Function: MyRegQueryValue
//
// Synopsis: Reads a registry value into [*Value]
//
//
// Arguments: [hKeyRoot] -
// [SubKey] -
// [ValueName] -
// [Value] -
// [pRegType] -
//
// Modifies: *[Value]
// *[pRegType]
//
// History:
//
//---------------------------------------------------------------------------
DWORD MyRegQueryValue( HKEY hKeyRoot, LPCTSTR SubKey, LPCTSTR ValueName, PVOID *Value, LPDWORD pRegType ) { DWORD Rcode; DWORD dSize=0; HKEY hKey=NULL; BOOL FreeMem=FALSE;
if (( Rcode = RegOpenKeyEx(hKeyRoot, SubKey, 0, KEY_READ, &hKey )) == ERROR_SUCCESS ) { //This is a safe usage. It only queries data type.
if (( Rcode = RegQueryValueEx(hKey, ValueName, 0, pRegType, NULL, &dSize )) == ERROR_SUCCESS ) { switch (*pRegType) { case REG_DWORD: case REG_DWORD_BIG_ENDIAN: //This is a safe usage. The data type is not REG_SZ.
Rcode = RegQueryValueEx(hKey, ValueName, 0, pRegType, (BYTE *)(*Value), &dSize ); if ( Rcode != ERROR_SUCCESS ) {
if ( *Value != NULL ) *((BYTE *)(*Value)) = 0; } break;
case REG_SZ: case REG_EXPAND_SZ: case REG_MULTI_SZ: if ( *Value == NULL ) { *Value = (PVOID)LocalAlloc( LPTR, (dSize+1)*sizeof(TCHAR)); FreeMem = TRUE; }
if ( *Value == NULL ) { Rcode = ERROR_NOT_ENOUGH_MEMORY; } else { //This is not a safe usage. make sure *Value is terminated. Raid #555873. yanggao.
Rcode = RegQueryValueEx(hKey,ValueName,0, pRegType,(BYTE *)(*Value), &dSize );
if ( (Rcode != ERROR_SUCCESS) && FreeMem ) { LocalFree(*Value); *Value = NULL; } }
break; default:
Rcode = ERROR_INVALID_DATATYPE;
break; } } }
if ( hKey ) { RegCloseKey( hKey ); }
return(Rcode); }
//+--------------------------------------------------------------------------
//
// Function: MyRegSetValue
//
// Synopsis: Writes a registry value into [*Value]
//
//
// Arguments: [hKeyRoot] -
// [SubKey] -
// [ValueName] -
// [Value] -
// [cbValue] -
// [pRegType] -
//
//
// History:
//
//---------------------------------------------------------------------------
DWORD MyRegSetValue( HKEY hKeyRoot, LPCTSTR SubKey, LPCTSTR ValueName, const BYTE *Value, const DWORD cbValue, const DWORD pRegType ) { DWORD Rcode=0; HKEY hKey=NULL; BOOL FreeMem=FALSE;
if (( Rcode = RegCreateKeyEx(hKeyRoot, SubKey, 0, 0, 0, KEY_READ|KEY_SET_VALUE|KEY_CREATE_SUB_KEY, NULL, &hKey, NULL)) == ERROR_SUCCESS ) { Rcode = RegSetValueEx(hKey, ValueName, 0, pRegType, Value, cbValue ); }
if ( hKey ) { RegCloseKey( hKey ); }
return(Rcode); }
BOOL FilePathExist(LPCTSTR Name, BOOL IsPath, int Flag) // Flag = 0 - check file, Flag = 1 - check path
{ // TODO:
struct _wfinddata_t FileInfo; intptr_t hFile; BOOL bExist = FALSE;
if ( (IsPath && Flag == 1) || (!IsPath && Flag == 0) ) { // must be exact match
hFile = _wfindfirst((LPTSTR)Name, &FileInfo); if ( hFile != -1 ) {// find it
if ( FileInfo.attrib & _A_SUBDIR ) { if ( Flag == 1) bExist = TRUE; } else if ( Flag == 0 ) bExist = TRUE; } _findclose(hFile); return bExist; }
if ( IsPath && Flag == 0 ) { // invalid parameter
return bExist; }
// IsPath = FALSE and Flag == 1 (a file name is passed in and search for its path)
CString tmpstr = CString(Name); int nPos = tmpstr.ReverseFind(L'\\');
if ( nPos > 2 ) { hFile = _wfindfirst(tmpstr.GetBufferSetLength(nPos), &FileInfo); if ( hFile != -1 && FileInfo.attrib & _A_SUBDIR ) bExist = TRUE;
_findclose(hFile); } else if ( nPos == 2 && Name[1] == L':') bExist = TRUE;
return bExist; }
//+--------------------------------------------------------------------------
//
// Function: MyFormatResMessage
//
// Synopsis: Creates an error message combining a description of an error
// returned from an SCE function (in rc), the extended description
// of that error (in errBuf), and a custom error message
// (in residMessage)
//
// Arguments: [rc] - The return code of an SCE function
// [residMessage] - the resource id of the base error message
// [errBuf] - Extended error info returned from an SCE function
// [strOut] - A CString to hold the formatted message
//
// Modifies: [strOut]
//
// History:
//
//---------------------------------------------------------------------------
void MyFormatResMessage(SCESTATUS rc, // in
UINT residMessage, // in
PSCE_ERROR_LOG_INFO errBuf,// in, optional
CString& strOut) // out
{ CString strMessage;
AFX_MANAGE_STATE(AfxGetStaticModuleState());
//
// If the LoadResource fails then strMessage will be empty
// It'll still be better to format the rest of the message than
// to return an empty strOut.
//
strMessage.LoadString(residMessage);
MyFormatMessage(rc,strMessage,errBuf,strOut); }
//+--------------------------------------------------------------------------
//
// Function: MyFormatMessage
//
// Synopsis: Creates an error message combining a description of an error
// returned from an SCE function (in rc), the extended description
// of that error (in errBuf), and a custom error message (in mes)
//
// Arguments: [rc] - The return code of an SCE function
// [mes] - The base message
// [errBuf] - Extended error info returned from an SCE function
// [strOut] - A CString to hold the formatted message
//
// Modifies: [strOut]
//
// History:
//
//---------------------------------------------------------------------------
void MyFormatMessage(SCESTATUS rc, // in
LPCTSTR mes, // in
PSCE_ERROR_LOG_INFO errBuf, // in, optional
CString& strOut) // out
{ LPVOID lpMsgBuf=NULL;
if ( rc != SCESTATUS_SUCCESS ) {
//
// translate SCESTATUS into DWORD
//
DWORD win32 = SceStatusToDosError(rc);
//
// get error description of rc
//
//This is a safe usage. The function is responsible to allocate memery.
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, win32, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR)&lpMsgBuf, 0, NULL ); }
if ( lpMsgBuf != NULL ) { strOut = (LPTSTR)lpMsgBuf; LocalFree(lpMsgBuf); lpMsgBuf = NULL; } else { strOut.Empty(); }
CString strEx; //Raid #485372, yanggao, 11/30/2001
switch(rc) { case SCESTATUS_INVALID_PARAMETER: case SCESTATUS_RECORD_NOT_FOUND: case SCESTATUS_INVALID_DATA: case SCESTATUS_OBJECT_EXIST: case SCESTATUS_PROFILE_NOT_FOUND: strEx.LoadString(IDS_OBJECT_FAILED_NOTE); break; case SCESTATUS_ACCESS_DENIED: case SCESTATUS_CANT_DELETE: strEx.LoadString(IDS_SAVE_FAILED_NOTE); break; case SCESTATUS_PREFIX_OVERFLOW: case SCESTATUS_ALREADY_RUNNING: case SCESTATUS_OTHER_ERROR: case SCESTATUS_BUFFER_TOO_SMALL: case SCESTATUS_BAD_FORMAT: case SCESTATUS_NOT_ENOUGH_RESOURCE: default: strEx.Empty(); break; }
if( strEx.IsEmpty() ) { strOut += mes; } else { strOut = strOut + mes + L" " + strEx; } strOut += L"\n";
//
// Loop through the error buffers and append each of them to strOut
//
for (PSCE_ERROR_LOG_INFO pErr = errBuf; pErr != NULL; pErr = pErr->next) {
if (NULL == pErr) { continue; } if ( pErr->rc != NO_ERROR) { //This is a safe usage. The function is responsible to allocate memery.
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, pErr->rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR)&lpMsgBuf, 0, NULL ); if ( lpMsgBuf ) { strOut += (LPTSTR)lpMsgBuf; LocalFree(lpMsgBuf); lpMsgBuf = NULL; } } if (pErr->buffer) { strOut += pErr->buffer; strOut += L"\n"; }
} }
DWORD FormatDBErrorMessage( SCESTATUS sceStatus, LPCTSTR pszDatabase, CString &strOut ) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); UINT uErr = 0;
switch (sceStatus) { case SCESTATUS_SUCCESS: return ERROR_INVALID_PARAMETER; case SCESTATUS_INVALID_DATA: uErr = IDS_DBERR_INVALID_DATA; break; case SCESTATUS_PROFILE_NOT_FOUND: uErr = IDS_DBERR5_PROFILE_NOT_FOUND; break; case SCESTATUS_BAD_FORMAT: uErr = IDS_DBERR_BAD_FORMAT; break; case SCESTATUS_BUFFER_TOO_SMALL: case SCESTATUS_NOT_ENOUGH_RESOURCE: uErr = IDS_DBERR_NOT_ENOUGH_RESOURCE; break; case SCESTATUS_ACCESS_DENIED: uErr = IDS_DBERR5_ACCESS_DENIED; break; case SCESTATUS_NO_TEMPLATE_GIVEN: uErr = IDS_DBERR_NO_TEMPLATE_GIVEN; break; case SCESTATUS_SPECIAL_ACCOUNT: //Raid #589139, DCR, yanggao, 4/10/2002.
uErr = IDS_ERR_PRIVILEGE; //.Net use IDS_ERR_PRIVILEGE instead of IDS_DBERR5_ACCESS_DENIED which is used for XPSP1.
break; case ERROR_NONE_MAPPED: //Raid #625342
uErr = IDS_NO_ACCOUNT_MAP; break; default: uErr = IDS_DBERR_OTHER_ERROR; }
if ( strOut.LoadString(uErr) ) { return ERROR_SUCCESS; } return ERROR_INVALID_PARAMETER; }
DWORD SceStatusToDosError(SCESTATUS SceStatus) { switch (SceStatus) {
case SCESTATUS_SUCCESS: return(NO_ERROR);
case SCESTATUS_OTHER_ERROR: return(ERROR_EXTENDED_ERROR);
case SCESTATUS_INVALID_PARAMETER: return(ERROR_INVALID_PARAMETER);
case SCESTATUS_RECORD_NOT_FOUND: return(ERROR_RESOURCE_DATA_NOT_FOUND);
case SCESTATUS_INVALID_DATA: return(ERROR_INVALID_DATA);
case SCESTATUS_OBJECT_EXIST: return(ERROR_FILE_EXISTS);
case SCESTATUS_BUFFER_TOO_SMALL: return(ERROR_INSUFFICIENT_BUFFER);
case SCESTATUS_PROFILE_NOT_FOUND: return(ERROR_FILE_NOT_FOUND);
case SCESTATUS_BAD_FORMAT: return(ERROR_BAD_FORMAT);
case SCESTATUS_NOT_ENOUGH_RESOURCE: return(ERROR_NOT_ENOUGH_MEMORY);
case SCESTATUS_ACCESS_DENIED: case SCESTATUS_SPECIAL_ACCOUNT: //Raid #589139, DCR, yanggao, 4/10/2002.
return(ERROR_ACCESS_DENIED);
case SCESTATUS_CANT_DELETE: return(ERROR_CURRENT_DIRECTORY);
case SCESTATUS_PREFIX_OVERFLOW: return(ERROR_BUFFER_OVERFLOW);
case SCESTATUS_ALREADY_RUNNING: return(ERROR_SERVICE_ALREADY_RUNNING);
default: return(ERROR_EXTENDED_ERROR); } }
//+--------------------------------------------------------------------------
//
// Function: CreateNewProfile
//
// Synopsis: Create a new tempate with default values in the ProfileName location
//
// Returns: TRUE if a template ends up in the ProfileName file
// FALSE otherwise
//
// History:
//
//---------------------------------------------------------------------------
BOOL CreateNewProfile(CString ProfileName,PSCE_PROFILE_INFO *ppspi) { SCESTATUS status; SCE_PROFILE_INFO *pTemplate; //
// profile name must end with .inf
//
int nLen = ProfileName.GetLength (); // start searching at the last 4 position
if ( ProfileName.Find (L".inf", nLen-4) != nLen-4 ) { return FALSE; }
//
// if the profile already exists then we don't need to do anything
//
if ( FilePathExist( (LPCTSTR)ProfileName, FALSE, 0) ) { return TRUE; }
//
// Make sure the directory for the profile exists
//
status = SceCreateDirectory(ProfileName,FALSE,NULL); if (SCESTATUS_SUCCESS != status) { return FALSE; }
pTemplate = (SCE_PROFILE_INFO*)LocalAlloc(LPTR,sizeof(SCE_PROFILE_INFO)); if (!pTemplate) { return FALSE; }
#ifdef FILL_WITH_DEFAULT_VALUES
SCE_PROFILE_INFO *pDefault = GetDefaultTemplate(); //
// Fill with default values
//
pTemplate->Type = SCE_ENGINE_SCP;
#define CD(X) pTemplate->X = pDefault->X;
#else // !FILL_WITH_DEFAULT_VALUES
#define CD(X) pTemplate->X = SCE_NO_VALUE;
#endif // !FILL_WITH_DEFAULT_VALUES
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);
#ifdef FILL_WITH_DEFAULT_VALUES
//
// These two are strings rather than DWORDs
//
if (pDefault->NewAdministratorName) { pTemplate->NewAdministratorName = (LPTSTR) LocalAlloc(LPTR,(lstrlen(pDefault->NewAdministratorName)+1)*sizeof(TCHAR)); if (pTemplate->NewAdministratorName) { //This may not be a safe usage. pTemplate->NewAdministratorName and pDefault->NewAdministratorName are both PWSTR. Consider fix.
lstrcpy(pTemplate->NewAdministratorName, pDefault->NewAdministratorName); } } if (pDefault->NewGuestName) { pTemplate->NewGuestName = (LPTSTR) LocalAlloc(LPTR,(lstrlen(pDefault->NewGuestName)+1)*sizeof(TCHAR)); if (pTemplate->NewGuestName) { //This may not be a safe usage. pTemplate->NewGuestName and pDefault->NewGuestName are both PWSTR. Consider fix.
lstrcpy(pTemplate->NewGuestName, pDefault->NewGuestName); } } #endif // FILL_WITH_DEFAULT_VALUES
#undef CD
status = SceWriteSecurityProfileInfo(ProfileName, AREA_ALL, pTemplate, NULL); if (ppspi) { *ppspi = pTemplate; } else { SceFreeProfileMemory(pTemplate); }
return (SCESTATUS_SUCCESS == status); }
BOOL VerifyKerberosInfo(PSCE_PROFILE_INFO pspi) { if (pspi->pKerberosInfo) { return TRUE; } pspi->pKerberosInfo = (PSCE_KERBEROS_TICKET_INFO) LocalAlloc(LPTR,sizeof(SCE_KERBEROS_TICKET_INFO));
if (pspi->pKerberosInfo) { pspi->pKerberosInfo->MaxTicketAge = SCE_NO_VALUE; pspi->pKerberosInfo->MaxRenewAge = SCE_NO_VALUE; pspi->pKerberosInfo->MaxServiceAge = SCE_NO_VALUE; pspi->pKerberosInfo->MaxClockSkew = SCE_NO_VALUE; pspi->pKerberosInfo->TicketValidateClient = SCE_NO_VALUE; return TRUE; } return FALSE; }
BOOL SetProfileInfo(LONG_PTR dwItem,LONG_PTR dwNew,PEDITTEMPLATE pEdit) { if (!pEdit) { return FALSE; } pEdit->SetDirty(AREA_SECURITY_POLICY);
switch (dwItem) { case IDS_MAX_PAS_AGE: pEdit->pTemplate->MaximumPasswordAge = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_MIN_PAS_AGE: pEdit->pTemplate->MinimumPasswordAge = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_MIN_PAS_LEN: pEdit->pTemplate->MinimumPasswordLength = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_PAS_UNIQUENESS: pEdit->pTemplate->PasswordHistorySize = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_PAS_COMPLEX: pEdit->pTemplate->PasswordComplexity = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_REQ_LOGON: pEdit->pTemplate->RequireLogonToChangePassword = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_LOCK_COUNT: pEdit->pTemplate->LockoutBadCount = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_LOCK_RESET_COUNT: pEdit->pTemplate->ResetLockoutCount = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_LOCK_DURATION: pEdit->pTemplate->LockoutDuration = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_FORCE_LOGOFF: pEdit->pTemplate->ForceLogoffWhenHourExpire = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_ENABLE_ADMIN: pEdit->pTemplate->EnableAdminAccount = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_ENABLE_GUEST: pEdit->pTemplate->EnableGuestAccount = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_LSA_ANON_LOOKUP: pEdit->pTemplate->LSAAnonymousNameLookup = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_NEW_ADMIN: if (pEdit->pTemplate->NewAdministratorName) { LocalFree(pEdit->pTemplate->NewAdministratorName); } if (dwNew && (dwNew != (LONG_PTR)ULongToPtr(SCE_NO_VALUE))) { pEdit->pTemplate->NewAdministratorName = (PWSTR)LocalAlloc(LPTR,(lstrlen((PWSTR)dwNew)+1)*sizeof(WCHAR)); if (pEdit->pTemplate->NewAdministratorName) { //This may not be a safe usage. pTemplate->NewAdministratorName and dwNew are both PWSTR. Consider fix.
lstrcpy(pEdit->pTemplate->NewAdministratorName,(PWSTR)dwNew); } } else { pEdit->pTemplate->NewAdministratorName = NULL; } break; case IDS_NEW_GUEST: if (pEdit->pTemplate->NewGuestName) { LocalFree(pEdit->pTemplate->NewGuestName); } if (dwNew && (dwNew != (LONG_PTR)ULongToPtr(SCE_NO_VALUE))) { pEdit->pTemplate->NewGuestName = (PWSTR)LocalAlloc(LPTR,(lstrlen((PWSTR)dwNew)+1)*sizeof(WCHAR)); if (pEdit->pTemplate->NewGuestName) { //This may not be a safe usage. pTemplate->NewGuestName and dwNew are both PWSTR. Consider fix.
lstrcpy(pEdit->pTemplate->NewGuestName,(PWSTR)dwNew); } } else { pEdit->pTemplate->NewGuestName = NULL; } break; case IDS_SYS_LOG_MAX: pEdit->pTemplate->MaximumLogSize[EVENT_TYPE_SYSTEM] = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_SYS_LOG_RET: pEdit->pTemplate->AuditLogRetentionPeriod[EVENT_TYPE_SYSTEM] = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_SYS_LOG_DAYS: pEdit->pTemplate->RetentionDays[EVENT_TYPE_SYSTEM] = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_SEC_LOG_MAX: pEdit->pTemplate->MaximumLogSize[EVENT_TYPE_SECURITY] = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_SEC_LOG_RET: pEdit->pTemplate->AuditLogRetentionPeriod[EVENT_TYPE_SECURITY] = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_SEC_LOG_DAYS: pEdit->pTemplate->RetentionDays[EVENT_TYPE_SECURITY] = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_APP_LOG_MAX: pEdit->pTemplate->MaximumLogSize[EVENT_TYPE_APP] = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_APP_LOG_RET: pEdit->pTemplate->AuditLogRetentionPeriod[EVENT_TYPE_APP] = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_APP_LOG_DAYS: pEdit->pTemplate->RetentionDays[EVENT_TYPE_APP] = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_SYSTEM_EVENT: pEdit->pTemplate->AuditSystemEvents = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_LOGON_EVENT: pEdit->pTemplate->AuditLogonEvents = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_OBJECT_ACCESS: pEdit->pTemplate->AuditObjectAccess = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_PRIVILEGE_USE: pEdit->pTemplate->AuditPrivilegeUse = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_POLICY_CHANGE: pEdit->pTemplate->AuditPolicyChange = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_ACCOUNT_MANAGE: pEdit->pTemplate->AuditAccountManage = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_PROCESS_TRACK: pEdit->pTemplate->AuditProcessTracking = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_DIRECTORY_ACCESS: pEdit->pTemplate->AuditDSAccess = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_ACCOUNT_LOGON: pEdit->pTemplate->AuditAccountLogon = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_SYS_LOG_GUEST: pEdit->pTemplate->RestrictGuestAccess[EVENT_TYPE_SYSTEM] = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_SEC_LOG_GUEST: pEdit->pTemplate->RestrictGuestAccess[EVENT_TYPE_SECURITY] = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_APP_LOG_GUEST: pEdit->pTemplate->RestrictGuestAccess[EVENT_TYPE_APP] = (DWORD)PtrToUlong((PVOID)dwNew); break; case IDS_CLEAR_PASSWORD: pEdit->pTemplate->ClearTextPassword = (DWORD)PtrToUlong((PVOID)dwNew); break;
case IDS_KERBEROS_MAX_SERVICE: if (VerifyKerberosInfo(pEdit->pTemplate)) { pEdit->pTemplate->pKerberosInfo->MaxServiceAge = (DWORD)PtrToUlong((PVOID)dwNew); } break; case IDS_KERBEROS_MAX_CLOCK: if (VerifyKerberosInfo( pEdit->pTemplate)) { pEdit->pTemplate->pKerberosInfo->MaxClockSkew = (DWORD)PtrToUlong((PVOID)dwNew); } break; case IDS_KERBEROS_VALIDATE_CLIENT: if (VerifyKerberosInfo( pEdit->pTemplate)) { pEdit->pTemplate->pKerberosInfo->TicketValidateClient = (DWORD)PtrToUlong((PVOID)dwNew); } break;
case IDS_KERBEROS_MAX_AGE: if (VerifyKerberosInfo( pEdit->pTemplate)) { pEdit->pTemplate->pKerberosInfo->MaxTicketAge = (DWORD)PtrToUlong((PVOID)dwNew); } break; case IDS_KERBEROS_RENEWAL: if (VerifyKerberosInfo( pEdit->pTemplate)) { pEdit->pTemplate->pKerberosInfo->MaxRenewAge = (DWORD)PtrToUlong((PVOID)dwNew); } break; default: return FALSE; } return TRUE;
}
//
// FUNCTION: ErrorHandlerEx(WORD, LPSTR)
//
// PURPOSE: Calls GetLastError() and uses FormatMessage() to display the
// textual information of the error code along with the file
// and line number.
//
// PARAMETERS:
// wLine - line number where the error occured
// lpszFile - file where the error occured
//
// RETURN VALUE:
// none
//
// COMMENTS:
// This function has a macro ErrorHandler() which handles filling in
// the line number and file name where the error occured. ErrorHandler()
// is always used instead of calling this function directly.
//
void ErrorHandlerEx( WORD wLine, LPTSTR lpszFile ) { LPVOID lpvMessage; DWORD dwError; CString szBuffer;
// The the text of the error message
//This is a safe usage.
dwError = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), (LPTSTR)&lpvMessage, 0, NULL);
// Check to see if an error occured calling FormatMessage()
if (0 == dwError) { //This is not a safe usage. avoid using wsprintf. Raid #555867. Yanggao.
szBuffer.Format(TEXT("An error occured calling FormatMessage().") TEXT("Error Code %d"), GetLastError()); MessageBox(NULL, szBuffer, TEXT("Security Configuration Editor"), MB_ICONSTOP | MB_ICONEXCLAMATION); return; }
// Display the error message
//This is not a safe usage. avoid using wsprinf. Raid #555867. Yanggao.
szBuffer.Format(TEXT("Generic, Line=%d, File=%s"), wLine, lpszFile); MessageBox(NULL, (LPTSTR)lpvMessage, szBuffer, MB_ICONEXCLAMATION | MB_OK);
return; }
BOOL GetSceStatusString(SCESTATUS status, CString *strStatus) { AFX_MANAGE_STATE(AfxGetStaticModuleState( )); if (!strStatus || (status > SCESTATUS_SERVICE_NOT_SUPPORT)) { return false; } return strStatus->LoadString(status + IDS_SCESTATUS_SUCCESS); }
//+---------------------------------------------------------------------------------------------
// EnumLangProc
//
// Creates the lanuage ID for the resource attached to the DLL. The function only enumerates
// on lanuage.
//
// Arguments: - See help on EnumResLangProc in the SDK Doc.
//
// Returns: - Returns FALSE because we only want the very first lanuage enumerated.
//
//+---------------------------------------------------------------------------------------------
BOOL CALLBACK EnumLangProc( HMODULE hMod, LPCTSTR pszType, LPCTSTR pszName, WORD wIDLanguage, LONG_PTR lParam ) { //
// We only want the very first enumerated type, so create the language ID
// and exit this enumeration.
//
*((DWORD *)lParam) = wIDLanguage; return FALSE; }
bool GetRightDisplayName(LPCTSTR szSystemName, LPCTSTR szName, LPTSTR szDisp, LPDWORD lpcbDisp) { LPTSTR szLCName; DWORD dwLang; int i;
if (!szDisp || !szName) { return false; }
//
// Enumerate our resource to find out what language the resource is in.
//
DWORD dwDefaultLang;
dwDefaultLang = GetUserDefaultUILanguage(); LCID localeID = MAKELCID(dwDefaultLang, SORT_DEFAULT);
LCID langDefault = GetThreadLocale(); SetThreadLocale( localeID );
*lpcbDisp = dwDefaultLang;
DWORD cBufSize=*lpcbDisp; BOOL bFound;
bFound = LookupPrivilegeDisplayName(szSystemName,szName,szDisp,lpcbDisp,&dwLang); if ( bFound && dwDefaultLang != dwLang && szSystemName ) { // not the language I am looking for
// search on local system
*lpcbDisp = cBufSize; bFound = LookupPrivilegeDisplayName(NULL,szName,szDisp,lpcbDisp,&dwLang); } SetThreadLocale(langDefault);
//Prefast warning 400: Using 'lstrcmpiW' to perform a case-insensitive compare to constant string.
//Yields unexpected result in non-English locales. Currently they are always English locale.
if (!bFound) { if (0 == _wcsicmp(szName,L"senetworklogonright")) { LoadString(AfxGetInstanceHandle(),IDS_SE_NETWORK_LOGON_RIGHT,szDisp,*lpcbDisp); } else if (0 == _wcsicmp(szName,L"seinteractivelogonright")) { LoadString(AfxGetInstanceHandle(),IDS_SE_INTERACTIVE_LOGON_RIGHT,szDisp,*lpcbDisp); } else if (0 == _wcsicmp(szName,L"sebatchlogonright")) { LoadString(AfxGetInstanceHandle(),IDS_SE_BATCH_LOGON_RIGHT,szDisp,*lpcbDisp); } else if (0 == _wcsicmp(szName,L"seservicelogonright")) { LoadString(AfxGetInstanceHandle(),IDS_SE_SERVICE_LOGON_RIGHT,szDisp,*lpcbDisp); } else if (0 == _wcsicmp(szName,L"sedenyinteractivelogonright")) { LoadString(AfxGetInstanceHandle(),IDS_DENY_LOGON_LOCALLY,szDisp,*lpcbDisp); } else if (0 == _wcsicmp(szName,L"sedenynetworklogonright")) { LoadString(AfxGetInstanceHandle(),IDS_DENY_LOGON_NETWORK,szDisp,*lpcbDisp); } else if (0 == _wcsicmp(szName,L"sedenyservicelogonright")) { LoadString(AfxGetInstanceHandle(),IDS_DENY_LOGON_SERVICE,szDisp,*lpcbDisp); } else if (0 == _wcsicmp(szName,L"sedenybatchlogonright")) { LoadString(AfxGetInstanceHandle(),IDS_DENY_LOGON_BATCH,szDisp,*lpcbDisp); } else if (0 == _wcsicmp(szName,L"sedenyremoteinteractivelogonright")) { LoadString(AfxGetInstanceHandle(),IDS_DENY_REMOTE_INTERACTIVE_LOGON,szDisp,*lpcbDisp); } else if (0 == _wcsicmp(szName,L"seremoteinteractivelogonright")) { LoadString(AfxGetInstanceHandle(),IDS_REMOTE_INTERACTIVE_LOGON,szDisp,*lpcbDisp); } else { //This is not a safe usage. Make sure szDisp is terminated. Raid #553113, yanggao
lstrcpyn(szDisp,szName,*lpcbDisp-1); } } return true; }
#define DPI(X) {str.Format(L"%S: %d\n",#X,pInfo->X);OutputDebugString(str);}
void DumpProfileInfo(PSCE_PROFILE_INFO pInfo) { CString str; PSCE_PRIVILEGE_ASSIGNMENT ppa; PSCE_NAME_LIST pName; PSCE_GROUP_MEMBERSHIP pgm;
if (!pInfo) { return; }
DPI(MinimumPasswordAge); DPI(MaximumPasswordAge); DPI(MinimumPasswordLength); DPI(PasswordComplexity); DPI(PasswordHistorySize); DPI(LockoutBadCount); DPI(ResetLockoutCount); DPI(LockoutDuration); DPI(RequireLogonToChangePassword); DPI(ForceLogoffWhenHourExpire); DPI(EnableAdminAccount); DPI(EnableGuestAccount); DPI(ClearTextPassword); DPI(AuditDSAccess); DPI(AuditAccountLogon); DPI(LSAAnonymousNameLookup); // DPI(EventAuditingOnOff);
DPI(AuditSystemEvents); DPI(AuditLogonEvents); DPI(AuditObjectAccess); DPI(AuditPrivilegeUse); DPI(AuditPolicyChange); DPI(AuditAccountManage); DPI(AuditProcessTracking);
if (pInfo->NewGuestName) { OutputDebugString(L"NewGuestName: "); if ((DWORD_PTR)ULongToPtr(SCE_NO_VALUE) == (DWORD_PTR)pInfo->NewGuestName) { OutputDebugString(L"[[undefined]]"); } else { OutputDebugString(pInfo->NewGuestName); } OutputDebugString(L"\n"); } else { OutputDebugString(L"NewGuestName: [[absent]]\n"); } if (pInfo->NewAdministratorName) { OutputDebugString(L"NewAdministratorName: "); if ((DWORD_PTR)ULongToPtr(SCE_NO_VALUE) == (DWORD_PTR)pInfo->NewAdministratorName) { OutputDebugString(L"[[undefined]]"); } else { OutputDebugString(pInfo->NewAdministratorName); } OutputDebugString(L"\n"); } else { OutputDebugString(L"NewGuestName: [[absent]]\n"); }
OutputDebugString(L"\n");
switch(pInfo->Type) { case SCE_ENGINE_SCP: ppa = pInfo->OtherInfo.scp.u.pInfPrivilegeAssignedTo; break; case SCE_ENGINE_SAP: ppa = pInfo->OtherInfo.sap.pPrivilegeAssignedTo; break; case SCE_ENGINE_SMP: ppa = pInfo->OtherInfo.smp.pPrivilegeAssignedTo; break; case SCE_ENGINE_SYSTEM: ppa = NULL; break; default: OutputDebugString(L"!!!Unknown Template Type!!!\n"); ppa = NULL; break; } while(ppa) { OutputDebugString(ppa->Name); OutputDebugString(L":"); pName = ppa->AssignedTo; while(pName) { OutputDebugString(pName->Name); OutputDebugString(L","); pName = pName->Next; } ppa = ppa->Next; OutputDebugString(L"\n"); } OutputDebugString(L"\n");
PSCE_REGISTRY_VALUE_INFO aRegValues; for(DWORD i = 0; i< pInfo->RegValueCount;i++) { OutputDebugString(pInfo->aRegValues[i].FullValueName); OutputDebugString(L":"); switch(pInfo->aRegValues[i].ValueType) { case SCE_REG_DISPLAY_STRING: OutputDebugString(pInfo->aRegValues[i].Value); break; default: str.Format(L"%d",(ULONG_PTR)pInfo->aRegValues[i].Value); OutputDebugString(str); } OutputDebugString(L"\n"); } OutputDebugString(L"\n");
pgm = pInfo->pGroupMembership; while(pgm) { OutputDebugString(L"\nGROUP: "); OutputDebugString(pgm->GroupName); OutputDebugString(L"\nMembers: "); pName = pgm->pMembers; while(pName) { OutputDebugString(pName->Name); OutputDebugString(L","); pName = pName->Next; } OutputDebugString(L"\nMember Of: "); pName = pgm->pMemberOf; while(pName) { OutputDebugString(pName->Name); OutputDebugString(L","); pName = pName->Next; } OutputDebugString(L"\n"); pgm = pgm->Next; } OutputDebugString(L"\nGROUP: "); }
HRESULT MyMakeSelfRelativeSD( PSECURITY_DESCRIPTOR psdOriginal, PSECURITY_DESCRIPTOR* ppsdNew ) { ASSERT( NULL != psdOriginal );
if ( NULL == psdOriginal || NULL == ppsdNew ) { return E_INVALIDARG; }
// we have to find out whether the original is already self-relative
SECURITY_DESCRIPTOR_CONTROL sdc = 0; DWORD dwRevision = 0; if ( !GetSecurityDescriptorControl( psdOriginal, &sdc, &dwRevision ) ) { ASSERT( FALSE ); DWORD err = GetLastError(); return HRESULT_FROM_WIN32( err ); }
DWORD cb = GetSecurityDescriptorLength( psdOriginal ) + 20; PSECURITY_DESCRIPTOR psdSelfRelativeCopy = (PSECURITY_DESCRIPTOR)LocalAlloc( LMEM_ZEROINIT, cb ); if (NULL == psdSelfRelativeCopy) { return E_UNEXPECTED; // just in case the exception is ignored
}
if ( sdc & SE_SELF_RELATIVE ) // the original is in self-relative format, just byte-copy it
{ //This is a safe usage.
memcpy( psdSelfRelativeCopy, psdOriginal, cb - 20 ); } else if ( !MakeSelfRelativeSD( psdOriginal, psdSelfRelativeCopy, &cb ) ) // the original is in absolute format, convert-copy it
{ ASSERT( FALSE ); VERIFY( NULL == LocalFree( psdSelfRelativeCopy ) ); DWORD err = GetLastError(); return HRESULT_FROM_WIN32( err ); } *ppsdNew = psdSelfRelativeCopy; return S_OK; }
PSCE_NAME_STATUS_LIST MergeNameStatusList(PSCE_NAME_LIST pTemplate, PSCE_NAME_LIST pInspect) { PSCE_NAME_LIST pTemp1; PSCE_NAME_STATUS_LIST plMerge=NULL, pTemp2; SCESTATUS rc=SCESTATUS_SUCCESS;
for ( pTemp1=pTemplate; pTemp1; pTemp1=pTemp1->Next ) {
rc = SceAddToNameStatusList(&plMerge, pTemp1->Name, 0, MERGED_TEMPLATE ); if ( SCESTATUS_SUCCESS != rc ) break; } if ( SCESTATUS_SUCCESS == rc ) { for ( pTemp1=pInspect; pTemp1; pTemp1=pTemp1->Next ) {
for ( pTemp2=plMerge; pTemp2 != NULL ; pTemp2=pTemp2->Next ) { if ( pTemp2->Status & MERGED_INSPECT ) { // this one is processed
continue; } else if ( _wcsicmp(pTemp1->Name, pTemp2->Name) == 0 ) { // find a match
pTemp2->Status = MERGED_TEMPLATE | MERGED_INSPECT; break; } } if ( !pTemp2 ) { // did not find the match, add this one in
rc = SceAddToNameStatusList(&plMerge, pTemp1->Name, 0, MERGED_INSPECT ); if ( SCESTATUS_SUCCESS != rc ) break; } } } if ( SCESTATUS_SUCCESS == rc ) { return plMerge; } else { SceFreeMemory(plMerge, SCE_STRUCT_NAME_STATUS_LIST); return NULL; } }
SCESTATUS ConvertMultiSzToDelim( IN PWSTR pValue, IN DWORD Len, IN WCHAR DelimFrom, IN WCHAR Delim ) /*
Convert the multi-sz delimiter \0 to space */ { DWORD i;
for ( i=0; i<Len && pValue; i++) { // if ( *(pValue+i) == L'\0' && *(pValue+i+1) != L'\0') {
if ( *(pValue+i) == DelimFrom && i+1 < Len && *(pValue+i+1) != L'\0' ) { //
// a NULL delimiter is encounted and it's not the end (double NULL)
//
*(pValue+i) = Delim; } }
return(SCESTATUS_SUCCESS); }
DWORD SceRegEnumAllValues( IN OUT PDWORD pCount, IN OUT PSCE_REGISTRY_VALUE_INFO *paRegValues ) /*
*/ { DWORD Win32Rc; HKEY hKey=NULL; PSCE_NAME_STATUS_LIST pnsList=NULL; DWORD nAdded=0;
Win32Rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE, SCE_ROOT_REGVALUE_PATH, 0, KEY_READ, &hKey );
DWORD cSubKeys = 0; DWORD nMaxLen;
if ( Win32Rc == ERROR_SUCCESS ) {
//
// enumerate all subkeys of the key
//
Win32Rc = RegQueryInfoKey ( hKey, NULL, NULL, NULL, &cSubKeys, &nMaxLen, NULL, NULL, NULL, NULL, NULL, NULL ); }
if ( Win32Rc == ERROR_SUCCESS && cSubKeys > 0 ) {
PWSTR szName = (PWSTR)LocalAlloc(0, (nMaxLen+2)*sizeof(WCHAR));
if ( !szName ) { Win32Rc = ERROR_NOT_ENOUGH_MEMORY;
} else {
DWORD BufSize; DWORD index = 0; DWORD RegType;
do {
BufSize = nMaxLen+1; Win32Rc = RegEnumKeyEx( hKey, index, szName, &BufSize, NULL, NULL, NULL, NULL);
if ( ERROR_SUCCESS == Win32Rc ) {
index++;
//
// get the full registry key name and Valuetype
//
cSubKeys = REG_SZ; PDWORD pType = &cSubKeys;
//
// query ValueType, if error, default REG_SZ
//
MyRegQueryValue( hKey, szName, SCE_REG_VALUE_TYPE, (PVOID *)&pType, &RegType );
if ( cSubKeys < REG_SZ || cSubKeys > REG_MULTI_SZ ) { cSubKeys = REG_SZ; }
//
// convert the path name
//
ConvertMultiSzToDelim(szName, BufSize, L'/', L'\\');
//
// compare with the input array, if not exist,
// add it
//
for ( DWORD i=0; i<*pCount; i++ ) { if ( (*paRegValues)[i].FullValueName && _wcsicmp(szName, (*paRegValues)[i].FullValueName) == 0 ) { break; } }
if ( i >= *pCount ) { //
// did not find a match, add it
//
if ( SCESTATUS_SUCCESS != SceAddToNameStatusList(&pnsList, szName, BufSize, cSubKeys) ) {
Win32Rc = ERROR_NOT_ENOUGH_MEMORY; break; } nAdded++; }
} else if ( ERROR_NO_MORE_ITEMS != Win32Rc ) { break; }
} while ( Win32Rc != ERROR_NO_MORE_ITEMS );
if ( Win32Rc == ERROR_NO_MORE_ITEMS ) { Win32Rc = ERROR_SUCCESS; }
//
// free the enumeration buffer
//
LocalFree(szName); } }
if ( hKey ) {
RegCloseKey(hKey); }
if ( ERROR_SUCCESS == Win32Rc ) { //
// add the name list to the output arrays
//
DWORD nNewCount = *pCount + nAdded; PSCE_REGISTRY_VALUE_INFO aNewArray;
if ( nNewCount ) {
aNewArray = (PSCE_REGISTRY_VALUE_INFO)LocalAlloc(0, nNewCount*sizeof(SCE_REGISTRY_VALUE_INFO)); if ( aNewArray ) { ZeroMemory(aNewArray, nNewCount * sizeof(SCE_REGISTRY_VALUE_INFO)); //This is a safe usage.
memcpy( aNewArray, *paRegValues, *pCount * sizeof( SCE_REGISTRY_VALUE_INFO ) ); DWORD i;
i=0; for ( PSCE_NAME_STATUS_LIST pns=pnsList; pns; pns=pns->Next ) {
if ( pns->Name && i < nAdded ) {
aNewArray[*pCount+i].FullValueName = pns->Name; pns->Name = NULL; aNewArray[*pCount+i].Value = NULL; aNewArray[*pCount+i].ValueType = pns->Status; aNewArray[*pCount+i].Status = SCE_STATUS_NOT_CONFIGURED; i++;
} }
//
// free the original array
// all components in the array are already transferred to the new array
//
LocalFree(*paRegValues); *pCount = nNewCount; *paRegValues = aNewArray;
} else {
Win32Rc = ERROR_NOT_ENOUGH_MEMORY; } } }
//
// free the name status list
//
SceFreeMemory(pnsList, SCE_STRUCT_NAME_STATUS_LIST);
return( Win32Rc );
}
DWORD GetGroupStatus( DWORD status, int flag ) {
DWORD NewStatus;
switch ( flag ) { case STATUS_GROUP_RECORD: if (status & SCE_GROUP_STATUS_NC_MEMBERS) {
NewStatus = SCE_STATUS_NOT_CONFIGURED;
} else if ( (status & SCE_GROUP_STATUS_MEMBERS_MISMATCH) || (status & SCE_GROUP_STATUS_MEMBEROF_MISMATCH)) {
NewStatus = SCE_STATUS_MISMATCH;
} else if (status & SCE_GROUP_STATUS_NOT_ANALYZED) {
NewStatus = SCE_STATUS_NOT_ANALYZED;
} else if (status & SCE_GROUP_STATUS_ERROR_ANALYZED) {
NewStatus = SCE_STATUS_ERROR_NOT_AVAILABLE;
} else { NewStatus = SCE_STATUS_GOOD; } break;
case STATUS_GROUP_MEMBERS:
if ( status & SCE_GROUP_STATUS_NOT_ANALYZED ) {
NewStatus = SCE_STATUS_NOT_ANALYZED; //do not display any status;
} else { if ( status & SCE_GROUP_STATUS_NC_MEMBERS ) {
NewStatus = SCE_STATUS_NOT_CONFIGURED;
} else if ( status & SCE_GROUP_STATUS_MEMBERS_MISMATCH ) { NewStatus = SCE_STATUS_MISMATCH; } else if (status & SCE_GROUP_STATUS_ERROR_ANALYZED) { NewStatus = SCE_STATUS_ERROR_NOT_AVAILABLE;
} else { NewStatus = SCE_STATUS_GOOD; } } break;
case STATUS_GROUP_MEMBEROF:
if ( status & SCE_GROUP_STATUS_NOT_ANALYZED ) {
NewStatus = SCE_STATUS_NOT_ANALYZED; // do not display any status;
} else { if ( status & SCE_GROUP_STATUS_NC_MEMBEROF ) {
NewStatus = SCE_STATUS_NOT_CONFIGURED;
} else if ( status & SCE_GROUP_STATUS_MEMBEROF_MISMATCH ) { NewStatus = SCE_STATUS_MISMATCH; } else if (status & SCE_GROUP_STATUS_ERROR_ANALYZED) { NewStatus = SCE_STATUS_ERROR_NOT_AVAILABLE; } else { NewStatus = SCE_STATUS_GOOD; } } break; default: NewStatus = 0; break; }
return NewStatus; }
//+--------------------------------------------------------------------------
//
// Function: AllocGetTempFileName
//
// Synopsis: Allocate and return a string with a temporary file name.
//
// Returns: The temporary file name, or 0 if a temp file can't be found
//
// History:
//
//---------------------------------------------------------------------------
LPTSTR AllocGetTempFileName() { DWORD dw; CString strPath; CString strFile; LPTSTR szPath; LPTSTR szFile;
//
// Get a temporary directory path in strPath
// If our buffer isn't large enough then keep reallocating until it is
//
dw = MAX_PATH; do { szPath = strPath.GetBuffer(dw); dw = GetTempPath(MAX_PATH,szPath); strPath.ReleaseBuffer(); } while (dw > (DWORD)strPath.GetLength() );
//
// Can't get a path to the temporary directory
//
if (!dw) { return 0; }
//
// Get a temporary file in that directory
//
szFile = strFile.GetBuffer(dw+MAX_PATH); if (!GetTempFileName(szPath,L"SCE",0,szFile)) { return 0; } strFile.ReleaseBuffer();
szFile = (LPTSTR)LocalAlloc(LPTR,(strFile.GetLength()+1)*sizeof(TCHAR)); if (!szFile) { return 0; } //This is a safe usage.
lstrcpy(szFile,(LPCTSTR)strFile); return szFile; }
// If the given environment variable exists as the first part of the path,
// then the environment variable is inserted into the output buffer.
//
// Returns TRUE if pszResult is filled in.
//
// Example: Input -- C:\WINNT\SYSTEM32\FOO.TXT -and- lpEnvVar = %SYSTEMROOT%
// Output -- %SYSTEMROOT%\SYSTEM32\FOO.TXT
BOOL UnExpandEnvironmentString(LPCTSTR pszPath, LPCTSTR pszEnvVar, LPTSTR pszResult, UINT cbResult) { TCHAR szEnvVar[MAX_PATH]; if( !pszPath || !pszEnvVar || !pszResult ) //Raid #553113, yanggao.
return FALSE; //This is not a safe usage. Make sure szEnvVar is terminated. Raid #553113, Yanggao.
memset(szEnvVar, '\0', (MAX_PATH)*sizeof(TCHAR)); DWORD dwEnvVar = ExpandEnvironmentStrings(pszEnvVar, szEnvVar, ARRAYSIZE(szEnvVar)) - 1; // don't count the NULL
if (CompareString(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, szEnvVar, dwEnvVar, pszPath, dwEnvVar) == 2) { if (lstrlen(pszPath) + dwEnvVar < cbResult) { //This is not a safe usage. validate pszPath, dwEnvVar, pszResult.
lstrcpy(pszResult, pszEnvVar); lstrcat(pszResult, pszPath + dwEnvVar); return TRUE; } } return FALSE; }
//+--------------------------------------------------------------------------
//
// Function: UnexpandEnvironmentVariables
//
// Synopsis: Given a path, contract any leading members to use matching
// environment variables, if any
//
// Arguments:
// [szPath] - The path to expand
//
// Returns: The newly allocated path (NULL if no changes are made)
//
// History:
//
//---------------------------------------------------------------------------
LPTSTR UnexpandEnvironmentVariables(LPCTSTR szPath) { UINT cbNew; LPTSTR szNew; LPTSTR mszEnvVars; LPTSTR szEnvVar; DWORD dwEnvType; BOOL bExpanded; CString strKey; CString strValueName;
CString str;
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (!strKey.LoadString(IDS_SECEDIT_KEY) || !strValueName.LoadString(IDS_ENV_VARS_REG_VALUE)) { return NULL; }
//
// Allocate memory for the new path
//
cbNew = lstrlen(szPath)+MAX_PATH+1; szNew = (LPTSTR) LocalAlloc(LPTR,cbNew * sizeof(TCHAR)); if (!szNew) { return NULL; }
//
// Get Vars to expand from the registry
//
mszEnvVars = NULL; if (ERROR_SUCCESS != MyRegQueryValue(HKEY_LOCAL_MACHINE, // hKeyRoot
strKey, // SubKey
strValueName, // ValueName
(LPVOID *)&mszEnvVars, // Value
&dwEnvType)) { // Reg Type
//
// Can't get any variables to expand
//
LocalFree(szNew); return NULL; }
//
// We need a multi-sz with the variables to replace in it
//
if (REG_MULTI_SZ != dwEnvType || mszEnvVars == NULL) //Bug350194, Yang Gao, 3/23/2001
{ LocalFree(szNew); return NULL; }
bExpanded = FALSE;
//
// Start at the beginning of the multi-sz block
//
szEnvVar = mszEnvVars; while (*szEnvVar) { if (UnExpandEnvironmentString(szPath,szEnvVar,szNew,cbNew)) { //
// We can only unexpand (successfully) once
//
bExpanded = TRUE; break; } //
// Advance szEnvVar to the end of this string
//
while (*szEnvVar) { szEnvVar++; } //
// And the beginning of the next
//
szEnvVar++; }
if (mszEnvVars) { LocalFree(mszEnvVars); }
if (!bExpanded) { LocalFree(szNew); szNew = NULL; }
return szNew; }
//+--------------------------------------------------------------------------
//
// Function: IsSystemDatabase
//
// Synopsis: Determine if a specific databse is the system database or a private one
//
// Arguments:
// [szDBPath] - The database path to check
//
// Returns: True if szDBPath is the system database, false otherwise
//
// History:
//
//---------------------------------------------------------------------------
BOOL IsSystemDatabase(LPCTSTR szDBPath) { CString szSysDB; BOOL bIsSysDB; DWORD rc; DWORD RegType;
if (!szDBPath) { return FALSE; }
//Raid bug 261450, Yang Gao, 3/30/2001
if (FAILED(GetSystemDatabase(&szSysDB))) { return FALSE; }
//
// We found an appropriate szSysDB, so compare it with szDBPath
//
if (lstrcmp(szDBPath,szSysDB) == 0) { bIsSysDB = TRUE; } else { bIsSysDB = FALSE; }
return bIsSysDB; }
//+--------------------------------------------------------------------------
//
// Function: GetSystemDatabase
//
// Synopsis: Get the name of the current system database
//
// Arguments:
// [szDBPath] - [in/out] a pointer for the name of the system database
// The caller is responsible for freeing it.
//
//
// Returns: S_OK if the system database is found, otherwise an error
//
// History:
//
//---------------------------------------------------------------------------
HRESULT GetSystemDatabase(CString *szDBPath) { if (!szDBPath) { return E_INVALIDARG; }
//Raid bug 261450, Yang Gao, 3/30/2001
CString sAppend; sAppend.LoadString( IDS_DB_DEFAULT );
PWSTR pszPath = (LPTSTR)LocalAlloc( 0, (MAX_PATH + sAppend.GetLength() + 1) * sizeof(WCHAR)); if ( pszPath == NULL ) //Raid bug 427956, Yanggao, 7/2/2001
{ return E_FAIL; } if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_WINDOWS, NULL, 0, pszPath))) { //This is a safe usage.
wcscpy( &(pszPath[lstrlen(pszPath)]), sAppend ); *szDBPath = pszPath; if (pszPath) { LocalFree(pszPath); pszPath = NULL; } return S_OK; }
if (pszPath) { LocalFree(pszPath); pszPath = NULL; } return E_FAIL; }
//+--------------------------------------------------------------------------
//
// Function: ObjectStatusToString
//
// Synopsis: Convert an object status value to a printable string
//
// Arguments:
// [status] - [in] The status value to convert
// [str] - [out] The string to store the value in
//
//
//---------------------------------------------------------------------------
UINT ObjectStatusToString(DWORD status, CString *strStatus) { AFX_MANAGE_STATE(AfxGetStaticModuleState());
if ( status & SCE_STATUS_PERMISSION_MISMATCH ) { status = IDS_MISMATCH; } else if (status & SCE_STATUS_AUDIT_MISMATCH) { status = IDS_MISMATCH; } else { status &= 0x0F; switch(status){ case SCE_STATUS_NOT_ANALYZED: status = IDS_NOT_ANALYZED; break; case SCE_STATUS_GOOD: status = IDS_OK ; break; case SCE_STATUS_MISMATCH: status = IDS_MISMATCH; break; case SCE_STATUS_NOT_CONFIGURED: //
// BUG 119215: The Analysis UI should never show "Not Defined"
// for the security of existing system objects
//
status = IDS_NOT_ANALYZED; break; case SCE_STATUS_CHILDREN_CONFIGURED: status = IDS_CHILDREN_CONFIGURED; break; case SCE_STATUS_ERROR_NOT_AVAILABLE: status = IDS_NOT_AVAILABLE; break; case SCE_STATUS_NEW_SERVICE: status = IDS_NEW_SERVICE; break; default: //
// We shouldn't get here, but for some reason we keep doing so
//
status = IDS_MISMATCH; break; } }
if(strStatus){ strStatus->LoadString(status); } return status; }
//+--------------------------------------------------------------------------
//
// Function: IsSecurityTemplate
//
// Synopsis: Validates a file to see if the file is a security template.
//
// Arguments: [pszFileName] - The full path to the file to check.
//
// Returns: FALSE if the file does not exist or is not a valid
// security template.
//
// TRUE if successful.
// History:
//
//---------------------------------------------------------------------------
BOOL IsSecurityTemplate( LPCTSTR pszFileName ) { if(!pszFileName){ return FALSE; }
HANDLE hProfile; SCESTATUS rc;
//
// Open the profile.
//
rc = SceOpenProfile( pszFileName, SCE_INF_FORMAT, &hProfile ); if(rc == SCESTATUS_SUCCESS && hProfile){
PSCE_PROFILE_INFO ProfileInfo = NULL; PSCE_ERROR_LOG_INFO ErrBuf = NULL;
//
// The profile will be validated by trying to load all the security areas.
//
rc = SceGetSecurityProfileInfo(hProfile, SCE_ENGINE_SCP, AREA_ALL, &ProfileInfo, &ErrBuf); if(ErrBuf){ rc = SCESTATUS_INVALID_DATA; }
//
// Free up the memory.
//
SceFreeMemory((PVOID)ErrBuf, SCE_STRUCT_ERROR_LOG_INFO); ErrBuf = NULL;
if ( ProfileInfo != NULL ) { SceFreeMemory((PVOID)ProfileInfo, AREA_ALL); LocalFree(ProfileInfo); } SceCloseProfile(&hProfile);
//
// return TRUE if everything is successful.
//
if(rc != SCESTATUS_INVALID_DATA){ return TRUE; }
}
return FALSE; }
//+--------------------------------------------------------------------------
//
// Function: WriteSprintf
//
// Synopsis: Writes formated [pszStr] to [pStm].
//
// Arguments: [pStm] - Stream to write to.
// [pszStr] - Format string to write.
// [...] - printf formating
//
// Returns: The total number of bytes written.
//
// History:
//
//---------------------------------------------------------------------------
int WriteSprintf( IStream *pStm, LPCTSTR pszStr, ...) { TCHAR szWrite[512]; va_list marker; va_start(marker, pszStr);
vswprintf(szWrite, pszStr, marker); va_end(marker);
ULONG nBytesWritten; int iLen = lstrlen(szWrite);
if(pStm){ pStm->Write( szWrite, iLen * sizeof(TCHAR), &nBytesWritten ); return nBytesWritten; } return iLen; }
//+--------------------------------------------------------------------------
//
// Function: ReadSprintf
//
// Synopsis: Reads formated [pszStr] from [pStm].
// supported character switches are
// 'd' - integer pointer.
//
// Arguments: [pStm] - Stream to read from.
// [pszStr] - Format string to test.
// [...] - pointer to the types defined by format
// specification types.
//
// Returns: Total number of bytes read from the stream
//
// History:
//
//---------------------------------------------------------------------------
int ReadSprintf( IStream *pStm, LPCTSTR pszStr, ...) {
if(!pStm || !pszStr){ return -1; }
va_list marker; va_start(marker, pszStr);
TCHAR szRead[256]; TCHAR szConv[512]; ULONG uRead = 0;
int i = 0; LPCTSTR pszNext = szRead; int iTotalRead = 0;
// Get the current seek position.
ULARGE_INTEGER liBack = { 0 }; LARGE_INTEGER liCur = { 0 }; pStm->Seek( liCur, STREAM_SEEK_CUR, &liBack);
#define INCBUFFER(sz)\
if(uRead){\ (sz)++;\ uRead--;\ } else {\ pStm->Read(szRead, 256 * sizeof(TCHAR), &uRead);\ uRead = uRead/sizeof(TCHAR);\ (sz) = szRead;\ }\ iTotalRead++;
while(*pszStr){ if(!uRead){ // Read information into buffer.
pStm->Read( szRead, 256 * sizeof(TCHAR), &uRead); pszNext = szRead;
uRead = uRead/sizeof(TCHAR); if(!uRead){ iTotalRead = -1; break; } }
if(*pszStr == '%'){ pszStr++; switch( *pszStr ){ case 'd': // read integer.
pszStr++; i = 0;
// copy number to our own buffer.
while( (*pszNext >= L'0' && *pszNext <= L'9') ){ szConv[i++] = *pszNext; INCBUFFER( pszNext ); }
szConv[i] = 0;
// convert string to integer.
*(va_arg(marker, int *)) = _wtol(szConv); continue; case 's': pszStr++; i = 0; // we have to have some kind of terminating character se we will use the
// next value in pszStr.
while( *pszNext && (*pszNext != *pszStr) ){ szConv[i++] = *pszNext;
INCBUFFER( pszNext ); }
if(*pszNext == *pszStr){ INCBUFFER( pszNext ); }
// copy the string value.
szConv[i] = 0; if( i ){ LPTSTR pNew = (LPTSTR)LocalAlloc(0, sizeof(TCHAR) * (i + 1)); if(NULL != pNew){ //This is a safe usage.
lstrcpy(pNew, szConv); }
LPTSTR *pArg; pArg = (va_arg(marker, LPTSTR *)); if (pArg) { *pArg = pNew; } } else { LPTSTR *pArg = va_arg(marker, LPTSTR *); //Prefast warning 269: Incorrect order of operations: dereference ignored. Comments: It is not necessary.
} pszStr++; continue; } } // check to make sure we are at the correct position in the file.
if(*pszStr != *pszNext){ iTotalRead = -1; break; } pszStr++;
// increment buffer pointer.
INCBUFFER( pszNext ); }
va_end(marker);
// Reset streem seek pointer.
liCur.LowPart = liBack.LowPart; if(iTotalRead >= 0){ liCur.LowPart += iTotalRead * sizeof(TCHAR); } liCur.HighPart = liBack.HighPart; pStm->Seek(liCur, STREAM_SEEK_SET, NULL);
return iTotalRead; #undef INCBUFFER
}
//+--------------------------------------------------------------------------------
// FileCreateError
//
// This function tries to create a new file use [pszFile]. It will display a
// message to the user if the file cannot be created.
//
// Arguments: [pszFile] - Full path of file to create.
// [dwFlags] - Flags
// FCE_IGNORE_FILEEXISTS - Ignore File exists error, and
// delete the file.
//
// Returns: IDYES the file can be created
// IDNo The file cannot be created
DWORD FileCreateError( LPCTSTR pszFile, DWORD dwFlags ) { if(!pszFile){ return ERROR_INVALID_PARAMETER; } HANDLE hFile; DWORD dwErr = IDNO; //
// Try to create the file.
//
hFile = ExpandAndCreateFile( pszFile, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_ARCHIVE, NULL ); if(hFile == INVALID_HANDLE_VALUE){ //
// Post error message to user.
//
dwErr = GetLastError(); LPTSTR pszErr; CString strErr; //This is a safe usage.
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwErr, 0, (LPTSTR)&pszErr, 0, NULL );
strErr = pszErr; strErr += pszFile;
if(pszErr){ LocalFree(pszErr); }
switch(dwErr){ case ERROR_ALREADY_EXISTS: case ERROR_FILE_EXISTS: if( dwFlags & FCE_IGNORE_FILEEXISTS ){ dwErr = IDYES; break; } //
// Confirm overwrite.
//
strErr.Format(IDS_FILE_EXISTS_FMT, pszFile); dwErr = AfxMessageBox( strErr, MB_YESNO ); break; default: //
// The file cannot be created.
//
AfxMessageBox( strErr, MB_OK ); dwErr = IDNO; break; }
} else { //
// It's OK to create the file.
//
::CloseHandle( hFile ); DeleteFile(pszFile);
dwErr = IDYES; }
return dwErr; }
//+--------------------------------------------------------------------------
//
// Function: IsDBCSPath
//
// Synopsis: Check if a path contains DBCS characters
//
// Arguments: [pszFile] - [in] The path to check
//
// Returns: TRUE if pszFile contains characters that can't be
// represented by a LPSTR
//
// FALSE if pszFile only contains characters that can
// be represented by a LPSTR
//
//
//+--------------------------------------------------------------------------
BOOL IsDBCSPath(LPCTSTR szWideFile) { while(*szWideFile) { if (*szWideFile >= 256) { return TRUE; } szWideFile++; } return FALSE;
/*
LPSTR szMBFile; int nMBFile; BOOL bUsedDefaultChar = FALSE;
nMBFile = sizeof(LPSTR)*(lstrlen(szWideFile)); szMBFile = (LPSTR)LocalAlloc(LPTR,nMBFile+1);
if (szMBFile) { WideCharToMultiByte( CP_ACP, 0, szWideFile, -1, szMBFile, nMBFile, NULL, &bUsedDefaultChar);
LocalFree(szMBFile); }
return bUsedDefaultChar; */ }
//+--------------------------------------------------------------------------
//
// Function: GetSeceditHelpFilename
//
// Synopsis: Return the fully qualified path the help file for Secedit
//
// Arguments: None
//
// Returns: a CString containing the fully qualified help file name.
//
//
//+--------------------------------------------------------------------------
CString GetSeceditHelpFilename() { static CString helpFileName;
if ( helpFileName.IsEmpty () ) { UINT result = ::GetSystemWindowsDirectory ( helpFileName.GetBufferSetLength (MAX_PATH+1), MAX_PATH); ASSERT(result != 0 && result <= MAX_PATH); //Bogus assert. Yanggao.
helpFileName.ReleaseBuffer ();
helpFileName += L"\\help\\wsecedit.hlp"; }
return helpFileName; }
//+--------------------------------------------------------------------------
//
// Function: GetGpeditHelpFilename
//
// Synopsis: Return the fully qualified path the help file for Secedit
//
// Arguments: None
//
// Returns: a CString containing the fully qualified help file name.
//
//
//+--------------------------------------------------------------------------
CString GetGpeditHelpFilename() { static CString helpFileName;
if ( helpFileName.IsEmpty () ) { UINT result = ::GetSystemWindowsDirectory ( helpFileName.GetBufferSetLength (MAX_PATH+1), MAX_PATH); ASSERT(result != 0 && result <= MAX_PATH); //Bogus Assert. Yanggao.
helpFileName.ReleaseBuffer ();
helpFileName += L"\\help\\gpedit.hlp"; }
return helpFileName; } //+--------------------------------------------------------------------------
//
// Function: ExpandEnvironmentStringWrapper
//
// Synopsis: Takes an LPTSTR and expands the enviroment variables in it
//
// Arguments: Pointer to the string to expand.
//
// Returns: a CString containing the fully expanded string.
//
//+--------------------------------------------------------------------------
CString ExpandEnvironmentStringWrapper(LPCTSTR psz) { LPTSTR pszBuffer = NULL; DWORD dwExpanded = 0; CString sz;
dwExpanded = ExpandEnvironmentStrings(psz, NULL, 0);
pszBuffer = sz.GetBuffer(dwExpanded); ExpandEnvironmentStrings(psz, pszBuffer, dwExpanded); sz.ReleaseBuffer();
return (sz); }
//+--------------------------------------------------------------------------
//
// Function: ExpandAndCreateFile
//
// Synopsis: Just does a normal CreateFile(), but expands the filename before
// creating the file.
//
// Arguments: Same as CreateFile().
//
// Returns: HANDLE to the created file.
//
//+--------------------------------------------------------------------------
HANDLE WINAPI ExpandAndCreateFile ( LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile ) { HANDLE hRet = INVALID_HANDLE_VALUE; CString sz;
sz = ExpandEnvironmentStringWrapper(lpFileName); //This is a safe usage. sz is full path.
return (CreateFile( sz, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile)); }
//**********************************************************************
//
// FUNCTION: IsAdmin - This function checks the token of the
// calling thread to see if the caller belongs to
// the Administrators group.
//
// PARAMETERS: none
//
// RETURN VALUE: TRUE if the caller is an administrator on the local
// machine. Otherwise, FALSE.
//
//**********************************************************************
BOOL IsAdmin(void) {
HANDLE hAccessToken = NULL; PTOKEN_GROUPS ptgGroups = NULL; DWORD cbGroups = 0; PSID psidAdmin = NULL; UINT i;
SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
// assume the caller is not an administrator
BOOL bIsAdmin = FALSE;
__try {
if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &hAccessToken)) {
if (GetLastError() != ERROR_NO_TOKEN) __leave;
// retry against process token if no thread token exists
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hAccessToken)) __leave; }
// determine required size of buffer for token information
if (GetTokenInformation(hAccessToken, TokenGroups, NULL, 0, &cbGroups)) {
// call should have failed due to zero-length buffer
__leave;
} else {
// call should have failed due to zero-length buffer
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) __leave; }
// allocate a buffer to hold the token groups
ptgGroups = (PTOKEN_GROUPS) HeapAlloc(GetProcessHeap(), 0, cbGroups); if (!ptgGroups) __leave;
// call GetTokenInformation() again to actually retrieve the groups
if (!GetTokenInformation(hAccessToken, TokenGroups, ptgGroups, cbGroups, &cbGroups)) __leave;
// create a SID for the local administrators group
// This is a safe usage.
if (!AllocateAndInitializeSid(&siaNtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdmin)) __leave;
// scan the token's groups and compare the SIDs to the admin SID
for (i = 0; i < ptgGroups->GroupCount; i++) { //This is a safe usage. psidAdmin is a local admin SID.
if (EqualSid(psidAdmin, ptgGroups->Groups[i].Sid)) { bIsAdmin = TRUE; break; } }
} __finally {
// free resources
if (hAccessToken) CloseHandle(hAccessToken);
if (ptgGroups) HeapFree(GetProcessHeap(), 0, ptgGroups);
if (psidAdmin) FreeSid(psidAdmin); }
return bIsAdmin; }
//+--------------------------------------------------------------------------
//
// Function: MultiSZToSZ
//
// Synopsis: Converts a multiline string to a comma delimited normal string
//
// Returns: The converted string
//
//+--------------------------------------------------------------------------
PWSTR MultiSZToSZ(PCWSTR sz) { PWSTR szOut = NULL;
ASSERT(sz); if (!sz) { return NULL; } //Bug 349000, Yang Gao, 3/23/2001
long i = 0; long j = 0; while( L'\0' != sz[i] ) { if( L',' == sz[i] ) j++; i++; }
szOut = (PWSTR) LocalAlloc(LPTR,(lstrlen(sz)+j*2+1)*sizeof(wchar_t)); //Raid #376228, 4/25/2001
if (!szOut) { return NULL; }
BOOL newline = FALSE; //raid #464335, Yang Gao, 9/7/2001
for(i=0,j=0; sz[i] != L'\0'; i++) { if( L'\n' == sz[i] ) { if( newline ) { szOut[j++] = MULTISZ_DELIMITER; } newline = FALSE; continue; } if( L'\r' == sz[i] ) { continue; // ignore it
} if( L' ' == sz[i] && !newline ) //raid #464335, Yang Gao, 9/7/2001
{ continue; //delete it if it occurs before any char of each line.
} newline = TRUE;
if( L',' == sz[i] ) { szOut[j++] = MULTISZ_QUOTE; szOut[j++] = sz[i]; szOut[j++] = MULTISZ_QUOTE; continue; }
szOut[j++] = sz[i]; }
return szOut; }
//+--------------------------------------------------------------------------
//
// Function: SZToMultiSZ
//
// Synopsis: Converts a comma delimited string to a multiline string
//
// Returns: The converted string
//
//+--------------------------------------------------------------------------
PWSTR SZToMultiSZ(PCWSTR sz) { PWSTR szOut = NULL;
ASSERT(sz); if (!sz) { return NULL; } //
// Calculate the length of the expanded string
//
int cSZ = 0; for (int i = 0;sz[i] != L'\0'; i++) { if (MULTISZ_DELIMITER == sz[i]) { //
// Delimiter expands into an extra character so count it twice
//
cSZ++; } cSZ++; }
szOut = (PWSTR) LocalAlloc(LPTR,(cSZ+1)*sizeof(wchar_t)); if (!szOut) { return NULL; }
BOOL qflag = FALSE; for(int i=0, c=0; sz[i] != L'\0'; i++) { //Bug 349000, Yang Gao, 3/23/2001
if( MULTISZ_QUOTE == sz[i] && MULTISZ_DELIMITER == sz[i+1] ) { qflag = TRUE; continue; } if( MULTISZ_DELIMITER == sz[i] && MULTISZ_QUOTE == sz[i+1] && qflag ) { szOut[c++] = sz[i]; i++; qflag = FALSE; continue; } qflag = FALSE; if (MULTISZ_DELIMITER == sz[i]) { szOut[c++] = L'\r'; szOut[c++] = L'\n'; } else { szOut[c++] = sz[i]; } }
return szOut; }
//+--------------------------------------------------------------------------
//
// Function: MultiSZToDisp
//
// Synopsis: Converts a comma delimited multiline string to a display string
//
// Returns: The converted string
// Bug 349000, Yang Gao, 3/23/2001
//+--------------------------------------------------------------------------
void MultiSZToDisp(PCWSTR sz, CString &pszOut) {
ASSERT(sz); if (!sz) { return; } //
// Calculate the length of the expanded string
//
int cSZ = 0; for (int i = 0;sz[i] != L'\0'; i++) { if (MULTISZ_DELIMITER == sz[i]) { //
// Delimiter expands into an extra character so count it twice
//
cSZ++; } cSZ++; }
PWSTR szOut; szOut = (PWSTR) LocalAlloc(LPTR,(cSZ+1)*sizeof(wchar_t)); if (!szOut) { return; }
BOOL qflag = FALSE; for(int i=0, c=0; sz[i] != L'\0'; i++) { if( MULTISZ_QUOTE == sz[i] && MULTISZ_DELIMITER == sz[i+1] ) { qflag = TRUE; continue; } if( MULTISZ_DELIMITER == sz[i] && MULTISZ_QUOTE == sz[i+1] && qflag ) { szOut[c++] = sz[i]; i++; qflag = FALSE; continue; } qflag = FALSE; szOut[c++] = sz[i]; }
pszOut = szOut; LocalFree(szOut); return; }
SCE_PROFILE_INFO *g_pDefaultTemplate = NULL;
SCE_PROFILE_INFO * GetDefaultTemplate() { SCE_PROFILE_INFO *pspi = NULL; DWORD RegType = 0; SCESTATUS rc = 0; LPTSTR szInfFile = NULL; PVOID pHandle = NULL;
if (g_pDefaultTemplate) { return g_pDefaultTemplate; }
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 NULL; } if (EngineOpenProfile(szInfFile,OPEN_PROFILE_CONFIGURE,&pHandle) != SCESTATUS_SUCCESS) { LocalFree(szInfFile); szInfFile = NULL; return NULL; } LocalFree(szInfFile); szInfFile = NULL; rc = SceGetSecurityProfileInfo(pHandle, SCE_ENGINE_SCP, AREA_ALL, &pspi, NULL );
SceCloseProfile(&pHandle); if (SCESTATUS_SUCCESS != rc) { //
// expand registry value section based on registry values list on local machine
//
SceRegEnumAllValues( &(pspi->RegValueCount), &(pspi->aRegValues) );
#define PD(X,Y) if (pspi->X == SCE_NO_VALUE) { pspi->X = Y; }
PD(MaximumPasswordAge,MAX_PASS_AGE_DEFAULT) PD(MinimumPasswordAge,MIN_PASS_AGE_DEFAULT) PD(MinimumPasswordLength,MIN_PASS_LENGTH_DEFAULT) PD(PasswordHistorySize,PASS_HISTORY_SIZE_DEFAULT) PD(PasswordComplexity,PASS_COMPLEXITY_DEFAULT) PD(RequireLogonToChangePassword,REQUIRE_LOGIN_DEFAULT) PD(LockoutBadCount,LOCKOUT_BAD_COUNT_DEFAULT) PD(ResetLockoutCount,RESET_LOCKOUT_COUNT_DEFAULT) PD(LockoutDuration,LOCKOUT_DURATION_DEFAULT) PD(AuditSystemEvents,AUDIT_SYSTEM_EVENTS_DEFAULT) PD(AuditLogonEvents,AUDIT_LOGON_EVENTS_DEFAULT) PD(AuditObjectAccess,AUDIT_OBJECT_ACCESS_DEFAULT) PD(AuditPrivilegeUse,AUDIT_PRIVILEGE_USE_DEFAULT) PD(AuditPolicyChange,AUDIT_POLICY_CHANGE_DEFAULT) PD(AuditAccountManage,AUDIT_ACCOUNT_MANAGE_DEFAULT) PD(AuditProcessTracking,AUDIT_PROCESS_TRACKING_DEFAULT) PD(AuditDSAccess,AUDIT_DS_ACCESS_DEFAULT) PD(AuditAccountLogon,AUDIT_ACCOUNT_LOGON_DEFAULT) PD(ForceLogoffWhenHourExpire,FORCE_LOGOFF_DEFAULT) PD(EnableAdminAccount,ENABLE_ADMIN_DEFAULT) PD(EnableGuestAccount,ENABLE_GUEST_DEFAULT) PD(LSAAnonymousNameLookup,LSA_ANON_LOOKUP_DEFAULT) PD(MaximumLogSize[EVENT_TYPE_SYSTEM],SYS_MAX_LOG_SIZE_DEFAULT) PD(MaximumLogSize[EVENT_TYPE_APP],APP_MAX_LOG_SIZE_DEFAULT) PD(MaximumLogSize[EVENT_TYPE_SECURITY],SEC_MAX_LOG_SIZE_DEFAULT) PD(AuditLogRetentionPeriod[EVENT_TYPE_SYSTEM],SYS_LOG_RETENTION_PERIOD_DEFAULT) PD(AuditLogRetentionPeriod[EVENT_TYPE_APP],APP_LOG_RETENTION_PERIOD_DEFAULT) PD(AuditLogRetentionPeriod[EVENT_TYPE_SECURITY],SEC_LOG_RETENTION_PERIOD_DEFAULT) PD(RetentionDays[EVENT_TYPE_APP],APP_LOG_RETENTION_DAYS_DEFAULT) PD(RetentionDays[EVENT_TYPE_SYSTEM],SYS_LOG_RETENTION_DAYS_DEFAULT) PD(RetentionDays[EVENT_TYPE_SECURITY],SEC_LOG_RETENTION_DAYS_DEFAULT) PD(RestrictGuestAccess[EVENT_TYPE_APP],APP_RESTRICT_GUEST_ACCESS_DEFAULT) PD(RestrictGuestAccess[EVENT_TYPE_SYSTEM],SYS_RESTRICT_GUEST_ACCESS_DEFAULT) PD(RestrictGuestAccess[EVENT_TYPE_SECURITY],SEC_RESTRICT_GUEST_ACCESS_DEFAULT)
if (pspi->pFiles.pAllNodes->Count == 0) { DWORD SDSize = 0; pspi->pFiles.pAllNodes->Count = 1; pspi->pFiles.pAllNodes->pObjectArray[0] = (PSCE_OBJECT_SECURITY) LocalAlloc(LPTR,sizeof(SCE_OBJECT_SECURITY)); if (pspi->pFiles.pAllNodes->pObjectArray[0]) { SceSvcConvertTextToSD ( FILE_SYSTEM_SECURITY_DEFAULT, &(pspi->pFiles.pAllNodes->pObjectArray[0]->pSecurityDescriptor), &SDSize, &(pspi->pFiles.pAllNodes->pObjectArray[0]->SeInfo) ); } }
if (pspi->pRegistryKeys.pAllNodes->Count == 0) { DWORD SDSize = 0; pspi->pRegistryKeys.pAllNodes->Count = 1; pspi->pRegistryKeys.pAllNodes->pObjectArray[0] = (PSCE_OBJECT_SECURITY) LocalAlloc(LPTR,sizeof(SCE_OBJECT_SECURITY)); if (pspi->pRegistryKeys.pAllNodes->pObjectArray[0]) { SceSvcConvertTextToSD ( REGISTRY_SECURITY_DEFAULT, &(pspi->pRegistryKeys.pAllNodes->pObjectArray[0]->pSecurityDescriptor), &SDSize, &(pspi->pRegistryKeys.pAllNodes->pObjectArray[0]->SeInfo) ); } }
if (pspi->pServices->General.pSecurityDescriptor == NULL) { DWORD SDSize = 0; SceSvcConvertTextToSD ( SERVICE_SECURITY_DEFAULT, &(pspi->pServices->General.pSecurityDescriptor), &SDSize, &(pspi->pServices->SeInfo) ); } } g_pDefaultTemplate = pspi; return pspi; }
HRESULT GetDefaultFileSecurity(PSECURITY_DESCRIPTOR *ppSD, SECURITY_INFORMATION *pSeInfo) { SCE_PROFILE_INFO *pspi = NULL;
ASSERT(ppSD); ASSERT(pSeInfo); if (!ppSD || !pSeInfo) { return E_INVALIDARG; }
pspi = GetDefaultTemplate(); *ppSD = NULL; *pSeInfo = 0;
if (!pspi) { return E_FAIL; } if (!pspi->pFiles.pAllNodes) { return E_FAIL; } if (pspi->pFiles.pAllNodes->Count == 0) { return E_FAIL; } *pSeInfo = pspi->pFiles.pAllNodes->pObjectArray[0]->SeInfo;
return MyMakeSelfRelativeSD(pspi->pFiles.pAllNodes->pObjectArray[0]->pSecurityDescriptor, ppSD); }
HRESULT GetDefaultRegKeySecurity(PSECURITY_DESCRIPTOR *ppSD, SECURITY_INFORMATION *pSeInfo) { SCE_PROFILE_INFO *pspi = NULL;
ASSERT(ppSD); ASSERT(pSeInfo); if (!ppSD || !pSeInfo) { return E_INVALIDARG; }
pspi = GetDefaultTemplate(); *ppSD = NULL; *pSeInfo = 0;
if (!pspi) { return E_FAIL; } if (!pspi->pRegistryKeys.pAllNodes) { return E_FAIL; } if (pspi->pRegistryKeys.pAllNodes->Count == 0) { return E_FAIL; } *pSeInfo = pspi->pRegistryKeys.pAllNodes->pObjectArray[0]->SeInfo;
return MyMakeSelfRelativeSD(pspi->pRegistryKeys.pAllNodes->pObjectArray[0]->pSecurityDescriptor, ppSD); }
HRESULT GetDefaultServiceSecurity(PSECURITY_DESCRIPTOR *ppSD, SECURITY_INFORMATION *pSeInfo) { SCE_PROFILE_INFO *pspi = NULL;
ASSERT(ppSD); ASSERT(pSeInfo); if (!ppSD || !pSeInfo) { return E_INVALIDARG; }
pspi = GetDefaultTemplate(); *ppSD = NULL; *pSeInfo = 0;
if (!pspi) { return E_FAIL; } if (!pspi->pServices) { return E_FAIL; } *pSeInfo = pspi->pServices->SeInfo;
return MyMakeSelfRelativeSD(pspi->pServices->General.pSecurityDescriptor, ppSD); }
BOOL GetSecureWizardName( OUT LPTSTR *ppstrPathName OPTIONAL, OUT LPTSTR *ppstrDisplayName OPTIONAL ) { BOOL b=FALSE;
if ( ppstrPathName == NULL && ppstrDisplayName == NULL) return FALSE;
if ( ppstrPathName ) *ppstrPathName = NULL;
if ( ppstrDisplayName ) *ppstrDisplayName = NULL;
#define SCE_WIZARD_PATH SCE_ROOT_PATH TEXT("\\Wizard")
DWORD rc; DWORD RegType; LPVOID pValue=NULL; PWSTR pPathName = NULL;
rc = MyRegQueryValue(HKEY_LOCAL_MACHINE, SCE_WIZARD_PATH, TEXT("Path"), &pValue, &RegType );
if ( ERROR_SUCCESS == rc && pValue && (RegType == REG_SZ || RegType == REG_EXPAND_SZ) ) {
if ( RegType == REG_EXPAND_SZ ) { //
// Expand the environment variable
//
DWORD dSize = ExpandEnvironmentStrings((LPTSTR)pValue, NULL, 0);
if ( dSize > 0 ) { pPathName = (PWSTR)LocalAlloc(LPTR, (dSize+1)*sizeof(WCHAR));
if ( pPathName ) {
ExpandEnvironmentStrings((LPTSTR)pValue, pPathName, dSize);
} else { LocalFree(pValue); return FALSE; }
} else {
LocalFree(pValue); return FALSE; }
} else {
//
// just simply take the string
//
pPathName = (LPTSTR)pValue; pValue = NULL; }
if ( ppstrDisplayName ) { //
// now query the display name (menu name) from the binary
// binary name is stored in pPathName (can't be NULL)
//
DWORD dwHandle=0;
DWORD dwSize = GetFileVersionInfoSize(pPathName, &dwHandle);
if ( dwSize > 0 ) {
LPVOID pBuffer = (LPVOID)LocalAlloc(LPTR, dwSize+1);
if ( pBuffer ) { if ( GetFileVersionInfo(pPathName, 0, dwSize, pBuffer) ) {
PVOID lpInfo = 0; UINT cch = 0; CString key; WCHAR szBuffer[10]; CString keyBase; //This is a safe usage.
wsprintf (szBuffer, L"%04X", GetUserDefaultLangID ()); wcscat (szBuffer, L"04B0");
keyBase = L"\\StringFileInfo\\"; keyBase += szBuffer; keyBase += L"\\";
key = keyBase + L"FileDescription"; if ( VerQueryValue (pBuffer, const_cast <PWSTR>((PCWSTR) key), &lpInfo, &cch) ) {
*ppstrDisplayName = (PWSTR)LocalAlloc(LPTR,(cch+1)*sizeof(WCHAR)); if ( *ppstrDisplayName ) { //This may not be a safe usage. ppstrDisplayName is PTSTR. Consider fix.
wcscpy(*ppstrDisplayName, (PWSTR)lpInfo);
b=TRUE; } } }
LocalFree(pBuffer);
} } }
//
// get the binary name
//
if ( ppstrPathName ) { *ppstrPathName = pPathName; pPathName = NULL;
b=TRUE; }
}
if ( pPathName && (pPathName != pValue ) ) { LocalFree(pPathName); }
if ( pValue ) { LocalFree(pValue); }
return b; }
BOOL IsValidFileName(CString& str) { CString text; CString charsWithSpaces; UINT nIndex = 0;
PCWSTR szInvalidCharSet = ILLEGAL_FILENAME_CHARS; if( str == L'.' || str == L"..") //Raid #617915, Yanggao
return FALSE;
if( -1 != str.FindOneOf(szInvalidCharSet) ) { while (szInvalidCharSet[nIndex]) { charsWithSpaces += szInvalidCharSet[nIndex]; charsWithSpaces += L" "; nIndex++; } //This is a sage usage.
text.FormatMessage (IDS_INVALID_FILENAME, charsWithSpaces);
AfxMessageBox(text, MB_OK|MB_ICONEXCLAMATION); return FALSE; }
//Raid 484084, Yanggao, 10/24/2001
int strlength = str.GetLength(); if( 1==strlength && (str.GetAt(0) == L'/' || str.GetAt(0) == L'\\') ) { szInvalidCharSet = ILLEGAL_FILENAME_CHARS2; //Raid #526397, 2/26/2002, yanggao
while (szInvalidCharSet[nIndex]) { charsWithSpaces += szInvalidCharSet[nIndex]; charsWithSpaces += L" "; nIndex++; } //This is a safe usage.
text.FormatMessage (IDS_INVALID_FILENAMEPATH, charsWithSpaces); AfxMessageBox(text, MB_OK|MB_ICONEXCLAMATION); return FALSE; } int pos1 = str.Find(L"\\\\"); int pos2 = str.Find(L"//"); int pos3 = str.Find(L"\\/"); int pos4 = str.Find(L"/\\"); if( pos1>=0 || pos2>=0 || pos3>=0 || pos4>=0 ) //Raid #498480, yanggao, do not accept "\\".
{ szInvalidCharSet = ILLEGAL_FILENAME_CHARS1; while (szInvalidCharSet[nIndex]) { charsWithSpaces += szInvalidCharSet[nIndex]; charsWithSpaces += L" "; nIndex++; } //This is a safe usage.
text.FormatMessage (IDS_INVALID_FILENAME, charsWithSpaces); AfxMessageBox(text, MB_OK|MB_ICONEXCLAMATION); return FALSE; }
return TRUE; }
///////////////////////////////////////////////////////////////////
//Raid #533432, yanggao, 4/3/2002
//Currently pextension should include '.'
///////////////////////////////////////////////////////////////////
#define IsDigit(c) ((c) >= L'0' && c <= L'9')
BOOL IsNameReserved(LPCWSTR pszName, LPCWSTR pextension) { static const WCHAR *rgszPorts3[] = { TEXT("NUL"), TEXT("PRN"), TEXT("CON"), TEXT("AUX"), };
static const WCHAR *rgszPorts4[] = { TEXT("LPT"), // LPT#
TEXT("COM"), // COM#
};
if( !pszName || !pextension ) return FALSE;
CString sz = pszName; CString tempsz = pextension; if( _wcsicmp(sz.Right(tempsz.GetLength()), tempsz) == 0 ) //Remove extension
{ tempsz = sz.Left(sz.GetLength() - tempsz.GetLength()); } else { tempsz = sz; }
int cch = tempsz.ReverseFind(L'\\'); //Remove path
int iMax = tempsz.ReverseFind(L'/'); if( cch < iMax ) { cch = iMax; } if( cch >= 0 ) { cch = tempsz.GetLength() - cch - 1; sz = tempsz.Right(cch); } else { sz = tempsz; }
LPCTSTR* rgszPorts = rgszPorts3; cch = sz.GetLength(); tempsz = sz;
iMax = ARRAYSIZE(rgszPorts3); if (cch == 4 && IsDigit(sz.GetAt(3))) { // if 4 chars start with LPT checks
// need to filter out:
// COM1, COM2, etc. LPT1, LPT2, etc
// but not:
// COM or LPT or LPT10 or COM10
// COM == 1 and LPT == 0
iMax = ARRAYSIZE(rgszPorts4); rgszPorts = rgszPorts4; sz.SetAt(3, L'\0'); cch = 3; }
if (cch == 3) { int i = 0; for (i; i < iMax; i++) { if (!lstrcmpi(rgszPorts[i], sz)) { break; } } if( i != iMax ) { sz.FormatMessage(IDS_RESERVED_NAME, tempsz); AfxMessageBox(sz, MB_OK|MB_ICONEXCLAMATION); return TRUE; } }
return FALSE; }
|