PDA

View Full Version : BRF file format investigation



mrblack51
10-03-2004, 05:05 PM
/media/lib/resources/RecordingQualityDocument.brf
/media/lib/resources/BitstreamFormatDocument.brf

those look like they will deal with resolutions and such, rather than the old resources we used to mess with. hmm, guess i need to start understanding the following functions (in 5.2):

0x013af834 <- seems to deal with the TuikRes in general
0x01260870 <- load/validate a brf file from tuikres
0x011b1e5c <- load/display? png from tuikres

mrblack51
10-03-2004, 05:32 PM
beginnings of brf documentation:


0A BF 00 01 ; magic number? seems to be at the beginning of every brf
04 ; number of records
AA BB CC DD ; indicates a record? AA is the record type, BB is the record order, starting with 00, increasing by one per record. CC is the record subtype? (0x04 == string). DD is the length of the record. note that the records aren't necessarily in order in the file

/sw_dvd/lib/BurningLibrary/TvDvdSharedBurningDataDocument.brf


00000000h: 0A BF 00 01 04 02 00 04 0F 64 76 64 5F 54 6F 70 ; ........dvd_Top
00000010h: 4D 65 6E 75 25 30 32 64 02 01 04 11 64 76 64 5F ; Menu%02d....dvd_
00000020h: 54 69 74 6C 65 4D 65 6E 75 25 30 32 64 02 02 04 ; TitleMenu%02d...
00000030h: 0E 64 76 64 5F 54 6F 70 4D 65 6E 75 56 6F 62 02 ; .dvd_TopMenuVob.
00000040h: 03 04 10 64 76 64 5F 54 69 74 6C 65 4D 65 6E 75 ; ...dvd_TitleMenu
00000050h: 56 6F 62 ; Vob



so the above has 4 records:
record 0x00, type 0x04, lenght 0x0F (15 bytes), value "dvd_TopMenu%02d"
record 0x01, type 0x04, lenght 0x11 (17 bytes), value "dvd_TitleMenu%02d"
record 0x02, type 0x04, lenght 0x0E (14 bytes), value "dvd_TopMenuVob"
record 0x03, type 0x04, lenght 0x10 (16 bytes), value "dvd_TitleMenuVob"

mrblack51
10-03-2004, 05:42 PM
00000000h: 0A BF 00 01 06 02 07 80 65 03 01 00 00 01 80 4B ; ......e.....K
00000010h: 1D 01 00 44 18 50 72 65 73 73 20 53 45 4C 45 43 ; ...D.Press SELEC
00000020h: 54 20 74 6F 20 63 6F 6E 74 69 6E 75 65 00 02 00 ; T to continue...
00000030h: 04 00 02 01 03 00 05 00 11 02 04 00 80 4A 01 01 ; ............J..
00000040h: 02 06 04 00 ; ....

01 XX 44 YY <- display string in dialog? followed by string of length YY



edit: this is more likely to be as follows:


/*
02 07 80 65 03 01 00 00 01
80 4B 1D 01 00 44
18 50 72 65 73 73 20 53 45 4C 45 43 54 20 74 6F 20 63 6F 6E 74 69 6E 75 65 00 ; Press SELECT to continue
*/

basically, its a record containing two subrecords, an 80 65 and an 80 4B. the 80 4B records are generally a total length, 3 bytes (I have seen 01 00 40 and 01 00 44), then a string in the standard type 4 format of size followed by data. still investigating, but seems more reasonable.

