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.

314 lines
6.7 KiB

  1. #include "main.h"
  2. //*************************************************************
  3. //
  4. // CheckSlash()
  5. //
  6. // Purpose: Checks for an ending slash and adds one if
  7. // it is missing.
  8. //
  9. // Parameters: lpDir - directory
  10. //
  11. // Return: Pointer to the end of the string
  12. //
  13. // Comments:
  14. //
  15. // History: Date Author Comment
  16. // 6/19/95 ericflo Created
  17. //
  18. //*************************************************************
  19. LPTSTR CheckSlash (LPTSTR lpDir)
  20. {
  21. DWORD dwStrLen;
  22. LPTSTR lpEnd;
  23. lpEnd = lpDir + lstrlen(lpDir);
  24. if (*(lpEnd - 1) != TEXT('\\')) {
  25. *lpEnd = TEXT('\\');
  26. lpEnd++;
  27. *lpEnd = TEXT('\0');
  28. }
  29. return lpEnd;
  30. }
  31. //*************************************************************
  32. //
  33. // RegDelnodeRecurse()
  34. //
  35. // Purpose: Deletes a registry key and all it's subkeys / values.
  36. // Called by RegDelnode
  37. //
  38. // Parameters: hKeyRoot - Root key
  39. // lpSubKey - SubKey to delete
  40. //
  41. // Return: TRUE if successful
  42. // FALSE if an error occurs
  43. //
  44. // Comments:
  45. //
  46. // History: Date Author Comment
  47. // 10/3/95 ericflo Created
  48. //
  49. //*************************************************************
  50. BOOL RegDelnodeRecurse (HKEY hKeyRoot, LPTSTR lpSubKey)
  51. {
  52. LPTSTR lpEnd;
  53. LONG lResult;
  54. DWORD dwSize;
  55. TCHAR szName[MAX_PATH];
  56. HKEY hKey;
  57. FILETIME ftWrite;
  58. //
  59. // First, see if we can delete the key without having
  60. // to recurse.
  61. //
  62. lResult = RegDeleteKey(hKeyRoot, lpSubKey);
  63. if (lResult == ERROR_SUCCESS) {
  64. return TRUE;
  65. }
  66. lResult = RegOpenKeyEx (hKeyRoot, lpSubKey, 0, KEY_READ, &hKey);
  67. if (lResult != ERROR_SUCCESS) {
  68. return FALSE;
  69. }
  70. lpEnd = CheckSlash(lpSubKey);
  71. //
  72. // Enumerate the keys
  73. //
  74. dwSize = MAX_PATH;
  75. lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL,
  76. NULL, NULL, &ftWrite);
  77. if (lResult == ERROR_SUCCESS) {
  78. do {
  79. lstrcpy (lpEnd, szName);
  80. if (!RegDelnodeRecurse(hKeyRoot, lpSubKey)) {
  81. break;
  82. }
  83. //
  84. // Enumerate again
  85. //
  86. dwSize = MAX_PATH;
  87. lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL,
  88. NULL, NULL, &ftWrite);
  89. } while (lResult == ERROR_SUCCESS);
  90. }
  91. lpEnd--;
  92. *lpEnd = TEXT('\0');
  93. RegCloseKey (hKey);
  94. //
  95. // Try again to delete the key
  96. //
  97. lResult = RegDeleteKey(hKeyRoot, lpSubKey);
  98. if (lResult == ERROR_SUCCESS) {
  99. return TRUE;
  100. }
  101. return FALSE;
  102. }
  103. //*************************************************************
  104. //
  105. // RegDelnode()
  106. //
  107. // Purpose: Deletes a registry key and all it's subkeys / values
  108. //
  109. // Parameters: hKeyRoot - Root key
  110. // lpSubKey - SubKey to delete
  111. //
  112. // Return: TRUE if successful
  113. // FALSE if an error occurs
  114. //
  115. // Comments:
  116. //
  117. // History: Date Author Comment
  118. // 10/3/95 ericflo Created
  119. //
  120. //*************************************************************
  121. BOOL RegDelnode (HKEY hKeyRoot, LPTSTR lpSubKey)
  122. {
  123. TCHAR szDelKey[2 * MAX_PATH];
  124. lstrcpy (szDelKey, lpSubKey);
  125. return RegDelnodeRecurse(hKeyRoot, szDelKey);
  126. }
  127. //*************************************************************
  128. //
  129. // RegCleanUpValue()
  130. //
  131. // Purpose: Removes the target value and if no more values / keys
  132. // are present, removes the key. This function then
  133. // works up the parent tree removing keys if they are
  134. // also empty. If any parent key has a value / subkey,
  135. // it won't be removed.
  136. //
  137. // Parameters: hKeyRoot - Root key
  138. // lpSubKey - SubKey
  139. // lpValueName - Value to remove
  140. //
  141. //
  142. // Return: TRUE if successful
  143. // FALSE if an error occurs
  144. //
  145. //*************************************************************
  146. BOOL RegCleanUpValue (HKEY hKeyRoot, LPTSTR lpSubKey, LPTSTR lpValueName)
  147. {
  148. TCHAR szDelKey[2 * MAX_PATH];
  149. LPTSTR lpEnd;
  150. DWORD dwKeys, dwValues;
  151. LONG lResult;
  152. HKEY hKey;
  153. //
  154. // Make a copy of the subkey so we can write to it.
  155. //
  156. lstrcpy (szDelKey, lpSubKey);
  157. //
  158. // First delete the value
  159. //
  160. lResult = RegOpenKeyEx (hKeyRoot, szDelKey, 0, KEY_WRITE, &hKey);
  161. if (lResult == ERROR_SUCCESS)
  162. {
  163. lResult = RegDeleteValue (hKey, lpValueName);
  164. RegCloseKey (hKey);
  165. if (lResult != ERROR_SUCCESS)
  166. {
  167. if (lResult != ERROR_FILE_NOT_FOUND)
  168. {
  169. DebugMsg((DM_WARNING, TEXT("RegCleanUpKey: Failed to delete value <%s> with %d."), lpValueName, lResult));
  170. return FALSE;
  171. }
  172. }
  173. }
  174. //
  175. // Now loop through each of the parents. If the parent is empty
  176. // eg: no values and no other subkeys, then remove the parent and
  177. // keep working up.
  178. //
  179. lpEnd = szDelKey + lstrlen(szDelKey) - 1;
  180. while (lpEnd >= szDelKey)
  181. {
  182. //
  183. // Find the parent key
  184. //
  185. while ((lpEnd > szDelKey) && (*lpEnd != TEXT('\\')))
  186. lpEnd--;
  187. //
  188. // Open the key
  189. //
  190. lResult = RegOpenKeyEx (hKeyRoot, szDelKey, 0, KEY_READ, &hKey);
  191. if (lResult != ERROR_SUCCESS)
  192. {
  193. if (lResult == ERROR_FILE_NOT_FOUND)
  194. {
  195. goto LoopAgain;
  196. }
  197. else
  198. {
  199. DebugMsg((DM_WARNING, TEXT("RegCleanUpKey: Failed to open key <%s> with %d."), szDelKey, lResult));
  200. return FALSE;
  201. }
  202. }
  203. //
  204. // See if there any any values / keys
  205. //
  206. lResult = RegQueryInfoKey (hKey, NULL, NULL, NULL, &dwKeys, NULL, NULL,
  207. &dwValues, NULL, NULL, NULL, NULL);
  208. RegCloseKey (hKey);
  209. if (lResult != ERROR_SUCCESS)
  210. {
  211. DebugMsg((DM_WARNING, TEXT("RegCleanUpKey: Failed to query key <%s> with %d."), szDelKey, lResult));
  212. return FALSE;
  213. }
  214. //
  215. // Exit now if this key has values or keys
  216. //
  217. if ((dwKeys != 0) || (dwValues != 0))
  218. {
  219. return TRUE;
  220. }
  221. RegDeleteKey (hKeyRoot, szDelKey);
  222. LoopAgain:
  223. //
  224. // If we are at the beginning of the subkey, we can leave now.
  225. //
  226. if (lpEnd == szDelKey)
  227. {
  228. return TRUE;
  229. }
  230. //
  231. // There is a parent key. Remove the slash and loop again.
  232. //
  233. if (*lpEnd == TEXT('\\'))
  234. {
  235. *lpEnd = TEXT('\0');
  236. }
  237. }
  238. return TRUE;
  239. }