⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pass2.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        info |= OS2_PROT_MODE_ONLY;
    }

    /* copy the fields in the os2_exe_header then change some of them */
    tmpfile->WinHeadOffset = oldfile->WinHeadOffset;
    /* copy the WinHead fields up to, but excluding, the segment_off field */
    memcpy( &(tmpne->WinHead), &(oldne->WinHead),
            offsetof(os2_exe_header, segment_off) );
    tmpne->WinHead.info = info;
    tableshift = tmpne->Res.Dir.TableSize +
                tmpne->Res.Str.StringBlockSize -
                (oldne->WinHead.resident_off - oldne->WinHead.resource_off );
    tmpne->WinHead.entry_off = oldne->WinHead.entry_off + tableshift;
    tmpne->WinHead.resident_off = oldne->WinHead.resident_off + tableshift;
    tmpne->WinHead.module_off = oldne->WinHead.module_off + tableshift;
    tmpne->WinHead.import_off = oldne->WinHead.import_off + tableshift;
    tmpne->WinHead.nonres_off = oldne->WinHead.nonres_off + tableshift;
    tmpne->WinHead.segment_off = sizeof(os2_exe_header);
    tmpne->WinHead.resource_off = tmpne->WinHead.segment_off +
                                tmpne->Seg.NumSegs * sizeof(segment_record);
    tmpne->WinHead.movable = oldne->WinHead.movable;
    tmpne->WinHead.resource = tmpne->Res.Dir.NumResources;
    tmpne->WinHead.target = oldne->WinHead.target;
    /* |= the next one since the WIN_GANGLOAD_PRESENT flag may be set */
    tmpne->WinHead.otherflags |= oldne->WinHead.otherflags;
    tmpne->WinHead.swaparea =   0;      /* What is this field for? */
    tmpne->WinHead.expver = CmdLineParms.VersionStamp;

    /* seek to the start of the os2_exe_header in tmpfile */
    seekrc = RcSeek( tmpfile->Handle, tmpfile->WinHeadOffset, SEEK_SET );
    if( seekrc == -1 ) {
        *err_code = errno;
        return( RS_WRITE_ERROR );
    }

    /* write the header */
    numwrote = RcWrite( tmpfile->Handle, &(tmpne->WinHead),
                sizeof(os2_exe_header) );
    if( numwrote != sizeof(os2_exe_header) ) {
        *err_code = errno;
        return( RS_WRITE_ERROR );
    }

    /* write the segment table */
    if( tmpne->Seg.NumSegs > 0 ) {
        numwrote = RcWrite( tmpfile->Handle, tmpne->Seg.Segments,
                    tmpne->Seg.NumSegs * sizeof(segment_record) );
        if( numwrote != tmpne->Seg.NumSegs * sizeof(segment_record)  ) {
            *err_code = errno;
            return( RS_WRITE_ERROR );
        }
    }

    /* write the resource table */
    error = WriteResTable( tmpfile->Handle, &(tmpne->Res), err_code );
    return( error );

} /* writeHeadAndTables */

/*
 * Processing OS/2 NE modules is very very similar to Windows NE processing
 * but there are enough differences in detail to warrant separate
 * implementation to keep the two cleaner.
 */