mrblack51
10-04-2004, 01:54 PM
00000000h: 0A BF 00 01 04 02 02 80 77 2E 60 16 43 55 53 54 ; ......w.`.CUST
00000010h: 4F 4D 45 52 5F 53 55 50 50 4F 52 54 5F 54 49 54 ; OMER_SUPPORT_TIT
00000020h: 4C 45 15 54 69 56 6F 20 43 75 73 74 6F 6D 65 72 ; LE.TiVo Customer
00000030h: 20 53 75 70 70 6F 72 74 02 01 80 77 28 60 17 43 ; Support..w(`.C
00000040h: 55 53 54 4F 4D 45 52 5F 53 55 50 50 4F 52 54 5F ; USTOMER_SUPPORT_
00000050h: 4E 55 4D 42 45 52 0E 31 2D 38 37 37 2D 33 36 37 ; NUMBER.1-877-367
00000060h: 2D 38 34 38 36 02 03 80 77 2F 60 18 43 55 53 54 ; -8486..w/`.CUST
00000070h: 4F 4D 45 52 5F 53 55 50 50 4F 52 54 5F 57 45 42 ; OMER_SUPPORT_WEB
00000080h: 53 49 54 45 14 77 77 77 2E 74 69 76 6F 2E 63 6F ; SITE.www.tivo.co
00000090h: 6D 2F 73 75 70 70 6F 72 74 02 00 00 80 77 03 00 ; m/support...w..
000000a0h: 01 02 ; ..


02 XX 80 77 ; seems to indicate a pairing of values
XX ; changes with each entry. seems to have some sort of ordering

2E ; total remaining length of the whole entry
60 ; consistent for all pairings in RuntimeCeDifference_paid.brf and RuntimeCeDifference_unpaid.brf
16 ; length of string, followed by string characters "CUSTOMER_SUPPORT_TITLE"
15 ; length of string, followed by "TiVo Customer Support"

02 00 00 80 77 03 00 01 02 ; filler (as noted by the post below)

note that with 02 XX entries, it seems that you can have 00 before the type value...not sure if it has a meaning

Juppers
02-20-2005, 02:24 PM
00000000h: 0A BF 00 01 04 02 02 80 77 2E 60 16 43 55 53 54 ; ......w.`.CUST
00000010h: 4F 4D 45 52 5F 53 55 50 50 4F 52 54 5F 54 49 54 ; OMER_SUPPORT_TIT
00000020h: 4C 45 15 54 69 56 6F 20 43 75 73 74 6F 6D 65 72 ; LE.TiVo Customer
00000030h: 20 53 75 70 70 6F 72 74 02 01 80 77 28 60 17 43 ; Support..w(`.C
00000040h: 55 53 54 4F 4D 45 52 5F 53 55 50 50 4F 52 54 5F ; USTOMER_SUPPORT_
00000050h: 4E 55 4D 42 45 52 0E 31 2D 38 37 37 2D 33 36 37 ; NUMBER.1-877-367
00000060h: 2D 38 34 38 36 02 03 80 77 2F 60 18 43 55 53 54 ; -8486..w/`.CUST
00000070h: 4F 4D 45 52 5F 53 55 50 50 4F 52 54 5F 57 45 42 ; OMER_SUPPORT_WEB
00000080h: 53 49 54 45 14 77 77 77 2E 74 69 76 6F 2E 63 6F ; SITE.www.tivo.co
00000090h: 6D 2F 73 75 70 70 6F 72 74 02 00 00 80 77 03 00 ; m/support...w..
000000a0h: 01 02 ; ..


02 XX 80 77 ; seems to indicate a pairing of values
YY ; changes with each entry. seems to have some sort of ordering
60 ; consistent for all pairings in RuntimeCeDifference_paid.brf and RuntimeCeDifference_unpaid.brf
16 ; length of string, followed by string characters "CUSTOMER_SUPPORT_TITLE"
15 ; length of string, followed by "TiVo Customer Support"

02 00 00 80 77 03 00 01 02 ; ???


I can answer part of the ??? string. Looks like the brf likes to be a certain size. The 03 00 01 02 at the end is filler. The 03 is how many filler spaces there are. the filler increments by 1.

mrblack51
03-05-2005, 03:40 PM
00000000h: 0A BF 00 01 01 02 00 00 04 80 51 00 09 53 75 63 ; ........Q..Suc
00000010h: 63 65 65 64 65 64 0F 50 65 6E 64 69 6E 67 20 72 ; ceeded.Pending r
00000020h: 65 73 74 61 72 74 17 2A 2A 2A 20 44 65 70 72 65 ; estart.*** Depre
00000030h: 63 61 74 65 64 20 28 30 33 29 20 2A 2A 2A 0B 53 ; cated (03) ***.S
00000040h: 74 61 72 74 69 6E 67 20 55 70 17 2A 2A 2A 20 44 ; tarting Up.*** D
00000050h: 65 70 72 65 63 61 74 65 64 20 28 30 35 29 20 2A ; eprecated (05) *
00000060h: 2A 2A 16 46 61 69 6C 65 64 2E 20 55 6E 6B 6E 6F ; **.Failed. Unkno
00000070h: 77 6E 20 65 72 72 6F 72 2E 1B ; wn error..

it continues...


0A BF 00 01 <-- magic
01 <-- only one record
02 00 00 04 80 51 00

Record 00 type ??
this seems to be used for an array of strings...probably indicated by the 0x04. not sure what the 80 51 00 indicates. i am guessing that 0x51 indicates how many entries there are, and 80 indicates that there is an array?

in any event, members of the array exist in the following format

SS DD DD DD DD ...

where SS is the size in bytes of the entry, followed by the entry itself



09 53 75 63 63 65 65 64 65 64 ; Succeeded <--- (9 bytes)
0F 50 65 6E 64 69 6E 67 20 72 65 73 74 61 72 74 ; Pending restart <--- (15 bytes)
17 2A 2A 2A 20 44 65 70 72 65 63 61 74 65 64 20 28 30 33 29 20 2A 2A 2A ; *** Deprecated (03) *** <--- (23 bytes)

mrblack51
03-05-2005, 03:44 PM
# silicon/lib/silicon/SiDefaultsDocument.brf

0A BF 00 01
1B
02 04 13 02 20 14
02 0E 80 54 01 00
01 80 56 04 01 00 40 02
01 80 55 09 60 02 06 72 65 74 75 72 6E
02 0F 80 54 03 20 01 03
01 80 56 04 01 00 40 04
01 80 55 0A 60 05 07 64 65 66 61 75 6C 74
01 80 56 04 01 00 40 03
01 80 55 0C 60 07 09 61 6C 74 65 72 6E 61 74 65
01 80 56 04 01 00 40 1B
01 80 55 09 60 09 06 64 65 6C 65 74 65
01 80 56 04 01 00 40 1C
01 80 55 07 60 0B 04 70 6C 61 79
02 10 80 54 06 20 04 06 08 0A 0C
02 00 03 FF AF AF AF
02 01 03 FF 00 00 00
02 02 02 00
02 03 02 00
02 05 02 18
02 06 03 FF 00 00 00
02 07 02 02
02 08 02 02
02 09 02 81 16
02 0A 02 83 74
02 0B 02 83 74
02 0C 04 80 49 3C 74 76 6D 6C 3E C2 A0 20 3C 69 6D 67 20 61 6C 69 67 6E 3D 22 74 6F 70 22 20 73 72 63 3D 22 2F 73 6F 6D 61 5F 75 69 63 6F 6D 6D 6F 6E 2F 69 6D 67 2F 61 73 74 65 72 69 73 6B 2E 70 6E 67 22 2F 3E 20 3C 2F 74 76 6D 6C 3E ; <tvml> <img align="top" src="/soma_uicommon/img/asterisk.png"/> </tvml>
02 0D 04 80 4D 3C 74 76 6D 6C 3E 20 3C 69 6D 67 20 61 6C 69 67 6E 3D 22 74 6F 70 22 20 73 72 63 3D 22 2F 73 6F 6D 61 5F 75 69 63 6F 6D 6D 6F 6E 2F 69 6D 67 2F 61 73 74 65 72 69 73 6B 5F 73 6D 61 6C 6C 2E 70 6E 67 22 2F 3E 20 3C 2F 74 76 6D 6C 3E ; <tvml> <img align="top" src="/soma_uicommon/img/asterisk_small.png"/> </tvml>

mrblack51
03-05-2005, 04:06 PM
/media/lib/resources/BitradeDocument.brf



01 80 6C 1A FF 70 03 80 64 85 83 AF 48 03 84 B1 C3 00 84 B1 C3 00 85 50 83 60 03 8F D0 00


01 80 6C
1A <- entry length
FF 70 <-- ??
03 <-- not sure, but it is either 01, 02, 03, 04, 05, or 07
data
D0 00 <-- not sure, but this seems to end each of these type of entries (actually, all end in 83 60 03 8F D0 00)

unlike the 02 type of records, these records dont seem to be enumerated

mrblack51
03-05-2005, 06:27 PM
I can answer part of the ??? string. Looks like the brf likes to be a certain size. The 03 00 01 02 at the end is filler. The 03 is how many filler spaces there are. the filler increments by 1.

are you sure this isnt being used to index the entries? i think some investigation into the interpreting code needs to happen

Beefy
03-15-2005, 04:02 AM
Ah, my favorite kind of puzzle.

Try this:



# silicon/lib/silicon/SiDefaultsDocument.brf

0A BF ; either a magic cookie or the file's length (wasn't clear if this was the whole file)

