📄 wrrdwnt.c
字号:
/****************************************************************************
*
* 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 + -