Beispiel #1
0
long int WRReadWinNTExeHeader( WResFileID file_handle, exe_pe_header *header )
{
    long int    old_pos;
    uint_16     offset;
    bool        ok;

    old_pos = -1;

    ok = (file_handle != -1 && header != NULL);

    if( ok ) {
        ok = ((old_pos = ResSeek( file_handle, 0x18, SEEK_SET )) != -1);
    }

    /* check the reloc offset */
    if( ok ) {
        ResReadUint16( &offset, file_handle );
        ok = (offset >= 0x0040);
    }

    if( ok ) {
        ok = (ResSeek( file_handle, PE_OFFSET, SEEK_SET ) != -1);
    }

    /* check header offset */
    if( ok ) {
        ResReadUint16( &offset, file_handle );
        ok = (offset != 0x0000);
    }

    if( ok ) {
        ok = (ResSeek( file_handle, offset, SEEK_SET ) != -1);
    }

    if( ok ) {
        ok = (read( file_handle, &PE32( *header ), sizeof( pe_header ) ) == sizeof( pe_header ));
        if( ok && IS_PE64( *header ) ) {
            ok = (ResSeek( file_handle, offset, SEEK_SET ) != -1);
            if( ok ) {
                ok = (read( file_handle, &PE64( *header ), sizeof( pe_header64 ) ) == sizeof( pe_header64 ));
            }
        }
    }

    /* check for valid Win32 EXE */
    if( ok ) {
        ok = WRIsHeaderValidWINNT( header );
    }

    if( old_pos != -1 ) {
        ok = (ResSeek( file_handle, old_pos, SEEK_SET ) != -1 && ok);
    }

    if( !ok ) {
        WRDisplayErrorMsg( WR_INVALIDNTEXE );
        offset = 0;
    }

    return( offset );
}
Beispiel #2
0
long int WRReadWin16ExeHeader( WResFileID file_handle, os2_exe_header *header )
{
    long int    old_pos;
    uint_16     offset;
    int         ok;

    old_pos = -1;

    ok = (file_handle != -1 && header != NULL);

    if( ok ) {
        ok = ((old_pos = ResSeek( file_handle, 0x18, SEEK_SET )) != -1);
    }

    /* check the reloc offset */
    if( ok ) {
        ResReadUint16( &offset, file_handle );
        ok = (offset >= 0x0040);
    }

    if( ok ) {
        ok = (ResSeek( file_handle, OS2_NE_OFFSET, SEEK_SET ) != -1);
    }

    /* check header offset */
    if( ok ) {
        ResReadUint16( &offset, file_handle );
        ok = (offset != 0x0000);
    }

    if( ok ) {
        ok = (ResSeek( file_handle, offset, SEEK_SET ) != -1);
    }

    if( ok ) {
        ok = (read( file_handle, header, sizeof( os2_exe_header ) ) ==
              sizeof( os2_exe_header ));
    }

    /* check for valid Win16 EXE */
    if( ok ) {
        ok = WRIsHeaderValidWIN16( header );
    }

    if( old_pos != -1 ) {
        ok = (ResSeek( file_handle, old_pos, SEEK_SET ) != -1 && ok);
    }

    if( ok ) {
        return( offset );
    } else {
        return( 0 );
    }
}
Beispiel #3
0
WResID *WRGetUniCodeWResID( WResFileID file_handle, uint_32 rva )
{
    uint_32 old_pos;
    uint_32 offset;
    uint_16 len;
    bool    ok;
    char    *unistr;
    WResID  *id;
    int     i;

    offset = WR_MAP_RES_RVA( rva );

    unistr = NULL;

    /* seek to the location of the Unicode string */
    ok = ((old_pos = ResSeek( file_handle, offset, SEEK_SET )) != -1);

    /* read the Unicode string */
    if( ok ) {
        ResReadUint16( &len, file_handle );
        len *= 2;
        unistr = (char *)MemAlloc( len + 2 );
        ok = (unistr != NULL);
    }

    if( ok ) {
        unistr[len] = 0;
        unistr[len + 1] = 0;
        ok = (read( file_handle, unistr, len ) == len);
    }

    if( ok ) {
        for( i = 0; i < len + 2; i += 2 ) {
            unistr[i / 2] = unistr[i];
        }
        ok = ((id = WResIDFromStr( unistr )) != NULL);
    }

#if 0
    if( old_pos != -1 ) {
        ok = (ResSeek( file_handle, old_pos, SEEK_SET ) != -1 && ok);
    }
#endif

    if( unistr != NULL ) {
        MemFree( unistr );
    }

    if( ok ) {
        return( id );
    } else {
        return( NULL );
    }
}
Beispiel #4
0
bool WRReadResourceHeader( WResFileID file_handle, uint_32 offset,
                           resource_dir_header *rd_hdr,
                           resource_dir_entry **rd_entry )
{
    bool ok;
    int rde_size;

    *rd_entry = NULL;

    /* if offset is zero don't perform the seek to beginning of resource directory */
    ok = (offset == 0 || ResSeek( file_handle, offset, SEEK_SET ) != -1);

    /* read the resource directory header */
    if( ok ) {
        ok = (read( file_handle, rd_hdr, sizeof( resource_dir_header ) ) ==
              sizeof( resource_dir_header ) );
    }

    if( ok ) {
        rde_size = sizeof( resource_dir_entry ) *
                   (rd_hdr->num_name_entries + rd_hdr->num_id_entries);
        *rd_entry = (resource_dir_entry *)MemAlloc( rde_size );
        ok = (*rd_entry != NULL);
    }

    if( ok ) {
        ok = (read( file_handle, *rd_entry, rde_size ) == rde_size);
    }

    if( !ok && *rd_entry != NULL ) {
        MemFree( *rd_entry );
    }

    return( ok );
}
Beispiel #5
0
int WRCalcObjTableOffset( WResFileID file, exe_pe_header *hdr )
{
    uint_16  pe_offset;
    int      offset;
    bool     ok;

    ok = (ResSeek( file, PE_OFFSET, SEEK_SET ) != -1);

    if( ok ) {
        ResReadUint16( &pe_offset, file );
        ok = (pe_offset != 0);
    }

    if ( ok ) {
        if( IS_PE64( *hdr ) ) {
            offset = pe_offset + PE64( *hdr ).nt_hdr_size + offsetof( pe_header64, magic );
        } else {
            offset = pe_offset + PE32( *hdr ).nt_hdr_size + offsetof( pe_header, magic );
        }
    } else {
        offset = 0;
    }

    return( offset );
}
Beispiel #6
0
bool WRReadResourceEntry( WResFileID file, uint_32 offset, resource_entry *res_entry )
{
    bool ok;

    /* if offset is zero don't perform the seek to beginning of resource directory */
    ok = (offset == 0 || ResSeek( file, offset, SEEK_SET ) != -1);

    /* read the resource entry */
    if( ok ) {
        ok = (read( file, res_entry, sizeof( resource_entry ) ) ==
              sizeof( resource_entry ));
    }

    return( ok );
}
Beispiel #7
0
void * WRAPI WRLoadResData( char *file, uint_32 offset, uint_32 length )
{
    void        *data;
    WResFileID  handle;
    int         ok;

    data = NULL;
    handle = -1;

    ok = (file != NULL && length != 0);

    if( ok ) {
        ok = ((data = WRMemAlloc( length )) != NULL);
    }

    if( ok ) {
        ok = ((handle = ResOpenFileRO( file )) != -1);
    }

    if( ok ) {
        ok = ((ResSeek( handle, offset, SEEK_SET )) != -1);
    }

    if( ok ) {
        ok = WRReadResData( handle, (BYTE *)data, length );
    }

    if( handle != -1 ) {
        ResCloseFile( handle );
    }

    if( !ok ) {
        if( data != NULL ) {
            WRMemFree( data );
            data = NULL;
        }
    }

    return( data );
}
Beispiel #8
0
int WRReadNTObjectTable( WResFileID file, exe_pe_header *hdr, pe_object **ot )
{
    int size;
    int ot_offset;

    ot_offset = WRCalcObjTableOffset( file, hdr );
    if( ot_offset == 0 || ResSeek( file, ot_offset, SEEK_SET ) == -1 ) {
        return( FALSE );
    }
    if( IS_PE64( *hdr ) ) {
        size = sizeof( pe_object ) * PE64( *hdr ).num_objects;
    } else {
        size = sizeof( pe_object ) * PE32( *hdr ).num_objects;
    }
    *ot = (pe_object *)MemAlloc( size );
    if( *ot != NULL ) {
        if( read( file, *ot, size ) != size ) {
            MemFree( *ot );
            *ot = NULL;
        }
    }

    return( *ot != NULL );
}
Beispiel #9
0
uint_32 WRReadNameTable( WResDir dir, WResFileID file_handle, uint_8 **name_table,
                         uint_32 num_leftover, uint_8 *leftover )
{
    static WResTypeNode *type_node;
    static WResResNode  *res_node;
    static uint_32      res_len;
    static uint_32      res_offset;
    static uint_32      num_read;
    uint_32             len;

    if( dir != NULL ) {
        type_node = WRFindTypeNode( dir, (uint_16)WR_RT_NAMETABLE, NULL );
        if( type_node != NULL ) {
            res_node = type_node->Head;
            /* if there are two name tables we ignore all but the first */
            res_len = res_node->Head->Info.Length;
            res_offset = res_node->Head->Info.Offset;
            if( ResSeek( file_handle, res_offset, SEEK_SET ) == -1 ) {
                return( FALSE );
            }
        } else {
            res_len = 0;
        }
        num_read = 0;
    }

    if( num_read == res_len ) {
        return( 0 );
    }

    *name_table = NULL;

    if( num_read + NAME_TABLE_MAX < res_len ) {
        len = NAME_TABLE_MAX;
    } else {
        len = res_len - num_read;
    }

    num_read += len;

    /* If there was data left over but we have a NULL pointer to the
     * leftover data then we are in a very bad situation.
     * What we shall do is skip the left over data.
     * If the seek to skip the data fails then we are totally SNAFU
     * and must abort the reading of the name resource!!
     */
    if( num_leftover != 0 && leftover == NULL ) {
        if( ResSeek( file_handle, num_leftover, SEEK_CUR ) == -1 ) {
            return( 0 );
        }
        num_read += num_leftover;
        num_leftover = 0;
    }

    *name_table = (uint_8 *)WRMemAlloc( len + num_leftover );
    if( *name_table == NULL ) {
        return( FALSE );
    }

    if( num_leftover != 0 ) {
        memcpy( *name_table, leftover, num_leftover );
    }

    if( read( file_handle, *name_table + num_leftover, len ) != len ) {
        /* hmmmm... the read failed */
    }

    return( len + num_leftover );
}
Beispiel #10
0
int WRLoadWResDirFromWin16EXE( WResFileID file_handle, WResDir *dir )
{
    os2_exe_header  win_header;
    long int        offset;
    uint_16         align_shift;
    uint_32         name_offset;
    WResTypeNode    *type_node;
    uint_8          *name_table;
    uint_8          *leftover;
    uint_32         name_table_len;
    uint_32         num_leftover;
    int             ok;

    ok = (file_handle != -1);

    if( ok ) {
        ok = ((*dir = WResInitDir()) != NULL);
    }

    if( ok ) {
        ok = ((offset = WRReadWin16ExeHeader( file_handle, &win_header )) != 0);
    }

    /* check if a resource table is present */
    if( ok ) {
        ok = WRWin16HeaderHasResourceTable( &win_header );
        if( !ok ) {
            return( TRUE );
        }
    }

    if( ok ) {
        ok = (ResSeek( file_handle, offset, SEEK_SET ) != -1);
    }

    if( ok ) {
        ok = (ResSeek( file_handle, win_header.resource_off, SEEK_CUR ) != -1);
    }

    if( ok ) {
        ResReadUint16( &align_shift, file_handle );
        ok = (align_shift <= 16);
        if( !ok ) {
            WRDisplayErrorMsg( WR_BADEXE );
        }
    }

    if( ok ) {
        (*dir)->NumResources = 0;
        type_node = WRReadWResTypeNodeFromExe( file_handle, align_shift );
        while( type_node != NULL ) {
            type_node->Next = NULL;
            type_node->Prev = (*dir)->Tail;
            if( (*dir)->Tail != NULL ) {
                (*dir)->Tail->Next = type_node;
            }
            if ( (*dir)->Head == NULL ) {
                (*dir)->Head = type_node;
            }
            (*dir)->Tail = type_node;
            (*dir)->NumTypes++;
            (*dir)->NumResources += type_node->Info.NumResources;
            type_node = WRReadWResTypeNodeFromExe ( file_handle, align_shift );
        }
        name_offset = tell( file_handle ) - offset - win_header.resource_off;
        ok = WRReadResourceNames( *dir, file_handle, name_offset );
    }

    if( ok && win_header.expver <= 0x300 ) {
        num_leftover = 0;
        leftover = NULL;
        name_table_len = WRReadNameTable( *dir, file_handle,
                                          &name_table, num_leftover, leftover );
        while( name_table_len != 0 ) {
            num_leftover = WRUseNameTable( *dir, name_table, name_table_len, &leftover );
            if( name_table != NULL ) {
                WRMemFree( name_table );
            }
            name_table_len = WRReadNameTable( NULL, file_handle, &name_table,
                                              num_leftover, leftover );
            if( leftover != NULL ) {
                WRMemFree( leftover );
                leftover = NULL;
            }
        }
    }

    return( ok );
}
Beispiel #11
0
WdeDialogBoxInfo *WdeLoadDialogFromRes( WdeResInfo *res_info,
                                        WResLangNode *lnode, bool is32bit )
{
    DialogExHeader32        h32ex;
    DialogBoxHeader32       h32;
    DialogBoxHeader         h16;

    DialogBoxControl        c16;
    DialogBoxControl32      c32;
    DialogBoxExControl32    c32ex;

    WdeDialogBoxInfo        *dlg_info;
    WResFileID              fid;
    WdeDialogBoxControl     *control;
    LIST                    *prev_control;
#if 0
    WdeDialogBoxControl     *nc;
    LIST                    *clist;
#endif
    int                     index;
    char                    *file_name;
    bool                    ok;

    dlg_info = NULL;
    fid = WRES_NIL_HANDLE;

    ok = (res_info != NULL && lnode != NULL);

    if( ok ) {
        file_name = res_info->info->tmp_file;
        dlg_info = (WdeDialogBoxInfo *)WRMemAlloc( sizeof( WdeDialogBoxInfo ) );
        ok = (dlg_info != NULL);
    }

    if( ok ) {
        dlg_info->dialog_header = WdeAllocDialogBoxHeader();
        ok = (dlg_info->dialog_header != NULL);
    }

    if( ok ) {
        dlg_info->dialog_header->is32bit = is32bit;
        dlg_info->control_list = NULL;
        dlg_info->MemoryFlags = 0;
        ok = ((fid = ResOpenFileRO( file_name )) != WRES_NIL_HANDLE);
    }

    if( ok ) {
        dlg_info->MemoryFlags = lnode->Info.MemoryFlags;
        ok = (ResSeek( fid, lnode->Info.Offset, SEEK_SET ) != -1);
    }

    if( ok ) {
        if( is32bit ) {
            /* JPK - check if its an extended dialog */
            dlg_info->dialog_header->is32bitEx = ResIsDialogEx( fid );
            ResSeek( fid, lnode->Info.Offset, SEEK_SET );

            if( dlg_info->dialog_header->is32bitEx ) {
                ok = !ResReadDialogExHeader32( &h32, &h32ex, fid );
            } else {
                ok = !ResReadDialogBoxHeader32( &h32, fid );
            }
        } else {
            ok = !ResReadDialogBoxHeader( &h16, fid );
        }
    }

    if( ok ) {
        if( is32bit ) {
            if( dlg_info->dialog_header->is32bitEx ) {
                dlg_info->dialog_header->FontWeight = h32ex.FontWeight;
                dlg_info->dialog_header->FontItalic = h32ex.FontItalic;
                dlg_info->dialog_header->FontCharset = h32ex.FontCharset;
                dlg_info->dialog_header->HelpId = h32ex.HelpId;
                dlg_info->dialog_header->FontWeightDefined = (h32ex.FontWeightDefined != 0);
                dlg_info->dialog_header->FontItalicDefined = (h32ex.FontItalicDefined != 0);
                dlg_info->dialog_header->FontCharsetDefined = (h32ex.FontCharsetDefined != 0);
            }
            dlg_info->dialog_header->Style = h32.Style;
            dlg_info->dialog_header->ExtendedStyle = h32.ExtendedStyle;
            dlg_info->dialog_header->NumOfItems = h32.NumOfItems;
            dlg_info->dialog_header->Size = h32.Size;
            dlg_info->dialog_header->MenuName = h32.MenuName;
            dlg_info->dialog_header->ClassName = h32.ClassName;
            dlg_info->dialog_header->Caption = h32.Caption;
            dlg_info->dialog_header->PointSize = h32.PointSize;
            dlg_info->dialog_header->FontName = h32.FontName;
        } else {
            dlg_info->dialog_header->Style = h16.Style;
            dlg_info->dialog_header->NumOfItems = h16.NumOfItems;
            dlg_info->dialog_header->Size = h16.Size;
            dlg_info->dialog_header->MenuName = h16.MenuName;
            dlg_info->dialog_header->ClassName = h16.ClassName;
            dlg_info->dialog_header->Caption = h16.Caption;
            dlg_info->dialog_header->PointSize = h16.PointSize;
            dlg_info->dialog_header->FontName = h16.FontName;
        }

        prev_control = NULL;
        for( index = 0; index < GETHDR_NUMITEMS( dlg_info->dialog_header ); index++ ) {
            control = WdeAllocDialogBoxControl();
            if( control == NULL ) {
                ok = false;
                break;
            }
            if( is32bit ) {
                /*
                 * JPK - check which control structure to expect based on
                 *       whether this an extended dialog or not
                */
                if( dlg_info->dialog_header->is32bitEx ) {
                    if( ResReadDialogExControl32( &c32ex, fid ) ) {
                        ok = false;
                        break;
                    }
                    control->HelpId = c32ex.HelpId;
                    control->ExtendedStyle = c32ex.ExtendedStyle;
                    control->Style = c32ex.Style;
                    control->Size = c32ex.Size;
                    control->ID = c32ex.ID;
                    control->ClassID = c32ex.ClassID;
                    control->Text = c32ex.Text;
                    control->ExtraBytes = c32ex.ExtraBytes;
                } else {
                    if( ResReadDialogBoxControl32( &c32, fid ) ) {
                        ok = false;
                        break;
                    }
                    control->Style = c32.Style;
                    control->ExtendedStyle = c32.ExtendedStyle;
                    control->Size = c32.Size;
                    control->ID = c32.ID;
                    control->ClassID = c32.ClassID;
                    control->Text = c32.Text;
                    control->ExtraBytes = c32.ExtraBytes;
                }
            } else {
                if( ResReadDialogBoxControl( &c16, fid ) ) {
                    ok = false;
                    break;
                }
                control->Size = c16.Size;
                control->ID = c16.ID;
                control->Style = c16.Style;
                control->ClassID = c16.ClassID;
                control->Text = c16.Text;
                control->ExtraBytes = c16.ExtraBytes;
            }
            if ( prev_control == NULL ) {
                ListAddElt( &dlg_info->control_list, (void *)control );
                prev_control = dlg_info->control_list;
            } else {
                ListInsertElt( prev_control, (void *)control );
                prev_control = ListNext( prev_control );
            }
        }
    }

#if 0
    /*
     * JPK - if the dialog is 32 bit but not EX, then convert the dialog
     *       header and the control list to EX; this will force all
     *       dialogs to EX, for now
    */
    if( is32bit && !dlg_info->dialog_header->is32bitEx ) {
        /* deal with the dialog header first */
        dlg_info->dialog_header->is32bitEx = TRUE;

        dlg_info->dialog_header->FontWeight = 0;
        dlg_info->dialog_header->FontItalic = 0;
        dlg_info->dialog_header->FontCharset = DEFAULT_CHARSET;
        dlg_info->dialog_header->HelpId = 0;
        dlg_info->dialog_header->FontWeightDefined = FALSE;
        dlg_info->dialog_header->FontItalicDefined = FALSE;
        dlg_info->dialog_header->FontCharsetDefined = FALSE;

        /* now deal with the list of controls */
        nc = (WdeDialogBoxControl *)WRMemAlloc( sizeof( WdeDialogBoxControl ) );
        for( clist = dlg_info->control_list; clist != NULL; clist = ListNext( clist ) ) {
            control = (WdeDialogBoxControl *)ListElement( clist );
            memcpy( nc, control, sizeof( WdeDialogBoxControl ) );

            nc->HelpId = 0;
            nc->ExtendedStyle = control->ExtendedStyle;
            nc->Style = control->Style;
            memcpy( &nc->Size, &control->Size, sizeof( DialogSizeInfo ) );
            nc->ID = control->ID;
            nc->ClassID = control->ClassID;
            nc->Text = control->Text;
            nc->ExtraBytes = control->ExtraBytes;

            memcpy( control, nc, sizeof( WdeDialogBoxControl ) );
        }
        WRMemFree( nc );
    }
#endif

    if( !ok ) {
        if( dlg_info != NULL ) {
            WdeFreeDialogBoxInfo( dlg_info );
            dlg_info = NULL;
        }
    }

    if( fid != WRES_NIL_HANDLE ) {
        ResCloseFile( fid );
    }

    return( dlg_info );
}
Beispiel #12
0
void SemWINWriteVerInfo( WResID * name, ResMemFlags flags,
                        VerFixedInfo * info, FullVerBlockNest * nest )