00 01 ; version? part of cookie? big-endian number of blocks/tables?

(1B: ; number of data elements to expect in following block/table

02 04
; unknown basic data type 13 (is this really variable-length?)
13 (02: 20 14)
02 0E
; unknown aggregate data type 54
80 54 (01: 00)
01
; unknown aggregate data type 56
80 56 (04: 01 00 40 02)
01
; text: r e t u r n
80 55 (09: 60 02 (06: 72 65 74 75 72 6E))
02 0F
; unknown aggregate data type 54
80 54 (03: 20 01 03)
01
; unknown aggregate data type 56
80 56 (04: 01 00 40 04)
01
; text: d e f a u l t
80 55 (0A: 60 05 (07: 64 65 66 61 75 6C 74))
01
; unknown aggregate data type 56
80 56 (04: 01 00 40 03)
01
; text: a l t e r n a t e
80 55 (0C: 60 07 (09: 61 6C 74 65 72 6E 61 74 65))
01
; unknown aggregate data type 56
80 56 (04: 01 00 40 1B)
01
; text: d e l e t e
80 55 (09: 60 09 (06: 64 65 6C 65 74 65))
01
; unknown aggregate data type 56
80 56 (04: 01 00 40 1C)
01
; text: p l a y
80 55 (07: 60 0B (04: 70 6C 61 79))
02 10
; unknown aggregate data type 54
80 54 (06: 20 (04: 06 08 0A 0C))
02 00
; color: light grey
03 FF AF AF AF
02 01
; color: black
03 FF 00 00 00
02 02
; variable-length integer: 0
02 00
02 03
; variable-length integer: 0
02 00
02 05
; variable-length integer: 24
02 18
02 06
; color: black
03 FF 00 00 00
02 07
; variable-length integer: 2
02 02
02 08
; variable-length integer: 2
02 02
02 09
; variable-length integer: 150, I think
02 81 16
02 0A
; variable-length integer: 500, I think
02 83 74
02 0B
; variable-length integer: 500, I think
02 83 74
02 0C
; string: < t v m l > . . . < i m g a l
04 80 (49: 3C 74 76 6D 6C 3E C2 A0 20 3C 69 6D 67 20 61 6C
; i g n = " t o p " s r c = " /
69 67 6E 3D 22 74 6F 70 22 20 73 72 63 3D 22 2F
; s o m a _ u i c o m m o n / i m
73 6F 6D 61 5F 75 69 63 6F 6D 6D 6F 6E 2F 69 6D
; g / a s t e r i s k . p n g " /
67 2F 61 73 74 65 72 69 73 6B 2E 70 6E 67 22 2F
; > < / t v m l >
3E 20 3C 2F 74 76 6D 6C 3E)
02 0D
; string: < t v m l > < i m g a l i g
04 80 (4D: 3C 74 76 6D 6C 3E 20 3C 69 6D 67 20 61 6C 69 67
; n = " t o p " s r c = " / s o
6E 3D 22 74 6F 70 22 20 73 72 63 3D 22 2F 73 6F
; m a _ u i c o m m o n / i m g /
6D 61 5F 75 69 63 6F 6D 6D 6F 6E 2F 69 6D 67 2F
; a s t e r i s k _ s m a l l . p
61 73 74 65 72 69 73 6B 5F 73 6D 61 6C 6C 2E 70
; n g " / > < / t v m l >
6E 67 22 2F 3E 20 3C 2F 74 76 6D 6C 3E)
)


