static void WritePharSimple( unsigned_32 start ) /**********************************************/ { simple_header header; unsigned_32 file_size; unsigned_32 header_size; unsigned_32 extra; unsigned_32 temp; if( FmtData.type & MK_PHAR_REX ) { SeekLoad( start + sizeof(simple_header) ); extra = start + sizeof( simple_header ) + WritePharRelocs(); header_size = MAKE_PARA( extra ); PadLoad( header_size - extra ); } else { SeekLoad( start + MAKE_PARA( sizeof(simple_header) ) ); header_size = MAKE_PARA( sizeof(simple_header) ); // para align. } file_size = header_size + WritePharData( start + header_size ); DBIWrite(); if( FmtData.type & MK_PHAR_SIMPLE ) { _HostU16toTarg( SIMPLE_SIGNATURE, header.signature ); } else { _HostU16toTarg( REX_SIGNATURE, header.signature ); } _HostU16toTarg( file_size % 512U, header.mod_size ); _HostU16toTarg( (file_size + 511U) / 512U, header.file_size ); _HostU16toTarg( Root->relocs, header.num_relocs ); _HostU16toTarg( header_size / 16, header.hdr_size ); extra = MemorySize() - file_size + header_size + 0xfff; temp = FmtData.u.phar.mindata + extra; if( temp < FmtData.u.phar.mindata ) temp = 0xffffffff; _HostU16toTarg( temp >> 12, header.min_data ); temp = FmtData.u.phar.maxdata + extra; if( temp < FmtData.u.phar.maxdata ) temp = 0xffffffff; _HostU16toTarg( temp >> 12, header.max_data ); _HostU32toTarg( StackAddr.off, header.ESP ); _HostU16toTarg( 0, header.checksum ); _HostU32toTarg( StartInfo.addr.off, header.EIP ); _HostU16toTarg( 0x1E, header.reloc_offset ); _HostU16toTarg( 0, header.overlay_num ); /* allow header size to exceed 1M */ _HostU16toTarg( (header_size / (16*0x10000ul)) + 1, header.always_one ); SeekLoad( start ); WriteLoad( &header, sizeof( simple_header ) ); if( FmtData.type & MK_PHAR_SIMPLE ) { PadLoad( 2 ); // header occupies a full paragraph. } }
static void WriteDOSSectRelocs( section *sect, bool repos ) /*********************************************************/ /* write all relocs associated with sect to the file */ { unsigned long loc; OUTFILELIST *out; if( sect->relocs != 0 ) { loc = sect->u.file_loc + MAKE_PARA( sect->size ); out = sect->outfile; if( out->file_loc > loc ) { SeekLoad( loc ); } else { if( repos ) { SeekLoad( out->file_loc ); } if( out->file_loc < loc ) { PadLoad( loc - out->file_loc ); out->file_loc = loc; } } loc += sect->relocs * sizeof( dos_addr ); DumpRelocList( sect->reloclist ); if( loc > out->file_loc ) { out->file_loc = loc; } } }
static bool WriteCOMGroup( group_entry *group, signed long chop ) /***************************************************************/ /* write the data for group to the loadfile */ /* returns TRUE if the file should be repositioned */ { unsigned long loc; signed long diff; section *sect; bool repos; outfilelist *finfo; repos = FALSE; sect = group->section; CurrSect = sect; finfo = sect->outfile; loc = SUB_ADDR( group->grp_addr, sect->sect_addr ) + sect->u.file_loc; diff = loc - finfo->file_loc; if( diff > 0 ) { PadLoad( diff ); } else if( diff != 0 ) { SeekLoad( loc ); repos = TRUE; } DEBUG((DBG_LOADDOS, "group %a section %d to %l in %s", &group->grp_addr, sect->ovl_num, loc, finfo->fname )); COMAmountWritten = 0; Ring2Lookup( group->leaders, DoCOMGroup, &chop ); loc += COMAmountWritten; if( loc > finfo->file_loc ) { finfo->file_loc = loc; } return( repos ); }
static bool WriteCOMGroup( group_entry *group, soffset chop ) /***********************************************************/ /* write the data for group to the loadfile */ /* returns true if the file should be repositioned */ { unsigned long file_loc; section *sect; bool repos; outfilelist *finfo; repos = false; sect = group->section; CurrSect = sect; finfo = sect->outfile; file_loc = GROUP_FILE_LOC( group ); if( file_loc > finfo->file_loc ) { PadLoad( file_loc - finfo->file_loc ); } else if( file_loc < finfo->file_loc ) { SeekLoad( file_loc ); repos = true; } DEBUG((DBG_LOADDOS, "group %a section %d to %l in %s", &group->grp_addr, sect->ovl_num, file_loc, finfo->fname )); COMAmountWritten = 0; Ring2Lookup( group->leaders, DoCOMGroup, &chop ); file_loc += COMAmountWritten; if( file_loc > finfo->file_loc ) { finfo->file_loc = file_loc; } return( repos ); }
static bool WriteSegData( void *_sdata, void *_start ) /****************************************************/ { segdata *sdata = _sdata; soffset *start = _start; soffset newpos; soffset pad; if( !sdata->isuninit && !sdata->isdead ) { newpos = *start + sdata->a.delta; if( newpos + (soffset)sdata->length > 0 ) { if( newpos > COMAmountWritten ) { pad = newpos - COMAmountWritten; PadLoad( pad ); WriteInfoLoad( sdata->u1.vm_ptr, sdata->length ); COMAmountWritten += sdata->length + pad; } else { pad = COMAmountWritten - newpos; WriteInfoLoad( sdata->u1.vm_ptr + pad, sdata->length - pad ); COMAmountWritten += sdata->length - pad; } } } return( false ); }
static bool WriteSegData( void *_sdata, void *_start ) /****************************************************/ { segdata *sdata = _sdata; unsigned long *start = _start; unsigned long newpos; unsigned long pad; if( !sdata->isuninit && !sdata->isdead ) { newpos = *start + sdata->a.delta; if( newpos + (unsigned long)sdata->length < newpos ) return( FALSE ); if( newpos > COMAmountWritten ) { pad = newpos - COMAmountWritten; PadLoad( pad ); WriteInfoLoad( sdata->u1.vm_ptr, sdata->length ); COMAmountWritten += sdata->length + pad; } else { pad = COMAmountWritten - newpos; WriteInfoLoad( sdata->u1.vm_ptr + pad, sdata->length - pad ); COMAmountWritten += sdata->length - pad; } } return( FALSE ); }
WResFileOffset res_seek( WResFileID fid, WResFileOffset amount, int where ) { if( fid == hInstance.fid ) { if( where == SEEK_SET ) { return( lseek( WRES_FID2PH( fid ), amount + WResFileShift, where ) - WResFileShift ); } else { return( lseek( WRES_FID2PH( fid ), amount, where ) ); } } DbgAssert( where != SEEK_END ); DbgAssert( !(where == SEEK_CUR && amount < 0) ); if( WRES_FID2PH( fid ) == Root->outfile->handle ) { if( where == SEEK_CUR ) { unsigned long old_pos; unsigned long new_pos; old_pos = PosLoad(); new_pos = old_pos + amount; if( new_pos > old_pos ) { PadLoad( (size_t)amount ); } else { SeekLoad( new_pos ); } return( new_pos ); } else { SeekLoad( amount ); return( amount ); } } else { return( QLSeek( WRES_FID2PH( fid ), amount, where, "resource file" ) ); } }
static void WriteRDOSData( void ) /**********************************************************/ /* copy code from extra memory to loadfile */ { group_entry *group; SECTION *sect; struct seg_leader *leader; SEGDATA *piece; int iscode; int isdata; DEBUG(( DBG_BASE, "Writing data" )); /* write groups and relocations */ for( group = Groups; group != NULL; ) { if( leader != group->leaders ) { iscode = 0; isdata = 0; leader = group->leaders; if( leader && leader->size && Extension == E_RDV ) { piece = leader->pieces; if( piece ) { if( piece->iscode && ( leader->seg_addr.seg == FmtData.u.rdos.code_seg ) ) { iscode = 1; } if( ( piece->isidata || piece->isuninit ) && ( leader->seg_addr.seg == FmtData.u.rdos.data_seg ) ) { isdata = 1; } } } } sect = group->section; CurrSect = sect; if( isdata ) { sect->u.file_loc = HeaderSize + CodeSize + DataSize; if( StackSegPtr != NULL ) { if( group->totalsize - group->size < StackSize ) { StackSize = group->totalsize - group->size; group->totalsize = group->size; } else { group->totalsize -= StackSize; } } WriteDOSGroup( group ); if( group->totalsize > group->size ) PadLoad( group->totalsize - group->size ); DataSize += group->totalsize; } group = group->next_group; } }
static void WriteRDOSCode( void ) /**********************************************************/ { group_entry *group; SECTION *sect; struct seg_leader *leader; SEGDATA *piece; int iscode; int isdata; DEBUG(( DBG_BASE, "Writing code" )); OrderGroups( CompareDosSegments ); CurrSect = Root; // needed for WriteInfo. Root->outfile->file_loc = Root->u.file_loc; Root->sect_addr = Groups->grp_addr; leader = 0; /* write groups and relocations */ for( group = Groups; group != NULL; ) { if( leader != group->leaders ) { iscode = 0; isdata = 0; leader = group->leaders; if( leader && leader->size && Extension == E_RDV ) { piece = leader->pieces; if( piece ) { if( piece->iscode && ( leader->seg_addr.seg == FmtData.u.rdos.code_seg ) ) { iscode = 1; } if( ( piece->isidata || piece->isuninit ) && ( leader->seg_addr.seg == FmtData.u.rdos.data_seg ) ) { isdata = 1; } } } } sect = group->section; CurrSect = sect; if( iscode ) { sect->u.file_loc = HeaderSize + CodeSize; WriteDOSGroup( group ); if( group->totalsize > group->size ) PadLoad( group->totalsize - group->size ); CodeSize += group->totalsize; } group = group->next_group; } }
static bool WriteSegData( void *_sdata, void *_start ) /****************************************************/ { segdata *sdata = _sdata; signed long *start = _start; signed long newpos; signed long pad; if( !sdata->isuninit && !sdata->isdead ) { newpos = *start + sdata->a.delta; if( newpos + (signed long)sdata->length <= 0 ) return( FALSE ); pad = newpos - COMAmountWritten; if( pad > 0 ) { PadLoad( pad ); COMAmountWritten += pad; pad = 0; } WriteInfo( sdata->data - pad, sdata->length + pad ); COMAmountWritten += sdata->length + pad; } return( FALSE ); }
static void ZeroLoad( virt_mem dummy, unsigned long length ) /**********************************************************/ { dummy = dummy; PadLoad( length ); }