Пример #1
0
static RcStatus copyFont( FontInfo * info, WResFileID handle, WResID * name,
                                ResMemFlags flags, int *err_code )
/************************************************************************/
{
    RcStatus            ret;
    char *              buffer;
    ResLocation         loc;
    long                pos;

    buffer = RCALLOC( FONT_BUFFER_SIZE );

    loc.start = SemStartResource();

    if( ResWriteFontInfo( info, CurrResFile.handle ) ) {
        ret = RS_WRITE_ERROR;
        *err_code = LastWresErr();
    } else {
        pos = RCTELL( handle );
        if( pos == -1 ) {
            ret = RS_READ_ERROR;
            *err_code = errno;
        } else {
            ret = SemCopyDataUntilEOF( pos, handle, buffer,
                                         FONT_BUFFER_SIZE, err_code );
        }
    }

    loc.len = SemEndResource( loc.start );
    /* add the font to the RES file directory */
    SemAddResourceFree( name, WResIDFromNum( (long)RT_FONT ), flags, loc );

    RCFREE( buffer );

    return( ret );
} /* copyFont */
Пример #2
0
static RcStatus copyBitmap( BitmapFileHeader *head, WResFileID handle,
                            WResID *name, ResMemFlags flags, int *err_code )
/**************************************************************************/
{
    RcStatus            ret;
    char *              buffer;
    ResLocation         loc;
    WResFileOffset      pos;

    buffer = RCALLOC( BITMAP_BUFFER_SIZE );

    loc.start = SemStartResource();

    pos = RCTELL( handle );
    if( pos == -1 ) {
        ret = RS_READ_ERROR;
        *err_code = errno;
    } else {
        ret = CopyData( pos, head->Size - sizeof(BitmapFileHeader),
                          handle, buffer, BITMAP_BUFFER_SIZE, err_code );
    }

    loc.len = SemEndResource( loc.start );
    /* add the bitmap to the RES file directory */
    SemAddResourceFree( name, WResIDFromNum( (long)(pointer_int)RT_BITMAP ), flags, loc );

    RCFREE( buffer );

    return( ret );
} /* copyBitmap */
Пример #3
0
static RcStatus seekPastResTable( int *err_code )
{
    long            winheadoffset;
    long            seekamount;
    ExeFileInfo     *tmpexe;
    uint_16         res_tbl_size;

    tmpexe = &(Pass2Info.TmpFile);

    if( Pass2Info.OldFile.u.NEInfo.WinHead.target == TARGET_OS2 )
        res_tbl_size = tmpexe->u.NEInfo.OS2Res.table_size;
    else
        res_tbl_size = tmpexe->u.NEInfo.Res.Dir.TableSize;

    seekamount = sizeof( os2_exe_header ) +
                    tmpexe->u.NEInfo.Seg.NumSegs * sizeof( segment_record ) +
                    res_tbl_size +
                    tmpexe->u.NEInfo.Res.Str.StringBlockSize;
    if( RCSEEK( tmpexe->Handle, seekamount, SEEK_CUR ) == -1 ) {
        *err_code = errno;
        return( RS_READ_ERROR );
    }
    winheadoffset = RCTELL( tmpexe->Handle );
    tmpexe->WinHeadOffset = winheadoffset;
    return( RS_OK );

} /* seekPastResTable */
Пример #4
0
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 );
    }
