LIB Format (Mythos Software)

From ModdingWiki
Jump to: navigation, search
LIB Format (Mythos Software)
Format typeArchive
Max files65,536
File Allocation Table (FAT)Beginning
Filenames?Yes, 8.3
Metadata?None
Supports compression?No
Supports encryption?No
Supports subdirectories?No
Hidden data?Yes
Games

Mythos Software's LIB Format is very similar to the LIB format used by Electronic Arts, which is fitting since EA was the publisher for Mythos Software. It is efficient in the sense that it only stores file names and starting positions in the header, so file lengths must be inferred. It does not support compression. There are two versions of LIB files. An earlier version used in The Lost Files of Sherlock Holmes: The Case of the Serrated Scalpel, and a later version used in The Lost Files of Sherlock Holmes: Case of the Rose Tattoo. The second version has a different layout and has yet to be examined.

File format

Signature

Version 1 LIB files begin with "LIB", then character 0x1A, then the number of files. You actually have to read one more file entry than the header suggests, as there is an empty file entry at the end of the list used for a file size calculation.

Data type Name Description
char[4] cSignature "LIB", plus 0x1A
UINT16LE fileCount Number of files

The signature is followed immediately by a file entry structure, repeated fileCount times.

File entry

Each file entry consists of the file name and its offset in the file. Even though the file name is fixed-width, it appears to be null-terminated.

Data type Name Description
char[13] filename File name (8.3 style), padded with nulls to 13 characters
UINT32LE offset File's offset from the start of the LIB archive

Each file's size must be calculated by subtracting it from the next file's offset. There is an additional null-named file at the end with an offset equal to the size of the file so you don't need any special code to get the final file's size. This entry is not included in fileCount in the header.

Hidden data

While no files appear to use this, it is possible to hide data after the list of file entries and before the first file.

As there is an extra file entry to hold the size of the archive file, it is also possible to hide data at the end of the file as long as it comes after the offset of the final null-named file entry.

Both these methods produce valid files where the hidden data would always be ignored.

Notes

The Music.lib group affixes 12 spaces to the beginning of each file. Although this may just be part of the music format, it is also affixed to the driver files. It is unknown why these spaces are in this lib group, but they do not show up in other lib files. Perhaps it was required for the sound engine?

Tools

The following tools are able to work with files in this format.

Name PlatformExtract files? Decompress on extract? Create new? Modify? Compress on insert? Access hidden data? Edit metadata? Notes
Camoto Linux/WindowsYesN/AYesYesN/ANoN/A

Source Code

This FreeBASIC code will extract all of the files from the LIB file into a folder named after the LIB file you specify.

' Specify the Mythos Software LIB file here:
Dim As String LibFileName = "music.lib"
 
Open LibFileName For Binary As #1
 
Print "Reading header..."
 
' Verify the format's magic word.
Dim As String MagicWord = Space(3)
Get #1, , MagicWord
If MagicWord <> "LIB" Then
    Print "Not a Mythos Software .LIB file."
    End
End If
 
' Header Structure
Dim As Byte Unknown1
Get #1, , Unknown1
Dim As UShort NumberOfFiles
Get #1, , NumberOfFiles
 
' An additional entry is made which has an empty file name and stores the length of the LIB file as the starting offset.
' This is used to calculate the length of the last file without needing special code to determine it based on the file size.
NumberOfFiles = NumberOfFiles + 1
 
Print "Valid LIB File."
 
' Load the header filenames and their offsets.
Dim FileName(1 To NumberOfFiles) As String
Dim FileStart(1 To NumberOfFiles) As UInteger
 
Dim As UShort FileNo
For FileNo = 1 To NumberOfFiles
    FileName(FileNo) = Space(13)
 
    Get #1, , FileName(FileNo)
    FileName(FileNo) = Left(FileName(FileNo), InStr(FileName(FileNo), Chr(0)) - 1)
 
    Get #1, , FileStart(FileNo)
Next FileNo
 
' Extract the files.
Print "Extracting..."
 
Dim As String LibFolder = Left(LibFileName, InStr(LibFileName, ".") - 1)
MkDir("./" + LibFolder)
 
Dim As ULongInt FileLength
For FileNo = 1 To (NumberOfFiles - 1)           ' Skip the last file which is not a real file anyway.
    FileLength = FileStart(FileNo + 1) - FileStart(FileNo)
 
    Print "    ./" + LibFolder + "/" + FileName(FileNo) + "  -  " + Str(FileLength) + " bytes"
 
    Dim FileContents(0 To (FileLength - 1)) As Byte
    Get #1, FileStart(FileNo) + 1, FileContents()
 
    Open ("./" + LibFolder + "/" + FileName(FileNo)) For Binary As #2
    Put #2, , FileContents()
    Close #2
Next FileNo
 
Close #1
Print : Print Str(NumberOfFiles - 1) + " file(s) extracted."
Sleep

Credits

This archive format was reverse engineered by TheAlmightyGuru. If you find this information helpful in a project you're working on, please give credit where credit is due. (A link back to this wiki would be nice too!)