Note that I've rearranged the data and put in (size: data) notation in places. Note also that this is nested in places.

---

Looks like command 02 means something like "Start new class/group with the following ID and append the following data element".

Looks like command 01 means something like "Append the following data element to *current* class/group".

---

Looks like data types can be either a basic type or an aggregate (multi-element, like a structure) type.

Looks like data type 02 is a variable-length integer, but not in the HME format. Looks like it's "int v=0; char c; do { c = getc(fp); v = (v<<7) | (c & 0x7f); } while( !(c & 0x80) );" It's not clear how they represent a negative number. It could just be a different type (01 instead of 02 for example), or they might assume you sign-extend the initial 7 bits. I would assume the latter, encoding -1 with 0x7f.

Looks like data type 03 is a color. Format is AA RR GG BB (or AA BB GG RR).

Looks like data type 04 is a pascal-style string. Format is size: bytes. There's an extra 0x80 before the size... I'm not sure what that's about. Maybe it's something AND a string, or maybe it's a 16-bit length with something funny in the top bit (HME uses 16-bit lengths). It could just be their way of having a fixed size integer that can still be decoded by the variable-length integer code or something weird like that. I dunno. It might be something specific to an actual tvml text type. Could be a type or a mask... ascii vs. unicode, etc.

No clue what data type 13 is. Looks like it's variable-length, but might be a coincidence. Hard to tell with only one of them.

