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.

609 lines
22 KiB

  1. /*******************************************************************************
  2. *
  3. * winadmin.cpp
  4. *
  5. * Defines the class behaviors for the application.
  6. *
  7. * copyright notice: Copyright 1997, Citrix Systems Inc.
  8. * Copyright (c) 1998 - 1999 Microsoft Corporation
  9. *
  10. * $Author: donm $ Don Messerli
  11. *
  12. * $Log: N:\nt\private\utils\citrix\winutils\tsadmin\VCS\winadmin.cpp $
  13. *
  14. * Rev 1.6 19 Feb 1998 17:42:44 donm
  15. * removed latest extension DLL support
  16. *
  17. * Rev 1.4 05 Nov 1997 14:31:02 donm
  18. * update
  19. *
  20. * Rev 1.3 13 Oct 1997 22:19:42 donm
  21. * update
  22. *
  23. * Rev 1.0 30 Jul 1997 17:13:08 butchd
  24. * Initial revision.
  25. *
  26. *******************************************************************************/
  27. #include "stdafx.h"
  28. #include "winadmin.h"
  29. #include <regapi.h>
  30. #include "mainfrm.h"
  31. #include "admindoc.h"
  32. #include "treeview.h"
  33. #include "rtpane.h"
  34. #include "blankvw.h"
  35. #include "winsvw.h"
  36. #include "servervw.h"
  37. #include <winsvc.h>
  38. #ifdef DBG
  39. bool g_fDebug = false;
  40. #endif
  41. #ifdef _DEBUG
  42. #define new DEBUG_NEW
  43. #undef THIS_FILE
  44. static char THIS_FILE[] = __FILE__;
  45. #endif
  46. //BOOL AreWeRunningTerminalServices(void);
  47. /////////////////////////////////////////////////////////////////////////////
  48. // CWinAdminApp
  49. BEGIN_MESSAGE_MAP(CWinAdminApp, CWinApp)
  50. //{{AFX_MSG_MAP(CWinAdminApp)
  51. ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
  52. // NOTE - the ClassWizard will add and remove mapping macros here.
  53. // DO NOT EDIT what you see in these blocks of generated code!
  54. //}}AFX_MSG_MAP
  55. END_MESSAGE_MAP()
  56. /////////////////////////////////////////////////////////////////////////////
  57. // CWinAdminApp construction
  58. CWinAdminApp::CWinAdminApp()
  59. {
  60. // TODO: add construction code here,
  61. // Place all significant initialization in InitInstance
  62. }
  63. /////////////////////////////////////////////////////////////////////////////
  64. // The one and only CWinAdminApp object
  65. CWinAdminApp theApp;
  66. static TCHAR szExtensionDLLName[] = TEXT("ADMINEX.DLL");
  67. static TCHAR szICABrowserServiceName[] = TEXT("ICABrowser");
  68. static CHAR szStart[] = "WAExStart";
  69. static CHAR szEnd[] = "WAExEnd";
  70. static CHAR szServerEnumerate[] = "WAExServerEnumerate";
  71. static CHAR szWinStationInit[] = "WAExWinStationInit";
  72. static CHAR szWinStationInfo[] = "WAExWinStationInfo";
  73. static CHAR szWinStationCleanup[] = "WAExWinStationCleanup";
  74. static CHAR szServerInit[] = "WAExServerInit";
  75. static CHAR szServerCleanup[] = "WAExServerCleanup";
  76. static CHAR szGetServerInfo[] = "WAExGetServerInfo";
  77. static CHAR szServerEvent[] = "WAExServerEvent";
  78. static CHAR szGetGlobalInfo[] = "WAExGetGlobalInfo";
  79. static CHAR szGetServerLicenses[] = "WAExGetServerLicenses";
  80. static CHAR szGetWinStationInfo[] = "WAExGetWinStationInfo";
  81. static CHAR szGetWinStationModules[] = "WAExGetWinStationModules";
  82. static CHAR szFreeServerLicenses[] = "WAExFreeServerLicenses";
  83. static CHAR szFreeWinStationModules[] = "WAExFreeWinStationModules";
  84. /////////////////////////////////////////////////////////////////////////////
  85. // CWinAdminApp initialization
  86. //
  87. BOOL CWinAdminApp::InitInstance()
  88. {
  89. #ifdef DBG
  90. // to avoid excessive debug spewage delete this key on checked builds
  91. HKEY hKey;
  92. LONG lStatus;
  93. DWORD dwDebugValue;
  94. DWORD dwSize = sizeof( DWORD );
  95. lStatus = RegOpenKeyEx( HKEY_CURRENT_USER,
  96. L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Terminal Server\\TSADMIN",
  97. 0 ,
  98. KEY_READ,
  99. &hKey );
  100. if( lStatus == ERROR_SUCCESS )
  101. {
  102. lStatus = RegQueryValueEx( hKey ,
  103. L"Debug",
  104. NULL,
  105. NULL,
  106. ( LPBYTE )&dwDebugValue,
  107. &dwSize );
  108. if( lStatus == ERROR_SUCCESS )
  109. {
  110. if( dwDebugValue != 0 )
  111. {
  112. g_fDebug = true;
  113. }
  114. }
  115. RegCloseKey( hKey );
  116. }
  117. #endif
  118. // Read the preferences from the registry
  119. ReadPreferences();
  120. // Check to see if this user is an Admin
  121. m_Admin = TestUserForAdmin(FALSE);
  122. // Set pointers to extension DLL's procedures to NULL
  123. m_lpfnWAExStart = NULL;
  124. m_lpfnWAExEnd = NULL;
  125. m_lpfnWAExServerEnumerate = NULL;
  126. m_lpfnWAExWinStationInit = NULL;
  127. m_lpfnWAExWinStationCleanup = NULL;
  128. m_lpfnWAExServerInit = NULL;
  129. m_lpfnWAExServerCleanup = NULL;
  130. m_lpfnWAExGetServerInfo = NULL;
  131. m_lpfnWAExGetGlobalInfo = NULL;
  132. m_lpfnWAExGetServerLicenses = NULL;
  133. m_lpfnWAExGetWinStationInfo = NULL;
  134. m_lpfnWAExGetWinStationModules = NULL;
  135. m_lpfnWAExFreeServerLicenses = NULL;
  136. m_lpfnWAExFreeWinStationModules = NULL;
  137. // Check to see if we are running under Picasso
  138. m_Picasso = FALSE;
  139. if(IsBrowserRunning()) {
  140. // Attempt to load our extension DLL
  141. m_hExtensionDLL = LoadLibrary(szExtensionDLLName);
  142. if(m_hExtensionDLL) {
  143. // Get all the addresses of the procedures
  144. m_lpfnWAExStart = (LPFNEXSTARTUPPROC)::GetProcAddress(m_hExtensionDLL, szStart);
  145. m_lpfnWAExEnd = (LPFNEXSHUTDOWNPROC)::GetProcAddress(m_hExtensionDLL, szEnd);
  146. m_lpfnWAExServerEnumerate = (LPFNEXENUMERATEPROC)::GetProcAddress(m_hExtensionDLL, szServerEnumerate);
  147. m_lpfnWAExWinStationInit = (LPFNEXWINSTATIONINITPROC)::GetProcAddress(m_hExtensionDLL, szWinStationInit);
  148. m_lpfnWAExWinStationInfo = (LPFNEXWINSTATIONINFOPROC)::GetProcAddress(m_hExtensionDLL, szWinStationInfo);
  149. m_lpfnWAExWinStationCleanup = (LPFNEXWINSTATIONCLEANUPPROC)::GetProcAddress(m_hExtensionDLL, szWinStationCleanup);
  150. m_lpfnWAExServerInit = (LPFNEXSERVERINITPROC)::GetProcAddress(m_hExtensionDLL, szServerInit);
  151. m_lpfnWAExServerCleanup = (LPFNEXSERVERCLEANUPPROC)::GetProcAddress(m_hExtensionDLL, szServerCleanup);
  152. m_lpfnWAExGetServerInfo = (LPFNEXGETSERVERINFOPROC)::GetProcAddress(m_hExtensionDLL, szGetServerInfo);
  153. m_lpfnWAExServerEvent = (LPFNEXSERVEREVENTPROC)::GetProcAddress(m_hExtensionDLL, szServerEvent);
  154. m_lpfnWAExGetGlobalInfo = (LPFNEXGETGLOBALINFOPROC)::GetProcAddress(m_hExtensionDLL, szGetGlobalInfo);
  155. m_lpfnWAExGetServerLicenses = (LPFNEXGETSERVERLICENSESPROC)::GetProcAddress(m_hExtensionDLL, szGetServerLicenses);
  156. m_lpfnWAExGetWinStationInfo = (LPFNEXGETWINSTATIONINFOPROC)::GetProcAddress(m_hExtensionDLL, szGetWinStationInfo);
  157. m_lpfnWAExGetWinStationModules = (LPFNEXGETWINSTATIONMODULESPROC)::GetProcAddress(m_hExtensionDLL, szGetWinStationModules);
  158. m_lpfnWAExFreeServerLicenses = (LPFNEXFREESERVERLICENSESPROC)::GetProcAddress(m_hExtensionDLL, szFreeServerLicenses);
  159. m_lpfnWAExFreeWinStationModules = (LPFNEXFREEWINSTATIONMODULESPROC)::GetProcAddress(m_hExtensionDLL, szFreeWinStationModules);
  160. m_Picasso = TRUE;
  161. } else {
  162. // Picasso is running, but we couldn't load the extension DLL.
  163. // Tell the user that added functionality will not be available
  164. CString MessageString;
  165. CString TitleString;
  166. TitleString.LoadString(AFX_IDS_APP_TITLE);
  167. MessageString.LoadString(IDS_NO_EXTENSION_DLL);
  168. ::MessageBox(NULL, MessageString, TitleString, MB_ICONEXCLAMATION | MB_OK);
  169. }
  170. }
  171. // Get information about the WinStation we are running from
  172. QueryCurrentWinStation(m_CurrentWinStationName, m_CurrentUserName,
  173. &m_CurrentLogonId, &m_CurrentWSFlags);
  174. // Load the system console string for rapid comparison in various
  175. // refresh cycles.
  176. lstrcpy( m_szSystemConsole , L"Console" );
  177. /*
  178. LoadString( m_hInstance, IDS_SYSTEM_CONSOLE_NAME,
  179. m_szSystemConsole, WINSTATIONNAME_LENGTH );
  180. */
  181. // Standard initialization
  182. // If you are not using these features and wish to reduce the size
  183. // of your final executable, you should remove from the following
  184. // the specific initialization routines you do not need.
  185. #ifdef _AFXDLL
  186. Enable3dControls(); // Call this when using MFC in a shared DLL
  187. #else
  188. Enable3dControlsStatic(); // Call this when linking to MFC statically
  189. #endif
  190. // LoadStdProfileSettings(); // Load standard INI file options (including MRU)
  191. // Get the current server name
  192. DWORD cchBuffer = MAX_COMPUTERNAME_LENGTH + 1;
  193. if(!GetComputerName(m_CurrentServerName, &cchBuffer)) {
  194. DWORD Error = GetLastError();
  195. }
  196. // Register the application's document templates. Document templates
  197. // serve as the connection between documents, frame windows and views.
  198. CSingleDocTemplate* pDocTemplate;
  199. pDocTemplate = new CSingleDocTemplate(
  200. IDR_MAINFRAME,
  201. RUNTIME_CLASS(CWinAdminDoc),
  202. RUNTIME_CLASS(CMainFrame), // main SDI frame window
  203. m_Picasso ? RUNTIME_CLASS(CBaseTreeView) : RUNTIME_CLASS(CAdminTreeView));
  204. AddDocTemplate(pDocTemplate);
  205. // Parse command line for standard shell commands, DDE, file open
  206. CCommandLineInfo cmdInfo;
  207. ParseCommandLine(cmdInfo);
  208. // Dispatch commands specified on the command line
  209. if (!ProcessShellCommand(cmdInfo))
  210. return FALSE;
  211. return TRUE;
  212. }
  213. /////////////////////////////////////////////////////////////////////////////
  214. // CWinAdminApp::ExitInstance
  215. //
  216. int CWinAdminApp::ExitInstance()
  217. {
  218. // write out the preferences
  219. WritePreferences();
  220. // if we loaded the extension DLL, unload it
  221. if(m_hExtensionDLL) FreeLibrary(m_hExtensionDLL);
  222. return 0;
  223. }
  224. static TCHAR szWinAdminAppKey[] = REG_SOFTWARE_TSERVER TEXT("\\TSADMIN");
  225. static TCHAR szPlacement[] = TEXT("Placement");
  226. static TCHAR szPlacementFormat[] = TEXT("%u,%u,%d,%d,%d,%d,%d,%d,%d,%d");
  227. static TCHAR szConfirmation[] = TEXT("Confirmation");
  228. static TCHAR szSaveSettings[] = TEXT("SaveSettingsOnExit");
  229. static TCHAR szShowSystemProcesses[] = TEXT("ShowSystemProcesses");
  230. static TCHAR szShowAllServers[] = TEXT("ShowAllServers");
  231. static TCHAR szListRefreshTime[] = TEXT("ListRefreshTime");
  232. static TCHAR szStatusRefreshTime[] = TEXT("StatusRefreshTime");
  233. static TCHAR szShadowHotkeyKey[] = TEXT("ShadowHotkeyKey");
  234. static TCHAR szShadowHotkeyShift[] = TEXT("ShadowHotkeyShift");
  235. static TCHAR szTreeWidth[] = TEXT("TreeWidth");
  236. /////////////////////////////////////////////////////////////////////////////
  237. // CWinAdminApp::ReadPreferences
  238. //
  239. void CWinAdminApp::ReadPreferences()
  240. {
  241. HKEY hKeyWinAdmin;
  242. DWORD dwType, cbData, dwValue;
  243. TCHAR szValue[128];
  244. // Set default values for everything
  245. m_Confirmation = 1;
  246. m_SavePreferences = 1;
  247. m_ProcessListRefreshTime = 5000;
  248. m_StatusRefreshTime = 1000;
  249. m_ShowSystemProcesses = TRUE;
  250. m_ShowAllServers = FALSE;
  251. m_ShadowHotkeyKey = VK_MULTIPLY;
  252. m_ShadowHotkeyShift = KBDCTRL;
  253. m_TreeWidth = 200;
  254. m_Placement.rcNormalPosition.right = -1;
  255. // Open registry key for our application
  256. DWORD Disposition;
  257. if(RegCreateKeyEx(HKEY_CURRENT_USER, szWinAdminAppKey, 0, TEXT(""), REG_OPTION_NON_VOLATILE,
  258. KEY_READ, NULL, &hKeyWinAdmin, &Disposition) != ERROR_SUCCESS) return;
  259. // Read the previous WINDOWPLACEMENT.
  260. cbData = sizeof(szValue);
  261. if((RegQueryValueEx(hKeyWinAdmin, szPlacement, NULL, &dwType,
  262. (LPBYTE)szValue, &cbData) != ERROR_SUCCESS) ||
  263. !(*szValue) ||
  264. (swscanf( szValue, szPlacementFormat,
  265. &m_Placement.flags, &m_Placement.showCmd,
  266. &m_Placement.ptMinPosition.x, &m_Placement.ptMinPosition.y,
  267. &m_Placement.ptMaxPosition.x, &m_Placement.ptMaxPosition.y,
  268. &m_Placement.rcNormalPosition.left,
  269. &m_Placement.rcNormalPosition.top,
  270. &m_Placement.rcNormalPosition.right,
  271. &m_Placement.rcNormalPosition.bottom ) != 10) ) {
  272. // Flag to use the default window placement.
  273. m_Placement.rcNormalPosition.right = -1;
  274. }
  275. /*
  276. * Flag for initial showing of main window in our override of
  277. * CFrameWnd::ActivateFrame() (in our CMainFrame class).
  278. */
  279. m_Placement.length = (UINT)-1;
  280. // Read the Confirmation flag
  281. cbData = sizeof(m_Confirmation);
  282. if(RegQueryValueEx(hKeyWinAdmin, szConfirmation, NULL, &dwType, (LPBYTE)&dwValue,
  283. &cbData) == ERROR_SUCCESS) {
  284. m_Confirmation = dwValue;
  285. }
  286. // Read the Save Preferences flag
  287. cbData = sizeof(m_SavePreferences);
  288. if(RegQueryValueEx(hKeyWinAdmin, szSaveSettings, NULL, &dwType, (LPBYTE)&dwValue,
  289. &cbData) == ERROR_SUCCESS) {
  290. m_SavePreferences = dwValue;
  291. }
  292. // Read the Show System Processes flag
  293. cbData = sizeof(m_ShowSystemProcesses);
  294. if(RegQueryValueEx(hKeyWinAdmin, szShowSystemProcesses, NULL, &dwType, (LPBYTE)&dwValue,
  295. &cbData) == ERROR_SUCCESS) {
  296. m_ShowSystemProcesses = dwValue;
  297. }
  298. #if 0
  299. // Read the Show All Servers flag
  300. cbData = sizeof(m_ShowAllServers);
  301. if(RegQueryValueEx(hKeyWinAdmin, szShowAllServers, NULL, &dwType, (LPBYTE)&dwValue,
  302. &cbData) == ERROR_SUCCESS) {
  303. m_ShowAllServers = dwValue;
  304. }
  305. #endif
  306. // Read the Process List Refresh Time
  307. cbData = sizeof(m_ProcessListRefreshTime);
  308. if(RegQueryValueEx(hKeyWinAdmin, szListRefreshTime, NULL, &dwType, (LPBYTE)&dwValue,
  309. &cbData) == ERROR_SUCCESS) {
  310. m_ProcessListRefreshTime = dwValue;
  311. }
  312. // Read the Status Dialog Refresh Time
  313. cbData = sizeof(m_StatusRefreshTime);
  314. if(RegQueryValueEx(hKeyWinAdmin, szStatusRefreshTime, NULL, &dwType, (LPBYTE)&dwValue,
  315. &cbData) == ERROR_SUCCESS) {
  316. m_StatusRefreshTime = dwValue;
  317. }
  318. // Read the Shadow Hotkey Key
  319. cbData = sizeof(m_ShadowHotkeyKey);
  320. if(RegQueryValueEx(hKeyWinAdmin, szShadowHotkeyKey, NULL, &dwType, (LPBYTE)&dwValue,
  321. &cbData) == ERROR_SUCCESS) {
  322. m_ShadowHotkeyKey = dwValue;
  323. }
  324. // Read the Shadow Hotkey Shift
  325. cbData = sizeof(m_ShadowHotkeyShift);
  326. if(RegQueryValueEx(hKeyWinAdmin, szShadowHotkeyShift, NULL, &dwType, (LPBYTE)&dwValue,
  327. &cbData) == ERROR_SUCCESS) {
  328. m_ShadowHotkeyShift = dwValue;
  329. }
  330. // CPR 1698: (Upgrade check for SouthBeach build 129 WINADMIN saved
  331. // profile). If the m_nShadowHotkeyKey is VK_ESCAPE (no longer allowed),
  332. // set the hotkey to CTRL-* (the new default).
  333. if(m_ShadowHotkeyKey == VK_ESCAPE) {
  334. m_ShadowHotkeyKey = VK_MULTIPLY;
  335. m_ShadowHotkeyShift = KBDCTRL;
  336. }
  337. // Read the Tree Width
  338. cbData = sizeof(m_TreeWidth);
  339. if(RegQueryValueEx(hKeyWinAdmin, szTreeWidth, NULL, &dwType, (LPBYTE)&dwValue,
  340. &cbData) == ERROR_SUCCESS) {
  341. m_TreeWidth = dwValue;
  342. }
  343. RegCloseKey(hKeyWinAdmin);
  344. } // end CWinAdminApp::ReadPreferences
  345. /////////////////////////////////////////////////////////////////////////////
  346. // CWinAdminApp::WritePreferences
  347. //
  348. void CWinAdminApp::WritePreferences()
  349. {
  350. HKEY hKeyWinAdmin;
  351. DWORD dwValue;
  352. TCHAR szValue[128];
  353. // Open registry key for our application
  354. DWORD Disposition;
  355. if(RegCreateKeyEx(HKEY_CURRENT_USER, szWinAdminAppKey, 0, TEXT(""), REG_OPTION_NON_VOLATILE,
  356. KEY_WRITE, NULL, &hKeyWinAdmin, &Disposition) != ERROR_SUCCESS) return;
  357. // Always write the Save Settings on Exit entry
  358. dwValue = m_SavePreferences;
  359. RegSetValueEx(hKeyWinAdmin, szSaveSettings, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
  360. // If the user didn't want to save settings, we're done
  361. if(!m_SavePreferences) {
  362. RegCloseKey(hKeyWinAdmin);
  363. return;
  364. }
  365. // Write the WINDOWPLACEMENT
  366. m_Placement.flags = 0;
  367. // if(m_pMainWnd->IsZoomed())
  368. // m_Placement.flags |= WPF_RESTORETOMAXIMIZED;
  369. wsprintf(szValue, szPlacementFormat, m_Placement.flags, m_Placement.showCmd,
  370. m_Placement.ptMinPosition.x, m_Placement.ptMinPosition.y,
  371. m_Placement.ptMaxPosition.x, m_Placement.ptMaxPosition.y,
  372. m_Placement.rcNormalPosition.left,
  373. m_Placement.rcNormalPosition.top,
  374. m_Placement.rcNormalPosition.right,
  375. m_Placement.rcNormalPosition.bottom);
  376. RegSetValueEx(hKeyWinAdmin, szPlacement, 0, REG_SZ,
  377. (LPBYTE)szValue, (lstrlen(szValue) + 1) * sizeof(TCHAR));
  378. // Write the Confirmation flag
  379. dwValue = m_Confirmation;
  380. RegSetValueEx(hKeyWinAdmin, szConfirmation, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
  381. // Write the Show System Processes flag
  382. dwValue = m_ShowSystemProcesses;
  383. RegSetValueEx(hKeyWinAdmin, szShowSystemProcesses, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
  384. // Write the Show All Servers flag
  385. dwValue = m_ShowAllServers;
  386. RegSetValueEx(hKeyWinAdmin, szShowAllServers, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
  387. // Write the Process List Refresh Time
  388. dwValue = m_ProcessListRefreshTime;
  389. RegSetValueEx(hKeyWinAdmin, szListRefreshTime, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
  390. // Write the Status Dialog Refresh Time
  391. dwValue = m_StatusRefreshTime;
  392. RegSetValueEx(hKeyWinAdmin, szStatusRefreshTime, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
  393. // Write the Shadow Hotkey Key
  394. dwValue = m_ShadowHotkeyKey;
  395. RegSetValueEx(hKeyWinAdmin, szShadowHotkeyKey, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
  396. // Write the Shadow Hotkey Shift state
  397. dwValue = m_ShadowHotkeyShift;
  398. RegSetValueEx(hKeyWinAdmin, szShadowHotkeyShift, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
  399. // Write the Tree Width
  400. dwValue = m_TreeWidth;
  401. RegSetValueEx(hKeyWinAdmin, szTreeWidth, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
  402. // Close the registry key
  403. RegCloseKey(hKeyWinAdmin);
  404. } // end CWinAdminApp::WritePreferences
  405. /////////////////////////////////////////////////////////////////////////////
  406. // CWinAdminApp::IsBrowserRunning
  407. //
  408. BOOL CWinAdminApp::IsBrowserRunning()
  409. {
  410. SC_HANDLE managerHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  411. SC_HANDLE serviceHandle = OpenService(managerHandle, szICABrowserServiceName, SERVICE_QUERY_STATUS);
  412. SERVICE_STATUS serviceStatus;
  413. QueryServiceStatus(serviceHandle, (LPSERVICE_STATUS)&serviceStatus);
  414. CloseServiceHandle(serviceHandle);
  415. CloseServiceHandle(managerHandle);
  416. if(serviceStatus.dwCurrentState != SERVICE_RUNNING) return FALSE;
  417. else return TRUE;
  418. } // end CWinAdminApp::IsBrowserRunning
  419. /*******************************************************************************
  420. *
  421. * OnAppAbout - CWinAdminApp member function: command
  422. *
  423. * Display the about box dialog (uses Shell32 generic About dialog).
  424. *
  425. * ENTRY:
  426. * EXIT:
  427. *
  428. ******************************************************************************/
  429. // Typedef for the ShellAbout function
  430. typedef void (WINAPI *LPFNSHELLABOUT)(HWND, LPCTSTR, LPCTSTR, HICON);
  431. void CWinAdminApp::OnAppAbout()
  432. {
  433. HMODULE hMod;
  434. LPFNSHELLABOUT lpfn;
  435. if ( hMod = ::LoadLibrary( TEXT("SHELL32") ) )
  436. {
  437. if (lpfn = (LPFNSHELLABOUT)::GetProcAddress( hMod,
  438. #ifdef UNICODE
  439. "ShellAboutW"
  440. #else
  441. "ShellAboutA"
  442. #endif // UNICODE
  443. ))
  444. {
  445. (*lpfn)( m_pMainWnd->m_hWnd, (LPCTSTR)m_pszAppName,
  446. (LPCTSTR)TEXT(""), LoadIcon(IDR_MAINFRAME) );
  447. }
  448. ::FreeLibrary(hMod);
  449. }
  450. else
  451. {
  452. ::MessageBeep( MB_ICONEXCLAMATION );
  453. }
  454. } // end CWinadminApp::OnAppAbout
  455. /*******************************************************************************
  456. *
  457. * AreWeRunningTerminalServices
  458. *
  459. * Check if we are running terminal server
  460. *
  461. * ENTRY:
  462. *
  463. * EXIT: BOOL: True if we are running Terminal Services False if we
  464. * are not running Terminal Services
  465. *
  466. *
  467. ******************************************************************************/
  468. /*
  469. BOOL AreWeRunningTerminalServices(void)
  470. {
  471. OSVERSIONINFOEX osVersionInfo;
  472. DWORDLONG dwlConditionMask = 0;
  473. ZeroMemory(&osVersionInfo, sizeof(OSVERSIONINFOEX));
  474. osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  475. osVersionInfo.wSuiteMask = VER_SUITE_TERMINAL | VER_SUITE_SINGLEUSERTS;
  476. VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_OR );
  477. return VerifyVersionInfo(
  478. &osVersionInfo,
  479. VER_SUITENAME,
  480. dwlConditionMask
  481. );
  482. }
  483. */
  484. /////////////////////////////////////////////////////////////////////////////
  485. // CWinAdminApp commands
  486. //=---------------------------------------------------------
  487. BEGIN_MESSAGE_MAP( CMyTabCtrl , CTabCtrl )
  488. ON_WM_SETFOCUS( )
  489. END_MESSAGE_MAP( )
  490. void CMyTabCtrl::OnSetFocus( CWnd *pOldWnd )
  491. {
  492. ODS( L"CMyTabCtrl::OnSetFocus\n" );
  493. CWinAdminDoc *pDoc = (CWinAdminDoc*)((CWinAdminApp*)AfxGetApp())->GetDocument();
  494. if( pDoc != NULL )
  495. {
  496. ODS( L"\tTabctrl has focus\n" );
  497. pDoc->RegisterLastFocus( TAB_CTRL );
  498. }
  499. CTabCtrl::OnSetFocus( pOldWnd );
  500. }