423 lines
9.3 KiB
C
423 lines
9.3 KiB
C
|
/*
|
||
|
|
||
|
5/06/99 AndrewR Created.
|
||
|
|
||
|
*/
|
||
|
|
||
|
#include <windows.h>
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <tchar.h>
|
||
|
#include <shellapi.h>
|
||
|
|
||
|
#if DBG
|
||
|
|
||
|
VOID
|
||
|
RtlAssert(
|
||
|
PVOID FailedAssertion,
|
||
|
PVOID FileName,
|
||
|
ULONG LineNumber,
|
||
|
PCHAR Message
|
||
|
);
|
||
|
|
||
|
#define ASSERT( exp ) \
|
||
|
if (!(exp)) \
|
||
|
RtlAssert( #exp, __FILE__, __LINE__, NULL )
|
||
|
|
||
|
#else
|
||
|
|
||
|
#define ASSERT( exp )
|
||
|
|
||
|
#endif // DBG
|
||
|
|
||
|
void PrintUsage(void) {
|
||
|
printf("retrieves information about a hive\n");
|
||
|
printf("\n");
|
||
|
printf("Usage: checkhiv -h HiveName -t TimeBomb -s Suite -p ProcCount -u Upgrade only\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
FileExists(
|
||
|
IN PCTSTR FileName,
|
||
|
OUT PWIN32_FIND_DATA FindData OPTIONAL
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Determine if a file exists and is accessible.
|
||
|
Errormode is set (and then restored) so the user will not see
|
||
|
any pop-ups.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
FileName - supplies full path of file to check for existance.
|
||
|
|
||
|
FindData - if specified, receives find data for the file.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE if the file exists and is accessible.
|
||
|
FALSE if not. GetLastError() returns extended error info.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
WIN32_FIND_DATA findData;
|
||
|
HANDLE FindHandle;
|
||
|
UINT OldMode;
|
||
|
DWORD Error;
|
||
|
|
||
|
OldMode = SetErrorMode(SEM_FAILCRITICALERRORS);
|
||
|
|
||
|
FindHandle = FindFirstFile(FileName,&findData);
|
||
|
if(FindHandle == INVALID_HANDLE_VALUE) {
|
||
|
Error = GetLastError();
|
||
|
} else {
|
||
|
FindClose(FindHandle);
|
||
|
if(FindData) {
|
||
|
*FindData = findData;
|
||
|
}
|
||
|
Error = NO_ERROR;
|
||
|
}
|
||
|
|
||
|
SetErrorMode(OldMode);
|
||
|
|
||
|
SetLastError(Error);
|
||
|
return (Error == NO_ERROR);
|
||
|
}
|
||
|
|
||
|
BOOLEAN
|
||
|
AdjustPrivilege(
|
||
|
PCTSTR Privilege
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine tries to adjust the priviliege of the current process.
|
||
|
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
Privilege - String with the name of the privilege to be adjusted.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
Returns TRUE if the privilege could be adjusted.
|
||
|
Returns FALSE, otherwise.
|
||
|
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
HANDLE TokenHandle;
|
||
|
LUID_AND_ATTRIBUTES LuidAndAttributes;
|
||
|
|
||
|
TOKEN_PRIVILEGES TokenPrivileges;
|
||
|
|
||
|
|
||
|
if( !OpenProcessToken( GetCurrentProcess(),
|
||
|
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
|
||
|
&TokenHandle ) ) {
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
|
||
|
if( !LookupPrivilegeValue( NULL,
|
||
|
Privilege,
|
||
|
&( LuidAndAttributes.Luid ) ) ) {
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
LuidAndAttributes.Attributes = SE_PRIVILEGE_ENABLED;
|
||
|
TokenPrivileges.PrivilegeCount = 1;
|
||
|
TokenPrivileges.Privileges[0] = LuidAndAttributes;
|
||
|
|
||
|
if( !AdjustTokenPrivileges( TokenHandle,
|
||
|
FALSE,
|
||
|
&TokenPrivileges,
|
||
|
0,
|
||
|
NULL,
|
||
|
NULL ) ) {
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
if( GetLastError() != NO_ERROR ) {
|
||
|
return( FALSE );
|
||
|
}
|
||
|
return( TRUE );
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
GetHiveData(
|
||
|
IN PCTSTR OriginalHiveName,
|
||
|
OUT PDWORD SuiteMask,
|
||
|
OUT PDWORD TimeBomb,
|
||
|
OUT PDWORD ProcCount,
|
||
|
OUT PBOOL StepUp
|
||
|
)
|
||
|
{
|
||
|
|
||
|
TCHAR HiveTarget[MAX_PATH];
|
||
|
TCHAR HiveName[MAX_PATH] = TEXT("xSETREG");
|
||
|
TCHAR lpszSetupReg[MAX_PATH] = TEXT("xSETREG\\ControlSet001\\Services\\setupdd");
|
||
|
TCHAR TargetPath[MAX_PATH];
|
||
|
|
||
|
LONG rslt;
|
||
|
HKEY hKey;
|
||
|
DWORD Type;
|
||
|
DWORD Buffer[4];
|
||
|
DWORD BufferSize = sizeof(Buffer);
|
||
|
DWORD tmp,i;
|
||
|
|
||
|
BOOL RetVal = FALSE;
|
||
|
TCHAR Dbg[1000];
|
||
|
|
||
|
ASSERT(OriginalHiveName && SuiteMask && TimeBomb && ProcCount && StepUp);
|
||
|
*SuiteMask = 0;
|
||
|
*TimeBomb = 0;
|
||
|
*ProcCount = 0;
|
||
|
*StepUp = FALSE;
|
||
|
|
||
|
//
|
||
|
// copy the hive locally since you can only have one open on a hive at a time
|
||
|
//
|
||
|
GetTempPath(MAX_PATH,TargetPath);
|
||
|
GetTempFileName(TargetPath,TEXT("set"),0,HiveTarget);
|
||
|
|
||
|
CopyFile(OriginalHiveName,HiveTarget,FALSE);
|
||
|
SetFileAttributes(HiveTarget,FILE_ATTRIBUTE_NORMAL);
|
||
|
|
||
|
//
|
||
|
// try to unload this first in case we faulted or something and the key is still loaded
|
||
|
//
|
||
|
RegUnLoadKey( HKEY_LOCAL_MACHINE, HiveName );
|
||
|
|
||
|
//
|
||
|
// need SE_RESTORE_NAME priviledge to call this API!
|
||
|
//
|
||
|
AdjustPrivilege((PWSTR)SE_RESTORE_NAME);
|
||
|
|
||
|
|
||
|
rslt = RegLoadKey( HKEY_LOCAL_MACHINE, HiveName, HiveTarget );
|
||
|
if (rslt != ERROR_SUCCESS) {
|
||
|
#ifdef DBG
|
||
|
wsprintf( Dbg, TEXT("Couldn't RegLoadKey, ec = %d\n"), rslt );
|
||
|
OutputDebugString(Dbg);
|
||
|
#endif
|
||
|
|
||
|
goto e1;
|
||
|
}
|
||
|
|
||
|
rslt = RegOpenKey(HKEY_LOCAL_MACHINE,lpszSetupReg,&hKey);
|
||
|
if (rslt != ERROR_SUCCESS) {
|
||
|
#ifdef DBG
|
||
|
OutputDebugString(TEXT("Couldn't RegOpenKey\n"));
|
||
|
#endif
|
||
|
|
||
|
goto e2;
|
||
|
}
|
||
|
|
||
|
rslt = RegQueryValueEx(hKey, NULL, NULL, &Type, (LPBYTE) Buffer, &BufferSize);
|
||
|
if (rslt != ERROR_SUCCESS || Type != REG_BINARY) {
|
||
|
#ifdef DBG
|
||
|
OutputDebugString(TEXT("Couldn't RegQueryValueEx\n"));
|
||
|
#endif
|
||
|
|
||
|
goto e3;
|
||
|
}
|
||
|
|
||
|
*TimeBomb = Buffer[0];
|
||
|
*StepUp = (BOOL)Buffer[1];
|
||
|
*ProcCount = Buffer[2];
|
||
|
*SuiteMask = Buffer[3];
|
||
|
|
||
|
RetVal = TRUE;
|
||
|
|
||
|
e3:
|
||
|
RegCloseKey( hKey );
|
||
|
e2:
|
||
|
RegUnLoadKey( HKEY_LOCAL_MACHINE, HiveName );
|
||
|
|
||
|
e1:
|
||
|
if (GetFileAttributes(HiveTarget) != 0xFFFFFFFF) {
|
||
|
SetFileAttributes(HiveTarget,FILE_ATTRIBUTE_NORMAL);
|
||
|
DeleteFile(HiveTarget);
|
||
|
}
|
||
|
|
||
|
return(RetVal);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
int _cdecl
|
||
|
main(
|
||
|
int argc,
|
||
|
char *argvA[]
|
||
|
)
|
||
|
{
|
||
|
PTSTR *argv;
|
||
|
PTSTR HiveName = NULL;
|
||
|
PTSTR TimeBombString = NULL;
|
||
|
PTSTR SuiteString = NULL;
|
||
|
PTSTR ProcCountString = NULL;
|
||
|
PTSTR UpgradeOnlyString = NULL;
|
||
|
|
||
|
TCHAR TempFile[MAX_PATH];
|
||
|
PTSTR p;
|
||
|
|
||
|
DWORD SuiteMask;
|
||
|
DWORD TimeBomb;
|
||
|
DWORD ProcCount;
|
||
|
BOOL Upgrade;
|
||
|
|
||
|
DWORD Result = 0;
|
||
|
|
||
|
DWORD ActualSuiteMask, ActualTimeBomb, ActualProcCount;
|
||
|
BOOL ActualStepUp;
|
||
|
|
||
|
// do commandline stuff
|
||
|
#ifdef UNICODE
|
||
|
argv = CommandLineToArgvW( GetCommandLine(), &argc );
|
||
|
#else
|
||
|
argv = argvA;
|
||
|
#endif
|
||
|
|
||
|
//
|
||
|
// parse args
|
||
|
//
|
||
|
while (--argc) {
|
||
|
|
||
|
argv++;
|
||
|
|
||
|
if ((argv[0][0] == TEXT('-')) || (argv[0][0] == TEXT('/'))) {
|
||
|
|
||
|
switch (argv[0][1]) {
|
||
|
|
||
|
case TEXT('h'):
|
||
|
case TEXT('H'):
|
||
|
HiveName = argv[1];
|
||
|
goto Next;
|
||
|
break;
|
||
|
case TEXT('p'):
|
||
|
case TEXT('P'):
|
||
|
ProcCountString = argv[1];
|
||
|
goto Next;
|
||
|
break;
|
||
|
case TEXT('s'):
|
||
|
case TEXT('S'):
|
||
|
SuiteString = argv[1];
|
||
|
goto Next;
|
||
|
break;
|
||
|
case TEXT('t'):
|
||
|
case TEXT('T'):
|
||
|
TimeBombString = argv[1];
|
||
|
goto Next;
|
||
|
break;
|
||
|
case TEXT('u'):
|
||
|
case TEXT('U'):
|
||
|
UpgradeOnlyString = argv[1];
|
||
|
goto Next;
|
||
|
break;
|
||
|
default:
|
||
|
PrintUsage();
|
||
|
return ERROR_INVALID_PARAMETER;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
Next:
|
||
|
;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Validate parameters
|
||
|
//
|
||
|
if (!HiveName || (!ProcCountString && !SuiteString && !TimeBombString && !UpgradeOnlyString)) {
|
||
|
printf("Invalid usage\n" );
|
||
|
PrintUsage();
|
||
|
return ERROR_INVALID_PARAMETER;
|
||
|
}
|
||
|
|
||
|
GetFullPathName(HiveName,sizeof(TempFile)/sizeof(TCHAR),TempFile,&p);
|
||
|
|
||
|
if (!FileExists(TempFile,NULL)) {
|
||
|
printf("Could not find hive file %S\n", TempFile );
|
||
|
PrintUsage();
|
||
|
return ERROR_FILE_NOT_FOUND;
|
||
|
}
|
||
|
|
||
|
HiveName = TempFile;
|
||
|
|
||
|
|
||
|
//
|
||
|
// retrieve hive information
|
||
|
//
|
||
|
if (!GetHiveData(HiveName,
|
||
|
&ActualSuiteMask,
|
||
|
&ActualTimeBomb,
|
||
|
&ActualProcCount,
|
||
|
&ActualStepUp
|
||
|
)) {
|
||
|
printf("Could not retrive information from hive\n" );
|
||
|
return ERROR_INVALID_DATA;
|
||
|
}
|
||
|
|
||
|
//marrq result was init to 1, changed to 0
|
||
|
Result = 0;
|
||
|
|
||
|
if (UpgradeOnlyString) {
|
||
|
Upgrade = !lstrcmpi(UpgradeOnlyString,L"TRUE");
|
||
|
if (Upgrade != ActualStepUp) {
|
||
|
printf("Upgrade only inconsistent --> hive says Upgrade = %s\n", ActualStepUp ? "TRUE" : "FALSE");
|
||
|
Result = ERROR_INVALID_DATA;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (ProcCountString) {
|
||
|
ProcCount = _ttoi(ProcCountString);
|
||
|
if (ProcCount != ActualProcCount) {
|
||
|
printf("Proc count inconsistent --> hive says Proc count = %d\n", ActualProcCount);
|
||
|
Result = ERROR_INVALID_DATA;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (SuiteString) {
|
||
|
SuiteMask = _ttoi(SuiteString);
|
||
|
if (SuiteMask != ActualSuiteMask) {
|
||
|
printf("Suite mask inconsistent --> hive says suite mask = %d\n", ActualSuiteMask);
|
||
|
Result = ERROR_INVALID_DATA;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (TimeBombString) {
|
||
|
TimeBomb = _ttoi(TimeBombString);
|
||
|
//
|
||
|
// convert to minutes
|
||
|
//
|
||
|
TimeBomb = TimeBomb * 60 * 24;
|
||
|
if (TimeBomb != ActualTimeBomb) {
|
||
|
printf("Time bomb inconsistent --> hive says Time bomb = %d days\n", (ActualTimeBomb / (60*24)));
|
||
|
Result = ERROR_INVALID_DATA;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
//marrq this was checking for 1, changed to 0
|
||
|
if (Result == 0) {
|
||
|
printf("Hive is valid.\n");
|
||
|
} else {
|
||
|
printf("One or more inconsistencies detected in hive.\n");
|
||
|
}
|
||
|
|
||
|
return Result;
|
||
|
|
||
|
}
|
||
|
|
||
|
|