Index: trunk/python/pyregfi/__init__.py
===================================================================
--- trunk/python/pyregfi/__init__.py	(revision 227)
+++ trunk/python/pyregfi/__init__.py	(revision 228)
@@ -95,8 +95,9 @@
 import sys
 import time
-from pyregfi.structures import *
-
 import ctypes
 import ctypes.util
+import threading
+from pyregfi.structures import *
+
 
 ## An enumeration of registry Value data types
@@ -218,5 +219,4 @@
 
 
-
 ## Abstract class for most objects returned by the library
 class _StructureWrapper(object):
@@ -239,5 +239,5 @@
     # Memory management for most regfi structures is taken care of here
     def __del__(self):
-        regfi.regfi_free_record(self._base)
+        regfi.regfi_free_record(self._hive.file, self._base)
 
 
@@ -299,5 +299,5 @@
                             + "Current log:\n" + GetLogMessages())
         
-        if not regfi.regfi_reference_record(key._base):
+        if not regfi.regfi_reference_record(key._hive.file, key._base):
             raise Exception("Could not create _GenericList; memory error."
                             + "Current log:\n" + GetLogMessages())
@@ -308,6 +308,6 @@
     
     def __del__(self):
-        regfi.regfi_free_record(self._key_base)
-    
+        regfi.regfi_free_record(self._hive.file, self._key_base)
+
 
     ## Length of list
@@ -486,5 +486,5 @@
                 ret_val = _buffer2bytearray(cn_struct.raw,
                                             cn_struct.size)
-            regfi.regfi_free_record(cn_p)
+            regfi.regfi_free_record(self._hive.file, cn_p)
 
         return ret_val
@@ -581,5 +581,5 @@
                                         data_struct.interpreted_size)
 
-        regfi.regfi_free_record(data_p)
+        regfi.regfi_free_record(self._hive.file, data_p)
         return ret_val
     
@@ -599,5 +599,5 @@
         ret_val = _buffer2bytearray(data_struct.raw,
                                     data_struct.size)
-        regfi.regfi_free_record(data_p)
+        regfi.regfi_free_record(self._hive.file, data_p)
         return ret_val
 
@@ -747,31 +747,42 @@
     _iter = None
     _iteration_root = None
+    _lock = None
 
     def __init__(self, hive):
-        self._iter = regfi.regfi_iterator_new(hive.file, REGFI_ENCODING_UTF8)
+        self._iter = regfi.regfi_iterator_new(hive.file)
         if not self._iter:
             raise Exception("Could not create iterator.  Current log:\n"
                             + GetLogMessages())
         self._hive = hive
-        
+        self._lock = threading.RLock()
+    
     def __getattr__(self, name):
-        return getattr(self.file.contents, name)
-
-    def __del__(self):    
+        self._lock.acquire()
+        ret_val = getattr(self._iter.contents, name)
+        self._lock.release()
+        return ret_val
+
+    def __del__(self):
+        self._lock.acquire()
         regfi.regfi_iterator_free(self._iter)
+        self._lock.release()
 
     def __iter__(self):
+        self._lock.acquire()
         self._iteration_root = None
+        self._lock.release()
         return self
 
     def __next__(self):
+        self._lock.acquire()
         if self._iteration_root == None:
-            self._iteration_root = self.current_key()
+            self._iteration_root = self.current_key().offset
         elif not regfi.regfi_iterator_down(self._iter):
             up_ret = regfi.regfi_iterator_up(self._iter)
             while (up_ret and
                    not regfi.regfi_iterator_next_subkey(self._iter)):
-                if self._iteration_root == self.current_key():
+                if self._iteration_root == self.current_key().offset:
                     self._iteration_root = None
+                    self._lock.release()
                     raise StopIteration('')
                 up_ret = regfi.regfi_iterator_up(self._iter)
@@ -779,13 +790,19 @@
             if not up_ret:
                 self._iteration_root = None
+                self._lock.release()
                 raise StopIteration('')
             
             # XXX: Use non-generic exception
             if not regfi.regfi_iterator_down(self._iter):
+                self._lock.release()
                 raise Exception('Error traversing iterator downward.'+
                                 ' Current log:\n'+ GetLogMessages())
 
         regfi.regfi_iterator_first_subkey(self._iter)
-        return self.current_key()
+        ret_val = self.current_key()
+        self._lock.release()
+
+        return ret_val
+
 
     # For Python 2.x
@@ -806,11 +823,17 @@
     # @return True if successful, False otherwise
     def down(self, subkey_name=None):
+        ret_val = None
         if subkey_name == None:
