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.

1108 lines
46 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. perfmon5.c
  5. Abstract:
  6. Program to adapt the command line Perfmon from NT4 and prior
  7. to the MMC & NT5 compatible format
  8. Author:
  9. Bob Watson (bobw) 11 may 99
  10. Revision History:
  11. --*/
  12. #define _OUTPUT_HTML 1
  13. //#define _DBG_MSG_PRINT 1
  14. #define _USE_MMC 1
  15. #define MAXSTR 512
  16. #include "perfmon5.h"
  17. // static & global variables
  18. #ifdef _USE_MMC
  19. static LPCWSTR szMmcExeCmd= (LPCWSTR)L"%windir%\\system32\\mmc.exe";
  20. static LPCWSTR szMmcExeArg= (LPCWSTR)L" %windir%\\system32\\perfmon.msc /s";
  21. #else
  22. static LPCWSTR szMmcExeCmd= (LPCWSTR)L"%windir%\\explorer.exe";
  23. static LPCWSTR szMmcExeArg= (LPCWSTR)L" ";
  24. #endif
  25. static LPCWSTR szMmcExeSetsArg= (LPCWSTR)L"/SYSMON%ws_SETTINGS \"%ws\"";
  26. static LPCWSTR szMmcExeSetsLogOpt= (LPCWSTR)L"LOG";
  27. static LPCWSTR szEmpty= (LPCWSTR)L"";
  28. //HTML Formatting definitions
  29. // these are not localized
  30. LPCWSTR szHtmlHeader = (LPCWSTR)L"\
  31. <HTML>\r\n\
  32. <HEAD>\r\n\
  33. <META NAME=\"GENERATOR\" Content=\"Microsoft System Monitor\">\r\n\
  34. <META HTTP-EQUIV=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\r\n\
  35. </HEAD><BODY bgcolor=\"#%6.6x\">\r\n";
  36. LPCWSTR szObjectHeader = (LPCWSTR)L"\
  37. <OBJECT ID=\"%s\" WIDTH=\"100%%\" HEIGHT=\"100%%\"\r\n\
  38. CLASSID=\"CLSID:C4D2D8E0-D1DD-11CE-940F-008029004347\">\r\n\
  39. <PARAM NAME=\"Version\" VALUE=\"196611\"\r\n";
  40. LPCWSTR szObjectFooter = (LPCWSTR)L"\
  41. </OBJECT>\r\n";
  42. LPCWSTR szHtmlFooter = (LPCWSTR)L"\
  43. </BODY>\r\n\
  44. </HTML>\r\n";
  45. LPCWSTR szHtmlDecimalParamFmt = (LPCWSTR)L" <PARAM NAME=\"%s\" VALUE=\"%d\">\r\n";
  46. LPCWSTR szHtmlStringParamFmt = (LPCWSTR)L" <PARAM NAME=\"%s\" VALUE=\"%s\">\r\n";
  47. LPCWSTR szHtmlWideStringParamFmt = (LPCWSTR)L" <PARAM NAME=\"%s\" VALUE=\"%ws\">\r\n";
  48. LPCWSTR szHtmlLineDecimalParamFmt = (LPCWSTR)L" <PARAM NAME=\"Counter%5.5d.%s\" VALUE=\"%d\">\r\n";
  49. LPCWSTR szHtmlLineRealParamFmt = (LPCWSTR)L" <PARAM NAME=\"Counter%5.5d.%s\" VALUE=\"%f\">\r\n";
  50. LPCWSTR szHtmlLineStringParamFmt = (LPCWSTR)L" <PARAM NAME=\"Counter%5.5d.%s\" VALUE=\"%s\">\r\n";
  51. LPCWSTR szSingleObjectName = (LPCWSTR)L"SystemMonitor1";
  52. LPCWSTR szSysmonControlIdFmt = (LPCWSTR)L"SysmonControl%d";
  53. // CODE STARTS HERE
  54. LPWSTR
  55. DiskStringRead (
  56. PDISKSTRING pDS
  57. )
  58. {
  59. LPWSTR szReturnString = NULL;
  60. if (pDS->dwLength == 0) {
  61. szReturnString = NULL;
  62. } else {
  63. szReturnString = HeapAlloc (GetProcessHeap(), 0, ((pDS->dwLength + 1) * sizeof (WCHAR)));
  64. if (szReturnString) {
  65. wcsncpy (szReturnString, (WCHAR *)((PBYTE) pDS + pDS->dwOffset),
  66. pDS->dwLength) ;
  67. szReturnString[pDS->dwLength] = 0;
  68. }
  69. }
  70. return (szReturnString) ;
  71. }
  72. static
  73. BOOL
  74. FileRead (HANDLE hFile,
  75. LPVOID lpMemory,
  76. DWORD nAmtToRead)
  77. { // FileRead
  78. BOOL bSuccess ;
  79. DWORD nAmtRead ;
  80. bSuccess = ReadFile (hFile, lpMemory, nAmtToRead, &nAmtRead, NULL) ;
  81. return (bSuccess && (nAmtRead == nAmtToRead)) ;
  82. } // FileRead
  83. BOOL
  84. ReadLogLine (
  85. HANDLE hFile,
  86. FILE *fOutFile,
  87. LPDWORD pdwLineNo,
  88. DWORD dwInFileType,
  89. PDISKLINE *ppDiskLine,
  90. DWORD *pSizeofDiskLine
  91. )
  92. /*
  93. Effect: Read in a line from the file hFile, at the current file
  94. position.
  95. Internals: The very first characters are a line signature, then a
  96. length integer. If the signature is correct, then allocate
  97. the length amount, and work with that.
  98. */
  99. {
  100. #ifdef _OUTPUT_HTML
  101. PDH_COUNTER_PATH_ELEMENTS_W pdhPathElem;
  102. WCHAR wszCounterPath[1024];
  103. PDH_STATUS pdhStatus;
  104. DWORD dwCounterPathSize = (sizeof(wszCounterPath)/sizeof(wszCounterPath[0]));
  105. #endif
  106. LOGENTRY LogEntry;
  107. UNREFERENCED_PARAMETER (dwInFileType);
  108. UNREFERENCED_PARAMETER (ppDiskLine);
  109. UNREFERENCED_PARAMETER (pSizeofDiskLine);
  110. //=============================//
  111. // read and compare signature //
  112. //=============================//
  113. if (!FileRead (hFile, &LogEntry, sizeof(LOGENTRY)-sizeof(LogEntry.pNextLogEntry)))
  114. return (FALSE) ;
  115. #ifdef _OUTPUT_HTML
  116. // expand log entry into counters: not this may not always work!
  117. if (lstrcmpW(LogEntry.szComputer, (LPCWSTR)L"....") != 0) {
  118. // then add the machine name
  119. pdhPathElem.szMachineName = LogEntry.szComputer;
  120. } else {
  121. pdhPathElem.szMachineName = NULL;
  122. }
  123. pdhPathElem.szObjectName = LogEntry.szObject;
  124. pdhPathElem.szInstanceName = (LPWSTR)L"*";
  125. pdhPathElem.szParentInstance = NULL;
  126. pdhPathElem.dwInstanceIndex = (DWORD)-1;
  127. pdhPathElem.szCounterName = (LPWSTR)L"*";
  128. pdhStatus = PdhMakeCounterPathW (
  129. &pdhPathElem,
  130. wszCounterPath,
  131. &dwCounterPathSize,
  132. 0);
  133. fwprintf (fOutFile, szHtmlLineStringParamFmt, *pdwLineNo, (LPCWSTR)L"Path", wszCounterPath);
  134. *pdwLineNo = *pdwLineNo + 1; // increment the line no
  135. #else
  136. fprintf (fOutFile, "\n Line[%3.3d].ObjectTitleIndex = %d", *pdwLineNo, LogEntry.ObjectTitleIndex);
  137. fprintf (fOutFile, "\n Line[%3.3d].szComputer = %ws", *pdwLineNo, LogEntry.szComputer);
  138. fprintf (fOutFile, "\n Line[%3.3d].szObject = %ws", *pdwLineNo, LogEntry.szObject);
  139. fprintf (fOutFile, "\n Line[%3.3d].bSaveCurrentName = %d", *pdwLineNo, LogEntry.bSaveCurrentName);
  140. *pdwLineNo = *pdwLineNo + 1; // increment the line no
  141. #endif
  142. return TRUE;
  143. }
  144. BOOL
  145. ReadLine (
  146. HANDLE hFile,
  147. FILE *fOutFile,
  148. LPDWORD pdwLineNo,
  149. DWORD dwInFileType,
  150. PDISKLINE *ppDiskLine,
  151. DWORD *pSizeofDiskLine
  152. )
  153. /*
  154. Effect: Read in a line from the file hFile, at the current file
  155. position.
  156. Internals: The very first characters are a line signature, then a
  157. length integer. If the signature is correct, then allocate
  158. the length amount, and work with that.
  159. */
  160. {
  161. PDISKLINE pDiskLine = NULL ;
  162. DWORD dwLineNo = *pdwLineNo;
  163. #ifdef _OUTPUT_HTML
  164. double dScaleFactor;
  165. PDH_STATUS pdhStatus;
  166. PDH_COUNTER_PATH_ELEMENTS_W pdhPathElem;
  167. WCHAR wszCounterPath[1024];
  168. DWORD dwCounterPathSize = (sizeof(wszCounterPath)/sizeof(wszCounterPath[0]));
  169. #else
  170. LPWSTR szTempString;
  171. #endif
  172. struct {
  173. DWORD dwSignature ;
  174. DWORD dwLength ;
  175. } LineHeader ;
  176. //=============================//
  177. // read and compare signature //
  178. //=============================//
  179. if (!FileRead (hFile, &LineHeader, sizeof (LineHeader)))
  180. return (FALSE) ;
  181. if (LineHeader.dwSignature != dwLineSignature ||
  182. LineHeader.dwLength == 0) {
  183. SetLastError (ERROR_BAD_FORMAT) ;
  184. return (FALSE) ;
  185. }
  186. //=============================//
  187. // read and allocate length //
  188. //=============================//
  189. // if (!FileRead (hFile, &dwLength, sizeof (dwLength)) || dwLength == 0)
  190. // return (NULL) ;
  191. // check if we need a bigger buffer,
  192. // normally, it should be the same except the first time...
  193. if (LineHeader.dwLength > *pSizeofDiskLine) {
  194. if (*ppDiskLine) {
  195. // free the previous buffer
  196. HeapFree (GetProcessHeap(), 0, *ppDiskLine);
  197. *pSizeofDiskLine = 0 ;
  198. }
  199. // re-allocate a new buffer
  200. *ppDiskLine = (PDISKLINE) HeapAlloc(GetProcessHeap(), 0, LineHeader.dwLength) ;
  201. if (!(*ppDiskLine)) {
  202. // no memory, should flag an error...
  203. return (FALSE) ;
  204. }
  205. *pSizeofDiskLine = LineHeader.dwLength ;
  206. }
  207. pDiskLine = *ppDiskLine ;
  208. //=============================//
  209. // copy diskline, alloc line //
  210. //=============================//
  211. if (!FileRead (hFile, pDiskLine, LineHeader.dwLength))
  212. return (FALSE) ;
  213. #ifdef _OUTPUT_HTML
  214. // HTML output requires 1 based indexes, not 0 based
  215. dwLineNo += 1;
  216. // make counter path string out of components
  217. pdhPathElem.szMachineName = DiskStringRead (&(pDiskLine->dsSystemName));
  218. if ( pdhPathElem.szMachineName != NULL
  219. && lstrcmpW (pdhPathElem.szMachineName, (LPCWSTR)L"....") == 0) {
  220. // then use local machine
  221. HeapFree (GetProcessHeap(), 0, pdhPathElem.szMachineName);
  222. pdhPathElem.szMachineName = NULL;
  223. }
  224. pdhPathElem.szObjectName = DiskStringRead (&(pDiskLine->dsObjectName));
  225. if (pDiskLine->dwUniqueID != PERF_NO_UNIQUE_ID) {
  226. pdhPathElem.szInstanceName = HeapAlloc (GetProcessHeap(), 0, 64);
  227. if (pdhPathElem.szInstanceName != NULL) {
  228. _ltow (pDiskLine->dwUniqueID, pdhPathElem.szInstanceName, 10);
  229. }
  230. } else {
  231. pdhPathElem.szInstanceName = DiskStringRead (&(pDiskLine->dsInstanceName));
  232. }
  233. pdhPathElem.szParentInstance = DiskStringRead (&(pDiskLine->dsPINName));
  234. pdhPathElem.dwInstanceIndex = (DWORD)-1;
  235. pdhPathElem.szCounterName = DiskStringRead (&(pDiskLine->dsCounterName));
  236. pdhStatus = PdhMakeCounterPathW (&pdhPathElem,
  237. wszCounterPath, &dwCounterPathSize, 0);
  238. if (pdhStatus == ERROR_SUCCESS) {
  239. fwprintf (fOutFile, szHtmlLineStringParamFmt, dwLineNo, (LPCWSTR)L"Path", wszCounterPath);
  240. if (dwInFileType == PMC_FILE) {
  241. //fwprintf (fOutFile, szHtmlLineDecimalParamFmt, dwLineNo, (LPCWSTR)L"ScaleFactor", pDiskLine->iScaleIndex);
  242. dScaleFactor = log10 (pDiskLine->eScale);
  243. dScaleFactor += 0.5;
  244. dScaleFactor = floor (dScaleFactor);
  245. fwprintf (fOutFile, szHtmlLineDecimalParamFmt, dwLineNo, (LPCWSTR)L"ScaleFactor", (LONG)dScaleFactor);
  246. fwprintf (fOutFile, szHtmlLineDecimalParamFmt, dwLineNo, (LPCWSTR)L"Color", *(DWORD *)&pDiskLine->Visual.crColor);
  247. fwprintf (fOutFile, szHtmlLineDecimalParamFmt, dwLineNo, (LPCWSTR)L"LineStyle", pDiskLine->Visual.iStyle );
  248. fwprintf (fOutFile, szHtmlLineDecimalParamFmt, dwLineNo, (LPCWSTR)L"Width", pDiskLine->Visual.iWidth);
  249. }
  250. if (dwInFileType == PMA_FILE) {
  251. fwprintf (fOutFile, szHtmlLineDecimalParamFmt, dwLineNo, (LPCWSTR)L"AlertOverUnder", pDiskLine->bAlertOver);
  252. fwprintf (fOutFile, szHtmlLineRealParamFmt, dwLineNo, (LPCWSTR)L"AlertThreshold", pDiskLine->eAlertValue);
  253. fwprintf (fOutFile, szHtmlLineDecimalParamFmt, dwLineNo, (LPCWSTR)L"Color", *(DWORD *)&pDiskLine->Visual.crColor);
  254. }
  255. }
  256. if (pdhPathElem.szMachineName) HeapFree (GetProcessHeap(), 0, pdhPathElem.szMachineName);
  257. if (pdhPathElem.szObjectName) HeapFree (GetProcessHeap(), 0, pdhPathElem.szObjectName);
  258. if (pdhPathElem.szInstanceName) HeapFree (GetProcessHeap(), 0, pdhPathElem.szInstanceName);
  259. if (pdhPathElem.szParentInstance) HeapFree (GetProcessHeap(), 0, pdhPathElem.szParentInstance);
  260. if (pdhPathElem.szCounterName) HeapFree (GetProcessHeap(), 0, pdhPathElem.szCounterName);
  261. #else
  262. UNREFERENCED_PARAMETER (dwInFileType);
  263. fwprintf (fOutFile, (LPCWSTR)L"\n Line[%3.3d].iLineType = %d", dwLineNo, pDiskLine->iLineType);
  264. szTempString = DiskStringRead (&(pDiskLine->dsSystemName));
  265. fwprintf (fOutFile, (LPCWSTR)L"\n Line[%3.3d].dsSystmeName = %ws", dwLineNo, (szTempString ? szTempString : (LPCWSTR)L""));
  266. if (szTempString != NULL) HeapFree (GetProcessHeap(), 0, szTempString);
  267. szTempString = DiskStringRead (&(pDiskLine->dsObjectName));
  268. fwprintf (fOutFile, (LPCWSTR)L"\n Line[%3.3d].dsObjectName = %ws", dwLineNo, (szTempString ? szTempString : (LPCWSTR)L""));
  269. if (szTempString != NULL) HeapFree (GetProcessHeap(), 0, szTempString);
  270. szTempString = DiskStringRead (&(pDiskLine->dsCounterName));
  271. fwprintf (fOutFile, (LPCWSTR)L"\n Line[%3.3d].dsCounterName = %ws", dwLineNo, (szTempString ? szTempString : (LPCWSTR)L""));
  272. if (szTempString != NULL) HeapFree (GetProcessHeap(), 0, szTempString);
  273. szTempString = DiskStringRead (&(pDiskLine->dsInstanceName));
  274. fwprintf (fOutFile, (LPCWSTR)L"\n Line[%3.3d].dsInstanceName = %ws", dwLineNo, (szTempString ? szTempString : (LPCWSTR)L""));
  275. if (szTempString != NULL) HeapFree (GetProcessHeap(), 0, szTempString);
  276. szTempString = DiskStringRead (&(pDiskLine->dsPINName));
  277. fwprintf (fOutFile, (LPCWSTR)L"\n Line[%3.3d].dsPINName = %ws", dwLineNo, (szTempString ? szTempString : (LPCWSTR)L""));
  278. if (szTempString != NULL) HeapFree (GetProcessHeap(), 0, szTempString);
  279. szTempString = DiskStringRead (&(pDiskLine->dsParentObjName));
  280. fwprintf (fOutFile, (LPCWSTR)L"\n Line[%3.3d].dsParentObjName = %ws", dwLineNo, (szTempString ? szTempString : (LPCWSTR)L""));
  281. if (szTempString != NULL) HeapFree (GetProcessHeap(), 0, szTempString);
  282. fwprintf (fOutFile, (LPCWSTR)L"\n Line[%3.3d].dwUniqueID = 0x%8.8x", dwLineNo, pDiskLine->dwUniqueID);
  283. fwprintf (fOutFile, (LPCWSTR)L"\n Line[%3.3d].iScaleIndex = %d", dwLineNo, pDiskLine->iScaleIndex);
  284. fwprintf (fOutFile, (LPCWSTR)L"\n Line[%3.3d].eScale = %e", dwLineNo, pDiskLine->eScale);
  285. fwprintf (fOutFile, (LPCWSTR)L"\n Line[%3.3d].bAlertOver = %d", dwLineNo, pDiskLine->bAlertOver);
  286. fwprintf (fOutFile, (LPCWSTR)L"\n Line[%3.3d].eAlertValue = %e", dwLineNo, pDiskLine->eAlertValue);
  287. szTempString = DiskStringRead (&(pDiskLine->dsAlertProgram));
  288. fwprintf (fOutFile, (LPCWSTR)L"\n Line[%3.3d].dsAlertProgram = %ws", dwLineNo, (szTempString ? szTempString : (LPCWSTR)L""));
  289. if (szTempString != NULL) HeapFree (GetProcessHeap(), 0, szTempString);
  290. fwprintf (fOutFile, (LPCWSTR)L"\n Line[%3.3d].bEveryTime = %d", dwLineNo, pDiskLine->bEveryTime);
  291. fwprintf (fOutFile, (LPCWSTR)L"\n Line[%3.3d].LV.crColor = 0x%8.8x", dwLineNo, *(DWORD *)&pDiskLine->Visual.crColor) ;
  292. fwprintf (fOutFile, (LPCWSTR)L"\n Line[%3.3d].LV.iColorIndex = %d", dwLineNo, pDiskLine->Visual.iColorIndex );
  293. fwprintf (fOutFile, (LPCWSTR)L"\n Line[%3.3d].LV.iStyle = %d", dwLineNo, pDiskLine->Visual.iStyle );
  294. fwprintf (fOutFile, (LPCWSTR)L"\n Line[%3.3d].LV.iStyleIndex = %d", dwLineNo, pDiskLine->Visual.iStyleIndex );
  295. fwprintf (fOutFile, (LPCWSTR)L"\n Line[%3.3d].LV.iWidth = %d", dwLineNo, pDiskLine->Visual.iWidth );
  296. fwprintf (fOutFile, (LPCWSTR)L"\n Line[%3.3d].LV.iWidthIndex = %d", dwLineNo, pDiskLine->Visual.iWidthIndex );
  297. #endif
  298. return TRUE;
  299. }
  300. void
  301. ReadLines (
  302. HANDLE hFile,
  303. FILE *fOutFile,
  304. DWORD dwFileType,
  305. DWORD dwNumLines
  306. )
  307. {
  308. DWORD i ;
  309. PDISKLINE pDiskLine = NULL ;
  310. DWORD SizeofDiskLine = 0 ; // bytes in pDiskLine
  311. DWORD dwLogLineNo;
  312. pDiskLine = HeapAlloc (GetProcessHeap(),0, MAX_PATH) ;
  313. if (!pDiskLine) {
  314. return ;
  315. }
  316. SizeofDiskLine = MAX_PATH;
  317. for (i = 0, dwLogLineNo = 1;
  318. i < dwNumLines ;
  319. i++) {
  320. if (dwFileType == PML_FILE) {
  321. ReadLogLine (hFile, fOutFile, &dwLogLineNo, dwFileType, &pDiskLine, &SizeofDiskLine) ;
  322. } else {
  323. ReadLine (hFile, fOutFile, &i, dwFileType, &pDiskLine, &SizeofDiskLine) ;
  324. }
  325. }
  326. if (pDiskLine) {
  327. HeapFree (GetProcessHeap(), 0, pDiskLine);
  328. }
  329. }
  330. BOOL
  331. OpenAlert (
  332. LPCWSTR szInFileName,
  333. HANDLE hFile,
  334. FILE * fOutFile,
  335. LPCWSTR szObjectName
  336. )
  337. { // OpenAlert
  338. DISKALERT DiskAlert ;
  339. BOOL bSuccess = TRUE ;
  340. DWORD dwLocalActionFlags = 0;
  341. #ifdef _OUTPUT_HTML
  342. WCHAR szComment[MAX_PATH];
  343. WCHAR path[_MAX_PATH];
  344. WCHAR drive[_MAX_DRIVE];
  345. WCHAR dir[_MAX_DIR];
  346. WCHAR fname[_MAX_FNAME];
  347. WCHAR ext[_MAX_EXT];
  348. #endif
  349. // read the next section if valid
  350. bSuccess = FileRead (hFile, &DiskAlert, sizeof (DISKALERT));
  351. if (bSuccess) {
  352. #ifdef _OUTPUT_HTML
  353. if (DiskAlert.dwNumLines > 0) {
  354. fwprintf (fOutFile, szObjectHeader, szObjectName);
  355. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"ManualUpdate", DiskAlert.bManualRefresh);
  356. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"ShowToolbar", DiskAlert.perfmonOptions.bMenubar);
  357. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"UpdateInterval", (int)DiskAlert.dwIntervalSecs / 1000);
  358. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"SampleIntervalUnitType", 1); // Seconds
  359. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"SampleIntervalValue", (int)DiskAlert.dwIntervalSecs / 1000);
  360. fwprintf (fOutFile, szHtmlStringParamFmt, (LPCWSTR)L"CommandFile", "");
  361. fwprintf (fOutFile, szHtmlStringParamFmt, (LPCWSTR)L"UserText", "");
  362. fwprintf (fOutFile, szHtmlStringParamFmt, (LPCWSTR)L"PerfLogName", "");
  363. dwLocalActionFlags |= 1; // perfmon normally logs to the UI, but we don't have one
  364. // so log to the event log by default
  365. if (DiskAlert.bNetworkAlert) {
  366. dwLocalActionFlags |= 2;
  367. }
  368. // perfmon does 1 net name per alert. we do 1 per file so leave it blank
  369. fwprintf (fOutFile, szHtmlStringParamFmt, (LPCWSTR)L"NetworkName", "");
  370. dwLocalActionFlags |= 0x00003F00; // command line flags
  371. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"ActionFlags",dwLocalActionFlags);
  372. // set the defaults to duplicate a perfmon log
  373. _wfullpath (path, szInFileName, _MAX_PATH);
  374. _wsplitpath (path, drive, dir, fname, ext);
  375. fwprintf (fOutFile, szHtmlWideStringParamFmt, (LPCWSTR)L"AlertName", fname);
  376. swprintf (szComment, (LPCWSTR)L"Created from Perfmon Settings File \"%ws%ws\"", fname, ext);
  377. fwprintf (fOutFile, szHtmlStringParamFmt, (LPCWSTR)L"Comment", szComment);
  378. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"LogType", 2); // Sysmon alert
  379. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"LogFileMaxSize", -1); // no size limit
  380. fwprintf (fOutFile, szHtmlWideStringParamFmt, (LPCWSTR)L"LogFileBaseName", fname);
  381. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"LogFileSerialNumber", 1);
  382. swprintf (szComment, (LPCWSTR)L"%ws%ws", drive, dir);
  383. fwprintf (fOutFile, szHtmlWideStringParamFmt, (LPCWSTR)L"LogFileFolder", szComment);
  384. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"LogFileAutoFormat", 0); //no auto name
  385. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"LogFileType", 2); // PDH binary counter log
  386. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"StartMode", 0); // manual start
  387. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"StopMode", 0); // manual stop
  388. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"RestartMode", 0); // no restart
  389. fwprintf (fOutFile, szHtmlStringParamFmt, (LPCWSTR)L"EOFCommandFile", "");
  390. // Get ready to list the counters
  391. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"CounterCount", DiskAlert.dwNumLines);
  392. }
  393. #else // output text
  394. UNREFERENCED_PARAMETER (szInFileName);
  395. UNREFERENCED_PARAMETER (szOutFileName);
  396. // dump settings file header
  397. fOutFile = stdout;
  398. fprintf (fOutFile, "\nDA.dwNumLines = %d", DiskAlert.dwNumLines);
  399. fprintf (fOutFile, "\nDA.dwIntervalSecs = %d", DiskAlert.dwIntervalSecs);
  400. fprintf (fOutFile, "\nDA.bManualRefresh = %d", DiskAlert.bManualRefresh);
  401. fprintf (fOutFile, "\nDA.bSwitchToAlert = %d", DiskAlert.bSwitchToAlert);
  402. fprintf (fOutFile, "\nDA.bNetworkAlert = %d", DiskAlert.bNetworkAlert);
  403. fprintf (fOutFile, "\nDA.MessageName = %16.16ws", DiskAlert.MessageName);
  404. fprintf (fOutFile, "\nDA.MiscOptions = 0x%8.8x", DiskAlert.MiscOptions);
  405. fprintf (fOutFile, "\nDA.LV.crColor = 0x%8.8x", *(DWORD *)&DiskAlert.Visual.crColor) ;
  406. fprintf (fOutFile, "\nDA.LV.iColorIndex = %d", DiskAlert.Visual.iColorIndex );
  407. fprintf (fOutFile, "\nDA.LV.iStyle = %d", DiskAlert.Visual.iStyle );
  408. fprintf (fOutFile, "\nDA.LV.iStyleIndex = %d", DiskAlert.Visual.iStyleIndex );
  409. fprintf (fOutFile, "\nDA.LV.iWidth = %d", DiskAlert.Visual.iWidth );
  410. fprintf (fOutFile, "\nDA.LV.iWidthIndex = %d", DiskAlert.Visual.iWidthIndex );
  411. fprintf (fOutFile, "\nDA.PO.bMenubar = %d", DiskAlert.perfmonOptions.bMenubar );
  412. fprintf (fOutFile, "\nDA.PO.bToolbar = %d", DiskAlert.perfmonOptions.bToolbar );
  413. fprintf (fOutFile, "\nDA.PO.bStatusbar = %d", DiskAlert.perfmonOptions.bStatusbar );
  414. fprintf (fOutFile, "\nDA.PO.bAlwaysOnTop = %d", DiskAlert.perfmonOptions.bAlwaysOnTop );
  415. #endif
  416. }
  417. if ((bSuccess) && (DiskAlert.dwNumLines > 0)) {
  418. ReadLines (hFile, fOutFile, PMA_FILE, DiskAlert.dwNumLines);
  419. #ifdef _OUTPUT_HTML
  420. fwprintf (fOutFile, szObjectFooter);
  421. #endif
  422. }
  423. return (bSuccess) ;
  424. } // OpenAlert
  425. BOOL
  426. OpenLog (
  427. LPCWSTR szInFileName,
  428. HANDLE hFile,
  429. FILE * fOutFile,
  430. LPCWSTR szObjectName
  431. )
  432. { // OpenLog
  433. DISKLOG DiskLog ;
  434. BOOL bSuccess = TRUE ;
  435. #ifdef _OUTPUT_HTML
  436. WCHAR szComment[MAX_PATH];
  437. WCHAR path[_MAX_PATH];
  438. WCHAR drive[_MAX_DRIVE];
  439. WCHAR dir[_MAX_DIR];
  440. WCHAR fname[_MAX_FNAME];
  441. WCHAR ext[_MAX_EXT];
  442. #endif
  443. // read the next section if valid
  444. bSuccess = FileRead (hFile, &DiskLog, sizeof (DISKLOG));
  445. if (bSuccess) {
  446. #ifdef _OUTPUT_HTML
  447. if (DiskLog.dwNumLines > 0) {
  448. fwprintf (fOutFile, szObjectHeader, szObjectName);
  449. // dump settings file header
  450. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"ManualUpdate", DiskLog.bManualRefresh);
  451. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"UpdateInterval", (int)DiskLog.dwIntervalSecs / 1000);
  452. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"SampleIntervalUnitType", 1); // Seconds
  453. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"SampleIntervalValue", (int)DiskLog.dwIntervalSecs / 1000);
  454. fwprintf (fOutFile, szHtmlWideStringParamFmt, (LPCWSTR)L"LogFileName", DiskLog.LogFileName);
  455. // set the defaults to duplicate a perfmon log
  456. _wfullpath (path, szInFileName, _MAX_PATH);
  457. _wsplitpath (path, drive, dir, fname, ext);
  458. fwprintf (fOutFile, szHtmlWideStringParamFmt, (LPCWSTR)L"LogName", fname);
  459. swprintf (szComment, (LPCWSTR)L"Created from Perfmon Settings File \"%ws%ws\"", fname, ext);
  460. fwprintf (fOutFile, szHtmlStringParamFmt, (LPCWSTR)L"Comment", szComment);
  461. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"LogType", 0); // PDH counter log
  462. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"LogFileMaxSize", -1); // no size limit
  463. fwprintf (fOutFile, szHtmlWideStringParamFmt, (LPCWSTR)L"LogFileBaseName", fname);
  464. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"LogFileSerialNumber", 1);
  465. swprintf (szComment, (LPCWSTR)L"%ws%ws", drive, dir);
  466. fwprintf (fOutFile, szHtmlWideStringParamFmt, (LPCWSTR)L"LogFileFolder", szComment);
  467. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"LogFileAutoFormat", 0); //no auto name
  468. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"LogFileType", 2); // PDH binary counter log
  469. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"StartMode", 0); // manual start
  470. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"StopMode", 0); // manual stop
  471. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"RestartMode", 0); // no restart
  472. fwprintf (fOutFile, szHtmlStringParamFmt, (LPCWSTR)L"EOFCommandFile", "");
  473. // Get ready to list the counters
  474. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"CounterCount", DiskLog.dwNumLines);
  475. }
  476. #else // output text
  477. UNREFERENCED_PARAMETER (szInFileName);
  478. // dump settings file header
  479. fOutFile = stdout;
  480. fprintf (fOutFile, "\nDL.dwNumLines = %d", DiskLog.dwNumLines);
  481. fprintf (fOutFile, "\nDL.bManualRefresh = %d", DiskLog.bManualRefresh);
  482. fprintf (fOutFile, "\nDL.dwIntervalSecs = %d", DiskLog.dwIntervalSecs);
  483. fprintf (fOutFile, "\nDL.LogFileName = %ws", DiskLog.LogFileName);
  484. fprintf (fOutFile, "\nDC.PO.bMenubar = %d", DiskLog.perfmonOptions.bMenubar );
  485. fprintf (fOutFile, "\nDC.PO.bToolbar = %d", DiskLog.perfmonOptions.bToolbar );
  486. fprintf (fOutFile, "\nDC.PO.bStatusbar = %d", DiskLog.perfmonOptions.bStatusbar );
  487. fprintf (fOutFile, "\nDC.PO.bAlwaysOnTop = %d", DiskLog.perfmonOptions.bAlwaysOnTop );
  488. #endif
  489. }
  490. if ((bSuccess) && (DiskLog.dwNumLines > 0)) {
  491. //the log settings file requires a special function to read the lines from
  492. ReadLines (hFile, fOutFile, PML_FILE, DiskLog.dwNumLines);
  493. #ifdef _OUTPUT_HTML
  494. fwprintf (fOutFile, szObjectFooter);
  495. #endif
  496. }
  497. return (bSuccess) ;
  498. } // OpenLog
  499. BOOL
  500. OpenReport (
  501. HANDLE hFile,
  502. FILE * fOutFile,
  503. LPCWSTR szObjectName
  504. )
  505. { // OpenReport
  506. DISKREPORT DiskReport ;
  507. BOOL bSuccess = TRUE ;
  508. DWORD dwColor;
  509. // read the next section if valid
  510. bSuccess = FileRead (hFile, &DiskReport, sizeof (DISKREPORT));
  511. if (bSuccess) {
  512. #ifdef _OUTPUT_HTML
  513. if (DiskReport.dwNumLines > 0) {
  514. // dump settings file header
  515. fwprintf (fOutFile, szObjectHeader, szObjectName);
  516. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"ManualUpdate", DiskReport.bManualRefresh);
  517. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"ShowToolbar", DiskReport.perfmonOptions.bToolbar);
  518. // report intervals are reported in mS
  519. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"UpdateInterval", (int)DiskReport.dwIntervalSecs/1000);
  520. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"DisplayType", 3); // report type
  521. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"ReportValueType", 0); // default display value
  522. // derive the following from the current windows environment
  523. dwColor = GetSysColor (COLOR_WINDOW);
  524. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"BackColor", dwColor);
  525. dwColor = GetSysColor (COLOR_3DFACE);
  526. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"BackColorCtl", dwColor);
  527. dwColor = GetSysColor(COLOR_BTNTEXT);
  528. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"ForeColor", dwColor);
  529. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"GridColor", dwColor);
  530. dwColor = 0x00FF0000; // red
  531. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"TimeBarColor", dwColor);
  532. // other perfmon settings that are assumed by perfmon but
  533. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"Appearance", 1); // 3d appearance
  534. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"BorderStyle", 0); // no border
  535. // Get ready to list the counters
  536. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"CounterCount", DiskReport.dwNumLines);
  537. } // else no counters to dump
  538. #else // output text
  539. // dump settings file header
  540. fprintf (fOutFile, "\nDR.dwNumLines = %d", DiskReport.dwNumLines);
  541. fprintf (fOutFile, "\nDR.bManualRefresh = %d", DiskReport.bManualRefresh);
  542. fprintf (fOutFile, "\nDC.dwIntervalSecs = %d", DiskReport.dwIntervalSecs);
  543. fprintf (fOutFile, "\nDR.LV.crColor = 0x%8.8x", *(DWORD *)&DiskReport.Visual.crColor) ;
  544. fprintf (fOutFile, "\nDR.LV.iColorIndex = %d", DiskReport.Visual.iColorIndex );
  545. fprintf (fOutFile, "\nDR.LV.iStyle = %d", DiskReport.Visual.iStyle );
  546. fprintf (fOutFile, "\nDR.LV.iStyleIndex = %d", DiskReport.Visual.iStyleIndex );
  547. fprintf (fOutFile, "\nDR.LV.iWidth = %d", DiskReport.Visual.iWidth );
  548. fprintf (fOutFile, "\nDR.LV.iWidthIndex = %d", DiskReport.Visual.iWidthIndex );
  549. fprintf (fOutFile, "\nDC.PO.bMenubar = %d", DiskReport.perfmonOptions.bMenubar );
  550. fprintf (fOutFile, "\nDC.PO.bToolbar = %d", DiskReport.perfmonOptions.bToolbar );
  551. fprintf (fOutFile, "\nDC.PO.bStatusbar = %d", DiskReport.perfmonOptions.bStatusbar );
  552. fprintf (fOutFile, "\nDC.PO.bAlwaysOnTop = %d", DiskReport.perfmonOptions.bAlwaysOnTop );
  553. #endif
  554. }
  555. if ((bSuccess) && (DiskReport.dwNumLines > 0)) {
  556. ReadLines (hFile, fOutFile, PMR_FILE, DiskReport.dwNumLines);
  557. #ifdef _OUTPUT_HTML
  558. fwprintf (fOutFile, szObjectFooter);
  559. #endif
  560. }
  561. return (bSuccess) ;
  562. } // OpenReport
  563. BOOL
  564. OpenChart (
  565. HANDLE hFile,
  566. FILE * fOutFile,
  567. LPCWSTR szObjectName
  568. )
  569. { // OpenChart
  570. DISKCHART DiskChart ;
  571. BOOL bSuccess = TRUE ;
  572. DWORD dwColor;
  573. // read the next section if valid
  574. bSuccess = FileRead (hFile, &DiskChart, sizeof (DISKCHART));
  575. if (bSuccess) {
  576. #ifdef _OUTPUT_HTML
  577. if (DiskChart.dwNumLines > 0) {
  578. // dump settings file header
  579. fwprintf (fOutFile, szObjectHeader, szObjectName);
  580. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"ManualUpdate", DiskChart.bManualRefresh);
  581. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"ShowLegend", DiskChart.gOptions.bLegendChecked);
  582. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"ShowScaleLabels", DiskChart.gOptions.bLabelsChecked);
  583. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"ShowVerticalGrid", DiskChart.gOptions.bVertGridChecked);
  584. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"ShowHorizontalGrid", DiskChart.gOptions.bHorzGridChecked);
  585. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"ShowToolbar", DiskChart.gOptions.bMenuChecked);
  586. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"MaximumScale", DiskChart.gOptions.iVertMax);
  587. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"UpdateInterval", (int)DiskChart.gOptions.eTimeInterval);
  588. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"DisplayType", (DiskChart.gOptions.iGraphOrHistogram == BAR_GRAPH ? 2 : 1));
  589. // derive the following from the current windows environment
  590. dwColor = GetSysColor (COLOR_3DFACE);
  591. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"BackColor", dwColor);
  592. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"BackColorCtl", dwColor);
  593. dwColor = GetSysColor(COLOR_BTNTEXT);
  594. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"ForeColor", dwColor);
  595. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"GridColor", dwColor);
  596. dwColor = 0x00FF0000; // red
  597. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"TimeBarColor", dwColor);
  598. // other perfmon settings that are assumed by perfmon but
  599. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"Appearance", 1); // 3d appearance
  600. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"BorderStyle", 0); // no border
  601. // Get ready to list the counters
  602. fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR)L"CounterCount", DiskChart.dwNumLines);
  603. } // else no counters to display
  604. #else // output text
  605. // dump settings file header
  606. fprintf (fOutFile, "\nDC.dwNumLines = %d", DiskChart.dwNumLines);
  607. fprintf (fOutFile, "\nDC.gMaxValues = %d", DiskChart.gMaxValues);
  608. fprintf (fOutFile, "\nDC.bManualRefresh = %d", DiskChart.bManualRefresh);
  609. fprintf (fOutFile, "\nDC.LV.crColor = 0x%8.8x", *(DWORD *)&DiskChart.Visual.crColor) ;
  610. fprintf (fOutFile, "\nDC.LV.iColorIndex = %d", DiskChart.Visual.iColorIndex );
  611. fprintf (fOutFile, "\nDC.LV.iStyle = %d", DiskChart.Visual.iStyle );
  612. fprintf (fOutFile, "\nDC.LV.iStyleIndex = %d", DiskChart.Visual.iStyleIndex );
  613. fprintf (fOutFile, "\nDC.LV.iWidth = %d", DiskChart.Visual.iWidth );
  614. fprintf (fOutFile, "\nDC.LV.iWidthIndex = %d", DiskChart.Visual.iWidthIndex );
  615. fprintf (fOutFile, "\nDC.GO.bLegendChecked = %d", DiskChart.gOptions.bLegendChecked );
  616. fprintf (fOutFile, "\nDC.GO.bMenuChecked = %d", DiskChart.gOptions.bMenuChecked );
  617. fprintf (fOutFile, "\nDC.GO.bLabelsChecked = %d", DiskChart.gOptions.bLabelsChecked );
  618. fprintf (fOutFile, "\nDC.GO.bVertGridChecked = %d", DiskChart.gOptions.bVertGridChecked );
  619. fprintf (fOutFile, "\nDC.GO.bHorzGridChecked = %d", DiskChart.gOptions.bHorzGridChecked );
  620. fprintf (fOutFile, "\nDC.GO.bStatusBarChecked = %d", DiskChart.gOptions.bStatusBarChecked );
  621. fprintf (fOutFile, "\nDC.GO.iVertMax = %d", DiskChart.gOptions.iVertMax );
  622. fprintf (fOutFile, "\nDC.GO.eTimeInterval = %e", DiskChart.gOptions.eTimeInterval );
  623. fprintf (fOutFile, "\nDC.GO.iGraphOrHistogram = %d", DiskChart.gOptions.iGraphOrHistogram );
  624. fprintf (fOutFile, "\nDC.GO.GraphVGrid = %d", DiskChart.gOptions.GraphVGrid );
  625. fprintf (fOutFile, "\nDC.GO.GraphHGrid = %d", DiskChart.gOptions.GraphHGrid );
  626. fprintf (fOutFile, "\nDC.GO.HistVGrid = %d", DiskChart.gOptions.HistVGrid );
  627. fprintf (fOutFile, "\nDC.GO.HistHGrid = %d", DiskChart.gOptions.HistHGrid );
  628. fprintf (fOutFile, "\nDC.PO.bMenubar = %d", DiskChart.perfmonOptions.bMenubar );
  629. fprintf (fOutFile, "\nDC.PO.bToolbar = %d", DiskChart.perfmonOptions.bToolbar );
  630. fprintf (fOutFile, "\nDC.PO.bStatusbar = %d", DiskChart.perfmonOptions.bStatusbar );
  631. fprintf (fOutFile, "\nDC.PO.bAlwaysOnTop = %d", DiskChart.perfmonOptions.bAlwaysOnTop );
  632. #endif
  633. }
  634. if ((bSuccess) && (DiskChart.dwNumLines > 0)) {
  635. ReadLines (hFile, fOutFile, PMC_FILE, DiskChart.dwNumLines);
  636. #ifdef _OUTPUT_HTML
  637. fwprintf (fOutFile, szObjectFooter);
  638. #endif
  639. }
  640. return (bSuccess) ;
  641. } // OpenChart
  642. static
  643. BOOL
  644. OpenWorkspace (
  645. LPCWSTR szPerfmonFileName,
  646. HANDLE hInFile,
  647. FILE * fOutFile)
  648. {
  649. DISKWORKSPACE DiskWorkspace ;
  650. WCHAR szObjectName[MAX_PATH];
  651. DWORD dwObjectId = 1;
  652. if (!FileRead (hInFile, &DiskWorkspace, sizeof(DiskWorkspace))) {
  653. goto Exit0 ;
  654. }
  655. if (DiskWorkspace.ChartOffset == 0 &&
  656. DiskWorkspace.AlertOffset == 0 &&
  657. DiskWorkspace.LogOffset == 0 &&
  658. DiskWorkspace.ReportOffset == 0) {
  659. // no entries to process
  660. goto Exit0 ;
  661. }
  662. if (DiskWorkspace.ChartOffset) {
  663. if (FileSeekBegin(hInFile, DiskWorkspace.ChartOffset) == 0xFFFFFFFF) {
  664. goto Exit0 ;
  665. }
  666. swprintf (szObjectName, szSysmonControlIdFmt, dwObjectId++);
  667. // process chart entry
  668. if (!OpenChart (hInFile, fOutFile, szObjectName)) {
  669. goto Exit0 ;
  670. }
  671. }
  672. if (DiskWorkspace.AlertOffset) {
  673. if (FileSeekBegin(hInFile, DiskWorkspace.AlertOffset) == 0xffffffff) {
  674. goto Exit0 ;
  675. }
  676. swprintf (szObjectName, szSysmonControlIdFmt, dwObjectId++);
  677. if (!OpenAlert (szPerfmonFileName, hInFile, fOutFile, szObjectName)) {
  678. goto Exit0 ;
  679. }
  680. }
  681. if (DiskWorkspace.LogOffset) {
  682. if (FileSeekBegin(hInFile, DiskWorkspace.LogOffset) == 0xffffffff) {
  683. goto Exit0 ;
  684. }
  685. swprintf (szObjectName, szSysmonControlIdFmt, dwObjectId++);
  686. if (!OpenLog (szPerfmonFileName, hInFile, fOutFile, szObjectName)) {
  687. goto Exit0 ;
  688. }
  689. }
  690. if (DiskWorkspace.ReportOffset) {
  691. if (FileSeekBegin(hInFile, DiskWorkspace.ReportOffset) == 0xffffffff) {
  692. goto Exit0 ;
  693. }
  694. swprintf (szObjectName, szSysmonControlIdFmt, dwObjectId++);
  695. if (!OpenReport (hInFile, fOutFile, szObjectName)) {
  696. goto Exit0 ;
  697. }
  698. }
  699. return (TRUE) ;
  700. Exit0:
  701. return (FALSE) ;
  702. } // OpenWorkspace
  703. static
  704. BOOL
  705. ConvertPerfmonFile (
  706. IN LPCWSTR szPerfmonFileName,
  707. IN LPCWSTR szSysmonFileName,
  708. IN LPDWORD pdwFileType
  709. )
  710. {
  711. HANDLE hInFile = INVALID_HANDLE_VALUE;
  712. PERFFILEHEADER pfHeader;
  713. BOOL bSuccess = FALSE;
  714. FILE * fOutFile = NULL;
  715. #ifdef _OUTPUT_HTML
  716. DWORD dwColor;
  717. #endif
  718. // open input file as read only
  719. hInFile = CreateFileW (
  720. szPerfmonFileName, // filename
  721. GENERIC_READ, // read access
  722. 0, // no sharing
  723. NULL, // default security
  724. OPEN_EXISTING, // only open existing files
  725. FILE_ATTRIBUTE_NORMAL, // normal attributes
  726. NULL); // no template file
  727. if (hInFile != INVALID_HANDLE_VALUE) {
  728. bSuccess = FileRead (hInFile, &pfHeader, sizeof (PERFFILEHEADER));
  729. if (bSuccess) {
  730. #ifdef _OUTPUT_HTML
  731. fOutFile = _wfopen (szSysmonFileName, (LPCWSTR)L"w+t");
  732. #else
  733. fOutFile = stdout;
  734. #endif
  735. if (fOutFile != NULL) {
  736. dwColor = GetSysColor (COLOR_3DFACE);
  737. fwprintf (fOutFile, szHtmlHeader, (dwColor & 0x00FFFFFF));
  738. if (lstrcmpW(pfHeader.szSignature, szPerfChartSignature) == 0) {
  739. #ifdef _DBG_MSG_PRINT
  740. fprintf (stderr, "\nConverting Chart Settings file \"%ws\" to \n \"%ws\"",
  741. szPerfmonFileName,
  742. szSysmonFileName);
  743. #endif
  744. bSuccess = OpenChart (hInFile, fOutFile, szSingleObjectName);
  745. *pdwFileType = PMC_FILE;
  746. } else if (lstrcmpW(pfHeader.szSignature, szPerfAlertSignature) == 0) {
  747. #ifdef _DBG_MSG_PRINT
  748. fprintf (stderr, "\nConverting Alert Settings file \"%ws\" to \n \"%ws\"",
  749. szPerfmonFileName,
  750. szSysmonFileName);
  751. #endif
  752. bSuccess = OpenAlert (szPerfmonFileName, hInFile, fOutFile, szSingleObjectName);
  753. *pdwFileType = PMA_FILE;
  754. } else if (lstrcmpW(pfHeader.szSignature, szPerfLogSignature) == 0) {
  755. #ifdef _DBG_MSG_PRINT
  756. fprintf (stderr, "\nConverting Log Settings file \"%ws\" to \n \"%ws\"",
  757. szPerfmonFileName,
  758. szSysmonFileName);
  759. #endif
  760. bSuccess = OpenLog (szPerfmonFileName, hInFile, fOutFile, szSingleObjectName);
  761. *pdwFileType = PML_FILE;
  762. } else if (lstrcmpW(pfHeader.szSignature, szPerfReportSignature) == 0) {
  763. #ifdef _DBG_MSG_PRINT
  764. fprintf (stderr, "\nConverting Report Settings file \"%ws\" to \n \"%ws\"",
  765. szPerfmonFileName,
  766. szSysmonFileName);
  767. #endif
  768. bSuccess = OpenReport (hInFile, fOutFile, szSingleObjectName);
  769. *pdwFileType = PMR_FILE;
  770. } else if (lstrcmpW(pfHeader.szSignature, szPerfWorkspaceSignature) == 0) {
  771. #ifdef _DBG_MSG_PRINT
  772. fprintf (stderr, "\nConverting Workspace Settings file \"%ws\" to \n \"%ws\"",
  773. szPerfmonFileName,
  774. szSysmonFileName);
  775. #endif
  776. bSuccess = OpenWorkspace (szPerfmonFileName, hInFile, fOutFile);
  777. *pdwFileType = PMW_FILE;
  778. } else {
  779. // not a valid signature
  780. bSuccess = FALSE;
  781. }
  782. fwprintf (fOutFile, szHtmlFooter);
  783. fclose (fOutFile);
  784. } else {
  785. // not a valid file open
  786. bSuccess = FALSE;
  787. }
  788. }
  789. }
  790. if (hInFile != INVALID_HANDLE_VALUE) CloseHandle (hInFile);
  791. return bSuccess;
  792. }
  793. static
  794. BOOL
  795. MakeTempFileName (
  796. IN LPCWSTR wszRoot,
  797. IN LPWSTR wszTempFilename
  798. )
  799. {
  800. FILETIME ft;
  801. DWORD dwReturn;
  802. WCHAR wszLocalFilename[MAX_PATH];
  803. GetSystemTimeAsFileTime (&ft);
  804. dwReturn = (DWORD) swprintf(wszLocalFilename,
  805. (LPCWSTR)L"%%temp%%\\%s_%8.8x%8.8x.htm",
  806. (wszRoot != NULL ? wszRoot : (LPCWSTR)L"LodCtr"),
  807. ft.dwHighDateTime, ft.dwLowDateTime);
  808. if (dwReturn > 0) {
  809. // expand env. vars
  810. dwReturn = ExpandEnvironmentStringsW (
  811. wszLocalFilename,
  812. wszTempFilename,
  813. MAX_PATH-1);
  814. }
  815. return (BOOL)(dwReturn > 0);
  816. }
  817. static
  818. BOOL
  819. IsPerfmonFile(
  820. IN LPWSTR szFileName
  821. )
  822. {
  823. LPWSTR szResult = NULL;
  824. _wcslwr (szFileName);
  825. if (szResult == NULL) szResult = wcsstr (szFileName, (LPCWSTR)L".pmc"); // test for chart settings file
  826. if (szResult == NULL) szResult = wcsstr (szFileName, (LPCWSTR)L".pmr"); // test for report settings file
  827. if (szResult == NULL) szResult = wcsstr (szFileName, (LPCWSTR)L".pma"); // test for alert settings file
  828. if (szResult == NULL) szResult = wcsstr (szFileName, (LPCWSTR)L".pml"); // test for log settings file
  829. if (szResult == NULL) szResult = wcsstr (szFileName, (LPCWSTR)L".pmw"); // test for workspace file
  830. if (szResult == NULL)
  831. return FALSE;
  832. else
  833. return TRUE;
  834. }
  835. int
  836. __cdecl wmain(
  837. int argc,
  838. wchar_t *argv[])
  839. {
  840. WCHAR szCommandLine[MAXSTR];
  841. WCHAR szArgList[2048];
  842. WCHAR szTempFileName[MAXSTR];
  843. WCHAR szTempArg[MAXSTR];
  844. LPWSTR szArgFileName;
  845. int iThisArg;
  846. DWORD dwArgListLen;
  847. DWORD dwArgLen;
  848. STARTUPINFOW startInfo;
  849. PROCESS_INFORMATION processInfo;
  850. DWORD dwReturnValue = ERROR_SUCCESS;
  851. BOOL bSuccess = TRUE;
  852. DWORD dwPmFileType = 0;
  853. BOOL bPerfmonFileMade = FALSE;
  854. BOOL bDeleteFileOnExit = TRUE;
  855. memset (&startInfo, 0, sizeof(startInfo));
  856. memset (&processInfo, 0, sizeof(processInfo));
  857. memset (szTempFileName, 0, sizeof (szTempFileName));
  858. startInfo.cb = sizeof(startInfo);
  859. startInfo.dwFlags = STARTF_USESTDHANDLES;
  860. startInfo.wShowWindow = SW_SHOWDEFAULT;
  861. szTempArg[0] = UNICODE_NULL;
  862. szArgList[0] = UNICODE_NULL;
  863. ExpandEnvironmentStringsW (szMmcExeCmd, szCommandLine, sizeof(szCommandLine)/sizeof(szCommandLine[0]));
  864. dwArgListLen = ExpandEnvironmentStringsW (szMmcExeArg, szArgList, sizeof(szArgList)/sizeof(szArgList[0]));
  865. szArgList[(sizeof(szArgList)/sizeof(szArgList[0]))-1] = UNICODE_NULL;
  866. if (argc >= 2) {
  867. for (iThisArg = 1; iThisArg < argc; iThisArg++) {
  868. if (IsPerfmonFile(argv[iThisArg])) {
  869. if (!bPerfmonFileMade) {
  870. if (szTempFileName[0] == 0) {
  871. // if there's no filename, then make one
  872. MakeTempFileName ((LPCWSTR)L"PMSettings", szTempFileName);
  873. }
  874. bSuccess = ConvertPerfmonFile (argv[iThisArg], szTempFileName, &dwPmFileType);
  875. if (bSuccess) {
  876. swprintf(
  877. (LPWSTR)szTempArg,
  878. szMmcExeSetsArg,
  879. ( PML_FILE == dwPmFileType || PMA_FILE == dwPmFileType )
  880. ? szMmcExeSetsLogOpt : szEmpty,
  881. szTempFileName );
  882. bPerfmonFileMade = TRUE;
  883. } else {
  884. // ignore this parameter
  885. szTempArg[0] = 0;
  886. szTempArg[1] = 0;
  887. }
  888. } else {
  889. // only process the first perfmon file in the path
  890. }
  891. } else if (lstrcmpiW(argv[iThisArg], (LPCWSTR)L"/WMI") == 0) {
  892. // this is a special switch
  893. lstrcpyW (szTempArg, (LPCWSTR)L"/SYSMON_WMI");
  894. } else if ((argv[iThisArg][0] == L'/')
  895. && ((argv[iThisArg][1] == L'H') || (argv[iThisArg][1] == L'h'))
  896. && ((argv[iThisArg][2] == L'T') || (argv[iThisArg][2] == L't'))
  897. && ((argv[iThisArg][3] == L'M') || (argv[iThisArg][3] == L'm'))
  898. && ((argv[iThisArg][4] == L'L') || (argv[iThisArg][4] == L'l'))
  899. && ((argv[iThisArg][5] == L'F') || (argv[iThisArg][5] == L'f'))
  900. && ((argv[iThisArg][6] == L'I') || (argv[iThisArg][6] == L'i'))
  901. && ((argv[iThisArg][7] == L'L') || (argv[iThisArg][7] == L'l'))
  902. && ((argv[iThisArg][8] == L'E') || (argv[iThisArg][8] == L'e'))
  903. && (argv[iThisArg][9] == L':')) {
  904. szArgFileName = &argv[iThisArg][10];
  905. if (bPerfmonFileMade) {
  906. // then copy the file from the temp to the save file
  907. CopyFileW (szTempFileName, szArgFileName, FALSE);
  908. } else {
  909. // else set the perfmon file name to the one specified in the command line
  910. lstrcpyW (szTempFileName, szArgFileName);
  911. bDeleteFileOnExit = FALSE;
  912. }
  913. } else {
  914. // just copy the arg
  915. lstrcpynW (szTempArg, argv[iThisArg], MAXSTR-1);
  916. szTempArg[MAXSTR-1] = UNICODE_NULL;
  917. }
  918. dwArgLen = lstrlenW (szTempArg) + 1;
  919. if ((dwArgLen + dwArgListLen) < sizeof(szArgList)/sizeof(szArgList[0])) {
  920. szArgList[dwArgListLen - 1] = L' '; // add in delimiter
  921. lstrcpynW(&szArgList[dwArgListLen], szTempArg,
  922. (sizeof(szArgList)/sizeof(szArgList[0]))
  923. - dwArgListLen - 2);
  924. dwArgListLen += dwArgLen;
  925. } else {
  926. // no more room in the arg list buffer so bail
  927. break;
  928. }
  929. }
  930. } else {
  931. // no settings file in the command line so leave it as is
  932. }
  933. if (bSuccess) {
  934. #ifdef _DBG_MSG_PRINT
  935. fwprintf (stderr, (LPCWSTR)L"\nStarting \"%ws\" \"%ws\"",
  936. szCommandLine,
  937. szArgList);
  938. #endif
  939. bSuccess = CreateProcessW (
  940. szCommandLine,
  941. szArgList,
  942. NULL, NULL,
  943. FALSE,
  944. DETACHED_PROCESS,
  945. NULL,
  946. NULL,
  947. &startInfo,
  948. &processInfo);
  949. if (!bSuccess) {
  950. dwReturnValue = GetLastError();
  951. } else {
  952. Sleep (5000); // wait for things to get going
  953. CloseHandle (processInfo.hProcess);
  954. CloseHandle (processInfo.hThread);
  955. }
  956. #ifndef _DBG_MSG_PRINT
  957. if (bPerfmonFileMade && bDeleteFileOnExit) {
  958. DeleteFileW (szTempFileName);
  959. }
  960. #endif
  961. }
  962. return (int)dwReturnValue;
  963. }