static RcStatus copyOneResource( ResTable *restab, FullTypeRecord *type, WResLangInfo *lang, WResResInfo *res, WResFileID reshandle, WResFileID outhandle, int shift_count, int *err_code ) /**********************************************************************/ { RcStatus ret; long out_offset; long align_amount; /* align the output file to a boundary for shift_count */ ret = RS_OK; align_amount = 0; // shut up gcc out_offset = RCTELL( outhandle ); if( out_offset == -1 ) { ret = RS_WRITE_ERROR; *err_code = errno; } if( ret == RS_OK ) { align_amount = AlignAmount( out_offset, shift_count ); if( RCSEEK( outhandle, align_amount, SEEK_CUR ) == -1 ) { ret = RS_WRITE_ERROR; *err_code = errno; } out_offset += align_amount; } if( ret == RS_OK ) { if( RCSEEK( reshandle, lang->Offset, SEEK_SET ) == -1 ) { ret = RS_READ_ERROR; *err_code = errno; } } if( ret == RS_OK ) { ret = CopyExeData( reshandle, outhandle, lang->Length ); *err_code = errno; } if( ret == RS_OK ) { align_amount = AlignAmount( RCTELL( outhandle ), shift_count ); ret = PadExeData( outhandle, align_amount ); *err_code = errno; } if( ret == RS_OK ) { addExeResRecord( restab, type, &(res->ResName), lang->MemoryFlags, out_offset >> shift_count, (lang->Length + align_amount) >> shift_count ); }
/* NB: We copy resources in one go even if they span multiple segments. * This is fine because all segments but the last one are 64K big, and * hence will be nicely aligned. */ static RcStatus copyOneResource( WResLangInfo *lang, WResFileID reshandle, WResFileID outhandle, int shift_count, int *err_code ) /************************************************************************/ { RcStatus ret; long out_offset; long align_amount; /* align the output file to a boundary for shift_count */ ret = RS_OK; out_offset = RCTELL( outhandle ); if( out_offset == -1 ) { ret = RS_WRITE_ERROR; *err_code = errno; } if( ret == RS_OK ) { align_amount = AlignAmount( out_offset, shift_count ); if( RCSEEK( outhandle, align_amount, SEEK_CUR ) == -1 ) { ret = RS_WRITE_ERROR; *err_code = errno; } out_offset += align_amount; } if( ret == RS_OK ) { if( RCSEEK( reshandle, lang->Offset, SEEK_SET ) == -1 ) { ret = RS_READ_ERROR; *err_code = errno; } } if( ret == RS_OK ) { ret = CopyExeData( reshandle, outhandle, lang->Length ); *err_code = errno; } if( ret == RS_OK ) { align_amount = AlignAmount( RCTELL( outhandle ), shift_count ); ret = PadExeData( outhandle, align_amount ); *err_code = errno; } return( ret ); } /* copyOneResource */
RcStatus CopyOS2Resources( void ) { OS2ResEntry *entry; WResDirWindow wind; OS2ResTable *restab; WResLangInfo *lang; WResFileID tmphandle; WResFileID reshandle; RcStatus ret; int err_code; int shift_count; int currseg; segment_record *tmpseg; uint_32 seg_offset; long align_amount; int i; restab = &(Pass2Info.TmpFile.u.NEInfo.OS2Res); tmphandle = Pass2Info.TmpFile.Handle; reshandle = Pass2Info.ResFiles->Handle; tmpseg = Pass2Info.TmpFile.u.NEInfo.Seg.Segments; currseg = Pass2Info.OldFile.u.NEInfo.Seg.NumSegs - Pass2Info.OldFile.u.NEInfo.Seg.NumOS2ResSegs; entry = restab->resources; ret = RS_OK; err_code = 0; tmpseg += currseg; shift_count = Pass2Info.TmpFile.u.NEInfo.WinHead.align; seg_offset = 0; // shut up gcc /* We may need to add padding before the first resource segment */ align_amount = AlignAmount( RCTELL( tmphandle ), shift_count ); if( align_amount ) { ret = PadExeData( tmphandle, align_amount ); err_code = errno; } /* Walk through the resource entries */ for( i = 0; i < restab->num_res_segs; i++, entry++, tmpseg++ ) { wind = entry->wind; lang = WResGetLangInfo( wind ); if( entry->first_part ) { seg_offset = RCTELL( tmphandle ); } else { seg_offset += 0x10000; } /* Fill in segment structure */ tmpseg->address = seg_offset >> shift_count; tmpseg->size = entry->seg_length; tmpseg->min = entry->seg_length; tmpseg->info = SEG_DATA | SEG_READ_ONLY | SEG_LEVEL_3; if( entry->mem_flags & MEMFLAG_MOVEABLE ) tmpseg->info |= SEG_MOVABLE; if( entry->mem_flags & MEMFLAG_PURE ) tmpseg->info |= SEG_PURE; if( entry->mem_flags & MEMFLAG_PRELOAD ) tmpseg->info |= SEG_PRELOAD; if( entry->mem_flags & MEMFLAG_DISCARDABLE ) tmpseg->info |= SEG_DISCARD; /* For non-last segment of a resource, there's nothing to copy */ if( !entry->first_part ) continue; /* Copy resource data */ ret = copyOneResource( lang, reshandle, tmphandle, shift_count, &err_code ); if( ret != RS_OK ) break; CheckDebugOffset( &(Pass2Info.TmpFile) ); } switch( ret ) { case RS_WRITE_ERROR: RcError( ERR_WRITTING_FILE, Pass2Info.TmpFile.name, strerror( err_code ) ); break; case RS_READ_ERROR: RcError( ERR_READING_RES, CmdLineParms.OutResFileName, strerror( err_code ) ); break; case RS_READ_INCMPLT: RcError( ERR_UNEXPECTED_EOF, CmdLineParms.OutResFileName ); break; default: break; } return( ret ); } /* CopyOS2Resources */