464 lines
9.6 KiB
C
464 lines
9.6 KiB
C
/*
|
|
* inifile.c - Initialization file processing module.
|
|
*/
|
|
|
|
|
|
/* Headers
|
|
**********/
|
|
|
|
#include "project.h"
|
|
#pragma hdrstop
|
|
|
|
|
|
/* Constants
|
|
************/
|
|
|
|
/* maximum length of .ini switch RHS */
|
|
|
|
#define MAX_INI_SWITCH_RHS_LEN MAX_PATH_LEN
|
|
|
|
|
|
/* Module Variables
|
|
*******************/
|
|
|
|
#ifdef DEBUG
|
|
|
|
#pragma data_seg(DATA_SEG_READ_ONLY)
|
|
|
|
/* Boolean TRUE strings used by IsIniYes() (comparison is case-insensitive) */
|
|
|
|
PRIVATE_DATA const LPCTSTR MrgcpcszTrue[] =
|
|
{
|
|
TEXT("1"),
|
|
TEXT("On"),
|
|
TEXT("True"),
|
|
TEXT("Y"),
|
|
TEXT("Yes")
|
|
};
|
|
|
|
/* Boolean FALSE strings used by IsIniYes() (comparison is case-insensitive) */
|
|
|
|
PRIVATE_DATA const LPCTSTR MrgcpcszFalse[] =
|
|
{
|
|
TEXT("0"),
|
|
TEXT("Off"),
|
|
TEXT("False"),
|
|
TEXT("N"),
|
|
TEXT("No")
|
|
};
|
|
|
|
#pragma data_seg()
|
|
|
|
#endif
|
|
|
|
|
|
/***************************** Private Functions *****************************/
|
|
|
|
/* Module Prototypes
|
|
********************/
|
|
|
|
#ifdef DEBUG
|
|
|
|
PRIVATE_CODE BOOL SetBOOLIniSwitch(PCBOOLINISWITCH);
|
|
PRIVATE_CODE BOOL SetDecimalIntIniSwitch(PCDECINTINISWITCH);
|
|
PRIVATE_CODE BOOL SetIniSwitch(PCVOID);
|
|
PRIVATE_CODE BOOL IsYesString(LPCTSTR);
|
|
PRIVATE_CODE BOOL IsNoString(LPCTSTR);
|
|
PRIVATE_CODE BOOL IsStringInList(LPCTSTR, const LPCTSTR *, UINT);
|
|
PRIVATE_CODE BOOL IsValidPCBOOLINISWITCH(PCBOOLINISWITCH);
|
|
PRIVATE_CODE BOOL IsValidPCDECINTINISWITCH(PCDECINTINISWITCH);
|
|
PRIVATE_CODE BOOL IsValidPCUNSDECINTINISWITCH(PCUNSDECINTINISWITCH);
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
/*
|
|
** SetBOOLIniSwitch()
|
|
**
|
|
**
|
|
**
|
|
** Arguments:
|
|
**
|
|
** Returns:
|
|
**
|
|
** Side Effects: none
|
|
*/
|
|
PRIVATE_CODE BOOL SetBOOLIniSwitch(PCBOOLINISWITCH pcbis)
|
|
{
|
|
DWORD dwcbKeyLen;
|
|
TCHAR rgchRHS[MAX_INI_SWITCH_RHS_LEN];
|
|
|
|
ASSERT(IS_VALID_STRUCT_PTR(pcbis, CBOOLINISWITCH));
|
|
|
|
/* Set boolean .ini switch. */
|
|
|
|
dwcbKeyLen = GetPrivateProfileString(GpcszIniSection, pcbis->pcszKeyName,
|
|
TEXT(""), rgchRHS, ARRAYSIZE(rgchRHS),
|
|
GpcszIniFile);
|
|
|
|
/* Is the .ini switch set? */
|
|
|
|
if (rgchRHS[0])
|
|
{
|
|
/* Yes. Set or clear flag? */
|
|
|
|
if (IsYesString(rgchRHS))
|
|
{
|
|
/* Set flag. */
|
|
|
|
if (IS_FLAG_CLEAR(*(pcbis->pdwParentFlags), pcbis->dwFlag))
|
|
{
|
|
SET_FLAG(*(pcbis->pdwParentFlags), pcbis->dwFlag);
|
|
|
|
WARNING_OUT((TEXT("SetBOOLIniSwitch(): %s set in %s![%s]."),
|
|
pcbis->pcszKeyName,
|
|
GpcszIniFile,
|
|
GpcszIniSection));
|
|
}
|
|
}
|
|
else if (IsNoString(rgchRHS))
|
|
{
|
|
/* Clear flag. */
|
|
|
|
if (IS_FLAG_SET(*(pcbis->pdwParentFlags), pcbis->dwFlag))
|
|
{
|
|
CLEAR_FLAG(*(pcbis->pdwParentFlags), pcbis->dwFlag);
|
|
|
|
WARNING_OUT((TEXT("SetBOOLIniSwitch(): %s cleared in %s![%s]."),
|
|
pcbis->pcszKeyName,
|
|
GpcszIniFile,
|
|
GpcszIniSection));
|
|
}
|
|
}
|
|
else
|
|
/* Unknown flag. */
|
|
WARNING_OUT((TEXT("SetBOOLIniSwitch(): Found unknown Boolean RHS %s for %s in %s![%s]."),
|
|
rgchRHS,
|
|
pcbis->pcszKeyName,
|
|
GpcszIniFile,
|
|
GpcszIniSection));
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
/*
|
|
** SetDecimalIntIniSwitch()
|
|
**
|
|
**
|
|
**
|
|
** Arguments:
|
|
**
|
|
** Returns:
|
|
**
|
|
** Side Effects: none
|
|
*/
|
|
PRIVATE_CODE BOOL SetDecimalIntIniSwitch(PCDECINTINISWITCH pcdiis)
|
|
{
|
|
INT nNewValue;
|
|
|
|
ASSERT(IS_VALID_STRUCT_PTR(pcdiis, CDECINTINISWITCH));
|
|
|
|
/* Get decimal integer .ini switch. */
|
|
|
|
nNewValue = GetPrivateProfileInt(GpcszIniSection, pcdiis->pcszKeyName,
|
|
*(pcdiis->pnValue), GpcszIniFile);
|
|
|
|
/* New value? */
|
|
|
|
if (nNewValue != *(pcdiis->pnValue))
|
|
{
|
|
/* Yes. */
|
|
|
|
*(pcdiis->pnValue) = nNewValue;
|
|
|
|
WARNING_OUT((TEXT("SetDecimalIntIniSwitch(): %s set to %d in %s![%s]."),
|
|
pcdiis->pcszKeyName,
|
|
*(pcdiis->pnValue),
|
|
GpcszIniFile,
|
|
GpcszIniSection));
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
/*
|
|
** SetUnsignedDecimalIntIniSwitch()
|
|
**
|
|
**
|
|
**
|
|
** Arguments:
|
|
**
|
|
** Returns:
|
|
**
|
|
** Side Effects: none
|
|
*/
|
|
PRIVATE_CODE BOOL SetUnsignedDecimalIntIniSwitch(PCUNSDECINTINISWITCH pcudiis)
|
|
{
|
|
INT nNewValue;
|
|
|
|
ASSERT(IS_VALID_STRUCT_PTR(pcudiis, CUNSDECINTINISWITCH));
|
|
|
|
/* Get unsigned decimal integer .ini switch as signed decimal integer. */
|
|
|
|
ASSERT(*(pcudiis->puValue) <= INT_MAX);
|
|
|
|
nNewValue = GetPrivateProfileInt(GpcszIniSection, pcudiis->pcszKeyName,
|
|
*(pcudiis->puValue), GpcszIniFile);
|
|
|
|
if (nNewValue >= 0)
|
|
{
|
|
if ((UINT)nNewValue != *(pcudiis->puValue))
|
|
{
|
|
/* New non-negative value. */
|
|
|
|
*(pcudiis->puValue) = nNewValue;
|
|
|
|
WARNING_OUT((TEXT("SetUnsignedDecimalIntIniSwitch(): %s set to %u in %s![%s]."),
|
|
pcudiis->pcszKeyName,
|
|
*(pcudiis->puValue),
|
|
GpcszIniFile,
|
|
GpcszIniSection));
|
|
}
|
|
}
|
|
else
|
|
/* Negative value. */
|
|
WARNING_OUT((TEXT("SetUnsignedDecimalIntIniSwitch(): Unsigned value %s set to %d in %s![%s]. Ignored."),
|
|
pcudiis->pcszKeyName,
|
|
nNewValue,
|
|
GpcszIniFile,
|
|
GpcszIniSection));
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
/*
|
|
** SetIniSwitch()
|
|
**
|
|
**
|
|
**
|
|
** Arguments:
|
|
**
|
|
** Returns:
|
|
**
|
|
** Side Effects: none
|
|
*/
|
|
PRIVATE_CODE BOOL SetIniSwitch(PCVOID pcvIniSwitch)
|
|
{
|
|
BOOL bResult;
|
|
|
|
ASSERT(IS_VALID_READ_PTR((PCINISWITCHTYPE)pcvIniSwitch, CINISWITCHTYPE));
|
|
|
|
/* Set .ini switch based upon type. */
|
|
|
|
switch (*(PCINISWITCHTYPE)pcvIniSwitch)
|
|
{
|
|
case IST_BOOL:
|
|
bResult = SetBOOLIniSwitch(pcvIniSwitch);
|
|
break;
|
|
|
|
case IST_DEC_INT:
|
|
bResult = SetDecimalIntIniSwitch(pcvIniSwitch);
|
|
break;
|
|
|
|
case IST_UNS_DEC_INT:
|
|
bResult = SetUnsignedDecimalIntIniSwitch(pcvIniSwitch);
|
|
break;
|
|
|
|
default:
|
|
ERROR_OUT((TEXT("SetIniSwitch(): Unrecognized .ini switch type %d."),
|
|
*(PCINISWITCHTYPE)pcvIniSwitch));
|
|
bResult = FALSE;
|
|
break;
|
|
}
|
|
|
|
return(bResult);
|
|
}
|
|
|
|
|
|
/*
|
|
** IsYesString()
|
|
**
|
|
**
|
|
**
|
|
** Arguments:
|
|
**
|
|
** Returns:
|
|
**
|
|
** Side Effects: none
|
|
*/
|
|
PRIVATE_CODE BOOL IsYesString(LPCTSTR pcsz)
|
|
{
|
|
ASSERT(IS_VALID_STRING_PTR(pcsz, CSTR));
|
|
|
|
return(IsStringInList(pcsz, MrgcpcszTrue, ARRAY_ELEMENTS(MrgcpcszTrue)));
|
|
}
|
|
|
|
|
|
/*
|
|
** IsNoString()
|
|
**
|
|
**
|
|
**
|
|
** Arguments:
|
|
**
|
|
** Returns:
|
|
**
|
|
** Side Effects: none
|
|
*/
|
|
PRIVATE_CODE BOOL IsNoString(LPCTSTR pcsz)
|
|
{
|
|
ASSERT(IS_VALID_STRING_PTR(pcsz, CSTR));
|
|
|
|
return(IsStringInList(pcsz, MrgcpcszFalse, ARRAY_ELEMENTS(MrgcpcszFalse)));
|
|
}
|
|
|
|
|
|
/*
|
|
** IsStringInList()
|
|
**
|
|
** Determines whether or not a given string matches a string in a list of
|
|
** strings.
|
|
**
|
|
** Arguments: pcsz - pointer to string to be checked
|
|
**
|
|
** Returns:
|
|
**
|
|
** Side Effects: none
|
|
**
|
|
** N.b., string comparison is case-insensitive.
|
|
*/
|
|
PRIVATE_CODE BOOL IsStringInList(LPCTSTR pcsz, const LPCTSTR *pcpcszList,
|
|
UINT ucbStrings)
|
|
{
|
|
UINT u;
|
|
BOOL bFound = FALSE;
|
|
|
|
ASSERT(IS_VALID_STRING_PTR(pcsz, CSTR));
|
|
ASSERT(IS_VALID_READ_BUFFER_PTR(pcpcszList, LPCTSTR, ucbStrings * sizeof(*pcpcszList)));
|
|
|
|
/* Search the list for the given string. */
|
|
|
|
for (u = 0; u < ucbStrings; u++)
|
|
{
|
|
ASSERT(IS_VALID_STRING_PTR(pcpcszList[u], CSTR));
|
|
|
|
if (! lstrcmpi(pcsz, pcpcszList[u]))
|
|
{
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return(bFound);
|
|
}
|
|
|
|
|
|
/*
|
|
** IsValidPCBOOLINIKEY()
|
|
**
|
|
**
|
|
**
|
|
** Arguments:
|
|
**
|
|
** Returns:
|
|
**
|
|
** Side Effects: none
|
|
*/
|
|
PRIVATE_CODE BOOL IsValidPCBOOLINISWITCH(PCBOOLINISWITCH pcbis)
|
|
{
|
|
return(IS_VALID_READ_PTR(pcbis, CBOOLINISWITCH) &&
|
|
EVAL(pcbis->istype == IST_BOOL) &&
|
|
IS_VALID_STRING_PTR(pcbis->pcszKeyName, CSTR) &&
|
|
IS_VALID_WRITE_PTR(pcbis->pdwParentFlags, DWORD) &&
|
|
EVAL(pcbis->dwFlag));
|
|
}
|
|
|
|
|
|
/*
|
|
** IsValidPCDECINTINISWITCH()
|
|
**
|
|
**
|
|
**
|
|
** Arguments:
|
|
**
|
|
** Returns:
|
|
**
|
|
** Side Effects: none
|
|
*/
|
|
PRIVATE_CODE BOOL IsValidPCDECINTINISWITCH(PCDECINTINISWITCH pcdiis)
|
|
{
|
|
return(IS_VALID_READ_PTR(pcdiis, CDECINTINISWITCH) &&
|
|
EVAL(pcdiis->istype == IST_DEC_INT) &&
|
|
IS_VALID_STRING_PTR(pcdiis->pcszKeyName, CSTR) &&
|
|
IS_VALID_WRITE_PTR(pcdiis->pnValue, INT));
|
|
}
|
|
|
|
|
|
/*
|
|
** IsValidPCUNSDECINTINISWITCH()
|
|
**
|
|
**
|
|
**
|
|
** Arguments:
|
|
**
|
|
** Returns:
|
|
**
|
|
** Side Effects: none
|
|
*/
|
|
PRIVATE_CODE BOOL IsValidPCUNSDECINTINISWITCH(PCUNSDECINTINISWITCH pcudiis)
|
|
{
|
|
return(IS_VALID_READ_PTR(pcudiis, CUNSDECINTINISWITCH) &&
|
|
EVAL(pcudiis->istype == IST_UNS_DEC_INT) &&
|
|
IS_VALID_STRING_PTR(pcudiis->pcszKeyName, CSTR) &&
|
|
IS_VALID_WRITE_PTR(pcudiis->puValue, UINT));
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/****************************** Public Functions *****************************/
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
/*
|
|
** SetIniSwitches()
|
|
**
|
|
** Set flags from initialization file.
|
|
**
|
|
** Arguments: ppcvIniSwitches - pointer to array of pointers to .ini switch
|
|
** structures describing .ini switches to set
|
|
** ucSwitches - number of .ini switch pointers in
|
|
** ppcvIniSwitches array
|
|
**
|
|
** Returns: TRUE if .ini switch processing is successful. FALSE if not.
|
|
**
|
|
** Side Effects: none
|
|
**
|
|
** N.b, the global variables GpcszIniFile and GpcszIniSection must be filled in
|
|
** before calling SetIniSwitches().
|
|
*/
|
|
PUBLIC_CODE BOOL SetIniSwitches(const PCVOID *pcpcvIniSwitches, UINT ucSwitches)
|
|
{
|
|
BOOL bResult = TRUE;
|
|
UINT u;
|
|
|
|
ASSERT(IS_VALID_READ_BUFFER_PTR(pcpcvIniSwitches, const PCVOID, ucSwitches * sizeof(*pcpcvIniSwitches)));
|
|
|
|
/* Process .ini switches. */
|
|
|
|
for (u = 0; u < ucSwitches; u++)
|
|
bResult = SetIniSwitch(pcpcvIniSwitches[u]) && bResult;
|
|
|
|
return(bResult);
|
|
}
|
|
|
|
#endif
|
|
|