/*++ Copyright (c) 1999 Microsoft Corporation Module Name: perfmon5.c Abstract: Program to adapt the command line Perfmon from NT4 and prior to the MMC & NT5 compatible format Author: Bob Watson (bobw) 11 may 99 Revision History: --*/ #define _OUTPUT_HTML 1 //#define _DBG_MSG_PRINT 1 #define _USE_MMC 1 #define MAXSTR 1024 #define MAX_ARG_STR 2048 #include "perfmon5.h" #include "strsafe.h" #define MemAlloc(s) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, s) #define MemReAlloc(h,s) HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, h, s) #define MemFree(h) if (h != NULL) { HeapFree(GetProcessHeap(), 0, h); } #define MemSize(h) ((h != NULL) ? HeapSize(GetPRocessHeap(), 0, h) : 0) // static & global variables #ifdef _USE_MMC LPCWSTR szMmcExeCmd = (LPCWSTR) L"%windir%\\system32\\mmc.exe"; LPCWSTR szMmcExeArg = (LPCWSTR) L" %windir%\\system32\\perfmon.msc /s"; #else LPCWSTR szMmcExeCmd = (LPCWSTR) L"%windir%\\explorer.exe"; LPCWSTR szMmcExeArg = (LPCWSTR) L" "; #endif LPCWSTR szMmcExeSetsArg = (LPCWSTR) L"/SYSMON%ws_SETTINGS \"%ws\""; LPCWSTR szMmcExeSetsLogOpt = (LPCWSTR) L"LOG"; LPCWSTR szEmpty = (LPCWSTR)L""; //HTML Formatting definitions // these are not localized LPCWSTR szHtmlHeader = (LPCWSTR) L"\ \r\n\ \r\n\ \r\n\ \r\n\ \r\n"; LPCWSTR szObjectHeader = (LPCWSTR) L"\ \r\n\ \r\n"; LPCWSTR szHtmlFooter = (LPCWSTR) L"\ \r\n\ \r\n"; LPCWSTR szHtmlDecimalParamFmt = (LPCWSTR) L" \r\n"; LPCWSTR szHtmlStringParamFmt = (LPCWSTR) L" \r\n"; LPCWSTR szHtmlWideStringParamFmt = (LPCWSTR) L" \r\n"; LPCWSTR szHtmlLineDecimalParamFmt = (LPCWSTR) L" \r\n"; LPCWSTR szHtmlLineRealParamFmt = (LPCWSTR) L" \r\n"; LPCWSTR szHtmlLineStringParamFmt = (LPCWSTR) L" \r\n"; LPCWSTR szSingleObjectName = (LPCWSTR) L"SystemMonitor1"; LPCWSTR szSysmonControlIdFmt = (LPCWSTR) L"SysmonControl%d"; // CODE STARTS HERE LPWSTR DiskStringRead( PDISKSTRING pDS ) { LPWSTR szReturnString = NULL; if (pDS->dwLength == 0) { szReturnString = NULL; } else { szReturnString = MemAlloc((pDS->dwLength + 1) * sizeof(WCHAR)); if (szReturnString) { StringCchCopyW(szReturnString, pDS->dwLength + 1, (LPWSTR) (((LPBYTE) pDS) + pDS->dwOffset)); } } return (szReturnString); } BOOL FileRead( HANDLE hFile, LPVOID lpMemory, DWORD nAmtToRead ) { BOOL bSuccess; DWORD nAmtRead; bSuccess = ReadFile(hFile, lpMemory, nAmtToRead, & nAmtRead, NULL); return (bSuccess && (nAmtRead == nAmtToRead)); } BOOL ReadLogLine( HANDLE hFile, FILE * fOutFile, LPDWORD pdwLineNo, DWORD dwInFileType, PDISKLINE * ppDiskLine, DWORD * pSizeofDiskLine ) /* Effect: Read in a line from the file hFile, at the current file position. Internals: The very first characters are a line signature, then a length integer. If the signature is correct, then allocate the length amount, and work with that. */ { #ifdef _OUTPUT_HTML PDH_COUNTER_PATH_ELEMENTS_W pdhPathElem; LPWSTR wszCounterPath = NULL; PDH_STATUS pdhStatus; DWORD dwCounterPathSize = 0; #endif LOGENTRY LogEntry; BOOL bReturn = TRUE; UNREFERENCED_PARAMETER(dwInFileType); UNREFERENCED_PARAMETER(ppDiskLine); UNREFERENCED_PARAMETER(pSizeofDiskLine); //=============================// // read and compare signature // //=============================// if (! FileRead(hFile, & LogEntry, sizeof(LOGENTRY) - sizeof(LogEntry.pNextLogEntry))) { return (FALSE); } #ifdef _OUTPUT_HTML // expand log entry into counters: not this may not always work! if (lstrcmpW(LogEntry.szComputer, (LPCWSTR) L"....") != 0) { // then add the machine name pdhPathElem.szMachineName = LogEntry.szComputer; } else { pdhPathElem.szMachineName = NULL; } pdhPathElem.szObjectName = LogEntry.szObject; pdhPathElem.szInstanceName = (LPWSTR) L"*"; pdhPathElem.szParentInstance = NULL; pdhPathElem.dwInstanceIndex = (DWORD) -1; pdhPathElem.szCounterName = (LPWSTR) L"*"; pdhStatus = PdhMakeCounterPathW(& pdhPathElem, wszCounterPath, & dwCounterPathSize, 0); while (pdhStatus == PDH_MORE_DATA) { MemFree(wszCounterPath); wszCounterPath = MemAlloc(dwCounterPathSize * sizeof(WCHAR)); if (wszCounterPath != NULL) { pdhStatus = PdhMakeCounterPathW(& pdhPathElem, wszCounterPath, & dwCounterPathSize, 0); } else { pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE; } } if (pdhStatus == ERROR_SUCCESS) { fwprintf(fOutFile, szHtmlLineStringParamFmt, * pdwLineNo, (LPCWSTR) L"Path", wszCounterPath); * pdwLineNo = * pdwLineNo + 1; // increment the line no } else { bReturn = FALSE; } MemFree(wszCounterPath); #else fprintf(fOutFile, "\n Line[%3.3d].ObjectTitleIndex = %d", * pdwLineNo, LogEntry.ObjectTitleIndex); fprintf(fOutFile, "\n Line[%3.3d].szComputer = %ws", * pdwLineNo, LogEntry.szComputer); fprintf(fOutFile, "\n Line[%3.3d].szObject = %ws", * pdwLineNo, LogEntry.szObject); fprintf(fOutFile, "\n Line[%3.3d].bSaveCurrentName = %d", * pdwLineNo, LogEntry.bSaveCurrentName); * pdwLineNo = * pdwLineNo + 1; // increment the line no #endif return bReturn; } BOOL ReadLine( HANDLE hFile, FILE * fOutFile, LPDWORD pdwLineNo, DWORD dwInFileType, PDISKLINE * ppDiskLine, DWORD * pSizeofDiskLine ) /* Effect: Read in a line from the file hFile, at the current file position. Internals: The very first characters are a line signature, then a length integer. If the signature is correct, then allocate the length amount, and work with that. */ { PDISKLINE pDiskLine = NULL; DWORD dwLineNo = * pdwLineNo; #ifdef _OUTPUT_HTML double dScaleFactor; PDH_STATUS pdhStatus; PDH_COUNTER_PATH_ELEMENTS_W pdhPathElem; LPWSTR wszCounterPath = NULL; DWORD dwCounterPathSize = 0; #else LPWSTR szTempString = NULL; #endif BOOL bReturn = FALSE; struct { DWORD dwSignature; DWORD dwLength; } LineHeader; //=============================// // read and compare signature // //=============================// if (! FileRead(hFile, & LineHeader, sizeof(LineHeader))) { goto Cleanup; } if (LineHeader.dwSignature != dwLineSignature || LineHeader.dwLength == 0) { SetLastError(ERROR_BAD_FORMAT); goto Cleanup; } //=============================// // read and allocate length // //=============================// // if (!FileRead (hFile, &dwLength, sizeof (dwLength)) || dwLength == 0) // return (NULL) ; // check if we need a bigger buffer, // normally, it should be the same except the first time... if (LineHeader.dwLength > * pSizeofDiskLine) { MemFree(* ppDiskLine); * pSizeofDiskLine = 0; // re-allocate a new buffer * ppDiskLine = (PDISKLINE) MemAlloc(LineHeader.dwLength); if ((* ppDiskLine) == NULL) { // no memory, should flag an error... goto Cleanup; } * pSizeofDiskLine = LineHeader.dwLength; } pDiskLine = * ppDiskLine; //=============================// // copy diskline, alloc line // //=============================// if (! FileRead(hFile, pDiskLine, LineHeader.dwLength)) { goto Cleanup; } #ifdef _OUTPUT_HTML // HTML output requires 1 based indexes, not 0 based dwLineNo += 1; // make counter path string out of components pdhPathElem.szMachineName = DiskStringRead(& (pDiskLine->dsSystemName)); if (pdhPathElem.szMachineName != NULL && lstrcmpW(pdhPathElem.szMachineName, (LPCWSTR) L"....") == 0) { // then use local machine MemFree(pdhPathElem.szMachineName); pdhPathElem.szMachineName = NULL; } pdhPathElem.szObjectName = DiskStringRead(& (pDiskLine->dsObjectName)); if (pDiskLine->dwUniqueID != PERF_NO_UNIQUE_ID) { pdhPathElem.szInstanceName = MemAlloc(MAXSTR); if (pdhPathElem.szInstanceName != NULL) { _ltow(pDiskLine->dwUniqueID, pdhPathElem.szInstanceName, 10); } } else { pdhPathElem.szInstanceName = DiskStringRead(& (pDiskLine->dsInstanceName)); } pdhPathElem.szParentInstance = DiskStringRead( &(pDiskLine->dsPINName)); pdhPathElem.dwInstanceIndex = (DWORD) -1; pdhPathElem.szCounterName = DiskStringRead( &(pDiskLine->dsCounterName)); pdhStatus = PdhMakeCounterPathW(& pdhPathElem, wszCounterPath, & dwCounterPathSize, 0); while (pdhStatus == PDH_MORE_DATA) { MemFree(wszCounterPath); wszCounterPath = MemAlloc(dwCounterPathSize * sizeof(WCHAR)); if (wszCounterPath != NULL) { pdhStatus = PdhMakeCounterPathW(& pdhPathElem, wszCounterPath, & dwCounterPathSize, 0); } else { pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE; } } if (pdhStatus == ERROR_SUCCESS) { fwprintf(fOutFile, szHtmlLineStringParamFmt, dwLineNo, (LPCWSTR) L"Path", wszCounterPath); if (dwInFileType == PMC_FILE) { dScaleFactor = log10(pDiskLine->eScale); dScaleFactor += 0.5; dScaleFactor = floor(dScaleFactor); fwprintf(fOutFile, szHtmlLineDecimalParamFmt, dwLineNo, (LPCWSTR) L"ScaleFactor", (LONG) dScaleFactor); fwprintf(fOutFile, szHtmlLineDecimalParamFmt, dwLineNo, (LPCWSTR) L"Color", * (DWORD *) & pDiskLine->Visual.crColor); fwprintf(fOutFile, szHtmlLineDecimalParamFmt, dwLineNo, (LPCWSTR) L"LineStyle", pDiskLine->Visual.iStyle ); fwprintf(fOutFile, szHtmlLineDecimalParamFmt, dwLineNo, (LPCWSTR) L"Width", pDiskLine->Visual.iWidth); } if (dwInFileType == PMA_FILE) { fwprintf(fOutFile, szHtmlLineDecimalParamFmt, dwLineNo, (LPCWSTR) L"AlertOverUnder", pDiskLine->bAlertOver); fwprintf(fOutFile, szHtmlLineRealParamFmt, dwLineNo, (LPCWSTR) L"AlertThreshold", pDiskLine->eAlertValue); fwprintf(fOutFile, szHtmlLineDecimalParamFmt, dwLineNo, (LPCWSTR) L"Color", * (DWORD *) & pDiskLine->Visual.crColor); } bReturn = TRUE; } MemFree(wszCounterPath); MemFree(pdhPathElem.szMachineName); MemFree(pdhPathElem.szObjectName); MemFree(pdhPathElem.szInstanceName); MemFree(pdhPathElem.szParentInstance); MemFree(pdhPathElem.szCounterName); #else UNREFERENCED_PARAMETER(dwInFileType); fwprintf(fOutFile, (LPCWSTR) L"\n Line[%3.3d].iLineType = %d", dwLineNo, pDiskLine->iLineType); szTempString = DiskStringRead(& (pDiskLine->dsSystemName)); fwprintf(fOutFile, (LPCWSTR) L"\n Line[%3.3d].dsSystmeName = %ws", dwLineNo, (szTempString ? szTempString : (LPCWSTR)L"")); MemFree(szTempString); szTempString = DiskStringRead(& (pDiskLine->dsObjectName)); fwprintf(fOutFile, (LPCWSTR) L"\n Line[%3.3d].dsObjectName = %ws", dwLineNo, (szTempString ? szTempString : (LPCWSTR)L"")); MemFree(szTempString); szTempString = DiskStringRead(& (pDiskLine->dsCounterName)); fwprintf(fOutFile, (LPCWSTR) L"\n Line[%3.3d].dsCounterName = %ws", dwLineNo, (szTempString ? szTempString : (LPCWSTR)L"")); MemFree(szTempString); szTempString = DiskStringRead(& (pDiskLine->dsInstanceName)); fwprintf(fOutFile, (LPCWSTR) L"\n Line[%3.3d].dsInstanceName = %ws", dwLineNo, (szTempString ? szTempString : (LPCWSTR)L"")); MemFree(szTempString); szTempString = DiskStringRead(& (pDiskLine->dsPINName)); fwprintf(fOutFile, (LPCWSTR) L"\n Line[%3.3d].dsPINName = %ws", dwLineNo, (szTempString ? szTempString : (LPCWSTR)L"")); MemFree(szTempString); szTempString = DiskStringRead(& (pDiskLine->dsParentObjName)); fwprintf(fOutFile, (LPCWSTR) L"\n Line[%3.3d].dsParentObjName = %ws", dwLineNo, (szTempString ? szTempString : (LPCWSTR)L"")); MemFree(szTempString); fwprintf(fOutFile, (LPCWSTR) L"\n Line[%3.3d].dwUniqueID = 0x%8.8x", dwLineNo, pDiskLine->dwUniqueID); fwprintf(fOutFile, (LPCWSTR) L"\n Line[%3.3d].iScaleIndex = %d", dwLineNo, pDiskLine->iScaleIndex); fwprintf(fOutFile, (LPCWSTR) L"\n Line[%3.3d].eScale = %e", dwLineNo, pDiskLine->eScale); fwprintf(fOutFile, (LPCWSTR) L"\n Line[%3.3d].bAlertOver = %d", dwLineNo, pDiskLine->bAlertOver); fwprintf(fOutFile, (LPCWSTR) L"\n Line[%3.3d].eAlertValue = %e", dwLineNo, pDiskLine->eAlertValue); szTempString = DiskStringRead(& (pDiskLine->dsAlertProgram)); fwprintf(fOutFile, (LPCWSTR) L"\n Line[%3.3d].dsAlertProgram = %ws", dwLineNo, (szTempString ? szTempString : (LPCWSTR)L"")); MemFree(szTempString); fwprintf(fOutFile, (LPCWSTR) L"\n Line[%3.3d].bEveryTime = %d", dwLineNo, pDiskLine->bEveryTime); fwprintf(fOutFile, (LPCWSTR) L"\n Line[%3.3d].LV.crColor = 0x%8.8x", dwLineNo, *(DWORD *)&pDiskLine->Visual.crColor) ; fwprintf(fOutFile, (LPCWSTR) L"\n Line[%3.3d].LV.iColorIndex = %d", dwLineNo, pDiskLine->Visual.iColorIndex ); fwprintf(fOutFile, (LPCWSTR) L"\n Line[%3.3d].LV.iStyle = %d", dwLineNo, pDiskLine->Visual.iStyle ); fwprintf(fOutFile, (LPCWSTR) L"\n Line[%3.3d].LV.iStyleIndex = %d", dwLineNo, pDiskLine->Visual.iStyleIndex ); fwprintf(fOutFile, (LPCWSTR) L"\n Line[%3.3d].LV.iWidth = %d", dwLineNo, pDiskLine->Visual.iWidth ); fwprintf(fOutFile, (LPCWSTR) L"\n Line[%3.3d].LV.iWidthIndex = %d", dwLineNo, pDiskLine->Visual.iWidthIndex ); bReturn = TRUE; #endif Cleanup: return bReturn; } void ReadLines( HANDLE hFile, FILE * fOutFile, DWORD dwFileType, DWORD dwNumLines ) { DWORD i; PDISKLINE pDiskLine = NULL; DWORD SizeofDiskLine = 0; // bytes in pDiskLine DWORD dwLogLineNo; SizeofDiskLine = MAX_PATH; for (i = 0, dwLogLineNo = 1; i < dwNumLines ; i ++) { if (dwFileType == PML_FILE) { ReadLogLine(hFile, fOutFile, & dwLogLineNo, dwFileType, & pDiskLine, & SizeofDiskLine); } else { ReadLine(hFile, fOutFile, & i, dwFileType, & pDiskLine, & SizeofDiskLine); } } MemFree(pDiskLine); } BOOL OpenAlert( LPCWSTR szInFileName, HANDLE hFile, FILE * fOutFile, LPCWSTR szObjectName ) { // OpenAlert DISKALERT DiskAlert; BOOL bSuccess = TRUE ; DWORD dwLocalActionFlags = 0; #ifdef _OUTPUT_HTML WCHAR szComment[MAX_PATH]; WCHAR path[_MAX_PATH]; WCHAR drive[_MAX_DRIVE]; WCHAR dir[_MAX_DIR]; WCHAR fname[_MAX_FNAME]; WCHAR ext[_MAX_EXT]; #endif // read the next section if valid bSuccess = FileRead (hFile, &DiskAlert, sizeof (DISKALERT)); if (bSuccess) { #ifdef _OUTPUT_HTML if (DiskAlert.dwNumLines > 0) { fwprintf(fOutFile, szObjectHeader, szObjectName); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"ManualUpdate", DiskAlert.bManualRefresh); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"ShowToolbar", DiskAlert.perfmonOptions.bMenubar); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"UpdateInterval", (int) DiskAlert.dwIntervalSecs / 1000); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"SampleIntervalUnitType", 1); // Seconds fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"SampleIntervalValue", (int) DiskAlert.dwIntervalSecs / 1000); fwprintf(fOutFile, szHtmlStringParamFmt, (LPCWSTR) L"CommandFile", ""); fwprintf(fOutFile, szHtmlStringParamFmt, (LPCWSTR) L"UserText", ""); fwprintf(fOutFile, szHtmlStringParamFmt, (LPCWSTR) L"PerfLogName", ""); dwLocalActionFlags |= 1; // perfmon normally logs to the UI, but we don't have one // so log to the event log by default if (DiskAlert.bNetworkAlert) { dwLocalActionFlags |= 2; } // perfmon does 1 net name per alert. we do 1 per file so leave it blank fwprintf(fOutFile, szHtmlStringParamFmt, (LPCWSTR) L"NetworkName", ""); dwLocalActionFlags |= 0x00003F00; // command line flags fwprintf (fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"ActionFlags",dwLocalActionFlags); // set the defaults to duplicate a perfmon log _wfullpath(path, szInFileName, _MAX_PATH); _wsplitpath(path, drive, dir, fname, ext); fwprintf(fOutFile, szHtmlWideStringParamFmt, (LPCWSTR) L"AlertName", fname); ZeroMemory(szComment, MAX_PATH * sizeof(WCHAR)); StringCchPrintfW(szComment, MAX_PATH, (LPCWSTR) L"Created from Perfmon Settings File \"%ws%ws\"", fname, ext); fwprintf(fOutFile, szHtmlStringParamFmt, (LPCWSTR) L"Comment", szComment); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"LogType", 2); // Sysmon alert fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"LogFileMaxSize", -1); // no size limit fwprintf(fOutFile, szHtmlWideStringParamFmt, (LPCWSTR) L"LogFileBaseName", fname); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"LogFileSerialNumber", 1); ZeroMemory(szComment, MAX_PATH * sizeof(WCHAR)); StringCchPrintfW(szComment, MAX_PATH, (LPCWSTR) L"%ws%ws", drive, dir); fwprintf(fOutFile, szHtmlWideStringParamFmt, (LPCWSTR) L"LogFileFolder", szComment); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"LogFileAutoFormat", 0); //no auto name fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"LogFileType", 2); // PDH binary counter log fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"StartMode", 0); // manual start fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"StopMode", 0); // manual stop fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"RestartMode", 0); // no restart fwprintf(fOutFile, szHtmlStringParamFmt, (LPCWSTR) L"EOFCommandFile", ""); // Get ready to list the counters fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"CounterCount", DiskAlert.dwNumLines); } #else // output text UNREFERENCED_PARAMETER(szInFileName); UNREFERENCED_PARAMETER(szOutFileName); // dump settings file header fOutFile = stdout; fprintf(fOutFile, "\nDA.dwNumLines = %d", DiskAlert.dwNumLines); fprintf(fOutFile, "\nDA.dwIntervalSecs = %d", DiskAlert.dwIntervalSecs); fprintf(fOutFile, "\nDA.bManualRefresh = %d", DiskAlert.bManualRefresh); fprintf(fOutFile, "\nDA.bSwitchToAlert = %d", DiskAlert.bSwitchToAlert); fprintf(fOutFile, "\nDA.bNetworkAlert = %d", DiskAlert.bNetworkAlert); fprintf(fOutFile, "\nDA.MessageName = %16.16ws", DiskAlert.MessageName); fprintf(fOutFile, "\nDA.MiscOptions = 0x%8.8x", DiskAlert.MiscOptions); fprintf(fOutFile, "\nDA.LV.crColor = 0x%8.8x", * (DWORD *) & DiskAlert.Visual.crColor); fprintf(fOutFile, "\nDA.LV.iColorIndex = %d", DiskAlert.Visual.iColorIndex); fprintf(fOutFile, "\nDA.LV.iStyle = %d", DiskAlert.Visual.iStyle); fprintf(fOutFile, "\nDA.LV.iStyleIndex = %d", DiskAlert.Visual.iStyleIndex); fprintf(fOutFile, "\nDA.LV.iWidth = %d", DiskAlert.Visual.iWidth); fprintf(fOutFile, "\nDA.LV.iWidthIndex = %d", DiskAlert.Visual.iWidthIndex); fprintf(fOutFile, "\nDA.PO.bMenubar = %d", DiskAlert.perfmonOptions.bMenubar); fprintf(fOutFile, "\nDA.PO.bToolbar = %d", DiskAlert.perfmonOptions.bToolbar); fprintf(fOutFile, "\nDA.PO.bStatusbar = %d", DiskAlert.perfmonOptions.bStatusbar); fprintf(fOutFile, "\nDA.PO.bAlwaysOnTop = %d", DiskAlert.perfmonOptions.bAlwaysOnTop); #endif } if ((bSuccess) && (DiskAlert.dwNumLines > 0)) { ReadLines(hFile, fOutFile, PMA_FILE, DiskAlert.dwNumLines); #ifdef _OUTPUT_HTML fwprintf(fOutFile, szObjectFooter); #endif } return (bSuccess); } // OpenAlert BOOL OpenLog( LPCWSTR szInFileName, HANDLE hFile, FILE * fOutFile, LPCWSTR szObjectName ) { // OpenLog DISKLOG DiskLog; BOOL bSuccess = TRUE; #ifdef _OUTPUT_HTML WCHAR szComment[MAX_PATH]; WCHAR path[_MAX_PATH]; WCHAR drive[_MAX_DRIVE]; WCHAR dir[_MAX_DIR]; WCHAR fname[_MAX_FNAME]; WCHAR ext[_MAX_EXT]; #endif // read the next section if valid bSuccess = FileRead(hFile, & DiskLog, sizeof(DISKLOG)); if (bSuccess) { #ifdef _OUTPUT_HTML if (DiskLog.dwNumLines > 0) { fwprintf(fOutFile, szObjectHeader, szObjectName); // dump settings file header fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"ManualUpdate", DiskLog.bManualRefresh); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"UpdateInterval", (int) DiskLog.dwIntervalSecs / 1000); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"SampleIntervalUnitType", 1); // Seconds fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"SampleIntervalValue", (int) DiskLog.dwIntervalSecs / 1000); fwprintf(fOutFile, szHtmlWideStringParamFmt, (LPCWSTR) L"LogFileName", DiskLog.LogFileName); // set the defaults to duplicate a perfmon log _wfullpath(path, szInFileName, _MAX_PATH); _wsplitpath(path, drive, dir, fname, ext); fwprintf(fOutFile, szHtmlWideStringParamFmt, (LPCWSTR) L"LogName", fname); ZeroMemory(szComment, MAX_PATH * sizeof(WCHAR)); StringCchPrintfW(szComment, MAX_PATH, (LPCWSTR) L"Created from Perfmon Settings File \"%ws%ws\"", fname, ext); fwprintf(fOutFile, szHtmlStringParamFmt, (LPCWSTR) L"Comment", szComment); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"LogType", 0); // PDH counter log fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"LogFileMaxSize", -1); // no size limit fwprintf(fOutFile, szHtmlWideStringParamFmt, (LPCWSTR) L"LogFileBaseName", fname); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"LogFileSerialNumber", 1); ZeroMemory(szComment, MAX_PATH * sizeof(WCHAR)); StringCchPrintfW(szComment, MAX_PATH, (LPCWSTR) L"%ws%ws", drive, dir); fwprintf(fOutFile, szHtmlWideStringParamFmt, (LPCWSTR) L"LogFileFolder", szComment); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"LogFileAutoFormat", 0); //no auto name fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"LogFileType", 2); // PDH binary counter log fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"StartMode", 0); // manual start fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"StopMode", 0); // manual stop fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"RestartMode", 0); // no restart fwprintf(fOutFile, szHtmlStringParamFmt, (LPCWSTR) L"EOFCommandFile", ""); // Get ready to list the counters fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"CounterCount", DiskLog.dwNumLines); } #else // output text UNREFERENCED_PARAMETER(szInFileName); // dump settings file header fOutFile = stdout; fprintf(fOutFile, "\nDL.dwNumLines = %d", DiskLog.dwNumLines); fprintf(fOutFile, "\nDL.bManualRefresh = %d", DiskLog.bManualRefresh); fprintf(fOutFile, "\nDL.dwIntervalSecs = %d", DiskLog.dwIntervalSecs); fprintf(fOutFile, "\nDL.LogFileName = %ws", DiskLog.LogFileName); fprintf(fOutFile, "\nDC.PO.bMenubar = %d", DiskLog.perfmonOptions.bMenubar); fprintf(fOutFile, "\nDC.PO.bToolbar = %d", DiskLog.perfmonOptions.bToolbar); fprintf(fOutFile, "\nDC.PO.bStatusbar = %d", DiskLog.perfmonOptions.bStatusbar); fprintf(fOutFile, "\nDC.PO.bAlwaysOnTop = %d", DiskLog.perfmonOptions.bAlwaysOnTop); #endif } if ((bSuccess) && (DiskLog.dwNumLines > 0)) { //the log settings file requires a special function to read the lines from ReadLines(hFile, fOutFile, PML_FILE, DiskLog.dwNumLines); #ifdef _OUTPUT_HTML fwprintf(fOutFile, szObjectFooter); #endif } return (bSuccess) ; } // OpenLog BOOL OpenReport( HANDLE hFile, FILE * fOutFile, LPCWSTR szObjectName ) { // OpenReport DISKREPORT DiskReport; BOOL bSuccess = TRUE; DWORD dwColor; // read the next section if valid bSuccess = FileRead(hFile, & DiskReport, sizeof(DISKREPORT)); if (bSuccess) { #ifdef _OUTPUT_HTML if (DiskReport.dwNumLines > 0) { // dump settings file header fwprintf(fOutFile, szObjectHeader, szObjectName); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"ManualUpdate", DiskReport.bManualRefresh); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"ShowToolbar", DiskReport.perfmonOptions.bToolbar); // report intervals are reported in mS fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"UpdateInterval", (int) DiskReport.dwIntervalSecs / 1000); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"DisplayType", 3); // report type fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"ReportValueType", 0); // default display value // derive the following from the current windows environment dwColor = GetSysColor(COLOR_WINDOW); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"BackColor", dwColor); dwColor = GetSysColor(COLOR_3DFACE); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"BackColorCtl", dwColor); dwColor = GetSysColor(COLOR_BTNTEXT); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"ForeColor", dwColor); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"GridColor", dwColor); dwColor = 0x00FF0000; // red fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"TimeBarColor", dwColor); // other perfmon settings that are assumed by perfmon but fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"Appearance", 1); // 3d appearance fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"BorderStyle", 0); // no border // Get ready to list the counters fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"CounterCount", DiskReport.dwNumLines); } // else no counters to dump #else // output text // dump settings file header fprintf(fOutFile, "\nDR.dwNumLines = %d", DiskReport.dwNumLines); fprintf(fOutFile, "\nDR.bManualRefresh = %d", DiskReport.bManualRefresh); fprintf(fOutFile, "\nDC.dwIntervalSecs = %d", DiskReport.dwIntervalSecs); fprintf(fOutFile, "\nDR.LV.crColor = 0x%8.8x", * (DWORD *) & DiskReport.Visual.crColor); fprintf(fOutFile, "\nDR.LV.iColorIndex = %d", DiskReport.Visual.iColorIndex); fprintf(fOutFile, "\nDR.LV.iStyle = %d", DiskReport.Visual.iStyle); fprintf(fOutFile, "\nDR.LV.iStyleIndex = %d", DiskReport.Visual.iStyleIndex); fprintf(fOutFile, "\nDR.LV.iWidth = %d", DiskReport.Visual.iWidth); fprintf(fOutFile, "\nDR.LV.iWidthIndex = %d", DiskReport.Visual.iWidthIndex); fprintf(fOutFile, "\nDC.PO.bMenubar = %d", DiskReport.perfmonOptions.bMenubar); fprintf(fOutFile, "\nDC.PO.bToolbar = %d", DiskReport.perfmonOptions.bToolbar); fprintf(fOutFile, "\nDC.PO.bStatusbar = %d", DiskReport.perfmonOptions.bStatusbar); fprintf(fOutFile, "\nDC.PO.bAlwaysOnTop = %d", DiskReport.perfmonOptions.bAlwaysOnTop); #endif } if ((bSuccess) && (DiskReport.dwNumLines > 0)) { ReadLines(hFile, fOutFile, PMR_FILE, DiskReport.dwNumLines); #ifdef _OUTPUT_HTML fwprintf(fOutFile, szObjectFooter); #endif } return (bSuccess); } // OpenReport BOOL OpenChart( HANDLE hFile, FILE * fOutFile, LPCWSTR szObjectName ) { // OpenChart DISKCHART DiskChart; BOOL bSuccess = TRUE; DWORD dwColor; // read the next section if valid bSuccess = FileRead(hFile, & DiskChart, sizeof(DISKCHART)); if (bSuccess) { #ifdef _OUTPUT_HTML if (DiskChart.dwNumLines > 0) { // dump settings file header fwprintf(fOutFile, szObjectHeader, szObjectName); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"ManualUpdate", DiskChart.bManualRefresh); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"ShowLegend", DiskChart.gOptions.bLegendChecked); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"ShowScaleLabels", DiskChart.gOptions.bLabelsChecked); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"ShowVerticalGrid", DiskChart.gOptions.bVertGridChecked); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"ShowHorizontalGrid", DiskChart.gOptions.bHorzGridChecked); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"ShowToolbar", DiskChart.gOptions.bMenuChecked); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"MaximumScale", DiskChart.gOptions.iVertMax); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"UpdateInterval", (int) DiskChart.gOptions.eTimeInterval); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"DisplayType", (DiskChart.gOptions.iGraphOrHistogram == BAR_GRAPH ? 2 : 1)); // derive the following from the current windows environment dwColor = GetSysColor(COLOR_3DFACE); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"BackColor", dwColor); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"BackColorCtl", dwColor); dwColor = GetSysColor(COLOR_BTNTEXT); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"ForeColor", dwColor); fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"GridColor", dwColor); dwColor = 0x00FF0000; // red fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"TimeBarColor", dwColor); // other perfmon settings that are assumed by perfmon but fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"Appearance", 1); // 3d appearance fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"BorderStyle", 0); // no border // Get ready to list the counters fwprintf(fOutFile, szHtmlDecimalParamFmt, (LPCWSTR) L"CounterCount", DiskChart.dwNumLines); } // else no counters to display #else // output text // dump settings file header fprintf(fOutFile, "\nDC.dwNumLines = %d", DiskChart.dwNumLines); fprintf(fOutFile, "\nDC.gMaxValues = %d", DiskChart.gMaxValues); fprintf(fOutFile, "\nDC.bManualRefresh = %d", DiskChart.bManualRefresh); fprintf(fOutFile, "\nDC.LV.crColor = 0x%8.8x", * (DWORD *) & DiskChart.Visual.crColor); fprintf(fOutFile, "\nDC.LV.iColorIndex = %d", DiskChart.Visual.iColorIndex); fprintf(fOutFile, "\nDC.LV.iStyle = %d", DiskChart.Visual.iStyle); fprintf(fOutFile, "\nDC.LV.iStyleIndex = %d", DiskChart.Visual.iStyleIndex); fprintf(fOutFile, "\nDC.LV.iWidth = %d", DiskChart.Visual.iWidth); fprintf(fOutFile, "\nDC.LV.iWidthIndex = %d", DiskChart.Visual.iWidthIndex); fprintf(fOutFile, "\nDC.GO.bLegendChecked = %d", DiskChart.gOptions.bLegendChecked); fprintf(fOutFile, "\nDC.GO.bMenuChecked = %d", DiskChart.gOptions.bMenuChecked); fprintf(fOutFile, "\nDC.GO.bLabelsChecked = %d", DiskChart.gOptions.bLabelsChecked); fprintf(fOutFile, "\nDC.GO.bVertGridChecked = %d", DiskChart.gOptions.bVertGridChecked); fprintf(fOutFile, "\nDC.GO.bHorzGridChecked = %d", DiskChart.gOptions.bHorzGridChecked); fprintf(fOutFile, "\nDC.GO.bStatusBarChecked = %d", DiskChart.gOptions.bStatusBarChecked); fprintf(fOutFile, "\nDC.GO.iVertMax = %d", DiskChart.gOptions.iVertMax); fprintf(fOutFile, "\nDC.GO.eTimeInterval = %e", DiskChart.gOptions.eTimeInterval); fprintf(fOutFile, "\nDC.GO.iGraphOrHistogram = %d", DiskChart.gOptions.iGraphOrHistogram); fprintf(fOutFile, "\nDC.GO.GraphVGrid = %d", DiskChart.gOptions.GraphVGrid); fprintf(fOutFile, "\nDC.GO.GraphHGrid = %d", DiskChart.gOptions.GraphHGrid); fprintf(fOutFile, "\nDC.GO.HistVGrid = %d", DiskChart.gOptions.HistVGrid); fprintf(fOutFile, "\nDC.GO.HistHGrid = %d", DiskChart.gOptions.HistHGrid); fprintf(fOutFile, "\nDC.PO.bMenubar = %d", DiskChart.perfmonOptions.bMenubar); fprintf(fOutFile, "\nDC.PO.bToolbar = %d", DiskChart.perfmonOptions.bToolbar); fprintf(fOutFile, "\nDC.PO.bStatusbar = %d", DiskChart.perfmonOptions.bStatusbar); fprintf(fOutFile, "\nDC.PO.bAlwaysOnTop = %d", DiskChart.perfmonOptions.bAlwaysOnTop); #endif } if ((bSuccess) && (DiskChart.dwNumLines > 0)) { ReadLines(hFile, fOutFile, PMC_FILE, DiskChart.dwNumLines); #ifdef _OUTPUT_HTML fwprintf(fOutFile, szObjectFooter); #endif } return (bSuccess); } // OpenChart BOOL OpenWorkspace( LPCWSTR szPerfmonFileName, HANDLE hInFile, FILE * fOutFile ) { DISKWORKSPACE DiskWorkspace; WCHAR szObjectName[MAX_PATH]; DWORD dwObjectId = 1; BOOL bReturn = FALSE; if (! FileRead(hInFile, & DiskWorkspace, sizeof(DISKWORKSPACE))) { goto Exit0 ; } if (DiskWorkspace.ChartOffset == 0 && DiskWorkspace.AlertOffset == 0 && DiskWorkspace.LogOffset == 0 && DiskWorkspace.ReportOffset == 0) { // no entries to process goto Exit0 ; } if (DiskWorkspace.ChartOffset) { if (FileSeekBegin(hInFile, DiskWorkspace.ChartOffset) == 0xFFFFFFFF) { goto Exit0 ; } ZeroMemory(szObjectName, MAX_PATH * sizeof(WCHAR)); StringCchPrintfW(szObjectName, MAX_PATH, szSysmonControlIdFmt, dwObjectId ++); // process chart entry if (! OpenChart(hInFile, fOutFile, szObjectName)) { goto Exit0 ; } } if (DiskWorkspace.AlertOffset) { if (FileSeekBegin(hInFile, DiskWorkspace.AlertOffset) == 0xffffffff) { goto Exit0 ; } ZeroMemory(szObjectName, MAX_PATH * sizeof(WCHAR)); StringCchPrintfW(szObjectName, MAX_PATH, szSysmonControlIdFmt, dwObjectId ++); if (! OpenAlert(szPerfmonFileName, hInFile, fOutFile, szObjectName)) { goto Exit0 ; } } if (DiskWorkspace.LogOffset) { if (FileSeekBegin(hInFile, DiskWorkspace.LogOffset) == 0xffffffff) { goto Exit0 ; } ZeroMemory(szObjectName, MAX_PATH * sizeof(WCHAR)); StringCchPrintfW(szObjectName, MAX_PATH, szSysmonControlIdFmt, dwObjectId ++); if (! OpenLog(szPerfmonFileName, hInFile, fOutFile, szObjectName)) { goto Exit0 ; } } if (DiskWorkspace.ReportOffset) { if (FileSeekBegin(hInFile, DiskWorkspace.ReportOffset) == 0xffffffff) { goto Exit0 ; } ZeroMemory(szObjectName, MAX_PATH * sizeof(WCHAR)); StringCchPrintfW(szObjectName, MAX_PATH, szSysmonControlIdFmt, dwObjectId ++); if (! OpenReport(hInFile, fOutFile, szObjectName)) { goto Exit0 ; } } bReturn = TRUE; Exit0: return bReturn; } // OpenWorkspace BOOL ConvertPerfmonFile( IN LPCWSTR szPerfmonFileName, IN LPCWSTR szSysmonFileName, IN LPDWORD pdwFileType ) { HANDLE hInFile = INVALID_HANDLE_VALUE; PERFFILEHEADER pfHeader; BOOL bSuccess = FALSE; FILE * fOutFile = NULL; #ifdef _OUTPUT_HTML DWORD dwColor; #endif // open input file as read only hInFile = CreateFileW( szPerfmonFileName, // filename GENERIC_READ, // read access 0, // no sharing NULL, // default security OPEN_EXISTING, // only open existing files FILE_ATTRIBUTE_NORMAL, // normal attributes NULL); // no template file if (hInFile != INVALID_HANDLE_VALUE) { bSuccess = FileRead(hInFile, & pfHeader, sizeof(PERFFILEHEADER)); if (bSuccess) { #ifdef _OUTPUT_HTML fOutFile = _wfopen(szSysmonFileName, (LPCWSTR) L"w+t"); #else fOutFile = stdout; #endif if (fOutFile != NULL) { dwColor = GetSysColor(COLOR_3DFACE); fwprintf(fOutFile, szHtmlHeader, (dwColor & 0x00FFFFFF)); if (lstrcmpW(pfHeader.szSignature, szPerfChartSignature) == 0) { #ifdef _DBG_MSG_PRINT fprintf(stderr, "\nConverting Chart Settings file \"%ws\" to \n \"%ws\"", szPerfmonFileName, szSysmonFileName); #endif bSuccess = OpenChart(hInFile, fOutFile, szSingleObjectName); * pdwFileType = PMC_FILE; } else if (lstrcmpW(pfHeader.szSignature, szPerfAlertSignature) == 0) { #ifdef _DBG_MSG_PRINT fprintf(stderr, "\nConverting Alert Settings file \"%ws\" to \n \"%ws\"", szPerfmonFileName, szSysmonFileName); #endif bSuccess = OpenAlert(szPerfmonFileName, hInFile, fOutFile, szSingleObjectName); * pdwFileType = PMA_FILE; } else if (lstrcmpW(pfHeader.szSignature, szPerfLogSignature) == 0) { #ifdef _DBG_MSG_PRINT fprintf(stderr, "\nConverting Log Settings file \"%ws\" to \n \"%ws\"", szPerfmonFileName, szSysmonFileName); #endif bSuccess = OpenLog(szPerfmonFileName, hInFile, fOutFile, szSingleObjectName); * pdwFileType = PML_FILE; } else if (lstrcmpW(pfHeader.szSignature, szPerfReportSignature) == 0) { #ifdef _DBG_MSG_PRINT fprintf(stderr, "\nConverting Report Settings file \"%ws\" to \n \"%ws\"", szPerfmonFileName, szSysmonFileName); #endif bSuccess = OpenReport(hInFile, fOutFile, szSingleObjectName); * pdwFileType = PMR_FILE; } else if (lstrcmpW(pfHeader.szSignature, szPerfWorkspaceSignature) == 0) { #ifdef _DBG_MSG_PRINT fprintf(stderr, "\nConverting Workspace Settings file \"%ws\" to \n \"%ws\"", szPerfmonFileName, szSysmonFileName); #endif bSuccess = OpenWorkspace(szPerfmonFileName, hInFile, fOutFile); * pdwFileType = PMW_FILE; } else { // not a valid signature bSuccess = FALSE; } fwprintf(fOutFile, szHtmlFooter); fclose(fOutFile); } else { // not a valid file open bSuccess = FALSE; } } } if (hInFile != INVALID_HANDLE_VALUE) CloseHandle(hInFile); return bSuccess; } BOOL MakeTempFileName ( IN LPCWSTR wszRoot, IN LPWSTR wszTempFilename, IN DWORD dwTempNameLen ) { FILETIME ft; DWORD dwReturn = 0; HRESULT hr = S_OK; WCHAR wszLocalFilename[MAX_PATH]; GetSystemTimeAsFileTime(& ft); ZeroMemory(wszLocalFilename, MAX_PATH * sizeof(WCHAR)); hr = StringCchPrintfW(wszLocalFilename, MAX_PATH, (LPCWSTR) L"%%temp%%\\%s_%8.8x%8.8x.htm", (wszRoot != NULL ? wszRoot : (LPCWSTR) L"LodCtr"), ft.dwHighDateTime, ft.dwLowDateTime); if (hr == S_OK) { // expand env. vars dwReturn = ExpandEnvironmentStringsW(wszLocalFilename, wszTempFilename, dwTempNameLen); } return (BOOL)(dwReturn > 0); } BOOL IsPerfmonFile( IN LPWSTR szFileName ) { LPWSTR szResult = NULL; _wcslwr(szFileName); if (szResult == NULL) szResult = wcsstr(szFileName, (LPCWSTR) L".pmc"); // test for chart settings file if (szResult == NULL) szResult = wcsstr(szFileName, (LPCWSTR) L".pmr"); // test for report settings file if (szResult == NULL) szResult = wcsstr(szFileName, (LPCWSTR) L".pma"); // test for alert settings file if (szResult == NULL) szResult = wcsstr(szFileName, (LPCWSTR) L".pml"); // test for log settings file if (szResult == NULL) szResult = wcsstr(szFileName, (LPCWSTR) L".pmw"); // test for workspace file return (szResult == NULL) ? (FALSE) : (TRUE); } int __cdecl wmain( int argc, wchar_t * argv[] ) { WCHAR szCommandLine[MAXSTR]; WCHAR szArgList[MAX_ARG_STR]; WCHAR szTempFileName[MAXSTR]; WCHAR szTempArg[MAXSTR]; LPWSTR szArgFileName; int iThisArg; DWORD dwArgListLen; DWORD dwArgLen; STARTUPINFOW startInfo; PROCESS_INFORMATION processInfo; DWORD dwReturnValue = ERROR_SUCCESS; BOOL bSuccess = TRUE; DWORD dwPmFileType = 0; BOOL bPerfmonFileMade = FALSE; BOOL bDeleteFileOnExit = TRUE; ZeroMemory(& startInfo, sizeof(STARTUPINFOW)); ZeroMemory(& processInfo, sizeof(PROCESS_INFORMATION)); ZeroMemory(szCommandLine, MAXSTR * sizeof(WCHAR)); ZeroMemory(szArgList, MAX_ARG_STR * sizeof(WCHAR)); ZeroMemory(szTempFileName, MAXSTR * sizeof(WCHAR)); ZeroMemory(szTempArg, MAXSTR * sizeof(WCHAR)); startInfo.cb = sizeof(startInfo); startInfo.dwFlags = STARTF_USESTDHANDLES; startInfo.wShowWindow = SW_SHOWDEFAULT; dwArgListLen = ExpandEnvironmentStringsW(szMmcExeCmd, szCommandLine, MAXSTR); dwArgListLen = ExpandEnvironmentStringsW(szMmcExeArg, szArgList, MAX_ARG_STR); szArgList[MAX_ARG_STR - 1] = UNICODE_NULL; if (argc >= 2) { for (iThisArg = 1; iThisArg < argc; iThisArg ++) { if (IsPerfmonFile(argv[iThisArg])) { if (! bPerfmonFileMade) { if (szTempFileName[0] == UNICODE_NULL) { // if there's no filename, then make one MakeTempFileName((LPCWSTR) L"PMSettings", szTempFileName, MAXSTR); } bSuccess = ConvertPerfmonFile(argv[iThisArg], szTempFileName, & dwPmFileType); if (bSuccess) { ZeroMemory(szTempArg, MAXSTR * sizeof(WCHAR)); StringCchPrintfW(szTempArg, MAXSTR, szMmcExeSetsArg, (PML_FILE == dwPmFileType || PMA_FILE == dwPmFileType) ? szMmcExeSetsLogOpt : szEmpty, szTempFileName); bPerfmonFileMade = TRUE; } else { // ignore this parameter szTempArg[0] = UNICODE_NULL; szTempArg[1] = UNICODE_NULL; } } } else if (lstrcmpiW(argv[iThisArg], (LPCWSTR) L"/WMI") == 0) { // this is a special switch ZeroMemory(szTempArg, MAXSTR * sizeof(WCHAR)); StringCchCopyW(szTempArg, MAXSTR, (LPCWSTR) L"/SYSMON_WMI"); } else if ( (argv[iThisArg][0] == L'/') && ((argv[iThisArg][1] == L'H') || (argv[iThisArg][1] == L'h')) && ((argv[iThisArg][2] == L'T') || (argv[iThisArg][2] == L't')) && ((argv[iThisArg][3] == L'M') || (argv[iThisArg][3] == L'm')) && ((argv[iThisArg][4] == L'L') || (argv[iThisArg][4] == L'l')) && ((argv[iThisArg][5] == L'F') || (argv[iThisArg][5] == L'f')) && ((argv[iThisArg][6] == L'I') || (argv[iThisArg][6] == L'i')) && ((argv[iThisArg][7] == L'L') || (argv[iThisArg][7] == L'l')) && ((argv[iThisArg][8] == L'E') || (argv[iThisArg][8] == L'e')) && (argv[iThisArg][9] == L':')) { szArgFileName = &argv[iThisArg][10]; if (bPerfmonFileMade) { // then copy the file from the temp to the save file CopyFileW(szTempFileName, szArgFileName, FALSE); } else { // else set the perfmon file name to the one specified in the command line ZeroMemory(szTempArg, MAXSTR * sizeof(WCHAR)); StringCchCopyW(szTempFileName, MAXSTR, szArgFileName); bDeleteFileOnExit = FALSE; } } else { // just copy the arg ZeroMemory(szTempArg, MAXSTR * sizeof(WCHAR)); StringCchCopyW(szTempArg, MAXSTR, argv[iThisArg]); szTempArg[MAXSTR - 1] = UNICODE_NULL; } dwArgLen = lstrlenW(szTempArg) + 1; if ((dwArgLen + dwArgListLen) < MAX_ARG_STR) { szArgList[dwArgListLen - 1] = L' '; // add in delimiter StringCchCopyW(& szArgList[dwArgListLen], MAX_ARG_STR - dwArgListLen - 1, szTempArg); dwArgListLen += dwArgLen; } else { // no more room in the arg list buffer so bail break; } } } if (bSuccess) { #ifdef _DBG_MSG_PRINT fwprintf(stderr, (LPCWSTR) L"\nStarting \"%ws\" \"%ws\"", szCommandLine, szArgList); #endif bSuccess = CreateProcessW( szCommandLine, szArgList, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, & startInfo, & processInfo); if (! bSuccess) { dwReturnValue = GetLastError(); } else { Sleep(5000); // wait for things to get going CloseHandle(processInfo.hProcess); CloseHandle(processInfo.hThread); } #ifndef _DBG_MSG_PRINT if (bPerfmonFileMade && bDeleteFileOnExit) { DeleteFileW(szTempFileName); } #endif } return (int) dwReturnValue; }