#include "idl_types.h"

/*
   IDL structures for perfcount code
*/

[
	pointer_default(unique)
]
	interface perfcount
{
	const int PERF_NO_INSTANCES		= -1;
	const int PERF_NO_UNIQUE_ID		= -1;

	/* These determine the data size */
	const int PERF_SIZE_DWORD		= 0x00000000;
	const int PERF_SIZE_LARGE		= 0x00000100;
	const int PERF_SIZE_ZERO		= 0x00000200;
	const int PERF_SIZE_VARIABLE_LEN	= 0x00000300;

	/* These determine the usage of the counter */
	const int PERF_TYPE_NUMBER		= 0x00000000;
	const int PERF_TYPE_COUNTER		= 0x00000400;
	const int PERF_TYPE_TEXT		= 0x00000800;
	const int PERF_TYPE_ZERO		= 0x00000C00;

	/* If PERF_TYPE_NUMBER was selected, these provide display information */
	const int PERF_NUMBER_HEX		= 0x00000000;
	const int PERF_NUMBER_DECIMAL		= 0x00010000;
	const int PERF_NUMBER_DEC_1000		= 0x00020000;

	/* If PERF_TYPE_COUNTER was selected, these provide display information */
	const int PERF_COUNTER_VALUE		= 0x00000000;
	const int PERF_COUNTER_RATE		= 0x00010000;
	const int PERF_COUNTER_FRACTION		= 0x00020000;
	const int PERF_COUNTER_BASE		= 0x00030000;
	const int PERF_COUNTER_ELAPSED		= 0x00040000;
	const int PERF_COUNTER_QUEUELEN		= 0x00050000;
	const int PERF_COUNTER_HISTOGRAM	= 0x00060000;
	const int PERF_COUNTER_PRECISION	= 0x00070000;

	/* If PERF_TYPE_TEXT was selected, these provide display information */
	const int PERF_TEXT_UNICODE		= 0x00000000;
	const int PERF_TEXT_ASCII		= 0x00010000;

	/* These provide information for which tick count to use when computing elapsed interval */
	const int PERF_TIMER_TICK		= 0x00000000;
	const int PERF_TIMER_100NS		= 0x00100000;
	const int PERF_OBJECT_TIMER		= 0x00200000;

	/* These affect how the data is manipulated prior to being displayed */
	const int PERF_DELTA_COUNTER		= 0x00400000;
	const int PERF_DELTA_BASE		= 0x00800000;
	const int PERF_INVERSE_COUNTER		= 0x01000000;
	const int PERF_MULTI_COUNTER		= 0x02000000;

	/* These determine if any text gets added when the value is displayed */
	const int PERF_DISPLAY_NO_SUFFIX	= 0x00000000;
	const int PERF_DISPLAY_PER_SEC		= 0x10000000;
	const int PERF_DISPLAY_PERCENT		= 0x20000000;
	const int PERF_DISPLAY_SECONDS		= 0x30000000;
	const int PERF_DISPLAY_NOSHOW		= 0x40000000;

	/* These determine the DetailLevel of the counter */
	const int PERF_DETAIL_NOVICE		= 100;
	const int PERF_DETAIL_ADVANCED		= 200;
	const int PERF_DETAIL_EXPERT		= 300;
	const int PERF_DETAIL_WIZARD		= 400;

	typedef struct {
		uint16 year;
		uint16 month;
		uint16 dayofweek;
		uint16 day;
		uint16 hour;
		uint16 minute;
		uint16 second;
		uint16 milliseconds;
	} SYSTEMTIME;

	typedef [public] struct {
		/* sizeof(PERF_COUNTER_DEFINITION) */
		uint32 ByteLength;
		uint32 CounterNameTitleIndex;
		uint32 CounterNameTitlePointer;
		uint32 CounterHelpTitleIndex;
		uint32 CounterHelpTitlePointer;
		uint32 DefaultScale;
		uint32 DetailLevel;
		uint32 CounterType;
		uint32 CounterSize;
		uint32 CounterOffset;
	} PERF_COUNTER_DEFINITION;

	typedef [public] struct {
		/* Total size of the data block, including all data plus this header */
		uint32 ByteLength;
		uint8 data[ByteLength];
	} PERF_COUNTER_BLOCK;

	typedef [public] struct {
		/* Total size of the instance definition, including the length of the terminated Name string */
		uint32 ByteLength;
		uint32 ParentObjectTitleIndex;
		uint32 ParentObjectTitlePointer;
		uint32 UniqueID;
		/* From the start of the PERF_INSTANCE_DEFINITION, the byte offset to the start of the Name string */
		uint32 NameOffset;
		uint32 NameLength;
		/* Unicode string containing the name for the instance */
		uint8 *data;
		PERF_COUNTER_BLOCK counter_data;
	} PERF_INSTANCE_DEFINITION;

	typedef [public] struct {
		/* Total size of the object block, including all PERF_INSTANCE_DEFINITIONs,
		   PERF_COUNTER_DEFINITIONs and PERF_COUNTER_BLOCKs in bytes */
		uint32 TotalByteLength;
		/* Size of this PERF_OBJECT_TYPE plus all PERF_COUNTER_DEFINITIONs in bytes */
		uint32 DefinitionLength;
		/* Size of this PERF_OBJECT_TYPE */
		uint32 HeaderLength;
		uint32 ObjectNameTitleIndex;
		uint32 ObjectNameTitlePointer;
		uint32 ObjectHelpTitleIndex;
		uint32 ObjectHelpTitlePointer;
		uint32 DetailLevel;
		uint32 NumCounters;
		uint32 DefaultCounter;
		uint32 NumInstances;
		uint32 CodePage;
		hyper PerfTime;
		hyper PerfFreq;
		PERF_COUNTER_DEFINITION counters[NumCounters];
		PERF_INSTANCE_DEFINITION instances[NumInstances];
		PERF_COUNTER_BLOCK counter_data;
	} PERF_OBJECT_TYPE;

	/* PerfCounter Inner Buffer structs */
	typedef [public] struct {
		/* hardcoded to read "P.E.R.F" */
		uint16 Signature[4];
		uint32 LittleEndian;
		/* both currently hardcoded to 1 */
		uint32 Version;
		uint32 Revision;
		/* bytes of PERF_OBJECT_TYPE data, does NOT include the PERF_DATA_BLOCK */
		uint32 TotalByteLength;
		/* size of PERF_DATA_BLOCK including the uint8 *data */
		uint32 HeaderLength;
		/* number of PERF_OBJECT_TYPE structures encoded */
		uint32 NumObjectTypes;
		uint32 DefaultObject;
		SYSTEMTIME SystemTime;
		/* This will guarantee that we're on a 64-bit boundary before we encode
		   PerfTime, and having it there will make my offset math much easier. */
		uint32 Padding;
		/* Now when I'm marshalling this, I'll need to call prs_align_uint64()
		   before I start encodint the uint64 structs */
		/* clock rate * seconds uptime */
		hyper PerfTime;
		/* The clock rate of the CPU */
		hyper PerfFreq;
		/* used for high-res timers -- for now PerfTime * 10e7 */
		hyper PerfTime100nSec;
		uint32 SystemNameLength;
		uint32 SystemNameOffset;
		/* The SystemName, in unicode, terminated */
		uint8* data;
		PERF_OBJECT_TYPE objects[NumObjectTypes];
	} PERF_DATA_BLOCK;
}