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.

451 lines
17 KiB

  1. #include "regutil.h"
  2. #include "edithive.h"
  3. NTSTATUS
  4. RiInitializeRegistryFromAsciiFile(
  5. IN PUNICODE_STRING HiveName,
  6. IN PUNICODE_STRING FileName
  7. );
  8. void
  9. Usage( void )
  10. {
  11. fprintf( stderr, "usage: HIVEINI -f hivefile [files...]\n" );
  12. exit( 1 );
  13. }
  14. PVOID OldValueBuffer;
  15. ULONG OldValueBufferSize;
  16. typedef struct _KEY_INFO {
  17. ULONG IndentAmount;
  18. UNICODE_STRING Name;
  19. HANDLE HiveHandle;
  20. HANDLE Handle;
  21. LARGE_INTEGER LastWriteTime;
  22. } KEY_INFO, *PKEY_INFO;
  23. #define MAX_KEY_DEPTH 64
  24. NTSTATUS
  25. RiInitializeRegistryFromAsciiFile(
  26. IN PUNICODE_STRING HiveName,
  27. IN PUNICODE_STRING FileName
  28. )
  29. {
  30. NTSTATUS Status;
  31. REG_UNICODE_FILE UnicodeFile;
  32. PWSTR EndKey, FirstEqual, BeginValue;
  33. ULONG IndentAmount;
  34. UNICODE_STRING InputLine;
  35. UNICODE_STRING KeyName;
  36. UNICODE_STRING KeyValue;
  37. PKEY_VALUE_FULL_INFORMATION OldValueInformation;
  38. PKEY_BASIC_INFORMATION KeyInformation;
  39. UCHAR KeyInformationBuffer[ 512 ];
  40. ULONG ResultLength;
  41. ULONG OldValueLength;
  42. PVOID ValueBuffer;
  43. ULONG ValueLength;
  44. ULONG ValueType;
  45. KEY_INFO KeyPath[ MAX_KEY_DEPTH ];
  46. PKEY_INFO CurrentKey;
  47. ULONG KeyPathLength;
  48. OBJECT_ATTRIBUTES ObjectAttributes;
  49. UNICODE_STRING Class;
  50. ULONG Disposition;
  51. BOOLEAN UpdateKeyValue;
  52. ULONG i;
  53. HANDLE HiveHandle;
  54. HANDLE RootKey;
  55. UNICODE_STRING RootName;
  56. HiveHandle = EhOpenHive(HiveName,
  57. &KeyPath[0].Handle,
  58. &KeyPath[0].Name,
  59. TYPE_SIMPLE);
  60. if (HiveHandle == NULL) {
  61. return(STATUS_OBJECT_PATH_NOT_FOUND);
  62. }
  63. KeyPath[0].Handle = (HANDLE)HCELL_NIL;
  64. OldValueInformation = (PKEY_VALUE_FULL_INFORMATION)OldValueBuffer;
  65. Class.Buffer = NULL;
  66. Class.Length = 0;
  67. Status = RegLoadAsciiFileAsUnicode( FileName,
  68. &UnicodeFile
  69. );
  70. if (!NT_SUCCESS( Status )) {
  71. return( Status );
  72. }
  73. KeyPathLength = 0;
  74. while (RegGetNextLine( &UnicodeFile, &IndentAmount, &FirstEqual )) {
  75. #if 0
  76. InputLine.Buffer = UnicodeFile.BeginLine;
  77. InputLine.Length = (USHORT)((PCHAR)UnicodeFile.EndOfLine - (PCHAR)UnicodeFile.BeginLine);
  78. InputLine.MaximumLength = InputLine.Length;
  79. printf( "GetNextLine: (%02u) '%wZ'\n", IndentAmount, &InputLine );
  80. #endif
  81. if (FirstEqual == NULL) {
  82. KeyName.Buffer = UnicodeFile.BeginLine;
  83. KeyName.Length = (USHORT)((PCHAR)UnicodeFile.EndOfLine - (PCHAR)KeyName.Buffer);
  84. KeyName.MaximumLength = (USHORT)(KeyName.Length + 1);
  85. #if 0
  86. printf( "%02u %04u KeyName: %wZ\n", KeyPathLength, IndentAmount, &KeyName );
  87. #endif
  88. CurrentKey = &KeyPath[ KeyPathLength ];
  89. if (KeyPathLength == 0 ||
  90. IndentAmount > CurrentKey->IndentAmount
  91. ) {
  92. if (KeyPathLength == MAX_KEY_DEPTH) {
  93. fprintf( stderr,
  94. "HIVEINI: %wZ key exceeded maximum depth (%u) of tree.\n",
  95. &KeyName,
  96. MAX_KEY_DEPTH
  97. );
  98. return( STATUS_UNSUCCESSFUL );
  99. }
  100. KeyPathLength++;
  101. CurrentKey++;
  102. }
  103. else {
  104. do {
  105. CurrentKey->Handle = NULL;
  106. if (IndentAmount == CurrentKey->IndentAmount) {
  107. break;
  108. }
  109. CurrentKey--;
  110. if (--KeyPathLength == 1) {
  111. break;
  112. }
  113. }
  114. while (IndentAmount <= CurrentKey->IndentAmount);
  115. }
  116. #if 0
  117. printf( " (%02u)\n", KeyPathLength );
  118. #endif
  119. CurrentKey->Name = KeyName;
  120. CurrentKey->IndentAmount = IndentAmount;
  121. Status = EhCreateChild(HiveHandle,
  122. KeyPath[ KeyPathLength-1 ].Handle,
  123. &KeyName,
  124. &CurrentKey->Handle,
  125. &Disposition);
  126. if (NT_SUCCESS( Status )) {
  127. if (DebugOutput) {
  128. fprintf( stderr, " Created key %02x %wZ (%08x)\n",
  129. CurrentKey->IndentAmount,
  130. &CurrentKey->Name,
  131. CurrentKey->Handle
  132. );
  133. }
  134. KeyInformation = (PKEY_BASIC_INFORMATION)KeyInformationBuffer;
  135. Status = EhQueryKey( HiveHandle,
  136. CurrentKey->Handle,
  137. KeyBasicInformation,
  138. KeyInformation,
  139. sizeof( KeyInformationBuffer ),
  140. &ResultLength
  141. );
  142. if (NT_SUCCESS( Status )) {
  143. CurrentKey->LastWriteTime = KeyInformation->LastWriteTime;
  144. }
  145. else {
  146. RtlZeroMemory( &CurrentKey->LastWriteTime,
  147. sizeof( CurrentKey->LastWriteTime )
  148. );
  149. }
  150. if (Disposition == REG_CREATED_NEW_KEY) {
  151. printf( "Created Key: " );
  152. for (i=0; i<KeyPathLength; i++) {
  153. printf( "%wZ\\", &KeyPath[ i ].Name );
  154. }
  155. printf( "%wZ\n", &KeyName );
  156. }
  157. }
  158. else {
  159. fprintf( stderr,
  160. "HIVEINI: CreateKey (%wZ) relative to handle (%lx) failed - %lx\n",
  161. &KeyName,
  162. ObjectAttributes.RootDirectory,
  163. Status
  164. );
  165. }
  166. }
  167. else {
  168. if (FirstEqual == UnicodeFile.BeginLine) {
  169. KeyName.Buffer = NULL;
  170. KeyName.Length = 0;
  171. KeyName.MaximumLength = 0;
  172. }
  173. else {
  174. EndKey = FirstEqual;
  175. while (EndKey > UnicodeFile.BeginLine && EndKey[ -1 ] <= L' ') {
  176. EndKey--;
  177. }
  178. KeyName.Buffer = UnicodeFile.BeginLine;
  179. KeyName.Length = (USHORT)((PCHAR)EndKey - (PCHAR)KeyName.Buffer);
  180. KeyName.MaximumLength = (USHORT)(KeyName.Length + 1);
  181. }
  182. BeginValue = FirstEqual + 1;
  183. while (BeginValue < UnicodeFile.EndOfLine && *BeginValue <= L' ') {
  184. BeginValue++;
  185. }
  186. KeyValue.Buffer = BeginValue;
  187. KeyValue.Length = (USHORT)((PCHAR)UnicodeFile.EndOfLine - (PCHAR)BeginValue);
  188. KeyValue.MaximumLength = (USHORT)(KeyValue.Length + 1);
  189. while (IndentAmount <= CurrentKey->IndentAmount) {
  190. if (DebugOutput) {
  191. fprintf( stderr, " Popping from key %02x %wZ (%08x)\n",
  192. CurrentKey->IndentAmount,
  193. &CurrentKey->Name,
  194. CurrentKey->Handle
  195. );
  196. }
  197. CurrentKey->Handle = NULL;
  198. CurrentKey--;
  199. if (--KeyPathLength == 1) {
  200. break;
  201. }
  202. }
  203. if (DebugOutput) {
  204. fprintf( stderr, " Adding value '%wZ = %wZ' to key %02x %wZ (%08x)\n",
  205. &KeyName,
  206. &KeyValue,
  207. CurrentKey->IndentAmount,
  208. &CurrentKey->Name,
  209. CurrentKey->Handle
  210. );
  211. }
  212. if (RegGetKeyValue( &KeyValue,
  213. &UnicodeFile,
  214. &ValueType,
  215. &ValueBuffer,
  216. &ValueLength
  217. )
  218. ) {
  219. if (ValueBuffer == NULL) {
  220. Status = EhDeleteValueKey( HiveHandle,
  221. KeyPath[ KeyPathLength+1 ].Handle,
  222. &KeyValue
  223. );
  224. if (NT_SUCCESS( Status )) {
  225. printf( "Delete value for Key: " );
  226. for (i=0; i<KeyPathLength; i++) {
  227. printf( "%wZ\\", &KeyPath[ i ].Name );
  228. }
  229. printf( "%wZ\n", &KeyName );
  230. }
  231. }
  232. else {
  233. if ( UnicodeFile.LastWriteTime.QuadPart >
  234. CurrentKey->LastWriteTime.QuadPart
  235. ) {
  236. Status = STATUS_UNSUCCESSFUL;
  237. UpdateKeyValue = TRUE;
  238. }
  239. else {
  240. Status = EhQueryValueKey( HiveHandle,
  241. CurrentKey->Handle,
  242. &KeyName,
  243. KeyValueFullInformation,
  244. OldValueInformation,
  245. OldValueBufferSize,
  246. &OldValueLength
  247. );
  248. if (NT_SUCCESS( Status )) {
  249. UpdateKeyValue = TRUE;
  250. }
  251. else {
  252. UpdateKeyValue = FALSE;
  253. }
  254. }
  255. if (!NT_SUCCESS( Status ) ||
  256. OldValueInformation->Type != ValueType ||
  257. OldValueInformation->DataLength != ValueLength ||
  258. !RtlEqualMemory( (PCHAR)OldValueInformation +
  259. OldValueInformation->DataOffset,
  260. ValueBuffer,
  261. ValueLength )
  262. ) {
  263. Status = EhSetValueKey( HiveHandle,
  264. CurrentKey->Handle,
  265. &KeyName,
  266. 0,
  267. ValueType,
  268. ValueBuffer,
  269. ValueLength
  270. );
  271. if (NT_SUCCESS( Status )) {
  272. printf( "%s value for Key: ",
  273. UpdateKeyValue ? "Updated" : "Created"
  274. );
  275. for (i=1; i<=KeyPathLength; i++) {
  276. printf( "%wZ\\", &KeyPath[ i ].Name );
  277. }
  278. if (KeyName.Length) {
  279. printf( "%wZ ", &KeyName );
  280. }
  281. printf( "= '%wZ'\n", &KeyValue );
  282. }
  283. else {
  284. fprintf( stderr,
  285. "HIVEINI: SetValueKey (%wZ) failed - %lx\n",
  286. &KeyName,
  287. Status
  288. );
  289. }
  290. }
  291. RtlFreeHeap( RtlProcessHeap(), 0, ValueBuffer );
  292. }
  293. }
  294. else {
  295. fprintf( stderr,
  296. "HIVEINI: Invalid key (%wZ) value (%wZ)\n", &KeyName,
  297. &KeyValue
  298. );
  299. }
  300. }
  301. }
  302. EhCloseHive(HiveHandle);
  303. return( Status );
  304. }
  305. int
  306. __cdecl main( argc, argv )
  307. int argc;
  308. char *argv[];
  309. {
  310. int i;
  311. char *s;
  312. NTSTATUS Status;
  313. BOOL FileArgumentSeen;
  314. BOOL HiveArgumentSeen=FALSE;
  315. ANSI_STRING AnsiString;
  316. UNICODE_STRING DosFileName;
  317. UNICODE_STRING FileName;
  318. UNICODE_STRING DosHiveName;
  319. UNICODE_STRING HiveName;
  320. OldValueBufferSize = VALUE_BUFFER_SIZE;
  321. OldValueBuffer = VirtualAlloc( NULL, OldValueBufferSize, MEM_COMMIT, PAGE_READWRITE );
  322. if (OldValueBuffer == NULL) {
  323. fprintf( stderr, "HIVEINI: Unable to allocate value buffer.\n" );
  324. exit( 1 );
  325. }
  326. RegInitialize();
  327. FileArgumentSeen = FALSE;
  328. HiveName.Length = HiveName.MaximumLength = 0;
  329. HiveName.Buffer = NULL;
  330. for (i=1; i<argc; i++) {
  331. s = argv[ i ];
  332. if (*s == '-' || *s == '/') {
  333. while (*++s) {
  334. switch( tolower( *s ) ) {
  335. case 'd':
  336. DebugOutput = TRUE;
  337. break;
  338. case 'f':
  339. if (++i < argc) {
  340. RtlInitAnsiString(&AnsiString, argv[i]);
  341. RtlAnsiStringToUnicodeString( &DosHiveName,
  342. &AnsiString,
  343. TRUE );
  344. RtlDosPathNameToNtPathName_U( DosHiveName.Buffer,
  345. &HiveName,
  346. NULL,
  347. NULL );
  348. break;
  349. }
  350. default: Usage();
  351. }
  352. }
  353. }
  354. else {
  355. FileArgumentSeen = TRUE;
  356. RtlInitAnsiString( &AnsiString, s );
  357. Status = RtlAnsiStringToUnicodeString( &DosFileName, &AnsiString, TRUE );
  358. if (NT_SUCCESS( Status )) {
  359. if (RtlDosPathNameToNtPathName_U( DosFileName.Buffer,
  360. &FileName,
  361. NULL,
  362. NULL
  363. )
  364. ) {
  365. Status = RiInitializeRegistryFromAsciiFile( &HiveName,
  366. &FileName );
  367. if (!NT_SUCCESS( Status )) {
  368. fprintf( stderr,
  369. "HIVEINI: Failed to load from %wZ - Status == %lx\n",
  370. &FileName,
  371. Status
  372. );
  373. }
  374. }
  375. else {
  376. Status = STATUS_UNSUCCESSFUL;
  377. fprintf( stderr,
  378. "HIVEINI: Unable to map Dos Name (%wZ) to NT name\n",
  379. &DosFileName
  380. );
  381. }
  382. }
  383. else {
  384. fprintf( stderr,
  385. "HIVEINI: Unable to convert %s to unicode - Status == %lx\n",
  386. &AnsiString,
  387. Status
  388. );
  389. }
  390. }
  391. }
  392. if (!FileArgumentSeen) {
  393. RtlInitUnicodeString( &FileName, L"\\SystemRoot\\System32\\Config\\registry.sys" );
  394. Status = RiInitializeRegistryFromAsciiFile( &HiveName,
  395. &FileName );
  396. if (!NT_SUCCESS( Status )) {
  397. fprintf( stderr,
  398. "HIVEINI: Failed to load from %wZ - Status == %lx\n",
  399. &FileName,
  400. Status
  401. );
  402. }
  403. else {
  404. RtlInitUnicodeString( &FileName, L"\\SystemRoot\\System32\\Config\\registry.usr" );
  405. Status = RiInitializeRegistryFromAsciiFile( &HiveName,
  406. &FileName );
  407. if (!NT_SUCCESS( Status )) {
  408. fprintf( stderr,
  409. "HIVEINI: Failed to load from %wZ - Status == %lx\n",
  410. &FileName,
  411. Status
  412. );
  413. }
  414. }
  415. }
  416. return( 0 );
  417. }