File: hfsplus.h

package info (click to toggle)
clamav 0.98.7+dfsg-0+deb6u2
  • links: PTS, VCS
  • area: main
  • in suites: squeeze-lts
  • size: 60,204 kB
  • ctags: 49,129
  • sloc: cpp: 267,090; ansic: 152,211; sh: 35,196; python: 2,630; makefile: 2,220; perl: 1,690; pascal: 1,218; lisp: 184; csh: 117; xml: 38; asm: 32; exp: 4
file content (291 lines) | stat: -rw-r--r-- 7,873 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
/*
 *  Copyright (C) 2013 Sourcefire, Inc.
 *
 *  Authors: David Raynor <draynor@sourcefire.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *  MA 02110-1301, USA.
 */

#ifndef __HFSPLUS_H
#define __HFSPLUS_H

#if HAVE_CONFIG_H
#include "clamav-config.h"
#endif

#include "cltypes.h"

/* Structures based on Apple Technote 1150 */

/* volume attributes that may affect reading */
enum hfsVolAttributes {
    /* hfsVolumeHardwareLockBit       =  7, */
    hfsVolumeUnmountedBit          =  8,
    hfsVolumeSparedBlocksBit       =  9,
    /* hfsVolumeNoCacheRequiredBit    = 10, */
    hfsBootVolumeInconsistentBit   = 11,
    hfsCatalogNodeIDsReusedBit     = 12,
    hfsVolumeJournaledBit          = 13
    /* hfsVolumeSoftwareLockBit       = 15 */
};

/* reserved CatalogNodeID values */
enum {
    hfsRootParentID            = 1,
    hfsRootFolderID            = 2,
    hfsExtentsFileID           = 3,
    hfsCatalogFileID           = 4,
    hfsBadBlockFileID          = 5,
    hfsAllocationFileID        = 6,
    hfsStartupFileID           = 7,
    hfsAttributesFileID        = 8,
    hfsRepairCatalogFileID     = 14,
    hfsBogusExtentFileID       = 15,
    hfsFirstUserCatalogNodeID  = 16
};

#ifndef HAVE_ATTRIB_PACKED
#define __attribute__(x)
#endif

#ifdef HAVE_PRAGMA_PACK
#pragma pack(2)
#endif

#ifdef HAVE_PRAGMA_PACK_HPPA
#pragma pack 2
#endif

/* Basic HFS+ structures */
struct hfsUniStr255 {
    uint16_t	length;
    uint16_t	unicode[255];
} __attribute__((__packed__));
typedef struct hfsUniStr255 hfsUniStr255;

struct hfsPlusExtentDescriptor {
    uint32_t	startBlock;
    uint32_t	blockCount;
} __attribute__((__packed__));
typedef struct hfsPlusExtentDescriptor hfsPlusExtentDescriptor;
typedef hfsPlusExtentDescriptor hfsPlusExtentRecord[8];

struct hfsPlusForkData {
    uint64_t	logicalSize;
    uint32_t	clumpSize;
    uint32_t	totalBlocks;
    hfsPlusExtentRecord	extents;
} __attribute__((__packed__));
typedef struct hfsPlusForkData hfsPlusForkData;

/* HFS+ Volume Header (512 bytes) */
struct hfsPlusVolumeHeader {
    uint16_t	signature; /* H+ for HFS+, HX for HFSX */
    uint16_t	version;
    uint32_t	attributes;
    uint32_t	lastMountedVersion;
    uint32_t	journalInfoBlock;

    uint32_t	createDate;
    uint32_t	modifyDate;
    uint32_t	backupDate;
    uint32_t	checkedDate;

    uint32_t	fileCount;
    uint32_t	folderCount;

    uint32_t	blockSize;
    uint32_t	totalBlocks;
    uint32_t	freeBlocks;

    uint32_t	nextAllocation;
    uint32_t	rsrcClumpSize;
    uint32_t	dataClumpSize;
    uint32_t	nextCatalogID; /* Next unused catalog ID */

    uint32_t	writeCount;
    uint64_t	encodingsBitmap;

    uint32_t	finderInfo[8]; /* for Finder */

    hfsPlusForkData	allocationFile;
    hfsPlusForkData	extentsFile;
    hfsPlusForkData	catalogFile;
    hfsPlusForkData	attributesFile;
    hfsPlusForkData	startupFile;
} __attribute__((__packed__));
typedef struct hfsPlusVolumeHeader hfsPlusVolumeHeader;

#define HFS_FILETREE_ALLOCATION 1 
#define HFS_FILETREE_EXTENTS 2
#define HFS_FILETREE_CATALOG 3
#define HFS_FILETREE_ATTRIBUTES 4
#define HFS_FILETREE_STARTUP 5

/* BSD object info (16 bytes) */
/* important parts for scanning are fileMode and the special part */
struct hfsPlusBSDInfo {
    uint32_t ownerID;
    uint32_t groupID;
    uint8_t	adminFlags;
    uint8_t	ownerFlags;
    uint16_t	fileMode;
    union {
        uint32_t	iNodeNum;
        uint32_t	linkCount;
        uint32_t	rawDevice;
    } special;
} __attribute__((__packed__));
typedef struct hfsPlusBSDInfo hfsPlusBSDInfo;

