windows-nt/Source/XPSP1/NT/base/mvdm/wow16/kernel31/error.c
2020-09-26 16:20:57 +08:00

441 lines
12 KiB
C

#include "kernel.h"
#define WINAPI _far _pascal _loadds
typedef unsigned int UINT;
typedef const char _far* LPCSTR;
typedef HANDLE HTASK;
#include "logerror.h"
int WINAPI FatalExitC(WORD);
void WINAPI OutputDebugString(LPCSTR);
void DebugLogParamError(VOID FAR* param, FARPROC lpfn, WORD err);
void DebugLogError(WORD err, VOID FAR* lpInfo);
int WINAPI GetOwnerName(WORD sel, char far *buf, WORD buflen);
int WINAPI FarGetOwner(WORD sel);
#define CODESEG _based(_segname("_CODE"))
#define SELECTOROF(lp) HIWORD(lp)
#define OFFSETOF(lp) LOWORD((DWORD)lp)
#define MAKELONG(a, b) ((LONG)(((WORD)(a)) | ((DWORD)((WORD)(b))) << 16))
#define MAKELP(sel, off) ((VOID FAR *)MAKELONG(off, sel))
#if KDEBUG
UINT DebugOptions = 0;
UINT DebugFilter = 0;
#define FMT_WORD 0
#define FMT_DWORD 1
#define FMT_LP 2
struct TYPEMAP
{
UINT err;
char CODESEG* szType; // Compiler bug: this can't be _based
char CODESEG* szFmt;
};
static char CODESEG szParam[] = "parameter";
static char CODESEG szD16[] = "%s: Invalid %s: %d\r\n";
static char CODESEG szD32[] = "%s: Invalid %s: %ld\r\n";
static char CODESEG szX16[] = "%s: Invalid %s: %#04x\r\n";
static char CODESEG szX32[] = "%s: Invalid %s: %#08lx\r\n";
static char CODESEG szLP[] = "%s: Invalid %s: %#04x:%#04x\r\n";
static char CODESEG sz_value[] = "value";
static char CODESEG sz_index[] = "index";
static char CODESEG sz_flags[] = "flags";
static char CODESEG sz_selector[] = "selector";
static char CODESEG sz_pointer[] = "pointer";
static char CODESEG sz_function_pointer [] = "function pointer";
static char CODESEG sz_string_pointer [] = "string pointer";
static char CODESEG sz_HINSTANCE[] = "HINSTANCE";
static char CODESEG sz_HMODULE[] = "HMODULE";
static char CODESEG sz_global_handle [] = "global handle";
static char CODESEG sz_local_handle [] = "local handle";
static char CODESEG sz_atom[] = "atom";
static char CODESEG sz_HWND[] = "HWND";
static char CODESEG sz_HMENU[] = "HMENU";
static char CODESEG sz_HCURSOR[] = "HCURSOR";
static char CODESEG sz_HICON[] = "HICON";
static char CODESEG sz_HGDIOBJ[] = "HGDIOBJ";
static char CODESEG sz_HDC[] = "HDC";
static char CODESEG sz_HPEN[] = "HPEN";
static char CODESEG sz_HFONT[] = "HFONT";
static char CODESEG sz_HBRUSH[] = "HBRUSH";
static char CODESEG sz_HBITMAP[] = "HBITMAP";
static char CODESEG sz_HRGN[] = "HRGN";
static char CODESEG sz_HPALETTE[] = "HPALETTE";
static char CODESEG sz_HANDLE[] = "HANDLE";
static char CODESEG sz_HFILE[] = "HFILE";
static char CODESEG sz_HMETAFILE[] = "HMETAFILE";
static char CODESEG sz_CID[] = "CID";
static char CODESEG sz_HDRVR[] = "HDRVR";
static char CODESEG sz_HDWP[] = "HDWP";
static char CODESEG*pszLP = szLP;
static char CODESEG*pszD32 = szD32;
static char CODESEG*pszX32 = szX32;
#define DEFMAP(err, type, fmt) \
{ err, type, fmt }
struct TYPEMAP CODESEG typemap[] =
{
DEFMAP(ERR_BAD_VALUE, sz_value, szD16),
DEFMAP(ERR_BAD_INDEX, sz_index, szD16),
DEFMAP(ERR_BAD_FLAGS, sz_flags, szX16),
DEFMAP(ERR_BAD_SELECTOR, sz_selector, szX16),
DEFMAP(ERR_BAD_DFLAGS, sz_flags, szX32),
DEFMAP(ERR_BAD_DVALUE, sz_value, szD32),
DEFMAP(ERR_BAD_DINDEX, sz_index, szD32),
DEFMAP(ERR_BAD_PTR, sz_pointer, szLP),
DEFMAP(ERR_BAD_FUNC_PTR, sz_function_pointer, szLP),
DEFMAP(ERR_BAD_STRING_PTR, sz_string_pointer, szLP),
DEFMAP(ERR_BAD_HINSTANCE, sz_HINSTANCE, szX16),
DEFMAP(ERR_BAD_HMODULE, sz_HMODULE, szX16),
DEFMAP(ERR_BAD_GLOBAL_HANDLE,sz_global_handle, szX16),
DEFMAP(ERR_BAD_LOCAL_HANDLE, sz_local_handle, szX16),
DEFMAP(ERR_BAD_ATOM, sz_atom, szX16),
DEFMAP(ERR_BAD_HWND, sz_HWND, szX16),
DEFMAP(ERR_BAD_HMENU, sz_HMENU, szX16),
DEFMAP(ERR_BAD_HCURSOR, sz_HCURSOR, szX16),
DEFMAP(ERR_BAD_HICON, sz_HICON, szX16),
DEFMAP(ERR_BAD_GDI_OBJECT, sz_HGDIOBJ, szX16),
DEFMAP(ERR_BAD_HDC, sz_HDC, szX16),
DEFMAP(ERR_BAD_HPEN, sz_HPEN, szX16),
DEFMAP(ERR_BAD_HFONT, sz_HFONT, szX16),
DEFMAP(ERR_BAD_HBRUSH, sz_HBRUSH, szX16),
DEFMAP(ERR_BAD_HBITMAP, sz_HBITMAP, szX16),
DEFMAP(ERR_BAD_HRGN, sz_HRGN, szX16),
DEFMAP(ERR_BAD_HPALETTE, sz_HPALETTE, szX16),
DEFMAP(ERR_BAD_HANDLE, sz_HANDLE, szX16),
DEFMAP(ERR_BAD_HFILE, sz_HFILE, szX16),
DEFMAP(ERR_BAD_HMETAFILE, sz_HMETAFILE, szX16),
DEFMAP(ERR_BAD_CID, sz_CID, szX16),
DEFMAP(ERR_BAD_HDRVR, sz_HDRVR, szX16),
DEFMAP(ERR_BAD_HDWP, sz_HDWP, szX16)
};
int (_cdecl _far *wsprintf)(LPSTR, LPCSTR, ...) = NULL;
int (WINAPI *wvsprintf)(LPSTR lpszOut, LPCSTR lpszFmt, const void FAR* lpParams) = NULL;
#define ORD_WSPRINTF 420
#define ORD_WVSPRINTF 421
BOOL _fastcall LoadWsprintf(void)
{
static char CODESEG rgchUSER[] = "USER";
HANDLE hmod;
hmod = GetModuleHandle(rgchUSER);
if (!hmod)
return FALSE;
(FARPROC)wsprintf = GetProcAddress(hmod, MAKELP(NULL, ORD_WSPRINTF));
(FARPROC)wvsprintf = GetProcAddress(hmod, MAKELP(NULL, ORD_WVSPRINTF));
if (!SELECTOROF(wsprintf))
{
static char CODESEG rgch[] = "KERNEL: Can't call wsprintf: USER not initialized\r\n";
OutputDebugString(rgch);
return FALSE;
}
return TRUE;
}
typedef struct
{
UINT flags;
LPCSTR lpszFmt;
WORD args[1];
} DOPARAMS;
#define BUFFERSLOP 32
BOOL DebugOutput2(DOPARAMS FAR* pparams)
{
UINT flags = pparams->flags;
BOOL fBreak = FALSE;
BOOL fPrint = TRUE;
char rgch[80*2 + BUFFERSLOP]; // max 2 lines (don't want to hog too much stack space)
static char CODESEG szCRLF[] = "\r\n";
char far *prefix, far *prefix1;
switch (flags & DBF_SEVMASK)
{
case DBF_TRACE:
// If the flags don't match the debug filter,
// don't print the trace message.
// If the trace matches the filter, check for TRACEBREAK.
//
prefix = "t ";
if (!((flags & DBF_FILTERMASK) & DebugFilter))
fPrint = FALSE;
else if (DebugOptions & DBO_TRACEBREAK)
fBreak = TRUE;
break;
case DBF_WARNING:
prefix = "wn ";
if (DebugOptions & DBO_WARNINGBREAK)
fBreak = TRUE;
break;
case DBF_ERROR:
prefix = "err ";
if (!(DebugOptions & DBO_NOERRORBREAK))
fBreak = TRUE;
break;
case DBF_FATAL:
prefix = "fatl ";
if (!(DebugOptions & DBO_NOFATALBREAK))
fBreak = TRUE;
break;
}
// If DBO_SILENT is specified, don't print anything.
//
if (DebugOptions & DBO_SILENT)
fPrint = FALSE;
if ((lstrlen((LPSTR)pparams->lpszFmt) <= sizeof(rgch) - BUFFERSLOP) &&
(SELECTOROF(wsprintf) || LoadWsprintf()) && (fPrint || fBreak))
{
int hinst = HIWORD(pparams);
for (prefix1 = rgch; *prefix; ) *prefix1++ = *prefix++;
prefix1 += GetOwnerName(hinst, prefix1, 16);
*prefix1++ = ' ';
wvsprintf(prefix1, pparams->lpszFmt, (void FAR*)pparams->args);
OutputDebugString(rgch);
OutputDebugString(szCRLF);
}
if (fBreak)
{
// If we are supposed to break with an int 3, then return TRUE.
//
if (DebugOptions & DBO_INT3BREAK)
return TRUE;
return FatalExitC(flags);
}
return FALSE;
}
BOOL LogParamError2(WORD err, FARPROC lpfn, VOID FAR* param, WORD caller)
{
BOOL fBreak;
fBreak = FALSE;
if (err & ERR_WARNING)
{
if (DebugOptions & DBO_WARNINGBREAK)
fBreak = TRUE;
}
else
{
if (!(DebugOptions & DBO_NOERRORBREAK))
fBreak = TRUE;
}
// If we're not breaking and SILENT is specified, just return.
//
if (!fBreak && (DebugOptions & DBO_SILENT))
return FALSE;
if (SELECTOROF(wsprintf) || LoadWsprintf())
{
char rgch[128];
char rgchProcName[50], far *rpn;
char CODESEG* pszType; // compiler bug: see above
char CODESEG* pszFmt;
int i, hinst;
WORD errT;
void FAR GetProcName(FARPROC lpfn, LPSTR lpch, int cch);
char far *prefix1;
GetProcName(lpfn, rgchProcName, sizeof(rgchProcName));
/* if we got a real proc name, then copy just the proc name */
for (rpn = rgchProcName; *rpn && (*rpn != '(') && (*rpn != ':'); rpn++)
;
if (*rpn == ':') {
lstrcpy(rgchProcName, rpn+1);
}
pszFmt = szX32;
pszType = szParam;
errT = (err & ~ERR_WARNING);
for (i = 0; i < (sizeof(typemap) / sizeof(struct TYPEMAP)); i++)
{
if (typemap[i].err == errT)
{
pszFmt = typemap[i].szFmt;
pszType = typemap[i].szType;
break;
}
}
if (err & ERR_WARNING) {
lstrcpy(rgch, "wn ");
prefix1 = rgch+3;
} else {
lstrcpy(rgch, "err ");
prefix1 = rgch+4;
}
hinst = HIWORD(prefix1);
prefix1 += GetOwnerName(hinst, prefix1, 16);
if (FarGetOwner(hinst) != FarGetOwner(caller)) {
*prefix1++ = '-';
*prefix1++ = '>';
prefix1 += GetOwnerName(caller, prefix1, 16);
}
*prefix1++ = ' ';
if (pszFmt == pszLP)
wsprintf(prefix1, pszFmt, (LPSTR)rgchProcName, (LPSTR)pszType, SELECTOROF(param), OFFSETOF(param));
else if (pszFmt == pszD32 || pszFmt == pszX32)
wsprintf(prefix1, pszFmt, (LPSTR)rgchProcName, (LPSTR)pszType, (DWORD)param);
else
wsprintf(prefix1, pszFmt, (LPSTR)rgchProcName, (LPSTR)pszType, (WORD)(DWORD)param);
OutputDebugString(rgch);
}
if (fBreak)
{
// If we are supposed to break with an int 3, then return TRUE.
//
if (DebugOptions & DBO_INT3BREAK)
return TRUE;
return FatalExitC(err);
}
return FALSE;
}
extern HTASK allocTask;
extern DWORD allocCount;
extern DWORD allocBreak;
extern char allocModName[8];
void FAR _loadds SetupAllocBreak(HTASK htask);
char far* GetTaskModNamePtr(HTASK htask);
BOOL WINAPI IGetWinDebugInfo(WINDEBUGINFO FAR* lpwdi, UINT flags)
{
int i;
lpwdi->flags = flags;
if (flags & WDI_OPTIONS)
lpwdi->dwOptions = DebugOptions;
if (flags & WDI_FILTER)
lpwdi->dwFilter = DebugFilter;
if (flags & WDI_ALLOCBREAK)
{
lpwdi->dwAllocBreak = allocBreak;
lpwdi->dwAllocCount = allocCount;
for (i = 0; i < 8; i++)
lpwdi->achAllocModule[i] = allocModName[i];
}
return TRUE;
}
BOOL WINAPI ISetWinDebugInfo(const WINDEBUGINFO FAR* lpwdi)
{
int i;
if (lpwdi->flags & WDI_OPTIONS)
DebugOptions = (UINT)lpwdi->dwOptions;
if (lpwdi->flags & WDI_FILTER)
DebugFilter = (UINT)lpwdi->dwFilter;
if (lpwdi->flags & WDI_ALLOCBREAK)
{
allocTask = NULL;
allocBreak = lpwdi->dwAllocBreak;
allocCount = 0; // Always reset count to 0.
for (i = 0; i < 8; i++)
allocModName[i] = lpwdi->achAllocModule[i];
{
extern HTASK headTDB;
HTASK htask;
// Enumerate all current tasks to see if any match
//
#define TDB_next 0
for (htask = headTDB; htask; htask = *((HTASK FAR*)MAKELP(htask, TDB_next)))
SetupAllocBreak(htask);
}
}
return TRUE;
}
void FAR _loadds SetupAllocBreak(HTASK htask)
{
int i;
char far* pchAlloc;
char far* pchTask;
// If alloc break task already set up, exit.
//
if (allocTask)
return;
// If no alloc break in effect, nothing to do.
//
if (allocModName[0] == 0)
return;
pchAlloc = allocModName;
pchTask = GetTaskModNamePtr(htask);
for (i = 8; --i != 0; pchAlloc++, pchTask++)
{
char ch1 = *pchAlloc;
char ch2 = *pchTask;
if (ch1 >= 'a' && ch1 <= 'z')
ch1 -= ('a' - 'A');
if (ch2 >= 'a' && ch2 <= 'z')
ch2 -= ('a' - 'A');
if (ch1 != ch2)
return;
if (ch1 == 0 || ch2 == 0)
break;
}
// Set the alloc break task, and init the count to 0.
//
allocTask = htask;
allocCount = 0;
}
#else // !KDEBUG
BOOL WINAPI GetWinDebugInfo(WINDEBUGINFO FAR* lpwdi, UINT flags)
{
return FALSE;
}
BOOL WINAPI SetWinDebugInfo(const WINDEBUGINFO FAR* lpwdi)
{
return FALSE;
}
#endif // !KDEBUG