19 package org.sleuthkit.autopsy.imagewriter;
21 import com.google.common.util.concurrent.ThreadFactoryBuilder;
22 import java.beans.PropertyChangeEvent;
23 import java.beans.PropertyChangeListener;
24 import java.util.concurrent.Callable;
25 import java.util.concurrent.Executors;
26 import java.util.concurrent.Future;
27 import java.util.concurrent.ScheduledFuture;
28 import java.util.concurrent.ScheduledThreadPoolExecutor;
29 import java.util.concurrent.TimeUnit;
30 import java.util.concurrent.ExecutionException;
31 import java.util.logging.Level;
32 import org.netbeans.api.progress.ProgressHandle;
33 import org.openide.util.NbBundle.Messages;
52 class ImageWriter
implements PropertyChangeListener{
56 private final Long dataSourceId;
59 private Long imageHandle = null;
60 private Future<Integer> finishTask = null;
61 private ProgressHandle progressHandle = null;
62 private ScheduledFuture<?> progressUpdateTask = null;
63 private boolean isCancelled =
false;
64 private boolean isStarted =
false;
65 private final Object currentTasksLock =
new Object();
68 private ScheduledThreadPoolExecutor periodicTasksExecutor = null;
69 private final boolean doUI;
70 private SleuthkitCase caseDb = null;
78 this.dataSourceId = dataSourceId;
79 this.settings = settings;
88 logger.log(Level.SEVERE,
"Unable to load case. Image writer will be cancelled.");
89 this.isCancelled =
true;
96 void subscribeToEvents(){
103 void unsubscribeFromEvents(){
112 public void propertyChange(PropertyChangeEvent evt) {
115 DataSourceAnalysisCompletedEvent
event = (DataSourceAnalysisCompletedEvent)evt;
117 if(event.getDataSource() != null){
118 long imageId =
event.getDataSource().getId();
119 String name =
event.getDataSource().getName();
122 if(imageId != dataSourceId){
126 startFinishImage(name);
130 logger.log(Level.SEVERE,
"DataSourceAnalysisCompletedEvent did not contain a dataSource object");
136 "# {0} - data source name",
137 "ImageWriter.progressBar.message=Finishing acquisition of {0} (unplug device to cancel)"
139 private void startFinishImage(String dataSourceName){
141 synchronized(currentTasksLock){
156 imageHandle = image.getImageHandle();
162 logger.log(Level.WARNING, String.format(
"Case closed before ImageWriter could start the finishing process for %s",
165 }
catch (TskCoreException ex){
166 logger.log(Level.SEVERE,
"Error loading image", ex);
170 logger.log(Level.INFO, String.format(
"Finishing VHD image for %s",
174 periodicTasksExecutor =
new ScheduledThreadPoolExecutor(1,
new ThreadFactoryBuilder().setNameFormat(
"image-writer-progress-update-%d").build());
175 progressHandle = ProgressHandle.createHandle(Bundle.ImageWriter_progressBar_message(dataSourceName));
176 progressHandle.start(100);
177 progressUpdateTask = periodicTasksExecutor.scheduleWithFixedDelay(
178 new ProgressUpdateTask(progressHandle, imageHandle), 0, 250, TimeUnit.MILLISECONDS);
184 finishTask = Executors.newSingleThreadExecutor().submit(
new Callable<Integer>(){
186 public Integer call()
throws TskCoreException{
188 int result = SleuthkitJNI.finishImageWriter(imageHandle);
194 caseDb.updateImagePath(settings.
getPath(), dataSourceId);
197 }
catch (TskCoreException ex){
198 logger.log(Level.SEVERE,
"Error finishing VHD image", ex);
212 result = finishTask.get();
213 }
catch (InterruptedException | ExecutionException ex){
214 logger.log(Level.SEVERE,
"Error finishing VHD image", ex);
217 synchronized(currentTasksLock){
220 progressUpdateTask.cancel(
true);
221 progressHandle.finish();
222 periodicTasksExecutor.shutdown();
227 logger.log(Level.INFO, String.format(
"Successfully finished writing VHD image for %s", dataSourceName));
229 logger.log(Level.INFO, String.format(
"Finished VHD image for %s with errors", dataSourceName));
239 void cancelIfNotStarted(){
240 synchronized(currentTasksLock){
252 boolean jobIsInProgress(){
253 synchronized(currentTasksLock){
254 return((isStarted) && (! finishTask.isDone()));
263 synchronized(currentTasksLock){
268 SleuthkitJNI.cancelFinishImage(imageHandle);
277 progressUpdateTask.cancel(
true);
278 progressHandle.finish();
288 void waitForJobToFinish(){
289 synchronized(currentTasksLock){
294 }
catch (InterruptedException | ExecutionException ex){
295 Logger.
getLogger(ImageWriter.class.getName()).log(Level.SEVERE,
"Error finishing VHD image", ex);
298 progressUpdateTask.cancel(
true);
308 final long imageHandle;
309 final ProgressHandle progressHandle;
312 this.imageHandle = imageHandle;
313 this.progressHandle = progressHandle;
319 int progress = SleuthkitJNI.getFinishImageProgress(imageHandle);
320 progressHandle.progress(progress);
321 }
catch (Exception ex) {
322 logger.log(Level.SEVERE,
"Unexpected exception in ProgressUpdateTask", ex);
static synchronized IngestManager getInstance()
static boolean runningWithGUI
void removeIngestJobEventListener(final PropertyChangeListener listener)
void addIngestJobEventListener(final PropertyChangeListener listener)
SleuthkitCase getSleuthkitCase()
synchronized static Logger getLogger(String name)
static Case getCurrentCaseThrows()
boolean getUpdateDatabasePath()