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.

499 lines
13 KiB

  1. /*++
  2. Copyright (C) 1998-2001 Microsoft Corporation
  3. Module Name:
  4. REG.CPP
  5. Abstract:
  6. Utility Registry classes
  7. History:
  8. raymcc 30-May-96 Created.
  9. raymcc 26-Jul-99 Updated for TCHAR.
  10. --*/
  11. #include "precomp.h"
  12. #include <wbemcli.h>
  13. #include <stdio.h>
  14. #include <reg.h>
  15. #include <tchar.h>
  16. #include <malloc.h>
  17. //***************************************************************************
  18. //
  19. //***************************************************************************
  20. // ok
  21. int Registry::Open(HKEY hStart, TCHAR *pszStartKey)
  22. {
  23. int nStatus = no_error;
  24. DWORD dwDisp = 0;
  25. m_nLastError = RegCreateKeyEx(hStart, pszStartKey,
  26. 0, 0, 0,
  27. KEY_ALL_ACCESS, 0, &hPrimaryKey, &dwDisp);
  28. if (m_nLastError != 0)
  29. nStatus = failed;
  30. return nStatus;
  31. }
  32. //***************************************************************************
  33. //
  34. //***************************************************************************
  35. // ok
  36. Registry::Registry(HKEY hRoot, REGSAM flags, TCHAR *pszStartKey)
  37. {
  38. hPrimaryKey = 0;
  39. hSubkey = 0;
  40. nStatus = RegOpenKeyEx(hRoot, pszStartKey,
  41. 0, flags, &hPrimaryKey
  42. );
  43. hSubkey = hPrimaryKey;
  44. m_nLastError = nStatus;
  45. }
  46. //***************************************************************************
  47. //
  48. //***************************************************************************
  49. // ok
  50. Registry::Registry(HKEY hRoot, DWORD dwOptions, REGSAM flags, TCHAR *pszStartKey)
  51. {
  52. hPrimaryKey = 0;
  53. hSubkey = 0;
  54. int nStatus = no_error;
  55. DWORD dwDisp = 0;
  56. m_nLastError = RegCreateKeyEx(hRoot, pszStartKey,
  57. 0, 0, dwOptions,
  58. flags, 0, &hPrimaryKey, &dwDisp
  59. );
  60. hSubkey = hPrimaryKey;
  61. }
  62. //***************************************************************************
  63. //
  64. //***************************************************************************
  65. // ok
  66. Registry::Registry(TCHAR *pszLocalMachineStartKey)
  67. {
  68. hPrimaryKey = 0;
  69. hSubkey = 0;
  70. nStatus = Open(HKEY_LOCAL_MACHINE, pszLocalMachineStartKey);
  71. hSubkey = hPrimaryKey;
  72. }
  73. //***************************************************************************
  74. //
  75. //***************************************************************************
  76. // ok
  77. Registry::Registry()
  78. {
  79. hPrimaryKey = 0;
  80. hSubkey = 0;
  81. nStatus = 0;
  82. hSubkey = 0;
  83. }
  84. //***************************************************************************
  85. //
  86. //***************************************************************************
  87. // ok
  88. Registry::~Registry()
  89. {
  90. if (hSubkey)
  91. RegCloseKey(hSubkey);
  92. if (hPrimaryKey != hSubkey)
  93. RegCloseKey(hPrimaryKey);
  94. }
  95. //***************************************************************************
  96. //
  97. //***************************************************************************
  98. // ok
  99. int Registry::MoveToSubkey(TCHAR *pszNewSubkey)
  100. {
  101. DWORD dwDisp = 0;
  102. m_nLastError = RegCreateKeyEx(hPrimaryKey, pszNewSubkey, 0, 0, 0, KEY_ALL_ACCESS,
  103. 0, &hSubkey, &dwDisp);
  104. if (m_nLastError != 0)
  105. return failed;
  106. return no_error;
  107. }
  108. //***************************************************************************
  109. //
  110. //***************************************************************************
  111. // ok
  112. int Registry::GetDWORD(TCHAR *pszValueName, DWORD *pdwValue)
  113. {
  114. DWORD dwSize = sizeof(DWORD);
  115. DWORD dwType = 0;
  116. if(hSubkey == NULL)
  117. return failed;
  118. m_nLastError = RegQueryValueEx(hSubkey, pszValueName, 0, &dwType,
  119. LPBYTE(pdwValue), &dwSize);
  120. if (m_nLastError != 0)
  121. return failed;
  122. if (dwType != REG_DWORD)
  123. return failed;
  124. return no_error;
  125. }
  126. //***************************************************************************
  127. //
  128. //***************************************************************************
  129. // ok
  130. int Registry::GetType(TCHAR *pszValueName, DWORD *pdwType)
  131. {
  132. if(hSubkey == NULL)
  133. return failed;
  134. m_nLastError = RegQueryValueEx(hSubkey, pszValueName, 0, pdwType,
  135. NULL, NULL);
  136. if (m_nLastError != 0)
  137. return failed;
  138. return no_error;
  139. }
  140. //***************************************************************************
  141. //
  142. //***************************************************************************
  143. // ok
  144. int Registry::GetDWORDStr(TCHAR *pszValueName, DWORD *pdwValue)
  145. {
  146. TCHAR cTemp[25];
  147. DWORD dwSize = 25;
  148. DWORD dwType = 0;
  149. TCHAR * pEnd = NULL; // gets set to character that stopped the scan
  150. if(hSubkey == NULL)
  151. return failed;
  152. m_nLastError = RegQueryValueEx(hSubkey, pszValueName, 0, &dwType,
  153. (LPBYTE)cTemp, &dwSize);
  154. if (m_nLastError != 0)
  155. return failed;
  156. if (dwType != REG_SZ)
  157. return failed;
  158. *pdwValue = wcstoul(cTemp, &pEnd, 10);
  159. if(pEnd == NULL || pEnd == cTemp)
  160. return failed;
  161. else
  162. return no_error;
  163. }
  164. //***************************************************************************
  165. //
  166. // Use operator delete on the returned pointer!!
  167. //
  168. //***************************************************************************
  169. // ok
  170. int Registry::GetBinary(TCHAR *pszValue, byte ** pData, DWORD * pdwSize)
  171. {
  172. *pData = 0;
  173. DWORD dwSize = 0;
  174. DWORD dwType = 0;
  175. if(m_nLastError)
  176. return failed;
  177. m_nLastError = RegQueryValueEx(hSubkey, pszValue, 0, &dwType,
  178. 0, &dwSize);
  179. if (m_nLastError != 0)
  180. return failed;
  181. if (dwType != REG_BINARY)
  182. return failed;
  183. byte *p = new byte[dwSize];
  184. if (p == NULL)
  185. return failed;
  186. m_nLastError = RegQueryValueEx(hSubkey, pszValue, 0, &dwType,
  187. LPBYTE(p), &dwSize);
  188. if (m_nLastError != 0)
  189. {
  190. delete [] p;
  191. return failed;
  192. }
  193. *pdwSize = dwSize;
  194. *pData = p;
  195. return no_error;
  196. }
  197. //***************************************************************************
  198. //
  199. //***************************************************************************
  200. // ok
  201. int Registry::SetBinary(TCHAR *pszValue, byte * pData, DWORD dwSize)
  202. {
  203. if(hSubkey == NULL)
  204. return failed;
  205. m_nLastError = RegSetValueEx(hSubkey, pszValue, 0, REG_BINARY, pData, dwSize);
  206. if (m_nLastError != 0)
  207. return failed;
  208. return no_error;
  209. }
  210. //***************************************************************************
  211. //
  212. //***************************************************************************
  213. // ok
  214. int Registry::SetDWORD(TCHAR *pszValueName, DWORD dwValue)
  215. {
  216. if(hSubkey == NULL)
  217. return failed;
  218. m_nLastError = RegSetValueEx(hSubkey, pszValueName, 0, REG_DWORD, LPBYTE(&dwValue),
  219. sizeof(DWORD));
  220. if (m_nLastError != 0)
  221. return failed;
  222. return no_error;
  223. }
  224. //***************************************************************************
  225. //
  226. //***************************************************************************
  227. // ok
  228. int Registry::SetDWORDStr(TCHAR *pszValueName, DWORD dwVal)
  229. {
  230. TCHAR cTemp[30];
  231. _stprintf(cTemp,__TEXT("%d"),dwVal);
  232. if(hSubkey == NULL)
  233. return failed;
  234. m_nLastError = RegSetValueEx(hSubkey, pszValueName, 0, REG_SZ, LPBYTE(cTemp),
  235. (_tcslen(cTemp)+1) * sizeof(TCHAR));
  236. if (m_nLastError != 0)
  237. return failed;
  238. return no_error;
  239. }
  240. //***************************************************************************
  241. //
  242. //***************************************************************************
  243. // ok
  244. int Registry::DeleteValue(TCHAR *pszValueName)
  245. {
  246. if(hSubkey == NULL)
  247. return failed;
  248. return RegDeleteValue(hSubkey, pszValueName);
  249. }
  250. //***************************************************************************
  251. //
  252. //***************************************************************************
  253. // ok
  254. int Registry::SetMultiStr(TCHAR *pszValueName, TCHAR * pszValue, DWORD dwSize)
  255. {
  256. if(hSubkey == NULL)
  257. return failed;
  258. m_nLastError = RegSetValueEx(hSubkey,
  259. pszValueName,
  260. 0,
  261. REG_MULTI_SZ,
  262. LPBYTE(pszValue),
  263. dwSize);
  264. if (m_nLastError != 0)
  265. return failed;
  266. return no_error;
  267. }
  268. //***************************************************************************
  269. //
  270. //***************************************************************************
  271. // ok
  272. int Registry::SetStr(TCHAR *pszValueName, TCHAR *pszValue)
  273. {
  274. int nSize = (_tcslen(pszValue)+1) * sizeof(TCHAR);
  275. if(hSubkey == NULL)
  276. return failed;
  277. m_nLastError = RegSetValueEx(hSubkey, pszValueName, 0, REG_SZ, LPBYTE(pszValue), nSize);
  278. if (m_nLastError != 0)
  279. return failed;
  280. return no_error;
  281. }
  282. //***************************************************************************
  283. //
  284. //***************************************************************************
  285. // ok
  286. int Registry::SetExpandStr(TCHAR *pszValueName, TCHAR *pszValue)
  287. {
  288. int nSize = (_tcslen(pszValue)+1) * sizeof(TCHAR);
  289. if(hSubkey == NULL)
  290. return failed;
  291. m_nLastError = RegSetValueEx(hSubkey, pszValueName, 0, REG_EXPAND_SZ, LPBYTE(pszValue), nSize);
  292. if (m_nLastError != 0)
  293. return failed;
  294. return no_error;
  295. }
  296. //***************************************************************************
  297. //
  298. //***************************************************************************
  299. // ok
  300. TCHAR* Registry::GetMultiStr(TCHAR *pszValueName, DWORD &dwSize)
  301. {
  302. //Find out the size of the buffer required
  303. DWORD dwType;
  304. if(hSubkey == NULL)
  305. return NULL;
  306. m_nLastError = RegQueryValueEx(hSubkey, pszValueName, 0, &dwType, NULL, &dwSize);
  307. if ((m_nLastError == ERROR_SUCCESS) && (dwType != REG_MULTI_SZ))
  308. {
  309. m_nLastError = WBEM_E_TYPE_MISMATCH;
  310. dwSize = 0;
  311. return NULL;
  312. }
  313. //If the error is an unexpected one bail out
  314. if ((m_nLastError != ERROR_SUCCESS) || (dwType != REG_MULTI_SZ))
  315. {
  316. dwSize = 0;
  317. return NULL;
  318. }
  319. if (dwSize == 0)
  320. {
  321. dwSize = 0;
  322. return NULL;
  323. }
  324. // Allocate the buffer required. Will be twice as big as required
  325. // in _UNICODE versions.
  326. // ===============================================================
  327. TCHAR *pData = new TCHAR[dwSize];
  328. if (pData == 0)
  329. return NULL;
  330. //get the values
  331. m_nLastError = RegQueryValueEx(hSubkey,
  332. pszValueName,
  333. 0,
  334. &dwType,
  335. LPBYTE(pData),
  336. &dwSize);
  337. //if an error bail out
  338. if (m_nLastError != 0)
  339. {
  340. delete [] pData;
  341. dwSize = 0;
  342. return NULL;
  343. }
  344. return pData;
  345. }
  346. //***************************************************************************
  347. //
  348. /// Use operator delete on returned value.
  349. //
  350. //***************************************************************************
  351. // ok
  352. int Registry::GetStr(TCHAR *pszValueName, TCHAR **pValue)
  353. {
  354. *pValue = 0;
  355. DWORD dwSize = 0;
  356. DWORD dwType = 0;
  357. if(hSubkey == NULL)
  358. return failed;
  359. m_nLastError = RegQueryValueEx(hSubkey, pszValueName, 0, &dwType,
  360. 0, &dwSize);
  361. if (m_nLastError != 0)
  362. return failed;
  363. if (dwType != REG_SZ && dwType != REG_EXPAND_SZ)
  364. return failed;
  365. //
  366. // length will not include the null terminated character when you don't
  367. // pass the buffer and the reg value was not already null terminated,
  368. // so make up for it. If you give RegQueryValueEx enough room in the buff
  369. // it will add the null terminator for you.
  370. //
  371. dwSize += sizeof(TCHAR);
  372. TCHAR *p = new TCHAR[dwSize]; // May be twice as big as required when _UNICODE
  373. // is defined, but harmless nonetheless.
  374. if (p == 0)
  375. return failed;
  376. m_nLastError = RegQueryValueEx(hSubkey, pszValueName, 0, &dwType,
  377. LPBYTE(p), &dwSize);
  378. if (m_nLastError != 0)
  379. {
  380. delete [] p;
  381. return failed;
  382. }
  383. if(dwType == REG_EXPAND_SZ)
  384. {
  385. TCHAR tTemp;
  386. // Get the initial length
  387. DWORD nSize = ExpandEnvironmentStrings((TCHAR *)p,&tTemp,1) + 1;
  388. TCHAR * pTemp = new TCHAR[nSize+1];
  389. if (pTemp == 0)
  390. {
  391. delete [] p;
  392. return failed;
  393. }
  394. ExpandEnvironmentStrings((TCHAR *)p,pTemp,nSize+1);
  395. delete [] p;
  396. *pValue = pTemp;
  397. }
  398. else
  399. *pValue = p;
  400. return no_error;
  401. }