Index: /test/pyregfi-smoketest.py
===================================================================
--- /test/pyregfi-smoketest.py	(revision 218)
+++ /test/pyregfi-smoketest.py	(revision 219)
@@ -82,5 +82,5 @@
     for k in hive:
         for v in k.values:
-            d = v.data
+            d = v.fetch_data()
             if d == None:
                 data_stat += 0.1
@@ -90,5 +90,5 @@
                 data_stat += d/2.0**64
 
-            d = v.data_raw
+            d = v.fetch_raw_data()
             if d == None:
                 dataraw_stat += 0.1
@@ -133,4 +133,25 @@
 
 
+# Iterates hive gathering stats about security and classname records
+def iterFetchRelated(hive):
+    security_stat = 0.0
+    classname_stat = 0.0
+    modified_stat = 0.0
+
+    for k in hive:
+        cn = k.fetch_classname()
+        if cn == None:
+            classname_stat += 0.000001
+        elif type(cn) == bytearray:
+            classname_stat += len(cn)/2**32
+        else:
+            classname_stat += len(cn)
+
+        modified_stat += k.modified
+        
+    print("  Security stat: %f" % security_stat)
+    print("  Classname stat: %f" % classname_stat)
+    print("  Modified stat: %f" % modified_stat)
+
 if len(sys.argv) < 2:
     usage()
@@ -138,6 +159,6 @@
 
 
-#tests = [("iterTallyNames",iterTallyNames),("iterParentWalk",iterParentWalk),("iterTallyData",iterTallyData),]
-tests = [("recurseKeyTally",recurseKeyTally),("iterParentWalk",iterParentWalk),]
+#tests = [("iterTallyNames",iterTallyNames),("iterParentWalk",iterParentWalk),("iterTallyData",iterTallyData),("recurseKeyTally",recurseKeyTally),("iterFetchRelated",iterFetchRelated),]
+tests = [("iterFetchRelated",iterFetchRelated),]
 
 files = []
Index: /trunk/include/regfi.h
===================================================================
--- /trunk/include/regfi.h	(revision 218)
+++ /trunk/include/regfi.h	(revision 219)
@@ -1656,5 +1656,5 @@
 void                  regfi_unix2nt_time(REGFI_NTTIME* nt, time_t t);
 _EXPORT
-time_t                regfi_nt2unix_time(const REGFI_NTTIME* nt);
+double                regfi_nt2unix_time(const REGFI_NTTIME* nt);
 
 
Index: /trunk/lib/regfi.c
===================================================================
--- /trunk/lib/regfi.c	(revision 218)
+++ /trunk/lib/regfi.c	(revision 219)
@@ -3649,8 +3649,8 @@
  converts this to real GMT.
 ****************************************************************************/