static int writeOS2HeadAndTables( int *err_code )
{
    ExeFileInfo *   oldfile;
    ExeFileInfo *   tmpfile;
    NEExeInfo *     oldne;
    NEExeInfo *     tmpne;
    uint_16         tableshift;     /* amount the tables are shifted in the */
                                    /* tmp file */
    long            seekrc;
    int             numwrote;
    int             error;

    oldfile = &(Pass2Info.OldFile);
    oldne = &oldfile->u.NEInfo;
    tmpfile = &(Pass2Info.TmpFile);
    tmpne = &tmpfile->u.NEInfo;

    /* copy the fields in the os2_exe_header then change some of them */
    tmpfile->WinHeadOffset = oldfile->WinHeadOffset;
    /* copy the WinHead fields up to, but excluding, the segment_off field */
    memcpy( &(tmpne->WinHead), &(oldne->WinHead),
            offsetof(os2_exe_header, segment_off) );
    tmpne->WinHead.info = oldne->WinHead.info;
    tmpne->WinHead.segment_off = sizeof(os2_exe_header);
    tmpne->WinHead.resource_off = tmpne->WinHead.segment_off +
                                tmpne->Seg.NumSegs * sizeof(segment_record);
    tableshift = tmpne->OS2Res.table_size -
                (oldne->WinHead.resident_off - oldne->WinHead.resource_off) +
                (tmpne->WinHead.resource_off - oldne->WinHead.resource_off);
    tmpne->WinHead.entry_off = oldne->WinHead.entry_off + tableshift;
    tmpne->WinHead.resident_off = oldne->WinHead.resident_off + tableshift;
    tmpne->WinHead.module_off = oldne->WinHead.module_off + tableshift;
    tmpne->WinHead.import_off = oldne->WinHead.import_off + tableshift;
    tmpne->WinHead.nonres_off = oldne->WinHead.nonres_off + tableshift;
    tmpne->WinHead.movable    = oldne->WinHead.movable;
    tmpne->WinHead.resource   = tmpne->OS2Res.num_res_segs;
    tmpne->WinHead.target     = oldne->WinHead.target;
    tmpne->WinHead.otherflags = oldne->WinHead.otherflags;
    tmpne->WinHead.segments   = tmpne->Seg.NumSegs;

    /* seek to the start of the os2_exe_header in tmpfile */
    seekrc = RcSeek( tmpfile->Handle, tmpfile->WinHeadOffset, SEEK_SET );
    if( seekrc == -1 ) {
        *err_code = errno;
        return( RS_WRITE_ERROR );
    }

    /* write the header */
    numwrote = RcWrite( tmpfile->Handle, &(tmpne->WinHead),
                sizeof(os2_exe_header) );
    if( numwrote != sizeof(os2_exe_header) ) {
        *err_code = errno;
        return( RS_WRITE_ERROR );
    }

    /* write the segment table */
    if( tmpne->Seg.NumSegs > 0 ) {
        numwrote = RcWrite( tmpfile->Handle, tmpne->Seg.Segments,
                    tmpne->Seg.NumSegs * sizeof(segment_record) );
        if( numwrote != tmpne->Seg.NumSegs * sizeof(segment_record)  ) {
            *err_code = errno;
            return( RS_WRITE_ERROR );
        }
    }

    /* write the resource table */
    error = WriteOS2ResTable( tmpfile->Handle, &(tmpne->OS2Res), err_code );
    return( error );

} /* writeOS2HeadAndTables */

static int findEndOfResources( int *err_code )
/* if this exe already contains resources find the end of them so we don't
   copy them with debug information.  Otherwise the file will grow whenever
   a resource file is added */
{
    NEExeInfo                   *oldneinfo;
    uint_32                     *debugoffset;
    int                         oldhdl;
    int                         rc;
    unsigned                    i;
    uint_32                     oldoffset;
    uint_16                     alignshift;
    uint_32                     end;
    uint_32                     tmp;
    resource_type_record        typeinfo;
    resource_record             nameinfo;

    end = 0;
    oldoffset = Pass2Info.OldFile.WinHeadOffset;
    oldneinfo = &Pass2Info.OldFile.u.NEInfo;
    oldhdl = Pass2Info.OldFile.Handle;
    debugoffset = &Pass2Info.OldFile.DebugOffset;

    if( oldneinfo->WinHead.resource_off == oldneinfo->WinHead.resident_off ) {
        return( RS_OK );
    }

    rc = RcSeek( oldhdl, oldneinfo->WinHead.resource_off + oldoffset,
                SEEK_SET );
    if( rc == -1 ) {
        *err_code = errno;
        return( RS_READ_ERROR );
    }

    rc = RcRead( oldhdl, &alignshift, sizeof( uint_16 ) );
    if( rc != sizeof( uint_16 ) ) {
        *err_code = errno;
        if( rc == -1 ) {
            return( RS_READ_ERROR );
        } else {
            return( RS_READ_INCMPLT );
        }
    }
    alignshift = 1 << alignshift;

    rc = RcRead( oldhdl, &typeinfo, sizeof( resource_type_record ) );
    if( rc != sizeof( resource_type_record ) )  {
        *err_code = errno;
        if( rc == -1 ) {
            return( RS_READ_ERROR );
        } else {
            return( RS_READ_INCMPLT );
        }
    }
    while( typeinfo.type != 0 ) {
        for( i=0; i < typeinfo.num_resources; i++ ) {
            rc = RcRead( oldhdl, &nameinfo, sizeof( resource_record ) );
            if( rc != sizeof( resource_record ) ) {
                *err_code = errno;
                if( rc == -1 ) {
                    return( RS_READ_ERROR );
                } else {
                    return( RS_READ_INCMPLT );
                }
            }
            tmp = nameinfo.offset + nameinfo.length;
            if( tmp > end ) end = tmp;
        }
        rc = RcRead( oldhdl, &typeinfo, sizeof( resource_type_record ) );
        if( rc != sizeof( resource_type_record ) ) {
            *err_code = errno;
            if( rc == -1 ) {
                return( RS_READ_ERROR );
            } else {
                return( RS_READ_INCMPLT );
            }
        }
    }
    end *= alignshift;
    if( end > *debugoffset ) {
        *debugoffset = end;
    }
    return( RS_OK );
}

