1 /*
2 ** The Sleuth Kit
3 **
4 ** Brian Carrier [carrier <at> sleuthkit [dot] org]
5 ** Copyright (c) 2006-2011 Brian Carrier, Basis Technology.  All Rights reserved
6 ** Copyright (c) 2004-2005 Brian Carrier.  All rights reserved
7 **
8 **
9 ** This software is distributed under the Common Public License 1.0
10 **
11 */
12 
13 #include "tsk_fs_i.h"
14 
15 
16 /**
17  *\file nofs_misc.c
18  * Contains internal functions that are common to the "non-file system" file systems, such as
19  * raw and swap. Many of the functions in this file simply give an error that the functionality
20  * is not supported for the given file system type.
21  */
22 
23 
24 /** \internal
25  * Print details about the file system to a file handle.
26  *
27  * @param a_fs File system to print details on
28  * @param hFile File handle to print text to
29  *
30  * @returns 1 on error and 0 on success
31  */
32 uint8_t
tsk_fs_nofs_fsstat(TSK_FS_INFO * a_fs,FILE * hFile)33 tsk_fs_nofs_fsstat(TSK_FS_INFO * a_fs, FILE * hFile)
34 {
35     tsk_fprintf(hFile, "%s Data\n", tsk_fs_type_toname(a_fs->ftype));
36     tsk_fprintf(hFile, "Block Size: %d\n", a_fs->block_size);
37     tsk_fprintf(hFile, "Block Range: 0 - %" PRIuDADDR "\n",
38         a_fs->last_block);
39     return 0;
40 }
41 
42 
43 /** \internal
44  */
45 TSK_FS_ATTR_TYPE_ENUM
tsk_fs_nofs_get_default_attr_type(const TSK_FS_FILE * a_fs_file)46 tsk_fs_nofs_get_default_attr_type(const TSK_FS_FILE * a_fs_file)
47 {
48     return TSK_FS_ATTR_TYPE_DEFAULT;
49 }
50 
51 
52 /** \internal
53  */
54 uint8_t
tsk_fs_nofs_make_data_run(TSK_FS_FILE * a_fs_file)55 tsk_fs_nofs_make_data_run(TSK_FS_FILE * a_fs_file)
56 {
57     tsk_error_reset();
58     tsk_error_set_errno(TSK_ERR_FS_UNSUPFUNC);
59     tsk_error_set_errstr("Illegal analysis method for %s data ",
60         (a_fs_file->fs_info) ? tsk_fs_type_toname(a_fs_file->
61             fs_info->ftype) : "");
62     return 1;
63 }
64 
65 
66 
67 /** \internal
68  */
69 void
tsk_fs_nofs_close(TSK_FS_INFO * a_fs)70 tsk_fs_nofs_close(TSK_FS_INFO * a_fs)
71 {
72     a_fs->tag = 0;
73     tsk_fs_free(a_fs);
74 }
75 
76 /************* BLOCKS *************/
77 
78 /** \internal
79  */
80 TSK_FS_BLOCK_FLAG_ENUM
tsk_fs_nofs_block_getflags(TSK_FS_INFO * a_fs,TSK_DADDR_T a_addr)81 tsk_fs_nofs_block_getflags(TSK_FS_INFO * a_fs, TSK_DADDR_T a_addr)
82 {
83     return TSK_FS_BLOCK_FLAG_ALLOC | TSK_FS_BLOCK_FLAG_CONT;
84 }
85 
86 
87 /** \internal
88  *
89  * return 1 on error and 0 on success
90  */
91 uint8_t
tsk_fs_nofs_block_walk(TSK_FS_INFO * fs,TSK_DADDR_T a_start_blk,TSK_DADDR_T a_end_blk,TSK_FS_BLOCK_WALK_FLAG_ENUM a_flags,TSK_FS_BLOCK_WALK_CB a_action,void * a_ptr)92 tsk_fs_nofs_block_walk(TSK_FS_INFO * fs, TSK_DADDR_T a_start_blk,
93     TSK_DADDR_T a_end_blk, TSK_FS_BLOCK_WALK_FLAG_ENUM a_flags,
94     TSK_FS_BLOCK_WALK_CB a_action, void *a_ptr)
95 {
96     TSK_FS_BLOCK *fs_block;
97     TSK_DADDR_T addr;
98 
99     // clean up any error messages that are lying around
100     tsk_error_reset();
101 
102     /*
103      * Sanity checks.
104      */
105     if (a_start_blk < fs->first_block || a_start_blk > fs->last_block) {
106         tsk_error_reset();
107         tsk_error_set_errno(TSK_ERR_FS_WALK_RNG);
108         tsk_error_set_errstr("nofs_block_walk: Start block number: %"
109             PRIuDADDR, a_start_blk);
110         return 1;
111     }
112 
113     if (a_end_blk < fs->first_block || a_end_blk > fs->last_block
114         || a_end_blk < a_start_blk) {
115         tsk_error_reset();
116         tsk_error_set_errno(TSK_ERR_FS_WALK_RNG);
117         tsk_error_set_errstr("nofs_block_walk: Last block number: %"
118             PRIuDADDR, a_end_blk);
119         return 1;
120     }
121 
122     /* Sanity check on a_flags -- make sure at least one ALLOC is set */
123     if (((a_flags & TSK_FS_BLOCK_WALK_FLAG_ALLOC) == 0) &&
124         ((a_flags & TSK_FS_BLOCK_WALK_FLAG_UNALLOC) == 0)) {
125         a_flags |=
126             (TSK_FS_BLOCK_WALK_FLAG_ALLOC |
127             TSK_FS_BLOCK_WALK_FLAG_UNALLOC);
128     }
129 
130     /* All swap has is allocated blocks... exit if not wanted */
131     if (!(a_flags & TSK_FS_BLOCK_FLAG_ALLOC)) {
132         return 0;
133     }
134 
135     if ((fs_block = tsk_fs_block_alloc(fs)) == NULL) {
136         return 1;
137     }
138 
139     for (addr = a_start_blk; addr <= a_end_blk; addr++) {
140         int retval;
141 
142         if (tsk_fs_block_get(fs, fs_block, addr) == NULL) {
143             tsk_error_set_errstr2("nofs_block_walk: Block %" PRIuDADDR,
144                 addr);
145             tsk_fs_block_free(fs_block);
146             return 1;
147         }
148 
149         retval = a_action(fs_block, a_ptr);
150         if (retval == TSK_WALK_STOP) {
151             break;
152         }
153         else if (retval == TSK_WALK_ERROR) {
154             tsk_fs_block_free(fs_block);
155             return 1;
156         }
157     }
158 
159     /*
160      * Cleanup.
161      */
162     tsk_fs_block_free(fs_block);
163     return 0;
164 }
165 
166 
167 /************ META / FILES ************/
168 
169 
170 /** \internal
171  */
172 uint8_t
tsk_fs_nofs_inode_walk(TSK_FS_INFO * a_fs,TSK_INUM_T a_start_inum,TSK_INUM_T a_end_inum,TSK_FS_META_FLAG_ENUM a_flags,TSK_FS_META_WALK_CB a_action,void * a_ptr)173 tsk_fs_nofs_inode_walk(TSK_FS_INFO * a_fs, TSK_INUM_T a_start_inum,
174     TSK_INUM_T a_end_inum, TSK_FS_META_FLAG_ENUM a_flags,
175     TSK_FS_META_WALK_CB a_action, void *a_ptr)
176 {
177     tsk_error_reset();
178     tsk_error_set_errno(TSK_ERR_FS_UNSUPFUNC);
179     tsk_error_set_errstr("Illegal analysis method for %s data ",
180         tsk_fs_type_toname(a_fs->ftype));
181     return 1;
182 }
183 
184 /** \internal
185  */
186 uint8_t
tsk_fs_nofs_file_add_meta(TSK_FS_INFO * a_fs,TSK_FS_FILE * a_fs_file,TSK_INUM_T inum)187 tsk_fs_nofs_file_add_meta(TSK_FS_INFO * a_fs, TSK_FS_FILE * a_fs_file,
188     TSK_INUM_T inum)
189 {
190     tsk_error_reset();
191     tsk_error_set_errno(TSK_ERR_FS_UNSUPFUNC);
192     tsk_error_set_errstr("Illegal analysis method for %s data ",
193         tsk_fs_type_toname(a_fs->ftype));
194     return 1;
195 }
196 
197 /** \internal
198  */
199 uint8_t
tsk_fs_nofs_istat(TSK_FS_INFO * a_fs,TSK_FS_ISTAT_FLAG_ENUM istat_flags,FILE * hFile,TSK_INUM_T inum,TSK_DADDR_T numblock,int32_t sec_skew)200 tsk_fs_nofs_istat(TSK_FS_INFO * a_fs, TSK_FS_ISTAT_FLAG_ENUM istat_flags, FILE * hFile, TSK_INUM_T inum,
201     TSK_DADDR_T numblock, int32_t sec_skew)
202 {
203     tsk_error_reset();
204     tsk_error_set_errno(TSK_ERR_FS_UNSUPFUNC);
205     tsk_error_set_errstr("Illegal analysis method for %s data ",
206         tsk_fs_type_toname(a_fs->ftype));
207     return 1;
208 }
209 
210 
211 
212 /************ DIR **************/
213 
214 /** \internal
215  */
216 TSK_RETVAL_ENUM
tsk_fs_nofs_dir_open_meta(TSK_FS_INFO * a_fs,TSK_FS_DIR ** a_fs_dir,TSK_INUM_T a_addr)217 tsk_fs_nofs_dir_open_meta(TSK_FS_INFO * a_fs, TSK_FS_DIR ** a_fs_dir,
218     TSK_INUM_T a_addr)
219 {
220     tsk_error_reset();
221     tsk_error_set_errno(TSK_ERR_FS_UNSUPFUNC);
222     tsk_error_set_errstr("Illegal analysis method for %s data ",
223         tsk_fs_type_toname(a_fs->ftype));
224     return TSK_ERR;
225 }
226 
227 /******** JOURNAL **********/
228 
229 /** \internal
230  */
231 uint8_t
tsk_fs_nofs_jopen(TSK_FS_INFO * a_fs,TSK_INUM_T inum)232 tsk_fs_nofs_jopen(TSK_FS_INFO * a_fs, TSK_INUM_T inum)
233 {
234     tsk_error_reset();
235     tsk_error_set_errno(TSK_ERR_FS_UNSUPFUNC);
236     tsk_error_set_errstr("Illegal analysis method for %s data ",
237         tsk_fs_type_toname(a_fs->ftype));
238     return 1;
239 }
240 
241 /** \internal
242  */
243 uint8_t
tsk_fs_nofs_jentry_walk(TSK_FS_INFO * a_fs,int a_flags,TSK_FS_JENTRY_WALK_CB a_action,void * a_ptr)244 tsk_fs_nofs_jentry_walk(TSK_FS_INFO * a_fs, int a_flags,
245     TSK_FS_JENTRY_WALK_CB a_action, void *a_ptr)
246 {
247     tsk_error_reset();
248     tsk_error_set_errno(TSK_ERR_FS_UNSUPFUNC);
249     tsk_error_set_errstr("Illegal analysis method for %s data ",
250         tsk_fs_type_toname(a_fs->ftype));
251     return 1;
252 }
253 
254 
255 /** \internal
256  */
257 uint8_t
tsk_fs_nofs_jblk_walk(TSK_FS_INFO * a_fs,TSK_INUM_T start,TSK_INUM_T end,int a_flags,TSK_FS_JBLK_WALK_CB a_action,void * a_ptr)258 tsk_fs_nofs_jblk_walk(TSK_FS_INFO * a_fs, TSK_INUM_T start, TSK_INUM_T end,
259     int a_flags, TSK_FS_JBLK_WALK_CB a_action, void *a_ptr)
260 {
261     tsk_error_reset();
262     tsk_error_set_errno(TSK_ERR_FS_UNSUPFUNC);
263     tsk_error_set_errstr("Illegal analysis method for %s data ",
264         tsk_fs_type_toname(a_fs->ftype));
265     return 1;
266 }
267 
268 int
tsk_fs_nofs_name_cmp(TSK_FS_INFO * a_fs_info,const char * s1,const char * s2)269 tsk_fs_nofs_name_cmp(TSK_FS_INFO * a_fs_info, const char *s1,
270     const char *s2)
271 {
272     return strcmp(s1, s2);
273 }
274