Looks like data type 80 is a resource or class of some sort, something built-in that can be decoded based on the id that follows the 80. For instance, 55 seems to be some sort of text resource, possibly with flags (e.g. bold) or position or ID preceding the string. One of the numbers tends to increase, so it might be vertical position in the menu?

That's enough for one night.

You should try applying this to your other file(s).

mrblack51
03-15-2005, 12:41 PM
it appears that any time there is use of an integer value for things such as record type, number of records, length, etc. the 7 bits per byte method is used.

ie: record type 0x8054 is type 84.

also, lots of the types I have found include text of one sort or another. Anytime i have found the text, its in the standard pascal style string format. Also, most formats are in the form {02 XX or 01} {data type} {length} {data}.

I believe type 74 (0x804A) is used for single bytes.
I type 00 seems to be an array (though there are some aberations to this)
02 04 00 ; array
80 4A ; of type 74
01 ; with 1 entry
01 ; the byte
type 22 (0x16) seems to be used for loading a png file. if the first byte is 00, it loads the png from the brf file directly. if its not 00, then the data is the pascal string representation of the path

Beefy
03-16-2005, 12:26 AM
it appears that any time there is use of an integer value for things such as record type, number of records, length, etc. the 7 bits per byte method is used.

ie: record type 0x8054 is type 84.
It's possible, but I'm not so sure about your specific example. There's no point in the leading 80, because that just results in seven zero bits getting shifted left seven and or'ed with the next 7 bits. It's a no-op waste of space, the very thing vints are meant to deal with. Heck, you can encode 0 by writing a hundred thousand 80's followed by an 00... but you wouldn't. :)

You could argue that the 80 might be the low 7 bits instead of the high 7, but since the settings in that defaults file worked out to nice, round numbers like 500 and 150 (which are probably key delay and repeat speeds in milliseconds), I'm assuming not.

I suspect the leading 80 in that case is something else, most likely the equivalent of the "struct" keyword in C, with the struct type ID following it. The type ID itself is possibly a vint, though. I tend to treat file parsers like token interpreters, which is what they really are. In that context, a special case for a pre-defined aggregate type makes sense.

Still doesn't explain the 80 in front of the pascal string type, though... hm.

mrblack51
03-16-2005, 03:07 AM
It's possible, but I'm not so sure about your specific example. There's no point in the leading 80, because that just results in seven zero bits getting shifted left seven and or'ed with the next 7 bits. It's a no-op waste of space, the very thing vints are meant to deal with. Heck, you can encode 0 by writing a hundred thousand 80's followed by an 00... but you wouldn't. :)

You could argue that the 80 might be the low 7 bits instead of the high 7, but since the settings in that defaults file worked out to nice, round numbers like 500 and 150 (which are probably key delay and repeat speeds in milliseconds), I'm assuming not.

I suspect the leading 80 in that case is something else, most likely the equivalent of the "struct" keyword in C, with the struct type ID following it. The type ID itself is possibly a vint, though. I tend to treat file parsers like token interpreters, which is what they really are. In that context, a special case for a pre-defined aggregate type makes sense.

Still doesn't explain the 80 in front of the pascal string type, though... hm.


at first i thought the same thing, however, check out this:


