/* * DIPCliMapAddr * Possibilites: * 1) We are mapping segments for a 32-bit extended app. In this case, * we return the segment:offset returned by CheckIsModuleWin32App * 2) We are mapping a segment for a 16-bit app that is NOT a load * on call segment. In this case, GlobalEntryModule works and * we return the value we obtain from it * 3) We are mapping a segment for a 16-bit app that IS a load * on call segment. In this case, GlobalEntryModule FAILS (stupid * f*cking Windows) and so we have to go find it ourselves using * horkyFindSegment. */ void DIGCLIENT DIPCliMapAddr( addr_ptr *addr, void *info ) { GLOBALENTRY ge; LPVOID ptr; WORD sel; WORD cs,ds; DWORD off; DEBUGOUT( "mapaddr" ); info = info; if( CheckIsModuleWin32App( DTModuleEntry.hModule, &ds, &cs, &off ) ) { addr->segment = cs; addr->offset = off; } else { ge.dwSize = sizeof( ge ); if( !GlobalEntryModule( &ge, DTModuleEntry.hModule, addr->segment ) ) { addr->segment = horkyFindSegment( DTModuleEntry.hModule, addr->segment ); } ptr = GlobalLock( ge.hBlock ); GlobalUnlock( ge.hBlock ); sel = FP_SEG( ptr ); if( sel == NULL ) { sel = (WORD)ge.hBlock + 1; } addr->segment = sel; addr->offset = 0; } }
/* * try32: * * see if a module is a Win386 app. If it is, then we add it to a list * of 32-bit apps, so that we can give the segment aliases for them later. */ static void try32( HANDLE mod ) { DWORD off; WORD ds; WORD cs; if( CheckIsModuleWin32App( mod, &ds, &cs, &off ) ) { modules32[ mod32Top ] = mod; mod32Top++; } } /* try32 */
/* * ReqGet_next_alias * * Get next alias, for 32-bit extender apps only * We maintain a list of all apps that are 32-bit, and return the * aliases for each of them. */ trap_retval ReqGet_next_alias( void ) { get_next_alias_req *acc; get_next_alias_ret *ret; WORD ds,cs; DWORD off; acc = GetInPtr( 0 ); ret = GetOutPtr( 0 ); ret->seg = 0; ret->alias = 0; if( mod32Top > 0 ) { mod32Top--; CheckIsModuleWin32App( modules32[ mod32Top ], &ds, &cs, &off ); ret->seg = cs; ret->alias = ds; } return( sizeof( *ret ) ); }
/* * ReqMap_addr * * Access request to map a segment number to a selector. * Possibilites: * 1) We are mapping segments for a 32-bit extended app. In this case, * we return the segment:offset returned by CheckIsModuleWin32App * 2) We are mapping a segment for a 16-bit app that is NOT a load * on call segment. In this case, GlobalEntryModule works and * we return the value we obtain from it * 3) We are mapping a segment for a 16-bit app that IS a load * on call segment. In this case, GlobalEntryModule FAILS (stupid * f*cking Windows) and so we have to go find it ourselves using * horkyFindSegment. Once horkyFindSegment is done, GlobalEntryModule * will give the right answer, and we return the value we obtain from it. */ trap_retval ReqMap_addr( void ) { GLOBALENTRY ge; LPVOID ptr; WORD sel; WORD cs,ds; DWORD off; int module; addr_seg in_seg; map_addr_req *acc; map_addr_ret *ret; acc = GetInPtr( 0 ); ret = GetOutPtr( 0 ); ret->out_addr = acc->in_addr; ret->lo_bound = 0; ret->hi_bound = ~(addr48_off)0; module = acc->handle; in_seg = acc->in_addr.segment; if( CheckIsModuleWin32App( moduleIDs[ module ], &ds, &cs, &off ) ) { Out((OUT_MAP,"is 32 bit module")); if( in_seg == MAP_FLAT_DATA_SELECTOR ) { ret->out_addr.segment = ds; } else { ret->out_addr.segment = cs; } ret->out_addr.offset = off; } else { switch( in_seg ) { case MAP_FLAT_CODE_SELECTOR: case MAP_FLAT_DATA_SELECTOR: in_seg = 1; break; } ge.dwSize = sizeof( ge ); if( !GlobalEntryModule( &ge, moduleIDs[ module ], in_seg ) ) { if( horkyFindSegment( module, in_seg ) ) { if( !GlobalEntryModule( &ge, moduleIDs[ module ], in_seg ) ) { Out((OUT_MAP,"GlobalEntry 2nd time failed" )); return( sizeof( *ret ) ); } } else { Out(( OUT_MAP,"Well I'll be! horkyFindSegment failed" )); return( sizeof( *ret ) ); } } ptr = GlobalLock( ge.hBlock ); GlobalUnlock( ge.hBlock ); sel = FP_SEG( ptr ); if( sel == NULL ) { sel = (WORD)ge.hBlock + 1; } ret->out_addr.segment = sel; ret->out_addr.offset = 0; } ret->out_addr.offset += acc->in_addr.offset; if( module == 0 ) { Out(( OUT_MAP,"in=%4.4x:%8.8lx out=%4.4x:%8.8lx", acc->in_addr.segment, acc->in_addr.offset, ret->out_addr.segment, ret->out_addr.offset )); } return( sizeof( *ret ) ); }
/* * newModule - handle a new module */ static void newModule( HANDLE hmod, char *name, samp_block_kinds kind ) { GLOBALENTRY ge; os2_exe_header ne; dos_exe_header de; seg_offset ovl; int i; LPVOID ptr; WORD sel; int handle; int numsegs; WORD win32ds; WORD win32cs; DWORD win32initialeip; int rc; ovl.offset = 0; ovl.segment = 0; rc = CheckIsModuleWin32App( hmod, &win32ds, &win32cs, &win32initialeip ); if( rc ) { if( win32ds != 0 ) { WriteCodeLoad( ovl, name, kind ); WriteAddrMap( 1, win32cs, win32initialeip ); WriteAddrMap( 2, win32ds, 0 ); } else if( kind == SAMP_MAIN_LOAD ) { FlagWin32AppAsDebugged( hmod ); WaitForInt3 = GetCurrentTask(); } else if( WaitForInt1 == 0 ) { FlagWin32AppAsDebugged( hmod ); WaitForInt1 = hmod; } return; } WriteCodeLoad( ovl, name, kind ); handle = open( name,O_BINARY | O_RDONLY ); if( handle >= 0 ) { read( handle, &de, sizeof( de ) ); if( de.signature == DOS_SIGNATURE ) { lseek( handle, ( de.file_size - 1L ) * 512L + (long)de.mod_size, SEEK_SET ); } else { lseek( handle, 0, SEEK_SET ); } read( handle, &ne, sizeof( ne ) ); if( ne.signature == OS2_SIGNATURE_WORD ) { numsegs = ne.segments; if( numsegs > 8192 ) { // must not really be a valid OS2 sig. numsegs = -1; } } else { numsegs = -1; } close( handle ); } for( i = 1; i < 8192; i++ ) { if( !MyGlobalEntryModule( &ge, hmod, i ) ) { if( numsegs > 0 ) { sel = horkyFindSegment( hmod, i ); if( sel == 0 ) { continue; } } else { continue; } } else { if( ge.hBlock != NULL ) { ptr = GlobalLock( ge.hBlock ); GlobalUnlock( ge.hBlock ); sel = FP_SEG( ptr ); if( sel == NULL ) { sel = (WORD)ge.hBlock + 1; } } else { continue; } } WriteAddrMap( i, sel, 0 ); numsegs--; if( numsegs == 0 ) { break; } } } /* newModule */