1 /*
2 ** The Sleuth Kit
3 **
4 ** Brian Carrier [carrier <at> sleuthkit [dot] org]
5 ** Copyright (c) 2003-2011 Brian Carrier.  All rights reserved
6 **
7 ** TASK
8 ** Copyright (c) 2002 Brian Carrier, @stake Inc.  All rights reserved
9 **
10 ** This software is distributed under the Common Public License 1.0
11 */
12 
13 /*
14  * Contains the structures and function APIs for YAFFSFS file system support.
15  */
16 
17 #ifndef _TSK_YAFFSFS_H
18 #define _TSK_YAFFSFS_H
19 
20 #include <map>
21 #include <utility>
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 /*
28 ** Constants
29 */
30 #define YAFFSFS_MAXNAMLEN	255
31 
32 #define YAFFS_DEFAULT_PAGE_SIZE     2048
33 #define YAFFS_DEFAULT_SPARE_SIZE    64
34 
35 #define YAFFS_DEFAULT_MAX_TEST_BLOCKS   400  // Maximum number of blocks to test looking for Yaffs2 spare under auto-detect
36 
37 #define YAFFS_HELP_MESSAGE   "See http://wiki.sleuthkit.org/index.php?title=YAFFS2 for help on Yaffs2 configuration"
38 
39 /*
40  * Yaffs config file constants and return values
41  */
42 #ifdef TSK_WIN32
43 #define YAFFS_CONFIG_FILE_SUFFIX          L"-yaffs2.config"
44 #else
45 #define YAFFS_CONFIG_FILE_SUFFIX          "-yaffs2.config"
46 #endif
47 
48 #define YAFFS_CONFIG_SEQ_NUM_STR          "spare_seq_num_offset"
49 #define YAFFS_CONFIG_OBJ_ID_STR           "spare_obj_id_offset"
50 #define YAFFS_CONFIG_CHUNK_ID_STR         "spare_chunk_id_offset"
51 #define YAFFS_CONFIG_PAGE_SIZE_STR        "flash_page_size"
52 #define YAFFS_CONFIG_SPARE_SIZE_STR       "flash_spare_size"
53 #define YAFFS_CONFIG_CHUNKS_PER_BLOCK_STR "flash_chunks_per_block"
54 
55 typedef enum {
56     YAFFS_CONFIG_OK,
57     YAFFS_CONFIG_FILE_NOT_FOUND,
58     YAFFS_CONFIG_ERROR
59 } YAFFS_CONFIG_STATUS;
60 
61 /*
62 ** Yaffs Object Flags
63 */
64     typedef enum {
65         NONE,
66         YAFFS_HEADER,
67         YAFFS_CHUNK,
68         YAFFS_PAGES,
69         YAFFS_SPARES,
70         YAFFS_PAGES_AND_SPARES,
71         UNKNOWN
72     } YAFFS_OBJECT_FLAGS;
73 
74 /*
75 ** Yaffs2 Header Object
76 */
77 
78 #define YAFFS_HEADER_NAME_LENGTH   256
79 #define YAFFS_HEADER_ALIAS_LENGTH  160
80     typedef struct yaffsObj_header {
81         uint32_t obj_type;
82         uint32_t parent_id;
83         char name[YAFFS_HEADER_NAME_LENGTH];
84         uint32_t file_mode;
85         uint32_t user_id;
86         uint32_t group_id;
87         uint32_t atime;
88         uint32_t mtime;
89         uint32_t ctime;
90         uint32_t file_size;
91         uint32_t equivalent_id;
92         char alias[YAFFS_HEADER_ALIAS_LENGTH];
93         uint32_t rdev_mode;
94         uint32_t win_ctime[2];
95         uint32_t win_atime[2];
96         uint32_t win_mtime[2];
97         uint32_t inband_obj_id;
98         uint32_t inband_is_shrink;
99         uint32_t file_size_high;
100         uint32_t reserved[1];
101         int shadows_obj;
102         uint32_t is_shrink;
103     } YaffsHeader;
104 
105 /*
106 ** Spare object - this is subject to change...
107 */
108 
109 #define YAFFS_OBJECT_SPACE              0x40000
110 #define YAFFS_MAX_OBJECT_ID             (YAFFS_OBJECT_SPACE - 1)
111 #define YAFFS_LOWEST_SEQUENCE_NUMBER    0x00001000
112 #define YAFFS_HIGHEST_SEQUENCE_NUMBER   0xefffff00
113 #define YAFFS_SPARE_FLAGS_IS_HEADER     0x80000000
114 #define YAFFS_SPARE_PARENT_ID_MASK      0x0fffffff
115 #define YAFFS_SPARE_OBJECT_TYPE_SHIFT   28
116 #define YAFFS_SPARE_OBJECT_TYPE_MASK    0xf0000000
117 
118 
119     typedef struct yaffsObj_spare {
120         uint32_t seq_number;
121         uint32_t object_id;
122         uint32_t chunk_id;
123 
124         uint32_t has_extra_fields;
125         uint32_t extra_object_type;
126         uint32_t extra_parent_id;
127     } YaffsSpare;
128 
129 /*
130 ** Holds the metadata for a single YAFFS2 chunk.
131 */
132     typedef enum {
133         YAFFS_CHUNK_DEAD,       /* Either bad or unallocated */
134         YAFFS_CHUNK_META,       /* Contains a header */
135         YAFFS_CHUNK_DATA        /* Contains file data */
136     } YaffsChunkType;
137 
138     typedef struct _YaffsChunk {
139         YaffsChunkType type;
140         YaffsSpare *spare;
141         YaffsHeader *header;
142     } YaffsChunk;
143 
144 /* File system State Values */
145 #define YAFFSFS_STATE_VALID	0x0001  /* unmounted correctly */
146 #define YAFFSFS_STATE_ERROR	0x0002  /* errors detected */
147 
148 /*
149  * Special File Objects for the YAFFS2 File system
150  */
151 #define YAFFS_OBJECT_ROOT 1
152 #define YAFFS_OBJECT_FIRST 1
153 #define YAFFS_OBJECT_LOSTNFOUND 2
154 #define YAFFS_OBJECT_UNLINKED 3
155 #define YAFFS_OBJECT_DELETED 4
156 
157 #define YAFFS_OBJECT_ROOT_NAME           ""
158 #define YAFFS_OBJECT_LOSTNFOUND_NAME     "lost+found"
159 #define YAFFS_OBJECT_UNLINKED_NAME       "<unlinked>"
160 #define YAFFS_OBJECT_DELETED_NAME        "<deleted>"
161 
162 /*
163  * Yaffs File Types...
164  */
165 #define YAFFS_TYPE_UNKNOWN 0
166 #define YAFFS_TYPE_FILE    1
167 #define YAFFS_TYPE_SOFTLINK 2
168 #define YAFFS_TYPE_DIRECTORY 3
169 #define YAFFS_TYPE_HARDLINK 4
170 #define YAFFS_TYPE_SPECIAL 5
171 
172 
173 
174     struct _YaffsCacheVersion;
175     struct _YaffsCacheChunk;
176 
177     typedef struct _YaffsCacheObject {
178         struct _YaffsCacheObject *yco_next;
179 
180         uint32_t yco_obj_id;
181 
182         struct _YaffsCacheVersion *yco_latest;
183     } YaffsCacheObject;
184 
185 #define YAFFS_OBJECT_ID_MASK         0x0003ffff
186 #define YAFFS_VERSION_NUM_SHIFT      18
187 #define YAFFS_VERSION_NUM_MASK       0x00003fff
188 
189     typedef struct _YaffsCacheVersion {
190         struct _YaffsCacheVersion *ycv_prior;
191 
192         uint32_t ycv_version;
193         uint32_t ycv_seq_number;
194 
195         struct _YaffsCacheChunk *ycv_header_chunk;
196         struct _YaffsCacheChunk *ycv_first_chunk;
197         struct _YaffsCacheChunk *ycv_last_chunk;
198     } YaffsCacheVersion;
199 
200     typedef struct _YaffsCacheChunk {
201         struct _YaffsCacheChunk *ycc_next;
202         struct _YaffsCacheChunk *ycc_prev;
203 
204         TSK_OFF_T ycc_offset;
205         uint32_t ycc_seq_number;
206         uint32_t ycc_obj_id;
207         uint32_t ycc_chunk_id;
208         uint32_t ycc_parent_id;
209         uint32_t ycc_n_bytes;
210     } YaffsCacheChunk;
211 
212     typedef struct _YaffsCacheChunkGroup {
213         YaffsCacheChunk *cache_chunks_head;
214         YaffsCacheChunk *cache_chunks_tail;
215     } YaffsCacheChunkGroup;
216 
217     /*
218      * Structure of an yaffsfs file system handle.
219      */
220     typedef struct {
221         TSK_FS_INFO fs_info;    /* super class */
222 
223         unsigned int page_size;
224         unsigned int spare_size;
225         unsigned int chunks_per_block;
226 
227         uint32_t max_obj_id;
228         uint32_t max_version;
229 
230         // Offsets into the spare area
231         unsigned int spare_seq_offset;
232         unsigned int spare_obj_id_offset;
233         unsigned int spare_chunk_id_offset;
234         unsigned int spare_nbytes_offset;
235 
236         tsk_lock_t cache_lock;
237         YaffsCacheObject *cache_objects;
238          std::map < uint32_t, YaffsCacheChunkGroup > *chunkMap;
239 
240         // If the user specified that the image is YAFFS2, print out additional verbose error messages
241         int autoDetect;
242     } YAFFSFS_INFO;
243 
244 #define YAFFS_FILE_CONTENT_LEN 0
245 
246 #ifdef __cplusplus
247 }
248 #endif
249 #endif
250