Index: trunk/include/regfi.h
===================================================================
--- trunk/include/regfi.h	(revision 177)
+++ trunk/include/regfi.h	(revision 178)
@@ -93,11 +93,4 @@
 
 #define REGFI_NUM_ENCODINGS    3
-
-/* Windows is lame */
-#ifdef O_BINARY
-#define REGFI_OPEN_FLAGS O_RDONLY|O_BINARY
-#else
-#define REGFI_OPEN_FLAGS O_RDONLY
-#endif
 
 /* Registry data types */
@@ -162,10 +155,9 @@
  /* Minimum time is Jan 1, 1990 00:00:00 */
 #define REGFI_MTIME_MIN_HIGH       0x01B41E6D
-#define REGFI_MTIME_MIN_LOW        0x26F98000
+
  /* Maximum time is Jan 1, 2290 00:00:00
   * (We hope no one is using Windows by then...) 
   */
 #define REGFI_MTIME_MAX_HIGH       0x03047543
-#define REGFI_MTIME_MAX_LOW        0xC80A4000
 
 
@@ -649,4 +641,14 @@
 
 
+typedef struct _regfi_raw_file
+{
+  off_t    (* seek)(); /* (REGFI_RAW_FILE* self, off_t offset, int whence) */
+  ssize_t  (* read)(); /* (REGFI_RAW_FILE* self, void* buf, size_t count) */
+
+  uint64_t cur_off;
+  uint64_t size;
+  void*    state;
+} REGFI_RAW_FILE;
+
 
 /** Registry hive file data structure
@@ -665,10 +667,10 @@
  * @ingroup regfiBase
  */ 
