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.

418 lines
10 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. regentry.cpp
  5. Abstract:
  6. Author:
  7. Vlad Sadovsky (vlads) 26-Jan-1997
  8. Revision History:
  9. 26-Jan-1997 VladS created
  10. --*/
  11. #include "cplusinc.h"
  12. #include "sticomm.h"
  13. RegEntry::RegEntry()
  14. {
  15. m_hkey = NULL;
  16. bhkeyValid = FALSE;
  17. }
  18. RegEntry::RegEntry(const TCHAR *pszSubKey, HKEY hkey)
  19. {
  20. m_hkey = NULL;
  21. bhkeyValid = FALSE;
  22. Open(pszSubKey, hkey);
  23. }
  24. RegEntry::~RegEntry()
  25. {
  26. Close();
  27. }
  28. BOOL RegEntry::Open(const TCHAR *pszSubKey, HKEY hkey)
  29. {
  30. Close();
  31. m_error = RegCreateKey(hkey, pszSubKey, &m_hkey);
  32. if (m_error) {
  33. bhkeyValid = FALSE;
  34. }
  35. else {
  36. bhkeyValid = TRUE;
  37. }
  38. return bhkeyValid;
  39. }
  40. BOOL RegEntry::Close()
  41. {
  42. if (bhkeyValid) {
  43. RegCloseKey(m_hkey);
  44. }
  45. m_hkey = NULL;
  46. bhkeyValid = FALSE;
  47. return TRUE;
  48. }
  49. long RegEntry::SetValue(const TCHAR *pszValue, const TCHAR *string)
  50. {
  51. if (bhkeyValid) {
  52. m_error = RegSetValueEx(m_hkey, pszValue, 0, REG_SZ,
  53. (BYTE *)string, sizeof(TCHAR) * (lstrlen(string) + 1));
  54. }
  55. return m_error;
  56. }
  57. long RegEntry::SetValue(const TCHAR *pszValue, const TCHAR *string, DWORD dwType)
  58. {
  59. DWORD cbData;
  60. cbData = sizeof(TCHAR) * (lstrlen(string) + 1);
  61. if (REG_MULTI_SZ == dwType)
  62. {
  63. // account for second null
  64. cbData+= sizeof(TCHAR);
  65. }
  66. if (bhkeyValid) {
  67. m_error = RegSetValueEx(m_hkey, pszValue, 0, dwType,
  68. (BYTE *)string, cbData);
  69. }
  70. return m_error;
  71. }
  72. long RegEntry::SetValue(const TCHAR *pszValue, unsigned long dwNumber)
  73. {
  74. if (bhkeyValid) {
  75. m_error = RegSetValueEx(m_hkey, pszValue, 0, REG_BINARY,
  76. (BYTE *)&dwNumber, sizeof(dwNumber));
  77. }
  78. return m_error;
  79. }
  80. long RegEntry::SetValue(const TCHAR *pszValue, BYTE * pValue,unsigned long dwNumber)
  81. {
  82. if (bhkeyValid) {
  83. m_error = RegSetValueEx(m_hkey, pszValue, 0, REG_BINARY,
  84. pValue, dwNumber);
  85. }
  86. return m_error;
  87. }
  88. long RegEntry::DeleteValue(const TCHAR *pszValue)
  89. {
  90. if (bhkeyValid) {
  91. m_error = RegDeleteValue(m_hkey, (LPTSTR) pszValue);
  92. }
  93. return m_error;
  94. }
  95. TCHAR *RegEntry::GetString(const TCHAR *pszValue, TCHAR *string, unsigned long length)
  96. {
  97. DWORD dwType = REG_SZ;
  98. if (bhkeyValid) {
  99. DWORD le;
  100. m_error = RegQueryValueEx(m_hkey, (LPTSTR) pszValue, 0, &dwType, (LPBYTE)string,
  101. &length);
  102. le = ::GetLastError();
  103. }
  104. if (!m_error) {
  105. //
  106. // Expand string if indicated
  107. //
  108. if (dwType == REG_EXPAND_SZ) {
  109. DWORD dwReqSize = 0;
  110. LPTSTR pszExpanded = new TCHAR[length];
  111. if (pszExpanded) {
  112. *pszExpanded = TEXT('\0');
  113. dwReqSize = ExpandEnvironmentStrings(string,pszExpanded,length);
  114. if (dwReqSize && dwReqSize <= length) {
  115. lstrcpy(string,pszExpanded);
  116. }
  117. delete[] pszExpanded;
  118. }
  119. }
  120. }
  121. else {
  122. *string = '\0';
  123. }
  124. return string;
  125. }
  126. long RegEntry::GetNumber(const TCHAR *pszValue, long dwDefault)
  127. {
  128. DWORD dwType = REG_BINARY;
  129. long dwNumber = 0L;
  130. DWORD dwSize = sizeof(dwNumber);
  131. if (bhkeyValid) {
  132. m_error = RegQueryValueEx(m_hkey, (LPTSTR) pszValue, 0, &dwType, (LPBYTE)&dwNumber,
  133. &dwSize);
  134. }
  135. if (m_error)
  136. dwNumber = dwDefault;
  137. return dwNumber;
  138. }
  139. VOID RegEntry::GetValue(const TCHAR *pszValueName, BUFFER *pValue)
  140. {
  141. DWORD dwType = REG_SZ;
  142. DWORD length;
  143. m_error = NOERROR;
  144. if (bhkeyValid) {
  145. m_error = RegQueryValueEx( m_hkey,
  146. (LPTSTR) pszValueName,
  147. 0,
  148. &dwType,
  149. NULL,
  150. &length );
  151. if (m_error == ERROR_SUCCESS) {
  152. pValue->Resize(length);
  153. if (length > (UINT)pValue->QuerySize()) {
  154. m_error = ERROR_NOT_ENOUGH_MEMORY;
  155. }
  156. }
  157. if (NOERROR == m_error ) {
  158. m_error = RegQueryValueEx( m_hkey,
  159. (LPTSTR) pszValueName,
  160. 0,
  161. &dwType,
  162. (LPBYTE) pValue->QueryPtr(),
  163. &length );
  164. }
  165. }
  166. if (m_error != ERROR_SUCCESS) {
  167. pValue->Resize(0);
  168. }
  169. }
  170. VOID RegEntry::MoveToSubKey(const TCHAR *pszSubKeyName)
  171. {
  172. HKEY _hNewKey;
  173. if (bhkeyValid) {
  174. m_error = RegOpenKey ( m_hkey,
  175. pszSubKeyName,
  176. &_hNewKey );
  177. if (m_error == ERROR_SUCCESS) {
  178. RegCloseKey(m_hkey);
  179. m_hkey = _hNewKey;
  180. }
  181. }
  182. }
  183. long RegEntry::FlushKey()
  184. {
  185. if (bhkeyValid) {
  186. m_error = RegFlushKey(m_hkey);
  187. }
  188. return m_error;
  189. }
  190. BOOL RegEntry::GetSubKeyInfo(DWORD *pNumberOfSubKeys, DWORD *pMaxSubKeyLength)
  191. {
  192. BOOL fResult = FALSE;
  193. if (bhkeyValid) {
  194. m_error = RegQueryInfoKey ( m_hkey, // Key
  195. NULL, // Buffer for class string
  196. NULL, // Size of class string buffer
  197. NULL, // Reserved
  198. pNumberOfSubKeys, // Number of subkeys
  199. pMaxSubKeyLength, // Longest subkey name
  200. NULL, // Longest class string
  201. NULL, // Number of value entries
  202. NULL, // Longest value name
  203. NULL, // Longest value data
  204. NULL, // Security descriptor
  205. NULL ); // Last write time
  206. if (m_error == ERROR_SUCCESS) {
  207. fResult = TRUE;
  208. }
  209. }
  210. return fResult;
  211. }
  212. BOOL RegEntry::EnumSubKey(DWORD index, StiCString *pstrString)
  213. {
  214. BOOL fResult = FALSE;
  215. m_error = NOERROR;
  216. if (!bhkeyValid) {
  217. return fResult;
  218. }
  219. m_error = RegEnumKey( m_hkey,
  220. index,
  221. (LPTSTR)(LPCTSTR)*pstrString,
  222. pstrString->GetAllocLength() );
  223. if (m_error == ERROR_SUCCESS) {
  224. fResult = TRUE;
  225. }
  226. return fResult;
  227. }
  228. RegEnumValues::RegEnumValues(RegEntry *pReqRegEntry)
  229. : pRegEntry(pReqRegEntry),
  230. iEnum(0),
  231. pchName(NULL),
  232. pbValue(NULL)
  233. {
  234. m_error = pRegEntry->GetError();
  235. if (m_error == ERROR_SUCCESS) {
  236. m_error = RegQueryInfoKey ( pRegEntry->GetKey(), // Key
  237. NULL, // Buffer for class string
  238. NULL, // Size of class string buffer
  239. NULL, // Reserved
  240. NULL, // Number of subkeys
  241. NULL, // Longest subkey name
  242. NULL, // Longest class string
  243. &cEntries, // Number of value entries
  244. &cMaxValueName, // Longest value name
  245. &cMaxData, // Longest value data
  246. NULL, // Security descriptor
  247. NULL ); // Last write time
  248. }
  249. if (m_error == ERROR_SUCCESS) {
  250. if (cEntries != 0) {
  251. cMaxValueName = cMaxValueName + 1; // REG_SZ needs one more for null
  252. cMaxData = cMaxData + 1; // REG_SZ needs one more for null
  253. pchName = new TCHAR[cMaxValueName];
  254. if (!pchName) {
  255. m_error = ERROR_NOT_ENOUGH_MEMORY;
  256. }
  257. else {
  258. if (cMaxData) {
  259. pbValue = new BYTE[cMaxData];
  260. if (!pbValue) {
  261. m_error = ERROR_NOT_ENOUGH_MEMORY;
  262. }
  263. }
  264. }
  265. }
  266. }
  267. }
  268. RegEnumValues::~RegEnumValues()
  269. {
  270. delete[] pchName;
  271. delete[] pbValue;
  272. }
  273. long RegEnumValues::Next()
  274. {
  275. if (m_error != ERROR_SUCCESS) {
  276. return m_error;
  277. }
  278. if (cEntries == iEnum) {
  279. return ERROR_NO_MORE_ITEMS;
  280. }
  281. DWORD cchName = cMaxValueName;
  282. dwDataLength = cMaxData;
  283. m_error = RegEnumValue ( pRegEntry->GetKey(), // Key
  284. iEnum, // Index of value
  285. pchName, // Address of buffer for value name
  286. &cchName, // Address for size of buffer
  287. NULL, // Reserved
  288. &dwType, // Data type
  289. pbValue, // Address of buffer for value data
  290. &dwDataLength ); // Address for size of data
  291. iEnum++;
  292. return m_error;
  293. }
  294. //
  295. // Temporarily here
  296. //
  297. VOID
  298. TokenizeIntoStringArray(
  299. STRArray& array,
  300. LPCTSTR lpstrIn,
  301. TCHAR tcSplitter
  302. )
  303. {
  304. //
  305. array.RemoveAll();
  306. if (IS_EMPTY_STRING(lpstrIn)) {
  307. return;
  308. }
  309. while (*lpstrIn) {
  310. // First, strip off any leading blanks
  311. while (*lpstrIn && *lpstrIn == _TEXT(' '))
  312. lpstrIn++;
  313. for (LPCTSTR lpstrMoi = lpstrIn;
  314. *lpstrMoi && *lpstrMoi != tcSplitter;
  315. lpstrMoi++)
  316. ;
  317. // If we hit the end, just add the whole thing to the array
  318. if (!*lpstrMoi) {
  319. if (*lpstrIn)
  320. array.Add(lpstrIn);
  321. return;
  322. }
  323. //
  324. // Otherwise, just add the string up to the splitter
  325. //
  326. TCHAR szNew[MAX_PATH];
  327. SIZE_T uiLen = (SIZE_T)(lpstrMoi - lpstrIn) + 1;
  328. if (uiLen < (sizeof(szNew) / sizeof(szNew[0])) - 1) {
  329. lstrcpyn(szNew,lpstrIn,(UINT)uiLen);
  330. szNew[uiLen] = TCHAR('\0');
  331. array.Add((LPCTSTR) szNew);
  332. }
  333. lpstrIn = lpstrMoi + 1;
  334. }
  335. }