Пример #5
0
ResLocation SemCopyRawFile( const char *filename )
/************************************************/
{
    WResFileID      handle;
    RcStatus        ret;
    char            *buffer;
    char            full_filename[_MAX_PATH];
    ResLocation     loc;
    int             err_code;
    WResFileOffset  pos;

    buffer = RCALLOC( BUFFER_SIZE );

    if( RcFindResource( filename, full_filename ) == -1 ) {
        RcError( ERR_CANT_FIND_FILE, filename );
        goto HANDLE_ERROR;
    }

    if( AddDependency( full_filename ) )
        goto HANDLE_ERROR;

    handle = RcIoOpenInput( full_filename, O_RDONLY | O_BINARY );
    if( handle == NIL_HANDLE ) {
        RcError( ERR_CANT_OPEN_FILE, filename, strerror( errno ) );
        goto HANDLE_ERROR;
    }

    loc.start = SemStartResource();

    pos = RCTELL( handle );
    if( pos == -1 ) {
        RcError( ERR_READING_DATA, full_filename, strerror( errno ) );
        RCCLOSE( handle );
        goto HANDLE_ERROR;
    } else {
        ret = SemCopyDataUntilEOF( pos, handle, buffer, BUFFER_SIZE, &err_code );
        if( ret != RS_OK ) {
            ReportCopyError( ret, ERR_READING_DATA, full_filename, err_code );
            RCCLOSE( handle );
            goto HANDLE_ERROR;
        }
    }

    loc.len = SemEndResource( loc.start );

    RCCLOSE( handle );

    RCFREE( buffer );

    return( loc );


HANDLE_ERROR:
    ErrorHasOccured = true;
    loc.start = 0;
    loc.len = 0;
    RCFREE( buffer );
    return( loc );
}
Пример #6
0
/* 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 */
Пример #7
0
static RcStatus copyOneCursor( const CurFileDirEntry *entry, WResFileID handle,
                void *buffer, int buffer_size, BitmapInfoHeader *dibhead,
                int *err_code )
