static int CompareOneResource( WResFileID fid1, WResDirWindow wind1, WResFileID fid2, WResDirWindow wind2 ) /********************************************************************/ { int retcode; int oldretcode; WResResInfo *res1; WResResInfo *res2; WResLangInfo *lang1; WResLangInfo *lang2; char * resname1; oldretcode = 0; res1 = WResGetResInfo( wind1 ); res2 = WResGetResInfo( wind2 ); lang1 = WResGetLangInfo( wind1 ); lang2 = WResGetLangInfo( wind2 ); if (lang1->MemoryFlags != lang2->MemoryFlags) { if (!CmdLineParms.Quiet) { resname1 = WResIDToStr( &(res1->ResName) ); printf( "Error: memory flags for resource %s are not the same\n", resname1 ); RESFREE( resname1 ); } oldretcode = 1; } if (lang1->Length != lang2->Length) { if (!CmdLineParms.Quiet) { resname1 = WResIDToStr( &(res1->ResName) ); printf( "Error: resource %s does not have the same length\n", resname1 ); RESFREE( resname1 ); } oldretcode = 1; } else { retcode = BinaryCompare( fid1, lang1->Offset, fid2, lang2->Offset, lang1->Length ); switch (retcode) { case 1: if (!CmdLineParms.Quiet) { resname1 = WResIDToStr( &(res1->ResName) ); printf( "Error: contents of resource %s are different.\n", resname1 ); RESFREE( resname1 ); } oldretcode = retcode; break; case -1: oldretcode = retcode; break; } } return( oldretcode ); }
static WResDirWindow LookUpResource( WResDirWindow wind1, WResDir dir2 ) /**********************************************************************/ { WResDirWindow wind2; WResTypeInfo *type1; WResResInfo *res1; WResLangInfo *lang1; char *resname1; type1 = WResGetTypeInfo( wind1 ); res1 = WResGetResInfo( wind1 ); lang1 = WResGetLangInfo( wind1 ); wind2 = WResFindResource( &(type1->TypeName), &(res1->ResName), dir2, &(lang1->lang) ); if (WResIsEmptyWindow( wind2 ) && !CmdLineParms.Quiet) { resname1 = WResIDToStr( &(res1->ResName) ); printf( "Error: Resource %s (lang 0x%X SubLang 0x%X) not in file %s\n", resname1, (int)lang1->lang.lang, (int)lang1->lang.sublang, CmdLineParms.FileName2 ); RESFREE( resname1 ); } return( wind2 ); }
/* Build OS/2 NE style resource table. Each resource gets one entry, and * resources > 64K will get an additional entry for each 64K chunk. */ static void buildOS2ResTable( OS2ResTable *res_tbl, WResDir dir ) /***************************************************************/ { WResDirWindow wind; WResLangInfo *lang; OS2ResEntry *entry; WResTypeInfo *res_type; WResResInfo *resinfo; uint_16 type; uint_16 id; int_32 length; entry = res_tbl->resources; /* Walk through the WRes directory */ for( wind = WResFirstResource( dir ); !WResIsEmptyWindow( wind ); wind = WResNextResource( wind, dir ) ) { lang = WResGetLangInfo( wind ); res_type = WResGetTypeInfo( wind ); resinfo = WResGetResInfo( wind ); // RT_DEFAULTICON is not written into the executable, ignore if( res_type->TypeName.ID.Num == OS2_RT_DEFAULTICON ) { wind = WResNextResource( wind, dir ); continue; } if( res_type->TypeName.IsName ) type = 0; else type = res_type->TypeName.ID.Num; if( resinfo->ResName.IsName ) id = 0; else id = resinfo->ResName.ID.Num; /* Fill in resource entries */ entry->res_type = type; entry->res_id = id; entry->wind = wind; entry->mem_flags = lang->MemoryFlags; entry->seg_length = 0; /* Zero means 64K */ entry->first_part = true; for( length = lang->Length; length > 0x10000; length -= 0x10000 ) { entry++; entry->res_type = type; entry->res_id = id; entry->wind = wind; entry->mem_flags = lang->MemoryFlags; entry->seg_length = 0; entry->first_part = false; } entry->seg_length = lang->Length % 0x10000; entry++; } }
DepInfo *WResGetAutoDep( const char *fname ) { WResFileID handle; WResDir dir; bool dup_discarded; WResID *name; WResID *type; WResDirWindow window; WResLangInfo *info; DepInfo *ret; WResFileSSize numread; ret = NULL; handle = ResOpenFileRO( fname ); if( handle != WRES_NIL_HANDLE ) { if( WResIsWResFile( handle ) && (dir = WResInitDir()) != NULL ) { if( !WResReadDir( handle, dir, &dup_discarded ) ) { name = WResIDFromStr( DEP_LIST_NAME ); type = WResIDFromNum( DEP_LIST_TYPE ); if( name != NULL && type != NULL ) { window = WResFindResource( type, name, dir, NULL ); if( WResIsEmptyWindow( window ) ) { WRES_ERROR( WRS_RES_NOT_FOUND ); } else { info = WResGetLangInfo( window ); if( WRESSEEK( handle, info->Offset, SEEK_SET ) == -1 ) { WRES_ERROR( WRS_SEEK_FAILED ); } else { ret = WRESALLOC( info->Length ); if( ret == NULL ) { WRES_ERROR( WRS_MALLOC_FAILED ); } else { numread = WRESREAD( handle, ret, info->Length ); if( numread != (WResFileSSize)info->Length ) { WRES_ERROR( WRESIOERR( handle, numread ) ? WRS_READ_FAILED : WRS_READ_INCOMPLETE ); ret = NULL; } } } } } if( name != NULL ) { WResIDFree( name ); } if( type != NULL ) { WResIDFree( type ); } } WResFreeDir( dir ); } ResCloseFile( handle ); } return( ret ); }
extern uint_32 ComputeWINResourceSize( WResDir dir ) /**************************************************/ { uint_32 length; WResDirWindow wind; WResLangInfo *res; length = 0; for( wind = WResFirstResource( dir ); !WResIsEmptyWindow( wind ); wind = WResNextResource( wind, dir ) ) { res = WResGetLangInfo( wind ); length += res->Length; } return( length ); } /* ComputeWINResourceSize */
extern int WResLoadResource2( WResDir dir, PHANDLE_INFO hInstance, UINT idType, UINT idResource, LPSTR *lpszBuffer, int *bufferSize ) /******************************************************************/ { int retcode; WResID resource_type; WResID resource_id; WResDirWindow wind; WResLangInfo *res; WResLangType lang; char *res_buffer; if( ( lpszBuffer == NULL ) || ( bufferSize == NULL ) ) { return( -1 ); } lang.lang = DEF_LANG; lang.sublang = DEF_SUBLANG; WResInitIDFromNum( idResource, &resource_id ); WResInitIDFromNum( (long)idType, &resource_type ); wind = WResFindResource( &resource_type, &resource_id, dir, &lang ); if( WResIsEmptyWindow( wind ) ) { retcode = -1; } else { res = WResGetLangInfo( wind ); // lets make sure we dont perturb malloc into apoplectic fits if( res->Length >= INT_MAX ) { return( -1 ); } res_buffer = WRESALLOC( res->Length ); *lpszBuffer = res_buffer; if( *lpszBuffer == NULL ) { return( -1 ); } *bufferSize = (int)res->Length; retcode = GetResource( res, hInstance, res_buffer ); } return( retcode ); }
static bool copyAResource( WResFileID fid, WResDirWindow *wind, char *buffer, const char *filename ) /****************************************************************/ { ResLocation loc; WResLangInfo *langinfo; WResTypeInfo *typeinfo; WResResInfo *resinfo; // RcStatus rc; int err_code; langinfo = WResGetLangInfo( *wind ); resinfo = WResGetResInfo( *wind ); typeinfo = WResGetTypeInfo( *wind ); loc.start = SemStartResource(); /* rc = */ CopyData( langinfo->Offset, langinfo->Length, fid, buffer, BUFFER_SIZE, &err_code ); loc.len = SemEndResource( loc.start ); SemAddResource2( &resinfo->ResName, &typeinfo->TypeName, langinfo->MemoryFlags, loc, filename ); return( false ); }
static bool DumpResource( WResDirWindow wind, WResFileID handle, uint_16 os ) /***************************************************************************/ { bool error; char resname[15]; char typename[20]; WResTypeInfo *type; WResResInfo *res; WResLangInfo *lang; type = WResGetTypeInfo( wind ); res = WResGetResInfo( wind ); lang = WResGetLangInfo( wind ); if( CmdLineParms.Type != NULL ) { if( !WResIDCmp( CmdLineParms.Type, &(type->TypeName) ) ) { return( false ); } } if( CmdLineParms.Name != NULL ) { if( !WResIDCmp( CmdLineParms.Name, &(res->ResName) ) ) { return( false ); } } ConvertIDToStr( &(res->ResName), resname, 15 ); ConvertTypeIDToStr( &(type->TypeName), typename, 20 ); fprintf( stdout, "%-20.20s %-15.15s 0x%04X 0x%02X ", typename, resname, (int)lang->lang.lang, (int)lang->lang.sublang ); PrintUint16Flags( lang->MemoryFlags, MemFlagsOnList, MemFlagsOffList, 53 ); if( CmdLineParms.DumpContents ) { error = DumpContents( type, res, lang, handle, os ); if( error ) { return( true ); } } return( false ); }
int WResLoadResource2( WResDir dir, PHANDLE_INFO hinfo, WResID *resource_type, WResID *resource_id, lpstr *lpszBuffer, size_t *bufferSize ) /*********************************************************************************/ { int retcode; WResDirWindow wind; WResLangInfo *res; WResLangType lang; char *res_buffer; if( ( resource_type == NULL ) || ( resource_id == NULL ) || ( lpszBuffer == NULL ) || ( bufferSize == NULL ) ) { return( -1 ); } lang.lang = DEF_LANG; lang.sublang = DEF_SUBLANG; wind = WResFindResource( resource_type, resource_id, dir, &lang ); if( WResIsEmptyWindow( wind ) ) { retcode = -1; } else { res = WResGetLangInfo( wind ); #ifdef _M_I86 // lets make sure we dont perturb malloc into apoplectic fits if( res->Length > (size_t)(-1LL) ) { return( -1 ); } #endif res_buffer = WRESALLOC( res->Length ); *lpszBuffer = res_buffer; if( *lpszBuffer == NULL ) { return( -1 ); } *bufferSize = (size_t)res->Length; retcode = GetResource( res, hinfo, res_buffer ); } return( retcode ); }
/* Compute the number of resource segments in an OS/2 NE module. Each * resource gets its own segment and resources > 64K will be split into * as many segments as necessary. */ extern uint_32 ComputeOS2ResSegCount( WResDir dir ) /*************************************************/ { uint_32 length; WResDirWindow wind; WResTypeInfo *res_type; WResLangInfo *res; uint_32 num_res_segs; num_res_segs = 0; for( wind = WResFirstResource( dir ); !WResIsEmptyWindow( wind ); wind = WResNextResource( wind, dir ) ) { res = WResGetLangInfo( wind ); res_type = WResGetTypeInfo( wind ); // RT_DEFAULTICON is not written into the executable, ignore if( res_type->TypeName.ID.Num != OS2_RT_DEFAULTICON ) { ++num_res_segs; for( length = res->Length; length > 0x10000; length -= 0x10000 ) { ++num_res_segs; } } } return( num_res_segs ); } /* ComputeOS2ResSegCount */
RcStatus CopyOS2Resources( void ) { OS2ResEntry *entry; WResDirWindow wind; OS2ResTable *restab; WResLangInfo *lang; WResFileID tmphandle; WResFileID reshandle; RcStatus ret; int err_code; int shift_count; int currseg; segment_record *tmpseg; uint_32 seg_offset; long align_amount; int i; restab = &(Pass2Info.TmpFile.u.NEInfo.OS2Res); tmphandle = Pass2Info.TmpFile.Handle; reshandle = Pass2Info.ResFiles->Handle; tmpseg = Pass2Info.TmpFile.u.NEInfo.Seg.Segments; currseg = Pass2Info.OldFile.u.NEInfo.Seg.NumSegs - Pass2Info.OldFile.u.NEInfo.Seg.NumOS2ResSegs; entry = restab->resources; ret = RS_OK; err_code = 0; tmpseg += currseg; shift_count = Pass2Info.TmpFile.u.NEInfo.WinHead.align; seg_offset = 0; // shut up gcc /* We may need to add padding before the first resource segment */ align_amount = AlignAmount( RCTELL( tmphandle ), shift_count ); if( align_amount ) { ret = PadExeData( tmphandle, align_amount ); err_code = errno; } /* Walk through the resource entries */ for( i = 0; i < restab->num_res_segs; i++, entry++, tmpseg++ ) { wind = entry->wind; lang = WResGetLangInfo( wind ); if( entry->first_part ) { seg_offset = RCTELL( tmphandle ); } else { seg_offset += 0x10000; } /* Fill in segment structure */ tmpseg->address = seg_offset >> shift_count; tmpseg->size = entry->seg_length; tmpseg->min = entry->seg_length; tmpseg->info = SEG_DATA | SEG_READ_ONLY | SEG_LEVEL_3; if( entry->mem_flags & MEMFLAG_MOVEABLE ) tmpseg->info |= SEG_MOVABLE; if( entry->mem_flags & MEMFLAG_PURE ) tmpseg->info |= SEG_PURE; if( entry->mem_flags & MEMFLAG_PRELOAD ) tmpseg->info |= SEG_PRELOAD; if( entry->mem_flags & MEMFLAG_DISCARDABLE ) tmpseg->info |= SEG_DISCARD; /* For non-last segment of a resource, there's nothing to copy */ if( !entry->first_part ) continue; /* Copy resource data */ ret = copyOneResource( lang, reshandle, tmphandle, shift_count, &err_code ); if( ret != RS_OK ) break; CheckDebugOffset( &(Pass2Info.TmpFile) ); } switch( ret ) { case RS_WRITE_ERROR: RcError( ERR_WRITTING_FILE, Pass2Info.TmpFile.name, strerror( err_code ) ); break; case RS_READ_ERROR: RcError( ERR_READING_RES, CmdLineParms.OutResFileName, strerror( err_code ) ); break; case RS_READ_INCMPLT: RcError( ERR_UNEXPECTED_EOF, CmdLineParms.OutResFileName ); break; default: break; } return( ret ); } /* CopyOS2Resources */