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.

538 lines
12 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1998.
  5. //
  6. // File: safereg.cxx
  7. //
  8. // Contents: Implementation of Win32 registry API C++ wrapper
  9. //
  10. // Classes: CSafeReg
  11. //
  12. // History: 1-02-1997 DavidMun Created
  13. //
  14. //---------------------------------------------------------------------------
  15. #include "precomp.hxx"
  16. #include "safereg.hxx"
  17. //+--------------------------------------------------------------------------
  18. //
  19. // Member: CSafeReg::Close
  20. //
  21. // Synopsis: Close the key if it is open.
  22. //
  23. // History: 3-31-1997 DavidMun Created
  24. //
  25. //---------------------------------------------------------------------------
  26. VOID
  27. CSafeReg::Close()
  28. {
  29. // TRACE_METHOD(CSafeReg, Close);
  30. if (_hKey)
  31. {
  32. LONG lr = RegCloseKey(_hKey);
  33. ASSERT(lr == ERROR_SUCCESS);
  34. _hKey = NULL;
  35. }
  36. }
  37. //+--------------------------------------------------------------------------
  38. //
  39. // Member: CSafeReg::Create
  40. //
  41. // Synopsis: Creates a new key with write access.
  42. //
  43. // Arguments: [wszSubKey] - name of new key
  44. // [pshkNew] - given new key; must not already have a key
  45. //
  46. // Returns: HRESULT
  47. //
  48. // Modifies: *[pshkNew]
  49. //
  50. // History: 3-31-1997 DavidMun Created
  51. //
  52. //---------------------------------------------------------------------------
  53. HRESULT
  54. CSafeReg::Create(
  55. LPCWSTR wszSubKey,
  56. CSafeReg *pshkNew)
  57. {
  58. ASSERT(_hKey);
  59. ASSERT(!pshkNew->_hKey);
  60. HRESULT hr = S_OK;
  61. LONG lr;
  62. DWORD dwDisposition;
  63. lr = RegCreateKeyEx(_hKey,
  64. wszSubKey,
  65. 0,
  66. NULL,
  67. REG_OPTION_NON_VOLATILE,
  68. KEY_WRITE,
  69. NULL,
  70. &pshkNew->_hKey,
  71. &dwDisposition);
  72. if (lr != ERROR_SUCCESS)
  73. {
  74. hr = HRESULT_FROM_WIN32(lr);
  75. }
  76. return hr;
  77. }
  78. //+--------------------------------------------------------------------------
  79. //
  80. // Member: CSafeReg::Connect
  81. //
  82. // Synopsis: Open a connection to HKLM or HKEY_USERS on
  83. // [ptszMachineName].
  84. //
  85. // Arguments: [ptszMachineName] - remote machine name.
  86. // [hkeyPredefined] - HKEY_LOCAL_MACHINE or HKEY_USERS.
  87. //
  88. // Returns: HRESULT
  89. //
  90. // History: 2-07-1997 DavidMun Created
  91. //
  92. //---------------------------------------------------------------------------
  93. HRESULT
  94. CSafeReg::Connect(
  95. LPCWSTR pwszMachineName,
  96. HKEY hkeyPredefined)
  97. {
  98. ASSERT(!_hKey);
  99. ASSERT(pwszMachineName);
  100. ASSERT(hkeyPredefined == HKEY_LOCAL_MACHINE ||
  101. hkeyPredefined == HKEY_USERS);
  102. HRESULT hr = S_OK;
  103. LONG lr;
  104. lr = RegConnectRegistry((LPWSTR)pwszMachineName,
  105. hkeyPredefined,
  106. &_hKey);
  107. if (lr != ERROR_SUCCESS)
  108. {
  109. hr = HRESULT_FROM_WIN32(lr);
  110. }
  111. return hr;
  112. }
  113. //+--------------------------------------------------------------------------
  114. //
  115. // Member: CSafeReg::Enum
  116. //
  117. // Synopsis: Wraps the RegEnumKeyEx API.
  118. //
  119. // Arguments: [ulSubKey] - 0-based subkey index
  120. // [pwszSubkeyName] - buffer to hold subkey
  121. // [cchSubkeyName] - size of buffer
  122. //
  123. // Returns: S_OK - success
  124. // S_FALSE - no more items
  125. // E_* - enum api failed
  126. //
  127. // Modifies: *[pwszSubkeyName]
  128. //
  129. // History: 2-10-1997 DavidMun Created
  130. //
  131. //---------------------------------------------------------------------------
  132. HRESULT
  133. CSafeReg::Enum(
  134. ULONG ulSubKey,
  135. LPWSTR pwszSubkeyName,
  136. ULONG cchSubkeyName)
  137. {
  138. ASSERT(_hKey);
  139. HRESULT hr = S_OK;
  140. LONG lr;
  141. FILETIME ftLastWrite;
  142. lr = RegEnumKeyEx(_hKey,
  143. ulSubKey,
  144. pwszSubkeyName,
  145. &cchSubkeyName,
  146. NULL,
  147. NULL,
  148. NULL,
  149. &ftLastWrite);
  150. if (lr != ERROR_SUCCESS)
  151. {
  152. if (lr == ERROR_NO_MORE_ITEMS)
  153. {
  154. hr = S_FALSE;
  155. }
  156. else
  157. {
  158. hr = HRESULT_FROM_WIN32(lr);
  159. }
  160. }
  161. return hr;
  162. }
  163. //+--------------------------------------------------------------------------
  164. //
  165. // Member: CSafeReg::Open
  166. //
  167. // Synopsis: Wraps the RegOpenKeyEx function.
  168. //
  169. // Arguments: [hKeyParent] - open parent key
  170. // [lpszKeyName] - name of key to open
  171. // [samDesired] - desired access level
  172. //
  173. // Returns: HRESULT representing result of RegOpenKeyEx.
  174. //
  175. // History: 1-13-1997 DavidMun Created
  176. //
  177. //---------------------------------------------------------------------------
  178. HRESULT
  179. CSafeReg::Open(
  180. HKEY hKeyParent,
  181. LPCTSTR lpszKeyName,
  182. REGSAM samDesired)
  183. {
  184. // TRACE_METHOD(CSafeReg, Open);
  185. ASSERT(hKeyParent);
  186. ASSERT(!_hKey);
  187. HRESULT hr = S_OK;
  188. HKEY hKey = NULL;
  189. LONG lr = RegOpenKeyEx(hKeyParent, lpszKeyName, 0, samDesired, &hKey);
  190. if (lr == ERROR_SUCCESS)
  191. {
  192. _hKey = hKey;
  193. }
  194. else
  195. {
  196. hr = HRESULT_FROM_WIN32(lr);
  197. }
  198. return hr;
  199. }
  200. //+--------------------------------------------------------------------------
  201. //
  202. // Member: CSafeReg::QueryBufSize
  203. //
  204. // Synopsis: Fill *[pcb] with the number bytes required to hold the
  205. // value specified by [wszValueName].
  206. //
  207. // Arguments: [wszValueName] - name of registry value on this key
  208. // [pcb] - filled with required buffer size, in bytes
  209. //
  210. // Returns: HRESULT
  211. //
  212. // Modifies: *[pcb]
  213. //
  214. // History: 2-24-1997 DavidMun Created
  215. //
  216. //---------------------------------------------------------------------------
  217. HRESULT
  218. CSafeReg::QueryBufSize(
  219. LPWSTR wszValueName,
  220. ULONG *pcb)
  221. {
  222. HRESULT hr = S_OK;
  223. LONG lr;
  224. ULONG ulType;
  225. lr = RegQueryValueEx(_hKey, wszValueName, NULL, NULL, NULL, pcb);
  226. if (lr != ERROR_SUCCESS)
  227. {
  228. hr = E_FAIL;
  229. }
  230. return hr;
  231. }
  232. //+--------------------------------------------------------------------------
  233. //
  234. // Member: CSafeReg::QueryDword
  235. //
  236. // Synopsis: Fill *[pdw] with the reg dword for value [wszValueName] on
  237. // this key.
  238. //
  239. // Arguments: [wszValueName] - name of dword value
  240. // [pdw] - filled with dword
  241. //
  242. // Returns: HRESULT from Registry call.
  243. //
  244. // Modifies: *[pdw]
  245. //
  246. // History: 1-15-1997 DavidMun Created
  247. //
  248. //---------------------------------------------------------------------------
  249. HRESULT
  250. CSafeReg::QueryDword(
  251. LPWSTR wszValueName,
  252. LPDWORD pdw)
  253. {
  254. // TRACE_METHOD(CSafeReg, QueryDword);
  255. ASSERT(_hKey);
  256. HRESULT hr = S_OK;
  257. ULONG cbData = sizeof(*pdw);
  258. ULONG ulType;
  259. LONG lr = RegQueryValueEx(_hKey,
  260. wszValueName,
  261. NULL,
  262. &ulType,
  263. (LPBYTE) pdw,
  264. &cbData);
  265. if (lr != ERROR_SUCCESS)
  266. {
  267. hr = E_FAIL;
  268. }
  269. else
  270. {
  271. ASSERT(REG_DWORD == ulType);
  272. }
  273. return hr;
  274. }
  275. //+--------------------------------------------------------------------------
  276. //
  277. // Member: CSafeReg::QueryPath
  278. //
  279. // Synopsis: Query this key for a value named [pwszValueName], which is
  280. // expected to be of type REG_SZ or REG_EXPAND_SZ, and put
  281. // the result in [pwszPathBuf].
  282. //
  283. // Arguments: [pwszValueName] - value to query for
  284. // [pwszPathBuf] - buffer for string
  285. // [cchPathBuf] - size, in wchars, of [pwszPathBuf]
  286. // [fExpand] - TRUE=>expand a REG_EXPAND_SZ string,
  287. // FALSE=>just copy it
  288. //
  289. // Returns: S_OK - [pwszPathBuf] valid
  290. // E_* - [pwszPathBuf] is an empty string
  291. //
  292. // Modifies: *[pwszPathBuf]
  293. //
  294. // History: 2-10-1997 DavidMun Created
  295. //
  296. // Notes: Strings are expanded using environment variables for the
  297. // current process, i.e., on the local machine, even if this
  298. // contains a key to a remote machine's registry.
  299. //
  300. //---------------------------------------------------------------------------
  301. HRESULT
  302. CSafeReg::QueryPath(
  303. LPWSTR pwszValueName,
  304. LPWSTR pwszPathBuf,
  305. ULONG cchPathBuf,
  306. BOOL fExpand)
  307. {
  308. // TRACE_METHOD(CSafeReg, QueryPath);
  309. ASSERT(_hKey);
  310. HRESULT hr = S_OK;
  311. DWORD dwType;
  312. *pwszPathBuf = L'\0'; // init for failure case
  313. LONG lr;
  314. ULONG cbPath = cchPathBuf * sizeof(WCHAR);
  315. lr = RegQueryValueEx(_hKey,
  316. pwszValueName,
  317. NULL,
  318. &dwType,
  319. (LPBYTE) pwszPathBuf,
  320. &cbPath);
  321. if (lr == ERROR_SUCCESS && dwType == REG_EXPAND_SZ)
  322. {
  323. if (fExpand)
  324. {
  325. LPWSTR pwszExpandedPath = new WCHAR[cchPathBuf];
  326. if (pwszExpandedPath)
  327. {
  328. lr = ExpandEnvironmentStrings(pwszPathBuf,
  329. pwszExpandedPath,
  330. cchPathBuf);
  331. if (!lr || (ULONG) lr > cchPathBuf)
  332. {
  333. if (!lr)
  334. {
  335. hr = HRESULT_FROM_WIN32(GetLastError());
  336. }
  337. else
  338. {
  339. hr = E_FAIL;
  340. }
  341. }
  342. else
  343. {
  344. lstrcpy(pwszPathBuf, pwszExpandedPath);
  345. }
  346. delete [] pwszExpandedPath;
  347. }
  348. else
  349. {
  350. hr = E_OUTOFMEMORY;
  351. }
  352. }
  353. }
  354. else if (lr == ERROR_SUCCESS && dwType != REG_SZ)
  355. {
  356. hr = E_FAIL;
  357. }
  358. else
  359. {
  360. hr = HRESULT_FROM_WIN32(lr);
  361. }
  362. return hr;
  363. }
  364. HRESULT
  365. CSafeReg::QueryStr(
  366. LPWSTR pwszValueName,
  367. LPWSTR pwszBuf,
  368. ULONG cchBuf)
  369. {
  370. // TRACE_METHOD(CSafeReg, QueryStr);
  371. ASSERT(_hKey);
  372. HRESULT hr = S_OK;
  373. DWORD dwType;
  374. *pwszBuf = L'\0'; // init for failure case
  375. LONG lr;
  376. ULONG cbBuf = cchBuf * sizeof(WCHAR);
  377. lr = RegQueryValueEx(_hKey,
  378. pwszValueName,
  379. NULL,
  380. &dwType,
  381. (LPBYTE) pwszBuf,
  382. &cbBuf);
  383. if (lr == ERROR_SUCCESS &&
  384. dwType != REG_SZ &&
  385. dwType != REG_MULTI_SZ &&
  386. dwType != REG_EXPAND_SZ)
  387. {
  388. hr = E_FAIL;
  389. }
  390. else if (lr != ERROR_SUCCESS)
  391. {
  392. hr = HRESULT_FROM_WIN32(lr);
  393. }
  394. return hr;
  395. }
  396. //+--------------------------------------------------------------------------
  397. //
  398. // Member: CSafeReg::SetDword
  399. //
  400. // Synopsis: Set a value with name [wszValueName] and type REG_DWORD on
  401. // the currently open key.
  402. //
  403. // Arguments: [wszValueName] - name of value to create or set
  404. // [dw] - dword to set
  405. //
  406. // Returns: Result of RegSetValueEx call.
  407. //
  408. // History: 1-20-1997 DavidMun Created
  409. //
  410. //---------------------------------------------------------------------------
  411. HRESULT
  412. CSafeReg::SetDword(
  413. LPWSTR wszValueName,
  414. DWORD dw)
  415. {
  416. ASSERT(_hKey);
  417. HRESULT hr = S_OK;
  418. LONG lr = RegSetValueEx(_hKey,
  419. wszValueName,
  420. 0,
  421. REG_DWORD,
  422. (PBYTE) &dw,
  423. sizeof dw);
  424. if (lr != ERROR_SUCCESS)
  425. {
  426. hr = HRESULT_FROM_WIN32(lr);
  427. }
  428. return hr;
  429. }
  430. HRESULT
  431. CSafeReg::SetValue(
  432. LPCWSTR wszValueName,
  433. ULONG ulType,
  434. const BYTE *pbValue,
  435. ULONG cbValue)
  436. {
  437. ASSERT(_hKey);
  438. HRESULT hr = S_OK;
  439. LONG lr = RegSetValueEx(_hKey,
  440. wszValueName,
  441. 0,
  442. ulType,
  443. pbValue,
  444. cbValue);
  445. if (lr != ERROR_SUCCESS)
  446. {
  447. hr = HRESULT_FROM_WIN32(lr);
  448. }
  449. return hr;
  450. }