Source code of Windows XP (NT5)
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.

313 lines
8.3 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // TITLE: Regeditp.c : Defines the private API RegExportRegFile() and
  4. // RegImportRegFile() for regedit.exe and reskit\reg.exe
  5. //
  6. // AUTHOR: Zeyong Xu
  7. //
  8. // DATE: March 1999
  9. //
  10. //---------------------------------------------------------------------------
  11. #include "stdafx.h"
  12. #include "regporte.h"
  13. #include "regeditp.h"
  14. HWND g_hRegProgressWnd;
  15. HINSTANCE g_hInstance;
  16. BOOL g_fSaveInDownlevelFormat;
  17. //
  18. // RegImportRegFile
  19. // PARAMETERS:
  20. // hWnd, handle of parent window.
  21. // fSilentMode, TRUE if no messages should be displayed, else FALSE.
  22. // lpFileName, address of file name buffer.
  23. //
  24. LONG WINAPI RegImportRegFile(HWND hWnd,
  25. BOOL fSilentMode,
  26. LPTSTR lpFileName)
  27. {
  28. ImportRegFileWorker(lpFileName);
  29. if(g_FileErrorStringID == IDS_IMPFILEERRSUCCESS)
  30. return ERROR_SUCCESS;
  31. else
  32. return GetLastError();
  33. }
  34. //
  35. // RegExportRegFile
  36. // PARAMETERS:
  37. // hWnd, handle of parent window.
  38. // fSilentMode, TRUE if no messages should be displayed, else FALSE.
  39. // lpFileName, address of file name buffer.
  40. // lpRegistryFullKey,
  41. //
  42. LONG WINAPI RegExportRegFile(HWND hWnd,
  43. BOOL fSilentMode,
  44. BOOL fUseDownlevelFormat,
  45. LPTSTR lpFileName,
  46. LPTSTR lpRegistryFullKey)
  47. {
  48. if (fUseDownlevelFormat)
  49. {
  50. g_fSaveInDownlevelFormat = TRUE;
  51. ExportWin40RegFile(lpFileName, lpRegistryFullKey);
  52. }
  53. else
  54. {
  55. ExportWinNT50RegFile(lpFileName, lpRegistryFullKey);
  56. }
  57. if (g_FileErrorStringID == IDS_EXPFILEERRFILEWRITE)
  58. {
  59. InternalMessageBox(g_hInstance,
  60. hWnd,
  61. MAKEINTRESOURCE(g_FileErrorStringID),
  62. MAKEINTRESOURCE(IDS_REGEDIT),
  63. MB_ICONERROR | MB_OK,
  64. lpFileName);
  65. }
  66. if(g_FileErrorStringID == IDS_EXPFILEERRSUCCESS)
  67. return ERROR_SUCCESS;
  68. else
  69. return GetLastError();
  70. }
  71. #ifdef WINNT
  72. // RegDeleteKeyRecursive
  73. // DESCRIPTION:
  74. // Adapted from \\kernel\razzle3,mvdm\wow32\wshell.c,WOWRegDeleteKey().
  75. // The Windows 95 implementation of RegDeleteKey recursively deletes all
  76. // the subkeys of the specified registry branch, but the NT implementation
  77. // only deletes leaf keys.
  78. LONG RegDeleteKeyRecursive(HKEY hKey,
  79. LPCTSTR lpszSubKey)
  80. /*++
  81. Routine Description:
  82. There is a significant difference between the Win3.1 and Win32
  83. behavior of RegDeleteKey when the key in question has subkeys.
  84. The Win32 API does not allow you to delete a key with subkeys,
  85. while the Win3.1 API deletes a key and all its subkeys.
  86. This routine is a recursive worker that enumerates the subkeys
  87. of a given key, applies itself to each one, then deletes itself.
  88. It specifically does not attempt to deal rationally with the
  89. case where the caller may not have access to some of the subkeys
  90. of the key to be deleted. In this case, all the subkeys which
  91. the caller can delete will be deleted, but the api will still
  92. return ERROR_ACCESS_DENIED.
  93. Arguments:
  94. hKey - Supplies a handle to an open registry key.
  95. lpszSubKey - Supplies the name of a subkey which is to be deleted
  96. along with all of its subkeys.
  97. Return Value:
  98. ERROR_SUCCESS - entire subtree successfully deleted.
  99. ERROR_ACCESS_DENIED - given subkey could not be deleted.
  100. --*/
  101. {
  102. DWORD i;
  103. HKEY Key;
  104. LONG Status;
  105. DWORD ClassLength=0;
  106. DWORD SubKeys;
  107. DWORD MaxSubKey;
  108. DWORD MaxClass;
  109. DWORD Values;
  110. DWORD MaxValueName;
  111. DWORD MaxValueData;
  112. DWORD SecurityLength;
  113. FILETIME LastWriteTime;
  114. LPTSTR NameBuffer;
  115. //
  116. // First open the given key so we can enumerate its subkeys
  117. //
  118. Status = RegOpenKeyEx(hKey,
  119. lpszSubKey,
  120. 0,
  121. KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,
  122. &Key);
  123. if (Status != ERROR_SUCCESS)
  124. {
  125. //
  126. // possibly we have delete access, but not enumerate/query.
  127. // So go ahead and try the delete call, but don't worry about
  128. // any subkeys. If we have any, the delete will fail anyway.
  129. //
  130. return(RegDeleteKey(hKey,lpszSubKey));
  131. }
  132. //
  133. // Use RegQueryInfoKey to determine how big to allocate the buffer
  134. // for the subkey names.
  135. //
  136. Status = RegQueryInfoKey(Key,
  137. NULL,
  138. &ClassLength,
  139. 0,
  140. &SubKeys,
  141. &MaxSubKey,
  142. &MaxClass,
  143. &Values,
  144. &MaxValueName,
  145. &MaxValueData,
  146. &SecurityLength,
  147. &LastWriteTime);
  148. if ((Status != ERROR_SUCCESS) &&
  149. (Status != ERROR_MORE_DATA) &&
  150. (Status != ERROR_INSUFFICIENT_BUFFER))
  151. {
  152. RegCloseKey(Key);
  153. return(Status);
  154. }
  155. NameBuffer = (LPTSTR) LocalAlloc(LPTR, (MaxSubKey + 1)*sizeof(TCHAR));
  156. if (NameBuffer == NULL)
  157. {
  158. RegCloseKey(Key);
  159. return(ERROR_NOT_ENOUGH_MEMORY);
  160. }
  161. //
  162. // Enumerate subkeys and apply ourselves to each one.
  163. //
  164. i=0;
  165. do
  166. {
  167. Status = RegEnumKey(Key,
  168. i,
  169. NameBuffer,
  170. MaxSubKey+1);
  171. if (Status == ERROR_SUCCESS)
  172. {
  173. Status = RegDeleteKeyRecursive(Key,NameBuffer);
  174. }
  175. if (Status != ERROR_SUCCESS)
  176. {
  177. //
  178. // Failed to delete the key at the specified index. Increment
  179. // the index and keep going. We could probably bail out here,
  180. // since the api is going to fail, but we might as well keep
  181. // going and delete everything we can.
  182. //
  183. ++i;
  184. }
  185. } while ( (Status != ERROR_NO_MORE_ITEMS) &&
  186. (i < SubKeys) );
  187. LocalFree((HLOCAL) NameBuffer);
  188. RegCloseKey(Key);
  189. return(RegDeleteKey(hKey,lpszSubKey));
  190. }
  191. #endif
  192. //
  193. // MessagePump
  194. // DESCRIPTION:
  195. // Processes the next queued message, if any.
  196. // PARAMETERS:
  197. // hDialogWnd, handle of modeless dialog.
  198. //
  199. BOOL PASCAL MessagePump(HWND hDialogWnd)
  200. {
  201. MSG Msg;
  202. BOOL fGotMessage;
  203. if ((fGotMessage = PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE)))
  204. {
  205. if (!IsDialogMessage(hDialogWnd, &Msg))
  206. {
  207. TranslateMessage(&Msg);
  208. DispatchMessage(&Msg);
  209. }
  210. }
  211. return fGotMessage;
  212. }
  213. // InternalMessageBox
  214. int PASCAL InternalMessageBox(HINSTANCE hInst,
  215. HWND hWnd,
  216. LPCTSTR pszFormat,
  217. LPCTSTR pszTitle,
  218. UINT fuStyle,
  219. ...)
  220. {
  221. TCHAR szTitle[80];
  222. TCHAR szFormat[512];
  223. LPTSTR pszMessage;
  224. BOOL fOk;
  225. int result;
  226. va_list ArgList;
  227. if (HIWORD(pszTitle))
  228. {
  229. // do nothing
  230. }
  231. else
  232. {
  233. // Allow this to be a resource ID
  234. LoadString(hInst, LOWORD(pszTitle), szTitle, ARRAYSIZE(szTitle));
  235. pszTitle = szTitle;
  236. }
  237. if (HIWORD(pszFormat))
  238. {
  239. // do nothing
  240. }
  241. else
  242. {
  243. // Allow this to be a resource ID
  244. LoadString(hInst, LOWORD(pszFormat), szFormat, ARRAYSIZE(szFormat));
  245. pszFormat = szFormat;
  246. }
  247. va_start(ArgList, fuStyle);
  248. fOk = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  249. FORMAT_MESSAGE_FROM_STRING,
  250. pszFormat,
  251. 0,
  252. 0,
  253. (LPTSTR)&pszMessage,
  254. 0,
  255. &ArgList);
  256. va_end(ArgList);
  257. if (fOk && pszMessage)
  258. {
  259. result = MessageBox(hWnd,
  260. pszMessage,
  261. pszTitle,
  262. fuStyle | MB_SETFOREGROUND);
  263. LocalFree(pszMessage);
  264. }
  265. else
  266. {
  267. return -1;
  268. }
  269. return result;
  270. }