01 38 ; type 56
80 68 ; 104 bytes
0E 0C F8 80 82 00 80 67 84 7A 0F 82 5F 32 00 60
2C 2F 73 6F 6D 61 5F 75 69 63 6F 6D 6D 6F 6E 2F 69 6D 67 2F 73 63 72 6F 6C 6C 5F 76 65 72 74 69 63 61 6C 5F 73 74 61 72 74 2E 70 6E 67 ; "/soma_uicommon/img/scroll_vertical_start.png"
2A 2F 73 6F 6D 61 5F 75 69 63 6F 6D 6D 6F 6E 2F 69 6D 67 2F 73 63 72 6F 6C 6C 5F 76 65 72 74 69 63 61 6C 5F 65 6E 64 2E 70 6E 67 ; "/soma_uicommon/img/scroll_vertical_end.png"


the data is, last i checked, 104 bytes long. yet, it uses the 80 68 rather than just 68. There could be a threshold of some sort, or some other reason, but this is not the only case where i have seen vints which use a leading 80 even though its not necessary.

Beefy
03-16-2005, 05:37 AM
Okay, my bad, I just figured out why there's a leading 0x80 on those values: a signed 7-bit entity can only hold values from -64..63. If we assume the first 7-bit value is sign-extended, then you need two bytes to represent anything greater than 63 (or less than -64).

Given that assumption, I'd suggest the following untested code to decode a vint, with checking for eof or overflow left as an exercise for the reader:



#define INT_BITS (sizeof(int) * 8)

int getvint( FILE *fp )
{
int c = fgetc( fp );
int v = c << (INT_BITS-7) >> (INT_BITS-7); // sign extend
while( c & 0x80 )
{
c = fgetc( fp );
v = (v << 7) | (c & 0x7f);
}
return v;
}


And obviously your guess about vints for most everything is probably correct.

mrblack51
03-16-2005, 05:03 PM
beefy: check your pm (if you havent already)

AlphaWolf
03-21-2005, 08:00 AM
I built a big ugly pyramid for the world to marvel at, attached below. It can yield many .brf files (and .png files) free for the recursive grepping.

Also, I found a really cool text string in /TuikRes/Holder/010606/soma_uicommon~20030905185748-275/lib/somaalpha/TvFreeTrialMessageDocument.brf:010101:0900062acf:


TiVo Plus feature %s(trial ends tomorrow)(trial ends today)(trial ends in %d days)inside

