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.
293 lines
7.8 KiB
293 lines
7.8 KiB
|
|
#include <windows.h>
|
|
#include <stdio.h>
|
|
|
|
DWORD DeleteGroupPolicyHistory( HKEY hkRoot );
|
|
LONG DeleteMachineUserPolicyHistoryKey(HANDLE hToken);
|
|
|
|
#define MACHINE_USER_GP_KEY L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Group Policy"
|
|
|
|
typedef struct _UNICODE_STRING {
|
|
USHORT Length;
|
|
USHORT MaximumLength;
|
|
#ifdef MIDL_PASS
|
|
[size_is(MaximumLength / 2), length_is((Length) / 2) ] USHORT * Buffer;
|
|
#else // MIDL_PASS
|
|
PWSTR Buffer;
|
|
#endif // MIDL_PASS
|
|
} UNICODE_STRING;
|
|
typedef UNICODE_STRING *PUNICODE_STRING;
|
|
|
|
|
|
LONG
|
|
RtlConvertSidToUnicodeString(
|
|
PUNICODE_STRING UnicodeString,
|
|
PSID Sid,
|
|
BOOLEAN AllocateDestinationString
|
|
);
|
|
|
|
VOID
|
|
RtlFreeUnicodeString(
|
|
PUNICODE_STRING UnicodeString
|
|
);
|
|
|
|
BOOL
|
|
ProcessGPOs( void* );
|
|
|
|
void
|
|
ReadPerfParams (
|
|
DWORD* pIterations,
|
|
BOOL* pbDeleteHistory,
|
|
BOOL* pbSkipFirstIteration,
|
|
BOOL* pbUser,
|
|
BOOL* pbMach,
|
|
WCHAR* szPath
|
|
);
|
|
|
|
void
|
|
MeasurePerf( void* lpGPOInfo, HANDLE hToken, BOOL bMach )
|
|
{
|
|
LARGE_INTEGER Freq;
|
|
LARGE_INTEGER Start, Stop, Total;
|
|
HKEY hkRoot;
|
|
DWORD Iterations;
|
|
BOOL bDeleteHistory;
|
|
BOOL bSkipFirstIteration;
|
|
BOOL bDoMach;
|
|
BOOL bDoUser;
|
|
WCHAR szPath[MAX_PATH+1];
|
|
|
|
ReadPerfParams (
|
|
&Iterations,
|
|
&bDeleteHistory,
|
|
&bSkipFirstIteration,
|
|
&bDoUser,
|
|
&bDoMach,
|
|
szPath
|
|
);
|
|
|
|
if ( ( bDoUser && !bMach ) || ( bDoMach && bMach ) )
|
|
{
|
|
FILE* file;
|
|
if ( bMach )
|
|
{
|
|
lstrcat( szPath, L"MachPerf.log" );
|
|
}
|
|
else
|
|
{
|
|
lstrcat( szPath, L"UserPerf.log" );
|
|
}
|
|
|
|
file = _wfopen( szPath, L"a+" );
|
|
|
|
if ( file )
|
|
{
|
|
DWORD n;
|
|
|
|
fwprintf( file, L"\n" );
|
|
|
|
if ( RegOpenCurrentUser( KEY_READ, &hkRoot ) == ERROR_SUCCESS )
|
|
{
|
|
QueryPerformanceFrequency( &Freq );
|
|
if ( !Freq.QuadPart )
|
|
{
|
|
Freq.QuadPart = 1;
|
|
}
|
|
|
|
Total.QuadPart = 0;
|
|
|
|
fprintf( file, "\nNew measurement: %d iterations\n\n", Iterations );
|
|
|
|
for ( n = 1; n <= Iterations; n++ )
|
|
{
|
|
if ( bDeleteHistory )
|
|
{
|
|
DeleteGroupPolicyHistory( hkRoot );
|
|
DeleteMachineUserPolicyHistoryKey(hToken);
|
|
}
|
|
|
|
QueryPerformanceCounter( &Start );
|
|
ProcessGPOs(lpGPOInfo);
|
|
QueryPerformanceCounter( &Stop );
|
|
|
|
if ( bSkipFirstIteration && (1 == n) )
|
|
{
|
|
bSkipFirstIteration = FALSE;
|
|
n--;
|
|
}
|
|
else
|
|
{
|
|
Total.QuadPart += Stop.QuadPart - Start.QuadPart;
|
|
}
|
|
fwprintf(
|
|
file,
|
|
L"%d\t%f\t%f\n",
|
|
n,
|
|
((double)Start.QuadPart / (double)Freq.QuadPart) * (double) 1000.0,
|
|
((double)Stop.QuadPart / (double)Freq.QuadPart) * (double) 1000.0
|
|
);
|
|
}
|
|
fprintf(
|
|
file,
|
|
"Time = %f milliseconds per iteration\n\n",
|
|
((double)Total.QuadPart / (double)Freq.QuadPart) / (double)Iterations * (double) 1000.0
|
|
);
|
|
RegCloseKey( hkRoot );
|
|
}
|
|
|
|
fclose( file );
|
|
}
|
|
}
|
|
}
|
|
|
|
DWORD DeleteGroupPolicyHistory( HKEY hkRoot )
|
|
{
|
|
return RegDelnode( hkRoot, L"Software\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\History" );
|
|
}
|
|
|
|
LONG DeleteMachineUserPolicyHistoryKey(HANDLE hToken)
|
|
{
|
|
UNICODE_STRING SidString;
|
|
BOOL bStatus;
|
|
DWORD Size;
|
|
UCHAR Buffer[sizeof(TOKEN_USER) + sizeof(SID) + ((SID_MAX_SUB_AUTHORITIES-1) * sizeof(ULONG))];
|
|
LONG Status;
|
|
HKEY hKeyGP;
|
|
HKEY hKeyUserGP;
|
|
PTOKEN_USER pTokenUser;
|
|
|
|
hKeyGP = NULL;
|
|
hKeyUserGP = NULL;
|
|
|
|
Size = sizeof(Buffer);
|
|
|
|
pTokenUser = (PTOKEN_USER) Buffer;
|
|
|
|
bStatus = GetTokenInformation(
|
|
hToken,
|
|
TokenUser,
|
|
pTokenUser,
|
|
Size,
|
|
&Size );
|
|
|
|
if ( ! bStatus )
|
|
{
|
|
return GetLastError();
|
|
}
|
|
|
|
Status = RtlConvertSidToUnicodeString(
|
|
&SidString,
|
|
pTokenUser->User.Sid,
|
|
TRUE );
|
|
|
|
if (ERROR_SUCCESS != Status) {
|
|
return Status;
|
|
}
|
|
|
|
Status = RegOpenKeyEx (
|
|
HKEY_LOCAL_MACHINE,
|
|
MACHINE_USER_GP_KEY,
|
|
0,
|
|
KEY_READ,
|
|
&hKeyGP);
|
|
|
|
if (ERROR_SUCCESS != Status) {
|
|
goto cleanup;
|
|
}
|
|
|
|
Status = RegOpenKeyEx (
|
|
hKeyGP,
|
|
SidString.Buffer,
|
|
0,
|
|
KEY_ALL_ACCESS,
|
|
&hKeyUserGP );
|
|
|
|
if (ERROR_SUCCESS != Status) {
|
|
goto cleanup;
|
|
}
|
|
|
|
Status = RegDelnode(
|
|
hKeyUserGP,
|
|
L"History");
|
|
|
|
cleanup:
|
|
|
|
if (hKeyGP) {
|
|
RegCloseKey(hKeyGP);
|
|
}
|
|
|
|
if (hKeyUserGP) {
|
|
RegCloseKey(hKeyUserGP);
|
|
}
|
|
|
|
RtlFreeUnicodeString( &SidString );
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
void
|
|
ReadPerfParams (
|
|
DWORD* pIterations,
|
|
BOOL* pbDeleteHistory,
|
|
BOOL* pbSkipFirstIteration,
|
|
BOOL* pbUser,
|
|
BOOL* pbMach,
|
|
WCHAR* szPath
|
|
)
|
|
{
|
|
HKEY hKey;
|
|
|
|
*pIterations = 5;
|
|
*pbDeleteHistory = TRUE;
|
|
*pbSkipFirstIteration = TRUE;
|
|
*pbUser = TRUE;
|
|
*pbMach = TRUE;
|
|
lstrcpy( szPath, L"C:\\" );
|
|
|
|
if ( RegOpenKeyEx (
|
|
HKEY_LOCAL_MACHINE,
|
|
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\GPPerf",
|
|
0,
|
|
KEY_READ,
|
|
&hKey
|
|
) == ERROR_SUCCESS )
|
|
{
|
|
DWORD dwType = 0;
|
|
DWORD dwData = 0;
|
|
DWORD cb = sizeof( DWORD );
|
|
|
|
if ( RegQueryValueEx( hKey, L"Iterations", 0, &dwType, (BYTE*)&dwData, &cb ) == ERROR_SUCCESS && dwType == REG_DWORD )
|
|
{
|
|
*pIterations = dwData;
|
|
}
|
|
cb = sizeof( DWORD );
|
|
if ( RegQueryValueEx( hKey, L"DeleteHistory", 0, &dwType, (BYTE*)&dwData, &cb ) == ERROR_SUCCESS && dwType == REG_DWORD )
|
|
{
|
|
*pbDeleteHistory = dwData;
|
|
}
|
|
cb = sizeof( DWORD );
|
|
if ( RegQueryValueEx( hKey, L"SkipFirst", 0, &dwType, (BYTE*)&dwData, &cb ) == ERROR_SUCCESS && dwType == REG_DWORD )
|
|
{
|
|
*pbSkipFirstIteration = dwData;
|
|
}
|
|
cb = sizeof( DWORD );
|
|
if ( RegQueryValueEx( hKey, L"User", 0, &dwType, (BYTE*)&dwData, &cb ) == ERROR_SUCCESS && dwType == REG_DWORD )
|
|
{
|
|
*pbUser = dwData;
|
|
}
|
|
cb = sizeof( DWORD );
|
|
if ( RegQueryValueEx( hKey, L"Machine", 0, &dwType, (BYTE*)&dwData, &cb ) == ERROR_SUCCESS && dwType == REG_DWORD )
|
|
{
|
|
*pbMach = dwData;
|
|
}
|
|
cb = MAX_PATH;
|
|
if ( !( RegQueryValueEx( hKey, L"Path", 0, &dwType, (BYTE*)szPath, &cb ) == ERROR_SUCCESS && dwType == REG_SZ ) )
|
|
{
|
|
lstrcpy( szPath, L"C:\\" );
|
|
}
|
|
|
|
RegCloseKey( hKey );
|
|
}
|
|
}
|
|
|