Changeset 228
- Timestamp:
- 04/18/11 16:25:46 (14 years ago)
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
test/Makefile
r180 r228 5 5 OPTS=-std=gnu99 -pedantic -Wall -ggdb 6 6 INC:=-I../trunk/include -I../trunk/src -I/usr/local/include 7 LIB=-L/usr/local/lib -lm -lpthread 7 LIB=-L/usr/local/lib -lm -lpthread -ltalloc 8 8 9 9 REGFI_THREADTEST=regfi-threadtest … … 14 14 15 15 deps: 16 cd ../trunk && $(MAKE) clean 17 cd ../trunk && $(MAKE) lib 16 cd ../trunk && scons libregfi 18 17 19 18 $(REGFI_THREADTEST): regfi-threadtest.o -
test/pyregfi-smoketest.py
r227 r228 5 5 import io 6 6 import time 7 import threading 7 8 import pyregfi 8 9 … … 189 190 pass 190 191 192 193 def threadIterMain(iter): 194 x = 0 195 try: 196 for k in iter: 197 #x += len(k.name) + len(k.subkeys) 198 pass 199 except Exception as e: 200 print("%s dying young: %s" % (threading.current_thread().name, repr(e))) 201 # Exceptions are thrown on iteration because python state gets out of 202 # whack. That's fine, because we're really just interested in finding 203 # segfaults. People should not use iterators without locks, but it 204 # should at least not segfault on them. 205 pass 206 print("%s finished" % threading.current_thread().name) 207 208 def iterMultithread(hive, fh): 209 num_threads = 10 210 iter = pyregfi.HiveIterator(hive) 211 threads = [] 212 for t in range(0,num_threads): 213 threads.append(threading.Thread(target=threadIterMain, args=(iter,))) 214 for t in threads: 215 t.start() 216 for t in threads: 217 t.join() 218 219 191 220 tests = { 192 221 "iterTallyNames":iterTallyNames, … … 197 226 "iterIterWalk":iterIterWalk, 198 227 "iterCallbackIO":iterCallbackIO, 228 "iterMultithread":iterMultithread, 199 229 } 200 230 -
test/regfi-threadtest.c
r185 r228 2 2 * A program to stress test regfi under multithreaded use. 3 3 * 4 * Copyright (C) 2005-201 0Timothy D. Morgan4 * Copyright (C) 2005-2011 Timothy D. Morgan 5 5 * Copyright (C) 2002 Richard Sharpe, rsharpe@richardsharpe.com 6 6 * … … 46 46 47 47 48 49 48 void traverseValueList(REGFI_ITERATOR* iter) 50 49 { 51 const REGFI_VK_REC* value; 52 53 value = regfi_iterator_first_value(iter); 54 while(value != NULL) 55 { 50 const REGFI_VK* value; 51 bool ret; 52 53 for(ret=regfi_iterator_first_value(iter); 54 ret; 55 ret=regfi_iterator_next_value(iter)) 56 { 57 value = regfi_iterator_cur_value(iter); 56 58 printMsgs(iter->f); 57 59 regfi_free_record(value); 58 value = regfi_iterator_next_value(iter);59 60 } 60 61 } … … 63 64 void traverseKeyTree(REGFI_ITERATOR* iter) 64 65 { 65 const REGFI_NK _REC* root = NULL;66 const REGFI_NK _REC* cur = NULL;67 const REGFI_NK _REC* sub = NULL;68 const REGFI_SK _REC* sk;66 const REGFI_NK* root = NULL; 67 const REGFI_NK* cur = NULL; 68 const REGFI_NK* sub = NULL; 69 const REGFI_SK* sk; 69 70 bool print_this = true; 70 71 71 72 root = cur = regfi_iterator_cur_key(iter); 72 sub = regfi_iterator_first_subkey(iter); 73 regfi_iterator_first_subkey(iter); 74 sub = regfi_iterator_cur_subkey(iter); 73 75 printMsgs(iter->f); 74 76 … … 86 88 { 87 89 /* We're done with this sub-tree, going up and hitting other branches. */ 90 regfi_free_record(cur); 88 91 if(!regfi_iterator_up(iter)) 89 92 { … … 95 98 /* fprintf(stderr, "%s\n", cur->keyname);*/ 96 99 printMsgs(iter->f); 97 sk = regfi_iterator_cur_sk(iter);98 printMsgs(iter->f);99 100 if(cur == NULL) 100 101 bailOut(REGLOOKUP_EXIT_DATAERR, "ERROR: unexpected NULL for key.\n"); 101 102 sub = regfi_iterator_next_subkey(iter); 102 sk = regfi_fetch_sk(iter->f, cur); 103 printMsgs(iter->f); 104 regfi_free_record(sk); 105 106 regfi_iterator_next_subkey(iter); 107 sub = regfi_iterator_cur_subkey(iter); 103 108 } 104 109 print_this = false; … … 108 113 * Let's move down and print this first sub-tree out. 109 114 */ 115 regfi_free_record(cur); 110 116 if(!regfi_iterator_down(iter)) 111 117 { … … 118 124 regfi_free_record(sub); 119 125 120 sub = regfi_iterator_first_subkey(iter); 126 regfi_iterator_first_subkey(iter); 127 sub = regfi_iterator_cur_subkey(iter); 121 128 printMsgs(iter->f); 122 129 print_this = true; … … 124 131 printMsgs(iter->f); 125 132 } while(!((cur == root) && (sub == NULL))); 133 regfi_free_record(root); 126 134 127 135 if(print_verbose) … … 138 146 regfi_log_set_mask(REGFI_LOG_INFO|REGFI_LOG_WARN|REGFI_LOG_ERROR); 139 147 140 iter = regfi_iterator_new((REGFI_FILE*)f , REGFI_ENCODING_ASCII);148 iter = regfi_iterator_new((REGFI_FILE*)f); 141 149 if(iter == NULL) 142 150 { … … 198 206 } 199 207 200 f = regfi_alloc(fd );208 f = regfi_alloc(fd, REGFI_ENCODING_ASCII); 201 209 if(f == NULL) 202 210 { … … 214 222 pthread_join(threads[i], NULL); 215 223 224 free(threads); 216 225 regfi_free(f); 217 226 close(fd); -
trunk/include/regfi.h
r226 r228 821 821 pthread_mutex_t sk_lock; 822 822 823 /* Needed to protect various talloc calls */ 824 pthread_mutex_t mem_lock; 825 823 826 } REGFI_FILE; 824 827 … … 971 974 /** Frees a record previously returned by one of the API functions. 972 975 * 973 * Can be used to free REGFI_NK, REGFI_VK, REGFI_SK, REGFI_DATA, and 974 * REGFI_CLASSNAME records. 975 * 976 * @note The "const" in the data type is a bit misleading and is there just for 976 * @param file The file from which the record originated. 977 * (This is needed for memory management reasons.) 978 * 979 * @param record Any of the following record types: REGFI_NK, REGFI_VK, 980 * REGFI_SK, REGFI_DATA, and REGFI_CLASSNAME records. 981 * 982 * @note The "const" in the record data type is a bit misleading and is there just for 977 983 * convenience. Since records returned previously must not be modified by users 978 984 * of the API due to internal caching, these are returned as const, so this … … 982 988 */ 983 989 _EXPORT 984 void regfi_free_record( const void* record);990 void regfi_free_record(REGFI_FILE* file, const void* record); 985 991 986 992 … … 992 998 * without requiring them to be in sync with when it is freed. 993 999 * 994 * Can be used on REGFI_NK, REGFI_VK, REGFI_SK, REGFI_DATA, and 995 * REGFI_CLASSNAME records. 1000 * @param file The file from which the record originated. 1001 * (This is needed for memory management reasons.) 1002 * 1003 * @param record Any of the following record types: REGFI_NK, REGFI_VK, 1004 * REGFI_SK, REGFI_DATA, and REGFI_CLASSNAME records. 996 1005 * 997 1006 * @return true on success, false otherwise … … 1000 1009 */ 1001 1010 _EXPORT 1002 bool regfi_reference_record( const void* record);1011 bool regfi_reference_record(REGFI_FILE* file, const void* record); 1003 1012 1004 1013 -
trunk/lib/regfi.c
r226 r228 1617 1617 } 1618 1618 1619 if(pthread_mutex_init(&rb->mem_lock, NULL) != 0) 1620 { 1621 regfi_log_add(REGFI_LOG_ERROR, "Failed to create mem_lock mutex."); 1622 goto fail; 1623 } 1624 1619 1625 rb->hbins = range_list_new(); 1620 1626 if(rb->hbins == NULL) … … 1657 1663 pthread_rwlock_destroy(&rb->hbins_lock); 1658 1664 pthread_mutex_destroy(&rb->sk_lock); 1665 pthread_mutex_destroy(&rb->mem_lock); 1659 1666 1660 1667 range_list_free(rb->hbins); … … 1721 1728 /****************************************************************************** 1722 1729 *****************************************************************************/ 1723 void regfi_free_record(const void* record) 1724 { 1730 void regfi_free_record(REGFI_FILE* file, const void* record) 1731 { 1732 if(!regfi_lock(file, &file->mem_lock, "regfi_free_record")) 1733 return; 1734 1725 1735 talloc_unlink(NULL, (void*)record); 1736 1737 regfi_unlock(file, &file->mem_lock, "regfi_free_record"); 1726 1738 } 1727 1739 … … 1729 1741 /****************************************************************************** 1730 1742 *****************************************************************************/ 1731 bool regfi_reference_record(const void* record) 1732 { 1743 bool regfi_reference_record(REGFI_FILE* file, const void* record) 1744 { 1745 bool ret_val = false; 1746 if(!regfi_lock(file, &file->mem_lock, "regfi_reference_record")) 1747 return ret_val; 1748 1733 1749 if(talloc_reference(NULL, record) != NULL) 1734 return true; 1735 return false; 1750 ret_val = true; 1751 1752 regfi_unlock(file, &file->mem_lock, "regfi_reference_record"); 1753 return ret_val; 1736 1754 } 1737 1755 … … 1823 1841 void regfi_iterator_free(REGFI_ITERATOR* i) 1824 1842 { 1825 talloc_ free(i);1843 talloc_unlink(NULL, i); 1826 1844 } 1827 1845 … … 1854 1872 talloc_unlink(NULL, subkey); 1855 1873 return false; 1856 } 1874 } 1857 1875 talloc_reparent(NULL, i, subkey); 1858 1876 … … 1875 1893 return false; 1876 1894 1895 if(!regfi_lock(i->f, &i->f->mem_lock, "regfi_iterator_up")) 1896 return false; 1897 1877 1898 talloc_unlink(i, i->cur_key); 1899 regfi_unlock(i->f, &i->f->mem_lock, "regfi_iterator_up"); 1900 1878 1901 i->cur_key = pos->nk; 1879 1902 i->cur_subkey = pos->cur_subkey; … … 1943 1966 const REGFI_NK* regfi_iterator_cur_key(REGFI_ITERATOR* i) 1944 1967 { 1945 return talloc_reference(NULL, i->cur_key); 1968 const REGFI_NK* ret_val = NULL; 1969 if(!regfi_lock(i->f, &i->f->mem_lock, "regfi_iterator_cur_key")) 1970 return ret_val; 1971 1972 ret_val = talloc_reference(NULL, i->cur_key); 1973 1974 regfi_unlock(i->f, &i->f->mem_lock, "regfi_iterator_cur_key"); 1975 return ret_val; 1946 1976 } 1947 1977 … … 2174 2204 } 2175 2205 2176 regfi_free_record( cur);2206 regfi_free_record(file, cur); 2177 2207 } 2178 2208 … … 2211 2241 } 2212 2242 2213 regfi_free_record( cur);2243 regfi_free_record(file, cur); 2214 2244 } 2215 2245 … … 2257 2287 { 2258 2288 if(key != NULL && key->parent_off != REGFI_OFFSET_NONE) 2259 {2260 /* fprintf(stderr, "key->parent_off=%.8X\n", key->parent_off);*/2261 2289 return regfi_load_key(file, 2262 2290 key->parent_off+REGFI_REGF_SIZE, 2263 2291 file->string_encoding, true); 2264 } 2265 2292 2266 2293 return NULL; 2267 2294 } -
trunk/python/pyregfi/__init__.py
r227 r228 95 95 import sys 96 96 import time 97 from pyregfi.structures import *98 99 97 import ctypes 100 98 import ctypes.util 99 import threading 100 from pyregfi.structures import * 101 101 102 102 103 ## An enumeration of registry Value data types … … 218 219 219 220 220 221 221 ## Abstract class for most objects returned by the library 222 222 class _StructureWrapper(object): … … 239 239 # Memory management for most regfi structures is taken care of here 240 240 def __del__(self): 241 regfi.regfi_free_record(self._ base)241 regfi.regfi_free_record(self._hive.file, self._base) 242 242 243 243 … … 299 299 + "Current log:\n" + GetLogMessages()) 300 300 301 if not regfi.regfi_reference_record(key._ base):301 if not regfi.regfi_reference_record(key._hive.file, key._base): 302 302 raise Exception("Could not create _GenericList; memory error." 303 303 + "Current log:\n" + GetLogMessages()) … … 308 308 309 309 def __del__(self): 310 regfi.regfi_free_record(self._ key_base)311 310 regfi.regfi_free_record(self._hive.file, self._key_base) 311 312 312 313 313 ## Length of list … … 486 486 ret_val = _buffer2bytearray(cn_struct.raw, 487 487 cn_struct.size) 488 regfi.regfi_free_record( cn_p)488 regfi.regfi_free_record(self._hive.file, cn_p) 489 489 490 490 return ret_val … … 581 581 data_struct.interpreted_size) 582 582 583 regfi.regfi_free_record( data_p)583 regfi.regfi_free_record(self._hive.file, data_p) 584 584 return ret_val 585 585 … … 599 599 ret_val = _buffer2bytearray(data_struct.raw, 600 600 data_struct.size) 601 regfi.regfi_free_record( data_p)601 regfi.regfi_free_record(self._hive.file, data_p) 602 602 return ret_val 603 603 … … 747 747 _iter = None 748 748 _iteration_root = None 749 _lock = None 749 750 750 751 def __init__(self, hive): 751 self._iter = regfi.regfi_iterator_new(hive.file , REGFI_ENCODING_UTF8)752 self._iter = regfi.regfi_iterator_new(hive.file) 752 753 if not self._iter: 753 754 raise Exception("Could not create iterator. Current log:\n" 754 755 + GetLogMessages()) 755 756 self._hive = hive 756 757 self._lock = threading.RLock() 758 757 759 def __getattr__(self, name): 758 return getattr(self.file.contents, name) 759 760 def __del__(self): 760 self._lock.acquire() 761 ret_val = getattr(self._iter.contents, name) 762 self._lock.release() 763 return ret_val 764 765 def __del__(self): 766 self._lock.acquire() 761 767 regfi.regfi_iterator_free(self._iter) 768 self._lock.release() 762 769 763 770 def __iter__(self): 771 self._lock.acquire() 764 772 self._iteration_root = None 773 self._lock.release() 765 774 return self 766 775 767 776 def __next__(self): 777 self._lock.acquire() 768 778 if self._iteration_root == None: 769 self._iteration_root = self.current_key() 779 self._iteration_root = self.current_key().offset 770 780 elif not regfi.regfi_iterator_down(self._iter): 771 781 up_ret = regfi.regfi_iterator_up(self._iter) 772 782 while (up_ret and 773 783 not regfi.regfi_iterator_next_subkey(self._iter)): 774 if self._iteration_root == self.current_key() :784 if self._iteration_root == self.current_key().offset: 775 785 self._iteration_root = None 786 self._lock.release() 776 787 raise StopIteration('') 777 788 up_ret = regfi.regfi_iterator_up(self._iter) … … 779 790 if not up_ret: 780 791 self._iteration_root = None 792 self._lock.release() 781 793 raise StopIteration('') 782 794 783 795 # XXX: Use non-generic exception 784 796 if not regfi.regfi_iterator_down(self._iter): 797 self._lock.release() 785 798 raise Exception('Error traversing iterator downward.'+ 786 799 ' Current log:\n'+ GetLogMessages()) 787 800 788 801 regfi.regfi_iterator_first_subkey(self._iter) 789 return self.current_key() 802 ret_val = self.current_key() 803 self._lock.release() 804 805 return ret_val 806 790 807 791 808 # For Python 2.x … … 806 823 # @return True if successful, False otherwise 807 824 def down(self, subkey_name=None): 825 ret_val = None 808 826 if subkey_name == None: 809 return regfi.regfi_iterator_down(self._iter) 827 self._lock.acquire() 828 ret_val = regfi.regfi_iterator_down(self._iter) 810 829 else: 811 830 if name != None: 812 831 name = name.encode('utf-8') 813 return (regfi.regfi_iterator_find_subkey(self._iter, name) 814 and regfi.regfi_iterator_down(self._iter)) 832 self._lock.acquire() 833 ret_val = (regfi.regfi_iterator_find_subkey(self._iter, name) 834 and regfi.regfi_iterator_down(self._iter)) 835 836 self._lock.release() 837 return ret_val 815 838 816 839 … … 824 847 # default selections. 825 848 def up(self): 826 return regfi.regfi_iterator_up(self._iter) 849 self._lock.acquire() 850 ret_val = regfi.regfi_iterator_up(self._iter) 851 self._lock.release() 852 return ret_val 827 853 828 854 … … 832 858 # None on error or if the current key has no subkeys. 833 859 def first_subkey(self): 860 ret_val = None 861 self._lock.acquire() 834 862 if regfi.regfi_iterator_first_subkey(self._iter): 835 return self.current_subkey() 836 return None 863 ret_val = self.current_subkey() 864 self._lock.release() 865 return ret_val 837 866 838 867 … … 842 871 # None on error or if the current key has no values. 843 872 def first_value(self): 873 ret_val = None 874 self._lock.acquire() 844 875 if regfi.regfi_iterator_first_value(self._iter): 845 return self.current_value() 846 return None 876 ret_val = self.current_value() 877 self._lock.release() 878 return ret_val 847 879 848 880 … … 852 884 # None if there are no remaining subkeys or an error occurred. 853 885 def next_subkey(self): 886 ret_val = None 887 self._lock.acquire() 854 888 if regfi.regfi_iterator_next_subkey(self._iter): 855 return self.current_subkey() 856 return None 889 ret_val = self.current_subkey() 890 self._lock.release() 891 return ret_val 857 892 858 893 … … 862 897 # None if there are no remaining values or an error occurred. 863 898 def next_value(self): 899 ret_val = None 900 self._lock.acquire() 864 901 if regfi.regfi_iterator_next_value(self._iter): 865 return self.current_value() 866 return None 902 ret_val = self.current_value() 903 self._lock.release() 904 return ret_val 867 905 868 906 … … 874 912 if name != None: 875 913 name = name.encode('utf-8') 914 ret_val = None 915 self._lock.acquire() 876 916 if regfi.regfi_iterator_find_subkey(self._iter, name): 877 return self.current_subkey() 878 return None 917 ret_val = self.current_subkey() 918 self._lock.release() 919 return ret_val 879 920 880 921 … … 886 927 if name != None: 887 928 name = name.encode('utf-8') 929 ret_val = None 930 self._lock.acquire() 888 931 if regfi.regfi_iterator_find_value(self._iter, name): 889 return self.current_value() 890 return None 932 ret_val = self.current_value() 933 self._lock.release() 934 return ret_val 891 935 892 936 ## Retrieves the currently selected subkey … … 894 938 # @return A Key instance of the current subkey 895 939 def current_subkey(self): 896 return Key(self._hive, regfi.regfi_iterator_cur_subkey(self._iter)) 940 self._lock.acquire() 941 ret_val = Key(self._hive, regfi.regfi_iterator_cur_subkey(self._iter)) 942 self._lock.release() 943 return ret_val 897 944 898 945 ## Retrieves the currently selected value … … 900 947 # @return A Value instance of the current value 901 948 def current_value(self): 902 return Value(self._hive, regfi.regfi_iterator_cur_value(self._iter)) 949 self._lock.acquire() 950 ret_val = Value(self._hive, regfi.regfi_iterator_cur_value(self._iter)) 951 self._lock.release() 952 return ret_val 903 953 904 954 ## Retrieves the current key … … 906 956 # @return A Key instance of the current position of the iterator 907 957 def current_key(self): 908 return Key(self._hive, regfi.regfi_iterator_cur_key(self._iter)) 958 self._lock.acquire() 959 ret_val = Key(self._hive, regfi.regfi_iterator_cur_key(self._iter)) 960 self._lock.release() 961 return ret_val 909 962 910 963 … … 919 972 cpath = _strlist2charss(path) 920 973 921 # XXX: Use non-generic exception 922 if not regfi.regfi_iterator_walk_path(self._iter, cpath): 974 self._lock.acquire() 975 result = regfi.regfi_iterator_walk_path(self._iter, cpath) 976 self._lock.release() 977 if not result: 978 # XXX: Use non-generic exception 923 979 raise Exception('Could not locate path.\n'+GetLogMessages()) 924 980 -
trunk/python/pyregfi/structures.py
r227 r228 171 171 REGFI_VALUE_LIST._fields_ = [('offset', c_uint32), 172 172 ('cell_size', c_uint32), 173 ('num_children', c_uint32),174 173 ('num_values', c_uint32), 175 174 ('elements', c_void_p), … … 247 246 regfi.regfi_get_rootkey.restype = POINTER(REGFI_NK) 248 247 249 regfi.regfi_free_record.argtypes = [ c_void_p]248 regfi.regfi_free_record.argtypes = [POINTER(REGFI_FILE), c_void_p] 250 249 regfi.regfi_free_record.restype = None 251 250 252 regfi.regfi_reference_record.argtypes = [ c_void_p]251 regfi.regfi_reference_record.argtypes = [POINTER(REGFI_FILE), c_void_p] 253 252 regfi.regfi_reference_record.restype = c_bool 254 253 … … 290 289 regfi.regfi_nt2unix_time.restype = c_double 291 290 292 regfi.regfi_iterator_new.argtypes = [POINTER(REGFI_FILE) , REGFI_ENCODING]291 regfi.regfi_iterator_new.argtypes = [POINTER(REGFI_FILE)] 293 292 regfi.regfi_iterator_new.restype = POINTER(REGFI_ITERATOR) 294 293 … … 305 304 regfi.regfi_iterator_to_root.restype = c_bool 306 305 307 regfi.regfi_iterator_walk_path.argtypes = [POINTER(REGFI_ITERATOR) ]306 regfi.regfi_iterator_walk_path.argtypes = [POINTER(REGFI_ITERATOR), POINTER(c_char_p)] 308 307 regfi.regfi_iterator_walk_path.restype = c_bool 309 308 -
trunk/src/reglookup-recover.c
r223 r228 291 291 { 292 292 /* XXX: Need to add a warning here */ 293 regfi_free_record( cur_ancestor);293 regfi_free_record(f, cur_ancestor); 294 294 void_stack_free(path_stack); 295 295 return NULL; … … 303 303 ret_val_size += path_element->len + 1; 304 304 305 regfi_free_record( cur_ancestor);305 regfi_free_record(f, cur_ancestor); 306 306 } 307 307 } … … 631 631 632 632 fail: 633 regfi_free_record( key);633 regfi_free_record(f, key); 634 634 return error_code; 635 635 } -
trunk/src/reglookup.c
r213 r228 95 95 fprintf(stderr, "WARN: While quoting value for '%s/%s', " 96 96 "warning returned: %s\n", prefix, quoted_name, conv_error); 97 regfi_free_record( data);97 regfi_free_record(iter->f, data); 98 98 } 99 99 … … 282 282 if(!type_filter_enabled || (value->type == type_filter)) 283 283 printValue(iter, value, prefix); 284 regfi_free_record( value);284 regfi_free_record(iter->f, value); 285 285 regfi_iterator_next_value(iter); 286 286 printMsgs(iter->f); … … 310 310 sacl = regfi_get_sacl(sk->sec_desc); 311 311 dacl = regfi_get_dacl(sk->sec_desc); 312 regfi_free_record( sk);312 regfi_free_record(iter->f, sk); 313 313 314 314 if(owner == NULL) … … 345 345 else 346 346 quoted_classname = empty_str; 347 regfi_free_record( classname);347 regfi_free_record(iter->f, classname); 348 348 349 349 printMsgs(iter->f); … … 365 365 printf("%s,KEY,,%s\n", full_path, mtime); 366 366 367 regfi_free_record( key);367 regfi_free_record(iter->f, key); 368 368 } 369 369 … … 406 406 if(cur != root) 407 407 { 408 regfi_free_record( cur);408 regfi_free_record(iter->f, cur); 409 409 /* We're done with this sub-tree, going up and hitting other branches. */ 410 410 if(!regfi_iterator_up(iter)) … … 430 430 * Let's move down and print this first sub-tree out. 431 431 */ 432 regfi_free_record( cur);432 regfi_free_record(iter->f, cur); 433 433 if(!regfi_iterator_down(iter)) 434 434 { … … 438 438 439 439 cur = regfi_iterator_cur_key(iter); 440 regfi_free_record( sub);440 regfi_free_record(iter->f, sub); 441 441 regfi_iterator_first_subkey(iter); 442 442 sub = regfi_iterator_cur_subkey(iter); … … 445 445 printMsgs(iter->f); 446 446 } while(!((cur == root) && (sub == NULL))); 447 regfi_free_record( root);447 regfi_free_record(iter->f, root); 448 448 449 449 if(print_verbose) … … 518 518 printValue(iter, value, tmp_path_joined); 519 519 520 regfi_free_record( value);520 regfi_free_record(iter->f, value); 521 521 free(tmp_path); 522 522 free(tmp_path_joined);
Note: See TracChangeset
for help on using the changeset viewer.