-time_t regfi_nt2unix_time(const REGFI_NTTIME* nt)
-{
-  double d;
-  time_t ret;
+double regfi_nt2unix_time(const REGFI_NTTIME* nt)
+{
+  double ret_val;
+
   /* The next two lines are a fix needed for the 
      broken SCO compiler. JRA. */
@@ -3661,18 +3661,17 @@
     return(0);
   
-  d = ((double)nt->high)*4.0*(double)(1<<30);
-  d += (nt->low&0xFFF00000);
-  d *= 1.0e-7;
+  ret_val = ((double)nt->high)*4.0*(double)(1<<30);
+  ret_val += nt->low;
+  ret_val *= 1.0e-7;
   
   /* now adjust by 369 years to make the secs since 1970 */
-  d -= TIME_FIXUP_CONSTANT;
-  
-  if (d <= l_time_min)
+  ret_val -= TIME_FIXUP_CONSTANT;
+  
+  /* XXX: should these sanity checks be removed? */
+  if (ret_val <= l_time_min)
     return (l_time_min);
   
-  if (d >= l_time_max)
+  if (ret_val >= l_time_max)
     return (l_time_max);
-  
-  ret = (time_t)(d+0.5);
   
   /* this takes us from kludge-GMT to real GMT */
@@ -3686,5 +3685,5 @@
   */
 
-  return(ret);
+  return ret_val;
 }
 
Index: /trunk/python/pyregfi/__init__.py
===================================================================
--- /trunk/python/pyregfi/__init__.py	(revision 218)
+++ /trunk/python/pyregfi/__init__.py	(revision 219)
@@ -6,4 +6,5 @@
 
 import sys
+import time
 import weakref
 from pyregfi.structures import *
@@ -70,4 +71,7 @@
 regfi.regfi_get_parentkey.argtypes = [POINTER(REGFI_FILE), POINTER(REGFI_NK)]
 regfi.regfi_get_parentkey.restype = POINTER(REGFI_NK)
+
+regfi.regfi_nt2unix_time.argtypes = [POINTER(REGFI_NTTIME)]
+regfi.regfi_nt2unix_time.restype = c_double
 
 regfi.regfi_iterator_new.argtypes = [POINTER(REGFI_FILE), REGFI_ENCODING]
@@ -302,7 +306,7 @@
 
     def __getattr__(self, name):
-        ret_val = super(Key, self).__getattr__(name)
-        
         if name == "name":
+            ret_val = super(Key, self).__getattr__(name)
+
             if ret_val == None:
                 ret_val = self.name_raw
@@ -311,13 +315,33 @@
                 
         elif name == "name_raw":
+            ret_val = super(Key, self).__getattr__(name)
             length = super(Key, self).__getattr__('name_length')
             ret_val = _buffer2bytearray(ret_val, length)
         
+        elif name == "modified":
+            ret_val = regfi.regfi_nt2unix_time(byref(self._base.contents.mtime))
+
+        else:
+            ret_val = super(Key, self).__getattr__(name)
+
         return ret_val
-
 
     def fetch_security(self):
         return Security(self._hive,
                         regfi.regfi_fetch_sk(self._hive.file, self._base))
+
+    def fetch_classname(self):
+        ret_val = None
+        cn_p = regfi.regfi_fetch_classname(self._hive.file, self._base)
+        if cn_p:
+            cn_struct = cn_p.contents
+            if cn_struct.interpreted:
+                ret_val = cn_struct.interpreted.decode('utf-8', 'replace')
+            else:
+                ret_val = _buffer2bytearray(cn_struct.raw,
+                                            cn_struct.size)
+            regfi.regfi_free_record(cn_p)
+
+        return ret_val
 
     def get_parent(self):
@@ -339,58 +363,60 @@
 # 
 class Value(_StructureWrapper):
+    def fetch_data(self):
+        ret_val = None
+        data_p = regfi.regfi_fetch_data(self._hive.file, self._base)
+        if not data_p:
+            return None
+        data_struct = data_p.contents
+
+        if data_struct.interpreted_size == 0:
+            ret_val = None
+        elif data_struct.type in (REG_SZ, REG_EXPAND_SZ, REG_LINK):
+            # Unicode strings
+            ret_val = data_struct.interpreted.string.decode('utf-8', 'replace')
+        elif data_struct.type in (REG_DWORD, REG_DWORD_BE):
+            # 32 bit integers
+            ret_val = data_struct.interpreted.dword
+        elif data_struct.type == REG_QWORD:
+            # 64 bit integers
+            ret_val = data_struct.interpreted.qword
+        elif data_struct.type == REG_MULTI_SZ:
+            ret_val = _charss2strlist(data_struct.interpreted.multiple_string)
+        elif data_struct.type in (REG_NONE, REG_RESOURCE_LIST,
+                                  REG_FULL_RESOURCE_DESCRIPTOR,
+                                  REG_RESOURCE_REQUIREMENTS_LIST,
+                                  REG_BINARY):
+            ret_val = _buffer2bytearray(data_struct.interpreted.none,
+                                        data_struct.interpreted_size)
+
+        regfi.regfi_free_record(data_p)
+        return ret_val
+        
+    def fetch_raw_data(self):
+        ret_val = None
+
+        # XXX: should we load the data without interpretation instead?
+        data_p = regfi.regfi_fetch_data(self._hive.file, self._base)
+        if not data_p:
+            return None
+
+        data_struct = data_p.contents
+        ret_val = _buffer2bytearray(data_struct.raw,
+                                    data_struct.size)
+        regfi.regfi_free_record(data_p)
+
+        return ret_val
+
     def __getattr__(self, name):
-        ret_val = None
-        if name == "data":
-            data_p = regfi.regfi_fetch_data(self._hive.file, self._base)
-            try:
-                data_struct = data_p.contents
-            except Exception:
-                return None
-
-            if data_struct.interpreted_size == 0:
-                ret_val = None
-            elif data_struct.type in (REG_SZ, REG_EXPAND_SZ, REG_LINK):
-                # Unicode strings
-                ret_val = data_struct.interpreted.string.decode('utf-8', 'replace')
-            elif data_struct.type in (REG_DWORD, REG_DWORD_BE):
-                # 32 bit integers
-                ret_val = data_struct.interpreted.dword
-            elif data_struct.type == REG_QWORD:
-                # 64 bit integers
-                ret_val = data_struct.interpreted.qword
-            elif data_struct.type == REG_MULTI_SZ:
-                ret_val = _charss2strlist(data_struct.interpreted.multiple_string)
-            elif data_struct.type in (REG_NONE, REG_RESOURCE_LIST,
-                                      REG_FULL_RESOURCE_DESCRIPTOR,
-                                      REG_RESOURCE_REQUIREMENTS_LIST,
-                                      REG_BINARY):
-                ret_val = _buffer2bytearray(data_struct.interpreted.none,
-                                            data_struct.interpreted_size)
-
-            regfi.regfi_free_record(data_p)
-            
-        elif name == "data_raw":
-            # XXX: should we load the data without interpretation instead?
-            data_p = regfi.regfi_fetch_data(self._hive.file, self._base)
-            try:
-                data_struct = data_p.contents
-            except Exception:
-                return None
-
-            ret_val = _buffer2bytearray(data_struct.raw,
-                                        data_struct.size)
-            regfi.regfi_free_record(data_p)
-            
-        else:
-            ret_val = super(Value, self).__getattr__(name)
-            if name == "name":
-                if ret_val == None:
-                    ret_val = self.name_raw
-                else:
-                    ret_val = ret_val.decode('utf-8', 'replace')
-
-            elif name == "name_raw":
-                length = super(Value, self).__getattr__('name_length')
-                ret_val = _buffer2bytearray(ret_val, length)
+        ret_val = super(Value, self).__getattr__(name)
+        if name == "name":
+            if ret_val == None:
+                ret_val = self.name_raw
+            else:
+                ret_val = ret_val.decode('utf-8', 'replace')
+
+        elif name == "name_raw":
+            length = super(Value, self).__getattr__('name_length')
+            ret_val = _buffer2bytearray(ret_val, length)
 
         return ret_val
Index: /trunk/src/common.c
===================================================================
--- /trunk/src/common.c	(revision 218)
+++ /trunk/src/common.c	(revision 219)
@@ -368,5 +368,5 @@
   struct tm* tmp_time_s = NULL;
 
-  *tmp_time = regfi_nt2unix_time(nttime);
+  *tmp_time = (time_t)regfi_nt2unix_time(nttime);
   tmp_time_s = gmtime(tmp_time);
   strftime(output, 