#define HFS_MODE_TYPEMASK	0170000
#define HFS_MODE_DIRECTORY	0040000
#define HFS_MODE_FILE		0100000
#define HFS_MODE_SOFTLINK	0120000

/******************************/
/* Node and tree structures   */
/******************************/

/* B-tree node descriptor (14 bytes) */
struct hfsNodeDescriptor {
    uint32_t	fLink;
    uint32_t	bLink;
    int8_t	kind;
    uint8_t	height;
    uint16_t	numRecords;
    uint16_t	reserved;
} __attribute__((__packed__));
typedef struct hfsNodeDescriptor hfsNodeDescriptor;

/* Node kinds are int8_t */
#define HFS_NODEKIND_LEAF	-1
#define HFS_NODEKIND_INDEX	0
#define HFS_NODEKIND_HEADER	1
#define HFS_NODEKIND_MAP	2

/* B-tree header record (106 bytes) */
struct hfsHeaderRecord {
    uint16_t	treeDepth;
    uint32_t	rootNode;
    uint32_t	leafRecords;
    uint32_t	firstLeafNode;
    uint32_t	lastLeafNode;
    uint16_t	nodeSize;
    uint16_t	maxKeyLength;
    uint32_t	totalNodes;
    uint32_t	freeNodes;
    uint16_t	reserved1;
    uint32_t	clumpSize;
    uint8_t	btreeType;
    uint8_t	keyCompareType;
    uint32_t	attributes;
    uint32_t	reserved3[16];
} __attribute__((__packed__));
typedef struct hfsHeaderRecord hfsHeaderRecord;

#define HFS_HEADERATTR_MASK	0x00000006
#define HFS_HEADERATTR_BIGKEYS	0x00000002
#define HFS_HEADERATTR_VARKEYS	0x00000004

struct hfsPlusCatalogKey {
    uint16_t	keyLength;
    uint32_t	parentID; /* CNID */
    hfsUniStr255	nodeName;
} __attribute__((__packed__));
typedef struct hfsPlusCatalogKey hfsPlusCatalogKey;

struct hfsPlusCatalogFolder {
    int16_t	recordType;
    uint16_t	flags;
    uint32_t	valence;
    uint32_t	folderID; /* CNID */
    uint32_t	dates[5];
    hfsPlusBSDInfo	permissions;
    uint16_t	userInfo[8]; /* FolderInfo */
    uint16_t	finderInfo[8]; /* ExtendedFolderInfo */
    uint32_t	textEncoding;
    uint32_t	reserved;
} __attribute__((__packed__));
typedef struct hfsPlusCatalogFolder hfsPlusCatalogFolder;

struct hfsPlusCatalogFile {
    int16_t	recordType;
    uint16_t	flags;
    uint32_t	reserved1;
    uint32_t	fileID; /* CNID */
    uint32_t	dates[5];
    hfsPlusBSDInfo	permissions;
    uint16_t	userInfo[8]; /* FileInfo */
    uint16_t	finderInfo[8]; /* ExtendedFileInfo */
    uint32_t	textEncoding;
    uint32_t	reserved2;
    hfsPlusForkData	dataFork;
    hfsPlusForkData	resourceFork;
};
typedef struct hfsPlusCatalogFile hfsPlusCatalogFile;

struct hfsPlusCatalogThread {
    int16_t	recordType;
    int16_t	reserved;
    uint32_t	parentID; /* CNID */
    hfsUniStr255	nodeName;
} __attribute__((__packed__));
typedef struct hfsPlusCatalogThread hfsPlusCatalogThread;

#define HFSPLUS_RECTYPE_FOLDER       0x0001
#define HFSPLUS_RECTYPE_FILE         0x0002
#define HFSPLUS_RECTYPE_FOLDERTHREAD 0x0003
#define HFSPLUS_RECTYPE_FILETHREAD   0x0004
/* HFS types are similar 
#define HFS_RECTYPE_FOLDER       0x0100
#define HFS_RECTYPE_FILE         0x0200
#define HFS_RECTYPE_FOLDERTHREAD 0x0300
#define HFS_RECTYPE_FILETHREAD   0x0400
 */

#define HFS_HARD_LINK_FILE_TYPE 0x686C6E6B /* hlnk */

/* Extents structures */
struct hfsPlusExtentKey {
    uint16_t	keyLength;
    uint8_t	forkType;
    uint8_t	pad;
    uint32_t	fileID; /* CNID */
    uint32_t	startBlock;
} __attribute__((__packed__));
typedef struct hfsPlusExtentKey hfsPlusExtentKey;

#define HFSPLUS_FORKTYPE_DATA 0x00
#define HFSPLUS_FORKTYPE_RSRC 0xFF

#ifdef HAVE_PRAGMA_PACK
#pragma pack()
#endif

#ifdef HAVE_PRAGMA_PACK_HPPA
#pragma pack
#endif

#define HFS_VOL_INCONSISTENT(hdr)	\
    ((hdr->attributes & (1 << hfsBootVolumeInconsistentBit))	\
    || !(hdr->attributes & (1 << hfsVolumeUnmountedBit)))

/* Maximum number of catalog leaf nodes to scan for records */
#define HFSPLUS_NODE_LIMIT 1000

int cli_scanhfsplus(cli_ctx *ctx);

#endif