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.

489 lines
12 KiB

  1. /*
  2. * reg - registry wrappers
  3. */
  4. #include "tweakui.h"
  5. #pragma BEGIN_CONST_DATA
  6. #pragma END_CONST_DATA
  7. /*****************************************************************************
  8. *
  9. * RegCanModifyKey
  10. *
  11. * Returns nonzero if the current user has permission to modify the
  12. * key.
  13. *
  14. *****************************************************************************/
  15. BOOL PASCAL
  16. RegCanModifyKey(HKEY hkRoot, LPCTSTR ptszSubkey)
  17. {
  18. BOOL fRc;
  19. if (g_fNT) {
  20. HKEY hk;
  21. DWORD dw;
  22. if (RegCreateKeyEx(hkRoot, ptszSubkey, 0, c_tszNil,
  23. REG_OPTION_NON_VOLATILE, KEY_WRITE, 0, &hk,
  24. &dw) == 0) {
  25. RegCloseKey(hk);
  26. fRc = 1;
  27. } else {
  28. fRc = 0;
  29. }
  30. } else {
  31. fRc = 1;
  32. }
  33. return fRc;
  34. }
  35. /*****************************************************************************
  36. *
  37. * _RegOpenKey
  38. *
  39. * Special version for NT that always asks for MAXIMUM_ALLOWED.
  40. *
  41. *****************************************************************************/
  42. LONG PASCAL
  43. _RegOpenKey(HKEY hk, LPCTSTR ptszSubKey, PHKEY phkResult)
  44. {
  45. return RegOpenKeyEx(hk, ptszSubKey, 0, MAXIMUM_ALLOWED, phkResult);
  46. }
  47. /*****************************************************************************
  48. *
  49. * _RegCreateKey
  50. *
  51. * Special version for NT that always asks for MAXIMUM_ALLOWED.
  52. *
  53. *****************************************************************************/
  54. LONG PASCAL
  55. _RegCreateKey(HKEY hk, LPCTSTR ptszSubKey, PHKEY phkResult)
  56. {
  57. DWORD dw;
  58. if (ptszSubKey) {
  59. return RegCreateKeyEx(hk, ptszSubKey, 0, c_tszNil,
  60. REG_OPTION_NON_VOLATILE, MAXIMUM_ALLOWED, 0,
  61. phkResult, &dw);
  62. } else {
  63. return RegOpenKey(hk, ptszSubKey, phkResult);
  64. }
  65. }
  66. /*****************************************************************************
  67. *
  68. * RegDeleteValues
  69. *
  70. * Deletes all the values under a key.
  71. *
  72. *****************************************************************************/
  73. void PASCAL
  74. RegDeleteValues(HKEY hkRoot, LPCTSTR ptszSubkey)
  75. {
  76. HKEY hk;
  77. if (_RegOpenKey(hkRoot, ptszSubkey, &hk) == 0) {
  78. DWORD dw, ctch;
  79. TCHAR tszValue[ctchKeyMax];
  80. dw = 0;
  81. while (ctch = cA(tszValue),
  82. RegEnumValue(hk, dw, tszValue, &ctch, 0, 0, 0, 0) == 0) {
  83. if (RegDeleteValue(hk, tszValue) == 0) {
  84. } else {
  85. dw++;
  86. }
  87. }
  88. RegCloseKey(hk);
  89. }
  90. }
  91. /*****************************************************************************
  92. *
  93. * RegDeleteTree
  94. *
  95. * Deletes an entire registry tree.
  96. *
  97. * Windows 95's RegDeleteKey will delete an entire tree, but Windows NT
  98. * forces you to do it yourself.
  99. *
  100. * Note that you need to watch out for the case where a key is undeletable,
  101. * in which case you must skip over the key and continue as best you can.
  102. *
  103. *****************************************************************************/
  104. LONG PASCAL
  105. RegDeleteTree(HKEY hkRoot, LPCTSTR ptszSubkey)
  106. {
  107. HKEY hk;
  108. LONG lRc;
  109. lRc = RegOpenKey(hkRoot, ptszSubkey, &hk);
  110. if (lRc == 0) {
  111. DWORD dw;
  112. TCHAR tszKey[ctchKeyMax];
  113. dw = 0;
  114. while (RegEnumKey(hk, dw, tszKey, cA(tszKey)) == 0) {
  115. if (RegDeleteTree(hk, tszKey) == 0) {
  116. } else {
  117. dw++;
  118. }
  119. }
  120. RegCloseKey(hk);
  121. lRc = RegDeleteKey(hkRoot, ptszSubkey);
  122. if (lRc == 0) {
  123. } else { /* Couldn't delete the key; at least nuke the values */
  124. RegDeleteValues(hkRoot, ptszSubkey);
  125. }
  126. }
  127. return lRc;
  128. }
  129. /*****************************************************************************
  130. *
  131. * RegKeyExists
  132. *
  133. *****************************************************************************/
  134. BOOL PASCAL
  135. RegKeyExists(HKEY hkRoot, LPCTSTR ptszSubkey)
  136. {
  137. LONG cb;
  138. return RegQueryValue(hkRoot, ptszSubkey, 0, &cb) == ERROR_SUCCESS;
  139. }
  140. /*****************************************************************************
  141. *
  142. * hkOpenClsid
  143. *
  144. * Open a class id (guid) registry key, returning the hkey.
  145. *
  146. *****************************************************************************/
  147. HKEY PASCAL
  148. hkOpenClsid(PCTSTR ptszClsid)
  149. {
  150. HKEY hk = 0;
  151. _RegOpenKey(pcdii->hkClsid, ptszClsid, &hk);
  152. return hk;
  153. }
  154. /*****************************************************************************
  155. *
  156. * GetRegStr
  157. *
  158. * Generic wrapper that pulls out a registry key/subkey.
  159. *
  160. *****************************************************************************/
  161. BOOL PASCAL
  162. GetRegStr(HKEY hkRoot, LPCTSTR ptszKey, LPCTSTR ptszSubkey,
  163. LPTSTR ptszBuf, int cbBuf)
  164. {
  165. HKEY hk;
  166. BOOL fRc;
  167. if ((UINT)cbBuf >= cbCtch(1)) {
  168. ptszBuf[0] = TEXT('\0');
  169. }
  170. if (hkRoot && _RegOpenKey(hkRoot, ptszKey, &hk) == 0) {
  171. DWORD cb = cbBuf;
  172. fRc = RegQueryValueEx(hk, ptszSubkey, 0, 0, (LPBYTE)ptszBuf, &cb) == 0;
  173. RegCloseKey(hk);
  174. } else {
  175. fRc = 0;
  176. }
  177. return fRc;
  178. }
  179. /*****************************************************************************
  180. *
  181. * GetStrPkl
  182. *
  183. * Read a registry key/subkey/string value given a key location.
  184. *
  185. *****************************************************************************/
  186. BOOL PASCAL
  187. GetStrPkl(LPTSTR ptszBuf, int cbBuf, PKL pkl)
  188. {
  189. return GetRegStr(*pkl->phkRoot, pkl->ptszKey, pkl->ptszSubkey,
  190. ptszBuf, cbBuf);
  191. }
  192. /*****************************************************************************
  193. *
  194. * GetRegDword
  195. *
  196. * Read a dword, returning the default if unable.
  197. *
  198. *****************************************************************************/
  199. DWORD PASCAL
  200. GetRegDword(HHK hhk, LPCSTR pszKey, LPCSTR pszSubkey, DWORD dwDefault)
  201. {
  202. DWORD dw;
  203. if (GetRegStr(hkeyHhk(hhk), pszKey, pszSubkey, (LPTSTR)&dw, sizeof(dw))) {
  204. return dw;
  205. } else {
  206. return dwDefault;
  207. }
  208. }
  209. /*****************************************************************************
  210. *
  211. * GetDwordPkl
  212. *
  213. * Given a location, read a dword, returning the default if unable.
  214. *
  215. *****************************************************************************/
  216. DWORD PASCAL
  217. GetDwordPkl(PKL pkl, DWORD dwDefault)
  218. {
  219. DWORD dw;
  220. if (GetRegStr(*pkl->phkRoot, pkl->ptszKey,
  221. pkl->ptszSubkey, (LPTSTR)&dw, sizeof(dw))) {
  222. return dw;
  223. } else {
  224. return dwDefault;
  225. }
  226. }
  227. /*****************************************************************************
  228. *
  229. * GetRegInt
  230. *
  231. * Generic wrapper that pulls out a registry key/subkey as an unsigned.
  232. *
  233. *****************************************************************************/
  234. UINT PASCAL
  235. GetRegInt(HHK hhk, LPCSTR pszKey, LPCSTR pszSubkey, UINT uiDefault)
  236. {
  237. TCH tsz[20];
  238. if (GetRegStr(hkeyHhk(hhk), pszKey, pszSubkey, tsz, cA(tsz))) {
  239. int i = iFromPtsz(tsz);
  240. return i == iErr ? uiDefault : (UINT)i;
  241. } else {
  242. return uiDefault;
  243. }
  244. }
  245. /*****************************************************************************
  246. *
  247. * GetIntPkl
  248. *
  249. * Generic wrapper that pulls out a registry key/subkey as an unsigned.
  250. *
  251. *****************************************************************************/
  252. UINT PASCAL
  253. GetIntPkl(UINT uiDefault, PKL pkl)
  254. {
  255. return GetRegInt(*pkl->phkRoot, pkl->ptszKey, pkl->ptszSubkey, uiDefault);
  256. }
  257. /*****************************************************************************
  258. *
  259. * RegSetValuePtsz
  260. *
  261. * Generic wrapper that writes out a registry key/subkey as a string.
  262. *
  263. *****************************************************************************/
  264. BOOL PASCAL
  265. RegSetValuePtsz(HKEY hk, LPCSTR pszSubkey, LPCTSTR ptszVal)
  266. {
  267. return RegSetValueEx(hk, pszSubkey, 0, REG_SZ, (LPBYTE)ptszVal,
  268. 1 + lstrlen(ptszVal)) == ERROR_SUCCESS;
  269. }
  270. /*****************************************************************************
  271. *
  272. * SetRegStr
  273. *
  274. * Generic wrapper that writes out a registry key/subkey.
  275. *
  276. * It is an error to call this with a bad hhk.
  277. *
  278. *****************************************************************************/
  279. BOOL PASCAL
  280. SetRegStr(HHK hhk, LPCTSTR ptszKey, LPCTSTR ptszSubkey, LPCTSTR ptszVal)
  281. {
  282. BOOL fRc = FALSE;
  283. HKEY hk;
  284. if (RegCreateKey(hkeyHhk(hhk), ptszKey, &hk) == 0) {
  285. fRc = RegSetValuePtsz(hk, ptszSubkey, ptszVal);
  286. RegCloseKey(hk);
  287. }
  288. return fRc;
  289. }
  290. /*****************************************************************************
  291. *
  292. * SetStrPkl
  293. *
  294. * Set a registry key/subkey/string value given a key location.
  295. *
  296. * It is an error to call this with a bad hkRoot.
  297. *
  298. *****************************************************************************/
  299. BOOL PASCAL
  300. SetStrPkl(PKL pkl, LPCTSTR ptszVal)
  301. {
  302. return SetRegStr(*pkl->phkRoot, pkl->ptszKey, pkl->ptszSubkey, ptszVal);
  303. }
  304. /*****************************************************************************
  305. *
  306. * SetRegInt
  307. *
  308. * Generic wrapper that writes out a registry key/subkey as an
  309. * unsigned integer.
  310. *
  311. *****************************************************************************/
  312. BOOL PASCAL
  313. SetRegInt(HHK hhk, LPCSTR pszKey, LPCSTR pszSubkey, UINT ui)
  314. {
  315. TCH tsz[20];
  316. wsprintf(tsz, c_tszPercentU, ui);
  317. return SetRegStr(hhk, pszKey, pszSubkey, tsz);
  318. }
  319. /*****************************************************************************
  320. *
  321. * SetIntPkl
  322. *
  323. * Writes out a registry key/subkey as an unsigned integer.
  324. *
  325. *****************************************************************************/
  326. BOOL PASCAL
  327. SetIntPkl(UINT ui, PKL pkl)
  328. {
  329. return SetRegInt(*pkl->phkRoot, pkl->ptszKey, pkl->ptszSubkey, ui);
  330. }
  331. /*****************************************************************************
  332. *
  333. * SetRegDwordEx
  334. *
  335. * Generic wrapper that writes out a registry key/subkey as a
  336. * dword, of requested type.
  337. *
  338. *****************************************************************************/
  339. BOOL PASCAL
  340. SetRegDwordEx(HHK hhk, LPCSTR pszKey, LPCSTR pszSubkey, DWORD dw, DWORD dwType)
  341. {
  342. BOOL fRc = FALSE;
  343. HKEY hk;
  344. if (RegCreateKey(hkeyHhk(hhk), pszKey, &hk) == 0) {
  345. /* Bad prototype for RegSetValueEx forces me to cast */
  346. fRc = RegSetValueEx(hk, pszSubkey, 0, dwType, (LPBYTE)&dw, sizeof(dw)) == 0;
  347. RegCloseKey(hk);
  348. }
  349. return fRc;
  350. }
  351. /*****************************************************************************
  352. *
  353. * SetRegDword
  354. *
  355. * Generic wrapper that writes out a registry key/subkey as a
  356. * dword, but typed as REG_BINARY (Win95 does this).
  357. *
  358. *****************************************************************************/
  359. BOOL PASCAL
  360. SetRegDword(HHK hhk, LPCSTR pszKey, LPCSTR pszSubkey, DWORD dw)
  361. {
  362. return SetRegDwordEx(hhk, pszKey, pszSubkey, dw, REG_BINARY);
  363. }
  364. /*****************************************************************************
  365. *
  366. * SetRegDword2
  367. *
  368. * Generic wrapper that writes out a registry key/subkey as a
  369. * real REG_DWORD.
  370. *
  371. *****************************************************************************/
  372. BOOL PASCAL
  373. SetRegDword2(HHK hhk, LPCSTR pszKey, LPCSTR pszSubkey, DWORD dw)
  374. {
  375. return SetRegDwordEx(hhk, pszKey, pszSubkey, dw, REG_DWORD);
  376. }
  377. /*****************************************************************************
  378. *
  379. * SetDwordPkl
  380. *
  381. * Generic wrapper that writes out a registry key/subkey as a
  382. * dword, given a key location.
  383. *
  384. *****************************************************************************/
  385. BOOL PASCAL
  386. SetDwordPkl(PKL pkl, DWORD dw)
  387. {
  388. return SetRegDword(*pkl->phkRoot, pkl->ptszKey, pkl->ptszSubkey, dw);
  389. }
  390. /*****************************************************************************
  391. *
  392. * SetDwordPkl2
  393. *
  394. * Generic wrapper that writes out a registry key/subkey as a
  395. * real REG_DWORD, given a key location.
  396. *
  397. *****************************************************************************/
  398. BOOL PASCAL
  399. SetDwordPkl2(PKL pkl, DWORD dw)
  400. {
  401. return SetRegDword2(*pkl->phkRoot, pkl->ptszKey, pkl->ptszSubkey, dw);
  402. }
  403. /*****************************************************************************
  404. *
  405. * DelPkl
  406. *
  407. * Generic wrapper that deletes a registry key/subkey.
  408. *
  409. *****************************************************************************/
  410. BOOL PASCAL
  411. DelPkl(PKL pkl)
  412. {
  413. BOOL fRc;
  414. HKEY hk;
  415. LONG lRc;
  416. lRc = _RegOpenKey(*pkl->phkRoot, pkl->ptszKey, &hk);
  417. switch (lRc) {
  418. case ERROR_SUCCESS:
  419. fRc = RegDeleteValue(hk, pkl->ptszSubkey) == 0;
  420. RegCloseKey(hk);
  421. break;
  422. case ERROR_FILE_NOT_FOUND:
  423. case ERROR_PATH_NOT_FOUND:
  424. fRc = TRUE; /* if it doesn't exist, then that's okay */
  425. break;
  426. default:
  427. fRc = FALSE;
  428. break;
  429. }
  430. return fRc;
  431. }