Windows NT 4.0 source code leak
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.

649 lines
20 KiB

4 years ago
  1. //==========================================================================//
  2. // Includes //
  3. //==========================================================================//
  4. #include <string.h> // strupr
  5. #include <stdio.h> // for sprintf.
  6. #include "perfmon.h"
  7. #include "init.h" // external declarations for this file
  8. #include "alert.h" // for AlertIitializeApplication
  9. #include "command.h" // for ViewChart
  10. #include "grafdata.h" // for QuerySaveChart
  11. #include "graph.h" // for GraphInitializeApplication
  12. #include "legend.h" // for LegendInitializeApplication
  13. #include "log.h" // for LogInitializeApplication
  14. #include "intrline.h" // for ILineInitializeApplication
  15. #include "perfdata.h" // for PerfDataInitializeInstance
  16. #include "perfmops.h" // for OpenFileHandler, for now
  17. #include "status.h" // for StatusInitializeApplication
  18. #include "timeline.h" // for TLineInitializeApplication
  19. #include "playback.h" // for PlaybackInitializeInstance
  20. #include "registry.h" // for Load/SaveMainWindowPlacement
  21. #include "report.h" // for ReportInitializeApplication
  22. #include "toolbar.h" // for ToolbarInitializeApplication
  23. #include "utils.h"
  24. #include "fileopen.h" // for FileOpen
  25. #include "pmemory.h" // for MemoryFree
  26. extern TCHAR DefaultLangId[] ;
  27. extern TCHAR EnglishLangId[] ;
  28. static LPSTR lpszCommandLine ;
  29. //==========================================================================//
  30. // Constants //
  31. //==========================================================================//
  32. #define szPerfmonMainClass TEXT("PerfmonMainClass")
  33. HHOOK lpMsgFilterProc ;
  34. DWORD FAR PASCAL MessageFilterProc (int nCode, WPARAM wParam,
  35. LPARAM lParam) ;
  36. //==========================================================================//
  37. // Local Functions //
  38. //==========================================================================//
  39. static
  40. LONG
  41. EnablePrivilege (
  42. IN LPTSTR szPrivName
  43. )
  44. {
  45. LUID SePrivNameValue;
  46. TOKEN_PRIVILEGES tkp;
  47. HANDLE hToken = NULL;
  48. /* Retrieve a handle of the access token. */
  49. if (!OpenProcessToken(GetCurrentProcess(),
  50. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  51. &hToken)) {
  52. goto Exit_Point;
  53. }
  54. /*
  55. * Enable the privilege by name and get the ID
  56. */
  57. if (!LookupPrivilegeValue((LPTSTR) NULL,
  58. szPrivName,
  59. &SePrivNameValue)) {
  60. goto Exit_Point;
  61. }
  62. tkp.PrivilegeCount = 1;
  63. tkp.Privileges[0].Luid = SePrivNameValue;
  64. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  65. AdjustTokenPrivileges(hToken,
  66. FALSE,
  67. &tkp,
  68. sizeof(TOKEN_PRIVILEGES),
  69. (PTOKEN_PRIVILEGES) NULL,
  70. (PDWORD) NULL);
  71. /* The return value of AdjustTokenPrivileges be texted. */
  72. Exit_Point:
  73. if (hToken != NULL) CloseHandle (hToken);
  74. return GetLastError();
  75. }
  76. void GetScalesFonts (void)
  77. {
  78. LOGFONT lf ;
  79. memset (&lf, 0, sizeof (lf)) ;
  80. lstrcpy (lf.lfFaceName, szScalesFontFace) ;
  81. lf.lfHeight = iScalesFontHeight ;
  82. lf.lfWeight = FW_REGULAR ;
  83. hFontScales = CreateFontIndirect (&lf) ;
  84. lf.lfWeight = FW_BOLD ;
  85. hFontScalesBold = CreateFontIndirect (&lf) ;
  86. }
  87. BOOL InitializeSystemValues (void)
  88. /*
  89. Effect: Read and store in variables the various system values,
  90. such as the width and height of the screen and icons,
  91. the width of scroll bars, etc.
  92. Called By: PerfmonInitialize only.
  93. Returns: Whether this function was successful in getting all
  94. needed system values.
  95. */
  96. { // InitializeSystemValues
  97. xScreenWidth = GetSystemMetrics (SM_CXSCREEN) ;
  98. yScreenHeight = GetSystemMetrics (SM_CYSCREEN) ;
  99. xBorderWidth = GetSystemMetrics (SM_CXBORDER) ;
  100. yBorderHeight = GetSystemMetrics (SM_CYBORDER) ;
  101. xScrollWidth = GetSystemMetrics (SM_CXVSCROLL) ;
  102. yScrollHeight = GetSystemMetrics (SM_CYHSCROLL) ;
  103. xScrollThumbWidth = GetSystemMetrics (SM_CXHTHUMB) ;
  104. yScrollThumbHeight = GetSystemMetrics (SM_CYVTHUMB) ;
  105. xDlgBorderWidth = GetSystemMetrics (SM_CXDLGFRAME) ;
  106. yDlgBorderHeight = GetSystemMetrics (SM_CYDLGFRAME) ;
  107. MinimumSize = yScrollHeight +
  108. GetSystemMetrics (SM_CYMENU) +
  109. GetSystemMetrics (SM_CYCAPTION) ;
  110. //================================================================//
  111. // create all the brushes and pens for performance improvement //
  112. //================================================================//
  113. CreatePerfmonSystemObjects () ;
  114. hWhitePen = CreatePen (PS_SOLID, 3, crWhite) ;
  115. return (TRUE) ;
  116. } // InitializeSystemValues
  117. BOOL InitializeApplication (void)
  118. /*
  119. Effect: Perform all initializations required for the FIRST
  120. instance of the Perfmon application. In particular,
  121. register all of Perfmon's window classes.
  122. Note: There is no background brush set for the MainWindow
  123. class so that the main window is never erased. The
  124. client area of MainWindow is always covered by one
  125. of the view windows. If we erase it, it would just
  126. flicker needlessly.
  127. Called By: PerfmonInitialize only.
  128. Returns: Whether this function was successful in initializing.
  129. */
  130. { // InitializeApplication
  131. BOOL bSuccess ;
  132. WNDCLASS wc ;
  133. TCHAR LocalHelpFileName [ShortTextLen] ;
  134. LPTSTR pFileName ;
  135. hIcon = LoadIcon (hInstance, idIcon) ;
  136. //=============================//
  137. // Register Main window class //
  138. //=============================//
  139. wc.style = CS_DBLCLKS | CS_BYTEALIGNCLIENT;
  140. wc.lpfnWndProc = (WNDPROC) MainWndProc;
  141. wc.hInstance = hInstance;
  142. wc.cbClsExtra = 0 ;
  143. wc.cbWndExtra = 0;
  144. wc.hIcon = hIcon ;
  145. wc.hCursor = LoadCursor(NULL, IDI_APPLICATION);
  146. wc.hbrBackground = NULL ; // see note above
  147. wc.lpszMenuName = idMenuChart ;
  148. wc.lpszClassName = szPerfmonMainClass ;
  149. bSuccess = RegisterClass (&wc) ;
  150. //=============================//
  151. // Register Abstract "Systems" //
  152. //=============================//
  153. hbLightGray = GetStockObject (LTGRAY_BRUSH) ;
  154. if (bSuccess)
  155. bSuccess = StatusInitializeApplication () ;
  156. if (bSuccess)
  157. bSuccess = GraphInitializeApplication () ;
  158. #ifdef ADVANCED_PERFMON
  159. if (bSuccess)
  160. bSuccess = LogInitializeApplication () ;
  161. if (bSuccess)
  162. bSuccess = AlertInitializeApplication () ;
  163. if (bSuccess)
  164. bSuccess = ReportInitializeApplication () ;
  165. if (bSuccess)
  166. bSuccess = ILineInitializeApplication () ;
  167. if (bSuccess)
  168. bSuccess = TLineInitializeApplication () ;
  169. #endif
  170. // setup messagehook to handle F1 as help
  171. lpMsgFilterProc = SetWindowsHookEx (WH_MSGFILTER,
  172. (HOOKPROC) MessageFilterProc,
  173. hInstance,
  174. GetCurrentThreadId()) ;
  175. // get the help file full path name
  176. LoadString (hInstance, IDS_HELPFILE_NAME,
  177. (LPTSTR)LocalHelpFileName, ShortTextLen-1);
  178. if (LocalHelpFileName[0])
  179. {
  180. pszHelpFile = (LPTSTR) MemoryAllocate (FilePathLen * sizeof (TCHAR)) ;
  181. SearchPath (NULL, LocalHelpFileName, NULL,
  182. FilePathLen - 1, pszHelpFile, &pFileName) ;
  183. }
  184. else
  185. {
  186. // no help file
  187. pszHelpFile = (LPTSTR) MemoryAllocate (sizeof (TCHAR)) ;
  188. *pszHelpFile = TEXT('\0') ;
  189. }
  190. return (bSuccess) ;
  191. } // InitializeApplication
  192. BOOL InitializeInstance (int nCmdShow, LPCSTR lpszCmdLine)
  193. /*
  194. Effect: Perform all initializations required for EACH instance
  195. of the Perfmon application. In particular, create all
  196. of Perfmon's initial windows, and perform any other
  197. initializations except registering classes (done in
  198. InitializeApplication).
  199. Called By: PerfmonInitialize only.
  200. Note: This function has multiple return points.
  201. Returns: Whether this function was successful in initalizing.
  202. */
  203. { // InitializeInstance
  204. DWORD ComputerNameLength;
  205. TCHAR szApplication [WindowCaptionLen] ;
  206. bCloseLocalMachine = FALSE;
  207. // enable privileges needed to profile system
  208. // if this fails, that's ok for now.
  209. EnablePrivilege (SE_SYSTEM_PROFILE_NAME); // to access perfdata
  210. EnablePrivilege (SE_INC_BASE_PRIORITY_NAME); // to raise priority
  211. //=============================//
  212. // Set Priority high //
  213. //=============================//
  214. SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS) ;
  215. SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST) ;
  216. //=============================//
  217. // Load Resources //
  218. //=============================//
  219. GetScalesFonts () ;
  220. hMenuChart = LoadMenu (hInstance, idMenuChart) ;
  221. #ifdef ADVANCED_PERFMON
  222. hMenuAlert = LoadMenu (hInstance, idMenuAlert) ;
  223. hMenuLog = LoadMenu (hInstance, idMenuLog) ;
  224. hMenuReport = LoadMenu (hInstance, idMenuReport) ;
  225. #endif
  226. hAccelerators = LoadAccelerators (hInstance, idAccelerators) ;
  227. //=============================//
  228. // Initialize Systems //
  229. //=============================//
  230. iLanguage = GetUserDefaultLangID() ;
  231. iEnglishLanguage = MAKELANGID (LANG_ENGLISH, LANG_NEUTRAL) ;
  232. // iEnglishLanguage = MAKELANGID (iLanguage & 0x0ff, LANG_NEUTRAL) ;
  233. TSPRINTF (DefaultLangId, TEXT("%03x"), iLanguage) ;
  234. TSPRINTF (EnglishLangId, TEXT("%03x"), iEnglishLanguage) ;
  235. // GetComputerName returns the name without the "\\" prefix. We add
  236. // the prefix before even calling the routine. This is so that all our
  237. // computer names have the prefix and are therefore compatible with
  238. // I_SetSystemFocus (see perfmops.c).
  239. ComputerNameLength = MAX_PATH + 1;
  240. lstrcpy (LocalComputerName, szComputerPrefix) ;
  241. GetComputerName (LocalComputerName + lstrlen (szComputerPrefix),
  242. &ComputerNameLength);
  243. PlaybackInitializeInstance () ;
  244. PerfDataInitializeInstance () ;
  245. //Copy command line into buffer for modification
  246. lpszCommandLine = (LPSTR)MemoryAllocate (strlen (lpszCmdLine) + sizeof(CHAR)) ;
  247. if(lpszCommandLine)
  248. strcpy(lpszCommandLine, lpszCmdLine) ;
  249. else
  250. return (FALSE) ;
  251. StringLoad (IDS_APPNAME, szApplication) ;
  252. //Insure CmdLineComputerName starts out NULL
  253. CmdLineComputerName[0] = TEXT('\0') ;
  254. //Check to see if there is a computer name specified on the command
  255. //line (indicated by /c, or /C). If there is, get it and
  256. //null out the command line string so that it is not mistaken for
  257. //startup file. This assumes that specifying a computer and a startup
  258. //file on the command line are mutually exclusive. If the /c option
  259. //is on the command line, anything else on the command line is discarded.
  260. if (!strempty (lpszCommandLine)) {
  261. LPSTR lpszNewCL ;
  262. //Preserve initial command line pointer position
  263. lpszNewCL = (LPSTR)lpszCommandLine ;
  264. while (*lpszNewCL != '\0' && *lpszCommandLine) {
  265. if (*lpszNewCL == '/' || *lpszNewCL == '-') {
  266. lpszNewCL++ ;
  267. if (*lpszNewCL == 'c' || *lpszNewCL == 'C') {
  268. int i = 0;
  269. lpszNewCL++ ;
  270. //ignore leading backslashes * spaces
  271. while (*lpszNewCL == '\\' || *lpszNewCL == ' ')
  272. lpszNewCL++ ;
  273. //Terminate at first blank space if there is one.
  274. //We don't allow anything else on the command line
  275. //if a computer name is specified.
  276. while (lpszNewCL[i] != ' ' && lpszNewCL[i] != '\0')
  277. i++ ;
  278. lpszNewCL[i] = '\0' ;
  279. if ((*lpszNewCL != '\0') && (strlen(lpszNewCL) <= MAX_PATH)) {
  280. int nSizePrefix ;
  281. nSizePrefix = lstrlen (szComputerPrefix) ;
  282. lstrcpy( CmdLineComputerName, szComputerPrefix ) ;
  283. MultiByteToWideChar (CP_ACP,
  284. MB_PRECOMPOSED,
  285. lpszNewCL,
  286. -1,
  287. CmdLineComputerName + nSizePrefix,
  288. sizeof(CmdLineComputerName) - nSizePrefix) ;
  289. //prevent lpszCommandLine from being used as input file & stop while loop
  290. *lpszCommandLine = '\0' ;
  291. } else {
  292. LPTSTR lpszErrMsg ;
  293. TCHAR lpszFormat[80] ;
  294. LoadString(hInstance, ERR_BADCOMPUTERNAME, lpszFormat, sizeof(lpszFormat)/sizeof(TCHAR)) ;
  295. lpszErrMsg = (LPTSTR)MemoryAllocate ((strlen (lpszNewCL) + 1)*sizeof(TCHAR) + sizeof(lpszFormat)) ;
  296. //If memory allocation failed, don't display error message
  297. if (lpszErrMsg) {
  298. //lpszFormat uses %S specifier so lpszNewCL can be ansi string
  299. wsprintf (lpszErrMsg, lpszFormat, lpszNewCL) ;
  300. MessageBox (NULL, lpszErrMsg, szApplication, MB_OK | MB_ICONSTOP | MB_TASKMODAL) ;
  301. }
  302. //prevent lpszCommandLine from being used as input file & stop while loop
  303. *lpszCommandLine = '\0' ;
  304. }
  305. }
  306. }
  307. lpszNewCL++ ;
  308. }
  309. }
  310. //=============================//
  311. // Create Window //
  312. //=============================//
  313. hWndMain = CreateWindow (szPerfmonMainClass,
  314. szApplication,
  315. WS_OVERLAPPEDWINDOW | WS_BORDER,
  316. CW_USEDEFAULT, CW_USEDEFAULT,
  317. CW_USEDEFAULT, CW_USEDEFAULT,
  318. NULL,
  319. NULL,
  320. NULL,
  321. NULL);
  322. if (!hWndMain)
  323. return (FALSE) ;
  324. ViewChart (hWndMain) ;
  325. LoadMainWindowPlacement (hWndMain) ;
  326. //=============================//
  327. // Setup for event logging //
  328. //=============================//
  329. hEventLog = RegisterEventSource (
  330. (LPTSTR)NULL, // Use Local Machine
  331. TEXT("PerfMon")); // event log app name to find in registry
  332. return (TRUE) ;
  333. } // InitializeInstance
  334. //==========================================================================//
  335. // Exported Functions //
  336. //==========================================================================//
  337. BOOL PerfmonInitialize (HINSTANCE hCurrentInstance,
  338. HINSTANCE hPrevInstance,
  339. LPCSTR lpszCmdLine,
  340. int nCmdShow)
  341. /*
  342. Effect: Performa all initializations required when Perfmon is
  343. started. In particular, initialize all "systems", register
  344. all window classes, create needed windows, read in and
  345. process font and Perfmon lists.
  346. Called By: WinMain only, at the start of the application.
  347. Assert: There are no other instances of Perfmon currently
  348. executing.
  349. Returns: Whether initialization was successful. If this function
  350. returns FALSE, Perfmon should exit immediately.
  351. Internals: The bSuccess variable is used to conditionalize each
  352. successive initialization step.
  353. */
  354. { // PerfmonInitialize
  355. BOOL bSuccess ;
  356. TCHAR szFilePath [FilePathLen + 1] ;
  357. LPTSTR pFileNameStart ;
  358. HANDLE hFindFile ;
  359. WIN32_FIND_DATA FindFileInfo ;
  360. CHAR QuoteChar ;
  361. LPSTR pCmdLine ;
  362. LPSTR lpszCmdLineStart = NULL ;
  363. int NameOffset ;
  364. int StringLen ;
  365. hInstance = hCurrentInstance ;
  366. bSuccess = InitializeSystemValues () ;
  367. if (bSuccess && !hPrevInstance)
  368. bSuccess = InitializeApplication () ;
  369. if (bSuccess)
  370. bSuccess = InitializeInstance (nCmdShow, lpszCmdLine) ;
  371. GetDateTimeFormats() ;
  372. lpszCmdLineStart = lpszCommandLine ;
  373. if (bSuccess)
  374. {
  375. if (strempty (lpszCommandLine))
  376. StringLoad (IDS_DEFAULTPATH, szFilePath) ;
  377. else
  378. {
  379. // check for single or double quote
  380. QuoteChar = *lpszCommandLine ;
  381. if (QuoteChar == '\'' || QuoteChar == '\"')
  382. {
  383. lpszCommandLine++ ;
  384. // remove the matching QuoteChar if found
  385. pCmdLine = (LPSTR) lpszCommandLine ;
  386. while (*pCmdLine != '\0')
  387. {
  388. if (*pCmdLine == QuoteChar)
  389. {
  390. *pCmdLine = '\0' ;
  391. break ;
  392. }
  393. else
  394. {
  395. pCmdLine++ ;
  396. }
  397. }
  398. }
  399. // convert the LPSTR to LPTSTR
  400. StringLen = strlen(lpszCommandLine) + 1 ;
  401. if (StringLen > sizeof(szFilePath))
  402. {
  403. StringLen = sizeof (szFilePath) - sizeof (TEXT('\0')) ;
  404. }
  405. szFilePath[FilePathLen] = TEXT('\0') ;
  406. mbstowcs (szFilePath, lpszCommandLine, StringLen) ;
  407. if (!(QuoteChar == '\'' || QuoteChar == '\"'))
  408. {
  409. // if there is no quote, then looking for trailing space
  410. LPTSTR lpTempStr = szFilePath ;
  411. while (*lpTempStr != TEXT('\0'))
  412. {
  413. if (*lpTempStr == TEXT(' '))
  414. {
  415. *lpTempStr = TEXT('\0') ;
  416. break ;
  417. }
  418. lpTempStr++ ;
  419. }
  420. }
  421. pFileNameStart = ExtractFileName (szFilePath) ;
  422. NameOffset = pFileNameStart - szFilePath ;
  423. // convert short filename to long NTFS filename if necessary
  424. hFindFile = FindFirstFile (szFilePath, &FindFileInfo) ;
  425. if (hFindFile && hFindFile != INVALID_HANDLE_VALUE)
  426. {
  427. // append the file name back to the path name
  428. lstrcpy (&szFilePath[NameOffset], FindFileInfo.cFileName) ;
  429. FindClose (hFindFile) ;
  430. }
  431. }
  432. // OpenFileHandler (hWndMain, szFilePath) ;
  433. FileOpen (hWndMain, (int)0, (LPTSTR)szFilePath) ;
  434. PrepareMenu (GetMenu (hWndMain));
  435. }
  436. if (lpszCmdLineStart)
  437. {
  438. MemoryFree (lpszCmdLineStart) ;
  439. lpszCommandLine = NULL ;
  440. }
  441. return (bSuccess) ;
  442. } // PerfmonInitialize
  443. void PerfmonClose (HWND hWndMain)
  444. {
  445. DWORD dwException;
  446. // close the log file for now.
  447. // need to query the user later..!!
  448. #if 0
  449. if (LogCollecting (hWndLog))
  450. {
  451. PLOG pLog = LogData (hWndLog) ;
  452. if (pLog)
  453. {
  454. CloseLog (hWndLog, pLog) ;
  455. }
  456. }
  457. #endif
  458. // reset all views - will free all systems as well
  459. ResetGraphView (hWndGraph) ;
  460. ResetAlertView (hWndAlert) ;
  461. ResetLogView (hWndLog) ;
  462. ResetReportView (hWndReport) ;
  463. try {
  464. // if the key has already been closed, this will
  465. // generate an exception so we'll catch that here
  466. // and continue...
  467. //
  468. // close the local machine
  469. if (bCloseLocalMachine)
  470. {
  471. RegCloseKey (HKEY_PERFORMANCE_DATA) ;
  472. }
  473. } except (EXCEPTION_EXECUTE_HANDLER) {
  474. // get the exception for the debugger user, that's all
  475. dwException = GetExceptionCode();
  476. }
  477. // free all the filenames
  478. if (pChartFullFileName)
  479. {
  480. MemoryFree (pChartFullFileName) ;
  481. pChartFullFileName = NULL ;
  482. }
  483. if (pAlertFullFileName)
  484. {
  485. MemoryFree (pAlertFullFileName) ;
  486. pAlertFullFileName = NULL ;
  487. }
  488. if (pLogFullFileName)
  489. {
  490. MemoryFree (pLogFullFileName) ;
  491. pLogFullFileName = NULL ;
  492. }
  493. if (pReportFullFileName)
  494. {
  495. MemoryFree (pReportFullFileName) ;
  496. pReportFullFileName = NULL ;
  497. }
  498. // free all the GDI resources
  499. DeletePen (hWhitePen) ;
  500. DeletePerfmonSystemObjects () ;
  501. // close event log
  502. DeregisterEventSource (hEventLog);
  503. SaveMainWindowPlacement (hWndMain) ;
  504. DestroyWindow (hWndMain) ;
  505. } // PerfmonClose