2N/A * GRUB -- GRand Unified Bootloader 2N/A * Copyright (C) 2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. 2N/A * GRUB is free software: you can redistribute it and/or modify 2N/A * it under the terms of the GNU General Public License as published by 2N/A * the Free Software Foundation, either version 3 of the License, or 2N/A * (at your option) any later version. 2N/A * GRUB is distributed in the hope that it will be useful, 2N/A * but WITHOUT ANY WARRANTY; without even the implied warranty of 2N/A * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2N/A * GNU General Public License for more details. 2N/A * You should have received a copy of the GNU General Public License 2N/A/* HFS is documented at 2N/A/* The two supported filesystems a record can have. */ 2N/A/* Catalog node ID (CNID). */ 2N/A/* A node descriptor. This is the header of every node. */ 2N/A/* The head of the B*-Tree. */ 2N/A /* The number of the first node. */ 2N/A/* The state of a mounted HFS filesystem. */ 2N/A/* The key as used on disk in a catalog tree. This is used to lookup 2N/A /* Filename length. */ 2N/A/* The key as used on disk in a extent overflow tree. Using this key 2N/A the extents can be looked up using a fileid and logical start block 2N/A /* The kind of fork. This is used to store meta information like 2N/A icons, attributes, etc. We will only use the datafork, which is 2N/A/* A directory record. This is used to find out the directory ID. */ 2N/A /* For a directory, type == 1. */ 2N/A/* Information about a file. */ 2N/A /* For a file, type == 2. */ 2N/A /* The first 3 extents of the file. The other extents can be found 2N/A in the extent overflow file. */ 2N/A/* A record descriptor, both key and data, used to pass to call back 2N/A/* Find block BLOCK of the file FILE in the mounted UFS filesystem 2N/A DATA. The first 3 extents are described by DAT. If cache is set, 2N/A using caching to improve non-random reads. */ 2N/A /* Try all 3 extents. */ 2N/A for (i = 0; i <
3; i++)
2N/A /* Check if the block is stored in this extent. */ 2N/A /* If the cache is enabled, store the current position 2N/A /* Try the next extent. */ 2N/A /* Lookup the block in the extent overflow file. */ 2N/A/* Read LEN bytes from the file described by DATA starting with byte 2N/A POS. Return the amount of read bytes in READ. */ 2N/A /* The last portion is exactly EXT2_BLOCK_SIZE (data). */ 2N/A /* If the block number is 0 this block is not stored on disk but 2N/A is zero filled instead. */ 2N/A/* Mount the filesystem on the disk DISK. */ 2N/A /* Read the superblock. */ 2N/A /* Check if this is a HFS filesystem. */ 2N/A /* Check if this is an embedded HFS+ filesystem. */ 2N/A /* Lookup the root node of the extent overflow tree. */ 2N/A /* Lookup the root node of the catalog tree. */ 2N/A /* Lookup the root directory node in the catalog tree using the 2N/A/* Compare the K1 and K2 catalog file keys using HFS character ordering. */ 2N/A /* Taken from hfsutils 3.2.6 and converted to a readable form */ 2N/A [
' '] =
32, [
0xCA] =
32,
2N/A [
'A'] =
71, [
'a'] =
71,
2N/A [
0x88] =
72, [
0xCB] =
72,
2N/A [
0x80] =
73, [
0x8A] =
73,
2N/A [
0x8B] =
74, [
0xCC] =
74,
2N/A [
0x81] =
75, [
0x8C] =
75,
2N/A [
0xAE] =
76, [
0xBE] =
76,
2N/A [
'B'] =
81, [
'b'] =
81,
2N/A [
'C'] =
82, [
'c'] =
82,
2N/A [
0x82] =
83, [
0x8D] =
83,
2N/A [
'D'] =
84, [
'd'] =
84,
2N/A [
'E'] =
85, [
'e'] =
85,
2N/A [
0x83] =
86, [
0x8E] =
86,
2N/A [
'F'] =
90, [
'f'] =
90,
2N/A [
'G'] =
91, [
'g'] =
91,
2N/A [
'H'] =
92, [
'h'] =
92,
2N/A [
'I'] =
93, [
'i'] =
93,
2N/A [
'J'] =
98, [
'j'] =
98,
2N/A [
'K'] =
99, [
'k'] =
99,
2N/A [
'L'] =
100, [
'l'] =
100,
2N/A [
'M'] =
101, [
'm'] =
101,
2N/A [
'N'] =
102, [
'n'] =
102,
2N/A [
0x84] =
103, [
0x96] =
103,
2N/A [
'O'] =
104, [
'o'] =
104,
2N/A [
0x85] =
105, [
0x9A] =
105,
2N/A [
0x9B] =
106, [
0xCD] =
106,
2N/A [
0xAF] =
107, [
0xBF] =
107,
2N/A [
0xCE] =
108, [
0xCF] =
108,
2N/A [
'P'] =
113, [
'p'] =
113,
2N/A [
'Q'] =
114, [
'q'] =
114,
2N/A [
'R'] =
115, [
'r'] =
115,
2N/A [
'S'] =
116, [
's'] =
116,
2N/A [
'T'] =
118, [
't'] =
118,
2N/A [
'U'] =
119, [
'u'] =
119,
2N/A [
0x86] =
120, [
0x9F] =
120,
2N/A [
'V'] =
124, [
'v'] =
124,
2N/A [
'W'] =
125, [
'w'] =
125,
2N/A [
'X'] =
126, [
'x'] =
126,
2N/A [
'Y'] =
127, [
'y'] =
127,
2N/A [
'Z'] =
129, [
'z'] =
129,
2N/A /* Shorter strings precede long ones. */ 2N/A/* Compare the K1 and K2 extent overflow file keys. */ 2N/A/* Iterate the records in the node with index IDX in the mounted HFS 2N/A filesystem DATA. This node holds data of the type TYPE (0 = 2N/A catalog node, 1 = extent overflow node). If this is set, continue 2N/A iterating to the next node. For every records, call NODE_HOOK. */ 2N/A /* Read the node into memory. */ 2N/A /* Iterate over all records in this node. */ 2N/A/* Lookup a record in the mounted filesystem DATA using the key KEY. 2N/A The index of the node on top of the tree is IDX. The tree is of 2N/A the type TYPE (0 = catalog node, 1 = extent overflow node). Return 2N/A the data in DATAR with a maximum length of DATALEN. */ 2N/A /* If the key is smaller or equal to the current node, mark the 2N/A entry. In case of a non-leaf mode it will be used to lookup 2N/A the rest of the tree. */ 2N/A else /* The key can not be found in the tree. */ 2N/A /* Check if this node is a leaf node. */ 2N/A/* Iterate over the directory with the id DIR. The tree is searched 2N/A starting with the node ROOT_IDX. For every entry in this directory 2N/A /* The lowest key possible with DIR as root directory. */ 2N/A /* An entry was found. */ 2N/A /* Stop when the entries do not match anymore. */ 2N/A /* If there was a matching record in this leaf node, continue the 2N/A iteration until the last record was found. */ 2N/A /* 80 */ "\xc3\x84",
2N/A /* 81 */ "\xc3\x85",
2N/A /* 82 */ "\xc3\x87",
2N/A /* 83 */ "\xc3\x89",
2N/A /* 84 */ "\xc3\x91",
2N/A /* 85 */ "\xc3\x96",
2N/A /* 86 */ "\xc3\x9c",
2N/A /* 87 */ "\xc3\xa1",
2N/A /* 88 */ "\xc3\xa0",
2N/A /* 89 */ "\xc3\xa2",
2N/A /* 8A */ "\xc3\xa4",
2N/A /* 8B */ "\xc3\xa3",
2N/A /* 8C */ "\xc3\xa5",
2N/A /* 8D */ "\xc3\xa7",
2N/A /* 8E */ "\xc3\xa9",
2N/A /* 8F */ "\xc3\xa8",
2N/A /* 90 */ "\xc3\xaa",
2N/A /* 91 */ "\xc3\xab",
2N/A /* 92 */ "\xc3\xad",
2N/A /* 93 */ "\xc3\xac",
2N/A /* 94 */ "\xc3\xae",
2N/A /* 95 */ "\xc3\xaf",
2N/A /* 96 */ "\xc3\xb1",
2N/A /* 97 */ "\xc3\xb3",
2N/A /* 98 */ "\xc3\xb2",
2N/A /* 99 */ "\xc3\xb4",
2N/A /* 9A */ "\xc3\xb6",
2N/A /* 9B */ "\xc3\xb5",
2N/A /* 9C */ "\xc3\xba",
2N/A /* 9D */ "\xc3\xb9",
2N/A /* 9E */ "\xc3\xbb",
2N/A /* 9F */ "\xc3\xbc",
2N/A /* A0 */ "\xe2\x80\xa0",
2N/A /* A1 */ "\xc2\xb0",
2N/A /* A2 */ "\xc2\xa2",
2N/A /* A3 */ "\xc2\xa3",
2N/A /* A4 */ "\xc2\xa7",
2N/A /* A5 */ "\xe2\x80\xa2",
2N/A /* A6 */ "\xc2\xb6",
2N/A /* A7 */ "\xc3\x9f",
2N/A /* A8 */ "\xc2\xae",
2N/A /* A9 */ "\xc2\xa9",
2N/A /* AA */ "\xe2\x84\xa2",
2N/A /* AB */ "\xc2\xb4",
2N/A /* AC */ "\xc2\xa8",
2N/A /* AD */ "\xe2\x89\xa0",
2N/A /* AE */ "\xc3\x86",
2N/A /* AF */ "\xc3\x98",
2N/A /* B0 */ "\xe2\x88\x9e",
2N/A /* B1 */ "\xc2\xb1",
2N/A /* B2 */ "\xe2\x89\xa4",
2N/A /* B3 */ "\xe2\x89\xa5",
2N/A /* B4 */ "\xc2\xa5",
2N/A /* B5 */ "\xc2\xb5",
2N/A /* B6 */ "\xe2\x88\x82",
2N/A /* B7 */ "\xe2\x88\x91",
2N/A /* B8 */ "\xe2\x88\x8f",
2N/A /* B9 */ "\xcf\x80",
2N/A /* BA */ "\xe2\x88\xab",
2N/A /* BB */ "\xc2\xaa",
2N/A /* BC */ "\xc2\xba",
2N/A /* BD */ "\xce\xa9",
2N/A /* BE */ "\xc3\xa6",
2N/A /* BF */ "\xc3\xb8",
2N/A /* C0 */ "\xc2\xbf",
2N/A /* C1 */ "\xc2\xa1",
2N/A /* C2 */ "\xc2\xac",
2N/A /* C3 */ "\xe2\x88\x9a",
2N/A /* C4 */ "\xc6\x92",
2N/A /* C5 */ "\xe2\x89\x88",
2N/A /* C6 */ "\xe2\x88\x86",
2N/A /* C7 */ "\xc2\xab",
2N/A /* C8 */ "\xc2\xbb",
2N/A /* C9 */ "\xe2\x80\xa6",
2N/A /* CA */ "\xc2\xa0",
2N/A /* CB */ "\xc3\x80",
2N/A /* CC */ "\xc3\x83",
2N/A /* CD */ "\xc3\x95",
2N/A /* CE */ "\xc5\x92",
2N/A /* CF */ "\xc5\x93",
2N/A /* D0 */ "\xe2\x80\x93",
2N/A /* D1 */ "\xe2\x80\x94",
2N/A /* D2 */ "\xe2\x80\x9c",
2N/A /* D3 */ "\xe2\x80\x9d",
2N/A /* D4 */ "\xe2\x80\x98",
2N/A /* D5 */ "\xe2\x80\x99",
2N/A /* D6 */ "\xc3\xb7",
2N/A /* D7 */ "\xe2\x97\x8a",
2N/A /* D8 */ "\xc3\xbf",
2N/A /* D9 */ "\xc5\xb8",
2N/A /* DA */ "\xe2\x81\x84",
2N/A /* DB */ "\xe2\x82\xac",
2N/A /* DC */ "\xe2\x80\xb9",
2N/A /* DD */ "\xe2\x80\xba",
2N/A /* DE */ "\xef\xac\x81",
2N/A /* DF */ "\xef\xac\x82",
2N/A /* E0 */ "\xe2\x80\xa1",
2N/A /* E1 */ "\xc2\xb7",
2N/A /* E2 */ "\xe2\x80\x9a",
2N/A /* E3 */ "\xe2\x80\x9e",
2N/A /* E4 */ "\xe2\x80\xb0",
2N/A /* E5 */ "\xc3\x82",
2N/A /* E6 */ "\xc3\x8a",
2N/A /* E7 */ "\xc3\x81",
2N/A /* E8 */ "\xc3\x8b",
2N/A /* E9 */ "\xc3\x88",
2N/A /* EA */ "\xc3\x8d",
2N/A /* EB */ "\xc3\x8e",
2N/A /* EC */ "\xc3\x8f",
2N/A /* ED */ "\xc3\x8c",
2N/A /* EE */ "\xc3\x93",
2N/A /* EF */ "\xc3\x94",
2N/A /* F0 */ "\xef\xa3\xbf",
2N/A /* F1 */ "\xc3\x92",
2N/A /* F2 */ "\xc3\x9a",
2N/A /* F3 */ "\xc3\x9b",
2N/A /* F4 */ "\xc3\x99",
2N/A /* F5 */ "\xc4\xb1",
2N/A /* F6 */ "\xcb\x86",
2N/A /* F7 */ "\xcb\x9c",
2N/A /* F8 */ "\xc2\xaf",
2N/A /* F9 */ "\xcb\x98",
2N/A /* FA */ "\xcb\x99",
2N/A /* FB */ "\xcb\x9a",
2N/A /* FC */ "\xc2\xb8",
2N/A /* FD */ "\xcb\x9d",
2N/A /* FE */ "\xcb\x9b",
2N/A /* FF */ "\xcb\x87",
2N/A /* Translate '/' to ':' as per HFS spec. */ 2N/A /* Translate ':' to '/' as per HFS spec. */ 2N/A for (i = 0; i <
0x80; i++)
2N/A /* Too long or not encodable. */ 2N/A/* Find a file or directory with the pathname PATH in the filesystem 2N/A DATA. Return the file record in RETDATA when it is non-zero. 2N/A Return the directory number in RETINODE when it is non-zero. */ 2N/A /* Isolate a part of the path. */ 2N/A /* Lookup this node. */ 2N/A /* First the directory ID for the directory. */ 2N/A/* Open a file named NAME and initialize FILE. */ 2N/A (
unsigned long long)