[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::wstringstream errorMsg;
-        errorMsg << L"TskPipeline::createModule - Unnkown exception : " << pElem->getAttribute(TskPipeline::MODULE_LOCATION_ATTR).c_str() ;
-        LOGERROR(errorMsg.str());
-        return NULL;
-    }
-
-}
-
-void TskPipeline::logModuleExecutionTimes() const
-{
-    for (std::map<int, Poco::Timespan>::const_iterator it = m_moduleExecTimes.begin(); it != m_moduleExecTimes.end(); ++it)
-    {
-        assert(m_moduleNames.find(it->first) != m_moduleNames.end());
-        std::stringstream msg;
-        msg << "TskPipeline::logModuleExecutionTimes : "  << m_moduleNames.find(it->first)->second << " total execution time was "
-        << it->second.days() << ":" << it->second.hours() << ":" << it->second.minutes() << ":" << it->second.seconds() << ":" << it->second.milliseconds()
-        << " (days:hrs:mins:secs:ms)";
-        LOGINFO(msg.str());
-    }
-}
-
-bool TskPipeline::excludeFile(const TskFile* file)
-{
-    if (file == NULL)
-    {
-        LOGERROR(L"TskPipeline::excludeFile - Passed NULL file pointer.");
-        throw TskNullPointerException();
-    }
-
-    // Exclude directories and Sleuthkit "virtual" files from analysis.
-    if (file->isDirectory() || file->isVirtual())
-        return true;
-
-    return false;
-}
-
-void TskPipeline::updateModuleExecutionTime(int moduleId, const Poco::Timespan::TimeDiff &executionTime)
-{
-    std::map<int, Poco::Timespan>::iterator it = m_moduleExecTimes.find(moduleId);
-    if (it != m_moduleExecTimes.end())
-    {
-        it->second += executionTime;
-    }
-    else
-    {
-        std::stringstream msg;
-        msg << "TskPipeline::updateModuleExecutionTime : unknown moduleId " << moduleId;
-        LOGERROR(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 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::wstringstream errorMsg;
+        errorMsg << L"TskPipeline::createModule - Unnkown exception : " << pElem->getAttribute(TskPipeline::MODULE_LOCATION_ATTR).c_str() ;
+        LOGERROR(errorMsg.str());
+        return NULL;
+    }
+
+}
+
+void TskPipeline::logModuleExecutionTimes() const
+{
+    for (std::map<int, Poco::Timespan>::const_iterator it = m_moduleExecTimes.begin(); it != m_moduleExecTimes.end(); ++it)
+    {
+        assert(m_moduleNames.find(it->first) != m_moduleNames.end());
+        std::stringstream msg;
+        msg << "TskPipeline::logModuleExecutionTimes : "  << m_moduleNames.find(it->first)->second << " total execution time was "
+        << it->second.days() << ":" << it->second.hours() << ":" << it->second.minutes() << ":" << it->second.seconds() << ":" << it->second.milliseconds()
+        << " (days:hrs:mins:secs:ms)";
+        LOGINFO(msg.str());
+    }
+}
+
+bool TskPipeline::excludeFile(const TskFile* file)
+{
+    if (file == NULL)
+    {
+        LOGERROR(L"TskPipeline::excludeFile - Passed NULL file pointer.");
+        throw TskNullPointerException();
+    }
+
+    // Exclude directories and Sleuthkit "virtual" files from analysis.
+    if (file->isDirectory() || file->isVirtual())
+        return true;
+
+    return false;
+}
+
+void TskPipeline::updateModuleExecutionTime(int moduleId, const Poco::Timespan::TimeDiff &executionTime)
+{
+    std::map<int, Poco::Timespan>::iterator it = m_moduleExecTimes.find(moduleId);
+    if (it != m_moduleExecTimes.end())
+    {
+        it->second += executionTime;
+    }
+    else
+    {
+        std::stringstream msg;
+        msg << "TskPipeline::updateModuleExecutionTime : unknown moduleId " << moduleId;
+        LOGERROR(msg.str());
+    }
+}
diff --git a/framework/tsk/framework/pipeline/TskPipeline.h b/framework/tsk/framework/pipeline/TskPipeline.h
index 4764634..f904c6f 100755
--- a/framework/tsk/framework/pipeline/TskPipeline.h
+++ b/framework/tsk/framework/pipeline/TskPipeline.h
@@ -1,160 +1,160 @@
-/*
- * 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.h
- * Contains the declarations for the TskPipeline class and the interface for methods
- * that are defined in the various implementations.
- */
-
-#ifndef _TSK_PIPELINE_H
-#define _TSK_PIPELINE_H
-
-// TSK includes
-#include "tsk/base/tsk_os.h" // for uint64_t
-
-// TSK Framework includes
-#include "TskModule.h"
-#include "TskPluginModule.h"
-
-// Poco includes
-#include "Poco/DOM/Element.h"
-#include "Poco/Timespan.h"
-
-// C/C++ library includes
-#include <list>
-#include <string>
-#include <map>
-
-/**
- * The Pipeline class controls the processing of data
- * through an ordered list of dynamic library or executable modules.
- * Different types of pipeline implementations exist for the different types of data. 
- * Pipelines are created by the TskPipelineManager class. 
- */
-class TSK_FRAMEWORK_API TskPipeline
-{
-public:
-    // DEVELOPERS: Changes to any of these elements and attributes require an update to $(TSK_HOME)\framework\docs\pipeline.dox 
-    static const std::string MODULE_ELEMENT; ///< module element in XML config file
-    static const std::string MODULE_TYPE_ATTR;  ///< attribute for module type in XML config file
-    static const std::string MODULE_ORDER_ATTR; ///< attribute for module order in XML config file
-    static const std::string MODULE_LOCATION_ATTR; ///< attribute for module location in XML config file
-    static const std::string MODULE_ARGS_ATTR; ///< attribute for module arguments in XML config file
-    static const std::string MODULE_OUTPUT_ATTR; ///< attribute for module output in XML config file
-    static const std::string MODULE_EXECUTABLE_TYPE; ///< value of MODULE_TYPE_ATTR for executable modules
-    static const std::string MODULE_PLUGIN_TYPE; ///< value of MODULE_TYPE_ATTR for library modules
-
-    /**
-     * Default constructor.
-     */
-    TskPipeline();
-
-    /**
-     * Destructor.
-     */
-    ~TskPipeline();
-
-    /**
-     * Validate a Pipeline based on the given XML configuration string. 
-     * @param pipelineConfig String of config file for the specific type of pipeline. 
-     * @throws TskException in case of error.
-     */
-    void validate(const std::string& pipelineConfig);
-
-    /**
-     * Parses the XML config file.  Modules are loaded if m_loadDll is set to true. 
-     * @param pipelineConfig String of a config file for the specific type of pipeline.
-     * @throws TskException in case of error.
-     */
-    void initialize(const std::string& pipelineConfig);
-    bool isEmpty() const { 
-        return m_modules.size() == 0; 
-    }
-
-    /**
-     * Run a file analysis pipeline on a file with the given ID.
-     * @param fileId Id of file to run pipeilne on.
-     * @throws exceptions on errors 
-     */
-    virtual void run(const uint64_t fileId) = 0;
-
-    /**
-     * Run a file analysis pipeline on the given file object.
-     * @param file TskFile object to run pipeilne on.
-     * @throws exceptions on errors 
-     */    
-    virtual void run(TskFile* file) = 0;
-
-    /**
-     * Run a reporting / post-analysis pipeline.
-     * @throws exceptions on errors     
-     */    
-    virtual void run() = 0;
-
-    /**
-     * Create a module for the given pipeline type.
-     * @returns Plug-in module
-     */
-
-    virtual TskPluginModule * createPluginModule() = 0;
-
-    /**
-     * Logs the recorded execution times of the modules in the pipeline.
-     */
-    void logModuleExecutionTimes() const;
-
-protected:
-    /**
-     * Determine whether a particular file should be processed.
-     * @returns true if file should be excluded, false otherwise
-     */
-    bool excludeFile(const TskFile*);
-    
-    /**
-     * Updates the recorded execution time of a module in the pipeline.
-     * @param moduleId Module ID of the module.
-     * @param executionTime Time increment to add to totasl execution time of the module.
-     */
-    void updateModuleExecutionTime(int moduleId, const Poco::Timespan::TimeDiff &executionTime);
-
-    /**
-     * Collection of modules in the pipeline.
-     */
-    std::vector<TskModule*> m_modules;
-
-    bool m_hasExeModule;    ///< True if any module is an executable module
-
-private:
-    // Disallow copying
-    TskPipeline(const TskPipeline&);
-    TskPipeline& operator=(const TskPipeline&);
-
-    /**
-     * Creates a module of the type specified in the XML element.
-     * @param pElem element type from XML file. 
-     * @returns NULL on error 
-     */
-    TskModule * createModule(Poco::XML::Element * pElem);
-
-    bool m_loadDll;     ///< True if dlls should be loaded during initialize
-    
-    /**
-     * A mapping of module IDs to module names.
-     */
-    std::map<int, std::string> m_moduleNames;
-
-    /**
-     * A mapping of module IDs to cumulative module execution times.
-     */
-    std::map<int, Poco::Timespan> m_moduleExecTimes;
-};
-
-#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 TskPipeline.h
+ * Contains the declarations for the TskPipeline class and the interface for methods
+ * that are defined in the various implementations.
+ */
+
+#ifndef _TSK_PIPELINE_H
+#define _TSK_PIPELINE_H
+
+// TSK includes
+#include "tsk/base/tsk_os.h" // for uint64_t
+
+// TSK Framework includes
+#include "TskModule.h"
+#include "TskPluginModule.h"
+
+// Poco includes
+#include "Poco/DOM/Element.h"
+#include "Poco/Timespan.h"
+
+// C/C++ library includes
+#include <list>
+#include <string>
+#include <map>
+
+/**
+ * The Pipeline class controls the processing of data
+ * through an ordered list of dynamic library or executable modules.
+ * Different types of pipeline implementations exist for the different types of data. 
+ * Pipelines are created by the TskPipelineManager class. 
+ */
+class TSK_FRAMEWORK_API TskPipeline
+{
+public:
+    // DEVELOPERS: Changes to any of these elements and attributes require an update to $(TSK_HOME)\framework\docs\pipeline.dox 
+    static const std::string MODULE_ELEMENT; ///< module element in XML config file
+    static const std::string MODULE_TYPE_ATTR;  ///< attribute for module type in XML config file
+    static const std::string MODULE_ORDER_ATTR; ///< attribute for module order in XML config file
+    static const std::string MODULE_LOCATION_ATTR; ///< attribute for module location in XML config file
+    static const std::string MODULE_ARGS_ATTR; ///< attribute for module arguments in XML config file
+    static const std::string MODULE_OUTPUT_ATTR; ///< attribute for module output in XML config file
+    static const std::string MODULE_EXECUTABLE_TYPE; ///< value of MODULE_TYPE_ATTR for executable modules
+    static const std::string MODULE_PLUGIN_TYPE; ///< value of MODULE_TYPE_ATTR for library modules
+
+    /**
+     * Default constructor.
+     */
+    TskPipeline();
+
+    /**
+     * Destructor.
+     */
+    ~TskPipeline();
+
+    /**
+     * Validate a Pipeline based on the given XML configuration string. 
+     * @param pipelineConfig String of config file for the specific type of pipeline. 
+     * @throws TskException in case of error.
+     */
+    void validate(const std::string& pipelineConfig);
+
+    /**
+     * Parses the XML config file.  Modules are loaded if m_loadDll is set to true. 
+     * @param pipelineConfig String of a config file for the specific type of pipeline.
+     * @throws TskException in case of error.
+     */
+    void initialize(const std::string& pipelineConfig);
+    bool isEmpty() const { 
+        return m_modules.size() == 0; 
+    }
+
+    /**
+     * Run a file analysis pipeline on a file with the given ID.
+     * @param fileId Id of file to run pipeilne on.
+     * @throws exceptions on errors 
+     */
+    virtual void run(const uint64_t fileId) = 0;
+
+    /**
+     * Run a file analysis pipeline on the given file object.
+     * @param file TskFile object to run pipeilne on.
+     * @throws exceptions on errors 
+     */    
+    virtual void run(TskFile* file) = 0;
+
+    /**
+     * Run a reporting / post-analysis pipeline.
+     * @throws exceptions on errors     
+     */    
+    virtual void run() = 0;
+
+    /**
+     * Create a module for the given pipeline type.
+     * @returns Plug-in module
+     */
+
+    virtual TskPluginModule * createPluginModule() = 0;
+
+    /**
+     * Logs the recorded execution times of the modules in the pipeline.
+     */
+    void logModuleExecutionTimes() const;
+
+protected:
+    /**
+     * Determine whether a particular file should be processed.
+     * @returns true if file should be excluded, false otherwise
+     */
+    bool excludeFile(const TskFile*);
+    
+    /**
+     * Updates the recorded execution time of a module in the pipeline.
+     * @param moduleId Module ID of the module.
+     * @param executionTime Time increment to add to totasl execution time of the module.
+     */
+    void updateModuleExecutionTime(int moduleId, const Poco::Timespan::TimeDiff &executionTime);
+
+    /**
+     * Collection of modules in the pipeline.
+     */
+    std::vector<TskModule*> m_modules;
+
+    bool m_hasExeModule;    ///< True if any module is an executable module
+
+private:
+    // Disallow copying
+    TskPipeline(const TskPipeline&);
+    TskPipeline& operator=(const TskPipeline&);
+
+    /**
+     * Creates a module of the type specified in the XML element.
+     * @param pElem element type from XML file. 
+     * @returns NULL on error 
+     */
+    TskModule * createModule(Poco::XML::Element * pElem);
+
+    bool m_loadDll;     ///< True if dlls should be loaded during initialize
+    
+    /**
+     * A mapping of module IDs to module names.
+     */
+    std::map<int, std::string> m_moduleNames;
+
+    /**
+     * A mapping of module IDs to cumulative module execution times.
+     */
+    std::map<int, Poco::Timespan> m_moduleExecTimes;
+};
+
+#endif
diff --git a/framework/tsk/framework/pipeline/TskPipelineManager.cpp b/framework/tsk/framework/pipeline/TskPipelineManager.cpp
index c81c4a3..11cb631 100755
--- a/framework/tsk/framework/pipeline/TskPipelineManager.cpp
+++ b/framework/tsk/framework/pipeline/TskPipelineManager.cpp
@@ -1,197 +1,197 @@
-/*
- * 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 TskPipelineManager.cpp
- * Contains the implementation for the TskPipelineManager class.
- */
-
-// System includes
-#include <sstream>
-#include <fstream>
-
-// Framework includes
-#include "TskPipelineManager.h"
-#include "tsk/framework/services/TskSystemProperties.h"
-#include "tsk/framework/utilities/TskException.h"
-#include "tsk/framework/services/TskServices.h"
-#include "TskFileAnalysisPipeline.h"
-#include "TskReportPipeline.h"
-
-// Poco includes
-#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"
-
-const std::string TskPipelineManager::FILE_ANALYSIS_PIPELINE_STR = "FileAnalysis";
-const std::string TskPipelineManager::POST_PROCESSING_PIPELINE_STR = "PostProcessing";
-const std::string TskPipelineManager::REPORTING_PIPELINE_STR = "Report";
-const std::string TskPipelineManager::PIPELINE_ELEMENT = "PIPELINE";
-const std::string TskPipelineManager::PIPELINE_TYPE_ATTRIBUTE = "type";
-const std::string TskPipelineManager::PIPELINE_NAME_ATTRIBUTE = "name";
-
-TskPipelineManager::TskPipelineManager()
-{
-}
-
-TskPipelineManager::~TskPipelineManager()
-{
-    // Delete our pipelines
-    for (std::vector<TskPipeline *>::iterator it = m_pipelines.begin(); it < m_pipelines.end(); it++)
-        delete *it;
-}
-
-TskPipeline * TskPipelineManager::createPipeline(const PIPELINE_TYPE type, const std::string& name)
-{
-    std::string funcName("TskPipelineManager::createPipeline");
-
-    std::string pipelineConfigFilePath = GetSystemProperty(TskSystemProperties::PIPELINE_CONFIG_FILE);
-    std::ifstream in(pipelineConfigFilePath.c_str());
-    if (!in)
-    {
-        throw TskException("Error opening pipeline config file.");
-    }
-    else 
-    {
-        std::stringstream msg;
-        msg << funcName << " : Using config file '" << pipelineConfigFilePath;
-        LOGINFO(msg.str());
-    }
-
-    std::string pipelineType = pipelineTypeToString(type);
-
-    try
-    {
-        Poco::XML::InputSource src(in);
-
-        // Parse the XML into a Poco::XML::Document
-        Poco::XML::DOMParser parser;
-        Poco::AutoPtr<Poco::XML::Document> xmlDoc = parser.parse(&src);
-
-        // Locate the PIPELINE element that matches pipelineType
-        Poco::AutoPtr<Poco::XML::NodeList> pipelines = 
-            xmlDoc->getElementsByTagName(TskPipelineManager::PIPELINE_ELEMENT);
-
-        if (pipelines->length() == 0)
-        {
-            throw TskException("No pipelines found in config file.");
-        }
-
-        TskPipeline * pipeline;
-        if (type == FILE_ANALYSIS_PIPELINE)
-            pipeline = new TskFileAnalysisPipeline();
-        else if (type == POST_PROCESSING_PIPELINE)
-            pipeline = new TskReportPipeline();
-        else
-            throw TskException("Unsupported pipeline type.");
-
-        m_pipelines.push_back(pipeline);
-
-        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);
-
-            if (pElem)
-            {
-                std::string xmlPipelineType = pElem->getAttribute(TskPipelineManager::PIPELINE_TYPE_ATTRIBUTE);
-                std::string xmlPipelineName = pElem->getAttribute(TskPipelineManager::PIPELINE_NAME_ATTRIBUTE);
-
-                // The following conditions are required because we want to be able to use 
-                // "PostProcessing" and "Report" to be used interchangeably (at least for the moment).
-                // Note that the sanity check below will not catch the case where there are both
-                // "PostProcessing" and "Report" pipelines in the configuration file.
-                if (xmlPipelineName == name && (xmlPipelineType == pipelineType) ||
-                    (pipelineType == REPORTING_PIPELINE_STR && xmlPipelineType == POST_PROCESSING_PIPELINE_STR) ||
-                    (pipelineType == POST_PROCESSING_PIPELINE_STR && xmlPipelineType == REPORTING_PIPELINE_STR))
-                {
-                    // quick sanity check to verify that there is only one pipeline in the config file for this type and name
-                    for (unsigned long i2 = i+1; i2 < pipelines->length(); i2++) {
-                        Poco::XML::Node * pNode2 = pipelines->item(i2);
-                        Poco::XML::Element* pElem2 = dynamic_cast<Poco::XML::Element*>(pNode2);
-
-                        if (pElem2 && 
-                            pElem2->getAttribute(TskPipelineManager::PIPELINE_TYPE_ATTRIBUTE) == pipelineType &&
-                            pElem2->getAttribute(TskPipelineManager::PIPELINE_NAME_ATTRIBUTE) == name) 
-                        {
-                            std::stringstream exMsg;
-                            exMsg << "Multiple pipelines found with the same type (" << pipelineType
-                                << ") and name (" << name << ")";
-                            throw TskException (exMsg.str());
-                        }
-                    }
-                    // We found the right pipeline so initialize it.
-                    Poco::XML::DOMWriter writer;
-                    std::ostringstream pipelineXml;
-                    writer.writeNode(pipelineXml, pNode);
-
-                    pipeline->initialize(pipelineXml.str());
-
-                    return pipeline;
-                }
-            }
-        }
-    }
-    catch (Poco::XML::SAXParseException& )
-    {
-        throw TskException("Error parsing pipeline config file.");
-    }
-    catch (TskException& ex)
-    {
-        throw ex;
-    }
-
-    std::stringstream errorMsg;
-    errorMsg << "Failed to find " << pipelineType << " pipeline";
-    if (!name.empty())
-        errorMsg << " with name " << name;
-
-    throw TskException(errorMsg.str());
-}
-
-/**
- * Creates a pipeline object by reading the pipeline config file specified as
- * a system property. 
- * @returns Pointer to TskPipeline.  Do not free this. It will be freed by the
- * TskPipelineManager destructor. 
- */
-TskPipeline * TskPipelineManager::createPipeline(const std::string &pipelineType)
-{
-    if (pipelineType == REPORTING_PIPELINE_STR || pipelineType == POST_PROCESSING_PIPELINE_STR)
-        return createPipeline(TskPipelineManager::POST_PROCESSING_PIPELINE);
-    else if (pipelineType == FILE_ANALYSIS_PIPELINE_STR)
-        return createPipeline(TskPipelineManager::FILE_ANALYSIS_PIPELINE);
-    else
-    {
-        std::stringstream exMsg;
-        exMsg << "TskPipelineManager::createPipeline : Unsupported pipeline type : " << pipelineType;
-        throw TskException(exMsg.str());
-    }
-}
-
-std::string TskPipelineManager::pipelineTypeToString(const PIPELINE_TYPE type)
-{
-    switch (type)
-    {
-    case FILE_ANALYSIS_PIPELINE:
-        return FILE_ANALYSIS_PIPELINE_STR;
-    case POST_PROCESSING_PIPELINE:
-        return POST_PROCESSING_PIPELINE_STR;
-    default:
-        return "Unknown pipeline type";
-    }
-}
+/*
+ * 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 TskPipelineManager.cpp
+ * Contains the implementation for the TskPipelineManager class.
+ */
+
+// System includes
+#include <sstream>
+#include <fstream>
+
+// Framework includes
+#include "TskPipelineManager.h"
+#include "tsk/framework/services/TskSystemProperties.h"
+#include "tsk/framework/utilities/TskException.h"
+#include "tsk/framework/services/TskServices.h"
+#include "TskFileAnalysisPipeline.h"
+#include "TskReportPipeline.h"
+
+// Poco includes
+#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"
+
+const std::string TskPipelineManager::FILE_ANALYSIS_PIPELINE_STR = "FileAnalysis";
+const std::string TskPipelineManager::POST_PROCESSING_PIPELINE_STR = "PostProcessing";
+const std::string TskPipelineManager::REPORTING_PIPELINE_STR = "Report";
+const std::string TskPipelineManager::PIPELINE_ELEMENT = "PIPELINE";
+const std::string TskPipelineManager::PIPELINE_TYPE_ATTRIBUTE = "type";
+const std::string TskPipelineManager::PIPELINE_NAME_ATTRIBUTE = "name";
+
+TskPipelineManager::TskPipelineManager()
+{
+}
+
+TskPipelineManager::~TskPipelineManager()
+{
+    // Delete our pipelines
+    for (std::vector<TskPipeline *>::iterator it = m_pipelines.begin(); it < m_pipelines.end(); it++)
+        delete *it;
+}
+
+TskPipeline * TskPipelineManager::createPipeline(const PIPELINE_TYPE type, const std::string& name)
+{
+    std::string funcName("TskPipelineManager::createPipeline");
+
+    std::string pipelineConfigFilePath = GetSystemProperty(TskSystemProperties::PIPELINE_CONFIG_FILE);
+    std::ifstream in(pipelineConfigFilePath.c_str());
+    if (!in)
+    {
+        throw TskException("Error opening pipeline config file.");
+    }
+    else 
+    {
+        std::stringstream msg;
+        msg << funcName << " : Using config file '" << pipelineConfigFilePath;
+        LOGINFO(msg.str());
+    }
+
+    std::string pipelineType = pipelineTypeToString(type);
+
+    try
+    {
+        Poco::XML::InputSource src(in);
+
+        // Parse the XML into a Poco::XML::Document
+        Poco::XML::DOMParser parser;
+        Poco::AutoPtr<Poco::XML::Document> xmlDoc = parser.parse(&src);
+
+        // Locate the PIPELINE element that matches pipelineType
+        Poco::AutoPtr<Poco::XML::NodeList> pipelines = 
+            xmlDoc->getElementsByTagName(TskPipelineManager::PIPELINE_ELEMENT);
+
+        if (pipelines->length() == 0)
+        {
+            throw TskException("No pipelines found in config file.");
+        }
+
+        TskPipeline * pipeline;
+        if (type == FILE_ANALYSIS_PIPELINE)
+            pipeline = new TskFileAnalysisPipeline();
+        else if (type == POST_PROCESSING_PIPELINE)
+            pipeline = new TskReportPipeline();
+        else
+            throw TskException("Unsupported pipeline type.");
+
+        m_pipelines.push_back(pipeline);
+
+        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);
+
+            if (pElem)
+            {
+                std::string xmlPipelineType = pElem->getAttribute(TskPipelineManager::PIPELINE_TYPE_ATTRIBUTE);
+                std::string xmlPipelineName = pElem->getAttribute(TskPipelineManager::PIPELINE_NAME_ATTRIBUTE);
+
+                // The following conditions are required because we want to be able to use 
+                // "PostProcessing" and "Report" to be used interchangeably (at least for the moment).
+                // Note that the sanity check below will not catch the case where there are both
+                // "PostProcessing" and "Report" pipelines in the configuration file.
+                if (xmlPipelineName == name && (xmlPipelineType == pipelineType) ||
+                    (pipelineType == REPORTING_PIPELINE_STR && xmlPipelineType == POST_PROCESSING_PIPELINE_STR) ||
+                    (pipelineType == POST_PROCESSING_PIPELINE_STR && xmlPipelineType == REPORTING_PIPELINE_STR))
+                {
+                    // quick sanity check to verify that there is only one pipeline in the config file for this type and name
+                    for (unsigned long i2 = i+1; i2 < pipelines->length(); i2++) {
+                        Poco::XML::Node * pNode2 = pipelines->item(i2);
+                        Poco::XML::Element* pElem2 = dynamic_cast<Poco::XML::Element*>(pNode2);
+
+                        if (pElem2 && 
+                            pElem2->getAttribute(TskPipelineManager::PIPELINE_TYPE_ATTRIBUTE) == pipelineType &&
+                            pElem2->getAttribute(TskPipelineManager::PIPELINE_NAME_ATTRIBUTE) == name) 
+                        {
+                            std::stringstream exMsg;
+                            exMsg << "Multiple pipelines found with the same type (" << pipelineType
+                                << ") and name (" << name << ")";
+                            throw TskException (exMsg.str());
+                        }
+                    }
+                    // We found the right pipeline so initialize it.
+                    Poco::XML::DOMWriter writer;
+                    std::ostringstream pipelineXml;
+                    writer.writeNode(pipelineXml, pNode);
+
+                    pipeline->initialize(pipelineXml.str());
+
+                    return pipeline;
+                }
+            }
+        }
+    }
+    catch (Poco::XML::SAXParseException& )
+    {
+        throw TskException("Error parsing pipeline config file.");
+    }
+    catch (TskException& ex)
+    {
+        throw ex;
+    }
+
+    std::stringstream errorMsg;
+    errorMsg << "Failed to find " << pipelineType << " pipeline";
+    if (!name.empty())
+        errorMsg << " with name " << name;
+
+    throw TskException(errorMsg.str());
+}
+
+/**
+ * Creates a pipeline object by reading the pipeline config file specified as
+ * a system property. 
+ * @returns Pointer to TskPipeline.  Do not free this. It will be freed by the
+ * TskPipelineManager destructor. 
+ */
+TskPipeline * TskPipelineManager::createPipeline(const std::string &pipelineType)
+{
+    if (pipelineType == REPORTING_PIPELINE_STR || pipelineType == POST_PROCESSING_PIPELINE_STR)
+        return createPipeline(TskPipelineManager::POST_PROCESSING_PIPELINE);
+    else if (pipelineType == FILE_ANALYSIS_PIPELINE_STR)
+        return createPipeline(TskPipelineManager::FILE_ANALYSIS_PIPELINE);
+    else
+    {
+        std::stringstream exMsg;
+        exMsg << "TskPipelineManager::createPipeline : Unsupported pipeline type : " << pipelineType;
+        throw TskException(exMsg.str());
+    }
+}
+
+std::string TskPipelineManager::pipelineTypeToString(const PIPELINE_TYPE type)
+{
+    switch (type)
+    {
+    case FILE_ANALYSIS_PIPELINE:
+        return FILE_ANALYSIS_PIPELINE_STR;
+    case POST_PROCESSING_PIPELINE:
+        return POST_PROCESSING_PIPELINE_STR;
+    default:
+        return "Unknown pipeline type";
+    }
+}
diff --git a/framework/tsk/framework/pipeline/TskPipelineManager.h b/framework/tsk/framework/pipeline/TskPipelineManager.h
index 9e0e080..7952cd2 100755
--- a/framework/tsk/framework/pipeline/TskPipelineManager.h
+++ b/framework/tsk/framework/pipeline/TskPipelineManager.h
@@ -1,63 +1,63 @@
-/*
- * 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 TskPipelineManager.h
- * Contains the declarations for the TskPipelineManager class.
- */
-
-#ifndef _TSK_PIPELINEMANAGER_H
-#define _TSK_PIPELINEMANAGER_H
-
-#include <string>
-#include "TskPipeline.h"
-
-/**
- * Responsible for creation and destruction of of TskPipeline objects.
- * This class is responsible for reading the pipeline configuration file.
- */
-class TSK_FRAMEWORK_API TskPipelineManager
-{
-public:
-    /// Supported pipeline types
-    enum PIPELINE_TYPE
-    {
-        FILE_ANALYSIS_PIPELINE, ///< A pipeline that operates on every file in the system
-        POST_PROCESSING_PIPELINE ///< A pipeline that is run once file analysis is complete
-    };
-
-    static const std::string FILE_ANALYSIS_PIPELINE_STR;  ///< String to use in pipeline configuration file when creating a file analysis pipeline
-    static const std::string POST_PROCESSING_PIPELINE_STR; ///< String to use in pipeline configuration file when creating a post processing pipeline
-    static const std::string REPORTING_PIPELINE_STR; ///< Deprecated: String to use in pipeline configuration file when creating a post processing pipeline
-    static const std::string PIPELINE_ELEMENT; ///< String to use in pipeline configuration file when creating a pipeline element
-    static const std::string PIPELINE_TYPE_ATTRIBUTE; ///< Attribute in PIPELINE_ELEMENT for pipeline type in config XML file
-    static const std::string PIPELINE_NAME_ATTRIBUTE; ///< Attribute in PIPELINE_ELEMENT for optional pipeline name in config XML file
-
-    TskPipelineManager();
-    ~TskPipelineManager();
-    TskPipeline * createPipeline(const std::string& pipelineType);
-
-    /**
-     * Create a pipeline of the given type and optionally a given name.
-     * @param type The type of pipeline to create
-     * @param name An optional string to disambiguate the situation where there are multiple pipelines
-     * of the same type.
-     * @return Pointer to a pipeline object. This pointer is managed by TskPipelineManager which will free it
-     * in its desctructor.
-     */
-    TskPipeline * createPipeline(const PIPELINE_TYPE type, const std::string& name="");
-
-private:
-    std::vector<TskPipeline *> m_pipelines;  ///< List of allocated pipelines
-
-    std::string pipelineTypeToString(const PIPELINE_TYPE type);
-};
-
-#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 TskPipelineManager.h
+ * Contains the declarations for the TskPipelineManager class.
+ */
+
+#ifndef _TSK_PIPELINEMANAGER_H
+#define _TSK_PIPELINEMANAGER_H
+
+#include <string>
+#include "TskPipeline.h"
+
+/**
+ * Responsible for creation and destruction of of TskPipeline objects.
+ * This class is responsible for reading the pipeline configuration file.
+ */
+class TSK_FRAMEWORK_API TskPipelineManager
+{
+public:
+    /// Supported pipeline types
+    enum PIPELINE_TYPE
+    {
+        FILE_ANALYSIS_PIPELINE, ///< A pipeline that operates on every file in the system
+        POST_PROCESSING_PIPELINE ///< A pipeline that is run once file analysis is complete
+    };
+
+    static const std::string FILE_ANALYSIS_PIPELINE_STR;  ///< String to use in pipeline configuration file when creating a file analysis pipeline
+    static const std::string POST_PROCESSING_PIPELINE_STR; ///< String to use in pipeline configuration file when creating a post processing pipeline
+    static const std::string REPORTING_PIPELINE_STR; ///< Deprecated: String to use in pipeline configuration file when creating a post processing pipeline
+    static const std::string PIPELINE_ELEMENT; ///< String to use in pipeline configuration file when creating a pipeline element
+    static const std::string PIPELINE_TYPE_ATTRIBUTE; ///< Attribute in PIPELINE_ELEMENT for pipeline type in config XML file
+    static const std::string PIPELINE_NAME_ATTRIBUTE; ///< Attribute in PIPELINE_ELEMENT for optional pipeline name in config XML file
+
+    TskPipelineManager();
+    ~TskPipelineManager();
+    TskPipeline * createPipeline(const std::string& pipelineType);
+
+    /**
+     * Create a pipeline of the given type and optionally a given name.
+     * @param type The type of pipeline to create
+     * @param name An optional string to disambiguate the situation where there are multiple pipelines
+     * of the same type.
+     * @return Pointer to a pipeline object. This pointer is managed by TskPipelineManager which will free it
+     * in its desctructor.
+     */
+    TskPipeline * createPipeline(const PIPELINE_TYPE type, const std::string& name="");
+
+private:
+    std::vector<TskPipeline *> m_pipelines;  ///< List of allocated pipelines
+
+    std::string pipelineTypeToString(const PIPELINE_TYPE type);
+};
+
+#endif 
diff --git a/framework/tsk/framework/pipeline/TskPluginModule.cpp b/framework/tsk/framework/pipeline/TskPluginModule.cpp
index 8b3171a..2453ac2 100755
--- a/framework/tsk/framework/pipeline/TskPluginModule.cpp
+++ b/framework/tsk/framework/pipeline/TskPluginModule.cpp
@@ -1,299 +1,299 @@
-/*
- * 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 TskPluginModule.cpp
- * Contains the implementation for the TskPluginModule class.
- */
-
-// Include the class definition first to ensure it does not depend on subsequent includes in this file.
-#include "TskPluginModule.h"
-
-// Framework includes
-#include "tsk/framework/services/TskServices.h"
-#include "tsk/framework/utilities/TskException.h"
-#include "tsk/framework/file/TskFileManagerImpl.h"
-#include "tsk/framework/TskVersionInfo.h"
-
-// Poco includes
-#include "Poco/String.h"
-#include "Poco/Path.h"
-#include "Poco/Environment.h"
-
-// C/C++ library includes
-#include <sstream>
-#include <string>
-
-const std::string TskPluginModule::GET_COMPILER_SYMBOL = "getCompiler";
-const std::string TskPluginModule::GET_COMPILER_VERSION_SYMBOL = "getCompilerVersion";
-const std::string TskPluginModule::GET_FRAMEWORK_VERSION_SYMBOL = "getFrameWorkVersion";
-const std::string TskPluginModule::GET_BUILD_TYPE_SYMBOL = "getBuildType";
-const std::string TskPluginModule::NAME_SYMBOL = "name";
-const std::string TskPluginModule::DESCRIPTION_SYMBOL = "description";
-const std::string TskPluginModule::VERSION_SYMBOL = "version";
-const std::string TskPluginModule::RUN_SYMBOL = "run";
-const std::string TskPluginModule::REPORT_SYMBOL = "report";
-const std::string TskPluginModule::INITIALIZE_SYMBOL = "initialize";
-const std::string TskPluginModule::FINALIZE_SYMBOL = "finalize";
-
-TskPluginModule::~TskPluginModule()
-{
-    if (m_sharedLibrary.isLoaded())
-    {
-        // Call finalize function if defined.
-        if (m_sharedLibrary.hasSymbol(TskPluginModule::FINALIZE_SYMBOL))
-        {
-            typedef TskModule::Status (*FinalizeFunc)();
-            FinalizeFunc fin = (FinalizeFunc)m_sharedLibrary.getSymbol(TskPluginModule::FINALIZE_SYMBOL);
-            fin();
-        }
-
-        m_sharedLibrary.unload();
-    }
-}
-
-void TskPluginModule::setPath(const std::string& location)
-{
-    try
-    {
-        if (location.empty()) 
-        {
-            throw TskException("TskPluginModule::setPath: location is empty or missing.");
-        }
-
-        std::string os = Poco::Environment::osName();        
-        Poco::Path tempPath = location;
-            
-        // If on Linux or Mac, then prefix with "lib"
-        if ((os.find("Linux") != std::string::npos) || (os.find("Darwin") != std::string::npos))
-        {
-            tempPath.setFileName("lib" + tempPath.getFileName());
-        } 
-
-        // Autogenerate filename extension if needed
-        if (tempPath.getExtension().empty())
-        {
-            if (os.find("Linux") != std::string::npos)
-            {
-                tempPath.setExtension("so");
-            } 
-            else if (os.find("Darwin") != std::string::npos)
-            {
-                tempPath.setExtension("dylib");
-            } 
-            else if (os.find("Windows") != std::string::npos ||
-                     os.find("CYGWIN")  != std::string::npos ||
-                     os.find("MINGW")   != std::string::npos )
-            {
-                tempPath.setExtension("dll");
-            } 
-            else
-            {
-                throw TskException("TskPluginModule::setPath: OS unknown. Cannot resolve plugin extension.");
-            }
-        }
-
-        // Search for location
-        // Absolute (fully qualified) paths are not allowed.
-        if (!tempPath.isAbsolute())
-        {
-            // See if we can find the executable in MODULE_DIR.
-            std::string pathsToSearch = GetSystemProperty(TskSystemProperties::MODULE_DIR);
-
-            bool found = Poco::Path::find(pathsToSearch, tempPath.toString(), tempPath);
-
-            // Confirm existence of file at found location.
-            Poco::File moduleFile(tempPath);
-            if (found && moduleFile.exists())
-            {
-                std::wstringstream msg;
-                msg << L"TskPluginModule::setPath - Module found at: "
-                    << tempPath.toString().c_str();
-                LOGINFO(msg.str());
-            }
-            else
-            {
-                std::stringstream msg;
-                msg << "TskPluginModule::setPath - Module not found: "
-                    << tempPath.toString().c_str();
-                throw TskException(msg.str());
-            }
-        }
-        else
-        {
-            std::stringstream msg;
-            msg << "TskPluginModule::setPath: location (" << tempPath.toString() << ") is not relative to MODULE_DIR.";
-            throw TskException(msg.str());
-        }
-
-        m_modulePath = tempPath.toString();
-
-        // Load the library.
-        m_sharedLibrary.load(m_modulePath);
-
-        if (m_sharedLibrary.isLoaded())
-        {
-           validateLibraryVersionInfo();
-
-           // TODO: Eliminate code duplication that follows.
-           typedef const char* (*MetaDataFunc)();
-           MetaDataFunc metaDataFunc = NULL;
-
-            if (m_sharedLibrary.hasSymbol(TskPluginModule::NAME_SYMBOL))
-            {
-                metaDataFunc = (MetaDataFunc)m_sharedLibrary.getSymbol(TskPluginModule::NAME_SYMBOL);
-                if (metaDataFunc)
-                {
-                    m_name = metaDataFunc();
-                    metaDataFunc = NULL;
-                }
-            }
-
-            if (m_sharedLibrary.hasSymbol(TskPluginModule::DESCRIPTION_SYMBOL))
-            {
-                metaDataFunc = (MetaDataFunc)m_sharedLibrary.getSymbol(TskPluginModule::DESCRIPTION_SYMBOL);
-                if (metaDataFunc)
-                {
-                    m_description = metaDataFunc();
-                    metaDataFunc = NULL;
-                }
-            }
-
-            if (m_sharedLibrary.hasSymbol(TskPluginModule::VERSION_SYMBOL))
-            {
-                metaDataFunc = (MetaDataFunc)m_sharedLibrary.getSymbol(TskPluginModule::VERSION_SYMBOL);
-                if (metaDataFunc)
-                {
-                    m_version = metaDataFunc();
-                    metaDataFunc = NULL;
-                }
-            }
-        }
-
-        if (m_name.empty())
-        {
-            Poco::Path modulePath(m_modulePath);
-            m_name = modulePath.getBaseName();
-        }
-    }
-    catch (TskException& ex)
-    {
-        // Base class has already logged an error so we simply rethrow.
-        throw ex;
-    }
-    catch(std::exception& ex)
-    {
-        // Log a message and throw a framework exception.
-        std::wstringstream msg;
-        msg << L"TskPluginModule::setPath - " << ex.what();
-        LOGERROR(msg.str());
-
-        throw TskException("Failed to set path: " + m_modulePath);
-    }
-}
-
-TskModule::Status TskPluginModule::initialize()
-{
-    const std::string MSG_PREFIX = "TskPluginModule::initialize : ";
-    TskModule::Status status = TskModule::FAIL;
-    if (m_sharedLibrary.hasSymbol(TskPluginModule::INITIALIZE_SYMBOL))
-    {
-        try
-        {
-            std::string arguments = expandArgumentMacros(m_arguments, 0);
-            typedef TskModule::Status (*InitializeFunc)(const char* args);
-            InitializeFunc init = (InitializeFunc) m_sharedLibrary.getSymbol(TskPluginModule::INITIALIZE_SYMBOL);
-            status = init(arguments.c_str());        
-        }
-        catch (TskException &ex) 
-        {
-            std::stringstream msg;
-            msg << MSG_PREFIX << "TskException initializing " << getName() << ": " << ex.message();
-            LOGERROR(msg.str());
-            status = TskModule::FAIL;
-        }
-        catch (Poco::Exception &ex) 
-        {
-            std::stringstream msg;
-            msg << MSG_PREFIX <<  "Poco::Exception initializing "  << getName() << ": " << ex.displayText();
-            LOGERROR(msg.str());
-            status = TskModule::FAIL;
-        }
-        catch (std::exception &ex) 
-        {
-            std::stringstream msg;
-            msg << MSG_PREFIX <<  "std::exception initializing "  << getName() << ": " << ex.what();
-            LOGERROR(msg.str());
-            status = TskModule::FAIL;
-        }
-        catch (...)
-        {
-            std::stringstream msg;
-            msg << MSG_PREFIX << "unrecognized exception initializing "  << getName();
-            LOGERROR(msg.str());
-            status = TskModule::FAIL;
-        }
-    }
-
-    return status;
-}
-
-bool TskPluginModule::isLoaded() const
-{
-    return (m_sharedLibrary.isLoaded());
-}
-
-void *TskPluginModule::getSymbol(const std::string symbol)
-{
-    return (void*)m_sharedLibrary.getSymbol(symbol);
-}
-
-bool TskPluginModule::hasSymbol(const std::string symbol) 
-{
-    return (m_sharedLibrary.hasSymbol(symbol));
-}
-
-void TskPluginModule::validateLibraryVersionInfo()
-{
-   if (!hasSymbol(GET_FRAMEWORK_VERSION_SYMBOL) || !hasSymbol(GET_COMPILER_SYMBOL) || !hasSymbol(GET_COMPILER_VERSION_SYMBOL) || !hasSymbol(GET_BUILD_TYPE_SYMBOL))
-   {
-      throw TskException("version info interface not implemented");
-   }
-
-   int frameworkVersion = TskVersionInfo::getFrameworkVersion();
-   typedef int (*GetFrameworkVersion)();
-   GetFrameworkVersion getFrameworkVersion = (GetFrameworkVersion) m_sharedLibrary.getSymbol(TskPluginModule::GET_FRAMEWORK_VERSION_SYMBOL);
-   int moduleFrameworkVersion = getFrameworkVersion();
-   if (((frameworkVersion >> 16) & 0xFFFF)  != (( moduleFrameworkVersion >> 16) & 0xFFFF))
-   {
-      throw TskException("TskPluginModule::validateLibraryVersionInfo : framework version mismatch");
-   }
-
-   typedef TskVersionInfo::Compiler (*GetCompiler)();
-   GetCompiler getCompiler = (GetCompiler) m_sharedLibrary.getSymbol(TskPluginModule::GET_COMPILER_SYMBOL);
-   if (TskVersionInfo::getCompiler() != getCompiler())
-   {
-      throw TskException("TskPluginModule::validateLibraryVersionInfo : compiler mismatch");
-   }
-
-   typedef int (*GetCompilerVersion)();
-   GetCompilerVersion getCompilerVersion = (GetCompilerVersion) m_sharedLibrary.getSymbol(TskPluginModule::GET_COMPILER_VERSION_SYMBOL);
-   if (TskVersionInfo::getCompilerVersion() != getCompilerVersion())
-   {
-      throw TskException("TskPluginModule::validateLibraryVersionInfo : compiler version mismatch");
-   }
-
-   typedef TskVersionInfo::BuildType (*GetBuildType)();
-   GetBuildType getBuildType = (GetBuildType) m_sharedLibrary.getSymbol(TskPluginModule::GET_BUILD_TYPE_SYMBOL);
-   if (TskVersionInfo::getBuildType() != getBuildType())
-   {
-      throw TskException("TskPluginModule::validateLibraryVersionInfo : build target mismatch");
-   }
-}
+/*
+ * 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 TskPluginModule.cpp
+ * Contains the implementation for the TskPluginModule class.
+ */
+
+// Include the class definition first to ensure it does not depend on subsequent includes in this file.
+#include "TskPluginModule.h"
+
+// Framework includes
+#include "tsk/framework/services/TskServices.h"
+#include "tsk/framework/utilities/TskException.h"
+#include "tsk/framework/file/TskFileManagerImpl.h"
+#include "tsk/framework/TskVersionInfo.h"
+
+// Poco includes
+#include "Poco/String.h"
+#include "Poco/Path.h"
+#include "Poco/Environment.h"
+
+// C/C++ library includes
+#include <sstream>
+#include <string>
+
+const std::string TskPluginModule::GET_COMPILER_SYMBOL = "getCompiler";
+const std::string TskPluginModule::GET_COMPILER_VERSION_SYMBOL = "getCompilerVersion";
+const std::string TskPluginModule::GET_FRAMEWORK_VERSION_SYMBOL = "getFrameWorkVersion";
+const std::string TskPluginModule::GET_BUILD_TYPE_SYMBOL = "getBuildType";
+const std::string TskPluginModule::NAME_SYMBOL = "name";
+const std::string TskPluginModule::DESCRIPTION_SYMBOL = "description";
+const std::string TskPluginModule::VERSION_SYMBOL = "version";
+const std::string TskPluginModule::RUN_SYMBOL = "run";
+const std::string TskPluginModule::REPORT_SYMBOL = "report";
+const std::string TskPluginModule::INITIALIZE_SYMBOL = "initialize";
+const std::string TskPluginModule::FINALIZE_SYMBOL = "finalize";
+
+TskPluginModule::~TskPluginModule()
+{
+    if (m_sharedLibrary.isLoaded())
+    {
+        // Call finalize function if defined.
+        if (m_sharedLibrary.hasSymbol(TskPluginModule::FINALIZE_SYMBOL))
+        {
+            typedef TskModule::Status (*FinalizeFunc)();
+            FinalizeFunc fin = (FinalizeFunc)m_sharedLibrary.getSymbol(TskPluginModule::FINALIZE_SYMBOL);
+            fin();
+        }
+
+        m_sharedLibrary.unload();
+    }
+}
+
+void TskPluginModule::setPath(const std::string& location)
+{
+    try
+    {
+        if (location.empty()) 
+        {
+            throw TskException("TskPluginModule::setPath: location is empty or missing.");
+        }
+
+        std::string os = Poco::Environment::osName();        
+        Poco::Path tempPath = location;
+            
+        // If on Linux or Mac, then prefix with "lib"
+        if ((os.find("Linux") != std::string::npos) || (os.find("Darwin") != std::string::npos))
+        {
+            tempPath.setFileName("lib" + tempPath.getFileName());
+        } 
+
+        // Autogenerate filename extension if needed
+        if (tempPath.getExtension().empty())
+        {
+            if (os.find("Linux") != std::string::npos)
+            {
+                tempPath.setExtension("so");
+            } 
+            else if (os.find("Darwin") != std::string::npos)
+            {
+                tempPath.setExtension("dylib");
+            } 
+            else if (os.find("Windows") != std::string::npos ||
+                     os.find("CYGWIN")  != std::string::npos ||
+                     os.find("MINGW")   != std::string::npos )
+            {
+                tempPath.setExtension("dll");
+            } 
+            else
+            {
+                throw TskException("TskPluginModule::setPath: OS unknown. Cannot resolve plugin extension.");
+            }
+        }
+
+        // Search for location
+        // Absolute (fully qualified) paths are not allowed.
+        if (!tempPath.isAbsolute())
+        {
+            // See if we can find the executable in MODULE_DIR.
+            std::string pathsToSearch = GetSystemProperty(TskSystemProperties::MODULE_DIR);
+
+            bool found = Poco::Path::find(pathsToSearch, tempPath.toString(), tempPath);
+
+            // Confirm existence of file at found location.
+            Poco::File moduleFile(tempPath);
+            if (found && moduleFile.exists())
+            {
+                std::wstringstream msg;
+                msg << L"TskPluginModule::setPath - Module found at: "
+                    << tempPath.toString().c_str();
+                LOGINFO(msg.str());
+            }
+            else
+            {
+                std::stringstream msg;
+                msg << "TskPluginModule::setPath - Module not found: "
+                    << tempPath.toString().c_str();
+                throw TskException(msg.str());
+            }
+        }
+        else
+        {
+            std::stringstream msg;
+            msg << "TskPluginModule::setPath: location (" << tempPath.toString() << ") is not relative to MODULE_DIR.";
+            throw TskException(msg.str());
+        }
+
+        m_modulePath = tempPath.toString();
+
+        // Load the library.
+        m_sharedLibrary.load(m_modulePath);
+
+        if (m_sharedLibrary.isLoaded())
+        {
+           validateLibraryVersionInfo();
+
+           // TODO: Eliminate code duplication that follows.
+           typedef const char* (*MetaDataFunc)();
+           MetaDataFunc metaDataFunc = NULL;
+
+            if (m_sharedLibrary.hasSymbol(TskPluginModule::NAME_SYMBOL))
+            {
+                metaDataFunc = (MetaDataFunc)m_sharedLibrary.getSymbol(TskPluginModule::NAME_SYMBOL);
+                if (metaDataFunc)
+                {
+                    m_name = metaDataFunc();
+                    metaDataFunc = NULL;
+                }
+            }
+
+            if (m_sharedLibrary.hasSymbol(TskPluginModule::DESCRIPTION_SYMBOL))
+            {
+                metaDataFunc = (MetaDataFunc)m_sharedLibrary.getSymbol(TskPluginModule::DESCRIPTION_SYMBOL);
+                if (metaDataFunc)
+                {
+                    m_description = metaDataFunc();
+                    metaDataFunc = NULL;
+                }
+            }
+
+            if (m_sharedLibrary.hasSymbol(TskPluginModule::VERSION_SYMBOL))
+            {
+                metaDataFunc = (MetaDataFunc)m_sharedLibrary.getSymbol(TskPluginModule::VERSION_SYMBOL);
+                if (metaDataFunc)
+                {
+                    m_version = metaDataFunc();
+                    metaDataFunc = NULL;
+                }
+            }
+        }
+
+        if (m_name.empty())
+        {
+            Poco::Path modulePath(m_modulePath);
+            m_name = modulePath.getBaseName();
+        }
+    }
+    catch (TskException& ex)
+    {
+        // Base class has already logged an error so we simply rethrow.
+        throw ex;
+    }
+    catch(std::exception& ex)
+    {
+        // Log a message and throw a framework exception.
+        std::wstringstream msg;
+        msg << L"TskPluginModule::setPath - " << ex.what();
+        LOGERROR(msg.str());
+
+        throw TskException("Failed to set path: " + m_modulePath);
+    }
+}
+
+TskModule::Status TskPluginModule::initialize()
+{
+    const std::string MSG_PREFIX = "TskPluginModule::initialize : ";
+    TskModule::Status status = TskModule::FAIL;
+    if (m_sharedLibrary.hasSymbol(TskPluginModule::INITIALIZE_SYMBOL))
+    {
+        try
+        {
+            std::string arguments = expandArgumentMacros(m_arguments, 0);
+            typedef TskModule::Status (*InitializeFunc)(const char* args);
+            InitializeFunc init = (InitializeFunc) m_sharedLibrary.getSymbol(TskPluginModule::INITIALIZE_SYMBOL);
+            status = init(arguments.c_str());        
+        }
+        catch (TskException &ex) 
+        {
+            std::stringstream msg;
+            msg << MSG_PREFIX << "TskException initializing " << getName() << ": " << ex.message();
+            LOGERROR(msg.str());
+            status = TskModule::FAIL;
+        }
+        catch (Poco::Exception &ex) 
+        {
+            std::stringstream msg;
+            msg << MSG_PREFIX <<  "Poco::Exception initializing "  << getName() << ": " << ex.displayText();
+            LOGERROR(msg.str());
+            status = TskModule::FAIL;
+        }
+        catch (std::exception &ex) 
+        {
+            std::stringstream msg;
+            msg << MSG_PREFIX <<  "std::exception initializing "  << getName() << ": " << ex.what();
+            LOGERROR(msg.str());
+            status = TskModule::FAIL;
+        }
+        catch (...)
+        {
+            std::stringstream msg;
+            msg << MSG_PREFIX << "unrecognized exception initializing "  << getName();
+            LOGERROR(msg.str());
+            status = TskModule::FAIL;
+        }
+    }
+
+    return status;
+}
+
+bool TskPluginModule::isLoaded() const
+{
+    return (m_sharedLibrary.isLoaded());
+}
+
+void *TskPluginModule::getSymbol(const std::string symbol)
+{
+    return (void*)m_sharedLibrary.getSymbol(symbol);
+}
+
+bool TskPluginModule::hasSymbol(const std::string symbol) 
+{
+    return (m_sharedLibrary.hasSymbol(symbol));
+}
+
+void TskPluginModule::validateLibraryVersionInfo()
+{
+   if (!hasSymbol(GET_FRAMEWORK_VERSION_SYMBOL) || !hasSymbol(GET_COMPILER_SYMBOL) || !hasSymbol(GET_COMPILER_VERSION_SYMBOL) || !hasSymbol(GET_BUILD_TYPE_SYMBOL))
+   {
+      throw TskException("version info interface not implemented");
+   }
+
+   int frameworkVersion = TskVersionInfo::getFrameworkVersion();
+   typedef int (*GetFrameworkVersion)();
+   GetFrameworkVersion getFrameworkVersion = (GetFrameworkVersion) m_sharedLibrary.getSymbol(TskPluginModule::GET_FRAMEWORK_VERSION_SYMBOL);
+   int moduleFrameworkVersion = getFrameworkVersion();
+   if (((frameworkVersion >> 16) & 0xFFFF)  != (( moduleFrameworkVersion >> 16) & 0xFFFF))
+   {
+      throw TskException("TskPluginModule::validateLibraryVersionInfo : framework version mismatch");
+   }
+
+   typedef TskVersionInfo::Compiler (*GetCompiler)();
+   GetCompiler getCompiler = (GetCompiler) m_sharedLibrary.getSymbol(TskPluginModule::GET_COMPILER_SYMBOL);
+   if (TskVersionInfo::getCompiler() != getCompiler())
+   {
+      throw TskException("TskPluginModule::validateLibraryVersionInfo : compiler mismatch");
+   }
+
+   typedef int (*GetCompilerVersion)();
+   GetCompilerVersion getCompilerVersion = (GetCompilerVersion) m_sharedLibrary.getSymbol(TskPluginModule::GET_COMPILER_VERSION_SYMBOL);
+   if (TskVersionInfo::getCompilerVersion() != getCompilerVersion())
+   {
+      throw TskException("TskPluginModule::validateLibraryVersionInfo : compiler version mismatch");
+   }
+
+   typedef TskVersionInfo::BuildType (*GetBuildType)();
+   GetBuildType getBuildType = (GetBuildType) m_sharedLibrary.getSymbol(TskPluginModule::GET_BUILD_TYPE_SYMBOL);
+   if (TskVersionInfo::getBuildType() != getBuildType())
+   {
+      throw TskException("TskPluginModule::validateLibraryVersionInfo : build target mismatch");
+   }
+}
diff --git a/framework/tsk/framework/pipeline/TskPluginModule.h b/framework/tsk/framework/pipeline/TskPluginModule.h
index c277dd3..1475260 100755
--- a/framework/tsk/framework/pipeline/TskPluginModule.h
+++ b/framework/tsk/framework/pipeline/TskPluginModule.h
@@ -1,102 +1,102 @@
-/*
- * 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_PLUGINMODULE_H
-#define _TSK_PLUGINMODULE_H
-
-// TSK Framework includes
-#include "TskModule.h"
-
-// Poco includes
-#include "Poco/SharedLibrary.h"
-
-/**
- * Supports the loading of a custom dynamic library to perform
- * analysis in either a TskPipeline or TskReportPipeline.
- */
-class TSK_FRAMEWORK_API TskPluginModule: public TskModule
-{
-public:
-    /** 
-     * Destructor that calls the finalize function of the module library and
-     * unloads the library.
-     */
-    virtual ~TskPluginModule();
-
-    /**
-     * Loads the module library.
-     *
-     * @param location Either a relative or fully qualified path to the module 
-     * library.
-     */
-    virtual void setPath(const std::string &location);
-
-    /**
-     * Calls the initialize function in the module library, if present.
-     */
-    TskModule::Status initialize();
-
-    /**
-     * Verifies that the required interface for a plugin module is defined by the module library. 
-     * 
-     * @return Throws TskException if the required interface is not defined.
-     */
-    virtual void checkInterface() = 0;
-
-protected:
-    static const std::string GET_COMPILER_SYMBOL;
-    static const std::string GET_COMPILER_VERSION_SYMBOL;
-    static const std::string GET_FRAMEWORK_VERSION_SYMBOL;
-    static const std::string GET_BUILD_TYPE_SYMBOL;
-    static const std::string NAME_SYMBOL;
-    static const std::string DESCRIPTION_SYMBOL;
-    static const std::string VERSION_SYMBOL;
-    static const std::string RUN_SYMBOL;
-    static const std::string REPORT_SYMBOL;
-    static const std::string INITIALIZE_SYMBOL;
-    static const std::string FINALIZE_SYMBOL;
-
-    /** 
-     * Checks whether or not the module library is loaded.
-     *
-     * @returns True if the module library is loaded.
-     */ 
-    bool isLoaded() const;
-
-    /**
-     * Checks whether or not the module library defines a particular symbol.
-     *
-     * @param symbol The symbol.
-     * @returns True if the symbol is defined, false otherwise.
-     */
-    bool hasSymbol(const std::string symbol);
-
-    /** 
-     * Get a pointer to a function in the module library.
-     *
-     * @param symbol The symbol associated with the desired pointer.
-     * @returns A pointer to the module library function corresponding to symbol.
-     * Throws Poco::NotFoundException if symbol is not found.
-     */
-    void *getSymbol(const std::string symbol);
-
-private:
-    /**
-     * Checks whether or not the module library was compiled with the same
-     * framework library version (major and minor version number components), 
-     * compiler, compiler version, and build target as the disk image 
-     * processing system that is loading the module.
-     */
-   void validateLibraryVersionInfo();
-
-    Poco::SharedLibrary m_sharedLibrary;
-};
-
-#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_PLUGINMODULE_H
+#define _TSK_PLUGINMODULE_H
+
+// TSK Framework includes
+#include "TskModule.h"
+
+// Poco includes
+#include "Poco/SharedLibrary.h"
+
+/**
+ * Supports the loading of a custom dynamic library to perform
+ * analysis in either a TskPipeline or TskReportPipeline.
+ */
+class TSK_FRAMEWORK_API TskPluginModule: public TskModule
+{
+public:
+    /** 
+     * Destructor that calls the finalize function of the module library and
+     * unloads the library.
+     */
+    virtual ~TskPluginModule();
+
+    /**
+     * Loads the module library.
+     *
+     * @param location Either a relative or fully qualified path to the module 
+     * library.
+     */
+    virtual void setPath(const std::string &location);
+
+    /**
+     * Calls the initialize function in the module library, if present.
+     */
+    TskModule::Status initialize();
+
+    /**
+     * Verifies that the required interface for a plugin module is defined by the module library. 
+     * 
+     * @return Throws TskException if the required interface is not defined.
+     */
+    virtual void checkInterface() = 0;
+
+protected:
+    static const std::string GET_COMPILER_SYMBOL;
+    static const std::string GET_COMPILER_VERSION_SYMBOL;
+    static const std::string GET_FRAMEWORK_VERSION_SYMBOL;
+    static const std::string GET_BUILD_TYPE_SYMBOL;
+    static const std::string NAME_SYMBOL;
+    static const std::string DESCRIPTION_SYMBOL;
+    static const std::string VERSION_SYMBOL;
+    static const std::string RUN_SYMBOL;
+    static const std::string REPORT_SYMBOL;
+    static const std::string INITIALIZE_SYMBOL;
+    static const std::string FINALIZE_SYMBOL;
+
+    /** 
+     * Checks whether or not the module library is loaded.
+     *
+     * @returns True if the module library is loaded.
+     */ 
+    bool isLoaded() const;
+
+    /**
+     * Checks whether or not the module library defines a particular symbol.
+     *
+     * @param symbol The symbol.
+     * @returns True if the symbol is defined, false otherwise.
+     */
+    bool hasSymbol(const std::string symbol);
+
+    /** 
+     * Get a pointer to a function in the module library.
+     *
+     * @param symbol The symbol associated with the desired pointer.
+     * @returns A pointer to the module library function corresponding to symbol.
+     * Throws Poco::NotFoundException if symbol is not found.
+     */
+    void *getSymbol(const std::string symbol);
+
+private:
+    /**
+     * Checks whether or not the module library was compiled with the same
+     * framework library version (major and minor version number components), 
+     * compiler, compiler version, and build target as the disk image 
+     * processing system that is loading the module.
+     */
+   void validateLibraryVersionInfo();
+
+    Poco::SharedLibrary m_sharedLibrary;
+};
+
+#endif
diff --git a/framework/tsk/framework/pipeline/TskReportPipeline.cpp b/framework/tsk/framework/pipeline/TskReportPipeline.cpp
index ea27ffb..b76da54 100755
--- a/framework/tsk/framework/pipeline/TskReportPipeline.cpp
+++ b/framework/tsk/framework/pipeline/TskReportPipeline.cpp
@@ -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 TskReportPipeline.cpp
- * Contains the implementation for the TskReportPipeline class.
- */
-
-// Include the class definition first to ensure it does not depend on subsequent includes in this file.
-#include "TskReportPipeline.h"
-
-// TSK Framework includes
-#include "tsk/framework/services/TskServices.h"
-
-// Poco includes
-#include "Poco/Stopwatch.h"
-
-// C/C++ library includes
-#include <sstream>
-
-void TskReportPipeline::run()
-{
-    Poco::Stopwatch stopWatch;
-    for (size_t i = 0; i < m_modules.size(); i++)
-    {
-        stopWatch.restart();
-        TskModule::Status status = m_modules[i]->report();
-        stopWatch.stop();
-        updateModuleExecutionTime(m_modules[i]->getModuleId(), stopWatch.elapsed());
-
-        TskServices::Instance().getImgDB().setModuleStatus(0, m_modules[i]->getModuleId(), (int)status);
-
-        // The reporting pipeline continues to run on module failure. Only shutdown the pipeline if a module signals STOP.
-        if (status == TskModule::STOP)
-        {
-            break;
-        }
-    }
-}
+/*
+ * 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 TskReportPipeline.cpp
+ * Contains the implementation for the TskReportPipeline class.
+ */
+
+// Include the class definition first to ensure it does not depend on subsequent includes in this file.
+#include "TskReportPipeline.h"
+
+// TSK Framework includes
+#include "tsk/framework/services/TskServices.h"
+
+// Poco includes
+#include "Poco/Stopwatch.h"
+
+// C/C++ library includes
+#include <sstream>
+
+void TskReportPipeline::run()
+{
+    Poco::Stopwatch stopWatch;
+    for (size_t i = 0; i < m_modules.size(); i++)
+    {
+        stopWatch.restart();
+        TskModule::Status status = m_modules[i]->report();
+        stopWatch.stop();
+        updateModuleExecutionTime(m_modules[i]->getModuleId(), stopWatch.elapsed());
+
+        TskServices::Instance().getImgDB().setModuleStatus(0, m_modules[i]->getModuleId(), (int)status);
+
+        // The reporting pipeline continues to run on module failure. Only shutdown the pipeline if a module signals STOP.
+        if (status == TskModule::STOP)
+        {
+            break;
+        }
+    }
+}
diff --git a/framework/tsk/framework/pipeline/TskReportPipeline.h b/framework/tsk/framework/pipeline/TskReportPipeline.h
index ebf414f..fc274ea 100755
--- a/framework/tsk/framework/pipeline/TskReportPipeline.h
+++ b/framework/tsk/framework/pipeline/TskReportPipeline.h
@@ -1,58 +1,58 @@
-/*
- * 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 TskReportPipeline.h
- * Contains the interface for the TskReportPipeline class.
- */
-
-#ifndef _TSK_REPORTPIPELINE_H
-#define _TSK_REPORTPIPELINE_H
-
-// TSK Framework includes
-#include "TskPipeline.h"
-#include "TskReportPluginModule.h"
-#include "tsk/framework/utilities/TskException.h"
-
-// C/C++ library includes
-#include <string>
-
-/**
- * Controls a series of reporting modules that are run
- * after all of the file-specific analysis modules are run.
- * The reporting pipeline can contain one or more TskModule
- * modules.
- */
-class TSK_FRAMEWORK_API TskReportPipeline : public TskPipeline
-{
-public:
-    // Doxygen comment in base class.
-    virtual void run(const uint64_t fileId) 
-    { 
-        throw TskException("TskReportPipeline::run : not implemented"); 
-    }
-
-    // Doxygen comment in base class.
-    virtual void run(TskFile *file) 
-    { 
-        throw TskException("TskReportPipeline::run : not implemented"); 
-    }
-
-    // Doxygen comment in base class.
-    virtual void run();
-
-    // Doxygen comment in base class.
-    virtual TskPluginModule *createPluginModule() 
-    { 
-        return (new TskReportPluginModule());
-    }
-};
-
-#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 TskReportPipeline.h
+ * Contains the interface for the TskReportPipeline class.
+ */
+
+#ifndef _TSK_REPORTPIPELINE_H
+#define _TSK_REPORTPIPELINE_H
+
+// TSK Framework includes
+#include "TskPipeline.h"
+#include "TskReportPluginModule.h"
+#include "tsk/framework/utilities/TskException.h"
+
+// C/C++ library includes
+#include <string>
+
+/**
+ * Controls a series of reporting modules that are run
+ * after all of the file-specific analysis modules are run.
+ * The reporting pipeline can contain one or more TskModule
+ * modules.
+ */
+class TSK_FRAMEWORK_API TskReportPipeline : public TskPipeline
+{
+public:
+    // Doxygen comment in base class.
+    virtual void run(const uint64_t fileId) 
+    { 
+        throw TskException("TskReportPipeline::run : not implemented"); 
+    }
+
+    // Doxygen comment in base class.
+    virtual void run(TskFile *file) 
+    { 
+        throw TskException("TskReportPipeline::run : not implemented"); 
+    }
+
+    // Doxygen comment in base class.
+    virtual void run();
+
+    // Doxygen comment in base class.
+    virtual TskPluginModule *createPluginModule() 
+    { 
+        return (new TskReportPluginModule());
+    }
+};
+
+#endif
diff --git a/framework/tsk/framework/pipeline/TskReportPluginModule.cpp b/framework/tsk/framework/pipeline/TskReportPluginModule.cpp
index 0a92d24..2261e95 100755
--- a/framework/tsk/framework/pipeline/TskReportPluginModule.cpp
+++ b/framework/tsk/framework/pipeline/TskReportPluginModule.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 TskReportPluginModule.cpp
- * Contains the implementation for the TskReportPluginModule class.
- */
-
-// Include the class definition first to ensure it does not depend on subsequent includes in this file.
-#include "TskReportPluginModule.h"
-
-// TSK Framework includes
-#include "tsk/framework/services/TskServices.h"
-#include "tsk/framework/utilities/TskException.h"
-
-// C/C++ includes
-#include <sstream>
-
-TskModule::Status TskReportPluginModule::report()
-{
-    const std::string MSG_PREFIX = "TskReportPluginModule::report : ";
-    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::REPORT_SYMBOL)) 
-        {
-            std::stringstream msg;
-            msg << MSG_PREFIX << "'" << getPath() << "' does not define the '" << TskPluginModule::REPORT_SYMBOL << "' symbol";
-            throw TskException(msg.str());
-        }
-
-        typedef TskModule::Status (*ReportFunc)();
-        ReportFunc report = (ReportFunc)getSymbol(TskPluginModule::REPORT_SYMBOL);
-        status = report();
-    }
-    catch (TskException &ex) 
-    {
-        std::stringstream msg;
-        msg << MSG_PREFIX << "TskException executing report function of " << getName() << ": " << ex.message();
-        LOGERROR(msg.str());
-        status = TskModule::FAIL;
-    }
-    catch (Poco::Exception &ex) 
-    {
-        std::stringstream msg;
-        msg << MSG_PREFIX <<  "Poco::Exception executing report function of "  << getName() << ": " << ex.displayText();
-        LOGERROR(msg.str());
-        status = TskModule::FAIL;
-    }
-    catch (std::exception &ex) 
-    {
-        std::stringstream msg;
-        msg << MSG_PREFIX <<  "std::exception executing report function of "  << getName() << ": " << ex.what();
-        LOGERROR(msg.str());
-        status = TskModule::FAIL;
-    }
-    catch (...)
-    {
-        std::stringstream msg;
-        msg << MSG_PREFIX << "unrecognized exception executing report function of "  << getName();
-        LOGERROR(msg.str());
-        status = TskModule::FAIL;
-    }
-
-    return status;
-}
-
-void TskReportPluginModule::checkInterface()
-{
-    const std::string MSG_PREFIX = "TskReportPluginModule::checkInterface : ";
-
-    if (!isLoaded())
-    {
-        std::stringstream msg;
-        msg << MSG_PREFIX << getPath() << " is not loaded";
-        LOGERROR(msg.str());
-        throw TskException(msg.str());
-    }
-
-    if (!hasSymbol(TskPluginModule::REPORT_SYMBOL)) 
-    {
-        std::stringstream msg;
-        msg << MSG_PREFIX << getPath() << " does not define the required '" << TskPluginModule::REPORT_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 TskReportPluginModule.cpp
+ * Contains the implementation for the TskReportPluginModule class.
+ */
+
+// Include the class definition first to ensure it does not depend on subsequent includes in this file.
+#include "TskReportPluginModule.h"
+
+// TSK Framework includes
+#include "tsk/framework/services/TskServices.h"
+#include "tsk/framework/utilities/TskException.h"
+
+// C/C++ includes
+#include <sstream>
+
+TskModule::Status TskReportPluginModule::report()
+{
+    const std::string MSG_PREFIX = "TskReportPluginModule::report : ";
+    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::REPORT_SYMBOL)) 
+        {
+            std::stringstream msg;
+            msg << MSG_PREFIX << "'" << getPath() << "' does not define the '" << TskPluginModule::REPORT_SYMBOL << "' symbol";
+            throw TskException(msg.str());
+        }
+
+        typedef TskModule::Status (*ReportFunc)();
+        ReportFunc report = (ReportFunc)getSymbol(TskPluginModule::REPORT_SYMBOL);
+        status = report();
+    }
+    catch (TskException &ex) 
+    {
+        std::stringstream msg;
+        msg << MSG_PREFIX << "TskException executing report function of " << getName() << ": " << ex.message();
+        LOGERROR(msg.str());
+        status = TskModule::FAIL;
+    }
+    catch (Poco::Exception &ex) 
+    {
+        std::stringstream msg;
+        msg << MSG_PREFIX <<  "Poco::Exception executing report function of "  << getName() << ": " << ex.displayText();
+        LOGERROR(msg.str());
+        status = TskModule::FAIL;
+    }
+    catch (std::exception &ex) 
+    {
+        std::stringstream msg;
+        msg << MSG_PREFIX <<  "std::exception executing report function of "  << getName() << ": " << ex.what();
+        LOGERROR(msg.str());
+        status = TskModule::FAIL;
+    }
+    catch (...)
+    {
+        std::stringstream msg;
+        msg << MSG_PREFIX << "unrecognized exception executing report function of "  << getName();
+        LOGERROR(msg.str());
+        status = TskModule::FAIL;
+    }
+
+    return status;
+}
+
+void TskReportPluginModule::checkInterface()
+{
+    const std::string MSG_PREFIX = "TskReportPluginModule::checkInterface : ";
+
+    if (!isLoaded())
+    {
+        std::stringstream msg;
+        msg << MSG_PREFIX << getPath() << " is not loaded";
+        LOGERROR(msg.str());
+        throw TskException(msg.str());
+    }
+
+    if (!hasSymbol(TskPluginModule::REPORT_SYMBOL)) 
+    {
+        std::stringstream msg;
+        msg << MSG_PREFIX << getPath() << " does not define the required '" << TskPluginModule::REPORT_SYMBOL << "' symbol";
+        throw TskException(msg.str());
+    }
+}
diff --git a/framework/tsk/framework/pipeline/TskReportPluginModule.h b/framework/tsk/framework/pipeline/TskReportPluginModule.h
index 6e0c727..a416eef 100755
--- a/framework/tsk/framework/pipeline/TskReportPluginModule.h
+++ b/framework/tsk/framework/pipeline/TskReportPluginModule.h
@@ -1,34 +1,34 @@
-/*
- * 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_REPORTPLUGINMODULE_H
-#define _TSK_REPORTPLUGINMODULE_H
-
-// TSK Framework includes
-#include "TskPluginModule.h"
-
-/**
- * Supports the use of custom dynamic libraries to perform
- * reporting and post-processing in a TskReportPipeline.
- */
-class TSK_FRAMEWORK_API TskReportPluginModule: public TskPluginModule
-{
-public:
-    // Doxygen comment in base class.
-    virtual Status run(TskFile *fileToAnalyze) { return report(); };
-
-    // Doxygen comment in base class.
-    virtual Status report();
-
-    // 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_REPORTPLUGINMODULE_H
+#define _TSK_REPORTPLUGINMODULE_H
+
+// TSK Framework includes
+#include "TskPluginModule.h"
+
+/**
+ * Supports the use of custom dynamic libraries to perform
+ * reporting and post-processing in a TskReportPipeline.
+ */
+class TSK_FRAMEWORK_API TskReportPluginModule: public TskPluginModule
+{
+public:
+    // Doxygen comment in base class.
+    virtual Status run(TskFile *fileToAnalyze) { return report(); };
+
+    // Doxygen comment in base class.
+    virtual Status report();
+
+    // Doxygen comment in base class.
+    virtual void checkInterface();
+};
+
+#endif
diff --git a/framework/tsk/framework/services/Log.cpp b/framework/tsk/framework/services/Log.cpp
index 950d9af..7f487ae 100755
--- a/framework/tsk/framework/services/Log.cpp
+++ b/framework/tsk/framework/services/Log.cpp
@@ -1,160 +1,160 @@
-/*
- * 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.h>
-#include <errno.h>
-#include "string.h"
-#include "Log.h"
-#include "tsk/framework/utilities/TskUtilities.h"
-#include "sys/stat.h"
-#include <time.h>
-#include "Poco/FileStream.h"
-#include "Poco/Exception.h"
-#include "Poco/LineEndingConverter.h"
-
-// @@@ imports for directory creation and deletion
-//#include "windows.h"
-
-
-Log::Log()
-: m_filePath(""), m_outStream()
-{
-}
-
-
-/**
- * Opens a single log file with a default name, based on the time
- * that the log was opened.
- * @returns 1 on error and 0 on success.
- */
-int Log::open()
-{
-    struct tm *newtime;
-    time_t aclock;
-
-    time(&aclock);   // Get time in seconds
-    newtime = localtime(&aclock);   // Convert time to struct tm form 
-    wchar_t filename[MAX_BUFF_LENGTH];
-    swprintf(filename, MAX_BUFF_LENGTH, L"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);
-
-    return open(filename);
-}
-/**
- * Open the single log file at the path specified. All messages
- * will be printed to the log.
- * @param a_logFileFullPath Path to logfile to open.
- * @returns 1 on error and 0 on success.
- */
-int Log::open(const wchar_t * a_logFileFullPath)
-{
-    return open(TskUtilities::toUTF8(a_logFileFullPath).c_str());
-}
-
-int Log::open(const char * a_logFileFullPath)
-{
-    close(); // if needed
-
-    try {
-        m_outStream.open(a_logFileFullPath, std::ios::app);
-    } catch (const std::exception ex) {
-        printf("The file '%s' cannot be opened. Exception: %s\n", a_logFileFullPath, ex.what());
-        return 1;
-    }
-
-    m_filePath.assign(a_logFileFullPath);
-
-    return 0;
-}
-
-/**
- * Close the opened log file.
- * @returns 0 on success
- */
-int Log::close()
-{
-    m_outStream.close();
-    if (m_outStream.bad()) {
-        printf("The file '%s' was not closed.", m_filePath.c_str());
-        return 1;
-    }
-    return 0;
-}
-
-Log::~Log()
-{
-    close();
-}
-
-
-void Log::logf(Channel a_channel, char const *format, ...)
-{
-    va_list args;
-    va_start(args, format);
-
-    char buf[2048];
-#ifdef TSK_WIN32
-    vsnprintf_s(buf, 2048, _TRUNCATE, format, args);
-#else
-    buf[2047] = '\0';
-    vsnprintf(buf, 2047, format, args);
-#endif
-    std::string msg(buf);
-    log(a_channel, buf);
-    va_end(args);
-}
-
-void Log::log(Channel a_channel, const std::string &a_msg)
-{
-    std::string level;
-    switch (a_channel) {
-    case Error:
-        level.assign("[ERROR]");
-        break;
-    case Warn:
-        level.assign("[WARN]");
-        break;
-    case Info:
-        level.assign("[INFO]");
-        break;
-    }
-
-    struct tm *newtime;
-    time_t aclock;
-
-    time(&aclock);   // Get time in seconds
-    newtime = localtime(&aclock);   // Convert time to struct tm form 
-    char timeStr[64];
-    snprintf(timeStr, 64, "%.2d/%.2d/%.2d %.2d:%.2d:%.2d",
-        newtime->tm_mon+1,newtime->tm_mday,newtime->tm_year % 100, 
-        newtime->tm_hour, newtime->tm_min, newtime->tm_sec);
-
-    if (m_outStream.good()) {
-        m_outStream << timeStr << " " << level << " " << a_msg << Poco::LineEnding::NEWLINE_DEFAULT;
-        m_outStream.flush();
-    }
-    else {
-        fprintf(stderr, "%s %s %s\n", timeStr, level.data(), a_msg.data());
-    }
-}
-
-void Log::log(Channel a_channel, const std::wstring &a_msg)
-{
-    log(a_channel, TskUtilities::toUTF8(a_msg).c_str());
-}
-/**
- * Return the path to the log file.
- * @returns path to log or NULL if log is going to STDERR
- */
-const wchar_t * Log::getLogPathW()
-{
-    return (const wchar_t *)TskUtilities::toUTF16(m_filePath).c_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
+ */
+
+#include <string.h>
+#include <errno.h>
+#include "string.h"
+#include "Log.h"
+#include "tsk/framework/utilities/TskUtilities.h"
+#include "sys/stat.h"
+#include <time.h>
+#include "Poco/FileStream.h"
+#include "Poco/Exception.h"
+#include "Poco/LineEndingConverter.h"
+
+// @@@ imports for directory creation and deletion
+//#include "windows.h"
+
+
+Log::Log()
+: m_filePath(""), m_outStream()
+{
+}
+
+
+/**
+ * Opens a single log file with a default name, based on the time
+ * that the log was opened.
+ * @returns 1 on error and 0 on success.
+ */
+int Log::open()
+{
+    struct tm *newtime;
+    time_t aclock;
+
+    time(&aclock);   // Get time in seconds
+    newtime = localtime(&aclock);   // Convert time to struct tm form 
+    wchar_t filename[MAX_BUFF_LENGTH];
+    swprintf(filename, MAX_BUFF_LENGTH, L"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);
+
+    return open(filename);
+}
+/**
+ * Open the single log file at the path specified. All messages
+ * will be printed to the log.
+ * @param a_logFileFullPath Path to logfile to open.
+ * @returns 1 on error and 0 on success.
+ */
+int Log::open(const wchar_t * a_logFileFullPath)
+{
+    return open(TskUtilities::toUTF8(a_logFileFullPath).c_str());
+}
+
+int Log::open(const char * a_logFileFullPath)
+{
+    close(); // if needed
+
+    try {
+        m_outStream.open(a_logFileFullPath, std::ios::app);
+    } catch (const std::exception ex) {
+        printf("The file '%s' cannot be opened. Exception: %s\n", a_logFileFullPath, ex.what());
+        return 1;
+    }
+
+    m_filePath.assign(a_logFileFullPath);
+
+    return 0;
+}
+
+/**
+ * Close the opened log file.
+ * @returns 0 on success
+ */
+int Log::close()
+{
+    m_outStream.close();
+    if (m_outStream.bad()) {
+        printf("The file '%s' was not closed.", m_filePath.c_str());
+        return 1;
+    }
+    return 0;
+}
+
+Log::~Log()
+{
+    close();
+}
+
+
+void Log::logf(Channel a_channel, char const *format, ...)
+{
+    va_list args;
+    va_start(args, format);
+
+    char buf[2048];
+#ifdef TSK_WIN32
+    vsnprintf_s(buf, 2048, _TRUNCATE, format, args);
+#else
+    buf[2047] = '\0';
+    vsnprintf(buf, 2047, format, args);
+#endif
+    std::string msg(buf);
+    log(a_channel, buf);
+    va_end(args);
+}
+
+void Log::log(Channel a_channel, const std::string &a_msg)
+{
+    std::string level;
+    switch (a_channel) {
+    case Error:
+        level.assign("[ERROR]");
+        break;
+    case Warn:
+        level.assign("[WARN]");
+        break;
+    case Info:
+        level.assign("[INFO]");
+        break;
+    }
+
+    struct tm *newtime;
+    time_t aclock;
+
+    time(&aclock);   // Get time in seconds
+    newtime = localtime(&aclock);   // Convert time to struct tm form 
+    char timeStr[64];
+    snprintf(timeStr, 64, "%.2d/%.2d/%.2d %.2d:%.2d:%.2d",
+        newtime->tm_mon+1,newtime->tm_mday,newtime->tm_year % 100, 
+        newtime->tm_hour, newtime->tm_min, newtime->tm_sec);
+
+    if (m_outStream.good()) {
+        m_outStream << timeStr << " " << level << " " << a_msg << Poco::LineEnding::NEWLINE_DEFAULT;
+        m_outStream.flush();
+    }
+    else {
+        fprintf(stderr, "%s %s %s\n", timeStr, level.data(), a_msg.data());
+    }
+}
+
+void Log::log(Channel a_channel, const std::wstring &a_msg)
+{
+    log(a_channel, TskUtilities::toUTF8(a_msg).c_str());
+}
+/**
+ * Return the path to the log file.
+ * @returns path to log or NULL if log is going to STDERR
+ */
+const wchar_t * Log::getLogPathW()
+{
+    return (const wchar_t *)TskUtilities::toUTF16(m_filePath).c_str();
+}
diff --git a/framework/tsk/framework/services/Log.h b/framework/tsk/framework/services/Log.h
index 3edffd5..47e84b8 100755
--- a/framework/tsk/framework/services/Log.h
+++ b/framework/tsk/framework/services/Log.h
@@ -1,132 +1,132 @@
-/*
- * 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 _OSS_LOG_H
-#define _OSS_LOG_H
-
-#include "tsk/framework/framework_i.h"
-#include <time.h>
-#include <string>
-#include <iostream>
-#include <fstream>
-
-// @@@ TODO: Resolve circular references between TskServices.h and this header by replacing macros with inline functions in TskServices.h
-
-/**
- * \file Log.h
- * Interface and default logging infrastructure that enables applications and framework
- * to log to a single place.  
- */
-
-/**
- * Macro that gets the log service and writes an error message in a
- * single statement. 
- * @param msg Message to log
- * @returns void
- */
-#define LOGERROR(msg) TskServices::Instance().getLog().log(Log::Error, msg)
-
-/**
- * Macro that gets the log service and writes a warning message in a
- * single statement. 
- * @param msg Message to log
- * @returns void
- */
-#define LOGWARN(msg) TskServices::Instance().getLog().log(Log::Warn, msg)
-
-
-/**
- * Macro that gets the log service and writes an info message in a
- * single statement. 
- * @param msg Message to log
- * @returns void
- */
-#define LOGINFO(msg) TskServices::Instance().getLog().log(Log::Info, msg)
-
-
-/**
- * Logging class to enable the framework, apps that use it, and modules to
- * log error and warning messages.  The default implementation writes
- * the log messages to a file if open() was called or prints the messages to
- * stderr if open() was never called. The class can be extended 
- * if you want logs to be saved in another way.
- * Can be registered with and retrieved from TskServices.
- *
- * Developers can either directly call the log() method with the logging
- * level, can call the logError(), etc. methods on the class or use the
- * LOGERROR() etc. macros, which will also get the Log service from TskServices.
- */
-class TSK_FRAMEWORK_API Log
-{
-public:
-    /** 
-     * Defined logging levels.
-     */
-    enum Channel {
-        Error, ///< Critical error that stops processing
-        Warn,  ///< Unexpected results that could be recovered from
-        Info    ///< General debugging information
-    };
-
-    Log();
-    virtual ~Log();
-
-    /**
-     * Generate a log message with a given level (wide string).
-     * @param a_channel Level of log to make
-     * @param a_msg Message to record.
-     */
-    virtual void log(Channel a_channel, const std::wstring &a_msg);
-
-    /**
-     * Generate a log message with a given level (narrow string).
-     * @param a_channel Level of log to make
-     * @param a_msg Message to record.
-     */
-    virtual void log(Channel a_channel, const std::string &a_msg);
-
-    /**
-     * Generate a log message with a given level (printf-style arguments).
-     * @param a_channel Level of log to make
-     * @param format Message to record.
-     */
-    virtual void logf(Channel a_channel, char const *format, ...);
-
-
-    /**
-     * Log an error message.
-     * @param msg Message to log
-     */
-    void logError(const std::wstring &msg) { log(Log::Error, msg); };
-
-    /**
-     * Log a warning message.
-     * @param msg Message to log
-     */
-    void logWarn(const std::wstring &msg)  { log(Log::Warn,  msg); };
-
-    /**
-     * Log an info message.
-     * @param msg Message to log
-     */
-    void logInfo(const std::wstring &msg)  { log(Log::Info,  msg); };
-
-    int open(const wchar_t * a_logFileFullPath);
-    int open(const char * a_outDir);
-    int open();
-    int close();
-    const wchar_t * getLogPathW();
-    const char * getLogPath() { return m_filePath.c_str(); }
-
-protected:
-    std::string m_filePath;
-    std::ofstream m_outStream;
-};
-#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 _OSS_LOG_H
+#define _OSS_LOG_H
+
+#include "tsk/framework/framework_i.h"
+#include <time.h>
+#include <string>
+#include <iostream>
+#include <fstream>
+
+// @@@ TODO: Resolve circular references between TskServices.h and this header by replacing macros with inline functions in TskServices.h
+
+/**
+ * \file Log.h
+ * Interface and default logging infrastructure that enables applications and framework
+ * to log to a single place.  
+ */
+
+/**
+ * Macro that gets the log service and writes an error message in a
+ * single statement. 
+ * @param msg Message to log
+ * @returns void
+ */
+#define LOGERROR(msg) TskServices::Instance().getLog().log(Log::Error, msg)
+
+/**
+ * Macro that gets the log service and writes a warning message in a
+ * single statement. 
+ * @param msg Message to log
+ * @returns void
+ */
+#define LOGWARN(msg) TskServices::Instance().getLog().log(Log::Warn, msg)
+
+
+/**
+ * Macro that gets the log service and writes an info message in a
+ * single statement. 
+ * @param msg Message to log
+ * @returns void
+ */
+#define LOGINFO(msg) TskServices::Instance().getLog().log(Log::Info, msg)
+
+
+/**
+ * Logging class to enable the framework, apps that use it, and modules to
+ * log error and warning messages.  The default implementation writes
+ * the log messages to a file if open() was called or prints the messages to
+ * stderr if open() was never called. The class can be extended 
+ * if you want logs to be saved in another way.
+ * Can be registered with and retrieved from TskServices.
+ *
+ * Developers can either directly call the log() method with the logging
+ * level, can call the logError(), etc. methods on the class or use the
+ * LOGERROR() etc. macros, which will also get the Log service from TskServices.
+ */
+class TSK_FRAMEWORK_API Log
+{
+public:
+    /** 
+     * Defined logging levels.
+     */
+    enum Channel {
+        Error, ///< Critical error that stops processing
+        Warn,  ///< Unexpected results that could be recovered from
+        Info    ///< General debugging information
+    };
+
+    Log();
+    virtual ~Log();
+
+    /**
+     * Generate a log message with a given level (wide string).
+     * @param a_channel Level of log to make
+     * @param a_msg Message to record.
+     */
+    virtual void log(Channel a_channel, const std::wstring &a_msg);
+
+    /**
+     * Generate a log message with a given level (narrow string).
+     * @param a_channel Level of log to make
+     * @param a_msg Message to record.
+     */
+    virtual void log(Channel a_channel, const std::string &a_msg);
+
+    /**
+     * Generate a log message with a given level (printf-style arguments).
+     * @param a_channel Level of log to make
+     * @param format Message to record.
+     */
+    virtual void logf(Channel a_channel, char const *format, ...);
+
+
+    /**
+     * Log an error message.
+     * @param msg Message to log
+     */
+    void logError(const std::wstring &msg) { log(Log::Error, msg); };
+
+    /**
+     * Log a warning message.
+     * @param msg Message to log
+     */
+    void logWarn(const std::wstring &msg)  { log(Log::Warn,  msg); };
+
+    /**
+     * Log an info message.
+     * @param msg Message to log
+     */
+    void logInfo(const std::wstring &msg)  { log(Log::Info,  msg); };
+
+    int open(const wchar_t * a_logFileFullPath);
+    int open(const char * a_outDir);
+    int open();
+    int close();
+    const wchar_t * getLogPathW();
+    const char * getLogPath() { return m_filePath.c_str(); }
+
+protected:
+    std::string m_filePath;
+    std::ofstream m_outStream;
+};
+#endif
diff --git a/framework/tsk/framework/services/Scheduler.cpp b/framework/tsk/framework/services/Scheduler.cpp
index 61fb4fe..062a743 100755
--- a/framework/tsk/framework/services/Scheduler.cpp
+++ b/framework/tsk/framework/services/Scheduler.cpp
@@ -1,17 +1,17 @@
-/*
- * 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 "Scheduler.h"
-
-Scheduler::~Scheduler()
-{
-
-}
-
+/*
+ * 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 "Scheduler.h"
+
+Scheduler::~Scheduler()
+{
+
+}
+
diff --git a/framework/tsk/framework/services/Scheduler.h b/framework/tsk/framework/services/Scheduler.h
index 97805ba..57976b0 100755
--- a/framework/tsk/framework/services/Scheduler.h
+++ b/framework/tsk/framework/services/Scheduler.h
@@ -1,76 +1,76 @@
-/*
- * 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 _OSS_SCHEDULER_H
-#define _OSS_SCHEDULER_H
-
-#include "tsk/framework/framework_i.h"
-
-
-/**
- * Interface for class that will handle scheduling of tasks.  
- * Different implementations will deal with how to get the tasks out (nextTask())
- * because some will immediately schedule and others may keep a sorted
- * list locally.  
- * The current scheduler can be registered with and retrieved from TskServices.
- */
-class TSK_FRAMEWORK_API Scheduler
-{
-public:
-    /// Types of tasks that can be scheduled or performed. 
-    enum TaskType {
-        Extract, ///< Analyze image and add files to database.
-        Carve,  ///< Carve a file that contains unallocated data.
-        FileAnalysis,    ///< Analye a file using a file analysis pipeline
-        Reporting   ///< Run the reporting / post-processing pipeline
-    };
-
-    
-    /// Describes a single task to be scheduled or perform. 
-    typedef struct {
-        Scheduler::TaskType task;   ///< type of task to perform
-        uint64_t id;    ///< ID of object to run task on
-    } task_struct;
-
-    virtual ~Scheduler();
-    
-    /**
-     * Schedule a new task for the range of IDs.
-     * @param task Task to schedule
-     * @param startId Starting ID of object to process
-     * @param endId Ending ID of object to process.
-     * @returns 1 on error 
-     */
-    virtual int schedule(Scheduler::TaskType task, uint64_t startId, uint64_t endId) {
-        return 0;
-    };
-
-    /**
-     * Schedule a new task for a specific ID.
-     * @param task Task to schedule
-     * @returns 1 on error 
-     */
-    int schedule(Scheduler::task_struct &task) {
-        return schedule(task.task, task.id, task.id);
-    };
-
-    /**
-     * Get the next task to process from the scheduler.  Note that different
-     * scheduling systems have a pull versus push architecture. This method is for 
-     * pulling designs and may return NULL in push designs (i.e. if the scheduler is
-     * a wrapper around another distributed system scheduler, then it may constantly 
-     * push tasks to the system scheduler and this will always return NULL because everything
-     * has already been submitted).
-     * @returns Next task to run or NULL if there are none to process.  Caller must 
-     * free the object.
-     */
-    virtual task_struct *nextTask() = 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
+ */
+
+#ifndef _OSS_SCHEDULER_H
+#define _OSS_SCHEDULER_H
+
+#include "tsk/framework/framework_i.h"
+
+
+/**
+ * Interface for class that will handle scheduling of tasks.  
+ * Different implementations will deal with how to get the tasks out (nextTask())
+ * because some will immediately schedule and others may keep a sorted
+ * list locally.  
+ * The current scheduler can be registered with and retrieved from TskServices.
+ */
+class TSK_FRAMEWORK_API Scheduler
+{
+public:
+    /// Types of tasks that can be scheduled or performed. 
+    enum TaskType {
+        Extract, ///< Analyze image and add files to database.
+        Carve,  ///< Carve a file that contains unallocated data.
+        FileAnalysis,    ///< Analye a file using a file analysis pipeline
+        Reporting   ///< Run the reporting / post-processing pipeline
+    };
+
+    
+    /// Describes a single task to be scheduled or perform. 
+    typedef struct {
+        Scheduler::TaskType task;   ///< type of task to perform
+        uint64_t id;    ///< ID of object to run task on
+    } task_struct;
+
+    virtual ~Scheduler();
+    
+    /**
+     * Schedule a new task for the range of IDs.
+     * @param task Task to schedule
+     * @param startId Starting ID of object to process
+     * @param endId Ending ID of object to process.
+     * @returns 1 on error 
+     */
+    virtual int schedule(Scheduler::TaskType task, uint64_t startId, uint64_t endId) {
+        return 0;
+    };
+
+    /**
+     * Schedule a new task for a specific ID.
+     * @param task Task to schedule
+     * @returns 1 on error 
+     */
+    int schedule(Scheduler::task_struct &task) {
+        return schedule(task.task, task.id, task.id);
+    };
+
+    /**
+     * Get the next task to process from the scheduler.  Note that different
+     * scheduling systems have a pull versus push architecture. This method is for 
+     * pulling designs and may return NULL in push designs (i.e. if the scheduler is
+     * a wrapper around another distributed system scheduler, then it may constantly 
+     * push tasks to the system scheduler and this will always return NULL because everything
+     * has already been submitted).
+     * @returns Next task to run or NULL if there are none to process.  Caller must 
+     * free the object.
+     */
+    virtual task_struct *nextTask() = 0;
+};
+#endif
diff --git a/framework/tsk/framework/services/TskBlackboard.cpp b/framework/tsk/framework/services/TskBlackboard.cpp
index e056a0f..9b9a090 100755
--- a/framework/tsk/framework/services/TskBlackboard.cpp
+++ b/framework/tsk/framework/services/TskBlackboard.cpp
@@ -1,199 +1,228 @@
-/*
-* 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 "TskBlackboard.h"
-
-map<int, TskArtifactNames> initializeArtifactTypeMap(){
-    map<int, TskArtifactNames> retval;
-    retval.insert(pair<int, TskArtifactNames>(TSK_GEN_INFO, TskArtifactNames("TSK_GEN_INFO", "General Info")));
-    retval.insert(pair<int, TskArtifactNames>(TSK_WEB_BOOKMARK, TskArtifactNames("TSK_WEB_BOOKMARK", "Web Bookmark")));
-    retval.insert(pair<int, TskArtifactNames>(TSK_WEB_COOKIE, TskArtifactNames("TSK_WEB_COOKIE", "Web Cookie")));
-    retval.insert(pair<int, TskArtifactNames>(TSK_WEB_HISTORY, TskArtifactNames("TSK_WEB_HISTORY", "History")));
-    retval.insert(pair<int, TskArtifactNames>(TSK_WEB_DOWNLOAD, TskArtifactNames("TSK_WEB_DOWNLOAD", "Download")));
-    retval.insert(pair<int, TskArtifactNames>(TSK_RECENT_OBJECT, TskArtifactNames("TSK_RECENT_OBJECT", "Recent History Object")));
-    retval.insert(pair<int, TskArtifactNames>(TSK_TRACKPOINT, TskArtifactNames("TSK_TRACKPOINT", "Trackpoint")));
-    retval.insert(pair<int, TskArtifactNames>(TSK_INSTALLED_PROG, TskArtifactNames("TSK_INSTALLED_PROG", "Installed Program")));
-    retval.insert(pair<int, TskArtifactNames>(TSK_KEYWORD_HIT, TskArtifactNames("TSK_KEYWORD_HIT", "Keyword Hit")));
-    retval.insert(pair<int, TskArtifactNames>(TSK_HASHSET_HIT, TskArtifactNames("TSK_HASHSET_HIT", "Hashset Hit")));
-    retval.insert(pair<int, TskArtifactNames>(TSK_DEVICE_ATTACHED, TskArtifactNames("TSK_DEVICE_ATTACHED", "Device Attached")));
-    retval.insert(pair<int, TskArtifactNames>(TSK_INTERESTING_FILE_HIT, TskArtifactNames("TSK_INTERESTING_FILE_HIT", "Interesting File")));
-    retval.insert(pair<int, TskArtifactNames>(TSK_EMAIL_MSG, TskArtifactNames("TSK_EMAIL_MSG", "E-Mail Message")));
-    retval.insert(pair<int, TskArtifactNames>(TSK_EXTRACTED_TEXT, TskArtifactNames("TSK_EXTRACTED_TEXT", "Extracted Text")));
-    retval.insert(pair<int, TskArtifactNames>(TSK_WEB_SEARCH_QUERY, TskArtifactNames("TSK_WEB_SEARCH_QUERY", "Web Search Engine Query")));
-    retval.insert(pair<int, TskArtifactNames>(TSK_METADATA_EXIF, TskArtifactNames("TSK_METADATA_EXIF", "EXIF Metadata")));
-    retval.insert(pair<int, TskArtifactNames>(TSK_TAG_FILE, TskArtifactNames("TSK_TAG_FILE", "File Tag")));
-    retval.insert(pair<int, TskArtifactNames>(TSK_TAG_ARTIFACT, TskArtifactNames("TSK_TAG_ARTIFACT", "Result Tag")));
-    retval.insert(pair<int, TskArtifactNames>(TSK_OS_INFO, TskArtifactNames("TSK_OS_INFO", "Operating System Information")));
-    retval.insert(pair<int, TskArtifactNames>(TSK_OS_ACCOUNT, TskArtifactNames("TSK_OS_ACCOUNT", "Operating System User Account")));
-    retval.insert(pair<int, TskArtifactNames>(TSK_SERVICE_ACCOUNT, TskArtifactNames("TSK_SERVICE_ACCOUNT", "Network Service User Account")));
-
-    return retval;
-}
-
-map<int, TskAttributeNames> initializeAttributeTypeMap(){
-    map<int, TskAttributeNames> retval;
-    retval.insert(pair<int, TskAttributeNames>(TSK_URL, TskAttributeNames("TSK_URL", "URL")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_DATETIME, TskAttributeNames("TSK_DATETIME", "Datetime")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_NAME, TskAttributeNames("TSK_NAME", "Name")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_PROG_NAME, TskAttributeNames("TSK_PROG_NAME", "Program Name")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_VALUE, TskAttributeNames("TSK_VALUE", "Value")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_FLAG, TskAttributeNames("TSK_FLAG", "Flag")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_PATH, TskAttributeNames("TSK_PATH", "Path")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_KEYWORD, TskAttributeNames("TSK_KEYWORD", "Keyword")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_KEYWORD_REGEXP, TskAttributeNames("TSK_KEYWORD_REGEXP", "Keyword Regular Expression")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_KEYWORD_PREVIEW, TskAttributeNames("TSK_KEYWORD_PREVIEW", "Keyword Preview")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_KEYWORD_SET, TskAttributeNames("TSK_KEYWORD_SET", "Keyword Set")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_USER_NAME, TskAttributeNames("TSK_USER_NAME", "Username")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_DOMAIN, TskAttributeNames("TSK_DOMAIN", "Domain")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_PASSWORD, TskAttributeNames("TSK_PASSWORD", "Password")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_NAME_PERSON, TskAttributeNames("TSK_NAME_PERSON", "Person Name")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_DEVICE_MODEL, TskAttributeNames("TSK_DEVICE_MODEL", "Device Model")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_DEVICE_MAKE, TskAttributeNames("TSK_DEVICE_MAKE", "Device Make")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_DEVICE_ID, TskAttributeNames("TSK_DEVICE_ID", "Device ID")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_EMAIL, TskAttributeNames("TSK_EMAIL", "Email")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_HASH_MD5, TskAttributeNames("TSK_HASH_MD5", "MD5 Hash")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_HASH_SHA1, TskAttributeNames("TSK_HASH_SHA1", "SHA1 Hash")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_HASH_SHA2_256, TskAttributeNames("TSK_HASH_SHA2_256", "SHA2-256 Hash")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_HASH_SHA2_512, TskAttributeNames("TSK_HASH_SHA2_512", "SHA2-512 Hash")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_TEXT, TskAttributeNames("TSK_TEXT", "Text")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_TEXT_FILE, TskAttributeNames("TSK_TEXT_FILE", "Text File")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_TEXT_LANGUAGE, TskAttributeNames("TSK_TEXT_LANGUAGE", "Text Language")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_ENTROPY, TskAttributeNames("TSK_ENTROPY", "Entropy")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_HASHSET_NAME, TskAttributeNames("TSK_HASHSET_NAME", "Hashset Name")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_INTERESTING_FILE, TskAttributeNames("TSK_INTERESTING_FILE", "Interesting File")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_REFERRER, TskAttributeNames("TSK_REFERRER", "Referrer URL")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_DATETIME_ACCESSED, TskAttributeNames("TSK_DATETIME_ACCESSED", "Date Accessed"))); 
-    retval.insert(pair<int, TskAttributeNames>(TSK_IP_ADDRESS, TskAttributeNames("TSK_IP_ADDRESS", "IP Address")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_PHONE_NUMBER, TskAttributeNames("TSK_PHONE_NUMBER", "Phone Number")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_PATH_ID, TskAttributeNames("TSK_PATH_ID", "Id of Path")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_SET_NAME, TskAttributeNames("TSK_SET_NAME", "Set Name")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_ENCRYPTION_DETECTED, TskAttributeNames("TSK_ENCRYPTION_DETECTED", "File Encryption Detected")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_MALWARE_DETECTED, TskAttributeNames("TSK_MALWARE_DETECTED", "Malware Detected")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_STEG_DETECTED, TskAttributeNames("TSK_STEG_DETECTED", "Steganography Detected")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_EMAIL_TO, TskAttributeNames("TSK_EMAIL_TO", "E-Mail To")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_EMAIL_CC, TskAttributeNames("TSK_EMAIL_CC", "E-Mail CC")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_EMAIL_BCC, TskAttributeNames("TSK_EMAIL_BCC", "E-Mail BCC")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_EMAIL_FROM, TskAttributeNames("TSK_EMAIL_FROM", "E-Mail From")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_EMAIL_CONTENT_PLAIN, TskAttributeNames("TSK_EMAIL_CONTENT_PLAIN", "Content (Plain Text)")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_EMAIL_CONTENT_HTML, TskAttributeNames("TSK_EMAIL_CONTENT_HTML", "Content (HTML)")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_EMAIL_CONTENT_RTF, TskAttributeNames("TSK_EMAIL_CONTENT_RTF", "Content (RTF)")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_MSG_ID, TskAttributeNames("TSK_MSG_ID", "Message ID")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_MSG_REPLY_ID, TskAttributeNames("TSK_MSG_REPLY_ID", "Message Reply ID")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_DATETIME_RCVD, TskAttributeNames("TSK_DATETIME_RCVD", "Date Received")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_DATETIME_SENT, TskAttributeNames("TSK_DATETIME_SENT", "Date Sent")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_SUBJECT, TskAttributeNames("TSK_SUBJECT", "Subject")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_GEO_LATITUDE, TskAttributeNames("TSK_GEO_LATITUDE", "Latitude")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_GEO_LONGITUDE, TskAttributeNames("TSK_GEO_LONGITUDE", "Longitude")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_GEO_VELOCITY, TskAttributeNames("TSK_GEO_VELOCITY", "Velocity")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_GEO_ALTITUDE, TskAttributeNames("TSK_GEO_ALTITUDE", "Altitude")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_GEO_BEARING, TskAttributeNames("TSK_GEO_BEARING", "Bearing")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_GEO_HPRECISION, TskAttributeNames("TSK_GEO_HPRECISION", "Horizontal Precision")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_GEO_VPRECISION, TskAttributeNames("TSK_GEO_VPRECISION", "Vertical Precision")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_GEO_MAPDATUM, TskAttributeNames("TSK_GEO_MAPDATUM", "Map Datum")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_FILE_TYPE_SIG, TskAttributeNames("TSK_FILE_TYPE_SIG", "File Type (by signature)")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_FILE_TYPE_EXT, TskAttributeNames("TSK_FILE_TYPE_EXT", "File Type (by extension)")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_TAGGED_ARTIFACT, TskAttributeNames("TSK_TAGGED_ARTIFACT", "Tagged Result")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_TAG_NAME, TskAttributeNames("TSK_TAG_NAME", "Tag Name")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_COMMENT, TskAttributeNames("TSK_COMMENT", "Comment")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_URL_DECODED, TskAttributeNames("TSK_URL_DECODED", "Decoded URL")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_DATETIME_CREATED, TskAttributeNames("TSK_DATETIME_CREATED", "Date Created")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_DATETIME_MODIFIED, TskAttributeNames("TSK_DATETIME_MODIFIED", "Date Modified")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_PROCESSOR_ARCHITECTURE, TskAttributeNames("TSK_PROCESSOR_ARCHITECTURE", "Processor Architecture")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_VERSION, TskAttributeNames("TSK_VERSION", "Version")));
-    retval.insert(pair<int, TskAttributeNames>(TSK_USER_ID, TskAttributeNames("TSK_USER_ID", "User ID")));
-
-    return retval;
-}
-
-/** \internal
-* The table used to store names and display names for built in artifacts
-*/
-
-static map<int, TskArtifactNames> artifact_type_table= initializeArtifactTypeMap();
-static map<int, TskAttributeNames> attribute_type_table= initializeAttributeTypeMap();
-
-int m_artifactIDcounter = 1000;
-int m_attributeIDcounter = 1000;
-
-string TskBlackboard::attrTypeIDToTypeDisplayName(const int attributeTypeID){
-    map<int, TskAttributeNames>::iterator it = attribute_type_table.find(attributeTypeID);
-    if(it == attribute_type_table.end())
-        throw TskException("No attribute type with that id");
-    else
-        return it->second.displayName;
-}
-int TskBlackboard::attrTypeNameToTypeID(const string& attributeTypeString){
-    map<int, TskAttributeNames>::iterator it;
-    for(it = attribute_type_table.begin(); it != attribute_type_table.end(); it++){
-        if(attributeTypeString.compare(it->second.typeName) == 0)
-            return it->first;
-    }
-    throw TskException("No attribute type with that name");
-}
-
-string TskBlackboard::attrTypeIDToTypeName(const int attributeTypeID){
-    map<int, TskAttributeNames>::iterator it = attribute_type_table.find(attributeTypeID);
-    if(it == attribute_type_table.end())
-        throw TskException("No attribute type with that id");
-    else
-        return it->second.typeName;
-}
-
-int TskBlackboard::addAttributeType(const string& attributeTypeName, const string& displayName){
-    map<int, TskAttributeNames>::iterator it = attribute_type_table.begin();
-    for(it; it != attribute_type_table.end(); it++){
-        if(attributeTypeName.compare(it->second.typeName) == 0)
-            throw TskException("Attribute type with that name already exists");
-    }
-    attribute_type_table.insert(pair<int, TskAttributeNames>(m_attributeIDcounter, TskAttributeNames(attributeTypeName, displayName)));
-    return m_attributeIDcounter++;
-}
-
-string TskBlackboard::artTypeIDToDisplayName(const int artifactTypeID){
-    map<int, TskArtifactNames>::iterator it = artifact_type_table.find(artifactTypeID);
-    if(it == artifact_type_table.end())
-        throw TskException("No artifact type with that id");
-    else
-        return it->second.displayName;
-}
-
-int TskBlackboard::artTypeNameToTypeID(const string& artifactTypeString){
-    map<int, TskArtifactNames>::iterator it = artifact_type_table.begin();
-    for(it; it != artifact_type_table.end(); it++){
-        if(artifactTypeString.compare(it->second.typeName) == 0)
-            return it->first;
-    }
-    throw TskException("No attribute type with that name");
-}
-
-string TskBlackboard::artTypeIDToTypeName(const int artifactTypeID){
-    map<int, TskArtifactNames>::iterator it = artifact_type_table.find(artifactTypeID);
-    if(it == artifact_type_table.end())
-        throw TskException("No attribute type with that id");
-    else
-        return it->second.typeName;
-}
-
-int TskBlackboard::addArtifactType(const string& artifactTypeName, const string& displayName){
-    map<int, TskArtifactNames>::iterator it = artifact_type_table.begin();
-    for(it; it != artifact_type_table.end(); it++){
-        if(artifactTypeName.compare(it->second.typeName) == 0)
-            throw TskException("Attribute type with that name already exists");
-    }
-    artifact_type_table.insert(pair<int, TskArtifactNames>(m_artifactIDcounter, TskArtifactNames(artifactTypeName, displayName)));
-    return m_artifactIDcounter++;
-}
-
-map<int, TskArtifactNames> TskBlackboard::getAllArtifactTypes(){
-    return artifact_type_table;
-}
-map<int, TskAttributeNames> TskBlackboard::getAllAttributeTypes(){
-    return attribute_type_table;
-}
+/*
+* 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 "TskBlackboard.h"
+
+map<int, TskArtifactNames> initializeArtifactTypeMap(){
+    map<int, TskArtifactNames> retval;
+    retval.insert(pair<int, TskArtifactNames>(TSK_GEN_INFO, TskArtifactNames("TSK_GEN_INFO", "General Info")));
+    retval.insert(pair<int, TskArtifactNames>(TSK_WEB_BOOKMARK, TskArtifactNames("TSK_WEB_BOOKMARK", "Web Bookmarks")));
+    retval.insert(pair<int, TskArtifactNames>(TSK_WEB_COOKIE, TskArtifactNames("TSK_WEB_COOKIE", "Web Cookies")));
+    retval.insert(pair<int, TskArtifactNames>(TSK_WEB_HISTORY, TskArtifactNames("TSK_WEB_HISTORY", "Web History")));
+    retval.insert(pair<int, TskArtifactNames>(TSK_WEB_DOWNLOAD, TskArtifactNames("TSK_WEB_DOWNLOAD", "Web Downloads")));
+    retval.insert(pair<int, TskArtifactNames>(TSK_RECENT_OBJECT, TskArtifactNames("TSK_RECENT_OBJECT", "Recent History Object")));
+    retval.insert(pair<int, TskArtifactNames>(TSK_GPS_TRACKPOINT, TskArtifactNames("TSK_GPS_TRACKPOINT", "GPS Trackpoints")));
+    retval.insert(pair<int, TskArtifactNames>(TSK_INSTALLED_PROG, TskArtifactNames("TSK_INSTALLED_PROG", "Installed Programs")));
+    retval.insert(pair<int, TskArtifactNames>(TSK_KEYWORD_HIT, TskArtifactNames("TSK_KEYWORD_HIT", "Keyword Hits")));
+    retval.insert(pair<int, TskArtifactNames>(TSK_HASHSET_HIT, TskArtifactNames("TSK_HASHSET_HIT", "Hashset Hits")));
+    retval.insert(pair<int, TskArtifactNames>(TSK_DEVICE_ATTACHED, TskArtifactNames("TSK_DEVICE_ATTACHED", "Devices Attached")));
+    retval.insert(pair<int, TskArtifactNames>(TSK_INTERESTING_FILE_HIT, TskArtifactNames("TSK_INTERESTING_FILE_HIT", "Interesting Files")));
+    retval.insert(pair<int, TskArtifactNames>(TSK_EMAIL_MSG, TskArtifactNames("TSK_EMAIL_MSG", "E-Mail Messages")));
+    retval.insert(pair<int, TskArtifactNames>(TSK_EXTRACTED_TEXT, TskArtifactNames("TSK_EXTRACTED_TEXT", "Extracted Text")));
+    retval.insert(pair<int, TskArtifactNames>(TSK_WEB_SEARCH_QUERY, TskArtifactNames("TSK_WEB_SEARCH_QUERY", "Web Search")));
+    retval.insert(pair<int, TskArtifactNames>(TSK_METADATA_EXIF, TskArtifactNames("TSK_METADATA_EXIF", "EXIF Metadata")));
+    retval.insert(pair<int, TskArtifactNames>(TSK_TAG_FILE, TskArtifactNames("TSK_TAG_FILE", "File Tags")));
+    retval.insert(pair<int, TskArtifactNames>(TSK_TAG_ARTIFACT, TskArtifactNames("TSK_TAG_ARTIFACT", "Result Tags")));
+    retval.insert(pair<int, TskArtifactNames>(TSK_OS_INFO, TskArtifactNames("TSK_OS_INFO", "Operating System Information")));
+    retval.insert(pair<int, TskArtifactNames>(TSK_OS_ACCOUNT, TskArtifactNames("TSK_OS_ACCOUNT", "Operating System User Account")));
+    retval.insert(pair<int, TskArtifactNames>(TSK_SERVICE_ACCOUNT, TskArtifactNames("TSK_SERVICE_ACCOUNT", "Accounts")));
+    retval.insert(pair<int, TskArtifactNames>(TSK_TOOL_OUTPUT, TskArtifactNames("TSK_TOOL_OUTPUT", "Raw Tool Output")));
+	retval.insert(pair<int, TskArtifactNames>(TSK_CONTACT, TskArtifactNames("TSK_CONTACT", "Contacts")));
+	retval.insert(pair<int, TskArtifactNames>(TSK_MESSAGE, TskArtifactNames("TSK_MESSAGE", "Messages")));
+	retval.insert(pair<int, TskArtifactNames>(TSK_CALLLOG, TskArtifactNames("TSK_CALLLOG", "Call Logs")));
+	retval.insert(pair<int, TskArtifactNames>(TSK_CALENDAR_ENTRY, TskArtifactNames("TSK_CALENDAR_ENTRY", "Calendar Entries")));
+	retval.insert(pair<int, TskArtifactNames>(TSK_SPEED_DIAL_ENTRY, TskArtifactNames("TSK_SPEED_DIAL_ENTRY", "Speed Dial Entries")));
+	retval.insert(pair<int, TskArtifactNames>(TSK_BLUETOOTH_PAIRING, TskArtifactNames("TSK_BLUETOOTH_PAIRING", "Bluetooth Pairings")));
+	retval.insert(pair<int, TskArtifactNames>(TSK_GPS_BOOKMARK, TskArtifactNames("TSK_GPS_BOOKMARK", "GPS Bookmarks")));
+	retval.insert(pair<int, TskArtifactNames>(TSK_GPS_LAST_KNOWN_LOCATION, TskArtifactNames("TSK_GPS_LAST_KNOWN_LOCATION", "GPS Last Known Location")));
+	retval.insert(pair<int, TskArtifactNames>(TSK_GPS_SEARCH, TskArtifactNames("TSK_GPS_SEARCH", "GPS Searches")));
+	
+    return retval;
+}
+
+map<int, TskAttributeNames> initializeAttributeTypeMap(){
+    map<int, TskAttributeNames> retval;
+    retval.insert(pair<int, TskAttributeNames>(TSK_URL, TskAttributeNames("TSK_URL", "URL")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_DATETIME, TskAttributeNames("TSK_DATETIME", "Datetime")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_NAME, TskAttributeNames("TSK_NAME", "Name")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_PROG_NAME, TskAttributeNames("TSK_PROG_NAME", "Program Name")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_VALUE, TskAttributeNames("TSK_VALUE", "Value")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_FLAG, TskAttributeNames("TSK_FLAG", "Flag")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_PATH, TskAttributeNames("TSK_PATH", "Path")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_KEYWORD, TskAttributeNames("TSK_KEYWORD", "Keyword")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_KEYWORD_REGEXP, TskAttributeNames("TSK_KEYWORD_REGEXP", "Keyword Regular Expression")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_KEYWORD_PREVIEW, TskAttributeNames("TSK_KEYWORD_PREVIEW", "Keyword Preview")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_KEYWORD_SET, TskAttributeNames("TSK_KEYWORD_SET", "Keyword Set")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_USER_NAME, TskAttributeNames("TSK_USER_NAME", "Username")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_DOMAIN, TskAttributeNames("TSK_DOMAIN", "Domain")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_PASSWORD, TskAttributeNames("TSK_PASSWORD", "Password")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_NAME_PERSON, TskAttributeNames("TSK_NAME_PERSON", "Person Name")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_DEVICE_MODEL, TskAttributeNames("TSK_DEVICE_MODEL", "Device Model")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_DEVICE_MAKE, TskAttributeNames("TSK_DEVICE_MAKE", "Device Make")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_DEVICE_ID, TskAttributeNames("TSK_DEVICE_ID", "Device ID")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_EMAIL, TskAttributeNames("TSK_EMAIL", "Email")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_HASH_MD5, TskAttributeNames("TSK_HASH_MD5", "MD5 Hash")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_HASH_SHA1, TskAttributeNames("TSK_HASH_SHA1", "SHA1 Hash")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_HASH_SHA2_256, TskAttributeNames("TSK_HASH_SHA2_256", "SHA2-256 Hash")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_HASH_SHA2_512, TskAttributeNames("TSK_HASH_SHA2_512", "SHA2-512 Hash")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_TEXT, TskAttributeNames("TSK_TEXT", "Text")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_TEXT_FILE, TskAttributeNames("TSK_TEXT_FILE", "Text File")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_TEXT_LANGUAGE, TskAttributeNames("TSK_TEXT_LANGUAGE", "Text Language")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_ENTROPY, TskAttributeNames("TSK_ENTROPY", "Entropy")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_HASHSET_NAME, TskAttributeNames("TSK_HASHSET_NAME", "Hashset Name")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_INTERESTING_FILE, TskAttributeNames("TSK_INTERESTING_FILE", "Interesting File")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_REFERRER, TskAttributeNames("TSK_REFERRER", "Referrer URL")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_DATETIME_ACCESSED, TskAttributeNames("TSK_DATETIME_ACCESSED", "Date Accessed"))); 
+    retval.insert(pair<int, TskAttributeNames>(TSK_IP_ADDRESS, TskAttributeNames("TSK_IP_ADDRESS", "IP Address")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_PHONE_NUMBER, TskAttributeNames("TSK_PHONE_NUMBER", "Phone Number")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_PATH_ID, TskAttributeNames("TSK_PATH_ID", "Id of Path")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_SET_NAME, TskAttributeNames("TSK_SET_NAME", "Set Name")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_ENCRYPTION_DETECTED, TskAttributeNames("TSK_ENCRYPTION_DETECTED", "File Encryption Detected")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_MALWARE_DETECTED, TskAttributeNames("TSK_MALWARE_DETECTED", "Malware Detected")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_STEG_DETECTED, TskAttributeNames("TSK_STEG_DETECTED", "Steganography Detected")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_EMAIL_TO, TskAttributeNames("TSK_EMAIL_TO", "E-Mail To")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_EMAIL_CC, TskAttributeNames("TSK_EMAIL_CC", "E-Mail CC")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_EMAIL_BCC, TskAttributeNames("TSK_EMAIL_BCC", "E-Mail BCC")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_EMAIL_FROM, TskAttributeNames("TSK_EMAIL_FROM", "E-Mail From")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_EMAIL_CONTENT_PLAIN, TskAttributeNames("TSK_EMAIL_CONTENT_PLAIN", "Content (Plain Text)")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_EMAIL_CONTENT_HTML, TskAttributeNames("TSK_EMAIL_CONTENT_HTML", "Content (HTML)")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_EMAIL_CONTENT_RTF, TskAttributeNames("TSK_EMAIL_CONTENT_RTF", "Content (RTF)")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_MSG_ID, TskAttributeNames("TSK_MSG_ID", "Message ID")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_MSG_REPLY_ID, TskAttributeNames("TSK_MSG_REPLY_ID", "Message Reply ID")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_DATETIME_RCVD, TskAttributeNames("TSK_DATETIME_RCVD", "Date Received")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_DATETIME_SENT, TskAttributeNames("TSK_DATETIME_SENT", "Date Sent")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_SUBJECT, TskAttributeNames("TSK_SUBJECT", "Subject")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_GEO_LATITUDE, TskAttributeNames("TSK_GEO_LATITUDE", "Latitude")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_GEO_LONGITUDE, TskAttributeNames("TSK_GEO_LONGITUDE", "Longitude")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_GEO_VELOCITY, TskAttributeNames("TSK_GEO_VELOCITY", "Velocity")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_GEO_ALTITUDE, TskAttributeNames("TSK_GEO_ALTITUDE", "Altitude")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_GEO_BEARING, TskAttributeNames("TSK_GEO_BEARING", "Bearing")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_GEO_HPRECISION, TskAttributeNames("TSK_GEO_HPRECISION", "Horizontal Precision")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_GEO_VPRECISION, TskAttributeNames("TSK_GEO_VPRECISION", "Vertical Precision")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_GEO_MAPDATUM, TskAttributeNames("TSK_GEO_MAPDATUM", "Map Datum")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_FILE_TYPE_SIG, TskAttributeNames("TSK_FILE_TYPE_SIG", "File Type (by signature)")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_FILE_TYPE_EXT, TskAttributeNames("TSK_FILE_TYPE_EXT", "File Type (by extension)")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_TAGGED_ARTIFACT, TskAttributeNames("TSK_TAGGED_ARTIFACT", "Tagged Result")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_TAG_NAME, TskAttributeNames("TSK_TAG_NAME", "Tag Name")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_COMMENT, TskAttributeNames("TSK_COMMENT", "Comment")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_URL_DECODED, TskAttributeNames("TSK_URL_DECODED", "Decoded URL")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_DATETIME_CREATED, TskAttributeNames("TSK_DATETIME_CREATED", "Date Created")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_DATETIME_MODIFIED, TskAttributeNames("TSK_DATETIME_MODIFIED", "Date Modified")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_PROCESSOR_ARCHITECTURE, TskAttributeNames("TSK_PROCESSOR_ARCHITECTURE", "Processor Architecture")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_VERSION, TskAttributeNames("TSK_VERSION", "Version")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_USER_ID, TskAttributeNames("TSK_USER_ID", "User ID")));
+    retval.insert(pair<int, TskAttributeNames>(TSK_DESCRIPTION, TskAttributeNames("TSK_DESCRIPTION", "Description")));
+	retval.insert(pair<int, TskAttributeNames>(TSK_MESSAGE_TYPE, TskAttributeNames("TSK_MESSAGE_TYPE",  "Message Type")));
+	retval.insert(pair<int, TskAttributeNames>(TSK_PHONE_NUMBER_HOME, TskAttributeNames("TSK_PHONE_NUMBER_HOME",  "Phone Number (Home)")));
+	retval.insert(pair<int, TskAttributeNames>(TSK_PHONE_NUMBER_OFFICE, TskAttributeNames("TSK_PHONE_NUMBER_OFFICE",  "Phone Number (Office)")));
+	retval.insert(pair<int, TskAttributeNames>(TSK_PHONE_NUMBER_MOBILE, TskAttributeNames("TSK_PHONE_NUMBER_MOBILE",  "Phone Number (Mobile)")));
+	retval.insert(pair<int, TskAttributeNames>(TSK_PHONE_NUMBER_FROM, TskAttributeNames("TSK_PHONE_NUMBER_FROM",  "From Phone Number")));
+	retval.insert(pair<int, TskAttributeNames>(TSK_PHONE_NUMBER_TO, TskAttributeNames("TSK_PHONE_NUMBER_TO",  "To Phone Number")));
+	retval.insert(pair<int, TskAttributeNames>(TSK_DIRECTION, TskAttributeNames("TSK_DIRECTION",  "Direction")));
+	retval.insert(pair<int, TskAttributeNames>(TSK_EMAIL_HOME, TskAttributeNames("TSK_EMAIL_HOME",  "Email (Home)")));
+	retval.insert(pair<int, TskAttributeNames>(TSK_EMAIL_OFFICE, TskAttributeNames("TSK_EMAIL_OFFICE", "Email (Office)")));
+	retval.insert(pair<int, TskAttributeNames>(TSK_DATETIME_START, TskAttributeNames("TSK_DATETIME_START",  "Start Date/Time")));
+	retval.insert(pair<int, TskAttributeNames>(TSK_DATETIME_END, TskAttributeNames("TSK_DATETIME_END",  "End Date/Time")));
+	retval.insert(pair<int, TskAttributeNames>(TSK_CALENDAR_ENTRY_TYPE, TskAttributeNames("TSK_CALENDAR_ENTRY_TYPE", "Calendar Entry Type")));
+	retval.insert(pair<int, TskAttributeNames>(TSK_LOCATION, TskAttributeNames("TSK_LOCATION", "Location")));
+	retval.insert(pair<int, TskAttributeNames>(TSK_SHORTCUT, TskAttributeNames("TSK_SHORTCUT",  "Short Cut")));
+	retval.insert(pair<int, TskAttributeNames>(TSK_DEVICE_NAME, TskAttributeNames("TSK_DEVICE_NAME", "Device Name")));
+	retval.insert(pair<int, TskAttributeNames>(TSK_CATEGORY, TskAttributeNames("TSK_CATEGORY",  "Category")));
+	retval.insert(pair<int, TskAttributeNames>(TSK_EMAIL_REPLYTO, TskAttributeNames("TSK_EMAIL_REPLYTO", "ReplyTo Address")));
+	retval.insert(pair<int, TskAttributeNames>(TSK_SERVER_NAME, TskAttributeNames("TSK_SERVER_NAME", "Server Name")));
+
+    return retval;
+}
+
+/** \internal
+* The table used to store names and display names for built in artifacts
+*/
+
+static map<int, TskArtifactNames> artifact_type_table= initializeArtifactTypeMap();
+static map<int, TskAttributeNames> attribute_type_table= initializeAttributeTypeMap();
+
+int m_artifactIDcounter = 1000;
+int m_attributeIDcounter = 1000;
+
+string TskBlackboard::attrTypeIDToTypeDisplayName(const int attributeTypeID){
+    map<int, TskAttributeNames>::iterator it = attribute_type_table.find(attributeTypeID);
+    if(it == attribute_type_table.end())
+        throw TskException("No attribute type with that id");
+    else
+        return it->second.displayName;
+}
+int TskBlackboard::attrTypeNameToTypeID(const string& attributeTypeString){
+    map<int, TskAttributeNames>::iterator it;
+    for(it = attribute_type_table.begin(); it != attribute_type_table.end(); it++){
+        if(attributeTypeString.compare(it->second.typeName) == 0)
+            return it->first;
+    }
+    throw TskException("No attribute type with that name");
+}
+
+string TskBlackboard::attrTypeIDToTypeName(const int attributeTypeID){
+    map<int, TskAttributeNames>::iterator it = attribute_type_table.find(attributeTypeID);
+    if(it == attribute_type_table.end())
+        throw TskException("No attribute type with that id");
+    else
+        return it->second.typeName;
+}
+
+int TskBlackboard::addAttributeType(const string& attributeTypeName, const string& displayName){
+    map<int, TskAttributeNames>::iterator it = attribute_type_table.begin();
+    for(it; it != attribute_type_table.end(); it++){
+        if(attributeTypeName.compare(it->second.typeName) == 0)
+            throw TskException("Attribute type with that name already exists");
+    }
+    attribute_type_table.insert(pair<int, TskAttributeNames>(m_attributeIDcounter, TskAttributeNames(attributeTypeName, displayName)));
+    return m_attributeIDcounter++;
+}
+
+string TskBlackboard::artTypeIDToDisplayName(const int artifactTypeID){
+    map<int, TskArtifactNames>::iterator it = artifact_type_table.find(artifactTypeID);
+    if(it == artifact_type_table.end())
+        throw TskException("No artifact type with that id");
+    else
+        return it->second.displayName;
+}
+
+int TskBlackboard::artTypeNameToTypeID(const string& artifactTypeString){
+    map<int, TskArtifactNames>::iterator it = artifact_type_table.begin();
+    for(it; it != artifact_type_table.end(); it++){
+        if(artifactTypeString.compare(it->second.typeName) == 0)
+            return it->first;
+    }
+    throw TskException("No attribute type with that name");
+}
+
+string TskBlackboard::artTypeIDToTypeName(const int artifactTypeID){
+    map<int, TskArtifactNames>::iterator it = artifact_type_table.find(artifactTypeID);
+    if(it == artifact_type_table.end())
+        throw TskException("No attribute type with that id");
+    else
+        return it->second.typeName;
+}
+
+int TskBlackboard::addArtifactType(const string& artifactTypeName, const string& displayName){
+    map<int, TskArtifactNames>::iterator it = artifact_type_table.begin();
+    for(it; it != artifact_type_table.end(); it++){
+        if(artifactTypeName.compare(it->second.typeName) == 0)
+            throw TskException("Attribute type with that name already exists");
+    }
+    artifact_type_table.insert(pair<int, TskArtifactNames>(m_artifactIDcounter, TskArtifactNames(artifactTypeName, displayName)));
+    return m_artifactIDcounter++;
+}
+
+map<int, TskArtifactNames> TskBlackboard::getAllArtifactTypes(){
+    return artifact_type_table;
+}
+map<int, TskAttributeNames> TskBlackboard::getAllAttributeTypes(){
+    return attribute_type_table;
+}
diff --git a/framework/tsk/framework/services/TskBlackboard.h b/framework/tsk/framework/services/TskBlackboard.h
index fe30305..b219448 100755
--- a/framework/tsk/framework/services/TskBlackboard.h
+++ b/framework/tsk/framework/services/TskBlackboard.h
@@ -1,405 +1,437 @@
-/*
- * 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 TskBlackboard.h
- * Interface for class that will implement the black board.  The black board
- * is used to store data from analysis modules.  The data is available to
- * later modules in the pipeline and in the final reporting phase.
- */
-
-#ifndef _TSK_BLACKBOARD_H
-#define _TSK_BLACKBOARD_H
-
-#include <string>
-#include <vector>
-#include "tsk/framework/utilities/TskException.h"
-#include "tsk/framework/framework_i.h"
-#include "tsk/framework/services/TskImgDB.h"
-#include "TskBlackboardArtifact.h"
-#include "TskBlackboardAttribute.h"
-
-using namespace std;
-
-/**
- * Built in artifact types.
- * Refer to http://wiki.sleuthkit.org/index.php?title=Artifact_Examples
- * for details on which attributes should be used for each artifact.
- */
-
-/* Note that the below comments are the only documentation 
- * for the standard types.  Please ensure that all types are
- * documented. 
- * 
- * The numbers are explicitly added to make it easier to verify
- * that the Java and C++ code is in sync.
- *
- * It is very important that this list be kept up to date and 
- * in sync with the Java code.  Do not add anything here unless
- * you also add it there.  
- * See bindings/java/src/org/sleuthkit/datamodel/BlackboardArtifact.java */
-enum TSK_ARTIFACT_TYPE {
-    TSK_GEN_INFO = 1,///< The general info artifact, if information doesn't need its own artifact it should go here
-    TSK_WEB_BOOKMARK = 2,///< A web bookmark. 
-    TSK_WEB_COOKIE = 3,///< A web cookie. 
-    TSK_WEB_HISTORY = 4,///< A web history enrty. 
-    TSK_WEB_DOWNLOAD = 5,///< A web download. 
-    TSK_RECENT_OBJECT = 6,///< A recently used object (MRU, recent document, etc.).
-    TSK_TRACKPOINT = 7,///< A trackpoint from a GPS log.
-    TSK_INSTALLED_PROG = 8,///< An installed program. 
-    TSK_KEYWORD_HIT = 9,///< A keyword hit. 
-    TSK_HASHSET_HIT = 10, ///< A hit within a known bad / notable hashset / hash database. 
-    TSK_DEVICE_ATTACHED = 11, ///< An event for a device being attached to the host computer
-    TSK_INTERESTING_FILE_HIT = 12, ///< A file that was flagged because it matched some search criteria for being interesting (i.e. because of its name, extension, etc.)
-    TSK_EMAIL_MSG = 13, ///< An e-mail message that was extracted from a file.
-    TSK_EXTRACTED_TEXT = 14, ///< Text that was extracted from a file.
-    TSK_WEB_SEARCH_QUERY = 15, ///< Web search engine query extracted from web history.
-    TSK_METADATA_EXIF = 16, ///< EXIF Metadata
-    TSK_TAG_FILE = 17, ///< File tags.
-    TSK_TAG_ARTIFACT = 18, ///< Result tags.
-    TSK_OS_INFO = 19, ///< Information pertaining to an operating system.
-    TSK_OS_ACCOUNT, ///< An operating system user account.
-    TSK_SERVICE_ACCOUNT, ///< A network service user account.
-    /* SEE ABOVE:
-    * - KEEP JAVA CODE IN SYNC 
-    * - UPDATE map in TskBlackboard.cpp
-    * - Update Wiki to reflect the attributes that should be part of the artifact. 
-    */
-};
-
-/**
- * Built in attribute types 
- */
-/* The numbers are explicitly added to make it easier to verify
- * that the Java and C++ code is in sync.
- *
- * It is very important that this list be kept up to date and 
- * in sync with the Java code.  Do not add anything here unless
- * you also add it there.  
- * See bindings/java/src/org/sleuthkit/datamodel/BlackboardAttribute.java 
- */
-enum TSK_ATTRIBUTE_TYPE {
-    TSK_URL = 1,///< String of a URL, should start with http:// or ftp:// etc.  You should also make a TskBlackoard::TSK_DOMAIN entry for the base domain name. 
-    TSK_DATETIME = 2,///< INT32: GMT based Unix time, defines number of secords elapsed since UTC Jan 1, 1970.
-    TSK_NAME = 3,///< STRING: The name associated with an artifact
-    TSK_PROG_NAME = 4,///< String of name of a program that was installed on the system
-    TSK_VALUE = 6,///< Some value associated with an artifact
-    TSK_FLAG = 7,///< Some flag associated with an artifact
-    TSK_PATH = 8,///< A filesystem path.  Should be fully qualified. Should set TSK_PATH_ID as well when this is set. TODO: Need to define this value more for cases with multiple images and multiple file systems per image. 
-    TSK_KEYWORD = 10,///< STRING: Keyword that was found in this file. 
-    TSK_KEYWORD_REGEXP = 11,///< STRING: A regular expression string
-    TSK_KEYWORD_PREVIEW = 12,///< STRING: A text preview
-    TSK_KEYWORD_SET = 13,///< STRING: A keyword set -- Deprecated in favor of TSK_SET_NAME
-    TSK_USER_NAME = 14,///< String of a user name.  Use TskBlackboard::TSK_DOMAIN to store the domain that the username is from (if it is known). 
-    TSK_DOMAIN = 15,///< String of a DNS Domain name, e.g. sleuthkit.org  use TskBlackboad::TSK_URL for a full URL.
-    TSK_PASSWORD = 16,///< String of a password that was found.  Use TskBlackboard::TSK_USER_NAME and TskBlackboard::TSK_DOMAIN to link the password to a given user and site. 
-    TSK_NAME_PERSON = 17,///< String of a person name
-    TSK_DEVICE_MODEL = 18,///< String of manufacturer name of device that was connected (or somehow related to) the data being analyzed
-    TSK_DEVICE_MAKE = 19,///< String of make of a device that was connected (or somehow related to) the data being analyzed
-    TSK_DEVICE_ID = 20,///< String of ID/serial number of a device that was connected (or somehow related to) the data being analyzed
-    TSK_EMAIL = 21,///< String of e-mail address in the form of user at host.com (note that there are also more specific TSK_EMAIL_TO and TSK_EMAIL_FROM attributes if you know the use of the address)
-    TSK_HASH_MD5 = 22,///< STRING: MD5 hash
-    TSK_HASH_SHA1 = 23,///< STRING: SHA1 hash
-    TSK_HASH_SHA2_256 = 24,///< STRING: SHA2 256 bit hash
-    TSK_HASH_SHA2_512 = 25,///< STRING: SHA2 512 bit hash
-    TSK_TEXT = 26,///< String of text extracted from a file (should be part of TSK_EXTRACTED_TEXT artifact).
-    TSK_TEXT_FILE = 27,///< String of path to file containing text. May be absolute or relative. If relative, will be evaluated relative to OUT_DIR setting. Should be part of TSK_EXTRACTED_TEXT artifact)
-    TSK_TEXT_LANGUAGE = 28,///< String of the detected language in ISO 639-3 language code of TskBlackboard::TSK_TEXT data in the same artifact (TSK_EXTRACTED_TEXT, for example).
-    TSK_ENTROPY = 29,///< DOUBLE: Entropy value of file
-    TSK_HASHSET_NAME = 30,///< String of the name or file name of the hashset -- Deprecated in favor of TSK_SET_NAME
-    TSK_INTERESTING_FILE = 31,///< An interesting file hit, potentially file id, name, or path
-    TSK_REFERRER = 32,///< String of referrer URL
-    TSK_DATETIME_ACCESSED = 33,///<datetime last time accessed
-    TSK_IP_ADDRESS = 34,///<String of IP Address
-    TSK_PHONE_NUMBER = 35,///<String of phone number
-    TSK_PATH_ID = 36,///< Object ID from database that a TSK_PATH attribute corresponds to.  Set to -1 if path is for a file that is not in database (i.e. deleted). 
-    TSK_SET_NAME = 37,///< STRING: The name of a set that was used to find this artifact (to be used for hash hits, keyword hits, interesting files, etc.)
-    TSK_ENCRYPTION_DETECTED = 38,///< STRING: The type of encryption that is believed to have been used on the file.
-    TSK_MALWARE_DETECTED = 39,///< STRING: The name of the malware that was detected in this file.
-    TSK_STEG_DETECTED = 40,///< STRING: The name of the steganography technique that was detected in this file.
-    TSK_EMAIL_TO = 41, ///< String of an e-mail address that a message is being sent to directly (not cc:).
-    TSK_EMAIL_CC = 42, ///< String of an e-mail address that a message is being sent to as a cc:.
-    TSK_EMAIL_BCC = 43, ///< String of an e-mail address that a message is being sent to as a bcc:.
-    TSK_EMAIL_FROM = 44, ///< String of an e-mail address that a message is being sent from.
-    TSK_EMAIL_CONTENT_PLAIN = 45, ///< String of e-mail message body in plain text
-    TSK_EMAIL_CONTENT_HTML = 46, ///< STring of e-mail message body in HTML
-    TSK_EMAIL_CONTENT_RTF = 47, ///< STring of e-mail message body in RTF
-    TSK_MSG_ID = 48, ///< String of a message ID (such as one of an e-mail message)
-    TSK_MSG_REPLY_ID = 49, ///< String of a message ID that a given message is in response to (such as one of an e-mail message) 
-    TSK_DATETIME_RCVD = 50, ///< Time in Unix epoch that something was received.
-    TSK_DATETIME_SENT = 51, ///< Time in Unix epoch that something was sent.
-    TSK_SUBJECT = 52, ///< String of a subject (such as one of an e-mail message)
-    TSK_TITLE = 53, ///< String of a title (such as a webpage or other document)
-    TSK_GEO_LATITUDE = 54, ///< Floating point of latitude coordinate.  Should be in WGS84. Positive North, Negative South. 
-    TSK_GEO_LONGITUDE = 55, ///< Floating point of longitude coordinate.  Should be in WGS84.  Positive East, Negative West.
-    TSK_GEO_VELOCITY = 56, ///< Floating point of velocity in geo coordinate in meters per second.
-    TSK_GEO_ALTITUDE = 57, ///< Floating point of altitude in geo coordinate in meters.
-    TSK_GEO_BEARING = 58, ///< Floating point of bearing in geo coordinate in true degrees.
-    TSK_GEO_HPRECISION = 59, ///< Floating point of horizontal precision in geo coordinate in meters.
-    TSK_GEO_VPRECISION = 60, ///< Floating point of vertical precision in geo coordinate in meters.
-    TSK_GEO_MAPDATUM = 61, ///< String of map datum used for coordinates if not WGS84.
-    TSK_FILE_TYPE_SIG = 62, ///< String of file type based on signature detection in file content.
-    TSK_FILE_TYPE_EXT = 63, ///< String of file type based on file name extension.
-    TSK_TAGGED_ARTIFACT = 64, ///< Tagged artifact (associated result).
-    TSK_TAG_NAME = 65, ///< The tag name.  Can contain slashes "/" to represent tag hierarchy.
-    TSK_COMMENT = 66, ///< Comment string.
-    TSK_URL_DECODED = 67, ///< Decoded URL.
-    TSK_DATETIME_CREATED = 68,///< Time in Unix epoch that something was created
-    TSK_DATETIME_MODIFIED = 69,///< Time in Unix epoch that something was modified
-    TSK_PROCESSOR_ARCHITECTURE = 70,///< String of processor architecture.  Naming convention from http://en.wikipedia.org/wiki/Comparison_of_CPU_architectures.  So far, we've used x86, x86-64, and IA64.
-    TSK_VERSION = 71,///< String for a software version 
-    TSK_USER_ID,///< User IDfor a user account, e.g., a Windows SID or Linux UID.
-
-    /* SEE ABOVE: 
-    * - KEEP JAVA CODE IN SYNC 
-    * - UPDATE map in TskBlackBoard.cpp too */
-};
-
-/**
- * Class used to store the pair of type and display names of attributes.
- */
-class TskAttributeNames{
-public:
-    string typeName;
-    string displayName;
-    TskAttributeNames(string name, string display):
-    typeName(name),
-        displayName(display){}
-};
-
-/**
- * Class used to store the pair of type and display names of artifacts.
- */
-class TskArtifactNames{
-public:
-    string typeName;
-    string displayName;
-    TskArtifactNames(string name, string display):
-    typeName(name),
-        displayName(display){}
-};
-
-/**
- * An interface for setting and retrieving name/value pairs to the blackboard.
- * The blackboard is used to store data for use by later modules in the pipeline.
- * Can be registered with and retrieved from TskServices.
- */
-class TSK_FRAMEWORK_API TskBlackboard
-{
-public:
-
-    /**
-    * Get the artifact with the given id
-    * @param artifactID id
-    * @returns the artifact throws an error if no artifact matches that id.
-    */
-    virtual TskBlackboardArtifact getBlackboardArtifact(const long artifactID) = 0;
-
-    /**
-    * Get all artifacts that match the given condition
-    * @param condition condition (implementation specific) to use for matching
-    * @returns vector of matching artifacts can return an empty vector if there are no matches
-    * @throws error if a bad condition string is supplied
-    */
-    virtual vector<TskBlackboardArtifact> getMatchingArtifacts(const string& condition)const = 0;
-    /**
-    * Get all artifacts with the given type name and file id
-    * @param file_id associated file id
-    * @param artifactTypeName type name
-    * @returns vector of matching artifacts can return an empty vector if there are no matches
-    */
-    virtual vector<TskBlackboardArtifact> getArtifacts(const uint64_t file_id, const string& artifactTypeName)const = 0;
-    /**
-    * Get all artifacts with the given type id and file id
-    * @param file_id associated file id
-    * @param artifactTypeID type id
-    * @returns vector of matching artifacts can return an empty vector if there are no matches
-    */
-    virtual vector<TskBlackboardArtifact> getArtifacts(const uint64_t file_id, int artifactTypeID)const = 0;
-    /**
-    * Get all artifacts with the given type and file id
-    * @param file_id associated file id
-    * @param artifactType name
-    * @returns vector of matching artifacts can return an empty vector if there are no matches
-    */
-    virtual vector<TskBlackboardArtifact> getArtifacts(const uint64_t file_id, TSK_ARTIFACT_TYPE artifactType)const = 0;
-    /**
-    * Get all artifacts with the given type
-    * @param artifactType type
-    * @returns vector of matching artifacts can return an empty vector if there are no matches
-    */
-    virtual vector<TskBlackboardArtifact> getArtifacts(const TSK_ARTIFACT_TYPE artifactType)const = 0;
-
-    /**
-    * Get all attributes that match the given condition 
-    * @param condition (implementation specific) to use for matching
-    * @returns vector of matching attributes can return an empty vector if there are no matches
-    * @throws error if a bad condition string is supplied
-    */
-    virtual vector<TskBlackboardAttribute> getMatchingAttributes(const string& condition)const = 0;   
-
-    /**
-    * Get all attributes with the given type name and file id
-    * @param file_id associated file id
-    * @param attributeTypeName type name
-    * @returns vector of matching attributes can return an empty vector if there are no matches
-    */
-    virtual vector<TskBlackboardAttribute> getAttributes(const uint64_t file_id, const string& attributeTypeName)const = 0;
-
-    /**
-    * Get all attributes with the given type and file id
-    * @param file_id associated file id
-    * @param attributeTypeID Type of attribute to return
-    * @returns vector of matching attributes can return an empty vector if there are no matches
-    */
-    virtual vector<TskBlackboardAttribute> getAttributes(const uint64_t file_id, int attributeTypeID)const = 0;
-
-    /** Get all attributes with the given type and file id
-    * @param file_id associated file id
-    * @param attributeType name
-    * @returns vector of matching attributes can return an empty vector if there are no matches
-    */
-    virtual vector<TskBlackboardAttribute> getAttributes(const uint64_t file_id, TSK_ATTRIBUTE_TYPE attributeType)const = 0;
-    /**
-    * Get all attributes with the given type
-    * @param attributeType type
-    * @returns vector of matching attributes can return an empty vector if there are no matches
-    */
-    virtual vector<TskBlackboardAttribute> getAttributes(const TSK_ATTRIBUTE_TYPE attributeType)const = 0;
-
-
-    /**
-    * Create a new blackboard artifact with the given type id and file id
-    * @param artifactTypeID artifact type id 
-    * @param file_id associated file id 
-    * @returns the new artifact
-    * @throws error if the artifact type does not exist
-    */
-    virtual TskBlackboardArtifact createArtifact(const uint64_t file_id, const int artifactTypeID) = 0;
-
-    /**
-    * Create a new blackboard artifact with the given type and file id
-    * @param file_id associated file id
-    * @param artifactType artifact type 
-    * @returns the new artifact
-    * @throws error if the artifact type does not exist
-    */
-    virtual TskBlackboardArtifact createArtifact(const uint64_t file_id, const TSK_ARTIFACT_TYPE artifactType) = 0;
-
-    /**
-    * Add a new artifact type with the given name and file id
-    * @param file_id associated file id
-    * @param artifactTypeName System name of artifact type 
-    * @returns the new artifact
-    * @throws error if the artifact type does not exist
-    */
-    virtual TskBlackboardArtifact createArtifact(const uint64_t file_id, const string& artifactTypeName) = 0;
-
-    /**
-    * Add a new attribute to the general info artifact for the given file
-    * @param file_id file id for the file to add the attribute to
-    * @param attr and attribute populated with values. this attribute will have
-    * its artifact_id and obj_id set by this method.
-    * @throws error if no file with the given id exists or if a bad attribute is passed in.
-    */
-    virtual void createGenInfoAttribute(const uint64_t file_id, TskBlackboardAttribute& attr) = 0;
-
-    /**
-    * Search the entire blackboard for all attribute types associated with any
-    * artifact of the given type.
-    * @param artifactTypeId artifact type to search
-    * @returns a vector of attribute ids can return an empty vector if no types are found
-    */
-    virtual vector<int> findAttributeTypes(int artifactTypeId) = 0;
-
-    /**
-    * Convert attribute type id to display name
-    * @param attributeTypeID attribute type id
-    * @returns display name
-    * @throws error if no type exists for that id
-    */
-    static string attrTypeIDToTypeDisplayName(const int attributeTypeID);
-    /**
-    * Convert attribute type name to id
-    * @param attributeTypeString attribute type name
-    * @returns attribute type id
-    * @throws error if no type exists with that name
-    */
-    static int attrTypeNameToTypeID(const string& attributeTypeString);
-    /**
-    * Convert attribute type id to name
-    * @param attributeTypeID id
-    * @returns attribute type name
-    * @throws error if no type exists with that name
-    */
-    static string attrTypeIDToTypeName(const int attributeTypeID);
-
-    /**
-    * Add a new attribute type with the given name and display name
-    * @param attributeTypeName name for the new attribute type. should be unique
-    * @param displayName name to display for this type. need not be unique
-    * @returns the new attribute type id generated for the type.
-    * @throws error if a type with that name already exists
-    */
-    static int addAttributeType(const string& attributeTypeName, const string& displayName);
-
-    /**
-    * Convert artifact type id to display name
-    * @param artifactTypeID artifact type id
-    * @returns display name
-    * @throws error if no type exists with that id
-    */
-    static string artTypeIDToDisplayName(const int artifactTypeID);
-    /**
-    * Convert artifact type name to id
-    * @param artifactTypeString artifact type name
-    * @returns artifact type id
-    * @throws error if no type exists with that name
-    */
-    static int artTypeNameToTypeID(const string& artifactTypeString);
-    /**
-    * Convert artifact type id to name
-    * @param artifactTypeID id
-    * @returns artifact type name
-    * @throws error if no type exists with that id
-    */
-    static string artTypeIDToTypeName(const int artifactTypeID);
-
-    /**
-    * Add a new artifact type with the given name and display name
-    * @param artifactTypeName name for the new attribute type. should be unique
-    * @param displayName name to display for this type. need not be unique
-    * @returns the new artifact type id generated for the type.
-    * @throws error if a type with that name already exists
-    */
-    static int addArtifactType(const string& artifactTypeName, const string& displayName);
-
-    friend class TskBlackboardArtifact;
-    friend class TskImgDB;
-
-protected:
-    static map<int, TskArtifactNames> getAllArtifactTypes();
-    static map<int, TskAttributeNames> getAllAttributeTypes();
-    virtual void addBlackboardAttribute(TskBlackboardAttribute& attr) = 0;
-    /// Default Constructor
-    TskBlackboard() {};
-
-    /// Copy Constructor
-    TskBlackboard(TskBlackboard const&) {};
-
-    /// Destructor
-    virtual ~TskBlackboard() {};
-
-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 TskBlackboard.h
+ * Interface for class that will implement the black board.  The black board
+ * is used to store data from analysis modules.  The data is available to
+ * later modules in the pipeline and in the final reporting phase.
+ */
+
+#ifndef _TSK_BLACKBOARD_H
+#define _TSK_BLACKBOARD_H
+
+#include <string>
+#include <vector>
+#include "tsk/framework/utilities/TskException.h"
+#include "tsk/framework/framework_i.h"
+#include "tsk/framework/services/TskImgDB.h"
+#include "TskBlackboardArtifact.h"
+#include "TskBlackboardAttribute.h"
+
+using namespace std;
+
+/**
+ * Built in artifact types.
+ * Refer to http://wiki.sleuthkit.org/index.php?title=Artifact_Examples
+ * for details on which attributes should be used for each artifact.
+ */
+
+/* Note that the below comments are the only documentation 
+ * for the standard types.  Please ensure that all types are
+ * documented. 
+ * 
+ * The numbers are explicitly added to make it easier to verify
+ * that the Java and C++ code is in sync.
+ *
+ * It is very important that this list be kept up to date and 
+ * in sync with the Java code.  Do not add anything here unless
+ * you also add it there.  
+ * See bindings/java/src/org/sleuthkit/datamodel/BlackboardArtifact.java */
+enum TSK_ARTIFACT_TYPE {
+    TSK_GEN_INFO = 1,///< The general info artifact, if information doesn't need its own artifact it should go here
+    TSK_WEB_BOOKMARK = 2,///< A web bookmark. 
+    TSK_WEB_COOKIE = 3,///< A web cookie. 
+    TSK_WEB_HISTORY = 4,///< A web history enrty. 
+    TSK_WEB_DOWNLOAD = 5,///< A web download. 
+    TSK_RECENT_OBJECT = 6,///< A recently used object (MRU, recent document, etc.).
+    TSK_GPS_TRACKPOINT = 7,///< A trackpoint from a GPS log.
+    TSK_INSTALLED_PROG = 8,///< An installed program. 
+    TSK_KEYWORD_HIT = 9,///< A keyword hit. 
+    TSK_HASHSET_HIT = 10, ///< A hit within a known bad / notable hashset / hash database. 
+    TSK_DEVICE_ATTACHED = 11, ///< An event for a device being attached to the host computer
+    TSK_INTERESTING_FILE_HIT = 12, ///< A file that was flagged because it matched some search criteria for being interesting (i.e. because of its name, extension, etc.)
+    TSK_EMAIL_MSG = 13, ///< An e-mail message that was extracted from a file.
+    TSK_EXTRACTED_TEXT = 14, ///< Text that was extracted from a file.
+    TSK_WEB_SEARCH_QUERY = 15, ///< Web search engine query extracted from web history.
+    TSK_METADATA_EXIF = 16, ///< EXIF Metadata
+    TSK_TAG_FILE = 17, ///< File tags.
+    TSK_TAG_ARTIFACT = 18, ///< Result tags.
+    TSK_OS_INFO = 19, ///< Information pertaining to an operating system.
+    TSK_OS_ACCOUNT = 20, ///< An operating system user account.
+    TSK_SERVICE_ACCOUNT = 21, ///< A network service user account.
+    TSK_TOOL_OUTPUT = 22,  ///< Output from an external tool or module (raw text)
+	TSK_CONTACT = 23, ///< A Contact extracted from a phone, or from an Addressbook/Email/Messaging Application
+	TSK_MESSAGE = 24, ///< An SMS/MMS message extracted from phone, or from another messaging application, like IM
+	TSK_CALLLOG = 25, ///< A Phone call log extracted from a phones or softphone application
+	TSK_CALENDAR_ENTRY = 26, ///< A Calendar entry from a phone, PIM or a Calendar application.
+	TSK_SPEED_DIAL_ENTRY = 27,  ///< A speed dial entry from a phone 
+	TSK_BLUETOOTH_PAIRING = 28,  ///< A bluetooth pairing entry
+	TSK_GPS_BOOKMARK = 29, ///< GPS Bookmarks
+	TSK_GPS_LAST_KNOWN_LOCATION = 30, ///< GPS Last known location
+	TSK_GPS_SEARCH = 31,	///< GPS Searches
+		 
+
+		
+    /* SEE ABOVE:
+    * - KEEP JAVA CODE IN SYNC 
+    * - UPDATE map in TskBlackboard.cpp
+    * - Update Wiki to reflect the attributes that should be part of the artifact. 
+    */
+};
+
+/**
+ * Built in attribute types 
+ */
+/* The numbers are explicitly added to make it easier to verify
+ * that the Java and C++ code is in sync.
+ *
+ * It is very important that this list be kept up to date and 
+ * in sync with the Java code.  Do not add anything here unless
+ * you also add it there.  
+ * See bindings/java/src/org/sleuthkit/datamodel/BlackboardAttribute.java 
+ */
+enum TSK_ATTRIBUTE_TYPE {
+    TSK_URL = 1,///< String of a URL, should start with http:// or ftp:// etc.  You should also make a TskBlackoard::TSK_DOMAIN entry for the base domain name. 
+    TSK_DATETIME = 2,///< INT32: GMT based Unix time, defines number of secords elapsed since UTC Jan 1, 1970.
+    TSK_NAME = 3,///< STRING: The name associated with an artifact
+    TSK_PROG_NAME = 4,///< String of name of a program that was installed on the system
+    TSK_VALUE = 6,///< Some value associated with an artifact
+    TSK_FLAG = 7,///< Some flag associated with an artifact
+    TSK_PATH = 8,///< A filesystem path.  Should be fully qualified. Should set TSK_PATH_ID as well when this is set. TODO: Need to define this value more for cases with multiple images and multiple file systems per image. 
+    TSK_KEYWORD = 10,///< STRING: Keyword that was found in this file. 
+    TSK_KEYWORD_REGEXP = 11,///< STRING: A regular expression string
+    TSK_KEYWORD_PREVIEW = 12,///< STRING: A text preview
+    TSK_KEYWORD_SET = 13,///< STRING: A keyword set -- Deprecated in favor of TSK_SET_NAME
+    TSK_USER_NAME = 14,///< String of a user name.  Use TskBlackboard::TSK_DOMAIN to store the domain that the username is from (if it is known). 
+    TSK_DOMAIN = 15,///< String of a DNS Domain name, e.g. sleuthkit.org  use TskBlackboad::TSK_URL for a full URL.
+    TSK_PASSWORD = 16,///< String of a password that was found.  Use TskBlackboard::TSK_USER_NAME and TskBlackboard::TSK_DOMAIN to link the password to a given user and site. 
+    TSK_NAME_PERSON = 17,///< String of a person name
+    TSK_DEVICE_MODEL = 18,///< String of manufacturer name of device that was connected (or somehow related to) the data being analyzed
+    TSK_DEVICE_MAKE = 19,///< String of make of a device that was connected (or somehow related to) the data being analyzed
+    TSK_DEVICE_ID = 20,///< String of ID/serial number of a device that was connected (or somehow related to) the data being analyzed
+    TSK_EMAIL = 21,///< String of e-mail address in the form of user at host.com (note that there are also more specific TSK_EMAIL_TO and TSK_EMAIL_FROM attributes if you know the use of the address)
+    TSK_HASH_MD5 = 22,///< STRING: MD5 hash
+    TSK_HASH_SHA1 = 23,///< STRING: SHA1 hash
+    TSK_HASH_SHA2_256 = 24,///< STRING: SHA2 256 bit hash
+    TSK_HASH_SHA2_512 = 25,///< STRING: SHA2 512 bit hash
+    TSK_TEXT = 26,///< String of text extracted from a file (should be part of TSK_EXTRACTED_TEXT artifact).
+    TSK_TEXT_FILE = 27,///< String of path to file containing text. May be absolute or relative. If relative, will be evaluated relative to OUT_DIR setting. Should be part of TSK_EXTRACTED_TEXT artifact)
+    TSK_TEXT_LANGUAGE = 28,///< String of the detected language in ISO 639-3 language code of TskBlackboard::TSK_TEXT data in the same artifact (TSK_EXTRACTED_TEXT, for example).
+    TSK_ENTROPY = 29,///< DOUBLE: Entropy value of file
+    TSK_HASHSET_NAME = 30,///< String of the name or file name of the hashset -- Deprecated in favor of TSK_SET_NAME
+    TSK_INTERESTING_FILE = 31,///< An interesting file hit, potentially file id, name, or path
+    TSK_REFERRER = 32,///< String of referrer URL
+    TSK_DATETIME_ACCESSED = 33,///<datetime last time accessed
+    TSK_IP_ADDRESS = 34,///<String of IP Address
+    TSK_PHONE_NUMBER = 35,///<String of phone number
+    TSK_PATH_ID = 36,///< Object ID from database that a TSK_PATH attribute corresponds to.  Set to -1 if path is for a file that is not in database (i.e. deleted). 
+    TSK_SET_NAME = 37,///< STRING: The name of a set that was used to find this artifact (to be used for hash hits, keyword hits, interesting files, etc.)
+    TSK_ENCRYPTION_DETECTED = 38,///< STRING: The type of encryption that is believed to have been used on the file.
+    TSK_MALWARE_DETECTED = 39,///< STRING: The name of the malware that was detected in this file.
+    TSK_STEG_DETECTED = 40,///< STRING: The name of the steganography technique that was detected in this file.
+    TSK_EMAIL_TO = 41, ///< String of an e-mail address that a message is being sent to directly (not cc:).
+    TSK_EMAIL_CC = 42, ///< String of an e-mail address that a message is being sent to as a cc:.
+    TSK_EMAIL_BCC = 43, ///< String of an e-mail address that a message is being sent to as a bcc:.
+    TSK_EMAIL_FROM = 44, ///< String of an e-mail address that a message is being sent from.
+    TSK_EMAIL_CONTENT_PLAIN = 45, ///< String of e-mail message body in plain text
+    TSK_EMAIL_CONTENT_HTML = 46, ///< STring of e-mail message body in HTML
+    TSK_EMAIL_CONTENT_RTF = 47, ///< STring of e-mail message body in RTF
+    TSK_MSG_ID = 48, ///< String of a message ID (such as one of an e-mail message)
+    TSK_MSG_REPLY_ID = 49, ///< String of a message ID that a given message is in response to (such as one of an e-mail message) 
+    TSK_DATETIME_RCVD = 50, ///< Time in Unix epoch that something was received.
+    TSK_DATETIME_SENT = 51, ///< Time in Unix epoch that something was sent.
+    TSK_SUBJECT = 52, ///< String of a subject (such as one of an e-mail message)
+    TSK_TITLE = 53, ///< String of a title (such as a webpage or other document)
+    TSK_GEO_LATITUDE = 54, ///< Floating point of latitude coordinate.  Should be in WGS84. Positive North, Negative South. 
+    TSK_GEO_LONGITUDE = 55, ///< Floating point of longitude coordinate.  Should be in WGS84.  Positive East, Negative West.
+    TSK_GEO_VELOCITY = 56, ///< Floating point of velocity in geo coordinate in meters per second.
+    TSK_GEO_ALTITUDE = 57, ///< Floating point of altitude in geo coordinate in meters.
+    TSK_GEO_BEARING = 58, ///< Floating point of bearing in geo coordinate in true degrees.
+    TSK_GEO_HPRECISION = 59, ///< Floating point of horizontal precision in geo coordinate in meters.
+    TSK_GEO_VPRECISION = 60, ///< Floating point of vertical precision in geo coordinate in meters.
+    TSK_GEO_MAPDATUM = 61, ///< String of map datum used for coordinates if not WGS84.
+    TSK_FILE_TYPE_SIG = 62, ///< String of file type based on signature detection in file content.
+    TSK_FILE_TYPE_EXT = 63, ///< String of file type based on file name extension.
+    TSK_TAGGED_ARTIFACT = 64, ///< Tagged artifact (associated result).
+    TSK_TAG_NAME = 65, ///< The tag name.  Can contain slashes "/" to represent tag hierarchy.
+    TSK_COMMENT = 66, ///< Comment string.
+    TSK_URL_DECODED = 67, ///< Decoded URL.
+    TSK_DATETIME_CREATED = 68,///< Time in Unix epoch that something was created
+    TSK_DATETIME_MODIFIED = 69,///< Time in Unix epoch that something was modified
+    TSK_PROCESSOR_ARCHITECTURE = 70,///< String of processor architecture.  Naming convention from http://en.wikipedia.org/wiki/Comparison_of_CPU_architectures.  So far, we've used x86, x86-64, and IA64.
+    TSK_VERSION = 71,///< String for a software version 
+    TSK_USER_ID = 72,///< User IDfor a user account, e.g., a Windows SID or Linux UID.
+    TSK_DESCRIPTION = 73, ///< String for a description associated with an artifact.
+	TSK_MESSAGE_TYPE =74, ///< SMS or MMS or IM ...
+	TSK_PHONE_NUMBER_HOME = 75, ///< Phone number (Home)
+	TSK_PHONE_NUMBER_OFFICE = 76, ///< Phone number (Office)
+	TSK_PHONE_NUMBER_MOBILE = 77, ///< Phone Number (Mobile)
+	TSK_PHONE_NUMBER_FROM = 78, ///<  Source Phone Number, originating a call or message
+	TSK_PHONE_NUMBER_TO = 79, /// < Destination Phone Number, receiving a call or message
+	TSK_DIRECTION = 80,  ///< Msg/Call direction: incoming, outgoing
+	TSK_EMAIL_HOME = 81, ///< Email (Home)"),
+	TSK_EMAIL_OFFICE = 82, ///< Email (Office)
+	TSK_DATETIME_START = 83, ///< start time of an event - call log, Calendar entry
+	TSK_DATETIME_END = 84, ///< end time of an event - call log, Calendar entry
+	TSK_CALENDAR_ENTRY_TYPE = 85, ///< calendar entry type: meeting, task, 
+	TSK_LOCATION = 86, 	// Location string associated with an event - Conf Room Name, Address ....
+	TSK_SHORTCUT = 87, ///< 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, ///< device name - a user assigned (usually) device name - such as "Joe's computer", "bob_win8", "BT Headset"
+	TSK_CATEGORY = 89, 	///< category/type, possible value set varies by the artifact
+	TSK_EMAIL_REPLYTO = 90, ///< ReplyTo address
+	TSK_SERVER_NAME = 91, 	///< server name
+
+    /* SEE ABOVE: 
+    * - KEEP JAVA CODE IN SYNC 
+    * - UPDATE map in TskBlackBoard.cpp too */
+};
+
+/**
+ * Class used to store the pair of type and display names of attributes.
+ */
+class TskAttributeNames{
+public:
+    string typeName;
+    string displayName;
+    TskAttributeNames(string name, string display):
+    typeName(name),
+        displayName(display){}
+};
+
+/**
+ * Class used to store the pair of type and display names of artifacts.
+ */
+class TskArtifactNames{
+public:
+    string typeName;
+    string displayName;
+    TskArtifactNames(string name, string display):
+    typeName(name),
+        displayName(display){}
+};
+
+/**
+ * An interface for setting and retrieving name/value pairs to the blackboard.
+ * The blackboard is used to store data for use by later modules in the pipeline.
+ * Can be registered with and retrieved from TskServices.
+ */
+class TSK_FRAMEWORK_API TskBlackboard
+{
+public:
+
+    /**
+    * Get the artifact with the given id
+    * @param artifactID id
+    * @returns the artifact throws an error if no artifact matches that id.
+    */
+    virtual TskBlackboardArtifact getBlackboardArtifact(const long artifactID) = 0;
+
+    /**
+    * Get all artifacts that match the given condition
+    * @param condition condition (implementation specific) to use for matching
+    * @returns vector of matching artifacts can return an empty vector if there are no matches
+    * @throws error if a bad condition string is supplied
+    */
+    virtual vector<TskBlackboardArtifact> getMatchingArtifacts(const string& condition)const = 0;
+    /**
+    * Get all artifacts with the given type name and file id
+    * @param file_id associated file id
+    * @param artifactTypeName type name
+    * @returns vector of matching artifacts can return an empty vector if there are no matches
+    */
+    virtual vector<TskBlackboardArtifact> getArtifacts(const uint64_t file_id, const string& artifactTypeName)const = 0;
+    /**
+    * Get all artifacts with the given type id and file id
+    * @param file_id associated file id
+    * @param artifactTypeID type id
+    * @returns vector of matching artifacts can return an empty vector if there are no matches
+    */
+    virtual vector<TskBlackboardArtifact> getArtifacts(const uint64_t file_id, int artifactTypeID)const = 0;
+    /**
+    * Get all artifacts with the given type and file id
+    * @param file_id associated file id
+    * @param artifactType name
+    * @returns vector of matching artifacts can return an empty vector if there are no matches
+    */
+    virtual vector<TskBlackboardArtifact> getArtifacts(const uint64_t file_id, TSK_ARTIFACT_TYPE artifactType)const = 0;
+    /**
+    * Get all artifacts with the given type
+    * @param artifactType type
+    * @returns vector of matching artifacts can return an empty vector if there are no matches
+    */
+    virtual vector<TskBlackboardArtifact> getArtifacts(const TSK_ARTIFACT_TYPE artifactType)const = 0;
+
+    /**
+    * Get all attributes that match the given condition 
+    * @param condition (implementation specific) to use for matching
+    * @returns vector of matching attributes can return an empty vector if there are no matches
+    * @throws error if a bad condition string is supplied
+    */
+    virtual vector<TskBlackboardAttribute> getMatchingAttributes(const string& condition)const = 0;   
+
+    /**
+    * Get all attributes with the given type name and file id
+    * @param file_id associated file id
+    * @param attributeTypeName type name
+    * @returns vector of matching attributes can return an empty vector if there are no matches
+    */
+    virtual vector<TskBlackboardAttribute> getAttributes(const uint64_t file_id, const string& attributeTypeName)const = 0;
+
+    /**
+    * Get all attributes with the given type and file id
+    * @param file_id associated file id
+    * @param attributeTypeID Type of attribute to return
+    * @returns vector of matching attributes can return an empty vector if there are no matches
+    */
+    virtual vector<TskBlackboardAttribute> getAttributes(const uint64_t file_id, int attributeTypeID)const = 0;
+
+    /** Get all attributes with the given type and file id
+    * @param file_id associated file id
+    * @param attributeType name
+    * @returns vector of matching attributes can return an empty vector if there are no matches
+    */
+    virtual vector<TskBlackboardAttribute> getAttributes(const uint64_t file_id, TSK_ATTRIBUTE_TYPE attributeType)const = 0;
+    /**
+    * Get all attributes with the given type
+    * @param attributeType type
+    * @returns vector of matching attributes can return an empty vector if there are no matches
+    */
+    virtual vector<TskBlackboardAttribute> getAttributes(const TSK_ATTRIBUTE_TYPE attributeType)const = 0;
+
+
+    /**
+    * Create a new blackboard artifact with the given type id and file id
+    * @param artifactTypeID artifact type id 
+    * @param file_id associated file id 
+    * @returns the new artifact
+    * @throws error if the artifact type does not exist
+    */
+    virtual TskBlackboardArtifact createArtifact(const uint64_t file_id, const int artifactTypeID) = 0;
+
+    /**
+    * Create a new blackboard artifact with the given type and file id
+    * @param file_id associated file id
+    * @param artifactType artifact type 
+    * @returns the new artifact
+    * @throws error if the artifact type does not exist
+    */
+    virtual TskBlackboardArtifact createArtifact(const uint64_t file_id, const TSK_ARTIFACT_TYPE artifactType) = 0;
+
+    /**
+    * Add a new artifact type with the given name and file id
+    * @param file_id associated file id
+    * @param artifactTypeName System name of artifact type 
+    * @returns the new artifact
+    * @throws error if the artifact type does not exist
+    */
+    virtual TskBlackboardArtifact createArtifact(const uint64_t file_id, const string& artifactTypeName) = 0;
+
+    /**
+    * Add a new attribute to the general info artifact for the given file
+    * @param file_id file id for the file to add the attribute to
+    * @param attr and attribute populated with values. this attribute will have
+    * its artifact_id and obj_id set by this method.
+    * @throws error if no file with the given id exists or if a bad attribute is passed in.
+    */
+    virtual void createGenInfoAttribute(const uint64_t file_id, TskBlackboardAttribute& attr) = 0;
+
+    /**
+    * Search the entire blackboard for all attribute types associated with any
+    * artifact of the given type.
+    * @param artifactTypeId artifact type to search
+    * @returns a vector of attribute ids can return an empty vector if no types are found
+    */
+    virtual vector<int> findAttributeTypes(int artifactTypeId) = 0;
+
+    /**
+    * Convert attribute type id to display name
+    * @param attributeTypeID attribute type id
+    * @returns display name
+    * @throws error if no type exists for that id
+    */
+    static string attrTypeIDToTypeDisplayName(const int attributeTypeID);
+    /**
+    * Convert attribute type name to id
+    * @param attributeTypeString attribute type name
+    * @returns attribute type id
+    * @throws error if no type exists with that name
+    */
+    static int attrTypeNameToTypeID(const string& attributeTypeString);
+    /**
+    * Convert attribute type id to name
+    * @param attributeTypeID id
+    * @returns attribute type name
+    * @throws error if no type exists with that name
+    */
+    static string attrTypeIDToTypeName(const int attributeTypeID);
+
+    /**
+    * Add a new attribute type with the given name and display name
+    * @param attributeTypeName name for the new attribute type. should be unique
+    * @param displayName name to display for this type. need not be unique
+    * @returns the new attribute type id generated for the type.
+    * @throws error if a type with that name already exists
+    */
+    static int addAttributeType(const string& attributeTypeName, const string& displayName);
+
+    /**
+    * Convert artifact type id to display name
+    * @param artifactTypeID artifact type id
+    * @returns display name
+    * @throws error if no type exists with that id
+    */
+    static string artTypeIDToDisplayName(const int artifactTypeID);
+    /**
+    * Convert artifact type name to id
+    * @param artifactTypeString artifact type name
+    * @returns artifact type id
+    * @throws error if no type exists with that name
+    */
+    static int artTypeNameToTypeID(const string& artifactTypeString);
+    /**
+    * Convert artifact type id to name
+    * @param artifactTypeID id
+    * @returns artifact type name
+    * @throws error if no type exists with that id
+    */
+    static string artTypeIDToTypeName(const int artifactTypeID);
+
+    /**
+    * Add a new artifact type with the given name and display name
+    * @param artifactTypeName name for the new attribute type. should be unique
+    * @param displayName name to display for this type. need not be unique
+    * @returns the new artifact type id generated for the type.
+    * @throws error if a type with that name already exists
+    */
+    static int addArtifactType(const string& artifactTypeName, const string& displayName);
+
+    friend class TskBlackboardArtifact;
+    friend class TskImgDB;
+
+protected:
+    static map<int, TskArtifactNames> getAllArtifactTypes();
+    static map<int, TskAttributeNames> getAllAttributeTypes();
+    virtual void addBlackboardAttribute(TskBlackboardAttribute& attr) = 0;
+    /// Default Constructor
+    TskBlackboard() {};
+
+    /// Copy Constructor
+    TskBlackboard(TskBlackboard const&) {};
+
+    /// Destructor
+    virtual ~TskBlackboard() {};
+
+private:
+
+};
+
+
+#endif
diff --git a/framework/tsk/framework/services/TskBlackboardArtifact.cpp b/framework/tsk/framework/services/TskBlackboardArtifact.cpp
index 3ecd7fb..914c655 100644
--- a/framework/tsk/framework/services/TskBlackboardArtifact.cpp
+++ b/framework/tsk/framework/services/TskBlackboardArtifact.cpp
@@ -1,99 +1,99 @@
-/*
-* 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 <vector>
-#include <iostream>
-#include <sstream>
-#include "tsk/framework/framework_i.h"
-#include "TskBlackboard.h"
-#include "TskBlackboardAttribute.h"
-#include "tsk/framework/utilities/TskException.h"
-#include "tsk/framework/services/TskServices.h"
-
-#define BLACKBOARD() (TskServices::Instance().getBlackboard())
-
-/**
-* Default destructor
-*/
-TskBlackboardArtifact::~TskBlackboardArtifact(){
-
-}
-
-/**
-* Get the artifact id
-* @returns artifact id
-*/
-uint64_t TskBlackboardArtifact::getArtifactID()const{
-    return m_artifactID;
-}
-
-/**
-* Get the object id
-* @returns object id
-*/
-uint64_t TskBlackboardArtifact::getObjectID()const{
-    return m_objID;
-}
-
-/**
-* Get the artifact type id
-* @returns artifact type id
-*/
-int TskBlackboardArtifact::getArtifactTypeID()const{
-    return m_artifactTypeID;
-}
-
-/**
-* Get the artifact type name
-* @returns artifact type name
-*/
-string TskBlackboardArtifact::getArtifactTypeName()const{
-    return BLACKBOARD().artTypeIDToTypeName(m_artifactTypeID);
-}
-
-/**
-* Get the display name
-* @returns display name
-*/
-string TskBlackboardArtifact::getDisplayName()const{
-    return BLACKBOARD().artTypeIDToDisplayName(m_artifactTypeID);
-}
-
-/**
-* Add an attribute to this artifact
-* @param attr attribute to be added
-* @throws error if the given attribute has a bad type
-*/
-void TskBlackboardArtifact::addAttribute(TskBlackboardAttribute& attr){
-    attr.setArtifactID(m_artifactID);
-    attr.setObjectID(m_objID);
-    BLACKBOARD().addBlackboardAttribute(attr);
-}
-
-/**
-* Get all attributes associated with this artifact
-* @returns a vector of attributes
-*/
-vector<TskBlackboardAttribute> TskBlackboardArtifact::getAttributes()const{
-    std::stringstream whereClause;
-    whereClause << "WHERE artifact_id = " << m_artifactID;
-
-    return BLACKBOARD().getMatchingAttributes(whereClause.str());
-}
-
-/**
-* Constructor
-* @param artifactID artifact id 
-* @param objID object id 
-* @param artifactTypeID arifact type id 
-*/	
-TskBlackboardArtifact::TskBlackboardArtifact(uint64_t artifactID, uint64_t objID, int artifactTypeID)
-: m_artifactID(artifactID), m_objID(objID), m_artifactTypeID(artifactTypeID) {}
+/*
+* 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 <vector>
+#include <iostream>
+#include <sstream>
+#include "tsk/framework/framework_i.h"
+#include "TskBlackboard.h"
+#include "TskBlackboardAttribute.h"
+#include "tsk/framework/utilities/TskException.h"
+#include "tsk/framework/services/TskServices.h"
+
+#define BLACKBOARD() (TskServices::Instance().getBlackboard())
+
+/**
+* Default destructor
+*/
+TskBlackboardArtifact::~TskBlackboardArtifact(){
+
+}
+
+/**
+* Get the artifact id
+* @returns artifact id
+*/
+uint64_t TskBlackboardArtifact::getArtifactID()const{
+    return m_artifactID;
+}
+
+/**
+* Get the object id
+* @returns object id
+*/
+uint64_t TskBlackboardArtifact::getObjectID()const{
+    return m_objID;
+}
+
+/**
+* Get the artifact type id
+* @returns artifact type id
+*/
+int TskBlackboardArtifact::getArtifactTypeID()const{
+    return m_artifactTypeID;
+}
+
+/**
+* Get the artifact type name
+* @returns artifact type name
+*/
+string TskBlackboardArtifact::getArtifactTypeName()const{
+    return BLACKBOARD().artTypeIDToTypeName(m_artifactTypeID);
+}
+
+/**
+* Get the display name
+* @returns display name
+*/
+string TskBlackboardArtifact::getDisplayName()const{
+    return BLACKBOARD().artTypeIDToDisplayName(m_artifactTypeID);
+}
+
+/**
+* Add an attribute to this artifact
+* @param attr attribute to be added
+* @throws error if the given attribute has a bad type
+*/
+void TskBlackboardArtifact::addAttribute(TskBlackboardAttribute& attr){
+    attr.setArtifactID(m_artifactID);
+    attr.setObjectID(m_objID);
+    BLACKBOARD().addBlackboardAttribute(attr);
+}
+
+/**
+* Get all attributes associated with this artifact
+* @returns a vector of attributes
+*/
+vector<TskBlackboardAttribute> TskBlackboardArtifact::getAttributes()const{
+    std::stringstream whereClause;
+    whereClause << "WHERE artifact_id = " << m_artifactID;
+
+    return BLACKBOARD().getMatchingAttributes(whereClause.str());
+}
+
+/**
+* Constructor
+* @param artifactID artifact id 
+* @param objID object id 
+* @param artifactTypeID arifact type id 
+*/	
+TskBlackboardArtifact::TskBlackboardArtifact(uint64_t artifactID, uint64_t objID, int artifactTypeID)
+: m_artifactID(artifactID), m_objID(objID), m_artifactTypeID(artifactTypeID) {}
diff --git a/framework/tsk/framework/services/TskBlackboardArtifact.h b/framework/tsk/framework/services/TskBlackboardArtifact.h
index 92e55ff..860c661 100644
--- a/framework/tsk/framework/services/TskBlackboardArtifact.h
+++ b/framework/tsk/framework/services/TskBlackboardArtifact.h
@@ -1,86 +1,86 @@
-/*
-* 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 TskBlackboardArtifact.h
-* Contains the definition for the TskBlackboardArtifact class.
-*/
-#ifndef _TSK_BLACKBOARD_ARTIFACT_H
-#define _TSK_BLACKBOARD_ARTIFACT_H
-
-#include <string>
-#include <vector>
-#include "tsk/framework/framework_i.h"
-
-using namespace std;
-
-class TskBlackboardAttribute;
-class TskBlackboard;
-
-/**
-* Class that represents a blackboard artifact object.
-*/
-class TSK_FRAMEWORK_API TskBlackboardArtifact
-{
-public:
-    /**
-    * Get the artifact id for this artifact
-    * @returns artifact id
-    */
-    uint64_t getArtifactID() const;
-    /**
-    * Get the object id for this artifact
-    * @returns object id
-    */
-    uint64_t getObjectID() const;
-    /**
-    * Get the artifact type id for this artifact
-    * @returns artifact type id
-    */
-    int getArtifactTypeID() const;
-    /**
-    * Get the artifact type name for this artifact
-    * @returns artifact type name
-    */
-    string getArtifactTypeName() const;
-    /**
-    * Get the display name for this artifact
-    * @returns display name
-    */
-    string getDisplayName() const;
-    /**
-    * Add an attribute to this artifact
-    * @param attr attribute to be added
-    */
-    void addAttribute(TskBlackboardAttribute& attr);
-    /**
-    * Get all attributes associated with this artifact
-    * @returns a vector of attributes
-    */
-    vector<TskBlackboardAttribute> getAttributes() const;	
-    /*
-    * destructor
-    */
-    ~TskBlackboardArtifact();
-
-    friend class TskBlackboard;
-    friend class TskFile;
-    friend class TskImgDB;
-
-protected:
-    TskBlackboardArtifact(const uint64_t artifactID, const uint64_t objID, const int artifactTypeID);
-
-private:
-    uint64_t m_artifactID;
-    uint64_t m_objID;
-    int m_artifactTypeID;
-};
-
-#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 TskBlackboardArtifact.h
+* Contains the definition for the TskBlackboardArtifact class.
+*/
+#ifndef _TSK_BLACKBOARD_ARTIFACT_H
+#define _TSK_BLACKBOARD_ARTIFACT_H
+
+#include <string>
+#include <vector>
+#include "tsk/framework/framework_i.h"
+
+using namespace std;
+
+class TskBlackboardAttribute;
+class TskBlackboard;
+
+/**
+* Class that represents a blackboard artifact object.
+*/
+class TSK_FRAMEWORK_API TskBlackboardArtifact
+{
+public:
+    /**
+    * Get the artifact id for this artifact
+    * @returns artifact id
+    */
+    uint64_t getArtifactID() const;
+    /**
+    * Get the object id for this artifact
+    * @returns object id
+    */
+    uint64_t getObjectID() const;
+    /**
+    * Get the artifact type id for this artifact
+    * @returns artifact type id
+    */
+    int getArtifactTypeID() const;
+    /**
+    * Get the artifact type name for this artifact
+    * @returns artifact type name
+    */
+    string getArtifactTypeName() const;
+    /**
+    * Get the display name for this artifact
+    * @returns display name
+    */
+    string getDisplayName() const;
+    /**
+    * Add an attribute to this artifact
+    * @param attr attribute to be added
+    */
+    void addAttribute(TskBlackboardAttribute& attr);
+    /**
+    * Get all attributes associated with this artifact
+    * @returns a vector of attributes
+    */
+    vector<TskBlackboardAttribute> getAttributes() const;	
+    /*
+    * destructor
+    */
+    ~TskBlackboardArtifact();
+
+    friend class TskBlackboard;
+    friend class TskFile;
+    friend class TskImgDB;
+
+protected:
+    TskBlackboardArtifact(const uint64_t artifactID, const uint64_t objID, const int artifactTypeID);
+
+private:
+    uint64_t m_artifactID;
+    uint64_t m_objID;
+    int m_artifactTypeID;
+};
+
+#endif
diff --git a/framework/tsk/framework/services/TskBlackboardAttribute.cpp b/framework/tsk/framework/services/TskBlackboardAttribute.cpp
index 1e08c9d..f8e5e17 100644
--- a/framework/tsk/framework/services/TskBlackboardAttribute.cpp
+++ b/framework/tsk/framework/services/TskBlackboardAttribute.cpp
@@ -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
-*/
-
-#include <string>
-#include <vector>
-#include "tsk/framework/framework_i.h"
-#include "TskBlackboardAttribute.h"
-#include "TskBlackboardArtifact.h"
-#include "TskBlackboard.h"
-#include "tsk/framework/utilities/TskException.h"
-#include "TskServices.h"
-
-/**
-* Default destructor
-*/	
-TskBlackboardAttribute::~TskBlackboardAttribute(){
-}
-
-/**
-* Constructor 
-* @param attributeTypeID attribute type id 
-* @param moduleName module that created this attribute 
-* @param context additional context 
-* @param valueInt integer value
-*/	
-TskBlackboardAttribute::TskBlackboardAttribute(const int attributeTypeID, const string& moduleName, const string& context, const int valueInt): 
-    m_artifactID(),
-    m_attributeTypeID(attributeTypeID),
-    m_moduleName(moduleName),
-    m_context(context),
-    m_valueType(TSK_INTEGER),
-    m_valueInt(valueInt),   
-    m_valueLong(),
-    m_valueDouble(),
-    m_valueString(),
-    m_valueBytes(),
-    m_objectID(){}
-
-/**
-* Constructor 
-* @param attributeTypeID attribute type id 
-* @param moduleName module that created this attribute 
-* @param context additional context 
-* @param valueLong 64 bit integer value
-*/	
-TskBlackboardAttribute::TskBlackboardAttribute(const int attributeTypeID, const string& moduleName, const string& context, const uint64_t valueLong): 
-    m_artifactID(),
-    m_attributeTypeID(attributeTypeID),
-    m_moduleName(moduleName),
-    m_context(context),
-    m_valueType(TSK_LONG),
-    m_valueInt(),
-    m_valueLong(valueLong),   
-    m_valueDouble(),
-    m_valueString(),
-    m_valueBytes(),
-    m_objectID(){}
-
-/**
-* Constructor 
-* @param attributeTypeID attribute type id 
-* @param moduleName module that created this attribute 
-* @param context additional context 
-* @param valueDouble double value
-*/	
-TskBlackboardAttribute::TskBlackboardAttribute(const int attributeTypeID, const string& moduleName, const string& context, const double valueDouble): 
-    m_artifactID(),
-    m_attributeTypeID(attributeTypeID),
-    m_moduleName(moduleName),
-    m_context(context),
-    m_valueType(TSK_DOUBLE),
-    m_valueInt(),
-    m_valueLong(),   
-    m_valueDouble(valueDouble),
-    m_valueString(),
-    m_valueBytes(),
-    m_objectID(){}
-
-/**
-* Constructor 
-* @param attributeTypeID attribute type id 
-* @param moduleName module that created this attribute 
-* @param context additional context 
-* @param valueString string value
-*/	
-TskBlackboardAttribute::TskBlackboardAttribute(const int attributeTypeID, const string& moduleName, const string& context, const string& valueString): 
-    m_artifactID(),
-    m_attributeTypeID(attributeTypeID),
-    m_moduleName(moduleName),
-    m_context(context),
-    m_valueType(TSK_STRING),
-    m_valueInt(),
-    m_valueLong(),   
-    m_valueDouble(),
-    m_valueString(valueString),
-    m_valueBytes(),
-    m_objectID(){}
-
-/**
-* Constructor 
-* @param attributeTypeID attribute type id 
-* @param moduleName module that created this attribute 
-* @param context additional context 
-* @param valueBytes byte array value
-*/	
-TskBlackboardAttribute::TskBlackboardAttribute(const int attributeTypeID, const string& moduleName, const string& context, const vector<unsigned char>& valueBytes): 
-    m_artifactID(),
-    m_attributeTypeID(attributeTypeID),
-    m_moduleName(moduleName),
-    m_context(context),
-    m_valueType(TSK_BYTE),
-    m_valueInt(),
-    m_valueLong(),   
-    m_valueDouble(),
-    m_valueString(),
-    m_valueBytes(valueBytes),
-    m_objectID(){}
-
-/**
-* Constructor 
-* @param artifactID if of the artifact this is associated with
-* @param attributeTypeID attribute type id 
-* @param moduleName module that created this attribute 
-* @param context additional context 
-* @param valueType Type of value being set (only the corresponding value from the next parameters will be used)
-* @param valueInt integer value
-* @param valueLong 64 bit integer value
-* @param valueDouble double value
-* @param valueString string value
-* @param valueBytes byte array value
-* @param objectID object the attribute is associated with
-*/	
-TskBlackboardAttribute::TskBlackboardAttribute(const uint64_t artifactID, const int attributeTypeID, const uint64_t objectID, const string& moduleName, const string& context,
-                                               const TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE valueType, const int valueInt, const uint64_t valueLong, const double valueDouble, 
-                                               const string& valueString, const vector<unsigned char>& valueBytes):
-m_artifactID(artifactID), 
-m_attributeTypeID(attributeTypeID),
-m_moduleName(moduleName),
-m_context(context),
-m_valueType(valueType),
-m_valueInt(valueInt),
-m_valueLong(valueLong),
-m_valueDouble(valueDouble),
-m_valueString(valueString),
-m_valueBytes(valueBytes),
-m_objectID(objectID){}
-
-/**
-* Get artifact id
-* @returns artifact id
-*/	
-uint64_t TskBlackboardAttribute::getArtifactID()const{
-    return m_artifactID;
-}
-
-/**
-* Get attribute type id
-* @returns attribute type id
-*/	
-int TskBlackboardAttribute::getAttributeTypeID()const{
-    return m_attributeTypeID;
-}
-
-/**
-* Get value type
-* @returns value type
-*/	
-TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE TskBlackboardAttribute::getValueType()const {
-    return m_valueType;
-}
-
-/**
-* Get value int
-* @returns value int
-*/	
-int TskBlackboardAttribute::getValueInt()const{
-    return m_valueInt;
-}
-
-/**
-* Get value long
-* @returns value long
-*/	
-uint64_t TskBlackboardAttribute::getValueLong()const{
-    return m_valueLong;
-}
-
-/**
-* Get value double
-* @returns value double
-*/	
-double TskBlackboardAttribute::getValueDouble()const{
-    return m_valueDouble;
-}
-
-/**
-* Get value string
-* @returns value string
-*/	
-string TskBlackboardAttribute::getValueString()const{
-    return m_valueString;
-}
-
-/**
-* Get value bytes
-* @returns value bytes
-*/	
-vector<unsigned char> TskBlackboardAttribute::getValueBytes()const{
-    return m_valueBytes;
-}
-
-/**
-* Get module name
-* @returns module name
-*/	
-string TskBlackboardAttribute::getModuleName()const{
-    return m_moduleName;
-}
-
-/**
-* Get context
-* @returns context
-*/	
-string TskBlackboardAttribute::getContext()const{
-    return m_context;
-}
-
-/**
-* Get parent artifact
-* @returns parent artifact
-*/	
-TskBlackboardArtifact TskBlackboardAttribute::getParentArtifact()const{
-    return TskServices::Instance().getBlackboard().getBlackboardArtifact(m_artifactID);
-}
-
-/**
-* Get object id
-* @returns object id
-*/
-uint64_t TskBlackboardAttribute::getObjectID()const{
-    return m_objectID;
-}
-
-/**
-* Set object id
-* @param objectID object id
-*/
-void TskBlackboardAttribute::setObjectID(uint64_t objectID){
-    m_objectID = objectID;
-}
-
-/**
-* Set artifact id
-* @param artifactID artifact id
-*/
-void TskBlackboardAttribute::setArtifactID(uint64_t artifactID){
-    m_artifactID = artifactID;
-}
+/*
+* 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 <vector>
+#include "tsk/framework/framework_i.h"
+#include "TskBlackboardAttribute.h"
+#include "TskBlackboardArtifact.h"
+#include "TskBlackboard.h"
+#include "tsk/framework/utilities/TskException.h"
+#include "TskServices.h"
+
+/**
+* Default destructor
+*/	
+TskBlackboardAttribute::~TskBlackboardAttribute(){
+}
+
+/**
+* Constructor 
+* @param attributeTypeID attribute type id 
+* @param moduleName module that created this attribute 
+* @param context additional context 
+* @param valueInt integer value
+*/	
+TskBlackboardAttribute::TskBlackboardAttribute(const int attributeTypeID, const string& moduleName, const string& context, const int valueInt): 
+    m_artifactID(),
+    m_attributeTypeID(attributeTypeID),
+    m_moduleName(moduleName),
+    m_context(context),
+    m_valueType(TSK_INTEGER),
+    m_valueInt(valueInt),   
+    m_valueLong(),
+    m_valueDouble(),
+    m_valueString(),
+    m_valueBytes(),
+    m_objectID(){}
+
+/**
+* Constructor 
+* @param attributeTypeID attribute type id 
+* @param moduleName module that created this attribute 
+* @param context additional context 
+* @param valueLong 64 bit integer value
+*/	
+TskBlackboardAttribute::TskBlackboardAttribute(const int attributeTypeID, const string& moduleName, const string& context, const uint64_t valueLong): 
+    m_artifactID(),
+    m_attributeTypeID(attributeTypeID),
+    m_moduleName(moduleName),
+    m_context(context),
+    m_valueType(TSK_LONG),
+    m_valueInt(),
+    m_valueLong(valueLong),   
+    m_valueDouble(),
+    m_valueString(),
+    m_valueBytes(),
+    m_objectID(){}
+
+/**
+* Constructor 
+* @param attributeTypeID attribute type id 
+* @param moduleName module that created this attribute 
+* @param context additional context 
+* @param valueDouble double value
+*/	
+TskBlackboardAttribute::TskBlackboardAttribute(const int attributeTypeID, const string& moduleName, const string& context, const double valueDouble): 
+    m_artifactID(),
+    m_attributeTypeID(attributeTypeID),
+    m_moduleName(moduleName),
+    m_context(context),
+    m_valueType(TSK_DOUBLE),
+    m_valueInt(),
+    m_valueLong(),   
+    m_valueDouble(valueDouble),
+    m_valueString(),
+    m_valueBytes(),
+    m_objectID(){}
+
+/**
+* Constructor 
+* @param attributeTypeID attribute type id 
+* @param moduleName module that created this attribute 
+* @param context additional context 
+* @param valueString string value
+*/	
+TskBlackboardAttribute::TskBlackboardAttribute(const int attributeTypeID, const string& moduleName, const string& context, const string& valueString): 
+    m_artifactID(),
+    m_attributeTypeID(attributeTypeID),
+    m_moduleName(moduleName),
+    m_context(context),
+    m_valueType(TSK_STRING),
+    m_valueInt(),
+    m_valueLong(),   
+    m_valueDouble(),
+    m_valueString(valueString),
+    m_valueBytes(),
+    m_objectID(){}
+
+/**
+* Constructor 
+* @param attributeTypeID attribute type id 
+* @param moduleName module that created this attribute 
+* @param context additional context 
+* @param valueBytes byte array value
+*/	
+TskBlackboardAttribute::TskBlackboardAttribute(const int attributeTypeID, const string& moduleName, const string& context, const vector<unsigned char>& valueBytes): 
+    m_artifactID(),
+    m_attributeTypeID(attributeTypeID),
+    m_moduleName(moduleName),
+    m_context(context),
+    m_valueType(TSK_BYTE),
+    m_valueInt(),
+    m_valueLong(),   
+    m_valueDouble(),
+    m_valueString(),
+    m_valueBytes(valueBytes),
+    m_objectID(){}
+
+/**
+* Constructor 
+* @param artifactID if of the artifact this is associated with
+* @param attributeTypeID attribute type id 
+* @param moduleName module that created this attribute 
+* @param context additional context 
+* @param valueType Type of value being set (only the corresponding value from the next parameters will be used)
+* @param valueInt integer value
+* @param valueLong 64 bit integer value
+* @param valueDouble double value
+* @param valueString string value
+* @param valueBytes byte array value
+* @param objectID object the attribute is associated with
+*/	
+TskBlackboardAttribute::TskBlackboardAttribute(const uint64_t artifactID, const int attributeTypeID, const uint64_t objectID, const string& moduleName, const string& context,
+                                               const TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE valueType, const int valueInt, const uint64_t valueLong, const double valueDouble, 
+                                               const string& valueString, const vector<unsigned char>& valueBytes):
+m_artifactID(artifactID), 
+m_attributeTypeID(attributeTypeID),
+m_moduleName(moduleName),
+m_context(context),
+m_valueType(valueType),
+m_valueInt(valueInt),
+m_valueLong(valueLong),
+m_valueDouble(valueDouble),
+m_valueString(valueString),
+m_valueBytes(valueBytes),
+m_objectID(objectID){}
+
+/**
+* Get artifact id
+* @returns artifact id
+*/	
+uint64_t TskBlackboardAttribute::getArtifactID()const{
+    return m_artifactID;
+}
+
+/**
+* Get attribute type id
+* @returns attribute type id
+*/	
+int TskBlackboardAttribute::getAttributeTypeID()const{
+    return m_attributeTypeID;
+}
+
+/**
+* Get value type
+* @returns value type
+*/	
+TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE TskBlackboardAttribute::getValueType()const {
+    return m_valueType;
+}
+
+/**
+* Get value int
+* @returns value int
+*/	
+int TskBlackboardAttribute::getValueInt()const{
+    return m_valueInt;
+}
+
+/**
+* Get value long
+* @returns value long
+*/	
+uint64_t TskBlackboardAttribute::getValueLong()const{
+    return m_valueLong;
+}
+
+/**
+* Get value double
+* @returns value double
+*/	
+double TskBlackboardAttribute::getValueDouble()const{
+    return m_valueDouble;
+}
+
+/**
+* Get value string
+* @returns value string
+*/	
+string TskBlackboardAttribute::getValueString()const{
+    return m_valueString;
+}
+
+/**
+* Get value bytes
+* @returns value bytes
+*/	
+vector<unsigned char> TskBlackboardAttribute::getValueBytes()const{
+    return m_valueBytes;
+}
+
+/**
+* Get module name
+* @returns module name
+*/	
+string TskBlackboardAttribute::getModuleName()const{
+    return m_moduleName;
+}
+
+/**
+* Get context
+* @returns context
+*/	
+string TskBlackboardAttribute::getContext()const{
+    return m_context;
+}
+
+/**
+* Get parent artifact
+* @returns parent artifact
+*/	
+TskBlackboardArtifact TskBlackboardAttribute::getParentArtifact()const{
+    return TskServices::Instance().getBlackboard().getBlackboardArtifact(m_artifactID);
+}
+
+/**
+* Get object id
+* @returns object id
+*/
+uint64_t TskBlackboardAttribute::getObjectID()const{
+    return m_objectID;
+}
+
+/**
+* Set object id
+* @param objectID object id
+*/
+void TskBlackboardAttribute::setObjectID(uint64_t objectID){
+    m_objectID = objectID;
+}
+
+/**
+* Set artifact id
+* @param artifactID artifact id
+*/
+void TskBlackboardAttribute::setArtifactID(uint64_t artifactID){
+    m_artifactID = artifactID;
+}
diff --git a/framework/tsk/framework/services/TskBlackboardAttribute.h b/framework/tsk/framework/services/TskBlackboardAttribute.h
index 4184665..40e0173 100644
--- a/framework/tsk/framework/services/TskBlackboardAttribute.h
+++ b/framework/tsk/framework/services/TskBlackboardAttribute.h
@@ -1,183 +1,183 @@
-/*
-* 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 TskBlackboardAttribute.h
-* Contains the definition for the TskBlackboardAttribute class.
-*/
-
-#ifndef _TSK_BLACKBOARD_ATTR_H
-#define _TSK_BLACKBOARD_ATTR_H
-
-#include <string>
-#include <vector>
-#include <map>
-#include "tsk/framework/framework_i.h"
-
-using namespace std;
-
-/**
-* Value type enum, should always correspond to the stored value in an 
-* attribute
-*/
-enum TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE {
-    TSK_STRING = 0,	   ///< string
-    TSK_INTEGER,   ///< int
-    TSK_LONG,			///< long
-    TSK_DOUBLE,	  ///< double
-    TSK_BYTE,
-};	  ///< byte
-
-
-class TskBlackboardArtifact;
-class TskBlackboard;
-
-/**
-* Class that represents a blackboard attribute object.
-*/
-class TSK_FRAMEWORK_API TskBlackboardAttribute 
-{
-public:
-
-
-    /**
-    * Constructor for an attribute storing an int 
-    * @param attributeTypeID attribute type id 
-    * @param moduleName module that created this attribute 
-    * @param context additional context 
-    * @param valueInt integer value
-    */	
-    TskBlackboardAttribute(const int attributeTypeID, const string& moduleName, const string& context, const int valueInt);
-    /**
-    * Constructor for an attribute storing a 64 bit integer 
-    * @param attributeTypeID attribute type id 
-    * @param moduleName module that created this attribute 
-    * @param context additional context 
-    * @param valueLong 64 bit integer value
-    */	
-    TskBlackboardAttribute(const int attributeTypeID, const string& moduleName, const string& context, const uint64_t valueLong);
-    /**
-    * Constructor for an attribute storing a double 
-    * @param attributeTypeID attribute type id 
-    * @param moduleName module that created this attribute 
-    * @param context additional context 
-    * @param valueDouble double value
-    */	
-    TskBlackboardAttribute(const int attributeTypeID, const string& moduleName, const string& context, const double valueDouble);
-    /**
-    * Constructor for an attribute storing a string
-    * @param attributeTypeID attribute type id 
-    * @param moduleName module that created this attribute 
-    * @param context additional context 
-    * @param valueString string value
-    */	
-    TskBlackboardAttribute(const int attributeTypeID, const string& moduleName, const string& context, const string& valueString);
-    /**
-    * Constructor for an attribute storing a byte array
-    * @param attributeTypeID attribute type id 
-    * @param moduleName module that created this attribute 
-    * @param context additional context 
-    * @param valueBytes byte array value
-    */
-    TskBlackboardAttribute(const int attributeTypeID, const string& moduleName, const string& context, const vector<unsigned char>& valueBytes);
-    /*
-    * destructor
-    */
-    ~TskBlackboardAttribute();
-
-    /**
-    * Get artifact id for the parent of this attribute
-    * @returns artifact id
-    */	
-    uint64_t getArtifactID() const;
-    /**
-    * Get attribute type id for this attribute
-    * @returns attribute type id
-    */	
-    int getAttributeTypeID() const;
-    /**
-    * Get typeof value this attribute stores
-    * @returns value type
-    */	
-    TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE getValueType() const;
-    /**
-    * Get value int (if the attribute stores an int)
-    * @returns value int
-    */	
-    int getValueInt() const;
-    /**
-    * Get value long (if the attribute stores a long0
-    * @returns value long
-    */	
-    uint64_t getValueLong() const;
-    /**
-    * Get value double (if the attribute stores a double)
-    * @returns value double
-    */	
-    double getValueDouble() const;
-    /**
-    * Get value string (if this attribute stores a string)
-    * @returns value string
-    */	
-    string getValueString() const;
-    /**
-    * Get value bytes (if this attribute stores bytes)
-    * @returns value bytes
-    */	
-    vector<unsigned char> getValueBytes() const;
-    /**
-    * Get nameof the module that created this attribute
-    * @returns module name
-    */
-    string getModuleName() const;
-    /**
-    * Get context for this attribute
-    * @returns context
-    */
-    string getContext() const;
-    /**
-    * Get object id this attribute is associated with
-    * @returns object id
-    */
-    uint64_t getObjectID() const;
-
-    /**
-    * Get parent artifact for this attribute
-    * @returns parent artifact
-    */	
-    TskBlackboardArtifact getParentArtifact() const; 
-
-    friend class TskImgDB;
-    friend class TskDBBlackboard;
-    friend class TskBlackboardArtifact;
-    friend class TskFile;
-
-protected:
-    void setArtifactID(uint64_t artifactID);
-    void setObjectID(uint64_t objectID);
-
-    TskBlackboardAttribute(const uint64_t artifactID, const int attributeTypeID, const uint64_t objectID, const string& moduleName, const string& context,
-        const TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE valueType, const int valueInt, const uint64_t valueLong, const double valueDouble, 
-        const string& valueString, const vector<unsigned char>& valueBytes);
-private:
-    uint64_t m_artifactID;
-    int m_attributeTypeID;
-    string m_moduleName;
-    string m_context;
-    TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE m_valueType;
-    int m_valueInt;
-    uint64_t m_valueLong;
-    double m_valueDouble;
-    string m_valueString;
-    vector<unsigned char> m_valueBytes;
-    uint64_t m_objectID;
-};
-
-#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 TskBlackboardAttribute.h
+* Contains the definition for the TskBlackboardAttribute class.
+*/
+
+#ifndef _TSK_BLACKBOARD_ATTR_H
+#define _TSK_BLACKBOARD_ATTR_H
+
+#include <string>
+#include <vector>
+#include <map>
+#include "tsk/framework/framework_i.h"
+
+using namespace std;
+
+/**
+* Value type enum, should always correspond to the stored value in an 
+* attribute
+*/
+enum TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE {
+    TSK_STRING = 0,	   ///< string
+    TSK_INTEGER,   ///< int
+    TSK_LONG,			///< long
+    TSK_DOUBLE,	  ///< double
+    TSK_BYTE,
+};	  ///< byte
+
+
+class TskBlackboardArtifact;
+class TskBlackboard;
+
+/**
+* Class that represents a blackboard attribute object.
+*/
+class TSK_FRAMEWORK_API TskBlackboardAttribute 
+{
+public:
+
+
+    /**
+    * Constructor for an attribute storing an int 
+    * @param attributeTypeID attribute type id 
+    * @param moduleName module that created this attribute 
+    * @param context additional context 
+    * @param valueInt integer value
+    */	
+    TskBlackboardAttribute(const int attributeTypeID, const string& moduleName, const string& context, const int valueInt);
+    /**
+    * Constructor for an attribute storing a 64 bit integer 
+    * @param attributeTypeID attribute type id 
+    * @param moduleName module that created this attribute 
+    * @param context additional context 
+    * @param valueLong 64 bit integer value
+    */	
+    TskBlackboardAttribute(const int attributeTypeID, const string& moduleName, const string& context, const uint64_t valueLong);
+    /**
+    * Constructor for an attribute storing a double 
+    * @param attributeTypeID attribute type id 
+    * @param moduleName module that created this attribute 
+    * @param context additional context 
+    * @param valueDouble double value
+    */	
+    TskBlackboardAttribute(const int attributeTypeID, const string& moduleName, const string& context, const double valueDouble);
+    /**
+    * Constructor for an attribute storing a string
+    * @param attributeTypeID attribute type id 
+    * @param moduleName module that created this attribute 
+    * @param context additional context 
+    * @param valueString string value
+    */	
+    TskBlackboardAttribute(const int attributeTypeID, const string& moduleName, const string& context, const string& valueString);
+    /**
+    * Constructor for an attribute storing a byte array
+    * @param attributeTypeID attribute type id 
+    * @param moduleName module that created this attribute 
+    * @param context additional context 
+    * @param valueBytes byte array value
+    */
+    TskBlackboardAttribute(const int attributeTypeID, const string& moduleName, const string& context, const vector<unsigned char>& valueBytes);
+    /*
+    * destructor
+    */
+    ~TskBlackboardAttribute();
+
+    /**
+    * Get artifact id for the parent of this attribute
+    * @returns artifact id
+    */	
+    uint64_t getArtifactID() const;
+    /**
+    * Get attribute type id for this attribute
+    * @returns attribute type id
+    */	
+    int getAttributeTypeID() const;
+    /**
+    * Get typeof value this attribute stores
+    * @returns value type
+    */	
+    TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE getValueType() const;
+    /**
+    * Get value int (if the attribute stores an int)
+    * @returns value int
+    */	
+    int getValueInt() const;
+    /**
+    * Get value long (if the attribute stores a long0
+    * @returns value long
+    */	
+    uint64_t getValueLong() const;
+    /**
+    * Get value double (if the attribute stores a double)
+    * @returns value double
+    */	
+    double getValueDouble() const;
+    /**
+    * Get value string (if this attribute stores a string)
+    * @returns value string
+    */	
+    string getValueString() const;
+    /**
+    * Get value bytes (if this attribute stores bytes)
+    * @returns value bytes
+    */	
+    vector<unsigned char> getValueBytes() const;
+    /**
+    * Get nameof the module that created this attribute
+    * @returns module name
+    */
+    string getModuleName() const;
+    /**
+    * Get context for this attribute
+    * @returns context
+    */
+    string getContext() const;
+    /**
+    * Get object id this attribute is associated with
+    * @returns object id
+    */
+    uint64_t getObjectID() const;
+
+    /**
+    * Get parent artifact for this attribute
+    * @returns parent artifact
+    */	
+    TskBlackboardArtifact getParentArtifact() const; 
+
+    friend class TskImgDB;
+    friend class TskDBBlackboard;
+    friend class TskBlackboardArtifact;
+    friend class TskFile;
+
+protected:
+    void setArtifactID(uint64_t artifactID);
+    void setObjectID(uint64_t objectID);
+
+    TskBlackboardAttribute(const uint64_t artifactID, const int attributeTypeID, const uint64_t objectID, const string& moduleName, const string& context,
+        const TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE valueType, const int valueInt, const uint64_t valueLong, const double valueDouble, 
+        const string& valueString, const vector<unsigned char>& valueBytes);
+private:
+    uint64_t m_artifactID;
+    int m_attributeTypeID;
+    string m_moduleName;
+    string m_context;
+    TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE m_valueType;
+    int m_valueInt;
+    uint64_t m_valueLong;
+    double m_valueDouble;
+    string m_valueString;
+    vector<unsigned char> m_valueBytes;
+    uint64_t m_objectID;
+};
+
+#endif
diff --git a/framework/tsk/framework/services/TskDBBlackboard.cpp b/framework/tsk/framework/services/TskDBBlackboard.cpp
index 9f38cac..7c94ba0 100755
--- a/framework/tsk/framework/services/TskDBBlackboard.cpp
+++ b/framework/tsk/framework/services/TskDBBlackboard.cpp
@@ -1,212 +1,212 @@
-/*
- * 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 "TskDBBlackboard.h"
-#include "tsk/framework/services/TskImgDB.h"
-#include "tsk/framework/services/TskServices.h"
-#include "tsk/framework/file/TskFileTsk.h"
-#include "tsk/framework/file/TskFile.h"
-#include "tsk/framework/file/TskFileManagerImpl.h"
-
-TskDBBlackboard * TskDBBlackboard::m_pInstance = NULL;
-
-#define IMGDB() (TskServices::Instance().getImgDB())
-
-TskDBBlackboard& TskDBBlackboard::instance()
-{
-    if (!m_pInstance)
-    {
-        m_pInstance = new TskDBBlackboard();
-    }
-    return *m_pInstance;
-}
-
-int TskDBBlackboard::addArtifactType(const string& artifactTypeName, const string& displayName){
-    try{
-        return TskBlackboard::artTypeNameToTypeID(artifactTypeName);
-    }
-    catch(TskException e){
-        try{
-            return IMGDB().getArtifactTypeID(artifactTypeName);
-        }
-        catch(TskException e){
-            int id = TskBlackboard::addArtifactType(artifactTypeName, displayName);
-            IMGDB().addArtifactType(id, artifactTypeName, displayName);
-            return id;
-        }
-    }
-}
-
-int TskDBBlackboard::addAttributeType(const string& attributeTypeName, const string& displayName){
-    try{
-        return TskBlackboard::attrTypeNameToTypeID(attributeTypeName);
-    }
-    catch(TskException e){
-        try{
-            return IMGDB().getAttributeTypeID(attributeTypeName);
-        }
-        catch(TskException e){
-            int id = TskBlackboard::addAttributeType(attributeTypeName, displayName);
-            IMGDB().addAttributeType(id, attributeTypeName, displayName);
-            return id;
-        }
-    }
-}
-
-void TskDBBlackboard::addBlackboardAttribute(TskBlackboardAttribute& attr){
-    if(attrTypeIDToTypeName(attr.getAttributeTypeID()).compare("") != 0)
-        IMGDB().addBlackboardAttribute(attr);
-    else
-        throw new TskException("No attribute type for the id of the given attribute");
-}
-
-string TskDBBlackboard::attrTypeIDToTypeDisplayName(const int attributeTypeID){
-    try{
-        return TskBlackboard::attrTypeIDToTypeDisplayName(attributeTypeID);
-    }
-    catch(TskException e){
-        return IMGDB().getAttributeTypeDisplayName(attributeTypeID);
-    }
-}
-
-int TskDBBlackboard::attrTypeNameToTypeID(const string& attributeTypeString){
-    try{
-        return TskBlackboard::attrTypeNameToTypeID(attributeTypeString);
-    }
-    catch(TskException e){
-        return IMGDB().getAttributeTypeID(attributeTypeString);
-    } 
-}
-
-string TskDBBlackboard::attrTypeIDToTypeName(const int attributeTypeID){
-    try{
-    return TskBlackboard::attrTypeIDToTypeName(attributeTypeID);
-    }
-    catch(TskException e){
-        return IMGDB().getAttributeTypeName(attributeTypeID);
-    }
-}
-
-string TskDBBlackboard::artTypeIDToDisplayName(const int artifactTypeID){
-    try{
-    return TskBlackboard::artTypeIDToDisplayName(artifactTypeID);}
-    catch(TskException e){
-        return IMGDB().getArtifactTypeDisplayName(artifactTypeID);
-    }
-}
-
-int TskDBBlackboard::artTypeNameToTypeID(const string& artifactTypeString){
-    try{
-    return TskBlackboard::artTypeNameToTypeID(artifactTypeString);}
-    catch(TskException e){
-        return IMGDB().getArtifactTypeID(artifactTypeString);
-    }
-}
-string TskDBBlackboard::artTypeIDToTypeName(const int artifactTypeID){
-    try{
-    return TskBlackboard::artTypeIDToTypeName(artifactTypeID);}
-    catch(TskException e){
-        return IMGDB().getArtifactTypeName(artifactTypeID);
-    }
-}
-
-TskBlackboardArtifact TskDBBlackboard::getBlackboardArtifact(const long artifactID){
-    stringstream condition;
-    condition << " WHERE artifact_id = " << artifactID;
-    return IMGDB().getMatchingArtifacts(condition.str())[0];
-}
-
-vector<TskBlackboardArtifact> TskDBBlackboard::getArtifacts(const uint64_t file_id, const string& artifactTypeName)const{
-    stringstream condition;
-    condition << " WHERE obj_id = " << file_id << " AND artifact_type_id = " << attrTypeNameToTypeID(artifactTypeName);
-    return IMGDB().getMatchingArtifacts(condition.str());
-}
-
-vector<TskBlackboardArtifact> TskDBBlackboard::getArtifacts(const uint64_t file_id, int artifactTypeID)const{
-    stringstream condition;
-    condition << " WHERE obj_id = " << file_id << " AND artifact_type_id = " << artifactTypeID;
-    return IMGDB().getMatchingArtifacts(condition.str());
-}
-
-vector<TskBlackboardArtifact> TskDBBlackboard::getArtifacts(const uint64_t file_id, TSK_ARTIFACT_TYPE artifactType)const{
-    stringstream condition;
-    condition << " WHERE obj_id = " << file_id << " AND artifact_type_id = " << artifactType;
-    return IMGDB().getMatchingArtifacts(condition.str());
-}
-
-vector<TskBlackboardArtifact> TskDBBlackboard::getArtifacts(TSK_ARTIFACT_TYPE artifactType)const{
-    stringstream condition;
-    condition << " WHERE artifact_type_id = " << artifactType;
-    return IMGDB().getMatchingArtifacts(condition.str());
-}
-
-vector<TskBlackboardArtifact> TskDBBlackboard::getMatchingArtifacts(const string& condition)const{
-    return IMGDB().getMatchingArtifacts(condition);
-}
-
-vector<TskBlackboardAttribute> TskDBBlackboard::getAttributes(const uint64_t file_id, const string& attributeTypeName)const{
-    stringstream condition;
-    condition << " WHERE obj_id = " << file_id << " AND attribute_type_id = " << attrTypeNameToTypeID(attributeTypeName);
-    return IMGDB().getMatchingAttributes(condition.str());
-}
-vector<TskBlackboardAttribute> TskDBBlackboard::getAttributes(const uint64_t file_id, int attributeTypeID)const{
-    stringstream condition;
-    condition << " WHERE obj_id = " << file_id << " AND attribute_type_id = " << attributeTypeID;
-    return IMGDB().getMatchingAttributes(condition.str());
-}
-vector<TskBlackboardAttribute> TskDBBlackboard::getAttributes(const uint64_t file_id, TSK_ATTRIBUTE_TYPE attributeType)const{
-    stringstream condition;
-    condition << " WHERE obj_id = " << file_id << " AND attribute_type_id = " << attributeType;
-    return IMGDB().getMatchingAttributes(condition.str());
-}
-vector<TskBlackboardAttribute> TskDBBlackboard::getAttributes(const TSK_ATTRIBUTE_TYPE attributeType)const{
-    stringstream condition;
-    condition << " WHERE attribute_type_id = " << attributeType;
-    return IMGDB().getMatchingAttributes(condition.str());
-}
-
-vector<TskBlackboardAttribute> TskDBBlackboard::getMatchingAttributes(const string& condition)const{
-    return IMGDB().getMatchingAttributes(condition);
-
-}
-
-TskBlackboardArtifact TskDBBlackboard::createArtifact(const uint64_t file_id, const int artifactTypeID){
-    if(artTypeIDToTypeName(artifactTypeID).compare("") != 0)
-        return IMGDB().createBlackboardArtifact(file_id, artifactTypeID);
-    else
-        throw new TskException("No Artifact type exists with that ID");
-}
-
-TskBlackboardArtifact TskDBBlackboard::createArtifact(const uint64_t file_id, const TSK_ARTIFACT_TYPE artifactType){
-    if(artTypeIDToTypeName(artifactType).compare("") != 0)
-        return IMGDB().createBlackboardArtifact(file_id, artifactType);
-    else
-        throw new TskException("No Artifact type exists with that name");
-}
-
-TskBlackboardArtifact TskDBBlackboard::createArtifact(const uint64_t file_id, const string& artifactTypeName){
-    if(artTypeNameToTypeID(artifactTypeName))
-        return IMGDB().createBlackboardArtifact(file_id, attrTypeNameToTypeID(artifactTypeName));
-    else
-        throw new TskException("Artifact type does not exist. Bad enum value.");
-}
-
-void TskDBBlackboard::createGenInfoAttribute(const uint64_t file_id, TskBlackboardAttribute& attr){
-    TskFile *file = TskFileManagerImpl::instance().getFile(file_id);
-    file->addGenInfoAttribute(attr);
-    delete file;
-}
-
-vector<int> TskDBBlackboard::findAttributeTypes(int artifactTypeId){
-    return IMGDB().findAttributeTypes(artifactTypeId);
-}
+/*
+ * 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 "TskDBBlackboard.h"
+#include "tsk/framework/services/TskImgDB.h"
+#include "tsk/framework/services/TskServices.h"
+#include "tsk/framework/file/TskFileTsk.h"
+#include "tsk/framework/file/TskFile.h"
+#include "tsk/framework/file/TskFileManagerImpl.h"
+
+TskDBBlackboard * TskDBBlackboard::m_pInstance = NULL;
+
+#define IMGDB() (TskServices::Instance().getImgDB())
+
+TskDBBlackboard& TskDBBlackboard::instance()
+{
+    if (!m_pInstance)
+    {
+        m_pInstance = new TskDBBlackboard();
+    }
+    return *m_pInstance;
+}
+
+int TskDBBlackboard::addArtifactType(const string& artifactTypeName, const string& displayName){
+    try{
+        return TskBlackboard::artTypeNameToTypeID(artifactTypeName);
+    }
+    catch(TskException e){
+        try{
+            return IMGDB().getArtifactTypeID(artifactTypeName);
+        }
+        catch(TskException e){
+            int id = TskBlackboard::addArtifactType(artifactTypeName, displayName);
+            IMGDB().addArtifactType(id, artifactTypeName, displayName);
+            return id;
+        }
+    }
+}
+
+int TskDBBlackboard::addAttributeType(const string& attributeTypeName, const string& displayName){
+    try{
+        return TskBlackboard::attrTypeNameToTypeID(attributeTypeName);
+    }
+    catch(TskException e){
+        try{
+            return IMGDB().getAttributeTypeID(attributeTypeName);
+        }
+        catch(TskException e){
+            int id = TskBlackboard::addAttributeType(attributeTypeName, displayName);
+            IMGDB().addAttributeType(id, attributeTypeName, displayName);
+            return id;
+        }
+    }
+}
+
+void TskDBBlackboard::addBlackboardAttribute(TskBlackboardAttribute& attr){
+    if(attrTypeIDToTypeName(attr.getAttributeTypeID()).compare("") != 0)
+        IMGDB().addBlackboardAttribute(attr);
+    else
+        throw new TskException("No attribute type for the id of the given attribute");
+}
+
+string TskDBBlackboard::attrTypeIDToTypeDisplayName(const int attributeTypeID){
+    try{
+        return TskBlackboard::attrTypeIDToTypeDisplayName(attributeTypeID);
+    }
+    catch(TskException e){
+        return IMGDB().getAttributeTypeDisplayName(attributeTypeID);
+    }
+}
+
+int TskDBBlackboard::attrTypeNameToTypeID(const string& attributeTypeString){
+    try{
+        return TskBlackboard::attrTypeNameToTypeID(attributeTypeString);
+    }
+    catch(TskException e){
+        return IMGDB().getAttributeTypeID(attributeTypeString);
+    } 
+}
+
+string TskDBBlackboard::attrTypeIDToTypeName(const int attributeTypeID){
+    try{
+    return TskBlackboard::attrTypeIDToTypeName(attributeTypeID);
+    }
+    catch(TskException e){
+        return IMGDB().getAttributeTypeName(attributeTypeID);
+    }
+}
+
+string TskDBBlackboard::artTypeIDToDisplayName(const int artifactTypeID){
+    try{
+    return TskBlackboard::artTypeIDToDisplayName(artifactTypeID);}
+    catch(TskException e){
+        return IMGDB().getArtifactTypeDisplayName(artifactTypeID);
+    }
+}
+
+int TskDBBlackboard::artTypeNameToTypeID(const string& artifactTypeString){
+    try{
+    return TskBlackboard::artTypeNameToTypeID(artifactTypeString);}
+    catch(TskException e){
+        return IMGDB().getArtifactTypeID(artifactTypeString);
+    }
+}
+string TskDBBlackboard::artTypeIDToTypeName(const int artifactTypeID){
+    try{
+    return TskBlackboard::artTypeIDToTypeName(artifactTypeID);}
+    catch(TskException e){
+        return IMGDB().getArtifactTypeName(artifactTypeID);
+    }
+}
+
+TskBlackboardArtifact TskDBBlackboard::getBlackboardArtifact(const long artifactID){
+    stringstream condition;
+    condition << " WHERE artifact_id = " << artifactID;
+    return IMGDB().getMatchingArtifacts(condition.str())[0];
+}
+
+vector<TskBlackboardArtifact> TskDBBlackboard::getArtifacts(const uint64_t file_id, const string& artifactTypeName)const{
+    stringstream condition;
+    condition << " WHERE obj_id = " << file_id << " AND artifact_type_id = " << attrTypeNameToTypeID(artifactTypeName);
+    return IMGDB().getMatchingArtifacts(condition.str());
+}
+
+vector<TskBlackboardArtifact> TskDBBlackboard::getArtifacts(const uint64_t file_id, int artifactTypeID)const{
+    stringstream condition;
+    condition << " WHERE obj_id = " << file_id << " AND artifact_type_id = " << artifactTypeID;
+    return IMGDB().getMatchingArtifacts(condition.str());
+}
+
+vector<TskBlackboardArtifact> TskDBBlackboard::getArtifacts(const uint64_t file_id, TSK_ARTIFACT_TYPE artifactType)const{
+    stringstream condition;
+    condition << " WHERE obj_id = " << file_id << " AND artifact_type_id = " << artifactType;
+    return IMGDB().getMatchingArtifacts(condition.str());
+}
+
+vector<TskBlackboardArtifact> TskDBBlackboard::getArtifacts(TSK_ARTIFACT_TYPE artifactType)const{
+    stringstream condition;
+    condition << " WHERE artifact_type_id = " << artifactType;
+    return IMGDB().getMatchingArtifacts(condition.str());
+}
+
+vector<TskBlackboardArtifact> TskDBBlackboard::getMatchingArtifacts(const string& condition)const{
+    return IMGDB().getMatchingArtifacts(condition);
+}
+
+vector<TskBlackboardAttribute> TskDBBlackboard::getAttributes(const uint64_t file_id, const string& attributeTypeName)const{
+    stringstream condition;
+    condition << " WHERE obj_id = " << file_id << " AND attribute_type_id = " << attrTypeNameToTypeID(attributeTypeName);
+    return IMGDB().getMatchingAttributes(condition.str());
+}
+vector<TskBlackboardAttribute> TskDBBlackboard::getAttributes(const uint64_t file_id, int attributeTypeID)const{
+    stringstream condition;
+    condition << " WHERE obj_id = " << file_id << " AND attribute_type_id = " << attributeTypeID;
+    return IMGDB().getMatchingAttributes(condition.str());
+}
+vector<TskBlackboardAttribute> TskDBBlackboard::getAttributes(const uint64_t file_id, TSK_ATTRIBUTE_TYPE attributeType)const{
+    stringstream condition;
+    condition << " WHERE obj_id = " << file_id << " AND attribute_type_id = " << attributeType;
+    return IMGDB().getMatchingAttributes(condition.str());
+}
+vector<TskBlackboardAttribute> TskDBBlackboard::getAttributes(const TSK_ATTRIBUTE_TYPE attributeType)const{
+    stringstream condition;
+    condition << " WHERE attribute_type_id = " << attributeType;
+    return IMGDB().getMatchingAttributes(condition.str());
+}
+
+vector<TskBlackboardAttribute> TskDBBlackboard::getMatchingAttributes(const string& condition)const{
+    return IMGDB().getMatchingAttributes(condition);
+
+}
+
+TskBlackboardArtifact TskDBBlackboard::createArtifact(const uint64_t file_id, const int artifactTypeID){
+    if(artTypeIDToTypeName(artifactTypeID).compare("") != 0)
+        return IMGDB().createBlackboardArtifact(file_id, artifactTypeID);
+    else
+        throw new TskException("No Artifact type exists with that ID");
+}
+
+TskBlackboardArtifact TskDBBlackboard::createArtifact(const uint64_t file_id, const TSK_ARTIFACT_TYPE artifactType){
+    if(artTypeIDToTypeName(artifactType).compare("") != 0)
+        return IMGDB().createBlackboardArtifact(file_id, artifactType);
+    else
+        throw new TskException("No Artifact type exists with that name");
+}
+
+TskBlackboardArtifact TskDBBlackboard::createArtifact(const uint64_t file_id, const string& artifactTypeName){
+    if(artTypeNameToTypeID(artifactTypeName))
+        return IMGDB().createBlackboardArtifact(file_id, attrTypeNameToTypeID(artifactTypeName));
+    else
+        throw new TskException("Artifact type does not exist. Bad enum value.");
+}
+
+void TskDBBlackboard::createGenInfoAttribute(const uint64_t file_id, TskBlackboardAttribute& attr){
+    TskFile *file = TskFileManagerImpl::instance().getFile(file_id);
+    file->addGenInfoAttribute(attr);
+    delete file;
+}
+
+vector<int> TskDBBlackboard::findAttributeTypes(int artifactTypeId){
+    return IMGDB().findAttributeTypes(artifactTypeId);
+}
diff --git a/framework/tsk/framework/services/TskDBBlackboard.h b/framework/tsk/framework/services/TskDBBlackboard.h
index 47d3ca7..ed99a63 100755
--- a/framework/tsk/framework/services/TskDBBlackboard.h
+++ b/framework/tsk/framework/services/TskDBBlackboard.h
@@ -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 TskDBBlackboard.h
-* Contains the definition for the TskDBBlackboard class.
-*/
-
-#ifndef _TSK_DB_BLACKBOARD_H
-#define _TSK_DB_BLACKBOARD_H
-
-#include <string>
-#include "tsk/framework/utilities/TskException.h"
-#include "tsk/framework/services/TskBlackboard.h"
-#include "tsk/framework/services/TskImgDB.h"
-#include "tsk/framework/services/TskServices.h"
-#include "TskBlackboardArtifact.h"
-#include "TskBlackboardAttribute.h"
-
-
-/**
-* An implementation of TskBlackboard that stores the name / value pairs
-* in the TskImgDB. 
-*/
-class TSK_FRAMEWORK_API TskDBBlackboard : public TskBlackboard
-{
-public:
-    // Singleton access
-    static TskDBBlackboard& instance();
-
-    virtual TskBlackboardArtifact getBlackboardArtifact(const long artifactID);
-
-    virtual vector<TskBlackboardArtifact> getMatchingArtifacts(const string& condition)const;
-    virtual vector<TskBlackboardArtifact> getArtifacts(const uint64_t file_id, const string& artifactTypeName)const;
-    virtual vector<TskBlackboardArtifact> getArtifacts(const uint64_t file_id, int artifactTypeID)const;
-    virtual vector<TskBlackboardArtifact> getArtifacts(const uint64_t file_id, TSK_ARTIFACT_TYPE artifactType)const;
-    virtual vector<TskBlackboardArtifact> getArtifacts(const TSK_ARTIFACT_TYPE artifactType)const;
-
-    virtual vector<TskBlackboardAttribute> getMatchingAttributes(const string& condition)const;   
-    virtual vector<TskBlackboardAttribute> getAttributes(const uint64_t file_id, const string& attributeTypeName)const;
-    virtual vector<TskBlackboardAttribute> getAttributes(const uint64_t file_id, int attributeTypeID)const;
-    virtual vector<TskBlackboardAttribute> getAttributes(const uint64_t file_id, TSK_ATTRIBUTE_TYPE attributeType)const;
-    virtual vector<TskBlackboardAttribute> getAttributes(const TSK_ATTRIBUTE_TYPE attributeType)const;
-
-
-    virtual TskBlackboardArtifact createArtifact(const uint64_t file_id, const int artifactTypeID);
-    virtual TskBlackboardArtifact createArtifact(const uint64_t file_id, const TSK_ARTIFACT_TYPE artifactType);
-    virtual TskBlackboardArtifact createArtifact(const uint64_t file_id, const string& artifactTypeName);
-
-    virtual void createGenInfoAttribute(const uint64_t file_id, TskBlackboardAttribute& attr);
-
-
-    static string attrTypeIDToTypeDisplayName(const int attributeTypeID);
-    static int attrTypeNameToTypeID(const string& attributeTypeString);
-    static string attrTypeIDToTypeName(const int attributeTypeID);
-
-    static int addAttributeType(const string& attributeTypeName, const string& displayName);
-
-    static string artTypeIDToDisplayName(const int artifactTypeID);
-    static int artTypeNameToTypeID(const string& artifactTypeString);
-    static string artTypeIDToTypeName(const int artifactTypeID);
-
-    static int addArtifactType(const string& artifactTypeName, const string& displayName);
-
-    virtual vector<int> findAttributeTypes(int artifactTypeId);
-
-    friend class TskBlackboardArtifact;
-
-protected:
-    virtual void addBlackboardAttribute(TskBlackboardAttribute& attr);
-    // Default Constructor
-    TskDBBlackboard() { 
-        m_pImgDB = &(TskServices::Instance().getImgDB()); 
-    };
-
-    // Copy Constructor
-    TskDBBlackboard(TskDBBlackboard const&) {};
-
-    // Assignment operator
-    TskDBBlackboard& operator=(TskDBBlackboard const&) { return *m_pInstance; };
-
-    // Destructor
-    virtual ~TskDBBlackboard() {};
-
-    // Our one and only instance
-    static TskDBBlackboard * m_pInstance;
-
-    TskImgDB * m_pImgDB;
-
-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 TskDBBlackboard.h
+* Contains the definition for the TskDBBlackboard class.
+*/
+
+#ifndef _TSK_DB_BLACKBOARD_H
+#define _TSK_DB_BLACKBOARD_H
+
+#include <string>
+#include "tsk/framework/utilities/TskException.h"
+#include "tsk/framework/services/TskBlackboard.h"
+#include "tsk/framework/services/TskImgDB.h"
+#include "tsk/framework/services/TskServices.h"
+#include "TskBlackboardArtifact.h"
+#include "TskBlackboardAttribute.h"
+
+
+/**
+* An implementation of TskBlackboard that stores the name / value pairs
+* in the TskImgDB. 
+*/
+class TSK_FRAMEWORK_API TskDBBlackboard : public TskBlackboard
+{
+public:
+    // Singleton access
+    static TskDBBlackboard& instance();
+
+    virtual TskBlackboardArtifact getBlackboardArtifact(const long artifactID);
+
+    virtual vector<TskBlackboardArtifact> getMatchingArtifacts(const string& condition)const;
+    virtual vector<TskBlackboardArtifact> getArtifacts(const uint64_t file_id, const string& artifactTypeName)const;
+    virtual vector<TskBlackboardArtifact> getArtifacts(const uint64_t file_id, int artifactTypeID)const;
+    virtual vector<TskBlackboardArtifact> getArtifacts(const uint64_t file_id, TSK_ARTIFACT_TYPE artifactType)const;
+    virtual vector<TskBlackboardArtifact> getArtifacts(const TSK_ARTIFACT_TYPE artifactType)const;
+
+    virtual vector<TskBlackboardAttribute> getMatchingAttributes(const string& condition)const;   
+    virtual vector<TskBlackboardAttribute> getAttributes(const uint64_t file_id, const string& attributeTypeName)const;
+    virtual vector<TskBlackboardAttribute> getAttributes(const uint64_t file_id, int attributeTypeID)const;
+    virtual vector<TskBlackboardAttribute> getAttributes(const uint64_t file_id, TSK_ATTRIBUTE_TYPE attributeType)const;
+    virtual vector<TskBlackboardAttribute> getAttributes(const TSK_ATTRIBUTE_TYPE attributeType)const;
+
+
+    virtual TskBlackboardArtifact createArtifact(const uint64_t file_id, const int artifactTypeID);
+    virtual TskBlackboardArtifact createArtifact(const uint64_t file_id, const TSK_ARTIFACT_TYPE artifactType);
+    virtual TskBlackboardArtifact createArtifact(const uint64_t file_id, const string& artifactTypeName);
+
+    virtual void createGenInfoAttribute(const uint64_t file_id, TskBlackboardAttribute& attr);
+
+
+    static string attrTypeIDToTypeDisplayName(const int attributeTypeID);
+    static int attrTypeNameToTypeID(const string& attributeTypeString);
+    static string attrTypeIDToTypeName(const int attributeTypeID);
+
+    static int addAttributeType(const string& attributeTypeName, const string& displayName);
+
+    static string artTypeIDToDisplayName(const int artifactTypeID);
+    static int artTypeNameToTypeID(const string& artifactTypeString);
+    static string artTypeIDToTypeName(const int artifactTypeID);
+
+    static int addArtifactType(const string& artifactTypeName, const string& displayName);
+
+    virtual vector<int> findAttributeTypes(int artifactTypeId);
+
+    friend class TskBlackboardArtifact;
+
+protected:
+    virtual void addBlackboardAttribute(TskBlackboardAttribute& attr);
+    // Default Constructor
+    TskDBBlackboard() { 
+        m_pImgDB = &(TskServices::Instance().getImgDB()); 
+    };
+
+    // Copy Constructor
+    TskDBBlackboard(TskDBBlackboard const&) {};
+
+    // Assignment operator
+    TskDBBlackboard& operator=(TskDBBlackboard const&) { return *m_pInstance; };
+
+    // Destructor
+    virtual ~TskDBBlackboard() {};
+
+    // Our one and only instance
+    static TskDBBlackboard * m_pInstance;
+
+    TskImgDB * m_pImgDB;
+
+private: 
+
+};
+#endif
diff --git a/framework/tsk/framework/services/TskImgDB.cpp b/framework/tsk/framework/services/TskImgDB.cpp
index 3b811cf..d53eed1 100755
--- a/framework/tsk/framework/services/TskImgDB.cpp
+++ b/framework/tsk/framework/services/TskImgDB.cpp
@@ -1,74 +1,73 @@
-/*
- * 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 TskImgDB.cpp
- * Some common defines used by the framework data model.
- */
-
-#include "TskImgDB.h"
-
-/// Default constructor
-TskImgDB::TskImgDB()
-{
-}
-
-/// Destructor
-TskImgDB::~TskImgDB()
-{
-}
-
-/**
- * Store meta_addr to object id mapping of the directory in a local cache map
- * @param fsObjId fs id of this directory
- * @param meta_addr meta_addr of this directory
- * @param objId object id of this directory from the objects table
- */
-void TskImgDB::storeParObjId(const int64_t & fsObjId, const TSK_INUM_T & meta_addr, const int64_t & objId) {
-	map<TSK_INUM_T,int64_t> &tmpMap = m_parentDirIdCache[fsObjId];
-	//store only if does not exist
-	if (tmpMap.count(meta_addr) == 0)
-		tmpMap[meta_addr] = objId;
-}
-
-/**
- * Find parent object id of TSK_FS_FILE. Use local cache map, if not found, fall back to SQL
- * @param fsObjId fs id of this file
- * @param meta_addr Meta address to find parent obj id for
- * @returns parent obj id ( > 0), -1 on error
- */
-int64_t TskImgDB::findParObjId(const int64_t & fsObjId, TSK_INUM_T meta_addr) {
-    //get from cache by parent meta addr, if available
-    map<TSK_INUM_T,int64_t> &tmpMap = m_parentDirIdCache[fsObjId];
-    if (tmpMap.count(meta_addr) > 0) {
-        return tmpMap[meta_addr];
-    }
-
-    return getFileId(fsObjId, meta_addr);
-}
-
-TskBlackboardAttribute TskImgDB::createAttribute(uint64_t artifactID, int attributeTypeID, uint64_t objectID, string moduleName, string context,
-		TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE valueType, int valueInt, uint64_t valueLong, double valueDouble, 
-        string valueString, vector<unsigned char> valueBytes){
-
-    return TskBlackboardAttribute(artifactID, attributeTypeID, objectID, moduleName, context,
-		valueType, valueInt, valueLong, valueDouble, valueString, valueBytes);
-}
-TskBlackboardArtifact TskImgDB::createArtifact(uint64_t artifactID, uint64_t objID, int artifactTypeID){
-    return TskBlackboardArtifact(artifactID, objID, artifactTypeID);
-}
-
-map<int, TskArtifactNames> TskImgDB::getAllArtifactTypes(){
-    return TskBlackboard::getAllArtifactTypes();
-}
-
-map<int, TskAttributeNames> TskImgDB::getAllAttributeTypes(){
-    return TskBlackboard::getAllAttributeTypes();
-}
+/*
+ * 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 TskImgDB.cpp
+ * Some common defines used by the framework data model.
+ */
+
+#include "TskImgDB.h"
+
+/// Default constructor
+TskImgDB::TskImgDB()
+{
+}
+
+/// Destructor
+TskImgDB::~TskImgDB()
+{
+}
+
+void TskImgDB::storeParObjId(const int64_t & fsObjId, const TSK_FS_FILE * fs_file, const int64_t & objId) {
+    map<TSK_INUM_T, map<uint32_t, int64_t> > &fsMap = m_parentDirIdCache[fsObjId];
+    //store only if does not exist -- otherwise '..' and '.' entries will overwrite
+    if (fsMap.count(fs_file->name->meta_addr) == 0) {
+        fsMap[fs_file->name->meta_addr][fs_file->name->meta_seq] = objId;
+    }
+    else {
+        map<uint32_t, int64_t> &fileMap = fsMap[fs_file->name->meta_addr];
+        if (fileMap.count(fs_file->name->meta_seq) == 0) {
+            fileMap[fs_file->name->meta_seq] = objId;
+        }
+    }
+}
+
+int64_t TskImgDB::findParObjId(const TSK_FS_FILE * fs_file, const int64_t & fsObjId) {
+    //get from cache by parent meta addr, if available
+    map<TSK_INUM_T, map<uint32_t, int64_t> > &fsMap = m_parentDirIdCache[fsObjId];
+    if (fsMap.count(fs_file->name->par_addr) > 0) {
+        map<uint32_t, int64_t> &fileMap = fsMap[fs_file->name->par_addr];
+        if (fileMap.count(fs_file->name->par_seq) > 0) {
+            return fileMap[fs_file->name->par_seq];
+        }
+    }
+
+
+    return getFileId(fsObjId, fs_file->name->par_addr);
+}
+
+TskBlackboardAttribute TskImgDB::createAttribute(uint64_t artifactID, int attributeTypeID, uint64_t objectID, string moduleName, string context,
+		TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE valueType, int valueInt, uint64_t valueLong, double valueDouble, 
+        string valueString, vector<unsigned char> valueBytes){
+
+    return TskBlackboardAttribute(artifactID, attributeTypeID, objectID, moduleName, context,
+		valueType, valueInt, valueLong, valueDouble, valueString, valueBytes);
+}
+TskBlackboardArtifact TskImgDB::createArtifact(uint64_t artifactID, uint64_t objID, int artifactTypeID){
+    return TskBlackboardArtifact(artifactID, objID, artifactTypeID);
+}
+
+map<int, TskArtifactNames> TskImgDB::getAllArtifactTypes(){
+    return TskBlackboard::getAllArtifactTypes();
+}
+
+map<int, TskAttributeNames> TskImgDB::getAllAttributeTypes(){
+    return TskBlackboard::getAllAttributeTypes();
+}
diff --git a/framework/tsk/framework/services/TskImgDB.h b/framework/tsk/framework/services/TskImgDB.h
index 3f4f922..a9defe0 100755
--- a/framework/tsk/framework/services/TskImgDB.h
+++ b/framework/tsk/framework/services/TskImgDB.h
@@ -1,541 +1,541 @@
-/*
- *
- *  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_IMGDB_H
-#define _TSK_IMGDB_H
-
-#define IMGDB_SCHEMA_VERSION "1.5"
-
-#include <string> // to get std::wstring
-#include <list>
-#include <vector>
-#include "tsk/libtsk.h"
-#include "tsk/framework/framework_i.h"
-#include "tsk/framework/utilities/SectorRuns.h"
-#include "tsk/framework/utilities/UnallocRun.h"
-#include "TskBlackboardAttribute.h"
-#include "TskBlackboard.h"
-#include "TskBlackboardArtifact.h"
-
-using namespace std;
-
-class TskArtifactNames;
-class TskAttributeNames;
-
-typedef uint64_t artifact_t;
-
-
-/**
- * Contains data from a volume/partition record in the database.
- */
-struct TskVolumeInfoRecord
-{
-    uint64_t vol_id;
-    TSK_DADDR_T sect_start;
-    TSK_DADDR_T sect_len;
-    std::string description;
-    TSK_VS_PART_FLAG_ENUM flags;
-};
-
-/**
- * Contains data from a file system record in the database.
- */
-struct TskFsInfoRecord
-{
-    uint64_t fs_id;
-    TSK_OFF_T img_byte_offset;
-    uint64_t vol_id;
-    TSK_FS_TYPE_ENUM  fs_type;
-    unsigned int block_size;
-    TSK_DADDR_T block_count;
-    TSK_INUM_T root_inum;
-    TSK_INUM_T first_inum;
-    TSK_INUM_T last_inum;
-};
-
-/**
- * Contains data derived from joining carved file records from multiple tables in the image database.
- */
-struct TskCarvedFileInfo
-{
-    /**
-     * The unique ID of the carved file.
-     */
-    uint64_t fileID;
-
-    /**
-     * A hash of the carved file. The type of the hash is a parameter to the function
-     * that returns objects of this type and is not included in the struct to reduce object size,
-     * since this struct is used to satisfy potentially high-volume data requests.
-     * The hash member may be an empty string if the requested hash is unavailable.
-     */
-    std::string hash;
-
-    /**
-     * A "cfile" name for the carved file of the form: cfile_[vol_id]_[start_sector]_[file_id].[ext].
-     */
-    std::string cFileName;
-};
-
-struct TskFileTypeRecord
-{
-    std::string suffix; // file extension, normalized to lowercase. If no extension, it is an empty string.
-    std::string description; // descript of the file type.
-    uint64_t count; // count of files with this extension.
-};
-
-struct TskModuleStatus;
-struct TskModuleInfo;
-struct TskBlackboardRecord;
-struct TskUnallocImgStatusRecord;
-
-/**
- * Contains data about the mapping of data in the unallocated chunks back
- * to their original location in the disk image.
- */
-struct TskAllocUnallocMapRecord
-{
-    int vol_id;
-    int unalloc_img_id;
-    TSK_DADDR_T unalloc_img_sect_start;
-    TSK_DADDR_T sect_len;
-    TSK_DADDR_T orig_img_sect_start;
-};
-
-/**
- * contains data about the 'unused sectors', which did not have carvable data.
- */
-struct TskUnusedSectorsRecord
-{
-    uint64_t fileId;
-    TSK_DADDR_T sectStart;
-    TSK_DADDR_T sectLen;
-};
-
-struct TskFileRecord;
-
-/**
- * Interface for class that implments database storage for an image.
- * The database will be used to store information about the data
- * being analyzed. 
- * Can be registered with and retrieved from TskServices.
- */
-class TSK_FRAMEWORK_API TskImgDB
-{
-public:
-    /// File type classifications used by the framework
-    enum FILE_TYPES
-    {
-        IMGDB_FILES_TYPE_FS = 0,
-        IMGDB_FILES_TYPE_CARVED,
-        IMGDB_FILES_TYPE_DERIVED,
-        IMGDB_FILES_TYPE_UNUSED
-    };
-
-    /// File analysis statuses used by the framework
-    enum FILE_STATUS
-    {
-        IMGDB_FILES_STATUS_CREATED = 0,
-        IMGDB_FILES_STATUS_READY_FOR_ANALYSIS,
-        IMGDB_FILES_STATUS_ANALYSIS_IN_PROGRESS,
-        IMGDB_FILES_STATUS_ANALYSIS_COMPLETE,
-        IMGDB_FILES_STATUS_ANALYSIS_FAILED,
-        IMGDB_FILES_STATUS_ANALYSIS_SKIPPED
-    };
-
-    /**
-     * Files have a 'known' status that is updated
-     * with the use of hash databases. */
-    enum KNOWN_STATUS
-    {
-        IMGDB_FILES_KNOWN = 0,  ///< 'Known', but cannot differentiate between good or bad.  NSRL, for example, identifies known, but does not assign a good or bad status. 
-        IMGDB_FILES_KNOWN_GOOD,  ///< Known to be good / safely ignorable.
-        IMGDB_FILES_KNOWN_BAD,  ///< Known to be bad or notable
-        IMGDB_FILES_UNKNOWN     ///< Unknown files.  Perhaps because they haven't been analyzed yet or perhaps because they are user files that are not in a database.  All files start off in this state. 
-    };
-
-    /// Hash types supported by framework
-    enum HASH_TYPE 
-    {
-        MD5 = 0,    ///< 128-bit MD5
-        SHA1,       ///< 160-bit SHA1
-        SHA2_256,   ///< 256-bit SHA2
-        SHA2_512    ///< 512-bit SHA2
-    };
-
-    /// Data types that can be stored in blackboard
-    enum VALUE_TYPE
-    {
-        BB_VALUE_TYPE_BYTE = 0, ///< Single byte
-        BB_VALUE_TYPE_STRING,   ///< String 
-        BB_VALUE_TYPE_INT32,    ///< 32-bit integer
-        BB_VALUE_TYPE_INT64,    ///< 64-bit integer
-        BB_VALUE_TYPE_DOUBLE    ///< double floating point
-    };
-
-    /// Unallocated sectors file statuses used by the framework
-    enum UNALLOC_IMG_STATUS
-    {
-        IMGDB_UNALLOC_IMG_STATUS_CREATED = 0,
-        IMGDB_UNALLOC_IMG_STATUS_SCHEDULE_OK,
-        IMGDB_UNALLOC_IMG_STATUS_SCHEDULE_ERR,
-        IMGDB_UNALLOC_IMG_STATUS_CARVED_OK,
-        IMGDB_UNALLOC_IMG_STATUS_CARVED_ERR,
-        IMGDB_UNALLOC_IMG_STATUS_CARVED_NOT_NEEDED,
-    };
-
-    TskImgDB();
-    virtual ~ TskImgDB();
-
-    /**
-     * Opens the database and creates the needed tables.
-     * @returns 1 on error and 0 on success.
-     */
-    virtual int initialize() = 0;
-
-    /**
-     * Opens an existing database. Use initialize() to create
-     * a new one.
-     * @returns 1 on error and 0 on success.
-     */
-    virtual int open() = 0;
-
-    /**
-     * Close the database.
-     * @returns 0 on success and 1 on failure.
-     */
-    virtual int close() = 0;
-
-    virtual int begin() = 0;
-    virtual int commit() = 0;
-
-    virtual int addToolInfo(const char* name, const char* version) = 0;
-    virtual int addImageInfo(int type, int sectorSize) = 0;
-
-    /**
-     * Add the path to the image to the image database
-     *
-     * @param imgPath The image path.
-     */    
-    virtual int addImageName(char const * imgPath) = 0;
-    
-    virtual int addVolumeInfo(const TSK_VS_PART_INFO * vs_part) = 0;
-    virtual int addFsInfo(int volId, int fsId, const TSK_FS_INFO * fs_info) = 0;
-
-    /**
-     * Add data for a file system file to the image database.
-     * @param fileSystemID File system ID of the file system the file belongs to
-     * @param fileSystemFile TSK_FS_FILE object for the file
-     * @param fileName File name
-     * @param fileSystemAttrType File system attribute type (see #TSK_FS_ATTR_TYPE_ENUM)
-     * @param fileSystemAttrID File system attribute ID, used to index attributes for files with multiple attributes 
-     * @param [out] fileID File ID assigned to the file by the image database
-     * @param filePath Path to the file in the image, file name omitted
-     * @returns 0 on success or -1 on error.
-     */
-    virtual int addFsFileInfo(int fileSystemID, const TSK_FS_FILE *fileSystemFile, const char *fileName, int fileSystemAttrType, int fileSystemAttrID, uint64_t &fileID, const char *filePath) = 0;
-
-    virtual int addCarvedFileInfo(int vol_id, const char *name, uint64_t size, uint64_t *runStarts, uint64_t *runLengths, int numRuns, uint64_t & fileId) = 0;
-    virtual int addDerivedFileInfo(const std::string& name, const uint64_t parentId, 
-                                        const bool isDirectory, const uint64_t size, const std::string& details,
-                                        const int ctime, const int crtime, const int atime, const int mtime, uint64_t & fileId, std::string path) = 0;
-    virtual int addFsBlockInfo(int fsID, uint64_t a_mFileId, int count, uint64_t blk_addr, uint64_t len) = 0;
-
-    /**
-     * Add information about how the unallocated images were created so that we can 
-     later 
-     * map where data was recovered from. This is typically used by CarvePrep and the results are 
-     * used by CarveExtract via getUnallocRun(). 
-     * @param a_volID Volume ID that the data was extracted from.
-     * @param unallocImgID ID of the unallocated image that the sectors were copied into. 
-     * @param unallocImgStart Sector offset of where in the unallocated image that t
-     he run starts.
-     * @param length Number of sectors that are in the run.
-     * @param origImgStart Sector offset in the original image (relative to start of
-        image) where the run starts  
-     * @returns 1 on errror
-     */
-    virtual int addAllocUnallocMapInfo(int a_volID, int unallocImgID, uint64_t unallocImgStart, uint64_t length, uint64_t origImgStart) = 0;
-
-    virtual int getSessionID() const = 0;
-    virtual int getFileIds(char *a_fileName, uint64_t *a_outBuffer, int a_buffSize) const = 0;
-    virtual int getNumFiles() const = 0;
-    virtual int getMaxFileIdReadyForAnalysis(uint64_t a_lastFileId, uint64_t & maxFileId) const = 0;
-    virtual int getMinFileIdReadyForAnalysis(uint64_t & minFileId) const = 0;
-    virtual uint64_t getFileId(int fsId, uint64_t fs_file_id) const = 0;
-
-    /**
-     * Queries the blackboard for raw information about a specific file. 
-     * @param fileId ID of file to lookup
-     * @param fileRecord Location where data should be stored
-     * @returns -1 on error and 0 on success.
-     */
-    virtual int getFileRecord(const uint64_t fileId, TskFileRecord& fileRecord) const = 0;
-    virtual SectorRuns * getFileSectors(uint64_t fileId) const = 0;
-
-    /**
-     * Gets the base name of the image, i.e., the file name of the first image path stored in the database.
-     *
-     * @return The name of the image, possibly the empty string if no image paths have been stored.
-     */    
-    virtual std::string getImageBaseName() const = 0;
-
-    /**
-     * Gets a list of image paths.
-     *
-     * @returns A vector of image paths as std::strings. There may be multiple paths for a split image or the list may be empty if no image paths have been stored.
-     */
-    virtual std::vector<std::wstring> getImageNamesW() const = 0;
-    virtual std::vector<std::string>  getImageNames() const = 0;
-
-    virtual int getFileUniqueIdentifiers(uint64_t a_fileId, uint64_t &a_fsOffset, uint64_t &a_fsFileId, int &a_attrType, int &a_attrId) const = 0;
-    virtual int getNumVolumes() const = 0;
-    virtual int getImageInfo(int & type, int & sectorSize) const = 0;
-    virtual int getVolumeInfo(std::list<TskVolumeInfoRecord> & volumeInfoList) const = 0;
-    virtual int getFsInfo(std::list<TskFsInfoRecord> & fsInfoList) const = 0;
-    virtual int getFileInfoSummary(std::list<TskFileTypeRecord>& fileTypeInfoList) const = 0;
-    virtual int getFileInfoSummary(FILE_TYPES fileType, std::list<TskFileTypeRecord> & fileTypeInfoList) const = 0;
-    /**
-     * Return the known status of the file with the given id
-     * @param fileId id of the file to get the status of
-     * @returns KNOWN_STATUS or -1 on error
-     */
-    virtual KNOWN_STATUS getKnownStatus(const uint64_t fileId) const = 0;
-    
-
-    /**
-     * Given an offset in an unallocated image that was created for carving, 
-     * return information about where that data came from in the original image.
-     * This is used to map where a carved file is located in the original image.
-     * 
-     * @param a_unalloc_img_id ID of the unallocated image that you want data about
-     * @param a_file_offset Sector offset where file was found in the unallocated image
-     * @return NULL on error or a run descriptor.  
-     */
-    virtual UnallocRun * getUnallocRun(int a_unalloc_img_id, int a_file_offset) const = 0; 
-
-    /**
-     * Returns a list of the sectors that are not used by files and that
-     * are in unpartitioned space.  Typically this is used by CarvePrep.
-     */
-    virtual SectorRuns * getFreeSectors() const = 0;
-
-    /**
-     * update the status field in the database for a given file.
-     * @param a_file_id File to update.
-     * @param a_status Status flag to update to.
-     * @returns 1 on error.
-     */
-    virtual int updateFileStatus(uint64_t a_file_id, FILE_STATUS a_status) = 0;
-
-    /**
-     * update the known status field in the database for a given file.
-     * @param a_file_id File to update.
-     * @param a_status Status flag to update to.
-     * @returns 1 on error.
-     */
-    virtual int updateKnownStatus(uint64_t a_file_id, KNOWN_STATUS a_status) = 0;
-	virtual bool dbExist() const = 0;
-
-    // Get set of file ids that match the given condition (i.e. SQL where clause)
-    virtual std::vector<uint64_t> getFileIds(const std::string& condition) const = 0;
-    virtual const std::vector<TskFileRecord> getFileRecords(const std::string& condition) const = 0;
-
-    // Get the number of files that match the given condition
-    virtual int getFileCount(const std::string& condition) const = 0;
-
-    /**
-     * Returns the file ids and carved file names for a unique set of carved files.
-     * Uniqueness is based on the value of a particular hash type. Where duplicate
-     * hash values exist, the lowest file_id is chosen.
-     * NOTE: This function is deprecated and will be removed in the next major release,
-     * use the getUniqueCarvedFilesInfo() member function instead.
-     *
-     * @param hashType The type of hash value to use when determining uniqueness.
-     * @return A map of file ids to the corresponding carved file name.
-     */
-    virtual std::map<uint64_t, std::string> getUniqueCarvedFiles(HASH_TYPE hashType) const = 0;
-
-    /**
-     * Returns the file ids, content hashes and, carved file names for a unique set of carved files.
-     * Uniqueness is based on the value of a particular hash type. Where duplicate
-     * hash values exist, the lowest file_id is chosen.
-     *
-     * @param hashType The type of hash value to use when determining uniqueness.
-     * @return A map of file ids to the corresponding carved file name. Throws TskException.
-     */
-    virtual std::vector<TskCarvedFileInfo> getUniqueCarvedFilesInfo(HASH_TYPE hashType) const = 0;
-
-    virtual std::vector<uint64_t> getCarvedFileIds() const = 0;
-
-    virtual std::vector<uint64_t> getUniqueFileIds(HASH_TYPE hashType) const = 0;
-    virtual std::vector<uint64_t> getFileIds() const = 0;
-
-    virtual int setHash(const uint64_t a_file_id, const TskImgDB::HASH_TYPE hashType, const std::string& hash) const = 0;
-    virtual std::string getCfileName(const uint64_t a_file_id) const = 0;
-
-    virtual int addModule(const std::string& name, const std::string& description, int & moduleId) = 0;
-    virtual int setModuleStatus(uint64_t file_id, int module_id, int status) = 0;
-	virtual int getModuleInfo(std::vector<TskModuleInfo> & moduleInfoList) const = 0;
-    virtual int getModuleErrors(std::vector<TskModuleStatus> & moduleStatusList) const = 0;
-    virtual std::string getFileName(uint64_t file_id) const = 0;
-
-    /**
-     * Used when a new unallocated image file is created for carving. 
-     * @param unallocImgId [out] Stores the unique ID assigned to the image.
-     * @returns -1 on error, 0 on success.
-     */
-    virtual int addUnallocImg(int & unallocImgId) = 0;
-
-    virtual int setUnallocImgStatus(int unallocImgId, TskImgDB::UNALLOC_IMG_STATUS status) = 0;
-    virtual TskImgDB::UNALLOC_IMG_STATUS getUnallocImgStatus(int unallocImgId) const = 0;
-    virtual int getAllUnallocImgStatus(std::vector<TskUnallocImgStatusRecord> & unallocImgStatusList) const = 0;
-
-    virtual int addUnusedSectors(int unallocImgId, std::vector<TskUnusedSectorsRecord> & unusedSectorsList) = 0;
-    virtual int getUnusedSector(uint64_t fileId, TskUnusedSectorsRecord & unusedSectorsRecord) const = 0;
-
-	// Quote and escape a string, the returned quoted string can be used as string literal in SQL statement.
-	virtual std::string quote(const std::string str) const = 0;
-
-    friend class TskDBBlackboard;
-
-protected:
-    map<int64_t, map<TSK_INUM_T,int64_t> > m_parentDirIdCache; //maps a file system ID to a map, which maps a directory file system meta address to its parent's ID in the database
-
-	/**
-	 * Store meta_addr to object id mapping of the directory in a local cache map
-	 * @param fsObjId fs id of this directory
-	 * @param meta_addr meta_addr of this directory
-	 * @param objId object id of this directory from the objects table
-	 */
-    void storeParObjId(const int64_t & fsObjId, const TSK_INUM_T & meta_addr, const int64_t & objId);
-
-	/**
-	 * Find parent object id of TSK_FS_FILE. Use local cache map, if not found, fall back to SQL
-	 * @param fsObjId Id of file system that this file and parent should be in.
-	 * @param meta_addr File system address to find parent of
-	 * @returns parent obj id ( > 0), -1 on error
-	 */	
-	int64_t findParObjId(const int64_t & fsObjId, TSK_INUM_T meta_addr);    
-
-	// Blackboard methods.
-    virtual TskBlackboardArtifact createBlackboardArtifact(uint64_t file_id, int artifactTypeID) = 0;
-    virtual void addBlackboardAttribute(TskBlackboardAttribute attr) = 0;
-    
-    virtual string getArtifactTypeDisplayName(int artifactTypeID) = 0;
-    virtual int getArtifactTypeID(string artifactTypeString) = 0;
-    virtual string getArtifactTypeName(int artifactTypeID) = 0;
-    virtual vector<TskBlackboardArtifact> getMatchingArtifacts(string whereClause) = 0;
-
-    virtual void addArtifactType(int typeID, string artifactTypeName, string displayName) = 0;
-    virtual void addAttributeType(int typeID, string attributeTypeName, string displayName)= 0;
-
-    virtual string getAttributeTypeDisplayName(int attributeTypeID) = 0;
-    virtual int getAttributeTypeID(string attributeTypeString) = 0;
-    virtual string getAttributeTypeName(int attributeTypeID) = 0;
-    virtual vector<TskBlackboardAttribute> getMatchingAttributes(string whereClause) = 0;
-    TskBlackboardAttribute createAttribute(uint64_t artifactID, int attributeTypeID, uint64_t objectID, string moduleName, string context,
-		TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE valueType, int valueInt, uint64_t valueLong, double valueDouble, 
-		string valueString, vector<unsigned char> valueBytes);
-    TskBlackboardArtifact createArtifact(uint64_t artifactID, uint64_t objID, int artifactTypeID);
-    virtual map<int, TskArtifactNames> getAllArtifactTypes();
-    virtual map<int, TskAttributeNames> getAllAttributeTypes();
-    virtual vector<int> findAttributeTypes(int artifactTypeId) = 0;
-
-private:
-
-};
-
-/**
- * Contains data from a file record in the database.
- */
-struct TskFileRecord
-{
-    uint64_t fileId;
-    TskImgDB::FILE_TYPES typeId;
-    std::string name;
-    uint64_t parentFileId;
-    TSK_FS_NAME_TYPE_ENUM dirType;
-    TSK_FS_META_TYPE_ENUM metaType;
-    TSK_FS_NAME_FLAG_ENUM dirFlags;
-    TSK_FS_META_FLAG_ENUM metaFlags;
-    TSK_OFF_T size;
-    time_t ctime;
-    time_t crtime;
-    time_t atime;
-    time_t mtime;
-    TSK_FS_META_MODE_ENUM mode;
-    TSK_UID_T uid;
-    TSK_GID_T gid;
-    TskImgDB::FILE_STATUS status;
-    std::string md5;
-    std::string sha1;
-    std::string sha2_256;
-    std::string sha2_512;
-    std::string fullPath;
-};
-
-/**
- * Contains data about the module return status for a given file (as recorded in the database)
- */
-struct TskModuleStatus
-{
-    uint64_t file_id;
-    std::string module_name;
-    int status;
-};
-
-/**
- * Contains data about a module
- */
-struct TskModuleInfo
-{
-	int module_id;
-    std::string module_name;
-    std::string module_description;
-};
-
-/**
- * Contains data for a blackboard entry for a given file and artifact ID
- */
-struct TskBlackboardRecord
-{
-    artifact_t artifactId;
-    uint64_t fileId;    ///< File that this information pertains to.
-    string attribute; ///< Name / type of the data being stored. Standard attribute names are defined in TskBlackboard
-    string source;  ///< Name of the module that added this data
-    string context; ///< Optional string that provides more context about the data.  For example, it may have "Last Printed" if the entry is a DATETIME entry about when a document was last printed.
-    TskImgDB::VALUE_TYPE valueType; ///< Type of data being stored
-    int32_t valueInt32;
-    int64_t valueInt64;
-    string valueString;
-    double valueDouble;
-    vector<unsigned char> valueByte;
-
-    TskBlackboardRecord(artifact_t a_artifactId, uint64_t a_fileId, string a_attribute, string a_source, string a_context)
-        : artifactId(a_artifactId), fileId(a_fileId), attribute(a_attribute), source(a_source), context(a_context)
-    {
-    }
-    TskBlackboardRecord() {}
-};
-
-/**
- * Contains data about the current status for an unallocated chunk of data.
- */
-struct TskUnallocImgStatusRecord
-{
-    int unallocImgId;
-    TskImgDB::UNALLOC_IMG_STATUS status;
-};
-
-
-#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_IMGDB_H
+#define _TSK_IMGDB_H
+
+#define IMGDB_SCHEMA_VERSION "1.5"
+
+#include <string> // to get std::wstring
+#include <list>
+#include <vector>
+#include "tsk/libtsk.h"
+#include "tsk/framework/framework_i.h"
+#include "tsk/framework/utilities/SectorRuns.h"
+#include "tsk/framework/utilities/UnallocRun.h"
+#include "TskBlackboardAttribute.h"
+#include "TskBlackboard.h"
+#include "TskBlackboardArtifact.h"
+
+using namespace std;
+
+class TskArtifactNames;
+class TskAttributeNames;
+
+typedef uint64_t artifact_t;
+
+
+/**
+ * Contains data from a volume/partition record in the database.
+ */
+struct TskVolumeInfoRecord
+{
+    uint64_t vol_id;
+    TSK_DADDR_T sect_start;
+    TSK_DADDR_T sect_len;
+    std::string description;
+    TSK_VS_PART_FLAG_ENUM flags;
+};
+
+/**
+ * Contains data from a file system record in the database.
+ */
+struct TskFsInfoRecord
+{
+    uint64_t fs_id;
+    TSK_OFF_T img_byte_offset;
+    uint64_t vol_id;
+    TSK_FS_TYPE_ENUM  fs_type;
+    unsigned int block_size;
+    TSK_DADDR_T block_count;
+    TSK_INUM_T root_inum;
+    TSK_INUM_T first_inum;
+    TSK_INUM_T last_inum;
+};
+
+/**
+ * Contains data derived from joining carved file records from multiple tables in the image database.
+ */
+struct TskCarvedFileInfo
+{
+    /**
+     * The unique ID of the carved file.
+     */
+    uint64_t fileID;
+
+    /**
+     * A hash of the carved file. The type of the hash is a parameter to the function
+     * that returns objects of this type and is not included in the struct to reduce object size,
+     * since this struct is used to satisfy potentially high-volume data requests.
+     * The hash member may be an empty string if the requested hash is unavailable.
+     */
+    std::string hash;
+
+    /**
+     * A "cfile" name for the carved file of the form: cfile_[vol_id]_[start_sector]_[file_id].[ext].
+     */
+    std::string cFileName;
+};
+
+struct TskFileTypeRecord
+{
+    std::string suffix; // file extension, normalized to lowercase. If no extension, it is an empty string.
+    std::string description; // descript of the file type.
+    uint64_t count; // count of files with this extension.
+};
+
+struct TskModuleStatus;
+struct TskModuleInfo;
+struct TskBlackboardRecord;
+struct TskUnallocImgStatusRecord;
+
+/**
+ * Contains data about the mapping of data in the unallocated chunks back
+ * to their original location in the disk image.
+ */
+struct TskAllocUnallocMapRecord
+{
+    int vol_id;
+    int unalloc_img_id;
+    TSK_DADDR_T unalloc_img_sect_start;
+    TSK_DADDR_T sect_len;
+    TSK_DADDR_T orig_img_sect_start;
+};
+
+/**
+ * contains data about the 'unused sectors', which did not have carvable data.
+ */
+struct TskUnusedSectorsRecord
+{
+    uint64_t fileId;
+    TSK_DADDR_T sectStart;
+    TSK_DADDR_T sectLen;
+};
+
+struct TskFileRecord;
+
+/**
+ * Interface for class that implments database storage for an image.
+ * The database will be used to store information about the data
+ * being analyzed. 
+ * Can be registered with and retrieved from TskServices.
+ */
+class TSK_FRAMEWORK_API TskImgDB
+{
+public:
+    /// File type classifications used by the framework
+    enum FILE_TYPES
+    {
+        IMGDB_FILES_TYPE_FS = 0,
+        IMGDB_FILES_TYPE_CARVED,
+        IMGDB_FILES_TYPE_DERIVED,
+        IMGDB_FILES_TYPE_UNUSED
+    };
+
+    /// File analysis statuses used by the framework
+    enum FILE_STATUS
+    {
+        IMGDB_FILES_STATUS_CREATED = 0,
+        IMGDB_FILES_STATUS_READY_FOR_ANALYSIS,
+        IMGDB_FILES_STATUS_ANALYSIS_IN_PROGRESS,
+        IMGDB_FILES_STATUS_ANALYSIS_COMPLETE,
+        IMGDB_FILES_STATUS_ANALYSIS_FAILED,
+        IMGDB_FILES_STATUS_ANALYSIS_SKIPPED
+    };
+
+    /**
+     * Files have a 'known' status that is updated
+     * with the use of hash databases. */
+    enum KNOWN_STATUS
+    {
+        IMGDB_FILES_KNOWN = 0,  ///< 'Known', but cannot differentiate between good or bad.  NSRL, for example, identifies known, but does not assign a good or bad status. 
+        IMGDB_FILES_KNOWN_GOOD,  ///< Known to be good / safely ignorable.
+        IMGDB_FILES_KNOWN_BAD,  ///< Known to be bad or notable
+        IMGDB_FILES_UNKNOWN     ///< Unknown files.  Perhaps because they haven't been analyzed yet or perhaps because they are user files that are not in a database.  All files start off in this state. 
+    };
+
+    /// Hash types supported by framework
+    enum HASH_TYPE 
+    {
+        MD5 = 0,    ///< 128-bit MD5
+        SHA1,       ///< 160-bit SHA1
+        SHA2_256,   ///< 256-bit SHA2
+        SHA2_512    ///< 512-bit SHA2
+    };
+
+    /// Data types that can be stored in blackboard
+    enum VALUE_TYPE
+    {
+        BB_VALUE_TYPE_BYTE = 0, ///< Single byte
+        BB_VALUE_TYPE_STRING,   ///< String 
+        BB_VALUE_TYPE_INT32,    ///< 32-bit integer
+        BB_VALUE_TYPE_INT64,    ///< 64-bit integer
+        BB_VALUE_TYPE_DOUBLE    ///< double floating point
+    };
+
+    /// Unallocated sectors file statuses used by the framework
+    enum UNALLOC_IMG_STATUS
+    {
+        IMGDB_UNALLOC_IMG_STATUS_CREATED = 0,
+        IMGDB_UNALLOC_IMG_STATUS_SCHEDULE_OK,
+        IMGDB_UNALLOC_IMG_STATUS_SCHEDULE_ERR,
+        IMGDB_UNALLOC_IMG_STATUS_CARVED_OK,
+        IMGDB_UNALLOC_IMG_STATUS_CARVED_ERR,
+        IMGDB_UNALLOC_IMG_STATUS_CARVED_NOT_NEEDED,
+    };
+
+    TskImgDB();
+    virtual ~ TskImgDB();
+
+    /**
+     * Opens the database and creates the needed tables.
+     * @returns 1 on error and 0 on success.
+     */
+    virtual int initialize() = 0;
+
+    /**
+     * Opens an existing database. Use initialize() to create
+     * a new one.
+     * @returns 1 on error and 0 on success.
+     */
+    virtual int open() = 0;
+
+    /**
+     * Close the database.
+     * @returns 0 on success and 1 on failure.
+     */
+    virtual int close() = 0;
+
+    virtual int begin() = 0;
+    virtual int commit() = 0;
+
+    virtual int addToolInfo(const char* name, const char* version) = 0;
+    virtual int addImageInfo(int type, int sectorSize) = 0;
+
+    /**
+     * Add the path to the image to the image database
+     *
+     * @param imgPath The image path.
+     */    
+    virtual int addImageName(char const * imgPath) = 0;
+    
+    virtual int addVolumeInfo(const TSK_VS_PART_INFO * vs_part) = 0;
+    virtual int addFsInfo(int volId, int fsId, const TSK_FS_INFO * fs_info) = 0;
+
+    /**
+     * Add data for a file system file to the image database.
+     * @param fileSystemID File system ID of the file system the file belongs to
+     * @param fileSystemFile TSK_FS_FILE object for the file
+     * @param fileName File name
+     * @param fileSystemAttrType File system attribute type (see #TSK_FS_ATTR_TYPE_ENUM)
+     * @param fileSystemAttrID File system attribute ID, used to index attributes for files with multiple attributes 
+     * @param [out] fileID File ID assigned to the file by the image database
+     * @param filePath Path to the file in the image, file name omitted
+     * @returns 0 on success or -1 on error.
+     */
+    virtual int addFsFileInfo(int fileSystemID, const TSK_FS_FILE *fileSystemFile, const char *fileName, int fileSystemAttrType, int fileSystemAttrID, uint64_t &fileID, const char *filePath) = 0;
+
+    virtual int addCarvedFileInfo(int vol_id, const char *name, uint64_t size, uint64_t *runStarts, uint64_t *runLengths, int numRuns, uint64_t & fileId) = 0;
+    virtual int addDerivedFileInfo(const std::string& name, const uint64_t parentId, 
+                                        const bool isDirectory, const uint64_t size, const std::string& details,
+                                        const int ctime, const int crtime, const int atime, const int mtime, uint64_t & fileId, std::string path) = 0;
+    virtual int addFsBlockInfo(int fsID, uint64_t a_mFileId, int count, uint64_t blk_addr, uint64_t len) = 0;
+
+    /**
+     * Add information about how the unallocated images were created so that we can 
+     later 
+     * map where data was recovered from. This is typically used by CarvePrep and the results are 
+     * used by CarveExtract via getUnallocRun(). 
+     * @param a_volID Volume ID that the data was extracted from.
+     * @param unallocImgID ID of the unallocated image that the sectors were copied into. 
+     * @param unallocImgStart Sector offset of where in the unallocated image that t
+     he run starts.
+     * @param length Number of sectors that are in the run.
+     * @param origImgStart Sector offset in the original image (relative to start of
+        image) where the run starts  
+     * @returns 1 on errror
+     */
+    virtual int addAllocUnallocMapInfo(int a_volID, int unallocImgID, uint64_t unallocImgStart, uint64_t length, uint64_t origImgStart) = 0;
+
+    virtual int getSessionID() const = 0;
+    virtual int getFileIds(char *a_fileName, uint64_t *a_outBuffer, int a_buffSize) const = 0;
+    virtual int getNumFiles() const = 0;
+    virtual int getMaxFileIdReadyForAnalysis(uint64_t a_lastFileId, uint64_t & maxFileId) const = 0;
+    virtual int getMinFileIdReadyForAnalysis(uint64_t & minFileId) const = 0;
+    virtual uint64_t getFileId(int fsId, uint64_t fs_file_id) const = 0;
+
+    /**
+     * Queries the blackboard for raw information about a specific file. 
+     * @param fileId ID of file to lookup
+     * @param fileRecord Location where data should be stored
+     * @returns -1 on error and 0 on success.
+     */
+    virtual int getFileRecord(const uint64_t fileId, TskFileRecord& fileRecord) const = 0;
+    virtual SectorRuns * getFileSectors(uint64_t fileId) const = 0;
+
+    /**
+     * Gets the base name of the image, i.e., the file name of the first image path stored in the database.
+     *
+     * @return The name of the image, possibly the empty string if no image paths have been stored.
+     */    
+    virtual std::string getImageBaseName() const = 0;
+
+    /**
+     * Gets a list of image paths.
+     *
+     * @returns A vector of image paths as std::strings. There may be multiple paths for a split image or the list may be empty if no image paths have been stored.
+     */
+    virtual std::vector<std::wstring> getImageNamesW() const = 0;
+    virtual std::vector<std::string>  getImageNames() const = 0;
+
+    virtual int getFileUniqueIdentifiers(uint64_t a_fileId, uint64_t &a_fsOffset, uint64_t &a_fsFileId, int &a_attrType, int &a_attrId) const = 0;
+    virtual int getNumVolumes() const = 0;
+    virtual int getImageInfo(int & type, int & sectorSize) const = 0;
+    virtual int getVolumeInfo(std::list<TskVolumeInfoRecord> & volumeInfoList) const = 0;
+    virtual int getFsInfo(std::list<TskFsInfoRecord> & fsInfoList) const = 0;
+    virtual int getFileInfoSummary(std::list<TskFileTypeRecord>& fileTypeInfoList) const = 0;
+    virtual int getFileInfoSummary(FILE_TYPES fileType, std::list<TskFileTypeRecord> & fileTypeInfoList) const = 0;
+    /**
+     * Return the known status of the file with the given id
+     * @param fileId id of the file to get the status of
+     * @returns KNOWN_STATUS or -1 on error
+     */
+    virtual KNOWN_STATUS getKnownStatus(const uint64_t fileId) const = 0;
+    
+
+    /**
+     * Given an offset in an unallocated image that was created for carving, 
+     * return information about where that data came from in the original image.
+     * This is used to map where a carved file is located in the original image.
+     * 
+     * @param a_unalloc_img_id ID of the unallocated image that you want data about
+     * @param a_file_offset Sector offset where file was found in the unallocated image
+     * @return NULL on error or a run descriptor.  
+     */
+    virtual UnallocRun * getUnallocRun(int a_unalloc_img_id, int a_file_offset) const = 0; 
+
+    /**
+     * Returns a list of the sectors that are not used by files and that
+     * are in unpartitioned space.  Typically this is used by CarvePrep.
+     */
+    virtual SectorRuns * getFreeSectors() const = 0;
+
+    /**
+     * update the status field in the database for a given file.
+     * @param a_file_id File to update.
+     * @param a_status Status flag to update to.
+     * @returns 1 on error.
+     */
+    virtual int updateFileStatus(uint64_t a_file_id, FILE_STATUS a_status) = 0;
+
+    /**
+     * update the known status field in the database for a given file.
+     * @param a_file_id File to update.
+     * @param a_status Status flag to update to.
+     * @returns 1 on error.
+     */
+    virtual int updateKnownStatus(uint64_t a_file_id, KNOWN_STATUS a_status) = 0;
+	virtual bool dbExist() const = 0;
+
+    // Get set of file ids that match the given condition (i.e. SQL where clause)
+    virtual std::vector<uint64_t> getFileIds(const std::string& condition) const = 0;
+    virtual const std::vector<TskFileRecord> getFileRecords(const std::string& condition) const = 0;
+
+    // Get the number of files that match the given condition
+    virtual int getFileCount(const std::string& condition) const = 0;
+
+    /**
+     * Returns the file ids and carved file names for a unique set of carved files.
+     * Uniqueness is based on the value of a particular hash type. Where duplicate
+     * hash values exist, the lowest file_id is chosen.
+     * NOTE: This function is deprecated and will be removed in the next major release,
+     * use the getUniqueCarvedFilesInfo() member function instead.
+     *
+     * @param hashType The type of hash value to use when determining uniqueness.
+     * @return A map of file ids to the corresponding carved file name.
+     */
+    virtual std::map<uint64_t, std::string> getUniqueCarvedFiles(HASH_TYPE hashType) const = 0;
+
+    /**
+     * Returns the file ids, content hashes and, carved file names for a unique set of carved files.
+     * Uniqueness is based on the value of a particular hash type. Where duplicate
+     * hash values exist, the lowest file_id is chosen.
+     *
+     * @param hashType The type of hash value to use when determining uniqueness.
+     * @return A map of file ids to the corresponding carved file name. Throws TskException.
+     */
+    virtual std::vector<TskCarvedFileInfo> getUniqueCarvedFilesInfo(HASH_TYPE hashType) const = 0;
+
+    virtual std::vector<uint64_t> getCarvedFileIds() const = 0;
+
+    virtual std::vector<uint64_t> getUniqueFileIds(HASH_TYPE hashType) const = 0;
+    virtual std::vector<uint64_t> getFileIds() const = 0;
+
+    virtual int setHash(const uint64_t a_file_id, const TskImgDB::HASH_TYPE hashType, const std::string& hash) const = 0;
+    virtual std::string getCfileName(const uint64_t a_file_id) const = 0;
+
+    virtual int addModule(const std::string& name, const std::string& description, int & moduleId) = 0;
+    virtual int setModuleStatus(uint64_t file_id, int module_id, int status) = 0;
+	virtual int getModuleInfo(std::vector<TskModuleInfo> & moduleInfoList) const = 0;
+    virtual int getModuleErrors(std::vector<TskModuleStatus> & moduleStatusList) const = 0;
+    virtual std::string getFileName(uint64_t file_id) const = 0;
+
+    /**
+     * Used when a new unallocated image file is created for carving. 
+     * @param unallocImgId [out] Stores the unique ID assigned to the image.
+     * @returns -1 on error, 0 on success.
+     */
+    virtual int addUnallocImg(int & unallocImgId) = 0;
+
+    virtual int setUnallocImgStatus(int unallocImgId, TskImgDB::UNALLOC_IMG_STATUS status) = 0;
+    virtual TskImgDB::UNALLOC_IMG_STATUS getUnallocImgStatus(int unallocImgId) const = 0;
+    virtual int getAllUnallocImgStatus(std::vector<TskUnallocImgStatusRecord> & unallocImgStatusList) const = 0;
+
+    virtual int addUnusedSectors(int unallocImgId, std::vector<TskUnusedSectorsRecord> & unusedSectorsList) = 0;
+    virtual int getUnusedSector(uint64_t fileId, TskUnusedSectorsRecord & unusedSectorsRecord) const = 0;
+
+	// Quote and escape a string, the returned quoted string can be used as string literal in SQL statement.
+	virtual std::string quote(const std::string str) const = 0;
+
+    friend class TskDBBlackboard;
+
+protected:
+    map<int64_t, map<TSK_INUM_T, map<uint32_t, int64_t> > > m_parentDirIdCache; //maps a file system ID to a map, which maps a directory file system meta address to a map, which maps a sequence ID to its object ID in the database
+
+    /**
+	 * Store meta_addr to object id mapping of the directory in a local cache map
+	 * @param fsObjId fs id of the directory
+	 * @param fs_file file object for the directory
+	 * @param objId object id of the directory from the objects table
+	 */
+    void storeParObjId(const int64_t & fsObjId, const TSK_FS_FILE * fs_file, const int64_t & objId);
+
+	/**
+	 * Find parent object id of TSK_FS_FILE. Use local cache map, if not found, fall back to SQL
+     * @param fs_file file to find parent obj id for
+     * @param fsObjId fs id of this file
+	 * @returns parent obj id ( > 0), -1 on error
+	 */	
+	int64_t findParObjId(const TSK_FS_FILE * fs_file, const int64_t & fsObjId);    
+
+	// Blackboard methods.
+    virtual TskBlackboardArtifact createBlackboardArtifact(uint64_t file_id, int artifactTypeID) = 0;
+    virtual void addBlackboardAttribute(TskBlackboardAttribute attr) = 0;
+    
+    virtual string getArtifactTypeDisplayName(int artifactTypeID) = 0;
+    virtual int getArtifactTypeID(string artifactTypeString) = 0;
+    virtual string getArtifactTypeName(int artifactTypeID) = 0;
+    virtual vector<TskBlackboardArtifact> getMatchingArtifacts(string whereClause) = 0;
+
+    virtual void addArtifactType(int typeID, string artifactTypeName, string displayName) = 0;
+    virtual void addAttributeType(int typeID, string attributeTypeName, string displayName)= 0;
+
+    virtual string getAttributeTypeDisplayName(int attributeTypeID) = 0;
+    virtual int getAttributeTypeID(string attributeTypeString) = 0;
+    virtual string getAttributeTypeName(int attributeTypeID) = 0;
+    virtual vector<TskBlackboardAttribute> getMatchingAttributes(string whereClause) = 0;
+    TskBlackboardAttribute createAttribute(uint64_t artifactID, int attributeTypeID, uint64_t objectID, string moduleName, string context,
+		TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE valueType, int valueInt, uint64_t valueLong, double valueDouble, 
+		string valueString, vector<unsigned char> valueBytes);
+    TskBlackboardArtifact createArtifact(uint64_t artifactID, uint64_t objID, int artifactTypeID);
+    virtual map<int, TskArtifactNames> getAllArtifactTypes();
+    virtual map<int, TskAttributeNames> getAllAttributeTypes();
+    virtual vector<int> findAttributeTypes(int artifactTypeId) = 0;
+
+private:
+
+};
+
+/**
+ * Contains data from a file record in the database.
+ */
+struct TskFileRecord
+{
+    uint64_t fileId;
+    TskImgDB::FILE_TYPES typeId;
+    std::string name;
+    uint64_t parentFileId;
+    TSK_FS_NAME_TYPE_ENUM dirType;
+    TSK_FS_META_TYPE_ENUM metaType;
+    TSK_FS_NAME_FLAG_ENUM dirFlags;
+    TSK_FS_META_FLAG_ENUM metaFlags;
+    TSK_OFF_T size;
+    time_t ctime;
+    time_t crtime;
+    time_t atime;
+    time_t mtime;
+    TSK_FS_META_MODE_ENUM mode;
+    TSK_UID_T uid;
+    TSK_GID_T gid;
+    TskImgDB::FILE_STATUS status;
+    std::string md5;
+    std::string sha1;
+    std::string sha2_256;
+    std::string sha2_512;
+    std::string fullPath;
+};
+
+/**
+ * Contains data about the module return status for a given file (as recorded in the database)
+ */
+struct TskModuleStatus
+{
+    uint64_t file_id;
+    std::string module_name;
+    int status;
+};
+
+/**
+ * Contains data about a module
+ */
+struct TskModuleInfo
+{
+	int module_id;
+    std::string module_name;
+    std::string module_description;
+};
+
+/**
+ * Contains data for a blackboard entry for a given file and artifact ID
+ */
+struct TskBlackboardRecord
+{
+    artifact_t artifactId;
+    uint64_t fileId;    ///< File that this information pertains to.
+    string attribute; ///< Name / type of the data being stored. Standard attribute names are defined in TskBlackboard
+    string source;  ///< Name of the module that added this data
+    string context; ///< Optional string that provides more context about the data.  For example, it may have "Last Printed" if the entry is a DATETIME entry about when a document was last printed.
+    TskImgDB::VALUE_TYPE valueType; ///< Type of data being stored
+    int32_t valueInt32;
+    int64_t valueInt64;
+    string valueString;
+    double valueDouble;
+    vector<unsigned char> valueByte;
+
+    TskBlackboardRecord(artifact_t a_artifactId, uint64_t a_fileId, string a_attribute, string a_source, string a_context)
+        : artifactId(a_artifactId), fileId(a_fileId), attribute(a_attribute), source(a_source), context(a_context)
+    {
+    }
+    TskBlackboardRecord() {}
+};
+
+/**
+ * Contains data about the current status for an unallocated chunk of data.
+ */
+struct TskUnallocImgStatusRecord
+{
+    int unallocImgId;
+    TskImgDB::UNALLOC_IMG_STATUS status;
+};
+
+
+#endif
diff --git a/framework/tsk/framework/services/TskImDBPostgreSQL.cpp b/framework/tsk/framework/services/TskImgDBPostgreSQL.cpp
similarity index 93%
rename from framework/tsk/framework/services/TskImDBPostgreSQL.cpp
rename to framework/tsk/framework/services/TskImgDBPostgreSQL.cpp
index e635f65..ba2f217 100755
--- a/framework/tsk/framework/services/TskImDBPostgreSQL.cpp
+++ b/framework/tsk/framework/services/TskImgDBPostgreSQL.cpp
@@ -1,3857 +1,3969 @@
-/*
- *
- *  The Sleuth Kit
- *
- *  Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- *  Copyright (c) 2010-2011 Basis Technology Corporation. All Rights
- *  reserved.
- *
- *  This software is distributed under the Common Public License 1.0
- */
-
-/**
- * \file TskImDBPostgreSQL.cpp 
- * A PostgreSQL based implementation of the framework data access layer.
- */
-#include <stdio.h>
-#include <iostream>
-#include <sstream>
-#include <iomanip>
-#include <Lmcons.h>
-#include <assert.h>
-
-#include "Services/TskDBBlackboard.h"
-#include "TskImgDBPostgreSQL.h"
-#include "Services/TskServices.h"
-#include "Utilities/TskException.h"
-#include "Utilities/TskUtilities.h"
-
-#include "Poco/String.h"
-#include "Poco/UnicodeConverter.h"
-#include "Poco/NumberParser.h"
-#include "Poco/Path.h"
-
-/**
- *
- */
-TskImgDBPostgreSQL::TskImgDBPostgreSQL(const std::string dbName) : m_dbName(dbName), m_dbConnection(NULL)
-{
-    m_artifactIDcounter = 1000;
-    m_attributeIDcounter = 1000;
-}
-
-TskImgDBPostgreSQL::~TskImgDBPostgreSQL()
-{
-    close();
-}
-
-int TskImgDBPostgreSQL::close()
-{
-    if (m_dbConnection != NULL)
-    {
-        m_dbConnection->disconnect();
-        delete m_dbConnection;
-        m_dbConnection = NULL;
-    }
-
-    return 0;
-}
-
-bool TskImgDBPostgreSQL::initialized() const
-{
-    if (m_dbConnection == NULL)
-    {
-        LOGERROR(L"TskImgDBPostgreSQL::initialized - Database not initialized.\n");
-        return false;
-    }
-
-    return true;
-}
-
-/** 
- * Open the DB and create the tables.
- * @returns 1 on error
- */
-int TskImgDBPostgreSQL::initialize()
-{
-
-    // Open the database.
-    if (open() != 0)
-    {
-        // Error message will have been logged by open()
-        return 1;
-    }
-
-    try
-    {
-        pqxx::work W(*m_dbConnection);
-        // ----- DB_INFO
-        W.exec("CREATE TABLE db_info (name TEXT PRIMARY KEY, version TEXT)");
-        // ----- IMAGE_INFO
-        W.exec("CREATE TABLE image_info (type INTEGER, ssize INTEGER)");
-        // ----- IMAGE_NAMES
-        W.exec("CREATE TABLE image_names (seq SERIAL PRIMARY KEY, name TEXT)");
-        // ----- VOL_INFO
-        W.exec("CREATE TABLE vol_info (vol_id SERIAL PRIMARY KEY, sect_start BIGINT NOT NULL, sect_len BIGINT NOT NULL, description TEXT, flags INTEGER)");
-        // ----- FS_INFO
-        W.exec("CREATE TABLE fs_info (fs_id SERIAL PRIMARY KEY, img_byte_offset BIGINT, vol_id INTEGER NOT NULL, fs_type INTEGER, block_size INTEGER, block_count BIGINT, root_inum BIGINT, first_inum BIGINT, last_inum BIGINT)");
-        // ----- FILES
-        W.exec("CREATE TABLE files (file_id BIGSERIAL PRIMARY KEY, type_id INTEGER, name TEXT, par_file_id BIGINT, dir_type INTEGER, meta_type INTEGER, dir_flags INTEGER, meta_flags INTEGER, size BIGINT, ctime INTEGER, crtime INTEGER, atime INTEGER, mtime INTEGER, mode INTEGER, uid INTEGER, gid INTEGER, status INTEGER, full_path TEXT)");
-        // ----- FS_FILES
-        W.exec("CREATE TABLE fs_files (file_id BIGINT PRIMARY KEY, fs_id INTEGER, fs_file_id BIGINT, attr_type INTEGER, attr_id INTEGER)");
-        // ----- FS_BLOCKS
-        W.exec("CREATE TABLE fs_blocks (fs_id INTEGER NOT NULL, file_id BIGINT NOT NULL, seq INTEGER, blk_start BIGINT NOT NULL, blk_len BIGINT NOT NULL)");
-        // ----- CARVED_FILES
-        W.exec("CREATE TABLE carved_files (file_id BIGINT PRIMARY KEY, vol_id INTEGER)");
-        // ----- CARVED_SECTORS
-        W.exec("CREATE TABLE carved_sectors (file_id BIGINT, seq INTEGER, sect_start BIGINT, sect_len BIGINT)");
-        // ----- DERIVED_FILES
-        W.exec("CREATE TABLE derived_files (file_id BIGINT PRIMARY KEY, derivation_details TEXT)");
-        // ----- ALLOC_UNALLOC_MAP
-        W.exec("CREATE TABLE alloc_unalloc_map (vol_id INTEGER, unalloc_img_id INTEGER, unalloc_img_sect_start BIGINT, sect_len BIGINT, orig_img_sect_start BIGINT)");
-        // ----- FILE_HASHES
-        W.exec("CREATE TABLE file_hashes (file_id BIGINT PRIMARY KEY, md5 TEXT, sha1 TEXT, sha2_256 TEXT, sha2_512 TEXT, known INTEGER)");
-        // ----- MODULES
-        W.exec("CREATE TABLE modules (module_id SERIAL PRIMARY KEY, name TEXT UNIQUE NOT NULL, description TEXT)");
-        // ----- MODULE_STATUS
-        W.exec("CREATE TABLE module_status (file_id BIGINT, module_id SERIAL, status INTEGER, PRIMARY KEY (file_id, module_id))");
-        // ----- UNALLOC_IMG_STATUS
-        W.exec("CREATE TABLE unalloc_img_status (unalloc_img_id SERIAL PRIMARY KEY, status INTEGER)");
-        // ----- UNUSED_SECTORS
-        W.exec("CREATE TABLE unused_sectors (file_id BIGINT PRIMARY KEY, sect_start BIGINT, sect_len BIGINT, vol_id INTEGER)");
-        // ----- BLACKBOARD_ARTIFACTS
-        W.exec("CREATE TABLE blackboard_artifacts (artifact_id BIGSERIAL PRIMARY KEY, obj_id BIGINT NOT NULL, artifact_type_id INTEGER)");
-        // ----- BLACKBOARD_ATTRIBUTES
-        W.exec("CREATE TABLE blackboard_attributes (artifact_id BIGINT NOT NULL, source TEXT, context TEXT, attribute_type_id INTEGER NOT NULL, value_type INTEGER NOT NULL, "
-        "value_byte BYTEA, value_text TEXT, value_int32 INTEGER, value_int64 BIGINT, value_double NUMERIC(20, 10), obj_id BIGINT NOT NULL)");
-        // ----- BLACKBOARD_ARTIFACT_TYPES
-        W.exec("CREATE TABLE blackboard_artifact_types (artifact_type_id INTEGER PRIMARY KEY, type_name TEXT, display_name TEXT)");
-        // ----- BLACKBOARD_ATTRIBUTE_TYPES
-        W.exec("CREATE TABLE blackboard_attribute_types (attribute_type_id INTEGER PRIMARY KEY, type_name TEXT, display_name TEXT)");
-        // ----- INDEX ON ARTIFACT_ID OF BLACKBOARD_ATTRIBUTES
-        W.exec("CREATE INDEX attrs_artifact_id ON blackboard_attributes(artifact_id)");        
-        // ----- INDEX ON ATTRIBUTE_TYPE OF BLACKBOARD_ATTRIBUTES
-        W.exec("CREATE INDEX attrs_attribute_type ON blackboard_attributes(attribute_type_id)");        
-        // ----- INDEX ON OBJ_ID OF BLACKBOARD_ATTRIBUTES
-        W.exec("CREATE INDEX attrs_obj_id ON blackboard_attributes(obj_id)");        
-        
-        W.exec("SET synchronous_commit TO OFF");
-
-        W.commit();
-
-        map<int, TskArtifactNames> artTypes = TskImgDB::getAllArtifactTypes();
-        for(map<int, TskArtifactNames>::iterator it = artTypes.begin(); it != artTypes.end(); it++){
-            addArtifactType(it->first, it->second.typeName, it->second.displayName);
-        }
-        map<int, TskAttributeNames> attrTypes = TskImgDB::getAllAttributeTypes();
-        for(map<int, TskAttributeNames>::iterator it = attrTypes.begin(); it != attrTypes.end(); it++){
-            addAttributeType(it->first, it->second.typeName, it->second.displayName);
-        }
-
-    }
-    catch (std::exception& ex)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::initialize - Error creating database: " << ex.what() << std::endl;
-        LOGERROR(errorMsg.str());
-        return 1;
-    }
-
-    addToolInfo("DbSchema", IMGDB_SCHEMA_VERSION);
-    LOGINFO(L"ImgDB Created.");
-
-    return 0;
-}
-
-/*
- * Attempt to connect to an existing database. If connection attempt fails
- * a new database is created. This database must be initialized before it
- * is used.
- * Returns 1 if connection attempt fails.
- */
-int TskImgDBPostgreSQL::open()
-{
-    // Get current user name. This will get used in connecting to the database.
-    char name[UNLEN+1];
-    DWORD size = UNLEN+1;
-
-    GetUserNameA(name, &size);
-
-    std::string db_host = GetSystemProperty(TskSystemProperties::DB_HOST);
-    std::string db_port = GetSystemProperty(TskSystemProperties::DB_PORT);
-
-    // Convert the hostname to an IPv4 address. We need to do this because if you attempt to establish a 
-    // connection to a database server that exists on the same machine PostgreSQL will use the 'localhost'
-    // rule from the pg_hba.conf file. Unfortunately, SSPI authentication doesn't work in that scenario.
-    std::string db_host_ip;
-
-    if (!TskUtilities::getHostIP(db_host, db_host_ip))
-        return 1;
-
-    try
-    {
-        // Construct the connection string to connect to the Postgres server.
-        std::stringstream pgConnectionString;
-        pgConnectionString << "host='" << db_host_ip << "' port='" << db_port
-            << "' dbname='postgres' user='" << name << "'";
-
-        pqxx::connection pgConnection(pgConnectionString.str());
-
-        // Check whether the database exists
-        pqxx::nontransaction nontrans(pgConnection);
-
-        std::stringstream dbQuery;
-        dbQuery << "select count(*) from pg_catalog.pg_database where datname = " << nontrans.quote(m_dbName);
-
-        pqxx::result R = nontrans.exec(dbQuery);
-
-        if (R.size() == 0 || R[0][0].as<int>() == 0) 
-        {
-            // There is no database. It needs to be created.
-            std::stringstream createDatabase;
-            createDatabase << "CREATE DATABASE \"" << m_dbName << "\" WITH OWNER=\"" << name << "\" ENCODING='UTF-8'";
-            nontrans.exec(createDatabase);
-        }
-
-        std::stringstream dbConnectionString;
-        dbConnectionString << "host='" << db_host_ip << "' port='" << db_port
-            << "' dbname='" << m_dbName << "' user='" << name << "'";
-
-        m_dbConnection = new pqxx::connection(dbConnectionString.str());
-    }
-    catch (std::exception& ex)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskDBPostgreSQL::open - Error connecting to the database: "
-            << ex.what() << std::endl;
-        LOGERROR(errorMsg.str());
-        return 1;
-    }
-
-    // We successfully connected to the database.
-    LOGINFO(L"ImgDB Opened.");
-    return 0;
-}
-
-pqxx::result TskImgDBPostgreSQL::executeStatement(const std::string& stmt) const
-{
-    pqxx::result R;
-
-    try
-    {
-        work W(*m_dbConnection);
-        R = W.exec(stmt);
-        W.commit();
-    }
-    catch (const exception &e)
-    {
-        std::stringstream errorMsg;
-        errorMsg << "TskDBPostgreSQL::executeStatement : " << e.what() << std::endl;
-        throw TskException(errorMsg.str());
-    }
-
-    return R;
-}
-
-int TskImgDBPostgreSQL::addToolInfo(const char* name, const char* version)
-{
-    if (!initialized())
-        return 1;
-
-    stringstream stmt;
-
-    stmt << "INSERT INTO db_info (name, version) VALUES ('" << name 
-        << "', '" << version << "')";
-
-    try
-    {
-        executeStatement(stmt.str());
-        return 0;
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskDBPostgreSQL::addToolInfo - Error adding data to db_info table: "
-            << e.what() << std::endl;
-        LOGERROR(errorMsg.str());
-
-        return 1;
-    }
-}
-
-int TskImgDBPostgreSQL::addImageInfo(int type, int size)
-{
-    if (!initialized())
-        return 1;
-
-    stringstream stmt;
-
-    stmt << "INSERT INTO image_info (type, ssize) VALUES (" << type << ", " << size << ")";
-
-    try
-    {
-        executeStatement(stmt.str());
-        return 0;
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskDBPostgreSQL::addImageInfo - Error adding data to image_info table: "
-            << e.what() << std::endl;
-        LOGERROR(errorMsg.str());
-
-        return 1;
-    }
-}
-
-int TskImgDBPostgreSQL::addImageName(char const * imgName)
-{
-    if (!initialized())
-        return 1;
-
-    stringstream stmt;
-
-    stmt << "INSERT INTO image_names (seq, name) VALUES (DEFAULT, E" 
-        << m_dbConnection->quote(imgName) << ")";
-
-    try
-    {
-        executeStatement(stmt.str());
-        return 0;
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskDBPostgreSQL::addImageName - Error adding data to image_names table: "
-            << e.what() << std::endl;
-        LOGERROR(errorMsg.str());
-
-        return 1;
-    }
-}
-
-/**
- * Adds the sector addresses of the volumes into the db.
- */
-int TskImgDBPostgreSQL::addVolumeInfo(const TSK_VS_PART_INFO * vs_part)
-{
-    if (!initialized())
-        return 1;
-
-    stringstream stmt;
-
-    stmt << "INSERT INTO vol_info (vol_id, sect_start, sect_len, description, flags) VALUES ("
-        << (int)vs_part->addr << ", " << vs_part->start 
-        << ", " << vs_part->len << ", '" << vs_part->desc 
-        << "', " << vs_part->flags << ")";
-
-    try
-    {
-        executeStatement(stmt.str());
-    }
-    catch (const TskException &e)
-    {
-        std::stringstream msg;
-        msg << "TskImgDBPostgreSQL::addVolumeInfo : " << e.what();
-        LOGERROR(msg.str());
-
-        return 1;
-    }
-
-    return 0;
-}
-
-int TskImgDBPostgreSQL::addFsInfo(int volId, int fsId, const TSK_FS_INFO * fs_info)
-{
-    if (!initialized())
-        return 1;
-
-    stringstream stmt;
-
-    stmt << "INSERT INTO fs_info (fs_id, img_byte_offset, vol_id, fs_type, block_size, block_count, root_inum, first_inum, last_inum) VALUES (" 
-        << fsId << ", " << fs_info->offset << ", " << volId
-        << ", " << (int)fs_info->ftype << ", " << fs_info->block_size << ", " << fs_info->block_count
-        << ", " << fs_info->root_inum << ", " << fs_info->first_inum << ", " << fs_info->last_inum << ")";
-
-    try
-    {
-        executeStatement(stmt.str());
-    }
-    catch (const TskException &e)
-    {
-        std::stringstream msg;
-        msg << "TskImgDBPostgreSQL::addFsInfo : " << e.what();
-        LOGERROR(msg.str());
-
-        return 1;
-    }
-
-    return 0;
-}
-
-
-/**
- * Given a file system and fs_file_id, return the file_id.
- */
-uint64_t TskImgDBPostgreSQL::getFileId(int a_fsId, uint64_t a_fsFileId) const
-{
-    if (!initialized())
-        return 0;
-
-    stringstream stmt;
-    uint64_t fileId = 0;
-
-    stmt << "SELECT file_id FROM fs_files WHERE fs_id=" 
-        << a_fsId << "AND fs_file_id=" << a_fsFileId;
-
-    try
-    {
-        pqxx::result R = executeStatement(stmt.str());
-
-        // @@@ It's possible to have multiple file_ids for the same fs_file_id.
-        // @@@ Which one should we use?
-        if (R.size() > 0)
-            fileId = R[0][0].as<uint64_t>();
-    }
-    catch (const TskException &e)
-    {
-        std::stringstream msg;
-        msg << "TskDBPostgreSQL::getFileId : Error querying fs_files table: " << e.what();
-        LOGERROR(msg.str());
-    }
-    return fileId;
-}
-
-/**
- * @returns the file record or -1 on error.
- */
-int TskImgDBPostgreSQL::getFileRecord(const uint64_t fileId, TskFileRecord& fileRecord) const
-{
-    if (!initialized())
-        return -1;
-
-    stringstream stmt;
-
-    stmt << "SELECT f.file_id, f.type_id, f.name, f.par_file_id, f.dir_type, f.meta_type, f.dir_flags, "
-        << "f.meta_flags, f.size, f.ctime, f.crtime, f.atime, f.mtime, f.mode, f.uid, f.gid, f.status, f.full_path, "
-        << "fh.md5, fh.sha1, fh.sha2_256, fh.sha2_512 "
-        << "FROM files f LEFT OUTER JOIN file_hashes fh ON f.file_id = fh.file_id WHERE f.file_id=" << fileId;
-
-    try
-    {
-        pqxx::read_transaction W(*m_dbConnection);
-        pqxx::result R = W.exec(stmt);
-
-        if (R.size() == 1)
-        {
-            R[0][0].to(fileRecord.fileId);
-            R[0][1].to((int &)fileRecord.typeId);
-            R[0][2].to(fileRecord.name);
-            R[0][3].to(fileRecord.parentFileId);
-            R[0][4].to((int &)fileRecord.dirType);
-            R[0][5].to((int &)fileRecord.metaType);
-            R[0][6].to((int &)fileRecord.dirFlags);
-            R[0][7].to((int &)fileRecord.metaFlags);
-            R[0][8].to(fileRecord.size);
-            R[0][9].to(fileRecord.ctime);
-            R[0][10].to(fileRecord.crtime);
-            R[0][11].to(fileRecord.atime);
-            R[0][12].to(fileRecord.mtime);
-            R[0][13].to((int &)fileRecord.mode);
-            R[0][14].to(fileRecord.uid);
-            R[0][15].to(fileRecord.gid);
-            R[0][16].to((int &)fileRecord.status);
-            R[0][17].to(fileRecord.fullPath);
-            R[0][18].to(fileRecord.md5);
-            R[0][19].to(fileRecord.sha1);
-            R[0][20].to(fileRecord.sha2_256);
-            R[0][21].to(fileRecord.sha2_512);            
-        }
-        else if (R.size() == 0)
-        {
-            std::wstringstream msg;
-            msg << L"TskImgDBPostgreSQL::getFileRecord - No record found for file id: " << fileId;
-            LOGERROR(msg.str());
-            return -1;
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream msg;
-        msg << L"TskImgDBPostgreSQL::getFileRecord - Error querying files table: "
-            << e.what();
-        LOGERROR(msg.str());
-        return -1;
-    }
-
-    return 0;
-}
-
-int TskImgDBPostgreSQL::addFsFileInfo(int fileSystemID, const TSK_FS_FILE *fileSystemFile, const char *fileName, int fileSystemAttrType, int fileSystemAttrID, uint64_t &fileID, const char *filePath)
-{
-    const std::string msgPrefix = "TskImgDBPostgreSQL::addFsFileInfo : ";
-    fileID = 0;
-
-    if (!initialized())
-    {
-        return -1;
-    }
-
-    // Construct the full path of the file within the image.
-    std::string fullpath(filePath);
-    fullpath.append(fileName);
-
-    // Check whether the file name contains a single quote. If so, replace it with a double single quote.
-    std::string fileNameAsString(fileName);
-    size_t found;
-    found = fileNameAsString.find("'");
-    if (found != std::string::npos) //Replace it and replace all its subsequent occurrences.
-    {
-        fileNameAsString.replace(found,1,"''");
-
-        while ((found=fileNameAsString.find("'",found+2)) != std::string::npos)// found+2 because we want to move past the newly inserted single quote.
-        {
-            fileNameAsString.replace(found,1,"''");
-        }
-    }
-
-    // Now remove all the control characters from the file name.
-    for (int codePoint=1; codePoint < 32; codePoint++)
-    {
-        char codePointAsHex[10];
-        codePointAsHex[0] = codePoint;
-        codePointAsHex[1] = '\0';
-        std::string stringToRemove(codePointAsHex);
-
-        found = fileNameAsString.find(stringToRemove);
-        if (found != std::string::npos) //Replace it and replace all its subsequent occurrences.
-        {
-            fileNameAsString.replace(found,1,"");
-
-            while ((found=fileNameAsString.find(stringToRemove,found+1)) != std::string::npos)// found+1 because the control characters are just 1 character.
-            {
-                fileNameAsString.replace(found,1,"");
-            }
-        }
-    }
-
-    fileName = fileNameAsString.c_str();
-
-    uint64_t parFileId = findParObjId(fileSystemID, fileSystemFile->name->par_addr);
-
-    // Get the file size.
-    TSK_OFF_T size = 0; 
-    const TSK_FS_ATTR *fileSystemAttribute = tsk_fs_file_attr_get_id(const_cast<TSK_FS_FILE*>(fileSystemFile), fileSystemAttrID); 
-    if (fileSystemAttribute)
-    {
-        size = fileSystemAttribute->size;
-    }
-
-    // Get the file metadata, if it's available.
-    int mtime = 0;
-    int crtime = 0;
-    int ctime = 0;
-    int atime = 0;
-    int meta_type = 0;
-    int meta_flags = 0;
-    int meta_mode = 0;
-    int gid = 0;
-    int uid = 0;
-    if (fileSystemFile->meta) 
-    {
-        mtime = static_cast<int>(fileSystemFile->meta->mtime);
-        atime = static_cast<int>(fileSystemFile->meta->atime);
-        ctime = static_cast<int>(fileSystemFile->meta->ctime);
-        crtime = static_cast<int>(fileSystemFile->meta->crtime);
-        meta_type = fileSystemFile->meta->type;
-        meta_flags = fileSystemFile->meta->flags;
-        meta_mode = fileSystemFile->meta->mode;
-        gid = fileSystemFile->meta->gid;
-        uid = fileSystemFile->meta->uid;
-    }
-
-    // Insert into the files table.
-    std::stringstream stmt;
-
-    try
-    {
-        stmt << "INSERT INTO files (file_id, type_id, status, name, par_file_id, dir_type, meta_type, dir_flags, meta_flags, size, crtime, ctime, atime, mtime, mode, gid, uid, full_path) VALUES ("
-            << "DEFAULT, " << IMGDB_FILES_TYPE_FS << ", " << IMGDB_FILES_STATUS_READY_FOR_ANALYSIS << ", " << m_dbConnection->quote(fileName) << ", "
-            << parFileId << ", " << fileSystemFile->name->type << ", " << meta_type << ", "
-            << fileSystemFile->name->flags << ", " << meta_flags << ", " << size << ", " << crtime << ", " << ctime << ", " << atime << ", "
-            << mtime << ", " << meta_mode << ", " << gid << ", " << uid << ", E" << m_dbConnection->quote(fullpath) << ")";
-
-        executeStatement(stmt.str());
-    }
-    catch (const exception &e)
-    {
-        std::ostringstream errorMsg;
-        errorMsg << msgPrefix << "Error adding data to files table: " << e.what();
-        LOGERROR(errorMsg.str());
-
-        return -1;
-    }
-
-    // get the file_id from the last insert
-    fileID = 0;
-    try
-    {
-        stmt.str("");
-        stmt << "SELECT currval(pg_get_serial_sequence('files', 'file_id'))";
-        result R = executeStatement(stmt.str());
-
-        if (R.size() == 1)
-        {
-            fileID = R[0][0].as<uint64_t>();
-        }
-        else if (R.size() > 1)
-        {
-            std::ostringstream msg;
-            msg << msgPrefix << "Unexpected number of records (" << R.size() << ") returned from files table INSERT";
-            LOGERROR(msg.str());
-        }
-    }
-    catch (const exception &e)
-    {
-        std::ostringstream errorMsg;
-        errorMsg << msgPrefix << "Error getting the file_id of the last inserted row: " << e.what();
-        LOGERROR(errorMsg.str());
-
-        return -1;
-    }
-
-    // Insert into the fs_files table.
-    try
-    {
-        stmt.str("");
-        stmt << "INSERT INTO fs_files (file_id, fs_id, fs_file_id, attr_type, attr_id) VALUES ("
-            << fileID << ", " << fileSystemID << ", " << fileSystemFile->name->meta_addr << ", " << fileSystemAttrType << ", " << fileSystemAttrID << ")";
-        executeStatement(stmt.str());
-    }
-    catch (const exception &e)
-    {
-        std::stringstream errorMsg;
-        errorMsg << msgPrefix << "Error adding data to fs_files table: " << e.what();
-        LOGERROR(errorMsg.str());
-
-        return -1;
-    }
-
-    //if dir, update parent id cache
-    if (meta_type == TSK_FS_META_TYPE_DIR) {
-        storeParObjId(fileSystemID, fileSystemFile->name->meta_addr, fileID);
-    }
-
-    return 0;
-}
-
-/**
- * Add block info to the database.  This table stores the run information for each file so that we
- * can map which blocks are used by what files.
- * @param a_fsId Id that the file is located in
- * @param a_fileId ID of the file
- * @param a_sequence The sequence number of this run in the file (0 for the first run, 1 for the second run, etc.)
- * @param a_blk_addr Block address (the address that the file system uses -- NOT the physical sector addr)
- * @param a_len The number of blocks in the run
- * @returns 1 on error
- */
-int TskImgDBPostgreSQL::addFsBlockInfo(int a_fsId, uint64_t a_fileId, int a_sequence, uint64_t a_blk_addr, uint64_t a_len)
-{
-    if (!initialized())
-        return 1;
-
-    stringstream stmt;
-
-    stmt << "INSERT INTO fs_blocks (fs_id, file_id, seq, blk_start, blk_len) VALUES ("
-        << a_fsId << ", " << a_fileId << ", " << a_sequence << ", " << a_blk_addr << ", " << a_len << ")";
-
-    try
-    {
-        executeStatement(stmt.str());
-    }
-    catch (const exception &e)
-    {
-        std::stringstream errorMsg;
-        errorMsg << "TskDBPostgreSQL::addFsBlockInfo : Error adding data to fs_blocks table: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-
-        return 1;
-    }
-
-    return 0;
-}
-
-
-int TskImgDBPostgreSQL::addAllocUnallocMapInfo(int a_volID, int unallocImgID, 
-                                               uint64_t unallocImgStart, uint64_t length, uint64_t origImgStart)
-{
-    if (!initialized())
-        return 1;
-
-    stringstream stmt;
-
-    stmt << "INSERT INTO alloc_unalloc_map (vol_id, unalloc_img_id, unalloc_img_sect_start, sect_len, orig_img_sect_start) VALUES ("
-        << a_volID << ", " << unallocImgID << ", " << unallocImgStart << ", " << length << ", " << origImgStart << ")";
-
-    try
-    {
-        executeStatement(stmt.str());
-        return 0;
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskDBPostgreSQL::addAllocUnallocMapInfo - Error adding data to alloc_unalloc_map table: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-
-        return 1;
-    }
-}
-
-/**
- * Get information on all of the free sectors in an image.
- *
- * @return Info on unallocated runs (or NULL on error).  Caller must free this when done.
- */
-SectorRuns * TskImgDBPostgreSQL::getFreeSectors() const
-{
-    if (!initialized())
-        return NULL;
-
-    SectorRuns * sr = new SectorRuns();
-
-    LOGINFO(L"TskImgDBPostgreSQL::getFreeSectors - Identifying Unallocated Sectors");
-
-    std::stringstream stmt;
-    std::wstringstream msg;
-
-    /********** FIND the unallocated volumes *************/
-    stmt << "SELECT vol_id, sect_start, sect_len, flags FROM vol_info";
-    try
-    {
-        pqxx::read_transaction readTrans(*m_dbConnection);
-        pqxx::result R = readTrans.exec(stmt);
-
-        for (int rownum=0; rownum < R.size(); ++rownum)
-        {
-            const result::tuple row = R[rownum];
-
-            int flags = row[3].as<int>();
-
-            int vol_id = row[0].as<int>();
-            int64_t start = row[1].as<int64_t>();
-            int64_t len = row[2].as<int64_t>();
-
-            // add the unallocated volumes
-            if (flags & TSK_VS_PART_FLAG_UNALLOC) {
-                sr->addRun(start, len, vol_id);
-            }
-
-            // add the allocated volumes that don't have a known file system
-            else
-            {
-                stmt.str("");
-                stmt << "SELECT fs_id FROM fs_info WHERE vol_id = " << vol_id;
-                pqxx::result R1 = readTrans.exec(stmt);
-
-                if (R1.size() == 0)
-                {
-                    sr->addRun(start, len, vol_id);
-                }
-            }
-        } // end of 'for' statement
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getFreeSectors - Error querying vol_info table: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-
-        return NULL;
-    }
-
-    /*************** Find the unallocated blocks in each file system *************/
-    // @@@ Need to make more dynamic
-    int blk_size[32];
-    memset(blk_size, 0, sizeof(blk_size));
-    uint64_t blk_count[32];
-    memset(blk_count, 0, sizeof(blk_count));
-    int vol_id[32];
-    uint64_t img_offset[32];
-
-    // get basic info on each file system
-    stmt.str("");
-    stmt << "SELECT fs_id, vol_id, img_byte_offset, block_size, block_count FROM fs_info";
-    try
-    {
-        pqxx::read_transaction readTrans(*m_dbConnection);
-        pqxx::result R = readTrans.exec(stmt);
-
-        LOGINFO(L"TskImgDBPostgreSQL::getFreeSectors - START LOOP: Find the unallocated blocks in each file system.");
-        for (int rownum=0; rownum < R.size(); ++rownum)
-        {
-            const result::tuple row = R[rownum];
-
-            int fs_id = row[0].as<int>();
-            if (fs_id > 32)
-            {
-                std::wstringstream errorMsg;
-                errorMsg << L"TskImgDBPostgreSQL::getFreeSectors - fs_id in fs_info is bigger than 32: " << fs_id;
-                LOGERROR(errorMsg.str());
-                break;
-            }
-
-            vol_id[fs_id] = row[1].as<int>();
-            img_offset[fs_id] = row[2].as<uint64_t>() / 512;
-            blk_size[fs_id] = row[3].as<int>() / 512;
-            blk_count[fs_id] = row[4].as<uint64_t>(); 
-
-            // Debug Info
-            msg.str(L"");
-            msg << L"TskImgDBPostgreSQL::getFreeSectors - fs_id=" << fs_id << " vol_id=" << vol_id[fs_id] << " img_offset=" << img_offset[fs_id] << " blk_size=" << blk_size[fs_id] <<
-                " blk_count=" << blk_count[fs_id];
-            LOGINFO(msg.str().c_str());
-        }
-        LOGINFO(L"TskImgDBPostgreSQL::getFreeSectors - DONE: Find the unallocated blocks in each file system.");
-    }// end of 'try' block
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getFreeSectors - Error querying fs_info table: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-
-        return NULL;
-    }
-
-    // see what blocks have been used and add them to a list
-    TSK_LIST *seen[32];
-    memset(seen, 0, 32*sizeof(TSK_LIST *));
-
-    stmt.str("");
-    stmt << "SELECT fs_id, file_id, blk_start, blk_len FROM fs_blocks";
-    try
-    {
-        pqxx::read_transaction readTrans(*m_dbConnection);
-        pqxx::result blocksResult = readTrans.exec(stmt);
-
-        LOGINFO(L"TskImgDBPostgreSQL::getFreeSectors - START LOOP: see what blocks have been used and add them to a list.");
-        for (int rownum=0; rownum < blocksResult.size(); ++rownum)
-        {
-            const result::tuple row = blocksResult[rownum];
-
-            int fs_id = row[0].as<int>();
-            if (fs_id > 32)
-            {
-                std::wstringstream errorMsg;
-                errorMsg << L"TskImgDBPostgreSQL::getFreeSectors - fs_id in fs_info is bigger than 32: " << fs_id;
-                LOGERROR(errorMsg.str());
-                break;
-            }
-            uint64_t file_id = row[1].as<uint64_t>();
-            int64_t addr = row[2].as<int64_t>();
-            int64_t len = row[3].as<int64_t>();
-
-            // We only want to consider the runs for files that we allocated.
-            int flags = 0;
-            stmt.str("");
-            stmt << "SELECT meta_flags from files WHERE file_id=" << file_id;
-            pqxx::result flagsResult = readTrans.exec(stmt);
-
-            // @@@ It is possible for fs_blocks entries to have a file_id = 0
-            // @@@ An example is "pointer" blocks in ext file systems that
-            // @@@ contain the addresses of where the file content is stored.
-            // @@@ We should tag these blocks with the actual file_id instead of 0
-            // @@@ and use another mechanism to identify them as non-content blocks.
-            if (file_id != 0 && flagsResult.size() == 0)
-            {
-                std::wstringstream errorMsg;
-                errorMsg << L"TskImgDBPostgreSQL::getFreeSectors - error finding flags for file " << file_id;
-                LOGERROR(errorMsg.str());
-                continue;
-            }
-            else if (flagsResult.size() > 0)
-            {
-                flags = flagsResult[0][0].as<int>();
-            }
-
-            if (flags & TSK_FS_META_FLAG_UNALLOC)
-                continue;
-
-            // @@@ We can probably find a more effecient storage method than this...
-            int error = 0;
-            for (int64_t i = 0; i < len; i++) {
-                if (tsk_list_add(&seen[fs_id], addr+i)) {
-                    std::wstringstream errorMsg;
-                    errorMsg << L"TskImgDBPostgreSQL::getFreeSectors - Error adding seen block address to list";
-                    LOGERROR(errorMsg.str());
-
-                    error = 1;
-                    break;
-                }
-            }
-            if (error)
-                break;
-        } // end of 'for' block
-        LOGINFO(L"TskImgDBPostgreSQL::getFreeSectors - DONE: see what blocks have been used and add them to a list.");
-    } // end of 'try' block
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getFreeSectors - Error querying fs_block table: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-
-        return NULL;
-    }
-
-    // cycle through each file system to find the unused blocks
-    LOGINFO(L"TskImgDBPostgreSQL::getFreeSectors - START LOOP: cycle through each file system to find the unused blocks.");
-    for (int f = 0; f < 32; f++) {
-        if (blk_count[f] == 0)
-            continue;
-
-        uint64_t st = 0;
-        int len = 0;
-        // we previously adjusted blk_size and img_offset to be in sectors
-
-        msg.str(L"");
-        msg << L"blk_count[" << f << "]=" << blk_count[f];
-        LOGINFO(msg.str().c_str());
-
-        for (uint64_t a = 0; a < blk_count[f]; a++) {
-            // see if this addr was used in a file
-            if (tsk_list_find(seen[f], a) == 0) {
-                // we already have a run being defined
-                if (len) {
-                    // same run, so add on to it
-                    if (st + len == a) {
-                        len++;
-                    }
-                    // different run, make a new one
-                    else {
-                        sr->addRun(img_offset[f]+st*blk_size[f], len*blk_size[f], vol_id[f]);
-                        st = a;
-                        len = 1;
-                    }
-                }
-                // start a new run
-                else {
-                    st = a;
-                    len = 1;
-                }
-            }
-        }
-        // add the final run
-        if (len) {
-            sr->addRun(img_offset[f]+st*blk_size[f], len*blk_size[f], vol_id[f]);
-        }
-        tsk_list_free(seen[f]);
-        seen[f] = NULL;
-    }
-    LOGINFO(L"TskImgDBPostgreSQL::getFreeSectors - DONE: cycle through each file system to find the unused blocks.");
-
-    return sr;
-}
-
-std::string TskImgDBPostgreSQL::getImageBaseName() const
-{
-    // There may be multiple file paths if the image is a split image. Oreder by sequence number to extract the file name from the first path.
-    pqxx::read_transaction trans(*m_dbConnection);
-    pqxx::result resultSet = trans.exec("SELECT name FROM image_names ORDER BY seq;");
-    if (resultSet.begin() != resultSet.end())
-    {
-        Poco::Path imagePath((resultSet.begin())[0].c_str()); 
-        return imagePath.getFileName();
-    }
-    else
-    {
-        return "";
-    }
-}
-
-std::vector<std::wstring> TskImgDBPostgreSQL::getImageNames() const
-{
-    std::vector<std::wstring> imgList;
-
-    if (!initialized())
-        return imgList;
-
-    stringstream stmt;
-
-    stmt << "SELECT name FROM image_names ORDER BY seq";
-
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-
-        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
-        {
-            std::wstring imgName;
-            Poco::UnicodeConverter::toUTF16(i[0].c_str(), imgName);
-
-            imgList.push_back(imgName);
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getImageNames - Error getting image names : "
-            << e.what();
-        LOGERROR(errorMsg.str());
-    }
-
-    if (imgList.empty()) 
-    {
-        LOGERROR(L"No images found in TskImgDBPostgres");
-    }
-
-    return imgList;
-}
-
-/**
- * @param a_fileId  File id to get information about
- * @param a_fsOffset Byte offset of start of file system that the file is located in
- * @param a_fsFileId File system-specific id of the file
- * @param a_attrType Type of attribute for this file
- * @param a_attrId The ID of the attribute for this file
- * @returns 0 on success, -1 on error
- */
-int TskImgDBPostgreSQL::getFileUniqueIdentifiers(uint64_t a_fileId, uint64_t &a_fsOffset, uint64_t &a_fsFileId, int &a_attrType, int &a_attrId) const
-{
-    if (!initialized())
-        return -1;
-
-    stringstream stmt;
-
-    stmt << "SELECT fs_file_id, attr_type, attr_id, fs_info.img_byte_offset "
-        "FROM fs_files, fs_info WHERE file_id=" << a_fileId
-        << " AND fs_info.fs_id = fs_files.fs_id";
-
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-
-        if (R.size() == 1)
-        {
-            R[0][0].to(a_fsFileId);
-            R[0][1].to(a_attrType);
-            R[0][2].to(a_attrId);
-            R[0][3].to(a_fsOffset);
-        }
-        else
-        {
-            std::wstringstream errorMsg;
-            errorMsg << L"TskImgDBPostgreSQL::getFileUniqueIdentifiers - Not a file system file : "
-                << a_fileId;
-            LOGERROR(errorMsg.str());
-
-            return -1;
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getFileUniqueIdentifiers - Error getting file identifiers: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-
-        return -1;
-    }
-
-    return 0;
-}
-
-/**
- * Get number of volumes in image.
- * @return Number of volumes in image or -1 on error
- */
-int TskImgDBPostgreSQL::getNumVolumes() const
-{
-    if (!initialized())
-        return -1;
-
-    int count = 0;
-
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec("SELECT count(*) from vol_info");
-
-        if (R.size() == 1)
-        {
-            R[0][0].to(count);
-        }
-        else
-        {
-            std::wstringstream errorMsg;
-            errorMsg << L"TskImgDBPostgreSQL::getNumVolumes - Unexpected number of rows returned."
-                << R.size();
-            LOGERROR(errorMsg.str());
-
-            return -1;
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getNumVolumes - Error getting number of volumes: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-
-        return -1;
-    }
-
-    return count;
-}
-
-/**
- * Get number of files in image.
- * @return Number of files in image or -1 on error
- */
-int TskImgDBPostgreSQL::getNumFiles() const
-{
-    if (!initialized())
-        return -1;
-
-    std::string condition("");
-    int count = getFileCount(condition);
-
-    return count;
-}
-
-/**
- * @returns the session_id or -1 on error.
- */
-int TskImgDBPostgreSQL::getSessionID() const
-{
-    if (!initialized())
-        return -1;
-
-    int sessionId;
-    stringstream stmt;
-
-    stmt << "SELECT version FROM db_info WHERE name = 'SID'";
-
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-
-        if (R.size() == 1)
-        {
-            R[0][0].to(sessionId);
-        }
-        else
-        {
-            std::wstringstream errorMsg;
-            errorMsg << L"TskImgDBPostgreSQL::getSessionID - Unexpected number of rows returned."
-                << R.size();
-            LOGERROR(errorMsg.str());
-
-            return -1;
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getSessionID - Error getting session id: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-
-        return -1;
-    }
-
-    return sessionId;
-}
-
-/**
- * begin is a no-op since all PostgreSQL statements are run in the
- * context of a transaction.
- */
-int TskImgDBPostgreSQL::begin()
-{
-    return 0;
-}
-
-/**
- * commit is a no-op since all PostgreSQL statements are run in the
- * context of a transaction.
- */
-int TskImgDBPostgreSQL::commit()
-{
-    return 0;
-}
-
-
-UnallocRun * TskImgDBPostgreSQL::getUnallocRun(int a_unalloc_img_id, int a_file_offset) const
-{
-    if (!initialized())
-        return NULL;
-
-    stringstream stmt;
-
-    stmt << "SELECT vol_id, unalloc_img_sect_start, sect_len, orig_img_sect_start FROM "
-        "alloc_unalloc_map WHERE unalloc_img_id = " << a_unalloc_img_id 
-        << " AND unalloc_img_sect_start <= " << a_file_offset << " ORDER BY unalloc_img_sect_start DESC";
-
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-
-        if (R.size() > 0)
-        {
-            int vol_id; R[0][0].to(vol_id);
-            int unalloc_img_sect_start; R[0][1].to(unalloc_img_sect_start);
-            int sect_len; R[0][2].to(sect_len);
-            int orig_img_sect_start; R[0][3].to(orig_img_sect_start);
-
-            return new UnallocRun(vol_id, a_unalloc_img_id, unalloc_img_sect_start, sect_len, orig_img_sect_start);
-        }
-        else
-        {
-            LOGERROR(L"TskImgDBPostgreSQL::getUnallocRun - No records returned.\n");
-            return new UnallocRun(-1, -1, -1, -1, -1);
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getUnallocRun - Error fetching data from alloc_unalloc_map table: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-
-        return new UnallocRun(-1, -1, -1, -1, -1);
-    }
-}
-
-/**
- * Adds information about a carved file into the database.  This includes the sector layout
- * information. 
- * 
- * @param vol_id ID of volume that file is locatd in
- * @param name Name of file
- * @param size Number of bytes in file
- * @param runStarts Array with starting sector (relative to start of image) for each run in file.
- * @param runLengths Array with number of sectors in each run 
- * @param numRuns Number of entries in previous arrays
- * @param fileId Carved file Id (output)
- * @returns 0 on success or -1 on error.
- */
-int TskImgDBPostgreSQL::addCarvedFileInfo(int vol_id, wchar_t * name, uint64_t size, 
-  uint64_t *runStarts, uint64_t *runLengths, int numRuns, uint64_t & fileId)
-{
-    if (!initialized())
-        return -1;
-
-    std::string utf8Name;
-    Poco::UnicodeConverter::toUTF8(name, utf8Name);
-
-    fileId = 0;
-
-    stringstream stmt;
-
-    stmt << "INSERT INTO files (file_id, type_id, name, par_file_id, dir_type, meta_type,"
-        "dir_flags, meta_flags, size, ctime, crtime, atime, mtime, mode, uid, gid, status, full_path) "
-        "VALUES (DEFAULT, " << IMGDB_FILES_TYPE_CARVED << ", " << m_dbConnection->quote(utf8Name)
-        << ", NULL, " <<  TSK_FS_NAME_TYPE_REG << ", " <<  TSK_FS_META_TYPE_REG << ", "
-        << TSK_FS_NAME_FLAG_UNALLOC << ", " << TSK_FS_META_FLAG_UNALLOC << ", "
-        << size << ", 0, 0, 0, 0, NULL, NULL, NULL, " << IMGDB_FILES_STATUS_CREATED << "," << m_dbConnection->quote(utf8Name) << ")";
-
-    try
-    {
-        pqxx::work W(*m_dbConnection);
-        pqxx::result R = W.exec(stmt);
-
-        // get the file_id from the last insert
-        stmt.str("");
-        stmt << "SELECT currval(pg_get_serial_sequence('files', 'file_id'))";
-        R = W.exec(stmt);
-
-        fileId = R[0][0].as<uint64_t>();
-
-        stmt.str("");
-
-        // insert into the carved_files_table
-        stmt << "INSERT INTO carved_files (file_id, vol_id) VALUES ("
-            << fileId << ", " << vol_id << ")";
-
-        R = W.exec(stmt);
-
-        // insert into carved_sectors table
-        for (int i = 0; i < numRuns; i++)
-        {
-            stmt.str("");
-            stmt << "INSERT INTO carved_sectors (file_id, seq, sect_start, sect_len) VALUES ("
-                << fileId << ", " << i << ", " << runStarts[i] << ", " << runLengths[i] << ")";
-
-            R = W.exec(stmt);
-        }
-
-        W.commit();
-    }
-    catch (exception& ex)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::addCarvedFileInfo - Error adding data to carved_files table: "
-            << ex.what();
-        LOGERROR(errorMsg.str());
-
-        return -1;
-    }
-
-    return 0;
-}
-
-/**
- * Adds information about derived files to the database.  Derived files typically come
- * from archives and may be compressed.
- * 
- * @param name The name of the file.
- * @param parentId The id of the file from which this file is derived.
- * @param isDirectory True if a directory
- * @param size The size of the file.
- * @param details This is a string that may contain extra details related
- * to the particular type of mechanism that was used to derive this file, 
- * e.g. files derived from zip archives may have extra information about the
- * compressed size of the file.
- * @param ctime Time file system file entry was changed.
- * @param crtime Time the file was created.
- * @param atime Last access time.
- * @param mtime Last modified time.
- * @param fileId Return the file_id value.
- * @param path Path of the file
- *
- * @returns 0 on success or -1 on error.
- */
-int TskImgDBPostgreSQL::addDerivedFileInfo(const std::string& name, const uint64_t parentId, 
-                                           const bool isDirectory, const uint64_t size,
-                                           const std::string& details,
-                                           const int ctime, const int crtime, const int atime, const int mtime,
-                                           uint64_t &fileId, std::string path)
-{
-    if (!initialized())
-        return -1;
-
-    // Ensure that strings are valid UTF-8
-    std::vector<char> cleanName(name.begin(), name.end());
-    cleanName.push_back('\0');
-    TskUtilities::cleanUTF8(&cleanName[0]);
-
-    std::vector<char> cleanDetails(details.begin(), details.end());
-    cleanDetails.push_back('\0');
-    TskUtilities::cleanUTF8(&cleanDetails[0]);
-
-    std::vector<char> cleanPath(path.begin(), path.end());
-    cleanPath.push_back('\0');
-    TskUtilities::cleanUTF8(&cleanPath[0]);
-
-    TSK_FS_NAME_TYPE_ENUM dirType = isDirectory ? TSK_FS_NAME_TYPE_DIR : TSK_FS_NAME_TYPE_REG;
-    TSK_FS_META_TYPE_ENUM metaType = isDirectory ? TSK_FS_META_TYPE_DIR : TSK_FS_META_TYPE_REG;
-
-    std::stringstream stmt;
-
-    stmt << "INSERT INTO files (file_id, type_id, name, par_file_id, dir_type, meta_type, size, ctime, crtime, atime, mtime, status, full_path) "
-        "VALUES (DEFAULT, " << IMGDB_FILES_TYPE_DERIVED << ", " << m_dbConnection->quote(&cleanName[0]) << ", " << parentId << ", " << dirType << ", " << metaType << ", " << size
-        << ", " << ctime << ", " << crtime << ", " << atime << ", " << mtime << ", " << IMGDB_FILES_STATUS_CREATED << ", E" << m_dbConnection->quote(&cleanPath[0]) << ")";
-
-    try
-    {
-        pqxx::work W(*m_dbConnection);
-        pqxx::result R = W.exec(stmt);
-
-        // get the file_id from the last insert
-        stmt.str("");
-        stmt << "SELECT currval(pg_get_serial_sequence('files', 'file_id'))";
-        R = W.exec(stmt);
-
-        fileId = R[0][0].as<uint64_t>();
-
-        stmt.str("");
-
-        // insert into the derived_files table
-        stmt << "INSERT INTO derived_files (file_id, derivation_details) VALUES ("
-            << fileId << ", E" << m_dbConnection->quote(&cleanDetails[0]) << ")";
-
-        R = W.exec(stmt);
-        W.commit();
-    }
-    catch (exception& ex)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::addDerivedFileInfo - Error adding derived file data: "
-            << ex.what();
-        LOGERROR(errorMsg.str());
-
-        return -1;
-    }
-
-    return 0;
-}
-
-/**
- * Fills outBuffer with file IDs that match the name fileName.
- * Returns the number of file IDs written into outBuffer or -1 on error.
- */
-int TskImgDBPostgreSQL::getFileIds(char *a_fileName, uint64_t *a_outBuffer, int a_buffSize) const
-{
-    if (!initialized())
-        return -1;
-
-    int outIdx = 0;
-    stringstream stmt;
-
-    stmt << "SELECT file_id FROM files WHERE name LIKE "
-        << m_dbConnection->quote(a_fileName);
-
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-
-        if (R.size() > a_buffSize)
-        {
-            std::wstringstream errorMsg;
-            errorMsg << L"TskImgDBPostgreSQL::getFileIds - Number of file ids returned ("
-                << R.size() << ") is greated than buffer capacity (" << a_buffSize << ")";
-            LOGERROR(errorMsg.str());
-            return -1;
-        }
-
-        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
-        {
-            i[0].to(a_outBuffer[outIdx++]);
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getFileIds - Error getting file ids : "
-            << e.what();
-        LOGERROR(errorMsg.str());
-
-        return -1;
-    }
-
-    return outIdx;
-}
-
-/**
- * Given the last file ID ready for analysis, find the largest file ID ready of analysis (in maxFileId)
- * Returns 0 on success or -1 on error.
- */
-int TskImgDBPostgreSQL::getMaxFileIdReadyForAnalysis(uint64_t a_lastFileId, uint64_t & maxFileId) const
-{
-    if (!initialized())
-        return -1;
-
-    maxFileId = 0;
-    stringstream stmt;
-
-    stmt << "SELECT max(file_id) FROM files WHERE status = " << TskImgDB::IMGDB_FILES_STATUS_READY_FOR_ANALYSIS
-        << " AND file_id >= " << a_lastFileId;
-
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-
-        if (R.size() == 1)
-        {
-            R[0][0].to(maxFileId);
-        }
-        else
-        {
-            std::wstringstream errorMsg;
-            errorMsg << L"TskImgDBPostgreSQL::getMaxFileIdReadyForAnalysis - Unexpected number of rows returned."
-                << R.size();
-            LOGERROR(errorMsg.str());
-            return -1;
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getMaxFileIdReadyForAnalysis - Error retrieving maximum file id: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-
-        return -1;
-    }
-
-    return 0;
-}
-
-/*
- * Return the minimum file id with status = READY_FOR_ANALYSIS in minFileId.
- * Return 0 on success, -1 if failed.
- */
-int TskImgDBPostgreSQL::getMinFileIdReadyForAnalysis(uint64_t & minFileId) const
-{
-    if (!initialized())
-        return -1;
-
-    minFileId = 0;
-    stringstream stmt;
-
-    stmt << "SELECT min(file_id) FROM files WHERE status = " << TskImgDB::IMGDB_FILES_STATUS_READY_FOR_ANALYSIS;
-
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-
-        if (R.size() == 1)
-        {
-            R[0][0].to(minFileId);
-        }
-        else
-        {
-            std::wstringstream errorMsg;
-            errorMsg << L"TskImgDBPostgreSQL::getMinFileIdReadyForAnalysis - Unexpected number of rows returned."
-                << R.size();
-            LOGERROR(errorMsg.str());
-            return -1;
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getMinFileIdReadyForAnalysis - Error retrieving minimum file id: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-
-        return -1;
-    }
-
-    return 0;
-}
-
-SectorRuns * TskImgDBPostgreSQL::getFileSectors(uint64_t a_fileId) const 
-{
-    if (!initialized())
-        return NULL;
-
-    SectorRuns * sr = new SectorRuns();
-    int srCount = 0;
-
-    stringstream stmt;
-
-    stmt << "SELECT fs_blocks.blk_start, fs_blocks.blk_len, "
-        "fs_info.block_size, fs_info.img_byte_offset, fs_info.vol_id "
-        "FROM files "
-        "JOIN fs_files ON files.file_id = fs_files.file_id "
-        "JOIN fs_blocks ON files.file_id = fs_blocks.file_id "
-        "JOIN fs_info ON fs_blocks.fs_id = fs_info.fs_id "
-        "WHERE files.file_id = " << a_fileId << " ORDER BY fs_blocks.seq;";
-
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-
-        for (pqxx::result::const_iterator i = R.begin(); i!= R.end(); ++i)
-        {
-            uint64_t blkStart; i[0].to(blkStart);
-            uint64_t blkLength; i[1].to(blkLength);
-            int blkSize; i[2].to(blkSize);
-            uint64_t imgByteOffset; i[3].to(imgByteOffset);
-            int volId; i[4].to(volId);
-
-            uint64_t start = (imgByteOffset + blkStart * blkSize) / 512;
-            uint64_t len = (blkLength * blkSize) / 512;
-
-            sr->addRun(start, len, volId);
-            srCount++;
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getFileSectors - Error finding block data for file_id= " << a_fileId
-            << e.what() << std::endl;
-        LOGERROR(errorMsg.str());
-
-        return NULL;
-    }
-
-    return sr;
-}
-
-/**
- * update the status field in the database for a given file.
- * @param a_file_id File to update.
- * @param a_status Status flag to update to.
- * @returns 1 on error.
- */
-int TskImgDBPostgreSQL::updateFileStatus(uint64_t a_file_id, TskImgDB::FILE_STATUS a_status)
-{
-    if (!initialized())
-        return 1;
-
-    stringstream stmt;
-
-    stmt << "UPDATE files SET status = " << a_status << " WHERE file_id = " << a_file_id;
-
-    try
-    {
-        work W(*m_dbConnection);
-        result R = W.exec(stmt);
-        W.commit();
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::updateFileStatus - Error updating file status: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-
-        return 1;
-    }
-
-    return 0;
-}
-
-/**
- * update the known status field in the database for a given file.
- * @param a_file_id File to update.
- * @param a_status Status flag to update to.
- * @returns 1 on error.
- */
-int TskImgDBPostgreSQL::updateKnownStatus(uint64_t a_file_id, TskImgDB::KNOWN_STATUS a_status)
-{
-    if (!initialized())
-        return 1;
-
-    stringstream stmt;
-
-    stmt << "SELECT known FROM file_hashes WHERE file_id = " << a_file_id;
-
-    try
-    {
-        int status;
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-        pqxx::result::const_iterator i = R.begin(); 
-        if(R.size() != 0)
-            i[0].to(status);
-        else
-            status = TskImgDB::IMGDB_FILES_UNKNOWN;
-        trans.commit();
-
-        if((status == TskImgDB::IMGDB_FILES_UNKNOWN) ||
-           (a_status == TskImgDB::IMGDB_FILES_KNOWN_BAD) ||
-           (status == TskImgDB::IMGDB_FILES_KNOWN && a_status == TskImgDB::IMGDB_FILES_KNOWN_GOOD)){
-            stmt.str("");
-            stmt << "UPDATE file_hashes SET known = " << a_status << " WHERE file_id = " << a_file_id;
-
-            work W(*m_dbConnection);
-            R = W.exec(stmt);
-            W.commit();
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::updateKnownStatus - Error updating file status: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-
-        return 1;
-    }
-
-    return 0;
-}
-
-bool TskImgDBPostgreSQL::dbExist() const
-{
-    bool rc = false;
-
-    // Get current user name. This will get used in connecting to the database.
-    char name[UNLEN+1];
-    DWORD size = UNLEN+1;
-
-    GetUserNameA(name, &size);
-
-    std::string db_host = GetSystemProperty(TskSystemProperties::DB_HOST);
-    std::string db_port = GetSystemProperty(TskSystemProperties::DB_PORT);
-    std::string db_host_ip;
-    if (!TskUtilities::getHostIP(db_host, db_host_ip))
-        return false;
-
-    try
-    {
-        // Construct the connection string to connect to the Postgres server.
-        std::stringstream pgConnectionString;
-        pgConnectionString << "host='" << db_host_ip << "' port='" << db_port
-            << "' dbname='postgres' user='" << name << "'";
-
-        pqxx::connection pgConnection(pgConnectionString.str());
-
-        // Check whether the database exists
-        pqxx::nontransaction nontrans(pgConnection);
-
-        std::stringstream dbQuery;
-        dbQuery << "select count(*) from pg_catalog.pg_database where datname = " << nontrans.quote(m_dbName);
-
-        pqxx::result R = nontrans.exec(dbQuery);
-
-        if (R.size() == 0 || R[0][0].as<int>() == 0) 
-        {
-            // There is no database.
-            ;
-        } else {
-            rc = true;
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskDBPostgreSQL::dbExist - Error pg_database where datname= " << m_dbName.c_str() << " Error: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-    }
-    return rc;
-}
-
-void TskImgDBPostgreSQL::getCarvedFileInfo(const std::string& stmt,
-                                           std::map<uint64_t, std::string>& results) const
-{
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-        uint64_t file_id;
-        std::string cfileName;
-        std::string fileName;
-        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
-        {
-            i[0].to(file_id);
-            i[1].to(fileName);
-            i[2].to(cfileName);
-
-            // Grab the extension and append it to the cfile name
-            std::string::size_type pos = fileName.rfind('.');
-            if (pos != std::string::npos)
-                cfileName.append(fileName.substr(pos));
-
-            results[file_id] = cfileName;
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream msg;
-        msg << L"TskImgDBPostgreSQL::getCarvedFileInfo - Error getting carved file details : "
-            << e.what();
-        LOGERROR(msg.str());
-    }
-}
-
-std::map<uint64_t, std::string> TskImgDBPostgreSQL::getUniqueCarvedFiles(HASH_TYPE hashType) const
-{
-    std::map<uint64_t, std::string> results;
-
-    if (!initialized())
-        return results;
-
-    string hash;
-    switch (hashType) {
-    case TskImgDB::MD5:
-        hash = "md5";
-        break;
-    case TskImgDB::SHA1:
-        hash = "sha1";
-        break;
-    case TskImgDB::SHA2_256:
-        hash = "sha2_256";
-        break;
-    case TskImgDB::SHA2_512:
-        hash = "sha2_512";
-        break;
-    default:
-        std::wstringstream msg;
-        msg << L"TskImgDBPostgreSQL::getUniqueCarvedFiles - Unsupported hashType : " << hashType;
-        LOGERROR(msg.str());
-        return results;
-    }
-
-    std::stringstream stmt;
-
-    // If hashes have not been calculated return all carved files.
-    stmt << "select count(*) from file_hashes";
-
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-        uint64_t counter = 0;
-        if (R.size() == 1)
-            counter = R[0][0].as<uint64_t>();
-        if (counter == 0) 
-        {
-            std::wstringstream msg;
-            msg << L"TskImgDBPostgreSQL::getUniqueCarvedFiles - file_hashes table is empty";
-            LOGWARN(msg.str());
-
-            trans.commit();
-
-            stmt.str("");
-            stmt << "select c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' "
-                << "|| c.file_id from files f, carved_files c, carved_sectors cs "
-                << "where c.file_id = cs.file_id and cs.seq = 0 and f.file_id = c.file_id order by c.file_id";
-            getCarvedFileInfo(stmt.str(), results);
-            return results;
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream msg;
-        msg << L"TskImgDBPostgreSQL::getUniqueCarvedFileIds - Error getting file_hashes count : "
-            << e.what();
-        LOGERROR(msg.str());
-    }
-
-    stmt.str("");
-    // Get the set of files for which the hash has been calculated.
-    stmt << "select c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' "
-        << "|| c.file_id from files f, carved_files c, carved_sectors cs "
-        << "where c.file_id = cs.file_id and cs.seq = 0 and f.file_id = c.file_id and c.file_id in "
-        << "(select min(file_id) from file_hashes where " << hash << " != '' group by " << hash << " ) order by c.file_id";
-
-    getCarvedFileInfo(stmt.str(), results);
-
-    // Next get the set of files for which the hash has *not* been calculated.
-    stmt.str("");
-    stmt << "select c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' "
-        << "|| c.file_id from files f, carved_files c, carved_sectors cs "
-        << "where c.file_id = cs.file_id and cs.seq = 0 and f.file_id = c.file_id and c.file_id in "
-        << "(select file_id from file_hashes where " << hash << " = '') order by c.file_id";
-
-    getCarvedFileInfo(stmt.str(), results);
-
-    // Finally, add file info for all of the carved files for which there are no hashes of any sort.
-        // All of these files must be included because without hashes there is no way to determine uniqueness.
-    stmt.clear();
-    stmt.str("");
-    stmt << "SELECT c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || c.file_id "
-         << "FROM files f, carved_files c, carved_sectors cs "
-         << "WHERE c.file_id = cs.file_id AND cs.seq = 0 AND f.file_id = c.file_id AND c.file_id NOT IN "
-         << "(SELECT fh.file_id FROM file_hashes fh) ORDER BY c.file_id";
-    getCarvedFileInfo(stmt.str(), results);
-
-    return results;
-}
-
-void TskImgDBPostgreSQL::getCarvedFileInfo(const std::string &stmtToExecute, bool getHash, std::vector<TskCarvedFileInfo> &carvedFileInfos) const
-{
-    TskCarvedFileInfo info;
-    std::string fileName;
-    pqxx::read_transaction trans(*m_dbConnection);
-    pqxx::result result = trans.exec(stmtToExecute);
-    for (pqxx::result::const_iterator row = result.begin(); row != result.end(); ++row)
-    {
-        row[0].to(info.fileID);
-        row[1].to(fileName);
-        row[2].to(info.cFileName);
-        if (getHash)
-        {
-            row[3].to(info.hash);
-        }
-
-        // Append the extension from the original file name to the constructed "cfile" name.
-        std::string::size_type pos = fileName.rfind('.');
-        if (pos != std::string::npos)
-        {
-            info.cFileName.append(fileName.substr(pos));
-        }
-
-        carvedFileInfos.push_back(info);
-    }
-}
-
-std::vector<TskCarvedFileInfo> TskImgDBPostgreSQL::getUniqueCarvedFilesInfo(HASH_TYPE hashType) const
-{
-    const std::string msgPrefix = "TskImgDBPostgreSQL::getUniqueCarvedFilesInfo : "; 
-
-    if (!initialized())
-    {
-        std::ostringstream msg;
-        msg << msgPrefix << "no database connection";
-        throw TskException(msg.str());
-    }
-
-    // Map the hash type to a file_hashes table column name.
-    string hash;
-    switch (hashType) 
-    {
-    case TskImgDB::MD5:
-        hash = "md5";
-        break;
-    case TskImgDB::SHA1:
-        hash = "sha1";
-        break;
-    case TskImgDB::SHA2_256:
-        hash = "sha2_256";
-        break;
-    case TskImgDB::SHA2_512:
-        hash = "sha2_512";
-        break;
-    default:
-        std::ostringstream msg;
-        msg << msgPrefix << "unsupported hash type :" << hashType;
-        throw TskException(msg.str());
-    }
-
-    try
-    {
-        std::vector<TskCarvedFileInfo> carvedFileInfos;
-
-        // Do a quick check to see if any hashes have been calculated.
-        std::ostringstream stmt;
-        stmt << "SELECT COUNT(*) FROM file_hashes;";
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result result = trans.exec(stmt.str());
-        uint64_t counter = 0;
-        if (result.size() == 1)
-        {
-            counter = result[0][0].as<uint64_t>();
-        }
-        trans.commit();
-
-        if (counter != 0)
-        {
-            // At least one type of hash has been calculated (presumably for all files, but this is not guaranteed). 
-            // First, add file info for the set of unique files among the carved files for which the specified type of hash is available.
-            stmt.clear();
-            stmt.str("");
-            stmt << "SELECT c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || c.file_id, fh." << hash << " "
-                 << "FROM files f, carved_files c, carved_sectors cs, file_hashes fh "
-                 << "WHERE c.file_id = cs.file_id AND cs.seq = 0 AND f.file_id = c.file_id AND c.file_id = fh.file_id AND c.file_id IN "
-                 << "(SELECT MIN(file_id) FROM file_hashes WHERE " << hash << " != '' GROUP BY " << hash << ") ORDER BY c.file_id";
-            getCarvedFileInfo(stmt.str(), true, carvedFileInfos);
-
-             // Next, add file info for all of the carved files for which the specified hash is not available.
-             // All of these files must be included because without the specified hash there is no acceptable way to determine uniqueness.
-            stmt.clear();
-            stmt.str("");
-            stmt << "SELECT c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || c.file_id "
-                 << "FROM files f, carved_files c, carved_sectors cs "
-                 << "WHERE c.file_id = cs.file_id AND cs.seq = 0 AND f.file_id = c.file_id AND c.file_id IN "
-                 << "(SELECT file_id FROM file_hashes WHERE " << hash << " = '') ORDER BY c.file_id";
-            getCarvedFileInfo(stmt.str(), false, carvedFileInfos);
-
-            // Finally, add file info for all of the carved files for which there are no hashes of any sort.
-             // All of these files must be included because without hashes there is no way to determine uniqueness.
-            stmt.clear();
-            stmt.str("");
-            stmt << "SELECT c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || c.file_id "
-                 << "FROM files f, carved_files c, carved_sectors cs "
-                 << "WHERE c.file_id = cs.file_id AND cs.seq = 0 AND f.file_id = c.file_id AND c.file_id NOT IN "
-                 << "(SELECT fh.file_id FROM file_hashes fh) ORDER BY c.file_id";
-            getCarvedFileInfo(stmt.str(), false, carvedFileInfos);
-        }
-        else
-        {
-            // No hashes have been calculated.
-            // Return carved file info all of the carved files because without hashes there is no way to determine uniqueness.
-            stmt.clear();
-            stmt.str("");
-            stmt << "SELECT c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || c.file_id "
-                 << "FROM files f, carved_files c, carved_sectors cs "
-                 << "WHERE c.file_id = cs.file_id AND cs.seq = 0 AND f.file_id = c.file_id ORDER BY c.file_id";
-            getCarvedFileInfo(stmt.str(), false, carvedFileInfos);
-
-            std::ostringstream msg;
-            msg << msgPrefix << "no hashes available, returning all carved files";
-            LOGWARN(msg.str());
-        }
-
-        return carvedFileInfos;
-    }
-    catch (std::exception &ex)
-    {
-        std::stringstream msg;
-        msg << msgPrefix << "std::exception: " << ex.what();
-        throw TskException(msg.str());
-    }
-    catch (...)
-    {
-        throw TskException(msgPrefix + "unrecognized exception");
-    }
-}
-
-std::vector<uint64_t> TskImgDBPostgreSQL::getCarvedFileIds() const
-{
-    return getFileIdsWorker("carved_files");
-}
-
-std::vector<uint64_t> TskImgDBPostgreSQL::getUniqueFileIds(HASH_TYPE hashType) const
-{
-    std::vector<uint64_t> results;
-
-    if (!initialized())
-        return results;
-
-    string hash;
-    switch (hashType) {
-    case TskImgDB::MD5:
-        hash = "md5";
-        break;
-    case TskImgDB::SHA1:
-        hash = "sha1";
-        break;
-    case TskImgDB::SHA2_256:
-        hash = "sha2_256";
-        break;
-    case TskImgDB::SHA2_512:
-        hash = "sha2_512";
-        break;
-    default:
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getUniqueFileIds - Unsupported hashType : " << hashType;
-        LOGERROR(errorMsg.str());
-        return results;
-    }
-
-    stringstream stmt;
-
-    stmt << "SELECT min(file_id) FROM file_hashes WHERE " << hash << " != '' group by " << hash ;
-
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-        uint64_t file_id;
-        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
-        {
-            i[0].to(file_id);
-            results.push_back(file_id);
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getUniqueFileIds - Error getting file ids : "
-            << e.what();
-        LOGERROR(errorMsg.str());
-    }
-
-    // Get all carved_files with empty hash, if hash was not generated.
-    stmt << "SELECT file_id FROM file_hashes WHERE " << hash << " = '' ";
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-        uint64_t file_id;
-        uint64_t counter = 0;
-        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
-        {
-            i[1].to(file_id);
-            results.push_back(file_id);
-            counter++;
-        }
-        if (counter) {
-            // There are some files without hash, generate a warning.
-            std::wstringstream errorMsg;
-            errorMsg << L"TskImgDBPostgreSQL::getUniqueFileIds - Including " << counter << L" files with no hash value.";
-            LOGWARN(errorMsg.str());
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getUniqueFileIds - Error getting file ids : "
-            << e.what();
-        LOGERROR(errorMsg.str());
-    }
-    return results;
-}
-
-/**
- * Get the list of file ids that match the given criteria.
- * The given string will be appended to "select files.file_id from files".
- *
- * @param condition Must be a valid SQL string defining the selection criteria.
- * @returns The collection of file ids matching the selection criteria. Throws
- * TskException if database not initialized.
- */
-std::vector<uint64_t> TskImgDBPostgreSQL::getFileIds(std::string& condition) const 
-{
-    if (!initialized())
-        throw TskException("Database not initialized.");
-
-    std::vector<uint64_t> results;
-    
-    std::string stmt("SELECT files.file_id from files");
-
-    constructStmt(stmt, condition);
-
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-        uint64_t file_id;
-        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
-        {
-            i[0].to(file_id);
-            results.push_back(file_id);
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getFileIds - Error getting file ids : "
-            << e.what();
-        LOGERROR(errorMsg.str());
-    }
-
-    return results;
-}
-
-/**
- * Get the list of file records that match the given criteria.
- * The given string will be appended to "select .... from files".
- *
- * @param condition Must be a valid SQL string defining the selection criteria.
- * @returns The collection of file records matching the selection criteria. Throws
- * TskException if database not initialized.
- */
-std::vector<const TskFileRecord> TskImgDBPostgreSQL::getFileRecords(std::string& condition) const 
-{
-    if (!initialized())
-        throw TskException("Database not initialized.");
-
-    std::vector<const TskFileRecord> results;
-    
-    std::stringstream stmtstrm;
-    stmtstrm << "SELECT f.file_id, f.type_id, f.name, f.par_file_id, f.dir_type, f.meta_type, f.dir_flags, "
-        << "f.meta_flags, f.size, f.ctime, f.crtime, f.atime, f.mtime, f.mode, f.uid, f.gid, f.status, f.full_path, "
-        << "fh.md5, fh.sha1, fh.sha2_256, fh.sha2_512 "
-        << "FROM files f LEFT OUTER JOIN file_hashes fh ON f.file_id = fh.file_id ";
-
-    std::string stmt = stmtstrm.str();
-
-    constructStmt(stmt, condition);
-
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
-        {
-            TskFileRecord fileRecord;
-            
-            i[0].to(fileRecord.fileId);
-            i[1].to((int &)fileRecord.typeId);
-            i[2].to(fileRecord.name);
-            i[3].to(fileRecord.parentFileId);
-            i[4].to((int &)fileRecord.dirType);
-            i[5].to((int &)fileRecord.metaType);
-            i[6].to((int &)fileRecord.dirFlags);
-            i[7].to((int &)fileRecord.metaFlags);
-            i[8].to(fileRecord.size);
-            i[9].to(fileRecord.ctime);
-            i[10].to(fileRecord.crtime);
-            i[11].to(fileRecord.atime);
-            i[12].to(fileRecord.mtime);
-            i[13].to((int &)fileRecord.mode);
-            i[14].to(fileRecord.uid);
-            i[15].to(fileRecord.gid);
-            i[16].to((int &)fileRecord.status);
-            i[17].to(fileRecord.fullPath);
-            i[18].to(fileRecord.md5);
-            i[19].to(fileRecord.sha1);
-            i[20].to(fileRecord.sha2_256);
-            i[21].to(fileRecord.sha2_512);   
-            results.push_back(fileRecord);
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getFileRecords - Error getting file records: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-    }
-
-    return results;
-}
-
-/**
- * Get the number of files that match the given criteria.
- * The given string will be appended to "select files.file_id from files".
- *
- * @param condition Must be a valid SQL string defining the selection criteria.
- * @returns The number of files matching the selection criteria. 
- */
-int TskImgDBPostgreSQL::getFileCount(std::string& condition) const 
-{
-    if (!initialized())
-        throw TskException("Database not initialized.");
-
-    int result = 0;
-    std::string stmt("SELECT count(files.file_id) from files");
-
-    constructStmt(stmt, condition);
-
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-
-        if (R.size() == 1)
-        {
-            R[0][0].to(result);
-        }
-        else
-        {
-            std::wstringstream msg;
-            msg << L"TskImgDBPostgreSQL::getFileCount - Unexpected number of rows returned."
-                << R.size();
-            LOGERROR(msg.str());
-
-            return -1;
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream msg;
-        msg << L"TskImgDBPostgreSQL::getFileCount - Error getting file count : "
-            << e.what();
-        LOGERROR(msg.str());
-        return -1;
-    }
-
-    return result;
-}
-
-
-
-void TskImgDBPostgreSQL::constructStmt(std::string& stmt, std::string& condition) const
-{
-    if (!condition.empty())
-    {
-        // Remove leading whitespace from condition
-        std::string trimmedCond = Poco::trimLeft(condition);
-
-        std::string whereClause("WHERE");
-        std::string joinClause("JOIN");
-        std::string leftClause("LEFT");
-        std::string orderClause("ORDER");
-
-        // If the condition doesn't start with a WHERE clause and it doesn't
-        // start with a comma it is presumably extending the FROM clause with
-        // one or more table names. In this case we need to add the comma to
-        // the statement.
-        if (Poco::icompare(trimmedCond, 0, whereClause.length(), whereClause) != 0 
-            && Poco::icompare(trimmedCond, 0, joinClause.length(), joinClause) != 0
-            && Poco::icompare(trimmedCond, 0, leftClause.length(), leftClause) != 0
-            && Poco::icompare(trimmedCond, 0, orderClause.length(), orderClause) != 0
-            && trimmedCond[0] != ',')
-        {
-            stmt.append(",");
-        }
-    }
-
-    stmt.append(" ");
-    stmt.append(condition);
-}
-
-std::vector<uint64_t> TskImgDBPostgreSQL::getFileIds() const
-{
-    return getFileIdsWorker("files");
-}
-
-std::vector<uint64_t> TskImgDBPostgreSQL::getFileIdsWorker(std::string tableName, const std::string condition) const
-{
-    std::vector<uint64_t> results;
-
-    if (!initialized())
-        return results;
-
-    stringstream stmt;
-    stmt << "SELECT file_id FROM " << tableName;
-    if (condition.compare("") != 0)
-        stmt << " WHERE " << condition;
-    stmt << " ORDER BY file_id";
-
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-        uint64_t file_id;
-        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
-        {
-            i[0].to(file_id);
-            results.push_back(file_id);
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        std::wstring wTableName;
-        Poco::UnicodeConverter::toUTF16(tableName, wTableName);
-        errorMsg << L"TskImgDBPostgreSQL::getFileIdsWorker - Error getting file ids from " << wTableName << " : "
-            << e.what();
-        LOGERROR(errorMsg.str());
-    }
-
-    return results;
-}
-
-// Set file hash for hashType for a_file_id
-// Return 1 on failure, 0 on success.
-int TskImgDBPostgreSQL::setHash(const uint64_t a_file_id, const TskImgDB::HASH_TYPE hashType, const std::string& hash) const
-{
-    if (!initialized())
-        return 1;
-
-    string hashTypeStr;
-    switch (hashType) {
-    case TskImgDB::MD5:
-        hashTypeStr = "md5";
-        break;
-    case TskImgDB::SHA1:
-        hashTypeStr = "sha1";
-        break;
-    case TskImgDB::SHA2_256:
-        hashTypeStr = "sha2_256";
-        break;
-    case TskImgDB::SHA2_512:
-        hashTypeStr = "sha2_512";
-        break;
-    default:
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::setHash - Unsupported hashType : " << hashType;
-        LOGERROR(errorMsg.str());
-        return 1;
-    }
-
-    stringstream stmt;
-    bool found = false;
-    std::string md5, sha1, sha2_256, sha2_512;
-    int known = IMGDB_FILES_UNKNOWN;
-    std::stringstream stream;
-
-    stmt << "SELECT md5, sha1, sha2_256, sha2_512, known from file_hashes WHERE file_id = " << a_file_id;
-    try 
-    {
-        pqxx::read_transaction W(*m_dbConnection);
-        result R = W.exec(stmt);
-        if (R.size() == 1) {
-            R[0][0].to(md5);
-            R[0][1].to(sha1);
-            R[0][2].to(sha2_256);
-            R[0][3].to(sha2_512);
-            R[0][4].to(known);
-            found = true;
-        }
-    }
-    catch (const exception&)
-    {
-        ; // ok to fail if file_id don't exist
-    }
-
-    if (found) {
-        // delete existing record
-        stmt.str("");
-        stmt << "DELETE FROM file_hashes WHERE file_id=" << a_file_id;
-        try
-        {
-            pqxx::work W(*m_dbConnection);
-            pqxx::result R = W.exec(stmt);
-            W.commit();
-        }
-        catch (const exception &e)
-        {
-            std::wstringstream errorMsg;
-            errorMsg << L"TskImgDBPostgreSQL::setHash - DELETE " << hashType << L" failed: " << e.what();
-            LOGERROR(errorMsg.str());
-            return 1;
-        }
-
-    }
-    // insert new record
-    stmt.str("");
-    stmt << "INSERT INTO file_hashes (file_id, md5, sha1, sha2_256, sha2_512, known) VALUES (" << a_file_id;
-    switch (hashType) {
-    case TskImgDB::MD5:
-        stmt << ", '" << hash << "'";
-        stmt << ", '" << sha1 << "'";
-        stmt << ", '" << sha2_256 << "'";
-        stmt << ", '" << sha2_512 << "'";
-        stream << known;
-        stmt << ", " << stream.str();
-        break;
-    case TskImgDB::SHA1:
-        stmt << ", '" << md5 << "'";
-        stmt << ", '" << hash << "'";
-        stmt << ", '" << sha2_256 << "'";
-        stmt << ", '" << sha2_512 << "'";
-        stream << known;
-        stmt << ", " << stream.str();
-        break;
-    case TskImgDB::SHA2_256:
-        stmt << ", '" << md5 << "'";
-        stmt << ", '" << sha1 << "'";
-        stmt << ", '" << hash << "'";
-        stmt << ", '" << sha2_512 << "'";
-        stream << known;
-        stmt << ", " << stream.str();
-        break;
-    case TskImgDB::SHA2_512:
-        stmt << ", '" << md5 << "'";
-        stmt << ", '" << sha1 << "'";
-        stmt << ", '" << sha2_256 << "'";
-        stmt << ", '" << hash << "'";
-        stream << known;
-        stmt << ", " << stream.str();
-        break;
-    }
-    stmt << ")";
-
-    try
-    {
-        work W(*m_dbConnection);
-        result R = W.exec(stmt);
-        W.commit();
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskDBPostgreSQL::setHash - INSERT failed: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-        return 1;
-    }
-    return 0;
-}
-
-std::string TskImgDBPostgreSQL::getCfileName(uint64_t a_file_id) const
-{
-    std::string cfileName;
-
-    if (!initialized())
-        return cfileName;
-
-    stringstream stmt;
-
-    stmt << "select 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || f.file_id"
-        " from files f, carved_files c, carved_sectors cs where f.file_id = c.file_id and c.file_id = cs.file_id and cs.seq = 0"
-        " and f.file_id = " << a_file_id;
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
-        {
-            cfileName = (char *)i[0].c_str();
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getCfileName - Error getting CFileName for file id " << a_file_id << " : "
-            << e.what();
-        LOGERROR(errorMsg.str());
-    }
-
-    stmt.str("");
-    stmt << "select f.name "
-        " from files f, carved_files c, carved_sectors cs where f.file_id = c.file_id and c.file_id = cs.file_id and cs.seq = 0"
-        " and f.file_id = " << a_file_id;
-    std::string name;
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
-        {
-            name = (char *)i[0].c_str();
-            int pos = name.rfind('.');
-            if (pos != string::npos)
-                cfileName += name.substr(pos);
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getCfileName - Error getting CFileName for file id " << a_file_id << " : "
-            << e.what();
-        LOGERROR(errorMsg.str());
-    }
-
-    return cfileName;
-}
-
-/**
- * Return the ImageInfo
- * @param type Image Type (output)
- * @param sectorSize Image sector size (output)
- * @returns 0 on success or -1 on error.
- */
-int TskImgDBPostgreSQL::getImageInfo(int & type, int & sectorSize) const
-{
-    int result = -1;
-
-    if (!initialized())
-        return result;
-
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec("SELECT type, ssize from image_info");
-
-        if (R.size() == 1)
-        {
-            R[0][0].to(type);
-            R[0][1].to(sectorSize);
-            result = 0;
-        }
-        else
-        {
-            std::wstringstream errorMsg;
-            errorMsg << L"TskImgDBPostgreSQL::getImageInfo - Unexpected number of rows returned."
-                << R.size();
-            LOGERROR(errorMsg.str());
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getImageInfo - Error getting image_info: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-    }
-    return result;
-}
-
-/**
- * Return a list of TskVolumeInfoRecord
- * @param volumeInfoList A list of TskVolumeInfoRecord (output)
- * @returns 0 on success or -1 on error.
- */
-int TskImgDBPostgreSQL::getVolumeInfo(std::list<TskVolumeInfoRecord> & volumeInfoList) const
-{
-    int rc = -1;
-
-    if (!initialized())
-        return rc;
-
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec("SELECT vol_id, sect_start, sect_len, description, flags FROM vol_info");
-
-        for (result::size_type rownum=0; rownum < R.size(); ++rownum) {
-            const result::tuple row = R[rownum];
-            TskVolumeInfoRecord vol_info;
-            vol_info.vol_id = row[0].as<int>();
-            vol_info.sect_start = row[1].as<uint64_t>();
-            vol_info.sect_len = row[2].as<uint64_t>();
-            vol_info.description.assign(row[3].as<const char *>());
-            vol_info.flags = (TSK_VS_PART_FLAG_ENUM)row[4].as<int>();
-            volumeInfoList.push_back(vol_info);
-        }
-        rc = 0;
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getVolumeInfo - Error getting vol_info: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-    }
-    return rc;
-}
-
-/**
- * Return a list of TskFsInfoRecord
- * @param fsInfoList A list of TskFsInfoRecord (output)
- * @returns 0 on success or -1 on error.
- */
-int TskImgDBPostgreSQL::getFsInfo(std::list<TskFsInfoRecord> & fsInfoList) const
-{
-    int rc = -1;
-
-    if (!initialized())
-        return rc;
-
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec("SELECT fs_id, img_byte_offset, vol_id, fs_type, block_size, block_count, root_inum, first_inum, last_inum FROM fs_info");
-
-        for (result::size_type rownum=0; rownum < R.size(); ++rownum) {
-            const result::tuple row = R[rownum];
-            TskFsInfoRecord fs_info;
-            fs_info.fs_id = row[0].as<int>();
-            fs_info.img_byte_offset = row[1].as<uint64_t>();
-            fs_info.vol_id = row[2].as<int>();
-            fs_info.fs_type = (TSK_FS_TYPE_ENUM)row[3].as<int>();
-            fs_info.block_size = row[4].as<int>();
-            fs_info.block_count = row[5].as<uint64_t>();
-            fs_info.root_inum = row[6].as<uint64_t>();
-            fs_info.first_inum = row[7].as<uint64_t>();
-            fs_info.last_inum =  row[8].as<uint64_t>();
-            fsInfoList.push_back(fs_info);
-        }
-        rc = 0;
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getFsInfo - Error getting fs_info: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-    }
-    return rc;
-}
-
-typedef std::map<std::string, int> FileTypeMap_t;
-
-static std::string getFileType(const char *name)
-{
-    std::string filename = name;
-    int pos = filename.rfind('.');
-    if (pos != std::string::npos) {
-        std::string suffix = filename.substr(pos);
-        std::string result;
-        for (size_t i=0; i < suffix.size(); i++) {
-            result += (char)tolower(suffix[i]);
-        }
-        return result;
-    }
-    else
-        return std::string("");
-}
-
-/**
- * Return a list of TskFileTypeRecord for all files.
- * @param fileTypeInfoList A list of TskFileTypeRecord (output)
- * @returns 0 on success or -1 on error.
- */
-int TskImgDBPostgreSQL::getFileInfoSummary(std::list<TskFileTypeRecord> &fileTypeInfoList) const
-{
-    std::stringstream stmt;
-    stmt << "SELECT name FROM files WHERE dir_type = " << TSK_FS_NAME_TYPE_REG;
-
-    return getFileTypeRecords(stmt.str(), fileTypeInfoList);
-}
-
-/**
- * Return a list of TskFileTypeRecord for fileType
- * @param fileType FILE_TYPE to report
- * @param fileTypeInfoList A list of TskFileTypeRecord (output)
- * @returns 0 on success or -1 on error.
- */
-int TskImgDBPostgreSQL::getFileInfoSummary(FILE_TYPES fileType, std::list<TskFileTypeRecord> & fileTypeInfoList) const
-{
-    std::stringstream stmt;
-    stmt << "SELECT name FROM files WHERE type_id = " << fileType << " AND dir_type = " << TSK_FS_NAME_TYPE_REG;
-
-    return getFileTypeRecords(stmt.str(), fileTypeInfoList);
-}
-
-/**
- * Return a list of TskFileTypeRecords matching the given SQL statement.
- * @param stmt The SQL statement used to match file records.
- * @param fileTypeInfoList A list of TskFileTypeRecord (output)
- * @returns 0 on success of -1 on error.
- */
-int TskImgDBPostgreSQL::getFileTypeRecords(std::string& stmt, std::list<TskFileTypeRecord>& fileTypeInfoList) const
-{
-    int rc = -1;
-
-    if (!initialized())
-        return rc;
-
-    std::list<TskFileTypeRecord> list;
-
-    try {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt.c_str());
-        FileTypeMap_t fileTypeMap;
-
-        for (result::size_type rownum=0; rownum < R.size(); ++rownum) {
-            const result::tuple row = R[rownum];
-            const char* name = row[0].as<const char *>();
-            std::string type = getFileType(name);
-            FileTypeMap_t::iterator iter = fileTypeMap.find(type);
-            if (iter != fileTypeMap.end()) {
-                // increment file counter
-                int count = iter->second;
-                fileTypeMap[type] = ++count;
-            } else {
-                // add a new file type
-                fileTypeMap.insert(pair<std::string, int>(type, 1));
-            }
-        }
-        for (FileTypeMap_t::const_iterator iter=fileTypeMap.begin(); iter != fileTypeMap.end(); iter++) {
-            TskFileTypeRecord info;
-            info.suffix.assign((*iter).first.c_str());
-            info.count = (*iter).second;
-            info.description.assign("File Type Description");
-            fileTypeInfoList.push_back(info);
-        }
-        rc = 0;
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getFileTypeRecords - Error retrieving file type records: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-    }
-    return rc;
-}
-
-/**
- * Insert the Module record, if module name does not already exist in modules table.
- * Returns Module Id associated with the Module record.
- * @param name Module name
- * @param description Module description
- * @param moduleId Module Id (output)
- * @returns 0 on success, -1 on error.
- */
-int TskImgDBPostgreSQL::addModule(const std::string& name, const std::string& description, int & moduleId)
-{
-    if (!initialized())
-        return 0;
-
-    stringstream stmt;
-
-    stmt << "SELECT module_id FROM modules WHERE name = " << m_dbConnection->quote(name);
-
-    try 
-    {
-        work W(*m_dbConnection);
-        result R = W.exec(stmt);
-
-        if (R.size() == 1)
-        {
-            // Already exists, return module_id
-            R[0][0].to(moduleId);
-            return 0;
-        }
-
-        // Insert a new one
-        stmt.str("");
-        stmt << "INSERT INTO modules (module_id, name, description) VALUES (DEFAULT, " << m_dbConnection->quote(name) << ", " << m_dbConnection->quote(description) << ")";
-
-        R = W.exec(stmt);
-
-        // Get the newly assigned module id
-        stmt.str("");
-        stmt << "SELECT currval(pg_get_serial_sequence('modules', 'module_id'))";
-        R = W.exec(stmt);
-        R[0][0].to(moduleId);
-        W.commit();
-    } 
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskDBPostgreSQL::addModule - Error inserting into modules table: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-        return -1;
-    }
-
-    return 0;
-}
-
-/**
- * Insert the module status record.
- * @param file_id file_id
- * @param module_id module_id
- * @param status Status of module
- * @returns 0 on success, -1 on error.
- */
-int TskImgDBPostgreSQL::setModuleStatus(uint64_t file_id, int module_id, int status)
-{
-    int rc = -1;
-
-    if (!initialized())
-        return rc;
-
-    stringstream stmt;
-    stmt << "INSERT INTO module_status (file_id, module_id, status) VALUES (" << 
-        file_id << ", " <<
-        module_id << ", " <<
-        status << ")";
-    try
-    {
-        work W(*m_dbConnection);
-        result R = W.exec(stmt);
-        W.commit();
-        rc = 0;
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskDBPostgreSQL::setModuleStatus - Error adding data to module_status table: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-    }
-    return rc;
-}
-
-/**
- * Get a list of TskModuleStatus.
- * @param moduleInfoList A list of TskModuleInfo (output)
- * @returns 0 on success, -1 on error.
- */
-int TskImgDBPostgreSQL::getModuleInfo(std::vector<TskModuleInfo> & moduleInfoList) const
-{
-    int rc = -1;
-
-    if (!initialized())
-        return rc;
-
-    stringstream stmt;
-    stmt << "SELECT module_id, name, description FROM modules"
-         << " ORDER BY module_id";
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-        TskModuleInfo moduleInfo;
-        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
-        {
-            i[0].to(moduleInfo.module_id);
-            moduleInfo.module_name.assign(i[1].c_str());
-            moduleInfo.module_description.assign(i[2].c_str());
-            moduleInfoList.push_back(moduleInfo);
-        }
-        rc = 0;
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getModuleErrors - Error getting module_status: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-    }
-    return rc;
-}
-
-/**
- * Get a list of TskModuleStatus.
- * @param moduleStatusList A list of TskModuleStatus (output)
- * @returns 0 on success, -1 on error.
- */
-int TskImgDBPostgreSQL::getModuleErrors(std::vector<TskModuleStatus> & moduleStatusList) const
-{
-    int rc = -1;
-
-    if (!initialized())
-        return rc;
-
-    stringstream stmt;
-    stmt << "SELECT f.file_id, m.name, ms.status FROM module_status ms, files f, modules m"
-         << " WHERE ms.status != 0 AND ms.file_id = f.file_id AND m.module_id = ms.module_id"
-         << " ORDER BY f.file_id";
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-        TskModuleStatus moduleStatus;
-        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
-        {
-            i[0].to(moduleStatus.file_id);
-            moduleStatus.module_name.assign(i[1].c_str());
-            i[2].to(moduleStatus.status);
-            moduleStatusList.push_back(moduleStatus);
-        }
-        rc = 0;
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getModuleErrors - Error getting module_status: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-    }
-    // Find report module errors. These have file_id = 0.
-    stmt.str("");
-    stmt << "SELECT 0, m.name, ms.status FROM module_status ms, modules m"
-         << " WHERE ms.status != 0 AND ms.file_id = 0 AND m.module_id = ms.module_id";
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-        TskModuleStatus moduleStatus;
-        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
-        {
-            i[0].to(moduleStatus.file_id);
-            moduleStatus.module_name.assign(i[1].c_str());
-            i[2].to(moduleStatus.status);
-            moduleStatusList.push_back(moduleStatus);
-        }
-        rc = 0;
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getModuleErrors - Error getting module_status: "
-            << e.what();
-        LOGERROR(errorMsg.str());
-    }
-    return rc;
-}
-
-/*
- * Return a file name associated with a file_id, prefer Cfilename, otherwise name in the files table.
- * @param file_id file id
- * @returns file name as std::string
- */
-std::string TskImgDBPostgreSQL::getFileName(uint64_t file_id) const
-{
-    std::string name;
-
-    if (!initialized())
-        return name;
-
-    name = getCfileName(file_id);
-    if (name == "") {
-        TskFileRecord fileRecord;
-        if (getFileRecord(file_id, fileRecord) == 0)
-            name = fileRecord.name;
-    }
-    return name;
-}
-
-/**
- * Return the known status of the file with the given id
- * @param fileId id of the file to get the status of
- * @returns KNOWN_STATUS
- */
-TskImgDB::KNOWN_STATUS TskImgDBPostgreSQL::getKnownStatus(const uint64_t fileId) const
-{
-     int retval = -1;
-
-    if (!initialized())
-        return (TskImgDB::KNOWN_STATUS)retval;
-
-    stringstream stmt;
-    stmt << "SELECT known FROM file_hashes WHERE file_id = " << fileId;
-
-    try
-    {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt);
-        pqxx::result::const_iterator i = R.begin(); 
-        if(i != R.end()){
-            i[0].to(retval);
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        std::wstring wTableName;
-        errorMsg << L"TskImgDBPostgreSQL::getFileIdsWorker - Error getting known status : "
-            << e.what() << std::endl;
-        LOGERROR(errorMsg.str());
-    }
-
-    return (TskImgDB::KNOWN_STATUS)retval;
-}
-
-/**
- * Add a new row to the unalloc_img_status table, returning the unalloc_img_id.
- * @param unallocImgId unalloc_img_id (output)
- * @returns -1 on error, 0 on success.
- */
-int TskImgDBPostgreSQL::addUnallocImg(int & unallocImgId)
-{
-    int rc = -1;
-
-    if (!initialized())
-        return rc;
-
-    std::stringstream stmt;
-    stmt << "INSERT INTO unalloc_img_status (unalloc_img_id, status) VALUES (DEFAULT, " << TskImgDB::IMGDB_UNALLOC_IMG_STATUS_CREATED << ")";
-    try
-    {
-        pqxx::work W(*m_dbConnection);
-        pqxx::result R = W.exec(stmt);
-
-        // get the unalloc_img_id from the last insert
-        stmt.str("");
-        stmt << "SELECT currval(pg_get_serial_sequence('unalloc_img_status', 'unalloc_img_id'))";
-        R = W.exec(stmt);
-        unallocImgId = R[0][0].as<int>();
-        W.commit();
-        rc = 0;
-    }
-    catch (const exception& ex)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::addUnallocImg - Error adding unalloc_img_status table: "
-            << ex.what();
-        LOGERROR(errorMsg.str());
-    }
-
-    return rc;
-}
-
-/**
- * Set the status in the unalloc_img_status table given the unalloc_img_id.
- * @param unallocImgId unalloc_img_id
- * @param status status of unalloc_img_id
- * @returns -1 on error, 0 on success.
- */
-int TskImgDBPostgreSQL::setUnallocImgStatus(int unallocImgId, TskImgDB::UNALLOC_IMG_STATUS status)
-{
-    int rc = -1;
-
-    if (!initialized())
-        return rc;
-
-    std::stringstream stmt;
-    stmt << "UPDATE unalloc_img_status SET status = " << status << " WHERE unalloc_img_id = " << unallocImgId;
-    try
-    {
-        pqxx::work W(*m_dbConnection);
-        pqxx::result R = W.exec(stmt);
-        W.commit();
-        rc = 0;
-    }
-    catch (const exception& ex)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::setUnallocImgStatus - Error updating unalloc_img_status table: "
-            << ex.what() << std::endl;
-        LOGERROR(errorMsg.str());
-    }
-
-    return rc;
-}
-
-/**
- * Get the status of the unalloc_img_status table given the unalloc_img_id.
- * Can throws TskException.
- * @param unallocImgId unalloc_img_id
- * @returns TskImgDB::UNALLOC_IMG_STATUS
- */
-TskImgDB::UNALLOC_IMG_STATUS TskImgDBPostgreSQL::getUnallocImgStatus(int unallocImgId) const
-{
-    if (!initialized())
-        throw TskException("Database not initialized.");
-
-    int status;
-
-    stringstream stmt;
-    stmt << "SELECT status FROM unalloc_img_status WHERE unalloc_img_id = " << unallocImgId;
-    try {
-        pqxx::read_transaction trans(*m_dbConnection);
-        pqxx::result R = trans.exec(stmt.str().c_str());
-        if (R.size() == 1) {
-            R[0][0].to(status);
-        } else {
-            throw TskException("No unalloc_img_status.");
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBPostgreSQL::getUnallocImgStatus - Error getting unalloc_img_status: "
-            << e.what() << std::endl;
-        LOGERROR(errorMsg.str());
-    }
-    return (TskImgDB::UNALLOC_IMG_STATUS)status;
-}
-
-/**
- * Get all the unalloc_img_status table.
- * @param unallocImgStatusList A vector of TskUnallocImgStatusRecord (output)
- * @returns -1 on error, 0 on success.
- */
-int TskImgDBPostgreSQL::getAllUnallocImgStatus(std::vector<TskUnallocImgStatusRecord> & unallocImgStatusList) const
-{
-    int rc = -1;
-    unallocImgStatusList.clear();
-
-    if (!initialized())
-        return rc;
-
-    stringstream stmt;
-    stmt << "SELECT unalloc_img_id, status FROM unalloc_img_status";
-
-    try
-    {
-        pqxx::read_transaction W(*m_dbConnection);
-        pqxx::result R = W.exec(stmt.str().c_str());
-
-        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
-        {
-            TskUnallocImgStatusRecord record;
-
-            i[0].to(record.unallocImgId);
-            i[1].to((int &)record.status);
-            unallocImgStatusList.push_back(record);
-        }
-        rc = 0;
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream msg;
-        msg << L"TskDBPostgreSQL::getAllBlackboardRows - Error querying blackboard table: "
-            << e.what() << std::endl;
-        LOGERROR(msg.str());
-    }
-    return rc;
-}
-
-/**
- * Find and add all the unused sectors (unallocated and uncarved bytes) in the given unallocImgId
- * @param unallocImgId The unalloc image id.
- * @param unusedSectorsList A vector of TskUnusedSectorsRecord
- * @returns -1 on error, 0 on success.
- */
-int TskImgDBPostgreSQL::addUnusedSectors(int unallocImgId, std::vector<TskUnusedSectorsRecord> & unusedSectorsList)
-{
-    assert(unallocImgId > 0);
-
-    if (!initialized())
-        return -1;
-
-    std::stringstream stmt;
-    stmt << "SELECT vol_id, unalloc_img_sect_start, sect_len, orig_img_sect_start FROM alloc_unalloc_map "
-        "WHERE unalloc_img_id = " << unallocImgId << " ORDER BY orig_img_sect_start ASC";
-
-    try {
-        pqxx::read_transaction W(*m_dbConnection);
-        pqxx::result R = W.exec(stmt.str());
-
-        vector<TskAllocUnallocMapRecord> allocUnallocMapList;
-
-        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
-        {
-            TskAllocUnallocMapRecord record;
-            i[0].to(record.vol_id);
-            record.unalloc_img_id = unallocImgId;
-            i[1].to(record.unalloc_img_sect_start);
-            i[2].to(record.sect_len);
-            i[3].to(record.orig_img_sect_start);
-            allocUnallocMapList.push_back(record);
-        }
-
-        W.commit();
-
-        for (std::vector<TskAllocUnallocMapRecord>::const_iterator it = allocUnallocMapList.begin();
-             it != allocUnallocMapList.end(); it++)
-        {
-            // Sector position tracks our position through the unallocated map record.
-            uint64_t sectPos = it->orig_img_sect_start;
-
-            uint64_t endSect = it->orig_img_sect_start + it->sect_len;
-
-            // Retrieve all carved_sector records in range for this section of unallocated space.
-            stmt.str("");
-            stmt << "SELECT cs.sect_start, cs.sect_len FROM carved_files cf, carved_sectors cs"
-                << " WHERE cf.file_id = cs.file_id AND cs.sect_start >= " << it->orig_img_sect_start
-                << " AND cs.sect_start < " << endSect << " ORDER BY cs.sect_start ASC";
-
-            pqxx::read_transaction trans(*m_dbConnection);
-
-            R = trans.exec(stmt.str());
-            trans.commit();
-
-            for (pqxx::result::const_iterator i = R.begin(); i != R.end(); i++)
-            {
-                uint64_t cfileSectStart;
-                uint64_t cfileSectLen;
-
-                i[0].to(cfileSectStart);
-                i[1].to(cfileSectLen);
-
-                if (cfileSectStart > sectPos)
-                {
-                    // We have a block of unused sectors between this position in the unallocated map
-                    // and the start of the carved file.
-                    addUnusedSector(sectPos, cfileSectStart, it->vol_id, unusedSectorsList);
-                }
-
-                sectPos = cfileSectStart + cfileSectLen;
-            }
-
-            // Handle case where there is slack at the end of the unalloc range
-            if (sectPos < endSect)
-                addUnusedSector(sectPos, endSect, it->vol_id, unusedSectorsList);
-        }
-    }
-    catch (const exception &e)
-    {
-        std::wstringstream msg;
-        msg << L"TskDBPostgreSQL::addUnusedSectors - Error adding unused sectors : "
-            << e.what() << std::endl;
-        LOGERROR(msg.str());
-    }
-
-    return 0;
-}
-
-/**
- * Add one unused sector to the database, add it to the files and unused_sectors tables.
- * @param sectStart Unused sector start.
- * @param sectEnd Unused sector end.
- * @param volId Volume Id of the unused sector.
- * @param unusedSectorsList A vector of TskUnusedSectorsRecord (output)
- * @returns -1 on error, 0 on success.
- */
-int TskImgDBPostgreSQL::addUnusedSector(uint64_t sectStart, uint64_t sectEnd, int volId, std::vector<TskUnusedSectorsRecord> & unusedSectorsList)
-{
-    assert(sectEnd > sectStart);
-    int rc = -1;
-    if (!initialized())
-        return rc;
-
-    char *ufilename = "ufile";
-    std::stringstream stmt;
-
-    std::string maxUnused = GetSystemProperty("MAX_UNUSED_FILE_SIZE_BYTES");
-    const uint64_t maxUnusedFileSizeBytes = maxUnused.empty() ? (50 * 1024 * 1024) : Poco::NumberParser::parse64(maxUnused);
-
-    uint64_t maxUnusedSectorSize = maxUnusedFileSizeBytes / 512;
-    uint64_t sectorIndex = 0;
-    uint64_t sectorCount = (sectEnd - sectStart) / maxUnusedSectorSize;
-
-    while (sectorIndex <= sectorCount) {
-        uint64_t thisSectStart = sectStart + (sectorIndex * maxUnusedSectorSize);
-        uint64_t thisSectEnd = thisSectStart + std::min(maxUnusedSectorSize, sectEnd - thisSectStart);
-
-        stmt.str("");
-        stmt << "INSERT INTO files (file_id, type_id, name, par_file_id, dir_type, meta_type,"
-            "dir_flags, meta_flags, size, ctime, crtime, atime, mtime, mode, uid, gid, status, full_path) "
-            "VALUES (DEFAULT, " << IMGDB_FILES_TYPE_UNUSED << ", " << m_dbConnection->quote(ufilename)
-            << ", NULL, " <<  TSK_FS_NAME_TYPE_REG << ", " <<  TSK_FS_META_TYPE_REG << ", "
-            << TSK_FS_NAME_FLAG_UNALLOC << ", " << TSK_FS_META_FLAG_UNALLOC << ", "
-            << (thisSectEnd - thisSectStart) * 512 << ", NULL, NULL, NULL, NULL, NULL, NULL, NULL, " << IMGDB_FILES_STATUS_READY_FOR_ANALYSIS << "," << m_dbConnection->quote(ufilename) << ")";
-        try
-        {
-            pqxx::work W(*m_dbConnection);
-            pqxx::result R = W.exec(stmt.str().c_str());
-
-            TskUnusedSectorsRecord record;
-
-            // get the file_id from the last insert
-            stmt.str("");
-            stmt << "SELECT currval(pg_get_serial_sequence('files', 'file_id'))";
-            R = W.exec(stmt.str().c_str());
-            record.fileId = R[0][0].as<uint64_t>();
-            record.sectStart = thisSectStart;
-            record.sectLen = thisSectEnd - thisSectStart;
-
-            std::stringstream name;
-            name << "ufile_" << thisSectStart << "_" << thisSectEnd << "_" << record.fileId;
-            stmt.str("");
-            stmt << "UPDATE files SET name = " << m_dbConnection->quote(name.str().c_str()) << ", full_path = " 
-                << m_dbConnection->quote(name.str().c_str()) << " WHERE file_id = " << record.fileId;
-            R = W.exec(stmt.str().c_str());
-
-            stmt.str("");
-            stmt << "INSERT INTO unused_sectors (file_id, sect_start, sect_len, vol_id) VALUES (" 
-                 << record.fileId << ", " << record.sectStart << ", " << record.sectLen << ", " << volId << ")";
-            R = W.exec(stmt.str().c_str());
-
-            W.commit();
-            unusedSectorsList.push_back(record);
-            rc = 0;
-        } 
-        catch (const exception& ex)
-        {
-            std::wstringstream errorMsg;
-            errorMsg << L"TskImgDBPostgreSQL::addUnusedSector - Error insert into files table: "
-                << ex.what() << std::endl;
-            LOGERROR(errorMsg.str());
-            rc = -1;
-            break;
-        }
-        sectorIndex++;
-    } // while
-    return rc;
-}
-
-/**
- * Get unused sector record given a file id.
- * @param fileId File id of the unused sector.
- * @param unusedSectorsRecord TskUnusedSectorsRecord (output)
- * @returns -1 on error, 0 on success.
- */
-int TskImgDBPostgreSQL::getUnusedSector(uint64_t fileId, TskUnusedSectorsRecord & unusedSectorsRecord) const
-{
-    int rc = -1;
-    if (!initialized())
-        return rc;
-
-    std::stringstream stmt;
-    stmt << "SELECT sect_start, sect_len FROM unused_sectors WHERE file_id = " << fileId;
-
-    try {
-        pqxx::read_transaction W(*m_dbConnection);
-        pqxx::result R = W.exec(stmt.str().c_str());
-        if (R.size() == 1) {
-            unusedSectorsRecord.fileId = fileId;
-            unusedSectorsRecord.sectStart = R[0][0].as<uint64_t>();
-            unusedSectorsRecord.sectLen = R[0][1].as<uint64_t>();
-            rc = 0;
-        } else {
-            std::wstringstream msg;
-            msg << L"TskDBPostgreSQL::getUnusedSector - Error querying unused_sectors table for file_id "
-                << fileId << ", result size = " << R.size() << std::endl;
-            LOGERROR(msg.str());
-        }
-    } 
-    catch (const exception &e)
-    {
-        std::wstringstream msg;
-        msg << L"TskDBPostgreSQL::getUnusedSector - Error querying unused_sectors table: "
-            << e.what() << std::endl;
-        LOGERROR(msg.str());
-    }
-    return rc;
-}
-
-///BLACKBOARD FUNCTIONS
-/**
- * Add the given blackboard attribute to the database
- * @param attr input attribute. should be fully populated
- */
-void TskImgDBPostgreSQL::addBlackboardAttribute(TskBlackboardAttribute attr){
-    if (!m_dbConnection)
-        throw TskException("No database.");
-
-    artifact_t artifactId = 0;
-    std::stringstream str;
-
-    str << "INSERT INTO blackboard_attributes (artifact_id, source, context, attribute_type_id, value_type, "
-        "value_byte, value_text, value_int32, value_int64, value_double, obj_id) VALUES (";
-        str << attr.getArtifactID() << ", ";
-    str << m_dbConnection->quote(attr.getModuleName()) << ", ";
-    str << m_dbConnection->quote(attr.getContext()) << ", ";
-    str << attr.getAttributeTypeID() << ", ";
-    str << attr.getValueType() << ", ";
-    std::string escStr;
-    int a_size;
-    unsigned char *pBuf;
-    switch (attr.getValueType()) {
-        case TSK_BYTE:
-            a_size = attr.getValueBytes().size();
-            pBuf = new unsigned char[a_size];
-            
-            for (int i = 0; i < a_size; i++) {
-                pBuf[i] = attr.getValueBytes()[i];
-            }
-
-            escStr = m_dbConnection->esc_raw(pBuf, a_size);
-            delete pBuf;
-            str << " '" << escStr.c_str() << "', '', 0, 0, 0.0";
-            break;
-        case TSK_STRING:
-            a_size = attr.getValueString().size();
-            pBuf = new unsigned char[a_size];
-            
-            for (int i = 0; i < a_size; i++) {
-                pBuf[i] = attr.getValueString()[i];
-            }
-            str << " '', E" << m_dbConnection->quote(attr.getValueString()) << ", 0, 0, 0.0";
-            break;
-        case TSK_INTEGER:
-            str << " '', '', " << attr.getValueInt() << ",     0, 0.0";
-            break;
-        case TSK_LONG:
-            str << " '', '', 0, " << attr.getValueLong() << ",     0.0";
-            break;
-        case TSK_DOUBLE:
-            str << " '', '', 0, 0, " << setprecision(20) << attr.getValueDouble();
-            break;
-    };
-    str << ", " << attr.getObjectID() << ")";
-
-    try
-    {
-        pqxx::work W(*m_dbConnection);
-        pqxx::result R = W.exec(str);
-  
-        W.commit();
-
-    } catch (const exception &e) {
-        std::wstringstream msg;
-        msg << L"TskDBPostgreSQL::addBlackboardAttribute - Error adding data to blackboard table: "
-            << e.what() << std::endl;
-        LOGERROR(msg.str());
-        throw TskException("TskDBPostgreSQL::addBlackboardInfo - Insert failed");
-    }
-}
-
-/**
- * Get the display name for the given artifact type id
- * @param artifactTypeID artifact type id
- * @returns display name
- */
-string TskImgDBPostgreSQL::getArtifactTypeDisplayName(int artifactTypeID){
-    if (!m_dbConnection)
-        throw TskException("No database.");
-
-    std::stringstream str;
-    std::string displayName = "";
-
-    str << "SELECT display_name FROM blackboard_artifact_types WHERE artifact_type_id = " << artifactTypeID;
-
-    try{
-        pqxx::work W(*m_dbConnection);
-        pqxx::result R = W.exec(str);
-        
-        if(R.size() > 0)
-            displayName = R[0][0].as<string>();
-        
-        W.commit();
-        return displayName;
-
-    }catch(const exception &e) {
-        std::wstringstream msg;
-        msg << L"TskDBPostgreSQL::getArtifactTypeDisplayName:"
-            << e.what() << std::endl;
-        LOGERROR(msg.str());
-        throw TskException("TskDBPostgreSQL::getArtifactTypeDisplayName - No artifact type with that ID");
-    }
-}
-
-/**
- * Get the artifact type id for the given artifact type string
- * @param artifactTypeString display name
- * @returns artifact type id
- */
-int TskImgDBPostgreSQL::getArtifactTypeID(string artifactTypeString){
-    if (!m_dbConnection)
-        throw TskException("No database.");
-
-    std::stringstream str;
-    int typeID;
-
-    str << "SELECT artifact_type_id FROM blackboard_artifact_types WHERE type_name = " << artifactTypeString;
-
-    try{
-        pqxx::work W(*m_dbConnection);
-        pqxx::result R = W.exec(str);
-        
-        if(R.size() > 0)
-            typeID = R[0][0].as<int>();
-        
-        W.commit();
-        return typeID;
-    }catch(const exception &e) {
-        std::wstringstream msg;
-        msg << L"TskDBPostgreSQL::getArtifactTypeID:"
-            << e.what() << std::endl;
-        LOGERROR(msg.str());
-        throw TskException("TskDBPostgreSQL::getArtifactTypeID - No artifact type with that name");
-    }
-}
-
-/**
- * Get the artifact type name for the given artifact type id
- * @param artifactTypeID id
- * @returns artifact type name
- */
-string TskImgDBPostgreSQL::getArtifactTypeName(int artifactTypeID){
-    if (!m_dbConnection)
-        throw TskException("No database.");
-
-    std::stringstream str;
-    std::string typeName = "";
-
-    str << "SELECT type_name FROM blackboard_artifact_types WHERE artifact_type_id = " << artifactTypeID;
-
-    try{
-        pqxx::work W(*m_dbConnection);
-        pqxx::result R = W.exec(str);
-        
-        if(R.size() > 0)
-            typeName = R[0][0].as<string>();
-        W.commit();
-        return typeName;
-    }
-    catch(const exception &e) {
-        std::wstringstream msg;
-        msg << L"TskDBPostgreSQL::getArtifactTypeName:"
-            << e.what() << std::endl;
-        LOGERROR(msg.str());
-        throw TskException("TskDBPostgreSQL::getArtifactTypeName - No artifact type with that id");
-    }
-}
-
-/**
- * Get the display name for the given attribute type id
- * @param attributeTypeID attribute type id
- * @returns display name
- */
-string TskImgDBPostgreSQL::getAttributeTypeDisplayName(int attributeTypeID){
-    if (!m_dbConnection)
-        throw TskException("No database.");
-
-    std::stringstream str;
-    std::string displayName = "";
-
-    str << "SELECT display_name FROM blackboard_attribute_types WHERE attribute_type_id = " << attributeTypeID;
-
-    try{
-        pqxx::work W(*m_dbConnection);
-        pqxx::result R = W.exec(str);
-        
-        if(R.size() > 0)
-            displayName = R[0][0].as<string>();
-        W.commit();
-        return displayName;
-    }
-    catch(const exception &e) {
-        std::wstringstream msg;
-        msg << L"TskDBPostgreSQL::getAttributeTypeDisplayName:"
-            << e.what() << std::endl;
-        LOGERROR(msg.str());
-        throw TskException("TskDBPostgreSQL::getAttributeTypeDisplayName - No attribute type with that id");
-    }
-}
-
-/**
- * Get the attribute type id for the given artifact type string
- * @param attributeTypeString display name
- * @returns attribute type id
- */
-int TskImgDBPostgreSQL::getAttributeTypeID(string attributeTypeString){
-    if (!m_dbConnection)
-        throw TskException("No database.");
-
-    std::stringstream str;
-    int typeID;
-
-    str << "SELECT attribute_type_id FROM blackboard_attribute_types WHERE type_name = " << attributeTypeString;
-
-    try{
-        pqxx::work W(*m_dbConnection);
-        pqxx::result R = W.exec(str);
-        
-        if(R.size() > 0)
-            typeID = R[0][0].as<int>();
-        W.commit();
-        return typeID;
-    }
-    catch(const exception &e) {
-        std::wstringstream msg;
-        msg << L"TskDBPostgreSQL::getAttributeTypeID:"
-            << e.what() << std::endl;
-        LOGERROR(msg.str());
-        throw TskException("TskDBPostgreSQL::getAttributeTypeID - No attribute type with that name");
-    }
-}
-
-
-/**
- * Get the attribute type name for the given artifact type id
- * @param attributeTypeID id
- * @returns attribute type name
- */
-string TskImgDBPostgreSQL::getAttributeTypeName(int attributeTypeID){
-    if (!m_dbConnection)
-        throw TskException("No database.");
-
-    std::stringstream str;
-    std::string typeName = "";
-
-    str << "SELECT type_name FROM blackboard_attribute_types WHERE attribute_type_id = " << attributeTypeID;
-
-    try{
-        pqxx::work W(*m_dbConnection);
-        pqxx::result R = W.exec(str);
-        
-        if(R.size() > 0)
-            typeName = R[0][0].as<string>();
-        W.commit();
-        return typeName;
-    }
-    catch(const exception &e) {
-        std::wstringstream msg;
-        msg << L"TskDBPostgreSQL::getAttributeTypeName:"
-            << e.what() << std::endl;
-        LOGERROR(msg.str());
-        throw TskException("TskDBPostgreSQL::getAttributeTypeName - No attribute type with that id");
-    }
-}
-
-/**
- * Get all artifacts with that match the given where clause 
- * @param whereClause where clause to use for matching
- * @returns vector of matching artifacts
- */
-vector<TskBlackboardArtifact> TskImgDBPostgreSQL::getMatchingArtifacts(string whereClause){
-    if (!m_dbConnection)
-        throw TskException("No database.");
-    
-    vector<TskBlackboardArtifact> artifacts;
-    std::string stmt("SELECT blackboard_artifacts.artifact_id, blackboard_artifacts.obj_id, blackboard_artifacts.artifact_type_id FROM blackboard_artifacts");
-
-    constructStmt(stmt, whereClause);
-
-    try
-    {
-        pqxx::work W(*m_dbConnection);
-        pqxx::result R = W.exec(stmt);
-        W.commit();
-
-        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i) 
-        {
-            int artifactTypeID = i[2].as<int>();
-            
-            artifacts.push_back(TskImgDB::createArtifact(i[0].as<uint64_t>(), i[1].as<uint64_t>(), artifactTypeID));
-        }
-        
-        return artifacts;
-    } catch(const exception &e) {
-        std::wstringstream msg;
-        msg << L"TskDBPostgreSQL::getMatchingArtifacts:"
-            << e.what() << std::endl;
-        LOGERROR(msg.str());
-        throw TskException("TskDBPostgreSQL::getMatchingArtifacts");
-    }
-    return artifacts;
-}
-
-/**
- * Get all attributes with that match the given where clause 
- * @param whereClause where clause to use for matching
- * @returns vector of matching attributes
- */
-vector<TskBlackboardAttribute> TskImgDBPostgreSQL::getMatchingAttributes(string whereClause){
-    if (!m_dbConnection)
-        throw TskException("No database.");
-    
-    vector<TskBlackboardAttribute> attributes;
-    std::string stmt("SELECT blackboard_attributes.artifact_id, blackboard_attributes.source, blackboard_attributes.context, blackboard_attributes.attribute_type_id, blackboard_attributes.value_type, blackboard_attributes.value_byte, blackboard_attributes.value_text, blackboard_attributes.value_int32, blackboard_attributes.value_int64, blackboard_attributes.value_double, blackboard_attributes.obj_id FROM blackboard_attributes ");
-
-    constructStmt(stmt, whereClause);
-
-    try
-    {
-        pqxx::work W(*m_dbConnection);
-        pqxx::result R = W.exec(stmt);
-
-        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i) 
-        {
-            pqxx::binarystring binStr(i[6]);
-            int a_size = binStr.size();
-            vector<unsigned char> bytes;
-            bytes.reserve(a_size);
-            for (int j = 0; j < a_size; j++)
-                bytes.push_back((unsigned char)binStr[j]);
-            
-            attributes.push_back(TskImgDB::createAttribute(i[0].as<uint64_t>(), i[3].as<int>(), i[10].as<uint64_t>(), 
-                i[1].as<string>(), i[2].as<string>(), (TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE) i[4].as<int>(), i[7].as<int>(), 
-                i[8].as<uint64_t>(), i[9].as<double>(), i[6].as<string>(), bytes));
-        }
-        W.commit();
-    } catch(const exception &e) {
-        std::wstringstream msg;
-        msg << L"TskDBPostgreSQL::getMatchingAttributes:"
-            << e.what() << std::endl;
-        LOGERROR(msg.str());
-        throw TskException("TskDBPostgreSQL::getMatchingAttributes");
-    }
-    return attributes;
-}
-
-/**
- * Create a new blackboard artifact with the given type id and file id
- * @param artifactTypeID artifact type id
- * @param file_id associated file id
- * @returns the new artifact
- */
-TskBlackboardArtifact TskImgDBPostgreSQL::createBlackboardArtifact(uint64_t file_id, int artifactTypeID){
-    if (!m_dbConnection)
-        throw TskException("No database.");
-
-    uint64_t artifactId = 0;
-    std::stringstream str;
-
-    str << "INSERT INTO blackboard_artifacts (artifact_id, obj_id, artifact_type_id) VALUES (DEFAULT, " 
-        << file_id << ", " << artifactTypeID << ")"
-        << "RETURNING artifact_id";
-
-    try {
-        pqxx::work W(*m_dbConnection);
-        pqxx::result R = W.exec(str);
-        
-        if (R.size() == 1)
-        {
-            R[0][0].to(artifactId);
-        }
-        else
-        {
-            std::stringstream errorMsg;
-            errorMsg << "TskImgDBPostgreSQL::createBlackboardArtifact - Unexpected number of rows returned."
-                << R.size();
-            throw TskException(errorMsg.str());
-        }
-        W.commit();
-    } catch(const exception &e) {
-        std::wstringstream msg;
-        msg << L"TskDBPostgreSQL::newBlackboardArtifact:"
-            << e.what() << std::endl;
-        LOGERROR(msg.str());
-        throw TskException("TskDBPostgreSQL::newBlackboardArtifact");
-    }
-
-    return TskImgDB::createArtifact(artifactId, file_id, artifactTypeID);
-}
-
-/**
- * Add a new artifact type with the given name, display name and id 
- * @param artifactTypeName type name
- * @param displayName display name
- * @param typeID type id
- */
-void TskImgDBPostgreSQL::addArtifactType(int typeID, string artifactTypeName, string displayName){
-    if (!m_dbConnection)
-        throw TskException("No database.");
-
-    std::stringstream str;
-
-    str << "SELECT * FROM blackboard_artifact_types WHERE type_name = '" << artifactTypeName << "'";
-
-    try{
-        pqxx::work W(*m_dbConnection);
-        pqxx::result R = W.exec(str);
-        if(R.size() == 0){
-            str.str("");
-            str << "INSERT INTO blackboard_artifact_types (artifact_type_id, type_name, display_name) VALUES (" << typeID << " , '" << artifactTypeName << "', '" << displayName << "')";
-            pqxx::result R = W.exec(str);
-
-        }
-        else{
-            throw TskException("TskImgDBPostgreSQL::addArtifactType - Artifact type with that name already exists");
-        }
-        W.commit();
-    } catch(const exception &e) {
-        std::wstringstream msg;
-        msg << L"TskDBPostgreSQL::addArtifactType:"
-            << e.what() << std::endl;
-        LOGERROR(msg.str());
-        throw TskException("TskDBPostgreSQL::addArtifactType");
-    }
-}
-
-/**
- * Add a new attribute type with the given name, display name and id 
- * @param attributeTypeName type name
- * @param displayName display name
- * @param typeID type id
- */
-void TskImgDBPostgreSQL::addAttributeType(int typeID, string attributeTypeName, string displayName){
-    if (!m_dbConnection)
-        throw TskException("No database.");
-
-    std::stringstream str;
-
-    str << "SELECT * FROM blackboard_attribute_types WHERE type_name = '" << attributeTypeName << "'";
-
-    try{
-        pqxx::work W(*m_dbConnection);
-        pqxx::result R = W.exec(str);
-        if(R.size() == 0){
-            str.str("");
-            str << "INSERT INTO blackboard_attribute_types (attribute_type_id, type_name, display_name) VALUES (" << typeID << " , '" << attributeTypeName << "', '" << displayName << "')";
-            pqxx::result R = W.exec(str);
-
-        }
-        else{
-            throw TskException("TskImgDBPostgreSQL::addArtifactType - Artifact type with that name already exists");
-        }
-        W.commit();
-    } catch(const exception &e) {
-        std::wstringstream msg;
-        msg << L"TskDBPostgreSQL::addAttributeType:"
-            << e.what() << std::endl;
-        LOGERROR(msg.str());
-        throw TskException("TskDBPostgreSQL::addAttributeType");
-    }
-}
-
-/**
- * Get all artifacts with the given type id, type name, and file id
- * @param artifactTypeID type id
- * @param artifactTypeName type name
- * @param file_id file id
- */
-vector<TskBlackboardArtifact> TskImgDBPostgreSQL::getArtifactsHelper(uint64_t file_id, int artifactTypeID, string artifactTypeName){
-    if (!m_dbConnection)
-        throw TskException("No database.");
-    
-    int result = 0;
-    vector<TskBlackboardArtifact> artifacts;
-    std::stringstream stmt;
-    stmt << "SELECT artifact_id, obj_id, artifact_type_id FROM blackboard_artifacts WHERE obj_id = " << file_id << " AND artifact_type_id = " << artifactTypeID;
-
-    try 
-    {
-
-        string displayName = getArtifactTypeDisplayName(artifactTypeID);
-        pqxx::work W(*m_dbConnection);
-        pqxx::result R = W.exec(stmt);
-
-        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i) 
-        {
-            int artifactTypeID = i[2].as<int>();
-            
-            artifacts.push_back(TskImgDB::createArtifact(i[0].as<uint64_t>(), file_id, artifactTypeID));
-        }
-        W.commit();
-    } catch(const exception &e) {
-        std::wstringstream msg;
-        msg << L"TskDBPostgreSQL::getArtifactsHelper:"
-            << e.what() << std::endl;
-        LOGERROR(msg.str());
-        throw TskException("TskDBPostgreSQL::getArtifactsHelper");
-    }
-    return artifacts;
-}
-vector<int> TskImgDBPostgreSQL::findAttributeTypes(int artifactTypeId){
-    if (!m_dbConnection)
-        throw TskException("No database.");
-    
-    int result = 0;
-    vector<int> attributeTypes;
-    std::stringstream stmt;
-    stmt << "SELECT DISTINCT(attribute_type_id) FROM blackboard_attributes JOIN blackboard_artifacts ON blackboard_attributes.artifact_id = blackboard_artifacts.artifact_id WHERE artifact_type_id = " << artifactTypeId;
-
-    try 
-    {
-        pqxx::work W(*m_dbConnection);
-        pqxx::result R = W.exec(stmt);
-
-        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i) 
-        {
-            int artifactTypeID = i[0].as<int>();
-            
-            attributeTypes.push_back(artifactTypeID);
-        }
-        W.commit();
-    } catch(const exception &e) {
-        std::wstringstream msg;
-        msg << L"TskDBPostgreSQL::findAttributeTypes:"
-            << e.what() << std::endl;
-        LOGERROR(msg.str());
-        throw TskException("TskDBPostgreSQL::findAttributeTypes");
-    }
-    return attributeTypes;
-}
-
-std::string TskImgDBPostgreSQL::quote(const std::string str) const
-{
-    return m_dbConnection->quote(str);
-}
+/*
+ *
+ *  The Sleuth Kit
+ *
+ *  Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ *  Copyright (c) 2010-2011 Basis Technology Corporation. All Rights
+ *  reserved.
+ *
+ *  This software is distributed under the Common Public License 1.0
+ */
+
+/**
+ * \file TskImgDBPostgreSQL.cpp
+ * A PostgreSQL based implementation of the framework data access layer.
+ */
+#include <stdio.h>
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+#include <Lmcons.h>
+#include <assert.h>
+
+#include "tsk/framework/services/TskDBBlackboard.h"
+#include "TskImgDBPostgreSQL.h"
+#include "tsk/framework/services/TskServices.h"
+#include "tsk/framework/utilities/TskException.h"
+#include "tsk/framework/utilities/TskUtilities.h"
+
+#include "Poco/String.h"
+#include "Poco/UnicodeConverter.h"
+#include "Poco/NumberParser.h"
+#include "Poco/Path.h"
+
+/**
+ *
+ */
+TskImgDBPostgreSQL::TskImgDBPostgreSQL(const std::string dbName) : m_dbName(dbName), m_dbConnection(NULL)
+{
+    m_artifactIDcounter = 1000;
+    m_attributeIDcounter = 1000;
+}
+
+TskImgDBPostgreSQL::~TskImgDBPostgreSQL()
+{
+    close();
+}
+
+int TskImgDBPostgreSQL::close()
+{
+    if (m_dbConnection != NULL)
+    {
+        m_dbConnection->disconnect();
+        delete m_dbConnection;
+        m_dbConnection = NULL;
+    }
+
+    return 0;
+}
+
+bool TskImgDBPostgreSQL::initialized() const
+{
+    if (m_dbConnection == NULL)
+    {
+        LOGERROR(L"TskImgDBPostgreSQL::initialized - Database not initialized.\n");
+        return false;
+    }
+
+    return true;
+}
+
+/** 
+ * Open the DB and create the tables.
+ * @returns 1 on error
+ */
+int TskImgDBPostgreSQL::initialize()
+{
+
+    // Open the database.
+    if (open() != 0)
+    {
+        // Error message will have been logged by open()
+        return 1;
+    }
+
+    try
+    {
+        pqxx::work W(*m_dbConnection);
+        // ----- DB_INFO
+        W.exec("CREATE TABLE db_info (name TEXT PRIMARY KEY, version TEXT)");
+        // ----- IMAGE_INFO
+        W.exec("CREATE TABLE image_info (type INTEGER, ssize INTEGER)");
+        // ----- IMAGE_NAMES
+        W.exec("CREATE TABLE image_names (seq SERIAL PRIMARY KEY, name TEXT)");
+        // ----- VOL_INFO
+        W.exec("CREATE TABLE vol_info (vol_id SERIAL PRIMARY KEY, sect_start BIGINT NOT NULL, sect_len BIGINT NOT NULL, description TEXT, flags INTEGER)");
+        // ----- FS_INFO
+        W.exec("CREATE TABLE fs_info (fs_id SERIAL PRIMARY KEY, img_byte_offset BIGINT, vol_id INTEGER NOT NULL, fs_type INTEGER, block_size INTEGER, block_count BIGINT, root_inum BIGINT, first_inum BIGINT, last_inum BIGINT)");
+        // ----- FILES
+        W.exec("CREATE TABLE files (file_id BIGSERIAL PRIMARY KEY, type_id INTEGER, name TEXT, par_file_id BIGINT, dir_type INTEGER, meta_type INTEGER, dir_flags INTEGER, meta_flags INTEGER, size BIGINT, ctime INTEGER, crtime INTEGER, atime INTEGER, mtime INTEGER, mode INTEGER, uid INTEGER, gid INTEGER, status INTEGER, full_path TEXT)");
+        // ----- FS_FILES
+        W.exec("CREATE TABLE fs_files (file_id BIGINT PRIMARY KEY, fs_id INTEGER, fs_file_id BIGINT, attr_type INTEGER, attr_id INTEGER)");
+        // ----- FS_BLOCKS
+        W.exec("CREATE TABLE fs_blocks (fs_id INTEGER NOT NULL, file_id BIGINT NOT NULL, seq INTEGER, blk_start BIGINT NOT NULL, blk_len BIGINT NOT NULL)");
+        // ----- CARVED_FILES
+        W.exec("CREATE TABLE carved_files (file_id BIGINT PRIMARY KEY, vol_id INTEGER)");
+        // ----- CARVED_SECTORS
+        W.exec("CREATE TABLE carved_sectors (file_id BIGINT, seq INTEGER, sect_start BIGINT, sect_len BIGINT)");
+        // ----- DERIVED_FILES
+        W.exec("CREATE TABLE derived_files (file_id BIGINT PRIMARY KEY, derivation_details TEXT)");
+        // ----- ALLOC_UNALLOC_MAP
+        W.exec("CREATE TABLE alloc_unalloc_map (vol_id INTEGER, unalloc_img_id INTEGER, unalloc_img_sect_start BIGINT, sect_len BIGINT, orig_img_sect_start BIGINT)");
+        // ----- FILE_HASHES
+        W.exec("CREATE TABLE file_hashes (file_id BIGINT PRIMARY KEY, md5 TEXT, sha1 TEXT, sha2_256 TEXT, sha2_512 TEXT, known INTEGER)");
+        // ----- MODULES
+        W.exec("CREATE TABLE modules (module_id SERIAL PRIMARY KEY, name TEXT UNIQUE NOT NULL, description TEXT)");
+        // ----- MODULE_STATUS
+        W.exec("CREATE TABLE module_status (file_id BIGINT, module_id SERIAL, status INTEGER, PRIMARY KEY (file_id, module_id))");
+        // ----- UNALLOC_IMG_STATUS
+        W.exec("CREATE TABLE unalloc_img_status (unalloc_img_id SERIAL PRIMARY KEY, status INTEGER)");
+        // ----- UNUSED_SECTORS
+        W.exec("CREATE TABLE unused_sectors (file_id BIGINT PRIMARY KEY, sect_start BIGINT, sect_len BIGINT, vol_id INTEGER)");
+        // ----- BLACKBOARD_ARTIFACTS
+        W.exec("CREATE TABLE blackboard_artifacts (artifact_id BIGSERIAL PRIMARY KEY, obj_id BIGINT NOT NULL, artifact_type_id INTEGER)");
+        // ----- BLACKBOARD_ATTRIBUTES
+        W.exec("CREATE TABLE blackboard_attributes (artifact_id BIGINT NOT NULL, source TEXT, context TEXT, attribute_type_id INTEGER NOT NULL, value_type INTEGER NOT NULL, "
+        "value_byte BYTEA, value_text TEXT, value_int32 INTEGER, value_int64 BIGINT, value_double NUMERIC(20, 10), obj_id BIGINT NOT NULL)");
+        // ----- BLACKBOARD_ARTIFACT_TYPES
+        W.exec("CREATE TABLE blackboard_artifact_types (artifact_type_id INTEGER PRIMARY KEY, type_name TEXT, display_name TEXT)");
+        // ----- BLACKBOARD_ATTRIBUTE_TYPES
+        W.exec("CREATE TABLE blackboard_attribute_types (attribute_type_id INTEGER PRIMARY KEY, type_name TEXT, display_name TEXT)");
+        // ----- INDEX ON ARTIFACT_ID OF BLACKBOARD_ATTRIBUTES
+        W.exec("CREATE INDEX attrs_artifact_id ON blackboard_attributes(artifact_id)");        
+        // ----- INDEX ON ATTRIBUTE_TYPE OF BLACKBOARD_ATTRIBUTES
+        W.exec("CREATE INDEX attrs_attribute_type ON blackboard_attributes(attribute_type_id)");        
+        // ----- INDEX ON OBJ_ID OF BLACKBOARD_ATTRIBUTES
+        W.exec("CREATE INDEX attrs_obj_id ON blackboard_attributes(obj_id)");        
+        
+        W.exec("SET synchronous_commit TO OFF");
+
+        W.commit();
+
+        map<int, TskArtifactNames> artTypes = TskImgDB::getAllArtifactTypes();
+        for(map<int, TskArtifactNames>::iterator it = artTypes.begin(); it != artTypes.end(); it++){
+            addArtifactType(it->first, it->second.typeName, it->second.displayName);
+        }
+        map<int, TskAttributeNames> attrTypes = TskImgDB::getAllAttributeTypes();
+        for(map<int, TskAttributeNames>::iterator it = attrTypes.begin(); it != attrTypes.end(); it++){
+            addAttributeType(it->first, it->second.typeName, it->second.displayName);
+        }
+
+    }
+    catch (std::exception& ex)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::initialize - Error creating database: " << ex.what() << std::endl;
+        LOGERROR(errorMsg.str());
+        return 1;
+    }
+
+    if (initializePreparedStatements())
+    {
+        // Error message will have been logged by initializePreparedStatements()
+        return 1;
+    }
+
+    addToolInfo("DbSchema", IMGDB_SCHEMA_VERSION);
+    LOGINFO(L"ImgDB Created.");
+
+    return 0;
+}
+
+/** 
+ * Initialize prepared statements (server-side function-like objects) in the DB.
+ * Assumes the DB is already created and open.
+ * @returns 1 on error
+ */
+int TskImgDBPostgreSQL::initializePreparedStatements()
+{
+    try
+    {
+        pqxx::work W(*m_dbConnection);
+
+        // Make prepared statement plans
+        {
+            std::stringstream stmt;
+            stmt << "PREPARE addFsFileInfoPlan (int, int, text, bigint, int, int, int, int, bigint, int, int, int, int, int, int, int, text) AS "
+                    << "INSERT INTO files (file_id, type_id, status, name, par_file_id, dir_type, meta_type, dir_flags, meta_flags, size, crtime, ctime, atime, mtime, mode, gid, uid, full_path) "
+                    << "VALUES (DEFAULT, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17) "
+                    << "RETURNING file_id";   
+            W.exec(stmt.str());
+        }
+        {
+            std::stringstream stmt;
+            stmt << "PREPARE addCarvedFileInfoPlan (int, int, text, int, int, int, int, bigint, text) AS "
+                    << "INSERT INTO files (file_id, type_id, status, name, par_file_id, dir_type, meta_type, dir_flags, meta_flags, size, crtime, ctime, atime, mtime, mode, gid, uid, full_path) "
+                    << "VALUES (DEFAULT, $1, $2, $3, NULL, $4, $5, $6, $7, $8, 0, 0, 0, 0, NULL, NULL, NULL, $9) "
+                    << "RETURNING file_id";   
+            W.exec(stmt.str());
+        }
+        {
+            std::stringstream stmt;
+            stmt << "PREPARE addDerivedFileInfoPlan (int, int, text, bigint, int, int, bigint, int, int, int, int, text) AS "
+                    << "INSERT INTO files (file_id, type_id, status, name, par_file_id, dir_type, meta_type, size, crtime, ctime, atime, mtime, full_path) "
+                    << "VALUES (DEFAULT, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) "
+                    << "RETURNING file_id";   
+            W.exec(stmt.str());
+        }
+
+        W.commit();
+    }
+    catch (std::exception& ex)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::initializePreparedStatements - Error creating prepared statements: " << ex.what() << std::endl;
+        LOGERROR(errorMsg.str());
+        return 1;
+    }
+    return 0;
+}
+
+/*
+ * Attempt to connect to an existing database. If connection attempt fails
+ * a new database is created. This database must be initialized before it
+ * is used.
+ * Returns 1 if connection attempt fails.
+ */
+int TskImgDBPostgreSQL::open()
+{
+    // Get current user name. This will get used in connecting to the database.
+    char name[UNLEN+1];
+    DWORD size = UNLEN+1;
+
+    GetUserNameA(name, &size);
+
+    std::string db_host = GetSystemProperty(TskSystemProperties::DB_HOST);
+    std::string db_port = GetSystemProperty(TskSystemProperties::DB_PORT);
+
+    // Convert the hostname to an IPv4 address. We need to do this because if you attempt to establish a 
+    // connection to a database server that exists on the same machine PostgreSQL will use the 'localhost'
+    // rule from the pg_hba.conf file. Unfortunately, SSPI authentication doesn't work in that scenario.
+    std::string db_host_ip;
+
+    bool db_new = false;
+
+    if (!TskUtilities::getHostIP(db_host, db_host_ip))
+        return 1;
+
+    try
+    {
+        // Construct the connection string to connect to the Postgres server.
+        std::stringstream pgConnectionString;
+        pgConnectionString << "host='" << db_host_ip << "' port='" << db_port
+            << "' dbname='postgres' user='" << name << "'";
+
+        pqxx::connection pgConnection(pgConnectionString.str());
+
+        // Check whether the database exists
+        pqxx::nontransaction nontrans(pgConnection);
+
+        std::stringstream dbQuery;
+        dbQuery << "select count(*) from pg_catalog.pg_database where datname = " << nontrans.quote(m_dbName);
+
+        pqxx::result R = nontrans.exec(dbQuery);
+
+        if (R.size() == 0 || R[0][0].as<int>() == 0) 
+        {
+            // There is no database. It needs to be created.
+            std::stringstream createDatabase;
+            createDatabase << "CREATE DATABASE \"" << m_dbName << "\" WITH OWNER=\"" << name << "\" ENCODING='UTF-8'";
+            nontrans.exec(createDatabase);
+            db_new = true;
+        }
+
+        std::stringstream dbConnectionString;
+        dbConnectionString << "host='" << db_host_ip << "' port='" << db_port
+            << "' dbname='" << m_dbName << "' user='" << name << "'";
+
+        m_dbConnection = new pqxx::connection(dbConnectionString.str());
+    }
+    catch (std::exception& ex)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskDBPostgreSQL::open - Error connecting to the database: "
+            << ex.what() << std::endl;
+        LOGERROR(errorMsg.str());
+        return 1;
+    }
+
+    if (!db_new)
+    {
+        if (initializePreparedStatements())
+        {
+            // Error message will have been logged by initializePreparedStatements()
+            return 1;
+        }
+    }
+
+    // We successfully connected to the database.
+    LOGINFO(L"ImgDB Opened.");
+    return 0;
+}
+
+pqxx::result TskImgDBPostgreSQL::executeStatement(const std::string& stmt) const
+{
+    pqxx::result R;
+
+    try
+    {
+        // if select then do a read-only transaction
+        std::string cmdstr("SELECT");
+        if (stmt.compare(0, cmdstr.size(), cmdstr, 0, cmdstr.size()) == 0)
+        {
+            pqxx::read_transaction trans(*m_dbConnection);
+            R = trans.exec(stmt);
+        }
+        else
+        {
+            pqxx::work W(*m_dbConnection);
+            R = W.exec(stmt);
+            W.commit();
+        }
+    }
+    catch (const exception &e)
+    {
+        std::stringstream errorMsg;
+        errorMsg << "TskDBPostgreSQL::executeStatement : " << e.what() << std::endl;
+        throw TskException(errorMsg.str());
+    }
+
+    return R;
+}
+
+int TskImgDBPostgreSQL::addToolInfo(const char* name, const char* version)
+{
+    if (!initialized())
+        return 1;
+
+    stringstream stmt;
+
+    stmt << "INSERT INTO db_info (name, version) VALUES ('" << name 
+        << "', '" << version << "')";
+
+    try
+    {
+        executeStatement(stmt.str());
+        return 0;
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskDBPostgreSQL::addToolInfo - Error adding data to db_info table: "
+            << e.what() << std::endl;
+        LOGERROR(errorMsg.str());
+
+        return 1;
+    }
+}
+
+int TskImgDBPostgreSQL::addImageInfo(int type, int size)
+{
+    if (!initialized())
+        return 1;
+
+    stringstream stmt;
+
+    stmt << "INSERT INTO image_info (type, ssize) VALUES (" << type << ", " << size << ")";
+
+    try
+    {
+        executeStatement(stmt.str());
+        return 0;
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskDBPostgreSQL::addImageInfo - Error adding data to image_info table: "
+            << e.what() << std::endl;
+        LOGERROR(errorMsg.str());
+
+        return 1;
+    }
+}
+
+int TskImgDBPostgreSQL::addImageName(char const * imgName)
+{
+    if (!initialized())
+        return 1;
+
+    stringstream stmt;
+
+    stmt << "INSERT INTO image_names (seq, name) VALUES (DEFAULT, E" 
+        << m_dbConnection->quote(imgName) << ")";
+
+    try
+    {
+        executeStatement(stmt.str());
+        return 0;
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskDBPostgreSQL::addImageName - Error adding data to image_names table: "
+            << e.what() << std::endl;
+        LOGERROR(errorMsg.str());
+
+        return 1;
+    }
+}
+
+/**
+ * Adds the sector addresses of the volumes into the db.
+ */
+int TskImgDBPostgreSQL::addVolumeInfo(const TSK_VS_PART_INFO * vs_part)
+{
+    if (!initialized())
+        return 1;
+
+    stringstream stmt;
+
+    stmt << "INSERT INTO vol_info (vol_id, sect_start, sect_len, description, flags) VALUES ("
+        << (int)vs_part->addr << ", " << vs_part->start 
+        << ", " << vs_part->len << ", '" << vs_part->desc 
+        << "', " << vs_part->flags << ")";
+
+    try
+    {
+        executeStatement(stmt.str());
+    }
+    catch (const TskException &e)
+    {
+        std::stringstream msg;
+        msg << "TskImgDBPostgreSQL::addVolumeInfo : " << e.what();
+        LOGERROR(msg.str());
+
+        return 1;
+    }
+
+    return 0;
+}
+
+int TskImgDBPostgreSQL::addFsInfo(int volId, int fsId, const TSK_FS_INFO * fs_info)
+{
+    if (!initialized())
+        return 1;
+
+    stringstream stmt;
+
+    stmt << "INSERT INTO fs_info (fs_id, img_byte_offset, vol_id, fs_type, block_size, block_count, root_inum, first_inum, last_inum) VALUES (" 
+        << fsId << ", " << fs_info->offset << ", " << volId
+        << ", " << (int)fs_info->ftype << ", " << fs_info->block_size << ", " << fs_info->block_count
+        << ", " << fs_info->root_inum << ", " << fs_info->first_inum << ", " << fs_info->last_inum << ")";
+
+    try
+    {
+        executeStatement(stmt.str());
+    }
+    catch (const TskException &e)
+    {
+        std::stringstream msg;
+        msg << "TskImgDBPostgreSQL::addFsInfo : " << e.what();
+        LOGERROR(msg.str());
+
+        return 1;
+    }
+
+    return 0;
+}
+
+
+/**
+ * Given a file system and fs_file_id, return the file_id.
+ */
+uint64_t TskImgDBPostgreSQL::getFileId(int a_fsId, uint64_t a_fsFileId) const
+{
+    if (!initialized())
+        return 0;
+
+    stringstream stmt;
+    uint64_t fileId = 0;
+
+    stmt << "SELECT file_id FROM fs_files WHERE fs_id=" 
+        << a_fsId << " AND fs_file_id=" << a_fsFileId;
+
+    try
+    {
+        pqxx::result R = executeStatement(stmt.str());
+
+        // @@@ It's possible to have multiple file_ids for the same fs_file_id.
+        // @@@ Which one should we use?
+        if (R.size() > 0)
+            fileId = R[0][0].as<uint64_t>();
+    }
+    catch (const TskException &e)
+    {
+        std::stringstream msg;
+        msg << "TskDBPostgreSQL::getFileId : Error querying fs_files table: " << e.what();
+        LOGERROR(msg.str());
+    }
+    return fileId;
+}
+
+/**
+ * @returns the file record or -1 on error.
+ */
+int TskImgDBPostgreSQL::getFileRecord(const uint64_t fileId, TskFileRecord& fileRecord) const
+{
+    if (!initialized())
+        return -1;
+
+    stringstream stmt;
+
+    stmt << "SELECT f.file_id, f.type_id, f.name, f.par_file_id, f.dir_type, f.meta_type, f.dir_flags, "
+        << "f.meta_flags, f.size, f.ctime, f.crtime, f.atime, f.mtime, f.mode, f.uid, f.gid, f.status, f.full_path, "
+        << "fh.md5, fh.sha1, fh.sha2_256, fh.sha2_512 "
+        << "FROM files f LEFT OUTER JOIN file_hashes fh ON f.file_id = fh.file_id WHERE f.file_id=" << fileId;
+
+    try
+    {
+        pqxx::read_transaction W(*m_dbConnection);
+        pqxx::result R = W.exec(stmt);
+
+        if (R.size() == 1)
+        {
+            R[0][0].to(fileRecord.fileId);
+            R[0][1].to((int &)fileRecord.typeId);
+            R[0][2].to(fileRecord.name);
+            R[0][3].to(fileRecord.parentFileId);
+            R[0][4].to((int &)fileRecord.dirType);
+            R[0][5].to((int &)fileRecord.metaType);
+            R[0][6].to((int &)fileRecord.dirFlags);
+            R[0][7].to((int &)fileRecord.metaFlags);
+            R[0][8].to(fileRecord.size);
+            R[0][9].to(fileRecord.ctime);
+            R[0][10].to(fileRecord.crtime);
+            R[0][11].to(fileRecord.atime);
+            R[0][12].to(fileRecord.mtime);
+            R[0][13].to((int &)fileRecord.mode);
+            R[0][14].to(fileRecord.uid);
+            R[0][15].to(fileRecord.gid);
+            R[0][16].to((int &)fileRecord.status);
+            R[0][17].to(fileRecord.fullPath);
+            R[0][18].to(fileRecord.md5);
+            R[0][19].to(fileRecord.sha1);
+            R[0][20].to(fileRecord.sha2_256);
+            R[0][21].to(fileRecord.sha2_512);            
+        }
+        else if (R.size() == 0)
+        {
+            std::wstringstream msg;
+            msg << L"TskImgDBPostgreSQL::getFileRecord - No record found for file id: " << fileId;
+            LOGERROR(msg.str());
+            return -1;
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream msg;
+        msg << L"TskImgDBPostgreSQL::getFileRecord - Error querying files table: "
+            << e.what();
+        LOGERROR(msg.str());
+        return -1;
+    }
+
+    return 0;
+}
+
+int TskImgDBPostgreSQL::addFsFileInfo(int fileSystemID, const TSK_FS_FILE *fileSystemFile, const char *fileName, int fileSystemAttrType, int fileSystemAttrID, uint64_t &fileID, const char *filePath)
+{
+    const std::string msgPrefix = "TskImgDBPostgreSQL::addFsFileInfo : ";
+    fileID = 0;
+
+    if (!initialized())
+    {
+        return -1;
+    }
+
+    // Construct the full path of the file within the image.
+    std::string fullpath(filePath);
+    fullpath.append(fileName);
+
+    // Check whether the file name contains a single quote. If so, replace it with a double single quote.
+    std::string fileNameAsString(fileName);
+    size_t found;
+    found = fileNameAsString.find("'");
+    if (found != std::string::npos) //Replace it and replace all its subsequent occurrences.
+    {
+        fileNameAsString.replace(found,1,"''");
+
+        while ((found=fileNameAsString.find("'",found+2)) != std::string::npos)// found+2 because we want to move past the newly inserted single quote.
+        {
+            fileNameAsString.replace(found,1,"''");
+        }
+    }
+
+    // Now remove all the control characters from the file name.
+    for (int codePoint=1; codePoint < 32; codePoint++)
+    {
+        char codePointAsHex[10];
+        codePointAsHex[0] = codePoint;
+        codePointAsHex[1] = '\0';
+        std::string stringToRemove(codePointAsHex);
+
+        found = fileNameAsString.find(stringToRemove);
+        if (found != std::string::npos) //Replace it and replace all its subsequent occurrences.
+        {
+            fileNameAsString.replace(found,1,"");
+
+            while ((found=fileNameAsString.find(stringToRemove,found+1)) != std::string::npos)// found+1 because the control characters are just 1 character.
+            {
+                fileNameAsString.replace(found,1,"");
+            }
+        }
+    }
+
+    fileName = fileNameAsString.c_str();
+
+    uint64_t parFileId = findParObjId(fileSystemFile, fileSystemID);
+
+    // Get the file size.
+    TSK_OFF_T size = 0; 
+    const TSK_FS_ATTR *fileSystemAttribute = tsk_fs_file_attr_get_id(const_cast<TSK_FS_FILE*>(fileSystemFile), fileSystemAttrID); 
+    if (fileSystemAttribute)
+    {
+        size = fileSystemAttribute->size;
+    }
+
+    // Get the file metadata, if it's available.
+    int mtime = 0;
+    int crtime = 0;
+    int ctime = 0;
+    int atime = 0;
+    int meta_type = 0;
+    int meta_flags = 0;
+    int meta_mode = 0;
+    int gid = 0;
+    int uid = 0;
+    if (fileSystemFile->meta) 
+    {
+        mtime = static_cast<int>(fileSystemFile->meta->mtime);
+        atime = static_cast<int>(fileSystemFile->meta->atime);
+        ctime = static_cast<int>(fileSystemFile->meta->ctime);
+        crtime = static_cast<int>(fileSystemFile->meta->crtime);
+        meta_type = fileSystemFile->meta->type;
+        meta_flags = fileSystemFile->meta->flags;
+        meta_mode = fileSystemFile->meta->mode;
+        gid = fileSystemFile->meta->gid;
+        uid = fileSystemFile->meta->uid;
+    }
+
+    // Insert into the files table.
+    std::stringstream stmt;
+
+    try
+    {
+        // We don't provide file_id to the prepared function because it uses DEFAULT for that.
+        stmt << "EXECUTE addFsFileInfoPlan ("
+            << IMGDB_FILES_TYPE_FS << ", "
+            << IMGDB_FILES_STATUS_READY_FOR_ANALYSIS << ", "
+            << m_dbConnection->quote(fileName) << ", "
+            << parFileId << ", "
+            << fileSystemFile->name->type << ", "
+            << meta_type << ", "
+            << fileSystemFile->name->flags << ", "
+            << meta_flags << ", "
+            << size << ", "
+            << crtime << ", "
+            << ctime << ", "
+            << atime << ", "
+            << mtime << ", "
+            << meta_mode << ", "
+            << gid << ", "
+            << uid
+            << ", E" << m_dbConnection->quote(fullpath) << ")";
+
+        result R = executeStatement(stmt.str());
+        
+        // get the file_id from the last insert
+        fileID = 0;
+        if (R.size() == 1)
+        {
+            fileID = R[0][0].as<uint64_t>();
+        }
+        else if (R.size() > 1)
+        {
+            std::ostringstream msg;
+            msg << msgPrefix << "Unexpected number of records (" << R.size() << ") returned from files table INSERT";
+            LOGERROR(msg.str());
+        }
+    }
+    catch (const exception &e)
+    {
+        std::ostringstream errorMsg;
+        errorMsg << msgPrefix << "Error adding data to files table: " << e.what();
+        LOGERROR(errorMsg.str());
+
+        return -1;
+    }
+
+    // Insert into the fs_files table.
+    try
+    {
+        stmt.str("");
+        stmt << "INSERT INTO fs_files (file_id, fs_id, fs_file_id, attr_type, attr_id) VALUES ("
+            << fileID << ", " << fileSystemID << ", " << fileSystemFile->name->meta_addr << ", " << fileSystemAttrType << ", " << fileSystemAttrID << ")";
+        executeStatement(stmt.str());
+    }
+    catch (const exception &e)
+    {
+        std::stringstream errorMsg;
+        errorMsg << msgPrefix << "Error adding data to fs_files table: " << e.what();
+        LOGERROR(errorMsg.str());
+
+        return -1;
+    }
+
+    //if dir, update parent id cache
+    if (meta_type == TSK_FS_META_TYPE_DIR) {
+        storeParObjId(fileSystemID, fileSystemFile, fileID);
+    }
+
+    return 0;
+}
+
+/**
+ * Add block info to the database.  This table stores the run information for each file so that we
+ * can map which blocks are used by what files.
+ * @param a_fsId Id that the file is located in
+ * @param a_fileId ID of the file
+ * @param a_sequence The sequence number of this run in the file (0 for the first run, 1 for the second run, etc.)
+ * @param a_blk_addr Block address (the address that the file system uses -- NOT the physical sector addr)
+ * @param a_len The number of blocks in the run
+ * @returns 1 on error
+ */
+int TskImgDBPostgreSQL::addFsBlockInfo(int a_fsId, uint64_t a_fileId, int a_sequence, uint64_t a_blk_addr, uint64_t a_len)
+{
+    if (!initialized())
+        return 1;
+
+    stringstream stmt;
+
+    stmt << "INSERT INTO fs_blocks (fs_id, file_id, seq, blk_start, blk_len) VALUES ("
+        << a_fsId << ", " << a_fileId << ", " << a_sequence << ", " << a_blk_addr << ", " << a_len << ")";
+
+    try
+    {
+        executeStatement(stmt.str());
+    }
+    catch (const exception &e)
+    {
+        std::stringstream errorMsg;
+        errorMsg << "TskDBPostgreSQL::addFsBlockInfo : Error adding data to fs_blocks table: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+
+        return 1;
+    }
+
+    return 0;
+}
+
+
+int TskImgDBPostgreSQL::addAllocUnallocMapInfo(int a_volID, int unallocImgID, 
+                                               uint64_t unallocImgStart, uint64_t length, uint64_t origImgStart)
+{
+    if (!initialized())
+        return 1;
+
+    stringstream stmt;
+
+    stmt << "INSERT INTO alloc_unalloc_map (vol_id, unalloc_img_id, unalloc_img_sect_start, sect_len, orig_img_sect_start) VALUES ("
+        << a_volID << ", " << unallocImgID << ", " << unallocImgStart << ", " << length << ", " << origImgStart << ")";
+
+    try
+    {
+        executeStatement(stmt.str());
+        return 0;
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskDBPostgreSQL::addAllocUnallocMapInfo - Error adding data to alloc_unalloc_map table: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+
+        return 1;
+    }
+}
+
+/**
+ * Get information on all of the free sectors in an image.
+ *
+ * @return Info on unallocated runs (or NULL on error).  Caller must free this when done.
+ */
+SectorRuns * TskImgDBPostgreSQL::getFreeSectors() const
+{
+    if (!initialized())
+        return NULL;
+
+    SectorRuns * sr = new SectorRuns();
+
+    LOGINFO(L"TskImgDBPostgreSQL::getFreeSectors - Identifying Unallocated Sectors");
+
+    std::stringstream stmt;
+    std::wstringstream msg;
+
+    /********** FIND the unallocated volumes *************/
+    stmt << "SELECT vol_id, sect_start, sect_len, flags FROM vol_info";
+    try
+    {
+        pqxx::read_transaction readTrans(*m_dbConnection);
+        pqxx::result R = readTrans.exec(stmt);
+
+        for (int rownum=0; rownum < R.size(); ++rownum)
+        {
+            const result::tuple row = R[rownum];
+
+            int flags = row[3].as<int>();
+
+            int vol_id = row[0].as<int>();
+            int64_t start = row[1].as<int64_t>();
+            int64_t len = row[2].as<int64_t>();
+
+            // add the unallocated volumes
+            if (flags & TSK_VS_PART_FLAG_UNALLOC) {
+                sr->addRun(start, len, vol_id);
+            }
+
+            // add the allocated volumes that don't have a known file system
+            else
+            {
+                stmt.str("");
+                stmt << "SELECT fs_id FROM fs_info WHERE vol_id = " << vol_id;
+                pqxx::result R1 = readTrans.exec(stmt);
+
+                if (R1.size() == 0)
+                {
+                    sr->addRun(start, len, vol_id);
+                }
+            }
+        } // end of 'for' statement
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getFreeSectors - Error querying vol_info table: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+
+        return NULL;
+    }
+
+    /*************** Find the unallocated blocks in each file system *************/
+    // @@@ Need to make more dynamic
+    int blk_size[32];
+    memset(blk_size, 0, sizeof(blk_size));
+    uint64_t blk_count[32];
+    memset(blk_count, 0, sizeof(blk_count));
+    int vol_id[32];
+    uint64_t img_offset[32];
+
+    // get basic info on each file system
+    stmt.str("");
+    stmt << "SELECT fs_id, vol_id, img_byte_offset, block_size, block_count FROM fs_info";
+    try
+    {
+        pqxx::read_transaction readTrans(*m_dbConnection);
+        pqxx::result R = readTrans.exec(stmt);
+
+        LOGINFO(L"TskImgDBPostgreSQL::getFreeSectors - START LOOP: Find the unallocated blocks in each file system.");
+        for (int rownum=0; rownum < R.size(); ++rownum)
+        {
+            const result::tuple row = R[rownum];
+
+            int fs_id = row[0].as<int>();
+            if (fs_id > 32)
+            {
+                std::wstringstream errorMsg;
+                errorMsg << L"TskImgDBPostgreSQL::getFreeSectors - fs_id in fs_info is bigger than 32: " << fs_id;
+                LOGERROR(errorMsg.str());
+                break;
+            }
+
+            vol_id[fs_id] = row[1].as<int>();
+            img_offset[fs_id] = row[2].as<uint64_t>() / 512;
+            blk_size[fs_id] = row[3].as<int>() / 512;
+            blk_count[fs_id] = row[4].as<uint64_t>(); 
+
+            // Debug Info
+            msg.str(L"");
+            msg << L"TskImgDBPostgreSQL::getFreeSectors - fs_id=" << fs_id << " vol_id=" << vol_id[fs_id] << " img_offset=" << img_offset[fs_id] << " blk_size=" << blk_size[fs_id] <<
+                " blk_count=" << blk_count[fs_id];
+            LOGINFO(msg.str().c_str());
+        }
+        LOGINFO(L"TskImgDBPostgreSQL::getFreeSectors - DONE: Find the unallocated blocks in each file system.");
+    }// end of 'try' block
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getFreeSectors - Error querying fs_info table: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+
+        return NULL;
+    }
+
+    // see what blocks have been used and add them to a list
+    TSK_LIST *seen[32];
+    memset(seen, 0, 32*sizeof(TSK_LIST *));
+
+    stmt.str("");
+    stmt << "SELECT fs_id, file_id, blk_start, blk_len FROM fs_blocks";
+    try
+    {
+        pqxx::read_transaction readTrans(*m_dbConnection);
+        pqxx::result blocksResult = readTrans.exec(stmt);
+
+        LOGINFO(L"TskImgDBPostgreSQL::getFreeSectors - START LOOP: see what blocks have been used and add them to a list.");
+        for (int rownum=0; rownum < blocksResult.size(); ++rownum)
+        {
+            const result::tuple row = blocksResult[rownum];
+
+            int fs_id = row[0].as<int>();
+            if (fs_id > 32)
+            {
+                std::wstringstream errorMsg;
+                errorMsg << L"TskImgDBPostgreSQL::getFreeSectors - fs_id in fs_info is bigger than 32: " << fs_id;
+                LOGERROR(errorMsg.str());
+                break;
+            }
+            uint64_t file_id = row[1].as<uint64_t>();
+            int64_t addr = row[2].as<int64_t>();
+            int64_t len = row[3].as<int64_t>();
+
+            // We only want to consider the runs for files that we allocated.
+            int flags = 0;
+            stmt.str("");
+            stmt << "SELECT meta_flags from files WHERE file_id=" << file_id;
+            pqxx::result flagsResult = readTrans.exec(stmt);
+
+            // @@@ It is possible for fs_blocks entries to have a file_id = 0
+            // @@@ An example is "pointer" blocks in ext file systems that
+            // @@@ contain the addresses of where the file content is stored.
+            // @@@ We should tag these blocks with the actual file_id instead of 0
+            // @@@ and use another mechanism to identify them as non-content blocks.
+            if (file_id != 0 && flagsResult.size() == 0)
+            {
+                std::wstringstream errorMsg;
+                errorMsg << L"TskImgDBPostgreSQL::getFreeSectors - error finding flags for file " << file_id;
+                LOGERROR(errorMsg.str());
+                continue;
+            }
+            else if (flagsResult.size() > 0)
+            {
+                flags = flagsResult[0][0].as<int>();
+            }
+
+            if (flags & TSK_FS_META_FLAG_UNALLOC)
+                continue;
+
+            // @@@ We can probably find a more effecient storage method than this...
+            int error = 0;
+            for (int64_t i = 0; i < len; i++) {
+                if (tsk_list_add(&seen[fs_id], addr+i)) {
+                    std::wstringstream errorMsg;
+                    errorMsg << L"TskImgDBPostgreSQL::getFreeSectors - Error adding seen block address to list";
+                    LOGERROR(errorMsg.str());
+
+                    error = 1;
+                    break;
+                }
+            }
+            if (error)
+                break;
+        } // end of 'for' block
+        LOGINFO(L"TskImgDBPostgreSQL::getFreeSectors - DONE: see what blocks have been used and add them to a list.");
+    } // end of 'try' block
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getFreeSectors - Error querying fs_block table: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+
+        return NULL;
+    }
+
+    // cycle through each file system to find the unused blocks
+    LOGINFO(L"TskImgDBPostgreSQL::getFreeSectors - START LOOP: cycle through each file system to find the unused blocks.");
+    for (int f = 0; f < 32; f++) {
+        if (blk_count[f] == 0)
+            continue;
+
+        uint64_t st = 0;
+        int len = 0;
+        // we previously adjusted blk_size and img_offset to be in sectors
+
+        msg.str(L"");
+        msg << L"blk_count[" << f << "]=" << blk_count[f];
+        LOGINFO(msg.str().c_str());
+
+        for (uint64_t a = 0; a < blk_count[f]; a++) {
+            // see if this addr was used in a file
+            if (tsk_list_find(seen[f], a) == 0) {
+                // we already have a run being defined
+                if (len) {
+                    // same run, so add on to it
+                    if (st + len == a) {
+                        len++;
+                    }
+                    // different run, make a new one
+                    else {
+                        sr->addRun(img_offset[f]+st*blk_size[f], len*blk_size[f], vol_id[f]);
+                        st = a;
+                        len = 1;
+                    }
+                }
+                // start a new run
+                else {
+                    st = a;
+                    len = 1;
+                }
+            }
+        }
+        // add the final run
+        if (len) {
+            sr->addRun(img_offset[f]+st*blk_size[f], len*blk_size[f], vol_id[f]);
+        }
+        tsk_list_free(seen[f]);
+        seen[f] = NULL;
+    }
+    LOGINFO(L"TskImgDBPostgreSQL::getFreeSectors - DONE: cycle through each file system to find the unused blocks.");
+
+    return sr;
+}
+
+std::string TskImgDBPostgreSQL::getImageBaseName() const
+{
+    // There may be multiple file paths if the image is a split image. Oreder by sequence number to extract the file name from the first path.
+    pqxx::read_transaction trans(*m_dbConnection);
+    pqxx::result resultSet = trans.exec("SELECT name FROM image_names ORDER BY seq;");
+    if (resultSet.begin() != resultSet.end())
+    {
+        Poco::Path imagePath((resultSet.begin())[0].c_str()); 
+        return imagePath.getFileName();
+    }
+    else
+    {
+        return "";
+    }
+}
+
+std::vector<std::wstring> TskImgDBPostgreSQL::getImageNamesW() const
+{
+    std::vector<std::wstring> imgList;
+
+    if (!initialized())
+        return imgList;
+
+    stringstream stmt;
+
+    stmt << "SELECT name FROM image_names ORDER BY seq";
+
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+
+        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
+        {
+            std::wstring imgName;
+            Poco::UnicodeConverter::toUTF16(i[0].c_str(), imgName);
+
+            imgList.push_back(imgName);
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getImageNames - Error getting image names : "
+            << e.what();
+        LOGERROR(errorMsg.str());
+    }
+
+    if (imgList.empty()) 
+    {
+        LOGERROR(L"No images found in TskImgDBPostgres");
+    }
+
+    return imgList;
+}
+
+std::vector<std::string> TskImgDBPostgreSQL::getImageNames() const
+{
+    std::vector<std::string> imgList;
+
+    if (!initialized())
+        return imgList;
+
+    stringstream stmt;
+
+    stmt << "SELECT name FROM image_names ORDER BY seq";
+
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+
+        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
+        {
+            imgList.push_back(i[0].c_str());
+        }
+    }
+    catch (const exception &e)
+    {
+        std::stringstream errorMsg;
+        errorMsg << "TskImgDBPostgreSQL::getImageNames - Error getting image names : "
+            << e.what();
+        LOGERROR(errorMsg.str());
+    }
+
+    if (imgList.empty()) 
+    {
+        LOGERROR("No images found in TskImgDBPostgres");
+    }
+
+    return imgList;
+}
+
+/**
+ * @param a_fileId  File id to get information about
+ * @param a_fsOffset Byte offset of start of file system that the file is located in
+ * @param a_fsFileId File system-specific id of the file
+ * @param a_attrType Type of attribute for this file
+ * @param a_attrId The ID of the attribute for this file
+ * @returns 0 on success, -1 on error
+ */
+int TskImgDBPostgreSQL::getFileUniqueIdentifiers(uint64_t a_fileId, uint64_t &a_fsOffset, uint64_t &a_fsFileId, int &a_attrType, int &a_attrId) const
+{
+    if (!initialized())
+        return -1;
+
+    stringstream stmt;
+
+    stmt << "SELECT fs_file_id, attr_type, attr_id, fs_info.img_byte_offset "
+        "FROM fs_files, fs_info WHERE file_id=" << a_fileId
+        << " AND fs_info.fs_id = fs_files.fs_id";
+
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+
+        if (R.size() == 1)
+        {
+            R[0][0].to(a_fsFileId);
+            R[0][1].to(a_attrType);
+            R[0][2].to(a_attrId);
+            R[0][3].to(a_fsOffset);
+        }
+        else
+        {
+            std::wstringstream errorMsg;
+            errorMsg << L"TskImgDBPostgreSQL::getFileUniqueIdentifiers - Not a file system file : "
+                << a_fileId;
+            LOGERROR(errorMsg.str());
+
+            return -1;
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getFileUniqueIdentifiers - Error getting file identifiers: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+
+        return -1;
+    }
+
+    return 0;
+}
+
+/**
+ * Get number of volumes in image.
+ * @return Number of volumes in image or -1 on error
+ */
+int TskImgDBPostgreSQL::getNumVolumes() const
+{
+    if (!initialized())
+        return -1;
+
+    int count = 0;
+
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec("SELECT count(*) from vol_info");
+
+        if (R.size() == 1)
+        {
+            R[0][0].to(count);
+        }
+        else
+        {
+            std::wstringstream errorMsg;
+            errorMsg << L"TskImgDBPostgreSQL::getNumVolumes - Unexpected number of rows returned."
+                << R.size();
+            LOGERROR(errorMsg.str());
+
+            return -1;
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getNumVolumes - Error getting number of volumes: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+
+        return -1;
+    }
+
+    return count;
+}
+
+/**
+ * Get number of files in image.
+ * @return Number of files in image or -1 on error
+ */
+int TskImgDBPostgreSQL::getNumFiles() const
+{
+    if (!initialized())
+        return -1;
+
+    std::string condition("");
+    int count = getFileCount(condition);
+
+    return count;
+}
+
+/**
+ * @returns the session_id or -1 on error.
+ */
+int TskImgDBPostgreSQL::getSessionID() const
+{
+    if (!initialized())
+        return -1;
+
+    int sessionId;
+    stringstream stmt;
+
+    stmt << "SELECT version FROM db_info WHERE name = 'SID'";
+
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+
+        if (R.size() == 1)
+        {
+            R[0][0].to(sessionId);
+        }
+        else
+        {
+            std::wstringstream errorMsg;
+            errorMsg << L"TskImgDBPostgreSQL::getSessionID - Unexpected number of rows returned."
+                << R.size();
+            LOGERROR(errorMsg.str());
+
+            return -1;
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getSessionID - Error getting session id: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+
+        return -1;
+    }
+
+    return sessionId;
+}
+
+/**
+ * begin is a no-op since all PostgreSQL statements are run in the
+ * context of a transaction.
+ */
+int TskImgDBPostgreSQL::begin()
+{
+    return 0;
+}
+
+/**
+ * commit is a no-op since all PostgreSQL statements are run in the
+ * context of a transaction.
+ */
+int TskImgDBPostgreSQL::commit()
+{
+    return 0;
+}
+
+
+UnallocRun * TskImgDBPostgreSQL::getUnallocRun(int a_unalloc_img_id, int a_file_offset) const
+{
+    if (!initialized())
+        return NULL;
+
+    stringstream stmt;
+
+    stmt << "SELECT vol_id, unalloc_img_sect_start, sect_len, orig_img_sect_start FROM "
+        "alloc_unalloc_map WHERE unalloc_img_id = " << a_unalloc_img_id 
+        << " AND unalloc_img_sect_start <= " << a_file_offset << " ORDER BY unalloc_img_sect_start DESC";
+
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+
+        if (R.size() > 0)
+        {
+            int vol_id; R[0][0].to(vol_id);
+            int unalloc_img_sect_start; R[0][1].to(unalloc_img_sect_start);
+            int sect_len; R[0][2].to(sect_len);
+            int orig_img_sect_start; R[0][3].to(orig_img_sect_start);
+
+            return new UnallocRun(vol_id, a_unalloc_img_id, unalloc_img_sect_start, sect_len, orig_img_sect_start);
+        }
+        else
+        {
+            LOGERROR(L"TskImgDBPostgreSQL::getUnallocRun - No records returned.\n");
+            return new UnallocRun(-1, -1, -1, -1, -1);
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getUnallocRun - Error fetching data from alloc_unalloc_map table: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+
+        return new UnallocRun(-1, -1, -1, -1, -1);
+    }
+}
+
+/**
+ * Adds information about a carved file into the database.  This includes the sector layout
+ * information. 
+ * 
+ * @param size Number of bytes in file
+ * @param runStarts Array with starting sector (relative to start of image) for each run in file.
+ * @param runLengths Array with number of sectors in each run 
+ * @param numRuns Number of entries in previous arrays
+ * @param fileId Carved file Id (output)
+ * @returns 0 on success or -1 on error.
+ */
+int TskImgDBPostgreSQL::addCarvedFileInfo(int vol_id, const char *name, uint64_t size, 
+                                          uint64_t *runStarts, uint64_t *runLengths, int numRuns, uint64_t & fileId)
+{
+    if (!initialized())
+        return -1;
+
+    std::string utf8Name(name);
+
+    fileId = 0;
+
+    stringstream stmt;
+
+    stmt << "EXECUTE addCarvedFileInfoPlan ("
+        << IMGDB_FILES_TYPE_CARVED << ", "
+        << IMGDB_FILES_STATUS_CREATED << ", "
+        << m_dbConnection->quote(utf8Name) << ", "
+        << TSK_FS_NAME_TYPE_REG << ", "
+        << TSK_FS_META_TYPE_REG << ", "
+        << TSK_FS_NAME_FLAG_UNALLOC << ", "
+        << TSK_FS_META_FLAG_UNALLOC << ", "
+        << size << ","
+        << m_dbConnection->quote(utf8Name) << ")";
+
+    try
+    {
+        pqxx::work W(*m_dbConnection);
+        pqxx::result R = W.exec(stmt);
+
+        // get the file_id from the last insert
+        fileId = R[0][0].as<uint64_t>();
+
+        stmt.str("");
+
+        // insert into the carved_files_table
+        stmt << "INSERT INTO carved_files (file_id, vol_id) VALUES ("
+            << fileId << ", " << vol_id << ")";
+
+        R = W.exec(stmt);
+
+        // insert into carved_sectors table
+        for (int i = 0; i < numRuns; i++)
+        {
+            stmt.str("");
+            stmt << "INSERT INTO carved_sectors (file_id, seq, sect_start, sect_len) VALUES ("
+                << fileId << ", " << i << ", " << runStarts[i] << ", " << runLengths[i] << ")";
+
+            R = W.exec(stmt);
+        }
+
+        W.commit();
+    }
+    catch (exception& ex)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::addCarvedFileInfo - Error adding data to carved_files table: "
+            << ex.what();
+        LOGERROR(errorMsg.str());
+
+        return -1;
+    }
+
+    return 0;
+}
+
+/**
+ * Adds information about derived files to the database.  Derived files typically come
+ * from archives and may be compressed.
+ * 
+ * @param name The name of the file.
+ * @param parentId The id of the file from which this file is derived.
+ * @param size The size of the file.
+ * @param details This is a string that may contain extra details related
+ * to the particular type of mechanism that was used to derive this file, 
+ * e.g. files derived from zip archives may have extra information about the
+ * compressed size of the file.
+ * @param ctime Time file system file entry was changed.
+ * @param crtime Time the file was created.
+ * @param atime Last access time.
+ * @param mtime Last modified time.
+ * @param fileId Return the file_id value.
+ *
+ * @returns 0 on success or -1 on error.
+ */
+int TskImgDBPostgreSQL::addDerivedFileInfo(const std::string& name, const uint64_t parentId, 
+                                           const bool isDirectory, const uint64_t size,
+                                           const std::string& details,
+                                           const int ctime, const int crtime, const int atime, const int mtime,
+                                           uint64_t &fileId, std::string path)
+{
+    if (!initialized())
+        return -1;
+
+    fileId = 0;
+
+    // Ensure that strings are valid UTF-8
+    std::vector<char> cleanName(name.begin(), name.end());
+    cleanName.push_back('\0');
+    TskUtilities::cleanUTF8(&cleanName[0]);
+
+    std::vector<char> cleanDetails(details.begin(), details.end());
+    cleanDetails.push_back('\0');
+    TskUtilities::cleanUTF8(&cleanDetails[0]);
+
+    std::vector<char> cleanPath(path.begin(), path.end());
+    cleanPath.push_back('\0');
+    TskUtilities::cleanUTF8(&cleanPath[0]);
+
+    TSK_FS_NAME_TYPE_ENUM dirType = isDirectory ? TSK_FS_NAME_TYPE_DIR : TSK_FS_NAME_TYPE_REG;
+    TSK_FS_META_TYPE_ENUM metaType = isDirectory ? TSK_FS_META_TYPE_DIR : TSK_FS_META_TYPE_REG;
+
+    std::stringstream stmt;
+
+    stmt << "EXECUTE addDerivedFileInfoPlan ("
+        << IMGDB_FILES_TYPE_DERIVED << ", "
+        << IMGDB_FILES_STATUS_CREATED << ", "
+        << m_dbConnection->quote(&cleanName[0]) << ", " 
+        << parentId << ", "
+        << dirType << ", "
+        << metaType << ", "
+        << size << ", "
+        << crtime << ", "
+        << ctime << ", "
+        << atime << ", "
+        << mtime << ", "
+        << m_dbConnection->quote(&cleanPath[0]) << ")";
+
+    try
+    {
+        pqxx::work W(*m_dbConnection);
+        pqxx::result R = W.exec(stmt);
+
+        // get the file_id from the last insert
+        fileId = R[0][0].as<uint64_t>();
+
+        stmt.str("");
+
+        // insert into the derived_files table
+        stmt << "INSERT INTO derived_files (file_id, derivation_details) VALUES ("
+            << fileId << ", E" << m_dbConnection->quote(&cleanDetails[0]) << ")";
+
+        R = W.exec(stmt);
+        W.commit();
+    }
+    catch (exception& ex)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::addDerivedFileInfo - Error adding derived file data: "
+            << ex.what();
+        LOGERROR(errorMsg.str());
+
+        return -1;
+    }
+
+    return 0;
+}
+
+/**
+ * Fills outBuffer with file IDs that match the name fileName.
+ * Returns the number of file IDs written into outBuffer or -1 on error.
+ */
+int TskImgDBPostgreSQL::getFileIds(char *a_fileName, uint64_t *a_outBuffer, int a_buffSize) const
+{
+    if (!initialized())
+        return -1;
+
+    int outIdx = 0;
+    stringstream stmt;
+
+    stmt << "SELECT file_id FROM files WHERE name LIKE "
+        << m_dbConnection->quote(a_fileName);
+
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+
+        if (R.size() > a_buffSize)
+        {
+            std::wstringstream errorMsg;
+            errorMsg << L"TskImgDBPostgreSQL::getFileIds - Number of file ids returned ("
+                << R.size() << ") is greated than buffer capacity (" << a_buffSize << ")";
+            LOGERROR(errorMsg.str());
+            return -1;
+        }
+
+        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
+        {
+            i[0].to(a_outBuffer[outIdx++]);
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getFileIds - Error getting file ids : "
+            << e.what();
+        LOGERROR(errorMsg.str());
+
+        return -1;
+    }
+
+    return outIdx;
+}
+
+/**
+ * Given the last file ID ready for analysis, find the largest file ID ready of analysis (in maxFileId)
+ * Returns 0 on success or -1 on error.
+ */
+int TskImgDBPostgreSQL::getMaxFileIdReadyForAnalysis(uint64_t a_lastFileId, uint64_t & maxFileId) const
+{
+    if (!initialized())
+        return -1;
+
+    maxFileId = 0;
+    stringstream stmt;
+
+    stmt << "SELECT max(file_id) FROM files WHERE status = " << TskImgDB::IMGDB_FILES_STATUS_READY_FOR_ANALYSIS
+        << " AND file_id >= " << a_lastFileId;
+
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+
+        if (R.size() == 1)
+        {
+            R[0][0].to(maxFileId);
+        }
+        else
+        {
+            std::wstringstream errorMsg;
+            errorMsg << L"TskImgDBPostgreSQL::getMaxFileIdReadyForAnalysis - Unexpected number of rows returned."
+                << R.size();
+            LOGERROR(errorMsg.str());
+            return -1;
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getMaxFileIdReadyForAnalysis - Error retrieving maximum file id: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+
+        return -1;
+    }
+
+    return 0;
+}
+
+/*
+ * Return the minimum file id with status = READY_FOR_ANALYSIS in minFileId.
+ * Return 0 on success, -1 if failed.
+ */
+int TskImgDBPostgreSQL::getMinFileIdReadyForAnalysis(uint64_t & minFileId) const
+{
+    if (!initialized())
+        return -1;
+
+    minFileId = 0;
+    stringstream stmt;
+
+    stmt << "SELECT min(file_id) FROM files WHERE status = " << TskImgDB::IMGDB_FILES_STATUS_READY_FOR_ANALYSIS;
+
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+
+        if (R.size() == 1)
+        {
+            R[0][0].to(minFileId);
+        }
+        else
+        {
+            std::wstringstream errorMsg;
+            errorMsg << L"TskImgDBPostgreSQL::getMinFileIdReadyForAnalysis - Unexpected number of rows returned."
+                << R.size();
+            LOGERROR(errorMsg.str());
+            return -1;
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getMinFileIdReadyForAnalysis - Error retrieving minimum file id: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+
+        return -1;
+    }
+
+    return 0;
+}
+
+SectorRuns * TskImgDBPostgreSQL::getFileSectors(uint64_t a_fileId) const 
+{
+    if (!initialized())
+        return NULL;
+
+    SectorRuns * sr = new SectorRuns();
+    int srCount = 0;
+
+    stringstream stmt;
+
+    stmt << "SELECT fs_blocks.blk_start, fs_blocks.blk_len, "
+        "fs_info.block_size, fs_info.img_byte_offset, fs_info.vol_id "
+        "FROM files "
+        "JOIN fs_files ON files.file_id = fs_files.file_id "
+        "JOIN fs_blocks ON files.file_id = fs_blocks.file_id "
+        "JOIN fs_info ON fs_blocks.fs_id = fs_info.fs_id "
+        "WHERE files.file_id = " << a_fileId << " ORDER BY fs_blocks.seq;";
+
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+
+        for (pqxx::result::const_iterator i = R.begin(); i!= R.end(); ++i)
+        {
+            uint64_t blkStart; i[0].to(blkStart);
+            uint64_t blkLength; i[1].to(blkLength);
+            int blkSize; i[2].to(blkSize);
+            uint64_t imgByteOffset; i[3].to(imgByteOffset);
+            int volId; i[4].to(volId);
+
+            uint64_t start = (imgByteOffset + blkStart * blkSize) / 512;
+            uint64_t len = (blkLength * blkSize) / 512;
+
+            sr->addRun(start, len, volId);
+            srCount++;
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getFileSectors - Error finding block data for file_id= " << a_fileId
+            << e.what() << std::endl;
+        LOGERROR(errorMsg.str());
+
+        return NULL;
+    }
+
+    return sr;
+}
+
+/**
+ * update the status field in the database for a given file.
+ * @param a_file_id File to update.
+ * @param a_status Status flag to update to.
+ * @returns 1 on error.
+ */
+int TskImgDBPostgreSQL::updateFileStatus(uint64_t a_file_id, TskImgDB::FILE_STATUS a_status)
+{
+    if (!initialized())
+        return 1;
+
+    stringstream stmt;
+
+    stmt << "UPDATE files SET status = " << a_status << " WHERE file_id = " << a_file_id;
+
+    try
+    {
+        work W(*m_dbConnection);
+        result R = W.exec(stmt);
+        W.commit();
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::updateFileStatus - Error updating file status: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+
+        return 1;
+    }
+
+    return 0;
+}
+
+/**
+ * update the known status field in the database for a given file.
+ * @param a_file_id File to update.
+ * @param a_status Status flag to update to.
+ * @returns 1 on error.
+ */
+int TskImgDBPostgreSQL::updateKnownStatus(uint64_t a_file_id, TskImgDB::KNOWN_STATUS a_status)
+{
+    if (!initialized())
+        return 1;
+
+    stringstream stmt;
+
+    stmt << "SELECT known FROM file_hashes WHERE file_id = " << a_file_id;
+
+    try
+    {
+        int status;
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+        pqxx::result::const_iterator i = R.begin(); 
+        if(R.size() != 0)
+            i[0].to(status);
+        else
+            status = TskImgDB::IMGDB_FILES_UNKNOWN;
+        trans.commit();
+
+        if((status == TskImgDB::IMGDB_FILES_UNKNOWN) ||
+           (a_status == TskImgDB::IMGDB_FILES_KNOWN_BAD) ||
+           (status == TskImgDB::IMGDB_FILES_KNOWN && a_status == TskImgDB::IMGDB_FILES_KNOWN_GOOD)){
+            stmt.str("");
+            stmt << "UPDATE file_hashes SET known = " << a_status << " WHERE file_id = " << a_file_id;
+
+            work W(*m_dbConnection);
+            R = W.exec(stmt);
+            W.commit();
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::updateKnownStatus - Error updating file status: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+
+        return 1;
+    }
+
+    return 0;
+}
+
+bool TskImgDBPostgreSQL::dbExist() const
+{
+    bool rc = false;
+
+    // Get current user name. This will get used in connecting to the database.
+    char name[UNLEN+1];
+    DWORD size = UNLEN+1;
+
+    GetUserNameA(name, &size);
+
+    std::string db_host = GetSystemProperty(TskSystemProperties::DB_HOST);
+    std::string db_port = GetSystemProperty(TskSystemProperties::DB_PORT);
+    std::string db_host_ip;
+    if (!TskUtilities::getHostIP(db_host, db_host_ip))
+        return false;
+
+    try
+    {
+        // Construct the connection string to connect to the Postgres server.
+        std::stringstream pgConnectionString;
+        pgConnectionString << "host='" << db_host_ip << "' port='" << db_port
+            << "' dbname='postgres' user='" << name << "'";
+
+        pqxx::connection pgConnection(pgConnectionString.str());
+
+        // Check whether the database exists
+        pqxx::nontransaction nontrans(pgConnection);
+
+        std::stringstream dbQuery;
+        dbQuery << "select count(*) from pg_catalog.pg_database where datname = " << nontrans.quote(m_dbName);
+
+        pqxx::result R = nontrans.exec(dbQuery);
+
+        if (R.size() == 0 || R[0][0].as<int>() == 0) 
+        {
+            // There is no database.
+            ;
+        } else {
+            rc = true;
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskDBPostgreSQL::dbExist - Error pg_database where datname= " << m_dbName.c_str() << " Error: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+    }
+    return rc;
+}
+
+void TskImgDBPostgreSQL::getCarvedFileInfo(const std::string& stmt,
+                                           std::map<uint64_t, std::string>& results) const
+{
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+        uint64_t file_id;
+        std::string cfileName;
+        std::string fileName;
+        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
+        {
+            i[0].to(file_id);
+            i[1].to(fileName);
+            i[2].to(cfileName);
+
+            // Grab the extension and append it to the cfile name
+            std::string::size_type pos = fileName.rfind('.');
+            if (pos != std::string::npos)
+                cfileName.append(fileName.substr(pos));
+
+            results[file_id] = cfileName;
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream msg;
+        msg << L"TskImgDBPostgreSQL::getCarvedFileInfo - Error getting carved file details : "
+            << e.what();
+        LOGERROR(msg.str());
+    }
+}
+
+std::map<uint64_t, std::string> TskImgDBPostgreSQL::getUniqueCarvedFiles(HASH_TYPE hashType) const
+{
+    std::map<uint64_t, std::string> results;
+
+    if (!initialized())
+        return results;
+
+    string hash;
+    switch (hashType) {
+    case TskImgDB::MD5:
+        hash = "md5";
+        break;
+    case TskImgDB::SHA1:
+        hash = "sha1";
+        break;
+    case TskImgDB::SHA2_256:
+        hash = "sha2_256";
+        break;
+    case TskImgDB::SHA2_512:
+        hash = "sha2_512";
+        break;
+    default:
+        std::wstringstream msg;
+        msg << L"TskImgDBPostgreSQL::getUniqueCarvedFiles - Unsupported hashType : " << hashType;
+        LOGERROR(msg.str());
+        return results;
+    }
+
+    std::stringstream stmt;
+
+    // If hashes have not been calculated return all carved files.
+    stmt << "select count(*) from file_hashes";
+
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+        uint64_t counter = 0;
+        if (R.size() == 1)
+            counter = R[0][0].as<uint64_t>();
+        if (counter == 0) 
+        {
+            std::wstringstream msg;
+            msg << L"TskImgDBPostgreSQL::getUniqueCarvedFiles - file_hashes table is empty";
+            LOGWARN(msg.str());
+
+            trans.commit();
+
+            stmt.str("");
+            stmt << "select c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' "
+                << "|| c.file_id from files f, carved_files c, carved_sectors cs "
+                << "where c.file_id = cs.file_id and cs.seq = 0 and f.file_id = c.file_id order by c.file_id";
+            getCarvedFileInfo(stmt.str(), results);
+            return results;
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream msg;
+        msg << L"TskImgDBPostgreSQL::getUniqueCarvedFileIds - Error getting file_hashes count : "
+            << e.what();
+        LOGERROR(msg.str());
+    }
+
+    stmt.str("");
+    // Get the set of files for which the hash has been calculated.
+    stmt << "select c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' "
+        << "|| c.file_id from files f, carved_files c, carved_sectors cs "
+        << "where c.file_id = cs.file_id and cs.seq = 0 and f.file_id = c.file_id and c.file_id in "
+        << "(select min(file_id) from file_hashes where " << hash << " != '' group by " << hash << " ) order by c.file_id";
+
+    getCarvedFileInfo(stmt.str(), results);
+
+    // Next get the set of files for which the hash has *not* been calculated.
+    stmt.str("");
+    stmt << "select c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' "
+        << "|| c.file_id from files f, carved_files c, carved_sectors cs "
+        << "where c.file_id = cs.file_id and cs.seq = 0 and f.file_id = c.file_id and c.file_id in "
+        << "(select file_id from file_hashes where " << hash << " = '') order by c.file_id";
+
+    getCarvedFileInfo(stmt.str(), results);
+
+    // Finally, add file info for all of the carved files for which there are no hashes of any sort.
+        // All of these files must be included because without hashes there is no way to determine uniqueness.
+    stmt.clear();
+    stmt.str("");
+    stmt << "SELECT c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || c.file_id "
+         << "FROM files f, carved_files c, carved_sectors cs "
+         << "WHERE c.file_id = cs.file_id AND cs.seq = 0 AND f.file_id = c.file_id AND c.file_id NOT IN "
+         << "(SELECT fh.file_id FROM file_hashes fh) ORDER BY c.file_id";
+    getCarvedFileInfo(stmt.str(), results);
+
+    return results;
+}
+
+void TskImgDBPostgreSQL::getCarvedFileInfo(const std::string &stmtToExecute, bool getHash, std::vector<TskCarvedFileInfo> &carvedFileInfos) const
+{
+    TskCarvedFileInfo info;
+    std::string fileName;
+    pqxx::read_transaction trans(*m_dbConnection);
+    pqxx::result result = trans.exec(stmtToExecute);
+    for (pqxx::result::const_iterator row = result.begin(); row != result.end(); ++row)
+    {
+        row[0].to(info.fileID);
+        row[1].to(fileName);
+        row[2].to(info.cFileName);
+        if (getHash)
+        {
+            row[3].to(info.hash);
+        }
+
+        // Append the extension from the original file name to the constructed "cfile" name.
+        std::string::size_type pos = fileName.rfind('.');
+        if (pos != std::string::npos)
+        {
+            info.cFileName.append(fileName.substr(pos));
+        }
+
+        carvedFileInfos.push_back(info);
+    }
+}
+
+std::vector<TskCarvedFileInfo> TskImgDBPostgreSQL::getUniqueCarvedFilesInfo(HASH_TYPE hashType) const
+{
+    const std::string msgPrefix = "TskImgDBPostgreSQL::getUniqueCarvedFilesInfo : "; 
+
+    if (!initialized())
+    {
+        std::ostringstream msg;
+        msg << msgPrefix << "no database connection";
+        throw TskException(msg.str());
+    }
+
+    // Map the hash type to a file_hashes table column name.
+    string hash;
+    switch (hashType) 
+    {
+    case TskImgDB::MD5:
+        hash = "md5";
+        break;
+    case TskImgDB::SHA1:
+        hash = "sha1";
+        break;
+    case TskImgDB::SHA2_256:
+        hash = "sha2_256";
+        break;
+    case TskImgDB::SHA2_512:
+        hash = "sha2_512";
+        break;
+    default:
+        std::ostringstream msg;
+        msg << msgPrefix << "unsupported hash type :" << hashType;
+        throw TskException(msg.str());
+    }
+
+    try
+    {
+        std::vector<TskCarvedFileInfo> carvedFileInfos;
+
+        // Do a quick check to see if any hashes have been calculated.
+        std::ostringstream stmt;
+        stmt << "SELECT COUNT(*) FROM file_hashes;";
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result result = trans.exec(stmt.str());
+        uint64_t counter = 0;
+        if (result.size() == 1)
+        {
+            counter = result[0][0].as<uint64_t>();
+        }
+        trans.commit();
+
+        if (counter != 0)
+        {
+            // At least one type of hash has been calculated (presumably for all files, but this is not guaranteed). 
+            // First, add file info for the set of unique files among the carved files for which the specified type of hash is available.
+            stmt.clear();
+            stmt.str("");
+            stmt << "SELECT c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || c.file_id, fh." << hash << " "
+                 << "FROM files f, carved_files c, carved_sectors cs, file_hashes fh "
+                 << "WHERE c.file_id = cs.file_id AND cs.seq = 0 AND f.file_id = c.file_id AND c.file_id = fh.file_id AND c.file_id IN "
+                 << "(SELECT MIN(file_id) FROM file_hashes WHERE " << hash << " != '' GROUP BY " << hash << ") ORDER BY c.file_id";
+            getCarvedFileInfo(stmt.str(), true, carvedFileInfos);
+
+             // Next, add file info for all of the carved files for which the specified hash is not available.
+             // All of these files must be included because without the specified hash there is no acceptable way to determine uniqueness.
+            stmt.clear();
+            stmt.str("");
+            stmt << "SELECT c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || c.file_id "
+                 << "FROM files f, carved_files c, carved_sectors cs "
+                 << "WHERE c.file_id = cs.file_id AND cs.seq = 0 AND f.file_id = c.file_id AND c.file_id IN "
+                 << "(SELECT file_id FROM file_hashes WHERE " << hash << " = '') ORDER BY c.file_id";
+            getCarvedFileInfo(stmt.str(), false, carvedFileInfos);
+
+            // Finally, add file info for all of the carved files for which there are no hashes of any sort.
+             // All of these files must be included because without hashes there is no way to determine uniqueness.
+            stmt.clear();
+            stmt.str("");
+            stmt << "SELECT c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || c.file_id "
+                 << "FROM files f, carved_files c, carved_sectors cs "
+                 << "WHERE c.file_id = cs.file_id AND cs.seq = 0 AND f.file_id = c.file_id AND c.file_id NOT IN "
+                 << "(SELECT fh.file_id FROM file_hashes fh) ORDER BY c.file_id";
+            getCarvedFileInfo(stmt.str(), false, carvedFileInfos);
+        }
+        else
+        {
+            // No hashes have been calculated.
+            // Return carved file info all of the carved files because without hashes there is no way to determine uniqueness.
+            stmt.clear();
+            stmt.str("");
+            stmt << "SELECT c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || c.file_id "
+                 << "FROM files f, carved_files c, carved_sectors cs "
+                 << "WHERE c.file_id = cs.file_id AND cs.seq = 0 AND f.file_id = c.file_id ORDER BY c.file_id";
+            getCarvedFileInfo(stmt.str(), false, carvedFileInfos);
+
+            std::ostringstream msg;
+            msg << msgPrefix << "no hashes available, returning all carved files";
+            LOGWARN(msg.str());
+        }
+
+        return carvedFileInfos;
+    }
+    catch (std::exception &ex)
+    {
+        std::stringstream msg;
+        msg << msgPrefix << "std::exception: " << ex.what();
+        throw TskException(msg.str());
+    }
+    catch (...)
+    {
+        throw TskException(msgPrefix + "unrecognized exception");
+    }
+}
+
+std::vector<uint64_t> TskImgDBPostgreSQL::getCarvedFileIds() const
+{
+    return getFileIdsWorker("carved_files");
+}
+
+std::vector<uint64_t> TskImgDBPostgreSQL::getUniqueFileIds(HASH_TYPE hashType) const
+{
+    std::vector<uint64_t> results;
+
+    if (!initialized())
+        return results;
+
+    string hash;
+    switch (hashType) {
+    case TskImgDB::MD5:
+        hash = "md5";
+        break;
+    case TskImgDB::SHA1:
+        hash = "sha1";
+        break;
+    case TskImgDB::SHA2_256:
+        hash = "sha2_256";
+        break;
+    case TskImgDB::SHA2_512:
+        hash = "sha2_512";
+        break;
+    default:
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getUniqueFileIds - Unsupported hashType : " << hashType;
+        LOGERROR(errorMsg.str());
+        return results;
+    }
+
+    stringstream stmt;
+
+    stmt << "SELECT min(file_id) FROM file_hashes WHERE " << hash << " != '' group by " << hash ;
+
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+        uint64_t file_id;
+        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
+        {
+            i[0].to(file_id);
+            results.push_back(file_id);
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getUniqueFileIds - Error getting file ids : "
+            << e.what();
+        LOGERROR(errorMsg.str());
+    }
+
+    // Get all carved_files with empty hash, if hash was not generated.
+    stmt << "SELECT file_id FROM file_hashes WHERE " << hash << " = '' ";
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+        uint64_t file_id;
+        uint64_t counter = 0;
+        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
+        {
+            i[1].to(file_id);
+            results.push_back(file_id);
+            counter++;
+        }
+        if (counter) {
+            // There are some files without hash, generate a warning.
+            std::wstringstream errorMsg;
+            errorMsg << L"TskImgDBPostgreSQL::getUniqueFileIds - Including " << counter << L" files with no hash value.";
+            LOGWARN(errorMsg.str());
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getUniqueFileIds - Error getting file ids : "
+            << e.what();
+        LOGERROR(errorMsg.str());
+    }
+    return results;
+}
+
+/**
+ * Get the list of file ids that match the given criteria.
+ * The given string will be appended to "select files.file_id from files".
+ *
+ * @param condition Must be a valid SQL string defining the selection criteria.
+ * @returns The collection of file ids matching the selection criteria. Throws
+ * TskException if database not initialized.
+ */
+std::vector<uint64_t> TskImgDBPostgreSQL::getFileIds(const std::string& condition) const 
+{
+    if (!initialized())
+        throw TskException("Database not initialized.");
+
+    std::vector<uint64_t> results;
+    
+    std::string stmt("SELECT files.file_id from files");
+
+    constructStmt(stmt, condition);
+
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+        uint64_t file_id;
+        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
+        {
+            i[0].to(file_id);
+            results.push_back(file_id);
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getFileIds - Error getting file ids : "
+            << e.what();
+        LOGERROR(errorMsg.str());
+    }
+
+    return results;
+}
+
+/**
+ * Get the list of file records that match the given criteria.
+ * The given string will be appended to "select .... from files".
+ *
+ * @param condition Must be a valid SQL string defining the selection criteria.
+ * @returns The collection of file records matching the selection criteria. Throws
+ * TskException if database not initialized.
+ */
+const std::vector<TskFileRecord> TskImgDBPostgreSQL::getFileRecords(const std::string& condition) const 
+{
+    if (!initialized())
+        throw TskException("Database not initialized.");
+
+    std::vector<TskFileRecord> results;
+    
+    std::stringstream stmtstrm;
+    stmtstrm << "SELECT f.file_id, f.type_id, f.name, f.par_file_id, f.dir_type, f.meta_type, f.dir_flags, "
+        << "f.meta_flags, f.size, f.ctime, f.crtime, f.atime, f.mtime, f.mode, f.uid, f.gid, f.status, f.full_path, "
+        << "fh.md5, fh.sha1, fh.sha2_256, fh.sha2_512 "
+        << "FROM files f LEFT OUTER JOIN file_hashes fh ON f.file_id = fh.file_id ";
+
+    std::string stmt = stmtstrm.str();
+
+    constructStmt(stmt, condition);
+
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
+        {
+            TskFileRecord fileRecord;
+            
+            i[0].to(fileRecord.fileId);
+            i[1].to((int &)fileRecord.typeId);
+            i[2].to(fileRecord.name);
+            i[3].to(fileRecord.parentFileId);
+            i[4].to((int &)fileRecord.dirType);
+            i[5].to((int &)fileRecord.metaType);
+            i[6].to((int &)fileRecord.dirFlags);
+            i[7].to((int &)fileRecord.metaFlags);
+            i[8].to(fileRecord.size);
+            i[9].to(fileRecord.ctime);
+            i[10].to(fileRecord.crtime);
+            i[11].to(fileRecord.atime);
+            i[12].to(fileRecord.mtime);
+            i[13].to((int &)fileRecord.mode);
+            i[14].to(fileRecord.uid);
+            i[15].to(fileRecord.gid);
+            i[16].to((int &)fileRecord.status);
+            i[17].to(fileRecord.fullPath);
+            i[18].to(fileRecord.md5);
+            i[19].to(fileRecord.sha1);
+            i[20].to(fileRecord.sha2_256);
+            i[21].to(fileRecord.sha2_512);   
+            results.push_back(fileRecord);
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getFileRecords - Error getting file records: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+    }
+
+    return results;
+}
+
+/**
+ * Get the number of files that match the given criteria.
+ * The given string will be appended to "select files.file_id from files".
+ *
+ * @param condition Must be a valid SQL string defining the selection criteria.
+ * @returns The number of files matching the selection criteria. 
+ */
+int TskImgDBPostgreSQL::getFileCount(const std::string& condition) const 
+{
+    if (!initialized())
+        throw TskException("Database not initialized.");
+
+    int result = 0;
+    std::string stmt("SELECT count(files.file_id) from files");
+
+    constructStmt(stmt, condition);
+
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+
+        if (R.size() == 1)
+        {
+            R[0][0].to(result);
+        }
+        else
+        {
+            std::wstringstream msg;
+            msg << L"TskImgDBPostgreSQL::getFileCount - Unexpected number of rows returned."
+                << R.size();
+            LOGERROR(msg.str());
+
+            return -1;
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream msg;
+        msg << L"TskImgDBPostgreSQL::getFileCount - Error getting file count : "
+            << e.what();
+        LOGERROR(msg.str());
+        return -1;
+    }
+
+    return result;
+}
+
+
+
+void TskImgDBPostgreSQL::constructStmt(std::string& stmt, std::string condition) const
+{
+    if (!condition.empty())
+    {
+        // Remove leading whitespace from condition
+        std::string trimmedCond = Poco::trimLeft(condition);
+
+        std::string whereClause("WHERE");
+        std::string joinClause("JOIN");
+        std::string leftClause("LEFT");
+        std::string orderClause("ORDER");
+
+        // If the condition doesn't start with a WHERE clause and it doesn't
+        // start with a comma it is presumably extending the FROM clause with
+        // one or more table names. In this case we need to add the comma to
+        // the statement.
+        if (Poco::icompare(trimmedCond, 0, whereClause.length(), whereClause) != 0 
+            && Poco::icompare(trimmedCond, 0, joinClause.length(), joinClause) != 0
+            && Poco::icompare(trimmedCond, 0, leftClause.length(), leftClause) != 0
+            && Poco::icompare(trimmedCond, 0, orderClause.length(), orderClause) != 0
+            && trimmedCond[0] != ',')
+        {
+            stmt.append(",");
+        }
+    }
+
+    stmt.append(" ");
+    stmt.append(condition);
+}
+
+std::vector<uint64_t> TskImgDBPostgreSQL::getFileIds() const
+{
+    return getFileIdsWorker("files");
+}
+
+std::vector<uint64_t> TskImgDBPostgreSQL::getFileIdsWorker(std::string tableName, const std::string condition) const
+{
+    std::vector<uint64_t> results;
+
+    if (!initialized())
+        return results;
+
+    stringstream stmt;
+    stmt << "SELECT file_id FROM " << tableName;
+    if (condition.compare("") != 0)
+        stmt << " WHERE " << condition;
+    stmt << " ORDER BY file_id";
+
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+        uint64_t file_id;
+        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
+        {
+            i[0].to(file_id);
+            results.push_back(file_id);
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        std::wstring wTableName;
+        Poco::UnicodeConverter::toUTF16(tableName, wTableName);
+        errorMsg << L"TskImgDBPostgreSQL::getFileIdsWorker - Error getting file ids from " << wTableName << " : "
+            << e.what();
+        LOGERROR(errorMsg.str());
+    }
+
+    return results;
+}
+
+// Set file hash for hashType for a_file_id
+// Return 1 on failure, 0 on success.
+int TskImgDBPostgreSQL::setHash(const uint64_t a_file_id, const TskImgDB::HASH_TYPE hashType, const std::string& hash) const
+{
+    if (!initialized())
+        return 1;
+
+    string hashTypeStr;
+    switch (hashType) {
+    case TskImgDB::MD5:
+        hashTypeStr = "md5";
+        break;
+    case TskImgDB::SHA1:
+        hashTypeStr = "sha1";
+        break;
+    case TskImgDB::SHA2_256:
+        hashTypeStr = "sha2_256";
+        break;
+    case TskImgDB::SHA2_512:
+        hashTypeStr = "sha2_512";
+        break;
+    default:
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::setHash - Unsupported hashType : " << hashType;
+        LOGERROR(errorMsg.str());
+        return 1;
+    }
+
+    stringstream stmt;
+    bool found = false;
+    std::string md5, sha1, sha2_256, sha2_512;
+    int known = IMGDB_FILES_UNKNOWN;
+    std::stringstream stream;
+
+    stmt << "SELECT md5, sha1, sha2_256, sha2_512, known from file_hashes WHERE file_id = " << a_file_id;
+    try 
+    {
+        pqxx::read_transaction W(*m_dbConnection);
+        result R = W.exec(stmt);
+        if (R.size() == 1) {
+            R[0][0].to(md5);
+            R[0][1].to(sha1);
+            R[0][2].to(sha2_256);
+            R[0][3].to(sha2_512);
+            R[0][4].to(known);
+            found = true;
+        }
+    }
+    catch (const exception&)
+    {
+        ; // ok to fail if file_id don't exist
+    }
+
+    if (found) {
+        // delete existing record
+        stmt.str("");
+        stmt << "DELETE FROM file_hashes WHERE file_id=" << a_file_id;
+        try
+        {
+            pqxx::work W(*m_dbConnection);
+            pqxx::result R = W.exec(stmt);
+            W.commit();
+        }
+        catch (const exception &e)
+        {
+            std::wstringstream errorMsg;
+            errorMsg << L"TskImgDBPostgreSQL::setHash - DELETE " << hashType << L" failed: " << e.what();
+            LOGERROR(errorMsg.str());
+            return 1;
+        }
+
+    }
+    // insert new record
+    stmt.str("");
+    stmt << "INSERT INTO file_hashes (file_id, md5, sha1, sha2_256, sha2_512, known) VALUES (" << a_file_id;
+    switch (hashType) {
+    case TskImgDB::MD5:
+        stmt << ", '" << hash << "'";
+        stmt << ", '" << sha1 << "'";
+        stmt << ", '" << sha2_256 << "'";
+        stmt << ", '" << sha2_512 << "'";
+        stream << known;
+        stmt << ", " << stream.str();
+        break;
+    case TskImgDB::SHA1:
+        stmt << ", '" << md5 << "'";
+        stmt << ", '" << hash << "'";
+        stmt << ", '" << sha2_256 << "'";
+        stmt << ", '" << sha2_512 << "'";
+        stream << known;
+        stmt << ", " << stream.str();
+        break;
+    case TskImgDB::SHA2_256:
+        stmt << ", '" << md5 << "'";
+        stmt << ", '" << sha1 << "'";
+        stmt << ", '" << hash << "'";
+        stmt << ", '" << sha2_512 << "'";
+        stream << known;
+        stmt << ", " << stream.str();
+        break;
+    case TskImgDB::SHA2_512:
+        stmt << ", '" << md5 << "'";
+        stmt << ", '" << sha1 << "'";
+        stmt << ", '" << sha2_256 << "'";
+        stmt << ", '" << hash << "'";
+        stream << known;
+        stmt << ", " << stream.str();
+        break;
+    }
+    stmt << ")";
+
+    try
+    {
+        work W(*m_dbConnection);
+        result R = W.exec(stmt);
+        W.commit();
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskDBPostgreSQL::setHash - INSERT failed: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+        return 1;
+    }
+    return 0;
+}
+
+std::string TskImgDBPostgreSQL::getCfileName(uint64_t a_file_id) const
+{
+    std::string cfileName;
+
+    if (!initialized())
+        return cfileName;
+
+    stringstream stmt;
+
+    stmt << "select 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || f.file_id"
+        " from files f, carved_files c, carved_sectors cs where f.file_id = c.file_id and c.file_id = cs.file_id and cs.seq = 0"
+        " and f.file_id = " << a_file_id;
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
+        {
+            cfileName = (char *)i[0].c_str();
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getCfileName - Error getting CFileName for file id " << a_file_id << " : "
+            << e.what();
+        LOGERROR(errorMsg.str());
+    }
+
+    stmt.str("");
+    stmt << "select f.name "
+        " from files f, carved_files c, carved_sectors cs where f.file_id = c.file_id and c.file_id = cs.file_id and cs.seq = 0"
+        " and f.file_id = " << a_file_id;
+    std::string name;
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
+        {
+            name = (char *)i[0].c_str();
+            int pos = name.rfind('.');
+            if (pos != string::npos)
+                cfileName += name.substr(pos);
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getCfileName - Error getting CFileName for file id " << a_file_id << " : "
+            << e.what();
+        LOGERROR(errorMsg.str());
+    }
+
+    return cfileName;
+}
+
+/**
+ * Return the ImageInfo
+ * @param type Image Type (output)
+ * @param sectorSize Image sector size (output)
+ * @returns 0 on success or -1 on error.
+ */
+int TskImgDBPostgreSQL::getImageInfo(int & type, int & sectorSize) const
+{
+    int result = -1;
+
+    if (!initialized())
+        return result;
+
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec("SELECT type, ssize from image_info");
+
+        if (R.size() == 1)
+        {
+            R[0][0].to(type);
+            R[0][1].to(sectorSize);
+            result = 0;
+        }
+        else
+        {
+            std::wstringstream errorMsg;
+            errorMsg << L"TskImgDBPostgreSQL::getImageInfo - Unexpected number of rows returned."
+                << R.size();
+            LOGERROR(errorMsg.str());
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getImageInfo - Error getting image_info: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+    }
+    return result;
+}
+
+/**
+ * Return a list of TskVolumeInfoRecord
+ * @param volumeInfoList A list of TskVolumeInfoRecord (output)
+ * @returns 0 on success or -1 on error.
+ */
+int TskImgDBPostgreSQL::getVolumeInfo(std::list<TskVolumeInfoRecord> & volumeInfoList) const
+{
+    int rc = -1;
+
+    if (!initialized())
+        return rc;
+
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec("SELECT vol_id, sect_start, sect_len, description, flags FROM vol_info");
+
+        for (result::size_type rownum=0; rownum < R.size(); ++rownum) {
+            const result::tuple row = R[rownum];
+            TskVolumeInfoRecord vol_info;
+            vol_info.vol_id = row[0].as<int>();
+            vol_info.sect_start = row[1].as<uint64_t>();
+            vol_info.sect_len = row[2].as<uint64_t>();
+            vol_info.description.assign(row[3].as<const char *>());
+            vol_info.flags = (TSK_VS_PART_FLAG_ENUM)row[4].as<int>();
+            volumeInfoList.push_back(vol_info);
+        }
+        rc = 0;
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getVolumeInfo - Error getting vol_info: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+    }
+    return rc;
+}
+
+/**
+ * Return a list of TskFsInfoRecord
+ * @param fsInfoList A list of TskFsInfoRecord (output)
+ * @returns 0 on success or -1 on error.
+ */
+int TskImgDBPostgreSQL::getFsInfo(std::list<TskFsInfoRecord> & fsInfoList) const
+{
+    int rc = -1;
+
+    if (!initialized())
+        return rc;
+
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec("SELECT fs_id, img_byte_offset, vol_id, fs_type, block_size, block_count, root_inum, first_inum, last_inum FROM fs_info");
+
+        for (result::size_type rownum=0; rownum < R.size(); ++rownum) {
+            const result::tuple row = R[rownum];
+            TskFsInfoRecord fs_info;
+            fs_info.fs_id = row[0].as<int>();
+            fs_info.img_byte_offset = row[1].as<uint64_t>();
+            fs_info.vol_id = row[2].as<int>();
+            fs_info.fs_type = (TSK_FS_TYPE_ENUM)row[3].as<int>();
+            fs_info.block_size = row[4].as<int>();
+            fs_info.block_count = row[5].as<uint64_t>();
+            fs_info.root_inum = row[6].as<uint64_t>();
+            fs_info.first_inum = row[7].as<uint64_t>();
+            fs_info.last_inum =  row[8].as<uint64_t>();
+            fsInfoList.push_back(fs_info);
+        }
+        rc = 0;
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getFsInfo - Error getting fs_info: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+    }
+    return rc;
+}
+
+typedef std::map<std::string, int> FileTypeMap_t;
+
+static std::string getFileType(const char *name)
+{
+    std::string filename = name;
+    int pos = filename.rfind('.');
+    if (pos != std::string::npos) {
+        std::string suffix = filename.substr(pos);
+        std::string result;
+        for (size_t i=0; i < suffix.size(); i++) {
+            result += (char)tolower(suffix[i]);
+        }
+        return result;
+    }
+    else
+        return std::string("");
+}
+
+/**
+ * Return a list of TskFileTypeRecord for all files.
+ * @param fileTypeInfoList A list of TskFileTypeRecord (output)
+ * @returns 0 on success or -1 on error.
+ */
+int TskImgDBPostgreSQL::getFileInfoSummary(std::list<TskFileTypeRecord> &fileTypeInfoList) const
+{
+    std::stringstream stmt;
+    stmt << "SELECT name FROM files WHERE dir_type = " << TSK_FS_NAME_TYPE_REG;
+
+    return getFileTypeRecords(stmt.str(), fileTypeInfoList);
+}
+
+/**
+ * Return a list of TskFileTypeRecord for fileType
+ * @param fileType FILE_TYPE to report
+ * @param fileTypeInfoList A list of TskFileTypeRecord (output)
+ * @returns 0 on success or -1 on error.
+ */
+int TskImgDBPostgreSQL::getFileInfoSummary(FILE_TYPES fileType, std::list<TskFileTypeRecord> & fileTypeInfoList) const
+{
+    std::stringstream stmt;
+    stmt << "SELECT name FROM files WHERE type_id = " << fileType << " AND dir_type = " << TSK_FS_NAME_TYPE_REG;
+
+    return getFileTypeRecords(stmt.str(), fileTypeInfoList);
+}
+
+/**
+ * Return a list of TskFileTypeRecords matching the given SQL statement.
+ * @param stmt The SQL statement used to match file records.
+ * @param fileTypeInfoList A list of TskFileTypeRecord (output)
+ * @returns 0 on success of -1 on error.
+ */
+int TskImgDBPostgreSQL::getFileTypeRecords(std::string& stmt, std::list<TskFileTypeRecord>& fileTypeInfoList) const
+{
+    int rc = -1;
+
+    if (!initialized())
+        return rc;
+
+    std::list<TskFileTypeRecord> list;
+
+    try {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt.c_str());
+        FileTypeMap_t fileTypeMap;
+
+        for (result::size_type rownum=0; rownum < R.size(); ++rownum) {
+            const result::tuple row = R[rownum];
+            const char* name = row[0].as<const char *>();
+            std::string type = getFileType(name);
+            FileTypeMap_t::iterator iter = fileTypeMap.find(type);
+            if (iter != fileTypeMap.end()) {
+                // increment file counter
+                int count = iter->second;
+                fileTypeMap[type] = ++count;
+            } else {
+                // add a new file type
+                fileTypeMap.insert(pair<std::string, int>(type, 1));
+            }
+        }
+        for (FileTypeMap_t::const_iterator iter=fileTypeMap.begin(); iter != fileTypeMap.end(); iter++) {
+            TskFileTypeRecord info;
+            info.suffix.assign((*iter).first.c_str());
+            info.count = (*iter).second;
+            info.description.assign("File Type Description");
+            fileTypeInfoList.push_back(info);
+        }
+        rc = 0;
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getFileTypeRecords - Error retrieving file type records: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+    }
+    return rc;
+}
+
+/**
+ * Insert the Module record, if module name does not already exist in modules table.
+ * Returns Module Id associated with the Module record.
+ * @param name Module name
+ * @param description Module description
+ * @param moduleId Module Id (output)
+ * @returns 0 on success, -1 on error.
+ */
+int TskImgDBPostgreSQL::addModule(const std::string& name, const std::string& description, int & moduleId)
+{
+    if (!initialized())
+        return 0;
+
+    stringstream stmt;
+
+    stmt << "SELECT module_id FROM modules WHERE name = " << m_dbConnection->quote(name);
+
+    try 
+    {
+        work W(*m_dbConnection);
+        result R = W.exec(stmt);
+
+        if (R.size() == 1)
+        {
+            // Already exists, return module_id
+            R[0][0].to(moduleId);
+            return 0;
+        }
+
+        // Insert a new one
+        stmt.str("");
+        stmt << "INSERT INTO modules (module_id, name, description) VALUES (DEFAULT, " << m_dbConnection->quote(name) << ", " << m_dbConnection->quote(description) << ")"
+             << " RETURNING module_id";
+
+        R = W.exec(stmt);
+
+        // Get the newly assigned module id
+        R[0][0].to(moduleId);
+        W.commit();
+    } 
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskDBPostgreSQL::addModule - Error inserting into modules table: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+        return -1;
+    }
+
+    return 0;
+}
+
+/**
+ * Insert the module status record.
+ * @param file_id file_id
+ * @param module_id module_id
+ * @param status Status of module
+ * @returns 0 on success, -1 on error.
+ */
+int TskImgDBPostgreSQL::setModuleStatus(uint64_t file_id, int module_id, int status)
+{
+    int rc = -1;
+
+    if (!initialized())
+        return rc;
+
+    stringstream stmt;
+    stmt << "INSERT INTO module_status (file_id, module_id, status) VALUES (" << 
+        file_id << ", " <<
+        module_id << ", " <<
+        status << ")";
+    try
+    {
+        work W(*m_dbConnection);
+        result R = W.exec(stmt);
+        W.commit();
+        rc = 0;
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskDBPostgreSQL::setModuleStatus - Error adding data to module_status table: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+    }
+    return rc;
+}
+
+/**
+ * Get a list of TskModuleStatus.
+ * @param moduleStatusList A list of TskModuleStatus (output)
+ * @returns 0 on success, -1 on error.
+ */
+int TskImgDBPostgreSQL::getModuleInfo(std::vector<TskModuleInfo> & moduleInfoList) const
+{
+    int rc = -1;
+
+    if (!initialized())
+        return rc;
+
+    stringstream stmt;
+    stmt << "SELECT module_id, name, description FROM modules"
+         << " ORDER BY module_id";
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+        TskModuleInfo moduleInfo;
+        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
+        {
+            i[0].to(moduleInfo.module_id);
+            moduleInfo.module_name.assign(i[1].c_str());
+            moduleInfo.module_description.assign(i[2].c_str());
+            moduleInfoList.push_back(moduleInfo);
+        }
+        rc = 0;
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getModuleErrors - Error getting module_status: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+    }
+    return rc;
+}
+
+/**
+ * Get a list of TskModuleStatus.
+ * @param moduleStatusList A list of TskModuleStatus (output)
+ * @returns 0 on success, -1 on error.
+ */
+int TskImgDBPostgreSQL::getModuleErrors(std::vector<TskModuleStatus> & moduleStatusList) const
+{
+    int rc = -1;
+
+    if (!initialized())
+        return rc;
+
+    stringstream stmt;
+    stmt << "SELECT f.file_id, m.name, ms.status FROM module_status ms, files f, modules m"
+         << " WHERE ms.status != 0 AND ms.file_id = f.file_id AND m.module_id = ms.module_id"
+         << " ORDER BY f.file_id";
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+        TskModuleStatus moduleStatus;
+        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
+        {
+            i[0].to(moduleStatus.file_id);
+            moduleStatus.module_name.assign(i[1].c_str());
+            i[2].to(moduleStatus.status);
+            moduleStatusList.push_back(moduleStatus);
+        }
+        rc = 0;
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getModuleErrors - Error getting module_status: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+    }
+    // Find report module errors. These have file_id = 0.
+    stmt.str("");
+    stmt << "SELECT 0, m.name, ms.status FROM module_status ms, modules m"
+         << " WHERE ms.status != 0 AND ms.file_id = 0 AND m.module_id = ms.module_id";
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+        TskModuleStatus moduleStatus;
+        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
+        {
+            i[0].to(moduleStatus.file_id);
+            moduleStatus.module_name.assign(i[1].c_str());
+            i[2].to(moduleStatus.status);
+            moduleStatusList.push_back(moduleStatus);
+        }
+        rc = 0;
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getModuleErrors - Error getting module_status: "
+            << e.what();
+        LOGERROR(errorMsg.str());
+    }
+    return rc;
+}
+
+/*
+ * Return a file name associated with a file_id, prefer Cfilename, otherwise name in the files table.
+ * @param file_id file id
+ * @returns file name as std::string
+ */
+std::string TskImgDBPostgreSQL::getFileName(uint64_t file_id) const
+{
+    std::string name;
+
+    if (!initialized())
+        return name;
+
+    name = getCfileName(file_id);
+    if (name == "") {
+        TskFileRecord fileRecord;
+        if (getFileRecord(file_id, fileRecord) == 0)
+            name = fileRecord.name;
+    }
+    return name;
+}
+
+/**
+ * Return the known status of the file with the given id
+ * @param fileId id of the file to get the status of
+ * @returns KNOWN_STATUS
+ */
+TskImgDB::KNOWN_STATUS TskImgDBPostgreSQL::getKnownStatus(const uint64_t fileId) const
+{
+     int retval = -1;
+
+    if (!initialized())
+        return (TskImgDB::KNOWN_STATUS)retval;
+
+    stringstream stmt;
+    stmt << "SELECT known FROM file_hashes WHERE file_id = " << fileId;
+
+    try
+    {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt);
+        pqxx::result::const_iterator i = R.begin(); 
+        if(i != R.end()){
+            i[0].to(retval);
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        std::wstring wTableName;
+        errorMsg << L"TskImgDBPostgreSQL::getFileIdsWorker - Error getting known status : "
+            << e.what() << std::endl;
+        LOGERROR(errorMsg.str());
+    }
+
+    return (TskImgDB::KNOWN_STATUS)retval;
+}
+
+/**
+ * Add a new row to the unalloc_img_status table, returning the unalloc_img_id.
+ * @param unallocImgId unalloc_img_id (output)
+ * @returns -1 on error, 0 on success.
+ */
+int TskImgDBPostgreSQL::addUnallocImg(int & unallocImgId)
+{
+    int rc = -1;
+
+    if (!initialized())
+        return rc;
+
+    std::stringstream stmt;
+    stmt << "INSERT INTO unalloc_img_status (unalloc_img_id, status) VALUES (DEFAULT, " << TskImgDB::IMGDB_UNALLOC_IMG_STATUS_CREATED << ")"
+         << " RETURNING unalloc_img_id";
+         
+    try
+    {
+        pqxx::work W(*m_dbConnection);
+        pqxx::result R = W.exec(stmt);
+
+        // get the unalloc_img_id from the last insert
+        unallocImgId = R[0][0].as<int>();
+        W.commit();
+        rc = 0;
+    }
+    catch (const exception& ex)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::addUnallocImg - Error adding unalloc_img_status table: "
+            << ex.what();
+        LOGERROR(errorMsg.str());
+    }
+
+    return rc;
+}
+
+/**
+ * Set the status in the unalloc_img_status table given the unalloc_img_id.
+ * @param unallocImgId unalloc_img_id
+ * @param status status of unalloc_img_id
+ * @returns -1 on error, 0 on success.
+ */
+int TskImgDBPostgreSQL::setUnallocImgStatus(int unallocImgId, TskImgDB::UNALLOC_IMG_STATUS status)
+{
+    int rc = -1;
+
+    if (!initialized())
+        return rc;
+
+    std::stringstream stmt;
+    stmt << "UPDATE unalloc_img_status SET status = " << status << " WHERE unalloc_img_id = " << unallocImgId;
+    try
+    {
+        pqxx::work W(*m_dbConnection);
+        pqxx::result R = W.exec(stmt);
+        W.commit();
+        rc = 0;
+    }
+    catch (const exception& ex)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::setUnallocImgStatus - Error updating unalloc_img_status table: "
+            << ex.what() << std::endl;
+        LOGERROR(errorMsg.str());
+    }
+
+    return rc;
+}
+
+/**
+ * Get the status of the unalloc_img_status table given the unalloc_img_id.
+ * Can throws TskException.
+ * @param unallocImgId unalloc_img_id
+ * @returns TskImgDB::UNALLOC_IMG_STATUS
+ */
+TskImgDB::UNALLOC_IMG_STATUS TskImgDBPostgreSQL::getUnallocImgStatus(int unallocImgId) const
+{
+    if (!initialized())
+        throw TskException("Database not initialized.");
+
+    int status;
+
+    stringstream stmt;
+    stmt << "SELECT status FROM unalloc_img_status WHERE unalloc_img_id = " << unallocImgId;
+    try {
+        pqxx::read_transaction trans(*m_dbConnection);
+        pqxx::result R = trans.exec(stmt.str().c_str());
+        if (R.size() == 1) {
+            R[0][0].to(status);
+        } else {
+            throw TskException("No unalloc_img_status.");
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBPostgreSQL::getUnallocImgStatus - Error getting unalloc_img_status: "
+            << e.what() << std::endl;
+        LOGERROR(errorMsg.str());
+    }
+    return (TskImgDB::UNALLOC_IMG_STATUS)status;
+}
+
+/**
+ * Get all the unalloc_img_status table.
+ * @param unallocImgStatusList A vector of TskUnallocImgStatusRecord (output)
+ * @returns -1 on error, 0 on success.
+ */
+int TskImgDBPostgreSQL::getAllUnallocImgStatus(std::vector<TskUnallocImgStatusRecord> & unallocImgStatusList) const
+{
+    int rc = -1;
+    unallocImgStatusList.clear();
+
+    if (!initialized())
+        return rc;
+
+    stringstream stmt;
+    stmt << "SELECT unalloc_img_id, status FROM unalloc_img_status";
+
+    try
+    {
+        pqxx::read_transaction W(*m_dbConnection);
+        pqxx::result R = W.exec(stmt.str().c_str());
+
+        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
+        {
+            TskUnallocImgStatusRecord record;
+
+            i[0].to(record.unallocImgId);
+            i[1].to((int &)record.status);
+            unallocImgStatusList.push_back(record);
+        }
+        rc = 0;
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream msg;
+        msg << L"TskDBPostgreSQL::getAllBlackboardRows - Error querying blackboard table: "
+            << e.what() << std::endl;
+        LOGERROR(msg.str());
+    }
+    return rc;
+}
+
+/**
+ * Find and add all the unused sectors (unallocated and uncarved bytes) in the given unallocImgId
+ * @param unallocImgId The unalloc image id.
+ * @param unusedSectorsList A vector of TskUnusedSectorsRecord
+ * @returns -1 on error, 0 on success.
+ */
+int TskImgDBPostgreSQL::addUnusedSectors(int unallocImgId, std::vector<TskUnusedSectorsRecord> & unusedSectorsList)
+{
+    assert(unallocImgId > 0);
+
+    if (!initialized())
+        return -1;
+
+    std::stringstream stmt;
+    stmt << "SELECT vol_id, unalloc_img_sect_start, sect_len, orig_img_sect_start FROM alloc_unalloc_map "
+        "WHERE unalloc_img_id = " << unallocImgId << " ORDER BY orig_img_sect_start ASC";
+
+    try {
+        pqxx::read_transaction W(*m_dbConnection);
+        pqxx::result R = W.exec(stmt.str());
+
+        vector<TskAllocUnallocMapRecord> allocUnallocMapList;
+
+        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i)
+        {
+            TskAllocUnallocMapRecord record;
+            i[0].to(record.vol_id);
+            record.unalloc_img_id = unallocImgId;
+            i[1].to(record.unalloc_img_sect_start);
+            i[2].to(record.sect_len);
+            i[3].to(record.orig_img_sect_start);
+            allocUnallocMapList.push_back(record);
+        }
+
+        W.commit();
+
+        for (std::vector<TskAllocUnallocMapRecord>::const_iterator it = allocUnallocMapList.begin();
+             it != allocUnallocMapList.end(); it++)
+        {
+            // Sector position tracks our position through the unallocated map record.
+            uint64_t sectPos = it->orig_img_sect_start;
+
+            uint64_t endSect = it->orig_img_sect_start + it->sect_len;
+
+            // Retrieve all carved_sector records in range for this section of unallocated space.
+            stmt.str("");
+            stmt << "SELECT cs.sect_start, cs.sect_len FROM carved_files cf, carved_sectors cs"
+                << " WHERE cf.file_id = cs.file_id AND cs.sect_start >= " << it->orig_img_sect_start
+                << " AND cs.sect_start < " << endSect << " ORDER BY cs.sect_start ASC";
+
+            pqxx::read_transaction trans(*m_dbConnection);
+
+            R = trans.exec(stmt.str());
+            trans.commit();
+
+            for (pqxx::result::const_iterator i = R.begin(); i != R.end(); i++)
+            {
+                uint64_t cfileSectStart;
+                uint64_t cfileSectLen;
+
+                i[0].to(cfileSectStart);
+                i[1].to(cfileSectLen);
+
+                if (cfileSectStart > sectPos)
+                {
+                    // We have a block of unused sectors between this position in the unallocated map
+                    // and the start of the carved file.
+                    addUnusedSector(sectPos, cfileSectStart, it->vol_id, unusedSectorsList);
+                }
+
+                sectPos = cfileSectStart + cfileSectLen;
+            }
+
+            // Handle case where there is slack at the end of the unalloc range
+            if (sectPos < endSect)
+                addUnusedSector(sectPos, endSect, it->vol_id, unusedSectorsList);
+        }
+    }
+    catch (const exception &e)
+    {
+        std::wstringstream msg;
+        msg << L"TskDBPostgreSQL::addUnusedSectors - Error adding unused sectors : "
+            << e.what() << std::endl;
+        LOGERROR(msg.str());
+    }
+
+    return 0;
+}
+
+/**
+ * Add one unused sector to the database, add it to the files and unused_sectors tables.
+ * @param sectStart Unused sector start.
+ * @param sectEnd Unused sector end.
+ * @param volId Volume Id of the unused sector.
+ * @param unusedSectorsList A vector of TskUnusedSectorsRecord (output)
+ * @returns -1 on error, 0 on success.
+ */
+int TskImgDBPostgreSQL::addUnusedSector(uint64_t sectStart, uint64_t sectEnd, int volId, std::vector<TskUnusedSectorsRecord> & unusedSectorsList)
+{
+    assert(sectEnd > sectStart);
+    int rc = -1;
+    if (!initialized())
+        return rc;
+
+    char *ufilename = "ufile";
+    std::stringstream stmt;
+
+    std::string maxUnused = GetSystemProperty("MAX_UNUSED_FILE_SIZE_BYTES");
+    const uint64_t maxUnusedFileSizeBytes = maxUnused.empty() ? (50 * 1024 * 1024) : Poco::NumberParser::parse64(maxUnused);
+
+    uint64_t maxUnusedSectorSize = maxUnusedFileSizeBytes / 512;
+    uint64_t sectorIndex = 0;
+    uint64_t sectorCount = (sectEnd - sectStart) / maxUnusedSectorSize;
+
+    while (sectorIndex <= sectorCount) {
+        uint64_t thisSectStart = sectStart + (sectorIndex * maxUnusedSectorSize);
+        uint64_t thisSectEnd = thisSectStart + std::min(maxUnusedSectorSize, sectEnd - thisSectStart);
+
+        stmt.str("");
+        stmt << "INSERT INTO files (file_id, type_id, name, par_file_id, dir_type, meta_type,"
+            "dir_flags, meta_flags, size, ctime, crtime, atime, mtime, mode, uid, gid, status, full_path) "
+            "VALUES (DEFAULT, " << IMGDB_FILES_TYPE_UNUSED << ", " << m_dbConnection->quote(ufilename)
+            << ", NULL, " <<  TSK_FS_NAME_TYPE_REG << ", " <<  TSK_FS_META_TYPE_REG << ", "
+            << TSK_FS_NAME_FLAG_UNALLOC << ", " << TSK_FS_META_FLAG_UNALLOC << ", "
+            << (thisSectEnd - thisSectStart) * 512 << ", NULL, NULL, NULL, NULL, NULL, NULL, NULL, " << IMGDB_FILES_STATUS_READY_FOR_ANALYSIS << "," << m_dbConnection->quote(ufilename) << ")"
+            << " RETURNING file_id";
+
+        try
+        {
+            pqxx::work W(*m_dbConnection);
+            pqxx::result R = W.exec(stmt.str().c_str());
+
+            TskUnusedSectorsRecord record;
+
+            // get the file_id from the last insert
+            record.fileId = R[0][0].as<uint64_t>();
+            record.sectStart = thisSectStart;
+            record.sectLen = thisSectEnd - thisSectStart;
+
+            std::stringstream name;
+            name << "ufile_" << thisSectStart << "_" << thisSectEnd << "_" << record.fileId;
+            stmt.str("");
+            stmt << "UPDATE files SET name = " << m_dbConnection->quote(name.str().c_str()) << ", full_path = " 
+                << m_dbConnection->quote(name.str().c_str()) << " WHERE file_id = " << record.fileId;
+            R = W.exec(stmt.str().c_str());
+
+            stmt.str("");
+            stmt << "INSERT INTO unused_sectors (file_id, sect_start, sect_len, vol_id) VALUES (" 
+                 << record.fileId << ", " << record.sectStart << ", " << record.sectLen << ", " << volId << ")";
+            R = W.exec(stmt.str().c_str());
+
+            W.commit();
+            unusedSectorsList.push_back(record);
+            rc = 0;
+        } 
+        catch (const exception& ex)
+        {
+            std::wstringstream errorMsg;
+            errorMsg << L"TskImgDBPostgreSQL::addUnusedSector - Error insert into files table: "
+                << ex.what() << std::endl;
+            LOGERROR(errorMsg.str());
+            rc = -1;
+            break;
+        }
+        sectorIndex++;
+    } // while
+    return rc;
+}
+
+/**
+ * Get unused sector record given a file id.
+ * @param fileId File id of the unused sector.
+ * @param unusedSectorsRecord TskUnusedSectorsRecord (output)
+ * @returns -1 on error, 0 on success.
+ */
+int TskImgDBPostgreSQL::getUnusedSector(uint64_t fileId, TskUnusedSectorsRecord & unusedSectorsRecord) const
+{
+    int rc = -1;
+    if (!initialized())
+        return rc;
+
+    std::stringstream stmt;
+    stmt << "SELECT sect_start, sect_len FROM unused_sectors WHERE file_id = " << fileId;
+
+    try {
+        pqxx::read_transaction W(*m_dbConnection);
+        pqxx::result R = W.exec(stmt.str().c_str());
+        if (R.size() == 1) {
+            unusedSectorsRecord.fileId = fileId;
+            unusedSectorsRecord.sectStart = R[0][0].as<uint64_t>();
+            unusedSectorsRecord.sectLen = R[0][1].as<uint64_t>();
+            rc = 0;
+        } else {
+            std::wstringstream msg;
+            msg << L"TskDBPostgreSQL::getUnusedSector - Error querying unused_sectors table for file_id "
+                << fileId << ", result size = " << R.size() << std::endl;
+            LOGERROR(msg.str());
+        }
+    } 
+    catch (const exception &e)
+    {
+        std::wstringstream msg;
+        msg << L"TskDBPostgreSQL::getUnusedSector - Error querying unused_sectors table: "
+            << e.what() << std::endl;
+        LOGERROR(msg.str());
+    }
+    return rc;
+}
+
+///BLACKBOARD FUNCTIONS
+/**
+ * Add the given blackboard attribute to the database
+ * @param attr input attribute. should be fully populated
+ */
+void TskImgDBPostgreSQL::addBlackboardAttribute(TskBlackboardAttribute attr){
+    if (!m_dbConnection)
+        throw TskException("No database.");
+
+    artifact_t artifactId = 0;
+    std::stringstream str;
+
+    str << "INSERT INTO blackboard_attributes (artifact_id, source, context, attribute_type_id, value_type, "
+        "value_byte, value_text, value_int32, value_int64, value_double, obj_id) VALUES (";
+        str << attr.getArtifactID() << ", ";
+    str << m_dbConnection->quote(attr.getModuleName()) << ", ";
+    str << m_dbConnection->quote(attr.getContext()) << ", ";
+    str << attr.getAttributeTypeID() << ", ";
+    str << attr.getValueType() << ", ";
+    std::string escStr;
+    int a_size;
+    unsigned char *pBuf;
+    switch (attr.getValueType()) {
+        case TSK_BYTE:
+            a_size = attr.getValueBytes().size();
+            pBuf = new unsigned char[a_size];
+            
+            for (int i = 0; i < a_size; i++) {
+                pBuf[i] = attr.getValueBytes()[i];
+            }
+
+            escStr = m_dbConnection->esc_raw(pBuf, a_size);
+            delete pBuf;
+            str << " '" << escStr.c_str() << "', '', 0, 0, 0.0";
+            break;
+        case TSK_STRING:
+            a_size = attr.getValueString().size();
+            pBuf = new unsigned char[a_size];
+            
+            for (int i = 0; i < a_size; i++) {
+                pBuf[i] = attr.getValueString()[i];
+            }
+            str << " '', E" << m_dbConnection->quote(attr.getValueString()) << ", 0, 0, 0.0";
+            break;
+        case TSK_INTEGER:
+            str << " '', '', " << attr.getValueInt() << ",     0, 0.0";
+            break;
+        case TSK_LONG:
+            str << " '', '', 0, " << attr.getValueLong() << ",     0.0";
+            break;
+        case TSK_DOUBLE:
+            str << " '', '', 0, 0, " << setprecision(20) << attr.getValueDouble();
+            break;
+    };
+    str << ", " << attr.getObjectID() << ")";
+
+    try
+    {
+        pqxx::work W(*m_dbConnection);
+        pqxx::result R = W.exec(str);
+  
+        W.commit();
+
+    } catch (const exception &e) {
+        std::wstringstream msg;
+        msg << L"TskDBPostgreSQL::addBlackboardAttribute - Error adding data to blackboard table: "
+            << e.what() << std::endl;
+        LOGERROR(msg.str());
+        throw TskException("TskDBPostgreSQL::addBlackboardInfo - Insert failed");
+    }
+}
+
+/**
+ * Get the display name for the given artifact type id
+ * @param artifactTypeID artifact type id
+ * @returns display name
+ */
+string TskImgDBPostgreSQL::getArtifactTypeDisplayName(int artifactTypeID){
+    if (!m_dbConnection)
+        throw TskException("No database.");
+
+    std::stringstream str;
+    std::string displayName = "";
+
+    str << "SELECT display_name FROM blackboard_artifact_types WHERE artifact_type_id = " << artifactTypeID;
+
+    try{
+        pqxx::work W(*m_dbConnection);
+        pqxx::result R = W.exec(str);
+        
+        if(R.size() > 0)
+            displayName = R[0][0].as<string>();
+        
+        W.commit();
+        return displayName;
+
+    }catch(const exception &e) {
+        std::wstringstream msg;
+        msg << L"TskDBPostgreSQL::getArtifactTypeDisplayName:"
+            << e.what() << std::endl;
+        LOGERROR(msg.str());
+        throw TskException("TskDBPostgreSQL::getArtifactTypeDisplayName - No artifact type with that ID");
+    }
+}
+
+/**
+ * Get the artifact type id for the given artifact type string
+ * @param artifactTypeString display name
+ * @returns artifact type id
+ */
+int TskImgDBPostgreSQL::getArtifactTypeID(string artifactTypeString){
+    if (!m_dbConnection)
+        throw TskException("No database.");
+
+    std::stringstream str;
+    int typeID;
+
+    str << "SELECT artifact_type_id FROM blackboard_artifact_types WHERE type_name = " << artifactTypeString;
+
+    try{
+        pqxx::work W(*m_dbConnection);
+        pqxx::result R = W.exec(str);
+        
+        if(R.size() > 0)
+            typeID = R[0][0].as<int>();
+        
+        W.commit();
+        return typeID;
+    }catch(const exception &e) {
+        std::wstringstream msg;
+        msg << L"TskDBPostgreSQL::getArtifactTypeID:"
+            << e.what() << std::endl;
+        LOGERROR(msg.str());
+        throw TskException("TskDBPostgreSQL::getArtifactTypeID - No artifact type with that name");
+    }
+}
+
+/**
+ * Get the artifact type name for the given artifact type id
+ * @param artifactTypeID id
+ * @returns artifact type name
+ */
+string TskImgDBPostgreSQL::getArtifactTypeName(int artifactTypeID){
+    if (!m_dbConnection)
+        throw TskException("No database.");
+
+    std::stringstream str;
+    std::string typeName = "";
+
+    str << "SELECT type_name FROM blackboard_artifact_types WHERE artifact_type_id = " << artifactTypeID;
+
+    try{
+        pqxx::work W(*m_dbConnection);
+        pqxx::result R = W.exec(str);
+        
+        if(R.size() > 0)
+            typeName = R[0][0].as<string>();
+        W.commit();
+        return typeName;
+    }
+    catch(const exception &e) {
+        std::wstringstream msg;
+        msg << L"TskDBPostgreSQL::getArtifactTypeName:"
+            << e.what() << std::endl;
+        LOGERROR(msg.str());
+        throw TskException("TskDBPostgreSQL::getArtifactTypeName - No artifact type with that id");
+    }
+}
+
+/**
+ * Get the display name for the given attribute type id
+ * @param attributeTypeID attribute type id
+ * @returns display name
+ */
+string TskImgDBPostgreSQL::getAttributeTypeDisplayName(int attributeTypeID){
+    if (!m_dbConnection)
+        throw TskException("No database.");
+
+    std::stringstream str;
+    std::string displayName = "";
+
+    str << "SELECT display_name FROM blackboard_attribute_types WHERE attribute_type_id = " << attributeTypeID;
+
+    try{
+        pqxx::work W(*m_dbConnection);
+        pqxx::result R = W.exec(str);
+        
+        if(R.size() > 0)
+            displayName = R[0][0].as<string>();
+        W.commit();
+        return displayName;
+    }
+    catch(const exception &e) {
+        std::wstringstream msg;
+        msg << L"TskDBPostgreSQL::getAttributeTypeDisplayName:"
+            << e.what() << std::endl;
+        LOGERROR(msg.str());
+        throw TskException("TskDBPostgreSQL::getAttributeTypeDisplayName - No attribute type with that id");
+    }
+}
+
+/**
+ * Get the attribute type id for the given artifact type string
+ * @param attributeTypeString display name
+ * @returns attribute type id
+ */
+int TskImgDBPostgreSQL::getAttributeTypeID(string attributeTypeString){
+    if (!m_dbConnection)
+        throw TskException("No database.");
+
+    std::stringstream str;
+    int typeID;
+
+    str << "SELECT attribute_type_id FROM blackboard_attribute_types WHERE type_name = " << attributeTypeString;
+
+    try{
+        pqxx::work W(*m_dbConnection);
+        pqxx::result R = W.exec(str);
+        
+        if(R.size() > 0)
+            typeID = R[0][0].as<int>();
+        W.commit();
+        return typeID;
+    }
+    catch(const exception &e) {
+        std::wstringstream msg;
+        msg << L"TskDBPostgreSQL::getAttributeTypeID:"
+            << e.what() << std::endl;
+        LOGERROR(msg.str());
+        throw TskException("TskDBPostgreSQL::getAttributeTypeID - No attribute type with that name");
+    }
+}
+
+
+/**
+ * Get the attribute type name for the given artifact type id
+ * @param attributeTypeID id
+ * @returns attribute type name
+ */
+string TskImgDBPostgreSQL::getAttributeTypeName(int attributeTypeID){
+    if (!m_dbConnection)
+        throw TskException("No database.");
+
+    std::stringstream str;
+    std::string typeName = "";
+
+    str << "SELECT type_name FROM blackboard_attribute_types WHERE attribute_type_id = " << attributeTypeID;
+
+    try{
+        pqxx::work W(*m_dbConnection);
+        pqxx::result R = W.exec(str);
+        
+        if(R.size() > 0)
+            typeName = R[0][0].as<string>();
+        W.commit();
+        return typeName;
+    }
+    catch(const exception &e) {
+        std::wstringstream msg;
+        msg << L"TskDBPostgreSQL::getAttributeTypeName:"
+            << e.what() << std::endl;
+        LOGERROR(msg.str());
+        throw TskException("TskDBPostgreSQL::getAttributeTypeName - No attribute type with that id");
+    }
+}
+
+/**
+ * Get all artifacts with that match the given where clause 
+ * @param whereClause where clause to use for matching
+ * @returns vector of matching artifacts
+ */
+vector<TskBlackboardArtifact> TskImgDBPostgreSQL::getMatchingArtifacts(string whereClause){
+    if (!m_dbConnection)
+        throw TskException("No database.");
+    
+    vector<TskBlackboardArtifact> artifacts;
+    std::string stmt("SELECT blackboard_artifacts.artifact_id, blackboard_artifacts.obj_id, blackboard_artifacts.artifact_type_id FROM blackboard_artifacts");
+
+    constructStmt(stmt, whereClause);
+
+    try
+    {
+        pqxx::work W(*m_dbConnection);
+        pqxx::result R = W.exec(stmt);
+        W.commit();
+
+        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i) 
+        {
+            int artifactTypeID = i[2].as<int>();
+            
+            artifacts.push_back(TskImgDB::createArtifact(i[0].as<uint64_t>(), i[1].as<uint64_t>(), artifactTypeID));
+        }
+        
+        return artifacts;
+    } catch(const exception &e) {
+        std::wstringstream msg;
+        msg << L"TskDBPostgreSQL::getMatchingArtifacts:"
+            << e.what() << std::endl;
+        LOGERROR(msg.str());
+        throw TskException("TskDBPostgreSQL::getMatchingArtifacts");
+    }
+    return artifacts;
+}
+
+/**
+ * Get all attributes with that match the given where clause 
+ * @param whereClause where clause to use for matching
+ * @returns vector of matching attributes
+ */
+vector<TskBlackboardAttribute> TskImgDBPostgreSQL::getMatchingAttributes(string whereClause){
+    if (!m_dbConnection)
+        throw TskException("No database.");
+    
+    vector<TskBlackboardAttribute> attributes;
+    std::string stmt("SELECT blackboard_attributes.artifact_id, blackboard_attributes.source, blackboard_attributes.context, blackboard_attributes.attribute_type_id, blackboard_attributes.value_type, blackboard_attributes.value_byte, blackboard_attributes.value_text, blackboard_attributes.value_int32, blackboard_attributes.value_int64, blackboard_attributes.value_double, blackboard_attributes.obj_id FROM blackboard_attributes ");
+
+    constructStmt(stmt, whereClause);
+
+    try
+    {
+        pqxx::work W(*m_dbConnection);
+        pqxx::result R = W.exec(stmt);
+
+        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i) 
+        {
+            pqxx::binarystring binStr(i[6]);
+            int a_size = binStr.size();
+            vector<unsigned char> bytes;
+            bytes.reserve(a_size);
+            for (int j = 0; j < a_size; j++)
+                bytes.push_back((unsigned char)binStr[j]);
+            
+            attributes.push_back(TskImgDB::createAttribute(i[0].as<uint64_t>(), i[3].as<int>(), i[10].as<uint64_t>(), 
+                i[1].as<string>(), i[2].as<string>(), (TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE) i[4].as<int>(), i[7].as<int>(), 
+                i[8].as<uint64_t>(), i[9].as<double>(), i[6].as<string>(), bytes));
+        }
+        W.commit();
+    } catch(const exception &e) {
+        std::wstringstream msg;
+        msg << L"TskDBPostgreSQL::getMatchingAttributes:"
+            << e.what() << std::endl;
+        LOGERROR(msg.str());
+        throw TskException("TskDBPostgreSQL::getMatchingAttributes");
+    }
+    return attributes;
+}
+
+/**
+ * Create a new blackboard artifact with the given type id and file id
+ * @param artifactTypeID artifact type id
+ * @param file_id associated file id
+ * @returns the new artifact
+ */
+TskBlackboardArtifact TskImgDBPostgreSQL::createBlackboardArtifact(uint64_t file_id, int artifactTypeID){
+    if (!m_dbConnection)
+        throw TskException("No database.");
+
+    uint64_t artifactId = 0;
+    std::stringstream str;
+
+    str << "INSERT INTO blackboard_artifacts (artifact_id, obj_id, artifact_type_id) VALUES (DEFAULT, " 
+        << file_id << ", " << artifactTypeID << ")"
+        << "RETURNING artifact_id";
+
+    try {
+        pqxx::work W(*m_dbConnection);
+        pqxx::result R = W.exec(str);
+        
+        if (R.size() == 1)
+        {
+            R[0][0].to(artifactId);
+        }
+        else
+        {
+            std::stringstream errorMsg;
+            errorMsg << "TskImgDBPostgreSQL::createBlackboardArtifact - Unexpected number of rows returned."
+                << R.size();
+            throw TskException(errorMsg.str());
+        }
+        W.commit();
+    } catch(const exception &e) {
+        std::wstringstream msg;
+        msg << L"TskDBPostgreSQL::newBlackboardArtifact:"
+            << e.what() << std::endl;
+        LOGERROR(msg.str());
+        throw TskException("TskDBPostgreSQL::newBlackboardArtifact");
+    }
+
+    return TskImgDB::createArtifact(artifactId, file_id, artifactTypeID);
+}
+
+/**
+ * Add a new artifact type with the given name, display name and id 
+ * @param artifactTypeName type name
+ * @param displayName display name
+ * @param typeID type id
+ */
+void TskImgDBPostgreSQL::addArtifactType(int typeID, string artifactTypeName, string displayName){
+    if (!m_dbConnection)
+        throw TskException("No database.");
+
+    std::stringstream str;
+
+    str << "SELECT * FROM blackboard_artifact_types WHERE type_name = '" << artifactTypeName << "'";
+
+    try{
+        pqxx::work W(*m_dbConnection);
+        pqxx::result R = W.exec(str);
+        if(R.size() == 0){
+            str.str("");
+            str << "INSERT INTO blackboard_artifact_types (artifact_type_id, type_name, display_name) VALUES (" << typeID << " , '" << artifactTypeName << "', '" << displayName << "')";
+            pqxx::result R = W.exec(str);
+
+        }
+        else{
+            throw TskException("TskImgDBPostgreSQL::addArtifactType - Artifact type with that name already exists");
+        }
+        W.commit();
+    } catch(const exception &e) {
+        std::wstringstream msg;
+        msg << L"TskDBPostgreSQL::addArtifactType:"
+            << e.what() << std::endl;
+        LOGERROR(msg.str());
+        throw TskException("TskDBPostgreSQL::addArtifactType");
+    }
+}
+
+/**
+ * Add a new attribute type with the given name, display name and id 
+ * @param attributeTypeName type name
+ * @param displayName display name
+ * @param typeID type id
+ */
+void TskImgDBPostgreSQL::addAttributeType(int typeID, string attributeTypeName, string displayName){
+    if (!m_dbConnection)
+        throw TskException("No database.");
+
+    std::stringstream str;
+
+    str << "SELECT * FROM blackboard_attribute_types WHERE type_name = '" << attributeTypeName << "'";
+
+    try{
+        pqxx::work W(*m_dbConnection);
+        pqxx::result R = W.exec(str);
+        if(R.size() == 0){
+            str.str("");
+            str << "INSERT INTO blackboard_attribute_types (attribute_type_id, type_name, display_name) VALUES (" << typeID << " , '" << attributeTypeName << "', '" << displayName << "')";
+            pqxx::result R = W.exec(str);
+
+        }
+        else{
+            throw TskException("TskImgDBPostgreSQL::addArtifactType - Artifact type with that name already exists");
+        }
+        W.commit();
+    } catch(const exception &e) {
+        std::wstringstream msg;
+        msg << L"TskDBPostgreSQL::addAttributeType:"
+            << e.what() << std::endl;
+        LOGERROR(msg.str());
+        throw TskException("TskDBPostgreSQL::addAttributeType");
+    }
+}
+
+/**
+ * Get all artifacts with the given type id, type name, and file id
+ * @param artifactTypeID type id
+ * @param artifactTypeName type name
+ * @param file_id file id
+ */
+vector<TskBlackboardArtifact> TskImgDBPostgreSQL::getArtifactsHelper(uint64_t file_id, int artifactTypeID, string artifactTypeName){
+    if (!m_dbConnection)
+        throw TskException("No database.");
+    
+    int result = 0;
+    vector<TskBlackboardArtifact> artifacts;
+    std::stringstream stmt;
+    stmt << "SELECT artifact_id, obj_id, artifact_type_id FROM blackboard_artifacts WHERE obj_id = " << file_id << " AND artifact_type_id = " << artifactTypeID;
+
+    try 
+    {
+
+        string displayName = getArtifactTypeDisplayName(artifactTypeID);
+        pqxx::work W(*m_dbConnection);
+        pqxx::result R = W.exec(stmt);
+
+        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i) 
+        {
+            int artifactTypeID = i[2].as<int>();
+            
+            artifacts.push_back(TskImgDB::createArtifact(i[0].as<uint64_t>(), file_id, artifactTypeID));
+        }
+        W.commit();
+    } catch(const exception &e) {
+        std::wstringstream msg;
+        msg << L"TskDBPostgreSQL::getArtifactsHelper:"
+            << e.what() << std::endl;
+        LOGERROR(msg.str());
+        throw TskException("TskDBPostgreSQL::getArtifactsHelper");
+    }
+    return artifacts;
+}
+vector<int> TskImgDBPostgreSQL::findAttributeTypes(int artifactTypeId){
+    if (!m_dbConnection)
+        throw TskException("No database.");
+    
+    int result = 0;
+    vector<int> attributeTypes;
+    std::stringstream stmt;
+    stmt << "SELECT DISTINCT(attribute_type_id) FROM blackboard_attributes JOIN blackboard_artifacts ON blackboard_attributes.artifact_id = blackboard_artifacts.artifact_id WHERE artifact_type_id = " << artifactTypeId;
+
+    try 
+    {
+        pqxx::work W(*m_dbConnection);
+        pqxx::result R = W.exec(stmt);
+
+        for (pqxx::result::const_iterator i = R.begin(); i != R.end(); ++i) 
+        {
+            int artifactTypeID = i[0].as<int>();
+            
+            attributeTypes.push_back(artifactTypeID);
+        }
+        W.commit();
+    } catch(const exception &e) {
+        std::wstringstream msg;
+        msg << L"TskDBPostgreSQL::findAttributeTypes:"
+            << e.what() << std::endl;
+        LOGERROR(msg.str());
+        throw TskException("TskDBPostgreSQL::findAttributeTypes");
+    }
+    return attributeTypes;
+}
+
+std::string TskImgDBPostgreSQL::quote(const std::string str) const
+{
+    return m_dbConnection->quote(str);
+}
diff --git a/framework/tsk/framework/services/TskImDBPostgreSQL.h b/framework/tsk/framework/services/TskImgDBPostgreSQL.h
similarity index 89%
rename from framework/tsk/framework/services/TskImDBPostgreSQL.h
rename to framework/tsk/framework/services/TskImgDBPostgreSQL.h
index 7397f6b..edd8ba3 100755
--- a/framework/tsk/framework/services/TskImDBPostgreSQL.h
+++ b/framework/tsk/framework/services/TskImgDBPostgreSQL.h
@@ -1,175 +1,177 @@
-/*
- *
- *  The Sleuth Kit
- *
- *  Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- *  Copyright (c) 2010-2011 Basis Technology Corporation. All Rights
- *  reserved.
- *
- *  This software is distributed under the Common Public License 1.0
- */
-
-#ifndef _TSK_IMGDBPOSTGRESQL_H
-#define _TSK_IMGDBPOSTGRESQL_H
-
-// System includes
-#include <string> // to get std::wstring
-#include <list>
-#include <vector>
-
-// Framework includes
-#include "framework_i.h"
-#include "Services/TskImgDB.h"
-#include "Utilities/SectorRuns.h"
-#include "Utilities/UnallocRun.h"
-#include "services/TskBlackboard.h"
-
-#include "tsk3/libtsk.h"
-
-#include <iostream>
-#include <stdlib.h>
-#undef min
-#undef max
-#include <pqxx/pqxx>
-using namespace std;
-using namespace pqxx;
-
-/// Framework data access layer the uses PostgreSQL as the back end.
-class TskImgDBPostgreSQL : public TskImgDB
-{
-public:
-    TskImgDBPostgreSQL(const std::string dbName);
-    virtual ~ TskImgDBPostgreSQL();
-
-    virtual int initialize();
-    virtual int open();
-
-    virtual int close();
-
-    virtual int begin();
-    virtual int commit();
-
-    virtual int addToolInfo(const char* name, const char* version);
-    virtual int addImageInfo(int type, int sectorSize);
-    virtual int addImageName(char const * imgName);
-    virtual int addVolumeInfo(const TSK_VS_PART_INFO * vs_part);
-    virtual int addFsInfo(int volId, int fsId, const TSK_FS_INFO * fs_info);
-    virtual int addFsFileInfo(int fileSystemID, const TSK_FS_FILE *fileSystemFile, const char *fileName, int fileSystemAttrType, int fileSystemAttrID, uint64_t &fileID, const char *filePath);
-    virtual int addCarvedFileInfo(int vol_id, wchar_t * name, uint64_t size, uint64_t *runStarts, uint64_t *runLengths, int numRuns, uint64_t & fileId);
-    virtual int addDerivedFileInfo(const std::string& name, const uint64_t parentId,
-                                        const bool isDirectory, const uint64_t size, const std::string& details,
-                                        const int ctime, const int crtime, const int atime, const int mtime, uint64_t & fileId, std::string path);
-    virtual int addFsBlockInfo(int fsID, uint64_t a_mFileId, int count, uint64_t blk_addr, uint64_t len);
-    virtual int addAllocUnallocMapInfo(int unallocVolID, int unallocImgID, uint64_t unallocImgStart, uint64_t length, uint64_t origImgStart);
-    virtual int getSessionID() const;
-    virtual int getFileIds(char *a_fileName, uint64_t *a_outBuffer, int a_buffSize) const;
-    virtual int getMaxFileIdReadyForAnalysis(uint64_t a_lastFileId, uint64_t & maxFileId) const;
-    virtual int getMinFileIdReadyForAnalysis(uint64_t & minFileId) const;
-    virtual uint64_t getFileId(int fsId, uint64_t fs_file_id) const;
-    virtual int getFileRecord(const uint64_t fileId, TskFileRecord& fileRecord) const;
-    virtual SectorRuns * getFileSectors(uint64_t fileId) const;
-    virtual std::string getImageBaseName() const;
-    virtual std::vector<std::wstring> getImageNames() const;
-    virtual int getFileUniqueIdentifiers(uint64_t a_fileId, uint64_t &a_fsOffset, uint64_t &a_fsFileId, int &a_attrType, int &a_attrId) const;
-    virtual int getNumVolumes() const;
-    virtual int getNumFiles() const;
-    virtual int getImageInfo(int & type, int & sectorSize) const;
-    virtual int getVolumeInfo(std::list<TskVolumeInfoRecord> & volumeInfoList) const;
-    virtual int getFsInfo(std::list<TskFsInfoRecord> & FsInfoList) const;
-    virtual int getFileInfoSummary(std::list<TskFileTypeRecord> & fileTypeInfoList) const;
-    virtual int getFileInfoSummary(FILE_TYPES fileType, std::list<TskFileTypeRecord> & fileTypeInfoList) const;
-    virtual TskImgDB::KNOWN_STATUS getKnownStatus(const uint64_t fileId) const;
-
-    virtual UnallocRun * getUnallocRun(int file_id, int file_offset) const; 
-    virtual SectorRuns * getFreeSectors() const;
-
-    virtual int updateFileStatus(uint64_t a_file_id, TskImgDB::FILE_STATUS a_status);
-    virtual int updateKnownStatus(uint64_t a_file_id, TskImgDB::KNOWN_STATUS a_status);
-	
-    virtual bool dbExist() const;
-
-    /// Get set of file ids that match the given condition (i.e. SQL where clause)
-    virtual std::vector<uint64_t> getFileIds(std::string& condition) const;
-    virtual std::vector<const TskFileRecord> getFileRecords(std::string& condition) const;
-
-    /// Get the number of files that match the given condition
-    virtual int getFileCount(std::string& condition) const;
-
-    virtual std::map<uint64_t, std::string> getUniqueCarvedFiles(HASH_TYPE hashType) const;
-    virtual std::vector<TskCarvedFileInfo> getUniqueCarvedFilesInfo(HASH_TYPE hashType) const;
-    virtual std::vector<uint64_t> getCarvedFileIds() const;
-
-    virtual std::vector<uint64_t> getUniqueFileIds(HASH_TYPE hashType) const;
-    virtual std::vector<uint64_t> getFileIds() const;
-
-    virtual int setHash(const uint64_t a_file_id, const TskImgDB::HASH_TYPE hashType, const std::string& hash) const;
-    virtual std::string getCfileName(const uint64_t a_file_id) const;
-
-    virtual int addModule(const std::string& name, const std::string& description, int & moduleId);
-    virtual int setModuleStatus(uint64_t file_id, int module_id, int status);
-	virtual int getModuleInfo(std::vector<TskModuleInfo> & moduleInfoList) const;
-    virtual int getModuleErrors(std::vector<TskModuleStatus> & moduleStatusList) const;
-    virtual std::string getFileName(uint64_t file_id) const;
-
-    virtual int addUnallocImg(int & unallocImgId);
-    virtual int setUnallocImgStatus(int unallocImgId, TskImgDB::UNALLOC_IMG_STATUS status);
-    virtual TskImgDB::UNALLOC_IMG_STATUS getUnallocImgStatus(int unallocImgId) const;
-    virtual int getAllUnallocImgStatus(std::vector<TskUnallocImgStatusRecord> & unallocImgStatusList) const;
- 
-    virtual int addUnusedSectors(int unallocImgId, std::vector<TskUnusedSectorsRecord> & unusedSectorsList);
-    virtual int getUnusedSector(uint64_t fileId, TskUnusedSectorsRecord & unusedSectorsRecord) const;
-
-    friend class TskDBBlackboard;
-
-protected:
-   // Blackboard methods.
-    virtual TskBlackboardArtifact createBlackboardArtifact(uint64_t file_id, int artifactTypeID);
-    virtual void addBlackboardAttribute(TskBlackboardAttribute attr);
-    
-    virtual void addArtifactType(int typeID, string artifactTypeName, string displayName);
-    virtual void addAttributeType(int typeID, string attributeTypeName, string displayName);
-
-    virtual string getArtifactTypeDisplayName(int artifactTypeID);
-    virtual int getArtifactTypeID(string artifactTypeString);
-    virtual string getArtifactTypeName(int artifactTypeID);
-    virtual vector<TskBlackboardArtifact> getMatchingArtifacts(string condition);
-
-    virtual string getAttributeTypeDisplayName(int attributeTypeID);
-    virtual int getAttributeTypeID(string attributeTypeString);
-    virtual string getAttributeTypeName(int attributeTypeID);
-    virtual vector<TskBlackboardAttribute> getMatchingAttributes(string condition);
-    
-    virtual vector<int> findAttributeTypes(int artifactTypeId);
-
-	std::string quote(const std::string str) const;
-
-private:
-    std::string m_dbName;
-    pqxx::connection * m_dbConnection;
-    int m_artifactIDcounter;
-    int m_attributeIDcounter;
-
-    // Execute the given statement and return the result set.
-	pqxx::result executeStatement(const std::string& stmt) const;
-
-    bool initialized() const;
-    std::vector<uint64_t> getFileIdsWorker(std::string tableName, const std::string condition = "") const;
-    void constructStmt(std::string& stmt, std::string& condition) const;
-    int addUnusedSector(uint64_t sectStart, uint64_t sectEnd, int volId, std::vector<TskUnusedSectorsRecord> & unusedSectorsList);
-    int getFileTypeRecords(std::string& stmt, std::list<TskFileTypeRecord>& fileTypeInfoList) const;
-    vector<TskBlackboardArtifact> getArtifactsHelper(uint64_t file_id, int artifactTypeID, string artifactTypeName);
-    void getCarvedFileInfo(const std::string& stmt, std::map<uint64_t, std::string>& results) const;
-
-    /**
-     * A helper function for getUniqueCarvedFilesInfo() that executes a very specific SQL SELECT statement 
-     * and returns the results as TskCarvedFileInfo objects.
-     *
-     * @param stmtToExecute The SQL statement
-     * @param getHash A flag indicating whether the SELECT includes a hash value
-     * @param carvedFileInfos The data returned by the query
-     * @return Throws TskException
-     */
-    void getCarvedFileInfo(const std::string &stmtToExecute,  bool getHash, std::vector<TskCarvedFileInfo> &carvedFileInfos) const;
-};
-
-#endif
+/*
+ *
+ *  The Sleuth Kit
+ *
+ *  Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ *  Copyright (c) 2010-2011 Basis Technology Corporation. All Rights
+ *  reserved.
+ *
+ *  This software is distributed under the Common Public License 1.0
+ */
+
+#ifndef _TSK_IMGDBPOSTGRESQL_H
+#define _TSK_IMGDBPOSTGRESQL_H
+
+// System includes
+#include <string> // to get std::wstring
+#include <list>
+#include <vector>
+
+// Framework includes
+#include "tsk/framework/framework_i.h"
+#include "tsk/framework/services/TskImgDB.h"
+#include "tsk/framework/utilities/SectorRuns.h"
+#include "tsk/framework/utilities/UnallocRun.h"
+#include "tsk/framework/services/TskBlackboard.h"
+
+#include "tsk/libtsk.h"
+
+#include <iostream>
+#include <stdlib.h>
+#undef min
+#undef max
+#include <pqxx/pqxx>
+using namespace std;
+using namespace pqxx;
+
+/// Framework data access layer the uses PostgreSQL as the back end.
+class TskImgDBPostgreSQL : public TskImgDB
+{
+public:
+    TskImgDBPostgreSQL(const std::string dbName);
+    virtual ~ TskImgDBPostgreSQL();
+
+    virtual int initialize();
+    virtual int initializePreparedStatements();
+    virtual int open();
+
+    virtual int close();
+
+    virtual int begin();
+    virtual int commit();
+
+    virtual int addToolInfo(const char* name, const char* version);
+    virtual int addImageInfo(int type, int sectorSize);
+    virtual int addImageName(char const * imgName);
+    virtual int addVolumeInfo(const TSK_VS_PART_INFO * vs_part);
+    virtual int addFsInfo(int volId, int fsId, const TSK_FS_INFO * fs_info);
+    virtual int addFsFileInfo(int fileSystemID, const TSK_FS_FILE *fileSystemFile, const char *fileName, int fileSystemAttrType, int fileSystemAttrID, uint64_t &fileID, const char *filePath);
+    virtual int addCarvedFileInfo(int vol_id, const char *name, uint64_t size, uint64_t *runStarts, uint64_t *runLengths, int numRuns, uint64_t & fileId);
+    virtual int addDerivedFileInfo(const std::string& name, const uint64_t parentId,
+                                        const bool isDirectory, const uint64_t size, const std::string& details,
+                                        const int ctime, const int crtime, const int atime, const int mtime, uint64_t & fileId, std::string path);
+    virtual int addFsBlockInfo(int fsID, uint64_t a_mFileId, int count, uint64_t blk_addr, uint64_t len);
+    virtual int addAllocUnallocMapInfo(int unallocVolID, int unallocImgID, uint64_t unallocImgStart, uint64_t length, uint64_t origImgStart);
+    virtual int getSessionID() const;
+    virtual int getFileIds(char *a_fileName, uint64_t *a_outBuffer, int a_buffSize) const;
+    virtual int getMaxFileIdReadyForAnalysis(uint64_t a_lastFileId, uint64_t & maxFileId) const;
+    virtual int getMinFileIdReadyForAnalysis(uint64_t & minFileId) const;
+    virtual uint64_t getFileId(int fsId, uint64_t fs_file_id) const;
+    virtual int getFileRecord(const uint64_t fileId, TskFileRecord& fileRecord) const;
+    virtual SectorRuns * getFileSectors(uint64_t fileId) const;
+    virtual std::string getImageBaseName() const;
+    virtual std::vector<std::wstring> getImageNamesW() const;
+    virtual std::vector<std::string>  getImageNames() const;
+    virtual int getFileUniqueIdentifiers(uint64_t a_fileId, uint64_t &a_fsOffset, uint64_t &a_fsFileId, int &a_attrType, int &a_attrId) const;
+    virtual int getNumVolumes() const;
+    virtual int getNumFiles() const;
+    virtual int getImageInfo(int & type, int & sectorSize) const;
+    virtual int getVolumeInfo(std::list<TskVolumeInfoRecord> & volumeInfoList) const;
+    virtual int getFsInfo(std::list<TskFsInfoRecord> & FsInfoList) const;
+    virtual int getFileInfoSummary(std::list<TskFileTypeRecord> & fileTypeInfoList) const;
+    virtual int getFileInfoSummary(FILE_TYPES fileType, std::list<TskFileTypeRecord> & fileTypeInfoList) const;
+    virtual TskImgDB::KNOWN_STATUS getKnownStatus(const uint64_t fileId) const;
+
+    virtual UnallocRun * getUnallocRun(int file_id, int file_offset) const; 
+    virtual SectorRuns * getFreeSectors() const;
+
+    virtual int updateFileStatus(uint64_t a_file_id, TskImgDB::FILE_STATUS a_status);
+    virtual int updateKnownStatus(uint64_t a_file_id, TskImgDB::KNOWN_STATUS a_status);
+	
+    virtual bool dbExist() const;
+
+    /// Get set of file ids that match the given condition (i.e. SQL where clause)
+    virtual std::vector<uint64_t> getFileIds(const std::string& condition) const;
+    virtual const std::vector<TskFileRecord> getFileRecords(const std::string& condition) const;
+
+    /// Get the number of files that match the given condition
+    virtual int getFileCount(const std::string& condition) const;
+
+    virtual std::map<uint64_t, std::string> getUniqueCarvedFiles(HASH_TYPE hashType) const;
+    virtual std::vector<TskCarvedFileInfo> getUniqueCarvedFilesInfo(HASH_TYPE hashType) const;
+    virtual std::vector<uint64_t> getCarvedFileIds() const;
+
+    virtual std::vector<uint64_t> getUniqueFileIds(HASH_TYPE hashType) const;
+    virtual std::vector<uint64_t> getFileIds() const;
+
+    virtual int setHash(const uint64_t a_file_id, const TskImgDB::HASH_TYPE hashType, const std::string& hash) const;
+    virtual std::string getCfileName(const uint64_t a_file_id) const;
+
+    virtual int addModule(const std::string& name, const std::string& description, int & moduleId);
+    virtual int setModuleStatus(uint64_t file_id, int module_id, int status);
+	virtual int getModuleInfo(std::vector<TskModuleInfo> & moduleInfoList) const;
+    virtual int getModuleErrors(std::vector<TskModuleStatus> & moduleStatusList) const;
+    virtual std::string getFileName(uint64_t file_id) const;
+
+    virtual int addUnallocImg(int & unallocImgId);
+    virtual int setUnallocImgStatus(int unallocImgId, TskImgDB::UNALLOC_IMG_STATUS status);
+    virtual TskImgDB::UNALLOC_IMG_STATUS getUnallocImgStatus(int unallocImgId) const;
+    virtual int getAllUnallocImgStatus(std::vector<TskUnallocImgStatusRecord> & unallocImgStatusList) const;
+ 
+    virtual int addUnusedSectors(int unallocImgId, std::vector<TskUnusedSectorsRecord> & unusedSectorsList);
+    virtual int getUnusedSector(uint64_t fileId, TskUnusedSectorsRecord & unusedSectorsRecord) const;
+
+    friend class TskDBBlackboard;
+
+protected:
+   // Blackboard methods.
+    virtual TskBlackboardArtifact createBlackboardArtifact(uint64_t file_id, int artifactTypeID);
+    virtual void addBlackboardAttribute(TskBlackboardAttribute attr);
+    
+    virtual void addArtifactType(int typeID, string artifactTypeName, string displayName);
+    virtual void addAttributeType(int typeID, string attributeTypeName, string displayName);
+
+    virtual string getArtifactTypeDisplayName(int artifactTypeID);
+    virtual int getArtifactTypeID(string artifactTypeString);
+    virtual string getArtifactTypeName(int artifactTypeID);
+    virtual vector<TskBlackboardArtifact> getMatchingArtifacts(string condition);
+
+    virtual string getAttributeTypeDisplayName(int attributeTypeID);
+    virtual int getAttributeTypeID(string attributeTypeString);
+    virtual string getAttributeTypeName(int attributeTypeID);
+    virtual vector<TskBlackboardAttribute> getMatchingAttributes(string condition);
+    
+    virtual vector<int> findAttributeTypes(int artifactTypeId);
+
+	std::string quote(const std::string str) const;
+
+private:
+    std::string m_dbName;
+    pqxx::connection * m_dbConnection;
+    int m_artifactIDcounter;
+    int m_attributeIDcounter;
+
+    // Execute the given statement and return the result set.
+	pqxx::result executeStatement(const std::string& stmt) const;
+
+    bool initialized() const;
+    std::vector<uint64_t> getFileIdsWorker(std::string tableName, const std::string condition = "") const;
+    void constructStmt(std::string& stmt, std::string condition) const;
+    int addUnusedSector(uint64_t sectStart, uint64_t sectEnd, int volId, std::vector<TskUnusedSectorsRecord> & unusedSectorsList);
+    int getFileTypeRecords(std::string& stmt, std::list<TskFileTypeRecord>& fileTypeInfoList) const;
+    vector<TskBlackboardArtifact> getArtifactsHelper(uint64_t file_id, int artifactTypeID, string artifactTypeName);
+    void getCarvedFileInfo(const std::string& stmt, std::map<uint64_t, std::string>& results) const;
+
+    /**
+     * A helper function for getUniqueCarvedFilesInfo() that executes a very specific SQL SELECT statement 
+     * and returns the results as TskCarvedFileInfo objects.
+     *
+     * @param stmtToExecute The SQL statement
+     * @param getHash A flag indicating whether the SELECT includes a hash value
+     * @param carvedFileInfos The data returned by the query
+     * @return Throws TskException
+     */
+    void getCarvedFileInfo(const std::string &stmtToExecute,  bool getHash, std::vector<TskCarvedFileInfo> &carvedFileInfos) const;
+};
+
+#endif
diff --git a/framework/tsk/framework/services/TskImgDBSqlite.cpp b/framework/tsk/framework/services/TskImgDBSqlite.cpp
index 232bd1e..0f06e79 100755
--- a/framework/tsk/framework/services/TskImgDBSqlite.cpp
+++ b/framework/tsk/framework/services/TskImgDBSqlite.cpp
@@ -1,3783 +1,3783 @@
-/*
- *
- *  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 TskImgDBSqlite.cpp
- * A SQLite based implementation of the framework data access layer.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <cassert>
-#include <iostream>
-#include <sstream>
-#include <iomanip>
-#include <map>
-#include <assert.h>
-
-#include "Poco/UnicodeConverter.h"
-#include "Poco/Thread.h"
-
-#include "TskImgDBSqlite.h"
-#include "TskServices.h"
-#include "tsk/framework/utilities/TskException.h"
-#include "TskDBBlackboard.h"
-
-#include "Poco/UnicodeConverter.h"
-#include "Poco/NumberParser.h"
-#include "Poco/Path.h"
-
-#define IMGDB_CHUNK_SIZE 1024*1024*1 // what size chunks should the database use when growing and shrinking
-#define IMGDB_MAX_RETRY_COUNT 50    // how many times will we retry a SQL statement
-#define IMGDB_RETRY_WAIT 100   // how long (in milliseconds) are we willing to wait between retries
-
-/**
- * Set the database location.  Must call
- * initialize() before the object can be used.
- * @param a_outpath Directory to store the database in. This 
- * directory must already exist.
-*/
-TskImgDBSqlite::TskImgDBSqlite(const char * a_outpath)
-{
-    strncpy(m_outPath, a_outpath, 256);
-    // ensure that the path ends with a '/'
-    if (m_outPath[strlen(m_outPath)-1] != '/') {
-        int len1 = strlen(m_outPath);
-        m_outPath[len1] = '/';
-        m_outPath[len1+1] = '\0';
-    }
-    strncpy(m_dbFilePath, m_outPath, 256);
-    strncat(m_dbFilePath, "image.db", 256);
-    m_db = NULL;
-}
-
-TskImgDBSqlite::~TskImgDBSqlite()
-{
-    (void) close();
-}
-
-int TskImgDBSqlite::close()
-{
-    if (m_db) {
-        if (sqlite3_close(m_db) == SQLITE_OK)
-            m_db = NULL;
-        else
-            return 1;
-    }
-    return 0;
-}
-
-int TskImgDBSqlite::dropTables()
-{
-    if (!m_db)
-        return 1;
-
-    char * errmsg;
-    // Drop all the tables. No error checking just Teutonic Destruction...
-    sqlite3_exec(m_db, "DROP TABLE db_info",NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP TABLE image_info",NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP TABLE image_names",NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP TABLE vol_info",NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP TABLE fs_info",NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP TABLE fs_files",NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP TABLE fs_blocks",NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP TABLE files",NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP TABLE derived_files",NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP TABLE carved_files",NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP TABLE carved_sectors",NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP TABLE alloc_unalloc_map", NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP TABLE blackboard_artifacts", NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP TABLE blackboard_attributes", NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP TABLE blackboard_artifact_types", NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP TABLE blackboard_attribute_types", NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP TABLE file_hashes", NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP TABLE modules", NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP TABLE module_status", NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP TABLE unalloc_img_status", NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP TABLE unused_sectors", NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP INDEX attrs_artifact_id", NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP INDEX attrs_attribute_type", NULL, NULL, &errmsg);
-    sqlite3_exec(m_db, "DROP INDEX attrs_obj_id", NULL, NULL, &errmsg);
-
-    return 0;
-}
-
-int TskImgDBSqlite::initialize()
-{
-    std::wstringstream infoMessage;
-    char * errmsg;
-
-    // Open the database.
-    if (open() != 0)
-    {
-        // Error message will have been logged by open()
-        return 1;
-    }
-
-    // Clean up the whole database.
-    dropTables();
-
-    std::string stmt;
-
-    sqlite3_stmt *statement;
-
-    // set page size -- 4k is much faster on Windows than the default
-    executeStatement("PRAGMA page_size = 4096;", statement, "TskImgDBSqlite::initialize");
-    sqlite3_finalize(statement);
-
-    // we don't have a mechanism to recover from a crash anyway
-    executeStatement("PRAGMA synchronous = 0;", statement, "TskImgDBSqlite::initialize");
-    sqlite3_finalize(statement);
-
-    // ----- DB_INFO
-    stmt = "CREATE TABLE db_info (name TEXT PRIMARY KEY, version TEXT)";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating db_info table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    // ----- IMAGE_INFO
-    stmt = "CREATE TABLE image_info (type INTEGER, ssize INTEGER)";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating image_info table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    // ----- IMAGE_NAMES
-    stmt = "CREATE TABLE image_names (seq INTEGER PRIMARY KEY, name TEXT)";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating image_names table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    // ----- VOL_INFO
-    stmt = "CREATE TABLE vol_info (vol_id INTEGER PRIMARY KEY, sect_start INTEGER NOT NULL, "
-        "sect_len INTEGER NOT NULL, description TEXT, flags INTEGER)";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating vol_info table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    // ----- FS_INFO
-    stmt = "CREATE TABLE fs_info (fs_id INTEGER PRIMARY KEY, img_byte_offset INTEGER, "
-        "vol_id INTEGER NOT NULL, fs_type INTEGER, block_size INTEGER, "
-        "block_count INTEGER, root_inum INTEGER, first_inum INTEGER, last_inum INTEGER)";
-    if (sqlite3_exec(m_db, stmt.c_str() , NULL, NULL, &errmsg) != SQLITE_OK) {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating fs_info table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    // ----- FILES
-    stmt = "CREATE TABLE files (file_id INTEGER PRIMARY KEY, type_id INTEGER, "
-        "name TEXT, par_file_id INTEGER, dir_type INTEGER, meta_type INTEGER, "
-        "dir_flags INTEGER, meta_flags INTEGER, size INTEGER, ctime INTEGER, "
-        "crtime INTEGER, atime INTEGER, mtime INTEGER, mode INTEGER, uid INTEGER, "
-        "gid INTEGER, status INTEGER, full_path TEXT)";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating files table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    // ----- FS_FILES
-    stmt = "CREATE TABLE fs_files (file_id INTEGER PRIMARY KEY, fs_id INTEGER, "
-        "fs_file_id INTEGER, attr_type INTEGER, attr_id INTEGER)";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK)
-    {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating fs_files table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    // ----- FS_BLOCKS
-    stmt = "CREATE TABLE fs_blocks (fs_id INTEGER NOT NULL, file_id INTEGER NOT NULL, seq INTEGER, "
-        "blk_start INTEGER NOT NULL, blk_len INTEGER NOT NULL)";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK)
-    {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating fs_blocks table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    // ----- CARVED_FILES
-    stmt = "CREATE TABLE carved_files (file_id INTEGER PRIMARY KEY, vol_id INTEGER)";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK)
-    {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating carved_files table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    // ----- SECTOR_LIST
-    stmt = "CREATE TABLE carved_sectors ("
-        "file_id INTEGER, seq INTEGER, sect_start INTEGER, sect_len INTEGER)";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK)
-    {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating carved_sectors table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    // ----- DERIVED_FILES
-    stmt = "CREATE TABLE derived_files (file_id INTEGER PRIMARY KEY, derivation_details TEXT)";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK)
-    {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating derived_files table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    // ----- ALLOC_UNALLOC_MAP
-    stmt = "CREATE TABLE alloc_unalloc_map (vol_id INTEGER, unalloc_img_id INTEGER, "
-        "unalloc_img_sect_start INTEGER, sect_len INTEGER, orig_img_sect_start INTEGER)";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK)
-    {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating alloc_unalloc_map table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    // ----- FILE_HASHES
-    stmt = "CREATE TABLE file_hashes (file_id INTEGER PRIMARY KEY, md5 TEXT, sha1 TEXT, sha2_256 TEXT, sha2_512 TEXT, known INTEGER)";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating file_hashes table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    // ----- MODULES
-    stmt = "CREATE TABLE modules (module_id INTEGER PRIMARY KEY, name TEXT UNIQUE NOT NULL, description TEXT)";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating module table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    // ----- MODULE_STATUS
-    stmt = "CREATE TABLE module_status (file_id INTEGER, module_id INTEGER, status INTEGER, PRIMARY KEY (file_id, module_id))";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating module_status table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    // ----- UNALLOC_IMG_STATUS
-    stmt = "CREATE TABLE unalloc_img_status (unalloc_img_id INTEGER PRIMARY KEY, status INTEGER)";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating unalloc_img_status table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    // ----- UNUSED_SECTORS
-    stmt = "CREATE TABLE unused_sectors (file_id INTEGER PRIMARY KEY, sect_start INTEGER, sect_len INTEGER, vol_id INTEGER)";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating unused_sectors table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    // ----- BLACKBOARD_ARTIFACTS
-    stmt = "CREATE TABLE blackboard_artifacts (artifact_id INTEGER PRIMARY KEY, obj_id INTEGER NOT NULL, artifact_type_id INTEGER)";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating blackboard_artifacts table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    // ----- BLACKBOARD_ATTRIBUTES
-    stmt = "CREATE TABLE blackboard_attributes (artifact_id INTEGER NOT NULL, source TEXT, context TEXT, attribute_type_id INTEGER NOT NULL, value_type INTEGER NOT NULL, "
-        "value_byte BLOB, value_text TEXT, value_int32 INTEGER, value_int64 INTEGER, value_double NUMERIC(20, 10), obj_id INTEGER NOT NULL)";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating blackboard_attributes table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    // ----- BLACKBOARD_ARTIFACT_TYPES
-    stmt = "CREATE TABLE blackboard_artifact_types (artifact_type_id INTEGER PRIMARY KEY, type_name TEXT, display_name TEXT)";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating blackboard_artifact_types table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    // ----- BLACKBOARD_ATTRIBUTE_TYPES
-    stmt = "CREATE TABLE blackboard_attribute_types (attribute_type_id INTEGER PRIMARY KEY, type_name TEXT, display_name TEXT)";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating blackboard_attribute_types table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    // ----- CREATE INDEXES
-    stmt = "CREATE INDEX attrs_artifact_id ON blackboard_attributes(artifact_id)";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating attrs_artifact_id index: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    stmt = "CREATE INDEX attrs_attribute_type ON blackboard_attributes(attribute_type_id)";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating attrs_attribute_type index: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    stmt = "CREATE INDEX attrs_obj_id ON blackboard_attributes(obj_id)";
-    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        infoMessage << L"TskImgDBSqlite::initialize - Error creating attrs_obj_id index: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    map<int, TskArtifactNames> artTypes = TskImgDB::getAllArtifactTypes();
-    for (map<int, TskArtifactNames>::iterator it = artTypes.begin(); it != artTypes.end(); it++) {
-        addArtifactType(it->first, it->second.typeName, it->second.displayName);
-    }
-    map<int, TskAttributeNames> attrTypes = TskImgDB::getAllAttributeTypes();
-    for (map<int, TskAttributeNames>::iterator it = attrTypes.begin(); it != attrTypes.end(); it++) {
-        addAttributeType(it->first, it->second.typeName, it->second.displayName);
-    }
-
-    addToolInfo("DBSchema", IMGDB_SCHEMA_VERSION);
-    LOGINFO(L"ImgDB Created.");
-
-    return 0;
-}
-
-/*
- * If the database file exists this method will open it otherwise
- * it will create a new database. 
- * This method also configures the chunk size and the busy handler
- * for the newly opened database.
-*/
-int TskImgDBSqlite::open()
-{
-    std::wstringstream infoMessage;
-
-#if 0
-    if (sqlite3_open16(m_dbFilePath, &m_db)) 
-#else
-    if (sqlite3_open(m_dbFilePath, &m_db)) 
-#endif
-    {
-        infoMessage << L"TskImgDBSqlite::open - Can't create new database: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-
-        sqlite3_close(m_db);
-        return 1;
-    }
-
-    // The chunk size setting defines by how much the database will grow
-    // or shrink. The primary motivation behind this setting is to reduce
-    // database file fragmentation and potential performance improvements.
-    // We, however, are using this setting as a workaround for database
-    // corruption issues we have been experiencing when the database is
-    // updated by multiple concurrent processes.
-    // Database corruption was occuring when SQLite determined that the 
-    // number of database pages in the database was greater than a value
-    // that it had previously cached. 
-    // This workaround is a crude mechanism to get around that situation.
-    int chunkSize = IMGDB_CHUNK_SIZE;
-
-    if (sqlite3_file_control(m_db, NULL, SQLITE_FCNTL_CHUNK_SIZE, &chunkSize) != SQLITE_OK)
-    {
-        infoMessage << L"TskImgDBSqlite::open - Failed to set chunk size: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-
-        sqlite3_close(m_db);
-        return 1;
-    }
-
-    // Register a busy handler that will retry statements in situations
-    // where the database is locked by another process.
-    if (sqlite3_busy_handler(m_db, TskImgDBSqlite::busyHandler, m_db) != SQLITE_OK)
-    {
-        infoMessage <<  L"TskImgDBSqlite::open - Failed to set busy handler: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-
-        sqlite3_close(m_db);
-        return 1;
-    }
-
-    LOGINFO(L"ImgDB Opened.");
-
-    return 0;
-}
-
-int TskImgDBSqlite::addToolInfo(const char* name, const char* version)
-{
-    char *errmsg;
-    char stmt[1024];
-
-    if (!m_db)
-        return 1;
-
-    sqlite3_snprintf(1024, stmt, 
-        "INSERT INTO db_info (name, version) VALUES ('%q', '%q');",
-        name, version);
-    if (sqlite3_exec(m_db, stmt, NULL, NULL, &errmsg) != SQLITE_OK)
-    {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::addToolInfo - Error adding data to db_info table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    return 0;
-}
-
-int TskImgDBSqlite::addImageInfo(int type, int size)
-{
-    char *errmsg;
-    std::stringstream stmt;
-
-    if (!m_db)
-        return 1;
-
-    stmt << "INSERT INTO image_info (type, ssize) VALUES ("<< type << ", " << size << ");";
-    if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, &errmsg) != SQLITE_OK)
-    {
-        std::wstringstream infoMessage;
-        infoMessage <<  L"TskImgDBSqlite::addImageInfo - Error adding data to image_info table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    return 0;
-}
-
-int TskImgDBSqlite::addImageName(char const *imgPath)
-{
-    char *errmsg;
-    char stmt[1024];
-
-    if (!m_db)
-        return 1;
-
-    sqlite3_snprintf(1024, stmt,
-        "INSERT INTO image_names (seq, name) VALUES (NULL, '%q')",
-        imgPath);
-    if (sqlite3_exec(m_db, stmt, NULL, NULL, &errmsg) != SQLITE_OK)
-    {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::addImageName - Error adding data to image_names table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-    return 0;
-}
-
-/*
- * Adds the sector addresses of the volumes into the db.
- */
-int TskImgDBSqlite::addVolumeInfo(const TSK_VS_PART_INFO * vs_part)
-{
-    char stmt[1024];
-    char * errmsg;
-
-    if (!m_db)
-        return 1;
-
-    sqlite3_snprintf(1024, stmt,
-        "INSERT INTO vol_info (vol_id, sect_start, sect_len, description, flags) VALUES (%d,%"
-        PRIuOFF ",%" PRIuOFF ",'%q',%d)", (int)vs_part->addr,
-        vs_part->start, vs_part->len, vs_part->desc, vs_part->flags);
-
-    if (sqlite3_exec(m_db, stmt, NULL, NULL, &errmsg) != SQLITE_OK) {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::addVolumeInfo - Error adding data to vol_info table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    return 0;
-}
-
-int TskImgDBSqlite::addFsInfo(int volId, int fsId, const TSK_FS_INFO * fs_info)
-{
-    std::stringstream stmt;
-    char * errmsg;
-
-    if (!m_db)
-        return 1;
-
-    stmt <<
-        "INSERT INTO fs_info (fs_id, img_byte_offset, vol_id, fs_type, block_size, "
-        "block_count, root_inum, first_inum, last_inum) VALUES (" << 
-        fsId << ", " << fs_info->offset << ", " <<  volId << ", " << 
-        (int)fs_info->ftype << ", " <<  fs_info->block_size << ", " <<  fs_info->block_count << ", " << 
-        fs_info->root_inum << ", " <<  fs_info->first_inum << ", " <<  fs_info->last_inum << ")";
-
-    if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::addFsInfo - Error adding data to fs_info table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    return 0;
-}
-
-
-/**
- * Given a file system and fs_file_id, return the file_id.
- */
-uint64_t TskImgDBSqlite::getFileId(int a_fsId, uint64_t a_fsFileId) const
-{
-    if (!m_db)
-        return 0;
-
-    sqlite3_stmt * statement;
-    std::stringstream stmt;
-    uint64_t fileId = 0;
-    stmt << "SELECT file_id FROM fs_files WHERE fs_id=" << a_fsId << " and fs_file_id=" << a_fsFileId << ";";
-
-    /********** FIND the unallocated volumes *************/
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        int result = sqlite3_step(statement);
-        if (result == SQLITE_ROW) {
-            fileId = (uint64_t)sqlite3_column_int64(statement, 0);
-        }
-        sqlite3_finalize(statement);
-    }
-    else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getFileId - Error querying fs_files table: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-
-        return 0;
-    }
-    return fileId;
-}
-
-
-int TskImgDBSqlite::getFileRecord(const uint64_t fileId, TskFileRecord& fileRecord) const
-{
-    if (!m_db)
-        return -1;
-
-    int ret = 0;
-
-    sqlite3_stmt * statement;
-    std::stringstream stmt;
-
-    stmt << "SELECT f.file_id, f.type_id, f.name, f.par_file_id, f.dir_type, f.meta_type, f.dir_flags, "
-        << "f.meta_flags, f.size, f.ctime, f.crtime, f.atime, f.mtime, f.mode, f.uid, f.gid, f.status, f.full_path, "
-        << "fh.md5, fh.sha1, fh.sha2_256, fh.sha2_512 "
-        << "FROM files f LEFT OUTER JOIN file_hashes fh ON f.file_id = fh.file_id WHERE f.file_id=" << fileId;
-
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) 
-    {
-        int result = sqlite3_step(statement);
-
-        if (result == SQLITE_ROW) 
-        {
-            fileRecord.fileId       = sqlite3_column_int64(statement, 0);
-            fileRecord.typeId = (TskImgDB::FILE_TYPES)sqlite3_column_int(statement, 1);
-            fileRecord.name         = (char *)sqlite3_column_text(statement, 2);
-            fileRecord.parentFileId = sqlite3_column_int64(statement, 3);
-            fileRecord.dirType = (TSK_FS_NAME_TYPE_ENUM) sqlite3_column_int(statement, 4);
-            fileRecord.metaType = (TSK_FS_META_TYPE_ENUM) sqlite3_column_int(statement, 5);
-            fileRecord.dirFlags = (TSK_FS_NAME_FLAG_ENUM) sqlite3_column_int(statement, 6);
-            fileRecord.metaFlags = (TSK_FS_META_FLAG_ENUM) sqlite3_column_int(statement, 7);
-            fileRecord.size         = sqlite3_column_int64(statement, 8);
-            fileRecord.ctime        = sqlite3_column_int(statement, 9);
-            fileRecord.crtime       = sqlite3_column_int(statement, 10);
-            fileRecord.atime        = sqlite3_column_int(statement, 11);
-            fileRecord.mtime        = sqlite3_column_int(statement, 12);
-            fileRecord.mode = (TSK_FS_META_MODE_ENUM)sqlite3_column_int(statement, 13);
-            fileRecord.uid          = sqlite3_column_int(statement, 14);
-            fileRecord.gid          = sqlite3_column_int(statement, 15);
-            fileRecord.status = (TskImgDB::FILE_STATUS) sqlite3_column_int(statement, 16);
-            fileRecord.fullPath     = (char *)sqlite3_column_text(statement, 17);
-
-            if (sqlite3_column_type(statement, 18) == SQLITE_TEXT)
-                fileRecord.md5      = (char *)sqlite3_column_text(statement, 18);
-            if (sqlite3_column_type(statement, 19) == SQLITE_TEXT)
-                fileRecord.sha1     = (char *)sqlite3_column_text(statement, 19);
-            if (sqlite3_column_type(statement, 20) == SQLITE_TEXT)
-                fileRecord.sha2_256 = (char *)sqlite3_column_text(statement, 20);
-            if (sqlite3_column_type(statement, 21) == SQLITE_TEXT)
-                fileRecord.sha2_512 = (char *)sqlite3_column_text(statement, 21);
-        }
-        else 
-        {
-            std::wstringstream msg;
-            msg << L"TskImgDBSqlite::getFileRecord - Error querying files table for file id: " << fileId;
-            LOGERROR(msg.str());
-
-            ret = -1;
-        }
-        sqlite3_finalize(statement);
-    }
-    else 
-    {
-        std::wstringstream msg;
-        msg << L"TskImgDBSqlite::getFileRecord - Error querying files table for file id: " << fileId;
-        LOGERROR(msg.str());
-
-        ret = -1;
-    }
-
-    return ret;
-}
-
-int TskImgDBSqlite::addFsFileInfo(int fileSystemID, const TSK_FS_FILE *fileSystemFile, const char *fileName, int fileSystemAttrType, int fileSystemAttrID, uint64_t &fileID, const char *filePath)
-{
-    const std::string msgPrefix = "TskImgDBSqlite::addFsFileInfo : ";
-    fileID = 0;
-
-    if (!m_db)
-    {
-        return -1;
-    }
-
-    // Construct the full path of the file within the image.
-    std::string fullpath(filePath);
-    fullpath.append(fileName);
-
-    // Replace all single quotes in the file name with double single quotes to comply with SQLLite syntax.
-    std::string fileNameAsString(fileName);
-    size_t found = fileNameAsString.find("'");
-    if (found != std::string::npos) //Replace it and replace all its subsequent occurrences.
-    {
-        fileNameAsString.replace(found,1,"''");
-
-        while ((found=fileNameAsString.find("'", found+2)) != std::string::npos)// found+2 because we want to move past the newly inserted single quote.
-        {
-            fileNameAsString.replace(found,1,"''");
-        }
-    }
-
-    // Now remove all the control characters from the file name.
-    for (int codePoint=1; codePoint < 32; codePoint++)
-    {
-        char codePointAsHex[10];
-        codePointAsHex[0] = codePoint;
-        codePointAsHex[1] = '\0';
-        std::string stringToRemove(codePointAsHex);
-
-        found = fileNameAsString.find(stringToRemove);
-        if (found != std::string::npos) //Replace it and replace all its subsequent occurrences.
-        {
-            fileNameAsString.replace(found,1,"");
-
-            while ((found=fileNameAsString.find(stringToRemove,found+1)) != std::string::npos)// found+1 because the control characters are just 1 character.
-            {
-                fileNameAsString.replace(found,1,"");
-            }
-        }
-    }
-
-    fileName = fileNameAsString.c_str();
-
-    // Get the file size.
-    TSK_OFF_T size = 0; 
-    const TSK_FS_ATTR *fileSystemAttribute = tsk_fs_file_attr_get_id(const_cast<TSK_FS_FILE*>(fileSystemFile), fileSystemAttrID); 
-    if (fileSystemAttribute)
-    {
-        size = fileSystemAttribute->size;
-    }
-
-    // Get the file metadata, if it's available.
-    int mtime = 0;
-    int crtime = 0;
-    int ctime = 0;
-    int atime = 0;
-    int meta_type = 0;
-    int meta_flags = 0;
-    int meta_mode = 0;
-    int gid = 0;
-    int uid = 0;
-    if (fileSystemFile->meta) 
-    {
-        mtime = static_cast<int>(fileSystemFile->meta->mtime);
-        atime = static_cast<int>(fileSystemFile->meta->atime);
-        ctime = static_cast<int>(fileSystemFile->meta->ctime);
-        crtime = static_cast<int>(fileSystemFile->meta->crtime);
-        meta_type = fileSystemFile->meta->type;
-        meta_flags = fileSystemFile->meta->flags;
-        meta_mode = fileSystemFile->meta->mode;
-        gid = fileSystemFile->meta->gid;
-        uid = fileSystemFile->meta->uid;
-    }
-
-    // Insert into the files table.
-    char stmt[4096];
-    sqlite3_snprintf(4096, stmt,
-        "INSERT INTO files (file_id, type_id, status, name, par_file_id, dir_type, meta_type, "
-        "dir_flags, meta_flags, size, crtime, ctime, atime, mtime, mode, gid, uid, full_path) VALUES (NULL, %d, %d,"
-        "'%q',%llu,%d,%d,%d,%d,%" PRIuOFF",%d,%d,%d,%d,%d,%d,%d,'%q')", 
-        IMGDB_FILES_TYPE_FS, IMGDB_FILES_STATUS_READY_FOR_ANALYSIS, fileName, 
-        findParObjId(fileSystemID, fileSystemFile->name->par_addr), 
-        fileSystemFile->name->type, meta_type,
-        fileSystemFile->name->flags, meta_flags, size, crtime, ctime, atime,
-        mtime, meta_mode, gid, uid, fullpath.c_str());
-    char *errmsg;
-    if (sqlite3_exec(m_db, stmt, NULL, NULL, &errmsg) != SQLITE_OK) 
-    {
-        std::ostringstream msg;
-        msg << msgPrefix << "Error adding data to files table: " << errmsg;
-        LOGERROR(msg.str());
-
-        sqlite3_free(errmsg);
-        return -1;
-    }
-
-    // Get the file_id from the last insert.
-    fileID = sqlite3_last_insert_rowid(m_db);
-
-    // Insert into the fs_files table.
-    sqlite3_snprintf(4096, stmt,
-        "INSERT INTO fs_files (file_id, fs_id, fs_file_id, attr_type, attr_id) VALUES (%llu,%d,%"
-        PRIuINUM ",%d,%d)", fileID, fileSystemID, fileSystemFile->name->meta_addr, fileSystemAttrType, fileSystemAttrID);
-
-    if (sqlite3_exec(m_db, stmt, NULL, NULL, &errmsg) != SQLITE_OK) 
-    {
-        std::ostringstream msg;
-        msg << msgPrefix << "Error adding data to fs_files table: " << errmsg;
-        LOGERROR(msg.str());
-
-        sqlite3_free(errmsg);
-        return -1;
-    }
-
-    //if dir, update parent id cache
-    if (meta_type == TSK_FS_META_TYPE_DIR) {
-        storeParObjId(fileSystemID, fileSystemFile->name->meta_addr, fileID);
-    }
-
-    return 0;
-}
-
-/**
- * Add block info to the database.  This table stores the run information for each file so that we
- * can map which blocks are used by what files.
- * @param a_fsId Id that the file is located in
- * @param a_fileId ID of the file
- * @param a_sequence The sequence number of this run in the file (0 for the first run, 1 for the second run, etc.)
- * @param a_blk_addr Block address (the address that the file system uses -- NOT the physical sector addr)
- * @param a_len The number of blocks in the run
- * @returns 1 on error
- */
-int TskImgDBSqlite::addFsBlockInfo(int a_fsId, uint64_t a_fileId, int a_sequence, uint64_t a_blk_addr, uint64_t a_len)
-{
-    std::stringstream stmt;
-    char * errmsg;
-
-    if (!m_db)
-        return 1;
-
-    stmt <<
-        "INSERT INTO fs_blocks (fs_id, file_id, seq, blk_start, blk_len) VALUES (" <<
-        a_fsId << "," << a_fileId << "," << a_sequence << "," << a_blk_addr << "," <<  a_len << ")";
-
-    if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::addFsBlockInfo - Error adding data to fs_blocks table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    return 0;
-}
-
-int TskImgDBSqlite::addAllocUnallocMapInfo(int a_volID, int unallocImgID, 
-                                           uint64_t unallocImgStart, uint64_t length, uint64_t origImgStart)
-{
-    std::stringstream stmt;
-    char * errmsg;
-
-    if (!m_db)
-        return 1;
-
-    stmt <<
-        "INSERT INTO alloc_unalloc_map (vol_id, unalloc_img_id, unalloc_img_sect_start, "
-        "sect_len, orig_img_sect_start) VALUES (" <<
-        a_volID << "," << unallocImgID << "," << 
-        unallocImgStart << "," << length << "," <<  origImgStart << ")";
-
-    if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::addAllocUnallocMapInfo - Error adding data to alloc_unalloc_map table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    return 0;
-}
-
-/**
- * Get information on all of the free sectors in an image.
- *
- * @return Info on unallocated runs (or NULL on error).  Caller must free this when done.
- */
-SectorRuns * TskImgDBSqlite::getFreeSectors() const
-{
-    std::stringstream infoMessage;
-    std::stringstream msg;
-
-    if (!m_db)
-        return NULL;
-
-    SectorRuns * sr = new SectorRuns();
-
-    LOGINFO("TskImgDBSqlite::getFreeSectors - Identifying Unallocated Sectors");
-
-    sqlite3_stmt * statement;
-
-    /********** FIND the unallocated volumes *************/
-    if (sqlite3_prepare_v2(m_db,
-        "SELECT vol_id, sect_start, sect_len, flags FROM vol_info;",
-        -1, &statement, 0) == SQLITE_OK) {
-            while(true) {
-                int result = sqlite3_step(statement);
-                if (result == SQLITE_ROW) {
-                    int flags = sqlite3_column_int(statement, 3);
-
-                    int vol_id = sqlite3_column_int(statement,0);
-                    int64_t start = sqlite3_column_int64(statement,1);
-                    int64_t len = sqlite3_column_int64(statement,2);
-
-                    // add the unallocated volumes
-                    if (flags & TSK_VS_PART_FLAG_UNALLOC) {
-                        sr->addRun(start, len, vol_id);
-                    }
-                    // add the allocated volumes that don't have a known file system
-                    else {
-                        std::stringstream stmt;
-                        sqlite3_stmt *statement2;
-                        stmt << "SELECT fs_id FROM fs_info WHERE vol_id = " << vol_id << ";";
-                        if (sqlite3_prepare_v2(m_db, stmt.str().c_str() , -1, &statement2, 0) == SQLITE_OK) {
-                            if (sqlite3_step(statement2) != SQLITE_ROW) {
-                                sr->addRun(start, len, vol_id);
-                            }
-                            sqlite3_finalize(statement2);
-                        }
-                    }
-                }
-                else {
-                    break;  
-                }
-            }
-            sqlite3_finalize(statement);
-    }
-    else {
-        infoMessage << "TskImgDBSqlite::getFreeSectors - Error querying vol_info table: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-
-        return NULL;
-    }
-
-    /*************** Find the unallocated blocks in each file system *************/
-    // @@@ Need to make more dynamic
-    int blk_size[32];
-    memset(blk_size, 0, sizeof(blk_size));
-    uint64_t blk_count[32];
-    memset(blk_count, 0, sizeof(blk_count));
-    int vol_id[32];
-    uint64_t img_offset[32];
-
-    // get basic info on each file system
-    if (sqlite3_prepare_v2(m_db, "SELECT fs_id, vol_id, img_byte_offset, block_size, block_count FROM fs_info;", -1, &statement, 0) == SQLITE_OK) {
-        LOGINFO("TskImgDBSqlite::getFreeSectors - START LOOP: Find the unallocated blocks in each file system.");
-        while(true)
-        {
-            int result = sqlite3_step(statement);
-            if (result == SQLITE_ROW)
-            {
-                int fs_id = sqlite3_column_int(statement, 0);
-                if (fs_id > 32)
-                {
-                    infoMessage.str("");
-                    infoMessage << "TskImgDBSqlite::getFreeSectors - fs_id in fs_info is bigger than 32: " << fs_id;
-                    LOGERROR(infoMessage.str());
-                    break;
-                }
-                vol_id[fs_id] = sqlite3_column_int(statement, 1);
-                img_offset[fs_id] = sqlite3_column_int64(statement, 2) / 512;
-                blk_size[fs_id] = sqlite3_column_int(statement, 3) / 512;
-                blk_count[fs_id] = sqlite3_column_int64(statement, 4);
-                // Debug Info
-                msg.str("");
-                msg << "TskImgDBSqlite::getFreeSectors - fs_id=" << fs_id << " vol_id=" << vol_id[fs_id] << " img_offset=" << img_offset[fs_id] << " blk_size=" << blk_size[fs_id] <<
-                    " blk_count=" << blk_count[fs_id];
-                LOGINFO(msg.str().c_str());
-            }
-            else
-            {
-                break;
-            }
-        }
-        sqlite3_finalize(statement);
-        LOGINFO("TskImgDBSqlite::getFreeSectors - DONE: Find the unallocated blocks in each file system.");
-    }
-    else
-    {
-        infoMessage.str("");
-        infoMessage << "TskImgDBSqlite::getFreeSectors - Error querying fs_info table: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-
-        return NULL;
-    }
-
-    // see what blocks have been used and add them to a list
-    TSK_LIST *seen[32];
-    memset(seen, 0, 32*sizeof(TSK_LIST *));
-
-    if (sqlite3_prepare_v2(m_db, "SELECT fs_id, file_id, blk_start, blk_len FROM fs_blocks;", -1, &statement, 0) == SQLITE_OK) {
-        LOGINFO("TskImgDBSqlite::getFreeSectors - START LOOP: see what blocks have been used and add them to a list.");
-        while(true) {
-            int result = sqlite3_step(statement);
-            if (result == SQLITE_ROW) {
-                int fs_id = sqlite3_column_int(statement, 0);
-                if (fs_id > 32) {
-                    infoMessage.str("");
-                    infoMessage << "TskImgDBSqlite::getFreeSectors - fs_id in fs_info is bigger than 32: " << fs_id;
-                    LOGERROR(infoMessage.str());
-                    continue;
-                }
-                uint64_t file_id = (uint64_t)sqlite3_column_int64(statement, 1);
-                int64_t addr = sqlite3_column_int64(statement, 2);
-                int64_t len = sqlite3_column_int64(statement, 3);
-
-                // We only want to consider the runs for files that we allocated.
-                std::stringstream stmt;
-                stmt << "SELECT meta_flags from files WHERE file_id=" << file_id;
-
-                sqlite3_stmt * statement2;
-                if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement2, 0) != SQLITE_OK) {
-                    infoMessage.str("");
-                    infoMessage << "TskImgDBSqlite::getFreeSectors - error finding flags for file " << file_id;
-                    LOGERROR(infoMessage.str());
-                    continue;
-                }
-                sqlite3_step(statement2);
-                int flags = sqlite3_column_int(statement2, 0);
-                sqlite3_finalize(statement2);
-
-                if (flags & TSK_FS_META_FLAG_UNALLOC)
-                    continue;
-
-                // @@@ We can probably find a more effecient storage method than this...
-                int error = 0;
-                for (int64_t i = 0; i < len; i++) {
-                    if (tsk_list_add(&seen[fs_id], addr+i)) {
-                        infoMessage.str("");
-                        infoMessage << "TskImgDBSqlite::getFreeSectors - Error adding seen block address to list";
-                        LOGERROR(infoMessage.str());
-
-                        error = 1;
-                        break;
-                    }
-                }
-                if (error)
-                    break;
-            }
-            else {
-                break;
-            }
-        }
-        sqlite3_finalize(statement);
-        LOGINFO("TskImgDBSqlite::getFreeSectors - DONE: see what blocks have been used and add them to a list.");
-    }
-    else {
-        infoMessage.str("");
-        infoMessage << "TskImgDBSqlite::getFreeSectors - Error querying fs_block table: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-
-        return NULL;
-    }
-
-    // cycle through each file system to find the unused blocks
-    LOGINFO("TskImgDBSqlite::getFreeSectors - START LOOP: cycle through each file system to find the unused blocks.");
-    for (int f = 0; f < 32; f++) {
-        if (blk_count[f] == 0)
-            continue;
-
-        uint64_t st = 0;
-        int len = 0;
-        // we previously adjusted blk_size and img_offset to be in sectors
-
-        msg.str("");
-        msg << "blk_count[" << f << "]=" << blk_count[f];
-        LOGINFO(msg.str().c_str());
-
-        for (uint64_t a = 0; a < blk_count[f]; a++) {
-            // see if this addr was used in a file
-            if (tsk_list_find(seen[f], a) == 0) {
-                // we already have a run being defined
-                if (len) {
-                    // same run, so add on to it
-                    if (st + len == a) {
-                        len++;
-                    }
-                    // different run, make a new one
-                    else {
-                        sr->addRun(img_offset[f]+st*blk_size[f], len*blk_size[f], vol_id[f]);
-                        st = a;
-                        len = 1;
-                    }
-                }
-                // start a new run
-                else {
-                    st = a;
-                    len = 1;
-                }
-            }
-        }
-        // add the final run
-        if (len) {
-            sr->addRun(img_offset[f]+st*blk_size[f], len*blk_size[f], vol_id[f]);
-        }
-        tsk_list_free(seen[f]);
-        seen[f] = NULL;
-    }
-    LOGINFO("TskImgDBSqlite::getFreeSectors - DONE: cycle through each file system to find the unused blocks.");
-
-    return sr;
-}
-
-std::string TskImgDBSqlite::getImageBaseName() const
-{
-    // There may be multiple file paths if the image is a split image. Oreder by sequence number to extract the file name from the first path.
-    sqlite3_stmt *statement;
-    executeStatement("SELECT name FROM image_names ORDER BY seq;", statement, "TskImgDBSqlite::getImageBaseName");
-
-    int result = sqlite3_step(statement);
-    if (result == SQLITE_ROW) 
-    {
-        Poco::Path imagePath(reinterpret_cast<const char*>(sqlite3_column_text(statement, 0))); // Reinterpret from const unsigned char*
-        return imagePath.getFileName();
-    }
-    else
-    {
-        return "";
-    }
-}
-
-std::vector<std::wstring> TskImgDBSqlite::getImageNamesW() const
-{
-    std::vector<std::wstring> imgList;
-
-    if (!m_db)
-        return imgList;
-
-    sqlite3_stmt *statement;
-
-    if (sqlite3_prepare_v2(m_db, "SELECT name FROM image_names ORDER BY seq;",
-        -1, &statement, 0) == SQLITE_OK) 
-    {
-        while(true)
-        {
-            int result = sqlite3_step(statement);
-            if (result == SQLITE_ROW) {
-                imgList.push_back((wchar_t *)sqlite3_column_text16(statement, 0));
-            }
-            else {
-                break;
-            }
-        }
-
-        sqlite3_finalize(statement);
-    }
-
-    return imgList;
-}
-
-
-std::vector<std::string> TskImgDBSqlite::getImageNames() const
-{
-    std::vector<std::string> imgList;
-
-    if (!m_db)
-        return imgList;
-
-    sqlite3_stmt *statement;
-
-    if (sqlite3_prepare_v2(m_db, "SELECT name FROM image_names ORDER BY seq;",
-        -1, &statement, 0) == SQLITE_OK) 
-    {
-        while(true)
-        {
-            int result = sqlite3_step(statement);
-            if (result == SQLITE_ROW) {
-                imgList.push_back((char *)sqlite3_column_text(statement, 0));
-            }
-            else {
-                break;
-            }
-        }
-
-        sqlite3_finalize(statement);
-    }
-
-    return imgList;
-}
-
-
-
-
-/**
- * @param a_fileId  File id to get information about
- * @param a_fsOffset Byte offset of start of file system that the file is located in
- * @param a_fsFileId File system-specific id of the file
- * @param a_attrType Type of attribute for this file
- * @param a_attrId The ID of the attribute for this file
- * @returns -1 on error
- */
-int TskImgDBSqlite::getFileUniqueIdentifiers(uint64_t a_fileId, uint64_t &a_fsOffset, uint64_t &a_fsFileId, int &a_attrType, int &a_attrId) const
-{
-    if (!m_db)
-        return -1;
-
-    sqlite3_stmt * statement;
-    std::stringstream stmt;
-
-    stmt <<
-        "SELECT fs_file_id, attr_type, attr_id, fs_info.img_byte_offset "
-        "FROM fs_files, fs_info WHERE file_id=" << a_fileId << " AND fs_info.fs_id = fs_files.fs_id;";
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        int result = sqlite3_step(statement);
-        if (result == SQLITE_ROW) {
-            a_fsFileId = sqlite3_column_int64(statement, 0);
-            a_attrType = sqlite3_column_int(statement, 1);
-            a_attrId = sqlite3_column_int(statement, 2);
-            a_fsOffset = sqlite3_column_int64(statement, 3);
-        }
-        else {
-            return -1;
-        }
-        sqlite3_finalize(statement);
-    }
-    else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getFileUniqueIdentifiers - Error querying fs_files table : " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-        return -1;
-    }
-
-    return 0;
-}
-
-/**
- * Get number of volumes in image.
- * @return Number of volumes in image or -1 on error
- */
-int TskImgDBSqlite::getNumVolumes() const
-{
-    if (!m_db)
-        return 0;
-
-    int count = 0;
-    sqlite3_stmt * statement;
-
-    /********** Get the number of volumes *************/
-    if (sqlite3_prepare_v2(m_db, "SELECT count(*) from vol_info;", -1, &statement, 0) == SQLITE_OK) 
-    {
-        int result = sqlite3_step(statement);
-        if (result == SQLITE_ROW) 
-        {
-            count = (int)sqlite3_column_int(statement, 0);
-        }
-        sqlite3_finalize(statement);
-    }
-    else 
-    {
-        std::wstringstream msg;
-        msg << L"TskImgDBSqlite::getNumVolumes - Error querying vol_info table: " << sqlite3_errmsg(m_db);
-        LOGERROR(msg.str());
-
-        return -1;
-    }
-
-    return count;
-}
-/**
- * Get number of files in image.
- * @return Number of files in image or -1 on error
- */
-int TskImgDBSqlite::getNumFiles() const
-{
-    if (!m_db)
-        return 0;
-
-    std::string condition("");
-    return getFileCount(condition);
-}
-
-/**
- * @returns the session_id or -1 on error.
- */
-int TskImgDBSqlite::getSessionID() const
-{
-    if (!m_db)
-        return 0;
-
-    sqlite3_stmt * statement;
-    std::string stmt("SELECT version from db_info WHERE name=\"SID\";");
-    int sessionId = -1;
-
-    /********** FIND the unallocated volumes *************/
-    if (sqlite3_prepare_v2(m_db, stmt.c_str(), -1, &statement, 0) == SQLITE_OK) {
-        int result = sqlite3_step(statement);
-        if (result == SQLITE_ROW) {
-            sessionId = (int)sqlite3_column_int(statement, 0);
-        }
-        sqlite3_finalize(statement);
-    }
-    else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getSessionID - Error querying db_info table for Session ID: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-
-        return -1;
-    }
-    return sessionId;
-}
-
-int TskImgDBSqlite::begin()
-{
-    char *errmsg;
-    if (!m_db)
-        return 1;
-
-    if (sqlite3_exec(m_db, "BEGIN", NULL, NULL, &errmsg) != SQLITE_OK) {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::begin - BEGIN Error: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-    return 0;
-}
-
-int TskImgDBSqlite::commit()
-{
-    char *errmsg;
-    if (!m_db)
-        return 1;
-
-    if (sqlite3_exec(m_db, "COMMIT", NULL, NULL, &errmsg) != SQLITE_OK) {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::commit - COMMIT Error: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return 1;
-    }
-    return 0;
-}
-
-UnallocRun * TskImgDBSqlite::getUnallocRun(int a_unalloc_img_id, int a_file_offset) const
-{
-    std::stringstream stmt;
-    char * errmsg;
-    if (!m_db)
-        return NULL;
-
-    stmt << "SELECT vol_id, unalloc_img_sect_start, sect_len, orig_img_sect_start FROM "
-        "alloc_unalloc_map WHERE unalloc_img_id = " << a_unalloc_img_id << 
-        " AND unalloc_img_sect_start <= " << a_file_offset << " ORDER BY unalloc_img_sect_start DESC";
-
-    char **result;
-    int nrow, ncol;
-    if (sqlite3_get_table(m_db, stmt.str().c_str(), &result, &nrow, &ncol, &errmsg) != SQLITE_OK)
-    {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getUnallocRun - Error fetching data from alloc_unalloc_map table: " << errmsg;
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-
-        return new UnallocRun(-1, -1, -1, -1, -1);
-    }
-    else
-    {
-        int vol_id;
-        int unalloc_img_sect_start;
-        int sect_len;
-        int orig_img_sect_start;
-        // skip the headers
-        // @@@ DO SOME ERROR CHECKING HERE to make sure that results has data...
-        sscanf(result[4], "%d", &vol_id);
-        sscanf(result[5], "%d", &unalloc_img_sect_start);
-        sscanf(result[6], "%d", &sect_len);
-        sscanf(result[7], "%d", &orig_img_sect_start);
-        sqlite3_free_table(result);
-        return new UnallocRun(vol_id, a_unalloc_img_id, unalloc_img_sect_start, sect_len, orig_img_sect_start);
-    }
-}
-
-/**
- * Adds information about a carved file into the database.  This includes the sector layout
- * information. 
- * 
- * @param vol_id Volume in which the carved file was found in
- * @param name Name of the file 
- * @param size Number of bytes in file
- * @param runStarts Array with starting sector (relative to start of image) for each run in file.
- * @param runLengths Array with number of sectors in each run 
- * @param numRuns Number of entries in previous arrays
- * @param fileId Carved file Id (output)
- * @returns 0 on success or -1 on error.
- */
-int TskImgDBSqlite::addCarvedFileInfo(int vol_id, const char *name, uint64_t size, 
-                                      uint64_t *runStarts, uint64_t *runLengths, int numRuns, uint64_t & fileId)
-{
-    char stmt[1024];
-    char * errmsg;
-    std::wstringstream infoMessage;
-
-    if (!m_db)
-        return -1;
-
-    // insert into files table
-    sqlite3_snprintf(1024, stmt,
-        "INSERT INTO files (file_id, type_id, name, par_file_id, dir_type, meta_type,"
-        "dir_flags, meta_flags, size, ctime, crtime, atime, mtime, mode, uid, gid, status, full_path) "
-        "VALUES (NULL, %d, '%q', NULL, %d, %d, %d, %d, %llu, 0, 0, 0, 0, NULL, NULL, NULL, %d, '%q')",
-        IMGDB_FILES_TYPE_CARVED, name, (int)TSK_FS_NAME_TYPE_REG, (int)TSK_FS_META_TYPE_REG,
-        (int)TSK_FS_NAME_FLAG_UNALLOC, (int)TSK_FS_META_FLAG_UNALLOC, size, IMGDB_FILES_STATUS_CREATED, name);
-    // MAY-118 NOTE: addCarvedFileInfo insert entry into files table, but actual file on disk has not been created yet.
-    if (sqlite3_exec(m_db, stmt, NULL, NULL, &errmsg) != SQLITE_OK) {
-        infoMessage << L"TskImgDBSqlite::addCarvedFileInfo - Error adding data to file table for carved file: " << errmsg << L" " << stmt;
-
-        LOGERROR(infoMessage.str());
-
-        sqlite3_free(errmsg);
-        return -1;
-    }
-
-    // get the assigned file_id
-    fileId = (uint64_t)sqlite3_last_insert_rowid(m_db);
-
-    // insert into the carved_files_table
-    sqlite3_snprintf(1024, stmt, "INSERT INTO carved_files (file_id, vol_id)"
-        "VALUES (%llu, %d)", fileId, vol_id);
-    if (sqlite3_exec(m_db, stmt, NULL, NULL, &errmsg) != SQLITE_OK) {
-        infoMessage << L"TskImgDBSqlite::addCarvedFileInfo - Error adding data to carved_files table: " << errmsg;
-
-        LOGERROR(infoMessage.str());
-        sqlite3_free(errmsg);
-        return -1;
-    }
-
-    // insert into carved_sectors table
-    for (int i = 0; i < numRuns; i++)
-    {
-        sqlite3_snprintf(1023, stmt,
-            "INSERT INTO carved_sectors (file_id, seq, sect_start, sect_len) "
-            "VALUES (%llu, %d, %llu, %llu)",
-            fileId, i, runStarts[i], runLengths[i]);
-        if (sqlite3_exec(m_db, stmt, NULL, NULL, &errmsg) != SQLITE_OK) {
-            infoMessage << L"TskImgDBSqlite::addCarvedFileInfo - Error adding data to carved_sectors table: " << errmsg;
-
-            LOGERROR(infoMessage.str());
-
-            sqlite3_free(errmsg);
-            return -1;
-        }
-    }
-
-    return 0;
-}
-
-/**
- * Adds information about derived files to the database.  Derived files typically come
- * from archives and may be compressed.
- * 
- * @param name The name of the file.
- * @param parentId The id of the file from which this file is derived.
- * @param isDirectory True if entry is for a directory verus a file
- * @param size The size of the file.
- * @param details This is a string that may contain extra details related
- * to the particular type of mechanism that was used to derive this file, 
- * e.g. files derived from zip archives may have extra information about the
- * compressed size of the file.
- * @param ctime Time file system file entry was changed.
- * @param crtime Time the file was created.
- * @param atime Last access time.
- * @param mtime Last modified time.
- * @param fileId Reference to location where file_id for file can be assigned
- * @param path Path of file
- *
- * @returns 0 on success or -1 on error.
- */
-int TskImgDBSqlite::addDerivedFileInfo(const std::string& name, const uint64_t parentId, 
-                                       const bool isDirectory, const uint64_t size,
-                                       const std::string& details,
-                                       const int ctime, const int crtime, const int atime, const int mtime,
-                                       uint64_t &fileId, std::string path)
-{
-    if (!m_db)
-        return -1;
-
-    char stmt[1024];
-    char * errmsg;
-
-    TSK_FS_NAME_TYPE_ENUM dirType = isDirectory ? TSK_FS_NAME_TYPE_DIR : TSK_FS_NAME_TYPE_REG;
-    TSK_FS_META_TYPE_ENUM metaType = isDirectory ? TSK_FS_META_TYPE_DIR : TSK_FS_META_TYPE_REG;
-
-    // insert into files table
-    sqlite3_snprintf(1024, stmt,
-        "INSERT INTO files (file_id, type_id, name, par_file_id, dir_type, meta_type, size, ctime, crtime, atime, mtime, status, full_path) "
-        "VALUES (NULL, %d, '%q', %llu, %d, %d, %llu, %d, %d, %d, %d, %d, '%q')",
-        IMGDB_FILES_TYPE_DERIVED, name.c_str(), parentId, dirType, metaType, size, ctime, crtime, atime, mtime, IMGDB_FILES_STATUS_CREATED, path.c_str());
-
-    if (sqlite3_exec(m_db, stmt, NULL, NULL, &errmsg) != SQLITE_OK) 
-    {
-        std::wstringstream msg;
-        msg << L"TskImgDBSqlite::addDerivedFileInfo - Error adding data to file table for derived file: "
-            << errmsg << L" " << stmt;
-
-        LOGERROR(msg.str());
-
-        sqlite3_free(errmsg);
-        return -1;
-    }
-
-    // get the assigned file_id
-    fileId = sqlite3_last_insert_rowid(m_db);
-
-    // insert into the derived_files table
-    sqlite3_snprintf(1024, stmt, "INSERT INTO derived_files (file_id, derivation_details) "
-        "VALUES (%llu, '%q')", fileId, details.c_str());
-    if (sqlite3_exec(m_db, stmt, NULL, NULL, &errmsg) != SQLITE_OK) 
-    {
-        std::wstringstream msg;
-        msg << L"TskImgDBSqlite::addDerivedFileInfo - Error adding data to derived_files table : "
-            << errmsg;
-
-        LOGERROR(msg.str());
-        sqlite3_free(errmsg);
-        return -1;
-    }
-
-    return 0;
-}
-
-/**
- * Fills outBuffer with file IDs that match the name fileName.
- * Returns the number of file IDs written into outBuffer or -1 on error.
- */
-int TskImgDBSqlite::getFileIds(char *a_fileName, uint64_t *a_outBuffer, int a_buffSize) const
-{
-
-    if (!m_db)
-        return -1;
-
-    int outIdx = 0;
-
-    sqlite3_stmt * statement;
-    std::stringstream stmt;
-    stmt << "SELECT file_id FROM files WHERE name LIKE '" << a_fileName << "';";
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        while(sqlite3_step(statement) == SQLITE_ROW) {
-            a_outBuffer[outIdx++] = (uint64_t)sqlite3_column_int64(statement, 0);
-        }
-        sqlite3_finalize(statement);
-    }
-    else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getFileIds - Error querying files table : " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-        return -1;
-    }
-
-    return outIdx;
-}
-
-/*
- * Return the minimum file id with status = READY_FOR_ANALYSIS in minFileId.
- * Return 0 on success, -1 if failed.
- */
-int TskImgDBSqlite::getMinFileIdReadyForAnalysis(uint64_t & minFileId) const
-{
-    if (!m_db)
-        return -1;
-
-    minFileId = 0;
-
-    sqlite3_stmt * statement;
-    std::stringstream stmt;
-    stmt << "SELECT min(file_id) FROM files WHERE status = " << 
-        TskImgDB::IMGDB_FILES_STATUS_READY_FOR_ANALYSIS << ";";
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        int result = sqlite3_step(statement);
-        if (result == SQLITE_ROW) {
-            minFileId = (uint64_t)sqlite3_column_int64(statement, 0);
-        }
-        sqlite3_finalize(statement);
-    }
-    else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getMinFileIdReadyForAnalysis - Error querying files table : " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-        return -1;
-    }
-    return 0;
-}
-
-/**
- * Given the last file ID ready for analysis, find the largest file ID ready of analysis (in maxFileId)
- * Returns 0 on success or -1 on error.
- */
-int TskImgDBSqlite::getMaxFileIdReadyForAnalysis(uint64_t a_lastFileId, uint64_t & maxFileId) const
-{
-    if (!m_db)
-        return -1;
-
-    maxFileId = 0;
-
-    sqlite3_stmt * statement;
-    std::stringstream stmt;
-    stmt << "SELECT max(file_id) FROM files WHERE status = " <<  
-        TskImgDB::IMGDB_FILES_STATUS_READY_FOR_ANALYSIS << 
-        " AND file_id >= " <<  a_lastFileId << ";";
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        int result = sqlite3_step(statement);
-        if (result == SQLITE_ROW) {
-            maxFileId = (uint64_t)sqlite3_column_int64(statement, 0);
-        }
-        sqlite3_finalize(statement);
-    }
-    else {
-        std::wstringstream infoMessage;
-        infoMessage <<  L"TskImgDBSqlite::getMaxFileIdReadyForAnalysis - Error querying files table : " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-        return -1;
-    }
-    return 0;
-}
-
-SectorRuns * TskImgDBSqlite::getFileSectors(uint64_t a_fileId) const
-{
-    if (!m_db)
-        return NULL;
-
-    SectorRuns * sr = new SectorRuns();
-
-    sqlite3_stmt * statement;
-    std::stringstream stmt;
-    int srCount = 0;
-    stmt <<
-        "SELECT fs_blocks.blk_start, fs_blocks.blk_len, "
-        "fs_info.block_size, fs_info.img_byte_offset, fs_info.vol_id "
-        "FROM files "
-        "JOIN fs_files ON files.file_id = fs_files.file_id "
-        "JOIN fs_blocks ON files.file_id = fs_blocks.file_id "
-        "JOIN fs_info ON fs_blocks.fs_id = fs_info.fs_id "
-        "WHERE files.file_id = " << a_fileId << " "
-        "ORDER BY fs_blocks.seq;";
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        while(sqlite3_step(statement) == SQLITE_ROW) {
-            uint64_t blkStart = (uint64_t)sqlite3_column_int64(statement, 0);
-            uint64_t blkLength = (uint64_t)sqlite3_column_int64(statement, 1);
-            int blkSize = sqlite3_column_int(statement, 2);
-            uint64_t imgByteOffset = (uint64_t)sqlite3_column_int64(statement, 3);
-            int volId = sqlite3_column_int(statement, 4);
-
-            uint64_t start = (imgByteOffset + blkStart * blkSize) / 512;
-            uint64_t len = (blkLength * blkSize) / 512;
-
-            sr->addRun(start, len, volId);
-            srCount++;
-        }
-
-        sqlite3_finalize(statement);
-    }
-    else {
-        std::wstringstream infoMessage;
-        infoMessage <<
-            L"TskImgDBSqlite::getFileSectors - "
-            L"Error finding block data for file_id=" << a_fileId << ": " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-        return NULL;
-    }
-
-    if (srCount < 1) {
-        delete sr;
-        sr = NULL;
-    }
-    return sr;
-}
-
-/**
- * This callback mechanism is registered with SQLite and is 
- * called whenever an operation would result in SQLITE_BUSY.
- * Each time this method is called we will back off IMGDB_RETRY_WAIT
- * x count milliseconds. A non zero return value tells SQLite to 
- * retry the statement and a zero return value tells SQLite to 
- * stop retrying, in which case it will return SQLITE_BUSY or
- * SQLITE_IOERR_BLOCKED to the caller.
- *
- * @param pDB - a pointer to the sqlite3 structure
- * @param count - the number of times this handler has been
- * called for this blocking event.
- */
-int TskImgDBSqlite::busyHandler(void * pDB, int count)
-{
-    if (count < IMGDB_MAX_RETRY_COUNT)
-    {
-        Poco::Thread::sleep(IMGDB_RETRY_WAIT * count);
-        return 1;
-    }
-
-    return 0;
-}
-
-
-
-int TskImgDBSqlite::updateFileStatus(uint64_t a_file_id, FILE_STATUS a_status)
-{
-    if (!m_db)
-        return 1;
-
-    std::stringstream stmt;
-    char * errmsg;
-
-    stmt << "UPDATE files SET status = " << a_status << " WHERE file_id = " << a_file_id << ";";
-    if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::updateFileStatus - Error UPDATE file status: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-        return 1;
-    }
-
-    return 0;
-}
-
-
-int TskImgDBSqlite::updateKnownStatus(uint64_t a_file_id, KNOWN_STATUS a_status)
-{
-    if (!m_db)
-        return 1;
-
-    std::stringstream stmt;
-    char * errmsg;
-
-    stmt << "UPDATE file_hashes SET known = " << a_status << " WHERE file_id = " << a_file_id << ";";
-    if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::updateFileStatus - Error UPDATE file status: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-        return 1;
-    }
-
-    return 0;
-}
-
-bool TskImgDBSqlite::dbExist() const
-{
-    if (m_db)
-        return true;
-    else
-        return false;
-}
-
-void TskImgDBSqlite::getCarvedFileInfo(const std::string& stmt, std::map<uint64_t, std::string>& results) const
-{
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.c_str(), -1, &statement, 0) == SQLITE_OK) 
-    {
-        while (sqlite3_step(statement) == SQLITE_ROW) 
-        {
-            uint64_t fileId = (uint64_t)sqlite3_column_int64(statement, 0);
-            std::string fileName = (char*)sqlite3_column_text(statement, 1);
-            std::string cfileName = (char*)sqlite3_column_text(statement, 2);
-
-            // Grab the extension and append it to the cfile name
-            std::string::size_type pos = fileName.rfind('.');
-            if (pos != std::string::npos)
-                cfileName.append(fileName.substr(pos));
-
-            results[fileId] = cfileName;
-        }
-        sqlite3_finalize(statement);
-    } else 
-    {
-        std::wstringstream msg;
-        msg << L"TskImgDBSqlite::getCarvedFileInfo - Error retrieving carved file details: "
-            << sqlite3_errmsg(m_db);
-        LOGERROR(msg.str());
-    }
-}
-
-std::map<uint64_t, std::string> TskImgDBSqlite::getUniqueCarvedFiles(HASH_TYPE hashType) const
-{
-    if (!m_db)
-        throw TskException("No database.");
-
-    std::map<uint64_t, std::string> results;
-
-    string hash;
-    switch (hashType) {
-    case TskImgDB::MD5:
-        hash = "md5";
-        break;
-    case TskImgDB::SHA1:
-        hash = "sha1";
-        break;
-    case TskImgDB::SHA2_256:
-        hash = "sha2_256";
-        break;
-    case TskImgDB::SHA2_512:
-        hash = "sha2_512";
-        break;
-    default:
-        std::wstringstream msg;
-        msg << L"TskImgDBSqlite::getUniqueCarvedFiles - Unsupported hashType : " << hashType;
-        LOGERROR(msg.str());
-        return results;
-    }
-
-    stringstream stmt;
-    
-    // If hashes have not been calculated return all carved files
-    stmt << "SELECT count(*) FROM file_hashes;";
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) 
-    {
-        if (sqlite3_step(statement) == SQLITE_ROW) 
-        {
-            uint64_t counter = (uint64_t)sqlite3_column_int64(statement, 0);
-            if (counter == 0) 
-            {
-                sqlite3_finalize(statement);
-                stmt.str("");
-                stmt << "select c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' "
-                    << "|| c.file_id from files f, carved_files c, carved_sectors cs "
-                    << "where c.file_id = cs.file_id and cs.seq = 0 and f.file_id = c.file_id order by c.file_id";
-                getCarvedFileInfo(stmt.str(), results);
-                return results;
-            }
-        }
-        sqlite3_finalize(statement);
-    } else 
-    {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getUniqueCarvedFiles - Error getting file_hashes count: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-    }
-
-    stmt.str("");
-
-    // Get the set of files for which the hash has been calculated.
-    stmt << "select c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' "
-        << "|| c.file_id from files f, carved_files c, carved_sectors cs "
-        << "where c.file_id = cs.file_id and cs.seq = 0 and f.file_id = c.file_id and c.file_id in "
-        << "(select min(file_id) from file_hashes where " << hash << " != '' group by " << hash << ") order by c.file_id";
-
-    getCarvedFileInfo(stmt.str(), results);
-
-    // Next get the set of files for which the hash has *not* been calculated.
-    stmt.str("");
-
-    stmt << "select c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' "
-        << "|| c.file_id from files f, carved_files c, carved_sectors cs "
-        << "where c.file_id = cs.file_id and cs.seq = 0 and f.file_id = c.file_id and c.file_id in "
-        << "(select file_id from file_hashes where " << hash << " = '') order by c.file_id";
-
-    getCarvedFileInfo(stmt.str(), results);
-
-    // Finally, add file info for all of the carved files for which there are no hashes of any sort.
-    // All of these files must be included because without hashes there is no way to determine uniqueness.
-    stmt.clear();
-    stmt.str("");
-    stmt << "SELECT c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || c.file_id "
-         << "FROM files f, carved_files c, carved_sectors cs "
-         << "WHERE c.file_id = cs.file_id AND cs.seq = 0 AND f.file_id = c.file_id AND c.file_id NOT IN "
-         << "(SELECT fh.file_id FROM file_hashes fh) ORDER BY c.file_id";
-    getCarvedFileInfo(stmt.str(), results);
-
-    return results;
-}
-
-void TskImgDBSqlite::getCarvedFileInfo(const std::string &query, bool getHash, std::vector<TskCarvedFileInfo> &carvedFileInfos) const
-{
-    sqlite3_stmt *statement;
-    executeStatement(query, statement, "TskImgDBSqlite::getCarvedFileInfo");
-
-    TskCarvedFileInfo info;
-    while (sqlite3_step(statement) == SQLITE_ROW) 
-    {
-        info.fileID = static_cast<uint64_t>(sqlite3_column_int64(statement, 0));
-        std::string fileName = reinterpret_cast<const char*>(sqlite3_column_text(statement, 1)); // Reinterpret from unsigned Char*
-        info.cFileName = reinterpret_cast<const char*>(sqlite3_column_text(statement, 2)); // Reinterpret from unsigned Char*
-        if (getHash)
-        {
-            info.hash = reinterpret_cast<const char*>(sqlite3_column_text(statement, 3));
-        }
-
-        // Append the extension from the original file name to the constructed "cfile" name.
-        std::string::size_type pos = fileName.rfind('.');
-        if (pos != std::string::npos)
-        {
-            info.cFileName.append(fileName.substr(pos));
-        }
-
-        carvedFileInfos.push_back(info);
-    }
-
-    sqlite3_finalize(statement);
-}
-
-std::vector<TskCarvedFileInfo> TskImgDBSqlite::getUniqueCarvedFilesInfo(HASH_TYPE hashType) const
-{
-    const std::string msgPrefix = "TskImgDBSqlite::getUniqueCarvedFilesInfo : "; 
-
-    if (!m_db)
-    {
-        std::ostringstream msg;
-        msg << msgPrefix << "no database connection";
-        throw TskException(msg.str());
-    }
-
-    // Map the requested hash type to a file_hashes table column name.
-    string hash;
-    switch (hashType) 
-    {
-    case TskImgDB::MD5:
-        hash = "md5";
-        break;
-    case TskImgDB::SHA1:
-        hash = "sha1";
-        break;
-    case TskImgDB::SHA2_256:
-        hash = "sha2_256";
-        break;
-    case TskImgDB::SHA2_512:
-        hash = "sha2_512";
-        break;
-    default:
-        std::ostringstream msg;
-        msg << msgPrefix << "unsupported hash type :" << hashType;
-        throw TskException(msg.str());
-    }
-
-    std::vector<TskCarvedFileInfo> carvedFileInfos;
-
-    // Do a quick check to see if any hashes have been calculated.
-    std::ostringstream query;
-    query << "SELECT COUNT(*) FROM file_hashes;";
-    sqlite3_stmt *countStmt;
-    executeStatement(query.str(), countStmt, "TskImgDBSqlite::getUniqueCarvedFiles");
-    if (sqlite3_step(countStmt) == SQLITE_ROW && static_cast<uint64_t>(sqlite3_column_int64(countStmt, 0)) != 0) 
-    {
-        // At least one type of hash has been calculated (presumably for all files, but this is not guaranteed). 
-        // First, add file info for the set of unique files among the carved files for which the specified type of hash is available.
-        query.clear();
-        query.str("");
-        query << "SELECT c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || c.file_id, fh." << hash << " "
-              << "FROM files f, carved_files c, carved_sectors cs, file_hashes fh "
-              << "WHERE c.file_id = cs.file_id AND cs.seq = 0 AND f.file_id = c.file_id AND c.file_id = fh.file_id AND c.file_id IN "
-              << "(SELECT MIN(file_id) FROM file_hashes WHERE " << hash << " != '' GROUP BY " << hash << ") ORDER BY c.file_id";
-        getCarvedFileInfo(query.str(), true, carvedFileInfos);
-
-         // Next, add file info for all of the carved files for which the specified hash is not available.
-         // All of these files must be included because without the specified hash there is no acceptable way to determine uniqueness.
-        query.clear();
-        query.str("");
-        query << "SELECT c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || c.file_id "
-              << "FROM files f, carved_files c, carved_sectors cs "
-              << "WHERE c.file_id = cs.file_id AND cs.seq = 0 AND f.file_id = c.file_id AND c.file_id IN "
-              << "(SELECT file_id FROM file_hashes WHERE " << hash << " = '') ORDER BY c.file_id";
-        getCarvedFileInfo(query.str(), false, carvedFileInfos);
-
-        // Finally, add file info for all of the carved files for which there are no hashes of any sort.
-        // All of these files must be included because without hashes there is no way to determine uniqueness.
-        query.clear();
-        query.str("");
-        query << "SELECT c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || c.file_id "
-              << "FROM files f, carved_files c, carved_sectors cs "
-              << "WHERE c.file_id = cs.file_id AND cs.seq = 0 AND f.file_id = c.file_id AND c.file_id NOT IN "
-              << "(SELECT fh.file_id FROM file_hashes fh) ORDER BY c.file_id";
-        getCarvedFileInfo(query.str(), false, carvedFileInfos);
-    }
-    else
-    {
-        // No hashes have been calculated.
-        // Return carved file info all of the carved files because without hashes there is no way to determine uniqueness.
-        query.clear();
-        query.str("");
-        query << "SELECT c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || c.file_id "
-              << "FROM files f, carved_files c, carved_sectors cs "
-              << "WHERE c.file_id = cs.file_id AND cs.seq = 0 AND f.file_id = c.file_id ORDER BY c.file_id";
-        getCarvedFileInfo(query.str(), false, carvedFileInfos);
-
-        std::ostringstream msg;
-        msg << msgPrefix << "no hashes available, returning all carved files";
-        LOGWARN(msg.str());
-    }
-    sqlite3_finalize(countStmt);
-
-    return carvedFileInfos;
-}
-
-std::vector<uint64_t> TskImgDBSqlite::getCarvedFileIds() const
-{
-    return getFileIdsWorker("carved_files");
-}
-
-std::vector<uint64_t> TskImgDBSqlite::getUniqueFileIds(HASH_TYPE hashType) const
-{
-    if (!m_db)
-        throw TskException("No database.");
-
-    std::vector<uint64_t> results;
-
-    string hash;
-    switch (hashType) {
-    case TskImgDB::MD5:
-        hash = "md5";
-        break;
-    case TskImgDB::SHA1:
-        hash = "sha1";
-        break;
-    case TskImgDB::SHA2_256:
-        hash = "sha2_256";
-        break;
-    case TskImgDB::SHA2_512:
-        hash = "sha2_512";
-        break;
-    default:
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBSqlite::getUniqueFileIds - Unsupported hashType : " << hashType ;
-        LOGERROR(errorMsg.str());
-        return results;
-    }
-
-    stringstream stmt;
-
-    stmt << "SELECT min(file_id) FROM file_hashes WHERE " << hash << " != '' group by " << hash ;
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        while (sqlite3_step(statement) == SQLITE_ROW) {
-            uint64_t fileId = (uint64_t)sqlite3_column_int64(statement, 0);
-            results.push_back(fileId);
-        }
-        sqlite3_finalize(statement);
-    } else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getUniqueFileIds - Error querying file_hashes table: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-    }
-    return results;
-}
-
-std::vector<uint64_t> TskImgDBSqlite::getFileIds() const
-{
-    return getFileIdsWorker("files");
-}
-
-std::vector<uint64_t> TskImgDBSqlite::getFileIdsWorker(std::string tableName, const std::string condition) const
-{
-    if (!m_db)
-        throw TskException("No database.");
-
-    std::vector<uint64_t> results;
-
-    stringstream stmt;
-
-    stmt << "SELECT file_id FROM " << tableName;
-    if (condition.compare("") != 0)
-        stmt << " WHERE " << condition;
-    stmt <<  " ORDER BY file_id";
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        while (sqlite3_step(statement) == SQLITE_ROW) {
-            uint64_t fileId = (uint64_t)sqlite3_column_int64(statement, 0);
-            results.push_back(fileId);
-        }
-        sqlite3_finalize(statement);
-    } else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getFileIdsWorker - Error getting file ids from table " << 
-            tableName.c_str() << ", " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-    }
-    return results;
-}
-
-/**
- * Get the list of file ids that match the given criteria.
- * The given string will be appended to "select files.file_id from files".
- * See \ref img_db_schema_v1_5_page for tables and columns to include in 
- * the selection criteria.
- *
- * @param condition Must be a valid SQL string defining the selection criteria.
- * @returns The collection of file ids matching the selection criteria. Throws
- * TskException if database not initialized.
- */
-std::vector<uint64_t> TskImgDBSqlite::getFileIds(const std::string& condition) const
-{
-    if (!m_db)
-        throw TskException("Database not initialized.");
-
-    std::vector<uint64_t> results;
-
-    std::string stmt("SELECT files.file_id FROM files");
-
-    constructStmt(stmt, condition);
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.c_str(), -1, &statement, 0) == SQLITE_OK) 
-    {
-        while (sqlite3_step(statement) == SQLITE_ROW) 
-        {
-            uint64_t fileId = (uint64_t)sqlite3_column_int64(statement, 0);
-            results.push_back(fileId);
-        }
-        sqlite3_finalize(statement);
-    } else 
-    {
-        std::wstringstream msg;
-        msg << L"TskImgDBSqlite::getFilesIds - Error getting file ids: " << sqlite3_errmsg(m_db);
-        LOGERROR(msg.str());
-    }
-    return results;
-}
-/*
- * Get the list of file records that match the given criteria.
- * The given string will be appended to "select ... from files".
- *
- * @param condition Must be a valid SQL string defining the selection criteria.
- * @returns The collection of file records matching the selection criteria. Throws
- * TskException if database not initialized.
- */
-const std::vector<TskFileRecord> TskImgDBSqlite::getFileRecords(const std::string& condition) const
-{
-    if (!m_db)
-        throw TskException("Database not initialized.");
-
-    std::vector<TskFileRecord> results;
-
-    std::stringstream stmtstrm;
-
-    stmtstrm << "SELECT f.file_id, f.type_id, f.name, f.par_file_id, f.dir_type, f.meta_type, f.dir_flags, "
-        << "f.meta_flags, f.size, f.ctime, f.crtime, f.atime, f.mtime, f.mode, f.uid, f.gid, f.status, f.full_path, "
-        << "fh.md5, fh.sha1, fh.sha2_256, fh.sha2_512 "
-        << "FROM files f LEFT OUTER JOIN file_hashes fh ON f.file_id = fh.file_id ";
-
-    std::string stmt = stmtstrm.str();
-    constructStmt(stmt, condition);
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.c_str(), -1, &statement, 0) == SQLITE_OK) 
-    {
-        while(sqlite3_step(statement) == SQLITE_ROW) {
-            TskFileRecord fileRecord;
-            fileRecord.fileId       = sqlite3_column_int64(statement, 0);
-            fileRecord.typeId       = (TskImgDB::FILE_TYPES) sqlite3_column_int(statement, 1);
-            fileRecord.name         = (char *)sqlite3_column_text(statement, 2);
-            fileRecord.parentFileId = sqlite3_column_int64(statement, 3);
-            fileRecord.dirType      = (TSK_FS_NAME_TYPE_ENUM) sqlite3_column_int(statement, 4);
-            fileRecord.metaType     = (TSK_FS_META_TYPE_ENUM) sqlite3_column_int(statement, 5);
-            fileRecord.dirFlags     = (TSK_FS_NAME_FLAG_ENUM) sqlite3_column_int(statement, 6);
-            fileRecord.metaFlags    = (TSK_FS_META_FLAG_ENUM) sqlite3_column_int(statement, 7);
-            fileRecord.size         = sqlite3_column_int64(statement, 8);
-            fileRecord.ctime        = sqlite3_column_int(statement, 9);
-            fileRecord.crtime       = sqlite3_column_int(statement, 10);
-            fileRecord.atime        = sqlite3_column_int(statement, 11);
-            fileRecord.mtime        = sqlite3_column_int(statement, 12);
-            fileRecord.mode         = (TSK_FS_META_MODE_ENUM) sqlite3_column_int(statement, 13);
-            fileRecord.uid          = sqlite3_column_int(statement, 14);
-            fileRecord.gid          = sqlite3_column_int(statement, 15);
-            fileRecord.status       = (TskImgDB::FILE_STATUS) sqlite3_column_int(statement, 16);
-            fileRecord.fullPath     = (char *)sqlite3_column_text(statement, 17);
-
-            if (sqlite3_column_type(statement, 18) == SQLITE_TEXT)
-                fileRecord.md5      = (char *)sqlite3_column_text(statement, 18);
-            if (sqlite3_column_type(statement, 19) == SQLITE_TEXT)
-                fileRecord.sha1     = (char *)sqlite3_column_text(statement, 19);
-            if (sqlite3_column_type(statement, 20) == SQLITE_TEXT)
-                fileRecord.sha2_256 = (char *)sqlite3_column_text(statement, 20);
-            if (sqlite3_column_type(statement, 21) == SQLITE_TEXT)
-                fileRecord.sha2_512 = (char *)sqlite3_column_text(statement, 21);
-            results.push_back(fileRecord);
-        }
-    }
-    else 
-    {
-        std::wstringstream msg;
-        msg << L"TskImgDBSqlite::getFilesRecords - Error getting file reocrds: " << sqlite3_errmsg(m_db);
-        LOGERROR(msg.str());
-    }
-    return results;
-}
-
-
-/**
- * Get the number of files that match the given criteria.
- * The given string will be appended to "select files.file_id from files".
- *
- * @param condition Must be a valid SQL string defining the selection criteria.
- * @returns The number of files matching the selection criteria. 
- */
-int TskImgDBSqlite::getFileCount(const std::string& condition) const
-{
-    if (!m_db)
-        throw TskException("Database not initialized.");
-
-    int result = 0;
-
-    std::string stmt("SELECT COUNT(files.file_id) FROM files");
-
-    constructStmt(stmt, condition);
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.c_str(), -1, &statement, 0) == SQLITE_OK) 
-    {
-        while (sqlite3_step(statement) == SQLITE_ROW) 
-        {
-            result = (uint64_t)sqlite3_column_int(statement, 0);
-        }
-        sqlite3_finalize(statement);
-    } else 
-    {
-        std::wstringstream msg;
-        msg << L"TskImgDBSqlite::getFileCount - Error getting file count: " << sqlite3_errmsg(m_db);
-        LOGERROR(msg.str());
-    }
-    return result;
-}
-
-int tsk_strnicmp(const char *s1, const char *s2, size_t N)
-{
-    if (N == 0)
-        return 0;
-    int diff = 0;
-    if (s1 && s2) {
-        while (N-- > 0 && (diff = (toupper(*s1) - toupper(*s2))) == 0 && *s1 && *s2) {
-            s1++;
-            s2++;
-        }
-    }
-    else if (s1)
-        return +1;
-    else if (s2)
-        return -1;
-    return diff;
-}
-
-/* Append condition to stmt to make a single SQL query.
- */
-void TskImgDBSqlite::constructStmt(std::string& stmt, std::string condition) const
-{
-    if (!condition.empty())
-    {
-        // Remove leading whitespace from condition
-        condition.erase(0, condition.find_first_not_of(' '));
-
-        std::string whereClause("WHERE");
-        std::string joinClause("JOIN");
-        std::string leftClause("LEFT");
-        std::string orderClause("ORDER");
-
-        /* If the condition doesn't start with one of the below statements 
-         * (WHERE, JOIN, etc.), then 
-         * it is presumably extending the FROM clause with
-         * one or more table names. In this case we need to add the comma to
-         * the statement. */
-        if (tsk_strnicmp(condition.c_str(), whereClause.c_str(), whereClause.length()) != 0 &&
-            tsk_strnicmp(condition.c_str(), joinClause.c_str(), joinClause.length()) != 0 &&
-            tsk_strnicmp(condition.c_str(), leftClause.c_str(), leftClause.length()) != 0 &&
-            tsk_strnicmp(condition.c_str(), orderClause.c_str(), orderClause.length()) != 0 &&
-            condition[0] != ',')
-        {
-            stmt.append(",");
-        }
-    }
-
-    stmt.append(" ");
-    stmt.append(condition);
-}
-
-// Set file hash for hashType for a_file_id
-// Return 1 on failure, 0 on success.
-int TskImgDBSqlite::setHash(const uint64_t a_file_id, const TskImgDB::HASH_TYPE hashType, const std::string& hash) const 
-{
-    if (!m_db)
-        throw TskException("No database.");
-
-    string hashTypeStr;
-    switch (hashType) {
-    case TskImgDB::MD5:
-        hashTypeStr = "md5";
-        break;
-    case TskImgDB::SHA1:
-        hashTypeStr = "sha1";
-        break;
-    case TskImgDB::SHA2_256:
-        hashTypeStr = "sha2_256";
-        break;
-    case TskImgDB::SHA2_512:
-        hashTypeStr = "sha2_512";
-        break;
-    default:
-        std::wstringstream errorMsg;
-        errorMsg << L"TskImgDBSqlite::setHash - Unsupported hashType : " << hashType ;
-        LOGERROR(errorMsg.str());
-        return 1;
-    }
-
-    stringstream stmt;
-    std::string md5, sha1, sha2_256, sha2_512;
-    int known = IMGDB_FILES_UNKNOWN;
-    std::stringstream stream;
-
-    stmt << "SELECT md5, sha1, sha2_256, sha2_512, known from file_hashes WHERE file_id = " << a_file_id;
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        int result = sqlite3_step(statement);
-        if (result == SQLITE_ROW) {
-            md5 = (char *)sqlite3_column_text(statement, 0);
-            sha1 = (char *)sqlite3_column_text(statement, 1);
-            sha2_256 = (char *)sqlite3_column_text(statement, 2);
-            sha2_512 = (char *)sqlite3_column_text(statement, 3);
-            known = (int)sqlite3_column_int(statement, 4);
-        } 
-        sqlite3_finalize(statement);
-    } else {
-        ; // OK if not exists
-    }
-
-    // insert new record
-    stmt.str("");
-    stmt << "INSERT OR REPLACE INTO file_hashes (file_id, md5, sha1, sha2_256, sha2_512, known) VALUES (" << a_file_id;
-    switch (hashType) {
-    case TskImgDB::MD5:
-        stmt << ", '" << hash << "'";
-        stmt << ", '" << sha1 << "'";
-        stmt << ", '" << sha2_256 << "'";
-        stmt << ", '" << sha2_512 << "'";
-        stream << known;
-        stmt << ", " << stream.str();
-        break;
-    case TskImgDB::SHA1:
-        stmt << ", '" << md5 << "'";
-        stmt << ", '" << hash << "'";
-        stmt << ", '" << sha2_256 << "'";
-        stmt << ", '" << sha2_512 << "'";
-        stream << known;
-        stmt << ", " << stream.str();
-        break;
-    case TskImgDB::SHA2_256:
-        stmt << ", '" << md5 << "'";
-        stmt << ", '" << sha1 << "'";
-        stmt << ", '" << hash << "'";
-        stmt << ", '" << sha2_512 << "'";
-        stream << known;
-        stmt << ", " << stream.str();
-        break;
-    case TskImgDB::SHA2_512:
-        stmt << ", '" << md5 << "'";
-        stmt << ", '" << sha1 << "'";
-        stmt << ", '" << sha2_256 << "'";
-        stmt << ", '" << hash << "'";
-        stream << known;
-        stmt << ", " << stream.str();
-        break;
-    }
-    stmt << ")";
-
-    char *errmsg;
-    if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::setHash - Error adding hash to file_hashes table: " << errmsg;
-        LOGERROR(infoMessage.str());
-        sqlite3_free(errmsg);
-        return 1;
-    }
-
-    return 0;
-}
-
-std::string TskImgDBSqlite::getCfileName(const uint64_t a_file_id) const
-{
-    if (!m_db)
-        throw TskException("No database.");
-
-    std::string cfileName;
-    stringstream stmt;
-
-    stmt << "select 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || f.file_id"
-        " from files f, carved_files c, carved_sectors cs where f.file_id = c.file_id and c.file_id = cs.file_id and cs.seq = 0"
-        " and f.file_id = " << a_file_id;
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        int result = sqlite3_step(statement);
-        if (result == SQLITE_ROW) {
-            cfileName = (char *)sqlite3_column_text(statement, 0);
-        }
-        sqlite3_finalize(statement);
-    } else {
-        std::wstringstream infoMessage;
-        infoMessage <<  L"TskImgDBSqlite::getCfileName - Error querying tables: %S" << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-    }
-
-    stmt.str("");
-    stmt << "select f.name "
-        " from files f, carved_files c, carved_sectors cs where f.file_id = c.file_id and c.file_id = cs.file_id and cs.seq = 0"
-        " and f.file_id = " << a_file_id;
-
-    std::string name;
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        int result = sqlite3_step(statement);
-        if (result == SQLITE_ROW) {
-            name = (char *)sqlite3_column_text(statement, 0);
-        }
-        sqlite3_finalize(statement);
-        size_t pos = name.rfind('.');
-        if (pos != string::npos)
-            cfileName += name.substr(pos);
-    } else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getCfileName - Error querying tables: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-    }
-
-    return cfileName;
-}
-
-/**
- * Return the ImageInfo
- * @param type Image Type (output)
- * @param sectorSize Image sector size (output)
- * @returns 0 on success or -1 on error.
- */
-int TskImgDBSqlite::getImageInfo(int & type, int & sectorSize) const
-{
-    int rc = -1;
-    if (!m_db)
-        return rc;
-
-    stringstream stmt;
-
-    stmt << "SELECT type, ssize FROM image_info";
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        int result = sqlite3_step(statement);
-        if (result == SQLITE_ROW) {
-            type = (int)sqlite3_column_int64(statement, 0);
-            sectorSize = (int)sqlite3_column_int64(statement, 1);
-            rc = 0;
-        }
-        sqlite3_finalize(statement);
-    } else {
-        std::wstringstream infoMessage;
-        infoMessage <<  L"TskImgDBSqlite::getImageInfo - Error querying image_info table: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-        return -1;
-    }
-    return rc;
-}
-
-/**
- * Return a list of TskVolumeInfoRecord
- * @param volumeInfoList A list of TskVolumeInfoRecord (output)
- * @returns 0 on success or -1 on error.
- */
-int TskImgDBSqlite::getVolumeInfo(std::list<TskVolumeInfoRecord> & volumeInfoList) const
-{
-    std::list<TskVolumeInfoRecord> list;
-
-    if (!m_db)
-        return -1;
-
-    stringstream stmt;
-    stmt << "SELECT vol_id, sect_start, sect_len, description, flags FROM vol_info";
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        while (sqlite3_step(statement) == SQLITE_ROW) {
-            TskVolumeInfoRecord vol_info;
-            vol_info.vol_id = sqlite3_column_int(statement,0);
-            vol_info.sect_start = sqlite3_column_int64(statement,1);
-            vol_info.sect_len = sqlite3_column_int64(statement,2);
-            vol_info.description.assign((char *)sqlite3_column_text(statement, 3));
-            vol_info.flags = (TSK_VS_PART_FLAG_ENUM)sqlite3_column_int(statement, 4);
-            volumeInfoList.push_back(vol_info);
-        }
-        sqlite3_finalize(statement);
-    } else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getVolumeInfo - Error getting from vol_info table: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-        return -1;
-    }
-    return 0;
-}
-
-/**
- * Return a list of TskFsInfoRecord
- * @param fsInfoList A list of TskFsInfoRecord (output)
- * @returns 0 on success or -1 on error.
- */
-int TskImgDBSqlite::getFsInfo(std::list<TskFsInfoRecord> & fsInfoList) const
-{
-    std::list<TskFsInfoRecord> list;
-
-    if (!m_db)
-        return -1;
-
-    stringstream stmt;
-    stmt << "SELECT fs_id, img_byte_offset, vol_id, fs_type, block_size, block_count, root_inum, first_inum, last_inum FROM fs_info";
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        while (sqlite3_step(statement) == SQLITE_ROW) {
-            TskFsInfoRecord fs_info;
-            fs_info.fs_id = sqlite3_column_int(statement,0);
-            fs_info.img_byte_offset = sqlite3_column_int64(statement,1);
-            fs_info.vol_id = sqlite3_column_int(statement,2);
-            fs_info.fs_type = (TSK_FS_TYPE_ENUM)sqlite3_column_int(statement,3);
-            fs_info.block_size = sqlite3_column_int(statement,4);
-            fs_info.block_count = sqlite3_column_int64(statement,5);
-            fs_info.root_inum = sqlite3_column_int64(statement,6);
-            fs_info.first_inum = sqlite3_column_int64(statement,7);
-            fs_info.last_inum = sqlite3_column_int64(statement,8);
-            fsInfoList.push_back(fs_info);
-        }
-        sqlite3_finalize(statement);
-    } else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getFsInfo - Error getting from fs_info table: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-        return -1;
-    }
-    return 0;
-}
-
-typedef std::map<std::string, int> FileTypeMap_t;
-
-static std::string getFileType(const char *name)
-{
-    std::string filename = name;
-    size_t pos = filename.rfind('.');
-    if (pos != std::string::npos) {
-        std::string suffix = filename.substr(pos);
-        std::string result;
-        for (size_t i=0; i < suffix.size(); i++) {
-            result += (char)tolower(suffix[i]);
-        }
-        return result;
-    }
-    else
-        return std::string("");
-}
-
-/**
- * Return a list of TskFileTypeRecord for all files.
- * @param fileTypeInfoList A list of TskFileTypeRecord (output)
- * @returns 0 on success or -1 on error.
- */
-int TskImgDBSqlite::getFileInfoSummary(std::list<TskFileTypeRecord> &fileTypeInfoList) const
-{
-    std::stringstream stmt;
-    stmt << "SELECT name FROM files WHERE dir_type = " << TSK_FS_NAME_TYPE_REG;
-
-    return getFileTypeRecords(stmt.str(), fileTypeInfoList);
-}
-
-/**
- * Return a list of TskFileTypeRecord for fileType
- * @param fileType FILE_TYPE to report
- * @param fileTypeInfoList A list of TskFileTypeRecord (output)
- * @returns 0 on success or -1 on error.
- */
-int TskImgDBSqlite::getFileInfoSummary(FILE_TYPES fileType, std::list<TskFileTypeRecord> & fileTypeInfoList) const
-{
-    stringstream stmt;
-    stmt << "SELECT name FROM files WHERE type_id = " << fileType << " AND dir_type = " << TSK_FS_NAME_TYPE_REG;
-
-    return getFileTypeRecords(stmt.str(), fileTypeInfoList);
-}
-
-/**
- * Return a list of TskFileTypeRecords matching the given SQL statement.
- * @param stmt The SQL statement used to match file records.
- * @param fileTypeInfoList A list of TskFileTypeRecord (output)
- * @returns 0 on success of -1 on error.
- */
-int TskImgDBSqlite::getFileTypeRecords(const std::string& stmt, std::list<TskFileTypeRecord>& fileTypeInfoList) const
-{
-    if (!m_db)
-        return -1;
-
-    std::list<TskFileTypeRecord> list;
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.c_str(), -1, &statement, 0) == SQLITE_OK) {
-        FileTypeMap_t fileTypeMap;
-        while (sqlite3_step(statement) == SQLITE_ROW) {
-            char *name = (char *)sqlite3_column_text(statement, 0);
-            std::string type = getFileType(name);
-            FileTypeMap_t::iterator iter = fileTypeMap.find(type);
-            if (iter != fileTypeMap.end()) {
-                // increment file counter
-                int count = iter->second;
-                fileTypeMap[type] = ++count;
-            } else {
-                // add a new file type
-                fileTypeMap.insert(pair<std::string, int>(type, 1));
-            }
-        }
-        for (FileTypeMap_t::const_iterator iter=fileTypeMap.begin(); iter != fileTypeMap.end(); iter++) {
-            TskFileTypeRecord info;
-            info.suffix.assign((*iter).first.c_str());
-            info.count = (*iter).second;
-            info.description.assign("File Type Description");
-            fileTypeInfoList.push_back(info);
-        }
-        sqlite3_finalize(statement);
-    } else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getFileTypeRecords - Error querying files table: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-        return -1;
-    }
-    return 0;
-}
-
-/**
- * Insert the Module record, if module name does not already exist in modules table.
- * Returns Module Id associated with the Module record.
- * @param name Module name
- * @param description Module description
- * @param moduleId Module Id (output)
- * @returns 0 on success, -1 on error.
- */
-int TskImgDBSqlite::addModule(const std::string& name, const std::string& description, int & moduleId)
-{
-    if (!m_db)
-        return -1;
-
-    if (name.empty())
-    {
-        LOGWARN(L"TskImgDBSqlite::addModule - Given an empty module name.");
-        return -1;
-    }
-
-    moduleId = 0;
-
-    sqlite3_stmt * statement;
-    char stmt[1024];
-    sqlite3_snprintf(1024, stmt, "SELECT module_id FROM modules WHERE name = '%q';",
-                     name.c_str());
-
-    if (sqlite3_prepare_v2(m_db, stmt, -1, &statement, 0) == SQLITE_OK) 
-    {
-        int result = sqlite3_step(statement);
-        if (result == SQLITE_ROW) 
-        {
-            // Already exists, return module_id
-            moduleId = sqlite3_column_int(statement, 0);
-        }
-        else
-        {
-            // Create a new module record.
-            char insertStmt[1024];
-            char * errmsg;
-            sqlite3_snprintf(1024, insertStmt, 
-                "INSERT INTO modules (module_id, name, description) VALUES (NULL, '%q', '%q');",
-                name.c_str(), description.c_str());
-            if (sqlite3_exec(m_db, insertStmt, NULL, NULL, &errmsg) == SQLITE_OK) 
-            {
-                moduleId = (int)sqlite3_last_insert_rowid(m_db);
-            } 
-            else 
-            {
-                std::wstringstream msg;
-                msg << L"TskImgDBSqlite::addModule - Error adding record to modules table: " << errmsg;
-                LOGERROR(msg.str());
-                sqlite3_free(errmsg);
-            }
-        }
-        sqlite3_finalize(statement);
-    }
-    else
-    {
-        std::wstringstream msg;
-        msg << L"TskImgDBSqlite::addModule - Failed to prepare statement: " << stmt;
-        LOGERROR(msg.str());
-    }
-    
-    if (moduleId == 0)
-        return -1;
-
-    return 0;
-}
-
-/**
- * Insert the module status record.
- * @param file_id file_id
- * @param module_id module_id
- * @param status Status of module
- * @returns 0 on success, -1 on error.
- */
-int TskImgDBSqlite::setModuleStatus(uint64_t file_id, int module_id, int status)
-{
-    int rc = -1;
-
-    if (!m_db)
-        return rc;
-
-    char * errmsg;
-    std::stringstream stmt;
-    stmt << "INSERT INTO module_status (file_id, module_id, status) VALUES (" <<
-        file_id << ", " <<  module_id << ", " << status << ")";
-
-    if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, &errmsg) == SQLITE_OK) {
-        rc = 0;
-    } else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::setModuleStatus - Error adding data to module_status table: " << errmsg;
-        LOGERROR(infoMessage.str());
-        sqlite3_free(errmsg);
-    }
-    return rc;
-}
-
-/**
- * Get a list of TskModuleStatus.
- * @param moduleInfoList A list of TskModuleStatus (output)
- * @returns 0 on success, -1 on error.
-*/
-int TskImgDBSqlite::getModuleInfo(std::vector<TskModuleInfo> & moduleInfoList) const
-{
-    int rc = -1;
-
-    if (!m_db)
-        return rc;
-
-    stringstream stmt;
-    stmt << "SELECT module_id, name, description FROM modules ORDER BY module_id";
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        TskModuleInfo moduleInfo;
-        while (sqlite3_step(statement) == SQLITE_ROW) {
-            moduleInfo.module_id = (int)sqlite3_column_int64(statement, 0);
-            moduleInfo.module_name = (char *)sqlite3_column_text(statement, 1);
-            moduleInfo.module_description = (char *)sqlite3_column_text(statement, 2);
-            moduleInfoList.push_back(moduleInfo);
-        }
-        sqlite3_finalize(statement);
-        rc = 0;
-    } else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getModuleInfo - Error querying modules table: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-    }
-    return rc;
-}
-
-/**
- * Get a list of TskModuleStatus.
- * @param moduleStatusList A list of TskModuleStatus (output)
- * @returns 0 on success, -1 on error.
-*/
-int TskImgDBSqlite::getModuleErrors(std::vector<TskModuleStatus> & moduleStatusList) const
-{
-    int rc = -1;
-
-    if (!m_db)
-        return rc;
-
-    stringstream stmt;
-    stmt << "SELECT f.file_id, m.name, ms.status FROM module_status ms, files f, modules m"
-        << " WHERE ms.status != 0 AND ms.file_id = f.file_id AND m.module_id = ms.module_id"
-        << " ORDER BY f.file_id";
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        TskModuleStatus moduleStatus;
-        while (sqlite3_step(statement) == SQLITE_ROW) {
-            moduleStatus.file_id = (uint64_t)sqlite3_column_int64(statement, 0);
-            moduleStatus.module_name = (char *)sqlite3_column_text(statement, 1);
-            moduleStatus.status = (int)sqlite3_column_int(statement, 2);
-            moduleStatusList.push_back(moduleStatus);
-        }
-        sqlite3_finalize(statement);
-        rc = 0;
-    } else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getModuleErrors - Error querying module_status table: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-    }
-    // Find report module errors. These have file_id = 0.
-    stmt.str("");
-    stmt << "SELECT 0, m.name, ms.status FROM module_status ms, modules m"
-         << " WHERE ms.status != 0 AND ms.file_id = 0 AND m.module_id = ms.module_id";
-
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        TskModuleStatus moduleStatus;
-        while (sqlite3_step(statement) == SQLITE_ROW) {
-            moduleStatus.file_id = (uint64_t)sqlite3_column_int64(statement, 0);
-            moduleStatus.module_name = (char *)sqlite3_column_text(statement, 1);
-            moduleStatus.status = (int)sqlite3_column_int(statement, 2);
-            moduleStatusList.push_back(moduleStatus);
-        }
-        sqlite3_finalize(statement);
-        rc = 0;
-    } else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getModuleErrors - Error querying module_status table: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-    }
-    return rc;
-}
-
-/*
- * Return a file name associated with a file_id, prefer Cfilename, otherwise name in the files table.
- * @param file_id file id
- * @returns file name as std::string
- */
-std::string TskImgDBSqlite::getFileName(uint64_t file_id) const
-{
-    std::string name;
-
-    if (!m_db)
-        return name;
-
-    name = getCfileName(file_id);
-    if (name == "") {
-        TskFileRecord fileRecord;
-        if (getFileRecord(file_id, fileRecord) == 0)
-            name = fileRecord.name;
-    }
-    return name;
-}
-
-
-TskImgDB::KNOWN_STATUS TskImgDBSqlite::getKnownStatus(const uint64_t fileId) const
-{
-    int retval = -1;
-
-    if (!m_db)
-        return (KNOWN_STATUS)retval;
-    
-    stringstream stmt;
-    stmt << "SELECT known FROM file_hashes WHERE file_id = " << fileId;
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        if(sqlite3_step(statement) == SQLITE_ROW) {
-            retval = (int)sqlite3_column_int(statement, 0);
-        }
-        sqlite3_finalize(statement);
-    } else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getKnownStatus - Error getting known status " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-    }
-
-    return (KNOWN_STATUS)retval;
-}
-
-
-/**
- * Add a new row to the unalloc_img_status table, returning the unalloc_img_id.
- * @param unallocImgId unalloc_img_id (output)
- * @returns -1 on error, 0 on success.
- */
-int TskImgDBSqlite::addUnallocImg(int & unallocImgId)
-{
-    int rc = -1;
-
-    if (!m_db)
-        return rc;
-
-    std::stringstream stmt;
-    stmt << "INSERT INTO unalloc_img_status (unalloc_img_id, status) VALUES (NULL, " << TskImgDB::IMGDB_UNALLOC_IMG_STATUS_CREATED << ")";
-    char * errmsg;
-    if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, &errmsg) == SQLITE_OK) {
-        unallocImgId = (int)sqlite3_last_insert_rowid(m_db);
-        rc = 0;
-    } else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::addUnallocImg - Error adding unalloc_img_status table: " << errmsg;
-        LOGERROR(infoMessage.str());
-        sqlite3_free(errmsg);
-    }
-    return rc;
-}
-
-/**
- * Set the status in the unalloc_img_status table given the unalloc_img_id.
- * @param unallocImgId unalloc_img_id
- * @param status status of unalloc_img_id
- * @returns -1 on error, 0 on success.
- */
-int TskImgDBSqlite::setUnallocImgStatus(int unallocImgId, TskImgDB::UNALLOC_IMG_STATUS status)
-{
-    int rc = -1;
-
-    if (!m_db)
-        return rc;
-
-    std::stringstream stmt;
-    stmt << "UPDATE unalloc_img_status SET status = " << status << " WHERE unalloc_img_id = " << unallocImgId;
-    char * errmsg;
-    if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, &errmsg) == SQLITE_OK) {
-        rc = 0;
-    } else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::addUnallocImg - Error adding unalloc_img_status table: " << errmsg;
-        LOGERROR(infoMessage.str());
-        sqlite3_free(errmsg);
-    }
-    return rc;
-}
-
-/**
- * Get the status of the unalloc_img_status table given the unalloc_img_id.
- * Can throws TskException.
- * @param unallocImgId unalloc_img_id
- * @returns TskImgDB::UNALLOC_IMG_STATUS
- */
-TskImgDB::UNALLOC_IMG_STATUS TskImgDBSqlite::getUnallocImgStatus(int unallocImgId) const
-{
-    if (!m_db)
-        throw TskException("Database not initialized.");
-
-    int status = 0;
-    stringstream stmt;
-    stmt << "SELECT status FROM unalloc_img_status WHERE unalloc_img_id = " << unallocImgId;
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        if (sqlite3_step(statement) == SQLITE_ROW) {
-            status = (int)sqlite3_column_int(statement, 0);
-        }
-        sqlite3_finalize(statement);
-    } else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getUnallocImgStatus - Error getting unalloc_img_status: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-    }
-    return (TskImgDB::UNALLOC_IMG_STATUS)status;
-}
-
-/**
- * Get all the unalloc_img_status table.
- * @param unallocImgStatusList A vector of TskUnallocImgStatusRecord (output)
- * @returns -1 on error, 0 on success.
- */
-int TskImgDBSqlite::getAllUnallocImgStatus(std::vector<TskUnallocImgStatusRecord> & unallocImgStatusList) const
-{
-    int rc = -1;
-    unallocImgStatusList.clear();
-
-    if (!m_db)
-        return rc;
-
-    stringstream stmt;
-    stmt << "SELECT unalloc_img_id, status FROM unalloc_img_status";
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        while (sqlite3_step(statement) == SQLITE_ROW) {
-            TskUnallocImgStatusRecord record;
-            record.unallocImgId = (int)sqlite3_column_int(statement, 0);
-            record.status = (TskImgDB::UNALLOC_IMG_STATUS)sqlite3_column_int(statement, 1);
-            unallocImgStatusList.push_back(record);
-        }
-        rc = 0;
-        sqlite3_finalize(statement);
-    } else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getAllUnallocImgStatus - Error getting unalloc_img_status: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-    }
-    return rc;
-}
-
-/**
- * Find and add all the unused sectors (unallocated and uncarved bytes) in the given unallocImgId
- * @param unallocImgId The unalloc image id.
- * @param unusedSectorsList A vector of TskUnusedSectorsRecord
- * @returns -1 on error, 0 on success.
- */
-int TskImgDBSqlite::addUnusedSectors(int unallocImgId, std::vector<TskUnusedSectorsRecord> & unusedSectorsList)
-{
-    assert(unallocImgId > 0);
-    int rc = -1;
-    if (!m_db)
-        return rc;
-
-    std::stringstream stmt;
-    stmt << "SELECT vol_id, unalloc_img_sect_start, sect_len, orig_img_sect_start FROM alloc_unalloc_map "
-        "WHERE unalloc_img_id = " << unallocImgId << " ORDER BY orig_img_sect_start ASC";
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        vector<TskAllocUnallocMapRecord> allocUnallocMapList;
-
-        while (sqlite3_step(statement) == SQLITE_ROW) {
-            TskAllocUnallocMapRecord record;
-            record.vol_id = (int)sqlite3_column_int(statement, 0);
-            record.unalloc_img_id = unallocImgId;
-            record.unalloc_img_sect_start = (uint64_t)sqlite3_column_int64(statement, 1);
-            record.sect_len = (uint64_t)sqlite3_column_int64(statement, 2);
-            record.orig_img_sect_start = (uint64_t)sqlite3_column_int64(statement, 3);
-            allocUnallocMapList.push_back(record);
-        }
-        sqlite3_finalize(statement);
-
-        for (std::vector<TskAllocUnallocMapRecord>::const_iterator it = allocUnallocMapList.begin();
-             it != allocUnallocMapList.end(); it++)
-        {
-            // Sector position tracks our position through the unallocated map record.
-            uint64_t sectPos = it->orig_img_sect_start;
-
-            uint64_t endSect = it->orig_img_sect_start + it->sect_len;
-
-            // Retrieve all carved_sector records in range for this section of unallocated space.
-            stmt.str("");
-            stmt << "SELECT cs.sect_start, cs.sect_len FROM carved_files cf, carved_sectors cs"
-                << " WHERE cf.file_id = cs.file_id AND cs.sect_start >= " << it->orig_img_sect_start
-                << " AND cs.sect_start < " << endSect << " ORDER BY cs.sect_start ASC";
-
-            if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-                while (sqlite3_step(statement) == SQLITE_ROW) {
-                    uint64_t cfileSectStart = (uint64_t)sqlite3_column_int64(statement, 0);
-                    uint64_t cfileSectLen = (uint64_t)sqlite3_column_int64(statement, 1);
-                    if (cfileSectStart > sectPos)
-                    {
-                        // We have a block of unused sectors between this position in the unallocated map
-                        // and the start of the carved file.
-                        addUnusedSector(sectPos, cfileSectStart, it->vol_id, unusedSectorsList);
-                    }
-
-                    sectPos = cfileSectStart + cfileSectLen;
-                }
-
-                // Handle case where there is slack at the end of the unalloc range
-                if (sectPos < endSect)
-                    addUnusedSector(sectPos, endSect, it->vol_id, unusedSectorsList);
-
-                sqlite3_finalize(statement);
-            } else {
-                std::wstringstream infoMessage;
-                infoMessage << L"TskImgDBSqlite::addUnusedSectors - Error querying carved_files, carved_sectors table: " << sqlite3_errmsg(m_db);
-                LOGERROR(infoMessage.str());
-            }
-        }
-    } else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::addUnusedSectors - Error querying alloc_unalloc_map table: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-    }
-    return 0;
-}
-
-/**
- * Add one unused sector to the database, add it to the files and unused_sectors tables.
- * @param sectStart Unused sector start.
- * @param sectEnd Unused sector end.
- * @param volId Volume Id of the unused sector.
- * @param unusedSectorsList A vector of TskUnusedSectorsRecord (output)
- * @returns -1 on error, 0 on success.
- */
-int TskImgDBSqlite::addUnusedSector(uint64_t sectStart, uint64_t sectEnd, int volId, std::vector<TskUnusedSectorsRecord> & unusedSectorsList)
-{
-    assert(sectEnd > sectStart);
-    int rc = -1;
-    if (!m_db)
-        return rc;
-
-    std::stringstream stmt;
-
-    std::string maxUnused = GetSystemProperty("MAX_UNUSED_FILE_SIZE_BYTES");
-    const uint64_t maxUnusedFileSizeBytes = maxUnused.empty() ? (50 * 1024 * 1024) : Poco::NumberParser::parse64(maxUnused);
-
-    uint64_t maxUnusedSectorSize = maxUnusedFileSizeBytes / 512;
-    uint64_t sectorIndex = 0;
-    uint64_t sectorCount = (sectEnd - sectStart) / maxUnusedSectorSize;
-
-    while (sectorIndex <= sectorCount) {
-        uint64_t thisSectStart = sectStart + (sectorIndex * maxUnusedSectorSize);
-        uint64_t thisSectEnd = thisSectStart + (std::min)(maxUnusedSectorSize, sectEnd - thisSectStart);
-
-        stmt.str("");
-        stmt << "INSERT INTO files (file_id, type_id, name, par_file_id, dir_type, meta_type,"
-            "dir_flags, meta_flags, size, ctime, crtime, atime, mtime, mode, uid, gid, status, full_path) "
-            "VALUES (NULL, " << IMGDB_FILES_TYPE_UNUSED << ", " << "'ufile'" 
-            << ", NULL, " <<  TSK_FS_NAME_TYPE_REG << ", " <<  TSK_FS_META_TYPE_REG << ", "
-            << TSK_FS_NAME_FLAG_UNALLOC << ", " << TSK_FS_META_FLAG_UNALLOC << ", "
-            << (thisSectEnd - thisSectStart) * 512 << ", NULL, NULL, NULL, NULL, NULL, NULL, NULL, " << IMGDB_FILES_STATUS_READY_FOR_ANALYSIS << "," << "'ufile'" << ")";
-
-        if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, NULL) == SQLITE_OK) {
-
-            TskUnusedSectorsRecord record;
-
-            // get the file_id from the last insert
-            record.fileId = sqlite3_last_insert_rowid(m_db);
-            record.sectStart = thisSectStart;
-            record.sectLen = thisSectEnd - thisSectStart;
-
-            std::stringstream name;
-            name << "ufile_" << thisSectStart << "_" << thisSectEnd << "_" << record.fileId;
-            stmt.str("");
-            char *item;
-            item = sqlite3_mprintf("%Q", name.str().c_str());
-            stmt << "UPDATE files SET name = " << item << ", full_path = " 
-                << item << " WHERE file_id = " << record.fileId;
-            sqlite3_free(item);
-
-            if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, NULL) != SQLITE_OK) {
-                std::wstringstream infoMessage;
-                infoMessage << L"TskImgDBSqlite::addUnusedSector - Error update into files table: " << sqlite3_errmsg(m_db);
-                LOGERROR(infoMessage.str());
-                rc = -1;
-                break;
-            }
-
-            stmt.str("");
-            stmt << "INSERT INTO unused_sectors (file_id, sect_start, sect_len, vol_id) VALUES (" 
-                 << record.fileId << ", " << record.sectStart << ", " << record.sectLen << ", " << volId << ")";
-
-            if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, NULL) != SQLITE_OK) {
-                std::wstringstream infoMessage;
-                infoMessage << L"TskImgDBSqlite::addUnusedSector - Error insert into unused_sectors table: " << sqlite3_errmsg(m_db);
-                LOGERROR(infoMessage.str());
-                rc = -1;
-                break;
-            }
-
-            unusedSectorsList.push_back(record);
-            rc = 0;
-
-        } else {
-            std::wstringstream infoMessage;
-            infoMessage << L"TskImgDBSqlite::addUnusedSector - Error insert into files table: " << sqlite3_errmsg(m_db);
-            LOGERROR(infoMessage.str());
-            rc = -1;
-            break;
-        }
-        sectorIndex++;
-    } // while
-    return rc;
-}
-
-/**
- * Get unused sector record given a file id.
- * @param fileId File id of the unused sector.
- * @param unusedSectorsRecord TskUnusedSectorsRecord (output)
- * @returns -1 on error, 0 on success.
- */
-int TskImgDBSqlite::getUnusedSector(uint64_t fileId, TskUnusedSectorsRecord & unusedSectorsRecord) const
-{
-    int rc = -1;
-    if (!m_db)
-        return rc;
-
-    std::stringstream stmt;
-    stmt << "SELECT sect_start, sect_len FROM unused_sectors WHERE file_id = " << fileId;
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        if (sqlite3_step(statement) == SQLITE_ROW) {
-            unusedSectorsRecord.fileId = fileId;
-            unusedSectorsRecord.sectStart = (uint64_t)sqlite3_column_int64(statement, 0);
-            unusedSectorsRecord.sectLen = (uint64_t)sqlite3_column_int64(statement, 1);
-            rc = 0;
-        } else {
-            std::wstringstream msg;
-            msg << L"TskDBSqlite::getUnusedSector - Error querying unused_sectors table for file_id "
-                << fileId ;
-            LOGERROR(msg.str());
-        }
-    } else {
-        std::wstringstream msg;
-        msg << L"TskDBSqlite::getUnusedSector - Error querying unused_sectors table: "
-            << sqlite3_errmsg(m_db) ;
-        LOGERROR(msg.str());
-    }
-    return rc;
-}
-
-///BLACKBOARD FUNCTIONS
-/**
- * Add the given blackboard attribute to the database
- * @param attr input attribute. should be fully populated
- */
-void TskImgDBSqlite::addBlackboardAttribute(TskBlackboardAttribute attr)
-{
-    if (!m_db)
-        throw TskException("No database.");
-
-    std::stringstream str;
-    char *item;
-    sqlite3_stmt * statement;
-
-    str << "INSERT INTO blackboard_attributes (artifact_id, source, context, attribute_type_id, value_type, "
-        "value_byte, value_text, value_int32, value_int64, value_double, obj_id) VALUES (";
-        str << attr.getArtifactID() << ", ";
-    item = sqlite3_mprintf("%Q", attr.getModuleName().c_str()); str << item << ", ";
-    sqlite3_free(item);
-    item = sqlite3_mprintf("%Q", attr.getContext().c_str()); str << item << ", ";
-    sqlite3_free(item);
-    str << attr.getAttributeTypeID() << ", ";
-    str << attr.getValueType() << ", ";
-    switch (attr.getValueType()) {
-        case TSK_BYTE:
-            str << " ?, '', 0, 0, 0.0";
-            break;
-        case TSK_STRING:
-            item = sqlite3_mprintf("%Q", attr.getValueString().c_str());
-            str << " '', " << item << ", 0, 0, 0.0";
-            sqlite3_free(item);
-            break;
-        case TSK_INTEGER:
-            str << " '', '', " << attr.getValueInt() << ",     0, 0.0";
-            break;
-        case TSK_LONG:
-            str << " '', '', 0, " << attr.getValueLong() << ",     0.0";
-            break;
-        case TSK_DOUBLE:
-            str << " '', '', 0, 0, " << setprecision(20) << attr.getValueDouble();
-            break;
-    };
-    str << ", " << attr.getObjectID();
-    str << ")";
-
-    if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        int result = SQLITE_OK;
-        unsigned char *pBuf = 0;
-        if (attr.getValueType() == TSK_BYTE) {
-            // Bind the byte vector
-            int a_size = attr.getValueBytes().size();
-            pBuf = new unsigned char[a_size];
-            for (int i = 0; i < a_size; i++) {
-                pBuf[i] = attr.getValueBytes()[i];
-            }
-            result = sqlite3_bind_blob(statement, 1, pBuf, a_size, SQLITE_STATIC);
-        }
-        if (result == SQLITE_OK) {
-            result = sqlite3_step(statement);
-            if (!(result == SQLITE_ROW || result == SQLITE_DONE)) {
-                sqlite3_finalize(statement);
-                if (pBuf) delete [] pBuf;
-                throw TskException("TskImgDBSqlite::addBlackboardAttribute - Insert failed");
-            }
-        } else {
-            std::wstringstream infoMessage;
-            infoMessage << L"TskImgDBSqlite::addBlackboardAttribute - Error in sqlite3_bind_blob: " << sqlite3_errmsg(m_db);
-            LOGERROR(infoMessage.str());
-            throw TskException("TskImgDBSqlite::addBlackboardAttribute - Insert failed");
-        }
-        sqlite3_finalize(statement);
-        if (pBuf) delete [] pBuf;
-    } else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::addBlackboardAttribute - Error adding data to blackboard table: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-        throw TskException("TskImgDBSqlite::addBlackboardAttribute - Insert failed");
-    }
-}
-
-/**
- * Get the display name for the given artifact type id
- * @param artifactTypeID artifact type id
- * @returns display name
- */
-string TskImgDBSqlite::getArtifactTypeDisplayName(int artifactTypeID){
-    if (!m_db)
-        throw TskException("No database.");
-
-    std::stringstream str;
-    sqlite3_stmt * statement;
-    std::string displayName = "";
-
-    str << "SELECT display_name FROM blackboard_artifact_types WHERE artifact_type_id = " << artifactTypeID;
-
-    if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK){
-        int result = sqlite3_step(statement);
-        if (result == SQLITE_ROW) {
-            displayName = (char *)sqlite3_column_text(statement, 0);
-        }
-        else{
-            std::wstringstream infoMessage;
-            infoMessage << L"TskImgDBSqlite::getArtifactTypeDisplayName: " << sqlite3_errmsg(m_db);
-            LOGERROR(infoMessage.str());
-            throw TskException("TskImgDBSqlite::getArtifactTypeDisplayName - No artifact type with that ID");
-        }
-        sqlite3_finalize(statement);
-        return displayName;
-    }
-    else{
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getArtifactTypeDisplayName: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-        throw TskException("TskImgDBSqlite::getArtifactTypeDisplayName - Select failed");
-    }
-}
-
-/**
- * Get the artifact type id for the given artifact type string
- * @param artifactTypeString display name
- * @returns artifact type id
- */
-int TskImgDBSqlite::getArtifactTypeID(string artifactTypeString){
-    if (!m_db)
-        throw TskException("No database.");
-
-    std::stringstream str;
-    sqlite3_stmt * statement;
-    int typeID;
-
-    str << "SELECT artifact_type_id FROM blackboard_artifact_types WHERE type_name = " << artifactTypeString;
-
-    if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK){
-        int result = sqlite3_step(statement);
-        if (result == SQLITE_ROW) {
-            typeID = (int) sqlite3_column_int(statement, 0);
-        }
-        else{
-            std::wstringstream infoMessage;
-            infoMessage << L"TskImgDBSqlite::getArtifactTypeID: " << sqlite3_errmsg(m_db);
-            LOGERROR(infoMessage.str());
-            throw TskException("TskImgDBSqlite::getArtifactTypeID - No artifact type with that name");
-        }
-        sqlite3_finalize(statement);
-        return typeID;
-    }
-    else{
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getArtifactTypeID: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-        throw TskException("TskImgDBSqlite::getArtifactTypeID - Select failed");
-    }
-}
-
-/**
- * Get the artifact type name for the given artifact type id
- * @param artifactTypeID id
- * @returns artifact type name
- */
-string TskImgDBSqlite::getArtifactTypeName(int artifactTypeID){
-    if (!m_db)
-        throw TskException("No database.");
-
-    std::stringstream str;
-    sqlite3_stmt * statement;
-    std::string typeName = "";
-
-    str << "SELECT type_name FROM blackboard_artifact_types WHERE artifact_type_id = " << artifactTypeID;
-
-    if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK){
-        int result = sqlite3_step(statement);
-        if (result == SQLITE_ROW) {
-            typeName = (char *)sqlite3_column_text(statement, 0);
-        }
-        else{
-            std::wstringstream infoMessage;
-            infoMessage << L"TskImgDBSqlite::getArtifactTypeName: " << sqlite3_errmsg(m_db);
-            LOGERROR(infoMessage.str());
-            throw TskException("TskImgDBSqlite::getArtifactTypeName - No artifact type with that ID");
-        }
-        sqlite3_finalize(statement);
-        return typeName;
-    }
-    else{
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getArtifactTypeName: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-        throw TskException("TskImgDBSqlite::getArtifactTypeName - Select failed");
-    }
-}
-
-/**
- * Get the display name for the given attribute type id
- * @param attributeTypeID attribute type id
- * @returns display name
- */
-string TskImgDBSqlite::getAttributeTypeDisplayName(int attributeTypeID){
-    if (!m_db)
-        throw TskException("No database.");
-
-    std::stringstream str;
-    sqlite3_stmt * statement;
-    std::string displayName = "";
-
-    str << "SELECT display_name FROM blackboard_attribute_types WHERE attribute_type_id = " << attributeTypeID;
-
-    if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK){
-        int result = sqlite3_step(statement);
-        if (result == SQLITE_ROW) {
-            displayName = (char *)sqlite3_column_text(statement, 0);
-        }
-        else{
-            std::wstringstream infoMessage;
-            infoMessage << L"TskImgDBSqlite::getAttributeTypeDisplayName: " << sqlite3_errmsg(m_db);
-            LOGERROR(infoMessage.str());
-            throw TskException("TskImgDBSqlite::getAttributeTypeDisplayName - No attribute type with that ID");
-        }
-        sqlite3_finalize(statement);
-        return displayName;
-    }
-    else{
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getAttributeTypeDisplayName: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-        throw TskException("TskImgDBSqlite::getAttributeTypeDisplayName - Select failed");
-    }
-}
-
-/**
- * Get the attribute type id for the given artifact type string
- * @param attributeTypeString display name
- * @returns attribute type id
- */
-int TskImgDBSqlite::getAttributeTypeID(string attributeTypeString){
-    if (!m_db)
-        throw TskException("No database.");
-
-    std::stringstream str;
-    sqlite3_stmt * statement;
-    int typeID;
-
-    str << "SELECT attribute_type_id FROM blackboard_attribute_types WHERE type_name = " << attributeTypeString;
-
-    if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK){
-        int result = sqlite3_step(statement);
-        if (result == SQLITE_ROW) {
-            typeID = (int) sqlite3_column_int(statement, 0);
-        }
-        else{
-            std::wstringstream infoMessage;
-            infoMessage << L"TskImgDBSqlite::getAttributeTypeID: " << sqlite3_errmsg(m_db);
-            LOGERROR(infoMessage.str());
-            throw TskException("TskImgDBSqlite::getAttributeTypeID - No artifact type with that name");
-        }
-        sqlite3_finalize(statement);
-        return typeID;
-    }
-    else{
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getAttributeTypeID: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-        throw TskException("TskImgDBSqlite::getAttributeTypeID - Select failed");
-    }
-}
-
-/**
- * Get the attribute type name for the given artifact type id
- * @param attributeTypeID id
- * @returns attribute type name
- */
-string TskImgDBSqlite::getAttributeTypeName(int attributeTypeID){
-    if (!m_db)
-        throw TskException("No database.");
-
-    std::stringstream str;
-    sqlite3_stmt * statement;
-    std::string typeName = "";
-
-    str << "SELECT type_name FROM blackboard_attribute_types WHERE attribute_type_id = " << attributeTypeID;
-
-    if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK){
-        int result = sqlite3_step(statement);
-        if (result == SQLITE_ROW) {
-            typeName = (char *)sqlite3_column_text(statement, 0);
-        }
-        else{
-            std::wstringstream infoMessage;
-            infoMessage << L"TskImgDBSqlite::getAttributeTypeName: " << sqlite3_errmsg(m_db);
-            LOGERROR(infoMessage.str());
-            throw TskException("TskImgDBSqlite::getAttributeTypeName - No attribute type with that ID");
-        }
-        sqlite3_finalize(statement);
-        return typeName;
-    }
-    else{
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::getAttributeTypeName: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-        throw TskException("TskImgDBSqlite::getAttributeTypeName - Select failed");
-    }
-}
-
-/**
- * Get all artifacts by performing a SQL Select statement with the given where clause.
- * @param condition The SQL select where clause that should be used in the query.
- * @returns vector of matching artifacts
- */
-vector<TskBlackboardArtifact> TskImgDBSqlite::getMatchingArtifacts(string condition)
-{
-    if (!m_db)
-        throw TskException("No database.");
-    
-    vector<TskBlackboardArtifact> artifacts;
-    std::string stmt("SELECT blackboard_artifacts.artifact_id, blackboard_artifacts.obj_id, blackboard_artifacts.artifact_type_id FROM blackboard_artifacts");
-
-    constructStmt(stmt, condition);
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.c_str(), -1, &statement, 0) == SQLITE_OK) 
-    {
-        while (sqlite3_step(statement) == SQLITE_ROW) 
-        {
-            int artifactTypeID = sqlite3_column_int(statement, 2);
-
-            artifacts.push_back(TskImgDB::createArtifact(sqlite3_column_int64(statement, 0), sqlite3_column_int64(statement, 1), artifactTypeID));
-        }
-        sqlite3_finalize(statement);
-    } else 
-    {
-        std::wstringstream msg;
-        msg << L"TskImgDBSqlite::getMatchingArtifacts - Error getting artifacts: " << sqlite3_errmsg(m_db);
-        LOGERROR(msg.str());
-        throw TskException("TskImgDBSqlite::getMatchingArtifacts - Select failed");
-    }
-    return artifacts;
-}
-
-/**
- * Get all attributes with that match the given where clause 
- * @param condition where clause to use for matching
- * @returns vector of matching attributes
- */
-vector<TskBlackboardAttribute> TskImgDBSqlite::getMatchingAttributes(string condition)
-{
-    if (!m_db)
-        throw TskException("No database.");
-    
-    vector<TskBlackboardAttribute> attributes;
-    std::string stmt("SELECT blackboard_attributes.artifact_id, blackboard_attributes.source, blackboard_attributes.context, blackboard_attributes.attribute_type_id, blackboard_attributes.value_type, blackboard_attributes.value_byte, blackboard_attributes.value_text, blackboard_attributes.value_int32, blackboard_attributes.value_int64, blackboard_attributes.value_double, blackboard_attributes.obj_id FROM blackboard_attributes ");
-
-    constructStmt(stmt, condition);
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.c_str(), -1, &statement, 0) == SQLITE_OK) 
-    {
-        while (sqlite3_step(statement) == SQLITE_ROW) 
-        { 
-            int blobSize = sqlite3_column_bytes(statement, 6);
-            const unsigned char *pBlob = (const unsigned char *)sqlite3_column_blob(statement, 6);
-            vector<unsigned char> bytes;
-            bytes.reserve(blobSize);
-            for (int i = 0; i < blobSize; i++) {
-                bytes.push_back((unsigned char)pBlob[i]);
-            }
-
-            attributes.push_back(TskImgDB::createAttribute(sqlite3_column_int64(statement, 0),sqlite3_column_int(statement, 3), sqlite3_column_int64(statement, 10), std::string((char *)sqlite3_column_text(statement, 1)), 
-                std::string((char *)sqlite3_column_text(statement, 2)), (TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE) sqlite3_column_int(statement, 4), sqlite3_column_int(statement, 7), 
-                sqlite3_column_int64(statement, 8), sqlite3_column_double(statement, 9), std::string((char *)sqlite3_column_text(statement, 6)), bytes));
-        }
-        sqlite3_finalize(statement);
-    } else {
-        std::wstringstream msg;
-        msg << L"TskImgDBSqlite::getMatchingAttributes - Error getting attributes: " << sqlite3_errmsg(m_db);
-        LOGERROR(msg.str());
-        throw TskException("TskImgDBSqlite::getMatchingAttributes - Select failed");
-    }
-    return attributes;
-}
-
-/**
- * Create a new blackboard artifact with the given type id and file id
- * @param artifactTypeID artifact type id
- * @param file_id associated file id
- * @returns the new artifact
- */
-TskBlackboardArtifact TskImgDBSqlite::createBlackboardArtifact(uint64_t file_id, int artifactTypeID)
-{
-    if (!m_db)
-        throw TskException("No database.");
-
-    uint64_t artifactId = 0;
-    std::stringstream str;
-    sqlite3_stmt * statement;
-
-    str << "INSERT INTO blackboard_artifacts (artifact_id, obj_id, artifact_type_id) VALUES (NULL, " << file_id << ", " << artifactTypeID << ")";
-
-    if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        if (!(sqlite3_step(statement) == SQLITE_DONE)) {
-            sqlite3_finalize(statement);
-            throw TskException("TskImgDBSqlite::addBlackboardInfo - Insert failed");
-        }
-        // select max(artifact_id) from blackboard
-        str.str("");
-        str << "SELECT artifact_id from blackboard_artifacts WHERE obj_id = " << file_id << " AND artifact_type_id = " << artifactTypeID;
-        sqlite3_finalize(statement);
-        if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-            while(sqlite3_step(statement) == SQLITE_ROW) {
-                uint64_t newID = sqlite3_column_int64(statement, 0);
-                if(newID > artifactId)
-                    artifactId = newID;
-            }
-        } else {
-            sqlite3_finalize(statement);
-            throw TskException("TskImgDBSqlite::newBlackboardArtifact - Select artifact_id failed");
-        }
-        sqlite3_finalize(statement);
-    } else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::newBlackboardArtifact - Error adding new artifact: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-        throw TskException("TskImgDBSqlite::newBlackboardArtifact - Insert failed");
-    }
-
-    return TskImgDB::createArtifact(artifactId, file_id, artifactTypeID);
-}
-
-/**
- * Add a new artifact type with the given name, display name and id 
- * @param artifactTypeName type name
- * @param displayName display name
- * @param typeID type id
- */
-void TskImgDBSqlite::addArtifactType(int typeID, string artifactTypeName, string displayName)
-{
-    if (!m_db)
-        throw TskException("No database.");
-
-    std::stringstream str;
-    sqlite3_stmt * statement;
-
-    str << "SELECT * FROM blackboard_artifact_types WHERE type_name = '" << artifactTypeName << "'";
-
-    if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        if (!(sqlite3_step(statement) == SQLITE_ROW)) {
-            sqlite3_finalize(statement);
-            str.str("");
-            str << "INSERT INTO blackboard_artifact_types (artifact_type_id, type_name, display_name) VALUES (" << typeID << " , '" << artifactTypeName << "', '" << displayName << "')";
-            if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-                if (!(sqlite3_step(statement) == SQLITE_DONE)) {
-                    sqlite3_finalize(statement);
-                    std::wstringstream infoMessage;
-                    infoMessage << L"TskImgDBSqlite::addArtifactType - Error adding data to blackboard table: " << sqlite3_errmsg(m_db);
-                    LOGERROR(infoMessage.str());
-                    throw TskException("TskImgDBSqlite::addArtifactType - Artifact type insert failed");
-                }
-            }
-        }
-        else{
-            sqlite3_finalize(statement);
-            throw TskException("TskImgDBSqlite::addArtifactType - Artifact type with that name already exists");
-        }
-        sqlite3_finalize(statement);
-    } else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::addArtifactType - Error adding data to blackboard table: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-        throw TskException("TskImgDBSqlite::addArtifactType - Insert failed");
-    }
-}
-
-/**
- * Add a new attribute type with the given name, display name and id 
- * @param attributeTypeName type name
- * @param displayName display name
- * @param typeID type id
- */
-void TskImgDBSqlite::addAttributeType(int typeID, string attributeTypeName, string displayName)
-{
-    if (!m_db)
-        throw TskException("No database.");
-
-    std::stringstream str;
-    sqlite3_stmt * statement;
-
-    str << "SELECT * FROM blackboard_attribute_types WHERE type_name = '" << attributeTypeName << "'";
-
-    if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-        if (!(sqlite3_step(statement) == SQLITE_ROW)) {
-            sqlite3_finalize(statement);
-            str.str("");
-            str << "INSERT INTO blackboard_attribute_types (attribute_type_id, type_name, display_name) VALUES (" << typeID << " , '" << attributeTypeName << "', '" << displayName << "')";
-            if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
-                if (!(sqlite3_step(statement) == SQLITE_DONE)) {
-                    sqlite3_finalize(statement);
-                    std::wstringstream infoMessage;
-                    infoMessage << L"TskImgDBSqlite::addAttributeType - Error adding data to blackboard table: " << sqlite3_errmsg(m_db);
-                    LOGERROR(infoMessage.str());
-                    throw TskException("TskImgDBSqlite::addAttributeType - Attribute type insert failed");
-                }
-            }
-        } else {
-            sqlite3_finalize(statement);
-            throw TskException("TskImgDBSqlite::addAttributeType - Attribute type with that name already exists");
-        }
-        sqlite3_finalize(statement);
-    } else {
-        std::wstringstream infoMessage;
-        infoMessage << L"TskImgDBSqlite::addAttributeType - Error adding data to blackboard table: " << sqlite3_errmsg(m_db);
-        LOGERROR(infoMessage.str());
-        throw TskException("TskImgDBSqlite::addAttributeType - Insert failed");
-    }
-}
-
-/**
- * Get all artifacts with the given type id, type name, and file id
- * @param artifactTypeID type id
- * @param artifactTypeName type name
- * @param file_id file id
- */
-vector<TskBlackboardArtifact> TskImgDBSqlite::getArtifactsHelper(uint64_t file_id, int artifactTypeID, string artifactTypeName)
-{
-    if (!m_db)
-        throw TskException("No database.");
-    
-    vector<TskBlackboardArtifact> artifacts;
-    std::stringstream stmt;
-    stmt << "SELECT artifact_id, obj_id, artifact_type_id FROM blackboard_artifacts WHERE obj_id = " << file_id << " AND artifact_type_id = " << artifactTypeID;
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) 
-    {
-        while (sqlite3_step(statement) == SQLITE_ROW) 
-        {
-            int artifactTypeID = sqlite3_column_int(statement, 2);
-
-            artifacts.push_back(TskImgDB::createArtifact(sqlite3_column_int64(statement, 0), file_id, artifactTypeID));
-        }
-        sqlite3_finalize(statement);
-    } else {
-        std::wstringstream msg;
-        msg << L"TskImgDBSqlite::getArtifactsHelper - Error getting artifacts: " << sqlite3_errmsg(m_db);
-        LOGERROR(msg.str());
-        throw TskException("TskImgDBSqlite::getArtifactsHelper - Select failed");
-    }
-    return artifacts;
-}
-
-vector<int> TskImgDBSqlite::findAttributeTypes(int artifactTypeId)
-{
-    if (!m_db) {
-        throw TskException("No database.");
-    }
-    vector<int> attrTypes;
-    std::stringstream stmt;
-    stmt << "SELECT DISTINCT(attribute_type_id) FROM blackboard_attributes JOIN blackboard_artifacts ON blackboard_attributes.artifact_id = blackboard_artifacts.artifact_id WHERE artifact_type_id = " << artifactTypeId;
-
-    sqlite3_stmt * statement;
-    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) 
-    {
-        while (sqlite3_step(statement) == SQLITE_ROW) 
-        {
-            int artifactTypeID = sqlite3_column_int(statement, 0);
-
-            attrTypes.push_back(artifactTypeID);
-        }
-        sqlite3_finalize(statement);
-    } else {
-        std::wstringstream msg;
-        msg << L"TskImgDBSqlite::findAttributeTypes - Error finding attribute types: " << sqlite3_errmsg(m_db);
-        LOGERROR(msg.str());
-        throw TskException("TskImgDBSqlite::findAttributeTypes - Select failed");
-    }
-    return attrTypes;
-}
-
-std::string TskImgDBSqlite::quote(const std::string str) const
-{
-    char *item = sqlite3_mprintf("%Q", str.c_str());
-    std::string returnStr(item);
-    sqlite3_free(item);
-    return returnStr;
-}
-
-void TskImgDBSqlite::executeStatement(const std::string &stmtToExecute, sqlite3_stmt *&statement, const std::string &caller) const
-{
-    if (sqlite3_prepare_v2(m_db, stmtToExecute.c_str(), -1, &statement, 0) != SQLITE_OK)
-    {
-        sqlite3_finalize(statement);
-        std::ostringstream msg;
-        msg << caller << " : error executing " << stmtToExecute << " : " << sqlite3_errmsg(m_db);
-        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 TskImgDBSqlite.cpp
+ * A SQLite based implementation of the framework data access layer.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <cassert>
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+#include <map>
+#include <assert.h>
+
+#include "Poco/UnicodeConverter.h"
+#include "Poco/Thread.h"
+
+#include "TskImgDBSqlite.h"
+#include "TskServices.h"
+#include "tsk/framework/utilities/TskException.h"
+#include "TskDBBlackboard.h"
+
+#include "Poco/UnicodeConverter.h"
+#include "Poco/NumberParser.h"
+#include "Poco/Path.h"
+
+#define IMGDB_CHUNK_SIZE 1024*1024*1 // what size chunks should the database use when growing and shrinking
+#define IMGDB_MAX_RETRY_COUNT 50    // how many times will we retry a SQL statement
+#define IMGDB_RETRY_WAIT 100   // how long (in milliseconds) are we willing to wait between retries
+
+/**
+ * Set the database location.  Must call
+ * initialize() before the object can be used.
+ * @param a_outpath Directory to store the database in. This 
+ * directory must already exist.
+*/
+TskImgDBSqlite::TskImgDBSqlite(const char * a_outpath)
+{
+    strncpy(m_outPath, a_outpath, 256);
+    // ensure that the path ends with a '/'
+    if (m_outPath[strlen(m_outPath)-1] != '/') {
+        int len1 = strlen(m_outPath);
+        m_outPath[len1] = '/';
+        m_outPath[len1+1] = '\0';
+    }
+    strncpy(m_dbFilePath, m_outPath, 256);
+    strncat(m_dbFilePath, "image.db", 256);
+    m_db = NULL;
+}
+
+TskImgDBSqlite::~TskImgDBSqlite()
+{
+    (void) close();
+}
+
+int TskImgDBSqlite::close()
+{
+    if (m_db) {
+        if (sqlite3_close(m_db) == SQLITE_OK)
+            m_db = NULL;
+        else
+            return 1;
+    }
+    return 0;
+}
+
+int TskImgDBSqlite::dropTables()
+{
+    if (!m_db)
+        return 1;
+
+    char * errmsg;
+    // Drop all the tables. No error checking just Teutonic Destruction...
+    sqlite3_exec(m_db, "DROP TABLE db_info",NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP TABLE image_info",NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP TABLE image_names",NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP TABLE vol_info",NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP TABLE fs_info",NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP TABLE fs_files",NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP TABLE fs_blocks",NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP TABLE files",NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP TABLE derived_files",NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP TABLE carved_files",NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP TABLE carved_sectors",NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP TABLE alloc_unalloc_map", NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP TABLE blackboard_artifacts", NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP TABLE blackboard_attributes", NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP TABLE blackboard_artifact_types", NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP TABLE blackboard_attribute_types", NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP TABLE file_hashes", NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP TABLE modules", NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP TABLE module_status", NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP TABLE unalloc_img_status", NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP TABLE unused_sectors", NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP INDEX attrs_artifact_id", NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP INDEX attrs_attribute_type", NULL, NULL, &errmsg);
+    sqlite3_exec(m_db, "DROP INDEX attrs_obj_id", NULL, NULL, &errmsg);
+
+    return 0;
+}
+
+int TskImgDBSqlite::initialize()
+{
+    std::wstringstream infoMessage;
+    char * errmsg;
+
+    // Open the database.
+    if (open() != 0)
+    {
+        // Error message will have been logged by open()
+        return 1;
+    }
+
+    // Clean up the whole database.
+    dropTables();
+
+    std::string stmt;
+
+    sqlite3_stmt *statement;
+
+    // set page size -- 4k is much faster on Windows than the default
+    executeStatement("PRAGMA page_size = 4096;", statement, "TskImgDBSqlite::initialize");
+    sqlite3_finalize(statement);
+
+    // we don't have a mechanism to recover from a crash anyway
+    executeStatement("PRAGMA synchronous = 0;", statement, "TskImgDBSqlite::initialize");
+    sqlite3_finalize(statement);
+
+    // ----- DB_INFO
+    stmt = "CREATE TABLE db_info (name TEXT PRIMARY KEY, version TEXT)";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating db_info table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    // ----- IMAGE_INFO
+    stmt = "CREATE TABLE image_info (type INTEGER, ssize INTEGER)";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating image_info table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    // ----- IMAGE_NAMES
+    stmt = "CREATE TABLE image_names (seq INTEGER PRIMARY KEY, name TEXT)";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating image_names table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    // ----- VOL_INFO
+    stmt = "CREATE TABLE vol_info (vol_id INTEGER PRIMARY KEY, sect_start INTEGER NOT NULL, "
+        "sect_len INTEGER NOT NULL, description TEXT, flags INTEGER)";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating vol_info table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    // ----- FS_INFO
+    stmt = "CREATE TABLE fs_info (fs_id INTEGER PRIMARY KEY, img_byte_offset INTEGER, "
+        "vol_id INTEGER NOT NULL, fs_type INTEGER, block_size INTEGER, "
+        "block_count INTEGER, root_inum INTEGER, first_inum INTEGER, last_inum INTEGER)";
+    if (sqlite3_exec(m_db, stmt.c_str() , NULL, NULL, &errmsg) != SQLITE_OK) {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating fs_info table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    // ----- FILES
+    stmt = "CREATE TABLE files (file_id INTEGER PRIMARY KEY, type_id INTEGER, "
+        "name TEXT, par_file_id INTEGER, dir_type INTEGER, meta_type INTEGER, "
+        "dir_flags INTEGER, meta_flags INTEGER, size INTEGER, ctime INTEGER, "
+        "crtime INTEGER, atime INTEGER, mtime INTEGER, mode INTEGER, uid INTEGER, "
+        "gid INTEGER, status INTEGER, full_path TEXT)";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating files table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    // ----- FS_FILES
+    stmt = "CREATE TABLE fs_files (file_id INTEGER PRIMARY KEY, fs_id INTEGER, "
+        "fs_file_id INTEGER, attr_type INTEGER, attr_id INTEGER)";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK)
+    {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating fs_files table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    // ----- FS_BLOCKS
+    stmt = "CREATE TABLE fs_blocks (fs_id INTEGER NOT NULL, file_id INTEGER NOT NULL, seq INTEGER, "
+        "blk_start INTEGER NOT NULL, blk_len INTEGER NOT NULL)";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK)
+    {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating fs_blocks table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    // ----- CARVED_FILES
+    stmt = "CREATE TABLE carved_files (file_id INTEGER PRIMARY KEY, vol_id INTEGER)";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK)
+    {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating carved_files table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    // ----- SECTOR_LIST
+    stmt = "CREATE TABLE carved_sectors ("
+        "file_id INTEGER, seq INTEGER, sect_start INTEGER, sect_len INTEGER)";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK)
+    {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating carved_sectors table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    // ----- DERIVED_FILES
+    stmt = "CREATE TABLE derived_files (file_id INTEGER PRIMARY KEY, derivation_details TEXT)";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK)
+    {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating derived_files table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    // ----- ALLOC_UNALLOC_MAP
+    stmt = "CREATE TABLE alloc_unalloc_map (vol_id INTEGER, unalloc_img_id INTEGER, "
+        "unalloc_img_sect_start INTEGER, sect_len INTEGER, orig_img_sect_start INTEGER)";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK)
+    {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating alloc_unalloc_map table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    // ----- FILE_HASHES
+    stmt = "CREATE TABLE file_hashes (file_id INTEGER PRIMARY KEY, md5 TEXT, sha1 TEXT, sha2_256 TEXT, sha2_512 TEXT, known INTEGER)";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating file_hashes table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    // ----- MODULES
+    stmt = "CREATE TABLE modules (module_id INTEGER PRIMARY KEY, name TEXT UNIQUE NOT NULL, description TEXT)";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating module table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    // ----- MODULE_STATUS
+    stmt = "CREATE TABLE module_status (file_id INTEGER, module_id INTEGER, status INTEGER, PRIMARY KEY (file_id, module_id))";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating module_status table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    // ----- UNALLOC_IMG_STATUS
+    stmt = "CREATE TABLE unalloc_img_status (unalloc_img_id INTEGER PRIMARY KEY, status INTEGER)";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating unalloc_img_status table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    // ----- UNUSED_SECTORS
+    stmt = "CREATE TABLE unused_sectors (file_id INTEGER PRIMARY KEY, sect_start INTEGER, sect_len INTEGER, vol_id INTEGER)";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating unused_sectors table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    // ----- BLACKBOARD_ARTIFACTS
+    stmt = "CREATE TABLE blackboard_artifacts (artifact_id INTEGER PRIMARY KEY, obj_id INTEGER NOT NULL, artifact_type_id INTEGER)";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating blackboard_artifacts table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    // ----- BLACKBOARD_ATTRIBUTES
+    stmt = "CREATE TABLE blackboard_attributes (artifact_id INTEGER NOT NULL, source TEXT, context TEXT, attribute_type_id INTEGER NOT NULL, value_type INTEGER NOT NULL, "
+        "value_byte BLOB, value_text TEXT, value_int32 INTEGER, value_int64 INTEGER, value_double NUMERIC(20, 10), obj_id INTEGER NOT NULL)";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating blackboard_attributes table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    // ----- BLACKBOARD_ARTIFACT_TYPES
+    stmt = "CREATE TABLE blackboard_artifact_types (artifact_type_id INTEGER PRIMARY KEY, type_name TEXT, display_name TEXT)";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating blackboard_artifact_types table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    // ----- BLACKBOARD_ATTRIBUTE_TYPES
+    stmt = "CREATE TABLE blackboard_attribute_types (attribute_type_id INTEGER PRIMARY KEY, type_name TEXT, display_name TEXT)";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating blackboard_attribute_types table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    // ----- CREATE INDEXES
+    stmt = "CREATE INDEX attrs_artifact_id ON blackboard_attributes(artifact_id)";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating attrs_artifact_id index: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    stmt = "CREATE INDEX attrs_attribute_type ON blackboard_attributes(attribute_type_id)";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating attrs_attribute_type index: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    stmt = "CREATE INDEX attrs_obj_id ON blackboard_attributes(obj_id)";
+    if (sqlite3_exec(m_db, stmt.c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        infoMessage << L"TskImgDBSqlite::initialize - Error creating attrs_obj_id index: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    map<int, TskArtifactNames> artTypes = TskImgDB::getAllArtifactTypes();
+    for (map<int, TskArtifactNames>::iterator it = artTypes.begin(); it != artTypes.end(); it++) {
+        addArtifactType(it->first, it->second.typeName, it->second.displayName);
+    }
+    map<int, TskAttributeNames> attrTypes = TskImgDB::getAllAttributeTypes();
+    for (map<int, TskAttributeNames>::iterator it = attrTypes.begin(); it != attrTypes.end(); it++) {
+        addAttributeType(it->first, it->second.typeName, it->second.displayName);
+    }
+
+    addToolInfo("DBSchema", IMGDB_SCHEMA_VERSION);
+    LOGINFO(L"ImgDB Created.");
+
+    return 0;
+}
+
+/*
+ * If the database file exists this method will open it otherwise
+ * it will create a new database. 
+ * This method also configures the chunk size and the busy handler
+ * for the newly opened database.
+*/
+int TskImgDBSqlite::open()
+{
+    std::wstringstream infoMessage;
+
+#if 0
+    if (sqlite3_open16(m_dbFilePath, &m_db)) 
+#else
+    if (sqlite3_open(m_dbFilePath, &m_db)) 
+#endif
+    {
+        infoMessage << L"TskImgDBSqlite::open - Can't create new database: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+
+        sqlite3_close(m_db);
+        return 1;
+    }
+
+    // The chunk size setting defines by how much the database will grow
+    // or shrink. The primary motivation behind this setting is to reduce
+    // database file fragmentation and potential performance improvements.
+    // We, however, are using this setting as a workaround for database
+    // corruption issues we have been experiencing when the database is
+    // updated by multiple concurrent processes.
+    // Database corruption was occuring when SQLite determined that the 
+    // number of database pages in the database was greater than a value
+    // that it had previously cached. 
+    // This workaround is a crude mechanism to get around that situation.
+    int chunkSize = IMGDB_CHUNK_SIZE;
+
+    if (sqlite3_file_control(m_db, NULL, SQLITE_FCNTL_CHUNK_SIZE, &chunkSize) != SQLITE_OK)
+    {
+        infoMessage << L"TskImgDBSqlite::open - Failed to set chunk size: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+
+        sqlite3_close(m_db);
+        return 1;
+    }
+
+    // Register a busy handler that will retry statements in situations
+    // where the database is locked by another process.
+    if (sqlite3_busy_handler(m_db, TskImgDBSqlite::busyHandler, m_db) != SQLITE_OK)
+    {
+        infoMessage <<  L"TskImgDBSqlite::open - Failed to set busy handler: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+
+        sqlite3_close(m_db);
+        return 1;
+    }
+
+    LOGINFO(L"ImgDB Opened.");
+
+    return 0;
+}
+
+int TskImgDBSqlite::addToolInfo(const char* name, const char* version)
+{
+    char *errmsg;
+    char stmt[1024];
+
+    if (!m_db)
+        return 1;
+
+    sqlite3_snprintf(1024, stmt, 
+        "INSERT INTO db_info (name, version) VALUES ('%q', '%q');",
+        name, version);
+    if (sqlite3_exec(m_db, stmt, NULL, NULL, &errmsg) != SQLITE_OK)
+    {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::addToolInfo - Error adding data to db_info table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    return 0;
+}
+
+int TskImgDBSqlite::addImageInfo(int type, int size)
+{
+    char *errmsg;
+    std::stringstream stmt;
+
+    if (!m_db)
+        return 1;
+
+    stmt << "INSERT INTO image_info (type, ssize) VALUES ("<< type << ", " << size << ");";
+    if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, &errmsg) != SQLITE_OK)
+    {
+        std::wstringstream infoMessage;
+        infoMessage <<  L"TskImgDBSqlite::addImageInfo - Error adding data to image_info table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    return 0;
+}
+
+int TskImgDBSqlite::addImageName(char const *imgPath)
+{
+    char *errmsg;
+    char stmt[1024];
+
+    if (!m_db)
+        return 1;
+
+    sqlite3_snprintf(1024, stmt,
+        "INSERT INTO image_names (seq, name) VALUES (NULL, '%q')",
+        imgPath);
+    if (sqlite3_exec(m_db, stmt, NULL, NULL, &errmsg) != SQLITE_OK)
+    {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::addImageName - Error adding data to image_names table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+    return 0;
+}
+
+/*
+ * Adds the sector addresses of the volumes into the db.
+ */
+int TskImgDBSqlite::addVolumeInfo(const TSK_VS_PART_INFO * vs_part)
+{
+    char stmt[1024];
+    char * errmsg;
+
+    if (!m_db)
+        return 1;
+
+    sqlite3_snprintf(1024, stmt,
+        "INSERT INTO vol_info (vol_id, sect_start, sect_len, description, flags) VALUES (%d,%"
+        PRIuOFF ",%" PRIuOFF ",'%q',%d)", (int)vs_part->addr,
+        vs_part->start, vs_part->len, vs_part->desc, vs_part->flags);
+
+    if (sqlite3_exec(m_db, stmt, NULL, NULL, &errmsg) != SQLITE_OK) {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::addVolumeInfo - Error adding data to vol_info table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    return 0;
+}
+
+int TskImgDBSqlite::addFsInfo(int volId, int fsId, const TSK_FS_INFO * fs_info)
+{
+    std::stringstream stmt;
+    char * errmsg;
+
+    if (!m_db)
+        return 1;
+
+    stmt <<
+        "INSERT INTO fs_info (fs_id, img_byte_offset, vol_id, fs_type, block_size, "
+        "block_count, root_inum, first_inum, last_inum) VALUES (" << 
+        fsId << ", " << fs_info->offset << ", " <<  volId << ", " << 
+        (int)fs_info->ftype << ", " <<  fs_info->block_size << ", " <<  fs_info->block_count << ", " << 
+        fs_info->root_inum << ", " <<  fs_info->first_inum << ", " <<  fs_info->last_inum << ")";
+
+    if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::addFsInfo - Error adding data to fs_info table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    return 0;
+}
+
+
+/**
+ * Given a file system and fs_file_id, return the file_id.
+ */
+uint64_t TskImgDBSqlite::getFileId(int a_fsId, uint64_t a_fsFileId) const
+{
+    if (!m_db)
+        return 0;
+
+    sqlite3_stmt * statement;
+    std::stringstream stmt;
+    uint64_t fileId = 0;
+    stmt << "SELECT file_id FROM fs_files WHERE fs_id=" << a_fsId << " and fs_file_id=" << a_fsFileId << ";";
+
+    /********** FIND the unallocated volumes *************/
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        int result = sqlite3_step(statement);
+        if (result == SQLITE_ROW) {
+            fileId = (uint64_t)sqlite3_column_int64(statement, 0);
+        }
+        sqlite3_finalize(statement);
+    }
+    else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getFileId - Error querying fs_files table: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+
+        return 0;
+    }
+    return fileId;
+}
+
+
+int TskImgDBSqlite::getFileRecord(const uint64_t fileId, TskFileRecord& fileRecord) const
+{
+    if (!m_db)
+        return -1;
+
+    int ret = 0;
+
+    sqlite3_stmt * statement;
+    std::stringstream stmt;
+
+    stmt << "SELECT f.file_id, f.type_id, f.name, f.par_file_id, f.dir_type, f.meta_type, f.dir_flags, "
+        << "f.meta_flags, f.size, f.ctime, f.crtime, f.atime, f.mtime, f.mode, f.uid, f.gid, f.status, f.full_path, "
+        << "fh.md5, fh.sha1, fh.sha2_256, fh.sha2_512 "
+        << "FROM files f LEFT OUTER JOIN file_hashes fh ON f.file_id = fh.file_id WHERE f.file_id=" << fileId;
+
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) 
+    {
+        int result = sqlite3_step(statement);
+
+        if (result == SQLITE_ROW) 
+        {
+            fileRecord.fileId       = sqlite3_column_int64(statement, 0);
+            fileRecord.typeId = (TskImgDB::FILE_TYPES)sqlite3_column_int(statement, 1);
+            fileRecord.name         = (char *)sqlite3_column_text(statement, 2);
+            fileRecord.parentFileId = sqlite3_column_int64(statement, 3);
+            fileRecord.dirType = (TSK_FS_NAME_TYPE_ENUM) sqlite3_column_int(statement, 4);
+            fileRecord.metaType = (TSK_FS_META_TYPE_ENUM) sqlite3_column_int(statement, 5);
+            fileRecord.dirFlags = (TSK_FS_NAME_FLAG_ENUM) sqlite3_column_int(statement, 6);
+            fileRecord.metaFlags = (TSK_FS_META_FLAG_ENUM) sqlite3_column_int(statement, 7);
+            fileRecord.size         = sqlite3_column_int64(statement, 8);
+            fileRecord.ctime        = sqlite3_column_int(statement, 9);
+            fileRecord.crtime       = sqlite3_column_int(statement, 10);
+            fileRecord.atime        = sqlite3_column_int(statement, 11);
+            fileRecord.mtime        = sqlite3_column_int(statement, 12);
+            fileRecord.mode = (TSK_FS_META_MODE_ENUM)sqlite3_column_int(statement, 13);
+            fileRecord.uid          = sqlite3_column_int(statement, 14);
+            fileRecord.gid          = sqlite3_column_int(statement, 15);
+            fileRecord.status = (TskImgDB::FILE_STATUS) sqlite3_column_int(statement, 16);
+            fileRecord.fullPath     = (char *)sqlite3_column_text(statement, 17);
+
+            if (sqlite3_column_type(statement, 18) == SQLITE_TEXT)
+                fileRecord.md5      = (char *)sqlite3_column_text(statement, 18);
+            if (sqlite3_column_type(statement, 19) == SQLITE_TEXT)
+                fileRecord.sha1     = (char *)sqlite3_column_text(statement, 19);
+            if (sqlite3_column_type(statement, 20) == SQLITE_TEXT)
+                fileRecord.sha2_256 = (char *)sqlite3_column_text(statement, 20);
+            if (sqlite3_column_type(statement, 21) == SQLITE_TEXT)
+                fileRecord.sha2_512 = (char *)sqlite3_column_text(statement, 21);
+        }
+        else 
+        {
+            std::wstringstream msg;
+            msg << L"TskImgDBSqlite::getFileRecord - Error querying files table for file id: " << fileId;
+            LOGERROR(msg.str());
+
+            ret = -1;
+        }
+        sqlite3_finalize(statement);
+    }
+    else 
+    {
+        std::wstringstream msg;
+        msg << L"TskImgDBSqlite::getFileRecord - Error querying files table for file id: " << fileId;
+        LOGERROR(msg.str());
+
+        ret = -1;
+    }
+
+    return ret;
+}
+
+int TskImgDBSqlite::addFsFileInfo(int fileSystemID, const TSK_FS_FILE *fileSystemFile, const char *fileName, int fileSystemAttrType, int fileSystemAttrID, uint64_t &fileID, const char *filePath)
+{
+    const std::string msgPrefix = "TskImgDBSqlite::addFsFileInfo : ";
+    fileID = 0;
+
+    if (!m_db)
+    {
+        return -1;
+    }
+
+    // Construct the full path of the file within the image.
+    std::string fullpath(filePath);
+    fullpath.append(fileName);
+
+    // Replace all single quotes in the file name with double single quotes to comply with SQLLite syntax.
+    std::string fileNameAsString(fileName);
+    size_t found = fileNameAsString.find("'");
+    if (found != std::string::npos) //Replace it and replace all its subsequent occurrences.
+    {
+        fileNameAsString.replace(found,1,"''");
+
+        while ((found=fileNameAsString.find("'", found+2)) != std::string::npos)// found+2 because we want to move past the newly inserted single quote.
+        {
+            fileNameAsString.replace(found,1,"''");
+        }
+    }
+
+    // Now remove all the control characters from the file name.
+    for (int codePoint=1; codePoint < 32; codePoint++)
+    {
+        char codePointAsHex[10];
+        codePointAsHex[0] = codePoint;
+        codePointAsHex[1] = '\0';
+        std::string stringToRemove(codePointAsHex);
+
+        found = fileNameAsString.find(stringToRemove);
+        if (found != std::string::npos) //Replace it and replace all its subsequent occurrences.
+        {
+            fileNameAsString.replace(found,1,"");
+
+            while ((found=fileNameAsString.find(stringToRemove,found+1)) != std::string::npos)// found+1 because the control characters are just 1 character.
+            {
+                fileNameAsString.replace(found,1,"");
+            }
+        }
+    }
+
+    fileName = fileNameAsString.c_str();
+
+    // Get the file size.
+    TSK_OFF_T size = 0; 
+    const TSK_FS_ATTR *fileSystemAttribute = tsk_fs_file_attr_get_id(const_cast<TSK_FS_FILE*>(fileSystemFile), fileSystemAttrID); 
+    if (fileSystemAttribute)
+    {
+        size = fileSystemAttribute->size;
+    }
+
+    // Get the file metadata, if it's available.
+    int mtime = 0;
+    int crtime = 0;
+    int ctime = 0;
+    int atime = 0;
+    int meta_type = 0;
+    int meta_flags = 0;
+    int meta_mode = 0;
+    int gid = 0;
+    int uid = 0;
+    if (fileSystemFile->meta) 
+    {
+        mtime = static_cast<int>(fileSystemFile->meta->mtime);
+        atime = static_cast<int>(fileSystemFile->meta->atime);
+        ctime = static_cast<int>(fileSystemFile->meta->ctime);
+        crtime = static_cast<int>(fileSystemFile->meta->crtime);
+        meta_type = fileSystemFile->meta->type;
+        meta_flags = fileSystemFile->meta->flags;
+        meta_mode = fileSystemFile->meta->mode;
+        gid = fileSystemFile->meta->gid;
+        uid = fileSystemFile->meta->uid;
+    }
+
+    // Insert into the files table.
+    char stmt[4096];
+    sqlite3_snprintf(4096, stmt,
+        "INSERT INTO files (file_id, type_id, status, name, par_file_id, dir_type, meta_type, "
+        "dir_flags, meta_flags, size, crtime, ctime, atime, mtime, mode, gid, uid, full_path) VALUES (NULL, %d, %d,"
+        "'%q',%llu,%d,%d,%d,%d,%" PRIuOFF",%d,%d,%d,%d,%d,%d,%d,'%q')", 
+        IMGDB_FILES_TYPE_FS, IMGDB_FILES_STATUS_READY_FOR_ANALYSIS, fileName, 
+        findParObjId(fileSystemFile, fileSystemID), 
+        fileSystemFile->name->type, meta_type,
+        fileSystemFile->name->flags, meta_flags, size, crtime, ctime, atime,
+        mtime, meta_mode, gid, uid, fullpath.c_str());
+    char *errmsg;
+    if (sqlite3_exec(m_db, stmt, NULL, NULL, &errmsg) != SQLITE_OK) 
+    {
+        std::ostringstream msg;
+        msg << msgPrefix << "Error adding data to files table: " << errmsg;
+        LOGERROR(msg.str());
+
+        sqlite3_free(errmsg);
+        return -1;
+    }
+
+    // Get the file_id from the last insert.
+    fileID = sqlite3_last_insert_rowid(m_db);
+
+    // Insert into the fs_files table.
+    sqlite3_snprintf(4096, stmt,
+        "INSERT INTO fs_files (file_id, fs_id, fs_file_id, attr_type, attr_id) VALUES (%llu,%d,%"
+        PRIuINUM ",%d,%d)", fileID, fileSystemID, fileSystemFile->name->meta_addr, fileSystemAttrType, fileSystemAttrID);
+
+    if (sqlite3_exec(m_db, stmt, NULL, NULL, &errmsg) != SQLITE_OK) 
+    {
+        std::ostringstream msg;
+        msg << msgPrefix << "Error adding data to fs_files table: " << errmsg;
+        LOGERROR(msg.str());
+
+        sqlite3_free(errmsg);
+        return -1;
+    }
+
+    //if dir, update parent id cache
+    if (meta_type == TSK_FS_META_TYPE_DIR) {
+        storeParObjId(fileSystemID, fileSystemFile, fileID);
+    }
+
+    return 0;
+}
+
+/**
+ * Add block info to the database.  This table stores the run information for each file so that we
+ * can map which blocks are used by what files.
+ * @param a_fsId Id that the file is located in
+ * @param a_fileId ID of the file
+ * @param a_sequence The sequence number of this run in the file (0 for the first run, 1 for the second run, etc.)
+ * @param a_blk_addr Block address (the address that the file system uses -- NOT the physical sector addr)
+ * @param a_len The number of blocks in the run
+ * @returns 1 on error
+ */
+int TskImgDBSqlite::addFsBlockInfo(int a_fsId, uint64_t a_fileId, int a_sequence, uint64_t a_blk_addr, uint64_t a_len)
+{
+    std::stringstream stmt;
+    char * errmsg;
+
+    if (!m_db)
+        return 1;
+
+    stmt <<
+        "INSERT INTO fs_blocks (fs_id, file_id, seq, blk_start, blk_len) VALUES (" <<
+        a_fsId << "," << a_fileId << "," << a_sequence << "," << a_blk_addr << "," <<  a_len << ")";
+
+    if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::addFsBlockInfo - Error adding data to fs_blocks table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    return 0;
+}
+
+int TskImgDBSqlite::addAllocUnallocMapInfo(int a_volID, int unallocImgID, 
+                                           uint64_t unallocImgStart, uint64_t length, uint64_t origImgStart)
+{
+    std::stringstream stmt;
+    char * errmsg;
+
+    if (!m_db)
+        return 1;
+
+    stmt <<
+        "INSERT INTO alloc_unalloc_map (vol_id, unalloc_img_id, unalloc_img_sect_start, "
+        "sect_len, orig_img_sect_start) VALUES (" <<
+        a_volID << "," << unallocImgID << "," << 
+        unallocImgStart << "," << length << "," <<  origImgStart << ")";
+
+    if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::addAllocUnallocMapInfo - Error adding data to alloc_unalloc_map table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    return 0;
+}
+
+/**
+ * Get information on all of the free sectors in an image.
+ *
+ * @return Info on unallocated runs (or NULL on error).  Caller must free this when done.
+ */
+SectorRuns * TskImgDBSqlite::getFreeSectors() const
+{
+    std::stringstream infoMessage;
+    std::stringstream msg;
+
+    if (!m_db)
+        return NULL;
+
+    SectorRuns * sr = new SectorRuns();
+
+    LOGINFO("TskImgDBSqlite::getFreeSectors - Identifying Unallocated Sectors");
+
+    sqlite3_stmt * statement;
+
+    /********** FIND the unallocated volumes *************/
+    if (sqlite3_prepare_v2(m_db,
+        "SELECT vol_id, sect_start, sect_len, flags FROM vol_info;",
+        -1, &statement, 0) == SQLITE_OK) {
+            while(true) {
+                int result = sqlite3_step(statement);
+                if (result == SQLITE_ROW) {
+                    int flags = sqlite3_column_int(statement, 3);
+
+                    int vol_id = sqlite3_column_int(statement,0);
+                    int64_t start = sqlite3_column_int64(statement,1);
+                    int64_t len = sqlite3_column_int64(statement,2);
+
+                    // add the unallocated volumes
+                    if (flags & TSK_VS_PART_FLAG_UNALLOC) {
+                        sr->addRun(start, len, vol_id);
+                    }
+                    // add the allocated volumes that don't have a known file system
+                    else {
+                        std::stringstream stmt;
+                        sqlite3_stmt *statement2;
+                        stmt << "SELECT fs_id FROM fs_info WHERE vol_id = " << vol_id << ";";
+                        if (sqlite3_prepare_v2(m_db, stmt.str().c_str() , -1, &statement2, 0) == SQLITE_OK) {
+                            if (sqlite3_step(statement2) != SQLITE_ROW) {
+                                sr->addRun(start, len, vol_id);
+                            }
+                            sqlite3_finalize(statement2);
+                        }
+                    }
+                }
+                else {
+                    break;  
+                }
+            }
+            sqlite3_finalize(statement);
+    }
+    else {
+        infoMessage << "TskImgDBSqlite::getFreeSectors - Error querying vol_info table: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+
+        return NULL;
+    }
+
+    /*************** Find the unallocated blocks in each file system *************/
+    // @@@ Need to make more dynamic
+    int blk_size[32];
+    memset(blk_size, 0, sizeof(blk_size));
+    uint64_t blk_count[32];
+    memset(blk_count, 0, sizeof(blk_count));
+    int vol_id[32];
+    uint64_t img_offset[32];
+
+    // get basic info on each file system
+    if (sqlite3_prepare_v2(m_db, "SELECT fs_id, vol_id, img_byte_offset, block_size, block_count FROM fs_info;", -1, &statement, 0) == SQLITE_OK) {
+        LOGINFO("TskImgDBSqlite::getFreeSectors - START LOOP: Find the unallocated blocks in each file system.");
+        while(true)
+        {
+            int result = sqlite3_step(statement);
+            if (result == SQLITE_ROW)
+            {
+                int fs_id = sqlite3_column_int(statement, 0);
+                if (fs_id > 32)
+                {
+                    infoMessage.str("");
+                    infoMessage << "TskImgDBSqlite::getFreeSectors - fs_id in fs_info is bigger than 32: " << fs_id;
+                    LOGERROR(infoMessage.str());
+                    break;
+                }
+                vol_id[fs_id] = sqlite3_column_int(statement, 1);
+                img_offset[fs_id] = sqlite3_column_int64(statement, 2) / 512;
+                blk_size[fs_id] = sqlite3_column_int(statement, 3) / 512;
+                blk_count[fs_id] = sqlite3_column_int64(statement, 4);
+                // Debug Info
+                msg.str("");
+                msg << "TskImgDBSqlite::getFreeSectors - fs_id=" << fs_id << " vol_id=" << vol_id[fs_id] << " img_offset=" << img_offset[fs_id] << " blk_size=" << blk_size[fs_id] <<
+                    " blk_count=" << blk_count[fs_id];
+                LOGINFO(msg.str().c_str());
+            }
+            else
+            {
+                break;
+            }
+        }
+        sqlite3_finalize(statement);
+        LOGINFO("TskImgDBSqlite::getFreeSectors - DONE: Find the unallocated blocks in each file system.");
+    }
+    else
+    {
+        infoMessage.str("");
+        infoMessage << "TskImgDBSqlite::getFreeSectors - Error querying fs_info table: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+
+        return NULL;
+    }
+
+    // see what blocks have been used and add them to a list
+    TSK_LIST *seen[32];
+    memset(seen, 0, 32*sizeof(TSK_LIST *));
+
+    if (sqlite3_prepare_v2(m_db, "SELECT fs_id, file_id, blk_start, blk_len FROM fs_blocks;", -1, &statement, 0) == SQLITE_OK) {
+        LOGINFO("TskImgDBSqlite::getFreeSectors - START LOOP: see what blocks have been used and add them to a list.");
+        while(true) {
+            int result = sqlite3_step(statement);
+            if (result == SQLITE_ROW) {
+                int fs_id = sqlite3_column_int(statement, 0);
+                if (fs_id > 32) {
+                    infoMessage.str("");
+                    infoMessage << "TskImgDBSqlite::getFreeSectors - fs_id in fs_info is bigger than 32: " << fs_id;
+                    LOGERROR(infoMessage.str());
+                    continue;
+                }
+                uint64_t file_id = (uint64_t)sqlite3_column_int64(statement, 1);
+                int64_t addr = sqlite3_column_int64(statement, 2);
+                int64_t len = sqlite3_column_int64(statement, 3);
+
+                // We only want to consider the runs for files that we allocated.
+                std::stringstream stmt;
+                stmt << "SELECT meta_flags from files WHERE file_id=" << file_id;
+
+                sqlite3_stmt * statement2;
+                if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement2, 0) != SQLITE_OK) {
+                    infoMessage.str("");
+                    infoMessage << "TskImgDBSqlite::getFreeSectors - error finding flags for file " << file_id;
+                    LOGERROR(infoMessage.str());
+                    continue;
+                }
+                sqlite3_step(statement2);
+                int flags = sqlite3_column_int(statement2, 0);
+                sqlite3_finalize(statement2);
+
+                if (flags & TSK_FS_META_FLAG_UNALLOC)
+                    continue;
+
+                // @@@ We can probably find a more effecient storage method than this...
+                int error = 0;
+                for (int64_t i = 0; i < len; i++) {
+                    if (tsk_list_add(&seen[fs_id], addr+i)) {
+                        infoMessage.str("");
+                        infoMessage << "TskImgDBSqlite::getFreeSectors - Error adding seen block address to list";
+                        LOGERROR(infoMessage.str());
+
+                        error = 1;
+                        break;
+                    }
+                }
+                if (error)
+                    break;
+            }
+            else {
+                break;
+            }
+        }
+        sqlite3_finalize(statement);
+        LOGINFO("TskImgDBSqlite::getFreeSectors - DONE: see what blocks have been used and add them to a list.");
+    }
+    else {
+        infoMessage.str("");
+        infoMessage << "TskImgDBSqlite::getFreeSectors - Error querying fs_block table: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+
+        return NULL;
+    }
+
+    // cycle through each file system to find the unused blocks
+    LOGINFO("TskImgDBSqlite::getFreeSectors - START LOOP: cycle through each file system to find the unused blocks.");
+    for (int f = 0; f < 32; f++) {
+        if (blk_count[f] == 0)
+            continue;
+
+        uint64_t st = 0;
+        int len = 0;
+        // we previously adjusted blk_size and img_offset to be in sectors
+
+        msg.str("");
+        msg << "blk_count[" << f << "]=" << blk_count[f];
+        LOGINFO(msg.str().c_str());
+
+        for (uint64_t a = 0; a < blk_count[f]; a++) {
+            // see if this addr was used in a file
+            if (tsk_list_find(seen[f], a) == 0) {
+                // we already have a run being defined
+                if (len) {
+                    // same run, so add on to it
+                    if (st + len == a) {
+                        len++;
+                    }
+                    // different run, make a new one
+                    else {
+                        sr->addRun(img_offset[f]+st*blk_size[f], len*blk_size[f], vol_id[f]);
+                        st = a;
+                        len = 1;
+                    }
+                }
+                // start a new run
+                else {
+                    st = a;
+                    len = 1;
+                }
+            }
+        }
+        // add the final run
+        if (len) {
+            sr->addRun(img_offset[f]+st*blk_size[f], len*blk_size[f], vol_id[f]);
+        }
+        tsk_list_free(seen[f]);
+        seen[f] = NULL;
+    }
+    LOGINFO("TskImgDBSqlite::getFreeSectors - DONE: cycle through each file system to find the unused blocks.");
+
+    return sr;
+}
+
+std::string TskImgDBSqlite::getImageBaseName() const
+{
+    // There may be multiple file paths if the image is a split image. Oreder by sequence number to extract the file name from the first path.
+    sqlite3_stmt *statement;
+    executeStatement("SELECT name FROM image_names ORDER BY seq;", statement, "TskImgDBSqlite::getImageBaseName");
+
+    int result = sqlite3_step(statement);
+    if (result == SQLITE_ROW) 
+    {
+        Poco::Path imagePath(reinterpret_cast<const char*>(sqlite3_column_text(statement, 0))); // Reinterpret from const unsigned char*
+        return imagePath.getFileName();
+    }
+    else
+    {
+        return "";
+    }
+}
+
+std::vector<std::wstring> TskImgDBSqlite::getImageNamesW() const
+{
+    std::vector<std::wstring> imgList;
+
+    if (!m_db)
+        return imgList;
+
+    sqlite3_stmt *statement;
+
+    if (sqlite3_prepare_v2(m_db, "SELECT name FROM image_names ORDER BY seq;",
+        -1, &statement, 0) == SQLITE_OK) 
+    {
+        while(true)
+        {
+            int result = sqlite3_step(statement);
+            if (result == SQLITE_ROW) {
+                imgList.push_back((wchar_t *)sqlite3_column_text16(statement, 0));
+            }
+            else {
+                break;
+            }
+        }
+
+        sqlite3_finalize(statement);
+    }
+
+    return imgList;
+}
+
+
+std::vector<std::string> TskImgDBSqlite::getImageNames() const
+{
+    std::vector<std::string> imgList;
+
+    if (!m_db)
+        return imgList;
+
+    sqlite3_stmt *statement;
+
+    if (sqlite3_prepare_v2(m_db, "SELECT name FROM image_names ORDER BY seq;",
+        -1, &statement, 0) == SQLITE_OK) 
+    {
+        while(true)
+        {
+            int result = sqlite3_step(statement);
+            if (result == SQLITE_ROW) {
+                imgList.push_back((char *)sqlite3_column_text(statement, 0));
+            }
+            else {
+                break;
+            }
+        }
+
+        sqlite3_finalize(statement);
+    }
+
+    return imgList;
+}
+
+
+
+
+/**
+ * @param a_fileId  File id to get information about
+ * @param a_fsOffset Byte offset of start of file system that the file is located in
+ * @param a_fsFileId File system-specific id of the file
+ * @param a_attrType Type of attribute for this file
+ * @param a_attrId The ID of the attribute for this file
+ * @returns -1 on error
+ */
+int TskImgDBSqlite::getFileUniqueIdentifiers(uint64_t a_fileId, uint64_t &a_fsOffset, uint64_t &a_fsFileId, int &a_attrType, int &a_attrId) const
+{
+    if (!m_db)
+        return -1;
+
+    sqlite3_stmt * statement;
+    std::stringstream stmt;
+
+    stmt <<
+        "SELECT fs_file_id, attr_type, attr_id, fs_info.img_byte_offset "
+        "FROM fs_files, fs_info WHERE file_id=" << a_fileId << " AND fs_info.fs_id = fs_files.fs_id;";
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        int result = sqlite3_step(statement);
+        if (result == SQLITE_ROW) {
+            a_fsFileId = sqlite3_column_int64(statement, 0);
+            a_attrType = sqlite3_column_int(statement, 1);
+            a_attrId = sqlite3_column_int(statement, 2);
+            a_fsOffset = sqlite3_column_int64(statement, 3);
+        }
+        else {
+            return -1;
+        }
+        sqlite3_finalize(statement);
+    }
+    else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getFileUniqueIdentifiers - Error querying fs_files table : " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+        return -1;
+    }
+
+    return 0;
+}
+
+/**
+ * Get number of volumes in image.
+ * @return Number of volumes in image or -1 on error
+ */
+int TskImgDBSqlite::getNumVolumes() const
+{
+    if (!m_db)
+        return 0;
+
+    int count = 0;
+    sqlite3_stmt * statement;
+
+    /********** Get the number of volumes *************/
+    if (sqlite3_prepare_v2(m_db, "SELECT count(*) from vol_info;", -1, &statement, 0) == SQLITE_OK) 
+    {
+        int result = sqlite3_step(statement);
+        if (result == SQLITE_ROW) 
+        {
+            count = (int)sqlite3_column_int(statement, 0);
+        }
+        sqlite3_finalize(statement);
+    }
+    else 
+    {
+        std::wstringstream msg;
+        msg << L"TskImgDBSqlite::getNumVolumes - Error querying vol_info table: " << sqlite3_errmsg(m_db);
+        LOGERROR(msg.str());
+
+        return -1;
+    }
+
+    return count;
+}
+/**
+ * Get number of files in image.
+ * @return Number of files in image or -1 on error
+ */
+int TskImgDBSqlite::getNumFiles() const
+{
+    if (!m_db)
+        return 0;
+
+    std::string condition("");
+    return getFileCount(condition);
+}
+
+/**
+ * @returns the session_id or -1 on error.
+ */
+int TskImgDBSqlite::getSessionID() const
+{
+    if (!m_db)
+        return 0;
+
+    sqlite3_stmt * statement;
+    std::string stmt("SELECT version from db_info WHERE name=\"SID\";");
+    int sessionId = -1;
+
+    /********** FIND the unallocated volumes *************/
+    if (sqlite3_prepare_v2(m_db, stmt.c_str(), -1, &statement, 0) == SQLITE_OK) {
+        int result = sqlite3_step(statement);
+        if (result == SQLITE_ROW) {
+            sessionId = (int)sqlite3_column_int(statement, 0);
+        }
+        sqlite3_finalize(statement);
+    }
+    else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getSessionID - Error querying db_info table for Session ID: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+
+        return -1;
+    }
+    return sessionId;
+}
+
+int TskImgDBSqlite::begin()
+{
+    char *errmsg;
+    if (!m_db)
+        return 1;
+
+    if (sqlite3_exec(m_db, "BEGIN", NULL, NULL, &errmsg) != SQLITE_OK) {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::begin - BEGIN Error: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+    return 0;
+}
+
+int TskImgDBSqlite::commit()
+{
+    char *errmsg;
+    if (!m_db)
+        return 1;
+
+    if (sqlite3_exec(m_db, "COMMIT", NULL, NULL, &errmsg) != SQLITE_OK) {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::commit - COMMIT Error: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return 1;
+    }
+    return 0;
+}
+
+UnallocRun * TskImgDBSqlite::getUnallocRun(int a_unalloc_img_id, int a_file_offset) const
+{
+    std::stringstream stmt;
+    char * errmsg;
+    if (!m_db)
+        return NULL;
+
+    stmt << "SELECT vol_id, unalloc_img_sect_start, sect_len, orig_img_sect_start FROM "
+        "alloc_unalloc_map WHERE unalloc_img_id = " << a_unalloc_img_id << 
+        " AND unalloc_img_sect_start <= " << a_file_offset << " ORDER BY unalloc_img_sect_start DESC";
+
+    char **result;
+    int nrow, ncol;
+    if (sqlite3_get_table(m_db, stmt.str().c_str(), &result, &nrow, &ncol, &errmsg) != SQLITE_OK)
+    {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getUnallocRun - Error fetching data from alloc_unalloc_map table: " << errmsg;
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+
+        return new UnallocRun(-1, -1, -1, -1, -1);
+    }
+    else
+    {
+        int vol_id;
+        int unalloc_img_sect_start;
+        int sect_len;
+        int orig_img_sect_start;
+        // skip the headers
+        // @@@ DO SOME ERROR CHECKING HERE to make sure that results has data...
+        sscanf(result[4], "%d", &vol_id);
+        sscanf(result[5], "%d", &unalloc_img_sect_start);
+        sscanf(result[6], "%d", &sect_len);
+        sscanf(result[7], "%d", &orig_img_sect_start);
+        sqlite3_free_table(result);
+        return new UnallocRun(vol_id, a_unalloc_img_id, unalloc_img_sect_start, sect_len, orig_img_sect_start);
+    }
+}
+
+/**
+ * Adds information about a carved file into the database.  This includes the sector layout
+ * information. 
+ * 
+ * @param vol_id Volume in which the carved file was found in
+ * @param name Name of the file 
+ * @param size Number of bytes in file
+ * @param runStarts Array with starting sector (relative to start of image) for each run in file.
+ * @param runLengths Array with number of sectors in each run 
+ * @param numRuns Number of entries in previous arrays
+ * @param fileId Carved file Id (output)
+ * @returns 0 on success or -1 on error.
+ */
+int TskImgDBSqlite::addCarvedFileInfo(int vol_id, const char *name, uint64_t size, 
+                                      uint64_t *runStarts, uint64_t *runLengths, int numRuns, uint64_t & fileId)
+{
+    char stmt[1024];
+    char * errmsg;
+    std::wstringstream infoMessage;
+
+    if (!m_db)
+        return -1;
+
+    // insert into files table
+    sqlite3_snprintf(1024, stmt,
+        "INSERT INTO files (file_id, type_id, name, par_file_id, dir_type, meta_type,"
+        "dir_flags, meta_flags, size, ctime, crtime, atime, mtime, mode, uid, gid, status, full_path) "
+        "VALUES (NULL, %d, '%q', NULL, %d, %d, %d, %d, %llu, 0, 0, 0, 0, NULL, NULL, NULL, %d, '%q')",
+        IMGDB_FILES_TYPE_CARVED, name, (int)TSK_FS_NAME_TYPE_REG, (int)TSK_FS_META_TYPE_REG,
+        (int)TSK_FS_NAME_FLAG_UNALLOC, (int)TSK_FS_META_FLAG_UNALLOC, size, IMGDB_FILES_STATUS_CREATED, name);
+    // MAY-118 NOTE: addCarvedFileInfo insert entry into files table, but actual file on disk has not been created yet.
+    if (sqlite3_exec(m_db, stmt, NULL, NULL, &errmsg) != SQLITE_OK) {
+        infoMessage << L"TskImgDBSqlite::addCarvedFileInfo - Error adding data to file table for carved file: " << errmsg << L" " << stmt;
+
+        LOGERROR(infoMessage.str());
+
+        sqlite3_free(errmsg);
+        return -1;
+    }
+
+    // get the assigned file_id
+    fileId = (uint64_t)sqlite3_last_insert_rowid(m_db);
+
+    // insert into the carved_files_table
+    sqlite3_snprintf(1024, stmt, "INSERT INTO carved_files (file_id, vol_id)"
+        "VALUES (%llu, %d)", fileId, vol_id);
+    if (sqlite3_exec(m_db, stmt, NULL, NULL, &errmsg) != SQLITE_OK) {
+        infoMessage << L"TskImgDBSqlite::addCarvedFileInfo - Error adding data to carved_files table: " << errmsg;
+
+        LOGERROR(infoMessage.str());
+        sqlite3_free(errmsg);
+        return -1;
+    }
+
+    // insert into carved_sectors table
+    for (int i = 0; i < numRuns; i++)
+    {
+        sqlite3_snprintf(1023, stmt,
+            "INSERT INTO carved_sectors (file_id, seq, sect_start, sect_len) "
+            "VALUES (%llu, %d, %llu, %llu)",
+            fileId, i, runStarts[i], runLengths[i]);
+        if (sqlite3_exec(m_db, stmt, NULL, NULL, &errmsg) != SQLITE_OK) {
+            infoMessage << L"TskImgDBSqlite::addCarvedFileInfo - Error adding data to carved_sectors table: " << errmsg;
+
+            LOGERROR(infoMessage.str());
+
+            sqlite3_free(errmsg);
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+/**
+ * Adds information about derived files to the database.  Derived files typically come
+ * from archives and may be compressed.
+ * 
+ * @param name The name of the file.
+ * @param parentId The id of the file from which this file is derived.
+ * @param isDirectory True if entry is for a directory verus a file
+ * @param size The size of the file.
+ * @param details This is a string that may contain extra details related
+ * to the particular type of mechanism that was used to derive this file, 
+ * e.g. files derived from zip archives may have extra information about the
+ * compressed size of the file.
+ * @param ctime Time file system file entry was changed.
+ * @param crtime Time the file was created.
+ * @param atime Last access time.
+ * @param mtime Last modified time.
+ * @param fileId Reference to location where file_id for file can be assigned
+ * @param path Path of file
+ *
+ * @returns 0 on success or -1 on error.
+ */
+int TskImgDBSqlite::addDerivedFileInfo(const std::string& name, const uint64_t parentId, 
+                                       const bool isDirectory, const uint64_t size,
+                                       const std::string& details,
+                                       const int ctime, const int crtime, const int atime, const int mtime,
+                                       uint64_t &fileId, std::string path)
+{
+    if (!m_db)
+        return -1;
+
+    char stmt[1024];
+    char * errmsg;
+
+    TSK_FS_NAME_TYPE_ENUM dirType = isDirectory ? TSK_FS_NAME_TYPE_DIR : TSK_FS_NAME_TYPE_REG;
+    TSK_FS_META_TYPE_ENUM metaType = isDirectory ? TSK_FS_META_TYPE_DIR : TSK_FS_META_TYPE_REG;
+
+    // insert into files table
+    sqlite3_snprintf(1024, stmt,
+        "INSERT INTO files (file_id, type_id, name, par_file_id, dir_type, meta_type, size, ctime, crtime, atime, mtime, status, full_path) "
+        "VALUES (NULL, %d, '%q', %llu, %d, %d, %llu, %d, %d, %d, %d, %d, '%q')",
+        IMGDB_FILES_TYPE_DERIVED, name.c_str(), parentId, dirType, metaType, size, ctime, crtime, atime, mtime, IMGDB_FILES_STATUS_CREATED, path.c_str());
+
+    if (sqlite3_exec(m_db, stmt, NULL, NULL, &errmsg) != SQLITE_OK) 
+    {
+        std::wstringstream msg;
+        msg << L"TskImgDBSqlite::addDerivedFileInfo - Error adding data to file table for derived file: "
+            << errmsg << L" " << stmt;
+
+        LOGERROR(msg.str());
+
+        sqlite3_free(errmsg);
+        return -1;
+    }
+
+    // get the assigned file_id
+    fileId = sqlite3_last_insert_rowid(m_db);
+
+    // insert into the derived_files table
+    sqlite3_snprintf(1024, stmt, "INSERT INTO derived_files (file_id, derivation_details) "
+        "VALUES (%llu, '%q')", fileId, details.c_str());
+    if (sqlite3_exec(m_db, stmt, NULL, NULL, &errmsg) != SQLITE_OK) 
+    {
+        std::wstringstream msg;
+        msg << L"TskImgDBSqlite::addDerivedFileInfo - Error adding data to derived_files table : "
+            << errmsg;
+
+        LOGERROR(msg.str());
+        sqlite3_free(errmsg);
+        return -1;
+    }
+
+    return 0;
+}
+
+/**
+ * Fills outBuffer with file IDs that match the name fileName.
+ * Returns the number of file IDs written into outBuffer or -1 on error.
+ */
+int TskImgDBSqlite::getFileIds(char *a_fileName, uint64_t *a_outBuffer, int a_buffSize) const
+{
+
+    if (!m_db)
+        return -1;
+
+    int outIdx = 0;
+
+    sqlite3_stmt * statement;
+    std::stringstream stmt;
+    stmt << "SELECT file_id FROM files WHERE name LIKE '" << a_fileName << "';";
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        while(sqlite3_step(statement) == SQLITE_ROW) {
+            a_outBuffer[outIdx++] = (uint64_t)sqlite3_column_int64(statement, 0);
+        }
+        sqlite3_finalize(statement);
+    }
+    else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getFileIds - Error querying files table : " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+        return -1;
+    }
+
+    return outIdx;
+}
+
+/*
+ * Return the minimum file id with status = READY_FOR_ANALYSIS in minFileId.
+ * Return 0 on success, -1 if failed.
+ */
+int TskImgDBSqlite::getMinFileIdReadyForAnalysis(uint64_t & minFileId) const
+{
+    if (!m_db)
+        return -1;
+
+    minFileId = 0;
+
+    sqlite3_stmt * statement;
+    std::stringstream stmt;
+    stmt << "SELECT min(file_id) FROM files WHERE status = " << 
+        TskImgDB::IMGDB_FILES_STATUS_READY_FOR_ANALYSIS << ";";
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        int result = sqlite3_step(statement);
+        if (result == SQLITE_ROW) {
+            minFileId = (uint64_t)sqlite3_column_int64(statement, 0);
+        }
+        sqlite3_finalize(statement);
+    }
+    else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getMinFileIdReadyForAnalysis - Error querying files table : " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+        return -1;
+    }
+    return 0;
+}
+
+/**
+ * Given the last file ID ready for analysis, find the largest file ID ready of analysis (in maxFileId)
+ * Returns 0 on success or -1 on error.
+ */
+int TskImgDBSqlite::getMaxFileIdReadyForAnalysis(uint64_t a_lastFileId, uint64_t & maxFileId) const
+{
+    if (!m_db)
+        return -1;
+
+    maxFileId = 0;
+
+    sqlite3_stmt * statement;
+    std::stringstream stmt;
+    stmt << "SELECT max(file_id) FROM files WHERE status = " <<  
+        TskImgDB::IMGDB_FILES_STATUS_READY_FOR_ANALYSIS << 
+        " AND file_id >= " <<  a_lastFileId << ";";
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        int result = sqlite3_step(statement);
+        if (result == SQLITE_ROW) {
+            maxFileId = (uint64_t)sqlite3_column_int64(statement, 0);
+        }
+        sqlite3_finalize(statement);
+    }
+    else {
+        std::wstringstream infoMessage;
+        infoMessage <<  L"TskImgDBSqlite::getMaxFileIdReadyForAnalysis - Error querying files table : " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+        return -1;
+    }
+    return 0;
+}
+
+SectorRuns * TskImgDBSqlite::getFileSectors(uint64_t a_fileId) const
+{
+    if (!m_db)
+        return NULL;
+
+    SectorRuns * sr = new SectorRuns();
+
+    sqlite3_stmt * statement;
+    std::stringstream stmt;
+    int srCount = 0;
+    stmt <<
+        "SELECT fs_blocks.blk_start, fs_blocks.blk_len, "
+        "fs_info.block_size, fs_info.img_byte_offset, fs_info.vol_id "
+        "FROM files "
+        "JOIN fs_files ON files.file_id = fs_files.file_id "
+        "JOIN fs_blocks ON files.file_id = fs_blocks.file_id "
+        "JOIN fs_info ON fs_blocks.fs_id = fs_info.fs_id "
+        "WHERE files.file_id = " << a_fileId << " "
+        "ORDER BY fs_blocks.seq;";
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        while(sqlite3_step(statement) == SQLITE_ROW) {
+            uint64_t blkStart = (uint64_t)sqlite3_column_int64(statement, 0);
+            uint64_t blkLength = (uint64_t)sqlite3_column_int64(statement, 1);
+            int blkSize = sqlite3_column_int(statement, 2);
+            uint64_t imgByteOffset = (uint64_t)sqlite3_column_int64(statement, 3);
+            int volId = sqlite3_column_int(statement, 4);
+
+            uint64_t start = (imgByteOffset + blkStart * blkSize) / 512;
+            uint64_t len = (blkLength * blkSize) / 512;
+
+            sr->addRun(start, len, volId);
+            srCount++;
+        }
+
+        sqlite3_finalize(statement);
+    }
+    else {
+        std::wstringstream infoMessage;
+        infoMessage <<
+            L"TskImgDBSqlite::getFileSectors - "
+            L"Error finding block data for file_id=" << a_fileId << ": " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+        return NULL;
+    }
+
+    if (srCount < 1) {
+        delete sr;
+        sr = NULL;
+    }
+    return sr;
+}
+
+/**
+ * This callback mechanism is registered with SQLite and is 
+ * called whenever an operation would result in SQLITE_BUSY.
+ * Each time this method is called we will back off IMGDB_RETRY_WAIT
+ * x count milliseconds. A non zero return value tells SQLite to 
+ * retry the statement and a zero return value tells SQLite to 
+ * stop retrying, in which case it will return SQLITE_BUSY or
+ * SQLITE_IOERR_BLOCKED to the caller.
+ *
+ * @param pDB - a pointer to the sqlite3 structure
+ * @param count - the number of times this handler has been
+ * called for this blocking event.
+ */
+int TskImgDBSqlite::busyHandler(void * pDB, int count)
+{
+    if (count < IMGDB_MAX_RETRY_COUNT)
+    {
+        Poco::Thread::sleep(IMGDB_RETRY_WAIT * count);
+        return 1;
+    }
+
+    return 0;
+}
+
+
+
+int TskImgDBSqlite::updateFileStatus(uint64_t a_file_id, FILE_STATUS a_status)
+{
+    if (!m_db)
+        return 1;
+
+    std::stringstream stmt;
+    char * errmsg;
+
+    stmt << "UPDATE files SET status = " << a_status << " WHERE file_id = " << a_file_id << ";";
+    if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::updateFileStatus - Error UPDATE file status: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+        return 1;
+    }
+
+    return 0;
+}
+
+
+int TskImgDBSqlite::updateKnownStatus(uint64_t a_file_id, KNOWN_STATUS a_status)
+{
+    if (!m_db)
+        return 1;
+
+    std::stringstream stmt;
+    char * errmsg;
+
+    stmt << "UPDATE file_hashes SET known = " << a_status << " WHERE file_id = " << a_file_id << ";";
+    if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::updateFileStatus - Error UPDATE file status: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+        return 1;
+    }
+
+    return 0;
+}
+
+bool TskImgDBSqlite::dbExist() const
+{
+    if (m_db)
+        return true;
+    else
+        return false;
+}
+
+void TskImgDBSqlite::getCarvedFileInfo(const std::string& stmt, std::map<uint64_t, std::string>& results) const
+{
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.c_str(), -1, &statement, 0) == SQLITE_OK) 
+    {
+        while (sqlite3_step(statement) == SQLITE_ROW) 
+        {
+            uint64_t fileId = (uint64_t)sqlite3_column_int64(statement, 0);
+            std::string fileName = (char*)sqlite3_column_text(statement, 1);
+            std::string cfileName = (char*)sqlite3_column_text(statement, 2);
+
+            // Grab the extension and append it to the cfile name
+            std::string::size_type pos = fileName.rfind('.');
+            if (pos != std::string::npos)
+                cfileName.append(fileName.substr(pos));
+
+            results[fileId] = cfileName;
+        }
+        sqlite3_finalize(statement);
+    } else 
+    {
+        std::wstringstream msg;
+        msg << L"TskImgDBSqlite::getCarvedFileInfo - Error retrieving carved file details: "
+            << sqlite3_errmsg(m_db);
+        LOGERROR(msg.str());
+    }
+}
+
+std::map<uint64_t, std::string> TskImgDBSqlite::getUniqueCarvedFiles(HASH_TYPE hashType) const
+{
+    if (!m_db)
+        throw TskException("No database.");
+
+    std::map<uint64_t, std::string> results;
+
+    string hash;
+    switch (hashType) {
+    case TskImgDB::MD5:
+        hash = "md5";
+        break;
+    case TskImgDB::SHA1:
+        hash = "sha1";
+        break;
+    case TskImgDB::SHA2_256:
+        hash = "sha2_256";
+        break;
+    case TskImgDB::SHA2_512:
+        hash = "sha2_512";
+        break;
+    default:
+        std::wstringstream msg;
+        msg << L"TskImgDBSqlite::getUniqueCarvedFiles - Unsupported hashType : " << hashType;
+        LOGERROR(msg.str());
+        return results;
+    }
+
+    stringstream stmt;
+    
+    // If hashes have not been calculated return all carved files
+    stmt << "SELECT count(*) FROM file_hashes;";
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) 
+    {
+        if (sqlite3_step(statement) == SQLITE_ROW) 
+        {
+            uint64_t counter = (uint64_t)sqlite3_column_int64(statement, 0);
+            if (counter == 0) 
+            {
+                sqlite3_finalize(statement);
+                stmt.str("");
+                stmt << "select c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' "
+                    << "|| c.file_id from files f, carved_files c, carved_sectors cs "
+                    << "where c.file_id = cs.file_id and cs.seq = 0 and f.file_id = c.file_id order by c.file_id";
+                getCarvedFileInfo(stmt.str(), results);
+                return results;
+            }
+        }
+        sqlite3_finalize(statement);
+    } else 
+    {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getUniqueCarvedFiles - Error getting file_hashes count: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+    }
+
+    stmt.str("");
+
+    // Get the set of files for which the hash has been calculated.
+    stmt << "select c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' "
+        << "|| c.file_id from files f, carved_files c, carved_sectors cs "
+        << "where c.file_id = cs.file_id and cs.seq = 0 and f.file_id = c.file_id and c.file_id in "
+        << "(select min(file_id) from file_hashes where " << hash << " != '' group by " << hash << ") order by c.file_id";
+
+    getCarvedFileInfo(stmt.str(), results);
+
+    // Next get the set of files for which the hash has *not* been calculated.
+    stmt.str("");
+
+    stmt << "select c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' "
+        << "|| c.file_id from files f, carved_files c, carved_sectors cs "
+        << "where c.file_id = cs.file_id and cs.seq = 0 and f.file_id = c.file_id and c.file_id in "
+        << "(select file_id from file_hashes where " << hash << " = '') order by c.file_id";
+
+    getCarvedFileInfo(stmt.str(), results);
+
+    // Finally, add file info for all of the carved files for which there are no hashes of any sort.
+    // All of these files must be included because without hashes there is no way to determine uniqueness.
+    stmt.clear();
+    stmt.str("");
+    stmt << "SELECT c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || c.file_id "
+         << "FROM files f, carved_files c, carved_sectors cs "
+         << "WHERE c.file_id = cs.file_id AND cs.seq = 0 AND f.file_id = c.file_id AND c.file_id NOT IN "
+         << "(SELECT fh.file_id FROM file_hashes fh) ORDER BY c.file_id";
+    getCarvedFileInfo(stmt.str(), results);
+
+    return results;
+}
+
+void TskImgDBSqlite::getCarvedFileInfo(const std::string &query, bool getHash, std::vector<TskCarvedFileInfo> &carvedFileInfos) const
+{
+    sqlite3_stmt *statement;
+    executeStatement(query, statement, "TskImgDBSqlite::getCarvedFileInfo");
+
+    TskCarvedFileInfo info;
+    while (sqlite3_step(statement) == SQLITE_ROW) 
+    {
+        info.fileID = static_cast<uint64_t>(sqlite3_column_int64(statement, 0));
+        std::string fileName = reinterpret_cast<const char*>(sqlite3_column_text(statement, 1)); // Reinterpret from unsigned Char*
+        info.cFileName = reinterpret_cast<const char*>(sqlite3_column_text(statement, 2)); // Reinterpret from unsigned Char*
+        if (getHash)
+        {
+            info.hash = reinterpret_cast<const char*>(sqlite3_column_text(statement, 3));
+        }
+
+        // Append the extension from the original file name to the constructed "cfile" name.
+        std::string::size_type pos = fileName.rfind('.');
+        if (pos != std::string::npos)
+        {
+            info.cFileName.append(fileName.substr(pos));
+        }
+
+        carvedFileInfos.push_back(info);
+    }
+
+    sqlite3_finalize(statement);
+}
+
+std::vector<TskCarvedFileInfo> TskImgDBSqlite::getUniqueCarvedFilesInfo(HASH_TYPE hashType) const
+{
+    const std::string msgPrefix = "TskImgDBSqlite::getUniqueCarvedFilesInfo : "; 
+
+    if (!m_db)
+    {
+        std::ostringstream msg;
+        msg << msgPrefix << "no database connection";
+        throw TskException(msg.str());
+    }
+
+    // Map the requested hash type to a file_hashes table column name.
+    string hash;
+    switch (hashType) 
+    {
+    case TskImgDB::MD5:
+        hash = "md5";
+        break;
+    case TskImgDB::SHA1:
+        hash = "sha1";
+        break;
+    case TskImgDB::SHA2_256:
+        hash = "sha2_256";
+        break;
+    case TskImgDB::SHA2_512:
+        hash = "sha2_512";
+        break;
+    default:
+        std::ostringstream msg;
+        msg << msgPrefix << "unsupported hash type :" << hashType;
+        throw TskException(msg.str());
+    }
+
+    std::vector<TskCarvedFileInfo> carvedFileInfos;
+
+    // Do a quick check to see if any hashes have been calculated.
+    std::ostringstream query;
+    query << "SELECT COUNT(*) FROM file_hashes;";
+    sqlite3_stmt *countStmt;
+    executeStatement(query.str(), countStmt, "TskImgDBSqlite::getUniqueCarvedFiles");
+    if (sqlite3_step(countStmt) == SQLITE_ROW && static_cast<uint64_t>(sqlite3_column_int64(countStmt, 0)) != 0) 
+    {
+        // At least one type of hash has been calculated (presumably for all files, but this is not guaranteed). 
+        // First, add file info for the set of unique files among the carved files for which the specified type of hash is available.
+        query.clear();
+        query.str("");
+        query << "SELECT c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || c.file_id, fh." << hash << " "
+              << "FROM files f, carved_files c, carved_sectors cs, file_hashes fh "
+              << "WHERE c.file_id = cs.file_id AND cs.seq = 0 AND f.file_id = c.file_id AND c.file_id = fh.file_id AND c.file_id IN "
+              << "(SELECT MIN(file_id) FROM file_hashes WHERE " << hash << " != '' GROUP BY " << hash << ") ORDER BY c.file_id";
+        getCarvedFileInfo(query.str(), true, carvedFileInfos);
+
+         // Next, add file info for all of the carved files for which the specified hash is not available.
+         // All of these files must be included because without the specified hash there is no acceptable way to determine uniqueness.
+        query.clear();
+        query.str("");
+        query << "SELECT c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || c.file_id "
+              << "FROM files f, carved_files c, carved_sectors cs "
+              << "WHERE c.file_id = cs.file_id AND cs.seq = 0 AND f.file_id = c.file_id AND c.file_id IN "
+              << "(SELECT file_id FROM file_hashes WHERE " << hash << " = '') ORDER BY c.file_id";
+        getCarvedFileInfo(query.str(), false, carvedFileInfos);
+
+        // Finally, add file info for all of the carved files for which there are no hashes of any sort.
+        // All of these files must be included because without hashes there is no way to determine uniqueness.
+        query.clear();
+        query.str("");
+        query << "SELECT c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || c.file_id "
+              << "FROM files f, carved_files c, carved_sectors cs "
+              << "WHERE c.file_id = cs.file_id AND cs.seq = 0 AND f.file_id = c.file_id AND c.file_id NOT IN "
+              << "(SELECT fh.file_id FROM file_hashes fh) ORDER BY c.file_id";
+        getCarvedFileInfo(query.str(), false, carvedFileInfos);
+    }
+    else
+    {
+        // No hashes have been calculated.
+        // Return carved file info all of the carved files because without hashes there is no way to determine uniqueness.
+        query.clear();
+        query.str("");
+        query << "SELECT c.file_id, f.name, 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || c.file_id "
+              << "FROM files f, carved_files c, carved_sectors cs "
+              << "WHERE c.file_id = cs.file_id AND cs.seq = 0 AND f.file_id = c.file_id ORDER BY c.file_id";
+        getCarvedFileInfo(query.str(), false, carvedFileInfos);
+
+        std::ostringstream msg;
+        msg << msgPrefix << "no hashes available, returning all carved files";
+        LOGWARN(msg.str());
+    }
+    sqlite3_finalize(countStmt);
+
+    return carvedFileInfos;
+}
+
+std::vector<uint64_t> TskImgDBSqlite::getCarvedFileIds() const
+{
+    return getFileIdsWorker("carved_files");
+}
+
+std::vector<uint64_t> TskImgDBSqlite::getUniqueFileIds(HASH_TYPE hashType) const
+{
+    if (!m_db)
+        throw TskException("No database.");
+
+    std::vector<uint64_t> results;
+
+    string hash;
+    switch (hashType) {
+    case TskImgDB::MD5:
+        hash = "md5";
+        break;
+    case TskImgDB::SHA1:
+        hash = "sha1";
+        break;
+    case TskImgDB::SHA2_256:
+        hash = "sha2_256";
+        break;
+    case TskImgDB::SHA2_512:
+        hash = "sha2_512";
+        break;
+    default:
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBSqlite::getUniqueFileIds - Unsupported hashType : " << hashType ;
+        LOGERROR(errorMsg.str());
+        return results;
+    }
+
+    stringstream stmt;
+
+    stmt << "SELECT min(file_id) FROM file_hashes WHERE " << hash << " != '' group by " << hash ;
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        while (sqlite3_step(statement) == SQLITE_ROW) {
+            uint64_t fileId = (uint64_t)sqlite3_column_int64(statement, 0);
+            results.push_back(fileId);
+        }
+        sqlite3_finalize(statement);
+    } else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getUniqueFileIds - Error querying file_hashes table: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+    }
+    return results;
+}
+
+std::vector<uint64_t> TskImgDBSqlite::getFileIds() const
+{
+    return getFileIdsWorker("files");
+}
+
+std::vector<uint64_t> TskImgDBSqlite::getFileIdsWorker(std::string tableName, const std::string condition) const
+{
+    if (!m_db)
+        throw TskException("No database.");
+
+    std::vector<uint64_t> results;
+
+    stringstream stmt;
+
+    stmt << "SELECT file_id FROM " << tableName;
+    if (condition.compare("") != 0)
+        stmt << " WHERE " << condition;
+    stmt <<  " ORDER BY file_id";
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        while (sqlite3_step(statement) == SQLITE_ROW) {
+            uint64_t fileId = (uint64_t)sqlite3_column_int64(statement, 0);
+            results.push_back(fileId);
+        }
+        sqlite3_finalize(statement);
+    } else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getFileIdsWorker - Error getting file ids from table " << 
+            tableName.c_str() << ", " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+    }
+    return results;
+}
+
+/**
+ * Get the list of file ids that match the given criteria.
+ * The given string will be appended to "select files.file_id from files".
+ * See \ref img_db_schema_v1_5_page for tables and columns to include in 
+ * the selection criteria.
+ *
+ * @param condition Must be a valid SQL string defining the selection criteria.
+ * @returns The collection of file ids matching the selection criteria. Throws
+ * TskException if database not initialized.
+ */
+std::vector<uint64_t> TskImgDBSqlite::getFileIds(const std::string& condition) const
+{
+    if (!m_db)
+        throw TskException("Database not initialized.");
+
+    std::vector<uint64_t> results;
+
+    std::string stmt("SELECT files.file_id FROM files");
+
+    constructStmt(stmt, condition);
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.c_str(), -1, &statement, 0) == SQLITE_OK) 
+    {
+        while (sqlite3_step(statement) == SQLITE_ROW) 
+        {
+            uint64_t fileId = (uint64_t)sqlite3_column_int64(statement, 0);
+            results.push_back(fileId);
+        }
+        sqlite3_finalize(statement);
+    } else 
+    {
+        std::wstringstream msg;
+        msg << L"TskImgDBSqlite::getFilesIds - Error getting file ids: " << sqlite3_errmsg(m_db);
+        LOGERROR(msg.str());
+    }
+    return results;
+}
+/*
+ * Get the list of file records that match the given criteria.
+ * The given string will be appended to "select ... from files".
+ *
+ * @param condition Must be a valid SQL string defining the selection criteria.
+ * @returns The collection of file records matching the selection criteria. Throws
+ * TskException if database not initialized.
+ */
+const std::vector<TskFileRecord> TskImgDBSqlite::getFileRecords(const std::string& condition) const
+{
+    if (!m_db)
+        throw TskException("Database not initialized.");
+
+    std::vector<TskFileRecord> results;
+
+    std::stringstream stmtstrm;
+
+    stmtstrm << "SELECT f.file_id, f.type_id, f.name, f.par_file_id, f.dir_type, f.meta_type, f.dir_flags, "
+        << "f.meta_flags, f.size, f.ctime, f.crtime, f.atime, f.mtime, f.mode, f.uid, f.gid, f.status, f.full_path, "
+        << "fh.md5, fh.sha1, fh.sha2_256, fh.sha2_512 "
+        << "FROM files f LEFT OUTER JOIN file_hashes fh ON f.file_id = fh.file_id ";
+
+    std::string stmt = stmtstrm.str();
+    constructStmt(stmt, condition);
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.c_str(), -1, &statement, 0) == SQLITE_OK) 
+    {
+        while(sqlite3_step(statement) == SQLITE_ROW) {
+            TskFileRecord fileRecord;
+            fileRecord.fileId       = sqlite3_column_int64(statement, 0);
+            fileRecord.typeId       = (TskImgDB::FILE_TYPES) sqlite3_column_int(statement, 1);
+            fileRecord.name         = (char *)sqlite3_column_text(statement, 2);
+            fileRecord.parentFileId = sqlite3_column_int64(statement, 3);
+            fileRecord.dirType      = (TSK_FS_NAME_TYPE_ENUM) sqlite3_column_int(statement, 4);
+            fileRecord.metaType     = (TSK_FS_META_TYPE_ENUM) sqlite3_column_int(statement, 5);
+            fileRecord.dirFlags     = (TSK_FS_NAME_FLAG_ENUM) sqlite3_column_int(statement, 6);
+            fileRecord.metaFlags    = (TSK_FS_META_FLAG_ENUM) sqlite3_column_int(statement, 7);
+            fileRecord.size         = sqlite3_column_int64(statement, 8);
+            fileRecord.ctime        = sqlite3_column_int(statement, 9);
+            fileRecord.crtime       = sqlite3_column_int(statement, 10);
+            fileRecord.atime        = sqlite3_column_int(statement, 11);
+            fileRecord.mtime        = sqlite3_column_int(statement, 12);
+            fileRecord.mode         = (TSK_FS_META_MODE_ENUM) sqlite3_column_int(statement, 13);
+            fileRecord.uid          = sqlite3_column_int(statement, 14);
+            fileRecord.gid          = sqlite3_column_int(statement, 15);
+            fileRecord.status       = (TskImgDB::FILE_STATUS) sqlite3_column_int(statement, 16);
+            fileRecord.fullPath     = (char *)sqlite3_column_text(statement, 17);
+
+            if (sqlite3_column_type(statement, 18) == SQLITE_TEXT)
+                fileRecord.md5      = (char *)sqlite3_column_text(statement, 18);
+            if (sqlite3_column_type(statement, 19) == SQLITE_TEXT)
+                fileRecord.sha1     = (char *)sqlite3_column_text(statement, 19);
+            if (sqlite3_column_type(statement, 20) == SQLITE_TEXT)
+                fileRecord.sha2_256 = (char *)sqlite3_column_text(statement, 20);
+            if (sqlite3_column_type(statement, 21) == SQLITE_TEXT)
+                fileRecord.sha2_512 = (char *)sqlite3_column_text(statement, 21);
+            results.push_back(fileRecord);
+        }
+    }
+    else 
+    {
+        std::wstringstream msg;
+        msg << L"TskImgDBSqlite::getFilesRecords - Error getting file reocrds: " << sqlite3_errmsg(m_db);
+        LOGERROR(msg.str());
+    }
+    return results;
+}
+
+
+/**
+ * Get the number of files that match the given criteria.
+ * The given string will be appended to "select files.file_id from files".
+ *
+ * @param condition Must be a valid SQL string defining the selection criteria.
+ * @returns The number of files matching the selection criteria. 
+ */
+int TskImgDBSqlite::getFileCount(const std::string& condition) const
+{
+    if (!m_db)
+        throw TskException("Database not initialized.");
+
+    int result = 0;
+
+    std::string stmt("SELECT COUNT(files.file_id) FROM files");
+
+    constructStmt(stmt, condition);
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.c_str(), -1, &statement, 0) == SQLITE_OK) 
+    {
+        while (sqlite3_step(statement) == SQLITE_ROW) 
+        {
+            result = (uint64_t)sqlite3_column_int(statement, 0);
+        }
+        sqlite3_finalize(statement);
+    } else 
+    {
+        std::wstringstream msg;
+        msg << L"TskImgDBSqlite::getFileCount - Error getting file count: " << sqlite3_errmsg(m_db);
+        LOGERROR(msg.str());
+    }
+    return result;
+}
+
+int tsk_strnicmp(const char *s1, const char *s2, size_t N)
+{
+    if (N == 0)
+        return 0;
+    int diff = 0;
+    if (s1 && s2) {
+        while (N-- > 0 && (diff = (toupper(*s1) - toupper(*s2))) == 0 && *s1 && *s2) {
+            s1++;
+            s2++;
+        }
+    }
+    else if (s1)
+        return +1;
+    else if (s2)
+        return -1;
+    return diff;
+}
+
+/* Append condition to stmt to make a single SQL query.
+ */
+void TskImgDBSqlite::constructStmt(std::string& stmt, std::string condition) const
+{
+    if (!condition.empty())
+    {
+        // Remove leading whitespace from condition
+        condition.erase(0, condition.find_first_not_of(' '));
+
+        std::string whereClause("WHERE");
+        std::string joinClause("JOIN");
+        std::string leftClause("LEFT");
+        std::string orderClause("ORDER");
+
+        /* If the condition doesn't start with one of the below statements 
+         * (WHERE, JOIN, etc.), then 
+         * it is presumably extending the FROM clause with
+         * one or more table names. In this case we need to add the comma to
+         * the statement. */
+        if (tsk_strnicmp(condition.c_str(), whereClause.c_str(), whereClause.length()) != 0 &&
+            tsk_strnicmp(condition.c_str(), joinClause.c_str(), joinClause.length()) != 0 &&
+            tsk_strnicmp(condition.c_str(), leftClause.c_str(), leftClause.length()) != 0 &&
+            tsk_strnicmp(condition.c_str(), orderClause.c_str(), orderClause.length()) != 0 &&
+            condition[0] != ',')
+        {
+            stmt.append(",");
+        }
+    }
+
+    stmt.append(" ");
+    stmt.append(condition);
+}
+
+// Set file hash for hashType for a_file_id
+// Return 1 on failure, 0 on success.
+int TskImgDBSqlite::setHash(const uint64_t a_file_id, const TskImgDB::HASH_TYPE hashType, const std::string& hash) const 
+{
+    if (!m_db)
+        throw TskException("No database.");
+
+    string hashTypeStr;
+    switch (hashType) {
+    case TskImgDB::MD5:
+        hashTypeStr = "md5";
+        break;
+    case TskImgDB::SHA1:
+        hashTypeStr = "sha1";
+        break;
+    case TskImgDB::SHA2_256:
+        hashTypeStr = "sha2_256";
+        break;
+    case TskImgDB::SHA2_512:
+        hashTypeStr = "sha2_512";
+        break;
+    default:
+        std::wstringstream errorMsg;
+        errorMsg << L"TskImgDBSqlite::setHash - Unsupported hashType : " << hashType ;
+        LOGERROR(errorMsg.str());
+        return 1;
+    }
+
+    stringstream stmt;
+    std::string md5, sha1, sha2_256, sha2_512;
+    int known = IMGDB_FILES_UNKNOWN;
+    std::stringstream stream;
+
+    stmt << "SELECT md5, sha1, sha2_256, sha2_512, known from file_hashes WHERE file_id = " << a_file_id;
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        int result = sqlite3_step(statement);
+        if (result == SQLITE_ROW) {
+            md5 = (char *)sqlite3_column_text(statement, 0);
+            sha1 = (char *)sqlite3_column_text(statement, 1);
+            sha2_256 = (char *)sqlite3_column_text(statement, 2);
+            sha2_512 = (char *)sqlite3_column_text(statement, 3);
+            known = (int)sqlite3_column_int(statement, 4);
+        } 
+        sqlite3_finalize(statement);
+    } else {
+        ; // OK if not exists
+    }
+
+    // insert new record
+    stmt.str("");
+    stmt << "INSERT OR REPLACE INTO file_hashes (file_id, md5, sha1, sha2_256, sha2_512, known) VALUES (" << a_file_id;
+    switch (hashType) {
+    case TskImgDB::MD5:
+        stmt << ", '" << hash << "'";
+        stmt << ", '" << sha1 << "'";
+        stmt << ", '" << sha2_256 << "'";
+        stmt << ", '" << sha2_512 << "'";
+        stream << known;
+        stmt << ", " << stream.str();
+        break;
+    case TskImgDB::SHA1:
+        stmt << ", '" << md5 << "'";
+        stmt << ", '" << hash << "'";
+        stmt << ", '" << sha2_256 << "'";
+        stmt << ", '" << sha2_512 << "'";
+        stream << known;
+        stmt << ", " << stream.str();
+        break;
+    case TskImgDB::SHA2_256:
+        stmt << ", '" << md5 << "'";
+        stmt << ", '" << sha1 << "'";
+        stmt << ", '" << hash << "'";
+        stmt << ", '" << sha2_512 << "'";
+        stream << known;
+        stmt << ", " << stream.str();
+        break;
+    case TskImgDB::SHA2_512:
+        stmt << ", '" << md5 << "'";
+        stmt << ", '" << sha1 << "'";
+        stmt << ", '" << sha2_256 << "'";
+        stmt << ", '" << hash << "'";
+        stream << known;
+        stmt << ", " << stream.str();
+        break;
+    }
+    stmt << ")";
+
+    char *errmsg;
+    if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, &errmsg) != SQLITE_OK) {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::setHash - Error adding hash to file_hashes table: " << errmsg;
+        LOGERROR(infoMessage.str());
+        sqlite3_free(errmsg);
+        return 1;
+    }
+
+    return 0;
+}
+
+std::string TskImgDBSqlite::getCfileName(const uint64_t a_file_id) const
+{
+    if (!m_db)
+        throw TskException("No database.");
+
+    std::string cfileName;
+    stringstream stmt;
+
+    stmt << "select 'cfile_' || c.vol_id || '_' || cs.sect_start || '_' || f.file_id"
+        " from files f, carved_files c, carved_sectors cs where f.file_id = c.file_id and c.file_id = cs.file_id and cs.seq = 0"
+        " and f.file_id = " << a_file_id;
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        int result = sqlite3_step(statement);
+        if (result == SQLITE_ROW) {
+            cfileName = (char *)sqlite3_column_text(statement, 0);
+        }
+        sqlite3_finalize(statement);
+    } else {
+        std::wstringstream infoMessage;
+        infoMessage <<  L"TskImgDBSqlite::getCfileName - Error querying tables: %S" << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+    }
+
+    stmt.str("");
+    stmt << "select f.name "
+        " from files f, carved_files c, carved_sectors cs where f.file_id = c.file_id and c.file_id = cs.file_id and cs.seq = 0"
+        " and f.file_id = " << a_file_id;
+
+    std::string name;
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        int result = sqlite3_step(statement);
+        if (result == SQLITE_ROW) {
+            name = (char *)sqlite3_column_text(statement, 0);
+        }
+        sqlite3_finalize(statement);
+        size_t pos = name.rfind('.');
+        if (pos != string::npos)
+            cfileName += name.substr(pos);
+    } else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getCfileName - Error querying tables: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+    }
+
+    return cfileName;
+}
+
+/**
+ * Return the ImageInfo
+ * @param type Image Type (output)
+ * @param sectorSize Image sector size (output)
+ * @returns 0 on success or -1 on error.
+ */
+int TskImgDBSqlite::getImageInfo(int & type, int & sectorSize) const
+{
+    int rc = -1;
+    if (!m_db)
+        return rc;
+
+    stringstream stmt;
+
+    stmt << "SELECT type, ssize FROM image_info";
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        int result = sqlite3_step(statement);
+        if (result == SQLITE_ROW) {
+            type = (int)sqlite3_column_int64(statement, 0);
+            sectorSize = (int)sqlite3_column_int64(statement, 1);
+            rc = 0;
+        }
+        sqlite3_finalize(statement);
+    } else {
+        std::wstringstream infoMessage;
+        infoMessage <<  L"TskImgDBSqlite::getImageInfo - Error querying image_info table: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+        return -1;
+    }
+    return rc;
+}
+
+/**
+ * Return a list of TskVolumeInfoRecord
+ * @param volumeInfoList A list of TskVolumeInfoRecord (output)
+ * @returns 0 on success or -1 on error.
+ */
+int TskImgDBSqlite::getVolumeInfo(std::list<TskVolumeInfoRecord> & volumeInfoList) const
+{
+    std::list<TskVolumeInfoRecord> list;
+
+    if (!m_db)
+        return -1;
+
+    stringstream stmt;
+    stmt << "SELECT vol_id, sect_start, sect_len, description, flags FROM vol_info";
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        while (sqlite3_step(statement) == SQLITE_ROW) {
+            TskVolumeInfoRecord vol_info;
+            vol_info.vol_id = sqlite3_column_int(statement,0);
+            vol_info.sect_start = sqlite3_column_int64(statement,1);
+            vol_info.sect_len = sqlite3_column_int64(statement,2);
+            vol_info.description.assign((char *)sqlite3_column_text(statement, 3));
+            vol_info.flags = (TSK_VS_PART_FLAG_ENUM)sqlite3_column_int(statement, 4);
+            volumeInfoList.push_back(vol_info);
+        }
+        sqlite3_finalize(statement);
+    } else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getVolumeInfo - Error getting from vol_info table: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+        return -1;
+    }
+    return 0;
+}
+
+/**
+ * Return a list of TskFsInfoRecord
+ * @param fsInfoList A list of TskFsInfoRecord (output)
+ * @returns 0 on success or -1 on error.
+ */
+int TskImgDBSqlite::getFsInfo(std::list<TskFsInfoRecord> & fsInfoList) const
+{
+    std::list<TskFsInfoRecord> list;
+
+    if (!m_db)
+        return -1;
+
+    stringstream stmt;
+    stmt << "SELECT fs_id, img_byte_offset, vol_id, fs_type, block_size, block_count, root_inum, first_inum, last_inum FROM fs_info";
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        while (sqlite3_step(statement) == SQLITE_ROW) {
+            TskFsInfoRecord fs_info;
+            fs_info.fs_id = sqlite3_column_int(statement,0);
+            fs_info.img_byte_offset = sqlite3_column_int64(statement,1);
+            fs_info.vol_id = sqlite3_column_int(statement,2);
+            fs_info.fs_type = (TSK_FS_TYPE_ENUM)sqlite3_column_int(statement,3);
+            fs_info.block_size = sqlite3_column_int(statement,4);
+            fs_info.block_count = sqlite3_column_int64(statement,5);
+            fs_info.root_inum = sqlite3_column_int64(statement,6);
+            fs_info.first_inum = sqlite3_column_int64(statement,7);
+            fs_info.last_inum = sqlite3_column_int64(statement,8);
+            fsInfoList.push_back(fs_info);
+        }
+        sqlite3_finalize(statement);
+    } else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getFsInfo - Error getting from fs_info table: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+        return -1;
+    }
+    return 0;
+}
+
+typedef std::map<std::string, int> FileTypeMap_t;
+
+static std::string getFileType(const char *name)
+{
+    std::string filename = name;
+    size_t pos = filename.rfind('.');
+    if (pos != std::string::npos) {
+        std::string suffix = filename.substr(pos);
+        std::string result;
+        for (size_t i=0; i < suffix.size(); i++) {
+            result += (char)tolower(suffix[i]);
+        }
+        return result;
+    }
+    else
+        return std::string("");
+}
+
+/**
+ * Return a list of TskFileTypeRecord for all files.
+ * @param fileTypeInfoList A list of TskFileTypeRecord (output)
+ * @returns 0 on success or -1 on error.
+ */
+int TskImgDBSqlite::getFileInfoSummary(std::list<TskFileTypeRecord> &fileTypeInfoList) const
+{
+    std::stringstream stmt;
+    stmt << "SELECT name FROM files WHERE dir_type = " << TSK_FS_NAME_TYPE_REG;
+
+    return getFileTypeRecords(stmt.str(), fileTypeInfoList);
+}
+
+/**
+ * Return a list of TskFileTypeRecord for fileType
+ * @param fileType FILE_TYPE to report
+ * @param fileTypeInfoList A list of TskFileTypeRecord (output)
+ * @returns 0 on success or -1 on error.
+ */
+int TskImgDBSqlite::getFileInfoSummary(FILE_TYPES fileType, std::list<TskFileTypeRecord> & fileTypeInfoList) const
+{
+    stringstream stmt;
+    stmt << "SELECT name FROM files WHERE type_id = " << fileType << " AND dir_type = " << TSK_FS_NAME_TYPE_REG;
+
+    return getFileTypeRecords(stmt.str(), fileTypeInfoList);
+}
+
+/**
+ * Return a list of TskFileTypeRecords matching the given SQL statement.
+ * @param stmt The SQL statement used to match file records.
+ * @param fileTypeInfoList A list of TskFileTypeRecord (output)
+ * @returns 0 on success of -1 on error.
+ */
+int TskImgDBSqlite::getFileTypeRecords(const std::string& stmt, std::list<TskFileTypeRecord>& fileTypeInfoList) const
+{
+    if (!m_db)
+        return -1;
+
+    std::list<TskFileTypeRecord> list;
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.c_str(), -1, &statement, 0) == SQLITE_OK) {
+        FileTypeMap_t fileTypeMap;
+        while (sqlite3_step(statement) == SQLITE_ROW) {
+            char *name = (char *)sqlite3_column_text(statement, 0);
+            std::string type = getFileType(name);
+            FileTypeMap_t::iterator iter = fileTypeMap.find(type);
+            if (iter != fileTypeMap.end()) {
+                // increment file counter
+                int count = iter->second;
+                fileTypeMap[type] = ++count;
+            } else {
+                // add a new file type
+                fileTypeMap.insert(pair<std::string, int>(type, 1));
+            }
+        }
+        for (FileTypeMap_t::const_iterator iter=fileTypeMap.begin(); iter != fileTypeMap.end(); iter++) {
+            TskFileTypeRecord info;
+            info.suffix.assign((*iter).first.c_str());
+            info.count = (*iter).second;
+            info.description.assign("File Type Description");
+            fileTypeInfoList.push_back(info);
+        }
+        sqlite3_finalize(statement);
+    } else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getFileTypeRecords - Error querying files table: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+        return -1;
+    }
+    return 0;
+}
+
+/**
+ * Insert the Module record, if module name does not already exist in modules table.
+ * Returns Module Id associated with the Module record.
+ * @param name Module name
+ * @param description Module description
+ * @param moduleId Module Id (output)
+ * @returns 0 on success, -1 on error.
+ */
+int TskImgDBSqlite::addModule(const std::string& name, const std::string& description, int & moduleId)
+{
+    if (!m_db)
+        return -1;
+
+    if (name.empty())
+    {
+        LOGWARN(L"TskImgDBSqlite::addModule - Given an empty module name.");
+        return -1;
+    }
+
+    moduleId = 0;
+
+    sqlite3_stmt * statement;
+    char stmt[1024];
+    sqlite3_snprintf(1024, stmt, "SELECT module_id FROM modules WHERE name = '%q';",
+                     name.c_str());
+
+    if (sqlite3_prepare_v2(m_db, stmt, -1, &statement, 0) == SQLITE_OK) 
+    {
+        int result = sqlite3_step(statement);
+        if (result == SQLITE_ROW) 
+        {
+            // Already exists, return module_id
+            moduleId = sqlite3_column_int(statement, 0);
+        }
+        else
+        {
+            // Create a new module record.
+            char insertStmt[1024];
+            char * errmsg;
+            sqlite3_snprintf(1024, insertStmt, 
+                "INSERT INTO modules (module_id, name, description) VALUES (NULL, '%q', '%q');",
+                name.c_str(), description.c_str());
+            if (sqlite3_exec(m_db, insertStmt, NULL, NULL, &errmsg) == SQLITE_OK) 
+            {
+                moduleId = (int)sqlite3_last_insert_rowid(m_db);
+            } 
+            else 
+            {
+                std::wstringstream msg;
+                msg << L"TskImgDBSqlite::addModule - Error adding record to modules table: " << errmsg;
+                LOGERROR(msg.str());
+                sqlite3_free(errmsg);
+            }
+        }
+        sqlite3_finalize(statement);
+    }
+    else
+    {
+        std::wstringstream msg;
+        msg << L"TskImgDBSqlite::addModule - Failed to prepare statement: " << stmt;
+        LOGERROR(msg.str());
+    }
+    
+    if (moduleId == 0)
+        return -1;
+
+    return 0;
+}
+
+/**
+ * Insert the module status record.
+ * @param file_id file_id
+ * @param module_id module_id
+ * @param status Status of module
+ * @returns 0 on success, -1 on error.
+ */
+int TskImgDBSqlite::setModuleStatus(uint64_t file_id, int module_id, int status)
+{
+    int rc = -1;
+
+    if (!m_db)
+        return rc;
+
+    char * errmsg;
+    std::stringstream stmt;
+    stmt << "INSERT INTO module_status (file_id, module_id, status) VALUES (" <<
+        file_id << ", " <<  module_id << ", " << status << ")";
+
+    if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, &errmsg) == SQLITE_OK) {
+        rc = 0;
+    } else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::setModuleStatus - Error adding data to module_status table: " << errmsg;
+        LOGERROR(infoMessage.str());
+        sqlite3_free(errmsg);
+    }
+    return rc;
+}
+
+/**
+ * Get a list of TskModuleStatus.
+ * @param moduleInfoList A list of TskModuleStatus (output)
+ * @returns 0 on success, -1 on error.
+*/
+int TskImgDBSqlite::getModuleInfo(std::vector<TskModuleInfo> & moduleInfoList) const
+{
+    int rc = -1;
+
+    if (!m_db)
+        return rc;
+
+    stringstream stmt;
+    stmt << "SELECT module_id, name, description FROM modules ORDER BY module_id";
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        TskModuleInfo moduleInfo;
+        while (sqlite3_step(statement) == SQLITE_ROW) {
+            moduleInfo.module_id = (int)sqlite3_column_int64(statement, 0);
+            moduleInfo.module_name = (char *)sqlite3_column_text(statement, 1);
+            moduleInfo.module_description = (char *)sqlite3_column_text(statement, 2);
+            moduleInfoList.push_back(moduleInfo);
+        }
+        sqlite3_finalize(statement);
+        rc = 0;
+    } else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getModuleInfo - Error querying modules table: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+    }
+    return rc;
+}
+
+/**
+ * Get a list of TskModuleStatus.
+ * @param moduleStatusList A list of TskModuleStatus (output)
+ * @returns 0 on success, -1 on error.
+*/
+int TskImgDBSqlite::getModuleErrors(std::vector<TskModuleStatus> & moduleStatusList) const
+{
+    int rc = -1;
+
+    if (!m_db)
+        return rc;
+
+    stringstream stmt;
+    stmt << "SELECT f.file_id, m.name, ms.status FROM module_status ms, files f, modules m"
+        << " WHERE ms.status != 0 AND ms.file_id = f.file_id AND m.module_id = ms.module_id"
+        << " ORDER BY f.file_id";
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        TskModuleStatus moduleStatus;
+        while (sqlite3_step(statement) == SQLITE_ROW) {
+            moduleStatus.file_id = (uint64_t)sqlite3_column_int64(statement, 0);
+            moduleStatus.module_name = (char *)sqlite3_column_text(statement, 1);
+            moduleStatus.status = (int)sqlite3_column_int(statement, 2);
+            moduleStatusList.push_back(moduleStatus);
+        }
+        sqlite3_finalize(statement);
+        rc = 0;
+    } else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getModuleErrors - Error querying module_status table: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+    }
+    // Find report module errors. These have file_id = 0.
+    stmt.str("");
+    stmt << "SELECT 0, m.name, ms.status FROM module_status ms, modules m"
+         << " WHERE ms.status != 0 AND ms.file_id = 0 AND m.module_id = ms.module_id";
+
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        TskModuleStatus moduleStatus;
+        while (sqlite3_step(statement) == SQLITE_ROW) {
+            moduleStatus.file_id = (uint64_t)sqlite3_column_int64(statement, 0);
+            moduleStatus.module_name = (char *)sqlite3_column_text(statement, 1);
+            moduleStatus.status = (int)sqlite3_column_int(statement, 2);
+            moduleStatusList.push_back(moduleStatus);
+        }
+        sqlite3_finalize(statement);
+        rc = 0;
+    } else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getModuleErrors - Error querying module_status table: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+    }
+    return rc;
+}
+
+/*
+ * Return a file name associated with a file_id, prefer Cfilename, otherwise name in the files table.
+ * @param file_id file id
+ * @returns file name as std::string
+ */
+std::string TskImgDBSqlite::getFileName(uint64_t file_id) const
+{
+    std::string name;
+
+    if (!m_db)
+        return name;
+
+    name = getCfileName(file_id);
+    if (name == "") {
+        TskFileRecord fileRecord;
+        if (getFileRecord(file_id, fileRecord) == 0)
+            name = fileRecord.name;
+    }
+    return name;
+}
+
+
+TskImgDB::KNOWN_STATUS TskImgDBSqlite::getKnownStatus(const uint64_t fileId) const
+{
+    int retval = -1;
+
+    if (!m_db)
+        return (KNOWN_STATUS)retval;
+    
+    stringstream stmt;
+    stmt << "SELECT known FROM file_hashes WHERE file_id = " << fileId;
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        if(sqlite3_step(statement) == SQLITE_ROW) {
+            retval = (int)sqlite3_column_int(statement, 0);
+        }
+        sqlite3_finalize(statement);
+    } else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getKnownStatus - Error getting known status " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+    }
+
+    return (KNOWN_STATUS)retval;
+}
+
+
+/**
+ * Add a new row to the unalloc_img_status table, returning the unalloc_img_id.
+ * @param unallocImgId unalloc_img_id (output)
+ * @returns -1 on error, 0 on success.
+ */
+int TskImgDBSqlite::addUnallocImg(int & unallocImgId)
+{
+    int rc = -1;
+
+    if (!m_db)
+        return rc;
+
+    std::stringstream stmt;
+    stmt << "INSERT INTO unalloc_img_status (unalloc_img_id, status) VALUES (NULL, " << TskImgDB::IMGDB_UNALLOC_IMG_STATUS_CREATED << ")";
+    char * errmsg;
+    if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, &errmsg) == SQLITE_OK) {
+        unallocImgId = (int)sqlite3_last_insert_rowid(m_db);
+        rc = 0;
+    } else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::addUnallocImg - Error adding unalloc_img_status table: " << errmsg;
+        LOGERROR(infoMessage.str());
+        sqlite3_free(errmsg);
+    }
+    return rc;
+}
+
+/**
+ * Set the status in the unalloc_img_status table given the unalloc_img_id.
+ * @param unallocImgId unalloc_img_id
+ * @param status status of unalloc_img_id
+ * @returns -1 on error, 0 on success.
+ */
+int TskImgDBSqlite::setUnallocImgStatus(int unallocImgId, TskImgDB::UNALLOC_IMG_STATUS status)
+{
+    int rc = -1;
+
+    if (!m_db)
+        return rc;
+
+    std::stringstream stmt;
+    stmt << "UPDATE unalloc_img_status SET status = " << status << " WHERE unalloc_img_id = " << unallocImgId;
+    char * errmsg;
+    if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, &errmsg) == SQLITE_OK) {
+        rc = 0;
+    } else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::addUnallocImg - Error adding unalloc_img_status table: " << errmsg;
+        LOGERROR(infoMessage.str());
+        sqlite3_free(errmsg);
+    }
+    return rc;
+}
+
+/**
+ * Get the status of the unalloc_img_status table given the unalloc_img_id.
+ * Can throws TskException.
+ * @param unallocImgId unalloc_img_id
+ * @returns TskImgDB::UNALLOC_IMG_STATUS
+ */
+TskImgDB::UNALLOC_IMG_STATUS TskImgDBSqlite::getUnallocImgStatus(int unallocImgId) const
+{
+    if (!m_db)
+        throw TskException("Database not initialized.");
+
+    int status = 0;
+    stringstream stmt;
+    stmt << "SELECT status FROM unalloc_img_status WHERE unalloc_img_id = " << unallocImgId;
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        if (sqlite3_step(statement) == SQLITE_ROW) {
+            status = (int)sqlite3_column_int(statement, 0);
+        }
+        sqlite3_finalize(statement);
+    } else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getUnallocImgStatus - Error getting unalloc_img_status: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+    }
+    return (TskImgDB::UNALLOC_IMG_STATUS)status;
+}
+
+/**
+ * Get all the unalloc_img_status table.
+ * @param unallocImgStatusList A vector of TskUnallocImgStatusRecord (output)
+ * @returns -1 on error, 0 on success.
+ */
+int TskImgDBSqlite::getAllUnallocImgStatus(std::vector<TskUnallocImgStatusRecord> & unallocImgStatusList) const
+{
+    int rc = -1;
+    unallocImgStatusList.clear();
+
+    if (!m_db)
+        return rc;
+
+    stringstream stmt;
+    stmt << "SELECT unalloc_img_id, status FROM unalloc_img_status";
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        while (sqlite3_step(statement) == SQLITE_ROW) {
+            TskUnallocImgStatusRecord record;
+            record.unallocImgId = (int)sqlite3_column_int(statement, 0);
+            record.status = (TskImgDB::UNALLOC_IMG_STATUS)sqlite3_column_int(statement, 1);
+            unallocImgStatusList.push_back(record);
+        }
+        rc = 0;
+        sqlite3_finalize(statement);
+    } else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getAllUnallocImgStatus - Error getting unalloc_img_status: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+    }
+    return rc;
+}
+
+/**
+ * Find and add all the unused sectors (unallocated and uncarved bytes) in the given unallocImgId
+ * @param unallocImgId The unalloc image id.
+ * @param unusedSectorsList A vector of TskUnusedSectorsRecord
+ * @returns -1 on error, 0 on success.
+ */
+int TskImgDBSqlite::addUnusedSectors(int unallocImgId, std::vector<TskUnusedSectorsRecord> & unusedSectorsList)
+{
+    assert(unallocImgId > 0);
+    int rc = -1;
+    if (!m_db)
+        return rc;
+
+    std::stringstream stmt;
+    stmt << "SELECT vol_id, unalloc_img_sect_start, sect_len, orig_img_sect_start FROM alloc_unalloc_map "
+        "WHERE unalloc_img_id = " << unallocImgId << " ORDER BY orig_img_sect_start ASC";
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        vector<TskAllocUnallocMapRecord> allocUnallocMapList;
+
+        while (sqlite3_step(statement) == SQLITE_ROW) {
+            TskAllocUnallocMapRecord record;
+            record.vol_id = (int)sqlite3_column_int(statement, 0);
+            record.unalloc_img_id = unallocImgId;
+            record.unalloc_img_sect_start = (uint64_t)sqlite3_column_int64(statement, 1);
+            record.sect_len = (uint64_t)sqlite3_column_int64(statement, 2);
+            record.orig_img_sect_start = (uint64_t)sqlite3_column_int64(statement, 3);
+            allocUnallocMapList.push_back(record);
+        }
+        sqlite3_finalize(statement);
+
+        for (std::vector<TskAllocUnallocMapRecord>::const_iterator it = allocUnallocMapList.begin();
+             it != allocUnallocMapList.end(); it++)
+        {
+            // Sector position tracks our position through the unallocated map record.
+            uint64_t sectPos = it->orig_img_sect_start;
+
+            uint64_t endSect = it->orig_img_sect_start + it->sect_len;
+
+            // Retrieve all carved_sector records in range for this section of unallocated space.
+            stmt.str("");
+            stmt << "SELECT cs.sect_start, cs.sect_len FROM carved_files cf, carved_sectors cs"
+                << " WHERE cf.file_id = cs.file_id AND cs.sect_start >= " << it->orig_img_sect_start
+                << " AND cs.sect_start < " << endSect << " ORDER BY cs.sect_start ASC";
+
+            if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+                while (sqlite3_step(statement) == SQLITE_ROW) {
+                    uint64_t cfileSectStart = (uint64_t)sqlite3_column_int64(statement, 0);
+                    uint64_t cfileSectLen = (uint64_t)sqlite3_column_int64(statement, 1);
+                    if (cfileSectStart > sectPos)
+                    {
+                        // We have a block of unused sectors between this position in the unallocated map
+                        // and the start of the carved file.
+                        addUnusedSector(sectPos, cfileSectStart, it->vol_id, unusedSectorsList);
+                    }
+
+                    sectPos = cfileSectStart + cfileSectLen;
+                }
+
+                // Handle case where there is slack at the end of the unalloc range
+                if (sectPos < endSect)
+                    addUnusedSector(sectPos, endSect, it->vol_id, unusedSectorsList);
+
+                sqlite3_finalize(statement);
+            } else {
+                std::wstringstream infoMessage;
+                infoMessage << L"TskImgDBSqlite::addUnusedSectors - Error querying carved_files, carved_sectors table: " << sqlite3_errmsg(m_db);
+                LOGERROR(infoMessage.str());
+            }
+        }
+    } else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::addUnusedSectors - Error querying alloc_unalloc_map table: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+    }
+    return 0;
+}
+
+/**
+ * Add one unused sector to the database, add it to the files and unused_sectors tables.
+ * @param sectStart Unused sector start.
+ * @param sectEnd Unused sector end.
+ * @param volId Volume Id of the unused sector.
+ * @param unusedSectorsList A vector of TskUnusedSectorsRecord (output)
+ * @returns -1 on error, 0 on success.
+ */
+int TskImgDBSqlite::addUnusedSector(uint64_t sectStart, uint64_t sectEnd, int volId, std::vector<TskUnusedSectorsRecord> & unusedSectorsList)
+{
+    assert(sectEnd > sectStart);
+    int rc = -1;
+    if (!m_db)
+        return rc;
+
+    std::stringstream stmt;
+
+    std::string maxUnused = GetSystemProperty("MAX_UNUSED_FILE_SIZE_BYTES");
+    const uint64_t maxUnusedFileSizeBytes = maxUnused.empty() ? (50 * 1024 * 1024) : Poco::NumberParser::parse64(maxUnused);
+
+    uint64_t maxUnusedSectorSize = maxUnusedFileSizeBytes / 512;
+    uint64_t sectorIndex = 0;
+    uint64_t sectorCount = (sectEnd - sectStart) / maxUnusedSectorSize;
+
+    while (sectorIndex <= sectorCount) {
+        uint64_t thisSectStart = sectStart + (sectorIndex * maxUnusedSectorSize);
+        uint64_t thisSectEnd = thisSectStart + (std::min)(maxUnusedSectorSize, sectEnd - thisSectStart);
+
+        stmt.str("");
+        stmt << "INSERT INTO files (file_id, type_id, name, par_file_id, dir_type, meta_type,"
+            "dir_flags, meta_flags, size, ctime, crtime, atime, mtime, mode, uid, gid, status, full_path) "
+            "VALUES (NULL, " << IMGDB_FILES_TYPE_UNUSED << ", " << "'ufile'" 
+            << ", NULL, " <<  TSK_FS_NAME_TYPE_REG << ", " <<  TSK_FS_META_TYPE_REG << ", "
+            << TSK_FS_NAME_FLAG_UNALLOC << ", " << TSK_FS_META_FLAG_UNALLOC << ", "
+            << (thisSectEnd - thisSectStart) * 512 << ", NULL, NULL, NULL, NULL, NULL, NULL, NULL, " << IMGDB_FILES_STATUS_READY_FOR_ANALYSIS << "," << "'ufile'" << ")";
+
+        if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, NULL) == SQLITE_OK) {
+
+            TskUnusedSectorsRecord record;
+
+            // get the file_id from the last insert
+            record.fileId = sqlite3_last_insert_rowid(m_db);
+            record.sectStart = thisSectStart;
+            record.sectLen = thisSectEnd - thisSectStart;
+
+            std::stringstream name;
+            name << "ufile_" << thisSectStart << "_" << thisSectEnd << "_" << record.fileId;
+            stmt.str("");
+            char *item;
+            item = sqlite3_mprintf("%Q", name.str().c_str());
+            stmt << "UPDATE files SET name = " << item << ", full_path = " 
+                << item << " WHERE file_id = " << record.fileId;
+            sqlite3_free(item);
+
+            if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, NULL) != SQLITE_OK) {
+                std::wstringstream infoMessage;
+                infoMessage << L"TskImgDBSqlite::addUnusedSector - Error update into files table: " << sqlite3_errmsg(m_db);
+                LOGERROR(infoMessage.str());
+                rc = -1;
+                break;
+            }
+
+            stmt.str("");
+            stmt << "INSERT INTO unused_sectors (file_id, sect_start, sect_len, vol_id) VALUES (" 
+                 << record.fileId << ", " << record.sectStart << ", " << record.sectLen << ", " << volId << ")";
+
+            if (sqlite3_exec(m_db, stmt.str().c_str(), NULL, NULL, NULL) != SQLITE_OK) {
+                std::wstringstream infoMessage;
+                infoMessage << L"TskImgDBSqlite::addUnusedSector - Error insert into unused_sectors table: " << sqlite3_errmsg(m_db);
+                LOGERROR(infoMessage.str());
+                rc = -1;
+                break;
+            }
+
+            unusedSectorsList.push_back(record);
+            rc = 0;
+
+        } else {
+            std::wstringstream infoMessage;
+            infoMessage << L"TskImgDBSqlite::addUnusedSector - Error insert into files table: " << sqlite3_errmsg(m_db);
+            LOGERROR(infoMessage.str());
+            rc = -1;
+            break;
+        }
+        sectorIndex++;
+    } // while
+    return rc;
+}
+
+/**
+ * Get unused sector record given a file id.
+ * @param fileId File id of the unused sector.
+ * @param unusedSectorsRecord TskUnusedSectorsRecord (output)
+ * @returns -1 on error, 0 on success.
+ */
+int TskImgDBSqlite::getUnusedSector(uint64_t fileId, TskUnusedSectorsRecord & unusedSectorsRecord) const
+{
+    int rc = -1;
+    if (!m_db)
+        return rc;
+
+    std::stringstream stmt;
+    stmt << "SELECT sect_start, sect_len FROM unused_sectors WHERE file_id = " << fileId;
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        if (sqlite3_step(statement) == SQLITE_ROW) {
+            unusedSectorsRecord.fileId = fileId;
+            unusedSectorsRecord.sectStart = (uint64_t)sqlite3_column_int64(statement, 0);
+            unusedSectorsRecord.sectLen = (uint64_t)sqlite3_column_int64(statement, 1);
+            rc = 0;
+        } else {
+            std::wstringstream msg;
+            msg << L"TskDBSqlite::getUnusedSector - Error querying unused_sectors table for file_id "
+                << fileId ;
+            LOGERROR(msg.str());
+        }
+    } else {
+        std::wstringstream msg;
+        msg << L"TskDBSqlite::getUnusedSector - Error querying unused_sectors table: "
+            << sqlite3_errmsg(m_db) ;
+        LOGERROR(msg.str());
+    }
+    return rc;
+}
+
+///BLACKBOARD FUNCTIONS
+/**
+ * Add the given blackboard attribute to the database
+ * @param attr input attribute. should be fully populated
+ */
+void TskImgDBSqlite::addBlackboardAttribute(TskBlackboardAttribute attr)
+{
+    if (!m_db)
+        throw TskException("No database.");
+
+    std::stringstream str;
+    char *item;
+    sqlite3_stmt * statement;
+
+    str << "INSERT INTO blackboard_attributes (artifact_id, source, context, attribute_type_id, value_type, "
+        "value_byte, value_text, value_int32, value_int64, value_double, obj_id) VALUES (";
+        str << attr.getArtifactID() << ", ";
+    item = sqlite3_mprintf("%Q", attr.getModuleName().c_str()); str << item << ", ";
+    sqlite3_free(item);
+    item = sqlite3_mprintf("%Q", attr.getContext().c_str()); str << item << ", ";
+    sqlite3_free(item);
+    str << attr.getAttributeTypeID() << ", ";
+    str << attr.getValueType() << ", ";
+    switch (attr.getValueType()) {
+        case TSK_BYTE:
+            str << " ?, '', 0, 0, 0.0";
+            break;
+        case TSK_STRING:
+            item = sqlite3_mprintf("%Q", attr.getValueString().c_str());
+            str << " '', " << item << ", 0, 0, 0.0";
+            sqlite3_free(item);
+            break;
+        case TSK_INTEGER:
+            str << " '', '', " << attr.getValueInt() << ",     0, 0.0";
+            break;
+        case TSK_LONG:
+            str << " '', '', 0, " << attr.getValueLong() << ",     0.0";
+            break;
+        case TSK_DOUBLE:
+            str << " '', '', 0, 0, " << setprecision(20) << attr.getValueDouble();
+            break;
+    };
+    str << ", " << attr.getObjectID();
+    str << ")";
+
+    if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        int result = SQLITE_OK;
+        unsigned char *pBuf = 0;
+        if (attr.getValueType() == TSK_BYTE) {
+            // Bind the byte vector
+            int a_size = attr.getValueBytes().size();
+            pBuf = new unsigned char[a_size];
+            for (int i = 0; i < a_size; i++) {
+                pBuf[i] = attr.getValueBytes()[i];
+            }
+            result = sqlite3_bind_blob(statement, 1, pBuf, a_size, SQLITE_STATIC);
+        }
+        if (result == SQLITE_OK) {
+            result = sqlite3_step(statement);
+            if (!(result == SQLITE_ROW || result == SQLITE_DONE)) {
+                sqlite3_finalize(statement);
+                if (pBuf) delete [] pBuf;
+                throw TskException("TskImgDBSqlite::addBlackboardAttribute - Insert failed");
+            }
+        } else {
+            std::wstringstream infoMessage;
+            infoMessage << L"TskImgDBSqlite::addBlackboardAttribute - Error in sqlite3_bind_blob: " << sqlite3_errmsg(m_db);
+            LOGERROR(infoMessage.str());
+            throw TskException("TskImgDBSqlite::addBlackboardAttribute - Insert failed");
+        }
+        sqlite3_finalize(statement);
+        if (pBuf) delete [] pBuf;
+    } else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::addBlackboardAttribute - Error adding data to blackboard table: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+        throw TskException("TskImgDBSqlite::addBlackboardAttribute - Insert failed");
+    }
+}
+
+/**
+ * Get the display name for the given artifact type id
+ * @param artifactTypeID artifact type id
+ * @returns display name
+ */
+string TskImgDBSqlite::getArtifactTypeDisplayName(int artifactTypeID){
+    if (!m_db)
+        throw TskException("No database.");
+
+    std::stringstream str;
+    sqlite3_stmt * statement;
+    std::string displayName = "";
+
+    str << "SELECT display_name FROM blackboard_artifact_types WHERE artifact_type_id = " << artifactTypeID;
+
+    if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK){
+        int result = sqlite3_step(statement);
+        if (result == SQLITE_ROW) {
+            displayName = (char *)sqlite3_column_text(statement, 0);
+        }
+        else{
+            std::wstringstream infoMessage;
+            infoMessage << L"TskImgDBSqlite::getArtifactTypeDisplayName: " << sqlite3_errmsg(m_db);
+            LOGERROR(infoMessage.str());
+            throw TskException("TskImgDBSqlite::getArtifactTypeDisplayName - No artifact type with that ID");
+        }
+        sqlite3_finalize(statement);
+        return displayName;
+    }
+    else{
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getArtifactTypeDisplayName: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+        throw TskException("TskImgDBSqlite::getArtifactTypeDisplayName - Select failed");
+    }
+}
+
+/**
+ * Get the artifact type id for the given artifact type string
+ * @param artifactTypeString display name
+ * @returns artifact type id
+ */
+int TskImgDBSqlite::getArtifactTypeID(string artifactTypeString){
+    if (!m_db)
+        throw TskException("No database.");
+
+    std::stringstream str;
+    sqlite3_stmt * statement;
+    int typeID;
+
+    str << "SELECT artifact_type_id FROM blackboard_artifact_types WHERE type_name = " << artifactTypeString;
+
+    if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK){
+        int result = sqlite3_step(statement);
+        if (result == SQLITE_ROW) {
+            typeID = (int) sqlite3_column_int(statement, 0);
+        }
+        else{
+            std::wstringstream infoMessage;
+            infoMessage << L"TskImgDBSqlite::getArtifactTypeID: " << sqlite3_errmsg(m_db);
+            LOGERROR(infoMessage.str());
+            throw TskException("TskImgDBSqlite::getArtifactTypeID - No artifact type with that name");
+        }
+        sqlite3_finalize(statement);
+        return typeID;
+    }
+    else{
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getArtifactTypeID: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+        throw TskException("TskImgDBSqlite::getArtifactTypeID - Select failed");
+    }
+}
+
+/**
+ * Get the artifact type name for the given artifact type id
+ * @param artifactTypeID id
+ * @returns artifact type name
+ */
+string TskImgDBSqlite::getArtifactTypeName(int artifactTypeID){
+    if (!m_db)
+        throw TskException("No database.");
+
+    std::stringstream str;
+    sqlite3_stmt * statement;
+    std::string typeName = "";
+
+    str << "SELECT type_name FROM blackboard_artifact_types WHERE artifact_type_id = " << artifactTypeID;
+
+    if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK){
+        int result = sqlite3_step(statement);
+        if (result == SQLITE_ROW) {
+            typeName = (char *)sqlite3_column_text(statement, 0);
+        }
+        else{
+            std::wstringstream infoMessage;
+            infoMessage << L"TskImgDBSqlite::getArtifactTypeName: " << sqlite3_errmsg(m_db);
+            LOGERROR(infoMessage.str());
+            throw TskException("TskImgDBSqlite::getArtifactTypeName - No artifact type with that ID");
+        }
+        sqlite3_finalize(statement);
+        return typeName;
+    }
+    else{
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getArtifactTypeName: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+        throw TskException("TskImgDBSqlite::getArtifactTypeName - Select failed");
+    }
+}
+
+/**
+ * Get the display name for the given attribute type id
+ * @param attributeTypeID attribute type id
+ * @returns display name
+ */
+string TskImgDBSqlite::getAttributeTypeDisplayName(int attributeTypeID){
+    if (!m_db)
+        throw TskException("No database.");
+
+    std::stringstream str;
+    sqlite3_stmt * statement;
+    std::string displayName = "";
+
+    str << "SELECT display_name FROM blackboard_attribute_types WHERE attribute_type_id = " << attributeTypeID;
+
+    if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK){
+        int result = sqlite3_step(statement);
+        if (result == SQLITE_ROW) {
+            displayName = (char *)sqlite3_column_text(statement, 0);
+        }
+        else{
+            std::wstringstream infoMessage;
+            infoMessage << L"TskImgDBSqlite::getAttributeTypeDisplayName: " << sqlite3_errmsg(m_db);
+            LOGERROR(infoMessage.str());
+            throw TskException("TskImgDBSqlite::getAttributeTypeDisplayName - No attribute type with that ID");
+        }
+        sqlite3_finalize(statement);
+        return displayName;
+    }
+    else{
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getAttributeTypeDisplayName: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+        throw TskException("TskImgDBSqlite::getAttributeTypeDisplayName - Select failed");
+    }
+}
+
+/**
+ * Get the attribute type id for the given artifact type string
+ * @param attributeTypeString display name
+ * @returns attribute type id
+ */
+int TskImgDBSqlite::getAttributeTypeID(string attributeTypeString){
+    if (!m_db)
+        throw TskException("No database.");
+
+    std::stringstream str;
+    sqlite3_stmt * statement;
+    int typeID;
+
+    str << "SELECT attribute_type_id FROM blackboard_attribute_types WHERE type_name = " << attributeTypeString;
+
+    if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK){
+        int result = sqlite3_step(statement);
+        if (result == SQLITE_ROW) {
+            typeID = (int) sqlite3_column_int(statement, 0);
+        }
+        else{
+            std::wstringstream infoMessage;
+            infoMessage << L"TskImgDBSqlite::getAttributeTypeID: " << sqlite3_errmsg(m_db);
+            LOGERROR(infoMessage.str());
+            throw TskException("TskImgDBSqlite::getAttributeTypeID - No artifact type with that name");
+        }
+        sqlite3_finalize(statement);
+        return typeID;
+    }
+    else{
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getAttributeTypeID: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+        throw TskException("TskImgDBSqlite::getAttributeTypeID - Select failed");
+    }
+}
+
+/**
+ * Get the attribute type name for the given artifact type id
+ * @param attributeTypeID id
+ * @returns attribute type name
+ */
+string TskImgDBSqlite::getAttributeTypeName(int attributeTypeID){
+    if (!m_db)
+        throw TskException("No database.");
+
+    std::stringstream str;
+    sqlite3_stmt * statement;
+    std::string typeName = "";
+
+    str << "SELECT type_name FROM blackboard_attribute_types WHERE attribute_type_id = " << attributeTypeID;
+
+    if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK){
+        int result = sqlite3_step(statement);
+        if (result == SQLITE_ROW) {
+            typeName = (char *)sqlite3_column_text(statement, 0);
+        }
+        else{
+            std::wstringstream infoMessage;
+            infoMessage << L"TskImgDBSqlite::getAttributeTypeName: " << sqlite3_errmsg(m_db);
+            LOGERROR(infoMessage.str());
+            throw TskException("TskImgDBSqlite::getAttributeTypeName - No attribute type with that ID");
+        }
+        sqlite3_finalize(statement);
+        return typeName;
+    }
+    else{
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::getAttributeTypeName: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+        throw TskException("TskImgDBSqlite::getAttributeTypeName - Select failed");
+    }
+}
+
+/**
+ * Get all artifacts by performing a SQL Select statement with the given where clause.
+ * @param condition The SQL select where clause that should be used in the query.
+ * @returns vector of matching artifacts
+ */
+vector<TskBlackboardArtifact> TskImgDBSqlite::getMatchingArtifacts(string condition)
+{
+    if (!m_db)
+        throw TskException("No database.");
+    
+    vector<TskBlackboardArtifact> artifacts;
+    std::string stmt("SELECT blackboard_artifacts.artifact_id, blackboard_artifacts.obj_id, blackboard_artifacts.artifact_type_id FROM blackboard_artifacts");
+
+    constructStmt(stmt, condition);
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.c_str(), -1, &statement, 0) == SQLITE_OK) 
+    {
+        while (sqlite3_step(statement) == SQLITE_ROW) 
+        {
+            int artifactTypeID = sqlite3_column_int(statement, 2);
+
+            artifacts.push_back(TskImgDB::createArtifact(sqlite3_column_int64(statement, 0), sqlite3_column_int64(statement, 1), artifactTypeID));
+        }
+        sqlite3_finalize(statement);
+    } else 
+    {
+        std::wstringstream msg;
+        msg << L"TskImgDBSqlite::getMatchingArtifacts - Error getting artifacts: " << sqlite3_errmsg(m_db);
+        LOGERROR(msg.str());
+        throw TskException("TskImgDBSqlite::getMatchingArtifacts - Select failed");
+    }
+    return artifacts;
+}
+
+/**
+ * Get all attributes with that match the given where clause 
+ * @param condition where clause to use for matching
+ * @returns vector of matching attributes
+ */
+vector<TskBlackboardAttribute> TskImgDBSqlite::getMatchingAttributes(string condition)
+{
+    if (!m_db)
+        throw TskException("No database.");
+    
+    vector<TskBlackboardAttribute> attributes;
+    std::string stmt("SELECT blackboard_attributes.artifact_id, blackboard_attributes.source, blackboard_attributes.context, blackboard_attributes.attribute_type_id, blackboard_attributes.value_type, blackboard_attributes.value_byte, blackboard_attributes.value_text, blackboard_attributes.value_int32, blackboard_attributes.value_int64, blackboard_attributes.value_double, blackboard_attributes.obj_id FROM blackboard_attributes ");
+
+    constructStmt(stmt, condition);
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.c_str(), -1, &statement, 0) == SQLITE_OK) 
+    {
+        while (sqlite3_step(statement) == SQLITE_ROW) 
+        { 
+            int blobSize = sqlite3_column_bytes(statement, 6);
+            const unsigned char *pBlob = (const unsigned char *)sqlite3_column_blob(statement, 6);
+            vector<unsigned char> bytes;
+            bytes.reserve(blobSize);
+            for (int i = 0; i < blobSize; i++) {
+                bytes.push_back((unsigned char)pBlob[i]);
+            }
+
+            attributes.push_back(TskImgDB::createAttribute(sqlite3_column_int64(statement, 0),sqlite3_column_int(statement, 3), sqlite3_column_int64(statement, 10), std::string((char *)sqlite3_column_text(statement, 1)), 
+                std::string((char *)sqlite3_column_text(statement, 2)), (TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE) sqlite3_column_int(statement, 4), sqlite3_column_int(statement, 7), 
+                sqlite3_column_int64(statement, 8), sqlite3_column_double(statement, 9), std::string((char *)sqlite3_column_text(statement, 6)), bytes));
+        }
+        sqlite3_finalize(statement);
+    } else {
+        std::wstringstream msg;
+        msg << L"TskImgDBSqlite::getMatchingAttributes - Error getting attributes: " << sqlite3_errmsg(m_db);
+        LOGERROR(msg.str());
+        throw TskException("TskImgDBSqlite::getMatchingAttributes - Select failed");
+    }
+    return attributes;
+}
+
+/**
+ * Create a new blackboard artifact with the given type id and file id
+ * @param artifactTypeID artifact type id
+ * @param file_id associated file id
+ * @returns the new artifact
+ */
+TskBlackboardArtifact TskImgDBSqlite::createBlackboardArtifact(uint64_t file_id, int artifactTypeID)
+{
+    if (!m_db)
+        throw TskException("No database.");
+
+    uint64_t artifactId = 0;
+    std::stringstream str;
+    sqlite3_stmt * statement;
+
+    str << "INSERT INTO blackboard_artifacts (artifact_id, obj_id, artifact_type_id) VALUES (NULL, " << file_id << ", " << artifactTypeID << ")";
+
+    if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        if (!(sqlite3_step(statement) == SQLITE_DONE)) {
+            sqlite3_finalize(statement);
+            throw TskException("TskImgDBSqlite::addBlackboardInfo - Insert failed");
+        }
+        // select max(artifact_id) from blackboard
+        str.str("");
+        str << "SELECT artifact_id from blackboard_artifacts WHERE obj_id = " << file_id << " AND artifact_type_id = " << artifactTypeID;
+        sqlite3_finalize(statement);
+        if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+            while(sqlite3_step(statement) == SQLITE_ROW) {
+                uint64_t newID = sqlite3_column_int64(statement, 0);
+                if(newID > artifactId)
+                    artifactId = newID;
+            }
+        } else {
+            sqlite3_finalize(statement);
+            throw TskException("TskImgDBSqlite::newBlackboardArtifact - Select artifact_id failed");
+        }
+        sqlite3_finalize(statement);
+    } else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::newBlackboardArtifact - Error adding new artifact: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+        throw TskException("TskImgDBSqlite::newBlackboardArtifact - Insert failed");
+    }
+
+    return TskImgDB::createArtifact(artifactId, file_id, artifactTypeID);
+}
+
+/**
+ * Add a new artifact type with the given name, display name and id 
+ * @param artifactTypeName type name
+ * @param displayName display name
+ * @param typeID type id
+ */
+void TskImgDBSqlite::addArtifactType(int typeID, string artifactTypeName, string displayName)
+{
+    if (!m_db)
+        throw TskException("No database.");
+
+    std::stringstream str;
+    sqlite3_stmt * statement;
+
+    str << "SELECT * FROM blackboard_artifact_types WHERE type_name = '" << artifactTypeName << "'";
+
+    if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        if (!(sqlite3_step(statement) == SQLITE_ROW)) {
+            sqlite3_finalize(statement);
+            str.str("");
+            str << "INSERT INTO blackboard_artifact_types (artifact_type_id, type_name, display_name) VALUES (" << typeID << " , '" << artifactTypeName << "', '" << displayName << "')";
+            if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+                if (!(sqlite3_step(statement) == SQLITE_DONE)) {
+                    sqlite3_finalize(statement);
+                    std::wstringstream infoMessage;
+                    infoMessage << L"TskImgDBSqlite::addArtifactType - Error adding data to blackboard table: " << sqlite3_errmsg(m_db);
+                    LOGERROR(infoMessage.str());
+                    throw TskException("TskImgDBSqlite::addArtifactType - Artifact type insert failed");
+                }
+            }
+        }
+        else{
+            sqlite3_finalize(statement);
+            throw TskException("TskImgDBSqlite::addArtifactType - Artifact type with that name already exists");
+        }
+        sqlite3_finalize(statement);
+    } else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::addArtifactType - Error adding data to blackboard table: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+        throw TskException("TskImgDBSqlite::addArtifactType - Insert failed");
+    }
+}
+
+/**
+ * Add a new attribute type with the given name, display name and id 
+ * @param attributeTypeName type name
+ * @param displayName display name
+ * @param typeID type id
+ */
+void TskImgDBSqlite::addAttributeType(int typeID, string attributeTypeName, string displayName)
+{
+    if (!m_db)
+        throw TskException("No database.");
+
+    std::stringstream str;
+    sqlite3_stmt * statement;
+
+    str << "SELECT * FROM blackboard_attribute_types WHERE type_name = '" << attributeTypeName << "'";
+
+    if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+        if (!(sqlite3_step(statement) == SQLITE_ROW)) {
+            sqlite3_finalize(statement);
+            str.str("");
+            str << "INSERT INTO blackboard_attribute_types (attribute_type_id, type_name, display_name) VALUES (" << typeID << " , '" << attributeTypeName << "', '" << displayName << "')";
+            if (sqlite3_prepare_v2(m_db, str.str().c_str(), -1, &statement, 0) == SQLITE_OK) {
+                if (!(sqlite3_step(statement) == SQLITE_DONE)) {
+                    sqlite3_finalize(statement);
+                    std::wstringstream infoMessage;
+                    infoMessage << L"TskImgDBSqlite::addAttributeType - Error adding data to blackboard table: " << sqlite3_errmsg(m_db);
+                    LOGERROR(infoMessage.str());
+                    throw TskException("TskImgDBSqlite::addAttributeType - Attribute type insert failed");
+                }
+            }
+        } else {
+            sqlite3_finalize(statement);
+            throw TskException("TskImgDBSqlite::addAttributeType - Attribute type with that name already exists");
+        }
+        sqlite3_finalize(statement);
+    } else {
+        std::wstringstream infoMessage;
+        infoMessage << L"TskImgDBSqlite::addAttributeType - Error adding data to blackboard table: " << sqlite3_errmsg(m_db);
+        LOGERROR(infoMessage.str());
+        throw TskException("TskImgDBSqlite::addAttributeType - Insert failed");
+    }
+}
+
+/**
+ * Get all artifacts with the given type id, type name, and file id
+ * @param artifactTypeID type id
+ * @param artifactTypeName type name
+ * @param file_id file id
+ */
+vector<TskBlackboardArtifact> TskImgDBSqlite::getArtifactsHelper(uint64_t file_id, int artifactTypeID, string artifactTypeName)
+{
+    if (!m_db)
+        throw TskException("No database.");
+    
+    vector<TskBlackboardArtifact> artifacts;
+    std::stringstream stmt;
+    stmt << "SELECT artifact_id, obj_id, artifact_type_id FROM blackboard_artifacts WHERE obj_id = " << file_id << " AND artifact_type_id = " << artifactTypeID;
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) 
+    {
+        while (sqlite3_step(statement) == SQLITE_ROW) 
+        {
+            int artifactTypeID = sqlite3_column_int(statement, 2);
+
+            artifacts.push_back(TskImgDB::createArtifact(sqlite3_column_int64(statement, 0), file_id, artifactTypeID));
+        }
+        sqlite3_finalize(statement);
+    } else {
+        std::wstringstream msg;
+        msg << L"TskImgDBSqlite::getArtifactsHelper - Error getting artifacts: " << sqlite3_errmsg(m_db);
+        LOGERROR(msg.str());
+        throw TskException("TskImgDBSqlite::getArtifactsHelper - Select failed");
+    }
+    return artifacts;
+}
+
+vector<int> TskImgDBSqlite::findAttributeTypes(int artifactTypeId)
+{
+    if (!m_db) {
+        throw TskException("No database.");
+    }
+    vector<int> attrTypes;
+    std::stringstream stmt;
+    stmt << "SELECT DISTINCT(attribute_type_id) FROM blackboard_attributes JOIN blackboard_artifacts ON blackboard_attributes.artifact_id = blackboard_artifacts.artifact_id WHERE artifact_type_id = " << artifactTypeId;
+
+    sqlite3_stmt * statement;
+    if (sqlite3_prepare_v2(m_db, stmt.str().c_str(), -1, &statement, 0) == SQLITE_OK) 
+    {
+        while (sqlite3_step(statement) == SQLITE_ROW) 
+        {
+            int artifactTypeID = sqlite3_column_int(statement, 0);
+
+            attrTypes.push_back(artifactTypeID);
+        }
+        sqlite3_finalize(statement);
+    } else {
+        std::wstringstream msg;
+        msg << L"TskImgDBSqlite::findAttributeTypes - Error finding attribute types: " << sqlite3_errmsg(m_db);
+        LOGERROR(msg.str());
+        throw TskException("TskImgDBSqlite::findAttributeTypes - Select failed");
+    }
+    return attrTypes;
+}
+
+std::string TskImgDBSqlite::quote(const std::string str) const
+{
+    char *item = sqlite3_mprintf("%Q", str.c_str());
+    std::string returnStr(item);
+    sqlite3_free(item);
+    return returnStr;
+}
+
+void TskImgDBSqlite::executeStatement(const std::string &stmtToExecute, sqlite3_stmt *&statement, const std::string &caller) const
+{
+    if (sqlite3_prepare_v2(m_db, stmtToExecute.c_str(), -1, &statement, 0) != SQLITE_OK)
+    {
+        sqlite3_finalize(statement);
+        std::ostringstream msg;
+        msg << caller << " : error executing " << stmtToExecute << " : " << sqlite3_errmsg(m_db);
+        throw TskException(msg.str());
+    }
+}
+
+
diff --git a/framework/tsk/framework/services/TskImgDBSqlite.h b/framework/tsk/framework/services/TskImgDBSqlite.h
index b2c8854..c10e5cd 100755
--- a/framework/tsk/framework/services/TskImgDBSqlite.h
+++ b/framework/tsk/framework/services/TskImgDBSqlite.h
@@ -1,181 +1,181 @@
-/*
- *
- *  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_IMGDBSQLITE_H
-#define _TSK_IMGDBSQLITE_H
-
-// System includes
-#include <string> // to get std::wstring
-#include <list>
-#include <vector>
-using namespace std;
-
-// Framework includes
-#include "tsk/framework/framework_i.h"
-#include "TskImgDB.h"
-#include "tsk/framework/utilities/SectorRuns.h"
-#include "tsk/framework/utilities/UnallocRun.h"
-#include "TskBlackboardArtifact.h"
-#include "TskBlackboardAttribute.h"
-
-#include "tsk/libtsk.h"
-#include "tsk/auto/sqlite3.h"
-
-/** 
- * Implementation of TskImgDB that uses SQLite to store the data.
- * Do not use this in a distributed environment if multiple processes
- * will be accessing the database at the same time. 
- */
-class TSK_FRAMEWORK_API TskImgDBSqlite : public TskImgDB
-{
-public:
-    TskImgDBSqlite(const char * a_outpath);
-    virtual ~ TskImgDBSqlite();
-
-    virtual int initialize();
-    virtual int open();
-
-    virtual int close();
-
-    virtual int begin();
-    virtual int commit();
-
-    virtual int addToolInfo(const char* name, const char* version);
-    virtual int addImageInfo(int type, int sectorSize);
-    virtual int addImageName(char const * imgName);
-    virtual int addVolumeInfo(const TSK_VS_PART_INFO * vs_part);
-    virtual int addFsInfo(int volId, int fsId, const TSK_FS_INFO * fs_info);
-    virtual int addFsFileInfo(int fsId, const TSK_FS_FILE *fs_file, const char *name, int type, int idx, uint64_t & fileId, const char * path);
-
-    virtual int addCarvedFileInfo(int vol_id, const char * name, uint64_t size, uint64_t *runStarts, uint64_t *runLengths, int numRuns, uint64_t & fileId);
-    virtual int addDerivedFileInfo(const std::string& name, const uint64_t parentId,
-                                        const bool isDirectory, const uint64_t size, const std::string& details,
-                                        const int ctime, const int crtime, const int atime, const int mtime, uint64_t & fileId, std::string path);
-    virtual int addFsBlockInfo(int fsID, uint64_t a_mFileId, int count, uint64_t blk_addr, uint64_t len);
-    virtual int addAllocUnallocMapInfo(int a_volID, int unallocImgID, uint64_t unallocImgStart, uint64_t length, uint64_t origImgStart);
-    virtual int getSessionID() const;
-    virtual int getFileIds(char *a_fileName, uint64_t *a_outBuffer, int a_buffSize) const;
-    virtual int getMaxFileIdReadyForAnalysis(uint64_t a_lastFileId, uint64_t & maxFileId) const;
-    virtual int getMinFileIdReadyForAnalysis(uint64_t & minFileId) const;
-    virtual uint64_t getFileId(int fsId, uint64_t fs_file_id) const;
-    virtual int getFileRecord(const uint64_t fileId, TskFileRecord& fileRecord) const;
-    virtual SectorRuns * getFileSectors(uint64_t fileId) const;
-    virtual std::string getImageBaseName() const;
-    virtual std::vector<std::wstring> getImageNamesW() const;
-    virtual std::vector<std::string> getImageNames() const;
-    virtual int getFileUniqueIdentifiers(uint64_t a_fileId, uint64_t &a_fsOffset, uint64_t &a_fsFileId, int &a_attrType, int &a_attrId) const;
-    virtual int getNumVolumes() const;
-    virtual int getNumFiles() const;
-    virtual int getImageInfo(int & type, int & sectorSize) const;
-    virtual int getVolumeInfo(std::list<TskVolumeInfoRecord> & volumeInfoList) const;
-    virtual int getFsInfo(std::list<TskFsInfoRecord> & fsInfoList) const;
-    virtual int getFileInfoSummary(std::list<TskFileTypeRecord>& fileTypeInfoList) const;
-    virtual int getFileInfoSummary(FILE_TYPES fileType, std::list<TskFileTypeRecord> & fileTypeInfoList) const;
-    virtual TskImgDB::KNOWN_STATUS getKnownStatus(const uint64_t fileId) const;
-
-    virtual UnallocRun * getUnallocRun(int file_id, int file_offset) const; 
-    virtual SectorRuns * getFreeSectors() const;
-
-    virtual int updateFileStatus(uint64_t a_file_id, FILE_STATUS a_status);
-    virtual int updateKnownStatus(uint64_t a_file_id, KNOWN_STATUS a_status);
-	virtual bool dbExist() const;
-
-    // Get set of file ids that match the given condition (i.e. SQL where clause)
-    virtual std::vector<uint64_t> getFileIds(const std::string& condition) const;
-    virtual const std::vector<TskFileRecord> getFileRecords(const std::string& condition) const;
-
-    // Get the number of files that match the given condition
-    virtual int getFileCount(const std::string& condition) const;
-
-    virtual std::map<uint64_t, std::string> getUniqueCarvedFiles(HASH_TYPE hashType) const;
-    virtual std::vector<TskCarvedFileInfo> getUniqueCarvedFilesInfo(HASH_TYPE hashType) const;
-    virtual std::vector<uint64_t> getCarvedFileIds() const;
-
-    virtual std::vector<uint64_t> getUniqueFileIds(HASH_TYPE hashType) const;
-    virtual std::vector<uint64_t> getFileIds() const;
-
-    virtual int setHash(const uint64_t a_file_id, const TskImgDB::HASH_TYPE hashType, const std::string& hash) const;
-    virtual std::string getCfileName(const uint64_t a_file_id) const;
-
-    virtual int addModule(const std::string& name, const std::string& description, int & moduleId);
-    virtual int setModuleStatus(uint64_t file_id, int module_id, int status);
-	virtual int getModuleInfo(std::vector<TskModuleInfo> & moduleInfoList) const;
-    virtual int getModuleErrors(std::vector<TskModuleStatus> & moduleStatusList) const;
-    virtual std::string getFileName(uint64_t file_id) const;
-
-    virtual int addUnallocImg(int & unallocImgId);
-    virtual int setUnallocImgStatus(int unallocImgId, TskImgDB::UNALLOC_IMG_STATUS status);
-    virtual TskImgDB::UNALLOC_IMG_STATUS getUnallocImgStatus(int unallocImgId) const;
-    virtual int getAllUnallocImgStatus(std::vector<TskUnallocImgStatusRecord> & unallocImgStatusList) const;
-
-    virtual int addUnusedSectors(int unallocImgId, std::vector<TskUnusedSectorsRecord> & unusedSectorsList);
-    virtual int getUnusedSector(uint64_t fileId, TskUnusedSectorsRecord & unusedSectorsRecord) const;
-
-	virtual std::string quote(const std::string str) const;
-
-	friend class TskDBBlackboard;
-
-protected:
-    // Blackboard methods.
-    virtual TskBlackboardArtifact createBlackboardArtifact(uint64_t file_id, int artifactTypeID);
-    virtual void addBlackboardAttribute(TskBlackboardAttribute attr);
-    
-    virtual void addArtifactType(int typeID, string artifactTypeName, string displayName);
-    virtual void addAttributeType(int typeID, string attributeTypeName, string displayName);
-
-    virtual string getArtifactTypeDisplayName(int artifactTypeID);
-    virtual int getArtifactTypeID(string artifactTypeString);
-    virtual string getArtifactTypeName(int artifactTypeID);
-    virtual vector<TskBlackboardArtifact> getMatchingArtifacts(string condition);
-
-    virtual string getAttributeTypeDisplayName(int attributeTypeID);
-    virtual int getAttributeTypeID(string attributeTypeString);
-    virtual string getAttributeTypeName(int attributeTypeID);
-    virtual vector<TskBlackboardAttribute> getMatchingAttributes(string condition);
-    virtual vector<int> findAttributeTypes(int artifactTypeId);
-private:
-    char m_outPath[256];
-    char m_dbFilePath[256];
-    sqlite3 * m_db;
-
-    int dropTables();
-
-    static int busyHandler(void *, int);
-    std::vector<uint64_t> getFileIdsWorker(std::string tableName, const std::string condition = "") const;
-    void constructStmt(std::string& stmt, std::string condition) const;
-    int addUnusedSector(uint64_t sectStart, uint64_t sectEnd, int volId, std::vector<TskUnusedSectorsRecord> & unusedSectorsList);
-    int getFileTypeRecords(const std::string& stmt, std::list<TskFileTypeRecord>& fileTypeInfoList) const;
-    virtual vector<TskBlackboardArtifact> getArtifactsHelper(uint64_t file_id, int artifactTypeID, string artifactTypeName);
-    void getCarvedFileInfo(const std::string& stmt, std::map<uint64_t, std::string>& results) const;
-    
-    /**
-     * A helper function for getUniqueCarvedFilesInfo() that executes a very specific SQL SELECT statement 
-     * assembled by the caller.
-     *
-     * @param stmtToExecute The SQL statement.
-     * @param getHash A flag indicating whether the SELECT includes a hash value.
-     * @param carvedFileInfos[out] The data returned by the query as TskCarvedFileInfo objects.
-     * @return Throws TskException
-     */
-    void getCarvedFileInfo(const std::string &query,  bool getHash, std::vector<TskCarvedFileInfo> &carvedFileInfos) const;
-    
-    /**
-     * Executes an SQL statement.
-     *
-     * @param stmtToExecute The SQL statement.
-     * @param[out] statement The result set as a sqlite3_stmt object, caller should call sqlite3_finalize() on the pointer in case of normal execution. 
-     * @param caller The caller in the form <class_name>::<member_function_name> for error messages.
-     * @return Throws TskException.
-     */
-    void executeStatement(const std::string &stmtToExecute, sqlite3_stmt *&statement, const std::string &caller) 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
+ */
+
+#ifndef _TSK_IMGDBSQLITE_H
+#define _TSK_IMGDBSQLITE_H
+
+// System includes
+#include <string> // to get std::wstring
+#include <list>
+#include <vector>
+using namespace std;
+
+// Framework includes
+#include "tsk/framework/framework_i.h"
+#include "TskImgDB.h"
+#include "tsk/framework/utilities/SectorRuns.h"
+#include "tsk/framework/utilities/UnallocRun.h"
+#include "TskBlackboardArtifact.h"
+#include "TskBlackboardAttribute.h"
+
+#include "tsk/libtsk.h"
+#include "tsk/auto/sqlite3.h"
+
+/** 
+ * Implementation of TskImgDB that uses SQLite to store the data.
+ * Do not use this in a distributed environment if multiple processes
+ * will be accessing the database at the same time. 
+ */
+class TSK_FRAMEWORK_API TskImgDBSqlite : public TskImgDB
+{
+public:
+    TskImgDBSqlite(const char * a_outpath);
+    virtual ~ TskImgDBSqlite();
+
+    virtual int initialize();
+    virtual int open();
+
+    virtual int close();
+
+    virtual int begin();
+    virtual int commit();
+
+    virtual int addToolInfo(const char* name, const char* version);
+    virtual int addImageInfo(int type, int sectorSize);
+    virtual int addImageName(char const * imgName);
+    virtual int addVolumeInfo(const TSK_VS_PART_INFO * vs_part);
+    virtual int addFsInfo(int volId, int fsId, const TSK_FS_INFO * fs_info);
+    virtual int addFsFileInfo(int fsId, const TSK_FS_FILE *fs_file, const char *name, int type, int idx, uint64_t & fileId, const char * path);
+
+    virtual int addCarvedFileInfo(int vol_id, const char * name, uint64_t size, uint64_t *runStarts, uint64_t *runLengths, int numRuns, uint64_t & fileId);
+    virtual int addDerivedFileInfo(const std::string& name, const uint64_t parentId,
+                                        const bool isDirectory, const uint64_t size, const std::string& details,
+                                        const int ctime, const int crtime, const int atime, const int mtime, uint64_t & fileId, std::string path);
+    virtual int addFsBlockInfo(int fsID, uint64_t a_mFileId, int count, uint64_t blk_addr, uint64_t len);
+    virtual int addAllocUnallocMapInfo(int a_volID, int unallocImgID, uint64_t unallocImgStart, uint64_t length, uint64_t origImgStart);
+    virtual int getSessionID() const;
+    virtual int getFileIds(char *a_fileName, uint64_t *a_outBuffer, int a_buffSize) const;
+    virtual int getMaxFileIdReadyForAnalysis(uint64_t a_lastFileId, uint64_t & maxFileId) const;
+    virtual int getMinFileIdReadyForAnalysis(uint64_t & minFileId) const;
+    virtual uint64_t getFileId(int fsId, uint64_t fs_file_id) const;
+    virtual int getFileRecord(const uint64_t fileId, TskFileRecord& fileRecord) const;
+    virtual SectorRuns * getFileSectors(uint64_t fileId) const;
+    virtual std::string getImageBaseName() const;
+    virtual std::vector<std::wstring> getImageNamesW() const;
+    virtual std::vector<std::string> getImageNames() const;
+    virtual int getFileUniqueIdentifiers(uint64_t a_fileId, uint64_t &a_fsOffset, uint64_t &a_fsFileId, int &a_attrType, int &a_attrId) const;
+    virtual int getNumVolumes() const;
+    virtual int getNumFiles() const;
+    virtual int getImageInfo(int & type, int & sectorSize) const;
+    virtual int getVolumeInfo(std::list<TskVolumeInfoRecord> & volumeInfoList) const;
+    virtual int getFsInfo(std::list<TskFsInfoRecord> & fsInfoList) const;
+    virtual int getFileInfoSummary(std::list<TskFileTypeRecord>& fileTypeInfoList) const;
+    virtual int getFileInfoSummary(FILE_TYPES fileType, std::list<TskFileTypeRecord> & fileTypeInfoList) const;
+    virtual TskImgDB::KNOWN_STATUS getKnownStatus(const uint64_t fileId) const;
+
+    virtual UnallocRun * getUnallocRun(int file_id, int file_offset) const; 
+    virtual SectorRuns * getFreeSectors() const;
+
+    virtual int updateFileStatus(uint64_t a_file_id, FILE_STATUS a_status);
+    virtual int updateKnownStatus(uint64_t a_file_id, KNOWN_STATUS a_status);
+	virtual bool dbExist() const;
+
+    // Get set of file ids that match the given condition (i.e. SQL where clause)
+    virtual std::vector<uint64_t> getFileIds(const std::string& condition) const;
+    virtual const std::vector<TskFileRecord> getFileRecords(const std::string& condition) const;
+
+    // Get the number of files that match the given condition
+    virtual int getFileCount(const std::string& condition) const;
+
+    virtual std::map<uint64_t, std::string> getUniqueCarvedFiles(HASH_TYPE hashType) const;
+    virtual std::vector<TskCarvedFileInfo> getUniqueCarvedFilesInfo(HASH_TYPE hashType) const;
+    virtual std::vector<uint64_t> getCarvedFileIds() const;
+
+    virtual std::vector<uint64_t> getUniqueFileIds(HASH_TYPE hashType) const;
+    virtual std::vector<uint64_t> getFileIds() const;
+
+    virtual int setHash(const uint64_t a_file_id, const TskImgDB::HASH_TYPE hashType, const std::string& hash) const;
+    virtual std::string getCfileName(const uint64_t a_file_id) const;
+
+    virtual int addModule(const std::string& name, const std::string& description, int & moduleId);
+    virtual int setModuleStatus(uint64_t file_id, int module_id, int status);
+	virtual int getModuleInfo(std::vector<TskModuleInfo> & moduleInfoList) const;
+    virtual int getModuleErrors(std::vector<TskModuleStatus> & moduleStatusList) const;
+    virtual std::string getFileName(uint64_t file_id) const;
+
+    virtual int addUnallocImg(int & unallocImgId);
+    virtual int setUnallocImgStatus(int unallocImgId, TskImgDB::UNALLOC_IMG_STATUS status);
+    virtual TskImgDB::UNALLOC_IMG_STATUS getUnallocImgStatus(int unallocImgId) const;
+    virtual int getAllUnallocImgStatus(std::vector<TskUnallocImgStatusRecord> & unallocImgStatusList) const;
+
+    virtual int addUnusedSectors(int unallocImgId, std::vector<TskUnusedSectorsRecord> & unusedSectorsList);
+    virtual int getUnusedSector(uint64_t fileId, TskUnusedSectorsRecord & unusedSectorsRecord) const;
+
+	virtual std::string quote(const std::string str) const;
+
+	friend class TskDBBlackboard;
+
+protected:
+    // Blackboard methods.
+    virtual TskBlackboardArtifact createBlackboardArtifact(uint64_t file_id, int artifactTypeID);
+    virtual void addBlackboardAttribute(TskBlackboardAttribute attr);
+    
+    virtual void addArtifactType(int typeID, string artifactTypeName, string displayName);
+    virtual void addAttributeType(int typeID, string attributeTypeName, string displayName);
+
+    virtual string getArtifactTypeDisplayName(int artifactTypeID);
+    virtual int getArtifactTypeID(string artifactTypeString);
+    virtual string getArtifactTypeName(int artifactTypeID);
+    virtual vector<TskBlackboardArtifact> getMatchingArtifacts(string condition);
+
+    virtual string getAttributeTypeDisplayName(int attributeTypeID);
+    virtual int getAttributeTypeID(string attributeTypeString);
+    virtual string getAttributeTypeName(int attributeTypeID);
+    virtual vector<TskBlackboardAttribute> getMatchingAttributes(string condition);
+    virtual vector<int> findAttributeTypes(int artifactTypeId);
+private:
+    char m_outPath[256];
+    char m_dbFilePath[256];
+    sqlite3 * m_db;
+
+    int dropTables();
+
+    static int busyHandler(void *, int);
+    std::vector<uint64_t> getFileIdsWorker(std::string tableName, const std::string condition = "") const;
+    void constructStmt(std::string& stmt, std::string condition) const;
+    int addUnusedSector(uint64_t sectStart, uint64_t sectEnd, int volId, std::vector<TskUnusedSectorsRecord> & unusedSectorsList);
+    int getFileTypeRecords(const std::string& stmt, std::list<TskFileTypeRecord>& fileTypeInfoList) const;
+    virtual vector<TskBlackboardArtifact> getArtifactsHelper(uint64_t file_id, int artifactTypeID, string artifactTypeName);
+    void getCarvedFileInfo(const std::string& stmt, std::map<uint64_t, std::string>& results) const;
+    
+    /**
+     * A helper function for getUniqueCarvedFilesInfo() that executes a very specific SQL SELECT statement 
+     * assembled by the caller.
+     *
+     * @param stmtToExecute The SQL statement.
+     * @param getHash A flag indicating whether the SELECT includes a hash value.
+     * @param carvedFileInfos[out] The data returned by the query as TskCarvedFileInfo objects.
+     * @return Throws TskException
+     */
+    void getCarvedFileInfo(const std::string &query,  bool getHash, std::vector<TskCarvedFileInfo> &carvedFileInfos) const;
+    
+    /**
+     * Executes an SQL statement.
+     *
+     * @param stmtToExecute The SQL statement.
+     * @param[out] statement The result set as a sqlite3_stmt object, caller should call sqlite3_finalize() on the pointer in case of normal execution. 
+     * @param caller The caller in the form <class_name>::<member_function_name> for error messages.
+     * @return Throws TskException.
+     */
+    void executeStatement(const std::string &stmtToExecute, sqlite3_stmt *&statement, const std::string &caller) const;
+};
+
+#endif
diff --git a/framework/tsk/framework/services/TskSchedulerQueue.cpp b/framework/tsk/framework/services/TskSchedulerQueue.cpp
index 1409ac6..ce14730 100644
--- a/framework/tsk/framework/services/TskSchedulerQueue.cpp
+++ b/framework/tsk/framework/services/TskSchedulerQueue.cpp
@@ -1,36 +1,36 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-#include "TskSchedulerQueue.h"
-
-int TskSchedulerQueue::schedule(Scheduler::TaskType task, uint64_t startId, uint64_t endId)
-{
-    if (endId < startId) {
-        // @@@ Log a message
-        return -1;
-    }
-
-    for (uint64_t i = startId; i <= endId; i++) {
-        TskSchedulerQueue::task_struct *t = new(task_struct);
-        t->task = task;
-        t->id = i;
-        m_queue.push(t);
-    }
-    return 0;
-};
-
-Scheduler::task_struct *TskSchedulerQueue::nextTask() 
-{
-    if (m_queue.empty())
-        return NULL;
-    
-    task_struct *t = m_queue.front();
-    m_queue.pop();
-    return t;
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+#include "TskSchedulerQueue.h"
+
+int TskSchedulerQueue::schedule(Scheduler::TaskType task, uint64_t startId, uint64_t endId)
+{
+    if (endId < startId) {
+        // @@@ Log a message
+        return -1;
+    }
+
+    for (uint64_t i = startId; i <= endId; i++) {
+        TskSchedulerQueue::task_struct *t = new(task_struct);
+        t->task = task;
+        t->id = i;
+        m_queue.push(t);
+    }
+    return 0;
+};
+
+Scheduler::task_struct *TskSchedulerQueue::nextTask() 
+{
+    if (m_queue.empty())
+        return NULL;
+    
+    task_struct *t = m_queue.front();
+    m_queue.pop();
+    return t;
 };
\ No newline at end of file
diff --git a/framework/tsk/framework/services/TskSchedulerQueue.h b/framework/tsk/framework/services/TskSchedulerQueue.h
index cde5230..80a24de 100644
--- a/framework/tsk/framework/services/TskSchedulerQueue.h
+++ b/framework/tsk/framework/services/TskSchedulerQueue.h
@@ -1,32 +1,32 @@
-/*
- * The Sleuth Kit
- *
- * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2012 Basis Technology Corporation. All Rights
- * reserved.
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-#ifndef TSK_SCHEDULER_QUEUE
-#define TSK_SCHEDULER_QUEUE
-
-#include "Scheduler.h"
-#include <queue>
-
-/**
- * Implementation of the Scheduler interface that keeps a 
- * local queue of tasks to run. Can be used in a non-distributed
- * environment.
- */
-class TSK_FRAMEWORK_API TskSchedulerQueue : public Scheduler {
-public:
-    int schedule(Scheduler::TaskType task, uint64_t startId, uint64_t endId);
-    task_struct *nextTask();
-
-private:
-    std::queue <task_struct *> m_queue;  
-};
-
-
+/*
+ * The Sleuth Kit
+ *
+ * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2012 Basis Technology Corporation. All Rights
+ * reserved.
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+#ifndef TSK_SCHEDULER_QUEUE
+#define TSK_SCHEDULER_QUEUE
+
+#include "Scheduler.h"
+#include <queue>
+
+/**
+ * Implementation of the Scheduler interface that keeps a 
+ * local queue of tasks to run. Can be used in a non-distributed
+ * environment.
+ */
+class TSK_FRAMEWORK_API TskSchedulerQueue : public Scheduler {
+public:
+    int schedule(Scheduler::TaskType task, uint64_t startId, uint64_t endId);
+    task_struct *nextTask();
+
+private:
+    std::queue <task_struct *> m_queue;  
+};
+
+
 #endif
\ No newline at end of file
diff --git a/framework/tsk/framework/services/TskServices.cpp b/framework/tsk/framework/services/TskServices.cpp
index fb997cf..2a7c98d 100755
--- a/framework/tsk/framework/services/TskServices.cpp
+++ b/framework/tsk/framework/services/TskServices.cpp
@@ -1,238 +1,238 @@
-/*
- * 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 "TskServices.h"
-#include "tsk/framework/utilities/TskException.h"
-#include "tsk/framework/services/TskSystemPropertiesImpl.h"
-
-TskServices *TskServices::m_pInstance = NULL;
-
-/**
- * Singleton interface to return the TskServices instance.
- */
-TskServices &TskServices::Instance()
-{
-    if (!m_pInstance) {
-        m_pInstance = new TskServices;
-        m_pInstance->m_log = NULL;
-        m_pInstance->m_scheduler = NULL;
-        m_pInstance->m_imgDB = NULL;
-        m_pInstance->m_blackboard = NULL;
-        m_pInstance->m_systemProperties = NULL;
-        m_pInstance->m_imageFile = NULL;
-        m_pInstance->m_fileManager = NULL;
-    }
-    return *m_pInstance;
-}
-
-/** 
- * Return the system log service.  If no log was setup, a service will be
- * created that sends messages to stderr.
- * @returns log reference. 
- */
-Log& TskServices::getLog()
-{
-    // create a default one if it has not been set yet
-    if (!m_log) {
-        m_defaultLog.logInfo(L"TskServices::getLog - Log has not been set, using default implementation.");
-        return m_defaultLog;
-    }
-    return *m_log;
-}
-
-/**
- * Set the log service. 
- * Throws an exception if one has already been set. 
- */
-void TskServices::setLog(Log &log)
-{
-    if (m_log) {
-        LOGERROR(L"TskServices::setLog - Log has already been initialized.");
-        throw TskException("Log already initialized.");
-    } else {
-        m_log = &log;
-    }
-}
-
-/** 
- * Return the system scheduler service.  If no service was setup, an exception
- * is thrown.
- * @returns scheduler reference. 
- */
-Scheduler& TskServices::getScheduler()
-{
-    if (m_scheduler == NULL)
-    {
-        LOGERROR(L"TskServices::getScheduler - Scheduler has not been initialized.");
-        throw TskException("Scheduler not initialized.");
-    }
-
-    return *m_scheduler;
-}
-
-/**
- * Set the scheduler service. 
- * Throws an exception if one has already been set. 
- */
-void TskServices::setScheduler(Scheduler &scheduler)
-{
-    if (m_scheduler) {
-        LOGERROR(L"TskServices::setScheduler - Scheduler has already been initialized.");
-        throw TskException("Scheduler already initialized.");
-    } else {
-        m_scheduler = &scheduler;
-    }
-}
-
-
-/** 
- * Return the database service.  If no service was setup, an exception
- * is thrown.
- * @returns database reference. 
- */
-TskImgDB& TskServices::getImgDB()
-{
-    if (m_imgDB == NULL)
-    {
-        LOGERROR(L"TskServices::getImgDB - ImgDB has not been initialized.");
-        throw TskException("ImgDB not initialized.");
-    }
-
-    return *m_imgDB;
-}
-
-/**
- * Set the database service. 
- * Throws an exception if one has already been set. 
- */
-void TskServices::setImgDB(TskImgDB& imgDB)
-{
-    if (m_imgDB) {
-        LOGERROR(L"TskServices::setImgDB - ImgDB has already been initialized.");
-        throw TskException("ImgDB already initialized.");
-    } else {
-        m_imgDB = &imgDB;
-    }
-}
-
-
-
-/**
- * Set the image file service. 
- * Throws an exception if one has already been set. 
- */
-void TskServices::setImageFile(TskImageFile& imageFile)
-{
-    if (m_imageFile) {
-        LOGERROR(L"TskServices::setImageFile - ImageFile has already been initialized.");
-        throw TskException("ImageFile already initialized.");
-    } else {
-        m_imageFile = &imageFile;
-    }
-}
-
-/** 
- * Return the image file service.  If no service was setup, an exception
- * is thrown.
- * @returns image file reference. 
- */
-TskImageFile& TskServices::getImageFile()
-{
-    if (m_imageFile == NULL)
-    {
-        LOGERROR(L"TskServices::getImageFile - ImageFile has not been initialized.");
-        throw TskException("ImageFile not initialized.");
-    }
-
-    return *m_imageFile;
-}
-
-/**
- * Set the blackboard service. 
- * Throws an exception if one has already been set. 
- */
-void TskServices::setBlackboard(TskBlackboard& blackboard)
-{
-    if (m_blackboard) {
-        LOGERROR(L"TskServices::setBlackboard - Blackboard has already been initialized.");
-        throw TskException("Blackboard already initialized.");
-    } else {
-        m_blackboard = &blackboard;
-    }
-}
-
-/** 
- * Return the blackboard service.  If no service was setup, an exception
- * is thrown.
- * @returns blackboard file reference. 
- */
-TskBlackboard& TskServices::getBlackboard()
-{
-    if (m_blackboard == NULL)
-    {
-        LOGERROR(L"TskServices::getBlackboard - Blackboard has not been initialized.");
-        throw TskException("Blackboard not initialized.");
-    }
-    return *m_blackboard;
-}
-
-/**
- * Set the system properties service. 
- * Throws an exception if one has already been set. 
- */
-void TskServices::setSystemProperties(TskSystemProperties& systemProperties)
-{
-    if (m_systemProperties) {
-        LOGERROR(L"TskServices::setSystemProperties - SystemProperties has already been initialized.");
-        throw TskException("SystemProperties already initialized.");
-    } else {
-        m_systemProperties = &systemProperties;
-    }
-}
-
-/** 
- * Return the system properties service.  If no service was setup, a
- * default memory-based version is created.
- * @returns system properties reference. 
- */
-TskSystemProperties& TskServices::getSystemProperties()
-{
-    if (m_systemProperties == NULL)
-    {
-        TskSystemPropertiesImpl *prop = new TskSystemPropertiesImpl();
-        prop->initialize();
-        setSystemProperties(*prop);
-
-        LOGINFO(L"TskServices::getSystemProperties - SystemProperties has not been set, using default implementation.");
-    }
-    return *m_systemProperties;
-}
-
-void TskServices::setFileManager(TskFileManager& fileManager)
-{
-    if (m_fileManager) {
-        LOGERROR(L"TskServices::setFileManager - File Manager has already been initialized.");
-        throw TskException("FileManager already initialized.");
-    } else {
-        m_fileManager = &fileManager;
-    }
-}
-
-TskFileManager& TskServices::getFileManager()
-{
-    if (m_fileManager == NULL)
-    {
-        LOGERROR(L"TskServices::getFileManager - File Manager has not been initialized.");
-        throw TskException("File Manager not initialized.");
-    }
-    return *m_fileManager;
-}
+/*
+ * 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 "TskServices.h"
+#include "tsk/framework/utilities/TskException.h"
+#include "tsk/framework/services/TskSystemPropertiesImpl.h"
+
+TskServices *TskServices::m_pInstance = NULL;
+
+/**
+ * Singleton interface to return the TskServices instance.
+ */
+TskServices &TskServices::Instance()
+{
+    if (!m_pInstance) {
+        m_pInstance = new TskServices;
+        m_pInstance->m_log = NULL;
+        m_pInstance->m_scheduler = NULL;
+        m_pInstance->m_imgDB = NULL;
+        m_pInstance->m_blackboard = NULL;
+        m_pInstance->m_systemProperties = NULL;
+        m_pInstance->m_imageFile = NULL;
+        m_pInstance->m_fileManager = NULL;
+    }
+    return *m_pInstance;
+}
+
+/** 
+ * Return the system log service.  If no log was setup, a service will be
+ * created that sends messages to stderr.
+ * @returns log reference. 
+ */
+Log& TskServices::getLog()
+{
+    // create a default one if it has not been set yet
+    if (!m_log) {
+        m_defaultLog.logInfo(L"TskServices::getLog - Log has not been set, using default implementation.");
+        return m_defaultLog;
+    }
+    return *m_log;
+}
+
+/**
+ * Set the log service. 
+ * Throws an exception if one has already been set. 
+ */
+void TskServices::setLog(Log &log)
+{
+    if (m_log) {
+        LOGERROR(L"TskServices::setLog - Log has already been initialized.");
+        throw TskException("Log already initialized.");
+    } else {
+        m_log = &log;
+    }
+}
+
+/** 
+ * Return the system scheduler service.  If no service was setup, an exception
+ * is thrown.
+ * @returns scheduler reference. 
+ */
+Scheduler& TskServices::getScheduler()
+{
+    if (m_scheduler == NULL)
+    {
+        LOGERROR(L"TskServices::getScheduler - Scheduler has not been initialized.");
+        throw TskException("Scheduler not initialized.");
+    }
+
+    return *m_scheduler;
+}
+
+/**
+ * Set the scheduler service. 
+ * Throws an exception if one has already been set. 
+ */
+void TskServices::setScheduler(Scheduler &scheduler)
+{
+    if (m_scheduler) {
+        LOGERROR(L"TskServices::setScheduler - Scheduler has already been initialized.");
+        throw TskException("Scheduler already initialized.");
+    } else {
+        m_scheduler = &scheduler;
+    }
+}
+
+
+/** 
+ * Return the database service.  If no service was setup, an exception
+ * is thrown.
+ * @returns database reference. 
+ */
+TskImgDB& TskServices::getImgDB()
+{
+    if (m_imgDB == NULL)
+    {
+        LOGERROR(L"TskServices::getImgDB - ImgDB has not been initialized.");
+        throw TskException("ImgDB not initialized.");
+    }
+
+    return *m_imgDB;
+}
+
+/**
+ * Set the database service. 
+ * Throws an exception if one has already been set. 
+ */
+void TskServices::setImgDB(TskImgDB& imgDB)
+{
+    if (m_imgDB) {
+        LOGERROR(L"TskServices::setImgDB - ImgDB has already been initialized.");
+        throw TskException("ImgDB already initialized.");
+    } else {
+        m_imgDB = &imgDB;
+    }
+}
+
+
+
+/**
+ * Set the image file service. 
+ * Throws an exception if one has already been set. 
+ */
+void TskServices::setImageFile(TskImageFile& imageFile)
+{
+    if (m_imageFile) {
+        LOGERROR(L"TskServices::setImageFile - ImageFile has already been initialized.");
+        throw TskException("ImageFile already initialized.");
+    } else {
+        m_imageFile = &imageFile;
+    }
+}
+
+/** 
+ * Return the image file service.  If no service was setup, an exception
+ * is thrown.
+ * @returns image file reference. 
+ */
+TskImageFile& TskServices::getImageFile()
+{
+    if (m_imageFile == NULL)
+    {
+        LOGERROR(L"TskServices::getImageFile - ImageFile has not been initialized.");
+        throw TskException("ImageFile not initialized.");
+    }
+
+    return *m_imageFile;
+}
+
+/**
+ * Set the blackboard service. 
+ * Throws an exception if one has already been set. 
+ */
+void TskServices::setBlackboard(TskBlackboard& blackboard)
+{
+    if (m_blackboard) {
+        LOGERROR(L"TskServices::setBlackboard - Blackboard has already been initialized.");
+        throw TskException("Blackboard already initialized.");
+    } else {
+        m_blackboard = &blackboard;
+    }
+}
+
+/** 
+ * Return the blackboard service.  If no service was setup, an exception
+ * is thrown.
+ * @returns blackboard file reference. 
+ */
+TskBlackboard& TskServices::getBlackboard()
+{
+    if (m_blackboard == NULL)
+    {
+        LOGERROR(L"TskServices::getBlackboard - Blackboard has not been initialized.");
+        throw TskException("Blackboard not initialized.");
+    }
+    return *m_blackboard;
+}
+
+/**
+ * Set the system properties service. 
+ * Throws an exception if one has already been set. 
+ */
+void TskServices::setSystemProperties(TskSystemProperties& systemProperties)
+{
+    if (m_systemProperties) {
+        LOGERROR(L"TskServices::setSystemProperties - SystemProperties has already been initialized.");
+        throw TskException("SystemProperties already initialized.");
+    } else {
+        m_systemProperties = &systemProperties;
+    }
+}
+
+/** 
+ * Return the system properties service.  If no service was setup, a
+ * default memory-based version is created.
+ * @returns system properties reference. 
+ */
+TskSystemProperties& TskServices::getSystemProperties()
+{
+    if (m_systemProperties == NULL)
+    {
+        TskSystemPropertiesImpl *prop = new TskSystemPropertiesImpl();
+        prop->initialize();
+        setSystemProperties(*prop);
+
+        LOGINFO(L"TskServices::getSystemProperties - SystemProperties has not been set, using default implementation.");
+    }
+    return *m_systemProperties;
+}
+
+void TskServices::setFileManager(TskFileManager& fileManager)
+{
+    if (m_fileManager) {
+        LOGERROR(L"TskServices::setFileManager - File Manager has already been initialized.");
+        throw TskException("FileManager already initialized.");
+    } else {
+        m_fileManager = &fileManager;
+    }
+}
+
+TskFileManager& TskServices::getFileManager()
+{
+    if (m_fileManager == NULL)
+    {
+        LOGERROR(L"TskServices::getFileManager - File Manager has not been initialized.");
+        throw TskException("File Manager not initialized.");
+    }
+    return *m_fileManager;
+}
diff --git a/framework/tsk/framework/services/TskServices.h b/framework/tsk/framework/services/TskServices.h
index 00ec69e..996aefc 100755
--- a/framework/tsk/framework/services/TskServices.h
+++ b/framework/tsk/framework/services/TskServices.h
@@ -1,208 +1,208 @@
-/*
- * 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_SERVICES_H
-#define _TSK_SERVICES_H
-
-#include "Log.h"
-#include "Scheduler.h"
-#include "TskImgDB.h"
-#include "tsk/framework/extraction/TskImageFile.h"
-#include "tsk/framework/services/TskBlackboard.h"
-#include "tsk/framework/services/TskSystemProperties.h"
-#include "tsk/framework/file/TskFileManager.h"
-
-/**
- * Provides singleton access to many framework services.  This is used
- * to register and access the classes that implement the services. 
- */
-class TSK_FRAMEWORK_API TskServices
-{
-public:
-    static TskServices &Instance(); 
-
-    Log& getLog();
-    void setLog(Log &log);
-
-    void setScheduler(Scheduler &scheduler);
-    Scheduler& getScheduler();
-
-    void setImgDB(TskImgDB& imgDB);
-    TskImgDB& getImgDB();
-
-    void setImageFile(TskImageFile& imgFile);
-    TskImageFile& getImageFile();
-
-    void setBlackboard(TskBlackboard& blackboard);
-    TskBlackboard& getBlackboard();
-
-    void setSystemProperties(TskSystemProperties& systemProperties);
-    TskSystemProperties& getSystemProperties();
-
-    /**
-     * Set the File Manager service.
-     * The standard framework implementation class is TskFileManagerImpl.
-     * @param fileManager A File Manager implementation.
-     * @throws TskException if one has already been set.
-     */
-    void setFileManager(TskFileManager& fileManager);
-    /**
-     * Return the File Manager service.
-     * @returns File Manager reference.
-     * @throws TskException if File Manager has not been set.
-     */
-    TskFileManager& getFileManager();
-
-private:
-    // Private constructor, copy constructor and assignment operator
-    // to prevent creation of multiple instances.
-    TskServices() {};
-    TskServices(TskServices const&) {};
-    TskServices& operator=(TskServices const&) { return *m_pInstance; };
-
-    // Private destructor to prevent deletion of our instance.
-    ~TskServices() {};
-
-    // Default log instance that is used until TskServices::setLog() is called.
-    Log m_defaultLog;
-
-    static TskServices *m_pInstance;
-    Log *m_log;
-    Scheduler *m_scheduler;
-    TskImgDB * m_imgDB;
-    TskImageFile * m_imageFile;
-    TskBlackboard * m_blackboard;
-    TskSystemProperties * m_systemProperties;
-    TskFileManager * m_fileManager;
-};
-
-/** 
- * Associates a string value with a name.
- *
- * @param prop An element of the /ref PredefinedProperty enum.
- * @param value The value to associate with the name corresponding to the
- * /ref PredefinedProperty enum element.
- * @return Throws /ref TskException if prop is out of range.
- */
-inline void SetSystemPropertyW(TskSystemProperties::PredefinedProperty prop, const std::wstring &value)
-{
-    TskServices::Instance().getSystemProperties().setW(prop, value);
-}
-
-/** 
- * Associates a string value with a name.
- *
- * @param name The name with which to associate the value.
- * @param value The value to associate with the name.
- * @return Throws /ref TskException if name is empty.
- */
-inline void SetSystemPropertyW(const std::wstring &name, const std::wstring &value)
-{
-    TskServices::Instance().getSystemProperties().setW(name, value);
-}
-
-/** 
- * Associates a string value with a name.
- *
- * @param prop An element of the /ref PredefinedProperty enum.
- * @param value The value to associate with the name corresponding to the
- * /ref PredefinedProperty enum element.
- * @return Throws /ref TskException if prop is out of range.
- */
-inline void SetSystemProperty(TskSystemProperties::PredefinedProperty prop, const std::string &value)
-{
-    TskServices::Instance().getSystemProperties().set(prop, value);
-}
-
-/** 
- * Associates a string value with a name.
- *
- * @param name The name with which to associate the value.
- * @param value The value to associate with the name.
- * @return Throws /ref TskException if name is empty.
- */
-inline void SetSystemProperty(const std::string &name, const std::string &value)
-{
-    TskServices::Instance().getSystemProperties().set(name, value);
-}
-
-/** 
- * Retrieves the string value associated with the given name.
- *
- * @param prop An element of the /ref PredefinedProperty enum.
- * @returns String value corresponding to prop. Throws
- * /ref TskException if the requested value is for a required predefined 
- * property that is not set.
- */
-inline std::wstring GetSystemPropertyW(TskSystemProperties::PredefinedProperty prop)
-{
-    return TskServices::Instance().getSystemProperties().getW(prop);
-}
-
-/** 
- * Retrieves the string value associated with the given name.
- *
- * @param name Name of value to retrieve.
- * @returns String value or empty string if name was not found. 
- */
-inline std::wstring GetSystemPropertyW(const std::wstring &name)
-{
-    return TskServices::Instance().getSystemProperties().getW(name);
-}
-
-/** 
- * Retrieves the string value associated with the given name.
- *
- * @param prop An element of the /ref PredefinedProperty enum.
- * @returns String value corresponding to prop. Throws
- * /ref TskException if the requested value is for a required predefined 
- * property that is not set.
- */
-inline std::string GetSystemProperty(TskSystemProperties::PredefinedProperty prop)
-{
-    return TskServices::Instance().getSystemProperties().get(prop);
-}
-
-/** 
- * Retrieves the string value associated with the given name.
- *
- * @param name Name of value to retrieve.
- * @returns String value or empty string if name was not found. 
- */
-inline std::string GetSystemProperty(const std::string &name)
-{
-    return TskServices::Instance().getSystemProperties().get(name);
-}
-
-/**
- * Recursively expands any system property macros in a given string. 
- *
- * @param inputStr The input string.
- * @return A copy of the input string with all system property macros
- * expanded.
- */
-inline std::wstring ExpandSystemPropertyMacrosW(const std::wstring &inputStr)
-{
-    return TskServices::Instance().getSystemProperties().expandMacrosW(inputStr);
-}
-
-/**
- * Recursively expands any system property macros in a given string. 
- *
- * @param inputStr The input string.
- * @return A copy of the input string with all system property macros
- * expanded.
- */
-inline std::string ExpandSystemPropertyMacros(const std::string &inputStr)
-{
-    return TskServices::Instance().getSystemProperties().expandMacros(inputStr);
-}
-
-#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_SERVICES_H
+#define _TSK_SERVICES_H
+
+#include "Log.h"
+#include "Scheduler.h"
+#include "TskImgDB.h"
+#include "tsk/framework/extraction/TskImageFile.h"
+#include "tsk/framework/services/TskBlackboard.h"
+#include "tsk/framework/services/TskSystemProperties.h"
+#include "tsk/framework/file/TskFileManager.h"
+
+/**
+ * Provides singleton access to many framework services.  This is used
+ * to register and access the classes that implement the services. 
+ */
+class TSK_FRAMEWORK_API TskServices
+{
+public:
+    static TskServices &Instance(); 
+
+    Log& getLog();
+    void setLog(Log &log);
+
+    void setScheduler(Scheduler &scheduler);
+    Scheduler& getScheduler();
+
+    void setImgDB(TskImgDB& imgDB);
+    TskImgDB& getImgDB();
+
+    void setImageFile(TskImageFile& imgFile);
+    TskImageFile& getImageFile();
+
+    void setBlackboard(TskBlackboard& blackboard);
+    TskBlackboard& getBlackboard();
+
+    void setSystemProperties(TskSystemProperties& systemProperties);
+    TskSystemProperties& getSystemProperties();
+
+    /**
+     * Set the File Manager service.
+     * The standard framework implementation class is TskFileManagerImpl.
+     * @param fileManager A File Manager implementation.
+     * @throws TskException if one has already been set.
+     */
+    void setFileManager(TskFileManager& fileManager);
+    /**
+     * Return the File Manager service.
+     * @returns File Manager reference.
+     * @throws TskException if File Manager has not been set.
+     */
+    TskFileManager& getFileManager();
+
+private:
+    // Private constructor, copy constructor and assignment operator
+    // to prevent creation of multiple instances.
+    TskServices() {};
+    TskServices(TskServices const&) {};
+    TskServices& operator=(TskServices const&) { return *m_pInstance; };
+
+    // Private destructor to prevent deletion of our instance.
+    ~TskServices() {};
+
+    // Default log instance that is used until TskServices::setLog() is called.
+    Log m_defaultLog;
+
+    static TskServices *m_pInstance;
+    Log *m_log;
+    Scheduler *m_scheduler;
+    TskImgDB * m_imgDB;
+    TskImageFile * m_imageFile;
+    TskBlackboard * m_blackboard;
+    TskSystemProperties * m_systemProperties;
+    TskFileManager * m_fileManager;
+};
+
+/** 
+ * Associates a string value with a name.
+ *
+ * @param prop An element of the /ref PredefinedProperty enum.
+ * @param value The value to associate with the name corresponding to the
+ * /ref PredefinedProperty enum element.
+ * @return Throws /ref TskException if prop is out of range.
+ */
+inline void SetSystemPropertyW(TskSystemProperties::PredefinedProperty prop, const std::wstring &value)
+{
+    TskServices::Instance().getSystemProperties().setW(prop, value);
+}
+
+/** 
+ * Associates a string value with a name.
+ *
+ * @param name The name with which to associate the value.
+ * @param value The value to associate with the name.
+ * @return Throws /ref TskException if name is empty.
+ */
+inline void SetSystemPropertyW(const std::wstring &name, const std::wstring &value)
+{
+    TskServices::Instance().getSystemProperties().setW(name, value);
+}
+
+/** 
+ * Associates a string value with a name.
+ *
+ * @param prop An element of the /ref PredefinedProperty enum.
+ * @param value The value to associate with the name corresponding to the
+ * /ref PredefinedProperty enum element.
+ * @return Throws /ref TskException if prop is out of range.
+ */
+inline void SetSystemProperty(TskSystemProperties::PredefinedProperty prop, const std::string &value)
+{
+    TskServices::Instance().getSystemProperties().set(prop, value);
+}
+
+/** 
+ * Associates a string value with a name.
+ *
+ * @param name The name with which to associate the value.
+ * @param value The value to associate with the name.
+ * @return Throws /ref TskException if name is empty.
+ */
+inline void SetSystemProperty(const std::string &name, const std::string &value)
+{
+    TskServices::Instance().getSystemProperties().set(name, value);
+}
+
+/** 
+ * Retrieves the string value associated with the given name.
+ *
+ * @param prop An element of the /ref PredefinedProperty enum.
+ * @returns String value corresponding to prop. Throws
+ * /ref TskException if the requested value is for a required predefined 
+ * property that is not set.
+ */
+inline std::wstring GetSystemPropertyW(TskSystemProperties::PredefinedProperty prop)
+{
+    return TskServices::Instance().getSystemProperties().getW(prop);
+}
+
+/** 
+ * Retrieves the string value associated with the given name.
+ *
+ * @param name Name of value to retrieve.
+ * @returns String value or empty string if name was not found. 
+ */
+inline std::wstring GetSystemPropertyW(const std::wstring &name)
+{
+    return TskServices::Instance().getSystemProperties().getW(name);
+}
+
+/** 
+ * Retrieves the string value associated with the given name.
+ *
+ * @param prop An element of the /ref PredefinedProperty enum.
+ * @returns String value corresponding to prop. Throws
+ * /ref TskException if the requested value is for a required predefined 
+ * property that is not set.
+ */
+inline std::string GetSystemProperty(TskSystemProperties::PredefinedProperty prop)
+{
+    return TskServices::Instance().getSystemProperties().get(prop);
+}
+
+/** 
+ * Retrieves the string value associated with the given name.
+ *
+ * @param name Name of value to retrieve.
+ * @returns String value or empty string if name was not found. 
+ */
+inline std::string GetSystemProperty(const std::string &name)
+{
+    return TskServices::Instance().getSystemProperties().get(name);
+}
+
+/**
+ * Recursively expands any system property macros in a given string. 
+ *
+ * @param inputStr The input string.
+ * @return A copy of the input string with all system property macros
+ * expanded.
+ */
+inline std::wstring ExpandSystemPropertyMacrosW(const std::wstring &inputStr)
+{
+    return TskServices::Instance().getSystemProperties().expandMacrosW(inputStr);
+}
+
+/**
+ * Recursively expands any system property macros in a given string. 
+ *
+ * @param inputStr The input string.
+ * @return A copy of the input string with all system property macros
+ * expanded.
+ */
+inline std::string ExpandSystemPropertyMacros(const std::string &inputStr)
+{
+    return TskServices::Instance().getSystemProperties().expandMacros(inputStr);
+}
+
+#endif
diff --git a/framework/tsk/framework/services/TskSystemProperties.cpp b/framework/tsk/framework/services/TskSystemProperties.cpp
index 1804eaa..c200c88 100644
--- a/framework/tsk/framework/services/TskSystemProperties.cpp
+++ b/framework/tsk/framework/services/TskSystemProperties.cpp
@@ -1,274 +1,274 @@
-/*
- *  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 TskSystemProperties.cpp
- * Contains the implementation of the TskSystemProperties class.
- */
-
-// Include the class definition first to ensure it does not depend on subsequent includes in this file.
-#include "TskSystemProperties.h"
-
-// TSK Framework includes
-#include "tsk/framework/services/TskServices.h" // @@@ TODO: Resolve need to include TskServices.h before Log.h (macros in Log.h cause circular references)
-#include "tsk/framework/services/Log.h"
-#include "tsk/framework/utilities/TskUtilities.h"
-#include "tsk/framework/utilities/TskException.h"
-
-// Poco includes
-#include "Poco/Path.h"
-#include "Poco/StringTokenizer.h"
-#include "Poco/LocalDateTime.h"
-#include "Poco/DateTimeFormatter.h"
-
-// C/C++ library includes
-#include <sstream>
-#include <assert.h>
-
-namespace
-{
-    const std::string DEFAULT_PROG_DIR = Poco::Path::current();
-    const std::string DEFAULT_CONFIG_DIR = std::string("#PROG_DIR#") + Poco::Path::separator() + std::string("Config");
-    const std::string DEFAULT_MODULE_DIR = std::string("#PROG_DIR#") + Poco::Path::separator() + std::string("Modules");
-    const std::string DEFAULT_SYSTEM_OUT_DIR = std::string("#OUT_DIR#") + Poco::Path::separator() + std::string("SystemOutput");
-    const std::string DEFAULT_MODULE_OUT_DIR = std::string("#OUT_DIR#") + Poco::Path::separator() + std::string("ModuleOutput");
-    const std::string DEFAULT_LOG_DIR = std::string("#SYSTEM_OUT_DIR#") + Poco::Path::separator() + std::string("Logs");
-    const std::string DEFAULT_CARVE_DIR = std::string("#SYSTEM_OUT_DIR#") + Poco::Path::separator() + std::string("Carving");
-    const std::string DEFAULT_UNALLOC_SECTORS_IMG_FILE_NAME = "unalloc.bin";
-    const std::string DEFAULT_MAX_UNALLOC_SECTORS_IMG_FILE_SIZE = "0";
-    const std::string DEFAULT_CARVE_EXTRACT_KEEP_INPUT_FILES = "false";
-    const std::string DEFAULT_CARVE_EXTRACT_KEEP_OUTPUT_FILES = "false";
-    const std::string DEFAULT_SCALPEL_CONFIG_FILE = std::string("#SCALPEL_DIR#") + Poco::Path::separator() + std::string("scalpel.conf");
-    const std::string DEFAULT_PIPELINE_CONFIG_FILE = std::string("#CONFIG_DIR#") + Poco::Path::separator() + std::string("pipeline_config.xml");
-
-    struct PredefProp
-    {
-        PredefProp(TskSystemProperties::PredefinedProperty propId, const std::string &macroToken, bool propRequired, const std::string &propDefaultValue) :
-            id(propId), token(macroToken), required(propRequired), defaultValue(propDefaultValue) {}
-        TskSystemProperties::PredefinedProperty id;
-        std::string token;
-        bool required;
-        std::string defaultValue;
-    };
-
-    const PredefProp predefinedProperties[] =
-    {
-        PredefProp(TskSystemProperties::PROG_DIR, "PROG_DIR", false, ""),
-        PredefProp(TskSystemProperties::CONFIG_DIR, "CONFIG_DIR", false, DEFAULT_CONFIG_DIR),
-        PredefProp(TskSystemProperties::MODULE_DIR, "MODULE_DIR", false, DEFAULT_MODULE_DIR),
-        PredefProp(TskSystemProperties::MODULE_CONFIG_DIR, "MODULE_CONFIG_DIR", false, DEFAULT_MODULE_DIR),    // default == MODULE_DIR
-        PredefProp(TskSystemProperties::OUT_DIR, "OUT_DIR", true, ""),
-        PredefProp(TskSystemProperties::SYSTEM_OUT_DIR, "SYSTEM_OUT_DIR", false, DEFAULT_SYSTEM_OUT_DIR),
-        PredefProp(TskSystemProperties::MODULE_OUT_DIR, "MODULE_OUT_DIR", false, DEFAULT_MODULE_OUT_DIR),
-        PredefProp(TskSystemProperties::LOG_DIR, "LOG_DIR", false, DEFAULT_LOG_DIR),
-        PredefProp(TskSystemProperties::DB_HOST, "DB_HOST", false, ""),
-        PredefProp(TskSystemProperties::DB_PORT, "DB_PORT", false, ""),
-        PredefProp(TskSystemProperties::CARVE_DIR, "CARVE_DIR", false, DEFAULT_CARVE_DIR),
-        PredefProp(TskSystemProperties::UNALLOC_SECTORS_IMG_FILE_NAME, "UNALLOC_SECTORS_IMG_FILE_NAME", false, DEFAULT_UNALLOC_SECTORS_IMG_FILE_NAME), 
-        PredefProp(TskSystemProperties::MAX_UNALLOC_SECTORS_IMG_FILE_SIZE, "MAX_UNALLOC_SECTORS_IMG_FILE_SIZE", false, DEFAULT_MAX_UNALLOC_SECTORS_IMG_FILE_SIZE),
-        PredefProp(TskSystemProperties::CARVE_EXTRACT_KEEP_INPUT_FILES, "CARVE_EXTRACT_KEEP_INPUT_FILES", false, DEFAULT_CARVE_EXTRACT_KEEP_INPUT_FILES), 
-        PredefProp(TskSystemProperties::CARVE_EXTRACT_KEEP_OUTPUT_FILES, "CARVE_EXTRACT_KEEP_OUTPUT_FILES", false, DEFAULT_CARVE_EXTRACT_KEEP_OUTPUT_FILES),
-        PredefProp(TskSystemProperties::SCALPEL_DIR, "SCALPEL_DIR", false, ""),
-        PredefProp(TskSystemProperties::SCALPEL_CONFIG_FILE, "SCALPEL_CONFIG_FILE", false, DEFAULT_SCALPEL_CONFIG_FILE),
-        PredefProp(TskSystemProperties::PIPELINE_CONFIG_FILE, "PIPELINE_CONFIG_FILE", false, DEFAULT_PIPELINE_CONFIG_FILE),
-        PredefProp(TskSystemProperties::SESSION_ID, "SESSION_ID", false, ""),
-        PredefProp(TskSystemProperties::CURRENT_TASK, "CURRENT_TASK", false, ""),
-        PredefProp(TskSystemProperties::CURRENT_SEQUENCE_NUMBER, "CURRENT_SEQUENCE_NUMBER", false, ""),
-        PredefProp(TskSystemProperties::NODE, "NODE", false, ""),
-        PredefProp(TskSystemProperties::PID, "PID", false, ""),
-        PredefProp(TskSystemProperties::START_TIME, "START_TIME", false, ""),
-        PredefProp(TskSystemProperties::CURRENT_TIME, "CURRENT_TIME", false, ""),
-        PredefProp(TskSystemProperties::UNIQUE_ID, "UNIQUE_ID", false, ""),
-        PredefProp(TskSystemProperties::IMAGE_FILE, "IMAGE_FILE", false, "")
-    };
-
-    const std::size_t MAX_PATH_LENGTH = 1024;
-    const std::size_t MAX_RECURSION_DEPTH = 10;
-}
-
-TskSystemProperties::TskSystemProperties()
-{
-    // Populate the lookup data structures. 
-    for (std::size_t i = 0; i < END_PROPS; ++i)
-    {
-        predefProps[predefinedProperties[i].token] = predefinedProperties[i].id;
-        predefPropNames[predefinedProperties[i].id] = predefinedProperties[i].token;
-        predefPropTokens.insert(predefinedProperties[i].token);
-
-        if (predefinedProperties[i].required)
-        {
-            requiredProps.insert(predefinedProperties[i].id);
-        }
-
-        predefPropDefaults[predefinedProperties[i].id] = predefinedProperties[i].defaultValue; 
-    }
-}
-
-bool TskSystemProperties::isConfigured() const
-{
-    // Check whether all of the required predefined system properties are set.
-    for (std::set<PredefinedProperty>::const_iterator prop = requiredProps.begin(); prop != requiredProps.end(); ++prop)
-    {
-        std::string value = getProperty(predefPropNames[*prop]);
-        if (value.empty())
-        {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-void TskSystemProperties::setW(PredefinedProperty prop, const std::wstring &value)
-{
-    set(prop, TskUtilities::toUTF8(value));
-}
-
-void TskSystemProperties::setW(const std::wstring &name, const std::wstring &value)
-{
-    set(TskUtilities::toUTF8(name), TskUtilities::toUTF8(value));
-}
-
-void TskSystemProperties::set(PredefinedProperty prop, const std::string &value)
-{
-    assert(prop >= PROG_DIR && prop < END_PROPS);
-    if (prop < PROG_DIR || prop >= END_PROPS)
-    {
-        throw TskException("TskSystemProperties::set : passed out of range prop argument");
-    }
-
-    set(predefPropNames[prop], value);
-}
-
-void TskSystemProperties::set(const std::string &name, const std::string &value)
-{
-    assert(!name.empty());
-    if (name.empty())
-    {
-        throw TskException("TskSystemProperties::set : passed empty name argument");
-    }
-
-    assert(name != "CURRENT_TIME");
-    if (name == "CURRENT_TIME")
-    {
-        LOGWARN("TskSystemProperties::set : attempt to set read-only CURRENT_TIME system property");
-        return;
-    }
-
-    setProperty(name, value);
-}
-
-std::wstring TskSystemProperties::getW(PredefinedProperty prop) const
-{
-    return TskUtilities::toUTF16(get(prop));
-}
-
-std::wstring TskSystemProperties::getW(const std::wstring &name) const
-{
-    return TskUtilities::toUTF16(get(TskUtilities::toUTF8(name)));
-}
-
-std::string TskSystemProperties::get(PredefinedProperty prop) const
-{
-    assert(prop >= PROG_DIR && prop < END_PROPS);
-    if (prop < PROG_DIR || prop >= END_PROPS)
-    {
-        throw TskException("TskSystemProperties::get : passed out of range prop argument");
-    }
-
-    if (prop == CURRENT_TIME)
-    {
-        // CURRENT_TIME is always computed upon request.
-        return Poco::DateTimeFormatter::format(Poco::LocalDateTime(), "%Y_%m_%d_%H_%M_%S");
-    }
-
-    std::string value = getProperty(predefPropNames[prop]);
-        
-    if (value.empty())
-    {
-        if (prop == PROG_DIR)
-        {            
-            // If PROG_DIR has not been set, set it to the location of the currently executing program.
-            value = TskUtilities::getProgDir();
-            const_cast<TskSystemProperties*>(this)->set(prop, value);
-        }
-        else if (prop == IMAGE_FILE)
-        {
-            // If IMAGE_FILE has not been set, attempt to retrieve it from the image database.
-            const std::vector<std::string> imgNames = TskServices::Instance().getImgDB().getImageNames();
-            if (!imgNames.empty())
-            {
-                const_cast<TskSystemProperties*>(this)->set(prop, imgNames[0]);
-            }
-        }
-        else
-        {
-            // Perhaps there is a default value.
-            value = predefPropDefaults[prop];
-        }
-    }
-
-    if (value.empty() && requiredProps.count(prop) != 0)
-    {
-        // The empty property is an unset required property.
-        std::stringstream msg;
-        msg << "TskSystemProperties::get : required predefined system property '" << predefPropNames[prop] << "' is not set";
-        throw TskException(msg.str());
-    }
-
-    return  expandMacros(value);
-}
-
-std::string TskSystemProperties::get(const std::string &name) const
-{
-    if (predefProps.count(name) != 0)
-    {
-        return get(predefProps[name]);
-    }
-
-    return expandMacros(getProperty(name));
-}
-
-std::wstring TskSystemProperties::expandMacrosW(const std::wstring &inputStr) const
-{
-    return TskUtilities::toUTF16(expandMacros(TskUtilities::toUTF8(inputStr)));
-}
-
-std::string TskSystemProperties::expandMacros(const std::string &inputStr) const
-{
-    std::string outputStr;
-    expandMacros(inputStr, outputStr, 1);
-    return outputStr;
-}
-
-void TskSystemProperties::expandMacros(const std::string &inputStr, std::string &outputStr, std::size_t depth) const
-{
-    assert(depth <= MAX_RECURSION_DEPTH);
-    if (depth > MAX_RECURSION_DEPTH)
-    {
-        std::wstringstream msg;
-        msg << L"TskSystemProperties::expandMacros : reached maximum depth (" << MAX_RECURSION_DEPTH << L") of recursion, cannot complete expansion of " << inputStr.c_str();
-        LOGERROR(msg.str());
-        return;
-    }
-
-    Poco::StringTokenizer tokenizer(inputStr, "#", Poco::StringTokenizer::TOK_IGNORE_EMPTY);
-    for (Poco::StringTokenizer::Iterator token = tokenizer.begin(); token != tokenizer.end(); ++token)
-    {
-        if (predefPropTokens.count(*token) != 0)
-        {
-            expandMacros(get(*token), outputStr, depth + 1);
-        }
-        else
-        {
-            outputStr += *token;
-        }
-    }
-}
+/*
+ *  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 TskSystemProperties.cpp
+ * Contains the implementation of the TskSystemProperties class.
+ */
+
+// Include the class definition first to ensure it does not depend on subsequent includes in this file.
+#include "TskSystemProperties.h"
+
+// TSK Framework includes
+#include "tsk/framework/services/TskServices.h" // @@@ TODO: Resolve need to include TskServices.h before Log.h (macros in Log.h cause circular references)
+#include "tsk/framework/services/Log.h"
+#include "tsk/framework/utilities/TskUtilities.h"
+#include "tsk/framework/utilities/TskException.h"
+
+// Poco includes
+#include "Poco/Path.h"
+#include "Poco/StringTokenizer.h"
+#include "Poco/LocalDateTime.h"
+#include "Poco/DateTimeFormatter.h"
+
+// C/C++ library includes
+#include <sstream>
+#include <assert.h>
+
+namespace
+{
+    const std::string DEFAULT_PROG_DIR = Poco::Path::current();
+    const std::string DEFAULT_CONFIG_DIR = std::string("#PROG_DIR#") + Poco::Path::separator() + std::string("Config");
+    const std::string DEFAULT_MODULE_DIR = std::string("#PROG_DIR#") + Poco::Path::separator() + std::string("Modules");
+    const std::string DEFAULT_SYSTEM_OUT_DIR = std::string("#OUT_DIR#") + Poco::Path::separator() + std::string("SystemOutput");
+    const std::string DEFAULT_MODULE_OUT_DIR = std::string("#OUT_DIR#") + Poco::Path::separator() + std::string("ModuleOutput");
+    const std::string DEFAULT_LOG_DIR = std::string("#SYSTEM_OUT_DIR#") + Poco::Path::separator() + std::string("Logs");
+    const std::string DEFAULT_CARVE_DIR = std::string("#SYSTEM_OUT_DIR#") + Poco::Path::separator() + std::string("Carving");
+    const std::string DEFAULT_UNALLOC_SECTORS_IMG_FILE_NAME = "unalloc.bin";
+    const std::string DEFAULT_MAX_UNALLOC_SECTORS_IMG_FILE_SIZE = "0";
+    const std::string DEFAULT_CARVE_EXTRACT_KEEP_INPUT_FILES = "false";
+    const std::string DEFAULT_CARVE_EXTRACT_KEEP_OUTPUT_FILES = "false";
+    const std::string DEFAULT_SCALPEL_CONFIG_FILE = std::string("#SCALPEL_DIR#") + Poco::Path::separator() + std::string("scalpel.conf");
+    const std::string DEFAULT_PIPELINE_CONFIG_FILE = std::string("#CONFIG_DIR#") + Poco::Path::separator() + std::string("pipeline_config.xml");
+
+    struct PredefProp
+    {
+        PredefProp(TskSystemProperties::PredefinedProperty propId, const std::string &macroToken, bool propRequired, const std::string &propDefaultValue) :
+            id(propId), token(macroToken), required(propRequired), defaultValue(propDefaultValue) {}
+        TskSystemProperties::PredefinedProperty id;
+        std::string token;
+        bool required;
+        std::string defaultValue;
+    };
+
+    const PredefProp predefinedProperties[] =
+    {
+        PredefProp(TskSystemProperties::PROG_DIR, "PROG_DIR", false, ""),
+        PredefProp(TskSystemProperties::CONFIG_DIR, "CONFIG_DIR", false, DEFAULT_CONFIG_DIR),
+        PredefProp(TskSystemProperties::MODULE_DIR, "MODULE_DIR", false, DEFAULT_MODULE_DIR),
+        PredefProp(TskSystemProperties::MODULE_CONFIG_DIR, "MODULE_CONFIG_DIR", false, DEFAULT_MODULE_DIR),    // default == MODULE_DIR
+        PredefProp(TskSystemProperties::OUT_DIR, "OUT_DIR", true, ""),
+        PredefProp(TskSystemProperties::SYSTEM_OUT_DIR, "SYSTEM_OUT_DIR", false, DEFAULT_SYSTEM_OUT_DIR),
+        PredefProp(TskSystemProperties::MODULE_OUT_DIR, "MODULE_OUT_DIR", false, DEFAULT_MODULE_OUT_DIR),
+        PredefProp(TskSystemProperties::LOG_DIR, "LOG_DIR", false, DEFAULT_LOG_DIR),
+        PredefProp(TskSystemProperties::DB_HOST, "DB_HOST", false, ""),
+        PredefProp(TskSystemProperties::DB_PORT, "DB_PORT", false, ""),
+        PredefProp(TskSystemProperties::CARVE_DIR, "CARVE_DIR", false, DEFAULT_CARVE_DIR),
+        PredefProp(TskSystemProperties::UNALLOC_SECTORS_IMG_FILE_NAME, "UNALLOC_SECTORS_IMG_FILE_NAME", false, DEFAULT_UNALLOC_SECTORS_IMG_FILE_NAME), 
+        PredefProp(TskSystemProperties::MAX_UNALLOC_SECTORS_IMG_FILE_SIZE, "MAX_UNALLOC_SECTORS_IMG_FILE_SIZE", false, DEFAULT_MAX_UNALLOC_SECTORS_IMG_FILE_SIZE),
+        PredefProp(TskSystemProperties::CARVE_EXTRACT_KEEP_INPUT_FILES, "CARVE_EXTRACT_KEEP_INPUT_FILES", false, DEFAULT_CARVE_EXTRACT_KEEP_INPUT_FILES), 
+        PredefProp(TskSystemProperties::CARVE_EXTRACT_KEEP_OUTPUT_FILES, "CARVE_EXTRACT_KEEP_OUTPUT_FILES", false, DEFAULT_CARVE_EXTRACT_KEEP_OUTPUT_FILES),
+        PredefProp(TskSystemProperties::SCALPEL_DIR, "SCALPEL_DIR", false, ""),
+        PredefProp(TskSystemProperties::SCALPEL_CONFIG_FILE, "SCALPEL_CONFIG_FILE", false, DEFAULT_SCALPEL_CONFIG_FILE),
+        PredefProp(TskSystemProperties::PIPELINE_CONFIG_FILE, "PIPELINE_CONFIG_FILE", false, DEFAULT_PIPELINE_CONFIG_FILE),
+        PredefProp(TskSystemProperties::SESSION_ID, "SESSION_ID", false, ""),
+        PredefProp(TskSystemProperties::CURRENT_TASK, "CURRENT_TASK", false, ""),
+        PredefProp(TskSystemProperties::CURRENT_SEQUENCE_NUMBER, "CURRENT_SEQUENCE_NUMBER", false, ""),
+        PredefProp(TskSystemProperties::NODE, "NODE", false, ""),
+        PredefProp(TskSystemProperties::PID, "PID", false, ""),
+        PredefProp(TskSystemProperties::START_TIME, "START_TIME", false, ""),
+        PredefProp(TskSystemProperties::CURRENT_TIME, "CURRENT_TIME", false, ""),
+        PredefProp(TskSystemProperties::UNIQUE_ID, "UNIQUE_ID", false, ""),
+        PredefProp(TskSystemProperties::IMAGE_FILE, "IMAGE_FILE", false, "")
+    };
+
+    const std::size_t MAX_PATH_LENGTH = 1024;
+    const std::size_t MAX_RECURSION_DEPTH = 10;
+}
+
+TskSystemProperties::TskSystemProperties()
+{
+    // Populate the lookup data structures. 
+    for (std::size_t i = 0; i < END_PROPS; ++i)
+    {
+        predefProps[predefinedProperties[i].token] = predefinedProperties[i].id;
+        predefPropNames[predefinedProperties[i].id] = predefinedProperties[i].token;
+        predefPropTokens.insert(predefinedProperties[i].token);
+
+        if (predefinedProperties[i].required)
+        {
+            requiredProps.insert(predefinedProperties[i].id);
+        }
+
+        predefPropDefaults[predefinedProperties[i].id] = predefinedProperties[i].defaultValue; 
+    }
+}
+
+bool TskSystemProperties::isConfigured() const
+{
+    // Check whether all of the required predefined system properties are set.
+    for (std::set<PredefinedProperty>::const_iterator prop = requiredProps.begin(); prop != requiredProps.end(); ++prop)
+    {
+        std::string value = getProperty(predefPropNames[*prop]);
+        if (value.empty())
+        {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+void TskSystemProperties::setW(PredefinedProperty prop, const std::wstring &value)
+{
+    set(prop, TskUtilities::toUTF8(value));
+}
+
+void TskSystemProperties::setW(const std::wstring &name, const std::wstring &value)
+{
+    set(TskUtilities::toUTF8(name), TskUtilities::toUTF8(value));
+}
+
+void TskSystemProperties::set(PredefinedProperty prop, const std::string &value)
+{
+    assert(prop >= PROG_DIR && prop < END_PROPS);
+    if (prop < PROG_DIR || prop >= END_PROPS)
+    {
+        throw TskException("TskSystemProperties::set : passed out of range prop argument");
+    }
+
+    set(predefPropNames[prop], value);
+}
+
+void TskSystemProperties::set(const std::string &name, const std::string &value)
+{
+    assert(!name.empty());
+    if (name.empty())
+    {
+        throw TskException("TskSystemProperties::set : passed empty name argument");
+    }
+
+    assert(name != "CURRENT_TIME");
+    if (name == "CURRENT_TIME")
+    {
+        LOGWARN("TskSystemProperties::set : attempt to set read-only CURRENT_TIME system property");
+        return;
+    }
+
+    setProperty(name, value);
+}
+
+std::wstring TskSystemProperties::getW(PredefinedProperty prop) const
+{
+    return TskUtilities::toUTF16(get(prop));
+}
+
+std::wstring TskSystemProperties::getW(const std::wstring &name) const
+{
+    return TskUtilities::toUTF16(get(TskUtilities::toUTF8(name)));
+}
+
+std::string TskSystemProperties::get(PredefinedProperty prop) const
+{
+    assert(prop >= PROG_DIR && prop < END_PROPS);
+    if (prop < PROG_DIR || prop >= END_PROPS)
+    {
+        throw TskException("TskSystemProperties::get : passed out of range prop argument");
+    }
+
+    if (prop == CURRENT_TIME)
+    {
+        // CURRENT_TIME is always computed upon request.
+        return Poco::DateTimeFormatter::format(Poco::LocalDateTime(), "%Y_%m_%d_%H_%M_%S");
+    }
+
+    std::string value = getProperty(predefPropNames[prop]);
+        
+    if (value.empty())
+    {
+        if (prop == PROG_DIR)
+        {            
+            // If PROG_DIR has not been set, set it to the location of the currently executing program.
+            value = TskUtilities::getProgDir();
+            const_cast<TskSystemProperties*>(this)->set(prop, value);
+        }
+        else if (prop == IMAGE_FILE)
+        {
+            // If IMAGE_FILE has not been set, attempt to retrieve it from the image database.
+            const std::vector<std::string> imgNames = TskServices::Instance().getImgDB().getImageNames();
+            if (!imgNames.empty())
+            {
+                const_cast<TskSystemProperties*>(this)->set(prop, imgNames[0]);
+            }
+        }
+        else
+        {
+            // Perhaps there is a default value.
+            value = predefPropDefaults[prop];
+        }
+    }
+
+    if (value.empty() && requiredProps.count(prop) != 0)
+    {
+        // The empty property is an unset required property.
+        std::stringstream msg;
+        msg << "TskSystemProperties::get : required predefined system property '" << predefPropNames[prop] << "' is not set";
+        throw TskException(msg.str());
+    }
+
+    return  expandMacros(value);
+}
+
+std::string TskSystemProperties::get(const std::string &name) const
+{
+    if (predefProps.count(name) != 0)
+    {
+        return get(predefProps[name]);
+    }
+
+    return expandMacros(getProperty(name));
+}
+
+std::wstring TskSystemProperties::expandMacrosW(const std::wstring &inputStr) const
+{
+    return TskUtilities::toUTF16(expandMacros(TskUtilities::toUTF8(inputStr)));
+}
+
+std::string TskSystemProperties::expandMacros(const std::string &inputStr) const
+{
+    std::string outputStr;
+    expandMacros(inputStr, outputStr, 1);
+    return outputStr;
+}
+
+void TskSystemProperties::expandMacros(const std::string &inputStr, std::string &outputStr, std::size_t depth) const
+{
+    assert(depth <= MAX_RECURSION_DEPTH);
+    if (depth > MAX_RECURSION_DEPTH)
+    {
+        std::wstringstream msg;
+        msg << L"TskSystemProperties::expandMacros : reached maximum depth (" << MAX_RECURSION_DEPTH << L") of recursion, cannot complete expansion of " << inputStr.c_str();
+        LOGERROR(msg.str());
+        return;
+    }
+
+    Poco::StringTokenizer tokenizer(inputStr, "#", Poco::StringTokenizer::TOK_IGNORE_EMPTY);
+    for (Poco::StringTokenizer::Iterator token = tokenizer.begin(); token != tokenizer.end(); ++token)
+    {
+        if (predefPropTokens.count(*token) != 0)
+        {
+            expandMacros(get(*token), outputStr, depth + 1);
+        }
+        else
+        {
+            outputStr += *token;
+        }
+    }
+}
diff --git a/framework/tsk/framework/services/TskSystemProperties.h b/framework/tsk/framework/services/TskSystemProperties.h
index 24b50e4..fc5df85 100755
--- a/framework/tsk/framework/services/TskSystemProperties.h
+++ b/framework/tsk/framework/services/TskSystemProperties.h
@@ -1,403 +1,403 @@
-/*
- * 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 TskSystemProperties.h
- * Contains the interface of the TskSystemProperties class.
- */
-
-#ifndef _TSK_SYSTEMPROPERTIES_H
-#define _TSK_SYSTEMPROPERTIES_H
-
-// TSK Framework includes
-#include "tsk/framework/framework_i.h"
-
-// C/C++ library includes
-#include <string>
-#include <map>
-#include <set>
-
-/**
- * A base class for setting and retrieving system-wide name/value pairs.
- * Typically used to store system settings so that all modules and classes can
- * access the settings. Can be registered with and retrieved from TskServices.
- *
- * The class defines several standard 'names' in the PredefinedProperties
- * enum.  Any 'name' can be used though.
- *
- * Values can refer to other 'names' in the SystemProperties.  When the
- * values are retrieved via one of the get() methods, the value is searched
- * for words between two '#' characters.  If the word is a defined system 
- * property, then its value will be replaced. For example, \#PROG_DIR\# would 
- * be replaced by the PROG_DIR system property value in "#PROG_DIR#\\foo". 
- * 
- * The class is abstract; derived classes supply property storage options and 
- * implement the private virtual functions setProperty and getProperty (the 
- * class design makes use of Herb Sutter's Non-Virtual Interface [NVI] idiom).
- */
-class TSK_FRAMEWORK_API TskSystemProperties
-{
-public:
-    /**
-     * The TSK Framework predefines a set of system properties. Many of these
-     * properties have default values, while others are required to have values 
-     * supplied by either the executing program or the framework configuration
-     * file. TskSystemProperties::isConfigured() may be called to do a runtime
-     * query of whether or not all required system properties are set.
-     */
-    enum PredefinedProperty
-    {
-        /** 
-         * Program root directory. Defaults to the directory where the 
-         * executing program is installed. 
-         */
-        PROG_DIR,
-
-        /** 
-         * Directory where configuration files and data can be found. 
-         * Defaults to \#PROG_DIR#/Config. 
-         */
-        CONFIG_DIR,
-        
-        /** 
-          * Directory where plug-in and executable modules can be found.
-          * Defaults to \#PROG_DIR#/Modules.
-          */
-        MODULE_DIR,
-
-        /** 
-          * Directory where plug-in modules can find their configuration files,
-          * if any.
-          * Defaults to MODULE_DIR.
-          */
-        MODULE_CONFIG_DIR,
-
-        /** 
-         * Root output directory. It should be a shared location if the TSK
-         * Framework is being used in a distributed environment. It is a 
-         * required system property.
-         */
-        OUT_DIR,
-
-        /** 
-         * The output directory for the executing program. Defaults to 
-         * \#OUT_DIR#/SystemOutput.
-         */
-        SYSTEM_OUT_DIR,
-
-        /** 
-         * The output directory for plug-in and executable modules. Defaults to 
-         * \#OUT_DIR#/ModuleOutput.
-         */
-        MODULE_OUT_DIR,
-
-        /** 
-         * Directory where system logs are written. Defaults to 
-         * \#SYSTEM_OUT_DIR#/Logs. 
-         */
-        LOG_DIR,
-
-        /** 
-         * Hostname of database server (if one is being used). 
-         */
-        DB_HOST,
-
-        /** 
-         * Port of database server (if one is being used) 
-         */
-        DB_PORT,
-
-        /** 
-         * Directory where unallocated sectors image files are stored prior to
-         * carving. Defaults to \#SYSTEM_OUT_DIR#\\Carving. 
-         */ 
-        CARVE_DIR,
-
-        /**
-         * File name to be given to all unallocated sectors image files.
-         * Default to unalloc.bin.
-         */
-        UNALLOC_SECTORS_IMG_FILE_NAME,
-
-        /**
-         * Maximum allowable size (in bytes) for unallocated sectors image files. Can be 
-         * set to zero to have no maximum size and instead break files on 
-         * volume boundaries only. Defaults to zero.
-         */
-        MAX_UNALLOC_SECTORS_IMG_FILE_SIZE,
-
-        /**
-         * Whether or not unallocated sectors image files should be retained
-         * after carving is completed. Defaults to false.
-         */
-        CARVE_EXTRACT_KEEP_INPUT_FILES,
-
-        /**
-         * Whether or not carved files should be retained in the carving 
-         * directory after they are copied to file storage. Defaults to false.
-         */
-        CARVE_EXTRACT_KEEP_OUTPUT_FILES,
-
-        /**
-         * Directory where scalpel.exe is installed. Used by the TSK 
-         * Framework's implementation of the CarveExtract interface. 
-         */
-        SCALPEL_DIR,
-
-        /**
-         * Path to a Scalpel configuration file. Used by the TSK 
-         * Framework's implementation of the CarveExtract interface.
-         * Defaults to \#SCALPEL_DIR#/scalpel.conf.
-         */
-        SCALPEL_CONFIG_FILE,
-
-        /** 
-         * Path to a pipeline configuration file. Defaults to 
-         * \#CONFIG_DIR#/pipeline_config.xml. 
-         */ 
-        PIPELINE_CONFIG_FILE,
-
-        /** 
-          * ID of this session.  The intended use of this is in a distributed
-          * environment that is processing multiple images at the same time.
-          * Each image would have a unique session ID. 
-          */
-        SESSION_ID,
-
-        /** 
-         * Currently executing task, e.g., file analysis, carving, etc. 
-         */
-        CURRENT_TASK,
-
-        /** 
-          * Can be used to assign a number in a sequence to a sub task of the
-          * current task. 
-          */ 
-        CURRENT_SEQUENCE_NUMBER,
-
-        /** 
-         * The hostname of the computer on which the program is executing. 
-         */
-        NODE,
-
-        /** 
-         * The process identifier of the process running the program. 
-         */
-        PID,
-
-        /** 
-         * The time the process running the program began executing. 
-         */
-        START_TIME,
-
-        /** 
-         * Current system time. Read only. 
-         */
-        CURRENT_TIME,
-
-        /** 
-         * A combination of elements that define a unique identifier for the
-         * current task. For example, this property might be defined to be a
-         * string of the form CurrentTask_HostName_PID_StartTime. 
-         */
-        UNIQUE_ID,
-
-        /** 
-         * Image file path. Defaults to the image file path stored in the image database. 
-         */
-        IMAGE_FILE,
-
-		END_PROPS
-    };
-
-    /** 
-     * Default constructor. 
-     */
-    TskSystemProperties();
-
-    /** 
-     * Destructor, virtual since this is an abstract base class. 
-     */
-    virtual ~TskSystemProperties() {}
-
-    /**
-     * Determines whether or not all required predefined system properties are
-     * currently set.
-     *
-     * @return True if all required properties are set, false otherwise.
-     */
-    bool isConfigured() const;
-
-    /** 
-     * Associates a string value with a name.
-     * See the class description for more details on setting properties
-     * based on other properties. 
-     *
-     * @param prop An element of the PredefinedProperty enum.
-     * @param value The value to associate with the name corresponding to the
-     * PredefinedProperty enum element.
-     * @return Throws TskException if prop is out of range.
-     */
-    void setW(PredefinedProperty prop, const std::wstring &value);
-    
-    /** 
-     * Associates a string value with an unofficial name.
-     * See the class description for more details on setting properties
-     * based on other properties. 
-     *
-     * @param name The name with which to associate the value.
-     * @param value The value to associate with the name.
-     * @return Throws TskException if name is empty.
-     */
-    void setW(const std::wstring &name, const std::wstring &value);
-
-    /** 
-     * Associates a string value with a name.
-     * See the class description for more details on setting properties
-     * based on other properties. 
-     *
-     * @param prop An element of the PredefinedProperty enum.
-     * @param value The value to associate with the name corresponding to the
-     * PredefinedProperty enum element.
-     * @return Throws TskException if prop is out of range.
-     */
-    void set(PredefinedProperty prop, const std::string &value);
-
-    /** 
-     * Associates a string value with an unofficial name.
-     * See the class description for more details on setting properties
-     * based on other properties. 
-     *
-     * @param name The name with which to associate the value.
-     * @param value The value to associate with the name.
-     * @return Throws TskException if name is empty.
-     */
-    void set(const std::string &name, const std::string &value);
-
-    /** 
-     * Retrieves the string value associated with a name.
-     *
-     * @param prop An element of the PredefinedProperty enum.
-     * @returns String value corresponding to prop. Throws
-     *  TskException if the requested value is for a required predefined 
-     * property that is not set.
-     */
-    std::wstring getW(PredefinedProperty prop) const;
-
-    /** 
-     * Retrieves the string value associated with a name.
-     *
-     * @param name Name of value to retrieve.
-     * @returns String value or empty string if name was not found. 
-     */
-    std::wstring getW(const std::wstring &name) const;
-
-    /** 
-     * Retrieves the string value associated with a name.
-     *
-     * @param prop An element of the PredefinedProperty enum.
-     * @returns String value corresponding to prop. Throws
-     * TskException if the requested value is for a required predefined 
-     * property that is not set.
-     */
-    std::string get(PredefinedProperty prop) const;
-    
-    /** 
-     * Retrieves the string value associated with a name.
-     *
-     * @param name Name of value to retrieve.
-     * @returns String value or empty string if name was not found. 
-     */
-    std::string get(const std::string &name) const;
-
-    /**
-     * Expands any system property macros in a given string. 
-     *
-     * @param inputStr The input string.
-     * @return A copy of the input string with all system property macros
-     * expanded.
-     */
-    std::wstring expandMacrosW(const std::wstring &inputStr) const;
-
-    /**
-     * Expands any system property macros in a given string. 
-     *
-     * @param inputStr The input string.
-     * @return A copy of the input string with all system property macros
-     * expanded.
-     */
-    std::string expandMacros(const std::string &inputStr) const;
-
-private:
-    /**
-     * Associates a string value with a name. Called by the public interface of
-     * this class in accordance with Herb Sutter's Non-Virtual Interface (NVI) 
-     * idiom.
-     *
-     * @param name The name with which to associate the value.
-     * @param value The value to associate with the name.
-     */
-    virtual void setProperty(const std::string &name, const std::string &value) = 0;
-
-    /** 
-     * Retrieves the string value associated with a name. Called by the public 
-     * interface of this class in accordance with Herb Sutter's Non-Virtual 
-     * Interface (NVI) idiom.
-     *
-     * @param name Name of value to retrieve.
-     * @returns String value or empty string if name was not found. 
-     */
-    virtual std::string getProperty(const std::string &name) const = 0;
-
-    /**
-     * Recursively expands the system property macros in a given string with
-     * recursion not to exceed TskSystemProperties::MAX_RECURSION_DEPTH. 
-     *
-     * @param inputStr The input string.
-     * @param outputStr The output string.
-     * @param depth The current depth of the recursion.
-     * @return A copy of the input string with all system property macros
-     * at the current recursion depth expanded.
-     */
-    void expandMacros(const std::string &inputStr, std::string &outputStr, std::size_t depth) const;
-
-    /**
-     * Lookup data structure used to map name strings of predefined system 
-     * properties to elements of the PredefinedProperty enum.
-     */
-    mutable std::map<std::string, PredefinedProperty> predefProps;
-
-    /**
-     * Lookup data structure used to map elements of the 
-     * PredefinedProperty enum to name strings.
-     */
-    mutable std::map<PredefinedProperty, std::string> predefPropNames;
-
-    /**
-     * Lookup data structure used to determine whether or not a token in a 
-     * string passed to the expandMacros function corresponds to a predefined 
-     * system property.
-     */
-    mutable std::set<std::string> predefPropTokens;
-
-    /**
-     * Lookup data structure used to determine whether or not a predefined 
-     * system property is required.
-     */
-    mutable std::set<PredefinedProperty> requiredProps; 
-
-    /**
-     * Lookup data structure used to get the default values of predefined 
-     * system properties.
-     */
-    mutable std::map<PredefinedProperty, std::string> predefPropDefaults;
-};
-
-#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 TskSystemProperties.h
+ * Contains the interface of the TskSystemProperties class.
+ */
+
+#ifndef _TSK_SYSTEMPROPERTIES_H
+#define _TSK_SYSTEMPROPERTIES_H
+
+// TSK Framework includes
+#include "tsk/framework/framework_i.h"
+
+// C/C++ library includes
+#include <string>
+#include <map>
+#include <set>
+
+/**
+ * A base class for setting and retrieving system-wide name/value pairs.
+ * Typically used to store system settings so that all modules and classes can
+ * access the settings. Can be registered with and retrieved from TskServices.
+ *
+ * The class defines several standard 'names' in the PredefinedProperties
+ * enum.  Any 'name' can be used though.
+ *
+ * Values can refer to other 'names' in the SystemProperties.  When the
+ * values are retrieved via one of the get() methods, the value is searched
+ * for words between two '#' characters.  If the word is a defined system 
+ * property, then its value will be replaced. For example, \#PROG_DIR\# would 
+ * be replaced by the PROG_DIR system property value in "#PROG_DIR#\\foo". 
+ * 
+ * The class is abstract; derived classes supply property storage options and 
+ * implement the private virtual functions setProperty and getProperty (the 
+ * class design makes use of Herb Sutter's Non-Virtual Interface [NVI] idiom).
+ */
+class TSK_FRAMEWORK_API TskSystemProperties
+{
+public:
+    /**
+     * The TSK Framework predefines a set of system properties. Many of these
+     * properties have default values, while others are required to have values 
+     * supplied by either the executing program or the framework configuration
+     * file. TskSystemProperties::isConfigured() may be called to do a runtime
+     * query of whether or not all required system properties are set.
+     */
+    enum PredefinedProperty
+    {
+        /** 
+         * Program root directory. Defaults to the directory where the 
+         * executing program is installed. 
+         */
+        PROG_DIR,
+
+        /** 
+         * Directory where configuration files and data can be found. 
+         * Defaults to \#PROG_DIR#/Config. 
+         */
+        CONFIG_DIR,
+        
+        /** 
+          * Directory where plug-in and executable modules can be found.
+          * Defaults to \#PROG_DIR#/Modules.
+          */
+        MODULE_DIR,
+
+        /** 
+          * Directory where plug-in modules can find their configuration files,
+          * if any.
+          * Defaults to MODULE_DIR.
+          */
+        MODULE_CONFIG_DIR,
+
+        /** 
+         * Root output directory. It should be a shared location if the TSK
+         * Framework is being used in a distributed environment. It is a 
+         * required system property.
+         */
+        OUT_DIR,
+
+        /** 
+         * The output directory for the executing program. Defaults to 
+         * \#OUT_DIR#/SystemOutput.
+         */
+        SYSTEM_OUT_DIR,
+
+        /** 
+         * The output directory for plug-in and executable modules. Defaults to 
+         * \#OUT_DIR#/ModuleOutput.
+         */
+        MODULE_OUT_DIR,
+
+        /** 
+         * Directory where system logs are written. Defaults to 
+         * \#SYSTEM_OUT_DIR#/Logs. 
+         */
+        LOG_DIR,
+
+        /** 
+         * Hostname of database server (if one is being used). 
+         */
+        DB_HOST,
+
+        /** 
+         * Port of database server (if one is being used) 
+         */
+        DB_PORT,
+
+        /** 
+         * Directory where unallocated sectors image files are stored prior to
+         * carving. Defaults to \#SYSTEM_OUT_DIR#\\Carving. 
+         */ 
+        CARVE_DIR,
+
+        /**
+         * File name to be given to all unallocated sectors image files.
+         * Default to unalloc.bin.
+         */
+        UNALLOC_SECTORS_IMG_FILE_NAME,
+
+        /**
+         * Maximum allowable size (in bytes) for unallocated sectors image files. Can be 
+         * set to zero to have no maximum size and instead break files on 
+         * volume boundaries only. Defaults to zero.
+         */
+        MAX_UNALLOC_SECTORS_IMG_FILE_SIZE,
+
+        /**
+         * Whether or not unallocated sectors image files should be retained
+         * after carving is completed. Defaults to false.
+         */
+        CARVE_EXTRACT_KEEP_INPUT_FILES,
+
+        /**
+         * Whether or not carved files should be retained in the carving 
+         * directory after they are copied to file storage. Defaults to false.
+         */
+        CARVE_EXTRACT_KEEP_OUTPUT_FILES,
+
+        /**
+         * Directory where scalpel.exe is installed. Used by the TSK 
+         * Framework's implementation of the CarveExtract interface. 
+         */
+        SCALPEL_DIR,
+
+        /**
+         * Path to a Scalpel configuration file. Used by the TSK 
+         * Framework's implementation of the CarveExtract interface.
+         * Defaults to \#SCALPEL_DIR#/scalpel.conf.
+         */
+        SCALPEL_CONFIG_FILE,
+
+        /** 
+         * Path to a pipeline configuration file. Defaults to 
+         * \#CONFIG_DIR#/pipeline_config.xml. 
+         */ 
+        PIPELINE_CONFIG_FILE,
+
+        /** 
+          * ID of this session.  The intended use of this is in a distributed
+          * environment that is processing multiple images at the same time.
+          * Each image would have a unique session ID. 
+          */
+        SESSION_ID,
+
+        /** 
+         * Currently executing task, e.g., file analysis, carving, etc. 
+         */
+        CURRENT_TASK,
+
+        /** 
+          * Can be used to assign a number in a sequence to a sub task of the
+          * current task. 
+          */ 
+        CURRENT_SEQUENCE_NUMBER,
+
+        /** 
+         * The hostname of the computer on which the program is executing. 
+         */
+        NODE,
+
+        /** 
+         * The process identifier of the process running the program. 
+         */
+        PID,
+
+        /** 
+         * The time the process running the program began executing. 
+         */
+        START_TIME,
+
+        /** 
+         * Current system time. Read only. 
+         */
+        CURRENT_TIME,
+
+        /** 
+         * A combination of elements that define a unique identifier for the
+         * current task. For example, this property might be defined to be a
+         * string of the form CurrentTask_HostName_PID_StartTime. 
+         */
+        UNIQUE_ID,
+
+        /** 
+         * Image file path. Defaults to the image file path stored in the image database. 
+         */
+        IMAGE_FILE,
+
+		END_PROPS
+    };
+
+    /** 
+     * Default constructor. 
+     */
+    TskSystemProperties();
+
+    /** 
+     * Destructor, virtual since this is an abstract base class. 
+     */
+    virtual ~TskSystemProperties() {}
+
+    /**
+     * Determines whether or not all required predefined system properties are
+     * currently set.
+     *
+     * @return True if all required properties are set, false otherwise.
+     */
+    bool isConfigured() const;
+
+    /** 
+     * Associates a string value with a name.
+     * See the class description for more details on setting properties
+     * based on other properties. 
+     *
+     * @param prop An element of the PredefinedProperty enum.
+     * @param value The value to associate with the name corresponding to the
+     * PredefinedProperty enum element.
+     * @return Throws TskException if prop is out of range.
+     */
+    void setW(PredefinedProperty prop, const std::wstring &value);
+    
+    /** 
+     * Associates a string value with an unofficial name.
+     * See the class description for more details on setting properties
+     * based on other properties. 
+     *
+     * @param name The name with which to associate the value.
+     * @param value The value to associate with the name.
+     * @return Throws TskException if name is empty.
+     */
+    void setW(const std::wstring &name, const std::wstring &value);
+
+    /** 
+     * Associates a string value with a name.
+     * See the class description for more details on setting properties
+     * based on other properties. 
+     *
+     * @param prop An element of the PredefinedProperty enum.
+     * @param value The value to associate with the name corresponding to the
+     * PredefinedProperty enum element.
+     * @return Throws TskException if prop is out of range.
+     */
+    void set(PredefinedProperty prop, const std::string &value);
+
+    /** 
+     * Associates a string value with an unofficial name.
+     * See the class description for more details on setting properties
+     * based on other properties. 
+     *
+     * @param name The name with which to associate the value.
+     * @param value The value to associate with the name.
+     * @return Throws TskException if name is empty.
+     */
+    void set(const std::string &name, const std::string &value);
+
+    /** 
+     * Retrieves the string value associated with a name.
+     *
+     * @param prop An element of the PredefinedProperty enum.
+     * @returns String value corresponding to prop. Throws
+     *  TskException if the requested value is for a required predefined 
+     * property that is not set.
+     */
+    std::wstring getW(PredefinedProperty prop) const;
+
+    /** 
+     * Retrieves the string value associated with a name.
+     *
+     * @param name Name of value to retrieve.
+     * @returns String value or empty string if name was not found. 
+     */
+    std::wstring getW(const std::wstring &name) const;
+
+    /** 
+     * Retrieves the string value associated with a name.
+     *
+     * @param prop An element of the PredefinedProperty enum.
+     * @returns String value corresponding to prop. Throws
+     * TskException if the requested value is for a required predefined 
+     * property that is not set.
+     */
+    std::string get(PredefinedProperty prop) const;
+    
+    /** 
+     * Retrieves the string value associated with a name.
+     *
+     * @param name Name of value to retrieve.
+     * @returns String value or empty string if name was not found. 
+     */
+    std::string get(const std::string &name) const;
+
+    /**
+     * Expands any system property macros in a given string. 
+     *
+     * @param inputStr The input string.
+     * @return A copy of the input string with all system property macros
+     * expanded.
+     */
+    std::wstring expandMacrosW(const std::wstring &inputStr) const;
+
+    /**
+     * Expands any system property macros in a given string. 
+     *
+     * @param inputStr The input string.
+     * @return A copy of the input string with all system property macros
+     * expanded.
+     */
+    std::string expandMacros(const std::string &inputStr) const;
+
+private:
+    /**
+     * Associates a string value with a name. Called by the public interface of
+     * this class in accordance with Herb Sutter's Non-Virtual Interface (NVI) 
+     * idiom.
+     *
+     * @param name The name with which to associate the value.
+     * @param value The value to associate with the name.
+     */
+    virtual void setProperty(const std::string &name, const std::string &value) = 0;
+
+    /** 
+     * Retrieves the string value associated with a name. Called by the public 
+     * interface of this class in accordance with Herb Sutter's Non-Virtual 
+     * Interface (NVI) idiom.
+     *
+     * @param name Name of value to retrieve.
+     * @returns String value or empty string if name was not found. 
+     */
+    virtual std::string getProperty(const std::string &name) const = 0;
+
+    /**
+     * Recursively expands the system property macros in a given string with
+     * recursion not to exceed TskSystemProperties::MAX_RECURSION_DEPTH. 
+     *
+     * @param inputStr The input string.
+     * @param outputStr The output string.
+     * @param depth The current depth of the recursion.
+     * @return A copy of the input string with all system property macros
+     * at the current recursion depth expanded.
+     */
+    void expandMacros(const std::string &inputStr, std::string &outputStr, std::size_t depth) const;
+
+    /**
+     * Lookup data structure used to map name strings of predefined system 
+     * properties to elements of the PredefinedProperty enum.
+     */
+    mutable std::map<std::string, PredefinedProperty> predefProps;
+
+    /**
+     * Lookup data structure used to map elements of the 
+     * PredefinedProperty enum to name strings.
+     */
+    mutable std::map<PredefinedProperty, std::string> predefPropNames;
+
+    /**
+     * Lookup data structure used to determine whether or not a token in a 
+     * string passed to the expandMacros function corresponds to a predefined 
+     * system property.
+     */
+    mutable std::set<std::string> predefPropTokens;
+
+    /**
+     * Lookup data structure used to determine whether or not a predefined 
+     * system property is required.
+     */
+    mutable std::set<PredefinedProperty> requiredProps; 
+
+    /**
+     * Lookup data structure used to get the default values of predefined 
+     * system properties.
+     */
+    mutable std::map<PredefinedProperty, std::string> predefPropDefaults;
+};
+
+#endif
diff --git a/framework/tsk/framework/services/TskSystemPropertiesImpl.cpp b/framework/tsk/framework/services/TskSystemPropertiesImpl.cpp
index 11c6ae1..00dd11c 100755
--- a/framework/tsk/framework/services/TskSystemPropertiesImpl.cpp
+++ b/framework/tsk/framework/services/TskSystemPropertiesImpl.cpp
@@ -1,75 +1,75 @@
-/*
- *
- *  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 TskSystemPropertiesImpl.cpp
- * Contains the implementation of the TskSystemPropertiesImpl class.
- */
-
-// Include the class definition first to ensure it does not depend on subsequent includes in this file.
-#include "TskSystemPropertiesImpl.h"
-
-#include "tsk/framework/services/Log.h"
-#include "tsk/framework/services/TskServices.h"
-#include "tsk/framework/utilities/TskUtilities.h"
-#include "tsk/framework/utilities/TskException.h"
-#include "Poco/Util/XMLConfiguration.h"
-#include "Poco/Util/MapConfiguration.h"
-#include <sstream>
-
-void TskSystemPropertiesImpl::initialize(const std::wstring &configFile) 
-{
-    initialize(TskUtilities::toUTF8(configFile));
-}
-
-void TskSystemPropertiesImpl::initialize(const std::string &configfile) 
-{
-    try {
-        m_abstractConfig = new Poco::Util::XMLConfiguration(configfile);
-    }
-    catch (Poco::FileNotFoundException& )
-    {
-        throw TskException("Configuration file not found : " + configfile);
-    }
-}
-
-void TskSystemPropertiesImpl::initialize()
-{
-    m_abstractConfig = new Poco::Util::MapConfiguration();
-}
-
-void TskSystemPropertiesImpl::setProperty(const std::string &name, const std::string &value)
-{
-    if (!m_abstractConfig) 
-    {
-        throw TskException("TskSystemPropertiesImpl::set - Configuration not initialized.");
-    } 
-
-    m_abstractConfig->setString(name, value);
-}
-
-std::string TskSystemPropertiesImpl::getProperty(const std::string &name) const
-{
-    if (!m_abstractConfig) 
-    {
-        throw TskException("TskSystemPropertiesImpl::get - Configuration not initialized.");
-    }
-
-    try 
-    {
-        return m_abstractConfig->getString(name);
-    } 
-    catch (Poco::NotFoundException &) 
-    {
-        // Return empty string per documentation of base class interface.
-        return "";
-    }
-}
+/*
+ *
+ *  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 TskSystemPropertiesImpl.cpp
+ * Contains the implementation of the TskSystemPropertiesImpl class.
+ */
+
+// Include the class definition first to ensure it does not depend on subsequent includes in this file.
+#include "TskSystemPropertiesImpl.h"
+
+#include "tsk/framework/services/Log.h"
+#include "tsk/framework/services/TskServices.h"
+#include "tsk/framework/utilities/TskUtilities.h"
+#include "tsk/framework/utilities/TskException.h"
+#include "Poco/Util/XMLConfiguration.h"
+#include "Poco/Util/MapConfiguration.h"
+#include <sstream>
+
+void TskSystemPropertiesImpl::initialize(const std::wstring &configFile) 
+{
+    initialize(TskUtilities::toUTF8(configFile));
+}
+
+void TskSystemPropertiesImpl::initialize(const std::string &configfile) 
+{
+    try {
+        m_abstractConfig = new Poco::Util::XMLConfiguration(configfile);
+    }
+    catch (Poco::FileNotFoundException& )
+    {
+        throw TskException("Configuration file not found : " + configfile);
+    }
+}
+
+void TskSystemPropertiesImpl::initialize()
+{
+    m_abstractConfig = new Poco::Util::MapConfiguration();
+}
+
+void TskSystemPropertiesImpl::setProperty(const std::string &name, const std::string &value)
+{
+    if (!m_abstractConfig) 
+    {
+        throw TskException("TskSystemPropertiesImpl::set - Configuration not initialized.");
+    } 
+
+    m_abstractConfig->setString(name, value);
+}
+
+std::string TskSystemPropertiesImpl::getProperty(const std::string &name) const
+{
+    if (!m_abstractConfig) 
+    {
+        throw TskException("TskSystemPropertiesImpl::get - Configuration not initialized.");
+    }
+
+    try 
+    {
+        return m_abstractConfig->getString(name);
+    } 
+    catch (Poco::NotFoundException &) 
+    {
+        // Return empty string per documentation of base class interface.
+        return "";
+    }
+}
diff --git a/framework/tsk/framework/services/TskSystemPropertiesImpl.h b/framework/tsk/framework/services/TskSystemPropertiesImpl.h
index da6b09f..5722f20 100755
--- a/framework/tsk/framework/services/TskSystemPropertiesImpl.h
+++ b/framework/tsk/framework/services/TskSystemPropertiesImpl.h
@@ -1,90 +1,90 @@
-/*
- *  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 TskSystemPropertiesImpl.h
- * Contains the interface of the TskSystemPropertiesImpl class.
- */
-
-#ifndef _TSK_SYSTEMPROPERTIESIMPL_H
-#define _TSK_SYSTEMPROPERTIESIMPL_H
-
-#include "tsk/framework/framework_i.h"
-#include "TskSystemProperties.h"
-#include "Poco/Util/AbstractConfiguration.h"
-#include <string>
-
-/**
- * An implementation of TskSystemProperties that uses Poco
- * AbstractConfiguration class to set and retrieve name/value
- * pairs from an XML file. Allows system property values to refer 
- * to other system property values (see the TskSystemProperties class 
- * description for more details).
- * 
- * The XML schema for this is that the name of the value is the tag and
- * the value is stored in the tag.  Here is an example:
- * 
- * \verbatim
- <?xml version="1.0" encoding="utf-8"?>
- <TSK_FRAMEWORK_CONFIG>
-   <CONFIG_DIR>#PROG_DIR#/Config</CONFIG_DIR>
-   <MODULE_DIR>#PROG_DIR#/Modules</MODULE_DIR>
- </TSK_FRAMEWORK_CONFIG>
- * \endverbatim
- * You can make up your own tags and the values will be inserted and 
- * available via the TskSystemProperties service. 
- */
-class TSK_FRAMEWORK_API TskSystemPropertiesImpl : public TskSystemProperties
-{
-public:
-    /**
-     * Default constructor. The TskSystemPropertiesImpl object must then be 
-     * initialized with a call to one of the initialize() member functions
-     * before the object can be used.
-     */ 
-    TskSystemPropertiesImpl() : m_abstractConfig(static_cast<Poco::Util::AbstractConfiguration*>(NULL)) {}
-
-    /**
-     * Initialize using a configuration file.
-     *
-     * @param configfile Path to the XML file to be used to initialize the
-     * system properties.
-     */
-    void initialize(const std::wstring &configfile);
-
-    /**
-     * Initialize using a configuration file.
-     *
-     * @param configfile Path to the XML file to be used to initialize the
-     * system properties.
-     */
-    void initialize(const std::string &configfile);
-
-    /**
-     * Initialize with no initial system property settings.
-     */
-    void initialize();
-
-private:
-    // Prohibit copying by declaring copy control functions without implementations. 
-    TskSystemPropertiesImpl(const TskSystemPropertiesImpl&);
-    TskSystemPropertiesImpl& operator=(const TskSystemPropertiesImpl&);
-
-    virtual void setProperty(const std::string &name, const std::string &value);
-    virtual std::string getProperty(const std::string &name) const;
-
-    /**
-     * Manages a pointer to a Poco::Util::XMLConfiguration or
-     * Poco::Util::MapConfiguration object that maps names to values. 
-     */ 
-    Poco::AutoPtr<Poco::Util::AbstractConfiguration> m_abstractConfig;
-};
-
-#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 TskSystemPropertiesImpl.h
+ * Contains the interface of the TskSystemPropertiesImpl class.
+ */
+
+#ifndef _TSK_SYSTEMPROPERTIESIMPL_H
+#define _TSK_SYSTEMPROPERTIESIMPL_H
+
+#include "tsk/framework/framework_i.h"
+#include "TskSystemProperties.h"
+#include "Poco/Util/AbstractConfiguration.h"
+#include <string>
+
+/**
+ * An implementation of TskSystemProperties that uses Poco
+ * AbstractConfiguration class to set and retrieve name/value
+ * pairs from an XML file. Allows system property values to refer 
+ * to other system property values (see the TskSystemProperties class 
+ * description for more details).
+ * 
+ * The XML schema for this is that the name of the value is the tag and
+ * the value is stored in the tag.  Here is an example:
+ * 
+ * \verbatim
+ <?xml version="1.0" encoding="utf-8"?>
+ <TSK_FRAMEWORK_CONFIG>
+   <CONFIG_DIR>#PROG_DIR#/Config</CONFIG_DIR>
+   <MODULE_DIR>#PROG_DIR#/Modules</MODULE_DIR>
+ </TSK_FRAMEWORK_CONFIG>
+ * \endverbatim
+ * You can make up your own tags and the values will be inserted and 
+ * available via the TskSystemProperties service. 
+ */
+class TSK_FRAMEWORK_API TskSystemPropertiesImpl : public TskSystemProperties
+{
+public:
+    /**
+     * Default constructor. The TskSystemPropertiesImpl object must then be 
+     * initialized with a call to one of the initialize() member functions
+     * before the object can be used.
+     */ 
+    TskSystemPropertiesImpl() : m_abstractConfig(static_cast<Poco::Util::AbstractConfiguration*>(NULL)) {}
+
+    /**
+     * Initialize using a configuration file.
+     *
+     * @param configfile Path to the XML file to be used to initialize the
+     * system properties.
+     */
+    void initialize(const std::wstring &configfile);
+
+    /**
+     * Initialize using a configuration file.
+     *
+     * @param configfile Path to the XML file to be used to initialize the
+     * system properties.
+     */
+    void initialize(const std::string &configfile);
+
+    /**
+     * Initialize with no initial system property settings.
+     */
+    void initialize();
+
+private:
+    // Prohibit copying by declaring copy control functions without implementations. 
+    TskSystemPropertiesImpl(const TskSystemPropertiesImpl&);
+    TskSystemPropertiesImpl& operator=(const TskSystemPropertiesImpl&);
+
+    virtual void setProperty(const std::string &name, const std::string &value);
+    virtual std::string getProperty(const std::string &name) const;
+
+    /**
+     * Manages a pointer to a Poco::Util::XMLConfiguration or
+     * Poco::Util::MapConfiguration object that maps names to values. 
+     */ 
+    Poco::AutoPtr<Poco::Util::AbstractConfiguration> m_abstractConfig;
+};
+
+#endif
diff --git a/framework/tsk/framework/utilities/SectorRuns.cpp b/framework/tsk/framework/utilities/SectorRuns.cpp
index 5dc498b..588b4f1 100755
--- a/framework/tsk/framework/utilities/SectorRuns.cpp
+++ b/framework/tsk/framework/utilities/SectorRuns.cpp
@@ -1,139 +1,139 @@
-/*
- * 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 "SectorRuns.h"
-#include "tsk/framework/services/TskServices.h"
-
-/* This class is used to store a list of sector runs.  It is 
- * used to identify which runs contain unallocated data.
- */
-SectorRuns::SectorRuns() :
-    m_runs(NULL),
-    m_numRunsUsed(0),
-    m_numRunsAlloc(0),
-    m_curRun(0)
-{
-    // @@@
-    // Constructor should query the DB
-    // and build a list of IDs to empty sectors.
-    // The list is what will be iterated over.
-}
-
-SectorRuns::~SectorRuns()
-{
-    if (m_runs)
-        free(m_runs);
-    m_runs = NULL;
-}
-
-
-/**
- * Add a run to the list. 
- *
- * @param a_start Starting sector address relative to start of image file
- * @param a_len Length of run in sectors. 
- * @param a_vol_id Volume ID that run is located in
- * @returns -1 on error
- */
-int SectorRuns::addRun(uint64_t a_start, uint64_t a_len, int a_vol_id)
-{
-    if (m_numRunsUsed == m_numRunsAlloc)
-    {
-        m_numRunsAlloc += 64;
-        if ((m_runs = (SectorRun *)realloc(m_runs, m_numRunsAlloc * sizeof(SectorRun))) == NULL)
-        {
-            TskServices::Instance().getLog().logError(L"SectorRuns::addRun - Error allocating sector runs\n");
-            return -1;
-        }
-    }
-    m_runs[m_numRunsUsed].start = a_start;
-    m_runs[m_numRunsUsed].len = a_len;
-    m_runs[m_numRunsUsed].vol_id = a_vol_id;
-    m_numRunsUsed++;
-    return 0;
-}
-
-/** 
- * reset so that the next get() returns data on the first entry.
- */
-void SectorRuns::reset()
-{
-    m_curRun = 0;
-}
-
-/**
- * Advances internal pointer to next run.
- *
- * @returns -1 when at end of list
- */
-int SectorRuns::next()
-{
-    if (m_curRun + 1 == m_numRunsUsed)
-        return -1;
-
-    m_curRun++;
-    return 0;
-}
-
-/**
- * Get the length of the current entry.
- * @returns length of run in sectors
- */
-uint64_t SectorRuns::getDataLen() const
-{
-    if (m_curRun >= m_numRunsUsed)
-        return 0;
-    return m_runs[m_curRun].len;
-}
-
-/**
- * Get starting address of current entry. 
- * @returns start of run in sectors
- */
-uint64_t SectorRuns::getDataStart() const
-{
-    if (m_curRun >= m_numRunsUsed)
-        return 0;
-    return m_runs[m_curRun].start;
-}
-
-/**
- * Get volume id of current entry.
- * @returns volume ID of run in sectors
- */
-int SectorRuns::getVolID() const
-{
-    if (m_curRun >= m_numRunsUsed)
-        return 0;
-    return m_runs[m_curRun].vol_id;
-}
-
-/**
- * Read data in the current entry into the buffer.
- *
- * @param a_offsetSect Sector offset to start reading from (relative to start of current sector run)
- * @param a_lenSect 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 SectorRuns::getData(uint64_t a_offsetSect, int a_lenSect, char * a_buffer) const
-{
-    if (m_curRun >= m_numRunsUsed)
-        return -1;
-
-    if (a_offsetSect > m_runs[m_curRun].len) 
-        return -1;
-
-    uint64_t len_toread = a_lenSect;
-    if (a_offsetSect + a_lenSect > m_runs[m_curRun].len)
-        len_toread = m_runs[m_curRun].len - a_offsetSect;
-
-    return TskServices::Instance().getImageFile().getSectorData(m_runs[m_curRun].start + a_offsetSect, len_toread, a_buffer);
-}
+/*
+ * 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 "SectorRuns.h"
+#include "tsk/framework/services/TskServices.h"
+
+/* This class is used to store a list of sector runs.  It is 
+ * used to identify which runs contain unallocated data.
+ */
+SectorRuns::SectorRuns() :
+    m_runs(NULL),
+    m_numRunsUsed(0),
+    m_numRunsAlloc(0),
+    m_curRun(0)
+{
+    // @@@
+    // Constructor should query the DB
+    // and build a list of IDs to empty sectors.
+    // The list is what will be iterated over.
+}
+
+SectorRuns::~SectorRuns()
+{
+    if (m_runs)
+        free(m_runs);
+    m_runs = NULL;
+}
+
+
+/**
+ * Add a run to the list. 
+ *
+ * @param a_start Starting sector address relative to start of image file
+ * @param a_len Length of run in sectors. 
+ * @param a_vol_id Volume ID that run is located in
+ * @returns -1 on error
+ */
+int SectorRuns::addRun(uint64_t a_start, uint64_t a_len, int a_vol_id)
+{
+    if (m_numRunsUsed == m_numRunsAlloc)
+    {
+        m_numRunsAlloc += 64;
+        if ((m_runs = (SectorRun *)realloc(m_runs, m_numRunsAlloc * sizeof(SectorRun))) == NULL)
+        {
+            TskServices::Instance().getLog().logError(L"SectorRuns::addRun - Error allocating sector runs\n");
+            return -1;
+        }
+    }
+    m_runs[m_numRunsUsed].start = a_start;
+    m_runs[m_numRunsUsed].len = a_len;
+    m_runs[m_numRunsUsed].vol_id = a_vol_id;
+    m_numRunsUsed++;
+    return 0;
+}
+
+/** 
+ * reset so that the next get() returns data on the first entry.
+ */
+void SectorRuns::reset()
+{
+    m_curRun = 0;
+}
+
+/**
+ * Advances internal pointer to next run.
+ *
+ * @returns -1 when at end of list
+ */
+int SectorRuns::next()
+{
+    if (m_curRun + 1 == m_numRunsUsed)
+        return -1;
+
+    m_curRun++;
+    return 0;
+}
+
+/**
+ * Get the length of the current entry.
+ * @returns length of run in sectors
+ */
+uint64_t SectorRuns::getDataLen() const
+{
+    if (m_curRun >= m_numRunsUsed)
+        return 0;
+    return m_runs[m_curRun].len;
+}
+
+/**
+ * Get starting address of current entry. 
+ * @returns start of run in sectors
+ */
+uint64_t SectorRuns::getDataStart() const
+{
+    if (m_curRun >= m_numRunsUsed)
+        return 0;
+    return m_runs[m_curRun].start;
+}
+
+/**
+ * Get volume id of current entry.
+ * @returns volume ID of run in sectors
+ */
+int SectorRuns::getVolID() const
+{
+    if (m_curRun >= m_numRunsUsed)
+        return 0;
+    return m_runs[m_curRun].vol_id;
+}
+
+/**
+ * Read data in the current entry into the buffer.
+ *
+ * @param a_offsetSect Sector offset to start reading from (relative to start of current sector run)
+ * @param a_lenSect 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 SectorRuns::getData(uint64_t a_offsetSect, int a_lenSect, char * a_buffer) const
+{
+    if (m_curRun >= m_numRunsUsed)
+        return -1;
+
+    if (a_offsetSect > m_runs[m_curRun].len) 
+        return -1;
+
+    uint64_t len_toread = a_lenSect;
+    if (a_offsetSect + a_lenSect > m_runs[m_curRun].len)
+        len_toread = m_runs[m_curRun].len - a_offsetSect;
+
+    return TskServices::Instance().getImageFile().getSectorData(m_runs[m_curRun].start + a_offsetSect, len_toread, a_buffer);
+}
diff --git a/framework/tsk/framework/utilities/SectorRuns.h b/framework/tsk/framework/utilities/SectorRuns.h
index 20ffeeb..3b1733b 100755
--- a/framework/tsk/framework/utilities/SectorRuns.h
+++ b/framework/tsk/framework/utilities/SectorRuns.h
@@ -1,51 +1,51 @@
-/*
- * 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 _OSS_SECTORRUNS_H
-#define _OSS_SECTORRUNS_H
-
-#include "tsk/framework/framework_i.h"
-
-/**
- * Stores a list of runs (which have a starting sector and length).
- * Can be used to store information about a file, unused areas of an
- * image, or ...
- */
-class TSK_FRAMEWORK_API SectorRuns
-{
-public:
-    SectorRuns();
-    virtual ~SectorRuns();
-
-    int addRun(uint64_t start, uint64_t len, int vol_id);
-
-    int next();     // updates the current run; return -1 if none available
-    void reset();
-    int getData(uint64_t offset, int len, char * buffer) const;   // fills buffer with data from current run
-                                                  // returns the number of bytes written
-                                                  // returns -1 if no further data in the run
-    uint64_t getDataLen() const;
-    uint64_t getDataStart() const;
-    int getVolID() const;
-
-private:
-    typedef struct {
-        uint64_t start;
-        uint64_t len;
-        int vol_id;
-    } SectorRun;
-
-    SectorRun *m_runs;
-    unsigned int m_numRunsUsed;
-    unsigned int m_numRunsAlloc;
-    unsigned int m_curRun; 
-};
-
-#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 _OSS_SECTORRUNS_H
+#define _OSS_SECTORRUNS_H
+
+#include "tsk/framework/framework_i.h"
+
+/**
+ * Stores a list of runs (which have a starting sector and length).
+ * Can be used to store information about a file, unused areas of an
+ * image, or ...
+ */
+class TSK_FRAMEWORK_API SectorRuns
+{
+public:
+    SectorRuns();
+    virtual ~SectorRuns();
+
+    int addRun(uint64_t start, uint64_t len, int vol_id);
+
+    int next();     // updates the current run; return -1 if none available
+    void reset();
+    int getData(uint64_t offset, int len, char * buffer) const;   // fills buffer with data from current run
+                                                  // returns the number of bytes written
+                                                  // returns -1 if no further data in the run
+    uint64_t getDataLen() const;
+    uint64_t getDataStart() const;
+    int getVolID() const;
+
+private:
+    typedef struct {
+        uint64_t start;
+        uint64_t len;
+        int vol_id;
+    } SectorRun;
+
+    SectorRun *m_runs;
+    unsigned int m_numRunsUsed;
+    unsigned int m_numRunsAlloc;
+    unsigned int m_curRun; 
+};
+
+#endif
diff --git a/framework/tsk/framework/utilities/TskException.cpp b/framework/tsk/framework/utilities/TskException.cpp
index 46e6636..a077208 100755
--- a/framework/tsk/framework/utilities/TskException.cpp
+++ b/framework/tsk/framework/utilities/TskException.cpp
@@ -1,65 +1,65 @@
-/*
- * 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 TskException.cpp
- * Contains definition of Framework exception classes.
- * Based on techniques used in the Poco Exception class.
- */
-
-#include "TskException.h"
-#include <typeinfo>
-
-TskException::TskException(int code) : m_code(code)
-{
-}
-
-TskException::TskException(const std::string &msg, int code) : m_msg(msg), m_code(code)
-{
-}
-
-TskException::TskException(const TskException &e) : std::exception(e), m_msg(e.m_msg), m_code(e.m_code)
-{
-}
-
-TskException::~TskException() throw()
-{
-}
-
-TskException& TskException::operator =(const TskException &e)
-{
-    if (&e != this)
-    {
-        m_msg = e.m_msg;
-        m_code = e.m_code;
-    }
-
-    return *this;
-}
-
-const char * TskException::name() const throw()
-{
-    return "TskException";
-}
-
-const char * TskException::className() const throw()
-{
-    return typeid(*this).name();
-}
-
-const char * TskException::what() const throw()
-{
-    return name();
-}
-
-TSK_IMPLEMENT_EXCEPTION(TskFileException, TskException, "File access error")
-TSK_IMPLEMENT_EXCEPTION(TskNullPointerException, TskException, "NULL pointer")
-TSK_IMPLEMENT_EXCEPTION(TskFileNotFoundException, TskFileException, "File not found")
-TSK_IMPLEMENT_EXCEPTION(TskSystemPropertiesException, TskException, "System property not found")
+/*
+ * 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 TskException.cpp
+ * Contains definition of Framework exception classes.
+ * Based on techniques used in the Poco Exception class.
+ */
+
+#include "TskException.h"
+#include <typeinfo>
+
+TskException::TskException(int code) : m_code(code)
+{
+}
+
+TskException::TskException(const std::string &msg, int code) : m_msg(msg), m_code(code)
+{
+}
+
+TskException::TskException(const TskException &e) : std::exception(e), m_msg(e.m_msg), m_code(e.m_code)
+{
+}
+
+TskException::~TskException() throw()
+{
+}
+
+TskException& TskException::operator =(const TskException &e)
+{
+    if (&e != this)
+    {
+        m_msg = e.m_msg;
+        m_code = e.m_code;
+    }
+
+    return *this;
+}
+
+const char * TskException::name() const throw()
+{
+    return "TskException";
+}
+
+const char * TskException::className() const throw()
+{
+    return typeid(*this).name();
+}
+
+const char * TskException::what() const throw()
+{
+    return name();
+}
+
+TSK_IMPLEMENT_EXCEPTION(TskFileException, TskException, "File access error")
+TSK_IMPLEMENT_EXCEPTION(TskNullPointerException, TskException, "NULL pointer")
+TSK_IMPLEMENT_EXCEPTION(TskFileNotFoundException, TskFileException, "File not found")
+TSK_IMPLEMENT_EXCEPTION(TskSystemPropertiesException, TskException, "System property not found")
diff --git a/framework/tsk/framework/utilities/TskException.h b/framework/tsk/framework/utilities/TskException.h
index 8fea8f9..f2d4f34 100755
--- a/framework/tsk/framework/utilities/TskException.h
+++ b/framework/tsk/framework/utilities/TskException.h
@@ -1,140 +1,140 @@
-/*
- * 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 TskException.h
- * Contains definition of Framework exception classes.
- * Based on techniques used in the Poco Exception class.
- */
-
-#ifndef _TSK_EXCEPTION_H
-#define _TSK_EXCEPTION_H
-
-#include <stdexcept>
-
-#include "tsk/framework/framework_i.h"
-
-/**
- * Framework exception class
- */
-class TSK_FRAMEWORK_API TskException : public std::exception
-{
-public:
-    /// Create an exception using the supplied message.
-    TskException(const std::string& msg, int code = 0);
-
-    /// Copy Constructor
-    TskException(const TskException& e);
-
-    /// Destructor
-    ~TskException() throw ();
-
-    /// Assignment operator
-    TskException& operator= (const TskException& e);
-
-    /// Returns a static string describing the exception.
-    virtual const char * name() const throw();
-
-    /// Returns the name of the exception class.
-    virtual const char * className() const throw();
-
-    /// Returns a static string describing the exception.
-    /// Same as name(), but for compatibility with std::exception.
-    virtual const char * what() const throw();
-
-    /// Returns the message text.
-    const std::string& message() const;
-
-    /// Returns the exception code.
-    int code() const;
-
-protected:
-    /// Default constructor.
-    TskException(int code = 0);
-
-    /// Sets the message for the exception.
-    void message(const std::string& msg);
-
-private:
-    std::string m_msg;
-    int m_code;
-};
-
-inline const std::string& TskException::message() const
-{
-    return m_msg;
-}
-
-inline void TskException::message(const std::string &msg)
-{
-    m_msg = msg;
-}
-
-inline int TskException::code() const
-{
-    return m_code;
-}
-
-//
-// Macros for quickly declaring and implementing exception classes.
-// Unfortunately, we cannot use a template here because character
-// pointers (which we need for specifying the exception name)
-// are not allowed as template arguments.
-//
-#define TSK_DECLARE_EXCEPTION(CLS, BASE) \
-	class TSK_FRAMEWORK_API CLS: public BASE									    \
-	{																				\
-	public:																			\
-		CLS(int code = 0);															\
-		CLS(const std::string& msg, int code = 0);									\
-		CLS(const CLS& exc);														\
-		~CLS() throw();																\
-		CLS& operator = (const CLS& exc);											\
-		const char* name() const throw();											\
-		const char* className() const throw();										\
-	};
-
-
-#define TSK_IMPLEMENT_EXCEPTION(CLS, BASE, NAME)													\
-	CLS::CLS(int code): BASE(code)																	\
-	{																								\
-	}																								\
-	CLS::CLS(const std::string& msg, int code): BASE(msg, code)										\
-	{																								\
-	}																								\
-	CLS::CLS(const CLS& exc): BASE(exc)																\
-	{																								\
-	}																								\
-	CLS::~CLS() throw()																				\
-	{																								\
-	}																								\
-	CLS& CLS::operator = (const CLS& exc)															\
-	{																								\
-		BASE::operator = (exc);																		\
-		return *this;																				\
-	}																								\
-	const char* CLS::name() const throw()	           												\
-	{																								\
-		return NAME;																				\
-	}																								\
-	const char* CLS::className() const throw()			    										\
-	{																								\
-		return typeid(*this).name();																\
-	}																								\
-
-//
-// Standard exception classes
-//
-TSK_DECLARE_EXCEPTION(TskFileException, TskException)
-TSK_DECLARE_EXCEPTION(TskNullPointerException, TskException)
-TSK_DECLARE_EXCEPTION(TskFileNotFoundException, TskFileException)
-TSK_DECLARE_EXCEPTION(TskSystemPropertiesException, TskException)
-
-#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 TskException.h
+ * Contains definition of Framework exception classes.
+ * Based on techniques used in the Poco Exception class.
+ */
+
+#ifndef _TSK_EXCEPTION_H
+#define _TSK_EXCEPTION_H
+
+#include <stdexcept>
+
+#include "tsk/framework/framework_i.h"
+
+/**
+ * Framework exception class
+ */
+class TSK_FRAMEWORK_API TskException : public std::exception
+{
+public:
+    /// Create an exception using the supplied message.
+    TskException(const std::string& msg, int code = 0);
+
+    /// Copy Constructor
+    TskException(const TskException& e);
+
+    /// Destructor
+    ~TskException() throw ();
+
+    /// Assignment operator
+    TskException& operator= (const TskException& e);
+
+    /// Returns a static string describing the exception.
+    virtual const char * name() const throw();
+
+    /// Returns the name of the exception class.
+    virtual const char * className() const throw();
+
+    /// Returns a static string describing the exception.
+    /// Same as name(), but for compatibility with std::exception.
+    virtual const char * what() const throw();
+
+    /// Returns the message text.
+    const std::string& message() const;
+
+    /// Returns the exception code.
+    int code() const;
+
+protected:
+    /// Default constructor.
+    TskException(int code = 0);
+
+    /// Sets the message for the exception.
+    void message(const std::string& msg);
+
+private:
+    std::string m_msg;
+    int m_code;
+};
+
+inline const std::string& TskException::message() const
+{
+    return m_msg;
+}
+
+inline void TskException::message(const std::string &msg)
+{
+    m_msg = msg;
+}
+
+inline int TskException::code() const
+{
+    return m_code;
+}
+
+//
+// Macros for quickly declaring and implementing exception classes.
+// Unfortunately, we cannot use a template here because character
+// pointers (which we need for specifying the exception name)
+// are not allowed as template arguments.
+//
+#define TSK_DECLARE_EXCEPTION(CLS, BASE) \
+	class TSK_FRAMEWORK_API CLS: public BASE									    \
+	{																				\
+	public:																			\
+		CLS(int code = 0);															\
+		CLS(const std::string& msg, int code = 0);									\
+		CLS(const CLS& exc);														\
+		~CLS() throw();																\
+		CLS& operator = (const CLS& exc);											\
+		const char* name() const throw();											\
+		const char* className() const throw();										\
+	};
+
+
+#define TSK_IMPLEMENT_EXCEPTION(CLS, BASE, NAME)													\
+	CLS::CLS(int code): BASE(code)																	\
+	{																								\
+	}																								\
+	CLS::CLS(const std::string& msg, int code): BASE(msg, code)										\
+	{																								\
+	}																								\
+	CLS::CLS(const CLS& exc): BASE(exc)																\
+	{																								\
+	}																								\
+	CLS::~CLS() throw()																				\
+	{																								\
+	}																								\
+	CLS& CLS::operator = (const CLS& exc)															\
+	{																								\
+		BASE::operator = (exc);																		\
+		return *this;																				\
+	}																								\
+	const char* CLS::name() const throw()	           												\
+	{																								\
+		return NAME;																				\
+	}																								\
+	const char* CLS::className() const throw()			    										\
+	{																								\
+		return typeid(*this).name();																\
+	}																								\
+
+//
+// Standard exception classes
+//
+TSK_DECLARE_EXCEPTION(TskFileException, TskException)
+TSK_DECLARE_EXCEPTION(TskNullPointerException, TskException)
+TSK_DECLARE_EXCEPTION(TskFileNotFoundException, TskFileException)
+TSK_DECLARE_EXCEPTION(TskSystemPropertiesException, TskException)
+
+#endif
diff --git a/framework/tsk/framework/utilities/TskModuleDev.h b/framework/tsk/framework/utilities/TskModuleDev.h
index bb4c4d5..f5e2348 100644
--- a/framework/tsk/framework/utilities/TskModuleDev.h
+++ b/framework/tsk/framework/utilities/TskModuleDev.h
@@ -1,71 +1,71 @@
-/*
- * 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_MODULEDEV_H
-#define _TSK_MODULEDEV_H
-
-/** 
- * Include this .h file when writing a dynamic link library
- */
-
-#include "tsk/framework/TskVersionInfo.h"
-#include "tsk/framework/services/TskServices.h"
-#include "tsk/framework/utilities/TskUtilities.h"
-#include "tsk/framework/pipeline/TskModule.h"
-
-#if defined(_WIN32)
-#if !defined(TSK_MODULE_IMPORT)
-    #define TSK_MODULE_EXPORT __declspec(dllexport)
-#else
-    #define TSK_MODULE_EXPORT __declspec(dllimport)
-#endif
-#else
-    #define TSK_MODULE_EXPORT
-#endif
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-    /**
-     * Returns the compiler that the module was built with.
-     */
-    TSK_MODULE_EXPORT TskVersionInfo::Compiler getCompiler()
-    {
-        return TskVersionInfo::getCompiler();
-    }
-
-    /**
-     * Returns the version of the compiler that the module was built with.
-     */
-    TSK_MODULE_EXPORT int getCompilerVersion()
-    {
-        return TskVersionInfo::getCompilerVersion();
-    }
-
-    /**
-     * Returns the version of the TSK framework that the module was built against.
-     */
-    TSK_MODULE_EXPORT int getFrameWorkVersion()
-    {
-        return TskVersionInfo::getFrameworkVersion();
-    }
-
-    /**
-     * Returns whether this is a debug or release build of the module.
-     */
-    TSK_MODULE_EXPORT TskVersionInfo::BuildType getBuildType()
-    {
-        return TskVersionInfo::getBuildType();
-    }
-#ifdef __cplusplus
-}
-#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_MODULEDEV_H
+#define _TSK_MODULEDEV_H
+
+/** 
+ * Include this .h file when writing a dynamic link library
+ */
+
+#include "tsk/framework/TskVersionInfo.h"
+#include "tsk/framework/services/TskServices.h"
+#include "tsk/framework/utilities/TskUtilities.h"
+#include "tsk/framework/pipeline/TskModule.h"
+
+#if defined(_WIN32)
+#if !defined(TSK_MODULE_IMPORT)
+    #define TSK_MODULE_EXPORT __declspec(dllexport)
+#else
+    #define TSK_MODULE_EXPORT __declspec(dllimport)
+#endif
+#else
+    #define TSK_MODULE_EXPORT
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+    /**
+     * Returns the compiler that the module was built with.
+     */
+    TSK_MODULE_EXPORT TskVersionInfo::Compiler getCompiler()
+    {
+        return TskVersionInfo::getCompiler();
+    }
+
+    /**
+     * Returns the version of the compiler that the module was built with.
+     */
+    TSK_MODULE_EXPORT int getCompilerVersion()
+    {
+        return TskVersionInfo::getCompilerVersion();
+    }
+
+    /**
+     * Returns the version of the TSK framework that the module was built against.
+     */
+    TSK_MODULE_EXPORT int getFrameWorkVersion()
+    {
+        return TskVersionInfo::getFrameworkVersion();
+    }
+
+    /**
+     * Returns whether this is a debug or release build of the module.
+     */
+    TSK_MODULE_EXPORT TskVersionInfo::BuildType getBuildType()
+    {
+        return TskVersionInfo::getBuildType();
+    }
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/framework/tsk/framework/utilities/TskUtilities.cpp b/framework/tsk/framework/utilities/TskUtilities.cpp
index 4083bca..25023fa 100755
--- a/framework/tsk/framework/utilities/TskUtilities.cpp
+++ b/framework/tsk/framework/utilities/TskUtilities.cpp
@@ -1,216 +1,216 @@
-/*
- *
- *  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 TskUtilities.cpp
- * Contains common utility methods.
- */
-
-// TSK and TSK Framework includes
-#include "TskUtilities.h"
-#include "tsk/framework/services/TskServices.h"
-#include "tsk/base/tsk_base_i.h"
-
-// Poco Includes
-#include "Poco/UnicodeConverter.h"
-#include "Poco/Net/DNS.h"
-#include "Poco/Net/HostEntry.h"
-#include "Poco/Net/NetException.h"
-#include "Poco/Path.h"
-
-// C/C++ library includes
-#include <sstream>
-
-#if defined _WIN32 || defined _WIN64
-#include <Windows.h>
-#endif
-
-#ifdef __APPLE__
-#include <mach-o/dyld.h>
-#endif
-
-/**
- * Convert a given UTF16 string to UTF8
- * @param utf16Str The UTF16 encoded string.
- * @returns A UTF8 encoded version of the input string.
- */
-std::string TskUtilities::toUTF8(const std::wstring &utf16Str)
-{
-    std::string utf8Str;
-    char *utf8Buf;
-    int utf8Size = utf16Str.size() * 5 + 1;
-    utf8Buf = new char[utf8Size];
-    UTF8 *ptr8;
-    wchar_t *ptr16;
-
-    ptr8 = (UTF8 *) utf8Buf;
-    ptr16 = (wchar_t *) utf16Str.c_str();
-
-    TSKConversionResult retval =
-        tsk_UTF16WtoUTF8_lclorder((const wchar_t **)&ptr16, 
-                                  (wchar_t *)&ptr16[utf16Str.size()+1],
-                                  &ptr8,
-                                  (UTF8 *) ((uintptr_t) ptr8 + utf8Size * sizeof(UTF8)), 
-                                  TSKstrictConversion);
-    if (retval != TSKconversionOK) 
-    {
-        return "";
-    }
-    utf8Str.assign(utf8Buf);
-    delete [] utf8Buf;
-    return utf8Str;
-}
-
-/**
- * Convert a given UTF8 string to UTF16
- * @param utf8Str The UTF8 encoded string.
- * @returns A UTF16 encoded version of the input string.
- */
-std::wstring TskUtilities::toUTF16(const std::string &utf8Str)
-{
-    std::wstring utf16Str;
-    wchar_t *utf16Buf;
-    int utf16Size = utf8Str.size() + 1;
-    utf16Buf = new wchar_t[utf16Size];
-    UTF8 *ptr8;
-    wchar_t *ptr16;
-
-    ptr16 = (wchar_t *) utf16Buf;
-    ptr8 = (UTF8 *) utf8Str.data();
-
-    TSKConversionResult retval =
-        tsk_UTF8toUTF16W((const UTF8 **) &ptr8, 
-                        (UTF8 *) & utf8Str.data()[utf8Str.size()], 
-                        &ptr16,
-                        (wchar_t *) ((uintptr_t) ptr16 + utf16Size * sizeof(wchar_t)), 
-                        TSKstrictConversion);
-    if (retval != TSKconversionOK) 
-    {
-        return L"";
-    }
-    utf16Str.assign(utf16Buf, ptr16 - utf16Buf);
-    delete [] utf16Buf;
-    return utf16Str;
-}
-
-void TskUtilities::cleanUTF8(char *buf)
-{
-    tsk_cleanupUTF8(buf, '^'); 
-}
-
-/**
- * Get the IP address for the given host name.
- * @param host The name of the host who's IP address you want.
- * @param host_ip This string will be filled in with the IP address.
- * @returns true on success, false otherwise.
- */
-bool TskUtilities::getHostIP(const std::string& host, std::string & host_ip)
-{
-    try
-    {
-        Poco::Net::HostEntry hostEntry = Poco::Net::DNS::hostByName(host);
-
-        if (hostEntry.addresses().empty())
-        {
-            LOGERROR(L"TskUtilities::getHostIP - No addresses found for host.\n");
-            return false;
-        }
-
-        // Take the first address.
-        host_ip = hostEntry.addresses()[0].toString();
-        return true;
-    }
-    catch (Poco::Net::NetException& netEx)
-    {
-        std::wstringstream msg;
-        msg << L"TskUtilities::getHostIP - Error resolving host name: " << host.c_str() 
-            << L" : " << netEx.what() << std::endl;
-        LOGERROR(msg.str());
-        return false;
-    }
-}
-
-/** Get the path of the directory where the currently executing program is 
- * installed.  
- *
- * @returns The path of the program directory.
- */
-std::string TskUtilities::getProgDir()
-{
-#ifdef TSK_WIN32
-    wchar_t progPath[256];
-    wchar_t fullPath[256];
-    HINSTANCE hInstance = GetModuleHandleW(NULL);
-
-    GetModuleFileNameW(hInstance, fullPath, 256);
-    int i = wcslen(fullPath)-1;
-    for (; i > 0; i--) {
-        if (i > 256)
-            break;
-
-        if (fullPath[i] == '\\') {
-            wcsncpy_s(progPath, fullPath, i+1);
-            break;
-        }
-    }
-
-    std::wstring progPathNoNull(progPath, i+1);
-    return TskUtilities::toUTF8(progPathNoNull);
-
-#elif __APPLE__
-    char path[MAXPATHLEN+1];
-    uint32_t path_len = MAXPATHLEN;
-    if (_NSGetExecutablePath(path, &path_len) == 0) {
-        Poco::Path p(path);
-        return p.makeParent().toString();
-    }
-    return std::string("");
-#else // NOT TSK_WIN32
-    int size = 256;
-    char* buf = 0;
-    int ret = 0;
- 
-    while (1) {
-        buf = (char*)realloc(buf, size*sizeof(char));
-        if (!buf)
-            return std::string("");
-        ret = readlink("/proc/self/exe", buf, size);
-        if (ret < 0) {
-            free(buf);
-            return std::string("");
-        }
-        if (ret < size) {
-            std::string s(buf, ret);
-            free(buf);
-            Poco::Path path(s);
-            return path.makeParent().toString();
-        }
-        size *= 2;
-    }
-    return std::string("");
-#endif // NOT TSK_WIN32
-}
-
-/** Strip matching leading and trailing double quotes from the input str.
- * If there is no matching quotes, the input str is returned.
- * @returns String without matching leading and trailing double quote.
- */
-std::string TskUtilities::stripQuotes(const std::string& str)
-{
-    if (str.length() == 0)
-        return str;
-    std::string outStr;
-    if (str[0] == '"' && str[str.length()-1] == '"') {
-        outStr = str.substr(1, str.length()-2);
-    } else
-        outStr = str;
-    return outStr;
-}
+/*
+ *
+ *  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 TskUtilities.cpp
+ * Contains common utility methods.
+ */
+
+// TSK and TSK Framework includes
+#include "TskUtilities.h"
+#include "tsk/framework/services/TskServices.h"
+#include "tsk/base/tsk_base_i.h"
+
+// Poco Includes
+#include "Poco/UnicodeConverter.h"
+#include "Poco/Net/DNS.h"
+#include "Poco/Net/HostEntry.h"
+#include "Poco/Net/NetException.h"
+#include "Poco/Path.h"
+
+// C/C++ library includes
+#include <sstream>
+
+#if defined _WIN32 || defined _WIN64
+#include <Windows.h>
+#endif
+
+#ifdef __APPLE__
+#include <mach-o/dyld.h>
+#endif
+
+/**
+ * Convert a given UTF16 string to UTF8
+ * @param utf16Str The UTF16 encoded string.
+ * @returns A UTF8 encoded version of the input string.
+ */
+std::string TskUtilities::toUTF8(const std::wstring &utf16Str)
+{
+    std::string utf8Str;
+    char *utf8Buf;
+    int utf8Size = utf16Str.size() * 5 + 1;
+    utf8Buf = new char[utf8Size];
+    UTF8 *ptr8;
+    wchar_t *ptr16;
+
+    ptr8 = (UTF8 *) utf8Buf;
+    ptr16 = (wchar_t *) utf16Str.c_str();
+
+    TSKConversionResult retval =
+        tsk_UTF16WtoUTF8_lclorder((const wchar_t **)&ptr16, 
+                                  (wchar_t *)&ptr16[utf16Str.size()+1],
+                                  &ptr8,
+                                  (UTF8 *) ((uintptr_t) ptr8 + utf8Size * sizeof(UTF8)), 
+                                  TSKstrictConversion);
+    if (retval != TSKconversionOK) 
+    {
+        return "";
+    }
+    utf8Str.assign(utf8Buf);
+    delete [] utf8Buf;
+    return utf8Str;
+}
+
+/**
+ * Convert a given UTF8 string to UTF16
+ * @param utf8Str The UTF8 encoded string.
+ * @returns A UTF16 encoded version of the input string.
+ */
+std::wstring TskUtilities::toUTF16(const std::string &utf8Str)
+{
+    std::wstring utf16Str;
+    wchar_t *utf16Buf;
+    int utf16Size = utf8Str.size() + 1;
+    utf16Buf = new wchar_t[utf16Size];
+    UTF8 *ptr8;
+    wchar_t *ptr16;
+
+    ptr16 = (wchar_t *) utf16Buf;
+    ptr8 = (UTF8 *) utf8Str.data();
+
+    TSKConversionResult retval =
+        tsk_UTF8toUTF16W((const UTF8 **) &ptr8, 
+                        (UTF8 *) & utf8Str.data()[utf8Str.size()], 
+                        &ptr16,
+                        (wchar_t *) ((uintptr_t) ptr16 + utf16Size * sizeof(wchar_t)), 
+                        TSKstrictConversion);
+    if (retval != TSKconversionOK) 
+    {
+        return L"";
+    }
+    utf16Str.assign(utf16Buf, ptr16 - utf16Buf);
+    delete [] utf16Buf;
+    return utf16Str;
+}
+
+void TskUtilities::cleanUTF8(char *buf)
+{
+    tsk_cleanupUTF8(buf, '^'); 
+}
+
+/**
+ * Get the IP address for the given host name.
+ * @param host The name of the host who's IP address you want.
+ * @param host_ip This string will be filled in with the IP address.
+ * @returns true on success, false otherwise.
+ */
+bool TskUtilities::getHostIP(const std::string& host, std::string & host_ip)
+{
+    try
+    {
+        Poco::Net::HostEntry hostEntry = Poco::Net::DNS::hostByName(host);
+
+        if (hostEntry.addresses().empty())
+        {
+            LOGERROR(L"TskUtilities::getHostIP - No addresses found for host.\n");
+            return false;
+        }
+
+        // Take the first address.
+        host_ip = hostEntry.addresses()[0].toString();
+        return true;
+    }
+    catch (Poco::Net::NetException& netEx)
+    {
+        std::wstringstream msg;
+        msg << L"TskUtilities::getHostIP - Error resolving host name: " << host.c_str() 
+            << L" : " << netEx.what() << std::endl;
+        LOGERROR(msg.str());
+        return false;
+    }
+}
+
+/** Get the path of the directory where the currently executing program is 
+ * installed.  
+ *
+ * @returns The path of the program directory.
+ */
+std::string TskUtilities::getProgDir()
+{
+#ifdef TSK_WIN32
+    wchar_t progPath[256];
+    wchar_t fullPath[256];
+    HINSTANCE hInstance = GetModuleHandleW(NULL);
+
+    GetModuleFileNameW(hInstance, fullPath, 256);
+    int i = wcslen(fullPath)-1;
+    for (; i > 0; i--) {
+        if (i > 256)
+            break;
+
+        if (fullPath[i] == '\\') {
+            wcsncpy_s(progPath, fullPath, i+1);
+            break;
+        }
+    }
+
+    std::wstring progPathNoNull(progPath, i+1);
+    return TskUtilities::toUTF8(progPathNoNull);
+
+#elif __APPLE__
+    char path[MAXPATHLEN+1];
+    uint32_t path_len = MAXPATHLEN;
+    if (_NSGetExecutablePath(path, &path_len) == 0) {
+        Poco::Path p(path);
+        return p.makeParent().toString();
+    }
+    return std::string("");
+#else // NOT TSK_WIN32
+    int size = 256;
+    char* buf = 0;
+    int ret = 0;
+ 
+    while (1) {
+        buf = (char*)realloc(buf, size*sizeof(char));
+        if (!buf)
+            return std::string("");
+        ret = readlink("/proc/self/exe", buf, size);
+        if (ret < 0) {
+            free(buf);
+            return std::string("");
+        }
+        if (ret < size) {
+            std::string s(buf, ret);
+            free(buf);
+            Poco::Path path(s);
+            return path.makeParent().toString();
+        }
+        size *= 2;
+    }
+    return std::string("");
+#endif // NOT TSK_WIN32
+}
+
+/** Strip matching leading and trailing double quotes from the input str.
+ * If there is no matching quotes, the input str is returned.
+ * @returns String without matching leading and trailing double quote.
+ */
+std::string TskUtilities::stripQuotes(const std::string& str)
+{
+    if (str.length() == 0)
+        return str;
+    std::string outStr;
+    if (str[0] == '"' && str[str.length()-1] == '"') {
+        outStr = str.substr(1, str.length()-2);
+    } else
+        outStr = str;
+    return outStr;
+}
diff --git a/framework/tsk/framework/utilities/TskUtilities.h b/framework/tsk/framework/utilities/TskUtilities.h
index d0d7c43..ac357b3 100755
--- a/framework/tsk/framework/utilities/TskUtilities.h
+++ b/framework/tsk/framework/utilities/TskUtilities.h
@@ -1,39 +1,39 @@
-/*
- *
- *  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 TskUtilities.h
- * Contains common utility methods.
- */
-
-#ifndef _TSK_UTILITIES_H
-#define _TSK_UTILITIES_H
-
-#include <string>
-
-#include "tsk/framework/framework_i.h"
-
-/**
- * Contains commonly needed utility methods.  Refer to the poco library
- * for other commonly needed methods.
- */
-class TSK_FRAMEWORK_API TskUtilities
-{
-public:
-    static std::string toUTF8(const std::wstring& utf16Str);
-    static std::wstring toUTF16(const std::string& utf8Str);
-    static void cleanUTF8(char *buf);
-    static bool getHostIP(const std::string& host, std::string& host_ip);
-    static std::string getProgDir();
-    static std::string stripQuotes(const std::string& str);
-};
-
-#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 TskUtilities.h
+ * Contains common utility methods.
+ */
+
+#ifndef _TSK_UTILITIES_H
+#define _TSK_UTILITIES_H
+
+#include <string>
+
+#include "tsk/framework/framework_i.h"
+
+/**
+ * Contains commonly needed utility methods.  Refer to the poco library
+ * for other commonly needed methods.
+ */
+class TSK_FRAMEWORK_API TskUtilities
+{
+public:
+    static std::string toUTF8(const std::wstring& utf16Str);
+    static std::wstring toUTF16(const std::string& utf8Str);
+    static void cleanUTF8(char *buf);
+    static bool getHostIP(const std::string& host, std::string& host_ip);
+    static std::string getProgDir();
+    static std::string stripQuotes(const std::string& str);
+};
+
+#endif
diff --git a/framework/tsk/framework/utilities/UnallocRun.cpp b/framework/tsk/framework/utilities/UnallocRun.cpp
index d54dded..285c5a2 100755
--- a/framework/tsk/framework/utilities/UnallocRun.cpp
+++ b/framework/tsk/framework/utilities/UnallocRun.cpp
@@ -1,59 +1,59 @@
-/*
- * 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 "UnallocRun.h"
-
-/**
- * Stores mapping between the unallocated images that are used for carving and
- * the original images.
- * @param a_volId Volume ID in original image that sector run is located in.
- * @param a_unallocImgId ID of the unallocated image
- * @param a_unallocStart Starting sector in unallocated image
- * @param a_length Number of sectors in run
- * @param a_allocStart Starting sector in original image
- */
-UnallocRun::UnallocRun(int a_volId, int a_unallocImgId, uint64_t a_unallocStart,
-                       uint64_t a_length, uint64_t a_allocStart) :
-        m_volId(a_volId),
-        m_unallocImgId(a_unallocImgId),
-        m_unallocStart(a_unallocStart),
-        m_length(a_length),
-        m_origStart(a_allocStart)
-{
-}
-
-UnallocRun::~UnallocRun()
-{
-}
-
-int UnallocRun::getVolId() const
-{
-    return m_volId;
-}
-
-int UnallocRun::getUnallocImgId() const
-{
-    return m_unallocImgId;
-}
-
-uint64_t UnallocRun::getUnallocStart() const
-{
-    return m_unallocStart;
-}
-
-uint64_t UnallocRun::getLength() const
-{
-    return m_length;
-}
-
-uint64_t UnallocRun::getAllocStart() const
-{
-    return m_origStart;
-}
+/*
+ * 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 "UnallocRun.h"
+
+/**
+ * Stores mapping between the unallocated images that are used for carving and
+ * the original images.
+ * @param a_volId Volume ID in original image that sector run is located in.
+ * @param a_unallocImgId ID of the unallocated image
+ * @param a_unallocStart Starting sector in unallocated image
+ * @param a_length Number of sectors in run
+ * @param a_allocStart Starting sector in original image
+ */
+UnallocRun::UnallocRun(int a_volId, int a_unallocImgId, uint64_t a_unallocStart,
+                       uint64_t a_length, uint64_t a_allocStart) :
+        m_volId(a_volId),
+        m_unallocImgId(a_unallocImgId),
+        m_unallocStart(a_unallocStart),
+        m_length(a_length),
+        m_origStart(a_allocStart)
+{
+}
+
+UnallocRun::~UnallocRun()
+{
+}
+
+int UnallocRun::getVolId() const
+{
+    return m_volId;
+}
+
+int UnallocRun::getUnallocImgId() const
+{
+    return m_unallocImgId;
+}
+
+uint64_t UnallocRun::getUnallocStart() const
+{
+    return m_unallocStart;
+}
+
+uint64_t UnallocRun::getLength() const
+{
+    return m_length;
+}
+
+uint64_t UnallocRun::getAllocStart() const
+{
+    return m_origStart;
+}
diff --git a/framework/tsk/framework/utilities/UnallocRun.h b/framework/tsk/framework/utilities/UnallocRun.h
index 95177a0..87c3d62 100755
--- a/framework/tsk/framework/utilities/UnallocRun.h
+++ b/framework/tsk/framework/utilities/UnallocRun.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
- */
-
-#ifndef _OSS_UNALLOCRUN_H
-#define _OSS_UNALLOCRUN_H
-
-#include "tsk/framework/framework_i.h"
-
-/**
- * Stores information that can map a region in the original disk image
- * to a region in one of the chunks of unallocated space (as created by
- * the CarvePrep implementation. 
- */
-class TSK_FRAMEWORK_API UnallocRun
-{
-public:
-    UnallocRun(int a_volId, int a_unallocImgId, uint64_t a_unallocStart,
-        uint64_t a_length, uint64_t a_allocStart);
-    ~UnallocRun();
-
-    int getVolId() const;
-    int getUnallocImgId() const;
-    uint64_t getUnallocStart() const;
-    uint64_t getLength() const;
-    uint64_t getAllocStart() const;
-
-private:
-    int m_volId;
-    int m_unallocImgId;
-    uint64_t m_unallocStart;
-    uint64_t m_length;
-    uint64_t m_origStart;
-};
-
-#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 _OSS_UNALLOCRUN_H
+#define _OSS_UNALLOCRUN_H
+
+#include "tsk/framework/framework_i.h"
+
+/**
+ * Stores information that can map a region in the original disk image
+ * to a region in one of the chunks of unallocated space (as created by
+ * the CarvePrep implementation. 
+ */
+class TSK_FRAMEWORK_API UnallocRun
+{
+public:
+    UnallocRun(int a_volId, int a_unallocImgId, uint64_t a_unallocStart,
+        uint64_t a_length, uint64_t a_allocStart);
+    ~UnallocRun();
+
+    int getVolId() const;
+    int getUnallocImgId() const;
+    uint64_t getUnallocStart() const;
+    uint64_t getLength() const;
+    uint64_t getAllocStart() const;
+
+private:
+    int m_volId;
+    int m_unallocImgId;
+    uint64_t m_unallocStart;
+    uint64_t m_length;
+    uint64_t m_origStart;
+};
+
+#endif
diff --git a/man/ils.1 b/man/ils.1
index 1b0460c..c0547a6 100644
--- a/man/ils.1
+++ b/man/ils.1
@@ -88,11 +88,9 @@ with at least one directory entry in the file system.
 List only inodes without any hard links. These belong to files that no
 longer exist, and to removed files that are still open or executing.
 .IP \fB-z\fR
-List only inodes with zero status change time. Presumably, these
-inodes were never used.
+List only inodes that were likely to have not been used.
 .IP \fB-Z\fR
-List only inodes with non-zero status change time. Presumably, these
-belong to files that still exist, or that existed in the past.
+List only inodes that were likely to be used.
 .PP
 The output format is in time machine format.
 The output begins with a two-line header that
diff --git a/man/tsk_comparedir.1 b/man/tsk_comparedir.1
index 66d6451..12b8936 100644
--- a/man/tsk_comparedir.1
+++ b/man/tsk_comparedir.1
@@ -1,59 +1,59 @@
-.TH TSK_COMPAREDIR 1 
-.SH NAME
-tsk_comparedir - compare the contents of a directory with the contents of an image or local device. 
-.SH SYNOPSIS
-.B tsk_comparedir [-vV] [-n
-.I start_inum
-.B ] [ -f
-.I fstype
-.B ] [ -i
-.I imgtype
-.B ] [ -b
-.I dev_sector_size
-.B ] [ -o
-.I sector_offset
-.B ]
-.I image [images] comparison_directory
-.SH DESCRIPTION
-.B tsk_comparedir 
-compares the contents of
-.I image
-to the contents of
-.I comparison_directory.
-This can be useful for detecting rootkits and when testing.  Rootkits can be detected by comparing the contents of a local directory and a local raw device.  The rootkits typically don't hide data when it is read directly from the raw device. 
-
-The arguments are as follows:
-.IP "-o sector_offset"
-Sector offset for a partition in the image or device to compare with.
-.IP "-n start_inum"
-Starting inum for a directory in the image to start the comparison at.
-.IP -v
-verbose output to stderr
-.IP -V
-Print version
+.TH TSK_COMPAREDIR 1 
+.SH NAME
+tsk_comparedir - compare the contents of a directory with the contents of an image or local device. 
+.SH SYNOPSIS
+.B tsk_comparedir [-vV] [-n
+.I start_inum
+.B ] [ -f
+.I fstype
+.B ] [ -i
+.I imgtype
+.B ] [ -b
+.I dev_sector_size
+.B ] [ -o
+.I sector_offset
+.B ]
+.I image [images] comparison_directory
+.SH DESCRIPTION
+.B tsk_comparedir 
+compares the contents of
+.I image
+to the contents of
+.I comparison_directory.
+This can be useful for detecting rootkits and when testing.  Rootkits can be detected by comparing the contents of a local directory and a local raw device.  The rootkits typically don't hide data when it is read directly from the raw device. 
+
+The arguments are as follows:
+.IP "-o sector_offset"
+Sector offset for a partition in the image or device to compare with.
+.IP "-n start_inum"
+Starting inum for a directory in the image to start the comparison at.
+.IP -v
+verbose output to stderr
+.IP -V
+Print version
 .IP "-f fstype"
 Specify the file system type.
 Use '\-f list' to list the supported file system types.
 If not given, autodetection methods are used.
-.IP "-i imgtype"
+.IP "-i imgtype"
 The format of the image file, such as raw.
 Use '\-i list' to list the supported types.
-If not given, autodetection methods are used.
-.IP "-b dev_sector_size"
-The size (in bytes) of the device sectors.
-If not given, autodetection methods are used.
+If not given, autodetection methods are used.
+.IP "-b dev_sector_size"
+The size (in bytes) of the device sectors.
+If not given, autodetection methods are used.
 .IP "image [images]"
 The disk or partition image to read, whose format is given with '\-i'.
 Multiple image file names can be given if the image is split into multiple segments.
 If only one image file is given, and its name is the first in a sequence (e.g., as indicated by ending in '.001'), subsequent image segments will be included automatically.
-
-.SH EXAMPLES
-To compare the directories in image.dd to those in directory:
-
-	# tsk_comparedir ./image.dd ./directory
-
-
-.SH AUTHOR
-Brian Carrier <carrier at sleuthkit dot org>
-
-Send documentation updates to <doc-updates at sleuthkit dot org>
+
+.SH EXAMPLES
+To compare the directories in image.dd to those in directory:
+
+	# tsk_comparedir ./image.dd ./directory
+
+
+.SH AUTHOR
+Brian Carrier <carrier at sleuthkit dot org>
+
+Send documentation updates to <doc-updates at sleuthkit dot org>
diff --git a/man/tsk_gettimes.1 b/man/tsk_gettimes.1
index a015d15..eb831cd 100644
--- a/man/tsk_gettimes.1
+++ b/man/tsk_gettimes.1
@@ -1,62 +1,62 @@
-.TH TSK_GETTIMES 1 
-.SH NAME
-tsk_gettimes - Collect MAC times from a disk image into a body file.
-.SH SYNOPSIS
+.TH TSK_GETTIMES 1 
+.SH NAME
+tsk_gettimes - Collect MAC times from a disk image into a body file.
+.SH SYNOPSIS
 .B tsk_gettimes [-vV] [ -f
 .I fstype
-.B ] [ -i
-.I imgtype
-.B ] [ -b
-.I dev_sector_size
-.B ] [ -z
-.I zone
-.B ] [ -s
-.I seconds
-.B ] 
-.I image [images]
-.SH DESCRIPTION
-.B tsk_gettimes
-examines each of the file systems in a disk image and returns the data about them in the MACtime body format (the same as running 'fls -m' on each file system).  The output of this can be used as input to mactime to make a timeline of file activity. The data is printed to STDOUT, which can then be redirected to a file.
-
-The arguments are as follows:
-.IP -v
-verbose output to stderr
-.IP -V
-Print version
+.B ] [ -i
+.I imgtype
+.B ] [ -b
+.I dev_sector_size
+.B ] [ -z
+.I zone
+.B ] [ -s
+.I seconds
+.B ] 
+.I image [images]
+.SH DESCRIPTION
+.B tsk_gettimes
+examines each of the file systems in a disk image and returns the data about them in the MACtime body format (the same as running 'fls -m' on each file system).  The output of this can be used as input to mactime to make a timeline of file activity. The data is printed to STDOUT, which can then be redirected to a file.
+
+The arguments are as follows:
+.IP -v
+verbose output to stderr
+.IP -V
+Print version
 .IP "-f fstype"
 Specify the file system type.
 Use '\-f list' to list the supported file system types.
 If not given, autodetection methods are used.
-.IP "-i imgtype"
+.IP "-i imgtype"
 The format of the image file, such as raw.
 Use '\-i list' to list the supported types.
-If not given, autodetection methods are used.
-.IP "-b dev_sector_size"
-The size (in bytes) of the device sectors.
-If not given, autodetection methods are used.  
-.IP "-o sector_offset"
-Sector offset for a volume to recover (recovers only that volume)
-If not given, will attempt to recover all volumes in image and save them
-to different folders. 
-.IP "-s seconds"
-The time skew of the original system in seconds.  For example, if the
-original system was 100 seconds slow, this value would be \-100.  
-.IP "-z zone"
-The ASCII string of the time zone of the original system.  For
-example, EST or GMT.  These strings must be defined by your operating
-system and may vary.
+If not given, autodetection methods are used.
+.IP "-b dev_sector_size"
+The size (in bytes) of the device sectors.
+If not given, autodetection methods are used.  
+.IP "-o sector_offset"
+Sector offset for a volume to recover (recovers only that volume)
+If not given, will attempt to recover all volumes in image and save them
+to different folders. 
+.IP "-s seconds"
+The time skew of the original system in seconds.  For example, if the
+original system was 100 seconds slow, this value would be \-100.  
+.IP "-z zone"
+The ASCII string of the time zone of the original system.  For
+example, EST or GMT.  These strings must be defined by your operating
+system and may vary.
 .IP "image [images]"
 The disk or partition image to read, whose format is given with '\-i'.
 Multiple image file names can be given if the image is split into multiple segments.
 If only one image file is given, and its name is the first in a sequence (e.g., as indicated by ending in '.001'), subsequent image segments will be included automatically.
-
-.SH EXAMPLES
-To collect data about image image.dd:
-
-	# tsk_gettimes ./image.dd > body.txt
-
-.SH AUTHOR
-Brian Carrier <carrier at sleuthkit dot org>
-
-Send documentation updates to <doc-updates at sleuthkit dot org>
-
+
+.SH EXAMPLES
+To collect data about image image.dd:
+
+	# tsk_gettimes ./image.dd > body.txt
+
+.SH AUTHOR
+Brian Carrier <carrier at sleuthkit dot org>
+
+Send documentation updates to <doc-updates at sleuthkit dot org>
+
diff --git a/man/tsk_loaddb.1 b/man/tsk_loaddb.1
index 879d62d..d8f610a 100644
--- a/man/tsk_loaddb.1
+++ b/man/tsk_loaddb.1
@@ -1,57 +1,57 @@
-.TH TSK_LOADDB 1 
-.SH NAME
-tsk_loaddb - populate a SQLite database with metadata from a disk image
-.SH SYNOPSIS
-.B tsk_loaddb [-ahkvV] [ -i
-.I imgtype
-.B ] [ -b
-.I dev_sector_size
-.B ] [ -i
-.I imgtype
-.B ] [ -d
-.I database
-.B ]
-.I image [images]
-.SH DESCRIPTION
-.B tsk_loaddb
-loads disk information from 
-.I image
-to a SQLite database.  This database can then be used by tools in other languages for analysis. By default, the database is stored in the same directory as the image with ".db" appended to the name or the database name can be specified with '-d'. 
-
-The arguments are as follows:
-.IP "-a"
-Adds image to an existing database instead of creating a new one.  Requires that -d be also specified.
-.IP "-d database"
-Path for the database (default is the same directory as the image with name derived from image name
-.IP -v
-verbose output to stderr
-.IP -V
-Print version
-.IP -k
-Don't create block data table.  This table maps each block to the file that
-allocated it.  This option will make this program run faster.
-.IP -h
-Calculate MD5 hash value for each file and store it in table.  This option
-will make the program run slower. 
-.IP "-i imgtype"
+.TH TSK_LOADDB 1 
+.SH NAME
+tsk_loaddb - populate a SQLite database with metadata from a disk image
+.SH SYNOPSIS
+.B tsk_loaddb [-ahkvV] [ -i
+.I imgtype
+.B ] [ -b
+.I dev_sector_size
+.B ] [ -i
+.I imgtype
+.B ] [ -d
+.I database
+.B ]
+.I image [images]
+.SH DESCRIPTION
+.B tsk_loaddb
+loads disk information from 
+.I image
+to a SQLite database.  This database can then be used by tools in other languages for analysis. By default, the database is stored in the same directory as the image with ".db" appended to the name or the database name can be specified with '-d'. 
+
+The arguments are as follows:
+.IP "-a"
+Adds image to an existing database instead of creating a new one.  Requires that -d be also specified.
+.IP "-d database"
+Path for the database (default is the same directory as the image with name derived from image name
+.IP -v
+verbose output to stderr
+.IP -V
+Print version
+.IP -k
+Don't create block data table.  This table maps each block to the file that
+allocated it.  This option will make this program run faster.
+.IP -h
+Calculate MD5 hash value for each file and store it in table.  This option
+will make the program run slower. 
+.IP "-i imgtype"
 The format of the image file, such as raw.
 Use '\-i list' to list the supported types.
-If not given, autodetection methods are used.
-.IP "-b dev_sector_size"
-The size (in bytes) of the device sectors.
-If not given, autodetection methods are used.
+If not given, autodetection methods are used.
+.IP "-b dev_sector_size"
+The size (in bytes) of the device sectors.
+If not given, autodetection methods are used.
 .IP "image [images]"
 The disk or partition image to read, whose format is given with '\-i'.
 Multiple image file names can be given if the image is split into multiple segments.
 If only one image file is given, and its name is the first in a sequence (e.g., as indicated by ending in '.001'), subsequent image segments will be included automatically.
-
-.SH EXAMPLES
-To load image data from image.dd to image.dd.db:
-
-	# tsk_loaddb ./image.dd
-
-
-.SH AUTHOR
-Brian Carrier <carrier at sleuthkit dot org>
-
-Send documentation updates to <doc-updates at sleuthkit dot org>
+
+.SH EXAMPLES
+To load image data from image.dd to image.dd.db:
+
+	# tsk_loaddb ./image.dd
+
+
+.SH AUTHOR
+Brian Carrier <carrier at sleuthkit dot org>
+
+Send documentation updates to <doc-updates at sleuthkit dot org>
diff --git a/man/tsk_recover.1 b/man/tsk_recover.1
index c1756f5..4ab9585 100644
--- a/man/tsk_recover.1
+++ b/man/tsk_recover.1
@@ -1,67 +1,67 @@
-.TH TSK_RECOVER 1 
-.SH NAME
-tsk_recover - Export files from an image into a local directory
-.SH SYNOPSIS
+.TH TSK_RECOVER 1 
+.SH NAME
+tsk_recover - Export files from an image into a local directory
+.SH SYNOPSIS
 .B tsk_recover [-vVae] [ -f
 .I fstype
-.B ] [ -i
-.I imgtype
-.B ] [ -b
-.I dev_sector_size
-.B ] [ -o
-.I sector_offset
-.B ] [ -d  
-.I dir_inum
-.B ]
-.I  image [images] output_dir 
-.SH DESCRIPTION
-.B tsk_recover
-recovers files to the
-.I output_dir
-from the 
-.I image.
-By default recovers only unallocated files. With flags, it will export all files.  
-
-The arguments are as follows:
-.IP -v
-verbose output to stderr
-.IP -V
-Print version
-.IP -a
-Recover allocated files only
-.IP -e
-Recover all files (allocated and unallocated)
+.B ] [ -i
+.I imgtype
+.B ] [ -b
+.I dev_sector_size
+.B ] [ -o
+.I sector_offset
+.B ] [ -d  
+.I dir_inum
+.B ]
+.I  image [images] output_dir 
+.SH DESCRIPTION
+.B tsk_recover
+recovers files to the
+.I output_dir
+from the 
+.I image.
+By default recovers only unallocated files. With flags, it will export all files.  
+
+The arguments are as follows:
+.IP -v
+verbose output to stderr
+.IP -V
+Print version
+.IP -a
+Recover allocated files only
+.IP -e
+Recover all files (allocated and unallocated)
 .IP "-f fstype"
 Specify the file system type.
 Use '\-f list' to list the supported file system types.
 If not given, autodetection methods are used.
-.IP "-i imgtype"
+.IP "-i imgtype"
 The format of the image file, such as raw.
 Use '\-i list' to list the supported types.
-If not given, autodetection methods are used.
-.IP "-b dev_sector_size"
-The size (in bytes) of the device sectors.
-If not given, autodetection methods are used.  
-.IP "-o sector_offset"
-Sector offset for a volume to recover (recovers only that volume)
-If not given, will attempt to recover all volumes in image and save them
-to different folders. 
-.IP "-d dir_inum"
-Directory inum to recover from (must also specify a specific partition using -o or there must not be a volume system)
+If not given, autodetection methods are used.
+.IP "-b dev_sector_size"
+The size (in bytes) of the device sectors.
+If not given, autodetection methods are used.  
+.IP "-o sector_offset"
+Sector offset for a volume to recover (recovers only that volume)
+If not given, will attempt to recover all volumes in image and save them
+to different folders. 
+.IP "-d dir_inum"
+Directory inum to recover from (must also specify a specific partition using -o or there must not be a volume system)
 .IP "image [images]"
 The disk or partition image to read, whose format is given with '\-i'.
 Multiple image file names can be given if the image is split into multiple segments.
 If only one image file is given, and its name is the first in a sequence (e.g., as indicated by ending in '.001'), subsequent image segments will be included automatically.
 .IP output_dir
 The directory in which to save recovered files.
-
-.SH EXAMPLES
-To recover only unallocated files from image.dd to the recovered directory:
-
-	# tsk_recover ./image.dd ./recovered
-
-.SH AUTHOR
-Brian Carrier <carrier at sleuthkit dot org>
-
-Send documentation updates to <doc-updates at sleuthkit dot org>
-
+
+.SH EXAMPLES
+To recover only unallocated files from image.dd to the recovered directory:
+
+	# tsk_recover ./image.dd ./recovered
+
+.SH AUTHOR
+Brian Carrier <carrier at sleuthkit dot org>
+
+Send documentation updates to <doc-updates at sleuthkit dot org>
+
diff --git a/packages/sleuthkit.spec b/packages/sleuthkit.spec
index cc0ba0e..a384ea6 100644
--- a/packages/sleuthkit.spec
+++ b/packages/sleuthkit.spec
@@ -1,5 +1,5 @@
 Name:		sleuthkit	
-Version:	4.1.0
+Version:	4.1.2
 Release:	1%{?dist}
 Summary:	The Sleuth Kit (TSK) is a library and collection of command line tools that allow you to investigate volume and file system data.	
 
diff --git a/tools/autotools/tsk_gettimes.cpp b/tools/autotools/tsk_gettimes.cpp
index de388a3..1f8f169 100644
--- a/tools/autotools/tsk_gettimes.cpp
+++ b/tools/autotools/tsk_gettimes.cpp
@@ -21,12 +21,13 @@ usage()
 {
     TFPRINTF(stderr,
         _TSK_T
-        ("usage: %s [-vV] [-i imgtype] [-b dev_sector_size] [-z zone] [-s seconds] image [image]\n"),
+        ("usage: %s [-vVm] [-i imgtype] [-b dev_sector_size] [-z zone] [-s seconds] image [image]\n"),
         progname);
     tsk_fprintf(stderr,
         "\t-i imgtype: The format of the image file (use '-i list' for supported types)\n");
     tsk_fprintf(stderr,
         "\t-b dev_sector_size: The size (in bytes) of the device sectors\n");
+	tsk_fprintf(stderr, "\t-m: Calculate MD5 hash in output (slow)\n");
     tsk_fprintf(stderr, "\t-v: verbose output to stderr\n");
     tsk_fprintf(stderr, "\t-V: Print version\n");
     tsk_fprintf(stderr,
@@ -42,6 +43,7 @@ usage()
 class TskGetTimes:public TskAuto {
 public:
     TskGetTimes(int32_t);
+	TskGetTimes(int32_t, bool);
     virtual TSK_RETVAL_ENUM processFile(TSK_FS_FILE * fs_file, const char *path);
     virtual TSK_FILTER_ENUM filterVol(const TSK_VS_PART_INFO * vs_part);
     virtual TSK_FILTER_ENUM filterFs(TSK_FS_INFO * fs_info);
@@ -50,6 +52,7 @@ public:
 private:
     int m_curVolAddr;
     int32_t m_secSkew;
+	bool m_compute_hash;
 };
 
 
@@ -57,6 +60,14 @@ TskGetTimes::TskGetTimes(int32_t a_secSkew)
 {
     m_curVolAddr = -1;
     m_secSkew = a_secSkew;
+	m_compute_hash = false;
+}
+
+TskGetTimes::TskGetTimes(int32_t a_secSkew, bool a_compute_hash)
+{
+    m_curVolAddr = -1;
+    m_secSkew = a_secSkew;
+	m_compute_hash = a_compute_hash;
 }
 
 // Print errors as they are encountered
@@ -82,10 +93,16 @@ TskGetTimes::filterFs(TSK_FS_INFO * fs_info)
     else 
         volName[0] = '\0';
 
-    if (tsk_fs_fls(fs_info, (TSK_FS_FLS_FLAG_ENUM)(TSK_FS_FLS_MAC | TSK_FS_FLS_DIR | TSK_FS_FLS_FILE | TSK_FS_FLS_FULL),
-       fs_info->root_inum, (TSK_FS_DIR_WALK_FLAG_ENUM)(TSK_FS_DIR_WALK_FLAG_ALLOC | TSK_FS_DIR_WALK_FLAG_UNALLOC | TSK_FS_DIR_WALK_FLAG_RECURSE), volName, m_secSkew)) {
-        
-    }
+	TSK_FS_FLS_FLAG_ENUM fls_flags = (TSK_FS_FLS_FLAG_ENUM)(TSK_FS_FLS_MAC | TSK_FS_FLS_DIR | TSK_FS_FLS_FILE | TSK_FS_FLS_FULL);
+	if(m_compute_hash){
+		fls_flags = (TSK_FS_FLS_FLAG_ENUM)(fls_flags | TSK_FS_FLS_HASH);
+	}
+
+	if (tsk_fs_fls(fs_info, (TSK_FS_FLS_FLAG_ENUM)(fls_flags),
+		fs_info->root_inum, (TSK_FS_DIR_WALK_FLAG_ENUM)(TSK_FS_DIR_WALK_FLAG_ALLOC | TSK_FS_DIR_WALK_FLAG_UNALLOC | TSK_FS_DIR_WALK_FLAG_RECURSE), volName, m_secSkew)) {
+	}
+
+
     return TSK_FILTER_SKIP;
 }
 
@@ -107,6 +124,7 @@ main(int argc, char **argv1)
     unsigned int ssize = 0;
     TSK_TCHAR *cp;
     int32_t sec_skew = 0;
+	bool do_hash = false;
 
 #ifdef TSK_WIN32
     // On Windows, get the wide arguments (mingw doesn't support wmain)
@@ -122,7 +140,7 @@ main(int argc, char **argv1)
     progname = argv[0];
     setlocale(LC_ALL, "");
 
-    while ((ch = GETOPT(argc, argv, _TSK_T("b:i:s:vVz:"))) > 0) {
+    while ((ch = GETOPT(argc, argv, _TSK_T("b:i:s:mvVz:"))) > 0) {
         switch (ch) {
         case _TSK_T('?'):
         default:
@@ -161,6 +179,9 @@ main(int argc, char **argv1)
             sec_skew = TATOI(OPTARG);
             break;
 
+        case _TSK_T('m'):
+            do_hash = true;
+            break;
 
         case _TSK_T('v'):
             tsk_verbose++;
@@ -194,7 +215,7 @@ main(int argc, char **argv1)
         usage();
     }
 
-    TskGetTimes tskGetTimes(sec_skew);
+    TskGetTimes tskGetTimes(sec_skew, do_hash);
     if (tskGetTimes.openImage(argc - OPTIND, &argv[OPTIND], imgtype,
             ssize)) {
         tsk_error_print(stderr);
diff --git a/tools/fiwalk/plugins/jpeg_extract.java b/tools/fiwalk/plugins/jpeg_extract.java
index 587b7c6..d17178e 100644
--- a/tools/fiwalk/plugins/jpeg_extract.java
+++ b/tools/fiwalk/plugins/jpeg_extract.java
@@ -46,7 +46,7 @@ class jpeg_extract {
 
     public static void main(String[] args){
 	//System.out.print(process(args[0]));
-        if (args.length >= 1){
+        if (args.length >= 1){
             System.out.print(process(args[0]));
         }else{
              System.out.println("Usage: jpeg_extract filename.***, legal extensions are .jpeg, .jpg");
diff --git a/tools/fiwalk/src/dfxml.cpp b/tools/fiwalk/src/dfxml.cpp
index ca1efb3..7f80e12 100644
--- a/tools/fiwalk/src/dfxml.cpp
+++ b/tools/fiwalk/src/dfxml.cpp
@@ -35,6 +35,10 @@ using namespace std;
 #include <fcntl.h>
 #include <stack>
 
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
 static const char *xml_header = "<?xml version='1.0' encoding='UTF-8'?>\n";
 
 // Implementation of mkstemp for windows found on pan-devel mailing
@@ -371,6 +375,7 @@ void xml::add_DFXML_execution_environment(const std::string &command_line)
 
 void xml::add_rusage()
 {
+#ifdef HAVE_SYS_RESOURCE_H
 #ifdef HAVE_GETRUSAGE
     struct rusage ru;
     memset(&ru,0,sizeof(ru));
@@ -400,6 +405,7 @@ void xml::add_rusage()
 	pop();
     }
 #endif
+#endif
 }
 
 
diff --git a/tools/fiwalk/src/fiwalk.cpp b/tools/fiwalk/src/fiwalk.cpp
index 1ca8a21..8bfba32 100644
--- a/tools/fiwalk/src/fiwalk.cpp
+++ b/tools/fiwalk/src/fiwalk.cpp
@@ -52,6 +52,11 @@
 //#define mkdir _mkdir
 #endif
 
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
 /* Output Devices */
 class arff *a = 0;			// ARFF generator
 class xml  *x = 0;
@@ -245,6 +250,12 @@ void partition_info(const string &name,long i)
     partition_info(name,buf,fw_empty);
 }
 
+void partition_info(const string &name, const struct timeval &ts)
+{
+    char buf[64];
+    sprintf(buf, "%d.%06d",(int)ts.tv_sec, (int)ts.tv_usec);
+    partition_info(name,buf,fw_empty);
+}
 
 /****************************************************************
  * These file_info(name,value) are called for each extracted attribute
@@ -466,7 +477,10 @@ int main(int argc, char * const *argv1)
     bool opt_zap = false;
     u_int sector_size=512;			// defaults to 512; may be changed by AFF
 
-    int t0 = time(0);
+    struct timeval tv0;
+    struct timeval tv1;
+    gettimeofday(&tv0,0);
+
     TSK_TCHAR * const *argv;
 
 #ifdef TSK_WIN32
@@ -679,11 +693,12 @@ int main(int argc, char * const *argv1)
     /* output per-run metadata for XML output */
     if(x){
 	/* Output Dublin Core information */
-	x->push("dfxml","version='1.0'");
-	x->push("metadata",
+	x->push("dfxml",
 		"\n  xmlns='http://www.forensicswiki.org/wiki/Category:Digital_Forensics_XML'"
-		"\n  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
-		"\n  xmlns:dc='http://purl.org/dc/elements/1.1/'" );
+		"\n  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'"
+		"\n  xmlns:dc='http://purl.org/dc/elements/1.1/'"
+		"\n  version='1.0'" );
+	x->push("metadata", "");
 	x->xmlout("dc:type","Disk Image",fw_empty,false);
 	x->pop();
 	    
@@ -728,26 +743,42 @@ int main(int argc, char * const *argv1)
     }
 #endif
 
-    int t1 = time(0);
-    comment("clock: %d",t1-t0);
+    /* Calculate time elapsed (reported as a comment and with rusage) */
+    struct timeval tv;
+    char tvbuf[64];
+    gettimeofday(&tv1,0);
+    tv.tv_sec = tv1.tv_sec - tv0.tv_sec;
+    if(tv1.tv_usec > tv0.tv_usec){
+        tv.tv_usec = tv1.tv_usec - tv0.tv_usec;
+    } else {
+        tv.tv_sec--;
+        tv.tv_usec = (tv1.tv_usec+1000000) - tv0.tv_usec;
+    }
+    sprintf(tvbuf, "%d.%06d",(int)tv.tv_sec, (int)tv.tv_usec);
+
+    comment("clock: %s",tvbuf);
+
+#ifdef HAVE_SYS_RESOURCE_H
 #ifdef HAVE_GETRUSAGE
     /* Print usage information */
     struct rusage ru;
     memset(&ru,0,sizeof(ru));
     if(getrusage(RUSAGE_SELF,&ru)==0){
-	if(x) x->push("runstats");
-	partition_info("user_seconds",ru.ru_utime.tv_sec);
-	partition_info("system_seconds",ru.ru_stime.tv_sec);
+	if(x) x->push("rusage");
+	partition_info("utime",ru.ru_utime);
+	partition_info("stime",ru.ru_stime);
 	partition_info("maxrss",ru.ru_maxrss);
-	partition_info("reclaims",ru.ru_minflt);
-	partition_info("faults",ru.ru_majflt);
-	partition_info("swaps",ru.ru_nswap);
-	partition_info("inputs",ru.ru_inblock);
-	partition_info("outputs",ru.ru_oublock);
-	partition_info("stop_time",cstr(mytime()));
+	partition_info("minflt",ru.ru_minflt);
+	partition_info("majflt",ru.ru_majflt);
+	partition_info("nswap",ru.ru_nswap);
+	partition_info("inblock",ru.ru_inblock);
+	partition_info("oublock",ru.ru_oublock);
+	partition_info("clocktime",tv);
+	comment("stop_time: %s",cstr(mytime()));
 	if(x) x->pop();
     }
 #endif
+#endif
 
     // *** Added <finished time="(time_t)" duration="<seconds>" />
 
diff --git a/tools/fiwalk/src/fiwalk.h b/tools/fiwalk/src/fiwalk.h
index d2f601a..4ddd593 100644
--- a/tools/fiwalk/src/fiwalk.h
+++ b/tools/fiwalk/src/fiwalk.h
@@ -154,6 +154,7 @@ extern FILE  *t;				// text output or body file enabled
 void partition_info(const string &name,const string &value,const string &attribute);
 void partition_info(const string &name,const string &value);
 void partition_info(const string &name,long i);
+void partition_info(const string &name, const struct timeval &ts);
 
 
 
diff --git a/tools/fiwalk/src/hexbuf.c b/tools/fiwalk/src/hexbuf.c
index ee60e48..07df7be 100644
--- a/tools/fiwalk/src/hexbuf.c
+++ b/tools/fiwalk/src/hexbuf.c
@@ -1,41 +1,41 @@
-/**
- * hexbuf()
- * Turns a binary buffer into a hexdecimal string.
- */
-
-#include "tsk/tsk_config.h"
-#include "hexbuf.h"
-#include <stdio.h>
-
-#ifdef _MSC_VER
-#define _CRT_SECURE_NO_WARNINGS
-#endif
-
-const char *hexbuf(char *dst,int dst_len,const unsigned char *bin,int bytes,int flag)
-{
-    int charcount = 0;
-    const char *start = dst;		// remember where the start of the string is
-    const char *fmt = (flag & HEXBUF_UPPERCASE) ? "%02X" : "%02x";
-
-    *dst = 0;				// begin with null termination
-    while(bytes>0 && dst_len > 3){
-	int add_spaces = 0;
-
-	sprintf(dst,fmt,*bin); // convert the next byte
-	dst += 2;
-	bin += 1;
-	dst_len -= 2;
-	bytes--;
-	charcount++;			// how many characters
-	
-	if(flag & HEXBUF_SPACE2) add_spaces = 1;
-	if((flag & HEXBUF_SPACE4) && charcount%2==0){
-	    *dst++ = ' ';
-	    *dst   = '\000';
-	    dst_len -= 1;
-	}
-    }
-    return start;			// return the start
-}
-
-
+/**
+ * hexbuf()
+ * Turns a binary buffer into a hexdecimal string.
+ */
+
+#include "tsk/tsk_config.h"
+#include "hexbuf.h"
+#include <stdio.h>
+
+#ifdef _MSC_VER
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+const char *hexbuf(char *dst,int dst_len,const unsigned char *bin,int bytes,int flag)
+{
+    int charcount = 0;
+    const char *start = dst;		// remember where the start of the string is
+    const char *fmt = (flag & HEXBUF_UPPERCASE) ? "%02X" : "%02x";
+
+    *dst = 0;				// begin with null termination
+    while(bytes>0 && dst_len > 3){
+	int add_spaces = 0;
+
+	sprintf(dst,fmt,*bin); // convert the next byte
+	dst += 2;
+	bin += 1;
+	dst_len -= 2;
+	bytes--;
+	charcount++;			// how many characters
+	
+	if(flag & HEXBUF_SPACE2) add_spaces = 1;
+	if((flag & HEXBUF_SPACE4) && charcount%2==0){
+	    *dst++ = ' ';
+	    *dst   = '\000';
+	    dst_len -= 1;
+	}
+    }
+    return start;			// return the start
+}
+
+
diff --git a/tools/fiwalk/src/utils.c b/tools/fiwalk/src/utils.c
index 681ee8c..3315138 100644
--- a/tools/fiwalk/src/utils.c
+++ b/tools/fiwalk/src/utils.c
@@ -1,114 +1,114 @@
-/**
- * A collection of utility functions that are useful.
- */
-
-// Just for this module
-#define _FILE_OFFSET_BITS 64
-
-
-/* required per C++ standard */
-#ifndef __STDC_FORMAT_MACROS
-#define __STDC_FORMAT_MACROS
-#endif
-
-#include "tsk/tsk_config.h"
-#include "utils.h"
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include <stdio.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <assert.h>
-
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <string.h>
-
-#ifndef HAVE_ERR
-#include <stdarg.h>
-void err(int eval,const char *fmt,...)
-{
-  va_list ap;
-  va_start(ap,fmt);
-  vfprintf(stderr,fmt,ap);
-  va_end(ap);
-  fprintf(stderr,": %s\n",strerror(errno));
-  exit(eval);
-}
-#endif
-
-#ifndef HAVE_ERRX
-#include <stdarg.h>
-void errx(int eval,const char *fmt,...)
-{
-  va_list ap;
-  va_start(ap,fmt);
-  vfprintf(stderr,fmt,ap);
-  fprintf(stderr,"%s\n",strerror(errno));
-  va_end(ap);
-  exit(eval);
-}
-#endif
-
-#ifndef HAVE_WARN
-#include <stdarg.h>
-void	warn(const char *fmt, ...)
-{
-    va_list args;
-    va_start(args,fmt);
-    vfprintf(stderr,fmt, args);
-    fprintf(stderr,": %s\n",strerror(errno));
-}
-#endif
-
-#ifndef HAVE_WARNX
-#include <stdarg.h>
-void warnx(const char *fmt,...)
-{
-  va_list ap;
-  va_start(ap,fmt);
-  vfprintf(stderr,fmt,ap);
-  va_end(ap);
-}
-#endif
-
-#ifdef _MSC_VER
-#define inline
-#include <io.h>
-#include <stdio.h>
-//pread implementation from https://gist.github.com/1258986
-int pread(unsigned int fd, char *buf, size_t count, int offset)
-{
-if (_lseek(fd, offset, SEEK_SET) != offset) {
-return -1;
-}
-return read(fd, buf, count);
-}
-
-#endif
-
-#ifndef HAVE_ISHEXNUMBER
-int ishexnumber(int c);
-inline int ishexnumber(int c)
-{
-    switch(c){
-    case '0':         case '1':         case '2':         case '3':         case '4':
-    case '5':         case '6':         case '7':         case '8':         case '9':
-    case 'A':         case 'B':         case 'C':         case 'D':         case 'E':
-    case 'F':         case 'a':         case 'b':         case 'c':         case 'd':
-    case 'e':         case 'f':
-	return 1;
-    }
-    return 0;
-}
-#endif
-
-
+/**
+ * A collection of utility functions that are useful.
+ */
+
+// Just for this module
+#define _FILE_OFFSET_BITS 64
+
+
+/* required per C++ standard */
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS
+#endif
+
+#include "tsk/tsk_config.h"
+#include "utils.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <assert.h>
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <string.h>
+
+#ifndef HAVE_ERR
+#include <stdarg.h>
+void err(int eval,const char *fmt,...)
+{
+  va_list ap;
+  va_start(ap,fmt);
+  vfprintf(stderr,fmt,ap);
+  va_end(ap);
+  fprintf(stderr,": %s\n",strerror(errno));
+  exit(eval);
+}
+#endif
+
+#ifndef HAVE_ERRX
+#include <stdarg.h>
+void errx(int eval,const char *fmt,...)
+{
+  va_list ap;
+  va_start(ap,fmt);
+  vfprintf(stderr,fmt,ap);
+  fprintf(stderr,"%s\n",strerror(errno));
+  va_end(ap);
+  exit(eval);
+}
+#endif
+
+#ifndef HAVE_WARN
+#include <stdarg.h>
+void	warn(const char *fmt, ...)
+{
+    va_list args;
+    va_start(args,fmt);
+    vfprintf(stderr,fmt, args);
+    fprintf(stderr,": %s\n",strerror(errno));
+}
+#endif
+
+#ifndef HAVE_WARNX
+#include <stdarg.h>
+void warnx(const char *fmt,...)
+{
+  va_list ap;
+  va_start(ap,fmt);
+  vfprintf(stderr,fmt,ap);
+  va_end(ap);
+}
+#endif
+
+#ifdef _MSC_VER
+#define inline
+#include <io.h>
+#include <stdio.h>
+//pread implementation from https://gist.github.com/1258986
+int pread(unsigned int fd, char *buf, size_t count, int offset)
+{
+if (_lseek(fd, offset, SEEK_SET) != offset) {
+return -1;
+}
+return read(fd, buf, count);
+}
+
+#endif
+
+#ifndef HAVE_ISHEXNUMBER
+int ishexnumber(int c);
+inline int ishexnumber(int c)
+{
+    switch(c){
+    case '0':         case '1':         case '2':         case '3':         case '4':
+    case '5':         case '6':         case '7':         case '8':         case '9':
+    case 'A':         case 'B':         case 'C':         case 'D':         case 'E':
+    case 'F':         case 'a':         case 'b':         case 'c':         case 'd':
+    case 'e':         case 'f':
+	return 1;
+    }
+    return 0;
+}
+#endif
+
+
diff --git a/tools/fiwalk/src/utils.h b/tools/fiwalk/src/utils.h
index 394f773..1d37b92 100644
--- a/tools/fiwalk/src/utils.h
+++ b/tools/fiwalk/src/utils.h
@@ -1,54 +1,54 @@
-/****************************************************************
- *** utils.h
- *** 
- *** To use utils.c/utils.h, be sure this is in your configure.ac file:
- ***
-AC_CHECK_HEADERS([err.h err.h sys/mman.h sys/resource.h unistd.h])
-AC_CHECK_FUNCS([ishexnumber unistd.h err errx warn warnx pread _lseeki64 ])
-
- ***
- ****************************************************************/
-
-
-
-#ifndef UTILS_H
-#define UTILS_H
-
-#include <sys/types.h>
-
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
-#ifndef __BEGIN_DECLS
-#if defined(__cplusplus)
-#define __BEGIN_DECLS   extern "C" {
-#define __END_DECLS     }
-#else
-#define __BEGIN_DECLS
-#define __END_DECLS
-#endif
-#endif
-
-__BEGIN_DECLS
-
-#ifdef HAVE_ERR_H
-#include <err.h>
-#else
-    #ifdef __GNUC__
-    void err(int eval,const char *fmt,...) __attribute__((format(printf, 2, 0))) __attribute__ ((__noreturn__));
-    void errx(int eval,const char *fmt,...) __attribute__((format(printf, 2, 0))) __attribute__ ((__noreturn__));
-    void warn(const char *fmt, ...) __attribute__((format(printf, 1, 0)));
-    void warnx(const char *fmt,...) __attribute__((format(printf, 1, 0)));
-    #else
-    void err(int eval,const char *fmt,...);
-    void errx(int eval,const char *fmt,...);
-    void warn(const char *fmt, ...);
-    void warnx(const char *fmt,...);
-    #endif
-#endif
-
-
-__END_DECLS
-
-#endif
+/****************************************************************
+ *** utils.h
+ *** 
+ *** To use utils.c/utils.h, be sure this is in your configure.ac file:
+ ***
+AC_CHECK_HEADERS([err.h err.h sys/mman.h unistd.h])
+AC_CHECK_FUNCS([ishexnumber unistd.h err errx warn warnx pread _lseeki64 ])
+
+ ***
+ ****************************************************************/
+
+
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <sys/types.h>
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#ifndef __BEGIN_DECLS
+#if defined(__cplusplus)
+#define __BEGIN_DECLS   extern "C" {
+#define __END_DECLS     }
+#else
+#define __BEGIN_DECLS
+#define __END_DECLS
+#endif
+#endif
+
+__BEGIN_DECLS
+
+#ifdef HAVE_ERR_H
+#include <err.h>
+#else
+    #ifdef __GNUC__
+    void err(int eval,const char *fmt,...) __attribute__((format(printf, 2, 0))) __attribute__ ((__noreturn__));
+    void errx(int eval,const char *fmt,...) __attribute__((format(printf, 2, 0))) __attribute__ ((__noreturn__));
+    void warn(const char *fmt, ...) __attribute__((format(printf, 1, 0)));
+    void warnx(const char *fmt,...) __attribute__((format(printf, 1, 0)));
+    #else
+    void err(int eval,const char *fmt,...);
+    void errx(int eval,const char *fmt,...);
+    void warn(const char *fmt, ...);
+    void warnx(const char *fmt,...);
+    #endif
+#endif
+
+
+__END_DECLS
+
+#endif
diff --git a/tools/fstools/ils.cpp b/tools/fstools/ils.cpp
index 8b45224..db44c47 100644
--- a/tools/fstools/ils.cpp
+++ b/tools/fstools/ils.cpp
@@ -48,8 +48,8 @@ usage()
     tsk_fprintf(stderr, "\t-A: Unallocated inodes\n");
     tsk_fprintf(stderr, "\t-l: Linked inodes\n");
     tsk_fprintf(stderr, "\t-L: Unlinked inodes\n");
-    tsk_fprintf(stderr, "\t-z: Unused inodes (ctime is 0)\n");
-    tsk_fprintf(stderr, "\t-Z: Used inodes (ctime is not 0)\n");
+    tsk_fprintf(stderr, "\t-z: Unused inodes\n");
+    tsk_fprintf(stderr, "\t-Z: Used inodes\n");
     tsk_fprintf(stderr,
         "\t-i imgtype: The format of the image file (use '-i list' for supported types)\n");
     tsk_fprintf(stderr,
diff --git a/tools/srchtools/srch_strings.c b/tools/srchtools/srch_strings.c
index 2028835..35fd29c 100644
--- a/tools/srchtools/srch_strings.c
+++ b/tools/srchtools/srch_strings.c
@@ -1,6 +1,6 @@
-/* From binutils-2.15 
+/* From binutils-2.15
  * removed getopt_long stuff
- *  
+ *
  */
 
 /* strings -- print the strings of printable characters in files
@@ -98,7 +98,7 @@
 
 /* The following were taken from other files in binutils */
 // from include/libiberty.h
-enum { 
+enum {
   /* In C99 */
   _sch_isblank  = 0x0001,       /* space \t */
   _sch_iscntrl  = 0x0002,       /* nonprinting characters */
@@ -142,7 +142,7 @@ enum {
 #define vs _sch_isvsp
 #define xd _sch_isxdigit
 
-/* Masks.  */ 
+/* Masks.  */
 #define L  (const unsigned short) (lo|is   |pr) /* lower case letter */
 #define XL (const unsigned short) (lo|is|xd|pr) /* lowercase hex digit */
 #define U  (const unsigned short) (up|is   |pr) /* upper case letter */
@@ -283,7 +283,7 @@ main (int argc, char **argv)
 	case 'n':
 	  string_min = integer_arg (optarg);
 	  if (string_min < 1) {
-	    fprintf (stderr, "invalid number %s", optarg);
+	    fprintf (stderr, "invalid number %s\n", optarg);
 	  }
 	  break;
 
@@ -401,13 +401,13 @@ get_file_size (const char * file_name)
   if (stat (file_name, &statbuf) < 0)
     {
       if (errno == ENOENT)
-        fprintf (stderr, "'%s': No such file", file_name);
+        fprintf (stderr, "'%s': No such file\n", file_name);
       else
-        fprintf (stderr, "Warning: could not locate '%s'.  reason: %s",
+        fprintf (stderr, "Warning: could not locate '%s'.  reason: %s\n",
                    file_name, strerror (errno));
     }
   else if (! S_ISREG (statbuf.st_mode)) {
-    fprintf(stderr, "Warning: '%s' is not an ordinary file", file_name);
+    fprintf(stderr, "Warning: '%s' is not an ordinary file\n", file_name);
   }
   else
     return statbuf.st_size;
@@ -600,7 +600,7 @@ print_strings (const char *filename, FILE *stream, uint64_t address,
 }
 

 /* Parse string S as an integer, using decimal radix by default,
-   but allowing octal and hex numbers as in C.  
+   but allowing octal and hex numbers as in C.
 
    Return 0 on error
  */
@@ -642,7 +642,7 @@ integer_arg (char *s)
     p--;
 
   if (*p) {
-      fprintf(stderr, "invalid integer argument %s", s);
+      fprintf(stderr, "invalid integer argument %s\n", s);
       return 0;
   }
 
diff --git a/tools/vstools/mmls.cpp b/tools/vstools/mmls.cpp
index 412f191..ee71365 100644
--- a/tools/vstools/mmls.cpp
+++ b/tools/vstools/mmls.cpp
@@ -297,7 +297,6 @@ main(int argc, char **argv1)
         exit(1);
     }
 
-    tsk_vs_close(vs);
     if ((recurse) && (vs->vstype == TSK_VS_TYPE_DOS)) {
         int i;
         /* disable recursing incase we hit another DOS partition
@@ -305,15 +304,16 @@ main(int argc, char **argv1)
         recurse = 0;
 
         for (i = 0; i < recurse_cnt; i++) {
-            vs = tsk_vs_open(img, recurse_list[i], TSK_VS_TYPE_DETECT);
-            if (vs != NULL) {
+            TSK_VS_INFO *vs2;
+            vs2 = tsk_vs_open(img, recurse_list[i], TSK_VS_TYPE_DETECT);
+            if (vs2 != NULL) {
                 tsk_printf("\n\n");
-                print_header(vs);
-                if (tsk_vs_part_walk(vs, 0, vs->part_count - 1,
+                print_header(vs2);
+                if (tsk_vs_part_walk(vs2, 0, vs2->part_count - 1,
                         (TSK_VS_PART_FLAG_ENUM) flags, part_act, NULL)) {
                     tsk_error_reset();
                 }
-                tsk_vs_close(vs);
+                tsk_vs_close(vs2);
             }
             else {
                 /* Ignore error in this case and reset */
@@ -322,6 +322,7 @@ main(int argc, char **argv1)
         }
     }
 
+    tsk_vs_close(vs);
     tsk_img_close(img);
     exit(0);
 }
diff --git a/tsk/Makefile.am b/tsk/Makefile.am
index 1ec47e3..48dcd6a 100644
--- a/tsk/Makefile.am
+++ b/tsk/Makefile.am
@@ -8,6 +8,6 @@ libtsk_la_LIBADD = base/libtskbase.la img/libtskimg.la \
     vs/libtskvs.la fs/libtskfs.la hashdb/libtskhashdb.la \
     auto/libtskauto.la
 # current:revision:age
-libtsk_la_LDFLAGS = -version-info 10:0:0
+libtsk_la_LDFLAGS = -version-info 11:1:1
 
 EXTRA_DIST = tsk_tools_i.h docs/Doxyfile docs/*.dox docs/*.html
diff --git a/tsk/Makefile.in b/tsk/Makefile.in
index 7364f31..d8d6b57 100644
--- a/tsk/Makefile.in
+++ b/tsk/Makefile.in
@@ -303,7 +303,7 @@ libtsk_la_LIBADD = base/libtskbase.la img/libtskimg.la \
     auto/libtskauto.la
 
 # current:revision:age
-libtsk_la_LDFLAGS = -version-info 10:0:0
+libtsk_la_LDFLAGS = -version-info 11:1:1
 EXTRA_DIST = tsk_tools_i.h docs/Doxyfile docs/*.dox docs/*.html
 all: tsk_config.h
 	$(MAKE) $(AM_MAKEFLAGS) all-recursive
diff --git a/tsk/auto/auto.cpp b/tsk/auto/auto.cpp
index 6f9f4a1..15a8185 100644
--- a/tsk/auto/auto.cpp
+++ b/tsk/auto/auto.cpp
@@ -23,10 +23,12 @@ TskAuto::TskAuto()
 {
     m_img_info = NULL;
     m_tag = TSK_AUTO_TAG;
-    m_volFilterFlags = TSK_VS_PART_FLAG_ALLOC;
+    m_volFilterFlags = (TSK_VS_PART_FLAG_ENUM)(TSK_VS_PART_FLAG_ALLOC | TSK_VS_PART_FLAG_UNALLOC);
     m_fileFilterFlags = TSK_FS_DIR_WALK_FLAG_RECURSE;
     m_stopAllProcessing = false;
     m_internalOpen = false;
+    m_curVsPartValid = false;
+    m_curVsPartDescr = "";
 }
 
 
@@ -43,6 +45,7 @@ void TskAuto::setCurVsPart(const TSK_VS_PART_INFO *partInfo) {
     else
         m_curVsPartDescr = "";
     m_curVsPartFlag = partInfo->flags;
+    m_curVsPartValid = true;
 }
 
 std::string TskAuto::getCurVsPartDescr() const {
@@ -53,6 +56,10 @@ TSK_VS_PART_FLAG_ENUM TskAuto::getCurVsPartFlag() const {
     return m_curVsPartFlag;
 }
 
+bool TskAuto::isCurVsValid() const {
+    return m_curVsPartValid;
+}
+
 /**
  * Opens the disk image to be analyzed.  This must be called before any
  * of the findFilesInXXX() methods.
@@ -345,7 +352,12 @@ TSK_RETVAL_ENUM
 
     TSK_FS_INFO *fs_info;
     if ((fs_info = tsk_fs_open_img(m_img_info, a_start, a_ftype)) == NULL) {
-        if (getCurVsPartFlag() & TSK_VS_PART_FLAG_ALLOC) {
+        if (isCurVsValid() == false) {
+            tsk_error_set_errstr2 ("Sector offset: %" PRIuOFF, a_start/512);
+            registerError();
+            return TSK_ERR;
+        }
+        else if (getCurVsPartFlag() & TSK_VS_PART_FLAG_ALLOC) {
             tsk_error_set_errstr2 ("Sector offset: %" PRIuOFF ", Partition Type: %s",
                 a_start/512, getCurVsPartDescr().c_str() );
             registerError();
@@ -425,7 +437,12 @@ uint8_t
 
     TSK_FS_INFO *fs_info;
     if ((fs_info = tsk_fs_open_img(m_img_info, a_start, a_ftype)) == NULL) {
-        if (getCurVsPartFlag() & TSK_VS_PART_FLAG_ALLOC) {
+        if (isCurVsValid() == false) {
+            tsk_error_set_errstr2 ("Sector offset: %" PRIuOFF, a_start/512);
+            registerError();
+            return TSK_ERR;
+        }
+        else if (getCurVsPartFlag() & TSK_VS_PART_FLAG_ALLOC) {
             tsk_error_set_errstr2(
                 "Sector offset: %" PRIuOFF ", Partition Type: %s",
                 a_start / 512, getCurVsPartDescr().c_str());
@@ -594,7 +611,7 @@ uint8_t TskAuto::registerError() {
     
     // call super class implementation
     uint8_t retval = handleError();
-    
+
     tsk_error_reset();
     return retval;
 }
diff --git a/tsk/auto/db_sqlite.cpp b/tsk/auto/db_sqlite.cpp
index 6cd22aa..c98586e 100644
--- a/tsk/auto/db_sqlite.cpp
+++ b/tsk/auto/db_sqlite.cpp
@@ -569,13 +569,21 @@ int
  * Store meta_addr to object id mapping of the directory in a local cache map
  * @param fsObjId fs id of this directory
  * @param meta_addr meta_addr of this directory
+ * @param meta_seq meta_seq of this directory
  * @param objId object id of this directory from the objects table
  */
-void TskDbSqlite::storeObjId(const int64_t & fsObjId, const TSK_INUM_T & meta_addr, const int64_t & objId) {
-	map<TSK_INUM_T,int64_t> &tmpMap = m_parentDirIdCache[fsObjId];
-	//store only if does not exist
-	if (tmpMap.count(meta_addr) == 0)
-		tmpMap[meta_addr] = objId;
+void TskDbSqlite::storeObjId(const int64_t & fsObjId, const TSK_INUM_T & meta_addr, const uint32_t & meta_seq, const int64_t & objId) {
+	map<TSK_INUM_T, map<uint32_t, int64_t> > &fsMap = m_parentDirIdCache[fsObjId];
+	//store only if does not exist -- otherwise '..' and '.' entries will overwrite
+	if (fsMap.count(meta_addr) == 0) {
+        fsMap[meta_addr][meta_seq] = objId;
+    }
+    else {
+        map<uint32_t, int64_t> &fileMap = fsMap[meta_addr];
+        if (fileMap.count(meta_seq) == 0) {
+            fileMap[meta_seq] = objId;
+        }
+    }
 }
 
 /**
@@ -586,12 +594,16 @@ void TskDbSqlite::storeObjId(const int64_t & fsObjId, const TSK_INUM_T & meta_ad
  */
 int64_t TskDbSqlite::findParObjId(const TSK_FS_FILE * fs_file, const int64_t & fsObjId) {
 	//get from cache by parent meta addr, if available
-	map<TSK_INUM_T,int64_t> &tmpMap = m_parentDirIdCache[fsObjId];
-	if (tmpMap.count(fs_file->name->par_addr) > 0) {
-		return tmpMap[fs_file->name->par_addr];
+	map<TSK_INUM_T, map<uint32_t, int64_t> > &fsMap = m_parentDirIdCache[fsObjId];
+	if (fsMap.count(fs_file->name->par_addr) > 0) {
+        map<uint32_t, int64_t>  &fileMap = fsMap[fs_file->name->par_addr];
+        if (fileMap.count(fs_file->name->par_seq) > 0) {
+		    return fileMap[fs_file->name->par_seq];
+        }
 	}
 
     // Find the parent file id in the database using the parent metadata address
+    // @@@ This should use sequence number when the new database supports it
     if (attempt(sqlite3_bind_int64(m_selectFilePreparedStmt, 1, fs_file->name->par_addr),
                 "TskDbSqlite::findParObjId: Error binding meta_addr to statment: %s (result code %d)\n")
         || attempt(sqlite3_bind_int64(m_selectFilePreparedStmt, 2, fsObjId),
@@ -795,7 +807,7 @@ int
 
     //if dir, update parent id cache
     if (meta_type == TSK_FS_META_TYPE_DIR) {
-        storeObjId(fsObjId, fs_file->name->meta_addr, objId);
+        storeObjId(fsObjId, fs_file->name->meta_addr, fs_file->name->meta_seq, objId);
     }
 
     free(name);
diff --git a/tsk/auto/tsk_auto.h b/tsk/auto/tsk_auto.h
index f99169a..9fc47d2 100644
--- a/tsk/auto/tsk_auto.h
+++ b/tsk/auto/tsk_auto.h
@@ -195,10 +195,17 @@ class TskAuto {
      * @return flags for lastly processed volume.
      */
     TSK_VS_PART_FLAG_ENUM getCurVsPartFlag() const;
+
+    /**
+     * Determine if we are inside of a volume system and 
+     * therefore we can trust the results of getCurVsPartFlag/Desc.
+     */
+    bool isCurVsValid() const;
     
   private:
     TSK_VS_PART_FLAG_ENUM m_volFilterFlags;
     TSK_FS_DIR_WALK_FLAG_ENUM m_fileFilterFlags;
+    
     std::vector<error_record> m_errors;
 
     // prevent copying until we add proper logic to handle it
@@ -214,7 +221,7 @@ class TskAuto {
 
     std::string m_curVsPartDescr; ///< description string of the current volume being processed
     TSK_VS_PART_FLAG_ENUM m_curVsPartFlag; ///< Flag of the current volume being processed
-
+    bool m_curVsPartValid;         ///< True if we are inside of a volume system (and therefore m_CurVs are valid)
     void setCurVsPart(const TSK_VS_PART_INFO *);
 
 
@@ -223,6 +230,7 @@ class TskAuto {
     bool m_internalOpen;        ///< True if m_img_info was opened in TskAuto and false if passed in
     bool m_stopAllProcessing;   ///< True if no further processing should occur
     
+    
     uint8_t isNtfsSystemFiles(TSK_FS_FILE * fs_file, const char *path);
     uint8_t isFATSystemFiles(TSK_FS_FILE * fs_file);
     uint8_t isDotDir(TSK_FS_FILE * fs_file);
diff --git a/tsk/auto/tsk_db_sqlite.h b/tsk/auto/tsk_db_sqlite.h
index 7a23ff6..5bfd8a1 100755
--- a/tsk/auto/tsk_db_sqlite.h
+++ b/tsk/auto/tsk_db_sqlite.h
@@ -232,7 +232,7 @@ class TskDbSqlite {
         const uint64_t size, vector<TSK_DB_FILE_LAYOUT_RANGE> & ranges, int64_t & objId);
     int addLayoutFileInfo(const int64_t parObjId, const int64_t fsObjId, const TSK_DB_FILES_TYPE_ENUM dbFileType, const char *fileName, const uint64_t size,
         int64_t & objId);
-    void storeObjId(const int64_t & fsObjId, const TSK_INUM_T & meta_addr, const int64_t & objId);
+    void storeObjId(const int64_t & fsObjId, const TSK_INUM_T & meta_addr, const uint32_t & meta_seq, const int64_t & objId);
     int64_t findParObjId(const TSK_FS_FILE * fs_file, const int64_t & fsObjId);
     sqlite3 *m_db;
     TSK_TCHAR m_dbFilePath[1024];
@@ -240,7 +240,7 @@ class TskDbSqlite {
     bool m_blkMapFlag;
     bool m_utf8; //encoding used for the database file name, not the actual database
     sqlite3_stmt *m_selectFilePreparedStmt;
-    map<int64_t, map<TSK_INUM_T,int64_t> > m_parentDirIdCache; //maps a file system ID to a map, which maps a directory file system meta address to its object ID in the database
+    map<int64_t, map<TSK_INUM_T, map<uint32_t, int64_t> > > m_parentDirIdCache; //maps a file system ID to a map, which maps a directory file system meta address to a map, which maps a sequence ID to its object ID in the database
 };
 
 #endif
diff --git a/tsk/base/Makefile.am b/tsk/base/Makefile.am
index c8315ac..54d3748 100644
--- a/tsk/base/Makefile.am
+++ b/tsk/base/Makefile.am
@@ -1,5 +1,4 @@
-AM_CFLAGS = -I../.. -Wall 
-AM_CXXFLAGS = -I../.. -Wall 
+AM_CPPFLAGS = -I../.. -Wall 
 
 noinst_LTLIBRARIES = libtskbase.la
 libtskbase_la_SOURCES = md5c.c mymalloc.c sha1c.c \
diff --git a/tsk/base/Makefile.in b/tsk/base/Makefile.in
index eccd92d..7f3e91a 100644
--- a/tsk/base/Makefile.in
+++ b/tsk/base/Makefile.in
@@ -235,8 +235,7 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_CFLAGS = -I../.. -Wall 
-AM_CXXFLAGS = -I../.. -Wall 
+AM_CPPFLAGS = -I../.. -Wall 
 noinst_LTLIBRARIES = libtskbase.la
 libtskbase_la_SOURCES = md5c.c mymalloc.c sha1c.c \
     crc.c crc.h \
diff --git a/tsk/base/crc.c b/tsk/base/crc.c
index 3b416ef..ef6a2a2 100644
--- a/tsk/base/crc.c
+++ b/tsk/base/crc.c
@@ -140,50 +140,6 @@ p_cm_t p_cm;
     return p_cm->cm_xorot ^ p_cm->cm_reg;
 }
 
-/******************************************************************************/
-
-ulong cm_tab (p_cm_t p_cm, int index)
-{
- int   i;
- ulong r;
- ulong topbit = BITMASK(p_cm->cm_width-1);
- ulong inbyte = (ulong) index;
-
- if (p_cm->cm_refin) inbyte = reflect(inbyte,8);
- r = inbyte << (p_cm->cm_width-8);
- for (i=0; i<8; i++)
-    if (r & topbit)
-       r = (r << 1) ^ p_cm->cm_poly;
-    else
-       r<<=1;
- if (p_cm->cm_refin) r = reflect(r,p_cm->cm_width);
- return r & widmask(p_cm);
-}
-
-
-void generate_crc_table(short *crctab[], p_cm_t p_cm){
-    int i, j;
-    unsigned long bit, crc;
-    unsigned long crchighbit = (unsigned long)1 << (p_cm->cm_width-1);
-    unsigned long crcmask = ((((unsigned long)1<<(p_cm->cm_width-1))-1)<<1)|1;
-
-    for (i=0; i<256; i++)
-    {
-        crc=(unsigned long)i;
-        if(p_cm->cm_refin) crc = reflect(crc,8);
-        crc <<= p_cm->cm_width-8;
-        for(j=0; j<8; j++)
-        {
-            bit = crc & crchighbit;
-            crc <<=1;
-            if(bit) crc ^=p_cm->cm_poly;
-        }
-        if(p_cm->cm_refin) crc = reflect(crc,p_cm->cm_width);
-        crc &= crcmask;
-        crctab[i]= crc;
-    }
-    return;
-}
 
 /******************************************************************************/
 /*                             End of crcmodel.c                              */
diff --git a/tsk/base/tsk_base.h b/tsk/base/tsk_base.h
index 3de0c9b..4220e6d 100644
--- a/tsk/base/tsk_base.h
+++ b/tsk/base/tsk_base.h
@@ -39,11 +39,11 @@
  * 3.1.2b1 would be 0x03010201.  Snapshot from Jan 2, 2003 would be
  * 0xFF030102.
  * See TSK_VERSION_STR for string form. */
-#define TSK_VERSION_NUM 0x040100ff
+#define TSK_VERSION_NUM 0x040102ff
 
 /** Version of code in string form. See TSK_VERSION_NUM for
  * integer form. */
-#define TSK_VERSION_STR "4.1.0"
+#define TSK_VERSION_STR "4.1.2"
 
 
 /* include the TSK-specific header file that we created in autoconf
@@ -473,6 +473,16 @@ documentation and/or software.
     void TSK_SHA_Init(TSK_SHA_CTX *);
     void TSK_SHA_Update(TSK_SHA_CTX *, BYTE * buffer, int count);
     void TSK_SHA_Final(BYTE * output, TSK_SHA_CTX *);
+
+/* Flags for which type of hash(es) to run */
+	typedef enum{
+		TSK_BASE_HASH_INVALID_ID = 0,
+		TSK_BASE_HASH_MD5 = 0x01,
+		TSK_BASE_HASH_SHA1 = 0x02
+		//TSK_BASE_HASH_SHA256 = 0x04,
+	} TSK_BASE_HASH_ENUM;
+
+
 //@}
 
 #ifdef __cplusplus
diff --git a/tsk/base/tsk_os.h b/tsk/base/tsk_os.h
index 9caf15f..e2ab094 100644
--- a/tsk/base/tsk_os.h
+++ b/tsk/base/tsk_os.h
@@ -98,7 +98,11 @@ typedef int mode_t;
 // if python.h is included
 #if !defined( HAVE_SSIZE_T )
 #define HAVE_SSIZE_T
-typedef int ssize_t;
+#if _WIN64
+typedef int64_t ssize_t;
+#else
+typedef int32_t ssize_t;
+#endif
 #endif
 
 // remap some of the POSIX functions
diff --git a/tsk/docs/fs.dox b/tsk/docs/fs.dox
index d6b64e7..d3d36f2 100644
--- a/tsk/docs/fs.dox
+++ b/tsk/docs/fs.dox
@@ -32,7 +32,7 @@ A basic ASCII diagram is shown here of the different categories.  The file syste
         +------------+      +-----------+      +-------------+
 </pre>
 
-The command line tools and the file system APIs are organized based on these layers.   Data at each layer can be directly accessed and some functions combine layers. 
+The command line tools and the file system APIs are organized based on these layers.   Data at each layer can be directly accessed and some functions combine layers. 
     
 \subsection fs_del Deleted Files
 
diff --git a/tsk/fs/Makefile.am b/tsk/fs/Makefile.am
index 8743330..5095ec0 100644
--- a/tsk/fs/Makefile.am
+++ b/tsk/fs/Makefile.am
@@ -1,4 +1,3 @@
-AM_CFLAGS = -I../.. -I$(srcdir)/../.. -Wall 
 AM_CPPFLAGS = -I../.. -I$(srcdir)/../.. -Wall 
 EXTRA_DIST = .indent.pro
 
diff --git a/tsk/fs/Makefile.in b/tsk/fs/Makefile.in
index 6ad656f..bb1caaf 100644
--- a/tsk/fs/Makefile.in
+++ b/tsk/fs/Makefile.in
@@ -240,7 +240,6 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_CFLAGS = -I../.. -I$(srcdir)/../.. -Wall 
 AM_CPPFLAGS = -I../.. -I$(srcdir)/../.. -Wall 
 EXTRA_DIST = .indent.pro
 noinst_LTLIBRARIES = libtskfs.la
diff --git a/tsk/fs/ext2fs_dent.c b/tsk/fs/ext2fs_dent.c
index 6783009..fd33bfc 100644
--- a/tsk/fs/ext2fs_dent.c
+++ b/tsk/fs/ext2fs_dent.c
@@ -282,6 +282,7 @@ ext2fs_dir_open_meta(TSK_FS_INFO * a_fs, TSK_FS_DIR ** a_fs_dir,
     fs_dir = *a_fs_dir;
     if (fs_dir) {
         tsk_fs_dir_reset(fs_dir);
+        fs_dir->addr = a_addr;
     }
     else {
         if ((*a_fs_dir = fs_dir =
diff --git a/tsk/fs/fatfs_dent.cpp b/tsk/fs/fatfs_dent.cpp
index 5b532de..8d1c371 100644
--- a/tsk/fs/fatfs_dent.cpp
+++ b/tsk/fs/fatfs_dent.cpp
@@ -642,6 +642,7 @@ TSK_RETVAL_ENUM
     fs_dir = *a_fs_dir;
     if (fs_dir) {
         tsk_fs_dir_reset(fs_dir);
+        fs_dir->addr = a_addr;
     }
     else {
         if ((*a_fs_dir = fs_dir =
diff --git a/tsk/fs/ffs_dent.c b/tsk/fs/ffs_dent.c
index e256e58..ee7b8ae 100644
--- a/tsk/fs/ffs_dent.c
+++ b/tsk/fs/ffs_dent.c
@@ -265,6 +265,7 @@ ffs_dir_open_meta(TSK_FS_INFO * a_fs, TSK_FS_DIR ** a_fs_dir,
     fs_dir = *a_fs_dir;
     if (fs_dir) {
         tsk_fs_dir_reset(fs_dir);
+        fs_dir->addr = a_addr;
     }
     else {
         if ((*a_fs_dir = fs_dir =
diff --git a/tsk/fs/fls_lib.c b/tsk/fs/fls_lib.c
index a9a8d1f..5cfde43 100644
--- a/tsk/fs/fls_lib.c
+++ b/tsk/fs/fls_lib.c
@@ -50,6 +50,7 @@ static void
 printit(TSK_FS_FILE * fs_file, const char *a_path,
     const TSK_FS_ATTR * fs_attr, const FLS_DATA * fls_data)
 {
+    TSK_FS_HASH_RESULTS hash_results;
     unsigned int i;
 
     if ((!(fls_data->flags & TSK_FS_FLS_FULL)) && (a_path)) {
@@ -67,8 +68,17 @@ printit(TSK_FS_FILE * fs_file, const char *a_path,
 
 
     if (fls_data->flags & TSK_FS_FLS_MAC) {
-        tsk_fs_name_print_mac(stdout, fs_file, a_path,
-            fs_attr, fls_data->macpre, fls_data->sec_skew);
+        if (fls_data->flags & TSK_FS_FLS_HASH) {
+            tsk_fs_file_hash_calc(fs_file, &hash_results,
+                TSK_BASE_HASH_MD5);
+            tsk_fs_name_print_mac_md5(stdout, fs_file, a_path, fs_attr,
+                fls_data->macpre, fls_data->sec_skew,
+                hash_results.md5_digest);
+        }
+        else {
+            tsk_fs_name_print_mac(stdout, fs_file, a_path,
+                fs_attr, fls_data->macpre, fls_data->sec_skew);
+        }
     }
     else if (fls_data->flags & TSK_FS_FLS_LONG) {
         tsk_fs_name_print_long(stdout, fs_file, a_path, fs_file->fs_info,
@@ -147,6 +157,19 @@ print_dent_act(TSK_FS_FILE * fs_file, const char *a_path, void *ptr)
                             ((fls_data->flags & TSK_FS_FLS_DOT) == 0)))
                         printit(fs_file, a_path, fs_attr, fls_data);
                 }
+                /* Print the FILE_NAME times if this is the same attribute
+                 * that we collected the times from. */
+                else if ((fs_attr->type == TSK_FS_ATTR_TYPE_NTFS_FNAME) &&
+                    (fs_attr->id == fs_file->meta->time2.ntfs.fn_id) &&
+                    (fls_data->flags & TSK_FS_FLS_MAC)) {
+                    /* If it is . or .. only print it if the flags say so,
+                     * we continue with other streams though in case the 
+                     * directory has a data stream 
+                     */
+                    if (!((TSK_FS_ISDOT(fs_file->name->name)) &&
+                            ((fls_data->flags & TSK_FS_FLS_DOT) == 0)))
+                        printit(fs_file, a_path, fs_attr, fls_data);
+                }
             }
 
             /* A user reported that an allocated file had the standard
@@ -180,7 +203,6 @@ tsk_fs_fls(TSK_FS_INFO * fs, TSK_FS_FLS_FLAG_ENUM lclflags,
 
 #ifdef TSK_WIN32
     {
-        char *cpre;
         size_t clen;
         UTF8 *ptr8;
         UTF16 *ptr16;
@@ -188,11 +210,11 @@ tsk_fs_fls(TSK_FS_INFO * fs, TSK_FS_FLS_FLAG_ENUM lclflags,
 
         if ((tpre != NULL) && (TSTRLEN(tpre) > 0)) {
             clen = TSTRLEN(tpre) * 4;
-            cpre = (char *) tsk_malloc(clen);
-            if (cpre == NULL) {
+            data.macpre = (char *) tsk_malloc(clen);
+            if (data.macpre == NULL) {
                 return 1;
             }
-            ptr8 = (UTF8 *) cpre;
+            ptr8 = (UTF8 *) data.macpre;
             ptr16 = (UTF16 *) tpre;
 
             retval =
@@ -207,18 +229,19 @@ tsk_fs_fls(TSK_FS_INFO * fs, TSK_FS_FLS_FLAG_ENUM lclflags,
                     retval);
                 return 1;
             }
-            data.macpre = cpre;
         }
         else {
-            data.macpre = NULL;
-            cpre = NULL;
+            data.macpre = (char *) tsk_malloc(1);
+            if (data.macpre == NULL) {
+                return 1;
+            }
+            data.macpre[0] = '\0';
         }
 
         retval = tsk_fs_dir_walk(fs, inode, flags, print_dent_act, &data);
 
-        if (cpre)
-            free(cpre);
-
+        free(data.macpre);
+        data.macpre = NULL;
         return retval;
     }
 #else
diff --git a/tsk/fs/fs_attrlist.c b/tsk/fs/fs_attrlist.c
index 4d0e494..ede0a7c 100644
--- a/tsk/fs/fs_attrlist.c
+++ b/tsk/fs/fs_attrlist.c
@@ -57,7 +57,7 @@ tsk_fs_attrlist_free(TSK_FS_ATTRLIST * a_fs_attrlist)
  *
  * @param a_fs_attrlist List structure to add to
  * @param a_fs_attr Data attribute to add
- * @returns 1 on error and 0 on success
+ * @returns 1 on error and 0 on success. Caller must free memory on error.
  */
 uint8_t
 tsk_fs_attrlist_add(TSK_FS_ATTRLIST * a_fs_attrlist,
@@ -164,8 +164,10 @@ tsk_fs_attrlist_getnew(TSK_FS_ATTRLIST * a_fs_attrlist,
                 return NULL;
 
             // add it to the list
-            if (tsk_fs_attrlist_add(a_fs_attrlist, fs_attr_cur))
+            if (tsk_fs_attrlist_add(a_fs_attrlist, fs_attr_cur)) {
+                tsk_fs_attr_free(fs_attr_cur);
                 return NULL;
+            }
         }
     }
 
diff --git a/tsk/fs/fs_dir.c b/tsk/fs/fs_dir.c
index ea72de6..307802e 100644
--- a/tsk/fs/fs_dir.c
+++ b/tsk/fs/fs_dir.c
@@ -104,6 +104,7 @@ tsk_fs_dir_reset(TSK_FS_DIR * a_fs_dir)
     }
     a_fs_dir->names_used = 0;
     a_fs_dir->addr = 0;
+    a_fs_dir->seq = 0;
 }
 
 
@@ -135,6 +136,7 @@ tsk_fs_dir_copy(const TSK_FS_DIR * a_src_dir, TSK_FS_DIR * a_dst_dir)
 
     a_dst_dir->names_used = a_src_dir->names_used;
     a_dst_dir->addr = a_src_dir->addr;
+    a_dst_dir->seq = a_src_dir->seq;
     return 0;
 }
 
@@ -214,8 +216,10 @@ tsk_fs_dir_add(TSK_FS_DIR * a_fs_dir, const TSK_FS_NAME * a_fs_name)
         return 1;
 
     // add the parent address
-    if (a_fs_dir->addr)
+    if (a_fs_dir->addr) {
         fs_name_dest->par_addr = a_fs_dir->addr;
+        fs_name_dest->par_seq = a_fs_dir->seq;
+    }
 
     return 0;
 }
@@ -403,6 +407,14 @@ tsk_fs_dir_get(const TSK_FS_DIR * a_fs_dir, size_t a_idx)
                 tsk_error_print(stderr);
             tsk_error_reset();
         }
+
+        // if the sequence numbers don't match, then don't load the meta
+        // should ideally have sequence in previous lookup, but it isn't 
+        // in all APIs yet
+        if (fs_file->meta->seq != fs_name->meta_seq) {
+            tsk_fs_meta_close(fs_file->meta);
+            fs_file->meta = NULL;
+        }
     }
     return fs_file;
 }
diff --git a/tsk/fs/fs_file.c b/tsk/fs/fs_file.c
index b4e0d31..9ac967a 100644
--- a/tsk/fs/fs_file.c
+++ b/tsk/fs/fs_file.c
@@ -185,6 +185,9 @@ tsk_fs_file_open(TSK_FS_INFO * a_fs,
     if (fs_file) {
         // Add the name to the structure
         fs_file->name = fs_name;
+
+        // path2inum did not put this in there...
+        fs_name->meta_seq = fs_file->meta->seq;
     }
     else {
         tsk_fs_name_free(fs_name);
@@ -563,3 +566,95 @@ tsk_fs_file_get_owner_sid(TSK_FS_FILE * a_fs_file, char **sid_str)
 
     return a_fs_file->fs_info->fread_owner_sid(a_fs_file, sid_str);
 }
+
+
+/**
+ * Internal struct used for hash calculations
+ */
+typedef struct {
+    TSK_BASE_HASH_ENUM flags;
+    TSK_MD5_CTX md5_context;
+    TSK_SHA_CTX sha1_context;
+} TSK_FS_HASH_DATA;
+
+/**
+ * Helper function for tsk_fs_file_get_md5
+ */
+TSK_WALK_RET_ENUM
+tsk_fs_file_hash_calc_callback(TSK_FS_FILE * file, TSK_OFF_T offset,
+    TSK_DADDR_T addr, char *buf, size_t size,
+    TSK_FS_BLOCK_FLAG_ENUM a_flags, void *ptr)
+{
+    TSK_FS_HASH_DATA *hash_data = (TSK_FS_HASH_DATA *) ptr;
+    if (hash_data == NULL)
+        return TSK_WALK_CONT;
+
+    if (hash_data->flags & TSK_BASE_HASH_MD5) {
+        TSK_MD5_Update(&(hash_data->md5_context), (unsigned char *) buf,
+            (unsigned int) size);
+    }
+
+    if (hash_data->flags & TSK_BASE_HASH_SHA1) {
+        TSK_SHA_Update(&(hash_data->sha1_context), (unsigned char *) buf,
+            (unsigned int) size);
+    }
+
+
+    return TSK_WALK_CONT;
+}
+
+/**
+ * Returns a string containing the md5 hash of the given file
+ *
+ * @param a_fs_file The file to calculate the hash of
+ * @param a_hash_results The results will be stored here (must be allocated beforehand)
+ * @param a_flags Indicates which hash algorithm(s) to use
+ * @returns 0 on success or 1 on error
+ */
+extern uint8_t
+tsk_fs_file_hash_calc(TSK_FS_FILE * a_fs_file,
+    TSK_FS_HASH_RESULTS * a_hash_results, TSK_BASE_HASH_ENUM a_flags)
+{
+    TSK_FS_HASH_DATA hash_data;
+
+    if ((a_fs_file == NULL) || (a_fs_file->fs_info == NULL)
+        || (a_fs_file->meta == NULL)) {
+        tsk_error_set_errno(TSK_ERR_FS_ARG);
+        tsk_error_set_errstr("tsk_fs_file_hash_calc: fs_info is NULL");
+        return 1;
+    }
+
+    if (a_hash_results == NULL) {
+        tsk_error_set_errno(TSK_ERR_FS_ARG);
+        tsk_error_set_errstr
+            ("tsk_fs_file_hash_calc: hash_results is NULL");
+        return 1;
+    }
+
+    if (a_flags & TSK_BASE_HASH_MD5) {
+        TSK_MD5_Init(&(hash_data.md5_context));
+    }
+    if (a_flags & TSK_BASE_HASH_SHA1) {
+        TSK_SHA_Init(&(hash_data.sha1_context));
+    }
+
+    hash_data.flags = a_flags;
+    if (tsk_fs_file_walk(a_fs_file, TSK_FS_FILE_WALK_FLAG_NONE,
+            tsk_fs_file_hash_calc_callback, (void *) &hash_data)) {
+        tsk_error_set_errno(TSK_ERR_FS_ARG);
+        tsk_error_set_errstr("tsk_fs_file_hash_calc: error in file walk");
+        return 1;
+    }
+
+    a_hash_results->flags = a_flags;
+    if (a_flags & TSK_BASE_HASH_MD5) {
+        TSK_MD5_Final(a_hash_results->md5_digest,
+            &(hash_data.md5_context));
+    }
+    if (a_flags & TSK_BASE_HASH_MD5) {
+        TSK_SHA_Final(a_hash_results->sha1_digest,
+            &(hash_data.sha1_context));
+    }
+
+    return 0;
+}
diff --git a/tsk/fs/fs_name.c b/tsk/fs/fs_name.c
index f692a69..f1e4988 100644
--- a/tsk/fs/fs_name.c
+++ b/tsk/fs/fs_name.c
@@ -7,7 +7,7 @@
 ** depending on the file system type.
 **
 ** Brian Carrier [carrier <at> sleuthkit [dot] org]
-** Copyright (c) 2006-2011 Brian Carrier.  All Rights reserved
+** Copyright (c) 2006-2013 Brian Carrier.  All Rights reserved
 ** Copyright (c) 2003-2005 Brian Carrier.  All rights reserved 
 **
 ** TASK
@@ -111,6 +111,7 @@ tsk_fs_name_reset(TSK_FS_NAME * a_fs_name)
     a_fs_name->meta_addr = 0;
     a_fs_name->meta_seq = 0;
     a_fs_name->par_addr = 0;
+    a_fs_name->par_seq = 0;
     a_fs_name->type = 0;
     a_fs_name->flags = 0;
 }
@@ -196,6 +197,7 @@ tsk_fs_name_copy(TSK_FS_NAME * a_fs_name_to,
     a_fs_name_to->meta_addr = a_fs_name_from->meta_addr;
     a_fs_name_to->meta_seq = a_fs_name_from->meta_seq;
     a_fs_name_to->par_addr = a_fs_name_from->par_addr;
+    a_fs_name_to->par_seq = a_fs_name_from->par_seq;
     a_fs_name_to->type = a_fs_name_from->type;
     a_fs_name_to->flags = a_fs_name_from->flags;
 
@@ -558,6 +560,8 @@ tsk_fs_name_print_long(FILE * hFile, const TSK_FS_FILE * fs_file,
 }
 
 
+
+
 /**
  * \internal
  *
@@ -580,14 +584,63 @@ tsk_fs_name_print_mac(FILE * hFile, const TSK_FS_FILE * fs_file,
     const char *a_path, const TSK_FS_ATTR * fs_attr,
     const char *prefix, int32_t time_skew)
 {
+    tsk_fs_name_print_mac_md5(hFile, fs_file, a_path, fs_attr, prefix,
+        time_skew, NULL);
+}
+
+/**
+ * \internal
+ *
+** Print output in the format that mactime reads.
+**
+** If the flags in the fs_file->meta structure are set to FS_FLAG_ALLOC
+** then it is assumed that the inode has been reallocated and the
+** contents are not displayed
+**
+** fs is not required (only used for block size).
+ * @param hFile handle to print results to
+ * @param fs_file File to print details about
+ * @param a_path Parent directory of file (needs to end with "/")
+ * @param fs_attr Attribute in file that is being called for (NULL for non-NTFS)
+ * @param prefix Path of mounting point for image
+ * @param time_skew number of seconds skew to adjust time
+ * @param hash_results Holds the calculated md5 hash
+*/
+void
+tsk_fs_name_print_mac_md5(FILE * hFile, const TSK_FS_FILE * fs_file,
+    const char *a_path, const TSK_FS_ATTR * fs_attr,
+    const char *prefix, int32_t time_skew,
+    const unsigned char *hash_results)
+{
     char ls[12];
     size_t i;
+    uint8_t isADS = 0;
 
     if ((!hFile) || (!fs_file))
         return;
 
-    /* md5 */
-    tsk_fprintf(hFile, "0|");
+    /* see if we are going to be printing the name of the attribute
+     * We don't do it for FNAME attributes, which we handle specially below.
+     */
+    if ((fs_attr) && (fs_attr->name)
+        && (fs_attr->type != TSK_FS_ATTR_TYPE_NTFS_FNAME)
+        && ((fs_attr->type != TSK_FS_ATTR_TYPE_NTFS_IDXROOT)
+            || (strcmp(fs_attr->name, "$I30") != 0))) {
+        isADS = 1;
+    }
+
+    /* hash
+     * Print out the hash buffer (if not null)
+     */
+    if (hash_results == NULL) {
+        tsk_fprintf(hFile, "0|");
+    }
+    else {
+        for (i = 0; i < 16; i++) {
+            tsk_fprintf(hFile, "%02x", hash_results[i]);
+        }
+        tsk_fprintf(hFile, "|");
+    }
 
     /* file name */
     tsk_fprintf(hFile, "%s", prefix);
@@ -610,9 +663,7 @@ tsk_fs_name_print_mac(FILE * hFile, const TSK_FS_FILE * fs_file,
     }
 
     /* print the data stream name if it exists and is not the default NTFS */
-    if ((fs_attr) && (fs_attr->name) &&
-        ((fs_attr->type != TSK_FS_ATTR_TYPE_NTFS_IDXROOT) ||
-            (strcmp(fs_attr->name, "$I30") != 0))) {
+    if (isADS) {
         tsk_fprintf(hFile, ":");
         for (i = 0; i < strlen(fs_attr->name); i++) {
             if (TSK_IS_CNTRL(fs_attr->name[i]))
@@ -622,6 +673,11 @@ tsk_fs_name_print_mac(FILE * hFile, const TSK_FS_FILE * fs_file,
         }
     }
 
+    // special label if FNAME
+    if ((fs_attr) && (fs_attr->type == TSK_FS_ATTR_TYPE_NTFS_FNAME)) {
+        tsk_fprintf(hFile, " ($FILE_NAME)");
+    }
+
     if ((fs_file->meta)
         && (fs_file->meta->type == TSK_FS_META_TYPE_LNK)
         && (fs_file->meta->link)) {
@@ -643,7 +699,7 @@ tsk_fs_name_print_mac(FILE * hFile, const TSK_FS_FILE * fs_file,
 
     tsk_fprintf(hFile, "|");
 
-    /* TYPE as specified in the directory entry 
+    /* TYPE as specified in the directory entry
      */
     if (fs_file->name->type < TSK_FS_NAME_TYPE_STR_MAX)
         tsk_fprintf(hFile, "%s/",
@@ -652,10 +708,9 @@ tsk_fs_name_print_mac(FILE * hFile, const TSK_FS_FILE * fs_file,
         tsk_fprintf(hFile, "-/");
 
     if (!fs_file->meta) {
-        tsk_fprintf(hFile, "----------|0|0|0|0|0|0|0\n");
+        tsk_fprintf(hFile, "----------|0|0|0|");
     }
     else {
-
         /* mode as string */
         tsk_fs_meta_make_ls(fs_file->meta, ls, sizeof(ls));
         tsk_fprintf(hFile, "%s|", ls);
@@ -669,30 +724,68 @@ tsk_fs_name_print_mac(FILE * hFile, const TSK_FS_FILE * fs_file,
             tsk_fprintf(hFile, "%" PRIuOFF "|", fs_attr->size);
         else
             tsk_fprintf(hFile, "%" PRIuOFF "|", fs_file->meta->size);
+    }
 
-        /* atime, mtime, ctime, crtime */
-        if (fs_file->meta->atime)
-            tsk_fprintf(hFile, "%" PRIu32 "|",
-                fs_file->meta->atime - time_skew);
-        else
-            tsk_fprintf(hFile, "%" PRIu32 "|", fs_file->meta->atime);
+    if (!fs_file->meta) {
+        tsk_fprintf(hFile, "0|0|0|0\n");
+    }
+    else {
+        // special case for NTFS FILE_NAME attribute
+        if ((fs_attr) && (fs_attr->type == TSK_FS_ATTR_TYPE_NTFS_FNAME)) {
+            /* atime, mtime, ctime, crtime */
+            if (fs_file->meta->time2.ntfs.fn_atime)
+                tsk_fprintf(hFile, "%" PRIu32 "|",
+                    fs_file->meta->time2.ntfs.fn_atime - time_skew);
+            else
+                tsk_fprintf(hFile, "%" PRIu32 "|",
+                    fs_file->meta->time2.ntfs.fn_atime);
 
-        if (fs_file->meta->mtime)
-            tsk_fprintf(hFile, "%" PRIu32 "|",
-                fs_file->meta->mtime - time_skew);
-        else
-            tsk_fprintf(hFile, "%" PRIu32 "|", fs_file->meta->mtime);
+            if (fs_file->meta->time2.ntfs.fn_mtime)
+                tsk_fprintf(hFile, "%" PRIu32 "|",
+                    fs_file->meta->time2.ntfs.fn_mtime - time_skew);
+            else
+                tsk_fprintf(hFile, "%" PRIu32 "|",
+                    fs_file->meta->time2.ntfs.fn_mtime);
 
-        if (fs_file->meta->ctime)
-            tsk_fprintf(hFile, "%" PRIu32 "|",
-                fs_file->meta->ctime - time_skew);
-        else
-            tsk_fprintf(hFile, "%" PRIu32 "|", fs_file->meta->ctime);
+            if (fs_file->meta->time2.ntfs.fn_ctime)
+                tsk_fprintf(hFile, "%" PRIu32 "|",
+                    fs_file->meta->time2.ntfs.fn_ctime - time_skew);
+            else
+                tsk_fprintf(hFile, "%" PRIu32 "|",
+                    fs_file->meta->time2.ntfs.fn_ctime);
 
-        if (fs_file->meta->crtime)
-            tsk_fprintf(hFile, "%" PRIu32 "\n",
-                fs_file->meta->crtime - time_skew);
-        else
-            tsk_fprintf(hFile, "%" PRIu32 "\n", fs_file->meta->crtime);
+            if (fs_file->meta->time2.ntfs.fn_crtime)
+                tsk_fprintf(hFile, "%" PRIu32 "\n",
+                    fs_file->meta->time2.ntfs.fn_crtime - time_skew);
+            else
+                tsk_fprintf(hFile, "%" PRIu32 "\n",
+                    fs_file->meta->time2.ntfs.fn_crtime);
+        }
+        else {
+            /* atime, mtime, ctime, crtime */
+            if (fs_file->meta->atime)
+                tsk_fprintf(hFile, "%" PRIu32 "|",
+                    fs_file->meta->atime - time_skew);
+            else
+                tsk_fprintf(hFile, "%" PRIu32 "|", fs_file->meta->atime);
+
+            if (fs_file->meta->mtime)
+                tsk_fprintf(hFile, "%" PRIu32 "|",
+                    fs_file->meta->mtime - time_skew);
+            else
+                tsk_fprintf(hFile, "%" PRIu32 "|", fs_file->meta->mtime);
+
+            if (fs_file->meta->ctime)
+                tsk_fprintf(hFile, "%" PRIu32 "|",
+                    fs_file->meta->ctime - time_skew);
+            else
+                tsk_fprintf(hFile, "%" PRIu32 "|", fs_file->meta->ctime);
+
+            if (fs_file->meta->crtime)
+                tsk_fprintf(hFile, "%" PRIu32 "\n",
+                    fs_file->meta->crtime - time_skew);
+            else
+                tsk_fprintf(hFile, "%" PRIu32 "\n", fs_file->meta->crtime);
+        }
     }
 }
diff --git a/tsk/fs/hfs_dent.c b/tsk/fs/hfs_dent.c
index 3392c48..0c259f1 100644
--- a/tsk/fs/hfs_dent.c
+++ b/tsk/fs/hfs_dent.c
@@ -404,6 +404,7 @@ hfs_dir_open_meta(TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir,
     fs_dir = *a_fs_dir;
     if (fs_dir) {
         tsk_fs_dir_reset(fs_dir);
+        fs_dir->addr = a_addr;
     }
     else if ((*a_fs_dir = fs_dir =
             tsk_fs_dir_alloc(fs, a_addr, 128)) == NULL) {
diff --git a/tsk/fs/ifind_lib.c b/tsk/fs/ifind_lib.c
index bbc57af..28353b6 100644
--- a/tsk/fs/ifind_lib.c
+++ b/tsk/fs/ifind_lib.c
@@ -196,6 +196,8 @@ tsk_fs_path2inum(TSK_FS_INFO * a_fs, const char *a_path,
         // create the dummy entry if needed
         if (a_fs_name) {
             a_fs_name->meta_addr = a_fs->root_inum;
+            // Note that we are not filling in meta_seq -- we could, we just aren't
+
             a_fs_name->type = TSK_FS_NAME_TYPE_DIR;
             a_fs_name->flags = TSK_FS_NAME_FLAG_ALLOC;
             if (a_fs_name->name)
diff --git a/tsk/fs/iso9660_dent.c b/tsk/fs/iso9660_dent.c
index 6dfc6b5..dabb026 100644
--- a/tsk/fs/iso9660_dent.c
+++ b/tsk/fs/iso9660_dent.c
@@ -250,6 +250,7 @@ iso9660_dir_open_meta(TSK_FS_INFO * a_fs, TSK_FS_DIR ** a_fs_dir,
     fs_dir = *a_fs_dir;
     if (fs_dir) {
         tsk_fs_dir_reset(fs_dir);
+        fs_dir->addr = a_addr;
     }
     else {
         if ((*a_fs_dir = fs_dir =
diff --git a/tsk/fs/ntfs.c b/tsk/fs/ntfs.c
index 5563704..237189f 100755
--- a/tsk/fs/ntfs.c
+++ b/tsk/fs/ntfs.c
@@ -2050,6 +2050,29 @@ ntfs_proc_attrseq(NTFS_INFO * ntfs,
             if (fname->nspace == NTFS_FNAME_DOS) {
                 continue;
             }
+            
+            fs_file->meta->time2.ntfs.fn_mtime =
+                nt2unixtime(tsk_getu64(fs->endian, fname->mtime));
+            fs_file->meta->time2.ntfs.fn_mtime_nano =
+                nt2nano(tsk_getu64(fs->endian, fname->mtime));
+            
+            fs_file->meta->time2.ntfs.fn_atime =
+                nt2unixtime(tsk_getu64(fs->endian, fname->atime));
+            fs_file->meta->time2.ntfs.fn_atime_nano =
+                nt2nano(tsk_getu64(fs->endian, fname->atime));
+            
+            fs_file->meta->time2.ntfs.fn_ctime =
+                nt2unixtime(tsk_getu64(fs->endian, fname->ctime));
+            fs_file->meta->time2.ntfs.fn_ctime_nano =
+                nt2nano(tsk_getu64(fs->endian, fname->ctime));
+            
+            fs_file->meta->time2.ntfs.fn_crtime =
+                nt2unixtime(tsk_getu64(fs->endian, fname->crtime));
+            fs_file->meta->time2.ntfs.fn_crtime_nano =
+                nt2nano(tsk_getu64(fs->endian, fname->crtime));
+
+            fs_file->meta->time2.ntfs.fn_id = id;
+            
 
             /* Seek to the end of the fs_name structures in TSK_FS_META */
             if (fs_file->meta->name2) {
@@ -2530,7 +2553,16 @@ ntfs_dinode_copy(NTFS_INFO * ntfs, TSK_FS_FILE * a_fs_file, char *a_buf,
     a_fs_file->meta->ctime_nano = 0;
     a_fs_file->meta->crtime = 0;
     a_fs_file->meta->crtime_nano = 0;
-
+    a_fs_file->meta->time2.ntfs.fn_mtime = 0;
+    a_fs_file->meta->time2.ntfs.fn_mtime_nano = 0;
+    a_fs_file->meta->time2.ntfs.fn_atime = 0;
+    a_fs_file->meta->time2.ntfs.fn_atime_nano = 0;
+    a_fs_file->meta->time2.ntfs.fn_ctime = 0;
+    a_fs_file->meta->time2.ntfs.fn_ctime_nano = 0;
+    a_fs_file->meta->time2.ntfs.fn_crtime = 0;
+    a_fs_file->meta->time2.ntfs.fn_crtime_nano = 0;
+    a_fs_file->meta->time2.ntfs.fn_id = 0;
+    
     /* add the flags */
     a_fs_file->meta->flags =
         ((tsk_getu16(fs->endian, mft->flags) &
@@ -4247,7 +4279,6 @@ ntfs_istat(TSK_FS_INFO * fs, FILE * hFile,
     if (fs_attr) {
 
         ntfs_attr_fname *fname = (ntfs_attr_fname *) fs_attr->rd.buf;
-        time_t cr_time, m_time, c_time, a_time;
         uint64_t flags;
         int a = 0;
         tsk_fprintf(hFile, "\n$FILE_NAME Attribute Values:\n");
@@ -4313,42 +4344,49 @@ ntfs_istat(TSK_FS_INFO * fs, FILE * hFile,
         /*
          * Times
          */
-        cr_time = nt2unixtime(tsk_getu64(fs->endian, fname->crtime));
-        /* altered - modified */
-        m_time = nt2unixtime(tsk_getu64(fs->endian, fname->mtime));
-        /* MFT modified */
-        c_time = nt2unixtime(tsk_getu64(fs->endian, fname->ctime));
-        /* Access */
-        a_time = nt2unixtime(tsk_getu64(fs->endian, fname->atime));
+        
+        /* Times - take it from fs_file->meta instead of redoing the work */
+        
         if (sec_skew != 0) {
             tsk_fprintf(hFile, "\nAdjusted times:\n");
-            cr_time -= sec_skew;
-            m_time -= sec_skew;
-            a_time -= sec_skew;
-            c_time -= sec_skew;
+            if (fs_file->meta->time2.ntfs.fn_mtime)
+                fs_file->meta->time2.ntfs.fn_mtime -= sec_skew;
+            if (fs_file->meta->time2.ntfs.fn_atime)
+                fs_file->meta->time2.ntfs.fn_atime -= sec_skew;
+            if (fs_file->meta->time2.ntfs.fn_ctime)
+                fs_file->meta->time2.ntfs.fn_ctime -= sec_skew;
+            if (fs_file->meta->time2.ntfs.fn_crtime)
+                fs_file->meta->time2.ntfs.fn_crtime -= sec_skew;
+            
             tsk_fprintf(hFile, "Created:\t%s\n",
-                tsk_fs_time_to_str(cr_time, timeBuf));
+                        tsk_fs_time_to_str(fs_file->meta->time2.ntfs.fn_crtime, timeBuf));
             tsk_fprintf(hFile, "File Modified:\t%s\n",
-                tsk_fs_time_to_str(m_time, timeBuf));
+                        tsk_fs_time_to_str(fs_file->meta->time2.ntfs.fn_mtime, timeBuf));
             tsk_fprintf(hFile, "MFT Modified:\t%s\n",
-                tsk_fs_time_to_str(c_time, timeBuf));
+                        tsk_fs_time_to_str(fs_file->meta->time2.ntfs.fn_ctime, timeBuf));
             tsk_fprintf(hFile, "Accessed:\t%s\n",
-                tsk_fs_time_to_str(a_time, timeBuf));
-            cr_time += sec_skew;
-            m_time += sec_skew;
-            a_time += sec_skew;
-            c_time += sec_skew;
+                        tsk_fs_time_to_str(fs_file->meta->time2.ntfs.fn_atime, timeBuf));
+            
+            if (fs_file->meta->time2.ntfs.fn_mtime == 0)
+                fs_file->meta->time2.ntfs.fn_mtime += sec_skew;
+            if (fs_file->meta->time2.ntfs.fn_atime == 0)
+                fs_file->meta->time2.ntfs.fn_atime += sec_skew;
+            if (fs_file->meta->time2.ntfs.fn_ctime == 0)
+                fs_file->meta->time2.ntfs.fn_ctime += sec_skew;
+            if (fs_file->meta->time2.ntfs.fn_crtime == 0)
+                fs_file->meta->time2.ntfs.fn_crtime += sec_skew;
+            
             tsk_fprintf(hFile, "\nOriginal times:\n");
         }
-
+        
         tsk_fprintf(hFile, "Created:\t%s\n",
-            tsk_fs_time_to_str(cr_time, timeBuf));
+                    tsk_fs_time_to_str(fs_file->meta->time2.ntfs.fn_crtime, timeBuf));
         tsk_fprintf(hFile, "File Modified:\t%s\n",
-            tsk_fs_time_to_str(m_time, timeBuf));
+                    tsk_fs_time_to_str(fs_file->meta->time2.ntfs.fn_mtime, timeBuf));
         tsk_fprintf(hFile, "MFT Modified:\t%s\n",
-            tsk_fs_time_to_str(c_time, timeBuf));
+                    tsk_fs_time_to_str(fs_file->meta->time2.ntfs.fn_ctime, timeBuf));
         tsk_fprintf(hFile, "Accessed:\t%s\n",
-            tsk_fs_time_to_str(a_time, timeBuf));
+                    tsk_fs_time_to_str(fs_file->meta->time2.ntfs.fn_atime, timeBuf));
     }
 
 
diff --git a/tsk/fs/ntfs_dent.cpp b/tsk/fs/ntfs_dent.cpp
index b3dc62c..8129f5a 100644
--- a/tsk/fs/ntfs_dent.cpp
+++ b/tsk/fs/ntfs_dent.cpp
@@ -640,6 +640,7 @@ ntfs_dir_open_meta(TSK_FS_INFO * a_fs, TSK_FS_DIR ** a_fs_dir,
     fs_dir = *a_fs_dir;
     if (fs_dir) {
         tsk_fs_dir_reset(fs_dir);
+        fs_dir->addr = a_addr;
     }
     else {
         if ((*a_fs_dir = fs_dir =
@@ -668,6 +669,8 @@ ntfs_dir_open_meta(TSK_FS_INFO * a_fs, TSK_FS_DIR ** a_fs_dir,
         return TSK_COR;
     }
 
+    // Update with the sequence number
+    fs_dir->seq = fs_dir->fs_file->meta->seq;
 
     /*
      * Read the Index Root Attribute  -- we do some sanity checking here
diff --git a/tsk/fs/tsk_fs.h b/tsk/fs/tsk_fs.h
index 2668a8d..39e0608 100644
--- a/tsk/fs/tsk_fs.h
+++ b/tsk/fs/tsk_fs.h
@@ -96,7 +96,7 @@ extern "C" {
 
 #define TSK_FS_BLOCK_TAG 0x1b7c3f4a
     /** 
-    * Generic data strcture to hold block data with metadata
+    * Generic data structure to hold block data with metadata
     */
     typedef struct {
         int tag;                ///< \internal Will be set to TSK_FS_BLOCK_TAG if structure is valid / allocated 
@@ -472,6 +472,17 @@ extern "C" {
                 time_t bkup_time;       ///< HFS+ backup time
                 uint32_t bkup_time_nano;        ///< nano-second resolution in addition to bkup_time
             } hfs;
+            struct {
+                time_t fn_crtime;   ///< NTFS Created time stored in FILE_NAME
+                time_t fn_crtime_nano;   ///< NTFS Created time stored in FILE_NAME in nano-second resolution
+                time_t fn_mtime;   ///< NTFS mod (content) stored in FILE_NAME
+                time_t fn_mtime_nano;   ///< NTFS mod time stored in FILE_NAME in nano-second resolution
+                time_t fn_atime;   ///< NTFS access time stored in FILE_NAME
+                time_t fn_atime_nano;   ///< NTFS access time stored in FILE_NAME in nano-second resolution
+                time_t fn_ctime;   ///< NTFS change (MFT Entry) time stored in FILE_NAME
+                time_t fn_ctime_nano;   ///< NTFS change (MFT Entry) time stored in FILE_NAME in nano-second resolution
+                uint16_t fn_id; ///< Attribute ID used to populate FN times. 
+            } ntfs;
         } time2;
 
         void *content_ptr;      ///< Pointer to file system specific data that is used to store references to file content
@@ -580,7 +591,8 @@ extern "C" {
 
         TSK_INUM_T meta_addr;   ///< Address of the metadata structure that the name points to. 
         uint32_t meta_seq;      ///< Sequence number for metadata structure (NTFS only) 
-        TSK_INUM_T par_addr;    ///< Metadata address of parent directory (equal to meta_addr if this entry is for root directory). 
+        TSK_INUM_T par_addr;    ///< Metadata address of parent directory (equal to meta_addr if this entry is for root directory).
+        uint32_t par_seq;       ///< Sequence number for parent directory (NTFS only)
 
         TSK_FS_NAME_TYPE_ENUM type;     ///< File type information (directory, file, etc.)
         TSK_FS_NAME_FLAG_ENUM flags;    ///< Flags that describe allocation status etc. 
@@ -612,7 +624,8 @@ extern "C" {
         size_t names_used;      ///< Number of name structures in queue being used
         size_t names_alloc;     ///< Number of name structures that were allocated
 
-        TSK_INUM_T addr;        ///< Metadata address of this directory 
+        TSK_INUM_T addr;        ///< Metadata address of this directory
+        uint32_t seq;           ///< Metadata address sequence (NTFS Only)
 
         TSK_FS_INFO *fs_info;   ///< Pointer to file system the directory is located in
     } TSK_FS_DIR;
@@ -711,6 +724,14 @@ extern "C" {
 
     extern uint8_t tsk_fs_file_get_owner_sid(TSK_FS_FILE *, char **);
 
+	typedef struct {
+		TSK_BASE_HASH_ENUM flags;
+		unsigned char md5_digest[16];
+		unsigned char sha1_digest[20];
+	} TSK_FS_HASH_RESULTS;
+
+	extern uint8_t tsk_fs_file_hash_calc(TSK_FS_FILE *, TSK_FS_HASH_RESULTS *, TSK_BASE_HASH_ENUM);
+
     //@}
 
 
@@ -765,8 +786,8 @@ extern "C" {
         TSK_FS_TYPE_HFS = 0x00001000,   ///< HFS file system
         TSK_FS_TYPE_HFS_DETECT = 0x00001000,    ///< HFS auto detection
         TSK_FS_TYPE_EXT4 = 0x00002000,  ///< Ext4 file system
-        TSK_FS_TYPE_YAFFS2 = 0x00003000,        ///< YAFFS2 file system
-        TSK_FS_TYPE_YAFFS2_DETECT = 0x00003000, ///< YAFFS2 auto detection
+        TSK_FS_TYPE_YAFFS2 = 0x00004000,        ///< YAFFS2 file system
+        TSK_FS_TYPE_YAFFS2_DETECT = 0x00004000, ///< YAFFS2 auto detection
         TSK_FS_TYPE_UNSUPP = 0xffffffff,        ///< Unsupported file system
     };
     /* NOTE: Update bindings/java/src/org/sleuthkit/datamodel/TskData.java
@@ -1032,6 +1053,7 @@ extern "C" {
         TSK_FS_FLS_DIR = 0x08,
         TSK_FS_FLS_FULL = 0x10,
         TSK_FS_FLS_MAC = 0x20,
+		TSK_FS_FLS_HASH = 0x40
     };
     typedef enum TSK_FS_FLS_FLAG_ENUM TSK_FS_FLS_FLAG_ENUM;
     extern uint8_t tsk_fs_fls(TSK_FS_INFO * fs,
diff --git a/tsk/fs/tsk_fs_i.h b/tsk/fs/tsk_fs_i.h
index 27538e2..944f281 100644
--- a/tsk/fs/tsk_fs_i.h
+++ b/tsk/fs/tsk_fs_i.h
@@ -162,6 +162,9 @@ extern "C" {
         int32_t);
     extern void tsk_fs_name_print_mac(FILE *, const TSK_FS_FILE *,
         const char *, const TSK_FS_ATTR * fs_attr, const char *, int32_t);
+    extern void tsk_fs_name_print_mac_md5(FILE *, const TSK_FS_FILE *,
+        const char *, const TSK_FS_ATTR * fs_attr, const char *, int32_t,
+		const unsigned char *);
     extern uint8_t tsk_fs_name_copy(TSK_FS_NAME * a_fs_name_to,
         const TSK_FS_NAME * a_fs_name_from);
     extern void tsk_fs_name_reset(TSK_FS_NAME * a_fs_name);
diff --git a/tsk/fs/yaffs.cpp b/tsk/fs/yaffs.cpp
index f7492ed..9288ed1 100644
--- a/tsk/fs/yaffs.cpp
+++ b/tsk/fs/yaffs.cpp
@@ -2339,6 +2339,7 @@ static TSK_RETVAL_ENUM
 
     if (fs_dir) {
         tsk_fs_dir_reset(fs_dir);
+        fs_dir->addr = a_addr;
     }
     else if ((*a_fs_dir = fs_dir = tsk_fs_dir_alloc(a_fs, a_addr, 128)) == NULL) {
         return TSK_ERR;
@@ -2639,6 +2640,8 @@ TSK_FS_INFO *
     yaffsfs->page_size = psize == 0 ? YAFFS_DEFAULT_PAGE_SIZE : psize;
     yaffsfs->spare_size = ssize == 0 ? YAFFS_DEFAULT_SPARE_SIZE : ssize;
     yaffsfs->chunks_per_block = 64;
+    // TODO: Why are 2 different memory allocation methods used in the same code?
+    // This makes things unnecessary complex.
     yaffsfs->chunkMap = new std::map<uint32_t, YaffsCacheChunkGroup>;
     yaffsfs->max_obj_id = 1;
     yaffsfs->max_version = 0;
@@ -2667,7 +2670,7 @@ TSK_FS_INFO *
         tsk_error_set_errstr("not a YAFFS file system (bad spare format)");
         if (tsk_verbose)
             fprintf(stderr, "yaffsfs_open: could not find valid spare area format\n");
-        return NULL;
+        goto on_error;
     }
 
     /*
@@ -2682,9 +2685,10 @@ TSK_FS_INFO *
         tsk_error_set_errstr("not a YAFFS file system (first record)");
         if (tsk_verbose)
             fprintf(stderr, "yaffsfs_open: invalid first record\n");
-        return NULL;
+        goto on_error;
     }
     free(first_header);
+    first_header = NULL;
 
     fs->duname = "Chunk";
 
@@ -2766,5 +2770,18 @@ TSK_FS_INFO *
     tsk_fs_dir_close(test_dir);
 
     return fs;
+
+on_error:
+    // Make sure to free yaffsfs here otherwise it will leak
+    if( yaffsfs != NULL ) {
+        // TODO: where is chunkMap freed in normal operations?
+        if( yaffsfs->chunkMap != NULL ) {
+            yaffsfs->chunkMap->clear();
+
+            delete yaffsfs->chunkMap;
+        }
+        free( yaffsfs );
+    }
+    return NULL;
 }
 
diff --git a/tsk/hashdb/Makefile.am b/tsk/hashdb/Makefile.am
index cc58345..7a1c074 100644
--- a/tsk/hashdb/Makefile.am
+++ b/tsk/hashdb/Makefile.am
@@ -1,4 +1,4 @@
-AM_CFLAGS = -I../.. -I$(srcdir)/../.. -Wall 
+AM_CPPFLAGS = -I../.. -I$(srcdir)/../.. -Wall 
 EXTRA_DIST = .indent.pro
 
 noinst_LTLIBRARIES = libtskhashdb.la
diff --git a/tsk/hashdb/Makefile.in b/tsk/hashdb/Makefile.in
index e6bdea0..51e9cc3 100644
--- a/tsk/hashdb/Makefile.in
+++ b/tsk/hashdb/Makefile.in
@@ -224,7 +224,7 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_CFLAGS = -I../.. -I$(srcdir)/../.. -Wall 
+AM_CPPFLAGS = -I../.. -I$(srcdir)/../.. -Wall 
 EXTRA_DIST = .indent.pro
 noinst_LTLIBRARIES = libtskhashdb.la
 libtskhashdb_la_SOURCES = tm_lookup.c md5sum_index.c nsrl_index.c \
diff --git a/tsk/hashdb/tm_lookup.c b/tsk/hashdb/tm_lookup.c
index 173f3c6..9a60263 100644
--- a/tsk/hashdb/tm_lookup.c
+++ b/tsk/hashdb/tm_lookup.c
@@ -625,6 +625,18 @@ hdb_setupindex(TSK_HDB_INFO * hdb_info, uint8_t htype)
             return 1;
         }
     }
+    else if (strcmp(ptr, TSK_HDB_DBTYPE_ENCASE_STR) == 0) {
+        if ((hdb_info->db_type != TSK_HDB_DBTYPE_ENCASE_ID) &&
+            (hdb_info->db_type != TSK_HDB_DBTYPE_IDXONLY_ID)) {
+            tsk_release_lock(&hdb_info->lock);
+            tsk_error_reset();
+            tsk_error_set_errno(TSK_ERR_HDB_UNKTYPE);
+            tsk_error_set_errstr(
+                     "hdb_indexsetup: DB detected as %s, index type has EnCase",
+                     ptr);
+            return 1;
+        }
+    }
     else if (hdb_info->db_type != TSK_HDB_DBTYPE_IDXONLY_ID) {
         tsk_release_lock(&hdb_info->lock);
         tsk_error_reset();
diff --git a/tsk/img/Makefile.am b/tsk/img/Makefile.am
index d47359e..da0ab8e 100644
--- a/tsk/img/Makefile.am
+++ b/tsk/img/Makefile.am
@@ -1,4 +1,4 @@
-AM_CFLAGS = -I../.. -I$(srcdir)/../.. -Wall
+AM_CPPFLAGS = -I../.. -I$(srcdir)/../.. -Wall
 EXTRA_DIST = .indent.pro 
 
 noinst_LTLIBRARIES = libtskimg.la
diff --git a/tsk/img/Makefile.in b/tsk/img/Makefile.in
index 00a9caf..20d143d 100644
--- a/tsk/img/Makefile.in
+++ b/tsk/img/Makefile.in
@@ -224,7 +224,7 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_CFLAGS = -I../.. -I$(srcdir)/../.. -Wall
+AM_CPPFLAGS = -I../.. -I$(srcdir)/../.. -Wall
 EXTRA_DIST = .indent.pro 
 noinst_LTLIBRARIES = libtskimg.la
 libtskimg_la_SOURCES = img_open.c img_types.c raw.c raw.h \
diff --git a/tsk/img/ewf.c b/tsk/img/ewf.c
index bfae3f9..07f5697 100644
--- a/tsk/img/ewf.c
+++ b/tsk/img/ewf.c
@@ -140,7 +140,7 @@ ewf_image_close(TSK_IMG_INFO * img_info)
     }
 
     tsk_deinit_lock(&(ewf_info->read_lock));
-    free(img_info);
+    tsk_img_free(img_info);
 }
 
 /* Tests if the image file header against the
@@ -236,7 +236,7 @@ ewf_open(int a_num_img,
             tsk_error_set_errstr("ewf_open: Not an E01 glob name (%s)",
                 error_string);
             libewf_error_free(&ewf_error);
-            free(ewf_info);
+            tsk_img_free(ewf_info);
             return NULL;
         }
 
@@ -256,7 +256,7 @@ ewf_open(int a_num_img,
             tsk_error_set_errno(TSK_ERR_IMG_MAGIC);
             tsk_error_set_errstr("ewf_open: Not an E01 glob name");
 
-            free(ewf_info);
+            tsk_img_free(ewf_info);
             return NULL;
         }
 #endif                          // end v1
@@ -273,14 +273,14 @@ ewf_open(int a_num_img,
         if ((ewf_info->images =
                 (TSK_TCHAR **) tsk_malloc(a_num_img *
                     sizeof(TSK_TCHAR *))) == NULL) {
-            free(ewf_info);
+            tsk_img_free(ewf_info);
             return NULL;
         }
         for (i = 0; i < a_num_img; i++) {
             if ((ewf_info->images[i] =
                     (TSK_TCHAR *) tsk_malloc((TSTRLEN(a_images[i]) +
                             1) * sizeof(TSK_TCHAR))) == NULL) {
-                free(ewf_info);
+                tsk_img_free(ewf_info);
                 return NULL;
             }
             TSTRNCPY(ewf_info->images[i], a_images[i],
@@ -306,7 +306,7 @@ ewf_open(int a_num_img,
             error_string);
         libewf_error_free(&ewf_error);
 
-        free(ewf_info);
+        tsk_img_free(ewf_info);
 
         if (tsk_verbose != 0) {
             tsk_fprintf(stderr, "Not an EWF file\n");
@@ -323,7 +323,7 @@ ewf_open(int a_num_img,
             ": Error initializing handle (%s)", a_images[0], error_string);
         libewf_error_free(&ewf_error);
 
-        free(ewf_info);
+        tsk_img_free(ewf_info);
 
         if (tsk_verbose != 0) {
             tsk_fprintf(stderr, "Unable to create EWF handle\n");
@@ -348,7 +348,7 @@ ewf_open(int a_num_img,
             ": Error opening (%s)", a_images[0], error_string);
         libewf_error_free(&ewf_error);
 
-        free(ewf_info);
+        tsk_img_free(ewf_info);
 
         if (tsk_verbose != 0) {
             tsk_fprintf(stderr, "Error opening EWF file\n");
@@ -366,7 +366,7 @@ ewf_open(int a_num_img,
             error_string);
         libewf_error_free(&ewf_error);
 
-        free(ewf_info);
+        tsk_img_free(ewf_info);
 
         if (tsk_verbose != 0) {
             tsk_fprintf(stderr, "Error getting size of EWF file\n");
@@ -386,7 +386,7 @@ ewf_open(int a_num_img,
             error_string);
         libewf_error_free(&ewf_error);
 
-        free(ewf_info);
+        tsk_img_free(ewf_info);
 
         if (tsk_verbose != 0) {
             tsk_fprintf(stderr, "Error getting size of EWF file\n");
@@ -407,7 +407,7 @@ ewf_open(int a_num_img,
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_IMG_MAGIC);
         tsk_error_set_errstr("ewf_open: Not an EWF file");
-        free(ewf_info);
+        tsk_img_free(ewf_info);
         if (tsk_verbose)
             tsk_fprintf(stderr, "Not an EWF file\n");
 
@@ -428,7 +428,7 @@ ewf_open(int a_num_img,
         tsk_error_set_errno(TSK_ERR_IMG_OPEN);
         tsk_error_set_errstr("ewf_open file: %" PRIttocTSK
             ": Error opening", ewf_info->images[0]);
-        free(ewf_info);
+        tsk_img_free(ewf_info);
 
         if (tsk_verbose != 0) {
             tsk_fprintf(stderr, "Error opening EWF file\n");
@@ -449,7 +449,7 @@ ewf_open(int a_num_img,
         tsk_error_set_errno(TSK_ERR_IMG_OPEN);
         tsk_error_set_errstr("ewf_open file: %" PRIttocTSK
             ": Error getting size of image", ewf_info->images[0]);
-        free(ewf_info);
+        tsk_img_free(ewf_info);
         if (tsk_verbose) {
             tsk_fprintf(stderr, "Error getting size of EWF file\n");
         }
diff --git a/tsk/img/img_io.c b/tsk/img/img_io.c
index 00e95c0..df783ed 100644
--- a/tsk/img/img_io.c
+++ b/tsk/img/img_io.c
@@ -26,15 +26,42 @@ tsk_img_read(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_off,
     char *a_buf, size_t a_len)
 {
 #define CACHE_AGE   1000
-    ssize_t retval = 0;
-    int i;
+    ssize_t read_count = 0;
+    int cache_index = 0;
     int cache_next = 0;         // index to lowest age cache (to use next)
-    size_t len2;
+    size_t len2 = 0;
 
     if (a_img_info == NULL) {
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_IMG_ARG);
-        tsk_error_set_errstr("tsk_img_read: pointer is NULL");
+        tsk_error_set_errstr("tsk_img_read: a_img_info: NULL");
+        return -1;
+    }
+
+    // Do not allow a_buf to be NULL.
+    if (a_buf == NULL) {
+        tsk_error_reset();
+        tsk_error_set_errno(TSK_ERR_IMG_ARG);
+        tsk_error_set_errstr("tsk_img_read: a_buf: NULL");
+        return -1;
+    }
+
+    // The function cannot handle negative offsets.
+    if (a_off < 0) {
+        tsk_error_reset();
+        tsk_error_set_errno(TSK_ERR_IMG_ARG);
+        tsk_error_set_errstr("tsk_img_read: a_off: %" PRIuOFF, a_off);
+        return -1;
+    }
+
+    // Protect a_off against overflowing when a_len is added since TSK_OFF_T
+    // maps to an int64 we prefer it over size_t although likely checking
+    // for ( a_len > SSIZE_MAX ) is better but the code does not seem to
+    // use that approach.
+    if ((TSK_OFF_T) a_len < 0) {
+        tsk_error_reset();
+        tsk_error_set_errno(TSK_ERR_IMG_ARG);
+        tsk_error_set_errstr("tsk_img_read: a_len: %zd", a_len);
         return -1;
     }
 
@@ -45,26 +72,27 @@ tsk_img_read(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_off,
     tsk_take_lock(&(a_img_info->cache_lock));
 
     // if they ask for more than the cache length, skip the cache
-    if ((a_len + a_off % 512) > TSK_IMG_INFO_CACHE_LEN) {
+    if ((a_len + (a_off % 512)) > TSK_IMG_INFO_CACHE_LEN) {
         ssize_t nbytes;
 
         /* Some of the lower-level methods like block-sized reads.
          * So if the len is not that multiple, then make it. */
         if (a_len % a_img_info->sector_size) {
             char *buf2 = a_buf;
-            size_t len2;
-            len2 = roundup(a_len, a_img_info->sector_size);
-            if ((buf2 = (char *)tsk_malloc(len2)) == NULL) {
+
+            size_t len_tmp;
+            len_tmp = roundup(a_len, a_img_info->sector_size);
+            if ((buf2 = (char *) tsk_malloc(len_tmp)) == NULL) {
                 tsk_release_lock(&(a_img_info->cache_lock));
                 return -1;
             }
-            nbytes = a_img_info->read(a_img_info, a_off, buf2, len2);
-            if ((nbytes > 0) && (nbytes < (ssize_t)a_len)) {
+            nbytes = a_img_info->read(a_img_info, a_off, buf2, len_tmp);
+            if ((nbytes > 0) && (nbytes < (ssize_t) a_len)) {
                 memcpy(a_buf, buf2, nbytes);
             }
             else {
                 memcpy(a_buf, buf2, a_len);
-                nbytes = a_len;
+                nbytes = (ssize_t)a_len;
             }
             free(buf2);
         }
@@ -75,6 +103,8 @@ tsk_img_read(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_off,
         return nbytes;
     }
 
+    // TODO: why not just return 0 here (and be POSIX compliant)?
+    // and why not check earlier for this condition?
     if (a_off >= a_img_info->size) {
         tsk_release_lock(&(a_img_info->cache_lock));
         tsk_error_reset();
@@ -86,34 +116,40 @@ tsk_img_read(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_off,
     /* See if the requested length is going to be too long.
      * we'll use this length when checking the cache. */
     len2 = a_len;
-    if (a_off + len2 > a_img_info->size)
+
+    // Protect against INT64_MAX + INT64_MAX > value
+    if (((TSK_OFF_T) len2 > a_img_info->size)
+        || (a_off >= (a_img_info->size - (TSK_OFF_T)len2))) {
         len2 = (size_t) (a_img_info->size - a_off);
+    }
 
     // check if it is in the cache
-    for (i = 0; i < TSK_IMG_INFO_CACHE_NUM; i++) {
+    for (cache_index = 0;
+        cache_index < TSK_IMG_INFO_CACHE_NUM; cache_index++) {
 
         // Look into the in-use cache entries
-        if (a_img_info->cache_len[i] > 0) {
+        if (a_img_info->cache_len[cache_index] > 0) {
 
-            // the retval check makes sure we don't go back in after data was read
-            if ((retval == 0) && (a_img_info->cache_off[i] <= a_off) &&
-                (a_img_info->cache_off[i] + a_img_info->cache_len[i] >=
-                    a_off + len2)) {
+            // the read_count check makes sure we don't go back in after data was read
+            if ((read_count == 0)
+                && (a_img_info->cache_off[cache_index] <= a_off)
+                && (a_img_info->cache_off[cache_index] +
+                    a_img_info->cache_len[cache_index] >= a_off + len2)) {
 
                 /*
                    if (tsk_verbose)
                    fprintf(stderr,
-                   "tsk_img_read: Read found in cache %d\n", i);
+                   "tsk_img_read: Read found in cache %d\n",  cache_index );
                  */
 
                 // We found it...
                 memcpy(a_buf,
-                    &a_img_info->cache[i][a_off -
-                        a_img_info->cache_off[i]], len2);
-                retval = (ssize_t) len2;
+                    &a_img_info->cache[cache_index][a_off -
+                        a_img_info->cache_off[cache_index]], len2);
+                read_count = (ssize_t) len2;
 
                 // reset its "age" since it was useful
-                a_img_info->cache_age[i] = CACHE_AGE;
+                a_img_info->cache_age[cache_index] = CACHE_AGE;
 
                 // we don't break out of the loop so that we update all ages
             }
@@ -121,23 +157,23 @@ tsk_img_read(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_off,
                 /* decrease its "age" since it was not useful.
                  * We don't let used ones go below 1 so that they are not
                  * confused with entries that have never been used. */
-                a_img_info->cache_age[i]--;
+                a_img_info->cache_age[cache_index]--;
 
                 // see if this is the most eligible replacement
                 if ((a_img_info->cache_len[cache_next] > 0)
-                    && (a_img_info->cache_age[i] <
+                    && (a_img_info->cache_age[cache_index] <
                         a_img_info->cache_age[cache_next]))
-                    cache_next = i;
+                    cache_next = cache_index;
             }
         }
         else {
-            cache_next = i;
+            cache_next = cache_index;
         }
     }
 
     // if we didn't find it, then load it into the cache_next entry
-    if (retval == 0) {
-        size_t rlen;
+    if (read_count == 0) {
+        size_t read_size = 0;
 
         // round the offset down to a sector boundary
         a_img_info->cache_off[cache_next] = (a_off / 512) * 512;
@@ -149,33 +185,40 @@ tsk_img_read(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_off,
            ")\n", cache_next, a_img_info->cache_off[cache_next]);
          */
 
-        // figure out the length to read into the cache
-        rlen = TSK_IMG_INFO_CACHE_LEN;
-        if (a_img_info->cache_off[cache_next] + rlen > a_img_info->size) {
-            rlen =
+        // Read a full cache block or the remaining data.
+        read_size = TSK_IMG_INFO_CACHE_LEN;
+
+        if ((a_img_info->cache_off[cache_next] + (TSK_OFF_T)read_size) >
+            a_img_info->size) {
+            read_size =
                 (size_t) (a_img_info->size -
                 a_img_info->cache_off[cache_next]);
         }
 
-        retval =
-            a_img_info->read(a_img_info, a_img_info->cache_off[cache_next],
-            a_img_info->cache[cache_next], rlen);
+        read_count = a_img_info->read(a_img_info,
+            a_img_info->cache_off[cache_next],
+            a_img_info->cache[cache_next], read_size);
 
         // if no error, then set the variables and copy the data
-        if (retval != -1) {
+        // Although a read_count of -1 indicates an error,
+        // since read_count is used in the calculation it may not be negative.
+        // Also it does not make sense to copy data when the read_count is 0.
+        if (read_count > 0) {
+            TSK_OFF_T rel_off = 0;
             a_img_info->cache_age[cache_next] = CACHE_AGE;
-            a_img_info->cache_len[cache_next] = retval;
-
-            // update the length we can actually copy (in case we did not get to read all that we wanted)
-            if (a_off + len2 > a_img_info->cache_off[cache_next] + retval)
-                len2 =
-                    (size_t) (a_img_info->cache_off[cache_next] + retval -
-                    a_off);
-
-            memcpy(a_buf,
-                &a_img_info->cache[cache_next][a_off -
-                    a_img_info->cache_off[cache_next]], len2);
-            retval = (ssize_t) len2;
+            a_img_info->cache_len[cache_next] = read_count;
+
+            // Determine the offset relative to the start of the cached data.
+            rel_off = a_off - a_img_info->cache_off[cache_next];
+
+            // Make sure not to copy more than is available in the cache.
+            if ((rel_off + (TSK_OFF_T) len2) > (TSK_OFF_T) read_count) {
+                len2 = (size_t) (read_count - rel_off);
+            }
+
+            memcpy(a_buf, &(a_img_info->cache[cache_next][rel_off]), len2);
+
+            read_count = (ssize_t) len2;
         }
         else {
             a_img_info->cache_len[cache_next] = 0;
@@ -185,5 +228,5 @@ tsk_img_read(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_off,
     }
 
     tsk_release_lock(&(a_img_info->cache_lock));
-    return retval;
+    return read_count;
 }
diff --git a/tsk/img/mult_files.c b/tsk/img/mult_files.c
index ac3cdd9..1cd41a5 100644
--- a/tsk/img/mult_files.c
+++ b/tsk/img/mult_files.c
@@ -142,6 +142,13 @@ getSegmentName(const TSK_TCHAR * a_startingName, int a_segmentNumber)
         return newName;
     }
 
+	// numeric counter, variable width
+    if (endsWith(a_startingName, _TSK_T(".bin"))) {
+		TSNPRINTF(newName + nameLen - 4, 36, _TSK_T("(%d).bin"),
+            a_segmentNumber);
+        return newName;
+    }
+
     // unknown name format
     free(newName);
     return NULL;
diff --git a/tsk/img/raw.c b/tsk/img/raw.c
index 6b5c832..432e0f6 100644
--- a/tsk/img/raw.c
+++ b/tsk/img/raw.c
@@ -74,27 +74,9 @@ raw_read_segment(IMG_RAW_INFO * raw_info, int idx, char *buf,
 
 #ifdef TSK_WIN32
         cimg->fd = CreateFile(raw_info->images[idx], FILE_READ_DATA,
-                              FILE_SHARE_READ, NULL, OPEN_EXISTING, 0,
+                              FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0,
                               NULL);
         if ( cimg->fd == INVALID_HANDLE_VALUE ) {
-            /* if it is a Windows device, try again with SHARE_WRITE */
-            if ((raw_info->images[idx][0] == _TSK_T('\\'))
-                && (raw_info->images[idx][1] == _TSK_T('\\'))
-                && ((raw_info->images[idx][2] == _TSK_T('.')) || (raw_info->images[idx][2] == _TSK_T('?')))
-                && (raw_info->images[idx][3] == _TSK_T('\\'))) {
-
-                if ( tsk_verbose ) {
-                    tsk_fprintf(stderr,
-                            "raw_read_segment: trying Windows device with FILE_SHARE_WRITE mode\n");
-                }
-
-                cimg->fd = CreateFile(raw_info->images[idx], FILE_READ_DATA,
-                                      FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
-                                      OPEN_EXISTING, 0, NULL);
-            }
-        }
-        
-        if ( cimg->fd == INVALID_HANDLE_VALUE ) {
             int lastError = (int)GetLastError();
             cimg->fd = 0; /* so we don't close it next time */
             tsk_error_reset();
@@ -438,44 +420,30 @@ get_size(const TSK_TCHAR * a_file, uint8_t a_is_winobj)
         DWORD dwHi, dwLo;
 
         if ((fd = CreateFile(a_file, FILE_READ_DATA,
-                    FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) ==
+                    FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 
+                    OPEN_EXISTING, 0, NULL)) ==
             INVALID_HANDLE_VALUE) {
-
-            // if it is a device, try with SHARE_WRITE
-            if (a_is_winobj) {
-                if (tsk_verbose) {
-                    tsk_fprintf(stderr,
-                        "raw_open: trying Windows device with FILE_SHARE_WRITE mode\n");
-                }
-
-                fd = CreateFile(a_file, FILE_READ_DATA,
-                    FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
-                    OPEN_EXISTING, 0, NULL);
+            int lastError = (int)GetLastError();
+            tsk_error_reset();
+            tsk_error_set_errno(TSK_ERR_IMG_OPEN);
+            // print string of commonly found errors
+            if (lastError == ERROR_ACCESS_DENIED) {
+                tsk_error_set_errstr("raw_open: file \"%" PRIttocTSK
+                    "\" - access denied", a_file);
             }
-
-            if (fd == INVALID_HANDLE_VALUE) {
-                int lastError = (int)GetLastError();
-                tsk_error_reset();
-                tsk_error_set_errno(TSK_ERR_IMG_OPEN);
-                // print string of commonly found errors
-                if (lastError == ERROR_ACCESS_DENIED) {
-                    tsk_error_set_errstr("raw_open: file \"%" PRIttocTSK
-                        "\" - access denied", a_file);
-                }
-                else if (lastError == ERROR_SHARING_VIOLATION) {
-                    tsk_error_set_errstr("raw_open: file \"%" PRIttocTSK
-                        "\" - sharing violation", a_file);
-                }
-                else if (lastError == ERROR_FILE_NOT_FOUND) {
-                    tsk_error_set_errstr("raw_open: file \"%" PRIttocTSK
-                        "\" - file not found", a_file);
-                }
-                else {
-                    tsk_error_set_errstr("raw_open: file \"%" PRIttocTSK
-                        "\" - (error %d)", a_file, lastError);
-                }
-                return -2;
+            else if (lastError == ERROR_SHARING_VIOLATION) {
+                tsk_error_set_errstr("raw_open: file \"%" PRIttocTSK
+                    "\" - sharing violation", a_file);
+            }
+            else if (lastError == ERROR_FILE_NOT_FOUND) {
+                tsk_error_set_errstr("raw_open: file \"%" PRIttocTSK
+                    "\" - file not found", a_file);
             }
+            else {
+                tsk_error_set_errstr("raw_open: file \"%" PRIttocTSK
+                    "\" - (error %d)", a_file, lastError);
+            }
+            return -2;
         }
 
         /* We need different techniques to determine the size of Windows physical
diff --git a/tsk/tsk_config.h.in b/tsk/tsk_config.h.in
index 5a24f99..fead5d7 100644
--- a/tsk/tsk_config.h.in
+++ b/tsk/tsk_config.h.in
@@ -36,6 +36,9 @@
 /* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
 #undef HAVE_FSEEKO
 
+/* Define to 1 if you have the `getrusage' function. */
+#undef HAVE_GETRUSAGE
+
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
@@ -85,6 +88,9 @@
 /* Define to 1 if you have the <sys/param.h> header file. */
 #undef HAVE_SYS_PARAM_H
 
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
 /* Define to 1 if you have the <sys/select.h> header file. */
 #undef HAVE_SYS_SELECT_H
 
diff --git a/tsk/vs/Makefile.am b/tsk/vs/Makefile.am
index 4fc3fd7..b4cae5b 100644
--- a/tsk/vs/Makefile.am
+++ b/tsk/vs/Makefile.am
@@ -1,4 +1,4 @@
-AM_CFLAGS = -I../.. -I$(srcdir)/../.. -Wall 
+AM_CPPFLAGS = -I../.. -I$(srcdir)/../.. -Wall 
 EXTRA_DIST = .indent.pro
 
 noinst_LTLIBRARIES = libtskvs.la
diff --git a/tsk/vs/Makefile.in b/tsk/vs/Makefile.in
index 94772e9..1e8de7d 100644
--- a/tsk/vs/Makefile.in
+++ b/tsk/vs/Makefile.in
@@ -224,7 +224,7 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-AM_CFLAGS = -I../.. -I$(srcdir)/../.. -Wall 
+AM_CPPFLAGS = -I../.. -I$(srcdir)/../.. -Wall 
 EXTRA_DIST = .indent.pro
 noinst_LTLIBRARIES = libtskvs.la
 # Note that the .h files are in the top-level Makefile
diff --git a/win32/BUILDING.txt b/win32/BUILDING.txt
index a14e317..f0d0421 100755
--- a/win32/BUILDING.txt
+++ b/win32/BUILDING.txt
@@ -1,28 +1,32 @@
-This file describes how to build TSK using Visual Studio (see README_win32.txt for instructions on building the win32 libraries and executables from Linux).  If you do not have a copy of Visual Studio, you can use the free Express Edition:
-
-    http://www.microsoft.com/express/vc/
-
-The Visual Studio Solution file has three build targets: Debug, Debug_NoLibs, and Release.  Debug and Release require that libewf exists (to provide support for E01 image files) and that zlib exists (to provide support for HFS+ compressed data).   Debug_NoLibs does not require libewf or zlib and you should be able to compile Debug_NoLibs without any additional setup.
-
-The steps below outline the process required to compile the Debug and Release targets.
-
-1) Download libewf-20130128 (or later) from:
-    http://sourceforge.net/projects/libewf/
-
-2) Open archive file and follow the README instructions in libewf to build libewf_dll (at the time of this writing, that includes downloading the zlib dll). Note that TSK will use only the Release version of libewf_dll.  Later steps also depend on the zlib dll being built inside of libewf. 
-
-3) Set the LIBEWF_HOME environment variable to point to the libewf folder that you created and built in step 2. 
-
-4) If you want to build libtsk_jni for the Java JNI bindings, then set the JDK_HOME environment variable to point to the top directory of your Java SDK.
-
-5) Open the TSK Visual Studio Solution file, tsk-win.sln, in the win32 directory. 
-
-6) Compile a Debug, Debug_NoLibs, or Release version of the libraries and executables.  The resulting libraries and executables will be put in win32/Debug, win32/Debug_NoLibs, or win32/Release as appropriate.
-
-7) Note that the libraries and executables will depend on the libewf and zlib dll files (which are copied to the TSK build directories). 
-
-Refer to the API docs at http://sleuthkit.org/sleuthkit/docs/api-docs/ for details on how to use the library in an application.
-
--------------------------------------------------------------------
-carrier <at> sleuthkit <dot> org
-Brian Carrier
+This file describes how to build TSK using Visual Studio (see README_win32.txt for instructions on building the win32 libraries and executables from Linux).  If you do not have a copy of Visual Studio, you can use the free Express Edition:
+
+    http://www.microsoft.com/express/vc/
+
+Visual Studio 2010 Express cannot make 64-bit versions of the executables.  To do that, you must download and install an additional SDK:
+
+    http://msdn.microsoft.com/en-us/windowsserver/bb980924.aspx
+
+The Visual Studio Solution file has three build targets: Debug, Debug_NoLibs, and Release.  Debug and Release require that libewf exists (to provide support for E01 image files) and that zlib exists (to provide support for HFS+ compressed data).   Debug_NoLibs does not require libewf or zlib and you should be able to compile Debug_NoLibs without any additional setup.
+
+The steps below outline the process required to compile the Debug and Release targets.
+
+1) Download libewf-20130128 (or later) from:
+    http://sourceforge.net/projects/libewf/
+
+2) Open archive file and follow the README instructions in libewf to build libewf_dll (at the time of this writing, that includes downloading the zlib dll). Note that TSK will use only the Release version of libewf_dll.  Later steps also depend on the zlib dll being built inside of libewf.  Note that libewf will need to be converted to Visual Studio 2010 and be upgraded to support a 64-bit build.
+
+3) Set the LIBEWF_HOME environment variable to point to the libewf folder that you created and built in step 2. 
+
+4) If you want to build libtsk_jni for the Java JNI bindings, then set the JDK_HOME environment variable to point to the top directory of your Java SDK.
+
+5) Open the TSK Visual Studio Solution file, tsk-win.sln, in the win32 directory. 
+
+6) Compile a Debug, Debug_NoLibs, or Release version of the libraries and executables.  The resulting libraries and executables on a 32-bit build will be put in win32/Debug, win32/Debug_NoLibs, or win32/Release as appropriate.  A 64-bit build will put them into the win32/x64 folders. You can change the type of build using the pulldown in Visual Studio and switching between Win32 and x64.
+
+7) Note that the libraries and executables will depend on the libewf and zlib dll files (which are copied to the TSK build directories). 
+
+Refer to the API docs at http://sleuthkit.org/sleuthkit/docs/api-docs/ for details on how to use the library in an application.
+
+-------------------------------------------------------------------
+carrier <at> sleuthkit <dot> org
+Brian Carrier
diff --git a/win32/blkcalc/blkcalc.vcxproj b/win32/blkcalc/blkcalc.vcxproj
index cf7fc79..479ba7a 100755
--- a/win32/blkcalc/blkcalc.vcxproj
+++ b/win32/blkcalc/blkcalc.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{46B82840-9832-466F-8568-132407CA3853}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -82,6 +129,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -105,6 +174,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -128,6 +219,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\fstools\blkcalc.cpp" />
   </ItemGroup>
diff --git a/win32/blkcat/blkcat.vcxproj b/win32/blkcat/blkcat.vcxproj
index c3c3048..dd29129 100755
--- a/win32/blkcat/blkcat.vcxproj
+++ b/win32/blkcat/blkcat.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{A2BEA467-A4CC-4FA6-9C74-587498E35467}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -82,6 +129,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -105,6 +174,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -128,6 +219,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\fstools\blkcat.cpp" />
   </ItemGroup>
diff --git a/win32/blkls/blkls.vcxproj b/win32/blkls/blkls.vcxproj
index 61947ba..a4f606f 100755
--- a/win32/blkls/blkls.vcxproj
+++ b/win32/blkls/blkls.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{48D98A0A-BF9C-4D7E-9AF8-E4CAE8437997}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -82,6 +129,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -105,6 +174,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -128,6 +219,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\fstools\blkls.cpp" />
   </ItemGroup>
diff --git a/win32/blkstat/blkstat.vcxproj b/win32/blkstat/blkstat.vcxproj
index d4556a5..00bf187 100755
--- a/win32/blkstat/blkstat.vcxproj
+++ b/win32/blkstat/blkstat.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{FBB66156-9A54-4713-A801-C507BE7A3AE3}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -82,6 +129,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -105,6 +174,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -128,6 +219,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\fstools\blkstat.cpp" />
   </ItemGroup>
diff --git a/win32/callback-cpp-sample/callback-cpp-sample.vcxproj b/win32/callback-cpp-sample/callback-cpp-sample.vcxproj
index 73ef5b6..4eadd06 100755
--- a/win32/callback-cpp-sample/callback-cpp-sample.vcxproj
+++ b/win32/callback-cpp-sample/callback-cpp-sample.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{3B32F1BE-9686-4DC9-8197-F734D146E9F8}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -79,6 +126,25 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
@@ -102,6 +168,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -125,6 +213,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\samples\callback-cpp-style.cpp" />
   </ItemGroup>
diff --git a/win32/callback-sample/callback-sample.vcxproj b/win32/callback-sample/callback-sample.vcxproj
index 31a9115..2b1bdff 100755
--- a/win32/callback-sample/callback-sample.vcxproj
+++ b/win32/callback-sample/callback-sample.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{6CE3D593-E90D-4CC1-A66B-694AC909F6B8}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -82,6 +129,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -105,6 +174,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -128,6 +219,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\samples\callback-style.cpp" />
   </ItemGroup>
diff --git a/win32/docs/README-win32.txt b/win32/docs/README-win32.txt
index 16f6f87..aa227d2 100755
--- a/win32/docs/README-win32.txt
+++ b/win32/docs/README-win32.txt
@@ -1,60 +1,60 @@
-                          The Sleuth Kit
-                        Windows Executables
-
-                http://www.sleuthkit.org/sleuthkit
-
-               Brian Carrier [carrier at sleuthkit.org]
-
-                     Last Updated: July 2012
-
-
-======================================================================
-
-This zip file contains the Microsoft Windows executables for The Sleuth
-Kit.  The full source code (including Visual Studio Solution files) and 
-documentation can be downloaded from:
-
-http://www.sleuthkit.org
-
-These are distributed under the IBM Public License and the Common 
-Public License, which can be found in the licenses folder. 
-
-
-NOTES
-
-The dll files in the zip file are required to run the executables. They
-must be either in the same directory as the executables or in the path.
-
-There have been reports of the exe files not running on some systems
-and they give the error "The system cannot execute the specified program".
-This occurs because the system can't find the needed dll files. Installing
-the "Microsoft Visual C++ 2008 SP1 Redistributable Package (x86)" seems
-to fix the problem.  It can be downloaded from Microsoft:
-
-http://www.microsoft.com/downloads/en/confirmation.aspx?FamilyID=A5C84275-3B97-4AB7-A40D-3802B2AF5FC2&displaylang=en
-
-
-mactime.pl requires a Windows port of Perl to be installed. If you have 
-the ".pl" extension associated with Perl, you should be able to run
-"mactime.pl" from the command line. Otherwise, you may need to run it
-as "perl mactime.pl".  Examples of Windows ports of Perl include:
-- ActivePerl (http://www.activestate.com/activeperl/)
-- Strawberry Perl (http://strawberryperl.com/)
-
-
-CURRENT LIMITATIONS
-
-The tools do not currently support globbing, which means that you 
-cannot use 'fls img.*' on a split image.  Windows does not automatically
-expand the '*' to all file names.  However, most split images can now
-be used in The Sleuth Kit by simply specifying the first segment's path.
-
-These programs can be run on a live system, if you use the 
-\\.\PhysicalDrive0 syntax.  Note though, that you may get errors or the
-file system type may not be detected because the data being read is out 
-of sync with cached versions of the data.  
-
-Unicode characters are not always properly displayed in the command
-shell.
-
-The AFF image formats are not supported. 
+                          The Sleuth Kit
+                        Windows Executables
+
+                http://www.sleuthkit.org/sleuthkit
+
+               Brian Carrier [carrier at sleuthkit.org]
+
+                     Last Updated: July 2012
+
+
+======================================================================
+
+This zip file contains the Microsoft Windows executables for The Sleuth
+Kit.  The full source code (including Visual Studio Solution files) and 
+documentation can be downloaded from:
+
+http://www.sleuthkit.org
+
+These are distributed under the IBM Public License and the Common 
+Public License, which can be found in the licenses folder. 
+
+
+NOTES
+
+The dll files in the zip file are required to run the executables. They
+must be either in the same directory as the executables or in the path.
+
+There have been reports of the exe files not running on some systems
+and they give the error "The system cannot execute the specified program".
+This occurs because the system can't find the needed dll files. Installing
+the "Microsoft Visual C++ 2008 SP1 Redistributable Package (x86)" seems
+to fix the problem.  It can be downloaded from Microsoft:
+
+http://www.microsoft.com/downloads/en/confirmation.aspx?FamilyID=A5C84275-3B97-4AB7-A40D-3802B2AF5FC2&displaylang=en
+
+
+mactime.pl requires a Windows port of Perl to be installed. If you have 
+the ".pl" extension associated with Perl, you should be able to run
+"mactime.pl" from the command line. Otherwise, you may need to run it
+as "perl mactime.pl".  Examples of Windows ports of Perl include:
+- ActivePerl (http://www.activestate.com/activeperl/)
+- Strawberry Perl (http://strawberryperl.com/)
+
+
+CURRENT LIMITATIONS
+
+The tools do not currently support globbing, which means that you 
+cannot use 'fls img.*' on a split image.  Windows does not automatically
+expand the '*' to all file names.  However, most split images can now
+be used in The Sleuth Kit by simply specifying the first segment's path.
+
+These programs can be run on a live system, if you use the 
+\\.\PhysicalDrive0 syntax.  Note though, that you may get errors or the
+file system type may not be detected because the data being read is out 
+of sync with cached versions of the data.  
+
+Unicode characters are not always properly displayed in the command
+shell.
+
+The AFF image formats are not supported. 
diff --git a/win32/fcat/fcat.vcxproj b/win32/fcat/fcat.vcxproj
index 30bdb30..e70fd31 100755
--- a/win32/fcat/fcat.vcxproj
+++ b/win32/fcat/fcat.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{E4A40368-152D-4D54-9E2E-4B140212F98F}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -82,6 +129,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -105,6 +174,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -128,6 +219,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\fstools\fcat.cpp" />
   </ItemGroup>
diff --git a/win32/ffind/ffind.vcxproj b/win32/ffind/ffind.vcxproj
index df1b687..c49ea63 100755
--- a/win32/ffind/ffind.vcxproj
+++ b/win32/ffind/ffind.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{7C132953-1700-42FF-9F61-A814C9F2C758}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -82,6 +129,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -105,6 +174,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -128,6 +219,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\fstools\ffind.cpp" />
   </ItemGroup>
diff --git a/win32/fls/fls.vcxproj b/win32/fls/fls.vcxproj
index fc589da..add799a 100755
--- a/win32/fls/fls.vcxproj
+++ b/win32/fls/fls.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{58DA1042-AC19-4779-AC1A-AA8EEB3A4524}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -82,6 +129,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -105,6 +174,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -128,6 +219,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\fstools\fls.cpp" />
   </ItemGroup>
diff --git a/win32/fsstat/fsstat.vcxproj b/win32/fsstat/fsstat.vcxproj
index e0e8c66..c43c892 100755
--- a/win32/fsstat/fsstat.vcxproj
+++ b/win32/fsstat/fsstat.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{D1E6567A-4F65-4832-8018-D33B3CB4692B}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -82,6 +129,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -105,6 +174,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -128,6 +219,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\fstools\fsstat.cpp" />
   </ItemGroup>
diff --git a/win32/hfind/hfind.vcxproj b/win32/hfind/hfind.vcxproj
index 5f335e7..413b792 100755
--- a/win32/hfind/hfind.vcxproj
+++ b/win32/hfind/hfind.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{0B127AE3-0C18-4EEF-AB20-A0693E6AA822}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -82,6 +129,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -105,6 +174,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -128,6 +219,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\hashtools\hfind.cpp" />
   </ItemGroup>
diff --git a/win32/icat/icat.vcxproj b/win32/icat/icat.vcxproj
index ab5657e..93e818f 100755
--- a/win32/icat/icat.vcxproj
+++ b/win32/icat/icat.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{38D89022-2C83-4436-A333-375A2E3E7BB0}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -82,6 +129,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -105,6 +174,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -128,6 +219,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\fstools\icat.cpp" />
   </ItemGroup>
diff --git a/win32/ifind/ifind.vcxproj b/win32/ifind/ifind.vcxproj
index 09df401..0f5cd96 100755
--- a/win32/ifind/ifind.vcxproj
+++ b/win32/ifind/ifind.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{52251CB2-65A3-421B-9CB4-7DAC13BB3758}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -82,6 +129,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -105,6 +174,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -128,6 +219,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\fstools\ifind.cpp" />
   </ItemGroup>
diff --git a/win32/ils/ils.vcxproj b/win32/ils/ils.vcxproj
index f3c172f..c4bafc3 100755
--- a/win32/ils/ils.vcxproj
+++ b/win32/ils/ils.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{62C97F5E-64DD-4623-9563-747C4C173348}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -82,6 +129,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -105,6 +174,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -128,6 +219,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\fstools\ils.cpp" />
   </ItemGroup>
diff --git a/win32/img_cat/img_cat.vcxproj b/win32/img_cat/img_cat.vcxproj
index 57ce7d7..2325b9b 100755
--- a/win32/img_cat/img_cat.vcxproj
+++ b/win32/img_cat/img_cat.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{671D843F-4DFA-4CB8-8BC9-D44E7F4ECF1E}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -82,6 +129,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -105,6 +174,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -128,6 +219,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\imgtools\img_cat.cpp" />
   </ItemGroup>
diff --git a/win32/img_stat/img_stat.vcxproj b/win32/img_stat/img_stat.vcxproj
index f43d520..ed1af89 100755
--- a/win32/img_stat/img_stat.vcxproj
+++ b/win32/img_stat/img_stat.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{48F52EA8-A5D1-4BF4-B774-6ECFCB0CE3C9}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -82,6 +129,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -105,6 +174,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -128,6 +219,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\imgtools\img_stat.cpp" />
   </ItemGroup>
diff --git a/win32/istat/istat.vcxproj b/win32/istat/istat.vcxproj
index 4661a24..2d0e5c1 100755
--- a/win32/istat/istat.vcxproj
+++ b/win32/istat/istat.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{D7643AD7-8518-4B3E-8F3F-F11258D9540E}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -82,6 +129,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -105,6 +174,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -128,6 +219,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\fstools\istat.cpp" />
   </ItemGroup>
diff --git a/win32/jcat/jcat.vcxproj b/win32/jcat/jcat.vcxproj
index 6225198..19a97f3 100755
--- a/win32/jcat/jcat.vcxproj
+++ b/win32/jcat/jcat.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{44A003BE-400D-4434-AFED-64D8E3B448D9}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -82,6 +129,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -105,6 +174,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -128,6 +219,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\fstools\jcat.cpp" />
   </ItemGroup>
diff --git a/win32/jls/jls.vcxproj b/win32/jls/jls.vcxproj
index 8b9cf63..bd50a0f 100755
--- a/win32/jls/jls.vcxproj
+++ b/win32/jls/jls.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{C52F935E-1FD2-443C-A181-27908DAB3BC8}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -82,6 +129,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -105,6 +174,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -128,6 +219,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\fstools\jls.cpp" />
   </ItemGroup>
diff --git a/win32/libtsk/libtsk.vcxproj b/win32/libtsk/libtsk.vcxproj
index e2fdf54..3fdc1ef 100755
--- a/win32/libtsk/libtsk.vcxproj
+++ b/win32/libtsk/libtsk.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{76EFC06C-1F64-4478-ABE8-79832716B393}</ProjectGuid>
@@ -24,36 +36,68 @@
     <ConfigurationType>StaticLibrary</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>StaticLibrary</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -74,6 +118,24 @@ copy "$(LIBEWF_HOME)\msvscpp\release\zlib.dll" "$(OutDir)"
 </Command>
     </PostBuildEvent>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;$(LIBEWF_HOME)\common;$(LIBEWF_HOME)\include;$(LIBEWF_HOME)\..\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;HAVE_LIBEWF;HAVE_LIBZ;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <PostBuildEvent>
+      <Command>copy "$(LIBEWF_HOME)\msvscpp\x64\release\libewf.dll" "$(OutDir)"
+copy "$(LIBEWF_HOME)\msvscpp\x64\release\zlib.dll" "$(OutDir)"
+</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
@@ -93,6 +155,25 @@ copy "$(LIBEWF_HOME)\msvscpp\release\zlib.dll" "$(OutDir)"
 </Command>
     </PostBuildEvent>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;$(LIBEWF_HOME)\common;$(LIBEWF_HOME)\include;$(LIBEWF_HOME)\..\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;HAVE_LIBEWF;HAVE_LIBZ;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <PostBuildEvent>
+      <Command>copy "$(LIBEWF_HOME)\msvscpp\x64\release\libewf.dll" "$(OutDir)"
+copy "$(LIBEWF_HOME)\msvscpp\x64\release\zlib.dll" "$(OutDir)"
+</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -107,6 +188,19 @@ copy "$(LIBEWF_HOME)\msvscpp\release\zlib.dll" "$(OutDir)"
       <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
     </ClCompile>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tsk\vs\bsd.c" />
     <ClCompile Include="..\..\tsk\vs\dos.c" />
@@ -229,4 +323,4 @@ copy "$(LIBEWF_HOME)\msvscpp\release\zlib.dll" "$(OutDir)"
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
diff --git a/win32/mmcat/mmcat.vcxproj b/win32/mmcat/mmcat.vcxproj
index 625830e..6632b84 100755
--- a/win32/mmcat/mmcat.vcxproj
+++ b/win32/mmcat/mmcat.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{A15F1E4F-951A-403E-B746-2A6D63D9C416}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -82,6 +129,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -105,6 +174,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -128,6 +219,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\vstools\mmcat.cpp" />
   </ItemGroup>
diff --git a/win32/mmls/mmls.vcxproj b/win32/mmls/mmls.vcxproj
index fd7549e..7347028 100755
--- a/win32/mmls/mmls.vcxproj
+++ b/win32/mmls/mmls.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{712DD83B-786E-485E-83C7-7197DD851B78}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -82,6 +129,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -105,6 +174,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -128,6 +219,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\vstools\mmls.cpp" />
   </ItemGroup>
diff --git a/win32/mmstat/mmstat.vcxproj b/win32/mmstat/mmstat.vcxproj
index 7ed19ed..45ac986 100755
--- a/win32/mmstat/mmstat.vcxproj
+++ b/win32/mmstat/mmstat.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{5D75FBFB-539A-4014-ACEB-520BB16F5BFC}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -82,6 +129,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -105,6 +174,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -128,6 +219,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\vstools\mmstat.cpp" />
   </ItemGroup>
diff --git a/win32/posix-cpp-sample/posix-cpp-sample.vcxproj b/win32/posix-cpp-sample/posix-cpp-sample.vcxproj
index af0a65e..8625bcc 100755
--- a/win32/posix-cpp-sample/posix-cpp-sample.vcxproj
+++ b/win32/posix-cpp-sample/posix-cpp-sample.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{5594DC0E-191C-4F2A-83FE-97F53A9C1222}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -79,6 +126,25 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
@@ -102,6 +168,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -122,6 +210,24 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\samples\posix-cpp-style.cpp" />
   </ItemGroup>
diff --git a/win32/posix-sample/posix-sample.vcxproj b/win32/posix-sample/posix-sample.vcxproj
index 5a1effd..0b42251 100755
--- a/win32/posix-sample/posix-sample.vcxproj
+++ b/win32/posix-sample/posix-sample.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{1BA0B9E8-F135-494F-9CF5-86427C1F6E41}</ProjectGuid>
@@ -24,39 +36,74 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -82,6 +129,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -105,6 +174,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -128,6 +219,27 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\samples\posix-style.cpp" />
   </ItemGroup>
diff --git a/win32/tsk-win.sln b/win32/tsk-win.sln
index 9905bc0..b9e77fc 100644
--- a/win32/tsk-win.sln
+++ b/win32/tsk-win.sln
@@ -64,190 +64,373 @@ EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug_NoLibs|Win32 = Debug_NoLibs|Win32
+		Debug_NoLibs|x64 = Debug_NoLibs|x64
 		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
 		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 		{48F52EA8-A5D1-4BF4-B774-6ECFCB0CE3C9}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{48F52EA8-A5D1-4BF4-B774-6ECFCB0CE3C9}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{48F52EA8-A5D1-4BF4-B774-6ECFCB0CE3C9}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{48F52EA8-A5D1-4BF4-B774-6ECFCB0CE3C9}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{48F52EA8-A5D1-4BF4-B774-6ECFCB0CE3C9}.Debug|Win32.ActiveCfg = Debug|Win32
 		{48F52EA8-A5D1-4BF4-B774-6ECFCB0CE3C9}.Debug|Win32.Build.0 = Debug|Win32
+		{48F52EA8-A5D1-4BF4-B774-6ECFCB0CE3C9}.Debug|x64.ActiveCfg = Debug|x64
+		{48F52EA8-A5D1-4BF4-B774-6ECFCB0CE3C9}.Debug|x64.Build.0 = Debug|x64
 		{48F52EA8-A5D1-4BF4-B774-6ECFCB0CE3C9}.Release|Win32.ActiveCfg = Release|Win32
 		{48F52EA8-A5D1-4BF4-B774-6ECFCB0CE3C9}.Release|Win32.Build.0 = Release|Win32
+		{48F52EA8-A5D1-4BF4-B774-6ECFCB0CE3C9}.Release|x64.ActiveCfg = Release|x64
+		{48F52EA8-A5D1-4BF4-B774-6ECFCB0CE3C9}.Release|x64.Build.0 = Release|x64
 		{712DD83B-786E-485E-83C7-7197DD851B78}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{712DD83B-786E-485E-83C7-7197DD851B78}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{712DD83B-786E-485E-83C7-7197DD851B78}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{712DD83B-786E-485E-83C7-7197DD851B78}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{712DD83B-786E-485E-83C7-7197DD851B78}.Debug|Win32.ActiveCfg = Debug|Win32
 		{712DD83B-786E-485E-83C7-7197DD851B78}.Debug|Win32.Build.0 = Debug|Win32
+		{712DD83B-786E-485E-83C7-7197DD851B78}.Debug|x64.ActiveCfg = Debug|x64
+		{712DD83B-786E-485E-83C7-7197DD851B78}.Debug|x64.Build.0 = Debug|x64
 		{712DD83B-786E-485E-83C7-7197DD851B78}.Release|Win32.ActiveCfg = Release|Win32
 		{712DD83B-786E-485E-83C7-7197DD851B78}.Release|Win32.Build.0 = Release|Win32
+		{712DD83B-786E-485E-83C7-7197DD851B78}.Release|x64.ActiveCfg = Release|x64
+		{712DD83B-786E-485E-83C7-7197DD851B78}.Release|x64.Build.0 = Release|x64
 		{671D843F-4DFA-4CB8-8BC9-D44E7F4ECF1E}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{671D843F-4DFA-4CB8-8BC9-D44E7F4ECF1E}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{671D843F-4DFA-4CB8-8BC9-D44E7F4ECF1E}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{671D843F-4DFA-4CB8-8BC9-D44E7F4ECF1E}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{671D843F-4DFA-4CB8-8BC9-D44E7F4ECF1E}.Debug|Win32.ActiveCfg = Debug|Win32
 		{671D843F-4DFA-4CB8-8BC9-D44E7F4ECF1E}.Debug|Win32.Build.0 = Debug|Win32
+		{671D843F-4DFA-4CB8-8BC9-D44E7F4ECF1E}.Debug|x64.ActiveCfg = Debug|x64
+		{671D843F-4DFA-4CB8-8BC9-D44E7F4ECF1E}.Debug|x64.Build.0 = Debug|x64
 		{671D843F-4DFA-4CB8-8BC9-D44E7F4ECF1E}.Release|Win32.ActiveCfg = Release|Win32
 		{671D843F-4DFA-4CB8-8BC9-D44E7F4ECF1E}.Release|Win32.Build.0 = Release|Win32
+		{671D843F-4DFA-4CB8-8BC9-D44E7F4ECF1E}.Release|x64.ActiveCfg = Release|x64
+		{671D843F-4DFA-4CB8-8BC9-D44E7F4ECF1E}.Release|x64.Build.0 = Release|x64
 		{5D75FBFB-539A-4014-ACEB-520BB16F5BFC}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{5D75FBFB-539A-4014-ACEB-520BB16F5BFC}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{5D75FBFB-539A-4014-ACEB-520BB16F5BFC}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{5D75FBFB-539A-4014-ACEB-520BB16F5BFC}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{5D75FBFB-539A-4014-ACEB-520BB16F5BFC}.Debug|Win32.ActiveCfg = Debug|Win32
 		{5D75FBFB-539A-4014-ACEB-520BB16F5BFC}.Debug|Win32.Build.0 = Debug|Win32
+		{5D75FBFB-539A-4014-ACEB-520BB16F5BFC}.Debug|x64.ActiveCfg = Debug|x64
+		{5D75FBFB-539A-4014-ACEB-520BB16F5BFC}.Debug|x64.Build.0 = Debug|x64
 		{5D75FBFB-539A-4014-ACEB-520BB16F5BFC}.Release|Win32.ActiveCfg = Release|Win32
 		{5D75FBFB-539A-4014-ACEB-520BB16F5BFC}.Release|Win32.Build.0 = Release|Win32
+		{5D75FBFB-539A-4014-ACEB-520BB16F5BFC}.Release|x64.ActiveCfg = Release|x64
+		{5D75FBFB-539A-4014-ACEB-520BB16F5BFC}.Release|x64.Build.0 = Release|x64
 		{58DA1042-AC19-4779-AC1A-AA8EEB3A4524}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{58DA1042-AC19-4779-AC1A-AA8EEB3A4524}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{58DA1042-AC19-4779-AC1A-AA8EEB3A4524}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{58DA1042-AC19-4779-AC1A-AA8EEB3A4524}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{58DA1042-AC19-4779-AC1A-AA8EEB3A4524}.Debug|Win32.ActiveCfg = Debug|Win32
 		{58DA1042-AC19-4779-AC1A-AA8EEB3A4524}.Debug|Win32.Build.0 = Debug|Win32
+		{58DA1042-AC19-4779-AC1A-AA8EEB3A4524}.Debug|x64.ActiveCfg = Debug|x64
+		{58DA1042-AC19-4779-AC1A-AA8EEB3A4524}.Debug|x64.Build.0 = Debug|x64
 		{58DA1042-AC19-4779-AC1A-AA8EEB3A4524}.Release|Win32.ActiveCfg = Release|Win32
 		{58DA1042-AC19-4779-AC1A-AA8EEB3A4524}.Release|Win32.Build.0 = Release|Win32
+		{58DA1042-AC19-4779-AC1A-AA8EEB3A4524}.Release|x64.ActiveCfg = Release|x64
+		{58DA1042-AC19-4779-AC1A-AA8EEB3A4524}.Release|x64.Build.0 = Release|x64
 		{D1E6567A-4F65-4832-8018-D33B3CB4692B}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{D1E6567A-4F65-4832-8018-D33B3CB4692B}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{D1E6567A-4F65-4832-8018-D33B3CB4692B}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{D1E6567A-4F65-4832-8018-D33B3CB4692B}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{D1E6567A-4F65-4832-8018-D33B3CB4692B}.Debug|Win32.ActiveCfg = Debug|Win32
 		{D1E6567A-4F65-4832-8018-D33B3CB4692B}.Debug|Win32.Build.0 = Debug|Win32
+		{D1E6567A-4F65-4832-8018-D33B3CB4692B}.Debug|x64.ActiveCfg = Debug|x64
+		{D1E6567A-4F65-4832-8018-D33B3CB4692B}.Debug|x64.Build.0 = Debug|x64
 		{D1E6567A-4F65-4832-8018-D33B3CB4692B}.Release|Win32.ActiveCfg = Release|Win32
 		{D1E6567A-4F65-4832-8018-D33B3CB4692B}.Release|Win32.Build.0 = Release|Win32
+		{D1E6567A-4F65-4832-8018-D33B3CB4692B}.Release|x64.ActiveCfg = Release|x64
+		{D1E6567A-4F65-4832-8018-D33B3CB4692B}.Release|x64.Build.0 = Release|x64
 		{A2BEA467-A4CC-4FA6-9C74-587498E35467}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{A2BEA467-A4CC-4FA6-9C74-587498E35467}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{A2BEA467-A4CC-4FA6-9C74-587498E35467}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{A2BEA467-A4CC-4FA6-9C74-587498E35467}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{A2BEA467-A4CC-4FA6-9C74-587498E35467}.Debug|Win32.ActiveCfg = Debug|Win32
 		{A2BEA467-A4CC-4FA6-9C74-587498E35467}.Debug|Win32.Build.0 = Debug|Win32
+		{A2BEA467-A4CC-4FA6-9C74-587498E35467}.Debug|x64.ActiveCfg = Debug|x64
+		{A2BEA467-A4CC-4FA6-9C74-587498E35467}.Debug|x64.Build.0 = Debug|x64
 		{A2BEA467-A4CC-4FA6-9C74-587498E35467}.Release|Win32.ActiveCfg = Release|Win32
 		{A2BEA467-A4CC-4FA6-9C74-587498E35467}.Release|Win32.Build.0 = Release|Win32
+		{A2BEA467-A4CC-4FA6-9C74-587498E35467}.Release|x64.ActiveCfg = Release|x64
+		{A2BEA467-A4CC-4FA6-9C74-587498E35467}.Release|x64.Build.0 = Release|x64
 		{FBB66156-9A54-4713-A801-C507BE7A3AE3}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{FBB66156-9A54-4713-A801-C507BE7A3AE3}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{FBB66156-9A54-4713-A801-C507BE7A3AE3}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{FBB66156-9A54-4713-A801-C507BE7A3AE3}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{FBB66156-9A54-4713-A801-C507BE7A3AE3}.Debug|Win32.ActiveCfg = Debug|Win32
 		{FBB66156-9A54-4713-A801-C507BE7A3AE3}.Debug|Win32.Build.0 = Debug|Win32
+		{FBB66156-9A54-4713-A801-C507BE7A3AE3}.Debug|x64.ActiveCfg = Debug|x64
+		{FBB66156-9A54-4713-A801-C507BE7A3AE3}.Debug|x64.Build.0 = Debug|x64
 		{FBB66156-9A54-4713-A801-C507BE7A3AE3}.Release|Win32.ActiveCfg = Release|Win32
 		{FBB66156-9A54-4713-A801-C507BE7A3AE3}.Release|Win32.Build.0 = Release|Win32
+		{FBB66156-9A54-4713-A801-C507BE7A3AE3}.Release|x64.ActiveCfg = Release|x64
+		{FBB66156-9A54-4713-A801-C507BE7A3AE3}.Release|x64.Build.0 = Release|x64
 		{46B82840-9832-466F-8568-132407CA3853}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{46B82840-9832-466F-8568-132407CA3853}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{46B82840-9832-466F-8568-132407CA3853}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{46B82840-9832-466F-8568-132407CA3853}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{46B82840-9832-466F-8568-132407CA3853}.Debug|Win32.ActiveCfg = Debug|Win32
 		{46B82840-9832-466F-8568-132407CA3853}.Debug|Win32.Build.0 = Debug|Win32
+		{46B82840-9832-466F-8568-132407CA3853}.Debug|x64.ActiveCfg = Debug|x64
+		{46B82840-9832-466F-8568-132407CA3853}.Debug|x64.Build.0 = Debug|x64
 		{46B82840-9832-466F-8568-132407CA3853}.Release|Win32.ActiveCfg = Release|Win32
 		{46B82840-9832-466F-8568-132407CA3853}.Release|Win32.Build.0 = Release|Win32
+		{46B82840-9832-466F-8568-132407CA3853}.Release|x64.ActiveCfg = Release|x64
+		{46B82840-9832-466F-8568-132407CA3853}.Release|x64.Build.0 = Release|x64
 		{48D98A0A-BF9C-4D7E-9AF8-E4CAE8437997}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{48D98A0A-BF9C-4D7E-9AF8-E4CAE8437997}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{48D98A0A-BF9C-4D7E-9AF8-E4CAE8437997}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{48D98A0A-BF9C-4D7E-9AF8-E4CAE8437997}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{48D98A0A-BF9C-4D7E-9AF8-E4CAE8437997}.Debug|Win32.ActiveCfg = Debug|Win32
 		{48D98A0A-BF9C-4D7E-9AF8-E4CAE8437997}.Debug|Win32.Build.0 = Debug|Win32
+		{48D98A0A-BF9C-4D7E-9AF8-E4CAE8437997}.Debug|x64.ActiveCfg = Debug|x64
+		{48D98A0A-BF9C-4D7E-9AF8-E4CAE8437997}.Debug|x64.Build.0 = Debug|x64
 		{48D98A0A-BF9C-4D7E-9AF8-E4CAE8437997}.Release|Win32.ActiveCfg = Release|Win32
 		{48D98A0A-BF9C-4D7E-9AF8-E4CAE8437997}.Release|Win32.Build.0 = Release|Win32
+		{48D98A0A-BF9C-4D7E-9AF8-E4CAE8437997}.Release|x64.ActiveCfg = Release|x64
+		{48D98A0A-BF9C-4D7E-9AF8-E4CAE8437997}.Release|x64.Build.0 = Release|x64
 		{7C132953-1700-42FF-9F61-A814C9F2C758}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{7C132953-1700-42FF-9F61-A814C9F2C758}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{7C132953-1700-42FF-9F61-A814C9F2C758}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{7C132953-1700-42FF-9F61-A814C9F2C758}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{7C132953-1700-42FF-9F61-A814C9F2C758}.Debug|Win32.ActiveCfg = Debug|Win32
 		{7C132953-1700-42FF-9F61-A814C9F2C758}.Debug|Win32.Build.0 = Debug|Win32
+		{7C132953-1700-42FF-9F61-A814C9F2C758}.Debug|x64.ActiveCfg = Debug|x64
+		{7C132953-1700-42FF-9F61-A814C9F2C758}.Debug|x64.Build.0 = Debug|x64
 		{7C132953-1700-42FF-9F61-A814C9F2C758}.Release|Win32.ActiveCfg = Release|Win32
 		{7C132953-1700-42FF-9F61-A814C9F2C758}.Release|Win32.Build.0 = Release|Win32
+		{7C132953-1700-42FF-9F61-A814C9F2C758}.Release|x64.ActiveCfg = Release|x64
+		{7C132953-1700-42FF-9F61-A814C9F2C758}.Release|x64.Build.0 = Release|x64
 		{38D89022-2C83-4436-A333-375A2E3E7BB0}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{38D89022-2C83-4436-A333-375A2E3E7BB0}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{38D89022-2C83-4436-A333-375A2E3E7BB0}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{38D89022-2C83-4436-A333-375A2E3E7BB0}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{38D89022-2C83-4436-A333-375A2E3E7BB0}.Debug|Win32.ActiveCfg = Debug|Win32
 		{38D89022-2C83-4436-A333-375A2E3E7BB0}.Debug|Win32.Build.0 = Debug|Win32
+		{38D89022-2C83-4436-A333-375A2E3E7BB0}.Debug|x64.ActiveCfg = Debug|x64
+		{38D89022-2C83-4436-A333-375A2E3E7BB0}.Debug|x64.Build.0 = Debug|x64
 		{38D89022-2C83-4436-A333-375A2E3E7BB0}.Release|Win32.ActiveCfg = Release|Win32
 		{38D89022-2C83-4436-A333-375A2E3E7BB0}.Release|Win32.Build.0 = Release|Win32
+		{38D89022-2C83-4436-A333-375A2E3E7BB0}.Release|x64.ActiveCfg = Release|x64
+		{38D89022-2C83-4436-A333-375A2E3E7BB0}.Release|x64.Build.0 = Release|x64
 		{52251CB2-65A3-421B-9CB4-7DAC13BB3758}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{52251CB2-65A3-421B-9CB4-7DAC13BB3758}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{52251CB2-65A3-421B-9CB4-7DAC13BB3758}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{52251CB2-65A3-421B-9CB4-7DAC13BB3758}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{52251CB2-65A3-421B-9CB4-7DAC13BB3758}.Debug|Win32.ActiveCfg = Debug|Win32
 		{52251CB2-65A3-421B-9CB4-7DAC13BB3758}.Debug|Win32.Build.0 = Debug|Win32
+		{52251CB2-65A3-421B-9CB4-7DAC13BB3758}.Debug|x64.ActiveCfg = Debug|x64
+		{52251CB2-65A3-421B-9CB4-7DAC13BB3758}.Debug|x64.Build.0 = Debug|x64
 		{52251CB2-65A3-421B-9CB4-7DAC13BB3758}.Release|Win32.ActiveCfg = Release|Win32
 		{52251CB2-65A3-421B-9CB4-7DAC13BB3758}.Release|Win32.Build.0 = Release|Win32
+		{52251CB2-65A3-421B-9CB4-7DAC13BB3758}.Release|x64.ActiveCfg = Release|x64
+		{52251CB2-65A3-421B-9CB4-7DAC13BB3758}.Release|x64.Build.0 = Release|x64
 		{62C97F5E-64DD-4623-9563-747C4C173348}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{62C97F5E-64DD-4623-9563-747C4C173348}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{62C97F5E-64DD-4623-9563-747C4C173348}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{62C97F5E-64DD-4623-9563-747C4C173348}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{62C97F5E-64DD-4623-9563-747C4C173348}.Debug|Win32.ActiveCfg = Debug|Win32
 		{62C97F5E-64DD-4623-9563-747C4C173348}.Debug|Win32.Build.0 = Debug|Win32
+		{62C97F5E-64DD-4623-9563-747C4C173348}.Debug|x64.ActiveCfg = Debug|x64
+		{62C97F5E-64DD-4623-9563-747C4C173348}.Debug|x64.Build.0 = Debug|x64
 		{62C97F5E-64DD-4623-9563-747C4C173348}.Release|Win32.ActiveCfg = Release|Win32
 		{62C97F5E-64DD-4623-9563-747C4C173348}.Release|Win32.Build.0 = Release|Win32
+		{62C97F5E-64DD-4623-9563-747C4C173348}.Release|x64.ActiveCfg = Release|x64
+		{62C97F5E-64DD-4623-9563-747C4C173348}.Release|x64.Build.0 = Release|x64
 		{D7643AD7-8518-4B3E-8F3F-F11258D9540E}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{D7643AD7-8518-4B3E-8F3F-F11258D9540E}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{D7643AD7-8518-4B3E-8F3F-F11258D9540E}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{D7643AD7-8518-4B3E-8F3F-F11258D9540E}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{D7643AD7-8518-4B3E-8F3F-F11258D9540E}.Debug|Win32.ActiveCfg = Debug|Win32
 		{D7643AD7-8518-4B3E-8F3F-F11258D9540E}.Debug|Win32.Build.0 = Debug|Win32
+		{D7643AD7-8518-4B3E-8F3F-F11258D9540E}.Debug|x64.ActiveCfg = Debug|x64
+		{D7643AD7-8518-4B3E-8F3F-F11258D9540E}.Debug|x64.Build.0 = Debug|x64
 		{D7643AD7-8518-4B3E-8F3F-F11258D9540E}.Release|Win32.ActiveCfg = Release|Win32
 		{D7643AD7-8518-4B3E-8F3F-F11258D9540E}.Release|Win32.Build.0 = Release|Win32
+		{D7643AD7-8518-4B3E-8F3F-F11258D9540E}.Release|x64.ActiveCfg = Release|x64
+		{D7643AD7-8518-4B3E-8F3F-F11258D9540E}.Release|x64.Build.0 = Release|x64
 		{44A003BE-400D-4434-AFED-64D8E3B448D9}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{44A003BE-400D-4434-AFED-64D8E3B448D9}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{44A003BE-400D-4434-AFED-64D8E3B448D9}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{44A003BE-400D-4434-AFED-64D8E3B448D9}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{44A003BE-400D-4434-AFED-64D8E3B448D9}.Debug|Win32.ActiveCfg = Debug|Win32
 		{44A003BE-400D-4434-AFED-64D8E3B448D9}.Debug|Win32.Build.0 = Debug|Win32
+		{44A003BE-400D-4434-AFED-64D8E3B448D9}.Debug|x64.ActiveCfg = Debug|x64
+		{44A003BE-400D-4434-AFED-64D8E3B448D9}.Debug|x64.Build.0 = Debug|x64
 		{44A003BE-400D-4434-AFED-64D8E3B448D9}.Release|Win32.ActiveCfg = Release|Win32
 		{44A003BE-400D-4434-AFED-64D8E3B448D9}.Release|Win32.Build.0 = Release|Win32
+		{44A003BE-400D-4434-AFED-64D8E3B448D9}.Release|x64.ActiveCfg = Release|x64
+		{44A003BE-400D-4434-AFED-64D8E3B448D9}.Release|x64.Build.0 = Release|x64
 		{C52F935E-1FD2-443C-A181-27908DAB3BC8}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{C52F935E-1FD2-443C-A181-27908DAB3BC8}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{C52F935E-1FD2-443C-A181-27908DAB3BC8}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{C52F935E-1FD2-443C-A181-27908DAB3BC8}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{C52F935E-1FD2-443C-A181-27908DAB3BC8}.Debug|Win32.ActiveCfg = Debug|Win32
 		{C52F935E-1FD2-443C-A181-27908DAB3BC8}.Debug|Win32.Build.0 = Debug|Win32
+		{C52F935E-1FD2-443C-A181-27908DAB3BC8}.Debug|x64.ActiveCfg = Debug|x64
+		{C52F935E-1FD2-443C-A181-27908DAB3BC8}.Debug|x64.Build.0 = Debug|x64
 		{C52F935E-1FD2-443C-A181-27908DAB3BC8}.Release|Win32.ActiveCfg = Release|Win32
 		{C52F935E-1FD2-443C-A181-27908DAB3BC8}.Release|Win32.Build.0 = Release|Win32
+		{C52F935E-1FD2-443C-A181-27908DAB3BC8}.Release|x64.ActiveCfg = Release|x64
+		{C52F935E-1FD2-443C-A181-27908DAB3BC8}.Release|x64.Build.0 = Release|x64
 		{0B127AE3-0C18-4EEF-AB20-A0693E6AA822}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{0B127AE3-0C18-4EEF-AB20-A0693E6AA822}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{0B127AE3-0C18-4EEF-AB20-A0693E6AA822}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{0B127AE3-0C18-4EEF-AB20-A0693E6AA822}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{0B127AE3-0C18-4EEF-AB20-A0693E6AA822}.Debug|Win32.ActiveCfg = Debug|Win32
 		{0B127AE3-0C18-4EEF-AB20-A0693E6AA822}.Debug|Win32.Build.0 = Debug|Win32
+		{0B127AE3-0C18-4EEF-AB20-A0693E6AA822}.Debug|x64.ActiveCfg = Debug|x64
+		{0B127AE3-0C18-4EEF-AB20-A0693E6AA822}.Debug|x64.Build.0 = Debug|x64
 		{0B127AE3-0C18-4EEF-AB20-A0693E6AA822}.Release|Win32.ActiveCfg = Release|Win32
 		{0B127AE3-0C18-4EEF-AB20-A0693E6AA822}.Release|Win32.Build.0 = Release|Win32
+		{0B127AE3-0C18-4EEF-AB20-A0693E6AA822}.Release|x64.ActiveCfg = Release|x64
+		{0B127AE3-0C18-4EEF-AB20-A0693E6AA822}.Release|x64.Build.0 = Release|x64
 		{A15F1E4F-951A-403E-B746-2A6D63D9C416}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{A15F1E4F-951A-403E-B746-2A6D63D9C416}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{A15F1E4F-951A-403E-B746-2A6D63D9C416}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{A15F1E4F-951A-403E-B746-2A6D63D9C416}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{A15F1E4F-951A-403E-B746-2A6D63D9C416}.Debug|Win32.ActiveCfg = Debug|Win32
 		{A15F1E4F-951A-403E-B746-2A6D63D9C416}.Debug|Win32.Build.0 = Debug|Win32
+		{A15F1E4F-951A-403E-B746-2A6D63D9C416}.Debug|x64.ActiveCfg = Debug|x64
+		{A15F1E4F-951A-403E-B746-2A6D63D9C416}.Debug|x64.Build.0 = Debug|x64
 		{A15F1E4F-951A-403E-B746-2A6D63D9C416}.Release|Win32.ActiveCfg = Release|Win32
 		{A15F1E4F-951A-403E-B746-2A6D63D9C416}.Release|Win32.Build.0 = Release|Win32
+		{A15F1E4F-951A-403E-B746-2A6D63D9C416}.Release|x64.ActiveCfg = Release|x64
+		{A15F1E4F-951A-403E-B746-2A6D63D9C416}.Release|x64.Build.0 = Release|x64
 		{6CE3D593-E90D-4CC1-A66B-694AC909F6B8}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{6CE3D593-E90D-4CC1-A66B-694AC909F6B8}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{6CE3D593-E90D-4CC1-A66B-694AC909F6B8}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{6CE3D593-E90D-4CC1-A66B-694AC909F6B8}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{6CE3D593-E90D-4CC1-A66B-694AC909F6B8}.Debug|Win32.ActiveCfg = Debug|Win32
 		{6CE3D593-E90D-4CC1-A66B-694AC909F6B8}.Debug|Win32.Build.0 = Debug|Win32
+		{6CE3D593-E90D-4CC1-A66B-694AC909F6B8}.Debug|x64.ActiveCfg = Debug|x64
+		{6CE3D593-E90D-4CC1-A66B-694AC909F6B8}.Debug|x64.Build.0 = Debug|x64
 		{6CE3D593-E90D-4CC1-A66B-694AC909F6B8}.Release|Win32.ActiveCfg = Release|Win32
 		{6CE3D593-E90D-4CC1-A66B-694AC909F6B8}.Release|Win32.Build.0 = Release|Win32
+		{6CE3D593-E90D-4CC1-A66B-694AC909F6B8}.Release|x64.ActiveCfg = Release|x64
+		{6CE3D593-E90D-4CC1-A66B-694AC909F6B8}.Release|x64.Build.0 = Release|x64
 		{1BA0B9E8-F135-494F-9CF5-86427C1F6E41}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{1BA0B9E8-F135-494F-9CF5-86427C1F6E41}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{1BA0B9E8-F135-494F-9CF5-86427C1F6E41}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{1BA0B9E8-F135-494F-9CF5-86427C1F6E41}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{1BA0B9E8-F135-494F-9CF5-86427C1F6E41}.Debug|Win32.ActiveCfg = Debug|Win32
 		{1BA0B9E8-F135-494F-9CF5-86427C1F6E41}.Debug|Win32.Build.0 = Debug|Win32
+		{1BA0B9E8-F135-494F-9CF5-86427C1F6E41}.Debug|x64.ActiveCfg = Debug|x64
+		{1BA0B9E8-F135-494F-9CF5-86427C1F6E41}.Debug|x64.Build.0 = Debug|x64
 		{1BA0B9E8-F135-494F-9CF5-86427C1F6E41}.Release|Win32.ActiveCfg = Release|Win32
 		{1BA0B9E8-F135-494F-9CF5-86427C1F6E41}.Release|Win32.Build.0 = Release|Win32
+		{1BA0B9E8-F135-494F-9CF5-86427C1F6E41}.Release|x64.ActiveCfg = Release|x64
+		{1BA0B9E8-F135-494F-9CF5-86427C1F6E41}.Release|x64.Build.0 = Release|x64
 		{06D707E5-68FF-4FC4-AFD0-C84584E32F47}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{06D707E5-68FF-4FC4-AFD0-C84584E32F47}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{06D707E5-68FF-4FC4-AFD0-C84584E32F47}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{06D707E5-68FF-4FC4-AFD0-C84584E32F47}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{06D707E5-68FF-4FC4-AFD0-C84584E32F47}.Debug|Win32.ActiveCfg = Debug|Win32
 		{06D707E5-68FF-4FC4-AFD0-C84584E32F47}.Debug|Win32.Build.0 = Debug|Win32
+		{06D707E5-68FF-4FC4-AFD0-C84584E32F47}.Debug|x64.ActiveCfg = Debug|x64
+		{06D707E5-68FF-4FC4-AFD0-C84584E32F47}.Debug|x64.Build.0 = Debug|x64
 		{06D707E5-68FF-4FC4-AFD0-C84584E32F47}.Release|Win32.ActiveCfg = Release|Win32
 		{06D707E5-68FF-4FC4-AFD0-C84584E32F47}.Release|Win32.Build.0 = Release|Win32
+		{06D707E5-68FF-4FC4-AFD0-C84584E32F47}.Release|x64.ActiveCfg = Release|x64
+		{06D707E5-68FF-4FC4-AFD0-C84584E32F47}.Release|x64.Build.0 = Release|x64
 		{96AFC6D4-A3DC-44D4-8F55-F74E1D21798C}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{96AFC6D4-A3DC-44D4-8F55-F74E1D21798C}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{96AFC6D4-A3DC-44D4-8F55-F74E1D21798C}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{96AFC6D4-A3DC-44D4-8F55-F74E1D21798C}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{96AFC6D4-A3DC-44D4-8F55-F74E1D21798C}.Debug|Win32.ActiveCfg = Debug|Win32
 		{96AFC6D4-A3DC-44D4-8F55-F74E1D21798C}.Debug|Win32.Build.0 = Debug|Win32
+		{96AFC6D4-A3DC-44D4-8F55-F74E1D21798C}.Debug|x64.ActiveCfg = Debug|x64
+		{96AFC6D4-A3DC-44D4-8F55-F74E1D21798C}.Debug|x64.Build.0 = Debug|x64
 		{96AFC6D4-A3DC-44D4-8F55-F74E1D21798C}.Release|Win32.ActiveCfg = Release|Win32
 		{96AFC6D4-A3DC-44D4-8F55-F74E1D21798C}.Release|Win32.Build.0 = Release|Win32
+		{96AFC6D4-A3DC-44D4-8F55-F74E1D21798C}.Release|x64.ActiveCfg = Release|x64
+		{96AFC6D4-A3DC-44D4-8F55-F74E1D21798C}.Release|x64.Build.0 = Release|x64
 		{8EE881F4-78DC-49C7-8845-E842358AC0FA}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{8EE881F4-78DC-49C7-8845-E842358AC0FA}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{8EE881F4-78DC-49C7-8845-E842358AC0FA}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{8EE881F4-78DC-49C7-8845-E842358AC0FA}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{8EE881F4-78DC-49C7-8845-E842358AC0FA}.Debug|Win32.ActiveCfg = Debug|Win32
 		{8EE881F4-78DC-49C7-8845-E842358AC0FA}.Debug|Win32.Build.0 = Debug|Win32
+		{8EE881F4-78DC-49C7-8845-E842358AC0FA}.Debug|x64.ActiveCfg = Debug|x64
+		{8EE881F4-78DC-49C7-8845-E842358AC0FA}.Debug|x64.Build.0 = Debug|x64
 		{8EE881F4-78DC-49C7-8845-E842358AC0FA}.Release|Win32.ActiveCfg = Release|Win32
 		{8EE881F4-78DC-49C7-8845-E842358AC0FA}.Release|Win32.Build.0 = Release|Win32
+		{8EE881F4-78DC-49C7-8845-E842358AC0FA}.Release|x64.ActiveCfg = Release|x64
+		{8EE881F4-78DC-49C7-8845-E842358AC0FA}.Release|x64.Build.0 = Release|x64
 		{3B32F1BE-9686-4DC9-8197-F734D146E9F8}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{3B32F1BE-9686-4DC9-8197-F734D146E9F8}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{3B32F1BE-9686-4DC9-8197-F734D146E9F8}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{3B32F1BE-9686-4DC9-8197-F734D146E9F8}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{3B32F1BE-9686-4DC9-8197-F734D146E9F8}.Debug|Win32.ActiveCfg = Debug|Win32
 		{3B32F1BE-9686-4DC9-8197-F734D146E9F8}.Debug|Win32.Build.0 = Debug|Win32
+		{3B32F1BE-9686-4DC9-8197-F734D146E9F8}.Debug|x64.ActiveCfg = Debug|x64
+		{3B32F1BE-9686-4DC9-8197-F734D146E9F8}.Debug|x64.Build.0 = Debug|x64
 		{3B32F1BE-9686-4DC9-8197-F734D146E9F8}.Release|Win32.ActiveCfg = Release|Win32
 		{3B32F1BE-9686-4DC9-8197-F734D146E9F8}.Release|Win32.Build.0 = Release|Win32
+		{3B32F1BE-9686-4DC9-8197-F734D146E9F8}.Release|x64.ActiveCfg = Release|x64
+		{3B32F1BE-9686-4DC9-8197-F734D146E9F8}.Release|x64.Build.0 = Release|x64
 		{5594DC0E-191C-4F2A-83FE-97F53A9C1222}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{5594DC0E-191C-4F2A-83FE-97F53A9C1222}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{5594DC0E-191C-4F2A-83FE-97F53A9C1222}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{5594DC0E-191C-4F2A-83FE-97F53A9C1222}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{5594DC0E-191C-4F2A-83FE-97F53A9C1222}.Debug|Win32.ActiveCfg = Debug|Win32
 		{5594DC0E-191C-4F2A-83FE-97F53A9C1222}.Debug|Win32.Build.0 = Debug|Win32
+		{5594DC0E-191C-4F2A-83FE-97F53A9C1222}.Debug|x64.ActiveCfg = Debug|x64
+		{5594DC0E-191C-4F2A-83FE-97F53A9C1222}.Debug|x64.Build.0 = Debug|x64
 		{5594DC0E-191C-4F2A-83FE-97F53A9C1222}.Release|Win32.ActiveCfg = Release|Win32
 		{5594DC0E-191C-4F2A-83FE-97F53A9C1222}.Release|Win32.Build.0 = Release|Win32
+		{5594DC0E-191C-4F2A-83FE-97F53A9C1222}.Release|x64.ActiveCfg = Release|x64
+		{5594DC0E-191C-4F2A-83FE-97F53A9C1222}.Release|x64.Build.0 = Release|x64
 		{11A8927C-F971-4104-A286-5DC11C25E2EC}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{11A8927C-F971-4104-A286-5DC11C25E2EC}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{11A8927C-F971-4104-A286-5DC11C25E2EC}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{11A8927C-F971-4104-A286-5DC11C25E2EC}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{11A8927C-F971-4104-A286-5DC11C25E2EC}.Debug|Win32.ActiveCfg = Debug|Win32
 		{11A8927C-F971-4104-A286-5DC11C25E2EC}.Debug|Win32.Build.0 = Debug|Win32
+		{11A8927C-F971-4104-A286-5DC11C25E2EC}.Debug|x64.ActiveCfg = Debug|x64
+		{11A8927C-F971-4104-A286-5DC11C25E2EC}.Debug|x64.Build.0 = Debug|x64
 		{11A8927C-F971-4104-A286-5DC11C25E2EC}.Release|Win32.ActiveCfg = Release|Win32
 		{11A8927C-F971-4104-A286-5DC11C25E2EC}.Release|Win32.Build.0 = Release|Win32
+		{11A8927C-F971-4104-A286-5DC11C25E2EC}.Release|x64.ActiveCfg = Release|x64
+		{11A8927C-F971-4104-A286-5DC11C25E2EC}.Release|x64.Build.0 = Release|x64
 		{62D88133-09F6-4E13-B39F-36FCEFBE4FAF}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{62D88133-09F6-4E13-B39F-36FCEFBE4FAF}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{62D88133-09F6-4E13-B39F-36FCEFBE4FAF}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{62D88133-09F6-4E13-B39F-36FCEFBE4FAF}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{62D88133-09F6-4E13-B39F-36FCEFBE4FAF}.Debug|Win32.ActiveCfg = Debug|Win32
 		{62D88133-09F6-4E13-B39F-36FCEFBE4FAF}.Debug|Win32.Build.0 = Debug|Win32
+		{62D88133-09F6-4E13-B39F-36FCEFBE4FAF}.Debug|x64.ActiveCfg = Debug|x64
+		{62D88133-09F6-4E13-B39F-36FCEFBE4FAF}.Debug|x64.Build.0 = Debug|x64
 		{62D88133-09F6-4E13-B39F-36FCEFBE4FAF}.Release|Win32.ActiveCfg = Release|Win32
 		{62D88133-09F6-4E13-B39F-36FCEFBE4FAF}.Release|Win32.Build.0 = Release|Win32
+		{62D88133-09F6-4E13-B39F-36FCEFBE4FAF}.Release|x64.ActiveCfg = Release|x64
+		{62D88133-09F6-4E13-B39F-36FCEFBE4FAF}.Release|x64.Build.0 = Release|x64
 		{76EFC06C-1F64-4478-ABE8-79832716B393}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{76EFC06C-1F64-4478-ABE8-79832716B393}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{76EFC06C-1F64-4478-ABE8-79832716B393}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{76EFC06C-1F64-4478-ABE8-79832716B393}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{76EFC06C-1F64-4478-ABE8-79832716B393}.Debug|Win32.ActiveCfg = Debug|Win32
 		{76EFC06C-1F64-4478-ABE8-79832716B393}.Debug|Win32.Build.0 = Debug|Win32
+		{76EFC06C-1F64-4478-ABE8-79832716B393}.Debug|x64.ActiveCfg = Debug|x64
+		{76EFC06C-1F64-4478-ABE8-79832716B393}.Debug|x64.Build.0 = Debug|x64
 		{76EFC06C-1F64-4478-ABE8-79832716B393}.Release|Win32.ActiveCfg = Release|Win32
 		{76EFC06C-1F64-4478-ABE8-79832716B393}.Release|Win32.Build.0 = Release|Win32
+		{76EFC06C-1F64-4478-ABE8-79832716B393}.Release|x64.ActiveCfg = Release|x64
+		{76EFC06C-1F64-4478-ABE8-79832716B393}.Release|x64.Build.0 = Release|x64
 		{E4A40368-152D-4D54-9E2E-4B140212F98F}.Debug_NoLibs|Win32.ActiveCfg = Debug_NoLibs|Win32
 		{E4A40368-152D-4D54-9E2E-4B140212F98F}.Debug_NoLibs|Win32.Build.0 = Debug_NoLibs|Win32
+		{E4A40368-152D-4D54-9E2E-4B140212F98F}.Debug_NoLibs|x64.ActiveCfg = Debug_NoLibs|x64
+		{E4A40368-152D-4D54-9E2E-4B140212F98F}.Debug_NoLibs|x64.Build.0 = Debug_NoLibs|x64
 		{E4A40368-152D-4D54-9E2E-4B140212F98F}.Debug|Win32.ActiveCfg = Debug|Win32
 		{E4A40368-152D-4D54-9E2E-4B140212F98F}.Debug|Win32.Build.0 = Debug|Win32
+		{E4A40368-152D-4D54-9E2E-4B140212F98F}.Debug|x64.ActiveCfg = Debug|x64
+		{E4A40368-152D-4D54-9E2E-4B140212F98F}.Debug|x64.Build.0 = Debug|x64
 		{E4A40368-152D-4D54-9E2E-4B140212F98F}.Release|Win32.ActiveCfg = Release|Win32
 		{E4A40368-152D-4D54-9E2E-4B140212F98F}.Release|Win32.Build.0 = Release|Win32
+		{E4A40368-152D-4D54-9E2E-4B140212F98F}.Release|x64.ActiveCfg = Release|x64
+		{E4A40368-152D-4D54-9E2E-4B140212F98F}.Release|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/win32/tsk_comparedir/tsk_compare.vcxproj b/win32/tsk_comparedir/tsk_compare.vcxproj
index 9225ef1..014428a 100755
--- a/win32/tsk_comparedir/tsk_compare.vcxproj
+++ b/win32/tsk_comparedir/tsk_compare.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectName>tsk_comparedir</ProjectName>
@@ -23,37 +35,70 @@
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>MultiByte</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>MultiByte</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -73,6 +118,22 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
@@ -92,6 +153,24 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -110,6 +189,22 @@
       <TargetMachine>NotSet</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <WarningLevel>Level1</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <Optimization>Disabled</Optimization>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AssemblyDebug>true</AssemblyDebug>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\autotools\tsk_comparedir.cpp" />
   </ItemGroup>
diff --git a/win32/tsk_gettimes/tsk_gettimes.vcxproj b/win32/tsk_gettimes/tsk_gettimes.vcxproj
index 4b1313d..0c3c20c 100755
--- a/win32/tsk_gettimes/tsk_gettimes.vcxproj
+++ b/win32/tsk_gettimes/tsk_gettimes.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{11A8927C-F971-4104-A286-5DC11C25E2EC}</ProjectGuid>
@@ -25,41 +37,80 @@
     <CharacterSet>Unicode</CharacterSet>
     <CLRSupport>true</CLRSupport>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <CLRSupport>false</CLRSupport>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <CLRSupport>true</CLRSupport>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <CLRSupport>false</CLRSupport>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <CLRSupport>true</CLRSupport>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <CLRSupport>false</CLRSupport>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
+    <IgnoreImportLibrary Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</IgnoreImportLibrary>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -80,6 +131,24 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AssemblyDebug>true</AssemblyDebug>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -97,6 +166,24 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -115,6 +202,23 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AssemblyDebug>true</AssemblyDebug>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <Reference Include="System">
       <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
diff --git a/win32/tsk_jni/tsk_jni.vcxproj b/win32/tsk_jni/tsk_jni.vcxproj
index 6246f2d..7aea699 100755
--- a/win32/tsk_jni/tsk_jni.vcxproj
+++ b/win32/tsk_jni/tsk_jni.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectName>libtsk_jni</ProjectName>
@@ -25,41 +37,78 @@
     <ConfigurationType>DynamicLibrary</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
     <UseOfMfc>false</UseOfMfc>
     <UseOfAtl>false</UseOfAtl>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <UseOfAtl>false</UseOfAtl>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>DynamicLibrary</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">true</LinkIncremental>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -89,6 +138,32 @@
       </Command>
     </PostBuildEvent>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(JDK_HOME)\include;$(JDK_HOME)\include\win32;$(ProjectDir)\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;TSK_JNI_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <ProjectReference>
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
+    </ProjectReference>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+    </Link>
+    <PostBuildEvent>
+      <Command>
+      </Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
@@ -117,6 +192,33 @@
       </Command>
     </PostBuildEvent>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>$(JDK_HOME)\include;$(JDK_HOME)\include\win32;$(ProjectDir)\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;TSK_JNI_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>
+      </DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+    </Link>
+    <PostBuildEvent>
+      <Command>
+      </Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -144,6 +246,31 @@
       </Command>
     </PostBuildEvent>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(JDK_HOME)\include;$(JDK_HOME)\include\win32;$(ProjectDir)\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;TSK_JNI_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <ProjectReference>
+      <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
+    </ProjectReference>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+    </Link>
+    <PostBuildEvent>
+      <Command>
+      </Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\bindings\java\jni\dataModel_SleuthkitJNI.cpp" />
   </ItemGroup>
diff --git a/win32/tsk_loaddb/tsk_loaddb.vcxproj b/win32/tsk_loaddb/tsk_loaddb.vcxproj
index 34cedb3..ae3568f 100755
--- a/win32/tsk_loaddb/tsk_loaddb.vcxproj
+++ b/win32/tsk_loaddb/tsk_loaddb.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{96AFC6D4-A3DC-44D4-8F55-F74E1D21798C}</ProjectGuid>
@@ -23,36 +35,68 @@
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>NotSet</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>MultiByte</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>NotSet</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -72,6 +116,22 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
@@ -92,6 +152,25 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -108,6 +187,20 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\autotools\tsk_loaddb.cpp" />
   </ItemGroup>
diff --git a/win32/tsk_recover/tsk_recover.vcxproj b/win32/tsk_recover/tsk_recover.vcxproj
index b69bc7f..563d533 100755
--- a/win32/tsk_recover/tsk_recover.vcxproj
+++ b/win32/tsk_recover/tsk_recover.vcxproj
@@ -5,14 +5,26 @@
       <Configuration>Debug_NoLibs</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug_NoLibs|x64">
+      <Configuration>Debug_NoLibs</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
     <ProjectGuid>{06D707E5-68FF-4FC4-AFD0-C84584E32F47}</ProjectGuid>
@@ -24,38 +36,73 @@
     <ConfigurationType>Application</ConfigurationType>
     <CLRSupport>false</CLRSupport>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CLRSupport>false</CLRSupport>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>Windows7.1SDK</PlatformToolset>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup>
     <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Configuration)\</IntDir>
     <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
     <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(OutDir)</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">$(Configuration)\</IntDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">$(Configuration)\</IntDir>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -78,6 +125,25 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <ClCompile>
       <Optimization>MaxSpeed</Optimization>
@@ -101,6 +167,28 @@
       <TargetMachine>MachineX86</TargetMachine>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>libewf.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>$(LIBEWF_HOME)\msvscpp\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|Win32'">
     <ClCompile>
       <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@@ -115,6 +203,19 @@
       <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
     </Link>
   </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_NoLibs|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(ProjectDir)\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <Optimization>Disabled</Optimization>
+    </ClCompile>
+    <Link>
+      <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+    </Link>
+  </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tools\autotools\tsk_recover.cpp" />
   </ItemGroup>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/forensics/sleuthkit.git



More information about the forensics-changes mailing list