diff --git a/tsk/hashdb/tsk_hashdb.c b/tsk/hashdb/tsk_hashdb.c
deleted file mode 100644
index 937a68b5ef776d5af1555bdba1c0ee804ff4876b..0000000000000000000000000000000000000000
--- a/tsk/hashdb/tsk_hashdb.c
+++ /dev/null
@@ -1,589 +0,0 @@
-/*
- * The Sleuth Kit
- *
- * Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2003-2014 Brian Carrier.  All rights reserved
- *
- *
- * This software is distributed under the Common Public License 1.0
- */
-
-#include "tsk_hashdb_i.h"
-#include <assert.h>
-
-#ifdef TSK_WIN32
-#include <share.h>
-#endif
-
-/**
- * \file hdb_open.c
- * Contains the code to open and close all supported hash database types.
- */
-
-// RJCTODO: Add internal comment
-static FILE *
-hdb_open_file(TSK_TCHAR *file_path)
-{
-    FILE *file = NULL;
-    int fd = 0;
-
-    assert(NULL != file_path);
-
-#ifdef TSK_WIN32
-    if (_wsopen_s(&fd, file_path, _O_RDONLY | _O_BINARY, _SH_DENYNO, 0)) {
-        file = _wfdopen(fd, L"rb");
-    }
-#else
-    file = _wfdopen(fd, L"rb");
-#endif
-
-    return file;
-}
-
-// RJCTODO: Add internal comment
-static TSK_HDB_DBTYPE_ENUM
-hdb_determine_db_type(FILE *hDb, const TSK_TCHAR *db_path)
-{
-    const char *func_name = "hdb_determine_db_type";
-    TSK_HDB_DBTYPE_ENUM db_type = TSK_HDB_DBTYPE_INVALID_ID;
-
-    assert(NULL != hDb);
-    assert(NULL != db_path);
-
-    if (sqlite3_test(hDb)) {
-        fseeko(hDb, 0, SEEK_SET);
-        return TSK_HDB_DBTYPE_SQLITE_ID;
-    }
-
-    // Try each supported text-format database type to ensure a confident
-    // identification. Only one of the tests should succeed. 
-    fseeko(hDb, 0, SEEK_SET);
-    if (nsrl_test(hDb)) {
-        db_type = TSK_HDB_DBTYPE_NSRL_ID;
-    }
-
-    fseeko(hDb, 0, SEEK_SET);
-    if (md5sum_test(hDb)) {
-        if (db_type != TSK_HDB_DBTYPE_INVALID_ID) {
-            fseeko(hDb, 0, SEEK_SET);
-            return TSK_HDB_DBTYPE_INVALID_ID;
-        }
-        db_type = TSK_HDB_DBTYPE_MD5SUM_ID;
-    }
-
-    fseeko(hDb, 0, SEEK_SET);
-    if (encase_test(hDb)) {
-        if (db_type != TSK_HDB_DBTYPE_INVALID_ID) {
-            fseeko(hDb, 0, SEEK_SET);
-            return TSK_HDB_DBTYPE_INVALID_ID;
-        }
-        db_type = TSK_HDB_DBTYPE_ENCASE_ID;
-    }
-
-    fseeko(hDb, 0, SEEK_SET);
-    if (hk_test(hDb)) {
-        if (db_type != TSK_HDB_DBTYPE_INVALID_ID) {
-            fseeko(hDb, 0, SEEK_SET);
-            return TSK_HDB_DBTYPE_INVALID_ID;
-        }
-        db_type = TSK_HDB_DBTYPE_HK_ID;
-    }
-
-    fseeko(hDb, 0, SEEK_SET);
-    return db_type;
-}
-
-/**
- * \ingroup hashdblib
- * Creates a new hash database. 
- * @param file_path Path for database to create.
- * @return 0 on success, 1 otherwise
- */
-uint8_t 
-tsk_hdb_create(TSK_TCHAR *file_path)
-{
-    assert(NULL != file_path);
-    if (NULL ==  file_path) {
-        tsk_error_reset();
-        tsk_error_set_errno(TSK_ERR_HDB_ARG);
-        tsk_error_set_errstr("tsk_hdb_create: NULL file path");
-        return 1;
-    }
-
-    // RJCTODO: Add enforcement of the .kdb extension here. Also to hfind.
-
-    return sqlite_hdb_create_db(file_path); 
-}
-
-/**
- * \ingroup hashdblib
- * Opens an existing hash database. 
- * @param file_path Path to database or database index file.
- * @param flags Flags for opening the database.  
- * @return Pointer to a struct representing the hash database or NULL on error.
- */
-TSK_HDB_INFO *
-tsk_hdb_open(TSK_TCHAR *file_path, TSK_HDB_OPEN_ENUM flags)
-{
-    const char *func_name = "tsk_hdb_create";
-    uint8_t file_path_is_idx_path = 0;
-    TSK_TCHAR *db_path = NULL;
-    TSK_TCHAR *ext = NULL; 
-    int fd = 0;
-    FILE *hDb = NULL;
-    FILE *hIdx = NULL;
-    TSK_HDB_DBTYPE_ENUM db_type = TSK_HDB_DBTYPE_INVALID_ID;
-    TSK_HDB_INFO *hdb_info = NULL;
-
-    assert(NULL != file_path);
-    if (NULL == file_path) {
-        tsk_error_reset();
-        tsk_error_set_errno(TSK_ERR_HDB_ARG);
-        tsk_error_set_errstr("%s: NULL file path", func_name);
-        return NULL;
-    }
-
-    // Determine the hash database path using the given file path. Note that
-    // direct use of an external index file for a text-format hash database for 
-    // simple yes/no lookups is both explicitly and implicitly supported. For 
-    // such "index only" databases, the path to where the hash database is 
-    // normally required to be is still needed because of the way the code for
-    // text-format hash databases has been written.
-    db_path = (TSK_TCHAR*)tsk_malloc((TSTRLEN(file_path) + 1) * sizeof(TSK_TCHAR));
-    if (NULL == db_path) {
-        return NULL;
-    }
-    ext = TSTRRCHR(file_path, _TSK_T('.'));    
-    if ((NULL != ext) && (TSTRLEN(ext) >= 4) && (TSTRCMP(ext, _TSK_T(".idx")) == 0)) {
-        // The file path extension suggests the path is for an external index
-        // file generated by TSK for a text-format hash database. In this case, 
-        // the database path should be the given file path sans the extension 
-        // because the hash database, if it is available for lookups, is 
-        // required to be be in the same directory as the external index file.
-        file_path_is_idx_path = 1;
-        TSTRNCPY(db_path, file_path, (ext - file_path));
-    }
-    else {
-        TSTRNCPY(db_path, file_path, TSTRLEN(file_path));
-    }
-
-    // Determine the database type.
-    if ((flags & TSK_HDB_OPEN_IDXONLY) == 0) {
-        hDb = hdb_open_file(db_path);
-        if (NULL != hDb) {
-            db_type = hdb_determine_db_type(hDb, db_path);
-            if (TSK_HDB_DBTYPE_INVALID_ID == db_type) {
-                tsk_error_reset();
-                tsk_error_set_errno(TSK_ERR_HDB_UNKTYPE);
-                tsk_error_set_errstr("%s: error determining hash database type of %"PRIttocTSK, func_name, db_path);
-                free(db_path);
-                return NULL;
-            }
-        }
-        else {
-            if (file_path_is_idx_path) {
-                db_type = TSK_HDB_DBTYPE_IDXONLY_ID;
-            }
-            else {
-                tsk_error_reset();
-                tsk_error_set_errno(TSK_ERR_HDB_OPEN);
-                tsk_error_set_errstr("%s: failed to open %"PRIttocTSK, func_name, db_path);
-                free(db_path);
-                return NULL;
-            }
-        }
-    }
-    else {
-        db_type = TSK_HDB_DBTYPE_IDXONLY_ID;
-    }
-
-    switch (db_type) {
-        case TSK_HDB_DBTYPE_NSRL_ID:
-            hdb_info = nsrl_open(hDb, db_path);
-            break;
-        case TSK_HDB_DBTYPE_MD5SUM_ID:
-            hdb_info = md5sum_open(hDb, db_path);
-            break;
-        case TSK_HDB_DBTYPE_ENCASE_ID:
-            hdb_info = encase_open(hDb, db_path);
-            break;
-        case TSK_HDB_DBTYPE_HK_ID:
-            hdb_info = hk_open(hDb, db_path);
-            break;
-        case TSK_HDB_DBTYPE_IDXONLY_ID:
-            hIdx = hdb_open_file(db_path);
-            if (NULL == hIdx) {
-                tsk_error_reset();
-                tsk_error_set_errno(TSK_ERR_HDB_OPEN);
-                tsk_error_set_errstr("%s: database is index only, failed to open index %"PRIttocTSK, func_name, db_path);
-                free(db_path);
-                return NULL;
-            } 
-            else {
-                fclose(hIdx);
-            }
-            hdb_info = idxonly_open(db_path);
-            break;
-        case TSK_HDB_DBTYPE_SQLITE_ID: 
-            if (NULL != hDb) {
-                fclose(hDb);
-            }
-            hdb_info = sqlite_hdb_open(db_path);
-            break;
-        default:
-            assert(0);
-    }
-
-    if (NULL != db_path) {
-        free(db_path);
-    }
-
-    return hdb_info;
-}
-
-/**
- * \ingroup hashdblib
- * Determine if the open hash database has an index.
- *
- * @param hdb_info Hash database to consider
- * @param htype Hash type that index should be of
- *
- * @return 1 if index exists and 0 if not
- */
-uint8_t
-tsk_hdb_has_idx(TSK_HDB_INFO * hdb_info, TSK_HDB_HTYPE_ENUM htype)
-{
-    assert(hdb_info);
-    if (!hdb_info) {
-        tsk_error_reset();
-        tsk_error_set_errno(TSK_ERR_HDB_ARG);
-        tsk_error_set_errstr("tsk_hdb_has_idx: NULL hdb_info");
-        return 0;
-    }
-
-    return (hdb_info->open_index(hdb_info, htype) == 0) ? 1 : 0;
-}
-
-/**
- * \ingroup hashdblib
- * Test for index only (legacy)
- * Assumes that the db was opened using the TSK_HDB_OPEN_TRY option.
- *
- * @param hdb_info Hash database to consider
- *
- * @return 1 if there is only a legacy index AND no db, 0 otherwise
- */
-uint8_t
-tsk_hdb_is_idx_only(TSK_HDB_INFO *hdb_info)
-{
-    assert(hdb_info);
-    if (!hdb_info) {
-        tsk_error_reset();
-        tsk_error_set_errno(TSK_ERR_HDB_ARG);
-        tsk_error_set_errstr("tsk_hdb_is_idx_only: NULL hdb_info");
-        return 0; // RJCTODO: Not sure this is too helpful
-    }
-
-    return (hdb_info->db_type == TSK_HDB_DBTYPE_IDXONLY_ID);
-}
-
-/**
- * \ingroup hashdblib
- * Create an index for an open hash database.
- * @param a_hdb_info Open hash database to index
- * @param a_type Text of hash database type
- * @returns 1 on error
- */
-uint8_t
-tsk_hdb_make_index(TSK_HDB_INFO *hdb_info, TSK_TCHAR *type)
-{
-    assert(hdb_info);
-    if (!hdb_info) {
-        tsk_error_reset();
-        tsk_error_set_errno(TSK_ERR_HDB_ARG);
-        tsk_error_set_errstr("tsk_hdb_make_index: NULL hdb_info");
-        return 1;
-    }
-
-    return hdb_info->make_index(hdb_info, type);
-}
-
-/**
- * \ingroup hashdblib
- * Search the index for a text/ASCII hash value
- *
- * @param hdb_info Open hash database (with index)
- * @param hash Hash value to search for (NULL terminated string)
- * @param flags Flags to use in lookup
- * @param action Callback function to call for each hash db entry 
- * (not called if QUICK flag is given)
- * @param ptr Pointer to data to pass to each callback
- *
- * @return -1 on error, 0 if hash value not found, and 1 if value was found.
- */
-int8_t
-tsk_hdb_lookup_str(TSK_HDB_INFO * hdb_info, const char *hash,
-                   TSK_HDB_FLAG_ENUM flags, TSK_HDB_LOOKUP_FN action,
-                   void *ptr)
-{
-    TSK_HDB_HTYPE_ENUM htype;
-
-    assert(hdb_info);
-    if (!hdb_info) {
-        tsk_error_reset();
-        tsk_error_set_errno(TSK_ERR_HDB_ARG);
-        tsk_error_set_errstr("tsk_hdb_lookup_str: NULL hdb_info");
-        return -1;
-    }
-
-    /* Sanity checks on the hash input */
-    if (strlen(hash) == TSK_HDB_HTYPE_MD5_LEN) {
-        htype = TSK_HDB_HTYPE_MD5_ID;
-    }
-    else if (strlen(hash) == TSK_HDB_HTYPE_SHA1_LEN) {
-        htype = TSK_HDB_HTYPE_SHA1_ID;
-    }
-    else {
-        tsk_error_reset();
-        tsk_error_set_errno(TSK_ERR_HDB_ARG);
-        tsk_error_set_errstr(
-                "tsk_hdb_lookup_str: invalid hash length: %s", hash);
-        return -1;
-    }
-
-    if (hdb_info->open_index(hdb_info, htype)) {
-        return -1;
-    }
-
-    return hdb_info->lookup_str(hdb_info, hash, flags, action, ptr);
-}
-
-/**
- * \ingroup hashdblib
- * Search the index for a text/ASCII hash value
- *
- * @param hdb_info Open hash database (with index)
- * @param hash Hash value to search for (NULL terminated string)
- * @param ptr Pointer to data to pass to each callback
- *
- * @return -1 on error, 0 if hash value not found, and the hash id if value was found.
- */
-int64_t
-tsk_hdb_lookup_str_id(TSK_HDB_INFO * hdb_info, const char *hash)
-{
-    // RJCTODO: THIS MUST GO!
-
-    TSK_HDB_HTYPE_ENUM htype;
-
-    assert(hdb_info);
-    if (!hdb_info) {
-        tsk_error_reset();
-        tsk_error_set_errno(TSK_ERR_HDB_ARG);
-        tsk_error_set_errstr("tsk_hdb_lookup_str_id: NULL hdb_info");
-        return -1;
-    }
-
-    /* Sanity checks on the hash input */
-    if (strlen(hash) == TSK_HDB_HTYPE_MD5_LEN) {
-        htype = TSK_HDB_HTYPE_MD5_ID;
-    }
-    else if (strlen(hash) == TSK_HDB_HTYPE_SHA1_LEN) {
-        htype = TSK_HDB_HTYPE_SHA1_ID;
-    }
-    else {
-        tsk_error_reset();
-        tsk_error_set_errno(TSK_ERR_HDB_ARG);
-        tsk_error_set_errstr(
-                "tsk_hdb_lookup_str_id: Invalid hash length: %s", hash);
-        return -1;
-    }
-
-    if (hdb_info->open_index(hdb_info, htype)) {
-        return -1;
-    }
-
-    // RJCTODO: This code is SQLite-specific, but probably worked due to a hack in the caller.
-    // Perhaps a flag and API indicatingf whether verbose lookup is supported is warranted.
-    // The caller is Java_org_sleuthkit_datamodel_SleuthkitJNI_hashDbLookupVerbose().
-    if (hdb_info->lookup_str(hdb_info, hash, TSK_HDB_FLAG_QUICK, NULL, NULL) == -1) {
-        return -1;
-    } else {
-        TSK_SQLITE_HDB_INFO *sqlite_hdb_info = (TSK_SQLITE_HDB_INFO*)hdb_info; 
-        return sqlite_hdb_info->last_id; 
-    }
-}
-
-/**
- * \ingroup hashdblib
- * Search the index for the given hash value given (in binary form).
- *
- * @param hdb_info Open hash database (with index)
- * @param hash Array with binary hash value to search for
- * @param len Number of bytes in binary hash value
- * @param flags Flags to use in lookup
- * @param action Callback function to call for each hash db entry 
- * (not called if QUICK flag is given)
- * @param ptr Pointer to data to pass to each callback
- *
- * @return -1 on error, 0 if hash value not found, and 1 if value was found.
- */
-int8_t
-tsk_hdb_lookup_bin(TSK_HDB_INFO * hdb_info, uint8_t * hash, uint8_t len,
-                   TSK_HDB_FLAG_ENUM flags,
-                   TSK_HDB_LOOKUP_FN action, void *ptr)
-{
-    TSK_HDB_HTYPE_ENUM htype;
-
-    assert(hdb_info);
-    if (!hdb_info) {
-        tsk_error_reset();
-        tsk_error_set_errno(TSK_ERR_HDB_ARG);
-        tsk_error_set_errstr("tsk_hdb_lookup_raw: NULL hdb_info");
-        return -1;
-    }
-
-    /* Sanity checks on the hash input */
-    if (len/2 == TSK_HDB_HTYPE_MD5_LEN) {
-        htype = TSK_HDB_HTYPE_MD5_ID;
-    }
-    else if (len/2 == TSK_HDB_HTYPE_SHA1_LEN) {
-        htype = TSK_HDB_HTYPE_SHA1_ID;
-    }
-    else {
-        tsk_error_reset();
-        tsk_error_set_errno(TSK_ERR_HDB_ARG);
-        tsk_error_set_errstr(
-                "hdb_lookup_raw: Invalid hash length: %s", hash);
-        return -1;
-    }
-
-    if (hdb_info->open_index(hdb_info, htype)) {
-        return -1;
-    }
-
-	return hdb_info->lookup_raw(hdb_info, hash, len, flags, action, ptr);
-}
-
-uint8_t 
-tsk_hdb_has_verbose_lookup()
-{
-}
- 
-void *
-tsk_hdb_lookup_verbose_str(TSK_HDB_INFO *hdb_info, const char *hash)
-{
-    if (hdb_info->has_verbose_lookup()) {
-        return hdb_info->lookup_verbose_str(hdb_info, hash);
-    }
-    else {
-        // RJCTODO: Error stuff
-    }
-}
-
-
-/**
- * \ingroup hashdblib
- * Add a binary hash entry to the index
- *
- * @param hdb_info the hash database object
- * @param filename Name of the file that was hashed (can be null)
- * @param md5 Text of MD5 hash (can be null)
- * @param sha1 Text of SHA1 hash (can be null)
- * @param sha256 Text of SHA256 hash (can be null)
- * @return 1 on error, 0 on success, -1 if not updateable
- */
-int8_t
-tsk_hdb_add_hash(TSK_HDB_INFO * hdb_info, const char *filename, const char *md5, 
-    const char *sha1, const char *sha256, const char *comment)
-{
-    int8_t ret = 0;
-
-    assert(hdb_info);
-    if (!hdb_info) {
-        tsk_error_reset();
-        tsk_error_set_errno(TSK_ERR_HDB_ARG);
-        tsk_error_set_errstr("tsk_hdb_add_hash: NULL hdb_info");
-        return 1;
-    }
-
-    // RJCTODO: Make this right!
-    //if(hdb_info == NULL) {
-    //    tsk_error_set_errstr2("tsk_hdb_add_str: null hdb_info");
-    //    ret = 1; //error
-    //} else {
-    //    uint8_t htype = TSK_HDB_HTYPE_MD5_ID;
-    //    if (hdb_setupindex(hdb_info, htype)) {
-    //        return 1; //error
-    //    }
-
-    //    // RJCTODO: Why is this calling SQLIte functions? Why is this not going through the proper function pointers?
-    //    if(hdb_info->idx_info->updateable == 1) {
-    //        ///@todo also allow use of other htypes
-    //        char * hvalue = (char *)md5;
-    //        if (hvalue == NULL) {
-    //            tsk_error_set_errstr2("tsk_hdb_add_str: no hash value(s) provided");
-    //            return 1; //error
-    //        }
-
-    //        // @todo Could set up a polymorphic mechanism like with finalize() but
-    //        // we know it's going to be sqlite in this function.
-    //        if (sqlite_v1_begin(hdb_info) == 1) {
-    //            tsk_error_set_errstr2("tsk_hdb_add_str: sqlite_v1_begin failed");
-    //            return 1; //error
-    //        }
-
-    //        // Attempt to add a new row to the hash index
-    //        TSK_OFF_T offset = 0; //not needed since there might not be an original DB
-    //        if (tsk_hdb_idxaddentry(hdb_info, hvalue, offset) != 0) {
-    //            tsk_error_reset();
-    //            tsk_error_set_errno(TSK_ERR_HDB_WRITE);
-    //            tsk_error_set_errstr("tsk_hdb_add_str: adding entry failed");
-    //            return 1; //error
-    //        }
-
-    //        // Add name and comment
-    //        if (hdb_info->idx_info->idx_struct.idx_sqlite_v1->lastId != 0) {
-    //            if ((filename != NULL) && (hdb_info->add_filename != NULL)) {
-    //                hdb_info->add_filename(hdb_info, (char *)filename, hdb_info->idx_info->idx_struct.idx_sqlite_v1->lastId);
-    //            }
-
-    //            if ((comment != NULL) && (hdb_info->add_comment != NULL)) {
-    //                hdb_info->add_comment(hdb_info, (char *)comment, hdb_info->idx_info->idx_struct.idx_sqlite_v1->lastId);
-    //            }
-    //        } else {
-    //            ret = 1; //error
-    //        }
-
-    //        // Close the index
-    //        if (tsk_hdb_idxfinalize(hdb_info) != 0) {
-    //            tsk_error_reset();
-    //            tsk_error_set_errno(TSK_ERR_HDB_WRITE);
-    //            tsk_error_set_errstr("tsk_hdb_add_str: finalizing index failed");
-    //            ret = 1; //error
-    //        }  
-    //        
-    //    } else {
-    //        ret = -1; //not updateable
-    //    }
-    //}
-    return ret;
-}
-
-/**
- * \ingroup hashdblib
- * Closes an open hash database.
- * @param hdb_info database to close
- */
-void
-tsk_hdb_close(TSK_HDB_INFO *hdb_info)
-{
-    assert(hdb_info);
-    if (!hdb_info) {
-        tsk_error_reset();
-        tsk_error_set_errno(TSK_ERR_HDB_ARG);
-        tsk_error_set_errstr("tsk_hdb_close: NULL hdb_info");
-        return;
-    }
-
-    hdb_info->close_db(hdb_info);
-}
diff --git a/win32/libtsk/libtsk.vcxproj b/win32/libtsk/libtsk.vcxproj
index 88a354c983f599fad60cc08a2239a311d3af7d0d..47e620e5dde2d1bf770a8e4a96b687e3dc31d506 100755
--- a/win32/libtsk/libtsk.vcxproj
+++ b/win32/libtsk/libtsk.vcxproj
@@ -279,7 +279,7 @@ copy "$(LIBEWF_HOME)\msvscpp\x64\release\zlib.dll" "$(OutDir)"
     <ClCompile Include="..\..\tsk\hashdb\idxonly.c" />
     <ClCompile Include="..\..\tsk\hashdb\md5sum.c" />
     <ClCompile Include="..\..\tsk\hashdb\nsrl.c" />
-    <ClCompile Include="..\..\tsk\hashdb\tsk_hashdb.c" />
+    <ClCompile Include="..\..\tsk\hashdb\tsk_hashdb.cpp" />
     <ClCompile Include="..\..\tsk\hashdb\sqlite.cpp" />
     <ClCompile Include="..\..\tsk\img\aff.c" />
     <ClCompile Include="..\..\tsk\img\ewf.c" />
diff --git a/win32/libtsk/libtsk.vcxproj.filters b/win32/libtsk/libtsk.vcxproj.filters
index 02369d61c718efd1425395a510abf9aff244f707..c64d69382acff28325a7a78046b5f55ae88fc4d4 100755
--- a/win32/libtsk/libtsk.vcxproj.filters
+++ b/win32/libtsk/libtsk.vcxproj.filters
@@ -274,7 +274,7 @@
     <ClCompile Include="..\..\tsk\hashdb\text_fmt_base.c">
       <Filter>hash</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\tsk\hashdb\tsk_hashdb.c">
+    <ClCompile Include="..\..\tsk\hashdb\tsk_hashdb.cpp">
       <Filter>hash</Filter>
     </ClCompile>
   </ItemGroup>