/********************************************************************/
{
    WResLangType    lang;
    VerBlockHeader  root;
    ResLocation     loc;
    int             padding;
    bool            error;
    bool            use_unicode;
    uint_8          os;
    int             err_code;

    if( CmdLineParms.TargetOS == RC_TARGET_OS_WIN32 ) {
        use_unicode = true;
        os = WRES_OS_WIN32;
    } else {
        use_unicode = false;
        os = WRES_OS_WIN16;
    }
    root.Key = "VS_VERSION_INFO";
    root.ValSize = sizeof(VerFixedInfo);
    root.Type = 0;
    padding = RES_PADDING( root.ValSize, sizeof(uint_32) );
    root.Size = ResSizeVerBlockHeader( &root, use_unicode, os )
                    + root.ValSize + padding + CalcNestSize( nest );
    /* pad the start of the resource so that padding within the resource */
    /* is easier */
    error = ResPadDWord( CurrResFile.handle );
    if( error ) {
        err_code = LastWresErr();
        goto OutputWriteError;
    }

    if( !ErrorHasOccured ) {
        loc.start = SemStartResource();

        error = ResWriteVerBlockHeader( &root, use_unicode, os,
                                        CurrResFile.handle);
        if( error ) {
            err_code = LastWresErr();
            goto OutputWriteError;
        }

        error = ResWriteVerFixedInfo( info, CurrResFile.handle );
        if( error ) {
            err_code = LastWresErr();
            goto OutputWriteError;
        }

        if( ResSeek( CurrResFile.handle, padding, SEEK_CUR ) == -1 )  {
            err_code = LastWresErr();
            goto OutputWriteError;
        }

        error = SemWriteVerBlockNest( nest, CurrResFile.handle, &err_code );
        if( error)
            goto OutputWriteError;

        loc.len = SemEndResource( loc.start );

        /* version info resources must be language neutral */

        lang.lang = DEF_LANG;
        lang.sublang = DEF_SUBLANG;
        SemWINSetResourceLanguage( &lang, false );
        SemAddResourceFree( name, WResIDFromNum( RT_VERSIONINFO ), flags, loc );
    } else {
        RCFREE( name );
    }

    RCFREE( info );
    FreeVerBlockNest( nest );

    return;

OutputWriteError:
    RcError( ERR_WRITTING_RES_FILE, CurrResFile.filename,
                strerror( err_code )  );
    ErrorHasOccured = true;
    RCFREE( info );
    FreeVerBlockNest( nest );
    return;
}
Beispiel #13
0
static void copyMSFormatRes( WResID * name, WResID * type, ResMemFlags flags,
                ResLocation loc, WResLangType *lang )
