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.

460 lines
9.7 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. tree.c
  5. Abstract:
  6. Implements routines that do operations on entire trees
  7. Author:
  8. Jim Schmidt (jimschm) 08-Mar-2000
  9. Revision History:
  10. <alias> <date> <comments>
  11. --*/
  12. #include "pch.h"
  13. //
  14. // Includes
  15. //
  16. // None
  17. #define DBG_TREE "Tree"
  18. //
  19. // Strings
  20. //
  21. // None
  22. //
  23. // Constants
  24. //
  25. // None
  26. //
  27. // Macros
  28. //
  29. // None
  30. //
  31. // Types
  32. //
  33. // None
  34. //
  35. // Globals
  36. //
  37. // None
  38. //
  39. // Macro expansion list
  40. //
  41. // None
  42. //
  43. // Private function prototypes
  44. //
  45. // None
  46. //
  47. // Macro expansion definition
  48. //
  49. // None
  50. //
  51. // Code
  52. //
  53. BOOL
  54. RgRemoveAllValuesInKeyA (
  55. IN PCSTR KeyToRemove
  56. )
  57. {
  58. REGTREE_ENUMA e;
  59. PCSTR pattern;
  60. BOOL result = TRUE;
  61. HKEY deleteHandle;
  62. REGSAM prevMode;
  63. LONG rc;
  64. pattern = ObsBuildEncodedObjectStringExA (KeyToRemove, "*", FALSE);
  65. if (EnumFirstRegObjectInTreeExA (
  66. &e,
  67. pattern,
  68. FALSE, // no key names
  69. TRUE, // ignored in this case
  70. TRUE, // values first
  71. TRUE, // depth first
  72. REGENUM_ALL_SUBLEVELS,
  73. TRUE, // use exclusions
  74. FALSE, // ReadValueData
  75. NULL
  76. )) {
  77. do {
  78. MYASSERT (!(e.Attributes & REG_ATTRIBUTE_KEY));
  79. prevMode = SetRegOpenAccessMode (KEY_ALL_ACCESS);
  80. deleteHandle = OpenRegKeyStrA (e.Location);
  81. if (deleteHandle) {
  82. rc = RegDeleteValueA (deleteHandle, e.Name);
  83. CloseRegKey (deleteHandle);
  84. SetRegOpenAccessMode (prevMode);
  85. if (rc != ERROR_SUCCESS && rc != ERROR_FILE_NOT_FOUND) {
  86. SetLastError (rc);
  87. AbortRegObjectInTreeEnumA (&e);
  88. ObsFreeA (pattern);
  89. return FALSE;
  90. }
  91. } else {
  92. SetRegOpenAccessMode (prevMode);
  93. AbortRegObjectInTreeEnumA (&e);
  94. ObsFreeA (pattern);
  95. return FALSE;
  96. }
  97. } while (EnumNextRegObjectInTreeA (&e));
  98. }
  99. ObsFreeA (pattern);
  100. return result;
  101. }
  102. BOOL
  103. RgRemoveAllValuesInKeyW (
  104. IN PCWSTR KeyToRemove
  105. )
  106. {
  107. REGTREE_ENUMW e;
  108. PCWSTR pattern;
  109. BOOL result = TRUE;
  110. HKEY deleteHandle;
  111. REGSAM prevMode;
  112. LONG rc;
  113. pattern = ObsBuildEncodedObjectStringExW (KeyToRemove, L"*", FALSE);
  114. if (EnumFirstRegObjectInTreeExW (
  115. &e,
  116. pattern,
  117. FALSE, // no key names
  118. TRUE, // ignored in this case
  119. TRUE, // values first
  120. TRUE, // depth first
  121. REGENUM_ALL_SUBLEVELS,
  122. TRUE, // use exclusions
  123. FALSE, // ReadValueData
  124. NULL
  125. )) {
  126. do {
  127. MYASSERT (!(e.Attributes & REG_ATTRIBUTE_KEY));
  128. prevMode = SetRegOpenAccessMode (KEY_ALL_ACCESS);
  129. deleteHandle = OpenRegKeyStrW (e.Location);
  130. if (deleteHandle) {
  131. rc = RegDeleteValueW (deleteHandle, e.Name);
  132. CloseRegKey (deleteHandle);
  133. SetRegOpenAccessMode (prevMode);
  134. if (rc != ERROR_SUCCESS && rc != ERROR_FILE_NOT_FOUND) {
  135. SetLastError (rc);
  136. AbortRegObjectInTreeEnumW (&e);
  137. ObsFreeW (pattern);
  138. return FALSE;
  139. }
  140. } else {
  141. SetRegOpenAccessMode (prevMode);
  142. AbortRegObjectInTreeEnumW (&e);
  143. ObsFreeW (pattern);
  144. return FALSE;
  145. }
  146. } while (EnumNextRegObjectInTreeW (&e));
  147. }
  148. ObsFreeW (pattern);
  149. return result;
  150. }
  151. BOOL
  152. pDeleteKeyStrA (
  153. IN OUT PSTR *DeleteKey
  154. )
  155. {
  156. PSTR p;
  157. HKEY key;
  158. LONG rc;
  159. if (*DeleteKey == NULL) {
  160. return TRUE;
  161. }
  162. p = (PSTR) FindLastWackA (*DeleteKey);
  163. if (p) {
  164. *p = 0;
  165. p++;
  166. key = OpenRegKeyStrA (*DeleteKey);
  167. if (key) {
  168. if (DeleteRegKeyA (key, p)) {
  169. rc = ERROR_SUCCESS;
  170. } else {
  171. rc = GetLastError ();
  172. }
  173. CloseRegKey (key);
  174. } else {
  175. rc = GetLastError();
  176. }
  177. if (rc == ERROR_FILE_NOT_FOUND) {
  178. rc = ERROR_SUCCESS;
  179. }
  180. } else {
  181. rc = ERROR_SUCCESS;
  182. }
  183. FreeTextA (*DeleteKey);
  184. *DeleteKey = NULL;
  185. SetLastError (rc);
  186. return rc == ERROR_SUCCESS;
  187. }
  188. BOOL
  189. pDeleteKeyStrW (
  190. IN OUT PWSTR *DeleteKey
  191. )
  192. {
  193. PWSTR p;
  194. HKEY key;
  195. LONG rc;
  196. if (*DeleteKey == NULL) {
  197. return TRUE;
  198. }
  199. p = (PWSTR) FindLastWackW (*DeleteKey);
  200. if (p) {
  201. *p = 0;
  202. p++;
  203. key = OpenRegKeyStrW (*DeleteKey);
  204. if (key) {
  205. if (DeleteRegKeyW (key, p)) {
  206. rc = ERROR_SUCCESS;
  207. } else {
  208. rc = GetLastError ();
  209. }
  210. CloseRegKey (key);
  211. } else {
  212. rc = GetLastError();
  213. }
  214. if (rc == ERROR_FILE_NOT_FOUND) {
  215. rc = ERROR_SUCCESS;
  216. }
  217. } else {
  218. rc = ERROR_SUCCESS;
  219. }
  220. FreeTextW (*DeleteKey);
  221. *DeleteKey = NULL;
  222. SetLastError (rc);
  223. return rc == ERROR_SUCCESS;
  224. }
  225. BOOL
  226. RgRemoveKeyA (
  227. IN PCSTR KeyToRemove
  228. )
  229. {
  230. REGTREE_ENUMA e;
  231. PCSTR pattern;
  232. BOOL result = TRUE;
  233. PSTR deleteKey = NULL;
  234. PSTR encodedKey;
  235. encodedKey = AllocTextA (ByteCountA (KeyToRemove) * 2 + 2 * sizeof (CHAR));
  236. ObsEncodeStringA (encodedKey, KeyToRemove);
  237. StringCatA (encodedKey, "\\*");
  238. pattern = ObsBuildEncodedObjectStringExA (encodedKey, NULL, FALSE);
  239. FreeTextA (encodedKey);
  240. if (EnumFirstRegObjectInTreeExA (
  241. &e,
  242. pattern,
  243. TRUE, // key names
  244. FALSE, // containers last
  245. TRUE, // values first
  246. TRUE, // depth first
  247. REGENUM_ALL_SUBLEVELS,
  248. TRUE, // use exclusions
  249. FALSE, // ReadValueData
  250. NULL
  251. )) {
  252. do {
  253. if (!pDeleteKeyStrA (&deleteKey)) {
  254. result = FALSE;
  255. break;
  256. }
  257. MYASSERT (e.Attributes & REG_ATTRIBUTE_KEY);
  258. if (!RgRemoveAllValuesInKeyA (e.NativeFullName)) {
  259. result = FALSE;
  260. break;
  261. }
  262. //
  263. // The reg enum wrappers hold on to a key handle, which prevents
  264. // us from deleting the key now. We need to hold on to the key
  265. // name, then continue on to the next item. At that time, we can
  266. // delete the key.
  267. //
  268. deleteKey = DuplicateTextA (e.NativeFullName);
  269. } while (EnumNextRegObjectInTreeA (&e));
  270. }
  271. ObsFreeA (pattern);
  272. if (result) {
  273. result = pDeleteKeyStrA (&deleteKey);
  274. result = result && RgRemoveAllValuesInKeyA (KeyToRemove);
  275. if (result) {
  276. deleteKey = DuplicateTextA (KeyToRemove);
  277. result = pDeleteKeyStrA (&deleteKey);
  278. }
  279. } else {
  280. AbortRegObjectInTreeEnumA (&e);
  281. if (deleteKey) {
  282. FreeTextA (deleteKey);
  283. INVALID_POINTER (deleteKey);
  284. }
  285. }
  286. return result;
  287. }
  288. BOOL
  289. RgRemoveKeyW (
  290. IN PCWSTR KeyToRemove
  291. )
  292. {
  293. REGTREE_ENUMW e;
  294. PCWSTR pattern;
  295. BOOL result = TRUE;
  296. PWSTR deleteKey = NULL;
  297. PWSTR encodedKey;
  298. encodedKey = AllocTextW (ByteCountW (KeyToRemove) * 2 + 2 * sizeof (WCHAR));
  299. ObsEncodeStringW (encodedKey, KeyToRemove);
  300. StringCatW (encodedKey, L"\\*");
  301. pattern = ObsBuildEncodedObjectStringExW (encodedKey, NULL, FALSE);
  302. FreeTextW (encodedKey);
  303. if (EnumFirstRegObjectInTreeExW (
  304. &e,
  305. pattern,
  306. TRUE, // key names
  307. FALSE, // containers last
  308. TRUE, // values first
  309. TRUE, // depth first
  310. REGENUM_ALL_SUBLEVELS,
  311. TRUE, // use exclusions
  312. FALSE, // ReadValueData
  313. NULL
  314. )) {
  315. do {
  316. if (!pDeleteKeyStrW (&deleteKey)) {
  317. result = FALSE;
  318. break;
  319. }
  320. MYASSERT (e.Attributes & REG_ATTRIBUTE_KEY);
  321. if (!RgRemoveAllValuesInKeyW (e.NativeFullName)) {
  322. result = FALSE;
  323. break;
  324. }
  325. //
  326. // The reg enum wrappers hold on to a key handle, which prevents
  327. // us from deleting the key now. We need to hold on to the key
  328. // name, then continue on to the next item. At that time, we can
  329. // delete the key.
  330. //
  331. deleteKey = DuplicateTextW (e.NativeFullName);
  332. } while (EnumNextRegObjectInTreeW (&e));
  333. }
  334. ObsFreeW (pattern);
  335. if (result) {
  336. result = pDeleteKeyStrW (&deleteKey);
  337. result = result && RgRemoveAllValuesInKeyW (KeyToRemove);
  338. if (result) {
  339. deleteKey = DuplicateTextW (KeyToRemove);
  340. result = pDeleteKeyStrW (&deleteKey);
  341. }
  342. } else {
  343. AbortRegObjectInTreeEnumW (&e);
  344. if (deleteKey) {
  345. FreeTextW (deleteKey);
  346. INVALID_POINTER (deleteKey);
  347. }
  348. }
  349. return result;
  350. }