-            return regfi.regfi_iterator_down(self._iter)
+            self._lock.acquire()
+            ret_val = regfi.regfi_iterator_down(self._iter)
         else:
             if name != None:
                 name = name.encode('utf-8')
-            return (regfi.regfi_iterator_find_subkey(self._iter, name) 
-                    and regfi.regfi_iterator_down(self._iter))
+            self._lock.acquire()
+            ret_val = (regfi.regfi_iterator_find_subkey(self._iter, name) 
+                       and regfi.regfi_iterator_down(self._iter))
+        
+        self._lock.release()
+        return ret_val
 
 
@@ -824,5 +847,8 @@
     #       default selections.
     def up(self):
-        return regfi.regfi_iterator_up(self._iter)
+        self._lock.acquire()
+        ret_val = regfi.regfi_iterator_up(self._iter)
+        self._lock.release()
+        return ret_val
 
 
@@ -832,7 +858,10 @@
     #         None on error or if the current key has no subkeys.
     def first_subkey(self):
+        ret_val = None
+        self._lock.acquire()
         if regfi.regfi_iterator_first_subkey(self._iter):
-            return self.current_subkey()
-        return None
+            ret_val = self.current_subkey()
+        self._lock.release()
+        return ret_val
 
 
@@ -842,7 +871,10 @@
     #         None on error or if the current key has no values.
     def first_value(self):
+        ret_val = None
+        self._lock.acquire()
         if regfi.regfi_iterator_first_value(self._iter):
-            return self.current_value()
-        return None
+            ret_val = self.current_value()
+        self._lock.release()
+        return ret_val
 
 
@@ -852,7 +884,10 @@
     #         None if there are no remaining subkeys or an error occurred.
     def next_subkey(self):
+        ret_val = None
+        self._lock.acquire()
         if regfi.regfi_iterator_next_subkey(self._iter):
-            return self.current_subkey()
-        return None
+            ret_val = self.current_subkey()
+        self._lock.release()
+        return ret_val
 
 
@@ -862,7 +897,10 @@
     #         None if there are no remaining values or an error occurred.
     def next_value(self):
+        ret_val = None
+        self._lock.acquire()
         if regfi.regfi_iterator_next_value(self._iter):
-            return self.current_value()
-        return None
+            ret_val = self.current_value()
+        self._lock.release()
+        return ret_val
 
 
@@ -874,7 +912,10 @@
         if name != None:
             name = name.encode('utf-8')
+        ret_val = None
+        self._lock.acquire()
         if regfi.regfi_iterator_find_subkey(self._iter, name):
-            return self.current_subkey()
-        return None
+            ret_val = self.current_subkey()
+        self._lock.release()
+        return ret_val
 
 
@@ -886,7 +927,10 @@
         if name != None:
             name = name.encode('utf-8')
+        ret_val = None
+        self._lock.acquire()
         if regfi.regfi_iterator_find_value(self._iter, name):
-            return self.current_value()
-        return None
+            ret_val = self.current_value()
+        self._lock.release()
+        return ret_val
 
     ## Retrieves the currently selected subkey
@@ -894,5 +938,8 @@
     # @return A Key instance of the current subkey
     def current_subkey(self):
-        return Key(self._hive, regfi.regfi_iterator_cur_subkey(self._iter))
+        self._lock.acquire()
+        ret_val = Key(self._hive, regfi.regfi_iterator_cur_subkey(self._iter))
+        self._lock.release()
+        return ret_val
 
     ## Retrieves the currently selected value
@@ -900,5 +947,8 @@
     # @return A Value instance of the current value
     def current_value(self):
-        return Value(self._hive, regfi.regfi_iterator_cur_value(self._iter))
+        self._lock.acquire()
+        ret_val = Value(self._hive, regfi.regfi_iterator_cur_value(self._iter))
+        self._lock.release()
+        return ret_val
 
     ## Retrieves the current key
@@ -906,5 +956,8 @@
     # @return A Key instance of the current position of the iterator
     def current_key(self):
-        return Key(self._hive, regfi.regfi_iterator_cur_key(self._iter))
+        self._lock.acquire()
+        ret_val = Key(self._hive, regfi.regfi_iterator_cur_key(self._iter))
+        self._lock.release()
+        return ret_val
 
 
@@ -919,6 +972,9 @@
         cpath = _strlist2charss(path)
 
-        # XXX: Use non-generic exception
-        if not regfi.regfi_iterator_walk_path(self._iter, cpath):
+        self._lock.acquire()
+        result = regfi.regfi_iterator_walk_path(self._iter, cpath)
+        self._lock.release()
+        if not result:
+            # XXX: Use non-generic exception
             raise Exception('Could not locate path.\n'+GetLogMessages())
 
