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.

381 lines
10 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. snapshot.c
  5. Abstract:
  6. Implements a memdb-based snapshot of all files, directories, registry keys and
  7. registry values.
  8. Author:
  9. Jim Schmidt (jimschm) 13-Mar-1998
  10. Revision History:
  11. <alias> <date> <comments>
  12. --*/
  13. #include "pch.h"
  14. #include "migshared.h"
  15. #define S_SNAPSHOT_A "Snapshot"
  16. BOOL
  17. pGetFullKeyA (
  18. IN OUT PSTR Object
  19. )
  20. {
  21. MEMDB_ENUMA e;
  22. CHAR Pattern[MEMDB_MAX];
  23. PSTR p;
  24. wsprintfA (Pattern, "%s*", Object);
  25. if (MemDbEnumFirstValue (&e, Pattern, MEMDB_THIS_LEVEL_ONLY, MEMDB_ENDPOINTS_ONLY)) {
  26. p = _mbsrchr (Object, TEXT('\\'));
  27. if (p) {
  28. p = _mbsinc (p);
  29. } else {
  30. p = Object;
  31. }
  32. StringCopyA (p, e.szName);
  33. return TRUE;
  34. } else {
  35. return FALSE;
  36. }
  37. }
  38. VOID
  39. pSnapDirsA (
  40. IN PCSTR Drive,
  41. IN BOOL DiffMode,
  42. IN HANDLE DiffHandle OPTIONAL
  43. )
  44. {
  45. TREE_ENUMA FileEnum;
  46. CHAR Node[MEMDB_MAX];
  47. DWORD Value;
  48. //
  49. // Enumerate the file system
  50. //
  51. if (EnumFirstFileInTreeA (&FileEnum, Drive, NULL, TRUE)) {
  52. do {
  53. wsprintfA (
  54. Node,
  55. "%s\\%s\\%u\\%u%u",
  56. S_SNAPSHOT_A,
  57. FileEnum.FullPath,
  58. FileEnum.FindData->nFileSizeLow,
  59. FileEnum.FindData->ftLastWriteTime.dwHighDateTime,
  60. FileEnum.FindData->ftLastWriteTime.dwLowDateTime
  61. );
  62. if (!DiffMode) {
  63. MemDbSetValueA (Node, SNAP_RESULT_DELETED);
  64. } else {
  65. Value = SNAP_RESULT_UNCHANGED;
  66. if (!MemDbGetValueA (Node, NULL)) {
  67. if (DiffHandle) {
  68. WriteFileStringA (DiffHandle, FileEnum.FullPath);
  69. WriteFileStringA (DiffHandle, "\r\n");
  70. }
  71. wsprintfA (Node, "%s\\%s,", S_SNAPSHOT_A, FileEnum.FullPath);
  72. Value = SNAP_RESULT_CHANGED;
  73. if (!pGetFullKeyA (Node)) {
  74. wsprintfA (
  75. Node,
  76. "%s\\%s\\%u\\%u%u",
  77. S_SNAPSHOT_A,
  78. FileEnum.FullPath,
  79. FileEnum.FindData->nFileSizeLow,
  80. FileEnum.FindData->ftLastWriteTime.dwHighDateTime,
  81. FileEnum.FindData->ftLastWriteTime.dwLowDateTime
  82. );
  83. Value = SNAP_RESULT_ADDED;
  84. }
  85. }
  86. MemDbSetValueA (Node, Value);
  87. }
  88. } while (EnumNextFileInTreeA (&FileEnum));
  89. }
  90. }
  91. VOID
  92. pSnapAllDrivesA (
  93. IN BOOL DiffMode,
  94. IN HANDLE DiffHandle OPTIONAL
  95. )
  96. {
  97. CHAR Drives[256];
  98. MULTISZ_ENUMA e;
  99. if (GetLogicalDriveStringsA (256, Drives)) {
  100. if (EnumFirstMultiSzA (&e, Drives)) {
  101. do {
  102. if (DRIVE_FIXED == GetDriveTypeA (e.CurrentString)) {
  103. pSnapDirsA (e.CurrentString, DiffMode, DiffHandle);
  104. break;
  105. }
  106. } while (EnumNextMultiSzA (&e));
  107. }
  108. }
  109. }
  110. VOID
  111. pSnapRegistryHiveA (
  112. IN PCSTR Hive,
  113. IN BOOL DiffMode,
  114. IN HANDLE DiffHandle OPTIONAL
  115. )
  116. {
  117. REGTREE_ENUMA RegEnum;
  118. REGVALUE_ENUMA RegValue;
  119. CHAR Node[MEMDB_MAX];
  120. PBYTE Data;
  121. DWORD Checksum;
  122. PBYTE p;
  123. UINT Count;
  124. DWORD Value;
  125. if (EnumFirstRegKeyInTreeA (&RegEnum, Hive)) {
  126. do {
  127. wsprintfA (
  128. Node,
  129. "%s\\%s",
  130. S_SNAPSHOT_A,
  131. RegEnum.FullKeyName
  132. );
  133. if (!DiffMode) {
  134. MemDbSetValueA (Node, SNAP_RESULT_DELETED);
  135. } else {
  136. if (!MemDbGetValueA (Node, NULL)) {
  137. if (DiffHandle) {
  138. WriteFileStringA (DiffHandle, RegEnum.FullKeyName);
  139. WriteFileStringA (DiffHandle, "\r\n");
  140. }
  141. } else {
  142. MemDbSetValueA (Node, SNAP_RESULT_UNCHANGED);
  143. }
  144. }
  145. if (EnumFirstRegValueA (&RegValue, RegEnum.CurrentKey->KeyHandle)) {
  146. do {
  147. Data = GetRegValueData (RegValue.KeyHandle, RegValue.ValueName);
  148. if (!Data) {
  149. continue;
  150. }
  151. Checksum = RegValue.Type;
  152. p = Data;
  153. for (Count = 0 ; Count < RegValue.DataSize ; Count++) {
  154. Checksum = (Checksum << 1) | (Checksum >> 31) | *p;
  155. p++;
  156. }
  157. MemFree (g_hHeap, 0, Data);
  158. wsprintfA (
  159. Node,
  160. "%s\\%s\\[%s],%u",
  161. S_SNAPSHOT_A,
  162. RegEnum.FullKeyName,
  163. RegValue.ValueName,
  164. Checksum
  165. );
  166. if (!DiffMode) {
  167. MemDbSetValueA (Node, SNAP_RESULT_DELETED);
  168. } else {
  169. Value = SNAP_RESULT_UNCHANGED;
  170. if (!MemDbGetValueA (Node, NULL)) {
  171. WriteFileStringA (DiffHandle, RegEnum.FullKeyName);
  172. WriteFileStringA (DiffHandle, " [");
  173. WriteFileStringA (DiffHandle, RegValue.ValueName);
  174. WriteFileStringA (DiffHandle, "]\r\n");
  175. wsprintfA (
  176. Node,
  177. "%s\\%s\\[%s],",
  178. S_SNAPSHOT_A,
  179. RegEnum.FullKeyName,
  180. RegValue.ValueName
  181. );
  182. Value = SNAP_RESULT_CHANGED;
  183. if (!pGetFullKeyA (Node)) {
  184. wsprintfA (
  185. Node,
  186. "%s\\%s\\[%s],%u",
  187. S_SNAPSHOT_A,
  188. RegEnum.FullKeyName,
  189. RegValue.ValueName,
  190. Checksum
  191. );
  192. Value = SNAP_RESULT_ADDED;
  193. }
  194. }
  195. MemDbSetValueA (Node, Value);
  196. }
  197. } while (EnumNextRegValueA (&RegValue));
  198. }
  199. } while (EnumNextRegKeyInTreeA (&RegEnum));
  200. }
  201. }
  202. VOID
  203. pSnapRegistryA (
  204. IN BOOL DiffMode,
  205. IN HANDLE DiffHandle OPTIONAL
  206. )
  207. {
  208. pSnapRegistryHiveA (TEXT("HKLM"), DiffMode, DiffHandle);
  209. pSnapRegistryHiveA (TEXT("HKU"), DiffMode, DiffHandle);
  210. }
  211. VOID
  212. TakeSnapShotEx (
  213. IN DWORD SnapFlags
  214. )
  215. {
  216. MemDbCreateTemporaryKeyA (S_SNAPSHOT_A);
  217. if (SnapFlags & SNAP_FILES) {
  218. pSnapAllDrivesA (FALSE, NULL);
  219. }
  220. if (SnapFlags & SNAP_REGISTRY) {
  221. pSnapRegistryA (FALSE, NULL);
  222. }
  223. }
  224. BOOL
  225. GenerateDiffOutputExA (
  226. IN PCSTR FileName,
  227. IN PCSTR Comment, OPTIONAL
  228. IN BOOL Append,
  229. IN DWORD SnapFlags
  230. )
  231. {
  232. HANDLE File = NULL;
  233. MEMDB_ENUMA e;
  234. if (FileName) {
  235. File = CreateFileA (
  236. FileName,
  237. GENERIC_WRITE,
  238. 0,
  239. NULL,
  240. Append ? OPEN_ALWAYS : CREATE_ALWAYS,
  241. FILE_ATTRIBUTE_NORMAL,
  242. NULL
  243. );
  244. if (File == INVALID_HANDLE_VALUE) {
  245. DEBUGMSG ((DBG_ERROR, "Can't open %s for output", FileName));
  246. return FALSE;
  247. }
  248. if (Append) {
  249. SetFilePointer (File, 0, NULL, FILE_END);
  250. }
  251. if (Comment) {
  252. WriteFileStringA (File, Comment);
  253. WriteFileStringA (File, "\r\n");
  254. }
  255. WriteFileStringA (File, "Changes:\r\n");
  256. }
  257. if (SnapFlags & SNAP_FILES) {
  258. pSnapAllDrivesA (TRUE, File);
  259. }
  260. if (SnapFlags & SNAP_REGISTRY) {
  261. pSnapRegistryA (TRUE, File);
  262. }
  263. if (File) {
  264. WriteFileStringA (File, "\r\nDeleted Settings:\r\n");
  265. if (MemDbGetValueExA (&e, S_SNAPSHOT_A, NULL, NULL)) {
  266. do {
  267. if (e.dwValue == SNAP_RESULT_DELETED) {
  268. WriteFileStringA (File, e.szName);
  269. WriteFileStringA (File, "\r\n");
  270. }
  271. } while (MemDbEnumNextValue (&e));
  272. }
  273. WriteFileStringA (File, "\r\nEnd.\r\n\r\n");
  274. CloseHandle (File);
  275. }
  276. return TRUE;
  277. }
  278. BOOL
  279. EnumFirstSnapFileA (
  280. IN OUT PSNAP_FILE_ENUMA e,
  281. IN PCSTR FilePattern, OPTIONAL
  282. IN DWORD SnapStatus
  283. )
  284. {
  285. CHAR node[MEMDB_MAX];
  286. e->FilePattern = FilePattern;
  287. e->SnapStatus = SnapStatus;
  288. e->FirstCall = TRUE;
  289. MemDbBuildKeyA (node, S_SNAPSHOT_A, "*", NULL, NULL);
  290. if (!MemDbEnumFirstValue (&(e->mEnum), node, MEMDB_ALL_SUBLEVELS, MEMDB_ENDPOINTS_ONLY)) {
  291. return FALSE;
  292. }
  293. return EnumNextSnapFileA (e);
  294. }
  295. BOOL
  296. EnumNextSnapFileA (
  297. IN OUT PSNAP_FILE_ENUMA e
  298. )
  299. {
  300. PSTR lastWack;
  301. while (e->FirstCall?(e->FirstCall = FALSE, TRUE):MemDbEnumNextValue (&(e->mEnum))) {
  302. StringCopyA (e->FileName, e->mEnum.szName);
  303. lastWack = _mbsrchr (e->FileName, '\\');
  304. if (lastWack) {
  305. *lastWack = 0;
  306. lastWack = _mbsrchr (e->FileName, '\\');
  307. if (lastWack) {
  308. *lastWack = 0;
  309. }
  310. }
  311. if (e->FilePattern && (!IsPatternMatch (e->FilePattern, e->FileName))) {
  312. continue;
  313. }
  314. if ((e->SnapStatus & e->mEnum.dwValue) == 0) {
  315. continue;
  316. }
  317. return TRUE;
  318. }
  319. return FALSE;
  320. }