It is accomplished ...

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
ejakowatz
2002-07-09 12:24:59 +00:00
commit 52a3801208
2025 changed files with 472889 additions and 0 deletions
+444
View File
@@ -0,0 +1,444 @@
# Annotations
# ===========
#
# This file contains a list of miscellaneous annotations.
# An entry has the following tags:
# * OS: the concerned "operating system" (BeOS R5, OBOS POSIX)
# * Module: the concerned class or file
# * Location: a more precise location, e.g. a function
# * Description: a description of the item
OS: BeOS R5
Module: BEntry
Location: BEntry(const BDirectory*, const char*),
SetTo(const BDirectory*, const char*)
Description: Crash when passing a NULL BDirectory.
OS: BeOS R5
Module: BEntry
Location: MoveTo()
Description: Crashs when passing a NULL BDirectory.
OS: BeOS R5
Module: BPath
Location: BPath(const BDirectory*, const char*, bool),
SetTo(const BDirectory*, const char*, bool)
Description: Crash when passing a NULL BDirectory.
OS: BeOS R5
Module: BPath
Location: GetParent()
Description: Crashs when called on an uninitialized object or when passing
a NULL BPath.
OS: BeOS R5
Module: BPath
Location: operator==(), operator!=()
Description: Uninitialized paths are not equal. An initialized path equals
a (const char*)NULL, an uninitialized path does not.
OS: BeOS R5
Module: BPath
Location: Flatten()
Description: Crashs when passing a NULL buffer and doesn't check the buffer
size.
OS: BeOS R5
Module: BStatable
Location: destructor
Description: Is not virtual.
OS: BeOS R5
Module: BStatable
Location: GetAccessTime(), SetAccessTime()
Description: Access time unused.
OS: BeOS R5
Module: BStatable
Location: GetPermissions()
Description: Doesn't filter the mode flags, thus not only the permissions are
returned.
OS: BeOS R5
Module: BStatable
Location: Get*()
Description: Crash when passing a NULL pointer.
OS: OBOS POSIX
Module: BStatable
Location: SetPermissions/ModificationTime/CreationTime()
Description: Don't work due to set_stat(FileDescriptor, StatMember)
limitations.
OS: OBOS POSIX
Module: kernel_interface
Location: set_stat(FileDescriptor, StatMember)
Description: WSTAT_MODE, WSTAT_*TIME can't be implemented due to missing
fchmod()/FD time setters.
OS: BeOS R5
Module: libroot
Location: fchown()
Description: fchown(file, 0xFFFFFFFF, gid) sets the UID to 0xFFFFFFFF, which
is a bug.
OS: BeOS R5
Module: libroot
Location: readdir(), fs_read_attr_dir()
Description: The d_reclen field of a dirent structure does not contain the
length of the whole structure (unlike stated in
BeBook::BEntryList), but only the length of the d_name field.
If the terminating '\0' is counted or not seems to depend on the
file system.
OS: OBOS POSIX
Module: kernel_interface
Location: read_link(FileDescriptor, char*, size_t)
Description: Can't be implemented due to the lack of an FD readlink() version.
OS: BeOS R5
Module: BSymLink
Location: MakeLinkedPath(const char*, BPath*)
Description: The dirPath seems to be converted into a BDirectory, which
causes links to be resolved, i.e. a "/tmp" dirPath expands to
"/boot/var/tmp". That does also mean, that the dirPath must
exists!
OS: BeOS R5
Module: BSymLink
Location: MakeLinkedPath()
Description: Crashs when passing a NULL const char* or BDirectory.
OS: BeOS R5
Module: BNode
Location: GetNextAttrName()
Description: Crashs when passing a NULL buffer.
OS: BeOS R5
Module: BNode
Location: Read/WriteAttrString()
Description: Crash when passing a NULL BString.
OS: BeOS R5
Module: BNode
Location: Lock()
Description: Given two BNode objects initialized to the same node, it is
possible to Lock() one of them, although the BeBook says it isn't.
OS: BeOS R5
Module: BDirectory
Location: BDirectory(const node_ref*), SetTo(const node_ref*)
Description: Crash when passing a NULL node_ref.
OS: BeOS R5
Module: BDirectory
Location: GetEntry()
Description: Crashs when passing a NULL BEntry.
OS: BeOS R5
Module: BDirectory
Location: FindEntry()
Description: Crashs when passing a NULL BEntry.
OS: BeOS R5
Module: BDirectory
Location: Contains()
Description: If the BDirectory is uninitialized, the const char* version
returns true for existing entries, whereas the const BEntry*
version returns false.
OS: BeOS R5
Module: BDirectory
Location: Contains(const BEntry*, bool)
Description: Crashs when passing a NULL BEntry.
OS: BeOS R5
Module: BDirectory
Location: Contains(const BEntry*, bool)
Description: Bug: Tests with a directory, contained file/dir/symlink and
the respective node kind (B_FILE_NODE/B_DIRECTORY_NODE/
B_SYMLINK_NODE) result false.
OS: BeOS R5
Module: BDirectory
Location: GetNextDirents()
Description: Crashs when passing a NULL buffer.
OS: OBOS
Module: BQuery
Location: Push*()
Description: Return status_t instead of void. Fail, if Fetch() has already
been called.
OS: BeOS R5
Module: BQuery
Location: PushOp()
Description: Crashs when pushing B_CONTAINS/B_BEGINS/ENDS_WITH on an empty
stack.
OS: BeOS R5
Module: BQuery
Location: PushUInt64()
Description: Doesn't work. Predicates constructed using it are invalid.
OS: BeOS R5
Module: BQuery
Location: Get/SetPredicate()
Description: Crash when passing a NULL BString/char*.
OS: BeOS R5
Module: BQuery
Location: SetVolume()
Description: Crashs when passing a NULL BVolume.
OS: BeOS R5
Module: BQuery
Location: GetNextEntry/Ref()
Description: Crash when passing a NULL BEntry/entry_ref.
OS: BeOS R5
Module: BMimeType
Location: {Get,Set}LongDescription()
Description: Crashes when passed a NULL description
OS: BeOS R5
Module: BMimeType
Location: GetLongDescription()
Description: The contents of the description string are modified even if
the function fails.
OS: BeOS R5
Module: BMimeType
Location: SetShortDescription()
Description: When passed a NULL description, doesn't crash, but does
appear to make the result of following calls to SetShortDescription
unreliable (sometimes they work, sometimes they don't).
OS: BeOS R5
Module: BMimeType
Location:
Description: The maximal MIME string length, BMimeType accepts is
B_MIME_TYPE_LENGTH *not* including terminating null. Note, that
app_info reserves only B_MIME_TYPE_LENGTH chars for the
signature field.
OS: BeOS R5
Module: BMimeType
Location: SetAppHint()
Description: The entry_ref passed to SetAppHint() must be valid but is not
required to refer to a file that actually exists; furthermore,
if it does exist, the MIME type of the file is not required to
match the BMimeType object's type.
OS: BeOS R5
Module: BMimeType
Location: SetIcon()
Description: The BBitmap passed to BMimeType::SetIcon() must be in the B_CMAP8
color space, or the application will crash. We should remember
to be smarter about this.
OS: BeOS R5
Module: BMimeType
Location: GetIcon()
Description: The BBitmap passed to BMimeType::GetIcon() must be in the B_CMAP8
color space. If not, the call returns B_OK but doesn't actually
modify the bitmap. We should remember to be smarter about this.
OS: BeOS R5
Module: BMimeType
Location: IsValid(const char*), GetSupertype(), Contains()
Description: Crash when passing NULL.
OS: BeOS R5
Module: BMimeType
Location: {Get,Set}IconForType(char*, BBitmap*, icon_size)
Description: Passing NULL as the first parameter is the same as calling
{Get,Set}Icon() with the second two parameters (i.e. {gets,sets}
the icon for the type itself).
OS: BeOS R5
Module: BMimeType
Location: SetFileExtensions()
Description: Passing a NULL message does not clear the File Extensions field
for the MIME type as indicated by the Be Book; instead, it crashes
the application :-)
OS: BeOS R5
Module: BMimeType
Location: GetFileExtensions()
Description: A B_STRING_TYPE field of name "type" is *added* to the result
containing the MIME type of the BMimeType object. Since the
BMessage passed to SetFileExtensions() appears to be simply
flattened into the appropriate attribute, the "type" field is
appended to any such "type" fields that may already exist in
the original BMessage.
OS: BeOS R5
Module: BMimeType
Location: Install()
Description: From the Be Book: "Currently, Install() may return a random value
if the object is already installed."
OS: BeOS R5
Module: BMimeType
Location:
Description: MIME Type strings are converted to lowercase before being used
as filenames in the MIME database.
OS: BeOS R5
Module: BMimeType
Location: Start/StopWatching()
Description: An invalid messenger (BMessenger::Invalid()) is fine as parameter.
OS: BeOS R5
Module: Mime.h/cpp
Location: get_device_icon()
Description: KDL when passing a NULL buffer!
OS: BeOS R5
Module: BMimeType
Location: CheckSnifferRule()
Description: Crashes when passing a NULL rule.
OS: BeOS R5
Module: BMimeType
Location: GetSnifferRule()
Description: Crashes when passing a NULL BString.
OS: BeOS R5
Module: BMimeType
Location: Check/Get/SetSnifferRule()
Description: The sniffer rules description in the BeBook deviates considerably
from the actual implementation:
- + masks
- + top level ORs: (patterns...) | (patterns...) | ...
- - range overriding: [range1] ([range2]pattern)
- either no or complete ranges: (pattern1 | pattern2)
or ([range1]pattern1 | [range2]pattern2), but not
([range1]pattern1 | pattern2)
- CheckSnifferRule() doesn't check some of the values, e.g.
ranges (negative values, or begin > end) or 0 <= priority <= 1.
OS: BeOS R5
Module: BMimeType
Location: GuessMimeType(const entry_ref *, BMimeType *)
Description: When passing an uninitialized entry_ref, B_OK and
"application/octet-stream" are returned.
OS: BeOS R5
Module: BMimeType
Location: SetAttrInfo
Description: Crashes when passed a NULL BMessage.
OS: BeOS R5
Module: BMimeType
Location: GetInstalledTypes(BMessage*)
Description: The set of types returned by this function is determined as follows:
+ All *entries* (files, dirs, or symlinks) in the root MIME database
directory treated as MIME types, except those that begin with an
underscore; only dirs are treated as supertypes (unless the dir's
META:TYPE attribute is different than its filename, in which case
it's not treated as a supertype).
+ For each supertype, all *entries* (files, dirs, or symlinks) in the
corresponding supertype subdirectory are treated as a MIME type, except
those that begin with an underscore.
+ The MIME type for supertypes is taken from the name of the supertype
subdirectory.
+ The MIME type for non-supertypes is take from the entry's META:TYPE
attribute. If the entry has no META:TYPE attribute, the MIME type is
derived by concatentating the name of the supertype directory to the
name of the entry, separated by a "/" character. Either way, the MIME
string returned is not checked to be valid.
OS: BeOS R5
Module: BMimeType
Location: GetInstalledTypes(char *super, BMessage*)
Description: The set of types returned by this function is determined as follows:
+ All *entries* (files, dirs, or symlinks) in the MIME database directory
corresponding to the "super" argument are treated as subtypes, *except*
those whose filenames begin with an underscore. It does not matter if
the supertype directory has a META:TYPE attribute or not.
+ The MIME type is taken from the entry's META:TYPE attribute. If the entry
has no such attribute, the MIME type is derived by concatentating the name
of the supertype directory (the directory's META:TYPE attribute is ignored
if present) to the name of the entry, separated by a "/" character. Either
way, the MIME string returned is not checked to be valid.
OS: BeOS R5
Module: BMimeType
Location: GetInstalledSupertypes(BMessage*)
Description: The set of types returned by this function is determined as follows:
+ All directories in the root MIME database directory are treated as
supertypes (even directories beginning with an underscore).
+ The MIME type is derived from the directory name, which is not
checked to be a valid MIME string.
OS: BeOS R5
Module: BMimeType
Location: GetWildcardApps()
Description: This code:
BMessage msg;
status_t error = BMimeType::GetWildcardApps(&msg);
is the same as:
BMessage msg;
BMimeType mime("application/octet-stream");
status_t error = mime.InitCheck();
if (!error)
error = mime.GetSupportingApps(&msg);
+5
View File
@@ -0,0 +1,5 @@
# Completed
# =========
#
# This file contains completed ToDo items.
+102
View File
@@ -0,0 +1,102 @@
<html>
<head>
<title>Registrar Notes</title>
</head>
<body bgcolor='#ffffff'>
<font face='Tahoma,Arial,SansSerif'>
<!-- Tasks -->
<hr>
<b>Registrar Tasks:</b>
<ul>
<li> MIME Database chores (note that BMimeType appears to read from the database directly for <code>Get*()</code> calls.)<br>
<ul>
<li> Writes to the database -- <code>SetLongDescription(), SetPreferredApp(), create_app_meta_mime(), etc</code>
<li> Monitoring of the database -- <code>{Start,Stop}Watching()</code> <br>
<li> Sniffer duties -- Sniffer code plus <code>{Get,Set,Check}SnifferRule()</code>
</ul>
<br>
<li> Timing chores
<ul>
<li> BMessageRunner functionality
</ul>
<li> System Shutdown chores <br>
<ul>
<li> Shutdown cycle
<li> System shutdown window
</ul>
<li> Roster chores
<ul>
<li> Recent documents, folders, and apps
<li> Info about running applications
<li> etc...
</ul>
</ul>
<!-- Internals -->
<hr>
<b>Registrar Internals:</b><br>
<br>
The registrar is a non-standard <code>BApplication</code>. It has a shadow app in the <code>app_server</code>
like a normal <code>BApplication</code>, but one of its ports is slightly different:
<ul>
<li> Standard ports -- snd, rcv, AppLooperPort
<li> Registrar ports -- snd, rcv, _roster_port_
</ul>
Since <code>BLooper::port_id</code> is private to <code>BLooper</code> (to whom <code>BApplication</code>
is a friend), and since you can't rename a port after it's been created,
it's likely that the only way to rename the <code>AppLooperPort</code> and have the registrar
still be a <code>BApplication</code> is to have <code>BApplication</code> check if it's the
registrar when it's created, and use <code>_roster_port_</code> as the name for what would
otherwise be its <code>AppLooperPort</code>.
<br>
<br>
The rationale behind having a port with a specific name is that the registrar
implements the roster functionality. Thus one can't address it using the app signature
constructor of BMessenger, but rather must send the message directly to
a named port (for example, upon creation, a BApplication object must find and contact
the registrar to notify it of another running application; if the registrar
cannot be found, the application putzes out).
<br>
<br>
The Registrar has three threads:
<ul>
<li> _roster_thread_
<li> timer_thread
<li> main_mime
</ul>
<!-- BMimeType Notes -->
<hr>
<b>BMimeType Notes:</b>
<ul>
<li> The <code>Get*()</code> methods directly access the MIME database.
<li> The <code>Set*()</code> methods send a message to another entity which does the job.
The function that does the sending is called <code>_send_to_roster_()</code>, so I
suppose the roster is the one. Since the registrar has a thread named
<code>_roster_thread_</code>, I assume the roster lives in the registrar.
<li> <code>Start/StopWatching()</code> call <code>BRoster::_Start/_StopWatching()</code>.
<li>Adding/removing a MIME type file in <code>~/config/settings/beos_mime/*/</code> does
not trigger a notification message. So obviously no node monitoring is
done and changes to the database are supposed to be done using the API.
</ul>
<!-- Links -->
<hr>
<b>Links:</b>
<ul>
<li> <a href='http://www.beatjapan.org/mirror/www.be.com/users/iconworld/icon5.html'>Icon World -- The Registrar</a>
<li> <a href='http://www.beosbible.com/exc_filetype.html'>The BeOS Bible -- File Typing and The Registrar</a>
<li> <a href='http://bang.dhs.org/be/bebook/The%20Application%20Kit/Application.html'>BApplication</a>
<li> <a href='http://bang.dhs.org/be/bebook/The%20Storage%20Kit/MimeType.html'>BMimeType</a>
<li> <a href='http://bang.dhs.org/be/bebook/Release%20Notes/StorageKit.html'>BMimeType (sniffer docs)</a>
<li> <a href='http://bang.dhs.org/be/bebook/The%20Application%20Kit/Roster.html'>BRoster</a>
</font>
</body>
</html>
+237
View File
@@ -0,0 +1,237 @@
# ToDo
# ====
#
# This file lists items that have to be worked on.
# An entry for an item has the following tags:
# * Module: the concerned class or file
# * Location: a more precise location, e.g. a function
# * Description: a description of the item
# * Priority: the priority of the item, may be
# deferrable: of no/little relevance for OBOS R1 (to be future compatible:
# the next release)
# low: of relevance for the next release, but not needed in the
# near future
# medium: of relevance for the next release, needed in the near future
# high: of relevance for the next release, needed as soon as possible
# urgent: of relevance for the next release, needed yesterday, i.e.
# some people depend on it being finished and can't continue
# with their tasks otherwise
#
# * Requires: a list of prerequisites needed for the item to be worked on,
# omitted, when empty
# * Responsible: a list of people working on the item, omitted, when empty
#
Module: BEntry
Location: Entry.cpp
Description: Definition of SYMLINK_MAX belongs to some header file. Remove it.
Priority: low
Module: BEntry
Location: SetTo(const BDirectory *, const char *, bool)
Description: Reimplement! Concatenating dir and leaf to an absolute path
prevents the user from accessing entries with longer absolute
path. R5 handles this without problems.
Priority: medium
Requires: - OBOS kernel?
Module: BEntry
Location: SetTo(const BDirectory *, const char *, bool)
Description: Reimplement! Implemented using StorageKit::entry_ref_to_path().
Priority: low
Requires: - OBOS kernel
Module: EntryTest
Location: InitTest1(), InitTest2()
Description: Enable tests with strlen(dir + leaf) > B_PATH_NAME_LENGTH.
Priority: low
Requires: - reimpl. of SetTo(const BDirectory *, const char *, bool)
Module: BPath
Location: Flatten()
Description: Reimplement for performance reasons. Don't call FlattenedSize().
Priority: low
Module: BVolume
Location: operator==()
Description: Implement.
Priority: high
Module: StatableTest
Location: GetXYZTest()
Description: Uncomment GetVolume() test, when BVolume::==() is implemented.
Priority: low
Requires: - implementation of BVolume::operator==()
Module: kernel_interface
Location: set_stat(const char*, StatMember)
Description: Implement WSTAT_CRTIME.
Priority: medium
Module: kernel_interface
Location: remove_attr()
Description: Verify return behavior of fs_remove_attr().
Priority: medium
Module: BeOS R5::libroot
Location:
Description: Propose a project wide common handling of the
B_FILE/PATH_NAME_LENGTH (+ 1?) issue.
Priority: low
Module: BSymLink
Location:
Description: Remove the work-around introduced because of the missing FD
version of readlink().
Priority: medium
Requires: - OBOS kernel
Module: BNode
Location: SetTo(const entry_ref *)
Description: Reimplement! Implemented using StorageKit::entry_ref_to_path().
Priority: low
Requires: - OBOS kernel
Module: BNode
Location: SetTo(const BEntry *)
Description: Check if necessary to reimplement! Implemented using
SetTo(const entry_ref*).
Priority: low
Requires: - OBOS kernel
Module: BNode
Location: SetTo(const BDirectory*, const char*)
Description: Check if necessary to reimplement! Implemented using
SetTo(const BEntry*).
Priority: low
Requires: - OBOS kernel
Module: BNode
Location: Lock(), Unlock()
Description: Implement when kernel support is available.
Priority: medium
Requires: - OBOS kernel
Module: NodeTest
Location: SyncTest()
Description: Add more thorough tests.
Priority: low
Requires: - OBOS kernel
Module: NodeTest
Location: LockTest()
Description: Implement when kernel support is available.
Priority: medium
Requires: - OBOS kernel
Module: BFile
Location: SetTo(const entry_ref *, uint32)
Description: Reimplement! Implemented using StorageKit::entry_ref_to_path().
Priority: low
Requires: - OBOS kernel
Module: BFile
Location: SetTo(const BEntry *, uint32)
Description: Check if necessary to reimplement! Implemented using
SetTo(const entry_ref*, uint32).
Priority: low
Requires: - OBOS kernel
Module: BFile
Location: SetTo(const BDirectory*, const char*, uint32)
Description: Check if necessary to reimplement! Implemented using
SetTo(const BEntry*, uint32).
Priority: low
Requires: - OBOS kernel
Module: BFile
Location: Read/Write[At]()
Description: Verify behavior of B_OPEN_AT_END.
Priority: medium
Module: FileTest
Location: PositionTest()
Description: Uncomment test, when B_OPEN_AT_END behavior is understood.
Priority: medium
Requires: - verification of B_OPEN_AT_END behavior
Module: BDirectory
Location: SetTo(const entry_ref *)
Description: Reimplement! Implemented using StorageKit::entry_ref_to_path().
Priority: low
Requires: - OBOS kernel
Module: BDirectory
Location: SetTo(const BEntry *)
Description: Check if necessary to reimplement! Implemented using
SetTo(const entry_ref*).
Priority: low
Requires: - OBOS kernel
Module: BDirectory
Location: SetTo(const BDirectory*, const char*)
Description: Check if necessary to reimplement! Implemented using
SetTo(const BEntry*).
Priority: low
Requires: - OBOS kernel
Module: BDirectory
Location: GetEntry()
Description: Check if necessary to reimplement! Implemented using
StorageKit::dir_to_self_entry_ref().
Priority: low
Requires: - OBOS kernel
Module: fs_info.h
Location: struct fs_info
Description: Change "char device_name[128]" to "char device_name[B_DEV_NAME_LENGTH]"
whenever appropriate, since B_DEV_NAME_LENGTH is now declared in
StorageDefs.h.
Priority: low
Requires: - filesystem support files in the source hierarchy
Module: BQuery
Location: SetTarget()
Description: Used a bad hack to get port and token of the BMessenger. Fix it.
Priority: low
Requires: - respective function(s) to be provided by the IK team
Module: BMimeType/MimeTypeTest
Location: update_mime_info(), create_app_meta_mime()
Description: Find out, what is the meaning of the force parameter. It does
obviously not mean, that calling the function twice, the second
time with force, has the same effect as calling it only at the
second time. At least the tests indicate, that the second call,
though with force, does not have any effect at all.
Priority: medium
Requires:
+691
View File
@@ -0,0 +1,691 @@
# Doxyfile 1.2.1
# This file describes the settings to be used by doxygen for a project
#
# All text after a hash (#) is considered a comment and will be ignored
# The format is:
# TAG = value [value, ...]
# For lists items can also be appended using:
# TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (" ")
#---------------------------------------------------------------------------
# General configuration options
#---------------------------------------------------------------------------
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
# by quotes) that should identify the project.
PROJECT_NAME = "OpenBeOS Storage Kit"
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER =
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY =
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language.
# The default language is English, other supported languages are:
# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese,
# Spanish, Russian, Croatian, Polish, and Portuguese.
OUTPUT_LANGUAGE = English
# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
# documentation are documented, even if no documentation was available.
# Private class members and static file members will be hidden unless
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
EXTRACT_ALL = NO
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
# will be included in the documentation.
EXTRACT_PRIVATE = YES
# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.
EXTRACT_STATIC = YES
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
# undocumented members of documented classes, files or namespaces.
# If set to NO (the default) these members will be included in the
# various overviews, but no documentation section is generated.
# This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_MEMBERS = NO
# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy.
# If set to NO (the default) these class will be included in the various
# overviews. This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_CLASSES = NO
# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
# include brief member descriptions after the members that are listed in
# the file and class documentation (similar to JavaDoc).
# Set to NO to disable this.
BRIEF_MEMBER_DESC = YES
# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
# the brief description of a member or function before the detailed description.
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed.
REPEAT_BRIEF = YES
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
# Doxygen will generate a detailed section even if there is only a brief
# description.
ALWAYS_DETAILED_SEC = NO
# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
# path before files name in the file list and in the header files. If set
# to NO the shortest path that makes the file name unique will be used.
FULL_PATH_NAMES = YES
# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
# can be used to strip a user defined part of the path. Stripping is
# only done if one of the specified strings matches the left-hand part of
# the path. It is allowed to use relative paths in the argument list.
STRIP_FROM_PATH = /cvsroot/open-beos/
# The INTERNAL_DOCS tag determines if documentation
# that is typed after a \internal command is included. If the tag is set
# to NO (the default) then the documentation will be excluded.
# Set it to YES to include the internal documentation.
INTERNAL_DOCS = NO
# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
# generate a class diagram (in Html and LaTeX) for classes with base or
# super classes. Setting the tag to NO turns the diagrams off.
CLASS_DIAGRAMS = YES
# If the SOURCE_BROWSER tag is set to YES then a list of source files will
# be generated. Documented entities will be cross-referenced with these sources.
SOURCE_BROWSER = YES
# Setting the INLINE_SOURCES tag to YES will include the body
# of functions and classes directly in the documentation.
INLINE_SOURCES = NO
# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
# doxygen to hide any special comment blocks from generated source code
# fragments. Normal C and C++ comments will always remain visible.
STRIP_CODE_COMMENTS = YES
# If the CASE_SENSE_NAMES tag is set to NO (the default) then Doxygen
# will only generate file names in lower case letters. If set to
# YES upper case letters are also allowed. This is useful if you have
# classes or files whose names only differ in case and if your file system
# supports case sensitive file names.
CASE_SENSE_NAMES = YES
# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
# will show members with their full class and namespace scopes in the
# documentation. If set to YES the scope will be hidden.
HIDE_SCOPE_NAMES = NO
# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
# will generate a verbatim copy of the header file for each class for
# which an include is specified. Set to NO to disable this.
VERBATIM_HEADERS = YES
# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
# will put list of the files that are included by a file in the documentation
# of that file.
SHOW_INCLUDE_FILES = YES
# If the JAVADOC_AUTOBRIEF tag is set to YES (the default) then Doxygen
# will interpret the first line (until the first dot) of a JavaDoc-style
# comment as the brief description. If set to NO, the Javadoc-style will
# behave just like the Qt-style comments.
JAVADOC_AUTOBRIEF = YES
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
# member inherits the documentation from any documented member that it
# reimplements.
INHERIT_DOCS = YES
# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
# is inserted in the documentation for inline members.
INLINE_INFO = YES
# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
# will sort the (detailed) documentation of file and class members
# alphabetically by member name. If set to NO the members will appear in
# declaration order.
SORT_MEMBER_DOCS = YES
# The TAB_SIZE tag can be used to set the number of spaces in a tab.
# Doxygen uses this value to replace tabs by spaces in code fragments.
TAB_SIZE = 4
# The ENABLE_SECTIONS tag can be used to enable conditional
# documentation sections, marked by \if sectionname ... \endif.
ENABLED_SECTIONS =
# The GENERATE_TODOLIST tag can be used to enable (YES) or
# disable (NO) the todo list. This list is created by putting \todo
# commands in the documentation.
GENERATE_TODOLIST = YES
# The GENERATE_TESTLIST tag can be used to enable (YES) or
# disable (NO) the test list. This list is created by putting \test
# commands in the documentation.
GENERATE_TESTLIST = YES
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
# The QUIET tag can be used to turn on/off the messages that are generated
# by doxygen. Possible values are YES and NO. If left blank NO is used.
QUIET = NO
# The WARNINGS tag can be used to turn on/off the warning messages that are
# generated by doxygen. Possible values are YES and NO. If left blank
# NO is used.
WARNINGS = YES
# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
# automatically be disabled.
WARN_IF_UNDOCUMENTED = YES
# The WARN_FORMAT tag determines the format of the warning messages that
# doxygen can produce. The string should contain the $file, $line, and $text
# tags, which will be replaced by the file and line number from which the
# warning originated and the warning text.
WARN_FORMAT = "$file:$line: $text"
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
# The INPUT tag can be used to specify the files and/or directories that contain
# documented source files. You may enter file names like "myfile.cpp" or
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = ../source/lib/
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank all files are included.
FILE_PATTERNS = *.cpp *.h
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
# should be searched for input files as well. Possible values are YES and NO.
# If left blank NO is used.
RECURSIVE = YES
# The EXCLUDE tag can be used to specify files and/or directories that should
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
EXCLUDE =
# If the value of the INPUT tag contains directories, you can use the
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
# certain files from those directories.
EXCLUDE_PATTERNS =
# The EXAMPLE_PATH tag can be used to specify one or more files or
# directories that contain example code fragments that are included (see
# the \include command).
EXAMPLE_PATH =
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank all files are included.
EXAMPLE_PATTERNS =
# The IMAGE_PATH tag can be used to specify one or more files or
# directories that contain image that are included in the documentation (see
# the \image command).
IMAGE_PATH =
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
# by executing (via popen()) the command <filter> <input-file>, where <filter>
# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
# input file. Doxygen will then use the output that the filter program writes
# to standard output.
INPUT_FILTER =
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
# of all compounds will be generated. Enable this if the project
# contains a lot of classes, structs, unions or interfaces.
ALPHABETICAL_INDEX = NO
# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
# in which this list will be split (can be a number in the range [1..20])
COLS_IN_ALPHA_INDEX = 5
# In case all classes in a project start with a common prefix, all
# classes will be put under the same header in the alphabetical index.
# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
# should be ignored while generating the index headers.
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
# generate HTML output.
GENERATE_HTML = YES
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `html' will be used as the default path.
HTML_OUTPUT = html
# The HTML_HEADER tag can be used to specify a personal HTML header for
# each generated HTML page. If it is left blank doxygen will generate a
# standard header.
HTML_HEADER =
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.
HTML_FOOTER =
# The HTML_STYLESHEET tag can be used to specify a user defined cascading
# style sheet that is used by each HTML page. It can be used to
# fine-tune the look of the HTML output. If the tag is left blank doxygen
# will generate a default style sheet
HTML_STYLESHEET =
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
# files or namespaces will be aligned in HTML using tables. If set to
# NO a bullet list will be used.
HTML_ALIGN_MEMBERS = YES
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
# will be generated that can be used as input for tools like the
# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
# of the generated HTML documentation.
GENERATE_HTMLHELP = NO
# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
# top of each HTML page. The value NO (the default) enables the index and
# the value YES disables it.
DISABLE_INDEX = NO
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
# generate Latex output.
GENERATE_LATEX = NO
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `latex' will be used as the default path.
LATEX_OUTPUT = latex
# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
# LaTeX documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_LATEX = NO
# The PAPER_TYPE tag can be used to set the paper type that is used
# by the printer. Possible values are: a4, a4wide, letter, legal and
# executive. If left blank a4wide will be used.
PAPER_TYPE = a4wide
# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
# packages that should be included in the LaTeX output.
EXTRA_PACKAGES =
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
# the generated latex document. The header should contain everything until
# the first chapter. If it is left blank doxygen will generate a
# standard header. Notice: only use this tag if you know what you are doing!
LATEX_HEADER =
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
# is prepared for conversion to pdf (using ps2pdf). The pdf file will
# contain links (just like the HTML output) instead of page references
# This makes the output suitable for online browsing using a pdf viewer.
PDF_HYPERLINKS = NO
# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
# plain latex in the generated Makefile. Set this option to YES to get a
# higher quality PDF documentation.
USE_PDFLATEX = NO
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
# command to the generated LaTeX files. This will instruct LaTeX to keep
# running if errors occur, instead of asking the user for help.
# This option is also used when generating formulas in HTML.
LATEX_BATCHMODE = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
# The RTF output is optimised for Word 97 and may not look very pretty with
# other RTF readers or editors.
GENERATE_RTF = NO
# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `rtf' will be used as the default path.
RTF_OUTPUT = rtf
# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
# RTF documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_RTF = NO
# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
# will contain hyperlink fields. The RTF file will
# contain links (just like the HTML output) instead of page references.
# This makes the output suitable for online browsing using a WORD or other.
# programs which support those fields.
# Note: wordpad (write) and others do not support links.
RTF_HYPERLINKS = NO
# Load stylesheet definitions from file. Syntax is similar to doxygen's
# config file, i.e. a series of assigments. You only have to provide
# replacements, missing definitions are set to their default value.
RTF_STYLESHEET_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
# generate man pages
GENERATE_MAN = NO
# The MAN_OUTPUT tag is used to specify where the man pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `man' will be used as the default path.
MAN_OUTPUT = man
# The MAN_EXTENSION tag determines the extension that is added to
# the generated man pages (default is the subroutine's section .3)
MAN_EXTENSION = .3
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
# If the GENERATE_XML tag is set to YES Doxygen will
# generate an XML file that captures the structure of
# the code including all documentation. Warning: This feature
# is still experimental and very incomplete.
GENERATE_XML = NO
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
# evaluate all C-preprocessor directives found in the sources and include
# files.
ENABLE_PREPROCESSING = YES
# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
# names in the source code. If set to NO (the default) only conditional
# compilation will be performed. Macro expansion can be done in a controlled
# way by setting EXPAND_ONLY_PREDEF to YES.
MACRO_EXPANSION = NO
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
# then the macro expansion is limited to the macros specified with the
# PREDEFINED and EXPAND_AS_PREDEFINED tags.
EXPAND_ONLY_PREDEF = NO
# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
# in the INCLUDE_PATH (see below) will be search if a #include is found.
SEARCH_INCLUDES = YES
# The INCLUDE_PATH tag can be used to specify one or more directories that
# contain include files that are not input files but should be processed by
# the preprocessor.
INCLUDE_PATH =
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
# directories. If left blank, the patterns specified with FILE_PATTERNS will
# be used.
INCLUDE_FILE_PATTERNS =
# The PREDEFINED tag can be used to specify one or more macro names that
# are defined before the preprocessor is started (similar to the -D option of
# gcc). The argument of the tag is a list of macros of the form: name
# or name=definition (no spaces). If the definition and the = are
# omitted =1 is assumed.
PREDEFINED =
# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
# The macro definition that is found in the sources will be used.
# Use the PREDEFINED tag if you want to use a different macro definition.
EXPAND_AS_DEFINED =
#---------------------------------------------------------------------------
# Configuration::addtions related to external references
#---------------------------------------------------------------------------
# The TAGFILES tag can be used to specify one or more tagfiles.
TAGFILES =
# When a file name is specified after GENERATE_TAGFILE, doxygen will create
# a tag file that is based on the input files it reads.
GENERATE_TAGFILE =
# If the ALLEXTERNALS tag is set to YES all external classes will be listed
# in the class index. If set to NO only the inherited external classes
# will be listed.
ALLEXTERNALS = NO
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of `which perl').
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
# available from the path. This tool is part of Graphviz, a graph visualization
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
# have no effect if this option is set to NO (the default)
HAVE_DOT = NO
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect inheritance relations. Setting this tag to YES will force the
# the CLASS_DIAGRAMS tag to NO.
CLASS_GRAPH = YES
# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
# will generate a graph for each documented class showing the direct and
# indirect implementation dependencies (inheritance, containment, and
# class references variables) of the class with other documented classes.
COLLABORATION_GRAPH = YES
# If the ENABLE_PREPROCESSING, INCLUDE_GRAPH, and HAVE_DOT tags are set to
# YES then doxygen will generate a graph for each documented file showing
# the direct and indirect include dependencies of the file with other
# documented files.
INCLUDE_GRAPH = YES
# If the ENABLE_PREPROCESSING, INCLUDED_BY_GRAPH, and HAVE_DOT tags are set to
# YES then doxygen will generate a graph for each documented header file showing
# the documented files that directly or indirectly include this file
INCLUDED_BY_GRAPH = YES
# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
# will graphical hierarchy of all classes instead of a textual one.
GRAPHICAL_HIERARCHY = YES
# The tag DOT_PATH can be used to specify the path where the dot tool can be
# found. If left blank, it is assumed the dot tool can be found on the path.
DOT_PATH =
# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
# this value, doxygen will try to truncate the graph, so that it fits within
# the specified constraint. Beware that most browsers cannot cope with very
# large images.
MAX_DOT_GRAPH_WIDTH = 1024
# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
# this value, doxygen will try to truncate the graph, so that it fits within
# the specified constraint. Beware that most browsers cannot cope with very
# large images.
MAX_DOT_GRAPH_HEIGHT = 1024
#---------------------------------------------------------------------------
# Configuration::addtions related to the search engine
#---------------------------------------------------------------------------
# The SEARCHENGINE tag specifies whether or not a search engine should be
# used. If set to NO the values of all tags below this one will be ignored.
SEARCHENGINE = NO
# The CGI_NAME tag should be the name of the CGI script that
# starts the search engine (doxysearch) with the correct parameters.
# A script with this name will be generated by doxygen.
CGI_NAME = search.cgi
# The CGI_URL tag should be the absolute URL to the directory where the
# cgi binaries are located. See the documentation of your http daemon for
# details.
CGI_URL =
# The DOC_URL tag should be the absolute URL to the directory where the
# documentation is located. If left blank the absolute path to the
# documentation, with file:// prepended to it, will be used.
DOC_URL =
# The DOC_ABSPATH tag should be the absolute path to the directory where the
# documentation is located. If left blank the directory on the local machine
# will be used.
DOC_ABSPATH =
# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
# is installed.
BIN_ABSPATH = /usr/local/bin/
# The EXT_DOC_PATHS tag can be used to specify one or more paths to
# documentation generated for other projects. This allows doxysearch to search
# the documentation for these projects as well.
EXT_DOC_PATHS =
@@ -0,0 +1,614 @@
\documentclass[12pt, a4paper]{article}
\usepackage{amssymb,amsmath,latexsym}
\usepackage[english]{babel}
\usepackage{hhline}
\newcommand{\code}[1]{{\tt #1}}
\newenvironment{nitemize}{
\newdimen\oldparindent
\oldparindent=\parindent
\begin{itemize}
\itemindent=-\oldparindent
}{
\end{itemize}
}
%\newcommand{\codeblockspace}{\vspace{12pt}}
% begin/end a code block
\newcommand{\codeblockbegin}{\begin{flushleft}\begin{minipage}{\textwidth}}
\newcommand{\codeblockend}{\end{minipage}\end{flushleft}}
\begin{document}
\sloppy
\title{The Resources Format}
%\date{}
\author{Ingo Weinhold ([email protected])}
\maketitle
\tableofcontents
\section{Introduction}
\label{introduction}
Resources provide a means to store structured but flat data in files. Unlike
attributes resources are part of the file contents and thus do not require a
special file system handling, but rather a special file format.
On the one hand there are formats of files that exclusively contain resources
(resource files), on the other hand these are file formats extended to
additionally contain resources -- namely the ELF and PEF object formats.
In either case the format of the chunk of data that frames the resources
themselves is the same. We call it the resources format.
Section \ref{file-formats} explains how the resources format is embedded in
different file formats. Section \ref{resources-format} discusses the resources
format itself. In section \ref{implementations} we focus on robustness of
resources reading/writing implementations.
The final section says some words about the status of the information provided
by this document.
\section{File Formats}
\label{file-formats}
In all file formats described in this section the resources are being located
at the end of the files. They are completely independent of their location.
\subsection{x86 Resource Files}
x86 resource files introduce the least overhead. The resources start directly
after the magic number identifying the file format:
%
\codeblockbegin
\begin{verbatim}
const char kX86ResourceFileMagic[4] = { 'R', 'S', 0, 0 };
const uint32 kX86ResourcesOffset = 0x00000004;
\end{verbatim}
\codeblockend
%
The resources start at \code{kX86ResourcesOffset}.
\subsection{PPC Resource Files}
PPC resource files begin with a PEF container header, after which the
resources start.
%
\codeblockbegin
\begin{verbatim}
typedef char PefOSType[4];
struct PEFContainerHeader {
PefOSType tag1;
PefOSType tag2;
PefOSType architecture;
uint32 formatVersion;
uint32 dateTimeStamp;
uint32 oldDefVersion;
uint32 oldImpVersion;
uint32 currentVersion;
uint16 sectionCount;
uint16 instSectionCount;
uint32 reservedA;
};
\end{verbatim}
\codeblockend
%
\codeblockbegin
\begin{verbatim}
const char kPEFFileMagic1[4] = { 'J', 'o', 'y', '!' };
const char kPPCResourceFileMagic[4] = { 'r', 'e', 's', 'f' };
const uint32 kPPCResourcesOffset = 0x00000028;
\end{verbatim}
\codeblockend
\begin{nitemize}
\item{\code{tag1}:
Must be \code{kPEFFileMagic1}.}
\item{\code{tag2}:
Must be \code{kPPCResourceFileMagic}.}
\item{All other fields must be set to 0.}
\end{nitemize}
\noindent
The resources start at \code{kPPCResourcesOffset}.
\subsection{ELF Object Files}
In an ELF file, resources are appended to rather than contained in the
regular data of the file. That is adding resources to an existing ELF file
will not cause any modification to its data (i.e. ELF header, program header
table, section header table or sections), but will enlarge the file by some
alignment padding and, of course, the resources themselves.
Therefore two values have to be known: The size of the actual ELF file and the
block size to which the resources must be aligned. As ELF files do not contain
a size field, it has to be deduced, where the file ends. This end offset is
supposed to be the maximum of the end offsets of ELF header, program header
table (if any), section header table (if any), sections and segments.
The block size to which the resources have to be aligned is the maximum of
\code{kELFMinResourceAlignment} and the alignments of the segments in the file.
%
\begin{verbatim}
const uint32 kELFMinResourceAlignment = 32;
\end{verbatim}
%
The data used for the padding between the end of the actual ELF data and the
beginning of the resources may be arbitrary.
\subsection{PEF Object Files}
Similar to ELF files the resources are simply appended to the regular data of
a PEF file, but they are not aligned to any value. That is the resources
start directly after the last PEF section without any padding.
As no field exists, that tells about the size of the PEF container (the
regular data), it has to be deduced by iterating through the PEF section
headers.
\section{The Resources Format}
\label{resources-format}
This section describes the resources format. After a subsection that outlines
their general layout, it follow subsections discussing the major parts.
A general remark regarding the byte ordering: Resources have no standard
endianess, that is the resources created by little endian and big endian
machines differ. Usually it should be possible, to deduce the used endianess
from the type of the file. x86 resource files contain little endian, PPC
resource files big endian data. The endianess of an ELF file is encoded in
its header.
As there is in fact no good reason to have different resource file formats,
even if they differ only in the format of the header (see section
\ref{file-formats}), it may be decided to use the x86 resource file format
also for big endian machines. Therefore the endianess may be deduced by the
first field of the resources header (\code{rh\_resources\_magic}, see
subsection \ref{resources-header}).
\subsection{Resources Layout}
The layout of the resources in a file is shown in figure
\ref{fig:resources-layout}.
\begin{figure}[h!tb]
\begin{center}
\begin{tabular}{|c|c|c|}
\hline
& \multicolumn{2}{c|}{resources header}\\
\hhline{|~==|}
admin section & & index section header \\
\hhline{~~|-|}
& index section & resource index \\
\hhline{~~|-|}
& & padding \\
\hhline{:===:}
\multicolumn{3}{|c|}{unknown section}\\
\hhline{:===:}
\multicolumn{3}{|c|}{data section}\\
\hhline{|~~~|}
\hhline{:===:}
\multicolumn{3}{|c|}{info section}\\
\hline
\end{tabular}
\end{center}
\caption{The Resources Layout.}
\label{fig:resources-layout}
\end{figure}
\noindent
There are four sections:
%
\begin{itemize}
\item{An administrative section which comprises the resources header and the
resource index subsection. The latter locates all other data in the file.
}
\item{An unknown section, whose purpose is (unsurprisingly) unknown, but which
seems to be unused, always containing the same data.
}
\item{A data section holding the actual resource data.
}
\item{An info section, which provides aditional information for each resource,
such as type, id and name.
}
\end{itemize}
\subsection{Resources Header}
\label{resources-header}
The resources header has the following structure:
%
\codeblockbegin
\begin{verbatim}
struct resources_header {
uint32 rh_resources_magic;
uint32 rh_resource_count;
uint32 rh_index_section_offset;
uint32 rh_admin_section_size;
uint32 rh_pad[13];
};
\end{verbatim}
\codeblockend
%
\codeblockbegin
\begin{verbatim}
const uint32 kResourcesHeaderMagic = 0x444f1000;
const uint32 kResourceIndexSectionOffset = 0x00000044;
const uint32 kResourceIndexSectionAlignment = 0x00000600;
\end{verbatim}
\codeblockend
\begin{nitemize}
\item{\code{rh\_resources\_magic}:
Must be \code{kResourcesHeaderMagic}.
}
\item{\code{rh\_resource\_count}:
Specifies the number of resources stored in this file. May be 0.
}
\item{\code{rh\_index\_section\_offset}:
Specifies the offset of the resource index section relative to the beginning
of the resources. An alternative interpretation may be the size of the
resources header.
Must be \code{kResourceIndexSectionOffset}.
}
\item{\code{rh\_admin\_section\_size}:
Specifies the size of the administrative section.
Must be \code{kResourceIndexSectionOffset} plus a multiple of
\code{kResourceIndexSectionAlignment}.
}
\item{\code{rh\_pad}:
Padding. \code{0x00000000} words.
}
\end{nitemize}
\subsection{Resource Index Section}
\label{resources-index}
The resource index section starts with a header, it follows a table of
\code{resource\_index\_entry} structures, that locates the data of each
resource, and the section ends with a special padding.
\noindent
The resource index header has the following structure:
%
\codeblockbegin
\begin{verbatim}
struct resource_index_section_header {
uint32 rish_index_section_offset;
uint32 rish_index_section_size;
uint32 rish_unused_data1;
uint32 rish_unknown_section_offset;
uint32 rish_unknown_section_size;
uint32 rish_unused_data2[25];
uint32 rish_info_table_offset;
uint32 rish_info_table_size;
uint32 rish_unused_data3;
};
\end{verbatim}
\codeblockend
\begin{verbatim}
const uint32 kUnknownResourceSectionSize = 0x00000168;
\end{verbatim}
%
\begin{nitemize}
\item{\code{rish\_index\_section\_offset}:
Specifies the offset of the resource index section relative to the beginning
of the resources. An alternative interpretation may be the size of the
resources header.
Must be \code{kResourceIndexSectionOffset}.
}
\item{\code{rish\_index\_section\_size}:
Specifies the size of the resource index section.
Must be a multiple of \code{kResourceIndexSectionAlignment}.
}
\item{\code{rish\_unused\_data1}:
Contains special data as described in section \ref{resources-unknown}.
}
\item{\code{rish\_unknown\_section\_offset}:
Specifies the offset of the unknown section relative to the beginning
of the resources.
Must be the same value as given in the resources header for
\code{rh\_admin\_section\_size}.
}
\item{\code{rish\_unknown\_section\_size}:
Specifies the offset of the unknown section relative to the beginning
of the resources.
Must be \code{kUnknownResourceSectionSize};
}
\item{\code{rish\_unused\_data2}:
Contains special data as described in section \ref{resources-unknown}.
}
\item{\code{rish\_info\_table\_offset}:
Specifies the offset of the resource info table relative to the beginning
of the resources.
}
\item{\code{rish\_info\_table\_size}:
Specifies the size of the resource info table.
}
\item{\code{rish\_unused\_data3}:
Contains special data as described in section \ref{resources-unknown}.
}
\end{nitemize}
Directly, without padding, it follows a table of \code{resource\_index\_entry}
structures. The number of entries in the table is the number of resources
stored in the file, that is the value specified by the
\code{rh\_resource\_count} member of the resources header. Since the entries
are stored without padding, the size of the table is exactly the product of
the size of \code{resource\_index\_entry} and the number of resources.
If the latter is 0, the table takes no space.
%
\codeblockbegin
\begin{verbatim}
struct resource_index_entry {
uint32 rie_offset;
uint32 rie_size;
uint32 rie_pad;
};
\end{verbatim}
\codeblockend
%
\begin{nitemize}
\item{\code{rie\_offset}:
Specifies the offset of the resource data relative to the beginning
of the resources.
}
\item{\code{rie\_size}:
Specifies the size of the resource data.
}
\item{\code{rie\_pad}:
Padding. Must be \code{0x00000000}.
}
\end{nitemize}
Since the size of the resource index section must be a multiple of
\code{kResourceIndexSectionAlignment}, some padding may be needed at the end
of this section. How this padding looks like is described in section
\ref{resources-unknown}.
\subsection{Unknown Section}
\label{resources-unknown}
The meaning of this section is unknown. It does not seem to be used at all.
It always contains the same data given by \code{kUnusedResourceDataPattern}:
%
\codeblockbegin
\begin{verbatim}
const uint32 kUnusedResourceDataPattern[3] = {
0xffffffff, 0x000003e9, 0x00000000
};
\end{verbatim}
\codeblockend
%
In section \ref{resources-index} some members where named \code{unused\_data}.
These fields contain the same kind of data. To understand what the value for a
certain field of this type is, it may help to imagine, that before the
resources are written to a file, the space they will take is filled with the
pattern specified by \code{kUnusedResourceDataPattern}, and that only those
fields are written that are not unused. Thus the original pattern can be seen
through at the unused locations.
To be precise: Let \verb|uint32 resources[]| be the resources and
\code{index} the index of an unused field in \code{resources}, then it holds:
%
\begin{verbatim}
resources[index] == kUnusedResourceDataPattern[index % 3];
\end{verbatim}
%
\subsection{Resource Info Table}
\label{resources-infotable}
The resource info table features exactly one entry for each resource.
Such an entry (resource info) specifies the ID and name of a
resource. Subsequent infos for resources of the same type are collected in
a block that starts with a type field.
The following grammar specifies the layout of the resource info table.
Nonterminals start with an upper case, terminals with a lower case letter.
%
\begin{verbatim}
ResourceInfoTable ::= [ ResourceBlockList ]
ResourceInfoSeparator
ResourceInfoTableEnd
ResourceBlockList ::= ResourceBlock
[ ResourceInfoSeparator
ResourceBlockList ]
ResourceBlock ::= type ResourceInfoList
ResourceInfoList ::= ResourceInfo [ ResourceInfoList ]
ResourceInfo ::= id index name_size name
ResourceInfoSeparator ::= 0xffffffff 0xffffffff
ResourceInfoTableEnd ::= check_sum 0x00000000
\end{verbatim}
%
The relevant structures follow:
%
\codeblockbegin
\begin{verbatim}
struct resource_info_block {
type_code rib_type;
resource_info rib_info[1];
};
\end{verbatim}
\codeblockend
%
\begin{nitemize}
\item{\code{rib\_type}:
Specifies the type of the resources in the block.
}
\item{\code{rib\_info}:
Is the first resource info of the block. More infos may follow.
}
\end{nitemize}
%
\codeblockbegin
\begin{verbatim}
struct resource_info {
int32 ri_id;
int32 ri_index;
uint16 ri_name_size;
char ri_name[1];
};
\end{verbatim}
\codeblockend
\begin{verbatim}
const uint32 kMinResourceInfoSize = 10;
\end{verbatim}
%
\begin{nitemize}
\item{\code{ri\_id}:
Specifies the ID of the resource.
}
\item{\code{ri\_index}:
Specifies the index of the resource this resource info refers to.
}
\item{\code{ri\_name\_size}:
Specifies the size of the resource name. May be 0 -- then the resource does
not have a name and \code{ri\_name} has a size of 0.
}
\item{\code{ri\_name}:
Specifies the name of the resource. The name must be null terminated.
\code{ri\_name\_size} specifies the size of this field (including the
terminating null). If it is 0, the resource does not have a name and
\code{ri\_name} is empty, i.e. has size 0.
}
\item{\code{kMinResourceInfoSize}:
Is the minimal size of a resource info. That is the size it has, if the
resource does not have a name.
}
\end{nitemize}
%
\codeblockbegin
\begin{verbatim}
struct resource_info_separator {
uint32 ris_value1;
uint32 ris_value2;
};
\end{verbatim}
\codeblockend
%
\begin{nitemize}
\item{\code{ris\_value1}:
Specifies the first word of the separator.
Must be \code{0xffffffff}.
}
\item{\code{ris\_value2}:
Specifies the second word of the separator.
Must be \code{0xffffffff}.
}
\end{nitemize}
%
\codeblockbegin
\begin{verbatim}
struct resource_info_table_end {
uint32 rite_check_sum;
uint32 rite_terminator;
};
\end{verbatim}
\codeblockend
%
\begin{nitemize}
\item{\code{rite\_check\_sum}:
Contains the check sum for the resource info table. The check sum is
calculated from all bytes of the resource info table not including
\code{rite\_check\_sum} and \code{rite\_terminator}. The data are grouped
into four byte blocks, which are interpreted as big endian unsigned words
and summed up, ignoring carry. If the number of bytes to be considered is
not dividable by four, the remaining bytes are interpreted as the lower
bytes of a big endian unsigned word (the upper byte(s) set to 0).
}
\item{\code{rite\_terminator}:
Terminates the resource info table.
Must be \code{0x00000000}.
}
\end{nitemize}
\section{Implementations}
\label{implementations}
Code that writes resources should strictly stick to the specification
presented in the preceding sections to achieve maximal compatibility.
Resources reading implementations may tolerate certain deviations that
for instance happen to occur in several files of the BeOS R5 distribution
and that are handled gracefully by xres and QuickRes. It follows a, possibly
incomplete, list:
%
\begin{itemize}
\item{The third and fourth byte of the x86 resource file magic (the 0 bytes)
may be arbitrary bytes.}
\item{\code{rh\_resource\_count} may be unreliable. The resource index table
should be read until its end, which is either marked by the unused data
pattern (see section \ref{resources-unknown}) or at the latest by the
beginning of the unknown section.}
\item{The resource info table may contain entries for indices that are out
of range, i.e. greater than the number of resources induced by the resource
index table. Those entries should be ignored.}
\item{The resource info table may contain multiple entries for an index.
Any such entry after the first one should be ignored.}
\item{The resource info table may not contain an entry for an index.
The respective resource should be ignored.}
\item{The resource info table may not contain a \code{ResourceInfoTableEnd}
(see section \ref{resources-infotable}) and thus no check sum. The table
should be accepted nevertheless. Note, that a table containing a wrong check
sum is {\em not} to be accepted.}
\end{itemize}
\section{Status of this Document}
\label{status}
The information contained in this document are obtained by analyzing
resources-containing files created or modified by tools available for BeOS R5,
namely QuickRes and xres. They are incomplete and may even be partially wrong,
where being based on incorrect assumptions.
\noindent
It follows a list of items with a low degree of reliance:
\begin{itemize}
\item{Resources alignment in ELF files: Several tests with linker object files
have shown, that QuickRes aligns their resources offset to 32 bytes.
For executables on the other hand the alignment was always 4096, which is
the usual memory page size of current x86 architectures and therefore the
preferred program segment alignment. From these two information it has been
deduced, that the alignment is, if present, the maximum of
the segment alignments to be found in the program header table,
but at minimum 32.}
\item{The resources layout: The general layout of the resources is not very
well understood. The layout presented in figure \ref{fig:resources-layout}
resulted from the attempt to assign all the fields a reasonable meaning, but
in fact not even the exact length and meaning of the fields of the resources
header is unclear. The same holds for the resource index section header.}
\item{The unknown section: The contents of the unknown section and of unknown
fields is base on educated guesses.}
\end{itemize}
\end{document}