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.

371 lines
10 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation 1996-2001.
  5. //
  6. // File: perfanal.cpp
  7. //
  8. // Contents: implementation of CPerformAnalysis
  9. //
  10. //----------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. #include "wsecmgr.h"
  13. #include "snapmgr.h"
  14. #include "PerfAnal.h"
  15. #include "wrapper.h"
  16. #include "util.h"
  17. #ifdef _DEBUG
  18. #define new DEBUG_NEW
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22. /////////////////////////////////////////////////////////////////////////////
  23. // CPerformAnalysis dialog
  24. CPerformAnalysis::CPerformAnalysis(CWnd * pParent, UINT nTemplateID)
  25. : CHelpDialog(a215HelpIDs, nTemplateID ? nTemplateID : IDD, pParent)
  26. {
  27. //{{AFX_DATA_INIT(CPerformAnalysis)
  28. m_strLogFile = _T("");
  29. //}}AFX_DATA_INIT
  30. }
  31. void CPerformAnalysis::DoDataExchange(CDataExchange* pDX)
  32. {
  33. CDialog::DoDataExchange(pDX);
  34. //{{AFX_DATA_MAP(CPerformAnalysis)
  35. DDX_Control(pDX, IDOK, m_ctlOK);
  36. DDX_Text(pDX, IDC_ERROR, m_strError);
  37. DDX_Text(pDX, IDC_LOG_FILE, m_strLogFile);
  38. //}}AFX_DATA_MAP
  39. }
  40. BEGIN_MESSAGE_MAP(CPerformAnalysis, CHelpDialog)
  41. //{{AFX_MSG_MAP(CPerformAnalysis)
  42. ON_BN_CLICKED(IDOK, OnOK)
  43. ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
  44. ON_EN_CHANGE(IDC_LOG_FILE, OnChangeLogFile)
  45. //}}AFX_MSG_MAP
  46. END_MESSAGE_MAP()
  47. /////////////////////////////////////////////////////////////////////////////
  48. // CPerformAnalysis message handlers
  49. void CPerformAnalysis::OnBrowse()
  50. {
  51. CString strLogFileExt;
  52. CString strLogFileFilter;
  53. CString strTitle;
  54. OPENFILENAME ofn;
  55. ::ZeroMemory (&ofn, sizeof (OPENFILENAME));
  56. ofn.lStructSize = sizeof(OPENFILENAME);
  57. UpdateData(TRUE);
  58. m_strLogFile.Remove(L'<'); //Raid #463367, '<' is a invalid filename char.
  59. strLogFileExt.LoadString(IDS_LOGFILE_DEF_EXT);
  60. strLogFileFilter.LoadString(IDS_LOGFILE_FILTER);
  61. strTitle.LoadString(IDS_LOGFILE_PICKER_TITLE);
  62. // Translate filter into commdlg format (lots of \0)
  63. LPTSTR szFilter = strLogFileFilter.GetBuffer(0); // modify the buffer in place
  64. // MFC delimits with '|' not '\0'
  65. LPTSTR pch = szFilter;
  66. while ((pch = _tcschr(pch, '|')) != NULL)
  67. *pch++ = '\0';
  68. // do not call ReleaseBuffer() since the string contains '\0' characters
  69. ofn.lpstrFilter = szFilter;
  70. ofn.lpstrFile = m_strLogFile.GetBuffer(MAX_PATH),
  71. ofn.nMaxFile = MAX_PATH;
  72. ofn.lpstrDefExt = strLogFileExt,
  73. ofn.hwndOwner = m_hWnd;
  74. ofn.Flags = OFN_HIDEREADONLY |
  75. OFN_EXPLORER |
  76. OFN_DONTADDTORECENT|
  77. OFN_NOREADONLYRETURN,
  78. ofn.lpstrTitle = strTitle;
  79. //
  80. // Default to the currently picked log file
  81. //
  82. if (GetOpenFileName(&ofn)) {
  83. m_strLogFile.ReleaseBuffer();
  84. UpdateData(FALSE);
  85. if (m_strLogFile.IsEmpty()) //Raid #669231, yanggao, 8/9/2002
  86. m_ctlOK.EnableWindow(FALSE);
  87. else
  88. m_ctlOK.EnableWindow(TRUE);
  89. } else {
  90. m_strLogFile.ReleaseBuffer();
  91. }
  92. }
  93. //+--------------------------------------------------------------------------
  94. //
  95. // Method: DoIt
  96. //
  97. // Synopsis: Actually Analyzes the system (separated from OnOK so it can
  98. // be overridden to Configure the system, etc. while still using
  99. // the same OnOK shell code
  100. //
  101. //---------------------------------------------------------------------------
  102. DWORD CPerformAnalysis::DoIt() {
  103. //
  104. // Store the log file we're using for next time
  105. //
  106. LPTSTR szLogFile = m_strLogFile.GetBuffer(0);
  107. m_pComponentData->GetWorkingDir(GWD_ANALYSIS_LOG,&szLogFile,TRUE,TRUE);
  108. m_strLogFile.ReleaseBuffer();
  109. //
  110. // InspectSystem will handle multi-threading and progress UI so
  111. // SCE doesn't get wierd on the user
  112. //
  113. return InspectSystem(
  114. NULL, // Always use the configuration assigned to the DB
  115. m_strDataBase.IsEmpty() ? NULL: (LPCTSTR)m_strDataBase,
  116. (LPCTSTR)m_strLogFile,
  117. AREA_ALL
  118. );
  119. }
  120. //+--------------------------------------------------------------------------
  121. //
  122. // Method: OnOK
  123. //
  124. // Synopsis: Analyzes the system
  125. //
  126. //---------------------------------------------------------------------------
  127. afx_msg void CPerformAnalysis::OnOK()
  128. {
  129. CWnd *cwnd;
  130. HANDLE hLogFile;
  131. UpdateData(TRUE);
  132. //
  133. // We require a log file that we can write to
  134. //
  135. CString strLogFileExt;
  136. strLogFileExt.LoadString(IDS_LOGFILE_DEF_EXT); //Raid #553110, yanggao
  137. strLogFileExt = TEXT(".") + strLogFileExt;
  138. if (m_strLogFile.IsEmpty()) {
  139. return;
  140. }
  141. else {
  142. m_strLogFile = ExpandEnvironmentStringWrapper(m_strLogFile);
  143. if( !IsValidFileName(m_strLogFile) || IsNameReserved(m_strLogFile, strLogFileExt)) //Raid #463367, Yang Gao, 9/5/2001.
  144. {
  145. CWnd* pwnd = GetDlgItem(IDC_LOG_FILE); //Raid #501877, yanggao, 12/03/2001
  146. if( pwnd )
  147. {
  148. pwnd->SendMessage(EM_SETSEL, (WPARAM)0, (LPARAM)-1);
  149. pwnd->SetFocus();
  150. }
  151. return;
  152. }
  153. }
  154. int i = m_strLogFile.ReverseFind(L'.'); //Raid #553110, yanggao
  155. if( i < 0 || strLogFileExt != m_strLogFile.Right(m_strLogFile.GetLength()-i) )
  156. {
  157. m_strLogFile = m_strLogFile + strLogFileExt;
  158. }
  159. LONG dwPosLow = 0, dwPosHigh = 0;
  160. //This is a safe usage. m_strLogFile is full path.
  161. hLogFile = CreateFile(m_strLogFile, // pointer to name of the file
  162. GENERIC_WRITE, // access (read-write) mode
  163. 0, // share mode
  164. NULL, // pointer to security attributes
  165. OPEN_ALWAYS, // how to create
  166. FILE_ATTRIBUTE_NORMAL, // file attributes
  167. NULL // handle to file with attributes to copy
  168. );
  169. if (INVALID_HANDLE_VALUE == hLogFile) {
  170. LPTSTR pszErr;
  171. CString strMsg;
  172. ////Raid #501886, yanggao, 12/03/2001, Get the error description from system.
  173. FormatMessage(
  174. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  175. FORMAT_MESSAGE_FROM_SYSTEM,
  176. NULL,
  177. GetLastError(),
  178. 0,
  179. (LPTSTR)&pszErr,
  180. 0,
  181. NULL
  182. );
  183. strMsg = pszErr + m_strLogFile;
  184. if( m_strLogFile.GetLength() >= MAX_PATH )
  185. {
  186. CString strTemp;
  187. strTemp.LoadString(IDS_PATH_TOO_LONG);
  188. strMsg = strMsg + L"\n" + strTemp;
  189. }
  190. CString strTitle;
  191. strTitle.LoadString(IDS_ANALYSIS_VIEWER_NAME);
  192. MessageBox(strMsg,strTitle,MB_OK);
  193. CWnd* pwnd = GetDlgItem(IDC_LOG_FILE);
  194. if( pwnd )
  195. {
  196. pwnd->SendMessage(EM_SETSEL, (WPARAM)0, (LPARAM)-1);
  197. pwnd->SetFocus();
  198. }
  199. return;
  200. }
  201. dwPosLow = SetFilePointer(hLogFile, 0, &dwPosHigh, FILE_END );
  202. CloseHandle(hLogFile);
  203. CWaitCursor wc;
  204. DWORD smstatus = ERROR_SUCCESS;
  205. LPNOTIFY pNotify = m_pComponentData->GetNotifier();
  206. ASSERT(pNotify);
  207. //
  208. // Lock the analysis pane since its data is invalid while we're inspecting
  209. //
  210. if (pNotify) {
  211. pNotify->LockAnalysisPane(TRUE);
  212. }
  213. CFolder *pFolder = m_pComponentData->GetAnalFolder();
  214. //
  215. // Force the Analysis root node to be selected so that we display
  216. // the generating information message. If we forse this repaint to happen
  217. // now then we don't seem to have that AV problem.
  218. //
  219. if(pFolder && pNotify){
  220. pNotify->SelectScopeItem(pFolder->GetScopeItem()->ID);
  221. }
  222. //
  223. // Make sure we don't have the database open. That'll prevent us
  224. // from being able to configure.
  225. //
  226. m_pComponentData->UnloadSadInfo();
  227. //
  228. // Disable the child windows so they don't respond to input while we're
  229. // performing the inspection
  230. //
  231. cwnd = GetWindow(GW_CHILD);
  232. while(cwnd) {
  233. cwnd->EnableWindow(FALSE);
  234. cwnd = cwnd->GetNextWindow();
  235. }
  236. smstatus = DoIt();
  237. //Raid #358503, 4/17/2001
  238. if( m_hPWnd )
  239. {
  240. ::EnableWindow(m_hPWnd, TRUE);
  241. }
  242. //
  243. // The inspection data is valid now, so let people back at it
  244. //
  245. if (pNotify) {
  246. pNotify->LockAnalysisPane(false, false);
  247. }
  248. m_pComponentData->SetErroredLogFile(m_strLogFile, dwPosLow );
  249. //
  250. // There was an error so display the log file (if any)
  251. //
  252. if (ERROR_SUCCESS != smstatus) {
  253. m_pComponentData->SetFlags( CComponentDataImpl::flag_showLogFile );
  254. }
  255. //
  256. // We're done inspecting so reenable input to the child windows
  257. //
  258. cwnd = GetWindow(GW_CHILD);
  259. while(cwnd) {
  260. cwnd->EnableWindow(TRUE);
  261. cwnd = cwnd->GetNextWindow();
  262. }
  263. //CDialog::OnOK();
  264. UpdateData();
  265. DestroyWindow();
  266. }
  267. BOOL CPerformAnalysis::OnInitDialog()
  268. {
  269. //Raid #669945, yanggao, 8/9/2002
  270. HWND framehwnd = NULL;
  271. LPCONSOLE pconsole = m_pComponentData->GetConsole();
  272. if( pconsole )
  273. {
  274. pconsole->GetMainWindow(&framehwnd);
  275. if( framehwnd )
  276. {
  277. m_hPWnd = framehwnd;
  278. ::EnableWindow(framehwnd, FALSE);
  279. }
  280. }
  281. CDialog::OnInitDialog();
  282. CWnd* pwnd = GetDlgItem(IDC_LOG_FILE); //Raid #501886, yanggao, 12/03/2001
  283. if( pwnd )
  284. {
  285. pwnd->SendMessage(EM_LIMITTEXT, MAX_PATH, 0);
  286. }
  287. UpdateData(FALSE);
  288. if (m_strLogFile.IsEmpty()) {
  289. m_ctlOK.EnableWindow(FALSE);
  290. }
  291. m_strOriginalLogFile = m_strLogFile;
  292. return TRUE; // return TRUE unless you set the focus to a control
  293. // EXCEPTION: OCX Property Pages should return FALSE
  294. }
  295. void CPerformAnalysis::OnChangeLogFile()
  296. {
  297. UpdateData(TRUE);
  298. if (m_strLogFile.IsEmpty())
  299. m_ctlOK.EnableWindow(FALSE);
  300. else
  301. m_ctlOK.EnableWindow(TRUE);
  302. m_strError.Empty();
  303. }
  304. void CPerformAnalysis::OnCancel() {
  305. // CDialog::OnCancel();
  306. if( m_hPWnd ) //Raid #669945, yanggao, 8/9/2002
  307. {
  308. ::EnableWindow(m_hPWnd, TRUE);
  309. }
  310. m_strLogFile = m_strOriginalLogFile;
  311. DestroyWindow();
  312. }