CRI ROFS

From Wiki - GameHacking.org
Revision as of 01:21, 29 June 2008 by LiquidManZero (talk | contribs)

ROFS is a bulk data file structure developed by CRI Middleware Co., Ltd. It is greatly built off of the ISO-9660 standard. These are easily identified as having the file name extension of CVM.



Random

Several official programs for handling CVM files are known to exist. Actual usage is not entirely known.

    rofstoko.exe - ? Seemingly used to change existing data and perhaps conversion of some file types.
    rofsedit.exe - ?
    rofsgen.exe  - ?
    rofsbld.exe  - ?
    rofsview.exe - ?

There are a few homemade programs created for interacting with CVM filesystems with various limited functionality.

Apache3 - Badly named but effective for extracting the contents of a CVM (and several other disc image types such as GCM). It can also replace files inside the image. Has entirely no capacity to create new files from scratch.

apache3_setup.exe v3.10.6 beta

Daemon Tools (and some other disc mounting software) - If a 0x1800 block is removed from the start of the file, it can be mounted as a disc image. Other mounting utilities may not cooperate.

Abyss - A tiny custom tool made by darthi8nt for beating up the TO7BTL.cvm file from Tales Of The Abyss. It looks to be only for that specific file and no others.

abyss.zip

abyss_update.zip

VF4EXt_n_reb - Another tool from darthi8nt. Same deal as with Abyss, but for VF4STRMS.cvm on Virtua Fighter 4.

VF4EXt_n_reb.rar


Structure

This information is incomplete and may by itself not be of much help. Note also that it may not apply to all containers of this format being that there are known to be incompatible revisions.

Basic

At least two versions exist, perhaps not compatible with each other. One is ROFSROFSBLD Ver.1.52 2003-06-09, another is ROFSROFSBLD Ver.1.23 2001-10-17.

From: XeNTaX - ROFS Compression\?Encryption? Method

    ROFS , By turning off the 0x1800 byte from the forefront of the file (header), and change the extension to .iso, Daemon tools can mount it.
    
    With the header where 0x1800 is gone, then it seems that its retained with the file system ( ISO9660 )
    
    ROFS (CVM) file format memo
    
    B = byte (8bit)
    W = word (16bit)
    L = long word (32bit)
    
    -- 
    0x0000-0xb7ff
    - ROFS version
    - GAME TITLE and PUBLISHER_NAME etc.
    
    offset 0xb800
    1W: first data length = A
    1L: START address START (little endian)
    1L: START address START (big endian)
    1L: FAT SIZE (little endian)
    1L: FAT SIZE (big endian)
    1B: 0x68??
    1B: data length X
    XB: ?? (date?)
    4B: 01 00 00 01 ??
    2B: 01 00 or 01 01
    01 01 as for the FAT SIZE-related data end?
    
    1W: next data length = B
    
    here byte become A. Reading B Byte next, it processes.  
    
    However, because completely it has become the same contents as A in regard to data which is read next, 
    as for meaning in regard to data of B you do          not understand well. For verification?
    
    -- 
    offset 0xb800 + A + B
    1W: data length C
    
    :DATA FIRST
    
    1L: START address START (little endian)
    1L: START address START (big endian)
    FILE START address = 0x800*START + 0x1800
    1L: file size (little endian)
    1L: file size (big endian)
    
    1B: 0x68 ??
    1B: data length Y
    YB: ?? (date?)
    4B: 01 00 00 01 ??
    1B: file name length Z
    ZB: file name
    2B: 3B 31 (flag?)
    
    0 fill are done
    
    last 1W: In case of data length of following data D
    0x0000, it adjusts the length of the following data and is packed (?)There is a place where it is done. The data other than
    0x00 appears to has the necessity to search.  
    
    The quantities of all to here byte become C. Reading D Byte next, it processes. 
    However, it adjusts and is packed (?)When it was done, data length stops being agreeable.  
    
    After returning to DATA FIRST, to FAT SIZE + 0x1800 it repeats processing.


From: XeNTaX - - ROFS Compression\?Encryption? Method

struct ROFSRootEntry
{
int Offset;
short Unknown;
std::string Name;
};

struct ROFSEntry
{
unsigned short EntrySize; // Entry Header Size
unsigned int Address; // File start offset
unsigned int Size; // File Size
unsigned char Unk0[10];
unsigned short Unk;
std::string Name;
};

if I remember correctly the root entries are a listing of all directories in the file. 
from there the rofsentry structure is used to navigate the actual directory and file structure. 
a flag in the rofsentry structure tells if the entry is a directory(0x02) or a file(0x01) but I don't know 
where that was ^_^; when the entry is a directory the offset leads to another listing of directories 
or files. the file is padded to 4096 or 2048 I don't remember. (directories always have "." and ".." entries)

First read the root entries at offset ??? load them into memory and use that to get the entire 
file list(with rofsentry structure) it is just a bunch of interconnecting nodes.


Links

CRI・ミドルウェア : インサイドミドルウェア : 第2話 インサイドROFS 「ROFSTOKO.EXE」: - Japanese page roughly describing ROFS.

ROFS について - Another page in Japanese, with actual information about the file structure.

Apache3 - Site for Apache3, Munge Explorer, and several other programs.

The Ins And Outs Of ISO 9660 And High Sierra - A rather detailed explanation of an ISO-9660 filesystem.