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

📄 wrrdw16.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include <windows.h>
#include <string.h>
#include <io.h>

#include "wrglbl.h"
#include "wrrdw16.h"
#include "wrfindt.h"
#include "wrmem.h"
#include "wrmsg.h"
#include "wrcmsg.gh"

/****************************************************************************/
/* external function prototypes                                             */
/****************************************************************************/

/****************************************************************************/
/* macro definitions                                                        */
/****************************************************************************/
#define NAME_TABLE_MAX   8192
#define WR_RT_NAMETABLE  15

/****************************************************************************/
/* type definitions                                                         */
/****************************************************************************/
typedef struct WRNameInfoStruct {
    uint_16 offset;
    uint_16 length;
    uint_16 flags;
    uint_16 id;
    uint_16 handle;
    uint_16 usage;
} WRNameInfo;

typedef struct WRNameTableEntry {
    uint_16 length;
    uint_16 type;
    uint_16 id;
    uint_8  no_idea;
    char    name[1];
} WRNameTableEntry;

/****************************************************************************/
/* static function prototypes                                               */
/****************************************************************************/
static int          WRLoadWResDirFromWin16EXE ( WResFileID, WResDir * );
static int          WRIsHeaderValidWIN16      ( os2_exe_header * );
static int          WRWin16HeaderHasResourceTable  ( os2_exe_header * );
static WResTypeNode *WRReadWResTypeNodeFromExe ( WResFileID, uint_16 );
static WResResNode  *WRReadWResResNodeFromExe  ( WResFileID, uint_16 );
static int          WRReadResourceNames       ( WResDir, WResFileID,
                                                  uint_32 );
static int          WRSetResName              ( WResDir, uint_32, char * );
static WResTypeNode *WRRenameWResTypeNode      ( WResDir, WResTypeNode *,
                                                  char * );
static WResResNode  *WRRenameWResResNode       ( WResTypeNode *,
                                                  WResResNode *, char * );
static uint_32       WRReadNameTable           ( WResDir, WResFileID,
                                                  uint_8 **, uint_32,
                                                  uint_8 * );
static uint_32       WRUseNameTable            ( WResDir, uint_8 *, uint_32,
                                                  uint_8 ** );
static int          WRSetResNameFromNameTable ( WResDir,
                                                  WRNameTableEntry * );

/****************************************************************************/
/* static variables                                                         */
/****************************************************************************/

int WRLoadResourceFromWin16EXE ( WRInfo *info )
{
    WResFileID file_handle;
    int       ok;

    ok = ( ( file_handle = ResOpenFileRO ( info->file_name ) ) != -1 );

    if ( ok ) {
        ok = WRLoadWResDirFromWin16EXE ( file_handle, &info->dir );
    }

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

    return ( ok );
}

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 );

    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 Win 16 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 );
    }
}

int WRIsHeaderValidWIN16 ( os2_exe_header  *header )
{
    if ( ( header->signature == OS2_SIGNATURE_WORD ) &&
         ( header->expver >= 0x300 ) ) {
        return ( TRUE );
    }

    return ( FALSE );
}

int WRWin16HeaderHasResourceTable ( os2_exe_header  *header )
{
    if ( header->resource_off != header->resident_off ) {
        return ( TRUE );
    }

    return ( FALSE );
}

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 ) {
            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 ) {
            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 );
}

WResTypeNode *WRReadWResTypeNodeFromExe ( WResFileID file_handle,
                                           uint_16 align_shift )
{
    uint_16       type_id;
    uint_16       resource_count;
    uint_32       reserved;
    WResTypeNode *type_node;
    WResResNode  *res_node;

    ResReadUint16( &type_id, file_handle);
    if ( type_id == 0x0000 ) {
        return ( NULL );
    }

    type_node = (WResTypeNode *) WRMemAlloc ( sizeof(WResTypeNode) );
    if ( type_node == NULL ) {
        return ( NULL );
    }

    ResReadUint16( &resource_count, file_handle);
    ResReadUint32( &reserved, file_handle);

    type_node->Next = NULL;
    type_node->Prev = NULL;
    type_node->Head = NULL;
    type_node->Tail = NULL;
    type_node->Info.NumResources = resource_count;
    if ( type_id & 0x8000 ) {
        type_node->Info.TypeName.IsName = FALSE;
    } else {
        type_node->Info.TypeName.IsName = TRUE;
    }
    type_node->Info.TypeName.ID.Num = ( type_id & 0x7fff );

    for ( ; resource_count; resource_count--) {
        res_node = WRReadWResResNodeFromExe ( file_handle, align_shift );
        if ( type_node->Head == NULL ) {
            type_node->Head = res_node;
        }
        if ( type_node->Tail != NULL ) {
            type_node->Tail->Next = res_node;
        }
        res_node->Prev  = type_node->Tail;
        type_node->Tail = res_node;
    }

    return ( type_node );
}

WResResNode  *WRReadWResResNodeFromExe ( WResFileID file, uint_16 align )

⌨️ 快捷键说明

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