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.

319 lines
6.7 KiB

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