/*****************************************************************************/
/* NOTE: this routine fills in dibhead as it copies the data */
{
    RcStatus        ret;
    WResFileOffset  curpos;

    ret = RS_OK;
    if( RCSEEK( handle, entry->Offset, SEEK_SET ) == -1 ) {
        ret = RS_READ_ERROR;
        *err_code = errno;
    }

    if( ret == RS_OK ) {
        ret = ReadBitmapInfoHeader( dibhead, handle );
        *err_code = errno;
    }
    if( ret == RS_OK ) {
        if( ResWriteBitmapInfoHeader( dibhead, CurrResFile.handle ) ) {
            ret = RS_WRITE_ERROR;
            *err_code = LastWresErr();
        }
    }
    if( ret == RS_OK ) {
        curpos = RCTELL( handle );
        if( curpos == -1 ) {
            ret = RS_READ_ERROR;
            *err_code = errno;
        } else {
            ret = CopyData( curpos,
                              entry->Length - sizeof(BitmapInfoHeader),
                              handle, buffer, buffer_size, err_code );
        }
    }

    return( ret );
}
Пример #8
0
static bool copyWINBody( void )
{
    NEExeInfo *         tmp;
    uint_16             sect2mask = 0;
    uint_16             sect2bits = 0;
    uint_16             shift_count;
    long                gangloadstart;
    long                gangloadlen;
    CpSegRc             copy_segs_ret;
    bool                use_gangload = false;

    tmp = &Pass2Info.TmpFile.u.NEInfo;

    switch( CmdLineParms.SegmentSorting ) {
    case SEG_SORT_NONE:     /* all segments in section 2 */
        sect2mask = 0;
        sect2bits = 0;
        use_gangload = false;
        Pass2Info.TmpFile.u.NEInfo.WinHead.align = Pass2Info.OldFile.u.NEInfo.WinHead.align;
        tmp->Res.Dir.ResShiftCount = computeShiftCount();
        break;
    case SEG_SORT_PRELOAD_ONLY:  /* all load on call segments in section 2 */
        sect2mask = SEG_PRELOAD;
        sect2bits = 0;
        use_gangload = true;
        checkShiftCount();
        break;
    case SEG_SORT_MANY:     /* only load on call, discardable, code segments */
                            /* in section 2 */
        sect2mask = SEG_DATA | SEG_PRELOAD | SEG_DISCARD;
        sect2bits = SEG_DISCARD;

        /* set the entry segment to be preload */
        {
            segment_record *    seg;        /* these two are here because a */
            uint_16             entry_seg;  /* 71 character field reference */
                                            /* is hard to read */
            seg = Pass2Info.OldFile.u.NEInfo.Seg.Segments;
            entry_seg = Pass2Info.OldFile.u.NEInfo.WinHead.entrynum;
            seg[entry_seg].info |= SEG_PRELOAD;
        }

        use_gangload = true;
        checkShiftCount();
        break;
    default:
        break;
    }

    /* third arg to Copy???? is false --> copy section one */
    gangloadstart = RCTELL( Pass2Info.TmpFile.Handle );
    gangloadstart += AlignAmount( gangloadstart, tmp->Res.Dir.ResShiftCount );
    copy_segs_ret = CopyWINSegments( sect2mask, sect2bits, false );
    switch( copy_segs_ret ) {
    case CPSEG_SEG_TOO_BIG:
        if( use_gangload ) {
            RcWarning( ERR_NO_GANGLOAD );
            use_gangload = false;
        }
        break;
    case CPSEG_ERROR:
        return( true );
    case CPSEG_OK:
    default:
        break;
    }
    if( ! CmdLineParms.NoResFile ) {
        if( CopyWINResources( sect2mask, sect2bits, false ) != RS_OK ) {
            return( true );
        }
    }
    gangloadlen = RCTELL( Pass2Info.TmpFile.Handle ) - gangloadstart;

    /* third arg to Copy???? is true  --> copy section two */
    copy_segs_ret = CopyWINSegments( sect2mask, sect2bits, true );
    if( copy_segs_ret == CPSEG_ERROR ) {
        return( true );
    }
    if( !CmdLineParms.NoResFile ) {
        if( CopyWINResources( sect2mask, sect2bits, true ) != RS_OK ) {
            return( true );
        }
    }

    if( use_gangload ) {
        shift_count = tmp->WinHead.align;
        tmp->WinHead.gangstart = gangloadstart >> shift_count;
        tmp->WinHead.ganglength = gangloadlen >> shift_count;
        tmp->WinHead.otherflags |= WIN_GANGLOAD_PRESENT;
    } else {
Пример #9
0
static CpSegRc copyOneSegment( const segment_record * inseg,
            segment_record * outseg, ExeFileInfo *inexe, ExeFileInfo *outexe,
            int old_shift_count, int new_shift_count, bool pad_end )
{
    CpSegRc         ret;
    bool            error;
    WResFileSSize   numread;
    uint_16         numrelocs;
    long            out_offset;
    long            align_amount;
    uint_32         seg_len = 0L;
    char            zero;

    zero = 0;
    error = false;
    ret = CPSEG_OK;

    /* check if this is a segment that has no image in the exe file */
    if( inseg->address != 0 ) {
        /* align in the out file so that shift_count will be valid */
        out_offset = RCTELL( outexe->Handle );
        if( out_offset == -1 ) {
            error = true;
            RcError( ERR_WRITTING_FILE, outexe->name, strerror( errno ) );
        }
        if( !error ) {
            align_amount = AlignAmount( out_offset, new_shift_count );
            if( RCSEEK( outexe->Handle, align_amount, SEEK_CUR ) == -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 */
            if( RCSEEK( inexe->Handle, (long)inseg->address << old_shift_count, SEEK_SET ) == -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 */
            numread = RCREAD( inexe->Handle, &numrelocs, sizeof(uint_16) );
            if( numread != sizeof( uint_16 ) ) {
                error = true;
                if( RCIOERR( inexe->Handle, numread ) ) {
                    RcError( ERR_READING_EXE, inexe->name, strerror( errno ) );
                } else {
                    RcError( ERR_UNEXPECTED_EOF, inexe->name );
                }
            } else {
                if( RCWRITE( outexe->Handle, &numrelocs, sizeof(uint_16) ) != 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;
            }
            if( RCSEEK( outexe->Handle, align_amount - 1, SEEK_CUR ) == -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 */
                if( RCWRITE( outexe->Handle, &zero, 1 ) != 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;
    }
Пример #10
0
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 */