/*
 * writePEHeadAndObjTable
 * NB when an error occurs this function must return without altering errno
 */
static RcStatus writePEHeadAndObjTable( void )
{
    ExeFileInfo *   tmp;
    PEExeInfo *     pe_info;
    pe_object *     last_object;
    long            seek_rc;
    int             num_wrote;
    int             obj_num;
    uint_32         image_size;

    tmp = &Pass2Info.TmpFile;
    pe_info = &tmp->u.PEInfo;

    /* adjust the image size in the header */
    last_object = &pe_info->Objects[ pe_info->WinHead->num_objects - 1 ];
    image_size = last_object->rva + last_object->physical_size;
    image_size = ALIGN_VALUE( image_size, pe_info->WinHead->object_align );
    pe_info->WinHead->image_size = image_size;

    seek_rc = RcSeek( tmp->Handle, tmp->WinHeadOffset, SEEK_SET );
    if( seek_rc == -1 ) return( RS_WRITE_ERROR );

    num_wrote = RcWrite( tmp->Handle, pe_info->WinHead, sizeof(pe_header) );
    if( num_wrote != sizeof(pe_header) ) return( RS_WRITE_ERROR );

    for( obj_num = 0; obj_num < pe_info->WinHead->num_objects; obj_num++ ) {
        num_wrote = RcWrite( tmp->Handle, pe_info->Objects + obj_num,
                            sizeof(pe_object) );
        if( num_wrote != sizeof(pe_object) ) return( RS_WRITE_ERROR );
    }

    return( RS_OK );

} /* writePEHeadAndObjTable */

/*
 * Windows NE files store resources in a special data structure. OS/2 NE
 * modules are quite different and store each resource in its own data
 * segment(s). The OS/2 resource table is completely different as well and
 * only contains resource types/IDs.
 */
extern int MergeResExeNE( void )
{
    RcStatus        error;
    int             err_code;

    error = copyStubFile( &err_code );
    if( error != RS_OK ) goto HANDLE_ERROR;
    if( StopInvoked ) goto STOP_ERROR;

    error = AllocAndReadSegTables( &err_code );
    if( error != RS_OK ) goto HANDLE_ERROR;
    if( StopInvoked ) goto STOP_ERROR;

    InitResTable();

    error = seekPastResTable( &err_code );
    if( error != RS_OK ) goto HANDLE_ERROR;
    if( StopInvoked ) goto STOP_ERROR;

    error = findEndOfResources( &err_code );
    if( error != RS_OK ) goto HANDLE_ERROR;
    if( StopInvoked ) goto STOP_ERROR;

    error = copyOtherTables( &err_code );
    if( error != RS_OK ) goto HANDLE_ERROR;
    if( StopInvoked ) goto STOP_ERROR;

    error = copyBody();
    if( error ) return( FALSE );
    if( StopInvoked ) goto STOP_ERROR;

    error = copyDebugInfo();
    if( error != RS_OK ) {
        err_code = errno;
        goto HANDLE_ERROR;
    }
    if( StopInvoked ) goto STOP_ERROR;

    error = writeHeadAndTables( &err_code );
    if( error != RS_OK ) goto HANDLE_ERROR;
    if( StopInvoked ) goto STOP_ERROR;

    return( TRUE );

HANDLE_ERROR:
    switch( error ) {
    case RS_READ_ERROR:
        RcError( ERR_READING_EXE, Pass2Info.OldFile.name,
                 strerror( err_code ) );
        break;
    case RS_READ_INCMPLT:
        RcError( ERR_UNEXPECTED_EOF, Pass2Info.OldFile.name );
        break;
    case RS_WRITE_ERROR:
        RcError( ERR_WRITTING_TMP, Pass2Info.TmpFile.name,
                 strerror( err_code ) );
        break;
    case RS_NO_MEM:
        break;
    default:
       RcError( ERR_INTERNAL, INTERR_UNKNOWN_RCSTATUS );
    }
    return( FALSE );

STOP_ERROR:
    RcFatalError( ERR_STOP_REQUESTED );
#if !defined( __WATCOMC__ )
    return( FALSE );
#endif
} /* MergeResExeNE */


extern int MergeResExeOS2NE( void )
{
    RcStatus        error;
    int             err_code;

    error = copyStubFile( &err_code );
    if( error != RS_OK ) goto HANDLE_ERROR;
    if( StopInvoked ) goto STOP_ERROR;

    error = InitOS2ResTable( &err_code );
    if( error != RS_OK ) goto HANDLE_ERROR;
    if( StopInvoked ) goto STOP_ERROR;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -