//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 #include #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 ); } ////////////////////////////////////////////////////////////////////////////////