Updated the resources support with the unmodified Haiku version.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34251 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,220 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2001-2007, Ingo Weinhold, [email protected]. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef _AUTO_DELETER_H
|
||||||
|
#define _AUTO_DELETER_H
|
||||||
|
|
||||||
|
/*! Scope-based automatic deletion of objects/arrays.
|
||||||
|
ObjectDeleter - deletes an object
|
||||||
|
ArrayDeleter - deletes an array
|
||||||
|
MemoryDeleter - free()s malloc()ed memory
|
||||||
|
CObjectDeleter - calls an arbitrary specified destructor function
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
|
||||||
|
// AutoDeleter
|
||||||
|
|
||||||
|
template<typename C, typename DeleteFunc>
|
||||||
|
class AutoDeleter {
|
||||||
|
public:
|
||||||
|
inline AutoDeleter()
|
||||||
|
: fObject(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline AutoDeleter(C *object)
|
||||||
|
: fObject(object)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ~AutoDeleter()
|
||||||
|
{
|
||||||
|
fDelete(fObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SetTo(C *object)
|
||||||
|
{
|
||||||
|
if (object != fObject) {
|
||||||
|
fDelete(fObject);
|
||||||
|
fObject = object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Unset()
|
||||||
|
{
|
||||||
|
SetTo(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Delete()
|
||||||
|
{
|
||||||
|
SetTo(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline C *Get() const
|
||||||
|
{
|
||||||
|
return fObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline C *Detach()
|
||||||
|
{
|
||||||
|
C *object = fObject;
|
||||||
|
fObject = NULL;
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
C *fObject;
|
||||||
|
DeleteFunc fDelete;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ObjectDeleter
|
||||||
|
|
||||||
|
template<typename C>
|
||||||
|
struct ObjectDelete
|
||||||
|
{
|
||||||
|
inline void operator()(C *object)
|
||||||
|
{
|
||||||
|
delete object;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename C>
|
||||||
|
struct ObjectDeleter : AutoDeleter<C, ObjectDelete<C> >
|
||||||
|
{
|
||||||
|
ObjectDeleter() : AutoDeleter<C, ObjectDelete<C> >() {}
|
||||||
|
ObjectDeleter(C *object) : AutoDeleter<C, ObjectDelete<C> >(object) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ArrayDeleter
|
||||||
|
|
||||||
|
template<typename C>
|
||||||
|
struct ArrayDelete
|
||||||
|
{
|
||||||
|
inline void operator()(C *array)
|
||||||
|
{
|
||||||
|
delete[] array;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename C>
|
||||||
|
struct ArrayDeleter : AutoDeleter<C, ArrayDelete<C> >
|
||||||
|
{
|
||||||
|
ArrayDeleter() : AutoDeleter<C, ArrayDelete<C> >() {}
|
||||||
|
ArrayDeleter(C *array) : AutoDeleter<C, ArrayDelete<C> >(array) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// MemoryDeleter
|
||||||
|
|
||||||
|
struct MemoryDelete
|
||||||
|
{
|
||||||
|
inline void operator()(void *memory)
|
||||||
|
{
|
||||||
|
free(memory);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MemoryDeleter : AutoDeleter<void, MemoryDelete >
|
||||||
|
{
|
||||||
|
MemoryDeleter() : AutoDeleter<void, MemoryDelete >() {}
|
||||||
|
MemoryDeleter(void *memory) : AutoDeleter<void, MemoryDelete >(memory) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// CObjectDeleter
|
||||||
|
|
||||||
|
template<typename Type, typename DestructorReturnType>
|
||||||
|
struct CObjectDelete
|
||||||
|
{
|
||||||
|
inline void operator()(Type *object)
|
||||||
|
{
|
||||||
|
if (fDestructor != NULL && object != NULL)
|
||||||
|
fDestructor(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Destructor>
|
||||||
|
inline void operator=(Destructor destructor)
|
||||||
|
{
|
||||||
|
fDestructor = destructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
DestructorReturnType (*fDestructor)(Type*);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Type, typename DestructorReturnType = void>
|
||||||
|
struct CObjectDeleter
|
||||||
|
: AutoDeleter<Type, CObjectDelete<Type, DestructorReturnType> >
|
||||||
|
{
|
||||||
|
typedef AutoDeleter<Type, CObjectDelete<Type, DestructorReturnType> > Base;
|
||||||
|
|
||||||
|
template<typename Destructor>
|
||||||
|
CObjectDeleter(Destructor destructor) : Base()
|
||||||
|
{
|
||||||
|
Base::fDelete = destructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Destructor>
|
||||||
|
CObjectDeleter(Type *object, Destructor destructor) : Base(object)
|
||||||
|
{
|
||||||
|
Base::fDelete = destructor;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// MethodDeleter
|
||||||
|
|
||||||
|
template<typename Type, typename DestructorReturnType>
|
||||||
|
struct MethodDelete
|
||||||
|
{
|
||||||
|
inline void operator()(Type *object)
|
||||||
|
{
|
||||||
|
if (fDestructor && object != NULL)
|
||||||
|
(object->*fDestructor)();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Destructor>
|
||||||
|
inline void operator=(Destructor destructor)
|
||||||
|
{
|
||||||
|
fDestructor = destructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
DestructorReturnType (Type::*fDestructor)();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename Type, typename DestructorReturnType = void>
|
||||||
|
struct MethodDeleter
|
||||||
|
: AutoDeleter<Type, MethodDelete<Type, DestructorReturnType> >
|
||||||
|
{
|
||||||
|
typedef AutoDeleter<Type, MethodDelete<Type, DestructorReturnType> > Base;
|
||||||
|
|
||||||
|
template<typename Destructor>
|
||||||
|
MethodDeleter(Destructor destructor) : Base()
|
||||||
|
{
|
||||||
|
Base::fDelete = destructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Destructor>
|
||||||
|
MethodDeleter(Type *object, Destructor destructor) : Base(object)
|
||||||
|
{
|
||||||
|
Base::fDelete = destructor;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
using BPrivate::ObjectDeleter;
|
||||||
|
using BPrivate::ArrayDeleter;
|
||||||
|
using BPrivate::MemoryDeleter;
|
||||||
|
using BPrivate::CObjectDeleter;
|
||||||
|
using BPrivate::MethodDeleter;
|
||||||
|
|
||||||
|
#endif // _AUTO_DELETER_H
|
||||||
@@ -1,14 +1,30 @@
|
|||||||
// Elf.h
|
/*
|
||||||
|
* Copyright 2002-2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
#ifndef _ELF_H
|
#ifndef _ELF_H
|
||||||
#define _ELF_H
|
#define _ELF_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
|
||||||
// types
|
// types
|
||||||
typedef uint32 Elf32_Addr;
|
typedef uint32 Elf32_Addr;
|
||||||
typedef uint16 Elf32_Half;
|
|
||||||
typedef uint32 Elf32_Off;
|
typedef uint32 Elf32_Off;
|
||||||
|
typedef uint16 Elf32_Half;
|
||||||
typedef int32 Elf32_Sword;
|
typedef int32 Elf32_Sword;
|
||||||
typedef uint32 Elf32_Word;
|
typedef uint32 Elf32_Word;
|
||||||
|
typedef uint32 Elf32_Xword;
|
||||||
|
typedef int32 Elf32_Sxword;
|
||||||
|
|
||||||
|
typedef uint64 Elf64_Addr;
|
||||||
|
typedef uint64 Elf64_Off;
|
||||||
|
typedef uint16 Elf64_Half;
|
||||||
|
typedef int32 Elf64_Sword;
|
||||||
|
typedef uint32 Elf64_Word;
|
||||||
|
typedef uint64 Elf64_Xword;
|
||||||
|
typedef int64 Elf64_Sxword;
|
||||||
|
|
||||||
// e_ident indices
|
// e_ident indices
|
||||||
#define EI_MAG0 0
|
#define EI_MAG0 0
|
||||||
@@ -21,23 +37,9 @@ typedef uint32 Elf32_Word;
|
|||||||
#define EI_PAD 7
|
#define EI_PAD 7
|
||||||
#define EI_NIDENT 16
|
#define EI_NIDENT 16
|
||||||
|
|
||||||
// object file header
|
// e_ident EI_VERSION values
|
||||||
typedef struct {
|
#define EV_NONE 0
|
||||||
unsigned char e_ident[EI_NIDENT];
|
#define EV_CURRENT 1
|
||||||
Elf32_Half e_type;
|
|
||||||
Elf32_Half e_machine;
|
|
||||||
Elf32_Word e_version;
|
|
||||||
Elf32_Addr e_entry;
|
|
||||||
Elf32_Off e_phoff;
|
|
||||||
Elf32_Off e_shoff;
|
|
||||||
Elf32_Word e_flags;
|
|
||||||
Elf32_Half e_ehsize;
|
|
||||||
Elf32_Half e_phentsize;
|
|
||||||
Elf32_Half e_phnum;
|
|
||||||
Elf32_Half e_shentsize;
|
|
||||||
Elf32_Half e_shnum;
|
|
||||||
Elf32_Half e_shstrndx;
|
|
||||||
} Elf32_Ehdr;
|
|
||||||
|
|
||||||
// e_ident EI_CLASS and EI_DATA values
|
// e_ident EI_CLASS and EI_DATA values
|
||||||
#define ELFCLASSNONE 0
|
#define ELFCLASSNONE 0
|
||||||
@@ -47,18 +49,6 @@ typedef struct {
|
|||||||
#define ELFDATA2LSB 1
|
#define ELFDATA2LSB 1
|
||||||
#define ELFDATA2MSB 2
|
#define ELFDATA2MSB 2
|
||||||
|
|
||||||
// program header
|
|
||||||
typedef struct {
|
|
||||||
Elf32_Word p_type;
|
|
||||||
Elf32_Off p_offset;
|
|
||||||
Elf32_Addr p_vaddr;
|
|
||||||
Elf32_Addr p_paddr;
|
|
||||||
Elf32_Word p_filesz;
|
|
||||||
Elf32_Word p_memsz;
|
|
||||||
Elf32_Word p_flags;
|
|
||||||
Elf32_Word p_align;
|
|
||||||
} Elf32_Phdr;
|
|
||||||
|
|
||||||
// p_type
|
// p_type
|
||||||
#define PT_NULL 0
|
#define PT_NULL 0
|
||||||
#define PT_LOAD 1
|
#define PT_LOAD 1
|
||||||
@@ -70,20 +60,6 @@ typedef struct {
|
|||||||
#define PT_LOPROC 0x70000000
|
#define PT_LOPROC 0x70000000
|
||||||
#define PT_HIPROC 0x7fffffff
|
#define PT_HIPROC 0x7fffffff
|
||||||
|
|
||||||
// section header
|
|
||||||
typedef struct {
|
|
||||||
Elf32_Word sh_name;
|
|
||||||
Elf32_Word sh_type;
|
|
||||||
Elf32_Word sh_flags;
|
|
||||||
Elf32_Addr sh_addr;
|
|
||||||
Elf32_Off sh_offset;
|
|
||||||
Elf32_Word sh_size;
|
|
||||||
Elf32_Word sh_link;
|
|
||||||
Elf32_Word sh_info;
|
|
||||||
Elf32_Word sh_addralign;
|
|
||||||
Elf32_Word sh_entsize;
|
|
||||||
} Elf32_Shdr;
|
|
||||||
|
|
||||||
// sh_type values
|
// sh_type values
|
||||||
#define SHT_NULL 0
|
#define SHT_NULL 0
|
||||||
#define SHT_PROGBITS 1
|
#define SHT_PROGBITS 1
|
||||||
@@ -102,6 +78,17 @@ typedef struct {
|
|||||||
#define SHT_LOUSER 0x80000000
|
#define SHT_LOUSER 0x80000000
|
||||||
#define SHT_HIUSER 0xffffffff
|
#define SHT_HIUSER 0xffffffff
|
||||||
|
|
||||||
|
// 32 bit definitions
|
||||||
|
#undef _ELFX_BITS
|
||||||
|
#define _ELFX_BITS 32
|
||||||
|
#include <ElfX.h>
|
||||||
|
|
||||||
|
// 64 bit definitions
|
||||||
|
#undef _ELFX_BITS
|
||||||
|
#define _ELFX_BITS 64
|
||||||
|
#include <ElfX.h>
|
||||||
|
|
||||||
|
#undef _ELFX_BITS
|
||||||
|
|
||||||
|
|
||||||
#endif // _ELF_H
|
#endif // _ELF_H
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2002-2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// No header guard: The file is included twice by <Elf.h> and must not be
|
||||||
|
// included elsewhere. The _ELFX_BITS macro must be define before inclusion.
|
||||||
|
|
||||||
|
|
||||||
|
#undef ElfX
|
||||||
|
|
||||||
|
#if _ELFX_BITS == 32
|
||||||
|
# define ElfX(x) Elf32_##x
|
||||||
|
#elif _ELFX_BITS == 64
|
||||||
|
# define ElfX(x) Elf64_##x
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// object file header
|
||||||
|
typedef struct {
|
||||||
|
unsigned char e_ident[EI_NIDENT];
|
||||||
|
ElfX(Half) e_type;
|
||||||
|
ElfX(Half) e_machine;
|
||||||
|
ElfX(Word) e_version;
|
||||||
|
ElfX(Addr) e_entry;
|
||||||
|
ElfX(Off) e_phoff;
|
||||||
|
ElfX(Off) e_shoff;
|
||||||
|
ElfX(Word) e_flags;
|
||||||
|
ElfX(Half) e_ehsize;
|
||||||
|
ElfX(Half) e_phentsize;
|
||||||
|
ElfX(Half) e_phnum;
|
||||||
|
ElfX(Half) e_shentsize;
|
||||||
|
ElfX(Half) e_shnum;
|
||||||
|
ElfX(Half) e_shstrndx;
|
||||||
|
} ElfX(Ehdr);
|
||||||
|
|
||||||
|
// program header
|
||||||
|
typedef struct {
|
||||||
|
ElfX(Word) p_type;
|
||||||
|
#if _ELFX_BITS == 64
|
||||||
|
ElfX(Word) p_flags;
|
||||||
|
#endif
|
||||||
|
ElfX(Off) p_offset;
|
||||||
|
ElfX(Addr) p_vaddr;
|
||||||
|
ElfX(Addr) p_paddr;
|
||||||
|
ElfX(Xword) p_filesz;
|
||||||
|
ElfX(Xword) p_memsz;
|
||||||
|
#if _ELFX_BITS == 32
|
||||||
|
ElfX(Word) p_flags;
|
||||||
|
#endif
|
||||||
|
ElfX(Xword) p_align;
|
||||||
|
} ElfX(Phdr);
|
||||||
|
|
||||||
|
// section header
|
||||||
|
typedef struct {
|
||||||
|
ElfX(Word) sh_name;
|
||||||
|
ElfX(Word) sh_type;
|
||||||
|
ElfX(Xword) sh_flags;
|
||||||
|
ElfX(Addr) sh_addr;
|
||||||
|
ElfX(Off) sh_offset;
|
||||||
|
ElfX(Xword) sh_size;
|
||||||
|
ElfX(Word) sh_link;
|
||||||
|
ElfX(Word) sh_info;
|
||||||
|
ElfX(Xword) sh_addralign;
|
||||||
|
ElfX(Xword) sh_entsize;
|
||||||
|
} ElfX(Shdr);
|
||||||
|
|
||||||
|
#undef ElfX
|
||||||
@@ -1,31 +1,37 @@
|
|||||||
//----------------------------------------------------------------------
|
/*
|
||||||
// This software is part of the OpenBeOS distribution and is covered
|
* Copyright 2002-2009, Ingo Weinhold, [email protected].
|
||||||
// by the OpenBeOS license.
|
* Distributed under the terms of the MIT License.
|
||||||
//---------------------------------------------------------------------
|
*/
|
||||||
|
#ifndef _RESOURCE_FILE_H
|
||||||
|
#define _RESOURCE_FILE_H
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\file ResourceFile.h
|
\file ResourceFile.h
|
||||||
ResourceFile interface declaration.
|
ResourceFile interface declaration.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _RESOURCE_FILE_H
|
|
||||||
#define _RESOURCE_FILE_H
|
|
||||||
|
|
||||||
#include <ByteOrder.h>
|
#include <ByteOrder.h>
|
||||||
|
|
||||||
#include "OffsetFile.h"
|
#include "OffsetFile.h"
|
||||||
|
|
||||||
|
|
||||||
struct resource_info;
|
struct resource_info;
|
||||||
struct PEFContainerHeader;
|
struct PEFContainerHeader;
|
||||||
|
|
||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
namespace Storage {
|
namespace Storage {
|
||||||
|
|
||||||
|
|
||||||
class Exception;
|
class Exception;
|
||||||
struct MemArea;
|
struct MemArea;
|
||||||
class ResourceItem;
|
class ResourceItem;
|
||||||
struct resource_parse_info;
|
struct resource_parse_info;
|
||||||
class ResourcesContainer;
|
class ResourcesContainer;
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class ResourceFile
|
\class ResourceFile
|
||||||
\brief Represents a file capable of containing resources.
|
\brief Represents a file capable of containing resources.
|
||||||
@@ -58,21 +64,33 @@ public:
|
|||||||
status_t InitCheck() const;
|
status_t InitCheck() const;
|
||||||
|
|
||||||
status_t InitContainer(ResourcesContainer& container);
|
status_t InitContainer(ResourcesContainer& container);
|
||||||
status_t ReadResource(ResourceItem &resource, bool force = false);
|
status_t ReadResource(ResourceItem& resource,
|
||||||
status_t ReadResources(ResourcesContainer &container, bool force = false);
|
bool force = false);
|
||||||
|
status_t ReadResources(ResourcesContainer& container,
|
||||||
|
bool force = false);
|
||||||
status_t WriteResources(ResourcesContainer& container);
|
status_t WriteResources(ResourcesContainer& container);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _InitFile(BFile& file, bool clobber);
|
void _InitFile(BFile& file, bool clobber);
|
||||||
|
|
||||||
void _InitELFFile(BFile& file);
|
void _InitELFFile(BFile& file);
|
||||||
void _InitPEFFile(BFile &file, const PEFContainerHeader &pefHeader);
|
|
||||||
|
template<typename ElfHeader, typename ElfProgramHeader,
|
||||||
|
typename ElfSectionHeader>
|
||||||
|
void _InitELFXFile(BFile& file, uint64 fileSize);
|
||||||
|
|
||||||
|
void _InitPEFFile(BFile& file,
|
||||||
|
const PEFContainerHeader& pefHeader);
|
||||||
void _ReadHeader(resource_parse_info& parseInfo);
|
void _ReadHeader(resource_parse_info& parseInfo);
|
||||||
void _ReadIndex(resource_parse_info& parseInfo);
|
void _ReadIndex(resource_parse_info& parseInfo);
|
||||||
bool _ReadIndexEntry(resource_parse_info &parseInfo, int32 index,
|
bool _ReadIndexEntry(resource_parse_info& parseInfo,
|
||||||
uint32 tableOffset, bool peekAhead);
|
int32 index, uint32 tableOffset,
|
||||||
|
bool peekAhead);
|
||||||
void _ReadInfoTable(resource_parse_info& parseInfo);
|
void _ReadInfoTable(resource_parse_info& parseInfo);
|
||||||
bool _ReadInfoTableEnd(const void *data, int32 dataSize);
|
bool _ReadInfoTableEnd(const void* data,
|
||||||
const void *_ReadResourceInfo(resource_parse_info &parseInfo,
|
int32 dataSize);
|
||||||
|
const void* _ReadResourceInfo(
|
||||||
|
resource_parse_info& parseInfo,
|
||||||
const MemArea& area,
|
const MemArea& area,
|
||||||
const resource_info* info, type_code type,
|
const resource_info* info, type_code type,
|
||||||
bool* readIndices);
|
bool* readIndices);
|
||||||
@@ -80,10 +98,12 @@ private:
|
|||||||
status_t _WriteResources(ResourcesContainer& container);
|
status_t _WriteResources(ResourcesContainer& container);
|
||||||
status_t _MakeEmptyResourceFile();
|
status_t _MakeEmptyResourceFile();
|
||||||
|
|
||||||
inline int16 _GetInt16(int16 value);
|
inline int16 _GetInt(int16 value) const;
|
||||||
inline uint16 _GetUInt16(uint16 value);
|
inline uint16 _GetInt(uint16 value) const;
|
||||||
inline int32 _GetInt32(int32 value);
|
inline int32 _GetInt(int32 value) const;
|
||||||
inline uint32 _GetUInt32(uint32 value);
|
inline uint32 _GetInt(uint32 value) const;
|
||||||
|
inline int64 _GetInt(int64 value) const;
|
||||||
|
inline uint64 _GetInt(uint64 value) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OffsetFile fFile;
|
OffsetFile fFile;
|
||||||
@@ -92,41 +112,51 @@ private:
|
|||||||
bool fEmptyResources;
|
bool fEmptyResources;
|
||||||
};
|
};
|
||||||
|
|
||||||
// _GetInt16
|
|
||||||
inline
|
inline int16
|
||||||
int16
|
ResourceFile::_GetInt(int16 value) const
|
||||||
ResourceFile::_GetInt16(int16 value)
|
|
||||||
{
|
{
|
||||||
return (fHostEndianess ? value : B_SWAP_INT16(value));
|
return fHostEndianess ? value : (int16)B_SWAP_INT16((uint16)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// _GetUInt16
|
|
||||||
inline
|
inline uint16
|
||||||
uint16
|
ResourceFile::_GetInt(uint16 value) const
|
||||||
ResourceFile::_GetUInt16(uint16 value)
|
|
||||||
{
|
{
|
||||||
return (fHostEndianess ? value : B_SWAP_INT16(value));
|
return fHostEndianess ? value : B_SWAP_INT16(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// _GetInt32
|
|
||||||
inline
|
inline int32
|
||||||
int32
|
ResourceFile::_GetInt(int32 value) const
|
||||||
ResourceFile::_GetInt32(int32 value)
|
|
||||||
{
|
{
|
||||||
return (fHostEndianess ? value : B_SWAP_INT32(value));
|
return fHostEndianess ? value : (int32)B_SWAP_INT32((uint32)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// _GetUInt32
|
|
||||||
inline
|
inline uint32
|
||||||
uint32
|
ResourceFile::_GetInt(uint32 value) const
|
||||||
ResourceFile::_GetUInt32(uint32 value)
|
|
||||||
{
|
{
|
||||||
return (fHostEndianess ? value : B_SWAP_INT32(value));
|
return fHostEndianess ? value : B_SWAP_INT32(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int64
|
||||||
|
ResourceFile::_GetInt(int64 value) const
|
||||||
|
{
|
||||||
|
return fHostEndianess ? value : (int64)B_SWAP_INT64((uint64)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline uint64
|
||||||
|
ResourceFile::_GetInt(uint64 value) const
|
||||||
|
{
|
||||||
|
return fHostEndianess ? value : B_SWAP_INT64(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}; // namespace Storage
|
}; // namespace Storage
|
||||||
}; // namespace BPrivate
|
}; // namespace BPrivate
|
||||||
|
|
||||||
|
|
||||||
#endif // _RESOURCE_FILE_H
|
#endif // _RESOURCE_FILE_H
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,42 +1,46 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2006, Haiku Inc.
|
* Copyright 2002-2009, Ingo Weinhold, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Tyler Dauwalder
|
|
||||||
* Ingo Weinhold, [email protected]
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\file ResourceFile.cpp
|
\file ResourceFile.cpp
|
||||||
ResourceFile implementation.
|
ResourceFile implementation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <ResourceFile.h>
|
#include <ResourceFile.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <new>
|
#include <new>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "Elf.h"
|
#include <AutoDeleter.h>
|
||||||
#include "Exception.h"
|
|
||||||
#include "Pef.h"
|
#include <Elf.h>
|
||||||
#include "ResourceItem.h"
|
#include <Exception.h>
|
||||||
#include "ResourcesContainer.h"
|
#include <Pef.h>
|
||||||
#include "ResourcesDefs.h"
|
#include <ResourceItem.h>
|
||||||
|
#include <ResourcesContainer.h>
|
||||||
|
#include <ResourcesDefs.h>
|
||||||
|
//#include <Warnings.h>
|
||||||
|
|
||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
namespace Storage {
|
namespace Storage {
|
||||||
|
|
||||||
|
|
||||||
// ELF defs
|
// ELF defs
|
||||||
static const uint32 kMaxELFHeaderSize = sizeof(Elf32_Ehdr) + 32;
|
static const uint32 kMaxELFHeaderSize
|
||||||
|
= std::max(sizeof(Elf32_Ehdr), sizeof(Elf64_Ehdr)) + 32;
|
||||||
static const char kELFFileMagic[4] = { 0x7f, 'E', 'L', 'F' };
|
static const char kELFFileMagic[4] = { 0x7f, 'E', 'L', 'F' };
|
||||||
|
|
||||||
// sanity bounds
|
// sanity bounds
|
||||||
static const uint32 kMaxResourceCount = 10000;
|
static const uint32 kMaxResourceCount = 10000;
|
||||||
static const uint32 kELFMaxResourceAlignment = 1024 * 1024 * 10; // 10 MB
|
static const uint32 kELFMaxResourceAlignment = 1024 * 1024 * 10; // 10 MB
|
||||||
|
|
||||||
|
|
||||||
// recognized file types (indices into kFileTypeNames)
|
// recognized file types (indices into kFileTypeNames)
|
||||||
enum {
|
enum {
|
||||||
FILE_TYPE_UNKNOWN = 0,
|
FILE_TYPE_UNKNOWN = 0,
|
||||||
@@ -47,6 +51,7 @@ enum {
|
|||||||
FILE_TYPE_EMPTY = 5,
|
FILE_TYPE_EMPTY = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const char* kFileTypeNames[] = {
|
const char* kFileTypeNames[] = {
|
||||||
"unknown",
|
"unknown",
|
||||||
"x86 resource file",
|
"x86 resource file",
|
||||||
@@ -56,17 +61,17 @@ const char *kFileTypeNames[] = {
|
|||||||
"empty file",
|
"empty file",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// debugging
|
// debugging
|
||||||
//#define DBG(x) x
|
//#define DBG(x) x
|
||||||
#define DBG(x)
|
#define DBG(x)
|
||||||
#define OUT printf
|
#define OUT printf
|
||||||
|
|
||||||
|
|
||||||
// helper functions/classes
|
// #pragma mark - helper functions/classes
|
||||||
|
|
||||||
// read_exactly
|
|
||||||
static
|
static void
|
||||||
void
|
|
||||||
read_exactly(BPositionIO& file, off_t position, void* buffer, size_t size,
|
read_exactly(BPositionIO& file, off_t position, void* buffer, size_t size,
|
||||||
const char* errorMessage = NULL)
|
const char* errorMessage = NULL)
|
||||||
{
|
{
|
||||||
@@ -82,9 +87,8 @@ read_exactly(BPositionIO &file, off_t position, void *buffer, size_t size,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// write_exactly
|
|
||||||
static
|
static void
|
||||||
void
|
|
||||||
write_exactly(BPositionIO& file, off_t position, const void* buffer,
|
write_exactly(BPositionIO& file, off_t position, const void* buffer,
|
||||||
size_t size, const char* errorMessage = NULL)
|
size_t size, const char* errorMessage = NULL)
|
||||||
{
|
{
|
||||||
@@ -100,18 +104,16 @@ write_exactly(BPositionIO &file, off_t position, const void *buffer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// align_value
|
|
||||||
template<typename TV, typename TA>
|
template<typename TV, typename TA>
|
||||||
static inline
|
static inline TV
|
||||||
TV
|
|
||||||
align_value(const TV& value, const TA& alignment)
|
align_value(const TV& value, const TA& alignment)
|
||||||
{
|
{
|
||||||
return ((value + alignment - 1) / alignment) * alignment;
|
return ((value + alignment - 1) / alignment) * alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate_checksum
|
|
||||||
static
|
static uint32
|
||||||
uint32
|
|
||||||
calculate_checksum(const void* data, uint32 size)
|
calculate_checksum(const void* data, uint32 size)
|
||||||
{
|
{
|
||||||
uint32 checkSum = 0;
|
uint32 checkSum = 0;
|
||||||
@@ -120,7 +122,7 @@ calculate_checksum(const void *data, uint32 size)
|
|||||||
const uint8* current = csData;
|
const uint8* current = csData;
|
||||||
for (; current < dataEnd; current += 4) {
|
for (; current < dataEnd; current += 4) {
|
||||||
uint32 word = 0;
|
uint32 word = 0;
|
||||||
int32 bytes = min_c(4L, (int32)(dataEnd - current));
|
int32 bytes = std::min((int32)4, (int32)(dataEnd - current));
|
||||||
for (int32 i = 0; i < bytes; i++)
|
for (int32 i = 0; i < bytes; i++)
|
||||||
word = (word << 8) + current[i];
|
word = (word << 8) + current[i];
|
||||||
checkSum += word;
|
checkSum += word;
|
||||||
@@ -128,25 +130,22 @@ calculate_checksum(const void *data, uint32 size)
|
|||||||
return checkSum;
|
return checkSum;
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip_bytes
|
|
||||||
static inline
|
static inline const void*
|
||||||
const void*
|
|
||||||
skip_bytes(const void* buffer, int32 offset)
|
skip_bytes(const void* buffer, int32 offset)
|
||||||
{
|
{
|
||||||
return (const char*)buffer + offset;
|
return (const char*)buffer + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip_bytes
|
|
||||||
static inline
|
static inline void*
|
||||||
void*
|
|
||||||
skip_bytes(void* buffer, int32 offset)
|
skip_bytes(void* buffer, int32 offset)
|
||||||
{
|
{
|
||||||
return (char*)buffer + offset;
|
return (char*)buffer + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill_pattern
|
|
||||||
static
|
static void
|
||||||
void
|
|
||||||
fill_pattern(uint32 byteOffset, void* _buffer, uint32 count)
|
fill_pattern(uint32 byteOffset, void* _buffer, uint32 count)
|
||||||
{
|
{
|
||||||
uint32* buffer = (uint32*)_buffer;
|
uint32* buffer = (uint32*)_buffer;
|
||||||
@@ -154,26 +153,23 @@ fill_pattern(uint32 byteOffset, void *_buffer, uint32 count)
|
|||||||
buffer[i] = kUnusedResourceDataPattern[(byteOffset / 4 + i) % 3];
|
buffer[i] = kUnusedResourceDataPattern[(byteOffset / 4 + i) % 3];
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill_pattern
|
|
||||||
static
|
static void
|
||||||
void
|
|
||||||
fill_pattern(const void* dataBegin, void* buffer, uint32 count)
|
fill_pattern(const void* dataBegin, void* buffer, uint32 count)
|
||||||
{
|
{
|
||||||
fill_pattern((char*)buffer - (const char*)dataBegin, buffer, count);
|
fill_pattern((char*)buffer - (const char*)dataBegin, buffer, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill_pattern
|
|
||||||
static
|
static void
|
||||||
void
|
|
||||||
fill_pattern(const void* dataBegin, void* buffer, const void* bufferEnd)
|
fill_pattern(const void* dataBegin, void* buffer, const void* bufferEnd)
|
||||||
{
|
{
|
||||||
fill_pattern(dataBegin, buffer,
|
fill_pattern(dataBegin, buffer,
|
||||||
((const char*)bufferEnd - (char*)buffer) / 4);
|
((const char*)bufferEnd - (char*)buffer) / 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check_pattern
|
|
||||||
static
|
static bool
|
||||||
bool
|
|
||||||
check_pattern(uint32 byteOffset, void* _buffer, uint32 count,
|
check_pattern(uint32 byteOffset, void* _buffer, uint32 count,
|
||||||
bool hostEndianess)
|
bool hostEndianess)
|
||||||
{
|
{
|
||||||
@@ -189,7 +185,10 @@ check_pattern(uint32 byteOffset, void *_buffer, uint32 count,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// MemArea
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
struct MemArea {
|
struct MemArea {
|
||||||
MemArea(const void* data, uint32 size) : data(data), size(size) {}
|
MemArea(const void* data, uint32 size) : data(data), size(size) {}
|
||||||
|
|
||||||
@@ -204,26 +203,7 @@ struct MemArea {
|
|||||||
uint32 size;
|
uint32 size;
|
||||||
};
|
};
|
||||||
|
|
||||||
// AutoDeleter
|
|
||||||
template<typename C>
|
|
||||||
struct AutoDeleter {
|
|
||||||
AutoDeleter(C *object, bool array = false) : object(object), array(array)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~AutoDeleter()
|
|
||||||
{
|
|
||||||
if (array)
|
|
||||||
delete[] object;
|
|
||||||
else
|
|
||||||
delete object;
|
|
||||||
}
|
|
||||||
|
|
||||||
C* object;
|
|
||||||
bool array;
|
|
||||||
};
|
|
||||||
|
|
||||||
// resource_parse_info
|
|
||||||
struct resource_parse_info {
|
struct resource_parse_info {
|
||||||
off_t file_size;
|
off_t file_size;
|
||||||
int32 resource_count;
|
int32 resource_count;
|
||||||
@@ -234,22 +214,25 @@ struct resource_parse_info {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// constructor
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
ResourceFile::ResourceFile()
|
ResourceFile::ResourceFile()
|
||||||
: fFile(),
|
:
|
||||||
|
fFile(),
|
||||||
fFileType(FILE_TYPE_UNKNOWN),
|
fFileType(FILE_TYPE_UNKNOWN),
|
||||||
fHostEndianess(true),
|
fHostEndianess(true),
|
||||||
fEmptyResources(true)
|
fEmptyResources(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// destructor
|
|
||||||
ResourceFile::~ResourceFile()
|
ResourceFile::~ResourceFile()
|
||||||
{
|
{
|
||||||
Unset();
|
Unset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetTo
|
|
||||||
status_t
|
status_t
|
||||||
ResourceFile::SetTo(BFile* file, bool clobber)
|
ResourceFile::SetTo(BFile* file, bool clobber)
|
||||||
{
|
{
|
||||||
@@ -269,25 +252,24 @@ ResourceFile::SetTo(BFile *file, bool clobber)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unset
|
|
||||||
void
|
void
|
||||||
ResourceFile::Unset()
|
ResourceFile::Unset()
|
||||||
{
|
{
|
||||||
// file
|
|
||||||
fFile.Unset();
|
fFile.Unset();
|
||||||
fFileType = FILE_TYPE_UNKNOWN;
|
fFileType = FILE_TYPE_UNKNOWN;
|
||||||
fHostEndianess = true;
|
fHostEndianess = true;
|
||||||
fEmptyResources = true;
|
fEmptyResources = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitCheck
|
|
||||||
status_t
|
status_t
|
||||||
ResourceFile::InitCheck() const
|
ResourceFile::InitCheck() const
|
||||||
{
|
{
|
||||||
return fFile.InitCheck();
|
return fFile.InitCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitContainer
|
|
||||||
status_t
|
status_t
|
||||||
ResourceFile::InitContainer(ResourcesContainer& container)
|
ResourceFile::InitContainer(ResourcesContainer& container)
|
||||||
{
|
{
|
||||||
@@ -321,7 +303,7 @@ ResourceFile::InitContainer(ResourcesContainer &container)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadResource
|
|
||||||
status_t
|
status_t
|
||||||
ResourceFile::ReadResource(ResourceItem& resource, bool force)
|
ResourceFile::ReadResource(ResourceItem& resource, bool force)
|
||||||
{
|
{
|
||||||
@@ -350,7 +332,7 @@ ResourceFile::ReadResource(ResourceItem &resource, bool force)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadResources
|
|
||||||
status_t
|
status_t
|
||||||
ResourceFile::ReadResources(ResourcesContainer& container, bool force)
|
ResourceFile::ReadResources(ResourcesContainer& container, bool force)
|
||||||
{
|
{
|
||||||
@@ -365,7 +347,7 @@ ResourceFile::ReadResources(ResourcesContainer &container, bool force)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteResources
|
|
||||||
status_t
|
status_t
|
||||||
ResourceFile::WriteResources(ResourcesContainer& container)
|
ResourceFile::WriteResources(ResourcesContainer& container)
|
||||||
{
|
{
|
||||||
@@ -382,7 +364,6 @@ ResourceFile::WriteResources(ResourcesContainer &container)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// _InitFile
|
|
||||||
void
|
void
|
||||||
ResourceFile::_InitFile(BFile& file, bool clobber)
|
ResourceFile::_InitFile(BFile& file, bool clobber)
|
||||||
{
|
{
|
||||||
@@ -461,22 +442,29 @@ ResourceFile::_InitFile(BFile &file, bool clobber)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// _InitELFFile
|
|
||||||
void
|
void
|
||||||
ResourceFile::_InitELFFile(BFile& file)
|
ResourceFile::_InitELFFile(BFile& file)
|
||||||
{
|
{
|
||||||
status_t error = B_OK;
|
status_t error = B_OK;
|
||||||
|
|
||||||
// get the file size
|
// get the file size
|
||||||
off_t fileSize = 0;
|
off_t fileSize = 0;
|
||||||
error = file.GetSize(&fileSize);
|
error = file.GetSize(&fileSize);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
throw Exception(error, "Failed to get the file size.");
|
throw Exception(error, "Failed to get the file size.");
|
||||||
// read ELF header
|
|
||||||
Elf32_Ehdr fileHeader;
|
// read the ELF headers e_ident field
|
||||||
read_exactly(file, 0, &fileHeader, sizeof(Elf32_Ehdr),
|
unsigned char identification[EI_NIDENT];
|
||||||
"Failed to read ELF header.");
|
read_exactly(file, 0, identification, EI_NIDENT,
|
||||||
|
"Failed to read ELF identification.");
|
||||||
|
|
||||||
|
// check version
|
||||||
|
if (identification[EI_VERSION] != EV_CURRENT)
|
||||||
|
throw Exception(B_UNSUPPORTED, "Unsupported ELF version.");
|
||||||
|
|
||||||
// check data encoding (endianess)
|
// check data encoding (endianess)
|
||||||
switch (fileHeader.e_ident[EI_DATA]) {
|
switch (identification[EI_DATA]) {
|
||||||
case ELFDATA2LSB:
|
case ELFDATA2LSB:
|
||||||
fHostEndianess = B_HOST_IS_LENDIAN;
|
fHostEndianess = B_HOST_IS_LENDIAN;
|
||||||
break;
|
break;
|
||||||
@@ -485,57 +473,84 @@ ResourceFile::_InitELFFile(BFile &file)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
case ELFDATANONE:
|
case ELFDATANONE:
|
||||||
throw Exception(B_IO_ERROR, "Unsupported ELF data encoding.");
|
throw Exception(B_UNSUPPORTED, "Unsupported ELF data encoding.");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check class (32/64 bit) and call the respective method handling it
|
||||||
|
switch (identification[EI_CLASS]) {
|
||||||
|
case ELFCLASS32:
|
||||||
|
_InitELFXFile<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>(file, fileSize);
|
||||||
|
break;
|
||||||
|
case ELFCLASS64:
|
||||||
|
_InitELFXFile<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>(file, fileSize);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw Exception(B_UNSUPPORTED, "Unsupported ELF class.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename ElfHeader, typename ElfProgramHeader,
|
||||||
|
typename ElfSectionHeader>
|
||||||
|
void
|
||||||
|
ResourceFile::_InitELFXFile(BFile& file, uint64 fileSize)
|
||||||
|
{
|
||||||
|
// read ELF header
|
||||||
|
ElfHeader fileHeader;
|
||||||
|
read_exactly(file, 0, &fileHeader, sizeof(ElfHeader),
|
||||||
|
"Failed to read ELF header.");
|
||||||
|
|
||||||
// get the header values
|
// get the header values
|
||||||
uint32 headerSize = _GetUInt16(fileHeader.e_ehsize);
|
uint32 headerSize = _GetInt(fileHeader.e_ehsize);
|
||||||
uint32 programHeaderTableOffset = _GetUInt32(fileHeader.e_phoff);
|
uint64 programHeaderTableOffset = _GetInt(fileHeader.e_phoff);
|
||||||
uint32 programHeaderSize = _GetUInt16(fileHeader.e_phentsize);
|
uint32 programHeaderSize = _GetInt(fileHeader.e_phentsize);
|
||||||
uint32 programHeaderCount = _GetUInt16(fileHeader.e_phnum);
|
uint32 programHeaderCount = _GetInt(fileHeader.e_phnum);
|
||||||
uint32 sectionHeaderTableOffset = _GetUInt32(fileHeader.e_shoff);
|
uint64 sectionHeaderTableOffset = _GetInt(fileHeader.e_shoff);
|
||||||
uint32 sectionHeaderSize = _GetUInt16(fileHeader.e_shentsize);
|
uint32 sectionHeaderSize = _GetInt(fileHeader.e_shentsize);
|
||||||
uint32 sectionHeaderCount = _GetUInt16(fileHeader.e_shnum);
|
uint32 sectionHeaderCount = _GetInt(fileHeader.e_shnum);
|
||||||
bool hasProgramHeaderTable = (programHeaderTableOffset != 0);
|
bool hasProgramHeaderTable = (programHeaderTableOffset != 0);
|
||||||
bool hasSectionHeaderTable = (sectionHeaderTableOffset != 0);
|
bool hasSectionHeaderTable = (sectionHeaderTableOffset != 0);
|
||||||
|
|
||||||
// check the sanity of the header values
|
// check the sanity of the header values
|
||||||
// ELF header size
|
// ELF header size
|
||||||
if (headerSize < sizeof(Elf32_Ehdr) || headerSize > kMaxELFHeaderSize) {
|
if (headerSize < sizeof(ElfHeader) || headerSize > kMaxELFHeaderSize) {
|
||||||
throw Exception(B_IO_ERROR,
|
throw Exception(B_IO_ERROR,
|
||||||
"Invalid ELF header: invalid ELF header size: %lu.",
|
"Invalid ELF header: invalid ELF header size: %lu.", headerSize);
|
||||||
headerSize);
|
|
||||||
}
|
}
|
||||||
uint32 resourceOffset = headerSize;
|
uint64 resourceOffset = headerSize;
|
||||||
uint32 resourceAlignment = 0;
|
uint64 resourceAlignment = 0;
|
||||||
|
|
||||||
// program header table offset and entry count/size
|
// program header table offset and entry count/size
|
||||||
uint32 programHeaderTableSize = 0;
|
uint64 programHeaderTableSize = 0;
|
||||||
if (hasProgramHeaderTable) {
|
if (hasProgramHeaderTable) {
|
||||||
if (programHeaderTableOffset < headerSize
|
if (programHeaderTableOffset < headerSize
|
||||||
|| programHeaderTableOffset > fileSize) {
|
|| programHeaderTableOffset > fileSize) {
|
||||||
throw Exception(B_IO_ERROR, "Invalid ELF header: invalid program "
|
throw Exception(B_IO_ERROR, "Invalid ELF header: invalid program "
|
||||||
"header table offset: %lu.",
|
"header table offset: %lu.", programHeaderTableOffset);
|
||||||
programHeaderTableOffset);
|
|
||||||
}
|
}
|
||||||
programHeaderTableSize = programHeaderSize * programHeaderCount;
|
programHeaderTableSize = (uint64)programHeaderSize * programHeaderCount;
|
||||||
if (programHeaderSize < sizeof(Elf32_Phdr)
|
if (programHeaderSize < sizeof(ElfProgramHeader)
|
||||||
|| programHeaderTableOffset + programHeaderTableSize > fileSize) {
|
|| programHeaderTableOffset + programHeaderTableSize > fileSize) {
|
||||||
throw Exception(B_IO_ERROR, "Invalid ELF header: program header "
|
throw Exception(B_IO_ERROR, "Invalid ELF header: program header "
|
||||||
"table exceeds file: %lu.",
|
"table exceeds file: %lu.",
|
||||||
programHeaderTableOffset + programHeaderTableSize);
|
programHeaderTableOffset + programHeaderTableSize);
|
||||||
}
|
}
|
||||||
resourceOffset = max_c(resourceOffset, programHeaderTableOffset
|
resourceOffset = std::max(resourceOffset,
|
||||||
+ programHeaderTableSize);
|
programHeaderTableOffset + programHeaderTableSize);
|
||||||
|
|
||||||
// iterate through the program headers
|
// iterate through the program headers
|
||||||
for (int32 i = 0; i < (int32)programHeaderCount; i++) {
|
for (uint32 i = 0; i < programHeaderCount; i++) {
|
||||||
uint32 shOffset = programHeaderTableOffset + i * programHeaderSize;
|
uint64 shOffset = programHeaderTableOffset + i * programHeaderSize;
|
||||||
Elf32_Phdr programHeader;
|
ElfProgramHeader programHeader;
|
||||||
read_exactly(file, shOffset, &programHeader, sizeof(Elf32_Shdr),
|
read_exactly(file, shOffset, &programHeader,
|
||||||
"Failed to read ELF program header.");
|
sizeof(ElfProgramHeader), "Failed to read ELF program header.");
|
||||||
|
|
||||||
// get the header values
|
// get the header values
|
||||||
uint32 type = _GetUInt32(programHeader.p_type);
|
uint32 type = _GetInt(programHeader.p_type);
|
||||||
uint32 offset = _GetUInt32(programHeader.p_offset);
|
uint64 offset = _GetInt(programHeader.p_offset);
|
||||||
uint32 size = _GetUInt32(programHeader.p_filesz);
|
uint64 size = _GetInt(programHeader.p_filesz);
|
||||||
uint32 alignment = _GetUInt32(programHeader.p_align);
|
uint64 alignment = _GetInt(programHeader.p_align);
|
||||||
|
|
||||||
// check the values
|
// check the values
|
||||||
// PT_NULL marks the header unused,
|
// PT_NULL marks the header unused,
|
||||||
if (type != PT_NULL) {
|
if (type != PT_NULL) {
|
||||||
@@ -543,44 +558,47 @@ ResourceFile::_InitELFFile(BFile &file)
|
|||||||
throw Exception(B_IO_ERROR, "Invalid ELF program header: "
|
throw Exception(B_IO_ERROR, "Invalid ELF program header: "
|
||||||
"invalid program offset: %lu.", offset);
|
"invalid program offset: %lu.", offset);
|
||||||
}
|
}
|
||||||
uint32 segmentEnd = offset + size;
|
uint64 segmentEnd = offset + size;
|
||||||
if (segmentEnd > fileSize) {
|
if (segmentEnd > fileSize) {
|
||||||
throw Exception(B_IO_ERROR, "Invalid ELF section header: "
|
throw Exception(B_IO_ERROR, "Invalid ELF section header: "
|
||||||
"segment exceeds file: %lu.", segmentEnd);
|
"segment exceeds file: %lu.", segmentEnd);
|
||||||
}
|
}
|
||||||
resourceOffset = max_c(resourceOffset, segmentEnd);
|
resourceOffset = std::max(resourceOffset, segmentEnd);
|
||||||
resourceAlignment = max_c(resourceAlignment, alignment);
|
resourceAlignment = std::max(resourceAlignment, alignment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// section header table offset and entry count/size
|
// section header table offset and entry count/size
|
||||||
uint32 sectionHeaderTableSize = 0;
|
uint64 sectionHeaderTableSize = 0;
|
||||||
if (hasSectionHeaderTable) {
|
if (hasSectionHeaderTable) {
|
||||||
if (sectionHeaderTableOffset < headerSize
|
if (sectionHeaderTableOffset < headerSize
|
||||||
|| sectionHeaderTableOffset > fileSize) {
|
|| sectionHeaderTableOffset > fileSize) {
|
||||||
throw Exception(B_IO_ERROR, "Invalid ELF header: invalid section "
|
throw Exception(B_IO_ERROR, "Invalid ELF header: invalid section "
|
||||||
"header table offset: %lu.",
|
"header table offset: %lu.", sectionHeaderTableOffset);
|
||||||
sectionHeaderTableOffset);
|
|
||||||
}
|
}
|
||||||
sectionHeaderTableSize = sectionHeaderSize * sectionHeaderCount;
|
sectionHeaderTableSize = (uint64)sectionHeaderSize * sectionHeaderCount;
|
||||||
if (sectionHeaderSize < sizeof(Elf32_Shdr)
|
if (sectionHeaderSize < sizeof(ElfSectionHeader)
|
||||||
|| sectionHeaderTableOffset + sectionHeaderTableSize > fileSize) {
|
|| sectionHeaderTableOffset + sectionHeaderTableSize > fileSize) {
|
||||||
throw Exception(B_IO_ERROR, "Invalid ELF header: section header "
|
throw Exception(B_IO_ERROR, "Invalid ELF header: section header "
|
||||||
"table exceeds file: %lu.",
|
"table exceeds file: %lu.",
|
||||||
sectionHeaderTableOffset + sectionHeaderTableSize);
|
sectionHeaderTableOffset + sectionHeaderTableSize);
|
||||||
}
|
}
|
||||||
resourceOffset = max_c(resourceOffset, sectionHeaderTableOffset
|
resourceOffset = std::max(resourceOffset,
|
||||||
+ sectionHeaderTableSize);
|
sectionHeaderTableOffset + sectionHeaderTableSize);
|
||||||
|
|
||||||
// iterate through the section headers
|
// iterate through the section headers
|
||||||
for (int32 i = 0; i < (int32)sectionHeaderCount; i++) {
|
for (uint32 i = 0; i < sectionHeaderCount; i++) {
|
||||||
uint32 shOffset = sectionHeaderTableOffset + i * sectionHeaderSize;
|
uint32 shOffset = sectionHeaderTableOffset + i * sectionHeaderSize;
|
||||||
Elf32_Shdr sectionHeader;
|
ElfSectionHeader sectionHeader;
|
||||||
read_exactly(file, shOffset, §ionHeader, sizeof(Elf32_Shdr),
|
read_exactly(file, shOffset, §ionHeader,
|
||||||
"Failed to read ELF section header.");
|
sizeof(ElfSectionHeader), "Failed to read ELF section header.");
|
||||||
|
|
||||||
// get the header values
|
// get the header values
|
||||||
uint32 type = _GetUInt32(sectionHeader.sh_type);
|
uint32 type = _GetInt(sectionHeader.sh_type);
|
||||||
uint32 offset = _GetUInt32(sectionHeader.sh_offset);
|
uint64 offset = _GetInt(sectionHeader.sh_offset);
|
||||||
uint32 size = _GetUInt32(sectionHeader.sh_size);
|
uint64 size = _GetInt(sectionHeader.sh_size);
|
||||||
|
|
||||||
// check the values
|
// check the values
|
||||||
// SHT_NULL marks the header unused,
|
// SHT_NULL marks the header unused,
|
||||||
// SHT_NOBITS sections take no space in the file
|
// SHT_NOBITS sections take no space in the file
|
||||||
@@ -589,15 +607,16 @@ ResourceFile::_InitELFFile(BFile &file)
|
|||||||
throw Exception(B_IO_ERROR, "Invalid ELF section header: "
|
throw Exception(B_IO_ERROR, "Invalid ELF section header: "
|
||||||
"invalid section offset: %lu.", offset);
|
"invalid section offset: %lu.", offset);
|
||||||
}
|
}
|
||||||
uint32 sectionEnd = offset + size;
|
uint64 sectionEnd = offset + size;
|
||||||
if (sectionEnd > fileSize) {
|
if (sectionEnd > fileSize) {
|
||||||
throw Exception(B_IO_ERROR, "Invalid ELF section header: "
|
throw Exception(B_IO_ERROR, "Invalid ELF section header: "
|
||||||
"section exceeds file: %lu.", sectionEnd);
|
"section exceeds file: %lu.", sectionEnd);
|
||||||
}
|
}
|
||||||
resourceOffset = max_c(resourceOffset, sectionEnd);
|
resourceOffset = std::max(resourceOffset, sectionEnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// align the offset
|
// align the offset
|
||||||
if (resourceAlignment < kELFMinResourceAlignment)
|
if (resourceAlignment < kELFMinResourceAlignment)
|
||||||
resourceAlignment = kELFMinResourceAlignment;
|
resourceAlignment = kELFMinResourceAlignment;
|
||||||
@@ -611,11 +630,12 @@ ResourceFile::_InitELFFile(BFile &file)
|
|||||||
fEmptyResources = true;
|
fEmptyResources = true;
|
||||||
} else
|
} else
|
||||||
fEmptyResources = false;
|
fEmptyResources = false;
|
||||||
|
|
||||||
// fine, init the offset file
|
// fine, init the offset file
|
||||||
fFile.SetTo(&file, resourceOffset);
|
fFile.SetTo(&file, resourceOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// _InitPEFFile
|
|
||||||
void
|
void
|
||||||
ResourceFile::_InitPEFFile(BFile& file, const PEFContainerHeader& pefHeader)
|
ResourceFile::_InitPEFFile(BFile& file, const PEFContainerHeader& pefHeader)
|
||||||
{
|
{
|
||||||
@@ -630,7 +650,7 @@ ResourceFile::_InitPEFFile(BFile &file, const PEFContainerHeader &pefHeader)
|
|||||||
throw Exception(B_IO_ERROR, "PEF file architecture is not PPC.");
|
throw Exception(B_IO_ERROR, "PEF file architecture is not PPC.");
|
||||||
fHostEndianess = B_HOST_IS_BENDIAN;
|
fHostEndianess = B_HOST_IS_BENDIAN;
|
||||||
// get the section count
|
// get the section count
|
||||||
uint16 sectionCount = _GetUInt16(pefHeader.sectionCount);
|
uint16 sectionCount = _GetInt(pefHeader.sectionCount);
|
||||||
// iterate through the PEF sections headers
|
// iterate through the PEF sections headers
|
||||||
uint32 sectionHeaderTableOffset = kPEFContainerHeaderSize;
|
uint32 sectionHeaderTableOffset = kPEFContainerHeaderSize;
|
||||||
uint32 sectionHeaderTableEnd
|
uint32 sectionHeaderTableEnd
|
||||||
@@ -642,8 +662,8 @@ ResourceFile::_InitPEFFile(BFile &file, const PEFContainerHeader &pefHeader)
|
|||||||
read_exactly(file, shOffset, §ionHeader, kPEFSectionHeaderSize,
|
read_exactly(file, shOffset, §ionHeader, kPEFSectionHeaderSize,
|
||||||
"Failed to read PEF section header.");
|
"Failed to read PEF section header.");
|
||||||
// get the header values
|
// get the header values
|
||||||
uint32 offset = _GetUInt32(sectionHeader.containerOffset);
|
uint32 offset = _GetInt(sectionHeader.containerOffset);
|
||||||
uint32 size = _GetUInt32(sectionHeader.packedSize);
|
uint32 size = _GetInt(sectionHeader.packedSize);
|
||||||
// check the values
|
// check the values
|
||||||
if (offset < sectionHeaderTableEnd || offset > fileSize) {
|
if (offset < sectionHeaderTableEnd || offset > fileSize) {
|
||||||
throw Exception(B_IO_ERROR, "Invalid PEF section header: invalid "
|
throw Exception(B_IO_ERROR, "Invalid PEF section header: invalid "
|
||||||
@@ -654,7 +674,7 @@ ResourceFile::_InitPEFFile(BFile &file, const PEFContainerHeader &pefHeader)
|
|||||||
throw Exception(B_IO_ERROR, "Invalid PEF section header: section "
|
throw Exception(B_IO_ERROR, "Invalid PEF section header: section "
|
||||||
"exceeds file: %lu.", sectionEnd);
|
"exceeds file: %lu.", sectionEnd);
|
||||||
}
|
}
|
||||||
resourceOffset = max_c(resourceOffset, sectionEnd);
|
resourceOffset = std::max(resourceOffset, sectionEnd);
|
||||||
}
|
}
|
||||||
if (resourceOffset >= fileSize) {
|
if (resourceOffset >= fileSize) {
|
||||||
// throw Exception("The PEF object file does not contain resources.");
|
// throw Exception("The PEF object file does not contain resources.");
|
||||||
@@ -665,7 +685,7 @@ ResourceFile::_InitPEFFile(BFile &file, const PEFContainerHeader &pefHeader)
|
|||||||
fFile.SetTo(&file, resourceOffset);
|
fFile.SetTo(&file, resourceOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// _ReadHeader
|
|
||||||
void
|
void
|
||||||
ResourceFile::_ReadHeader(resource_parse_info& parseInfo)
|
ResourceFile::_ReadHeader(resource_parse_info& parseInfo)
|
||||||
{
|
{
|
||||||
@@ -675,7 +695,7 @@ ResourceFile::_ReadHeader(resource_parse_info &parseInfo)
|
|||||||
"Failed to read the header.");
|
"Failed to read the header.");
|
||||||
// check the header
|
// check the header
|
||||||
// magic
|
// magic
|
||||||
uint32 magic = _GetUInt32(header.rh_resources_magic);
|
uint32 magic = _GetInt(header.rh_resources_magic);
|
||||||
if (magic == kResourcesHeaderMagic) {
|
if (magic == kResourcesHeaderMagic) {
|
||||||
// everything is fine
|
// everything is fine
|
||||||
} else if (B_SWAP_INT32(magic) == kResourcesHeaderMagic) {
|
} else if (B_SWAP_INT32(magic) == kResourcesHeaderMagic) {
|
||||||
@@ -690,11 +710,11 @@ ResourceFile::_ReadHeader(resource_parse_info &parseInfo)
|
|||||||
} else
|
} else
|
||||||
throw Exception(B_IO_ERROR, "Invalid resources header magic.");
|
throw Exception(B_IO_ERROR, "Invalid resources header magic.");
|
||||||
// resource count
|
// resource count
|
||||||
uint32 resourceCount = _GetUInt32(header.rh_resource_count);
|
uint32 resourceCount = _GetInt(header.rh_resource_count);
|
||||||
if (resourceCount > kMaxResourceCount)
|
if (resourceCount > kMaxResourceCount)
|
||||||
throw Exception(B_IO_ERROR, "Bad number of resources.");
|
throw Exception(B_IO_ERROR, "Bad number of resources.");
|
||||||
// index section offset
|
// index section offset
|
||||||
uint32 indexSectionOffset = _GetUInt32(header.rh_index_section_offset);
|
uint32 indexSectionOffset = _GetInt(header.rh_index_section_offset);
|
||||||
if (indexSectionOffset != kResourceIndexSectionOffset) {
|
if (indexSectionOffset != kResourceIndexSectionOffset) {
|
||||||
throw Exception(B_IO_ERROR, "Unexpected resource index section "
|
throw Exception(B_IO_ERROR, "Unexpected resource index section "
|
||||||
"offset. Is: %lu, should be: %lu.", indexSectionOffset,
|
"offset. Is: %lu, should be: %lu.", indexSectionOffset,
|
||||||
@@ -705,7 +725,7 @@ ResourceFile::_ReadHeader(resource_parse_info &parseInfo)
|
|||||||
+ kResourceIndexEntrySize * resourceCount;
|
+ kResourceIndexEntrySize * resourceCount;
|
||||||
indexSectionSize = align_value(indexSectionSize,
|
indexSectionSize = align_value(indexSectionSize,
|
||||||
kResourceIndexSectionAlignment);
|
kResourceIndexSectionAlignment);
|
||||||
uint32 adminSectionSize = _GetUInt32(header.rh_admin_section_size);
|
uint32 adminSectionSize = _GetInt(header.rh_admin_section_size);
|
||||||
if (adminSectionSize != indexSectionOffset + indexSectionSize) {
|
if (adminSectionSize != indexSectionOffset + indexSectionSize) {
|
||||||
throw Exception(B_IO_ERROR, "Unexpected resource admin section size. "
|
throw Exception(B_IO_ERROR, "Unexpected resource admin section size. "
|
||||||
"Is: %lu, should be: %lu.", adminSectionSize,
|
"Is: %lu, should be: %lu.", adminSectionSize,
|
||||||
@@ -715,7 +735,7 @@ ResourceFile::_ReadHeader(resource_parse_info &parseInfo)
|
|||||||
parseInfo.resource_count = resourceCount;
|
parseInfo.resource_count = resourceCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
// _ReadIndex
|
|
||||||
void
|
void
|
||||||
ResourceFile::_ReadIndex(resource_parse_info& parseInfo)
|
ResourceFile::_ReadIndex(resource_parse_info& parseInfo)
|
||||||
{
|
{
|
||||||
@@ -728,7 +748,7 @@ ResourceFile::_ReadIndex(resource_parse_info &parseInfo)
|
|||||||
"Failed to read the resource index section header.");
|
"Failed to read the resource index section header.");
|
||||||
// check the header
|
// check the header
|
||||||
// index section offset
|
// index section offset
|
||||||
uint32 indexSectionOffset = _GetUInt32(header.rish_index_section_offset);
|
uint32 indexSectionOffset = _GetInt(header.rish_index_section_offset);
|
||||||
if (indexSectionOffset != kResourceIndexSectionOffset) {
|
if (indexSectionOffset != kResourceIndexSectionOffset) {
|
||||||
throw Exception(B_IO_ERROR, "Unexpected resource index section "
|
throw Exception(B_IO_ERROR, "Unexpected resource index section "
|
||||||
"offset. Is: %lu, should be: %lu.", indexSectionOffset,
|
"offset. Is: %lu, should be: %lu.", indexSectionOffset,
|
||||||
@@ -739,7 +759,7 @@ ResourceFile::_ReadIndex(resource_parse_info &parseInfo)
|
|||||||
+ kResourceIndexEntrySize * resourceCount;
|
+ kResourceIndexEntrySize * resourceCount;
|
||||||
expectedIndexSectionSize = align_value(expectedIndexSectionSize,
|
expectedIndexSectionSize = align_value(expectedIndexSectionSize,
|
||||||
kResourceIndexSectionAlignment);
|
kResourceIndexSectionAlignment);
|
||||||
uint32 indexSectionSize = _GetUInt32(header.rish_index_section_size);
|
uint32 indexSectionSize = _GetInt(header.rish_index_section_size);
|
||||||
if (indexSectionSize != expectedIndexSectionSize) {
|
if (indexSectionSize != expectedIndexSectionSize) {
|
||||||
throw Exception(B_IO_ERROR, "Unexpected resource index section size. "
|
throw Exception(B_IO_ERROR, "Unexpected resource index section size. "
|
||||||
"Is: %lu, should be: %lu.", indexSectionSize,
|
"Is: %lu, should be: %lu.", indexSectionSize,
|
||||||
@@ -747,22 +767,22 @@ ResourceFile::_ReadIndex(resource_parse_info &parseInfo)
|
|||||||
}
|
}
|
||||||
// unknown section offset
|
// unknown section offset
|
||||||
uint32 unknownSectionOffset
|
uint32 unknownSectionOffset
|
||||||
= _GetUInt32(header.rish_unknown_section_offset);
|
= _GetInt(header.rish_unknown_section_offset);
|
||||||
if (unknownSectionOffset != indexSectionOffset + indexSectionSize) {
|
if (unknownSectionOffset != indexSectionOffset + indexSectionSize) {
|
||||||
throw Exception(B_IO_ERROR, "Unexpected resource index section size. "
|
throw Exception(B_IO_ERROR, "Unexpected resource index section size. "
|
||||||
"Is: %lu, should be: %lu.", unknownSectionOffset,
|
"Is: %lu, should be: %lu.", unknownSectionOffset,
|
||||||
indexSectionOffset + indexSectionSize);
|
indexSectionOffset + indexSectionSize);
|
||||||
}
|
}
|
||||||
// unknown section size
|
// unknown section size
|
||||||
uint32 unknownSectionSize = _GetUInt32(header.rish_unknown_section_size);
|
uint32 unknownSectionSize = _GetInt(header.rish_unknown_section_size);
|
||||||
if (unknownSectionSize != kUnknownResourceSectionSize) {
|
if (unknownSectionSize != kUnknownResourceSectionSize) {
|
||||||
throw Exception(B_IO_ERROR, "Unexpected resource index section "
|
throw Exception(B_IO_ERROR, "Unexpected resource index section "
|
||||||
"offset. Is: %lu, should be: %lu.",
|
"offset. Is: %lu, should be: %lu.",
|
||||||
unknownSectionOffset, kUnknownResourceSectionSize);
|
unknownSectionOffset, kUnknownResourceSectionSize);
|
||||||
}
|
}
|
||||||
// info table offset and size
|
// info table offset and size
|
||||||
uint32 infoTableOffset = _GetUInt32(header.rish_info_table_offset);
|
uint32 infoTableOffset = _GetInt(header.rish_info_table_offset);
|
||||||
uint32 infoTableSize = _GetUInt32(header.rish_info_table_size);
|
uint32 infoTableSize = _GetInt(header.rish_info_table_size);
|
||||||
if (infoTableOffset + infoTableSize > fileSize)
|
if (infoTableOffset + infoTableSize > fileSize)
|
||||||
throw Exception(B_IO_ERROR, "Invalid info table location.");
|
throw Exception(B_IO_ERROR, "Invalid info table location.");
|
||||||
parseInfo.info_table_offset = infoTableOffset;
|
parseInfo.info_table_offset = infoTableOffset;
|
||||||
@@ -793,7 +813,7 @@ ResourceFile::_ReadIndex(resource_parse_info &parseInfo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// _ReadIndexEntry
|
|
||||||
bool
|
bool
|
||||||
ResourceFile::_ReadIndexEntry(resource_parse_info& parseInfo, int32 index,
|
ResourceFile::_ReadIndexEntry(resource_parse_info& parseInfo, int32 index,
|
||||||
uint32 tableOffset, bool peekAhead)
|
uint32 tableOffset, bool peekAhead)
|
||||||
@@ -816,8 +836,8 @@ ResourceFile::_ReadIndexEntry(resource_parse_info &parseInfo, int32 index,
|
|||||||
}
|
}
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
uint32 offset = _GetUInt32(entry.rie_offset);
|
uint32 offset = _GetInt(entry.rie_offset);
|
||||||
uint32 size = _GetUInt32(entry.rie_size);
|
uint32 size = _GetInt(entry.rie_size);
|
||||||
// check the location
|
// check the location
|
||||||
if (result && offset + size > fileSize) {
|
if (result && offset + size > fileSize) {
|
||||||
if (peekAhead) {
|
if (peekAhead) {
|
||||||
@@ -825,8 +845,8 @@ ResourceFile::_ReadIndexEntry(resource_parse_info &parseInfo, int32 index,
|
|||||||
// "table.");
|
// "table.");
|
||||||
} else {
|
} else {
|
||||||
throw Exception(B_IO_ERROR, "Invalid resource index entry: index: "
|
throw Exception(B_IO_ERROR, "Invalid resource index entry: index: "
|
||||||
"%ld, offset: %lu (%lx), size: %lu (%lx).",
|
"%ld, offset: %lu (%lx), size: %lu (%lx).", index + 1, offset,
|
||||||
index + 1, offset, offset, size, size);
|
offset, size, size);
|
||||||
}
|
}
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
@@ -844,7 +864,7 @@ ResourceFile::_ReadIndexEntry(resource_parse_info &parseInfo, int32 index,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// _ReadInfoTable
|
|
||||||
void
|
void
|
||||||
ResourceFile::_ReadInfoTable(resource_parse_info& parseInfo)
|
ResourceFile::_ReadInfoTable(resource_parse_info& parseInfo)
|
||||||
{
|
{
|
||||||
@@ -863,7 +883,7 @@ ResourceFile::_ReadInfoTable(resource_parse_info &parseInfo)
|
|||||||
// + 1 => always > 0
|
// + 1 => always > 0
|
||||||
if (!readIndices)
|
if (!readIndices)
|
||||||
throw Exception(B_NO_MEMORY);
|
throw Exception(B_NO_MEMORY);
|
||||||
AutoDeleter<bool> readIndicesDeleter(readIndices, true);
|
ArrayDeleter<bool> readIndicesDeleter(readIndices);
|
||||||
for (int32 i = 0; i < resourceCount; i++)
|
for (int32 i = 0; i < resourceCount; i++)
|
||||||
readIndices[i] = false;
|
readIndices[i] = false;
|
||||||
MemArea area(tableData, dataSize);
|
MemArea area(tableData, dataSize);
|
||||||
@@ -883,7 +903,7 @@ ResourceFile::_ReadInfoTable(resource_parse_info &parseInfo)
|
|||||||
}
|
}
|
||||||
const resource_info_block* infoBlock
|
const resource_info_block* infoBlock
|
||||||
= (const resource_info_block*)data;
|
= (const resource_info_block*)data;
|
||||||
type_code type = _GetUInt32(infoBlock->rib_type);
|
type_code type = _GetInt(infoBlock->rib_type);
|
||||||
// read the infos of this block
|
// read the infos of this block
|
||||||
const resource_info* info = infoBlock->rib_info;
|
const resource_info* info = infoBlock->rib_info;
|
||||||
while (info) {
|
while (info) {
|
||||||
@@ -895,8 +915,8 @@ ResourceFile::_ReadInfoTable(resource_parse_info &parseInfo)
|
|||||||
}
|
}
|
||||||
const resource_info_separator* separator
|
const resource_info_separator* separator
|
||||||
= (const resource_info_separator*)data;
|
= (const resource_info_separator*)data;
|
||||||
if (_GetUInt32(separator->ris_value1) == 0xffffffff
|
if (_GetInt(separator->ris_value1) == 0xffffffff
|
||||||
&& _GetUInt32(separator->ris_value2) == 0xffffffff) {
|
&& _GetInt(separator->ris_value2) == 0xffffffff) {
|
||||||
// info block ends
|
// info block ends
|
||||||
info = NULL;
|
info = NULL;
|
||||||
data = skip_bytes(data, kResourceInfoSeparatorSize);
|
data = skip_bytes(data, kResourceInfoSeparatorSize);
|
||||||
@@ -916,8 +936,8 @@ ResourceFile::_ReadInfoTable(resource_parse_info &parseInfo)
|
|||||||
}
|
}
|
||||||
const resource_info_separator* tableTerminator
|
const resource_info_separator* tableTerminator
|
||||||
= (const resource_info_separator*)data;
|
= (const resource_info_separator*)data;
|
||||||
if (_GetUInt32(tableTerminator->ris_value1) != 0xffffffff
|
if (_GetInt(tableTerminator->ris_value1) != 0xffffffff
|
||||||
|| _GetUInt32(tableTerminator->ris_value2) != 0xffffffff) {
|
|| _GetInt(tableTerminator->ris_value2) != 0xffffffff) {
|
||||||
throw Exception(B_IO_ERROR, "The resource info table ought to be "
|
throw Exception(B_IO_ERROR, "The resource info table ought to be "
|
||||||
"empty, but is not properly terminated.");
|
"empty, but is not properly terminated.");
|
||||||
}
|
}
|
||||||
@@ -941,7 +961,7 @@ ResourceFile::_ReadInfoTable(resource_parse_info &parseInfo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// _ReadInfoTableEnd
|
|
||||||
bool
|
bool
|
||||||
ResourceFile::_ReadInfoTableEnd(const void* data, int32 dataSize)
|
ResourceFile::_ReadInfoTableEnd(const void* data, int32 dataSize)
|
||||||
{
|
{
|
||||||
@@ -954,17 +974,17 @@ ResourceFile::_ReadInfoTableEnd(const void *data, int32 dataSize)
|
|||||||
const resource_info_table_end* tableEnd
|
const resource_info_table_end* tableEnd
|
||||||
= (const resource_info_table_end*)
|
= (const resource_info_table_end*)
|
||||||
skip_bytes(data, dataSize - kResourceInfoTableEndSize);
|
skip_bytes(data, dataSize - kResourceInfoTableEndSize);
|
||||||
if (_GetInt32(tableEnd->rite_terminator) != 0)
|
if (_GetInt(tableEnd->rite_terminator) != 0)
|
||||||
hasTableEnd = false;
|
hasTableEnd = false;
|
||||||
if (hasTableEnd) {
|
if (hasTableEnd) {
|
||||||
dataSize -= kResourceInfoTableEndSize;
|
dataSize -= kResourceInfoTableEndSize;
|
||||||
// checksum
|
// checksum
|
||||||
uint32 checkSum = calculate_checksum(data, dataSize);
|
uint32 checkSum = calculate_checksum(data, dataSize);
|
||||||
uint32 fileCheckSum = _GetUInt32(tableEnd->rite_check_sum);
|
uint32 fileCheckSum = _GetInt(tableEnd->rite_check_sum);
|
||||||
if (checkSum != fileCheckSum) {
|
if (checkSum != fileCheckSum) {
|
||||||
throw Exception(B_IO_ERROR, "Invalid resource info table check"
|
throw Exception(B_IO_ERROR, "Invalid resource info table check"
|
||||||
" sum: In file: %lx, calculated: %lx.",
|
" sum: In file: %lx, calculated: %lx.", fileCheckSum,
|
||||||
fileCheckSum, checkSum);
|
checkSum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -973,17 +993,16 @@ ResourceFile::_ReadInfoTableEnd(const void *data, int32 dataSize)
|
|||||||
return hasTableEnd;
|
return hasTableEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
// _ReadResourceInfo
|
|
||||||
const void*
|
const void*
|
||||||
ResourceFile::_ReadResourceInfo(resource_parse_info& parseInfo,
|
ResourceFile::_ReadResourceInfo(resource_parse_info& parseInfo,
|
||||||
const MemArea &area, const resource_info *info,
|
const MemArea& area, const resource_info* info, type_code type,
|
||||||
type_code type, bool *readIndices)
|
bool* readIndices)
|
||||||
{
|
{
|
||||||
int32& resourceCount = parseInfo.resource_count;
|
int32& resourceCount = parseInfo.resource_count;
|
||||||
//
|
int32 id = _GetInt(info->ri_id);
|
||||||
int32 id = _GetInt32(info->ri_id);
|
int32 index = _GetInt(info->ri_index);
|
||||||
int32 index = _GetInt32(info->ri_index);
|
uint16 nameSize = _GetInt(info->ri_name_size);
|
||||||
uint16 nameSize = _GetUInt16(info->ri_name_size);
|
|
||||||
const char* name = info->ri_name;
|
const char* name = info->ri_name;
|
||||||
// check the values
|
// check the values
|
||||||
bool ignore = false;
|
bool ignore = false;
|
||||||
@@ -1024,7 +1043,7 @@ ResourceFile::_ReadResourceInfo(resource_parse_info &parseInfo,
|
|||||||
return skip_bytes(name, nameSize);
|
return skip_bytes(name, nameSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// _WriteResources
|
|
||||||
status_t
|
status_t
|
||||||
ResourceFile::_WriteResources(ResourcesContainer& container)
|
ResourceFile::_WriteResources(ResourcesContainer& container)
|
||||||
{
|
{
|
||||||
@@ -1043,12 +1062,12 @@ ResourceFile::_WriteResources(ResourcesContainer &container)
|
|||||||
indexSectionSize = align_value(indexSectionSize,
|
indexSectionSize = align_value(indexSectionSize,
|
||||||
kResourceIndexSectionAlignment);
|
kResourceIndexSectionAlignment);
|
||||||
size += indexSectionSize;
|
size += indexSectionSize;
|
||||||
bufferSize = max_c((uint32)bufferSize, indexSectionSize);
|
bufferSize = std::max((uint32)bufferSize, indexSectionSize);
|
||||||
// unknown section
|
// unknown section
|
||||||
uint32 unknownSectionOffset = size;
|
uint32 unknownSectionOffset = size;
|
||||||
uint32 unknownSectionSize = kUnknownResourceSectionSize;
|
uint32 unknownSectionSize = kUnknownResourceSectionSize;
|
||||||
size += unknownSectionSize;
|
size += unknownSectionSize;
|
||||||
bufferSize = max_c((uint32)bufferSize, unknownSectionSize);
|
bufferSize = std::max((uint32)bufferSize, unknownSectionSize);
|
||||||
// data
|
// data
|
||||||
uint32 dataOffset = size;
|
uint32 dataOffset = size;
|
||||||
uint32 dataSize = 0;
|
uint32 dataSize = 0;
|
||||||
@@ -1057,7 +1076,7 @@ ResourceFile::_WriteResources(ResourcesContainer &container)
|
|||||||
if (!item->IsLoaded())
|
if (!item->IsLoaded())
|
||||||
throw Exception(B_IO_ERROR, "Resource is not loaded.");
|
throw Exception(B_IO_ERROR, "Resource is not loaded.");
|
||||||
dataSize += item->DataSize();
|
dataSize += item->DataSize();
|
||||||
bufferSize = max_c(bufferSize, item->DataSize());
|
bufferSize = std::max(bufferSize, item->DataSize());
|
||||||
}
|
}
|
||||||
size += dataSize;
|
size += dataSize;
|
||||||
// info table
|
// info table
|
||||||
@@ -1081,7 +1100,7 @@ ResourceFile::_WriteResources(ResourcesContainer &container)
|
|||||||
infoTableSize += kResourceInfoSeparatorSize
|
infoTableSize += kResourceInfoSeparatorSize
|
||||||
+ kResourceInfoTableEndSize;
|
+ kResourceInfoTableEndSize;
|
||||||
size += infoTableSize;
|
size += infoTableSize;
|
||||||
bufferSize = max_c((uint32)bufferSize, infoTableSize);
|
bufferSize = std::max((uint32)bufferSize, infoTableSize);
|
||||||
|
|
||||||
// write...
|
// write...
|
||||||
// set the file size
|
// set the file size
|
||||||
@@ -1216,7 +1235,7 @@ ResourceFile::_WriteResources(ResourcesContainer &container)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// _MakeEmptyResourceFile
|
|
||||||
status_t
|
status_t
|
||||||
ResourceFile::_MakeEmptyResourceFile()
|
ResourceFile::_MakeEmptyResourceFile()
|
||||||
{
|
{
|
||||||
@@ -1249,7 +1268,3 @@ ResourceFile::_MakeEmptyResourceFile()
|
|||||||
|
|
||||||
}; // namespace Storage
|
}; // namespace Storage
|
||||||
}; // namespace BPrivate
|
}; // namespace BPrivate
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user