int CompareResources( WResFileID fid1, WResDir dir1, WResFileID fid2, WResDir dir2 ) /*****************************************************/ { int retcode; int oldretcode; WResDirWindow wind1; WResDirWindow wind2; oldretcode = 0; if (WResIsEmpty( dir1 )) { if (WResIsEmpty( dir2 )) { return( 0 ); } else { return( 1 ); } } else { wind1 = WResFirstResource( dir1 ); while( !WResIsEmptyWindow( wind1 ) ) { /* find the window in dir2 over the same resource */ wind2 = LookUpResource( wind1, dir2 ); if ( !WResIsEmptyWindow( wind2 ) ) { /* compare the contents of the actual resource */ retcode = CompareOneResource( fid1, wind1, fid2, wind2 ); switch (retcode) { case -1: return( -1 ); break; case 1: if (!CmdLineParms.CheckAll) { return( 1 ); } else { oldretcode = 1; } break; } } else { if (!CmdLineParms.CheckAll) { return( 1 ); } else { oldretcode = 1; } } wind1 = WResNextResource( wind1, dir1 ); } /* while */ } /* if dir is empty */ 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++; } }
static bool copyResourcesFromRes( const char *full_filename ) /***********************************************************/ { WResFileID fid; WResDir dir; bool dup_discarded; WResDirWindow wind; char *buffer; bool error; buffer = NULL; dir = WResInitDir(); fid = RcIoOpenInput( full_filename, false ); if( fid == WRES_NIL_HANDLE ) { RcError( ERR_CANT_OPEN_FILE, full_filename, strerror( errno ) ); goto HANDLE_ERROR; } error = WResReadDir( fid, dir, &dup_discarded ); if( error ) { switch( LastWresStatus() ) { case WRS_BAD_SIG: RcError( ERR_INVALID_RES, full_filename ); break; case WRS_BAD_VERSION: RcError( ERR_BAD_RES_VER, full_filename ); break; default: RcError( ERR_READING_RES, full_filename, LastWresErrStr() ); break; } goto HANDLE_ERROR; } if( WResGetTargetOS( dir ) != WResGetTargetOS( CurrResFile.dir ) ) { RcError( ERR_RES_OS_MISMATCH, full_filename ); goto HANDLE_ERROR; } buffer = RESALLOC( BUFFER_SIZE ); wind = WResFirstResource( dir ); while( !WResIsEmptyWindow( wind ) ) { copyAResource( fid, &wind, buffer, full_filename ); wind = WResNextResource( wind, dir ); } RESFREE( buffer ); WResFreeDir( dir ); RESCLOSE( fid ); return( false ); HANDLE_ERROR: ErrorHasOccured = true; WResFreeDir( dir ); if( fid != WRES_NIL_HANDLE ) RESCLOSE( fid ); return( true ); }
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 */
/* * WResAddResource - Add the new entry to the directory. If type is NULL the * default is used. If the entry is already in the * directory don't add anything, set duplicate TRUE * and return an error. Return is TRUE if any error has * occured (including duplicate entry) */ int WResAddResource( const WResID *type, const WResID *name, uint_16 memflags, off_t offset, uint_32 length, WResDir currdir, WResLangType *lang, int *duplicate ) /************************************************************/ { int rc; WResDirWindow dup; rc = WResAddResource2( type, name, memflags, offset, length, currdir, lang, &dup, NULL ); if( duplicate != NULL ) { *duplicate = !WResIsEmptyWindow( dup ); } return( rc ); }
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 ); }
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 */
static int readMResDir( WResFileID handle, WResDir currdir, int *dup_discarded, char iswin32, void *fileinfo ) /******************************************************************************/ { MResResourceHeader *head = NULL; M32ResResourceHeader *head32 = NULL; WResDirWindow dup; int error; off_t seek_rc; WResID *name; WResID *type; error = FALSE; if( iswin32 ) { /* Read NULL header */ head32 = M32ResReadResourceHeader( handle ); if( head32 != NULL ) { MResFreeResourceHeader( head32->head16 ); WRESFREE( head32 ); } else { error = TRUE; } if( !error ) { head32 = M32ResReadResourceHeader( handle ); if( head32 != NULL ) { head = head32->head16; } else { error = TRUE; } } } else { head = MResReadResourceHeader( handle ); if( head == NULL ) error = TRUE; } if( dup_discarded != NULL ) { *dup_discarded = FALSE; } if( iswin32 ) { currdir->TargetOS = WRES_OS_WIN32; } else { currdir->TargetOS = WRES_OS_WIN16; } /* assume that a NULL head is the EOF which is the only way of detecting */ /* the end of a MS .RES file */ while( head != NULL && !( iswin32 && head32 == NULL ) && !error ) { name = WResIDFromNameOrOrd( head->Name ); type = WResIDFromNameOrOrd( head->Type ); error = (name == NULL || type == NULL); /* MResReadResourceHeader leaves the file at the start of the resource*/ if( !error ) { if( !type->IsName && type->ID.Num == RT_NAMETABLE ) { error = FALSE; } else { error = WResAddResource2( type, name, head->MemoryFlags, WRESTELL( handle ), head->Size, currdir, NULL, &dup, fileinfo ); if( error && !WResIsEmptyWindow( dup ) ) { error = FALSE; if( dup_discarded != NULL ) { *dup_discarded = TRUE; } } } } if( !error ) { seek_rc = WRESSEEK( handle, head->Size, SEEK_CUR ); if( seek_rc == -1L ) { error = TRUE; WRES_ERROR( WRS_SEEK_FAILED ); } } if( name != NULL ) { WRESFREE( name ); name = NULL; } if( type != NULL ) { WRESFREE( type ); type = NULL; } MResFreeResourceHeader( head ); if( iswin32 ) { WRESFREE( head32 ); } if( !error ) { if( iswin32 ) { head32 = M32ResReadResourceHeader( handle ); if( head32 != NULL ) { head = head32->head16; } } else { head = MResReadResourceHeader( handle ); } } } return( error ); } /* readMResDir */