diff --git a/API-CHANGES.txt b/API-CHANGES.txt
index 59f2923c891c228557b324b15d37861f9e983644..142dbd527dc2319afaf4a3cad67aa9601e8f54e6 100644
--- a/API-CHANGES.txt
+++ b/API-CHANGES.txt
@@ -4,3 +4,4 @@ Changes to make once we are ready to do a backwards incompatible change.
 - Java SleuthkitCase.addArtifactType shoudl return different if artifact already exists or getArtifactId should....
 - Java SleuthkitCase.findFilesWhere should return AbstractFile liek findFiles
 - getUniquePath() should not throw exception. 
+- hashdb idx_open (and others) shoudl have htype be enum
diff --git a/tsk/hashdb/Makefile.am b/tsk/hashdb/Makefile.am
index e5027f08de3d054c5bdce6877491fda29d24dc07..9e91b48edd20980f9e629377860756f3620fb44d 100644
--- a/tsk/hashdb/Makefile.am
+++ b/tsk/hashdb/Makefile.am
@@ -4,6 +4,7 @@ EXTRA_DIST = .indent.pro
 noinst_LTLIBRARIES = libtskhashdb.la
 libtskhashdb_la_SOURCES = ascii_index.c sqlite_index.cpp \
     tm_lookup.cpp md5sum_index.c nsrl_index.c \
+    hdb_open.cpp hdb_index.cpp \
     hk_index.c idxonly_index.c encase_index.c tsk_hashdb_i.h
 
 indent:
diff --git a/tsk/hashdb/ascii_index.c b/tsk/hashdb/ascii_index.c
index 98762eeddd67b057772d0ebcfd6e76bea1f79ce2..e090f95cfd04a21df658bc4f93fe84f75714dda5 100644
--- a/tsk/hashdb/ascii_index.c
+++ b/tsk/hashdb/ascii_index.c
@@ -14,7 +14,8 @@
 
 /**
  * \file sqlite_index.c
- * Contains functions for creating a SQLite format hash index
+ * Contains functions for creating the original binary search / ASCII index
+ * and looking up values in it. 
  */
 
 /** Initialize the TSK hash DB index file. This creates the intermediate file,
@@ -64,6 +65,7 @@ plain_txt_addentry_bin(TSK_HDB_INFO * hdb_info, unsigned char *hvalue, int hlen,
         TSK_OFF_T offset)
 {
     // Creating plain text indices is unsupported
+    // @@@ ERROR NEEDED HERE
     return 1;
 }
 
@@ -78,6 +80,7 @@ plain_txt_addentry_bin(TSK_HDB_INFO * hdb_info, unsigned char *hvalue, int hlen,
 plain_txt_finalize(TSK_HDB_INFO * hdb_info)
 {
     // Creating plain text indices is unsupported
+    // @@@ ERROR NEEDED HERE
     return 1;
 }
 
@@ -300,11 +303,6 @@ plain_txt_open(TSK_HDB_INFO * hdb_info, TSK_IDX_INFO * idx_info, uint8_t htype)
 
 
 
-
-
-
-
-
 /**
  * \ingroup hashdblib
  * Search the index for a text/ASCII hash value
diff --git a/tsk/hashdb/hdb_index.cpp b/tsk/hashdb/hdb_index.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ba37ea028041f3d4e17507a51e315a46d2f0640a
--- /dev/null
+++ b/tsk/hashdb/hdb_index.cpp
@@ -0,0 +1,507 @@
+/*
+ * The Sleuth Kit
+ *
+ * Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2003-2013 Brian Carrier.  All rights reserved
+ *
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+#include "tsk_hashdb_i.h"
+
+
+/**
+ * \file hdb_index.cpp
+ * Contains the code to make indexes for databases.
+ */
+
+
+/**
+ * Open a file and return a handle to it.
+ */
+static FILE *
+tsk_idx_open_file(TSK_TCHAR *idx_fname)
+{
+    if (idx_fname == NULL) {
+        return NULL;
+    }
+
+    FILE * idx = NULL;
+
+#ifdef TSK_WIN32
+    {
+        HANDLE hWin;
+        //DWORD szLow, szHi;
+
+        if (-1 == GetFileAttributes(idx_fname)) {
+            //tsk_release_lock(&idx_info->lock);
+            tsk_error_reset();
+            tsk_error_set_errno(TSK_ERR_HDB_MISSING);
+            tsk_error_set_errstr(
+                    "tsk_idx_open_file: Error finding index file: %"PRIttocTSK,
+                    idx_fname);
+            return NULL;
+        }
+
+        if ((hWin = CreateFile(idx_fname, GENERIC_READ,
+                        FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0)) ==
+                INVALID_HANDLE_VALUE) {
+            //tsk_release_lock(&idx_info->lock);
+            tsk_error_reset();
+            tsk_error_set_errno(TSK_ERR_HDB_OPEN);
+            tsk_error_set_errstr(
+                    "tsk_idx_open_file: Error opening index file: %"PRIttocTSK,
+                    idx_fname);
+            return NULL;
+        }
+
+        idx = _fdopen(_open_osfhandle((intptr_t) hWin, _O_RDONLY), "r");
+    }
+#else
+    {
+        idx = fopen(idx_fname, "r");
+    }
+#endif
+
+    return idx;
+}
+
+
+/**
+ * Open an index for the given hash db
+ * We only create kdb (SQLite) files, but can open old indexes.
+ * @return NULL on error, TSK_IDX_INFO instance on success
+ */
+// @@@ htype should be enum
+static TSK_IDX_INFO *
+tsk_idx_open(TSK_HDB_INFO * hdb_info, uint8_t htype, uint8_t create)
+{
+    TSK_IDX_INFO * idx_info;
+    size_t flen;
+    const int header_size = 16;
+    char header[header_size];
+    FILE * idx = NULL;
+
+    if (hdb_info->idx_info != NULL) {
+        return hdb_info->idx_info;
+    }
+
+    if ((idx_info =
+         (TSK_IDX_INFO *) tsk_malloc(sizeof(TSK_IDX_INFO))) == NULL) {
+        return NULL;
+    }
+
+    hdb_info->idx_info = idx_info;
+
+    /* Make the name for the index file */
+    flen = TSTRLEN(hdb_info->db_fname) + 32;
+    idx_info->idx_fname =
+        (TSK_TCHAR *) tsk_malloc(flen * sizeof(TSK_TCHAR));
+    if (idx_info->idx_fname == NULL) {
+        free(idx_info);
+        // @@@ ERROR INFO NEEDED
+        return NULL;
+    }
+
+    /* Get hash type specific information */
+    switch (htype) {
+        case TSK_HDB_HTYPE_MD5_ID:
+            hdb_info->hash_type = static_cast<TSK_HDB_HTYPE_ENUM>(htype);
+            hdb_info->hash_len = TSK_HDB_HTYPE_MD5_LEN;
+            break;
+        case TSK_HDB_HTYPE_SHA1_ID:
+            hdb_info->hash_type = static_cast<TSK_HDB_HTYPE_ENUM>(htype);
+            hdb_info->hash_len = TSK_HDB_HTYPE_SHA1_LEN;
+            break;
+        default:
+            free(idx_info);
+            // @@@ ERROR INFO NEEDED
+            return NULL;
+    }
+
+
+    // Verify the new SQLITE index exists, get its size, and open it for header reading
+    TSNPRINTF(idx_info->idx_fname, flen,
+            _TSK_T("%s.kdb"), hdb_info->db_fname);
+    if (((idx = tsk_idx_open_file(idx_info->idx_fname)) == NULL) && (create == 0)) {
+
+        // Try opening an old format index file
+
+        // Change the filename to the old format
+        switch (htype) {
+            case TSK_HDB_HTYPE_MD5_ID:
+                TSNPRINTF(idx_info->idx_fname, flen,
+                          _TSK_T("%s-%") PRIcTSK _TSK_T(".idx"),
+                          hdb_info->db_fname, TSK_HDB_HTYPE_MD5_STR);
+                break;
+            case TSK_HDB_HTYPE_SHA1_ID:
+                TSNPRINTF(idx_info->idx_fname, flen,
+                          _TSK_T("%s-%") PRIcTSK _TSK_T(".idx"),
+                          hdb_info->db_fname, TSK_HDB_HTYPE_SHA1_STR);
+                break;
+        }
+
+        idx = tsk_idx_open_file(idx_info->idx_fname);
+
+        if (!idx) {
+            free(idx_info);
+            // @@@ ERROR NEEDED
+            return NULL;
+        }
+        
+        if (1 != fread(header, header_size, 1, idx)) {
+            ///@@@ ERROR
+            return NULL;
+        }
+        else if (strncmp(header,
+                           IDX_PLAIN_TXT_HEADER,
+                           strlen(IDX_PLAIN_TXT_HEADER)) == 0) {
+            idx_info->index_type = TSK_HDB_ITYPE_PLAIN_TXT;
+            idx_info->open = plain_txt_open;
+            idx_info->close = plain_txt_close;
+            idx_info->initialize = plain_txt_initialize;
+            idx_info->addentry = plain_txt_addentry;
+            idx_info->addentry_bin = plain_txt_addentry_bin;
+            idx_info->finalize = plain_txt_finalize;
+            idx_info->lookup_str = plain_txt_lookup_str;
+            idx_info->lookup_raw = plain_txt_lookup_raw;
+        }
+        else {
+            tsk_error_reset();
+            tsk_error_set_errno(TSK_ERR_HDB_MISSING);
+            tsk_error_set_errstr(
+                                 "tsk_idx_open: Unrecognized header format: %s\n",
+                                 idx_info->idx_fname);
+            free(idx_info);
+            return NULL;
+        }
+    }
+    // kdb extension
+    else {
+        if (idx) {
+            if (1 != fread(header, header_size, 1, idx)) {
+                ///@todo should this actually be an error?
+                idx_info->index_type = TSK_HDB_ITYPE_SQLITE_V1;
+            }
+            else if (strncmp(header,
+                        IDX_SQLITE_V1_HEADER,
+                        strlen(IDX_SQLITE_V1_HEADER)) == 0) {
+                idx_info->index_type = TSK_HDB_ITYPE_SQLITE_V1;
+            }
+            else {
+                tsk_error_reset();
+                tsk_error_set_errno(TSK_ERR_HDB_MISSING);
+                tsk_error_set_errstr(
+                        "tsk_idx_open: Unrecognized header format: %s\n",
+                        idx_info->idx_fname);
+                free(idx_info);
+                return NULL;
+            }
+        }
+
+        idx_info->open = sqlite_v1_open;
+        idx_info->close = sqlite_v1_close;
+        idx_info->initialize = sqlite_v1_initialize;
+        idx_info->addentry = sqlite_v1_addentry;
+        idx_info->addentry_bin = sqlite_v1_addentry_bin;
+        idx_info->finalize = sqlite_v1_finalize;
+        idx_info->lookup_str = sqlite_v1_lookup_str;
+        idx_info->lookup_raw = sqlite_v1_lookup_raw;
+    }
+
+    // Open
+    if (idx_info->open(hdb_info, idx_info, htype) == 0) {
+        return idx_info;
+    }
+
+    tsk_error_reset();
+    tsk_error_set_errno(TSK_ERR_HDB_ARG);
+    tsk_error_set_errstr(
+             "Error setting up idx_info struct: %d\n", htype);
+    free(idx_info);
+    return NULL;
+}
+
+
+/**
+ * Ensures that the index is already opened or can be opened. 
+ * @param hdb_info Database handle
+ * @param htype TSK_HDB_HTYPE_ENUM value
+ * @param 
+ * @return 0 if already set up or if setup successful, 1 otherwise
+ */
+uint8_t
+hdb_setupindex(TSK_HDB_INFO * hdb_info, uint8_t htype, uint8_t create)
+{
+    // Lock for lazy load of idx_info and lazy alloc of idx_lbuf.
+    tsk_take_lock(&hdb_info->lock);
+
+    // already opened
+    if (hdb_info->idx_info != NULL) {
+        tsk_release_lock(&hdb_info->lock);
+        return 0;
+    }
+
+    hdb_info->idx_info = tsk_idx_open(hdb_info, htype, create);
+
+    if (hdb_info->idx_info != NULL) {
+        tsk_release_lock(&hdb_info->lock);
+        return 0;
+    }
+
+    tsk_release_lock(&hdb_info->lock);
+    return 1;
+}
+
+
+/** 
+ * Creates and initialize a new TSK hash DB index file.
+ *
+ * @param hdb_info Hash database state structure
+ * @param a_dbtype String of index type to create
+ *
+ * @return 1 on error and 0 on success
+ */
+uint8_t
+tsk_hdb_idxinitialize(TSK_HDB_INFO * hdb_info, TSK_TCHAR * a_dbtype)
+{
+    char dbtmp[32];
+    int i;
+    bool create = true; //create new file if it doesn't already exist
+
+    /* Use the string of the index/hash type to figure out some
+     * settings */
+
+    // convert to char -- cheating way to deal with WCHARs..
+    for (i = 0; i < 31 && a_dbtype[i] != '\0'; i++) {
+        dbtmp[i] = (char) a_dbtype[i];
+    }
+    dbtmp[i] = '\0';
+
+    // MD5 index for NSRL file
+    if (strcmp(dbtmp, TSK_HDB_DBTYPE_NSRL_MD5_STR) == 0) {
+
+        if (hdb_info->db_type != TSK_HDB_DBTYPE_NSRL_ID) {
+            tsk_error_reset();
+            tsk_error_set_errno(TSK_ERR_HDB_ARG);
+            tsk_error_set_errstr(
+                     "hdb_idxinitialize: database detected as: %d index creation as: %d",
+                     hdb_info->db_type, TSK_HDB_DBTYPE_NSRL_ID);
+            return 1;
+        }
+        hdb_info->hash_type = TSK_HDB_HTYPE_MD5_ID;
+    }
+    // SHA1 index for NSRL file
+    else if (strcmp(dbtmp, TSK_HDB_DBTYPE_NSRL_SHA1_STR) == 0) {
+        if (hdb_info->db_type != TSK_HDB_DBTYPE_NSRL_ID) {
+            tsk_error_reset();
+            tsk_error_set_errno(TSK_ERR_HDB_ARG);
+            tsk_error_set_errstr(
+                     "hdb_idxinitialize: database detected as: %d index creation as: %d",
+                     hdb_info->db_type, TSK_HDB_DBTYPE_NSRL_ID);
+            return 1;
+        }
+        hdb_info->hash_type = TSK_HDB_HTYPE_SHA1_ID;
+    }
+    else if (strcmp(dbtmp, TSK_HDB_DBTYPE_MD5SUM_STR) == 0) {
+        if (hdb_info->db_type != TSK_HDB_DBTYPE_MD5SUM_ID) {
+            tsk_error_reset();
+            tsk_error_set_errno(TSK_ERR_HDB_ARG);
+            tsk_error_set_errstr(
+                     "hdb_idxinitialize: database detected as: %d index creation as: %d",
+                     hdb_info->db_type, TSK_HDB_DBTYPE_MD5SUM_ID);
+            return 1;
+        }
+        hdb_info->hash_type = TSK_HDB_HTYPE_MD5_ID;
+    }
+    else if (strcmp(dbtmp, TSK_HDB_DBTYPE_HK_STR) == 0) {
+        if (hdb_info->db_type != TSK_HDB_DBTYPE_HK_ID) {
+            tsk_error_reset();
+            tsk_error_set_errno(TSK_ERR_HDB_ARG);
+            tsk_error_set_errstr(
+                     "hdb_idxinitialize: database detected as: %d index creation as: %d",
+                     hdb_info->db_type, TSK_HDB_DBTYPE_HK_ID);
+            return 1;
+        }
+        hdb_info->hash_type = TSK_HDB_HTYPE_MD5_ID;
+    }
+    else if (strcmp(dbtmp, TSK_HDB_DBTYPE_ENCASE_STR) == 0) {
+        if (hdb_info->db_type != TSK_HDB_DBTYPE_ENCASE_ID) {
+            tsk_error_reset();
+            tsk_error_set_errno(TSK_ERR_HDB_ARG);
+            tsk_error_set_errstr(
+                     "hdb_idxinitialize: database detected as: %d index creation as: %d",
+                     hdb_info->db_type, TSK_HDB_DBTYPE_ENCASE_ID);
+            return 1;
+        }
+        hdb_info->hash_type = TSK_HDB_HTYPE_MD5_ID;
+    }
+    else {
+        tsk_error_reset();
+        tsk_error_set_errno(TSK_ERR_HDB_ARG);
+        tsk_error_set_errstr(
+                 "hdb_idxinitialize: Unknown database type request: %s",
+                 dbtmp);
+        return 1;
+    }
+
+    /* Setup the internal hash information */
+    if (hdb_setupindex(hdb_info, hdb_info->hash_type, create)) {
+        return 1;
+    }
+
+    /* Call db-specific initialize function */
+	return hdb_info->idx_info->initialize(hdb_info, a_dbtype);
+}
+
+/**
+ * Add a string hash entry to the index
+ *
+ * @param hdb_info Hash database state info
+ * @param hvalue String of hash value to add
+ * @param offset Byte offset of hash entry in original database.
+ * @return 1 on error and 0 on success
+ */
+uint8_t
+tsk_hdb_idxaddentry(TSK_HDB_INFO * hdb_info, char *hvalue,
+                    TSK_OFF_T offset)
+{
+    return hdb_info->idx_info->addentry(hdb_info, hvalue, offset);
+}
+
+/**
+ * Add a binary hash entry to the index
+ *
+ * @param hdb_info Hash database state info
+ * @param hvalue Array of integers of hash value to add
+ * @param hlen Number of bytes in hvalue
+ * @param offset Byte offset of hash entry in original database.
+ * @return 1 on error and 0 on success
+ */
+uint8_t
+tsk_hdb_idxaddentry_bin(TSK_HDB_INFO * hdb_info, unsigned char *hvalue, int hlen,
+                    TSK_OFF_T offset)
+{
+    return hdb_info->idx_info->addentry_bin(hdb_info, hvalue, hlen, offset);
+}
+
+/**
+ * Finalize index creation process.
+ *
+ * @param hdb_info Hash database state info structure.
+ * @return 1 on error and 0 on success
+ */
+uint8_t
+tsk_hdb_idxfinalize(TSK_HDB_INFO * hdb_info)
+{
+    return hdb_info->idx_info->finalize(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_hasindex(TSK_HDB_INFO * hdb_info, uint8_t htype)
+{
+    /* Check if the index is already open, and 
+     * try to open it if not */
+    if (hdb_setupindex(hdb_info, htype, false)) {
+        return 0;
+    } else {
+        return 1;
+    }
+}
+
+
+
+/**
+ * \ingroup hashdblib
+ * Close an open hash index
+ *
+ * @param idx_info index to close
+ */
+void tsk_idx_close(TSK_IDX_INFO * idx_info)
+{
+    if (idx_info->idx_fname) {
+        free(idx_info->idx_fname);
+    }
+
+    idx_info->close(idx_info);
+}
+
+
+/**
+ * \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_makeindex(TSK_HDB_INFO * a_hdb_info, TSK_TCHAR * a_type)
+{
+    return a_hdb_info->makeindex(a_hdb_info, a_type);
+}
+
+/**
+ * Set db_name to the name of the database file
+ *
+ * @param hdb_info the hash database object
+ */
+void
+tsk_hdb_name_from_path(TSK_HDB_INFO * hdb_info)
+{
+#ifdef TSK_WIN32
+    const char PATH_CHAR = '\\';
+#else
+    const char PATH_CHAR = '/';
+#endif
+    TSK_TCHAR * begin;
+    TSK_TCHAR * end;
+    int i;
+
+    hdb_info->db_name[0] = '\0';
+
+    begin = TSTRRCHR(hdb_info->db_fname, PATH_CHAR);
+#ifdef TSK_WIN32
+    // cygwin can have forward slashes, so try that too on Windows
+    if (!begin) {
+        begin = TSTRRCHR(hdb_info->db_fname, '/');
+    }
+#endif
+
+    if (!begin) {
+        begin = hdb_info->db_fname;
+    }
+    else {
+        // unlikely since this means that the dbname is "/"
+        if (TSTRLEN(begin) == 1)
+            return;
+        else
+            begin++;
+    }
+
+    // end points to the byte after the last one we want to use
+    if ((TSTRLEN(hdb_info->db_fname) > 4) && (TSTRICMP(&hdb_info->db_fname[TSTRLEN(hdb_info->db_fname)-4], _TSK_T(".idx")) == 0)) 
+        end = &hdb_info->db_fname[TSTRLEN(hdb_info->db_fname)-4];
+    else
+        end = begin + TSTRLEN(begin);
+        
+
+    // @@@ TODO: Use TskUTF16_to_UTF8 to properly convert for Windows
+    for(i = 0; i < (end-begin); i++)
+    {
+        hdb_info->db_name[i] = (char) begin[i];
+    }
+
+    hdb_info->db_name[i] = '\0';
+}
diff --git a/tsk/hashdb/hdb_open.cpp b/tsk/hashdb/hdb_open.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..305a5fcfc28320a24b3a987f5e7611400a4819c8
--- /dev/null
+++ b/tsk/hashdb/hdb_open.cpp
@@ -0,0 +1,211 @@
+/*
+ * The Sleuth Kit
+ *
+ * Brian Carrier [carrier <at> sleuthkit [dot] org]
+ * Copyright (c) 2003-2013 Brian Carrier.  All rights reserved
+ *
+ *
+ * This software is distributed under the Common Public License 1.0
+ */
+
+#include "tsk_hashdb_i.h"
+
+
+/**
+ * \file hdb_open.c
+ * Contains the generic hash database creation and lookup code.
+ */
+
+
+
+/**
+ * \ingroup hashdblib
+ * Open an existing hash database. 
+ *
+ * @param db_file Path to database (even if only an index exists, in which case db path should still be listed).
+ * @param flags Flags for opening the database.  
+ *
+ * @return Poiner to hash database state structure or NULL on error
+ */
+TSK_HDB_INFO *
+tsk_hdb_open(TSK_TCHAR * db_file, TSK_HDB_OPEN_ENUM flags)
+{
+    TSK_HDB_INFO *hdb_info;
+    size_t flen;
+    FILE *hDb;
+    uint8_t dbtype = 0;
+
+    if ((flags & TSK_HDB_OPEN_IDXONLY) == 0) {
+        /* Open the database file */
+#ifdef TSK_WIN32
+        {
+            HANDLE hWin;
+
+            if ((hWin = CreateFile(db_file, GENERIC_READ,
+                                   FILE_SHARE_READ, 0, OPEN_EXISTING, 0,
+                                   0)) == INVALID_HANDLE_VALUE) {
+                tsk_error_reset();
+                tsk_error_set_errno(TSK_ERR_HDB_OPEN);
+                tsk_error_set_errstr(
+                         "hdb_open: Error opening database file: %S",
+                         db_file);
+                return NULL;
+            }
+            hDb =
+                _fdopen(_open_osfhandle((intptr_t) hWin, _O_RDONLY), "r");
+            if (hDb == NULL) {
+                tsk_error_reset();
+                tsk_error_set_errno(TSK_ERR_HDB_OPEN);
+                tsk_error_set_errstr(
+                         "hdb_open: Error converting Windows handle to C handle");
+                return NULL;
+            }
+        }
+#else
+        if (NULL == (hDb = fopen(db_file, "r"))) {
+            tsk_error_reset();
+            tsk_error_set_errno(TSK_ERR_HDB_OPEN);
+            tsk_error_set_errstr(
+                     "hdb_open: Error opening database file: %s", db_file);
+            return NULL;
+        }
+#endif
+
+        /* Try to figure out what type of DB it is */
+        if (nsrl_test(hDb)) {
+            dbtype = TSK_HDB_DBTYPE_NSRL_ID;
+        }
+        if (md5sum_test(hDb)) {
+            if (dbtype != 0) {
+                tsk_error_reset();
+                tsk_error_set_errno(TSK_ERR_HDB_UNKTYPE);
+                tsk_error_set_errstr(
+                         "hdb_open: Error determining DB type (MD5sum)");
+                return NULL;
+            }
+            dbtype = TSK_HDB_DBTYPE_MD5SUM_ID;
+        }
+        if (encase_test(hDb)) {
+            if (dbtype != 0) {
+                tsk_error_reset();
+                tsk_error_set_errno(TSK_ERR_HDB_UNKTYPE);
+                tsk_error_set_errstr(
+                         "hdb_open: Error determining DB type (EnCase)");
+                return NULL;
+            }
+            dbtype = TSK_HDB_DBTYPE_ENCASE_ID;
+        }
+        if (hk_test(hDb)) {
+            if (dbtype != 0) {
+                tsk_error_reset();
+                tsk_error_set_errno(TSK_ERR_HDB_UNKTYPE);
+                tsk_error_set_errstr(
+                         "hdb_open: Error determining DB type (HK)");
+                return NULL;
+            }
+            dbtype = TSK_HDB_DBTYPE_HK_ID;
+        }
+        if (dbtype == 0) {
+            tsk_error_reset();
+            tsk_error_set_errno(TSK_ERR_HDB_UNKTYPE);
+            tsk_error_set_errstr(
+                     "hdb_open: Error determining DB type");
+            return NULL;
+        }
+        fseeko(hDb, 0, SEEK_SET);
+    }
+    else {
+        dbtype = TSK_HDB_DBTYPE_IDXONLY_ID;
+        hDb = NULL;
+    }
+
+    if ((hdb_info =
+         (TSK_HDB_INFO *) tsk_malloc(sizeof(TSK_HDB_INFO))) == NULL)
+        return NULL;
+
+    hdb_info->hDb = hDb;
+
+    /* Copy the database name into the structure */
+    flen = TSTRLEN(db_file) + 8;        // + 32;
+
+    hdb_info->db_fname =
+        (TSK_TCHAR *) tsk_malloc(flen * sizeof(TSK_TCHAR));
+    if (hdb_info->db_fname == NULL) {
+        free(hdb_info);
+        return NULL;
+    }
+    TSTRNCPY(hdb_info->db_fname, db_file, flen);
+
+    
+    hdb_info->hash_type = static_cast<TSK_HDB_HTYPE_ENUM>(0);
+    hdb_info->hash_len = 0;
+    hdb_info->idx_info = NULL;
+
+    // Initialize mutex (or critical section) obj
+    tsk_init_lock(&hdb_info->lock);
+
+    /* Get database specific information */
+    hdb_info->db_type = static_cast<TSK_HDB_DBTYPE_ENUM>(dbtype);
+    switch (dbtype) {
+        case TSK_HDB_DBTYPE_NSRL_ID:
+            nsrl_name(hdb_info);
+            hdb_info->getentry = nsrl_getentry;
+            hdb_info->makeindex = nsrl_makeindex;
+            break;
+
+        case TSK_HDB_DBTYPE_MD5SUM_ID:
+            md5sum_name(hdb_info);
+            hdb_info->getentry = md5sum_getentry;
+            hdb_info->makeindex = md5sum_makeindex;
+            break;
+
+        case TSK_HDB_DBTYPE_ENCASE_ID:
+            encase_name(hdb_info);
+            hdb_info->getentry = encase_getentry;
+            hdb_info->makeindex = encase_makeindex;
+            break;
+
+        case TSK_HDB_DBTYPE_HK_ID:
+            hk_name(hdb_info);
+            hdb_info->getentry = hk_getentry;
+            hdb_info->makeindex = hk_makeindex;
+            break;
+
+        case TSK_HDB_DBTYPE_IDXONLY_ID:
+            idxonly_name(hdb_info);
+            hdb_info->getentry = idxonly_getentry;
+            hdb_info->makeindex = idxonly_makeindex;
+            break;
+
+        default:
+            return NULL;
+    }
+
+    return hdb_info;
+}
+
+
+
+/**
+ * \ingroup hashdblib
+ * Close an open hash database.
+ *
+ * @param hdb_info database to close
+ */
+void
+tsk_hdb_close(TSK_HDB_INFO * hdb_info)
+{
+    if (hdb_info->db_fname)
+        free(hdb_info->db_fname);
+
+    if (hdb_info->hDb)
+        fclose(hdb_info->hDb);
+
+    if (hdb_info->idx_info) {
+        tsk_idx_close(hdb_info->idx_info);
+    }
+
+    tsk_deinit_lock(&hdb_info->lock);
+
+    free(hdb_info);
+}
diff --git a/tsk/hashdb/sqlite_index.cpp b/tsk/hashdb/sqlite_index.cpp
index c1a831a6bd2ce71c952cff2bb50c980959fd3f19..3057d37ace629101f53000faf0c1c7e5a46f7a03 100644
--- a/tsk/hashdb/sqlite_index.cpp
+++ b/tsk/hashdb/sqlite_index.cpp
@@ -85,7 +85,7 @@ static uint8_t tsk_hdb_commit_transaction(TSK_IDX_INFO * idx_info) {
 	return attempt_exec_nocallback("COMMIT", "Error committing transaction %s\n", idx_info->idx_struct.idx_sqlite_v1->hIdx_sqlite);
 }
 
-/** Initialize the TSK hash DB index file.
+/** Initialize the TSK hash DB index file by creating tables, etc..
  *
  * @param hdb_info Hash database state structure
  * @param htype String of index type to create
@@ -125,11 +125,12 @@ sqlite_v1_initialize(TSK_HDB_INFO * hdb_info, TSK_TCHAR * htype)
 	}
 
 	if (attempt_exec_nocallback
-		("CREATE TABLE hashset_hashes (md5 BINARY(16), sha1 BINARY(20), database_offset INTEGER);",
+		("CREATE TABLE hashset_hashes (md5 BINARY(16), sha1 BINARY(20), sha256 BINARY(32), database_offset INTEGER);",
 		"Error creating hashset_hashes table %s\n", hdb_info->idx_info->idx_struct.idx_sqlite_v1->hIdx_sqlite)) {
 			return 1;
 	}
 
+    // @@@ This seems like the wrong long-term place for this because we could want to insert even if we don't initialize a new DB
 	if (hdb_info->hash_type == TSK_HDB_HTYPE_MD5_ID) {
 		insertStmt = "INSERT INTO hashset_hashes (md5, database_offset) VALUES (?, ?)";
 	} else if (hdb_info->hash_type == TSK_HDB_HTYPE_SHA1_ID) {
@@ -147,8 +148,9 @@ sqlite_v1_initialize(TSK_HDB_INFO * hdb_info, TSK_TCHAR * htype)
 	return 0;
 }
 
+
 /**
- * Add a string entry to the intermediate index file.
+ * Add a string representation of a hash value to the index.
  *
  * @param hdb_info Hash database state info
  * @param hvalue String of hash value to add
@@ -188,7 +190,7 @@ sqlite_v1_addentry(TSK_HDB_INFO * hdb_info, char *hvalue,
 }
 
 /**
- * Add a binary entry to the intermediate index file.
+ * Add a binary representation of a hash value into the index.
  *
  * @param hdb_info Hash database state info
  * @param hvalue Array of integers of hash value to add
@@ -217,8 +219,7 @@ sqlite_v1_addentry_bin(TSK_HDB_INFO * hdb_info, uint8_t* hvalue, int hlen,
 }
 
 /**
- * Finalize index creation process by sorting the index and removing the
- * intermediate temp file.
+ * Finalize index creation process
  *
  * @param hdb_info Hash database state info structure.
  * @return 1 on error and 0 on success
@@ -244,11 +245,11 @@ sqlite_v1_finalize(TSK_HDB_INFO * hdb_info)
 
 
 /** \internal
- * Setup the internal variables to read an index. This
+ * Setup the internal variables to read an index or database. This
  * opens the index and sets the needed size information.
  *
  * @param hdb_info Hash database to analyze
- * @param hash The hash type that was used to make the index.
+ * @param htype The hash type that was used to make the index.
  *
  * @return 1 on error and 0 on success
  */
diff --git a/tsk/hashdb/tm_lookup.cpp b/tsk/hashdb/tm_lookup.cpp
index 769447c3e95e95fd9f7394e0eb96e51675bdefe3..7029a772deddad5d47457628deee86bd4a3e738e 100644
--- a/tsk/hashdb/tm_lookup.cpp
+++ b/tsk/hashdb/tm_lookup.cpp
@@ -2,7 +2,7 @@
  * The Sleuth Kit
  *
  * Brian Carrier [carrier <at> sleuthkit [dot] org]
- * Copyright (c) 2003-2011 Brian Carrier.  All rights reserved
+ * Copyright (c) 2003-2013 Brian Carrier.  All rights reserved
  *
  *
  * This software is distributed under the Common Public License 1.0
@@ -13,388 +13,10 @@
 
 /**
  * \file tm_lookup.c
- * Contains the generic hash database creation and lookup code.
+ * Contains the generic hash database lookup code.
  */
 
 
-/**
- * Open an existing old plaintext idx structure.
- * We can load both kdb (SQLite) and the old plaintext idx files.
- */
-FILE *
-tsk_idx_open_file(TSK_TCHAR *idx_fname)
-{
-    if (idx_fname == NULL) {
-        return NULL;
-    }
-
-    FILE * idx = NULL;
-
-#ifdef TSK_WIN32
-    {
-        HANDLE hWin;
-        //DWORD szLow, szHi;
-
-        if (-1 == GetFileAttributes(idx_fname)) {
-            //tsk_release_lock(&idx_info->lock);
-            tsk_error_reset();
-            tsk_error_set_errno(TSK_ERR_HDB_MISSING);
-            tsk_error_set_errstr(
-                    "tsk_idx_open_file: Error finding index file: %"PRIttocTSK,
-                    idx_fname);
-            return NULL;
-        }
-
-        if ((hWin = CreateFile(idx_fname, GENERIC_READ,
-                        FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0)) ==
-                INVALID_HANDLE_VALUE) {
-            //tsk_release_lock(&idx_info->lock);
-            tsk_error_reset();
-            tsk_error_set_errno(TSK_ERR_HDB_OPEN);
-            tsk_error_set_errstr(
-                    "tsk_idx_open_file: Error opening index file: %"PRIttocTSK,
-                    idx_fname);
-            return NULL;
-        }
-
-        idx = _fdopen(_open_osfhandle((intptr_t) hWin, _O_RDONLY), "r");
-    }
-#else
-    {
-        idx = fopen(idx_fname, "r");
-    }
-#endif
-
-    return idx;
-}
-
-
-/**
- * Open a newly created blank index file for the given hash db
- * We only create kdb (SQLite) files.
- * @return NULL on error, TSK_IDX_INFO instance on success
- */
-TSK_IDX_INFO *
-tsk_idx_open(TSK_HDB_INFO * hdb_info, uint8_t htype, bool create)
-{
-    TSK_IDX_INFO * idx_info;
-    size_t flen;
-    const int header_size = 16;
-    char header[header_size];
-    FILE * idx = NULL;
-
-    if (hdb_info->idx_info != NULL) {
-        return hdb_info->idx_info;
-    }
-
-    if ((idx_info =
-         (TSK_IDX_INFO *) tsk_malloc(sizeof(TSK_IDX_INFO))) == NULL) {
-        return NULL;
-    }
-
-    hdb_info->idx_info = idx_info;
-
-    /* Make the name for the index file */
-    flen = TSTRLEN(hdb_info->db_fname) + 32;
-    idx_info->idx_fname =
-        (TSK_TCHAR *) tsk_malloc(flen * sizeof(TSK_TCHAR));
-    if (idx_info->idx_fname == NULL) {
-        free(idx_info);
-        return NULL;
-    }
-
-    /* Get hash type specific information */
-    switch (htype) {
-        case TSK_HDB_HTYPE_MD5_ID:
-            hdb_info->hash_type = static_cast<TSK_HDB_HTYPE_ENUM>(htype);
-            hdb_info->hash_len = TSK_HDB_HTYPE_MD5_LEN;
-            TSNPRINTF(idx_info->idx_fname, flen,
-                    _TSK_T("%s.kdb"),
-                    hdb_info->db_fname);
-            break;
-        case TSK_HDB_HTYPE_SHA1_ID:
-            hdb_info->hash_type = static_cast<TSK_HDB_HTYPE_ENUM>(htype);
-            hdb_info->hash_len = TSK_HDB_HTYPE_SHA1_LEN;
-            TSNPRINTF(idx_info->idx_fname, flen,
-                    _TSK_T("%s.kdb"),
-                    hdb_info->db_fname);
-            break;
-        default:
-            free(idx_info);
-            return NULL;
-    }
-
-
-    // Verify the index exists, get its size, and open it for header reading
-    if ((idx = tsk_idx_open_file(idx_info->idx_fname)) == NULL) {
-
-        // If file DNE, then we might want to create a new one
-        if (create) {
-            idx_info->index_type = TSK_HDB_ITYPE_SQLITE_V1;
-        } else {
-            // Try opening an old format index file
-
-            // Change the filename to the old format
-            switch (htype) {
-                case TSK_HDB_HTYPE_MD5_ID:
-                    TSNPRINTF(idx_info->idx_fname, flen,
-                              _TSK_T("%s-%") PRIcTSK _TSK_T(".idx"),
-                              hdb_info->db_fname, TSK_HDB_HTYPE_MD5_STR);
-                    break;
-                case TSK_HDB_HTYPE_SHA1_ID:
-                    TSNPRINTF(idx_info->idx_fname, flen,
-                              _TSK_T("%s-%") PRIcTSK _TSK_T(".idx"),
-                              hdb_info->db_fname, TSK_HDB_HTYPE_SHA1_STR);
-                    break;
-            }
-
-            idx = tsk_idx_open_file(idx_info->idx_fname);
-
-            if (!idx) {
-                free(idx_info);
-                return NULL;
-            }
-        }
-    }
-
-    // Read header (if this was an existing file)
-    if (idx) {
-        if (NULL == fread(header, header_size, 1, idx)) {
-            ///@todo should this actually be an error?
-            idx_info->index_type = TSK_HDB_ITYPE_SQLITE_V1;
-        } else if (strncmp(header,
-                    IDX_SQLITE_V1_HEADER,
-                    strlen(IDX_SQLITE_V1_HEADER)) == 0) {
-            idx_info->index_type = TSK_HDB_ITYPE_SQLITE_V1;
-        } else if (strncmp(header,
-                    IDX_PLAIN_TXT_HEADER,
-                    strlen(IDX_PLAIN_TXT_HEADER)) == 0) {
-            idx_info->index_type = TSK_HDB_ITYPE_PLAIN_TXT;
-        } else {
-            tsk_error_reset();
-            tsk_error_set_errno(TSK_ERR_HDB_MISSING);
-            tsk_error_set_errstr(
-                    "tsk_idx_open: Unrecognized header format: %s\n",
-                    idx_info->idx_fname);
-            free(idx_info);
-            return NULL;
-        }
-    }
-
-    // Set up function pointers based on index type
-    switch (idx_info->index_type) {
-        case TSK_HDB_ITYPE_SQLITE_V1:
-            idx_info->open = sqlite_v1_open;
-            idx_info->close = sqlite_v1_close;
-            idx_info->initialize = sqlite_v1_initialize;
-            idx_info->addentry = sqlite_v1_addentry;
-            idx_info->addentry_bin = sqlite_v1_addentry_bin;
-            idx_info->finalize = sqlite_v1_finalize;
-            idx_info->lookup_str = sqlite_v1_lookup_str;
-            idx_info->lookup_raw = sqlite_v1_lookup_raw;
-            break;
-        case TSK_HDB_ITYPE_PLAIN_TXT:
-            idx_info->open = plain_txt_open;
-            idx_info->close = plain_txt_close;
-            idx_info->initialize = plain_txt_initialize;
-            idx_info->addentry = plain_txt_addentry;
-            idx_info->addentry_bin = plain_txt_addentry_bin;
-            idx_info->finalize = plain_txt_finalize;
-            idx_info->lookup_str = plain_txt_lookup_str;
-            idx_info->lookup_raw = plain_txt_lookup_raw;
-            break;
-        default:
-            free(idx_info);
-            return NULL;
-    }
-
-    // Open
-    if (idx_info->open(hdb_info, idx_info, htype) == 0) {
-        return idx_info;
-    }
-
-    tsk_error_reset();
-    tsk_error_set_errno(TSK_ERR_HDB_ARG);
-    tsk_error_set_errstr(
-             "Error setting up idx_info struct: %d\n", htype);
-    free(idx_info);
-    return NULL;
-}
-
-
-/**
- * Set up the internal index structures
- * @return 0 if already set up or if setup successful, 1 otherwise
- */
-uint8_t
-hdb_setupindex(TSK_HDB_INFO * hdb_info, uint8_t htype, bool create)
-{
-    // Lock for lazy load of idx_info and lazy alloc of idx_lbuf.
-    tsk_take_lock(&hdb_info->lock);
-
-    if (hdb_info->idx_info != NULL) {
-        tsk_release_lock(&hdb_info->lock);
-        return 0;
-    }
-
-    hdb_info->idx_info = tsk_idx_open(hdb_info, htype, create);
-
-
-    if (hdb_info->idx_info != NULL) {
-        tsk_release_lock(&hdb_info->lock);
-        return 0;
-    }
-
-    tsk_release_lock(&hdb_info->lock);
-    return 1;
-}
-
-
-/** Initialize the TSK hash DB index file. This creates the intermediate file,
- * which will have entries added to it.
- *
- * @param hdb_info Hash database state structure
- * @param htype String of index type to create
- *
- * @return 1 on error and 0 on success
- *
- */
-uint8_t
-tsk_hdb_idxinitialize(TSK_HDB_INFO * hdb_info, TSK_TCHAR * htype)
-{
-    char dbtmp[32];
-    int i;
-    bool create = true; //create new file if it doesn't already exist
-
-    /* Use the string of the index/hash type to figure out some
-     * settings */
-
-    // convert to char -- cheating way to deal with WCHARs..
-    for (i = 0; i < 31 && htype[i] != '\0'; i++) {
-        dbtmp[i] = (char) htype[i];
-    }
-    dbtmp[i] = '\0';
-
-    if (strcmp(dbtmp, TSK_HDB_DBTYPE_NSRL_MD5_STR) == 0) {
-
-        if (hdb_info->db_type != TSK_HDB_DBTYPE_NSRL_ID) {
-            tsk_error_reset();
-            tsk_error_set_errno(TSK_ERR_HDB_ARG);
-            tsk_error_set_errstr(
-                     "hdb_idxinitialize: database detected as: %d index creation as: %d",
-                     hdb_info->db_type, TSK_HDB_DBTYPE_NSRL_ID);
-            return 1;
-        }
-        hdb_info->hash_type = TSK_HDB_HTYPE_MD5_ID;
-    }
-    else if (strcmp(dbtmp, TSK_HDB_DBTYPE_NSRL_SHA1_STR) == 0) {
-        if (hdb_info->db_type != TSK_HDB_DBTYPE_NSRL_ID) {
-            tsk_error_reset();
-            tsk_error_set_errno(TSK_ERR_HDB_ARG);
-            tsk_error_set_errstr(
-                     "hdb_idxinitialize: database detected as: %d index creation as: %d",
-                     hdb_info->db_type, TSK_HDB_DBTYPE_NSRL_ID);
-            return 1;
-        }
-        hdb_info->hash_type = TSK_HDB_HTYPE_SHA1_ID;
-    }
-    else if (strcmp(dbtmp, TSK_HDB_DBTYPE_MD5SUM_STR) == 0) {
-        if (hdb_info->db_type != TSK_HDB_DBTYPE_MD5SUM_ID) {
-            tsk_error_reset();
-            tsk_error_set_errno(TSK_ERR_HDB_ARG);
-            tsk_error_set_errstr(
-                     "hdb_idxinitialize: database detected as: %d index creation as: %d",
-                     hdb_info->db_type, TSK_HDB_DBTYPE_MD5SUM_ID);
-            return 1;
-        }
-        hdb_info->hash_type = TSK_HDB_HTYPE_MD5_ID;
-    }
-    else if (strcmp(dbtmp, TSK_HDB_DBTYPE_HK_STR) == 0) {
-        if (hdb_info->db_type != TSK_HDB_DBTYPE_HK_ID) {
-            tsk_error_reset();
-            tsk_error_set_errno(TSK_ERR_HDB_ARG);
-            tsk_error_set_errstr(
-                     "hdb_idxinitialize: database detected as: %d index creation as: %d",
-                     hdb_info->db_type, TSK_HDB_DBTYPE_HK_ID);
-            return 1;
-        }
-        hdb_info->hash_type = TSK_HDB_HTYPE_MD5_ID;
-    }
-    else if (strcmp(dbtmp, TSK_HDB_DBTYPE_ENCASE_STR) == 0) {
-        if (hdb_info->db_type != TSK_HDB_DBTYPE_ENCASE_ID) {
-            tsk_error_reset();
-            tsk_error_set_errno(TSK_ERR_HDB_ARG);
-            tsk_error_set_errstr(
-                     "hdb_idxinitialize: database detected as: %d index creation as: %d",
-                     hdb_info->db_type, TSK_HDB_DBTYPE_ENCASE_ID);
-            return 1;
-        }
-        hdb_info->hash_type = TSK_HDB_HTYPE_MD5_ID;
-    }
-    else {
-        tsk_error_reset();
-        tsk_error_set_errno(TSK_ERR_HDB_ARG);
-        tsk_error_set_errstr(
-                 "hdb_idxinitialize: Unknown database type request: %s",
-                 dbtmp);
-        return 1;
-    }
-
-    /* Setup the internal hash information */
-    if (hdb_setupindex(hdb_info, hdb_info->hash_type, create)) {
-        return 1;
-    }
-
-    /* Call htype-specific initialize function */
-	return hdb_info->idx_info->initialize(hdb_info, htype);
-}
-
-/**
- * Add a string entry to the intermediate index file.
- *
- * @param hdb_info Hash database state info
- * @param hvalue String of hash value to add
- * @param offset Byte offset of hash entry in original database.
- * @return 1 on error and 0 on success
- */
-uint8_t
-tsk_hdb_idxaddentry(TSK_HDB_INFO * hdb_info, char *hvalue,
-                    TSK_OFF_T offset)
-{
-    return hdb_info->idx_info->addentry(hdb_info, hvalue, offset);
-}
-
-/**
- * Add a binary entry to the intermediate index file.
- *
- * @param hdb_info Hash database state info
- * @param hvalue Array of integers of hash value to add
- * @param hlen Number of bytes in hvalue
- * @param offset Byte offset of hash entry in original database.
- * @return 1 on error and 0 on success
- */
-uint8_t
-tsk_hdb_idxaddentry_bin(TSK_HDB_INFO * hdb_info, unsigned char *hvalue, int hlen,
-                    TSK_OFF_T offset)
-{
-    return hdb_info->idx_info->addentry_bin(hdb_info, hvalue, hlen, offset);
-}
-
-/**
- * Finalize index creation process by sorting the index and removing the
- * intermediate temp file.
- *
- * @param hdb_info Hash database state info structure.
- * @return 1 on error and 0 on success
- */
-uint8_t
-tsk_hdb_idxfinalize(TSK_HDB_INFO * hdb_info)
-{
-    return hdb_info->idx_info->finalize(hdb_info);
-}
-
-
-
 
 /**
  * \ingroup hashdblib
@@ -481,298 +103,3 @@ tsk_hdb_lookup_raw(TSK_HDB_INFO * hdb_info, uint8_t * hash, uint8_t len,
 
 	return hdb_info->idx_info->lookup_raw(hdb_info, hash, len, flags, action, ptr);
 }
-
-/**
- * \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_hasindex(TSK_HDB_INFO * hdb_info, uint8_t htype)
-{
-    /* Check if the index is already open, and 
-     * try to open it if not */
-    if (hdb_setupindex(hdb_info, htype, false)) {
-        return 0;
-    } else {
-        return 1;
-    }
-}
-
-
-/**
- * \ingroup hashdblib
- * Open a hash database. 
- *
- * @param db_file Path to database (even if only an index exists).
- * @param flags Flags for opening the database.  
- *
- * @return Poiner to hash database state structure or NULL on error
- */
-TSK_HDB_INFO *
-tsk_hdb_open(TSK_TCHAR * db_file, TSK_HDB_OPEN_ENUM flags)
-{
-    TSK_HDB_INFO *hdb_info;
-    size_t flen;
-    FILE *hDb;
-    uint8_t dbtype = 0;
-
-    if ((flags & TSK_HDB_OPEN_IDXONLY) == 0) {
-        /* Open the database file */
-#ifdef TSK_WIN32
-        {
-            HANDLE hWin;
-
-            if ((hWin = CreateFile(db_file, GENERIC_READ,
-                                   FILE_SHARE_READ, 0, OPEN_EXISTING, 0,
-                                   0)) == INVALID_HANDLE_VALUE) {
-                tsk_error_reset();
-                tsk_error_set_errno(TSK_ERR_HDB_OPEN);
-                tsk_error_set_errstr(
-                         "hdb_open: Error opening database file: %S",
-                         db_file);
-                return NULL;
-            }
-            hDb =
-                _fdopen(_open_osfhandle((intptr_t) hWin, _O_RDONLY), "r");
-            if (hDb == NULL) {
-                tsk_error_reset();
-                tsk_error_set_errno(TSK_ERR_HDB_OPEN);
-                tsk_error_set_errstr(
-                         "hdb_open: Error converting Windows handle to C handle");
-                return NULL;
-            }
-        }
-#else
-        if (NULL == (hDb = fopen(db_file, "r"))) {
-            tsk_error_reset();
-            tsk_error_set_errno(TSK_ERR_HDB_OPEN);
-            tsk_error_set_errstr(
-                     "hdb_open: Error opening database file: %s", db_file);
-            return NULL;
-        }
-#endif
-
-        /* Try to figure out what type of DB it is */
-        if (nsrl_test(hDb)) {
-            dbtype = TSK_HDB_DBTYPE_NSRL_ID;
-        }
-        if (md5sum_test(hDb)) {
-            if (dbtype != 0) {
-                tsk_error_reset();
-                tsk_error_set_errno(TSK_ERR_HDB_UNKTYPE);
-                tsk_error_set_errstr(
-                         "hdb_open: Error determining DB type (MD5sum)");
-                return NULL;
-            }
-            dbtype = TSK_HDB_DBTYPE_MD5SUM_ID;
-        }
-        if (encase_test(hDb)) {
-            if (dbtype != 0) {
-                tsk_error_reset();
-                tsk_error_set_errno(TSK_ERR_HDB_UNKTYPE);
-                tsk_error_set_errstr(
-                         "hdb_open: Error determining DB type (EnCase)");
-                return NULL;
-            }
-            dbtype = TSK_HDB_DBTYPE_ENCASE_ID;
-        }
-        if (hk_test(hDb)) {
-            if (dbtype != 0) {
-                tsk_error_reset();
-                tsk_error_set_errno(TSK_ERR_HDB_UNKTYPE);
-                tsk_error_set_errstr(
-                         "hdb_open: Error determining DB type (HK)");
-                return NULL;
-            }
-            dbtype = TSK_HDB_DBTYPE_HK_ID;
-        }
-        if (dbtype == 0) {
-            tsk_error_reset();
-            tsk_error_set_errno(TSK_ERR_HDB_UNKTYPE);
-            tsk_error_set_errstr(
-                     "hdb_open: Error determining DB type");
-            return NULL;
-        }
-        fseeko(hDb, 0, SEEK_SET);
-    }
-    else {
-        dbtype = TSK_HDB_DBTYPE_IDXONLY_ID;
-        hDb = NULL;
-    }
-
-    if ((hdb_info =
-         (TSK_HDB_INFO *) tsk_malloc(sizeof(TSK_HDB_INFO))) == NULL)
-        return NULL;
-
-    hdb_info->hDb = hDb;
-
-    /* Copy the database name into the structure */
-    flen = TSTRLEN(db_file) + 8;        // + 32;
-
-    hdb_info->db_fname =
-        (TSK_TCHAR *) tsk_malloc(flen * sizeof(TSK_TCHAR));
-    if (hdb_info->db_fname == NULL) {
-        free(hdb_info);
-        return NULL;
-    }
-    TSTRNCPY(hdb_info->db_fname, db_file, flen);
-
-    
-    hdb_info->hash_type = static_cast<TSK_HDB_HTYPE_ENUM>(0);
-    hdb_info->hash_len = 0;
-    hdb_info->idx_info = NULL;
-
-    // Initialize mutex (or critical section) obj
-    tsk_init_lock(&hdb_info->lock);
-
-    /* Get database specific information */
-    hdb_info->db_type = static_cast<TSK_HDB_DBTYPE_ENUM>(dbtype);
-    switch (dbtype) {
-        case TSK_HDB_DBTYPE_NSRL_ID:
-            nsrl_name(hdb_info);
-            hdb_info->getentry = nsrl_getentry;
-            hdb_info->makeindex = nsrl_makeindex;
-            break;
-
-        case TSK_HDB_DBTYPE_MD5SUM_ID:
-            md5sum_name(hdb_info);
-            hdb_info->getentry = md5sum_getentry;
-            hdb_info->makeindex = md5sum_makeindex;
-            break;
-
-        case TSK_HDB_DBTYPE_ENCASE_ID:
-            encase_name(hdb_info);
-            hdb_info->getentry = encase_getentry;
-            hdb_info->makeindex = encase_makeindex;
-            break;
-
-        case TSK_HDB_DBTYPE_HK_ID:
-            hk_name(hdb_info);
-            hdb_info->getentry = hk_getentry;
-            hdb_info->makeindex = hk_makeindex;
-            break;
-
-        case TSK_HDB_DBTYPE_IDXONLY_ID:
-            idxonly_name(hdb_info);
-            hdb_info->getentry = idxonly_getentry;
-            hdb_info->makeindex = idxonly_makeindex;
-            break;
-
-        default:
-            return NULL;
-    }
-
-
-    return hdb_info;
-}
-
-/**
- * \ingroup hashdblib
- * Close an open hash index
- *
- * @param idx_info index to close
- */
-void tsk_idx_close(TSK_IDX_INFO * idx_info)
-{
-    if (idx_info->idx_fname) {
-        free(idx_info->idx_fname);
-    }
-
-    idx_info->close(idx_info);
-}
-
-/**
- * \ingroup hashdblib
- * Close an open hash database.
- *
- * @param hdb_info database to close
- */
-void
-tsk_hdb_close(TSK_HDB_INFO * hdb_info)
-{
-    if (hdb_info->db_fname)
-        free(hdb_info->db_fname);
-
-    if (hdb_info->hDb)
-        fclose(hdb_info->hDb);
-
-    if (hdb_info->idx_info) {
-        tsk_idx_close(hdb_info->idx_info);
-    }
-
-    tsk_deinit_lock(&hdb_info->lock);
-
-    free(hdb_info);
-}
-
-/**
- * \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_makeindex(TSK_HDB_INFO * a_hdb_info, TSK_TCHAR * a_type)
-{
-    return a_hdb_info->makeindex(a_hdb_info, a_type);
-}
-
-/**
- * Set db_name to the name of the database file
- *
- * @param hdb_info the hash database object
- */
-void
-tsk_hdb_name_from_path(TSK_HDB_INFO * hdb_info)
-{
-#ifdef TSK_WIN32
-    const char PATH_CHAR = '\\';
-#else
-    const char PATH_CHAR = '/';
-#endif
-    TSK_TCHAR * begin;
-    TSK_TCHAR * end;
-    int i;
-
-    hdb_info->db_name[0] = '\0';
-
-    begin = TSTRRCHR(hdb_info->db_fname, PATH_CHAR);
-#ifdef TSK_WIN32
-    // cygwin can have forward slashes, so try that too on Windows
-    if (!begin) {
-        begin = TSTRRCHR(hdb_info->db_fname, '/');
-    }
-#endif
-
-    if (!begin) {
-        begin = hdb_info->db_fname;
-    }
-    else {
-        // unlikely since this means that the dbname is "/"
-        if (TSTRLEN(begin) == 1)
-            return;
-        else
-            begin++;
-    }
-
-    // end points to the byte after the last one we want to use
-    if ((TSTRLEN(hdb_info->db_fname) > 4) && (TSTRICMP(&hdb_info->db_fname[TSTRLEN(hdb_info->db_fname)-4], _TSK_T(".idx")) == 0)) 
-        end = &hdb_info->db_fname[TSTRLEN(hdb_info->db_fname)-4];
-    else
-        end = begin + TSTRLEN(begin);
-        
-
-    // @@@ TODO: Use TskUTF16_to_UTF8 to properly convert for Windows
-    for(i = 0; i < (end-begin); i++)
-    {
-        hdb_info->db_name[i] = (char) begin[i];
-    }
-
-    hdb_info->db_name[i] = '\0';
-}
diff --git a/tsk/hashdb/tsk_hashdb.h b/tsk/hashdb/tsk_hashdb.h
index 06a82b04a6025a05eeb25caafc772a1921ede2ef..071ff55df0c177e1bc8e691d26c3ea4e8bbbd483 100644
--- a/tsk/hashdb/tsk_hashdb.h
+++ b/tsk/hashdb/tsk_hashdb.h
@@ -96,12 +96,12 @@ extern "C" {
 
 
     /* String versions of DB types */
-#define TSK_HDB_DBTYPE_NSRL_STR		        "nsrl"  ///< NSRL String name
-#define TSK_HDB_DBTYPE_NSRL_MD5_STR		"nsrl-md5"      ///< NSRL md5 string name
-#define TSK_HDB_DBTYPE_NSRL_SHA1_STR		"nsrl-sha1"     ///< NSRL SHA1 string name
-#define TSK_HDB_DBTYPE_MD5SUM_STR		"md5sum"        ///< md5sum db string n ame
-#define TSK_HDB_DBTYPE_HK_STR			"hk"    ///< hash keeper string name
-#define TSK_HDB_DBTYPE_ENCASE_STR			"encase"    ///< encase string name
+#define TSK_HDB_DBTYPE_NSRL_STR		        "nsrl"  ///< NSRL database 
+#define TSK_HDB_DBTYPE_NSRL_MD5_STR		"nsrl-md5"      ///< NSRL database with MD5 index
+#define TSK_HDB_DBTYPE_NSRL_SHA1_STR		"nsrl-sha1"     ///< NSRL database with SHA1 index
+#define TSK_HDB_DBTYPE_MD5SUM_STR		"md5sum"        ///< md5sum database
+#define TSK_HDB_DBTYPE_HK_STR			"hk"    ///< hash keeper index
+#define TSK_HDB_DBTYPE_ENCASE_STR			"encase"    ///< encase index
     /// List of supported data base types
 #define TSK_HDB_DBTYPE_SUPPORT_STR		"nsrl-md5, nsrl-sha1, md5sum, encase, hk"
 
diff --git a/tsk/hashdb/tsk_hashdb_i.h b/tsk/hashdb/tsk_hashdb_i.h
index b0820c80a2ae3358e52f2c9e7af0bebb00a14da5..60101da395f54f5fa3a60cfcaed763756eba2561 100644
--- a/tsk/hashdb/tsk_hashdb_i.h
+++ b/tsk/hashdb/tsk_hashdb_i.h
@@ -67,6 +67,11 @@ extern "C" {
 #define IDX_SQLITE_V1_HEADER "SQLite format 3"
 
 
+    extern uint8_t
+        hdb_setupindex(TSK_HDB_INFO * hdb_info, uint8_t htype, uint8_t create);
+
+    extern void tsk_idx_close(TSK_IDX_INFO * idx_info);
+
     extern uint8_t tsk_hdb_idxinitialize(TSK_HDB_INFO *,
                                          TSK_TCHAR * dbname);
     extern uint8_t tsk_hdb_idxaddentry(TSK_HDB_INFO *, char *hvalue,