1 /*
2  * Sleuth Kit Data Model
3  *
4  * Copyright 2011-2017 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.datamodel;
20 
21 import java.util.List;
22 
23 /**
24  * Represents a file system object stored in tsk_fs_info table FileSystem has a
25  * parent content object (volume or image) and children content objects (files
26  * and directories) and fs-specific attributes. The object also maintains a
27  * handle to internal file-system structures and the handle is reused across
28  * reads.
29  */
30 public class FileSystem extends AbstractContent {
31 
32 	private long imgOffset, blockSize, blockCount, rootInum,
33 			firstInum, lastInum;
34 	private TskData.TSK_FS_TYPE_ENUM fsType;
35 	private Content parent;
36 	private volatile long filesystemHandle = 0;
37 
38 	/**
39 	 * Constructor most inputs are from the database
40 	 *
41 	 * @param db          the case handle
42 	 * @param obj_id      the unique object id
43 	 * @param name        filesystem name
44 	 * @param img_offset  image offset
45 	 * @param fs_type     filesystem type
46 	 * @param block_size  block size in this fs
47 	 * @param block_count number of blocks in this fs
48 	 * @param root_inum   the root inum
49 	 * @param first_inum  the first inum
50 	 * @param last_inum   the last inum
51 	 */
FileSystem(SleuthkitCase db, long obj_id, String name, long img_offset, TskData.TSK_FS_TYPE_ENUM fs_type, long block_size, long block_count, long root_inum, long first_inum, long last_inum)52 	protected FileSystem(SleuthkitCase db, long obj_id, String name, long img_offset,
53 			TskData.TSK_FS_TYPE_ENUM fs_type, long block_size, long block_count, long root_inum,
54 			long first_inum, long last_inum) {
55 		super(db, obj_id, name);
56 		this.imgOffset = img_offset;
57 		this.fsType = fs_type;
58 		this.blockSize = block_size;
59 		this.blockCount = block_count;
60 		this.rootInum = root_inum;
61 		this.firstInum = first_inum;
62 		this.lastInum = last_inum;
63 	}
64 
65 	@Override
close()66 	public void close() {
67 		//does nothing currently, we are caching the fs handles
68 	}
69 
70 	@Override
read(byte[] buf, long offset, long len)71 	public int read(byte[] buf, long offset, long len) throws TskCoreException {
72 		return SleuthkitJNI.readFs(getFileSystemHandle(), buf, offset, len);
73 	}
74 
75 	@Override
getSize()76 	public long getSize() {
77 		return blockSize * blockCount;
78 	}
79 
80 	/**
81 	 * Lazily loads the internal file system structure: won't be loaded until
82 	 * this is called and maintains the handle to it to reuse it
83 	 *
84 	 * @return a filesystem pointer from the sleuthkit
85 	 *
86 	 * @throws TskCoreException exception throw if an internal tsk core error
87 	 *                          occurs
88 	 */
getFileSystemHandle()89 	long getFileSystemHandle() throws TskCoreException {
90 		if (filesystemHandle == 0) {
91 			synchronized (this) {
92 				if (filesystemHandle == 0) {
93 					Content dataSource = getDataSource();
94 					if ((dataSource != null) && (dataSource instanceof Image)) {
95 						Image image = (Image) dataSource;
96 						filesystemHandle = SleuthkitJNI.openFs(image.getImageHandle(), imgOffset, getSleuthkitCase());
97 					} else {
98 						throw new TskCoreException("Data Source of File System is not an image");
99 					}
100 				}
101 			}
102 		}
103 		return this.filesystemHandle;
104 	}
105 
getRootDirectory()106 	public Directory getRootDirectory() throws TskCoreException {
107 
108 		List<Content> children = getChildren();
109 		if (children.size() != 1) {
110 			throw new TskCoreException("FileSystem must have only one child.");
111 		}
112 
113 		if (!(children.get(0) instanceof Directory)) {
114 			throw new TskCoreException("Child of FileSystem must be a Directory.");
115 		}
116 
117 		return (Directory) children.get(0);
118 	}
119 
120 	/**
121 	 * Get the byte offset of this file system in the image
122 	 *
123 	 * @return offset
124 	 */
getImageOffset()125 	public long getImageOffset() {
126 		return imgOffset;
127 	}
128 
129 	/**
130 	 * Get the file system type
131 	 *
132 	 * @return enum value of fs type
133 	 */
getFsType()134 	public TskData.TSK_FS_TYPE_ENUM getFsType() {
135 		return fsType;
136 	}
137 
138 	/**
139 	 * Get the block size
140 	 *
141 	 * @return block size
142 	 */
getBlock_size()143 	public long getBlock_size() {
144 		return blockSize;
145 	}
146 
147 	/**
148 	 * Get the number of blocks
149 	 *
150 	 * @return block count
151 	 */
getBlock_count()152 	public long getBlock_count() {
153 		return blockCount;
154 	}
155 
156 	/**
157 	 * Get the inum of the root directory
158 	 *
159 	 * @return Root metadata address of the file system
160 	 */
getRoot_inum()161 	public long getRoot_inum() {
162 		return rootInum;
163 	}
164 
165 	/**
166 	 * Get the first inum in this file system
167 	 *
168 	 * @return first inum
169 	 */
getFirst_inum()170 	public long getFirst_inum() {
171 		return firstInum;
172 	}
173 
174 	/**
175 	 * Get the last inum
176 	 *
177 	 * @return last inum
178 	 */
getLastInum()179 	public long getLastInum() {
180 		return lastInum;
181 	}
182 
183 	@Override
finalize()184 	public void finalize() throws Throwable {
185 		try {
186 			if (filesystemHandle != 0) {
187 				// SleuthkitJNI.closeFs(filesystemHandle); // closeFs is currently a no-op
188 				filesystemHandle = 0;
189 			}
190 		} finally {
191 			super.finalize();
192 		}
193 	}
194 
195 	@Override
accept(SleuthkitItemVisitor<T> v)196 	public <T> T accept(SleuthkitItemVisitor<T> v) {
197 		return v.visit(this);
198 	}
199 
200 	@Override
accept(ContentVisitor<T> v)201 	public <T> T accept(ContentVisitor<T> v) {
202 		return v.visit(this);
203 	}
204 
205 	@Override
toString(boolean preserveState)206 	public String toString(boolean preserveState) {
207 		return super.toString(preserveState) + "FileSystem [\t" + " blockCount " + blockCount + "\t" + "blockSize " + blockSize + "\t" + "firstInum " + firstInum + "\t" + "fsType " + fsType + "\t" + "imgOffset " + imgOffset + "\t" + "lastInum " + lastInum + "\t" + "rootInum " + rootInum + "\t" + "]"; //NON-NLS
208 	}
209 }
210