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.

484 lines
10 KiB

  1. #include "pch.h"
  2. #pragma hdrstop
  3. #include "global.h"
  4. #include "value.h"
  5. #include "util.h"
  6. #include "ncreg.h"
  7. #include "ncstring.h"
  8. static const int c_valueSzMax;
  9. CValue::CValue()
  10. : m_fInit(FALSE),
  11. m_eType(VALUETYPE_UNKNOWN),
  12. m_fNumeric(FALSE),
  13. m_fHex(FALSE),
  14. m_fPresent(FALSE),
  15. m_fInvalidChars(FALSE),
  16. m_fEmptyString(FALSE),
  17. m_psz(0)
  18. {
  19. }
  20. CValue::~CValue()
  21. {
  22. #ifdef DBG
  23. if (!m_fNumeric)
  24. {
  25. AssertSz(!m_psz, "m_psz not deallocated before ~CValue called.");
  26. }
  27. #endif
  28. }
  29. VOID CValue::Init(VALUETYPE type, DWORD value)
  30. {
  31. Assert(m_fInit == FALSE);
  32. m_fInit = TRUE;
  33. SetType(type);
  34. SetPresent(TRUE);
  35. SetInvalidChars(FALSE);
  36. SetEmptyString(FALSE);
  37. if ((GetType() == VALUETYPE_EDIT) ||
  38. (GetType() == VALUETYPE_ENUM) ||
  39. (GetType() == VALUETYPE_KONLY))
  40. {
  41. m_fNumeric = FALSE;
  42. m_psz = NULL;
  43. FromString(NULL);
  44. }
  45. else
  46. {
  47. m_fNumeric = TRUE;
  48. m_dw = value;
  49. }
  50. }
  51. VOID CValue::InitNotPresent(VALUETYPE type)
  52. {
  53. Init(type, 0);
  54. SetPresent(FALSE);
  55. }
  56. VOID CValue::Destroy()
  57. {
  58. AssertSz(m_fInit, "CValue class not Init'ed");
  59. if (!IsNumeric())
  60. {
  61. delete m_psz;
  62. m_psz = NULL;
  63. }
  64. m_dw = NULL; // since all other values are a union, this'll clear
  65. // out everything.
  66. m_fInit = FALSE;
  67. }
  68. // copies into current object
  69. VOID CValue::Copy(CValue *pvSrc)
  70. {
  71. AssertSz(m_fInit, "CValue class not Init'ed");
  72. Assert(pvSrc != NULL);
  73. AssertSz(m_eType == pvSrc->m_eType,
  74. "Can't copy from different value types.");
  75. // Clear out the destination value
  76. Destroy();
  77. AssertSz( ! m_psz, "Memory should have been deallocated by Destroy()");
  78. // Copy contents of source value
  79. *this = *pvSrc;
  80. // Reallocate string
  81. if ( ! pvSrc->IsNumeric())
  82. {
  83. if (pvSrc->m_psz)
  84. {
  85. // allocate and copy string.
  86. m_psz = new WCHAR[lstrlenW(pvSrc->m_psz) + 1];
  87. if (m_psz == NULL)
  88. {
  89. Assert(0);
  90. return;
  91. }
  92. lstrcpyW(m_psz,pvSrc->m_psz);
  93. }
  94. }
  95. }
  96. VOID CValue::SetNumericValue(DWORD dw)
  97. {
  98. Assert(m_fInit);
  99. Assert(m_fNumeric);
  100. switch(m_eType)
  101. {
  102. case VALUETYPE_DWORD:
  103. SetDword(dw);
  104. break;
  105. case VALUETYPE_LONG:
  106. SetLong(dw);
  107. break;
  108. case VALUETYPE_WORD:
  109. Assert(dw <= USHRT_MAX);
  110. SetWord(static_cast<WORD>(dw));
  111. break;
  112. case VALUETYPE_INT:
  113. Assert(dw <= SHRT_MAX);
  114. Assert(dw >= SHRT_MIN);
  115. SetShort(static_cast<short>(dw));
  116. break;
  117. default:
  118. AssertSz(FALSE, "Invalid numeric type for this value");
  119. break;
  120. }
  121. }
  122. BOOL CValue::FromString(const WCHAR * const pszValue)
  123. {
  124. UINT uBase;
  125. PWSTR pszEnd;
  126. PWSTR psz;
  127. WCHAR szTemp[VALUE_SZMAX];
  128. AssertSz(m_fInit, "CValue class not Init'ed");
  129. // Fixup string
  130. if (!pszValue)
  131. {
  132. szTemp[0] = L'\0';
  133. }
  134. else
  135. {
  136. lstrcpynW(szTemp,pszValue, celems(szTemp));
  137. StripSpaces(szTemp);
  138. }
  139. psz = szTemp;
  140. // Get numeric base
  141. uBase = IsHex() ? 16 : 10;
  142. // Initialize to valid
  143. SetInvalidChars(FALSE);
  144. SetEmptyString(FALSE);
  145. if ( ! *psz)
  146. {
  147. SetEmptyString(TRUE);
  148. }
  149. // Convert
  150. switch (GetType())
  151. {
  152. default:
  153. case VALUETYPE_INT:
  154. SetShort((short)wcstol(psz,&pszEnd,uBase));
  155. if (*pszEnd != L'\0')
  156. {
  157. SetInvalidChars(TRUE);
  158. }
  159. break;
  160. case VALUETYPE_LONG:
  161. SetLong(wcstol(psz,&pszEnd,uBase));
  162. if (*pszEnd != L'\0')
  163. {
  164. SetInvalidChars(TRUE);
  165. }
  166. break;
  167. case VALUETYPE_WORD:
  168. SetWord((WORD)wcstoul(psz,&pszEnd,uBase));
  169. if (*pszEnd != L'\0')
  170. {
  171. SetInvalidChars(TRUE);
  172. }
  173. break;
  174. case VALUETYPE_DWORD:
  175. SetDword(wcstoul(psz,&pszEnd,uBase));
  176. if (*pszEnd != L'\0')
  177. {
  178. SetInvalidChars(TRUE);
  179. }
  180. break;
  181. case VALUETYPE_ENUM:
  182. case VALUETYPE_EDIT:
  183. if (m_psz)
  184. {
  185. delete m_psz;
  186. m_psz = NULL;
  187. }
  188. m_psz = new WCHAR[lstrlenW(psz) + 1];
  189. if (m_psz == NULL)
  190. {
  191. return(FALSE);
  192. }
  193. lstrcpyW(m_psz,psz);
  194. break;
  195. case VALUETYPE_KONLY:
  196. break;
  197. }
  198. return TRUE;
  199. }
  200. BOOL CValue::ToString(WCHAR * sz, UINT cch)
  201. {
  202. UINT len;
  203. AssertSz(m_fInit, "CValue class not Init'ed");
  204. Assert(sz != NULL);
  205. switch (GetType())
  206. {
  207. case VALUETYPE_INT:
  208. len = (UINT)wsprintfW(sz,L"%d",GetShort());
  209. Assert(len+1 <= cch); // verify that we allocated enough space
  210. break;
  211. case VALUETYPE_LONG:
  212. len = (UINT)wsprintfW(sz,L"%ld",GetLong());
  213. Assert(len+1 <= cch);
  214. break;
  215. case VALUETYPE_WORD:
  216. if (IsHex()) {
  217. len = (UINT)wsprintfW(sz,L"%-2X",GetWord());
  218. } else {
  219. len = (UINT)wsprintfW(sz,L"%u",GetWord());
  220. }
  221. Assert(len+1 <= cch);
  222. break;
  223. case VALUETYPE_DWORD:
  224. if (IsHex()) {
  225. len = (UINT)wsprintfW(sz,L"%-2lX",GetDword());
  226. } else {
  227. len = (UINT)wsprintfW(sz,L"%lu",GetDword());
  228. }
  229. Assert(len+1 <= cch);
  230. break;
  231. case VALUETYPE_ENUM:
  232. case VALUETYPE_EDIT:
  233. lstrcpynW (sz, m_psz, cch);
  234. break;
  235. case VALUETYPE_KONLY:
  236. Assert(cch >= 2);
  237. lstrcpynW (sz, L"1", cch); // If present, store a "1" in the registry.
  238. break;
  239. }
  240. return TRUE;
  241. }
  242. // Compares the current object to another object
  243. // Return values: 0 = both objs are the same
  244. // <0 = cur obj is less then the other obj
  245. // >0 = cur obj is greater than the other obj
  246. int CValue::Compare(CValue *pv2)
  247. {
  248. AssertSz(m_fInit, "CValue class not Init'ed");
  249. Assert(pv2 != NULL);
  250. Assert(GetType() == pv2->GetType());
  251. // Present/not present (present is greater than not present)
  252. if (!IsPresent() && !pv2->IsPresent())
  253. {
  254. return 0;
  255. }
  256. if (!IsPresent() && pv2->IsPresent())
  257. {
  258. return -1;
  259. }
  260. if (IsPresent() && !pv2->IsPresent())
  261. {
  262. return 1;
  263. }
  264. // Compare
  265. switch (GetType())
  266. {
  267. case VALUETYPE_INT:
  268. if (GetShort() == pv2->GetShort())
  269. {
  270. return 0;
  271. }
  272. return (GetShort() < pv2->GetShort()) ? -1 : 1;
  273. case VALUETYPE_LONG:
  274. if (GetLong() == pv2->GetLong())
  275. {
  276. return 0;
  277. }
  278. return (GetLong() < pv2->GetLong())? -1 : 1;
  279. case VALUETYPE_WORD:
  280. if (GetWord() == pv2->GetWord())
  281. {
  282. return 0;
  283. }
  284. return (GetWord() < pv2->GetWord())? -1 : 1;
  285. case VALUETYPE_DWORD:
  286. if (GetDword() == pv2->GetDword())
  287. {
  288. return 0;
  289. }
  290. return (GetDword() < pv2->GetDword())? -1 : 1;
  291. case VALUETYPE_ENUM:
  292. case VALUETYPE_EDIT:
  293. if ((GetPsz() != NULL) && (pv2->GetPsz() != NULL))
  294. {
  295. return lstrcmpW(GetPsz(),pv2->GetPsz());
  296. }
  297. else
  298. {
  299. return -2; // REVIEW: what does -2 mean?
  300. }
  301. case VALUETYPE_KONLY:
  302. return 1;
  303. default:
  304. Assert(FALSE);
  305. return 1; // to stop compiler warning.
  306. }
  307. }
  308. // if false, then value doesn't change.
  309. BOOL CValue::FLoadFromRegistry(HKEY hk, const WCHAR * pszValueName, HKEY hkParam /* = INVALID_HANDLE_VALUE */)
  310. {
  311. DWORD cbBuf;
  312. WCHAR szBuf[VALUE_SZMAX];
  313. DWORD dwType;
  314. HRESULT hr = S_OK;
  315. HKEY hkTemp;
  316. AssertSz(m_fInit, "CValue class not Init'ed");
  317. Assert(hk);
  318. Assert(pszValueName);
  319. // determine base
  320. SetHex(FALSE);
  321. if (hkParam != (HKEY)INVALID_HANDLE_VALUE)
  322. hkTemp = hkParam;
  323. else
  324. hkTemp = hk;
  325. if (Reg_QueryInt(hkTemp, c_szRegParamBase,10) == 16)
  326. {
  327. SetHex(TRUE);
  328. }
  329. cbBuf = sizeof(szBuf);
  330. hr = HrRegQueryValueEx(hk,pszValueName,&dwType,(BYTE*)szBuf,&cbBuf);
  331. if (SUCCEEDED(hr))
  332. {
  333. AssertSz(REG_SZ == dwType,
  334. "Expecting REG_SZ, but got something else.");
  335. }
  336. if (FAILED(hr) || !szBuf[0])
  337. {
  338. return FALSE;
  339. }
  340. m_fPresent = TRUE;
  341. return FromString(szBuf);
  342. }
  343. BOOL CValue::FSaveToRegistry(HKEY hk, const WCHAR * pszValueName)
  344. {
  345. DWORD cbBuf;
  346. WCHAR szBuf[VALUE_SZMAX];
  347. AssertSz(m_fInit, "CValue class not Init'ed");
  348. Assert(hk);
  349. Assert(pszValueName);
  350. if (!IsPresent())
  351. {
  352. RegDeleteValue(hk,pszValueName);
  353. return TRUE;
  354. }
  355. ToString(szBuf,celems(szBuf));
  356. cbBuf = CbOfSzAndTerm(szBuf);
  357. return (RegSetValueEx(
  358. hk,
  359. pszValueName,
  360. NULL,
  361. REG_SZ,
  362. (LPBYTE)
  363. szBuf,
  364. cbBuf)
  365. == ERROR_SUCCESS);
  366. }
  367. int CValue::GetNumericValueAsSignedInt()
  368. {
  369. Assert(m_fInit);
  370. Assert(m_fPresent);
  371. Assert(m_fNumeric);
  372. int nret = 0;
  373. switch (m_eType)
  374. {
  375. case VALUETYPE_DWORD:
  376. nret = GetDword();
  377. break;
  378. case VALUETYPE_LONG:
  379. nret = GetLong();
  380. break;
  381. case VALUETYPE_WORD:
  382. nret = GetWord();
  383. break;
  384. case VALUETYPE_INT:
  385. nret = GetShort();
  386. break;
  387. default:
  388. Assert("Hit default case in GetNumericValueAsSignedInt");
  389. break;
  390. }
  391. return nret;
  392. }
  393. DWORD CValue::GetNumericValueAsDword()
  394. {
  395. AssertH(m_fInit);
  396. AssertH(m_fPresent);
  397. AssertH(m_fNumeric);
  398. DWORD dwret = 0;
  399. switch (m_eType)
  400. {
  401. case VALUETYPE_DWORD:
  402. dwret = GetDword();
  403. break;
  404. case VALUETYPE_LONG:
  405. dwret = GetLong();
  406. break;
  407. case VALUETYPE_WORD:
  408. dwret = GetWord();
  409. break;
  410. case VALUETYPE_INT:
  411. dwret = GetShort();
  412. break;
  413. default:
  414. Assert("Hit default case in GetNumericValueAsSignedInt");
  415. break;
  416. }
  417. return dwret;
  418. }