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.

463 lines
9.5 KiB

  1. /*
  2. * inifile.c - Initialization file processing module.
  3. */
  4. /* Headers
  5. **********/
  6. #include "project.h"
  7. #pragma hdrstop
  8. #ifdef DEBUG
  9. /* Constants
  10. ************/
  11. /* maximum length of .ini switch RHS */
  12. #define MAX_INI_SWITCH_RHS_LEN MAX_PATH_LEN
  13. /* Module Variables
  14. *******************/
  15. #pragma data_seg(DATA_SEG_READ_ONLY)
  16. /* Boolean TRUE strings used by IsIniYes() (comparison is case-insensitive) */
  17. PRIVATE_DATA const PCSTR s_rgcszTrue[] =
  18. {
  19. "1",
  20. "On",
  21. "True",
  22. "Y",
  23. "Yes"
  24. };
  25. /* Boolean FALSE strings used by IsIniYes() (comparison is case-insensitive) */
  26. PRIVATE_DATA const PCSTR s_rgcszFalse[] =
  27. {
  28. "0",
  29. "Off",
  30. "False",
  31. "N",
  32. "No"
  33. };
  34. #pragma data_seg()
  35. #endif
  36. /***************************** Private Functions *****************************/
  37. /* Module Prototypes
  38. ********************/
  39. #ifdef DEBUG
  40. PRIVATE_CODE BOOL SetBOOLIniSwitch(PCBOOLINISWITCH);
  41. PRIVATE_CODE BOOL SetDecimalIntIniSwitch(PCDECINTINISWITCH);
  42. PRIVATE_CODE BOOL SetIniSwitch(PCVOID);
  43. PRIVATE_CODE BOOL IsYesString(PCSTR);
  44. PRIVATE_CODE BOOL IsNoString(PCSTR);
  45. PRIVATE_CODE BOOL IsStringInList(PCSTR, const PCSTR *, UINT);
  46. PRIVATE_CODE BOOL IsValidPCBOOLINISWITCH(PCBOOLINISWITCH);
  47. PRIVATE_CODE BOOL IsValidPCDECINTINISWITCH(PCDECINTINISWITCH);
  48. PRIVATE_CODE BOOL IsValidPCUNSDECINTINISWITCH(PCUNSDECINTINISWITCH);
  49. #endif
  50. #ifdef DEBUG
  51. /*
  52. ** SetBOOLIniSwitch()
  53. **
  54. **
  55. **
  56. ** Arguments:
  57. **
  58. ** Returns:
  59. **
  60. ** Side Effects: none
  61. */
  62. PRIVATE_CODE BOOL SetBOOLIniSwitch(PCBOOLINISWITCH pcbis)
  63. {
  64. DWORD dwcbKeyLen;
  65. char rgchRHS[MAX_INI_SWITCH_RHS_LEN];
  66. ASSERT(IS_VALID_STRUCT_PTR(pcbis, CBOOLINISWITCH));
  67. /* Set boolean .ini switch. */
  68. dwcbKeyLen = GetPrivateProfileString(g_pcszIniSection, pcbis->pcszKeyName,
  69. "", rgchRHS, sizeof(rgchRHS),
  70. g_pcszIniFile);
  71. /* Is the .ini switch set? */
  72. if (rgchRHS[0])
  73. {
  74. /* Yes. Set or clear flag? */
  75. if (IsYesString(rgchRHS))
  76. {
  77. /* Set flag. */
  78. if (IS_FLAG_CLEAR(*(pcbis->pdwParentFlags), pcbis->dwFlag))
  79. {
  80. SET_FLAG(*(pcbis->pdwParentFlags), pcbis->dwFlag);
  81. WARNING_OUT(("SetBOOLIniSwitch(): %s set in %s![%s].",
  82. pcbis->pcszKeyName,
  83. g_pcszIniFile,
  84. g_pcszIniSection));
  85. }
  86. }
  87. else if (IsNoString(rgchRHS))
  88. {
  89. /* Clear flag. */
  90. if (IS_FLAG_SET(*(pcbis->pdwParentFlags), pcbis->dwFlag))
  91. {
  92. CLEAR_FLAG(*(pcbis->pdwParentFlags), pcbis->dwFlag);
  93. WARNING_OUT(("SetBOOLIniSwitch(): %s cleared in %s![%s].",
  94. pcbis->pcszKeyName,
  95. g_pcszIniFile,
  96. g_pcszIniSection));
  97. }
  98. }
  99. else
  100. /* Unknown flag. */
  101. WARNING_OUT(("SetBOOLIniSwitch(): Found unknown Boolean RHS %s for %s in %s![%s].",
  102. rgchRHS,
  103. pcbis->pcszKeyName,
  104. g_pcszIniFile,
  105. g_pcszIniSection));
  106. }
  107. return(TRUE);
  108. }
  109. /*
  110. ** SetDecimalIntIniSwitch()
  111. **
  112. **
  113. **
  114. ** Arguments:
  115. **
  116. ** Returns:
  117. **
  118. ** Side Effects: none
  119. */
  120. PRIVATE_CODE BOOL SetDecimalIntIniSwitch(PCDECINTINISWITCH pcdiis)
  121. {
  122. INT nNewValue;
  123. ASSERT(IS_VALID_STRUCT_PTR(pcdiis, CDECINTINISWITCH));
  124. /* Get decimal integer .ini switch. */
  125. nNewValue = GetPrivateProfileInt(g_pcszIniSection, pcdiis->pcszKeyName,
  126. *(pcdiis->pnValue), g_pcszIniFile);
  127. /* New value? */
  128. if (nNewValue != *(pcdiis->pnValue))
  129. {
  130. /* Yes. */
  131. *(pcdiis->pnValue) = nNewValue;
  132. WARNING_OUT(("SetDecimalIntIniSwitch(): %s set to %d in %s![%s].",
  133. pcdiis->pcszKeyName,
  134. *(pcdiis->pnValue),
  135. g_pcszIniFile,
  136. g_pcszIniSection));
  137. }
  138. return(TRUE);
  139. }
  140. /*
  141. ** SetUnsignedDecimalIntIniSwitch()
  142. **
  143. **
  144. **
  145. ** Arguments:
  146. **
  147. ** Returns:
  148. **
  149. ** Side Effects: none
  150. */
  151. PRIVATE_CODE BOOL SetUnsignedDecimalIntIniSwitch(PCUNSDECINTINISWITCH pcudiis)
  152. {
  153. INT nNewValue;
  154. ASSERT(IS_VALID_STRUCT_PTR(pcudiis, CUNSDECINTINISWITCH));
  155. /* Get unsigned decimal integer .ini switch as signed decimal integer. */
  156. ASSERT(*(pcudiis->puValue) <= INT_MAX);
  157. nNewValue = GetPrivateProfileInt(g_pcszIniSection, pcudiis->pcszKeyName,
  158. *(pcudiis->puValue), g_pcszIniFile);
  159. if (nNewValue >= 0)
  160. {
  161. if ((UINT)nNewValue != *(pcudiis->puValue))
  162. {
  163. /* New non-negative value. */
  164. *(pcudiis->puValue) = nNewValue;
  165. WARNING_OUT(("SetUnsignedDecimalIntIniSwitch(): %s set to %u in %s![%s].",
  166. pcudiis->pcszKeyName,
  167. *(pcudiis->puValue),
  168. g_pcszIniFile,
  169. g_pcszIniSection));
  170. }
  171. }
  172. else
  173. /* Negative value. */
  174. WARNING_OUT(("SetUnsignedDecimalIntIniSwitch(): Unsigned value %s set to %d in %s![%s]. Ignored.",
  175. pcudiis->pcszKeyName,
  176. nNewValue,
  177. g_pcszIniFile,
  178. g_pcszIniSection));
  179. return(TRUE);
  180. }
  181. /*
  182. ** SetIniSwitch()
  183. **
  184. **
  185. **
  186. ** Arguments:
  187. **
  188. ** Returns:
  189. **
  190. ** Side Effects: none
  191. */
  192. PRIVATE_CODE BOOL SetIniSwitch(PCVOID pcvIniSwitch)
  193. {
  194. BOOL bResult;
  195. ASSERT(IS_VALID_READ_PTR((PCINISWITCHTYPE)pcvIniSwitch, CINISWITCHTYPE));
  196. /* Set .ini switch based upon type. */
  197. switch (*(PCINISWITCHTYPE)pcvIniSwitch)
  198. {
  199. case IST_BOOL:
  200. bResult = SetBOOLIniSwitch(pcvIniSwitch);
  201. break;
  202. case IST_DEC_INT:
  203. bResult = SetDecimalIntIniSwitch(pcvIniSwitch);
  204. break;
  205. case IST_UNS_DEC_INT:
  206. bResult = SetUnsignedDecimalIntIniSwitch(pcvIniSwitch);
  207. break;
  208. default:
  209. ERROR_OUT(("SetIniSwitch(): Unrecognized .ini switch type %d.",
  210. *(PCINISWITCHTYPE)pcvIniSwitch));
  211. bResult = FALSE;
  212. break;
  213. }
  214. return(bResult);
  215. }
  216. /*
  217. ** IsYesString()
  218. **
  219. **
  220. **
  221. ** Arguments:
  222. **
  223. ** Returns:
  224. **
  225. ** Side Effects: none
  226. */
  227. PRIVATE_CODE BOOL IsYesString(PCSTR pcsz)
  228. {
  229. ASSERT(IS_VALID_STRING_PTR(pcsz, CSTR));
  230. return(IsStringInList(pcsz, s_rgcszTrue, ARRAY_ELEMENTS(s_rgcszTrue)));
  231. }
  232. /*
  233. ** IsNoString()
  234. **
  235. **
  236. **
  237. ** Arguments:
  238. **
  239. ** Returns:
  240. **
  241. ** Side Effects: none
  242. */
  243. PRIVATE_CODE BOOL IsNoString(PCSTR pcsz)
  244. {
  245. ASSERT(IS_VALID_STRING_PTR(pcsz, CSTR));
  246. return(IsStringInList(pcsz, s_rgcszFalse, ARRAY_ELEMENTS(s_rgcszFalse)));
  247. }
  248. /*
  249. ** IsStringInList()
  250. **
  251. ** Determines whether or not a given string matches a string in a list of
  252. ** strings.
  253. **
  254. ** Arguments: pcsz - pointer to string to be checked
  255. **
  256. ** Returns:
  257. **
  258. ** Side Effects: none
  259. **
  260. ** N.b., string comparison is case-insensitive.
  261. */
  262. PRIVATE_CODE BOOL IsStringInList(PCSTR pcsz, const PCSTR *pcpcszList,
  263. UINT ucbStrings)
  264. {
  265. UINT u;
  266. BOOL bFound = FALSE;
  267. ASSERT(IS_VALID_STRING_PTR(pcsz, CSTR));
  268. ASSERT(IS_VALID_READ_BUFFER_PTR(pcpcszList, PCSTR, ucbStrings * sizeof(*pcpcszList)));
  269. /* Search the list for the given string. */
  270. for (u = 0; u < ucbStrings; u++)
  271. {
  272. ASSERT(IS_VALID_STRING_PTR(pcpcszList[u], CSTR));
  273. if (! lstrcmpi(pcsz, pcpcszList[u]))
  274. {
  275. bFound = TRUE;
  276. break;
  277. }
  278. }
  279. return(bFound);
  280. }
  281. /*
  282. ** IsValidPCBOOLINIKEY()
  283. **
  284. **
  285. **
  286. ** Arguments:
  287. **
  288. ** Returns:
  289. **
  290. ** Side Effects: none
  291. */
  292. PRIVATE_CODE BOOL IsValidPCBOOLINISWITCH(PCBOOLINISWITCH pcbis)
  293. {
  294. return(IS_VALID_READ_PTR(pcbis, CBOOLINISWITCH) &&
  295. EVAL(pcbis->istype == IST_BOOL) &&
  296. IS_VALID_STRING_PTR(pcbis->pcszKeyName, CSTR) &&
  297. IS_VALID_WRITE_PTR(pcbis->pdwParentFlags, DWORD) &&
  298. EVAL(pcbis->dwFlag));
  299. }
  300. /*
  301. ** IsValidPCDECINTINISWITCH()
  302. **
  303. **
  304. **
  305. ** Arguments:
  306. **
  307. ** Returns:
  308. **
  309. ** Side Effects: none
  310. */
  311. PRIVATE_CODE BOOL IsValidPCDECINTINISWITCH(PCDECINTINISWITCH pcdiis)
  312. {
  313. return(IS_VALID_READ_PTR(pcdiis, CDECINTINISWITCH) &&
  314. EVAL(pcdiis->istype == IST_DEC_INT) &&
  315. IS_VALID_STRING_PTR(pcdiis->pcszKeyName, CSTR) &&
  316. IS_VALID_WRITE_PTR(pcdiis->pnValue, INT));
  317. }
  318. /*
  319. ** IsValidPCUNSDECINTINISWITCH()
  320. **
  321. **
  322. **
  323. ** Arguments:
  324. **
  325. ** Returns:
  326. **
  327. ** Side Effects: none
  328. */
  329. PRIVATE_CODE BOOL IsValidPCUNSDECINTINISWITCH(PCUNSDECINTINISWITCH pcudiis)
  330. {
  331. return(IS_VALID_READ_PTR(pcudiis, CUNSDECINTINISWITCH) &&
  332. EVAL(pcudiis->istype == IST_UNS_DEC_INT) &&
  333. IS_VALID_STRING_PTR(pcudiis->pcszKeyName, CSTR) &&
  334. IS_VALID_WRITE_PTR(pcudiis->puValue, UINT));
  335. }
  336. #endif
  337. /****************************** Public Functions *****************************/
  338. #ifdef DEBUG
  339. /*
  340. ** SetIniSwitches()
  341. **
  342. ** Set flags from initialization file.
  343. **
  344. ** Arguments: ppcvIniSwitches - pointer to array of pointers to .ini switch
  345. ** structures describing .ini switches to set
  346. ** ucSwitches - number of .ini switch pointers in
  347. ** ppcvIniSwitches array
  348. **
  349. ** Returns: TRUE if .ini switch processing is successful. FALSE if not.
  350. **
  351. ** Side Effects: none
  352. **
  353. ** N.b, the global variables g_pcszIniFile and g_pcszIniSection must be filled in
  354. ** before calling SetIniSwitches().
  355. */
  356. PUBLIC_CODE BOOL SetIniSwitches(const PCVOID *pcpcvIniSwitches, UINT ucSwitches)
  357. {
  358. BOOL bResult = TRUE;
  359. UINT u;
  360. ASSERT(IS_VALID_READ_BUFFER_PTR(pcpcvIniSwitches, const PCVOID, ucSwitches * sizeof(*pcpcvIniSwitches)));
  361. /* Process .ini switches. */
  362. for (u = 0; u < ucSwitches; u++)
  363. bResult = SetIniSwitch(pcpcvIniSwitches[u]) && bResult;
  364. return(bResult);
  365. }
  366. #endif