Have fun, and try not to find yourself stunned by my l33t programming skillz. This script assumes you have dirname and mfs_uberexport present in your path (it doesn't seem to like frommfs for some reason.)

EDIT: This script is obsolete, I am only leaving it here for historical purposes. Scroll down for the good one.

drnull
03-21-2005, 10:03 AM
I built a big ugly pyramid for the world to marvel at, attached below. It can yield many .brf files (and .png files) free for the recursive grepping.


Haha, loved the pyramid!! Ya know, as academically incorrect as that might be, it works just fine.

Btw, though, on 4.0, you can find the .brf's all in one directory. I'm pretty sure it's all of them anyways, come to think of it, I never double checked. Hrm.

Check out TuikRes/SHA1

drnull
03-21-2005, 10:43 AM
Okay, my bad, I just figured out why there's a leading 0x80 on those values: a signed 7-bit entity can only hold values from -64..63. If we assume the first 7-bit value is sign-extended, then you need two bytes to represent anything greater than 63 (or less than -64).

Given that assumption, I'd suggest the following untested code to decode a vint, with checking for eof or overflow left as an exercise for the reader:



#define INT_BITS (sizeof(int) * 8)

int getvint( FILE *fp )
{
int c = fgetc( fp );
int v = c << (INT_BITS-7) >> (INT_BITS-7); // sign extend
while( c & 0x80 )
{
c = fgetc( fp );
v = (v << 7) | (c & 0x7f);
}
return v;
}


And obviously your guess about vints for most everything is probably correct.

Actually, looking at tivoapp and trying to guess how vints are handled by how tivoapp handles it, you'll see the following:

VMA Address in 4.0 tivoapp:
0x00f25a20: 0abf0001 checking, so we are handling .brf files at this point.... find this location in any other source by looking for lui ??, 0xabf followed by ori ??, ??, 0x01
0x00f25a84: call to get a vint

get_vint function:
0x00f24e34: looking through this function, you'll see that for the first character:
msb (I call it bit 7) is the continuation bit (read the next char for more of this int)
bit 6 is the sign bit.

After that, we use 7 bits of each character for adding to the vint, until bit 7 is 0, then we're done. Oh and at the end, if bit6 of the original character was set, then we negate the resulting value.

It's entirely possible I've mis-read the mips, but that's what I got out of it. So in my book, a vint of 0x8054 is 0x54. It's expanded to two bytes because bit 6 would be set in 0x54, causing it to be interpreted as -0x54, whatever that is. (lazy) ok, 0xac or something like that.

A few other notes from what I've found in looking at the b[a]rfs. (I'm really not enjoying this file format, but I'm addicted to figuring it out now)

Like you've pointed out, it's


0x0abf0001
vint: num_records
i=0; i<num_records; i++ {
vint: rec_type (1 or 2, anything else throws an error in tivoapp, so we're good here.)
if (rec_type == 2) {
vint: entry# (I'm pretty sure this is entry number. Seems the entries don't have to be in order in the brf)
}
vint: entry_type;
}

Of course, entry_type breaks into a case statement to handle the different entry types. Here's what I kinda understand so far, and take this with a grain of salt. These are kinda WORKSFORME_FOR_MOST_FILES definitions. Also, rec_type 2 seems to be fairly simple, but rec_type 1 has me quite confused. Is it just a aggregate type like beefy mentioned or is there somethign else to it? Why waste that byte to just say "here comes another record"? Who knows. I lost the trail down into tivoapp as I think it started calling polymorphic class methods or something that required address lookup at runtype. Basically, the standard gp offset address weren't being used, and I don't know how to track down function calls after that point.

edit: btw, all numbers here are in hex



entry_type_0 { // array
vint: sub_type;
vint: array_size;
entry[array_size] sub_entries;
}

entry_type_1 { // just a vint?
vint value;
}

entry_type_2 { // just another vint?
vint value;
}

entry_type_3 { // color: thanks beefy
char value;
char[3] rgb_or_something_like_that;
}

entry_type_4 { // String (pascal style, as already mentioned)
vint length;
char[length] string;
}

entry_type_13 { // aggregate of some type
vint length;
char[length] stuff; // other data types are in here, just haven't got around to figuring out how to decode this block yet
}

entry_type_16 { // Resource
vint length;
if (length > 0) {
char[length] path;
} else {
vint size;
char[size] embedded_png;
}
}



fwiw

drnull
03-21-2005, 02:19 PM
Check out TuikRes/SHA1

Alternate script for dumping brf's:

AlphaWolf
03-21-2005, 02:40 PM
Haha, loved the pyramid!! Ya know, as academically incorrect as that might be, it works just fine.

Btw, though, on 4.0, you can find the .brf's all in one directory. I'm pretty sure it's all of them anyways, come to think of it, I never double checked. Hrm.

Check out TuikRes/SHA1

I was just about to post the changes for that but then I noticed that it doesn't



bash-2.02# ./mfsres2unix.tcl | wc -l
821
bash-2.02# ./mfsres2unix2.tcl | wc -l
553


(note if I add a regexp for .brf files, the count reduces by about half from 400 something to 200 something.)

Bummer though, that would have been a much easier approach. That makes me wonder if there are even more in the /TuikRes/Group tydir.

EDIT: Something else I am noticing, for some reason or another the tridge libraries are unable to mfs_export a few of these files. Just a few of them are ending up with zero length output files. This is happening in both 6.2 and 5.2 on completely different disk images. Odd...

EDIT2: Jamie has identified the cause of the problem and will fix it in mfs_uberexport later tonight.

AlphaWolf
03-22-2005, 03:14 AM
Heres a clean mfsres2unix.tcl script that was based both on my code and drnull's code. It does recursive lookups the right way so the depth is infinite and the pyramid is no more. Add a -b parameter to get only .brf files.

EDIT: This script is obsoleted by the one in the post below.

AlphaWolf
03-27-2005, 06:55 PM
Heres a modification to filter out dupes and to also get the fsid from the TuikResource subobject (in case you ever modify any of the .brf files; if you do then the first level FSID will be invalid.)

TivoWare
08-10-2005, 01:15 AM
I'm still not understanding the vint and the best way to handle it in tcl.I am doing it, but not how I think it should be done.

0x80 0x47 = 0x47 (71)
0x81 0x68 = 0xE8 (232)
0x81 0x04 = 0x84 (132)
0x81 0x0A = 0x8A (138)
0x82 0x4A = 0x01 0x4A (330)
0x83 0x38 = 0x01 0xB8 (440)
0x84 0x0E = 0x02 0x0E (526) (Yes there is one this big)

I'm just handling it by case
0x80 Use next number
0x81 Add 128 to the next number
0x82 Add 256 to the next number
0x83 Add 384 to the next number
0x84 Add 512 to the next number

What would be the correct way of shifting the bits?
--------------------------

Edit: (Many hours later)

I seem to have it working in tcl based on what Beefy did..
# Thanks Beefy!
proc GetVint {uFileData uIndex} {
upvar $uFileData FileData
upvar $uIndex Index
set Buffer 0
scan [string index $FileData $Index] %c Buffer
incr Index
set Int [expr $Buffer & 0x7F]
while {$Buffer & 0x80} {
puts "[format "%02X" $Buffer] [format "%02X" $Int]"
set Buffer 0
scan [string index $FileData $Index] %c Buffer
incr Index
set Int [expr ($Int << 7) | ($Buffer & 0x7f)]
puts " [format "%02X" $Buffer] [format "%02X" $Int]"
}
return $Int
}

TivoWare
08-10-2005, 05:48 PM
I figured the best way to test all this was to make a parser. So far I only have it handling the text data types. Right now is can parse 53 of 211 brf file on my system.

AdvisoryDocument.brf, AlternateAudioStrings.brf, AtscStringDocument.brf, AutoRecordShowcaseDocument.brf, CallStatusDocument.brf, ConflictDocument.brf, ConflictGroupDocument.brf, ConflictPresentationDocument.brf, ConstantsDocument.brf, DemoModeDocument.brf, DialTimeDocument.brf, DynamicLineupDocument.brf, FeaturesDocument.brf, FindActionsDocument.brf, GenreMapperDocument.brf, GuideColorsDocument.brf, GuideUIDocument.brf, InternetRecordingDocument.brf, LayoutConstDocument.brf, LowPgdMessagesDocument.brf, ManufacturerDocument.brf, MpaaRatingDocument.brf, NetworkMessage.brf, OemLayoutConstDocument.brf, PlatformFeaturesDocument.brf, PlatformStringDocument.brf, ProgramSourceUtilDocument.brf, PvrDateDocument.brf, QAIdentifier.brf, RecordOptionsDocument.brf, SatelliteStringDocument.brf, ServiceMessageDocument.brf, SetupCableConnectionDocument.brf, SetupDialPrefixDocument.brf, SetupRemoteDocument.brf, SetupResetDocument.brf, SetupStringDocument.brf, ShowingBitsDocument.brf, SiDateFormatStringDocument.brf, SomaCommonImagesDocument.brf, SoundDocument.brf, StatesDocument.brf, SwUpdateFailureDocument.brf, TClientDocument.brf, TuneDialogDocument.brf, TvProgressDefaultFormatterDocument.brf, TvRatingDocument.brf, TvSchedulerResultFormatDocument.brf, UIStringDocument.brf, WatchLiveDocument.brf, WatchRecordingDocument.brf, XmlParserDocument.brf

Here it is:

mrblack51
08-11-2005, 01:58 AM
here is the beginnings of a BRF parser. i dont remember if this is the newest version or not, and its certainly not the cleanest or most well tested code. however, it is a decent start. dont complain if it doesnt work for you. some testing has been done and stuff. feel free to post improvements and such

if you dont know what to do with this file, you dont belong in this thread

MuscleNerd
11-05-2006, 04:43 PM
Back in the day, I mentioned in various places that you can serve these brf and other TUIK resource files from a web server -- with the appropriate environment variable setting, tivoapp will fetch from a URL instead of from MFS.

Today I noticed that my posting of this method on alt.org inaccurately named the environment variable (it's TV_HTML_SERVER):

http://alt.org/forum/index.php?t=msg&th=119&start=0&rid=19#msg_num_1

woracan
10-07-2009, 02:55 PM
Has anyone updated mrblack51's BRF parser so it can handle brf files from the latest TiVo software versions?