找到一個別人分析的PBL庫文件的結構說明 (Fixed Version)
+--------------------------------------------------------------+ I PBL File Format 2003 - 2009 I +--------------------------------------------------------------+ Dear PB Fans out there, these are the results of the analysis I did, written down as a short ASCII text description (valid thru PB5-11.5). With this knowledge you can write your own LibraryDirectory or Export Function for PowerBuilder PBL/PBD/DLL/EXE files. Think about the possibility; including files via PBR assignment and extracting them during runtime. That is a nice gimmick. Most of the terms used are the results and presumptions of my analysis. Thanks to: - Kevin Cai for Bytes 17-18 of the Node-Block - Jeremy Lakeman for Bytes 19-20, 23-24 of the Node-Block Regards Arnd Schmidt Aug 2009 arnd.schmidt@dwox.com +--------------------------------------------------------------+ I PBL File Format I +--------------------------------------------------------------+ Rules and facts: 1.) A PBL is always made out of blocks of 512, except the Node Block (NOD*), that has a size of 6 blocks, meaning 3072 Bytes. 2.) There is always one Header (HDR*) block, followed by a free/used blocks bitmap (FRE*). Then follows the first 'NOD*' block . Theoretically this first 'NOD*' block might(!) point to a parent node, but I have never seen that. 3.) Object Data (also SCC Informations) are always stored in single forward linked/chained of 'DAT*'-Blocks. The information about the offset and the length is stored in the Header (HDR*). 4.) A PBD is a PBL. 5.) DLL and EXE files have a 'TRL*' at the end of the file. This is pointing to the one and only 'HDR*'-Block. Attention: For signed DLLs (like PowerBuilder's signed DLLs in Version 11.5) you have to recalculate the offset to the 'TRL*' Block. +--------------------------------------------------------------+ I Library Header Block (512 Bytes) I +-----------+------------+-------------------------------------+ I Pos.(HEX) I Type I Information I +-----------+------------+-------------------------------------+ I 0 - 3 I Char(4) I 'HDR*' I I 4 - 11 I String I 'PowerBuilder' + 0x00 + 0x00 I I 12 - 15 I Char(4) I PBL Format Version? (0400/0500/0600)I I 16 - 19 I Long I Creation/Optimization Datetime I I 1c - ff I String I Library Comment I I 11c - 11f I Long I Offset of first SCC data block I I 120 - 123 I Long I Size (Net size of SCC data) I +-----------+------------+-------------------------------------+ +--------------------------------------------------------------+ I Library Header Block - Unicode (1024 Bytes) I +-----------+------------+-------------------------------------+ I Pos.(HEX) I Type I Information I +-----------+------------+-------------------------------------+ I 0 - 3 I Char(4) I 'HDR*' I I 4 - 1f I StringW I 'PowerBuilder' + 0x00 + 0x00 I I 20 - 27 I CharW(4) I PBL Format Version? (0400/0500/0600)I I 28 - 2b I Long I Creation/Optimization Datetime I I 2c - ff I StringW I Library Comment I I 22e - 231 I Long I Offset of first SCC data block I I 232 - 235 I Long I Size (Net size of SCC data) I +-----------+------------+-------------------------------------+ +--------------------------------------------------------------+ I Bitmap Block (512 Bytes) I +-----------+------------+-------------------------------------+ I Pos.(HEX) I Type I Information I +-----------+------------+-------------------------------------+ I 0 - 3 I Char(4) I 'FRE*' I I 4 - 7 I Long I Offset of next block or 0 I I 8 - 1ff I Bit(504*8) I Bitmap, each Bit represents a block I +-----------+------------+-------------------------------------+ (512 - 8) * 8 = 4032 Blocks are referenced +--------------------------------------------------------------+ I Node Block (3072 Bytes) I +-----------+------------+-------------------------------------+ I Pos.(HEX) I Type I Information I +-----------+------------+-------------------------------------+ I 0 - 3 I Char(4) I 'NOD*' I I 4 - 7 I Long I Offset of next (left ) block or 0 I I 8 - b I Long I Offset of parent block or 0 I I c - f I Long I Offset of next (right) block or 0 I I 10 - 11 I Integer I Space left in block, inital = 3040 I I 12 - 13 I Integer I Position of alphabetically I I I I last Objectname in this block I I 14 - 15 I Integer I Count of entries in that node I I 16 - 17 I Integer I Position of alphabetically I I I I first Objectname in this block I I 20 - bff I Chunks I 'ENT*'-Chunks I +-----------+------------+-------------------------------------+ +--------------------------------------------------------------+ I Entry Chunk (Variable Length) I +-----------+------------+-------------------------------------+ I Pos.(HEX) I Type I Information I +-----------+------------+-------------------------------------+ I 0 - 3 I Char(4) I 'ENT*' I I 4 - 7 I Char(4) I PBL version? (0400/0500/0600) I I 8 - b I Long I Offset of first data block I I c - f I Long I Objectsize (Net size of data) I I 10 - 13 I Long I Unix datetime I I 14 - 15 I Integer I Length of comment I I 16 - 17 I Integer I Length of objectname(include '/0') I I 18 - ff I String I Objectname I +-----------+------------+-------------------------------------+ +--------------------------------------------------------------+ I Entry Chunk - Unicode (Variable Length) I +-----------+------------+-------------------------------------+ I Pos.(HEX) I Type I Information I +-----------+------------+-------------------------------------+ I 0 - 3 I Char(4) I 'ENT*' I I 4 - b I CharW(4) I PBL version? (0400/0500/0600) I I c - f I Long I Offset of first data block I I 10 - 13 I Long I Objectsize (Net size of data) I I 14 - 17 I Long I Unix datetime I I 18 - 19 I Integer I Length of comment I I 1a - 1b I Integer I Length of objectname I I 1c - ff I StringW I Objectname I +-----------+------------+-------------------------------------+ +--------------------------------------------------------------+ I Data Block (512 Bytes) I +-----------+------------+-------------------------------------+ I Pos.(HEX) I Type I Information I +-----------+------------+-------------------------------------+ I 0 - 3 I Char(4) I 'DAT*' I I 4 - 7 I Long I Offset of next data block or 0 I I 8 - 9 I Integer I Length of data in block I I 11 - XXX I Blob{} I Data (maximum Length is 502) I +-----------+------------+-------------------------------------+ +--------------------------------------------------------------+ I Trailer Block (in DLL/EXE) always last block (512 Bytes) I +-----------+------------+-------------------------------------+ I Pos.(HEX) I Type I Information I +-----------+------------+-------------------------------------+ I 0 - 3 I Char(4) I 'TRL*' I I 4 - 7 I Long I Offset of Library Header ('HDR*') I +-----------+------------+-------------------------------------+ +--------------------------------------------------------------+ I SCC DATA I I Structure of status information chunks I I in DAT*-blocks (Variable Length) I +---------+----------------------------------------------------I I Type I Information I +---------+----------------------------------------------------I I String I Libraryname (the opposite!) I I String I Objectname I I String I Developername I I Char(1) I Flag I +---------+----------------------------------------------------I +--------------------------------------------------------------+ I PB6/7 Status Flags I +------+------+------------------------------------------------+ I Icon I Flag I Meaning I +------+------+------------------------------------------------+ I I r I Object is registered I I I d I Object is Checked Out (locked) I I I s I Object (Working Copy) to be checked in I I I u I Unknown?! After an Error occurred. I I I I (Checked out by user I I I I Could be set to 'r' with an Hex-Editor.) I +------+------+------------------------------------------------+ +--------------------------------------------------------------+ I SCC DATA chunk I I In newer PB Versions the DAT*-blocks content starts with the I I ansi-encoded String 'SCC*'. I I Objectname and Version Informations are stored as I I 0-Byte (Word) separated strings. I +----------+---------------------------------------------------I I Type I Information I +----------+------------+--------------------------------------+ I 0 - 3 I Char(4) I 'SCC*' I I 5 - xxx I Blob I Objectname (string) followed by I I I I Null-Byte 0x00 (Word in Unicode) I I I I indicating the string end I I I I Version (String) followed by I I I I Null-Byte 0x00 (Word in Unicode) I I I I indicating the string end I I I I Next Objectname und Versioninfo I I I I repeatedly until the end I +----------+------------+--------------------------------------+ DateTimes are stored in Long format in Unix representation. Timezone is always GMT (+/- 0:00), so the datetime has to be converted to LocalDateTime via LocalTimeZone conversation. In the compiled object data blocks, there are at least 2 more datetimes, starting at byte 23 and the other one at 27! Looks like these are the modification and regeneration date...