/*++ 

Copyright (c) 1997-1998 Microsoft Corporation

Module Name:

    datats.c

Abstract:
       
    Constant data structures used by the Performance Monitor data for the
    Terminal Server User and WinStation performance data objects

Created:

    Erik Mavrinac  25-Nov-1998

Revision History:

    30-Mar-1998 - Last revision of original Terminal Server 4.0
                  counter code base.

--*/

#include <windows.h>
#include <winperf.h>
#include <ntprfctr.h>
#include <perfutil.h>
#include "datats.h"


// Dummy variables for field sizing.
static PROCESS_COUNTER_DATA pcd;
static WINSTATION_COUNTER_DATA wsd;


//
// We need to define our own counter for ThinWire display.
//

#define PERF_COUNTER_TS_PERCENT        \
            (PERF_SIZE_DWORD | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL |\
             PERF_DISPLAY_NO_SUFFIX)


// Default TS scaling factor for the raw counts.
#define TS_SCALE_FACTOR   (-10000)


#define FIELDSIZE(type, field)   (sizeof(((type *)1)->field))
#define FIELDOFFSET(type, field) ((UINT_PTR)(&((type *)0)->field))


// Note that we set the counter names and descriptions as the offset counters
// from tslabels.h. Later when we load we will read the registry start offset
// and add it into each of the slots below to create the resulting
// real indices. See tslbl009.ini for descriptions.
WINSTATION_DATA_DEFINITION WinStationDataDefinition =
{
    {   sizeof(WINSTATION_DATA_DEFINITION) + sizeof(WINSTATION_COUNTER_DATA),
        sizeof(WINSTATION_DATA_DEFINITION),
        sizeof(PERF_OBJECT_TYPE),
        WINSTATION_OBJECT,
        0,
        WINSTATION_OBJECT + 1,
        0,
        PERF_DETAIL_NOVICE,
        (sizeof(WINSTATION_DATA_DEFINITION) - sizeof(PERF_OBJECT_TYPE)) / 
            sizeof(PERF_COUNTER_DEFINITION),
        0,
        0,
        UNICODE_CODE_PAGE,
        {0L,0L},
        {10000000L,0L}
    },

    // Process counters totaled on a per-WinStation basis.
    {   sizeof(PERF_COUNTER_DEFINITION),
        6,
        0,
        189,
        0,
        0,
        PERF_DETAIL_NOVICE,
        PERF_100NSEC_TIMER,
        FIELDSIZE(WINSTATION_COUNTER_DATA, pcd.ProcessorTime),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, pcd.ProcessorTime)
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        142,
        0,
        157,
        0,
        0,
        PERF_DETAIL_ADVANCED,
        PERF_100NSEC_TIMER,
        FIELDSIZE(WINSTATION_COUNTER_DATA, pcd.UserTime),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, pcd.UserTime)
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        144,
        0,
        159,
        0,
        0,
        PERF_DETAIL_ADVANCED,
        PERF_100NSEC_TIMER,
        FIELDSIZE(WINSTATION_COUNTER_DATA, pcd.KernelTime),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, pcd.KernelTime)
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        172,
        0,
        173,
        0,
        -6,
        PERF_DETAIL_EXPERT,
        PERF_COUNTER_LARGE_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, pcd.PeakVirtualSize),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, pcd.PeakVirtualSize)
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        174,
        0,
        175,
        0,
        -6,
        PERF_DETAIL_EXPERT,
        PERF_COUNTER_LARGE_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, pcd.VirtualSize),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, pcd.VirtualSize)
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        28,
        0,
        177,
        0,
        -1,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_COUNTER,
        FIELDSIZE(WINSTATION_COUNTER_DATA, pcd.PageFaults),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, pcd.PageFaults)
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        178,
        0,
        179,
        0,
        -5,
        PERF_DETAIL_ADVANCED,
        PERF_COUNTER_LARGE_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, pcd.PeakWorkingSet),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, pcd.PeakWorkingSet)
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        180,
        0,
        181,
        0,
        -5,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_LARGE_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, pcd.TotalWorkingSet),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, pcd.TotalWorkingSet)
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        182,
        0,
        183,
        0,
        -6,
        PERF_DETAIL_ADVANCED,
        PERF_COUNTER_LARGE_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, pcd.PeakPageFile),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, pcd.PeakPageFile)
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        184,
        0,
        185,
        0,
        -6,
        PERF_DETAIL_ADVANCED,
        PERF_COUNTER_LARGE_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, pcd.PageFile),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, pcd.PageFile)
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        186,
        0,
        187,
        0,
        -5,
        PERF_DETAIL_ADVANCED,
        PERF_COUNTER_LARGE_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, pcd.PrivatePages),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, pcd.PrivatePages)
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        680,
        0,
        681,
        0,
        0,
        PERF_DETAIL_ADVANCED,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, pcd.ThreadCount),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, pcd.ThreadCount)
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        56,
        0,
        57,
        0,
        -5,
        PERF_DETAIL_ADVANCED,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, pcd.PagedPool),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, pcd.PagedPool)
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        58,
        0,
        59,
        0,
        -5,
        PERF_DETAIL_ADVANCED,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, pcd.NonPagedPool),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, pcd.NonPagedPool)
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        952,
        0,
        953,
        0,
        0,
        PERF_DETAIL_ADVANCED,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, pcd.HandleCount),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, pcd.HandleCount)
    },


    // Input counters for WinStation protocols

    {   sizeof(PERF_COUNTER_DEFINITION),
        INWDBYTES,
        0,
        INWDBYTES + 1,
        0,
        -2,  // scale
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_COUNTER,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Input.WdBytes),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Input.WdBytes),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        INWDFRAMES,
        0,
        INWDFRAMES + 1,
        0,
        0, // no scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_COUNTER,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Input.WdFrames),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Input.WdFrames),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        INWAITFOROUTBUF,
        0,
        INWAITFOROUTBUF + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Input.WaitForOutBuf),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Input.WaitForOutBuf),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        INFRAMES,
        0,
        INFRAMES + 1,
        0,
        0, // no scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_COUNTER,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Input.Frames),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Input.Frames),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        INBYTES,
        0,
        INBYTES + 1,
        0,
        -2,  // scale
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_COUNTER,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Input.Bytes),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Input.Bytes),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        INCOMPBYTES,
        0,
        INCOMPBYTES + 1,
        0,
        -2,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_COUNTER,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Input.CompressedBytes),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA,
            Input.CompressedBytes),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        INCOMPFLUSHES,
        0,
        INCOMPFLUSHES + 1,
        0,
        -2,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Input.CompressFlushes),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA,
            Input.CompressFlushes),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        INERRORS,
        0,
        INERRORS + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Input.Errors),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Input.Errors),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        INTIMEOUTS,
        0,
        INTIMEOUTS + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Input.Timeouts),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Input.Timeouts),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        INASYNCFRAMEERR,
        0,
        INASYNCFRAMEERR + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Input.AsyncFramingError),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Input.AsyncFramingError),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        INASYNCOVERRUN,
        0,
        INASYNCOVERRUN + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Input.AsyncOverrunError),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Input.AsyncOverrunError),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        INASYNCOVERFLOW,
        0,
        INASYNCOVERFLOW + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Input.AsyncOverflowError),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Input.AsyncOverflowError),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        INASYNCPARITY,
        0,
        INASYNCPARITY + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Input.AsyncParityError),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Input.AsyncParityError),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        INTDERRORS,
        0,
        INTDERRORS + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Input.TdErrors),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Input.TdErrors),
    },


    // Output counters for WinStation protocols

    {   sizeof(PERF_COUNTER_DEFINITION),
        OUTWDBYTES,
        0,
        OUTWDBYTES + 1,
        0,
        -2,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_COUNTER,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Output.WdBytes),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Output.WdBytes),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        OUTWDFRAMES,
        0,
        OUTWDFRAMES + 1,
        0,
        0, // no scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_COUNTER,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Output.WdFrames),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Output.WdFrames),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        OUTWAITFOROUTBUF,
        0,
        OUTWAITFOROUTBUF + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Output.WaitForOutBuf),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Output.WaitForOutBuf),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        OUTFRAMES,
        0,
        OUTFRAMES + 1,
        0,
        0, // no scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_COUNTER,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Output.Frames),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Output.Frames),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        OUTBYTES,
        0,
        OUTBYTES + 1,
        0,
        -2,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_COUNTER,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Output.Bytes),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Output.Bytes),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        OUTCOMPBYTES,
        0,
        OUTCOMPBYTES + 1,
        0,
        -2,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_COUNTER,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Output.CompressedBytes),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Output.CompressedBytes),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        OUTCOMPFLUSHES,
        0,
        OUTCOMPFLUSHES + 1,
        0,
        -2,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Output.CompressFlushes),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Output.CompressFlushes),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        OUTERRORS,
        0,
        OUTERRORS + 1,
        0,
        -2,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Output.Errors),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Output.Errors),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        OUTTIMEOUTS,
        0,
        OUTTIMEOUTS + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Output.Timeouts),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Output.Timeouts),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        OUTASYNCFRAMEERR,
        0,
        OUTASYNCFRAMEERR + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Output.AsyncFramingError),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Output.AsyncFramingError),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        OUTASYNCOVERRUN,
        0,
        OUTASYNCOVERRUN + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Output.AsyncOverrunError),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Output.AsyncOverrunError),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        OUTASYNCOVERFLOW,
        0,
        OUTASYNCOVERFLOW + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Output.AsyncOverflowError),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Output.AsyncOverflowError),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        OUTASYNCPARITY,
        0,
        OUTASYNCPARITY + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Output.AsyncParityError),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Output.AsyncParityError),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        OUTTDERRORS,
        0,
        OUTTDERRORS + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Output.TdErrors),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Output.TdErrors),
    },


    // Totals counters

    {   sizeof(PERF_COUNTER_DEFINITION),
        TOTALWDBYTES,
        0,
        TOTALWDBYTES + 1,
        0,
        -2,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_COUNTER,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Total.WdBytes),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Total.WdBytes),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        TOTALWDFRAMES,
        0,
        TOTALWDFRAMES + 1,
        0,
        0, // no scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_COUNTER,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Total.WdFrames),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Total.WdFrames),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        TOTALWAITFOROUTBUF,
        0,
        TOTALWAITFOROUTBUF + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Total.WaitForOutBuf),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Total.WaitForOutBuf),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        TOTALFRAMES,
        0,
        TOTALFRAMES + 1,
        0,
        0, // no scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_COUNTER,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Total.Frames),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Total.Frames),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        TOTALBYTES,
        0,
        TOTALBYTES + 1,
        0,
        -2,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_COUNTER,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Total.Bytes),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Total.Bytes),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        TOTALCOMPBYTES,
        0,
        TOTALCOMPBYTES + 1,
        0,
        -2,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_COUNTER,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Total.CompressedBytes),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Total.CompressedBytes),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        TOTALCOMPFLUSHES,
        0,
        TOTALCOMPFLUSHES + 1,
        0,
        -2,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Total.CompressFlushes),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Total.CompressFlushes),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        TOTALERRORS,
        0,
        TOTALERRORS + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Total.Errors),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Total.Errors),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        TOTALTIMEOUTS,
        0,
        TOTALTIMEOUTS + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Total.Timeouts),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Total.Timeouts),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        TOTALASYNCFRAMEERR,
        0,
        TOTALASYNCFRAMEERR + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Total.AsyncFramingError),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Total.AsyncFramingError),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        TOTALASYNCOVERRUN,
        0,
        TOTALASYNCOVERRUN + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Total.AsyncOverrunError),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Total.AsyncOverrunError),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        TOTALASYNCOVERFLOW,
        0,
        TOTALASYNCOVERFLOW + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Total.AsyncOverflowError),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Total.AsyncOverflowError),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        TOTALASYNCPARITY,
        0,
        TOTALASYNCPARITY + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Total.AsyncParityError),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Total.AsyncParityError),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        TOTALTDERRORS,
        0,
        TOTALTDERRORS + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, Total.TdErrors),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, Total.TdErrors),
    },


    // Display driver statistics -- these are set up the same way for
    // both ICA and RDP.
    {   sizeof(PERF_COUNTER_DEFINITION),
        DDCACHEREAD,
        0,
        DDCACHEREAD + 1,
        0,
        TS_SCALE_FACTOR,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, DDTotal.CacheReads),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, DDTotal.CacheReads),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        DDCACHEHIT,
        0,
        DDCACHEHIT + 1,
        0,
        TS_SCALE_FACTOR,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, DDTotal.CacheHits),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, DDTotal.CacheHits),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        DDCACHEPERCENT,
        0,
        DDCACHEPERCENT + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_TS_PERCENT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, DDTotal.HitRatio),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, DDTotal.HitRatio),
    },


    // Bitmap cache

    {   sizeof(PERF_COUNTER_DEFINITION),
        DDBITMAPCACHEREAD,
        0,
        DDBITMAPCACHEREAD + 1,
        0,
        TS_SCALE_FACTOR,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, DDBitmap.CacheReads),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, DDBitmap.CacheReads),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        DDBITMAPCACHEHIT,
        0,
        DDBITMAPCACHEHIT + 1,
        0,
        TS_SCALE_FACTOR,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, DDBitmap.CacheHits),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, DDBitmap.CacheHits),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        DDBITMAPCACHEPERCENT,
        0,
        DDBITMAPCACHEPERCENT + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_TS_PERCENT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, DDBitmap.HitRatio),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, DDBitmap.HitRatio),
    },

    // Glyph cache

    {   sizeof(PERF_COUNTER_DEFINITION),
        DDGLYPHCACHEREAD,
        0,
        DDGLYPHCACHEREAD + 1,
        0,
        TS_SCALE_FACTOR,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, DDGlyph.CacheReads),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, DDGlyph.CacheReads),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        DDGLYPHCACHEHIT,
        0,
        DDGLYPHCACHEHIT + 1,
        0,
        TS_SCALE_FACTOR,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, DDGlyph.CacheHits),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, DDGlyph.CacheHits),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        DDGLYPHCACHEPERCENT,
        0,
        DDGLYPHCACHEPERCENT + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_TS_PERCENT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, DDGlyph.HitRatio),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, DDGlyph.HitRatio),
    },

    // Brush cache

    {   sizeof(PERF_COUNTER_DEFINITION),
        DDBRUSHCACHEREAD,
        0,
        DDBRUSHCACHEREAD + 1,
        0,
        TS_SCALE_FACTOR,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, DDBrush.CacheReads),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, DDBrush.CacheReads),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        DDBRUSHCACHEHIT,
        0,
        DDBRUSHCACHEHIT + 1,
        0,
        TS_SCALE_FACTOR,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, DDBrush.CacheHits),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, DDBrush.CacheHits),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        DDBRUSHCACHEPERCENT,
        0,
        DDBRUSHCACHEPERCENT + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_TS_PERCENT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, DDBrush.HitRatio),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, DDBrush.HitRatio),
    },

    // Save screen bitmap cache

    {   sizeof(PERF_COUNTER_DEFINITION),
        DDSAVESCRCACHEREAD,
        0,
        DDSAVESCRCACHEREAD + 1,
        0,
        TS_SCALE_FACTOR,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, DDSaveScr.CacheReads),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, DDSaveScr.CacheReads),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        DDSAVESCRCACHEHIT,
        0,
        DDSAVESCRCACHEHIT + 1,
        0,
        TS_SCALE_FACTOR,
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, DDSaveScr.CacheHits),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, DDSaveScr.CacheHits),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        DDSAVESCRCACHEPERCENT,
        0,
        DDSAVESCRCACHEPERCENT + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_TS_PERCENT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, DDSaveScr.HitRatio),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, DDSaveScr.HitRatio),
    },


    // Compression ratios

    {   sizeof(PERF_COUNTER_DEFINITION),
        INCOMPRESS_PERCENT,
        0,
        INCOMPRESS_PERCENT + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_TS_PERCENT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, InputCompressionRatio),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, InputCompressionRatio),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        OUTCOMPRESS_PERCENT,
        0,
        OUTCOMPRESS_PERCENT + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_TS_PERCENT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, OutputCompressionRatio),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, OutputCompressionRatio),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        TOTALCOMPRESS_PERCENT,
        0,
        TOTALCOMPRESS_PERCENT + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_TS_PERCENT,
        FIELDSIZE(WINSTATION_COUNTER_DATA, TotalCompressionRatio),
        (DWORD)FIELDOFFSET(WINSTATION_COUNTER_DATA, TotalCompressionRatio),
    },
};



