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.

322 lines
7.2 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. #define DELKEY_SIZE (2 * MAX_PATH)
  129. TCHAR szDelKey[DELKEY_SIZE];
  130. lstrcpyn( szDelKey, lpSubKey, DELKEY_SIZE );
  131. szDelKey[DELKEY_SIZE-1] = TEXT('\0');
  132. return RegDelnodeRecurse(hKeyRoot, szDelKey);
  133. }
  134. //*************************************************************
  135. //
  136. // RegCleanUpValue()
  137. //
  138. // Purpose: Removes the target value and if no more values / keys
  139. // are present, removes the key. This function then
  140. // works up the parent tree removing keys if they are
  141. // also empty. If any parent key has a value / subkey,
  142. // it won't be removed.
  143. //
  144. // Parameters: hKeyRoot - Root key
  145. // lpSubKey - SubKey
  146. // lpValueName - Value to remove
  147. //
  148. //
  149. // Return: TRUE if successful
  150. // FALSE if an error occurs
  151. //
  152. //*************************************************************
  153. BOOL RegCleanUpValue (HKEY hKeyRoot, LPTSTR lpSubKey, LPTSTR lpValueName)
  154. {
  155. #define DELKEY_SIZE (2 * MAX_PATH)
  156. TCHAR szDelKey[DELKEY_SIZE];
  157. LPTSTR lpEnd;
  158. DWORD dwKeys, dwValues;
  159. LONG lResult;
  160. HKEY hKey;
  161. //
  162. // Make a copy of the subkey so we can write to it.
  163. //
  164. lstrcpyn( szDelKey, lpSubKey, DELKEY_SIZE );
  165. szDelKey[DELKEY_SIZE-1] = TEXT('\0');
  166. //
  167. // First delete the value
  168. //
  169. lResult = RegOpenKeyEx (hKeyRoot, szDelKey, 0, KEY_WRITE, &hKey);
  170. if (lResult == ERROR_SUCCESS)
  171. {
  172. lResult = RegDeleteValue (hKey, lpValueName);
  173. RegCloseKey (hKey);
  174. if (lResult != ERROR_SUCCESS)
  175. {
  176. if (lResult != ERROR_FILE_NOT_FOUND)
  177. {
  178. DebugMsg((DM_WARNING, TEXT("RegCleanUpKey: Failed to delete value <%s> with %d."), lpValueName, lResult));
  179. return FALSE;
  180. }
  181. }
  182. }
  183. //
  184. // Now loop through each of the parents. If the parent is empty
  185. // eg: no values and no other subkeys, then remove the parent and
  186. // keep working up.
  187. //
  188. lpEnd = szDelKey + lstrlen(szDelKey) - 1;
  189. while (lpEnd >= szDelKey)
  190. {
  191. //
  192. // Find the parent key
  193. //
  194. while ((lpEnd > szDelKey) && (*lpEnd != TEXT('\\')))
  195. lpEnd--;
  196. //
  197. // Open the key
  198. //
  199. lResult = RegOpenKeyEx (hKeyRoot, szDelKey, 0, KEY_READ, &hKey);
  200. if (lResult != ERROR_SUCCESS)
  201. {
  202. if (lResult == ERROR_FILE_NOT_FOUND)
  203. {
  204. goto LoopAgain;
  205. }
  206. else
  207. {
  208. DebugMsg((DM_WARNING, TEXT("RegCleanUpKey: Failed to open key <%s> with %d."), szDelKey, lResult));
  209. return FALSE;
  210. }
  211. }
  212. //
  213. // See if there any any values / keys
  214. //
  215. lResult = RegQueryInfoKey (hKey, NULL, NULL, NULL, &dwKeys, NULL, NULL,
  216. &dwValues, NULL, NULL, NULL, NULL);
  217. RegCloseKey (hKey);
  218. if (lResult != ERROR_SUCCESS)
  219. {
  220. DebugMsg((DM_WARNING, TEXT("RegCleanUpKey: Failed to query key <%s> with %d."), szDelKey, lResult));
  221. return FALSE;
  222. }
  223. //
  224. // Exit now if this key has values or keys
  225. //
  226. if ((dwKeys != 0) || (dwValues != 0))
  227. {
  228. return TRUE;
  229. }
  230. RegDeleteKey (hKeyRoot, szDelKey);
  231. LoopAgain:
  232. //
  233. // If we are at the beginning of the subkey, we can leave now.
  234. //
  235. if (lpEnd == szDelKey)
  236. {
  237. return TRUE;
  238. }
  239. //
  240. // There is a parent key. Remove the slash and loop again.
  241. //
  242. if (*lpEnd == TEXT('\\'))
  243. {
  244. *lpEnd = TEXT('\0');
  245. }
  246. }
  247. return TRUE;
  248. }