📄 exerespe.c
字号:
}
}
return( RS_OK );
}
/*
* writeEntry-
* NB when an error occurs this function MUST return without altering errno
*/
static RcStatus writeEntry( PEResEntry * entry, void * _handle )
/**************************************************************/
{
int *handle = _handle;
if( entry->IsDirEntry ) {
return( writeDirEntry( &entry->u.Dir, *handle ) );
} else {
return( writeDataEntry( &entry->u.Data, *handle ) );
}
} /* writeEntry */
/*
* writeDirectory
* NB when an error occurs this function MUST return without altering errno
*/
static RcStatus writeDirectory( PEResDir * dir, int handle )
/********************************************************************/
{
long seek_rc;
int num_wrote;
RcStatus ret;
seek_rc = RcSeek( handle, dir->ResOffset, SEEK_SET );
if( seek_rc == -1 ) return( RS_WRITE_ERROR );
/* write the root entry header */
ret = writeDirEntry( &dir->Root, handle );
if( ret != RS_OK ) return( ret );
ret = traverseTree( dir, &handle, writeEntry );
if( ret != RS_OK ) return( ret );
if( dir->String.StringBlock != 0 ) {
num_wrote = RcWrite( handle, dir->String.StringBlock,
dir->String.StringBlockSize );
if( num_wrote != dir->String.StringBlockSize ) {
return( RS_WRITE_ERROR );
}
}
return( RS_OK );
} /* writeDirectory */
static void FreeSubDir( PEResDirEntry * subdir )
/**********************************************/
{
int num_children;
PEResEntry * last_child;
PEResEntry * curr;
num_children = subdir->Head.num_id_entries + subdir->Head.num_name_entries;
last_child = subdir->Children + num_children;
curr = subdir->Children;
while( curr < last_child ) {
if( curr->IsDirEntry ) {
FreeSubDir( &curr->u.Dir );
}
curr++;
}
RcMemFree( subdir->Children );
}
static void FreePEResDir( PEResDir * dir )
/****************************************/
{
FreeSubDir( &dir->Root );
RcMemFree( dir->String.StringBlock );
RcMemFree( dir->String.StringList );
}
#ifndef INSIDE_WLINK
extern int RcPadFile( int handle, long pad )
/******************************************/
{
char zero = 0;
if( pad > 0 ) {
if( RcSeek( handle, pad - 1, SEEK_CUR ) == -1 ) {
return( TRUE );
}
if( RcWrite( handle, &zero, 1 ) != 1 ) {
return( TRUE );
}
}
return( FALSE );
}
#endif
/*
* padObject
* NB when an error occurs this function MUST return without altering errno
*/
static int padObject( PEResDir *dir, ExeFileInfo *tmp, long size )
{
long pos;
long pad;
pos = RcTell( tmp->Handle );
if( pos == -1 ) return( TRUE );
pad = dir->ResOffset + size - pos;
if( pad > 0 ) {
RcPadFile( tmp->Handle, pad );
}
CheckDebugOffset( tmp );
return( FALSE );
#if(0)
long seek_rc;
char zero=0;
seek_rc = RcSeek( tmp->Handle, dir->ResOffset, SEEK_SET );
if( seek_rc == -1 ) return( TRUE );
seek_rc = RcSeek( tmp->Handle, size-1, SEEK_CUR );
if( seek_rc == -1 ) return( TRUE );
if( RcWrite( tmp->Handle, &zero, 1 ) != 1 ) return( TRUE );
CheckDebugOffset( tmp );
return( FALSE );
#endif
}
static void fillResourceObj( pe_object *res_obj, PEResDir *dir,
uint_32 alignment )
/****************************************************************/
{
strncpy( res_obj->name, RESOURCE_OBJECT_NAME, PE_OBJ_NAME_LEN );
res_obj->virtual_size = 0;
res_obj->rva = dir->ResRVA;
res_obj->physical_size = ALIGN_VALUE( dir->ResSize, alignment );
res_obj->physical_offset = dir->ResOffset;
res_obj->relocs_rva = 0;
res_obj->linnum_rva = 0;
res_obj->num_relocs = 0;
res_obj->num_linnums = 0;
res_obj->flags = PE_OBJ_INIT_DATA | PE_OBJ_READABLE;
}
// merge the directories of all the res files into one large directory
// stored on the first resfileinfo node
int mergeDirectory( ResFileInfo *resfiles, WResMergeError **errs )
/******************************************************************/
{
ResFileInfo *cur;
if( errs != NULL ) *errs = NULL;
if( resfiles == NULL ) return( FALSE );
cur = resfiles->next;
while( cur != NULL ) {
if( WResMergeDirs( resfiles->Dir, cur->Dir, errs ) ) {
return( TRUE );
}
cur = cur->next;
}
return( FALSE );
}
static void setDataOffsets( PEResDir *dir, unsigned_32 *curr_rva,
ResFileInfo *resfiles, int writebyfile )
/****************************************************************/
{
DataEntryCookie cookie;
cookie.rva = curr_rva;
if( writebyfile ) {
while( resfiles != NULL ) {
cookie.curfile = resfiles;
traverseTree( dir, &cookie, setDataEntry );
resfiles = resfiles->next;
}
} else {
cookie.curfile = NULL;
traverseTree( dir, &cookie, setDataEntry );
}
}
#define NAME_LEN 256
static void reportDuplicateResources( WResMergeError *errs )
/************************************************************/
{
WResMergeError *curerr;
ResFileInfo *file1;
ResFileInfo *file2;
WResResInfo *resinfo;
WResTypeInfo *typeinfo;
curerr = errs;
while( curerr != NULL ) {
resinfo = WResGetResInfo( curerr->dstres );
typeinfo = WResGetTypeInfo( curerr->dstres );
file1 = WResGetFileInfo( curerr->dstres );
file2 = WResGetFileInfo( curerr->srcres );
ReportDupResource( &resinfo->ResName, &typeinfo->TypeName,
file1->name, file2->name, FALSE );
curerr = curerr->next;
}
}
extern int BuildResourceObject( ExeFileInfo *exeinfo, ResFileInfo *resinfo,
pe_object *res_obj, unsigned_32 rva,
unsigned_32 offset, int writebyfile )
/**************************************************************************/
{
PEResDir * dir;
RcStatus status;
unsigned_32 curr_rva;
WResMergeError *errs;
ResFileInfo *errres;
dir = &exeinfo->u.PEInfo.Res;
mergeDirectory( resinfo, &errs );
if( errs != NULL ) {
reportDuplicateResources( errs );
WResFreeMergeErrors( errs );
return( TRUE );
}
if( PEResDirBuild( dir, resinfo->Dir ) ) {
RcError( ERR_INTERNAL, INTERR_ERR_BUILDING_RES_DIR );
return( TRUE );
}
CompleteTree( dir );
exeinfo->u.PEInfo.Res.ResOffset = offset;
exeinfo->u.PEInfo.Res.ResRVA = rva;
curr_rva = rva + exeinfo->u.PEInfo.Res.DirSize
+ exeinfo->u.PEInfo.Res.String.StringBlockSize;
curr_rva = ALIGN_VALUE( curr_rva, sizeof( uint_32 ) );
setDataOffsets( dir, &curr_rva, resinfo, writebyfile );
status = writeDirectory( dir, exeinfo->Handle );
if( status != RS_OK ) {
RcError( ERR_WRITTING_FILE, exeinfo->name, strerror( errno ) );
return( TRUE );
}
status = copyPEResources( exeinfo, resinfo, exeinfo->Handle,
writebyfile, &errres );
// warning - the file names output in these messages could be
// incorrect if the -fr switch is in use
if( status != RS_OK ) {
switch( status ) {
case RS_WRITE_ERROR:
RcError( ERR_WRITTING_FILE, exeinfo->name, strerror( errno ) );
break;
case RS_READ_ERROR:
RcError( ERR_READING_RES, errres->name, strerror( errno ) );
break;
case RS_OPEN_ERROR:
RcError( ERR_CANT_OPEN_FILE, errres->name, strerror( errno ) );
case RS_READ_INCMPLT:
RcError( ERR_UNEXPECTED_EOF, errres->name );
break;
default:
RcError( ERR_INTERNAL, INTERR_UNKNOWN_RCSTATUS );
break;
}
return( TRUE );
}
exeinfo->u.PEInfo.Res.ResSize = curr_rva - rva;
fillResourceObj( res_obj, dir, exeinfo->u.PEInfo.WinHead->file_align );
if( padObject( dir, exeinfo, res_obj->physical_size ) ) {
RcError( ERR_WRITTING_FILE, exeinfo->name, strerror( errno ) );
return( TRUE );
}
/* set the resource element of the table in the header */
exeinfo->u.PEInfo.WinHead->table[ PE_TBL_RESOURCE ].rva = res_obj->rva;
exeinfo->u.PEInfo.WinHead->table[ PE_TBL_RESOURCE ].size =
res_obj->physical_size;
FreePEResDir( dir );
return( FALSE );
} /* BuildResourceObject */
#ifndef INSIDE_WLINK
int RcBuildResourceObject( void ) {
/***********************************/
pe_object *res_obj;
unsigned_32 rva;
unsigned_32 offset;
RcStatus error;
ExeFileInfo *exeinfo;
exeinfo = &Pass2Info.TmpFile;
if( CmdLineParms.NoResFile ) {
exeinfo->u.PEInfo.WinHead->table[ PE_TBL_RESOURCE ].rva = 0;
exeinfo->u.PEInfo.WinHead->table[ PE_TBL_RESOURCE ].size = 0;
error = RS_OK;
} else {
res_obj = exeinfo->u.PEInfo.Objects
+ exeinfo->u.PEInfo.WinHead->num_objects - 1;
rva = GetNextObjRVA( &exeinfo->u.PEInfo );
offset = GetNextObjPhysOffset( &exeinfo->u.PEInfo );
error = BuildResourceObject( exeinfo, Pass2Info.ResFiles,
res_obj, rva, offset,
!Pass2Info.AllResFilesOpen );
// use of CmdLineParms.WritableRes has been commented out in param.c
// removed here too as it wasn't initialised anymore (Ernest ter Kuile 31 aug 2003)
// if( CmdLineParms.WritableRes ) {
// res_obj->flags |= PE_OBJ_WRITABLE;
// }
}
return( error );
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -