📄 exeseg.c
字号:
RcError( ERR_WRITTING_FILE, outexe->name, strerror( errno ) );
}
if (!error) {
align_amount = AlignAmount( out_offset, new_shift_count );
iorc = RcSeek( outexe->Handle, align_amount, SEEK_CUR );
if( iorc == -1 ) {
error = TRUE;
RcError( ERR_WRITTING_FILE, outexe->name, strerror( errno ) );
}
out_offset += align_amount;
}
/* move in the in file to the start of the segment */
if (!error) {
/* convert the address to a long before shifting it */
iorc = RcSeek( inexe->Handle,
(long) inseg->address << old_shift_count, SEEK_SET );
if( iorc == -1 ) {
error = TRUE;
RcError( ERR_READING_EXE, inexe->name, strerror( errno ) );
}
}
if (!error) {
if (inseg->size == 0) {
seg_len = 0x10000L;
} else {
seg_len = inseg->size;
}
error = myCopyExeData( inexe, outexe, seg_len );
}
if (inseg->info & SEG_RELOC && !error) {
/* read the number of relocation items */
iorc = RcRead( inexe->Handle, &numrelocs, sizeof(uint_16) );
if( iorc != sizeof( uint_16 ) ) {
error = TRUE;
if( iorc == -1 ) {
RcError( ERR_READING_EXE, inexe->name, strerror( errno ) );
} else {
RcError( ERR_UNEXPECTED_EOF, inexe->name );
}
} else {
iorc = RcWrite( outexe->Handle, &numrelocs, sizeof(uint_16) );
if( iorc != sizeof( uint_16 ) ) {
error = TRUE;
RcError( ERR_WRITTING_FILE, outexe->name,
strerror( errno ) );
}
}
/* copy the relocation information */
if (!error) {
error = myCopyExeData( inexe, outexe,
numrelocs * OS_RELOC_ITEM_SIZE );
}
if (numrelocs * OS_RELOC_ITEM_SIZE + seg_len > 0x10000L) {
ret = CPSEG_SEG_TOO_BIG;
}
}
if (pad_end && ret != CPSEG_SEG_TOO_BIG && !error) {
align_amount = AlignAmount( RcTell( outexe->Handle ),
new_shift_count );
/* make sure there is room for the memory arena header */
if (align_amount < 16) {
align_amount += 16;
}
iorc = RcSeek( outexe->Handle, align_amount - 1, SEEK_CUR );
if( iorc == -1 ) {
error = TRUE;
RcError( ERR_WRITTING_FILE, outexe->name );
} else {
/* write something out so if we have just seeked past the
* end of the file the file's size will be adjusted
* appropriately */
iorc = RcWrite( outexe->Handle, &dum, 1 );
if( iorc != 1 ) {
error = TRUE;
RcError( ERR_WRITTING_FILE, outexe->name );
}
}
}
} else {
out_offset = 0;
}
/* copy the segment record to outseg */
if (!error) {
outseg->size = inseg->size;
outseg->info = inseg->info;
outseg->min = inseg->min;
outseg->address = out_offset >> new_shift_count;
}
if (error) {
ret = CPSEG_ERROR;
}
return( ret );
} /* copyOneSegment */
extern CpSegRc CopySegments( uint_16 sect2mask, uint_16 sect2bits, bool sect2 )
/*****************************************************************************/
/* Note: sect2 must be either 1 (do section 2) or 0 (do section 1) */
/* CopySegments should be called twice, once with sect2 false, and once with */
/* it true. The values of sect2mask and sect2bits should be the same for both */
/* calls. The segment table for the temporary file will not be properly */
/* filled in until after the second call */
{
segment_record * oldseg;
segment_record * tmpseg;
bool padend;
int num_segs;
ExeFileInfo *old_exe_info;
ExeFileInfo *tmp_exe_info;
int old_shift_count;
int new_shift_count;
int currseg;
CpSegRc cponeret;
CpSegRc ret;
oldseg = Pass2Info.OldFile.u.NEInfo.Seg.Segments;
tmpseg = Pass2Info.TmpFile.u.NEInfo.Seg.Segments;
num_segs = Pass2Info.OldFile.u.NEInfo.Seg.NumSegs;
old_exe_info = &Pass2Info.OldFile;
tmp_exe_info = &Pass2Info.TmpFile;
old_shift_count = Pass2Info.OldFile.u.NEInfo.WinHead.align;
new_shift_count = Pass2Info.TmpFile.u.NEInfo.WinHead.align;
ret = CPSEG_OK;
cponeret = CPSEG_OK;
padend = !sect2;
currseg = 0;
while (currseg < num_segs) {
/* if the bits are unequal and this is section 1 --> copy segment */
/* if the bits are equal and this is section 2 --> copy segment */
/* otherwise --> do nothing */
if (ARE_BITS_EQUAL( sect2mask, sect2bits, oldseg->info ) == sect2) {
cponeret = copyOneSegment( oldseg, tmpseg, old_exe_info,
tmp_exe_info, old_shift_count,
new_shift_count, padend );
if (cponeret == CPSEG_SEG_TOO_BIG) {
padend = FALSE;
ret = CPSEG_SEG_TOO_BIG;
}
CheckDebugOffset( &(Pass2Info.OldFile) );
CheckDebugOffset( &(Pass2Info.TmpFile) );
}
if (cponeret == CPSEG_ERROR) break;
/* mark section 1 segments as preload */
if (!sect2) {
tmpseg->info |= SEG_PRELOAD;
}
currseg++;
oldseg++;
tmpseg++;
}
if (cponeret == CPSEG_ERROR) {
ret = CPSEG_ERROR;
Pass2Info.TmpFile.u.NEInfo.Seg.NumSegs = 0;
} else {
Pass2Info.TmpFile.u.NEInfo.Seg.NumSegs =
Pass2Info.OldFile.u.NEInfo.Seg.NumSegs;
}
return( ret );
} /* CopySegments */
extern CpSegRc CopyOS2Segments( void )
/*************************************
* Akin to CopySegments() only much, much simpler - just copies all segments
* without messing with them in any way. Only called once. Won't copy
* resource segments.
*/
{
segment_record *oldseg;
segment_record *tmpseg;
int num_segs;
SegTable *old_seg_tbl;
ExeFileInfo *old_exe_info;
ExeFileInfo *tmp_exe_info;
int old_shift_count;
int new_shift_count;
int currseg;
CpSegRc cponeret;
CpSegRc ret;
old_seg_tbl = &Pass2Info.TmpFile.u.NEInfo.Seg;
oldseg = old_seg_tbl->Segments;
tmpseg = Pass2Info.TmpFile.u.NEInfo.Seg.Segments;
num_segs = old_seg_tbl->NumSegs - old_seg_tbl->NumOS2ResSegs;
old_exe_info = &Pass2Info.OldFile;
tmp_exe_info = &Pass2Info.TmpFile;
old_shift_count = Pass2Info.OldFile.u.NEInfo.WinHead.align;
new_shift_count = Pass2Info.TmpFile.u.NEInfo.WinHead.align;
ret = CPSEG_OK;
cponeret = CPSEG_OK;
currseg = 0;
while( currseg < num_segs ) {
cponeret = copyOneSegment( oldseg, tmpseg, old_exe_info,
tmp_exe_info, old_shift_count,
new_shift_count, FALSE );
if( cponeret == CPSEG_SEG_TOO_BIG ) {
ret = CPSEG_SEG_TOO_BIG;
}
CheckDebugOffset( &(Pass2Info.OldFile) );
CheckDebugOffset( &(Pass2Info.TmpFile) );
if( cponeret == CPSEG_ERROR ) {
break;
}
currseg++;
oldseg++;
tmpseg++;
}
if( cponeret == CPSEG_ERROR ) {
ret = CPSEG_ERROR;
Pass2Info.TmpFile.u.NEInfo.Seg.NumSegs = 0;
} else if( old_seg_tbl->NumOS2ResSegs ) {
uint_32 end_offset;
int iorc;
/* Must seek past the last segment in old file */
oldseg += old_seg_tbl->NumOS2ResSegs - 1;
end_offset = (uint_32)oldseg->address << old_shift_count;
if( oldseg->size == 0 )
end_offset += 0x10000;
else
end_offset += oldseg->size;
iorc = RcSeek( old_exe_info->Handle, end_offset, SEEK_SET );
if( iorc == -1 ) {
ret = CPSEG_ERROR;
RcError( ERR_READING_EXE, old_exe_info->name, strerror( errno ) );
}
CheckDebugOffset( &(Pass2Info.OldFile) );
}
return( ret );
} /* CopyOS2Segments */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -