Leaked source code of windows server 2003
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.

620 lines
23 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. // Command lines switches are not used therefore we are commenting the
  206. // following code out to resolve BUG 536006
  207. // Parse command line for standard shell commands, DDE, file open
  208. //CCommandLineInfo cmdInfo;
  209. //ParseCommandLine(cmdInfo);
  210. // Dispatch commands specified on the command line
  211. //if (!ProcessShellCommand(cmdInfo))
  212. // return FALSE;
  213. // Since ProcessShellCommand is not being used, we still need to start our app
  214. // the following code is taken from ProcessShellCommand MFC code
  215. if (!AfxGetApp()->OnCmdMsg(ID_FILE_NEW, 0, NULL, NULL))
  216. OnFileNew();
  217. if (m_pMainWnd == NULL)
  218. return FALSE;
  219. return TRUE;
  220. }
  221. /////////////////////////////////////////////////////////////////////////////
  222. // CWinAdminApp::ExitInstance
  223. //
  224. int CWinAdminApp::ExitInstance()
  225. {
  226. // write out the preferences
  227. WritePreferences();
  228. // if we loaded the extension DLL, unload it
  229. if(m_hExtensionDLL) FreeLibrary(m_hExtensionDLL);
  230. return 0;
  231. }
  232. static TCHAR szWinAdminAppKey[] = REG_SOFTWARE_TSERVER TEXT("\\TSADMIN");
  233. static TCHAR szPlacement[] = TEXT("Placement");
  234. static TCHAR szPlacementFormat[] = TEXT("%u,%u,%d,%d,%d,%d,%d,%d,%d,%d");
  235. static TCHAR szConfirmation[] = TEXT("Confirmation");
  236. static TCHAR szSaveSettings[] = TEXT("SaveSettingsOnExit");
  237. static TCHAR szShowSystemProcesses[] = TEXT("ShowSystemProcesses");
  238. static TCHAR szShowAllServers[] = TEXT("ShowAllServers");
  239. static TCHAR szListRefreshTime[] = TEXT("ListRefreshTime");
  240. static TCHAR szStatusRefreshTime[] = TEXT("StatusRefreshTime");
  241. static TCHAR szShadowHotkeyKey[] = TEXT("ShadowHotkeyKey");
  242. static TCHAR szShadowHotkeyShift[] = TEXT("ShadowHotkeyShift");
  243. static TCHAR szTreeWidth[] = TEXT("TreeWidth");
  244. /////////////////////////////////////////////////////////////////////////////
  245. // CWinAdminApp::ReadPreferences
  246. //
  247. void CWinAdminApp::ReadPreferences()
  248. {
  249. HKEY hKeyWinAdmin;
  250. DWORD dwType, cbData, dwValue;
  251. TCHAR szValue[128];
  252. // Set default values for everything
  253. m_Confirmation = 1;
  254. m_SavePreferences = 1;
  255. m_ProcessListRefreshTime = 5000;
  256. m_StatusRefreshTime = 1000;
  257. m_ShowSystemProcesses = TRUE;
  258. m_ShowAllServers = FALSE;
  259. m_ShadowHotkeyKey = VK_MULTIPLY;
  260. m_ShadowHotkeyShift = KBDCTRL;
  261. m_TreeWidth = 200;
  262. m_Placement.rcNormalPosition.right = -1;
  263. // Open registry key for our application
  264. DWORD Disposition;
  265. if(RegCreateKeyEx(HKEY_CURRENT_USER, szWinAdminAppKey, 0, TEXT(""), REG_OPTION_NON_VOLATILE,
  266. KEY_READ, NULL, &hKeyWinAdmin, &Disposition) != ERROR_SUCCESS) return;
  267. // Read the previous WINDOWPLACEMENT.
  268. cbData = sizeof(szValue);
  269. if((RegQueryValueEx(hKeyWinAdmin, szPlacement, NULL, &dwType,
  270. (LPBYTE)szValue, &cbData) != ERROR_SUCCESS) ||
  271. !(*szValue) ||
  272. (swscanf( szValue, szPlacementFormat,
  273. &m_Placement.flags, &m_Placement.showCmd,
  274. &m_Placement.ptMinPosition.x, &m_Placement.ptMinPosition.y,
  275. &m_Placement.ptMaxPosition.x, &m_Placement.ptMaxPosition.y,
  276. &m_Placement.rcNormalPosition.left,
  277. &m_Placement.rcNormalPosition.top,
  278. &m_Placement.rcNormalPosition.right,
  279. &m_Placement.rcNormalPosition.bottom ) != 10) ) {
  280. // Flag to use the default window placement.
  281. m_Placement.rcNormalPosition.right = -1;
  282. }
  283. /*
  284. * Flag for initial showing of main window in our override of
  285. * CFrameWnd::ActivateFrame() (in our CMainFrame class).
  286. */
  287. m_Placement.length = (UINT)-1;
  288. // Read the Confirmation flag
  289. cbData = sizeof(m_Confirmation);
  290. if(RegQueryValueEx(hKeyWinAdmin, szConfirmation, NULL, &dwType, (LPBYTE)&dwValue,
  291. &cbData) == ERROR_SUCCESS) {
  292. m_Confirmation = dwValue;
  293. }
  294. // Read the Save Preferences flag
  295. cbData = sizeof(m_SavePreferences);
  296. if(RegQueryValueEx(hKeyWinAdmin, szSaveSettings, NULL, &dwType, (LPBYTE)&dwValue,
  297. &cbData) == ERROR_SUCCESS) {
  298. m_SavePreferences = dwValue;
  299. }
  300. // Read the Show System Processes flag
  301. cbData = sizeof(m_ShowSystemProcesses);
  302. if(RegQueryValueEx(hKeyWinAdmin, szShowSystemProcesses, NULL, &dwType, (LPBYTE)&dwValue,
  303. &cbData) == ERROR_SUCCESS) {
  304. m_ShowSystemProcesses = dwValue;
  305. }
  306. #if 0
  307. // Read the Show All Servers flag
  308. cbData = sizeof(m_ShowAllServers);
  309. if(RegQueryValueEx(hKeyWinAdmin, szShowAllServers, NULL, &dwType, (LPBYTE)&dwValue,
  310. &cbData) == ERROR_SUCCESS) {
  311. m_ShowAllServers = dwValue;
  312. }
  313. #endif
  314. // Read the Process List Refresh Time
  315. cbData = sizeof(m_ProcessListRefreshTime);
  316. if(RegQueryValueEx(hKeyWinAdmin, szListRefreshTime, NULL, &dwType, (LPBYTE)&dwValue,
  317. &cbData) == ERROR_SUCCESS) {
  318. m_ProcessListRefreshTime = dwValue;
  319. }
  320. // Read the Status Dialog Refresh Time
  321. cbData = sizeof(m_StatusRefreshTime);
  322. if(RegQueryValueEx(hKeyWinAdmin, szStatusRefreshTime, NULL, &dwType, (LPBYTE)&dwValue,
  323. &cbData) == ERROR_SUCCESS) {
  324. m_StatusRefreshTime = dwValue;
  325. }
  326. // Read the Shadow Hotkey Key
  327. cbData = sizeof(m_ShadowHotkeyKey);
  328. if(RegQueryValueEx(hKeyWinAdmin, szShadowHotkeyKey, NULL, &dwType, (LPBYTE)&dwValue,
  329. &cbData) == ERROR_SUCCESS) {
  330. m_ShadowHotkeyKey = dwValue;
  331. }
  332. // Read the Shadow Hotkey Shift
  333. cbData = sizeof(m_ShadowHotkeyShift);
  334. if(RegQueryValueEx(hKeyWinAdmin, szShadowHotkeyShift, NULL, &dwType, (LPBYTE)&dwValue,
  335. &cbData) == ERROR_SUCCESS) {
  336. m_ShadowHotkeyShift = dwValue;
  337. }
  338. // CPR 1698: (Upgrade check for SouthBeach build 129 WINADMIN saved
  339. // profile). If the m_nShadowHotkeyKey is VK_ESCAPE (no longer allowed),
  340. // set the hotkey to CTRL-* (the new default).
  341. if(m_ShadowHotkeyKey == VK_ESCAPE) {
  342. m_ShadowHotkeyKey = VK_MULTIPLY;
  343. m_ShadowHotkeyShift = KBDCTRL;
  344. }
  345. // Read the Tree Width
  346. cbData = sizeof(m_TreeWidth);
  347. if(RegQueryValueEx(hKeyWinAdmin, szTreeWidth, NULL, &dwType, (LPBYTE)&dwValue,
  348. &cbData) == ERROR_SUCCESS) {
  349. m_TreeWidth = dwValue;
  350. }
  351. RegCloseKey(hKeyWinAdmin);
  352. } // end CWinAdminApp::ReadPreferences
  353. /////////////////////////////////////////////////////////////////////////////
  354. // CWinAdminApp::WritePreferences
  355. //
  356. void CWinAdminApp::WritePreferences()
  357. {
  358. HKEY hKeyWinAdmin;
  359. DWORD dwValue;
  360. TCHAR szValue[128];
  361. // Open registry key for our application
  362. DWORD Disposition;
  363. if(RegCreateKeyEx(HKEY_CURRENT_USER, szWinAdminAppKey, 0, TEXT(""), REG_OPTION_NON_VOLATILE,
  364. KEY_WRITE, NULL, &hKeyWinAdmin, &Disposition) != ERROR_SUCCESS) return;
  365. // Always write the Save Settings on Exit entry
  366. dwValue = m_SavePreferences;
  367. RegSetValueEx(hKeyWinAdmin, szSaveSettings, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
  368. // If the user didn't want to save settings, we're done
  369. if(!m_SavePreferences) {
  370. RegCloseKey(hKeyWinAdmin);
  371. return;
  372. }
  373. // Write the WINDOWPLACEMENT
  374. m_Placement.flags = 0;
  375. // if(m_pMainWnd->IsZoomed())
  376. // m_Placement.flags |= WPF_RESTORETOMAXIMIZED;
  377. wsprintf(szValue, szPlacementFormat, m_Placement.flags, m_Placement.showCmd,
  378. m_Placement.ptMinPosition.x, m_Placement.ptMinPosition.y,
  379. m_Placement.ptMaxPosition.x, m_Placement.ptMaxPosition.y,
  380. m_Placement.rcNormalPosition.left,
  381. m_Placement.rcNormalPosition.top,
  382. m_Placement.rcNormalPosition.right,
  383. m_Placement.rcNormalPosition.bottom);
  384. RegSetValueEx(hKeyWinAdmin, szPlacement, 0, REG_SZ,
  385. (LPBYTE)szValue, (lstrlen(szValue) + 1) * sizeof(TCHAR));
  386. // Write the Confirmation flag
  387. dwValue = m_Confirmation;
  388. RegSetValueEx(hKeyWinAdmin, szConfirmation, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
  389. // Write the Show System Processes flag
  390. dwValue = m_ShowSystemProcesses;
  391. RegSetValueEx(hKeyWinAdmin, szShowSystemProcesses, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
  392. // Write the Show All Servers flag
  393. dwValue = m_ShowAllServers;
  394. RegSetValueEx(hKeyWinAdmin, szShowAllServers, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
  395. // Write the Process List Refresh Time
  396. dwValue = m_ProcessListRefreshTime;
  397. RegSetValueEx(hKeyWinAdmin, szListRefreshTime, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
  398. // Write the Status Dialog Refresh Time
  399. dwValue = m_StatusRefreshTime;
  400. RegSetValueEx(hKeyWinAdmin, szStatusRefreshTime, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
  401. // Write the Shadow Hotkey Key
  402. dwValue = m_ShadowHotkeyKey;
  403. RegSetValueEx(hKeyWinAdmin, szShadowHotkeyKey, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
  404. // Write the Shadow Hotkey Shift state
  405. dwValue = m_ShadowHotkeyShift;
  406. RegSetValueEx(hKeyWinAdmin, szShadowHotkeyShift, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
  407. // Write the Tree Width
  408. dwValue = m_TreeWidth;
  409. RegSetValueEx(hKeyWinAdmin, szTreeWidth, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
  410. // Close the registry key
  411. RegCloseKey(hKeyWinAdmin);
  412. } // end CWinAdminApp::WritePreferences
  413. /////////////////////////////////////////////////////////////////////////////
  414. // CWinAdminApp::IsBrowserRunning
  415. //
  416. BOOL CWinAdminApp::IsBrowserRunning()
  417. {
  418. SC_HANDLE managerHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  419. SC_HANDLE serviceHandle = OpenService(managerHandle, szICABrowserServiceName, SERVICE_QUERY_STATUS);
  420. SERVICE_STATUS serviceStatus;
  421. QueryServiceStatus(serviceHandle, (LPSERVICE_STATUS)&serviceStatus);
  422. CloseServiceHandle(serviceHandle);
  423. CloseServiceHandle(managerHandle);
  424. if(serviceStatus.dwCurrentState != SERVICE_RUNNING) return FALSE;
  425. else return TRUE;
  426. } // end CWinAdminApp::IsBrowserRunning
  427. /*******************************************************************************
  428. *
  429. * OnAppAbout - CWinAdminApp member function: command
  430. *
  431. * Display the about box dialog (uses Shell32 generic About dialog).
  432. *
  433. * ENTRY:
  434. * EXIT:
  435. *
  436. ******************************************************************************/
  437. // Typedef for the ShellAbout function
  438. typedef void (WINAPI *LPFNSHELLABOUT)(HWND, LPCTSTR, LPCTSTR, HICON);
  439. void CWinAdminApp::OnAppAbout()
  440. {
  441. HMODULE hMod;
  442. LPFNSHELLABOUT lpfn;
  443. if ( hMod = ::LoadLibrary( TEXT("SHELL32") ) )
  444. {
  445. if (lpfn = (LPFNSHELLABOUT)::GetProcAddress( hMod,
  446. #ifdef UNICODE
  447. "ShellAboutW"
  448. #else
  449. "ShellAboutA"
  450. #endif // UNICODE
  451. ))
  452. {
  453. (*lpfn)( m_pMainWnd->m_hWnd, (LPCTSTR)m_pszAppName,
  454. (LPCTSTR)TEXT(""), LoadIcon(IDR_MAINFRAME) );
  455. }
  456. ::FreeLibrary(hMod);
  457. }
  458. else
  459. {
  460. ::MessageBeep( MB_ICONEXCLAMATION );
  461. }
  462. } // end CWinadminApp::OnAppAbout
  463. /*******************************************************************************
  464. *
  465. * AreWeRunningTerminalServices
  466. *
  467. * Check if we are running terminal server
  468. *
  469. * ENTRY:
  470. *
  471. * EXIT: BOOL: True if we are running Terminal Services False if we
  472. * are not running Terminal Services
  473. *
  474. *
  475. ******************************************************************************/
  476. /*
  477. BOOL AreWeRunningTerminalServices(void)
  478. {
  479. OSVERSIONINFOEX osVersionInfo;
  480. DWORDLONG dwlConditionMask = 0;
  481. ZeroMemory(&osVersionInfo, sizeof(OSVERSIONINFOEX));
  482. osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  483. osVersionInfo.wSuiteMask = VER_SUITE_TERMINAL | VER_SUITE_SINGLEUSERTS;
  484. VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_OR );
  485. return VerifyVersionInfo(
  486. &osVersionInfo,
  487. VER_SUITENAME,
  488. dwlConditionMask
  489. );
  490. }
  491. */
  492. /////////////////////////////////////////////////////////////////////////////
  493. // CWinAdminApp commands
  494. //=---------------------------------------------------------
  495. BEGIN_MESSAGE_MAP( CMyTabCtrl , CTabCtrl )
  496. ON_WM_SETFOCUS( )
  497. END_MESSAGE_MAP( )
  498. void CMyTabCtrl::OnSetFocus( CWnd *pOldWnd )
  499. {
  500. ODS( L"CMyTabCtrl::OnSetFocus\n" );
  501. CWinAdminDoc *pDoc = (CWinAdminDoc*)((CWinAdminApp*)AfxGetApp())->GetDocument();
  502. if( pDoc != NULL )
  503. {
  504. ODS( L"\tTabctrl has focus\n" );
  505. pDoc->RegisterLastFocus( TAB_CTRL );
  506. }
  507. CTabCtrl::OnSetFocus( pOldWnd );
  508. }