Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

428 lines
12 KiB

/********************************************************************/
/** Copyright(c) 1985-1998 Microsoft Corporation. **/
/********************************************************************/
//***
//
// Filename: perfmon.c
//
// Description:
//
// History: Feb 11,1998 NarenG Created original version.
//
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <winperf.h>
#include <lmcons.h>
#include <lmapibuf.h>
#include <lmaccess.h>
#include <raserror.h>
#include <time.h>
#include <string.h>
#include <rasauth.h>
#include <stdlib.h>
#include <stdio.h>
#include <rtutils.h>
#include <mprlog.h>
#include <mprerror.h>
#define INCL_RASAUTHATTRIBUTES
#include <ppputil.h>
#include "radclnt.h"
#include "md5.h"
#include "perfmon.h"
// ADD
#define PERFORMANCEKEY TEXT("SYSTEM\\CurrentControlSet\\Services\\Rasrad\\Performance")
#define FIRSTCOUNTER TEXT("First Counter")
#define FIRSTHELP TEXT("First Help")
#define QUERY_GLOBAL 1
#define QUERY_FOREIGN 2
#define QUERY_COSTLY 3
#define QUERY_ITEMS 4
#define DELIMITER 1
#define DIGIT 2
#define INVALID 3
#pragma pack(4)
// ADD
#define NUMBER_COUNTERS 9
#define AUTHREQSENT_OFFSET sizeof(DWORD)
#define AUTHREQFAILED_OFFSET (AUTHREQSENT_OFFSET + sizeof(DWORD))
#define AUTHREQSUCCEDED_OFFSET (AUTHREQFAILED_OFFSET + sizeof(DWORD))
#define AUTHREQTIMEOUT_OFFSET (AUTHREQSUCCEDED_OFFSET + sizeof(DWORD))
#define ACCTREQSENT_OFFSET (AUTHREQTIMEOUT_OFFSET + sizeof(DWORD))
#define ACCTBADPACK_OFFSET (ACCTREQSENT_OFFSET + sizeof(DWORD))
#define ACCTREQSUCCEDED_OFFSET (ACCTBADPACK_OFFSET + sizeof(DWORD))
#define ACCTREQTIMEOUT_OFFSET (ACCTREQSUCCEDED_OFFSET + sizeof(DWORD))
#define AUTHBADPACK_OFFSET (ACCTREQTIMEOUT_OFFSET + sizeof(DWORD))
#define CB_PERF_DATA (sizeof(PERF_COUNTER_BLOCK) + (NUMBER_COUNTERS * sizeof(DWORD)))
typedef struct
{
PERF_OBJECT_TYPE PerfObjectType;
// ADD
PERF_COUNTER_DEFINITION cAuthReqSent;
PERF_COUNTER_DEFINITION cAuthReqFailed;
PERF_COUNTER_DEFINITION cAuthReqSucceded;
PERF_COUNTER_DEFINITION cAuthReqTimeout;
PERF_COUNTER_DEFINITION cAcctReqSent;
PERF_COUNTER_DEFINITION cAcctBadPack;
PERF_COUNTER_DEFINITION cAcctReqSucceded;
PERF_COUNTER_DEFINITION cAcctReqTimeout;
PERF_COUNTER_DEFINITION cAuthBadPack;
} PERF_DATA;
#pragma pack()
DWORD GetQueryType(LPWSTR pwszQuery);
BOOL IsNumberInUnicodeList(DWORD dwNumber, WCHAR UNALIGNED *pwszUnicodeList);
DWORD g_cRef = 0;
CONST WCHAR g_wszGlobal[] = L"Global";
CONST WCHAR g_wszForeign[] = L"Foreign";
CONST WCHAR g_wszCostly[] = L"Costly";
PERF_DATA g_PerfData =
{
{
sizeof(PERF_DATA) + CB_PERF_DATA, sizeof(PERF_DATA), sizeof(PERF_OBJECT_TYPE),
RADIUS_CLIENT_COUNTER_OBJECT, 0, RADIUS_CLIENT_COUNTER_OBJECT, 0, PERF_DETAIL_NOVICE, (sizeof(PERF_DATA) - sizeof(PERF_OBJECT_TYPE)) / sizeof(PERF_COUNTER_DEFINITION),
0, 0, 0
},
// ADD
{
sizeof(PERF_COUNTER_DEFINITION), AUTHREQSENT, 0, AUTHREQSENT, 0, 0, PERF_DETAIL_NOVICE, PERF_COUNTER_RAWCOUNT,
sizeof(DWORD), AUTHREQSENT_OFFSET
},
{
sizeof(PERF_COUNTER_DEFINITION), AUTHREQFAILED, 0, AUTHREQFAILED, 0, 0, PERF_DETAIL_NOVICE, PERF_COUNTER_RAWCOUNT,
sizeof(DWORD), AUTHREQFAILED_OFFSET
},
{
sizeof(PERF_COUNTER_DEFINITION), AUTHREQSUCCEDED, 0, AUTHREQSUCCEDED, 0, 0, PERF_DETAIL_NOVICE, PERF_COUNTER_RAWCOUNT,
sizeof(DWORD), AUTHREQSUCCEDED_OFFSET
},
{
sizeof(PERF_COUNTER_DEFINITION), AUTHREQTIMEOUT, 0, AUTHREQTIMEOUT, 0, 0, PERF_DETAIL_NOVICE, PERF_COUNTER_RAWCOUNT,
sizeof(DWORD), AUTHREQTIMEOUT_OFFSET
},
{
sizeof(PERF_COUNTER_DEFINITION), ACCTREQSENT, 0, ACCTREQSENT, 0, 0, PERF_DETAIL_NOVICE, PERF_COUNTER_RAWCOUNT,
sizeof(DWORD), ACCTREQSENT_OFFSET
},
{
sizeof(PERF_COUNTER_DEFINITION), ACCTBADPACK, 0, ACCTBADPACK, 0, 0, PERF_DETAIL_NOVICE, PERF_COUNTER_RAWCOUNT,
sizeof(DWORD), ACCTBADPACK_OFFSET
},
{
sizeof(PERF_COUNTER_DEFINITION), ACCTREQSUCCEDED, 0, ACCTREQSUCCEDED, 0, 0, PERF_DETAIL_NOVICE, PERF_COUNTER_RAWCOUNT,
sizeof(DWORD), ACCTREQSUCCEDED_OFFSET
},
{
sizeof(PERF_COUNTER_DEFINITION), ACCTREQTIMEOUT, 0, ACCTREQTIMEOUT, 0, 0, PERF_DETAIL_NOVICE, PERF_COUNTER_RAWCOUNT,
sizeof(DWORD), ACCTREQTIMEOUT_OFFSET
},
{
sizeof(PERF_COUNTER_DEFINITION), AUTHBADPACK, 0, AUTHBADPACK, 0, 0, PERF_DETAIL_NOVICE, PERF_COUNTER_RAWCOUNT,
sizeof(DWORD), AUTHBADPACK_OFFSET
},
};
// ============================= EvalChar ==========================================
DWORD EvalChar(WCHAR wch, WCHAR wchDelimiter)
{
if (wch == wchDelimiter || wch == 0)
return (DELIMITER);
if (wch >= (WCHAR) '0' && wch <= (WCHAR) '9')
return (DIGIT);
return (INVALID);
} // EvalChar()
// ================================== CompareQuery ===================================
BOOL CompareQuery(WCHAR UNALIGNED *pwszFirst, WCHAR UNALIGNED *pwszSecond)
{
BOOL fFound = TRUE;
while ((*pwszFirst != 0) && (*pwszSecond != 0))
{
if (*pwszFirst++ != *pwszSecond++)
{
fFound = FALSE;
break;
}
}
return (fFound);
} // CompareQuery()
// ================================ Open ===========================================
DWORD APIENTRY Open(LPWSTR *pwszDeviceName)
{
DWORD Status = ERROR_SUCCESS;
if (g_cRef == 0)
{
HKEY hKey = NULL;
DWORD Size, Type, dwFirstCounter, dwFirstHelp;
__try
{
Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, PERFORMANCEKEY, 0, KEY_ALL_ACCESS, &hKey);
if (Status != ERROR_SUCCESS)
__leave;
Size = sizeof(DWORD);
Status = RegQueryValueEx(hKey, FIRSTCOUNTER, 0, &Type, (PBYTE) &dwFirstCounter, &Size);
if (Status != ERROR_SUCCESS)
__leave;
Size = sizeof(DWORD);
Status = RegQueryValueEx(hKey, FIRSTHELP, 0, &Type, (PBYTE) &dwFirstHelp, &Size);
if (Status != ERROR_SUCCESS)
__leave;
g_PerfData.PerfObjectType.ObjectNameTitleIndex += dwFirstCounter;
g_PerfData.PerfObjectType.ObjectHelpTitleIndex += dwFirstHelp;
// ADD
g_PerfData.cAuthReqSent.CounterNameTitleIndex += dwFirstCounter;
g_PerfData.cAuthReqSent.CounterHelpTitleIndex += dwFirstHelp;
g_PerfData.cAuthReqFailed.CounterNameTitleIndex += dwFirstCounter;
g_PerfData.cAuthReqFailed.CounterHelpTitleIndex += dwFirstHelp;
g_PerfData.cAuthReqSucceded.CounterNameTitleIndex += dwFirstCounter;
g_PerfData.cAuthReqSucceded.CounterHelpTitleIndex += dwFirstHelp;
g_PerfData.cAuthReqTimeout.CounterNameTitleIndex += dwFirstCounter;
g_PerfData.cAuthReqTimeout.CounterHelpTitleIndex += dwFirstHelp;
g_PerfData.cAcctReqSent.CounterNameTitleIndex += dwFirstCounter;
g_PerfData.cAcctReqSent.CounterHelpTitleIndex += dwFirstHelp;
g_PerfData.cAcctBadPack.CounterNameTitleIndex += dwFirstCounter;
g_PerfData.cAcctBadPack.CounterHelpTitleIndex += dwFirstHelp;
g_PerfData.cAcctReqSucceded.CounterNameTitleIndex += dwFirstCounter;
g_PerfData.cAcctReqSucceded.CounterHelpTitleIndex += dwFirstHelp;
g_PerfData.cAcctReqTimeout.CounterNameTitleIndex += dwFirstCounter;
g_PerfData.cAcctReqTimeout.CounterHelpTitleIndex += dwFirstHelp;
g_PerfData.cAuthBadPack.CounterNameTitleIndex += dwFirstCounter;
g_PerfData.cAuthBadPack.CounterHelpTitleIndex += dwFirstHelp;
} // __try
__finally
{
RegCloseKey(hKey);
} // __finally
} // g_cRef == 0
g_cRef ++;
return (Status);
} // Open()
// ================================ Collect ========================================
DWORD APIENTRY Collect(LPWSTR pwszValue, LPVOID *ppvData, LPDWORD pcbData, LPDWORD pcObjectTypes)
{
DWORD dwQueryType, *pdwCounter, dwSpaceNeeded;
PERF_DATA UNALIGNED *pPerfData;
PERF_COUNTER_BLOCK UNALIGNED *pPerfCounter;
dwQueryType = GetQueryType(pwszValue);
if (dwQueryType == QUERY_FOREIGN)
{
*pcbData = 0;
*pcObjectTypes = 0;
return (ERROR_SUCCESS);
}
if (dwQueryType == QUERY_ITEMS)
{
if (IsNumberInUnicodeList(g_PerfData.PerfObjectType.ObjectNameTitleIndex, pwszValue) == FALSE)
{
*pcbData = 0;
*pcObjectTypes = 0;
return (ERROR_SUCCESS);
}
} // QUERY_ITEMS
pPerfData = (PERF_DATA *) *ppvData;
dwSpaceNeeded = sizeof(PERF_DATA) + CB_PERF_DATA;
if (*pcbData < dwSpaceNeeded)
{
*pcbData = 0;
*pcObjectTypes = 0;
return (ERROR_MORE_DATA);
}
CopyMemory(pPerfData, &g_PerfData, sizeof(PERF_DATA));
pPerfCounter = (PERF_COUNTER_BLOCK *) &pPerfData[1];
pPerfCounter->ByteLength = CB_PERF_DATA;
pdwCounter = (DWORD *) &pPerfCounter[1];
// ADD
*pdwCounter = g_cAuthReqSent;
pdwCounter += 1;
*pdwCounter = g_cAuthReqFailed;
pdwCounter += 1;
*pdwCounter = g_cAuthReqSucceded;
pdwCounter += 1;
*pdwCounter = g_cAuthReqTimeout;
pdwCounter += 1;
*pdwCounter = g_cAcctReqSent;
pdwCounter += 1;
*pdwCounter = g_cAcctBadPack;
pdwCounter += 1;
*pdwCounter = g_cAcctReqSucceded;
pdwCounter += 1;
*pdwCounter = g_cAcctReqTimeout;
pdwCounter += 1;
*pdwCounter = g_cAuthBadPack;
pdwCounter += 1;
*ppvData = (PVOID) pdwCounter;
*pcObjectTypes = 1;
*pcbData = (DWORD) ((PBYTE) pdwCounter - (PBYTE) pPerfData);
return (ERROR_SUCCESS);
} // Collect()
// ================================= Close ==========================================
DWORD APIENTRY Close(VOID)
{
g_cRef --;
if (g_cRef == 0)
{
}
return (ERROR_SUCCESS);
} // Close()
// ================================== GetQueryType ==================================
DWORD GetQueryType(LPWSTR pwszQuery)
{
if (pwszQuery == NULL || *pwszQuery == 0)
{
return (QUERY_GLOBAL);
}
if (CompareQuery(pwszQuery, (WCHAR *) g_wszGlobal))
return (QUERY_GLOBAL);
if (CompareQuery(pwszQuery, (WCHAR *) g_wszForeign))
return (QUERY_FOREIGN);
if (CompareQuery(pwszQuery, (WCHAR *) g_wszCostly))
return (QUERY_COSTLY);
return (QUERY_ITEMS);
} // GetQueryType()
// ============================== IsNumberInUnicodeList ===============================
BOOL IsNumberInUnicodeList(DWORD dwNumber, WCHAR UNALIGNED *pwszUnicodeList)
{
BOOL fInList = FALSE;
__try
{
WCHAR UNALIGNED *pwszCh = pwszUnicodeList;
BOOL fNewItem = TRUE;
BOOL fValidNumber = FALSE;
DWORD dwThisNumber = 0;
if (pwszUnicodeList == NULL)
__leave;
while (TRUE)
{
switch (EvalChar(*pwszCh, (WCHAR) ' '))
{
case DIGIT:
if (fNewItem == TRUE)
{
fNewItem = FALSE;
fValidNumber = TRUE;
}
if (fValidNumber == TRUE)
{
dwThisNumber *= 10;
dwThisNumber += (*pwszCh - (WCHAR) '0');
}
break;
case DELIMITER:
if (fValidNumber)
{
if (dwThisNumber == dwNumber)
{
fInList = TRUE;
__leave;
// Fixed because of PREFAST warning
//
// return (TRUE);
//
}
fValidNumber = FALSE;
}
if (*pwszCh == 0)
{
fInList = FALSE;
__leave;
// Fixed because of PREFAST warning
//
// return (FALSE);
//
}
else
{
fNewItem = TRUE;
dwThisNumber = 0;
}
break;
case INVALID:
fValidNumber = FALSE;
break;
default:
break;
} // EvalChar
pwszCh++;
} // TRUE
} // __try
__finally
{
} // __finally
return (fInList);
} // IsNumberInUnicodeList()