/***************************************************************************/
{
    MResResourceHeader  ms_head;
    long                cur_byte_num;
    uint_8              cur_byte;
    long                seek_rc;
    int                 error;
    int                 tmp_handle;

    /* fill in and output a MS format resource header */
    ms_head.Type = WResIDToNameOrOrd( type );
    ms_head.Name = WResIDToNameOrOrd( name );
    ms_head.MemoryFlags = flags;
    ms_head.Size = loc.len;
    ms_head.LanguageId = MAKELANGID( lang->lang, lang->sublang );
    ms_head.Version = 0L; /* Currently Unsupported */
    ms_head.DataVersion = 0L;
    ms_head.Characteristics = 0L; /* Currently Unsupported */

    /* OS/2 resource header happens to be identical to Win16 */
    if( CmdLineParms.TargetOS == RC_TARGET_OS_WIN16 ||
        CmdLineParms.TargetOS == RC_TARGET_OS_OS2 ) {
        error = MResWriteResourceHeader( &ms_head, CurrResFile.handle, FALSE );
    } else {
        error = MResWriteResourceHeader( &ms_head, CurrResFile.handle, TRUE );
    }
    if (error) {
        RcError( ERR_WRITTING_RES_FILE, CurrResFile.filename,
                 LastWresErrStr() );
        RcMemFree( ms_head.Type );
        RcMemFree( ms_head.Name );
        ErrorHasOccured = TRUE;
    } else {
        RcMemFree( ms_head.Type );
        RcMemFree( ms_head.Name );
        tmp_handle = ResOpenFileRO( MSFormatTmpFile );
        if (tmp_handle == -1) {
            RcError( ERR_OPENING_TMP, MSFormatTmpFile, LastWresErrStr() );
            ErrorHasOccured = TRUE;
            return;
        }

        /* copy the data from the temperary file to the RES file */
        seek_rc = ResSeek( tmp_handle, loc.start, SEEK_SET );
        if (seek_rc == -1) {
            RcError( ERR_READING_TMP, MSFormatTmpFile, LastWresErrStr() );
            ResCloseFile( tmp_handle );
            ErrorHasOccured = TRUE;
            return;
        }

        /* this is very inefficient but hopefully the buffering in layer0.c */
        /* will make it tolerable */
        for (cur_byte_num = 0; cur_byte_num < loc.len; cur_byte_num++) {
            error = ResReadUint8( &cur_byte, tmp_handle );
            if( error ) {
                RcError( ERR_READING_TMP, MSFormatTmpFile, LastWresErrStr() );
                ResCloseFile( tmp_handle );
                ErrorHasOccured = TRUE;
                return;
            } else {
                error = ResWriteUint8( &cur_byte, CurrResFile.handle );
                if( error ) {
                    RcError( ERR_WRITTING_RES_FILE,
                             CurrResFile.filename, LastWresErrStr() );
                    ResCloseFile( tmp_handle );
                    ErrorHasOccured = TRUE;
                    return;
                }
            }
        }
        if( ResCloseFile( tmp_handle ) == -1 ) {
            RcError( ERR_WRITTING_RES_FILE, MSFormatTmpFile,
                     LastWresErrStr() );
            ErrorHasOccured = TRUE;
        }
    }
}