|
|
#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
|