diff --git a/tsk/hashdb/Makefile.am b/tsk/hashdb/Makefile.am
index 4f69ed91db93ac93fbe5b8b596bcf91084fa68fb..e5027f08de3d054c5bdce6877491fda29d24dc07 100644
--- a/tsk/hashdb/Makefile.am
+++ b/tsk/hashdb/Makefile.am
@@ -2,12 +2,12 @@ AM_CPPFLAGS = -I../.. -I$(srcdir)/../.. -Wall
 EXTRA_DIST = .indent.pro
 
 noinst_LTLIBRARIES = libtskhashdb.la
-libtskhashdb_la_SOURCES = ascii_index.c sqlite_index.c \
-    tm_lookup.c md5sum_index.c nsrl_index.c \
+libtskhashdb_la_SOURCES = ascii_index.c sqlite_index.cpp \
+    tm_lookup.cpp md5sum_index.c nsrl_index.c \
     hk_index.c idxonly_index.c encase_index.c tsk_hashdb_i.h
 
 indent:
-	indent *.c *.h
+	indent *.cpp *.c *.h
 
 clean-local:
 	-rm -f *.c~ *.h~
diff --git a/tsk/hashdb/ascii_index.c b/tsk/hashdb/ascii_index.c
index 10169236801206ad2c9ec6ddc8842b87ca3f26fc..98762eeddd67b057772d0ebcfd6e76bea1f79ce2 100644
--- a/tsk/hashdb/ascii_index.c
+++ b/tsk/hashdb/ascii_index.c
@@ -111,7 +111,6 @@ plain_txt_open(TSK_HDB_INFO * hdb_info, TSK_IDX_INFO * idx_info, uint8_t htype)
 
     if ((htype != TSK_HDB_HTYPE_MD5_ID)
             && (htype != TSK_HDB_HTYPE_SHA1_ID)) {
-        tsk_release_lock(&idx_info->lock);
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_HDB_ARG);
         tsk_error_set_errstr(
@@ -128,7 +127,6 @@ plain_txt_open(TSK_HDB_INFO * hdb_info, TSK_IDX_INFO * idx_info, uint8_t htype)
         DWORD szLow, szHi;
 
         if (-1 == GetFileAttributes(idx_info->idx_fname)) {
-            tsk_release_lock(&idx_info->lock);
             tsk_error_reset();
             tsk_error_set_errno(TSK_ERR_HDB_MISSING);
             tsk_error_set_errstr(
@@ -140,7 +138,6 @@ plain_txt_open(TSK_HDB_INFO * hdb_info, TSK_IDX_INFO * idx_info, uint8_t htype)
         if ((hWin = CreateFile(idx_info->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(
@@ -151,7 +148,6 @@ plain_txt_open(TSK_HDB_INFO * hdb_info, TSK_IDX_INFO * idx_info, uint8_t htype)
         idx_info->idx_struct.idx_plain_txt->hIdx =
             _fdopen(_open_osfhandle((intptr_t) hWin, _O_RDONLY), "r");
         if (idx_info->idx_struct.idx_plain_txt->hIdx == NULL) {
-            tsk_release_lock(&idx_info->lock);
             tsk_error_reset();
             tsk_error_set_errno(TSK_ERR_HDB_OPEN);
             tsk_error_set_errstr(
@@ -161,7 +157,6 @@ plain_txt_open(TSK_HDB_INFO * hdb_info, TSK_IDX_INFO * idx_info, uint8_t htype)
 
         szLow = GetFileSize(hWin, &szHi);
         if (szLow == 0xffffffff) {
-            tsk_release_lock(&idx_info->lock);
             tsk_error_reset();
             tsk_error_set_errno(TSK_ERR_HDB_OPEN);
             tsk_error_set_errstr(
@@ -176,7 +171,6 @@ plain_txt_open(TSK_HDB_INFO * hdb_info, TSK_IDX_INFO * idx_info, uint8_t htype)
     {
         struct stat sb;
         if (stat(idx_info->idx_fname, &sb) < 0) {
-            tsk_release_lock(&idx_info->lock);
             tsk_error_reset();
             tsk_error_set_errno(TSK_ERR_HDB_MISSING);
             tsk_error_set_errstr(
@@ -187,7 +181,6 @@ plain_txt_open(TSK_HDB_INFO * hdb_info, TSK_IDX_INFO * idx_info, uint8_t htype)
         idx_info->idx_struct.idx_plain_txt->idx_size = sb.st_size;
 
         if (NULL == (idx_info->idx_struct.idx_plain_txt->hIdx = fopen(idx_info->idx_fname, "r"))) {
-            tsk_release_lock(&idx_info->lock);
             tsk_error_reset();
             tsk_error_set_errno(TSK_ERR_HDB_OPEN);
             tsk_error_set_errstr(
@@ -201,7 +194,6 @@ plain_txt_open(TSK_HDB_INFO * hdb_info, TSK_IDX_INFO * idx_info, uint8_t htype)
 
     /* Do some testing on the first line */
     if (NULL == fgets(head, TSK_HDB_MAXLEN, idx_info->idx_struct.idx_plain_txt->hIdx)) {
-        tsk_release_lock(&idx_info->lock);
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_HDB_READIDX);
         tsk_error_set_errstr(
@@ -211,7 +203,6 @@ plain_txt_open(TSK_HDB_INFO * hdb_info, TSK_IDX_INFO * idx_info, uint8_t htype)
 
     if (strncmp(head, TSK_HDB_IDX_HEAD_TYPE_STR, strlen(TSK_HDB_IDX_HEAD_TYPE_STR))
         != 0) {
-        tsk_release_lock(&idx_info->lock);
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_HDB_UNKTYPE);
         tsk_error_set_errstr(
@@ -221,7 +212,6 @@ plain_txt_open(TSK_HDB_INFO * hdb_info, TSK_IDX_INFO * idx_info, uint8_t htype)
 
     /* Do some testing on the second line */
     if (NULL == fgets(head2, TSK_HDB_MAXLEN, idx_info->idx_struct.idx_plain_txt->hIdx)) {
-        tsk_release_lock(&idx_info->lock);
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_HDB_READIDX);
         tsk_error_set_errstr(
@@ -251,7 +241,6 @@ plain_txt_open(TSK_HDB_INFO * hdb_info, TSK_IDX_INFO * idx_info, uint8_t htype)
     if (strcmp(ptr, TSK_HDB_DBTYPE_NSRL_STR) == 0) {
         if ((hdb_info->db_type != TSK_HDB_DBTYPE_NSRL_ID) &&
             (hdb_info->db_type != TSK_HDB_DBTYPE_IDXONLY_ID)) {
-            tsk_release_lock(&idx_info->lock);
             tsk_error_reset();
             tsk_error_set_errno(TSK_ERR_HDB_UNKTYPE);
             tsk_error_set_errstr(
@@ -263,7 +252,6 @@ plain_txt_open(TSK_HDB_INFO * hdb_info, TSK_IDX_INFO * idx_info, uint8_t htype)
     else if (strcmp(ptr, TSK_HDB_DBTYPE_MD5SUM_STR) == 0) {
         if ((hdb_info->db_type != TSK_HDB_DBTYPE_MD5SUM_ID) &&
             (hdb_info->db_type != TSK_HDB_DBTYPE_IDXONLY_ID)) {
-            tsk_release_lock(&idx_info->lock);
             tsk_error_reset();
             tsk_error_set_errno(TSK_ERR_HDB_UNKTYPE);
             tsk_error_set_errstr(
@@ -275,7 +263,6 @@ plain_txt_open(TSK_HDB_INFO * hdb_info, TSK_IDX_INFO * idx_info, uint8_t htype)
     else if (strcmp(ptr, TSK_HDB_DBTYPE_HK_STR) == 0) {
         if ((hdb_info->db_type != TSK_HDB_DBTYPE_HK_ID) &&
             (hdb_info->db_type != TSK_HDB_DBTYPE_IDXONLY_ID)) {
-            tsk_release_lock(&idx_info->lock);
             tsk_error_reset();
             tsk_error_set_errno(TSK_ERR_HDB_UNKTYPE);
             tsk_error_set_errstr(
@@ -285,7 +272,6 @@ plain_txt_open(TSK_HDB_INFO * hdb_info, TSK_IDX_INFO * idx_info, uint8_t htype)
         }
     }
     else if (hdb_info->db_type != TSK_HDB_DBTYPE_IDXONLY_ID) {
-        tsk_release_lock(&idx_info->lock);
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_HDB_UNKTYPE);
         tsk_error_set_errstr(
@@ -297,7 +283,6 @@ plain_txt_open(TSK_HDB_INFO * hdb_info, TSK_IDX_INFO * idx_info, uint8_t htype)
     /* Do some sanity checking */
     if (((idx_info->idx_struct.idx_plain_txt->idx_size - idx_info->idx_struct.idx_plain_txt->idx_off) % idx_info->idx_struct.idx_plain_txt->idx_llen) !=
         0) {
-        tsk_release_lock(&idx_info->lock);
         tsk_error_reset();
         tsk_error_set_errno(TSK_ERR_HDB_CORRUPT);
         tsk_error_set_errstr(
@@ -307,12 +292,9 @@ plain_txt_open(TSK_HDB_INFO * hdb_info, TSK_IDX_INFO * idx_info, uint8_t htype)
 
     /* allocate a buffer for a row */
     if ((idx_info->idx_struct.idx_plain_txt->idx_lbuf = tsk_malloc(idx_info->idx_struct.idx_plain_txt->idx_llen + 1)) == NULL) {
-        tsk_release_lock(&idx_info->lock);
         return 1;
     }
 
-    tsk_release_lock(&idx_info->lock);
-
     return 0;
 }
 
@@ -394,14 +376,14 @@ plain_txt_lookup_str(TSK_HDB_INFO * hdb_info, const char *hash,
 
     // We have to lock access to idx_info->idx_struct.idx_plain_txt->idx_lbuf, but since we're in a loop,
     // I'm assuming one lock up front is better than many inside.
-    tsk_take_lock(&hdb_info->idx_info->lock);
+    tsk_take_lock(&hdb_info->lock);
 
     while (1) {
         TSK_OFF_T offset;
 
         /* If top and bottom are the same, it's not there */
         if (up == low) {
-            tsk_release_lock(&hdb_info->idx_info->lock);
+            tsk_release_lock(&hdb_info->lock);
             return 0;
         }
 
@@ -410,7 +392,7 @@ plain_txt_lookup_str(TSK_HDB_INFO * hdb_info, const char *hash,
 
         /* Sanity Check */
         if ((offset % hdb_info->idx_info->idx_struct.idx_plain_txt->idx_llen) != 0) {
-            tsk_release_lock(&hdb_info->idx_info->lock);
+            tsk_release_lock(&hdb_info->lock);
             tsk_error_reset();
             tsk_error_set_errno(TSK_ERR_HDB_CORRUPT);
             tsk_error_set_errstr(
@@ -423,13 +405,13 @@ plain_txt_lookup_str(TSK_HDB_INFO * hdb_info, const char *hash,
 
         /* If we didn't move, then it's not there */
         if (poffset == offset) {
-            tsk_release_lock(&hdb_info->idx_info->lock);
+            tsk_release_lock(&hdb_info->lock);
             return 0;
         }
 
         /* Seek to the offset and read it */
         if (0 != fseeko(hdb_info->idx_info->idx_struct.idx_plain_txt->hIdx, offset, SEEK_SET)) {
-            tsk_release_lock(&hdb_info->idx_info->lock);
+            tsk_release_lock(&hdb_info->lock);
             tsk_error_reset();
             tsk_error_set_errno(TSK_ERR_HDB_READIDX);
             tsk_error_set_errstr(
@@ -442,10 +424,10 @@ plain_txt_lookup_str(TSK_HDB_INFO * hdb_info, const char *hash,
             fgets(hdb_info->idx_info->idx_struct.idx_plain_txt->idx_lbuf, (int) hdb_info->idx_info->idx_struct.idx_plain_txt->idx_llen + 1,
                   hdb_info->idx_info->idx_struct.idx_plain_txt->hIdx)) {
             if (feof(hdb_info->idx_info->idx_struct.idx_plain_txt->hIdx)) {
-                tsk_release_lock(&hdb_info->idx_info->lock);
+                tsk_release_lock(&hdb_info->lock);
                 return 0;
             }
-            tsk_release_lock(&hdb_info->idx_info->lock);
+            tsk_release_lock(&hdb_info->lock);
             tsk_error_reset();
             tsk_error_set_errno(TSK_ERR_HDB_READIDX);
             tsk_error_set_errstr(
@@ -457,7 +439,7 @@ plain_txt_lookup_str(TSK_HDB_INFO * hdb_info, const char *hash,
         /* Sanity Check */
         if ((strlen(hdb_info->idx_info->idx_struct.idx_plain_txt->idx_lbuf) < hdb_info->idx_info->idx_struct.idx_plain_txt->idx_llen) ||
             (hdb_info->idx_info->idx_struct.idx_plain_txt->idx_lbuf[hdb_info->hash_len] != '|')) {
-            tsk_release_lock(&hdb_info->idx_info->lock);
+            tsk_release_lock(&hdb_info->lock);
             tsk_error_reset();
             tsk_error_set_errno(TSK_ERR_HDB_CORRUPT);
             tsk_error_set_errstr(
@@ -489,7 +471,7 @@ plain_txt_lookup_str(TSK_HDB_INFO * hdb_info, const char *hash,
 
             if ((flags & TSK_HDB_FLAG_QUICK)
                 || (hdb_info->db_type == TSK_HDB_DBTYPE_IDXONLY_ID)) {
-                tsk_release_lock(&hdb_info->idx_info->lock);
+                tsk_release_lock(&hdb_info->lock);
                 return 1;
             }
             else {
@@ -507,7 +489,7 @@ plain_txt_lookup_str(TSK_HDB_INFO * hdb_info, const char *hash,
                 /* Print the one that we found first */
                 if (hdb_info->
                     getentry(hdb_info, hash, db_off, flags, action, ptr)) {
-                    tsk_release_lock(&hdb_info->idx_info->lock);
+                    tsk_release_lock(&hdb_info->lock);
                     tsk_error_set_errstr2( "hdb_lookup");
                     return -1;
                 }
@@ -526,7 +508,7 @@ plain_txt_lookup_str(TSK_HDB_INFO * hdb_info, const char *hash,
                         break;
 
                     if (0 != fseeko(hdb_info->idx_info->idx_struct.idx_plain_txt->hIdx, tmpoff, SEEK_SET)) {
-                        tsk_release_lock(&hdb_info->idx_info->lock);
+                        tsk_release_lock(&hdb_info->lock);
                         tsk_error_reset();
                         tsk_error_set_errno(TSK_ERR_HDB_READIDX);
                         tsk_error_set_errstr(
@@ -539,7 +521,7 @@ plain_txt_lookup_str(TSK_HDB_INFO * hdb_info, const char *hash,
                         fgets(hdb_info->idx_info->idx_struct.idx_plain_txt->idx_lbuf,
                               (int) hdb_info->idx_info->idx_struct.idx_plain_txt->idx_llen + 1,
                               hdb_info->idx_info->idx_struct.idx_plain_txt->hIdx)) {
-                        tsk_release_lock(&hdb_info->idx_info->lock);
+                        tsk_release_lock(&hdb_info->lock);
                         tsk_error_reset();
                         tsk_error_set_errno(TSK_ERR_HDB_READIDX);
                         tsk_error_set_errstr(
@@ -549,7 +531,7 @@ plain_txt_lookup_str(TSK_HDB_INFO * hdb_info, const char *hash,
                     }
                     else if (strlen(hdb_info->idx_info->idx_struct.idx_plain_txt->idx_lbuf) <
                              hdb_info->idx_info->idx_struct.idx_plain_txt->idx_llen) {
-                        tsk_release_lock(&hdb_info->idx_info->lock);
+                        tsk_release_lock(&hdb_info->lock);
                         tsk_error_reset();
                         tsk_error_set_errno(TSK_ERR_HDB_CORRUPT);
                         tsk_error_set_errstr(
@@ -577,7 +559,7 @@ plain_txt_lookup_str(TSK_HDB_INFO * hdb_info, const char *hash,
                     if (hdb_info->
                         getentry(hdb_info, hash, db_off, flags, action,
                                  ptr)) {
-                        tsk_release_lock(&hdb_info->idx_info->lock);
+                        tsk_release_lock(&hdb_info->lock);
                         return -1;
                     }
                     tmpoff -= hdb_info->idx_info->idx_struct.idx_plain_txt->idx_llen;
@@ -588,7 +570,7 @@ plain_txt_lookup_str(TSK_HDB_INFO * hdb_info, const char *hash,
                 while (tmpoff < up) {
 
                     if (0 != fseeko(hdb_info->idx_info->idx_struct.idx_plain_txt->hIdx, tmpoff, SEEK_SET)) {
-                        tsk_release_lock(&hdb_info->idx_info->lock);
+                        tsk_release_lock(&hdb_info->lock);
                         tsk_error_reset();
                         tsk_error_set_errno(TSK_ERR_HDB_READIDX);
                         tsk_error_set_errstr(
@@ -603,7 +585,7 @@ plain_txt_lookup_str(TSK_HDB_INFO * hdb_info, const char *hash,
                               hdb_info->idx_info->idx_struct.idx_plain_txt->hIdx)) {
                         if (feof(hdb_info->idx_info->idx_struct.idx_plain_txt->hIdx))
                             break;
-                        tsk_release_lock(&hdb_info->idx_info->lock);
+                        tsk_release_lock(&hdb_info->lock);
                         tsk_error_reset();
                         tsk_error_set_errno(TSK_ERR_HDB_READIDX);
                         tsk_error_set_errstr(
@@ -613,7 +595,7 @@ plain_txt_lookup_str(TSK_HDB_INFO * hdb_info, const char *hash,
                     }
                     else if (strlen(hdb_info->idx_info->idx_struct.idx_plain_txt->idx_lbuf) <
                              hdb_info->idx_info->idx_struct.idx_plain_txt->idx_llen) {
-                        tsk_release_lock(&hdb_info->idx_info->lock);
+                        tsk_release_lock(&hdb_info->lock);
                         tsk_error_reset();
                         tsk_error_set_errno(TSK_ERR_HDB_CORRUPT);
                         tsk_error_set_errstr(
@@ -639,7 +621,7 @@ plain_txt_lookup_str(TSK_HDB_INFO * hdb_info, const char *hash,
                     if (hdb_info->
                         getentry(hdb_info, hash, db_off, flags, action,
                                  ptr)) {
-                        tsk_release_lock(&hdb_info->idx_info->lock);
+                        tsk_release_lock(&hdb_info->lock);
                         return -1;
                     }
 
@@ -650,7 +632,7 @@ plain_txt_lookup_str(TSK_HDB_INFO * hdb_info, const char *hash,
         }
         poffset = offset;
     }
-    tsk_release_lock(&hdb_info->idx_info->lock);
+    tsk_release_lock(&hdb_info->lock);
 
     return wasFound;
 }
diff --git a/tsk/hashdb/sqlite_index.c b/tsk/hashdb/sqlite_index.cpp
similarity index 92%
rename from tsk/hashdb/sqlite_index.c
rename to tsk/hashdb/sqlite_index.cpp
index 20b416c1a385a26d48002abd8b0ffcda28d94a82..c1a831a6bd2ce71c952cff2bb50c980959fd3f19 100644
--- a/tsk/hashdb/sqlite_index.c
+++ b/tsk/hashdb/sqlite_index.cpp
@@ -160,7 +160,8 @@ sqlite_v1_addentry(TSK_HDB_INFO * hdb_info, char *hvalue,
                     TSK_OFF_T offset)
 {
 	const size_t len = (hdb_info->hash_len)/2;
-	unsigned char hash[len+1];
+    uint8_t* hash = (uint8_t*) tsk_malloc(len+1);
+    
 	size_t count;
 
 	if (strlen(hvalue) != hdb_info->hash_len) {
@@ -171,13 +172,19 @@ sqlite_v1_addentry(TSK_HDB_INFO * hdb_info, char *hvalue,
 		return 1;
 	}
 
-	for (count = 0; count < len; count++) {
-		sscanf(hvalue, "%2hhx", &(hash[count]));
+    // We use an intermediate short to be compatible with Microsoft's implementation of the scanf family format
+    short unsigned int binval;
+    for (count = 0; count < len; count++) {
+		int r = sscanf(hvalue, "%2hx", &binval);
+        hash[count] = (uint8_t) binval;
 		hvalue += 2 * sizeof(char);
 	}
 
-	return tsk_hdb_idxaddentry_bin(hdb_info, hash, len, offset);
+    uint8_t ret = tsk_hdb_idxaddentry_bin(hdb_info, hash, len, offset);
 
+    delete [] hash;
+
+	return ret;
 }
 
 /**
@@ -190,10 +197,10 @@ sqlite_v1_addentry(TSK_HDB_INFO * hdb_info, char *hvalue,
  * @return 1 on error and 0 on success
  */
 uint8_t
-sqlite_v1_addentry_bin(TSK_HDB_INFO * hdb_info, unsigned char *hvalue, int hlen,
+sqlite_v1_addentry_bin(TSK_HDB_INFO * hdb_info, uint8_t* hvalue, int hlen,
                     TSK_OFF_T offset)
 {
-    if (attempt(sqlite3_bind_blob(m_stmt, 1, hvalue, hlen, NULL),
+    if (attempt(sqlite3_bind_blob(m_stmt, 1, hvalue, hlen, SQLITE_TRANSIENT),
 		SQLITE_OK,
 		"Error binding binary blob: %s\n",
 		hdb_info->idx_info->idx_struct.idx_sqlite_v1->hIdx_sqlite) ||
@@ -248,7 +255,7 @@ sqlite_v1_finalize(TSK_HDB_INFO * hdb_info)
 uint8_t
 sqlite_v1_open(TSK_HDB_INFO * hdb_info, TSK_IDX_INFO * idx_info, uint8_t htype)
 {
-    sqlite3 * sqlite;
+    sqlite3 * sqlite = NULL;
 
     if ((idx_info->idx_struct.idx_sqlite_v1 =
                 (TSK_IDX_SQLITE_V1 *) tsk_malloc
@@ -278,6 +285,7 @@ sqlite_v1_open(TSK_HDB_INFO * hdb_info, TSK_IDX_INFO * idx_info, uint8_t htype)
             sqlite3_close(sqlite);
             return 1;
         }
+
     }
 #else
     {
@@ -320,7 +328,7 @@ sqlite_v1_lookup_str(TSK_HDB_INFO * hdb_info, const char *hash,
                    void *ptr)
 {
 	const size_t len = strlen(hash)/2;
-	uint8_t * hashBlob = (uint8_t *) malloc(len+1);
+	uint8_t * hashBlob = (uint8_t *) tsk_malloc(len+1);
 	const char * pos = hash;
 	size_t count = 0;
 
@@ -358,9 +366,11 @@ sqlite_v1_lookup_raw(TSK_HDB_INFO * hdb_info, uint8_t * hash, uint8_t len,
 	TSK_OFF_T offset;
     char * selectStmt;
 
+    tsk_take_lock(&hdb_info->lock);
 
 	/* Sanity check */
 	if ((hdb_info->hash_len)/2 != len) {
+        tsk_release_lock(&hdb_info->lock);
 		tsk_error_reset();
 		tsk_error_set_errno(TSK_ERR_HDB_ARG);
 		tsk_error_set_errstr("hdb_lookup: Hash passed is different size than expected: %d vs %d",
@@ -374,6 +384,7 @@ sqlite_v1_lookup_raw(TSK_HDB_INFO * hdb_info, uint8_t * hash, uint8_t len,
         } else if (hdb_info->hash_type == TSK_HDB_HTYPE_SHA1_ID) {
             selectStmt = "SELECT sha1,database_offset from hashset_hashes where sha1=? limit 1";
         } else {
+            tsk_release_lock(&hdb_info->lock);
             tsk_error_reset();
             tsk_error_set_errno(TSK_ERR_HDB_ARG);
             tsk_error_set_errstr("Unknown hash type: %d\n", hdb_info->hash_type);
@@ -386,6 +397,7 @@ sqlite_v1_lookup_raw(TSK_HDB_INFO * hdb_info, uint8_t * hash, uint8_t len,
 		SQLITE_OK,
 		"Error binding binary blob: %s\n",
 		hdb_info->idx_info->idx_struct.idx_sqlite_v1->hIdx_sqlite)) {
+            tsk_release_lock(&hdb_info->lock);
 			return -1;
 	}
 
@@ -393,6 +405,7 @@ sqlite_v1_lookup_raw(TSK_HDB_INFO * hdb_info, uint8_t * hash, uint8_t len,
 		if ((flags & TSK_HDB_FLAG_QUICK)
 			|| (hdb_info->db_type == TSK_HDB_DBTYPE_IDXONLY_ID)) {
 				sqlite3_reset(m_stmt);
+                tsk_release_lock(&hdb_info->lock);
 				return 1;
 		} else {
 			for (i = 0; i < len; i++) {
@@ -405,6 +418,7 @@ sqlite_v1_lookup_raw(TSK_HDB_INFO * hdb_info, uint8_t * hash, uint8_t len,
 			sqlite3_reset(m_stmt);
 
 			if (hdb_info->getentry(hdb_info, hashbuf, offset, flags, action, ptr)) {
+                tsk_release_lock(&hdb_info->lock);
 				tsk_error_set_errstr2("hdb_lookup");
 				return -1;
 			}
@@ -413,6 +427,8 @@ sqlite_v1_lookup_raw(TSK_HDB_INFO * hdb_info, uint8_t * hash, uint8_t len,
 	}
 
 	sqlite3_reset(m_stmt);
+    
+    tsk_release_lock(&hdb_info->lock);
 
 	return 0;
 
diff --git a/tsk/hashdb/tm_lookup.c b/tsk/hashdb/tm_lookup.cpp
similarity index 83%
rename from tsk/hashdb/tm_lookup.c
rename to tsk/hashdb/tm_lookup.cpp
index c24fa83717b8c5d08de9d110ad5b327928c286dc..769447c3e95e95fd9f7394e0eb96e51675bdefe3 100644
--- a/tsk/hashdb/tm_lookup.c
+++ b/tsk/hashdb/tm_lookup.cpp
@@ -10,22 +10,78 @@
 
 #include "tsk_hashdb_i.h"
 
+
 /**
  * \file tm_lookup.c
  * Contains the generic hash database creation and 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 the index structure for the given hash db
+ * 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)
+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;
+    FILE * idx = NULL;
 
     if (hdb_info->idx_info != NULL) {
         return hdb_info->idx_info;
@@ -50,65 +106,61 @@ tsk_idx_open(TSK_HDB_INFO * hdb_info, uint8_t htype)
     /* Get hash type specific information */
     switch (htype) {
         case TSK_HDB_HTYPE_MD5_ID:
-            hdb_info->hash_type = htype;
+            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-%") PRIcTSK _TSK_T(".idx"),
-                    hdb_info->db_fname, TSK_HDB_HTYPE_MD5_STR);
+                    _TSK_T("%s.kdb"),
+                    hdb_info->db_fname);
             break;
         case TSK_HDB_HTYPE_SHA1_ID:
-            hdb_info->hash_type = htype;
+            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-%") PRIcTSK _TSK_T(".idx"),
-                    hdb_info->db_fname, TSK_HDB_HTYPE_SHA1_STR);
+                    _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 */
-#ifdef TSK_WIN32
-    {
-        HANDLE hWin;
-        DWORD szLow, szHi;
 
-        if (-1 == GetFileAttributes(hdb_info->idx_fname)) {
-            tsk_release_lock(&hdb_info->lock);
-            tsk_error_reset();
-            tsk_error_set_errno(TSK_ERR_HDB_MISSING);
-            tsk_error_set_errstr(
-                    "hdb_setupindex: Error finding index file: %"PRIttocTSK,
-                    hdb_info->idx_fname);
-            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 ((hWin = CreateFile(hdb_info->idx_fname, GENERIC_READ,
-                        FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0)) ==
-                INVALID_HANDLE_VALUE) {
-            tsk_release_lock(&hdb_info->lock);
-            tsk_error_reset();
-            tsk_error_set_errno(TSK_ERR_HDB_OPEN);
-            tsk_error_set_errstr(
-                    "hdb_setupindex: Error opening index file: %"PRIttocTSK,
-                    hdb_info->idx_fname);
-            free(idx_info);
-            return 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;
+            }
         }
-        idx =
-            _fdopen(_open_osfhandle((intptr_t) hWin, _O_RDONLY), "r");
     }
-#else
-    {
-        idx = fopen(idx_info->idx_fname, "r");
-    }
-#endif
 
-    if (NULL != idx)
-    {
-        if(NULL == fread(header, header_size, 1, idx)) {
+    // 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,
@@ -122,15 +174,14 @@ tsk_idx_open(TSK_HDB_INFO * hdb_info, uint8_t htype)
             tsk_error_reset();
             tsk_error_set_errno(TSK_ERR_HDB_MISSING);
             tsk_error_set_errstr(
-                    "hdb_setupindex: Unrecognized header format: %s\n",
+                    "tsk_idx_open: Unrecognized header format: %s\n",
                     idx_info->idx_fname);
             free(idx_info);
             return NULL;
         }
-    } else {
-        idx_info->index_type = TSK_HDB_ITYPE_SQLITE_V1;
     }
 
+    // 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;
@@ -157,6 +208,7 @@ tsk_idx_open(TSK_HDB_INFO * hdb_info, uint8_t htype)
             return NULL;
     }
 
+    // Open
     if (idx_info->open(hdb_info, idx_info, htype) == 0) {
         return idx_info;
     }
@@ -175,19 +227,25 @@ tsk_idx_open(TSK_HDB_INFO * hdb_info, uint8_t htype)
  * @return 0 if already set up or if setup successful, 1 otherwise
  */
 uint8_t
-hdb_setupindex(TSK_HDB_INFO * hdb_info, uint8_t htype)
+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);
+    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;
 }
 
@@ -206,7 +264,7 @@ 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 */
@@ -283,7 +341,7 @@ tsk_hdb_idxinitialize(TSK_HDB_INFO * hdb_info, TSK_TCHAR * htype)
     }
 
     /* Setup the internal hash information */
-    if (hdb_setupindex(hdb_info, hdb_info->hash_type)) {
+    if (hdb_setupindex(hdb_info, hdb_info->hash_type, create)) {
         return 1;
     }
 
@@ -373,7 +431,7 @@ tsk_hdb_lookup_str(TSK_HDB_INFO * hdb_info, const char *hash,
         return -1;
     }
 
-    if (hdb_setupindex(hdb_info, htype)) {
+    if (hdb_setupindex(hdb_info, htype, false)) {
         return -1;
     }
 
@@ -417,7 +475,7 @@ tsk_hdb_lookup_raw(TSK_HDB_INFO * hdb_info, uint8_t * hash, uint8_t len,
         return -1;
     }
 
-    if (hdb_setupindex(hdb_info, htype)) {
+    if (hdb_setupindex(hdb_info, htype, false)) {
         return -1;
     }
 
@@ -438,10 +496,11 @@ 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 (tsk_idx_open(hdb_info, htype))
+    if (hdb_setupindex(hdb_info, htype, false)) {
         return 0;
-    else
+    } else {
         return 1;
+    }
 }
 
 
@@ -564,12 +623,15 @@ tsk_hdb_open(TSK_TCHAR * db_file, TSK_HDB_OPEN_ENUM flags)
     TSTRNCPY(hdb_info->db_fname, db_file, flen);
 
     
-    hdb_info->hash_type = 0;
+    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 = dbtype;
+    hdb_info->db_type = static_cast<TSK_HDB_DBTYPE_ENUM>(dbtype);
     switch (dbtype) {
         case TSK_HDB_DBTYPE_NSRL_ID:
             nsrl_name(hdb_info);
@@ -643,7 +705,7 @@ tsk_hdb_close(TSK_HDB_INFO * hdb_info)
         tsk_idx_close(hdb_info->idx_info);
     }
 
-    tsk_deinit_lock(&hdb_info->idx_info->lock);
+    tsk_deinit_lock(&hdb_info->lock);
 
     free(hdb_info);
 }
diff --git a/tsk/hashdb/tsk_hashdb.h b/tsk/hashdb/tsk_hashdb.h
index 482790a03622e0d32d6f186491a89ce19158877d..06a82b04a6025a05eeb25caafc772a1921ede2ef 100644
--- a/tsk/hashdb/tsk_hashdb.h
+++ b/tsk/hashdb/tsk_hashdb.h
@@ -146,9 +146,6 @@ extern "C" {
         TSK_HDB_ITYPE_ENUM index_type;   ///< Type of index
         TSK_TCHAR *idx_fname;   ///< Name of index file
         
-        /* lock protects idx_lbuf and lazy loading of hIdx */
-        tsk_lock_t lock;        ///< Lock for lazy loading and idx_lbuf
-
         union {
             TSK_IDX_SQLITE_V1 * idx_sqlite_v1;
             TSK_IDX_PLAIN_TXT * idx_plain_txt;
@@ -185,6 +182,9 @@ extern "C" {
         TSK_HDB_DBTYPE_ENUM db_type;    ///< Type of database
         TSK_IDX_INFO * idx_info;  ///< The index for the hdb info
 
+        /* lock protects idx_lbuf and lazy loading of idx_info */
+        tsk_lock_t lock;        ///< Lock for lazy loading and idx_lbuf
+
         uint8_t(*getentry) (TSK_HDB_INFO *, const char *, TSK_OFF_T, TSK_HDB_FLAG_ENUM, TSK_HDB_LOOKUP_FN, void *);    ///< \internal Database-specific function to find entry at a given offset
         uint8_t(*makeindex) (TSK_HDB_INFO *, TSK_TCHAR *);     ///< \internal Database-specific function to make index
     };
diff --git a/win32/libtsk/libtsk.vcxproj b/win32/libtsk/libtsk.vcxproj
index 1ba7fcc9c512a463c6338f9f7177a687583244dd..a6c4b9879fee3d39675868168aeb92cb2270ccfb 100755
--- a/win32/libtsk/libtsk.vcxproj
+++ b/win32/libtsk/libtsk.vcxproj
@@ -203,7 +203,7 @@ copy "$(LIBEWF_HOME)\msvscpp\x64\release\zlib.dll" "$(OutDir)"
   </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="..\..\tsk\hashdb\ascii_index.c" />
-    <ClCompile Include="..\..\tsk\hashdb\sqlite_index.c" />
+    <ClCompile Include="..\..\tsk\hashdb\sqlite_index.cpp" />
     <ClCompile Include="..\..\tsk\vs\bsd.c" />
     <ClCompile Include="..\..\tsk\vs\dos.c" />
     <ClCompile Include="..\..\tsk\vs\gpt.c" />
@@ -280,7 +280,7 @@ copy "$(LIBEWF_HOME)\msvscpp\x64\release\zlib.dll" "$(OutDir)"
     <ClCompile Include="..\..\tsk\hashdb\idxonly_index.c" />
     <ClCompile Include="..\..\tsk\hashdb\md5sum_index.c" />
     <ClCompile Include="..\..\tsk\hashdb\nsrl_index.c" />
-    <ClCompile Include="..\..\tsk\hashdb\tm_lookup.c" />
+    <ClCompile Include="..\..\tsk\hashdb\tm_lookup.cpp" />
     <ClCompile Include="..\..\tsk\img\aff.c" />
     <ClCompile Include="..\..\tsk\img\ewf.c" />
     <ClCompile Include="..\..\tsk\img\img_io.c" />
diff --git a/win32/libtsk/libtsk.vcxproj.filters b/win32/libtsk/libtsk.vcxproj.filters
index ebddf1787d19de45e1734733794a1e29cb5209d9..571974dad5bd53c64c3da905009b502c5fcd6104 100755
--- a/win32/libtsk/libtsk.vcxproj.filters
+++ b/win32/libtsk/libtsk.vcxproj.filters
@@ -237,9 +237,6 @@
     <ClCompile Include="..\..\tsk\hashdb\nsrl_index.c">
       <Filter>hash</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\tsk\hashdb\tm_lookup.c">
-      <Filter>hash</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\tsk\img\aff.c">
       <Filter>img</Filter>
     </ClCompile>
@@ -274,7 +271,10 @@
     <ClCompile Include="..\..\tsk\hashdb\ascii_index.c">
       <Filter>hash</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\tsk\hashdb\sqlite_index.c">
+    <ClCompile Include="..\..\tsk\hashdb\tm_lookup.cpp">
+      <Filter>hash</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\tsk\hashdb\sqlite_index.cpp">
       <Filter>hash</Filter>
     </ClCompile>
   </ItemGroup>