// Counter descriptions for overall data.
TERMSERVER_DATA_DEFINITION TermServerDataDefinition =
{
    {   sizeof(TERMSERVER_DATA_DEFINITION) + sizeof(TERMSERVER_COUNTER_DATA),
        sizeof(TERMSERVER_DATA_DEFINITION),
        sizeof(PERF_OBJECT_TYPE),
        TERMSERVER_OBJECT,
        0,
        TERMSERVER_OBJECT + 1,
        0,
        PERF_DETAIL_NOVICE,
        (sizeof(TERMSERVER_DATA_DEFINITION) - sizeof(PERF_OBJECT_TYPE)) / 
            sizeof(PERF_COUNTER_DEFINITION),
        0,
        -1,  // No instances
        UNICODE_CODE_PAGE,
        {0L,0L},
        {10000000L,0L}
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        NUMSESSIONS,
        0,
        NUMSESSIONS + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(TERMSERVER_COUNTER_DATA, NumSessions),
        (DWORD)FIELDOFFSET(TERMSERVER_COUNTER_DATA, NumSessions),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        NUMACTIVESESSIONS,
        0,
        NUMACTIVESESSIONS + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(TERMSERVER_COUNTER_DATA, NumActiveSessions),
        (DWORD)FIELDOFFSET(TERMSERVER_COUNTER_DATA, NumActiveSessions),
    },
    {   sizeof(PERF_COUNTER_DEFINITION),
        NUMINACTIVESESSIONS,
        0,
        NUMINACTIVESESSIONS + 1,
        0,
        0,         // No scaling
        PERF_DETAIL_NOVICE,
        PERF_COUNTER_RAWCOUNT,
        FIELDSIZE(TERMSERVER_COUNTER_DATA, NumInactiveSessions),
        (DWORD)FIELDOFFSET(TERMSERVER_COUNTER_DATA, NumInactiveSessions),
    },
};