//
// performanceinfo.c
//
// memory performances informations
//
// loïc berthelot
// nov. 2004
//
// only for nt4, 2k and xp
//



#include <windows.h>
#include "scolMMemory.h"
//#include <psapi.h>


////////////////////////////////////////////////////////////////////////
//
// DATA
//
////////////////////////////////////////////////////////////////////////

#ifndef PERFORMANCE_INFORMATION
typedef struct _PERFORMANCE_INFORMATION 
{
    DWORD cb;
    SIZE_T CommitTotal;
    SIZE_T CommitLimit;
    SIZE_T CommitPeak;
    SIZE_T PhysicalTotal;
    SIZE_T PhysicalAvailable;
    SIZE_T SystemCache;
    SIZE_T KernelTotal;
    SIZE_T KernelPaged;
    SIZE_T KernelNonpaged;
    SIZE_T PageSize;
    DWORD HandleCount;
    DWORD ProcessCount;
    DWORD ThreadCount;
} PERFORMANCE_INFORMATION, *PPERFORMANCE_INFORMATION;
#endif



static BOOL bPSAPIInitialized					= FALSE;

//WinNT Functions, via PSAPI DLL
typedef BOOL (WINAPI *GETPERFORMANCEINFO)      ( PPERFORMANCE_INFORMATION, DWORD);

static GETPERFORMANCEINFO      p_GetPerformanceInfo   = NULL;

HINSTANCE hPSAPI                                = NULL;


PERFORMANCE_INFORMATION oldPI;


/////////////////////////////////////////////////////////////////////////
//
// INTERNAL BODY
//
////////////////////////////////////////////////////////////////////////


/****************************************/
/* static BOOL InitPSAPI()              */
/*                                      */
/* PSAPI initialization                 */
/****************************************/   
static BOOL InitPSAPI()
{
    if ( bPSAPIInitialized )
        return ( TRUE ) ;


    
    // loading PSAPI dll
    hPSAPI = LoadLibrary ( "PSAPI.DLL" ) ;

    if (hPSAPI != NULL)
	{
	    // get functions pointers
		p_GetPerformanceInfo =	(GETPERFORMANCEINFO)GetProcAddress (hPSAPI,  "GetPerformanceInfo" );
	}

	if (p_GetPerformanceInfo )
		bPSAPIInitialized = TRUE ;

	ZeroMemory (&oldPI, sizeof(PERFORMANCE_INFORMATION));

    return ( TRUE ) ;
}






/****************************************/
/* static BOOL ClosePSAPI()             */
/*                                      */
/* close the PSAPI library              */
/****************************************/  
static BOOL ClosePSAPI()
{
	if (hPSAPI)
	{
		FreeLibrary (hPSAPI);
		hPSAPI = NULL;
	}
	bPSAPIInitialized = FALSE;
	return (TRUE);
}





void PrintPerformanceInfo (PERFORMANCE_INFORMATION* pi)
{
		MMechostr(0, "\n\n____________________\nPERFORMANCE INFORMATIONS\n________________________\n");

		MMechostr(0, "\nCommitTotal : %d", pi->CommitTotal);
		MMechostr(0, "\nCommitLimit : %d", pi->CommitLimit);
		MMechostr(0, "\nCommitPeak : %d", pi->CommitPeak);
		MMechostr(0, "\nPhysicalTotal : %d", pi->PhysicalTotal);
		MMechostr(0, "\nPhysicalAvailable : %d", pi->PhysicalAvailable);
		MMechostr(0, "\nSystemCache : %d", pi->SystemCache);
		MMechostr(0, "\nKernelTotal : %d", pi->KernelTotal);
		MMechostr(0, "\nKernelPaged : %d", pi->KernelPaged);
		MMechostr(0, "\nKernelNonpaged : %d", pi->KernelNonpaged);
		MMechostr(0, "\nPageSize : %d", pi->PageSize);
		MMechostr(0, "\nHandleCount : ¨%d", pi->HandleCount);
		MMechostr(0, "\nProcessCount : %d", pi->ProcessCount);
		MMechostr(0, "\nThreadCount : %d", pi->ThreadCount);

		MMechostr(0, "\n____________________________\n_____________________________\n\n");
}





/////////////////////////////////////////////////////////////////////////
//
// EXTERNAL BODY
//
////////////////////////////////////////////////////////////////////////




int GetPerformanceInfo (BOOL printResults)
{
PERFORMANCE_INFORMATION pi;


    InitPSAPI ();

	ZeroMemory (&pi, sizeof(PERFORMANCE_INFORMATION));
	pi.cb = sizeof(PERFORMANCE_INFORMATION);

	if (!p_GetPerformanceInfo (&pi, sizeof(PERFORMANCE_INFORMATION)))
	{
			ClosePSAPI();
			MMechostr(0, "\n!! PERFORMANCE INFO ERROR !!\n");
			return (-1);
	}


	/*
	    DWORD cb;
    SIZE_T CommitTotal;
    SIZE_T CommitLimit;
    SIZE_T CommitPeak;
    SIZE_T PhysicalTotal;
    SIZE_T PhysicalAvailable;
    SIZE_T SystemCache;
    SIZE_T KernelTotal;
    SIZE_T KernelPaged;
    SIZE_T KernelNonpaged;
    SIZE_T PageSize;
    DWORD HandleCount;
    DWORD ProcessCount;
    DWORD ThreadCount;
	*/


	if (printResults) PrintPerformanceInfo (&pi);


	// <=> not the first time
	if (oldPI.cb != 0)
	{
		
	}


	// save the values
	oldPI.cb = pi.cb;
    oldPI.CommitTotal = pi.CommitTotal;
    oldPI.CommitLimit = pi.CommitLimit;
    oldPI.CommitPeak = pi.CommitPeak;
    oldPI.PhysicalTotal = pi.PhysicalTotal;
    oldPI.PhysicalAvailable = pi.PhysicalAvailable;
    oldPI.SystemCache = pi.SystemCache;
    oldPI.KernelTotal = pi.KernelTotal;
    oldPI.KernelPaged = pi.KernelPaged;
    oldPI.KernelNonpaged = pi.KernelNonpaged;
    oldPI.PageSize = pi.PageSize;
    oldPI.HandleCount = pi.HandleCount;
    oldPI.ProcessCount = pi.ProcessCount;
    oldPI.ThreadCount = pi.ThreadCount;


	return 0;
}