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.
 
 
 
 
 
 

597 lines
16 KiB

//====== Assertion/Debug output APIs =================================
#if defined(DECLARE_DEBUG) && defined(DEBUG)
//
// Declare module-specific debug strings
//
// When including this header in your private header file, do not
// define DECLARE_DEBUG. But do define DECLARE_DEBUG in one of the
// source files in your project, and then include this header file.
//
// You may also define the following:
//
// SZ_DEBUGINI - the .ini file used to set debug flags
// SZ_DEBUGSECTION - the section in the .ini file specific to
// the module component.
// SZ_MODULE - ansi version of the name of your module.
//
//
#ifndef DATASEG_READONLY
#define DATASEG_READONLY ".text" // read only data, same as one generated by linker
#endif
#pragma data_seg(DATASEG_READONLY)
TCHAR const FAR c_szCcshellIniFile[] = SZ_DEBUGINI;
TCHAR const FAR c_szCcshellIniSecDebug[] = SZ_DEBUGSECTION;
#ifdef UNICODE
WCHAR const FAR c_wszTrace[] = TEXT("t ") TEXT(SZ_MODULE) TEXT(" ");
#else
WCHAR const FAR c_wszTrace[] = L"";
#endif // UNICODE
// (This is deliberately CHAR)
CHAR const FAR c_szTrace[] = "t " SZ_MODULE " ";
TCHAR const FAR c_szAssertFailed[] = TEXT(SZ_MODULE) TEXT(" Assert %s, line %d\r\n");
#pragma data_seg()
#endif // DECLARE_DEBUG && DEBUG
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(DECLARE_DEBUG)
//
// Debug macros and validation code
//
#undef Assert
#undef AssertE
#undef AssertMsg
#undef DebugMsg
#undef FullDebugMsg
#undef ASSERT
#undef EVAL
extern DWORD g_dwDumpFlags;
extern DWORD g_dwBreakFlags;
extern DWORD g_dwTraceFlags;
extern DWORD g_dwPrototype;
extern DWORD g_dwFuncTraceFlags;
// (There are no reserved bits for g_dwPrototype. It is for use
// by the component.)
// Break flags
#define BF_ONVALIDATE 0x00000001 // Break on assertions or validation
#define BF_ONOPEN 0x00000002
#define BF_ONCLOSE 0x00000004
#define BF_ONRUNONCE 0x00000008
#define BF_ONTHREADATT 0x00000010
#define BF_ONTHREADDET 0x00000020
#define BF_ONPROCESSATT 0x00000040
#define BF_ONPROCESSDET 0x00000080
#define BF_ONAPIENTER 0x00000100 // Break on entering an API
// Trace flags
#define TF_ALWAYS 0xFFFFFFFF
#define TF_NEVER 0x00000000
#define TF_WARNING 0x00000001
#define TF_ERROR 0x00000002
#define TF_GENERAL 0x00000004 // Standard messages
#define TF_FUNC 0x00000008 // Trace function calls
// (Upper 28 bits reserved for custom use per-module)
// Function trace flags (FTF_) are per-component
// Debug mask APIs
// BUGBUG (scotth): the following flags will be phased out over time.
#ifdef DM_TRACE
#undef DM_TRACE
#undef DM_WARNING
#undef DM_ERROR
#endif
#define DM_TRACE TF_GENERAL // OBSOLETE Trace messages
#define DM_WARNING TF_WARNING // OBSOLETE Warning
#define DM_ERROR TF_ERROR // OBSOLETE Error
// NOTE: Default debug mask is 0x00ff (show everything)
//
// Inside debugger, you can modify wDebugMask variable.
//
// Set debug mask; returning previous.
//
UINT WINAPI SetDebugMask(UINT mask);
// Get debug mask.
//
UINT WINAPI GetDebugMask();
#ifndef WIN32
#if (defined(BUILDDLL) && !defined(ASSERTSEG))
#define ASSERTSEG _based(_segname("_ERRTEXT"))
#endif
#ifndef ASSERTSEG
#define ASSERTSEG _based(_segname("_CODE"))
#endif
#else
#define ASSERTSEG
#endif
// Use this macro to declare message text that will be placed
// in the CODE segment (useful if DS is getting full)
//
// Ex: DEBUGTEXT(szMsg, "Invalid whatever: %d");
//
#define DEBUGTEXT(sz, msg) /* ;Internal */ \
static const TCHAR ASSERTSEG sz[] = msg;
#ifndef NOSHELLDEBUG // Others have own versions of these.
#ifdef DEBUG
// Assert(f) -- Generate "assertion failed in line x of file.c"
// message if f is NOT true.
//
// AssertMsg(f, msg, args...) -- Generate wsprintf-formatted msg w/params
// if f is NOT true.
//
// DebugMsg(mask, msg, args...) -
// Generate wsprintf-formatted msg using
// specified debug mask. System debug mask
// governs whether message is output.
//
void CcshellAssertFailed(LPCTSTR szFile, int line);
#define Assert(f) \
{ \
DEBUGTEXT(szFile, TEXT(__FILE__)); \
if (!(f)) \
CcshellAssertFailed(szFile, __LINE__); \
}
#define AssertE(f) Assert(f)
#define ASSERT(f) Assert(f)
void __cdecl _AssertMsg(BOOL f, LPCTSTR pszMsg, ...);
#define AssertMsg _AssertMsg
void __cdecl _DebugMsg(DWORD flag, LPCTSTR psz, ...);
#define DebugMsg _DebugMsg
#ifdef FULL_DEBUG
#define FullDebugMsg _DebugMsg
#else
#define FullDebugMsg 1 ? (void)0 : (void)
#endif
/*
* EVAL() may only be used as a logical expression.
*
* E.g.,
*
* if (EVAL(exp))
* bResult = TRUE;
*/
#define EVAL(exp) ((exp) || (TraceMsg(TF_ERROR, "evaluation failed '%s'", (LPCTSTR)#exp), 0))
#define Dbg_SafeStrA(psz) (SAFECAST(psz, LPCSTR), (psz) ? (psz) : "NULL string")
#define Dbg_SafeStrW(psz) (SAFECAST(psz, LPCWSTR), (psz) ? (psz) : L"NULL string")
#ifdef UNICODE
#define Dbg_SafeStr Dbg_SafeStrW
#else
#define Dbg_SafeStr Dbg_SafeStrA
#endif
void CcshellStackEnter(void);
void CcshellStackLeave(void);
void
CDECL
CcshellDebugMsgW(
DWORD mask,
LPCSTR pszMsg, ...);
void
CDECL
CcshellDebugMsgA(
DWORD mask,
LPCSTR pszMsg, ...);
#ifdef UNICODE
#define CcshellDebugMsg CcshellDebugMsgW
#else
#define CcshellDebugMsg CcshellDebugMsgA
#endif // UNICODE
void
CDECL
CcshellFuncMsgW(
DWORD mask,
LPCSTR pszMsg, ...);
void
CDECL
CcshellFuncMsgA(
DWORD mask,
LPCSTR pszMsg, ...);
#ifdef UNICODE
#define CcshellFuncMsg CcshellFuncMsgW
#else
#define CcshellFuncMsg CcshellFuncMsgA
#endif // UNICODE
void
CDECL
CcshellAssertMsgW(
BOOL bAssert,
LPCSTR pszMsg, ...);
void
CDECL
CcshellAssertMsgA(
BOOL bAssert,
LPCSTR pszMsg, ...);
#ifdef UNICODE
#define CcshellAssertMsg CcshellAssertMsgW
#else
#define CcshellAssertMsg CcshellAssertMsgA
#endif // UNICODE
// ASSERT_MSG(bAssert, msg, args...) - Generate wsprintf-formatted msg
// if the assertion is false. System trace mask
// governs whether message is output, and
// whether the function DebugBreaks.
//
#define ASSERT_MSGW CcshellAssertMsgW
#define ASSERT_MSGA CcshellAssertMsgA
#define ASSERT_MSG CcshellAssertMsg
// TraceMsg(mask, msg, args...) - Generate wsprintf-formatted msg using
// specified trace mask. System trace mask
// governs whether message is output.
//
// (The difference b/t TraceMsg and DebugMsg is only one thing:
// TraceMsg does not require you to wrap msg with TEXT() for
// the unicode platform. It is always LPSTR, and properly
// converts.)
#define TRACE_MSGW CcshellDebugMsgW
#define TRACE_MSGA CcshellDebugMsgA
#define TRACE_MSG CcshellDebugMsg
#define TraceMsgW TRACE_MSGW
#define TraceMsgA TRACE_MSGA
#define TraceMsg TRACE_MSG
#define FUNC_MSG CcshellFuncMsg
// Debug function enter
// DBG_ENTER(flag, fn) -- Generates a function entry debug spew for
// a function
//
#define DBG_ENTER(flagFTF, fn) \
(FUNC_MSG(flagFTF, " > " #fn "()"), \
CcshellStackEnter())
// DBG_ENTER_TYPE(flag, fn, dw, pfnStrFromType) -- Generates a function entry debug
// spew for functions that accept <type>.
//
#define DBG_ENTER_TYPE(flagFTF, fn, dw, pfnStrFromType) \
(FUNC_MSG(flagFTF, " < " #fn "(..., %s, ...)", (LPCTSTR)pfnStrFromType(dw)), \
CcshellStackEnter())
// DBG_ENTER_SZ(flag, fn, sz) -- Generates a function entry debug spew for
// a function that accepts a string as one of its
// parameters.
//
#define DBG_ENTER_SZ(flagFTF, fn, sz) \
(FUNC_MSG(flagFTF, " > " #fn "(..., \"%s\",...)", Dbg_SafeStr(sz)), \
CcshellStackEnter())
// Debug function exit
// DBG_EXIT(flag, fn) -- Generates a function exit debug spew
//
#define DBG_EXIT(flagFTF, fn) \
(CcshellStackLeave(), \
FUNC_MSG(flagFTF, " < " #fn "()"))
// DBG_EXIT_TYPE(flag, fn, dw, pfnStrFromType) -- Generates a function exit debug
// spew for functions that return <type>.
//
#define DBG_EXIT_TYPE(flagFTF, fn, dw, pfnStrFromType) \
(CcshellStackLeave(), \
FUNC_MSG(flagFTF, " < " #fn "() with %s", (LPCTSTR)pfnStrFromType(dw)))
// DBG_EXIT_INT(flag, fn, us) -- Generates a function exit debug spew for
// functions that return an INT.
//
#define DBG_EXIT_INT(flagFTF, fn, n) \
(CcshellStackLeave(), \
FUNC_MSG(flagFTF, " < " #fn "() with %d", (int)(n)))
// DBG_EXIT_BOOL(flag, fn, b) -- Generates a function exit debug spew for
// functions that return a boolean.
//
#define DBG_EXIT_BOOL(flagFTF, fn, b) \
(CcshellStackLeave(), \
FUNC_MSG(flagFTF, " < " #fn "() with %s", (b) ? (LPTSTR)TEXT("TRUE") : (LPTSTR)TEXT("FALSE")))
// DBG_EXIT_UL(flag, fn, ul) -- Generates a function exit debug spew for
// functions that return a ULONG.
//
#define DBG_EXIT_UL(flagFTF, fn, ul) \
(CcshellStackLeave(), \
FUNC_MSG(flagFTF, " < " #fn "() with %#08lx", (ULONG)(ul)))
#define DBG_EXIT_DWORD DBG_EXIT_UL
// DBG_EXIT_HRES(flag, fn, hres) -- Generates a function exit debug spew for
// functions that return an HRESULT.
//
#define DBG_EXIT_HRES(flagFTF, fn, hres) DBG_EXIT_TYPE(flagFTF, fn, hres, Dbg_GetHRESULTName)
#else // DEBUG
#define Assert(f)
#define AssertE(f) (f)
#define ASSERT(f)
#define AssertMsg 1 ? (void)0 : (void)
#define DebugMsg 1 ? (void)0 : (void)
#define FullDebugMsg 1 ? (void)0 : (void)
#define EVAL(exp) ((exp) != 0)
#define Dbg_SafeStr 1 ? (void)0 : (void)
#define TRACE_MSGA 1 ? (void)0 : (void)
#define TRACE_MSGW 1 ? (void)0 : (void)
#ifdef UNICODE
#define TRACE_MSG TRACE_MSGW
#else
#define TRACE_MSG TRACE_MSGA
#endif
#define TraceMsgW TRACE_MSGW
#define TraceMsgA TRACE_MSGA
#define TraceMsg TRACE_MSG
#define FUNC_MSG 1 ? (void)0 : (void)
#define ASSERT_MSGA TRACE_MSGA
#define ASSERT_MSGW TRACE_MSGW
#define ASSERT_MSG TRACE_MSG
#define DBG_ENTER(flagFTF, fn)
#define DBG_ENTER_TYPE(flagFTF, fn, dw, pfn)
#define DBG_ENTER_SZ(flagFTF, fn, sz)
#define DBG_EXIT(flagFTF, fn)
#define DBG_EXIT_INT(flagFTF, fn, n)
#define DBG_EXIT_BOOL(flagFTF, fn, b)
#define DBG_EXIT_UL(flagFTF, fn, ul)
#define DBG_EXIT_DWORD DBG_EXIT_UL
#define DBG_EXIT_TYPE(flagFTF, fn, dw, pfn)
#define DBG_EXIT_HRES(flagFTF, fn, hres)
#endif // DEBUG
/* parameter validation macros */
/*
* call as:
*
* bOK = IS_VALID_READ_PTR(pfoo, CFOO);
*
* bOK = IS_VALID_HANDLE(hfoo, FOO);
*/
#ifdef DEBUG
#define IS_VALID_READ_PTR(ptr, type) \
(IsBadReadPtr((ptr), sizeof(type)) ? \
(ASSERT_MSG(FALSE, "invalid %s read pointer - %#08lx", (LPCTSTR)"P"#type, (ptr)), FALSE) : \
TRUE)
#define IS_VALID_WRITE_PTR(ptr, type) \
(IsBadWritePtr((PVOID)(ptr), sizeof(type)) ? \
(ASSERT_MSG(FALSE, "invalid %s write pointer - %#08lx", (LPCTSTR)"P"#type, (ptr)), FALSE) : \
TRUE)
#define IS_VALID_STRING_PTRA(ptr, type) \
(IsBadStringPtrA((ptr), (UINT)-1) ? \
(ASSERT_MSG(FALSE, "invalid %s pointer - %#08lx", (LPCTSTR)"P"#type, (ptr)), FALSE) : \
TRUE)
#define IS_VALID_STRING_PTRW(ptr, type) \
(IsBadStringPtrW((ptr), (UINT)-1) ? \
(ASSERT_MSG(FALSE, "invalid %s pointer - %#08lx", (LPCTSTR)"P"#type, (ptr)), FALSE) : \
TRUE)
#define IS_VALID_CODE_PTR(ptr, type) \
(IsBadCodePtr((FARPROC)(ptr)) ? \
(ASSERT_MSG(FALSE, "invalid %s code pointer - %#08lx", (LPCTSTR)#type, (ptr)), FALSE) : \
TRUE)
#define IS_VALID_READ_BUFFER_PTR(ptr, type, len) \
(IsBadReadPtr((ptr), len) ? \
(ASSERT_MSG(FALSE, "invalid %s read pointer - %#08lx", (LPCTSTR)"P"#type, (ptr)), FALSE) : \
TRUE)
#define IS_VALID_WRITE_BUFFER_PTR(ptr, type, len) \
(IsBadWritePtr((ptr), len) ? \
(ASSERT_MSG(FALSE, "invalid %s write pointer - %#08lx", (LPCTSTR)"P"#type, (ptr)), FALSE) : \
TRUE)
#define FLAGS_ARE_VALID(dwFlags, dwAllFlags) \
(((dwFlags) & (~(dwAllFlags))) ? \
(ASSERT_MSG(FALSE, "invalid flags set - %#08lx", ((dwFlags) & (~(dwAllFlags)))), FALSE) : \
TRUE)
#else
#define IS_VALID_READ_PTR(ptr, type) \
(! IsBadReadPtr((ptr), sizeof(type)))
#define IS_VALID_WRITE_PTR(ptr, type) \
(! IsBadWritePtr((PVOID)(ptr), sizeof(type)))
#define IS_VALID_STRING_PTRA(ptr, type) \
(! IsBadStringPtrA((ptr), (UINT)-1))
#define IS_VALID_STRING_PTRW(ptr, type) \
(! IsBadStringPtrW((ptr), (UINT)-1))
#define IS_VALID_CODE_PTR(ptr, type) \
(! IsBadCodePtr((FARPROC)(ptr)))
#define IS_VALID_READ_BUFFER_PTR(ptr, type, len) \
(! IsBadReadPtr((ptr), len))
#define IS_VALID_WRITE_BUFFER_PTR(ptr, type, len) \
(! IsBadWritePtr((ptr), len))
#define FLAGS_ARE_VALID(dwFlags, dwAllFlags) \
(((dwFlags) & (~(dwAllFlags))) ? FALSE : TRUE)
#endif
#ifdef UNICODE
#define IS_VALID_STRING_PTR IS_VALID_STRING_PTRW
#else
#define IS_VALID_STRING_PTR IS_VALID_STRING_PTRA
#endif
/* handle validation macros */
#ifdef DEBUG
#define IS_VALID_HANDLE(hnd, type) \
(IsValidH##type(hnd) ? \
TRUE : \
(ASSERT_MSG(FALSE, "invalid H" #type " - %#08lx", (hnd)), FALSE))
#else
#define IS_VALID_HANDLE(hnd, type) \
(IsValidH##type(hnd))
#endif
/* structure validation macros */
// Define VSTF if you want to validate the fields in structures. This
// requires a handler function (of the form IsValid*()) that knows how
// to validate the specific structure type.
#ifdef VSTF
#ifdef DEBUG
#define IS_VALID_STRUCT_PTR(ptr, type) \
(IsValidP##type(ptr) ? \
TRUE : \
(ASSERT_MSG(FALSE, "invalid %s pointer - %#08lx", (LPCTSTR)"P"#type, (ptr)), FALSE))
#else
#define IS_VALID_STRUCT_PTR(ptr, type) \
(IsValidP##type(ptr))
#endif
#else
#define IS_VALID_STRUCT_PTR(ptr, type) \
(! IsBadReadPtr((ptr), sizeof(type)))
#endif
/* OLE interface validation macro */
#define IS_VALID_INTERFACE_PTR(ptr, iface) \
IS_VALID_STRUCT_PTR(ptr, ##iface)
#endif // NOSHELLDEBUG
#ifdef DEBUG
BOOL
CcshellGetDebugFlags(void);
#if !defined(NO_SHELL_VALIDATION)
BOOL
IsValidPath(
LPCTSTR pcszPath);
BOOL
IsValidPathResult(
HRESULT hr,
LPCTSTR pcszPath,
UINT cchPathBufLen);
BOOL
IsValidExtension(
LPCTSTR pcszExt);
BOOL
IsValidIconIndex(
HRESULT hr,
LPCTSTR pcszIconFile,
UINT cchIconFileBufLen,
int niIcon);
BOOL
IsValidHANDLE(
HANDLE hnd);
#define IsValidHEVENT IsValidHANDLE
#define IsValidHGLOBAL IsValidHANDLE
#define IsValidHFILE IsValidHANDLE
#define IsValidHMENU IsValidHANDLE
#define IsValidHINSTANCE IsValidHANDLE
#define IsValidHICON IsValidHANDLE
#define IsValidHKEY IsValidHANDLE
#define IsValidHMODULE IsValidHANDLE
#define IsValidHPROCESS IsValidHANDLE
BOOL
IsValidHWND(
HWND hwnd);
BOOL
IsValidShowCmd(
int nShow);
BOOL
IsFullPath(
LPCTSTR pcszPath);
#endif // NO_SHELL_VALIDATION
#endif // DEBUG
#endif // DECLARE_DEBUG
#ifdef __cplusplus
};
#endif