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

📄 wrrdwnt.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 "wrrdwnt.h"
#include "wrfindt.h"
#include "wrmem.h"
#include "wrmsg.h"
#include "wrcmsg.gh"

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

/****************************************************************************/
/* macro definitions                                                        */
/****************************************************************************/
#define PE_OFFSET                 0x3c

/****************************************************************************/
/* type definitions                                                         */
/****************************************************************************/

/****************************************************************************/
/* static function prototypes                                               */
/****************************************************************************/
static int        WRIsHeaderValidWINNT      ( pe_header * );
static int        WRWinNTHeaderHasResourceTable  ( pe_header * );
static int        WRCalcObjTableOffset      ( WResFileID, pe_header * );
static int        WRReadNTObjectTable       ( WResFileID, pe_header *,
                                              pe_object ** );
static int        WRLoadWResDirFromWinNTEXE ( WResFileID, WResDir * );
static int        WRHandleWinNTTypeDir      ( WResFileID, WResDir *,
                                              uint_32 );
static int        WRHandleWinNTTypeEntry    ( WResFileID, WResDir *,
                                              resource_dir_entry *, int );
static int        WRHandleWinNTNameDir      ( WResFileID, WResDir *,
                                              WResID *, uint_32 );
static int        WRHandleWinNTNameEntry    ( WResFileID, WResDir *, WResID *,
                                              resource_dir_entry *, int );
static int        WRHandleWinNTLangIDDir    ( WResFileID, WResDir *,
                                              WResID *, WResID *, uint_32 );
static int        WRHandleWinNTLangIDEntry  ( WResFileID, WResDir *, WResID *,
                                              WResID *, resource_dir_entry * );
static int        WRReadResourceHeader      ( WResFileID, uint_32,
                                              resource_dir_header *,
                                              resource_dir_entry ** );
static WResID    *WRGetUniCodeWResID        ( WResFileID, uint_32 );

/****************************************************************************/
/* static variables                                                         */
/****************************************************************************/
static uint_32 res_offset = 0;
static uint_32 res_rva    = 0;

#define WR_MAP_DATA_RVA(rva)    (uint_32)((rva-res_rva) + res_offset)
#define WR_MAP_RES_RVA(rva)     (uint_32)(rva+res_offset)

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

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

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

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

    return ( ok );
}

long int WRReadWinNTExeHeader ( WResFileID file_handle, pe_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, 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, header, sizeof(pe_header) ) ==
               sizeof(pe_header) );
    }

    /* check for valid Win NT 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 );
}

int WRCalcObjTableOffset ( WResFileID file, pe_header *hdr )
{
    uint_16  pe_offset;
    int      offset;
    int      ok;

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

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

    if ( ok ) {
        offset = pe_offset + hdr->nt_hdr_size + offsetof(pe_header,magic);
    } else {
        offset = 0;
    }

    return ( offset );
}

int WRReadNTObjectTable ( WResFileID file, pe_header *hdr, pe_object **ot )
{
    int size;
    int ot_offset;

    ot_offset = WRCalcObjTableOffset ( file, hdr );
    if ( !ot_offset || ( ResSeek ( file, ot_offset, SEEK_SET ) ) == -1 ) {
        return ( FALSE );
    }
    size = ( sizeof(pe_object) * hdr->num_objects );
    *ot = (pe_object *) WRMemAlloc ( size );
    if ( *ot ) {
        if ( read ( file, *ot, size ) != size ) {
            WRMemFree ( *ot );
            *ot = NULL;
        }
    }

    return ( *ot != NULL );
}

int WRIsHeaderValidWINNT ( pe_header *header )
{
    /* at some point will we have to check the CPUTYPE ????!!!! */
    return ( header->signature == PE_SIGNATURE );
}

int WRWinNTHeaderHasResourceTable ( pe_header *header )
{
    return ( ( header->num_tables > PE_TBL_RESOURCE ) &&
               header->table[PE_TBL_RESOURCE].rva     &&
               header->table[PE_TBL_RESOURCE].size );
}

int WRLoadWResDirFromWinNTEXE ( WResFileID file_handle, WResDir *dir )
{
    pe_header            nt_header;
    pe_object           *otable;
    uint_32              physical_size;
    uint_32              physical_offset;
    int                  i;
    int                 ok;

    ok = ( file_handle != -1 );

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

    if ( ok ) {
        ok = ( WRReadWinNTExeHeader ( file_handle, &nt_header ) != 0 );
    }

    /* check if a resource table is present */
    if ( ok ) {
        ok = WRWinNTHeaderHasResourceTable ( &nt_header );
        if ( !ok ) {
            WRDisplayErrorMsg( WR_EXENORES );
            return ( TRUE );
        }
    }

    /* read NT object table */
    otable = NULL;
    if ( ok ) {
        ok = WRReadNTObjectTable ( file_handle, &nt_header, &otable );
    }

    /* find resource object in object table */
    if ( ok ) {
        physical_size   = 0;
        physical_offset = 0;
        for ( i=0; i<nt_header.num_objects; i++ ) {
            if ( otable[i].rva == nt_header.table[PE_TBL_RESOURCE].rva ) {
                physical_size   = otable[i].physical_size;
                physical_offset = otable[i].physical_offset;
                break;
            }
        }
        ok = ( physical_size && physical_offset &&
               !( physical_size % nt_header.file_align ) &&
               !( physical_offset % nt_header.file_align ) );
    }

    if ( otable ) {
        WRMemFree ( otable );
    }

    /* read the resource information */
    if ( ok ) {
        res_offset = physical_offset;
        res_rva    = nt_header.table[PE_TBL_RESOURCE].rva;
        ok = WRHandleWinNTTypeDir ( file_handle, dir, physical_offset );
    }

    return ( ok );
}

int WRHandleWinNTTypeDir ( WResFileID file, WResDir *dir, uint_32 offset )
{
    resource_dir_header  rd_hdr;
    resource_dir_entry  *rd_entry;
    int                  i;
    int                 ok;

    ok = WRReadResourceHeader ( file, offset, &rd_hdr, &rd_entry );

    if ( ok ) {
        for ( i=0; i<rd_hdr.num_name_entries; i++ ) {
            WRHandleWinNTTypeEntry ( file, dir, &(rd_entry[i]), TRUE );
        }
        for ( i=rd_hdr.num_name_entries;
              i<(rd_hdr.num_name_entries + rd_hdr.num_id_entries); i++ ) {
            WRHandleWinNTTypeEntry ( file, dir, &(rd_entry[i]), FALSE );
        }
        WRMemFree ( rd_entry );

⌨️ 快捷键说明

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