[Forensics-changes] [sleuthkit] 02/03: Merging upstream version 4.1.2

Michael Prokop mika at moszumanska.debian.org
Tue Feb 4 13:26:47 UTC 2014


This is an automated email from the git hooks/post-receive script.

mika pushed a commit to branch debian
in repository sleuthkit.

commit aa40ef4f700c298fdfc443d83f703e4eb0f31240
Author: Michael Prokop <mika at debian.org>
Date:   Tue Feb 4 14:17:06 2014 +0100

    Merging upstream version 4.1.2
---
 NEWS.txt                                           |   32 +
 bindings/java/build-unix.xml                       |   37 +
 bindings/java/build-windows.xml                    |   80 +
 bindings/java/build.xml                            |   42 +-
 bindings/java/doxygen/main.dox                     |   20 +
 bindings/java/jni/dataModel_SleuthkitJNI.cpp       |   19 +-
 .../org/sleuthkit/datamodel/AbstractContent.java   |   14 +-
 .../src/org/sleuthkit/datamodel/AbstractFile.java  |   16 +-
 .../sleuthkit/datamodel/BlackboardArtifact.java    |   26 +-
 .../sleuthkit/datamodel/BlackboardAttribute.java   |   23 +
 .../java/src/org/sleuthkit/datamodel/Content.java  |   31 +-
 .../src/org/sleuthkit/datamodel/FsContent.java     |   31 +-
 .../java/src/org/sleuthkit/datamodel/Image.java    |  160 +-
 .../src/org/sleuthkit/datamodel/LibraryUtils.java  |  268 +
 .../datamodel/LogicalFileTransaction.java          |  148 +
 .../org/sleuthkit/datamodel/ResultSetHelper.java   |   10 +-
 .../src/org/sleuthkit/datamodel/SleuthkitCase.java |  591 +-
 .../src/org/sleuthkit/datamodel/SleuthkitJNI.java  |   28 +-
 .../src/org/sleuthkit/datamodel/Transaction.java   |   59 +
 .../java/src/org/sleuthkit/datamodel/TskData.java  |   83 +-
 .../java/src/org/sleuthkit/datamodel/Volume.java   |   17 +-
 .../src/org/sleuthkit/datamodel/VolumeSystem.java  |    5 +-
 configure                                          |   34 +-
 configure.ac                                       |   16 +-
 framework/RUNNING_msvs.txt                         |   14 +-
 framework/SampleConfig/framework_config.xml        |   44 +-
 .../SampleConfig/framework_config_bindist.xml      |   18 +-
 .../SampleConfig/framework_config_template.xml     |   18 +-
 .../SampleConfig/framework_config_unixdev.xml      |   18 +-
 .../SampleConfig/framework_config_win32dev.xml     |   16 +-
 framework/SampleConfig/pipeline_config.xml         |   50 +-
 framework/docs/fileToDoxPage.py                    |   56 +-
 framework/docs/img_db_schema_v1_5.dox              |  360 +-
 framework/docs/module_dev.dox                      |    6 +-
 framework/docs/pipeline.dox                        |   18 +-
 framework/docs/sample_pipeline_config_file.dox     |   68 +-
 .../modules/c_EntropyModule/EntropyModule.cpp      |  890 +--
 framework/modules/c_EntropyModule/NEWS.txt         |   18 +-
 framework/modules/c_EntropyModule/README.txt       |   66 +-
 .../c_EntropyModule/win32/EntropyModule.sln        |   40 +-
 .../modules/c_FileTypeSigModule/FileTypeModule.cpp |  406 +-
 framework/modules/c_FileTypeSigModule/NEWS.txt     |   36 +-
 framework/modules/c_FileTypeSigModule/README.txt   |  166 +-
 .../README_BuildingLibMagicWin32.txt               |   80 +-
 framework/modules/c_FileTypeSigModule/configure.ac |    2 +-
 .../modules/c_HashCalcModule/HashCalcModule.cpp    |  448 +-
 framework/modules/c_HashCalcModule/NEWS.txt        |   26 +-
 framework/modules/c_HashCalcModule/README.txt      |   80 +-
 .../InterestingFilesModule.cpp                     | 1278 ++--
 .../modules/c_InterestingFilesModule/NEWS.txt      |   18 +-
 .../modules/c_InterestingFilesModule/README.txt    |  218 +-
 .../c_InterestingFilesModule/interesting_files.xml |   58 +-
 framework/modules/c_LibExifModule/NEWS.txt         |   18 +-
 .../libexif-0.6.20/win32/lib_exif/lib_exif.vcproj  |  822 +-
 .../libexif-0.6.20/win32/lib_exifVC9.sln           |   40 +-
 .../win32/lib_exifVC9/lib_exifVC9.vcproj           |  840 +--
 framework/modules/c_RegRipperModule/NEWS.txt       |   48 +-
 framework/modules/c_RegRipperModule/README.txt     |  178 +-
 .../modules/c_RegRipperModule/RegRipperModule.cpp  | 1266 ++--
 .../modules/c_SaveInterestingFilesModule/NEWS.txt  |   18 +-
 .../c_SaveInterestingFilesModule/README.txt        |  142 +-
 .../SaveInterestingFilesModule.cpp                 |  916 +--
 framework/modules/c_SummaryReportModule/NEWS.txt   |   24 +-
 framework/modules/c_SummaryReportModule/README.txt |   96 +-
 .../c_SummaryReportModule/SummaryReport.cpp        |  626 +-
 .../modules/c_SummaryReportModule/SummaryReport.h  |   44 +-
 .../c_SummaryReportModule/SummaryReportModule.cpp  |  386 +-
 framework/modules/c_TskHashLookupModule/NEWS.txt   |   18 +-
 framework/modules/c_TskHashLookupModule/README.txt |  108 +-
 .../c_TskHashLookupModule/TskHashLookupModule.cpp  |  528 +-
 framework/modules/c_ZIPExtractionModule/NEWS.txt   |   18 +-
 framework/modules/c_ZIPExtractionModule/README.txt |   64 +-
 .../c_ZIPExtractionModule/ZipExtractionModule.cpp  |  752 +-
 framework/msvcpp/Makefile                          |  154 +-
 framework/tools/tsk_analyzeimg/tsk_analyzeimg.cpp  |  902 +--
 .../tsk_validatepipeline/tsk_validatepipeline.cpp  |  356 +-
 framework/tsk/framework/TskVersionInfo.h           |  164 +-
 framework/tsk/framework/extraction/CarveExtract.h  |   84 +-
 framework/tsk/framework/extraction/CarvePrep.h     |   92 +-
 framework/tsk/framework/extraction/TskAutoImpl.cpp |  876 +--
 framework/tsk/framework/extraction/TskAutoImpl.h   |  140 +-
 .../extraction/TskCarveExtractScalpel.cpp          |  778 +-
 .../framework/extraction/TskCarveExtractScalpel.h  |  196 +-
 .../extraction/TskCarvePrepSectorConcat.cpp        |  620 +-
 .../extraction/TskCarvePrepSectorConcat.h          |  270 +-
 .../tsk/framework/extraction/TskImageFile.cpp      |   60 +-
 framework/tsk/framework/extraction/TskImageFile.h  |  406 +-
 .../tsk/framework/extraction/TskImageFileTsk.cpp   |  860 +--
 .../tsk/framework/extraction/TskImageFileTsk.h     |  220 +-
 .../tsk/framework/extraction/TskL01Extract.cpp     |   52 +-
 framework/tsk/framework/file/TskFile.cpp           |  809 +-
 framework/tsk/framework/file/TskFile.h             |  530 +-
 framework/tsk/framework/file/TskFileManager.h      |  486 +-
 .../tsk/framework/file/TskFileManagerImpl.cpp      |  962 +--
 framework/tsk/framework/file/TskFileManagerImpl.h  |  196 +-
 framework/tsk/framework/file/TskFileTsk.cpp        |  616 +-
 framework/tsk/framework/file/TskFileTsk.h          |  192 +-
 framework/tsk/framework/framework_i.h              |   72 +-
 .../tsk/framework/pipeline/TskExecutableModule.cpp |  464 +-
 .../tsk/framework/pipeline/TskExecutableModule.h   |   92 +-
 .../framework/pipeline/TskFileAnalysisPipeline.cpp |  322 +-
 .../framework/pipeline/TskFileAnalysisPipeline.h   |  104 +-
 .../pipeline/TskFileAnalysisPluginModule.cpp       |  200 +-
 .../pipeline/TskFileAnalysisPluginModule.h         |   62 +-
 framework/tsk/framework/pipeline/TskModule.cpp     |  228 +-
 framework/tsk/framework/pipeline/TskModule.h       |  214 +-
 framework/tsk/framework/pipeline/TskPipeline.cpp   |  614 +-
 framework/tsk/framework/pipeline/TskPipeline.h     |  320 +-
 .../tsk/framework/pipeline/TskPipelineManager.cpp  |  394 +-
 .../tsk/framework/pipeline/TskPipelineManager.h    |  126 +-
 .../tsk/framework/pipeline/TskPluginModule.cpp     |  598 +-
 framework/tsk/framework/pipeline/TskPluginModule.h |  204 +-
 .../tsk/framework/pipeline/TskReportPipeline.cpp   |   92 +-
 .../tsk/framework/pipeline/TskReportPipeline.h     |  116 +-
 .../framework/pipeline/TskReportPluginModule.cpp   |  200 +-
 .../tsk/framework/pipeline/TskReportPluginModule.h |   68 +-
 framework/tsk/framework/services/Log.cpp           |  320 +-
 framework/tsk/framework/services/Log.h             |  264 +-
 framework/tsk/framework/services/Scheduler.cpp     |   34 +-
 framework/tsk/framework/services/Scheduler.h       |  152 +-
 framework/tsk/framework/services/TskBlackboard.cpp |  427 +-
 framework/tsk/framework/services/TskBlackboard.h   |  842 ++-
 .../framework/services/TskBlackboardArtifact.cpp   |  198 +-
 .../tsk/framework/services/TskBlackboardArtifact.h |  172 +-
 .../framework/services/TskBlackboardAttribute.cpp  |  530 +-
 .../framework/services/TskBlackboardAttribute.h    |  366 +-
 .../tsk/framework/services/TskDBBlackboard.cpp     |  424 +-
 framework/tsk/framework/services/TskDBBlackboard.h |  200 +-
 framework/tsk/framework/services/TskImgDB.cpp      |  147 +-
 framework/tsk/framework/services/TskImgDB.h        | 1082 +--
 ...skImDBPostgreSQL.cpp => TskImgDBPostgreSQL.cpp} | 7826 ++++++++++----------
 .../{TskImDBPostgreSQL.h => TskImgDBPostgreSQL.h}  |  352 +-
 .../tsk/framework/services/TskImgDBSqlite.cpp      | 7566 +++++++++----------
 framework/tsk/framework/services/TskImgDBSqlite.h  |  362 +-
 .../tsk/framework/services/TskSchedulerQueue.cpp   |   70 +-
 .../tsk/framework/services/TskSchedulerQueue.h     |   62 +-
 framework/tsk/framework/services/TskServices.cpp   |  476 +-
 framework/tsk/framework/services/TskServices.h     |  416 +-
 .../tsk/framework/services/TskSystemProperties.cpp |  548 +-
 .../tsk/framework/services/TskSystemProperties.h   |  806 +-
 .../framework/services/TskSystemPropertiesImpl.cpp |  150 +-
 .../framework/services/TskSystemPropertiesImpl.h   |  180 +-
 framework/tsk/framework/utilities/SectorRuns.cpp   |  278 +-
 framework/tsk/framework/utilities/SectorRuns.h     |  102 +-
 framework/tsk/framework/utilities/TskException.cpp |  130 +-
 framework/tsk/framework/utilities/TskException.h   |  280 +-
 framework/tsk/framework/utilities/TskModuleDev.h   |  142 +-
 framework/tsk/framework/utilities/TskUtilities.cpp |  432 +-
 framework/tsk/framework/utilities/TskUtilities.h   |   78 +-
 framework/tsk/framework/utilities/UnallocRun.cpp   |  118 +-
 framework/tsk/framework/utilities/UnallocRun.h     |   84 +-
 man/ils.1                                          |    6 +-
 man/tsk_comparedir.1                               |   98 +-
 man/tsk_gettimes.1                                 |  100 +-
 man/tsk_loaddb.1                                   |  102 +-
 man/tsk_recover.1                                  |  106 +-
 packages/sleuthkit.spec                            |    2 +-
 tools/autotools/tsk_gettimes.cpp                   |   35 +-
 tools/fiwalk/plugins/jpeg_extract.java             |    2 +-
 tools/fiwalk/src/dfxml.cpp                         |    6 +
 tools/fiwalk/src/fiwalk.cpp                        |   63 +-
 tools/fiwalk/src/fiwalk.h                          |    1 +
 tools/fiwalk/src/hexbuf.c                          |   82 +-
 tools/fiwalk/src/utils.c                           |  228 +-
 tools/fiwalk/src/utils.h                           |  108 +-
 tools/fstools/ils.cpp                              |    4 +-
 tools/srchtools/srch_strings.c                     |   20 +-
 tools/vstools/mmls.cpp                             |   13 +-
 tsk/Makefile.am                                    |    2 +-
 tsk/Makefile.in                                    |    2 +-
 tsk/auto/auto.cpp                                  |   25 +-
 tsk/auto/db_sqlite.cpp                             |   30 +-
 tsk/auto/tsk_auto.h                                |   10 +-
 tsk/auto/tsk_db_sqlite.h                           |    4 +-
 tsk/base/Makefile.am                               |    3 +-
 tsk/base/Makefile.in                               |    3 +-
 tsk/base/crc.c                                     |   44 -
 tsk/base/tsk_base.h                                |   14 +-
 tsk/base/tsk_os.h                                  |    6 +-
 tsk/docs/fs.dox                                    |    2 +-
 tsk/fs/Makefile.am                                 |    1 -
 tsk/fs/Makefile.in                                 |    1 -
 tsk/fs/ext2fs_dent.c                               |    1 +
 tsk/fs/fatfs_dent.cpp                              |    1 +
 tsk/fs/ffs_dent.c                                  |    1 +
 tsk/fs/fls_lib.c                                   |   47 +-
 tsk/fs/fs_attrlist.c                               |    6 +-
 tsk/fs/fs_dir.c                                    |   14 +-
 tsk/fs/fs_file.c                                   |   95 +
 tsk/fs/fs_name.c                                   |  153 +-
 tsk/fs/hfs_dent.c                                  |    1 +
 tsk/fs/ifind_lib.c                                 |    2 +
 tsk/fs/iso9660_dent.c                              |    1 +
 tsk/fs/ntfs.c                                      |   90 +-
 tsk/fs/ntfs_dent.cpp                               |    3 +
 tsk/fs/tsk_fs.h                                    |   32 +-
 tsk/fs/tsk_fs_i.h                                  |    3 +
 tsk/fs/yaffs.cpp                                   |   21 +-
 tsk/hashdb/Makefile.am                             |    2 +-
 tsk/hashdb/Makefile.in                             |    2 +-
 tsk/hashdb/tm_lookup.c                             |   12 +
 tsk/img/Makefile.am                                |    2 +-
 tsk/img/Makefile.in                                |    2 +-
 tsk/img/ewf.c                                      |   26 +-
 tsk/img/img_io.c                                   |  143 +-
 tsk/img/mult_files.c                               |    7 +
 tsk/img/raw.c                                      |   76 +-
 tsk/tsk_config.h.in                                |    6 +
 tsk/vs/Makefile.am                                 |    2 +-
 tsk/vs/Makefile.in                                 |    2 +-
 win32/BUILDING.txt                                 |   60 +-
 win32/blkcalc/blkcalc.vcxproj                      |  112 +
 win32/blkcat/blkcat.vcxproj                        |  112 +
 win32/blkls/blkls.vcxproj                          |  112 +
 win32/blkstat/blkstat.vcxproj                      |  112 +
 .../callback-cpp-sample.vcxproj                    |  109 +
 win32/callback-sample/callback-sample.vcxproj      |  112 +
 win32/docs/README-win32.txt                        |  120 +-
 win32/fcat/fcat.vcxproj                            |  112 +
 win32/ffind/ffind.vcxproj                          |  112 +
 win32/fls/fls.vcxproj                              |  112 +
 win32/fsstat/fsstat.vcxproj                        |  112 +
 win32/hfind/hfind.vcxproj                          |  112 +
 win32/icat/icat.vcxproj                            |  112 +
 win32/ifind/ifind.vcxproj                          |  112 +
 win32/ils/ils.vcxproj                              |  112 +
 win32/img_cat/img_cat.vcxproj                      |  112 +
 win32/img_stat/img_stat.vcxproj                    |  112 +
 win32/istat/istat.vcxproj                          |  112 +
 win32/jcat/jcat.vcxproj                            |  112 +
 win32/jls/jls.vcxproj                              |  112 +
 win32/libtsk/libtsk.vcxproj                        |   96 +-
 win32/mmcat/mmcat.vcxproj                          |  112 +
 win32/mmls/mmls.vcxproj                            |  112 +
 win32/mmstat/mmstat.vcxproj                        |  112 +
 win32/posix-cpp-sample/posix-cpp-sample.vcxproj    |  106 +
 win32/posix-sample/posix-sample.vcxproj            |  112 +
 win32/tsk-win.sln                                  |  183 +
 win32/tsk_comparedir/tsk_compare.vcxproj           |   95 +
 win32/tsk_gettimes/tsk_gettimes.vcxproj            |  104 +
 win32/tsk_jni/tsk_jni.vcxproj                      |  127 +
 win32/tsk_loaddb/tsk_loaddb.vcxproj                |   93 +
 win32/tsk_recover/tsk_recover.vcxproj              |  101 +
 243 files changed, 31941 insertions(+), 26978 deletions(-)

diff --git a/NEWS.txt b/NEWS.txt
index 3371b93..39338f6 100644
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -1,6 +1,38 @@
 Numbers refer to SourceForge.net tracker IDs:
     http://sourceforge.net/tracker/?group_id=55685
 
+---------------- VERSION 4.1.2 --------------
+Core:
+- Fixed more visual studio projects to work on 64-bit
+
+Java: 
+- added method to Image to perform sanity check on image sizes.
+
+fiwalk:
+- Fixed compile error on Linux etc.
+
+
+
+---------------- VERSION 4.1.1 --------------
+Core: 
+- Added FILE_SHARE_WRITE to all windows open calls.
+- removed unused methods in CRC code that caused compile errors.
+- Added NTFS FNAME times to time2 struct in TSK_FS_META to make them 
+  easier to access -- should have done this a long time ago!
+- fls -m and tsk_gettimes output NTFS FNAME times to output for timelines.
+- hfind with EnCase hashsets works when DB is specified (and not only index)
+- TskAuto now goes into UNALLOC partitions by default too. 
+- Added support to automatically find all Cellebrite raw dump files given
+  the name of the first image. 
+- Added 64-bit windows targets to VisualStudio files.
+- Added NTFS sequence to parent address in directory and directory itself.
+- Updated SQLite code to use sequence when finding parent object ID.
+
+Java:
+- Java bindings JAR files now have native libraries in them. 
+- Logical files are added with a transaction 
+
+
 ---------------- VERSION 4.1.0 --------------
 Core:
 - Added YAFFS2 support (patch from viaForensics).
diff --git a/bindings/java/build-unix.xml b/bindings/java/build-unix.xml
index 52e8df9..f145140 100644
--- a/bindings/java/build-unix.xml
+++ b/bindings/java/build-unix.xml
@@ -37,13 +37,50 @@
         <property environment="env"/>
         <copy file="./jni/.libs/libtsk_jni.dylib" tofile="./libtsk_jni.jnilib"/>
     </target>
+	
+	<target name="copyMacLibs" depends="testTSKLibs" if="tsk_dylib.present">
+        <property environment="env"/>
+		<property name="jni.dylib" location="${basedir}/jni/.libs/libtsk_jni.dylib" />
+		<property name="jni.jnilib" value="libtsk_jni.jnilib" />
+		<property name="zlib.jni" location="/usr/lib/libz.dylib"/>
+		<property name="libewf.jni" location="/usr/local/lib/libewf.dylib"/>
+		<!-- x86_64 -->
+        <copy file="${jni.dylib}" tofile="${x86_64}/mac/${jni.jnilib}"/>
+		<copy file="${zlib.jni}" tofile="${x86_64}/mac/zlib.dylib"/>
+		<copy file="${libewf.jni}" tofile="${x86_64}/mac/libewf.dylib"/>
+		<!-- amd64 -->
+		<copy file="${jni.dylib}" tofile="${amd64}/mac/${jni.jnilib}"/>
+		<copy file="${zlib.jni}" tofile="${x86_64}/mac/zlib.dylib"/>
+		<copy file="${libewf.jni}" tofile="${x86_64}/mac/libewf.dylib"/>
+    </target>
 
     <!-- Non-OS X -->
     <target name="copyTskLibs_so" depends="testTSKLibs" if="tsk_so.present">
         <property environment="env"/>
         <copy file="./jni/.libs/libtsk_jni.so" tofile="./libtsk_jni.so"/>
     </target>
+	
+	<target name="copyLinuxLibs" depends="testTSKLibs" if="tsk_so.present">
+		<property environment="env"/>
+		<property name="jni.so" location="${basedir}/jni/.libs/libtsk_jni.so" />
+		<!-- x86_64 -->
+		<copy file="${jni.so}" tofile="${x86_64}/linux/libtsk_jni.so"/>
+		<!-- amd64 -->
+		<copy file="${jni.so}" tofile="${amd64}/linux/libtsk_jni.so"/>
+		<!-- x86 -->
+		<copy file="${jni.so}" tofile="${x86}/linux/libtsk_jni.so"/>
+		<!-- i386 -->
+		<copy file="${jni.so}" tofile="${i386}/linux/libtsk_jni.so"/>
+		<!-- i586 -->
+		<copy file="${jni.so}" tofile="${i586}/linux/libtsk_jni.so"/>
+		<!-- i686 -->
+		<copy file="${jni.so}" tofile="${i686}/linux/libtsk_jni.so"/>
+	</target>
 
+	<target name="copyLibs" depends="copyLinuxLibs,copyMacLibs" />
+	
+	<target name="copyLibsDebug" depends="copyLibs" />
+	
     <target name="copyTSKLibs" depends="copyTskLibs_so,copyTskLibs_dylib">
         <!-- depends targets take care of the actual copying since the file differs on OS X and Linux -->
         <!-- This assumes that TSK, libewf, and zlib have been installed on the system and those libraries will be with normal loading approaches -->
diff --git a/bindings/java/build-windows.xml b/bindings/java/build-windows.xml
index f391200..821ae12 100644
--- a/bindings/java/build-windows.xml
+++ b/bindings/java/build-windows.xml
@@ -33,4 +33,84 @@
 			<sysproperty key="types" value="${test-types}"/>
 		</java>
 	</target>
+	
+	<target name="copyLibs" depends="copyWinLibs" description="Copy native libs to the correct folder">
+		<property name="tsk.config" value="Release"/>
+		<antcall target="copyWinLibs" />
+	</target>
+	
+	<target name="copyLibsDebug" depends="copyWinLibs" description="Copy native libs to the correct folder">
+		<property name="tsk.config" value="Debug"/>
+		<antcall target="copyWinLibs" />
+	</target>
+	
+	<target name="copyWinLibs" depends="copyWinLibs64,copyWinLibs32" description="Copy windows dlls to the correct location." />
+	
+	<target name="checkLibDirs">
+		<available property="win64.exists" type="dir" file="${basedir}/../../win32/x64/${tsk.config}" />
+		<available property="win32.exists" type="dir" file="${basedir}/../../win32/${tsk.config}" />
+	</target>
+	
+	<target name="copyWinLibs64" depends="checkLibDirs" if="win64.exists">
+		<property name="win64dir" location="${basedir}/../../win32/x64/${tsk.config}" />
+		
+		<fileset dir="${win64dir}" id="win64dlls">
+			<include name="*.dll" />
+		</fileset>
+		<fileset dir="${crt}/win64" id="crt64dlls">
+			<include name="*.dll" />
+		</fileset>
+		
+		<copy todir="${amd64}/win" overwrite="true">
+			<fileset refid="win64dlls" />
+		</copy>
+		<copy todir="${amd64}/win" overwrite="true">
+			<fileset refid="crt64dlls" />
+		</copy>
+		
+		<copy todir="${x86_64}/win" overwrite="true">
+			<fileset refid="win64dlls" />
+		</copy>		
+		<copy todir="${x86_64}/win" overwrite="true">
+			<fileset refid="crt64dlls" />
+		</copy>
+	</target>
+	
+	<target name="copyWinLibs32" depends="checkLibDirs" if="win32.exists">
+		<property name="win32dir" location="${basedir}/../../win32/${tsk.config}" />
+		<fileset dir="${win32dir}" id="win32dlls">
+			<include name="*.dll" />
+		</fileset>
+		<fileset dir="${crt}/win32" id="crt32dlls">
+			<include name="*.dll" />
+		</fileset>
+		
+		<copy todir="${i386}/win" overwrite="true">
+			<fileset refid="win32dlls" />
+		</copy>
+		<copy todir="${i386}/win" overwrite="true">
+			<fileset refid="crt32dlls" />
+		</copy>
+		
+		<copy todir="${x86}/win" overwrite="true">
+			<fileset refid="win32dlls" />
+		</copy>
+		<copy todir="${x86}/win" overwrite="true">
+			<fileset refid="crt32dlls" />
+		</copy>
+		
+		<copy todir="${i586}/win" overwrite="true">
+			<fileset refid="win32dlls" />
+		</copy>
+		<copy todir="${i586}/win" overwrite="true">
+			<fileset refid="crt32dlls" />
+		</copy>		
+		
+		<copy todir="${i686}/win" overwrite="true">
+			<fileset refid="win32dlls" />
+		</copy>
+		<copy todir="${i686}/win" overwrite="true">
+			<fileset refid="crt32dlls" />
+		</copy>	
+	</target>
 </project>
diff --git a/bindings/java/build.xml b/bindings/java/build.xml
index 2cf1362..dcd3a31 100755
--- a/bindings/java/build.xml
+++ b/bindings/java/build.xml
@@ -20,6 +20,14 @@
 	<property name="test-results" location="test/output/results"/>
 	<property name="test-input" location="test/input"/>
 	<property name="test-types" location="test/org/sleuthkit/datamodel"/>
+	<property name="native-libs" location="build/NATIVELIBS" />
+	<property name="amd64" location="build/NATIVELIBS/amd64" />
+	<property name="x86" location="build/NATIVELIBS/x86" />
+	<property name="x86_64" location="build/NATIVELIBS/x86_64" />
+	<property name="i386" location="build/NATIVELIBS/i386" />
+	<property name="i586" location="build/NATIVELIBS/i586" />
+	<property name="i686" location="build/NATIVELIBS/i686"/>
+	<property name="crt" location="${basedir}/crt" />
   
 	<path id="libraries">
 		<fileset dir="${lib}">
@@ -28,7 +36,7 @@
 		<pathelement path="${build}"/>
 	</path>
 
-
+	<!-- Only added win folders for now -->
 	<target name="init">
 		<mkdir dir="${build}"/>
 		<mkdir dir="${dist}"/>
@@ -36,6 +44,27 @@
 		<mkdir dir="${test-input}"/>
 		<mkdir dir="${test-standards}"/>
 		<mkdir dir="${test-results}"/>
+		<mkdir dir="${native-libs}" />
+		<mkdir dir="${amd64}" />
+		<mkdir dir="${amd64}/win" />
+		<mkdir dir="${amd64}/mac" />
+		<mkdir dir="${amd64}/linux" />
+	    <mkdir dir="${x86}" />
+		<mkdir dir="${x86}/win" />
+		<mkdir dir="${x86}/linux" />
+		<mkdir dir="${x86_64}" />
+		<mkdir dir="${x86_64}/win" />
+		<mkdir dir="${x86_64}/mac" />
+		<mkdir dir="${x86_64}/linux"/>
+		<mkdir dir="${i386}" />
+		<mkdir dir="${i386}/win" />
+		<mkdir dir="${i386}/linux"/>
+		<mkdir dir="${i586}" />
+		<mkdir dir="${i586}/win" />
+		<mkdir dir="${i586}/linux" />
+		<mkdir dir="${i686}"/>
+		<mkdir dir="${i686}/win"/>
+		<mkdir dir="${i686}/linux"/>
 	</target>
   
 	<property name="ivy.install.version" value="2.3.0-rc2" />
@@ -46,7 +75,6 @@
 	<property name="ivy.jar.dir" value="${ivy.home}/lib" />
 	<property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar" />
 
-
 	<target name="download-ivy" unless="offline">
         <available file="${ivy.jar.file}" property="ivy.available"/>
         <antcall target="-download-ivy" />
@@ -88,12 +116,20 @@ pattern="lib/[artifact]-[revision](-[classifier]).[ext]" />
 		</javac>
 	</target>
 
-	<target name="dist" depends="init-ivy, compile"
+	<target name="dist" depends="init-ivy, compile, copyLibs"
+        description="generate the distribution" >
+    <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
+		<jar jarfile="${dist}/Tsk_DataModel.jar" basedir="${build}"/>
+	</target>
+	
+	<target name="dist-debug" depends="init-ivy, compile, copyLibsDebug"
         description="generate the distribution" >
     <!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
 		<jar jarfile="${dist}/Tsk_DataModel.jar" basedir="${build}"/>
 	</target>
   
+	
+	
 	<target name="jni" depends="compile" description="make the jni.h file">
 		<javah classpath = "${build}" outputFile="jni/dataModel_SleuthkitJNI.h" force="yes">
 			<class name="org.sleuthkit.datamodel.SleuthkitJNI"/>
diff --git a/bindings/java/doxygen/main.dox b/bindings/java/doxygen/main.dox
index d05b412..7a5d8dc 100644
--- a/bindings/java/doxygen/main.dox
+++ b/bindings/java/doxygen/main.dox
@@ -8,6 +8,26 @@ The Sleuth Kit is primarily a C/C++ library and set of command line tools. These
 
 Expand on this to mention what classes to use, etc.
 
+\section jni_hierarchy Class Hierarchy
+
+Flush out here on general layout. 
+
+- org.sleuthkit.datamodel.Content is top-level interface and gets more specific as it goes down.
+- Types disk and file system organization concepts (org.sleuthkit.datamodel.FileSystem, org.sleuthkit.datamodel.Image, etc. )
+- org.sleuthkit.datamodel.AbstractFile is interface for various types of files with more specific classes below it ( org.sleuthkit.datamodel.DerivedFile, org.sleuthkit.datamodel.FsContent, etc.)
+
+\section jni_blackboard The Blackboard
+
+The blackboard in the database is used to communicate with modules in The Sleuth Kit framework and in Autopsy.  The blackboard concepts are described in the framework documentation (http://sleuthkit.org/sleuthkit/docs/framework-docs/mod_bbpage.html).
+This section provides a high-level overview of the relevant topics from the Java perspective (since the previous document focuses on the C++ APIs). 
+
+To make an artifact, one first calls the org.sleuthkit.datamodel.AbstractContent.newArtifact() method for the object that the artifact is being added to.  This returns a org.sleuthkit.datamodel.BlackboardArtifact object.  Attributes of type org.sleuthkit.datamodel.BlackboardAttribute are then created and added to the artifact.  
+
+To find artifacts, you have two general options.  If you have an org.sleuthkit.datamodel.AbstractContent object or a derived object, then you can use the org.sleuthkit.datamodel.AbstractContent.getArtifacts() methods to perform various queries. If you want artifacts beyond those for a single file, then you must use the various org.sleuthkit.datamodel.SleuthkitCase.getBlackboardArtifacts() methods.
+
+If you want to create an artifact type that is not defined in the framework/bindings, then use org.sleuthkit.datamodel.SleuthkitCase.addArtifactType() to define the type.  This will return back an artifact ID that you can pass in to create actual artifacts.  Note that each database instance could assign a different ID for the custom attributes and artifacts.  It all depends on what modules were run before it and if they added their own types.  Later modules will need the ID of the new ty [...]
+
+
 */
 
 
diff --git a/bindings/java/jni/dataModel_SleuthkitJNI.cpp b/bindings/java/jni/dataModel_SleuthkitJNI.cpp
index c998e9c..5804785 100644
--- a/bindings/java/jni/dataModel_SleuthkitJNI.cpp
+++ b/bindings/java/jni/dataModel_SleuthkitJNI.cpp
@@ -485,9 +485,20 @@ JNIEXPORT jlong JNICALL
         return 0;
     }
 
-    tskAuto->setAddUnallocSpace(addUnallocSpace?true:false);
+    // set the options flags
+    if (addUnallocSpace) {
+        tskAuto->setAddUnallocSpace(true, 500*1024*1024);
+    }
+    else {
+        tskAuto->setAddUnallocSpace(false);
+    }
     tskAuto->setNoFatFsOrphans(noFatFsOrphans?true:false);
-	tskAuto->setAddUnallocSpace(true, 500000000);
+
+    // we don't use the block map and it slows it down
+    tskAuto->createBlockMap(false);
+
+    // ingest modules calc hashes
+    tskAuto->hashFiles(false);
 
     return (jlong) tskAuto;
 }
@@ -518,10 +529,6 @@ JNIEXPORT void JNICALL
         return;
     }
 
-    //change to true when autopsy needs the block table.
-    tskAuto->createBlockMap(false);
-    //change to false if hashes aren't needed
-    tskAuto->hashFiles(false);
 
     // move the strings into the C++ world
 
diff --git a/bindings/java/src/org/sleuthkit/datamodel/AbstractContent.java b/bindings/java/src/org/sleuthkit/datamodel/AbstractContent.java
index f1e5641..d618e91 100755
--- a/bindings/java/src/org/sleuthkit/datamodel/AbstractContent.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/AbstractContent.java
@@ -31,7 +31,7 @@ import org.sleuthkit.datamodel.SleuthkitCase.ObjectInfo;
 public abstract class AbstractContent implements Content {
 
 	public final static long UNKNOWN_ID = -1;
-	private SleuthkitCase db;
+	private final SleuthkitCase db;
 	private long objId;
 	private String name;
 	private Content parent;
@@ -208,6 +208,18 @@ public abstract class AbstractContent implements Content {
 	public ArrayList<BlackboardArtifact> getArtifacts(BlackboardArtifact.ARTIFACT_TYPE type) throws TskCoreException {
 		return db.getBlackboardArtifacts(type, objId);
 	}
+	
+	@Override
+	public BlackboardArtifact getGenInfoArtifact() throws TskCoreException {
+		ArrayList<BlackboardArtifact> arts = getArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO);
+		if (arts.isEmpty()) {
+			BlackboardArtifact art = newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_GEN_INFO);
+			return art;
+		}
+		else {
+			return arts.get(0);
+		}
+	}
 
 	@Override
 	public ArrayList<BlackboardArtifact> getAllArtifacts() throws TskCoreException {
diff --git a/bindings/java/src/org/sleuthkit/datamodel/AbstractFile.java b/bindings/java/src/org/sleuthkit/datamodel/AbstractFile.java
index a78ce64..1821f76 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/AbstractFile.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/AbstractFile.java
@@ -169,7 +169,7 @@ public abstract class AbstractFile extends AbstractContent {
 	}
 
 	/**
-	 * Get the change time as Date
+	 * Get the change time as Date (in local timezone)
 	 *
 	 * @return change time as Date
 	 */
@@ -187,7 +187,7 @@ public abstract class AbstractFile extends AbstractContent {
 	}
 
 	/**
-	 * Get the creation time as Date
+	 * Get the creation time as Date (in local timezone)
 	 *
 	 * @return creation time as Date
 	 */
@@ -205,7 +205,7 @@ public abstract class AbstractFile extends AbstractContent {
 	}
 
 	/**
-	 * Get the access time as Date
+	 * Get the access time as Date (in local timezone)
 	 *
 	 * @return access time as Date
 	 */
@@ -223,7 +223,7 @@ public abstract class AbstractFile extends AbstractContent {
 	}
 
 	/**
-	 * Get the modified time as Date
+	 * Get the modified time as Date (in local timezone)
 	 *
 	 * @return modified time as Date
 	 */
@@ -694,7 +694,7 @@ public abstract class AbstractFile extends AbstractContent {
 					try {
 						localFileHandle = new RandomAccessFile(localFile, "r");
 					} catch (FileNotFoundException ex) {
-						final String msg = "Error reading local file: " + this.toString();
+						final String msg = "Error reading local file: " + localAbsPath;
 						logger.log(Level.SEVERE, msg, ex);
 						//file could have been deleted or moved
 						throw new TskCoreException(msg, ex);
@@ -712,7 +712,7 @@ public abstract class AbstractFile extends AbstractContent {
 			//note, we are always writing at 0 offset of user buffer
 			bytesRead = localFileHandle.read(buf, 0, (int) len);
 		} catch (IOException ex) {
-			final String msg = "Cannot read local file: " + this.toString();
+			final String msg = "Cannot read local file: " + localAbsPath;
 			logger.log(Level.SEVERE, msg, ex);
 			//local file could have been deleted / moved
 			throw new TskCoreException(msg, ex);
@@ -828,7 +828,7 @@ public abstract class AbstractFile extends AbstractContent {
 					try {
 						localFileHandle.close();
 					} catch (IOException ex) {
-						logger.log(Level.SEVERE, "Could not close file handle for file: " + this.toString(), ex);
+						logger.log(Level.SEVERE, "Could not close file handle for file: " + getParentPath() + "/" + getName(), ex);
 					}
 					localFileHandle = null;
 				}
@@ -881,7 +881,7 @@ public abstract class AbstractFile extends AbstractContent {
 	public static String epochToTime(long epoch) {
 		String time = "0000-00-00 00:00:00";
 		if (epoch != 0) {
-			time = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date(epoch * 1000));
+			time = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss z").format(new java.util.Date(epoch * 1000));
 		}
 		return time;
 	}
diff --git a/bindings/java/src/org/sleuthkit/datamodel/BlackboardArtifact.java b/bindings/java/src/org/sleuthkit/datamodel/BlackboardArtifact.java
index 0cec254..d36970d 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/BlackboardArtifact.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/BlackboardArtifact.java
@@ -43,12 +43,12 @@ public class BlackboardArtifact implements SleuthkitVisitableItem {
 	public enum ARTIFACT_TYPE implements SleuthkitVisitableItem {
 
 		TSK_GEN_INFO(1, "TSK_GEN_INFO", "General Info"), ///< Default type
-		TSK_WEB_BOOKMARK(2, "TSK_WEB_BOOKMARK", "Bookmarks"), ///< web bookmarks
-		TSK_WEB_COOKIE(3, "TSK_WEB_COOKIE", "Cookies"), ///< web cookies
+		TSK_WEB_BOOKMARK(2, "TSK_WEB_BOOKMARK", "Web Bookmarks"), ///< web bookmarks
+		TSK_WEB_COOKIE(3, "TSK_WEB_COOKIE", "Web Cookies"), ///< web cookies
 		TSK_WEB_HISTORY(4, "TSK_WEB_HISTORY", "Web History"), ///< web history
-		TSK_WEB_DOWNLOAD(5, "TSK_WEB_DOWNLOAD", "Downloads"), ///< web downloads
+		TSK_WEB_DOWNLOAD(5, "TSK_WEB_DOWNLOAD", "Web Downloads"), ///< web downloads
 		TSK_RECENT_OBJECT(6, "TSK_RECENT_OBJ", "Recent Documents"), ///< recent objects 
-		TSK_TRACKPOINT(7, "TSK_TRACKPOINT", "Trackpoints"), ///< trackpoint (geo location data)
+		TSK_GPS_TRACKPOINT(7, "TSK_GPS_TRACKPOINT", "GPS Trackpoints"), ///< trackpoint (geo location data)
 		TSK_INSTALLED_PROG(8, "TSK_INSTALLED_PROG", "Installed Programs"), ///< installed programs
 		TSK_KEYWORD_HIT(9, "TSK_KEYWORD_HIT", "Keyword Hits"), ///< keyword search hits
 		TSK_HASHSET_HIT(10, "TSK_HASHSET_HIT", "Hashset Hits"), ///< hashset hits
@@ -56,14 +56,26 @@ public class BlackboardArtifact implements SleuthkitVisitableItem {
 		TSK_INTERESTING_FILE_HIT(12, "TSK_INTERESTING_FILE_HIT", "Interesting Files"), ///< an interesting/notable file hit
 		TSK_EMAIL_MSG(13, "TSK_EMAIL_MSG", "E-Mail Messages"), ///< email message
 		TSK_EXTRACTED_TEXT(14, "TSK_EXTRACTED_TEXT", "Extracted Text"), ///< text extracted from file
-		TSK_WEB_SEARCH_QUERY(15, "TSK_WEB_SEARCH_QUERY", "Web Search Engine Queries"), ///< web search engine query extracted from web history
+		TSK_WEB_SEARCH_QUERY(15, "TSK_WEB_SEARCH_QUERY", "Web Search"), ///< web search engine query extracted from web history
 		TSK_METADATA_EXIF(16, "TSK_METADATA_EXIF", "EXIF Metadata"), ///< EXIF Metadata
 		TSK_TAG_FILE(17, "TSK_TAG_FILE", "File Tags"), ///< tagged files
 		TSK_TAG_ARTIFACT(18, "TSK_TAG_ARTIFACT", "Result Tags"), ///< tagged results/artifacts
 		TSK_OS_INFO(19, "TSK_OS_INFO", "Operating System Information"), ///< Information pertaining to an operating system.
 		TSK_OS_ACCOUNT(20, "TSK_OS_ACCOUNT", "Operating System User Account"), ///< An operating system user account.
-		TSK_SERVICE_ACCOUNT(21, "TSK_SERVICE_ACCOUNT", "Network Service User Account"), ///< A network service user account.
-        ; 
+		TSK_SERVICE_ACCOUNT(21, "TSK_SERVICE_ACCOUNT", "Accounts"), ///< An application/service/web user account.
+        TSK_TOOL_OUTPUT(22, "TSK_TOOL_OUTPUT", "Raw Tool Output"), ///< Output from an external tool or module that (raw text)
+		TSK_CONTACT(23, "TSK_CONTACT", "Contacts"), ///< A Contact extracted from a phone, or from an Addressbook/Email/Messaging Application
+		TSK_MESSAGE(24, "TSK_MESSAGE", "Messages"), ///< An SMS/MMS message extracted from phone, or from another messaging application, like IM
+		TSK_CALLLOG(25, "TSK_CALLLOG", "Call Logs"), ///< A Phone call log extracted from a phones or softphone application
+		TSK_CALENDAR_ENTRY(26, "TSK_CALENDAR_ENTRY", "Calendar Entries"), ///< A Calendar entry from a phone, PIM or a Calendar application.
+		TSK_SPEED_DIAL_ENTRY(27, "TSK_SPEED_DIAL_ENTRY", "Speed Dial Entries"), ///< A speed dial entry from a phone 
+		TSK_BLUETOOTH_PAIRING(28, "TSK_BLUETOOTH_PAIRING", "BlueTooth Pairings"), ///< A bluetooth pairing entry
+		TSK_GPS_BOOKMARK(29, "TSK_GPS_BOOKMARK", "GPS Bookmarks"),	// GPS Bookmarks
+		TSK_GPS_LAST_KNOWN_LOCATION(30, "TSK_GPS_LAST_KNOWN_LOCATION", "GPS Last Known Location"),	// GPS Last known location
+		TSK_GPS_SEARCH(31, "TSK_GPS_SEARCH", "GPS Searches"),	// GPS Searches
+		 
+		
+		; 
 		/* SEE ABOVE -- KEEP C++ CODE IN SYNC */
 		private String label;
 		private int typeID;
diff --git a/bindings/java/src/org/sleuthkit/datamodel/BlackboardAttribute.java b/bindings/java/src/org/sleuthkit/datamodel/BlackboardAttribute.java
index 8da3706..8ba434f 100755
--- a/bindings/java/src/org/sleuthkit/datamodel/BlackboardAttribute.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/BlackboardAttribute.java
@@ -169,6 +169,29 @@ public class BlackboardAttribute {
 		TSK_PROCESSOR_ARCHITECTURE(70, "TSK_PROCESSOR_ARCHITECTURE", "Processor Architecture"),
 		TSK_VERSION(71, "TSK_VERSION", "Version"),
 		TSK_USER_ID(72, "TSK_USER_ID", "User ID"),
+		TSK_DESCRIPTION(73, "TSK_DESCRIPTION", "Description"),
+		TSK_MESSAGE_TYPE(74, "TSK_MESSAGE_TYPE", "Message Type"),	// SMS or MMS or IM ...
+		TSK_PHONE_NUMBER_HOME(75, "TSK_PHONE_NUMBER_HOME", "Phone Number (Home)"),
+		TSK_PHONE_NUMBER_OFFICE(76, "TSK_PHONE_NUMBER_OFFICE", "Phone Number (Office)"),
+		TSK_PHONE_NUMBER_MOBILE(77, "TSK_PHONE_NUMBER_MOBILE", "Phone Number (Mobile)"),
+		TSK_PHONE_NUMBER_FROM(78, "TSK_PHONE_NUMBER_FROM", "From Phone Number"),
+		TSK_PHONE_NUMBER_TO(79, "TSK_PHONE_NUMBER_TO", "To Phone Number"),
+		TSK_DIRECTION(80, "TSK_DIRECTION", "Direction"), // Msg/Call direction: incoming, outgoing
+		TSK_EMAIL_HOME(81, "TSK_EMAIL_HOME", "Email (Home)"),
+		TSK_EMAIL_OFFICE(82, "TSK_EMAIL_OFFICE", "Email (Office)"),
+		TSK_DATETIME_START(83, "TSK_DATETIME_START", "Start Date/Time"),	// start time of an event - call log, Calendar entry
+		TSK_DATETIME_END(84, "TSK_DATETIME_END", "End Date/Time"),	// end time of an event - call log, Calendar entry
+		TSK_CALENDAR_ENTRY_TYPE(85, "TSK_CALENDAR_ENTRY_TYPE", "Calendar Entry Type"),	// meeting, task, 
+		TSK_LOCATION(86, "TSK_LOCATION", "Location"),	// Location string associated with an event - Conf Room Name, Address ....
+		TSK_SHORTCUT(87, "TSK_SHORTCUT", "Short Cut"),	// Short Cut string - short code or dial string for Speed dial, a URL short cut - e.g. bitly string, Windows Desktop Short cut name etc.
+		TSK_DEVICE_NAME(88, "TSK_DEVICE_NAME", "Device Name"),	// device name - a user assigned (usually) device name - such as "Joe's computer", "bob_win8", "BT Headset"
+		TSK_CATEGORY(89, "TSK_CATEGORY", "Category"),	// category/type, possible value set varies by the artifact
+		TSK_EMAIL_REPLYTO(90, "TSK_EMAIL_REPLYTO", "ReplyTo Address"),	// ReplyTo address
+		TSK_SERVER_NAME(91, "TSK_SERVER_NAME", "Server Name"),	// server name, e.g. a mail server name - "smtp.google.com", a DNS server name...
+		
+		
+		
+		
 		;
 		/* SEE ABOVE -- ALSO ADD TO C++ CODE */
 		private String label;
diff --git a/bindings/java/src/org/sleuthkit/datamodel/Content.java b/bindings/java/src/org/sleuthkit/datamodel/Content.java
index e918e70..ac3b8bd 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/Content.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/Content.java
@@ -23,15 +23,21 @@ import java.util.List;
 
 /**
  * Interface for all datatypes that can be found in the database.
+ * Content objects make up a tree and each object can have a parent
+ * and children.  For example, the child of an Image object is a 
+ * Volume or File System.  This interface defines the basic methods for
+ * reading the content associated with this object, the parent and children,
+ * and adding artifacts. 
  */
 public interface Content extends SleuthkitVisitableItem {
 
 	/**
-	 * Read data from the content object
+	 * Reads data that this content object is associated with (file contents, 
+	 * volume contents, etc.).
 	 *
 	 * @param buf a character array of data (in bytes) to copy read data to
-	 * @param offset offset in the content to start reading from
-	 * @param len amount of data to read (in bytes)
+	 * @param offset byte offset in the content to start reading from
+	 * @param len number of bytes to read into buf. 
 	 * @return num of bytes read, or -1 on error
 	 * @throws TskCoreException if critical error occurred during read in the
 	 * tsk core
@@ -46,7 +52,9 @@ public interface Content extends SleuthkitVisitableItem {
 	public void close();
 
 	/**
-	 * Get the size of the content
+	 * Get the (reported) size of the content object and, in theory, how
+	 * much you should be able to read from it.  In some cases, data corruption
+	 * may mean that you cannot read this much data.
 	 *
 	 * @return size of the content
 	 */
@@ -61,7 +69,7 @@ public interface Content extends SleuthkitVisitableItem {
 	public <T> T accept(ContentVisitor<T> v);
 
 	/**
-	 * Get the name of this content object
+	 * Get the name of this content object (does not include parent path)
 	 *
 	 * @return the name
 	 */
@@ -75,7 +83,8 @@ public interface Content extends SleuthkitVisitableItem {
 	public String getUniquePath() throws TskCoreException;
 
 	/**
-	 * Gets the content object id.
+	 * Returns the unique object ID that was assigned to it in the database.
+	 * This is a Sleuth Kit database-assigned number.
 	 *
 	 * @return object id
 	 */
@@ -163,6 +172,16 @@ public interface Content extends SleuthkitVisitableItem {
 	 */
 	public ArrayList<BlackboardArtifact> getArtifacts(String artifactTypeName) throws TskCoreException;
 
+	
+	/**
+	 * Return the TSK_GEN_INFO artifact for the file so that individual attributes 
+	 * can be added to it.
+	 * 
+	 * @returna Instance of the TSK_GEN_INFO artifact
+	 * @throws TskCoreException 
+	 */
+	public BlackboardArtifact getGenInfoArtifact() throws TskCoreException;
+	
 	/**
 	 * Get all artifacts associated with this content that have the given type
 	 * id
diff --git a/bindings/java/src/org/sleuthkit/datamodel/FsContent.java b/bindings/java/src/org/sleuthkit/datamodel/FsContent.java
index ac171bf..c229d97 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/FsContent.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/FsContent.java
@@ -18,8 +18,6 @@
  */
 package org.sleuthkit.datamodel;
 
-import java.util.Collections;
-import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import org.sleuthkit.datamodel.TskData.FileKnown;
@@ -42,6 +40,8 @@ public abstract class FsContent extends AbstractFile {
 	protected final long fsObjId;
 	private String uniquePath;
 	///read-write database tsk_files fields
+	private final SleuthkitCase tskCase;
+	
 	/**
 	 * parent file system
 	 */
@@ -84,6 +84,7 @@ public abstract class FsContent extends AbstractFile {
 			long size, long ctime, long crtime, long atime, long mtime, short modes, int uid, int gid, String md5Hash, FileKnown knownState,
 			String parentPath) {
 		super(db, objId, attrType, attrId, name, TskData.TSK_DB_FILES_TYPE_ENUM.FS, metaAddr, dirType, metaType, dirFlag, metaFlags, size, ctime, crtime, atime, mtime, modes, uid, gid, md5Hash, knownState, parentPath);
+		this.tskCase = db;
 		this.fsObjId = fsObjId;
 	}
 
@@ -123,18 +124,26 @@ public abstract class FsContent extends AbstractFile {
 
 	@Override
 	protected int readInt(byte[] buf, long offset, long len) throws TskCoreException {
-		if (offset == 0 && size == 0) {
-			//special case for 0-size file
-			return 0;
-		}
-		if (fileHandle == 0) {
-			synchronized (this) {
-				if (fileHandle == 0) {
-					fileHandle = SleuthkitJNI.openFile(getFileSystem().getFileSystemHandle(), metaAddr, attrType, attrId);
+		try {
+			if (offset == 0 && size == 0) {
+				//special case for 0-size file
+				return 0;
+			}
+			if (fileHandle == 0) {
+				synchronized (this) {
+					if (fileHandle == 0) {
+						fileHandle = SleuthkitJNI.openFile(getFileSystem().getFileSystemHandle(), metaAddr, attrType, attrId);
+					}
 				}
 			}
+			return SleuthkitJNI.readFile(fileHandle, buf, offset, len);
+		}
+		catch (TskCoreException ex) {
+			if (!getImage().imageFileExists()) {
+				tskCase.submitError("Image File Read Error", "Image file is does not exist or is inaccessible.");
+			}
+			throw ex;
 		}
-		return SleuthkitJNI.readFile(fileHandle, buf, offset, len);
 	}
 
 	@Override
diff --git a/bindings/java/src/org/sleuthkit/datamodel/Image.java b/bindings/java/src/org/sleuthkit/datamodel/Image.java
index 3c025b5..9df8d40 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/Image.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/Image.java
@@ -1,7 +1,7 @@
 /*
  * Autopsy Forensic Browser
  * 
- * Copyright 2011 Basis Technology Corp.
+ * Copyright 2011-2013 Basis Technology Corp.
  * Contact: carrier <at> sleuthkit <dot> org
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,10 +23,11 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import java.io.File;
 
 /**
  * Represents a disk image file, stored in tsk_image_info. Populated based on
- * data in database.
+ * data in database.  
  *
  * Caches internal tsk image handle and reuses it for reads
  */
@@ -122,8 +123,8 @@ public class Image extends AbstractContent {
 	 *
 	 * @return image type
 	 */
-	public long getType() {
-		return type;
+	public TskData.TSK_IMG_TYPE_ENUM getType() {
+		return TskData.TSK_IMG_TYPE_ENUM.valueOf(type);
 	}
 
 	/**
@@ -204,93 +205,6 @@ public class Image extends AbstractContent {
 		return timezone;
 	}
 
-	// ----- Methods for Image Type conversion / mapping -----
-	/**
-	 * Convert image type id to string value
-	 *
-	 * @param imageType to convert
-	 * @return string representation of the image type
-	 */
-	public static String imageTypeToValue(long imageType) {
-
-		String result = "";
-
-		for (TskData.TSK_IMG_TYPE_ENUM imgType : TskData.TSK_IMG_TYPE_ENUM.values()) {
-			if (imgType.getImageType() == imageType) {
-				result = imgType.toString();
-			}
-		}
-		return result;
-	}
-
-	/**
-	 * Convert image type value string to image type id
-	 *
-	 * @param imageType value string to convert
-	 * @return image type id
-	 */
-	public static long valueToImageType(String imageType) {
-
-		long result = 0;
-
-		for (TskData.TSK_IMG_TYPE_ENUM imgType : TskData.TSK_IMG_TYPE_ENUM.values()) {
-			if (imgType.toString().equals(imageType)) {
-				result = imgType.getImageType();
-			}
-		}
-		return result;
-	}
-
-	/**
-	 * Convert image type id to string representation
-	 *
-	 * @param imageType to convert
-	 * @return user-readable string representation of the image type
-	 */
-	public static String imageTypeToString(long imageType) {
-
-		String result = "";
-
-		long detect = TskData.TSK_IMG_TYPE_ENUM.TSK_IMG_TYPE_DETECT.getImageType();
-		long raw = TskData.TSK_IMG_TYPE_ENUM.TSK_IMG_TYPE_RAW_SING.getImageType();
-		long split = TskData.TSK_IMG_TYPE_ENUM.TSK_IMG_TYPE_RAW_SPLIT.getImageType();
-		long aff = TskData.TSK_IMG_TYPE_ENUM.TSK_IMG_TYPE_AFF_AFF.getImageType();
-		long afd = TskData.TSK_IMG_TYPE_ENUM.TSK_IMG_TYPE_AFF_AFD.getImageType();
-		long afm = TskData.TSK_IMG_TYPE_ENUM.TSK_IMG_TYPE_AFF_AFM.getImageType();
-		long afflib = TskData.TSK_IMG_TYPE_ENUM.TSK_IMG_TYPE_AFF_ANY.getImageType();
-		long ewf = TskData.TSK_IMG_TYPE_ENUM.TSK_IMG_TYPE_EWF_EWF.getImageType();
-		long unsupported = TskData.TSK_IMG_TYPE_ENUM.TSK_IMG_TYPE_UNSUPP.getImageType();
-
-		if (imageType == detect) {
-			result = "Auto Detection";
-		}
-		if (imageType == raw) {
-			result = "Single raw file (dd)";
-		}
-		if (imageType == split) {
-			result = "Split raw files";
-		}
-		if (imageType == aff) {
-			result = "Advanced Forensic Format";
-		}
-		if (imageType == afd) {
-			result = "AFF Multiple File";
-		}
-		if (imageType == afm) {
-			result = "AFF with external metadata";
-		}
-		if (imageType == afflib) {
-			result = "All AFFLIB image formats (including beta ones)";
-		}
-		if (imageType == ewf) {
-			result = "Expert Witness format (encase)";
-		}
-		if (imageType == unsupported) {
-			result = "Unsupported Image Type";
-		}
-
-		return result;
-	}
 
 	@Override
 	public <T> T accept(SleuthkitItemVisitor<T> v) {
@@ -315,4 +229,68 @@ public class Image extends AbstractContent {
 	public String toString(boolean preserveState){
 		return super.toString(preserveState) + "Image [\t" + "\t" + "paths " + Arrays.toString(paths) + "\t" + "size " + size + "\t" + "ssize " + ssize + "\t" + "timezone " + timezone + "\t" + "type " + type + "]\t";
 	}
+	
+	/**
+	 * Test if the image represented by this object exists on disk. 
+	 * @return True if the file still exists
+	 */
+	public Boolean imageFileExists() {
+		if (paths.length > 0) {
+			File imageFile = new File(paths[0]);
+			return imageFile.exists();
+		}
+		
+		return false;
+	}
+	
+	/**
+     * Perform some sanity checks on the bounds of the image contents to 
+     * determine if we could be missing some pieces of the image. 
+     * 
+     * @returns String of error messages to display to user or empty string if there are no errors 
+     */
+    public String verifyImageSize() {
+        Logger logger1 = Logger.getLogger("verifyImageSizes");
+        String errorString = "";
+        try {
+            List<VolumeSystem> volumeSystems = getVolumeSystems();
+            for (VolumeSystem vs : volumeSystems) {
+                List<Volume> volumes = vs.getVolumes();
+                for (Volume v : volumes) {
+                    byte[] buf = new byte[512];
+                    long endOffset = (v.getStart() + v.getLength()) * 512 - 512;
+                    try {
+                        int readBytes = read(buf, endOffset, 512);
+                        if (readBytes < 0) {
+                            logger1.warning("Possible Incomplete Image: Error reading volume at offset " + endOffset);
+                            errorString = "\nPossible Incomplete Image: Error reading volume at offset " + endOffset;
+                        }
+                    } catch (TskCoreException ex) {
+                        logger1.warning("Possible Incomplete Image: Error reading volume at offset " + endOffset + ": " + ex.getLocalizedMessage());
+                        errorString = "\nPossible Incomplete Image: Error reading volume at offset " + endOffset;
+                    }
+                }
+            }
+            
+            List<FileSystem> fileSystems = getFileSystems();
+            for (FileSystem fs : fileSystems) {
+                long block_size = fs.getBlock_size();
+                long endOffset = fs.getImageOffset() + fs.getSize() - block_size;
+                try {
+                    byte[] buf = new byte[(int) block_size];
+                    int readBytes = read(buf, endOffset, block_size);
+                    if (readBytes < 0) {
+                        logger1.warning("Possible Incomplete Image: Error reading file system at offset " + endOffset);
+                        errorString = "\nPossible Incomplete Image: Error reading file system at offset " + endOffset;
+                    }
+                } catch (TskCoreException ex) {
+                    logger1.warning("Possible Incomplete Image: Error reading file system at offset " + endOffset + ": " + ex.getLocalizedMessage());
+                    errorString = "\nPossible Incomplete Image: Error reading file system at offset " + endOffset;
+                }
+            }
+        } catch (TskException ex) {
+            // do nothing if we got an exception from trying to get file systems and volume systems
+        }
+        return errorString;
+    }
 }
diff --git a/bindings/java/src/org/sleuthkit/datamodel/LibraryUtils.java b/bindings/java/src/org/sleuthkit/datamodel/LibraryUtils.java
new file mode 100644
index 0000000..dd7e506
--- /dev/null
+++ b/bindings/java/src/org/sleuthkit/datamodel/LibraryUtils.java
@@ -0,0 +1,268 @@
+/*
+ * Sleuth Kit Data Model
+ * 
+ * Copyright 2013 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.datamodel;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Collection of methods to load libraries embedded in the TSK Datamodel Jar file.
+ * 
+ * @author jwallace
+ */
+public class LibraryUtils {
+	
+	public static final String[] EXTS = new String[] { ".so", ".dylib", ".dll", ".jnilib" };
+	
+	public static final Lib[] CRT_LIBS = new Lib[] { Lib.MSVCP, Lib.MSVCR };
+	
+	public static final Lib[] OTHER_LIBS = new Lib[] { Lib.ZLIB, Lib.LIBEWF };
+
+	/**
+	 * The libraries the TSK Datamodel needs.
+	 */
+	public enum Lib {
+		MSVCP ("msvcp100", ""),
+		MSVCR ("msvcr100", ""),
+		ZLIB ("zlib", "z"),
+		LIBEWF ("libewf", "ewf"),
+		TSK_JNI ("libtsk_jni", "tsk_jni");
+		
+		private final String name;
+		private final String unixName;
+		
+		Lib(String name, String unixName) {
+			this.name = name;
+			this.unixName = unixName;
+		}
+		
+		public String getLibName() {
+			return this.name;
+		}
+		
+		public String getUnixName() {
+			return this.unixName;
+		}
+	}
+	
+	/**
+	 * Load all libraries needed for the current platform except the TSK JNI.
+	 * 
+	 * @return 
+	 */
+	public static boolean loadAuxilliaryLibs() {
+		System.out.println("Java lib path: " + System.getProperty("java.library.path"));
+		boolean loaded = true;
+        if (LibraryUtils.isWindows()) {
+            loaded = LibraryUtils.loadCRTLibs();
+		}
+		
+		if (! LibraryUtils.isLinux()) {
+			
+			for(LibraryUtils.Lib lib : LibraryUtils.getLibs()) {
+				loaded = LibraryUtils.loadLibFromJar(lib);
+				if (!loaded) {
+					System.out.println("SleuthkitJNI: failed to load " + lib.getLibName());
+				} else {
+					System.out.println("SleuthkitJNI: loaded " + lib.getLibName());
+				}
+			}
+		} else {
+			System.out.println("In unix path.");
+			// Unix platform
+			for (Lib lib : LibraryUtils.getLibs()) {
+				try {
+					System.out.println("Lib name: " + lib.getUnixName());
+					System.loadLibrary(lib.getUnixName());
+					System.out.println("SleuthkitJNI: loaded " + lib.getLibName());
+				} catch (UnsatisfiedLinkError e) {
+					loaded = false;
+					System.out.println("SleuthkitJNI: failed to load " + lib.getLibName());
+				}
+			}
+		}
+		return loaded;
+	}
+	
+	/**
+	 * Load the Sleuthkit JNI.
+	 * 
+	 * @return 
+	 */
+	public static boolean loadSleuthkitJNI() {
+		boolean loaded = LibraryUtils.loadLibFromJar(Lib.TSK_JNI);
+		if (!loaded) {
+			System.out.println("SleuthkitJNI: failed to load " + Lib.TSK_JNI.getLibName());
+		} else {
+			System.out.println("SleuthkitJNI: loaded " + Lib.TSK_JNI.getLibName());
+		}
+		return loaded;
+	}
+	
+	/** Load the CRT Libraries.
+	 * 
+	 * @return 
+	 */
+	private static boolean loadCRTLibs() {
+		boolean loaded = true;
+		try { 
+			// on windows force loading ms crt dependencies first
+			// in case linker can't find them on some systems
+			// Note: if shipping with a different CRT version, this will only print a warning
+			// and try to use linker mechanism to find the correct versions of libs.
+			// We should update this if we officially switch to a new version of CRT/compiler
+			for(LibraryUtils.Lib crt : LibraryUtils.getCRTLibs()) {
+				loaded = LibraryUtils.loadLibFromJar(crt);
+				if(!loaded) {
+					System.out.println("SleuthkitJNI: failed to load " + crt.getLibName());
+				} else {
+					System.out.println("SleuthkitJNI: loaded " + crt.getLibName());
+				}
+			}
+		} catch (UnsatisfiedLinkError e1) {
+			System.out.println(e1.toString());
+			try {
+				//Try to load from system path.
+				System.out.println("Can't find CRT libraries, attempting to load from System.loadLibrary");
+				System.loadLibrary("msvcr100");
+				System.loadLibrary("msvcp100");
+				loaded = true;
+			} catch (UnsatisfiedLinkError e2) {
+				System.out.println("SleuthkitJNI: error loading CRT libraries, " + e2.toString());
+				loaded = false;
+			}
+		}
+		return loaded;
+	}
+		
+	/**
+	 * Get the name of the current platform.
+	 * 
+	 * @return a platform identifier, formatted as "OS_ARCH/OS_NAME"
+	 */
+	private static String getPlatform() {
+		String os = System.getProperty("os.name").toLowerCase();
+		if(LibraryUtils.isWindows()) {
+			os = "win";
+		} else if(LibraryUtils.isMac()) {
+			os = "mac";
+		}
+		// os.arch represents the architecture of the JVM, not the os
+		String arch = System.getProperty("os.arch");
+		return arch.toLowerCase() + "/" + os.toLowerCase();
+	}
+	
+	/**
+	 * Is the platform Windows?
+	 * 
+	 * @return 
+	 */
+	private static boolean isWindows() {
+		return System.getProperty("os.name").toLowerCase().contains("windows");
+	}
+
+	/**
+	 * Is the platform Mac?
+	 * 
+	 * @return 
+	 */
+	private static boolean isMac() {
+		return System.getProperty("os.name").toLowerCase().contains("mac");
+	}
+	
+	/**
+	 * Is the platform Linux?
+	 * 
+	 * @return
+	 */
+	private static boolean isLinux() {
+		return System.getProperty("os.name").equals("Linux");
+	}
+	
+    /**
+	 * Attempt to extract and load the specified library.
+	 * 
+	 * @param library
+	 * @return 
+	 */
+	private static boolean loadLibFromJar(Lib library) {
+		StringBuilder path = new StringBuilder();
+		path.append("/NATIVELIBS/");
+		path.append(getPlatform());
+		
+		String libName = library.getLibName();
+		
+		path.append("/");
+		path.append(libName);
+		
+		URL libraryURL = null;
+		String libExt = null;
+		for(String ext : EXTS) {
+			libraryURL = SleuthkitJNI.class.getResource(path.toString() +  ext);
+			if (libraryURL != null) {
+				libExt = ext;
+				break;
+			}
+		}
+		
+		if(libraryURL == null) {
+			return false;
+		}
+		
+		// copy library to temp folder and load it
+		try {
+			java.io.File libTemp = new java.io.File(System.getProperty("java.io.tmpdir") + libName + libExt);
+
+			if(libTemp.exists()) {
+				// Delete old file
+				libTemp.delete();
+			}
+
+			InputStream in = libraryURL.openStream();
+			OutputStream out = new FileOutputStream(libTemp);
+
+			byte[] buffer = new byte[1024];
+			int length;
+			while((length = in.read(buffer)) > 0) {
+				out.write(buffer, 0, length);
+			}
+			in.close();
+			out.close();
+
+			System.load(libTemp.getAbsolutePath());
+		} catch (IOException e) {
+			// Loading failed.
+			return false;
+		} 
+		return true;
+	} 
+	
+	private static Lib[] getCRTLibs() {
+		return CRT_LIBS;
+	}
+	
+	private static Lib[] getLibs() {
+		return OTHER_LIBS;
+	}
+}
diff --git a/bindings/java/src/org/sleuthkit/datamodel/LogicalFileTransaction.java b/bindings/java/src/org/sleuthkit/datamodel/LogicalFileTransaction.java
new file mode 100755
index 0000000..5039492
--- /dev/null
+++ b/bindings/java/src/org/sleuthkit/datamodel/LogicalFileTransaction.java
@@ -0,0 +1,148 @@
+/*
+ * Sleuth Kit Data Model
+ * 
+ * Copyright 2013 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.datamodel;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import static org.sleuthkit.datamodel.SleuthkitCase.*;
+
+/**
+ * implements the Transaction interface
+ *
+ *
+ *
+ *
+ */
+class LogicalFileTransaction implements Transaction {
+
+	/**
+	 * private commit state
+	 */
+	private Boolean committed = false;
+	/**
+	 * db Connection this transaction is associated with
+	 */
+	private Connection con;
+	private static final Logger logger = Logger.getLogger(LogicalFileTransaction.class.getName());
+	private Boolean closed = false;
+
+	/**
+	 * private constructor
+	 */
+	private LogicalFileTransaction() {
+	}
+
+	/**
+	 * factory creation method
+	 *
+	 * @param con the {@link  ava.sql.Connection}
+	 * @return a LogicalFileTransaction for the given connection
+	 * @throws SQLException
+	 */
+	static public LogicalFileTransaction startTransaction(Connection con) throws SQLException {
+
+		LogicalFileTransaction lft = new LogicalFileTransaction();
+		lft.con = con;
+
+		//get the write lock, released in close()
+		dbWriteLock();
+		try {
+			con.setAutoCommit(false);
+
+		} catch (SQLException ex) {
+			Logger.getLogger(LogicalFileTransaction.class.getName()).log(Level.SEVERE, "failed to set auto-commit to to false", ex);
+			throw ex;
+		}
+
+		return lft;
+	}
+
+	/**
+	 * {@inheritDoc }
+	 *
+	 * NOTE: this implementation of commit also closes the transaction whether
+	 * the commit succeeded or failed
+	 */
+	@Override
+	public void commit() {
+		if (!committed && !closed) {
+			try {
+				con.commit();
+			} catch (SQLException ex) {
+				rollback();
+			} finally {
+				close();
+			}
+		}
+	}
+
+	/**
+	 * {@inheritDoc }
+	 */
+	@Override
+	public Boolean isCommitted() {
+		return committed;
+
+	}
+
+	/**
+	 * {@inheritDoc }
+	 */
+	@Override
+	public void rollback() {
+		if (!committed && !closed) {
+			try {
+				con.rollback();
+			} catch (SQLException ex1) {
+				Logger.getLogger(LogicalFileTransaction.class.getName()).log(Level.SEVERE, "Exception while attempting to rollback!!", ex1);
+			}
+		}
+	}
+
+	/**
+	 * {@inheritDoc }
+	 *
+	 */
+	@Override
+	public void close() {
+		if (!closed) {
+			try {
+				con.setAutoCommit(true);
+			} catch (SQLException ex) {
+				logger.log(Level.SEVERE, "Error setting auto-commit to true.", ex);
+			} finally {
+				con = null;
+				committed = true;
+				closed = true;
+				dbWriteUnlock();
+			}
+		}
+	}
+
+	/**
+	 * {@inheritDoc }
+	 *
+	 */
+	@Override
+	public Boolean isClosed() {
+		return closed;
+	}
+}
diff --git a/bindings/java/src/org/sleuthkit/datamodel/ResultSetHelper.java b/bindings/java/src/org/sleuthkit/datamodel/ResultSetHelper.java
index b58a152..f51aa6c 100755
--- a/bindings/java/src/org/sleuthkit/datamodel/ResultSetHelper.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/ResultSetHelper.java
@@ -130,7 +130,7 @@ class ResultSetHelper {
 				TSK_FS_ATTR_TYPE_ENUM.valueOf(rs.getShort("attr_type")),
 				rs.getShort("attr_id"), rs.getString("name"), rs.getLong("meta_addr"),
 				TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort("dir_type")),
-				TSK_FS_META_TYPE_ENUM.ValueOf(rs.getShort("meta_type")),
+				TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort("meta_type")),
 				TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort("dir_flags")),
 				rs.getShort("meta_flags"), rs.getLong("size"),
 				rs.getLong("ctime"), rs.getLong("crtime"), rs.getLong("atime"), rs.getLong("mtime"),
@@ -156,7 +156,7 @@ class ResultSetHelper {
 				TSK_FS_ATTR_TYPE_ENUM.valueOf(rs.getShort("attr_type")),
 				rs.getShort("attr_id"), name, rs.getLong("meta_addr"),
 				TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort("dir_type")),
-				TSK_FS_META_TYPE_ENUM.ValueOf(rs.getShort("meta_type")),
+				TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort("meta_type")),
 				TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort("dir_flags")),
 				rs.getShort("meta_flags"), rs.getLong("size"),
 				rs.getLong("ctime"), rs.getLong("crtime"), rs.getLong("atime"), rs.getLong("mtime"),
@@ -183,7 +183,7 @@ class ResultSetHelper {
 		final VirtualDirectory vd = new VirtualDirectory(db, rs.getLong("obj_id"),
 				rs.getString("name"),
 				TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort("dir_type")),
-				TSK_FS_META_TYPE_ENUM.ValueOf(rs.getShort("meta_type")),
+				TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort("meta_type")),
 				TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort("dir_flags")), rs.getShort("meta_flags"),
 				rs.getLong("size"), rs.getString("md5"),
 				FileKnown.valueOf(rs.getByte("known")), parentPath);
@@ -240,7 +240,7 @@ class ResultSetHelper {
 		final DerivedFile df =
 				new DerivedFile(db, objId, rs.getString("name"),
 				TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort("dir_type")),
-				TSK_FS_META_TYPE_ENUM.ValueOf(rs.getShort("meta_type")),
+				TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort("meta_type")),
 				TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort("dir_flags")), rs.getShort("meta_flags"),
 				rs.getLong("size"),
 				rs.getLong("ctime"), rs.getLong("crtime"), rs.getLong("atime"), rs.getLong("mtime"),
@@ -275,7 +275,7 @@ class ResultSetHelper {
 		final LocalFile lf =
 				new LocalFile(db, objId, rs.getString("name"),
 				TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort("dir_type")),
-				TSK_FS_META_TYPE_ENUM.ValueOf(rs.getShort("meta_type")),
+				TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort("meta_type")),
 				TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort("dir_flags")), rs.getShort("meta_flags"),
 				rs.getLong("size"),
 				rs.getLong("ctime"), rs.getLong("crtime"), rs.getLong("atime"), rs.getLong("mtime"),
diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
index 88678e7..dc4283f 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java
@@ -35,8 +35,8 @@ import java.util.*;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 import java.util.logging.Level;
-import org.sleuthkit.datamodel.TskData.ObjectType;
 import java.util.logging.Logger;
+import org.sleuthkit.datamodel.TskData.ObjectType;
 import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
 import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
 import org.sleuthkit.datamodel.SleuthkitJNI.CaseDbHandle.AddImageProcess;
@@ -66,10 +66,8 @@ public class SleuthkitCase {
 	private ResultSetHelper rsHelper = new ResultSetHelper(this);
 	private int artifactIDcounter = 1001;
 	private int attributeIDcounter = 1001;
-	
 	// for use by getCarvedDirectoryId method only
 	private final Map<Long, Long> systemIdMap = new HashMap<Long, Long>();
-
 	//database lock
 	private static final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(true); //use fairness policy
 	private static final Lock caseDbLock = rwLock.writeLock(); //using exclusing lock for all db ops for now
@@ -111,6 +109,7 @@ public class SleuthkitCase {
 	private PreparedStatement getLastContentIdSt;
 	private PreparedStatement getFsIdForFileIdSt;
 	private static final Logger logger = Logger.getLogger(SleuthkitCase.class.getName());
+	private ArrayList<ErrorObserver> errorObservers = new ArrayList<ErrorObserver>();
 
 	/**
 	 * constructor (private) - client uses openCase() and newCase() instead
@@ -132,7 +131,29 @@ public class SleuthkitCase {
 		configureDB();
 		initBlackboardTypes();
 		initStatements();
-		
+
+	}
+
+	/**
+	 * create a new transaction: lock the database and set auto-commit false.
+	 * this transaction should be passed to methods who take a transaction and
+	 * then have transaction.commit() invoked on it to commit changes and unlock
+	 * the database
+	 *
+	 * @return
+	 * @throws TskCoreException
+	 */
+	public LogicalFileTransaction createTransaction() throws TskCoreException {
+		if (con != null) {
+			try {
+				return LogicalFileTransaction.startTransaction(con);
+			} catch (SQLException ex) {
+				Logger.getLogger(SleuthkitCase.class.getName()).log(Level.SEVERE, "failed to create transaction", ex);
+				throw new TskCoreException("Failed to create transaction", ex);
+			}
+		} else {
+			throw new TskCoreException("could not create transaction with null db connection");
+		}
 	}
 
 	/**
@@ -225,9 +246,9 @@ public class SleuthkitCase {
 		updateMd5St = con.prepareStatement("UPDATE tsk_files SET md5 = ? WHERE obj_id = ?");
 
 		getPathSt = con.prepareStatement("SELECT path FROM tsk_files_path WHERE obj_id = ?");
-		
+
 		getFileParentPathSt = con.prepareStatement("SELECT parent_path FROM tsk_files WHERE obj_id = ?");
-		
+
 		getFileNameSt = con.prepareStatement("SELECT name FROM tsk_files WHERE obj_id = ?");
 
 		getDerivedInfoSt = con.prepareStatement("SELECT derived_id, rederive FROM tsk_files_derived WHERE obj_id = ?");
@@ -243,7 +264,7 @@ public class SleuthkitCase {
 		addFileSt = con.prepareStatement(
 				"INSERT INTO tsk_files (obj_id, fs_obj_id, name, type, has_path, dir_type, meta_type, dir_flags, meta_flags, size, ctime, crtime, atime, mtime, parent_path) "
 				+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
-		
+
 		addLayoutFileSt = con.prepareStatement(
 				"INSERT INTO tsk_file_layout (obj_id, byte_start, byte_len, sequence) "
 				+ "VALUES (?, ?, ?, ?)");
@@ -253,7 +274,7 @@ public class SleuthkitCase {
 
 		hasChildrenSt = con.prepareStatement(
 				"SELECT COUNT(obj_id) FROM tsk_objects WHERE par_obj_id = ?");
-		
+
 		getFsIdForFileIdSt = con.prepareStatement(
 				"SELECT fs_obj_id from tsk_files WHERE obj_id=?");
 
@@ -353,7 +374,7 @@ public class SleuthkitCase {
 				getFileWithParentSt.close();
 				getFileWithParentSt = null;
 			}
-			
+
 			if (getFileNameSt != null) {
 				getFileNameSt.close();
 				getFileNameSt = null;
@@ -363,7 +384,7 @@ public class SleuthkitCase {
 				updateMd5St.close();
 				updateMd5St = null;
 			}
-			
+
 			if (getLastContentIdSt != null) {
 				getLastContentIdSt.close();
 				getLastContentIdSt = null;
@@ -373,7 +394,7 @@ public class SleuthkitCase {
 				getPathSt.close();
 				getPathSt = null;
 			}
-			
+
 			if (getFileParentPathSt != null) {
 				getFileParentPathSt.close();
 				getFileParentPathSt = null;
@@ -399,7 +420,7 @@ public class SleuthkitCase {
 				addFileSt.close();
 				addFileSt = null;
 			}
-			
+
 			if (addLayoutFileSt != null) {
 				addLayoutFileSt.close();
 				addLayoutFileSt = null;
@@ -414,12 +435,12 @@ public class SleuthkitCase {
 				hasChildrenSt.close();
 				hasChildrenSt = null;
 			}
-			
+
 			if (getFsIdForFileIdSt != null) {
 				getFsIdForFileIdSt.close();
 				getFsIdForFileIdSt = null;
 			}
-			
+
 
 		} catch (SQLException e) {
 			logger.log(Level.WARNING,
@@ -598,7 +619,8 @@ public class SleuthkitCase {
 	}
 
 	/**
-	 * Get the list of root objects, meaning image files or local files virtual dir container.
+	 * Get the list of root objects, meaning image files or local files virtual
+	 * dir container.
 	 *
 	 * @return list of content objects.
 	 * @throws TskCoreException exception thrown if a critical error occurs
@@ -625,18 +647,15 @@ public class SleuthkitCase {
 			for (ObjectInfo i : infos) {
 				if (i.type == ObjectType.IMG) {
 					rootObjs.add(getImageById(i.id));
-				}
-				else if (i.type == ObjectType.ABSTRACTFILE) {
+				} else if (i.type == ObjectType.ABSTRACTFILE) {
 					//check if virtual dir for local files
 					AbstractFile af = getAbstractFileById(i.id);
 					if (af instanceof VirtualDirectory) {
 						rootObjs.add(af);
-					}
-					else {
+					} else {
 						throw new TskCoreException("Parentless object has wrong type to be a root (ABSTRACTFILE, but not VIRTUAL_DIRECTORY: " + i.type);
 					}
-				} 
-				else {
+				} else {
 					throw new TskCoreException("Parentless object has wrong type to be a root: " + i.type);
 				}
 			}
@@ -1023,6 +1042,27 @@ public class SleuthkitCase {
 	}
 
 	/**
+	 * Get all of the blackboard artifact types that are in use in the
+	 * blackboard.
+	 *
+	 * @return List of blackboard artifact types
+	 * @throws TskCoreException
+	 */
+	public ArrayList<BlackboardArtifact.ARTIFACT_TYPE> getBlackboardArtifactTypesInUse() throws TskCoreException {
+		// @@@ TODO: This should be rewritten as a single query. 
+
+		ArrayList<BlackboardArtifact.ARTIFACT_TYPE> allArts = getBlackboardArtifactTypes();
+		ArrayList<BlackboardArtifact.ARTIFACT_TYPE> usedArts = new ArrayList<BlackboardArtifact.ARTIFACT_TYPE>();
+
+		for (BlackboardArtifact.ARTIFACT_TYPE art : allArts) {
+			if (getBlackboardArtifactsTypeCount(art.getTypeID()) > 0) {
+				usedArts.add(art);
+			}
+		}
+		return usedArts;
+	}
+
+	/**
 	 * Get all blackboard attribute types
 	 *
 	 * Gets both static (in enum) and dynamic attributes types (created by
@@ -2048,11 +2088,11 @@ public class SleuthkitCase {
 		return hasChildren;
 
 	}
-	
+
 	/**
-	 * Counts if the content object  children. Note: this is generally more
-	 * efficient then preloading all children and counting,
-	 * and facilities lazy loading.
+	 * Counts if the content object children. Note: this is generally more
+	 * efficient then preloading all children and counting, and facilities lazy
+	 * loading.
 	 *
 	 * @param content content object to check for children count
 	 * @return children count
@@ -2119,11 +2159,11 @@ public class SleuthkitCase {
 						result = rsHelper.file(rs, null);
 					}
 					children.add(result);
-				} else if (type == TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR) {	
+				} else if (type == TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR) {
 					VirtualDirectory virtDir = rsHelper.virtualDirectory(rs);
 					children.add(virtDir);
-				} else if (type == TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS ||
-						type == TSK_DB_FILES_TYPE_ENUM.CARVED) {
+				} else if (type == TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS
+						|| type == TSK_DB_FILES_TYPE_ENUM.CARVED) {
 					String parentPath = rs.getString("parent_path");
 					if (parentPath == null) {
 						parentPath = "";
@@ -2131,9 +2171,9 @@ public class SleuthkitCase {
 					final LayoutFile lf =
 							new LayoutFile(this, rs.getLong("obj_id"), rs.getString("name"),
 							type,
-							TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort("dir_type")), 
-							TSK_FS_META_TYPE_ENUM.ValueOf(rs.getShort("meta_type")),
-							TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort("dir_flags")), 
+							TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort("dir_type")),
+							TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort("meta_type")),
+							TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort("dir_flags")),
 							rs.getShort("meta_flags"),
 							rs.getLong("size"),
 							rs.getString("md5"), FileKnown.valueOf(rs.getByte("known")), parentPath);
@@ -2386,8 +2426,7 @@ public class SleuthkitCase {
 	}
 
 	/**
-	 * Get a path of a file in tsk_files_path table or null if there
-	 * is none
+	 * Get a path of a file in tsk_files_path table or null if there is none
 	 *
 	 * @param id id of the file to get path for
 	 * @return file path or null
@@ -2418,10 +2457,9 @@ public class SleuthkitCase {
 
 		return filePath;
 	}
-	
+
 	/**
-	 * Get a parent_path of a file in tsk_files table or null if there
-	 * is none
+	 * Get a parent_path of a file in tsk_files table or null if there is none
 	 *
 	 * @param id id of the file to get path for
 	 * @return file path or null
@@ -2452,10 +2490,9 @@ public class SleuthkitCase {
 
 		return parentPath;
 	}
-	
+
 	/**
-	 * Get a name of a file in tsk_files table or null if there
-	 * is none
+	 * Get a name of a file in tsk_files table or null if there is none
 	 *
 	 * @param id id of the file to get name for
 	 * @return file name or null
@@ -2575,14 +2612,12 @@ public class SleuthkitCase {
 		}
 
 	}
-	
-	
-	
-	
+
 	/**
-	 * Get file system id value for file or -1 if there isn't one
-	 * Note: for FsContent files, this is the real fs
-	 * for other non-fs AbstractFile files, this field is used internally for data source id (the root content obj)
+	 * Get file system id value for file or -1 if there isn't one Note: for
+	 * FsContent files, this is the real fs for other non-fs AbstractFile files,
+	 * this field is used internally for data source id (the root content obj)
+	 *
 	 * @param fileId file id to get fs column id for
 	 * @return fs_id or -1 if not present
 	 */
@@ -2602,11 +2637,9 @@ public class SleuthkitCase {
 					ret = -1;
 				}
 			}
-		}
-		catch (SQLException e) {
+		} catch (SQLException e) {
 			logger.log(Level.SEVERE, "Error checking file system id of a file", e);
-		}
-		finally {
+		} finally {
 			if (rs != null) {
 				try {
 					rs.close();
@@ -2620,8 +2653,34 @@ public class SleuthkitCase {
 	}
 
 	/**
-	 * Checks if the file is a (sub)child of the data source (parentless Content object
-	 * such as Image or VirtualDirectory representing filesets)
+	 * Gets the root-level data source object id (such as Image or
+	 * VirtualDirectory representing filesets) for the file
+	 *
+	 * @param file file to get the root-level object id for
+	 * @return the root content object id in the hierarchy, or -1 if not found
+	 * (such as when invalid file object passed in)
+	 * @throws TskCoreException thrown if check failed due to a critical tsk
+	 * error
+	 */
+	public long getFileDataSource(AbstractFile file) throws TskCoreException {
+
+		final Image image = file.getImage();
+		if (image != null) {
+			//case for image data source
+			return image.getId();
+		} else {
+			//otherwise, get the root non-image data source id
+			//note, we are currently using fs_id internally to store data source id for such files
+
+			return getFileSystemByFileId(file.getId());
+		}
+
+	}
+
+	/**
+	 * Checks if the file is a (sub)child of the data source (parentless Content
+	 * object such as Image or VirtualDirectory representing filesets)
+	 *
 	 * @param dataSource dataSource to check
 	 * @param fileId id of file to check
 	 * @return true if the file is in the dataSource hierarchy
@@ -2633,62 +2692,60 @@ public class SleuthkitCase {
 			logger.log(Level.SEVERE, msg);
 			throw new IllegalArgumentException(msg);
 		}
-		
+
 		//get fs_id for file id
 		long fsId = getFileSystemByFileId(fileId);
 		if (fsId == -1) {
 			return false;
 		}
-		
+
 		//if image, check if one of fs in data source
-		
+
 		if (dataSource instanceof Image) {
-			Collection<FileSystem> fss = getFileSystems((Image)dataSource);
+			Collection<FileSystem> fss = getFileSystems((Image) dataSource);
 			for (FileSystem fs : fss) {
 				if (fs.getId() == fsId) {
 					return true;
 				}
 			}
 			return false;
-			
-		}
-		//if VirtualDirectory, check if dataSource id is the fs_id
+
+		} //if VirtualDirectory, check if dataSource id is the fs_id
 		else if (dataSource instanceof VirtualDirectory) {
 			//fs_obj_id is not a real fs in this case
 			//we are currently using this field internally to get to data source of non-fs files quicker
 			//this will be fixed in 2.5 schema
 			return dataSource.getId() == fsId;
-			
-		}
-		else {
+
+		} else {
 			final String msg = "Error, data source should be Image or VirtualDirectory, got: " + dataSource;
 			logger.log(Level.SEVERE, msg);
 			throw new IllegalArgumentException(msg);
 		}
-		
+
 	}
-	
-	
+
 	/**
-	 * @param dataSource the dataSource (Image, parent-less VirtualDirectory) to search for the given file name
-	 * @param fileName the name of the file or directory to match (case
-	 * insensitive)
-	 * @return a list of AbstractFile for files/directories whose name matches the
-	 * given fileName
+	 * @param dataSource the dataSource (Image, parent-less VirtualDirectory) to
+	 * search for the given file name
+	 * @param fileName Pattern of the name of the file or directory to match
+	 * (case insensitive, used in LIKE SQL statement).
+	 * @return a list of AbstractFile for files/directories whose name matches
+	 * the given fileName
 	 * @throws TskCoreException thrown if check failed
 	 */
 	public List<AbstractFile> findFiles(Content dataSource, String fileName) throws TskCoreException {
-		
+
 		if (dataSource.getParent() != null) {
 			final String msg = "Error, data source should be parent-less (images, file-sets), got: " + dataSource;
 			logger.log(Level.SEVERE, msg);
 			throw new IllegalArgumentException(msg);
 		}
-		
+
 		// set the file name in the prepared statement
 		List<AbstractFile> files = new ArrayList<AbstractFile>();
 		ResultSet rs = null;
-		
+
 		dbReadLock();
 		try {
 			if (dataSource instanceof Image) {
@@ -2734,24 +2791,25 @@ public class SleuthkitCase {
 	}
 
 	/**
-	 * @param dataSource the dataSource (Image, parent-less VirtualDirectory) to search for the given file name
-	 * @param fileName the name of the file or directory to match (case
-	 * insensitive)
-	 * @param dirName the name of a parent directory of fileName (case
-	 * insensitive)
+	 * @param dataSource the dataSource (Image, parent-less VirtualDirectory) to
+	 * search for the given file name
+	 * @param fileName Pattern of the name of the file or directory to match
+	 * (case insensitive, used in LIKE SQL statement).
+	 * @param dirName Pattern of the name of a parent directory of fileName
+	 * (case insensitive, used in LIKE SQL statement)
 	 * @return a list of AbstractFile for files/directories whose name matches
 	 * fileName and whose parent directory contains dirName.
 	 */
 	public List<AbstractFile> findFiles(Content dataSource, String fileName, String dirName) throws TskCoreException {
-			if (dataSource.getParent() != null) {
+		if (dataSource.getParent() != null) {
 			final String msg = "Error, data source should be parent-less (images, file-sets), got: " + dataSource;
 			logger.log(Level.SEVERE, msg);
 			throw new IllegalArgumentException(msg);
 		}
-		
+
 		ResultSet rs = null;
 		List<AbstractFile> files = new ArrayList<AbstractFile>();
-		
+
 		dbReadLock();
 		try {
 			if (dataSource instanceof Image) {
@@ -2807,7 +2865,6 @@ public class SleuthkitCase {
 		return files;
 	}
 
-	
 	/**
 	 * Add a path (such as a local path) for a content object to tsk_file_paths
 	 *
@@ -2821,50 +2878,73 @@ public class SleuthkitCase {
 			addPathSt.setLong(1, objId);
 			addPathSt.setString(2, path);
 			addPathSt.executeUpdate();
-		}
-		finally {
+		} finally {
 			addPathSt.clearParameters();
 		}
 	}
-	
+
+	/**
+	 * wraps the version of addVirtualDirectory that takes a Transaction in a
+	 * transaction local to this method
+	 *
+	 * @param parentId
+	 * @param directoryName
+	 * @return
+	 * @throws TskCoreException
+	 */
+	public VirtualDirectory addVirtualDirectory(long parentId, String directoryName) throws TskCoreException {
+
+		LogicalFileTransaction localTrans = createTransaction();
+		VirtualDirectory newVD = addVirtualDirectory(parentId, directoryName, localTrans);
+		localTrans.commit();
+		return newVD;
+
+	}
+
 	/**
 	 * Adds a virtual directory to the database and returns a VirtualDirectory
 	 * object representing it.
+	 *
+	 * todo: at the moment we trust the transaction and don't do anything to
+	 * check it is valid or in the correct state. we should.
+	 *
 	 * @param parentId the ID of the parent, or 0 if NULL
 	 * @param directoryName the name of the virtual directory to create
-	 * @return a VirtualDirectory object representing the one added to the database.
-	 * @throws TskCoreException 
+	 * @param trans the transaction that will take care of locking and unlocking
+	 * the database
+	 * @return a VirtualDirectory object representing the one added to the
+	 * database.
+	 * @throws TskCoreException
 	 */
-	public VirtualDirectory addVirtualDirectory(long parentId, String directoryName) throws TskCoreException {	
+	public VirtualDirectory addVirtualDirectory(long parentId, String directoryName, Transaction trans) throws TskCoreException {
 		// get the parent path
 		String parentPath = getFileParentPath(parentId);
 		if (parentPath == null) {
 			parentPath = "";
-		} 
+		}
 		String parentName = getFileName(parentId);
 		if (parentName != null) {
 			parentPath = parentPath + "/" + parentName;
 		}
-		
+
 		//propagate fs id if parent is a file and fs id is set
 		long parentFs = this.getFileSystemByFileId(parentId);
 		if (parentFs == -1) {
 			//use the parentId fs obj id as data source id  internally
 			parentFs = parentId;
 		}
-		
-		dbWriteLock();
-		
+
+
 		VirtualDirectory vd = null;
 
-		//all in one write lock and transaction
+		//don't need to lock database or setAutoCommit(false), since we are
+		//passed Transaction which handles that.
+
 		//get last object id
 		//create tsk_objects object with new id
 		//create tsk_files object with the new id
 		try {
 
-			con.setAutoCommit(false);
-
 			long newObjId = getLastObjectId() + 1;
 			if (newObjId < 1) {
 				throw new TskCoreException("Error creating a virtual directory, cannot get new id of the object.");
@@ -2885,11 +2965,10 @@ public class SleuthkitCase {
 			//obj_id, fs_obj_id, name
 			addFileSt.clearParameters(); //clear from previous, so we can skip nulls
 			addFileSt.setLong(1, newObjId);
-			
+
 			if (parentFs < 1) {
 				addFileSt.setNull(2, java.sql.Types.BIGINT);
-			}
-			else {
+			} else {
 				addFileSt.setLong(2, parentFs);
 			}
 			addFileSt.setString(3, directoryName);
@@ -2919,7 +2998,7 @@ public class SleuthkitCase {
 			addFileSt.setString(15, parentPath);
 
 			addFileSt.executeUpdate();
-			
+
 			vd = new VirtualDirectory(this, newObjId, directoryName, dirType,
 					metaType, dirFlag, metaFlags, size, null, FileKnown.UKNOWN,
 					parentPath);
@@ -2932,35 +3011,21 @@ public class SleuthkitCase {
 			} catch (SQLException ex) {
 				logger.log(Level.SEVERE, "Error clearing parameters after adding virtual directory.", ex);
 			}
-			
-			try {
-				con.commit();
-			} catch (SQLException ex) {
-				logger.log(Level.SEVERE, "Error committing after adding virtual directory.", ex);
-			} finally {
-				try {
-					con.setAutoCommit(true);
-				} catch (SQLException ex) {
-					logger.log(Level.SEVERE, "Error setting auto-commit after adding virtual directory.", ex);
-				} finally {
-					dbWriteUnlock();
-				}
-			}
+
 		}
 
 		return vd;
 	}
-	
-	
+
 	/**
-	 * Get IDs of the virtual folder roots (at the same level as image), used for containers
-	 * such as for local files. 
-	 * 
+	 * Get IDs of the virtual folder roots (at the same level as image), used
+	 * for containers such as for local files.
+	 *
 	 * @return IDs of virtual directory root objects.
 	 */
 	public List<VirtualDirectory> getVirtualDirectoryRoots() throws TskCoreException {
 		final List<VirtualDirectory> virtDirRootIds = new ArrayList<VirtualDirectory>();
-		
+
 		//use lock to ensure atomic cache check and db/cache update
 		dbReadLock();
 
@@ -2968,41 +3033,36 @@ public class SleuthkitCase {
 		ResultSet rs = null;
 		try {
 			statement = con.createStatement();
-			rs = statement.executeQuery("SELECT tsk_files.* FROM tsk_objects, tsk_files WHERE " 
-					+ "tsk_objects.par_obj_id IS NULL AND " 
-					+ "tsk_objects.type = " + TskData.ObjectType.ABSTRACTFILE.getObjectType() + " AND " 
+			rs = statement.executeQuery("SELECT tsk_files.* FROM tsk_objects, tsk_files WHERE "
+					+ "tsk_objects.par_obj_id IS NULL AND "
+					+ "tsk_objects.type = " + TskData.ObjectType.ABSTRACTFILE.getObjectType() + " AND "
 					+ "tsk_objects.obj_id = tsk_files.obj_id AND "
 					+ "tsk_files.type = " + TskData.TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType());
-					
+
 			while (rs.next()) {
 				virtDirRootIds.add(rsHelper.virtualDirectory(rs));
 			}
-		}
-		catch (SQLException ex) {
+		} catch (SQLException ex) {
 			logger.log(Level.SEVERE, "Error getting local files virtual folder id, ", ex);
 			throw new TskCoreException("Error getting local files virtual folder id, ", ex);
-		}
-		
-		finally {
-			try{
+		} finally {
+			try {
 				if (rs != null) {
 					rs.close();
 				}
 				if (statement != null) {
 					statement.close();
 				}
-			}
-			catch (SQLException e) {
+			} catch (SQLException e) {
 				logger.log(Level.WARNING, "Error closing statements after getting local files virt folder id", e);
-			}
-			finally {
+			} finally {
 				dbReadUnlock();
 			}
 		}
 
 		return virtDirRootIds;
 	}
-	
+
 	/**
 	 * @param id an image, volume or file system ID
 	 * @return the ID of the '$CarvedFiles' directory for the given systemId
@@ -3069,34 +3129,35 @@ public class SleuthkitCase {
 
 		return ret;
 	}
-	
+
 	/**
 	 * Adds a carved file to the VirtualDirectory '$CarvedFiles' in the volume
 	 * or file system given by systemId.
-	 * @param carvedFileName the name of the carved file to add 
+	 *
+	 * @param carvedFileName the name of the carved file to add
 	 * @param carvedFileSize the size of the carved file to add
 	 * @param systemId the ID of the parent volume or file system
-	 * @param data the layout information - a list of offsets that make up
-	 * this carved file.
+	 * @param data the layout information - a list of offsets that make up this
+	 * carved file.
 	 */
 	public LayoutFile addCarvedFile(String carvedFileName, long carvedFileSize,
 			long systemId, List<TskFileRange> data) throws TskCoreException {
-		
+
 		// get the ID of the appropriate '$CarvedFiles' directory
 		long carvedFilesId = getCarvedDirectoryId(systemId);
-		
+
 		// get the parent path for the $CarvedFiles directory		
 		String parentPath = getFileParentPath(carvedFilesId);
 		if (parentPath == null) {
 			parentPath = "";
-		} 
+		}
 		String parentName = getFileName(carvedFilesId);
 		if (parentName != null) {
 			parentPath = parentPath + "/" + parentName;
 		}
-		
+
 		dbWriteLock();
-		
+
 		LayoutFile lf = null;
 
 		//all in one write lock and transaction
@@ -3130,7 +3191,7 @@ public class SleuthkitCase {
 			// type
 			final TSK_DB_FILES_TYPE_ENUM type = TSK_DB_FILES_TYPE_ENUM.CARVED;
 			addFileSt.setShort(4, type.getFileType());
-			
+
 			// has_path
 			addFileSt.setBoolean(5, true);
 
@@ -3157,24 +3218,24 @@ public class SleuthkitCase {
 			addFileSt.setString(15, parentPath);
 
 			addFileSt.executeUpdate();
-			
+
 			// tsk_file_layout
-			
+
 			// add an entry in the tsk_layout_file table for each TskFileRange
 			for (TskFileRange tskFileRange : data) {
-				
+
 				// set the object ID
 				addLayoutFileSt.setLong(1, newObjId);
-				
+
 				// set byte_start
 				addLayoutFileSt.setLong(2, tskFileRange.getByteStart());
-				
+
 				// set byte_len
 				addLayoutFileSt.setLong(3, tskFileRange.getByteLen());
-				
+
 				// set the sequence number
 				addLayoutFileSt.setLong(4, tskFileRange.getSequence());
-				
+
 				// execute it
 				addLayoutFileSt.executeUpdate();
 			}
@@ -3193,7 +3254,7 @@ public class SleuthkitCase {
 			} catch (SQLException ex) {
 				logger.log(Level.SEVERE, "Error clearing parameters after adding derived file", ex);
 			}
-			
+
 			try {
 				con.commit();
 			} catch (SQLException ex) {
@@ -3215,7 +3276,7 @@ public class SleuthkitCase {
 	/**
 	 * Creates a new derived file object, adds it to database and returns it.
 	 *
-	 * TODO add support for adding derived method 
+	 * TODO add support for adding derived method
 	 *
 	 * @param fileName file name the derived file
 	 * @param localPath local path of the derived file, including the file name.
@@ -3237,20 +3298,20 @@ public class SleuthkitCase {
 	 * due to a critical system error
 	 */
 	public DerivedFile addDerivedFile(String fileName, String localPath,
-			long size, long ctime, long crtime, long atime, long mtime, 
+			long size, long ctime, long crtime, long atime, long mtime,
 			boolean isFile, AbstractFile parentFile,
 			String rederiveDetails, String toolName, String toolVersion, String otherDetails) throws TskCoreException {
-		
+
 		final long parentId = parentFile.getId();
 		final String parentPath = parentFile.getParentPath() + parentFile.getName() + '/';
-		
+
 		//get fs_obj_id of the parentFile and propagate it to the new derived file
 		//note, fs_obj_id is fs id for FsContent, but for others it is used internally as data source id, and it is not 
 		//part of AbstractFile API, until the next schema change
 		long fsObjId = this.getFileSystemByFileId(parentId);
 
 		DerivedFile ret = null;
-		
+
 		long newObjId = -1;
 
 		dbWriteLock();
@@ -3316,7 +3377,7 @@ public class SleuthkitCase {
 			addFileSt.setString(15, parentPath);
 
 			addFileSt.executeUpdate();
-			
+
 			//add localPath 
 			addFilePath(newObjId, localPath);
 
@@ -3335,7 +3396,7 @@ public class SleuthkitCase {
 			} catch (SQLException ex) {
 				logger.log(Level.SEVERE, "Error clearing parameters after adding derived file", ex);
 			}
-			
+
 			try {
 				con.commit();
 			} catch (SQLException ex) {
@@ -3354,61 +3415,97 @@ public class SleuthkitCase {
 
 		return ret;
 	}
-	
+
+	/**
+	 *
+	 * wraps the version of addLocalFile that takes a Transaction in a
+	 * transaction local to this method.
+	 *
+	 * @param fileName
+	 * @param localPath
+	 * @param size
+	 * @param ctime
+	 * @param crtime
+	 * @param atime
+	 * @param mtime
+	 * @param isFile
+	 * @param parent
+	 * @return
+	 * @throws TskCoreException
+	 */
+	public LocalFile addLocalFile(String fileName, String localPath,
+			long size, long ctime, long crtime, long atime, long mtime,
+			boolean isFile, AbstractFile parent) throws TskCoreException {
+		LogicalFileTransaction localTrans = createTransaction();
+		LocalFile created = addLocalFile(fileName, localPath, size, ctime, crtime, atime, mtime, isFile, parent, localTrans);
+		localTrans.commit();
+		return created;
+
+	}
+
 	/**
 	 * Creates a new local file object, adds it to database and returns it.
 	 *
+	 *
+	 * todo: at the moment we trust the transaction and don't do anything to
+	 * check it is valid or in the correct state. we should.
+	 *
+	 *
 	 * @param fileName file name the derived file
-	 * @param localPath local absolute path of the local file, including the file name.
+	 * @param localPath local absolute path of the local file, including the
+	 * file name.
 	 * @param size size of the derived file in bytes
 	 * @param ctime
 	 * @param crtime
 	 * @param atime
 	 * @param mtime
 	 * @param isFile whether a file or directory, true if a file
-	 * @param parent parent file object (such as virtual directory, another local file, or FsContent type of file)
+	 * @param parent parent file object (such as virtual directory, another
+	 * local file, or FsContent type of file)
+	 * @param trans the transaction that will take care of locking and unlocking
+	 * the database
 	 * @return newly created derived file object
 	 * @throws TskCoreException exception thrown if the object creation failed
 	 * due to a critical system error
 	 */
 	public LocalFile addLocalFile(String fileName, String localPath,
-			long size, long ctime, long crtime, long atime, long mtime, 
-			boolean isFile, AbstractFile parent) throws TskCoreException {
-		
+			long size, long ctime, long crtime, long atime, long mtime,
+			boolean isFile, AbstractFile parent, Transaction trans) throws TskCoreException {
+
 		long parentId = -1;
 		String parentPath;
 		if (parent == null) {
 			throw new TskCoreException("Error adding local file: " + fileName + ", parent to add to is null");
-		}
-		else {
+		} else {
 			parentId = parent.getId();
 			parentPath = parent.getParentPath() + "/" + parent.getName();
 		}
-		
+
 		//check parent is a data source (the root obj) and set fs_obj_id that we currently use to track or data sources accordingly
 		long dataSourceId = -1;
 		boolean isParentDataSource = parent.getParent() == null;
 		if (isParentDataSource) {
 			dataSourceId = parentId;
-		}
-		else {
+		} else {
 			//else propagate from parent fs_obj_id
 			dataSourceId = getFileSystemByFileId(parentId);
 		}
 
 		LocalFile ret = null;
-		
+
 		long newObjId = -1;
 
-		dbWriteLock();
 
-		//all in one write lock and transaction
+
+		//don't need to lock database or setAutoCommit(false), since we are
+		//passed Transaction which handles that.
+
+
 		//get last object id
 		//create tsk_objects object with new id
 		//create tsk_files object with the new id
 		try {
 
-			con.setAutoCommit(false);
 
 			newObjId = getLastObjectId() + 1;
 			if (newObjId < 1) {
@@ -3463,7 +3560,7 @@ public class SleuthkitCase {
 			addFileSt.setString(15, parentPath);
 
 			addFileSt.executeUpdate();
-			
+
 			//add localPath 
 			addFilePath(newObjId, localPath);
 
@@ -3480,31 +3577,20 @@ public class SleuthkitCase {
 			} catch (SQLException ex) {
 				logger.log(Level.SEVERE, "Error clearing parameters after adding derived file", ex);
 			}
-			
-			try {
-				con.commit();
-			} catch (SQLException ex) {
-				logger.log(Level.SEVERE, "Error committing after adding derived file", ex);
-			} finally {
-				try {
-					con.setAutoCommit(true);
-				} catch (SQLException ex) {
-					logger.log(Level.SEVERE, "Error setting auto-commit after adding derived file", ex);
-				} finally {
-					dbWriteUnlock();
-				}
-			}
+
+
 		}
 		return ret;
 	}
 
-
 	/**
 	 * Find all files in the data source, by name and parent
-	 * @param dataSource the dataSource (Image, parent-less VirtualDirectory) to search for the given file name
-	 * @param fileName the name of the file or directory to match (case
-	 * insensitive)
-	 * @param parentFile
+	 *
+	 * @param dataSource the dataSource (Image, parent-less VirtualDirectory) to
+	 * search for the given file name
+	 * @param fileName Pattern of the name of the file or directory to match
+	 * (case insensitive, used in LIKE SQL statement).
+	 * @param parentFile Object for parent file/directory to find children in
 	 * @return a list of AbstractFile for files/directories whose name matches
 	 * fileName and that were inside a directory described by parentFile.
 	 */
@@ -3512,10 +3598,9 @@ public class SleuthkitCase {
 		return findFiles(dataSource, fileName, parentFile.getName());
 	}
 
-	
 	/**
 	 * Count files matching the specific Where clause
-	 * 
+	 *
 	 * @param sqlWhereClause a SQL where clause appropriate for the desired
 	 * files (do not begin the WHERE clause with the word WHERE!)
 	 * @return count of files each of which satisfy the given WHERE clause
@@ -3549,14 +3634,15 @@ public class SleuthkitCase {
 			dbReadUnlock();
 		}
 	}
-	
-	
+
 	/**
-	 * Find and return list of all (abstract) files matching the specific Where clause
-	 * 
+	 * Find and return list of all (abstract) files matching the specific Where
+	 * clause
+	 *
 	 * @param sqlWhereClause a SQL where clause appropriate for the desired
 	 * files (do not begin the WHERE clause with the word WHERE!)
-	 * @return a list of AbstractFile each of which satisfy the given WHERE clause
+	 * @return a list of AbstractFile each of which satisfy the given WHERE
+	 * clause
 	 * @throws TskCoreException
 	 */
 	public List<AbstractFile> findAllFilesWhere(String sqlWhereClause) throws TskCoreException {
@@ -3589,8 +3675,9 @@ public class SleuthkitCase {
 	}
 
 	/**
-	 * Find and return list of all (abstract) ids of files matching the specific Where clause
-	 * 
+	 * Find and return list of all (abstract) ids of files matching the specific
+	 * Where clause
+	 *
 	 * @param sqlWhereClause a SQL where clause appropriate for the desired
 	 * files (do not begin the WHERE clause with the word WHERE!)
 	 * @return a list of file ids each of which satisfy the given WHERE clause
@@ -3604,7 +3691,7 @@ public class SleuthkitCase {
 		try {
 			statement = con.createStatement();
 			rs = statement.executeQuery("SELECT obj_id FROM tsk_files WHERE " + sqlWhereClause);
-			while(rs.next()) {
+			while (rs.next()) {
 				ret.add(rs.getLong(1));
 			}
 		} catch (SQLException e) {
@@ -3629,10 +3716,9 @@ public class SleuthkitCase {
 		return ret;
 	}
 
-
 	/**
 	 * Find and return list of files matching the specific Where clause
-	 * 
+	 *
 	 * @param sqlWhereClause a SQL where clause appropriate for the desired
 	 * files (do not begin the WHERE clause with the word WHERE!)
 	 * @return a list of FsContent each of which satisfy the given WHERE clause
@@ -3666,12 +3752,12 @@ public class SleuthkitCase {
 			dbReadUnlock();
 		}
 	}
-	
+
 	/**
-	 * Find and return list of file IDs matching the specific Where clause.
-	 * Use this like findFilesWhere() and where file objects are not required upfront
-	 * and so heap usage can be reduced.
-	 * 
+	 * Find and return list of file IDs matching the specific Where clause. Use
+	 * this like findFilesWhere() and where file objects are not required
+	 * upfront and so heap usage can be reduced.
+	 *
 	 * @param sqlWhereClause a SQL where clause appropriate for the desired
 	 * files (do not begin the WHERE clause with the word WHERE!)
 	 * @return a list of file ids each of which satisfy the given WHERE clause
@@ -3688,7 +3774,7 @@ public class SleuthkitCase {
 			while (rs.next()) {
 				ret.add(rs.getLong(1));
 			}
-			
+
 		} catch (SQLException e) {
 			throw new TskCoreException("SQLException thrown when calling 'SleuthkitCase.findFileIdsWhere() " + sqlWhereClause, e);
 		} finally {
@@ -3712,7 +3798,8 @@ public class SleuthkitCase {
 	}
 
 	/**
-	 * @param dataSource the data source (Image, VirtualDirectory for file-sets, etc) to search for the given file name
+	 * @param dataSource the data source (Image, VirtualDirectory for file-sets,
+	 * etc) to search for the given file name
 	 * @param filePath The full path to the file(s) of interest. This can
 	 * optionally include the image and volume names. Treated in a case-
 	 * insensitive manner.
@@ -4026,7 +4113,6 @@ public class SleuthkitCase {
 			dbReadUnlock();
 		}
 	}
-	
 
 	/**
 	 * Helper to return FileSystems in an Image
@@ -4340,8 +4426,8 @@ public class SleuthkitCase {
 	 * Returns a list of all direct children for a given virtual directory
 	 *
 	 * @param vDir virtual directory to get the list of direct children for
-	 * @return list of direct children (layout/local files or directories) for
-	 * a given virtual directory
+	 * @return list of direct children (layout/local files or directories) for a
+	 * given virtual directory
 	 * @throws TskCoreException thrown if a critical error occurred within tsk
 	 * core
 	 */
@@ -4439,18 +4525,17 @@ public class SleuthkitCase {
 
 		return images;
 	}
-	
-	
+
 	/**
 	 * Get last (max) object id of content object in tsk_objects.
-	 * 
-	 * Note, if you
-	 * are using this id to create a new object, make sure you are getting and
-	 * using it in the same write lock/transaction to avoid potential
-	 * concurrency issues with other writes
+	 *
+	 * Note, if you are using this id to create a new object, make sure you are
+	 * getting and using it in the same write lock/transaction to avoid
+	 * potential concurrency issues with other writes
 	 *
 	 * @return currently max id
-	 * @throws TskCoreException exception thrown when database error occurs and last object id could not be queried
+	 * @throws TskCoreException exception thrown when database error occurs and
+	 * last object id could not be queried
 	 */
 	public long getLastObjectId() throws TskCoreException {
 		long id = -1;
@@ -4479,7 +4564,6 @@ public class SleuthkitCase {
 		return id;
 	}
 
-
 	/**
 	 * Set the file paths for the image given by obj_id
 	 *
@@ -4536,8 +4620,8 @@ public class SleuthkitCase {
 				} else if (type == TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()) {
 					final VirtualDirectory virtDir = rsHelper.virtualDirectory(rs);
 					results.add(virtDir);
-				} else if (type == TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS.getFileType() ||
-						type == TSK_DB_FILES_TYPE_ENUM.CARVED.getFileType()) {
+				} else if (type == TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS.getFileType()
+						|| type == TSK_DB_FILES_TYPE_ENUM.CARVED.getFileType()) {
 					TSK_DB_FILES_TYPE_ENUM atype = TSK_DB_FILES_TYPE_ENUM.valueOf(type);
 					String parentPath = rs.getString("parent_path");
 					if (parentPath == null) {
@@ -4546,7 +4630,7 @@ public class SleuthkitCase {
 					LayoutFile lf = new LayoutFile(this, rs.getLong("obj_id"),
 							rs.getString("name"),
 							atype,
-							TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort("dir_type")), TSK_FS_META_TYPE_ENUM.ValueOf(rs.getShort("meta_type")),
+							TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort("dir_type")), TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort("meta_type")),
 							TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort("dir_flags")), rs.getShort("meta_flags"),
 							rs.getLong("size"),
 							rs.getString("md5"), FileKnown.valueOf(rs.getByte("known")), parentPath);
@@ -4838,7 +4922,6 @@ public class SleuthkitCase {
 		}
 		return count;
 	}
-	
 
 	/**
 	 * Escape the single quotes in the given string so they can be added to the
@@ -4867,7 +4950,7 @@ public class SleuthkitCase {
 		try {
 			s = con.createStatement();
 			rs = s.executeQuery("SELECT * FROM tsk_files WHERE "
-				+ " md5 = '" + md5Hash + "' "
+					+ " md5 = '" + md5Hash + "' "
 					+ "AND size > 0");
 			return resultSetToAbstractFiles(rs);
 
@@ -4971,4 +5054,50 @@ public class SleuthkitCase {
 		}
 		return count;
 	}
+
+	/**
+	 * This is a temporary workaround to avoid an API change.
+	 *
+	 * @deprecated
+	 */
+	@Deprecated
+	public interface ErrorObserver {
+
+		void receiveError(String context, String errorMessage);
+	}
+
+	/**
+	 * This is a temporary workaround to avoid an API change.
+	 *
+	 * @deprecated
+	 */
+	@Deprecated
+	public void addErrorObserver(ErrorObserver observer) {
+		errorObservers.add(observer);
+	}
+
+	/**
+	 * This is a temporary workaround to avoid an API change.
+	 *
+	 * @deprecated
+	 */
+	@Deprecated
+	public void removerErrorObserver(ErrorObserver observer) {
+		int i = errorObservers.indexOf(observer);
+		if (i >= 0) {
+			errorObservers.remove(i);
+		}
+	}
+
+	/**
+	 * This is a temporary workaround to avoid an API change.
+	 *
+	 * @deprecated
+	 */
+	@Deprecated
+	public void submitError(String context, String errorMessage) {
+		for (ErrorObserver observer : errorObservers) {
+			observer.receiveError(context, errorMessage);
+		}
+	}
 }
diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java
index d34b398..2d75ca6 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitJNI.java
@@ -118,31 +118,9 @@ public class SleuthkitJNI {
 
 	//Linked library loading
 	static {
-		try {
-			System.loadLibrary("zlib");
-		} catch (UnsatisfiedLinkError e) {
-			System.out.println("SleuthkitJNI: error loading zlib library, " + e.toString());
-		}
-		
-		try {
-			System.loadLibrary("libewf");
-		} catch (UnsatisfiedLinkError e) {
-			System.out.println("SleuthkitJNI: error loading libewf library, " + e.toString());
-		}
-
-		/* We should rename the Windows dll, to remove the lib prefix.
-		 * First try windows version of the name and then try Unix-style.
-		 */
-		try {
-			System.loadLibrary("libtsk_jni");
-		} catch (UnsatisfiedLinkError e1) {
-			try {
-				System.loadLibrary("tsk_jni");
-			} catch (UnsatisfiedLinkError e2) {
-				System.out.println("SleuthkitJNI: Error loading tsk_jni library " + e2.toString());
-			}
-		}
-	}
+		LibraryUtils.loadAuxilliaryLibs();
+		LibraryUtils.loadSleuthkitJNI();
+    }
 
 	public SleuthkitJNI() {
 	}
diff --git a/bindings/java/src/org/sleuthkit/datamodel/Transaction.java b/bindings/java/src/org/sleuthkit/datamodel/Transaction.java
new file mode 100755
index 0000000..780a619
--- /dev/null
+++ b/bindings/java/src/org/sleuthkit/datamodel/Transaction.java
@@ -0,0 +1,59 @@
+/*
+ * Sleuth Kit Data Model
+ * 
+ * Copyright 2013 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.datamodel;
+
+/**
+ * interface to encapsulate database transactions
+ *
+ *
+ *
+ */
+public interface Transaction {
+
+	/**
+	 * rollback whatever changes this transaction represents
+	 */
+	public void rollback();
+
+	/**
+	 * check whether this transaction has already been committed
+	 *
+	 * @return whether this transaction has already been committed
+	 */
+	public Boolean isCommitted();
+
+	/**
+	 * commit this transaction to the database
+	 */
+	public void commit();
+
+	/**
+	 *
+	 * close this Transaction so it cannot be committed or rolledback. A closed
+	 * Transaction no longer has a reference to a db Connection and methods
+	 * invoked on a closed Transaction have no effect.
+	 */
+	public void close();
+
+	/**
+	 *
+	 * @return true if this transaction is closed
+	 */
+	public Boolean isClosed();
+}
diff --git a/bindings/java/src/org/sleuthkit/datamodel/TskData.java b/bindings/java/src/org/sleuthkit/datamodel/TskData.java
index e18a9b9..971e3de 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/TskData.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/TskData.java
@@ -118,7 +118,7 @@ public class TskData {
 			return metaTypeStr;
 		}
 		
-		public static TSK_FS_META_TYPE_ENUM ValueOf(short metaType) {
+		public static TSK_FS_META_TYPE_ENUM valueOf(short metaType) {
 			for (TSK_FS_META_TYPE_ENUM type : TSK_FS_META_TYPE_ENUM.values()) {
 				if (type.getValue() == metaType) {
 					return type;
@@ -316,6 +316,7 @@ public class TskData {
 		public long getVsFlag(){
 			return vs_flag;
 		}
+		
 	} 
 
 	/**
@@ -450,48 +451,78 @@ public class TskData {
 	 */
 	public enum TSK_IMG_TYPE_ENUM {
 		/* The following describe the image type */
-		TSK_IMG_TYPE_DETECT(0),       // Auto Detection
-		TSK_IMG_TYPE_RAW_SING(1),     // Single raw file (dd)
-		TSK_IMG_TYPE_RAW_SPLIT(2),    // Split raw files
-		TSK_IMG_TYPE_AFF_AFF(4),      // Advanced Forensic Format
-		TSK_IMG_TYPE_AFF_AFD(8),      // AFF Multiple File
-		TSK_IMG_TYPE_AFF_AFM(16),     // AFF with external metadata
-		TSK_IMG_TYPE_AFF_ANY(32),     // All AFFLIB image formats (including beta ones)
-		TSK_IMG_TYPE_EWF_EWF(64),     // Expert Witness format (encase)
-		TSK_IMG_TYPE_UNSUPP(65535);   // Unsupported Image Type
+		TSK_IMG_TYPE_DETECT(0, "Auto Detect"),       // Auto Detection
+		TSK_IMG_TYPE_RAW_SING(1, "Raw Single"),     // Single raw file (dd)
+		TSK_IMG_TYPE_RAW_SPLIT(2, "Raw Split"),    // Split raw files
+		TSK_IMG_TYPE_AFF_AFF(4, "AFF"),      // Advanced Forensic Format
+		TSK_IMG_TYPE_AFF_AFD(8, "AFD"),      // AFF Multiple File
+		TSK_IMG_TYPE_AFF_AFM(16, "AFM"),     // AFF with external metadata
+		TSK_IMG_TYPE_AFF_ANY(32, "AFF"),     // All AFFLIB image formats (including beta ones)
+		TSK_IMG_TYPE_EWF_EWF(64, "E01"),     // Expert Witness format (encase)
+		TSK_IMG_TYPE_UNSUPP(65535, "Unknown");   // Unsupported Image Type
 
 		private long imgType;
+		private String name;
 
-		private TSK_IMG_TYPE_ENUM (long type){
+		private TSK_IMG_TYPE_ENUM (long type, String name){
 			this.imgType = type;
+			this.name = name;
 		}
 
+		public static TSK_IMG_TYPE_ENUM valueOf(long imgType) {
+			for (TSK_IMG_TYPE_ENUM type : TSK_IMG_TYPE_ENUM.values()) {
+				if (type.getValue() == imgType) {
+					return type;
+				}
+			}
+			throw new IllegalArgumentException("No TSK_IMG_TYPE_ENUM of value: " + imgType);
+		}
+		
 		/**
-		 * Get long value of the image tyoe
+		 * Get long value of the image type
 		 * @return the long value of the image type
 		 */
-		public long getImageType(){
+		public long getValue(){
 			return imgType;
 		}
+		
+		/**
+		 * Get the name of the image type
+		 * @return 
+		 */
+		public String getName() {
+			return name;
+		}
 	};
     
 	/**
 	 * Volume System type
 	 */
     public enum TSK_VS_TYPE_ENUM {
-        TSK_VS_TYPE_DETECT(0x0000),    ///< Use autodetection methods
-        TSK_VS_TYPE_DOS(0x0001),       ///< DOS Partition table
-        TSK_VS_TYPE_BSD(0x0002),       ///< BSD Partition table
-        TSK_VS_TYPE_SUN(0x0004),       ///< Sun VTOC
-        TSK_VS_TYPE_MAC(0x0008),       ///< Mac partition table
-        TSK_VS_TYPE_GPT(0x0010),       ///< GPT partition table
-        TSK_VS_TYPE_DBFILLER(0x00F0),  ///< fake partition table type for loaddb (for images that do not have a volume system)
-        TSK_VS_TYPE_UNSUPP(0xFFFF);    ///< Unsupported
+        TSK_VS_TYPE_DETECT(0x0000, "Auto Detect"),    ///< Use autodetection methods
+        TSK_VS_TYPE_DOS(0x0001, "DOS"),       ///< DOS Partition table
+        TSK_VS_TYPE_BSD(0x0002, "BSD"),       ///< BSD Partition table
+        TSK_VS_TYPE_SUN(0x0004, "SUN VTOC"),       ///< Sun VTOC
+        TSK_VS_TYPE_MAC(0x0008, "Mac"),       ///< Mac partition table
+        TSK_VS_TYPE_GPT(0x0010, "GPT"),       ///< GPT partition table
+        TSK_VS_TYPE_DBFILLER(0x00F0, "Fake"),  ///< fake partition table type for loaddb (for images that do not have a volume system)
+        TSK_VS_TYPE_UNSUPP(0xFFFF, "Unsupported");    ///< Unsupported
         
         private long vsType;
-        private TSK_VS_TYPE_ENUM(long type){
+		private String name;
+        private TSK_VS_TYPE_ENUM(long type, String name){
             this.vsType = type;
+			this.name = name;
         }
+		
+		public static TSK_VS_TYPE_ENUM valueOf(long vsType) {
+			for (TSK_VS_TYPE_ENUM type : TSK_VS_TYPE_ENUM.values()) {
+				if (type.getVsType() == vsType) {
+					return type;
+				}
+			}
+			throw new IllegalArgumentException("No TSK_VS_TYPE_ENUM of value: " + vsType);
+		}
         
 		
 		/**
@@ -501,6 +532,14 @@ public class TskData {
         public long getVsType() {
             return vsType;
         }
+		
+		/**
+		 * Get the name of the volume system type.
+		 * @return 
+		 */
+		public String getName() {
+			return name;
+		}
     };
 	
 	
diff --git a/bindings/java/src/org/sleuthkit/datamodel/Volume.java b/bindings/java/src/org/sleuthkit/datamodel/Volume.java
index 3584a1b..6af6dd4 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/Volume.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/Volume.java
@@ -26,8 +26,7 @@ import java.util.List;
  * Populated based on data in database.
  */
 public class Volume extends AbstractContent {
-	// @@@ We should comment somewhere what the units are (bytes, sectors, etc.)
-
+	
 	private long addr;
 	private long start; //in sectors, relative to volume system start
 	private long length; //in sectors
@@ -41,8 +40,8 @@ public class Volume extends AbstractContent {
 	 * @param db database object
 	 * @param obj_id
 	 * @param addr
-	 * @param start
-	 * @param length
+	 * @param start	in sectors, relative to start of VS
+	 * @param length in sectors
 	 * @param flags
 	 * @param desc
 	 */
@@ -123,7 +122,7 @@ public class Volume extends AbstractContent {
 	//methods get exact data from database. could be manipulated to get more
 	//meaningful data.
 	/**
-	 * get the partition address
+	 * get the unique partition address within this volume system (assigned by The Sleuth Kit)
 	 *
 	 * @return partition address in volume system
 	 */
@@ -132,16 +131,16 @@ public class Volume extends AbstractContent {
 	}
 
 	/**
-	 * get the starting byte offset
+	 * get the starting sector address of this volume relative to start of the volume system
 	 *
-	 * @return starting byte offset
+	 * @return starting address
 	 */
 	public long getStart() {
 		return start;
 	}
 
 	/**
-	 * get the length
+	 * get the length of the volume in sectors
 	 *
 	 * @return length
 	 */
@@ -168,7 +167,7 @@ public class Volume extends AbstractContent {
 	}
 
 	/**
-	 * get the description
+	 * get the description. This is set by the volume system and doesn't exist for all volumes.
 	 *
 	 * @return description
 	 */
diff --git a/bindings/java/src/org/sleuthkit/datamodel/VolumeSystem.java b/bindings/java/src/org/sleuthkit/datamodel/VolumeSystem.java
index 8265bc3..e6f8023 100644
--- a/bindings/java/src/org/sleuthkit/datamodel/VolumeSystem.java
+++ b/bindings/java/src/org/sleuthkit/datamodel/VolumeSystem.java
@@ -20,6 +20,7 @@ package org.sleuthkit.datamodel;
 
 import java.util.ArrayList;
 import java.util.List;
+import org.sleuthkit.datamodel.TskData.TSK_VS_TYPE_ENUM;
 
 /**
  * Represents a volume system. Populated based on data in database.
@@ -66,8 +67,8 @@ public class VolumeSystem extends AbstractContent {
 	 *
 	 * @return type
 	 */
-	public long getType() {
-		return type;
+	public TSK_VS_TYPE_ENUM getType() {
+		return TskData.TSK_VS_TYPE_ENUM.valueOf(type);
 	}
 
 	/**
diff --git a/configure b/configure
index 67ac36f..64d7318 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for sleuthkit 4.1.0.
+# Generated by GNU Autoconf 2.69 for sleuthkit 4.1.2.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -587,8 +587,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='sleuthkit'
 PACKAGE_TARNAME='sleuthkit'
-PACKAGE_VERSION='4.1.0'
-PACKAGE_STRING='sleuthkit 4.1.0'
+PACKAGE_VERSION='4.1.2'
+PACKAGE_STRING='sleuthkit 4.1.2'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -1340,7 +1340,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures sleuthkit 4.1.0 to adapt to many kinds of systems.
+\`configure' configures sleuthkit 4.1.2 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1410,7 +1410,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of sleuthkit 4.1.0:";;
+     short | recursive ) echo "Configuration of sleuthkit 4.1.2:";;
    esac
   cat <<\_ACEOF
 
@@ -1528,7 +1528,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-sleuthkit configure 4.1.0
+sleuthkit configure 4.1.2
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2068,7 +2068,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by sleuthkit $as_me 4.1.0, which was
+It was created by sleuthkit $as_me 4.1.2, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3088,7 +3088,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='sleuthkit'
- VERSION='4.1.0'
+ VERSION='4.1.2'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -16456,7 +16456,7 @@ fi
 #AC_HEADER_MAJOR
 #AC_HEADER_SYS_WAIT
 #AC_CHECK_HEADERS([fcntl.h inttypes.h limits.h locale.h memory.h netinet/in.h stdint.h stdlib.h string.h sys/ioctl.h sys/param.h sys/time.h unistd.h utime.h wchar.h wctype.h])
-for ac_header in err.h inttypes.h unistd.h stdint.h sys/param.h
+for ac_header in err.h inttypes.h unistd.h stdint.h sys/param.h sys/resource.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -17588,7 +17588,7 @@ done
 
 
 #AC_CHECK_FUNCS([dup2 gethostname isascii iswprint memset munmap regcomp select setlocale strcasecmp strchr strdup strerror strndup strrchr strtol strtoul strtoull utime wcwidth])
-for ac_func in ishexnumber err errx warn warnx vasprintf
+for ac_func in ishexnumber err errx warn warnx vasprintf getrusage
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -17945,7 +17945,7 @@ if test x"$ax_pthread_ok" = xyes; then
 $as_echo "#define HAVE_PTHREAD 1" >>confdefs.h
 
             CLIBS="$PTHREAD_LIBS $LIBS"
-            CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+            CPPFLAGS="$CPPFLAGS $PTHREAD_CFLAGS"
             LDFLAGS="$LDFLAGS $PTHREAD_CFLAGS"
             CC="$PTHREAD_CC"
         :
@@ -17962,7 +17962,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 # Not all compilers include /usr/local in the include and link path
 if test -d /usr/local/include; then
-    CFLAGS="$CFLAGS -I/usr/local/include"
+    CPPFLAGS="$CPPFLAGS -I/usr/local/include"
     LDFLAGS="$LDFLAGS -L/usr/local/lib"
 fi
 
@@ -17985,7 +17985,7 @@ if test "x$with_afflib" != "xno"; then :
   # Test the dir if they specified something beyond yes/no
     if test "x$with_afflib" != "xyes"; then :
   if test -d ${with_afflib}/include; then :
-  CFLAGS="$CFLAGS -I${with_afflib}/include"
+  CPPFLAGS="$CPPFLAGS -I${with_afflib}/include"
                 LDFLAGS="$LDFLAGS -L${with_afflib}/lib"
 else
   # Dir given was not correct
@@ -18082,7 +18082,7 @@ $as_echo "$as_me: checking for zlib" >&6;}
   { $as_echo "$as_me:${as_lineno-$LINENO}: LOOKING for zlib in ${with_zlib}" >&5
 $as_echo "$as_me: LOOKING for zlib in ${with_zlib}" >&6;}
        if test -d ${with_zlib}; then :
-  CFLAGS="$CFLAGS -I${with_zlib}/include"
+  CPPFLAGS="$CPPFLAGS -I${with_zlib}/include"
                 LDFLAGS="$LDFLAGS -L${with_zlib}/lib"
 else
   # Dir given was not correct
@@ -18234,7 +18234,7 @@ if test "x$with_libewf" != "xno"; then :
   # Test the dir if they specified something beyond yes/no
     if test "x$with_libewf" != "xyes"; then :
   if test -d ${with_libewf}/include; then :
-  CFLAGS="$CFLAGS -I${with_libewf}/include"
+  CPPFLAGS="$CPPFLAGS -I${with_libewf}/include"
                 LDFLAGS="$LDFLAGS -L${with_libewf}/lib"
 else
   # Dir given was not correct
@@ -19188,7 +19188,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by sleuthkit $as_me 4.1.0, which was
+This file was extended by sleuthkit $as_me 4.1.2, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -19254,7 +19254,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-sleuthkit config.status 4.1.0
+sleuthkit config.status 4.1.2
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index 586bcf1..55c5862 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,7 +4,7 @@
 
 AC_PREREQ(2.59)
 
-AC_INIT(sleuthkit, 4.1.0)
+AC_INIT(sleuthkit, 4.1.2)
 m4_include([m4/ax_pthread.m4])
 # include the version from 1.12.1. This will work for 
 m4_include([m4/cppunit.m4])
@@ -38,7 +38,7 @@ AC_HEADER_STDC
 #AC_HEADER_MAJOR
 #AC_HEADER_SYS_WAIT
 #AC_CHECK_HEADERS([fcntl.h inttypes.h limits.h locale.h memory.h netinet/in.h stdint.h stdlib.h string.h sys/ioctl.h sys/param.h sys/time.h unistd.h utime.h wchar.h wctype.h])
-AC_CHECK_HEADERS([err.h inttypes.h unistd.h stdint.h sys/param.h])
+AC_CHECK_HEADERS([err.h inttypes.h unistd.h stdint.h sys/param.h sys/resource.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
 AC_HEADER_STDBOOL
@@ -73,16 +73,16 @@ AC_FUNC_SELECT_ARGTYPES
 AC_FUNC_UTIME_NULL
 AC_FUNC_VPRINTF
 #AC_CHECK_FUNCS([dup2 gethostname isascii iswprint memset munmap regcomp select setlocale strcasecmp strchr strdup strerror strndup strrchr strtol strtoul strtoull utime wcwidth])
-AC_CHECK_FUNCS([ishexnumber err errx warn warnx vasprintf])
+AC_CHECK_FUNCS([ishexnumber err errx warn warnx vasprintf getrusage])
 AX_PTHREAD( [
             AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.])
             CLIBS="$PTHREAD_LIBS $LIBS"
-            CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+            CPPFLAGS="$CPPFLAGS $PTHREAD_CFLAGS"
             LDFLAGS="$LDFLAGS $PTHREAD_CFLAGS"
             CC="$PTHREAD_CC"],[])
 # Not all compilers include /usr/local in the include and link path
 if test -d /usr/local/include; then
-    CFLAGS="$CFLAGS -I/usr/local/include"
+    CPPFLAGS="$CPPFLAGS -I/usr/local/include"
     LDFLAGS="$LDFLAGS -L/usr/local/lib"
 fi
 
@@ -102,7 +102,7 @@ AS_IF([test "x$with_afflib" != "xno"],
     # Test the dir if they specified something beyond yes/no
     [AS_IF([test "x$with_afflib" != "xyes"],
         [AS_IF([test -d ${with_afflib}/include],
-            [CFLAGS="$CFLAGS -I${with_afflib}/include"
+            [CPPFLAGS="$CPPFLAGS -I${with_afflib}/include"
                 LDFLAGS="$LDFLAGS -L${with_afflib}/lib"],
             # Dir given was not correct
             [AC_MSG_FAILURE([AFFLIB directory not found at ${with_afflib}])])
@@ -134,7 +134,7 @@ AS_IF(
    [AS_IF([test "x$with_zlib" != "xyes"],
        [AC_MSG_NOTICE([LOOKING for zlib in ${with_zlib}])]
        [AS_IF([test -d ${with_zlib}],
-           [CFLAGS="$CFLAGS -I${with_zlib}/include"
+           [CPPFLAGS="$CPPFLAGS -I${with_zlib}/include"
                 LDFLAGS="$LDFLAGS -L${with_zlib}/lib"],
            # Dir given was not correct
            [AC_MSG_FAILURE([ZLIB directory not found at ${with_zlib}])]
@@ -173,7 +173,7 @@ AS_IF([test "x$with_libewf" != "xno"],
     # Test the dir if they specified something beyond yes/no
     [AS_IF([test "x$with_libewf" != "xyes"],
         [AS_IF([test -d ${with_libewf}/include],
-            [CFLAGS="$CFLAGS -I${with_libewf}/include"
+            [CPPFLAGS="$CPPFLAGS -I${with_libewf}/include"  
                 LDFLAGS="$LDFLAGS -L${with_libewf}/lib"],
             # Dir given was not correct
             [AC_MSG_FAILURE([libewf directory not found at ${with_libewf}])])
diff --git a/framework/RUNNING_msvs.txt b/framework/RUNNING_msvs.txt
index 8201f8b..b25230a 100755
--- a/framework/RUNNING_msvs.txt
+++ b/framework/RUNNING_msvs.txt
@@ -1,7 +1,7 @@
-This file contains some notes on running this library and tools as a developer from within Visual Studio.
-
-The libframework project will copy a framework config file into the debug or release folder. This is specially crafted to refer to the directory structure of the source code folder (which is different from the directory structure of the binary distribution of tsk_analyzeimg). 
-
-You should be able to run tsk_analyzeimg from inside of the debug or release folders. tsk_analyzeimg will find the framework_config file in the current folder and then refer to the pipeline config file in the SampleConfig folder. 
-
-If you want to debug tsk_analyzeimg, then you will need to edit the debug properties to change the working directory.  By default, Visual Studio will put you in the folder above the Debug or Release folders.  Set the "Working Directory" (set in Properties -> Configuration Properties -> Debugging) to be $(OutDir), which will be set to the Debug or Release folder.  You should then be able to use the Visual Studio debugger and use the standard framework and pipeline settings. 
+This file contains some notes on running this library and tools as a developer from within Visual Studio.
+
+The libframework project will copy a framework config file into the debug or release folder. This is specially crafted to refer to the directory structure of the source code folder (which is different from the directory structure of the binary distribution of tsk_analyzeimg). 
+
+You should be able to run tsk_analyzeimg from inside of the debug or release folders. tsk_analyzeimg will find the framework_config file in the current folder and then refer to the pipeline config file in the SampleConfig folder. 
+
+If you want to debug tsk_analyzeimg, then you will need to edit the debug properties to change the working directory.  By default, Visual Studio will put you in the folder above the Debug or Release folders.  Set the "Working Directory" (set in Properties -> Configuration Properties -> Debugging) to be $(OutDir), which will be set to the Debug or Release folder.  You should then be able to use the Visual Studio debugger and use the standard framework and pipeline settings. 
diff --git a/framework/SampleConfig/framework_config.xml b/framework/SampleConfig/framework_config.xml
index a6cb724..72c3320 100755
--- a/framework/SampleConfig/framework_config.xml
+++ b/framework/SampleConfig/framework_config.xml
@@ -1,22 +1,22 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- General version of the framework config.  Contains all possible settings -->
-<!-- For more information please consult the TskSystemProperties::PredefinedProperty member enumeration documentation at http://www.sleuthkit.org/sleuthkit/docs/framework-docs/classTskSystemProperties.html -->
-<TSK_FRAMEWORK_CONFIG>
-  <!-- <PROG_DIR>path</PROG_DIR> -->
-  <!-- <CONFIG_DIR>absolute path or #PROG_DIR#\... </CONFIG_DIR> -->
-  <!-- <MODULE_DIR>absolute path or #PROG_DIR#\... </MODULE_DIR> -->
-  <!-- <OUT_DIR>path</OUT_DIR> -->
-  <!-- <SYSTEM_OUT_DIR>path</SYSTEM_OUT_DIR> -->
-  <!-- <MODULE_OUT_DIR>path</MODULE_OUT_DIR> -->
-  <!-- <LOG_DIR>path</LOG_DIR> -->
-  <!-- <DB_HOST>host</DB_HOST> -->
-  <!-- <DB_PORT>port</DB_PORT> -->
-  <!-- <CARVE_DIR>path</CARVE_DIR> -->
-  <!-- <UNALLOC_SECTORS_IMG_FILE_NAME>filename</UNALLOC_SECTORS_IMG_FILE_NAME> -->
-  <!-- <MAX_UNALLOC_SECTORS_IMG_FILE_SIZE>number</MAX_UNALLOC_SECTORS_IMG_FILE_SIZE> -->
-  <!-- <CARVE_EXTRACT_KEEP_INPUT_FILES>true|false</CARVE_EXTRACT_KEEP_INPUT_FILES> -->
-  <!-- <CARVE_EXTRACT_KEEP_OUTPUT_FILES>true|false</CARVE_EXTRACT_KEEP_OUTPUT_FILES> -->
-  <!-- <SCALPEL_DIR>path</SCALPEL_DIR> -->
-  <!-- <SCALPEL_CONFIG_FILE>path</SCALPEL_CONFIG_FILE> -->  
-  <!-- <PIPELINE_CONFIG_FILE>path</PIPELINE_CONFIG_FILE>-->
-</TSK_FRAMEWORK_CONFIG>
+<?xml version="1.0" encoding="utf-8"?>
+<!-- General version of the framework config.  Contains all possible settings -->
+<!-- For more information please consult the TskSystemProperties::PredefinedProperty member enumeration documentation at http://www.sleuthkit.org/sleuthkit/docs/framework-docs/classTskSystemProperties.html -->
+<TSK_FRAMEWORK_CONFIG>
+  <!-- <PROG_DIR>path</PROG_DIR> -->
+  <!-- <CONFIG_DIR>absolute path or #PROG_DIR#\... </CONFIG_DIR> -->
+  <!-- <MODULE_DIR>absolute path or #PROG_DIR#\... </MODULE_DIR> -->
+  <!-- <OUT_DIR>path</OUT_DIR> -->
+  <!-- <SYSTEM_OUT_DIR>path</SYSTEM_OUT_DIR> -->
+  <!-- <MODULE_OUT_DIR>path</MODULE_OUT_DIR> -->
+  <!-- <LOG_DIR>path</LOG_DIR> -->
+  <!-- <DB_HOST>host</DB_HOST> -->
+  <!-- <DB_PORT>port</DB_PORT> -->
+  <!-- <CARVE_DIR>path</CARVE_DIR> -->
+  <!-- <UNALLOC_SECTORS_IMG_FILE_NAME>filename</UNALLOC_SECTORS_IMG_FILE_NAME> -->
+  <!-- <MAX_UNALLOC_SECTORS_IMG_FILE_SIZE>number</MAX_UNALLOC_SECTORS_IMG_FILE_SIZE> -->
+  <!-- <CARVE_EXTRACT_KEEP_INPUT_FILES>true|false</CARVE_EXTRACT_KEEP_INPUT_FILES> -->
+  <!-- <CARVE_EXTRACT_KEEP_OUTPUT_FILES>true|false</CARVE_EXTRACT_KEEP_OUTPUT_FILES> -->
+  <!-- <SCALPEL_DIR>path</SCALPEL_DIR> -->
+  <!-- <SCALPEL_CONFIG_FILE>path</SCALPEL_CONFIG_FILE> -->  
+  <!-- <PIPELINE_CONFIG_FILE>path</PIPELINE_CONFIG_FILE>-->
+</TSK_FRAMEWORK_CONFIG>
diff --git a/framework/SampleConfig/framework_config_bindist.xml b/framework/SampleConfig/framework_config_bindist.xml
index 8b4829c..866704f 100755
--- a/framework/SampleConfig/framework_config_bindist.xml
+++ b/framework/SampleConfig/framework_config_bindist.xml
@@ -1,9 +1,9 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Used in binary distribution of framework  - Contains only the settings that are relevant for it -->
-<!-- For more information please consult the TskSystemProperties::PredefinedProperty member enumeration documentation at http://www.sleuthkit.org/sleuthkit/docs/framework-docs/classTskSystemProperties.html -->
-<TSK_FRAMEWORK_CONFIG>
-  <CONFIG_DIR>#PROG_DIR#</CONFIG_DIR>
-  <MODULE_DIR>#PROG_DIR#\..\modules\</MODULE_DIR>  
-  <MODULE_CONFIG_DIR>#PROG_DIR#\..\modules\</MODULE_CONFIG_DIR>  
-  <!-- <SCALPEL_DIR>path</SCALPEL_DIR> -->
-</TSK_FRAMEWORK_CONFIG>
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Used in binary distribution of framework  - Contains only the settings that are relevant for it -->
+<!-- For more information please consult the TskSystemProperties::PredefinedProperty member enumeration documentation at http://www.sleuthkit.org/sleuthkit/docs/framework-docs/classTskSystemProperties.html -->
+<TSK_FRAMEWORK_CONFIG>
+  <CONFIG_DIR>#PROG_DIR#</CONFIG_DIR>
+  <MODULE_DIR>#PROG_DIR#\..\modules\</MODULE_DIR>  
+  <MODULE_CONFIG_DIR>#PROG_DIR#\..\modules\</MODULE_CONFIG_DIR>  
+  <!-- <SCALPEL_DIR>path</SCALPEL_DIR> -->
+</TSK_FRAMEWORK_CONFIG>
diff --git a/framework/SampleConfig/framework_config_template.xml b/framework/SampleConfig/framework_config_template.xml
index 6355eeb..167602a 100644
--- a/framework/SampleConfig/framework_config_template.xml
+++ b/framework/SampleConfig/framework_config_template.xml
@@ -1,9 +1,9 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Template of framework config.  Contains enough settings for installation. -->
-<!-- For more information please consult the TskSystemProperties::PredefinedProperty member enumeration documentation at http://www.sleuthkit.org/sleuthkit/docs/framework-docs/classTskSystemProperties.html -->
-<TSK_FRAMEWORK_CONFIG>
-  <CONFIG_DIR>#CONFIGDIRPATH#</CONFIG_DIR>
-  <MODULE_DIR>#MODULEDIRPATH#</MODULE_DIR>
-  <MODULE_CONFIG_DIR>#MODULECONFIGDIRPATH#</MODULE_CONFIG_DIR>
-  <PIPELINE_CONFIG_FILE>#CONFIG_DIR#/pipeline_config.xml</PIPELINE_CONFIG_FILE>
-</TSK_FRAMEWORK_CONFIG>
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Template of framework config.  Contains enough settings for installation. -->
+<!-- For more information please consult the TskSystemProperties::PredefinedProperty member enumeration documentation at http://www.sleuthkit.org/sleuthkit/docs/framework-docs/classTskSystemProperties.html -->
+<TSK_FRAMEWORK_CONFIG>
+  <CONFIG_DIR>#CONFIGDIRPATH#</CONFIG_DIR>
+  <MODULE_DIR>#MODULEDIRPATH#</MODULE_DIR>
+  <MODULE_CONFIG_DIR>#MODULECONFIGDIRPATH#</MODULE_CONFIG_DIR>
+  <PIPELINE_CONFIG_FILE>#CONFIG_DIR#/pipeline_config.xml</PIPELINE_CONFIG_FILE>
+</TSK_FRAMEWORK_CONFIG>
diff --git a/framework/SampleConfig/framework_config_unixdev.xml b/framework/SampleConfig/framework_config_unixdev.xml
index 8e5344a..7175b28 100644
--- a/framework/SampleConfig/framework_config_unixdev.xml
+++ b/framework/SampleConfig/framework_config_unixdev.xml
@@ -1,9 +1,9 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- General version of the framework config for running in src tree in Linux/OS X. -->
-<!-- For more information please consult the TskSystemProperties::PredefinedProperty member enumeration documentation at http://www.sleuthkit.org/sleuthkit/docs/framework-docs/classTskSystemProperties.html -->
-<TSK_FRAMEWORK_CONFIG>
-  <CONFIG_DIR>#PROG_DIR#/../../../SampleConfig</CONFIG_DIR>
-  <PIPELINE_CONFIG_FILE>#CONFIG_DIR#/pipeline_config.xml</PIPELINE_CONFIG_FILE>
-  <MODULE_DIR>#PROG_DIR#/../../../runtime/modules</MODULE_DIR>
-  <MODULE_CONFIG_DIR>#PROG_DIR#/../../../runtime/modules_config</MODULE_CONFIG_DIR>
-</TSK_FRAMEWORK_CONFIG>
+<?xml version="1.0" encoding="utf-8"?>
+<!-- General version of the framework config for running in src tree in Linux/OS X. -->
+<!-- For more information please consult the TskSystemProperties::PredefinedProperty member enumeration documentation at http://www.sleuthkit.org/sleuthkit/docs/framework-docs/classTskSystemProperties.html -->
+<TSK_FRAMEWORK_CONFIG>
+  <CONFIG_DIR>#PROG_DIR#/../../../SampleConfig</CONFIG_DIR>
+  <PIPELINE_CONFIG_FILE>#CONFIG_DIR#/pipeline_config.xml</PIPELINE_CONFIG_FILE>
+  <MODULE_DIR>#PROG_DIR#/../../../runtime/modules</MODULE_DIR>
+  <MODULE_CONFIG_DIR>#PROG_DIR#/../../../runtime/modules_config</MODULE_CONFIG_DIR>
+</TSK_FRAMEWORK_CONFIG>
diff --git a/framework/SampleConfig/framework_config_win32dev.xml b/framework/SampleConfig/framework_config_win32dev.xml
index 2530836..6fdfb1b 100755
--- a/framework/SampleConfig/framework_config_win32dev.xml
+++ b/framework/SampleConfig/framework_config_win32dev.xml
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Framework config that is used when running from the VS dev environment - gets copied into debug/release folder. - contains only relevant settings -->
-<!-- For more information please consult the TskSystemProperties::PredefinedProperty member enumeration documentation at http://www.sleuthkit.org/sleuthkit/docs/framework-docs/classTskSystemProperties.html -->
-<TSK_FRAMEWORK_CONFIG>
-  <CONFIG_DIR>#PROG_DIR#\..\SampleConfig</CONFIG_DIR>
-  <MODULE_DIR>#PROG_DIR#</MODULE_DIR>
-  <MODULE_CONFIG_DIR>#PROG_DIR#</MODULE_CONFIG_DIR>
-</TSK_FRAMEWORK_CONFIG>
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Framework config that is used when running from the VS dev environment - gets copied into debug/release folder. - contains only relevant settings -->
+<!-- For more information please consult the TskSystemProperties::PredefinedProperty member enumeration documentation at http://www.sleuthkit.org/sleuthkit/docs/framework-docs/classTskSystemProperties.html -->
+<TSK_FRAMEWORK_CONFIG>
+  <CONFIG_DIR>#PROG_DIR#\..\SampleConfig</CONFIG_DIR>
+  <MODULE_DIR>#PROG_DIR#</MODULE_DIR>
+  <MODULE_CONFIG_DIR>#PROG_DIR#</MODULE_CONFIG_DIR>
+</TSK_FRAMEWORK_CONFIG>
diff --git a/framework/SampleConfig/pipeline_config.xml b/framework/SampleConfig/pipeline_config.xml
index 247ef67..3172753 100755
--- a/framework/SampleConfig/pipeline_config.xml
+++ b/framework/SampleConfig/pipeline_config.xml
@@ -1,25 +1,25 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Contains only the modules that ship with TSK -->
-<PIPELINE_CONFIG>
-    <PIPELINE type="FileAnalysis">
-      <MODULE order="1" type="plugin" location="tskHashCalcModule"/>
-<!--<MODULE order="2" type="plugin" location="tskHashLookupModule" arguments="TODO: See README for how to create NSRL index file"/>-->
-
-      <MODULE order="3" type="plugin" location="tskFileTypeSigModule"/>
-      <MODULE order="4" type="plugin" location="tskEntropyModule"/>
-      <MODULE order="5" type="plugin" location="tskZipExtractionModule"/>
-      <MODULE order="6" type="plugin" location="tskLibExifModule"/>
-    </PIPELINE>
-
-    <PIPELINE type="PostProcessing">
-      <!--This pipeline configuration assumes that the RegRipper executable is named rip.exe and is present in the program directory-->
-      <!--<MODULE order="1" type="plugin" location="tskRegRipperModule" arguments="-e #PROG_DIR#/RegRipper/rip.exe; -o #MODULE_OUT_DIR#/RegRipper/"/>-->
-
-      <MODULE order="2" type="plugin" location="tskInterestingFilesModule"/>
-
-      <MODULE order="3" type="plugin" location="tskSaveInterestingFilesModule"/>
-
-      <MODULE order="4" type="plugin" location="tskSummaryReportModule"/>
-
-    </PIPELINE>
-</PIPELINE_CONFIG>
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Contains only the modules that ship with TSK -->
+<PIPELINE_CONFIG>
+    <PIPELINE type="FileAnalysis">
+      <MODULE order="1" type="plugin" location="tskHashCalcModule"/>
+<!--<MODULE order="2" type="plugin" location="tskHashLookupModule" arguments="TODO: See README for how to create NSRL index file"/>-->
+
+      <MODULE order="3" type="plugin" location="tskFileTypeSigModule"/>
+      <MODULE order="4" type="plugin" location="tskEntropyModule"/>
+      <MODULE order="5" type="plugin" location="tskZipExtractionModule"/>
+      <MODULE order="6" type="plugin" location="tskLibExifModule"/>
+    </PIPELINE>
+
+    <PIPELINE type="PostProcessing">
+      <!--This pipeline configuration assumes that the RegRipper executable is named rip.exe and is present in the program directory-->
+      <!--<MODULE order="1" type="plugin" location="tskRegRipperModule" arguments="-e #PROG_DIR#/RegRipper/rip.exe; -o #MODULE_OUT_DIR#/RegRipper/"/>-->
+
+      <MODULE order="2" type="plugin" location="tskInterestingFilesModule"/>
+
+      <MODULE order="3" type="plugin" location="tskSaveInterestingFilesModule"/>
+
+      <MODULE order="4" type="plugin" location="tskSummaryReportModule"/>
+
+    </PIPELINE>
+</PIPELINE_CONFIG>
diff --git a/framework/docs/fileToDoxPage.py b/framework/docs/fileToDoxPage.py
index 17c71d8..c5ff196 100755
--- a/framework/docs/fileToDoxPage.py
+++ b/framework/docs/fileToDoxPage.py
@@ -1,28 +1,28 @@
-from __future__ import with_statement
-
-import os
-from optparse import OptionParser
-                 
-"""
-Creates a Doxygen page that displays the contents of a file.
-"""
-if __name__ == "__main__":
-    parser = OptionParser(usage = 'usage: %prog <src_file_path> <output_dir> <page_name> <page_title>')
-    (options, args) = parser.parse_args()
-    if len(args) != 4:
-        parser.error("incorrect number of arguments")
-
-    with open(args[0], 'r') as srcFile:
-        srcFileContents = srcFile.read()
-        
-    (fileName, fileExt) = os.path.splitext(args[0])
-        
-    with open(os.path.join(args[1], args[2] + '.dox'), 'w') as doxFile:
-        doxFile.write('/*! \\page ' + args[2] + '_page ' + args[3] + '\n\n')
-        if fileExt is None:
-            doxFile.write('\\code\n\n')
-        else:
-            doxFile.write('\\code{' + fileExt + '}\n\n')
-        doxFile.write(srcFileContents)
-        doxFile.write('\n\n\\endcode\n\n*/')
-
+from __future__ import with_statement
+
+import os
+from optparse import OptionParser
+                 
+"""
+Creates a Doxygen page that displays the contents of a file.
+"""
+if __name__ == "__main__":
+    parser = OptionParser(usage = 'usage: %prog <src_file_path> <output_dir> <page_name> <page_title>')
+    (options, args) = parser.parse_args()
+    if len(args) != 4:
+        parser.error("incorrect number of arguments")
+
+    with open(args[0], 'r') as srcFile:
+        srcFileContents = srcFile.read()
+        
+    (fileName, fileExt) = os.path.splitext(args[0])
+        
+    with open(os.path.join(args[1], args[2] + '.dox'), 'w') as doxFile:
+        doxFile.write('/*! \\page ' + args[2] + '_page ' + args[3] + '\n\n')
+        if fileExt is None:
+            doxFile.write('\\code\n\n')
+        else:
+            doxFile.write('\\code{' + fileExt + '}\n\n')
+        doxFile.write(srcFileContents)
+        doxFile.write('\n\n\\endcode\n\n*/')
+
diff --git a/framework/docs/img_db_schema_v1_5.dox b/framework/docs/img_db_schema_v1_5.dox
index 970edd1..6ec1db5 100755
--- a/framework/docs/img_db_schema_v1_5.dox
+++ b/framework/docs/img_db_schema_v1_5.dox
@@ -1,181 +1,181 @@
-/*! \page img_db_schema_v1_5_page SQLite Image Database Schema v1.5
-
-\section general_information_tables Analysis Process Metadata Tables
-
-\subsection db_info_table db_info
-Contains metadata about the software that produced the image database.
-- <i>name</i> - Name of the software, e.g., DBSchema, Sleuth Kit, etc. (TEXT)
-- <i>version</i> - Version of the software, e.g., 1.5, 4.0.0, etc. (TEXT)
-
-\subsection modules_table modules
-Contains one row for each module used to produce the image database.
-- <i>module_id</i> - Id assigned to the module (INTEGER) 
-- <i>name</i> - Name of the module (TEXT)
-- <i>description</i> - Description of the module (TEXT)
-
-\subsection module_status_table module_status
-Contains one row for each status code returned by the modules in the file analysis pipeline.
-- <i>module_id</i> - Id assigned to the module (INTEGER - foreign key, \ref modules_table) 
-- <i>file_id</i> - Id assigned to the file the module analyzed (INTEGER - foreign key, \ref files_table)
-- <i>status</i> - Status reported by the module on completion of its analysis of the file (INTEGER -  \ref TskModule::Status) 
-
-\section image_tables Image Tables
-
-\subsection image_info_table image_info 
-Contains one row for each image in the set of images analyzed to produce the image database.  
-There will be more than one row in this table for split images. 
-- <i>type</i> - Disk image file type (INTEGER - \ref TSK_IMG_TYPE_ENUM)
-- <i>ssize</i> - Block (sector) size of imaged device in bytes (INTEGER)
-
-\subsection image_names_table img_names
-Contains one row for each image in the set of images analyzed to produce the image database.  
-There will be more than one row in this table for split images. 
-- <i>name</i> - Image file path (TEXT)
-- <i>seq</i> - Sequence number, counting up from one, of the image within the image set (INTEGER) 
-
-\section volume_tables Volume / Partition Tables 
-
-\subsection vol_info_table vol_info
-Contains one row for every volume/partition in the set of images analyzed to produce the database.
-- <i>vol_id</i> - Id assigned to the volume / partition (INTEGER)
-- <i>sect_start</i> - Block (sector) offset of the start of the volume / partition in the image (INTEGER)
-- <i>sect_len</i> - Number of blocks (sectors) in the volume / partition (INTEGER)
-- <i>description</i> - Description of the volume/partition (TEXT)
-- <i>flags</i> - Flags for the the volume/partition (INTEGER - \ref TSK_VS_PART_FLAG_ENUM)
-
-\section file_system_tables File System Tables
-
-\subsection fs_info_table fs_info
-Contains one row for for every file system in the set of images analyzed to produce the database. 
-- <i>fs_id</i> - Id assigned to the file system (INTEGER)
-- <i>img_byte_offset</i> - Byte offset of the start of the file system within the image (INTEGER)
-- <i>vol_id</i> - Id of the volume/partition where the file system resides (INTEGER - foreign key, \ref vol_info_table)
-- <i>fs_type</i> - File system type (INTEGER - \ref TSK_FS_TYPE_ENUM)
-- <i>block_size</i> - Block size in bytes (INTEGER)
-- <i>block_count</i> - Number of blocks (INTEGER)
-- <i>root_inum</i> - Metadata address of root directory (INTEGER)
-- <i>first_inum</i> - First valid metadata address (INTEGER)
-- <i>last_inum</i> - Last valid metadata address (INTEGER)
-
-\subsection files_table files
-Contains one row for for every file found in the set of images analyzed to produce the database.  
-- <i>file_id</i> - Id assigned to the file (INTEGER)
-- <i>par_file_id</i> - Parent file of the file, e.g., a directory for a regular file, an archive file for a derived file (INTEGER - foreign key, \ref files_table)
-- <i>name</i> - File name (TEXT)
-- <i>full_path</i> - Path of the file in the image (TEXT)
-- <i>size</i> - Size in bytes (INTEGER)
-- <i>type_id</i> - File classification by image analysis system, e.g., file system file, carved file, etc. (INTEGER - \ref TSK_DB_FILES_TYPE_ENUM)
-- <i>dir_type</i> - File type as specified in the directory metadata structure, e.g., directory, regular file, etc. (INTEGER - \ref TSK_FS_NAME_TYPE_ENUM)
-- <i>meta_type</i> - File meta-type, e.g., directory, regular file, etc. (INTEGER - \ref TSK_FS_META_TYPE_ENUM)
-- <i>dir_flags</i> -  Allocation status (INTEGER - \ref TSK_FS_NAME_FLAG_ENUM)
-- <i>meta_flags</i> - File metadata structure flags (INTEGER - \ref TSK_FS_META_FLAG_ENUM)
-- <i>ctime</i> - Last file / metadata status change time as seconds since Jan 1, 1970 UTC (INTEGER)
-- <i>crtime</i> - Create time (INTEGER)
-- <i>atime</i> - Access time (INTEGER)
-- <i>mtime</i> - Modification time (INTEGER)
-- <i>mode</i> - Unix-style file permissions (INTEGER - \ref TSK_FS_META_MODE_ENUM)
-- <i>uid</i> - Owner id (INTEGER)
-- <i>gid</i> - Group id (INTEGER)
-- <i>status</i> - Analysis status (INTEGER - \ref TskImgDB::FILE_STATUS)
-
-\subsection file_hashes_table file_hashes
-Contains one row of file content hash values for every file found in the set of images analyzed to produce the database.
-The hash values may be NULL if not computed.
-- <i>file_id</i> - Id assigned to the file (INTEGER - foreign key, \ref files_table)
-- <i>md5</i> - MD5 hash (TEXT)
-- <i>sha1</i> - SHA-1 hash (TEXT)
-- <i>sha2_256</i> - SHA-256 hash (TEXT)
-- <i>sha2_512</i> - SHA-512 hash (TEXT)
-- <i>known</i> - Known status as determined by hash database lookups (INTEGER - \ref TskImgDB::KNOWN_STATUS)
-
-\subsection fs_files_table fs_files
-Contains one row for each file discovered during file system analysis.
-- <i>file_id</i> - Id assigned to the file (INTEGER - foreign key, \ref files_table)
-- <i>fs_id</i> - Id of the file system that contained the file (INTEGER - foreign key, \ref fs_info_table)
-- <i>fs_file_id</i> - Id assigned to the file by the file system, e.g., an inode number (INTEGER)
-- <i>attr_id</i> - The MFT attribute id of files in NTFS file systems (INTEGER)
-- <i>attr_type</i> - The MFT attribute type of files in NTFS file systems (INTEGER - \ref TSK_FS_ATTR_TYPE_ENUM)
-
-\subsection fs_blocks_table fs_blocks
-Contains one row for each contiguous run of blocks in a file system file.
-- <i>file_id</i> - Id assigned to the file (INTEGER - foreign key, \ref files_table)
-- <i>fs_id</i> - Id assigned to the file system that contains the file (INTEGER - foreign key, \ref fs_info_table)
-- <i>seq</i> - Sequence number, counting up from one, of the run within the set of runs (INTEGER)
-- <i>blk_start</i> - Logical block offset of the beginning of the run (INTEGER)
-- <i>blk_len</i> - Number of blocks in the run (INTEGER)
-
-\subsection alloc_unalloc_map_table alloc_unalloc_map
-Contains one row for each contiguous run of unallocated blocks (sectors) in a volume / partition.
-These runs are used to create unallocated sectors files in preparation for carving.
-- <i>unalloc_img_id</i> - Id assigned to the unallocated sectors file that contains the run (INTEGER)
-- <i>vol_id</i> - Id of the volume / partition that contains the run (INTEGER - foreign key, \ref vol_info_table)
-- <i>unalloc_img_sect_start</i> - Sector offset of the beginning of the run in the unallocated sectors image file (INTEGER)
-- <i>orig_img_sect_start</i> - Sector offset of the beginning of the run in the image (INTEGER)
-- <i>sect_len</i> - Length of the run in sectors (INTEGER)
-
-\subsection unalloc_img_status_table unalloc_img_status
-Contains one row for each unallocated sectors file created in preparation for carving.
-- <i>unalloc_img_id</i> - Id assigned to the file (INTEGER) 
-- <i>status</i> - Analysis status (INTEGER - \ref TskImgDB::UNALLOC_IMG_STATUS) 
-
-\subsection carved_files_table carved_files
-Contains one row for each file carved from unallocated space.
-- <i>file_id</i> - Id assigned to the file (INTEGER - foreign key, \ref files_table)
-- <i>vol_id</i> - Volume/partition where the carved file resided (INTEGER - foreign key, \ref vol_info_table)
-
-\subsection carved_sectors_table carved_sectors
-Contains one row for each contiguous run of blocks (sectors) of unallocated space used to create carved files.
-- <i>file_id</i> - Id assigned to the carved file that contains the run (INTEGER - foreign key, \ref files_table)
-- <i>seq</i> - Sequence number, counting up from one, of the run within the set of runs in the carved file (INTEGER)
-- <i>sect_start</i> - Sector offset of the run in the image (INTEGER)
-- <i>sect_len</i> - Length of the run in sectors (INTEGER)
-
-\subsection unused_sectors_table unused_sectors
-Contains one row for each contiguous run of blocks (sectors) of unallocated space left over after carving.
-These runs are used to create unused sectors files to pass through the file analysis pipeline.
-- <i>file_id</i> - Id assigned to the unused sectors file that contains the run (INTEGER - foreign key, \ref files_table)
-- <i>vol_id</i> - Id of the volume / partition that contains the run (INTEGER - foreign key, \ref vol_info_table)
-- <i>sect_start</i> - Sector offset of the run in the image (INTEGER)
-- <i>sect_len</i> - Length of the run in sectors (INTEGER)
-
-\subsection derived_files_table derived_files
-Contains one row for each file derived from another file, e.g., files extracted from archive files.
-- <i>file_id</i> - Id assigned to the file (INTEGER - foreign key, \ref files_table)
-- <i>derivation_details</i> - Unused (TEXT)
-
-\section blackboard_tables Blackboard Tables
-
-\subsection blackboard_artifacts_table blackboard_artifacts
-Contains one row for each artifact found in the set of images analyzed to produce the database.
-- <i>artifact_id</i> - Id assigned to the artifact (INTEGER)
-- <i>obj_id</i> - Id assigned to the file associated with the artifact (INTEGER - foreign key, \ref files_table)
-- <i>artifact_type_id</i> - Id assigned to the type of artifact (INTEGER - foreign key, \ref blackboard_attribute_types_table)
-
-\subsection blackboard_attributes_table blackboard_attributes
-Stores the values of the name-value pairs that are the attributes associated with an artifact. 
-Only one of the value columns should be populated.
-- <i>artifact_id</i> - Id assigned to the artifact (INTEGER)
-- <i>source</i> - Source string, should be the name of the module that discovered the artifact (TEXT)
-- <i>context</i> - Additional context information (TEXT)
-- <i>attribute_type_id</i> - Id for the type of attribute (INTEGER - foreign key, \ref blackboard_attribute_types_table)
-- <i>value_type</i> - The type of the value, serves as discriminant for the union of the value columns ( INTEGER - \ref TskImgDB::VALUE_TYPE)
-- <i>value_byte</i> - A blob of binary data (BLOB)
-- <i>value_text</i> - A string of text (TEXT)
-- <i>value_int32</i> - An 32-bit integer (INTEGER - 0 by default default)
-- <i>value_int64</i> - A 64-bit integer (INTEGER - 0 by default default)
-- <i>value_double</i> - A double (NUMERIC - 0 by default default)
-- <i>obj_id</i> - Id assigned to the file associated with the attribute (INTEGER - foreign key, \ref files_table)
-
-\subsection blackboard_artifact_types_table blackboard_artifact_types
-Artifact types.
-- <i>artifact_type_id</i> - Id assigned to the type (INTEGER)
-- <i>type_name</i> - A unique string identifier for the type (TEXT)
-- <i>display_name</i> - A human-readable display name for the type (TEXT)
-
-\subsection blackboard_attribute_types_table blackboard_attribute_types
-Artifact attribute types.
-- <i>attribute_type_id</i> - Id assigned to the type (INTEGER)
-- <i>type_name</i> - A unique string identifier for the type (TEXT)
-- <i>display_name</i> - A human-readable display name for the type (TEXT)
-
+/*! \page img_db_schema_v1_5_page SQLite Image Database Schema v1.5
+
+\section general_information_tables Analysis Process Metadata Tables
+
+\subsection db_info_table db_info
+Contains metadata about the software that produced the image database.
+- <i>name</i> - Name of the software, e.g., DBSchema, Sleuth Kit, etc. (TEXT)
+- <i>version</i> - Version of the software, e.g., 1.5, 4.0.0, etc. (TEXT)
+
+\subsection modules_table modules
+Contains one row for each module used to produce the image database.
+- <i>module_id</i> - Id assigned to the module (INTEGER) 
+- <i>name</i> - Name of the module (TEXT)
+- <i>description</i> - Description of the module (TEXT)
+
+\subsection module_status_table module_status
+Contains one row for each status code returned by the modules in the file analysis pipeline.
+- <i>module_id</i> - Id assigned to the module (INTEGER - foreign key, \ref modules_table) 
+- <i>file_id</i> - Id assigned to the file the module analyzed (INTEGER - foreign key, \ref files_table)
+- <i>status</i> - Status reported by the module on completion of its analysis of the file (INTEGER -  \ref TskModule::Status) 
+
+\section image_tables Image Tables
+
+\subsection image_info_table image_info 
+Contains one row for each image in the set of images analyzed to produce the image database.  
+There will be more than one row in this table for split images. 
+- <i>type</i> - Disk image file type (INTEGER - \ref TSK_IMG_TYPE_ENUM)
+- <i>ssize</i> - Block (sector) size of imaged device in bytes (INTEGER)
+
+\subsection image_names_table img_names
+Contains one row for each image in the set of images analyzed to produce the image database.  
+There will be more than one row in this table for split images. 
+- <i>name</i> - Image file path (TEXT)
+- <i>seq</i> - Sequence number, counting up from one, of the image within the image set (INTEGER) 
+
+\section volume_tables Volume / Partition Tables 
+
+\subsection vol_info_table vol_info
+Contains one row for every volume/partition in the set of images analyzed to produce the database.
+- <i>vol_id</i> - Id assigned to the volume / partition (INTEGER)
+- <i>sect_start</i> - Block (sector) offset of the start of the volume / partition in the image (INTEGER)
+- <i>sect_len</i> - Number of blocks (sectors) in the volume / partition (INTEGER)
+- <i>description</i> - Description of the volume/partition (TEXT)
+- <i>flags</i> - Flags for the the volume/partition (INTEGER - \ref TSK_VS_PART_FLAG_ENUM)
+
+\section file_system_tables File System Tables
+
+\subsection fs_info_table fs_info
+Contains one row for for every file system in the set of images analyzed to produce the database. 
+- <i>fs_id</i> - Id assigned to the file system (INTEGER)
+- <i>img_byte_offset</i> - Byte offset of the start of the file system within the image (INTEGER)
+- <i>vol_id</i> - Id of the volume/partition where the file system resides (INTEGER - foreign key, \ref vol_info_table)
+- <i>fs_type</i> - File system type (INTEGER - \ref TSK_FS_TYPE_ENUM)
+- <i>block_size</i> - Block size in bytes (INTEGER)
+- <i>block_count</i> - Number of blocks (INTEGER)
+- <i>root_inum</i> - Metadata address of root directory (INTEGER)
+- <i>first_inum</i> - First valid metadata address (INTEGER)
+- <i>last_inum</i> - Last valid metadata address (INTEGER)
+
+\subsection files_table files
+Contains one row for for every file found in the set of images analyzed to produce the database.  
+- <i>file_id</i> - Id assigned to the file (INTEGER)
+- <i>par_file_id</i> - Parent file of the file, e.g., a directory for a regular file, an archive file for a derived file (INTEGER - foreign key, \ref files_table)
+- <i>name</i> - File name (TEXT)
+- <i>full_path</i> - Path of the file in the image (TEXT)
+- <i>size</i> - Size in bytes (INTEGER)
+- <i>type_id</i> - File classification by image analysis system, e.g., file system file, carved file, etc. (INTEGER - \ref TSK_DB_FILES_TYPE_ENUM)
+- <i>dir_type</i> - File type as specified in the directory metadata structure, e.g., directory, regular file, etc. (INTEGER - \ref TSK_FS_NAME_TYPE_ENUM)
+- <i>meta_type</i> - File meta-type, e.g., directory, regular file, etc. (INTEGER - \ref TSK_FS_META_TYPE_ENUM)
+- <i>dir_flags</i> -  Allocation status (INTEGER - \ref TSK_FS_NAME_FLAG_ENUM)
+- <i>meta_flags</i> - File metadata structure flags (INTEGER - \ref TSK_FS_META_FLAG_ENUM)
+- <i>ctime</i> - Last file / metadata status change time as seconds since Jan 1, 1970 UTC (INTEGER)
+- <i>crtime</i> - Create time (INTEGER)
+- <i>atime</i> - Access time (INTEGER)
+- <i>mtime</i> - Modification time (INTEGER)
+- <i>mode</i> - Unix-style file permissions (INTEGER - \ref TSK_FS_META_MODE_ENUM)
+- <i>uid</i> - Owner id (INTEGER)
+- <i>gid</i> - Group id (INTEGER)
+- <i>status</i> - Analysis status (INTEGER - \ref TskImgDB::FILE_STATUS)
+
+\subsection file_hashes_table file_hashes
+Contains one row of file content hash values for every file found in the set of images analyzed to produce the database.
+The hash values may be NULL if not computed.
+- <i>file_id</i> - Id assigned to the file (INTEGER - foreign key, \ref files_table)
+- <i>md5</i> - MD5 hash (TEXT)
+- <i>sha1</i> - SHA-1 hash (TEXT)
+- <i>sha2_256</i> - SHA-256 hash (TEXT)
+- <i>sha2_512</i> - SHA-512 hash (TEXT)
+- <i>known</i> - Known status as determined by hash database lookups (INTEGER - \ref TskImgDB::KNOWN_STATUS)
+
+\subsection fs_files_table fs_files
+Contains one row for each file discovered during file system analysis.
+- <i>file_id</i> - Id assigned to the file (INTEGER - foreign key, \ref files_table)
+- <i>fs_id</i> - Id of the file system that contained the file (INTEGER - foreign key, \ref fs_info_table)
+- <i>fs_file_id</i> - Id assigned to the file by the file system, e.g., an inode number (INTEGER)
+- <i>attr_id</i> - The MFT attribute id of files in NTFS file systems (INTEGER)
+- <i>attr_type</i> - The MFT attribute type of files in NTFS file systems (INTEGER - \ref TSK_FS_ATTR_TYPE_ENUM)
+
+\subsection fs_blocks_table fs_blocks
+Contains one row for each contiguous run of blocks in a file system file.
+- <i>file_id</i> - Id assigned to the file (INTEGER - foreign key, \ref files_table)
+- <i>fs_id</i> - Id assigned to the file system that contains the file (INTEGER - foreign key, \ref fs_info_table)
+- <i>seq</i> - Sequence number, counting up from one, of the run within the set of runs (INTEGER)
+- <i>blk_start</i> - Logical block offset of the beginning of the run (INTEGER)
+- <i>blk_len</i> - Number of blocks in the run (INTEGER)
+
+\subsection alloc_unalloc_map_table alloc_unalloc_map
+Contains one row for each contiguous run of unallocated blocks (sectors) in a volume / partition.
+These runs are used to create unallocated sectors files in preparation for carving.
+- <i>unalloc_img_id</i> - Id assigned to the unallocated sectors file that contains the run (INTEGER)
+- <i>vol_id</i> - Id of the volume / partition that contains the run (INTEGER - foreign key, \ref vol_info_table)
+- <i>unalloc_img_sect_start</i> - Sector offset of the beginning of the run in the unallocated sectors image file (INTEGER)
+- <i>orig_img_sect_start</i> - Sector offset of the beginning of the run in the image (INTEGER)
+- <i>sect_len</i> - Length of the run in sectors (INTEGER)
+
+\subsection unalloc_img_status_table unalloc_img_status
+Contains one row for each unallocated sectors file created in preparation for carving.
+- <i>unalloc_img_id</i> - Id assigned to the file (INTEGER) 
+- <i>status</i> - Analysis status (INTEGER - \ref TskImgDB::UNALLOC_IMG_STATUS) 
+
+\subsection carved_files_table carved_files
+Contains one row for each file carved from unallocated space.
+- <i>file_id</i> - Id assigned to the file (INTEGER - foreign key, \ref files_table)
+- <i>vol_id</i> - Volume/partition where the carved file resided (INTEGER - foreign key, \ref vol_info_table)
+
+\subsection carved_sectors_table carved_sectors
+Contains one row for each contiguous run of blocks (sectors) of unallocated space used to create carved files.
+- <i>file_id</i> - Id assigned to the carved file that contains the run (INTEGER - foreign key, \ref files_table)
+- <i>seq</i> - Sequence number, counting up from one, of the run within the set of runs in the carved file (INTEGER)
+- <i>sect_start</i> - Sector offset of the run in the image (INTEGER)
+- <i>sect_len</i> - Length of the run in sectors (INTEGER)
+
+\subsection unused_sectors_table unused_sectors
+Contains one row for each contiguous run of blocks (sectors) of unallocated space left over after carving.
+These runs are used to create unused sectors files to pass through the file analysis pipeline.
+- <i>file_id</i> - Id assigned to the unused sectors file that contains the run (INTEGER - foreign key, \ref files_table)
+- <i>vol_id</i> - Id of the volume / partition that contains the run (INTEGER - foreign key, \ref vol_info_table)
+- <i>sect_start</i> - Sector offset of the run in the image (INTEGER)
+- <i>sect_len</i> - Length of the run in sectors (INTEGER)
+
+\subsection derived_files_table derived_files
+Contains one row for each file derived from another file, e.g., files extracted from archive files.
+- <i>file_id</i> - Id assigned to the file (INTEGER - foreign key, \ref files_table)
+- <i>derivation_details</i> - Unused (TEXT)
+
+\section blackboard_tables Blackboard Tables
+
+\subsection blackboard_artifacts_table blackboard_artifacts
+Contains one row for each artifact found in the set of images analyzed to produce the database.
+- <i>artifact_id</i> - Id assigned to the artifact (INTEGER)
+- <i>obj_id</i> - Id assigned to the file associated with the artifact (INTEGER - foreign key, \ref files_table)
+- <i>artifact_type_id</i> - Id assigned to the type of artifact (INTEGER - foreign key, \ref blackboard_attribute_types_table)
+
+\subsection blackboard_attributes_table blackboard_attributes
+Stores the values of the name-value pairs that are the attributes associated with an artifact. 
+Only one of the value columns should be populated.
+- <i>artifact_id</i> - Id assigned to the artifact (INTEGER)
+- <i>source</i> - Source string, should be the name of the module that discovered the artifact (TEXT)
+- <i>context</i> - Additional context information (TEXT)
+- <i>attribute_type_id</i> - Id for the type of attribute (INTEGER - foreign key, \ref blackboard_attribute_types_table)
+- <i>value_type</i> - The type of the value, serves as discriminant for the union of the value columns ( INTEGER - \ref TskImgDB::VALUE_TYPE)
+- <i>value_byte</i> - A blob of binary data (BLOB)
+- <i>value_text</i> - A string of text (TEXT)
+- <i>value_int32</i> - An 32-bit integer (INTEGER - 0 by default default)
+- <i>value_int64</i> - A 64-bit integer (INTEGER - 0 by default default)
+- <i>value_double</i> - A double (NUMERIC - 0 by default default)
+- <i>obj_id</i> - Id assigned to the file associated with the attribute (INTEGER - foreign key, \ref files_table)
+
+\subsection blackboard_artifact_types_table blackboard_artifact_types
+Artifact types.
+- <i>artifact_type_id</i> - Id assigned to the type (INTEGER)
+- <i>type_name</i> - A unique string identifier for the type (TEXT)
+- <i>display_name</i> - A human-readable display name for the type (TEXT)
+
+\subsection blackboard_attribute_types_table blackboard_attribute_types
+Artifact attribute types.
+- <i>attribute_type_id</i> - Id assigned to the type (INTEGER)
+- <i>type_name</i> - A unique string identifier for the type (TEXT)
+- <i>display_name</i> - A human-readable display name for the type (TEXT)
+
 */
\ No newline at end of file
diff --git a/framework/docs/module_dev.dox b/framework/docs/module_dev.dox
index abb0472..a0e9aaa 100644
--- a/framework/docs/module_dev.dox
+++ b/framework/docs/module_dev.dox
@@ -89,7 +89,7 @@ Unlike the module execution function for a file analysis pipeline, this function
 
The <tt>report</tt> function does not have access to an individual file pointer as an argument, but may access files as described in the \ref  mod_stuff_files section below.  
 Like the <tt>run</tt> function, the report() function can stop subsequent modules in the pipeline from executing by returning a TskModule::STOP status. 
 This should not be done lightly. 
-Returning TskModule::STOP from the <tt>run</tt> function terminates analysis of the current file, but returning TskModule::STOP from <tt>report</tt> terminates analysis of the current disk image.
+Returning TskModule::STOP from the <tt>run</tt> function terminates analysis of the current file, but returning TskModule::STOP from <tt>report</tt> terminates analysis of the current disk image.
 
 
 \subsection mod_setup_cleanup Module Cleanup Function
@@ -173,7 +173,7 @@ Now that you know how to structure your module, we'll examine how your module ca
 \subsection mod_stuff_services Framework Services
 The framework provides a set of services to each module.  
 These services allow the module to access common resources and information, and can be accessed through the singleton TskServices class. 
-The following code snippet demonstrates how to use the TskServices class to get access to the Log service:
+The following code snippet demonstrates how to use the TskServices class to get access to the Log service:
 
 <pre>Log& tskLog = TskServices::Instance().getLog();</pre>
 
Other framework services can be accessed in a similar manner.  
@@ -194,7 +194,7 @@ Because of this, some services may be unavailable in a given application:
   <li>Scheduler provides a mechanism to schedule other types of analysis (especially useful for distributed implementations).  For example, if a module opens up a ZIP file, it might schedule analysis of each of the extracted files. </li>
 
   <li>ImageFile provides access to the disk image being analyzed.  This allows a module to access a specific file or raw data directly from the image.</li>
-</ul>
+</ul>
 
 
 \subsection mod_stuff_file Accessing File Content and Metadata
diff --git a/framework/docs/pipeline.dox b/framework/docs/pipeline.dox
index c72a974..efb2292 100755
--- a/framework/docs/pipeline.dox
+++ b/framework/docs/pipeline.dox
@@ -48,11 +48,11 @@ Note that each module to be included in a pipeline is represented by a <tt>MODUL
 <table>
 <tr><th>Attribute</th><th>Description</th><th>Required?</th></tr>
 
-<tr><td>order</td><td>The position of the module within the pipeline.</td><td>Yes</td></tr>
-<tr><td>type</td><td>Either "executable" or "plugin".</td><td>Yes</td></tr>
-<tr><td>location</td><td>The path of the program to be run by an executable module or the dynamic library to be loaded for a plug-in module. This can either be a fully qualified path or a relative path. If the path is relative, the framework will look for the file in the current working directory, TskSystemProperties::MODULE_DIR, and TskSystemProperties::PROG_DIR.</td><td>Yes</td></tr>
-<tr><td>arguments</td><td>The arguments to pass to the module.  See \ref pipe_config_macros to learn how arguments can incorporate information not available until runtime.</td><td>No</td></tr> 
-<tr><td>output</td><td>The path to a file to contain anything the module writes to <tt>stdout</tt>. This attribute applies only to executable modules.  See \ref pipe_config_macros to learn how output file paths can incorporate information not available until runtime.</td><td>No</td></tr>
+<tr><td>order</td><td>The position of the module within the pipeline.</td><td>Yes</td></tr>
+<tr><td>type</td><td>Either "executable" or "plugin".</td><td>Yes</td></tr>
+<tr><td>location</td><td>The path of the program to be run by an executable module or the dynamic library to be loaded for a plug-in module. This can either be a fully qualified path or a relative path. If the path is relative, the framework will look for the file in the current working directory, TskSystemProperties::MODULE_DIR, and TskSystemProperties::PROG_DIR.</td><td>Yes</td></tr>
+<tr><td>arguments</td><td>The arguments to pass to the module.  See \ref pipe_config_macros to learn how arguments can incorporate information not available until runtime.</td><td>No</td></tr> 
+<tr><td>output</td><td>The path to a file to contain anything the module writes to <tt>stdout</tt>. This attribute applies only to executable modules.  See \ref pipe_config_macros to learn how output file paths can incorporate information not available until runtime.</td><td>No</td></tr>
 
 </table>
 
@@ -63,15 +63,15 @@ When configuring a pipeline module pay particular attention to the following det
 - Redirected output on executable modules will be appended to the specified output file. 
 Attempting to write output to a shared file may result in file access errors when multiple pipelines (in a multithreaded or distributed environment) attempt to write data to the same file. 
 You can avoid this by using the TskSystemProperties::UNIQUE_ID macro (if the property is set) to construct the output file name for an executable module (see \ref pipe_config_macros for more on configuration file macros).
-
-- You must escape the following characters if you wish to include them in the command line:
+
+- You must escape the following characters if you wish to include them in the command line:
 
 
 <table>
<tr><th>Character</th><th>Escaped Character</th></tr>
<tr><td>&</td><td>&amp;</td></tr>
<tr><td>"</td><td>&quot;</td></tr>
<tr><td>></td><td>&gt;</td></tr>
<tr><td><</td><td>&lt;</td></tr>
<tr><td>'</td><td>&apos;</td></tr>
 </table>
 
 
-\subsection pipe_config_macros Configuration File Macros
+\subsection pipe_config_macros Configuration File Macros
 
 The <tt>arguments</tt> and <tt>output</tt> attributes of a <tt>MODULE</tt> element in a pipeline configuration file allow for the substitution of runtime values into the associated strings. 
 This is possible because there is a set of configuration file macros that the framework expands when it reads in a pipeline configuration file.   
@@ -88,5 +88,5 @@ Note that although this macro is not strictly necessary for plug-in modules beca
 
 The tsk_validatepipeline tool, which comes with the framework, can be used to verify that a pipeline configuration file is well-formed and all of the modules specified in the file can be found.
 
-
+
 */
diff --git a/framework/docs/sample_pipeline_config_file.dox b/framework/docs/sample_pipeline_config_file.dox
index 2bcc9d4..b429bec 100755
--- a/framework/docs/sample_pipeline_config_file.dox
+++ b/framework/docs/sample_pipeline_config_file.dox
@@ -1,34 +1,34 @@
-/*! \page sample_pipeline_config_file_page Sample Pipeline Config File
-
-\code{.xml}
-
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Contains only the modules that ship with TSK -->
-<PIPELINE_CONFIG>
-    <PIPELINE type="FileAnalysis">
-      <MODULE order="1" type="plugin" location="tskHashCalcModule"/>
-<!--<MODULE order="2" type="plugin" location="tskHashLookupModule" arguments="TODO: See README for how to create NSRL index file"/>-->
-
-      <MODULE order="3" type="plugin" location="tskFileTypeSigModule"/>
-      <MODULE order="4" type="plugin" location="tskEntropyModule"/>
-      <MODULE order="5" type="plugin" location="tskZipExtractionModule"/>
-      <MODULE order="6" type="plugin" location="tskLibExifModule"/>
-    </PIPELINE>
-
-    <PIPELINE type="PostProcessing">
-      <!--This pipeline configuration assumes that the RegRipper executable is named rip.exe and is present in the program directory-->
-      <!--<MODULE order="1" type="plugin" location="tskRegRipperModule" arguments="-e #PROG_DIR#/RegRipper/rip.exe; -o #MODULE_OUT_DIR#/RegRipper/"/>-->
-
-      <MODULE order="2" type="plugin" location="tskInterestingFilesModule" arguments="#MODULE_CONFIG_DIR#/InterestingFilesModule/interesting_files.xml"/>
-
-      <MODULE order="3" type="plugin" location="tskSaveInterestingFilesModule"/>
-
-      <MODULE order="4" type="plugin" location="tskSummaryReportModule"/>
-
-    </PIPELINE>
-</PIPELINE_CONFIG>
-
-
-\endcode
-
-*/
+/*! \page sample_pipeline_config_file_page Sample Pipeline Config File
+
+\code{.xml}
+
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Contains only the modules that ship with TSK -->
+<PIPELINE_CONFIG>
+    <PIPELINE type="FileAnalysis">
+      <MODULE order="1" type="plugin" location="tskHashCalcModule"/>
+<!--<MODULE order="2" type="plugin" location="tskHashLookupModule" arguments="TODO: See README for how to create NSRL index file"/>-->
+
+      <MODULE order="3" type="plugin" location="tskFileTypeSigModule"/>
+      <MODULE order="4" type="plugin" location="tskEntropyModule"/>
+      <MODULE order="5" type="plugin" location="tskZipExtractionModule"/>
+      <MODULE order="6" type="plugin" location="tskLibExifModule"/>
+    </PIPELINE>
+
+    <PIPELINE type="PostProcessing">
+      <!--This pipeline configuration assumes that the RegRipper executable is named rip.exe and is present in the program directory-->
+      <!--<MODULE order="1" type="plugin" location="tskRegRipperModule" arguments="-e #PROG_DIR#/RegRipper/rip.exe; -o #MODULE_OUT_DIR#/RegRipper/"/>-->
+
+      <MODULE order="2" type="plugin" location="tskInterestingFilesModule" arguments="#MODULE_CONFIG_DIR#/InterestingFilesModule/interesting_files.xml"/>
+
+      <MODULE order="3" type="plugin" location="tskSaveInterestingFilesModule"/>
+
+      <MODULE order="4" type="plugin" location="tskSummaryReportModule"/>
+
+    </PIPELINE>
+</PIPELINE_CONFIG>
+
+
+\endcode
+
+*/
diff --git a/framework/modules/c_EntropyModule/EntropyModule.cpp b/framework/modules/c_EntropyModule/EntropyModule.cpp
index 4e8142b..c836060 100644
--- a/framework/modules/c_EntropyModule/EntropyModule.cpp
+++ b/framework/modules/c_EntropyModule/EntropyModule.cpp
@@ -1,445 +1,445 @@
-/*
-*
-*  The Sleuth Kit
-*
-*  Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
-*
-*  This is free and unencumbered software released into the public domain.
-*  
-*  Anyone is free to copy, modify, publish, use, compile, sell, or
-*  distribute this software, either in source code form or as a compiled
-*  binary, for any purpose, commercial or non-commercial, and by any
-*  means.
-*  
-*  In jurisdictions that recognize copyright laws, the author or authors
-*  of this software dedicate any and all copyright interest in the
-*  software to the public domain. We make this dedication for the benefit
-*  of the public at large and to the detriment of our heirs and
-*  successors. We intend this dedication to be an overt act of
-*  relinquishment in perpetuity of all present and future rights to this
-*  software under copyright law.
-*  
-*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-*  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
-*  OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-*  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-*  OTHER DEALINGS IN THE SOFTWARE. 
-*/
-
-/**
-* \file EntropyModule.cpp
-* Contains the implementation of a file analysis module that calculates the
-* entropy of a file's contents.
-*
-* This sample module shows a basic Sleuth Kit Framework module.  It is
-* released as public domain and you are free to remove this header,  use
-* it as a starting point for your module, and choose whatever license that
-* you want.  Note that the framework itself is NOT public domain.
-*/
-
-// TSK Framework includes
-#include "tsk/framework/utilities/TskModuleDev.h"
-
-// Poco includes
-// Uncomment this include if using the Poco catch blocks.
-//#include "Poco/Exception.h"
-
-// C/C++ library includes
-#include <string>
-#include <cstring>
-#include <sstream>
-#include <math.h>
-#include <assert.h>
-
-// More complex modules will likely put functions and variables other than 
-// the module API functions in separate source files and/or may define various
-// C++ classes to perform the work of the module. However, it is possible to simply 
-// enclose such functions and variables in an anonymous namespace to give them file scope 
-// instead of global scope, as is done in this module. This replaces the older practice 
-// of declaring file scope functions and variables using the "static" keyword. An 
-// anonymous namespace is a more flexible construct, since it is possible to define 
-// types within it.
-//
-// NOTE: Linux/OS-X module developers should make sure module functions
-// other than the module API functions are either uniquely named or bound at module link time. 
-// Placing these functions in an anonymous namespace to give them static-linkage is one way to 
-// accomplish this.
-//
-// CAVEAT: Static data can be incompatible with multithreading, since each
-// thread will get its own copy of the data.
-namespace
-{
-    const char *MODULE_NAME = "tskEntropyModule";
-    const char *MODULE_DESCRIPTION = "Performs an entropy calculation for the contents of a given file";
-    const char *MODULE_VERSION = "1.0.0";
-
-    /**
-    * Calculates the entropy of a file.
-    *
-    * @param pFile A TskFile object corrersponding to a file.
-    * @return The entropy of the file.
-    */
-    double calculateEntropy(TskFile *pFile)
-    {
-        const uint32_t FILE_BUFFER_SIZE = 8193;
-
-        uint8_t byte = 0;
-        long byteCounts[256];
-        memset(byteCounts, 0, sizeof(long) * 256);
-        long totalBytes = 0;
-        char buffer[FILE_BUFFER_SIZE];
-        ssize_t bytesRead = 0;
-        do
-        {
-            memset(buffer, 0, FILE_BUFFER_SIZE);
-            bytesRead = pFile->read(buffer, FILE_BUFFER_SIZE);
-            if (bytesRead > 0)
-            {
-                for (int i = 0; i < bytesRead; ++i)
-                {
-                    byte = static_cast<uint8_t>(buffer[i]);
-                    byteCounts[byte]++;
-                }
-
-                totalBytes += bytesRead;
-            }
-        } 
-        while (bytesRead > 0);
-
-        double entropy = 0.0;
-        for (int i = 0; i<256; ++i)
-        {
-            double p = static_cast<double>(byteCounts[i]) / static_cast<double>(totalBytes);
-            if (p > 0.0)
-            {
-                entropy -= p * (log(p) / log(2.0));
-            }
-        }
-
-        return entropy;
-    }
-}
-
-extern "C" 
-{
-    /**
-    * Module identification function. 
-    *
-    * CAVEAT: This function is intended to be called by TSK Framework only. 
-    * Linux/OS-X modules should *not* call this function within the module 
-    * unless appropriate compiler/linker options are used to bind all 
-    * library-internal symbols at link time. 
-    *
-    * @return The name of the module.
-    */
-    TSK_MODULE_EXPORT const char *name()
-    {
-        return MODULE_NAME;
-    }
-
-    /**
-    * Module identification function. 
-    *
-    * CAVEAT: This function is intended to be called by TSK Framework only. 
-    * Linux/OS-X modules should *not* call this function within the module 
-    * unless appropriate compiler/linker options are used to bind all 
-    * library-internal symbols at link time. 
-    *
-    * @return A description of the module.
-    */
-    TSK_MODULE_EXPORT const char *description()
-    {
-        return MODULE_DESCRIPTION;
-    }
-
-    /**
-    * Module identification function. 
-    *
-    * CAVEAT: This function is intended to be called by TSK Framework only. 
-    * Linux/OS-X modules should *not* call this function within the module 
-    * unless appropriate compiler/linker options are used to bind all 
-    * library-internal symbols at link time. 
-    *
-    * @return The version of the module.
-    */
-    TSK_MODULE_EXPORT const char *version()
-    {
-        return MODULE_VERSION;
-    }
-
-    /**
-    * Module initialization function. Receives a string of initialization arguments, 
-    * typically read by the caller from a pipeline configuration file. 
-    * Returns TskModule::OK or TskModule::FAIL. Returning TskModule::FAIL indicates 
-    * the module is not in an operational state.  
-    *
-    * CAVEAT: This function is intended to be called by TSK Framework only. 
-    * Linux/OS-X modules should *not* call this function within the module 
-    * unless appropriate compiler/linker options are used to bind all 
-    * library-internal symbols at link time. 
-    *
-    * @param args a string of initialization arguments.
-    * @return TskModule::OK if initialization succeeded, otherwise TskModule::FAIL.
-    */
-    TskModule::Status TSK_MODULE_EXPORT initialize(const char* arguments)
-    {    
-        // The TSK Framework convention is to prefix error messages with the
-        // name of the module/class and the function that emitted the message. 
-        std::ostringstream msgPrefix;
-        msgPrefix << MODULE_NAME << "::initialize : ";
-
-        // Well-behaved modules should catch and log all possible exceptions
-        // and return an appropriate TskModule::Status to the TSK Framework. 
-        try
-        {
-            // If this module required initialization, the initialization code would
-            // go here.
-
-            return TskModule::OK;
-        }
-        catch (TskException &ex)
-        {
-            std::ostringstream msg;
-            msg << msgPrefix.str() << "TskException: " << ex.message();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        // Uncomment this catch block and the #include of "Poco/Exception.h" if using Poco.
-        //catch (Poco::Exception &ex)
-        //{
-        //    std::ostringstream msg;
-        //    msg << msgPrefix.str() << "Poco::Exception: " << ex.displayText();
-        //    LOGERROR(msg.str());
-        //    return TskModule::FAIL;
-        //}
-        catch (std::exception &ex)
-        {
-            std::ostringstream msg;
-            msg << msgPrefix.str() << "std::exception: " << ex.what();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        // Uncomment this catch block and add necessary .NET references if using C++/CLI.
-        //catch (System::Exception ^ex)
-        //{
-        //    std::ostringstream msg;
-        //    msg << msgPrefix.str() << "System::Exception: " << Maytag::systemStringToStdString(ex->Message);
-        //    LOGERROR(msg.str());
-        //    return TskModule::FAIL;
-        //}        
-        catch (...)
-        {
-            LOGERROR(msgPrefix.str() + "unrecognized exception");
-            return TskModule::FAIL;
-        }
-    }
-
-    /**
-    * Module execution function for file analysis modules. 
-    * Receives a pointer to a file the module is to process. The file is 
-    * represented by a TskFile interface from which both file content and file 
-    * metadata can be retrieved. Returns TskModule::OK, TskModule::FAIL, or 
-    * TskModule::STOP. Returning TskModule::FAIL indicates the module 
-    * experienced an error processing the file. 
-    *
-    * CAVEAT: This function is intended to be called by TSK Framework only. 
-    * Linux/OS-X modules should *not* call this function within the module 
-    * unless appropriate compiler/linker options are used to bind all 
-    * library-internal symbols at link time. 
-    *
-    * @param pFile A pointer to a file to be processed.
-    * @returns TskModule::OK on success, TskModule::FAIL on error, or 
-    * TskModule::STOP. Returning TskModule::STOP is a request to terminate 
-    * processing of the file.     
-    */
-    TskModule::Status TSK_MODULE_EXPORT run(TskFile *pFile)
-    {
-        // The TSK Framework convention is to prefix error messages with the
-        // name of the module/class and the function that emitted the message. 
-        std::ostringstream msgPrefix;
-        msgPrefix << MODULE_NAME << "::run : ";
-
-        // Well-behaved modules should catch and log all possible exceptions
-        // and return an appropriate TskModule::Status to the TSK Framework. 
-        try
-        {
-            assert(pFile != NULL);
-            if (pFile == NULL) 
-            {
-                throw TskException("passed NULL TskFile pointer");
-            }
-
-            // Calculate an entropy value for the file.
-            double entropy = calculateEntropy(pFile);
-
-            // Post the value to the blackboard.
-            pFile->addGenInfoAttribute(TskBlackboardAttribute(TSK_ENTROPY, MODULE_NAME, "", entropy));
-
-            return TskModule::OK;
-        }
-        catch (TskException &ex)
-        {
-            std::ostringstream msg;
-            msg << msgPrefix.str() << "TskException: " << ex.message();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        // Uncomment this catch block and the #include of "Poco/Exception.h" if using Poco.
-        //catch (Poco::Exception &ex)
-        //{
-        //    std::ostringstream msg;
-        //    msg << msgPrefix.str() << "Poco::Exception: " << ex.displayText();
-        //    LOGERROR(msg.str());
-        //    return TskModule::FAIL;
-        //}
-        catch (std::exception &ex)
-        {
-            std::ostringstream msg;
-            msg << msgPrefix.str() << "std::exception: " << ex.what();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        // Uncomment this catch block and add necessary .NET references if using C++/CLI.
-        //catch (System::Exception ^ex)
-        //{
-        //    std::ostringstream msg;
-        //    msg << msgPrefix.str() << "System::Exception: " << Maytag::systemStringToStdString(ex->Message);
-        //    LOGERROR(msg.str());
-        //    return TskModule::FAIL;
-        //}        
-        catch (...)
-        {
-            LOGERROR(msgPrefix.str() + "unrecognized exception");
-            return TskModule::FAIL;
-        }
-    }
-
-    //  /**
-    //   * Module execution function for post-processing modules. 
-    //   *
-    //   * CAVEAT: This function is intended to be called by TSK Framework only. 
-    //   * Linux/OS-X modules should *not* call this function within the module 
-    //   * unless appropriate compiler/linker options are used to bind all 
-    //   * library-internal symbols at link time. 
-    //   *
-    //   * @returns TskModule::OK on success, TskModule::FAIL on error
-    //   */
-    //  TskModule::Status TSK_MODULE_EXPORT report()
-    //  {
-    //      // The TSK Framework convention is to prefix error messages with the
-    //      // name of the module/class and the function that emitted the message. 
-    //      std::ostringstream msgPrefix;
-    //      msgPrefix << MODULE_NAME << "::report : ";
-    //
-    //      // Well-behaved modules should catch and log all possible exceptions
-    //      // and return an appropriate TskModule::Status to the TSK Framework. 
-    //      try
-    //      {
-    //          // If this module could be used in a post-processing pipeline, the 
-    //	      // code would go here.
-    //
-    //		  return TskModule::OK;
-    //      }
-    //      catch (TskException &ex)
-    //      {
-    //          std::ostringstream msg;
-    //          msg << msgPrefix.str() << "TskException: " << ex.message();
-    //          LOGERROR(msg.str());
-    //          return TskModule::FAIL;
-    //      }
-    //      // Uncomment this catch block and the #include of "Poco/Exception.h" if using Poco.
-    //      //catch (Poco::Exception &ex)
-    //      //{
-    //      //    std::ostringstream msg;
-    //      //    msg << msgPrefix.str() << "Poco::Exception: " << ex.displayText();
-    //      //    LOGERROR(msg.str());
-    //      //    return TskModule::FAIL;
-    //      //}
-    //      catch (std::exception &ex)
-    //      {
-    //          std::ostringstream msg;
-    //          msg << msgPrefix.str() << "std::exception: " << ex.what();
-    //          LOGERROR(msg.str());
-    //          return TskModule::FAIL;
-    //      }
-    //      // Uncomment this catch block and add necessary .NET references if using C++/CLI.
-    //      //catch (System::Exception ^ex)
-    //      //{
-    //      //    std::ostringstream msg;
-    //      //    msg << msgPrefix.str() << "System::Exception: " << Maytag::systemStringToStdString(ex->Message);
-    //      //    LOGERROR(msg.str());
-    //      //    return TskModule::FAIL;
-    //      //}        
-    //      catch (...)
-    //      {
-    //          LOGERROR(msgPrefix.str() + "unrecognized exception");
-    //          return TskModule::FAIL;
-    //      }
-    //  }
-
-    /**
-    * Module cleanup function. This is where the module should free any resources 
-    * allocated during initialization or execution.
-    *
-    * CAVEAT: This function is intended to be called by TSK Framework only. 
-    * Linux/OS-X modules should *not* call this function within the module 
-    * unless appropriate compiler/linker options are used to bind all 
-    * library-internal symbols at link time. 
-    *
-    * @returns TskModule::OK on success and TskModule::FAIL on error.
-    */
-    TskModule::Status TSK_MODULE_EXPORT finalize()
-    {
-        // The TSK Framework convention is to prefix error messages with the
-        // name of the module/class and the function that emitted the message. 
-        std::ostringstream msgPrefix;
-        msgPrefix << MODULE_NAME << "::finalize : ";
-
-        // Well-behaved modules should catch and log all possible exceptions
-        // and return an appropriate TskModule::Status to the TSK Framework. 
-        try
-        {
-            // If this module required finalization, the finalization code would
-            // go here.
-
-            return TskModule::OK;
-        }
-        catch (TskException &ex)
-        {
-            std::ostringstream msg;
-            msg << msgPrefix.str() << "TskException: " << ex.message();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        // Uncomment this catch block and the #include of "Poco/Exception.h" if using Poco.
-        //catch (Poco::Exception &ex)
-        //{
-        //    std::ostringstream msg;
-        //    msg << msgPrefix.str() << "Poco::Exception: " << ex.displayText();
-        //    LOGERROR(msg.str());
-        //    return TskModule::FAIL;
-        //}
-        catch (std::exception &ex)
-        {
-            std::ostringstream msg;
-            msg << msgPrefix.str() << "std::exception: " << ex.what();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        // Uncomment this catch block and add necessary .NET references if using C++/CLI.
-        //catch (System::Exception ^ex)
-        //{
-        //    std::ostringstream msg;
-        //    msg << msgPrefix.str() << "System::Exception: " << Maytag::systemStringToStdString(ex->Message);
-        //    LOGERROR(msg.str());
-        //    return TskModule::FAIL;
-        //}        
-        catch (...)
-        {
-            LOGERROR(msgPrefix.str() + "unrecognized exception");
-            return TskModule::FAIL;
-        }
-    }
-}
+/*
+*
+*  The Sleuth Kit
+*
+*  Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+*
+*  This is free and unencumbered software released into the public domain.
+*  
+*  Anyone is free to copy, modify, publish, use, compile, sell, or
+*  distribute this software, either in source code form or as a compiled
+*  binary, for any purpose, commercial or non-commercial, and by any
+*  means.
+*  
+*  In jurisdictions that recognize copyright laws, the author or authors
+*  of this software dedicate any and all copyright interest in the
+*  software to the public domain. We make this dedication for the benefit
+*  of the public at large and to the detriment of our heirs and
+*  successors. We intend this dedication to be an overt act of
+*  relinquishment in perpetuity of all present and future rights to this
+*  software under copyright law.
+*  
+*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+*  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+*  OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+*  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+*  OTHER DEALINGS IN THE SOFTWARE. 
+*/
+
+/**
+* \file EntropyModule.cpp
+* Contains the implementation of a file analysis module that calculates the
+* entropy of a file's contents.
+*
+* This sample module shows a basic Sleuth Kit Framework module.  It is
+* released as public domain and you are free to remove this header,  use
+* it as a starting point for your module, and choose whatever license that
+* you want.  Note that the framework itself is NOT public domain.
+*/
+
+// TSK Framework includes
+#include "tsk/framework/utilities/TskModuleDev.h"
+
+// Poco includes
+// Uncomment this include if using the Poco catch blocks.
+//#include "Poco/Exception.h"
+
+// C/C++ library includes
+#include <string>
+#include <cstring>
+#include <sstream>
+#include <math.h>
+#include <assert.h>
+
+// More complex modules will likely put functions and variables other than 
+// the module API functions in separate source files and/or may define various
+// C++ classes to perform the work of the module. However, it is possible to simply 
+// enclose such functions and variables in an anonymous namespace to give them file scope 
+// instead of global scope, as is done in this module. This replaces the older practice 
+// of declaring file scope functions and variables using the "static" keyword. An 
+// anonymous namespace is a more flexible construct, since it is possible to define 
+// types within it.
+//
+// NOTE: Linux/OS-X module developers should make sure module functions
+// other than the module API functions are either uniquely named or bound at module link time. 
+// Placing these functions in an anonymous namespace to give them static-linkage is one way to 
+// accomplish this.
+//
+// CAVEAT: Static data can be incompatible with multithreading, since each
+// thread will get its own copy of the data.
+namespace
+{
+    const char *MODULE_NAME = "tskEntropyModule";
+    const char *MODULE_DESCRIPTION = "Performs an entropy calculation for the contents of a given file";
+    const char *MODULE_VERSION = "1.0.0";
+
+    /**
+    * Calculates the entropy of a file.
+    *
+    * @param pFile A TskFile object corrersponding to a file.
+    * @return The entropy of the file.
+    */
+    double calculateEntropy(TskFile *pFile)
+    {
+        const uint32_t FILE_BUFFER_SIZE = 8193;
+
+        uint8_t byte = 0;
+        long byteCounts[256];
+        memset(byteCounts, 0, sizeof(long) * 256);
+        long totalBytes = 0;
+        char buffer[FILE_BUFFER_SIZE];
+        ssize_t bytesRead = 0;
+        do
+        {
+            memset(buffer, 0, FILE_BUFFER_SIZE);
+            bytesRead = pFile->read(buffer, FILE_BUFFER_SIZE);
+            if (bytesRead > 0)
+            {
+                for (int i = 0; i < bytesRead; ++i)
+                {
+                    byte = static_cast<uint8_t>(buffer[i]);
+                    byteCounts[byte]++;
+                }
+
+                totalBytes += bytesRead;
+            }
+        } 
+        while (bytesRead > 0);
+
+        double entropy = 0.0;
+        for (int i = 0; i<256; ++i)
+        {
+            double p = static_cast<double>(byteCounts[i]) / static_cast<double>(totalBytes);
+            if (p > 0.0)
+            {
+                entropy -= p * (log(p) / log(2.0));
+            }
+        }
+
+        return entropy;
+    }
+}
+
+extern "C" 
+{
+    /**
+    * Module identification function. 
+    *
+    * CAVEAT: This function is intended to be called by TSK Framework only. 
+    * Linux/OS-X modules should *not* call this function within the module 
+    * unless appropriate compiler/linker options are used to bind all 
+    * library-internal symbols at link time. 
+    *
+    * @return The name of the module.
+    */
+    TSK_MODULE_EXPORT const char *name()
+    {
+        return MODULE_NAME;
+    }
+
+    /**
+    * Module identification function. 
+    *
+    * CAVEAT: This function is intended to be called by TSK Framework only. 
+    * Linux/OS-X modules should *not* call this function within the module 
+    * unless appropriate compiler/linker options are used to bind all 
+    * library-internal symbols at link time. 
+    *
+    * @return A description of the module.
+    */
+    TSK_MODULE_EXPORT const char *description()
+    {
+        return MODULE_DESCRIPTION;
+    }
+
+    /**
+    * Module identification function. 
+    *
+    * CAVEAT: This function is intended to be called by TSK Framework only. 
+    * Linux/OS-X modules should *not* call this function within the module 
+    * unless appropriate compiler/linker options are used to bind all 
+    * library-internal symbols at link time. 
+    *
+    * @return The version of the module.
+    */
+    TSK_MODULE_EXPORT const char *version()
+    {
+        return MODULE_VERSION;
+    }
+
+    /**
+    * Module initialization function. Receives a string of initialization arguments, 
+    * typically read by the caller from a pipeline configuration file. 
+    * Returns TskModule::OK or TskModule::FAIL. Returning TskModule::FAIL indicates 
+    * the module is not in an operational state.  
+    *
+    * CAVEAT: This function is intended to be called by TSK Framework only. 
+    * Linux/OS-X modules should *not* call this function within the module 
+    * unless appropriate compiler/linker options are used to bind all 
+    * library-internal symbols at link time. 
+    *
+    * @param args a string of initialization arguments.
+    * @return TskModule::OK if initialization succeeded, otherwise TskModule::FAIL.
+    */
+    TskModule::Status TSK_MODULE_EXPORT initialize(const char* arguments)
+    {    
+        // The TSK Framework convention is to prefix error messages with the
+        // name of the module/class and the function that emitted the message. 
+        std::ostringstream msgPrefix;
+        msgPrefix << MODULE_NAME << "::initialize : ";
+
+        // Well-behaved modules should catch and log all possible exceptions
+        // and return an appropriate TskModule::Status to the TSK Framework. 
+        try
+        {
+            // If this module required initialization, the initialization code would
+            // go here.
+
+            return TskModule::OK;
+        }
+        catch (TskException &ex)
+        {
+            std::ostringstream msg;
+            msg << msgPrefix.str() << "TskException: " << ex.message();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        // Uncomment this catch block and the #include of "Poco/Exception.h" if using Poco.
+        //catch (Poco::Exception &ex)
+        //{
+        //    std::ostringstream msg;
+        //    msg << msgPrefix.str() << "Poco::Exception: " << ex.displayText();
+        //    LOGERROR(msg.str());
+        //    return TskModule::FAIL;
+        //}
+        catch (std::exception &ex)
+        {
+            std::ostringstream msg;
+            msg << msgPrefix.str() << "std::exception: " << ex.what();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        // Uncomment this catch block and add necessary .NET references if using C++/CLI.
+        //catch (System::Exception ^ex)
+        //{
+        //    std::ostringstream msg;
+        //    msg << msgPrefix.str() << "System::Exception: " << Maytag::systemStringToStdString(ex->Message);
+        //    LOGERROR(msg.str());
+        //    return TskModule::FAIL;
+        //}        
+        catch (...)
+        {
+            LOGERROR(msgPrefix.str() + "unrecognized exception");
+            return TskModule::FAIL;
+        }
+    }
+
+    /**
+    * Module execution function for file analysis modules. 
+    * Receives a pointer to a file the module is to process. The file is 
+    * represented by a TskFile interface from which both file content and file 
+    * metadata can be retrieved. Returns TskModule::OK, TskModule::FAIL, or 
+    * TskModule::STOP. Returning TskModule::FAIL indicates the module 
+    * experienced an error processing the file. 
+    *
+    * CAVEAT: This function is intended to be called by TSK Framework only. 
+    * Linux/OS-X modules should *not* call this function within the module 
+    * unless appropriate compiler/linker options are used to bind all 
+    * library-internal symbols at link time. 
+    *
+    * @param pFile A pointer to a file to be processed.
+    * @returns TskModule::OK on success, TskModule::FAIL on error, or 
+    * TskModule::STOP. Returning TskModule::STOP is a request to terminate 
+    * processing of the file.     
+    */
+    TskModule::Status TSK_MODULE_EXPORT run(TskFile *pFile)
+    {
+        // The TSK Framework convention is to prefix error messages with the
+        // name of the module/class and the function that emitted the message. 
+        std::ostringstream msgPrefix;
+        msgPrefix << MODULE_NAME << "::run : ";
+
+        // Well-behaved modules should catch and log all possible exceptions
+        // and return an appropriate TskModule::Status to the TSK Framework. 
+        try
+        {
+            assert(pFile != NULL);
+            if (pFile == NULL) 
+            {
+                throw TskException("passed NULL TskFile pointer");
+            }
+
+            // Calculate an entropy value for the file.
+            double entropy = calculateEntropy(pFile);
+
+            // Post the value to the blackboard.
+            pFile->addGenInfoAttribute(TskBlackboardAttribute(TSK_ENTROPY, MODULE_NAME, "", entropy));
+
+            return TskModule::OK;
+        }
+        catch (TskException &ex)
+        {
+            std::ostringstream msg;
+            msg << msgPrefix.str() << "TskException: " << ex.message();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        // Uncomment this catch block and the #include of "Poco/Exception.h" if using Poco.
+        //catch (Poco::Exception &ex)
+        //{
+        //    std::ostringstream msg;
+        //    msg << msgPrefix.str() << "Poco::Exception: " << ex.displayText();
+        //    LOGERROR(msg.str());
+        //    return TskModule::FAIL;
+        //}
+        catch (std::exception &ex)
+        {
+            std::ostringstream msg;
+            msg << msgPrefix.str() << "std::exception: " << ex.what();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        // Uncomment this catch block and add necessary .NET references if using C++/CLI.
+        //catch (System::Exception ^ex)
+        //{
+        //    std::ostringstream msg;
+        //    msg << msgPrefix.str() << "System::Exception: " << Maytag::systemStringToStdString(ex->Message);
+        //    LOGERROR(msg.str());
+        //    return TskModule::FAIL;
+        //}        
+        catch (...)
+        {
+            LOGERROR(msgPrefix.str() + "unrecognized exception");
+            return TskModule::FAIL;
+        }
+    }
+
+    //  /**
+    //   * Module execution function for post-processing modules. 
+    //   *
+    //   * CAVEAT: This function is intended to be called by TSK Framework only. 
+    //   * Linux/OS-X modules should *not* call this function within the module 
+    //   * unless appropriate compiler/linker options are used to bind all 
+    //   * library-internal symbols at link time. 
+    //   *
+    //   * @returns TskModule::OK on success, TskModule::FAIL on error
+    //   */
+    //  TskModule::Status TSK_MODULE_EXPORT report()
+    //  {
+    //      // The TSK Framework convention is to prefix error messages with the
+    //      // name of the module/class and the function that emitted the message. 
+    //      std::ostringstream msgPrefix;
+    //      msgPrefix << MODULE_NAME << "::report : ";
+    //
+    //      // Well-behaved modules should catch and log all possible exceptions
+    //      // and return an appropriate TskModule::Status to the TSK Framework. 
+    //      try
+    //      {
+    //          // If this module could be used in a post-processing pipeline, the 
+    //	      // code would go here.
+    //
+    //		  return TskModule::OK;
+    //      }
+    //      catch (TskException &ex)
+    //      {
+    //          std::ostringstream msg;
+    //          msg << msgPrefix.str() << "TskException: " << ex.message();
+    //          LOGERROR(msg.str());
+    //          return TskModule::FAIL;
+    //      }
+    //      // Uncomment this catch block and the #include of "Poco/Exception.h" if using Poco.
+    //      //catch (Poco::Exception &ex)
+    //      //{
+    //      //    std::ostringstream msg;
+    //      //    msg << msgPrefix.str() << "Poco::Exception: " << ex.displayText();
+    //      //    LOGERROR(msg.str());
+    //      //    return TskModule::FAIL;
+    //      //}
+    //      catch (std::exception &ex)
+    //      {
+    //          std::ostringstream msg;
+    //          msg << msgPrefix.str() << "std::exception: " << ex.what();
+    //          LOGERROR(msg.str());
+    //          return TskModule::FAIL;
+    //      }
+    //      // Uncomment this catch block and add necessary .NET references if using C++/CLI.
+    //      //catch (System::Exception ^ex)
+    //      //{
+    //      //    std::ostringstream msg;
+    //      //    msg << msgPrefix.str() << "System::Exception: " << Maytag::systemStringToStdString(ex->Message);
+    //      //    LOGERROR(msg.str());
+    //      //    return TskModule::FAIL;
+    //      //}        
+    //      catch (...)
+    //      {
+    //          LOGERROR(msgPrefix.str() + "unrecognized exception");
+    //          return TskModule::FAIL;
+    //      }
+    //  }
+
+    /**
+    * Module cleanup function. This is where the module should free any resources 
+    * allocated during initialization or execution.
+    *
+    * CAVEAT: This function is intended to be called by TSK Framework only. 
+    * Linux/OS-X modules should *not* call this function within the module 
+    * unless appropriate compiler/linker options are used to bind all 
+    * library-internal symbols at link time. 
+    *
+    * @returns TskModule::OK on success and TskModule::FAIL on error.
+    */
+    TskModule::Status TSK_MODULE_EXPORT finalize()
+    {
+        // The TSK Framework convention is to prefix error messages with the
+        // name of the module/class and the function that emitted the message. 
+        std::ostringstream msgPrefix;
+        msgPrefix << MODULE_NAME << "::finalize : ";
+
+        // Well-behaved modules should catch and log all possible exceptions
+        // and return an appropriate TskModule::Status to the TSK Framework. 
+        try
+        {
+            // If this module required finalization, the finalization code would
+            // go here.
+
+            return TskModule::OK;
+        }
+        catch (TskException &ex)
+        {
+            std::ostringstream msg;
+            msg << msgPrefix.str() << "TskException: " << ex.message();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        // Uncomment this catch block and the #include of "Poco/Exception.h" if using Poco.
+        //catch (Poco::Exception &ex)
+        //{
+        //    std::ostringstream msg;
+        //    msg << msgPrefix.str() << "Poco::Exception: " << ex.displayText();
+        //    LOGERROR(msg.str());
+        //    return TskModule::FAIL;
+        //}
+        catch (std::exception &ex)
+        {
+            std::ostringstream msg;
+            msg << msgPrefix.str() << "std::exception: " << ex.what();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        // Uncomment this catch block and add necessary .NET references if using C++/CLI.
+        //catch (System::Exception ^ex)
+        //{
+        //    std::ostringstream msg;
+        //    msg << msgPrefix.str() << "System::Exception: " << Maytag::systemStringToStdString(ex->Message);
+        //    LOGERROR(msg.str());
+        //    return TskModule::FAIL;
+        //}        
+        catch (...)
+        {
+            LOGERROR(msgPrefix.str() + "unrecognized exception");
+            return TskModule::FAIL;
+        }
+    }
+}
diff --git a/framework/modules/c_EntropyModule/NEWS.txt b/framework/modules/c_EntropyModule/NEWS.txt
index 5735901..f1c392a 100644
--- a/framework/modules/c_EntropyModule/NEWS.txt
+++ b/framework/modules/c_EntropyModule/NEWS.txt
@@ -1,9 +1,9 @@
-Numbers refer to github.net issue #s:
-    https://github.com/sleuthkit/c_EntropyModule/issues
-    
----------------- VERSION 1.0.0 --------------
-New Features:
-- Initial public release.
-
-Bug Fixes:
-- N/A. 
+Numbers refer to github.net issue #s:
+    https://github.com/sleuthkit/c_EntropyModule/issues
+    
+---------------- VERSION 1.0.0 --------------
+New Features:
+- Initial public release.
+
+Bug Fixes:
+- N/A. 
diff --git a/framework/modules/c_EntropyModule/README.txt b/framework/modules/c_EntropyModule/README.txt
index da7708e..01f4b83 100644
--- a/framework/modules/c_EntropyModule/README.txt
+++ b/framework/modules/c_EntropyModule/README.txt
@@ -1,33 +1,33 @@
-Entropy Calculation Module
-Sleuth Kit Framework C++ Module
-May 2012
-
-
-This module is for the C++ Sleuth Kit Framework.
-
-
-DESCRIPTION
-
-This module is a file analysis module that performs an 
-entropy calculation for the contents of a given file. Entropy
-shows how random the file is and can be used to detect 
-encrypted or compressed files.
-
-DEPLOYMENT REQUIREMENTS
-
-This module does not have any specific deployment requirements.
-
-USAGE
-
-Add this module to a file analysis pipeline.  See the TSK 
-Framework documents for information on adding the module 
-to the pipeline:
-
-    http://www.sleuthkit.org/sleuthkit/docs/framework-docs/
-
-This module takes no configuration arguments.  
-
-RESULTS
-
-The result of the calculation is written to an attribute
-in the blackboard.
+Entropy Calculation Module
+Sleuth Kit Framework C++ Module
+May 2012
+
+
+This module is for the C++ Sleuth Kit Framework.
+
+
+DESCRIPTION
+
+This module is a file analysis module that performs an 
+entropy calculation for the contents of a given file. Entropy
+shows how random the file is and can be used to detect 
+encrypted or compressed files.
+
+DEPLOYMENT REQUIREMENTS
+
+This module does not have any specific deployment requirements.
+
+USAGE
+
+Add this module to a file analysis pipeline.  See the TSK 
+Framework documents for information on adding the module 
+to the pipeline:
+
+    http://www.sleuthkit.org/sleuthkit/docs/framework-docs/
+
+This module takes no configuration arguments.  
+
+RESULTS
+
+The result of the calculation is written to an attribute
+in the blackboard.
diff --git a/framework/modules/c_EntropyModule/win32/EntropyModule.sln b/framework/modules/c_EntropyModule/win32/EntropyModule.sln
index 4197985..ff6340b 100644
--- a/framework/modules/c_EntropyModule/win32/EntropyModule.sln
+++ b/framework/modules/c_EntropyModule/win32/EntropyModule.sln
@@ -1,20 +1,20 @@
-
-Microsoft Visual Studio Solution File, Format Version 10.00
-# Visual C++ Express 2008
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EntropyModule", "EntropyModule.vcproj", "{00E3B0EE-B612-433A-A43E-1CE0B3DE1015}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Win32 = Debug|Win32
-		Release|Win32 = Release|Win32
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{00E3B0EE-B612-433A-A43E-1CE0B3DE1015}.Debug|Win32.ActiveCfg = Debug|Win32
-		{00E3B0EE-B612-433A-A43E-1CE0B3DE1015}.Debug|Win32.Build.0 = Debug|Win32
-		{00E3B0EE-B612-433A-A43E-1CE0B3DE1015}.Release|Win32.ActiveCfg = Release|Win32
-		{00E3B0EE-B612-433A-A43E-1CE0B3DE1015}.Release|Win32.Build.0 = Release|Win32
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual C++ Express 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EntropyModule", "EntropyModule.vcproj", "{00E3B0EE-B612-433A-A43E-1CE0B3DE1015}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{00E3B0EE-B612-433A-A43E-1CE0B3DE1015}.Debug|Win32.ActiveCfg = Debug|Win32
+		{00E3B0EE-B612-433A-A43E-1CE0B3DE1015}.Debug|Win32.Build.0 = Debug|Win32
+		{00E3B0EE-B612-433A-A43E-1CE0B3DE1015}.Release|Win32.ActiveCfg = Release|Win32
+		{00E3B0EE-B612-433A-A43E-1CE0B3DE1015}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/framework/modules/c_FileTypeSigModule/FileTypeModule.cpp b/framework/modules/c_FileTypeSigModule/FileTypeModule.cpp
index e80a8ba..0b70417 100644
--- a/framework/modules/c_FileTypeSigModule/FileTypeModule.cpp
+++ b/framework/modules/c_FileTypeSigModule/FileTypeModule.cpp
@@ -1,203 +1,203 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file FileTypeSigModule.cpp
- * Contains the module that uses libmagic to determine the
- * file type based on signatures.
- */
-
-// System includes
-#include <string>
-#include <sstream>
-#include <stdlib.h>
-#include <string.h>
-
-// Framework includes
-#include "tsk/framework/utilities/TskModuleDev.h"
-
-// Poco includes
-#include "Poco/UnicodeConverter.h"
-#include "Poco/File.h"
-#include "Poco/Path.h"
-
-// Magic includes
-#include "magic.h"
-
-namespace 
-{
-    const char *MODULE_NAME = "tskFileTypeSigModule";
-    const char *MODULE_DESCRIPTION = "Determines file type based on signature using libmagic";
-    const char *MODULE_VERSION = "1.0.3";
-
-  static const uint32_t FILE_BUFFER_SIZE = 1024;
-
-  static magic_t magicHandle = NULL;
-}
-
-extern "C" 
-{
-    /**
-     * Module identification function. 
-     *
-     * @return The name of the module.
-     */
-    TSK_MODULE_EXPORT const char *name() 
-    {
-        return MODULE_NAME;
-    }
-
-    /**
-     * Module identification function. 
-     *
-     * @return A description of the module.
-     */
-    TSK_MODULE_EXPORT const char *description()
-    {
-        return MODULE_DESCRIPTION;
-    }
-
-    /**
-     * Module identification function. 
-     *
-     * @return The version of the module.
-     */
-    TSK_MODULE_EXPORT const char *version()
-    {
-        return MODULE_VERSION;
-    }
-
-    /**
-     * Module initialization function. Takes a string as input that allows
-     * arguments to be passed into the module.
-     * @param arguments Tells the module which
-     */
-    TskModule::Status TSK_MODULE_EXPORT initialize(const char* arguments)
-    {
-        magicHandle = magic_open(MAGIC_NONE);
-        if (magicHandle == NULL) {
-            LOGERROR("FileTypeSigModule: Error allocating magic cookie.");
-            return TskModule::FAIL;
-        }
-
-//Attempt to load magic database from default places on Linux.
-//Don't bother trying magic_load() for defaults on win32 because it will always cause an exception instead of gracefully returning.
-#ifndef TSK_WIN32
-        /* Load the default magic database, which is found in this order:
-               1. MAGIC env variable
-               2. $HOME/.magic.mgc (or $HOME/.magic dir)
-               3. /usr/share/misc/magic.mgc (or /usr/share/misc/magic dir) (unless libmagic was build configured abnormally)
-        */
-        if (magic_load(magicHandle, NULL)) {
-            std::stringstream msg;
-            msg << "FileTypeSigModule: Error loading default magic file: " << magic_error(magicHandle);
-            LOGERROR(msg.str());
-            //don't return, just fall through to the default loading below
-        } else {
-            return TskModule::OK;
-        }
-#endif
-        //Load the magic database file in the repo
-        std::string path = GetSystemProperty(TskSystemProperties::MODULE_CONFIG_DIR) + Poco::Path::separator() + MODULE_NAME + Poco::Path::separator() + "magic.mgc";
-
-        Poco::File magicFile = Poco::File(path);
-        if (magicFile.exists() == false) {
-            std::stringstream msg;
-            msg << "FileTypeSigModule: Magic file not found: " << path;
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-
-        if (magic_load(magicHandle, path.c_str())) {
-            std::stringstream msg;
-            msg << "FileTypeSigModule: Error loading magic file: " << magic_error(magicHandle) << GetSystemProperty(TskSystemProperties::MODULE_CONFIG_DIR);
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-
-        return TskModule::OK;
-    }
-
-    /**
-     * The run() method is where the module's work is performed.
-     * The module will be passed a pointer to a file from which both
-     * content and metadata can be retrieved.
-     * @param pFile A pointer to a file to be processed.
-     * @returns TskModule::OK on success and TskModule::FAIL on error.
-     */
-    TskModule::Status TSK_MODULE_EXPORT run(TskFile * pFile)
-    {
-        if (pFile == NULL)
-        {
-            LOGERROR("FileTypeSigModule: Passed NULL file pointer.");
-            return TskModule::FAIL;
-        }
-
-        if (pFile->getSize() == 0)
-            return TskModule::OK;
-
-        try
-        {
-            char buffer[FILE_BUFFER_SIZE];
-
-            //Do that magic magic
-            ssize_t readLen = pFile->read(buffer, FILE_BUFFER_SIZE);
-            // we shouldn't get zero as a return value since we know the file is not 0 sized at this point
-            if (readLen <= 0) {
-                std::stringstream msg;
-                msg << "FileTypeSigModule: Error reading file contents for file " << pFile->getId();
-                LOGERROR(msg.str());
-                return TskModule::FAIL;
-            }
-
-            const char *type = magic_buffer(magicHandle, buffer, readLen);
-            if (type == NULL) {
-                std::stringstream msg;
-                msg << "FileTypeSigModule: Error getting file type: " << magic_error(magicHandle);
-                LOGERROR(msg.str());
-                return TskModule::FAIL;
-            }
-
-            // clean up type -- we've seen invalid UTF-8 data being returned
-            char cleanType[1024];
-            cleanType[1023] = '\0';
-            strncpy(cleanType, type, 1023);
-            TskUtilities::cleanUTF8(cleanType);
-
-            // Add to blackboard
-            TskBlackboardAttribute attr(TSK_FILE_TYPE_SIG, MODULE_NAME, "", cleanType);
-            pFile->addGenInfoAttribute(attr);
-        }
-        catch (TskException& tskEx)
-        {
-            std::stringstream msg;
-            msg << "FileTypeModule: Caught framework exception: " << tskEx.message();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        catch (std::exception& ex)
-        {
-            std::stringstream msg;
-            msg << "FileTypeModule: Caught exception: " << ex.what();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-
-        return TskModule::OK;
-    }
-
-    TskModule::Status TSK_MODULE_EXPORT finalize()
-    {
-        if (magicHandle != NULL) {
-            magic_close(magicHandle);
-        }
-        return TskModule::OK;
-    }
-}
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file FileTypeSigModule.cpp
+ * Contains the module that uses libmagic to determine the
+ * file type based on signatures.
+ */
+
+// System includes
+#include <string>
+#include <sstream>
+#include <stdlib.h>
+#include <string.h>
+
+// Framework includes
+#include "tsk/framework/utilities/TskModuleDev.h"
+
+// Poco includes
+#include "Poco/UnicodeConverter.h"
+#include "Poco/File.h"
+#include "Poco/Path.h"
+
+// Magic includes
+#include "magic.h"
+
+namespace 
+{
+    const char *MODULE_NAME = "tskFileTypeSigModule";
+    const char *MODULE_DESCRIPTION = "Determines file type based on signature using libmagic";
+    const char *MODULE_VERSION = "1.0.3";
+
+  static const uint32_t FILE_BUFFER_SIZE = 1024;
+
+  static magic_t magicHandle = NULL;
+}
+
+extern "C" 
+{
+    /**
+     * Module identification function. 
+     *
+     * @return The name of the module.
+     */
+    TSK_MODULE_EXPORT const char *name() 
+    {
+        return MODULE_NAME;
+    }
+
+    /**
+     * Module identification function. 
+     *
+     * @return A description of the module.
+     */
+    TSK_MODULE_EXPORT const char *description()
+    {
+        return MODULE_DESCRIPTION;
+    }
+
+    /**
+     * Module identification function. 
+     *
+     * @return The version of the module.
+     */
+    TSK_MODULE_EXPORT const char *version()
+    {
+        return MODULE_VERSION;
+    }
+
+    /**
+     * Module initialization function. Takes a string as input that allows
+     * arguments to be passed into the module.
+     * @param arguments Tells the module which
+     */
+    TskModule::Status TSK_MODULE_EXPORT initialize(const char* arguments)
+    {
+        magicHandle = magic_open(MAGIC_NONE);
+        if (magicHandle == NULL) {
+            LOGERROR("FileTypeSigModule: Error allocating magic cookie.");
+            return TskModule::FAIL;
+        }
+
+//Attempt to load magic database from default places on Linux.
+//Don't bother trying magic_load() for defaults on win32 because it will always cause an exception instead of gracefully returning.
+#ifndef TSK_WIN32
+        /* Load the default magic database, which is found in this order:
+               1. MAGIC env variable
+               2. $HOME/.magic.mgc (or $HOME/.magic dir)
+               3. /usr/share/misc/magic.mgc (or /usr/share/misc/magic dir) (unless libmagic was build configured abnormally)
+        */
+        if (magic_load(magicHandle, NULL)) {
+            std::stringstream msg;
+            msg << "FileTypeSigModule: Error loading default magic file: " << magic_error(magicHandle);
+            LOGERROR(msg.str());
+            //don't return, just fall through to the default loading below
+        } else {
+            return TskModule::OK;
+        }
+#endif
+        //Load the magic database file in the repo
+        std::string path = GetSystemProperty(TskSystemProperties::MODULE_CONFIG_DIR) + Poco::Path::separator() + MODULE_NAME + Poco::Path::separator() + "magic.mgc";
+
+        Poco::File magicFile = Poco::File(path);
+        if (magicFile.exists() == false) {
+            std::stringstream msg;
+            msg << "FileTypeSigModule: Magic file not found: " << path;
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+
+        if (magic_load(magicHandle, path.c_str())) {
+            std::stringstream msg;
+            msg << "FileTypeSigModule: Error loading magic file: " << magic_error(magicHandle) << GetSystemProperty(TskSystemProperties::MODULE_CONFIG_DIR);
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+
+        return TskModule::OK;
+    }
+
+    /**
+     * The run() method is where the module's work is performed.
+     * The module will be passed a pointer to a file from which both
+     * content and metadata can be retrieved.
+     * @param pFile A pointer to a file to be processed.
+     * @returns TskModule::OK on success and TskModule::FAIL on error.
+     */
+    TskModule::Status TSK_MODULE_EXPORT run(TskFile * pFile)
+    {
+        if (pFile == NULL)
+        {
+            LOGERROR("FileTypeSigModule: Passed NULL file pointer.");
+            return TskModule::FAIL;
+        }
+
+        if (pFile->getSize() == 0)
+            return TskModule::OK;
+
+        try
+        {
+            char buffer[FILE_BUFFER_SIZE];
+
+            //Do that magic magic
+            ssize_t readLen = pFile->read(buffer, FILE_BUFFER_SIZE);
+            // we shouldn't get zero as a return value since we know the file is not 0 sized at this point
+            if (readLen <= 0) {
+                std::stringstream msg;
+                msg << "FileTypeSigModule: Error reading file contents for file " << pFile->getId();
+                LOGERROR(msg.str());
+                return TskModule::FAIL;
+            }
+
+            const char *type = magic_buffer(magicHandle, buffer, readLen);
+            if (type == NULL) {
+                std::stringstream msg;
+                msg << "FileTypeSigModule: Error getting file type: " << magic_error(magicHandle);
+                LOGERROR(msg.str());
+                return TskModule::FAIL;
+            }
+
+            // clean up type -- we've seen invalid UTF-8 data being returned
+            char cleanType[1024];
+            cleanType[1023] = '\0';
+            strncpy(cleanType, type, 1023);
+            TskUtilities::cleanUTF8(cleanType);
+
+            // Add to blackboard
+            TskBlackboardAttribute attr(TSK_FILE_TYPE_SIG, MODULE_NAME, "", cleanType);
+            pFile->addGenInfoAttribute(attr);
+        }
+        catch (TskException& tskEx)
+        {
+            std::stringstream msg;
+            msg << "FileTypeModule: Caught framework exception: " << tskEx.message();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        catch (std::exception& ex)
+        {
+            std::stringstream msg;
+            msg << "FileTypeModule: Caught exception: " << ex.what();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+
+        return TskModule::OK;
+    }
+
+    TskModule::Status TSK_MODULE_EXPORT finalize()
+    {
+        if (magicHandle != NULL) {
+            magic_close(magicHandle);
+        }
+        return TskModule::OK;
+    }
+}
diff --git a/framework/modules/c_FileTypeSigModule/NEWS.txt b/framework/modules/c_FileTypeSigModule/NEWS.txt
index ad2cd52..c4cd8a5 100644
--- a/framework/modules/c_FileTypeSigModule/NEWS.txt
+++ b/framework/modules/c_FileTypeSigModule/NEWS.txt
@@ -1,18 +1,18 @@
-Numbers refer to github.net issue #s:
-    https://github.com/sleuthkit/c_FileTypeSigModule/issues
-    
----------------- VERSION 1.0.3 --------------
-- Linux support
-
----------------- VERSION 1.0.2 --------------
-- Log message update
-
----------------- VERSION 1.0.1 --------------
-
-
----------------- VERSION 1.0.0 --------------
-New Features:
-- Initial public release.
-
-Bug Fixes:
-- N/A. 
+Numbers refer to github.net issue #s:
+    https://github.com/sleuthkit/c_FileTypeSigModule/issues
+    
+---------------- VERSION 1.0.3 --------------
+- Linux support
+
+---------------- VERSION 1.0.2 --------------
+- Log message update
+
+---------------- VERSION 1.0.1 --------------
+
+
+---------------- VERSION 1.0.0 --------------
+New Features:
+- Initial public release.
+
+Bug Fixes:
+- N/A. 
diff --git a/framework/modules/c_FileTypeSigModule/README.txt b/framework/modules/c_FileTypeSigModule/README.txt
index 2861d03..2e5d60e 100644
--- a/framework/modules/c_FileTypeSigModule/README.txt
+++ b/framework/modules/c_FileTypeSigModule/README.txt
@@ -1,83 +1,83 @@
-File Type Detection Based on Signature Module
-Sleuth Kit Framework C++ Module
-July 2012. Updated Dec 2012.
-
-This module is for the C++ Sleuth Kit Framework.
-
-
-DESCRIPTION
-
-This module is a file analysis module that examines the file content
-to determine its type (i.e. PDF, JPEG).  It does this based on file
-signatures in libmagic.
-
-DEPLOYMENT REQUIREMENTS
-
-This module has the following deployment requirements for each platform.
-
-Linux:
-
-1. libmagic1
-2. libmagic-dev
-
-Install libmagic1 and libmagic-dev packages, or download the source from one of these places:
-    ftp://ftp.astron.com/pub/file/
-    https://github.com/glensc/file
-If downloaded from the FTP site, the source archive name will be something like "file-5.11.tar.gz".
-
-Win32:
-
-1. libmagic-1.dll must be in the same folder as the module.
-2. The magic file "magic.mgc" must be in a folder named
-   "FileTypeSigModule" in your modules folder.
-
-See also "README_BuildingLibMagicWin32.txt".
-
-USAGE
-
-Add this module to a file analysis pipeline.  See the TSK 
-Framework documents for information on adding the module 
-to the pipeline:
-
-    http://www.sleuthkit.org/sleuthkit/docs/framework-docs/
-
-This module takes no configuration arguments.  
-
-RESULTS
-
-The result of the signature check is written to an attribute
-in the blackboard.
-
-LICENSES
-
-This module uses libmagic.  It has the following license requirements:
-
-$File: COPYING,v 1.1 2008/02/05 19:08:11 christos Exp $
-Copyright (c) Ian F. Darwin 1986, 1987, 1989, 1990, 1991, 1992, 1994, 1995.
-Software written by Ian F. Darwin and others;
-maintained 1994- Christos Zoulas.
-
-This software is not subject to any export provision of the United States
-Department of Commerce, and may be exported to any country or planet.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
-   notice immediately at the beginning of the file, without modification,
-   this list of conditions, and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
- 
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
+File Type Detection Based on Signature Module
+Sleuth Kit Framework C++ Module
+July 2012. Updated Dec 2012.
+
+This module is for the C++ Sleuth Kit Framework.
+
+
+DESCRIPTION
+
+This module is a file analysis module that examines the file content
+to determine its type (i.e. PDF, JPEG).  It does this based on file
+signatures in libmagic.
+
+DEPLOYMENT REQUIREMENTS
+
+This module has the following deployment requirements for each platform.
+
+Linux:
+
+1. libmagic1
+2. libmagic-dev
+
+Install libmagic1 and libmagic-dev packages, or download the source from one of these places:
+    ftp://ftp.astron.com/pub/file/
+    https://github.com/glensc/file
+If downloaded from the FTP site, the source archive name will be something like "file-5.11.tar.gz".
+
+Win32:
+
+1. libmagic-1.dll must be in the same folder as the module.
+2. The magic file "magic.mgc" must be in a folder named
+   "FileTypeSigModule" in your modules folder.
+
+See also "README_BuildingLibMagicWin32.txt".
+
+USAGE
+
+Add this module to a file analysis pipeline.  See the TSK 
+Framework documents for information on adding the module 
+to the pipeline:
+
+    http://www.sleuthkit.org/sleuthkit/docs/framework-docs/
+
+This module takes no configuration arguments.  
+
+RESULTS
+
+The result of the signature check is written to an attribute
+in the blackboard.
+
+LICENSES
+
+This module uses libmagic.  It has the following license requirements:
+
+$File: COPYING,v 1.1 2008/02/05 19:08:11 christos Exp $
+Copyright (c) Ian F. Darwin 1986, 1987, 1989, 1990, 1991, 1992, 1994, 1995.
+Software written by Ian F. Darwin and others;
+maintained 1994- Christos Zoulas.
+
+This software is not subject to any export provision of the United States
+Department of Commerce, and may be exported to any country or planet.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice immediately at the beginning of the file, without modification,
+   this list of conditions, and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+ 
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
diff --git a/framework/modules/c_FileTypeSigModule/README_BuildingLibMagicWin32.txt b/framework/modules/c_FileTypeSigModule/README_BuildingLibMagicWin32.txt
index ffd6c74..fc473d8 100755
--- a/framework/modules/c_FileTypeSigModule/README_BuildingLibMagicWin32.txt
+++ b/framework/modules/c_FileTypeSigModule/README_BuildingLibMagicWin32.txt
@@ -1,41 +1,41 @@
-Building libmagic (and libgnurx, I guess):
-
-  First, you need a copy of mingw and msys installed (for convenience, in the
-top-level directory (C:)).  Then, you need to go into the mingw-libgnurx-2.5.1
-directory in third-party-tools.  From there, run this in an msys shell (yes, it
-does matter):
-
-  ./configure --prefix=/mingw && make && make install
-
-  Now you have a copy of libgnurx.  The configure script should be able to tell
-that it has to cross-compile, so now you should have a copy of libgnurx-0.dll
-installed in the right place (which is under /mingw, because the mingw linker is
-funny and doesn't look other places).  Go back to this directory (file-5.08) and
-run
-
-  ./configure && make
-
-  There should now be a copy of libmagic-1.dll sitting in src/.libs.   Copy it
-into this directory.
-
-Creating libmagic-1.lib:
-
-  Linking against libmagic using Microsoft development tools requires the creation
-  of an "import library" (aka a .lib file). You can create the .lib file as follows:
-  
-  1. Generate a .def file (export definitions) for the dll by running the following 
-     commands in your MSYS shell:
-  
-     a. mingw-get install mingw32-gendef
-  
-     b. gendef libmagic-1.dll
-     
-     This will result in a file named libmagic-1.def
-     
-  2. Generate the .lib file by running the following command in a Microsoft Visual
-     Studio shell:
-     
-     a. lib.exe /machine:i386 /def:libmagic-1.def /out:libmagic-1.lib
-     
-   That's it. You can now link against libmagic in Visual Studio project files by
+Building libmagic (and libgnurx, I guess):
+
+  First, you need a copy of mingw and msys installed (for convenience, in the
+top-level directory (C:)).  Then, you need to go into the mingw-libgnurx-2.5.1
+directory in third-party-tools.  From there, run this in an msys shell (yes, it
+does matter):
+
+  ./configure --prefix=/mingw && make && make install
+
+  Now you have a copy of libgnurx.  The configure script should be able to tell
+that it has to cross-compile, so now you should have a copy of libgnurx-0.dll
+installed in the right place (which is under /mingw, because the mingw linker is
+funny and doesn't look other places).  Go back to this directory (file-5.08) and
+run
+
+  ./configure && make
+
+  There should now be a copy of libmagic-1.dll sitting in src/.libs.   Copy it
+into this directory.
+
+Creating libmagic-1.lib:
+
+  Linking against libmagic using Microsoft development tools requires the creation
+  of an "import library" (aka a .lib file). You can create the .lib file as follows:
+  
+  1. Generate a .def file (export definitions) for the dll by running the following 
+     commands in your MSYS shell:
+  
+     a. mingw-get install mingw32-gendef
+  
+     b. gendef libmagic-1.dll
+     
+     This will result in a file named libmagic-1.def
+     
+  2. Generate the .lib file by running the following command in a Microsoft Visual
+     Studio shell:
+     
+     a. lib.exe /machine:i386 /def:libmagic-1.def /out:libmagic-1.lib
+     
+   That's it. You can now link against libmagic in Visual Studio project files by
    including libmagic-1.lib (and the path in which it lives) as linker settings.
\ No newline at end of file
diff --git a/framework/modules/c_FileTypeSigModule/configure.ac b/framework/modules/c_FileTypeSigModule/configure.ac
index c78379e..3b81a2a 100644
--- a/framework/modules/c_FileTypeSigModule/configure.ac
+++ b/framework/modules/c_FileTypeSigModule/configure.ac
@@ -128,7 +128,6 @@ AC_CHECK_HEADERS([magic.h],
   [AC_MSG_WARN([Cound not find magic headers.])]
 )
 AM_CONDITIONAL([HAS_LIBMAGIC], [test "x$with_magic" = "xyes"])
-AM_COND_IF([HAS_LIBMAGIC], [rm -f missing_libs.txt], [echo "libmagic for FileTypeModule" > missing_libs.txt])
 
 # If libmagic was not found, we continue on and do not error. 
 # The makefile will simply not compile anything. 
@@ -165,6 +164,7 @@ fi
 else
 # action if libmagic is not found
 AC_MSG_WARN([libmagic library not found. FileTypeSigModule will not be built.])
+echo "libmagic for FileTypeModule" > missing_libs.txt
 fi
 
 AC_CONFIG_FILES([Makefile])
diff --git a/framework/modules/c_HashCalcModule/HashCalcModule.cpp b/framework/modules/c_HashCalcModule/HashCalcModule.cpp
index 0b8ea2c..43ab9a2 100755
--- a/framework/modules/c_HashCalcModule/HashCalcModule.cpp
+++ b/framework/modules/c_HashCalcModule/HashCalcModule.cpp
@@ -1,224 +1,224 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2011-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/** \file HashCalcModule.cpp 
- * Contains the implementation of the hash calculation file analysis module.
- */
-
-// System includes
-#include <string>
-#include <sstream>
-#include <string.h>
-
-// Framework includes
-#include "tsk/framework/utilities/TskModuleDev.h"
-
-// strings for command line arguments
-static const std::string MD5_NAME("MD5");
-static const std::string SHA1_NAME("SHA1");
-
-static bool calculateMD5 = true;
-static bool calculateSHA1 = false;
-
-static const char hexMap[] = "0123456789abcdef";
-
-extern "C" 
-{
-    /**
-     * Module identification function. 
-     *
-     * @return The name of the module.
-     */
-    TSK_MODULE_EXPORT const char *name()
-    {
-        return "tskHashCalcModule";
-    }
-
-    /**
-     * Module identification function. 
-     *
-     * @return A description of the module.
-     */
-    TSK_MODULE_EXPORT const char *description()
-    {
-        return "Calculates MD5 and/or SHA-1 hashes of file content";
-    }
-
-    /**
-     * Module identification function. 
-     *
-     * @return The version of the module.
-     */
-    TSK_MODULE_EXPORT const char *version()
-    {
-        return "1.0.1";
-    }
-
-    /**
-     * Module initialization function. Receives arguments, typically read by the
-     * caller from a pipeline configuration file, that determine what hashes the 
-     * module calculates for a given file.
-     *
-     * @param args Valid values are "MD5", "SHA1" or the empty string which will 
-     * result in just "MD5" being calculated. Hash names can be in any order,
-     * separated by spaces or commas. 
-     * @return TskModule::OK if initialization arguments are valid, otherwise 
-     * TskModule::FAIL.
-     */
-    TskModule::Status TSK_MODULE_EXPORT initialize(const char* arguments)
-    {
-        std::string args(arguments);
-
-        // If the argument string is empty we calculate both hashes.
-        if (args.empty()) {
-            calculateMD5 = true;
-            calculateSHA1 = false;
-        }
-        else {
-            calculateMD5 = false;
-            calculateSHA1 = false;
-
-            // If the argument string contains "MD5" we calculate an MD5 hash.
-            if (args.find(MD5_NAME) != std::string::npos) 
-                calculateMD5 = true;
-
-            // If the argument string contains "SHA1" we calculate a SHA1 hash.
-            if (args.find(SHA1_NAME) != std::string::npos) 
-                calculateSHA1 = true;
-
-            // If neither hash is to be calculated it means that the arguments
-            // passed to the module were incorrect. We log an error message
-            // through the framework logging facility.
-            if (!calculateMD5 && !calculateSHA1) {
-                std::stringstream msg;
-                msg << "Invalid arguments passed to hash module: " << args.c_str();
-                LOGERROR(msg.str());
-                return TskModule::FAIL;
-            }
-        }
-
-        if (calculateMD5)
-            LOGINFO("HashCalcModule: Configured to calculate MD5 hashes");
-
-        if (calculateSHA1)
-            LOGINFO("HashCalcModule: Configured to calculate SHA-1 hashes");
-
-        return TskModule::OK;
-    }
-
-    /**
-     * Module execution function. Receives a pointer to a file the module is to
-     * process. The file is represented by a TskFile interface which is used
-     * to read the contents of the file and post calculated hashes of the 
-     * file contents to the database.
-     *
-     * @param pFile A pointer to a file for which the hash calculations are to be performed.
-     * @returns TskModule::OK on success, TskModule::FAIL on error.
-     */
-    TskModule::Status TSK_MODULE_EXPORT run(TskFile * pFile) 
-    {
-        if (pFile == NULL) 
-        {
-            LOGERROR("HashCalcModule: passed NULL file pointer.");
-            return TskModule::FAIL;
-        }
-
-        // We will not attempt to calculate hash values for "unused sector"
-        // files.
-        if (pFile->getTypeId() == TskImgDB::IMGDB_FILES_TYPE_UNUSED)
-            return TskModule::OK;
-
-        try 
-        {
-            TSK_MD5_CTX md5Ctx;
-            TSK_SHA_CTX sha1Ctx;
-
-            if (calculateMD5)
-                TSK_MD5_Init(&md5Ctx);
-
-            if (calculateSHA1)
-                TSK_SHA_Init(&sha1Ctx);
-
-            // file buffer
-            static const uint32_t FILE_BUFFER_SIZE = 32768;
-            char buffer[FILE_BUFFER_SIZE];
-
-            ssize_t bytesRead = 0;
-
-            // Read file content into buffer and write it to the DigestOutputStream.
-            do 
-            {
-                bytesRead = pFile->read(buffer, FILE_BUFFER_SIZE);
-                if (bytesRead > 0) {
-                    if (calculateMD5)
-                        TSK_MD5_Update(&md5Ctx, (unsigned char *) buffer, (unsigned int) bytesRead);
-
-                    if (calculateSHA1)
-                        TSK_SHA_Update(&sha1Ctx, (unsigned char *) buffer, (unsigned int) bytesRead);                  
-                }
-            } while (bytesRead > 0);
-
-            if (calculateMD5) {
-                unsigned char md5Hash[16];
-                TSK_MD5_Final(md5Hash, &md5Ctx);
-
-                char md5TextBuff[33];            
-                for (int i = 0; i < 16; i++) {
-                    md5TextBuff[2 * i] = hexMap[(md5Hash[i] >> 4) & 0xf];
-                    md5TextBuff[2 * i + 1] = hexMap[md5Hash[i] & 0xf];
-                }
-                md5TextBuff[32] = '\0';
-                pFile->setHash(TskImgDB::MD5, md5TextBuff);
-            }
-
-            if (calculateSHA1) {
-                unsigned char sha1Hash[20];
-                TSK_SHA_Final(sha1Hash, &sha1Ctx);
-
-                char textBuff[41];            
-                for (int i = 0; i < 20; i++) {
-                    textBuff[2 * i] = hexMap[(sha1Hash[i] >> 4) & 0xf];
-                    textBuff[2 * i + 1] = hexMap[sha1Hash[i] & 0xf];
-                }
-                textBuff[40] = '\0';
-                pFile->setHash(TskImgDB::SHA1, textBuff);
-            }
-
-        }
-        catch (TskException& tskEx)
-        {
-            std::stringstream msg;
-            msg << "HashCalcModule - Error processing file id " << pFile->getId() << ": " << tskEx.what();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        catch (std::exception& ex)
-        {
-            std::stringstream msg;
-            msg << "HashCalcModule - Error processing file id " << pFile->getId() << ": " << ex.what();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-
-        return TskModule::OK;
-    }
-
-    /**
-     * Module cleanup function. This module does not need to free any 
-     * resources allocated during initialization or execution.
-     *
-     * @returns TskModule::OK
-     */
-    TskModule::Status TSK_MODULE_EXPORT finalize()
-    {
-        return TskModule::OK;
-    }
-}
-
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2011-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/** \file HashCalcModule.cpp 
+ * Contains the implementation of the hash calculation file analysis module.
+ */
+
+// System includes
+#include <string>
+#include <sstream>
+#include <string.h>
+
+// Framework includes
+#include "tsk/framework/utilities/TskModuleDev.h"
+
+// strings for command line arguments
+static const std::string MD5_NAME("MD5");
+static const std::string SHA1_NAME("SHA1");
+
+static bool calculateMD5 = true;
+static bool calculateSHA1 = false;
+
+static const char hexMap[] = "0123456789abcdef";
+
+extern "C" 
+{
+    /**
+     * Module identification function. 
+     *
+     * @return The name of the module.
+     */
+    TSK_MODULE_EXPORT const char *name()
+    {
+        return "tskHashCalcModule";
+    }
+
+    /**
+     * Module identification function. 
+     *
+     * @return A description of the module.
+     */
+    TSK_MODULE_EXPORT const char *description()
+    {
+        return "Calculates MD5 and/or SHA-1 hashes of file content";
+    }
+
+    /**
+     * Module identification function. 
+     *
+     * @return The version of the module.
+     */
+    TSK_MODULE_EXPORT const char *version()
+    {
+        return "1.0.1";
+    }
+
+    /**
+     * Module initialization function. Receives arguments, typically read by the
+     * caller from a pipeline configuration file, that determine what hashes the 
+     * module calculates for a given file.
+     *
+     * @param args Valid values are "MD5", "SHA1" or the empty string which will 
+     * result in just "MD5" being calculated. Hash names can be in any order,
+     * separated by spaces or commas. 
+     * @return TskModule::OK if initialization arguments are valid, otherwise 
+     * TskModule::FAIL.
+     */
+    TskModule::Status TSK_MODULE_EXPORT initialize(const char* arguments)
+    {
+        std::string args(arguments);
+
+        // If the argument string is empty we calculate both hashes.
+        if (args.empty()) {
+            calculateMD5 = true;
+            calculateSHA1 = false;
+        }
+        else {
+            calculateMD5 = false;
+            calculateSHA1 = false;
+
+            // If the argument string contains "MD5" we calculate an MD5 hash.
+            if (args.find(MD5_NAME) != std::string::npos) 
+                calculateMD5 = true;
+
+            // If the argument string contains "SHA1" we calculate a SHA1 hash.
+            if (args.find(SHA1_NAME) != std::string::npos) 
+                calculateSHA1 = true;
+
+            // If neither hash is to be calculated it means that the arguments
+            // passed to the module were incorrect. We log an error message
+            // through the framework logging facility.
+            if (!calculateMD5 && !calculateSHA1) {
+                std::stringstream msg;
+                msg << "Invalid arguments passed to hash module: " << args.c_str();
+                LOGERROR(msg.str());
+                return TskModule::FAIL;
+            }
+        }
+
+        if (calculateMD5)
+            LOGINFO("HashCalcModule: Configured to calculate MD5 hashes");
+
+        if (calculateSHA1)
+            LOGINFO("HashCalcModule: Configured to calculate SHA-1 hashes");
+
+        return TskModule::OK;
+    }
+
+    /**
+     * Module execution function. Receives a pointer to a file the module is to
+     * process. The file is represented by a TskFile interface which is used
+     * to read the contents of the file and post calculated hashes of the 
+     * file contents to the database.
+     *
+     * @param pFile A pointer to a file for which the hash calculations are to be performed.
+     * @returns TskModule::OK on success, TskModule::FAIL on error.
+     */
+    TskModule::Status TSK_MODULE_EXPORT run(TskFile * pFile) 
+    {
+        if (pFile == NULL) 
+        {
+            LOGERROR("HashCalcModule: passed NULL file pointer.");
+            return TskModule::FAIL;
+        }
+
+        // We will not attempt to calculate hash values for "unused sector"
+        // files.
+        if (pFile->getTypeId() == TskImgDB::IMGDB_FILES_TYPE_UNUSED)
+            return TskModule::OK;
+
+        try 
+        {
+            TSK_MD5_CTX md5Ctx;
+            TSK_SHA_CTX sha1Ctx;
+
+            if (calculateMD5)
+                TSK_MD5_Init(&md5Ctx);
+
+            if (calculateSHA1)
+                TSK_SHA_Init(&sha1Ctx);
+
+            // file buffer
+            static const uint32_t FILE_BUFFER_SIZE = 32768;
+            char buffer[FILE_BUFFER_SIZE];
+
+            ssize_t bytesRead = 0;
+
+            // Read file content into buffer and write it to the DigestOutputStream.
+            do 
+            {
+                bytesRead = pFile->read(buffer, FILE_BUFFER_SIZE);
+                if (bytesRead > 0) {
+                    if (calculateMD5)
+                        TSK_MD5_Update(&md5Ctx, (unsigned char *) buffer, (unsigned int) bytesRead);
+
+                    if (calculateSHA1)
+                        TSK_SHA_Update(&sha1Ctx, (unsigned char *) buffer, (unsigned int) bytesRead);                  
+                }
+            } while (bytesRead > 0);
+
+            if (calculateMD5) {
+                unsigned char md5Hash[16];
+                TSK_MD5_Final(md5Hash, &md5Ctx);
+
+                char md5TextBuff[33];            
+                for (int i = 0; i < 16; i++) {
+                    md5TextBuff[2 * i] = hexMap[(md5Hash[i] >> 4) & 0xf];
+                    md5TextBuff[2 * i + 1] = hexMap[md5Hash[i] & 0xf];
+                }
+                md5TextBuff[32] = '\0';
+                pFile->setHash(TskImgDB::MD5, md5TextBuff);
+            }
+
+            if (calculateSHA1) {
+                unsigned char sha1Hash[20];
+                TSK_SHA_Final(sha1Hash, &sha1Ctx);
+
+                char textBuff[41];            
+                for (int i = 0; i < 20; i++) {
+                    textBuff[2 * i] = hexMap[(sha1Hash[i] >> 4) & 0xf];
+                    textBuff[2 * i + 1] = hexMap[sha1Hash[i] & 0xf];
+                }
+                textBuff[40] = '\0';
+                pFile->setHash(TskImgDB::SHA1, textBuff);
+            }
+
+        }
+        catch (TskException& tskEx)
+        {
+            std::stringstream msg;
+            msg << "HashCalcModule - Error processing file id " << pFile->getId() << ": " << tskEx.what();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        catch (std::exception& ex)
+        {
+            std::stringstream msg;
+            msg << "HashCalcModule - Error processing file id " << pFile->getId() << ": " << ex.what();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+
+        return TskModule::OK;
+    }
+
+    /**
+     * Module cleanup function. This module does not need to free any 
+     * resources allocated during initialization or execution.
+     *
+     * @returns TskModule::OK
+     */
+    TskModule::Status TSK_MODULE_EXPORT finalize()
+    {
+        return TskModule::OK;
+    }
+}
+
diff --git a/framework/modules/c_HashCalcModule/NEWS.txt b/framework/modules/c_HashCalcModule/NEWS.txt
index 6c827e7..759c30b 100644
--- a/framework/modules/c_HashCalcModule/NEWS.txt
+++ b/framework/modules/c_HashCalcModule/NEWS.txt
@@ -1,13 +1,13 @@
-Numbers refer to github.net issue #s:
-    https://github.com/sleuthkit/c_HashCalcModule/issues
-    
----------------- VERSION 1.0.1 --------------
-- SHA-1 is not done by default
-- Use TSK libraries instead of POCO
-
----------------- VERSION 1.0.0 --------------
-New Features:
-- Initial public release.
-
-Bug Fixes:
-- N/A. 
+Numbers refer to github.net issue #s:
+    https://github.com/sleuthkit/c_HashCalcModule/issues
+    
+---------------- VERSION 1.0.1 --------------
+- SHA-1 is not done by default
+- Use TSK libraries instead of POCO
+
+---------------- VERSION 1.0.0 --------------
+New Features:
+- Initial public release.
+
+Bug Fixes:
+- N/A. 
diff --git a/framework/modules/c_HashCalcModule/README.txt b/framework/modules/c_HashCalcModule/README.txt
index 68c9a20..839b697 100644
--- a/framework/modules/c_HashCalcModule/README.txt
+++ b/framework/modules/c_HashCalcModule/README.txt
@@ -1,40 +1,40 @@
-Hash Calculation Module
-Sleuth Kit Framework C++ Module
-May 2012
-
-
-This module is for the C++ Sleuth Kit Framework.
-
-
-DESCRIPTION
-
-This module is a file analysis module that calculates 
-MD5 or SHA-1 hash values of file content.  Hash values
-are used to detect known files and are used to later show
-that file content has not changed. 
-
-
-DEPLOYMENT REQUIREMENTS
-
-This module does not have any specific deployment requirements.
-
-
-USAGE
-
-Add this module to a file analysis pipeline.  See the TSK 
-Framework documents for information on adding the module 
-to the pipeline:
-
-    http://www.sleuthkit.org/sleuthkit/docs/framework-docs/
-
-By default, the module will only calculate the MD5 hash.
-To configure the module to calculate SHA-1 or both values,
-then pass either "MD5" or "SHA1" in the pipeline config file.
-If you want to specify that both be calculated, then specify
-both strings in any order and with spaces or commas in between. 
-
-
-RESULTS
-
-The hash values are stored in the central database. 
-
+Hash Calculation Module
+Sleuth Kit Framework C++ Module
+May 2012
+
+
+This module is for the C++ Sleuth Kit Framework.
+
+
+DESCRIPTION
+
+This module is a file analysis module that calculates 
+MD5 or SHA-1 hash values of file content.  Hash values
+are used to detect known files and are used to later show
+that file content has not changed. 
+
+
+DEPLOYMENT REQUIREMENTS
+
+This module does not have any specific deployment requirements.
+
+
+USAGE
+
+Add this module to a file analysis pipeline.  See the TSK 
+Framework documents for information on adding the module 
+to the pipeline:
+
+    http://www.sleuthkit.org/sleuthkit/docs/framework-docs/
+
+By default, the module will only calculate the MD5 hash.
+To configure the module to calculate SHA-1 or both values,
+then pass either "MD5" or "SHA1" in the pipeline config file.
+If you want to specify that both be calculated, then specify
+both strings in any order and with spaces or commas in between. 
+
+
+RESULTS
+
+The hash values are stored in the central database. 
+
diff --git a/framework/modules/c_InterestingFilesModule/InterestingFilesModule.cpp b/framework/modules/c_InterestingFilesModule/InterestingFilesModule.cpp
index b6ea729..be6e0f1 100644
--- a/framework/modules/c_InterestingFilesModule/InterestingFilesModule.cpp
+++ b/framework/modules/c_InterestingFilesModule/InterestingFilesModule.cpp
@@ -1,639 +1,639 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/** \file InterestingFilesModule.cpp
- * Contains the implementation of a post-processing/reporting module that
- * looks for files matching interesting file set criteria specified in a 
- * module configuration file. The module posts its findings to the blackboard. 
- */
-
-// TSK Framework includes
-#include "tsk/framework/utilities/TskModuleDev.h"
-
-// Poco includes
-#include "Poco/String.h"
-#include "Poco/AutoPtr.h"
-#include "Poco/Path.h"
-#include "Poco/File.h"
-#include "Poco/DOM/DOMParser.h"
-#include "Poco/DOM/Document.h"
-#include "Poco/DOM/NodeList.h"
-#include "Poco/DOM/NamedNodeMap.h"
-#include "Poco/SAX/InputSource.h"
-#include "Poco/SAX/SAXException.h"
-
-// System includes
-#include <string>
-#include <vector>
-#include <set>
-#include <sstream>
-#include <fstream>
-
-namespace
-{
-    const char *MODULE_NAME = "tskInterestingFilesModule";
-    const char *MODULE_DESCRIPTION = "Looks for files matching criteria specified in a module configuration file";
-    const char *MODULE_VERSION = "1.0.0";
-    const std::string DEFAULT_CONFIG_FILE_NAME = "interesting_files.xml";
-    const std::string INTERESTING_FILE_SET_ELEMENT_TAG = "INTERESTING_FILE_SET"; 
-    const std::string NAME_ATTRIBUTE = "name";
-    const std::string DESCRIPTION_ATTRIBUTE_TAG = "description";
-    const std::string NAME_ELEMENT_TAG = "NAME";
-    const std::string EXTENSION_ELEMENT_TAG = "EXTENSION";
-    const std::string PATH_FILTER_ATTRIBUTE = "pathFilter";
-    const std::string TYPE_FILTER_ATTRIBUTE = "typeFilter";
-    const std::string FILE_TYPE_FILTER_VALUE = "file";
-    const std::string DIR_TYPE_FILTER_VALUE = "dir";
-
-    std::string configFilePath;
-
-    /** 
-     * An interesting files set is defined by a set name, a set description, 
-     * and one or more SQL WHERE clauses that specify what files belong to the
-     * set.
-     */
-    struct InterestingFilesSet
-    {
-        InterestingFilesSet() : name(""), description("") {}
-        std::string name;
-        std::string description;
-        vector<std::string> conditions;
-    };
-
-    /**
-     * Interesting file set definitions are read from a configuration file in 
-     * the initialize() module API and the file queries are executed in the 
-     * report() module API. The following vector stores the search objects 
-     * between calls to intitialize() and report(). 
-     */
-    std::vector<InterestingFilesSet> fileSets;
-
-    /** 
-     * Looks for glob wildcards in a string.
-     *
-     * @param stringToCheck The string to be checked.
-     * @return True if any glob wildcards where found.
-     */
-    bool hasGlobWildcards(const std::string &stringToCheck)
-    {
-        return stringToCheck.find("*") != std::string::npos;
-    }
-
-    std::string EscapeWildcard(const std::string &s, char escChar) 
-    {
-        std::string newS;
-        for (size_t i = 0; i < s.length(); i++) {
-            char c = s[i];
-            if (c == '_' || c == '%' || c == escChar) {
-                newS += escChar;
-            }
-            newS += c;
-        }
-        return newS;
-    }
-
-    /** 
-     * Converts glob wildcards in a string to SQL wildcards.
-     *
-     * @param stringToChange The string to be changed.
-     */
-    void convertGlobWildcardsToSQLWildcards(std::string &stringToChange)
-    {
-        // Escape all SQL wildcards chars and escape chars that happen to be in the input string.
-        stringToChange = EscapeWildcard(stringToChange, '#');
-
-        // Convert the glob wildcard chars to SQL wildcard chars.
-        Poco::replaceInPlace(stringToChange, "*", "%");
-    }
-
-    /** 
-     * Adds optional file type (file, directory) and path substring filters to 
-     * an SQL WHERE clause for a file search condition.
-     *
-     * @param conditionDefinition A file name or extension condition XML 
-     * element.
-     * @param conditionBuilder A string stream to which to append the filters.
-     */
-    void addPathAndTypeFilterOptions(const Poco::XML::Node *conditionDefinition, std::stringstream &conditionBuilder)
-    {
-        const std::string MSG_PREFIX = "InterestingFilesModule::compileExtensionSearchCondition : ";
-
-        if (conditionDefinition->hasAttributes())
-        {
-            // Look for pathFilter and typeFilter attributes.
-            Poco::AutoPtr<Poco::XML::NamedNodeMap> attributes = conditionDefinition->attributes(); 
-            for (unsigned long i = 0; i < attributes->length(); ++i)
-            {
-                Poco::XML::Node *attribute = attributes->item(i);
-                const std::string& attributeName = Poco::XML::fromXMLString(attribute->nodeName());
-                std::string attributeValue(Poco::XML::fromXMLString(attribute->nodeValue()));
-                if (attributeName == PATH_FILTER_ATTRIBUTE)
-                {        
-                    if (!attributeValue.empty())
-                    {
-                        // File must include a specified substring somewhere in its path.
-                        convertGlobWildcardsToSQLWildcards(attributeValue);
-                        conditionBuilder << " AND UPPER(full_path) LIKE UPPER('%" + attributeValue + "%') ESCAPE '#'";
-                    }
-                    else
-                    {
-                        std::ostringstream msg;
-                        msg << MSG_PREFIX << Poco::XML::fromXMLString(conditionDefinition->nodeName()) << " element has empty " << PATH_FILTER_ATTRIBUTE << " attribute"; 
-                        throw TskException(msg.str());
-                    }
-                }
-                else if (attributeName == TYPE_FILTER_ATTRIBUTE)
-                {
-                    if (!attributeValue.empty())
-                    {
-                        if (attributeValue == FILE_TYPE_FILTER_VALUE)
-                        {
-                            // File must be a regular file.
-                            conditionBuilder << " AND meta_type = " << TSK_FS_META_TYPE_REG;
-                        }
-                        else if (attributeValue == DIR_TYPE_FILTER_VALUE)
-                        {
-                            // File must be a directory.
-                            conditionBuilder << " AND meta_type = " << TSK_FS_META_TYPE_DIR;
-                        }
-                        else
-                        {
-                            std::ostringstream msg;
-                            msg << MSG_PREFIX << Poco::XML::fromXMLString(conditionDefinition->nodeName()) << " element has unrecognized " << TYPE_FILTER_ATTRIBUTE << " attribute value: " << attributeValue; 
-                            throw TskException(msg.str());
-                        }
-                    }
-                    else
-                    {
-                        std::ostringstream msg;
-                        msg << MSG_PREFIX << Poco::XML::fromXMLString(conditionDefinition->nodeName()) << " element has empty " << TYPE_FILTER_ATTRIBUTE << " attribute"; 
-                        throw TskException(msg.str());
-                    }
-                }
-                else
-                {
-                    std::stringstream msg;
-                    msg << MSG_PREFIX << Poco::XML::fromXMLString(conditionDefinition->nodeName()) << " element has unrecognized " << attributeName << " attribute"; 
-                    throw TskException(msg.str());
-                }
-            }
-        }
-    }
-
-    /**
-      * Creates an SQL WHERE clause for a file query from a file name
-      * condition.
-      *
-      * @param conditionDefinition A file name condition XML element.
-      * @param conditions The WHERE clause is added to this collection.
-      */
-    void compileFileNameSearchCondition(const Poco::XML::Node *conditionDefinition, std::vector<std::string> &conditions)
-    {
-        const std::string MSG_PREFIX = "InterestingFilesModule::compileFileNameSearchCondition : ";
-
-        std::string name(Poco::XML::fromXMLString(conditionDefinition->innerText()));
-        if (name.empty())
-        {
-            std::ostringstream msg;
-            msg << MSG_PREFIX << "empty " << NAME_ELEMENT_TAG << " element"; 
-            throw TskException(msg.str());
-        }
-
-        std::stringstream conditionBuilder;
-        if (hasGlobWildcards(name))
-        {
-            convertGlobWildcardsToSQLWildcards(name);
-            conditionBuilder << "WHERE UPPER(name) LIKE UPPER(" << TskServices::Instance().getImgDB().quote(name) << ") ESCAPE '#' ";
-        }
-        else
-        {
-            conditionBuilder << "WHERE UPPER(name) = UPPER(" +  TskServices::Instance().getImgDB().quote(name) + ")";
-        }
-
-        addPathAndTypeFilterOptions(conditionDefinition, conditionBuilder);
-        conditionBuilder << " ORDER BY file_id";
-        conditions.push_back(conditionBuilder.str());
-    }
-
-    /**
-      * Creates an SQL WHERE clause for a file query from a file extension
-      * condition.
-      *
-      * @param conditionDefinition A file extension condition XML element.
-      * @param conditions The WHERE clause is added to this collection.
-      */
-    void compileExtensionSearchCondition(const Poco::XML::Node *conditionDefinition, std::vector<std::string> &conditions)
-    {
-        const std::string MSG_PREFIX = "InterestingFilesModule::compileExtensionSearchCondition : ";
-
-        std::string extension(Poco::XML::fromXMLString(conditionDefinition->innerText()));
-        if (extension.empty())
-        {
-            std::ostringstream msg;
-            msg << MSG_PREFIX << "empty " << EXTENSION_ELEMENT_TAG << " element"; 
-            throw TskException(msg.str());
-        }
-
-        // Supply the leading dot, if omitted.
-        if (extension[0] != '.')
-        {
-            extension.insert(0, ".");
-        }
-
-        convertGlobWildcardsToSQLWildcards(extension);
-        
-        // Extension searches must always have an initial SQL zero to many chars wildcard.
-        // @@@ TODO: In combination with glob wildcards this may create some unxepected matches.
-        // For example, ".htm*" will become "%.htm%" which will match "file.htm.txt" and the like.
-        std::stringstream conditionBuilder;
-        conditionBuilder << "WHERE UPPER(name) LIKE UPPER('%" << extension << "') ESCAPE '#' ";
-
-        addPathAndTypeFilterOptions(conditionDefinition, conditionBuilder);            
-        conditionBuilder << " ORDER BY file_id";
-        conditions.push_back(conditionBuilder.str());
-    }
-
-    /** 
-     * Creates an InterestingFilesSet object from an an interesting files 
-     * set definition. 
-     *
-     * @param fileSetDefinition An interesting file set definition XML element.
-     */
-    void compileInterestingFilesSet(const Poco::XML::Node *fileSetDefinition)
-    {
-        // Create a counter for use in generating default interesting file set names.
-        static unsigned long defaultSetNumber = 1;
-
-        // Keep track of unique file set names.
-        static std::set<std::string> setNames;
-
-        // Determine the name and description of the file set. Every file set must be named, but the description is optional.
-        // A default name is provided if omitted, so the parsing that follows logs warnings if unexpected attributes or values are parsed.
-        const std::string MSG_PREFIX = "InterestingFilesModule::compileInterestingFilesSet : ";
-        InterestingFilesSet fileSet;
-        if (fileSetDefinition->hasAttributes())
-        {
-            Poco::AutoPtr<Poco::XML::NamedNodeMap> attributes = fileSetDefinition->attributes(); 
-            for (unsigned long i = 0; i < attributes->length(); ++i)
-            {
-                Poco::XML::Node *attribute = attributes->item(i);
-                const std::string &attributeName = Poco::XML::fromXMLString(attribute->nodeName());                
-                const std::string &attributeValue = Poco::XML::fromXMLString(attribute->nodeValue());
-                if (!attributeValue.empty())
-                {
-                    if (attributeName == NAME_ATTRIBUTE)
-                    {        
-                        if (!attributeValue.empty())
-                        {
-                            fileSet.name = attributeValue;
-                        }
-                        else
-                        {
-                            std::ostringstream msg;
-                            msg << MSG_PREFIX << "ignored " << INTERESTING_FILE_SET_ELEMENT_TAG << "'" << NAME_ATTRIBUTE << "' attribute without a value"; 
-                            LOGWARN(msg.str());
-                        }
-                    }
-                    else if (attributeName == DESCRIPTION_ATTRIBUTE_TAG)
-                    {
-                        if (!attributeValue.empty())
-                        {
-                            fileSet.description = attributeValue;
-                        }
-                        else
-                        {
-                            std::ostringstream msg;
-                            msg << MSG_PREFIX << "ignored " << INTERESTING_FILE_SET_ELEMENT_TAG << "'" << DESCRIPTION_ATTRIBUTE_TAG << "' attribute without a value"; 
-                            LOGWARN(msg.str());
-                        }
-                    }
-                    else
-                    {
-                        std::ostringstream msg;
-                        msg << MSG_PREFIX << "ignored unrecognized " << INTERESTING_FILE_SET_ELEMENT_TAG << "'" << attributeName << "' attribute"; 
-                        LOGWARN(msg.str());
-                    }
-                }
-            }
-        }
-
-        if (fileSet.name.empty())
-        {
-            // Supply a default name.
-            std::stringstream nameBuilder;
-            nameBuilder << "Unnamed_" << defaultSetNumber++;
-            fileSet.name = nameBuilder.str();
-        }
-
-        // The file set name cannot contain a path character since it may be used later
-        // as a folder name by a save interesting files module.
-        if (fileSet.name.find_first_of("<>:\"/\\|?*") != std::string::npos)
-        {
-            std::ostringstream msg;
-            msg << MSG_PREFIX << INTERESTING_FILE_SET_ELEMENT_TAG << " element " << NAME_ATTRIBUTE << " attribute value '" << fileSet.name << "' contains file path character";
-            throw TskException(msg.str());
-        }
-
-        // The file set name cannot be shorthand for the a current directory or parent directory since it may be used later
-        // as a folder name by a save interesting files module.
-        if (fileSet.name == (".") || fileSet.name == (".."))
-        {
-            std::ostringstream msg;
-            msg << MSG_PREFIX << INTERESTING_FILE_SET_ELEMENT_TAG << " element " << NAME_ATTRIBUTE << " attribute value '" << fileSet.name << "' is directory alias";
-            throw TskException(msg.str());
-        }
-
-        // Every file set must be uniquely named since it may be used later as a folder name by a save interesting files module.
-        if (setNames.count(fileSet.name) != 0)
-        {
-            std::ostringstream msg;
-            msg << MSG_PREFIX << "duplicate " << INTERESTING_FILE_SET_ELEMENT_TAG << " element " << NAME_ATTRIBUTE << " attribute value '" << fileSet.name << "'";
-            throw TskException(msg.str());
-        }
-
-        // Get the search conditions.
-        Poco::AutoPtr<Poco::XML::NodeList>conditionDefinitions = fileSetDefinition->childNodes();
-        for (unsigned long i = 0; i < conditionDefinitions->length(); ++i)
-        {
-            Poco::XML::Node *conditionDefinition = conditionDefinitions->item(i);
-            if (conditionDefinition->nodeType() == Poco::XML::Node::ELEMENT_NODE) 
-            {
-                const std::string &conditionType = Poco::XML::fromXMLString(conditionDefinition->nodeName());
-                if (conditionType == NAME_ELEMENT_TAG)
-                {
-                    compileFileNameSearchCondition(conditionDefinition, fileSet.conditions);
-                }
-                else if (conditionType == EXTENSION_ELEMENT_TAG)
-                {
-                    compileExtensionSearchCondition(conditionDefinition, fileSet.conditions);
-                }
-                else
-                {
-                    std::ostringstream msg;
-                    msg << MSG_PREFIX << "unrecognized " << INTERESTING_FILE_SET_ELEMENT_TAG << " child element '" << conditionType << "'"; 
-                    throw TskException(msg.str());
-                }
-            }
-
-        }
-
-        if (!fileSet.conditions.empty())
-        {
-            fileSets.push_back(fileSet);
-        }
-        else
-        {
-            std::ostringstream msg;
-            msg << MSG_PREFIX << "empty " << INTERESTING_FILE_SET_ELEMENT_TAG << " element '" << fileSet.name << "'"; 
-            //throw TskException(msg.str());
-        }
-    }
-}
-
-extern "C" 
-{
-    /**
-     * Module identification function. 
-     *
-     * @return The name of the module.
-     */
-    TSK_MODULE_EXPORT const char *name()
-    {
-        return MODULE_NAME;
-    }
-
-    /**
-     * Module identification function. 
-     *
-     * @return A description of the module.
-     */
-    TSK_MODULE_EXPORT const char *description()
-    {
-        return MODULE_DESCRIPTION;
-    }
-
-    /**
-     * Module identification function. 
-     *
-     * @return The version of the module.
-     */
-    TSK_MODULE_EXPORT const char *version()
-    {
-        return MODULE_VERSION;
-    }
-
-    /**
-     * Module initialization function. The initialization arguments string should
-     * provide the path of a module configuration file that defines what files 
-     * are interesting. If the empty string is passed to this function, the module
-     * assumes a default config file is present in the output directory.
-     *
-     * @param args Path of the configuration file that defines what files are 
-     * interesting, may be set to the empty string.
-     * @return TskModule::OK on success, TskModule::FAIL otherwise. 
-     */
-    TSK_MODULE_EXPORT TskModule::Status initialize(const char* arguments)
-    {
-        TskModule::Status status = TskModule::OK;
-
-        const std::string MSG_PREFIX = "InterestingFilesModule::initialize : ";
-        try
-        {
-            // Make sure the file sets are cleared in case initialize() is called more than once.
-            fileSets.clear();
-
-            configFilePath.assign(arguments);
-            if (configFilePath.empty())
-            {
-                // Use the default config file path.
-                Poco::Path configurationFilePath(Poco::Path::forDirectory(GetSystemProperty(TskSystemProperties::MODULE_CONFIG_DIR)));
-                configurationFilePath.pushDirectory(MODULE_NAME);
-                configurationFilePath.setFileName(DEFAULT_CONFIG_FILE_NAME);
-                configFilePath = configurationFilePath.toString();
-            }
-
-            // Compile the contents of the config file into interesting file set definitions.
-            Poco::File configFile = Poco::File(configFilePath);
-            if (configFile.exists())
-            {
-                std::ifstream configStream(configFile.path().c_str());
-                if (configStream)
-                {
-                    Poco::XML::InputSource inputSource(configStream);
-                    Poco::AutoPtr<Poco::XML::Document> configDoc = Poco::XML::DOMParser().parse(&inputSource);
-                    Poco::AutoPtr<Poco::XML::NodeList> fileSetDefinitions = configDoc->getElementsByTagName(INTERESTING_FILE_SET_ELEMENT_TAG);
-                    for (unsigned long i = 0; i < fileSetDefinitions->length(); ++i) 
-                    {
-                        compileInterestingFilesSet(fileSetDefinitions->item(i));
-                    }
-                }
-                else
-                {
-                    std::ostringstream msg;
-                    msg << MSG_PREFIX << "failed to open config file '" << configFilePath << "'";
-                    throw TskException(msg.str());
-                }
-            }
-            else
-            {
-                std::ostringstream msg;
-                msg << MSG_PREFIX << "config file'" << configFilePath << "' does not exist";
-                LOGERROR(msg.str());
-            }
-
-            // Log the configuration.
-            std::ostringstream msg;
-            msg << MSG_PREFIX << "configured with " << fileSets.size() << " interesting file set definitions from '" << configFilePath << "'";
-            LOGINFO(msg.str());
-        }
-        catch (TskException &ex)
-        {
-            status = TskModule::FAIL;
-            configFilePath.clear();
-            std::ostringstream msg;
-            msg << MSG_PREFIX << "TskException: " << ex.message();
-            LOGERROR(msg.str());
-        }
-        catch (Poco::Exception &ex)
-        {
-            status = TskModule::FAIL;
-            configFilePath.clear();
-            std::ostringstream msg;
-            msg << MSG_PREFIX << "Poco::Exception: " << ex.displayText();
-            LOGERROR(msg.str());
-        }
-        catch (std::exception &ex)
-        {
-            status = TskModule::FAIL;
-            configFilePath.clear();
-            std::ostringstream msg;
-            msg << MSG_PREFIX << "std::exception: " << ex.what();
-            LOGERROR(msg.str());
-        }
-        catch (...)
-        {
-            status = TskModule::FAIL;
-            configFilePath.clear();
-            LOGERROR(MSG_PREFIX + "unrecognized exception");
-        }
-
-        return status;
-    }
-
-    /**
-     * Module execution function. Looks for files matching the criteria specified in the 
-     * configuration file and posts its findings to the blackboard.
-     *
-     * @returns Returns TskModule::FAIL if an error occurs, TskModule::OK otherwise.
-     */
-    TSK_MODULE_EXPORT TskModule::Status report()
-    {
-        TskModule::Status status = TskModule::OK;
-
-        const std::string MSG_PREFIX = "InterestingFilesModule::report : ";
-        try
-        {
-            if (configFilePath.empty())
-            {
-                // Initialization failed. The reason why was already logged in initialize().
-                return TskModule::FAIL;
-            }
-
-            for (std::vector<InterestingFilesSet>::iterator fileSet = fileSets.begin(); fileSet != fileSets.end(); ++fileSet)
-            {
-                for (std::vector<string>::iterator condition = (*fileSet).conditions.begin(); condition != (*fileSet).conditions.end(); ++condition)
-                {
-                    vector<uint64_t> fileIds = TskServices::Instance().getImgDB().getFileIds(*condition);
-                    for (size_t i = 0; i < fileIds.size(); i++)
-                    {
-                        TskBlackboardArtifact artifact = TskServices::Instance().getBlackboard().createArtifact(fileIds[i], TSK_INTERESTING_FILE_HIT);
-                        TskBlackboardAttribute attribute(TSK_SET_NAME, "InterestingFiles", (*fileSet).description, (*fileSet).name);
-                        artifact.addAttribute(attribute);
-                    }
-                }
-            }
-        }
-        catch (TskException &ex)
-        {
-            status = TskModule::FAIL;
-            std::ostringstream msg;
-            msg << MSG_PREFIX << "TskException: " << ex.message();
-            LOGERROR(msg.str());
-        }
-        catch (Poco::Exception &ex)
-        {
-            status = TskModule::FAIL;
-            std::ostringstream msg;
-            msg << MSG_PREFIX << "Poco::Exception: " << ex.displayText();
-            LOGERROR(msg.str());
-        }
-        catch (std::exception &ex)
-        {
-            status = TskModule::FAIL;
-            std::ostringstream msg;
-            msg << MSG_PREFIX << "std::exception: " << ex.what();
-            LOGERROR(msg.str());
-        }
-        catch (...)
-        {
-            status = TskModule::FAIL;
-            LOGERROR(MSG_PREFIX + "unrecognized exception");
-        }
-
-        return status;
-    }
-
-    /**
-     * Module cleanup function. Disposes of file search data created during initialization.
-     *
-     * @returns TskModule::OK
-     */
-    TskModule::Status TSK_MODULE_EXPORT finalize()
-    {
-        TskModule::Status status = TskModule::OK;
-
-        const std::string MSG_PREFIX = "InterestingFilesModule::finalize : ";
-        try
-        {
-            fileSets.clear();
-        }
-        catch (TskException &ex)
-        {
-            status = TskModule::FAIL;
-            configFilePath.clear();
-            std::ostringstream msg;
-            msg << MSG_PREFIX << "TskException: " << ex.message();
-            LOGERROR(msg.str());
-        }
-        catch (Poco::Exception &ex)
-        {
-            status = TskModule::FAIL;
-            configFilePath.clear();
-            std::ostringstream msg;
-            msg << MSG_PREFIX << "Poco::Exception: " << ex.displayText();
-            LOGERROR(msg.str());
-        }
-        catch (std::exception &ex)
-        {
-            status = TskModule::FAIL;
-            configFilePath.clear();
-            std::ostringstream msg;
-            msg << MSG_PREFIX << "std::exception: " << ex.what();
-            LOGERROR(msg.str());
-        }
-        catch (...)
-        {
-            status = TskModule::FAIL;
-            LOGERROR(MSG_PREFIX + "unrecognized exception");
-        }
-
-        return status;
-    }
-}
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/** \file InterestingFilesModule.cpp
+ * Contains the implementation of a post-processing/reporting module that
+ * looks for files matching interesting file set criteria specified in a 
+ * module configuration file. The module posts its findings to the blackboard. 
+ */
+
+// TSK Framework includes
+#include "tsk/framework/utilities/TskModuleDev.h"
+
+// Poco includes
+#include "Poco/String.h"
+#include "Poco/AutoPtr.h"
+#include "Poco/Path.h"
+#include "Poco/File.h"
+#include "Poco/DOM/DOMParser.h"
+#include "Poco/DOM/Document.h"
+#include "Poco/DOM/NodeList.h"
+#include "Poco/DOM/NamedNodeMap.h"
+#include "Poco/SAX/InputSource.h"
+#include "Poco/SAX/SAXException.h"
+
+// System includes
+#include <string>
+#include <vector>
+#include <set>
+#include <sstream>
+#include <fstream>
+
+namespace
+{
+    const char *MODULE_NAME = "tskInterestingFilesModule";
+    const char *MODULE_DESCRIPTION = "Looks for files matching criteria specified in a module configuration file";
+    const char *MODULE_VERSION = "1.0.0";
+    const std::string DEFAULT_CONFIG_FILE_NAME = "interesting_files.xml";
+    const std::string INTERESTING_FILE_SET_ELEMENT_TAG = "INTERESTING_FILE_SET"; 
+    const std::string NAME_ATTRIBUTE = "name";
+    const std::string DESCRIPTION_ATTRIBUTE_TAG = "description";
+    const std::string NAME_ELEMENT_TAG = "NAME";
+    const std::string EXTENSION_ELEMENT_TAG = "EXTENSION";
+    const std::string PATH_FILTER_ATTRIBUTE = "pathFilter";
+    const std::string TYPE_FILTER_ATTRIBUTE = "typeFilter";
+    const std::string FILE_TYPE_FILTER_VALUE = "file";
+    const std::string DIR_TYPE_FILTER_VALUE = "dir";
+
+    std::string configFilePath;
+
+    /** 
+     * An interesting files set is defined by a set name, a set description, 
+     * and one or more SQL WHERE clauses that specify what files belong to the
+     * set.
+     */
+    struct InterestingFilesSet
+    {
+        InterestingFilesSet() : name(""), description("") {}
+        std::string name;
+        std::string description;
+        vector<std::string> conditions;
+    };
+
+    /**
+     * Interesting file set definitions are read from a configuration file in 
+     * the initialize() module API and the file queries are executed in the 
+     * report() module API. The following vector stores the search objects 
+     * between calls to intitialize() and report(). 
+     */
+    std::vector<InterestingFilesSet> fileSets;
+
+    /** 
+     * Looks for glob wildcards in a string.
+     *
+     * @param stringToCheck The string to be checked.
+     * @return True if any glob wildcards where found.
+     */
+    bool hasGlobWildcards(const std::string &stringToCheck)
+    {
+        return stringToCheck.find("*") != std::string::npos;
+    }
+
+    std::string EscapeWildcard(const std::string &s, char escChar) 
+    {
+        std::string newS;
+        for (size_t i = 0; i < s.length(); i++) {
+            char c = s[i];
+            if (c == '_' || c == '%' || c == escChar) {
+                newS += escChar;
+            }
+            newS += c;
+        }
+        return newS;
+    }
+
+    /** 
+     * Converts glob wildcards in a string to SQL wildcards.
+     *
+     * @param stringToChange The string to be changed.
+     */
+    void convertGlobWildcardsToSQLWildcards(std::string &stringToChange)
+    {
+        // Escape all SQL wildcards chars and escape chars that happen to be in the input string.
+        stringToChange = EscapeWildcard(stringToChange, '#');
+
+        // Convert the glob wildcard chars to SQL wildcard chars.
+        Poco::replaceInPlace(stringToChange, "*", "%");
+    }
+
+    /** 
+     * Adds optional file type (file, directory) and path substring filters to 
+     * an SQL WHERE clause for a file search condition.
+     *
+     * @param conditionDefinition A file name or extension condition XML 
+     * element.
+     * @param conditionBuilder A string stream to which to append the filters.
+     */
+    void addPathAndTypeFilterOptions(const Poco::XML::Node *conditionDefinition, std::stringstream &conditionBuilder)
+    {
+        const std::string MSG_PREFIX = "InterestingFilesModule::compileExtensionSearchCondition : ";
+
+        if (conditionDefinition->hasAttributes())
+        {
+            // Look for pathFilter and typeFilter attributes.
+            Poco::AutoPtr<Poco::XML::NamedNodeMap> attributes = conditionDefinition->attributes(); 
+            for (unsigned long i = 0; i < attributes->length(); ++i)
+            {
+                Poco::XML::Node *attribute = attributes->item(i);
+                const std::string& attributeName = Poco::XML::fromXMLString(attribute->nodeName());
+                std::string attributeValue(Poco::XML::fromXMLString(attribute->nodeValue()));
+                if (attributeName == PATH_FILTER_ATTRIBUTE)
+                {        
+                    if (!attributeValue.empty())
+                    {
+                        // File must include a specified substring somewhere in its path.
+                        convertGlobWildcardsToSQLWildcards(attributeValue);
+                        conditionBuilder << " AND UPPER(full_path) LIKE UPPER('%" + attributeValue + "%') ESCAPE '#'";
+                    }
+                    else
+                    {
+                        std::ostringstream msg;
+                        msg << MSG_PREFIX << Poco::XML::fromXMLString(conditionDefinition->nodeName()) << " element has empty " << PATH_FILTER_ATTRIBUTE << " attribute"; 
+                        throw TskException(msg.str());
+                    }
+                }
+                else if (attributeName == TYPE_FILTER_ATTRIBUTE)
+                {
+                    if (!attributeValue.empty())
+                    {
+                        if (attributeValue == FILE_TYPE_FILTER_VALUE)
+                        {
+                            // File must be a regular file.
+                            conditionBuilder << " AND meta_type = " << TSK_FS_META_TYPE_REG;
+                        }
+                        else if (attributeValue == DIR_TYPE_FILTER_VALUE)
+                        {
+                            // File must be a directory.
+                            conditionBuilder << " AND meta_type = " << TSK_FS_META_TYPE_DIR;
+                        }
+                        else
+                        {
+                            std::ostringstream msg;
+                            msg << MSG_PREFIX << Poco::XML::fromXMLString(conditionDefinition->nodeName()) << " element has unrecognized " << TYPE_FILTER_ATTRIBUTE << " attribute value: " << attributeValue; 
+                            throw TskException(msg.str());
+                        }
+                    }
+                    else
+                    {
+                        std::ostringstream msg;
+                        msg << MSG_PREFIX << Poco::XML::fromXMLString(conditionDefinition->nodeName()) << " element has empty " << TYPE_FILTER_ATTRIBUTE << " attribute"; 
+                        throw TskException(msg.str());
+                    }
+                }
+                else
+                {
+                    std::stringstream msg;
+                    msg << MSG_PREFIX << Poco::XML::fromXMLString(conditionDefinition->nodeName()) << " element has unrecognized " << attributeName << " attribute"; 
+                    throw TskException(msg.str());
+                }
+            }
+        }
+    }
+
+    /**
+      * Creates an SQL WHERE clause for a file query from a file name
+      * condition.
+      *
+      * @param conditionDefinition A file name condition XML element.
+      * @param conditions The WHERE clause is added to this collection.
+      */
+    void compileFileNameSearchCondition(const Poco::XML::Node *conditionDefinition, std::vector<std::string> &conditions)
+    {
+        const std::string MSG_PREFIX = "InterestingFilesModule::compileFileNameSearchCondition : ";
+
+        std::string name(Poco::XML::fromXMLString(conditionDefinition->innerText()));
+        if (name.empty())
+        {
+            std::ostringstream msg;
+            msg << MSG_PREFIX << "empty " << NAME_ELEMENT_TAG << " element"; 
+            throw TskException(msg.str());
+        }
+
+        std::stringstream conditionBuilder;
+        if (hasGlobWildcards(name))
+        {
+            convertGlobWildcardsToSQLWildcards(name);
+            conditionBuilder << "WHERE UPPER(name) LIKE UPPER(" << TskServices::Instance().getImgDB().quote(name) << ") ESCAPE '#' ";
+        }
+        else
+        {
+            conditionBuilder << "WHERE UPPER(name) = UPPER(" +  TskServices::Instance().getImgDB().quote(name) + ")";
+        }
+
+        addPathAndTypeFilterOptions(conditionDefinition, conditionBuilder);
+        conditionBuilder << " ORDER BY file_id";
+        conditions.push_back(conditionBuilder.str());
+    }
+
+    /**
+      * Creates an SQL WHERE clause for a file query from a file extension
+      * condition.
+      *
+      * @param conditionDefinition A file extension condition XML element.
+      * @param conditions The WHERE clause is added to this collection.
+      */
+    void compileExtensionSearchCondition(const Poco::XML::Node *conditionDefinition, std::vector<std::string> &conditions)
+    {
+        const std::string MSG_PREFIX = "InterestingFilesModule::compileExtensionSearchCondition : ";
+
+        std::string extension(Poco::XML::fromXMLString(conditionDefinition->innerText()));
+        if (extension.empty())
+        {
+            std::ostringstream msg;
+            msg << MSG_PREFIX << "empty " << EXTENSION_ELEMENT_TAG << " element"; 
+            throw TskException(msg.str());
+        }
+
+        // Supply the leading dot, if omitted.
+        if (extension[0] != '.')
+        {
+            extension.insert(0, ".");
+        }
+
+        convertGlobWildcardsToSQLWildcards(extension);
+        
+        // Extension searches must always have an initial SQL zero to many chars wildcard.
+        // @@@ TODO: In combination with glob wildcards this may create some unxepected matches.
+        // For example, ".htm*" will become "%.htm%" which will match "file.htm.txt" and the like.
+        std::stringstream conditionBuilder;
+        conditionBuilder << "WHERE UPPER(name) LIKE UPPER('%" << extension << "') ESCAPE '#' ";
+
+        addPathAndTypeFilterOptions(conditionDefinition, conditionBuilder);            
+        conditionBuilder << " ORDER BY file_id";
+        conditions.push_back(conditionBuilder.str());
+    }
+
+    /** 
+     * Creates an InterestingFilesSet object from an an interesting files 
+     * set definition. 
+     *
+     * @param fileSetDefinition An interesting file set definition XML element.
+     */
+    void compileInterestingFilesSet(const Poco::XML::Node *fileSetDefinition)
+    {
+        // Create a counter for use in generating default interesting file set names.
+        static unsigned long defaultSetNumber = 1;
+
+        // Keep track of unique file set names.
+        static std::set<std::string> setNames;
+
+        // Determine the name and description of the file set. Every file set must be named, but the description is optional.
+        // A default name is provided if omitted, so the parsing that follows logs warnings if unexpected attributes or values are parsed.
+        const std::string MSG_PREFIX = "InterestingFilesModule::compileInterestingFilesSet : ";
+        InterestingFilesSet fileSet;
+        if (fileSetDefinition->hasAttributes())
+        {
+            Poco::AutoPtr<Poco::XML::NamedNodeMap> attributes = fileSetDefinition->attributes(); 
+            for (unsigned long i = 0; i < attributes->length(); ++i)
+            {
+                Poco::XML::Node *attribute = attributes->item(i);
+                const std::string &attributeName = Poco::XML::fromXMLString(attribute->nodeName());                
+                const std::string &attributeValue = Poco::XML::fromXMLString(attribute->nodeValue());
+                if (!attributeValue.empty())
+                {
+                    if (attributeName == NAME_ATTRIBUTE)
+                    {        
+                        if (!attributeValue.empty())
+                        {
+                            fileSet.name = attributeValue;
+                        }
+                        else
+                        {
+                            std::ostringstream msg;
+                            msg << MSG_PREFIX << "ignored " << INTERESTING_FILE_SET_ELEMENT_TAG << "'" << NAME_ATTRIBUTE << "' attribute without a value"; 
+                            LOGWARN(msg.str());
+                        }
+                    }
+                    else if (attributeName == DESCRIPTION_ATTRIBUTE_TAG)
+                    {
+                        if (!attributeValue.empty())
+                        {
+                            fileSet.description = attributeValue;
+                        }
+                        else
+                        {
+                            std::ostringstream msg;
+                            msg << MSG_PREFIX << "ignored " << INTERESTING_FILE_SET_ELEMENT_TAG << "'" << DESCRIPTION_ATTRIBUTE_TAG << "' attribute without a value"; 
+                            LOGWARN(msg.str());
+                        }
+                    }
+                    else
+                    {
+                        std::ostringstream msg;
+                        msg << MSG_PREFIX << "ignored unrecognized " << INTERESTING_FILE_SET_ELEMENT_TAG << "'" << attributeName << "' attribute"; 
+                        LOGWARN(msg.str());
+                    }
+                }
+            }
+        }
+
+        if (fileSet.name.empty())
+        {
+            // Supply a default name.
+            std::stringstream nameBuilder;
+            nameBuilder << "Unnamed_" << defaultSetNumber++;
+            fileSet.name = nameBuilder.str();
+        }
+
+        // The file set name cannot contain a path character since it may be used later
+        // as a folder name by a save interesting files module.
+        if (fileSet.name.find_first_of("<>:\"/\\|?*") != std::string::npos)
+        {
+            std::ostringstream msg;
+            msg << MSG_PREFIX << INTERESTING_FILE_SET_ELEMENT_TAG << " element " << NAME_ATTRIBUTE << " attribute value '" << fileSet.name << "' contains file path character";
+            throw TskException(msg.str());
+        }
+
+        // The file set name cannot be shorthand for the a current directory or parent directory since it may be used later
+        // as a folder name by a save interesting files module.
+        if (fileSet.name == (".") || fileSet.name == (".."))
+        {
+            std::ostringstream msg;
+            msg << MSG_PREFIX << INTERESTING_FILE_SET_ELEMENT_TAG << " element " << NAME_ATTRIBUTE << " attribute value '" << fileSet.name << "' is directory alias";
+            throw TskException(msg.str());
+        }
+
+        // Every file set must be uniquely named since it may be used later as a folder name by a save interesting files module.
+        if (setNames.count(fileSet.name) != 0)
+        {
+            std::ostringstream msg;
+            msg << MSG_PREFIX << "duplicate " << INTERESTING_FILE_SET_ELEMENT_TAG << " element " << NAME_ATTRIBUTE << " attribute value '" << fileSet.name << "'";
+            throw TskException(msg.str());
+        }
+
+        // Get the search conditions.
+        Poco::AutoPtr<Poco::XML::NodeList>conditionDefinitions = fileSetDefinition->childNodes();
+        for (unsigned long i = 0; i < conditionDefinitions->length(); ++i)
+        {
+            Poco::XML::Node *conditionDefinition = conditionDefinitions->item(i);
+            if (conditionDefinition->nodeType() == Poco::XML::Node::ELEMENT_NODE) 
+            {
+                const std::string &conditionType = Poco::XML::fromXMLString(conditionDefinition->nodeName());
+                if (conditionType == NAME_ELEMENT_TAG)
+                {
+                    compileFileNameSearchCondition(conditionDefinition, fileSet.conditions);
+                }
+                else if (conditionType == EXTENSION_ELEMENT_TAG)
+                {
+                    compileExtensionSearchCondition(conditionDefinition, fileSet.conditions);
+                }
+                else
+                {
+                    std::ostringstream msg;
+                    msg << MSG_PREFIX << "unrecognized " << INTERESTING_FILE_SET_ELEMENT_TAG << " child element '" << conditionType << "'"; 
+                    throw TskException(msg.str());
+                }
+            }
+
+        }
+
+        if (!fileSet.conditions.empty())
+        {
+            fileSets.push_back(fileSet);
+        }
+        else
+        {
+            std::ostringstream msg;
+            msg << MSG_PREFIX << "empty " << INTERESTING_FILE_SET_ELEMENT_TAG << " element '" << fileSet.name << "'"; 
+            //throw TskException(msg.str());
+        }
+    }
+}
+
+extern "C" 
+{
+    /**
+     * Module identification function. 
+     *
+     * @return The name of the module.
+     */
+    TSK_MODULE_EXPORT const char *name()
+    {
+        return MODULE_NAME;
+    }
+
+    /**
+     * Module identification function. 
+     *
+     * @return A description of the module.
+     */
+    TSK_MODULE_EXPORT const char *description()
+    {
+        return MODULE_DESCRIPTION;
+    }
+
+    /**
+     * Module identification function. 
+     *
+     * @return The version of the module.
+     */
+    TSK_MODULE_EXPORT const char *version()
+    {
+        return MODULE_VERSION;
+    }
+
+    /**
+     * Module initialization function. The initialization arguments string should
+     * provide the path of a module configuration file that defines what files 
+     * are interesting. If the empty string is passed to this function, the module
+     * assumes a default config file is present in the output directory.
+     *
+     * @param args Path of the configuration file that defines what files are 
+     * interesting, may be set to the empty string.
+     * @return TskModule::OK on success, TskModule::FAIL otherwise. 
+     */
+    TSK_MODULE_EXPORT TskModule::Status initialize(const char* arguments)
+    {
+        TskModule::Status status = TskModule::OK;
+
+        const std::string MSG_PREFIX = "InterestingFilesModule::initialize : ";
+        try
+        {
+            // Make sure the file sets are cleared in case initialize() is called more than once.
+            fileSets.clear();
+
+            configFilePath.assign(arguments);
+            if (configFilePath.empty())
+            {
+                // Use the default config file path.
+                Poco::Path configurationFilePath(Poco::Path::forDirectory(GetSystemProperty(TskSystemProperties::MODULE_CONFIG_DIR)));
+                configurationFilePath.pushDirectory(MODULE_NAME);
+                configurationFilePath.setFileName(DEFAULT_CONFIG_FILE_NAME);
+                configFilePath = configurationFilePath.toString();
+            }
+
+            // Compile the contents of the config file into interesting file set definitions.
+            Poco::File configFile = Poco::File(configFilePath);
+            if (configFile.exists())
+            {
+                std::ifstream configStream(configFile.path().c_str());
+                if (configStream)
+                {
+                    Poco::XML::InputSource inputSource(configStream);
+                    Poco::AutoPtr<Poco::XML::Document> configDoc = Poco::XML::DOMParser().parse(&inputSource);
+                    Poco::AutoPtr<Poco::XML::NodeList> fileSetDefinitions = configDoc->getElementsByTagName(INTERESTING_FILE_SET_ELEMENT_TAG);
+                    for (unsigned long i = 0; i < fileSetDefinitions->length(); ++i) 
+                    {
+                        compileInterestingFilesSet(fileSetDefinitions->item(i));
+                    }
+                }
+                else
+                {
+                    std::ostringstream msg;
+                    msg << MSG_PREFIX << "failed to open config file '" << configFilePath << "'";
+                    throw TskException(msg.str());
+                }
+            }
+            else
+            {
+                std::ostringstream msg;
+                msg << MSG_PREFIX << "config file'" << configFilePath << "' does not exist";
+                LOGERROR(msg.str());
+            }
+
+            // Log the configuration.
+            std::ostringstream msg;
+            msg << MSG_PREFIX << "configured with " << fileSets.size() << " interesting file set definitions from '" << configFilePath << "'";
+            LOGINFO(msg.str());
+        }
+        catch (TskException &ex)
+        {
+            status = TskModule::FAIL;
+            configFilePath.clear();
+            std::ostringstream msg;
+            msg << MSG_PREFIX << "TskException: " << ex.message();
+            LOGERROR(msg.str());
+        }
+        catch (Poco::Exception &ex)
+        {
+            status = TskModule::FAIL;
+            configFilePath.clear();
+            std::ostringstream msg;
+            msg << MSG_PREFIX << "Poco::Exception: " << ex.displayText();
+            LOGERROR(msg.str());
+        }
+        catch (std::exception &ex)
+        {
+            status = TskModule::FAIL;
+            configFilePath.clear();
+            std::ostringstream msg;
+            msg << MSG_PREFIX << "std::exception: " << ex.what();
+            LOGERROR(msg.str());
+        }
+        catch (...)
+        {
+            status = TskModule::FAIL;
+            configFilePath.clear();
+            LOGERROR(MSG_PREFIX + "unrecognized exception");
+        }
+
+        return status;
+    }
+
+    /**
+     * Module execution function. Looks for files matching the criteria specified in the 
+     * configuration file and posts its findings to the blackboard.
+     *
+     * @returns Returns TskModule::FAIL if an error occurs, TskModule::OK otherwise.
+     */
+    TSK_MODULE_EXPORT TskModule::Status report()
+    {
+        TskModule::Status status = TskModule::OK;
+
+        const std::string MSG_PREFIX = "InterestingFilesModule::report : ";
+        try
+        {
+            if (configFilePath.empty())
+            {
+                // Initialization failed. The reason why was already logged in initialize().
+                return TskModule::FAIL;
+            }
+
+            for (std::vector<InterestingFilesSet>::iterator fileSet = fileSets.begin(); fileSet != fileSets.end(); ++fileSet)
+            {
+                for (std::vector<string>::iterator condition = (*fileSet).conditions.begin(); condition != (*fileSet).conditions.end(); ++condition)
+                {
+                    vector<uint64_t> fileIds = TskServices::Instance().getImgDB().getFileIds(*condition);
+                    for (size_t i = 0; i < fileIds.size(); i++)
+                    {
+                        TskBlackboardArtifact artifact = TskServices::Instance().getBlackboard().createArtifact(fileIds[i], TSK_INTERESTING_FILE_HIT);
+                        TskBlackboardAttribute attribute(TSK_SET_NAME, "InterestingFiles", (*fileSet).description, (*fileSet).name);
+                        artifact.addAttribute(attribute);
+                    }
+                }
+            }
+        }
+        catch (TskException &ex)
+        {
+            status = TskModule::FAIL;
+            std::ostringstream msg;
+            msg << MSG_PREFIX << "TskException: " << ex.message();
+            LOGERROR(msg.str());
+        }
+        catch (Poco::Exception &ex)
+        {
+            status = TskModule::FAIL;
+            std::ostringstream msg;
+            msg << MSG_PREFIX << "Poco::Exception: " << ex.displayText();
+            LOGERROR(msg.str());
+        }
+        catch (std::exception &ex)
+        {
+            status = TskModule::FAIL;
+            std::ostringstream msg;
+            msg << MSG_PREFIX << "std::exception: " << ex.what();
+            LOGERROR(msg.str());
+        }
+        catch (...)
+        {
+            status = TskModule::FAIL;
+            LOGERROR(MSG_PREFIX + "unrecognized exception");
+        }
+
+        return status;
+    }
+
+    /**
+     * Module cleanup function. Disposes of file search data created during initialization.
+     *
+     * @returns TskModule::OK
+     */
+    TskModule::Status TSK_MODULE_EXPORT finalize()
+    {
+        TskModule::Status status = TskModule::OK;
+
+        const std::string MSG_PREFIX = "InterestingFilesModule::finalize : ";
+        try
+        {
+            fileSets.clear();
+        }
+        catch (TskException &ex)
+        {
+            status = TskModule::FAIL;
+            configFilePath.clear();
+            std::ostringstream msg;
+            msg << MSG_PREFIX << "TskException: " << ex.message();
+            LOGERROR(msg.str());
+        }
+        catch (Poco::Exception &ex)
+        {
+            status = TskModule::FAIL;
+            configFilePath.clear();
+            std::ostringstream msg;
+            msg << MSG_PREFIX << "Poco::Exception: " << ex.displayText();
+            LOGERROR(msg.str());
+        }
+        catch (std::exception &ex)
+        {
+            status = TskModule::FAIL;
+            configFilePath.clear();
+            std::ostringstream msg;
+            msg << MSG_PREFIX << "std::exception: " << ex.what();
+            LOGERROR(msg.str());
+        }
+        catch (...)
+        {
+            status = TskModule::FAIL;
+            LOGERROR(MSG_PREFIX + "unrecognized exception");
+        }
+
+        return status;
+    }
+}
diff --git a/framework/modules/c_InterestingFilesModule/NEWS.txt b/framework/modules/c_InterestingFilesModule/NEWS.txt
index 6887b66..850e595 100644
--- a/framework/modules/c_InterestingFilesModule/NEWS.txt
+++ b/framework/modules/c_InterestingFilesModule/NEWS.txt
@@ -1,9 +1,9 @@
-Numbers refer to github.net issue #s:
-    https://github.com/sleuthkit/c_InterestingFilesModule/issues
-
----------------- VERSION 1.0.0 --------------
-New Features:
-- Initial public release.
-
-Bug Fixes:
-- N/A. 
+Numbers refer to github.net issue #s:
+    https://github.com/sleuthkit/c_InterestingFilesModule/issues
+
+---------------- VERSION 1.0.0 --------------
+New Features:
+- Initial public release.
+
+Bug Fixes:
+- N/A. 
diff --git a/framework/modules/c_InterestingFilesModule/README.txt b/framework/modules/c_InterestingFilesModule/README.txt
index 548cea4..9201ca2 100644
--- a/framework/modules/c_InterestingFilesModule/README.txt
+++ b/framework/modules/c_InterestingFilesModule/README.txt
@@ -1,109 +1,109 @@
-Interesting Files Module
-Sleuth Kit Framework C++ Module
-May 2012
-
-
-This module is for the C++ Sleuth Kit Framework.
-
-
-DESCRIPTION
-
-This module is a post-processing module that looks for files
-matching criteria specified in a module configuration file. 
-This module is useful for identifying all files of a given
-type (based on extension) or given name or contained in a 
-directory of a given name. 
-
-DEPLOYMENT REQUIREMENTS
-
-This module requires a configuration file (discussed below).
-The location of the configuration file can be passed as an
-argument to the module. 
-If the location is not passed as an argument the module will 
-look for a file named "interesting_files.xml" in a folder named 
-"InterestingFilesModule" located in the modules folder.
-
-USAGE
-
-Add this module to a post-processing/reporting pipeline.  See the TSK 
-Framework documents for information on adding the module 
-to the pipeline:
-
-    http://www.sleuthkit.org/sleuthkit/docs/framework-docs/
-
-The module takes the path to the configuration file as an argument. 
-The configuration file is an XML document that defines interesting
-file sets in terms of search criteria.  Here is a sample: 
-
-<?xml version="1.0" encoding="utf-8"?>
-<INTERESTING_FILES>
-    <INTERESTING_FILE_SET name="HTMLFilesType" description="Files with extension .htm*">
-        <EXTENSION typeFilter="file">.htm*</EXTENSION>
-    </INTERESTING_FILE_SET>
-    <INTERESTING_FILE_SET name="Password" description="Files with password in the name">
-        <NAME typeFilter="file">*password*</NAME>
-    </INTERESTING_FILE_SET>
-    <INTERESTING_FILE_SET name="HTMLFiles" description="Files named file.htm or file.html">
-        <NAME typeFilter="file">file.htm</NAME>
-        <NAME typeFilter="file">file.html</NAME>
-    </INTERESTING_FILE_SET>
-    <INTERESTING_FILE_SET name="TextFiles" description="Files with .txt extensions">
-        <EXTENSION typeFilter="file">.txt</EXTENSION>
-    </INTERESTING_FILE_SET>
-    <INTERESTING_FILE_SET name="JPEGFiles" description="JPEG files">
-        <EXTENSION typeFilter="file">.jpg</EXTENSION>
-        <EXTENSION typeFilter="file">.jpeg</EXTENSION>
-    </INTERESTING_FILE_SET>
-    <INTERESTING_FILE_SET name="SuspiciousFolders" description="Contents of suspicious folders">
-        <NAME typeFilter="dir">/DIR1/</NAME>
-        <NAME typeFilter="dir">/DIR2/</NAME>
-      </INTERESTING_FILE_SET>
-    <INTERESTING_FILE_SET name="SuspiciousDocs" description="Suspicious files">
-        <NAME typeFilter="file">readme.txt</NAME>
-        <NAME typeFilter="file" pathFilter="installer\installs">install.doc</NAME>
-        <EXTENSION>.bak</EXTENSION>
-    </INTERESTING_FILE_SET>
-</INTERESTING_FILES>
-
-Each 'INTERESTING_FILE_SET' element must be given a unique name using its
-'name' attribute.  If this attribute is omitted, the module generates a 
-default name (e.g., Unamed_1, Unamed_2, etc.). 
-
-The 'description' attribute of 'INTERESTING_FILE_SET' element is optional.  
-Its intended use is to describe why the search is important.  It could 
-let the end user know what next step to take if this search is successful.
-
-Each 'INTERESTING_FILE_SET' element may contain any number of 'NAME' and/or 
-'EXTENSION' elements.
-
-A 'NAME' element says search the file names for a file or directory with a 
-name that matches the element text.  The match must be an exact length, 
-case insensitive match.  For example, the string "bomb" will not match "abomb". 
-
-An 'EXTENSION' element says search the end of file names for the element text. 
-If the leading "." is omitted the module will add it. 
-
-Wildcard is supported in both 'NAME' and 'EXTENSION' elements. The asterisk
-character '*' is used to represent a match of zero or more characters.
-
-'NAME' and 'EXTENSION' elements may be qualified with optional 'typeFilter'
-attributes. Valid values for 'typeFilter' are 'file' (for regular files) and 
-'dir' (for directories).  If no 'typeFilter' is specified, directories and
-*any* type of file are valid matches.  For example, in the sample above, the
-search named "SuspiciousFiles" will find files and directories that end in
-".bak", including files and directories named ".bak". 
-
-'NAME' and 'EXTENSION' elements may be qualified with optional 'pathFilter'
-attributes. Matches with this filter must contain the specified string as
-a sub-string of the file or directory path.
-
-
-RESULTS
-
-The result of the lookup is written to the blackboard as an artifact. 
-You can use the SaveInterestingFiles module to save the identified 
-files to a local directory. 
-
-
-
-
+Interesting Files Module
+Sleuth Kit Framework C++ Module
+May 2012
+
+
+This module is for the C++ Sleuth Kit Framework.
+
+
+DESCRIPTION
+
+This module is a post-processing module that looks for files
+matching criteria specified in a module configuration file. 
+This module is useful for identifying all files of a given
+type (based on extension) or given name or contained in a 
+directory of a given name. 
+
+DEPLOYMENT REQUIREMENTS
+
+This module requires a configuration file (discussed below).
+The location of the configuration file can be passed as an
+argument to the module. 
+If the location is not passed as an argument the module will 
+look for a file named "interesting_files.xml" in a folder named 
+"InterestingFilesModule" located in the modules folder.
+
+USAGE
+
+Add this module to a post-processing/reporting pipeline.  See the TSK 
+Framework documents for information on adding the module 
+to the pipeline:
+
+    http://www.sleuthkit.org/sleuthkit/docs/framework-docs/
+
+The module takes the path to the configuration file as an argument. 
+The configuration file is an XML document that defines interesting
+file sets in terms of search criteria.  Here is a sample: 
+
+<?xml version="1.0" encoding="utf-8"?>
+<INTERESTING_FILES>
+    <INTERESTING_FILE_SET name="HTMLFilesType" description="Files with extension .htm*">
+        <EXTENSION typeFilter="file">.htm*</EXTENSION>
+    </INTERESTING_FILE_SET>
+    <INTERESTING_FILE_SET name="Password" description="Files with password in the name">
+        <NAME typeFilter="file">*password*</NAME>
+    </INTERESTING_FILE_SET>
+    <INTERESTING_FILE_SET name="HTMLFiles" description="Files named file.htm or file.html">
+        <NAME typeFilter="file">file.htm</NAME>
+        <NAME typeFilter="file">file.html</NAME>
+    </INTERESTING_FILE_SET>
+    <INTERESTING_FILE_SET name="TextFiles" description="Files with .txt extensions">
+        <EXTENSION typeFilter="file">.txt</EXTENSION>
+    </INTERESTING_FILE_SET>
+    <INTERESTING_FILE_SET name="JPEGFiles" description="JPEG files">
+        <EXTENSION typeFilter="file">.jpg</EXTENSION>
+        <EXTENSION typeFilter="file">.jpeg</EXTENSION>
+    </INTERESTING_FILE_SET>
+    <INTERESTING_FILE_SET name="SuspiciousFolders" description="Contents of suspicious folders">
+        <NAME typeFilter="dir">/DIR1/</NAME>
+        <NAME typeFilter="dir">/DIR2/</NAME>
+      </INTERESTING_FILE_SET>
+    <INTERESTING_FILE_SET name="SuspiciousDocs" description="Suspicious files">
+        <NAME typeFilter="file">readme.txt</NAME>
+        <NAME typeFilter="file" pathFilter="installer\installs">install.doc</NAME>
+        <EXTENSION>.bak</EXTENSION>
+    </INTERESTING_FILE_SET>
+</INTERESTING_FILES>
+
+Each 'INTERESTING_FILE_SET' element must be given a unique name using its
+'name' attribute.  If this attribute is omitted, the module generates a 
+default name (e.g., Unamed_1, Unamed_2, etc.). 
+
+The 'description' attribute of 'INTERESTING_FILE_SET' element is optional.  
+Its intended use is to describe why the search is important.  It could 
+let the end user know what next step to take if this search is successful.
+
+Each 'INTERESTING_FILE_SET' element may contain any number of 'NAME' and/or 
+'EXTENSION' elements.
+
+A 'NAME' element says search the file names for a file or directory with a 
+name that matches the element text.  The match must be an exact length, 
+case insensitive match.  For example, the string "bomb" will not match "abomb". 
+
+An 'EXTENSION' element says search the end of file names for the element text. 
+If the leading "." is omitted the module will add it. 
+
+Wildcard is supported in both 'NAME' and 'EXTENSION' elements. The asterisk
+character '*' is used to represent a match of zero or more characters.
+
+'NAME' and 'EXTENSION' elements may be qualified with optional 'typeFilter'
+attributes. Valid values for 'typeFilter' are 'file' (for regular files) and 
+'dir' (for directories).  If no 'typeFilter' is specified, directories and
+*any* type of file are valid matches.  For example, in the sample above, the
+search named "SuspiciousFiles" will find files and directories that end in
+".bak", including files and directories named ".bak". 
+
+'NAME' and 'EXTENSION' elements may be qualified with optional 'pathFilter'
+attributes. Matches with this filter must contain the specified string as
+a sub-string of the file or directory path.
+
+
+RESULTS
+
+The result of the lookup is written to the blackboard as an artifact. 
+You can use the SaveInterestingFiles module to save the identified 
+files to a local directory. 
+
+
+
+
diff --git a/framework/modules/c_InterestingFilesModule/interesting_files.xml b/framework/modules/c_InterestingFilesModule/interesting_files.xml
index 9f248e8..3f77d57 100644
--- a/framework/modules/c_InterestingFilesModule/interesting_files.xml
+++ b/framework/modules/c_InterestingFilesModule/interesting_files.xml
@@ -1,29 +1,29 @@
-<?xml version="1.0" encoding="utf-8"?>
-<INTERESTING_FILES>
-    <INTERESTING_FILE_SET name="HTMLFilesType" description="Files with extension .htm*">
-        <EXTENSION typeFilter="file">.htm*</EXTENSION>
-    </INTERESTING_FILE_SET>
-    <INTERESTING_FILE_SET name="Password" description="Files with password in the name">
-        <NAME typeFilter="file">*password*</NAME>
-    </INTERESTING_FILE_SET>
-    <INTERESTING_FILE_SET name="HTMLFiles" description="Files named file.htm or file.html">
-        <NAME typeFilter="file">file.htm</NAME>
-        <NAME typeFilter="file">file.html</NAME>
-    </INTERESTING_FILE_SET>
-    <INTERESTING_FILE_SET name="TextFiles" description="Files with .txt extensions">
-        <EXTENSION typeFilter="file">.txt</EXTENSION>
-    </INTERESTING_FILE_SET>
-    <INTERESTING_FILE_SET name="JPEGFiles" description="JPEG files">
-        <EXTENSION typeFilter="file">.jpg</EXTENSION>
-        <EXTENSION typeFilter="file">.jpeg</EXTENSION>
-    </INTERESTING_FILE_SET>
-    <INTERESTING_FILE_SET name="SuspiciousFolders" description="Contents of suspicious folders">
-        <NAME typeFilter="dir">/DIR1/</NAME>
-        <NAME typeFilter="dir">/DIR2/</NAME>
-      </INTERESTING_FILE_SET>
-    <INTERESTING_FILE_SET name="SuspiciousDocs" description="Suspicious files">
-        <NAME typeFilter="file">readme.txt</NAME>
-        <NAME typeFilter="file" pathFilter="installer\installs">install.doc</NAME>
-        <EXTENSION>.bak</EXTENSION>
-    </INTERESTING_FILE_SET>
-</INTERESTING_FILES>
+<?xml version="1.0" encoding="utf-8"?>
+<INTERESTING_FILES>
+    <INTERESTING_FILE_SET name="HTMLFilesType" description="Files with extension .htm*">
+        <EXTENSION typeFilter="file">.htm*</EXTENSION>
+    </INTERESTING_FILE_SET>
+    <INTERESTING_FILE_SET name="Password" description="Files with password in the name">
+        <NAME typeFilter="file">*password*</NAME>
+    </INTERESTING_FILE_SET>
+    <INTERESTING_FILE_SET name="HTMLFiles" description="Files named file.htm or file.html">
+        <NAME typeFilter="file">file.htm</NAME>
+        <NAME typeFilter="file">file.html</NAME>
+    </INTERESTING_FILE_SET>
+    <INTERESTING_FILE_SET name="TextFiles" description="Files with .txt extensions">
+        <EXTENSION typeFilter="file">.txt</EXTENSION>
+    </INTERESTING_FILE_SET>
+    <INTERESTING_FILE_SET name="JPEGFiles" description="JPEG files">
+        <EXTENSION typeFilter="file">.jpg</EXTENSION>
+        <EXTENSION typeFilter="file">.jpeg</EXTENSION>
+    </INTERESTING_FILE_SET>
+    <INTERESTING_FILE_SET name="SuspiciousFolders" description="Contents of suspicious folders">
+        <NAME typeFilter="dir">/DIR1/</NAME>
+        <NAME typeFilter="dir">/DIR2/</NAME>
+      </INTERESTING_FILE_SET>
+    <INTERESTING_FILE_SET name="SuspiciousDocs" description="Suspicious files">
+        <NAME typeFilter="file">readme.txt</NAME>
+        <NAME typeFilter="file" pathFilter="installer\installs">install.doc</NAME>
+        <EXTENSION>.bak</EXTENSION>
+    </INTERESTING_FILE_SET>
+</INTERESTING_FILES>
diff --git a/framework/modules/c_LibExifModule/NEWS.txt b/framework/modules/c_LibExifModule/NEWS.txt
index 02de826..3c71daa 100644
--- a/framework/modules/c_LibExifModule/NEWS.txt
+++ b/framework/modules/c_LibExifModule/NEWS.txt
@@ -1,9 +1,9 @@
-Numbers refer to github.net issue #s:
-    https://github.com/sleuthkit/c_LibExifModule/issues
-
----------------- VERSION 1.0.0 --------------
-New Features:
-- Initial public release.
-
-Bug Fixes:
-- N/A. 
+Numbers refer to github.net issue #s:
+    https://github.com/sleuthkit/c_LibExifModule/issues
+
+---------------- VERSION 1.0.0 --------------
+New Features:
+- Initial public release.
+
+Bug Fixes:
+- N/A. 
diff --git a/framework/modules/c_LibExifModule/libexif-0.6.20/win32/lib_exif/lib_exif.vcproj b/framework/modules/c_LibExifModule/libexif-0.6.20/win32/lib_exif/lib_exif.vcproj
index 2b59b8c..8a12a19 100644
--- a/framework/modules/c_LibExifModule/libexif-0.6.20/win32/lib_exif/lib_exif.vcproj
+++ b/framework/modules/c_LibExifModule/libexif-0.6.20/win32/lib_exif/lib_exif.vcproj
@@ -1,411 +1,411 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="9.00"
-	Name="lib_exif"
-	ProjectGUID="{DB081B8E-C5A3-44FB-BB6C-8803C26A705A}"
-	RootNamespace="lib_exif"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
-			IntermediateDirectory="$(ConfigurationName)"
-			ConfigurationType="4"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories="..\..\"
-				MinimalRebuild="true"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="3"
-				WarningLevel="3"
-				DebugInformationFormat="4"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
-			IntermediateDirectory="$(ConfigurationName)"
-			ConfigurationType="4"
-			CharacterSet="2"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				EnableIntrinsicFunctions="true"
-				AdditionalIncludeDirectories=".;..\..\"
-				PreprocessorDefinitions="GETTEXT_PACKAGE=\"libexif-12\";LOCALEDIR="
-				RuntimeLibrary="2"
-				EnableFunctionLevelLinking="true"
-				WarningLevel="3"
-				DebugInformationFormat="3"
-				ForcedIncludeFiles=""
-				ForcedUsingFiles=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
-			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
-			>
-			<File
-				RelativePath="..\..\libexif\exif-byte-order.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						ForcedIncludeFiles=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-content.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-data.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-entry.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-format.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-ifd.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-loader.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-log.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-mem.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						ForcedIncludeFiles="$(SolutionDir)\lib_exif\config.h"
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\..\libexif\canon\exif-mnote-data-canon.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\fuji\exif-mnote-data-fuji.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\olympus\exif-mnote-data-olympus.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\pentax\exif-mnote-data-pentax.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-mnote-data.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-tag.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-utils.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\canon\mnote-canon-entry.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\canon\mnote-canon-tag.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\fuji\mnote-fuji-entry.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\fuji\mnote-fuji-tag.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\olympus\mnote-olympus-entry.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						ForcedIncludeFiles=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\..\libexif\olympus\mnote-olympus-tag.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\pentax\mnote-pentax-entry.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\pentax\mnote-pentax-tag.c"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl;inc;xsd"
-			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
-			>
-			<File
-				RelativePath="..\..\libexif\_stdint.h"
-				>
-			</File>
-			<File
-				RelativePath=".\config.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-byte-order.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-content.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-data-type.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-data.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-entry.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-format.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-ifd.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-loader.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-log.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-mem.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\canon\exif-mnote-data-canon.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\fuji\exif-mnote-data-fuji.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\olympus\exif-mnote-data-olympus.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\pentax\exif-mnote-data-pentax.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-mnote-data-priv.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-mnote-data.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-system.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-tag.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-utils.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\i18n.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\canon\mnote-canon-entry.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\canon\mnote-canon-tag.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\fuji\mnote-fuji-entry.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\fuji\mnote-fuji-tag.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\olympus\mnote-olympus-entry.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\olympus\mnote-olympus-tag.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\pentax\mnote-pentax-entry.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\pentax\mnote-pentax-tag.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Resource Files"
-			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
-			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
-			>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="lib_exif"
+	ProjectGUID="{DB081B8E-C5A3-44FB-BB6C-8803C26A705A}"
+	RootNamespace="lib_exif"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="4"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="4"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				AdditionalIncludeDirectories=".;..\..\"
+				PreprocessorDefinitions="GETTEXT_PACKAGE=\"libexif-12\";LOCALEDIR="
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+				ForcedIncludeFiles=""
+				ForcedUsingFiles=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\..\libexif\exif-byte-order.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						ForcedIncludeFiles=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-content.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-data.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-entry.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-format.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-ifd.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-loader.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-log.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-mem.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						ForcedIncludeFiles="$(SolutionDir)\lib_exif\config.h"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\..\libexif\canon\exif-mnote-data-canon.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\fuji\exif-mnote-data-fuji.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\olympus\exif-mnote-data-olympus.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\pentax\exif-mnote-data-pentax.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-mnote-data.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-tag.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-utils.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\canon\mnote-canon-entry.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\canon\mnote-canon-tag.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\fuji\mnote-fuji-entry.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\fuji\mnote-fuji-tag.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\olympus\mnote-olympus-entry.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						ForcedIncludeFiles=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\..\libexif\olympus\mnote-olympus-tag.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\pentax\mnote-pentax-entry.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\pentax\mnote-pentax-tag.c"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath="..\..\libexif\_stdint.h"
+				>
+			</File>
+			<File
+				RelativePath=".\config.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-byte-order.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-content.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-data-type.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-data.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-entry.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-format.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-ifd.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-loader.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-log.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-mem.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\canon\exif-mnote-data-canon.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\fuji\exif-mnote-data-fuji.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\olympus\exif-mnote-data-olympus.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\pentax\exif-mnote-data-pentax.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-mnote-data-priv.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-mnote-data.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-system.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-tag.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-utils.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\i18n.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\canon\mnote-canon-entry.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\canon\mnote-canon-tag.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\fuji\mnote-fuji-entry.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\fuji\mnote-fuji-tag.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\olympus\mnote-olympus-entry.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\olympus\mnote-olympus-tag.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\pentax\mnote-pentax-entry.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\pentax\mnote-pentax-tag.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/framework/modules/c_LibExifModule/libexif-0.6.20/win32/lib_exifVC9.sln b/framework/modules/c_LibExifModule/libexif-0.6.20/win32/lib_exifVC9.sln
index 44fac59..e1d6997 100644
--- a/framework/modules/c_LibExifModule/libexif-0.6.20/win32/lib_exifVC9.sln
+++ b/framework/modules/c_LibExifModule/libexif-0.6.20/win32/lib_exifVC9.sln
@@ -1,20 +1,20 @@
-
-Microsoft Visual Studio Solution File, Format Version 10.00
-# Visual C++ Express 2008
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_exifVC9", "lib_exifVC9\lib_exifVC9.vcproj", "{DB081B8E-C5A3-44FB-BB6C-8803C26A705A}"
-EndProject
-Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Win32 = Debug|Win32
-		Release|Win32 = Release|Win32
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{DB081B8E-C5A3-44FB-BB6C-8803C26A705A}.Debug|Win32.ActiveCfg = Debug|Win32
-		{DB081B8E-C5A3-44FB-BB6C-8803C26A705A}.Debug|Win32.Build.0 = Debug|Win32
-		{DB081B8E-C5A3-44FB-BB6C-8803C26A705A}.Release|Win32.ActiveCfg = Release|Win32
-		{DB081B8E-C5A3-44FB-BB6C-8803C26A705A}.Release|Win32.Build.0 = Release|Win32
-	EndGlobalSection
-	GlobalSection(SolutionProperties) = preSolution
-		HideSolutionNode = FALSE
-	EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual C++ Express 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_exifVC9", "lib_exifVC9\lib_exifVC9.vcproj", "{DB081B8E-C5A3-44FB-BB6C-8803C26A705A}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{DB081B8E-C5A3-44FB-BB6C-8803C26A705A}.Debug|Win32.ActiveCfg = Debug|Win32
+		{DB081B8E-C5A3-44FB-BB6C-8803C26A705A}.Debug|Win32.Build.0 = Debug|Win32
+		{DB081B8E-C5A3-44FB-BB6C-8803C26A705A}.Release|Win32.ActiveCfg = Release|Win32
+		{DB081B8E-C5A3-44FB-BB6C-8803C26A705A}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/framework/modules/c_LibExifModule/libexif-0.6.20/win32/lib_exifVC9/lib_exifVC9.vcproj b/framework/modules/c_LibExifModule/libexif-0.6.20/win32/lib_exifVC9/lib_exifVC9.vcproj
index 10b7e2b..72f1d10 100644
--- a/framework/modules/c_LibExifModule/libexif-0.6.20/win32/lib_exifVC9/lib_exifVC9.vcproj
+++ b/framework/modules/c_LibExifModule/libexif-0.6.20/win32/lib_exifVC9/lib_exifVC9.vcproj
@@ -1,420 +1,420 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-	ProjectType="Visual C++"
-	Version="9.00"
-	Name="lib_exifVC9"
-	ProjectGUID="{DB081B8E-C5A3-44FB-BB6C-8803C26A705A}"
-	RootNamespace="lib_exif"
-	TargetFrameworkVersion="196613"
-	>
-	<Platforms>
-		<Platform
-			Name="Win32"
-		/>
-	</Platforms>
-	<ToolFiles>
-	</ToolFiles>
-	<Configurations>
-		<Configuration
-			Name="Debug|Win32"
-			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
-			IntermediateDirectory="$(ConfigurationName)"
-			ConfigurationType="4"
-			CharacterSet="2"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="0"
-				AdditionalIncludeDirectories="..\..\;$(SolutionDir)\lib_exif"
-				PreprocessorDefinitions="GETTEXT_PACKAGE=\"libexif-12\";LOCALEDIR=;"
-				MinimalRebuild="true"
-				BasicRuntimeChecks="3"
-				RuntimeLibrary="3"
-				WarningLevel="3"
-				DebugInformationFormat="4"
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-		<Configuration
-			Name="Release|Win32"
-			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
-			IntermediateDirectory="$(ConfigurationName)"
-			ConfigurationType="4"
-			CharacterSet="2"
-			WholeProgramOptimization="1"
-			>
-			<Tool
-				Name="VCPreBuildEventTool"
-			/>
-			<Tool
-				Name="VCCustomBuildTool"
-			/>
-			<Tool
-				Name="VCXMLDataGeneratorTool"
-			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
-			<Tool
-				Name="VCMIDLTool"
-			/>
-			<Tool
-				Name="VCCLCompilerTool"
-				Optimization="2"
-				EnableIntrinsicFunctions="true"
-				AdditionalIncludeDirectories="..\..\;$(SolutionDir)\lib_exif"
-				PreprocessorDefinitions="GETTEXT_PACKAGE=\"libexif-12\";LOCALEDIR="
-				RuntimeLibrary="2"
-				EnableFunctionLevelLinking="true"
-				WarningLevel="3"
-				DebugInformationFormat="3"
-				ForcedIncludeFiles=""
-				ForcedUsingFiles=""
-			/>
-			<Tool
-				Name="VCManagedResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCResourceCompilerTool"
-			/>
-			<Tool
-				Name="VCPreLinkEventTool"
-			/>
-			<Tool
-				Name="VCLibrarianTool"
-			/>
-			<Tool
-				Name="VCALinkTool"
-			/>
-			<Tool
-				Name="VCXDCMakeTool"
-			/>
-			<Tool
-				Name="VCBscMakeTool"
-			/>
-			<Tool
-				Name="VCFxCopTool"
-			/>
-			<Tool
-				Name="VCPostBuildEventTool"
-			/>
-		</Configuration>
-	</Configurations>
-	<References>
-	</References>
-	<Files>
-		<Filter
-			Name="Source Files"
-			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
-			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
-			>
-			<File
-				RelativePath="..\..\libexif\exif-byte-order.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						ForcedIncludeFiles=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-content.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-data.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-entry.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-format.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-ifd.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-loader.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-log.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-mem.c"
-				>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						ForcedIncludeFiles="$(SolutionDir)\lib_exif\config.h"
-					/>
-				</FileConfiguration>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						ForcedIncludeFiles="$(SolutionDir)\lib_exif\config.h"
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\..\libexif\canon\exif-mnote-data-canon.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\fuji\exif-mnote-data-fuji.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\olympus\exif-mnote-data-olympus.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\pentax\exif-mnote-data-pentax.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-mnote-data.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-tag.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-utils.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\canon\mnote-canon-entry.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\canon\mnote-canon-tag.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\fuji\mnote-fuji-entry.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\fuji\mnote-fuji-tag.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\olympus\mnote-olympus-entry.c"
-				>
-				<FileConfiguration
-					Name="Release|Win32"
-					>
-					<Tool
-						Name="VCCLCompilerTool"
-						ForcedIncludeFiles=""
-					/>
-				</FileConfiguration>
-			</File>
-			<File
-				RelativePath="..\..\libexif\olympus\mnote-olympus-tag.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\pentax\mnote-pentax-entry.c"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\pentax\mnote-pentax-tag.c"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Header Files"
-			Filter="h;hpp;hxx;hm;inl;inc;xsd"
-			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
-			>
-			<File
-				RelativePath="..\..\libexif\_stdint.h"
-				>
-			</File>
-			<File
-				RelativePath="..\lib_exif\config.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-byte-order.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-content.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-data-type.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-data.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-entry.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-format.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-ifd.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-loader.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-log.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-mem.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\canon\exif-mnote-data-canon.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\fuji\exif-mnote-data-fuji.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\olympus\exif-mnote-data-olympus.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\pentax\exif-mnote-data-pentax.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-mnote-data-priv.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-mnote-data.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-system.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-tag.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif-utils.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\exif.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\i18n.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\canon\mnote-canon-entry.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\canon\mnote-canon-tag.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\fuji\mnote-fuji-entry.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\fuji\mnote-fuji-tag.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\olympus\mnote-olympus-entry.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\olympus\mnote-olympus-tag.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\pentax\mnote-pentax-entry.h"
-				>
-			</File>
-			<File
-				RelativePath="..\..\libexif\pentax\mnote-pentax-tag.h"
-				>
-			</File>
-		</Filter>
-		<Filter
-			Name="Resource Files"
-			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
-			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
-			>
-		</Filter>
-	</Files>
-	<Globals>
-	</Globals>
-</VisualStudioProject>
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="lib_exifVC9"
+	ProjectGUID="{DB081B8E-C5A3-44FB-BB6C-8803C26A705A}"
+	RootNamespace="lib_exif"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="4"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\;$(SolutionDir)\lib_exif"
+				PreprocessorDefinitions="GETTEXT_PACKAGE=\"libexif-12\";LOCALEDIR=;"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				WarningLevel="3"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="4"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				EnableIntrinsicFunctions="true"
+				AdditionalIncludeDirectories="..\..\;$(SolutionDir)\lib_exif"
+				PreprocessorDefinitions="GETTEXT_PACKAGE=\"libexif-12\";LOCALEDIR="
+				RuntimeLibrary="2"
+				EnableFunctionLevelLinking="true"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+				ForcedIncludeFiles=""
+				ForcedUsingFiles=""
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="..\..\libexif\exif-byte-order.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						ForcedIncludeFiles=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-content.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-data.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-entry.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-format.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-ifd.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-loader.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-log.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-mem.c"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						ForcedIncludeFiles="$(SolutionDir)\lib_exif\config.h"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						ForcedIncludeFiles="$(SolutionDir)\lib_exif\config.h"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\..\libexif\canon\exif-mnote-data-canon.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\fuji\exif-mnote-data-fuji.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\olympus\exif-mnote-data-olympus.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\pentax\exif-mnote-data-pentax.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-mnote-data.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-tag.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-utils.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\canon\mnote-canon-entry.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\canon\mnote-canon-tag.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\fuji\mnote-fuji-entry.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\fuji\mnote-fuji-tag.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\olympus\mnote-olympus-entry.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						ForcedIncludeFiles=""
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\..\libexif\olympus\mnote-olympus-tag.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\pentax\mnote-pentax-entry.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\pentax\mnote-pentax-tag.c"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath="..\..\libexif\_stdint.h"
+				>
+			</File>
+			<File
+				RelativePath="..\lib_exif\config.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-byte-order.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-content.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-data-type.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-data.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-entry.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-format.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-ifd.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-loader.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-log.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-mem.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\canon\exif-mnote-data-canon.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\fuji\exif-mnote-data-fuji.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\olympus\exif-mnote-data-olympus.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\pentax\exif-mnote-data-pentax.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-mnote-data-priv.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-mnote-data.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-system.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-tag.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif-utils.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\exif.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\i18n.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\canon\mnote-canon-entry.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\canon\mnote-canon-tag.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\fuji\mnote-fuji-entry.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\fuji\mnote-fuji-tag.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\olympus\mnote-olympus-entry.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\olympus\mnote-olympus-tag.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\pentax\mnote-pentax-entry.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\libexif\pentax\mnote-pentax-tag.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/framework/modules/c_RegRipperModule/NEWS.txt b/framework/modules/c_RegRipperModule/NEWS.txt
index 8f8d365..378e3bc 100644
--- a/framework/modules/c_RegRipperModule/NEWS.txt
+++ b/framework/modules/c_RegRipperModule/NEWS.txt
@@ -1,24 +1,24 @@
-Numbers refer to github.net issue #s:
-    https://github.com/sleuthkit/c_RegRipperModule/issues
-
----------------- VERSION 1.0.2 --------------
-New Features:
-- Added support for using an interpreter command as the exe path argument.
-- Merged master branch and linux-build branch
-- Updated to RegRipper v2.5
-- Output files now have MD5 included in name.
-    
----------------- VERSION 1.0.1 --------------
-New Features:
-- Added ability to search output for a specific string.
-- Added processorarchitecture.pl plugin.
-
-Bug Fixes:
-- N/A. 
-
----------------- VERSION 1.0.0 --------------
-New Features:
-- Initial public release.
-
-Bug Fixes:
-- N/A. 
+Numbers refer to github.net issue #s:
+    https://github.com/sleuthkit/c_RegRipperModule/issues
+
+---------------- VERSION 1.0.2 --------------
+New Features:
+- Added support for using an interpreter command as the exe path argument.
+- Merged master branch and linux-build branch
+- Updated to RegRipper v2.5
+- Output files now have MD5 included in name.
+    
+---------------- VERSION 1.0.1 --------------
+New Features:
+- Added ability to search output for a specific string.
+- Added processorarchitecture.pl plugin.
+
+Bug Fixes:
+- N/A. 
+
+---------------- VERSION 1.0.0 --------------
+New Features:
+- Initial public release.
+
+Bug Fixes:
+- N/A. 
diff --git a/framework/modules/c_RegRipperModule/README.txt b/framework/modules/c_RegRipperModule/README.txt
index 288f553..0278d75 100644
--- a/framework/modules/c_RegRipperModule/README.txt
+++ b/framework/modules/c_RegRipperModule/README.txt
@@ -1,89 +1,89 @@
-Reg Ripper Module
-Sleuth Kit Framework C++ Module
-May 2012
-
-
-This module is for the C++ Sleuth Kit Framework.
-
-
-DESCRIPTION
-
-This module is a report/post-processing module that runs the RegRipper 
-executable against the common set of Windows registry files (i.e., NTUSER, 
-SYSTEM, SAM and SOFTWARE).
-
-This module allows you to extract information from the system's registry.
-
-DEPLOYMENT REQUIREMENTS
-
-This module requires that RegRipper be installed on the system. You can 
-download it from:
-
-    http://regripper.wordpress.com/
-
-
-USAGE
-
-Add this module to a post-processing/reporting pipeline.  See the TSK 
-Framework documents for information on adding the module 
-to the pipeline:
-
-    http://www.sleuthkit.org/sleuthkit/docs/framework-docs/
-
-
-This module takes optional configuration arguments in a semi-colon separated 
-list of arguments:
-
-	-e Path to the RegRipper executable
-	-o Path to directory in which to place RegRipper output
-
-If the executable path is omitted the module will look for RegRipper/rip.exe
-in the program directory. If the executable is not found there, it will try
-to find it using the system PATH environment variable.
-
-If the output directory path is omitted, the module will store the results in
-a "RegRipper" directory in the module output directory specified in the framework 
-system properties.   
-
-This module currently pulls out operating system information and posts it to
-the blackboard. The OS name and version will be available with the base version
-of RegRipper. If you want to get the processor architecture as well place the 
-included RegRipper plugin (processorarchitecture.pl) in the RegRipper plugins
-directory and update the "system" file in that directory to include
-"processorarchitecture" as it's own line.
-
-
-NON-WINDOWS PLATFORMS
-
-The module executable path argument (`-e`) may point to the RegRipper perl file
-instead of the Windows executable, e.g. `-e /foobar/rrv2.5/rip.pl`.
-
-If necessary, the executable path may include the interpreter command itself,
-e.g. `-e perl /foobar/rrv2.5/rip.pl`.
-
-Requirements:
-
-* Perl is installed.
-* You have downloaded and unzipped:
-    * RegRipper
-    * RegRipper plugins (regripperplugins)
-    * Parse-Win32Registry (http://search.cpan.org/~jmacfarla/Parse-Win32Registry-0.40/)
-    
-The RegRipper script (rip.pl) may need modification to run on your system.
-RegRipper Plugins must be copied to a `plugins` subdirectory relative to where
-rip.pl exists. Parse-Win32Registry must be properly installed for Perl to find
-it. If that is not possible, a workaround is to provide it as an argument to
-Perl, e.g. `perl -p /foo/Parse-Win32Registry-1.0/lib /foobar/rrv2.5/rip.pl`.
-
-
-RESULTS
-
-The RegRipper output will be located in the location as described in the 
-previous section. Currently, the module does not interpret any of the results.
-It simply runs the tool.  It will save the analysis results from each 
-hive to its own text file. Errors from RegRipper will be logged to 
-RegRipperErrors.txt in the output directory.
-
-
-TODO
-- Make the module find RegRipper if is in the module's configuration directory.
+Reg Ripper Module
+Sleuth Kit Framework C++ Module
+May 2012
+
+
+This module is for the C++ Sleuth Kit Framework.
+
+
+DESCRIPTION
+
+This module is a report/post-processing module that runs the RegRipper 
+executable against the common set of Windows registry files (i.e., NTUSER, 
+SYSTEM, SAM and SOFTWARE).
+
+This module allows you to extract information from the system's registry.
+
+DEPLOYMENT REQUIREMENTS
+
+This module requires that RegRipper be installed on the system. You can 
+download it from:
+
+    http://regripper.wordpress.com/
+
+
+USAGE
+
+Add this module to a post-processing/reporting pipeline.  See the TSK 
+Framework documents for information on adding the module 
+to the pipeline:
+
+    http://www.sleuthkit.org/sleuthkit/docs/framework-docs/
+
+
+This module takes optional configuration arguments in a semi-colon separated 
+list of arguments:
+
+	-e Path to the RegRipper executable
+	-o Path to directory in which to place RegRipper output
+
+If the executable path is omitted the module will look for RegRipper/rip.exe
+in the program directory. If the executable is not found there, it will try
+to find it using the system PATH environment variable.
+
+If the output directory path is omitted, the module will store the results in
+a "RegRipper" directory in the module output directory specified in the framework 
+system properties.   
+
+This module currently pulls out operating system information and posts it to
+the blackboard. The OS name and version will be available with the base version
+of RegRipper. If you want to get the processor architecture as well place the 
+included RegRipper plugin (processorarchitecture.pl) in the RegRipper plugins
+directory and update the "system" file in that directory to include
+"processorarchitecture" as it's own line.
+
+
+NON-WINDOWS PLATFORMS
+
+The module executable path argument (`-e`) may point to the RegRipper perl file
+instead of the Windows executable, e.g. `-e /foobar/rrv2.5/rip.pl`.
+
+If necessary, the executable path may include the interpreter command itself,
+e.g. `-e perl /foobar/rrv2.5/rip.pl`.
+
+Requirements:
+
+* Perl is installed.
+* You have downloaded and unzipped:
+    * RegRipper
+    * RegRipper plugins (regripperplugins)
+    * Parse-Win32Registry (http://search.cpan.org/~jmacfarla/Parse-Win32Registry-0.40/)
+    
+The RegRipper script (rip.pl) may need modification to run on your system.
+RegRipper Plugins must be copied to a `plugins` subdirectory relative to where
+rip.pl exists. Parse-Win32Registry must be properly installed for Perl to find
+it. If that is not possible, a workaround is to provide it as an argument to
+Perl, e.g. `perl -p /foo/Parse-Win32Registry-1.0/lib /foobar/rrv2.5/rip.pl`.
+
+
+RESULTS
+
+The RegRipper output will be located in the location as described in the 
+previous section. Currently, the module does not interpret any of the results.
+It simply runs the tool.  It will save the analysis results from each 
+hive to its own text file. Errors from RegRipper will be logged to 
+RegRipperErrors.txt in the output directory.
+
+
+TODO
+- Make the module find RegRipper if is in the module's configuration directory.
diff --git a/framework/modules/c_RegRipperModule/RegRipperModule.cpp b/framework/modules/c_RegRipperModule/RegRipperModule.cpp
index da6cf4b..c8722b8 100644
--- a/framework/modules/c_RegRipperModule/RegRipperModule.cpp
+++ b/framework/modules/c_RegRipperModule/RegRipperModule.cpp
@@ -1,633 +1,633 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2013 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file RegRipperModule.cpp
- * Contains the implementation for the reg ripper reporting module.
- * This module runs the RegRipper executable against the common set of
- * Windows registry files (i.e., NTUSER, SYSTEM, SAM and SOFTWARE).
- */
-
-// TSK Framework includes
-#include "tsk/framework/utilities/TskModuleDev.h"
-
-// Poco includes
-#include "Poco/String.h"
-#include "Poco/StringTokenizer.h"
-#include "Poco/File.h"
-#include "Poco/Process.h"
-#include "Poco/PipeStream.h"
-#include "Poco/FileStream.h"
-#include "Poco/StreamCopier.h"
-#include "Poco/Path.h"
-#include "Poco/RegularExpression.h"
-#include "Poco/Environment.h"
-
-// C/C++ standard library includes
-#include <string>
-#include <sstream>
-#include <cassert>
-
-namespace
-{
-    const char *MODULE_NAME = "RegRipper";
-    const char *MODULE_DESCRIPTION = "Runs the RegRipper executable against the common set of Windows registry files (i.e., NTUSER, SYSTEM, SAM and SOFTWARE)";
-    const char *MODULE_VERSION = "1.0.2";
-    const uint64_t VOLUME_SHADOW_SNAPSHOT_FILE_PARENT_ID = 9223372036854775807;
-
-    std::string ripExePath;
-    std::string outputFolderPath;
-    std::vector<std::string> interpreterArgs;
-    std::string pluginPath;
-    
-    enum RegistryHiveType
-    {
-        NTUSER,
-        SYSTEM,
-        SAM,
-        SOFTWARE
-    };
-
-    /**
-     * Looks for an executable file in the PATH environment variable.
-     * If exeFilename is found, it is also tested to see if it's executable.
-     * @param  exeFilename The filename of an executable file.
-     * @return Path found to the executable if it exists, otherwise an empty string
-     */
-    static const std::string checkExeEnvPath(const std::string & exeFilename)
-    {
-        static const short unsigned int MAX_ENV_LEN = 4096;
-
-        std::string envPaths = Poco::Environment::get("PATH");
-
-        // Don't waste time checking if env var is unreasonably large
-        if (envPaths.length() < MAX_ENV_LEN)
-        {
-            Poco::Path p;
-            if (Poco::Path::find(envPaths, exeFilename, p))
-            {
-                std::string newExePath = p.toString();
-
-                // Check if executable mode is set
-                Poco::File exeFile(newExePath);
-                if (exeFile.canExecute())
-                {
-                    return newExePath;
-                }
-            }
-        }
-        return std::string();
-    }
-
-    /**
-     * Parse RegRipper output from a specific output file for matches on the valueName. The 
-     * function will return all lines in the file that match the valueName followed by one 
-     * of the potential RegRipper separators. This may not always find all lines if a plugin
-     * writer uses a new separator.
-     * @param regRipperFileName The full path to a regRipper output file.
-     * @param valueName The name of the value to search for. Will support regex matches that
-     * come before a separator.
-     * @return A vector of matching lines from the file.
-     */
-    std::vector<std::string> getRegRipperValues(const std::string& regRipperFileName, const std::string& valueName)
-    {
-        Poco::FileInputStream inStream(regRipperFileName);
-        std::vector<std::string> results;
-
-        std::string line;
-
-        std::stringstream pattern;
-        pattern << valueName << "[\\s\\->=:]+";
-
-        Poco::RegularExpression regex(pattern.str(), 0, true);
-        Poco::RegularExpression::Match match;
-
-        while (std::getline(inStream, line))
-        {
-            int nummatches = regex.match(line, match, 0);
-            if (nummatches > 0)
-            {
-                results.push_back(line.substr(match.offset + match.length, line.size()));
-            }
-        }
-
-        inStream.close();
-        return results;
-    }
-
-    /**
-     * Processes the RegRipper output from a SOFTWARE hive and creates blackboard
-     * entries for operating system details.
-     * @param pFile A pointer to the SOFTWARE file object.
-     * @param fileName The name of the RegRipper output file for the SOFTWARE hive.
-     */
-    void getSoftwareInfo(TskFile * pFile, const std::string& fileName)
-    {
-        std::vector<std::string> names = getRegRipperValues(fileName, "ProductName");
-
-        TskBlackboardArtifact osart = pFile->createArtifact(TSK_OS_INFO);
-        for (size_t i = 0; i < names.size(); i++)
-        {
-            TskBlackboardAttribute attr(TSK_NAME, MODULE_NAME, "", names[i]);
-            osart.addAttribute(attr);
-        }
-
-        vector<std::string> versions = getRegRipperValues(fileName, "CSDVersion");
-        for (size_t i = 0; i < versions.size(); i++)
-        {
-            TskBlackboardAttribute attr(TSK_VERSION, MODULE_NAME, "", versions[i]);
-            osart.addAttribute(attr);
-        }
-    }
-
-    /**
-     * Processes the RegRipper output from a SYSTEM hive and creates blackboard
-     * entries for operating system details.
-     * @param pFile A pointer to the SYSTEM file object.
-     * @param fileName The name of the RegRipper output file for the SYSTEM hive.
-     */
-    void getSystemInfo(TskFile * pFile, const std::string& fileName)
-    {
-        std::vector<std::string> names = getRegRipperValues(fileName, "ProcessorArchitecture");
-        TskBlackboardArtifact osart = pFile->createArtifact(TSK_OS_INFO);
-        for (size_t i = 0; i < names.size(); i++)
-        {
-            if (names[i].compare("AMD64") == 0)
-            {
-                TskBlackboardAttribute attr(TSK_PROCESSOR_ARCHITECTURE, MODULE_NAME, "", "x86-64");
-                osart.addAttribute(attr);
-            }
-            else
-            {
-                TskBlackboardAttribute attr(TSK_PROCESSOR_ARCHITECTURE, MODULE_NAME, "", names[i]);
-                osart.addAttribute(attr);
-            }
-        }
-    }
-
-    void getFileNamesForHiveType(RegistryHiveType type, std::string &hiveFileName, std::string &pluginSetFileName)
-    {
-        std::string funcName(MODULE_NAME + std::string("RegRipperModule::getFileNamesForHiveType"));
-
-        std::string pluginsPath;
-        pluginsPath = Poco::Path(ripExePath).parent().toString();
-        pluginsPath.append("plugins");
-
-        Poco::Path pluginSetFilePath;
-        switch (type)
-        {
-        case NTUSER:
-            hiveFileName = "NTUSER.DAT";
-            if (!Poco::Path::find(pluginsPath, "ntuser-all", pluginSetFilePath) && 
-                !Poco::Path::find(pluginsPath, "ntuser", pluginSetFilePath))
-            {
-                throw TskException("failed to find either ntuser-all or ntuser plugin wrapper file");
-            }
-            break;
-
-        case SYSTEM:
-            hiveFileName = "SYSTEM";
-            if (!Poco::Path::find(pluginsPath, "system-all", pluginSetFilePath) && 
-                !Poco::Path::find(pluginsPath, "system", pluginSetFilePath))
-            {
-                throw TskException("failed to find either system-all or system plugin wrapper file");
-            }
-            break;
-
-        case SOFTWARE:
-            hiveFileName = "SOFTWARE";
-            if (!Poco::Path::find(pluginsPath, "software-all", pluginSetFilePath) &&
-                !Poco::Path::find(pluginsPath, "software", pluginSetFilePath))
-            {
-                throw TskException("failed to find either software-all or software plugin wrapper file");
-            }
-            break;
-
-        case SAM:
-            hiveFileName = "SAM";
-            if (!Poco::Path::find(pluginsPath, "sam-all", pluginSetFilePath) &&
-                !Poco::Path::find(pluginsPath, "sam", pluginSetFilePath))
-            {
-                throw TskException("failed to find either sam-all or sam plugin wrapper file");
-            }
-            break;
-
-        default:
-            std::ostringstream msg;
-            msg << "unexpected RegistryHiveType value " << type << " in " << funcName;
-            assert(false && msg.str().c_str());
-            throw TskException(msg.str());
-        }
-
-        pluginSetFileName = pluginSetFilePath.getFileName();
-    }
-
-    void runRegRipper(RegistryHiveType type)
-    {
-        std::string funcName(MODULE_NAME + std::string("RegRipperModule::runRegRipper"));
-
-        // Get the hive name and plugin set file names.
-        std::string hiveFileName; 
-        std::string pluginSetFileName;
-        getFileNamesForHiveType(type, hiveFileName, pluginSetFileName);
-
-        TskFileManager& fileManager = TskServices::Instance().getFileManager();
-
-        // Get a list corresponding to the files
-        TskFileManager::AutoFilePtrList files(fileManager.findFilesByName(hiveFileName, TSK_FS_META_TYPE_REG));
-
-        // Iterate over the files running RegRipper on each one.
-        for (TskFileManager::FilePtrList::iterator file = files.begin(); file != files.end(); ++file)
-        {
-            // Skip empty files
-            if ((*file)->getSize() == 0)
-            {
-                continue;
-            }
-
-            // Save the file content so that we can run RegRipper against it
-            fileManager.saveFile(*file);
-
-            // Create a file stream for the RegRipper output. 
-            Poco::Path outputFilePath = Poco::Path::forDirectory(outputFolderPath);
-            std::ostringstream fileName;
-            if ((*file)->getParentFileId() == VOLUME_SHADOW_SNAPSHOT_FILE_PARENT_ID)
-            {
-                Poco::Path filePath((*file)->getFullPath());
-                fileName << filePath.directory(0) << "_"; 
-            }
-            fileName << (*file)->getName() << "_" << (*file)->getHash(TskImgDB::MD5) << "_" << (*file)->getId() << ".txt";
-            outputFilePath.setFileName(fileName.str());
-
-            // Log what's happening.
-            std::ostringstream msg;
-            msg << funcName << " : ripping " << (*file)->getName() << " to " << outputFilePath.toString();
-            LOGINFO(msg.str());
-
-            // Run RegRipper.
-            Poco::Process::Args cmdArgs;
-
-            // Insert interpreter arguments, if any
-            for (std::vector<std::string>::iterator it = interpreterArgs.begin(); it != interpreterArgs.end(); ++it) {
-                cmdArgs.push_back(*it);
-            }
-
-            cmdArgs.push_back("-f");
-            cmdArgs.push_back(pluginSetFileName);
-            cmdArgs.push_back("-r");
-            cmdArgs.push_back((*file)->getPath());
-            Poco::Pipe outPipe;
-            Poco::ProcessHandle handle = Poco::Process::launch(ripExePath, cmdArgs, NULL, &outPipe, &outPipe);
-
-            // Capture the RegRipper output.
-            Poco::PipeInputStream istr(outPipe);
-            Poco::FileOutputStream ostr(outputFilePath.toString());
-            while (istr)
-            {
-                Poco::StreamCopier::copyStream(istr, ostr);
-            }
-            ostr.close();
-
-            if (Poco::Process::wait(handle) == 0)
-            {
-                // If Regripper runs without error, parse selected artifacts from the raw output and post them to the blackboard.
-                if (type == SOFTWARE)
-                {
-                    getSoftwareInfo(*file, outputFilePath.toString());
-                }
-                else if (type == SYSTEM)
-                {
-                    getSystemInfo(*file, outputFilePath.toString());
-                }
-            }
-            else
-            {
-                // If RegRipper fails on a particular file, log a warning and move on to the next file.
-                std::stringstream msg;
-                msg << funcName << " : RegRipper returned error code for " << (*file)->getName() << " (file id = " << (*file)->getId() << ")";
-                LOGWARN(msg.str());            
-            }
-        }
-    }
-
-    void parseOption(const std::string &option, std::string &arg)
-    {
-        if (!arg.empty())
-        {
-            std::ostringstream msg;
-            msg << "module command line has multiple " << option << " options";
-            throw TskException(msg.str());                
-        }
-
-        arg = option.substr(3);
-        if (arg.empty())
-        {
-            std::ostringstream msg;
-            msg << "module command line missing argument for " << option << " option";
-            throw TskException(msg.str());                
-        }
-
-        TskUtilities::stripQuotes(arg);
-    }
-
-    void parseModuleCommandLine(const char *arguments)
-    {
-        ripExePath.clear();
-        outputFolderPath.clear();
-
-        Poco::StringTokenizer tokenizer(std::string(arguments), ";");
-        for (Poco::StringTokenizer::Iterator token = tokenizer.begin(); token != tokenizer.end(); ++token)
-        {
-            if ((*token).find("-e") == 0)
-            {
-                parseOption(*token, ripExePath); 
-            }
-            else if ((*token).find("-o") == 0)
-            {
-                parseOption(*token, outputFolderPath); 
-            }
-            else
-            {
-                std::ostringstream msg;
-                msg << "module command line " << *token << " option not recognized";
-                throw TskException(msg.str());                
-            }
-        }
-
-        if (ripExePath.empty())
-        {
-            Poco::Path defaultPath = Poco::Path::forDirectory(GetSystemProperty(TskSystemProperties::PROG_DIR));
-            defaultPath.pushDirectory("RegRipper");
-            defaultPath.setFileName("rip.exe");
-            ripExePath = defaultPath.toString();
-        }
-        else
-        {
-            // Check to see if we have been asked to run RegRipper through 
-            // the perl interpreter. 
-            std::string perl = "perl";
-
-            if (ripExePath.substr(0, perl.size()) == perl)
-            {
-                /* We have been asked to run the perl interpreter format (e.g. "perl /foobar/rip.pl").
-                   Assumptions:
-                   - The last token is the script path
-                   - Any other script arguments are space delimited
-                   - There are no nested quotes
-                */
-                Poco::StringTokenizer tokenizer(ripExePath, " ");
-                if (tokenizer.count() > 1)
-                {
-                    ripExePath = *tokenizer.begin();             // The interpreter exe path
-                    std::string ripdotplPath = tokenizer[tokenizer.count()-1]; // RegRipper script path
-
-                    // Our plugin path will be relative to where rip.pl lives
-                    pluginPath = Poco::Path(ripdotplPath).parent().toString();
-
-                    // Get interpreter arguments, if any
-                    Poco::StringTokenizer::Iterator it = tokenizer.begin();
-                    interpreterArgs = std::vector<std::string>(++it, tokenizer.end());
-                }
-
-            }
-            else
-            {
-                // Not perl so the plugin path is relative to the RegRipper executable
-                pluginPath = Poco::Path(ripExePath).parent().toString();
-            }
-        }
-
-        if (outputFolderPath.empty())
-        {
-            std::string moduleOutDir = GetSystemProperty(TskSystemProperties::MODULE_OUT_DIR);
-            if (moduleOutDir.empty())
-            {
-                throw TskException("output folder not specified in module command line and MODULE_OUT_DIR is system property not set");
-            }
-
-            Poco::Path defaultPath(Poco::Path::forDirectory(moduleOutDir));
-            defaultPath.pushDirectory(MODULE_NAME);
-            outputFolderPath = defaultPath.toString();
-        }
-    }
-}
-
-extern "C" 
-{
-    /**
-     * Module identification function. 
-     *
-     * @return The name of the module.
-     */
-    TSK_MODULE_EXPORT const char *name()
-    {
-        return MODULE_NAME;
-    }
-
-    /**
-     * Module identification function. 
-     *
-     * @return A description of the module.
-     */
-    TSK_MODULE_EXPORT const char *description()
-    {
-        return MODULE_DESCRIPTION;
-    }
-
-    /**
-     * Module identification function. 
-     *
-     * @return The version of the module.
-     */
-    TSK_MODULE_EXPORT const char *version()
-    {
-        return MODULE_VERSION;
-    }
-
-    /**
-     * Module initialization function. Receives a string of intialization arguments, 
-     * typically read by the caller from a pipeline configuration file. 
-     * Returns TskModule::OK or TskModule::FAIL. Returning TskModule::FAIL indicates 
-     * the module is not in an operational state.  
-     *
-     * @param args An optional semicolon separated list of arguments:
-     *      -e Path to the RegRipper executable
-     *      -o Directory in which to place RegRipper output
-     * @return TskModule::OK if initialization succeeded, otherwise TskModule::FAIL.
-     */
-    TskModule::Status TSK_MODULE_EXPORT initialize(const char* arguments)
-    {
-		const std::string funcName(MODULE_NAME + std::string("::initialize"));
-        try
-        {
-            parseModuleCommandLine(arguments);
-
-            // Log the configuration of the module.
-            std::ostringstream msg;
-            msg << funcName << " : using RegRipper executable '" << ripExePath << "'";
-            LOGINFO(msg.str());
-
-            msg.str("");
-            msg.clear();
-            msg << funcName << " : writing output to '" + outputFolderPath << "'";
-            LOGINFO(msg.str());
-
-            // Verify the RegRipper executable path.
-            Poco::File ripExe(ripExePath);
-            if (!ripExe.exists() || !ripExe.canExecute())
-            {
-                // Try to find it in a dir in the path environment variable
-                std::string newpath = checkExeEnvPath(ripExePath);
-
-                if (!newpath.empty())
-                {
-                    ripExePath = newpath;
-                }
-                else
-                {
-                    std::ostringstream msg;
-                    msg << "'" << ripExePath << "' does not exist or is not executable";
-                    throw TskException(msg.str());
-                }
-            }
-
-            // Create the output folder.
-            Poco::File(outputFolderPath).createDirectories();
-
-            return TskModule::OK;
-        }
-        catch (TskException &ex)
-        {
-            std::ostringstream msg;
-            msg << funcName << ": TskException : " << ex.message();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        catch (Poco::Exception &ex)
-        {
-            std::ostringstream msg;
-            msg << funcName << ": Poco::Exception : " << ex.displayText();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        catch (std::exception &ex)
-        {
-            std::ostringstream msg;
-            msg << funcName << ": std::exception : " << ex.what();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        catch (...)
-        {
-            LOGERROR(funcName + ": unrecognized exception");
-            return TskModule::FAIL;
-        }
-    }
-
-    /**
-     * Module execution function. Returns TskModule::OK, TskModule::FAIL, or TskModule::STOP. 
-     * Returning TskModule::FAIL indicates error performing its job. Returning TskModule::STOP
-     * is a request to terminate execution of the reporting pipeline.
-     *
-     * @returns TskModule::OK on success, TskModule::FAIL on error, or TskModule::STOP.
-     */
-    TskModule::Status TSK_MODULE_EXPORT report()
-    {
-        std::string funcName(MODULE_NAME + std::string("report"));
-        try
-        {
-            runRegRipper(NTUSER);
-            runRegRipper(SYSTEM);
-            runRegRipper(SAM);
-            runRegRipper(SOFTWARE);
-
-            return TskModule::OK;
-        }
-        catch (TskException &ex)
-        {
-            std::ostringstream msg;
-            msg << funcName << ": TskException : " << ex.message();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        catch (Poco::Exception &ex)
-        {
-            std::ostringstream msg;
-            msg << funcName << ": Poco::Exception : " << ex.displayText();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        catch (std::exception &ex)
-        {
-            std::ostringstream msg;
-            msg << funcName << ": std::exception : " << ex.what();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        catch (...)
-        {
-            LOGERROR(funcName + ": unrecognized exception");
-            return TskModule::FAIL;
-        }
-    }
-
-    /**
-     * Module cleanup function. Deletes output directory if it is empty.
-     *
-     * @returns TskModule::OK on success and TskModule::FAIL on error.
-     */
-    TskModule::Status TSK_MODULE_EXPORT finalize()
-    {
-        std::string funcName(MODULE_NAME + std::string("report"));
-        try
-        {
-#if !defined(_DEBUG) 
-
-            Poco::File folder(outputFolderPath);
-            std::vector<std::string> files;
-            folder.list(files);
-
-            if (files.empty())
-            {
-                folder.remove(false);
-            }
-
-#endif
-
-            return TskModule::OK;
-        }
-        catch (TskException &ex)
-        {
-            std::ostringstream msg;
-            msg << funcName << ": TskException : " << ex.message();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        catch (Poco::Exception &ex)
-        {
-            std::ostringstream msg;
-            msg << funcName << ": Poco::Exception : " << ex.displayText();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        catch (std::exception &ex)
-        {
-            std::ostringstream msg;
-            msg << funcName << ": std::exception : " << ex.what();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        catch (...)
-        {
-            LOGERROR(funcName + ": unrecognized exception");
-            return TskModule::FAIL;
-        }
-    }
- }
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2013 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file RegRipperModule.cpp
+ * Contains the implementation for the reg ripper reporting module.
+ * This module runs the RegRipper executable against the common set of
+ * Windows registry files (i.e., NTUSER, SYSTEM, SAM and SOFTWARE).
+ */
+
+// TSK Framework includes
+#include "tsk/framework/utilities/TskModuleDev.h"
+
+// Poco includes
+#include "Poco/String.h"
+#include "Poco/StringTokenizer.h"
+#include "Poco/File.h"
+#include "Poco/Process.h"
+#include "Poco/PipeStream.h"
+#include "Poco/FileStream.h"
+#include "Poco/StreamCopier.h"
+#include "Poco/Path.h"
+#include "Poco/RegularExpression.h"
+#include "Poco/Environment.h"
+
+// C/C++ standard library includes
+#include <string>
+#include <sstream>
+#include <cassert>
+
+namespace
+{
+    const char *MODULE_NAME = "RegRipper";
+    const char *MODULE_DESCRIPTION = "Runs the RegRipper executable against the common set of Windows registry files (i.e., NTUSER, SYSTEM, SAM and SOFTWARE)";
+    const char *MODULE_VERSION = "1.0.2";
+    const uint64_t VOLUME_SHADOW_SNAPSHOT_FILE_PARENT_ID = 9223372036854775807;
+
+    std::string ripExePath;
+    std::string outputFolderPath;
+    std::vector<std::string> interpreterArgs;
+    std::string pluginPath;
+    
+    enum RegistryHiveType
+    {
+        NTUSER,
+        SYSTEM,
+        SAM,
+        SOFTWARE
+    };
+
+    /**
+     * Looks for an executable file in the PATH environment variable.
+     * If exeFilename is found, it is also tested to see if it's executable.
+     * @param  exeFilename The filename of an executable file.
+     * @return Path found to the executable if it exists, otherwise an empty string
+     */
+    static const std::string checkExeEnvPath(const std::string & exeFilename)
+    {
+        static const short unsigned int MAX_ENV_LEN = 4096;
+
+        std::string envPaths = Poco::Environment::get("PATH");
+
+        // Don't waste time checking if env var is unreasonably large
+        if (envPaths.length() < MAX_ENV_LEN)
+        {
+            Poco::Path p;
+            if (Poco::Path::find(envPaths, exeFilename, p))
+            {
+                std::string newExePath = p.toString();
+
+                // Check if executable mode is set
+                Poco::File exeFile(newExePath);
+                if (exeFile.canExecute())
+                {
+                    return newExePath;
+                }
+            }
+        }
+        return std::string();
+    }
+
+    /**
+     * Parse RegRipper output from a specific output file for matches on the valueName. The 
+     * function will return all lines in the file that match the valueName followed by one 
+     * of the potential RegRipper separators. This may not always find all lines if a plugin
+     * writer uses a new separator.
+     * @param regRipperFileName The full path to a regRipper output file.
+     * @param valueName The name of the value to search for. Will support regex matches that
+     * come before a separator.
+     * @return A vector of matching lines from the file.
+     */
+    std::vector<std::string> getRegRipperValues(const std::string& regRipperFileName, const std::string& valueName)
+    {
+        Poco::FileInputStream inStream(regRipperFileName);
+        std::vector<std::string> results;
+
+        std::string line;
+
+        std::stringstream pattern;
+        pattern << valueName << "[\\s\\->=:]+";
+
+        Poco::RegularExpression regex(pattern.str(), 0, true);
+        Poco::RegularExpression::Match match;
+
+        while (std::getline(inStream, line))
+        {
+            int nummatches = regex.match(line, match, 0);
+            if (nummatches > 0)
+            {
+                results.push_back(line.substr(match.offset + match.length, line.size()));
+            }
+        }
+
+        inStream.close();
+        return results;
+    }
+
+    /**
+     * Processes the RegRipper output from a SOFTWARE hive and creates blackboard
+     * entries for operating system details.
+     * @param pFile A pointer to the SOFTWARE file object.
+     * @param fileName The name of the RegRipper output file for the SOFTWARE hive.
+     */
+    void getSoftwareInfo(TskFile * pFile, const std::string& fileName)
+    {
+        std::vector<std::string> names = getRegRipperValues(fileName, "ProductName");
+
+        TskBlackboardArtifact osart = pFile->createArtifact(TSK_OS_INFO);
+        for (size_t i = 0; i < names.size(); i++)
+        {
+            TskBlackboardAttribute attr(TSK_NAME, MODULE_NAME, "", names[i]);
+            osart.addAttribute(attr);
+        }
+
+        vector<std::string> versions = getRegRipperValues(fileName, "CSDVersion");
+        for (size_t i = 0; i < versions.size(); i++)
+        {
+            TskBlackboardAttribute attr(TSK_VERSION, MODULE_NAME, "", versions[i]);
+            osart.addAttribute(attr);
+        }
+    }
+
+    /**
+     * Processes the RegRipper output from a SYSTEM hive and creates blackboard
+     * entries for operating system details.
+     * @param pFile A pointer to the SYSTEM file object.
+     * @param fileName The name of the RegRipper output file for the SYSTEM hive.
+     */
+    void getSystemInfo(TskFile * pFile, const std::string& fileName)
+    {
+        std::vector<std::string> names = getRegRipperValues(fileName, "ProcessorArchitecture");
+        TskBlackboardArtifact osart = pFile->createArtifact(TSK_OS_INFO);
+        for (size_t i = 0; i < names.size(); i++)
+        {
+            if (names[i].compare("AMD64") == 0)
+            {
+                TskBlackboardAttribute attr(TSK_PROCESSOR_ARCHITECTURE, MODULE_NAME, "", "x86-64");
+                osart.addAttribute(attr);
+            }
+            else
+            {
+                TskBlackboardAttribute attr(TSK_PROCESSOR_ARCHITECTURE, MODULE_NAME, "", names[i]);
+                osart.addAttribute(attr);
+            }
+        }
+    }
+
+    void getFileNamesForHiveType(RegistryHiveType type, std::string &hiveFileName, std::string &pluginSetFileName)
+    {
+        std::string funcName(MODULE_NAME + std::string("RegRipperModule::getFileNamesForHiveType"));
+
+        std::string pluginsPath;
+        pluginsPath = Poco::Path(ripExePath).parent().toString();
+        pluginsPath.append("plugins");
+
+        Poco::Path pluginSetFilePath;
+        switch (type)
+        {
+        case NTUSER:
+            hiveFileName = "NTUSER.DAT";
+            if (!Poco::Path::find(pluginsPath, "ntuser-all", pluginSetFilePath) && 
+                !Poco::Path::find(pluginsPath, "ntuser", pluginSetFilePath))
+            {
+                throw TskException("failed to find either ntuser-all or ntuser plugin wrapper file");
+            }
+            break;
+
+        case SYSTEM:
+            hiveFileName = "SYSTEM";
+            if (!Poco::Path::find(pluginsPath, "system-all", pluginSetFilePath) && 
+                !Poco::Path::find(pluginsPath, "system", pluginSetFilePath))
+            {
+                throw TskException("failed to find either system-all or system plugin wrapper file");
+            }
+            break;
+
+        case SOFTWARE:
+            hiveFileName = "SOFTWARE";
+            if (!Poco::Path::find(pluginsPath, "software-all", pluginSetFilePath) &&
+                !Poco::Path::find(pluginsPath, "software", pluginSetFilePath))
+            {
+                throw TskException("failed to find either software-all or software plugin wrapper file");
+            }
+            break;
+
+        case SAM:
+            hiveFileName = "SAM";
+            if (!Poco::Path::find(pluginsPath, "sam-all", pluginSetFilePath) &&
+                !Poco::Path::find(pluginsPath, "sam", pluginSetFilePath))
+            {
+                throw TskException("failed to find either sam-all or sam plugin wrapper file");
+            }
+            break;
+
+        default:
+            std::ostringstream msg;
+            msg << "unexpected RegistryHiveType value " << type << " in " << funcName;
+            assert(false && msg.str().c_str());
+            throw TskException(msg.str());
+        }
+
+        pluginSetFileName = pluginSetFilePath.getFileName();
+    }
+
+    void runRegRipper(RegistryHiveType type)
+    {
+        std::string funcName(MODULE_NAME + std::string("RegRipperModule::runRegRipper"));
+
+        // Get the hive name and plugin set file names.
+        std::string hiveFileName; 
+        std::string pluginSetFileName;
+        getFileNamesForHiveType(type, hiveFileName, pluginSetFileName);
+
+        TskFileManager& fileManager = TskServices::Instance().getFileManager();
+
+        // Get a list corresponding to the files
+        TskFileManager::AutoFilePtrList files(fileManager.findFilesByName(hiveFileName, TSK_FS_META_TYPE_REG));
+
+        // Iterate over the files running RegRipper on each one.
+        for (TskFileManager::FilePtrList::iterator file = files.begin(); file != files.end(); ++file)
+        {
+            // Skip empty files
+            if ((*file)->getSize() == 0)
+            {
+                continue;
+            }
+
+            // Save the file content so that we can run RegRipper against it
+            fileManager.saveFile(*file);
+
+            // Create a file stream for the RegRipper output. 
+            Poco::Path outputFilePath = Poco::Path::forDirectory(outputFolderPath);
+            std::ostringstream fileName;
+            if ((*file)->getParentFileId() == VOLUME_SHADOW_SNAPSHOT_FILE_PARENT_ID)
+            {
+                Poco::Path filePath((*file)->getFullPath());
+                fileName << filePath.directory(0) << "_"; 
+            }
+            fileName << (*file)->getName() << "_" << (*file)->getHash(TskImgDB::MD5) << "_" << (*file)->getId() << ".txt";
+            outputFilePath.setFileName(fileName.str());
+
+            // Log what's happening.
+            std::ostringstream msg;
+            msg << funcName << " : ripping " << (*file)->getName() << " to " << outputFilePath.toString();
+            LOGINFO(msg.str());
+
+            // Run RegRipper.
+            Poco::Process::Args cmdArgs;
+
+            // Insert interpreter arguments, if any
+            for (std::vector<std::string>::iterator it = interpreterArgs.begin(); it != interpreterArgs.end(); ++it) {
+                cmdArgs.push_back(*it);
+            }
+
+            cmdArgs.push_back("-f");
+            cmdArgs.push_back(pluginSetFileName);
+            cmdArgs.push_back("-r");
+            cmdArgs.push_back((*file)->getPath());
+            Poco::Pipe outPipe;
+            Poco::ProcessHandle handle = Poco::Process::launch(ripExePath, cmdArgs, NULL, &outPipe, &outPipe);
+
+            // Capture the RegRipper output.
+            Poco::PipeInputStream istr(outPipe);
+            Poco::FileOutputStream ostr(outputFilePath.toString());
+            while (istr)
+            {
+                Poco::StreamCopier::copyStream(istr, ostr);
+            }
+            ostr.close();
+
+            if (Poco::Process::wait(handle) == 0)
+            {
+                // If Regripper runs without error, parse selected artifacts from the raw output and post them to the blackboard.
+                if (type == SOFTWARE)
+                {
+                    getSoftwareInfo(*file, outputFilePath.toString());
+                }
+                else if (type == SYSTEM)
+                {
+                    getSystemInfo(*file, outputFilePath.toString());
+                }
+            }
+            else
+            {
+                // If RegRipper fails on a particular file, log a warning and move on to the next file.
+                std::stringstream msg;
+                msg << funcName << " : RegRipper returned error code for " << (*file)->getName() << " (file id = " << (*file)->getId() << ")";
+                LOGWARN(msg.str());            
+            }
+        }
+    }
+
+    void parseOption(const std::string &option, std::string &arg)
+    {
+        if (!arg.empty())
+        {
+            std::ostringstream msg;
+            msg << "module command line has multiple " << option << " options";
+            throw TskException(msg.str());                
+        }
+
+        arg = option.substr(3);
+        if (arg.empty())
+        {
+            std::ostringstream msg;
+            msg << "module command line missing argument for " << option << " option";
+            throw TskException(msg.str());                
+        }
+
+        TskUtilities::stripQuotes(arg);
+    }
+
+    void parseModuleCommandLine(const char *arguments)
+    {
+        ripExePath.clear();
+        outputFolderPath.clear();
+
+        Poco::StringTokenizer tokenizer(std::string(arguments), ";");
+        for (Poco::StringTokenizer::Iterator token = tokenizer.begin(); token != tokenizer.end(); ++token)
+        {
+            if ((*token).find("-e") == 0)
+            {
+                parseOption(*token, ripExePath); 
+            }
+            else if ((*token).find("-o") == 0)
+            {
+                parseOption(*token, outputFolderPath); 
+            }
+            else
+            {
+                std::ostringstream msg;
+                msg << "module command line " << *token << " option not recognized";
+                throw TskException(msg.str());                
+            }
+        }
+
+        if (ripExePath.empty())
+        {
+            Poco::Path defaultPath = Poco::Path::forDirectory(GetSystemProperty(TskSystemProperties::PROG_DIR));
+            defaultPath.pushDirectory("RegRipper");
+            defaultPath.setFileName("rip.exe");
+            ripExePath = defaultPath.toString();
+        }
+        else
+        {
+            // Check to see if we have been asked to run RegRipper through 
+            // the perl interpreter. 
+            std::string perl = "perl";
+
+            if (ripExePath.substr(0, perl.size()) == perl)
+            {
+                /* We have been asked to run the perl interpreter format (e.g. "perl /foobar/rip.pl").
+                   Assumptions:
+                   - The last token is the script path
+                   - Any other script arguments are space delimited
+                   - There are no nested quotes
+                */
+                Poco::StringTokenizer tokenizer(ripExePath, " ");
+                if (tokenizer.count() > 1)
+                {
+                    ripExePath = *tokenizer.begin();             // The interpreter exe path
+                    std::string ripdotplPath = tokenizer[tokenizer.count()-1]; // RegRipper script path
+
+                    // Our plugin path will be relative to where rip.pl lives
+                    pluginPath = Poco::Path(ripdotplPath).parent().toString();
+
+                    // Get interpreter arguments, if any
+                    Poco::StringTokenizer::Iterator it = tokenizer.begin();
+                    interpreterArgs = std::vector<std::string>(++it, tokenizer.end());
+                }
+
+            }
+            else
+            {
+                // Not perl so the plugin path is relative to the RegRipper executable
+                pluginPath = Poco::Path(ripExePath).parent().toString();
+            }
+        }
+
+        if (outputFolderPath.empty())
+        {
+            std::string moduleOutDir = GetSystemProperty(TskSystemProperties::MODULE_OUT_DIR);
+            if (moduleOutDir.empty())
+            {
+                throw TskException("output folder not specified in module command line and MODULE_OUT_DIR is system property not set");
+            }
+
+            Poco::Path defaultPath(Poco::Path::forDirectory(moduleOutDir));
+            defaultPath.pushDirectory(MODULE_NAME);
+            outputFolderPath = defaultPath.toString();
+        }
+    }
+}
+
+extern "C" 
+{
+    /**
+     * Module identification function. 
+     *
+     * @return The name of the module.
+     */
+    TSK_MODULE_EXPORT const char *name()
+    {
+        return MODULE_NAME;
+    }
+
+    /**
+     * Module identification function. 
+     *
+     * @return A description of the module.
+     */
+    TSK_MODULE_EXPORT const char *description()
+    {
+        return MODULE_DESCRIPTION;
+    }
+
+    /**
+     * Module identification function. 
+     *
+     * @return The version of the module.
+     */
+    TSK_MODULE_EXPORT const char *version()
+    {
+        return MODULE_VERSION;
+    }
+
+    /**
+     * Module initialization function. Receives a string of intialization arguments, 
+     * typically read by the caller from a pipeline configuration file. 
+     * Returns TskModule::OK or TskModule::FAIL. Returning TskModule::FAIL indicates 
+     * the module is not in an operational state.  
+     *
+     * @param args An optional semicolon separated list of arguments:
+     *      -e Path to the RegRipper executable
+     *      -o Directory in which to place RegRipper output
+     * @return TskModule::OK if initialization succeeded, otherwise TskModule::FAIL.
+     */
+    TskModule::Status TSK_MODULE_EXPORT initialize(const char* arguments)
+    {
+		const std::string funcName(MODULE_NAME + std::string("::initialize"));
+        try
+        {
+            parseModuleCommandLine(arguments);
+
+            // Log the configuration of the module.
+            std::ostringstream msg;
+            msg << funcName << " : using RegRipper executable '" << ripExePath << "'";
+            LOGINFO(msg.str());
+
+            msg.str("");
+            msg.clear();
+            msg << funcName << " : writing output to '" + outputFolderPath << "'";
+            LOGINFO(msg.str());
+
+            // Verify the RegRipper executable path.
+            Poco::File ripExe(ripExePath);
+            if (!ripExe.exists() || !ripExe.canExecute())
+            {
+                // Try to find it in a dir in the path environment variable
+                std::string newpath = checkExeEnvPath(ripExePath);
+
+                if (!newpath.empty())
+                {
+                    ripExePath = newpath;
+                }
+                else
+                {
+                    std::ostringstream msg;
+                    msg << "'" << ripExePath << "' does not exist or is not executable";
+                    throw TskException(msg.str());
+                }
+            }
+
+            // Create the output folder.
+            Poco::File(outputFolderPath).createDirectories();
+
+            return TskModule::OK;
+        }
+        catch (TskException &ex)
+        {
+            std::ostringstream msg;
+            msg << funcName << ": TskException : " << ex.message();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        catch (Poco::Exception &ex)
+        {
+            std::ostringstream msg;
+            msg << funcName << ": Poco::Exception : " << ex.displayText();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        catch (std::exception &ex)
+        {
+            std::ostringstream msg;
+            msg << funcName << ": std::exception : " << ex.what();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        catch (...)
+        {
+            LOGERROR(funcName + ": unrecognized exception");
+            return TskModule::FAIL;
+        }
+    }
+
+    /**
+     * Module execution function. Returns TskModule::OK, TskModule::FAIL, or TskModule::STOP. 
+     * Returning TskModule::FAIL indicates error performing its job. Returning TskModule::STOP
+     * is a request to terminate execution of the reporting pipeline.
+     *
+     * @returns TskModule::OK on success, TskModule::FAIL on error, or TskModule::STOP.
+     */
+    TskModule::Status TSK_MODULE_EXPORT report()
+    {
+        std::string funcName(MODULE_NAME + std::string("report"));
+        try
+        {
+            runRegRipper(NTUSER);
+            runRegRipper(SYSTEM);
+            runRegRipper(SAM);
+            runRegRipper(SOFTWARE);
+
+            return TskModule::OK;
+        }
+        catch (TskException &ex)
+        {
+            std::ostringstream msg;
+            msg << funcName << ": TskException : " << ex.message();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        catch (Poco::Exception &ex)
+        {
+            std::ostringstream msg;
+            msg << funcName << ": Poco::Exception : " << ex.displayText();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        catch (std::exception &ex)
+        {
+            std::ostringstream msg;
+            msg << funcName << ": std::exception : " << ex.what();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        catch (...)
+        {
+            LOGERROR(funcName + ": unrecognized exception");
+            return TskModule::FAIL;
+        }
+    }
+
+    /**
+     * Module cleanup function. Deletes output directory if it is empty.
+     *
+     * @returns TskModule::OK on success and TskModule::FAIL on error.
+     */
+    TskModule::Status TSK_MODULE_EXPORT finalize()
+    {
+        std::string funcName(MODULE_NAME + std::string("report"));
+        try
+        {
+#if !defined(_DEBUG) 
+
+            Poco::File folder(outputFolderPath);
+            std::vector<std::string> files;
+            folder.list(files);
+
+            if (files.empty())
+            {
+                folder.remove(false);
+            }
+
+#endif
+
+            return TskModule::OK;
+        }
+        catch (TskException &ex)
+        {
+            std::ostringstream msg;
+            msg << funcName << ": TskException : " << ex.message();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        catch (Poco::Exception &ex)
+        {
+            std::ostringstream msg;
+            msg << funcName << ": Poco::Exception : " << ex.displayText();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        catch (std::exception &ex)
+        {
+            std::ostringstream msg;
+            msg << funcName << ": std::exception : " << ex.what();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        catch (...)
+        {
+            LOGERROR(funcName + ": unrecognized exception");
+            return TskModule::FAIL;
+        }
+    }
+ }
diff --git a/framework/modules/c_SaveInterestingFilesModule/NEWS.txt b/framework/modules/c_SaveInterestingFilesModule/NEWS.txt
index e5691ea..ef2bab6 100644
--- a/framework/modules/c_SaveInterestingFilesModule/NEWS.txt
+++ b/framework/modules/c_SaveInterestingFilesModule/NEWS.txt
@@ -1,9 +1,9 @@
-Numbers refer to github.net issue #s:
-    https://github.com/sleuthkit/c_SaveInterestingFilesModule/issues
-
----------------- VERSION 1.0.0 --------------
-New Features:
-- Initial public release.
-
-Bug Fixes:
-- N/A. 
+Numbers refer to github.net issue #s:
+    https://github.com/sleuthkit/c_SaveInterestingFilesModule/issues
+
+---------------- VERSION 1.0.0 --------------
+New Features:
+- Initial public release.
+
+Bug Fixes:
+- N/A. 
diff --git a/framework/modules/c_SaveInterestingFilesModule/README.txt b/framework/modules/c_SaveInterestingFilesModule/README.txt
index 1e3d4fc..d83656a 100644
--- a/framework/modules/c_SaveInterestingFilesModule/README.txt
+++ b/framework/modules/c_SaveInterestingFilesModule/README.txt
@@ -1,71 +1,71 @@
-Save Interesting Files Module
-Sleuth Kit Framework C++ Module
-May 2012
-
-
-This module is for the C++ Sleuth Kit Framework.
-
-
-DESCRIPTION
-
-This module is a post-processing module that saves files and directories
-that were flagged as being interesting by the InterestingFiles module. 
-It is used to extract the suspicious files for further analysis.
-For example, you could use InterestingFiles to flag all files of
-a given type and then use this module to save them to a local
-folder for manual analysis. 
-
-DEPLOYMENT REQUIREMENTS
-
-This module does not have any specific deployment requirements.
-
-USAGE
-
-Add this module to a post-processing pipeline.  See the TSK 
-Framework documents for information on adding the module 
-to the pipeline:
-
-    http://www.sleuthkit.org/sleuthkit/docs/framework-docs/
-
-The module takes the path to a folder where the files should be saved.
-
-
-RESULTS
-
-Interesting files are saved to the output folder in subdirectories bearing
-the name given to the matching interesting files set in the configuration
-file for the Interesting Files module.  File names are augmented with
-their file ids to avoid name collisions. The resulting directory structure
-will night something like this:
-
-        c:\img503\out\Interesting Files\
-            ReadmeFiles\
-                README_1
-                readme_24.txt
-                readme_382.txt
-                ReadmeFiles.xml    
-
-The contents of interesting directories are saved to the output folder in 
-subdirectories bearing the name given to the matching interesting files set 
-in the configuration file for the Interesting Files module.  A subdirectory 
-is created with the same name as the directory, but augmented with the
-directory's file id to avoid name collisions. The contents of the directory,
-including both files and subdirectories, is then saved. The resulting 
-directory structure might look something like this:
-
-        c:\img503\out\Interesting Files\
-            SuspiciousDirs\
-                bomb_1\
-                    bomb\
-                        intructions.txt
-                        names.doc
-                bomb_42\
-                    bomb\
-                        readme.txt
-                        instructions\
-                            intructions.txt
-                            names.doc
-                SuspiciousDirs.xml
-
-Note that an XML report listing the saved files is placed in each interesting
-files set subdirectory. 
+Save Interesting Files Module
+Sleuth Kit Framework C++ Module
+May 2012
+
+
+This module is for the C++ Sleuth Kit Framework.
+
+
+DESCRIPTION
+
+This module is a post-processing module that saves files and directories
+that were flagged as being interesting by the InterestingFiles module. 
+It is used to extract the suspicious files for further analysis.
+For example, you could use InterestingFiles to flag all files of
+a given type and then use this module to save them to a local
+folder for manual analysis. 
+
+DEPLOYMENT REQUIREMENTS
+
+This module does not have any specific deployment requirements.
+
+USAGE
+
+Add this module to a post-processing pipeline.  See the TSK 
+Framework documents for information on adding the module 
+to the pipeline:
+
+    http://www.sleuthkit.org/sleuthkit/docs/framework-docs/
+
+The module takes the path to a folder where the files should be saved.
+
+
+RESULTS
+
+Interesting files are saved to the output folder in subdirectories bearing
+the name given to the matching interesting files set in the configuration
+file for the Interesting Files module.  File names are augmented with
+their file ids to avoid name collisions. The resulting directory structure
+will night something like this:
+
+        c:\img503\out\Interesting Files\
+            ReadmeFiles\
+                README_1
+                readme_24.txt
+                readme_382.txt
+                ReadmeFiles.xml    
+
+The contents of interesting directories are saved to the output folder in 
+subdirectories bearing the name given to the matching interesting files set 
+in the configuration file for the Interesting Files module.  A subdirectory 
+is created with the same name as the directory, but augmented with the
+directory's file id to avoid name collisions. The contents of the directory,
+including both files and subdirectories, is then saved. The resulting 
+directory structure might look something like this:
+
+        c:\img503\out\Interesting Files\
+            SuspiciousDirs\
+                bomb_1\
+                    bomb\
+                        intructions.txt
+                        names.doc
+                bomb_42\
+                    bomb\
+                        readme.txt
+                        instructions\
+                            intructions.txt
+                            names.doc
+                SuspiciousDirs.xml
+
+Note that an XML report listing the saved files is placed in each interesting
+files set subdirectory. 
diff --git a/framework/modules/c_SaveInterestingFilesModule/SaveInterestingFilesModule.cpp b/framework/modules/c_SaveInterestingFilesModule/SaveInterestingFilesModule.cpp
index 0b65cdb..b50e141 100644
--- a/framework/modules/c_SaveInterestingFilesModule/SaveInterestingFilesModule.cpp
+++ b/framework/modules/c_SaveInterestingFilesModule/SaveInterestingFilesModule.cpp
@@ -1,458 +1,458 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/** \file InterestingFiles.cpp
- * This file contains the implementation of a module that saves interesting 
- * files recorded on the blackboard to a user-specified output directory.
- */
-
-// Framework includes
-#include "tsk/framework/utilities/TskModuleDev.h"
-
-// Poco includes
-#include "Poco/Path.h"
-#include "Poco/File.h"
-#include "Poco/FileStream.h"
-#include "Poco/Exception.h"
-#include "Poco/XML/XMLWriter.h"
-#include "Poco/DOM/AutoPtr.h"
-#include "Poco/DOM/Document.h"
-#include "Poco/DOM/Element.h"
-#include "Poco/DOM/Attr.h"
-#include "Poco/DOM/DOMWriter.h"
-#include "Poco/DOM/Text.h"
-#include "Poco/DOM/Text.h"
-#include "Poco/DOM/DOMException.h"
-
-// System includes
-#include <string>
-#include <sstream>
-#include <vector>
-#include <set>
-#include <map>
-#include <iostream>
-#include <memory>
-#include <string.h>
-
-namespace
-{
-    const char *MODULE_NAME = "tskSaveInterestingFilesModule";
-    const char *MODULE_DESCRIPTION = "Saves files and directories that were flagged as being interesting to a location for further analysis";
-    const char *MODULE_VERSION = "1.0.0";
-
-    typedef std::map<std::string, std::string> FileSets; 
-    typedef std::multimap<std::string, TskBlackboardArtifact> FileSetHits;
-    typedef std::pair<FileSetHits::iterator, FileSetHits::iterator> FileSetHitsRange; 
-
-    std::string outputFolderPath;
-
-    void addFileToReport(const TskFile &file, const std::string &filePath, Poco::XML::Document *report)
-    {
-        Poco::XML::Element *reportRoot = static_cast<Poco::XML::Element*>(report->firstChild());
-
-        Poco::AutoPtr<Poco::XML::Element> fileElement; 
-        if (file.getMetaType() == TSK_FS_META_TYPE_DIR)
-        {
-            fileElement = report->createElement("SavedDirectory");
-        }
-        else
-        {
-            fileElement = report->createElement("SavedFile");
-        }
-        reportRoot->appendChild(fileElement);
-
-        Poco::AutoPtr<Poco::XML::Element> savedPathElement = report->createElement("Path");
-        fileElement->appendChild(savedPathElement);        
-        Poco::AutoPtr<Poco::XML::Text> savedPathText = report->createTextNode(filePath);
-        savedPathElement->appendChild(savedPathText);
-
-        Poco::AutoPtr<Poco::XML::Element> originalPathElement = report->createElement("OriginalPath");        
-        fileElement->appendChild(originalPathElement);
-        Poco::AutoPtr<Poco::XML::Text> originalPathText = report->createTextNode(file.getFullPath());
-        originalPathElement->appendChild(originalPathText);
-
-        Poco::AutoPtr<Poco::XML::Element> uniquePathElement = report->createElement("UniquePath");        
-        fileElement->appendChild(uniquePathElement);
-        Poco::AutoPtr<Poco::XML::Text> uniquePathText = report->createTextNode(file.getUniquePath());
-        uniquePathElement->appendChild(uniquePathText);
-
-        if (file.getMetaType() != TSK_FS_META_TYPE_DIR)
-        {
-            // This element will be empty unless a hash calculation module has operated on the file.
-            Poco::AutoPtr<Poco::XML::Element> md5HashElement = report->createElement("MD5");        
-            fileElement->appendChild(md5HashElement);                
-            Poco::AutoPtr<Poco::XML::Text> md5HashText = report->createTextNode(file.getHash(TskImgDB::MD5));
-            md5HashElement->appendChild(md5HashText);
-        }
-    }
-
-    void saveDirectoryContents(const std::string &dirPath, const TskFile &dir, Poco::XML::Document *report)
-    {
-        // Get a list corresponding to the files in the directory.
-        TskFileManager::AutoFilePtrList files(TskServices::Instance().getFileManager().findFilesByParent(dir.getId()));
-
-        // Save each file and subdirectory in the directory.
-        for (TskFileManager::FilePtrList::iterator file = files.begin(); file != files.end(); ++file)
-        {
-            if ((*file)->getMetaType() == TSK_FS_META_TYPE_DIR)
-            {
-                // Create a subdirectory to hold the contents of this subdirectory.
-                Poco::Path subDirPath(Poco::Path::forDirectory(dirPath));
-                subDirPath.pushDirectory((*file)->getName());
-                Poco::File(subDirPath).createDirectory();
-                
-                // Recurse into the subdirectory.
-                saveDirectoryContents(subDirPath.toString(), **file, report);
-            }
-            else
-            {
-                // Save the file.
-                std::stringstream filePath;
-                filePath << dirPath << Poco::Path::separator() << (*file)->getName();
-                TskServices::Instance().getFileManager().copyFile(*file, TskUtilities::toUTF16(filePath.str()));
-                addFileToReport(**file, (*file)->getName(), report);
-            }
-        }
-    }
-
-    void saveInterestingDirectory(const TskFile &dir, const std::string &fileSetFolderPath, Poco::XML::Document *report)
-    {
-        // Make a subdirectory of the output folder named for the interesting file search set and create a further subdirectory
-        // corresponding to the directory to be saved. The resulting directory structure will look like this:
-        // <output folder>/
-        //      <interesting file set name>/
-        //          <directory name>_<file id>/ /*Suffix the directory with its its file id to ensure uniqueness*/
-        //              <directory name>/
-        //                  <contents of directory including subdirectories>
-        //
-        Poco::Path path(Poco::Path::forDirectory(fileSetFolderPath));
-        std::stringstream subDir;
-        subDir << dir.getName() << '_' << dir.getId();
-        path.pushDirectory(subDir.str());
-        path.pushDirectory(dir.getName());
-        Poco::File(path).createDirectories();
-
-        addFileToReport(dir, path.toString(), report);
-
-        saveDirectoryContents(path.toString(), dir, report);
-    }
-
-    void saveInterestingFile(const TskFile &file, const std::string &fileSetFolderPath, Poco::XML::Document *report)
-    {
-        // Construct a path to write the contents of the file to a subdirectory of the output folder named for the interesting file search
-        // set. The resulting directory structure will look like this:
-        // <output folder>/
-        //      <interesting file set name>/
-        //          <file name>_<fileId>.<ext> /*Suffix the file with its its file id to ensure uniqueness*/
-        std::string fileName = file.getName();
-        std::stringstream id;
-        id << '_' << file.getId();
-        std::string::size_type pos = 0;
-        if ((pos = fileName.rfind(".")) != std::string::npos && pos != 0)
-        {
-            // The file name has a conventional extension. Insert the file id before the '.' of the extension.
-            fileName.insert(pos, id.str());
-        }
-        else
-        {
-            // The file has no extension or the only '.' in the file is an initial '.', as in a hidden file.
-            // Add the file id to the end of the file name.
-            fileName.append(id.str());
-        }
-        std::stringstream filePath;
-        filePath << fileSetFolderPath.c_str() << Poco::Path::separator() << fileName.c_str();
-    
-        // Save the file.
-        TskServices::Instance().getFileManager().copyFile(file.getId(), TskUtilities::toUTF16(filePath.str()));
-
-        addFileToReport(file, fileName.c_str(), report);
-    }
-
-    void saveFiles(const std::string &setName, const std::string &setDescription, FileSetHitsRange fileSetHitsRange)
-    {
-        // Start an XML report of the files in the set.
-        Poco::AutoPtr<Poco::XML::Document> report = new Poco::XML::Document();
-        Poco::AutoPtr<Poco::XML::Element> reportRoot = report->createElement("InterestingFileSet");
-        reportRoot->setAttribute("name", setName);
-        reportRoot->setAttribute("description", setDescription);
-        report->appendChild(reportRoot);
-
-        // Make a subdirectory of the output folder named for the interesting file set.
-        Poco::Path fileSetFolderPath(Poco::Path::forDirectory(outputFolderPath));
-        fileSetFolderPath.pushDirectory(setName);
-        Poco::File(fileSetFolderPath).createDirectory();
-        
-        // Save all of the files in the set.
-        for (FileSetHits::iterator fileHit = fileSetHitsRange.first; fileHit != fileSetHitsRange.second; ++fileHit)
-        {
-            std::auto_ptr<TskFile> file(TskServices::Instance().getFileManager().getFile((*fileHit).second.getObjectID()));
-            if (file->getMetaType() == TSK_FS_META_TYPE_DIR)
-            {
-                 saveInterestingDirectory(*file, fileSetFolderPath.toString(), report); 
-            }
-            else
-            {
-                saveInterestingFile(*file, fileSetFolderPath.toString(), report);
-            }
-        }
-
-        // Write out the completed XML report.
-        fileSetFolderPath.setFileName(setName + ".xml");
-        Poco::FileStream reportFile(fileSetFolderPath.toString());
-        Poco::XML::DOMWriter writer;
-        writer.setNewLine("\n");
-        writer.setOptions(Poco::XML::XMLWriter::PRETTY_PRINT);
-        writer.writeNode(reportFile, report);
-    }
-}
-
-extern "C" 
-{
-    /**
-     * Module identification function. 
-     *
-     * @return The name of the module.
-     */
-    TSK_MODULE_EXPORT const char *name()
-    {
-        return MODULE_NAME;
-    }
-
-    /**
-     * Module identification function. 
-     *
-     * @return A description of the module.
-     */
-    TSK_MODULE_EXPORT const char *description()
-    {
-        return MODULE_DESCRIPTION;
-    }
-
-    /**
-     * Module identification function. 
-     *
-     * @return The version of the module.
-     */
-    TSK_MODULE_EXPORT const char *version()
-    {
-        return MODULE_VERSION;
-    }
-
-    /**
-     * Module initialization function. Optionally receives an output folder
-     * path as the location for saving the files corresponding to interesting
-     * file set hits. The default output folder path is a folder named for the
-     * module in #MODULE_OUT_DIR#.
-     *
-     * @param args Optional output folder path.
-     * @return TskModule::OK if an output folder is created, TskModule::FAIL
-     * otherwise. 
-     */
-    TSK_MODULE_EXPORT TskModule::Status initialize(const char* arguments)
-    {
-        TskModule::Status status = TskModule::OK;
-
-        const std::string MSG_PREFIX = "SaveInterestingFilesModule::initialize : ";
-        try
-        {
-            Poco::Path outputDirPath;
-            if (strlen(arguments) != 0)
-            {
-                outputDirPath = Poco::Path::forDirectory(arguments);
-            }
-            else
-            {
-                outputDirPath = Poco::Path::forDirectory(GetSystemProperty(TskSystemProperties::MODULE_OUT_DIR));
-                outputDirPath.pushDirectory(MODULE_NAME);
-            }
-            outputFolderPath = outputDirPath.toString();
-
-            Poco::File(outputDirPath).createDirectories();
-        }
-        catch (TskException &ex)
-        {
-            status = TskModule::FAIL;
-            outputFolderPath.clear();
-            std::stringstream msg;
-            msg << MSG_PREFIX << "TskException: " << ex.message();
-            LOGERROR(msg.str());
-        }
-        catch (Poco::Exception &ex)
-        {
-            status = TskModule::FAIL;
-            outputFolderPath.clear();
-            std::stringstream msg;
-            msg << MSG_PREFIX << "Poco::Exception: " << ex.displayText();
-            LOGERROR(msg.str());
-        }
-        catch (std::exception &ex)
-        {
-            status = TskModule::FAIL;
-            outputFolderPath.clear();
-            std::stringstream msg;
-            msg << MSG_PREFIX << "std::exception: " << ex.what();
-            LOGERROR(msg.str());
-        }
-        catch (...)
-        {
-            status = TskModule::FAIL;
-            outputFolderPath.clear();
-            LOGERROR(MSG_PREFIX + "unrecognized exception");
-        }
-
-        return status;
-    }
-
-    /**
-     * Module execution function. Saves interesting files recorded on the 
-     * blackboard to a user-specified output directory.
-     *
-     * @returns TskModule::OK on success if all files saved, TskModule::FAIL if one or more files were not saved
-     */
-    TSK_MODULE_EXPORT TskModule::Status report()
-    {
-        TskModule::Status status = TskModule::OK;
-        
-        const std::string MSG_PREFIX = "SaveInterestingFilesModule::report : ";
-        try
-        {
-            if (outputFolderPath.empty())
-            {
-                // Initialization failed. The reason why was already logged in initialize().
-                return TskModule::FAIL;
-            }
-
-            // Get the interesting file set hits from the blackboard and sort them by set name.
-            FileSets fileSets;
-            FileSetHits fileSetHits;
-            std::vector<TskBlackboardArtifact> fileSetHitArtifacts = TskServices::Instance().getBlackboard().getArtifacts(TSK_INTERESTING_FILE_HIT);
-            for (std::vector<TskBlackboardArtifact>::iterator fileHit = fileSetHitArtifacts.begin(); fileHit != fileSetHitArtifacts.end(); ++fileHit)
-            {
-                // Find the set name attrbute of the artifact.
-                bool setNameFound = false;
-                std::vector<TskBlackboardAttribute> attrs = (*fileHit).getAttributes();
-                for (std::vector<TskBlackboardAttribute>::iterator attr = attrs.begin(); attr != attrs.end(); ++attr)
-                {
-                    if ((*attr).getAttributeTypeID() == TSK_SET_NAME)
-                    {
-                        setNameFound = true;
-                        
-                        // Save the set name and description, using a map to ensure that these values are saved once per file set.
-                        fileSets.insert(make_pair((*attr).getValueString(), (*attr).getContext()));
-                        
-                        // Drop the artifact into a multimap to allow for retrieval of all of the file hits for a file set as an 
-                        // iterator range.
-                        fileSetHits.insert(make_pair((*attr).getValueString(), (*fileHit)));
-                    }
-                }
-
-                if (!setNameFound)
-                {
-                    // Log the error and try the next artifact.
-                    std::stringstream msg;
-                    msg << MSG_PREFIX << "failed to find TSK_SET_NAME attribute for TSK_INTERESTING_FILE_HIT artifact with id '" << (*fileHit).getArtifactID() << "', skipping artifact";
-                    LOGERROR(msg.str());
-                }
-            }
-
-            // Save the interesting files to the output directory, file set by file set.
-            for (map<std::string, std::string>::const_iterator fileSet = fileSets.begin(); fileSet != fileSets.end(); ++fileSet)
-            {
-                // Get the file hits for the file set as an iterator range.
-                FileSetHitsRange fileSetHitsRange = fileSetHits.equal_range((*fileSet).first); 
-
-                // Save the files corresponding to the file hit artifacts.
-                saveFiles((*fileSet).first, (*fileSet).second, fileSetHitsRange);
-            }
-        }
-        catch (TskException &ex)
-        {
-            status = TskModule::FAIL;
-            std::stringstream msg;
-            msg << MSG_PREFIX << "TskException: " << ex.message();
-            LOGERROR(msg.str());
-        }
-        catch (Poco::Exception &ex)
-        {
-            status = TskModule::FAIL;
-            std::stringstream msg;
-            msg << MSG_PREFIX << "Poco::Exception: " << ex.displayText();
-            LOGERROR(msg.str());
-        }
-        catch (std::exception &ex)
-        {
-            status = TskModule::FAIL;
-            std::stringstream msg;
-            msg << MSG_PREFIX << "std::exception: " << ex.what();
-            LOGERROR(msg.str());
-        }
-        catch (...)
-        {
-            status = TskModule::FAIL;
-            LOGERROR(MSG_PREFIX + "unrecognized exception");
-        }
-        
-        return status;
-    }
-
-    /**
-     * Module cleanup function. Deletes output folder if empty.
-     *
-     * @returns TskModule::OK on success and TskModule::FAIL on error.
-     */
-    TSK_MODULE_EXPORT TskModule::Status finalize()
-    {
-        TskModule::Status status = TskModule::OK;        
-
-        const std::string MSG_PREFIX = "SaveInterestingFilesModule::finalize : ";
-        try
-        {
-            #if !defined(_DEBUG) 
-
-            Poco::File outputFolder(outputFolderPath);
-            std::vector<Poco::File> filesList;
-            outputFolder.list(filesList);
-            if (filesList.empty())
-            {
-                outputFolder.remove(true);
-            }
-
-            #endif
-        }
-        catch (TskException &ex)
-        {
-            status = TskModule::FAIL;
-            std::stringstream msg;
-            msg << MSG_PREFIX << "TskException: " << ex.message();
-            LOGERROR(msg.str());
-        }
-        catch (Poco::Exception &ex)
-        {
-            status = TskModule::FAIL;
-            std::stringstream msg;
-            msg << MSG_PREFIX << "Poco::Exception: " << ex.displayText();
-            LOGERROR(msg.str());
-        }
-        catch (std::exception &ex)
-        {
-            status = TskModule::FAIL;
-            std::stringstream msg;
-            msg << MSG_PREFIX << "std::exception: " << ex.what();
-            LOGERROR(msg.str());
-        }
-        catch (...)
-        {
-            status = TskModule::FAIL;
-            LOGERROR(MSG_PREFIX + "unrecognized exception");
-        }
-
-        return status;
-    }
-}
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/** \file InterestingFiles.cpp
+ * This file contains the implementation of a module that saves interesting 
+ * files recorded on the blackboard to a user-specified output directory.
+ */
+
+// Framework includes
+#include "tsk/framework/utilities/TskModuleDev.h"
+
+// Poco includes
+#include "Poco/Path.h"
+#include "Poco/File.h"
+#include "Poco/FileStream.h"
+#include "Poco/Exception.h"
+#include "Poco/XML/XMLWriter.h"
+#include "Poco/DOM/AutoPtr.h"
+#include "Poco/DOM/Document.h"
+#include "Poco/DOM/Element.h"
+#include "Poco/DOM/Attr.h"
+#include "Poco/DOM/DOMWriter.h"
+#include "Poco/DOM/Text.h"
+#include "Poco/DOM/Text.h"
+#include "Poco/DOM/DOMException.h"
+
+// System includes
+#include <string>
+#include <sstream>
+#include <vector>
+#include <set>
+#include <map>
+#include <iostream>
+#include <memory>
+#include <string.h>
+
+namespace
+{
+    const char *MODULE_NAME = "tskSaveInterestingFilesModule";
+    const char *MODULE_DESCRIPTION = "Saves files and directories that were flagged as being interesting to a location for further analysis";
+    const char *MODULE_VERSION = "1.0.0";
+
+    typedef std::map<std::string, std::string> FileSets; 
+    typedef std::multimap<std::string, TskBlackboardArtifact> FileSetHits;
+    typedef std::pair<FileSetHits::iterator, FileSetHits::iterator> FileSetHitsRange; 
+
+    std::string outputFolderPath;
+
+    void addFileToReport(const TskFile &file, const std::string &filePath, Poco::XML::Document *report)
+    {
+        Poco::XML::Element *reportRoot = static_cast<Poco::XML::Element*>(report->firstChild());
+
+        Poco::AutoPtr<Poco::XML::Element> fileElement; 
+        if (file.getMetaType() == TSK_FS_META_TYPE_DIR)
+        {
+            fileElement = report->createElement("SavedDirectory");
+        }
+        else
+        {
+            fileElement = report->createElement("SavedFile");
+        }
+        reportRoot->appendChild(fileElement);
+
+        Poco::AutoPtr<Poco::XML::Element> savedPathElement = report->createElement("Path");
+        fileElement->appendChild(savedPathElement);        
+        Poco::AutoPtr<Poco::XML::Text> savedPathText = report->createTextNode(filePath);
+        savedPathElement->appendChild(savedPathText);
+
+        Poco::AutoPtr<Poco::XML::Element> originalPathElement = report->createElement("OriginalPath");        
+        fileElement->appendChild(originalPathElement);
+        Poco::AutoPtr<Poco::XML::Text> originalPathText = report->createTextNode(file.getFullPath());
+        originalPathElement->appendChild(originalPathText);
+
+        Poco::AutoPtr<Poco::XML::Element> uniquePathElement = report->createElement("UniquePath");        
+        fileElement->appendChild(uniquePathElement);
+        Poco::AutoPtr<Poco::XML::Text> uniquePathText = report->createTextNode(file.getUniquePath());
+        uniquePathElement->appendChild(uniquePathText);
+
+        if (file.getMetaType() != TSK_FS_META_TYPE_DIR)
+        {
+            // This element will be empty unless a hash calculation module has operated on the file.
+            Poco::AutoPtr<Poco::XML::Element> md5HashElement = report->createElement("MD5");        
+            fileElement->appendChild(md5HashElement);                
+            Poco::AutoPtr<Poco::XML::Text> md5HashText = report->createTextNode(file.getHash(TskImgDB::MD5));
+            md5HashElement->appendChild(md5HashText);
+        }
+    }
+
+    void saveDirectoryContents(const std::string &dirPath, const TskFile &dir, Poco::XML::Document *report)
+    {
+        // Get a list corresponding to the files in the directory.
+        TskFileManager::AutoFilePtrList files(TskServices::Instance().getFileManager().findFilesByParent(dir.getId()));
+
+        // Save each file and subdirectory in the directory.
+        for (TskFileManager::FilePtrList::iterator file = files.begin(); file != files.end(); ++file)
+        {
+            if ((*file)->getMetaType() == TSK_FS_META_TYPE_DIR)
+            {
+                // Create a subdirectory to hold the contents of this subdirectory.
+                Poco::Path subDirPath(Poco::Path::forDirectory(dirPath));
+                subDirPath.pushDirectory((*file)->getName());
+                Poco::File(subDirPath).createDirectory();
+                
+                // Recurse into the subdirectory.
+                saveDirectoryContents(subDirPath.toString(), **file, report);
+            }
+            else
+            {
+                // Save the file.
+                std::stringstream filePath;
+                filePath << dirPath << Poco::Path::separator() << (*file)->getName();
+                TskServices::Instance().getFileManager().copyFile(*file, TskUtilities::toUTF16(filePath.str()));
+                addFileToReport(**file, (*file)->getName(), report);
+            }
+        }
+    }
+
+    void saveInterestingDirectory(const TskFile &dir, const std::string &fileSetFolderPath, Poco::XML::Document *report)
+    {
+        // Make a subdirectory of the output folder named for the interesting file search set and create a further subdirectory
+        // corresponding to the directory to be saved. The resulting directory structure will look like this:
+        // <output folder>/
+        //      <interesting file set name>/
+        //          <directory name>_<file id>/ /*Suffix the directory with its its file id to ensure uniqueness*/
+        //              <directory name>/
+        //                  <contents of directory including subdirectories>
+        //
+        Poco::Path path(Poco::Path::forDirectory(fileSetFolderPath));
+        std::stringstream subDir;
+        subDir << dir.getName() << '_' << dir.getId();
+        path.pushDirectory(subDir.str());
+        path.pushDirectory(dir.getName());
+        Poco::File(path).createDirectories();
+
+        addFileToReport(dir, path.toString(), report);
+
+        saveDirectoryContents(path.toString(), dir, report);
+    }
+
+    void saveInterestingFile(const TskFile &file, const std::string &fileSetFolderPath, Poco::XML::Document *report)
+    {
+        // Construct a path to write the contents of the file to a subdirectory of the output folder named for the interesting file search
+        // set. The resulting directory structure will look like this:
+        // <output folder>/
+        //      <interesting file set name>/
+        //          <file name>_<fileId>.<ext> /*Suffix the file with its its file id to ensure uniqueness*/
+        std::string fileName = file.getName();
+        std::stringstream id;
+        id << '_' << file.getId();
+        std::string::size_type pos = 0;
+        if ((pos = fileName.rfind(".")) != std::string::npos && pos != 0)
+        {
+            // The file name has a conventional extension. Insert the file id before the '.' of the extension.
+            fileName.insert(pos, id.str());
+        }
+        else
+        {
+            // The file has no extension or the only '.' in the file is an initial '.', as in a hidden file.
+            // Add the file id to the end of the file name.
+            fileName.append(id.str());
+        }
+        std::stringstream filePath;
+        filePath << fileSetFolderPath.c_str() << Poco::Path::separator() << fileName.c_str();
+    
+        // Save the file.
+        TskServices::Instance().getFileManager().copyFile(file.getId(), TskUtilities::toUTF16(filePath.str()));
+
+        addFileToReport(file, fileName.c_str(), report);
+    }
+
+    void saveFiles(const std::string &setName, const std::string &setDescription, FileSetHitsRange fileSetHitsRange)
+    {
+        // Start an XML report of the files in the set.
+        Poco::AutoPtr<Poco::XML::Document> report = new Poco::XML::Document();
+        Poco::AutoPtr<Poco::XML::Element> reportRoot = report->createElement("InterestingFileSet");
+        reportRoot->setAttribute("name", setName);
+        reportRoot->setAttribute("description", setDescription);
+        report->appendChild(reportRoot);
+
+        // Make a subdirectory of the output folder named for the interesting file set.
+        Poco::Path fileSetFolderPath(Poco::Path::forDirectory(outputFolderPath));
+        fileSetFolderPath.pushDirectory(setName);
+        Poco::File(fileSetFolderPath).createDirectory();
+        
+        // Save all of the files in the set.
+        for (FileSetHits::iterator fileHit = fileSetHitsRange.first; fileHit != fileSetHitsRange.second; ++fileHit)
+        {
+            std::auto_ptr<TskFile> file(TskServices::Instance().getFileManager().getFile((*fileHit).second.getObjectID()));
+            if (file->getMetaType() == TSK_FS_META_TYPE_DIR)
+            {
+                 saveInterestingDirectory(*file, fileSetFolderPath.toString(), report); 
+            }
+            else
+            {
+                saveInterestingFile(*file, fileSetFolderPath.toString(), report);
+            }
+        }
+
+        // Write out the completed XML report.
+        fileSetFolderPath.setFileName(setName + ".xml");
+        Poco::FileStream reportFile(fileSetFolderPath.toString());
+        Poco::XML::DOMWriter writer;
+        writer.setNewLine("\n");
+        writer.setOptions(Poco::XML::XMLWriter::PRETTY_PRINT);
+        writer.writeNode(reportFile, report);
+    }
+}
+
+extern "C" 
+{
+    /**
+     * Module identification function. 
+     *
+     * @return The name of the module.
+     */
+    TSK_MODULE_EXPORT const char *name()
+    {
+        return MODULE_NAME;
+    }
+
+    /**
+     * Module identification function. 
+     *
+     * @return A description of the module.
+     */
+    TSK_MODULE_EXPORT const char *description()
+    {
+        return MODULE_DESCRIPTION;
+    }
+
+    /**
+     * Module identification function. 
+     *
+     * @return The version of the module.
+     */
+    TSK_MODULE_EXPORT const char *version()
+    {
+        return MODULE_VERSION;
+    }
+
+    /**
+     * Module initialization function. Optionally receives an output folder
+     * path as the location for saving the files corresponding to interesting
+     * file set hits. The default output folder path is a folder named for the
+     * module in #MODULE_OUT_DIR#.
+     *
+     * @param args Optional output folder path.
+     * @return TskModule::OK if an output folder is created, TskModule::FAIL
+     * otherwise. 
+     */
+    TSK_MODULE_EXPORT TskModule::Status initialize(const char* arguments)
+    {
+        TskModule::Status status = TskModule::OK;
+
+        const std::string MSG_PREFIX = "SaveInterestingFilesModule::initialize : ";
+        try
+        {
+            Poco::Path outputDirPath;
+            if (strlen(arguments) != 0)
+            {
+                outputDirPath = Poco::Path::forDirectory(arguments);
+            }
+            else
+            {
+                outputDirPath = Poco::Path::forDirectory(GetSystemProperty(TskSystemProperties::MODULE_OUT_DIR));
+                outputDirPath.pushDirectory(MODULE_NAME);
+            }
+            outputFolderPath = outputDirPath.toString();
+
+            Poco::File(outputDirPath).createDirectories();
+        }
+        catch (TskException &ex)
+        {
+            status = TskModule::FAIL;
+            outputFolderPath.clear();
+            std::stringstream msg;
+            msg << MSG_PREFIX << "TskException: " << ex.message();
+            LOGERROR(msg.str());
+        }
+        catch (Poco::Exception &ex)
+        {
+            status = TskModule::FAIL;
+            outputFolderPath.clear();
+            std::stringstream msg;
+            msg << MSG_PREFIX << "Poco::Exception: " << ex.displayText();
+            LOGERROR(msg.str());
+        }
+        catch (std::exception &ex)
+        {
+            status = TskModule::FAIL;
+            outputFolderPath.clear();
+            std::stringstream msg;
+            msg << MSG_PREFIX << "std::exception: " << ex.what();
+            LOGERROR(msg.str());
+        }
+        catch (...)
+        {
+            status = TskModule::FAIL;
+            outputFolderPath.clear();
+            LOGERROR(MSG_PREFIX + "unrecognized exception");
+        }
+
+        return status;
+    }
+
+    /**
+     * Module execution function. Saves interesting files recorded on the 
+     * blackboard to a user-specified output directory.
+     *
+     * @returns TskModule::OK on success if all files saved, TskModule::FAIL if one or more files were not saved
+     */
+    TSK_MODULE_EXPORT TskModule::Status report()
+    {
+        TskModule::Status status = TskModule::OK;
+        
+        const std::string MSG_PREFIX = "SaveInterestingFilesModule::report : ";
+        try
+        {
+            if (outputFolderPath.empty())
+            {
+                // Initialization failed. The reason why was already logged in initialize().
+                return TskModule::FAIL;
+            }
+
+            // Get the interesting file set hits from the blackboard and sort them by set name.
+            FileSets fileSets;
+            FileSetHits fileSetHits;
+            std::vector<TskBlackboardArtifact> fileSetHitArtifacts = TskServices::Instance().getBlackboard().getArtifacts(TSK_INTERESTING_FILE_HIT);
+            for (std::vector<TskBlackboardArtifact>::iterator fileHit = fileSetHitArtifacts.begin(); fileHit != fileSetHitArtifacts.end(); ++fileHit)
+            {
+                // Find the set name attrbute of the artifact.
+                bool setNameFound = false;
+                std::vector<TskBlackboardAttribute> attrs = (*fileHit).getAttributes();
+                for (std::vector<TskBlackboardAttribute>::iterator attr = attrs.begin(); attr != attrs.end(); ++attr)
+                {
+                    if ((*attr).getAttributeTypeID() == TSK_SET_NAME)
+                    {
+                        setNameFound = true;
+                        
+                        // Save the set name and description, using a map to ensure that these values are saved once per file set.
+                        fileSets.insert(make_pair((*attr).getValueString(), (*attr).getContext()));
+                        
+                        // Drop the artifact into a multimap to allow for retrieval of all of the file hits for a file set as an 
+                        // iterator range.
+                        fileSetHits.insert(make_pair((*attr).getValueString(), (*fileHit)));
+                    }
+                }
+
+                if (!setNameFound)
+                {
+                    // Log the error and try the next artifact.
+                    std::stringstream msg;
+                    msg << MSG_PREFIX << "failed to find TSK_SET_NAME attribute for TSK_INTERESTING_FILE_HIT artifact with id '" << (*fileHit).getArtifactID() << "', skipping artifact";
+                    LOGERROR(msg.str());
+                }
+            }
+
+            // Save the interesting files to the output directory, file set by file set.
+            for (map<std::string, std::string>::const_iterator fileSet = fileSets.begin(); fileSet != fileSets.end(); ++fileSet)
+            {
+                // Get the file hits for the file set as an iterator range.
+                FileSetHitsRange fileSetHitsRange = fileSetHits.equal_range((*fileSet).first); 
+
+                // Save the files corresponding to the file hit artifacts.
+                saveFiles((*fileSet).first, (*fileSet).second, fileSetHitsRange);
+            }
+        }
+        catch (TskException &ex)
+        {
+            status = TskModule::FAIL;
+            std::stringstream msg;
+            msg << MSG_PREFIX << "TskException: " << ex.message();
+            LOGERROR(msg.str());
+        }
+        catch (Poco::Exception &ex)
+        {
+            status = TskModule::FAIL;
+            std::stringstream msg;
+            msg << MSG_PREFIX << "Poco::Exception: " << ex.displayText();
+            LOGERROR(msg.str());
+        }
+        catch (std::exception &ex)
+        {
+            status = TskModule::FAIL;
+            std::stringstream msg;
+            msg << MSG_PREFIX << "std::exception: " << ex.what();
+            LOGERROR(msg.str());
+        }
+        catch (...)
+        {
+            status = TskModule::FAIL;
+            LOGERROR(MSG_PREFIX + "unrecognized exception");
+        }
+        
+        return status;
+    }
+
+    /**
+     * Module cleanup function. Deletes output folder if empty.
+     *
+     * @returns TskModule::OK on success and TskModule::FAIL on error.
+     */
+    TSK_MODULE_EXPORT TskModule::Status finalize()
+    {
+        TskModule::Status status = TskModule::OK;        
+
+        const std::string MSG_PREFIX = "SaveInterestingFilesModule::finalize : ";
+        try
+        {
+            #if !defined(_DEBUG) 
+
+            Poco::File outputFolder(outputFolderPath);
+            std::vector<Poco::File> filesList;
+            outputFolder.list(filesList);
+            if (filesList.empty())
+            {
+                outputFolder.remove(true);
+            }
+
+            #endif
+        }
+        catch (TskException &ex)
+        {
+            status = TskModule::FAIL;
+            std::stringstream msg;
+            msg << MSG_PREFIX << "TskException: " << ex.message();
+            LOGERROR(msg.str());
+        }
+        catch (Poco::Exception &ex)
+        {
+            status = TskModule::FAIL;
+            std::stringstream msg;
+            msg << MSG_PREFIX << "Poco::Exception: " << ex.displayText();
+            LOGERROR(msg.str());
+        }
+        catch (std::exception &ex)
+        {
+            status = TskModule::FAIL;
+            std::stringstream msg;
+            msg << MSG_PREFIX << "std::exception: " << ex.what();
+            LOGERROR(msg.str());
+        }
+        catch (...)
+        {
+            status = TskModule::FAIL;
+            LOGERROR(MSG_PREFIX + "unrecognized exception");
+        }
+
+        return status;
+    }
+}
diff --git a/framework/modules/c_SummaryReportModule/NEWS.txt b/framework/modules/c_SummaryReportModule/NEWS.txt
index e79b430..dfecd82 100644
--- a/framework/modules/c_SummaryReportModule/NEWS.txt
+++ b/framework/modules/c_SummaryReportModule/NEWS.txt
@@ -1,12 +1,12 @@
-Numbers refer to github.net issue #s:
-    https://github.com/sleuthkit/c_SummaryReportModule/issues
-
----------------- VERSION 1.0.1 --------------
-- Minor udpate to way that directory paths are internally stored.
-
----------------- VERSION 1.0.0 --------------
-New Features:
-- Initial public release.
-
-Bug Fixes:
-- N/A. 
+Numbers refer to github.net issue #s:
+    https://github.com/sleuthkit/c_SummaryReportModule/issues
+
+---------------- VERSION 1.0.1 --------------
+- Minor udpate to way that directory paths are internally stored.
+
+---------------- VERSION 1.0.0 --------------
+New Features:
+- Initial public release.
+
+Bug Fixes:
+- N/A. 
diff --git a/framework/modules/c_SummaryReportModule/README.txt b/framework/modules/c_SummaryReportModule/README.txt
index ed4496d..e937cb1 100644
--- a/framework/modules/c_SummaryReportModule/README.txt
+++ b/framework/modules/c_SummaryReportModule/README.txt
@@ -1,48 +1,48 @@
-Tsk Summary Report Module
-Sleuth Kit Framework C++ Module
-May 2012
-
-This module is for the C++ Sleuth Kit Framework.
-
-
-DESCRIPTION
-
-This module is a post-processing module that creates a generic HTML report based on data in
-the blackboard.  This report will show the results from previously run analysis 
-modules.  This report is intended to be used by developers so that they can 
-see what their modules are posting to the blackboard and for users who want a
-very generic report.  In the future, module writers will hopefully make more
-customized reports. 
-
-This report has one table per artifact type that was found during the analysis.  
-Each table will have a column for each attribute.  There is a row for each
-artifact.
-
-DEPLOYMENT REQUIREMENTS
-
-This module does not have any specific deployment requirements.
-
-USAGE
-
-Add this module to a post-processing analysis pipeline.  See the TSK 
-Framework documents for information on adding the module to the pipeline:
-
-    http://www.sleuthkit.org/sleuthkit/docs/framework-docs/
-
-This module takes no configuration arguments.  
-
-
-RESULTS
-
-The HTML report is saved to the "Reports" folder in the output directory as defined
-in the framework for that session.
-
-
-TODO:
- - Add parameters to allow for selective artifact/attribute lookup for more custom
-   reports.
- - Add a table of contents showing the artifact types and the counts of artifacts
-   with links to the tables for easier navigation.
-
-
-
+Tsk Summary Report Module
+Sleuth Kit Framework C++ Module
+May 2012
+
+This module is for the C++ Sleuth Kit Framework.
+
+
+DESCRIPTION
+
+This module is a post-processing module that creates a generic HTML report based on data in
+the blackboard.  This report will show the results from previously run analysis 
+modules.  This report is intended to be used by developers so that they can 
+see what their modules are posting to the blackboard and for users who want a
+very generic report.  In the future, module writers will hopefully make more
+customized reports. 
+
+This report has one table per artifact type that was found during the analysis.  
+Each table will have a column for each attribute.  There is a row for each
+artifact.
+
+DEPLOYMENT REQUIREMENTS
+
+This module does not have any specific deployment requirements.
+
+USAGE
+
+Add this module to a post-processing analysis pipeline.  See the TSK 
+Framework documents for information on adding the module to the pipeline:
+
+    http://www.sleuthkit.org/sleuthkit/docs/framework-docs/
+
+This module takes no configuration arguments.  
+
+
+RESULTS
+
+The HTML report is saved to the "Reports" folder in the output directory as defined
+in the framework for that session.
+
+
+TODO:
+ - Add parameters to allow for selective artifact/attribute lookup for more custom
+   reports.
+ - Add a table of contents showing the artifact types and the counts of artifacts
+   with links to the tables for easier navigation.
+
+
+
diff --git a/framework/modules/c_SummaryReportModule/SummaryReport.cpp b/framework/modules/c_SummaryReportModule/SummaryReport.cpp
index 5bd32af..ba3a4d0 100755
--- a/framework/modules/c_SummaryReportModule/SummaryReport.cpp
+++ b/framework/modules/c_SummaryReportModule/SummaryReport.cpp
@@ -1,313 +1,313 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2011-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/** 
- * \file SummaryReport.cpp 
- * Contains the implementation of a function that creates a blackboard artifacts report.
- */
-
-// TSK Framework includes
-#include "tsk/framework/utilities/TskUtilities.h"
-#include "tsk/framework/services/TskServices.h"
-
-// Poco includes
-#include "Poco/FileStream.h"
-
-// C/C++ standard library includes 
-#include <string>
-#include <sstream>
-
-namespace
-{
-    // Convert reserved HTML characters to HTML entities
-    std::string HTMLEncode(const std::string &str)
-    {
-        std::string convertedStr;
-        for (size_t i = 0; i < str.size(); i++) 
-        {
-            if (str[i] == '<')
-                convertedStr.append("<");
-            else if (str[i] == '>')
-                convertedStr.append(">");
-            else if (str[i] == '&')
-                convertedStr.append("&");
-            else if (str[i] == '"')
-                convertedStr.append(""");
-            else if (str[i] == '\'')
-                convertedStr.append("'");
-            else
-                convertedStr += str[i];
-        }
-        return convertedStr;
-    }
-
-    void addStyle(Poco::FileOutputStream &out)
-    {
-        out << "<style type=\"text/css\">" << std::endl <<  
-            "table.gridtable {" << std::endl <<
-            "font-family: verdana,arial,sans-serif;" << std::endl <<
-            "font-size:11px;" << std::endl <<
-            "color:#333333;" << std::endl <<
-            "border-width: 1px;" << std::endl <<
-            "border-color: #666666;" << std::endl <<
-            "border-collapse: collapse;" << std::endl <<
-            "}" << std::endl <<
-            "table.gridtable th {" << std::endl <<
-            "border-width: 1px;" << std::endl <<
-            "padding: 8px;" << std::endl <<
-            "border-style: solid;" << std::endl <<
-            "border-color: #666666;" << std::endl <<
-            "background-color: #dedede;" << std::endl <<
-            "}" << std::endl <<
-            "table.gridtable td {" << std::endl <<
-            "border-width: 1px;" << std::endl <<
-            "padding: 8px;" << std::endl <<
-            "border-style: solid;" << std::endl <<
-            "border-color: #666666;" << std::endl <<
-            "background-color: #ffffff;" << std::endl <<
-            "}" << std::endl <<
-            "h1 {" << std::endl <<
-            "font-size: 1.5em;" << std::endl <<
-            "color: #000000;" << std::endl <<
-            "font-family: Arial, sans-serif;" << std::endl <<
-            "}" << std::endl <<
-
-            "h2 {" << std::endl <<
-            "font-size: 1.2em;" << std::endl <<
-            "color: #000000;" << std::endl <<
-            "font-family: Arial, sans-serif;" << std::endl <<
-            "}" << std::endl <<
-
-            "h3 {" << std::endl <<
-            "margin-left: 0;" << std::endl <<
-            "margin-bottom: 0;" << std::endl <<
-            "font-size: 1.0em;" << std::endl <<
-            "color: #000000;" << std::endl <<
-            "font-family: Arial, sans-serif;" << std::endl <<
-            "}" << std::endl <<
-            "</style>" << std::endl;
-    }
-
-    void writeReport(Poco::FileOutputStream &out)
-    {
-            out << "<html>" << std::endl;
-            out << "<head>" << std::endl;
-            out << "<meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />" << std::endl;
-            addStyle(out);
-
-            out << "<title>Report</title>" << std::endl;
-            out << "</head>" << std::endl;
-            out << "<body>" << std::endl;
-
-            TskBlackboard &blackboard = TskServices::Instance().getBlackboard();
-            TskImgDB &imgdb = TskServices::Instance().getImgDB();
-            std::stringstream condition;
-
-            out << "<h1>Sleuth Kit Framework Summary Report</h1>" << std::endl;
-            std::vector<std::string> names = imgdb.getImageNames();
-            out << "<h2>Image Path: " << names.front() << "</h2>" << std::endl;
-
-            out << "<h2>Image Layout</h2>" << std::endl;
-            std::list<TskVolumeInfoRecord> volumeInfoList;
-            imgdb.getVolumeInfo(volumeInfoList);
-
-            std::list<TskFsInfoRecord> fsInfoList;
-            imgdb.getFsInfo(fsInfoList);
-            TskFsInfoRecord fsInfo;
-
-            if (fsInfoList.size() == 0)
-            {
-                out << "<em>NO FILE SYSTEMS FOUND IN THE DISK IMAGE.</em>" << std::endl;
-            }
-
-            out << "<table class=\"gridtable\">" << std::endl;
-            out << "<thead>" << std::endl;
-            out << "<tr>" << std::endl;
-            out << "<th>Start Sector</th>" << std::endl;
-            out << "<th>End Sector</th>" << std::endl;
-            out << "<th>Partition Type</th>" << std::endl;
-            out << "<th>Detected FS</th>" << std::endl;
-            out << "</tr>" << std::endl;
-            out << "</thead>" << std::endl;
-
-            for (list<TskVolumeInfoRecord>::const_iterator iter = volumeInfoList.begin(); iter != volumeInfoList.end(); iter++) 
-            {
-                const TskVolumeInfoRecord & vol_info = *iter;
-                out << "<tr>" << std::endl;
-                out << "<td>" << vol_info.sect_start << "</td>" << std::endl;
-                out << "<td>" << (vol_info.sect_start + vol_info.sect_len) - 1 << "</td>" << std::endl;
-                out << "<td>" << vol_info.description << "</td>" << std::endl;
-
-                for (list<TskFsInfoRecord>::const_iterator iter2 = fsInfoList.begin(); iter2 != fsInfoList.end(); iter2++)
-                {
-                    fsInfo = (*iter2); 
-                    if(fsInfo.vol_id == vol_info.vol_id)
-                    {
-                        const char* fsName = tsk_fs_type_toname((TSK_FS_TYPE_ENUM)fsInfo.fs_type);
-                        if (!fsName)
-                        {
-                            out << "<td>Name of file system type is unknown.</td>" << std::endl;
-                            LOGERROR("writeReport: Name of file system type is unknown.");
-                        }
-                        else
-                        {
-                            out << "<td>" << fsName << "</td>" << std::endl;
-                        }
-                    }
-                }
-
-                out << "</tr>" << std::endl;
-            }
-            out << "</table>" << std::endl;
-
-            out << "<h2>File Categories</h2>" << std::endl;
-            out << "<table class=\"gridtable\">" << std::endl;
-
-            out << "<tr>" << std::endl;
-            condition.str("");
-            condition << "WHERE files.dir_type = " << TSK_FS_NAME_TYPE_REG 
-                      << " AND files.type_id = " << TskImgDB::IMGDB_FILES_TYPE_FS;
-            out << "<td><b>File System:</b></td>";
-            out << "<td>" << imgdb.getFileCount(condition.str()) << "</td>" << std::endl;
-            out << "</tr>" << std::endl;
-
-            out << "<tr>" << std::endl;
-            condition.str("");
-            condition << "WHERE files.dir_type = " << TSK_FS_NAME_TYPE_REG 
-                      << " AND files.type_id = " << TskImgDB::IMGDB_FILES_TYPE_DERIVED;
-            out << "<td><b>Derived:</b></td>";
-            out << "<td>" << imgdb.getFileCount(condition.str()) << "</td>" << std::endl;
-            out << "</tr>" << std::endl;
-
-            out << "<tr>" << std::endl;
-            condition.str("");
-            condition << "WHERE files.dir_type = " << TSK_FS_NAME_TYPE_REG 
-                      << " AND files.type_id = " << TskImgDB::IMGDB_FILES_TYPE_CARVED;
-            out << "<td><b>Carved:</b></td>";
-            out << "<td>" << imgdb.getFileCount(condition.str()) << "</td>" << std::endl;
-            out << "</tr>" << std::endl;
-
-            out << "<tr>" << std::endl;
-            condition.str("");
-            condition << "WHERE files.dir_type = " << TSK_FS_NAME_TYPE_REG 
-                      << " AND files.type_id = " << TskImgDB::IMGDB_FILES_TYPE_UNUSED;
-            out << "<td><b>Contiguous Unallocated Sectors:</b></td>";
-            out << "<td>" << imgdb.getFileCount(condition.str()) << "</td>" << std::endl;
-            out << "</tr>" << std::endl;
-
-            out << "<tr>" << std::endl;
-            condition.str("");
-            condition << "WHERE files.dir_type = " << TSK_FS_NAME_TYPE_REG;
-            out << "<td><b>Total Files:</b></td>";
-            out << "<td><b>" << imgdb.getFileCount(condition.str()) << "</b></td>" << std::endl;
-            out << "</tr>" << std::endl;
-
-            out << "<tr>" << std::endl;
-            out << "</table>" << std::endl;
-
-            std::vector<TskBlackboardArtifact> artifacts = blackboard.getMatchingArtifacts("ORDER BY artifact_type_id");
-            std::vector<TskBlackboardArtifact>::iterator it;
-            int currentArtType = -1;
-            std::vector<int> attrTypeIDs;
-            out << "<h2>Blackboard Artifacts</h2>" << std::endl;
-            for (it = artifacts.begin(); it != artifacts.end(); it++)
-            {
-                if (currentArtType != it->getArtifactTypeID())
-                {
-                    if (currentArtType != -1)
-                    {
-                        out << "</tbody>" << std::endl << "</table>" << std::endl;
-                    }
-                    currentArtType = it->getArtifactTypeID();
-                    out << "<h3>" << it->getDisplayName() << "</h3>" << std::endl;
-                    attrTypeIDs = blackboard.findAttributeTypes(currentArtType);
-                    out << "<table class=\"gridtable\">" << std::endl;
-                    out << "<thead>" << std::endl;
-                    out << "<tr>" << std::endl;
-                    out << "<th>File Name</th>" << std::endl;
-                    for (size_t i = 0; i < attrTypeIDs.size(); i++)
-                    {
-                        out << "<th>" << blackboard.attrTypeIDToTypeDisplayName(attrTypeIDs[i]) << "</th>" << std::endl;
-                    }
-                    out << "</tr>" << std::endl << "</thead>" << std::endl;
-                    out << "<tbody>" << std::endl;
-                }
-                out << "<tr>" << std::endl;
-                out << "<td>" << imgdb.getFileName(it->getObjectID()) << "</td>" << std::endl;
-                std::vector<TskBlackboardAttribute> attrs = it->getAttributes();
-
-                for (size_t j = 0; j < attrTypeIDs.size(); j++)
-                {
-                    TskBlackboardAttribute * attr;
-                    bool found = false;
-                    for (size_t k = 0; k < attrs.size(); k++)
-                    {
-                        if (attrs[k].getAttributeTypeID() == attrTypeIDs[j])
-                        {
-                            attr = &attrs[k];
-                            found = true;
-                            break;
-                        }
-                    }
-                    if (!found)
-                    {
-                        out << "<td/>" << std::endl;
-                    }
-                    else
-                    {
-                        out << "<td>";
-                        std::vector<unsigned char> bytes;
-                        switch(attr->getValueType())
-                        {
-                            case TSK_BYTE:
-                                bytes = attr->getValueBytes();
-                                for(size_t k = 0; k < bytes.size(); k++)
-                                    out << bytes[k];
-                                out << "</td>" << std::endl;
-                                break;
-
-                            case TSK_DOUBLE:
-                                out << attr->getValueDouble() << "</td>" << std::endl;
-                                break;
-
-                            case TSK_INTEGER:
-                                out << attr->getValueInt() << "</td>" << std::endl;
-                                break;
-
-                            case TSK_LONG:
-                                out << attr->getValueLong() << "</td>" << std::endl;
-                                break;
-
-                            case TSK_STRING:
-                                std::string encoded = HTMLEncode(attr->getValueString());
-                                out << encoded << "</td>" << std::endl;
-                                break;
-                        }
-                    }
-                }
-                out << "</tr>" << std::endl;
-            }
-            if (artifacts.size() > 0)
-            {
-                out << "</tbody>" << std::endl << "</table>" << std::endl;
-            }
-            out << "</body>" << std::endl;
-            out << "</html>" << std::endl;
-    }
-}
-
-namespace TskSummaryReport
-{
-    void generateReport(const std::string &reportPath)
-    {
-        Poco::FileOutputStream out(reportPath, std::ios::out | std::ios::trunc);
-        writeReport(out);
-    }
-}
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2011-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/** 
+ * \file SummaryReport.cpp 
+ * Contains the implementation of a function that creates a blackboard artifacts report.
+ */
+
+// TSK Framework includes
+#include "tsk/framework/utilities/TskUtilities.h"
+#include "tsk/framework/services/TskServices.h"
+
+// Poco includes
+#include "Poco/FileStream.h"
+
+// C/C++ standard library includes 
+#include <string>
+#include <sstream>
+
+namespace
+{
+    // Convert reserved HTML characters to HTML entities
+    std::string HTMLEncode(const std::string &str)
+    {
+        std::string convertedStr;
+        for (size_t i = 0; i < str.size(); i++) 
+        {
+            if (str[i] == '<')
+                convertedStr.append("<");
+            else if (str[i] == '>')
+                convertedStr.append(">");
+            else if (str[i] == '&')
+                convertedStr.append("&");
+            else if (str[i] == '"')
+                convertedStr.append(""");
+            else if (str[i] == '\'')
+                convertedStr.append("'");
+            else
+                convertedStr += str[i];
+        }
+        return convertedStr;
+    }
+
+    void addStyle(Poco::FileOutputStream &out)
+    {
+        out << "<style type=\"text/css\">" << std::endl <<  
+            "table.gridtable {" << std::endl <<
+            "font-family: verdana,arial,sans-serif;" << std::endl <<
+            "font-size:11px;" << std::endl <<
+            "color:#333333;" << std::endl <<
+            "border-width: 1px;" << std::endl <<
+            "border-color: #666666;" << std::endl <<
+            "border-collapse: collapse;" << std::endl <<
+            "}" << std::endl <<
+            "table.gridtable th {" << std::endl <<
+            "border-width: 1px;" << std::endl <<
+            "padding: 8px;" << std::endl <<
+            "border-style: solid;" << std::endl <<
+            "border-color: #666666;" << std::endl <<
+            "background-color: #dedede;" << std::endl <<
+            "}" << std::endl <<
+            "table.gridtable td {" << std::endl <<
+            "border-width: 1px;" << std::endl <<
+            "padding: 8px;" << std::endl <<
+            "border-style: solid;" << std::endl <<
+            "border-color: #666666;" << std::endl <<
+            "background-color: #ffffff;" << std::endl <<
+            "}" << std::endl <<
+            "h1 {" << std::endl <<
+            "font-size: 1.5em;" << std::endl <<
+            "color: #000000;" << std::endl <<
+            "font-family: Arial, sans-serif;" << std::endl <<
+            "}" << std::endl <<
+
+            "h2 {" << std::endl <<
+            "font-size: 1.2em;" << std::endl <<
+            "color: #000000;" << std::endl <<
+            "font-family: Arial, sans-serif;" << std::endl <<
+            "}" << std::endl <<
+
+            "h3 {" << std::endl <<
+            "margin-left: 0;" << std::endl <<
+            "margin-bottom: 0;" << std::endl <<
+            "font-size: 1.0em;" << std::endl <<
+            "color: #000000;" << std::endl <<
+            "font-family: Arial, sans-serif;" << std::endl <<
+            "}" << std::endl <<
+            "</style>" << std::endl;
+    }
+
+    void writeReport(Poco::FileOutputStream &out)
+    {
+            out << "<html>" << std::endl;
+            out << "<head>" << std::endl;
+            out << "<meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />" << std::endl;
+            addStyle(out);
+
+            out << "<title>Report</title>" << std::endl;
+            out << "</head>" << std::endl;
+            out << "<body>" << std::endl;
+
+            TskBlackboard &blackboard = TskServices::Instance().getBlackboard();
+            TskImgDB &imgdb = TskServices::Instance().getImgDB();
+            std::stringstream condition;
+
+            out << "<h1>Sleuth Kit Framework Summary Report</h1>" << std::endl;
+            std::vector<std::string> names = imgdb.getImageNames();
+            out << "<h2>Image Path: " << names.front() << "</h2>" << std::endl;
+
+            out << "<h2>Image Layout</h2>" << std::endl;
+            std::list<TskVolumeInfoRecord> volumeInfoList;
+            imgdb.getVolumeInfo(volumeInfoList);
+
+            std::list<TskFsInfoRecord> fsInfoList;
+            imgdb.getFsInfo(fsInfoList);
+            TskFsInfoRecord fsInfo;
+
+            if (fsInfoList.size() == 0)
+            {
+                out << "<em>NO FILE SYSTEMS FOUND IN THE DISK IMAGE.</em>" << std::endl;
+            }
+
+            out << "<table class=\"gridtable\">" << std::endl;
+            out << "<thead>" << std::endl;
+            out << "<tr>" << std::endl;
+            out << "<th>Start Sector</th>" << std::endl;
+            out << "<th>End Sector</th>" << std::endl;
+            out << "<th>Partition Type</th>" << std::endl;
+            out << "<th>Detected FS</th>" << std::endl;
+            out << "</tr>" << std::endl;
+            out << "</thead>" << std::endl;
+
+            for (list<TskVolumeInfoRecord>::const_iterator iter = volumeInfoList.begin(); iter != volumeInfoList.end(); iter++) 
+            {
+                const TskVolumeInfoRecord & vol_info = *iter;
+                out << "<tr>" << std::endl;
+                out << "<td>" << vol_info.sect_start << "</td>" << std::endl;
+                out << "<td>" << (vol_info.sect_start + vol_info.sect_len) - 1 << "</td>" << std::endl;
+                out << "<td>" << vol_info.description << "</td>" << std::endl;
+
+                for (list<TskFsInfoRecord>::const_iterator iter2 = fsInfoList.begin(); iter2 != fsInfoList.end(); iter2++)
+                {
+                    fsInfo = (*iter2); 
+                    if(fsInfo.vol_id == vol_info.vol_id)
+                    {
+                        const char* fsName = tsk_fs_type_toname((TSK_FS_TYPE_ENUM)fsInfo.fs_type);
+                        if (!fsName)
+                        {
+                            out << "<td>Name of file system type is unknown.</td>" << std::endl;
+                            LOGERROR("writeReport: Name of file system type is unknown.");
+                        }
+                        else
+                        {
+                            out << "<td>" << fsName << "</td>" << std::endl;
+                        }
+                    }
+                }
+
+                out << "</tr>" << std::endl;
+            }
+            out << "</table>" << std::endl;
+
+            out << "<h2>File Categories</h2>" << std::endl;
+            out << "<table class=\"gridtable\">" << std::endl;
+
+            out << "<tr>" << std::endl;
+            condition.str("");
+            condition << "WHERE files.dir_type = " << TSK_FS_NAME_TYPE_REG 
+                      << " AND files.type_id = " << TskImgDB::IMGDB_FILES_TYPE_FS;
+            out << "<td><b>File System:</b></td>";
+            out << "<td>" << imgdb.getFileCount(condition.str()) << "</td>" << std::endl;
+            out << "</tr>" << std::endl;
+
+            out << "<tr>" << std::endl;
+            condition.str("");
+            condition << "WHERE files.dir_type = " << TSK_FS_NAME_TYPE_REG 
+                      << " AND files.type_id = " << TskImgDB::IMGDB_FILES_TYPE_DERIVED;
+            out << "<td><b>Derived:</b></td>";
+            out << "<td>" << imgdb.getFileCount(condition.str()) << "</td>" << std::endl;
+            out << "</tr>" << std::endl;
+
+            out << "<tr>" << std::endl;
+            condition.str("");
+            condition << "WHERE files.dir_type = " << TSK_FS_NAME_TYPE_REG 
+                      << " AND files.type_id = " << TskImgDB::IMGDB_FILES_TYPE_CARVED;
+            out << "<td><b>Carved:</b></td>";
+            out << "<td>" << imgdb.getFileCount(condition.str()) << "</td>" << std::endl;
+            out << "</tr>" << std::endl;
+
+            out << "<tr>" << std::endl;
+            condition.str("");
+            condition << "WHERE files.dir_type = " << TSK_FS_NAME_TYPE_REG 
+                      << " AND files.type_id = " << TskImgDB::IMGDB_FILES_TYPE_UNUSED;
+            out << "<td><b>Contiguous Unallocated Sectors:</b></td>";
+            out << "<td>" << imgdb.getFileCount(condition.str()) << "</td>" << std::endl;
+            out << "</tr>" << std::endl;
+
+            out << "<tr>" << std::endl;
+            condition.str("");
+            condition << "WHERE files.dir_type = " << TSK_FS_NAME_TYPE_REG;
+            out << "<td><b>Total Files:</b></td>";
+            out << "<td><b>" << imgdb.getFileCount(condition.str()) << "</b></td>" << std::endl;
+            out << "</tr>" << std::endl;
+
+            out << "<tr>" << std::endl;
+            out << "</table>" << std::endl;
+
+            std::vector<TskBlackboardArtifact> artifacts = blackboard.getMatchingArtifacts("ORDER BY artifact_type_id");
+            std::vector<TskBlackboardArtifact>::iterator it;
+            int currentArtType = -1;
+            std::vector<int> attrTypeIDs;
+            out << "<h2>Blackboard Artifacts</h2>" << std::endl;
+            for (it = artifacts.begin(); it != artifacts.end(); it++)
+            {
+                if (currentArtType != it->getArtifactTypeID())
+                {
+                    if (currentArtType != -1)
+                    {
+                        out << "</tbody>" << std::endl << "</table>" << std::endl;
+                    }
+                    currentArtType = it->getArtifactTypeID();
+                    out << "<h3>" << it->getDisplayName() << "</h3>" << std::endl;
+                    attrTypeIDs = blackboard.findAttributeTypes(currentArtType);
+                    out << "<table class=\"gridtable\">" << std::endl;
+                    out << "<thead>" << std::endl;
+                    out << "<tr>" << std::endl;
+                    out << "<th>File Name</th>" << std::endl;
+                    for (size_t i = 0; i < attrTypeIDs.size(); i++)
+                    {
+                        out << "<th>" << blackboard.attrTypeIDToTypeDisplayName(attrTypeIDs[i]) << "</th>" << std::endl;
+                    }
+                    out << "</tr>" << std::endl << "</thead>" << std::endl;
+                    out << "<tbody>" << std::endl;
+                }
+                out << "<tr>" << std::endl;
+                out << "<td>" << imgdb.getFileName(it->getObjectID()) << "</td>" << std::endl;
+                std::vector<TskBlackboardAttribute> attrs = it->getAttributes();
+
+                for (size_t j = 0; j < attrTypeIDs.size(); j++)
+                {
+                    TskBlackboardAttribute * attr;
+                    bool found = false;
+                    for (size_t k = 0; k < attrs.size(); k++)
+                    {
+                        if (attrs[k].getAttributeTypeID() == attrTypeIDs[j])
+                        {
+                            attr = &attrs[k];
+                            found = true;
+                            break;
+                        }
+                    }
+                    if (!found)
+                    {
+                        out << "<td/>" << std::endl;
+                    }
+                    else
+                    {
+                        out << "<td>";
+                        std::vector<unsigned char> bytes;
+                        switch(attr->getValueType())
+                        {
+                            case TSK_BYTE:
+                                bytes = attr->getValueBytes();
+                                for(size_t k = 0; k < bytes.size(); k++)
+                                    out << bytes[k];
+                                out << "</td>" << std::endl;
+                                break;
+
+                            case TSK_DOUBLE:
+                                out << attr->getValueDouble() << "</td>" << std::endl;
+                                break;
+
+                            case TSK_INTEGER:
+                                out << attr->getValueInt() << "</td>" << std::endl;
+                                break;
+
+                            case TSK_LONG:
+                                out << attr->getValueLong() << "</td>" << std::endl;
+                                break;
+
+                            case TSK_STRING:
+                                std::string encoded = HTMLEncode(attr->getValueString());
+                                out << encoded << "</td>" << std::endl;
+                                break;
+                        }
+                    }
+                }
+                out << "</tr>" << std::endl;
+            }
+            if (artifacts.size() > 0)
+            {
+                out << "</tbody>" << std::endl << "</table>" << std::endl;
+            }
+            out << "</body>" << std::endl;
+            out << "</html>" << std::endl;
+    }
+}
+
+namespace TskSummaryReport
+{
+    void generateReport(const std::string &reportPath)
+    {
+        Poco::FileOutputStream out(reportPath, std::ios::out | std::ios::trunc);
+        writeReport(out);
+    }
+}
diff --git a/framework/modules/c_SummaryReportModule/SummaryReport.h b/framework/modules/c_SummaryReportModule/SummaryReport.h
index efbfbad..69574c2 100755
--- a/framework/modules/c_SummaryReportModule/SummaryReport.h
+++ b/framework/modules/c_SummaryReportModule/SummaryReport.h
@@ -1,22 +1,22 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2011-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/** 
- * \file SummaryReport.h 
- * Contains the declaration of a function that creates a blackboard artifacts report.
- */
-
-// C/C++ standard library includes 
-#include <string>
-
-namespace TskSummaryReport
-{
-    void generateReport(const std::string &reportPath);
-}
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2011-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/** 
+ * \file SummaryReport.h 
+ * Contains the declaration of a function that creates a blackboard artifacts report.
+ */
+
+// C/C++ standard library includes 
+#include <string>
+
+namespace TskSummaryReport
+{
+    void generateReport(const std::string &reportPath);
+}
diff --git a/framework/modules/c_SummaryReportModule/SummaryReportModule.cpp b/framework/modules/c_SummaryReportModule/SummaryReportModule.cpp
index 6f12a47..74a5ac3 100644
--- a/framework/modules/c_SummaryReportModule/SummaryReportModule.cpp
+++ b/framework/modules/c_SummaryReportModule/SummaryReportModule.cpp
@@ -1,193 +1,193 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2011-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/** 
- * \file SummaryReportModule.cpp 
- * Contains the implementation of a post-processing module that creates a blackboard artifacts report.
- */
-
-// Module includes
-#include "SummaryReport.h"
-
-// TSK Framework includes
-#include "tsk/framework/utilities/TskModuleDev.h"
-#include "tsk/framework/services/TskSystemProperties.h"
-
-// Poco includes
-#include "Poco/Path.h"
-#include "Poco/File.h"
-#include "Poco/Exception.h"
-
-// C/C++ standard library includes 
-#include <string>
-#include <sstream>
-#include <vector>
-
-namespace
-{
-    const char * MODULE_NAME = "tskSummaryReportModule";
-    const char * MODULE_DESCRIPTION = "Creates an HTML report on data posted to the blackboard";
-    const char * MODULE_VERSION = "1.0.0";        
-}
-
-extern "C" 
-{
-    /**
-     * Module identification function. 
-     *
-     * @return The name of the module.
-     */
-    TSK_MODULE_EXPORT const char *name()
-    {
-        return MODULE_NAME;
-    }
-
-    /**
-     * Module identification function. 
-     *
-     * @return A description of the module.
-     */
-    TSK_MODULE_EXPORT const char *description()
-    {
-        return MODULE_DESCRIPTION;
-    }
-
-    /**
-     * Module identification function. 
-     *
-     * @return The version of the module.
-     */
-    TSK_MODULE_EXPORT const char *version()
-    {
-        return MODULE_VERSION;
-    }
-
-    /**
-     * Module initialization function. Receives a string of initialization arguments, 
-     * typically read by the caller from a pipeline configuration file. 
-     * Returns TskModule::OK or TskModule::FAIL. Returning TskModule::FAIL indicates 
-     * the module is not in an operational state.  
-     *
-     * @param args a string of initialization arguments.
-     * @return TskModule::OK if initialization succeeded, otherwise TskModule::FAIL.
-     */
-    TskModule::Status TSK_MODULE_EXPORT initialize(const char* arguments)
-    {    
-        return TskModule::OK;
-    }
-
-    /**
-     * Module execution function. 
-     *
-     * @returns TskModule::OK on success, TskModule::FAIL on error, or TskModule::STOP.
-     */
-    TskModule::Status TSK_MODULE_EXPORT report() 
-    {
-        std::ostringstream msgPrefix;
-        msgPrefix << MODULE_NAME << "::report : ";
-        try
-        {
-            // Create an output folder.
-            Poco::Path outputFolderPath = Poco::Path::forDirectory(GetSystemProperty(TskSystemProperties::MODULE_OUT_DIR));
-            outputFolderPath.pushDirectory(MODULE_NAME);
-            Poco::File(outputFolderPath).createDirectories();
-
-            // Generate the report.
-            outputFolderPath.setFileName("SummaryReport.htm");
-            TskSummaryReport::generateReport(outputFolderPath.toString());
-
-            return TskModule::OK;
-        }
-        catch (TskException &ex)
-        {
-            std::ostringstream msg;
-            msg << msgPrefix.str() << "TskException: " << ex.message();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        catch (Poco::Exception &ex)
-        {
-            std::ostringstream msg;
-            msg << msgPrefix.str() << "Poco::Exception: " << ex.displayText();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        catch (std::exception &ex)
-        {
-            std::ostringstream msg;
-            msg << msgPrefix.str() << "std::exception: " << ex.what();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        catch (...)
-        {
-            LOGERROR(msgPrefix.str() + "unrecognized exception");
-            return TskModule::FAIL;
-        }
-    }
-
-    /**
-     * Module cleanup function. This is where the module should free any resources 
-     * allocated during initialization or execution.
-     *
-     * @returns TskModule::OK on success and TskModule::FAIL on error.
-     */
-    TskModule::Status TSK_MODULE_EXPORT finalize()
-    {
-        std::ostringstream msgPrefix;
-        msgPrefix << MODULE_NAME << "::finalize : ";
-        try
-        {
-            #if !defined(_DEBUG) 
-
-            // Delete the output folder if it's empty.
-            Poco::Path outputFolderPath = Poco::Path::forDirectory(GetSystemProperty(TskSystemProperties::MODULE_OUT_DIR));
-            outputFolderPath.pushDirectory(MODULE_NAME);
-            Poco::File outputFolder(outputFolderPath);
-            std::vector<Poco::File> filesList;
-            outputFolder.list(filesList);
-            if (filesList.empty())
-            {
-                outputFolder.remove(true);
-            }
-
-            #endif
-
-            return TskModule::OK;
-        }
-        catch (TskException &ex)
-        {
-            std::ostringstream msg;
-            msg << msgPrefix.str() << "TskException: " << ex.message();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        catch (Poco::Exception &ex)
-        {
-            std::ostringstream msg;
-            msg << msgPrefix.str() << "Poco::Exception: " << ex.displayText();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        catch (std::exception &ex)
-        {
-            std::ostringstream msg;
-            msg << msgPrefix.str() << "std::exception: " << ex.what();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-        catch (...)
-        {
-            LOGERROR(msgPrefix.str() + "unrecognized exception");
-            return TskModule::FAIL;
-        }
-    }
-}
-
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2011-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/** 
+ * \file SummaryReportModule.cpp 
+ * Contains the implementation of a post-processing module that creates a blackboard artifacts report.
+ */
+
+// Module includes
+#include "SummaryReport.h"
+
+// TSK Framework includes
+#include "tsk/framework/utilities/TskModuleDev.h"
+#include "tsk/framework/services/TskSystemProperties.h"
+
+// Poco includes
+#include "Poco/Path.h"
+#include "Poco/File.h"
+#include "Poco/Exception.h"
+
+// C/C++ standard library includes 
+#include <string>
+#include <sstream>
+#include <vector>
+
+namespace
+{
+    const char * MODULE_NAME = "tskSummaryReportModule";
+    const char * MODULE_DESCRIPTION = "Creates an HTML report on data posted to the blackboard";
+    const char * MODULE_VERSION = "1.0.0";        
+}
+
+extern "C" 
+{
+    /**
+     * Module identification function. 
+     *
+     * @return The name of the module.
+     */
+    TSK_MODULE_EXPORT const char *name()
+    {
+        return MODULE_NAME;
+    }
+
+    /**
+     * Module identification function. 
+     *
+     * @return A description of the module.
+     */
+    TSK_MODULE_EXPORT const char *description()
+    {
+        return MODULE_DESCRIPTION;
+    }
+
+    /**
+     * Module identification function. 
+     *
+     * @return The version of the module.
+     */
+    TSK_MODULE_EXPORT const char *version()
+    {
+        return MODULE_VERSION;
+    }
+
+    /**
+     * Module initialization function. Receives a string of initialization arguments, 
+     * typically read by the caller from a pipeline configuration file. 
+     * Returns TskModule::OK or TskModule::FAIL. Returning TskModule::FAIL indicates 
+     * the module is not in an operational state.  
+     *
+     * @param args a string of initialization arguments.
+     * @return TskModule::OK if initialization succeeded, otherwise TskModule::FAIL.
+     */
+    TskModule::Status TSK_MODULE_EXPORT initialize(const char* arguments)
+    {    
+        return TskModule::OK;
+    }
+
+    /**
+     * Module execution function. 
+     *
+     * @returns TskModule::OK on success, TskModule::FAIL on error, or TskModule::STOP.
+     */
+    TskModule::Status TSK_MODULE_EXPORT report() 
+    {
+        std::ostringstream msgPrefix;
+        msgPrefix << MODULE_NAME << "::report : ";
+        try
+        {
+            // Create an output folder.
+            Poco::Path outputFolderPath = Poco::Path::forDirectory(GetSystemProperty(TskSystemProperties::MODULE_OUT_DIR));
+            outputFolderPath.pushDirectory(MODULE_NAME);
+            Poco::File(outputFolderPath).createDirectories();
+
+            // Generate the report.
+            outputFolderPath.setFileName("SummaryReport.htm");
+            TskSummaryReport::generateReport(outputFolderPath.toString());
+
+            return TskModule::OK;
+        }
+        catch (TskException &ex)
+        {
+            std::ostringstream msg;
+            msg << msgPrefix.str() << "TskException: " << ex.message();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        catch (Poco::Exception &ex)
+        {
+            std::ostringstream msg;
+            msg << msgPrefix.str() << "Poco::Exception: " << ex.displayText();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        catch (std::exception &ex)
+        {
+            std::ostringstream msg;
+            msg << msgPrefix.str() << "std::exception: " << ex.what();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        catch (...)
+        {
+            LOGERROR(msgPrefix.str() + "unrecognized exception");
+            return TskModule::FAIL;
+        }
+    }
+
+    /**
+     * Module cleanup function. This is where the module should free any resources 
+     * allocated during initialization or execution.
+     *
+     * @returns TskModule::OK on success and TskModule::FAIL on error.
+     */
+    TskModule::Status TSK_MODULE_EXPORT finalize()
+    {
+        std::ostringstream msgPrefix;
+        msgPrefix << MODULE_NAME << "::finalize : ";
+        try
+        {
+            #if !defined(_DEBUG) 
+
+            // Delete the output folder if it's empty.
+            Poco::Path outputFolderPath = Poco::Path::forDirectory(GetSystemProperty(TskSystemProperties::MODULE_OUT_DIR));
+            outputFolderPath.pushDirectory(MODULE_NAME);
+            Poco::File outputFolder(outputFolderPath);
+            std::vector<Poco::File> filesList;
+            outputFolder.list(filesList);
+            if (filesList.empty())
+            {
+                outputFolder.remove(true);
+            }
+
+            #endif
+
+            return TskModule::OK;
+        }
+        catch (TskException &ex)
+        {
+            std::ostringstream msg;
+            msg << msgPrefix.str() << "TskException: " << ex.message();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        catch (Poco::Exception &ex)
+        {
+            std::ostringstream msg;
+            msg << msgPrefix.str() << "Poco::Exception: " << ex.displayText();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        catch (std::exception &ex)
+        {
+            std::ostringstream msg;
+            msg << msgPrefix.str() << "std::exception: " << ex.what();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+        catch (...)
+        {
+            LOGERROR(msgPrefix.str() + "unrecognized exception");
+            return TskModule::FAIL;
+        }
+    }
+}
+
diff --git a/framework/modules/c_TskHashLookupModule/NEWS.txt b/framework/modules/c_TskHashLookupModule/NEWS.txt
index 98fd3dd..ee4c8f9 100644
--- a/framework/modules/c_TskHashLookupModule/NEWS.txt
+++ b/framework/modules/c_TskHashLookupModule/NEWS.txt
@@ -1,9 +1,9 @@
-Numbers refer to github.net issue #s:
-    https://github.com/sleuthkit/c_TskHashLookupModule/issues
-
----------------- VERSION 1.0.0 --------------
-New Features:
-- Initial public release.
-
-Bug Fixes:
-- N/A. 
+Numbers refer to github.net issue #s:
+    https://github.com/sleuthkit/c_TskHashLookupModule/issues
+
+---------------- VERSION 1.0.0 --------------
+New Features:
+- Initial public release.
+
+Bug Fixes:
+- N/A. 
diff --git a/framework/modules/c_TskHashLookupModule/README.txt b/framework/modules/c_TskHashLookupModule/README.txt
index 23f314c..37e1a06 100755
--- a/framework/modules/c_TskHashLookupModule/README.txt
+++ b/framework/modules/c_TskHashLookupModule/README.txt
@@ -1,54 +1,54 @@
-Tsk Hash Lookup Module
-Sleuth Kit Framework C++ Module
-May 2012
-
-
-This module is for the C++ Sleuth Kit Framework.
-
-
-DESCRIPTION
-
-This module is a file analysis module that looks up a file's MD5 
-hash value in one or more hash databases that have been indexed using the
-Sleuth Kit's hfind tool.  Hash databases are used to identify files that are
-'known' and previously seen.  Known files can be both good (such as standard 
-OS files) or bad (such as contraband).
-
-DEPLOYMENT REQUIREMENTS
-
-The module requires that at least one hash database indexed using the Sleuth 
-Kit's hfind tool is specified in its arguments.  See the link below for instructions
-on using the Sleuthkit's hfind tool to create an NSRL database index file.
-
-  http://www.sleuthkit.org/informer/sleuthkit-informer-7.html#nsrl 
-
-
-USAGE
-
-Add this module to a file analysis pipeline.  See the TSK 
-Framework documents for information on adding the module 
-to the pipeline:
-
-    http://www.sleuthkit.org/sleuthkit/docs/framework-docs/
-
-
-This module takes a semi-colon delimited list of arguments:
-
-     -k <path> The path of a 'known' files hash database.
-     -b <path> The path of a 'known bad' or 'notable' files hash database.
-               Multiple 'known bad' hash sets may be specified.
-     -s        A flag directing the module to issue a pipeline stop request if
-               a hash set hit occurs.
-
-
-RESULTS
-
-Each hash set hit that is found is posted to the blackboard. If directed to do
-so, the module will also stop the file analysis pipeline for the file when a hit 
-occurs.
-
-TODO:
- - Make a downstream module to issue stop requests after reading results 
-   from the blackboard. This would allow for multiple decision making criteria
-   and would support the ability to insert additional processing between the 
-   look up and the decision.
+Tsk Hash Lookup Module
+Sleuth Kit Framework C++ Module
+May 2012
+
+
+This module is for the C++ Sleuth Kit Framework.
+
+
+DESCRIPTION
+
+This module is a file analysis module that looks up a file's MD5 
+hash value in one or more hash databases that have been indexed using the
+Sleuth Kit's hfind tool.  Hash databases are used to identify files that are
+'known' and previously seen.  Known files can be both good (such as standard 
+OS files) or bad (such as contraband).
+
+DEPLOYMENT REQUIREMENTS
+
+The module requires that at least one hash database indexed using the Sleuth 
+Kit's hfind tool is specified in its arguments.  See the link below for instructions
+on using the Sleuthkit's hfind tool to create an NSRL database index file.
+
+  http://www.sleuthkit.org/informer/sleuthkit-informer-7.html#nsrl 
+
+
+USAGE
+
+Add this module to a file analysis pipeline.  See the TSK 
+Framework documents for information on adding the module 
+to the pipeline:
+
+    http://www.sleuthkit.org/sleuthkit/docs/framework-docs/
+
+
+This module takes a semi-colon delimited list of arguments:
+
+     -k <path> The path of a 'known' files hash database.
+     -b <path> The path of a 'known bad' or 'notable' files hash database.
+               Multiple 'known bad' hash sets may be specified.
+     -s        A flag directing the module to issue a pipeline stop request if
+               a hash set hit occurs.
+
+
+RESULTS
+
+Each hash set hit that is found is posted to the blackboard. If directed to do
+so, the module will also stop the file analysis pipeline for the file when a hit 
+occurs.
+
+TODO:
+ - Make a downstream module to issue stop requests after reading results 
+   from the blackboard. This would allow for multiple decision making criteria
+   and would support the ability to insert additional processing between the 
+   look up and the decision.
diff --git a/framework/modules/c_TskHashLookupModule/TskHashLookupModule.cpp b/framework/modules/c_TskHashLookupModule/TskHashLookupModule.cpp
index 5bc4327..5483f8e 100644
--- a/framework/modules/c_TskHashLookupModule/TskHashLookupModule.cpp
+++ b/framework/modules/c_TskHashLookupModule/TskHashLookupModule.cpp
@@ -1,264 +1,264 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2011-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/** \file TskHashLookupModule.cpp
- * Contains an implementation of a hash look up file analysis module that uses one or more
- * TSK hash database indexes to check a given file's MD5 hash against known bad file and 
- * known file hash sets. Hash set hits are posted to the blackboard and the module can be 
- * configured to issue a pipeline stop request if there is a hit.
- */
-
-// System includes
-#include <string>
-#include <vector>
-#include <sstream>
-
-// Framework includes
-#include "tsk/framework/utilities/TskModuleDev.h"
-
-// Poco includes
-#include "Poco/StringTokenizer.h"
-
-namespace
-{
-    const char *MODULE_NAME = "TskHashLookup";
-    const char *MODULE_DESCRIPTION = "Looks up a file's MD5 hash value in one or more hash databases that have been indexed using the Sleuth Kit's hfind tool";
-    const char *MODULE_VERSION = "1.0.0";
-
-    static bool issueStopRequestsOnHits = false;
-    static TSK_HDB_INFO* knownHashDBInfo = NULL;
-    static std::vector<TSK_HDB_INFO*> knownBadHashDBInfos;
-}
-
-
-
-/**
- * Helper function to open the index file for a TSK-indexed hash database.
- *
- * @param hashDatabasePath The path to a TSK-indexed hash database file.
- * @param option           The option argument associated with the file, 
- *                         for logging purposes.
- * @return                 A TSK_HDB_INFO pointer if the index file is 
- *                         successfully opened, NULL otherwise.
- */
-static TSK_HDB_INFO* openHashDatabaseIndexFile(const std::string& hashDatabasePath, const std::string& option)
-{
-    // Was the hash database path specified?
-    if (hashDatabasePath.empty()) {
-        std::wstringstream msg;
-        msg << L"TskHashLookupModule::initialize - missing hash database path for " << option.c_str() << L" option.";
-        LOGERROR(msg.str());
-        return NULL;
-    }
-
-    // Get a hash database info record for the hash database.
-    std::vector<TSK_TCHAR> hashDbPath(hashDatabasePath.length() + 1);
-    std::copy(hashDatabasePath.begin(), hashDatabasePath.end(), hashDbPath.begin());
-    hashDbPath[hashDatabasePath.length()] = '\0';
-    TSK_HDB_INFO* hashDBInfo = tsk_hdb_open(&hashDbPath[0], TSK_HDB_OPEN_IDXONLY);
-
-    if (!hashDBInfo) {
-        std::wstringstream msg;
-        msg << L"TskHashLookupModule::initialize - failed to hash database info record for '" << hashDatabasePath.c_str() << L"'";
-        LOGERROR(msg.str());
-        return NULL;
-    }
-
-    // Is there an MD5 index?
-    if (!tsk_hdb_hasindex(hashDBInfo, TSK_HDB_HTYPE_MD5_ID)) {
-        std::wstringstream msg;
-        msg << L"TskHashLookupModule::initialize - failed to find MD5 index for '" << hashDatabasePath.c_str() << L"'";
-        LOGERROR(msg.str());
-        return NULL;
-    }
-
-    return hashDBInfo;
-}
-
-extern "C" 
-{
-    /**
-     * Module identification function. 
-     *
-     * @return The name of the module.
-     */
-    TSK_MODULE_EXPORT const char *name()
-    {
-        return MODULE_NAME;
-    }
-
-    /**
-     * Module identification function. 
-     *
-     * @return A description of the module.
-     */
-    TSK_MODULE_EXPORT const char *description()
-    {
-        return MODULE_DESCRIPTION;
-    }
-
-    /**
-     * Module identification function. 
-     *
-     * @return The version of the module.
-     */
-    TSK_MODULE_EXPORT const char *version()
-    {
-        return MODULE_VERSION;
-    }
-
-    /**
-     * Module initialization function. 
-     *
-     * @param args A semicolon delimited list of arguments:
-     *      -k <path> The path of a TSK-indexed hash database for a known files
-     *                hash set.
-     *      -b <path> The path of a TSK-indexed hash database for a known bad 
-     *                files hash set. Multiple known bad hash sets may be 
-     *                specified.
-     *      -s        A flag directing the module to issue a pipeline stop 
-     *                request if a hash set hit occurs.
-     * @return TskModule::OK if initialization succeeded, otherwise TskModule::FAIL.
-     */
-    TskModule::Status TSK_MODULE_EXPORT initialize(const char* arguments)
-    {
-        std::string args(arguments);
-
-        // At least one hash database path must be provided.
-        if (args.empty()) {
-            LOGERROR(L"TskHashLookupModule::initialize - passed empty argument string.");
-            return TskModule::FAIL;
-        }
-
-        // Parse and process the arguments.
-        Poco::StringTokenizer tokenizer(args, ";");
-        std::vector<std::string> argsVector(tokenizer.begin(), tokenizer.end());
-        for (std::vector<std::string>::const_iterator it = argsVector.begin(); it < argsVector.end(); ++it) {
-            if ((*it).find("-s") == 0) {
-                issueStopRequestsOnHits = true;
-            }
-            else if ((*it).find("-k") == 0) {
-                // Only one known files hash set may be specified.
-                if (knownHashDBInfo) {
-                    LOGERROR(L"TskHashLookupModule::initialize - multiple known hash databases specified, only one is allowed.");
-                    return TskModule::FAIL;
-                }
-
-                knownHashDBInfo = openHashDatabaseIndexFile((*it).substr(3), "-k");
-                if (!knownHashDBInfo)
-                    return TskModule::FAIL;
-            }
-            else if ((*it).find("-b") == 0) {
-                // Any number of known bad files hash sets may be specified.
-                TSK_HDB_INFO* hashDBInfo = openHashDatabaseIndexFile((*it).substr(3), "-b");
-                if (hashDBInfo)
-                    knownBadHashDBInfos.push_back(hashDBInfo);
-                else
-                    return TskModule::FAIL;
-            }
-            else {
-                LOGERROR(L"TskHashLookupModule::initialize - unrecognized option in argument string.");
-                return TskModule::FAIL;
-            }
-        }
-
-        // At least one hash database file path must be provided.
-        if (!knownHashDBInfo && knownBadHashDBInfos.empty()) {
-            LOGERROR(L"TskHashLookupModule::initialize - no hash database paths specified in argument string.");
-            return TskModule::FAIL;
-        }
-
-        return TskModule::OK;
-    }
-
-    /**
-     * Module execution function. Receives a pointer to a file the module is to
-     * process. The file is represented by a TskFile interface which is queried
-     * to get the MD5 hash of the file. The hash is then used do a lookup in
-     * the hash database. If the lookup succeeds, a request to terminate 
-     * processing of the file is issued.
-     *
-     * @param pFile File for which the hash database lookup is to be performed.
-     * @returns     TskModule::FAIL if an error occurs, otherwise TskModule::OK 
-     *              or TskModule::STOP. TskModule::STOP is returned if the look 
-     *              up succeeds and the module is configured to request a 
-     *              pipeline stop when a hash set hit occurs.
-     */
-    TskModule::Status TSK_MODULE_EXPORT run(TskFile * pFile)
-    {
-        // Received a file to analyze?
-        if (pFile == NULL) {
-            LOGERROR(L"TskHashLookupModule::run passed NULL file pointer.");
-            return TskModule::FAIL;
-        }
-
-        // Need at least one hash database index file to run.
-        if (!knownHashDBInfo && knownBadHashDBInfos.empty()) {
-            LOGERROR(L"TskHashLookupModule::run - no hash database index files to search.");
-            return TskModule::FAIL;
-        }
-
-        // Check for hash set hits.
-        TskBlackboard &blackBoard = TskServices::Instance().getBlackboard();
-        TskImgDB& imageDB = TskServices::Instance().getImgDB();
-        bool hashSetHit = false;
-        try {
-            std::string md5 = pFile->getHash(TskImgDB::MD5); 
-
-            // Check for known bad files hash set hits. If a hit occurs, mark the file as IMGDB_FILES_KNOWN_BAD
-            // and post the hit to the blackboard.
-            for (std::vector<TSK_HDB_INFO*>::iterator it = knownBadHashDBInfos.begin(); it < knownBadHashDBInfos.end(); ++it) {
-                if (tsk_hdb_lookup_str(*it, md5.c_str(), TSK_HDB_FLAG_QUICK, NULL, NULL)) {
-                    if (!hashSetHit) {
-                        imageDB.updateKnownStatus(pFile->getId(), TskImgDB::IMGDB_FILES_KNOWN_BAD);
-                        hashSetHit = true;
-                    }
-                    TskBlackboardArtifact artifact = blackBoard.createArtifact(pFile->getId(), TSK_HASHSET_HIT);
-                    TskBlackboardAttribute attribute(TSK_SET_NAME, "TskHashLookupModule", "", (*it)->db_name);
-                    artifact.addAttribute(attribute);
-                }
-            }
-
-            // If there were no known bad file hits, check for a known file hash set hit. if a hit occurs, 
-            // mark the file as IMGDB_FILES_KNOWN and post the hit to the blackboard.
-            if (knownHashDBInfo && !hashSetHit && tsk_hdb_lookup_str(knownHashDBInfo, md5.c_str(), TSK_HDB_FLAG_QUICK, NULL, NULL)) {
-                imageDB.updateKnownStatus(pFile->getId(), TskImgDB::IMGDB_FILES_KNOWN);
-                hashSetHit = true;
-                TskBlackboardArtifact artifact = blackBoard.createArtifact(pFile->getId(), TSK_HASHSET_HIT);
-                TskBlackboardAttribute attribute(TSK_SET_NAME, "TskHashLookupModule", "", knownHashDBInfo->db_name);
-                artifact.addAttribute(attribute);
-            }
-        }
-        catch (TskException& ex) {
-            std::wstringstream msg;
-            msg << L"TskHashLookupModule::run - error on lookup for file id " << pFile->getId() << L": " << ex.what();
-            LOGERROR(msg.str());
-            return TskModule::FAIL;
-        }
-
-        return hashSetHit && issueStopRequestsOnHits ? TskModule::STOP : TskModule::OK;
-    }
-
-    /**
-     * Module cleanup function that closes the hash database index files.
-     *
-     * @returns TskModule::OK 
-     */
-    TskModule::Status TSK_MODULE_EXPORT finalize() 
-    {
-        if (knownHashDBInfo != NULL)
-            tsk_hdb_close(knownHashDBInfo); // Closes the index file and frees the memory for the TSK_HDB_INFO struct. 
-
-        for (std::vector<TSK_HDB_INFO*>::iterator it = knownBadHashDBInfos.begin(); it < knownBadHashDBInfos.end(); ++it)
-            tsk_hdb_close(*it); // Closes the index file and frees the memory for the TSK_HDB_INFO struct.
-
-        return TskModule::OK;
-    }
-}
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2011-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/** \file TskHashLookupModule.cpp
+ * Contains an implementation of a hash look up file analysis module that uses one or more
+ * TSK hash database indexes to check a given file's MD5 hash against known bad file and 
+ * known file hash sets. Hash set hits are posted to the blackboard and the module can be 
+ * configured to issue a pipeline stop request if there is a hit.
+ */
+
+// System includes
+#include <string>
+#include <vector>
+#include <sstream>
+
+// Framework includes
+#include "tsk/framework/utilities/TskModuleDev.h"
+
+// Poco includes
+#include "Poco/StringTokenizer.h"
+
+namespace
+{
+    const char *MODULE_NAME = "TskHashLookup";
+    const char *MODULE_DESCRIPTION = "Looks up a file's MD5 hash value in one or more hash databases that have been indexed using the Sleuth Kit's hfind tool";
+    const char *MODULE_VERSION = "1.0.0";
+
+    static bool issueStopRequestsOnHits = false;
+    static TSK_HDB_INFO* knownHashDBInfo = NULL;
+    static std::vector<TSK_HDB_INFO*> knownBadHashDBInfos;
+}
+
+
+
+/**
+ * Helper function to open the index file for a TSK-indexed hash database.
+ *
+ * @param hashDatabasePath The path to a TSK-indexed hash database file.
+ * @param option           The option argument associated with the file, 
+ *                         for logging purposes.
+ * @return                 A TSK_HDB_INFO pointer if the index file is 
+ *                         successfully opened, NULL otherwise.
+ */
+static TSK_HDB_INFO* openHashDatabaseIndexFile(const std::string& hashDatabasePath, const std::string& option)
+{
+    // Was the hash database path specified?
+    if (hashDatabasePath.empty()) {
+        std::wstringstream msg;
+        msg << L"TskHashLookupModule::initialize - missing hash database path for " << option.c_str() << L" option.";
+        LOGERROR(msg.str());
+        return NULL;
+    }
+
+    // Get a hash database info record for the hash database.
+    std::vector<TSK_TCHAR> hashDbPath(hashDatabasePath.length() + 1);
+    std::copy(hashDatabasePath.begin(), hashDatabasePath.end(), hashDbPath.begin());
+    hashDbPath[hashDatabasePath.length()] = '\0';
+    TSK_HDB_INFO* hashDBInfo = tsk_hdb_open(&hashDbPath[0], TSK_HDB_OPEN_IDXONLY);
+
+    if (!hashDBInfo) {
+        std::wstringstream msg;
+        msg << L"TskHashLookupModule::initialize - failed to hash database info record for '" << hashDatabasePath.c_str() << L"'";
+        LOGERROR(msg.str());
+        return NULL;
+    }
+
+    // Is there an MD5 index?
+    if (!tsk_hdb_hasindex(hashDBInfo, TSK_HDB_HTYPE_MD5_ID)) {
+        std::wstringstream msg;
+        msg << L"TskHashLookupModule::initialize - failed to find MD5 index for '" << hashDatabasePath.c_str() << L"'";
+        LOGERROR(msg.str());
+        return NULL;
+    }
+
+    return hashDBInfo;
+}
+
+extern "C" 
+{
+    /**
+     * Module identification function. 
+     *
+     * @return The name of the module.
+     */
+    TSK_MODULE_EXPORT const char *name()
+    {
+        return MODULE_NAME;
+    }
+
+    /**
+     * Module identification function. 
+     *
+     * @return A description of the module.
+     */
+    TSK_MODULE_EXPORT const char *description()
+    {
+        return MODULE_DESCRIPTION;
+    }
+
+    /**
+     * Module identification function. 
+     *
+     * @return The version of the module.
+     */
+    TSK_MODULE_EXPORT const char *version()
+    {
+        return MODULE_VERSION;
+    }
+
+    /**
+     * Module initialization function. 
+     *
+     * @param args A semicolon delimited list of arguments:
+     *      -k <path> The path of a TSK-indexed hash database for a known files
+     *                hash set.
+     *      -b <path> The path of a TSK-indexed hash database for a known bad 
+     *                files hash set. Multiple known bad hash sets may be 
+     *                specified.
+     *      -s        A flag directing the module to issue a pipeline stop 
+     *                request if a hash set hit occurs.
+     * @return TskModule::OK if initialization succeeded, otherwise TskModule::FAIL.
+     */
+    TskModule::Status TSK_MODULE_EXPORT initialize(const char* arguments)
+    {
+        std::string args(arguments);
+
+        // At least one hash database path must be provided.
+        if (args.empty()) {
+            LOGERROR(L"TskHashLookupModule::initialize - passed empty argument string.");
+            return TskModule::FAIL;
+        }
+
+        // Parse and process the arguments.
+        Poco::StringTokenizer tokenizer(args, ";");
+        std::vector<std::string> argsVector(tokenizer.begin(), tokenizer.end());
+        for (std::vector<std::string>::const_iterator it = argsVector.begin(); it < argsVector.end(); ++it) {
+            if ((*it).find("-s") == 0) {
+                issueStopRequestsOnHits = true;
+            }
+            else if ((*it).find("-k") == 0) {
+                // Only one known files hash set may be specified.
+                if (knownHashDBInfo) {
+                    LOGERROR(L"TskHashLookupModule::initialize - multiple known hash databases specified, only one is allowed.");
+                    return TskModule::FAIL;
+                }
+
+                knownHashDBInfo = openHashDatabaseIndexFile((*it).substr(3), "-k");
+                if (!knownHashDBInfo)
+                    return TskModule::FAIL;
+            }
+            else if ((*it).find("-b") == 0) {
+                // Any number of known bad files hash sets may be specified.
+                TSK_HDB_INFO* hashDBInfo = openHashDatabaseIndexFile((*it).substr(3), "-b");
+                if (hashDBInfo)
+                    knownBadHashDBInfos.push_back(hashDBInfo);
+                else
+                    return TskModule::FAIL;
+            }
+            else {
+                LOGERROR(L"TskHashLookupModule::initialize - unrecognized option in argument string.");
+                return TskModule::FAIL;
+            }
+        }
+
+        // At least one hash database file path must be provided.
+        if (!knownHashDBInfo && knownBadHashDBInfos.empty()) {
+            LOGERROR(L"TskHashLookupModule::initialize - no hash database paths specified in argument string.");
+            return TskModule::FAIL;
+        }
+
+        return TskModule::OK;
+    }
+
+    /**
+     * Module execution function. Receives a pointer to a file the module is to
+     * process. The file is represented by a TskFile interface which is queried
+     * to get the MD5 hash of the file. The hash is then used do a lookup in
+     * the hash database. If the lookup succeeds, a request to terminate 
+     * processing of the file is issued.
+     *
+     * @param pFile File for which the hash database lookup is to be performed.
+     * @returns     TskModule::FAIL if an error occurs, otherwise TskModule::OK 
+     *              or TskModule::STOP. TskModule::STOP is returned if the look 
+     *              up succeeds and the module is configured to request a 
+     *              pipeline stop when a hash set hit occurs.
+     */
+    TskModule::Status TSK_MODULE_EXPORT run(TskFile * pFile)
+    {
+        // Received a file to analyze?
+        if (pFile == NULL) {
+            LOGERROR(L"TskHashLookupModule::run passed NULL file pointer.");
+            return TskModule::FAIL;
+        }
+
+        // Need at least one hash database index file to run.
+        if (!knownHashDBInfo && knownBadHashDBInfos.empty()) {
+            LOGERROR(L"TskHashLookupModule::run - no hash database index files to search.");
+            return TskModule::FAIL;
+        }
+
+        // Check for hash set hits.
+        TskBlackboard &blackBoard = TskServices::Instance().getBlackboard();
+        TskImgDB& imageDB = TskServices::Instance().getImgDB();
+        bool hashSetHit = false;
+        try {
+            std::string md5 = pFile->getHash(TskImgDB::MD5); 
+
+            // Check for known bad files hash set hits. If a hit occurs, mark the file as IMGDB_FILES_KNOWN_BAD
+            // and post the hit to the blackboard.
+            for (std::vector<TSK_HDB_INFO*>::iterator it = knownBadHashDBInfos.begin(); it < knownBadHashDBInfos.end(); ++it) {
+                if (tsk_hdb_lookup_str(*it, md5.c_str(), TSK_HDB_FLAG_QUICK, NULL, NULL)) {
+                    if (!hashSetHit) {
+                        imageDB.updateKnownStatus(pFile->getId(), TskImgDB::IMGDB_FILES_KNOWN_BAD);
+                        hashSetHit = true;
+                    }
+                    TskBlackboardArtifact artifact = blackBoard.createArtifact(pFile->getId(), TSK_HASHSET_HIT);
+                    TskBlackboardAttribute attribute(TSK_SET_NAME, "TskHashLookupModule", "", (*it)->db_name);
+                    artifact.addAttribute(attribute);
+                }
+            }
+
+            // If there were no known bad file hits, check for a known file hash set hit. if a hit occurs, 
+            // mark the file as IMGDB_FILES_KNOWN and post the hit to the blackboard.
+            if (knownHashDBInfo && !hashSetHit && tsk_hdb_lookup_str(knownHashDBInfo, md5.c_str(), TSK_HDB_FLAG_QUICK, NULL, NULL)) {
+                imageDB.updateKnownStatus(pFile->getId(), TskImgDB::IMGDB_FILES_KNOWN);
+                hashSetHit = true;
+                TskBlackboardArtifact artifact = blackBoard.createArtifact(pFile->getId(), TSK_HASHSET_HIT);
+                TskBlackboardAttribute attribute(TSK_SET_NAME, "TskHashLookupModule", "", knownHashDBInfo->db_name);
+                artifact.addAttribute(attribute);
+            }
+        }
+        catch (TskException& ex) {
+            std::wstringstream msg;
+            msg << L"TskHashLookupModule::run - error on lookup for file id " << pFile->getId() << L": " << ex.what();
+            LOGERROR(msg.str());
+            return TskModule::FAIL;
+        }
+
+        return hashSetHit && issueStopRequestsOnHits ? TskModule::STOP : TskModule::OK;
+    }
+
+    /**
+     * Module cleanup function that closes the hash database index files.
+     *
+     * @returns TskModule::OK 
+     */
+    TskModule::Status TSK_MODULE_EXPORT finalize() 
+    {
+        if (knownHashDBInfo != NULL)
+            tsk_hdb_close(knownHashDBInfo); // Closes the index file and frees the memory for the TSK_HDB_INFO struct. 
+
+        for (std::vector<TSK_HDB_INFO*>::iterator it = knownBadHashDBInfos.begin(); it < knownBadHashDBInfos.end(); ++it)
+            tsk_hdb_close(*it); // Closes the index file and frees the memory for the TSK_HDB_INFO struct.
+
+        return TskModule::OK;
+    }
+}
diff --git a/framework/modules/c_ZIPExtractionModule/NEWS.txt b/framework/modules/c_ZIPExtractionModule/NEWS.txt
index 000c8cf..f96b74d 100644
--- a/framework/modules/c_ZIPExtractionModule/NEWS.txt
+++ b/framework/modules/c_ZIPExtractionModule/NEWS.txt
@@ -1,9 +1,9 @@
-Numbers refer to github.net issue #s:
-    https://github.com/sleuthkit/c_ZIPExtractionModule/issues
-
----------------- VERSION 1.0.0 --------------
-New Features:
-- Initial public release.
-
-Bug Fixes:
-- N/A. 
+Numbers refer to github.net issue #s:
+    https://github.com/sleuthkit/c_ZIPExtractionModule/issues
+
+---------------- VERSION 1.0.0 --------------
+New Features:
+- Initial public release.
+
+Bug Fixes:
+- N/A. 
diff --git a/framework/modules/c_ZIPExtractionModule/README.txt b/framework/modules/c_ZIPExtractionModule/README.txt
index 829fe38..5790b4c 100644
--- a/framework/modules/c_ZIPExtractionModule/README.txt
+++ b/framework/modules/c_ZIPExtractionModule/README.txt
@@ -1,33 +1,33 @@
-Zip Exraction Module
-Sleuth Kit Framework C++ Module
-May 2012
-
-
-This module is for the C++ Sleuth Kit Framework.
-
-
-DESCRIPTION
-
-This module extracts the files stored inside of ZIP files. This
-enables you to find all possible files with evidence. Files 
-extracted from ZIP files are scheduled so that they can later be
-analyzed in a file analysis pipeline.
-
-DEPLOYMENT REQUIREMENTS
-
-This module does not have any specific deployment requirements.
-
-USAGE
-
-Add this module to a file analysis pipeline.  See the TSK 
-Framework documents for information on adding the module 
-to the pipeline:
-
-    http://www.sleuthkit.org/sleuthkit/docs/framework-docs/
-
-This module takes no configuration arguments.  
-
-RESULTS
-
-The files are extracted, added to the database, and scheduled
+Zip Exraction Module
+Sleuth Kit Framework C++ Module
+May 2012
+
+
+This module is for the C++ Sleuth Kit Framework.
+
+
+DESCRIPTION
+
+This module extracts the files stored inside of ZIP files. This
+enables you to find all possible files with evidence. Files 
+extracted from ZIP files are scheduled so that they can later be
+analyzed in a file analysis pipeline.
+
+DEPLOYMENT REQUIREMENTS
+
+This module does not have any specific deployment requirements.
+
+USAGE
+
+Add this module to a file analysis pipeline.  See the TSK 
+Framework documents for information on adding the module 
+to the pipeline:
+
+    http://www.sleuthkit.org/sleuthkit/docs/framework-docs/
+
+This module takes no configuration arguments.  
+
+RESULTS
+
+The files are extracted, added to the database, and scheduled
 for analysis. 
\ No newline at end of file
diff --git a/framework/modules/c_ZIPExtractionModule/ZipExtractionModule.cpp b/framework/modules/c_ZIPExtractionModule/ZipExtractionModule.cpp
index 8bc0e85..d0afd75 100644
--- a/framework/modules/c_ZIPExtractionModule/ZipExtractionModule.cpp
+++ b/framework/modules/c_ZIPExtractionModule/ZipExtractionModule.cpp
@@ -1,376 +1,376 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file ZipExtractionModule.cpp
- * Contains the implementation for the Zip extraction file analysis module.
- * This module extracts zip file content and creates entries in the database 
- * for the extracted files. 
- */
-
-// System includes
-#include <sstream>
-#include <iostream>
-#include <fstream>
-
-// Poco includes
-#include "Poco/Path.h"
-#include "Poco/Zip/ZipStream.h"
-#include "Poco/Zip/Decompress.h"
-
-// Framework includes
-#include "tsk/framework/utilities/TskModuleDev.h"
-
-namespace
-{
-    const char *MODULE_NAME = "tskZipExtractionModule";
-    const char *MODULE_DESCRIPTION = "Extracts the files stored inside of ZIP files";
-    const char *MODULE_VERSION = "1.0.0";
-}
-
-namespace
-{
-    std::set<uint64_t> fileIdsToSchedule;
-
-    /**
-     * Schedule files for analysis. Iterates over the fileIdsToSchedule
-     * set calling Scheduler::schedule() for each consecutive range of
-     * file ids.
-     */
-    void scheduleFiles()
-    {
-        if (fileIdsToSchedule.empty())
-            return;
-
-        Scheduler& scheduler = TskServices::Instance().getScheduler();
-
-        std::set<uint64_t>::const_iterator it = fileIdsToSchedule.begin();
-        uint64_t startId = *it, endId = *it;
-
-        while (++it != fileIdsToSchedule.end())
-        {
-            if (*it > endId + 1)
-            {
-                scheduler.schedule(Scheduler::FileAnalysis, startId, endId);
-                startId = endId = *it;
-            }
-            else
-            {
-                endId++;
-            }
-        }
-
-        scheduler.schedule(Scheduler::FileAnalysis, startId, endId);
-        fileIdsToSchedule.clear();
-    }
-}
-
-/**
- * Get the file id corresponding to the last directory on the given path.
- * If elements along the path have not been seen before, create new entries
- * for those elements both in the database and in the directory map (3rd parameter). 
- * Note that the parent id for top level directories will be the file id of the zip file.
- */
-static uint64_t getParentIdForPath(Poco::Path& path, const uint64_t fileId, std::string parentPath, std::map<std::string, uint64_t>& directoryMap)
-{
-    // If the path references a file, make it refer to to its parent instead
-    if (path.isFile())
-        path = path.makeParent();
-
-    // Initialize parent id to be the file id of the zip file.
-    uint64_t parentId = fileId;
-
-    // Iterate over every element of the path checking to see if we 
-    // already have an entry in the database and in the directory map.
-    Poco::Path tempPath;
-    TskImgDB& imgDB = TskServices::Instance().getImgDB();
-    std::map<std::string, uint64_t>::const_iterator pos;
-    for (int i = 0; i < path.depth(); i++)
-    {
-        // Build up a temporary path that only contains the path
-        // elements seen so far. This temporary path will be used
-        // below to add the full path to the map.
-        tempPath.pushDirectory(path[i]);
-
-        // Have we already seen this path?
-        pos = directoryMap.find(tempPath.toString());
-
-        if (pos == directoryMap.end())
-        {
-			std::string fullpath = "";
-            fullpath.append(parentPath);
-            fullpath.append("\\");
-            fullpath.append(path.toString());
-
-            // No entry exists for this directory so we create one.
-            if (imgDB.addDerivedFileInfo(path[i], parentId,
-                                         true, // isDirectory
-                                         0, // uncompressed size
-                                         "", // no details
-                                         0, // ctime
-                                         0, // crtime
-                                         0, // atime
-                                         0, // mtime
-                                         parentId,
-                                         fullpath) == -1)
-            {
-                throw TskException("ZipExtraction::getParentIdForPath : Failed to add derived file for " + path[i]);
-            }
-
-            // Add the full path (to this point) and new id to the map.
-            directoryMap[tempPath.toString()] = parentId;
-
-            // Update file status to indicate that it is ready for analysis.
-            imgDB.updateFileStatus(parentId, TskImgDB::IMGDB_FILES_STATUS_READY_FOR_ANALYSIS);
-            fileIdsToSchedule.insert(parentId);
-        }
-        else
-        {
-            parentId = pos->second;
-        }
-    }
-
-    return parentId;
-}
-
-extern "C" 
-{
-    /**
-     * Module identification function. 
-     *
-     * @return The name of the module.
-     */
-    TSK_MODULE_EXPORT const char *name()
-    {
-        return MODULE_NAME;
-    }
-
-    /**
-     * Module identification function. 
-     *
-     * @return A description of the module.
-     */
-    TSK_MODULE_EXPORT const char *description()
-    {
-        return MODULE_DESCRIPTION;
-    }
-
-    /**
-     * Module identification function. 
-     *
-     * @return The version of the module.
-     */
-    TSK_MODULE_EXPORT const char *version()
-    {
-        return MODULE_VERSION;
-    }
-
-    /**
-     * Module initialization function. Receives a string of intialization arguments, 
-     * typically read by the caller from a pipeline configuration file. 
-     * Returns TskModule::OK or TskModule::FAIL. Returning TskModule::FAIL indicates 
-     * the module is not in an operational state.  
-     *
-     * @param args Initialization arguments.
-     * @return TskModule::OK if initialization succeeded, otherwise TskModule::FAIL.
-     */
-    TskModule::Status TSK_MODULE_EXPORT initialize(const char* args)
-    {
-        return TskModule::OK;
-    }
-    
-    /**
-     * Module execution function. Receives a pointer to a file the module is to
-     * process. The file is represented by a TskFile interface from which both
-     * file content and file metadata can be retrieved. Returns TskModule::OK, 
-     * TskModule::FAIL, or TskModule::STOP. Returning TskModule::FAIL indicates 
-     * the module experienced an error processing the file. Returning TskModule::STOP
-     * is a request to terminate processing of the file.
-     *
-     * @param pFile A pointer to a file to be processed.
-     * @returns TskModule::OK on success, TskModule::FAIL on error, or TskModule::STOP.
-     */
-    TskModule::Status TSK_MODULE_EXPORT run(TskFile * pFile)
-    {
-        if (pFile == NULL)
-        {
-            LOGERROR(L"Zip extraction module passed NULL file pointer.");
-            return TskModule::FAIL;
-        }
-
-        try
-        {
-            TskImgDB& imgDB = TskServices::Instance().getImgDB();
-
-			// Create a map of directory names to file ids to use to 
-			// associate files/directories with the correct parent.
-			std::map<std::string, uint64_t> directoryMap;
-            uint64_t parentId = 0;
-
-            // Save the file to disk and attempt to open it as an archive file.
-            pFile->save();
-            std::ifstream input(pFile->getPath().c_str(), std::ios_base::binary);
-            Poco::Zip::ZipArchive archive(input);
-            Poco::Zip::ZipArchive::FileHeaders::const_iterator fh;
-
-            // Attempt to extract the files contained in the archive file.
-            for (fh = archive.headerBegin(); fh != archive.headerEnd(); ++fh)
-            {
-                Poco::Path path(fh->first);
-                Poco::Path parent = path.parent();
-                std::string name;
-
-                if (path.isDirectory())
-                    name = path[path.depth() - 1];
-                else
-                    name = path[path.depth()];
-
-                // Determine the parent id of the file.
-                if (path.depth() == 0 || (path.isDirectory() && path.depth() == 1))
-                    // This file or directory lives at the root so our parent id
-                    // is the containing file id.
-                    parentId = pFile->getId();
-                else
-                {
-                    // We are not at the root so we need to lookup the id of our
-                    // parent directory.
-                    std::map<std::string, uint64_t>::const_iterator pos;
-                    pos = directoryMap.find(parent.toString());
-
-                    if (pos == directoryMap.end())
-                    {
-                        // In certain circumstances (Windows Send to zip and .docx files)
-                        // there may not be entries in the zip file for directories.
-                        // For these cases we create database entries for the directories
-                        // so that we can accurately track parent relationships. The
-                        // getParentIdForPath() method creates the database entries for the
-                        // given path and returns the parentId of the last directory on the path.
-                        parentId = getParentIdForPath(parent, pFile->getId(), pFile->getFullPath(), directoryMap);
-                    }
-                    else
-                    {
-                        parentId = pos->second;
-                    }
-                }
-
-                // Store some extra details about the derived (i.e, extracted) file.
-                std::stringstream details;
-                details << "<ZIPFILE name=\"" << fh->second.getFileName()
-                    << "\" compressed_size=\"" << fh->second.getCompressedSize()
-                    << "\" uncompressed_size=\"" << fh->second.getUncompressedSize()
-                    << "\" crc=\"" << fh->second.getCRC()
-                    << "\" start_pos=\"" << fh->second.getStartPos()
-                    << "\" end_pos=\"" << fh->second.getEndPos()
-                    << "\" major_version=\"" << fh->second.getMajorVersionNumber()
-                    << "\" minor_version=\"" << fh->second.getMinorVersionNumber() << "\""
-                    << "</ZIPFILE>";
-
-                uint64_t fileId;
-
-                std::string fullpath = "";
-                fullpath.append(pFile->getFullPath());
-                fullpath.append("\\");
-                fullpath.append(path.toString());
-
-                if (imgDB.addDerivedFileInfo(name,
-                    parentId,
-                    path.isDirectory(),
-                    fh->second.getUncompressedSize(),
-                    details.str(), 
-                    0, // ctime
-                    0, // crtime
-                    0, // atime
-                    static_cast<int>(fh->second.lastModifiedAt().utcTime()),
-                    fileId, fullpath) == -1) 
-                {
-                        std::wstringstream msg;
-                        msg << L"ZipExtractionModule - addDerivedFileInfo failed for name="
-                            << name.c_str();
-                        LOGERROR(msg.str());
-
-                        return TskModule::FAIL;
-                }
-
-                TskImgDB::FILE_STATUS fileStatus = TskImgDB::IMGDB_FILES_STATUS_READY_FOR_ANALYSIS;
-
-                if (path.isDirectory())
-                {
-                    directoryMap[path.toString()] = fileId;
-                }
-                else
-                {
-                    // Only DEFLATE and STORE compression methods are supported. The STORE method
-                    // simply stores a file without compression.
-                    if (fh->second.getCompressionMethod() == Poco::Zip::ZipCommon::CM_DEFLATE ||
-                        fh->second.getCompressionMethod() == Poco::Zip::ZipCommon::CM_STORE)
-                    {
-                        // Save the file for subsequent processing.
-                        Poco::Zip::ZipInputStream zipin(input, fh->second);
-                        TskServices::Instance().getFileManager().addFile(fileId, zipin);
-                    }
-                    else
-                    {
-                        std::wstringstream msg;
-                        msg << L"ZipExtractionModule - Unsupported compression method for file: "
-                            << name.c_str();
-                        LOGWARN(msg.str());
-                        
-                        fileStatus = TskImgDB::IMGDB_FILES_STATUS_ANALYSIS_FAILED;
-                    }
-                }
-
-                // Update file status to indicate that it is ready for analysis.
-                imgDB.updateFileStatus(fileId, fileStatus);
-                fileIdsToSchedule.insert(fileId);
-            }
-
-            // Schedule files for analysis
-            scheduleFiles();
-        }
-        catch (Poco::IllegalStateException&)
-        {
-            // Poco::IllegalStateException is thrown if the file is not a valid zip file
-            // so we simply skip the file.
-            return TskModule::OK;
-        }
-        catch (Poco::AssertionViolationException&)
-        {
-            // Corrupt zip files are not uncommon, especially for carved files.
-            std::wstringstream msg;
-            msg << L"ZipExtractionModule - Encountered corrupt zip file ( " << pFile->getName().c_str()
-                << L")";
-            LOGWARN(msg.str());
-
-            return TskModule::FAIL;
-        }
-        catch (std::exception& ex)
-        {
-            std::wstringstream msg;
-            msg << L"ZipExtractionModule - Error processing zip file ( " << pFile->getName().c_str()
-                << L") : " << ex.what();
-            LOGERROR(msg.str());
-
-            return TskModule::FAIL;
-        }
-
-        return TskModule::OK;
-    }
-
-    /**
-     * Module cleanup function. This is where the module should free any resources 
-     * allocated during initialization or execution.
-     *
-     * @returns TskModule::OK on success and TskModule::FAIL on error.
-     */
-    TskModule::Status TSK_MODULE_EXPORT finalize()
-    {
-        return TskModule::OK;
-    }
-}
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file ZipExtractionModule.cpp
+ * Contains the implementation for the Zip extraction file analysis module.
+ * This module extracts zip file content and creates entries in the database 
+ * for the extracted files. 
+ */
+
+// System includes
+#include <sstream>
+#include <iostream>
+#include <fstream>
+
+// Poco includes
+#include "Poco/Path.h"
+#include "Poco/Zip/ZipStream.h"
+#include "Poco/Zip/Decompress.h"
+
+// Framework includes
+#include "tsk/framework/utilities/TskModuleDev.h"
+
+namespace
+{
+    const char *MODULE_NAME = "tskZipExtractionModule";
+    const char *MODULE_DESCRIPTION = "Extracts the files stored inside of ZIP files";
+    const char *MODULE_VERSION = "1.0.0";
+}
+
+namespace
+{
+    std::set<uint64_t> fileIdsToSchedule;
+
+    /**
+     * Schedule files for analysis. Iterates over the fileIdsToSchedule
+     * set calling Scheduler::schedule() for each consecutive range of
+     * file ids.
+     */
+    void scheduleFiles()
+    {
+        if (fileIdsToSchedule.empty())
+            return;
+
+        Scheduler& scheduler = TskServices::Instance().getScheduler();
+
+        std::set<uint64_t>::const_iterator it = fileIdsToSchedule.begin();
+        uint64_t startId = *it, endId = *it;
+
+        while (++it != fileIdsToSchedule.end())
+        {
+            if (*it > endId + 1)
+            {
+                scheduler.schedule(Scheduler::FileAnalysis, startId, endId);
+                startId = endId = *it;
+            }
+            else
+            {
+                endId++;
+            }
+        }
+
+        scheduler.schedule(Scheduler::FileAnalysis, startId, endId);
+        fileIdsToSchedule.clear();
+    }
+}
+
+/**
+ * Get the file id corresponding to the last directory on the given path.
+ * If elements along the path have not been seen before, create new entries
+ * for those elements both in the database and in the directory map (3rd parameter). 
+ * Note that the parent id for top level directories will be the file id of the zip file.
+ */
+static uint64_t getParentIdForPath(Poco::Path& path, const uint64_t fileId, std::string parentPath, std::map<std::string, uint64_t>& directoryMap)
+{
+    // If the path references a file, make it refer to to its parent instead
+    if (path.isFile())
+        path = path.makeParent();
+
+    // Initialize parent id to be the file id of the zip file.
+    uint64_t parentId = fileId;
+
+    // Iterate over every element of the path checking to see if we 
+    // already have an entry in the database and in the directory map.
+    Poco::Path tempPath;
+    TskImgDB& imgDB = TskServices::Instance().getImgDB();
+    std::map<std::string, uint64_t>::const_iterator pos;
+    for (int i = 0; i < path.depth(); i++)
+    {
+        // Build up a temporary path that only contains the path
+        // elements seen so far. This temporary path will be used
+        // below to add the full path to the map.
+        tempPath.pushDirectory(path[i]);
+
+        // Have we already seen this path?
+        pos = directoryMap.find(tempPath.toString());
+
+        if (pos == directoryMap.end())
+        {
+			std::string fullpath = "";
+            fullpath.append(parentPath);
+            fullpath.append("\\");
+            fullpath.append(path.toString());
+
+            // No entry exists for this directory so we create one.
+            if (imgDB.addDerivedFileInfo(path[i], parentId,
+                                         true, // isDirectory
+                                         0, // uncompressed size
+                                         "", // no details
+                                         0, // ctime
+                                         0, // crtime
+                                         0, // atime
+                                         0, // mtime
+                                         parentId,
+                                         fullpath) == -1)
+            {
+                throw TskException("ZipExtraction::getParentIdForPath : Failed to add derived file for " + path[i]);
+            }
+
+            // Add the full path (to this point) and new id to the map.
+            directoryMap[tempPath.toString()] = parentId;
+
+            // Update file status to indicate that it is ready for analysis.
+            imgDB.updateFileStatus(parentId, TskImgDB::IMGDB_FILES_STATUS_READY_FOR_ANALYSIS);
+            fileIdsToSchedule.insert(parentId);
+        }
+        else
+        {
+            parentId = pos->second;
+        }
+    }
+
+    return parentId;
+}
+
+extern "C" 
+{
+    /**
+     * Module identification function. 
+     *
+     * @return The name of the module.
+     */
+    TSK_MODULE_EXPORT const char *name()
+    {
+        return MODULE_NAME;
+    }
+
+    /**
+     * Module identification function. 
+     *
+     * @return A description of the module.
+     */
+    TSK_MODULE_EXPORT const char *description()
+    {
+        return MODULE_DESCRIPTION;
+    }
+
+    /**
+     * Module identification function. 
+     *
+     * @return The version of the module.
+     */
+    TSK_MODULE_EXPORT const char *version()
+    {
+        return MODULE_VERSION;
+    }
+
+    /**
+     * Module initialization function. Receives a string of intialization arguments, 
+     * typically read by the caller from a pipeline configuration file. 
+     * Returns TskModule::OK or TskModule::FAIL. Returning TskModule::FAIL indicates 
+     * the module is not in an operational state.  
+     *
+     * @param args Initialization arguments.
+     * @return TskModule::OK if initialization succeeded, otherwise TskModule::FAIL.
+     */
+    TskModule::Status TSK_MODULE_EXPORT initialize(const char* args)
+    {
+        return TskModule::OK;
+    }
+    
+    /**
+     * Module execution function. Receives a pointer to a file the module is to
+     * process. The file is represented by a TskFile interface from which both
+     * file content and file metadata can be retrieved. Returns TskModule::OK, 
+     * TskModule::FAIL, or TskModule::STOP. Returning TskModule::FAIL indicates 
+     * the module experienced an error processing the file. Returning TskModule::STOP
+     * is a request to terminate processing of the file.
+     *
+     * @param pFile A pointer to a file to be processed.
+     * @returns TskModule::OK on success, TskModule::FAIL on error, or TskModule::STOP.
+     */
+    TskModule::Status TSK_MODULE_EXPORT run(TskFile * pFile)
+    {
+        if (pFile == NULL)
+        {
+            LOGERROR(L"Zip extraction module passed NULL file pointer.");
+            return TskModule::FAIL;
+        }
+
+        try
+        {
+            TskImgDB& imgDB = TskServices::Instance().getImgDB();
+
+			// Create a map of directory names to file ids to use to 
+			// associate files/directories with the correct parent.
+			std::map<std::string, uint64_t> directoryMap;
+            uint64_t parentId = 0;
+
+            // Save the file to disk and attempt to open it as an archive file.
+            pFile->save();
+            std::ifstream input(pFile->getPath().c_str(), std::ios_base::binary);
+            Poco::Zip::ZipArchive archive(input);
+            Poco::Zip::ZipArchive::FileHeaders::const_iterator fh;
+
+            // Attempt to extract the files contained in the archive file.
+            for (fh = archive.headerBegin(); fh != archive.headerEnd(); ++fh)
+            {
+                Poco::Path path(fh->first);
+                Poco::Path parent = path.parent();
+                std::string name;
+
+                if (path.isDirectory())
+                    name = path[path.depth() - 1];
+                else
+                    name = path[path.depth()];
+
+                // Determine the parent id of the file.
+                if (path.depth() == 0 || (path.isDirectory() && path.depth() == 1))
+                    // This file or directory lives at the root so our parent id
+                    // is the containing file id.
+                    parentId = pFile->getId();
+                else
+                {
+                    // We are not at the root so we need to lookup the id of our
+                    // parent directory.
+                    std::map<std::string, uint64_t>::const_iterator pos;
+                    pos = directoryMap.find(parent.toString());
+
+                    if (pos == directoryMap.end())
+                    {
+                        // In certain circumstances (Windows Send to zip and .docx files)
+                        // there may not be entries in the zip file for directories.
+                        // For these cases we create database entries for the directories
+                        // so that we can accurately track parent relationships. The
+                        // getParentIdForPath() method creates the database entries for the
+                        // given path and returns the parentId of the last directory on the path.
+                        parentId = getParentIdForPath(parent, pFile->getId(), pFile->getFullPath(), directoryMap);
+                    }
+                    else
+                    {
+                        parentId = pos->second;
+                    }
+                }
+
+                // Store some extra details about the derived (i.e, extracted) file.
+                std::stringstream details;
+                details << "<ZIPFILE name=\"" << fh->second.getFileName()
+                    << "\" compressed_size=\"" << fh->second.getCompressedSize()
+                    << "\" uncompressed_size=\"" << fh->second.getUncompressedSize()
+                    << "\" crc=\"" << fh->second.getCRC()
+                    << "\" start_pos=\"" << fh->second.getStartPos()
+                    << "\" end_pos=\"" << fh->second.getEndPos()
+                    << "\" major_version=\"" << fh->second.getMajorVersionNumber()
+                    << "\" minor_version=\"" << fh->second.getMinorVersionNumber() << "\""
+                    << "</ZIPFILE>";
+
+                uint64_t fileId;
+
+                std::string fullpath = "";
+                fullpath.append(pFile->getFullPath());
+                fullpath.append("\\");
+                fullpath.append(path.toString());
+
+                if (imgDB.addDerivedFileInfo(name,
+                    parentId,
+                    path.isDirectory(),
+                    fh->second.getUncompressedSize(),
+                    details.str(), 
+                    0, // ctime
+                    0, // crtime
+                    0, // atime
+                    static_cast<int>(fh->second.lastModifiedAt().utcTime()),
+                    fileId, fullpath) == -1) 
+                {
+                        std::wstringstream msg;
+                        msg << L"ZipExtractionModule - addDerivedFileInfo failed for name="
+                            << name.c_str();
+                        LOGERROR(msg.str());
+
+                        return TskModule::FAIL;
+                }
+
+                TskImgDB::FILE_STATUS fileStatus = TskImgDB::IMGDB_FILES_STATUS_READY_FOR_ANALYSIS;
+
+                if (path.isDirectory())
+                {
+                    directoryMap[path.toString()] = fileId;
+                }
+                else
+                {
+                    // Only DEFLATE and STORE compression methods are supported. The STORE method
+                    // simply stores a file without compression.
+                    if (fh->second.getCompressionMethod() == Poco::Zip::ZipCommon::CM_DEFLATE ||
+                        fh->second.getCompressionMethod() == Poco::Zip::ZipCommon::CM_STORE)
+                    {
+                        // Save the file for subsequent processing.
+                        Poco::Zip::ZipInputStream zipin(input, fh->second);
+                        TskServices::Instance().getFileManager().addFile(fileId, zipin);
+                    }
+                    else
+                    {
+                        std::wstringstream msg;
+                        msg << L"ZipExtractionModule - Unsupported compression method for file: "
+                            << name.c_str();
+                        LOGWARN(msg.str());
+                        
+                        fileStatus = TskImgDB::IMGDB_FILES_STATUS_ANALYSIS_FAILED;
+                    }
+                }
+
+                // Update file status to indicate that it is ready for analysis.
+                imgDB.updateFileStatus(fileId, fileStatus);
+                fileIdsToSchedule.insert(fileId);
+            }
+
+            // Schedule files for analysis
+            scheduleFiles();
+        }
+        catch (Poco::IllegalStateException&)
+        {
+            // Poco::IllegalStateException is thrown if the file is not a valid zip file
+            // so we simply skip the file.
+            return TskModule::OK;
+        }
+        catch (Poco::AssertionViolationException&)
+        {
+            // Corrupt zip files are not uncommon, especially for carved files.
+            std::wstringstream msg;
+            msg << L"ZipExtractionModule - Encountered corrupt zip file ( " << pFile->getName().c_str()
+                << L")";
+            LOGWARN(msg.str());
+
+            return TskModule::FAIL;
+        }
+        catch (std::exception& ex)
+        {
+            std::wstringstream msg;
+            msg << L"ZipExtractionModule - Error processing zip file ( " << pFile->getName().c_str()
+                << L") : " << ex.what();
+            LOGERROR(msg.str());
+
+            return TskModule::FAIL;
+        }
+
+        return TskModule::OK;
+    }
+
+    /**
+     * Module cleanup function. This is where the module should free any resources 
+     * allocated during initialization or execution.
+     *
+     * @returns TskModule::OK on success and TskModule::FAIL on error.
+     */
+    TskModule::Status TSK_MODULE_EXPORT finalize()
+    {
+        return TskModule::OK;
+    }
+}
diff --git a/framework/msvcpp/Makefile b/framework/msvcpp/Makefile
index 9de593d..372a262 100755
--- a/framework/msvcpp/Makefile
+++ b/framework/msvcpp/Makefile
@@ -1,77 +1,77 @@
-BUILDLOG = BuildLog.txt
-RM	= rm -f
-MORE	= cat
-MSBUILD	= msbuild.exe
-
-TSK_SOLN = "$(TSK_HOME)\win32\tsk-win.sln"
-EWF_SOLN = "$(LIBEWF_HOME)\msvscpp\libewf.sln"
-FRMWK_SOLN = "$(TSK_HOME)\framework\msvcpp\framework\framework.sln"
-POCO_SOLN = "$(POCO_HOME)\Foundation\Foundation_vs100.sln"
-POCO_UTIL_SOLN = "$(POCO_HOME)\Util\Util_vs100.sln"
-POCO_XML_SOLN = "$(POCO_HOME)\XML\XML_vs100.sln"
-POCO_NET_SOLN = "$(POCO_HOME)\Net\Net_vs100.sln"
-POCO_ZIP_SOLN = "$(POCO_HOME)\Zip\Zip_vs100.sln"
-
-RELEASE_FLAGS = "/property:Configuration=Release"
-DEBUG_FLAGS = "/property:Configuration=Debug"
-POCO_RELEASE_FLAGS = "/property:Configuration=release_shared"
-POCO_DEBUG_FLAGS = "/property:Configuration=debug_shared"
-
-LOGFILE_FLAGS = "/fileloggerparameters:logfile=$(BUILDLOG);Append;Verbosity=detailed"
-
-all:	debug
-
-usage:
-    @echo Usage: nmake [poco ^| libewf ^| all_deps ^| debug ^| release ^| clean ^| spotless]
-    @echo "   poco: Builds debug and release versions of Poco libraries"
-    @echo "   libewf: Builds release version of libewf_dll and zlib"
-    @echo "   all_deps: Builds all dependencies (i.e. Poco, libewf and zlib)"
-    @echo "   release: Builds release versions of libtsk and libtskframework"
-    @echo "   debug: Builds debug versions of libtsk and libtskframework"
-    @echo "   clean: Cleans debug and release versions of libtsk and libtskframework"
-    @echo "   spotless: Cleans libtsk, libtskframework, libewf, zlib and Poco."
-
-poco:
-	$(MSBUILD)  $(POCO_SOLN) /target:Foundation $(POCO_DEBUG_FLAGS) $(LOGFILE_FLAGS)
-	$(MSBUILD)  $(POCO_XML_SOLN) /target:XML $(POCO_DEBUG_FLAGS) $(LOGFILE_FLAGS)
-	$(MSBUILD)  $(POCO_NET_SOLN) /target:Net $(POCO_DEBUG_FLAGS) $(LOGFILE_FLAGS)
-	$(MSBUILD)  $(POCO_ZIP_SOLN) /target:Zip $(POCO_DEBUG_FLAGS) $(LOGFILE_FLAGS)
-	$(MSBUILD)  $(POCO_UTIL_SOLN) /target:Util $(POCO_DEBUG_FLAGS) $(LOGFILE_FLAGS)
-	$(MSBUILD)  $(POCO_SOLN) /target:Foundation $(POCO_RELEASE_FLAGS) $(LOGFILE_FLAGS)
-	$(MSBUILD)  $(POCO_XML_SOLN) /target:XML $(POCO_RELEASE_FLAGS) $(LOGFILE_FLAGS)
-	$(MSBUILD)  $(POCO_NET_SOLN) /target:Net $(POCO_RELEASE_FLAGS) $(LOGFILE_FLAGS)
-	$(MSBUILD)  $(POCO_ZIP_SOLN) /target:Zip $(POCO_RELEASE_FLAGS) $(LOGFILE_FLAGS)
-	$(MSBUILD)  $(POCO_UTIL_SOLN) /target:Util $(POCO_RELEASE_FLAGS) $(LOGFILE_FLAGS)
-
-libewf:
-	$(MSBUILD)  $(EWF_SOLN) /target:libewf_dll $(RELEASE_FLAGS) $(LOGFILE_FLAGS)
-    
-all_deps: poco libewf
-
-release: all_deps
-	$(MSBUILD)  $(TSK_SOLN) /target:libtsk $(RELEASE_FLAGS) $(LOGFILE_FLAGS)
-	$(MSBUILD)  $(FRMWK_SOLN) $(RELEASE_FLAGS) $(LOGFILE_FLAGS)
-
-debug: all_deps
-	$(MSBUILD)  $(TSK_SOLN) /target:libtsk $(DEBUG_FLAGS) $(LOGFILE_FLAGS)
-	$(MSBUILD)  $(FRMWK_SOLN) $(DEBUG_FLAGS) $(LOGFILE_FLAGS)
-
-clean:
-    $(RM) $(BUILDLOG)
-	$(MSBUILD) $(TSK_SOLN) /target:Clean $(DEBUG_FLAGS)
-	$(MSBUILD) $(FRMWK_SOLN) /target:Clean $(DEBUG_FLAGS)
-	$(MSBUILD) $(TSK_SOLN) /target:Clean $(RELEASE_FLAGS)
-	$(MSBUILD) $(FRMWK_SOLN) /target:Clean $(RELEASE_FLAGS)
-
-spotless: clean
-	$(MSBUILD) $(EWF_SOLN) /target:Clean $(RELEASE_FLAGS)
-	$(MSBUILD) $(POCO_SOLN) /target:Clean $(POCO_DEBUG_FLAGS)
-	$(MSBUILD) $(POCO_XML_SOLN) /target:Clean $(POCO_DEBUG_FLAGS)
-	$(MSBUILD) $(POCO_NET_SOLN) /target:Clean $(POCO_DEBUG_FLAGS)
-	$(MSBUILD) $(POCO_ZIP_SOLN) /target:Clean $(POCO_DEBUG_FLAGS)
-	$(MSBUILD) $(POCO_UTIL_SOLN) /target:Clean $(POCO_DEBUG_FLAGS)
-	$(MSBUILD) $(POCO_SOLN) /target:Clean $(POCO_RELEASE_FLAGS)
-	$(MSBUILD) $(POCO_XML_SOLN) /target:Clean $(POCO_RELEASE_FLAGS)
-	$(MSBUILD) $(POCO_NET_SOLN) /target:Clean $(POCO_RELEASE_FLAGS)
-	$(MSBUILD) $(POCO_ZIP_SOLN) /target:Clean $(POCO_RELEASE_FLAGS)
-	$(MSBUILD) $(POCO_UTIL_SOLN) /target:Clean $(POCO_RELEASE_FLAGS)
+BUILDLOG = BuildLog.txt
+RM	= rm -f
+MORE	= cat
+MSBUILD	= msbuild.exe
+
+TSK_SOLN = "$(TSK_HOME)\win32\tsk-win.sln"
+EWF_SOLN = "$(LIBEWF_HOME)\msvscpp\libewf.sln"
+FRMWK_SOLN = "$(TSK_HOME)\framework\msvcpp\framework\framework.sln"
+POCO_SOLN = "$(POCO_HOME)\Foundation\Foundation_vs100.sln"
+POCO_UTIL_SOLN = "$(POCO_HOME)\Util\Util_vs100.sln"
+POCO_XML_SOLN = "$(POCO_HOME)\XML\XML_vs100.sln"
+POCO_NET_SOLN = "$(POCO_HOME)\Net\Net_vs100.sln"
+POCO_ZIP_SOLN = "$(POCO_HOME)\Zip\Zip_vs100.sln"
+
+RELEASE_FLAGS = "/property:Configuration=Release"
+DEBUG_FLAGS = "/property:Configuration=Debug"
+POCO_RELEASE_FLAGS = "/property:Configuration=release_shared"
+POCO_DEBUG_FLAGS = "/property:Configuration=debug_shared"
+
+LOGFILE_FLAGS = "/fileloggerparameters:logfile=$(BUILDLOG);Append;Verbosity=detailed"
+
+all:	debug
+
+usage:
+    @echo Usage: nmake [poco ^| libewf ^| all_deps ^| debug ^| release ^| clean ^| spotless]
+    @echo "   poco: Builds debug and release versions of Poco libraries"
+    @echo "   libewf: Builds release version of libewf_dll and zlib"
+    @echo "   all_deps: Builds all dependencies (i.e. Poco, libewf and zlib)"
+    @echo "   release: Builds release versions of libtsk and libtskframework"
+    @echo "   debug: Builds debug versions of libtsk and libtskframework"
+    @echo "   clean: Cleans debug and release versions of libtsk and libtskframework"
+    @echo "   spotless: Cleans libtsk, libtskframework, libewf, zlib and Poco."
+
+poco:
+	$(MSBUILD)  $(POCO_SOLN) /target:Foundation $(POCO_DEBUG_FLAGS) $(LOGFILE_FLAGS)
+	$(MSBUILD)  $(POCO_XML_SOLN) /target:XML $(POCO_DEBUG_FLAGS) $(LOGFILE_FLAGS)
+	$(MSBUILD)  $(POCO_NET_SOLN) /target:Net $(POCO_DEBUG_FLAGS) $(LOGFILE_FLAGS)
+	$(MSBUILD)  $(POCO_ZIP_SOLN) /target:Zip $(POCO_DEBUG_FLAGS) $(LOGFILE_FLAGS)
+	$(MSBUILD)  $(POCO_UTIL_SOLN) /target:Util $(POCO_DEBUG_FLAGS) $(LOGFILE_FLAGS)
+	$(MSBUILD)  $(POCO_SOLN) /target:Foundation $(POCO_RELEASE_FLAGS) $(LOGFILE_FLAGS)
+	$(MSBUILD)  $(POCO_XML_SOLN) /target:XML $(POCO_RELEASE_FLAGS) $(LOGFILE_FLAGS)
+	$(MSBUILD)  $(POCO_NET_SOLN) /target:Net $(POCO_RELEASE_FLAGS) $(LOGFILE_FLAGS)
+	$(MSBUILD)  $(POCO_ZIP_SOLN) /target:Zip $(POCO_RELEASE_FLAGS) $(LOGFILE_FLAGS)
+	$(MSBUILD)  $(POCO_UTIL_SOLN) /target:Util $(POCO_RELEASE_FLAGS) $(LOGFILE_FLAGS)
+
+libewf:
+	$(MSBUILD)  $(EWF_SOLN) /target:libewf_dll $(RELEASE_FLAGS) $(LOGFILE_FLAGS)
+    
+all_deps: poco libewf
+
+release: all_deps
+	$(MSBUILD)  $(TSK_SOLN) /target:libtsk $(RELEASE_FLAGS) $(LOGFILE_FLAGS)
+	$(MSBUILD)  $(FRMWK_SOLN) $(RELEASE_FLAGS) $(LOGFILE_FLAGS)
+
+debug: all_deps
+	$(MSBUILD)  $(TSK_SOLN) /target:libtsk $(DEBUG_FLAGS) $(LOGFILE_FLAGS)
+	$(MSBUILD)  $(FRMWK_SOLN) $(DEBUG_FLAGS) $(LOGFILE_FLAGS)
+
+clean:
+    $(RM) $(BUILDLOG)
+	$(MSBUILD) $(TSK_SOLN) /target:Clean $(DEBUG_FLAGS)
+	$(MSBUILD) $(FRMWK_SOLN) /target:Clean $(DEBUG_FLAGS)
+	$(MSBUILD) $(TSK_SOLN) /target:Clean $(RELEASE_FLAGS)
+	$(MSBUILD) $(FRMWK_SOLN) /target:Clean $(RELEASE_FLAGS)
+
+spotless: clean
+	$(MSBUILD) $(EWF_SOLN) /target:Clean $(RELEASE_FLAGS)
+	$(MSBUILD) $(POCO_SOLN) /target:Clean $(POCO_DEBUG_FLAGS)
+	$(MSBUILD) $(POCO_XML_SOLN) /target:Clean $(POCO_DEBUG_FLAGS)
+	$(MSBUILD) $(POCO_NET_SOLN) /target:Clean $(POCO_DEBUG_FLAGS)
+	$(MSBUILD) $(POCO_ZIP_SOLN) /target:Clean $(POCO_DEBUG_FLAGS)
+	$(MSBUILD) $(POCO_UTIL_SOLN) /target:Clean $(POCO_DEBUG_FLAGS)
+	$(MSBUILD) $(POCO_SOLN) /target:Clean $(POCO_RELEASE_FLAGS)
+	$(MSBUILD) $(POCO_XML_SOLN) /target:Clean $(POCO_RELEASE_FLAGS)
+	$(MSBUILD) $(POCO_NET_SOLN) /target:Clean $(POCO_RELEASE_FLAGS)
+	$(MSBUILD) $(POCO_ZIP_SOLN) /target:Clean $(POCO_RELEASE_FLAGS)
+	$(MSBUILD) $(POCO_UTIL_SOLN) /target:Clean $(POCO_RELEASE_FLAGS)
diff --git a/framework/tools/tsk_analyzeimg/tsk_analyzeimg.cpp b/framework/tools/tsk_analyzeimg/tsk_analyzeimg.cpp
index 61140bc..789f382 100755
--- a/framework/tools/tsk_analyzeimg/tsk_analyzeimg.cpp
+++ b/framework/tools/tsk_analyzeimg/tsk_analyzeimg.cpp
@@ -1,451 +1,451 @@
-/*
-*
-*  The Sleuth Kit
-*
-*  Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
-*  Copyright (c) 2011-2012 Basis Technology Corporation. All Rights
-*  reserved.
-*
-*  This software is distributed under the Common Public License 1.0
-*/
-#include <iostream>
-#include <cstdio>
-#include <cstdlib>
-#include <string>
-#include <sstream>
-#include <time.h>
-#include <memory>
-
-#include "tsk/tsk_tools_i.h" // Needed for tsk_getopt
-#include "tsk/framework/framework.h"
-#include "tsk/framework/services/TskSchedulerQueue.h"
-#include "tsk/framework/services/TskSystemPropertiesImpl.h"
-#include "tsk/framework/services/TskImgDBSqlite.h"
-#include "tsk/framework/file/TskFileManagerImpl.h"
-#include "tsk/framework/extraction/TskCarvePrepSectorConcat.h"
-#include "tsk/framework/extraction/TskCarveExtractScalpel.h"
-#include "tsk/framework/extraction/TskExtract.h"
-
-#include "Poco/Path.h"
-#include "Poco/File.h"
-
-#ifdef TSK_WIN32
-#include <Windows.h>
-#else
-#include <sys/stat.h>
-#endif
-
-#include "Poco/File.h"
-#include "Poco/UnicodeConverter.h"
-
-static uint8_t 
-makeDir(const char *dir) 
-{
-    Poco::File path(dir);
-    try {
-        if (!path.createDirectory()) {
-            fprintf(stderr, "Error creating directory: %s\n", dir);
-            return 1;
-        }
-    } catch (const Poco::Exception &ex) {
-        std::stringstream msg;
-        msg << "Error creating directory: " << dir << " Poco exception: " << ex.displayText();
-        fprintf(stderr, "%s\n", msg.str().c_str());
-        return 1;
-    }
-    return 0;
-}
-
-/**
- * Logs all messages to a log file and prints
- * error messages to STDERR
- */
-class StderrLog : public Log
-{
-public:
-    StderrLog() : Log() {
-    }
-
-    ~StderrLog() {
-    }
-
-    void log(Channel a_channel, const std::wstring &a_msg)
-    {
-        Log::log(a_channel, a_msg);
-        if (a_channel != Error) {
-            return;
-        }
-        fprintf(stderr, "%S\n", a_msg.c_str());
-    }
-};
-
-void 
-usage(const char *program) 
-{
-    fprintf(stderr, "%s [-c framework_config_file] [-p pipeline_config_file] [-d outdir] [-C] [-v] [-V] [-L] image_name\n", program);
-    fprintf(stderr, "\t-c framework_config_file: Path to XML framework config file\n");
-    fprintf(stderr, "\t-p pipeline_config_file: Path to XML pipeline config file (overrides pipeline config specified with -c)\n");
-    fprintf(stderr, "\t-d outdir: Path to output directory\n");
-    fprintf(stderr, "\t-C: Disable carving, overriding framework config file settings\n");
-    fprintf(stderr, "\t-u: Enable unused sector file creation\n");
-    fprintf(stderr, "\t-v: Enable verbose mode to get more debug information\n");
-    fprintf(stderr, "\t-V: Display the tool version\n");
-    fprintf(stderr, "\t-L: Print no error messages to STDERR -- only log them\n");
-    exit(1);
-}
-
-int main(int argc, char **argv1)
-{
-    TSK_TCHAR **argv;
-    extern int OPTIND;
-    int ch;
-    std::string pipeline_config;
-    std::string framework_config;
-    std::string outDirPath;
-    bool suppressSTDERR = false;
-    bool doCarving = true;
-    bool createUnusedSectorFiles = false;
-
-#ifdef TSK_WIN32
-    // On Windows, get the wide arguments (mingw doesn't support wmain)
-    argv = CommandLineToArgvW(GetCommandLineW(), &argc);
-    if (argv == NULL) {
-        fprintf(stderr, "Error getting wide arguments\n");
-        exit(1);
-    }
-#else
-    argv = (TSK_TCHAR **) argv1;
-#endif
-
-    while ((ch =
-        GETOPT(argc, argv, _TSK_T("d:c:p:vuVLC"))) > 0) {
-        switch (ch) {
-        case _TSK_T('c'):
-#ifdef TSK_WIN32
-            framework_config.assign(TskUtilities::toUTF8(std::wstring(OPTARG)));
-#else
-            framework_config.assign(OPTARG);
-#endif
-            break;
-
-        case _TSK_T('p'):
-#ifdef TSK_WIN32
-            pipeline_config.assign(TskUtilities::toUTF8(std::wstring(OPTARG)));
-#else
-            pipeline_config.assign(OPTARG);
-#endif
-            break;
-        case _TSK_T('u'):
-            createUnusedSectorFiles = true;
-            break;
-        case _TSK_T('v'):
-            tsk_verbose++;
-            break;
-
-        case _TSK_T('V'):
-            tsk_version_print(stdout);
-            exit(0);
-            break;
-
-        case _TSK_T('d'):
-#ifdef TSK_WIN32
-            outDirPath.assign(TskUtilities::toUTF8(std::wstring(OPTARG)));
-#else
-            outDirPath.assign(OPTARG);
-#endif
-            break;
-
-        case _TSK_T('C'):
-            doCarving = false;
-            break;
-
-        case _TSK_T('L'):
-            suppressSTDERR = true;
-            break;
-
-        case _TSK_T('?'):
-        default:
-            TFPRINTF(stderr, _TSK_T("Invalid argument: %s\n"),
-                argv[OPTIND]);
-            usage(argv1[0]);
-        }
-    }
-
-    /* We need at least one more argument */
-    if (OPTIND == argc) {
-        tsk_fprintf(stderr, "Missing image name\n");
-        usage(argv1[0]);
-    }
-
-    std::string imagePath;
-#ifdef TSK_WIN32
-    imagePath = TskUtilities::toUTF8(std::wstring(argv[OPTIND]));
-#else
-    imagePath = argv1[OPTIND];
-#endif
-    
-    if (!Poco::File(imagePath).exists()) {
-        std::stringstream msg;
-        msg << "Image file not found: " << imagePath;
-        LOGERROR(msg.str());
-        return 1;
-    }
-
-    // Load the framework config if they specified it
-    try
-    {
-        // try the one specified on the command line
-        if (framework_config.size()) {
-            TskSystemPropertiesImpl *systemProperties = new TskSystemPropertiesImpl();
-            systemProperties->initialize(framework_config);
-            TskServices::Instance().setSystemProperties(*systemProperties);
-        }
-        // try the one in the current directory
-        else if (Poco::File("framework_config.xml").exists()) {
-            TskSystemPropertiesImpl *systemProperties = new TskSystemPropertiesImpl();
-            systemProperties->initialize("framework_config.xml");
-            TskServices::Instance().setSystemProperties(*systemProperties);
-        }
-        // try one back up a few directories for the use case that we built this in
-        // the source tree.
-        else {
-            TskSystemPropertiesImpl *systemProperties = new TskSystemPropertiesImpl();
-            systemProperties->initialize();
-            std::string progdir = systemProperties->get(TskSystemProperties::PROG_DIR);
-            std::string configPath = progdir + "../../../runtime/framework_config.xml";
-            if (Poco::File(configPath).exists()) {
-                systemProperties->initialize(configPath);
-                TskServices::Instance().setSystemProperties(*systemProperties);
-            } else {
-                fprintf(stderr, "No framework config file found\n");
-            }
-        }
-    }
-    catch (TskException& ex)
-    {
-        fprintf(stderr, "Loading framework config file: %s\n", ex.message().c_str());
-        return 1;
-    }
-
-    // if they didn't specify the output directory, make one
-    if (outDirPath == "") {
-        outDirPath.assign(imagePath);
-        outDirPath.append("_tsk_out");
-    }
-    if (Poco::File(outDirPath).exists()) {
-        std::stringstream msg;
-        msg << "Output directory already exists " << outDirPath;
-        LOGERROR(msg.str());
-        return 1;
-    }
-
-    SetSystemProperty(TskSystemProperties::OUT_DIR, outDirPath);
-    // make the output dirs, makeDir() logs the error.
-    if (makeDir(outDirPath.c_str()))  {
-        return 1;
-    }
-
-    if (makeDir(GetSystemProperty(TskSystemProperties::SYSTEM_OUT_DIR).c_str())) {
-        return 1;
-    }
-
-    if (makeDir(GetSystemProperty(TskSystemProperties::MODULE_OUT_DIR).c_str())) {
-        return 1;
-    }
-
-    std::string logDir = GetSystemProperty(TskSystemProperties::LOG_DIR);
-    if (makeDir(logDir.c_str()))  {
-        return 1;
-    }
-
-
-    // Create a log object
-    struct tm * newtime;
-    time_t aclock;
-
-    time(&aclock);   // Get time in seconds
-    newtime = localtime(&aclock);
-    char filename[MAX_BUFF_LENGTH];
-    snprintf(filename, MAX_BUFF_LENGTH, "/log_%.4d-%.2d-%.2d-%.2d-%.2d-%.2d.txt",
-        newtime->tm_year + 1900, newtime->tm_mon+1, newtime->tm_mday,  
-        newtime->tm_hour, newtime->tm_min, newtime->tm_sec);
-
-    logDir.append(filename);
-    std::auto_ptr<Log> log(NULL);
-
-    if(suppressSTDERR)
-        log = std::auto_ptr<Log>(new Log());
-    else
-        log = std::auto_ptr<Log>(new StderrLog());
-
-    log->open(logDir.c_str());
-    TskServices::Instance().setLog(*log);
-
-    // Create and register our SQLite ImgDB class   
-    std::auto_ptr<TskImgDB> pImgDB(NULL);
-    pImgDB = std::auto_ptr<TskImgDB>(new TskImgDBSqlite(outDirPath.c_str()));
-    if (pImgDB->initialize() != 0) {
-        std::stringstream msg;
-        msg << "Error initializing SQLite database: " << outDirPath;
-        LOGERROR(msg.str());
-        return 1;
-    }
-
-    // @@@ Call pImgDB->addToolInfo() as needed to set version info...
-
-    TskServices::Instance().setImgDB(*pImgDB);
-
-    // Create a Blackboard and register it with the framework.
-    TskServices::Instance().setBlackboard((TskBlackboard &) TskDBBlackboard::instance());
-
-    if (pipeline_config.size()) 
-        SetSystemProperty(TskSystemProperties::PIPELINE_CONFIG_FILE, pipeline_config);
-
-    // Create a Scheduler and register it
-    TskSchedulerQueue scheduler;
-    TskServices::Instance().setScheduler(scheduler);
-
-    // Create a FileManager and register it with the framework.
-    TskServices::Instance().setFileManager(TskFileManagerImpl::instance());
-
-    TskImageFileTsk imageFileTsk;
-
-    // Check to see if input image is actually a container file
-    TskArchiveExtraction::ExtractorPtr containerExtractor = TskArchiveExtraction::createExtractor(imagePath);
-
-    if (containerExtractor.isNull())
-    {
-        // Create an ImageFile and register it with the framework.
-        if (imageFileTsk.open(imagePath) != 0) {
-            std::stringstream msg;
-            msg << "Error opening image: " << imagePath;
-            LOGERROR(msg.str());
-            return 1;
-        }
-        TskServices::Instance().setImageFile(imageFileTsk);
-    }
-
-    // Let's get the pipelines setup to make sure there are no errors.
-    TskPipelineManager pipelineMgr;
-    TskPipeline *filePipeline;
-    try {
-        filePipeline = pipelineMgr.createPipeline(TskPipelineManager::FILE_ANALYSIS_PIPELINE);
-    }
-    catch (const TskException &e ) {
-        std::stringstream msg;
-        msg << "Error creating file analysis pipeline: " << e.message();
-        LOGERROR(msg.str());
-        filePipeline = NULL;
-    }
-
-    TskPipeline *reportPipeline;
-    try {
-        reportPipeline = pipelineMgr.createPipeline(TskPipelineManager::POST_PROCESSING_PIPELINE);
-    }
-    catch (const TskException &e ) {
-        std::stringstream msg;
-        msg << "Error creating reporting pipeline: " << e.message();
-        LOGERROR(msg.str());
-        reportPipeline = NULL;
-    }
-
-    if ((filePipeline == NULL) && (reportPipeline == NULL)) {
-        std::stringstream msg;
-        msg << "No pipelines configured.  Stopping";
-        LOGERROR(msg.str());
-        exit(1);
-    }
-
-    // Now we analyze the data.
-
-    std::auto_ptr<TskCarveExtractScalpel> carver(new TskCarveExtractScalpel(createUnusedSectorFiles));
-
-    // Extract
-    if (!containerExtractor.isNull())   // Input is an archive file
-    {
-        if (containerExtractor->extractFiles() != 0)
-        {
-            std::wstringstream msg;
-            msg << L"Error adding archived file info to database";
-            LOGERROR(msg.str());
-            return 1;
-        }
-    }
-    else // Input is an image file
-    {
-        if (imageFileTsk.extractFiles() != 0)
-        {
-            std::wstringstream msg;
-            msg << L"Error adding file system info to database";
-            LOGERROR(msg.str());
-            return 1;
-        }
-
-        if (doCarving && !GetSystemProperty("SCALPEL_DIR").empty())
-        {
-            TskCarvePrepSectorConcat carvePrep;
-            carvePrep.processSectors();
-            carver.reset(new TskCarveExtractScalpel());
-        }
-    }
-
-    TskSchedulerQueue::task_struct *task;
-    while ((task = scheduler.nextTask()) != NULL) 
-    {
-        try
-        {
-            if (task->task == Scheduler::FileAnalysis && filePipeline && !filePipeline->isEmpty())
-            {
-                filePipeline->run(task->id);
-            }
-            else if (task->task == Scheduler::Carve && carver.get())
-            {
-                carver->processFile(static_cast<int>(task->id));
-            }
-            else
-            {
-                std::stringstream msg;
-                msg << "WARNING: Skipping task: " << task->task;
-                LOGWARN(msg.str());
-            }
-            delete task;
-        }
-        catch (...) 
-        {
-            // Error message has been logged already.
-        }
-    }
-
-    if (filePipeline && !filePipeline->isEmpty())
-    {
-        filePipeline->logModuleExecutionTimes();
-    }
-
-    // Do image analysis tasks.
-    if (reportPipeline) 
-    {
-        try 
-        {
-            reportPipeline->run();
-        }
-        catch (...) 
-        {
-            std::stringstream msg;
-            msg << "Error running reporting pipeline";
-            LOGERROR(msg.str());
-            return 1;
-        }
-        
-        if (!reportPipeline->isEmpty())
-        {
-            reportPipeline->logModuleExecutionTimes();
-        }
-    }
-
-    std::stringstream msg;
-    msg << "image analysis complete";
-    LOGINFO(msg.str());
-    cout << "Results saved to " << outDirPath << std::endl;
-    return 0;
-}
-
+/*
+*
+*  The Sleuth Kit
+*
+*  Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+*  Copyright (c) 2011-2012 Basis Technology Corporation. All Rights
+*  reserved.
+*
+*  This software is distributed under the Common Public License 1.0
+*/
+#include <iostream>
+#include <cstdio>
+#include <cstdlib>
+#include <string>
+#include <sstream>
+#include <time.h>
+#include <memory>
+
+#include "tsk/tsk_tools_i.h" // Needed for tsk_getopt
+#include "tsk/framework/framework.h"
+#include "tsk/framework/services/TskSchedulerQueue.h"
+#include "tsk/framework/services/TskSystemPropertiesImpl.h"
+#include "tsk/framework/services/TskImgDBSqlite.h"
+#include "tsk/framework/file/TskFileManagerImpl.h"
+#include "tsk/framework/extraction/TskCarvePrepSectorConcat.h"
+#include "tsk/framework/extraction/TskCarveExtractScalpel.h"
+#include "tsk/framework/extraction/TskExtract.h"
+
+#include "Poco/Path.h"
+#include "Poco/File.h"
+
+#ifdef TSK_WIN32
+#include <Windows.h>
+#else
+#include <sys/stat.h>
+#endif
+
+#include "Poco/File.h"
+#include "Poco/UnicodeConverter.h"
+
+static uint8_t 
+makeDir(const char *dir) 
+{
+    Poco::File path(dir);
+    try {
+        if (!path.createDirectory()) {
+            fprintf(stderr, "Error creating directory: %s\n", dir);
+            return 1;
+        }
+    } catch (const Poco::Exception &ex) {
+        std::stringstream msg;
+        msg << "Error creating directory: " << dir << " Poco exception: " << ex.displayText();
+        fprintf(stderr, "%s\n", msg.str().c_str());
+        return 1;
+    }
+    return 0;
+}
+
+/**
+ * Logs all messages to a log file and prints
+ * error messages to STDERR
+ */
+class StderrLog : public Log
+{
+public:
+    StderrLog() : Log() {
+    }
+
+    ~StderrLog() {
+    }
+
+    void log(Channel a_channel, const std::wstring &a_msg)
+    {
+        Log::log(a_channel, a_msg);
+        if (a_channel != Error) {
+            return;
+        }
+        fprintf(stderr, "%S\n", a_msg.c_str());
+    }
+};
+
+void 
+usage(const char *program) 
+{
+    fprintf(stderr, "%s [-c framework_config_file] [-p pipeline_config_file] [-d outdir] [-C] [-v] [-V] [-L] image_name\n", program);
+    fprintf(stderr, "\t-c framework_config_file: Path to XML framework config file\n");
+    fprintf(stderr, "\t-p pipeline_config_file: Path to XML pipeline config file (overrides pipeline config specified with -c)\n");
+    fprintf(stderr, "\t-d outdir: Path to output directory\n");
+    fprintf(stderr, "\t-C: Disable carving, overriding framework config file settings\n");
+    fprintf(stderr, "\t-u: Enable unused sector file creation\n");
+    fprintf(stderr, "\t-v: Enable verbose mode to get more debug information\n");
+    fprintf(stderr, "\t-V: Display the tool version\n");
+    fprintf(stderr, "\t-L: Print no error messages to STDERR -- only log them\n");
+    exit(1);
+}
+
+int main(int argc, char **argv1)
+{
+    TSK_TCHAR **argv;
+    extern int OPTIND;
+    int ch;
+    std::string pipeline_config;
+    std::string framework_config;
+    std::string outDirPath;
+    bool suppressSTDERR = false;
+    bool doCarving = true;
+    bool createUnusedSectorFiles = false;
+
+#ifdef TSK_WIN32
+    // On Windows, get the wide arguments (mingw doesn't support wmain)
+    argv = CommandLineToArgvW(GetCommandLineW(), &argc);
+    if (argv == NULL) {
+        fprintf(stderr, "Error getting wide arguments\n");
+        exit(1);
+    }
+#else
+    argv = (TSK_TCHAR **) argv1;
+#endif
+
+    while ((ch =
+        GETOPT(argc, argv, _TSK_T("d:c:p:vuVLC"))) > 0) {
+        switch (ch) {
+        case _TSK_T('c'):
+#ifdef TSK_WIN32
+            framework_config.assign(TskUtilities::toUTF8(std::wstring(OPTARG)));
+#else
+            framework_config.assign(OPTARG);
+#endif
+            break;
+
+        case _TSK_T('p'):
+#ifdef TSK_WIN32
+            pipeline_config.assign(TskUtilities::toUTF8(std::wstring(OPTARG)));
+#else
+            pipeline_config.assign(OPTARG);
+#endif
+            break;
+        case _TSK_T('u'):
+            createUnusedSectorFiles = true;
+            break;
+        case _TSK_T('v'):
+            tsk_verbose++;
+            break;
+
+        case _TSK_T('V'):
+            tsk_version_print(stdout);
+            exit(0);
+            break;
+
+        case _TSK_T('d'):
+#ifdef TSK_WIN32
+            outDirPath.assign(TskUtilities::toUTF8(std::wstring(OPTARG)));
+#else
+            outDirPath.assign(OPTARG);
+#endif
+            break;
+
+        case _TSK_T('C'):
+            doCarving = false;
+            break;
+
+        case _TSK_T('L'):
+            suppressSTDERR = true;
+            break;
+
+        case _TSK_T('?'):
+        default:
+            TFPRINTF(stderr, _TSK_T("Invalid argument: %s\n"),
+                argv[OPTIND]);
+            usage(argv1[0]);
+        }
+    }
+
+    /* We need at least one more argument */
+    if (OPTIND == argc) {
+        tsk_fprintf(stderr, "Missing image name\n");
+        usage(argv1[0]);
+    }
+
+    std::string imagePath;
+#ifdef TSK_WIN32
+    imagePath = TskUtilities::toUTF8(std::wstring(argv[OPTIND]));
+#else
+    imagePath = argv1[OPTIND];
+#endif
+    
+    if (!Poco::File(imagePath).exists()) {
+        std::stringstream msg;
+        msg << "Image file not found: " << imagePath;
+        LOGERROR(msg.str());
+        return 1;
+    }
+
+    // Load the framework config if they specified it
+    try
+    {
+        // try the one specified on the command line
+        if (framework_config.size()) {
+            TskSystemPropertiesImpl *systemProperties = new TskSystemPropertiesImpl();
+            systemProperties->initialize(framework_config);
+            TskServices::Instance().setSystemProperties(*systemProperties);
+        }
+        // try the one in the current directory
+        else if (Poco::File("framework_config.xml").exists()) {
+            TskSystemPropertiesImpl *systemProperties = new TskSystemPropertiesImpl();
+            systemProperties->initialize("framework_config.xml");
+            TskServices::Instance().setSystemProperties(*systemProperties);
+        }
+        // try one back up a few directories for the use case that we built this in
+        // the source tree.
+        else {
+            TskSystemPropertiesImpl *systemProperties = new TskSystemPropertiesImpl();
+            systemProperties->initialize();
+            std::string progdir = systemProperties->get(TskSystemProperties::PROG_DIR);
+            std::string configPath = progdir + "../../../runtime/framework_config.xml";
+            if (Poco::File(configPath).exists()) {
+                systemProperties->initialize(configPath);
+                TskServices::Instance().setSystemProperties(*systemProperties);
+            } else {
+                fprintf(stderr, "No framework config file found\n");
+            }
+        }
+    }
+    catch (TskException& ex)
+    {
+        fprintf(stderr, "Loading framework config file: %s\n", ex.message().c_str());
+        return 1;
+    }
+
+    // if they didn't specify the output directory, make one
+    if (outDirPath == "") {
+        outDirPath.assign(imagePath);
+        outDirPath.append("_tsk_out");
+    }
+    if (Poco::File(outDirPath).exists()) {
+        std::stringstream msg;
+        msg << "Output directory already exists " << outDirPath;
+        LOGERROR(msg.str());
+        return 1;
+    }
+
+    SetSystemProperty(TskSystemProperties::OUT_DIR, outDirPath);
+    // make the output dirs, makeDir() logs the error.
+    if (makeDir(outDirPath.c_str()))  {
+        return 1;
+    }
+
+    if (makeDir(GetSystemProperty(TskSystemProperties::SYSTEM_OUT_DIR).c_str())) {
+        return 1;
+    }
+
+    if (makeDir(GetSystemProperty(TskSystemProperties::MODULE_OUT_DIR).c_str())) {
+        return 1;
+    }
+
+    std::string logDir = GetSystemProperty(TskSystemProperties::LOG_DIR);
+    if (makeDir(logDir.c_str()))  {
+        return 1;
+    }
+
+
+    // Create a log object
+    struct tm * newtime;
+    time_t aclock;
+
+    time(&aclock);   // Get time in seconds
+    newtime = localtime(&aclock);
+    char filename[MAX_BUFF_LENGTH];
+    snprintf(filename, MAX_BUFF_LENGTH, "/log_%.4d-%.2d-%.2d-%.2d-%.2d-%.2d.txt",
+        newtime->tm_year + 1900, newtime->tm_mon+1, newtime->tm_mday,  
+        newtime->tm_hour, newtime->tm_min, newtime->tm_sec);
+
+    logDir.append(filename);
+    std::auto_ptr<Log> log(NULL);
+
+    if(suppressSTDERR)
+        log = std::auto_ptr<Log>(new Log());
+    else
+        log = std::auto_ptr<Log>(new StderrLog());
+
+    log->open(logDir.c_str());
+    TskServices::Instance().setLog(*log);
+
+    // Create and register our SQLite ImgDB class   
+    std::auto_ptr<TskImgDB> pImgDB(NULL);
+    pImgDB = std::auto_ptr<TskImgDB>(new TskImgDBSqlite(outDirPath.c_str()));
+    if (pImgDB->initialize() != 0) {
+        std::stringstream msg;
+        msg << "Error initializing SQLite database: " << outDirPath;
+        LOGERROR(msg.str());
+        return 1;
+    }
+
+    // @@@ Call pImgDB->addToolInfo() as needed to set version info...
+
+    TskServices::Instance().setImgDB(*pImgDB);
+
+    // Create a Blackboard and register it with the framework.
+    TskServices::Instance().setBlackboard((TskBlackboard &) TskDBBlackboard::instance());
+
+    if (pipeline_config.size()) 
+        SetSystemProperty(TskSystemProperties::PIPELINE_CONFIG_FILE, pipeline_config);
+
+    // Create a Scheduler and register it
+    TskSchedulerQueue scheduler;
+    TskServices::Instance().setScheduler(scheduler);
+
+    // Create a FileManager and register it with the framework.
+    TskServices::Instance().setFileManager(TskFileManagerImpl::instance());
+
+    TskImageFileTsk imageFileTsk;
+
+    // Check to see if input image is actually a container file
+    TskArchiveExtraction::ExtractorPtr containerExtractor = TskArchiveExtraction::createExtractor(imagePath);
+
+    if (containerExtractor.isNull())
+    {
+        // Create an ImageFile and register it with the framework.
+        if (imageFileTsk.open(imagePath) != 0) {
+            std::stringstream msg;
+            msg << "Error opening image: " << imagePath;
+            LOGERROR(msg.str());
+            return 1;
+        }
+        TskServices::Instance().setImageFile(imageFileTsk);
+    }
+
+    // Let's get the pipelines setup to make sure there are no errors.
+    TskPipelineManager pipelineMgr;
+    TskPipeline *filePipeline;
+    try {
+        filePipeline = pipelineMgr.createPipeline(TskPipelineManager::FILE_ANALYSIS_PIPELINE);
+    }
+    catch (const TskException &e ) {
+        std::stringstream msg;
+        msg << "Error creating file analysis pipeline: " << e.message();
+        LOGERROR(msg.str());
+        filePipeline = NULL;
+    }
+
+    TskPipeline *reportPipeline;
+    try {
+        reportPipeline = pipelineMgr.createPipeline(TskPipelineManager::POST_PROCESSING_PIPELINE);
+    }
+    catch (const TskException &e ) {
+        std::stringstream msg;
+        msg << "Error creating reporting pipeline: " << e.message();
+        LOGERROR(msg.str());
+        reportPipeline = NULL;
+    }
+
+    if ((filePipeline == NULL) && (reportPipeline == NULL)) {
+        std::stringstream msg;
+        msg << "No pipelines configured.  Stopping";
+        LOGERROR(msg.str());
+        exit(1);
+    }
+
+    // Now we analyze the data.
+
+    std::auto_ptr<TskCarveExtractScalpel> carver(new TskCarveExtractScalpel(createUnusedSectorFiles));
+
+    // Extract
+    if (!containerExtractor.isNull())   // Input is an archive file
+    {
+        if (containerExtractor->extractFiles() != 0)
+        {
+            std::wstringstream msg;
+            msg << L"Error adding archived file info to database";
+            LOGERROR(msg.str());
+            return 1;
+        }
+    }
+    else // Input is an image file
+    {
+        if (imageFileTsk.extractFiles() != 0)
+        {
+            std::wstringstream msg;
+            msg << L"Error adding file system info to database";
+            LOGERROR(msg.str());
+            return 1;
+        }
+
+        if (doCarving && !GetSystemProperty("SCALPEL_DIR").empty())
+        {
+            TskCarvePrepSectorConcat carvePrep;
+            carvePrep.processSectors();
+            carver.reset(new TskCarveExtractScalpel());
+        }
+    }
+
+    TskSchedulerQueue::task_struct *task;
+    while ((task = scheduler.nextTask()) != NULL) 
+    {
+        try
+        {
+            if (task->task == Scheduler::FileAnalysis && filePipeline && !filePipeline->isEmpty())
+            {
+                filePipeline->run(task->id);
+            }
+            else if (task->task == Scheduler::Carve && carver.get())
+            {
+                carver->processFile(static_cast<int>(task->id));
+            }
+            else
+            {
+                std::stringstream msg;
+                msg << "WARNING: Skipping task: " << task->task;
+                LOGWARN(msg.str());
+            }
+            delete task;
+        }
+        catch (...) 
+        {
+            // Error message has been logged already.
+        }
+    }
+
+    if (filePipeline && !filePipeline->isEmpty())
+    {
+        filePipeline->logModuleExecutionTimes();
+    }
+
+    // Do image analysis tasks.
+    if (reportPipeline) 
+    {
+        try 
+        {
+            reportPipeline->run();
+        }
+        catch (...) 
+        {
+            std::stringstream msg;
+            msg << "Error running reporting pipeline";
+            LOGERROR(msg.str());
+            return 1;
+        }
+        
+        if (!reportPipeline->isEmpty())
+        {
+            reportPipeline->logModuleExecutionTimes();
+        }
+    }
+
+    std::stringstream msg;
+    msg << "image analysis complete";
+    LOGINFO(msg.str());
+    cout << "Results saved to " << outDirPath << std::endl;
+    return 0;
+}
+
diff --git a/framework/tools/tsk_validatepipeline/tsk_validatepipeline.cpp b/framework/tools/tsk_validatepipeline/tsk_validatepipeline.cpp
index d38c3bc..e6c5cde 100755
--- a/framework/tools/tsk_validatepipeline/tsk_validatepipeline.cpp
+++ b/framework/tools/tsk_validatepipeline/tsk_validatepipeline.cpp
@@ -1,178 +1,178 @@
-/*
-*
-*  The Sleuth Kit
-*
-*  Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
-*  Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
-*  reserved.
-*
-*  This software is distributed under the Common Public License 1.0
-*/
-#include <cstdio>
-#include <cstdlib>
-#include <fstream>
-#include <sstream>
-
-#include "tsk/framework/framework.h"
-#include "tsk/framework/services/TskSystemPropertiesImpl.h"
-
-#include "Poco/AutoPtr.h"
-#include "Poco/Path.h"
-#include "Poco/UnicodeConverter.h"
-#include "Poco/DOM/DOMParser.h"
-#include "Poco/DOM/Document.h"
-#include "Poco/DOM/NodeList.h"
-#include "Poco/DOM/NodeIterator.h"
-#include "Poco/DOM/DOMWriter.h"
-#include "Poco/SAX/InputSource.h"
-#include "Poco/SAX/SAXException.h"
-#include "Poco/Util/XMLConfiguration.h"
-#include "Poco/Util/AbstractConfiguration.h"
-#include "Poco/TemporaryFile.h"
-
-#define VALIDATE_PIPELINE_VERSION "1.0.0.0"
-
-class ValidatePipeline
-{
-public:
-    ValidatePipeline();
-    ~ValidatePipeline();
-
-    bool isValid(const char * a_configPath) const;
-
-private:
-    const char *m_configPath;
-};
-
-static char *progname;
-
-static void usage()
-{
-    fprintf(stderr, "Usage: %s framework_config_file pipeline_config_file \n", progname);
-    fprintf(stderr, "\tframework_config_file: Framework config file that identifies where module directory, etc. is found.\n");
-    fprintf(stderr, "\tpipeline_config_file: Pipeline config file to validate.\n");
-}
-
-ValidatePipeline::ValidatePipeline()
-{
-}
-
-ValidatePipeline::~ValidatePipeline()
-{
-}
-
-/* Validate all of the pipelines in the given config file. 
-* This method does some basic parsing of the config file to learn
-* about the various pipelines that exist in the file.
-*/
-bool ValidatePipeline::isValid(const char *a_configPath) const
-{
-    bool failed = false;
-
-    std::ifstream in(a_configPath);
-    if (!in) {
-        fprintf(stdout, "Error opening pipeline config file: %s\n", a_configPath);
-    } else {
-        try {
-            Poco::XML::InputSource src(in);
-            Poco::XML::DOMParser parser;
-            // basic parsing
-            Poco::AutoPtr<Poco::XML::Document> xmlDoc = parser.parse(&src);
-
-            // must have at least one pipeline element
-            Poco::AutoPtr<Poco::XML::NodeList> pipelines = 
-                xmlDoc->getElementsByTagName(TskPipelineManager::PIPELINE_ELEMENT);
-
-            if (pipelines->length() == 0) {
-                fprintf(stdout, "No pipelines found in config file.\n");
-            } else {
-                // parse all pipelines in the config file
-                for (unsigned long i = 0; i < pipelines->length(); i++)
-                {
-                    Poco::XML::Node * pNode = pipelines->item(i);
-                    Poco::XML::Element* pElem = dynamic_cast<Poco::XML::Element*>(pNode);
-                    Poco::XML::DOMWriter writer;
-                    std::ostringstream pipelineXml;
-                    writer.writeNode(pipelineXml, pNode);
-
-                    std::string pipelineType = pElem->getAttribute(TskPipelineManager::PIPELINE_TYPE_ATTRIBUTE);
-
-                    TskPipeline * pipeline = 0;
-                    if (pipelineType == TskPipelineManager::FILE_ANALYSIS_PIPELINE_STR)
-                        pipeline = new TskFileAnalysisPipeline();
-                    else if (pipelineType == TskPipelineManager::REPORTING_PIPELINE_STR)
-                        pipeline = new TskReportPipeline();
-                    else {
-                        fprintf(stdout, "Unsupported pipeline type: %s\n", pipelineType.c_str());
-                        failed = true;
-                        continue;
-                    }
-
-                    try {
-                        pipeline->validate(pipelineXml.str());
-                    } catch (...) {
-                        fprintf(stdout, "Error parsing pipeline: %s\n", pElem->getAttribute(TskPipelineManager::PIPELINE_TYPE_ATTRIBUTE).c_str());
-                        failed = true;
-                    }
-                        delete pipeline;
-                }
-            }
-        } catch (Poco::XML::SAXParseException& ex) {
-            fprintf(stderr, "Error parsing pipeline config file: %s (%s)\n", a_configPath, ex.what());
-        }
-    }
- 
-    // If any of the pipelines failed validation we return false
-    return failed ? false : true;
-}
-
-int main(int argc, char **argv)
-{
-    progname = argv[0];
-    if (argc != 3) {
-        usage();
-        return 1;
-    }
-    char *frameworkConfigPath = argv[1];
-    char *pipelineConfigPath = argv[2];
-
-    fprintf(stderr, "Validating %s\n", pipelineConfigPath);
-
-    // open the log temp file
-    Log log;
-    Poco::TemporaryFile filename;
-
-    log.open(filename.path().c_str());
-    TskServices::Instance().setLog(log);
-
-    std::string progDirPath = TskUtilities::getProgDir();
-
-    // Initialize properties based on the config file. Do this to shutdown noise in validation.
-    TskSystemPropertiesImpl systemProperties;
-    systemProperties.initialize(frameworkConfigPath);
-    TskServices::Instance().setSystemProperties(systemProperties);
-
-    SetSystemProperty(TskSystemProperties::PROG_DIR, progDirPath); 
-
-    ValidatePipeline vp;
-    bool valid = vp.isValid(pipelineConfigPath);
-    fprintf(stdout, "%s is %s\n", pipelineConfigPath, (valid ? "valid." : "invalid."));
-
-    // close the log file and dump content to stdout
-    log.close();
-
-#define MAX_BUF 1024
-    char buf[MAX_BUF];
-    std::ifstream fin(filename.path().c_str());
-
-    fprintf(stdout, "\nLog messages created during validation: \n");
-    while (fin.getline(buf, MAX_BUF)) {
-        fprintf(stdout, "%s\n", buf);
-    }
-    fin.close();
-
-    if (valid)
-        return 0;
-    else
-        return 1;
-}
+/*
+*
+*  The Sleuth Kit
+*
+*  Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+*  Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+*  reserved.
+*
+*  This software is distributed under the Common Public License 1.0
+*/
+#include <cstdio>
+#include <cstdlib>
+#include <fstream>
+#include <sstream>
+
+#include "tsk/framework/framework.h"
+#include "tsk/framework/services/TskSystemPropertiesImpl.h"
+
+#include "Poco/AutoPtr.h"
+#include "Poco/Path.h"
+#include "Poco/UnicodeConverter.h"
+#include "Poco/DOM/DOMParser.h"
+#include "Poco/DOM/Document.h"
+#include "Poco/DOM/NodeList.h"
+#include "Poco/DOM/NodeIterator.h"
+#include "Poco/DOM/DOMWriter.h"
+#include "Poco/SAX/InputSource.h"
+#include "Poco/SAX/SAXException.h"
+#include "Poco/Util/XMLConfiguration.h"
+#include "Poco/Util/AbstractConfiguration.h"
+#include "Poco/TemporaryFile.h"
+
+#define VALIDATE_PIPELINE_VERSION "1.0.0.0"
+
+class ValidatePipeline
+{
+public:
+    ValidatePipeline();
+    ~ValidatePipeline();
+
+    bool isValid(const char * a_configPath) const;
+
+private:
+    const char *m_configPath;
+};
+
+static char *progname;
+
+static void usage()
+{
+    fprintf(stderr, "Usage: %s framework_config_file pipeline_config_file \n", progname);
+    fprintf(stderr, "\tframework_config_file: Framework config file that identifies where module directory, etc. is found.\n");
+    fprintf(stderr, "\tpipeline_config_file: Pipeline config file to validate.\n");
+}
+
+ValidatePipeline::ValidatePipeline()
+{
+}
+
+ValidatePipeline::~ValidatePipeline()
+{
+}
+
+/* Validate all of the pipelines in the given config file. 
+* This method does some basic parsing of the config file to learn
+* about the various pipelines that exist in the file.
+*/
+bool ValidatePipeline::isValid(const char *a_configPath) const
+{
+    bool failed = false;
+
+    std::ifstream in(a_configPath);
+    if (!in) {
+        fprintf(stdout, "Error opening pipeline config file: %s\n", a_configPath);
+    } else {
+        try {
+            Poco::XML::InputSource src(in);
+            Poco::XML::DOMParser parser;
+            // basic parsing
+            Poco::AutoPtr<Poco::XML::Document> xmlDoc = parser.parse(&src);
+
+            // must have at least one pipeline element
+            Poco::AutoPtr<Poco::XML::NodeList> pipelines = 
+                xmlDoc->getElementsByTagName(TskPipelineManager::PIPELINE_ELEMENT);
+
+            if (pipelines->length() == 0) {
+                fprintf(stdout, "No pipelines found in config file.\n");
+            } else {
+                // parse all pipelines in the config file
+                for (unsigned long i = 0; i < pipelines->length(); i++)
+                {
+                    Poco::XML::Node * pNode = pipelines->item(i);
+                    Poco::XML::Element* pElem = dynamic_cast<Poco::XML::Element*>(pNode);
+                    Poco::XML::DOMWriter writer;
+                    std::ostringstream pipelineXml;
+                    writer.writeNode(pipelineXml, pNode);
+
+                    std::string pipelineType = pElem->getAttribute(TskPipelineManager::PIPELINE_TYPE_ATTRIBUTE);
+
+                    TskPipeline * pipeline = 0;
+                    if (pipelineType == TskPipelineManager::FILE_ANALYSIS_PIPELINE_STR)
+                        pipeline = new TskFileAnalysisPipeline();
+                    else if (pipelineType == TskPipelineManager::REPORTING_PIPELINE_STR)
+                        pipeline = new TskReportPipeline();
+                    else {
+                        fprintf(stdout, "Unsupported pipeline type: %s\n", pipelineType.c_str());
+                        failed = true;
+                        continue;
+                    }
+
+                    try {
+                        pipeline->validate(pipelineXml.str());
+                    } catch (...) {
+                        fprintf(stdout, "Error parsing pipeline: %s\n", pElem->getAttribute(TskPipelineManager::PIPELINE_TYPE_ATTRIBUTE).c_str());
+                        failed = true;
+                    }
+                        delete pipeline;
+                }
+            }
+        } catch (Poco::XML::SAXParseException& ex) {
+            fprintf(stderr, "Error parsing pipeline config file: %s (%s)\n", a_configPath, ex.what());
+        }
+    }
+ 
+    // If any of the pipelines failed validation we return false
+    return failed ? false : true;
+}
+
+int main(int argc, char **argv)
+{
+    progname = argv[0];
+    if (argc != 3) {
+        usage();
+        return 1;
+    }
+    char *frameworkConfigPath = argv[1];
+    char *pipelineConfigPath = argv[2];
+
+    fprintf(stderr, "Validating %s\n", pipelineConfigPath);
+
+    // open the log temp file
+    Log log;
+    Poco::TemporaryFile filename;
+
+    log.open(filename.path().c_str());
+    TskServices::Instance().setLog(log);
+
+    std::string progDirPath = TskUtilities::getProgDir();
+
+    // Initialize properties based on the config file. Do this to shutdown noise in validation.
+    TskSystemPropertiesImpl systemProperties;
+    systemProperties.initialize(frameworkConfigPath);
+    TskServices::Instance().setSystemProperties(systemProperties);
+
+    SetSystemProperty(TskSystemProperties::PROG_DIR, progDirPath); 
+
+    ValidatePipeline vp;
+    bool valid = vp.isValid(pipelineConfigPath);
+    fprintf(stdout, "%s is %s\n", pipelineConfigPath, (valid ? "valid." : "invalid."));
+
+    // close the log file and dump content to stdout
+    log.close();
+
+#define MAX_BUF 1024
+    char buf[MAX_BUF];
+    std::ifstream fin(filename.path().c_str());
+
+    fprintf(stdout, "\nLog messages created during validation: \n");
+    while (fin.getline(buf, MAX_BUF)) {
+        fprintf(stdout, "%s\n", buf);
+    }
+    fin.close();
+
+    if (valid)
+        return 0;
+    else
+        return 1;
+}
diff --git a/framework/tsk/framework/TskVersionInfo.h b/framework/tsk/framework/TskVersionInfo.h
index 64e28c9..a37fb45 100755
--- a/framework/tsk/framework/TskVersionInfo.h
+++ b/framework/tsk/framework/TskVersionInfo.h
@@ -1,82 +1,82 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-#ifndef _TSK_VERSIONINFO_H
-#define _TSK_VERSIONINFO_H
-
-#include "tsk/base/tsk_base.h"
-
-/** 
- * Class that allows us to determine framework version,
- * compiler version and build type (debug or release).
- */
-class TskVersionInfo
-{
-public:
-    enum BuildType
-    {
-        DEBUG,
-        RELEASE
-    };
-
-    enum Compiler
-    {
-        MSVC,
-        UNKNOWN
-    };
-
-    /**
-     * Returns whether the component was built in debug or release mode.
-     * Only applicable if built by MSVC compiler.
-     */
-    static BuildType getBuildType()
-    {
-#if defined _WIN32 && defined _DEBUG
-        return DEBUG;
-#else
-        return RELEASE;
-#endif
-    }
-    
-    /**
-     * Returned the compiler that was used to build the component.
-     */
-    static Compiler getCompiler()
-    {
-#if defined _WIN32
-        return MSVC;
-#else
-        return UNKNOWN;
-#endif
-    }
-
-    /**
-     * Returns the version number of the compiler.
-     * Initial implementation only supports MSVC compiler.
-     */
-    static int getCompilerVersion()
-    {
-#if defined _MSC_VER
-        return _MSC_VER;
-#else
-        return 0;
-#endif
-    }
-
-    /**
-     * Returns the version of the Sleuthkit framework the component was compiled with.
-     */
-    static int getFrameworkVersion()
-    {
-        return TSK_VERSION_NUM;
-    }
-};
-
-#endif
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+#ifndef _TSK_VERSIONINFO_H
+#define _TSK_VERSIONINFO_H
+
+#include "tsk/base/tsk_base.h"
+
+/** 
+ * Class that allows us to determine framework version,
+ * compiler version and build type (debug or release).
+ */
+class TskVersionInfo
+{
+public:
+    enum BuildType
+    {
+        DEBUG,
+        RELEASE
+    };
+
+    enum Compiler
+    {
+        MSVC,
+        UNKNOWN
+    };
+
+    /**
+     * Returns whether the component was built in debug or release mode.
+     * Only applicable if built by MSVC compiler.
+     */
+    static BuildType getBuildType()
+    {
+#if defined _WIN32 && defined _DEBUG
+        return DEBUG;
+#else
+        return RELEASE;
+#endif
+    }
+    
+    /**
+     * Returned the compiler that was used to build the component.
+     */
+    static Compiler getCompiler()
+    {
+#if defined _WIN32
+        return MSVC;
+#else
+        return UNKNOWN;
+#endif
+    }
+
+    /**
+     * Returns the version number of the compiler.
+     * Initial implementation only supports MSVC compiler.
+     */
+    static int getCompilerVersion()
+    {
+#if defined _MSC_VER
+        return _MSC_VER;
+#else
+        return 0;
+#endif
+    }
+
+    /**
+     * Returns the version of the Sleuthkit framework the component was compiled with.
+     */
+    static int getFrameworkVersion()
+    {
+        return TSK_VERSION_NUM;
+    }
+};
+
+#endif
diff --git a/framework/tsk/framework/extraction/CarveExtract.h b/framework/tsk/framework/extraction/CarveExtract.h
index cc117c6..4c419a1 100755
--- a/framework/tsk/framework/extraction/CarveExtract.h
+++ b/framework/tsk/framework/extraction/CarveExtract.h
@@ -1,42 +1,42 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file CarveExtract.h
- * Contains the interface of the abstract CarveExtract class.
- */
-#ifndef _TSK_CARVEEXTRACT_H
-#define _TSK_CARVEEXTRACT_H
-
-#include "tsk/framework/services/TskImgDB.h"
-
-/**
- * Interface for class that will carve an unallocated sectors image file. The 
- * design assumes that the unallocated sectors image file was created by a 
- * CarvePrep implementation. 
- */
-class TSK_FRAMEWORK_API CarveExtract
-{
-public:
-    /**
-     * Virtual destructor to ensure derived class constructors are called
-     * polymorphically.
-     */
-    virtual ~CarveExtract() {}
-
-    /**
-     * Carve a specified unallocated sectors image file. 
-     *
-     * @param unallocImgId Id of the file to carve.
-     * @returns 1 on error. 
-     */
-    virtual int processFile(int unallocImgId) = 0;
-};
-#endif
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file CarveExtract.h
+ * Contains the interface of the abstract CarveExtract class.
+ */
+#ifndef _TSK_CARVEEXTRACT_H
+#define _TSK_CARVEEXTRACT_H
+
+#include "tsk/framework/services/TskImgDB.h"
+
+/**
+ * Interface for class that will carve an unallocated sectors image file. The 
+ * design assumes that the unallocated sectors image file was created by a 
+ * CarvePrep implementation. 
+ */
+class TSK_FRAMEWORK_API CarveExtract
+{
+public:
+    /**
+     * Virtual destructor to ensure derived class constructors are called
+     * polymorphically.
+     */
+    virtual ~CarveExtract() {}
+
+    /**
+     * Carve a specified unallocated sectors image file. 
+     *
+     * @param unallocImgId Id of the file to carve.
+     * @returns 1 on error. 
+     */
+    virtual int processFile(int unallocImgId) = 0;
+};
+#endif
diff --git a/framework/tsk/framework/extraction/CarvePrep.h b/framework/tsk/framework/extraction/CarvePrep.h
index ba1b326..39547ce 100755
--- a/framework/tsk/framework/extraction/CarvePrep.h
+++ b/framework/tsk/framework/extraction/CarvePrep.h
@@ -1,46 +1,46 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file CarvePrep.h
- * Contains the interface of the abstract CarvePrep class.
- */
-#ifndef _TSK_CARVE_PREP_H
-#define _TSK_CARVE_PREP_H
-
-#include "tsk/framework/services/TskImgDB.h"
-
-/**
- * Interface for class that prepares for later carving. 
- * CarvePrep is responsible for making unallocated sectors image files for 
- * later carving.  The implementation can choose to create 1 or dozens
- * of such files.  Refer to \ref fw_extract_carve for details,
- * but this class should get unallocated image IDs from TskImgDB,
- * populate the unalloc_alloc map in the database, and schedule
- * each unallocated image for later carving. 
- */
-class TSK_FRAMEWORK_API CarvePrep
-{
-public:
-    /**
-     * Virtual destructor to ensure derived class constructors are called
-     * polymorphically.
-     */
-    virtual ~CarvePrep(void) {}
-    
-    /**
-     * Make one or more unallocated sectors image files to carve. 
-     *
-     * @returns 0 on success, 1 on error. 
-     */
-    virtual int processSectors() = 0;
-};
-
-#endif
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file CarvePrep.h
+ * Contains the interface of the abstract CarvePrep class.
+ */
+#ifndef _TSK_CARVE_PREP_H
+#define _TSK_CARVE_PREP_H
+
+#include "tsk/framework/services/TskImgDB.h"
+
+/**
+ * Interface for class that prepares for later carving. 
+ * CarvePrep is responsible for making unallocated sectors image files for 
+ * later carving.  The implementation can choose to create 1 or dozens
+ * of such files.  Refer to \ref fw_extract_carve for details,
+ * but this class should get unallocated image IDs from TskImgDB,
+ * populate the unalloc_alloc map in the database, and schedule
+ * each unallocated image for later carving. 
+ */
+class TSK_FRAMEWORK_API CarvePrep
+{
+public:
+    /**
+     * Virtual destructor to ensure derived class constructors are called
+     * polymorphically.
+     */
+    virtual ~CarvePrep(void) {}
+    
+    /**
+     * Make one or more unallocated sectors image files to carve. 
+     *
+     * @returns 0 on success, 1 on error. 
+     */
+    virtual int processSectors() = 0;
+};
+
+#endif
diff --git a/framework/tsk/framework/extraction/TskAutoImpl.cpp b/framework/tsk/framework/extraction/TskAutoImpl.cpp
index 93946e8..df0a3c1 100755
--- a/framework/tsk/framework/extraction/TskAutoImpl.cpp
+++ b/framework/tsk/framework/extraction/TskAutoImpl.cpp
@@ -1,438 +1,438 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-#include <string>
-#include <sstream>
-#include <string.h>
-
-#include "TskAutoImpl.h"
-#include "tsk/framework/services/TskServices.h"
-
-#define TSK_SCHEMA_VER 1
-
-TSKAutoImpl::TSKAutoImpl() : m_db(TskServices::Instance().getImgDB()), m_numFilesSeen(0)
-{
-    m_curFsId = 0;
-    m_curVsId = 0;
-    m_vsSeen = false;
-    m_lastUpdateMsg = 0;
-
-    setVolFilterFlags((TSK_VS_PART_FLAG_ENUM)(TSK_VS_PART_FLAG_ALLOC | TSK_VS_PART_FLAG_UNALLOC));
-    setFileFilterFlags((TSK_FS_DIR_WALK_FLAG_ENUM)(TSK_FS_DIR_WALK_FLAG_ALLOC|TSK_FS_DIR_WALK_FLAG_UNALLOC));
-
-    // add the version to the DB
-    m_db.addToolInfo("Sleuth Kit", tsk_version_get_str()); 
-}
-
-TSKAutoImpl::~TSKAutoImpl()
-{
-}
-
-uint8_t TSKAutoImpl::openImage(TSK_IMG_INFO *a_img_info)
-{
-    m_curFsId = 0;
-    m_curVsId = 0;
-
-    return TskAuto::openImageHandle(a_img_info);
-}
-
-void
- TSKAutoImpl::closeImage()
-{
-    TskAuto::closeImage();
-}
-
-
-/**
- * Main method to call for this class after image has been opened as it takes care of the transactions.
- */
-uint8_t TSKAutoImpl::extractFiles() 
-{
-    m_db.begin();
-    uint8_t retval = findFilesInImg();  
-    commitAndSchedule();
-    return retval;
-}
-
-/**
-* Scan the image for file systems creating allocated volumes for file systems found
-* and unallocated volumes for areas in the image that do not contain file systems.
-* Will initially look for file system in first sect_count sectors. If a file system
-* is found then it will continue to process the remainder of the image for other
-* file systems.
-* 
-* @param sect_start Start looking for file systems starting at this sector.
-* @param sect_count The initial number of sectors to scan for file systems.
-* @return 0 on success, 1 on failure 
-*/
-uint8_t TSKAutoImpl::scanImgForFs(const uint64_t sect_start, const uint64_t sect_count)
-{
-    if (m_img_info == NULL)
-    {
-        LOGERROR(L"TSKAutoImpl::scanImgForFs - Image not open.");
-        return 1;
-    }
-
-    LOGINFO(L"TSKAutoImpl::scanImgForFs - Starting file system scan.");
-
-    // Initialize current offset to our starting byte location.
-    TSK_OFF_T current_offset = sect_start * m_img_info->sector_size;
-
-    TSK_OFF_T end_offset = current_offset + (sect_count * m_img_info->sector_size);
-
-    // Last offset keeps track of byte location where we last saw file system
-    // data. It gets initialized to our starting location.
-    TSK_OFF_T last_offset = current_offset;
-
-    while (current_offset < end_offset)
-    {
-        TSK_FS_INFO * fs_info;
-
-        if ((fs_info = tsk_fs_open_img(m_img_info, 
-                                       current_offset, 
-                                       TSK_FS_TYPE_DETECT)) == NULL)
-        {
-            // We didn't find a file system so we move on to the next sector.
-            current_offset += m_img_info->sector_size;
-        }
-        else
-        {
-            // We found a file system so we will continue to search for file
-            // systems beyond the initial sectors.
-            end_offset = m_img_info->size;
-
-            // If there is a gap between the location of this file system and
-            // where we last saw file system data, an unallocated volume entry
-            // needs to be created for the gap.
-            if (fs_info->offset > last_offset)
-            {
-                createDummyVolume(last_offset / m_img_info->sector_size,
-                                  (fs_info->offset - last_offset) / m_img_info->sector_size,
-                                  "Dummy volume for carving purposes",
-                                  TSK_VS_PART_FLAG_UNALLOC);
-            }
-
-            /* The call to findFilesInFs will take care of creating a
-             * dummy volume for the file system.*/
-            /* errors encountered during this phase will have been
-             * logged. */
-            findFilesInFs(fs_info);
-
-            // Move the current offset past the file system we just found.
-            current_offset += ((fs_info->block_count + 1) * fs_info->block_size);
-
-            // Update the last location we saw file system data.
-            last_offset = current_offset;
-
-            tsk_fs_close(fs_info);
-        }
-    }
-
-    // Finally, create a dummy unallocated volume for the area between the
-    // last offset and the end of the image.
-   if (last_offset < m_img_info->size)
-    {
-        createDummyVolume(last_offset / m_img_info->sector_size,
-            (m_img_info->size - last_offset) / m_img_info->sector_size,
-            "Dummy volume for carving purposes",
-            TSK_VS_PART_FLAG_UNALLOC);
-    }
-
-    LOGINFO(L"TSKAutoImpl::scanImgForFs - File system scan complete.");
-
-    return 0;
-}
-
-TSK_FILTER_ENUM TSKAutoImpl::filterVol(const TSK_VS_PART_INFO * a_vsPart)
-{
-    // flag that this image has a volume system
-    m_vsSeen = true;
-    m_db.addVolumeInfo(a_vsPart);
-
-    m_curVsId = a_vsPart->addr;
-
-    std::wstringstream msg;
-    msg << L"TSKAutoImpl::filterVol - Discovered " << a_vsPart->desc 
-        << L" partition (sectors " << a_vsPart->start << L"-" 
-        << ((a_vsPart->start + a_vsPart->len) - 1) << L")";
-    LOGINFO(msg.str());
-
-    // we only want to process the allocated volumes
-    if ((a_vsPart->flags & TSK_VS_PART_FLAG_ALLOC) == 0)
-        return TSK_FILTER_SKIP;
-
-    return TSK_FILTER_CONT;
-}
-
-
-TSK_FILTER_ENUM TSKAutoImpl::filterFs(TSK_FS_INFO * a_fsInfo)
-{
-    // add a volume entry if there is no file system
-    if (m_vsSeen == false) 
-    {
-        TSK_DADDR_T start_sect = a_fsInfo->offset / a_fsInfo->img_info->sector_size;
-        TSK_DADDR_T end_sect = start_sect + 
-            ((a_fsInfo->block_count * a_fsInfo->block_size) / a_fsInfo->img_info->sector_size);
-
-        createDummyVolume(start_sect, (end_sect - start_sect) + 1,
-                          "Dummy volume for file system",
-                          TSK_VS_PART_FLAG_ALLOC);
-    }
-
-    m_curFsId++;
-    m_db.addFsInfo(m_curVsId, m_curFsId, a_fsInfo);
-
-    /* Process the root directory so that its contents are added to
-     * the DB.  We won't see it during the dir_walk. */
-    TSK_FS_FILE *fs_file = tsk_fs_file_open(a_fsInfo, NULL, "/");
-    if (fs_file != NULL)
-    {
-        processFile(fs_file, "\\");
-    }
-
-    // make sure that flags are set to get all files -- we need this to
-    // find parent directory
-    setFileFilterFlags((TSK_FS_DIR_WALK_FLAG_ENUM)
-        (TSK_FS_DIR_WALK_FLAG_ALLOC | TSK_FS_DIR_WALK_FLAG_UNALLOC));
-
-    std::wstringstream msg;
-    msg << L"TSKAutoImpl::filterFs - Discovered " << tsk_fs_type_toname(a_fsInfo->ftype) 
-        << L" file system at offset " << a_fsInfo->offset << L" with Id : " << m_curFsId;
-    LOGINFO(msg.str());
-
-    return TSK_FILTER_CONT;
-}
-
-/* Insert the file data into the file table.
- * @returns OK on success, COR on error because of the data (and we should keep on processing more files), 
- * and ERR because of system error (and we shoudl proabably stop processing)
- */
-TSK_RETVAL_ENUM TSKAutoImpl::insertFileData(TSK_FS_FILE * a_fsFile,
-    const TSK_FS_ATTR * a_fsAttr, const char * a_path, uint64_t & fileId)
-{
-    int type = TSK_FS_ATTR_TYPE_NOT_FOUND;
-    int idx = 0;
-    fileId = 0;
-
-    if (a_fsFile->name == NULL) {
-        LOGERROR(L"TSKAutoImpl::insertFileData name value is NULL");
-        return TSK_COR;
-    }
-
-    size_t attr_len = 0;
-    if (a_fsAttr) {
-        type = a_fsAttr->type;
-        idx = a_fsAttr->id;
-        if (a_fsAttr->name)
-        {
-            if ((a_fsAttr->type != TSK_FS_ATTR_TYPE_NTFS_IDXROOT) ||
-                (strcmp(a_fsAttr->name, "$I30") != 0))
-            {
-                attr_len = strlen(a_fsAttr->name);
-            }
-        }
-    }
-
-    // clean up special characters in name before we insert
-    size_t len = strlen(a_fsFile->name->name);
-    char *name;
-    size_t nlen = 2 * (len + attr_len);
-    if ((name = (char *) malloc(nlen + 1)) == NULL)
-    {
-        LOGERROR(L"Error allocating memory");
-        return TSK_ERR;
-    }
-    memset(name, 0, nlen+1);
-
-    size_t j = 0;
-    for (size_t i = 0; i < len && j < nlen; i++)
-    {
-        // ' is special in SQLite
-        if (a_fsFile->name->name[i] == '\'')
-        {
-            name[j++] = '\'';
-            name[j++] = '\'';
-        }
-        else
-        {
-            name[j++] = a_fsFile->name->name[i];
-        }
-    }
-
-    // Add the attribute name
-    if (attr_len > 0) {
-        name[j++] = ':';
-
-        for (unsigned i = 0; i < attr_len && j < nlen; i++) {
-            // ' is special in SQLite
-            if (a_fsAttr->name[i] == '\'')
-            {
-                name[j++] = '\'';
-                name[j++] = '\'';
-            }
-            else
-            {
-                name[j++] = a_fsAttr->name[i];
-            }
-        }
-    }
-
-    int result = m_db.addFsFileInfo(m_curFsId, a_fsFile, name, type, idx, fileId, a_path);
-    free(name);
-
-    // Message was already logged
-    if (result) {
-        return TSK_COR;
-    }
-    
-    Scheduler::task_struct task;
-    task.task = Scheduler::FileAnalysis;
-    task.id = fileId;
-    m_filesToSchedule.push(task);
-
-    return TSK_OK;
-}
-
-
-/* Based on the error handling design, we only return OK or STOP.  All
- * other errors have been handled, so we don't return ERROR to TSK. */
-TSK_RETVAL_ENUM TSKAutoImpl::processFile(TSK_FS_FILE * a_fsFile, const char * a_path)
-{
-    // skip the . and .. dirs
-    if (isDotDir(a_fsFile) == 1)
-    {
-        return TSK_OK;
-    }
-
-    TSK_RETVAL_ENUM retval;
-    // process the attributes if there are more than 1
-    if (tsk_fs_file_attr_getsize(a_fsFile) == 0)
-    {
-        uint64_t fileId;
-        // If COR is returned, then keep on going. 
-        if (insertFileData(a_fsFile, NULL, a_path, fileId) == TSK_ERR) {
-            retval = TSK_STOP;
-        }
-        else {
-            m_numFilesSeen++;
-            retval = TSK_OK;
-        }
-    }
-    else
-    {
-        retval = processAttributes(a_fsFile, a_path);
-    }
-
-    time_t timeNow = time(NULL);
-    if ((timeNow - m_lastUpdateMsg) > 3600)
-    {
-        m_lastUpdateMsg = timeNow;
-        std::wstringstream msg;
-        msg << L"TSKAutoImpl::processFile : Processed " << m_numFilesSeen << " files.";
-        LOGINFO(msg.str());
-    }
-
-    if (m_filesToSchedule.size() > m_numOfFilesToQueue) {
-        commitAndSchedule();
-        m_db.begin();
-    }
-
-    return retval;
-}
-
-/**
- * commits the open transaction and schedules the files that
- * were queued up as being part of that transaction.
- * Does not create a new transaction.
- */
-void TSKAutoImpl::commitAndSchedule()
-{
-    m_db.commit();
-
-    while (m_filesToSchedule.size() > 0) {
-        Scheduler::task_struct &task = m_filesToSchedule.front();
-        if (TskServices::Instance().getScheduler().schedule(task)) {
-            LOGERROR(L"Error adding file for scheduling");
-        }
-        m_filesToSchedule.pop();
-    }
-}
-
-uint8_t TSKAutoImpl::handleError()
-{
-    const char * tskMsg = tsk_error_get();
-
-    // @@@ Possibly test tsk_errno to determine how the message should be logged.
-    if (tskMsg != NULL)
-    {
-        std::wstringstream msg;
-        msg << L"TskAutoImpl::handleError " << tsk_error_get();
-
-        LOGWARN(msg.str());
-    }
-    return 0;
-}
-
-
-
-/* Based on the error handling design, we only return OK or STOP.  All
- * other errors have been handled, so we don't return ERROR to TSK. */
-TSK_RETVAL_ENUM TSKAutoImpl::processAttribute(TSK_FS_FILE * a_fsFile,
-    const TSK_FS_ATTR * a_fsAttr, const char * a_path)
-{
-    uint64_t mFileId = 0;
-
-    // add the file metadata for the default attribute type
-    if (isDefaultType(a_fsFile, a_fsAttr))
-    {
-        // if COR is returned, then keep on going.
-        if (insertFileData(a_fsAttr->fs_file, a_fsAttr, a_path, mFileId) == TSK_ERR)
-            return TSK_STOP;
-    }
-
-    // add the block map, if the file is non-resident
-    if (isNonResident(a_fsAttr))
-    {
-        TSK_FS_ATTR_RUN *run;
-        int count = 0;
-        for (run = a_fsAttr->nrd.run; run != NULL; run = run->next)
-        {
-            // ignore sparse blocks
-            if (run->flags & TSK_FS_ATTR_RUN_FLAG_SPARSE)
-                continue;
-            
-            if (m_db.addFsBlockInfo(m_curFsId, mFileId, count++, run->addr, run->len))
-            {
-                // this error should have been logged.
-                // we'll continue to try processing the file
-            }
-        }
-    }
-     
-    return TSK_OK;
-}
-
-void TSKAutoImpl::createDummyVolume(const TSK_DADDR_T sect_start, const TSK_DADDR_T sect_len, 
-                                    const char * desc, TSK_VS_PART_FLAG_ENUM flags)
-{
-    m_curVsId++;
-
-    TSK_VS_PART_INFO part;
-    part.addr = m_curVsId;
-    part.len = sect_len;
-    part.start = sect_start;
-    part.flags = flags;
-    part.desc = (char *)desc; // remove the cast when TSK_VS_PART_INFO.desc is const char *
-
-    if (m_db.addVolumeInfo(&part))
-    {
-        LOGERROR(L"TSKAutoImpl::createDummyVolume - Error creating volume.");
-    }
-}
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+#include <string>
+#include <sstream>
+#include <string.h>
+
+#include "TskAutoImpl.h"
+#include "tsk/framework/services/TskServices.h"
+
+#define TSK_SCHEMA_VER 1
+
+TSKAutoImpl::TSKAutoImpl() : m_db(TskServices::Instance().getImgDB()), m_numFilesSeen(0)
+{
+    m_curFsId = 0;
+    m_curVsId = 0;
+    m_vsSeen = false;
+    m_lastUpdateMsg = 0;
+
+    setVolFilterFlags((TSK_VS_PART_FLAG_ENUM)(TSK_VS_PART_FLAG_ALLOC | TSK_VS_PART_FLAG_UNALLOC));
+    setFileFilterFlags((TSK_FS_DIR_WALK_FLAG_ENUM)(TSK_FS_DIR_WALK_FLAG_ALLOC|TSK_FS_DIR_WALK_FLAG_UNALLOC));
+
+    // add the version to the DB
+    m_db.addToolInfo("Sleuth Kit", tsk_version_get_str()); 
+}
+
+TSKAutoImpl::~TSKAutoImpl()
+{
+}
+
+uint8_t TSKAutoImpl::openImage(TSK_IMG_INFO *a_img_info)
+{
+    m_curFsId = 0;
+    m_curVsId = 0;
+
+    return TskAuto::openImageHandle(a_img_info);
+}
+
+void
+ TSKAutoImpl::closeImage()
+{
+    TskAuto::closeImage();
+}
+
+
+/**
+ * Main method to call for this class after image has been opened as it takes care of the transactions.
+ */
+uint8_t TSKAutoImpl::extractFiles() 
+{
+    m_db.begin();
+    uint8_t retval = findFilesInImg();  
+    commitAndSchedule();
+    return retval;
+}
+
+/**
+* Scan the image for file systems creating allocated volumes for file systems found
+* and unallocated volumes for areas in the image that do not contain file systems.
+* Will initially look for file system in first sect_count sectors. If a file system
+* is found then it will continue to process the remainder of the image for other
+* file systems.
+* 
+* @param sect_start Start looking for file systems starting at this sector.
+* @param sect_count The initial number of sectors to scan for file systems.
+* @return 0 on success, 1 on failure 
+*/
+uint8_t TSKAutoImpl::scanImgForFs(const uint64_t sect_start, const uint64_t sect_count)
+{
+    if (m_img_info == NULL)
+    {
+        LOGERROR(L"TSKAutoImpl::scanImgForFs - Image not open.");
+        return 1;
+    }
+
+    LOGINFO(L"TSKAutoImpl::scanImgForFs - Starting file system scan.");
+
+    // Initialize current offset to our starting byte location.
+    TSK_OFF_T current_offset = sect_start * m_img_info->sector_size;
+
+    TSK_OFF_T end_offset = current_offset + (sect_count * m_img_info->sector_size);
+
+    // Last offset keeps track of byte location where we last saw file system
+    // data. It gets initialized to our starting location.
+    TSK_OFF_T last_offset = current_offset;
+
+    while (current_offset < end_offset)
+    {
+        TSK_FS_INFO * fs_info;
+
+        if ((fs_info = tsk_fs_open_img(m_img_info, 
+                                       current_offset, 
+                                       TSK_FS_TYPE_DETECT)) == NULL)
+        {
+            // We didn't find a file system so we move on to the next sector.
+            current_offset += m_img_info->sector_size;
+        }
+        else
+        {
+            // We found a file system so we will continue to search for file
+            // systems beyond the initial sectors.
+            end_offset = m_img_info->size;
+
+            // If there is a gap between the location of this file system and
+            // where we last saw file system data, an unallocated volume entry
+            // needs to be created for the gap.
+            if (fs_info->offset > last_offset)
+            {
+                createDummyVolume(last_offset / m_img_info->sector_size,
+                                  (fs_info->offset - last_offset) / m_img_info->sector_size,
+                                  "Dummy volume for carving purposes",
+                                  TSK_VS_PART_FLAG_UNALLOC);
+            }
+
+            /* The call to findFilesInFs will take care of creating a
+             * dummy volume for the file system.*/
+            /* errors encountered during this phase will have been
+             * logged. */
+            findFilesInFs(fs_info);
+
+            // Move the current offset past the file system we just found.
+            current_offset += ((fs_info->block_count + 1) * fs_info->block_size);
+
+            // Update the last location we saw file system data.
+            last_offset = current_offset;
+
+            tsk_fs_close(fs_info);
+        }
+    }
+
+    // Finally, create a dummy unallocated volume for the area between the
+    // last offset and the end of the image.
+   if (last_offset < m_img_info->size)
+    {
+        createDummyVolume(last_offset / m_img_info->sector_size,
+            (m_img_info->size - last_offset) / m_img_info->sector_size,
+            "Dummy volume for carving purposes",
+            TSK_VS_PART_FLAG_UNALLOC);
+    }
+
+    LOGINFO(L"TSKAutoImpl::scanImgForFs - File system scan complete.");
+
+    return 0;
+}
+
+TSK_FILTER_ENUM TSKAutoImpl::filterVol(const TSK_VS_PART_INFO * a_vsPart)
+{
+    // flag that this image has a volume system
+    m_vsSeen = true;
+    m_db.addVolumeInfo(a_vsPart);
+
+    m_curVsId = a_vsPart->addr;
+
+    std::wstringstream msg;
+    msg << L"TSKAutoImpl::filterVol - Discovered " << a_vsPart->desc 
+        << L" partition (sectors " << a_vsPart->start << L"-" 
+        << ((a_vsPart->start + a_vsPart->len) - 1) << L")";
+    LOGINFO(msg.str());
+
+    // we only want to process the allocated volumes
+    if ((a_vsPart->flags & TSK_VS_PART_FLAG_ALLOC) == 0)
+        return TSK_FILTER_SKIP;
+
+    return TSK_FILTER_CONT;
+}
+
+
+TSK_FILTER_ENUM TSKAutoImpl::filterFs(TSK_FS_INFO * a_fsInfo)
+{
+    // add a volume entry if there is no file system
+    if (m_vsSeen == false) 
+    {
+        TSK_DADDR_T start_sect = a_fsInfo->offset / a_fsInfo->img_info->sector_size;
+        TSK_DADDR_T end_sect = start_sect + 
+            ((a_fsInfo->block_count * a_fsInfo->block_size) / a_fsInfo->img_info->sector_size);
+
+        createDummyVolume(start_sect, (end_sect - start_sect) + 1,
+                          "Dummy volume for file system",
+                          TSK_VS_PART_FLAG_ALLOC);
+    }
+
+    m_curFsId++;
+    m_db.addFsInfo(m_curVsId, m_curFsId, a_fsInfo);
+
+    /* Process the root directory so that its contents are added to
+     * the DB.  We won't see it during the dir_walk. */
+    TSK_FS_FILE *fs_file = tsk_fs_file_open(a_fsInfo, NULL, "/");
+    if (fs_file != NULL)
+    {
+        processFile(fs_file, "\\");
+    }
+
+    // make sure that flags are set to get all files -- we need this to
+    // find parent directory
+    setFileFilterFlags((TSK_FS_DIR_WALK_FLAG_ENUM)
+        (TSK_FS_DIR_WALK_FLAG_ALLOC | TSK_FS_DIR_WALK_FLAG_UNALLOC));
+
+    std::wstringstream msg;
+    msg << L"TSKAutoImpl::filterFs - Discovered " << tsk_fs_type_toname(a_fsInfo->ftype) 
+        << L" file system at offset " << a_fsInfo->offset << L" with Id : " << m_curFsId;
+    LOGINFO(msg.str());
+
+    return TSK_FILTER_CONT;
+}
+
+/* Insert the file data into the file table.
+ * @returns OK on success, COR on error because of the data (and we should keep on processing more files), 
+ * and ERR because of system error (and we shoudl proabably stop processing)
+ */
+TSK_RETVAL_ENUM TSKAutoImpl::insertFileData(TSK_FS_FILE * a_fsFile,
+    const TSK_FS_ATTR * a_fsAttr, const char * a_path, uint64_t & fileId)
+{
+    int type = TSK_FS_ATTR_TYPE_NOT_FOUND;
+    int idx = 0;
+    fileId = 0;
+
+    if (a_fsFile->name == NULL) {
+        LOGERROR(L"TSKAutoImpl::insertFileData name value is NULL");
+        return TSK_COR;
+    }
+
+    size_t attr_len = 0;
+    if (a_fsAttr) {
+        type = a_fsAttr->type;
+        idx = a_fsAttr->id;
+        if (a_fsAttr->name)
+        {
+            if ((a_fsAttr->type != TSK_FS_ATTR_TYPE_NTFS_IDXROOT) ||
+                (strcmp(a_fsAttr->name, "$I30") != 0))
+            {
+                attr_len = strlen(a_fsAttr->name);
+            }
+        }
+    }
+
+    // clean up special characters in name before we insert
+    size_t len = strlen(a_fsFile->name->name);
+    char *name;
+    size_t nlen = 2 * (len + attr_len);
+    if ((name = (char *) malloc(nlen + 1)) == NULL)
+    {
+        LOGERROR(L"Error allocating memory");
+        return TSK_ERR;
+    }
+    memset(name, 0, nlen+1);
+
+    size_t j = 0;
+    for (size_t i = 0; i < len && j < nlen; i++)
+    {
+        // ' is special in SQLite
+        if (a_fsFile->name->name[i] == '\'')
+        {
+            name[j++] = '\'';
+            name[j++] = '\'';
+        }
+        else
+        {
+            name[j++] = a_fsFile->name->name[i];
+        }
+    }
+
+    // Add the attribute name
+    if (attr_len > 0) {
+        name[j++] = ':';
+
+        for (unsigned i = 0; i < attr_len && j < nlen; i++) {
+            // ' is special in SQLite
+            if (a_fsAttr->name[i] == '\'')
+            {
+                name[j++] = '\'';
+                name[j++] = '\'';
+            }
+            else
+            {
+                name[j++] = a_fsAttr->name[i];
+            }
+        }
+    }
+
+    int result = m_db.addFsFileInfo(m_curFsId, a_fsFile, name, type, idx, fileId, a_path);
+    free(name);
+
+    // Message was already logged
+    if (result) {
+        return TSK_COR;
+    }
+    
+    Scheduler::task_struct task;
+    task.task = Scheduler::FileAnalysis;
+    task.id = fileId;
+    m_filesToSchedule.push(task);
+
+    return TSK_OK;
+}
+
+
+/* Based on the error handling design, we only return OK or STOP.  All
+ * other errors have been handled, so we don't return ERROR to TSK. */
+TSK_RETVAL_ENUM TSKAutoImpl::processFile(TSK_FS_FILE * a_fsFile, const char * a_path)
+{
+    // skip the . and .. dirs
+    if (isDotDir(a_fsFile) == 1)
+    {
+        return TSK_OK;
+    }
+
+    TSK_RETVAL_ENUM retval;
+    // process the attributes if there are more than 1
+    if (tsk_fs_file_attr_getsize(a_fsFile) == 0)
+    {
+        uint64_t fileId;
+        // If COR is returned, then keep on going. 
+        if (insertFileData(a_fsFile, NULL, a_path, fileId) == TSK_ERR) {
+            retval = TSK_STOP;
+        }
+        else {
+            m_numFilesSeen++;
+            retval = TSK_OK;
+        }
+    }
+    else
+    {
+        retval = processAttributes(a_fsFile, a_path);
+    }
+
+    time_t timeNow = time(NULL);
+    if ((timeNow - m_lastUpdateMsg) > 3600)
+    {
+        m_lastUpdateMsg = timeNow;
+        std::wstringstream msg;
+        msg << L"TSKAutoImpl::processFile : Processed " << m_numFilesSeen << " files.";
+        LOGINFO(msg.str());
+    }
+
+    if (m_filesToSchedule.size() > m_numOfFilesToQueue) {
+        commitAndSchedule();
+        m_db.begin();
+    }
+
+    return retval;
+}
+
+/**
+ * commits the open transaction and schedules the files that
+ * were queued up as being part of that transaction.
+ * Does not create a new transaction.
+ */
+void TSKAutoImpl::commitAndSchedule()
+{
+    m_db.commit();
+
+    while (m_filesToSchedule.size() > 0) {
+        Scheduler::task_struct &task = m_filesToSchedule.front();
+        if (TskServices::Instance().getScheduler().schedule(task)) {
+            LOGERROR(L"Error adding file for scheduling");
+        }
+        m_filesToSchedule.pop();
+    }
+}
+
+uint8_t TSKAutoImpl::handleError()
+{
+    const char * tskMsg = tsk_error_get();
+
+    // @@@ Possibly test tsk_errno to determine how the message should be logged.
+    if (tskMsg != NULL)
+    {
+        std::wstringstream msg;
+        msg << L"TskAutoImpl::handleError " << tsk_error_get();
+
+        LOGWARN(msg.str());
+    }
+    return 0;
+}
+
+
+
+/* Based on the error handling design, we only return OK or STOP.  All
+ * other errors have been handled, so we don't return ERROR to TSK. */
+TSK_RETVAL_ENUM TSKAutoImpl::processAttribute(TSK_FS_FILE * a_fsFile,
+    const TSK_FS_ATTR * a_fsAttr, const char * a_path)
+{
+    uint64_t mFileId = 0;
+
+    // add the file metadata for the default attribute type
+    if (isDefaultType(a_fsFile, a_fsAttr))
+    {
+        // if COR is returned, then keep on going.
+        if (insertFileData(a_fsAttr->fs_file, a_fsAttr, a_path, mFileId) == TSK_ERR)
+            return TSK_STOP;
+    }
+
+    // add the block map, if the file is non-resident
+    if (isNonResident(a_fsAttr))
+    {
+        TSK_FS_ATTR_RUN *run;
+        int count = 0;
+        for (run = a_fsAttr->nrd.run; run != NULL; run = run->next)
+        {
+            // ignore sparse blocks
+            if (run->flags & TSK_FS_ATTR_RUN_FLAG_SPARSE)
+                continue;
+            
+            if (m_db.addFsBlockInfo(m_curFsId, mFileId, count++, run->addr, run->len))
+            {
+                // this error should have been logged.
+                // we'll continue to try processing the file
+            }
+        }
+    }
+     
+    return TSK_OK;
+}
+
+void TSKAutoImpl::createDummyVolume(const TSK_DADDR_T sect_start, const TSK_DADDR_T sect_len, 
+                                    const char * desc, TSK_VS_PART_FLAG_ENUM flags)
+{
+    m_curVsId++;
+
+    TSK_VS_PART_INFO part;
+    part.addr = m_curVsId;
+    part.len = sect_len;
+    part.start = sect_start;
+    part.flags = flags;
+    part.desc = (char *)desc; // remove the cast when TSK_VS_PART_INFO.desc is const char *
+
+    if (m_db.addVolumeInfo(&part))
+    {
+        LOGERROR(L"TSKAutoImpl::createDummyVolume - Error creating volume.");
+    }
+}
diff --git a/framework/tsk/framework/extraction/TskAutoImpl.h b/framework/tsk/framework/extraction/TskAutoImpl.h
index 0426743..12b47a4 100755
--- a/framework/tsk/framework/extraction/TskAutoImpl.h
+++ b/framework/tsk/framework/extraction/TskAutoImpl.h
@@ -1,70 +1,70 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-#include "tsk/framework/framework_i.h"
-
-#ifndef _TSK_AUTO_IMPL_H
-#define _TSK_AUTO_IMPL_H
-
-#ifdef __cplusplus
-
-// Include the other TSK header files
-#include "tsk/libtsk.h"
-#include "tsk/framework/services/TskImgDB.h"
-#include "tsk/framework/services/Scheduler.h"
-#include <map>
-#include <string>
-#include <queue>
-
-/** 
- * Implements TskAuto and is used to analyze the data in a disk image
- * and populate TskImgDB with the results.  Call extractFiles() after
- * image has been opened.
- * Will queue up files and submit them after m_numOfFilesToQueue files
- * are added to the queue.
- */
-class TSK_FRAMEWORK_API TSKAutoImpl:public TskAuto {
-public:
-    TSKAutoImpl();
-    virtual ~ TSKAutoImpl();
-
-    virtual uint8_t openImage(TSK_IMG_INFO *);
-    virtual void closeImage();
-
-    virtual TSK_FILTER_ENUM filterVol(const TSK_VS_PART_INFO * vs_part);
-    virtual TSK_FILTER_ENUM filterFs(TSK_FS_INFO * fs_info);
-    virtual TSK_RETVAL_ENUM processFile(TSK_FS_FILE * fs_file, const char *path);
-    virtual uint8_t handleError();
-    uint8_t extractFiles();
-    uint8_t scanImgForFs(const uint64_t sect_start, const uint64_t sect_count = 1024);
-
-private:
-    TskImgDB &m_db;
-    int m_curFsId;
-    int m_curVsId;
-    bool m_vsSeen;
-    uint64_t m_numFilesSeen;
-    time_t m_lastUpdateMsg;
-    std::queue<Scheduler::task_struct> m_filesToSchedule;   ///< Scheduler tasks to submit once transaction is commited
-    static const unsigned int m_numOfFilesToQueue = 1000;    ///< max number of files to queue up in a transaction before commiting
-
-    TSK_RETVAL_ENUM insertFileData(TSK_FS_FILE * fs_file,
-        const TSK_FS_ATTR *, const char *path, uint64_t & fileId);
-    TSK_RETVAL_ENUM insertBlockData(const TSK_FS_ATTR * fs_attr);
-    virtual TSK_RETVAL_ENUM processAttribute(TSK_FS_FILE *,
-        const TSK_FS_ATTR * fs_attr, const char *path);
-    void createDummyVolume(const TSK_DADDR_T sect_start, const TSK_DADDR_T sect_len, 
-                           const char * desc, TSK_VS_PART_FLAG_ENUM flags);
-    void commitAndSchedule();
-};
-
-#endif
-
-#endif
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+#include "tsk/framework/framework_i.h"
+
+#ifndef _TSK_AUTO_IMPL_H
+#define _TSK_AUTO_IMPL_H
+
+#ifdef __cplusplus
+
+// Include the other TSK header files
+#include "tsk/libtsk.h"
+#include "tsk/framework/services/TskImgDB.h"
+#include "tsk/framework/services/Scheduler.h"
+#include <map>
+#include <string>
+#include <queue>
+
+/** 
+ * Implements TskAuto and is used to analyze the data in a disk image
+ * and populate TskImgDB with the results.  Call extractFiles() after
+ * image has been opened.
+ * Will queue up files and submit them after m_numOfFilesToQueue files
+ * are added to the queue.
+ */
+class TSK_FRAMEWORK_API TSKAutoImpl:public TskAuto {
+public:
+    TSKAutoImpl();
+    virtual ~ TSKAutoImpl();
+
+    virtual uint8_t openImage(TSK_IMG_INFO *);
+    virtual void closeImage();
+
+    virtual TSK_FILTER_ENUM filterVol(const TSK_VS_PART_INFO * vs_part);
+    virtual TSK_FILTER_ENUM filterFs(TSK_FS_INFO * fs_info);
+    virtual TSK_RETVAL_ENUM processFile(TSK_FS_FILE * fs_file, const char *path);
+    virtual uint8_t handleError();
+    uint8_t extractFiles();
+    uint8_t scanImgForFs(const uint64_t sect_start, const uint64_t sect_count = 1024);
+
+private:
+    TskImgDB &m_db;
+    int m_curFsId;
+    int m_curVsId;
+    bool m_vsSeen;
+    uint64_t m_numFilesSeen;
+    time_t m_lastUpdateMsg;
+    std::queue<Scheduler::task_struct> m_filesToSchedule;   ///< Scheduler tasks to submit once transaction is commited
+    static const unsigned int m_numOfFilesToQueue = 1000;    ///< max number of files to queue up in a transaction before commiting
+
+    TSK_RETVAL_ENUM insertFileData(TSK_FS_FILE * fs_file,
+        const TSK_FS_ATTR *, const char *path, uint64_t & fileId);
+    TSK_RETVAL_ENUM insertBlockData(const TSK_FS_ATTR * fs_attr);
+    virtual TSK_RETVAL_ENUM processAttribute(TSK_FS_FILE *,
+        const TSK_FS_ATTR * fs_attr, const char *path);
+    void createDummyVolume(const TSK_DADDR_T sect_start, const TSK_DADDR_T sect_len, 
+                           const char * desc, TSK_VS_PART_FLAG_ENUM flags);
+    void commitAndSchedule();
+};
+
+#endif
+
+#endif
diff --git a/framework/tsk/framework/extraction/TskCarveExtractScalpel.cpp b/framework/tsk/framework/extraction/TskCarveExtractScalpel.cpp
index bd5bc48..10525c6 100644
--- a/framework/tsk/framework/extraction/TskCarveExtractScalpel.cpp
+++ b/framework/tsk/framework/extraction/TskCarveExtractScalpel.cpp
@@ -1,389 +1,389 @@
-/*
- *
- *  The Sleuth Kit
- *
- *  Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- *  Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- *  reserved.
- *
- *  This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskCarveExtractScalpel.cpp
- * Contains the implementation of the TskCarveExtractScalpel class.
- */
-
-// Include the class definition first to ensure it does not depend on subsequent includes in this file.
-#include "TskCarveExtractScalpel.h"
-
-// TSK Framework includes
-#include "tsk/framework/services/TskServices.h"
-#include "tsk/framework/services/TskImgDB.h"
-#include "tsk/framework/utilities/TskUtilities.h"
-#include "tsk/framework/utilities/UnallocRun.h"
-#include "tsk/framework/utilities/TskException.h"
-
-// Poco includes
-#include "Poco/Path.h"
-#include "Poco/File.h"
-#include "Poco/Process.h"
-#include "Poco/Pipe.h"
-#include "Poco/PipeStream.h"
-#include "Poco/FileStream.h"
-#include "Poco/StreamCopier.h"
-#include "Poco/StringTokenizer.h"
-#include "Poco/Exception.h"
-
-// C/C++ library includes
-#include <sstream>
-#include <fstream>
-#include <cstdlib>
-#include <vector>
-#include <algorithm>
-#include <memory>
-
-namespace
-{
-#ifdef TSK_WIN32
-    const std::string SCALPEL_EXE_FILE_NAME = "scalpel.exe";
-#else
-    const std::string SCALPEL_EXE_FILE_NAME = "scalpel";
-#endif
-    const std::string CARVED_FILES_FOLDER = "CarvedFiles";
-    const std::string SCALPEL_RESULTS_FILE_NAME = "audit.txt";
-    const std::string STD_OUT_DUMP_FILE_NAME = "stdout.txt";
-    const std::string STD_ERR_DUMP_FILE_NAME = "stderr.txt";
-}
-
-int TskCarveExtractScalpel::processFile(int unallocImgId)
-{
-    TskImgDB *imgDB = NULL; 
-    try
-    {
-        imgDB = &TskServices::Instance().getImgDB();
-
-        // Get the input folder path. The file to carve resides in a subdirectory of the carve prep output folder. The name of the subdirectory is the unallocated image file id.
-        std::string carvePrepOutputPath = GetSystemProperty("CARVE_DIR");
-        if (!Poco::File(carvePrepOutputPath).exists())
-        {
-            std::stringstream msg;
-            msg << "TskCarveExtractScalpel::processFile : specified carve prep output folder '" << carvePrepOutputPath << "' does not exist";
-            throw TskException(msg.str());
-        }
-        std::stringstream inputFolderPathBuilder; 
-        inputFolderPathBuilder << carvePrepOutputPath << Poco::Path::separator() << unallocImgId;
-    
-        // Get the input file name and construct the input file path. All of the files to carve have the same name.
-        std::string carvePrepOutputFileName = GetSystemProperty("UNALLOC_SECTORS_IMG_FILE_NAME");
-        std::stringstream unallocImgFilePathBuilder;
-        unallocImgFilePathBuilder << inputFolderPathBuilder.str() <<  Poco::Path::separator() << carvePrepOutputFileName;
-        Poco::File unallocImgFile(unallocImgFilePathBuilder.str());
-
-        if (!unallocImgFile.exists())
-        {
-            std::stringstream msg;
-            msg << "TskCarveExtractScalpel::processFile : did not find unalloc img file number " << unallocImgId << " at '" << unallocImgFilePathBuilder.str() << "'";
-            throw TskException(msg.str());
-        }
-
-        if (unallocImgFile.getSize() > static_cast<Poco::File::FileSize>(0))
-        {
-            // Attempt to carve the file, storing the carved files in a subdirectory of the input folder and the Scalpel console output in the input folder.
-            // The console output is placed in the input folder rather than the output folder because Scalpel will only write to an empty directory.
-            std::stringstream outputFolderPath;
-            outputFolderPath << inputFolderPathBuilder.str() << Poco::Path::separator() << CARVED_FILES_FOLDER;
-            std::stringstream stdOutFilePath;
-            stdOutFilePath << inputFolderPathBuilder.str() << Poco::Path::separator() << STD_OUT_DUMP_FILE_NAME;
-            std::stringstream stdErrFilePath;
-            stdErrFilePath << inputFolderPathBuilder.str() << Poco::Path::separator() << STD_ERR_DUMP_FILE_NAME;
-            carveFile(unallocImgFilePathBuilder.str(), outputFolderPath.str(), stdOutFilePath.str(), stdErrFilePath.str());
-
-            // Scalpel lists any files it carves out in a results file. Use the file list to add the files to the image DB and copy them to file storage.
-            std::stringstream resultsFilePath;
-            resultsFilePath << outputFolderPath.str() << Poco::Path::separator() << SCALPEL_RESULTS_FILE_NAME;
-            processCarvedFiles(outputFolderPath.str(), parseCarvingResultsFile(unallocImgId, resultsFilePath.str()));
-
-            // Update the unused sector info in the image database so it is known which of the unallocated sectors just carved did not go into a carved file.
-            if (m_createUnusedSectorFiles)
-            {
-                std::vector<TskUnusedSectorsRecord> unusedSectorsList;
-                imgDB->addUnusedSectors(unallocImgId, unusedSectorsList);
-            }
-        }
-        else
-        {
-            // There is nothing to do if the file to be carved is of length zero.
-            imgDB->setUnallocImgStatus(unallocImgId, TskImgDB::IMGDB_UNALLOC_IMG_STATUS_CARVED_NOT_NEEDED);
-        }
-
-        return 0;
-    }
-    catch (TskException &ex)
-    {
-        LOGERROR(TskUtilities::toUTF16(ex.message()));
-
-        if (imgDB)
-        {
-            imgDB->setUnallocImgStatus(unallocImgId, TskImgDB::IMGDB_UNALLOC_IMG_STATUS_CARVED_ERR);
-        }
-
-        return 1;
-    }
-}
-
-void TskCarveExtractScalpel::carveFile(const std::string &unallocImgPath, const std::string &outputFolderPath, const std::string &stdOutFilePath, const std::string &stdErrFilePath) const
-{
-    try
-    {
-        // Find out where Scalpel is installed.
-        std::string scalpelDirPath = GetSystemProperty("SCALPEL_DIR");
-        if (scalpelDirPath.empty())
-        {
-            throw TskException("TskCarveExtractScalpel::configure : Scalpel directory not set");
-        }
-
-        if (!Poco::File(scalpelDirPath).exists())
-        {
-            std::stringstream msg;
-            msg << "TskCarveExtractScalpel::configure : specified Scalpel directory '" << scalpelDirPath << "' does not exist";
-            throw TskException(msg.str());
-        }
-
-        // Get the path to the Scalpel executable.
-        std::stringstream pathBuilder;
-        pathBuilder << scalpelDirPath << Poco::Path::separator() << SCALPEL_EXE_FILE_NAME;
-        std::string scalpelExePath = pathBuilder.str();
-        if (!Poco::File(scalpelExePath).exists())
-        {
-            std::stringstream msg;
-            msg << "TskCarveExtractScalpel::configure : Scalpel executable '" << scalpelExePath << "' does not exist";
-            throw TskException(msg.str());
-        }
-
-        // Get the path to the Scalpel config file.
-        std::string scalpelConfigFilePath = GetSystemProperty("SCALPEL_CONFIG_FILE");
-        if (!Poco::File(scalpelConfigFilePath).exists())
-        {
-            std::stringstream msg;
-            msg << "TskCarveExtractScalpel::TskCarveExtractScalpel : Scalpel config file '" << scalpelConfigFilePath << "' does not exist";
-            throw TskException(msg.str());
-        }
-
-        // Set the Scalpel command line: specify the Scalpel config file.
-        Poco::Process::Args args;
-        args.push_back("-c");
-        args.push_back(scalpelConfigFilePath);
-
-        // Set the Scalpel command line: allow for nested headers and footers.
-        args.push_back("-e");
-        
-        // Set the Scalpel command line: put any carved files directly into the output folder.
-        args.push_back("-o");
-        args.push_back(outputFolderPath);
-        args.push_back("-O");
-
-        // Set the Scalpel command line: specify the file to carve.
-        args.push_back(unallocImgPath);
-
-        // Launch Scalpel with console output redirects.
-        Poco::Pipe outPipe;
-        Poco::Pipe errPipe;
-        Poco::ProcessHandle handle = Poco::Process::launch(scalpelExePath, args, NULL, &outPipe, &errPipe);
-
-        // Capture the console output. Note that Scalpel may block at times as it waits for this loop to empty the stream buffers.
-        Poco::PipeInputStream stdOutInputStream(outPipe);
-        Poco::FileOutputStream stdOutOutputStream(stdOutFilePath);
-        Poco::PipeInputStream stdErrInputStream(errPipe);
-        Poco::FileOutputStream stdErrOutputStream(stdErrFilePath);
-        while (stdOutInputStream || stdErrInputStream)
-        {
-            if (stdOutInputStream)
-            {
-                Poco::StreamCopier::copyStream(stdOutInputStream, stdOutOutputStream);
-            }
-
-            if (stdErrInputStream)
-            {
-                Poco::StreamCopier::copyStream(stdErrInputStream, stdErrOutputStream);
-            }
-        }
-    
-        // Scalpel should be finished since the console output streams are closed.
-        int exitCode = Poco::Process::wait(handle);
-
-        stdOutOutputStream.flush();
-        stdErrOutputStream.flush();
-
-        // On the first invocation of Scalpel, record its use in the image database.
-        static bool toolInfoRecorded = false;
-        if (!toolInfoRecorded)
-        {
-            std::ifstream stdOutStream(stdOutFilePath.c_str());
-            if (stdOutStream)
-            {
-                std::string versionString;
-                std::getline(stdOutStream, versionString);
-                Poco::StringTokenizer tokenizer(versionString, "\t ", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM); 
-                if (tokenizer[0] == "Scalpel" && tokenizer[1] == "version")
-                {
-                    TskServices::Instance().getImgDB().addToolInfo("Scalpel", tokenizer[2].c_str());
-                    toolInfoRecorded = true;
-                }
-                else
-                {
-                    LOGWARN("TskCarveExtractScalpel::carveFile : Scalpel stdout output format changed, cannot record tool info");
-                }
-            }
-            else
-            {
-                LOGWARN("TskCarveExtractScalpel::carveFile : failed to open stdout stream, cannot record tool info");
-            }
-        }
-
-        // Delete input files by default.
-        std::string option = GetSystemProperty("CARVE_EXTRACT_KEEP_INPUT_FILES");
-        std::transform(option.begin(), option.end(), option.begin(), ::toupper);
-        bool deleteInputFiles = (option != "TRUE");
-
-        if (deleteInputFiles)
-        {
-            Poco::File file(unallocImgPath);
-            file.remove();
-        }
-
-        if (exitCode != 0)
-        {
-            std::stringstream msg;
-            msg << "TskCarveExtractScalpel::carveFile : Scalpel exited with error exit code " << exitCode << " when carving '" << unallocImgPath.c_str() << "'";
-            throw TskException(msg.str());
-        }
-    }
-    catch (Poco::Exception &ex)
-    {
-        std::stringstream msg;
-        msg << "TskCarveExtractScalpel::carveFile : Poco exception: " << ex.displayText();
-        throw TskException(msg.str());
-    }
-}
-
-std::vector<TskCarveExtractScalpel::CarvedFile> TskCarveExtractScalpel::parseCarvingResultsFile(int unallocImgId, const std::string &resultsFilePath) const
-{
-    try
-    {
-        std::vector<CarvedFile> carvedFiles;
-
-        Poco::File resultsFile(resultsFilePath);
-        if (!resultsFile.exists())
-        {
-            std::stringstream msg;
-            msg << "TskCarveExtractScalpel::parseCarvingResultsFile : could not find Scalpel carving results file for unalloc img id " << unallocImgId;
-            throw TskException(msg.str());
-        }
-        
-        std::ifstream resultsStream(resultsFilePath.c_str());
-        if (!resultsStream)
-        {
-            std::stringstream msg;
-            msg << "TskCarveExtractScalpel::parseCarvingResultsFile : unable to open Scalpel carving results file for unalloc img id " << unallocImgId;
-            throw TskException(msg.str());
-        }
-
-        // Discard all of the file up to and including the header for the carved files list.
-        std::string line;
-        while (std::getline(resultsStream, line) && line.find("Extracted From") == std::string::npos);
-
-        // Parse the files list.
-        const std::size_t numberOfFileFields = 5;
-        while (std::getline(resultsStream, line))
-        {
-            // Tokenize the next line of the results file and see if it is part of the files list by checking the number of tokens.
-            Poco::StringTokenizer tokenizer(line, "\t ", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM); 
-            if (tokenizer.count() != numberOfFileFields)
-            {
-                // No more files in the files list.
-                break;
-            }
-
-            carvedFiles.push_back(CarvedFile(unallocImgId, tokenizer[0], tokenizer[1], tokenizer[3]));
-        }
-
-        resultsStream.close();
-
-        return carvedFiles;
-    }
-    catch (Poco::Exception &ex)
-    {
-        std::stringstream msg;
-        msg << "TskCarveExtractScalpel::parseCarvingResultsFile : Poco exception: " <<  ex.displayText();
-        throw TskException(msg.str());
-    }
-}
-
-void TskCarveExtractScalpel::processCarvedFiles(const std::string &outputFolderPath, const std::vector<TskCarveExtractScalpel::CarvedFile> &carvedFiles) const
-{
-    try
-    {
-        TskImgDB& imgDB = TskServices::Instance().getImgDB();
-        const uint64_t sectorSize = 512;
-
-        for (std::vector<CarvedFile>::const_iterator file = carvedFiles.begin(); file != carvedFiles.end(); ++file)
-        {
-            std::stringstream filePath;
-            filePath << outputFolderPath << Poco::Path::separator() << (*file).name;
-
-            // Convert the starting offset (in bytes) of the carved file in the unallocated image file the and length of the carved file (in bytes)
-            // into a range of "sectors."
-            int fileStartSectorOffset = static_cast<int>((*file).offset / sectorSize); 
-            int fileEndSectorOffset = static_cast<int>(((*file).offset + (*file).length) / sectorSize); 
-            
-            // Get the unallocated sectors run corresponding to the unallocated image file and map the file sector offsets to image sector offset and length. 
-            std::auto_ptr<UnallocRun> run(imgDB.getUnallocRun((*file).id, fileStartSectorOffset));
-            int numberOfRuns = 1;
-            uint64_t sectorRunStart[] = { run->getAllocStart() + fileStartSectorOffset - run->getUnallocStart() };
-            uint64_t sectorRunLength[] = { run->getAllocStart() + fileEndSectorOffset - run->getUnallocStart() - sectorRunStart[0] };
-
-            // Add the mapping to the image database.
-            uint64_t fileId;
-            if (imgDB.addCarvedFileInfo(run->getVolId(), (*file).name.c_str(), (*file).length, &sectorRunStart[0], &sectorRunLength[0], numberOfRuns, fileId) == -1)
-            {
-                std::stringstream msg;
-                msg << "TskCarveExtractScalpel::processCarvedFiles : unable to save carved file info for '" << filePath.str() << "'";
-                throw TskException(msg.str());
-            }
-
-            std::wstring f(TskUtilities::toUTF16(filePath.str()));
-            TskServices::Instance().getFileManager().addFile(fileId, f);
-
-            // Delete output (carved) files by default.
-            std::string option = GetSystemProperty("CARVE_EXTRACT_KEEP_OUTPUT_FILES");
-            std::transform(option.begin(), option.end(), option.begin(), ::toupper);
-            bool deleteOutputFiles = (option != "TRUE");
-
-            if (deleteOutputFiles)
-            {
-                Poco::File file(filePath.str());
-                file.remove();
-            }
-
-            if (imgDB.updateFileStatus(fileId, TskImgDB::IMGDB_FILES_STATUS_READY_FOR_ANALYSIS) == 1)
-            {
-                std::stringstream msg;
-                msg << "TskCarveExtractScalpel::processCarvedFiles : unable to update file status for '" << filePath.str() << "'";
-                throw TskException(msg.str());
-            }
-        }
-    }
-    catch (Poco::Exception &ex)
-    {
-        std::stringstream msg;
-        msg << "TskCarveExtractScalpel::processCarvedFiles : Poco exception: " <<  ex.displayText();
-        throw TskException(msg.str());
-    }
-}
-
-// @@@ TODO: Replace strtoul() call with a strtoull() call when a newer version of C++ is available.
-TskCarveExtractScalpel::CarvedFile::CarvedFile(int unallocImgId, const std::string &fileName, const std::string &offsetInBytes, const std::string &lengthInBytes) : 
-    id(unallocImgId), name(fileName), offset(strtoul(offsetInBytes.c_str(), 0, 10)), length(strtoul(lengthInBytes.c_str(), 0, 10))
-{
-}
+/*
+ *
+ *  The Sleuth Kit
+ *
+ *  Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ *  Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ *  reserved.
+ *
+ *  This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file TskCarveExtractScalpel.cpp
+ * Contains the implementation of the TskCarveExtractScalpel class.
+ */
+
+// Include the class definition first to ensure it does not depend on subsequent includes in this file.
+#include "TskCarveExtractScalpel.h"
+
+// TSK Framework includes
+#include "tsk/framework/services/TskServices.h"
+#include "tsk/framework/services/TskImgDB.h"
+#include "tsk/framework/utilities/TskUtilities.h"
+#include "tsk/framework/utilities/UnallocRun.h"
+#include "tsk/framework/utilities/TskException.h"
+
+// Poco includes
+#include "Poco/Path.h"
+#include "Poco/File.h"
+#include "Poco/Process.h"
+#include "Poco/Pipe.h"
+#include "Poco/PipeStream.h"
+#include "Poco/FileStream.h"
+#include "Poco/StreamCopier.h"
+#include "Poco/StringTokenizer.h"
+#include "Poco/Exception.h"
+
+// C/C++ library includes
+#include <sstream>
+#include <fstream>
+#include <cstdlib>
+#include <vector>
+#include <algorithm>
+#include <memory>
+
+namespace
+{
+#ifdef TSK_WIN32
+    const std::string SCALPEL_EXE_FILE_NAME = "scalpel.exe";
+#else
+    const std::string SCALPEL_EXE_FILE_NAME = "scalpel";
+#endif
+    const std::string CARVED_FILES_FOLDER = "CarvedFiles";
+    const std::string SCALPEL_RESULTS_FILE_NAME = "audit.txt";
+    const std::string STD_OUT_DUMP_FILE_NAME = "stdout.txt";
+    const std::string STD_ERR_DUMP_FILE_NAME = "stderr.txt";
+}
+
+int TskCarveExtractScalpel::processFile(int unallocImgId)
+{
+    TskImgDB *imgDB = NULL; 
+    try
+    {
+        imgDB = &TskServices::Instance().getImgDB();
+
+        // Get the input folder path. The file to carve resides in a subdirectory of the carve prep output folder. The name of the subdirectory is the unallocated image file id.
+        std::string carvePrepOutputPath = GetSystemProperty("CARVE_DIR");
+        if (!Poco::File(carvePrepOutputPath).exists())
+        {
+            std::stringstream msg;
+            msg << "TskCarveExtractScalpel::processFile : specified carve prep output folder '" << carvePrepOutputPath << "' does not exist";
+            throw TskException(msg.str());
+        }
+        std::stringstream inputFolderPathBuilder; 
+        inputFolderPathBuilder << carvePrepOutputPath << Poco::Path::separator() << unallocImgId;
+    
+        // Get the input file name and construct the input file path. All of the files to carve have the same name.
+        std::string carvePrepOutputFileName = GetSystemProperty("UNALLOC_SECTORS_IMG_FILE_NAME");
+        std::stringstream unallocImgFilePathBuilder;
+        unallocImgFilePathBuilder << inputFolderPathBuilder.str() <<  Poco::Path::separator() << carvePrepOutputFileName;
+        Poco::File unallocImgFile(unallocImgFilePathBuilder.str());
+
+        if (!unallocImgFile.exists())
+        {
+            std::stringstream msg;
+            msg << "TskCarveExtractScalpel::processFile : did not find unalloc img file number " << unallocImgId << " at '" << unallocImgFilePathBuilder.str() << "'";
+            throw TskException(msg.str());
+        }
+
+        if (unallocImgFile.getSize() > static_cast<Poco::File::FileSize>(0))
+        {
+            // Attempt to carve the file, storing the carved files in a subdirectory of the input folder and the Scalpel console output in the input folder.
+            // The console output is placed in the input folder rather than the output folder because Scalpel will only write to an empty directory.
+            std::stringstream outputFolderPath;
+            outputFolderPath << inputFolderPathBuilder.str() << Poco::Path::separator() << CARVED_FILES_FOLDER;
+            std::stringstream stdOutFilePath;
+            stdOutFilePath << inputFolderPathBuilder.str() << Poco::Path::separator() << STD_OUT_DUMP_FILE_NAME;
+            std::stringstream stdErrFilePath;
+            stdErrFilePath << inputFolderPathBuilder.str() << Poco::Path::separator() << STD_ERR_DUMP_FILE_NAME;
+            carveFile(unallocImgFilePathBuilder.str(), outputFolderPath.str(), stdOutFilePath.str(), stdErrFilePath.str());
+
+            // Scalpel lists any files it carves out in a results file. Use the file list to add the files to the image DB and copy them to file storage.
+            std::stringstream resultsFilePath;
+            resultsFilePath << outputFolderPath.str() << Poco::Path::separator() << SCALPEL_RESULTS_FILE_NAME;
+            processCarvedFiles(outputFolderPath.str(), parseCarvingResultsFile(unallocImgId, resultsFilePath.str()));
+
+            // Update the unused sector info in the image database so it is known which of the unallocated sectors just carved did not go into a carved file.
+            if (m_createUnusedSectorFiles)
+            {
+                std::vector<TskUnusedSectorsRecord> unusedSectorsList;
+                imgDB->addUnusedSectors(unallocImgId, unusedSectorsList);
+            }
+        }
+        else
+        {
+            // There is nothing to do if the file to be carved is of length zero.
+            imgDB->setUnallocImgStatus(unallocImgId, TskImgDB::IMGDB_UNALLOC_IMG_STATUS_CARVED_NOT_NEEDED);
+        }
+
+        return 0;
+    }
+    catch (TskException &ex)
+    {
+        LOGERROR(TskUtilities::toUTF16(ex.message()));
+
+        if (imgDB)
+        {
+            imgDB->setUnallocImgStatus(unallocImgId, TskImgDB::IMGDB_UNALLOC_IMG_STATUS_CARVED_ERR);
+        }
+
+        return 1;
+    }
+}
+
+void TskCarveExtractScalpel::carveFile(const std::string &unallocImgPath, const std::string &outputFolderPath, const std::string &stdOutFilePath, const std::string &stdErrFilePath) const
+{
+    try
+    {
+        // Find out where Scalpel is installed.
+        std::string scalpelDirPath = GetSystemProperty("SCALPEL_DIR");
+        if (scalpelDirPath.empty())
+        {
+            throw TskException("TskCarveExtractScalpel::configure : Scalpel directory not set");
+        }
+
+        if (!Poco::File(scalpelDirPath).exists())
+        {
+            std::stringstream msg;
+            msg << "TskCarveExtractScalpel::configure : specified Scalpel directory '" << scalpelDirPath << "' does not exist";
+            throw TskException(msg.str());
+        }
+
+        // Get the path to the Scalpel executable.
+        std::stringstream pathBuilder;
+        pathBuilder << scalpelDirPath << Poco::Path::separator() << SCALPEL_EXE_FILE_NAME;
+        std::string scalpelExePath = pathBuilder.str();
+        if (!Poco::File(scalpelExePath).exists())
+        {
+            std::stringstream msg;
+            msg << "TskCarveExtractScalpel::configure : Scalpel executable '" << scalpelExePath << "' does not exist";
+            throw TskException(msg.str());
+        }
+
+        // Get the path to the Scalpel config file.
+        std::string scalpelConfigFilePath = GetSystemProperty("SCALPEL_CONFIG_FILE");
+        if (!Poco::File(scalpelConfigFilePath).exists())
+        {
+            std::stringstream msg;
+            msg << "TskCarveExtractScalpel::TskCarveExtractScalpel : Scalpel config file '" << scalpelConfigFilePath << "' does not exist";
+            throw TskException(msg.str());
+        }
+
+        // Set the Scalpel command line: specify the Scalpel config file.
+        Poco::Process::Args args;
+        args.push_back("-c");
+        args.push_back(scalpelConfigFilePath);
+
+        // Set the Scalpel command line: allow for nested headers and footers.
+        args.push_back("-e");
+        
+        // Set the Scalpel command line: put any carved files directly into the output folder.
+        args.push_back("-o");
+        args.push_back(outputFolderPath);
+        args.push_back("-O");
+
+        // Set the Scalpel command line: specify the file to carve.
+        args.push_back(unallocImgPath);
+
+        // Launch Scalpel with console output redirects.
+        Poco::Pipe outPipe;
+        Poco::Pipe errPipe;
+        Poco::ProcessHandle handle = Poco::Process::launch(scalpelExePath, args, NULL, &outPipe, &errPipe);
+
+        // Capture the console output. Note that Scalpel may block at times as it waits for this loop to empty the stream buffers.
+        Poco::PipeInputStream stdOutInputStream(outPipe);
+        Poco::FileOutputStream stdOutOutputStream(stdOutFilePath);
+        Poco::PipeInputStream stdErrInputStream(errPipe);
+        Poco::FileOutputStream stdErrOutputStream(stdErrFilePath);
+        while (stdOutInputStream || stdErrInputStream)
+        {
+            if (stdOutInputStream)
+            {
+                Poco::StreamCopier::copyStream(stdOutInputStream, stdOutOutputStream);
+            }
+
+            if (stdErrInputStream)
+            {
+                Poco::StreamCopier::copyStream(stdErrInputStream, stdErrOutputStream);
+            }
+        }
+    
+        // Scalpel should be finished since the console output streams are closed.
+        int exitCode = Poco::Process::wait(handle);
+
+        stdOutOutputStream.flush();
+        stdErrOutputStream.flush();
+
+        // On the first invocation of Scalpel, record its use in the image database.
+        static bool toolInfoRecorded = false;
+        if (!toolInfoRecorded)
+        {
+            std::ifstream stdOutStream(stdOutFilePath.c_str());
+            if (stdOutStream)
+            {
+                std::string versionString;
+                std::getline(stdOutStream, versionString);
+                Poco::StringTokenizer tokenizer(versionString, "\t ", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM); 
+                if (tokenizer[0] == "Scalpel" && tokenizer[1] == "version")
+                {
+                    TskServices::Instance().getImgDB().addToolInfo("Scalpel", tokenizer[2].c_str());
+                    toolInfoRecorded = true;
+                }
+                else
+                {
+                    LOGWARN("TskCarveExtractScalpel::carveFile : Scalpel stdout output format changed, cannot record tool info");
+                }
+            }
+            else
+            {
+                LOGWARN("TskCarveExtractScalpel::carveFile : failed to open stdout stream, cannot record tool info");
+            }
+        }
+
+        // Delete input files by default.
+        std::string option = GetSystemProperty("CARVE_EXTRACT_KEEP_INPUT_FILES");
+        std::transform(option.begin(), option.end(), option.begin(), ::toupper);
+        bool deleteInputFiles = (option != "TRUE");
+
+        if (deleteInputFiles)
+        {
+            Poco::File file(unallocImgPath);
+            file.remove();
+        }
+
+        if (exitCode != 0)
+        {
+            std::stringstream msg;
+            msg << "TskCarveExtractScalpel::carveFile : Scalpel exited with error exit code " << exitCode << " when carving '" << unallocImgPath.c_str() << "'";
+            throw TskException(msg.str());
+        }
+    }
+    catch (Poco::Exception &ex)
+    {
+        std::stringstream msg;
+        msg << "TskCarveExtractScalpel::carveFile : Poco exception: " << ex.displayText();
+        throw TskException(msg.str());
+    }
+}
+
+std::vector<TskCarveExtractScalpel::CarvedFile> TskCarveExtractScalpel::parseCarvingResultsFile(int unallocImgId, const std::string &resultsFilePath) const
+{
+    try
+    {
+        std::vector<CarvedFile> carvedFiles;
+
+        Poco::File resultsFile(resultsFilePath);
+        if (!resultsFile.exists())
+        {
+            std::stringstream msg;
+            msg << "TskCarveExtractScalpel::parseCarvingResultsFile : could not find Scalpel carving results file for unalloc img id " << unallocImgId;
+            throw TskException(msg.str());
+        }
+        
+        std::ifstream resultsStream(resultsFilePath.c_str());
+        if (!resultsStream)
+        {
+            std::stringstream msg;
+            msg << "TskCarveExtractScalpel::parseCarvingResultsFile : unable to open Scalpel carving results file for unalloc img id " << unallocImgId;
+            throw TskException(msg.str());
+        }
+
+        // Discard all of the file up to and including the header for the carved files list.
+        std::string line;
+        while (std::getline(resultsStream, line) && line.find("Extracted From") == std::string::npos);
+
+        // Parse the files list.
+        const std::size_t numberOfFileFields = 5;
+        while (std::getline(resultsStream, line))
+        {
+            // Tokenize the next line of the results file and see if it is part of the files list by checking the number of tokens.
+            Poco::StringTokenizer tokenizer(line, "\t ", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM); 
+            if (tokenizer.count() != numberOfFileFields)
+            {
+                // No more files in the files list.
+                break;
+            }
+
+            carvedFiles.push_back(CarvedFile(unallocImgId, tokenizer[0], tokenizer[1], tokenizer[3]));
+        }
+
+        resultsStream.close();
+
+        return carvedFiles;
+    }
+    catch (Poco::Exception &ex)
+    {
+        std::stringstream msg;
+        msg << "TskCarveExtractScalpel::parseCarvingResultsFile : Poco exception: " <<  ex.displayText();
+        throw TskException(msg.str());
+    }
+}
+
+void TskCarveExtractScalpel::processCarvedFiles(const std::string &outputFolderPath, const std::vector<TskCarveExtractScalpel::CarvedFile> &carvedFiles) const
+{
+    try
+    {
+        TskImgDB& imgDB = TskServices::Instance().getImgDB();
+        const uint64_t sectorSize = 512;
+
+        for (std::vector<CarvedFile>::const_iterator file = carvedFiles.begin(); file != carvedFiles.end(); ++file)
+        {
+            std::stringstream filePath;
+            filePath << outputFolderPath << Poco::Path::separator() << (*file).name;
+
+            // Convert the starting offset (in bytes) of the carved file in the unallocated image file the and length of the carved file (in bytes)
+            // into a range of "sectors."
+            int fileStartSectorOffset = static_cast<int>((*file).offset / sectorSize); 
+            int fileEndSectorOffset = static_cast<int>(((*file).offset + (*file).length) / sectorSize); 
+            
+            // Get the unallocated sectors run corresponding to the unallocated image file and map the file sector offsets to image sector offset and length. 
+            std::auto_ptr<UnallocRun> run(imgDB.getUnallocRun((*file).id, fileStartSectorOffset));
+            int numberOfRuns = 1;
+            uint64_t sectorRunStart[] = { run->getAllocStart() + fileStartSectorOffset - run->getUnallocStart() };
+            uint64_t sectorRunLength[] = { run->getAllocStart() + fileEndSectorOffset - run->getUnallocStart() - sectorRunStart[0] };
+
+            // Add the mapping to the image database.
+            uint64_t fileId;
+            if (imgDB.addCarvedFileInfo(run->getVolId(), (*file).name.c_str(), (*file).length, &sectorRunStart[0], &sectorRunLength[0], numberOfRuns, fileId) == -1)
+            {
+                std::stringstream msg;
+                msg << "TskCarveExtractScalpel::processCarvedFiles : unable to save carved file info for '" << filePath.str() << "'";
+                throw TskException(msg.str());
+            }
+
+            std::wstring f(TskUtilities::toUTF16(filePath.str()));
+            TskServices::Instance().getFileManager().addFile(fileId, f);
+
+            // Delete output (carved) files by default.
+            std::string option = GetSystemProperty("CARVE_EXTRACT_KEEP_OUTPUT_FILES");
+            std::transform(option.begin(), option.end(), option.begin(), ::toupper);
+            bool deleteOutputFiles = (option != "TRUE");
+
+            if (deleteOutputFiles)
+            {
+                Poco::File file(filePath.str());
+                file.remove();
+            }
+
+            if (imgDB.updateFileStatus(fileId, TskImgDB::IMGDB_FILES_STATUS_READY_FOR_ANALYSIS) == 1)
+            {
+                std::stringstream msg;
+                msg << "TskCarveExtractScalpel::processCarvedFiles : unable to update file status for '" << filePath.str() << "'";
+                throw TskException(msg.str());
+            }
+        }
+    }
+    catch (Poco::Exception &ex)
+    {
+        std::stringstream msg;
+        msg << "TskCarveExtractScalpel::processCarvedFiles : Poco exception: " <<  ex.displayText();
+        throw TskException(msg.str());
+    }
+}
+
+// @@@ TODO: Replace strtoul() call with a strtoull() call when a newer version of C++ is available.
+TskCarveExtractScalpel::CarvedFile::CarvedFile(int unallocImgId, const std::string &fileName, const std::string &offsetInBytes, const std::string &lengthInBytes) : 
+    id(unallocImgId), name(fileName), offset(strtoul(offsetInBytes.c_str(), 0, 10)), length(strtoul(lengthInBytes.c_str(), 0, 10))
+{
+}
diff --git a/framework/tsk/framework/extraction/TskCarveExtractScalpel.h b/framework/tsk/framework/extraction/TskCarveExtractScalpel.h
index b92b8ea..5412f1d 100644
--- a/framework/tsk/framework/extraction/TskCarveExtractScalpel.h
+++ b/framework/tsk/framework/extraction/TskCarveExtractScalpel.h
@@ -1,98 +1,98 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskCarveExtractScalpel.h
- * Contains the interface of the TskCarveExtractScalpel class.
- */
-
-#ifndef _TSK_CARVEEXTRACTSCALPEL_H
-#define _TSK_CARVEEXTRACTSCALPEL_H
-
-// TSK Framework includes
-#include "tsk/framework/extraction/CarveExtract.h"
-
-// Poco includes
-#include "Poco/Pipe.h"
-
-// C/C++ library includes
-#include <string>
-#include <vector>
-
-/**
- * The TskCarveExtractScalpel class implements the CarveExtract interface to 
- * carve unallocated sectors image files using Scalpel.
- */
-class TSK_FRAMEWORK_API TskCarveExtractScalpel : public CarveExtract
-{
-public:
-    TskCarveExtractScalpel(bool createUnusedSectorFiles = false)
-        : m_createUnusedSectorFiles(createUnusedSectorFiles) {}
-
-    virtual int processFile(int unallocImgId);
-
-private:
-    // Whether to generate unused sector files after carving.
-    bool m_createUnusedSectorFiles;
-
-    /**
-     * Uses Scalpel to attempt carving an unallocated sectors image file.
-     *
-     * @param unallocImgPath The path to the unallocated sectors image file to 
-     * be carved.
-     * @param outputFolderPath The directory to which any carved files are
-     * to be written.
-     * @param stdOutFilePath The file in which output written by Scalpel to
-     * standard out is to be stored.
-     * @param stdErrFilePath The file in which output written by Scalpel to
-     * standard err is to be stored.
-     * @return Throws TskException on error.
-     */
-    void carveFile(const std::string &unallocImgPath, const std::string &outputFolderPath, const std::string &stdOutFilePath, const std::string &stdErrFilePath) const;
-
-    /**
-     * Bundles information concerning a carved file produced by Scalpel.
-     */
-    struct CarvedFile
-    {
-        CarvedFile(int unallocImgId, const std::string &fileName, const std::string &offsetInBytes, const std::string &lengthInBytes);
-        int id;
-        std::string name;
-        unsigned long offset;
-        unsigned long length;
-    };
-
-    /**
-     * Parses a Scalpel carving results file to determine what files, if any, 
-     * Scalpel carved out of an unallocated sectors image file.
-     *
-     * @param unallocImgId The identifier of the unallocated sectors image 
-     * file that was carved.
-     & @param resultsFilePath The path to the Scalpel carving results file 
-     * to be parsed.
-     * @return A possibly empty vector of CarvedFile objects representing 
-     * carved files. Throws TskException on error.
-     */
-    std::vector<CarvedFile> parseCarvingResultsFile(int unallocImgId, const std::string &resultsFilePath) const;
-
-    /**
-     * Writes the unallocated sectors mapping of a set of carved files to the 
-     * image database and saves copies of the carved files.
-     *
-     * @param outputFolderPath The directory to which any carved files were
-     * written.
-     * @param carvedFiles A vector of CarvedFile objects representing carved
-     * files.
-     * @return Throws TskException on error.
-     */
-    void processCarvedFiles(const std::string &outputFolderPath, const std::vector<CarvedFile> &carvedFiles) const;
-};
-
-#endif
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file TskCarveExtractScalpel.h
+ * Contains the interface of the TskCarveExtractScalpel class.
+ */
+
+#ifndef _TSK_CARVEEXTRACTSCALPEL_H
+#define _TSK_CARVEEXTRACTSCALPEL_H
+
+// TSK Framework includes
+#include "tsk/framework/extraction/CarveExtract.h"
+
+// Poco includes
+#include "Poco/Pipe.h"
+
+// C/C++ library includes
+#include <string>
+#include <vector>
+
+/**
+ * The TskCarveExtractScalpel class implements the CarveExtract interface to 
+ * carve unallocated sectors image files using Scalpel.
+ */
+class TSK_FRAMEWORK_API TskCarveExtractScalpel : public CarveExtract
+{
+public:
+    TskCarveExtractScalpel(bool createUnusedSectorFiles = false)
+        : m_createUnusedSectorFiles(createUnusedSectorFiles) {}
+
+    virtual int processFile(int unallocImgId);
+
+private:
+    // Whether to generate unused sector files after carving.
+    bool m_createUnusedSectorFiles;
+
+    /**
+     * Uses Scalpel to attempt carving an unallocated sectors image file.
+     *
+     * @param unallocImgPath The path to the unallocated sectors image file to 
+     * be carved.
+     * @param outputFolderPath The directory to which any carved files are
+     * to be written.
+     * @param stdOutFilePath The file in which output written by Scalpel to
+     * standard out is to be stored.
+     * @param stdErrFilePath The file in which output written by Scalpel to
+     * standard err is to be stored.
+     * @return Throws TskException on error.
+     */
+    void carveFile(const std::string &unallocImgPath, const std::string &outputFolderPath, const std::string &stdOutFilePath, const std::string &stdErrFilePath) const;
+
+    /**
+     * Bundles information concerning a carved file produced by Scalpel.
+     */
+    struct CarvedFile
+    {
+        CarvedFile(int unallocImgId, const std::string &fileName, const std::string &offsetInBytes, const std::string &lengthInBytes);
+        int id;
+        std::string name;
+        unsigned long offset;
+        unsigned long length;
+    };
+
+    /**
+     * Parses a Scalpel carving results file to determine what files, if any, 
+     * Scalpel carved out of an unallocated sectors image file.
+     *
+     * @param unallocImgId The identifier of the unallocated sectors image 
+     * file that was carved.
+     & @param resultsFilePath The path to the Scalpel carving results file 
+     * to be parsed.
+     * @return A possibly empty vector of CarvedFile objects representing 
+     * carved files. Throws TskException on error.
+     */
+    std::vector<CarvedFile> parseCarvingResultsFile(int unallocImgId, const std::string &resultsFilePath) const;
+
+    /**
+     * Writes the unallocated sectors mapping of a set of carved files to the 
+     * image database and saves copies of the carved files.
+     *
+     * @param outputFolderPath The directory to which any carved files were
+     * written.
+     * @param carvedFiles A vector of CarvedFile objects representing carved
+     * files.
+     * @return Throws TskException on error.
+     */
+    void processCarvedFiles(const std::string &outputFolderPath, const std::vector<CarvedFile> &carvedFiles) const;
+};
+
+#endif
diff --git a/framework/tsk/framework/extraction/TskCarvePrepSectorConcat.cpp b/framework/tsk/framework/extraction/TskCarvePrepSectorConcat.cpp
index 9e449c2..1771d8a 100644
--- a/framework/tsk/framework/extraction/TskCarvePrepSectorConcat.cpp
+++ b/framework/tsk/framework/extraction/TskCarvePrepSectorConcat.cpp
@@ -1,336 +1,336 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskCarvePrepSectorConcat.cpp
- * Contains the implementation of the TskCarvePrepSectorConcat class.
- */
-
-// Include the class definition first to ensure it does not depend on subsequent includes in this file.
-#include "TskCarvePrepSectorConcat.h" 
-
-// TSK Framework includes
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file TskCarvePrepSectorConcat.cpp
+ * Contains the implementation of the TskCarvePrepSectorConcat class.
+ */
+
+// Include the class definition first to ensure it does not depend on subsequent includes in this file.
+#include "TskCarvePrepSectorConcat.h" 
+
+// TSK Framework includes
 #include "tsk/framework/services/TskImgDB.h"
 #include "tsk/framework/services/TskServices.h"
 #include "tsk/framework/services/Log.h"
 #include "tsk/framework/utilities/TskUtilities.h"
-
-// Poco includes
-#include "Poco/File.h"
-#include "Poco/Exception.h"
-#include "Poco/Path.h"
-#include "Poco/String.h"
-
-// C/C++ library includes
-#include <assert.h>
-#include <string>
-#include <sstream>
-#include <cstdlib>
+
+// Poco includes
+#include "Poco/File.h"
+#include "Poco/Exception.h"
+#include "Poco/Path.h"
+#include "Poco/String.h"
+
+// C/C++ library includes
+#include <assert.h>
+#include <string>
+#include <sstream>
+#include <cstdlib>
 #include <iostream>
 #include <fstream>
 #include <memory>
-
-namespace
-{
-    const size_t SECTOR_SIZE = 512;
-    const size_t DEFAULT_SECTORS_PER_READ = 32; 
-}
-
-TskCarvePrepSectorConcat::TskCarvePrepSectorConcat()
-{
-}
-
-int TskCarvePrepSectorConcat::processSectors()
-{
-    try 
-    {
-        std::string outputFolderPath;
-        std::string outputFileName;
-        size_t maxOutputFileSize;
-        setUpForCarvePrep(outputFolderPath, outputFileName, maxOutputFileSize);
-
-        std::auto_ptr<SectorRuns> sectorRuns(TskServices::Instance().getImgDB().getFreeSectors());
-        if (sectorRuns.get())
-        {
-            createUnallocSectorsImgFiles(outputFolderPath, outputFileName, maxOutputFileSize, *sectorRuns);
-        }
-    }
-    catch (TskException &ex) 
-    {
-        LOGERROR(ex.message());
-        return 1;
-    }
-
-    return 0;
-}
-
-void TskCarvePrepSectorConcat::processFiles(const std::string &fileName) const
-{
-    assert(!fileName.empty());
-    if (fileName.empty())
-    {
-        throw TskException("TskCarvePrepSectorConcat::processFiles : empty file name argument");
-    }
-
-	std::string outputFolderPath;
-    std::string outputFileName;
-    size_t maxOutputFileSize;
-    setUpForCarvePrep(outputFolderPath, outputFileName, maxOutputFileSize);
-
-    // Get the file ids for any files with the the specified file name.
-    TskImgDB &imgDB = TskServices::Instance().getImgDB();
-    std::stringstream condition;
-    condition << "WHERE files.name = " << "'" << fileName << "'";
-    std::vector<uint64_t> fileIds = imgDB.getFileIds(condition.str());
-
-    std::auto_ptr<SectorRuns> sectorRuns;
-    for (std::vector<uint64_t>::const_iterator it = fileIds.begin(); it != fileIds.end(); ++it)
-    {
-        sectorRuns.reset(imgDB.getFileSectors(*it));
-        if (sectorRuns.get()) 
-        {
-            createUnallocSectorsImgFiles(outputFolderPath, outputFileName, maxOutputFileSize, *sectorRuns);
-        }
-    }
-}
-
-void TskCarvePrepSectorConcat::onUnallocSectorsImgFileCreated(int unallocSectorsImgId) const
-{
-    // Schedule the file for carving.
-    TskImgDB &imgDB = TskServices::Instance().getImgDB();
-
-    if (TskServices::Instance().getScheduler().schedule(Scheduler::Carve, unallocSectorsImgId, unallocSectorsImgId) == 0)
-    {
-        imgDB.setUnallocImgStatus(unallocSectorsImgId, TskImgDB::IMGDB_UNALLOC_IMG_STATUS_SCHEDULE_OK);
-    }
-    else 
-    {
-        imgDB.setUnallocImgStatus(unallocSectorsImgId, TskImgDB::IMGDB_UNALLOC_IMG_STATUS_SCHEDULE_ERR);
-        std::stringstream msg;
-        msg << "TskCarvePrepSectorConcat::onUnallocSectorsImgFileCreated : failed to schedule carving of unallocated image file " << unallocSectorsImgId; 
-        throw TskException(msg.str());
-    }
-}
-
-void TskCarvePrepSectorConcat::setUpForCarvePrep(std::string &outputFolderPath, std::string &outputFileName, size_t &maxOutputFileSize) const
-{
-    try
-    {
-        // Create the output folder. Since multiple calls to processSectors() and/or processFiles() are possible, check to see if the folder already exists.
-        outputFolderPath = GetSystemProperty("CARVE_DIR");
-        Poco::File folder(outputFolderPath);
-        if (!folder.exists())
-        {
-            folder.createDirectory();
-        }
-
-        outputFileName = GetSystemProperty("UNALLOC_SECTORS_IMG_FILE_NAME");
-        maxOutputFileSize = strtoul(GetSystemProperty("MAX_UNALLOC_SECTORS_IMG_FILE_SIZE").c_str(), NULL, 10);
-    }
-    catch (Poco::Exception &ex) 
-    {
-        std::stringstream msg;
-        msg << "TskCarvePrepSectorConcat::createFolder : Poco exception: " << ex.displayText();
-        throw TskException(msg.str());
-    }
-}
-
-void TskCarvePrepSectorConcat::createUnallocSectorsImgFiles(const std::string &outputFolderPath, const std::string &outputFileName, size_t maxOutputFileSize, SectorRuns &sectorRuns) const
-{
-    char *sectorBuffer = NULL;
-    try
-    {
-        // Create a buffer for data from sector runs. If not breaking output files only on volume boundaries (i.e., max output file size is zero), 
-        // be sure sectors to read is less than or equal to max output file size.
-        size_t sectorsPerRead = DEFAULT_SECTORS_PER_READ;
-        if ((maxOutputFileSize > 0) && (sectorsPerRead * SECTOR_SIZE > maxOutputFileSize))
-        {
-            sectorsPerRead = maxOutputFileSize / SECTOR_SIZE;
-        }
-        sectorBuffer = new char[sectorsPerRead * SECTOR_SIZE];
-
-        TskImgDB &imgDB = TskServices::Instance().getImgDB();       
-        int volumeID = -1;
-        int unallocSectorsImgId = 0;
+
+namespace
+{
+    const size_t SECTOR_SIZE = 512;
+    const size_t DEFAULT_SECTORS_PER_READ = 32; 
+}
+
+TskCarvePrepSectorConcat::TskCarvePrepSectorConcat()
+{
+}
+
+int TskCarvePrepSectorConcat::processSectors()
+{
+    try 
+    {
+        std::string outputFolderPath;
+        std::string outputFileName;
+        size_t maxOutputFileSize;
+        setUpForCarvePrep(outputFolderPath, outputFileName, maxOutputFileSize);
+
+        std::auto_ptr<SectorRuns> sectorRuns(TskServices::Instance().getImgDB().getFreeSectors());
+        if (sectorRuns.get())
+        {
+            createUnallocSectorsImgFiles(outputFolderPath, outputFileName, maxOutputFileSize, *sectorRuns);
+        }
+    }
+    catch (TskException &ex) 
+    {
+        LOGERROR(ex.message());
+        return 1;
+    }
+
+    return 0;
+}
+
+void TskCarvePrepSectorConcat::processFiles(const std::string &fileName) const
+{
+    assert(!fileName.empty());
+    if (fileName.empty())
+    {
+        throw TskException("TskCarvePrepSectorConcat::processFiles : empty file name argument");
+    }
+
+	std::string outputFolderPath;
+    std::string outputFileName;
+    size_t maxOutputFileSize;
+    setUpForCarvePrep(outputFolderPath, outputFileName, maxOutputFileSize);
+
+    // Get the file ids for any files with the the specified file name.
+    TskImgDB &imgDB = TskServices::Instance().getImgDB();
+    std::stringstream condition;
+    condition << "WHERE files.name = " << "'" << fileName << "'";
+    std::vector<uint64_t> fileIds = imgDB.getFileIds(condition.str());
+
+    std::auto_ptr<SectorRuns> sectorRuns;
+    for (std::vector<uint64_t>::const_iterator it = fileIds.begin(); it != fileIds.end(); ++it)
+    {
+        sectorRuns.reset(imgDB.getFileSectors(*it));
+        if (sectorRuns.get()) 
+        {
+            createUnallocSectorsImgFiles(outputFolderPath, outputFileName, maxOutputFileSize, *sectorRuns);
+        }
+    }
+}
+
+void TskCarvePrepSectorConcat::onUnallocSectorsImgFileCreated(int unallocSectorsImgId) const
+{
+    // Schedule the file for carving.
+    TskImgDB &imgDB = TskServices::Instance().getImgDB();
+
+    if (TskServices::Instance().getScheduler().schedule(Scheduler::Carve, unallocSectorsImgId, unallocSectorsImgId) == 0)
+    {
+        imgDB.setUnallocImgStatus(unallocSectorsImgId, TskImgDB::IMGDB_UNALLOC_IMG_STATUS_SCHEDULE_OK);
+    }
+    else 
+    {
+        imgDB.setUnallocImgStatus(unallocSectorsImgId, TskImgDB::IMGDB_UNALLOC_IMG_STATUS_SCHEDULE_ERR);
+        std::stringstream msg;
+        msg << "TskCarvePrepSectorConcat::onUnallocSectorsImgFileCreated : failed to schedule carving of unallocated image file " << unallocSectorsImgId; 
+        throw TskException(msg.str());
+    }
+}
+
+void TskCarvePrepSectorConcat::setUpForCarvePrep(std::string &outputFolderPath, std::string &outputFileName, size_t &maxOutputFileSize) const
+{
+    try
+    {
+        // Create the output folder. Since multiple calls to processSectors() and/or processFiles() are possible, check to see if the folder already exists.
+        outputFolderPath = GetSystemProperty("CARVE_DIR");
+        Poco::File folder(outputFolderPath);
+        if (!folder.exists())
+        {
+            folder.createDirectory();
+        }
+
+        outputFileName = GetSystemProperty("UNALLOC_SECTORS_IMG_FILE_NAME");
+        maxOutputFileSize = strtoul(GetSystemProperty("MAX_UNALLOC_SECTORS_IMG_FILE_SIZE").c_str(), NULL, 10);
+    }
+    catch (Poco::Exception &ex) 
+    {
+        std::stringstream msg;
+        msg << "TskCarvePrepSectorConcat::createFolder : Poco exception: " << ex.displayText();
+        throw TskException(msg.str());
+    }
+}
+
+void TskCarvePrepSectorConcat::createUnallocSectorsImgFiles(const std::string &outputFolderPath, const std::string &outputFileName, size_t maxOutputFileSize, SectorRuns &sectorRuns) const
+{
+    char *sectorBuffer = NULL;
+    try
+    {
+        // Create a buffer for data from sector runs. If not breaking output files only on volume boundaries (i.e., max output file size is zero), 
+        // be sure sectors to read is less than or equal to max output file size.
+        size_t sectorsPerRead = DEFAULT_SECTORS_PER_READ;
+        if ((maxOutputFileSize > 0) && (sectorsPerRead * SECTOR_SIZE > maxOutputFileSize))
+        {
+            sectorsPerRead = maxOutputFileSize / SECTOR_SIZE;
+        }
+        sectorBuffer = new char[sectorsPerRead * SECTOR_SIZE];
+
+        TskImgDB &imgDB = TskServices::Instance().getImgDB();       
+        int volumeID = -1;
+        int unallocSectorsImgId = 0;
         std::ofstream outfile;
-        uint64_t currentFileOffset = 0; // In bytes
-        do 
-        {
-            // Keep track of the starting offsets in the output file (in bytes) and in the image (in sectors) of the sector run or part of a sector run 
-            // being written to the current output file. This data will be needed to store a mapping of the sectors in the output file to the corresponding  
-            // sectors in the image.
-            uint64_t startingFileOffset = currentFileOffset; // In bytes
-            uint64_t startingImageOffset = sectorRuns.getDataStart(); // In sectors 
-            
-            // Read the contents of the sectors in the current run in chunks.
-            for (uint64_t sectorRunOffset = 0; sectorRunOffset < sectorRuns.getDataLen(); ) 
-            {
-                // Calculate how many sectors to read in the current chunk.
-                uint64_t sectorsToRead = sectorsPerRead;
-                if (sectorsToRead > sectorRuns.getDataLen() - sectorRunOffset)
-                {
-                    sectorsToRead = sectorRuns.getDataLen() - sectorRunOffset;
-                }
-
-                // If the read will make the output file exceed the maximum file size, or if a volume boundary
-                // has been reached, close the current output file and open a new output file. Note that the 
-                // first time this loop is entered, the initial output file will be created here 
-                // since the image volume ID was initialized to an invalid value.
-                if ((sectorRuns.getVolID() != volumeID) || ((maxOutputFileSize > 0) && ((sectorsToRead * 512) + currentFileOffset > maxOutputFileSize))) 
-                {
-                    // Store the mapping of the sectors written to the output file to the corresponding sectors in the image.
-                    if (currentFileOffset != startingFileOffset) 
-                    {
+        uint64_t currentFileOffset = 0; // In bytes
+        do 
+        {
+            // Keep track of the starting offsets in the output file (in bytes) and in the image (in sectors) of the sector run or part of a sector run 
+            // being written to the current output file. This data will be needed to store a mapping of the sectors in the output file to the corresponding  
+            // sectors in the image.
+            uint64_t startingFileOffset = currentFileOffset; // In bytes
+            uint64_t startingImageOffset = sectorRuns.getDataStart(); // In sectors 
+            
+            // Read the contents of the sectors in the current run in chunks.
+            for (uint64_t sectorRunOffset = 0; sectorRunOffset < sectorRuns.getDataLen(); ) 
+            {
+                // Calculate how many sectors to read in the current chunk.
+                uint64_t sectorsToRead = sectorsPerRead;
+                if (sectorsToRead > sectorRuns.getDataLen() - sectorRunOffset)
+                {
+                    sectorsToRead = sectorRuns.getDataLen() - sectorRunOffset;
+                }
+
+                // If the read will make the output file exceed the maximum file size, or if a volume boundary
+                // has been reached, close the current output file and open a new output file. Note that the 
+                // first time this loop is entered, the initial output file will be created here 
+                // since the image volume ID was initialized to an invalid value.
+                if ((sectorRuns.getVolID() != volumeID) || ((maxOutputFileSize > 0) && ((sectorsToRead * 512) + currentFileOffset > maxOutputFileSize))) 
+                {
+                    // Store the mapping of the sectors written to the output file to the corresponding sectors in the image.
+                    if (currentFileOffset != startingFileOffset) 
+                    {
                         mapFileToImage(unallocSectorsImgId, outfile, startingFileOffset, currentFileOffset, sectorRuns.getVolID(), startingImageOffset);
-
-                        // Advance the starting image offset to accurately reflect the starting image offset for the next output file.  
-                        startingImageOffset += (currentFileOffset - startingFileOffset) / 512;
-                    }
-
-                    // Close the current output file.
-                    if (unallocSectorsImgId) 
-                    {
+
+                        // Advance the starting image offset to accurately reflect the starting image offset for the next output file.  
+                        startingImageOffset += (currentFileOffset - startingFileOffset) / 512;
+                    }
+
+                    // Close the current output file.
+                    if (unallocSectorsImgId) 
+                    {
                         outfile.close();
-                    }
-
-                    // Schedule the current output file for carving. Note that derived classes can change this behavior by overriding onUnallocSectorsImgFileCreated.
-                    if (currentFileOffset > 0) 
-                    {
-                        onUnallocSectorsImgFileCreated(unallocSectorsImgId); 
-                    }
-
-                    // Get the next output file number. 
-                    if (imgDB.addUnallocImg(unallocSectorsImgId) == -1) 
-                    {
-                        throw TskException("TskCarvePrepSectorConcat::createUnallocSectorsImgFiles : failed to get next output file number");
-                    }
-
-                    // Create a subdirectory named for the file number.
-                    std::stringstream path;
-                    path << outputFolderPath.c_str() << Poco::Path::separator() << unallocSectorsImgId;
-                    createFolder(path.str());
-                    
-                    // Create an output file in the subdirectory.
-                    path << Poco::Path::separator() << outputFileName.c_str();
+                    }
+
+                    // Schedule the current output file for carving. Note that derived classes can change this behavior by overriding onUnallocSectorsImgFileCreated.
+                    if (currentFileOffset > 0) 
+                    {
+                        onUnallocSectorsImgFileCreated(unallocSectorsImgId); 
+                    }
+
+                    // Get the next output file number. 
+                    if (imgDB.addUnallocImg(unallocSectorsImgId) == -1) 
+                    {
+                        throw TskException("TskCarvePrepSectorConcat::createUnallocSectorsImgFiles : failed to get next output file number");
+                    }
+
+                    // Create a subdirectory named for the file number.
+                    std::stringstream path;
+                    path << outputFolderPath.c_str() << Poco::Path::separator() << unallocSectorsImgId;
+                    createFolder(path.str());
+                    
+                    // Create an output file in the subdirectory.
+                    path << Poco::Path::separator() << outputFileName.c_str();
                     outfile.open(path.str().c_str(), std::ios_base::out|std::ios_base::binary);
                     if (outfile.fail())
-                    {
-                        TskServices::Instance().getImgDB().setUnallocImgStatus(unallocSectorsImgId, TskImgDB::IMGDB_UNALLOC_IMG_STATUS_CARVED_ERR);
-
-                        std::stringstream msg;
-                        msg << "TskCarvePrepSectorConcat::createUnallocSectorsImgFiles : failed to create output file " << unallocSectorsImgId;
-                        throw TskException(msg.str());
-                    }
-                    // Reset the output file offsets and volume ID.
-                    currentFileOffset = 0;
-                    startingFileOffset = 0;
-                    volumeID = sectorRuns.getVolID();
-                }
-
-                // Read another chunk of sectors from this run. 
-                int sectorsRead = sectorRuns.getData(sectorRunOffset, static_cast<int>(sectorsToRead), sectorBuffer);
-                if (sectorsRead == -1)
-                {
-                    imgDB.setUnallocImgStatus(unallocSectorsImgId, TskImgDB::IMGDB_UNALLOC_IMG_STATUS_CARVED_ERR);
-                    LOGERROR("TskCarvePrepSectorConcat::createUnallocSectorsImgFiles : error reading sector contents from sector run");
-                    break;
-                }
-
-                // Write the chunk of sectors to the output file.
+                    {
+                        TskServices::Instance().getImgDB().setUnallocImgStatus(unallocSectorsImgId, TskImgDB::IMGDB_UNALLOC_IMG_STATUS_CARVED_ERR);
+
+                        std::stringstream msg;
+                        msg << "TskCarvePrepSectorConcat::createUnallocSectorsImgFiles : failed to create output file " << unallocSectorsImgId;
+                        throw TskException(msg.str());
+                    }
+                    // Reset the output file offsets and volume ID.
+                    currentFileOffset = 0;
+                    startingFileOffset = 0;
+                    volumeID = sectorRuns.getVolID();
+                }
+
+                // Read another chunk of sectors from this run. 
+                int sectorsRead = sectorRuns.getData(sectorRunOffset, static_cast<int>(sectorsToRead), sectorBuffer);
+                if (sectorsRead == -1)
+                {
+                    imgDB.setUnallocImgStatus(unallocSectorsImgId, TskImgDB::IMGDB_UNALLOC_IMG_STATUS_CARVED_ERR);
+                    LOGERROR("TskCarvePrepSectorConcat::createUnallocSectorsImgFiles : error reading sector contents from sector run");
+                    break;
+                }
+
+                // Write the chunk of sectors to the output file.
                 outfile.write(sectorBuffer, sectorsRead * 512);
                 if (outfile.bad())
-                {
-                    imgDB.setUnallocImgStatus(unallocSectorsImgId, TskImgDB::IMGDB_UNALLOC_IMG_STATUS_CARVED_ERR);
-                    std::stringstream msg;
-                    msg << "TskCarvePrepSectorConcat::createUnallocSectorsImgFiles : error writing to output file " << unallocSectorsImgId;
-                    throw TskException(msg.str());
-                }
-
-                // Update the output file and sector run offsets to reflect the sucessful read.
+                {
+                    imgDB.setUnallocImgStatus(unallocSectorsImgId, TskImgDB::IMGDB_UNALLOC_IMG_STATUS_CARVED_ERR);
+                    std::stringstream msg;
+                    msg << "TskCarvePrepSectorConcat::createUnallocSectorsImgFiles : error writing to output file " << unallocSectorsImgId;
+                    throw TskException(msg.str());
+                }
+
+                // Update the output file and sector run offsets to reflect the sucessful read.
                 currentFileOffset += sectorsRead * 512;
-                sectorRunOffset += sectorsRead;
-
-                if (sectorsRead == 0) 
-                {
-                    break;
-                }
-            }
-
-            // Store the mapping of the sectors written to the output file to the corresponding sectors in the image.
-            if (currentFileOffset != startingFileOffset)
-            {
+                sectorRunOffset += sectorsRead;
+
+                if (sectorsRead == 0) 
+                {
+                    break;
+                }
+            }
+
+            // Store the mapping of the sectors written to the output file to the corresponding sectors in the image.
+            if (currentFileOffset != startingFileOffset)
+            {
                 mapFileToImage(unallocSectorsImgId, outfile, startingFileOffset, currentFileOffset, sectorRuns.getVolID(), startingImageOffset);
-            }
+            }
         }
-        while(sectorRuns.next() != -1);
-
-        // Close the final output file.
-        if (unallocSectorsImgId) 
-        {
+        while(sectorRuns.next() != -1);
+
+        // Close the final output file.
+        if (unallocSectorsImgId) 
+        {
             outfile.close();
-        }
-
-        // Schedule the final output file.
-        if (currentFileOffset > 0)
-        {
-            onUnallocSectorsImgFileCreated(unallocSectorsImgId);
-        }
+        }
+
+        // Schedule the final output file.
+        if (currentFileOffset > 0)
+        {
+            onUnallocSectorsImgFileCreated(unallocSectorsImgId);
+        }
 
         if (sectorBuffer != NULL)
         {
             delete [] sectorBuffer;
         }
-    }
-    catch(...)
-    {
-        if (sectorBuffer != NULL)
-        {
-            delete [] sectorBuffer;
-        }
-
-        throw;
-    }
-}
-
-void TskCarvePrepSectorConcat::createFolder(const std::string &path) const
-{
-    try 
-    {
-        Poco::File folder(path);
-        if (folder.exists())
-        {
-            folder.remove(true);
-        }
-        
-        folder.createDirectory();
-    }
-    catch (Poco::Exception& ex) 
-    {
-        std::stringstream msg;
-        msg << "TskCarvePrepSectorConcat::createFolder : failed to create folder '" << path << "': " << ex.message();
-        throw TskException(msg.str());
-    }
-}
-
+    }
+    catch(...)
+    {
+        if (sectorBuffer != NULL)
+        {
+            delete [] sectorBuffer;
+        }
+
+        throw;
+    }
+}
+
+void TskCarvePrepSectorConcat::createFolder(const std::string &path) const
+{
+    try 
+    {
+        Poco::File folder(path);
+        if (folder.exists())
+        {
+            folder.remove(true);
+        }
+        
+        folder.createDirectory();
+    }
+    catch (Poco::Exception& ex) 
+    {
+        std::stringstream msg;
+        msg << "TskCarvePrepSectorConcat::createFolder : failed to create folder '" << path << "': " << ex.message();
+        throw TskException(msg.str());
+    }
+}
+
 void TskCarvePrepSectorConcat::mapFileToImage(int unallocSectorsImgId, std::ofstream & outfile, uint64_t startingFileOffset, uint64_t endingFileOffset, int volumeID, uint64_t startingImageOffset) const
-{
-    // Convert the starting offset in the output file from a byte offset to a sector offset and calculate the number of sectors written to the file.
-    uint64_t startingFileOffsetInSectors = startingFileOffset / 512;
-    uint64_t sectorsWritten = (endingFileOffset - startingFileOffset) / 512;
-
-    // Store the mapping of the output file sectors to image sectors.
-    if (TskServices::Instance().getImgDB().addAllocUnallocMapInfo(volumeID, unallocSectorsImgId, startingFileOffsetInSectors, sectorsWritten, startingImageOffset) != 0) 
-    {
+{
+    // Convert the starting offset in the output file from a byte offset to a sector offset and calculate the number of sectors written to the file.
+    uint64_t startingFileOffsetInSectors = startingFileOffset / 512;
+    uint64_t sectorsWritten = (endingFileOffset - startingFileOffset) / 512;
+
+    // Store the mapping of the output file sectors to image sectors.
+    if (TskServices::Instance().getImgDB().addAllocUnallocMapInfo(volumeID, unallocSectorsImgId, startingFileOffsetInSectors, sectorsWritten, startingImageOffset) != 0) 
+    {
         outfile.close();
-        std::stringstream msg;
-        msg << "TskCarvePrepSectorConcat::mapFileToImage : failed to add mapping to image for output file " << unallocSectorsImgId;
-        throw TskException(msg.str());
-    }
+        std::stringstream msg;
+        msg << "TskCarvePrepSectorConcat::mapFileToImage : failed to add mapping to image for output file " << unallocSectorsImgId;
+        throw TskException(msg.str());
+    }
 }
diff --git a/framework/tsk/framework/extraction/TskCarvePrepSectorConcat.h b/framework/tsk/framework/extraction/TskCarvePrepSectorConcat.h
index 02f7e4e..ff3a033 100644
--- a/framework/tsk/framework/extraction/TskCarvePrepSectorConcat.h
+++ b/framework/tsk/framework/extraction/TskCarvePrepSectorConcat.h
@@ -1,136 +1,136 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskCarvePrepSectorConcat.h
- * Contains the interface of the TskCarvePrepSectorConcat class.
- */
-
-#ifndef _TSK_CARVE_PREP_CONCAT_H
-#define _TSK_CARVE_PREP_CONCAT_H
-
-// TSK Framework includes
-#include "CarvePrep.h"
-
-// C/C++ library includes
-#include <string>
-
-/**
- * The TskCarvePrepSectorConcat class implements the CarvePrep abstract 
- * interface. It concatenates unallocated sector runs from an image and writes
- * the contents to one or more unallocated sectors image files with a 
- * configurable maximum size. Instances of this class are also able to treat a
- * file as a run of unallocated sectors, whcih may be helpful for carving page
- * files, etc. 
- *
- * This class assumes the availability of the Microsoft Windows API.
- * @@@ TODO: Use Poco API instead.
- */
-class TSK_FRAMEWORK_API TskCarvePrepSectorConcat : public CarvePrep
-{
-public:
-	TskCarvePrepSectorConcat();
-	virtual ~TskCarvePrepSectorConcat() {}
-
-    virtual int processSectors();
-
-    /**
-     * Treats the contents of a set of files as unallocated sector runs and 
-     * writes the contents of the files to zero to many unallocated sectors 
-     * image files for later carving. This may be useful for carving page
-     * files, hibernation files, etc.
-     *
-     * @param fileName Output files for all files with this name will be 
-     * generated.
-     * @return Throws TskException on error.
-     */
-    void processFiles(const std::string &fileName) const;
-
-protected:
-
-    /**
-     * Called by createUnallocSectorsImgFiles to allow specialization of 
-     * behavior when an unallocated sectors image file is produced. The default
-     * implementation optionally schedules carving of the output file.
-     *
-     * @param unallocSectorsImgId ID assigned to the file by 
-     * TskImgDB::addUnallocImg().
-     * @return Default implementation throws TskException on error.
-     */
-    virtual void onUnallocSectorsImgFileCreated(int unallocSectorsImgId) const; 
-
-private:
-
-    /**
-     * Looks up carving parameters and creates the output folder
-     * if it doesn't already exist.
-     *
-     * @param outputFolderPath The value of the CARVE_DIR system property 
-     * or a default value.
-     * @param outputFileName  The value of the UNALLOC_IMG_FILE_NAME system 
-     * property or a default value.
-     * @param maxOutputFileSize  The value of the MAX_UNALLOC_IMG_FILE_SIZE 
-     * system property or a default value.
-     * @return Throws TskException on error.
-     */
-    void setUpForCarvePrep(std::string &outputFolderPath, std::string &outputFileName, size_t &maxOutputFileSize) const;
-
-    /** 
-     * Writes sector runs to one or more unallocated sectors image files. The 
-     * maximum size of any single output file will not exceed the value of the 
-     * MAX_UNALLOC_IMG_FILE_SIZE system property (or default) and each output 
-     * file will contain sectors from only a single volume, unless 
-     * MAX_UNALLOC_IMG_FILE_SIZE is set to zero In that case, output files 
-     * break on volume boundaries. 
-     * 
-     * @param outputFolderPath Folder to which the output files are written.
-     * @param outputFileName  Name given to the output files.
-     * @param maxOutputFileSize  Maximum output file size in bytes. If 0, then no size limit is used.
-     * @param sectorRuns Sector runs to be written to the output files.
-     * @return Throws TskException on error.
-     */
-    void createUnallocSectorsImgFiles(const std::string &outputFolderPath, const std::string &outputFileName, size_t maxOutputFileSize, SectorRuns &sectorRuns) const;
-
-    /** 
-     * Creates a folder. If the specified folder already exists, deletes it
-     * first.
-     * 
-     * @param path Path of the folder to be created.
-     * @return Throws TskException on error
-     */
-    void createFolder(const std::string &path) const;
-
-    /** 
-     *  Maps the sectors written to an unallocated sectors image file to the 
-     *  corresponding sectors in the image and writes the results to the image 
-     *  database.
-     * 
-     *  @param unallocSectorsImgId ID assigned to the unallocated sectors image
-     *  file by TskImgDB::addUnallocImg().
-     *  @param outputFileHandle File handle used to access the unallocated 
-     *  sectors image file.
-     *  @param startingFileOffset Starting offset in the unallocated sectors 
-     *  image file (in bytes) of the unallocated sectors run or part of a 
-     *  sectors run that was written to the file. 
-     *  @param endingFileOffset Ending offset in the unallocated sectors image
-     *  file (in bytes) of the unallocated sectors run or part of a sectors run
-     *  that was written to the file.
-     *  @param volumeID Volume ID of the volume that was the source of the 
-     *  unallocated sectors run or part of a sectors run that was written to the
-     *  unallocated sectors image file.
-     *  @param startingImageOffset Starting offset in the image (in sectors) of 
-     *  the unallocated sectors run or part of a sectors run that was written to 
-     *  the unallocated sectors image file.  
-     *  @return Throws TskException on error.
-     */
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file TskCarvePrepSectorConcat.h
+ * Contains the interface of the TskCarvePrepSectorConcat class.
+ */
+
+#ifndef _TSK_CARVE_PREP_CONCAT_H
+#define _TSK_CARVE_PREP_CONCAT_H
+
+// TSK Framework includes
+#include "CarvePrep.h"
+
+// C/C++ library includes
+#include <string>
+
+/**
+ * The TskCarvePrepSectorConcat class implements the CarvePrep abstract 
+ * interface. It concatenates unallocated sector runs from an image and writes
+ * the contents to one or more unallocated sectors image files with a 
+ * configurable maximum size. Instances of this class are also able to treat a
+ * file as a run of unallocated sectors, whcih may be helpful for carving page
+ * files, etc. 
+ *
+ * This class assumes the availability of the Microsoft Windows API.
+ * @@@ TODO: Use Poco API instead.
+ */
+class TSK_FRAMEWORK_API TskCarvePrepSectorConcat : public CarvePrep
+{
+public:
+	TskCarvePrepSectorConcat();
+	virtual ~TskCarvePrepSectorConcat() {}
+
+    virtual int processSectors();
+
+    /**
+     * Treats the contents of a set of files as unallocated sector runs and 
+     * writes the contents of the files to zero to many unallocated sectors 
+     * image files for later carving. This may be useful for carving page
+     * files, hibernation files, etc.
+     *
+     * @param fileName Output files for all files with this name will be 
+     * generated.
+     * @return Throws TskException on error.
+     */
+    void processFiles(const std::string &fileName) const;
+
+protected:
+
+    /**
+     * Called by createUnallocSectorsImgFiles to allow specialization of 
+     * behavior when an unallocated sectors image file is produced. The default
+     * implementation optionally schedules carving of the output file.
+     *
+     * @param unallocSectorsImgId ID assigned to the file by 
+     * TskImgDB::addUnallocImg().
+     * @return Default implementation throws TskException on error.
+     */
+    virtual void onUnallocSectorsImgFileCreated(int unallocSectorsImgId) const; 
+
+private:
+
+    /**
+     * Looks up carving parameters and creates the output folder
+     * if it doesn't already exist.
+     *
+     * @param outputFolderPath The value of the CARVE_DIR system property 
+     * or a default value.
+     * @param outputFileName  The value of the UNALLOC_IMG_FILE_NAME system 
+     * property or a default value.
+     * @param maxOutputFileSize  The value of the MAX_UNALLOC_IMG_FILE_SIZE 
+     * system property or a default value.
+     * @return Throws TskException on error.
+     */
+    void setUpForCarvePrep(std::string &outputFolderPath, std::string &outputFileName, size_t &maxOutputFileSize) const;
+
+    /** 
+     * Writes sector runs to one or more unallocated sectors image files. The 
+     * maximum size of any single output file will not exceed the value of the 
+     * MAX_UNALLOC_IMG_FILE_SIZE system property (or default) and each output 
+     * file will contain sectors from only a single volume, unless 
+     * MAX_UNALLOC_IMG_FILE_SIZE is set to zero In that case, output files 
+     * break on volume boundaries. 
+     * 
+     * @param outputFolderPath Folder to which the output files are written.
+     * @param outputFileName  Name given to the output files.
+     * @param maxOutputFileSize  Maximum output file size in bytes. If 0, then no size limit is used.
+     * @param sectorRuns Sector runs to be written to the output files.
+     * @return Throws TskException on error.
+     */
+    void createUnallocSectorsImgFiles(const std::string &outputFolderPath, const std::string &outputFileName, size_t maxOutputFileSize, SectorRuns &sectorRuns) const;
+
+    /** 
+     * Creates a folder. If the specified folder already exists, deletes it
+     * first.
+     * 
+     * @param path Path of the folder to be created.
+     * @return Throws TskException on error
+     */
+    void createFolder(const std::string &path) const;
+
+    /** 
+     *  Maps the sectors written to an unallocated sectors image file to the 
+     *  corresponding sectors in the image and writes the results to the image 
+     *  database.
+     * 
+     *  @param unallocSectorsImgId ID assigned to the unallocated sectors image
+     *  file by TskImgDB::addUnallocImg().
+     *  @param outputFileHandle File handle used to access the unallocated 
+     *  sectors image file.
+     *  @param startingFileOffset Starting offset in the unallocated sectors 
+     *  image file (in bytes) of the unallocated sectors run or part of a 
+     *  sectors run that was written to the file. 
+     *  @param endingFileOffset Ending offset in the unallocated sectors image
+     *  file (in bytes) of the unallocated sectors run or part of a sectors run
+     *  that was written to the file.
+     *  @param volumeID Volume ID of the volume that was the source of the 
+     *  unallocated sectors run or part of a sectors run that was written to the
+     *  unallocated sectors image file.
+     *  @param startingImageOffset Starting offset in the image (in sectors) of 
+     *  the unallocated sectors run or part of a sectors run that was written to 
+     *  the unallocated sectors image file.  
+     *  @return Throws TskException on error.
+     */
     void mapFileToImage(int unallocSectorsImgId, std::ofstream & outfile, uint64_t startingFileOffset, uint64_t endingFileOffset, int volumeID, uint64_t startingImageOffset) const;
-};
-
-#endif
+};
+
+#endif
diff --git a/framework/tsk/framework/extraction/TskImageFile.cpp b/framework/tsk/framework/extraction/TskImageFile.cpp
index bd7df9a..891b9e8 100755
--- a/framework/tsk/framework/extraction/TskImageFile.cpp
+++ b/framework/tsk/framework/extraction/TskImageFile.cpp
@@ -1,30 +1,30 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskImageFile.cpp
- * Contains the implementation for the TskImageFile base class.
- */
-
-#include "TskImageFile.h"
-
-/**
- *
- */
-TskImageFile::TskImageFile()
-{
-}
-
-/**
- *
- */
-TskImageFile::~TskImageFile()
-{
-}
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file TskImageFile.cpp
+ * Contains the implementation for the TskImageFile base class.
+ */
+
+#include "TskImageFile.h"
+
+/**
+ *
+ */
+TskImageFile::TskImageFile()
+{
+}
+
+/**
+ *
+ */
+TskImageFile::~TskImageFile()
+{
+}
diff --git a/framework/tsk/framework/extraction/TskImageFile.h b/framework/tsk/framework/extraction/TskImageFile.h
index 1e5c470..50809fc 100755
--- a/framework/tsk/framework/extraction/TskImageFile.h
+++ b/framework/tsk/framework/extraction/TskImageFile.h
@@ -1,203 +1,203 @@
-/*
- *
- *  The Sleuth Kit
- *
- *  Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- *  Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- *  reserved.
- *
- *  This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskImageFile.h
- * Contains the interface for the TskImageFile class.
- */
-
-#ifndef _TSK_IMAGEFILE_H
-#define _TSK_IMAGEFILE_H
-
-#include "tsk/framework/framework_i.h"
-#include <vector>
-#include <string>
-
-/**
- * An interface to a class that allows file system and low-level 
- * access to a disk image.
- * It supports opening split image files, extracting file system 
- * information from the image and extracting data for a specific file
- * or for a range of sectors.  You must call one of the open() methods
- * before using any of the other methods in the interface. 
- */
-class TSK_FRAMEWORK_API TskImageFile
-{
-public:
-    /**
-     * You must call one of the open() methods after creating the object.
-     */
-    TskImageFile();
-
-    virtual ~TskImageFile();
-
-    /**
-     * open the images at the paths saved in ImgDB
-     * @returns 0 on success and -1 on error
-     */
-    virtual int open() = 0;
-
-    /// Close the disk image.
-    virtual void close() = 0;
-
-    /// Return the file name(s) that make up the image.
-    virtual std::vector<std::string> getFileNames() const = 0;
-    virtual std::vector<std::wstring> getFileNamesW() const = 0;
-
-    /**
-     * Analyze the volume and file systems in the opened images and 
-     * populate the TskImgDB instance registered with TskServices.  This
-     * will not perform file carving.
-     * @returns 1 if there was a major error that prevented any extraction.  0 will
-     * be returned if there were minor errors during extraction or if there were 
-     * no errors.
-     */
-    virtual int extractFiles() = 0;
-
-    /**
-     * Return the data located at the given sector offset in the disk image.
-     * @param sect_start Sector offset into image from which to return data
-     * @param sect_len Number of sectors to read
-     * @param buffer A buffer into which data will be placed. Must be at
-     * least len * 512 large
-     * @return Number of sectors read or -1 on error
-     */
-    virtual int getSectorData(const uint64_t sect_start, 
-                              const uint64_t sect_len, 
-                              char *buffer) = 0;
-
-    /**
-     * Return the data located at the given byte offset in the disk image.
-     * @param byte_start Byte offset into image from which to return data
-     * @param byte_len Number of bytes to read
-     * @param buffer A buffer into which data will be placed. Must be at
-     * least byte_len large
-     * @return Number of bytes read or -1 on error
-     */
-    virtual int getByteData(const uint64_t byte_start, 
-                            const uint64_t byte_len, 
-                            char *buffer) = 0;
-
-    /**
-     * Provides access to the content of a specific file that was extracted from the disk image.
-     *
-     * @param fileId ID of the file (can be found in database)
-     * @returns A handle to the file or -1 on error.
-     */
-    virtual int openFile(const uint64_t fileId) = 0;
-
-    /**
-     * Reads content of a file that was opened with openFile(). 
-     * @param handle File handle that was returned by an earlier call to openFile()
-     * @param byte_offset Starting byte offset from which to read data
-     * @param byte_len The number of bytes to read
-     * @param buffer A buffer into which data will be placed. Must be at least
-     * byte_len bytes.
-     * @return Number of bytes read or -1 on error
-     */
-    virtual int readFile(const int handle, 
-                         const TSK_OFF_T byte_offset, 
-                         const size_t byte_len, 
-                         char * buffer) = 0;
-   /**
-     * Closes an opened file.
-     * @param handle File handle that was returned by an earlier call to openFile()
-     */
-    virtual int closeFile(const int handle) = 0;
-
-    /**
-    * Opens a single (non-split) disk image file so that it can be read.
-    *
-    * @param imageFile The path to the image file
-    * @param imageType The disk image type (can be autodetection)
-    * @param sectorSize Size of device sector in bytes (or 0 for default)
-    *
-    * @return -1 on error and 0 on success
-    */
-    virtual int open(const TSK_TCHAR *imageFile, 
-                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT, 
-                     const unsigned int sectorSize = 0) = 0;
-
-    /**
-    * Opens one or more disk image files so that they can be read. e UTF8, then consider
-    *
-    * @param numberOfImages The number of images to open (will be > 1 for split images).
-    * @param imageFile The path to the image files (the number of files must
-    * be equal to num_img and they must be in a sorted order)
-    * @param imageType The disk image type (can be autodetection)
-    * @param sectorSize Size of device sector in bytes (or 0 for default)
-    *
-    * @return -1 on error and 0 on success
-    */
-    virtual int open(const int numberOfImages, 
-                     const TSK_TCHAR * const imageFile[], 
-                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT, 
-                     const unsigned int sectorSize = 0) = 0;
-
-    /**
-    * Opens a single (non-split) disk image file so that it can be read.  This version
-    * always takes a UTF-8 encoding of the disk image.
-    *
-    * @param imageFile The UTF-8 path to the image file
-    * @param imageType The disk image type (can be autodetection)
-    * @param sectorSize Size of device sector in bytes (or 0 for default)
-    *
-    * @return -1 on error and 0 on success
-    */
-    virtual int open(const std::string &imageFile, 
-                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT, 
-                     const unsigned int sectorSize = 0) = 0;
-
-    /**
-    * Opens a single (non-split) disk image file so that it can be read.
-    *
-    * @param imageFile The path to the image file
-    * @param imageType The disk image type (can be autodetection)
-    * @param sectorSize Size of device sector in bytes (or 0 for default)
-    *
-    * @return -1 on error and 0 on success
-    */
-    virtual int open(const std::wstring &imageFile, 
-                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT, 
-                     const unsigned int sectorSize = 0) = 0;
-
-    /**
-    * Opens one or more disk image files so that they can be read.  This
-    * version always takes a UTF-8 encoding of the image files.
-    *
-    * @param imageFile A vector of UTF-8 encoded image files
-    * @param imageType The disk image type (can be autodetection)
-    * @param sectorSize Size of device sector in bytes (or 0 for default)
-    *
-    * @return -1 on error and 0 on success
-    */
-    virtual int open(const std::vector<std::string> &imageFile, 
-                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT, 
-                     const unsigned int sectorSize = 0) = 0;
-
-    /**
-    * Opens one or more disk image files so that they can be read.
-    *
-    * @param imageFile A vector of image files
-    * @param imageType The disk image type (can be autodetection)
-    * @param sectorSize Size of device sector in bytes (or 0 for default)
-    *
-    * @return -1 on error and 0 on success
-    */
-    virtual int open(const std::vector<std::wstring> &imageFile,
-                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT,
-                     const unsigned int sectorSize = 0) = 0;
-
-private:
-
-};
-
-#endif
+/*
+ *
+ *  The Sleuth Kit
+ *
+ *  Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ *  Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ *  reserved.
+ *
+ *  This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file TskImageFile.h
+ * Contains the interface for the TskImageFile class.
+ */
+
+#ifndef _TSK_IMAGEFILE_H
+#define _TSK_IMAGEFILE_H
+
+#include "tsk/framework/framework_i.h"
+#include <vector>
+#include <string>
+
+/**
+ * An interface to a class that allows file system and low-level 
+ * access to a disk image.
+ * It supports opening split image files, extracting file system 
+ * information from the image and extracting data for a specific file
+ * or for a range of sectors.  You must call one of the open() methods
+ * before using any of the other methods in the interface. 
+ */
+class TSK_FRAMEWORK_API TskImageFile
+{
+public:
+    /**
+     * You must call one of the open() methods after creating the object.
+     */
+    TskImageFile();
+
+    virtual ~TskImageFile();
+
+    /**
+     * open the images at the paths saved in ImgDB
+     * @returns 0 on success and -1 on error
+     */
+    virtual int open() = 0;
+
+    /// Close the disk image.
+    virtual void close() = 0;
+
+    /// Return the file name(s) that make up the image.
+    virtual std::vector<std::string> getFileNames() const = 0;
+    virtual std::vector<std::wstring> getFileNamesW() const = 0;
+
+    /**
+     * Analyze the volume and file systems in the opened images and 
+     * populate the TskImgDB instance registered with TskServices.  This
+     * will not perform file carving.
+     * @returns 1 if there was a major error that prevented any extraction.  0 will
+     * be returned if there were minor errors during extraction or if there were 
+     * no errors.
+     */
+    virtual int extractFiles() = 0;
+
+    /**
+     * Return the data located at the given sector offset in the disk image.
+     * @param sect_start Sector offset into image from which to return data
+     * @param sect_len Number of sectors to read
+     * @param buffer A buffer into which data will be placed. Must be at
+     * least len * 512 large
+     * @return Number of sectors read or -1 on error
+     */
+    virtual int getSectorData(const uint64_t sect_start, 
+                              const uint64_t sect_len, 
+                              char *buffer) = 0;
+
+    /**
+     * Return the data located at the given byte offset in the disk image.
+     * @param byte_start Byte offset into image from which to return data
+     * @param byte_len Number of bytes to read
+     * @param buffer A buffer into which data will be placed. Must be at
+     * least byte_len large
+     * @return Number of bytes read or -1 on error
+     */
+    virtual int getByteData(const uint64_t byte_start, 
+                            const uint64_t byte_len, 
+                            char *buffer) = 0;
+
+    /**
+     * Provides access to the content of a specific file that was extracted from the disk image.
+     *
+     * @param fileId ID of the file (can be found in database)
+     * @returns A handle to the file or -1 on error.
+     */
+    virtual int openFile(const uint64_t fileId) = 0;
+
+    /**
+     * Reads content of a file that was opened with openFile(). 
+     * @param handle File handle that was returned by an earlier call to openFile()
+     * @param byte_offset Starting byte offset from which to read data
+     * @param byte_len The number of bytes to read
+     * @param buffer A buffer into which data will be placed. Must be at least
+     * byte_len bytes.
+     * @return Number of bytes read or -1 on error
+     */
+    virtual int readFile(const int handle, 
+                         const TSK_OFF_T byte_offset, 
+                         const size_t byte_len, 
+                         char * buffer) = 0;
+   /**
+     * Closes an opened file.
+     * @param handle File handle that was returned by an earlier call to openFile()
+     */
+    virtual int closeFile(const int handle) = 0;
+
+    /**
+    * Opens a single (non-split) disk image file so that it can be read.
+    *
+    * @param imageFile The path to the image file
+    * @param imageType The disk image type (can be autodetection)
+    * @param sectorSize Size of device sector in bytes (or 0 for default)
+    *
+    * @return -1 on error and 0 on success
+    */
+    virtual int open(const TSK_TCHAR *imageFile, 
+                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT, 
+                     const unsigned int sectorSize = 0) = 0;
+
+    /**
+    * Opens one or more disk image files so that they can be read. e UTF8, then consider
+    *
+    * @param numberOfImages The number of images to open (will be > 1 for split images).
+    * @param imageFile The path to the image files (the number of files must
+    * be equal to num_img and they must be in a sorted order)
+    * @param imageType The disk image type (can be autodetection)
+    * @param sectorSize Size of device sector in bytes (or 0 for default)
+    *
+    * @return -1 on error and 0 on success
+    */
+    virtual int open(const int numberOfImages, 
+                     const TSK_TCHAR * const imageFile[], 
+                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT, 
+                     const unsigned int sectorSize = 0) = 0;
+
+    /**
+    * Opens a single (non-split) disk image file so that it can be read.  This version
+    * always takes a UTF-8 encoding of the disk image.
+    *
+    * @param imageFile The UTF-8 path to the image file
+    * @param imageType The disk image type (can be autodetection)
+    * @param sectorSize Size of device sector in bytes (or 0 for default)
+    *
+    * @return -1 on error and 0 on success
+    */
+    virtual int open(const std::string &imageFile, 
+                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT, 
+                     const unsigned int sectorSize = 0) = 0;
+
+    /**
+    * Opens a single (non-split) disk image file so that it can be read.
+    *
+    * @param imageFile The path to the image file
+    * @param imageType The disk image type (can be autodetection)
+    * @param sectorSize Size of device sector in bytes (or 0 for default)
+    *
+    * @return -1 on error and 0 on success
+    */
+    virtual int open(const std::wstring &imageFile, 
+                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT, 
+                     const unsigned int sectorSize = 0) = 0;
+
+    /**
+    * Opens one or more disk image files so that they can be read.  This
+    * version always takes a UTF-8 encoding of the image files.
+    *
+    * @param imageFile A vector of UTF-8 encoded image files
+    * @param imageType The disk image type (can be autodetection)
+    * @param sectorSize Size of device sector in bytes (or 0 for default)
+    *
+    * @return -1 on error and 0 on success
+    */
+    virtual int open(const std::vector<std::string> &imageFile, 
+                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT, 
+                     const unsigned int sectorSize = 0) = 0;
+
+    /**
+    * Opens one or more disk image files so that they can be read.
+    *
+    * @param imageFile A vector of image files
+    * @param imageType The disk image type (can be autodetection)
+    * @param sectorSize Size of device sector in bytes (or 0 for default)
+    *
+    * @return -1 on error and 0 on success
+    */
+    virtual int open(const std::vector<std::wstring> &imageFile,
+                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT,
+                     const unsigned int sectorSize = 0) = 0;
+
+private:
+
+};
+
+#endif
diff --git a/framework/tsk/framework/extraction/TskImageFileTsk.cpp b/framework/tsk/framework/extraction/TskImageFileTsk.cpp
index 009eafa..be3e3c1 100755
--- a/framework/tsk/framework/extraction/TskImageFileTsk.cpp
+++ b/framework/tsk/framework/extraction/TskImageFileTsk.cpp
@@ -1,430 +1,430 @@
-/*
- *
- *  The Sleuth Kit
- *
- *  Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- *  Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- *  reserved.
- *
- *  This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskImageFileTsk.cpp
- * Contains The Sleuth Kit implementation of the TskImageFile interface.
- */
-
-#include <iostream>
-#include <sstream>
-#include <algorithm>
-
-#include "TskImageFileTsk.h"
-#include "TskAutoImpl.h"
-#include "tsk/framework/utilities/TskUtilities.h"
-#include "tsk/framework/services/TskServices.h"
-#include "tsk/base/tsk_base_i.h"
-
-
-/**
- * Utility function to close file system handles.
- * @param pair An element from the file system map.
- */
-void TskImageFileTsk::closeFs(std::pair<uint64_t, TSK_FS_INFO*> pair)
-{
-    tsk_fs_close(pair.second);
-}
-
-TskImageFileTsk::TskImageFileTsk() : m_db(TskServices::Instance().getImgDB())
-{
-    m_img_info = NULL;
-    m_images_ptrs = NULL;
-}
-
-TskImageFileTsk::~TskImageFileTsk()
-{
-    close();
-}
-
-/*
- * Opens the image files listed in ImgDB for later analysis and extraction.  
- * @returns -1 on error and 0 on success
- */
-int TskImageFileTsk::open()
-{
-    if (!m_images.empty()) {
-        close();        
-    }
-    std::vector<std::string> images = m_db.getImageNames();
-    if (images.empty()) {
-        LOGERROR(L"TskImageFileTsk::open: Error getting image names from ImgDB");
-        return -1;
-    }
-    for (size_t i = 0; i < images.size(); i++) {
-        m_images.push_back(images[i]);
-    }
-    return openImages();
-}
-
-/**
- * Open the image using the names that were already populated in
- * m_images.  Used internally by both open() methods.
- * @returns -1 on error.
- */
-int TskImageFileTsk::openImages(const TSK_IMG_TYPE_ENUM imageType,
-                                const unsigned int sectorSize) 
-{
-    m_images_ptrs = (const char **)malloc(m_images.size() * sizeof(char *));
-    if (m_images_ptrs == NULL)
-        return -1;
-
-    int i = 0;
-    for(std::vector<std::string>::iterator list_iter = m_images.begin(); 
-        list_iter != m_images.end(); list_iter++) {
-            m_images_ptrs[i++] = (*list_iter).c_str();
-    }
-
-    m_img_info = tsk_img_open_utf8(i, m_images_ptrs, imageType, sectorSize);
-    if (m_img_info == NULL) 
-    {
-        std::wstringstream logMessage;
-        logMessage << L"TskImageFileTsk::openImages - Error with tsk_img_open: " << tsk_error_get() << std::endl;
-        LOGERROR(logMessage.str());
-
-        return -1;
-    }
-
-    return 0;
-}
-
-
-void TskImageFileTsk::close()
-{
-    if (m_img_info) {
-        tsk_img_close(m_img_info);
-        m_img_info = NULL;
-    }
-
-    if (m_images_ptrs) {
-        free(m_images_ptrs);
-        m_images_ptrs = NULL;
-    }
-
-    m_images.clear();
-
-    // Close the handles in m_openFiles and m_openFs
-    for (uint32_t i = 0; i < m_openFiles.size(); i++)
-        closeFile(i);
-
-    std::for_each(m_openFs.begin(), m_openFs.end(), (&TskImageFileTsk::closeFs));
-}
-
-/*
- * @param start Sector offset to start reading from in current sector run
- * @param len Number of sectors to read
- * @param a_buffer Buffer to read into (must be of size a_len * 512 or larger)
- * @returns -1 on error or number of sectors read
- */
-int TskImageFileTsk::getSectorData(const uint64_t sect_start, 
-                                const uint64_t sect_len, 
-                                char *buffer)
-{
-    int retval = getByteData(sect_start*512, sect_len*512, buffer);
-    if (retval != -1)
-        return retval / 512;
-    else
-        return retval;
-}
-
-/*
- * @param byte_start Byte offset to start reading from start of file
- * @param byte_len Number of bytes to read
- * @param buffer Buffer to read into (must be of size byte_len or larger)
- * @returns -1 on error or number of bytes read
- */
-int TskImageFileTsk::getByteData(const uint64_t byte_start, 
-                                const uint64_t byte_len, 
-                                char *buffer)
-{
-    if (m_img_info == NULL) {
-        if (open() != 0)
-            return -1;
-    }
-
-    int retval = tsk_img_read(m_img_info, byte_start, buffer, (size_t)(byte_len));
-    if (retval == -1) {
-        std::wstringstream message;
-        message << L"TskImageFileTsk::getByteData - tsk_img_read -- start: " 
-            << byte_start << " -- len: " << byte_len
-            << "(" << tsk_error_get() << ")" << std::endl;
-        LOGERROR(message.str());
-        return -1;
-    }
-
-    return retval;
-}
-
-int TskImageFileTsk::extractFiles()
-{
-    // @@@ Add Sanity check that DB is empty 
-    if (m_img_info == NULL) {
-        LOGERROR(L"TskImageFileTsk::extractFiles: Images not open yet\n");
-        return 1;
-    }
-
-    m_db.addImageInfo((int)m_img_info->itype, m_img_info->sector_size);
-
-    for (uint32_t i = 0; i < m_images.size(); i++) {
-        const char *img_ptr = NULL;
-        img_ptr = m_images[i].c_str();
-        m_db.addImageName(img_ptr);
-     }
-
-    TSKAutoImpl tskAutoImpl;
-    if (tskAutoImpl.openImage(m_img_info)) 
-    {
-        std::wstringstream msg;
-        msg << L"TSKExtract::processImage - Error opening image: " << tsk_error_get() << std::endl;
-        LOGERROR(msg.str());
-        return 1;
-    }
-
-    // TskAutoImpl will log errors as they occur
-    tskAutoImpl.extractFiles();
-
-    // It's possible that this is an image with no volumes or file systems.
-    // Scan the image for file systems starting at sector 0.
-    // By default it will scan 1024 sectors.
-    if (m_db.getNumVolumes() == 0)
-    {
-        tskAutoImpl.scanImgForFs(0);
-    }
-
-    return 0;
-}
-
-int TskImageFileTsk::openFile(const uint64_t fileId)
-{
-    if (m_img_info == NULL) {
-        if (open() != 0)
-            return -1;
-    }
-
-    // Use ImgDb::getFileUniqueIdentifiers to get the four needed values.
-    uint64_t fsByteOffset = 0;
-    uint64_t fsFileId = 0;
-    int attrType = TSK_FS_ATTR_TYPE_NOT_FOUND;
-    int attrId = 0;
-
-    if (m_db.getFileUniqueIdentifiers(fileId, fsByteOffset, fsFileId, attrType, attrId) != 0)
-    {
-        LOGERROR(L"TskImageFileTsk::openFile - Error getting file identifiers.\n");
-        return -1;
-    }
-
-    // Check if the file system at the offset is already open (using m_openFs).  If not, open it (tsk_fs_open) and add it to the map.
-    TSK_FS_INFO * fsInfo = m_openFs[fsByteOffset];
-
-    if (fsInfo == NULL)
-    {
-        // Open the file system and add it to the map.
-        fsInfo = tsk_fs_open_img(m_img_info, fsByteOffset, TSK_FS_TYPE_DETECT);
-
-        if (fsInfo == NULL)
-        {
-            std::wstringstream errorMsg;
-            errorMsg << L"TskImageFileTsk::openFile - Error opening file system : " << tsk_error_get();
-            LOGERROR(errorMsg.str());
-            return -1;
-        }
-
-        m_openFs[fsByteOffset] = fsInfo;
-    }
-
-    // Find a new entry in m_openFiles and use tsk_fs_file_open to open the file and save the handle in m_openFiles. 
-    TSK_FS_FILE * fsFile = tsk_fs_file_open_meta(fsInfo, NULL, fsFileId);
-
-    if (fsFile == NULL)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImageFileTsk::openFile - Error opening file : " << tsk_error_get();
-        LOGERROR(errorMsg.str());
-        return -1;
-    }
-
-    const TSK_FS_ATTR * fsAttr = tsk_fs_file_attr_get_id(fsFile, attrId);
-
-    // @@@ TSK_ATTR_TYPE_ENUM should have a value added to it to represent an
-    // empty (or null) attribute type and we should then compare attrType against
-    // this enum value instead of 0.
-
-    // It is possible to have a file with no attributes. We only report an
-    // error if we are expecting a valid attribute.
-    if (attrType != TSK_FS_ATTR_TYPE_NOT_FOUND && fsAttr == NULL)
-    {
-        std::wstringstream msg;
-        msg << L"TskImageFileTsk::openFile - Error getting attribute : " << tsk_error_get();
-        LOGERROR(msg.str());
-        return -1;
-    }
-
-    TskImageFileTsk::OPEN_FILE * openFile = new TskImageFileTsk::OPEN_FILE();
-    openFile->fsFile = fsFile;
-    openFile->fsAttr = fsAttr;
-
-    m_openFiles.push_back(openFile);
-
-    // Return the index into m_openFiles
-    return m_openFiles.size() - 1;
-}
-
-int TskImageFileTsk::readFile(const int handle, 
-                              const TSK_OFF_T byte_offset, 
-                              const size_t byte_len, 
-                              char * buffer)
-{
-    TskImageFileTsk::OPEN_FILE * openFile = m_openFiles[handle];
-
-    if (openFile == NULL || openFile->fsFile == NULL)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImageFileTsk::readFile - Either OPEN_FILE or TSK_FS_FILE is null." << std::endl;
-        LOGERROR(errorMsg.str());
-        return -1;
-    }
-
-    // fsAttr can be NULL if the file has no attributes.
-    if (openFile->fsAttr == NULL || (TSK_OFF_T)byte_offset >= openFile->fsAttr->size)
-    {
-        // If the offset is larger than the attribute size then there is nothing left to read.
-        return 0;
-    }
-
-    int bytesRead = tsk_fs_attr_read(openFile->fsAttr, byte_offset, buffer, 
-                                          byte_len, TSK_FS_FILE_READ_FLAG_NONE);
-    if (bytesRead == -1)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImageFileTsk::readFile - Error reading file (FS_OFFSET: " 
-            << openFile->fsFile->fs_info->offset << " - ID: "
-            << openFile->fsFile->meta->addr << " - " 
-            << ((openFile->fsFile->meta->flags & TSK_FS_META_FLAG_ALLOC) ? "Allocated" : "Deleted")
-            << ") (" 
-            << tsk_error_get() << ")" << std::endl;
-        LOGERROR(errorMsg.str());
-    }
-
-    return bytesRead;
-}
-
-int TskImageFileTsk::closeFile(const int handle)
-{
-    // get the handle from m_openFiles
-    TskImageFileTsk::OPEN_FILE * openFile = m_openFiles[handle];
-
-    if (openFile == NULL || openFile->fsFile == NULL)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImageFileTsk::closeFile - Either OPEN_FILE ot TSK_FS_FILE is null." << std::endl;
-        LOGERROR(errorMsg.str());
-        return -1;
-    }
-
-    // close the file
-    tsk_fs_file_close(openFile->fsFile);
-
-    // remove the entry from m_openFiles
-    m_openFiles.erase(m_openFiles.begin() + handle);
-
-    // delete the struct
-    delete openFile;
-
-    return 0;
-}
-
-std::vector<std::wstring> TskImageFileTsk::getFileNamesW() const
-{
-    std::vector<std::wstring>imagesWide;
-    for (size_t i = 0; i < imagesWide.size(); i++) {
-        imagesWide.push_back(TskUtilities::toUTF16(m_images[i]));
-    }
-    return imagesWide;
-}
-
-int TskImageFileTsk::open(const TSK_TCHAR *imageFile, 
-                          const TSK_IMG_TYPE_ENUM imageType,
-                          const unsigned int sectorSize)
-{
-    if (!m_images.empty()) {
-        close();        
-    }
-#ifdef TSK_WIN32
-    m_images.push_back(TskUtilities::toUTF8(imageFile));
-#else
-    m_images.push_back(std::string(imageFile));
-#endif
-    return openImages(imageType, sectorSize);
-}
-
-int TskImageFileTsk::open(const int numberOfImages, 
-                          const TSK_TCHAR * const imageFile[], 
-                          const TSK_IMG_TYPE_ENUM imageType,
-                          const unsigned int sectorSize)
-{
-    if (!m_images.empty()) {
-        close();        
-    }
-    for (int i = 0; i < numberOfImages; i++) {
-#ifdef WIN32
-        m_images.push_back(TskUtilities::toUTF8(imageFile[i]));
-#else
-        m_images.push_back(std::string(imageFile[i]));
-#endif
-    }
-    return openImages(imageType, sectorSize);
-}
-
-int TskImageFileTsk::open(const std::string &imageFile, 
-                          const TSK_IMG_TYPE_ENUM imageType,
-                          const unsigned int sectorSize)
-{
-    if (!m_images.empty()) {
-        close();        
-    }
-    m_images.push_back(imageFile);
-    return openImages(imageType, sectorSize);
-}
-
-int TskImageFileTsk::open(const std::wstring &imageFile, 
-                          const TSK_IMG_TYPE_ENUM imageType,
-                          const unsigned int sectorSize)
-{
-    return open(TskUtilities::toUTF8(imageFile), imageType, sectorSize);
-}
-
-int TskImageFileTsk::open(const std::vector<std::string> &imageFile, 
-                          const TSK_IMG_TYPE_ENUM imageType,
-                          const unsigned int sectorSize)
-{
-    if (!m_images.empty()) {
-        close();        
-    }
-    for (size_t i = 0; i < imageFile.size(); i++) {
-        m_images.push_back(imageFile[i]);
-    }
-    return openImages(imageType, sectorSize);
-}
-
-int TskImageFileTsk::open(const std::vector<std::wstring> &imageFile, 
-                          const TSK_IMG_TYPE_ENUM imageType,
-                          const unsigned int sectorSize)
-{
-    if (!m_images.empty()) {
-        close();        
-    }
-    for (size_t i = 0; i < imageFile.size(); i++) {
-        m_images.push_back(TskUtilities::toUTF8(imageFile[i]));
-    }
-    return openImages(imageType, sectorSize);
-}
-
-
+/*
+ *
+ *  The Sleuth Kit
+ *
+ *  Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ *  Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ *  reserved.
+ *
+ *  This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file TskImageFileTsk.cpp
+ * Contains The Sleuth Kit implementation of the TskImageFile interface.
+ */
+
+#include <iostream>
+#include <sstream>
+#include <algorithm>
+
+#include "TskImageFileTsk.h"
+#include "TskAutoImpl.h"
+#include "tsk/framework/utilities/TskUtilities.h"
+#include "tsk/framework/services/TskServices.h"
+#include "tsk/base/tsk_base_i.h"
+
+
+/**
+ * Utility function to close file system handles.
+ * @param pair An element from the file system map.
+ */
+void TskImageFileTsk::closeFs(std::pair<uint64_t, TSK_FS_INFO*> pair)
+{
+    tsk_fs_close(pair.second);
+}
+
+TskImageFileTsk::TskImageFileTsk() : m_db(TskServices::Instance().getImgDB())
+{
+    m_img_info = NULL;
+    m_images_ptrs = NULL;
+}
+
+TskImageFileTsk::~TskImageFileTsk()
+{
+    close();
+}
+
+/*
+ * Opens the image files listed in ImgDB for later analysis and extraction.  
+ * @returns -1 on error and 0 on success
+ */
+int TskImageFileTsk::open()
+{
+    if (!m_images.empty()) {
+        close();        
+    }
+    std::vector<std::string> images = m_db.getImageNames();
+    if (images.empty()) {
+        LOGERROR(L"TskImageFileTsk::open: Error getting image names from ImgDB");
+        return -1;
+    }
+    for (size_t i = 0; i < images.size(); i++) {
+        m_images.push_back(images[i]);
+    }
+    return openImages();
+}
+
+/**
+ * Open the image using the names that were already populated in
+ * m_images.  Used internally by both open() methods.
+ * @returns -1 on error.
+ */
+int TskImageFileTsk::openImages(const TSK_IMG_TYPE_ENUM imageType,
+                                const unsigned int sectorSize) 
+{
+    m_images_ptrs = (const char **)malloc(m_images.size() * sizeof(char *));
+    if (m_images_ptrs == NULL)
+        return -1;
+
+    int i = 0;
+    for(std::vector<std::string>::iterator list_iter = m_images.begin(); 
+        list_iter != m_images.end(); list_iter++) {
+            m_images_ptrs[i++] = (*list_iter).c_str();
+    }
+
+    m_img_info = tsk_img_open_utf8(i, m_images_ptrs, imageType, sectorSize);
+    if (m_img_info == NULL) 
+    {
+        std::wstringstream logMessage;
+        logMessage << L"TskImageFileTsk::openImages - Error with tsk_img_open: " << tsk_error_get() << std::endl;
+        LOGERROR(logMessage.str());
+
+        return -1;
+    }
+
+    return 0;
+}
+
+
+void TskImageFileTsk::close()
+{
+    if (m_img_info) {
+        tsk_img_close(m_img_info);
+        m_img_info = NULL;
+    }
+
+    if (m_images_ptrs) {
+        free(m_images_ptrs);
+        m_images_ptrs = NULL;
+    }
+
+    m_images.clear();
+
+    // Close the handles in m_openFiles and m_openFs
+    for (uint32_t i = 0; i < m_openFiles.size(); i++)
+        closeFile(i);
+
+    std::for_each(m_openFs.begin(), m_openFs.end(), (&TskImageFileTsk::closeFs));
+}
+
+/*
+ * @param start Sector offset to start reading from in current sector run
+ * @param len Number of sectors to read
+ * @param a_buffer Buffer to read into (must be of size a_len * 512 or larger)
+ * @returns -1 on error or number of sectors read
+ */
+int TskImageFileTsk::getSectorData(const uint64_t sect_start, 
+                                const uint64_t sect_len, 
+                                char *buffer)
+{
+    int retval = getByteData(sect_start*512, sect_len*512, buffer);
+    if (retval != -1)
+        return retval / 512;
+    else
+        return retval;
+}
+
+/*
+ * @param byte_start Byte offset to start reading from start of file
+ * @param byte_len Number of bytes to read
+ * @param buffer Buffer to read into (must be of size byte_len or larger)
+ * @returns -1 on error or number of bytes read
+ */
+int TskImageFileTsk::getByteData(const uint64_t byte_start, 
+                                const uint64_t byte_len, 
+                                char *buffer)
+{
+    if (m_img_info == NULL) {
+        if (open() != 0)
+            return -1;
+    }
+
+    int retval = tsk_img_read(m_img_info, byte_start, buffer, (size_t)(byte_len));
+    if (retval == -1) {
+        std::wstringstream message;
+        message << L"TskImageFileTsk::getByteData - tsk_img_read -- start: " 
+            << byte_start << " -- len: " << byte_len
+            << "(" << tsk_error_get() << ")" << std::endl;
+        LOGERROR(message.str());
+        return -1;
+    }
+
+    return retval;
+}
+
+int TskImageFileTsk::extractFiles()
+{
+    // @@@ Add Sanity check that DB is empty 
+    if (m_img_info == NULL) {
+        LOGERROR(L"TskImageFileTsk::extractFiles: Images not open yet\n");
+        return 1;
+    }
+
+    m_db.addImageInfo((int)m_img_info->itype, m_img_info->sector_size);
+
+    for (uint32_t i = 0; i < m_images.size(); i++) {
+        const char *img_ptr = NULL;
+        img_ptr = m_images[i].c_str();
+        m_db.addImageName(img_ptr);
+     }
+
+    TSKAutoImpl tskAutoImpl;
+    if (tskAutoImpl.openImage(m_img_info)) 
+    {
+        std::wstringstream msg;
+        msg << L"TSKExtract::processImage - Error opening image: " << tsk_error_get() << std::endl;
+        LOGERROR(msg.str());
+        return 1;
+    }
+
+    // TskAutoImpl will log errors as they occur
+    tskAutoImpl.extractFiles();
+
+    // It's possible that this is an image with no volumes or file systems.
+    // Scan the image for file systems starting at sector 0.
+    // By default it will scan 1024 sectors.
+    if (m_db.getNumVolumes() == 0)
+    {
+        tskAutoImpl.scanImgForFs(0);
+    }
+
+    return 0;
+}
+
+int TskImageFileTsk::openFile(const uint64_t fileId)
+{
+    if (m_img_info == NULL) {
+        if (open() != 0)
+            return -1;
+    }
+
+    // Use ImgDb::getFileUniqueIdentifiers to get the four needed values.
+    uint64_t fsByteOffset = 0;
+    uint64_t fsFileId = 0;
+    int attrType = TSK_FS_ATTR_TYPE_NOT_FOUND;
+    int attrId = 0;
+
+    if (m_db.getFileUniqueIdentifiers(fileId, fsByteOffset, fsFileId, attrType, attrId) != 0)
+    {
+        LOGERROR(L"TskImageFileTsk::openFile - Error getting file identifiers.\n");
+        return -1;
+    }
+
+    // Check if the file system at the offset is already open (using m_openFs).  If not, open it (tsk_fs_open) and add it to the map.
+    TSK_FS_INFO * fsInfo = m_openFs[fsByteOffset];
+
+    if (fsInfo == NULL)
+    {
+        // Open the file system and add it to the map.
+        fsInfo = tsk_fs_open_img(m_img_info, fsByteOffset, TSK_FS_TYPE_DETECT);
+
+        if (fsInfo == NULL)
+        {
+            std::wstringstream errorMsg;
+            errorMsg << L"TskImageFileTsk::openFile - Error opening file system : " << tsk_error_get();
+            LOGERROR(errorMsg.str());
+            return -1;
+        }
+
+        m_openFs[fsByteOffset] = fsInfo;
+    }
+
+    // Find a new entry in m_openFiles and use tsk_fs_file_open to open the file and save the handle in m_openFiles. 
+    TSK_FS_FILE * fsFile = tsk_fs_file_open_meta(fsInfo, NULL, fsFileId);
+
+    if (fsFile == NULL)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImageFileTsk::openFile - Error opening file : " << tsk_error_get();
+        LOGERROR(errorMsg.str());
+        return -1;
+    }
+
+    const TSK_FS_ATTR * fsAttr = tsk_fs_file_attr_get_id(fsFile, attrId);
+
+    // @@@ TSK_ATTR_TYPE_ENUM should have a value added to it to represent an
+    // empty (or null) attribute type and we should then compare attrType against
+    // this enum value instead of 0.
+
+    // It is possible to have a file with no attributes. We only report an
+    // error if we are expecting a valid attribute.
+    if (attrType != TSK_FS_ATTR_TYPE_NOT_FOUND && fsAttr == NULL)
+    {
+        std::wstringstream msg;
+        msg << L"TskImageFileTsk::openFile - Error getting attribute : " << tsk_error_get();
+        LOGERROR(msg.str());
+        return -1;
+    }
+
+    TskImageFileTsk::OPEN_FILE * openFile = new TskImageFileTsk::OPEN_FILE();
+    openFile->fsFile = fsFile;
+    openFile->fsAttr = fsAttr;
+
+    m_openFiles.push_back(openFile);
+
+    // Return the index into m_openFiles
+    return m_openFiles.size() - 1;
+}
+
+int TskImageFileTsk::readFile(const int handle, 
+                              const TSK_OFF_T byte_offset, 
+                              const size_t byte_len, 
+                              char * buffer)
+{
+    TskImageFileTsk::OPEN_FILE * openFile = m_openFiles[handle];
+
+    if (openFile == NULL || openFile->fsFile == NULL)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImageFileTsk::readFile - Either OPEN_FILE or TSK_FS_FILE is null." << std::endl;
+        LOGERROR(errorMsg.str());
+        return -1;
+    }
+
+    // fsAttr can be NULL if the file has no attributes.
+    if (openFile->fsAttr == NULL || (TSK_OFF_T)byte_offset >= openFile->fsAttr->size)
+    {
+        // If the offset is larger than the attribute size then there is nothing left to read.
+        return 0;
+    }
+
+    int bytesRead = tsk_fs_attr_read(openFile->fsAttr, byte_offset, buffer, 
+                                          byte_len, TSK_FS_FILE_READ_FLAG_NONE);
+    if (bytesRead == -1)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImageFileTsk::readFile - Error reading file (FS_OFFSET: " 
+            << openFile->fsFile->fs_info->offset << " - ID: "
+            << openFile->fsFile->meta->addr << " - " 
+            << ((openFile->fsFile->meta->flags & TSK_FS_META_FLAG_ALLOC) ? "Allocated" : "Deleted")
+            << ") (" 
+            << tsk_error_get() << ")" << std::endl;
+        LOGERROR(errorMsg.str());
+    }
+
+    return bytesRead;
+}
+
+int TskImageFileTsk::closeFile(const int handle)
+{
+    // get the handle from m_openFiles
+    TskImageFileTsk::OPEN_FILE * openFile = m_openFiles[handle];
+
+    if (openFile == NULL || openFile->fsFile == NULL)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImageFileTsk::closeFile - Either OPEN_FILE ot TSK_FS_FILE is null." << std::endl;
+        LOGERROR(errorMsg.str());
+        return -1;
+    }
+
+    // close the file
+    tsk_fs_file_close(openFile->fsFile);
+
+    // remove the entry from m_openFiles
+    m_openFiles.erase(m_openFiles.begin() + handle);
+
+    // delete the struct
+    delete openFile;
+
+    return 0;
+}
+
+std::vector<std::wstring> TskImageFileTsk::getFileNamesW() const
+{
+    std::vector<std::wstring>imagesWide;
+    for (size_t i = 0; i < imagesWide.size(); i++) {
+        imagesWide.push_back(TskUtilities::toUTF16(m_images[i]));
+    }
+    return imagesWide;
+}
+
+int TskImageFileTsk::open(const TSK_TCHAR *imageFile, 
+                          const TSK_IMG_TYPE_ENUM imageType,
+                          const unsigned int sectorSize)
+{
+    if (!m_images.empty()) {
+        close();        
+    }
+#ifdef TSK_WIN32
+    m_images.push_back(TskUtilities::toUTF8(imageFile));
+#else
+    m_images.push_back(std::string(imageFile));
+#endif
+    return openImages(imageType, sectorSize);
+}
+
+int TskImageFileTsk::open(const int numberOfImages, 
+                          const TSK_TCHAR * const imageFile[], 
+                          const TSK_IMG_TYPE_ENUM imageType,
+                          const unsigned int sectorSize)
+{
+    if (!m_images.empty()) {
+        close();        
+    }
+    for (int i = 0; i < numberOfImages; i++) {
+#ifdef WIN32
+        m_images.push_back(TskUtilities::toUTF8(imageFile[i]));
+#else
+        m_images.push_back(std::string(imageFile[i]));
+#endif
+    }
+    return openImages(imageType, sectorSize);
+}
+
+int TskImageFileTsk::open(const std::string &imageFile, 
+                          const TSK_IMG_TYPE_ENUM imageType,
+                          const unsigned int sectorSize)
+{
+    if (!m_images.empty()) {
+        close();        
+    }
+    m_images.push_back(imageFile);
+    return openImages(imageType, sectorSize);
+}
+
+int TskImageFileTsk::open(const std::wstring &imageFile, 
+                          const TSK_IMG_TYPE_ENUM imageType,
+                          const unsigned int sectorSize)
+{
+    return open(TskUtilities::toUTF8(imageFile), imageType, sectorSize);
+}
+
+int TskImageFileTsk::open(const std::vector<std::string> &imageFile, 
+                          const TSK_IMG_TYPE_ENUM imageType,
+                          const unsigned int sectorSize)
+{
+    if (!m_images.empty()) {
+        close();        
+    }
+    for (size_t i = 0; i < imageFile.size(); i++) {
+        m_images.push_back(imageFile[i]);
+    }
+    return openImages(imageType, sectorSize);
+}
+
+int TskImageFileTsk::open(const std::vector<std::wstring> &imageFile, 
+                          const TSK_IMG_TYPE_ENUM imageType,
+                          const unsigned int sectorSize)
+{
+    if (!m_images.empty()) {
+        close();        
+    }
+    for (size_t i = 0; i < imageFile.size(); i++) {
+        m_images.push_back(TskUtilities::toUTF8(imageFile[i]));
+    }
+    return openImages(imageType, sectorSize);
+}
+
+
diff --git a/framework/tsk/framework/extraction/TskImageFileTsk.h b/framework/tsk/framework/extraction/TskImageFileTsk.h
index a4e73c3..4bd98de 100755
--- a/framework/tsk/framework/extraction/TskImageFileTsk.h
+++ b/framework/tsk/framework/extraction/TskImageFileTsk.h
@@ -1,110 +1,110 @@
-/*
- *
- *  The Sleuth Kit
- *
- *  Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- *  Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- *  reserved.
- *
- *  This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskImageFile.h
- * An implementation of the TskImageFile class that uses The Sleuth Kit.
- */
-#ifndef _TSK_IMAGEFILETSK_H
-#define _TSK_IMAGEFILETSK_H
-
-#include "TskImageFile.h"
-#include "tsk/framework/services/TskImgDB.h"
-#include "tsk/framework/services/Log.h"
-#include "tsk/libtsk.h"
-
-#include <vector>
-#include <map>
-
-/// A Sleuth Kit implementation of the TskImageFile interface. 
-/**
- * TskImageFile defines an interface for interacting with disk images.
- * TskImageFileTsk is an implementation of that interface that uses The Sleuth Kit 
- */
-class TSK_FRAMEWORK_API TskImageFileTsk : public TskImageFile
-{
-public:
-    TskImageFileTsk();
-
-    virtual ~TskImageFileTsk();
-
-    virtual int open();
-    virtual void close();
-
-    virtual std::vector<std::string> getFileNames() const { return m_images; }
-    virtual std::vector<std::wstring> getFileNamesW() const;
-
-    virtual int getSectorData(const uint64_t sect_start, 
-                              const uint64_t sect_len, 
-                              char *buffer);
-
-    virtual int getByteData(const uint64_t byte_start, 
-                            const uint64_t byte_len, 
-                            char *buffer);
-
-    virtual int extractFiles();
-
-    virtual int openFile(const uint64_t fileId);
-
-    virtual int readFile(const int handle, 
-                         const TSK_OFF_T byte_offset, 
-                         const size_t byte_len, 
-                         char * buffer);
-
-    virtual int closeFile(const int handle);
-
-    virtual int open(const TSK_TCHAR *imageFile, 
-                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT, 
-                     const unsigned int sectorSize = 0);
-
-    virtual int open(const int numberOfImages, 
-                     const TSK_TCHAR * const imageFile[], 
-                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT, 
-                     const unsigned int sectorSize = 0);
-
-    virtual int open(const std::string &imageFile, 
-                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT, 
-                     const unsigned int sectorSize = 0);
-
-    virtual int open(const std::wstring &imageFile, 
-                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT, 
-                     const unsigned int sectorSize = 0);
-
-    virtual int open(const std::vector<std::string> &imageFile, 
-                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT, 
-                     const unsigned int sectorSize = 0);
-
-    virtual int open(const std::vector<std::wstring> &imageFile,
-                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT,
-                     const unsigned int sectorSize = 0);
-
-private:
-    TskImgDB &m_db;
-    TSK_IMG_INFO *m_img_info;
-    std::vector<std::string> m_images;
-    const char **m_images_ptrs;
-
-    struct TSK_FRAMEWORK_API OPEN_FILE
-    {
-        TSK_FS_FILE * fsFile;
-        const TSK_FS_ATTR * fsAttr;
-    };
-
-    std::vector<OPEN_FILE *> m_openFiles; // maps handle returned from openFile() to the open TSK_FS_FILE object
-    std::map<uint64_t, TSK_FS_INFO *> m_openFs; // maps the byte offset of a file system to its open object.
-
-    int openImages(const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT,
-                   const unsigned int sectorSize = 0);
-
-    static void closeFs(std::pair<uint64_t, TSK_FS_INFO *> pair);
-};
-
-#endif
+/*
+ *
+ *  The Sleuth Kit
+ *
+ *  Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ *  Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ *  reserved.
+ *
+ *  This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file TskImageFile.h
+ * An implementation of the TskImageFile class that uses The Sleuth Kit.
+ */
+#ifndef _TSK_IMAGEFILETSK_H
+#define _TSK_IMAGEFILETSK_H
+
+#include "TskImageFile.h"
+#include "tsk/framework/services/TskImgDB.h"
+#include "tsk/framework/services/Log.h"
+#include "tsk/libtsk.h"
+
+#include <vector>
+#include <map>
+
+/// A Sleuth Kit implementation of the TskImageFile interface. 
+/**
+ * TskImageFile defines an interface for interacting with disk images.
+ * TskImageFileTsk is an implementation of that interface that uses The Sleuth Kit 
+ */
+class TSK_FRAMEWORK_API TskImageFileTsk : public TskImageFile
+{
+public:
+    TskImageFileTsk();
+
+    virtual ~TskImageFileTsk();
+
+    virtual int open();
+    virtual void close();
+
+    virtual std::vector<std::string> getFileNames() const { return m_images; }
+    virtual std::vector<std::wstring> getFileNamesW() const;
+
+    virtual int getSectorData(const uint64_t sect_start, 
+                              const uint64_t sect_len, 
+                              char *buffer);
+
+    virtual int getByteData(const uint64_t byte_start, 
+                            const uint64_t byte_len, 
+                            char *buffer);
+
+    virtual int extractFiles();
+
+    virtual int openFile(const uint64_t fileId);
+
+    virtual int readFile(const int handle, 
+                         const TSK_OFF_T byte_offset, 
+                         const size_t byte_len, 
+                         char * buffer);
+
+    virtual int closeFile(const int handle);
+
+    virtual int open(const TSK_TCHAR *imageFile, 
+                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT, 
+                     const unsigned int sectorSize = 0);
+
+    virtual int open(const int numberOfImages, 
+                     const TSK_TCHAR * const imageFile[], 
+                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT, 
+                     const unsigned int sectorSize = 0);
+
+    virtual int open(const std::string &imageFile, 
+                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT, 
+                     const unsigned int sectorSize = 0);
+
+    virtual int open(const std::wstring &imageFile, 
+                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT, 
+                     const unsigned int sectorSize = 0);
+
+    virtual int open(const std::vector<std::string> &imageFile, 
+                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT, 
+                     const unsigned int sectorSize = 0);
+
+    virtual int open(const std::vector<std::wstring> &imageFile,
+                     const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT,
+                     const unsigned int sectorSize = 0);
+
+private:
+    TskImgDB &m_db;
+    TSK_IMG_INFO *m_img_info;
+    std::vector<std::string> m_images;
+    const char **m_images_ptrs;
+
+    struct TSK_FRAMEWORK_API OPEN_FILE
+    {
+        TSK_FS_FILE * fsFile;
+        const TSK_FS_ATTR * fsAttr;
+    };
+
+    std::vector<OPEN_FILE *> m_openFiles; // maps handle returned from openFile() to the open TSK_FS_FILE object
+    std::map<uint64_t, TSK_FS_INFO *> m_openFs; // maps the byte offset of a file system to its open object.
+
+    int openImages(const TSK_IMG_TYPE_ENUM imageType = TSK_IMG_TYPE_DETECT,
+                   const unsigned int sectorSize = 0);
+
+    static void closeFs(std::pair<uint64_t, TSK_FS_INFO *> pair);
+};
+
+#endif
diff --git a/framework/tsk/framework/extraction/TskL01Extract.cpp b/framework/tsk/framework/extraction/TskL01Extract.cpp
index ef34c43..106f654 100755
--- a/framework/tsk/framework/extraction/TskL01Extract.cpp
+++ b/framework/tsk/framework/extraction/TskL01Extract.cpp
@@ -778,29 +778,29 @@ int TskL01Extract::saveFile(const uint64_t fileId, const ArchivedFile &archivedF
     }
 }
 
-void TskL01Extract::scheduleFiles()
-{
-    if (m_fileIdsToSchedule.empty())
-        return;
-
-    Scheduler& scheduler = TskServices::Instance().getScheduler();
-
-    std::set<uint64_t>::const_iterator it = m_fileIdsToSchedule.begin();
-    uint64_t startId = *it, endId = *it;
-
-    while (++it != m_fileIdsToSchedule.end())
-    {
-        if (*it > endId + 1)
-        {
-            scheduler.schedule(Scheduler::FileAnalysis, startId, endId);
-            startId = endId = *it;
-        }
-        else
-        {
-            endId++;
-        }
-    }
-
-    scheduler.schedule(Scheduler::FileAnalysis, startId, endId);
-    m_fileIdsToSchedule.clear();
-}
+void TskL01Extract::scheduleFiles()
+{
+    if (m_fileIdsToSchedule.empty())
+        return;
+
+    Scheduler& scheduler = TskServices::Instance().getScheduler();
+
+    std::set<uint64_t>::const_iterator it = m_fileIdsToSchedule.begin();
+    uint64_t startId = *it, endId = *it;
+
+    while (++it != m_fileIdsToSchedule.end())
+    {
+        if (*it > endId + 1)
+        {
+            scheduler.schedule(Scheduler::FileAnalysis, startId, endId);
+            startId = endId = *it;
+        }
+        else
+        {
+            endId++;
+        }
+    }
+
+    scheduler.schedule(Scheduler::FileAnalysis, startId, endId);
+    m_fileIdsToSchedule.clear();
+}
diff --git a/framework/tsk/framework/file/TskFile.cpp b/framework/tsk/framework/file/TskFile.cpp
index ddec7fc..19b9527 100755
--- a/framework/tsk/framework/file/TskFile.cpp
+++ b/framework/tsk/framework/file/TskFile.cpp
@@ -1,399 +1,410 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskFile.cpp
- * Contains the implementation for the TskFile class.
- */
-
-// System includes
-#include <sstream>
-
-// Framework includes
-#include "TskFile.h"
-#include "tsk/framework/services/TskServices.h"
-
-/**
- * Delete the TskFile object.
- */
-TskFile::~TskFile(void)
-{
-}
-
-
-void TskFile::initialize()
-{
-    TskImgDB * imgDB = &TskServices::Instance().getImgDB();
-    // getDB will throw exception if ImgDB has not been setup
-
-    if (imgDB != NULL) {
-        if (imgDB->getFileRecord(m_id, m_fileRecord)) {
-            throw TskException("TskFile::initialize: Error looking up file: " + m_id);
-        }
-    }
-}
-
-void TskFile::save()
-{
-    if (m_id == 0)
-    {
-        LOGERROR(L"TskFile::save - Attempt to save file with file id 0.");
-        throw TskException("Attempt to save file with file id 0.");
-    }
-
-    // If the file already exists we have nothing to do.
-    if (exists())
-        return;
-
-    // Make sure the file is open before saving.
-    open();
-
-    TskServices::Instance().getFileManager().saveFile(this);
-}
-
-/**
- * What is this files id?
- */
-uint64_t TskFile::getId() const
-{
-    return m_id;
-}
-
-TskImgDB::FILE_TYPES TskFile::getTypeId() const
-{
-    return m_fileRecord.typeId;
-}
-
-/**
- * What is this files name?
- */
-std::string TskFile::getName() const
-{
-    return m_fileRecord.name;
-}
-
-/**
- * What is this files extension?
- */
-std::string TskFile::getExtension() const
-{
-    size_t pos = m_fileRecord.name.find_last_of(".");
-    if (pos == std::string::npos)
-        return std::string("");
-    else
-        return m_fileRecord.name.substr(pos + 1);
-}
-
-/**
- * What is this files parent file id?
- */
-uint64_t TskFile::getParentFileId() const
-{
-    return m_fileRecord.parentFileId;
-}
-
-/**
- * What is this files directory type?
- */
-TSK_FS_NAME_TYPE_ENUM TskFile::getDirType() const
-{
-    return m_fileRecord.dirType;
-}
-/**
- * What is this files metadata type?
- */
-TSK_FS_META_TYPE_ENUM TskFile::getMetaType() const
-{
-    return m_fileRecord.metaType;
-}
-
-/**
- * What are this files directory flags?
- */
-TSK_FS_NAME_FLAG_ENUM TskFile::getDirFlags() const
-{
-    return m_fileRecord.dirFlags;
-}
-
-/**
- * What are this files metadata flags?
- */
-TSK_FS_META_FLAG_ENUM TskFile::getMetaFlags() const
-{
-    return m_fileRecord.metaFlags;
-}
-
-/**
- * What is this files size?
- */
-TSK_OFF_T TskFile::getSize() const
-{
-    return m_fileRecord.size;
-}
-
-/**
- * What is this files change time?
- */
-time_t TskFile::getCtime() const
-{
-    return m_fileRecord.ctime;
-}
-
-/**
- * What is this files creation time?
- */
-time_t TskFile::getCrtime() const
-{
-    return m_fileRecord.crtime;
-}
-
-/**
- * What is this files access time?
- */
-time_t TskFile::getAtime() const
-{
-    return m_fileRecord.atime;
-}
-
-/**
- * What is this files modify time?
- */
-time_t TskFile::getMtime() const
-{
-    return m_fileRecord.mtime;
-}
-
-/**
- * What is this files mode?
- */
-TSK_FS_META_MODE_ENUM TskFile::getMode() const
-{
-    return m_fileRecord.mode;
-}
-
-/**
- * What is this files user id?
- */
-TSK_UID_T TskFile::getUid() const
-{
-    return m_fileRecord.uid;
-}
-
-/**
- * What is this files group id?
- */
-TSK_GID_T TskFile::getGid() const
-{
-    return m_fileRecord.gid;
-}
-
-/**
- * What is this files status?
- */
-TskImgDB::FILE_STATUS TskFile::getStatus() const
-{
-    return m_fileRecord.status;
-}
-
-/*
- * What is this files full path
- */
-std::string TskFile::getFullPath() const
-{
-    return m_fileRecord.fullPath;
-}
-
-std::string TskFile::getUniquePath() const
-{
-    const uint64_t VOLUME_SHADOW_SNAPSHOT_FILE_PARENT_ID = 9223372036854775807;
-    
-    std::stringstream path;
-    
-    if (m_fileRecord.typeId == TskImgDB::IMGDB_FILES_TYPE_CARVED)
-    {
-        path << "/carved/" << m_fileRecord.fullPath;
-    }
-    else
-    {
-        uint64_t fileSystemSectorOffset = 0;
-        uint64_t unusedUint = 0;
-        int unusedInt = 0;
-        if (m_fileRecord.typeId == TskImgDB::IMGDB_FILES_TYPE_DERIVED)
-        {
-            if (m_fileRecord.parentFileId != VOLUME_SHADOW_SNAPSHOT_FILE_PARENT_ID)
-            {
-                TskServices::Instance().getImgDB().getFileUniqueIdentifiers(m_fileRecord.parentFileId, fileSystemSectorOffset, unusedUint, unusedInt, unusedInt);
-            }
-            else
-            {
-                // The full path will have an initial component of the form /Volume<N>_Snapshot<N> that
-                // both makes the path unique and clearly indicates the source of the file. 
-                path << m_fileRecord.fullPath;
-            }
-        }
-        else
-        {
-            TskServices::Instance().getImgDB().getFileUniqueIdentifiers(m_fileRecord.fileId, fileSystemSectorOffset, unusedUint, unusedInt, unusedInt);
-        }
-        path << "/FsOffset-" << fileSystemSectorOffset << "/" << m_fileRecord.fullPath;
-    }
-
-    return path.str();
-}
-
-std::string TskFile::getHash(TskImgDB::HASH_TYPE hashType) const
-{
-    switch (hashType) {
-    case TskImgDB::MD5:
-        return m_fileRecord.md5;
-        break;
-    case TskImgDB::SHA1:
-        return m_fileRecord.sha1;
-        break;
-    case TskImgDB::SHA2_256:
-        return m_fileRecord.sha2_256;
-        break;
-    case TskImgDB::SHA2_512:
-        return m_fileRecord.sha2_512;
-        break;
-    };
-    return "";
-}
-
-// Set the file hash
-void TskFile::setHash(TskImgDB::HASH_TYPE hashType, const std::string hash)
-{
-    switch (hashType) {
-    case TskImgDB::MD5:
-        m_fileRecord.md5 = hash;
-        break;
-    case TskImgDB::SHA1:
-        m_fileRecord.sha1 = hash;
-        break;
-    case TskImgDB::SHA2_256:
-        m_fileRecord.sha2_256 = hash;
-        break;
-    case TskImgDB::SHA2_512:
-        m_fileRecord.sha2_512 = hash;
-        break;
-    };
-    if (TskServices::Instance().getImgDB().setHash(m_fileRecord.fileId, hashType, hash)) {
-        throw TskException("setHash failed.");
-    }
-}
-
-TskImgDB::KNOWN_STATUS TskFile::getKnownStatus() const
-{
-    return TskServices::Instance().getImgDB().getKnownStatus(getId());
-}
-
-void TskFile::setStatus(TskImgDB::FILE_STATUS status)
-{
-    m_fileRecord.status = status;
-    TskServices::Instance().getImgDB().updateFileStatus(getId(), status);
-}
-
-/**
- * Create a new artifact with the given type id
- * @param artifactTypeID type id
- * @returns the new artifact
- * @throws error if the artifact type does not exist
- */
-TskBlackboardArtifact TskFile::createArtifact(int artifactTypeID)
-{
-    return TskServices::Instance().getBlackboard().createArtifact(m_id, artifactTypeID);
-}
-
-/**
- * Create a new artifact with the given type
- * @param type artifact type
- * @returns the new artifact
- * @throws error if the artifact type does not exist
- */
-TskBlackboardArtifact TskFile::createArtifact(TSK_ARTIFACT_TYPE type)
-{
-    return TskServices::Instance().getBlackboard().createArtifact(m_id, type);
-}
-
-/**
- * Create a new artifact with the given type name
- * @param artifactTypeName artifact type name
- * @returns the new artifact
- * @throws error if the artifact type does not exist
- */
-TskBlackboardArtifact TskFile::createArtifact(string artifactTypeName)
-{
-    return TskServices::Instance().getBlackboard().createArtifact(m_id, artifactTypeName);
-}
-
-/**
- * Get all artifacts associated with this file with the given type name
- * @param artifactTypeName type name
- * @returns all matching artifacts will return an empty vector if there are no matches
- */
-vector<TskBlackboardArtifact> TskFile::getArtifacts(string artifactTypeName)
-{
-    return TskServices::Instance().getBlackboard().getArtifacts(m_id, artifactTypeName);
-}
-
-/**
- * Get all artifacts associated with this file with the given type id
- * @param artifactTypeID type id
- * @returns all matching artifacts will return an empty vector if there are no matches
- */
-vector<TskBlackboardArtifact> TskFile::getArtifacts(int artifactTypeID)
-{
-    return TskServices::Instance().getBlackboard().getArtifacts(m_id, artifactTypeID);
-}
-
-/**
- * Get all artifacts associated with this file with the given type
- * @param type artifact type
- * @returns all matching artifacts will return an empty vector if there are no matches
- */
-vector<TskBlackboardArtifact> TskFile::getArtifacts(TSK_ARTIFACT_TYPE type)
-{
-    return TskServices::Instance().getBlackboard().getArtifacts(m_id, type);
-}
-
-/**
- * Get all artifacts associated with this file
- * @returns all artifacts
- */
-vector<TskBlackboardArtifact> TskFile::getAllArtifacts()
-{
-    stringstream str;
-    str << "WHERE obj_id = " << m_id;
-    return TskServices::Instance().getBlackboard().getMatchingArtifacts(str.str());
-}
-
-/**
- * Get the general info artifact for this file
- * @returns the general info artifact or creates it if it has not already been made
- */
-TskBlackboardArtifact TskFile::getGenInfo()
-{
-    vector<TskBlackboardArtifact> artifacts;
-    artifacts = getArtifacts(TSK_GEN_INFO);
-
-    if(artifacts.size() == 0)
-        return createArtifact(TSK_GEN_INFO);
-    else
-        return artifacts[0];
-}
-
-/**
- * Add an attribute to the general info artifact for this file
- * @param attr attribute to be added
- */
-void TskFile::addGenInfoAttribute(TskBlackboardAttribute attr)
-{
-    getGenInfo().addAttribute(attr);
-}
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file TskFile.cpp
+ * Contains the implementation for the TskFile class.
+ */
+
+// System includes
+#include <sstream>
+
+// Framework includes
+#include "TskFile.h"
+#include "tsk/framework/services/TskServices.h"
+
+/**
+ * Delete the TskFile object.
+ */
+TskFile::~TskFile(void)
+{
+}
+
+
+void TskFile::initialize()
+{
+    TskImgDB * imgDB = &TskServices::Instance().getImgDB();
+    // getDB will throw exception if ImgDB has not been setup
+
+    if (imgDB != NULL) {
+        if (imgDB->getFileRecord(m_id, m_fileRecord)) {
+            throw TskException("TskFile::initialize: Error looking up file: " + m_id);
+        }
+    }
+}
+
+void TskFile::save()
+{
+    if (m_id == 0)
+    {
+        LOGERROR(L"TskFile::save - Attempt to save file with file id 0.");
+        throw TskException("Attempt to save file with file id 0.");
+    }
+
+    // If the file already exists we have nothing to do.
+    if (exists())
+        return;
+
+    // Make sure the file is open before saving.
+    open();
+
+    TskServices::Instance().getFileManager().saveFile(this);
+}
+
+/**
+ * What is this files id?
+ */
+uint64_t TskFile::getId() const
+{
+    return m_id;
+}
+
+TskImgDB::FILE_TYPES TskFile::getTypeId() const
+{
+    return m_fileRecord.typeId;
+}
+
+/**
+ * What is this files name?
+ */
+std::string TskFile::getName() const
+{
+    return m_fileRecord.name;
+}
+
+/**
+ * What is this files extension?
+ */
+std::string TskFile::getExtension() const
+{
+    size_t pos = m_fileRecord.name.find_last_of(".");
+    if (pos == std::string::npos)
+        return std::string("");
+    else
+        return m_fileRecord.name.substr(pos + 1);
+}
+
+/**
+ * What is this files parent file id?
+ */
+uint64_t TskFile::getParentFileId() const
+{
+    return m_fileRecord.parentFileId;
+}
+
+/**
+ * What is this files directory type?
+ */
+TSK_FS_NAME_TYPE_ENUM TskFile::getDirType() const
+{
+    return m_fileRecord.dirType;
+}
+/**
+ * What is this files metadata type?
+ */
+TSK_FS_META_TYPE_ENUM TskFile::getMetaType() const
+{
+    return m_fileRecord.metaType;
+}
+
+/**
+ * What are this files directory flags?
+ */
+TSK_FS_NAME_FLAG_ENUM TskFile::getDirFlags() const
+{
+    return m_fileRecord.dirFlags;
+}
+
+/**
+ * What are this files metadata flags?
+ */
+TSK_FS_META_FLAG_ENUM TskFile::getMetaFlags() const
+{
+    return m_fileRecord.metaFlags;
+}
+
+/**
+ * What is this files size?
+ */
+TSK_OFF_T TskFile::getSize() const
+{
+    return m_fileRecord.size;
+}
+
+/**
+ * What is this files change time?
+ */
+time_t TskFile::getCtime() const
+{
+    return m_fileRecord.ctime;
+}
+
+/**
+ * What is this files creation time?
+ */
+time_t TskFile::getCrtime() const
+{
+    return m_fileRecord.crtime;
+}
+
+/**
+ * What is this files access time?
+ */
+time_t TskFile::getAtime() const
+{
+    return m_fileRecord.atime;
+}
+
+/**
+ * What is this files modify time?
+ */
+time_t TskFile::getMtime() const
+{
+    return m_fileRecord.mtime;
+}
+
+/**
+ * What is this files mode?
+ */
+TSK_FS_META_MODE_ENUM TskFile::getMode() const
+{
+    return m_fileRecord.mode;
+}
+
+/**
+ * What is this files user id?
+ */
+TSK_UID_T TskFile::getUid() const
+{
+    return m_fileRecord.uid;
+}
+
+/**
+ * What is this files group id?
+ */
+TSK_GID_T TskFile::getGid() const
+{
+    return m_fileRecord.gid;
+}
+
+/**
+ * What is this files status?
+ */
+TskImgDB::FILE_STATUS TskFile::getStatus() const
+{
+    return m_fileRecord.status;
+}
+
+/*
+ * What is this files full path
+ */
+std::string TskFile::getFullPath() const
+{
+    return m_fileRecord.fullPath;
+}
+
+std::string TskFile::getUniquePath() const
+{
+    const uint64_t VOLUME_SHADOW_SNAPSHOT_FILE_PARENT_ID = 9223372036854775807;
+    
+    std::stringstream path;
+    
+    if (m_fileRecord.typeId == TskImgDB::IMGDB_FILES_TYPE_CARVED)
+    {
+        path << "/carved/" << m_fileRecord.fullPath;
+    }
+    else if (m_fileRecord.typeId == TskImgDB::IMGDB_FILES_TYPE_DERIVED)
+    {
+        if (m_fileRecord.parentFileId == VOLUME_SHADOW_SNAPSHOT_FILE_PARENT_ID)
+        {
+            // The full path will have an initial component of the form /Volume<N>_Snapshot<N> that
+            // both makes the path unique and clearly indicates the source of the file. 
+            path << m_fileRecord.fullPath;
+        }
+        else
+        {
+            uint64_t fileSystemSectorOffset = 0;
+            uint64_t unusedUint = 0;
+            int unusedInt = 0;
+
+            // To determine the file system offset for a derived file we have to
+            // find the top level parent it was derived from.
+            // The top level parent may be a file system or carved file or we may
+            // make it to the top of the hierarchy (e.g. for L01 or RAR input).
+            TskFileRecord fileRecord = m_fileRecord;
+            while (fileRecord.parentFileId != 0 && fileRecord.typeId == TskImgDB::IMGDB_FILES_TYPE_DERIVED)
+            {
+                TskServices::Instance().getImgDB().getFileRecord(fileRecord.parentFileId, fileRecord);
+            }
+
+            if (fileRecord.typeId == TskImgDB::IMGDB_FILES_TYPE_CARVED)
+            {
+                path << "/carved/" << m_fileRecord.fullPath;
+            }
+            else
+            {
+                TskServices::Instance().getImgDB().getFileUniqueIdentifiers(fileRecord.fileId, fileSystemSectorOffset, unusedUint, unusedInt, unusedInt);
+                path << "/FsOffset-" << fileSystemSectorOffset << "/" << m_fileRecord.fullPath;
+            }
+        }
+    }
+
+    return path.str();
+}
+
+std::string TskFile::getHash(TskImgDB::HASH_TYPE hashType) const
+{
+    switch (hashType) {
+    case TskImgDB::MD5:
+        return m_fileRecord.md5;
+        break;
+    case TskImgDB::SHA1:
+        return m_fileRecord.sha1;
+        break;
+    case TskImgDB::SHA2_256:
+        return m_fileRecord.sha2_256;
+        break;
+    case TskImgDB::SHA2_512:
+        return m_fileRecord.sha2_512;
+        break;
+    };
+    return "";
+}
+
+// Set the file hash
+void TskFile::setHash(TskImgDB::HASH_TYPE hashType, const std::string hash)
+{
+    switch (hashType) {
+    case TskImgDB::MD5:
+        m_fileRecord.md5 = hash;
+        break;
+    case TskImgDB::SHA1:
+        m_fileRecord.sha1 = hash;
+        break;
+    case TskImgDB::SHA2_256:
+        m_fileRecord.sha2_256 = hash;
+        break;
+    case TskImgDB::SHA2_512:
+        m_fileRecord.sha2_512 = hash;
+        break;
+    };
+    if (TskServices::Instance().getImgDB().setHash(m_fileRecord.fileId, hashType, hash)) {
+        throw TskException("setHash failed.");
+    }
+}
+
+TskImgDB::KNOWN_STATUS TskFile::getKnownStatus() const
+{
+    return TskServices::Instance().getImgDB().getKnownStatus(getId());
+}
+
+void TskFile::setStatus(TskImgDB::FILE_STATUS status)
+{
+    m_fileRecord.status = status;
+    TskServices::Instance().getImgDB().updateFileStatus(getId(), status);
+}
+
+/**
+ * Create a new artifact with the given type id
+ * @param artifactTypeID type id
+ * @returns the new artifact
+ * @throws error if the artifact type does not exist
+ */
+TskBlackboardArtifact TskFile::createArtifact(int artifactTypeID)
+{
+    return TskServices::Instance().getBlackboard().createArtifact(m_id, artifactTypeID);
+}
+
+/**
+ * Create a new artifact with the given type
+ * @param type artifact type
+ * @returns the new artifact
+ * @throws error if the artifact type does not exist
+ */
+TskBlackboardArtifact TskFile::createArtifact(TSK_ARTIFACT_TYPE type)
+{
+    return TskServices::Instance().getBlackboard().createArtifact(m_id, type);
+}
+
+/**
+ * Create a new artifact with the given type name
+ * @param artifactTypeName artifact type name
+ * @returns the new artifact
+ * @throws error if the artifact type does not exist
+ */
+TskBlackboardArtifact TskFile::createArtifact(string artifactTypeName)
+{
+    return TskServices::Instance().getBlackboard().createArtifact(m_id, artifactTypeName);
+}
+
+/**
+ * Get all artifacts associated with this file with the given type name
+ * @param artifactTypeName type name
+ * @returns all matching artifacts will return an empty vector if there are no matches
+ */
+vector<TskBlackboardArtifact> TskFile::getArtifacts(string artifactTypeName)
+{
+    return TskServices::Instance().getBlackboard().getArtifacts(m_id, artifactTypeName);
+}
+
+/**
+ * Get all artifacts associated with this file with the given type id
+ * @param artifactTypeID type id
+ * @returns all matching artifacts will return an empty vector if there are no matches
+ */
+vector<TskBlackboardArtifact> TskFile::getArtifacts(int artifactTypeID)
+{
+    return TskServices::Instance().getBlackboard().getArtifacts(m_id, artifactTypeID);
+}
+
+/**
+ * Get all artifacts associated with this file with the given type
+ * @param type artifact type
+ * @returns all matching artifacts will return an empty vector if there are no matches
+ */
+vector<TskBlackboardArtifact> TskFile::getArtifacts(TSK_ARTIFACT_TYPE type)
+{
+    return TskServices::Instance().getBlackboard().getArtifacts(m_id, type);
+}
+
+/**
+ * Get all artifacts associated with this file
+ * @returns all artifacts
+ */
+vector<TskBlackboardArtifact> TskFile::getAllArtifacts()
+{
+    stringstream str;
+    str << "WHERE obj_id = " << m_id;
+    return TskServices::Instance().getBlackboard().getMatchingArtifacts(str.str());
+}
+
+/**
+ * Get the general info artifact for this file
+ * @returns the general info artifact or creates it if it has not already been made
+ */
+TskBlackboardArtifact TskFile::getGenInfo()
+{
+    vector<TskBlackboardArtifact> artifacts;
+    artifacts = getArtifacts(TSK_GEN_INFO);
+
+    if(artifacts.size() == 0)
+        return createArtifact(TSK_GEN_INFO);
+    else
+        return artifacts[0];
+}
+
+/**
+ * Add an attribute to the general info artifact for this file
+ * @param attr attribute to be added
+ */
+void TskFile::addGenInfoAttribute(TskBlackboardAttribute attr)
+{
+    getGenInfo().addAttribute(attr);
+}
diff --git a/framework/tsk/framework/file/TskFile.h b/framework/tsk/framework/file/TskFile.h
index ed32f00..4416407 100755
--- a/framework/tsk/framework/file/TskFile.h
+++ b/framework/tsk/framework/file/TskFile.h
@@ -1,265 +1,265 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskFile.h
- * Contains the interface for the TskFile class.
- */
-
-#ifndef _TSK_FILE_H
-#define _TSK_FILE_H
-
-// System includes
-#include <string>
-#include <ios>
-
-// Framework includes
-#include "tsk/framework/services/TskImgDB.h"
-#include "tsk/framework/services/TskBlackboardArtifact.h"
-
-/**
- * An interface that is used to represent a file. This interface
- * is used during the analysis of a file and is typically created
- * based on data in TskImgDB, which was created by CarveExtract
- * or TskImageFile.  Different implementations of this class 
- * may retrieve file content and metadata in different ways.
- * TskFile objects are obtained from TskFileManager.
- */
-class TSK_FRAMEWORK_API TskFile
-{
-public:
-	virtual ~TskFile();
-
-    /** Returns the file id.
-     */
-    uint64_t getId() const;
-
-    /**
-     * Get the high-level type (file system, local, carved, etc.)
-     */
-    TskImgDB::FILE_TYPES getTypeId() const;
-
-    /** Get the name
-     */
-    std::string getName() const;
-
-    /** Get the extension
-    */
-    std::string getExtension() const;
-
-    /** Get the parent file id
-    */
-    uint64_t getParentFileId() const;
-
-    /** Get the directory type
-    */
-    TSK_FS_NAME_TYPE_ENUM getDirType() const;
-
-    /** Get the metadata flags
-    */
-    TSK_FS_META_TYPE_ENUM getMetaType() const;
-
-    /** Get the directory flags
-    */
-    TSK_FS_NAME_FLAG_ENUM getDirFlags() const;
-
-    /** Get the metadata flags
-    */
-    TSK_FS_META_FLAG_ENUM getMetaFlags() const;
-
-    /** Get the file size
-    */
-    TSK_OFF_T getSize() const;
-
-    /** Get the change time
-     */
-    time_t getCtime() const;
-
-    /** Get the creation time
-    */
-    time_t getCrtime() const;
-
-    /** Get the last access time
-    */
-    time_t getAtime() const;
-
-    /** Get the modify time
-    */
-    time_t getMtime() const;
-
-    /** Get the mode
-    */
-    TSK_FS_META_MODE_ENUM  getMode() const;
-
-    /** Get the user id
-    */
-    TSK_UID_T getUid() const;
-
-    /** Get the group id
-    */
-    TSK_GID_T getGid() const;
-
-    /**
-     * Get the path of the file in the disk image.  This
-     * will not include the file name and will not include 
-     * any information about the file system or volume that
-     * it was found in (if there were multiple file systems
-     * in the image. 
-     * @returns Original path of the file.
-     */
-    std::string getFullPath() const;
-    
-    /**
-     * Get the path of the file in the disk image.  This
-     * will not include the file name but will include 
-     * either information about the file system or volume that
-     * it was found in or an indicator that the file was produced
-     * by carving. 
-     * @returns Original path of the file.
-     */
-    std::string getUniquePath() const;
-
-    /**
-     * Get the fully qualified path of where this file should
-     * be locally stored.  It does not check if the file is 
-     * locally stored.   Use exists() for that.
-     */
-    virtual std::string getPath() const = 0;
-
-    /** 
-     * Get the pre-calculated hash value of the specified type.
-     * @param hashType Type of hash to lookup
-     * @returns String of hash value or empty string if the value
-     * has not been calculated. 
-     */
-    std::string getHash(TskImgDB::HASH_TYPE hashType) const;
-
-    /**
-     * Sets the file's hash value in the database.  note that hash values
-     * are not stored in the blackboard. 
-     * @param hashType Type of hash value
-     * @param hash String value of hash.
-     */
-    void setHash(TskImgDB::HASH_TYPE hashType, const std::string hash);
-    
-    /**
-     * Return the known status of the file
-     * @returns KNOWN_STATUS or -1 on error
-     */
-    TskImgDB::KNOWN_STATUS getKnownStatus() const;
-
-    /**
-     * Tests if a local copy of the file exists at the default location. 
-     * @return True if a file exists, false otherwise
-     */ 
-    virtual bool exists() const = 0;
-
-    /**
-     * @return True if this is a directory, false otherwise
-     */ 
-    virtual bool isDirectory() const = 0;
-
-    /**
-     * @return True if this is a "virtual" file, false otherwise
-     */ 
-    virtual bool isVirtual() const = 0;
-
-    /** 
-     * Open the file. Must be called before reading. Implementations must
-     * support concept of open() being called multiple times even if file 
-     * is already open. 
-     * @throws TskFileException on error
-     */
-    virtual void open() = 0;
-
-    /**
-     * Closes the open file.
-     */
-    virtual void close() = 0;
-
-    /**
-     * Save the file to the default location. This is a simple wrapper
-     * around TskFileManager::saveFile.
-     * @throws TskException if file id is zero along with exceptions 
-     * thrown by TskFileManager::saveFile.
-     */
-    virtual void save();
-
-    /**
-     * Get the current byte offset within the file.
-     * @returns Current byte offset.
-     * @throws TskFileException if file is not open.
-     */
-    virtual TSK_OFF_T tell() const = 0;
-
-    /**
-     * Set the byte offset within the file. If the second parameter is not
-     * supplied the offset will be set relative to the beginning of the file.
-     * @param off Number off bytes to offset from origin.
-     * @param origin The point from which the given offset is relative to. Defaults
-     * to beginning of file. If origin is std::ios::end the offset must be a 
-     * negative number.
-     * @returns The absolute file offset resulting from the repositioning.
-     * @throws TskFileException if file is not open or if you attempt to seek
-     * to an invalid offset.
-     */
-    virtual TSK_OFF_T seek(const TSK_OFF_T off, std::ios::seekdir origin = std::ios::beg) = 0;
-
-    /**
-     * Read file content into a buffer.  Reads from end of last read.
-     * @param buf Buffer into which file content will be placed.
-     * Must be at least "count" bytes in size.
-     * @param count The number of bytes to read from the file.
-     * @return The number of bytes read or -1 on error.
-     */
-    virtual ssize_t read(char * buf, const size_t count) = 0;
-
-    /**
-     * Set the file status (where it is in its analysis life cycle)
-     */
-    void setStatus(TskImgDB::FILE_STATUS status);
-
-    /** Get the analysis status of the file (where it is in the analysis life cycle)
-     */
-    TskImgDB::FILE_STATUS getStatus() const;
-
-    //Blackboard methods
-    virtual TskBlackboardArtifact createArtifact(int artifactTypeID);
-    virtual TskBlackboardArtifact createArtifact(TSK_ARTIFACT_TYPE type);
-    virtual TskBlackboardArtifact createArtifact(string artifactTypeName);
-    virtual vector<TskBlackboardArtifact> getArtifacts(string artifactTypeName);
-    virtual vector<TskBlackboardArtifact> getArtifacts(int artifactTypeID);
-    virtual vector<TskBlackboardArtifact> getArtifacts(TSK_ARTIFACT_TYPE type);
-    virtual vector<TskBlackboardArtifact> getAllArtifacts();
-    virtual TskBlackboardArtifact getGenInfo();
-    virtual void addGenInfoAttribute(TskBlackboardAttribute attr);
-
-
-protected:
-    // File id.
-    uint64_t m_id;
-
-    // Our current offset into the file
-    TSK_OFF_T m_offset;
-
-    // Is the file open (used for both on disk and image files)
-    bool m_isOpen;
-
-    // The database file record.
-    TskFileRecord m_fileRecord;
-
-    /**
-     * Loads the raw file data from the database.
-     * @throws TskException on error
-     */
-    void initialize();
-};
-
-#endif
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file TskFile.h
+ * Contains the interface for the TskFile class.
+ */
+
+#ifndef _TSK_FILE_H
+#define _TSK_FILE_H
+
+// System includes
+#include <string>
+#include <ios>
+
+// Framework includes
+#include "tsk/framework/services/TskImgDB.h"
+#include "tsk/framework/services/TskBlackboardArtifact.h"
+
+/**
+ * An interface that is used to represent a file. This interface
+ * is used during the analysis of a file and is typically created
+ * based on data in TskImgDB, which was created by CarveExtract
+ * or TskImageFile.  Different implementations of this class 
+ * may retrieve file content and metadata in different ways.
+ * TskFile objects are obtained from TskFileManager.
+ */
+class TSK_FRAMEWORK_API TskFile
+{
+public:
+	virtual ~TskFile();
+
+    /** Returns the file id.
+     */
+    uint64_t getId() const;
+
+    /**
+     * Get the high-level type (file system, local, carved, etc.)
+     */
+    TskImgDB::FILE_TYPES getTypeId() const;
+
+    /** Get the name
+     */
+    std::string getName() const;
+
+    /** Get the extension
+    */
+    std::string getExtension() const;
+
+    /** Get the parent file id
+    */
+    uint64_t getParentFileId() const;
+
+    /** Get the directory type
+    */
+    TSK_FS_NAME_TYPE_ENUM getDirType() const;
+
+    /** Get the metadata flags
+    */
+    TSK_FS_META_TYPE_ENUM getMetaType() const;
+
+    /** Get the directory flags
+    */
+    TSK_FS_NAME_FLAG_ENUM getDirFlags() const;
+
+    /** Get the metadata flags
+    */
+    TSK_FS_META_FLAG_ENUM getMetaFlags() const;
+
+    /** Get the file size
+    */
+    TSK_OFF_T getSize() const;
+
+    /** Get the change time
+     */
+    time_t getCtime() const;
+
+    /** Get the creation time
+    */
+    time_t getCrtime() const;
+
+    /** Get the last access time
+    */
+    time_t getAtime() const;
+
+    /** Get the modify time
+    */
+    time_t getMtime() const;
+
+    /** Get the mode
+    */
+    TSK_FS_META_MODE_ENUM  getMode() const;
+
+    /** Get the user id
+    */
+    TSK_UID_T getUid() const;
+
+    /** Get the group id
+    */
+    TSK_GID_T getGid() const;
+
+    /**
+     * Get the path of the file in the disk image.  This
+     * will not include the file name and will not include 
+     * any information about the file system or volume that
+     * it was found in (if there were multiple file systems
+     * in the image. 
+     * @returns Original path of the file.
+     */
+    std::string getFullPath() const;
+    
+    /**
+     * Get the path of the file in the disk image.  This
+     * will not include the file name but will include 
+     * either information about the file system or volume that
+     * it was found in or an indicator that the file was produced
+     * by carving. 
+     * @returns Original path of the file.
+     */
+    std::string getUniquePath() const;
+
+    /**
+     * Get the fully qualified path of where this file should
+     * be locally stored.  It does not check if the file is 
+     * locally stored.   Use exists() for that.
+     */
+    virtual std::string getPath() const = 0;
+
+    /** 
+     * Get the pre-calculated hash value of the specified type.
+     * @param hashType Type of hash to lookup
+     * @returns String of hash value or empty string if the value
+     * has not been calculated. 
+     */
+    std::string getHash(TskImgDB::HASH_TYPE hashType) const;
+
+    /**
+     * Sets the file's hash value in the database.  note that hash values
+     * are not stored in the blackboard. 
+     * @param hashType Type of hash value
+     * @param hash String value of hash.
+     */
+    void setHash(TskImgDB::HASH_TYPE hashType, const std::string hash);
+    
+    /**
+     * Return the known status of the file
+     * @returns KNOWN_STATUS or -1 on error
+     */
+    TskImgDB::KNOWN_STATUS getKnownStatus() const;
+
+    /**
+     * Tests if a local copy of the file exists at the default location. 
+     * @return True if a file exists, false otherwise
+     */ 
+    virtual bool exists() const = 0;
+
+    /**
+     * @return True if this is a directory, false otherwise
+     */ 
+    virtual bool isDirectory() const = 0;
+
+    /**
+     * @return True if this is a "virtual" file, false otherwise
+     */ 
+    virtual bool isVirtual() const = 0;
+
+    /** 
+     * Open the file. Must be called before reading. Implementations must
+     * support concept of open() being called multiple times even if file 
+     * is already open. 
+     * @throws TskFileException on error
+     */
+    virtual void open() = 0;
+
+    /**
+     * Closes the open file.
+     */
+    virtual void close() = 0;
+
+    /**
+     * Save the file to the default location. This is a simple wrapper
+     * around TskFileManager::saveFile.
+     * @throws TskException if file id is zero along with exceptions 
+     * thrown by TskFileManager::saveFile.
+     */
+    virtual void save();
+
+    /**
+     * Get the current byte offset within the file.
+     * @returns Current byte offset.
+     * @throws TskFileException if file is not open.
+     */
+    virtual TSK_OFF_T tell() const = 0;
+
+    /**
+     * Set the byte offset within the file. If the second parameter is not
+     * supplied the offset will be set relative to the beginning of the file.
+     * @param off Number off bytes to offset from origin.
+     * @param origin The point from which the given offset is relative to. Defaults
+     * to beginning of file. If origin is std::ios::end the offset must be a 
+     * negative number.
+     * @returns The absolute file offset resulting from the repositioning.
+     * @throws TskFileException if file is not open or if you attempt to seek
+     * to an invalid offset.
+     */
+    virtual TSK_OFF_T seek(const TSK_OFF_T off, std::ios::seekdir origin = std::ios::beg) = 0;
+
+    /**
+     * Read file content into a buffer.  Reads from end of last read.
+     * @param buf Buffer into which file content will be placed.
+     * Must be at least "count" bytes in size.
+     * @param count The number of bytes to read from the file.
+     * @return The number of bytes read or -1 on error.
+     */
+    virtual ssize_t read(char * buf, const size_t count) = 0;
+
+    /**
+     * Set the file status (where it is in its analysis life cycle)
+     */
+    void setStatus(TskImgDB::FILE_STATUS status);
+
+    /** Get the analysis status of the file (where it is in the analysis life cycle)
+     */
+    TskImgDB::FILE_STATUS getStatus() const;
+
+    //Blackboard methods
+    virtual TskBlackboardArtifact createArtifact(int artifactTypeID);
+    virtual TskBlackboardArtifact createArtifact(TSK_ARTIFACT_TYPE type);
+    virtual TskBlackboardArtifact createArtifact(string artifactTypeName);
+    virtual vector<TskBlackboardArtifact> getArtifacts(string artifactTypeName);
+    virtual vector<TskBlackboardArtifact> getArtifacts(int artifactTypeID);
+    virtual vector<TskBlackboardArtifact> getArtifacts(TSK_ARTIFACT_TYPE type);
+    virtual vector<TskBlackboardArtifact> getAllArtifacts();
+    virtual TskBlackboardArtifact getGenInfo();
+    virtual void addGenInfoAttribute(TskBlackboardAttribute attr);
+
+
+protected:
+    // File id.
+    uint64_t m_id;
+
+    // Our current offset into the file
+    TSK_OFF_T m_offset;
+
+    // Is the file open (used for both on disk and image files)
+    bool m_isOpen;
+
+    // The database file record.
+    TskFileRecord m_fileRecord;
+
+    /**
+     * Loads the raw file data from the database.
+     * @throws TskException on error
+     */
+    void initialize();
+};
+
+#endif
diff --git a/framework/tsk/framework/file/TskFileManager.h b/framework/tsk/framework/file/TskFileManager.h
index 8d81665..fb8c7df 100755
--- a/framework/tsk/framework/file/TskFileManager.h
+++ b/framework/tsk/framework/file/TskFileManager.h
@@ -1,243 +1,243 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskFileManager.h
- * Contains the interface for the TskFileManager class.
- */
-
-#ifndef _TSK_FILEMANAGER_H
-#define _TSK_FILEMANAGER_H
-
-#include <memory>
-#include "tsk/framework/framework_i.h"
-#include "TskFile.h"
-
-
-/**
- * Responsible for managing TskFile objects in the system.
- */
-class TSK_FRAMEWORK_API TskFileManager
-{
-public:
-    typedef TskFile* FilePtr;
-    typedef std::vector< FilePtr > FilePtrList;
-
-    /**
-        This nested class should be used to hold a FilePtrList object returned
-        by methods such as findFilesByName() so that the file objects will be 
-        automatically freed. Example:
-        @code
-        AutoFilePtrList flist(fileManager.findFilesByName(fileName));
-        for (FilePtrList::iterator i = flist.begin(); i != flist.end(); ++i)
-        { ... //do stuff }
-        // Don't worry about delete'ing each file obj--flist will take care of
-        // that when it goes out of scope.
-        @endcode
-    */
-    class AutoFilePtrList
-    {
-    public:
-        AutoFilePtrList(FilePtrList v) : m_Files(v) {}
-        ~AutoFilePtrList()
-        {
-            for (FilePtrList::iterator it = m_Files.begin(); it != m_Files.end(); ++it)
-            {
-                delete *it;
-            }
-        }
-        FilePtrList::iterator begin() { return m_Files.begin(); }
-        FilePtrList::iterator end()   { return m_Files.end(); }
-        FilePtrList::size_type size() { return m_Files.size(); }
-    private:
-        AutoFilePtrList(const AutoFilePtrList&);
-        AutoFilePtrList& operator=(const AutoFilePtrList&);
-
-        TskFileManager::FilePtrList m_Files;
-    };
-
-    /**
-     * Return a TskFile object for a given file ID.
-     * @param fileId ID of file to return object of.
-     * @returns Pointer to file object. Caller must free it.
-     * @throws TskException in case of error.
-     */
-    virtual TskFile * getFile(const uint64_t fileId) = 0;
-
-    /**
-     * Return a list of TskFile objects mapped to the given list of file ids.
-     * @param fileIds List of fileId IDs.
-     * @returns List of pointers to file objects.
-     */
-    virtual FilePtrList getFiles(const std::vector<uint64_t>& fileIds) = 0;
-
-    /**
-     * Return a list of any TskFile objects matching the given filename
-     * @param name The file name.
-     * @param fsFileType Optional file meta type. Will not filter on meta_type if this is omitted.
-     * @returns List of pointers to file objects. Caller must use AutoFilePtrList or manually free them.
-     */
-    virtual FilePtrList findFilesByName(const std::string& name, const TSK_FS_META_TYPE_ENUM fsFileType = TSK_FS_META_TYPE_UNDEF) = 0;
-    
-    /**
-     * Return a list of any TskFile objects matching the given filename extension
-     * @param extensions List of file name extension strings.
-     * @returns List of pointers to file objects.  Caller must use AutoFilePtrList or manually free them.
-     */
-    virtual FilePtrList findFilesByExtension(const std::vector<std::string>& extensions) = 0;
-    
-    /**
-     * Return a list of any TskFile objects that are children of the given file id.
-     * @param parentFileId ID of parent file.
-     * @returns List of pointers to file objects.  Caller must use AutoFilePtrList or manually free them.
-     */
-    virtual FilePtrList findFilesByParent(const uint64_t parentFileId) = 0;
-    
-    /**
-     * Return a list of any TskFile objects that match the given file meta type.
-     * @param fsFileType File meta type.
-     * @returns List of pointers to file objects. Caller must use AutoFilePtrList or manually free them.
-     */
-    virtual FilePtrList findFilesByFsFileType(TSK_FS_META_TYPE_ENUM fsFileType) = 0;
-
-    /**
-     * Return a list of any TskFile objects that match the given file and path patterns.
-     * @param namePattern File name pattern. Can include "%" wildcards.
-     * @param pathPattern File path pattern. Can include "%" wildcards.
-     * @returns List of pointers to file objects. Caller must use AutoFilePtrList or manually free them.
-     */
-    virtual FilePtrList findFilesByPattern(const std::string& namePattern, const std::string& pathPattern) = 0;
-
-    /** 
-     * Return the fully qualified path to where the local instance of the file with the given ID
-     * should exist.  This does not validate that the ID is for a file and does
-     * not validate that the file actually exists. 
-     * @param fileId Id of the file.
-     * @returns Path to where local file should exist. 
-     */
-    virtual std::wstring getPath(const uint64_t fileId) = 0;
-
-    /**
-     * Save the file to the default location. 
-     * @param fileToSave File object of the file to save.
-     * @throws various exceptions on errors
-     */
-    virtual void saveFile(TskFile* fileToSave) = 0;
-
-    /**
-     * Save the file to the default location. 
-     * @param fileId ID of the file to save.
-     * @throws various exceptions on errors
-     */
-    virtual void saveFile(const uint64_t fileId)
-    {
-        saveFile(getFile(fileId));
-    }
-
-    /**
-     * Copy the file to the given fully qualifed file path. 
-     * Directories along the path will be created if they do not exist.
-     * If the destination file exists it will be replaced.
-     * @param fileToSave The file to save.
-     * @param filePath The path to save to, including the file name. 
-     * @throws various exceptions on errors
-     */
-    virtual void copyFile(TskFile* fileToSave, const std::wstring& filePath) = 0;
-
-    /**
-     * Copy the file to the given fully qualifed file path. 
-     * Directories along the path will be created if they do not exist.
-     * If the destination file exists it will be replaced.
-     * @param fileId ID of the file to save.
-     * @param filePath The path to save to, including the file name. 
-     * @throws various exceptions on errors
-     */
-    virtual void copyFile(const uint64_t fileId, const std::wstring& filePath)
-    {
-        copyFile(std::auto_ptr<TskFile>(getFile(fileId)).get(), filePath);
-    }
-
-    /**
-     * Copy the contents of a directory to the given fully qualifed file path. 
-     * Directories along the path will be created if they do not exist.
-     * If the destination directory exists it will be replaced.
-	 * Defaults to a non-recursive copy.
-     * @param directoryToCopy The TskFile object representing the directory to copy.
-     * @param destinationPath The path to save directory contents to, including the directory name.
-	 * @param bRecurse Whether to recursively copy directory contents.
-     * @throws various exceptions on errors
-     */
-    virtual void copyDirectory(TskFile* directoryToCopy, const std::wstring& destinationPath, const bool bRecurse = false) = 0;
-
-    /**
-     * Copy the contents of a directory to the given fully qualifed file path. 
-     * Directories along the path will be created if they do not exist.
-     * If the destination directory exists it will be replaced.
-	 * Defaults to a non-recursive copy.
-     * @param directoryIdToCopy The id representing the directory to copy.
-     * @param destinationPath The path to save directory contents to, including the directory name. 
-	 * @param bRecurse Whether to recursively copy directory contents.
-     * @throws various exceptions on errors
-     */
-    virtual void copyDirectory(uint64_t directoryIdToCopy, const std::wstring& destinationPath, const bool bRecurse = false)
-    {
-        copyDirectory(std::auto_ptr<TskFile>(getFile(directoryIdToCopy)).get(), destinationPath, bRecurse);
-    }
-
-    /**
-     * Add a file to the system using the given file id and input stream.
-     * This method saves a local copy of the content contained in the input stream.
-     * @param fileId ID of the new file.
-     * @param istr Input stream containing the file content to save.
-     * @throws TskFileException if a file with the given fileId already exists or
-     * if an error is encountered while saving the input stream.
-     */
-    virtual void addFile(const uint64_t fileId, std::istream& istr) = 0;
-
-    /**
-     * Add a file to the system using the given file id and path.
-     * This method saves a local copy of the file given in the path.
-     * @param fileId ID of the new file.
-     * @param filePath The path of the file to save.
-     * @throws TskFileException if a file with the given fileId already exists,
-     * the file specified in filePath does not exist or an error is encountered 
-     * while saving the file.
-     */
-    virtual void addFile(const uint64_t fileId, std::wstring& filePath) = 0;
-
-    /**
-     * Delete the local copy of a file.
-     * @param fileToDelete Object of file to delete local copy of
-     * @throws various exceptions on errors
-     */
-    virtual void deleteFile(TskFile* fileToDelete) = 0;
-
-    /**
-     * Delete the local copy of a file.
-     * @param fileId ID of file to delete local copy of
-     * @throws various exceptions on errors
-     */
-    virtual void deleteFile(const uint64_t fileId)
-    {
-        deleteFile(std::auto_ptr<TskFile>(getFile(fileId)).get());
-    }
-
-protected:
-    /// Default Constructor
-    TskFileManager() {};
-
-    /// Copy Constructor
-    TskFileManager(TskFileManager const&) {};
-
-    /// Destructor
-    virtual ~TskFileManager() {};
-};
-
-#endif
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file TskFileManager.h
+ * Contains the interface for the TskFileManager class.
+ */
+
+#ifndef _TSK_FILEMANAGER_H
+#define _TSK_FILEMANAGER_H
+
+#include <memory>
+#include "tsk/framework/framework_i.h"
+#include "TskFile.h"
+
+
+/**
+ * Responsible for managing TskFile objects in the system.
+ */
+class TSK_FRAMEWORK_API TskFileManager
+{
+public:
+    typedef TskFile* FilePtr;
+    typedef std::vector< FilePtr > FilePtrList;
+
+    /**
+        This nested class should be used to hold a FilePtrList object returned
+        by methods such as findFilesByName() so that the file objects will be 
+        automatically freed. Example:
+        @code
+        AutoFilePtrList flist(fileManager.findFilesByName(fileName));
+        for (FilePtrList::iterator i = flist.begin(); i != flist.end(); ++i)
+        { ... //do stuff }
+        // Don't worry about delete'ing each file obj--flist will take care of
+        // that when it goes out of scope.
+        @endcode
+    */
+    class AutoFilePtrList
+    {
+    public:
+        AutoFilePtrList(FilePtrList v) : m_Files(v) {}
+        ~AutoFilePtrList()
+        {
+            for (FilePtrList::iterator it = m_Files.begin(); it != m_Files.end(); ++it)
+            {
+                delete *it;
+            }
+        }
+        FilePtrList::iterator begin() { return m_Files.begin(); }
+        FilePtrList::iterator end()   { return m_Files.end(); }
+        FilePtrList::size_type size() { return m_Files.size(); }
+    private:
+        AutoFilePtrList(const AutoFilePtrList&);
+        AutoFilePtrList& operator=(const AutoFilePtrList&);
+
+        TskFileManager::FilePtrList m_Files;
+    };
+
+    /**
+     * Return a TskFile object for a given file ID.
+     * @param fileId ID of file to return object of.
+     * @returns Pointer to file object. Caller must free it.
+     * @throws TskException in case of error.
+     */
+    virtual TskFile * getFile(const uint64_t fileId) = 0;
+
+    /**
+     * Return a list of TskFile objects mapped to the given list of file ids.
+     * @param fileIds List of fileId IDs.
+     * @returns List of pointers to file objects.
+     */
+    virtual FilePtrList getFiles(const std::vector<uint64_t>& fileIds) = 0;
+
+    /**
+     * Return a list of any TskFile objects matching the given filename
+     * @param name The file name.
+     * @param fsFileType Optional file meta type. Will not filter on meta_type if this is omitted.
+     * @returns List of pointers to file objects. Caller must use AutoFilePtrList or manually free them.
+     */
+    virtual FilePtrList findFilesByName(const std::string& name, const TSK_FS_META_TYPE_ENUM fsFileType = TSK_FS_META_TYPE_UNDEF) = 0;
+    
+    /**
+     * Return a list of any TskFile objects matching the given filename extension
+     * @param extensions List of file name extension strings.
+     * @returns List of pointers to file objects.  Caller must use AutoFilePtrList or manually free them.
+     */
+    virtual FilePtrList findFilesByExtension(const std::vector<std::string>& extensions) = 0;
+    
+    /**
+     * Return a list of any TskFile objects that are children of the given file id.
+     * @param parentFileId ID of parent file.
+     * @returns List of pointers to file objects.  Caller must use AutoFilePtrList or manually free them.
+     */
+    virtual FilePtrList findFilesByParent(const uint64_t parentFileId) = 0;
+    
+    /**
+     * Return a list of any TskFile objects that match the given file meta type.
+     * @param fsFileType File meta type.
+     * @returns List of pointers to file objects. Caller must use AutoFilePtrList or manually free them.
+     */
+    virtual FilePtrList findFilesByFsFileType(TSK_FS_META_TYPE_ENUM fsFileType) = 0;
+
+    /**
+     * Return a list of any TskFile objects that match the given file and path patterns.
+     * @param namePattern File name pattern. Can include "%" wildcards.
+     * @param pathPattern File path pattern. Can include "%" wildcards.
+     * @returns List of pointers to file objects. Caller must use AutoFilePtrList or manually free them.
+     */
+    virtual FilePtrList findFilesByPattern(const std::string& namePattern, const std::string& pathPattern) = 0;
+
+    /** 
+     * Return the fully qualified path to where the local instance of the file with the given ID
+     * should exist.  This does not validate that the ID is for a file and does
+     * not validate that the file actually exists. 
+     * @param fileId Id of the file.
+     * @returns Path to where local file should exist. 
+     */
+    virtual std::wstring getPath(const uint64_t fileId) = 0;
+
+    /**
+     * Save the file to the default location. 
+     * @param fileToSave File object of the file to save.
+     * @throws various exceptions on errors
+     */
+    virtual void saveFile(TskFile* fileToSave) = 0;
+
+    /**
+     * Save the file to the default location. 
+     * @param fileId ID of the file to save.
+     * @throws various exceptions on errors
+     */
+    virtual void saveFile(const uint64_t fileId)
+    {
+        saveFile(getFile(fileId));
+    }
+
+    /**
+     * Copy the file to the given fully qualifed file path. 
+     * Directories along the path will be created if they do not exist.
+     * If the destination file exists it will be replaced.
+     * @param fileToSave The file to save.
+     * @param filePath The path to save to, including the file name. 
+     * @throws various exceptions on errors
+     */
+    virtual void copyFile(TskFile* fileToSave, const std::wstring& filePath) = 0;
+
+    /**
+     * Copy the file to the given fully qualifed file path. 
+     * Directories along the path will be created if they do not exist.
+     * If the destination file exists it will be replaced.
+     * @param fileId ID of the file to save.
+     * @param filePath The path to save to, including the file name. 
+     * @throws various exceptions on errors
+     */
+    virtual void copyFile(const uint64_t fileId, const std::wstring& filePath)
+    {
+        copyFile(std::auto_ptr<TskFile>(getFile(fileId)).get(), filePath);
+    }
+
+    /**
+     * Copy the contents of a directory to the given fully qualifed file path. 
+     * Directories along the path will be created if they do not exist.
+     * If the destination directory exists it will be replaced.
+	 * Defaults to a non-recursive copy.
+     * @param directoryToCopy The TskFile object representing the directory to copy.
+     * @param destinationPath The path to save directory contents to, including the directory name.
+	 * @param bRecurse Whether to recursively copy directory contents.
+     * @throws various exceptions on errors
+     */
+    virtual void copyDirectory(TskFile* directoryToCopy, const std::wstring& destinationPath, const bool bRecurse = false) = 0;
+
+    /**
+     * Copy the contents of a directory to the given fully qualifed file path. 
+     * Directories along the path will be created if they do not exist.
+     * If the destination directory exists it will be replaced.
+	 * Defaults to a non-recursive copy.
+     * @param directoryIdToCopy The id representing the directory to copy.
+     * @param destinationPath The path to save directory contents to, including the directory name. 
+	 * @param bRecurse Whether to recursively copy directory contents.
+     * @throws various exceptions on errors
+     */
+    virtual void copyDirectory(uint64_t directoryIdToCopy, const std::wstring& destinationPath, const bool bRecurse = false)
+    {
+        copyDirectory(std::auto_ptr<TskFile>(getFile(directoryIdToCopy)).get(), destinationPath, bRecurse);
+    }
+
+    /**
+     * Add a file to the system using the given file id and input stream.
+     * This method saves a local copy of the content contained in the input stream.
+     * @param fileId ID of the new file.
+     * @param istr Input stream containing the file content to save.
+     * @throws TskFileException if a file with the given fileId already exists or
+     * if an error is encountered while saving the input stream.
+     */
+    virtual void addFile(const uint64_t fileId, std::istream& istr) = 0;
+
+    /**
+     * Add a file to the system using the given file id and path.
+     * This method saves a local copy of the file given in the path.
+     * @param fileId ID of the new file.
+     * @param filePath The path of the file to save.
+     * @throws TskFileException if a file with the given fileId already exists,
+     * the file specified in filePath does not exist or an error is encountered 
+     * while saving the file.
+     */
+    virtual void addFile(const uint64_t fileId, std::wstring& filePath) = 0;
+
+    /**
+     * Delete the local copy of a file.
+     * @param fileToDelete Object of file to delete local copy of
+     * @throws various exceptions on errors
+     */
+    virtual void deleteFile(TskFile* fileToDelete) = 0;
+
+    /**
+     * Delete the local copy of a file.
+     * @param fileId ID of file to delete local copy of
+     * @throws various exceptions on errors
+     */
+    virtual void deleteFile(const uint64_t fileId)
+    {
+        deleteFile(std::auto_ptr<TskFile>(getFile(fileId)).get());
+    }
+
+protected:
+    /// Default Constructor
+    TskFileManager() {};
+
+    /// Copy Constructor
+    TskFileManager(TskFileManager const&) {};
+
+    /// Destructor
+    virtual ~TskFileManager() {};
+};
+
+#endif
diff --git a/framework/tsk/framework/file/TskFileManagerImpl.cpp b/framework/tsk/framework/file/TskFileManagerImpl.cpp
index d850612..a893cbf 100755
--- a/framework/tsk/framework/file/TskFileManagerImpl.cpp
+++ b/framework/tsk/framework/file/TskFileManagerImpl.cpp
@@ -1,482 +1,482 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskFileManagerImpl.cpp
- * Default implementation of the TskFileManager class.
- */
-
-#include <sstream>
-#include <cstring>
-
-// Framework includes
-#include "TskFileManagerImpl.h"
-#include "TskFileTsk.h"
-#include "tsk/framework/services/TskSystemProperties.h"
-#include "tsk/framework/services/TskServices.h"
-#include "tsk/framework/utilities/TskException.h"
-#include "tsk/framework/utilities/TskUtilities.h"
-
-// Poco includes
-#include "Poco/Exception.h"
-#include "Poco/Path.h"
-#include "Poco/FileStream.h"
-#include "Poco/StreamCopier.h"
-#include "Poco/NumberFormatter.h"
-
-// C/C++ standard library includes
-#include <cassert>
-#include <sstream>
-#include <memory>
-
-TskFileManagerImpl * TskFileManagerImpl::m_pInstance = NULL;
-
-const int TskFileManagerImpl::FILES_PER_DIR = 1000;
-const int TskFileManagerImpl::FILE_BUFFER_SIZE = 8192;
-const std::string TskFileManagerImpl::FILES_DIRECTORY = "Files";
-
-TskFileManagerImpl& TskFileManagerImpl::instance()
-{
-    if (!m_pInstance)
-    {
-        m_pInstance = new TskFileManagerImpl();
-        m_pInstance->initialize();
-    }
-
-    return *m_pInstance;
-}
-
-void TskFileManagerImpl::initialize()
-{
-    try
-    {
-        std::string storagePath = GetSystemProperty(TskSystemProperties::SYSTEM_OUT_DIR);
-        m_storageDir = new Poco::File(storagePath + Poco::Path::separator() + FILES_DIRECTORY);
-
-        // Create the directory if it does not exist.
-        try {
-            m_storageDir->createDirectory();
-        } catch (Poco::FileExistsException &) {
-            ; // Ignore. This can happen when another process is creating the same directory.
-        }
-    }
-    catch (Poco::Exception& ex)
-    {
-        // Log a message
-        std::wstringstream errorMsg;
-        errorMsg << L"TskFileManagerImpl::initialize - File manager initialization failed with the following message: " 
-            << ex.message().c_str() << std::endl;
-        LOGERROR(errorMsg.str());
-        
-        // Throw a framework specific exception
-        throw TskFileException(ex.message());
-    }
-}
-
-TskFile * TskFileManagerImpl::getFile(const uint64_t fileId)
-{
-    /* If we were to ever have different subclasses of TskFile
-     * that differentiate file types, this is where the logic
-     * should go to create the correct version. 
-     */
-    return new TskFileTsk(fileId);
-}
-
-TskFileManager::FilePtrList TskFileManagerImpl::getFiles(const std::vector<uint64_t>& fileIds)
-{
-	TskFileManager::FilePtrList ret;
-    for (std::vector<uint64_t>::const_iterator it = fileIds.begin(); it != fileIds.end(); ++it)
-    {
-        ret.push_back(TskFileManager::FilePtr(getFile(*it)));
-    }
-
-	return ret;
-}
-
-TskFileManager::FilePtrList TskFileManagerImpl::findFilesByName(const std::string& name, const TSK_FS_META_TYPE_ENUM fsFileType /*= TSK_FS_META_TYPE_UNDEF*/)
-{
-    // Construct SQL condition
-    std::stringstream condition;
-    condition << "WHERE UPPER(files.name) = '" << name << "'";
-    if (fsFileType != TSK_FS_META_TYPE_UNDEF)
-    {
-        condition << " AND files.meta_type = " << static_cast<int>(fsFileType);
-    }
-
-    // Get the file ids matching our condition
-    TskImgDB& imgDB = TskServices::Instance().getImgDB();
-    std::vector<uint64_t> fileIds = imgDB.getFileIds(condition.str());
-
-    return getFiles(fileIds);
-}
-
-TskFileManager::FilePtrList TskFileManagerImpl::findFilesByExtension(const std::vector<std::string>& extensions)
-{
-    // Construct SQL condition
-    TskImgDB& imgDB = TskServices::Instance().getImgDB();
-    std::stringstream condition;
-    ///@todo check if extension already has a period
-    //period = ".";
-    condition << "WHERE (UPPER(name) LIKE ";
-    for (std::vector<std::string>::const_iterator it = extensions.begin(); it != extensions.end(); ++it)
-    {
-        condition << imgDB.quote("%." + *it);
-        if (it != --extensions.end())
-        {
-            condition << " OR UPPER(name) LIKE ";
-        }
-    }
-    condition << ") AND size > 0";
-
-    // Get the file ids matching our condition
-    std::vector<uint64_t> fileIds = imgDB.getFileIds(condition.str());
-
-	return getFiles(fileIds);
-}
-
-TskFileManager::FilePtrList TskFileManagerImpl::findFilesByParent(const uint64_t parentFileId)
-{
-    // Construct SQL condition
-    std::stringstream condition;
-    condition << "WHERE par_file_id = " << parentFileId;
-
-    // Get the file ids matching our condition
-    TskImgDB& imgDB = TskServices::Instance().getImgDB();
-    std::vector<uint64_t> fileIds = imgDB.getFileIds(condition.str());
-
-	return getFiles(fileIds);
-}
-
-TskFileManager::FilePtrList TskFileManagerImpl::findFilesByFsFileType(TSK_FS_META_TYPE_ENUM fsFileType)
-{
-    // Construct SQL condition
-    std::stringstream condition;
-    condition << "WHERE files.meta_type = " << static_cast<int>(fsFileType);
-
-    // Get the file ids matching our condition
-    TskImgDB& imgDB = TskServices::Instance().getImgDB();
-    std::vector<uint64_t> fileIds = imgDB.getFileIds(condition.str());
-
-    return getFiles(fileIds);
-}
-
-TskFileManager::FilePtrList TskFileManagerImpl::findFilesByPattern(const std::string& namePattern, const std::string& pathPattern)
-{
-    // Construct SQL condition
-    TskImgDB& imgDB = TskServices::Instance().getImgDB();
-    std::stringstream condition;
-    condition << "WHERE files.meta_type = " << static_cast<int>(TSK_FS_META_TYPE_REG)
-              << " AND UPPER(files.name) LIKE " << imgDB.quote(namePattern) 
-              << " AND UPPER(files.full_path) LIKE " << imgDB.quote(pathPattern);
-
-    // Get the file ids matching our condition
-    std::vector<uint64_t> fileIds = imgDB.getFileIds(condition.str());
-
-    return getFiles(fileIds);
-}
-
-std::wstring TskFileManagerImpl::getPath(const uint64_t fileId)
-{
-    // Determine which directory the file should live in.
-    std::stringstream dirPath;
-    dirPath << m_storageDir->path() << Poco::Path::separator()
-        << fileId / FILES_PER_DIR;
-
-    // Create the directory if it does not exist.
-    Poco::File fileDir(dirPath.str());
-    try {
-        fileDir.createDirectory();
-    } catch (Poco::FileExistsException &) {
-        ; // Ignore. This can happen when another process is creating the same directory.
-    }
-
-    // Add the fileId onto the path
-    dirPath << Poco::Path::separator() << fileId;
-
-    // Convert from Poco's UTF8 representation to std::wstring
-    std::wstring path = TskUtilities::toUTF16(dirPath.str());
-
-    return path;
-}
-
-void TskFileManagerImpl::saveFile(TskFile* fileToSave)
-{
-    TskImgDB::FILE_TYPES fileType = fileToSave->getTypeId(); 
-    if ((fileType != TskImgDB::IMGDB_FILES_TYPE_CARVED) && (fileType != TskImgDB::IMGDB_FILES_TYPE_DERIVED)) 
-    {
-        copyFile(fileToSave, getPath(fileToSave->getId()));
-    }
-    else
-    {
-        // Carved and derived files should already have been saved to storage by a call to addFile().
-        Poco::File file(Poco::Path(TskUtilities::toUTF8(getPath(fileToSave->getId()))));
-        assert(file.exists());
-        if(!file.exists())
-        {
-            std::ostringstream msg;
-            msg << "TskFileManagerImpl::saveFile : " << (fileType == TskImgDB::IMGDB_FILES_TYPE_CARVED ? "carved file" : "derived file") << " with file id = " << fileToSave->getId() << " does not exist in storage"; 
-            throw TskException(msg.str());
-        }
-    }
-}
-
-void TskFileManagerImpl::copyFile(TskFile* fileToSave, const std::wstring& filePath)
-{
-    try 
-    {
-        if (fileToSave == NULL)
-        {
-			throw TskException("TskFile pointer is NULL.");
-        }
-
-		if (fileToSave->isDirectory())
-		{
-			throw TskException("Attempt to copy directory where file is expected.");
-		}
-
-        Poco::Path destPath(TskUtilities::toUTF8(filePath));
-
-        // Create directories that may be missing along the path.
-        Poco::File destDir(destPath.parent());
-
-        try
-        {
-            destDir.createDirectories();
-        }
-        catch (Poco::FileExistsException& )
-        {
-            // It's ok if the directory already exists.
-        }
-
-        Poco::File destFile(destPath);
-
-        // If the destination file exists it is replaced
-        if (destFile.exists())
-        {
-            destFile.remove();
-        }
-
-        // If the source file exists we simply copy it to the target
-        if (fileToSave->exists())
-        {
-            Poco::File sourceFile(fileToSave->getPath());
-            sourceFile.copyTo(destPath.toString());
-        }
-        else
-        {
-            // We read the content from the file and write it to the target
-
-            // Open the file whose content we are saving
-            fileToSave->open();
-
-            // Create a new empty file.
-            destFile.createFile();
-
-            // Call File.read() to get the file content and write to new file.
-            Poco::FileOutputStream fos(destFile.path());
-            char buffer[FILE_BUFFER_SIZE];
-            int bytesRead = 0;
-
-            // Remember the offset the file was at when we were called.
-            TSK_OFF_T savedOffset = fileToSave->tell();
-
-            // Reset to start of file to ensure all content is saved.
-            fileToSave->seek(0, std::ios_base::beg);
-
-            do
-            {
-                memset(buffer, 0, FILE_BUFFER_SIZE);
-                bytesRead = fileToSave->read(buffer, FILE_BUFFER_SIZE);
-                if (bytesRead > 0)
-                    fos.write(buffer, bytesRead);
-            } while (bytesRead > 0);
-
-            // Flush and close the output stream.
-            fos.flush();
-            fos.close();
-
-            // Restore the saved offset.
-            fileToSave->seek(savedOffset, std::ios_base::beg);
-
-            // Close the file
-            fileToSave->close();
-        }
-    }
-    catch (TskFileException& tskEx)
-    {
-        // Rethrow the exception up to our caller
-        throw tskEx;
-    }
-    catch (Poco::PathNotFoundException&)
-    {
-        throw TskException("Path not found : " + fileToSave->getPath());
-    }
-    catch (std::exception & ex)
-    {
-        throw ex;
-    }
-}
-
-void TskFileManagerImpl::copyDirectory(TskFile* directoryToCopy, const std::wstring& destinationPath, const bool bRecurse)
-{
-	if (directoryToCopy == NULL)
-	{
-		throw TskException("Directory pointer is NULL.");
-	}
-
-	if (!directoryToCopy->isDirectory())
-	{
-		throw TskException("File object to copy is not a directory.");
-	}
-
-	try
-	{
-		Poco::File destDir(TskUtilities::toUTF8(destinationPath));
-
-        // If the destination directory exists it is replaced.
-        if (destDir.exists())
-        {
-            destDir.remove(true);
-        }
-
-        // Create directories that may be missing along the path.
-		destDir.createDirectories();
-
-        // If the source directory exists we simply copy it to the destination.
-        if (directoryToCopy->exists())
-        {
-            Poco::File sourceFile(directoryToCopy->getPath());
-            sourceFile.copyTo(destDir.path());
-        }
-        else
-        {
-			// Find all files contained in this directory.
-			std::stringstream condition;
-			condition << "WHERE par_file_id = " << directoryToCopy->getId();
-
-			std::vector<uint64_t> fileIds = TskServices::Instance().getImgDB().getFileIds(condition.str());
-
-			for (std::vector<uint64_t>::const_iterator it = fileIds.begin(); it != fileIds.end(); ++it)
-			{
-				TskFile * pFile = getFile(*it);
-
-				if (pFile == NULL)
-				{
-				  std::stringstream msg;
-				  msg << "Failed to create file object for file id " << *it;
-				  throw TskException(msg.str());
-				}
-
-				if (pFile->isDirectory() && bRecurse)
-				{
-					Poco::Path subDirPath = Poco::Path::forDirectory(destDir.path());
-					subDirPath.pushDirectory(pFile->getName());
-					copyDirectory(pFile, TskUtilities::toUTF16(subDirPath.toString()), bRecurse);
-				}
-
-				if (!pFile->isDirectory())
-				{
-					Poco::Path filePath(destDir.path());
-					filePath.append(pFile->getName());
-					copyFile(pFile, TskUtilities::toUTF16(filePath.toString()));
-				}
-                delete pFile;
-			}
-		}
-	}
-    catch (TskException& tskEx)
-    {
-        // Rethrow the exception up to our caller
-        throw tskEx;
-    }
-    catch (std::exception & ex)
-    {
-        throw ex;
-    }
-}
-
-void TskFileManagerImpl::addFile(const uint64_t fileId, std::istream& istr)
-{
-    // If a file with this id already exists we raise an error
-    TskFile * pFile = getFile(fileId);
-
-    if (pFile != NULL && pFile->exists())
-    {
-        delete pFile;
-        std::stringstream msg;
-        msg << "File id " << fileId << " already exists.";
-        throw TskFileException(msg.str());
-    }
-    delete pFile;
-
-    try
-    {
-        Poco::Path destPath(TskUtilities::toUTF8(getPath(fileId)));
-        Poco::File destFile(destPath);
-
-        // Create the destination
-        destFile.createFile();
-
-        // Save the file
-        Poco::FileOutputStream fos(destFile.path(), std::ios::binary);
-        Poco::StreamCopier::copyStream(istr, fos);
-    }
-    catch (Poco::Exception& ex)
-    {
-        std::wstringstream msg;
-        msg << L"TskFileManagerImpl::addFile - Error saving file from stream : " << ex.displayText().c_str();
-        LOGERROR(msg.str());
-        throw TskFileException("Error saving file from stream.");
-    }
-}
-
-void TskFileManagerImpl::addFile(const uint64_t fileId, std::wstring& filePath)
-{
-    try
-    {
-        Poco::File sourceFile(TskUtilities::toUTF8(filePath));
-        sourceFile.copyTo(TskUtilities::toUTF8(getPath(fileId)));
-    }
-    catch (Poco::Exception& ex)
-    {
-        std::wstringstream msg;
-        msg << L"TskFileManagerImpl::addFile - Error opening file " << TskUtilities::toUTF8(filePath).c_str()  
-            << L" : " << ex.displayText().c_str();
-        LOGERROR(msg.str());
-        throw TskFileException("Error opening input file.");
-    }
-}
-
-void TskFileManagerImpl::deleteFile(TskFile* fileToDelete)
-{
-    try
-    {
-        if (fileToDelete == NULL)
-        {
-            LOGERROR(L"TskFileManagerImpl::deleteFile - Passed NULL file pointer.");
-            throw TskNullPointerException();
-        }
-
-        if (fileToDelete->exists())
-        {
-            Poco::File targetFile(fileToDelete->getPath());
-            targetFile.remove();
-        }
-    }
-    catch (Poco::Exception& ex)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskFileManagerImpl::delete - Failed to delete file " 
-            << fileToDelete->getPath().c_str() << L". Error: " << ex.displayText().c_str() << std::endl;
-        LOGERROR(errorMsg.str());
-
-        throw TskFileException("Failed to delete file.");
-    }
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file TskFileManagerImpl.cpp
+ * Default implementation of the TskFileManager class.
+ */
+
+#include <sstream>
+#include <cstring>
+
+// Framework includes
+#include "TskFileManagerImpl.h"
+#include "TskFileTsk.h"
+#include "tsk/framework/services/TskSystemProperties.h"
+#include "tsk/framework/services/TskServices.h"
+#include "tsk/framework/utilities/TskException.h"
+#include "tsk/framework/utilities/TskUtilities.h"
+
+// Poco includes
+#include "Poco/Exception.h"
+#include "Poco/Path.h"
+#include "Poco/FileStream.h"
+#include "Poco/StreamCopier.h"
+#include "Poco/NumberFormatter.h"
+
+// C/C++ standard library includes
+#include <cassert>
+#include <sstream>
+#include <memory>
+
+TskFileManagerImpl * TskFileManagerImpl::m_pInstance = NULL;
+
+const int TskFileManagerImpl::FILES_PER_DIR = 1000;
+const int TskFileManagerImpl::FILE_BUFFER_SIZE = 8192;
+const std::string TskFileManagerImpl::FILES_DIRECTORY = "Files";
+
+TskFileManagerImpl& TskFileManagerImpl::instance()
+{
+    if (!m_pInstance)
+    {
+        m_pInstance = new TskFileManagerImpl();
+        m_pInstance->initialize();
+    }
+
+    return *m_pInstance;
+}
+
+void TskFileManagerImpl::initialize()
+{
+    try
+    {
+        std::string storagePath = GetSystemProperty(TskSystemProperties::SYSTEM_OUT_DIR);
+        m_storageDir = new Poco::File(storagePath + Poco::Path::separator() + FILES_DIRECTORY);
+
+        // Create the directory if it does not exist.
+        try {
+            m_storageDir->createDirectory();
+        } catch (Poco::FileExistsException &) {
+            ; // Ignore. This can happen when another process is creating the same directory.
+        }
+    }
+    catch (Poco::Exception& ex)
+    {
+        // Log a message
+        std::wstringstream errorMsg;
+        errorMsg << L"TskFileManagerImpl::initialize - File manager initialization failed with the following message: " 
+            << ex.message().c_str() << std::endl;
+        LOGERROR(errorMsg.str());
+        
+        // Throw a framework specific exception
+        throw TskFileException(ex.message());
+    }
+}
+
+TskFile * TskFileManagerImpl::getFile(const uint64_t fileId)
+{
+    /* If we were to ever have different subclasses of TskFile
+     * that differentiate file types, this is where the logic
+     * should go to create the correct version. 
+     */
+    return new TskFileTsk(fileId);
+}
+
+TskFileManager::FilePtrList TskFileManagerImpl::getFiles(const std::vector<uint64_t>& fileIds)
+{
+	TskFileManager::FilePtrList ret;
+    for (std::vector<uint64_t>::const_iterator it = fileIds.begin(); it != fileIds.end(); ++it)
+    {
+        ret.push_back(TskFileManager::FilePtr(getFile(*it)));
+    }
+
+	return ret;
+}
+
+TskFileManager::FilePtrList TskFileManagerImpl::findFilesByName(const std::string& name, const TSK_FS_META_TYPE_ENUM fsFileType /*= TSK_FS_META_TYPE_UNDEF*/)
+{
+    // Construct SQL condition
+    std::stringstream condition;
+    condition << "WHERE UPPER(files.name) = '" << name << "'";
+    if (fsFileType != TSK_FS_META_TYPE_UNDEF)
+    {
+        condition << " AND files.meta_type = " << static_cast<int>(fsFileType);
+    }
+
+    // Get the file ids matching our condition
+    TskImgDB& imgDB = TskServices::Instance().getImgDB();
+    std::vector<uint64_t> fileIds = imgDB.getFileIds(condition.str());
+
+    return getFiles(fileIds);
+}
+
+TskFileManager::FilePtrList TskFileManagerImpl::findFilesByExtension(const std::vector<std::string>& extensions)
+{
+    // Construct SQL condition
+    TskImgDB& imgDB = TskServices::Instance().getImgDB();
+    std::stringstream condition;
+    ///@todo check if extension already has a period
+    //period = ".";
+    condition << "WHERE (UPPER(name) LIKE ";
+    for (std::vector<std::string>::const_iterator it = extensions.begin(); it != extensions.end(); ++it)
+    {
+        condition << imgDB.quote("%." + *it);
+        if (it != --extensions.end())
+        {
+            condition << " OR UPPER(name) LIKE ";
+        }
+    }
+    condition << ") AND size > 0";
+
+    // Get the file ids matching our condition
+    std::vector<uint64_t> fileIds = imgDB.getFileIds(condition.str());
+
+	return getFiles(fileIds);
+}
+
+TskFileManager::FilePtrList TskFileManagerImpl::findFilesByParent(const uint64_t parentFileId)
+{
+    // Construct SQL condition
+    std::stringstream condition;
+    condition << "WHERE par_file_id = " << parentFileId;
+
+    // Get the file ids matching our condition
+    TskImgDB& imgDB = TskServices::Instance().getImgDB();
+    std::vector<uint64_t> fileIds = imgDB.getFileIds(condition.str());
+
+	return getFiles(fileIds);
+}
+
+TskFileManager::FilePtrList TskFileManagerImpl::findFilesByFsFileType(TSK_FS_META_TYPE_ENUM fsFileType)
+{
+    // Construct SQL condition
+    std::stringstream condition;
+    condition << "WHERE files.meta_type = " << static_cast<int>(fsFileType);
+
+    // Get the file ids matching our condition
+    TskImgDB& imgDB = TskServices::Instance().getImgDB();
+    std::vector<uint64_t> fileIds = imgDB.getFileIds(condition.str());
+
+    return getFiles(fileIds);
+}
+
+TskFileManager::FilePtrList TskFileManagerImpl::findFilesByPattern(const std::string& namePattern, const std::string& pathPattern)
+{
+    // Construct SQL condition
+    TskImgDB& imgDB = TskServices::Instance().getImgDB();
+    std::stringstream condition;
+    condition << "WHERE files.meta_type = " << static_cast<int>(TSK_FS_META_TYPE_REG)
+              << " AND UPPER(files.name) LIKE " << imgDB.quote(namePattern) 
+              << " AND UPPER(files.full_path) LIKE " << imgDB.quote(pathPattern);
+
+    // Get the file ids matching our condition
+    std::vector<uint64_t> fileIds = imgDB.getFileIds(condition.str());
+
+    return getFiles(fileIds);
+}
+
+std::wstring TskFileManagerImpl::getPath(const uint64_t fileId)
+{
+    // Determine which directory the file should live in.
+    std::stringstream dirPath;
+    dirPath << m_storageDir->path() << Poco::Path::separator()
+        << fileId / FILES_PER_DIR;
+
+    // Create the directory if it does not exist.
+    Poco::File fileDir(dirPath.str());
+    try {
+        fileDir.createDirectory();
+    } catch (Poco::FileExistsException &) {
+        ; // Ignore. This can happen when another process is creating the same directory.
+    }
+
+    // Add the fileId onto the path
+    dirPath << Poco::Path::separator() << fileId;
+
+    // Convert from Poco's UTF8 representation to std::wstring
+    std::wstring path = TskUtilities::toUTF16(dirPath.str());
+
+    return path;
+}
+
+void TskFileManagerImpl::saveFile(TskFile* fileToSave)
+{
+    TskImgDB::FILE_TYPES fileType = fileToSave->getTypeId(); 
+    if ((fileType != TskImgDB::IMGDB_FILES_TYPE_CARVED) && (fileType != TskImgDB::IMGDB_FILES_TYPE_DERIVED)) 
+    {
+        copyFile(fileToSave, getPath(fileToSave->getId()));
+    }
+    else
+    {
+        // Carved and derived files should already have been saved to storage by a call to addFile().
+        Poco::File file(Poco::Path(TskUtilities::toUTF8(getPath(fileToSave->getId()))));
+        assert(file.exists());
+        if(!file.exists())
+        {
+            std::ostringstream msg;
+            msg << "TskFileManagerImpl::saveFile : " << (fileType == TskImgDB::IMGDB_FILES_TYPE_CARVED ? "carved file" : "derived file") << " with file id = " << fileToSave->getId() << " does not exist in storage"; 
+            throw TskException(msg.str());
+        }
+    }
+}
+
+void TskFileManagerImpl::copyFile(TskFile* fileToSave, const std::wstring& filePath)
+{
+    try 
+    {
+        if (fileToSave == NULL)
+        {
+			throw TskException("TskFile pointer is NULL.");
+        }
+
+		if (fileToSave->isDirectory())
+		{
+			throw TskException("Attempt to copy directory where file is expected.");
+		}
+
+        Poco::Path destPath(TskUtilities::toUTF8(filePath));
+
+        // Create directories that may be missing along the path.
+        Poco::File destDir(destPath.parent());
+
+        try
+        {
+            destDir.createDirectories();
+        }
+        catch (Poco::FileExistsException& )
+        {
+            // It's ok if the directory already exists.
+        }
+
+        Poco::File destFile(destPath);
+
+        // If the destination file exists it is replaced
+        if (destFile.exists())
+        {
+            destFile.remove();
+        }
+
+        // If the source file exists we simply copy it to the target
+        if (fileToSave->exists())
+        {
+            Poco::File sourceFile(fileToSave->getPath());
+            sourceFile.copyTo(destPath.toString());
+        }
+        else
+        {
+            // We read the content from the file and write it to the target
+
+            // Open the file whose content we are saving
+            fileToSave->open();
+
+            // Create a new empty file.
+            destFile.createFile();
+
+            // Call File.read() to get the file content and write to new file.
+            Poco::FileOutputStream fos(destFile.path());
+            char buffer[FILE_BUFFER_SIZE];
+            int bytesRead = 0;
+
+            // Remember the offset the file was at when we were called.
+            TSK_OFF_T savedOffset = fileToSave->tell();
+
+            // Reset to start of file to ensure all content is saved.
+            fileToSave->seek(0, std::ios_base::beg);
+
+            do
+            {
+                memset(buffer, 0, FILE_BUFFER_SIZE);
+                bytesRead = fileToSave->read(buffer, FILE_BUFFER_SIZE);
+                if (bytesRead > 0)
+                    fos.write(buffer, bytesRead);
+            } while (bytesRead > 0);
+
+            // Flush and close the output stream.
+            fos.flush();
+            fos.close();
+
+            // Restore the saved offset.
+            fileToSave->seek(savedOffset, std::ios_base::beg);
+
+            // Close the file
+            fileToSave->close();
+        }
+    }
+    catch (TskFileException& tskEx)
+    {
+        // Rethrow the exception up to our caller
+        throw tskEx;
+    }
+    catch (Poco::PathNotFoundException&)
+    {
+        throw TskException("Path not found : " + fileToSave->getPath());
+    }
+    catch (std::exception & ex)
+    {
+        throw ex;
+    }
+}
+
+void TskFileManagerImpl::copyDirectory(TskFile* directoryToCopy, const std::wstring& destinationPath, const bool bRecurse)
+{
+	if (directoryToCopy == NULL)
+	{
+		throw TskException("Directory pointer is NULL.");
+	}
+
+	if (!directoryToCopy->isDirectory())
+	{
+		throw TskException("File object to copy is not a directory.");
+	}
+
+	try
+	{
+		Poco::File destDir(TskUtilities::toUTF8(destinationPath));
+
+        // If the destination directory exists it is replaced.
+        if (destDir.exists())
+        {
+            destDir.remove(true);
+        }
+
+        // Create directories that may be missing along the path.
+		destDir.createDirectories();
+
+        // If the source directory exists we simply copy it to the destination.
+        if (directoryToCopy->exists())
+        {
+            Poco::File sourceFile(directoryToCopy->getPath());
+            sourceFile.copyTo(destDir.path());
+        }
+        else
+        {
+			// Find all files contained in this directory.
+			std::stringstream condition;
+			condition << "WHERE par_file_id = " << directoryToCopy->getId();
+
+			std::vector<uint64_t> fileIds = TskServices::Instance().getImgDB().getFileIds(condition.str());
+
+			for (std::vector<uint64_t>::const_iterator it = fileIds.begin(); it != fileIds.end(); ++it)
+			{
+				TskFile * pFile = getFile(*it);
+
+				if (pFile == NULL)
+				{
+				  std::stringstream msg;
+				  msg << "Failed to create file object for file id " << *it;
+				  throw TskException(msg.str());
+				}
+
+				if (pFile->isDirectory() && bRecurse)
+				{
+					Poco::Path subDirPath = Poco::Path::forDirectory(destDir.path());
+					subDirPath.pushDirectory(pFile->getName());
+					copyDirectory(pFile, TskUtilities::toUTF16(subDirPath.toString()), bRecurse);
+				}
+
+				if (!pFile->isDirectory())
+				{
+					Poco::Path filePath(destDir.path());
+					filePath.append(pFile->getName());
+					copyFile(pFile, TskUtilities::toUTF16(filePath.toString()));
+				}
+                delete pFile;
+			}
+		}
+	}
+    catch (TskException& tskEx)
+    {
+        // Rethrow the exception up to our caller
+        throw tskEx;
+    }
+    catch (std::exception & ex)
+    {
+        throw ex;
+    }
+}
+
+void TskFileManagerImpl::addFile(const uint64_t fileId, std::istream& istr)
+{
+    // If a file with this id already exists we raise an error
+    TskFile * pFile = getFile(fileId);
+
+    if (pFile != NULL && pFile->exists())
+    {
+        delete pFile;
+        std::stringstream msg;
+        msg << "File id " << fileId << " already exists.";
+        throw TskFileException(msg.str());
+    }
+    delete pFile;
+
+    try
+    {
+        Poco::Path destPath(TskUtilities::toUTF8(getPath(fileId)));
+        Poco::File destFile(destPath);
+
+        // Create the destination
+        destFile.createFile();
+
+        // Save the file
+        Poco::FileOutputStream fos(destFile.path(), std::ios::binary);
+        Poco::StreamCopier::copyStream(istr, fos);
+    }
+    catch (Poco::Exception& ex)
+    {
+        std::wstringstream msg;
+        msg << L"TskFileManagerImpl::addFile - Error saving file from stream : " << ex.displayText().c_str();
+        LOGERROR(msg.str());
+        throw TskFileException("Error saving file from stream.");
+    }
+}
+
+void TskFileManagerImpl::addFile(const uint64_t fileId, std::wstring& filePath)
+{
+    try
+    {
+        Poco::File sourceFile(TskUtilities::toUTF8(filePath));
+        sourceFile.copyTo(TskUtilities::toUTF8(getPath(fileId)));
+    }
+    catch (Poco::Exception& ex)
+    {
+        std::wstringstream msg;
+        msg << L"TskFileManagerImpl::addFile - Error opening file " << TskUtilities::toUTF8(filePath).c_str()  
+            << L" : " << ex.displayText().c_str();
+        LOGERROR(msg.str());
+        throw TskFileException("Error opening input file.");
+    }
+}
+
+void TskFileManagerImpl::deleteFile(TskFile* fileToDelete)
+{
+    try
+    {
+        if (fileToDelete == NULL)
+        {
+            LOGERROR(L"TskFileManagerImpl::deleteFile - Passed NULL file pointer.");
+            throw TskNullPointerException();
+        }
+
+        if (fileToDelete->exists())
+        {
+            Poco::File targetFile(fileToDelete->getPath());
+            targetFile.remove();
+        }
+    }
+    catch (Poco::Exception& ex)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskFileManagerImpl::delete - Failed to delete file " 
+            << fileToDelete->getPath().c_str() << L". Error: " << ex.displayText().c_str() << std::endl;
+        LOGERROR(errorMsg.str());
+
+        throw TskFileException("Failed to delete file.");
+    }
 }
\ No newline at end of file
diff --git a/framework/tsk/framework/file/TskFileManagerImpl.h b/framework/tsk/framework/file/TskFileManagerImpl.h
index 3d9a136..2857a75 100755
--- a/framework/tsk/framework/file/TskFileManagerImpl.h
+++ b/framework/tsk/framework/file/TskFileManagerImpl.h
@@ -1,98 +1,98 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskFileManagerImpl.h
- * Default implementation of the TskFileManager class.
- */
-
-#ifndef _TSK_FILEMANAGERIMPL_H
-#define _TSK_FILEMANAGERIMPL_H
-
-// Framework Includes
-#include "TskFileManager.h"
-
-// Poco Includes
-#include "Poco/File.h"
-
-/**
- * An implementation of the TskFileManager
- * interface that stores files in a directory named 'files' 
- * based on their file ids.
- */
-class TSK_FRAMEWORK_API TskFileManagerImpl : public TskFileManager
-{
-public:
-    static const int FILES_PER_DIR;
-    static const int FILE_BUFFER_SIZE;
-    static const std::string FILES_DIRECTORY;
-
-    // The TskFileManagerImpl is implemented as a singleton
-    static TskFileManagerImpl& instance();
-
-    // Return a File object for the given file id.
-    virtual TskFile* getFile(const uint64_t fileId);
-
-    // Return a list of File objects mapped to the given list of file ids.
-    virtual TskFileManager::FilePtrList getFiles(const std::vector<uint64_t>& fileIds);
-
-    // Return a list of File objects matching the given filename
-    virtual TskFileManager::FilePtrList findFilesByName(const std::string& name, const TSK_FS_META_TYPE_ENUM fsFileType = TSK_FS_META_TYPE_UNDEF);
-    
-    // Return a list of File objects matching the given filename extension
-    virtual TskFileManager::FilePtrList findFilesByExtension(const std::vector<std::string>& extensions);
-    
-    // Return a list of File objects that are children of the given file id
-    virtual TskFileManager::FilePtrList findFilesByParent(const uint64_t parentFileId);
-    
-    // Return a list of File objects that match the given file meta type
-    virtual TskFileManager::FilePtrList findFilesByFsFileType(TSK_FS_META_TYPE_ENUM fsFileType);
-    
-    // Return a list of File objects that match the given filename and path patterns.
-    virtual TskFileManager::FilePtrList findFilesByPattern(const std::string& namePattern, const std::string& pathPattern);
-
-    // Return the path including the file name for the given file id.
-    virtual std::wstring getPath(const uint64_t fileId);
-
-    // Save the given file to disk.
-    virtual void saveFile(TskFile* fileToSave);
-
-    // Copy the given file to the specified fully qualified file name
-    virtual void copyFile(TskFile* fileToSave, const std::wstring& filePath);
-
-	// Copy the contents of a directory to the specified path.
-	virtual void copyDirectory(TskFile* directoryToCopy, const std::wstring& destinationPath, const bool bRecurse = false);
-
-	// Save the contents of the input stream to a file with the given fileId
-    virtual void addFile(const uint64_t fileId, std::istream& istr);
-
-    virtual void addFile(const uint64_t fileId, std::wstring& filePath);
-
-    // Delete the file from disk.
-    virtual void deleteFile(TskFile* fileToDelete);
-
-private:
-    // Private constructors and assignment operator to prevent direct
-    // instantiation.
-    TskFileManagerImpl() {};
-    TskFileManagerImpl(TskFileManagerImpl const&) {};
-    TskFileManagerImpl& operator=(TskFileManagerImpl const&) { return * m_pInstance; };
-    ~TskFileManagerImpl() {};
-
-    // Our one and only instance
-    static TskFileManagerImpl * m_pInstance;
-
-    // Our storage location
-    Poco::File * m_storageDir;
-
-    // Ensure that the storage location is set up
-    void initialize();
-};
-#endif
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file TskFileManagerImpl.h
+ * Default implementation of the TskFileManager class.
+ */
+
+#ifndef _TSK_FILEMANAGERIMPL_H
+#define _TSK_FILEMANAGERIMPL_H
+
+// Framework Includes
+#include "TskFileManager.h"
+
+// Poco Includes
+#include "Poco/File.h"
+
+/**
+ * An implementation of the TskFileManager
+ * interface that stores files in a directory named 'files' 
+ * based on their file ids.
+ */
+class TSK_FRAMEWORK_API TskFileManagerImpl : public TskFileManager
+{
+public:
+    static const int FILES_PER_DIR;
+    static const int FILE_BUFFER_SIZE;
+    static const std::string FILES_DIRECTORY;
+
+    // The TskFileManagerImpl is implemented as a singleton
+    static TskFileManagerImpl& instance();
+
+    // Return a File object for the given file id.
+    virtual TskFile* getFile(const uint64_t fileId);
+
+    // Return a list of File objects mapped to the given list of file ids.
+    virtual TskFileManager::FilePtrList getFiles(const std::vector<uint64_t>& fileIds);
+
+    // Return a list of File objects matching the given filename
+    virtual TskFileManager::FilePtrList findFilesByName(const std::string& name, const TSK_FS_META_TYPE_ENUM fsFileType = TSK_FS_META_TYPE_UNDEF);
+    
+    // Return a list of File objects matching the given filename extension
+    virtual TskFileManager::FilePtrList findFilesByExtension(const std::vector<std::string>& extensions);
+    
+    // Return a list of File objects that are children of the given file id
+    virtual TskFileManager::FilePtrList findFilesByParent(const uint64_t parentFileId);
+    
+    // Return a list of File objects that match the given file meta type
+    virtual TskFileManager::FilePtrList findFilesByFsFileType(TSK_FS_META_TYPE_ENUM fsFileType);
+    
+    // Return a list of File objects that match the given filename and path patterns.
+    virtual TskFileManager::FilePtrList findFilesByPattern(const std::string& namePattern, const std::string& pathPattern);
+
+    // Return the path including the file name for the given file id.
+    virtual std::wstring getPath(const uint64_t fileId);
+
+    // Save the given file to disk.
+    virtual void saveFile(TskFile* fileToSave);
+
+    // Copy the given file to the specified fully qualified file name
+    virtual void copyFile(TskFile* fileToSave, const std::wstring& filePath);
+
+	// Copy the contents of a directory to the specified path.
+	virtual void copyDirectory(TskFile* directoryToCopy, const std::wstring& destinationPath, const bool bRecurse = false);
+
+	// Save the contents of the input stream to a file with the given fileId
+    virtual void addFile(const uint64_t fileId, std::istream& istr);
+
+    virtual void addFile(const uint64_t fileId, std::wstring& filePath);
+
+    // Delete the file from disk.
+    virtual void deleteFile(TskFile* fileToDelete);
+
+private:
+    // Private constructors and assignment operator to prevent direct
+    // instantiation.
+    TskFileManagerImpl() {};
+    TskFileManagerImpl(TskFileManagerImpl const&) {};
+    TskFileManagerImpl& operator=(TskFileManagerImpl const&) { return * m_pInstance; };
+    ~TskFileManagerImpl() {};
+
+    // Our one and only instance
+    static TskFileManagerImpl * m_pInstance;
+
+    // Our storage location
+    Poco::File * m_storageDir;
+
+    // Ensure that the storage location is set up
+    void initialize();
+};
+#endif
diff --git a/framework/tsk/framework/file/TskFileTsk.cpp b/framework/tsk/framework/file/TskFileTsk.cpp
index df0f0ff..9b16f37 100755
--- a/framework/tsk/framework/file/TskFileTsk.cpp
+++ b/framework/tsk/framework/file/TskFileTsk.cpp
@@ -1,308 +1,308 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskFileTsk.cpp
- * Contains a Sleuthkit and Poco implementation of the TskFileTsk class.
- */
-
-// System includes
-#include <sstream>
-
-// Framework includes
-#include "TskFileTsk.h"
-#include "tsk/framework/services/TskServices.h"
-#include "tsk/framework/utilities/TskException.h"
-#include "tsk/framework/utilities/TskUtilities.h"
-#include "TskFileManagerImpl.h"
-
-/**
- * Create a TskFileTsk object given a file id.
- */
-TskFileTsk::TskFileTsk(uint64_t id) 
-    : m_file(TskUtilities::toUTF8(TskFileManagerImpl::instance().getPath(id))), 
-    m_fileInStream(NULL), m_handle(-1)
-{
-    m_id = id;
-    m_offset = 0;
-    m_isOpen = false;
-
-    initialize();
-}
-
-
-TskFileTsk::~TskFileTsk(void)
-{
-    close();
-}
-
-
-bool TskFileTsk::exists() const
-{
-    if (m_file.path().empty())
-        return false;
-    else
-        return m_file.exists();
-}
-
-
-bool TskFileTsk::isDirectory() const
-{
-    return m_fileRecord.dirType == TSK_FS_NAME_TYPE_DIR;
-}
-
-
-bool TskFileTsk::isVirtual() const
-{
-    return m_fileRecord.dirType == TSK_FS_NAME_TYPE_VIRT;
-}
-
-
-std::string TskFileTsk::getPath() const
-{
-    return m_file.path();
-}
-
-
-
-/*
- * Either initialize an input stream for files that exist on disk
- * or open a handle through the Sleuthkit for file system files that
- * have not been written to disk.
- */
-void TskFileTsk::open()
-{
-    if (m_isOpen)
-        return;
-    
-    // Files inside of the file system
-    if (getTypeId() == TskImgDB::IMGDB_FILES_TYPE_FS)
-    {
-        // Otherwise, we open a handle to the file in ImageFile
-        m_handle = TskServices::Instance().getImageFile().openFile(m_id);
-
-        if (m_handle == -1)
-        {
-            LOGERROR(L"TskFileTsk::open - Error opening file.");
-            throw TskFileException("Error opening file");
-        }
-    }
-    else if (getTypeId() == TskImgDB::IMGDB_FILES_TYPE_UNUSED)
-    {
-        if (TskServices::Instance().getImgDB().getUnusedSector(getId(), m_unusedSectorsRecord) == -1) {
-            LOGERROR(L"TskFileTsk::open - Error opening file.");
-            throw TskFileException("Error opening file");
-        }
-    }
-    // CARVED and DERIVED
-    else if ((getTypeId() == TskImgDB::IMGDB_FILES_TYPE_CARVED) || (getTypeId() == TskImgDB::IMGDB_FILES_TYPE_DERIVED)) {
-        if (exists()) {
-            // Open our input stream if not already open
-            if (m_fileInStream == NULL)
-            {
-                m_fileInStream = new Poco::FileInputStream(m_file.path());
-            }
-        }
-        else {
-            std::wstringstream msg;
-            msg << L"TskFileTsk::open - Open failed because file id (" << m_id
-                << ") does not exist on disk and is carved or derived.";
-            LOGERROR(msg.str());
-            throw TskFileException("Error opening file");
-        }
-    }
-    else
-    {
-        std::wstringstream msg;
-        msg << L"TskFileTsk::open - Open failed because file id (" << m_id
-            << ") has unknown type (" << getTypeId() << ").";
-        LOGERROR(msg.str());
-        throw TskFileException("Error opening file");
-    }
-
-    m_offset = 0;
-    m_isOpen = true;
-}
-
-void TskFileTsk::close()
-{
-    // Close and delete our input stream if it's open.
-    if (m_fileInStream != NULL)
-    {
-        m_fileInStream->close();
-        delete m_fileInStream;
-        m_fileInStream = NULL;
-    }
-
-    // Close our handle in the image file if it's open.
-    if (m_handle != -1)
-    {
-        TskServices::Instance().getImageFile().closeFile(m_handle);
-        m_handle = -1;
-    }
-
-    if (getTypeId() == TskImgDB::IMGDB_FILES_TYPE_UNUSED) {
-        m_handle = -1;
-    }
-
-    m_offset = 0;
-    m_isOpen = false;
-}
-
-
-ssize_t TskFileTsk::read(char *buf, const size_t count)
-{
-    // File must be opened before you can read.
-    if (!m_isOpen)
-    {
-        LOGERROR(L"TskFileTsk::read - File not open.");
-        return -1;
-    }
-    
-    //if the file size is 0 don't bother trying to read
-    if (!getSize())
-        return 0;
-
-    try
-    {
-        // If an on disk file exists we read the content from it
-        if (m_fileInStream != NULL)
-        {
-            m_fileInStream->read(buf, count);
-            /* @@@ BC: I am not entirely sure that POCO will
-             * not be throwing this as an exception -- the C++ streams can be 
-             * configured either way.  If it is, we'll catch that below */
-            // check for errors -- fail is set if EOF is reached
-            if ((m_fileInStream->fail()) && (m_fileInStream->eof() == false)) {
-                std::wstringstream message;
-                message << L"TskFileTsk::read - error reading stream -  offset: " 
-                    << m_fileInStream->tellg() << " -- len: " << count << std::endl;
-                LOGERROR(message.str());
-                return -1;
-            }
-            return m_fileInStream->gcount();
-        }
-        else if (getTypeId() == TskImgDB::IMGDB_FILES_TYPE_FS)
-        {
-            // readFile will log any errors
-            int bytesRead = TskServices::Instance().getImageFile().readFile(m_handle, m_offset, count, buf);
-            if (bytesRead > 0)
-                m_offset += bytesRead;
-
-            return bytesRead;
-        }
-        else if (getTypeId() == TskImgDB::IMGDB_FILES_TYPE_UNUSED)
-        {
-            int bytesRead = 0;
-            uint64_t bytesToRead = 0;
-            uint64_t fileSize = m_unusedSectorsRecord.sectLen * 512;
-            if ((uint64_t)m_offset + count > fileSize) {
-                if (fileSize - m_offset > 0)
-                    bytesToRead = fileSize - m_offset;
-                else
-                    return bytesRead;
-            } else {
-                bytesToRead = count;
-            }
-            // getByteData will log any errors
-            bytesRead = TskServices::Instance().getImageFile().getByteData(m_unusedSectorsRecord.sectStart * 512 + m_offset, bytesToRead, buf);
-            if (bytesRead > 0)
-                m_offset += bytesRead;
-            return bytesRead;
-        }
-        else {
-            std::wstringstream errorMsg;
-            errorMsg << "TskFileTsk::read ID: " << m_id << " -- unknown type" << std::endl;
-            LOGERROR(errorMsg.str());
-            return -1;
-        }
-    }
-    catch (std::exception& ex)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << "TskFileTsk::read ID: " << m_id << " -- " << ex.what() << std::endl;
-        LOGERROR(errorMsg.str());
-        return -1;
-    }
-}
-
-TSK_OFF_T TskFileTsk::tell() const
-{
-    if (!m_isOpen)
-    {
-        LOGERROR(L"TskFileTsk::tell : File not open.");
-        throw TskFileException("File not open.");
-    }
-
-    if (m_fileInStream != NULL)
-        return m_fileInStream->tellg();
-    else
-        return m_offset;
-}
-
-TSK_OFF_T TskFileTsk::seek(const TSK_OFF_T off, std::ios::seekdir origin)
-{
-    if (!m_isOpen)
-    {
-        LOGERROR(L"TskFileTsk::seek : File not open.");
-        throw TskFileException("File not open.");
-    }
-
-    if (m_fileInStream != NULL)
-    {
-        // Clear all error flags before seeking since an earlier
-        // read may have set the eof flag.
-        m_fileInStream->clear();
-        m_fileInStream->seekg(off, origin);
-        return m_fileInStream->tellg();
-    }
-    else
-    {
-        if (origin == std::ios::beg)
-        {
-            if (off > getSize())
-            {
-                LOGERROR(L"TskFileTsk::seek - Attempt to seek beyond end of file.");
-                throw TskFileException("Attempt to seek beyond end of file.");
-            }
-
-            m_offset = off;
-        }
-        else if (origin == std::ios::end)
-        {
-            if (off > 0)
-            {
-                LOGERROR(L"TskFileTsk::seek - Offset must be a negative number when seeking from end of file.");
-                throw TskFileException("Seek from end requires negative offset.");
-            }
-            if (getSize() + off < 0)
-            {
-                LOGERROR(L"TskFileTsk::seek - Attempt to seek prior to start of file.");
-                throw TskFileException("Attempt to seek prior to start of file");
-            }
-            m_offset = getSize() + off;
-        }
-        else
-        {
-            if (m_offset + off > getSize())
-            {
-                LOGERROR(L"TskFileTsk::seek - Attempt to seek beyond end of file.");
-                throw TskFileException("Attempt to seek beyond end of file.");
-            }
-            if (m_offset + off < 0)
-            {
-                LOGERROR(L"TskFileTsk::seek - Attempt to seek prior to start of file.");
-                throw TskFileException("Attempt to seek prior to start of file.");
-            }
-            m_offset += off;
-        }
-        return m_offset;
-    }
-}
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file TskFileTsk.cpp
+ * Contains a Sleuthkit and Poco implementation of the TskFileTsk class.
+ */
+
+// System includes
+#include <sstream>
+
+// Framework includes
+#include "TskFileTsk.h"
+#include "tsk/framework/services/TskServices.h"
+#include "tsk/framework/utilities/TskException.h"
+#include "tsk/framework/utilities/TskUtilities.h"
+#include "TskFileManagerImpl.h"
+
+/**
+ * Create a TskFileTsk object given a file id.
+ */
+TskFileTsk::TskFileTsk(uint64_t id) 
+    : m_file(TskUtilities::toUTF8(TskFileManagerImpl::instance().getPath(id))), 
+    m_fileInStream(NULL), m_handle(-1)
+{
+    m_id = id;
+    m_offset = 0;
+    m_isOpen = false;
+
+    initialize();
+}
+
+
+TskFileTsk::~TskFileTsk(void)
+{
+    close();
+}
+
+
+bool TskFileTsk::exists() const
+{
+    if (m_file.path().empty())
+        return false;
+    else
+        return m_file.exists();
+}
+
+
+bool TskFileTsk::isDirectory() const
+{
+    return m_fileRecord.dirType == TSK_FS_NAME_TYPE_DIR;
+}
+
+
+bool TskFileTsk::isVirtual() const
+{
+    return m_fileRecord.dirType == TSK_FS_NAME_TYPE_VIRT;
+}
+
+
+std::string TskFileTsk::getPath() const
+{
+    return m_file.path();
+}
+
+
+
+/*
+ * Either initialize an input stream for files that exist on disk
+ * or open a handle through the Sleuthkit for file system files that
+ * have not been written to disk.
+ */
+void TskFileTsk::open()
+{
+    if (m_isOpen)
+        return;
+    
+    // Files inside of the file system
+    if (getTypeId() == TskImgDB::IMGDB_FILES_TYPE_FS)
+    {
+        // Otherwise, we open a handle to the file in ImageFile
+        m_handle = TskServices::Instance().getImageFile().openFile(m_id);
+
+        if (m_handle == -1)
+        {
+            LOGERROR(L"TskFileTsk::open - Error opening file.");
+            throw TskFileException("Error opening file");
+        }
+    }
+    else if (getTypeId() == TskImgDB::IMGDB_FILES_TYPE_UNUSED)
+    {
+        if (TskServices::Instance().getImgDB().getUnusedSector(getId(), m_unusedSectorsRecord) == -1) {
+            LOGERROR(L"TskFileTsk::open - Error opening file.");
+            throw TskFileException("Error opening file");
+        }
+    }
+    // CARVED and DERIVED
+    else if ((getTypeId() == TskImgDB::IMGDB_FILES_TYPE_CARVED) || (getTypeId() == TskImgDB::IMGDB_FILES_TYPE_DERIVED)) {
+        if (exists()) {
+            // Open our input stream if not already open
+            if (m_fileInStream == NULL)
+            {
+                m_fileInStream = new Poco::FileInputStream(m_file.path());
+            }
+        }
+        else {
+            std::wstringstream msg;
+            msg << L"TskFileTsk::open - Open failed because file id (" << m_id
+                << ") does not exist on disk and is carved or derived.";
+            LOGERROR(msg.str());
+            throw TskFileException("Error opening file");
+        }
+    }
+    else
+    {
+        std::wstringstream msg;
+        msg << L"TskFileTsk::open - Open failed because file id (" << m_id
+            << ") has unknown type (" << getTypeId() << ").";
+        LOGERROR(msg.str());
+        throw TskFileException("Error opening file");
+    }
+
+    m_offset = 0;
+    m_isOpen = true;
+}
+
+void TskFileTsk::close()
+{
+    // Close and delete our input stream if it's open.
+    if (m_fileInStream != NULL)
+    {
+        m_fileInStream->close();
+        delete m_fileInStream;
+        m_fileInStream = NULL;
+    }
+
+    // Close our handle in the image file if it's open.
+    if (m_handle != -1)
+    {
+        TskServices::Instance().getImageFile().closeFile(m_handle);
+        m_handle = -1;
+    }
+
+    if (getTypeId() == TskImgDB::IMGDB_FILES_TYPE_UNUSED) {
+        m_handle = -1;
+    }
+
+    m_offset = 0;
+    m_isOpen = false;
+}
+
+
+ssize_t TskFileTsk::read(char *buf, const size_t count)
+{
+    // File must be opened before you can read.
+    if (!m_isOpen)
+    {
+        LOGERROR(L"TskFileTsk::read - File not open.");
+        return -1;
+    }
+    
+    //if the file size is 0 don't bother trying to read
+    if (!getSize())
+        return 0;
+
+    try
+    {
+        // If an on disk file exists we read the content from it
+        if (m_fileInStream != NULL)
+        {
+            m_fileInStream->read(buf, count);
+            /* @@@ BC: I am not entirely sure that POCO will
+             * not be throwing this as an exception -- the C++ streams can be 
+             * configured either way.  If it is, we'll catch that below */
+            // check for errors -- fail is set if EOF is reached
+            if ((m_fileInStream->fail()) && (m_fileInStream->eof() == false)) {
+                std::wstringstream message;
+                message << L"TskFileTsk::read - error reading stream -  offset: " 
+                    << m_fileInStream->tellg() << " -- len: " << count << std::endl;
+                LOGERROR(message.str());
+                return -1;
+            }
+            return m_fileInStream->gcount();
+        }
+        else if (getTypeId() == TskImgDB::IMGDB_FILES_TYPE_FS)
+        {
+            // readFile will log any errors
+            int bytesRead = TskServices::Instance().getImageFile().readFile(m_handle, m_offset, count, buf);
+            if (bytesRead > 0)
+                m_offset += bytesRead;
+
+            return bytesRead;
+        }
+        else if (getTypeId() == TskImgDB::IMGDB_FILES_TYPE_UNUSED)
+        {
+            int bytesRead = 0;
+            uint64_t bytesToRead = 0;
+            uint64_t fileSize = m_unusedSectorsRecord.sectLen * 512;
+            if ((uint64_t)m_offset + count > fileSize) {
+                if (fileSize - m_offset > 0)
+                    bytesToRead = fileSize - m_offset;
+                else
+                    return bytesRead;
+            } else {
+                bytesToRead = count;
+            }
+            // getByteData will log any errors
+            bytesRead = TskServices::Instance().getImageFile().getByteData(m_unusedSectorsRecord.sectStart * 512 + m_offset, bytesToRead, buf);
+            if (bytesRead > 0)
+                m_offset += bytesRead;
+            return bytesRead;
+        }
+        else {
+            std::wstringstream errorMsg;
+            errorMsg << "TskFileTsk::read ID: " << m_id << " -- unknown type" << std::endl;
+            LOGERROR(errorMsg.str());
+            return -1;
+        }
+    }
+    catch (std::exception& ex)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << "TskFileTsk::read ID: " << m_id << " -- " << ex.what() << std::endl;
+        LOGERROR(errorMsg.str());
+        return -1;
+    }
+}
+
+TSK_OFF_T TskFileTsk::tell() const
+{
+    if (!m_isOpen)
+    {
+        LOGERROR(L"TskFileTsk::tell : File not open.");
+        throw TskFileException("File not open.");
+    }
+
+    if (m_fileInStream != NULL)
+        return m_fileInStream->tellg();
+    else
+        return m_offset;
+}
+
+TSK_OFF_T TskFileTsk::seek(const TSK_OFF_T off, std::ios::seekdir origin)
+{
+    if (!m_isOpen)
+    {
+        LOGERROR(L"TskFileTsk::seek : File not open.");
+        throw TskFileException("File not open.");
+    }
+
+    if (m_fileInStream != NULL)
+    {
+        // Clear all error flags before seeking since an earlier
+        // read may have set the eof flag.
+        m_fileInStream->clear();
+        m_fileInStream->seekg(off, origin);
+        return m_fileInStream->tellg();
+    }
+    else
+    {
+        if (origin == std::ios::beg)
+        {
+            if (off > getSize())
+            {
+                LOGERROR(L"TskFileTsk::seek - Attempt to seek beyond end of file.");
+                throw TskFileException("Attempt to seek beyond end of file.");
+            }
+
+            m_offset = off;
+        }
+        else if (origin == std::ios::end)
+        {
+            if (off > 0)
+            {
+                LOGERROR(L"TskFileTsk::seek - Offset must be a negative number when seeking from end of file.");
+                throw TskFileException("Seek from end requires negative offset.");
+            }
+            if (getSize() + off < 0)
+            {
+                LOGERROR(L"TskFileTsk::seek - Attempt to seek prior to start of file.");
+                throw TskFileException("Attempt to seek prior to start of file");
+            }
+            m_offset = getSize() + off;
+        }
+        else
+        {
+            if (m_offset + off > getSize())
+            {
+                LOGERROR(L"TskFileTsk::seek - Attempt to seek beyond end of file.");
+                throw TskFileException("Attempt to seek beyond end of file.");
+            }
+            if (m_offset + off < 0)
+            {
+                LOGERROR(L"TskFileTsk::seek - Attempt to seek prior to start of file.");
+                throw TskFileException("Attempt to seek prior to start of file.");
+            }
+            m_offset += off;
+        }
+        return m_offset;
+    }
+}
diff --git a/framework/tsk/framework/file/TskFileTsk.h b/framework/tsk/framework/file/TskFileTsk.h
index ac50bd5..f5df2f3 100755
--- a/framework/tsk/framework/file/TskFileTsk.h
+++ b/framework/tsk/framework/file/TskFileTsk.h
@@ -1,96 +1,96 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskFile.h
- * Contains the interface for the TskFile class.
- */
-
-#ifndef _TSK_FILE_TSK_H
-#define _TSK_FILE_TSK_H
-
-// System includes
-#include <string>
-
-// Framework includes
-#include "TskFile.h"
-#include "tsk/framework/services/TskImgDB.h"
-#include "tsk/base/tsk_os.h"
-
-// Poco includes
-#include "Poco/File.h"
-#include "Poco/FileStream.h"
-
-/**
- * TskFileTsk is a Sleuthkit and Poco based implementation
- * of the TskFile interface.
- */
-class TSK_FRAMEWORK_API TskFileTsk : public TskFile
-{
-public:
-    
-
-	virtual ~TskFileTsk();
-
-    /// Fully qualified path to on-disk representation of file.
-    virtual std::string getPath() const;
-
-    /// Does a file exist on disk for this TskFile object.
-    /**
-     * @return True if a file exists, false otherwise
-     */ 
-    virtual bool exists() const;
-
-    /// Does this file represent a directory.
-    /**
-     * @return True if this is a directory, false otherwise
-     */ 
-    virtual bool isDirectory() const;
-
-    /// Is this a Sleuthkit "virtual" file (created by TSK for
-    /// file system areas).
-    /**
-     * @return True if this is a "virtual" file, false otherwise
-     */ 
-    virtual bool isVirtual() const;
-
-    /// Open the file. Must be called before reading.
-    virtual void open();
-
-    /// Close the file.
-    virtual void close();
-
-    virtual TSK_OFF_T tell() const;
-
-    virtual TSK_OFF_T seek(const TSK_OFF_T off, std::ios::seekdir origin = std::ios::beg);
-
-    virtual ssize_t read(char * buf, const size_t count);
-
-protected:
-    friend class TskFileManagerImpl;
-
-    // Construct a file for the given id.
-	TskFileTsk(const uint64_t id);
-
-    TskFileTsk() {};
-
-    // A handle to the file on disk
-    Poco::File m_file;
-
-    // An input stream for the file on disk
-    Poco::FileInputStream * m_fileInStream;
-
-    // A Sleuthkit handle to the file in an image
-    int m_handle;
-
-    // For IMGDB_FILES_TYPE_UNUSED unused_sectors only
-    TskUnusedSectorsRecord m_unusedSectorsRecord;
-};
-#endif
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file TskFile.h
+ * Contains the interface for the TskFile class.
+ */
+
+#ifndef _TSK_FILE_TSK_H
+#define _TSK_FILE_TSK_H
+
+// System includes
+#include <string>
+
+// Framework includes
+#include "TskFile.h"
+#include "tsk/framework/services/TskImgDB.h"
+#include "tsk/base/tsk_os.h"
+
+// Poco includes
+#include "Poco/File.h"
+#include "Poco/FileStream.h"
+
+/**
+ * TskFileTsk is a Sleuthkit and Poco based implementation
+ * of the TskFile interface.
+ */
+class TSK_FRAMEWORK_API TskFileTsk : public TskFile
+{
+public:
+    
+
+	virtual ~TskFileTsk();
+
+    /// Fully qualified path to on-disk representation of file.
+    virtual std::string getPath() const;
+
+    /// Does a file exist on disk for this TskFile object.
+    /**
+     * @return True if a file exists, false otherwise
+     */ 
+    virtual bool exists() const;
+
+    /// Does this file represent a directory.
+    /**
+     * @return True if this is a directory, false otherwise
+     */ 
+    virtual bool isDirectory() const;
+
+    /// Is this a Sleuthkit "virtual" file (created by TSK for
+    /// file system areas).
+    /**
+     * @return True if this is a "virtual" file, false otherwise
+     */ 
+    virtual bool isVirtual() const;
+
+    /// Open the file. Must be called before reading.
+    virtual void open();
+
+    /// Close the file.
+    virtual void close();
+
+    virtual TSK_OFF_T tell() const;
+
+    virtual TSK_OFF_T seek(const TSK_OFF_T off, std::ios::seekdir origin = std::ios::beg);
+
+    virtual ssize_t read(char * buf, const size_t count);
+
+protected:
+    friend class TskFileManagerImpl;
+
+    // Construct a file for the given id.
+	TskFileTsk(const uint64_t id);
+
+    TskFileTsk() {};
+
+    // A handle to the file on disk
+    Poco::File m_file;
+
+    // An input stream for the file on disk
+    Poco::FileInputStream * m_fileInStream;
+
+    // A Sleuthkit handle to the file in an image
+    int m_handle;
+
+    // For IMGDB_FILES_TYPE_UNUSED unused_sectors only
+    TskUnusedSectorsRecord m_unusedSectorsRecord;
+};
+#endif
diff --git a/framework/tsk/framework/framework_i.h b/framework/tsk/framework/framework_i.h
index 285382a..0cee3cf 100755
--- a/framework/tsk/framework/framework_i.h
+++ b/framework/tsk/framework/framework_i.h
@@ -1,36 +1,36 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-#ifndef _TSK_OSSLIBTSK_I_H
-#define _TSK_OSSLIBTSK_I_H
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <tsk/libtsk.h>
-
-#define MAX_BUFF_LENGTH 1024
-
-
-#if defined(TSK_WIN32) 
-#if defined(TSK_EXPORTS)
-    #define TSK_FRAMEWORK_API __declspec(dllexport)
-#else
-    #define TSK_FRAMEWORK_API __declspec(dllimport)
-#endif
-// non-win32
-#else
-    #define TSK_FRAMEWORK_API 
-#endif
-
-#if defined(_MSC_VER)
-#pragma warning(disable:4251) // ... needs to have dll-interface warning
-#endif
-
-#endif
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+#ifndef _TSK_OSSLIBTSK_I_H
+#define _TSK_OSSLIBTSK_I_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <tsk/libtsk.h>
+
+#define MAX_BUFF_LENGTH 1024
+
+
+#if defined(TSK_WIN32) 
+#if defined(TSK_EXPORTS)
+    #define TSK_FRAMEWORK_API __declspec(dllexport)
+#else
+    #define TSK_FRAMEWORK_API __declspec(dllimport)
+#endif
+// non-win32
+#else
+    #define TSK_FRAMEWORK_API 
+#endif
+
+#if defined(_MSC_VER)
+#pragma warning(disable:4251) // ... needs to have dll-interface warning
+#endif
+
+#endif
diff --git a/framework/tsk/framework/pipeline/TskExecutableModule.cpp b/framework/tsk/framework/pipeline/TskExecutableModule.cpp
index cd869f0..e9e7f06 100755
--- a/framework/tsk/framework/pipeline/TskExecutableModule.cpp
+++ b/framework/tsk/framework/pipeline/TskExecutableModule.cpp
@@ -1,232 +1,232 @@
-/*
- *
- *  The Sleuth Kit
- *
- *  Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- *  Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- *  reserved.
- *
- *  This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskExecutableModule.cpp
- * Contains the implementation for the TskExecutableModule class.
- */
-
-// System includes
-#include <sstream>
-
-// Framework includes
-#include "TskExecutableModule.h"
-#include "tsk/framework/services/TskServices.h"
-#include "tsk/framework/utilities/TskException.h"
-#include "tsk/framework/file/TskFileManagerImpl.h"
-#include "tsk/framework/utilities/TskUtilities.h"
-
-// Poco includes
-#include "Poco/String.h"
-#include "Poco/StringTokenizer.h"
-#include "Poco/FileStream.h"
-#include "Poco/Process.h"
-#include "Poco/PipeStream.h"
-#include "Poco/StreamCopier.h"
-#include "Poco/Path.h"
-#include "Poco/DateTimeFormatter.h"
-#include "Poco/DateTimeFormat.h"
-#include "Poco/Environment.h"
-
-/**
- * Constructor
- */
-TskExecutableModule::TskExecutableModule() : m_output("")
-{
-}
-
-/**
- * Destructor
- */
-TskExecutableModule::~TskExecutableModule()
-{
-}
-
-/**
- * Run the module on the given file.
- */
-TskModule::Status TskExecutableModule::run(TskFile* fileToAnalyze)
-{
-
-    if (fileToAnalyze == NULL)
-    {
-        LOGERROR(L"TskExecutableModule::run - Passed NULL file pointer.");
-        throw TskException("Module execution failed.");
-    }
-
-    return execute(fileToAnalyze);
-}
-
-/**
- * Run the module in the reporting pipeline.
- */
-TskModule::Status TskExecutableModule::report()
-{
-    return execute(NULL);
-}
-
-/**
- * Confirm that an executable file exists at location.
- */
-void TskExecutableModule::setPath(const std::string& location)
-{
-    try
-    {
-        // Autogenerate filename extension if needed
-        Poco::Path tempPath = location;
-        if (tempPath.getExtension().empty())
-        {
-            std::string os = Poco::Environment::osName();
-            if (os.find("Windows") != std::string::npos ||
-                os.find("CYGWIN")  != std::string::npos ||
-                os.find("MINGW")   != std::string::npos )
-            {
-                tempPath.setExtension("exe");
-            }
-            // Else we assume the user is on a platform that doesn't use executable extensions.
-        }
-
-        // Call our parent to validate the location.
-        TskModule::setPath(tempPath.toString());
-
-        m_name = Poco::Path(m_modulePath).getBaseName();
-
-        // Verify that the file is executable.
-        Poco::File exeFile(m_modulePath);
-
-        if (!exeFile.canExecute())
-        {
-            std::wstringstream msg;
-            msg << L"TskExecutableModule::setPath - File is not executable: "
-                << m_modulePath.c_str();
-            LOGERROR(msg.str());
-            throw TskException("File is not executable.");
-        }
-    }
-    catch (TskException& tskEx)
-    {
-        throw tskEx;
-    }
-    catch(std::exception& ex)
-    {
-        // Log a message and throw a framework exception.
-        std::wstringstream msg;
-        msg << "TskExecutableModule::setPath : " << ex.what();
-        LOGERROR(msg.str());
-
-        throw TskException("Failed to set location: " + m_modulePath);
-    }
-}
-
-/**
- *
- */
-void TskExecutableModule::setOutput(const std::string& outFile)
-{
-    m_output = outFile;
-}
-
-/**
- *
- */
-std::string TskExecutableModule::getOutput() const
-{
-    return m_output;
-}
-
-TskModule::Status TskExecutableModule::execute(TskFile * fileToAnalyze){
-    try
-    {
-        // Perform macro expansion on command line args.
-        std::string arguments = expandArgumentMacros(m_arguments, fileToAnalyze);
-
-        // Split the arguments into a vector of strings.
-        Poco::StringTokenizer tokenizer(arguments, " ");
-
-        std::vector<std::string> vectorArgs(tokenizer.begin(), tokenizer.end());
-
-        // Perform macro expansion on our output location
-        std::string outFilePath = expandArgumentMacros(m_output, fileToAnalyze);
-
-        // If an output file has been specified we need to ensure that anything
-        // written to stdout gets put in the file. This is accomplished by passing
-        // a pipe to Poco::Process::launch and reading its contents once the process
-        // has terminated.
-        if (!outFilePath.empty())
-        {
-            // Create directories that may be missing along the path.
-            std::string outFilePathNoQuote(TskUtilities::stripQuotes(outFilePath));
-            Poco::Path outPath(outFilePathNoQuote);
-            Poco::File outDir(outPath.parent());
-            outDir.createDirectories();
-
-            // Create the output file if it does not exist.
-            Poco::File outFile(outFilePathNoQuote);
-
-            if (!outFile.exists())
-            {
-                outFile.createFile();
-            }
-
-            // Create process redirecting its output to a Pipe.
-            Poco::Pipe outPipe;
-
-            Poco::ProcessHandle handle = Poco::Process::launch(m_modulePath, vectorArgs, NULL, &outPipe, NULL);
-            
-            // Copy output from Pipe to the output file.
-            Poco::PipeInputStream istr(outPipe);
-            Poco::FileOutputStream ostr(outFile.path(), std::ios::out|std::ios::app);
-
-            while (istr)
-            {
-                Poco::StreamCopier::copyStream(istr, ostr);
-            }
-
-            // The process should be finished. Check its exit code.
-            int exitCode = Poco::Process::wait(handle);
-
-            if (exitCode != 0)
-            {
-                // If a module fails we log a warning message and continue.
-                std::wstringstream msg;
-                msg << L"TskExecutableModule::execute - Module (" << m_modulePath.c_str()
-                    << L") failed with exit code: " << exitCode;
-                LOGWARN(msg.str());
-            }
-        }
-        else
-        {
-            // No output file was specified.
-            Poco::ProcessHandle handle = Poco::Process::launch(m_modulePath, vectorArgs);
-
-            // Wait for the process to complete
-            int exitCode = Poco::Process::wait(handle);
-
-            if (exitCode != 0)
-            {
-                // If a module fails we log a warning message and continue.
-                std::wstringstream msg;
-                msg << L"TskExecutableModule::execute - Module (" << m_modulePath.c_str()
-                    << L") failed with exit code: " << exitCode;
-                LOGWARN(msg.str());
-            }
-        }
-    }
-    catch (Poco::Exception& ex)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskExecutableModule::execute - Error: " << ex.displayText().c_str();
-        LOGERROR(errorMsg.str());
-        throw TskException("Module execution failed.");
-    }
-
-    return TskModule::OK;
-}
+/*
+ *
+ *  The Sleuth Kit
+ *
+ *  Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ *  Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ *  reserved.
+ *
+ *  This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file TskExecutableModule.cpp
+ * Contains the implementation for the TskExecutableModule class.
+ */
+
+// System includes
+#include <sstream>
+
+// Framework includes
+#include "TskExecutableModule.h"
+#include "tsk/framework/services/TskServices.h"
+#include "tsk/framework/utilities/TskException.h"
+#include "tsk/framework/file/TskFileManagerImpl.h"
+#include "tsk/framework/utilities/TskUtilities.h"
+
+// Poco includes
+#include "Poco/String.h"
+#include "Poco/StringTokenizer.h"
+#include "Poco/FileStream.h"
+#include "Poco/Process.h"
+#include "Poco/PipeStream.h"
+#include "Poco/StreamCopier.h"
+#include "Poco/Path.h"
+#include "Poco/DateTimeFormatter.h"
+#include "Poco/DateTimeFormat.h"
+#include "Poco/Environment.h"
+
+/**
+ * Constructor
+ */
+TskExecutableModule::TskExecutableModule() : m_output("")
+{
+}
+
+/**
+ * Destructor
+ */
+TskExecutableModule::~TskExecutableModule()
+{
+}
+
+/**
+ * Run the module on the given file.
+ */
+TskModule::Status TskExecutableModule::run(TskFile* fileToAnalyze)
+{
+
+    if (fileToAnalyze == NULL)
+    {
+        LOGERROR(L"TskExecutableModule::run - Passed NULL file pointer.");
+        throw TskException("Module execution failed.");
+    }
+
+    return execute(fileToAnalyze);
+}
+
+/**
+ * Run the module in the reporting pipeline.
+ */
+TskModule::Status TskExecutableModule::report()
+{
+    return execute(NULL);
+}
+
+/**
+ * Confirm that an executable file exists at location.
+ */
+void TskExecutableModule::setPath(const std::string& location)
+{
+    try
+    {
+        // Autogenerate filename extension if needed
+        Poco::Path tempPath = location;
+        if (tempPath.getExtension().empty())
+        {
+            std::string os = Poco::Environment::osName();
+            if (os.find("Windows") != std::string::npos ||
+                os.find("CYGWIN")  != std::string::npos ||
+                os.find("MINGW")   != std::string::npos )
+            {
+                tempPath.setExtension("exe");
+            }
+            // Else we assume the user is on a platform that doesn't use executable extensions.
+        }
+
+        // Call our parent to validate the location.
+        TskModule::setPath(tempPath.toString());
+
+        m_name = Poco::Path(m_modulePath).getBaseName();
+
+        // Verify that the file is executable.
+        Poco::File exeFile(m_modulePath);
+
+        if (!exeFile.canExecute())
+        {
+            std::wstringstream msg;
+            msg << L"TskExecutableModule::setPath - File is not executable: "
+                << m_modulePath.c_str();
+            LOGERROR(msg.str());
+            throw TskException("File is not executable.");
+        }
+    }
+    catch (TskException& tskEx)
+    {
+        throw tskEx;
+    }
+    catch(std::exception& ex)
+    {
+        // Log a message and throw a framework exception.
+        std::wstringstream msg;
+        msg << "TskExecutableModule::setPath : " << ex.what();
+        LOGERROR(msg.str());
+
+        throw TskException("Failed to set location: " + m_modulePath);
+    }
+}
+
+/**
+ *
+ */
+void TskExecutableModule::setOutput(const std::string& outFile)
+{
+    m_output = outFile;
+}
+
+/**
+ *
+ */
+std::string TskExecutableModule::getOutput() const
+{
+    return m_output;
+}
+
+TskModule::Status TskExecutableModule::execute(TskFile * fileToAnalyze){
+    try
+    {
+        // Perform macro expansion on command line args.
+        std::string arguments = expandArgumentMacros(m_arguments, fileToAnalyze);
+
+        // Split the arguments into a vector of strings.
+        Poco::StringTokenizer tokenizer(arguments, " ");
+
+        std::vector<std::string> vectorArgs(tokenizer.begin(), tokenizer.end());
+
+        // Perform macro expansion on our output location
+        std::string outFilePath = expandArgumentMacros(m_output, fileToAnalyze);
+
+        // If an output file has been specified we need to ensure that anything
+        // written to stdout gets put in the file. This is accomplished by passing
+        // a pipe to Poco::Process::launch and reading its contents once the process
+        // has terminated.
+        if (!outFilePath.empty())
+        {
+            // Create directories that may be missing along the path.
+            std::string outFilePathNoQuote(TskUtilities::stripQuotes(outFilePath));
+            Poco::Path outPath(outFilePathNoQuote);
+            Poco::File outDir(outPath.parent());
+            outDir.createDirectories();
+
+            // Create the output file if it does not exist.
+            Poco::File outFile(outFilePathNoQuote);
+
+            if (!outFile.exists())
+            {
+                outFile.createFile();
+            }
+
+            // Create process redirecting its output to a Pipe.
+            Poco::Pipe outPipe;
+
+            Poco::ProcessHandle handle = Poco::Process::launch(m_modulePath, vectorArgs, NULL, &outPipe, NULL);
+            
+            // Copy output from Pipe to the output file.
+            Poco::PipeInputStream istr(outPipe);
+            Poco::FileOutputStream ostr(outFile.path(), std::ios::out|std::ios::app);
+
+            while (istr)
+            {
+                Poco::StreamCopier::copyStream(istr, ostr);
+            }
+
+            // The process should be finished. Check its exit code.
+            int exitCode = Poco::Process::wait(handle);
+
+            if (exitCode != 0)
+            {
+                // If a module fails we log a warning message and continue.
+                std::wstringstream msg;
+                msg << L"TskExecutableModule::execute - Module (" << m_modulePath.c_str()
+                    << L") failed with exit code: " << exitCode;
+                LOGWARN(msg.str());
+            }
+        }
+        else
+        {
+            // No output file was specified.
+            Poco::ProcessHandle handle = Poco::Process::launch(m_modulePath, vectorArgs);
+
+            // Wait for the process to complete
+            int exitCode = Poco::Process::wait(handle);
+
+            if (exitCode != 0)
+            {
+                // If a module fails we log a warning message and continue.
+                std::wstringstream msg;
+                msg << L"TskExecutableModule::execute - Module (" << m_modulePath.c_str()
+                    << L") failed with exit code: " << exitCode;
+                LOGWARN(msg.str());
+            }
+        }
+    }
+    catch (Poco::Exception& ex)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskExecutableModule::execute - Error: " << ex.displayText().c_str();
+        LOGERROR(errorMsg.str());
+        throw TskException("Module execution failed.");
+    }
+
+    return TskModule::OK;
+}
diff --git a/framework/tsk/framework/pipeline/TskExecutableModule.h b/framework/tsk/framework/pipeline/TskExecutableModule.h
index 46facbf..376e271 100755
--- a/framework/tsk/framework/pipeline/TskExecutableModule.h
+++ b/framework/tsk/framework/pipeline/TskExecutableModule.h
@@ -1,46 +1,46 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-#ifndef _TSK_EXECUTABLEMODULE_H
-#define _TSK_EXECUTABLEMODULE_H
-
-#include "TskModule.h"
-
-/**
- * Supports launching a process via an executable file to perform
- * some analysis on a TskFile object in a TskPipeline.
- */
-class TSK_FRAMEWORK_API TskExecutableModule: public TskModule
-{
-public:
-    // Default Constructor
-    TskExecutableModule();
-
-    // Destructor
-    virtual ~TskExecutableModule();
-
-    virtual Status run(TskFile* fileToAnalyze);
-    virtual Status report();
-
-    /// Set the path of the executable to run.
-    virtual void setPath(const std::string& location);
-
-    /// Set the output location
-    void setOutput(const std::string& outFile);
-
-    std::string getOutput() const;
-
-private:
-    std::string m_output;
-    Status execute(TskFile* fileToAnalyze);
-
-};
-
-#endif
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+#ifndef _TSK_EXECUTABLEMODULE_H
+#define _TSK_EXECUTABLEMODULE_H
+
+#include "TskModule.h"
+
+/**
+ * Supports launching a process via an executable file to perform
+ * some analysis on a TskFile object in a TskPipeline.
+ */
+class TSK_FRAMEWORK_API TskExecutableModule: public TskModule
+{
+public:
+    // Default Constructor
+    TskExecutableModule();
+
+    // Destructor
+    virtual ~TskExecutableModule();
+
+    virtual Status run(TskFile* fileToAnalyze);
+    virtual Status report();
+
+    /// Set the path of the executable to run.
+    virtual void setPath(const std::string& location);
+
+    /// Set the output location
+    void setOutput(const std::string& outFile);
+
+    std::string getOutput() const;
+
+private:
+    std::string m_output;
+    Status execute(TskFile* fileToAnalyze);
+
+};
+
+#endif
diff --git a/framework/tsk/framework/pipeline/TskFileAnalysisPipeline.cpp b/framework/tsk/framework/pipeline/TskFileAnalysisPipeline.cpp
index e9ca1eb..694d08a 100755
--- a/framework/tsk/framework/pipeline/TskFileAnalysisPipeline.cpp
+++ b/framework/tsk/framework/pipeline/TskFileAnalysisPipeline.cpp
@@ -1,161 +1,161 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskFileAnalysisPipeline.cpp
- * Contains the implementation for the TskFileAnalysisPipeline class.
- */
-
-// Include the class definition first to ensure it does not depend on subsequent includes in this file.
-#include "TskFileAnalysisPipeline.h"
-
-// TSK Framework includes
-#include "tsk/framework/file/TskFileManagerImpl.h"
-#include "tsk/framework/services/TskServices.h"
-
-// Poco includes
-#include "Poco/AutoPtr.h"
-#include "Poco/Stopwatch.h"
-
-// C/C++ library includes
-#include <sstream>
-#include <memory>
-
-void TskFileAnalysisPipeline::run(const uint64_t fileId)
-{
-    // Get a file object for the given fileId
-    std::auto_ptr<TskFile> file(TskFileManagerImpl::instance().getFile(fileId));
-
-    if (m_modules.size() == 0){
-        file->setStatus(TskImgDB::IMGDB_FILES_STATUS_ANALYSIS_COMPLETE);
-        return;
-    }
-
-    // Run the file object through the pipeline.
-    run(file.get());
-}
-
-void TskFileAnalysisPipeline::run(TskFile* file)
-{
-    const std::string MSG_PREFIX = "TskFileAnalysisPipeline::run : ";
-
-    if (m_modules.size() == 0)
-        return;
-
-    if (file == NULL)
-    {
-        LOGERROR(MSG_PREFIX + "passed NULL file pointer");
-        throw TskNullPointerException();
-    }
-
-    TskImgDB& imgDB = TskServices::Instance().getImgDB();
-
-    try
-    {
-        // If this is an excluded file or the file is not ready for analysis
-        // we return without processing.
-        if (excludeFile(file))
-        {
-            std::stringstream msg;
-            msg << MSG_PREFIX << "skipping file (excluded) "  << file->getName() << "(" << file->getId() << ")";
-            LOGINFO(msg.str());
-            file->setStatus(TskImgDB::IMGDB_FILES_STATUS_ANALYSIS_SKIPPED);
-            return;
-        }
-
-        if (file->getStatus() != TskImgDB::IMGDB_FILES_STATUS_READY_FOR_ANALYSIS) 
-        {
-            std::stringstream msg;
-            msg << MSG_PREFIX << "skipping file (not ready) " << file->getName() << "(" << file->getId() << ")";
-            LOGINFO(msg.str());
-            return;
-        }
-
-        // Update status to indicate analysis is in progress.
-        file->setStatus(TskImgDB::IMGDB_FILES_STATUS_ANALYSIS_IN_PROGRESS);
-        std::stringstream msg;
-        msg << MSG_PREFIX <<  "analyzing " << file->getName() << "(" << file->getId() << ")";
-        LOGINFO(msg.str());
-
-        imgDB.begin();
-
-        // If there is an Executable module in the pipeline we must
-        // ensure that the file exists on disk.
-        if (m_hasExeModule && !file->exists())
-        {
-            TskFileManagerImpl::instance().saveFile(file);
-        }
-
-        bool bModuleFailed = false;
-
-        Poco::Stopwatch stopWatch;
-        for (size_t i = 0; i < m_modules.size(); i++)
-        {
-            // we have no way of knowing if the file was closed by a module,
-            // so always make sure it is open
-            file->open();
-
-            // Reset the file offset to the beginning of the file.
-            file->seek(0);
-
-            stopWatch.restart();
-            TskModule::Status status = m_modules[i]->run(file);
-            stopWatch.stop();            
-            updateModuleExecutionTime(m_modules[i]->getModuleId(), stopWatch.elapsed());
-            
-            imgDB.setModuleStatus(file->getId(), m_modules[i]->getModuleId(), (int)status);
-
-            // If any module encounters a failure while processing a file
-            // we will set the file status to failed once the pipeline is complete.
-            if (status == TskModule::FAIL)
-                bModuleFailed = true;
-
-            // Stop processing the file when a module tells us to.
-            else if (status == TskModule::STOP)
-                break;
-        }
-
-        // Delete the file if it exists. The file may have been created by us
-        // above or by a module that required it to exist on disk.
-        // Carved and derived files should not be deleted since the content is
-        // typically created by external tools.
-        if (file->getTypeId() != TskImgDB::IMGDB_FILES_TYPE_CARVED &&
-            file->getTypeId() != TskImgDB::IMGDB_FILES_TYPE_DERIVED &&
-            file->exists())
-        { 
-            TskFileManagerImpl::instance().deleteFile(file);
-        }
-
-        // We allow modules to set status on the file so we only update it
-        // if the modules haven't.
-        if (file->getStatus() == TskImgDB::IMGDB_FILES_STATUS_ANALYSIS_IN_PROGRESS)
-        {
-            if (bModuleFailed)
-            {
-                file->setStatus(TskImgDB::IMGDB_FILES_STATUS_ANALYSIS_FAILED);
-            }
-            else
-            {
-                file->setStatus(TskImgDB::IMGDB_FILES_STATUS_ANALYSIS_COMPLETE);
-            }
-        }
-        imgDB.commit();
-    }
-    catch (std::exception& ex)
-    {
-        std::stringstream msg;
-        msg << MSG_PREFIX << "error while processing file id (" << file->getId() << ") : " << ex.what();
-        LOGERROR(msg.str());
-        imgDB.updateFileStatus(file->getId(), TskImgDB::IMGDB_FILES_STATUS_ANALYSIS_FAILED);
-        imgDB.commit();
-        // Rethrow the exception
-        throw;
-    }
-}
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file TskFileAnalysisPipeline.cpp
+ * Contains the implementation for the TskFileAnalysisPipeline class.
+ */
+
+// Include the class definition first to ensure it does not depend on subsequent includes in this file.
+#include "TskFileAnalysisPipeline.h"
+
+// TSK Framework includes
+#include "tsk/framework/file/TskFileManagerImpl.h"
+#include "tsk/framework/services/TskServices.h"
+
+// Poco includes
+#include "Poco/AutoPtr.h"
+#include "Poco/Stopwatch.h"
+
+// C/C++ library includes
+#include <sstream>
+#include <memory>
+
+void TskFileAnalysisPipeline::run(const uint64_t fileId)
+{
+    // Get a file object for the given fileId
+    std::auto_ptr<TskFile> file(TskFileManagerImpl::instance().getFile(fileId));
+
+    if (m_modules.size() == 0){
+        file->setStatus(TskImgDB::IMGDB_FILES_STATUS_ANALYSIS_COMPLETE);
+        return;
+    }
+
+    // Run the file object through the pipeline.
+    run(file.get());
+}
+
+void TskFileAnalysisPipeline::run(TskFile* file)
+{
+    const std::string MSG_PREFIX = "TskFileAnalysisPipeline::run : ";
+
+    if (m_modules.size() == 0)
+        return;
+
+    if (file == NULL)
+    {
+        LOGERROR(MSG_PREFIX + "passed NULL file pointer");
+        throw TskNullPointerException();
+    }
+
+    TskImgDB& imgDB = TskServices::Instance().getImgDB();
+
+    try
+    {
+        // If this is an excluded file or the file is not ready for analysis
+        // we return without processing.
+        if (excludeFile(file))
+        {
+            std::stringstream msg;
+            msg << MSG_PREFIX << "skipping file (excluded) "  << file->getName() << "(" << file->getId() << ")";
+            LOGINFO(msg.str());
+            file->setStatus(TskImgDB::IMGDB_FILES_STATUS_ANALYSIS_SKIPPED);
+            return;
+        }
+
+        if (file->getStatus() != TskImgDB::IMGDB_FILES_STATUS_READY_FOR_ANALYSIS) 
+        {
+            std::stringstream msg;
+            msg << MSG_PREFIX << "skipping file (not ready) " << file->getName() << "(" << file->getId() << ")";
+            LOGINFO(msg.str());
+            return;
+        }
+
+        // Update status to indicate analysis is in progress.
+        file->setStatus(TskImgDB::IMGDB_FILES_STATUS_ANALYSIS_IN_PROGRESS);
+        std::stringstream msg;
+        msg << MSG_PREFIX <<  "analyzing " << file->getName() << "(" << file->getId() << ")";
+        LOGINFO(msg.str());
+
+        imgDB.begin();
+
+        // If there is an Executable module in the pipeline we must
+        // ensure that the file exists on disk.
+        if (m_hasExeModule && !file->exists())
+        {
+            TskFileManagerImpl::instance().saveFile(file);
+        }
+
+        bool bModuleFailed = false;
+
+        Poco::Stopwatch stopWatch;
+        for (size_t i = 0; i < m_modules.size(); i++)
+        {
+            // we have no way of knowing if the file was closed by a module,
+            // so always make sure it is open
+            file->open();
+
+            // Reset the file offset to the beginning of the file.
+            file->seek(0);
+
+            stopWatch.restart();
+            TskModule::Status status = m_modules[i]->run(file);
+            stopWatch.stop();            
+            updateModuleExecutionTime(m_modules[i]->getModuleId(), stopWatch.elapsed());
+            
+            imgDB.setModuleStatus(file->getId(), m_modules[i]->getModuleId(), (int)status);
+
+            // If any module encounters a failure while processing a file
+            // we will set the file status to failed once the pipeline is complete.
+            if (status == TskModule::FAIL)
+                bModuleFailed = true;
+
+            // Stop processing the file when a module tells us to.
+            else if (status == TskModule::STOP)
+                break;
+        }
+
+        // Delete the file if it exists. The file may have been created by us
+        // above or by a module that required it to exist on disk.
+        // Carved and derived files should not be deleted since the content is
+        // typically created by external tools.
+        if (file->getTypeId() != TskImgDB::IMGDB_FILES_TYPE_CARVED &&
+            file->getTypeId() != TskImgDB::IMGDB_FILES_TYPE_DERIVED &&
+            file->exists())
+        { 
+            TskFileManagerImpl::instance().deleteFile(file);
+        }
+
+        // We allow modules to set status on the file so we only update it
+        // if the modules haven't.
+        if (file->getStatus() == TskImgDB::IMGDB_FILES_STATUS_ANALYSIS_IN_PROGRESS)
+        {
+            if (bModuleFailed)
+            {
+                file->setStatus(TskImgDB::IMGDB_FILES_STATUS_ANALYSIS_FAILED);
+            }
+            else
+            {
+                file->setStatus(TskImgDB::IMGDB_FILES_STATUS_ANALYSIS_COMPLETE);
+            }
+        }
+        imgDB.commit();
+    }
+    catch (std::exception& ex)
+    {
+        std::stringstream msg;
+        msg << MSG_PREFIX << "error while processing file id (" << file->getId() << ") : " << ex.what();
+        LOGERROR(msg.str());
+        imgDB.updateFileStatus(file->getId(), TskImgDB::IMGDB_FILES_STATUS_ANALYSIS_FAILED);
+        imgDB.commit();
+        // Rethrow the exception
+        throw;
+    }
+}
diff --git a/framework/tsk/framework/pipeline/TskFileAnalysisPipeline.h b/framework/tsk/framework/pipeline/TskFileAnalysisPipeline.h
index f3ca7d1..c891d64 100755
--- a/framework/tsk/framework/pipeline/TskFileAnalysisPipeline.h
+++ b/framework/tsk/framework/pipeline/TskFileAnalysisPipeline.h
@@ -1,52 +1,52 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskFileAnalysisPipeline.h
- * Contains the interface for the TskFileAnalysisPipeline class.
- */
-
-#ifndef _TSK_FILEANALYSISPIPELINE_H
-#define _TSK_FILEANALYSISPIPELINE_H
-
-
-// TSK Framework includes
-#include "TskPipeline.h"
-#include "TskFileAnalysisPluginModule.h"
-
-// C/C++ library includes
-#include <string>
-
-/**
- * Controls the processing of a file analysis pipeline.  
- */
-class TSK_FRAMEWORK_API TskFileAnalysisPipeline : public TskPipeline
-{
-public:
-    // Doxygen comment in base class.
-    virtual void run(const uint64_t fileId);
-
-    // Doxygen comment in base class.
-    virtual void run(TskFile* file);
-
-    // Doxygen comment in base class.
-    virtual void run() 
-    { 
-        throw TskException("TskFileAnalysisPipeline::run : not implemented"); 
-    }
-
-    // Doxygen comment in base class.
-    TskPluginModule *createPluginModule() 
-    { 
-        return (new TskFileAnalysisPluginModule());
-    }
-};
-
-#endif
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file TskFileAnalysisPipeline.h
+ * Contains the interface for the TskFileAnalysisPipeline class.
+ */
+
+#ifndef _TSK_FILEANALYSISPIPELINE_H
+#define _TSK_FILEANALYSISPIPELINE_H
+
+
+// TSK Framework includes
+#include "TskPipeline.h"
+#include "TskFileAnalysisPluginModule.h"
+
+// C/C++ library includes
+#include <string>
+
+/**
+ * Controls the processing of a file analysis pipeline.  
+ */
+class TSK_FRAMEWORK_API TskFileAnalysisPipeline : public TskPipeline
+{
+public:
+    // Doxygen comment in base class.
+    virtual void run(const uint64_t fileId);
+
+    // Doxygen comment in base class.
+    virtual void run(TskFile* file);
+
+    // Doxygen comment in base class.
+    virtual void run() 
+    { 
+        throw TskException("TskFileAnalysisPipeline::run : not implemented"); 
+    }
+
+    // Doxygen comment in base class.
+    TskPluginModule *createPluginModule() 
+    { 
+        return (new TskFileAnalysisPluginModule());
+    }
+};
+
+#endif
diff --git a/framework/tsk/framework/pipeline/TskFileAnalysisPluginModule.cpp b/framework/tsk/framework/pipeline/TskFileAnalysisPluginModule.cpp
index 6d41743..abd19cb 100755
--- a/framework/tsk/framework/pipeline/TskFileAnalysisPluginModule.cpp
+++ b/framework/tsk/framework/pipeline/TskFileAnalysisPluginModule.cpp
@@ -1,100 +1,100 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskFileAnalysisPluginModule.cpp
- * Contains the implementation for the TskFileAnalysisPluginModule class.
- */
-
-// Include the class definition first to ensure it does not depend on subsequent includes in this file.
-#include "TskFileAnalysisPluginModule.h"
-
-// Framework includes
-#include "tsk/framework/services/TskServices.h"
-#include "tsk/framework/utilities/TskException.h"
-
-// C/C++ library includes
-#include <sstream>
-
-TskModule::Status TskFileAnalysisPluginModule::run(TskFile *fileToAnalyze)
-{
-    const std::string MSG_PREFIX = "TskFileAnalysisPluginModule::run : ";
-    TskModule::Status status = TskModule::OK;
-    try
-    {
-        if (!isLoaded())
-        {
-            std::stringstream msg;
-            msg << MSG_PREFIX << getPath() << " is not loaded";
-            throw TskException(msg.str());
-        }
-
-        if (!hasSymbol(TskPluginModule::RUN_SYMBOL)) 
-        {
-            std::stringstream msg;
-            msg << MSG_PREFIX << getPath() << " does not define the '" << TskPluginModule::RUN_SYMBOL << "' symbol";
-            throw TskException(msg.str());
-        }
-
-        typedef TskModule::Status (*RunFunc)(TskFile*);
-        RunFunc run = (RunFunc)getSymbol(TskPluginModule::RUN_SYMBOL);
-        status = run(fileToAnalyze);
-    }
-    catch (TskException &ex) 
-    {
-        std::stringstream msg;
-        msg << MSG_PREFIX << "TskException executing run function of " << getName() << ": " << ex.message();
-        LOGERROR(msg.str());
-        status = TskModule::FAIL;
-    }
-    catch (Poco::Exception &ex) 
-    {
-        std::stringstream msg;
-        msg << MSG_PREFIX <<  "Poco::Exception executing run function of "  << getName() << ": " << ex.displayText();
-        LOGERROR(msg.str());
-        status = TskModule::FAIL;
-    }
-    catch (std::exception &ex) 
-    {
-        std::stringstream msg;
-        msg << MSG_PREFIX <<  "std::exception executing run function of "  << getName() << ": " << ex.what();
-        LOGERROR(msg.str());
-        status = TskModule::FAIL;
-    }
-    catch (...)
-    {
-        std::stringstream msg;
-        msg << MSG_PREFIX << "unrecognized exception executing run function of "  << getName();
-        LOGERROR(msg.str());
-        status = TskModule::FAIL;
-    }
-
-    return status;
-}
-
-void TskFileAnalysisPluginModule::checkInterface()
-{
-    const std::string MSG_PREFIX = "TskFileAnalysisPluginModule::checkInterface : ";
-
-    if (!isLoaded())
-    {
-        std::stringstream msg;
-        msg << MSG_PREFIX << getPath() << " is not loaded";
-        LOGERROR(msg.str());
-        throw TskException(msg.str());
-    }
-
-    if (!hasSymbol(TskPluginModule::RUN_SYMBOL)) 
-    {
-        std::stringstream msg;
-        msg << MSG_PREFIX << getPath() << " does not define the required '" << TskPluginModule::RUN_SYMBOL << "' symbol";
-        throw TskException(msg.str());
-    }
-}
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file TskFileAnalysisPluginModule.cpp
+ * Contains the implementation for the TskFileAnalysisPluginModule class.
+ */
+
+// Include the class definition first to ensure it does not depend on subsequent includes in this file.
+#include "TskFileAnalysisPluginModule.h"
+
+// Framework includes
+#include "tsk/framework/services/TskServices.h"
+#include "tsk/framework/utilities/TskException.h"
+
+// C/C++ library includes
+#include <sstream>
+
+TskModule::Status TskFileAnalysisPluginModule::run(TskFile *fileToAnalyze)
+{
+    const std::string MSG_PREFIX = "TskFileAnalysisPluginModule::run : ";
+    TskModule::Status status = TskModule::OK;
+    try
+    {
+        if (!isLoaded())
+        {
+            std::stringstream msg;
+            msg << MSG_PREFIX << getPath() << " is not loaded";
+            throw TskException(msg.str());
+        }
+
+        if (!hasSymbol(TskPluginModule::RUN_SYMBOL)) 
+        {
+            std::stringstream msg;
+            msg << MSG_PREFIX << getPath() << " does not define the '" << TskPluginModule::RUN_SYMBOL << "' symbol";
+            throw TskException(msg.str());
+        }
+
+        typedef TskModule::Status (*RunFunc)(TskFile*);
+        RunFunc run = (RunFunc)getSymbol(TskPluginModule::RUN_SYMBOL);
+        status = run(fileToAnalyze);
+    }
+    catch (TskException &ex) 
+    {
+        std::stringstream msg;
+        msg << MSG_PREFIX << "TskException executing run function of " << getName() << ": " << ex.message();
+        LOGERROR(msg.str());
+        status = TskModule::FAIL;
+    }
+    catch (Poco::Exception &ex) 
+    {
+        std::stringstream msg;
+        msg << MSG_PREFIX <<  "Poco::Exception executing run function of "  << getName() << ": " << ex.displayText();
+        LOGERROR(msg.str());
+        status = TskModule::FAIL;
+    }
+    catch (std::exception &ex) 
+    {
+        std::stringstream msg;
+        msg << MSG_PREFIX <<  "std::exception executing run function of "  << getName() << ": " << ex.what();
+        LOGERROR(msg.str());
+        status = TskModule::FAIL;
+    }
+    catch (...)
+    {
+        std::stringstream msg;
+        msg << MSG_PREFIX << "unrecognized exception executing run function of "  << getName();
+        LOGERROR(msg.str());
+        status = TskModule::FAIL;
+    }
+
+    return status;
+}
+
+void TskFileAnalysisPluginModule::checkInterface()
+{
+    const std::string MSG_PREFIX = "TskFileAnalysisPluginModule::checkInterface : ";
+
+    if (!isLoaded())
+    {
+        std::stringstream msg;
+        msg << MSG_PREFIX << getPath() << " is not loaded";
+        LOGERROR(msg.str());
+        throw TskException(msg.str());
+    }
+
+    if (!hasSymbol(TskPluginModule::RUN_SYMBOL)) 
+    {
+        std::stringstream msg;
+        msg << MSG_PREFIX << getPath() << " does not define the required '" << TskPluginModule::RUN_SYMBOL << "' symbol";
+        throw TskException(msg.str());
+    }
+}
diff --git a/framework/tsk/framework/pipeline/TskFileAnalysisPluginModule.h b/framework/tsk/framework/pipeline/TskFileAnalysisPluginModule.h
index 7b628f2..6d99df7 100755
--- a/framework/tsk/framework/pipeline/TskFileAnalysisPluginModule.h
+++ b/framework/tsk/framework/pipeline/TskFileAnalysisPluginModule.h
@@ -1,31 +1,31 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-#ifndef _TSK_FILEANALYSISPLUGINMODULE_H
-#define _TSK_FILEANALYSISPLUGINMODULE_H
-
-// TSK Framework includes
-#include "TskPluginModule.h"
-
-/**
- * Supports the loading of custom dynamic libraries to perform
- * analysis on a single TskFile
- */
-class TSK_FRAMEWORK_API TskFileAnalysisPluginModule: public TskPluginModule
-{
-public:
-    // Doxygen comment in base class.
-    virtual Status run(TskFile *fileToAnalyze);
-
-    // Doxygen comment in base class.
-    virtual void checkInterface();
-};
-
-#endif
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+#ifndef _TSK_FILEANALYSISPLUGINMODULE_H
+#define _TSK_FILEANALYSISPLUGINMODULE_H
+
+// TSK Framework includes
+#include "TskPluginModule.h"
+
+/**
+ * Supports the loading of custom dynamic libraries to perform
+ * analysis on a single TskFile
+ */
+class TSK_FRAMEWORK_API TskFileAnalysisPluginModule: public TskPluginModule
+{
+public:
+    // Doxygen comment in base class.
+    virtual Status run(TskFile *fileToAnalyze);
+
+    // Doxygen comment in base class.
+    virtual void checkInterface();
+};
+
+#endif
diff --git a/framework/tsk/framework/pipeline/TskModule.cpp b/framework/tsk/framework/pipeline/TskModule.cpp
index 643a684..ee9ee98 100755
--- a/framework/tsk/framework/pipeline/TskModule.cpp
+++ b/framework/tsk/framework/pipeline/TskModule.cpp
@@ -1,114 +1,114 @@
-/*
- *
- *  The Sleuth Kit
- *
- *  Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- *  Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- *  reserved.
- *
- *  This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskModule.cpp
- * Contains the implementation for the TskModule base class.
- */
-
-#include <sstream>
-
-#include "TskModule.h"
-#include "tsk/framework/services/TskServices.h"
-#include "tsk/framework/services/TskSystemProperties.h"
-
-#include "Poco/String.h"
-#include "Poco/Environment.h"
-#include "Poco/Path.h"
-#include "Poco/File.h"
-
-const std::string TskModule::CURRENT_FILE_MACRO = "#CURRENT_FILE#";
-
-TskModule::TskModule() : m_moduleId(0)
-{
-}
-
-TskModule::~TskModule()
-{
-}
-
-/**
- * Sets the location of the module given an absolute or relative location.
- * For relative paths we look for the
- * module first in PROG_DIR, then MODULE_DIR, then the
- * current directory, and 
- * finally the system path. Will throw an exception if the module cannot 
- * be found.
- * @param location Absolute or relative path string for module.
- */
-void TskModule::setPath(const std::string& location)
-{
-    if (location.empty()) 
-    {
-        throw TskException("TskModule::setPath: location is empty or missing.");
-    }
-
-    Poco::Path tempPath = location;
-
-    if (!tempPath.isAbsolute())
-    {
-        // If this is a relative path, then see if we can find the
-        // executable either in PROG_DIR, in MODULE_DIR, in the current directory,
-        // or on the system path.        
-        std::string pathsToSearch = GetSystemProperty(TskSystemProperties::PROG_DIR); 
-        if (!pathsToSearch.empty())
-            pathsToSearch += Poco::Path::pathSeparator();
-        pathsToSearch += GetSystemProperty(TskSystemProperties::MODULE_DIR);
-        if (!pathsToSearch.empty())
-            pathsToSearch += Poco::Path::pathSeparator();
-        pathsToSearch += ".";
-
-        if (!Poco::Path::find(pathsToSearch, location, tempPath))
-        {
-            // if we didn't find them in the above paths, check on the path. 
-            if (Poco::Environment::has("Path"))
-            {
-                std::string systemPath = Poco::Environment::get("Path");
-            
-                if (!systemPath.empty())
-                {
-                    Poco::Path::find(systemPath, location, tempPath);
-                }
-            }
-        }
-    }
-
-    // Confirm existence of file at location.
-    Poco::File moduleFile(tempPath);
-
-    if (!moduleFile.exists())
-    {
-        std::stringstream msg;
-        msg << "TskModule::setPath - Module not found: "
-            << tempPath.toString().c_str();
-        throw TskException(msg.str());
-    }
-    else {
-        std::wstringstream msg;
-        msg << L"TskModule::setPath - Module found at: "
-            << tempPath.toString().c_str();
-        LOGINFO(msg.str());
-    }
-
-    m_modulePath = tempPath.toString();
-}
-
-std::string TskModule::expandArgumentMacros(const std::string &args, const TskFile *fileToAnalyze)
-{
-    std::string outputStr = args;
-
-    if (fileToAnalyze)
-    {
-        Poco::replaceInPlace(outputStr, TskModule::CURRENT_FILE_MACRO, fileToAnalyze->getPath());
-    }
-
-    return ExpandSystemPropertyMacros(outputStr);
-}
+/*
+ *
+ *  The Sleuth Kit
+ *
+ *  Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ *  Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ *  reserved.
+ *
+ *  This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file TskModule.cpp
+ * Contains the implementation for the TskModule base class.
+ */
+
+#include <sstream>
+
+#include "TskModule.h"
+#include "tsk/framework/services/TskServices.h"
+#include "tsk/framework/services/TskSystemProperties.h"
+
+#include "Poco/String.h"
+#include "Poco/Environment.h"
+#include "Poco/Path.h"
+#include "Poco/File.h"
+
+const std::string TskModule::CURRENT_FILE_MACRO = "#CURRENT_FILE#";
+
+TskModule::TskModule() : m_moduleId(0)
+{
+}
+
+TskModule::~TskModule()
+{
+}
+
+/**
+ * Sets the location of the module given an absolute or relative location.
+ * For relative paths we look for the
+ * module first in PROG_DIR, then MODULE_DIR, then the
+ * current directory, and 
+ * finally the system path. Will throw an exception if the module cannot 
+ * be found.
+ * @param location Absolute or relative path string for module.
+ */
+void TskModule::setPath(const std::string& location)
+{
+    if (location.empty()) 
+    {
+        throw TskException("TskModule::setPath: location is empty or missing.");
+    }
+
+    Poco::Path tempPath = location;
+
+    if (!tempPath.isAbsolute())
+    {
+        // If this is a relative path, then see if we can find the
+        // executable either in PROG_DIR, in MODULE_DIR, in the current directory,
+        // or on the system path.        
+        std::string pathsToSearch = GetSystemProperty(TskSystemProperties::PROG_DIR); 
+        if (!pathsToSearch.empty())
+            pathsToSearch += Poco::Path::pathSeparator();
+        pathsToSearch += GetSystemProperty(TskSystemProperties::MODULE_DIR);
+        if (!pathsToSearch.empty())
+            pathsToSearch += Poco::Path::pathSeparator();
+        pathsToSearch += ".";
+
+        if (!Poco::Path::find(pathsToSearch, location, tempPath))
+        {
+            // if we didn't find them in the above paths, check on the path. 
+            if (Poco::Environment::has("Path"))
+            {
+                std::string systemPath = Poco::Environment::get("Path");
+            
+                if (!systemPath.empty())
+                {
+                    Poco::Path::find(systemPath, location, tempPath);
+                }
+            }
+        }
+    }
+
+    // Confirm existence of file at location.
+    Poco::File moduleFile(tempPath);
+
+    if (!moduleFile.exists())
+    {
+        std::stringstream msg;
+        msg << "TskModule::setPath - Module not found: "
+            << tempPath.toString().c_str();
+        throw TskException(msg.str());
+    }
+    else {
+        std::wstringstream msg;
+        msg << L"TskModule::setPath - Module found at: "
+            << tempPath.toString().c_str();
+        LOGINFO(msg.str());
+    }
+
+    m_modulePath = tempPath.toString();
+}
+
+std::string TskModule::expandArgumentMacros(const std::string &args, const TskFile *fileToAnalyze)
+{
+    std::string outputStr = args;
+
+    if (fileToAnalyze)
+    {
+        Poco::replaceInPlace(outputStr, TskModule::CURRENT_FILE_MACRO, fileToAnalyze->getPath());
+    }
+
+    return ExpandSystemPropertyMacros(outputStr);
+}
diff --git a/framework/tsk/framework/pipeline/TskModule.h b/framework/tsk/framework/pipeline/TskModule.h
index dde738d..972db0d 100755
--- a/framework/tsk/framework/pipeline/TskModule.h
+++ b/framework/tsk/framework/pipeline/TskModule.h
@@ -1,107 +1,107 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskModule.h
- * Contains the interface for the Module class.
- */
-
-#ifndef _TSK_MODULE_H
-#define _TSK_MODULE_H
-
-#include "tsk/framework/file/TskFile.h"
-
-/**
- * Interface for classes that represent different types of modules
- * in the pipeline. Example module types include dynamic library
- * and executables. These modules perform some operation in the
- * context of a TskPipeline.
- */
-class TSK_FRAMEWORK_API TskModule
-{
-public:
-    /**
-     * The TskModule class supports the use of a string macro that is expanded
-     * to the path of the file currently under analysis. This macro is intended
-     * to be used in the arguments strings passed to the initialization
-     * functions of file analysis modules. "#CURRENT_FILE#" is the literal form
-     * of the macro.
-     */
-    static const std::string CURRENT_FILE_MACRO;
-
-    /// Standard values that module methods can return.
-    enum Status
-    {
-        OK = 0, ///< Indicates that the module sucessfully analyzed the data or was able to decide that it should not analyze the data.
-        FAIL, ///< Indicates that the module wanted to perform analysis on the data, but was unable to because of an error.  
-        STOP  ///< Indicates that the module wants the pipeline to stop processing. 
-    };
-
-    // Default Constructor
-    TskModule();
-
-    // Virtual destructor since Module must be subclassed to be useful
-    virtual ~TskModule();
-
-    /**
-     * Method that is used to run file analysis modules.
-     * @returns Status of module
-     */
-    virtual Status run(TskFile* fileToAnalyze) = 0;
-
-    /**
-     * Method that is used to run report modules.
-     * @returns Status of module
-     */
-    virtual Status report() { return TskModule::OK; };
-
-    virtual void setPath(const std::string& location);
-
-    /**
-     * Returns the fully qualified path to the module.
-     */
-    virtual std::string getPath() const { return m_modulePath; }
-
-    /// Set the arguments to be passed to the module.
-    void setArguments(const std::string& args) { m_arguments = args; }
-
-    /// Get the arguments
-    std::string getArguments() const { return m_arguments; }
-
-    /// Get the module name
-    std::string getName() const { return m_name; }
-
-    /// Get the module description
-    std::string getDescription() const { return m_description; }
-
-    /// Get the module version
-    std::string getVersion() const { return m_version; }
-
-    /// Set the module id
-    void setModuleId(int moduleId) { m_moduleId = moduleId; }
-
-    /// Get the module id
-    int getModuleId() const { return m_moduleId; }
-
-protected:
-    std::string m_modulePath;
-    std::string m_arguments;
-    std::string m_name;
-    std::string m_description;
-    std::string m_version;
-    int m_moduleId;
-
-    static std::string expandArgumentMacros(const std::string &args, const TskFile *fileToAnalyze);
-
-private:
-
-};
-
-#endif
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file TskModule.h
+ * Contains the interface for the Module class.
+ */
+
+#ifndef _TSK_MODULE_H
+#define _TSK_MODULE_H
+
+#include "tsk/framework/file/TskFile.h"
+
+/**
+ * Interface for classes that represent different types of modules
+ * in the pipeline. Example module types include dynamic library
+ * and executables. These modules perform some operation in the
+ * context of a TskPipeline.
+ */
+class TSK_FRAMEWORK_API TskModule
+{
+public:
+    /**
+     * The TskModule class supports the use of a string macro that is expanded
+     * to the path of the file currently under analysis. This macro is intended
+     * to be used in the arguments strings passed to the initialization
+     * functions of file analysis modules. "#CURRENT_FILE#" is the literal form
+     * of the macro.
+     */
+    static const std::string CURRENT_FILE_MACRO;
+
+    /// Standard values that module methods can return.
+    enum Status
+    {
+        OK = 0, ///< Indicates that the module sucessfully analyzed the data or was able to decide that it should not analyze the data.
+        FAIL, ///< Indicates that the module wanted to perform analysis on the data, but was unable to because of an error.  
+        STOP  ///< Indicates that the module wants the pipeline to stop processing. 
+    };
+
+    // Default Constructor
+    TskModule();
+
+    // Virtual destructor since Module must be subclassed to be useful
+    virtual ~TskModule();
+
+    /**
+     * Method that is used to run file analysis modules.
+     * @returns Status of module
+     */
+    virtual Status run(TskFile* fileToAnalyze) = 0;
+
+    /**
+     * Method that is used to run report modules.
+     * @returns Status of module
+     */
+    virtual Status report() { return TskModule::OK; };
+
+    virtual void setPath(const std::string& location);
+
+    /**
+     * Returns the fully qualified path to the module.
+     */
+    virtual std::string getPath() const { return m_modulePath; }
+
+    /// Set the arguments to be passed to the module.
+    void setArguments(const std::string& args) { m_arguments = args; }
+
+    /// Get the arguments
+    std::string getArguments() const { return m_arguments; }
+
+    /// Get the module name
+    std::string getName() const { return m_name; }
+
+    /// Get the module description
+    std::string getDescription() const { return m_description; }
+
+    /// Get the module version
+    std::string getVersion() const { return m_version; }
+
+    /// Set the module id
+    void setModuleId(int moduleId) { m_moduleId = moduleId; }
+
+    /// Get the module id
+    int getModuleId() const { return m_moduleId; }
+
+protected:
+    std::string m_modulePath;
+    std::string m_arguments;
+    std::string m_name;
+    std::string m_description;
+    std::string m_version;
+    int m_moduleId;
+
+    static std::string expandArgumentMacros(const std::string &args, const TskFile *fileToAnalyze);
+
+private:
+
+};
+
+#endif
diff --git a/framework/tsk/framework/pipeline/TskPipeline.cpp b/framework/tsk/framework/pipeline/TskPipeline.cpp
index c6a9ca8..b0fafc3 100755
--- a/framework/tsk/framework/pipeline/TskPipeline.cpp
+++ b/framework/tsk/framework/pipeline/TskPipeline.cpp
@@ -1,307 +1,307 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskPipeline.cpp
- * Contains the implementation for the TskPipeline class.
- */
-
-// Include the class definition first to ensure it does not depend on subsequent includes in this file.
-#include "TskPipeline.h"
-
-// TSK Framework includes
-#include "TskExecutableModule.h"
-#include "TskPluginModule.h"
-#include "tsk/framework/file/TskFileManagerImpl.h"
-#include "tsk/framework/services/TskServices.h"
-#include "tsk/framework/utilities/TskException.h"
-#include "tsk/framework/utilities/TskUtilities.h"
-
-// Poco includes
-#include "Poco/AutoPtr.h"
-#include "Poco/NumberParser.h"
-#include "Poco/DOM/DOMParser.h"
-#include "Poco/DOM/NodeList.h"
-#include "Poco/DOM/Document.h"
-#include "Poco/UnicodeConverter.h"
-
-// C/C++ library includes
-#include <sstream>
-#include <assert.h>
-#include <memory>
-
-const std::string TskPipeline::MODULE_ELEMENT = "MODULE";
-const std::string TskPipeline::MODULE_TYPE_ATTR = "type";
-const std::string TskPipeline::MODULE_ORDER_ATTR = "order";
-const std::string TskPipeline::MODULE_LOCATION_ATTR = "location";
-const std::string TskPipeline::MODULE_ARGS_ATTR = "arguments";
-const std::string TskPipeline::MODULE_OUTPUT_ATTR = "output";
-const std::string TskPipeline::MODULE_EXECUTABLE_TYPE = "executable";
-const std::string TskPipeline::MODULE_PLUGIN_TYPE = "plugin";
-
-TskPipeline::TskPipeline() : m_hasExeModule(false), m_loadDll(true)
-{
-}
-
-TskPipeline::~TskPipeline()
-{
-    // Delete modules
-    for (std::vector<TskModule*>::iterator it = m_modules.begin(); it != m_modules.end(); it++)
-        delete *it;
-}
-
-void TskPipeline::validate(const std::string & pipelineConfig)
-{
-    m_loadDll = false;
-    initialize(pipelineConfig);
-}
-
-void TskPipeline::initialize(const std::string & pipelineConfig)
-{
-    if (pipelineConfig.empty())
-    {
-        throw TskException("TskPipeline::initialize: Pipeline configuration string is empty.");
-    }
-
-    try
-    {
-        Poco::XML::DOMParser parser;
-        Poco::AutoPtr<Poco::XML::Document> xmlDoc = parser.parseString(pipelineConfig);
-
-        // Get all Module elements
-        Poco::AutoPtr<Poco::XML::NodeList> modules = 
-            xmlDoc->getElementsByTagName(TskPipeline::MODULE_ELEMENT);
-
-        if (modules->length() == 0)
-        {
-            LOGWARN(L"TskPipeline::initialize - No modules found in config file.");
-            return;
-        }
-
-        // Size our list based on the number of modules
-        m_modules.resize(modules->length());
-
-        // Iterate through the module elements, make sure they are increasing order
-        // we now allow for gaps to make it easier to comment things out.
-        int prevOrder = -1;
-        for (unsigned int i = 0; i < modules->length(); i++)
-        {
-            Poco::XML::Node * pNode = modules->item(i);
-            Poco::XML::Element* pElem = dynamic_cast<Poco::XML::Element*>(pNode);
-            Poco::XML::XMLString orderStr = pElem->getAttribute(TskPipeline::MODULE_ORDER_ATTR);
-            if (orderStr == "") {
-                throw TskException("TskPipeline::initialize: Module order missing.");
-            }
-            int order;
-            try 
-            {
-                order = Poco::NumberParser::parse(orderStr);
-            } catch (Poco::SyntaxException ex) 
-            {
-                std::stringstream msg;
-                msg << "TskPipeline::initialize - Module order must a decimal number. Got " << orderStr.c_str();
-                throw TskException(msg.str());
-            }
-            if (order <= prevOrder) 
-            {
-                std::stringstream msg;
-                msg << "TskPipeline::initialize - Expecting order bigger than " << prevOrder << ", got " << order;
-                throw TskException(msg.str());
-            }
-            prevOrder = order;
-        }
-
-        // Iterate through the module elements creating a new Module for each one
-        m_modules.clear();
-        for (unsigned int i = 0; i < modules->length(); i++)
-        {
-            Poco::XML::Node * pNode = modules->item(i);
-            Poco::XML::Element* pElem = dynamic_cast<Poco::XML::Element*>(pNode);
-
-            if (!pElem)
-                continue;
-
-            // Create a new module
-            TskModule * pModule = createModule(pElem);
-
-            if (pModule == NULL)
-            {
-                throw TskException("TskPipeline::initialize - Module creation failed.");
-            }
-
-            if (m_loadDll) 
-            {
-                TskImgDB& imgDB = TskServices::Instance().getImgDB();
-
-                // Insert into Modules table
-                int moduleId = 0;
-                if (imgDB.addModule(pModule->getName(), pModule->getDescription(), moduleId)) 
-                {
-                    std::stringstream errorMsg;
-                    errorMsg << "TskPipeline::initialize - Failed to insert into Modules table. "  
-                             << " module name=" << pModule->getName() ;
-                    throw TskException(errorMsg.str());
-                } 
-                else 
-                {
-                    pModule->setModuleId(moduleId);
-                    m_moduleNames.insert(std::make_pair(moduleId, pModule->getName()));
-                    m_moduleExecTimes.insert(std::make_pair(moduleId, Poco::Timespan()));
-                }
-                bool duplicate = false;
-                for (std::vector<TskModule*>::iterator it = m_modules.begin(); it != m_modules.end(); it++) {
-                    if ((*it)->getModuleId() == pModule->getModuleId()) {
-                        duplicate = true;
-                        std::stringstream msg;
-                        msg << "TskPipeline::initialize - " << pModule->getName() << " is a duplicate module. " <<
-                            "The duplicate will not be added to the pipeline";
-                        throw TskException(msg.str());
-                    }
-                }
-                if (!duplicate)
-                    m_modules.push_back(pModule);
-            }
-        }
-    }
-    // rethrow this, otherwise it is caught by std::exception and we lose the detail.
-    catch (TskException& ex) {
-        throw(ex);
-    }
-    catch (std::exception& ex)
-    {
-        std::stringstream errorMsg;
-        errorMsg << "TskPipeline::initialize - Pipeline initialization failed: " <<ex.what() ;
-        throw TskException(errorMsg.str());
-    }
-}
-
-TskModule * TskPipeline::createModule(Poco::XML::Element *pElem)
-{
-    if (!pElem)
-    {
-        LOGERROR(L"TskPipeline::createModule - Passed NULL Element.");
-        return NULL;
-    }
-
-    try
-    {
-        if (pElem->getAttribute(TskPipeline::MODULE_TYPE_ATTR) == MODULE_EXECUTABLE_TYPE)
-        {
-            // Use auto_ptr to ensure that module will be deleted if there 
-            // are exceptions.
-            std::auto_ptr<TskExecutableModule> pModule(new TskExecutableModule());
-            std::string location(pElem->getAttribute(TskPipeline::MODULE_LOCATION_ATTR));
-            pModule->setPath(location);
-            //pModule->setPath(pElem->getAttribute(TskPipeline::MODULE_LOCATION_ATTR));
-            pModule->setArguments(pElem->getAttribute(TskPipeline::MODULE_ARGS_ATTR));
-            pModule->setOutput(pElem->getAttribute(TskPipeline::MODULE_OUTPUT_ATTR));
-
-            m_hasExeModule = true;
-
-            // The module was successfully created so we no longer need the
-            // auto_ptr to manage it.
-            return pModule.release();
-        }
-        else if (pElem->getAttribute(TskPipeline::MODULE_TYPE_ATTR) == MODULE_PLUGIN_TYPE)
-        {
-            std::auto_ptr<TskPluginModule> pModule(createPluginModule());
-            pModule->setPath(pElem->getAttribute(TskPipeline::MODULE_LOCATION_ATTR));
-            pModule->setArguments(pElem->getAttribute(TskPipeline::MODULE_ARGS_ATTR));
-            pModule->checkInterface();
-
-            // Initialize the module.
-            if (m_loadDll)
-            {
-                if (pModule->initialize() != TskModule::OK)
-                {
-                    return NULL;
-                }
-            }
-
-            // The module was successfully created and initialized so we no longer
-            // need the auto_ptr to manage it.
-            return pModule.release();
-        }
-        else
-        {
-            std::wstringstream errorMsg;
-            errorMsg << "TskPipeline::createModule - Unrecognized module type : "
-                << pElem->getAttribute(TskPipeline::MODULE_TYPE_ATTR).c_str();
-            LOGERROR(errorMsg.str());
-
-            return NULL;
-        }
-    }
-    catch (TskException& ex)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskPipeline::createModule - Module creation failed: " << pElem->getAttribute(TskPipeline::MODULE_LOCATION_ATTR).c_str() << L" ("<< ex.message().c_str()<< L")";
-        LOGERROR(errorMsg.str());
-        return NULL;
-    }
-    catch (std::exception & ex)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskPipeline::createModule - Module creation failed: " << pElem->getAttribute(TskPipeline::MODULE_LOCATION_ATTR).c_str() << L" ("<< ex.what() << L")";
-        LOGERROR(errorMsg.str());
-        return NULL;
-    }
-    catch (...)
-    {
-        std::wstringst