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.

459 lines
10 KiB

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