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.

422 lines
9.7 KiB

  1. /*
  2. 5/06/99 AndrewR Created.
  3. */
  4. #include <windows.h>
  5. #include <stdio.h>
  6. #include <tchar.h>
  7. #include <shellapi.h>
  8. #if DBG
  9. VOID
  10. RtlAssert(
  11. PVOID FailedAssertion,
  12. PVOID FileName,
  13. ULONG LineNumber,
  14. PCHAR Message
  15. );
  16. #define ASSERT( exp ) \
  17. if (!(exp)) \
  18. RtlAssert( #exp, __FILE__, __LINE__, NULL )
  19. #else
  20. #define ASSERT( exp )
  21. #endif // DBG
  22. void PrintUsage(void) {
  23. printf("retrieves information about a hive\n");
  24. printf("\n");
  25. printf("Usage: checkhiv -h HiveName -t TimeBomb -s Suite -p ProcCount -u Upgrade only\n");
  26. return;
  27. }
  28. BOOL
  29. FileExists(
  30. IN PCTSTR FileName,
  31. OUT PWIN32_FIND_DATA FindData OPTIONAL
  32. )
  33. /*++
  34. Routine Description:
  35. Determine if a file exists and is accessible.
  36. Errormode is set (and then restored) so the user will not see
  37. any pop-ups.
  38. Arguments:
  39. FileName - supplies full path of file to check for existance.
  40. FindData - if specified, receives find data for the file.
  41. Return Value:
  42. TRUE if the file exists and is accessible.
  43. FALSE if not. GetLastError() returns extended error info.
  44. --*/
  45. {
  46. WIN32_FIND_DATA findData;
  47. HANDLE FindHandle;
  48. UINT OldMode;
  49. DWORD Error;
  50. OldMode = SetErrorMode(SEM_FAILCRITICALERRORS);
  51. FindHandle = FindFirstFile(FileName,&findData);
  52. if(FindHandle == INVALID_HANDLE_VALUE) {
  53. Error = GetLastError();
  54. } else {
  55. FindClose(FindHandle);
  56. if(FindData) {
  57. *FindData = findData;
  58. }
  59. Error = NO_ERROR;
  60. }
  61. SetErrorMode(OldMode);
  62. SetLastError(Error);
  63. return (Error == NO_ERROR);
  64. }
  65. BOOLEAN
  66. AdjustPrivilege(
  67. PCTSTR Privilege
  68. )
  69. /*++
  70. Routine Description:
  71. This routine tries to adjust the priviliege of the current process.
  72. Arguments:
  73. Privilege - String with the name of the privilege to be adjusted.
  74. Return Value:
  75. Returns TRUE if the privilege could be adjusted.
  76. Returns FALSE, otherwise.
  77. --*/
  78. {
  79. HANDLE TokenHandle;
  80. LUID_AND_ATTRIBUTES LuidAndAttributes;
  81. TOKEN_PRIVILEGES TokenPrivileges;
  82. if( !OpenProcessToken( GetCurrentProcess(),
  83. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  84. &TokenHandle ) ) {
  85. return( FALSE );
  86. }
  87. if( !LookupPrivilegeValue( NULL,
  88. Privilege,
  89. &( LuidAndAttributes.Luid ) ) ) {
  90. return( FALSE );
  91. }
  92. LuidAndAttributes.Attributes = SE_PRIVILEGE_ENABLED;
  93. TokenPrivileges.PrivilegeCount = 1;
  94. TokenPrivileges.Privileges[0] = LuidAndAttributes;
  95. if( !AdjustTokenPrivileges( TokenHandle,
  96. FALSE,
  97. &TokenPrivileges,
  98. 0,
  99. NULL,
  100. NULL ) ) {
  101. return( FALSE );
  102. }
  103. if( GetLastError() != NO_ERROR ) {
  104. return( FALSE );
  105. }
  106. return( TRUE );
  107. }
  108. BOOL
  109. GetHiveData(
  110. IN PCTSTR OriginalHiveName,
  111. OUT PDWORD SuiteMask,
  112. OUT PDWORD TimeBomb,
  113. OUT PDWORD ProcCount,
  114. OUT PBOOL StepUp
  115. )
  116. {
  117. TCHAR HiveTarget[MAX_PATH];
  118. TCHAR HiveName[MAX_PATH] = TEXT("xSETREG");
  119. TCHAR lpszSetupReg[MAX_PATH] = TEXT("xSETREG\\ControlSet001\\Services\\setupdd");
  120. TCHAR TargetPath[MAX_PATH];
  121. LONG rslt;
  122. HKEY hKey;
  123. DWORD Type;
  124. DWORD Buffer[4];
  125. DWORD BufferSize = sizeof(Buffer);
  126. DWORD tmp,i;
  127. BOOL RetVal = FALSE;
  128. TCHAR Dbg[1000];
  129. ASSERT(OriginalHiveName && SuiteMask && TimeBomb && ProcCount && StepUp);
  130. *SuiteMask = 0;
  131. *TimeBomb = 0;
  132. *ProcCount = 0;
  133. *StepUp = FALSE;
  134. //
  135. // copy the hive locally since you can only have one open on a hive at a time
  136. //
  137. GetTempPath(MAX_PATH,TargetPath);
  138. GetTempFileName(TargetPath,TEXT("set"),0,HiveTarget);
  139. CopyFile(OriginalHiveName,HiveTarget,FALSE);
  140. SetFileAttributes(HiveTarget,FILE_ATTRIBUTE_NORMAL);
  141. //
  142. // try to unload this first in case we faulted or something and the key is still loaded
  143. //
  144. RegUnLoadKey( HKEY_LOCAL_MACHINE, HiveName );
  145. //
  146. // need SE_RESTORE_NAME priviledge to call this API!
  147. //
  148. AdjustPrivilege((PWSTR)SE_RESTORE_NAME);
  149. rslt = RegLoadKey( HKEY_LOCAL_MACHINE, HiveName, HiveTarget );
  150. if (rslt != ERROR_SUCCESS) {
  151. #ifdef DBG
  152. wsprintf( Dbg, TEXT("Couldn't RegLoadKey, ec = %d\n"), rslt );
  153. OutputDebugString(Dbg);
  154. #endif
  155. goto e1;
  156. }
  157. rslt = RegOpenKey(HKEY_LOCAL_MACHINE,lpszSetupReg,&hKey);
  158. if (rslt != ERROR_SUCCESS) {
  159. #ifdef DBG
  160. OutputDebugString(TEXT("Couldn't RegOpenKey\n"));
  161. #endif
  162. goto e2;
  163. }
  164. rslt = RegQueryValueEx(hKey, NULL, NULL, &Type, (LPBYTE) Buffer, &BufferSize);
  165. if (rslt != ERROR_SUCCESS || Type != REG_BINARY) {
  166. #ifdef DBG
  167. OutputDebugString(TEXT("Couldn't RegQueryValueEx\n"));
  168. #endif
  169. goto e3;
  170. }
  171. *TimeBomb = Buffer[0];
  172. *StepUp = (BOOL)Buffer[1];
  173. *ProcCount = Buffer[2];
  174. *SuiteMask = Buffer[3];
  175. RetVal = TRUE;
  176. e3:
  177. RegCloseKey( hKey );
  178. e2:
  179. RegUnLoadKey( HKEY_LOCAL_MACHINE, HiveName );
  180. e1:
  181. if (GetFileAttributes(HiveTarget) != 0xFFFFFFFF) {
  182. SetFileAttributes(HiveTarget,FILE_ATTRIBUTE_NORMAL);
  183. DeleteFile(HiveTarget);
  184. }
  185. return(RetVal);
  186. }
  187. int _cdecl
  188. main(
  189. int argc,
  190. char *argvA[]
  191. )
  192. {
  193. PTSTR *argv;
  194. PTSTR HiveName = NULL;
  195. PTSTR TimeBombString = NULL;
  196. PTSTR SuiteString = NULL;
  197. PTSTR ProcCountString = NULL;
  198. PTSTR UpgradeOnlyString = NULL;
  199. TCHAR TempFile[MAX_PATH];
  200. PTSTR p;
  201. DWORD SuiteMask;
  202. DWORD TimeBomb;
  203. DWORD ProcCount;
  204. BOOL Upgrade;
  205. DWORD Result = 0;
  206. DWORD ActualSuiteMask, ActualTimeBomb, ActualProcCount;
  207. BOOL ActualStepUp;
  208. // do commandline stuff
  209. #ifdef UNICODE
  210. argv = CommandLineToArgvW( GetCommandLine(), &argc );
  211. #else
  212. argv = argvA;
  213. #endif
  214. //
  215. // parse args
  216. //
  217. while (--argc) {
  218. argv++;
  219. if ((argv[0][0] == TEXT('-')) || (argv[0][0] == TEXT('/'))) {
  220. switch (argv[0][1]) {
  221. case TEXT('h'):
  222. case TEXT('H'):
  223. HiveName = argv[1];
  224. goto Next;
  225. break;
  226. case TEXT('p'):
  227. case TEXT('P'):
  228. ProcCountString = argv[1];
  229. goto Next;
  230. break;
  231. case TEXT('s'):
  232. case TEXT('S'):
  233. SuiteString = argv[1];
  234. goto Next;
  235. break;
  236. case TEXT('t'):
  237. case TEXT('T'):
  238. TimeBombString = argv[1];
  239. goto Next;
  240. break;
  241. case TEXT('u'):
  242. case TEXT('U'):
  243. UpgradeOnlyString = argv[1];
  244. goto Next;
  245. break;
  246. default:
  247. PrintUsage();
  248. return ERROR_INVALID_PARAMETER;
  249. }
  250. }
  251. Next:
  252. ;
  253. }
  254. //
  255. // Validate parameters
  256. //
  257. if (!HiveName || (!ProcCountString && !SuiteString && !TimeBombString && !UpgradeOnlyString)) {
  258. printf("Invalid usage\n" );
  259. PrintUsage();
  260. return ERROR_INVALID_PARAMETER;
  261. }
  262. GetFullPathName(HiveName,sizeof(TempFile)/sizeof(TCHAR),TempFile,&p);
  263. if (!FileExists(TempFile,NULL)) {
  264. printf("Could not find hive file %S\n", TempFile );
  265. PrintUsage();
  266. return ERROR_FILE_NOT_FOUND;
  267. }
  268. HiveName = TempFile;
  269. //
  270. // retrieve hive information
  271. //
  272. if (!GetHiveData(HiveName,
  273. &ActualSuiteMask,
  274. &ActualTimeBomb,
  275. &ActualProcCount,
  276. &ActualStepUp
  277. )) {
  278. printf("Could not retrive information from hive\n" );
  279. return ERROR_INVALID_DATA;
  280. }
  281. //marrq result was init to 1, changed to 0
  282. Result = 0;
  283. if (UpgradeOnlyString) {
  284. Upgrade = !lstrcmpi(UpgradeOnlyString,L"TRUE");
  285. if (Upgrade != ActualStepUp) {
  286. printf("Upgrade only inconsistent --> hive says Upgrade = %s\n", ActualStepUp ? "TRUE" : "FALSE");
  287. Result = ERROR_INVALID_DATA;
  288. }
  289. }
  290. if (ProcCountString) {
  291. ProcCount = _ttoi(ProcCountString);
  292. if (ProcCount != ActualProcCount) {
  293. printf("Proc count inconsistent --> hive says Proc count = %d\n", ActualProcCount);
  294. Result = ERROR_INVALID_DATA;
  295. }
  296. }
  297. if (SuiteString) {
  298. SuiteMask = _ttoi(SuiteString);
  299. if (SuiteMask != ActualSuiteMask) {
  300. printf("Suite mask inconsistent --> hive says suite mask = %d\n", ActualSuiteMask);
  301. Result = ERROR_INVALID_DATA;
  302. }
  303. }
  304. if (TimeBombString) {
  305. TimeBomb = _ttoi(TimeBombString);
  306. //
  307. // convert to minutes
  308. //
  309. TimeBomb = TimeBomb * 60 * 24;
  310. if (TimeBomb != ActualTimeBomb) {
  311. printf("Time bomb inconsistent --> hive says Time bomb = %d days\n", (ActualTimeBomb / (60*24)));
  312. Result = ERROR_INVALID_DATA;
  313. }
  314. }
  315. //marrq this was checking for 1, changed to 0
  316. if (Result == 0) {
  317. printf("Hive is valid.\n");
  318. } else {
  319. printf("One or more inconsistencies detected in hive.\n");
  320. }
  321. return Result;
  322. }