-typedef struct 
+typedef struct _regfi_file
 {
   /* Run-time information */
   /************************/
-  /* file descriptor */
-  int fd;
+  /* Functions for accessing the file */
+  REGFI_RAW_FILE* cb;
 
   /* For sanity checking (not part of the registry header) */
@@ -798,17 +800,4 @@
 /******************************************************************************/
 
-/** Attempts to open a registry hive and allocate related data structures.
- * 
- * @param filename A string containing the relative or absolute path of the
- *               registry hive to be opened.
- *
- * @return A reference to a newly allocated REGFI_FILE structure, 
- *         if successful;  NULL on error.
- *
- * @ingroup regfiBase
- */
-REGFI_FILE*           regfi_open(const char* filename);
-
-
 /** Parses file headers of an already open registry hive file and 
  *  allocates related structures for further parsing.
@@ -824,14 +813,17 @@
 
 
-/** Closes and frees an open registry hive.
- *
- * @param file The registry structure to close.
- *
- * @return 0 on success, -1 on failure with errno set.  
- *         errno codes are similar to those of close(2).
+/** Parses file headers returned by supplied callback functions.
+ *
+ * This interface is useful if you have a registry hive in memory
+ * or have some other reason to emulate a real file.
+ *
+ * @param file_cb A structure defining the callback functions needed to access the file. 
+ *
+ * @return A reference to a newly allocated REGFI_FILE structure, if successful;
+ *         NULL on error.
  *
  * @ingroup regfiBase
  */
-int                   regfi_close(REGFI_FILE* file);
+REGFI_FILE*           regfi_alloc_cb(REGFI_RAW_FILE* file_cb);
 
 
@@ -1298,5 +1290,5 @@
 /******************************************************************************/
 
-REGFI_FILE*           regfi_parse_regf(int fd, bool strict);
+REGFI_FILE*           regfi_parse_regf(REGFI_RAW_FILE* file_cb, bool strict);
 REGFI_HBIN*           regfi_parse_hbin(REGFI_FILE* file, uint32_t offset, 
 				       bool strict);
@@ -1367,5 +1359,5 @@
  * @ingroup regfiParseLayer
  */
-bool                  regfi_parse_cell(int fd, uint32_t offset, 
+bool                  regfi_parse_cell(REGFI_RAW_FILE* file_cb, uint32_t offset,
 				       uint8_t* hdr, uint32_t hdr_len,
 				       uint32_t* cell_length, bool* unalloc);
@@ -1410,5 +1402,13 @@
 				    REGFI_ENCODING output_encoding);
 void                  regfi_subkeylist_free(REGFI_SUBKEY_LIST* list);
-uint32_t              regfi_read(int fd, uint8_t* buf, uint32_t* length);
+
+off_t                 regfi_raw_seek(REGFI_RAW_FILE* self, 
+				     off_t offset, int whence);
+ssize_t               regfi_raw_read(REGFI_RAW_FILE* self, 
+				     void* buf, size_t count);
+off_t                 regfi_seek(REGFI_RAW_FILE* file_cb, 
+				 off_t offset, int whence);
+uint32_t              regfi_read(REGFI_RAW_FILE* file_cb, 
+				 uint8_t* buf, uint32_t* length);
 
 const char*           regfi_type_val2str(unsigned int val);
Index: trunk/lib/regfi.c
===================================================================
--- trunk/lib/regfi.c	(revision 177)
+++ trunk/lib/regfi.c	(revision 178)
@@ -422,8 +422,29 @@
 
 
+off_t regfi_raw_seek(REGFI_RAW_FILE* self, off_t offset, int whence)
+{
+  return lseek(*(int*)self->state, offset, whence);
+}
+
+ssize_t regfi_raw_read(REGFI_RAW_FILE* self, void* buf, size_t count)
+{
+  return read(*(int*)self->state, buf, count);
+}
+
+
+/*****************************************************************************
+ * Convenience function to wrap up the ugly callback stuff
+ *****************************************************************************/
+off_t regfi_seek(REGFI_RAW_FILE* file_cb, off_t offset, int whence)
+{
+  return file_cb->seek(file_cb, offset, whence);
+}
+
+
 /*****************************************************************************
  * This function is just like read(2), except that it continues to
  * re-try reading from the file descriptor if EINTR or EAGAIN is received.  
- * regfi_read will attempt to read length bytes from fd and write them to buf.
+ * regfi_read will attempt to read length bytes from the file and write them to
+ * buf.
  *
  * On success, 0 is returned.  Upon failure, an errno code is returned.
@@ -433,5 +454,5 @@
  * returned as 0, then EOF was encountered immediately
  *****************************************************************************/
-uint32_t regfi_read(int fd, uint8_t* buf, uint32_t* length)
+uint32_t regfi_read(REGFI_RAW_FILE* file_cb, uint8_t* buf, uint32_t* length)
 {
   uint32_t rsize = 0;
@@ -440,5 +461,5 @@
   do
   {
-    rret = read(fd, buf + rsize, *length - rsize);
+    rret = file_cb->read(file_cb, buf + rsize, *length - rsize);
     if(rret > 0)
       rsize += rret;
@@ -457,6 +478,6 @@
  *
  *****************************************************************************/
-bool regfi_parse_cell(int fd, uint32_t offset, uint8_t* hdr, uint32_t hdr_len,
-		      uint32_t* cell_length, bool* unalloc)
+bool regfi_parse_cell(REGFI_RAW_FILE* file_cb, uint32_t offset, uint8_t* hdr, 
+		      uint32_t hdr_len, uint32_t* cell_length, bool* unalloc)
 {
   uint32_t length;
@@ -464,9 +485,9 @@
   uint8_t tmp[4];
 
-  if(lseek(fd, offset, SEEK_SET) == -1)
+  if(regfi_seek(file_cb, offset, SEEK_SET) == -1)
     return false;
 
   length = 4;
-  if((regfi_read(fd, tmp, &length) != 0) || length != 4)
+  if((regfi_read(file_cb, tmp, &length) != 0) || length != 4)
     return false;
   raw_length = IVALS(tmp, 0);
@@ -489,5 +510,5 @@
   {
     length = hdr_len;
-    if((regfi_read(fd, hdr, &length) != 0) || length != hdr_len)
+    if((regfi_read(file_cb, hdr, &length) != 0) || length != hdr_len)
       return false;
   }
@@ -634,5 +655,5 @@
   bool recursive_type;
 
-  if(!regfi_parse_cell(file->fd, offset, buf, REGFI_SUBKEY_LIST_MIN_LEN, 
+  if(!regfi_parse_cell(file->cb, offset, buf, REGFI_SUBKEY_LIST_MIN_LEN,
 		       &cell_length, &unalloc))
   {
@@ -704,5 +725,5 @@
 
   read_len = length;
-  if(regfi_read(file->fd, elements, &read_len) != 0 || read_len != length)
+  if(regfi_read(file->cb, elements, &read_len) != 0 || read_len!=length)
     goto fail;
 
@@ -802,5 +823,5 @@
   bool unalloc = false;
 
-  if(!regfi_parse_cell(file->fd, offset, sk_header, REGFI_SK_MIN_LENGTH,
+  if(!regfi_parse_cell(file->cb, offset, sk_header, REGFI_SK_MIN_LENGTH,
 		       &cell_length, &unalloc))
   {
@@ -868,5 +889,5 @@
 
   length = ret_val->desc_size;
-  if(regfi_read(file->fd, sec_desc_buf, &length) != 0 
+  if(regfi_read(file->cb, sec_desc_buf, &length) != 0 
      || length != ret_val->desc_size)
   {
@@ -904,5 +925,5 @@
   bool unalloc;
 
-  if(!regfi_parse_cell(file->fd, offset, NULL, 0, &cell_length, &unalloc))
+  if(!regfi_parse_cell(file->cb, offset, NULL, 0, &cell_length, &unalloc))
   {
     regfi_add_message(file, REGFI_MSG_ERROR, "Failed to read cell header"
@@ -943,5 +964,5 @@
 
   length = read_len;
-  if((regfi_read(file->fd, (uint8_t*)ret_val->elements, &length) != 0) 
+  if((regfi_read(file->cb, (uint8_t*)ret_val->elements, &length) != 0) 
      || length != read_len)
   {
@@ -1265,5 +1286,5 @@
   while(cur_offset < hbin_end)
   {
-    if(!regfi_parse_cell(file->fd, cur_offset, NULL, 0, &cell_length, &unalloc))
+    if(!regfi_parse_cell(file->cb, cur_offset, NULL, 0, &cell_length, &unalloc))
     {
       regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell at offset"
@@ -1289,26 +1310,4 @@
 
 
-/******************************************************************************
- ******************************************************************************/
-REGFI_FILE* regfi_open(const char* filename)
-{
-  REGFI_FILE* ret_val;
-  int fd;
-
-  /* open an existing file */
-  if ((fd = open(filename, REGFI_OPEN_FLAGS)) == -1)
-  {
-    /* fprintf(stderr, "regfi_open: failure to open %s (%s)\n", filename, strerror(errno));*/
-    return NULL;
-  }
-
-  ret_val = regfi_alloc(fd);
-
-  if(ret_val == NULL)
-    close(fd);
-
-  return ret_val;
-}
-
 
 /******************************************************************************
@@ -1316,31 +1315,63 @@
 REGFI_FILE* regfi_alloc(int fd)
 {
-  struct stat sbuf;
+  REGFI_FILE* ret_val;
+  REGFI_RAW_FILE* file_cb = talloc(NULL, REGFI_RAW_FILE);
+  if(file_cb == NULL) 
+    return NULL;
+
+  file_cb->state = (void*)talloc(file_cb, int);
+  if(file_cb->state == NULL)
+    goto fail;
+  *(int*)file_cb->state = fd;
+  
+  file_cb->cur_off = 0;
+  file_cb->size = 0;
+  file_cb->read = &regfi_raw_read;
+  file_cb->seek = &regfi_raw_seek;
+  
+  ret_val = regfi_alloc_cb(file_cb);
+  if(ret_val == NULL)
+    goto fail;
+
+  /* In this case, we want file_cb to be freed when ret_val is */
+  talloc_steal(ret_val, file_cb);
+  return ret_val;
+
+ fail:
+    talloc_free(file_cb);
+    return NULL;
+}
+
+
+
+REGFI_FILE* regfi_alloc_cb(REGFI_RAW_FILE* file_cb)
+{
   REGFI_FILE* rb;
   REGFI_HBIN* hbin = NULL;
-  uint32_t hbin_off, file_length, cache_secret;
+  uint32_t hbin_off, cache_secret;
+  int32_t file_length;
   bool rla;
 
-  /* Determine file length.  Must be at least big enough 
-   * for the header and one hbin. 
+  /* Determine file length.  Must be at least big enough for the header
+   * and one hbin.
    */
-  if (fstat(fd, &sbuf) == -1)
-    return NULL;
-  file_length = sbuf.st_size;
+  file_length = file_cb->seek(file_cb, 0, SEEK_END);
   if(file_length < REGFI_REGF_SIZE+REGFI_HBIN_ALLOC)
     return NULL;
+  file_cb->seek(file_cb, 0, SEEK_SET);
 
   /* Read file header */
-  if ((rb = regfi_parse_regf(fd, true)) == NULL) 
-  {
-    /* fprintf(stderr, "regfi_alloc: Failed to read initial REGF block\n"); */
+  if ((rb = regfi_parse_regf(file_cb, true)) == NULL) 
+  {
+    /* fprintf(stderr, "regfi_alloc_cb: Failed to read initial REGF block\n");*/
     return NULL;
   }
   rb->file_length = file_length;  
+  rb->cb = file_cb;
 
   rb->hbins = range_list_new();
   if(rb->hbins == NULL)
   {
-    /* fprintf(stderr, "regfi_alloc: Failed to create HBIN list.\n"); */
+    /* fprintf(stderr, "regfi_alloc_cb: Failed to create HBIN list.\n"); */
     talloc_free(rb);
     return NULL;
@@ -1374,23 +1405,4 @@
   /* success */
   return rb;
-}
-
-
-/******************************************************************************
- ******************************************************************************/
-int regfi_close(REGFI_FILE* file)
-{
-  int fd;
-
-  /* nothing to do if there is no open file */
-  if ((file == NULL) || (file->fd == -1))
-    return 0;
-
-  fd = file->fd;
-  file->fd = -1;
-
-  regfi_free(file);
-
-  return close(fd);
 }
 
@@ -2183,5 +2195,5 @@
  * XXX: Add way to return more detailed error information.
  *******************************************************************/
-REGFI_FILE* regfi_parse_regf(int fd, bool strict)
+REGFI_FILE* regfi_parse_regf(REGFI_RAW_FILE* file_cb, bool strict)
 {
   uint8_t file_header[REGFI_REGF_SIZE];
@@ -2193,11 +2205,11 @@
     return NULL;
 
-  ret_val->fd = fd;
   ret_val->sk_cache = NULL;
   ret_val->last_message = NULL;
   ret_val->hbins = NULL;
-  
+
   length = REGFI_REGF_SIZE;
-  if((regfi_read(fd, file_header, &length)) != 0 || length != REGFI_REGF_SIZE)
+  if((regfi_read(file_cb, file_header, &length)) != 0 
+     || length != REGFI_REGF_SIZE)
     goto fail;
   
@@ -2217,4 +2229,5 @@
 		      ret_val->magic[2], ret_val->magic[3]);
   }
+
   ret_val->sequence1 = IVAL(file_header, 0x4);
   ret_val->sequence2 = IVAL(file_header, 0x8);
@@ -2270,5 +2283,5 @@
     return NULL;
 
-  if(lseek(file->fd, offset, SEEK_SET) == -1)
+  if(regfi_seek(file->cb, offset, SEEK_SET) == -1)
   {
     regfi_add_message(file, REGFI_MSG_ERROR, "Seek failed"
@@ -2278,9 +2291,9 @@
 
   length = REGFI_HBIN_HEADER_SIZE;
-  if((regfi_read(file->fd, hbin_header, &length) != 0) 
+  if((regfi_read(file->cb, hbin_header, &length) != 0) 
      || length != REGFI_HBIN_HEADER_SIZE)
     return NULL;
 
-  if(lseek(file->fd, offset, SEEK_SET) == -1)
+  if(regfi_seek(file->cb, offset, SEEK_SET) == -1)
   {
     regfi_add_message(file, REGFI_MSG_ERROR, "Seek failed"
@@ -2341,5 +2354,5 @@
   bool unalloc = false;
 
-  if(!regfi_parse_cell(file->fd, offset, nk_header, REGFI_NK_MIN_LENGTH,
+  if(!regfi_parse_cell(file->cb, offset, nk_header, REGFI_NK_MIN_LENGTH,
 		       &cell_length, &unalloc))
   {
@@ -2399,9 +2412,10 @@
    */
   if(unalloc
-     && ((ret_val->mtime.high < REGFI_MTIME_MIN_HIGH 
-	  && ret_val->mtime.low < REGFI_MTIME_MIN_LOW)
-	 || (ret_val->mtime.high > REGFI_MTIME_MAX_HIGH 
-	     && ret_val->mtime.low > REGFI_MTIME_MAX_LOW)))
-    return NULL;
+     && (ret_val->mtime.high < REGFI_MTIME_MIN_HIGH 
+	 || ret_val->mtime.high > REGFI_MTIME_MAX_HIGH))
+  {
+    talloc_free(ret_val);
+    return NULL;
+  }
 
   ret_val->unknown1 = IVAL(nk_header, 0xC);
@@ -2459,5 +2473,5 @@
   /* Don't need to seek, should be at the right offset */
   length = ret_val->name_length;
-  if((regfi_read(file->fd, (uint8_t*)ret_val->keyname_raw, &length) != 0)
+  if((regfi_read(file->cb, (uint8_t*)ret_val->keyname_raw, &length) != 0)
      || length != ret_val->name_length)
   {
@@ -2483,5 +2497,5 @@
      && (offset & 0x00000007) == 0)
   {
-    if(!regfi_parse_cell(file->fd, offset, NULL, 0, &cell_length, &unalloc))
+    if(!regfi_parse_cell(file->cb, offset, NULL, 0, &cell_length, &unalloc))
     {
       regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell header"
@@ -2521,5 +2535,5 @@
     {
       length = *name_length;
-      if((regfi_read(file->fd, ret_val, &length) != 0)
+      if((regfi_read(file->cb, ret_val, &length) != 0)
 	 || length != *name_length)
       {
@@ -2546,5 +2560,5 @@
   bool unalloc = false;
 
-  if(!regfi_parse_cell(file->fd, offset, vk_header, REGFI_VK_MIN_LENGTH,
+  if(!regfi_parse_cell(file->cb, offset, vk_header, REGFI_VK_MIN_LENGTH,
 		       &cell_length, &unalloc))
   {
@@ -2629,5 +2643,5 @@
 
     length = ret_val->name_length;
-    if((regfi_read(file->fd, (uint8_t*)ret_val->valuename_raw, &length) != 0)
+    if((regfi_read(file->cb, (uint8_t*)ret_val->valuename_raw, &length) != 0)
        || length != ret_val->name_length)
     {
@@ -2697,5 +2711,5 @@
     }
     
-    if(!regfi_parse_cell(file->fd, offset, NULL, 0,
+    if(!regfi_parse_cell(file->cb, offset, NULL, 0,
 			 &cell_length, &unalloc))
     {
@@ -2770,5 +2784,5 @@
   ret_val.len = 0;
   
-  if(lseek(file->fd, offset+4, SEEK_SET) == -1)
+  if(regfi_seek(file->cb, offset+4, SEEK_SET) == -1)
   {
     regfi_add_message(file, REGFI_MSG_WARN, "Could not seek while "
@@ -2782,5 +2796,5 @@
   
   read_length = length;
-  if((regfi_read(file->fd, ret_val.buf, &read_length) != 0)
+  if((regfi_read(file->cb, ret_val.buf, &read_length) != 0)
      || read_length != length)
   {
@@ -2848,5 +2862,5 @@
   }
 
-  if(!regfi_parse_cell(file->fd, offset, ret_val.buf, REGFI_BIG_DATA_MIN_LENGTH,
+  if(!regfi_parse_cell(file->cb, offset, ret_val.buf, REGFI_BIG_DATA_MIN_LENGTH,
 		       &cell_length, &unalloc))
   {
@@ -2902,5 +2916,5 @@
     goto fail;
 
-  if(!regfi_parse_cell(file->fd, offset, (uint8_t*)ret_val,
+  if(!regfi_parse_cell(file->cb, offset, (uint8_t*)ret_val,
 		       num_chunks*sizeof(uint32_t),
 		       &indirect_length, &unalloc))
@@ -2957,5 +2971,5 @@
   {
     chunk_offset = offsets[i]+REGFI_REGF_SIZE;
-    if(!regfi_parse_cell(file->fd, chunk_offset, NULL, 0,
+    if(!regfi_parse_cell(file->cb, chunk_offset, NULL, 0,
 			 &cell_length, &unalloc))
     {
@@ -3065,5 +3079,5 @@
     }
 
-    if(lseek(file->fd, cell_info->offset+sizeof(uint32_t), SEEK_SET) == -1)
+    if(regfi_seek(file->cb, cell_info->offset+sizeof(uint32_t), SEEK_SET) == -1)
     {
       regfi_add_message(file, REGFI_MSG_WARN, "Could not seek to chunk while "
@@ -3074,5 +3088,5 @@
 
     tmp_len = read_length;
-    if(regfi_read(file->fd, ret_val.buf+(data_length-data_left), 
+    if(regfi_read(file->cb, ret_val.buf+(data_length-data_left), 
 		  &read_length) != 0 || (read_length != tmp_len))
     {
@@ -3130,5 +3144,5 @@
     while(curr_off < hbin->block_size)
     {
-      if(!regfi_parse_cell(file->fd, hbin->file_off+curr_off, NULL, 0,
+      if(!regfi_parse_cell(file->cb, hbin->file_off+curr_off, NULL, 0,
 			   &cell_len, &is_unalloc))
 	break;
Index: trunk/src/common.c
===================================================================
--- trunk/src/common.c	(revision 177)
+++ trunk/src/common.c	(revision 178)
@@ -38,4 +38,12 @@
 
 
+/* Windows is lame */
+#ifdef O_BINARY
+#define REGLOOKUP_OPEN_FLAGS O_RDONLY|O_BINARY
+#else
+#define REGLOOKUP_OPEN_FLAGS O_RDONLY
+#endif
+
+
 void bailOut(int code, char* message)
 {
@@ -337,2 +345,32 @@
   return ret_val;
 }
+
+
+int openHive(const char* filename)
+{
+  int ret_val;
+
+  /* open an existing file */
+  if ((ret_val = open(filename, REGLOOKUP_OPEN_FLAGS)) == -1)
+  {
+    fprintf(stderr, "ERROR: Failed to open hive.  Error returned: %s\n", 
+	    strerror(errno));
+    return -1;
+  }
+
+  return ret_val;
+}
+
+
+void formatTime(const REGFI_NTTIME* nttime, char* output)
+{
+  time_t tmp_time[1];
+  struct tm* tmp_time_s = NULL;
+
+  *tmp_time = regfi_nt2unix_time(nttime);
+  tmp_time_s = gmtime(tmp_time);
+  strftime(output, 
+	   (4+1+2+1+2)+1+(2+1+2+1+2)+1, 
+              "%Y-%m-%d %H:%M:%S", 
+	   tmp_time_s);
+}
Index: trunk/src/reglookup-recover.c
===================================================================
--- trunk/src/reglookup-recover.c	(revision 177)
+++ trunk/src/reglookup-recover.c	(revision 178)
@@ -40,5 +40,5 @@
 
 
-char* getQuotedData(int fd, uint32_t offset, uint32_t length)
+char* getQuotedData(REGFI_RAW_FILE* file_cb, uint32_t offset, uint32_t length)
 {
   uint8_t* buf;
@@ -46,5 +46,5 @@
   uint32_t len;
 
-  if((lseek(fd, offset, SEEK_SET)) == -1)
+  if((regfi_seek(file_cb, offset, SEEK_SET)) == -1)
     return NULL;
 
@@ -54,5 +54,5 @@
 
   len = length;
-  if((regfi_read(fd, buf, &length) != 0) || length != len)
+  if((regfi_read(file_cb, buf, &length) != 0) || length != len)
   {
     free(buf);
@@ -69,14 +69,10 @@
 void printKey(REGFI_FILE* f, REGFI_NK_REC* nk, const char* prefix)
 {
-  char mtime[20];
-  time_t tmp_time[1];
-  struct tm* tmp_time_s = NULL;
+  char mtime[24];
   char* quoted_name = NULL;
   char* quoted_raw = "";
 
-  *tmp_time = regfi_nt2unix_time(&nk->mtime);
-  tmp_time_s = gmtime(tmp_time);
-  strftime(mtime, sizeof(mtime), "%Y-%m-%d %H:%M:%S", tmp_time_s);
-
+  formatTime(&nk->mtime, mtime);
+  
   /* XXX: Add command line option to choose output encoding */
   regfi_interpret_keyname(f, nk, REGFI_ENCODING_ASCII, true);
@@ -96,5 +92,5 @@
 
   if(print_parsedraw)
-    quoted_raw = getQuotedData(f->fd, nk->offset, nk->cell_size);
+    quoted_raw = getQuotedData(f->cb, nk->offset, nk->cell_size);
 
   printf("%.8X,%.8X,KEY,%s,%s,%s,%d,,,,,,,,%s\n", nk->offset, nk->cell_size,
@@ -162,5 +158,5 @@
 
   if(print_parsedraw)
-    quoted_raw = getQuotedData(f->fd, vk->offset, vk->cell_size);
+    quoted_raw = getQuotedData(f->cb, vk->offset, vk->cell_size);
 
   str_type = regfi_type_val2str(vk->type);
@@ -195,5 +191,5 @@
 
   if(print_parsedraw)
-    quoted_raw = getQuotedData(f->fd, sk->offset, sk->cell_size);
+    quoted_raw = getQuotedData(f->cb, sk->offset, sk->cell_size);
 
   if(owner == NULL)
@@ -229,8 +225,8 @@
   bool unalloc;
 
-  if(!regfi_parse_cell(f->fd, offset, NULL, 0, &cell_length, &unalloc))
+  if(!regfi_parse_cell(f->cb, offset, NULL, 0, &cell_length, &unalloc))
     return 1;
 
-  quoted_buf = getQuotedData(f->fd, offset, cell_length);
+  quoted_buf = getQuotedData(f->cb, offset, cell_length);
   if(quoted_buf == NULL)
     return 2;
@@ -490,5 +486,5 @@
 	max_size = regfi_calc_maxsize(file, offset);
 	if(max_size >= 0 
-	   && regfi_parse_cell(file->fd, offset, NULL, 0,
+	   && regfi_parse_cell(file->cb, offset, NULL, 0,
 			       &cell_length, &unalloc)
 	   && (cell_length & 0x00000007) == 0
@@ -789,5 +785,6 @@
   REGFI_VK_REC* tmp_value;
   uint32_t argi, arge, i, j, ret, num_unalloc_keys;
-  
+  int fd;
+
   /* Process command line arguments */
   if(argc < 2)
@@ -826,10 +823,18 @@
     bailOut(REGLOOKUP_EXIT_OSERR, "ERROR: Memory allocation problem.\n");
 
-  f = regfi_open(registry_file);
-  if(f == NULL)
+  fd = openHive(registry_file);
+  if(fd < 0)
   {
     fprintf(stderr, "ERROR: Couldn't open registry file: %s\n", registry_file);
     bailOut(REGLOOKUP_EXIT_NOINPUT, "");
   }
+
+  f = regfi_alloc(fd);
+  if(f == NULL)
+  {
+    close(fd);
+    bailOut(REGLOOKUP_EXIT_NOINPUT, "ERROR: Failed to create REGFI_FILE structure.\n");
+  }
+
   if(print_verbose)
     regfi_set_message_mask(f, REGFI_MSG_ERROR|REGFI_MSG_WARN|REGFI_MSG_INFO);
@@ -991,4 +996,7 @@
   range_list_free(unalloc_sks);
 
+  regfi_free(f);
+  close(fd);
+
   return 0;
 }
Index: trunk/src/reglookup.c
===================================================================
--- trunk/src/reglookup.c	(revision 177)
+++ trunk/src/reglookup.c	(revision 178)
@@ -296,15 +296,11 @@
   char* sacl = NULL;
   char* dacl = NULL;
+  char mtime[24];
   char* quoted_classname;
-  char mtime[20];
-  time_t tmp_time[1];
-  struct tm* tmp_time_s = NULL;
   const REGFI_SK_REC* sk;
   const REGFI_NK_REC* k = regfi_iterator_cur_key(iter);
   REGFI_CLASSNAME* classname;
 
-  *tmp_time = regfi_nt2unix_time(&k->mtime);
-  tmp_time_s = gmtime(tmp_time);
-  strftime(mtime, sizeof(mtime), "%Y-%m-%d %H:%M:%S", tmp_time_s);
+  formatTime(&k->mtime, mtime);
 
   if(print_security && (sk=regfi_iterator_cur_sk(iter)))
@@ -563,5 +559,5 @@
   char** path = NULL;
   REGFI_ITERATOR* iter;
-  int retr_path_ret;
+  int retr_path_ret, fd;
   uint32_t argi, arge;
 
@@ -624,9 +620,16 @@
     bailOut(REGLOOKUP_EXIT_OSERR, "ERROR: Memory allocation problem.\n");
 
-  f = regfi_open(registry_file);
-  if(f == NULL)
+  fd = openHive(registry_file);
+  if(fd < 0)
   {
     fprintf(stderr, "ERROR: Couldn't open registry file: %s\n", registry_file);
     bailOut(REGLOOKUP_EXIT_NOINPUT, "");
+  }
+
+  f = regfi_alloc(fd);
+  if(f == NULL)
+  {
+    close(fd);
+    bailOut(REGLOOKUP_EXIT_NOINPUT, "ERROR: Failed to create REGFI_FILE structure.\n");
   }
 
@@ -675,5 +678,6 @@
 
   regfi_iterator_free(iter);
-  regfi_close(f);
+  regfi_free(f);
+  close(fd);
 
   return 0;
