Bugfix: Improved GetCodeHandle16 / GetCodeInfo16.

oldstable
Ulrich Weigand 1999-09-20 15:30:27 +00:00 committed by Alexandre Julliard
parent 5b2415da69
commit a2d5bb393a
2 changed files with 91 additions and 46 deletions

View File

@ -54,7 +54,7 @@ FARPROC16 WINAPI FileCDR16(FARPROC16);
WORD WINAPI FreeSelector16(WORD); WORD WINAPI FreeSelector16(WORD);
HANDLE16 WINAPI GetAtomHandle16(ATOM); HANDLE16 WINAPI GetAtomHandle16(ATOM);
HANDLE16 WINAPI GetCodeHandle16(FARPROC16); HANDLE16 WINAPI GetCodeHandle16(FARPROC16);
VOID WINAPI GetCodeInfo16(FARPROC16,SEGINFO*); BOOL16 WINAPI GetCodeInfo16(FARPROC16,SEGINFO*);
DWORD WINAPI GetCurrentPDB16(void); DWORD WINAPI GetCurrentPDB16(void);
HTASK16 WINAPI GetCurrentTask(void); HTASK16 WINAPI GetCurrentTask(void);
SEGPTR WINAPI GetDOSEnvironment16(void); SEGPTR WINAPI GetDOSEnvironment16(void);

View File

@ -971,72 +971,117 @@ void WINAPI FreeProcInstance16( FARPROC16 func )
TASK_FreeThunk( GetCurrentTask(), (SEGPTR)func ); TASK_FreeThunk( GetCurrentTask(), (SEGPTR)func );
} }
/**********************************************************************
* TASK_GetCodeSegment
*
* Helper function for GetCodeHandle/GetCodeInfo: Retrieve the module
* and logical segment number of a given code segment.
*
* 'proc' either *is* already a pair of module handle and segment number,
* in which case there's nothing to do. Otherwise, it is a pointer to
* a function, and we need to retrieve the code segment. If the pointer
* happens to point to a thunk, we'll retrieve info about the code segment
* where the function pointed to by the thunk resides, not the thunk itself.
*
* FIXME: if 'proc' is a SNOOP16 return stub, we should retrieve info about
* the function the snoop code will return to ...
*
*/
static BOOL TASK_GetCodeSegment( FARPROC16 proc, NE_MODULE **ppModule,
SEGTABLEENTRY **ppSeg, int *pSegNr )
{
NE_MODULE *pModule = NULL;
SEGTABLEENTRY *pSeg = NULL;
int segNr;
/* Try pair of module handle / segment number */
pModule = (NE_MODULE *) GlobalLock16( HIWORD( proc ) );
if ( pModule && pModule->magic == IMAGE_OS2_SIGNATURE )
{
segNr = LOWORD( proc );
if ( segNr && segNr <= pModule->seg_count )
pSeg = NE_SEG_TABLE( pModule ) + segNr-1;
}
/* Try thunk or function */
else
{
BYTE *thunk = (BYTE *)PTR_SEG_TO_LIN( proc );
WORD selector;
if ((thunk[0] == 0xb8) && (thunk[3] == 0xea))
selector = thunk[6] + (thunk[7] << 8);
else
selector = HIWORD( proc );
pModule = NE_GetPtr( GlobalHandle16( selector ) );
pSeg = pModule? NE_SEG_TABLE( pModule ) : NULL;
if ( pModule )
for ( segNr = 1; segNr <= pModule->seg_count; segNr++, pSeg++ )
if ( GlobalHandleToSel16(pSeg->hSeg) == selector )
break;
if ( pModule && segNr > pModule->seg_count )
pSeg = NULL;
}
/* Abort if segment not found */
if ( !pModule || !pSeg )
return FALSE;
/* Return segment data */
if ( ppModule ) *ppModule = pModule;
if ( ppSeg ) *ppSeg = pSeg;
if ( pSegNr ) *pSegNr = segNr;
return TRUE;
}
/********************************************************************** /**********************************************************************
* GetCodeHandle (KERNEL.93) * GetCodeHandle (KERNEL.93)
*/ */
HANDLE16 WINAPI GetCodeHandle16( FARPROC16 proc ) HANDLE16 WINAPI GetCodeHandle16( FARPROC16 proc )
{ {
HANDLE16 handle; SEGTABLEENTRY *pSeg;
BYTE *thunk = (BYTE *)PTR_SEG_TO_LIN( proc );
/* Return the code segment containing 'proc'. */ if ( !TASK_GetCodeSegment( proc, NULL, &pSeg, NULL ) )
/* Not sure if this is really correct (shouldn't matter that much). */ return (HANDLE16)0;
/* Check if it is really a thunk */ return pSeg->hSeg;
if ((thunk[0] == 0xb8) && (thunk[3] == 0xea))
handle = GlobalHandle16( thunk[6] + (thunk[7] << 8) );
else
handle = GlobalHandle16( HIWORD(proc) );
return handle;
} }
/********************************************************************** /**********************************************************************
* GetCodeInfo (KERNEL.104) * GetCodeInfo (KERNEL.104)
*/ */
VOID WINAPI GetCodeInfo16( FARPROC16 proc, SEGINFO *segInfo ) BOOL16 WINAPI GetCodeInfo16( FARPROC16 proc, SEGINFO *segInfo )
{ {
BYTE *thunk = (BYTE *)PTR_SEG_TO_LIN( proc ); NE_MODULE *pModule;
NE_MODULE *pModule = NULL; SEGTABLEENTRY *pSeg;
SEGTABLEENTRY *pSeg = NULL; int segNr;
WORD segNr;
/* proc is either a thunk, or else a pair of module handle if ( !TASK_GetCodeSegment( proc, &pModule, &pSeg, &segNr ) )
and segment number. In the first case, we also need to return FALSE;
extract module and segment number. */
if ((thunk[0] == 0xb8) && (thunk[3] == 0xea)) /* Fill in segment information */
{
WORD selector = thunk[6] + (thunk[7] << 8);
pModule = NE_GetPtr( GlobalHandle16( selector ) );
pSeg = pModule? NE_SEG_TABLE( pModule ) : NULL;
if ( pModule ) segInfo->offSegment = pSeg->filepos;
for ( segNr = 0; segNr < pModule->seg_count; segNr++, pSeg++ ) segInfo->cbSegment = pSeg->size;
if ( GlobalHandleToSel16(pSeg->hSeg) == selector ) segInfo->flags = pSeg->flags;
break; segInfo->cbAlloc = pSeg->minsize;
segInfo->h = pSeg->hSeg;
segInfo->alignShift = pModule->alignment;
if ( pModule && segNr >= pModule->seg_count ) if ( segNr == pModule->dgroup )
pSeg = NULL; segInfo->cbAlloc += pModule->heap_size + pModule->stack_size;
}
else
{
pModule = NE_GetPtr( HIWORD( proc ) );
segNr = LOWORD( proc );
if ( pModule && segNr < pModule->seg_count ) /* Return module handle in %es */
pSeg = NE_SEG_TABLE( pModule ) + segNr;
}
/* fill in segment information */ CURRENT_STACK16->es = GlobalHandleToSel16( pModule->self );
segInfo->offSegment = pSeg? pSeg->filepos : 0; return TRUE;
segInfo->cbSegment = pSeg? pSeg->size : 0;
segInfo->flags = pSeg? pSeg->flags : 0;
segInfo->cbAlloc = pSeg? pSeg->minsize : 0;
segInfo->h = pSeg? pSeg->hSeg : 0;
segInfo->alignShift = pModule? pModule->alignment : 0;
} }