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.

355 lines
9.5 KiB

  1. //-----------------------------------------------------------------------//
  2. //
  3. // File: delete.cpp
  4. // Created: April 1997
  5. // By: Martin Holladay (a-martih)
  6. // Purpose: Registry Delete Support for REG.CPP
  7. // Modification History:
  8. // Copied from Update.cpp and modificd - April 1997 (a-martih)
  9. // April 1999 Zeyong Xu: re-design, revision -> version 2.0
  10. //
  11. //------------------------------------------------------------------------//
  12. #include "stdafx.h"
  13. #include "reg.h"
  14. //-----------------------------------------------------------------------//
  15. //
  16. // DeleteRegistry()
  17. //
  18. //-----------------------------------------------------------------------//
  19. LONG DeleteRegistry(PAPPVARS pAppVars, UINT argc, TCHAR *argv[])
  20. {
  21. LONG nResult;
  22. //
  23. // Parse the cmd-line
  24. //
  25. nResult = ParseDeleteCmdLine(pAppVars, argc, argv);
  26. if (nResult != ERROR_SUCCESS)
  27. {
  28. return nResult;
  29. }
  30. //
  31. // Connect to the Remote Machine(s) - if applicable
  32. //
  33. nResult = RegConnectMachine(pAppVars);
  34. if (nResult != ERROR_SUCCESS)
  35. {
  36. return nResult;
  37. }
  38. // if delete a value or delete all values under this key
  39. if( pAppVars->szValueName ||
  40. pAppVars->bAllValues )
  41. {
  42. nResult = DeleteValues(pAppVars);
  43. }
  44. // if delete the key
  45. else if (Prompt(_T("\nPermanently delete the registry key %s (Y/N)? "),
  46. pAppVars->szSubKey,
  47. pAppVars->bForce))
  48. {
  49. nResult = RecursiveDeleteKey(pAppVars->hRootKey,
  50. pAppVars->szSubKey);
  51. }
  52. return nResult;
  53. }
  54. //------------------------------------------------------------------------//
  55. //
  56. // ParseDeleteCmdLine()
  57. //
  58. //------------------------------------------------------------------------//
  59. REG_STATUS ParseDeleteCmdLine(PAPPVARS pAppVars,
  60. UINT argc,
  61. TCHAR *argv[])
  62. {
  63. BOOL bHasValue = FALSE;
  64. REG_STATUS nResult;
  65. UINT i;
  66. if(argc < 3)
  67. {
  68. return REG_STATUS_TOFEWPARAMS;
  69. }
  70. else if(argc > 6)
  71. {
  72. return REG_STATUS_TOMANYPARAMS;
  73. }
  74. // Machine Name and Registry key
  75. //
  76. nResult = BreakDownKeyString(argv[2], pAppVars);
  77. if(nResult != ERROR_SUCCESS)
  78. return nResult;
  79. // parsing
  80. for(i=3; i<argc; i++)
  81. {
  82. if(!_tcsicmp(argv[i], _T("/v")))
  83. {
  84. if(bHasValue)
  85. return REG_STATUS_INVALIDPARAMS;
  86. bHasValue = TRUE;
  87. i++;
  88. if(i<argc)
  89. {
  90. pAppVars->szValueName = (TCHAR*) calloc(_tcslen(argv[i]) + 1,
  91. sizeof(TCHAR));
  92. _tcscpy(pAppVars->szValueName, argv[i]);
  93. }
  94. else
  95. return REG_STATUS_TOFEWPARAMS;
  96. }
  97. else if(!_tcsicmp(argv[i], _T("/ve")))
  98. {
  99. if(bHasValue)
  100. return REG_STATUS_INVALIDPARAMS;
  101. bHasValue = TRUE;
  102. pAppVars->szValueName = (TCHAR*) calloc(1, sizeof(TCHAR));
  103. }
  104. else if(!_tcsicmp(argv[i], _T("/va")))
  105. {
  106. if(bHasValue)
  107. return REG_STATUS_INVALIDPARAMS;
  108. bHasValue = TRUE;
  109. pAppVars->bAllValues = TRUE;
  110. }
  111. else if(!_tcsicmp(argv[i], _T("/f")))
  112. {
  113. pAppVars->bForce = TRUE;
  114. }
  115. else
  116. return REG_STATUS_INVALIDPARAMS;
  117. }
  118. return ERROR_SUCCESS;
  119. }
  120. //-----------------------------------------------------------------------//
  121. //
  122. // RecursiveDeleteKey() - Recursive registry key delete
  123. //
  124. //-----------------------------------------------------------------------//
  125. LONG RecursiveDeleteKey(HKEY hKey, LPCTSTR szName)
  126. {
  127. LONG nResult;
  128. HKEY hSubKey;
  129. DWORD dwNumOfSubkey;
  130. DWORD dwLenOfKeyName;
  131. TCHAR* pszNameBuf;
  132. DWORD dwIndex = 0;
  133. //
  134. // Open the SubKey
  135. //
  136. nResult = RegOpenKeyEx( hKey,
  137. szName,
  138. 0,
  139. KEY_ALL_ACCESS,
  140. &hSubKey);
  141. if (nResult != ERROR_SUCCESS)
  142. {
  143. return nResult;
  144. }
  145. // query key info
  146. nResult = RegQueryInfoKey(hSubKey,
  147. NULL,
  148. NULL,
  149. NULL,
  150. &dwNumOfSubkey,
  151. &dwLenOfKeyName,
  152. NULL,
  153. NULL,
  154. NULL,
  155. NULL,
  156. NULL,
  157. NULL);
  158. if (nResult != ERROR_SUCCESS)
  159. {
  160. RegCloseKey(hSubKey);
  161. return nResult;
  162. }
  163. #ifndef REG_FOR_WIN2000 // ansi version for win98
  164. // fix API bugs: RegQueryInfoKey() returns non-correct length values
  165. // on remote Win98
  166. if(dwLenOfKeyName < MAX_PATH)
  167. dwLenOfKeyName = MAX_PATH;
  168. #endif
  169. // create buffer
  170. dwLenOfKeyName++;
  171. pszNameBuf = (TCHAR*) calloc(dwNumOfSubkey * dwLenOfKeyName,
  172. sizeof(TCHAR));
  173. // Now Enumerate all of the keys
  174. dwIndex = 0;
  175. while(dwIndex < dwNumOfSubkey && nResult == ERROR_SUCCESS)
  176. {
  177. DWORD dwSize = dwLenOfKeyName;
  178. nResult = RegEnumKeyEx(hSubKey,
  179. dwIndex,
  180. pszNameBuf + (dwIndex * dwLenOfKeyName),
  181. &dwSize,
  182. NULL,
  183. NULL,
  184. NULL,
  185. NULL);
  186. dwIndex++;
  187. }
  188. dwIndex = 0;
  189. while(nResult == ERROR_SUCCESS && dwIndex < dwNumOfSubkey)
  190. {
  191. nResult = RecursiveDeleteKey(hSubKey,
  192. pszNameBuf + (dwIndex * dwLenOfKeyName));
  193. if(nResult != ERROR_SUCCESS)
  194. break;
  195. dwIndex++;
  196. }
  197. // freee memory
  198. if(pszNameBuf)
  199. free(pszNameBuf);
  200. // close this subkey and delete it
  201. RegCloseKey(hSubKey);
  202. if (nResult == ERROR_SUCCESS)
  203. nResult = RegDeleteKey(hKey, szName);
  204. return nResult;
  205. }
  206. LONG DeleteValues(PAPPVARS pAppVars)
  207. {
  208. LONG nResult;
  209. HKEY hSubKey;
  210. TCHAR* pszNameBuf = NULL;
  211. DWORD dwIndex = 0;
  212. DWORD dwSize = 0;
  213. if( pAppVars->bAllValues &&
  214. !Prompt(_T("\nDelete all values under the registry key %s (Y/N)? "),
  215. pAppVars->szSubKey,
  216. pAppVars->bForce))
  217. {
  218. return ERROR_SUCCESS;
  219. }
  220. else if( pAppVars->szValueName &&
  221. !Prompt(_T("\nDelete the registry value %s (Y/N)? "),
  222. pAppVars->szValueName,
  223. pAppVars->bForce))
  224. {
  225. return ERROR_SUCCESS;
  226. }
  227. // Open the registry key
  228. nResult = RegOpenKeyEx(pAppVars->hRootKey,
  229. pAppVars->szSubKey,
  230. 0,
  231. KEY_ALL_ACCESS,
  232. &hSubKey);
  233. if( nResult != ERROR_SUCCESS)
  234. {
  235. return nResult;
  236. }
  237. if(pAppVars->szValueName) // delete a single value
  238. {
  239. nResult = RegDeleteValue(hSubKey, pAppVars->szValueName);
  240. }
  241. else if(pAppVars->bAllValues) // delete all values
  242. {
  243. // query source key info
  244. DWORD dwLenOfValueName;
  245. DWORD dwNumOfValues;
  246. nResult = RegQueryInfoKey(hSubKey,
  247. NULL,
  248. NULL,
  249. NULL,
  250. NULL,
  251. NULL,
  252. NULL,
  253. &dwNumOfValues,
  254. &dwLenOfValueName,
  255. NULL,
  256. NULL,
  257. NULL);
  258. if (nResult != ERROR_SUCCESS)
  259. {
  260. RegCloseKey(hSubKey);
  261. return nResult;
  262. }
  263. #ifndef REG_FOR_WIN2000 // ansi version for win98
  264. // fix API bugs: RegQueryInfoKey() returns non-correct length values
  265. // on remote Win98
  266. if(dwLenOfValueName < MAX_PATH)
  267. dwLenOfValueName = MAX_PATH;
  268. #endif
  269. // create buffer
  270. dwLenOfValueName++;
  271. pszNameBuf = (TCHAR*) calloc(dwNumOfValues * dwLenOfValueName,
  272. sizeof(TCHAR));
  273. // Now Enumerate all values
  274. dwIndex = 0;
  275. dwSize = 0;
  276. while(dwIndex < dwNumOfValues && nResult == ERROR_SUCCESS)
  277. {
  278. dwSize = dwLenOfValueName;
  279. nResult = RegEnumValue(hSubKey,
  280. dwIndex,
  281. pszNameBuf + (dwIndex * dwLenOfValueName),
  282. &dwSize,
  283. NULL,
  284. NULL,
  285. NULL,
  286. NULL);
  287. dwIndex++;
  288. }
  289. dwIndex = 0;
  290. while(nResult == ERROR_SUCCESS && dwIndex < dwNumOfValues)
  291. {
  292. nResult = RegDeleteValue(hSubKey,
  293. pszNameBuf + (dwIndex * dwLenOfValueName));
  294. if(nResult != ERROR_SUCCESS)
  295. break;
  296. dwIndex++;
  297. }
  298. // free memory
  299. if(pszNameBuf)
  300. free(pszNameBuf);
  301. }
  302. RegCloseKey(hSubKey);
  303. return nResult;
  304. }