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.

402 lines
9.6 KiB

  1. #include "pch.h"
  2. #pragma hdrstop
  3. #include "global.h"
  4. #include "ncreg.h"
  5. #include "ncstring.h"
  6. #include "ncxbase.h"
  7. #include "param.h"
  8. #include "resource.h"
  9. #include "util.h"
  10. CParam::CParam ()
  11. : m_fInit(FALSE),
  12. m_eType(VALUETYPE_UNKNOWN),
  13. m_hkRoot(NULL),
  14. m_pszKeyName(NULL),
  15. m_pszDesc(NULL),
  16. m_pszHelpFile(NULL),
  17. m_dwHelpContext(0),
  18. m_uLimitText(0),
  19. m_hkEnum(NULL),
  20. m_fOptional(FALSE),
  21. m_fModified(FALSE),
  22. m_fReadOnly(FALSE),
  23. m_fOEMText(FALSE),
  24. m_fUppercase(FALSE)
  25. {
  26. }
  27. BOOL CParam::FInit(HKEY hkRoot, HKEY hkNdiParam, PWSTR pszSubKey)
  28. {
  29. HRESULT hr = S_OK;
  30. DWORD cbBuf;
  31. BYTE szBuf[VALUE_SZMAX];
  32. UINT uTemp;
  33. DWORD dwType;
  34. HKEY hkParamInfo;
  35. // store hkRoot, pszSubKey for future reference
  36. m_hkRoot = hkRoot;
  37. m_pszKeyName = new WCHAR[lstrlenW (pszSubKey) + 1];
  38. if (m_pszKeyName == NULL)
  39. {
  40. return(FALSE);
  41. }
  42. lstrcpyW (m_pszKeyName, pszSubKey);
  43. hr = HrRegOpenKeyEx(hkNdiParam, pszSubKey, KEY_READ,
  44. &hkParamInfo);
  45. if (FAILED(hr))
  46. {
  47. hkParamInfo = NULL;
  48. goto error;
  49. }
  50. // Get the parameter type, use EDIT if none specified
  51. // range values (etc.) for the type. If 'type' is empty
  52. // or invalid, the "int" type is returned.
  53. cbBuf = sizeof(szBuf);
  54. hr = HrRegQueryValueEx(hkParamInfo,c_szRegParamType,&dwType,szBuf,&cbBuf);
  55. if (SUCCEEDED(hr))
  56. {
  57. AssertSz(REG_SZ == dwType,
  58. "Expecting REG_SZ type but got something else.");
  59. }
  60. else
  61. {
  62. ((PWCHAR)szBuf)[0] = L'\0';
  63. }
  64. InitParamType((PTSTR)szBuf);
  65. // Get the description text
  66. cbBuf = sizeof(szBuf);
  67. hr = HrRegQueryValueEx(hkParamInfo,c_szRegParamDesc,&dwType,szBuf,&cbBuf);
  68. if (SUCCEEDED(hr))
  69. {
  70. AssertSz(REG_SZ == dwType,
  71. "Expecting REG_SZ type but got something else.");
  72. }
  73. else
  74. {
  75. // No description string
  76. lstrcpyW((WCHAR *)szBuf, SzLoadIds (IDS_NO_DESCRIPTION));
  77. }
  78. // allocate and store description
  79. m_pszDesc = new WCHAR[lstrlenW((WCHAR *)szBuf) + 1];
  80. if (m_pszDesc == NULL)
  81. {
  82. return(FALSE);
  83. }
  84. lstrcpyW(m_pszDesc, (WCHAR *)szBuf);
  85. // Optional parameter
  86. m_fOptional = FALSE;
  87. uTemp = Reg_QueryInt(hkParamInfo,c_szRegParamOptional,0);
  88. if (uTemp != 0)
  89. {
  90. m_fOptional = TRUE;
  91. }
  92. // Help file info
  93. m_pszHelpFile = NULL;
  94. m_dwHelpContext = 0;
  95. cbBuf = sizeof(szBuf);
  96. hr = HrRegQueryValueEx(hkParamInfo,c_szRegParamHelpFile,&dwType,
  97. szBuf,&cbBuf);
  98. if (SUCCEEDED(hr))
  99. {
  100. AssertSz(REG_SZ == dwType,
  101. "Expecting REG_SZ type but got something else.");
  102. m_pszHelpFile = new WCHAR[lstrlenW((WCHAR *)szBuf)+1];
  103. if (m_pszHelpFile == NULL)
  104. {
  105. return(FALSE);
  106. }
  107. lstrcpyW(m_pszHelpFile, (WCHAR *)szBuf);
  108. m_dwHelpContext = Reg_QueryInt(hkParamInfo,c_szRegParamHelpContext,0);
  109. }
  110. // Numeric Type Info
  111. if (m_vValue.IsNumeric())
  112. {
  113. // if no step value in registry, default to 1 (default already
  114. // set in FInitParamType() )
  115. m_vStep.FLoadFromRegistry(hkParamInfo,c_szRegParamStep);
  116. if (m_vStep.GetNumericValueAsDword() == 0)
  117. {
  118. m_vStep.SetNumericValue(1);
  119. }
  120. // get m_vMix and m_vMax from registry (no effect if doesn't exist,
  121. // defaults were set in FInitParamType() )
  122. (VOID) m_vMin.FLoadFromRegistry(hkParamInfo,c_szRegParamMin);
  123. (VOID) m_vMax.FLoadFromRegistry(hkParamInfo,c_szRegParamMax);
  124. }
  125. // Edit type info
  126. else if (m_eType == VALUETYPE_EDIT)
  127. {
  128. // Limit text
  129. m_uLimitText = VALUE_SZMAX-1;
  130. uTemp = Reg_QueryInt(hkParamInfo,c_szRegParamLimitText,m_uLimitText);
  131. if ((uTemp > 0) && (uTemp < VALUE_SZMAX))
  132. {
  133. m_uLimitText = uTemp;
  134. }
  135. // Read-only
  136. m_fReadOnly = FALSE;
  137. uTemp = Reg_QueryInt(hkParamInfo,c_szRegParamReadOnly,0);
  138. if (uTemp != 0)
  139. {
  140. m_fReadOnly = TRUE;
  141. }
  142. // OEMText
  143. m_fOEMText = FALSE;
  144. uTemp = Reg_QueryInt(hkParamInfo,c_szRegParamOEMText,0);
  145. if (uTemp != 0)
  146. {
  147. m_fOEMText = TRUE;
  148. }
  149. // Uppercase
  150. m_fUppercase = FALSE;
  151. uTemp = Reg_QueryInt(hkParamInfo,c_szRegParamUppercase,0);
  152. if (uTemp != 0)
  153. {
  154. m_fUppercase = TRUE;
  155. }
  156. }
  157. // Enum type info
  158. else if (m_eType == VALUETYPE_ENUM)
  159. {
  160. hr = HrRegOpenKeyEx(hkParamInfo,c_szRegParamTypeEnum,KEY_READ,
  161. &m_hkEnum);
  162. if (FAILED(hr))
  163. {
  164. m_hkEnum = NULL;
  165. }
  166. }
  167. // Current Value
  168. m_fModified = FALSE;
  169. if (!m_vValue.FLoadFromRegistry(m_hkRoot,m_pszKeyName,hkParamInfo))
  170. {
  171. // Use default value (current value not in registry)
  172. if (!m_vValue.FLoadFromRegistry(hkParamInfo,c_szRegParamDefault))
  173. {
  174. // If no default in registry, assume a decent value
  175. if (m_vValue.IsNumeric())
  176. {
  177. m_vValue.Copy(&m_vMin);
  178. }
  179. else
  180. {
  181. m_vValue.FromString(L"");
  182. }
  183. }
  184. // Keep not-present state of optional parameters.
  185. // Mark required parameters modified since we read the default.
  186. if (m_fOptional)
  187. {
  188. m_vValue.SetPresent(FALSE);
  189. }
  190. else
  191. {
  192. m_fModified = TRUE;
  193. }
  194. }
  195. // Save initial value for comparison in Param_Validate
  196. // The initial value is always valid - in case the user hand-mucks
  197. // it to something outside the specified range.
  198. m_vInitial.Copy(&m_vValue);
  199. m_fInit = TRUE;
  200. RegSafeCloseKey(hkParamInfo);
  201. return TRUE;
  202. error:
  203. // Cleanup done by destructor.
  204. return FALSE;
  205. }
  206. VOID CParam::InitParamType(PTSTR pszType)
  207. {
  208. typedef struct tagPTABLE
  209. {
  210. const WCHAR * pszToken;
  211. VALUETYPE type;
  212. DWORD dwMin;
  213. DWORD dwMax;
  214. } PTABLE;
  215. static PTABLE ptable[] =
  216. {
  217. // 1st entry is default if pszType is invalid or unknown
  218. {c_szRegParamTypeEdit, VALUETYPE_EDIT, NULL, NULL},
  219. {c_szRegParamTypeInt, VALUETYPE_INT, SHRT_MIN, SHRT_MAX},
  220. {c_szRegParamTypeLong, VALUETYPE_LONG, LONG_MIN,(DWORD)LONG_MAX},
  221. {c_szRegParamTypeWord, VALUETYPE_WORD, 0, USHRT_MAX},
  222. {c_szRegParamTypeDword, VALUETYPE_DWORD, 0, ULONG_MAX},
  223. {c_szRegParamTypeEnum, VALUETYPE_ENUM, NULL, NULL},
  224. {c_szRegParamTypeKeyonly, VALUETYPE_KONLY, NULL, NULL}
  225. };
  226. UINT i;
  227. PTABLE* pt;
  228. Assert(pszType != NULL);
  229. // Lookup token in param table
  230. for (i=0; i < celems(ptable); i++)
  231. {
  232. pt = &ptable[i];
  233. if (lstrcmpiW(pt->pszToken,pszType) == 0)
  234. {
  235. break;
  236. }
  237. }
  238. if (i >= celems(ptable))
  239. {
  240. pt = &ptable[0];
  241. }
  242. // Table default values
  243. m_eType = pt->type;
  244. m_vValue.Init(pt->type,0);
  245. m_vInitial.Init(pt->type,0);
  246. if (m_vValue.IsNumeric())
  247. {
  248. m_vMin.Init(pt->type,pt->dwMin);
  249. m_vMax.Init(pt->type,pt->dwMax);
  250. m_vStep.Init(pt->type,1);
  251. }
  252. else
  253. {
  254. m_vMin.Init(pt->type,NULL);
  255. m_vMax.Init(pt->type,NULL);
  256. m_vStep.Init(pt->type,0);
  257. }
  258. }
  259. // Notes: Don't close m_hkRoot since other's may have copies of it.
  260. // ~CAdvanced will close it.
  261. //
  262. CParam::~CParam()
  263. {
  264. // Close the enum subkey
  265. RegSafeCloseKey(m_hkEnum);
  266. // free strings
  267. delete m_pszKeyName;
  268. delete m_pszDesc;
  269. delete m_pszHelpFile;
  270. // free values
  271. m_vValue.Destroy();
  272. m_vInitial.Destroy();
  273. m_vMin.Destroy();
  274. m_vMax.Destroy();
  275. m_vStep.Destroy();
  276. }
  277. // Applies from In-Memory storage to registry
  278. BOOL CParam::Apply() {
  279. AssertSz(m_fInit,"CParam not FInit()'ed.");
  280. if (!FIsModified())
  281. {
  282. return TRUE; // not modified, don't save.
  283. }
  284. Assert(0 == m_vValue.Compare(&m_vValue));
  285. m_fModified = FALSE;
  286. m_vInitial.Copy(&m_vValue);
  287. return m_vValue.FSaveToRegistry(m_hkRoot,m_pszKeyName);
  288. }
  289. UINT CParam::Validate()
  290. {
  291. AssertSz(m_fInit, "CParam not FInit()'ed.");
  292. // Equal to the initial value is ok
  293. if (m_vValue.Compare(&m_vInitial) == 0)
  294. {
  295. return VALUE_OK;
  296. }
  297. // Unpresent-optional value is ok
  298. if (FIsOptional() && !m_vValue.IsPresent())
  299. {
  300. return VALUE_OK;
  301. }
  302. // Invalid characters
  303. if (m_vValue.IsInvalidChars())
  304. {
  305. return VALUE_BAD_CHARS;
  306. }
  307. // Empty required field
  308. if (m_vValue.IsEmptyString() && m_vValue.IsPresent() && (m_vValue.GetType() != VALUETYPE_KONLY))
  309. {
  310. return VALUE_EMPTY;
  311. }
  312. // Numeric range
  313. if (m_vValue.IsNumeric())
  314. {
  315. // If value is < min, out of range
  316. if (m_vValue.Compare(&m_vMin) < 0)
  317. {
  318. return VALUE_OUTOFRANGE;
  319. }
  320. // If value is > max, out of range
  321. if (m_vValue.Compare(&m_vMax) > 0)
  322. {
  323. return VALUE_OUTOFRANGE;
  324. }
  325. // Step-range
  326. Assert(m_vStep.GetNumericValueAsDword() != 0);
  327. if (((m_vValue.GetNumericValueAsDword() -
  328. m_vMin.GetNumericValueAsDword())
  329. % m_vStep.GetNumericValueAsDword()) != 0)
  330. {
  331. return VALUE_OUTOFRANGE;
  332. }
  333. }
  334. return VALUE_OK;
  335. }
  336. VOID CParam::GetDescription(WCHAR * sz, UINT cch)
  337. {
  338. AssertSz(m_fInit, "CParam not FInit()'ed.");
  339. lstrcpynW(sz, m_pszDesc, cch);
  340. }
  341. VOID CParam::GetHelpFile(WCHAR * sz, UINT cch)
  342. {
  343. AssertSz(m_fInit, "CParam not FInit()'ed.");
  344. lstrcpynW(sz, m_pszHelpFile, cch);
  345. }