890 lines
22 KiB
C
890 lines
22 KiB
C
/****************************************************************************
|
|
|
|
INTEL CORPORATION PROPRIETARY INFORMATION
|
|
Copyright (c) 1992 Intel Corporation
|
|
All Rights Reserved
|
|
|
|
This software is supplied under the terms of a license
|
|
agreement or non-disclosure agreement with Intel Corporation
|
|
and may not be copied or disclosed except in accordance
|
|
with the terms of that agreement
|
|
|
|
$Source: q:/prism/network/isrdbg/rcs/isrdbg.c $
|
|
$Revision: 1.3 $
|
|
$Date: 30 Dec 1996 16:44:32 $
|
|
$Author: EHOWARDX $
|
|
$Locker: $
|
|
|
|
Description
|
|
-----------
|
|
VCITest - test harness for VCI and underlaying subsystems.
|
|
|
|
****************************************************************************/
|
|
|
|
// Turn off Windows stuff will never use.
|
|
#define NOSOUND
|
|
#define NOSYSMETRICS
|
|
#define NOTEXTMETRIC
|
|
#define NOWH
|
|
#define NOCOMM
|
|
#define NOKANJI
|
|
|
|
#ifndef STRICT
|
|
#define STRICT
|
|
#endif // not defined STRICT
|
|
|
|
#include <windows.h>
|
|
|
|
#include <string.h>
|
|
|
|
#define ISRDBG32_C
|
|
#include <isrg.h> // exports to functions.
|
|
|
|
#include "isrdbg32.h" // private header file for this app
|
|
|
|
|
|
|
|
HINSTANCE ghAppInstance = 0; // global instance handle
|
|
|
|
// Global lock to protect:
|
|
// gStrTabOfs, guNumItems
|
|
HANDLE gSemaphore = 0; // global semaphore for accessing dbg info.
|
|
|
|
|
|
|
|
// Most data needs to be globally mapped because info is shared with viewer and apps
|
|
// placing debug info into the buffers.
|
|
typedef struct _tDS
|
|
{
|
|
UINT uBindCount; // How many copies of this DLL have run.
|
|
UINT guNumModules;
|
|
UINT guNumItems;
|
|
UINT gStrTabOfs;
|
|
WORD ghDefaultModule;
|
|
} tDS,*ptDS;
|
|
|
|
HANDLE ghDS = 0;
|
|
ptDS gpDS = NULL;
|
|
|
|
HANDLE ghModuleTable = 0;
|
|
ptISRModule gpModuleTable = NULL;
|
|
|
|
HANDLE ghDbgTable = 0;
|
|
ptISRItem gpDbgTable = NULL;
|
|
|
|
HANDLE ghzStrTab = 0;
|
|
LPSTR gpzStrTab = NULL;
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
ptISRItem WINAPI
|
|
ISR_GetItemInternal (UINT uItem);
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
BOOL MapGlobalWin32Memory(void** pMem,HANDLE* hMem,UINT MemSize,char* MemName)
|
|
{
|
|
BOOL fInit;
|
|
|
|
|
|
if (!pMem || !hMem)
|
|
return FALSE;
|
|
|
|
*hMem = CreateFileMapping(
|
|
INVALID_HANDLE_VALUE, // use paging file
|
|
NULL, // no security attr.
|
|
PAGE_READWRITE, // read/write access
|
|
0, // size: high 32-bits
|
|
MemSize, // size: low 32-bits
|
|
MemName); // name of map object
|
|
if (!*hMem)
|
|
return FALSE;
|
|
|
|
// The first process to attach initializes memory.
|
|
fInit = (GetLastError() != ERROR_ALREADY_EXISTS);
|
|
|
|
// Get a pointer to the file-mapped shared memory.
|
|
*pMem = MapViewOfFile(
|
|
*hMem, // object to map view of
|
|
FILE_MAP_WRITE, // read/write access
|
|
0, // high offset: map from
|
|
0, // low offset: beginning
|
|
0); // default: map entire file
|
|
if (!*pMem)
|
|
{
|
|
CloseHandle(*hMem);
|
|
*hMem = 0;
|
|
return FALSE;
|
|
}
|
|
|
|
// Initialize memory if this is the first process.
|
|
if (fInit)
|
|
{
|
|
memset(*pMem,0,MemSize);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
void FreeGlobalWin32Memory(void* pMem,HANDLE hMem)
|
|
{
|
|
// Unmap shared memory from the process's address space.
|
|
if (pMem)
|
|
UnmapViewOfFile(pMem);
|
|
|
|
// Close the process's handle to the file-mapping object.
|
|
if (hMem)
|
|
CloseHandle(hMem);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// InitModules
|
|
// Init the Module filters on startup.
|
|
// Do not init the filters when the module is registered.
|
|
// The display app may have some global filters in effect by the time
|
|
// the individual register module calls come in.
|
|
//------------------------------------------------------------------------------
|
|
static void
|
|
InitModules (void)
|
|
{
|
|
UINT hMod;
|
|
ptISRModule pMod;
|
|
|
|
|
|
for (hMod = 0; hMod < kMaxModules; hMod++)
|
|
{
|
|
pMod = ISR_GetModule(hMod);
|
|
if (!pMod)
|
|
break;
|
|
|
|
pMod->DisplayFilter = 0xFF;
|
|
pMod->CaptureFilter = 0xFF;
|
|
}
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// ValidCaptureMsg
|
|
// Validate the capture filters to determine if this message should be
|
|
// dropped.
|
|
//
|
|
// Returns:
|
|
// TRUE - if msg is valid and should be kept
|
|
// FALSE - if msg is filtered out and should be dropped.
|
|
//------------------------------------------------------------------------------
|
|
static UINT
|
|
ValidCaptureMsg (WORD hISRInst, BYTE DbgLevel)
|
|
{
|
|
ptISRModule pMod;
|
|
|
|
|
|
pMod = ISR_GetModule(hISRInst);
|
|
if (!pMod)
|
|
return FALSE;
|
|
|
|
if (DbgLevel & pMod->CaptureFilter)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// OutputRec ()
|
|
// Store a string resource Id to be displayed at task time.
|
|
// In addition store a number to be displayed in printf format of the
|
|
// string.
|
|
//------------------------------------------------------------------------------
|
|
ISR_DLL void WINAPI
|
|
OutputRec
|
|
(
|
|
WORD hISRInst, // Our handle to registered modules
|
|
BYTE DbgLevel, // Caller determined debug level
|
|
BYTE Flags,
|
|
UINT IP, // Callers Instruction Ptr address
|
|
DWORD Param1,
|
|
DWORD Param2
|
|
)
|
|
{
|
|
ptISRItem pItem;
|
|
UINT uItem;
|
|
|
|
|
|
// Capture Filter
|
|
if ( !ValidCaptureMsg(hISRInst, DbgLevel) )
|
|
return;
|
|
|
|
// Protect against reentrancy. Just drop the msg if reentered.
|
|
if (WAIT_OBJECT_0 != WaitForSingleObject(gSemaphore,100))
|
|
return;
|
|
|
|
uItem = gpDS->guNumItems++;
|
|
if (kMaxISRItems <= gpDS->guNumItems)
|
|
{
|
|
gpDS->guNumItems = 0;
|
|
}
|
|
ReleaseSemaphore(gSemaphore,1,NULL);
|
|
|
|
pItem = ISR_GetItemInternal(uItem);
|
|
if (!pItem)
|
|
{
|
|
// This is a serious bug. Our debugger is even hosed.
|
|
// Need to think of a way to indicate this to the user.
|
|
return;
|
|
}
|
|
|
|
pItem->hISRInst = hISRInst;
|
|
pItem->DbgLevel = DbgLevel;
|
|
pItem->Flags = Flags;
|
|
pItem->IP = IP;
|
|
pItem->Param1 = Param1;
|
|
pItem->Param2 = Param2;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
//------------------------------------------------------------------------------
|
|
ISR_DLL void WINAPI
|
|
OutputRecStr
|
|
(
|
|
WORD hISRInst, // Our handle to registered modules
|
|
BYTE DbgLevel, // Caller determined debug level
|
|
BYTE Flags,
|
|
UINT IP, // Callers Instruction Ptr address
|
|
LPSTR pzStr1,
|
|
LPSTR pzStr2,
|
|
DWORD Param1
|
|
)
|
|
{
|
|
LPSTR pzStrTab;
|
|
UINT uStrOfs;
|
|
UINT uStrLen;
|
|
UINT StrLen1;
|
|
UINT StrLen2;
|
|
|
|
|
|
// Capture Filter
|
|
if ( !ValidCaptureMsg(hISRInst, DbgLevel) )
|
|
return;
|
|
|
|
if (pzStr1)
|
|
StrLen1 = lstrlen(pzStr1);
|
|
else
|
|
StrLen1 = 0;
|
|
if (pzStr2)
|
|
StrLen2 = lstrlen(pzStr2);
|
|
else
|
|
StrLen2 = 0;
|
|
uStrLen = StrLen1 + StrLen2 + 1; // 1 for null terminator.
|
|
if (kMaxStrTab <= uStrLen)
|
|
{
|
|
return; // It is so big.
|
|
}
|
|
|
|
// Protect against reentrancy. Just drop the msg if reentered.
|
|
if (WAIT_OBJECT_0 != WaitForSingleObject(gSemaphore,100))
|
|
return;
|
|
|
|
uStrOfs = gpDS->gStrTabOfs;
|
|
gpDS->gStrTabOfs += uStrLen;
|
|
if (kMaxStrTab <= gpDS->gStrTabOfs)
|
|
{
|
|
uStrOfs = 0;
|
|
gpDS->gStrTabOfs = uStrLen;
|
|
|
|
// Also reset items which would otherwise point in trashed strings.
|
|
gpDS->guNumItems = 0;
|
|
}
|
|
pzStrTab = gpzStrTab + uStrOfs;
|
|
ReleaseSemaphore(gSemaphore,1,NULL);
|
|
|
|
if (pzStr1)
|
|
lstrcpy(pzStrTab, pzStr1);
|
|
if (pzStr2)
|
|
lstrcpy(pzStrTab+StrLen1, pzStr2);
|
|
|
|
OutputRec(hISRInst, DbgLevel, kParam1IsStr, IP, uStrOfs, Param1);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// ISR_HookDbgStrStr
|
|
// Allow two strings to be concatenated together.
|
|
//------------------------------------------------------------------------------
|
|
ISR_DLL void WINAPI DLL_EXPORT
|
|
ISR_HookDbgStrStr (UINT IP, WORD hISRInst, BYTE DbgLevel, LPSTR pzStr1, LPSTR pzStr2)
|
|
{
|
|
OutputRecStr(hISRInst, DbgLevel, kParam1IsStr, IP, pzStr1, pzStr2, 0);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// ISR_HookDbgRes
|
|
// Use a resource to format a number.
|
|
//------------------------------------------------------------------------------
|
|
ISR_DLL void WINAPI DLL_EXPORT
|
|
ISR_HookDbgRes (UINT IP, WORD hISRInst, BYTE DbgLevel, UINT uResId, DWORD Param1)
|
|
{
|
|
OutputRec(hISRInst, DbgLevel, kParam1IsRes, IP, uResId, Param1);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// ISR_HookDbgStr
|
|
// Use a str to format a number.
|
|
//------------------------------------------------------------------------------
|
|
ISR_DLL void WINAPI DLL_EXPORT
|
|
ISR_HookDbgStr (UINT IP, WORD hISRInst, BYTE DbgLevel, LPSTR pzStr1, DWORD Param1)
|
|
{
|
|
OutputRecStr(hISRInst, DbgLevel, kParam1IsStr, IP, pzStr1, 0, Param1);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// ISR_DbgStrStr
|
|
// Allow two strings to be concatenated together.
|
|
//------------------------------------------------------------------------------
|
|
ISR_DLL void WINAPI DLL_EXPORT
|
|
ISR_DbgStrStr (WORD hISRInst, BYTE DbgLevel, LPSTR pzStr1, LPSTR pzStr2)
|
|
{
|
|
UINT IP = 0;
|
|
|
|
|
|
// _asm
|
|
// {
|
|
// push ax
|
|
// mov ax,[bp+2]
|
|
// mov IP,ax
|
|
// pop ax
|
|
// }
|
|
ISR_HookDbgStrStr(IP, hISRInst, DbgLevel, pzStr1, pzStr2);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// ISR_DbgRes
|
|
// Use a resource to format a number.
|
|
//------------------------------------------------------------------------------
|
|
ISR_DLL void WINAPI DLL_EXPORT
|
|
ISR_DbgRes (WORD hISRInst, BYTE DbgLevel, UINT uResId, DWORD Param1)
|
|
{
|
|
UINT IP = 0;
|
|
|
|
|
|
// _asm
|
|
// {
|
|
// push ax
|
|
// mov ax,[bp+2]
|
|
// mov IP,ax
|
|
// pop ax
|
|
// }
|
|
ISR_HookDbgRes(IP, hISRInst, DbgLevel, uResId, Param1);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// ISR_DbgStr
|
|
// Use a str to format a number.
|
|
//------------------------------------------------------------------------------
|
|
ISR_DLL void WINAPI DLL_EXPORT
|
|
ISR_DbgStr (WORD hISRInst, BYTE DbgLevel, LPSTR pzStr1, DWORD Param1)
|
|
{
|
|
UINT IP = 0;
|
|
|
|
|
|
// _asm
|
|
// {
|
|
// push ax
|
|
// mov ax,[bp+2]
|
|
// mov IP,ax
|
|
// pop ax
|
|
// }
|
|
ISR_HookDbgStr(IP, hISRInst, DbgLevel, pzStr1, Param1);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// TT_DbgMsg
|
|
// This function builds a formatted string, based upon numeric or
|
|
// string input parameters, and sends the string to isrdbg.dll to
|
|
// be displayed in the isrdsp.exe window. THIS FUNCTION CAN NOT
|
|
// BE CALLED AT INTERRUPT-TIME. This function uses the same
|
|
// mechanism as isrdbg.dll to enable/disable debug output.
|
|
//
|
|
// In:
|
|
// hISRInst, - Module's ISRDBG handle.
|
|
// DbgLevel, - Appropriate ISRDBG level.
|
|
// zMsgFmt, - Output format string (like printf).
|
|
// ... - Optional parameter list.
|
|
//
|
|
// Out:
|
|
// none
|
|
//
|
|
// Return:
|
|
// none
|
|
//------------------------------------------------------------------------------
|
|
ISR_DLL void FAR cdecl DLL_EXPORT
|
|
TTDbgMsg
|
|
(
|
|
WORD hISRInst,
|
|
BYTE DbgLevel,
|
|
LPCSTR zMsgFmt,
|
|
...
|
|
)
|
|
{
|
|
WORD TempIP = 0;
|
|
char MsgBuf[256];
|
|
|
|
// _asm
|
|
// {
|
|
// push ax
|
|
// mov ax,[bp+2]
|
|
// mov TempIP,ax
|
|
// pop ax
|
|
// }
|
|
|
|
#ifdef _M_ALPHA
|
|
va_list valDummy;
|
|
ZeroMemory(&valDummy, sizeof(valDummy));
|
|
|
|
va_start (valDummy,zMsgFmt);
|
|
wvsprintf (MsgBuf, zMsgFmt, valDummy);
|
|
va_end (valDummy);
|
|
#else // _M_ALPHA
|
|
wvsprintf (MsgBuf, zMsgFmt, (va_list) (&zMsgFmt + 1));
|
|
#endif // _M_ALPHA
|
|
|
|
ISR_HookDbgStrStr(TempIP, hISRInst, DbgLevel, MsgBuf, 0);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// ISR_OutputDbgStr ()
|
|
// Store a string to be displayed at task time.
|
|
// The passed in string will be copied to a local storage.
|
|
// Therefore the caller can reuse on return.
|
|
//------------------------------------------------------------------------------
|
|
ISR_DLL void WINAPI DLL_EXPORT
|
|
ISR_OutputDbgStr (LPSTR pzStr)
|
|
{
|
|
WORD TempIP = 0;
|
|
|
|
|
|
// _asm
|
|
// {
|
|
// push ax
|
|
// mov ax,[bp+2]
|
|
// mov TempIP,ax
|
|
// pop ax
|
|
// }
|
|
|
|
ISR_HookDbgStrStr(TempIP, gpDS->ghDefaultModule, kISRDefault, pzStr, 0);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// ISR_OutputStr ()
|
|
// Store a string resource Id to be displayed at task time.
|
|
//------------------------------------------------------------------------------
|
|
ISR_DLL void WINAPI DLL_EXPORT
|
|
ISR_OutputStr (UINT uResId)
|
|
{
|
|
UINT TempIP = 0;
|
|
|
|
|
|
// _asm
|
|
// {
|
|
// push ax
|
|
// mov ax,[bp+2]
|
|
// mov TempIP,ax
|
|
// pop ax
|
|
// }
|
|
ISR_HookDbgRes(TempIP, gpDS->ghDefaultModule, kISRDefault, uResId, 0);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// ISR_OutputNum ()
|
|
// Store a string resource Id to be displayed at task time.
|
|
// In addition store a number to be displayed in printf format of the
|
|
// string.
|
|
//------------------------------------------------------------------------------
|
|
ISR_DLL void WINAPI DLL_EXPORT
|
|
ISR_OutputNum (UINT uResId, DWORD Num)
|
|
{
|
|
WORD TempIP = 0;
|
|
|
|
|
|
// _asm
|
|
// {
|
|
// push ax
|
|
// mov ax,[bp+2]
|
|
// mov TempIP,ax
|
|
// pop ax
|
|
// }
|
|
ISR_HookDbgRes(TempIP, gpDS->ghDefaultModule, kISRDefault, uResId, Num);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// DbgMsg ()
|
|
// Canned Debug format that may be useful. This function has nothen
|
|
// to do with Interrupt time display. However it keeps all the
|
|
// display info in one place. Basically it is convenient.
|
|
//
|
|
// WARNING: Do not call this at interrupt time. wsprintf is not reentrant.
|
|
//------------------------------------------------------------------------------
|
|
ISR_DLL void FAR cdecl DLL_EXPORT
|
|
DbgMsg
|
|
(
|
|
LPCSTR module,
|
|
int state,
|
|
LPCSTR format_str,
|
|
...
|
|
)
|
|
{
|
|
WORD TempIP = 0;
|
|
char MsgBuf[256];
|
|
va_list valDummy;
|
|
|
|
|
|
// _asm
|
|
// {
|
|
// push ax
|
|
// mov ax,[bp+2]
|
|
// mov TempIP,ax
|
|
// pop ax
|
|
// }
|
|
|
|
wsprintf (MsgBuf, ">--<%s> %s", module,
|
|
(LPSTR) ((state == ISR_DBG) ? "debug : " : "ERROR : "));
|
|
|
|
|
|
#ifdef _M_ALPHA
|
|
ZeroMemory(&valDummy, sizeof(valDummy));
|
|
|
|
va_start (valDummy,format_str);
|
|
wvsprintf ((LPSTR) (MsgBuf + lstrlen (MsgBuf)), format_str,valDummy);
|
|
va_end (valDummy);
|
|
#else // _M_ALPHA
|
|
wvsprintf ((LPSTR) (MsgBuf + lstrlen (MsgBuf)), format_str,
|
|
(va_list) (&format_str + 1));
|
|
|
|
#endif // _M_ALPHA
|
|
|
|
|
|
ISR_HookDbgStrStr(TempIP, gpDS->ghDefaultModule, kISRDefault, MsgBuf, 0);
|
|
|
|
// lstrcat (MsgBuf, "\n");
|
|
|
|
// OutputDebugString (MsgBuf);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// ISR_ClearItems ()
|
|
// Clear the list of debug msgs.
|
|
//------------------------------------------------------------------------------
|
|
ISR_DLL void WINAPI DLL_EXPORT
|
|
ISR_ClearItems (void)
|
|
{
|
|
// Protect against reentrancy. Just drop the msg if reentered.
|
|
if (WAIT_OBJECT_0 != WaitForSingleObject(gSemaphore,100))
|
|
return;
|
|
|
|
// This is not a serious race condition. Must likely failure
|
|
// is what messages get dropped.
|
|
gpDS->guNumItems = 0;
|
|
gpDS->gStrTabOfs = 0;
|
|
|
|
ReleaseSemaphore(gSemaphore,1,NULL);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// ISR_GetNumItems ()
|
|
// Return the number of items that have be entered.
|
|
//------------------------------------------------------------------------------
|
|
ISR_DLL UINT WINAPI DLL_EXPORT
|
|
ISR_GetNumItems (void)
|
|
{
|
|
return gpDS->guNumItems;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
// ISR_GetNumModules ()
|
|
// Return the number of modules that have be entered.
|
|
//------------------------------------------------------------------------------
|
|
ISR_DLL UINT WINAPI DLL_EXPORT
|
|
ISR_GetNumModules (void)
|
|
{
|
|
return gpDS->guNumModules;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// ISR_GetItemInternal
|
|
// Return a pointer to the record num uItem. Only reason to
|
|
// do it this way is to hide the buf struct. This way I can use a
|
|
// heap manager such as BigMem or SmartHeap or NT HeapAlloc.
|
|
// The items are numbered 0..n-1.
|
|
// Alternatively a Ptr to the array of records could be passed back.
|
|
//------------------------------------------------------------------------------
|
|
ptISRItem WINAPI
|
|
ISR_GetItemInternal (UINT uItem)
|
|
{
|
|
if (kMaxISRItems <= uItem)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
return &gpDbgTable[uItem];
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// ISR_GetItem
|
|
// Return a pointer to the record num uItem. Only reason to
|
|
// do it this way is to hide the buf struct. This way I can use a
|
|
// heap manager such as BigMem or SmartHeap or NT HeapAlloc.
|
|
// The items are numbered 0..n-1.
|
|
// Alternatively a Ptr to the array of records could be passed back.
|
|
//------------------------------------------------------------------------------
|
|
ISR_DLL ptISRItem WINAPI DLL_EXPORT
|
|
ISR_GetItem (UINT uItem,ptISRItem pItem)
|
|
{
|
|
ptISRItem pISRItem;
|
|
|
|
if (!pItem)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
pISRItem = ISR_GetItemInternal(uItem);
|
|
if (!pISRItem)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
memcpy(pItem,pISRItem,sizeof(tISRItem));
|
|
if (pISRItem->Flags & kParam1IsStr)
|
|
{
|
|
// This memory is shared so therefore need to make a copy for upper layers
|
|
// Ptr within the struct are offsets so now need to be ptrs again.
|
|
// Each instance of DLL in Win32 has its own memory map
|
|
pItem->Param1 += (DWORD_PTR)gpzStrTab;
|
|
}
|
|
|
|
return pItem;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// ISR_RegisterModule
|
|
// Register a name to be associated with related debug strings.
|
|
// The debug display code can then present this information to the user
|
|
// to determine how to filter the data.
|
|
//
|
|
// Params:
|
|
// zShortName - name to display when space is critical.
|
|
// zLongName - name to display when a complete description is needed.
|
|
//
|
|
// Returns:
|
|
// on error zero for the compatible handle.
|
|
// a handle to be used when making all other debug output calls.
|
|
//------------------------------------------------------------------------------
|
|
ISR_DLL void WINAPI DLL_EXPORT
|
|
ISR_RegisterModule (LPWORD phISRInst, LPSTR pzShortName, LPSTR pzLongName)
|
|
{
|
|
ptISRModule pMod;
|
|
UINT hMod;
|
|
|
|
if (!phISRInst)
|
|
return;
|
|
|
|
*phISRInst = 0;
|
|
|
|
if (kMaxModules <= gpDS->guNumModules)
|
|
{
|
|
// We are out of handles.
|
|
// Return the default handle and drop the name info.
|
|
return;
|
|
}
|
|
|
|
// Check if this module label was used before. If it has then just reuse it.
|
|
// This case will most likely happen when the module is loaded, unloaded,
|
|
// and then reloaded. Another case is when the same name is used in two
|
|
// different instances. This would be a confusing programmer oversight
|
|
// and that his problem.
|
|
for (hMod = 0; hMod < kMaxModules; hMod++)
|
|
{
|
|
// if no name then we cannot group very well.
|
|
// In this case waste another handle.
|
|
if (!pzShortName || (0 == *pzShortName))
|
|
break;
|
|
|
|
pMod = ISR_GetModule(hMod);
|
|
if (!pMod)
|
|
break;
|
|
|
|
if ( !_strnicmp(pzShortName,pMod->zSName,sizeof(pMod->zSName)-1) )
|
|
{
|
|
// It matched so just reuse it.
|
|
*phISRInst = (WORD)hMod;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
*phISRInst = gpDS->guNumModules++;
|
|
|
|
pMod = ISR_GetModule(*phISRInst);
|
|
if (!pMod)
|
|
return;
|
|
|
|
if (pzShortName)
|
|
strncpy(pMod->zSName,pzShortName,sizeof(pMod->zSName));
|
|
pMod->zSName[sizeof(pMod->zSName)-1] = 0;
|
|
if (pzLongName)
|
|
strncpy(pMod->zLName,pzLongName,sizeof(pMod->zLName));
|
|
pMod->zLName[sizeof(pMod->zLName)-1] = 0;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// ISR_GetModule
|
|
// Return a pointer to the module record. Only reason to
|
|
// do it this way is to hide the buf struct. This way I can use a
|
|
// heap manager such as BigMem or SmartHeap or NT HeapAlloc.
|
|
// Alternatively a Ptr to the array of records could be passed back.
|
|
//------------------------------------------------------------------------------
|
|
ISR_DLL ptISRModule WINAPI DLL_EXPORT
|
|
ISR_GetModule (UINT hISRInst)
|
|
{
|
|
if (kMaxModules <= hISRInst)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
return(&gpModuleTable[hISRInst]);
|
|
}
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// ISR_SetCaptureFilter
|
|
// Debug Messages for a given module can be dropped based on a low/high
|
|
// filter. If the entire module is not wanted then call with
|
|
// LoFilter = 255, and HiFilter = 0.
|
|
//
|
|
//------------------------------------------------------------------------------
|
|
ISR_DLL int WINAPI DLL_EXPORT
|
|
ISR_SetCaptureFilter (WORD hISRInst, BYTE CaptureFilter, BYTE DisplayFilter)
|
|
{
|
|
ptISRModule pMod;
|
|
|
|
|
|
pMod = ISR_GetModule(hISRInst);
|
|
if (!pMod)
|
|
return -1;
|
|
|
|
pMod->CaptureFilter = CaptureFilter;
|
|
pMod->DisplayFilter = DisplayFilter;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
LibMain()
|
|
DLL entry point
|
|
|
|
Parameters
|
|
hDllInstance = instance handle of the DLL (NOT our caller!)
|
|
wDataSegment = our DS
|
|
wHeapSize = size of our heap in DS (see .def)
|
|
lpzCmdLine = argv passed to application (our caller)
|
|
|
|
Returns
|
|
TRUE iff we were able to register our window class
|
|
|
|
|
|
Side Effects
|
|
- Unlocks our data segment (which is really a NOP for protect mode)
|
|
|
|
****************************************************************************/
|
|
extern BOOL WINAPI
|
|
DllMain
|
|
(
|
|
HINSTANCE hDllInstance,
|
|
DWORD dwReason,
|
|
PVOID pReserved
|
|
)
|
|
{
|
|
switch (dwReason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
{
|
|
// Called for each exe binding. Each time a exe binds a different hDllInstance will
|
|
// be passed in. Also our global data will be unique for each Process binding.
|
|
ghAppInstance = hDllInstance;
|
|
|
|
// Create a named file mapping object for the base table.
|
|
MapGlobalWin32Memory(&gpDS,&ghDS,sizeof(tDS),"ISRDBG_DS");
|
|
MapGlobalWin32Memory(&gpModuleTable,&ghModuleTable,sizeof(tISRModule) * kMaxModules,"ISRDBG_ModuleTable");
|
|
MapGlobalWin32Memory(&gpDbgTable,&ghDbgTable,sizeof(tISRItem) * kMaxISRItems,"ISRDBG_DbgTable");
|
|
MapGlobalWin32Memory(&gpzStrTab,&ghzStrTab,kMaxStrTab,"ISRDBG_StrTab");
|
|
if (!gpDS || !gpModuleTable || !gpDbgTable || !gpzStrTab)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
gSemaphore = CreateSemaphore(NULL,1,1,NULL);
|
|
|
|
if (!gpDS->uBindCount++)
|
|
{
|
|
// Set the filters before any output.
|
|
InitModules();
|
|
|
|
// Reserve the default module.
|
|
ISR_RegisterModule(&gpDS->ghDefaultModule, "Default", "<ISRDBG><Default Module>");
|
|
ISR_DbgStrStr(gpDS->ghDefaultModule, kISRDefault, "<ISRDBG><DllMain>", "Win32 x1.00");
|
|
ISR_DbgStrStr(gpDS->ghDefaultModule, kISRDefault, "<ISRDBG><DllMain>", "Line 2 test");
|
|
}
|
|
break;
|
|
}
|
|
case DLL_THREAD_ATTACH:
|
|
{
|
|
break;
|
|
}
|
|
|
|
case DLL_THREAD_DETACH:
|
|
{
|
|
break;
|
|
}
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
{
|
|
if (gSemaphore)
|
|
{
|
|
CloseHandle(gSemaphore);
|
|
gSemaphore = 0;
|
|
}
|
|
|
|
// The DLL is detaching from a process due to
|
|
// process termination or a call to FreeLibrary.
|
|
FreeGlobalWin32Memory(gpDS,ghDS);
|
|
FreeGlobalWin32Memory(gpModuleTable,ghModuleTable);
|
|
FreeGlobalWin32Memory(gpDbgTable,ghDbgTable);
|
|
FreeGlobalWin32Memory(gpzStrTab,ghzStrTab);
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|