Changeset 224 for trunk


Ignore:
Timestamp:
04/03/11 12:53:59 (13 years ago)
Author:
tim
Message:

added new regfi API function to help manage memory better
fixed reference loop problems in pyregfi

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/regfi.h

    r221 r224  
    979979
    980980
     981/** Increments reference count on record
     982 *
     983 * Adds an extra internal reference to specified record, making it necessary to
     984 * call regfi_free_record on it an additional time before it is freed.  This is
     985 * useful in cases where multiple threads/structures need access to a record,
     986 * without requiring them to be in sync with when it is freed.
     987 *
     988 * Can be used on REGFI_NK, REGFI_VK, REGFI_SK, REGFI_DATA, and
     989 * REGFI_CLASSNAME records.
     990 *
     991 * @return true on success, false otherwise
     992 *
     993 * @ingroup regfiBase
     994 */
     995_EXPORT
     996bool regfi_reference_record(const void* record);
     997
     998
    981999/** Retrieves number of subkeys referenced by this key.
    9821000 *
  • trunk/lib/regfi.c

    r223 r224  
    17201720
    17211721
     1722/******************************************************************************
     1723 *****************************************************************************/
     1724bool regfi_reference_record(const void* record)
     1725{
     1726  if(talloc_reference(NULL, record) != NULL)
     1727    return true;
     1728  return false;
     1729}
    17221730
    17231731
  • trunk/python/pyregfi/__init__.py

    r221 r224  
    200200        self._base = base
    201201
     202
    202203    # Memory management for most regfi structures is taken care of here
    203204    def __del__(self):
    204205        regfi.regfi_free_record(self._base)
     206
    205207
    206208    # Any attribute requests not explicitly defined in subclasses gets passed
     
    208210    def __getattr__(self, name):
    209211        return getattr(self._base.contents, name)
     212
    210213   
    211214    ## Test for equality
     
    224227        return (type(self) == type(other)) and (self.offset == other.offset)
    225228
     229
    226230    def __ne__(self, other):
    227231        return (not self.__eq__(other))
     
    244248class _GenericList(object):
    245249    _hive = None
    246     _key = None
     250    _key_base = None
    247251    _length = None
    248252    _current = None
     
    255259
    256260    def __init__(self, key):
     261        if not key:
     262            raise Exception("Could not create _GenericList; key is NULL."
     263                            + "Current log:\n" + GetLogMessages())
     264       
     265        if not regfi.regfi_reference_record(key._base):
     266            raise Exception("Could not create _GenericList; memory error."
     267                            + "Current log:\n" + GetLogMessages())
     268        self._key_base = key._base
     269        self._length = self._fetch_num(self._key_base)
    257270        self._hive = key._hive
    258271
    259         # Normally it's good to avoid cyclic references like this
    260         # (key.list.key...) but in this case it makes ctypes memory
    261         # management easier to reference the Key instead of the base
    262         # structure.  We use a weak reference in order to allow for garbage
    263         # collection, since value/subkey lists should not be usable if their
    264         # parent Key is freed anyway.
    265 
    266         # XXX: check for NULL here, throw an exception if so.
    267         self._key = weakref.proxy(key)
    268         self._length = self._fetch_num(key._base)
    269    
    270    
     272   
     273    def __del__(self):
     274        regfi.regfi_free_record(self._key_base)
     275   
     276
    271277    ## Length of list
    272278    def __len__(self):
     
    286292            name = create_string_buffer(bytes(name))
    287293
    288         if self._find_element(self._hive.file, self._key._base,
     294        if self._find_element(self._hive.file, self._key_base,
    289295                              name, byref(index)):
    290296            return self._constructor(self._hive,
    291297                                     self._get_element(self._hive.file,
    292                                                        self._key._base,
     298                                                       self._key_base,
    293299                                                       index))
    294300        raise KeyError('')
     
    308314            raise StopIteration('')
    309315
    310         elem = self._get_element(self._hive.file, self._key._base,
     316        elem = self._get_element(self._hive.file, self._key_base,
    311317                                 ctypes.c_uint32(self._current))
    312318        self._current += 1
     
    638644    def __getattr__(self, name):
    639645        if name == "root":
    640             if self._root == None:
    641                 self._root = Key(self, regfi.regfi_get_rootkey(self.file))
    642             return self._root
     646            # XXX: This creates reference loops.  Need to cache better inside regfi
     647            #if self._root == None:
     648            #    self._root = Key(self, regfi.regfi_get_rootkey(self.file))
     649            #return self._root
     650            return Key(self, regfi.regfi_get_rootkey(self.file))
    643651
    644652        elif name == "modified":
  • trunk/python/pyregfi/structures.py

    r221 r224  
    241241regfi.regfi_free_record.restype = None
    242242
     243regfi.regfi_reference_record.argtypes = [c_void_p]
     244regfi.regfi_reference_record.restype = c_bool
     245
    243246regfi.regfi_fetch_num_subkeys.argtypes = [POINTER(REGFI_NK)]
    244247regfi.regfi_fetch_num_subkeys.restype = c_uint32
Note: See TracChangeset for help on using the changeset viewer.