Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1112 lines
34 KiB

  1. //Copyright (c) 1998 - 1999 Microsoft Corporation
  2. /*******************************************************************************
  3. *
  4. * wincfg.cpp
  5. *
  6. * WinStation Configuration application
  7. *
  8. * copyright notice: Copyright 1996, Citrix Systems Inc.
  9. *
  10. * $Author: donm $ Butch Davis
  11. *
  12. * $Log: N:\nt\private\utils\citrix\winutils\tscfg\VCS\wincfg.cpp $
  13. *
  14. * Rev 1.34 24 Apr 1998 09:44:28 donm
  15. * removed command line options
  16. *
  17. * Rev 1.33 18 Apr 1998 15:31:42 donm
  18. * Added capability bits
  19. *
  20. * Rev 1.32 14 Feb 1998 11:22:38 donm
  21. * fixed memory leak by avoiding CDocManager::OpenDocumentFile
  22. *
  23. * Rev 1.31 26 Jan 1998 18:33:04 thanhl
  24. * Save CharSet Font info
  25. *
  26. * Rev 1.30 13 Jan 1998 14:08:38 donm
  27. * gets encryption levels from extension DLL
  28. *
  29. * Rev 1.29 10 Dec 1997 15:59:28 donm
  30. * added ability to have extension DLLs
  31. *
  32. * Rev 1.28 26 Sep 1997 19:05:06 butchd
  33. * Hydra registry name changes
  34. *
  35. * Rev 1.27 02 Jul 1997 15:21:10 butchd
  36. * update
  37. *
  38. * Rev 1.26 27 Jun 1997 15:58:42 butchd
  39. * Registry changes for Wds/Tds/Pds/Cds
  40. *
  41. *******************************************************************************/
  42. /*
  43. * include files
  44. */
  45. #include "stdafx.h"
  46. #include "wincfg.h"
  47. #include "mainfrm.h"
  48. #include "rowview.h"
  49. #include "appsvdoc.h"
  50. #include "appsvvw.h"
  51. #include "security.h"
  52. #include <errno.h>
  53. #include <hydra\regapi.h>
  54. #ifdef _DEBUG
  55. #undef THIS_FILE
  56. static char BASED_CODE THIS_FILE[] = __FILE__;
  57. #endif
  58. /*
  59. * Global command line variables.
  60. */
  61. extern USHORT g_Add;
  62. /*
  63. * Global variables for WINUTILS Common functions.
  64. */
  65. extern "C" {
  66. LPCTSTR WinUtilsAppName = NULL;
  67. HWND WinUtilsAppWindow = NULL;
  68. HINSTANCE WinUtilsAppInstance = NULL;
  69. }
  70. ////////////////////////////////////////////////////////////////////////////////
  71. // CWincfgApp class implementation / construction, destruction
  72. /*******************************************************************************
  73. *
  74. * CWincfgApp - CWincfgApp constructor
  75. *
  76. * ENTRY:
  77. * EXIT:
  78. *
  79. ******************************************************************************/
  80. CWincfgApp::CWincfgApp()
  81. : m_pszRegWinStationCreate(TEXT("RegWinStationCreate")),
  82. m_pszRegWinStationSetSecurity(TEXT("RegWinStationSetSecurity")),
  83. m_pszRegWinStationQuery(TEXT("RegWinStationQuery")),
  84. m_pszRegWinStationDelete(TEXT("RegWinStationDelete")),
  85. m_pszGetDefaultWinStationSecurity(TEXT("GetDefaultWinStationSecurity")),
  86. m_pszGetWinStationSecurity(TEXT("GetWinStationSecurity"))
  87. {
  88. } // end CWincfgApp::CWincfgApp
  89. ////////////////////////////////////////////////////////////////////////////////
  90. // The one and only CWincfgApp object and a application-global reference to it.
  91. CWincfgApp theApp;
  92. CWincfgApp *pApp = &theApp;
  93. BOOL AreWeRunningTerminalServices(void);
  94. ////////////////////////////////////////////////////////////////////////////////
  95. // CWincfgApp overrides of MFC CWinApp class
  96. /*******************************************************************************
  97. *
  98. * InitInstance - CWincfgApp member function: CWinApp override
  99. *
  100. * Perform application initialization and previous state restoration.
  101. *
  102. * ENTRY:
  103. *
  104. * EXIT:
  105. * (BOOL)
  106. * TRUE if initialization sucessful; FALSE otherwise.
  107. *
  108. ******************************************************************************/
  109. BOOL
  110. CWincfgApp::InitInstance()
  111. {
  112. //Check if we are running under Terminal Server
  113. if(!AreWeRunningTerminalServices())
  114. {
  115. AfxMessageBox(IDS_ERROR_NOT_TS,MB_OK |MB_ICONSTOP );
  116. return FALSE;
  117. }
  118. if(FAILED(CoInitialize(NULL)))
  119. return FALSE;
  120. /*
  121. * Initialize the global WINUTILS app name and instance variables.
  122. */
  123. WinUtilsAppName = AfxGetAppName();
  124. WinUtilsAppInstance = AfxGetInstanceHandle();
  125. /*
  126. * Fetch and save the Computer Name as the local AppServer and current
  127. * AppServer.
  128. */
  129. DWORD cchBuffer = MAX_COMPUTERNAME_LENGTH+1;
  130. m_szLocalAppServer[0] = m_szLocalAppServer[1] = TEXT('\\');
  131. GetComputerName(m_szLocalAppServer+2, &cchBuffer);
  132. lstrcpy(m_szCurrentAppServer, m_szLocalAppServer);
  133. /*
  134. * Load the system console string for rapid comparison in the 'IsAllowed'
  135. * functions.
  136. */
  137. LoadString( m_hInstance, IDS_SYSTEM_CONSOLE_NAME,
  138. m_szSystemConsole, WINSTATIONNAME_LENGTH );
  139. /*
  140. * Default to 'help allowed'.
  141. */
  142. m_bAllowHelp = TRUE;
  143. /*
  144. * Initialize the application defaults.
  145. */
  146. if ( !Initialize() )
  147. return(FALSE);
  148. /*
  149. * Register the application's document templates. Document templates
  150. * serve as the connection between documents, frame windows and views.
  151. */
  152. CSingleDocTemplate *pTemplate = new CSingleDocTemplate( IDR_MAINFRAME,
  153. RUNTIME_CLASS(CAppServerDoc),
  154. RUNTIME_CLASS(CMainFrame),
  155. RUNTIME_CLASS(CAppServerView) );
  156. if(!pTemplate) return(FALSE);
  157. AddDocTemplate(pTemplate);
  158. /*
  159. * open the initial document window for the current (default local) AppServer.
  160. * NOTE: We can't call CWinApp::OpenDocumentFile because it causes
  161. * a memory leek in SHELL32.DLL SHGetFileInfo since we were trying to
  162. * pass the server name (i.e. \\MYSERVER) as the file name.
  163. * CWinApp::OpenDocumentFile will trap if we pass a NULL, therefore
  164. * we call CSingleDocTemplate::OpenDocumentFile which can handle
  165. * a NULL.
  166. */
  167. if(!pTemplate->OpenDocumentFile(NULL)) {
  168. Terminate();
  169. return(FALSE);
  170. } else {
  171. CAppServerDoc *pDoc =
  172. (CAppServerDoc *)((CFrameWnd *)m_pMainWnd)->GetActiveDocument();
  173. /*
  174. * Initialize the global WINUTILS app window handle.
  175. */
  176. WinUtilsAppWindow = m_pMainWnd->m_hWnd;
  177. #ifdef USING_3DCONTROLS
  178. Enable3dControls();
  179. #endif
  180. /*
  181. * Take care of special command line flags (only one allowed
  182. * at a time).
  183. */
  184. if ( g_Add )
  185. m_pMainWnd->PostMessage(WM_ADDWINSTATION);
  186. return(TRUE);
  187. }
  188. } // end CWincfgApp::InitInstance
  189. /*******************************************************************************
  190. *
  191. * AddToRecentFileList - CWincfgApp member function: override
  192. *
  193. * Suppress the adding of MRU file names to .INI file.
  194. *
  195. * ENTRY:
  196. * EXIT:
  197. * (Refer to CWinApp::AddToRecentFileList documentation)
  198. *
  199. ******************************************************************************/
  200. void
  201. CWincfgApp::AddToRecentFileList( const char * pszPathName )
  202. {
  203. /*
  204. * Don't do anything: we don't use a MRU or .INI file.
  205. */
  206. } // end CWincfgApp::AddToRecentFileList
  207. ////////////////////////////////////////////////////////////////////////////////
  208. // CWincfgApp Operations
  209. static TCHAR BASED_CODE szWincfgAppKey[] = REG_SOFTWARE_TSERVER TEXT("\\TSCFG");
  210. static TCHAR BASED_CODE szPlacement[] = TEXT("Placement");
  211. static TCHAR BASED_CODE szPlacementFormat[] = TEXT("%u,%u,%d,%d,%d,%d,%d,%d,%d,%d");
  212. static TCHAR BASED_CODE szFont[] = TEXT("Font");
  213. static TCHAR BASED_CODE szFontFace[] = TEXT("FontFace");
  214. static TCHAR BASED_CODE szFontFormat[] = TEXT("%ld,%ld,%d,%d,%d,%d");
  215. static TCHAR BASED_CODE szConfirm[] = TEXT("Confirmation");
  216. static TCHAR BASED_CODE szSaveSettings[] = TEXT("SaveSettingsOnExit");
  217. static TCHAR BASED_CODE szHexBase[] = TEXT("HexBase");
  218. static CHAR szStart[] = "ExtStart";
  219. static CHAR szEnd[] = "ExtEnd";
  220. static CHAR szDialog[] = "ExtDialog";
  221. static CHAR szDeleteObject[] = "ExtDeleteObject";
  222. static CHAR szDupObject[] = "ExtDupObject";
  223. static CHAR szRegQuery[] = "ExtRegQuery";
  224. static CHAR szRegCreate[] = "ExtRegCreate";
  225. static CHAR szRegDelete[] = "ExtRegDelete";
  226. static CHAR szCompareObjects[] = "ExtCompareObjects";
  227. static CHAR szEncryptionLevels[] = "ExtEncryptionLevels";
  228. static CHAR szGetCapabilities[] = "ExtGetCapabilities";
  229. /*******************************************************************************
  230. *
  231. * Initialize - CWincfgApp member function: private operation
  232. *
  233. * Restore state settings from app's profile and initialize the
  234. * Pd and Wd lists.
  235. *
  236. * ENTRY:
  237. *
  238. * EXIT:
  239. * (BOOL) TRUE if initialization sucessful; FALSE otherwise.
  240. *
  241. ******************************************************************************/
  242. BOOL
  243. CWincfgApp::Initialize()
  244. {
  245. LONG Status;
  246. ULONG Index, Index2, ByteCount, Entries, Entries2;
  247. PDNAME PdKey;
  248. WDNAME WdKey;
  249. LONG QStatus;
  250. PTERMLOBJECT pWdListObject;
  251. WDCONFIG2 WdConfig;
  252. CObList *pTdList, *pPdList;
  253. PPDLOBJECT pPdListObject;
  254. PDCONFIG3 PdConfig;
  255. TCHAR WdDll[MAX_PATH];
  256. /*
  257. * Fetch the application's profile information.
  258. */
  259. GetAppProfileInfo();
  260. /*
  261. * Set up the application's font.
  262. */
  263. m_font.DeleteObject();
  264. m_font.CreateFontIndirect( &m_lfDefFont );
  265. /*
  266. * Initialize the Wd list.
  267. */
  268. for ( Index = 0, Entries = 1, ByteCount = sizeof(WDNAME);
  269. (Status =
  270. RegWdEnumerate( SERVERNAME_CURRENT,
  271. &Index,
  272. &Entries,
  273. WdKey,
  274. &ByteCount )) == ERROR_SUCCESS;
  275. ByteCount = sizeof(WDNAME) ) {
  276. if ( ( QStatus = RegWdQuery( SERVERNAME_CURRENT, WdKey, &WdConfig,
  277. sizeof(WdConfig),
  278. &ByteCount ) ) != ERROR_SUCCESS ) {
  279. STANDARD_ERROR_MESSAGE(( WINAPPSTUFF, LOGONID_NONE, QStatus,
  280. IDP_ERROR_REGWDQUERY, WdKey ))
  281. return(FALSE);
  282. }
  283. /*
  284. * Only place this Wd in the WdList if it's DLL is present
  285. * on the system.
  286. */
  287. GetSystemDirectory( WdDll, MAX_PATH );
  288. lstrcat( WdDll, TEXT("\\Drivers\\") );
  289. lstrcat( WdDll, WdConfig.Wd.WdDLL );
  290. lstrcat( WdDll, TEXT(".sys" ) );
  291. if ( lstr_access( WdDll, 0 ) != 0 )
  292. continue;
  293. /*
  294. * Create a new WdList object and initialize from WdConfig
  295. * structure, adding it to the end of the WdList.
  296. */
  297. if ( !(pWdListObject = new CWdListObject) ) {
  298. ERROR_MESSAGE((IDP_ERROR_WDLISTALLOC))
  299. return(FALSE);
  300. }
  301. pWdListObject->m_WdConfig = WdConfig;
  302. pWdListObject->m_Capabilities = (ULONG)0;
  303. // Load the extension DLL for this WD
  304. pWdListObject->m_hExtensionDLL = ::LoadLibrary(WdConfig.Wd.CfgDLL);
  305. if(pWdListObject->m_hExtensionDLL) {
  306. // Get the entry points
  307. pWdListObject->m_lpfnExtStart = (LPFNEXTSTARTPROC)::GetProcAddress(pWdListObject->m_hExtensionDLL, szStart);
  308. pWdListObject->m_lpfnExtEnd = (LPFNEXTENDPROC)::GetProcAddress(pWdListObject->m_hExtensionDLL, szEnd);
  309. pWdListObject->m_lpfnExtDialog = (LPFNEXTDIALOGPROC)::GetProcAddress(pWdListObject->m_hExtensionDLL, szDialog);
  310. pWdListObject->m_lpfnExtDeleteObject = (LPFNEXTDELETEOBJECTPROC)::GetProcAddress(pWdListObject->m_hExtensionDLL, szDeleteObject);
  311. pWdListObject->m_lpfnExtDupObject = (LPFNEXTDUPOBJECTPROC)::GetProcAddress(pWdListObject->m_hExtensionDLL, szDupObject);
  312. pWdListObject->m_lpfnExtRegQuery = (LPFNEXTREGQUERYPROC)::GetProcAddress(pWdListObject->m_hExtensionDLL, szRegQuery);
  313. pWdListObject->m_lpfnExtRegCreate = (LPFNEXTREGCREATEPROC)::GetProcAddress(pWdListObject->m_hExtensionDLL, szRegCreate);
  314. pWdListObject->m_lpfnExtRegDelete = (LPFNEXTREGDELETEPROC)::GetProcAddress(pWdListObject->m_hExtensionDLL, szRegDelete);
  315. pWdListObject->m_lpfnExtCompareObjects = (LPFNEXTCOMPAREOBJECTSPROC)::GetProcAddress(pWdListObject->m_hExtensionDLL, szCompareObjects);
  316. pWdListObject->m_lpfnExtEncryptionLevels = (LPFNEXTENCRYPTIONLEVELSPROC)::GetProcAddress(pWdListObject->m_hExtensionDLL, szEncryptionLevels);
  317. pWdListObject->m_lpfnExtGetCapabilities = (LPFNEXTGETCAPABILITIES)::GetProcAddress(pWdListObject->m_hExtensionDLL, szGetCapabilities);
  318. // Call the ExtStart() function in the extension DLL
  319. if(pWdListObject->m_lpfnExtStart)(*pWdListObject->m_lpfnExtStart)(&WdConfig.Wd.WdName);
  320. // Call the ExtGetCapabilities function in the extension DLL
  321. // to get the capabilities for this WD
  322. if(pWdListObject->m_lpfnExtGetCapabilities) {
  323. pWdListObject->m_Capabilities = (*pWdListObject->m_lpfnExtGetCapabilities)();
  324. }
  325. }
  326. m_WdList.AddTail( pWdListObject );
  327. /*
  328. * Create and initialize Td list with all Tds defined for this Wd.
  329. */
  330. if ( !(pTdList = new CObList) ) {
  331. ERROR_MESSAGE((IDP_ERROR_TDLISTALLOC))
  332. return(FALSE);
  333. }
  334. m_TdListList.AddTail( (CObject *)pTdList );
  335. for ( Index2 = 0, Entries2 = 1, ByteCount = sizeof(PDNAME);
  336. (Status =
  337. RegPdEnumerate( SERVERNAME_CURRENT,
  338. WdKey,
  339. TRUE,
  340. &Index2,
  341. &Entries2,
  342. PdKey,
  343. &ByteCount )) == ERROR_SUCCESS;
  344. ByteCount = sizeof(PDNAME) ) {
  345. if ( ( QStatus = RegPdQuery( SERVERNAME_CURRENT,
  346. WdKey,
  347. TRUE,
  348. PdKey,
  349. &PdConfig,
  350. sizeof(PdConfig),
  351. &ByteCount ) ) != ERROR_SUCCESS ) {
  352. STANDARD_ERROR_MESSAGE(( WINAPPSTUFF, LOGONID_NONE, QStatus,
  353. IDP_ERROR_REGPDQUERY, PdKey ))
  354. return(FALSE);
  355. }
  356. /*
  357. * Create a new PdListObject and initialize from PdConfig
  358. * structure, then add to the Td list.
  359. */
  360. if ( !(pPdListObject = new CPdListObject) ) {
  361. ERROR_MESSAGE((IDP_ERROR_TDLISTALLOC))
  362. return(FALSE);
  363. }
  364. pPdListObject->m_PdConfig = PdConfig;
  365. pTdList->AddTail( pPdListObject );
  366. }
  367. /*
  368. * Create and initialize Pd list with all Pds defined for this Wd.
  369. */
  370. if ( !(pPdList = new CObList) ) {
  371. ERROR_MESSAGE((IDP_ERROR_PDLISTALLOC))
  372. return(FALSE);
  373. }
  374. m_PdListList.AddTail( (CObject *)pPdList );
  375. for ( Index2 = 0, Entries2 = 1, ByteCount = sizeof(PDNAME);
  376. (Status =
  377. RegPdEnumerate( SERVERNAME_CURRENT,
  378. WdKey,
  379. FALSE,
  380. &Index2,
  381. &Entries2,
  382. PdKey,
  383. &ByteCount )) == ERROR_SUCCESS;
  384. ByteCount = sizeof(PDNAME) ) {
  385. if ( ( QStatus = RegPdQuery( SERVERNAME_CURRENT,
  386. WdKey,
  387. FALSE,
  388. PdKey,
  389. &PdConfig,
  390. sizeof(PdConfig),
  391. &ByteCount ) ) != ERROR_SUCCESS ) {
  392. STANDARD_ERROR_MESSAGE(( WINAPPSTUFF, LOGONID_NONE, QStatus,
  393. IDP_ERROR_REGPDQUERY, PdKey ))
  394. return(FALSE);
  395. }
  396. /*
  397. * Create a new PdListObject and initialize from PdConfig
  398. * structure, then add to the Pd list.
  399. */
  400. if ( !(pPdListObject = new CPdListObject) ) {
  401. ERROR_MESSAGE((IDP_ERROR_PDLISTALLOC))
  402. return(FALSE);
  403. }
  404. pPdListObject->m_PdConfig = PdConfig;
  405. pPdList->AddTail( pPdListObject );
  406. }
  407. }
  408. /*
  409. * If no Wds are defined, complain and return FALSE.
  410. */
  411. if ( !m_WdList.GetCount() ) {
  412. ERROR_MESSAGE((IDP_ERROR_EMPTYWDLIST))
  413. return(FALSE);
  414. }
  415. return(TRUE);
  416. } // end CWincfgApp::Initialize
  417. /*******************************************************************************
  418. *
  419. * GetAppProfileInfo - CWincfgApp member function: private operation
  420. *
  421. * Retrieve the app's profile information from the registry, or set
  422. * defaults if not there.
  423. *
  424. * ENTRY:
  425. * EXIT:
  426. *
  427. ******************************************************************************/
  428. void
  429. CWincfgApp::GetAppProfileInfo()
  430. {
  431. int Italic, Underline, PitchAndFamily, CharSet;
  432. HKEY hKeyWincfg;
  433. DWORD dwType, cbData, dwValue;
  434. TCHAR szValue[128], *pszFontFace = TEXT("MS Shell Dlg");
  435. /*
  436. * Open (or create if not there) the registry key for this application.
  437. */
  438. RegCreateKey(HKEY_CURRENT_USER, szWincfgAppKey, &hKeyWincfg);
  439. /*
  440. * Get previous WINDOWPLACEMENT.
  441. */
  442. cbData = sizeof(szValue);
  443. if ( !hKeyWincfg ||
  444. (RegQueryValueEx( hKeyWincfg, szPlacement, NULL, &dwType,
  445. (LPBYTE)szValue, &cbData ) != ERROR_SUCCESS ) ||
  446. !(*szValue) ||
  447. (lstrscanf( szValue, szPlacementFormat,
  448. &m_Placement.flags, &m_Placement.showCmd,
  449. &m_Placement.ptMinPosition.x, &m_Placement.ptMinPosition.y,
  450. &m_Placement.ptMaxPosition.x, &m_Placement.ptMaxPosition.y,
  451. &m_Placement.rcNormalPosition.left,
  452. &m_Placement.rcNormalPosition.top,
  453. &m_Placement.rcNormalPosition.right,
  454. &m_Placement.rcNormalPosition.bottom ) != 10) ) {
  455. /*
  456. * Flag to use the default window placement.
  457. */
  458. m_Placement.rcNormalPosition.right = -1;
  459. } else {
  460. /*
  461. * Never use a retrieved 'hidden' state from registry.
  462. */
  463. if ( m_Placement.showCmd == SW_HIDE )
  464. m_Placement.showCmd = SW_SHOWNORMAL;
  465. }
  466. /*
  467. * Flag for initial showing of main window in our override of
  468. * CFrameWnd::ActivateFrame() (in our CMainFrame class).
  469. */
  470. m_Placement.length = (UINT)-1;
  471. /*
  472. * Get application's font.
  473. */
  474. cbData = sizeof(szValue);
  475. if ( !hKeyWincfg ||
  476. (RegQueryValueEx( hKeyWincfg, szFont, NULL, &dwType,
  477. (LPBYTE)szValue, &cbData ) != ERROR_SUCCESS ) ||
  478. !(*szValue) ||
  479. (lstrscanf( szValue, szFontFormat,
  480. &m_lfDefFont.lfHeight, &m_lfDefFont.lfWeight,
  481. &Italic, &Underline, &PitchAndFamily, &CharSet ) != 6) )
  482. {
  483. /*
  484. * Set up a default font.
  485. */
  486. m_lfDefFont.lfHeight = -13;
  487. m_lfDefFont.lfWeight = FW_NORMAL;
  488. m_lfDefFont.lfItalic = 0;
  489. m_lfDefFont.lfUnderline = 0;
  490. m_lfDefFont.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
  491. #ifdef DBCS
  492. CHARSETINFO csi;
  493. DWORD dw = ::GetACP();
  494. if (!::TranslateCharsetInfo((DWORD *)dw, &csi, TCI_SRCCODEPAGE))
  495. m_lfDefFont.lfCharSet = ANSI_CHARSET;
  496. else
  497. m_lfDefFont.lfCharSet = csi.ciCharset;
  498. #endif
  499. } else {
  500. m_lfDefFont.lfItalic = (BYTE)Italic;
  501. m_lfDefFont.lfUnderline = (BYTE)Underline;
  502. m_lfDefFont.lfPitchAndFamily = (BYTE)PitchAndFamily;
  503. #ifdef DBCS
  504. m_lfDefFont.lfCharSet = CharSet;
  505. #endif
  506. cbData = sizeof(szValue);
  507. if ( (RegQueryValueEx( hKeyWincfg, szFontFace, NULL, &dwType,
  508. (LPBYTE)szValue, &cbData ) == ERROR_SUCCESS ) &&
  509. *szValue )
  510. pszFontFace = szValue;
  511. }
  512. lstrcpy( m_lfDefFont.lfFaceName, pszFontFace );
  513. /*
  514. * Get other profile settings.
  515. */
  516. cbData = sizeof(m_nConfirmation);
  517. if ( !hKeyWincfg ||
  518. (RegQueryValueEx( hKeyWincfg, szConfirm, NULL, &dwType,
  519. (LPBYTE)&dwValue, &cbData ) != ERROR_SUCCESS) )
  520. m_nConfirmation = 1;
  521. else
  522. m_nConfirmation = dwValue;
  523. cbData = sizeof(m_nSaveSettingsOnExit);
  524. if ( !hKeyWincfg ||
  525. (RegQueryValueEx( hKeyWincfg, szSaveSettings, NULL, &dwType,
  526. (LPBYTE)&dwValue, &cbData ) != ERROR_SUCCESS) )
  527. m_nSaveSettingsOnExit = 1;
  528. else
  529. m_nSaveSettingsOnExit = dwValue;
  530. cbData = sizeof(m_nHexBase);
  531. if ( !hKeyWincfg ||
  532. (RegQueryValueEx( hKeyWincfg, szHexBase, NULL, &dwType,
  533. (LPBYTE)&dwValue, &cbData ) != ERROR_SUCCESS) )
  534. m_nHexBase = 1;
  535. else
  536. m_nHexBase = dwValue;
  537. if ( hKeyWincfg )
  538. RegCloseKey(hKeyWincfg);
  539. } // end CWincfgApp::GetAppProfileInfo
  540. /*******************************************************************************
  541. *
  542. * Terminate - CWincfgApp member function: public operation
  543. *
  544. * Save state settings to the app's profile and free the Pd and Wd
  545. * list contents.
  546. *
  547. * ENTRY:
  548. * EXIT:
  549. *
  550. ******************************************************************************/
  551. void
  552. CWincfgApp::Terminate()
  553. {
  554. POSITION pos1, pos2, pos3, pos4;
  555. CObject *pObject;
  556. CObList *pTdList, *pPdList;
  557. /*
  558. * Save app profile information.
  559. */
  560. SetAppProfileInfo();
  561. /*
  562. * We need to close all documents here so that when CWinStationListObjects
  563. * are deleted in the document they can find the proper Wd in the WdList
  564. * so that they can call the proper extension DLL to delete it's
  565. * corresponding object.
  566. */
  567. CloseAllDocuments(1);
  568. /*
  569. * Clean up the TdList list.
  570. */
  571. for ( pos1 = m_TdListList.GetHeadPosition(); (pos2 = pos1) != NULL; ) {
  572. m_TdListList.GetNext( pos1 );
  573. pTdList = (CObList *)m_TdListList.GetAt( pos2 );
  574. for ( pos3 = pTdList->GetHeadPosition(); (pos4 = pos3) != NULL; ) {
  575. pTdList->GetNext( pos3 );
  576. pObject = pTdList->GetAt( pos4 );
  577. pTdList->RemoveAt( pos4 );
  578. delete ( pObject );
  579. }
  580. m_TdListList.RemoveAt( pos2 );
  581. delete ( pTdList );
  582. }
  583. /*
  584. * Clean up the PdList list.
  585. */
  586. for ( pos1 = m_PdListList.GetHeadPosition(); (pos2 = pos1) != NULL; ) {
  587. m_PdListList.GetNext( pos1 );
  588. pPdList = (CObList *)m_PdListList.GetAt( pos2 );
  589. for ( pos3 = pPdList->GetHeadPosition(); (pos4 = pos3) != NULL; ) {
  590. pPdList->GetNext( pos3 );
  591. pObject = pPdList->GetAt( pos4 );
  592. pPdList->RemoveAt( pos4 );
  593. delete ( pObject );
  594. }
  595. m_PdListList.RemoveAt( pos2 );
  596. delete ( pPdList );
  597. }
  598. /*
  599. * Clean up the WdList.
  600. */
  601. for ( pos1 = m_WdList.GetHeadPosition(); (pos2 = pos1) != NULL; ) {
  602. m_WdList.GetNext( pos1 );
  603. pObject = m_WdList.GetAt( pos2 );
  604. m_WdList.RemoveAt( pos2 );
  605. if(((PTERMLOBJECT)pObject)->m_hExtensionDLL) {
  606. if(((PTERMLOBJECT)pObject)->m_lpfnExtEnd) (*((PTERMLOBJECT)pObject)->m_lpfnExtEnd)();
  607. ::FreeLibrary(((PTERMLOBJECT)pObject)->m_hExtensionDLL);
  608. }
  609. delete ( pObject );
  610. }
  611. /*
  612. * Clean up security strings (in case security functions were requested).
  613. */
  614. FreeSecurityStrings();
  615. CoUninitialize();
  616. } // end CWincfgApp::Terminate
  617. /*******************************************************************************
  618. *
  619. * SetAppProfileInfo - CWincfgApp member function: private operation
  620. *
  621. * Save the app's profile information to the registry, if requested.
  622. *
  623. * ENTRY:
  624. * EXIT:
  625. *
  626. ******************************************************************************/
  627. void
  628. CWincfgApp::SetAppProfileInfo()
  629. {
  630. HKEY hKeyWincfg;
  631. DWORD dwValue;
  632. TCHAR szValue[128];
  633. /*
  634. * Open the registry key for this application.
  635. */
  636. RegCreateKey(HKEY_CURRENT_USER, szWincfgAppKey, &hKeyWincfg);
  637. /*
  638. * Save settings if requested by user and we're not in batch mode.
  639. */
  640. if ( hKeyWincfg && m_nSaveSettingsOnExit && !g_Batch ) {
  641. /*
  642. * Fetch and set current window placement.
  643. */
  644. if ( m_pMainWnd &&
  645. m_pMainWnd->GetWindowPlacement(&m_Placement) ) {
  646. m_Placement.flags = 0;
  647. if ( m_pMainWnd->IsZoomed() )
  648. m_Placement.flags |= WPF_RESTORETOMAXIMIZED;
  649. wsprintf( szValue, szPlacementFormat,
  650. m_Placement.flags, m_Placement.showCmd,
  651. m_Placement.ptMinPosition.x, m_Placement.ptMinPosition.y,
  652. m_Placement.ptMaxPosition.x, m_Placement.ptMaxPosition.y,
  653. m_Placement.rcNormalPosition.left,
  654. m_Placement.rcNormalPosition.top,
  655. m_Placement.rcNormalPosition.right,
  656. m_Placement.rcNormalPosition.bottom);
  657. RegSetValueEx( hKeyWincfg, szPlacement, 0, REG_SZ,
  658. (LPBYTE)szValue,
  659. (lstrlen(szValue) + 1) * sizeof(TCHAR) );
  660. }
  661. /*
  662. * Set the current font.
  663. */
  664. wsprintf( szValue, szFontFormat,
  665. m_lfDefFont.lfHeight, m_lfDefFont.lfWeight,
  666. m_lfDefFont.lfItalic, m_lfDefFont.lfUnderline,
  667. m_lfDefFont.lfPitchAndFamily, m_lfDefFont.lfCharSet);
  668. RegSetValueEx( hKeyWincfg, szFont, 0, REG_SZ,
  669. (LPBYTE)szValue,
  670. (lstrlen(szValue) + 1) * sizeof(TCHAR) );
  671. lstrcpy(szValue,m_lfDefFont.lfFaceName);
  672. RegSetValueEx( hKeyWincfg, szFontFace, 0, REG_SZ,
  673. (LPBYTE)szValue,
  674. (lstrlen(szValue) + 1) * sizeof(TCHAR) );
  675. /*
  676. * Set other profile settings.
  677. */
  678. dwValue = m_nConfirmation;
  679. RegSetValueEx( hKeyWincfg, szConfirm, 0, REG_DWORD,
  680. (LPBYTE)&dwValue, sizeof(DWORD) );
  681. dwValue = m_nHexBase;
  682. RegSetValueEx( hKeyWincfg, szHexBase, 0, REG_DWORD,
  683. (LPBYTE)&dwValue, sizeof(DWORD) );
  684. }
  685. /*
  686. * Always write the "SaveSettingsOnExit" value to retain user's preference.
  687. */
  688. if ( hKeyWincfg ) {
  689. dwValue = m_nSaveSettingsOnExit;
  690. RegSetValueEx( hKeyWincfg, szSaveSettings, 0, REG_DWORD,
  691. (LPBYTE)&dwValue, sizeof(DWORD) );
  692. RegCloseKey(hKeyWincfg);
  693. }
  694. } // end CWincfgApp::SetAppProfileInfo
  695. ////////////////////////////////////////////////////////////////////////////////
  696. // CWincfgApp message map
  697. #pragma warning( disable : 4245 ) // can remove when we update to MFC 3.0
  698. BEGIN_MESSAGE_MAP(CWincfgApp, CWinApp)
  699. //{{AFX_MSG_MAP(CWincfgApp)
  700. ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
  701. ON_COMMAND(ID_OPTIONS_FONT, OnOptionsFont)
  702. ON_COMMAND(ID_OPTIONS_CONFIRMATION, OnOptionsConfirmation)
  703. ON_UPDATE_COMMAND_UI(ID_OPTIONS_CONFIRMATION, OnUpdateOptionsConfirmation)
  704. ON_COMMAND(ID_OPTIONS_SAVE_SETTINGS_ON_EXIT, OnOptionsSaveSettingsOnExit)
  705. ON_UPDATE_COMMAND_UI(ID_OPTIONS_SAVE_SETTINGS_ON_EXIT, OnUpdateOptionsSaveSettingsOnExit)
  706. ON_COMMAND(ID_HELP_SEARCH_FOR, OnHelpSearchFor)
  707. ON_COMMAND(ID_HELP, OnHelp)
  708. //}}AFX_MSG_MAP
  709. // Global help commands
  710. ON_COMMAND(ID_HELP_INDEX, CWinApp::OnHelpIndex)
  711. ON_COMMAND(ID_HELP_USING, CWinApp::OnHelpUsing)
  712. ON_COMMAND(ID_CONTEXT_HELP, CWinApp::OnContextHelp)
  713. ON_COMMAND(ID_DEFAULT_HELP, CWinApp::OnHelpIndex)
  714. END_MESSAGE_MAP()
  715. #pragma warning( default : 4245 ) // can remove when we update to MFC 3.0
  716. ////////////////////////////////////////////////////////////////////////////////
  717. // CWincfgApp commands
  718. /*******************************************************************************
  719. *
  720. * OnAppAbout - CWincfgApp member function: command
  721. *
  722. * Display the about box dialog (uses Shell32 generic About dialog).
  723. *
  724. * ENTRY:
  725. * EXIT:
  726. *
  727. ******************************************************************************/
  728. // Typedef for the ShellAbout function
  729. typedef void (WINAPI *LPFNSHELLABOUT)(HWND, LPCTSTR, LPCTSTR, HICON);
  730. void
  731. CWincfgApp::OnAppAbout()
  732. {
  733. HMODULE hMod;
  734. LPFNSHELLABOUT lpfn;
  735. if (hMod = ::LoadLibrary(TEXT("SHELL32")))
  736. {
  737. if (lpfn = (LPFNSHELLABOUT)::GetProcAddress( hMod,
  738. #ifdef UNICODE
  739. "ShellAboutW"
  740. #else
  741. "ShellAboutA"
  742. #endif // UNICODE
  743. ))
  744. {
  745. (*lpfn)( m_pMainWnd->m_hWnd, (LPCTSTR)m_pszAppName,
  746. (LPCTSTR)(TEXT("")), LoadIcon(IDR_MAINFRAME) );
  747. }
  748. ::FreeLibrary(hMod);
  749. }
  750. else
  751. {
  752. ::MessageBeep( MB_ICONEXCLAMATION );
  753. }
  754. } // end CWincfgApp::OnAppAbout
  755. /*******************************************************************************
  756. *
  757. * OnOptionsFont - CWincfgApp member function: command
  758. *
  759. * Prompt for a new font to use in views and set if given.
  760. *
  761. * ENTRY:
  762. *
  763. * EXIT:
  764. *
  765. ******************************************************************************/
  766. void
  767. CWincfgApp::OnOptionsFont()
  768. {
  769. CFontDialog dlg( &m_lfDefFont, CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT );
  770. /*
  771. * We don't want the Help button since none of the other NT utilities
  772. * in our 'family' offer this. Also, we need to block the F1 'help' and
  773. * unblock when done.
  774. */
  775. dlg.m_cf.Flags &= ~CF_SHOWHELP;
  776. m_bAllowHelp = FALSE;
  777. if ( dlg.DoModal() == IDOK ) {
  778. /*
  779. * switch to newly selected font.
  780. */
  781. m_font.DeleteObject();
  782. if ( m_font.CreateFontIndirect( &m_lfDefFont ) ) {
  783. CAppServerView *pView;
  784. /*
  785. * Update the view.
  786. *
  787. * NOTE: Call the MDIGetActive function in a loop for MDI
  788. * application to get each MDI Child window, then get the view
  789. * associated with each child window and call its ResetView
  790. * member function with TRUE argument to cause new field maximums
  791. * to be calculated.
  792. */
  793. if ( (pView = (CAppServerView *)
  794. ((CMainFrame *)(m_pMainWnd))->GetActiveView()) )
  795. pView->ResetView( TRUE );
  796. }
  797. }
  798. m_bAllowHelp = TRUE;
  799. } // end CWincfgApp::OnOptionsFont
  800. /*******************************************************************************
  801. *
  802. * OnOptionsConfirmation- CWincfgApp member function: command
  803. *
  804. * Toggle the "confirmation" flag.
  805. *
  806. * ENTRY:
  807. *
  808. * EXIT:
  809. *
  810. ******************************************************************************/
  811. void
  812. CWincfgApp::OnOptionsConfirmation()
  813. {
  814. m_nConfirmation ^= 1;
  815. } // end CWincfgApp::OnOptionsConfirmation
  816. /*******************************************************************************
  817. *
  818. * OnUpdateOptionsConfirmation - CWincfgApp member function: command
  819. *
  820. * Check or uncheck the "confirmation" menu item based on the state
  821. * of the m_nConfirmation flag.
  822. *
  823. * ENTRY:
  824. *
  825. * pCndUI (input)
  826. * Points to the CCmdUI object of the "confirmation" menu item.
  827. *
  828. * EXIT:
  829. *
  830. ******************************************************************************/
  831. void
  832. CWincfgApp::OnUpdateOptionsConfirmation( CCmdUI* pCmdUI )
  833. {
  834. pCmdUI->SetCheck( m_nConfirmation );
  835. } // end CWincfgApp::OnUpdateOptionsConfirmation
  836. /*******************************************************************************
  837. *
  838. * OnOptionsSaveSettingsOnExit - CWincfgApp member function: command
  839. *
  840. * Toggle the "save settings on exit" flag.
  841. *
  842. * ENTRY:
  843. *
  844. * EXIT:
  845. *
  846. ******************************************************************************/
  847. void
  848. CWincfgApp::OnOptionsSaveSettingsOnExit()
  849. {
  850. m_nSaveSettingsOnExit ^= 1;
  851. } // end CWincfgApp::OnOptionsSaveSettingsOnExit
  852. /*******************************************************************************
  853. *
  854. * OnUpdateOptionsSaveSettingsOnExit - CWincfgApp member function: command
  855. *
  856. * Check or uncheck the "save settings on exit" menu item based on the
  857. * state of the m_nSaveSettingsOnExit flag.
  858. *
  859. * ENTRY:
  860. *
  861. * pCndUI (input)
  862. * Points to the CCmdUI object of the "save settings on exit"
  863. * menu item.
  864. *
  865. * EXIT:
  866. *
  867. ******************************************************************************/
  868. void
  869. CWincfgApp::OnUpdateOptionsSaveSettingsOnExit( CCmdUI* pCmdUI )
  870. {
  871. pCmdUI->SetCheck( m_nSaveSettingsOnExit );
  872. } // end CWincfgApp::OnUpdateOptionsSaveSettingsOnExit
  873. /*******************************************************************************
  874. *
  875. * OnHelp - CWincfgApp member function: command
  876. *
  877. * Invoke standard CWinApp::WinHelp if we're allowing help at this time.
  878. *
  879. * ENTRY:
  880. * EXIT:
  881. *
  882. ******************************************************************************/
  883. void
  884. CWincfgApp::OnHelp()
  885. {
  886. /*
  887. * If we're allowing help now, call default help helper.
  888. */
  889. if ( m_bAllowHelp )
  890. CWinApp::OnHelp();
  891. } // end CWincfgApp::OnHelp
  892. /*******************************************************************************
  893. *
  894. * OnHelpSearchFor - CWincfgApp member function: command
  895. *
  896. * Invoke WinHelp on our app's help file to bring up the 'search' window.
  897. *
  898. * ENTRY:
  899. * EXIT:
  900. *
  901. ******************************************************************************/
  902. void
  903. CWincfgApp::OnHelpSearchFor()
  904. {
  905. WinHelp((DWORD)((LPCTSTR)TEXT("")), HELP_PARTIALKEY);
  906. } // end CWincfgApp::OnHelpSearchFor
  907. /*******************************************************************************
  908. *
  909. * AreWeRunningTerminalServices
  910. *
  911. * Check if we are running terminal server
  912. *
  913. * ENTRY:
  914. *
  915. * EXIT: BOOL: True if we are running Terminal Services False if we
  916. * are not running Terminal Services
  917. *
  918. *
  919. ******************************************************************************/
  920. BOOL AreWeRunningTerminalServices(void)
  921. {
  922. OSVERSIONINFOEX osVersionInfo;
  923. DWORDLONG dwlConditionMask = 0;
  924. ZeroMemory(&osVersionInfo, sizeof(OSVERSIONINFOEX));
  925. osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  926. osVersionInfo.wSuiteMask = VER_SUITE_TERMINAL;
  927. VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_AND );
  928. return VerifyVersionInfo(
  929. &osVersionInfo,
  930. VER_SUITENAME,
  931. dwlConditionMask
  932. );
  933. }
  934. ////////////////////////////////////////////////////////////////////////////////