windows-nt/Source/XPSP1/NT/termsrv/admtools/winutils/tscfg/wincfg.cpp
2020-09-26 16:20:57 +08:00

1113 lines
34 KiB
C++

//Copyright (c) 1998 - 1999 Microsoft Corporation
/*******************************************************************************
*
* wincfg.cpp
*
* WinStation Configuration application
*
* copyright notice: Copyright 1996, Citrix Systems Inc.
*
* $Author: donm $ Butch Davis
*
* $Log: N:\nt\private\utils\citrix\winutils\tscfg\VCS\wincfg.cpp $
*
* Rev 1.34 24 Apr 1998 09:44:28 donm
* removed command line options
*
* Rev 1.33 18 Apr 1998 15:31:42 donm
* Added capability bits
*
* Rev 1.32 14 Feb 1998 11:22:38 donm
* fixed memory leak by avoiding CDocManager::OpenDocumentFile
*
* Rev 1.31 26 Jan 1998 18:33:04 thanhl
* Save CharSet Font info
*
* Rev 1.30 13 Jan 1998 14:08:38 donm
* gets encryption levels from extension DLL
*
* Rev 1.29 10 Dec 1997 15:59:28 donm
* added ability to have extension DLLs
*
* Rev 1.28 26 Sep 1997 19:05:06 butchd
* Hydra registry name changes
*
* Rev 1.27 02 Jul 1997 15:21:10 butchd
* update
*
* Rev 1.26 27 Jun 1997 15:58:42 butchd
* Registry changes for Wds/Tds/Pds/Cds
*
*******************************************************************************/
/*
* include files
*/
#include "stdafx.h"
#include "wincfg.h"
#include "mainfrm.h"
#include "rowview.h"
#include "appsvdoc.h"
#include "appsvvw.h"
#include "security.h"
#include <errno.h>
#include <hydra\regapi.h>
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
/*
* Global command line variables.
*/
extern USHORT g_Add;
/*
* Global variables for WINUTILS Common functions.
*/
extern "C" {
LPCTSTR WinUtilsAppName = NULL;
HWND WinUtilsAppWindow = NULL;
HINSTANCE WinUtilsAppInstance = NULL;
}
////////////////////////////////////////////////////////////////////////////////
// CWincfgApp class implementation / construction, destruction
/*******************************************************************************
*
* CWincfgApp - CWincfgApp constructor
*
* ENTRY:
* EXIT:
*
******************************************************************************/
CWincfgApp::CWincfgApp()
: m_pszRegWinStationCreate(TEXT("RegWinStationCreate")),
m_pszRegWinStationSetSecurity(TEXT("RegWinStationSetSecurity")),
m_pszRegWinStationQuery(TEXT("RegWinStationQuery")),
m_pszRegWinStationDelete(TEXT("RegWinStationDelete")),
m_pszGetDefaultWinStationSecurity(TEXT("GetDefaultWinStationSecurity")),
m_pszGetWinStationSecurity(TEXT("GetWinStationSecurity"))
{
} // end CWincfgApp::CWincfgApp
////////////////////////////////////////////////////////////////////////////////
// The one and only CWincfgApp object and a application-global reference to it.
CWincfgApp theApp;
CWincfgApp *pApp = &theApp;
BOOL AreWeRunningTerminalServices(void);
////////////////////////////////////////////////////////////////////////////////
// CWincfgApp overrides of MFC CWinApp class
/*******************************************************************************
*
* InitInstance - CWincfgApp member function: CWinApp override
*
* Perform application initialization and previous state restoration.
*
* ENTRY:
*
* EXIT:
* (BOOL)
* TRUE if initialization sucessful; FALSE otherwise.
*
******************************************************************************/
BOOL
CWincfgApp::InitInstance()
{
//Check if we are running under Terminal Server
if(!AreWeRunningTerminalServices())
{
AfxMessageBox(IDS_ERROR_NOT_TS,MB_OK |MB_ICONSTOP );
return FALSE;
}
if(FAILED(CoInitialize(NULL)))
return FALSE;
/*
* Initialize the global WINUTILS app name and instance variables.
*/
WinUtilsAppName = AfxGetAppName();
WinUtilsAppInstance = AfxGetInstanceHandle();
/*
* Fetch and save the Computer Name as the local AppServer and current
* AppServer.
*/
DWORD cchBuffer = MAX_COMPUTERNAME_LENGTH+1;
m_szLocalAppServer[0] = m_szLocalAppServer[1] = TEXT('\\');
GetComputerName(m_szLocalAppServer+2, &cchBuffer);
lstrcpy(m_szCurrentAppServer, m_szLocalAppServer);
/*
* Load the system console string for rapid comparison in the 'IsAllowed'
* functions.
*/
LoadString( m_hInstance, IDS_SYSTEM_CONSOLE_NAME,
m_szSystemConsole, WINSTATIONNAME_LENGTH );
/*
* Default to 'help allowed'.
*/
m_bAllowHelp = TRUE;
/*
* Initialize the application defaults.
*/
if ( !Initialize() )
return(FALSE);
/*
* Register the application's document templates. Document templates
* serve as the connection between documents, frame windows and views.
*/
CSingleDocTemplate *pTemplate = new CSingleDocTemplate( IDR_MAINFRAME,
RUNTIME_CLASS(CAppServerDoc),
RUNTIME_CLASS(CMainFrame),
RUNTIME_CLASS(CAppServerView) );
if(!pTemplate) return(FALSE);
AddDocTemplate(pTemplate);
/*
* open the initial document window for the current (default local) AppServer.
* NOTE: We can't call CWinApp::OpenDocumentFile because it causes
* a memory leek in SHELL32.DLL SHGetFileInfo since we were trying to
* pass the server name (i.e. \\MYSERVER) as the file name.
* CWinApp::OpenDocumentFile will trap if we pass a NULL, therefore
* we call CSingleDocTemplate::OpenDocumentFile which can handle
* a NULL.
*/
if(!pTemplate->OpenDocumentFile(NULL)) {
Terminate();
return(FALSE);
} else {
CAppServerDoc *pDoc =
(CAppServerDoc *)((CFrameWnd *)m_pMainWnd)->GetActiveDocument();
/*
* Initialize the global WINUTILS app window handle.
*/
WinUtilsAppWindow = m_pMainWnd->m_hWnd;
#ifdef USING_3DCONTROLS
Enable3dControls();
#endif
/*
* Take care of special command line flags (only one allowed
* at a time).
*/
if ( g_Add )
m_pMainWnd->PostMessage(WM_ADDWINSTATION);
return(TRUE);
}
} // end CWincfgApp::InitInstance
/*******************************************************************************
*
* AddToRecentFileList - CWincfgApp member function: override
*
* Suppress the adding of MRU file names to .INI file.
*
* ENTRY:
* EXIT:
* (Refer to CWinApp::AddToRecentFileList documentation)
*
******************************************************************************/
void
CWincfgApp::AddToRecentFileList( const char * pszPathName )
{
/*
* Don't do anything: we don't use a MRU or .INI file.
*/
} // end CWincfgApp::AddToRecentFileList
////////////////////////////////////////////////////////////////////////////////
// CWincfgApp Operations
static TCHAR BASED_CODE szWincfgAppKey[] = REG_SOFTWARE_TSERVER TEXT("\\TSCFG");
static TCHAR BASED_CODE szPlacement[] = TEXT("Placement");
static TCHAR BASED_CODE szPlacementFormat[] = TEXT("%u,%u,%d,%d,%d,%d,%d,%d,%d,%d");
static TCHAR BASED_CODE szFont[] = TEXT("Font");
static TCHAR BASED_CODE szFontFace[] = TEXT("FontFace");
static TCHAR BASED_CODE szFontFormat[] = TEXT("%ld,%ld,%d,%d,%d,%d");
static TCHAR BASED_CODE szConfirm[] = TEXT("Confirmation");
static TCHAR BASED_CODE szSaveSettings[] = TEXT("SaveSettingsOnExit");
static TCHAR BASED_CODE szHexBase[] = TEXT("HexBase");
static CHAR szStart[] = "ExtStart";
static CHAR szEnd[] = "ExtEnd";
static CHAR szDialog[] = "ExtDialog";
static CHAR szDeleteObject[] = "ExtDeleteObject";
static CHAR szDupObject[] = "ExtDupObject";
static CHAR szRegQuery[] = "ExtRegQuery";
static CHAR szRegCreate[] = "ExtRegCreate";
static CHAR szRegDelete[] = "ExtRegDelete";
static CHAR szCompareObjects[] = "ExtCompareObjects";
static CHAR szEncryptionLevels[] = "ExtEncryptionLevels";
static CHAR szGetCapabilities[] = "ExtGetCapabilities";
/*******************************************************************************
*
* Initialize - CWincfgApp member function: private operation
*
* Restore state settings from app's profile and initialize the
* Pd and Wd lists.
*
* ENTRY:
*
* EXIT:
* (BOOL) TRUE if initialization sucessful; FALSE otherwise.
*
******************************************************************************/
BOOL
CWincfgApp::Initialize()
{
LONG Status;
ULONG Index, Index2, ByteCount, Entries, Entries2;
PDNAME PdKey;
WDNAME WdKey;
LONG QStatus;
PTERMLOBJECT pWdListObject;
WDCONFIG2 WdConfig;
CObList *pTdList, *pPdList;
PPDLOBJECT pPdListObject;
PDCONFIG3 PdConfig;
TCHAR WdDll[MAX_PATH];
/*
* Fetch the application's profile information.
*/
GetAppProfileInfo();
/*
* Set up the application's font.
*/
m_font.DeleteObject();
m_font.CreateFontIndirect( &m_lfDefFont );
/*
* Initialize the Wd list.
*/
for ( Index = 0, Entries = 1, ByteCount = sizeof(WDNAME);
(Status =
RegWdEnumerate( SERVERNAME_CURRENT,
&Index,
&Entries,
WdKey,
&ByteCount )) == ERROR_SUCCESS;
ByteCount = sizeof(WDNAME) ) {
if ( ( QStatus = RegWdQuery( SERVERNAME_CURRENT, WdKey, &WdConfig,
sizeof(WdConfig),
&ByteCount ) ) != ERROR_SUCCESS ) {
STANDARD_ERROR_MESSAGE(( WINAPPSTUFF, LOGONID_NONE, QStatus,
IDP_ERROR_REGWDQUERY, WdKey ))
return(FALSE);
}
/*
* Only place this Wd in the WdList if it's DLL is present
* on the system.
*/
GetSystemDirectory( WdDll, MAX_PATH );
lstrcat( WdDll, TEXT("\\Drivers\\") );
lstrcat( WdDll, WdConfig.Wd.WdDLL );
lstrcat( WdDll, TEXT(".sys" ) );
if ( lstr_access( WdDll, 0 ) != 0 )
continue;
/*
* Create a new WdList object and initialize from WdConfig
* structure, adding it to the end of the WdList.
*/
if ( !(pWdListObject = new CWdListObject) ) {
ERROR_MESSAGE((IDP_ERROR_WDLISTALLOC))
return(FALSE);
}
pWdListObject->m_WdConfig = WdConfig;
pWdListObject->m_Capabilities = (ULONG)0;
// Load the extension DLL for this WD
pWdListObject->m_hExtensionDLL = ::LoadLibrary(WdConfig.Wd.CfgDLL);
if(pWdListObject->m_hExtensionDLL) {
// Get the entry points
pWdListObject->m_lpfnExtStart = (LPFNEXTSTARTPROC)::GetProcAddress(pWdListObject->m_hExtensionDLL, szStart);
pWdListObject->m_lpfnExtEnd = (LPFNEXTENDPROC)::GetProcAddress(pWdListObject->m_hExtensionDLL, szEnd);
pWdListObject->m_lpfnExtDialog = (LPFNEXTDIALOGPROC)::GetProcAddress(pWdListObject->m_hExtensionDLL, szDialog);
pWdListObject->m_lpfnExtDeleteObject = (LPFNEXTDELETEOBJECTPROC)::GetProcAddress(pWdListObject->m_hExtensionDLL, szDeleteObject);
pWdListObject->m_lpfnExtDupObject = (LPFNEXTDUPOBJECTPROC)::GetProcAddress(pWdListObject->m_hExtensionDLL, szDupObject);
pWdListObject->m_lpfnExtRegQuery = (LPFNEXTREGQUERYPROC)::GetProcAddress(pWdListObject->m_hExtensionDLL, szRegQuery);
pWdListObject->m_lpfnExtRegCreate = (LPFNEXTREGCREATEPROC)::GetProcAddress(pWdListObject->m_hExtensionDLL, szRegCreate);
pWdListObject->m_lpfnExtRegDelete = (LPFNEXTREGDELETEPROC)::GetProcAddress(pWdListObject->m_hExtensionDLL, szRegDelete);
pWdListObject->m_lpfnExtCompareObjects = (LPFNEXTCOMPAREOBJECTSPROC)::GetProcAddress(pWdListObject->m_hExtensionDLL, szCompareObjects);
pWdListObject->m_lpfnExtEncryptionLevels = (LPFNEXTENCRYPTIONLEVELSPROC)::GetProcAddress(pWdListObject->m_hExtensionDLL, szEncryptionLevels);
pWdListObject->m_lpfnExtGetCapabilities = (LPFNEXTGETCAPABILITIES)::GetProcAddress(pWdListObject->m_hExtensionDLL, szGetCapabilities);
// Call the ExtStart() function in the extension DLL
if(pWdListObject->m_lpfnExtStart)(*pWdListObject->m_lpfnExtStart)(&WdConfig.Wd.WdName);
// Call the ExtGetCapabilities function in the extension DLL
// to get the capabilities for this WD
if(pWdListObject->m_lpfnExtGetCapabilities) {
pWdListObject->m_Capabilities = (*pWdListObject->m_lpfnExtGetCapabilities)();
}
}
m_WdList.AddTail( pWdListObject );
/*
* Create and initialize Td list with all Tds defined for this Wd.
*/
if ( !(pTdList = new CObList) ) {
ERROR_MESSAGE((IDP_ERROR_TDLISTALLOC))
return(FALSE);
}
m_TdListList.AddTail( (CObject *)pTdList );
for ( Index2 = 0, Entries2 = 1, ByteCount = sizeof(PDNAME);
(Status =
RegPdEnumerate( SERVERNAME_CURRENT,
WdKey,
TRUE,
&Index2,
&Entries2,
PdKey,
&ByteCount )) == ERROR_SUCCESS;
ByteCount = sizeof(PDNAME) ) {
if ( ( QStatus = RegPdQuery( SERVERNAME_CURRENT,
WdKey,
TRUE,
PdKey,
&PdConfig,
sizeof(PdConfig),
&ByteCount ) ) != ERROR_SUCCESS ) {
STANDARD_ERROR_MESSAGE(( WINAPPSTUFF, LOGONID_NONE, QStatus,
IDP_ERROR_REGPDQUERY, PdKey ))
return(FALSE);
}
/*
* Create a new PdListObject and initialize from PdConfig
* structure, then add to the Td list.
*/
if ( !(pPdListObject = new CPdListObject) ) {
ERROR_MESSAGE((IDP_ERROR_TDLISTALLOC))
return(FALSE);
}
pPdListObject->m_PdConfig = PdConfig;
pTdList->AddTail( pPdListObject );
}
/*
* Create and initialize Pd list with all Pds defined for this Wd.
*/
if ( !(pPdList = new CObList) ) {
ERROR_MESSAGE((IDP_ERROR_PDLISTALLOC))
return(FALSE);
}
m_PdListList.AddTail( (CObject *)pPdList );
for ( Index2 = 0, Entries2 = 1, ByteCount = sizeof(PDNAME);
(Status =
RegPdEnumerate( SERVERNAME_CURRENT,
WdKey,
FALSE,
&Index2,
&Entries2,
PdKey,
&ByteCount )) == ERROR_SUCCESS;
ByteCount = sizeof(PDNAME) ) {
if ( ( QStatus = RegPdQuery( SERVERNAME_CURRENT,
WdKey,
FALSE,
PdKey,
&PdConfig,
sizeof(PdConfig),
&ByteCount ) ) != ERROR_SUCCESS ) {
STANDARD_ERROR_MESSAGE(( WINAPPSTUFF, LOGONID_NONE, QStatus,
IDP_ERROR_REGPDQUERY, PdKey ))
return(FALSE);
}
/*
* Create a new PdListObject and initialize from PdConfig
* structure, then add to the Pd list.
*/
if ( !(pPdListObject = new CPdListObject) ) {
ERROR_MESSAGE((IDP_ERROR_PDLISTALLOC))
return(FALSE);
}
pPdListObject->m_PdConfig = PdConfig;
pPdList->AddTail( pPdListObject );
}
}
/*
* If no Wds are defined, complain and return FALSE.
*/
if ( !m_WdList.GetCount() ) {
ERROR_MESSAGE((IDP_ERROR_EMPTYWDLIST))
return(FALSE);
}
return(TRUE);
} // end CWincfgApp::Initialize
/*******************************************************************************
*
* GetAppProfileInfo - CWincfgApp member function: private operation
*
* Retrieve the app's profile information from the registry, or set
* defaults if not there.
*
* ENTRY:
* EXIT:
*
******************************************************************************/
void
CWincfgApp::GetAppProfileInfo()
{
int Italic, Underline, PitchAndFamily, CharSet;
HKEY hKeyWincfg;
DWORD dwType, cbData, dwValue;
TCHAR szValue[128], *pszFontFace = TEXT("MS Shell Dlg");
/*
* Open (or create if not there) the registry key for this application.
*/
RegCreateKey(HKEY_CURRENT_USER, szWincfgAppKey, &hKeyWincfg);
/*
* Get previous WINDOWPLACEMENT.
*/
cbData = sizeof(szValue);
if ( !hKeyWincfg ||
(RegQueryValueEx( hKeyWincfg, szPlacement, NULL, &dwType,
(LPBYTE)szValue, &cbData ) != ERROR_SUCCESS ) ||
!(*szValue) ||
(lstrscanf( szValue, szPlacementFormat,
&m_Placement.flags, &m_Placement.showCmd,
&m_Placement.ptMinPosition.x, &m_Placement.ptMinPosition.y,
&m_Placement.ptMaxPosition.x, &m_Placement.ptMaxPosition.y,
&m_Placement.rcNormalPosition.left,
&m_Placement.rcNormalPosition.top,
&m_Placement.rcNormalPosition.right,
&m_Placement.rcNormalPosition.bottom ) != 10) ) {
/*
* Flag to use the default window placement.
*/
m_Placement.rcNormalPosition.right = -1;
} else {
/*
* Never use a retrieved 'hidden' state from registry.
*/
if ( m_Placement.showCmd == SW_HIDE )
m_Placement.showCmd = SW_SHOWNORMAL;
}
/*
* Flag for initial showing of main window in our override of
* CFrameWnd::ActivateFrame() (in our CMainFrame class).
*/
m_Placement.length = (UINT)-1;
/*
* Get application's font.
*/
cbData = sizeof(szValue);
if ( !hKeyWincfg ||
(RegQueryValueEx( hKeyWincfg, szFont, NULL, &dwType,
(LPBYTE)szValue, &cbData ) != ERROR_SUCCESS ) ||
!(*szValue) ||
(lstrscanf( szValue, szFontFormat,
&m_lfDefFont.lfHeight, &m_lfDefFont.lfWeight,
&Italic, &Underline, &PitchAndFamily, &CharSet ) != 6) )
{
/*
* Set up a default font.
*/
m_lfDefFont.lfHeight = -13;
m_lfDefFont.lfWeight = FW_NORMAL;
m_lfDefFont.lfItalic = 0;
m_lfDefFont.lfUnderline = 0;
m_lfDefFont.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
#ifdef DBCS
CHARSETINFO csi;
DWORD dw = ::GetACP();
if (!::TranslateCharsetInfo((DWORD *)dw, &csi, TCI_SRCCODEPAGE))
m_lfDefFont.lfCharSet = ANSI_CHARSET;
else
m_lfDefFont.lfCharSet = csi.ciCharset;
#endif
} else {
m_lfDefFont.lfItalic = (BYTE)Italic;
m_lfDefFont.lfUnderline = (BYTE)Underline;
m_lfDefFont.lfPitchAndFamily = (BYTE)PitchAndFamily;
#ifdef DBCS
m_lfDefFont.lfCharSet = CharSet;
#endif
cbData = sizeof(szValue);
if ( (RegQueryValueEx( hKeyWincfg, szFontFace, NULL, &dwType,
(LPBYTE)szValue, &cbData ) == ERROR_SUCCESS ) &&
*szValue )
pszFontFace = szValue;
}
lstrcpy( m_lfDefFont.lfFaceName, pszFontFace );
/*
* Get other profile settings.
*/
cbData = sizeof(m_nConfirmation);
if ( !hKeyWincfg ||
(RegQueryValueEx( hKeyWincfg, szConfirm, NULL, &dwType,
(LPBYTE)&dwValue, &cbData ) != ERROR_SUCCESS) )
m_nConfirmation = 1;
else
m_nConfirmation = dwValue;
cbData = sizeof(m_nSaveSettingsOnExit);
if ( !hKeyWincfg ||
(RegQueryValueEx( hKeyWincfg, szSaveSettings, NULL, &dwType,
(LPBYTE)&dwValue, &cbData ) != ERROR_SUCCESS) )
m_nSaveSettingsOnExit = 1;
else
m_nSaveSettingsOnExit = dwValue;
cbData = sizeof(m_nHexBase);
if ( !hKeyWincfg ||
(RegQueryValueEx( hKeyWincfg, szHexBase, NULL, &dwType,
(LPBYTE)&dwValue, &cbData ) != ERROR_SUCCESS) )
m_nHexBase = 1;
else
m_nHexBase = dwValue;
if ( hKeyWincfg )
RegCloseKey(hKeyWincfg);
} // end CWincfgApp::GetAppProfileInfo
/*******************************************************************************
*
* Terminate - CWincfgApp member function: public operation
*
* Save state settings to the app's profile and free the Pd and Wd
* list contents.
*
* ENTRY:
* EXIT:
*
******************************************************************************/
void
CWincfgApp::Terminate()
{
POSITION pos1, pos2, pos3, pos4;
CObject *pObject;
CObList *pTdList, *pPdList;
/*
* Save app profile information.
*/
SetAppProfileInfo();
/*
* We need to close all documents here so that when CWinStationListObjects
* are deleted in the document they can find the proper Wd in the WdList
* so that they can call the proper extension DLL to delete it's
* corresponding object.
*/
CloseAllDocuments(1);
/*
* Clean up the TdList list.
*/
for ( pos1 = m_TdListList.GetHeadPosition(); (pos2 = pos1) != NULL; ) {
m_TdListList.GetNext( pos1 );
pTdList = (CObList *)m_TdListList.GetAt( pos2 );
for ( pos3 = pTdList->GetHeadPosition(); (pos4 = pos3) != NULL; ) {
pTdList->GetNext( pos3 );
pObject = pTdList->GetAt( pos4 );
pTdList->RemoveAt( pos4 );
delete ( pObject );
}
m_TdListList.RemoveAt( pos2 );
delete ( pTdList );
}
/*
* Clean up the PdList list.
*/
for ( pos1 = m_PdListList.GetHeadPosition(); (pos2 = pos1) != NULL; ) {
m_PdListList.GetNext( pos1 );
pPdList = (CObList *)m_PdListList.GetAt( pos2 );
for ( pos3 = pPdList->GetHeadPosition(); (pos4 = pos3) != NULL; ) {
pPdList->GetNext( pos3 );
pObject = pPdList->GetAt( pos4 );
pPdList->RemoveAt( pos4 );
delete ( pObject );
}
m_PdListList.RemoveAt( pos2 );
delete ( pPdList );
}
/*
* Clean up the WdList.
*/
for ( pos1 = m_WdList.GetHeadPosition(); (pos2 = pos1) != NULL; ) {
m_WdList.GetNext( pos1 );
pObject = m_WdList.GetAt( pos2 );
m_WdList.RemoveAt( pos2 );
if(((PTERMLOBJECT)pObject)->m_hExtensionDLL) {
if(((PTERMLOBJECT)pObject)->m_lpfnExtEnd) (*((PTERMLOBJECT)pObject)->m_lpfnExtEnd)();
::FreeLibrary(((PTERMLOBJECT)pObject)->m_hExtensionDLL);
}
delete ( pObject );
}
/*
* Clean up security strings (in case security functions were requested).
*/
FreeSecurityStrings();
CoUninitialize();
} // end CWincfgApp::Terminate
/*******************************************************************************
*
* SetAppProfileInfo - CWincfgApp member function: private operation
*
* Save the app's profile information to the registry, if requested.
*
* ENTRY:
* EXIT:
*
******************************************************************************/
void
CWincfgApp::SetAppProfileInfo()
{
HKEY hKeyWincfg;
DWORD dwValue;
TCHAR szValue[128];
/*
* Open the registry key for this application.
*/
RegCreateKey(HKEY_CURRENT_USER, szWincfgAppKey, &hKeyWincfg);
/*
* Save settings if requested by user and we're not in batch mode.
*/
if ( hKeyWincfg && m_nSaveSettingsOnExit && !g_Batch ) {
/*
* Fetch and set current window placement.
*/
if ( m_pMainWnd &&
m_pMainWnd->GetWindowPlacement(&m_Placement) ) {
m_Placement.flags = 0;
if ( m_pMainWnd->IsZoomed() )
m_Placement.flags |= WPF_RESTORETOMAXIMIZED;
wsprintf( szValue, szPlacementFormat,
m_Placement.flags, m_Placement.showCmd,
m_Placement.ptMinPosition.x, m_Placement.ptMinPosition.y,
m_Placement.ptMaxPosition.x, m_Placement.ptMaxPosition.y,
m_Placement.rcNormalPosition.left,
m_Placement.rcNormalPosition.top,
m_Placement.rcNormalPosition.right,
m_Placement.rcNormalPosition.bottom);
RegSetValueEx( hKeyWincfg, szPlacement, 0, REG_SZ,
(LPBYTE)szValue,
(lstrlen(szValue) + 1) * sizeof(TCHAR) );
}
/*
* Set the current font.
*/
wsprintf( szValue, szFontFormat,
m_lfDefFont.lfHeight, m_lfDefFont.lfWeight,
m_lfDefFont.lfItalic, m_lfDefFont.lfUnderline,
m_lfDefFont.lfPitchAndFamily, m_lfDefFont.lfCharSet);
RegSetValueEx( hKeyWincfg, szFont, 0, REG_SZ,
(LPBYTE)szValue,
(lstrlen(szValue) + 1) * sizeof(TCHAR) );
lstrcpy(szValue,m_lfDefFont.lfFaceName);
RegSetValueEx( hKeyWincfg, szFontFace, 0, REG_SZ,
(LPBYTE)szValue,
(lstrlen(szValue) + 1) * sizeof(TCHAR) );
/*
* Set other profile settings.
*/
dwValue = m_nConfirmation;
RegSetValueEx( hKeyWincfg, szConfirm, 0, REG_DWORD,
(LPBYTE)&dwValue, sizeof(DWORD) );
dwValue = m_nHexBase;
RegSetValueEx( hKeyWincfg, szHexBase, 0, REG_DWORD,
(LPBYTE)&dwValue, sizeof(DWORD) );
}
/*
* Always write the "SaveSettingsOnExit" value to retain user's preference.
*/
if ( hKeyWincfg ) {
dwValue = m_nSaveSettingsOnExit;
RegSetValueEx( hKeyWincfg, szSaveSettings, 0, REG_DWORD,
(LPBYTE)&dwValue, sizeof(DWORD) );
RegCloseKey(hKeyWincfg);
}
} // end CWincfgApp::SetAppProfileInfo
////////////////////////////////////////////////////////////////////////////////
// CWincfgApp message map
#pragma warning( disable : 4245 ) // can remove when we update to MFC 3.0
BEGIN_MESSAGE_MAP(CWincfgApp, CWinApp)
//{{AFX_MSG_MAP(CWincfgApp)
ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
ON_COMMAND(ID_OPTIONS_FONT, OnOptionsFont)
ON_COMMAND(ID_OPTIONS_CONFIRMATION, OnOptionsConfirmation)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_CONFIRMATION, OnUpdateOptionsConfirmation)
ON_COMMAND(ID_OPTIONS_SAVE_SETTINGS_ON_EXIT, OnOptionsSaveSettingsOnExit)
ON_UPDATE_COMMAND_UI(ID_OPTIONS_SAVE_SETTINGS_ON_EXIT, OnUpdateOptionsSaveSettingsOnExit)
ON_COMMAND(ID_HELP_SEARCH_FOR, OnHelpSearchFor)
ON_COMMAND(ID_HELP, OnHelp)
//}}AFX_MSG_MAP
// Global help commands
ON_COMMAND(ID_HELP_INDEX, CWinApp::OnHelpIndex)
ON_COMMAND(ID_HELP_USING, CWinApp::OnHelpUsing)
ON_COMMAND(ID_CONTEXT_HELP, CWinApp::OnContextHelp)
ON_COMMAND(ID_DEFAULT_HELP, CWinApp::OnHelpIndex)
END_MESSAGE_MAP()
#pragma warning( default : 4245 ) // can remove when we update to MFC 3.0
////////////////////////////////////////////////////////////////////////////////
// CWincfgApp commands
/*******************************************************************************
*
* OnAppAbout - CWincfgApp member function: command
*
* Display the about box dialog (uses Shell32 generic About dialog).
*
* ENTRY:
* EXIT:
*
******************************************************************************/
// Typedef for the ShellAbout function
typedef void (WINAPI *LPFNSHELLABOUT)(HWND, LPCTSTR, LPCTSTR, HICON);
void
CWincfgApp::OnAppAbout()
{
HMODULE hMod;
LPFNSHELLABOUT lpfn;
if (hMod = ::LoadLibrary(TEXT("SHELL32")))
{
if (lpfn = (LPFNSHELLABOUT)::GetProcAddress( hMod,
#ifdef UNICODE
"ShellAboutW"
#else
"ShellAboutA"
#endif // UNICODE
))
{
(*lpfn)( m_pMainWnd->m_hWnd, (LPCTSTR)m_pszAppName,
(LPCTSTR)(TEXT("")), LoadIcon(IDR_MAINFRAME) );
}
::FreeLibrary(hMod);
}
else
{
::MessageBeep( MB_ICONEXCLAMATION );
}
} // end CWincfgApp::OnAppAbout
/*******************************************************************************
*
* OnOptionsFont - CWincfgApp member function: command
*
* Prompt for a new font to use in views and set if given.
*
* ENTRY:
*
* EXIT:
*
******************************************************************************/
void
CWincfgApp::OnOptionsFont()
{
CFontDialog dlg( &m_lfDefFont, CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT );
/*
* We don't want the Help button since none of the other NT utilities
* in our 'family' offer this. Also, we need to block the F1 'help' and
* unblock when done.
*/
dlg.m_cf.Flags &= ~CF_SHOWHELP;
m_bAllowHelp = FALSE;
if ( dlg.DoModal() == IDOK ) {
/*
* switch to newly selected font.
*/
m_font.DeleteObject();
if ( m_font.CreateFontIndirect( &m_lfDefFont ) ) {
CAppServerView *pView;
/*
* Update the view.
*
* NOTE: Call the MDIGetActive function in a loop for MDI
* application to get each MDI Child window, then get the view
* associated with each child window and call its ResetView
* member function with TRUE argument to cause new field maximums
* to be calculated.
*/
if ( (pView = (CAppServerView *)
((CMainFrame *)(m_pMainWnd))->GetActiveView()) )
pView->ResetView( TRUE );
}
}
m_bAllowHelp = TRUE;
} // end CWincfgApp::OnOptionsFont
/*******************************************************************************
*
* OnOptionsConfirmation- CWincfgApp member function: command
*
* Toggle the "confirmation" flag.
*
* ENTRY:
*
* EXIT:
*
******************************************************************************/
void
CWincfgApp::OnOptionsConfirmation()
{
m_nConfirmation ^= 1;
} // end CWincfgApp::OnOptionsConfirmation
/*******************************************************************************
*
* OnUpdateOptionsConfirmation - CWincfgApp member function: command
*
* Check or uncheck the "confirmation" menu item based on the state
* of the m_nConfirmation flag.
*
* ENTRY:
*
* pCndUI (input)
* Points to the CCmdUI object of the "confirmation" menu item.
*
* EXIT:
*
******************************************************************************/
void
CWincfgApp::OnUpdateOptionsConfirmation( CCmdUI* pCmdUI )
{
pCmdUI->SetCheck( m_nConfirmation );
} // end CWincfgApp::OnUpdateOptionsConfirmation
/*******************************************************************************
*
* OnOptionsSaveSettingsOnExit - CWincfgApp member function: command
*
* Toggle the "save settings on exit" flag.
*
* ENTRY:
*
* EXIT:
*
******************************************************************************/
void
CWincfgApp::OnOptionsSaveSettingsOnExit()
{
m_nSaveSettingsOnExit ^= 1;
} // end CWincfgApp::OnOptionsSaveSettingsOnExit
/*******************************************************************************
*
* OnUpdateOptionsSaveSettingsOnExit - CWincfgApp member function: command
*
* Check or uncheck the "save settings on exit" menu item based on the
* state of the m_nSaveSettingsOnExit flag.
*
* ENTRY:
*
* pCndUI (input)
* Points to the CCmdUI object of the "save settings on exit"
* menu item.
*
* EXIT:
*
******************************************************************************/
void
CWincfgApp::OnUpdateOptionsSaveSettingsOnExit( CCmdUI* pCmdUI )
{
pCmdUI->SetCheck( m_nSaveSettingsOnExit );
} // end CWincfgApp::OnUpdateOptionsSaveSettingsOnExit
/*******************************************************************************
*
* OnHelp - CWincfgApp member function: command
*
* Invoke standard CWinApp::WinHelp if we're allowing help at this time.
*
* ENTRY:
* EXIT:
*
******************************************************************************/
void
CWincfgApp::OnHelp()
{
/*
* If we're allowing help now, call default help helper.
*/
if ( m_bAllowHelp )
CWinApp::OnHelp();
} // end CWincfgApp::OnHelp
/*******************************************************************************
*
* OnHelpSearchFor - CWincfgApp member function: command
*
* Invoke WinHelp on our app's help file to bring up the 'search' window.
*
* ENTRY:
* EXIT:
*
******************************************************************************/
void
CWincfgApp::OnHelpSearchFor()
{
WinHelp((DWORD)((LPCTSTR)TEXT("")), HELP_PARTIALKEY);
} // end CWincfgApp::OnHelpSearchFor
/*******************************************************************************
*
* AreWeRunningTerminalServices
*
* Check if we are running terminal server
*
* ENTRY:
*
* EXIT: BOOL: True if we are running Terminal Services False if we
* are not running Terminal Services
*
*
******************************************************************************/
BOOL AreWeRunningTerminalServices(void)
{
OSVERSIONINFOEX osVersionInfo;
DWORDLONG dwlConditionMask = 0;
ZeroMemory(&osVersionInfo, sizeof(OSVERSIONINFOEX));
osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
osVersionInfo.wSuiteMask = VER_SUITE_TERMINAL;
VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_AND );
return VerifyVersionInfo(
&osVersionInfo,
VER_SUITENAME,
dwlConditionMask
);
}
////////////////////////////////////////////////////////////////////////////////