Leaked source code of windows server 2003
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.

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