Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

1119 lines
26 KiB

//
// Debug squirty functions
//
#include "proj.h"
#pragma hdrstop
#define DEBUG_BREAK _try { DebugBreak(); } _except (EXCEPTION_EXECUTE_HANDLER) {;}
#ifdef DEBUG
DWORD g_dwDumpFlags = 0; // DF_*
DWORD g_dwBreakFlags = BF_ONVALIDATE; // BF_*
DWORD g_dwTraceFlags = 0; // TF_*
DWORD g_dwPrototype = 0;
DWORD g_dwFuncTraceFlags = 0; // FTF_*
// TLS slot used to store depth for CcshellFuncMsg indentation
static DWORD g_tlsStackDepth = TLS_OUT_OF_INDEXES;
// Hack stack depth counter used when g_tlsStackDepth is not available
static DWORD g_dwHackStackDepth = 0;
static char g_szIndentLeader[] = " ";
#ifdef WINNT
static WCHAR g_wszIndentLeader[] = L" ";
#endif
#pragma data_seg(DATASEG_READONLY)
static CHAR const FAR c_szNewline[] = "\r\n"; // (Deliberately CHAR)
#ifdef UNICODE
static WCHAR const FAR c_wszNewline[] = TEXT("\r\n");
#else
static WCHAR const FAR c_wszNewline[] = L"";
#endif
#pragma data_seg()
extern CHAR const FAR c_szTrace[]; // (Deliberately CHAR)
extern WCHAR const FAR c_wszTrace[];
extern TCHAR const FAR c_szAssertFailed[];
// BUGBUG (scotth): the following functions are temporary and will
// be removed once all the components don't have TEXT() wrapping their
// debug strings anymore.
void WINCAPI _AssertMsg(BOOL f, LPCTSTR pszMsg, ...)
{
TCHAR ach[1024+40];
va_list vArgs;
if (!f)
{
int cch;
#ifdef UNICODE
lstrcpy(ach, c_wszTrace);
#else
lstrcpy(ach, c_szTrace);
#endif
cch = lstrlen(ach);
va_start(vArgs, pszMsg);
wvsprintf(&ach[cch], pszMsg, vArgs);
va_end(vArgs);
OutputDebugString(ach);
#ifdef UNICODE
OutputDebugString(c_wszNewline);
#else
OutputDebugString(c_szNewline);
#endif
if (IsFlagSet(g_dwBreakFlags, BF_ONVALIDATE))
DEBUG_BREAK;
}
}
void WINCAPI _DebugMsg(DWORD flag, LPCTSTR pszMsg, ...)
{
TCHAR ach[5*MAX_PATH+40]; // Handles 5*largest path + slop for message
va_list vArgs;
if (TF_ALWAYS == flag || (IsFlagSet(g_dwTraceFlags, flag) && flag))
{
int cch;
#ifdef UNICODE
lstrcpy(ach, c_wszTrace);
#else
lstrcpy(ach, c_szTrace);
#endif
cch = lstrlen(ach);
va_start(vArgs, pszMsg);
try
{
wvsprintf(&ach[cch], pszMsg, vArgs);
}
except(EXCEPTION_EXECUTE_HANDLER)
{
OutputDebugString(TEXT("CCSHELL: DebugMsg exception: "));
OutputDebugString(pszMsg);
}
va_end(vArgs);
OutputDebugString(ach);
#ifdef UNICODE
OutputDebugString(c_wszNewline);
#else
OutputDebugString(c_szNewline);
#endif
}
}
//
// Smart debug functions
//
/*----------------------------------------------------------
Purpose: Displays assertion string.
Returns: --
Cond: --
*/
void
CcshellAssertFailed(
LPCTSTR pszFile,
int line)
{
LPCTSTR psz;
TCHAR ach[256];
// Strip off path info from filename string, if present.
//
for (psz = pszFile + lstrlen(pszFile); psz != pszFile; psz=CharPrev(pszFile, psz))
{
if ((CharPrev(pszFile, psz)!= (psz-2)) && *(psz - 1) == TEXT('\\'))
break;
}
wsprintf(ach, c_szAssertFailed, psz, line);
OutputDebugString(ach);
if (IsFlagSet(g_dwBreakFlags, BF_ONVALIDATE))
DEBUG_BREAK;
}
/*----------------------------------------------------------
Purpose: Keep track of the stack depth for function call trace
messages.
Returns: --
Cond: --
*/
void
CcshellStackEnter(void)
{
if (TLS_OUT_OF_INDEXES != g_tlsStackDepth)
{
DWORD dwDepth;
dwDepth = (DWORD)TlsGetValue(g_tlsStackDepth);
TlsSetValue(g_tlsStackDepth, (LPVOID)(dwDepth + 1));
}
else
{
g_dwHackStackDepth++;
}
}
/*----------------------------------------------------------
Purpose: Keep track of the stack depth for functionc all trace
messages.
Returns: --
Cond: --
*/
void
CcshellStackLeave(void)
{
if (TLS_OUT_OF_INDEXES != g_tlsStackDepth)
{
DWORD dwDepth;
dwDepth = (DWORD)TlsGetValue(g_tlsStackDepth);
if (EVAL(0 < dwDepth))
{
EVAL(TlsSetValue(g_tlsStackDepth, (LPVOID)(dwDepth - 1)));
}
}
else
{
if (EVAL(0 < g_dwHackStackDepth))
{
g_dwHackStackDepth--;
}
}
}
/*----------------------------------------------------------
Purpose: Return the stack depth.
Returns: see above
Cond: --
*/
static
DWORD
CcshellGetStackDepth(void)
{
DWORD dwDepth;
if (TLS_OUT_OF_INDEXES != g_tlsStackDepth)
{
dwDepth = (DWORD)TlsGetValue(g_tlsStackDepth);
}
else
{
dwDepth = g_dwHackStackDepth;
}
return dwDepth;
}
#ifdef WINNT
/*----------------------------------------------------------
Purpose: This function converts a multi-byte string to a
wide-char string.
If pszBuf is non-NULL and the converted string can fit in
pszBuf, then *ppszWide will point to the given buffer.
Otherwise, this function will allocate a buffer that can
hold the converted string.
If pszAnsi is NULL, then *ppszWide will be freed. Note
that pszBuf must be the same pointer between the call
that converted the string and the call that frees the
string.
Returns: TRUE
FALSE (if out of memory)
Cond: --
*/
BOOL
UnicodeFromAnsi(
LPWSTR * ppwszWide,
LPCSTR pszAnsi, // NULL to clean up
LPWSTR pwszBuf,
int cchBuf)
{
BOOL bRet;
// Convert the string?
if (pszAnsi)
{
// Yes; determine the converted string length
int cch;
LPWSTR pwsz;
int cchAnsi = lstrlenA(pszAnsi)+1;
cch = MultiByteToWideChar(CP_ACP, 0, pszAnsi, cchAnsi, NULL, 0);
// String too big, or is there no buffer?
if (cch > cchBuf || NULL == pwszBuf)
{
// Yes; allocate space
cchBuf = cch + 1;
pwsz = (LPWSTR)LocalAlloc(LPTR, CbFromCchW(cchBuf));
}
else
{
// No; use the provided buffer
ASSERT(pwszBuf);
pwsz = pwszBuf;
}
if (pwsz)
{
// Convert the string
cch = MultiByteToWideChar(CP_ACP, 0, pszAnsi, cchAnsi, pwsz, cchBuf);
bRet = (0 < cch);
}
else
{
bRet = FALSE;
}
*ppwszWide = pwsz;
}
else
{
// No; was this buffer allocated?
if (*ppwszWide && pwszBuf != *ppwszWide)
{
// Yes; clean up
LocalFree((HLOCAL)*ppwszWide);
*ppwszWide = NULL;
}
bRet = TRUE;
}
return bRet;
}
/*----------------------------------------------------------
Purpose: Wide-char version of CcshellAssertMsgA
Returns: --
Cond: --
*/
void
CDECL
CcshellAssertMsgW(
BOOL f,
LPCSTR pszMsg, ...)
{
WCHAR ach[1024+40]; // Largest path plus extra
va_list vArgs;
if (!f)
{
int cch;
WCHAR wszBuf[1024];
LPWSTR pwsz;
lstrcpyW(ach, c_wszTrace);
cch = lstrlenW(ach);
va_start(vArgs, pszMsg);
// (We convert the string, rather than simply input an
// LPCWSTR parameter, so the caller doesn't have to wrap
// all the string constants with the TEXT() macro.)
if (UnicodeFromAnsi(&pwsz, pszMsg, wszBuf, SIZECHARS(wszBuf)))
{
wvsprintfW(&ach[cch], pwsz, vArgs);
UnicodeFromAnsi(&pwsz, NULL, wszBuf, 0);
}
va_end(vArgs);
OutputDebugStringW(ach);
OutputDebugStringW(c_wszNewline);
if (IsFlagSet(g_dwBreakFlags, BF_ONVALIDATE))
DEBUG_BREAK;
}
}
/*----------------------------------------------------------
Purpose: Wide-char version of CcshellDebugMsgA. Note this
function deliberately takes an ANSI format string
so our trace messages don't all need to be wrapped
in TEXT().
Returns: --
Cond: --
*/
void
CDECL
CcshellDebugMsgW(
DWORD flag,
LPCSTR pszMsg, ...) // (this is deliberately CHAR)
{
WCHAR ach[1024+40]; // Largest path plus extra
va_list vArgs;
if (TF_ALWAYS == flag || IsFlagSet(g_dwTraceFlags, flag))
{
int cch;
WCHAR wszBuf[1024];
LPWSTR pwsz;
lstrcpyW(ach, c_wszTrace);
cch = lstrlenW(ach);
va_start(vArgs, pszMsg);
// (We convert the string, rather than simply input an
// LPCWSTR parameter, so the caller doesn't have to wrap
// all the string constants with the TEXT() macro.)
if (UnicodeFromAnsi(&pwsz, pszMsg, wszBuf, SIZECHARS(wszBuf)))
{
wvsprintfW(&ach[cch], pwsz, vArgs);
UnicodeFromAnsi(&pwsz, NULL, wszBuf, 0);
}
va_end(vArgs);
OutputDebugStringW(ach);
OutputDebugStringW(c_wszNewline);
}
}
/*----------------------------------------------------------
Purpose: Wide-char version of CcshellFuncMsgA. Note this
function deliberately takes an ANSI format string
so our trace messages don't all need to be wrapped
in TEXT().
Returns: --
Cond: --
*/
void
CDECL
CcshellFuncMsgW(
DWORD flag,
LPCSTR pszMsg, ...) // (this is deliberately CHAR)
{
WCHAR ach[1024+40]; // Largest path plus extra
va_list vArgs;
if (IsFlagSet(g_dwTraceFlags, TF_FUNC) &&
IsFlagSet(g_dwFuncTraceFlags, flag))
{
int cch;
WCHAR wszBuf[1024];
LPWSTR pwsz;
DWORD dwStackDepth;
LPWSTR pszLeaderEnd;
WCHAR chSave;
// Determine the indentation for trace message based on
// stack depth.
dwStackDepth = CcshellGetStackDepth();
if (dwStackDepth < SIZECHARS(g_szIndentLeader))
{
pszLeaderEnd = &g_wszIndentLeader[dwStackDepth];
}
else
{
pszLeaderEnd = &g_wszIndentLeader[SIZECHARS(g_wszIndentLeader)-1];
}
chSave = *pszLeaderEnd;
*pszLeaderEnd = '\0';
wsprintfW(ach, TEXT("%s %s"), c_wszTrace, g_wszIndentLeader);
*pszLeaderEnd = chSave;
// Compose remaining string
cch = lstrlenW(ach);
va_start(vArgs, pszMsg);
// (We convert the string, rather than simply input an
// LPCWSTR parameter, so the caller doesn't have to wrap
// all the string constants with the TEXT() macro.)
if (UnicodeFromAnsi(&pwsz, pszMsg, wszBuf, SIZECHARS(wszBuf)))
{
wvsprintfW(&ach[cch], pwsz, vArgs);
UnicodeFromAnsi(&pwsz, NULL, wszBuf, 0);
}
va_end(vArgs);
OutputDebugStringW(ach);
OutputDebugStringW(c_wszNewline);
}
}
#endif // WINNT
/*----------------------------------------------------------
Purpose: Assert failed message only
Returns: --
Cond: --
*/
void
CDECL
CcshellAssertMsgA(
BOOL f,
LPCSTR pszMsg, ...)
{
CHAR ach[1024+40]; // Largest path plus extra
va_list vArgs;
if (!f)
{
int cch;
lstrcpyA(ach, c_szTrace);
cch = lstrlenA(ach);
va_start(vArgs, pszMsg);
wvsprintfA(&ach[cch], pszMsg, vArgs);
va_end(vArgs);
OutputDebugStringA(ach);
OutputDebugStringA(c_szNewline);
if (IsFlagSet(g_dwBreakFlags, BF_ONVALIDATE))
DEBUG_BREAK;
}
}
/*----------------------------------------------------------
Purpose: Debug spew
Returns: --
Cond: --
*/
void
CDECL
CcshellDebugMsgA(
DWORD flag,
LPCSTR pszMsg, ...)
{
CHAR ach[1024+40]; // Largest path plus extra
va_list vArgs;
if (TF_ALWAYS == flag || IsFlagSet(g_dwTraceFlags, flag))
{
int cch;
lstrcpyA(ach, c_szTrace);
cch = lstrlenA(ach);
va_start(vArgs, pszMsg);
wvsprintfA(&ach[cch], pszMsg, vArgs);
va_end(vArgs);
OutputDebugStringA(ach);
OutputDebugStringA(c_szNewline);
}
}
/*----------------------------------------------------------
Purpose: Debug spew for function trace calls
Returns: --
Cond: --
*/
void
CDECL
CcshellFuncMsgA(
DWORD flag,
LPCSTR pszMsg, ...)
{
CHAR ach[1024+40]; // Largest path plus extra
va_list vArgs;
if (IsFlagSet(g_dwTraceFlags, TF_FUNC) &&
IsFlagSet(g_dwFuncTraceFlags, flag))
{
int cch;
DWORD dwStackDepth;
LPSTR pszLeaderEnd;
CHAR chSave;
// Determine the indentation for trace message based on
// stack depth.
dwStackDepth = CcshellGetStackDepth();
if (dwStackDepth < sizeof(g_szIndentLeader))
{
pszLeaderEnd = &g_szIndentLeader[dwStackDepth];
}
else
{
pszLeaderEnd = &g_szIndentLeader[sizeof(g_szIndentLeader)-1];
}
chSave = *pszLeaderEnd;
*pszLeaderEnd = '\0';
wsprintfA(ach, "%s %s", c_szTrace, g_szIndentLeader);
*pszLeaderEnd = chSave;
// Compose remaining string
cch = lstrlenA(ach);
va_start(vArgs, pszMsg);
wvsprintfA(&ach[cch], pszMsg, vArgs);
va_end(vArgs);
OutputDebugStringA(ach);
OutputDebugStringA(c_szNewline);
}
}
//
// Debug .ini functions
//
#pragma data_seg(DATASEG_READONLY)
// (c_szCcshellIniFile and c_szCcshellIniSecDebug are declared in debug.h)
extern TCHAR const FAR c_szCcshellIniFile[];
extern TCHAR const FAR c_szCcshellIniSecDebug[];
TCHAR const FAR c_szNull[] = TEXT("");
TCHAR const FAR c_szZero[] = TEXT("0");
TCHAR const FAR c_szIniKeyBreakFlags[] = TEXT("BreakFlags");
TCHAR const FAR c_szIniKeyTraceFlags[] = TEXT("TraceFlags");
TCHAR const FAR c_szIniKeyFuncTraceFlags[] = TEXT("FuncTraceFlags");
TCHAR const FAR c_szIniKeyDumpFlags[] = TEXT("DumpFlags");
TCHAR const FAR c_szIniKeyProtoFlags[] = TEXT("Prototype");
#pragma data_seg()
// Some of the .ini processing code was pimped from the sync engine.
//
typedef struct _INIKEYHEADER
{
LPCTSTR pszSectionName;
LPCTSTR pszKeyName;
LPCTSTR pszDefaultRHS;
} INIKEYHEADER;
typedef struct _BOOLINIKEY
{
INIKEYHEADER ikh;
LPDWORD puStorage;
DWORD dwFlag;
} BOOLINIKEY;
typedef struct _INTINIKEY
{
INIKEYHEADER ikh;
LPDWORD puStorage;
} INTINIKEY;
#define PutIniIntCmp(idsSection, idsKey, nNewValue, nSave) \
if ((nNewValue) != (nSave)) PutIniInt(idsSection, idsKey, nNewValue)
#define WritePrivateProfileInt(szApp, szKey, i, lpFileName) \
{CHAR sz[7]; \
WritePrivateProfileString(szApp, szKey, SzFromInt(sz, i), lpFileName);}
#ifdef BOOL_INI_VALUES
/* Boolean TRUE strings used by IsIniYes() (comparison is case-insensitive) */
static LPCTSTR s_rgpszTrue[] =
{
TEXT("1"),
TEXT("On"),
TEXT("True"),
TEXT("Y"),
TEXT("Yes")
};
/* Boolean FALSE strings used by IsIniYes() (comparison is case-insensitive) */
static LPCTSTR s_rgpszFalse[] =
{
TEXT("0"),
TEXT("Off"),
TEXT("False"),
TEXT("N"),
TEXT("No")
};
#endif
#ifdef BOOL_INI_VALUES
/*----------------------------------------------------------
Purpose: Determines whether a string corresponds to a boolean
TRUE value.
Returns: The boolean value (TRUE or FALSE)
Cond: --
*/
BOOL
PRIVATE
IsIniYes(
LPCTSTR psz)
{
int i;
BOOL bNotFound = TRUE;
BOOL bResult;
ASSERT(psz);
/* Is the value TRUE? */
for (i = 0; i < ARRAYSIZE(s_rgpszTrue); i++)
{
if (IsSzEqual(psz, s_rgpszTrue[i]))
{
bResult = TRUE;
bNotFound = FALSE;
break;
}
}
/* Is the value FALSE? */
if (bNotFound)
{
for (i = 0; i < ARRAYSIZE(s_rgpszFalse); i++)
{
if (IsSzEqual(psz, s_rgpszFalse[i]))
{
bResult = FALSE;
bNotFound = FALSE;
break;
}
}
/* Is the value a known string? */
if (bNotFound)
{
/* No. Whine about it. */
TRACE_MSG(TF_WARNING, "IsIniYes() called on unknown Boolean RHS '%s'.", psz);
bResult = FALSE;
}
}
return bResult;
}
/*----------------------------------------------------------
Purpose: Process keys with boolean RHSs.
Returns: --
Cond: --
*/
void
PRIVATE
ProcessBooleans(void)
{
int i;
for (i = 0; i < ARRAYSIZE(s_rgbik); i++)
{
DWORD dwcbKeyLen;
TCHAR szRHS[MAX_BUF];
BOOLINIKEY * pbik = &(s_rgbik[i]);
LPCTSTR lpcszRHS;
/* Look for key. */
dwcbKeyLen = GetPrivateProfileString(pbik->ikh.pszSectionName,
pbik->ikh.pszKeyName, TEXT(""), szRHS,
SIZECHARS(szRHS), c_szCcshellIniFile);
if (dwcbKeyLen)
lpcszRHS = szRHS;
else
lpcszRHS = pbik->ikh.pszDefaultRHS;
if (IsIniYes(lpcszRHS))
{
if (IsFlagClear(*(pbik->puStorage), pbik->dwFlag))
TRACE_MSG(TF_GENERAL, "ProcessIniFile(): %s set in %s![%s].",
pbik->ikh.pszKeyName,
c_szCcshellIniFile,
pbik->ikh.pszSectionName);
SetFlag(*(pbik->puStorage), pbik->dwFlag);
}
else
{
if (IsFlagSet(*(pbik->puStorage), pbik->dwFlag))
TRACE_MSG(TF_GENERAL, "ProcessIniFile(): %s cleared in %s![%s].",
pbik->ikh.pszKeyName,
c_szCcshellIniFile,
pbik->ikh.pszSectionName);
ClearFlag(*(pbik->puStorage), pbik->dwFlag);
}
}
}
#endif
/*----------------------------------------------------------
Purpose: Special verion of atoi. Supports hexadecimal too.
If this function returns FALSE, *piRet is set to 0.
Returns: TRUE if the string is a number, or contains a partial number
FALSE if the string is not a number
Cond: --
*/
static
BOOL
MyStrToIntExA(
LPCSTR pszString,
DWORD dwFlags, // STIF_ bitfield
int FAR * piRet)
{
#define IS_DIGIT(ch) InRange(ch, '0', '9')
BOOL bRet;
int n;
BOOL bNeg = FALSE;
LPCSTR psz;
LPCSTR pszAdj;
// Skip leading whitespace
//
for (psz = pszString; *psz == ' ' || *psz == '\n' || *psz == '\t'; psz = CharNextA(psz))
;
// Determine possible explicit signage
//
if (*psz == '+' || *psz == '-')
{
bNeg = (*psz == '+') ? FALSE : TRUE;
psz++;
}
// Or is this hexadecimal?
//
pszAdj = CharNextA(psz);
if ((STIF_SUPPORT_HEX & dwFlags) &&
*psz == '0' && (*pszAdj == 'x' || *pszAdj == 'X'))
{
// Yes
// (Never allow negative sign with hexadecimal numbers)
bNeg = FALSE;
psz = CharNextA(pszAdj);
pszAdj = psz;
// Do the conversion
//
for (n = 0; ; psz = CharNextA(psz))
{
if (IS_DIGIT(*psz))
n = 0x10 * n + *psz - '0';
else
{
CHAR ch = *psz;
int n2;
if (ch >= 'a')
ch -= 'a' - 'A';
n2 = ch - 'A' + 0xA;
if (n2 >= 0xA && n2 <= 0xF)
n = 0x10 * n + n2;
else
break;
}
}
// Return TRUE if there was at least one digit
bRet = (psz != pszAdj);
}
else
{
// No
pszAdj = psz;
// Do the conversion
for (n = 0; IS_DIGIT(*psz); psz = CharNextA(psz))
n = 10 * n + *psz - '0';
// Return TRUE if there was at least one digit
bRet = (psz != pszAdj);
}
*piRet = bNeg ? -n : n;
return bRet;
}
#ifdef UNICODE
/*----------------------------------------------------------
Purpose: This function converts a wide-char string to a multi-byte
string.
If pszBuf is non-NULL and the converted string can fit in
pszBuf, then *ppszAnsi will point to the given buffer.
Otherwise, this function will allocate a buffer that can
hold the converted string.
If pszWide is NULL, then *ppszAnsi will be freed. Note
that pszBuf must be the same pointer between the call
that converted the string and the call that frees the
string.
Returns: TRUE
FALSE (if out of memory)
Cond: --
*/
static
BOOL
MyAnsiFromUnicode(
LPSTR * ppszAnsi,
LPCWSTR pwszWide, // NULL to clean up
LPSTR pszBuf,
int cchBuf)
{
BOOL bRet;
// Convert the string?
if (pwszWide)
{
// Yes; determine the converted string length
int cch;
LPSTR psz;
cch = WideCharToMultiByte(CP_ACP, 0, pwszWide, -1, NULL, 0, NULL, NULL);
// String too big, or is there no buffer?
if (cch > cchBuf || NULL == pszBuf)
{
// Yes; allocate space
cchBuf = cch + 1;
psz = (LPSTR)LocalAlloc(LPTR, CbFromCchA(cchBuf));
}
else
{
// No; use the provided buffer
ASSERT(pszBuf);
psz = pszBuf;
}
if (psz)
{
// Convert the string
cch = WideCharToMultiByte(CP_ACP, 0, pwszWide, -1, psz, cchBuf, NULL, NULL);
bRet = (0 < cch);
}
else
{
bRet = FALSE;
}
*ppszAnsi = psz;
}
else
{
// No; was this buffer allocated?
if (*ppszAnsi && pszBuf != *ppszAnsi)
{
// Yes; clean up
LocalFree((HLOCAL)*ppszAnsi);
*ppszAnsi = NULL;
}
bRet = TRUE;
}
return bRet;
}
/*----------------------------------------------------------
Purpose: Wide-char wrapper for StrToIntExA.
Returns: see StrToIntExA
Cond: --
*/
static
BOOL
MyStrToIntExW(
LPCWSTR pwszString,
DWORD dwFlags, // STIF_ bitfield
int FAR * piRet)
{
// Most strings will simply use this temporary buffer, but AnsiFromUnicode
// will allocate a buffer if the supplied string is bigger.
CHAR szBuf[MAX_PATH];
LPSTR pszString;
BOOL bRet = MyAnsiFromUnicode(&pszString, pwszString, szBuf, SIZECHARS(szBuf));
if (bRet)
{
bRet = MyStrToIntExA(pszString, dwFlags, piRet);
MyAnsiFromUnicode(&pszString, NULL, szBuf, 0);
}
return bRet;
}
#endif // UNICODE
#ifdef UNICODE
#define MyStrToIntEx MyStrToIntExW
#else
#define MyStrToIntEx MyStrToIntExA
#endif
/*----------------------------------------------------------
Purpose: This function reads a .ini file to determine the debug
flags to set. The .ini file and section are specified
by the following manifest constants:
SZ_DEBUGINI
SZ_DEBUGSECTION
The debug variables that are set by this function are
g_dwDumpFlags, g_dwTraceFlags, g_dwBreakFlags, and
g_dwFuncTraceFlags, g_dwPrototype.
Returns: TRUE if initialization is successful
Cond: --
*/
BOOL
PUBLIC
CcshellGetDebugFlags(void)
{
TCHAR szRHS[MAX_PATH];
int val;
// BUGBUG (scotth): Yes, COMCTL32 exports StrToIntEx, but I
// don't want to cause a dependency delta and force everyone
// to get a new comctl32 just because they built debug.
// So use a local version of StrToIntEx.
// Trace Flags
GetPrivateProfileString(c_szCcshellIniSecDebug,
c_szIniKeyTraceFlags,
c_szNull,
szRHS,
SIZECHARS(szRHS),
c_szCcshellIniFile);
if (MyStrToIntEx(szRHS, STIF_SUPPORT_HEX, &val))
g_dwTraceFlags = (DWORD)val;
TRACE_MSG(TF_GENERAL, "CcshellGetDebugFlags(): %s set to %#08x.",
c_szIniKeyTraceFlags, g_dwTraceFlags);
// Function trace Flags
GetPrivateProfileString(c_szCcshellIniSecDebug,
c_szIniKeyFuncTraceFlags,
c_szNull,
szRHS,
SIZECHARS(szRHS),
c_szCcshellIniFile);
if (MyStrToIntEx(szRHS, STIF_SUPPORT_HEX, &val))
g_dwFuncTraceFlags = (DWORD)val;
TRACE_MSG(TF_GENERAL, "CcshellGetDebugFlags(): %s set to %#08x.",
c_szIniKeyFuncTraceFlags, g_dwFuncTraceFlags);
// Dump Flags
GetPrivateProfileString(c_szCcshellIniSecDebug,
c_szIniKeyDumpFlags,
c_szNull,
szRHS,
SIZECHARS(szRHS),
c_szCcshellIniFile);
if (MyStrToIntEx(szRHS, STIF_SUPPORT_HEX, &val))
g_dwDumpFlags = (DWORD)val;
TRACE_MSG(TF_GENERAL, "CcshellGetDebugFlags(): %s set to %#08x.",
c_szIniKeyDumpFlags, g_dwDumpFlags);
// Break Flags
GetPrivateProfileString(c_szCcshellIniSecDebug,
c_szIniKeyBreakFlags,
c_szNull,
szRHS,
SIZECHARS(szRHS),
c_szCcshellIniFile);
if (MyStrToIntEx(szRHS, STIF_SUPPORT_HEX, &val))
g_dwBreakFlags = (DWORD)val;
TRACE_MSG(TF_GENERAL, "CcshellGetDebugFlags(): %s set to %#08x.",
c_szIniKeyBreakFlags, g_dwBreakFlags);
// Prototype Flags
GetPrivateProfileString(c_szCcshellIniSecDebug,
c_szIniKeyProtoFlags,
c_szNull,
szRHS,
SIZECHARS(szRHS),
c_szCcshellIniFile);
if (MyStrToIntEx(szRHS, STIF_SUPPORT_HEX, &val))
g_dwPrototype = (DWORD)val;
TRACE_MSG(TF_GENERAL, "CcshellGetDebugFlags(): %s set to %#08x.",
c_szIniKeyProtoFlags, g_dwPrototype);
return TRUE;
}
#endif // DEBUG