home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- *
- * Grafdata.c - This module handles the non-drawing functions of the graph,
- * such as allocating linked structures and their memory, freeing it,
- * unlinking, starting and stopping the timer,
- * setting up the first graph (CPU), and all the numeric functions for
- * the different counter types.
- *
- * Microsoft Confidential
- * Copyright (c) 1992-1997 Microsoft Corporation
- *
- *
- ****************************************************************************/
-
-
- //==========================================================================//
- // Includes //
- //==========================================================================//
-
- #include <stdio.h> // for sprintf
-
- #include "perfmon.h" // main perfmon declarations
- #include "grafdata.h" // external declarations for this file
- #include <float.h> // for FLT_MAX constant
-
- #include "addline.h" // for AddLine, EditLine
- #include "counters.h" // for CounterEntry
- #include "graph.h" // for SizeGraphComponents
- #include "pmemory.h" // for MemoryXXX (mallloc-type) routines
- #include "perfdata.h" // for UpdateLines
- #include "playback.h" // for PlayingBackLog, PlaybackLines
- #include "legend.h"
- #include "system.h" // for SystemGet
- #include "utils.h"
- #include "line.h" // for LineFree
- #include "valuebar.h" // for StatusTimer
-
- #include "fileopen.h" // for FileGetName
- #include "fileutil.h" // for FileRead...
- #include "menuids.h" // for IDM_VIEWCHART
- #include "perfmops.h" // for ExportFileHeader
- #include "status.h" // for StatusLineReady
-
- extern BOOL SaveFileHandler(HWND hWnd,DWORD type) ;
-
- // this macro is used in doing a simple DDA (Digital Differential Analyzer)
- // * 10 + 5 is to make the result round up with .5
- #define DDA_DISTRIBUTE(TotalTics, numOfData) \
- ((TotalTics * 10 / numOfData) + 5) / 10
-
- #define szSmallValueFormat TEXT("%10.3f")
- #define szLargeValueFormat TEXT("%10.0f")
-
- //==========================================================================//
- // Local Data //
- //==========================================================================//
-
-
-
-
- //==========================================================================//
- // Local Functions //
- //==========================================================================//
-
-
- /****************************************************************************
- * eUpdateMinMaxAve -
- ****************************************************************************/
- void eUpdateMinMaxAve (FLOAT eValue, PLINESTRUCT pLineStruct, INT iValidValues,
- INT iTotalValidPoints, INT iDataPoint, INT gMaxPoints)
- {
- INT i ;
- INT iDataNum = iTotalValidPoints ;
- FLOAT eMin,
- eMax,
- eSum,
- eNewValue ;
-
-
- eMax = eMin = eValue ;
-
- if (PlayingBackLog())
- {
- eSum = (FLOAT) 0.0 ;
- }
- else
- {
- eSum = eValue ;
- }
-
- if (iValidValues == iTotalValidPoints)
- {
- for (i=0 ; i < iValidValues ; i++)
- {
- if (i == iDataPoint)
- {
- // skip the data point we are going to replace
- continue ;
- }
-
- eNewValue = pLineStruct->lnValues[i] ;
-
- eSum += eNewValue ;
-
- if (eNewValue > eMax)
- {
- eMax = eNewValue ;
- }
-
- if (eNewValue < eMin)
- {
- eMin = eNewValue ;
- }
- }
- }
- else
- {
- // special case when we start the new line in the middle of the chart
- for (i = iDataPoint, iTotalValidPoints-- ;
- iTotalValidPoints > 0 ;
- iTotalValidPoints-- )
- {
- i-- ;
- if (i < 0)
- {
- // for the wrap-around case..
- i = gMaxPoints - 1 ;
- }
-
- if (i == iDataPoint)
- {
- // skip the data point we are going to replace
- continue ;
- }
- eNewValue = pLineStruct->lnValues[i] ;
-
- eSum += eNewValue ;
-
- if (eNewValue > eMax)
- {
- eMax = eNewValue ;
- }
-
- if (eNewValue < eMin)
- {
- eMin = eNewValue ;
- }
- }
- }
-
- pLineStruct->lnMinValue = eMin ;
- pLineStruct->lnMaxValue = eMax ;
-
- if (iDataNum)
- {
- pLineStruct->lnAveValue = eSum / (FLOAT) iDataNum ;
- }
- else
- {
- pLineStruct->lnAveValue = (FLOAT) 0.0 ;
- }
- }
-
-
- // UpdateValueBarData is used to update the value bar data
- // It is called when the user switches to a diff. line from
- // the legned window.
- VOID UpdateValueBarData (PGRAPHSTRUCT pGraph)
- {
- PLINESTRUCT pCurrentGraphLine ;
- INT KnownValue,
- MaxValues,
- iValidValues,
- iDataPoint ;
- FLOAT eValue ;
- pCurrentGraphLine = CurrentGraphLine (hWndGraph) ;
-
- if (!pCurrentGraphLine || pCurrentGraphLine->bFirstTime)
- {
- // we have not collect enough samples
- return ;
- }
-
- KnownValue = pGraph->gKnownValue ;
- MaxValues = pGraph->gMaxValues ;
-
- // The valid values is the number of valid entries in the
- // data buffer. After we wrap the buffer, all the values are
- // valid.
- iValidValues = pGraph->gTimeLine.iValidValues ;
-
- // Get the index to the data point we are updating.
-
- iDataPoint = KnownValue % MaxValues ;
- eValue = pCurrentGraphLine->lnValues[iDataPoint] ;
-
- // get the statistical data for this line
- eUpdateMinMaxAve(eValue, pCurrentGraphLine,
- iValidValues, pCurrentGraphLine->lnValidValues,
- iDataPoint, MaxValues) ;
- } // UpdateValueBarData
-
-
- VOID UpdateLGData (PGRAPHSTRUCT pGraph)
- {
- PLINESTRUCT pLine ;
- PLINESTRUCT pCurrentGraphLine ;
- INT KnownValue,
- MaxValues,
- iValidValues,
- iDataPoint ;
- FLOAT eValue ;
- // Known Value is the where data is placed in the buffer.
- pGraph->gKnownValue++;
-
- KnownValue = pGraph->gKnownValue ;
-
- // Update the high water mark for valid data in the lnValues
- // (aka DataPoint) buffer.
-
-
- MaxValues = pGraph->gMaxValues ;
-
- // The valid values is the number of valid entries in the
- // data buffer. After we wrap the buffer, all the values are
- // valid.
- iValidValues = pGraph->gTimeLine.iValidValues ;
-
- if (iValidValues < MaxValues)
- iValidValues = (KnownValue % MaxValues) + 1 ;
-
- pGraph->gTimeLine.iValidValues = iValidValues ;
-
- // Get the index to the data point we are updating.
-
- iDataPoint = KnownValue % MaxValues ;
-
- // loop through lines,
- // If one of the lines is highlighted then do the calculations
- // for average, min, & max on that line.
-
- pCurrentGraphLine = CurrentGraphLine (hWndGraph) ;
-
- for (pLine=pGraph->pLineFirst; pLine; pLine=pLine->pLineNext)
- { // for
-
- if (pLine->bFirstTime)
- {
- // skip until we have collect enough samples to plot the first data
- continue ;
- }
-
- if (pLine->lnValidValues < MaxValues)
- {
- (pLine->lnValidValues)++ ;
- }
-
- // Get the new value for this line.
- eValue = CounterEntry (pLine) ;
-
- if (pLine == pCurrentGraphLine)
- { // if
- // get the statistical data for this line
- eUpdateMinMaxAve (eValue, pLine,
- iValidValues, pLine->lnValidValues,
- iDataPoint, MaxValues) ;
- } // if
-
- // Now put the new value into the data array
- pLine->lnValues[iDataPoint] = eValue ;
- }
-
- GetLocalTime (&(pGraph->pDataTime[iDataPoint])) ;
- } // UpdateLGData
-
-
-
- BOOL HandleGraphTimer (void)
- {
- PGRAPHSTRUCT pGraph;
-
- //NOTE: get a strategy for these "no-go" states
- if (!(pGraph = pGraphs) || !pGraphs->pSystemFirst)
- return(FALSE);
-
-
- if (!UpdateLines(&(pGraphs->pSystemFirst), pGraphs->pLineFirst))
- return (TRUE) ;
-
- UpdateLGData(pGraph);
-
- return(TRUE);
- }
-
-
- VOID ClearGraphTimer(PGRAPHSTRUCT pGraph)
- {
- KillTimer(pGraph->hWnd, GRAPH_TIMER_ID);
- }
-
-
- VOID SetGraphTimer(PGRAPHSTRUCT pGraph)
- {
- SetTimer(pGraph->hWnd, GRAPH_TIMER_ID, pGraph->gInterval, NULL) ;
- }
-
- VOID ResetGraphTimer(PGRAPHSTRUCT pGraph)
- {
- KillTimer(pGraph->hWnd, GRAPH_TIMER_ID);
- SetGraphTimer(pGraph);
- }
-
-
- VOID GetGraphConfig(PGRAPHSTRUCT pGraph)
- {
-
- LoadRefreshSettings(pGraph);
- LoadLineGraphSettings(pGraph);
-
-
- // Init the structure
- pGraph->pLineFirst = NULL;
-
- //NOTE: put the rest of this in Config
-
- pGraph->gOptions.bLegendChecked = TRUE;
- pGraph->gOptions.bMenuChecked = TRUE;
- pGraph->gOptions.bLabelsChecked = TRUE;
- pGraph->gOptions.bVertGridChecked = FALSE;
- pGraph->gOptions.bHorzGridChecked = FALSE;
- pGraph->gOptions.bStatusBarChecked = TRUE;
- pGraph->gOptions.GraphVGrid = TRUE;
- pGraph->gOptions.GraphHGrid = TRUE;
- pGraph->gOptions.HistVGrid = TRUE;
- pGraph->gOptions.HistHGrid = TRUE;
-
- pGraph->gOptions.iGraphOrHistogram = LINE_GRAPH; // vs. BAR_GRAPH
- pGraph->gOptions.iVertMax = DEF_GRAPH_VMAX;
-
- return;
- }
-
-
- BOOL InsertGraph (HWND hWnd)
- {
- PGRAPHSTRUCT pGraph;
-
- pGraph = MemoryAllocate (sizeof (GRAPHSTRUCT)) ;
- if (!pGraph)
- return (FALSE) ;
-
-
- pGraphs = pGraph;
-
-
- GetGraphConfig(pGraph);
- pGraph->bManualRefresh = FALSE ;
-
- pGraph->gMaxValues = DEFAULT_MAX_VALUES;
- pGraph->pptDataPoints =
- (PPOINT) MemoryAllocate (sizeof (POINT) * pGraph->gMaxValues) ;
-
- pGraph->pDataTime =
- (SYSTEMTIME *) MemoryAllocate (sizeof(SYSTEMTIME) * pGraph->gMaxValues) ;
-
- pGraph->hWnd = hWnd ;
- pGraph->bModified = FALSE ;
-
- pGraph->Visual.iColorIndex = 0 ;
- pGraph->Visual.iWidthIndex = 0 ;
- pGraph->Visual.iStyleIndex = 0 ;
-
- return(TRUE) ;
- }
-
-
-
- void PlaybackSetGraphLines (HWND hWndChart,
- PLINE pLineFirst,
- int iDisplayTic,
- int iLogTic,
- BOOL CalcData)
- {
- PLINE pLine ;
- FLOAT eValue ;
-
- for (pLine = pLineFirst ;
- pLine ;
- pLine = pLine->pLineNext)
- { // for
- eValue = CounterEntry (pLine) ;
- pLine->lnValues[iDisplayTic] = eValue ;
- pLine->aiLogIndexes[iDisplayTic] = iLogTic ;
-
- // only need to do this on request.
- if (CalcData)
- {
- eUpdateMinMaxAve (eValue, pLine, iDisplayTic, iDisplayTic,
- iDisplayTic, iDisplayTic) ;
- } // if
- } // for
- } // PlaybackSetGraphLines
-
-
-
- BOOL ChartInsertLine (PGRAPHSTRUCT pGraph,
- PLINE pLine)
- /*
- Effect: Insert the line pLine into the graph pGraph and
- allocate space for the graph's number of values.
-
- Returns: Whether the line could be added and space allocated.
-
- See Also: LineAllocate (line.c), ChartDeleteLine.
- */
- { // ChartInsertLine
- PLINE pLineEquivalent ;
- INT i ;
- FLOAT *pTempPts;
- HPEN tempPen ;
-
- pGraph->bModified = TRUE ;
-
- pLineEquivalent = FindEquivalentLine (pLine, pGraph->pLineFirst) ;
- if (pLineEquivalent)
- {
- pLineEquivalent->Visual = pLine->Visual ;
- pLineEquivalent->iScaleIndex = pLine->iScaleIndex ;
- pLineEquivalent->eScale = pLine->eScale ;
-
- tempPen = pLineEquivalent->hPen ;
- pLineEquivalent->hPen = pLine->hPen ;
- pLine->hPen = tempPen ;
- return FALSE ;
- }
- else
- {
- if (!pGraph->pLineFirst && !PlayingBackLog())
- {
- SetGraphTimer (pGraph) ;
- }
-
- if (!SystemAdd (&pGraph->pSystemFirst, pLine->lnSystemName))
- return FALSE;
-
- LineAppend (&pGraph->pLineFirst, pLine) ;
-
- pLine->lnMinValue = FLT_MAX ;
- pLine->lnMaxValue = - FLT_MAX ;
- pLine->lnAveValue = 0.0F ;
- pLine->lnValidValues = 0 ;
-
- pLine->lnValues =
- (FLOAT *) MemoryAllocate (sizeof (FLOAT) * pGraph->gMaxValues) ;
-
- for (i = pGraph->gMaxValues, pTempPts = pLine->lnValues ;
- i > 0 ;
- i-- )
- {
- *pTempPts++ = (FLOAT) 0.0 ;
- }
-
- if (PlayingBackLog ())
- {
- pLine->aiLogIndexes =
- (int *) MemoryAllocate (sizeof (LONG) * pGraph->gMaxValues) ;
- }
-
- // Add the line to the legend, resize the legend window, and then
- // select the new line as the current legend item. Do it in this
- // sequence to avoid the legend scroll bar momentarily appearing and
- // then disappearing, since the resize will obviate the scroll bar.
-
- LegendAddItem (hWndGraphLegend, pLine) ;
-
- if (!bDelayAddAction)
- {
- SizeGraphComponents (hWndGraph) ;
- LegendSetSelection (hWndGraphLegend,
- LegendNumItems (hWndGraphLegend) - 1) ;
-
- if (PlayingBackLog ())
- PlaybackChart (pGraph->hWnd) ;
- }
- }
-
- return (TRUE) ;
- } // ChartInsertLine
-
-
- VOID ChartDeleteLine (PGRAPHSTRUCT pGraph,
- PLINESTRUCT pLine)
- {
- PLINESTRUCT npLine;
-
-
- pGraph->bModified = TRUE ;
-
- if (pGraph->pLineFirst == pLine)
- pGraph->pLineFirst = pLine->pLineNext;
- else
- {
- for (npLine = pGraph->pLineFirst; npLine; npLine = npLine->pLineNext)
- {
- if (npLine->pLineNext == pLine)
- npLine->pLineNext = pLine->pLineNext;
- }
- }
-
- if (!pGraph->pLineFirst)
- {
- ResetGraph (pGraph) ;
- }
- else
- {
- BuildValueListForSystems (
- pGraph->pSystemFirst,
- pGraph->pLineFirst) ;
- }
-
- // Delete the legend entry for this line.
- // If the line was highlighted then this will undo the highlight.
-
- LegendDeleteItem (hWndGraphLegend, pLine) ;
-
- LineFree (pLine) ;
-
- SizeGraphComponents (hWndGraph) ;
-
-
- }
-
-
- FLOAT Counter_Queuelen(PLINESTRUCT pLine)
- {
-
- return((FLOAT)0.0);
- // pLine;
- }
-
-
- void ClearGraphDisplay (PGRAPHSTRUCT pGraph)
- {
- PLINESTRUCT pLine;
-
- // reset the timeline data
- // pGraph->gKnownValue = -1 ;
- pGraph->gKnownValue = 0 ;
- pGraph->gTimeLine.iValidValues = 0 ;
- pGraph->gTimeLine.xLastTime = 0 ;
- memset (pGraph->pDataTime, 0, sizeof(SYSTEMTIME) * pGraph->gMaxValues) ;
-
- // loop through lines,
- // If one of the lines is highlighted then do the calculations
- // for average, min, & max on that line.
-
- for (pLine=pGraph->pLineFirst; pLine; pLine=pLine->pLineNext)
- { // for
-
- pLine->bFirstTime = 2 ;
- pLine->lnMinValue = FLT_MAX ;
- pLine->lnMaxValue = - FLT_MAX ;
- pLine->lnAveValue = 0.0F ;
- pLine->lnValidValues = 0 ;
- memset (pLine->lnValues, 0, sizeof(FLOAT) * pGraph->gMaxValues) ;
- }
-
- StatusTimer (hWndGraphStatus, TRUE) ;
- WindowInvalidate (hWndGraphDisplay) ;
- }
-
- void ResetGraphView (HWND hWndGraph)
- {
- PGRAPHSTRUCT pGraph ;
-
- pGraph = GraphData (hWndGraph) ;
-
-
- if (!pGraph)
- {
- return ;
- }
-
- ChangeSaveFileName (NULL, IDM_VIEWCHART) ;
-
- if (pGraph->pSystemFirst)
- {
- ResetGraph (pGraph) ;
- }
- } // ResetGraphView
-
- void ResetGraph (PGRAPHSTRUCT pGraph)
- {
- ClearGraphTimer (pGraph) ;
- ClearLegend (hWndGraphLegend) ;
- if (pGraph->pLineFirst)
- {
- FreeLines (pGraph->pLineFirst) ;
- pGraph->pLineFirst = NULL ;
- }
-
- if (pGraph->pSystemFirst)
- {
- FreeSystems (pGraph->pSystemFirst) ;
- pGraph->pSystemFirst = NULL ;
- }
- // pGraph->gKnownValue = -1 ;
- pGraph->gKnownValue = 0 ;
- pGraph->gTimeLine.iValidValues = 0 ;
- pGraph->gTimeLine.xLastTime = 0 ;
-
- // reset visual data
- pGraph->Visual.iColorIndex = 0 ;
- pGraph->Visual.iWidthIndex = 0 ;
- pGraph->Visual.iStyleIndex = 0 ;
-
- memset (pGraph->pDataTime, 0, sizeof(SYSTEMTIME) * pGraph->gMaxValues) ;
-
- SizeGraphComponents (hWndGraph) ;
- InvalidateRect(hWndGraph, NULL, TRUE) ;
- }
-
-
-
- void PlaybackChart (HWND hWndChart)
- { // PlaybackChart
- int iDisplayTics ; // num visual points to display
- int iDisplayTic ;
- int iLogTic ;
- int iLogTicsMove ;
- BOOL bFirstTime = TRUE;
- int iLogTicsRemaining ;
-
- if (!pGraphs->pLineFirst)
- {
- // no line to playback
- return ;
- }
-
- iLogTicsRemaining = PlaybackLog.iSelectedTics ;
-
-
- // we only have iDisplayTics-1 points since
- // we have to use the first two sample points to
- // get the first data points.
- if (iLogTicsRemaining <= pGraphs->gMaxValues)
- {
- iDisplayTics = iLogTicsRemaining ;
- pGraphs->gTimeLine.iValidValues = iDisplayTics - 1 ;
- }
- else
- {
- iDisplayTics = pGraphs->gMaxValues ;
- pGraphs->gTimeLine.iValidValues = iDisplayTics ;
- }
-
- iDisplayTic = -1 ;
- iLogTic = PlaybackLog.StartIndexPos.iPosition ;
-
- while (iDisplayTics)
- {
-
- PlaybackLines (pGraphs->pSystemFirst,
- pGraphs->pLineFirst,
- iLogTic) ;
-
- if (bFirstTime)
- {
- bFirstTime = FALSE ;
-
- // get the second sample data to form the first data point
- iLogTic++ ;
- iLogTicsRemaining-- ;
- PlaybackLines (pGraphs->pSystemFirst,
- pGraphs->pLineFirst,
- iLogTic) ;
- }
- iDisplayTic++ ;
- PlaybackSetGraphLines (hWndChart, pGraphs->pLineFirst,
- iDisplayTic, iLogTic, (iDisplayTics == 1)) ;
-
- // setup DDA to get the index of the next sample point
- iLogTicsMove = DDA_DISTRIBUTE (iLogTicsRemaining, iDisplayTics) ;
- iLogTicsRemaining -= iLogTicsMove ;
- iLogTic += iLogTicsMove ;
-
- iDisplayTics-- ;
-
- } // while
-
- // point to the last value for valuebar display
- pGraphs->gKnownValue = iDisplayTic ;
-
- } // PlaybackChart
-
-
-
- #if 0
- PLINESTRUCT CurrentGraphLine (HWND hWndGraph)
- { // CurrentGraphLine
- UNREFERENCED_PARAMETER (hWndGraph) ;
-
- return (LegendCurrentLine (hWndGraphLegend)) ;
- }
- #endif
-
-
- BOOL AddChart (HWND hWndParent)
- {
- PLINE pCurrentLine = CurrentGraphLine (hWndGraph) ;
-
- return (AddLine (hWndParent,
- &(pGraphs->pSystemFirst),
- &(pGraphs->Visual),
- pCurrentLine ? pCurrentLine->lnSystemName : NULL,
- LineTypeChart)) ;
- }
-
-
- BOOL EditChart (HWND hWndParent)
- { // EditChart
- return (EditLine (hWndParent,
- &(pGraphs->pSystemFirst),
- CurrentGraphLine (hWndGraph),
- LineTypeChart)) ;
- }
-
- void GraphAddAction ()
- {
- PGRAPHSTRUCT pGraph ;
-
- pGraph = GraphData (hWndGraph) ;
-
- SizeGraphComponents (hWndGraph) ;
-
- LegendSetSelection (hWndGraphLegend,
- LegendNumItems (hWndGraphLegend) - 1) ;
-
- if (PlayingBackLog ())
- PlaybackChart (pGraph->hWnd) ;
- }
-
- BOOL OpenChartVer1 (HANDLE hFile,
- DISKCHART *pDiskChart,
- PGRAPHSTRUCT pGraph)
- { // OpenChartVer1
- bDelayAddAction = TRUE ;
- pGraph->Visual = pDiskChart->Visual ;
- pGraph->gOptions = pDiskChart->gOptions ;
- pGraph->gMaxValues = pDiskChart->gMaxValues ;
- pGraph->bManualRefresh = pDiskChart->bManualRefresh ;
- pGraphs->gInterval = (INT) (pGraph->gOptions.eTimeInterval * (FLOAT) 1000.0) ;
- ReadLines (hFile, pDiskChart->dwNumLines,
- &(pGraph->pSystemFirst), &(pGraph->pLineFirst), IDM_VIEWCHART) ;
-
- bDelayAddAction = FALSE ;
-
- GraphAddAction () ;
-
- return (TRUE) ;
- } // OpenChartVer1
-
-
-
- BOOL OpenChart (HWND hWndGraph,
- HANDLE hFile,
- DWORD dwMajorVersion,
- DWORD dwMinorVersion,
- BOOL bChartFile)
- { // OpenChart
- PGRAPHSTRUCT pGraph ;
- DISKCHART DiskChart ;
- BOOL bSuccess = TRUE ;
-
- pGraph = pGraphs ;
- if (!pGraph)
- {
- bSuccess = FALSE ;
- goto Exit0 ;
- }
-
- if (!FileRead (hFile, &DiskChart, sizeof (DISKCHART)))
- {
- bSuccess = FALSE ;
- goto Exit0 ;
- }
-
-
- switch (dwMajorVersion)
- {
- case (1):
-
- SetHourglassCursor() ;
-
- ResetGraphView (hWndGraph) ;
-
- OpenChartVer1 (hFile, &DiskChart, pGraph) ;
-
- // change to chart view if we are opening a
- // chart file
- if (bChartFile && iPerfmonView != IDM_VIEWCHART)
- {
- SendMessage (hWndMain, WM_COMMAND, (LONG)IDM_VIEWCHART, 0L) ;
- }
-
- if (iPerfmonView == IDM_VIEWCHART)
- {
- SetPerfmonOptions (&DiskChart.perfmonOptions) ;
- }
-
- SetArrowCursor() ;
-
- break ;
- } // switch
-
- Exit0:
-
- if (bChartFile)
- {
- CloseHandle (hFile) ;
- }
-
- return (bSuccess) ;
- } // OpenChart
-
- BOOL SaveChart (HWND hWndGraph, HANDLE hInputFile, BOOL bGetFileName)
- {
- PGRAPHSTRUCT pGraph ;
- PLINE pLine ;
- HANDLE hFile ;
- DISKCHART DiskChart ;
- PERFFILEHEADER FileHeader ;
- TCHAR szFileName [256] ;
- BOOL newFileName = FALSE ;
-
- if (hInputFile)
- {
- // use the input file handle if it is available
- // this is the case for saving workspace data
- hFile = hInputFile ;
- }
- else
- {
- if (pChartFullFileName)
- {
- lstrcpy (szFileName, pChartFullFileName) ;
- }
- if (bGetFileName || pChartFullFileName == NULL)
- {
- // if (!pChartFullFileName)
- // {
- // StringLoad (IDS_GRAPH_FNAME, szFileName) ;
- // }
-
- if (!FileGetName (hWndGraph, IDS_CHARTFILE, szFileName))
- {
- return (FALSE) ;
- }
- newFileName = TRUE ;
- }
-
- hFile = FileHandleCreate (szFileName) ;
-
- if (hFile && newFileName)
- {
- ChangeSaveFileName (szFileName, IDM_VIEWCHART) ;
- }
- else if (!hFile)
- {
- DlgErrorBox (hWndGraph, ERR_CANT_OPEN, szFileName) ;
- }
- }
-
- if (!hFile)
- return (FALSE) ;
-
- pGraph = pGraphs ;
- if (!pGraph)
- {
- if (!hInputFile)
- {
- CloseHandle (hFile) ;
- }
- return (FALSE) ;
- }
-
- if (!hInputFile)
- {
- // only need to write file header if not workspace
- memset (&FileHeader, 0, sizeof (FileHeader)) ;
- lstrcpy (FileHeader.szSignature, szPerfChartSignature) ;
- FileHeader.dwMajorVersion = ChartMajorVersion ;
- FileHeader.dwMinorVersion = ChartMinorVersion ;
-
- if (!FileWrite (hFile, &FileHeader, sizeof (PERFFILEHEADER)))
- {
- goto Exit0 ;
- }
- }
-
- DiskChart.Visual = pGraph->Visual ;
- DiskChart.gOptions = pGraph->gOptions ;
- DiskChart.gMaxValues = pGraph->gMaxValues ;
- DiskChart.dwNumLines = NumLines (pGraph->pLineFirst) ;
- DiskChart.bManualRefresh = pGraph->bManualRefresh ;
- DiskChart.perfmonOptions = Options ;
-
- if (!FileWrite (hFile, &DiskChart, sizeof (DISKCHART)))
- {
- goto Exit0 ;
- }
-
- for (pLine = pGraph->pLineFirst ;
- pLine ;
- pLine = pLine->pLineNext)
- { // for
- if (!WriteLine (pLine, hFile))
- {
- goto Exit0 ;
- }
- } // for
-
- if (!hInputFile)
- {
- CloseHandle (hFile) ;
- }
-
- return (TRUE) ;
-
- Exit0:
- if (!hInputFile)
- {
- CloseHandle (hFile) ;
-
- // only need to report error if not workspace
- DlgErrorBox (hWndGraph, ERR_SETTING_FILE, szFileName) ;
- }
- return (FALSE) ;
-
- } // SaveChart
-
- #define TIME_TO_WRITE 2
- BOOL ExportChartLabels (HANDLE hFile, PGRAPHSTRUCT pGraph)
- {
- TCHAR UnicodeBuff [LongTextLen] ;
- CHAR TempBuff [LongTextLen * 2] ;
- int StringLen ;
- PLINESTRUCT pLine;
- int TimeToWriteFile ;
- int iIndex ;
- LPTSTR lpItem ;
-
- for (iIndex = 0 ; iIndex < 5 ; iIndex++)
- {
- // for iIndex == 0, get counter name
- // for iIndex == 1, get instance name
- // for iIndex == 2, get parent name
- // for iIndex == 3, get object name
- // for iIndex == 4, get computer name
- if (iIndex == 4)
- {
- // the last label field, write date/time labels
- strcpy (TempBuff, LineEndStr) ;
- StringLen = strlen (TempBuff) ;
- StringLoad (IDS_EXPORT_DATE, UnicodeBuff) ;
- ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
- strcat (TempBuff, pDelimiter) ;
- StringLen = strlen (TempBuff) ;
-
- StringLoad (IDS_EXPORT_TIME, UnicodeBuff) ;
- ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
- strcat (TempBuff, pDelimiter) ;
- StringLen = strlen (TempBuff) ;
- }
- else
- {
- strcpy (TempBuff, LineEndStr) ;
- strcat (TempBuff, pDelimiter) ;
- strcat (TempBuff, pDelimiter) ;
- StringLen = strlen (TempBuff) ;
- }
-
- TimeToWriteFile = 0 ;
-
- for (pLine=pGraph->pLineFirst; pLine; pLine=pLine->pLineNext)
- {
- switch (iIndex)
- {
- case 0:
- lpItem = (LPTSTR) pLine->lnCounterName ;
- break ;
-
- case 1:
- lpItem = (LPTSTR) pLine->lnInstanceName ;
- break ;
-
- case 2:
- lpItem = (LPTSTR) pLine->lnPINName ;
- break ;
-
- case 3:
- lpItem = (LPTSTR) pLine->lnObjectName ;
- break ;
-
- case 4:
- lpItem = (LPTSTR) pLine->lnSystemName ;
- break ;
- }
-
- if (lpItem)
- {
- ConvertUnicodeStr (&TempBuff[StringLen], lpItem) ;
- }
- else
- {
- TempBuff[StringLen] = '\0' ;
- }
- strcat (TempBuff, pDelimiter);
- StringLen = strlen (TempBuff) ;
-
- if (++TimeToWriteFile > TIME_TO_WRITE)
- {
- // better write the buffers before they overflow.
- // there are better ways to check for overflow
- // but this is good enough
-
- if (!FileWrite (hFile, TempBuff, StringLen))
- {
- goto Exit0 ;
- }
- StringLen = TimeToWriteFile = 0 ;
- }
- } // for each line
-
- if (StringLen)
- {
- // write the last block of data
- if (!FileWrite (hFile, TempBuff, StringLen))
- {
- goto Exit0 ;
- }
- }
- } // for iIndex
-
- return (TRUE) ;
-
- Exit0:
- return (FALSE) ;
-
- } // ExportChartLabels
-
- BOOL ExportLogChart (HANDLE hFile, PGRAPHSTRUCT pGraph)
- {
- TCHAR UnicodeBuff [LongTextLen] ;
- CHAR TempBuff [LongTextLen * 2] ;
- int StringLen ;
- PLINESTRUCT pLine;
- int TimeToWriteFile ;
- FLOAT eValue ;
- int iLogTic ;
- BOOL bFirstTime = TRUE ;
- SYSTEMTIME LogSystemTime ;
- LOGPOSITION LogPosition ;
-
- iLogTic = PlaybackLog.StartIndexPos.iPosition ;
-
- // we have to export every point from the log file
-
- for ( ; iLogTic <= PlaybackLog.StopIndexPos.iPosition ; iLogTic++)
- {
-
- PlaybackLines (pGraphs->pSystemFirst,
- pGraphs->pLineFirst,
- iLogTic) ;
-
- if (!bFirstTime)
- {
- // export the values
- TimeToWriteFile = 0 ;
-
-
- if (!LogPositionN (iLogTic, &LogPosition))
- {
- goto Exit0 ;
- }
-
- LogPositionSystemTime (&LogPosition, &LogSystemTime) ;
-
- strcpy (TempBuff, LineEndStr) ;
- StringLen = strlen (TempBuff) ;
-
- SystemTimeDateString (&LogSystemTime, UnicodeBuff) ;
- ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
- strcat (TempBuff, pDelimiter) ;
- StringLen = strlen (TempBuff) ;
-
- SystemTimeTimeString (&LogSystemTime, UnicodeBuff, FALSE) ;
- ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
- strcat (TempBuff, pDelimiter) ;
- StringLen = strlen (TempBuff) ;
-
- for (pLine=pGraph->pLineFirst; pLine; pLine=pLine->pLineNext)
- {
-
- eValue = CounterEntry (pLine) ;
-
- TSPRINTF (UnicodeBuff,
- eValue > (FLOAT)999999.0 ?
- szLargeValueFormat : szSmallValueFormat,
- eValue) ;
- ConvertDecimalPoint (UnicodeBuff) ;
- ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
- strcat (TempBuff, pDelimiter) ;
- StringLen = strlen (TempBuff) ;
-
- if (++TimeToWriteFile > TIME_TO_WRITE)
- {
- if (!FileWrite (hFile, TempBuff, StringLen))
- {
- goto Exit0 ;
- }
- StringLen = TimeToWriteFile = 0 ;
- TempBuff[0] = '\0' ;
- }
- }
-
- if (StringLen)
- {
- if (!FileWrite (hFile, TempBuff, StringLen))
- {
- goto Exit0 ;
- }
- }
- }
- else
- {
- // skip the first data point since we
- // need 2 points to form the first value
- bFirstTime = FALSE ;
- }
- }
-
- return (TRUE) ;
-
- Exit0:
- return (FALSE) ;
-
- } // ExportLogChart
-
- BOOL ExportLineValue (HANDLE hFile, PGRAPHSTRUCT pGraph,
- int CurrentIndex, int iDataPoint)
- {
- TCHAR UnicodeBuff [MiscTextLen] ;
- CHAR TempBuff [LongTextLen] ;
- int StringLen ;
- PLINESTRUCT pLine;
- int MaxValues ;
- int TimeToWriteFile ;
- SYSTEMTIME *pSystemTime ;
- BOOL ValidValue ;
-
- pSystemTime = pGraph->pDataTime ;
- pSystemTime += CurrentIndex ;
-
- if (pSystemTime->wYear == 0 && pSystemTime->wYear == 0)
- {
- // ignore value that has 0 system time
- return (TRUE) ;
- }
-
- MaxValues = pGraph->gMaxValues ;
- strcpy (TempBuff, LineEndStr) ;
- StringLen = strlen (TempBuff) ;
-
- SystemTimeDateString (pSystemTime, UnicodeBuff) ;
- ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
- strcat (TempBuff, pDelimiter) ;
- StringLen = strlen (TempBuff) ;
-
- SystemTimeTimeString (pSystemTime, UnicodeBuff, FALSE) ;
- ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
- strcat (TempBuff, pDelimiter) ;
- StringLen = strlen (TempBuff) ;
-
- TimeToWriteFile = 0 ;
- for (pLine=pGraph->pLineFirst; pLine; pLine=pLine->pLineNext)
- {
- if (!pLine->bFirstTime)
- {
- ValidValue = FALSE ;
- // check if this is a valid value
- if (pLine->lnValidValues == MaxValues)
- {
- // this is the simple case where we have filled up
- // the whole buffer
- ValidValue = TRUE ;
- }
- else if (pLine->lnValidValues <= iDataPoint)
- {
- if (CurrentIndex <= iDataPoint &&
- CurrentIndex > iDataPoint - pLine->lnValidValues)
- {
- ValidValue = TRUE ;
- }
- }
- else
- {
- if (CurrentIndex <= iDataPoint ||
- CurrentIndex > (MaxValues - pLine->lnValidValues + iDataPoint))
- {
- // this is the case when we start the new line in the middle
- // and data buffer has been wrap-around.
- ValidValue = TRUE ;
- }
- }
-
- // only export the data when we determine it is valid
- if (ValidValue)
- {
- TSPRINTF (UnicodeBuff,
- pLine->lnValues[CurrentIndex] > (FLOAT)999999.0 ?
- szLargeValueFormat : szSmallValueFormat,
- pLine->lnValues[CurrentIndex]) ;
- ConvertDecimalPoint (UnicodeBuff) ;
- ConvertUnicodeStr (&TempBuff[StringLen], UnicodeBuff) ;
- }
- }
- strcat (TempBuff, pDelimiter) ;
- StringLen = strlen (TempBuff) ;
-
- if (++TimeToWriteFile > TIME_TO_WRITE)
- {
- // better write the buffers before they overflow.
- // there are better ways to check for overflow
- // but this is good enough
-
- if (!FileWrite (hFile, TempBuff, StringLen))
- {
- goto Exit0 ;
- }
- StringLen = TimeToWriteFile = 0 ;
- TempBuff[0] = '\0' ;
- }
- }
-
- if (StringLen)
- {
- // write the last block of data
- if (!FileWrite (hFile, TempBuff, StringLen))
- {
- goto Exit0 ;
- }
- }
-
- return (TRUE) ;
-
- Exit0:
- return (FALSE) ;
-
- } // ExportLineValue
-
- BOOL ExportCurrentChart (HANDLE hFile, PGRAPHSTRUCT pGraph)
- {
- int KnownValue,
- MaxValues,
- iValidValues,
- iDataPoint ;
- BOOL SimpleCase = FALSE ;
- int iIndex ;
-
- MaxValues = pGraph->gMaxValues ;
- KnownValue = pGraph->gKnownValue ;
- iValidValues = pGraph->gTimeLine.iValidValues ;
-
- if (iValidValues < MaxValues)
- {
- // data have not wrapped around, so the oldest time
- // is started at 0.
- SimpleCase = TRUE ;
- iValidValues = (KnownValue % MaxValues) + 1 ;
- }
-
- iDataPoint = KnownValue % MaxValues ;
-
- if (!SimpleCase)
- {
- for (iIndex = iDataPoint+1 ; iIndex < MaxValues ; iIndex++)
- {
- if (!ExportLineValue (hFile, pGraph, iIndex, iDataPoint))
- {
- goto Exit0 ;
- }
- }
- }
-
- for (iIndex = 0 ; iIndex <= iDataPoint ; iIndex++)
- {
- if (!ExportLineValue (hFile, pGraph, iIndex, iDataPoint))
- {
- goto Exit0 ;
- }
- }
-
- return (TRUE) ;
-
- Exit0:
- return (FALSE) ;
-
- } // ExportCurrentChart
-
-
- void ExportChart (void)
- {
-
- PGRAPHSTRUCT pGraph ;
- HANDLE hFile = 0 ;
- LPTSTR pFileName = NULL ;
- INT ErrCode = 0 ;
-
- if (!(pGraph = pGraphs))
- {
- return ;
- }
-
- // see if there is anything to export..
- if (!(pGraph->pLineFirst))
- {
- return ;
- }
-
- SetHourglassCursor() ;
-
- if (ErrCode = ExportFileOpen (hWndGraph, &hFile, pGraph->gInterval, &pFileName))
- {
- goto Exit0 ;
- }
-
- if (!pFileName)
- {
- // this is the case when user cancel.
- goto Exit0 ;
- }
-
- // export the column labels
- if (!ExportChartLabels (hFile, pGraph))
- {
-
- ErrCode = ERR_EXPORT_FILE ;
- goto Exit0 ;
- }
-
- // export the lines
- if (PlayingBackLog())
- {
- if (!ExportLogChart (hFile, pGraph))
- {
- ErrCode = ERR_EXPORT_FILE ;
- goto Exit0 ;
- }
- }
- else
- {
- if (!ExportCurrentChart (hFile, pGraph))
- {
- ErrCode = ERR_EXPORT_FILE ;
- goto Exit0 ;
- }
- }
- Exit0:
-
- SetArrowCursor() ;
-
- if (hFile)
- {
- CloseHandle (hFile) ;
- }
-
- if (pFileName)
- {
- if (ErrCode)
- {
- DlgErrorBox (hWndGraph, ErrCode, pFileName) ;
- }
-
- MemoryFree (pFileName) ;
- }
-
- } // ExportChart
-
-
- typedef struct CHARTDATAPOINTSTRUCT
- {
- int iLogIndex ;
- int xDispDataPoint ;
- } CHARTDATAPOINT, *PCHARTDATAPOINT ;
-
- void PlaybackChartDataPoint (PCHARTDATAPOINT pChartDataPoint)
- { // PlaybackChartDataPoint
- int iDisplayTics ; // num visual points to display
- int iDisplayTic ;
- int iLogTic ;
- int iLogTicsMove ;
- BOOL bFirstTime = TRUE;
- int iLogTicsRemaining ;
- int numOfData, xDispDataPoint, rectWidth, xPos ;
- PGRAPHSTRUCT pGraph ;
-
- pGraph = GraphData (hWndGraph) ;
-
- iLogTicsRemaining = PlaybackLog.iSelectedTics ;
-
-
- // we only have iDisplayTics-1 points since
- // we have to use the first two sample points to
- // get the first data points.
- if (iLogTicsRemaining <= pGraphs->gMaxValues)
- {
- iDisplayTics = iLogTicsRemaining ;
- }
- else
- {
- iDisplayTics = pGraphs->gMaxValues ;
- }
-
- iDisplayTic = -1 ;
- iLogTic = PlaybackLog.StartIndexPos.iPosition ;
-
- numOfData = pGraph->gMaxValues - 1 ;
- rectWidth = pGraph->rectData.right - pGraph->rectData.left ;
- xDispDataPoint = pGraph->rectData.left ;
-
- while (iDisplayTics && numOfData)
- {
-
- if (!bFirstTime)
- {
- iDisplayTic++ ;
- }
- else
- {
- bFirstTime = FALSE ;
-
- // get the second sample data to form the first data point
- iLogTic++ ;
- iLogTicsRemaining-- ;
-
- iDisplayTic++ ;
- }
-
- pChartDataPoint[iDisplayTic].iLogIndex = iLogTic ;
- pChartDataPoint[iDisplayTic].xDispDataPoint = xDispDataPoint ;
-
- // setup DDA to get the index of the next sample point
- iLogTicsMove = DDA_DISTRIBUTE (iLogTicsRemaining, iDisplayTics) ;
- iLogTicsRemaining -= iLogTicsMove ;
- iLogTic += iLogTicsMove ;
-
-
- xPos = DDA_DISTRIBUTE (rectWidth, numOfData) ;
- xDispDataPoint += xPos ;
- numOfData-- ;
- rectWidth -= xPos ;
-
- iDisplayTics-- ;
-
- } // while
-
- } // PlaybackChartDataPoint
-