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.

348 lines
8.7 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. regcopy.c
  5. Abstract:
  6. This is for supporting copying and munging the registry files.
  7. Author:
  8. Sean Selitrennikoff - 4/5/98
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. typedef BOOL (*PFNGETPROFILESDIRECTORYW)(LPWSTR lpProfile, LPDWORD dwSize);
  14. HKEY HiveRoot;
  15. REG_CONTEXT RegistryContext;
  16. PWSTR MachineName;
  17. PWSTR HiveFileName;
  18. PWSTR HiveRootName;
  19. DWORD
  20. DoFullRegBackup(
  21. PWCHAR MirrorRoot
  22. )
  23. /*++
  24. Routine Description:
  25. This routine copies all the registries to the given server path.
  26. Arguments:
  27. None.
  28. Return Value:
  29. NO_ERROR if everything was backed up properly, else the appropriate error code.
  30. --*/
  31. {
  32. PWSTR w;
  33. LONG Error;
  34. HKEY HiveListKey;
  35. PWSTR KeyName;
  36. PWSTR FileName;
  37. PWSTR Name;
  38. DWORD ValueIndex;
  39. DWORD ValueType;
  40. DWORD ValueNameLength;
  41. DWORD ValueDataLength;
  42. WCHAR ConfigPath[ MAX_PATH ];
  43. WCHAR HiveName[ MAX_PATH ];
  44. WCHAR HivePath[ MAX_PATH ];
  45. WCHAR DirectoryPath[ MAX_PATH ];
  46. WCHAR FilePath[ MAX_PATH ];
  47. HANDLE hInstDll;
  48. PFNGETPROFILESDIRECTORYW pfnGetProfilesDirectory;
  49. NTSTATUS Status;
  50. BOOLEAN savedBackup;
  51. //
  52. // First try and give ourselves enough priviledge
  53. //
  54. if (!RTEnableBackupRestorePrivilege()) {
  55. return(GetLastError());
  56. }
  57. //
  58. // Now attach to the registry
  59. //
  60. Error = RTConnectToRegistry(MachineName,
  61. HiveFileName,
  62. HiveRootName,
  63. NULL,
  64. &RegistryContext
  65. );
  66. if (Error != NO_ERROR) {
  67. RTDisableBackupRestorePrivilege();
  68. return Error;
  69. }
  70. //
  71. // Get handle to hivelist key
  72. //
  73. KeyName = L"HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Hivelist";
  74. Error = RTOpenKey(&RegistryContext,
  75. NULL,
  76. KeyName,
  77. MAXIMUM_ALLOWED,
  78. 0,
  79. &HiveListKey
  80. );
  81. if (Error != NO_ERROR) {
  82. RTDisconnectFromRegistry(&RegistryContext);
  83. return Error;
  84. }
  85. //
  86. // get path data for system hive, which will allow us to compute
  87. // path name to config dir in form that hivelist uses.
  88. // (an NT internal form of path) this is NOT the way the path to
  89. // the config directory should generally be computed.
  90. //
  91. ValueDataLength = sizeof(ConfigPath);
  92. Error = RTQueryValueKey(&RegistryContext,
  93. HiveListKey,
  94. L"\\Registry\\Machine\\System",
  95. &ValueType,
  96. &ValueDataLength,
  97. ConfigPath
  98. );
  99. if (Error != NO_ERROR) {
  100. RTDisconnectFromRegistry(&RegistryContext);
  101. return Error;
  102. }
  103. w = wcsrchr(ConfigPath, L'\\');
  104. *w = UNICODE_NULL;
  105. //
  106. // ennumerate entries in hivelist. for each entry, find it's hive file
  107. // path then save it.
  108. //
  109. for (ValueIndex = 0; TRUE; ValueIndex++) {
  110. savedBackup = FALSE;
  111. ValueType = REG_NONE;
  112. ValueNameLength = ARRAYSIZE( HiveName );
  113. ValueDataLength = sizeof( HivePath );
  114. Error = RTEnumerateValueKey(&RegistryContext,
  115. HiveListKey,
  116. ValueIndex,
  117. &ValueType,
  118. &ValueNameLength,
  119. HiveName,
  120. &ValueDataLength,
  121. HivePath
  122. );
  123. if (Error == ERROR_NO_MORE_ITEMS) {
  124. break;
  125. } else if (Error != NO_ERROR) {
  126. RTDisconnectFromRegistry(&RegistryContext);
  127. return Error;
  128. }
  129. //printf("HiveName='%ws', HivePath='%ws'\n", HiveName, HivePath);
  130. if ((ValueType == REG_SZ) && (ValueDataLength > sizeof(UNICODE_NULL))) {
  131. //
  132. // there's a file, compute it's path, hive branch, etc
  133. //
  134. if (w = wcsrchr( HivePath, L'\\' )) {
  135. *w++ = UNICODE_NULL;
  136. }
  137. FileName = w;
  138. if (w = wcsrchr( HiveName, L'\\' )) {
  139. *w++ = UNICODE_NULL;
  140. }
  141. Name = w;
  142. HiveRoot = NULL;
  143. if (w = wcsrchr( HiveName, L'\\' )) {
  144. w += 1;
  145. if (!_wcsicmp( w, L"MACHINE" )) {
  146. HiveRoot = HKEY_LOCAL_MACHINE;
  147. } else if (!_wcsicmp( w, L"USER" )) {
  148. HiveRoot = HKEY_USERS;
  149. } else {
  150. printf("Unexpected hive with hive name %ws skipped\n", HiveName);
  151. continue;
  152. }
  153. }
  154. if (FileName != NULL && Name != NULL && HiveRoot != NULL) {
  155. //
  156. // Extract the path name from HivePath
  157. //
  158. if (_wcsicmp(HivePath, L"\\Device")) {
  159. w = HivePath + 1;
  160. w = wcsstr(w, L"\\");
  161. w++;
  162. w = wcsstr(w, L"\\");
  163. w++;
  164. } else if (*(HivePath + 1) == L':') {
  165. w = HivePath + 2;
  166. } else {
  167. printf("Unexpected hive with file name %ws skipped\n", HivePath);
  168. continue;
  169. }
  170. //
  171. // Do the save
  172. //
  173. swprintf( DirectoryPath, L"%ws\\%ws", MirrorRoot, w );
  174. swprintf( FilePath, L"%ws\\%ws\\%ws", MirrorRoot, w, FileName );
  175. printf("Now copying hive %ws\\%ws to %ws\n", HiveName, Name, FilePath);
  176. #if 1
  177. Error = DoSpecificRegBackup(DirectoryPath,
  178. FilePath,
  179. HiveRoot,
  180. Name
  181. );
  182. #else
  183. Error = NO_ERROR;
  184. #endif
  185. if (Error != NO_ERROR) {
  186. printf("Error %d copying hive\n", Error);
  187. //return Error;
  188. }
  189. }
  190. }
  191. }
  192. RTDisconnectFromRegistry(&RegistryContext);
  193. return NO_ERROR;
  194. }
  195. DWORD
  196. CreateHiveDirectory (
  197. PWSTR HiveDirectory
  198. )
  199. {
  200. PWSTR p;
  201. p = wcschr( HiveDirectory, L'\\' );
  202. if ( (p == HiveDirectory) ||
  203. ((p != HiveDirectory) && (*(p-1) == L':')) ) {
  204. p = wcschr( p + 1, L'\\' );
  205. }
  206. while ( p != NULL ) {
  207. *p = 0;
  208. CreateDirectory( HiveDirectory, NULL );
  209. *p = L'\\';
  210. p = wcschr( p + 1, L'\\' );
  211. }
  212. CreateDirectory( HiveDirectory, NULL );
  213. return 0;
  214. }
  215. DWORD
  216. DeleteHiveFile (
  217. PWSTR HiveDirectoryAndFile
  218. )
  219. {
  220. SetFileAttributes( HiveDirectoryAndFile, FILE_ATTRIBUTE_NORMAL );
  221. DeleteFile( HiveDirectoryAndFile );
  222. return 0;
  223. }
  224. DWORD
  225. DoSpecificRegBackup(
  226. PWSTR HiveDirectory,
  227. PWSTR HiveDirectoryAndFile,
  228. HKEY HiveRoot,
  229. PWSTR HiveName
  230. )
  231. /*++
  232. Routine Description:
  233. This routine copies all the registries to the given server path.
  234. Arguments:
  235. HiveDirectory - name of directory for hive file
  236. HiveDirectoryAndFile - file name to pass directly to OS
  237. HiveRoot - HKEY_LOCAL_MACHINE or HKEY_USERS
  238. HiveName - 1st level subkey under machine or users
  239. Return Value:
  240. NO_ERROR if everything was backed up properly, else the appropriate error code.
  241. --*/
  242. {
  243. HKEY HiveKey;
  244. ULONG Disposition;
  245. LONG Error;
  246. char *Reason;
  247. //
  248. // get a handle to the hive. use special create call what will
  249. // use privileges
  250. //
  251. Reason = "accessing";
  252. Error = RTCreateKey(&RegistryContext,
  253. HiveRoot,
  254. HiveName,
  255. KEY_READ,
  256. REG_OPTION_BACKUP_RESTORE,
  257. NULL,
  258. &HiveKey,
  259. &Disposition
  260. );
  261. if (Error == NO_ERROR) {
  262. Reason = "saving";
  263. CreateHiveDirectory(HiveDirectory);
  264. DeleteHiveFile(HiveDirectoryAndFile);
  265. Error = RegSaveKey(HiveKey, HiveDirectoryAndFile, NULL);
  266. RTCloseKey(&RegistryContext, HiveKey);
  267. }
  268. return Error;
  269. }