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.
 
 
 
 
 
 

1233 lines
28 KiB

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
emdp3.c
Abstract:
This file contains the some of the machine independent portions of the
execution model. The machine dependent portions are in other files.
Author:
Kent Forschmiedt (kentf) 11-8-93
Environment:
Win32 -- User
Notes:
The orginal source for this came from the CodeView group.
--*/
extern RD Rgrd[];
extern const unsigned CRgrd;
extern struct RGFD Rgfd[];
extern const unsigned CRgfd;
//
// This list is only used when there is no DM present. Whenever an
// hpid is created, the real list is obtained from the DM and stored
// in a list bound to the hprc.
//
static EXCEPTION_DESCRIPTION DefaultExceptionList[] = {
{EXCEPTION_ACCESS_VIOLATION, efdStop, "Access Violation"},
{EXCEPTION_DATATYPE_MISALIGNMENT, efdStop, "Data Misalignment"},
{EXCEPTION_ARRAY_BOUNDS_EXCEEDED, efdStop, "Array Bounds Exceeded"},
{EXCEPTION_FLT_DENORMAL_OPERAND, efdStop, "FP Denormal Operand"},
{EXCEPTION_FLT_DIVIDE_BY_ZERO, efdStop, "FP Divide by Zero"},
{EXCEPTION_FLT_INEXACT_RESULT, efdStop, "FP Inexact Result"},
{EXCEPTION_FLT_INVALID_OPERATION, efdStop, "FP Invalid Operation"},
{EXCEPTION_FLT_OVERFLOW, efdStop, "FP Overflow"},
{EXCEPTION_FLT_STACK_CHECK, efdStop, "FP Stack Check"},
{EXCEPTION_FLT_UNDERFLOW, efdStop, "FP Underflow"},
{EXCEPTION_INT_DIVIDE_BY_ZERO, efdStop, "Int Divide by zero"},
{EXCEPTION_INT_OVERFLOW, efdStop, "Int Overflow"},
{EXCEPTION_PRIV_INSTRUCTION, efdStop, "Insufficient Privilege"},
{EXCEPTION_IN_PAGE_ERROR, efdStop, "I/O Error in Paging"},
{EXCEPTION_ILLEGAL_INSTRUCTION, efdStop, "Illegal Instruction"},
{EXCEPTION_NONCONTINUABLE_EXCEPTION,efdStop, "Noncontinuable Exception"},
{EXCEPTION_STACK_OVERFLOW, efdStop, "Stack Overflow"},
{EXCEPTION_INVALID_DISPOSITION, efdStop, "Invalid Disposition"},
{RPC_S_OUT_OF_RESOURCES, efdNotify, "RPC Out Of Resources"},
{RPC_S_SERVER_UNAVAILABLE, efdNotify, "RPC Server Unavailable"},
{RPC_S_SERVER_TOO_BUSY, efdNotify, "RPC Server Too Busy"},
{DBG_CONTROL_C, efdStop, "Control-C break"},
{0xE06d7363, efdNotify, "Microsoft C++ EH Exception"},
{(DWORD)STATUS_NO_MEMORY, efdStop, "No Memory"},
{(DWORD)NULL, efdStop, "Unknown"},
};
XOSD
HandleBreakpoints(
HPID hpid,
DWORD wValue,
LONG lValue
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
LPBPS lpbps = (LPBPS) lValue;
LPDBB lpdbb = malloc(sizeof(DBB) + wValue);
// let the DM handle everything?
lpdbb->hpid = hpid;
lpdbb->htid = NULL;
lpdbb->dmf = dmfBreakpoint;
memcpy(lpdbb->rgbVar, lpbps, wValue);
CallTL ( tlfRequest, hpid, sizeof ( DBB ) + wValue, (LPVOID)lpdbb );
if (LpDmMsg->xosdRet == xosdNone) {
memcpy(DwNotification(lpbps),
DwNotification( (LPBPS)(LpDmMsg->rgb) ),
lpbps->cbpis * sizeof(DWORD));
}
return LpDmMsg->xosdRet;
}
XOSD
Go (
HPID hpid,
HTID htid,
LPEXOP lpexop
)
{
UpdateChild ( hpid, htid, dmfGo );
return SendRequestX(dmfGo, hpid, htid, sizeof(EXOP), lpexop);
}
#if 0
XOSD
ReturnStep (
HPID hpid,
HTID htid,
LPEXOP lpexop
)
{
HTHD hthd;
HPRC hprc = ValidHprcFromHpid(hpid);
RTRNSTP rtrnstp;
XOSD xosd = xosdNone;
HTID vhtid = htid;
if (!hprc) {
return xosdInvalidProc;
}
if ( (hthd = HthdFromHtid(hprc, htid)) == hthdInvalid || hthd == NULL ) {
return xosdInvalidThread;
}
rtrnstp.exop = *lpexop;
if ((((DWORD)htid) & 1) == 0) {
xosd = DoGetFrame( hpid, vhtid, 1, (DWORD)&vhtid );
}
if ( xosd == xosdNone ) {
xosd = DoGetFrame( hpid, vhtid, 1, (DWORD)&vhtid );
if ( xosd == xosdNone ) {
xosd = GetAddr( hpid, vhtid, adrPC, &(rtrnstp.addrRA) );
}
}
if ( xosd != xosdNone ) {
return( xosd );
}
return SendRequestX ( dmfReturnStep, hpid, htid, sizeof(rtrnstp), &rtrnstp);
}
#endif
XOSD
ThreadStatus (
HPID hpid,
HTID htid,
LPTST lptst
)
{
XOSD xosd = SendRequest ( dmfThreadStatus, hpid, htid );
if (xosd == xosdNone) {
xosd = LpDmMsg->xosdRet;
}
if (xosd == xosdNone) {
memcpy(lptst, LpDmMsg->rgb, sizeof(TST));
}
return xosd;
}
XOSD
ProcessStatus(
HPID hpid,
LPPST lppst
)
{
XOSD xosd;
xosd = SendRequest(dmfProcessStatus, hpid, NULL );
if (xosd == xosdNone) {
xosd = LpDmMsg->xosdRet;
}
if (xosd == xosdNone) {
memcpy(lppst, LpDmMsg->rgb, sizeof(PST));
}
return xosd;
}
#ifdef OSDEBUG4
XOSD
Freeze (
HPID hpid,
HTID htid
)
{
HTHD hthd;
HPRC hprc = ValidHprcFromHpid(hpid);
if (!hprc) {
return xosdBadProcess;
}
if ( (hthd = HthdFromHtid(hprc, htid)) == hthdInvalid || hthd == NULL ) {
return xosdBadThread;
}
SendRequest ( dmfFreeze, hpid, htid);
return LpDmMsg->xosdRet;
}
XOSD
Thaw (
HPID hpid,
HTID htid
)
{
HTHD hthd;
HPRC hprc = ValidHprcFromHpid(hpid);
if (!hprc) {
return xosdBadProcess;
}
if ( (hthd = HthdFromHtid(hprc, htid)) == hthdInvalid || hthd == NULL ) {
return xosdBadThread;
}
SendRequest ( dmfResume, hpid, htid);
return LpDmMsg->xosdRet;
}
#endif
XOSD
DebugMetric (
HPID hpid,
HTID htid,
MTRC mtrc,
LPLONG lpl
)
/*++
Routine Description:
The debugger queries this function to find out the size of OS and machine
dependent values, e.g. the size of a process ID.
Arguments:
hpid
htid
mtrc - metric identifier
lpl - answer buffer
Return Value:
xosdNone if the request succeeded, xosd error code otherwise.
--*/
{
HPRC hprc;
LPPRC lpprc = NULL;
XOSD xosd = xosdNone;
hprc = HprcFromHpid(hpid);
if (hprc) {
lpprc = LLLock( hprc );
assert( lpprc );
switch ( mtrc ) {
default:
break;
//
// Invalidate cache for some items:
//
case mtrcProcessorType:
case mtrcProcessorLevel:
case mtrcOSVersion:
lpprc->fDmiCache = FALSE;
case mtrcEndian:
case mtrcThreads:
case mtrcAsync:
case mtrcAsyncStop:
case mtrcBreakPoints:
case mtrcReturnStep:
case mtrcRemote:
if (!lpprc->fDmiCache) {
xosd = SendRequest ( dmfGetDmInfo, hpid, htid );
if (xosd == xosdNone) {
memcpy(&lpprc->dmi, LpDmMsg->rgb, sizeof(DMINFO));
lpprc->fDmiCache = TRUE;
}
}
break;
}
if (xosd != xosdNone) {
LLUnlock( hprc );
return xosd;
}
}
switch ( mtrc ) {
default:
assert(FALSE);
xosd = xosdInvalidParameter;
break;
case mtrcProcessorType:
assert(lpprc);
*lpl = lpprc->dmi.Processor.Type;
break;
case mtrcProcessorLevel:
assert(lpprc);
*lpl = lpprc->dmi.Processor.Level;
break;
case mtrcEndian:
assert(lpprc);
*lpl = lpprc->dmi.Processor.Endian;
break;
case mtrcThreads:
assert(lpprc);
*lpl = lpprc->dmi.fHasThreads;
break;
case mtrcCRegs:
*lpl = CRgrd;
break;
case mtrcCFlags:
*lpl = CRgfd;
break;
case mtrcExtRegs:
assert(0 && "do something with this");
break;
case mtrcExtFP:
assert(0 && "do something with this");
break;
case mtrcExtMMU:
assert(0 && "do something with this");
break;
case mtrcExceptionHandling:
*( (LPDWORD) lpl) = TRUE;
break;
case mtrcAssembler:
#if defined(TARGET_i386)
*( (LPDWORD) lpl) = TRUE;
#elif defined(TARGET_PPC)
*( (LPDWORD) lpl) = FALSE;
#elif defined(TARGET_MIPS)
*( (LPDWORD) lpl) = FALSE;
#elif defined(TARGET_ALPHA)
*( (LPDWORD) lpl) = TRUE;
#else
#error "Unknown CPU type"
#endif
break;
case mtrcAsync:
assert(lpprc);
*lpl = lpprc->dmi.fAsync;
break;
case mtrcAsyncStop:
assert(lpprc);
*lpl = lpprc->dmi.fAsyncStop;
break;
case mtrcBreakPoints:
assert(lpprc);
//
// Message BPs are implemented in the EM
// on top of the exec BP implemented by the DM.
//
*lpl = lpprc->dmi.Breakpoints |
bptsMessage |
bptsMClass;
break;
case mtrcReturnStep:
assert(lpprc);
*lpl = lpprc->dmi.fReturnStep;
break;
case mtrcShowDebuggee:
*lpl = FALSE;
break;
case mtrcHardSoftMode:
*lpl = FALSE;
break;
case mtrcRemote:
assert(lpprc);
*lpl = lpprc->dmi.fRemote;
break;
case mtrcOleRpc:
*lpl = FALSE;
break;
case mtrcNativeDebugger:
*lpl = FALSE;
break;
case mtrcOSVersion:
*lpl = MAKELONG( lpprc->dmi.MinorVersion, lpprc->dmi.MajorVersion );
break;
case mtrcMultInstances:
*(BOOL*) lpl = TRUE;
break;
}
LLUnlock( hprc );
return xosdNone;
}
XOSD
FakeGetExceptionState(
EXCEPTION_CONTROL exc,
LPEXCEPTION_DESCRIPTION lpexd
)
/*++
Routine Description:
Handle the GetExceptionState call when there is no DM connected.
Arguments:
exc - Supplies exfFirst, exfSpecified or exfNext
lpexd - Returns EXCEPTION_DESCRIPTION record
Return Value:
xosdNone except when exc is exfNext and lpexd->dwExceptionCode
was not in the list.
--*/
{
DWORD dwT;
int i;
if (exc == exfFirst) {
*lpexd = DefaultExceptionList[0];
return xosdNone;
}
for (i = 0; DefaultExceptionList[i].dwExceptionCode != 0; i++) {
if (DefaultExceptionList[i].dwExceptionCode == lpexd->dwExceptionCode) {
break;
}
}
if (exc == exfSpecified) {
dwT = lpexd->dwExceptionCode;
*lpexd = DefaultExceptionList[i];
lpexd->dwExceptionCode = dwT;
return xosdNone;
}
if (DefaultExceptionList[i].dwExceptionCode != 0) {
*lpexd = DefaultExceptionList[++i];
return xosdNone;
}
return xosdInvalidParameter;
}
XOSD
GetExceptionState(
HPID hpid,
HTID htid,
EXCEPTION_CONTROL exc,
LPEXCEPTION_DESCRIPTION lpexd
)
{
HPRC hprc;
LPPRC lpprc;
XOSD xosd = xosdNone;
HEXD hexd;
if (!hpid) {
return FakeGetExceptionState(exc, lpexd);
}
hprc = HprcFromHpid( hpid );
assert(hprc);
lpprc = LLLock(hprc);
switch (exc) {
default:
assert( 0 && "Invalid arg to em!GetExceptionState" );
xosd = xosdInvalidParameter;
break;
case exfFirst:
hexd = LLNext( lpprc->llexc, NULL );
if (!hexd) {
// get the default exception record
DWORD dwT = 0;
hexd = LLFind( lpprc->llexc, NULL, &dwT, 0 );
}
if (!hexd) {
memset(lpexd, 0, sizeof(EXCEPTION_DESCRIPTION));
}
else {
*lpexd = *(LPEXCEPTION_DESCRIPTION)LLLock(hexd);
LLUnlock(hexd);
}
break;
case exfSpecified:
hexd = LLFind( lpprc->llexc, NULL, &lpexd->dwExceptionCode, 0 );
if (!hexd) {
// get the default exception record
DWORD dwT = 0;
hexd = LLFind( lpprc->llexc, NULL, &dwT, 0 );
}
if (!hexd) {
memset(lpexd, 0, sizeof(EXCEPTION_DESCRIPTION));
xosd = xosdInvalidParameter;
}
else {
*lpexd = *(LPEXCEPTION_DESCRIPTION)LLLock(hexd);
LLUnlock(hexd);
}
break;
case exfNext:
hexd = LLFind( lpprc->llexc, NULL, &lpexd->dwExceptionCode, 0 );
if (!hexd) {
//
// origin must exist
//
xosd = xosdInvalidParameter;
} else {
//
// but the next one need not
//
hexd = LLNext( lpprc->llexc, hexd );
if (!hexd) {
memset(lpexd, 0, sizeof(EXCEPTION_DESCRIPTION));
xosd = xosdEndOfStack;
} else {
*lpexd = *(LPEXCEPTION_DESCRIPTION)LLLock(hexd);
LLUnlock(hexd);
}
}
break;
}
LLUnlock(hprc);
return xosd;
}
XOSD
SetExceptionState(
HPID hpid,
HTID htid,
LPEXCEPTION_DESCRIPTION lpexd
)
{
HPRC hprc = HprcFromHpid( hpid );
HLLI llexc;
HEXD hexd;
assert(lpexd->efd == efdIgnore ||
lpexd->efd == efdNotify ||
lpexd->efd == efdCommand ||
lpexd->efd == efdStop);
if (!hprc) {
return xosdInvalidProc;
}
llexc = ((LPPRC)LLLock(hprc))->llexc;
LLUnlock(hprc);
hexd = LLFind( llexc, NULL, &lpexd->dwExceptionCode, 0 );
if (!hexd) {
hexd = LLCreate( llexc );
if (!hexd) {
return xosdOutOfMemory;
}
LLAdd( llexc, hexd );
}
*(LPEXCEPTION_DESCRIPTION)LLLock(hexd) = *lpexd;
LLUnlock(hexd);
return SendRequestX( dmfSetExceptionState, hpid, htid,
sizeof(EXCEPTION_DESCRIPTION), lpexd);
}
#ifdef OSDEBUG4
XOSD
GetMemoryInfo(
HPID hpid,
HTID htid,
LPMEMINFO lpmi
)
{
PMEMORY_BASIC_INFORMATION lpmbi;
ADDR addr;
XOSD xosd = xosdNone;
Unreferenced(htid);
addr = lpmi->addr;
if (ADDR_IS_LI(addr)) {
xosd = FixupAddr(hpid, &addr);
}
if (xosd == xosdNone) {
xosd = SendRequestX( dmfVirtualQuery, hpid, 0, sizeof(ADDR),
(LPVOID)&addr );
}
if (xosd == xosdNone) {
lpmbi = (PMEMORY_BASIC_INFORMATION) LpDmMsg->rgb;
lpmi->addrAllocBase = addr;
lpmi->addrAllocBase.addr.off = (UOFF32)lpmbi->AllocationBase;
lpmi->uRegionSize = (UOFF32)lpmbi->RegionSize;
lpmi->dwProtect = lpmbi->Protect;
lpmi->dwState = lpmbi->State;
lpmi->dwType = lpmbi->Type;
}
return xosd;
}
XOSD
FreezeThread(
HPID hpid,
HTID htid,
BOOL fFreeze
)
{
HTHD hthd;
HPRC hprc = ValidHprcFromHpid(hpid);
if (!hprc) {
return xosdBadProcess;
}
if ( (hthd = HthdFromHtid(hprc, htid)) == hthdInvalid || hthd == NULL ) {
return xosdBadThread;
}
if (fFreeze) {
SendRequest ( dmfFreeze, hpid, htid);
} else {
SendRequest ( dmfResume, hpid, htid);
}
return LpDmMsg->xosdRet;
}
#define FreeModuleList(m) free(m)
#define ModuleListCount(m) ((m)->Count)
#define FirstModuleEntry(m) ((LPMODULE_ENTRY)((m)+1))
#define NextModuleEntry(e) ((e)+1)
#define NthModuleEntry(m,n) (FirstModuleEntry(m)+(n))
#define ModuleEntryFlat(e) ((e)->Flat)
#define ModuleEntryReal(e) ((e)->Real)
#define ModuleEntrySegment(e) ((e)->Segment)
#define ModuleEntrySelector(e) ((e)->Selector)
#define ModuleEntryBase(e) ((e)->Base)
#define ModuleEntryLimit(e) ((e)->Limit)
#define ModuleEntryType(e) ((e)->Type)
#define ModuleEntrySectionCount(e) ((e)->SectionCount)
#define ModuleEntryName(e) ((e)->Name)
XOSD
GetModuleList(
HPID hpid,
HTID htid,
LPSTR lpModuleName,
LPMODULE_LIST FAR * lplpModuleList
)
{
XOSD xosd = xosdNone;
HLLI llmdi;
HMDI hmdi;
LPMDI lpmdi;
DWORD Count;
LPMODULE_LIST ModList;
LPMODULE_LIST TmpList;
LPMODULE_ENTRY Entry;
LDT_ENTRY Ldt;
DWORD MaxSize;
DWORD Delta;
DWORD i;
SEGMENT Selector;
DWORD Base;
DWORD Limit;
OBJD *ObjD;
char *p;
char WantedName[ MAX_PATH ];
char WantedExt[ MAX_PATH ];
char ModName[ MAX_PATH ];
char ModExt[ MAX_PATH ];
char Name[ MAX_PATH ];
*WantedName = '\0';
*WantedExt = '\0';
if ( !lplpModuleList ) {
xosd = xosdInvalidParameter;
goto Done;
}
*lplpModuleList = NULL;
llmdi = LlmdiFromHprc( HprcFromHpid ( hpid ));
if ( !llmdi ) {
xosd = xosdBadProcess;
goto Done;
}
//
// Estimate the list size, to minimize the calls to realloc.
//
if ( lpModuleName ) {
Count = 20;
_splitpath( lpModuleName, NULL, NULL, WantedName, WantedExt );
} else {
hmdi = hmdiNull;
Count = 0;
while ( (hmdi = LLNext( llmdi, hmdi )) != hmdiNull ) {
lpmdi = LLLock( hmdi );
Count += lpmdi->fFlatMode ? 1 : lpmdi->cobj;
LLUnlock( hmdi );
}
}
//
// Allocate the list
//
MaxSize = sizeof(MODULE_LIST) + Count * sizeof(MODULE_ENTRY);
ModList = MHAlloc( MaxSize );
if ( !ModList ) {
xosd = xosdOutOfMemory;
goto Done;
}
//
// Build the list
//
Count = 0;
for ( hmdi = NULL; (hmdi = LLNext( llmdi, hmdi )); LLUnlock( hmdi ) ) {
lpmdi = LLLock( hmdi );
//
// Get the module name
//
p = (*(lpmdi->lszName) == '|') ? lpmdi->lszName+1 : lpmdi->lszName;
strcpy( Name, p );
p = strchr( Name, '|' );
if ( p ) {
*p = '\0';
}
if ( lpModuleName ) {
//
// Add if base name matches
//
_splitpath( Name, NULL, NULL, ModName, ModExt );
if (_stricmp(WantedName, ModName) || _stricmp(WantedExt, ModExt) ) {
continue;
}
}
Delta = lpmdi->fFlatMode ? 1 : lpmdi->cobj;
//
// Reallocate buffer if necessary
//
if ( (Count + Delta) * sizeof(MODULE_ENTRY) > MaxSize ) {
MaxSize += Delta * sizeof(MODULE_ENTRY);
TmpList = realloc( ModList, MaxSize );
if ( !TmpList ) {
FreeModuleList(ModList);
xosd = xosdOutOfMemory;
break;
}
ModList = TmpList;
}
//
// have buffer, fill it up
//
if ( lpmdi->fFlatMode ) {
Entry = NthModuleEntry(ModList,Count);
ModuleEntryFlat(Entry) = TRUE;
ModuleEntrySegment(Entry) = 0;
ModuleEntrySelector(Entry) = 0;
ModuleEntryBase(Entry) = lpmdi->lpBaseOfDll;
ModuleEntryLimit(Entry) = 0;
ModuleEntryType(Entry) = 0;
ModuleEntrySectionCount(Entry) = lpmdi->cobj;
strcpy(ModuleEntryName(Entry), Name);
Count++;
} else {
for ( i=0, ObjD = lpmdi->rgobjd; i < Delta; i++, ObjD++ ) {
if ( ObjD->wSel ) {
Selector = ObjD->wSel;
Entry = NthModuleEntry(ModList,Count);
ModuleEntrySegment(Entry) = i+1;
ModuleEntrySelector(Entry) = Selector;
ModuleEntryType(Entry) = 0;
ModuleEntrySectionCount(Entry) = 0;
strcpy(ModuleEntryName(Entry), Name);
if ( lpmdi->fRealMode ) {
xosd = xosdNone;
ModuleEntryFlat(Entry) = FALSE;
ModuleEntryReal(Entry) = TRUE;
ModuleEntryBase(Entry) = 0xBAD00BAD;
ModuleEntryLimit(Entry) = 0xBAD00BAD;
Count++;
} else {
xosd = SendRequestX( dmfQuerySelector,
hpid,
NULL,
sizeof(SEGMENT),
&Selector );
if (xosd == xosdNone) {
_fmemcpy( &Ldt, LpDmMsg->rgb, sizeof(Ldt));
Base = (Ldt.HighWord.Bits.BaseHi << 0x18) |
(Ldt.HighWord.Bits.BaseMid << 0x10) |
Ldt.BaseLow;
Limit = (Ldt.HighWord.Bits.LimitHi << 0x10) |
Ldt.LimitLow;
ModuleEntryFlat(Entry) = FALSE;
ModuleEntryReal(Entry) = FALSE;
ModuleEntryBase(Entry) = Base;
ModuleEntryLimit(Entry) = Limit;
Count++;
} else {
xosd = xosdNone;
ModuleEntryFlat(Entry) = FALSE;
ModuleEntryReal(Entry) = FALSE;
ModuleEntryBase(Entry) = 0xBAD00BAD;
ModuleEntryLimit(Entry) = 0xBAD00BAD;
Count++;
}
}
}
}
}
}
if (hmdi) {
LLUnlock(hmdi);
}
ModuleListCount(ModList) = Count;
*lplpModuleList = ModList;
Done:
return xosd;
}
XOSD
DoContinue(
HPID hpid
)
{
LPPRC lpprc;
HPRC hprc = HprcFromHpid(hpid);
XOSD xosd = xosdUnknown;
BYTE b = 1;
assert(hprc);
lpprc = LLLock(hprc);
if (lpprc->fLoadingModule) {
lpprc->fRunning = TRUE;
lpprc->fLoadingModule = FALSE;
CallTL ( tlfReply, hpid, 1, &b );
xosd = xosdNone;
} else if (lpprc->fUnloadingModule) {
lpprc->fRunning = TRUE;
lpprc->fUnloadingModule = FALSE;
CallTL ( tlfReply, hpid, 1, &b );
xosd = xosdNone;
}
LLUnlock(hprc);
return xosd;
}
XOSD
DoCustomCommand(
HPID hpid,
HTID htid,
DWORD wValue,
LPSSS lpsss
)
{
LPSTR lpsz = lpsss->rgbData;
LPSTR p;
XOSD xosd;
char cmd[256];
//
// parse the command from the command line
//
p = cmd;
while (*lpsz && !isspace(*lpsz)) {
*p++ = *lpsz++;
}
*p = '\0';
//
// this is where you would _stricmp() for your custom em command
// otherwise it is passed to the dm
//
return SendRequestX( dmfSystemService, hpid, htid, wValue, (LPVOID) lpsss );
//
// this is what would be executed if you have a custom em command
// instead of the above sendrequest()
//
#if 0
strcpy( lpiol->rgbVar, lpsz );
xosd = IoctlCmd(hpid, htid, wValue, lpiol);
return xosd;
#endif
} /* DoCustomCommand */
XOSD
SystemService(
HPID hpid,
HTID htid,
DWORD wValue,
LPSSS lpsss
)
/*++
Routine Description:
This function examines SystemService requests (escapes) and deals
with those which the EM knows about. All others are passed on to
the DM for later processing.
Arguments:
argument-name - Supplies | Returns description of argument.
.
.
Return Value:
return-value - Description of conditions needed to return value. - or -
None.
--*/
{
XOSD xosd;
DWORD dw;
HPRC hprc;
HTHD hthd;
LPTHD lpthd;
switch( lpsss-> ssvc ) {
case ssvcGetStackFrame:
hprc = HprcFromHpid( hpid );
hthd = HthdFromHtid ( hprc, htid );
assert(hthd);
lpthd = LLLock(hthd);
_fmemcpy(lpsss->rgbData, &lpthd->StackFrame, sizeof(STACKFRAME));
lpsss->cbReturned = sizeof(STACKFRAME);
xosd = xosdNone;
break;
case ssvcGetThreadContext:
xosd = SendRequest ( dmfReadReg, hpid, htid );
if (xosd == xosdNone) {
xosd = LpDmMsg->xosdRet;
dw = min(lpsss->cbSend, sizeof(CONTEXT));
_fmemcpy (lpsss->rgbData, LpDmMsg->rgb, dw);
lpsss->cbReturned = dw;
}
break;
case ssvcSetThreadContext:
xosd = SendRequestX( dmfWriteReg, hpid, htid, lpsss->cbSend,
lpsss->rgbData );
break;
case ssvcGetProcessHandle:
case ssvcGetThreadHandle:
xosd = SendRequestX(dmfSystemService,hpid, htid, wValue, (LPVOID)lpsss);
if (xosd == xosdNone) {
xosd = LpDmMsg->xosdRet;
dw = min(lpsss->cbSend, sizeof(HANDLE));
_fmemcpy (lpsss->rgbData, LpDmMsg->rgb, dw);
lpsss->cbReturned = dw;
}
break;
case ssvcCustomCommand:
xosd = DoCustomCommand(hpid, htid, wValue, lpsss);
break;
case ssvcGetPrompt:
xosd = SendRequestX(dmfSystemService, hpid, htid, wValue, (LPVOID)lpsss);
if (xosd == xosdNone) {
xosd = LpDmMsg->xosdRet;
lpsss->cbReturned = ((LPPROMPTMSG)((LPSSS)LpDmMsg->rgb))->len + sizeof(PROMPTMSG);
if (lpsss->cbReturned) {
_fmemcpy((LPVOID)lpsss->rgbData,
LpDmMsg->rgb,
lpsss->cbReturned);
}
}
break;
case ssvcGeneric:
xosd = SendRequestX(dmfSystemService,hpid,htid,wValue,(LPVOID)lpsss);
if (xosd == xosdNone) {
xosd = LpDmMsg->xosdRet;
lpsss->cbReturned = *((LPDWORD)LpDmMsg->rgb);
if (lpsss->cbReturned) {
_fmemcpy ( (LPVOID)lpsss->rgbData,
LpDmMsg->rgb + sizeof(DWORD),
lpsss->cbReturned);
}
}
break;
default:
xosd = SendRequestX(dmfSystemService,hpid,htid,wValue,(LPVOID)lpsss);
break;
}
return xosd;
}
#endif // OSDEBUG4
XOSD
RangeStep (
HPID hpid,
HTID htid,
LPRSS lprss
)
/*++
Routine Description:
This function is called to implement range steps in the EM. A range
step is defined as step all instructions as long as the program counter
remains within the starting and ending addresses.
Arguments:
hpid - Supplies the handle of the process to be stepped
htid - Supplies the handle of thread to be stepped
Return Value:
XOSD error code
--*/
{
XOSD xosd = xosdNone;
RST rst = {0};
UpdateChild ( hpid, htid, dmfRangeStep );
rst.fStepOver = lprss->lpExop->fStepOver;
rst.fAllThreads = !lprss->lpExop->fSingleThread;
rst.fInitialBP = lprss->lpExop->fInitialBP;
rst.offStart = lprss->lpaddrMin->addr.off;
rst.offEnd = lprss->lpaddrMax->addr.off;
return SendRequestX (
dmfRangeStep,
hpid,
htid,
sizeof ( RST ),
&rst
);
} /* RangeStep() */
XOSD
SingleStep (
HPID hpid,
HTID htid,
LPEXOP lpexop
)
{
assert ( hpid != NULL );
assert ( htid != NULL );
UpdateChild ( hpid, htid, dmfSingleStep );
return SendRequestX (
dmfSingleStep,
hpid,
htid,
sizeof(EXOP),
lpexop
);
}