/* 5/06/99 AndrewR Created. */ #include #include #include #include #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; }