Changeset 182
- Timestamp:
- 03/17/10 02:41:17 (15 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/regfi.h
r180 r182 81 81 82 82 /* regfi library error message types */ 83 #define REGFI_MSG_INFO 0x0001 84 #define REGFI_MSG_WARN 0x0004 85 #define REGFI_MSG_ERROR 0x0010 83 #define REGFI_LOG_INFO 0x0001 84 #define REGFI_LOG_WARN 0x0004 85 #define REGFI_LOG_ERROR 0x0010 86 87 /* For internal use */ 88 pthread_key_t REGFI_LOG_KEY; 86 89 87 90 typedef uint8_t REGFI_ENCODING; … … 240 243 241 244 245 typedef struct _regfi_log 246 { 247 /* Error/warning/info messages returned by lower layer functions */ 248 char* messages; 249 250 /* Mask for error message types that will be stored. */ 251 uint16_t msg_mask; 252 253 } REGFI_LOG; 254 255 242 256 /** HBIN block information 243 257 * @ingroup regfiMiddleLayer … … 695 709 pthread_mutex_t* sk_lock; 696 710 697 /* Error/warning/info messages returned by lower layer functions */698 char* last_message;699 700 /* Mask for error message types that will be stored. */701 uint16_t msg_mask;702 703 704 711 /* Data parsed from file header */ 705 712 /********************************/ … … 849 856 850 857 858 /** Enables regfi library logging for the current thread. 859 * 860 * XXX: finish documenting 861 * 862 * @ingroup regfiBase 863 */ 864 void regfi_log_start(uint16_t mask); 865 866 851 867 /** Get errors, warnings, and/or verbose information relating to processing of 852 868 * the given registry file. 853 869 * 854 * @param file the structure for the registry file855 *856 870 * @return A newly allocated char* which must be free()d by the caller. 857 871 * 858 872 * @ingroup regfiBase 859 873 */ 860 char* regfi_get_messages(REGFI_FILE* file);874 char* regfi_log_get_str(); 861 875 862 876 … … 865 879 * 866 880 * This may be called at any time and will take effect immediately. 867 *868 * @param file the structure for the registry file869 881 * 870 882 * @param mask an integer representing the types of messages desired. … … 883 895 * @ingroup regfiBase 884 896 */ 885 void regfi_set_message_mask(REGFI_FILE* file, uint16_t mask); 897 void regfi_log_set_mask(uint16_t mask); 898 899 900 /** Disables regfi library logging for the current thread. 901 * 902 * XXX: finish documenting 903 * 904 * @ingroup regfiBase 905 */ 906 void regfi_log_stop(); 886 907 887 908 -
trunk/lib/regfi.c
r181 r182 45 45 46 46 47 47 48 /****************************************************************************** 48 49 ******************************************************************************/ 49 void regfi_add_message(REGFI_FILE* file, uint16_t msg_type, const char* fmt, ...) 50 { 51 /* XXX: This function is not particularly efficient, 52 * but then it is mostly used during errors. 50 void regfi_log_start(uint16_t msg_mask) 51 { 52 REGFI_LOG* log_info = talloc(NULL, REGFI_LOG); 53 if(log_info == NULL) 54 return; 55 56 log_info->msg_mask = msg_mask; 57 log_info->messages = NULL; 58 59 /* XXX: Should we bother with a destructor here? */ 60 if(pthread_key_create(®FI_LOG_KEY, NULL) != 0) 61 { 62 fprintf(stderr, "ERROR: key_create\n"); 63 goto fail; 64 } 65 66 if(pthread_setspecific(REGFI_LOG_KEY, log_info) != 0) 67 { 68 fprintf(stderr, "ERROR: setspecific\n"); 69 goto fail; 70 } 71 72 return; 73 74 fail: 75 talloc_free(log_info); 76 } 77 78 79 /****************************************************************************** 80 ******************************************************************************/ 81 void regfi_log_add(uint16_t msg_type, const char* fmt, ...) 82 { 83 /* XXX: Switch internal storage over to a linked list or stack. 84 * Then add a regfi_log_get function that returns the list in some 85 * convenient, user-friendly data structure. regfi_log_get_str should 86 * stick around and will simply smush the list into a big string when 87 * it's called, rather than having messages smushed when they're first 88 * written to the log. 53 89 */ 54 90 uint32_t buf_size, buf_used; 55 91 char* new_msg; 92 REGFI_LOG* log_info; 56 93 va_list args; 57 94 58 if((file->msg_mask & msg_type) != 0) 59 { 60 if(file->last_message == NULL) 61 buf_used = 0; 62 else 63 buf_used = strlen(file->last_message); 64 65 buf_size = buf_used+strlen(fmt)+160; 66 new_msg = realloc(file->last_message, buf_size); 67 if(new_msg == NULL) 68 /* XXX: should we report this? */ 69 return; 70 71 switch (msg_type) 72 { 73 case REGFI_MSG_INFO: 74 strcpy(new_msg+buf_used, "INFO: "); 75 buf_used += 6; 76 break; 77 case REGFI_MSG_WARN: 78 strcpy(new_msg+buf_used, "WARN: "); 79 buf_used += 6; 80 break; 81 case REGFI_MSG_ERROR: 82 strcpy(new_msg+buf_used, "ERROR: "); 83 buf_used += 7; 84 break; 85 } 86 87 va_start(args, fmt); 88 vsnprintf(new_msg+buf_used, buf_size-buf_used, fmt, args); 89 va_end(args); 90 strncat(new_msg, "\n", buf_size-1); 91 92 file->last_message = new_msg; 93 } 95 log_info = (REGFI_LOG*)pthread_getspecific(REGFI_LOG_KEY); 96 if(log_info == NULL || (log_info->msg_mask & msg_type) == 0) 97 return; 98 99 if(log_info->messages == NULL) 100 buf_used = 0; 101 else 102 buf_used = strlen(log_info->messages); 103 104 buf_size = buf_used+strlen(fmt)+160; 105 new_msg = realloc(log_info->messages, buf_size); 106 if(new_msg == NULL) 107 /* XXX: should we report this? */ 108 return; 109 110 switch (msg_type) 111 { 112 case REGFI_LOG_INFO: 113 strcpy(new_msg+buf_used, "INFO: "); 114 buf_used += 6; 115 break; 116 case REGFI_LOG_WARN: 117 strcpy(new_msg+buf_used, "WARN: "); 118 buf_used += 6; 119 break; 120 case REGFI_LOG_ERROR: 121 strcpy(new_msg+buf_used, "ERROR: "); 122 buf_used += 7; 123 break; 124 } 125 126 va_start(args, fmt); 127 vsnprintf(new_msg+buf_used, buf_size-buf_used, fmt, args); 128 va_end(args); 129 strncat(new_msg, "\n", buf_size-1); 130 131 log_info->messages = new_msg; 94 132 } 95 133 … … 97 135 /****************************************************************************** 98 136 ******************************************************************************/ 99 char* regfi_get_messages(REGFI_FILE* file) 100 { 101 char* ret_val = file->last_message; 102 file->last_message = NULL; 137 char* regfi_log_get_str() 138 { 139 char* ret_val; 140 REGFI_LOG* log_info = (REGFI_LOG*)pthread_getspecific(REGFI_LOG_KEY); 141 if(log_info == NULL) 142 return NULL; 143 144 ret_val = log_info->messages; 145 log_info->messages = NULL; 103 146 104 147 return ret_val; … … 106 149 107 150 108 void regfi_set_message_mask(REGFI_FILE* file, uint16_t mask) 109 { 110 file->msg_mask = mask; 151 /****************************************************************************** 152 ******************************************************************************/ 153 void regfi_log_set_mask(uint16_t msg_mask) 154 { 155 REGFI_LOG* log_info = (REGFI_LOG*)pthread_getspecific(REGFI_LOG_KEY); 156 if(log_info == NULL) 157 return; 158 159 log_info->msg_mask = msg_mask; 160 } 161 162 163 /****************************************************************************** 164 ******************************************************************************/ 165 void regfi_log_stop() 166 { 167 REGFI_LOG* log_info = (REGFI_LOG*)pthread_getspecific(REGFI_LOG_KEY); 168 if(log_info == NULL) 169 return; 170 171 if(log_info->messages != NULL) 172 free(log_info->messages); 173 174 pthread_key_delete(REGFI_LOG_KEY); 175 talloc_free(log_info); 111 176 } 112 177 … … 427 492 if(lock_ret != 0) 428 493 { 429 regfi_ add_message(file, REGFI_MSG_ERROR, "Error obtaining read lock in"494 regfi_log_add(REGFI_LOG_ERROR, "Error obtaining read lock in" 430 495 "%s due to: %s\n", context, strerror(lock_ret)); 431 496 return false; … … 441 506 if(lock_ret != 0) 442 507 { 443 regfi_ add_message(file, REGFI_MSG_ERROR, "Error obtaining write lock in"508 regfi_log_add(REGFI_LOG_ERROR, "Error obtaining write lock in" 444 509 "%s due to: %s\n", context, strerror(lock_ret)); 445 510 return false; … … 455 520 if(lock_ret != 0) 456 521 { 457 regfi_ add_message(file, REGFI_MSG_ERROR, "Error releasing lock in"522 regfi_log_add(REGFI_LOG_ERROR, "Error releasing lock in" 458 523 "%s due to: %s\n", context, strerror(lock_ret)); 459 524 return false; … … 469 534 if(lock_ret != 0) 470 535 { 471 regfi_ add_message(file, REGFI_MSG_ERROR, "Error obtaining mutex lock in"536 regfi_log_add(REGFI_LOG_ERROR, "Error obtaining mutex lock in" 472 537 "%s due to: %s\n", context, strerror(lock_ret)); 473 538 return false; … … 483 548 if(lock_ret != 0) 484 549 { 485 regfi_ add_message(file, REGFI_MSG_ERROR, "Error releasing mutex lock in"550 regfi_log_add(REGFI_LOG_ERROR, "Error releasing mutex lock in" 486 551 "%s due to: %s\n", context, strerror(lock_ret)); 487 552 return false; … … 644 709 if(ret_val == NULL) 645 710 { 646 regfi_ add_message(file, REGFI_MSG_WARN, "Failed to load subkey list at"711 regfi_log_add(REGFI_LOG_WARN, "Failed to load subkey list at" 647 712 " offset 0x%.8X.", offset); 648 713 return NULL; … … 655 720 * now if they don't match. 656 721 */ 657 regfi_ add_message(file, REGFI_MSG_WARN, "Number of subkeys listed in parent"722 regfi_log_add(REGFI_LOG_WARN, "Number of subkeys listed in parent" 658 723 " (%d) did not match number found in subkey list/tree (%d)" 659 724 " while parsing subkey list/tree at offset 0x%.8X.", … … 678 743 if(depth_left == 0) 679 744 { 680 regfi_ add_message(file, REGFI_MSG_WARN, "Maximum depth reached"745 regfi_log_add(REGFI_LOG_WARN, "Maximum depth reached" 681 746 " while parsing subkey list/tree at offset 0x%.8X.", 682 747 offset); … … 731 796 &cell_length, &unalloc)) 732 797 { 733 regfi_ add_message(file, REGFI_MSG_WARN, "Could not parse cell while "798 regfi_log_add(REGFI_LOG_WARN, "Could not parse cell while " 734 799 "parsing subkey-list at offset 0x%.8X.", offset); 735 800 goto fail_locked; … … 738 803 if(cell_length > max_size) 739 804 { 740 regfi_ add_message(file, REGFI_MSG_WARN, "Cell size longer than max_size"805 regfi_log_add(REGFI_LOG_WARN, "Cell size longer than max_size" 741 806 " while parsing subkey-list at offset 0x%.8X.", offset); 742 807 if(strict) … … 757 822 else 758 823 { 759 regfi_ add_message(file, REGFI_MSG_ERROR, "Unknown magic number"824 regfi_log_add(REGFI_LOG_ERROR, "Unknown magic number" 760 825 " (0x%.2X, 0x%.2X) encountered while parsing" 761 826 " subkey-list at offset 0x%.8X.", buf[0], buf[1], offset); … … 780 845 if(cell_length - REGFI_SUBKEY_LIST_MIN_LEN - sizeof(uint32_t) < length) 781 846 { 782 regfi_ add_message(file, REGFI_MSG_WARN, "Number of elements too large for"847 regfi_log_add(REGFI_LOG_WARN, "Number of elements too large for" 783 848 " cell while parsing subkey-list at offset 0x%.8X.", 784 849 offset); … … 907 972 &cell_length, &unalloc)) 908 973 { 909 regfi_ add_message(file, REGFI_MSG_WARN, "Could not parse SK record cell"974 regfi_log_add(REGFI_LOG_WARN, "Could not parse SK record cell" 910 975 " at offset 0x%.8X.", offset); 911 976 goto fail_locked; … … 914 979 if(sk_header[0] != 's' || sk_header[1] != 'k') 915 980 { 916 regfi_ add_message(file, REGFI_MSG_WARN, "Magic number mismatch in parsing"981 regfi_log_add(REGFI_LOG_WARN, "Magic number mismatch in parsing" 917 982 " SK record at offset 0x%.8X.", offset); 918 983 goto fail_locked; … … 934 999 || (strict && (ret_val->cell_size & 0x00000007) != 0)) 935 1000 { 936 regfi_ add_message(file, REGFI_MSG_WARN, "Invalid cell size found while"1001 regfi_log_add(REGFI_LOG_WARN, "Invalid cell size found while" 937 1002 " parsing SK record at offset 0x%.8X.", offset); 938 1003 goto fail_locked; … … 951 1016 || (ret_val->next_sk_off & 0x00000007) != 0) 952 1017 { 953 regfi_ add_message(file, REGFI_MSG_WARN, "SK record's next/previous offsets"1018 regfi_log_add(REGFI_LOG_WARN, "SK record's next/previous offsets" 954 1019 " are not a multiple of 8 while parsing SK record at" 955 1020 " offset 0x%.8X.", offset); … … 959 1024 if(ret_val->desc_size + REGFI_SK_MIN_LENGTH > ret_val->cell_size) 960 1025 { 961 regfi_ add_message(file, REGFI_MSG_WARN, "Security descriptor too large for"1026 regfi_log_add(REGFI_LOG_WARN, "Security descriptor too large for" 962 1027 " cell while parsing SK record at offset 0x%.8X.", 963 1028 offset); … … 973 1038 || length != ret_val->desc_size) 974 1039 { 975 regfi_ add_message(file, REGFI_MSG_ERROR, "Failed to read security"1040 regfi_log_add(REGFI_LOG_ERROR, "Failed to read security" 976 1041 " descriptor while parsing SK record at offset 0x%.8X.", 977 1042 offset); … … 985 1050 ret_val->desc_size))) 986 1051 { 987 regfi_ add_message(file, REGFI_MSG_ERROR, "Failed to parse security"1052 regfi_log_add(REGFI_LOG_ERROR, "Failed to parse security" 988 1053 " descriptor while parsing SK record at offset 0x%.8X.", 989 1054 offset); … … 1016 1081 if(!regfi_parse_cell(file->cb, offset, NULL, 0, &cell_length, &unalloc)) 1017 1082 { 1018 regfi_ add_message(file, REGFI_MSG_ERROR, "Failed to read cell header"1083 regfi_log_add(REGFI_LOG_ERROR, "Failed to read cell header" 1019 1084 " while parsing value list at offset 0x%.8X.", offset); 1020 1085 goto fail_locked; … … 1023 1088 if((cell_length & 0x00000007) != 0) 1024 1089 { 1025 regfi_ add_message(file, REGFI_MSG_WARN, "Cell length not a multiple of 8"1090 regfi_log_add(REGFI_LOG_WARN, "Cell length not a multiple of 8" 1026 1091 " while parsing value list at offset 0x%.8X.", offset); 1027 1092 if(strict) … … 1032 1097 if((num_values * sizeof(uint32_t)) > cell_length-sizeof(uint32_t)) 1033 1098 { 1034 regfi_ add_message(file, REGFI_MSG_WARN, "Too many values found"1099 regfi_log_add(REGFI_LOG_WARN, "Too many values found" 1035 1100 " while parsing value list at offset 0x%.8X.", offset); 1036 1101 if(strict) … … 1054 1119 || length != read_len) 1055 1120 { 1056 regfi_ add_message(file, REGFI_MSG_ERROR, "Failed to read value pointers"1121 regfi_log_add(REGFI_LOG_ERROR, "Failed to read value pointers" 1057 1122 " while parsing value list at offset 0x%.8X.", offset); 1058 1123 goto fail_locked; … … 1075 1140 || ((ret_val->elements[i] & 0x00000007) != 0)) 1076 1141 { 1077 regfi_ add_message(file, REGFI_MSG_WARN, "Invalid value pointer"1142 regfi_log_add(REGFI_LOG_WARN, "Invalid value pointer" 1078 1143 " (0x%.8X) found while parsing value list at offset" 1079 1144 " 0x%.8X.", ret_val->elements[i], offset); … … 1130 1195 if(tmp_size < 0) 1131 1196 { 1132 regfi_ add_message(file, REGFI_MSG_WARN, "Error occurred while converting"1197 regfi_log_add(REGFI_LOG_WARN, "Error occurred while converting" 1133 1198 " valuename to encoding %s. Error message: %s", 1134 1199 regfi_encoding_int2str(output_encoding), … … 1174 1239 if((num_values+1) * sizeof(uint32_t) > max_size) 1175 1240 { 1176 regfi_ add_message(file, REGFI_MSG_WARN, "Number of values indicated by"1241 regfi_log_add(REGFI_LOG_WARN, "Number of values indicated by" 1177 1242 " parent key (%d) would cause cell to straddle HBIN" 1178 1243 " boundary while loading value list at offset" … … 1224 1289 if(tmp_size < 0) 1225 1290 { 1226 regfi_ add_message(file, REGFI_MSG_WARN, "Error occurred while converting"1291 regfi_log_add(REGFI_LOG_WARN, "Error occurred while converting" 1227 1292 " keyname to encoding %s. Error message: %s", 1228 1293 regfi_encoding_int2str(output_encoding), … … 1252 1317 if((nk = regfi_parse_nk(file, offset, max_size, true)) == NULL) 1253 1318 { 1254 regfi_ add_message(file, REGFI_MSG_ERROR, "Could not load NK record at"1255 1319 regfi_log_add(REGFI_LOG_ERROR, "Could not load NK record at" 1320 " offset 0x%.8X.", offset); 1256 1321 return NULL; 1257 1322 } … … 1281 1346 if(nk->values == NULL) 1282 1347 { 1283 regfi_ add_message(file, REGFI_MSG_WARN, "Could not load value list"1284 1348 regfi_log_add(REGFI_LOG_WARN, "Could not load value list" 1349 " for NK record at offset 0x%.8X.", offset); 1285 1350 if(strict) 1286 1351 { … … 1315 1380 if(nk->subkeys == NULL) 1316 1381 { 1317 regfi_ add_message(file, REGFI_MSG_WARN, "Could not load subkey list"1318 1382 regfi_log_add(REGFI_LOG_WARN, "Could not load subkey list" 1383 " while parsing NK record at offset 0x%.8X.", offset); 1319 1384 nk->num_subkeys = 0; 1320 1385 } … … 1392 1457 if(!regfi_parse_cell(file->cb, cur_offset, NULL, 0, &cell_length, &unalloc)) 1393 1458 { 1394 regfi_ add_message(file, REGFI_MSG_WARN, "Could not parse cell at offset"1395 1459 regfi_log_add(REGFI_LOG_WARN, "Could not parse cell at offset" 1460 " 0x%.8X while searching for root key.", cur_offset); 1396 1461 return NULL; 1397 1462 } … … 1465 1530 file_length = file_cb->seek(file_cb, 0, SEEK_END); 1466 1531 if(file_length < REGFI_REGF_SIZE+REGFI_HBIN_ALLOC) 1467 return NULL; 1532 { 1533 regfi_log_add(REGFI_LOG_ERROR, "File length (%d) too short to contain a" 1534 " header and at least one HBIN.", file_length); 1535 return NULL; 1536 } 1468 1537 file_cb->seek(file_cb, 0, SEEK_SET); 1469 1538 1470 1539 /* Read file header */ 1471 if ((rb = regfi_parse_regf(file_cb, true)) == NULL)1472 { 1473 /* fprintf(stderr, "regfi_alloc_cb: Failed to read initial REGF block\n");*/1540 if ((rb = regfi_parse_regf(file_cb, false)) == NULL) 1541 { 1542 regfi_log_add(REGFI_LOG_ERROR, "Failed to read REGF block."); 1474 1543 return NULL; 1475 1544 } … … 1482 1551 rb->cb_lock = talloc(rb, pthread_mutex_t); 1483 1552 if(rb->cb_lock == NULL || pthread_mutex_init(rb->cb_lock, NULL) != 0) 1484 goto fail; 1553 { 1554 regfi_log_add(REGFI_LOG_ERROR, "Failed to create cb_lock mutex."); 1555 goto fail; 1556 } 1485 1557 1486 1558 rb->hbins_lock = talloc(rb, pthread_rwlock_t); 1487 1559 if(rb->hbins_lock == NULL || pthread_rwlock_init(rb->hbins_lock, NULL) != 0) 1488 goto fail; 1560 { 1561 regfi_log_add(REGFI_LOG_ERROR, "Failed to create hbins_lock rwlock."); 1562 goto fail; 1563 } 1489 1564 1490 1565 rb->sk_lock = talloc(rb, pthread_mutex_t); 1491 1566 if(rb->sk_lock == NULL || pthread_mutex_init(rb->sk_lock, NULL) != 0) 1492 goto fail; 1567 { 1568 regfi_log_add(REGFI_LOG_ERROR, "Failed to create sk_lock mutex."); 1569 goto fail; 1570 } 1493 1571 1494 1572 rb->hbins = range_list_new(); 1495 1573 if(rb->hbins == NULL) 1496 goto fail; 1574 { 1575 regfi_log_add(REGFI_LOG_ERROR, "Failed to create HBIN range_list."); 1576 goto fail; 1577 } 1497 1578 talloc_steal(rb, rb->hbins); 1498 1579 … … 1518 1599 /* Cache an unlimited number of SK records. Typically there are very few. */ 1519 1600 rb->sk_cache = lru_cache_create_ctx(rb, 0, cache_secret, true); 1520 1521 /* Default message mask */1522 rb->msg_mask = REGFI_MSG_ERROR|REGFI_MSG_WARN;1523 1601 1524 1602 /* success */ … … 1545 1623 void regfi_free(REGFI_FILE *file) 1546 1624 { 1547 if(file->last_message != NULL)1548 free(file->last_message);1549 1550 1625 pthread_mutex_destroy(file->cb_lock); 1551 1626 pthread_rwlock_destroy(file->hbins_lock); … … 1576 1651 } 1577 1652 1578 regfi_ add_message(file, REGFI_MSG_WARN, "File header indicated root key at"1579 1580 1653 regfi_log_add(REGFI_LOG_WARN, "File header indicated root key at" 1654 " location 0x%.8X, but no root key found." 1655 " Searching rest of file...", root_offset); 1581 1656 1582 1657 /* If the file header gives bad info, scan through the file one HBIN … … 1640 1715 && output_encoding != REGFI_ENCODING_ASCII) 1641 1716 { 1642 regfi_ add_message(file, REGFI_MSG_ERROR, "Invalid output_encoding supplied"1643 1717 regfi_log_add(REGFI_LOG_ERROR, "Invalid output_encoding supplied" 1718 " in creation of regfi iterator."); 1644 1719 return NULL; 1645 1720 } … … 1984 2059 if(raw == NULL) 1985 2060 { 1986 regfi_ add_message(i->f, REGFI_MSG_WARN, "Could not parse class"1987 1988 2061 regfi_log_add(REGFI_LOG_WARN, "Could not parse class" 2062 " name at offset 0x%.8X for key record at offset 0x%.8X.", 2063 offset, key->offset); 1989 2064 return NULL; 1990 2065 } … … 2006 2081 if(conv_size < 0) 2007 2082 { 2008 regfi_ add_message(i->f, REGFI_MSG_WARN, "Error occurred while"2009 2010 2083 regfi_log_add(REGFI_LOG_WARN, "Error occurred while" 2084 " converting classname to charset %s. Error message: %s", 2085 i->string_encoding, strerror(-conv_size)); 2011 2086 talloc_free(interpreted); 2012 2087 ret_val->interpreted = NULL; … … 2037 2112 if(raw_data.buf == NULL) 2038 2113 { 2039 regfi_ add_message(i->f, REGFI_MSG_WARN, "Could not parse data record"2040 2041 2114 regfi_log_add(REGFI_LOG_WARN, "Could not parse data record" 2115 " while parsing VK record at offset 0x%.8X.", 2116 value->offset); 2042 2117 } 2043 2118 else … … 2047 2122 if(ret_val == NULL) 2048 2123 { 2049 regfi_ add_message(i->f, REGFI_MSG_WARN, "Error occurred in converting"2050 2051 2052 2124 regfi_log_add(REGFI_LOG_WARN, "Error occurred in converting" 2125 " data buffer to data structure while interpreting " 2126 "data for VK record at offset 0x%.8X.", 2127 value->offset); 2053 2128 talloc_free(raw_data.buf); 2054 2129 return NULL; … … 2057 2132 if(!regfi_interpret_data(i->f, i->string_encoding, value->type, ret_val)) 2058 2133 { 2059 regfi_ add_message(i->f, REGFI_MSG_INFO, "Error occurred while"2060 2061 2134 regfi_log_add(REGFI_LOG_INFO, "Error occurred while" 2135 " interpreting data for VK record at offset 0x%.8X.", 2136 value->offset); 2062 2137 } 2063 2138 } … … 2139 2214 if(tmp_size < 0) 2140 2215 { 2141 regfi_ add_message(file, REGFI_MSG_INFO, "Error occurred while"2142 2143 2216 regfi_log_add(REGFI_LOG_INFO, "Error occurred while" 2217 " converting data of type %d to %s. Error message: %s", 2218 type, string_encoding, strerror(-tmp_size)); 2144 2219 talloc_free(tmp_str); 2145 2220 data->interpreted.string = NULL; … … 2206 2281 if(tmp_size < 0) 2207 2282 { 2208 regfi_ add_message(file, REGFI_MSG_INFO, "Error occurred while"2209 2210 2283 regfi_log_add(REGFI_LOG_INFO, "Error occurred while" 2284 " converting data of type %d to %s. Error message: %s", 2285 type, string_encoding, strerror(-tmp_size)); 2211 2286 talloc_free(tmp_str); 2212 2287 data->interpreted.multiple_string = NULL; … … 2337 2412 2338 2413 /******************************************************************* 2339 * XXX: Add way to return more detailed error information.2340 2414 *******************************************************************/ 2341 2415 REGFI_FILE* regfi_parse_regf(REGFI_RAW_FILE* file_cb, bool strict) … … 2350 2424 2351 2425 ret_val->sk_cache = NULL; 2352 ret_val->last_message = NULL;2353 2426 ret_val->hbins = NULL; 2354 2427 … … 2356 2429 if((regfi_read(file_cb, file_header, &length)) != 0 2357 2430 || length != REGFI_REGF_SIZE) 2358 goto fail; 2359 2431 { 2432 regfi_log_add(REGFI_LOG_WARN, "Read failed while parsing REGF structure."); 2433 goto fail; 2434 } 2435 2360 2436 ret_val->checksum = IVAL(file_header, 0x1FC); 2361 2437 ret_val->computed_checksum = regfi_compute_header_checksum(file_header); 2362 2438 if (strict && (ret_val->checksum != ret_val->computed_checksum)) 2363 goto fail; 2439 { 2440 regfi_log_add(REGFI_LOG_WARN, "Stored header checksum (%.8X) did not equal" 2441 " computed checksum (%.8X).", 2442 ret_val->checksum, ret_val->computed_checksum); 2443 if(strict) 2444 goto fail; 2445 } 2364 2446 2365 2447 memcpy(ret_val->magic, file_header, REGFI_REGF_MAGIC_SIZE); 2366 2448 if(memcmp(ret_val->magic, "regf", REGFI_REGF_MAGIC_SIZE) != 0) 2367 2449 { 2368 if(strict) 2369 goto fail; 2370 regfi_add_message(ret_val, REGFI_MSG_WARN, "Magic number mismatch " 2371 "(%.2X %.2X %.2X %.2X) while parsing hive header", 2372 ret_val->magic[0], ret_val->magic[1], 2373 ret_val->magic[2], ret_val->magic[3]); 2450 regfi_log_add(REGFI_LOG_ERROR, "Magic number mismatch " 2451 "(%.2X %.2X %.2X %.2X) while parsing hive header", 2452 ret_val->magic[0], ret_val->magic[1], 2453 ret_val->magic[2], ret_val->magic[3]); 2454 goto fail; 2374 2455 } 2375 2456 … … 2384 2465 ret_val->root_cell = IVAL(file_header, 0x24); 2385 2466 ret_val->last_block = IVAL(file_header, 0x28); 2386 2387 2467 ret_val->cluster = IVAL(file_header, 0x2C); 2388 2468 … … 2432 2512 if(regfi_seek(file->cb, offset, SEEK_SET) == -1) 2433 2513 { 2434 regfi_ add_message(file, REGFI_MSG_ERROR, "Seek failed"2435 2514 regfi_log_add(REGFI_LOG_ERROR, "Seek failed" 2515 " while parsing hbin at offset 0x%.8X.", offset); 2436 2516 goto fail_locked; 2437 2517 } … … 2440 2520 if((regfi_read(file->cb, hbin_header, &length) != 0) 2441 2521 || length != REGFI_HBIN_HEADER_SIZE) 2522 { 2523 regfi_log_add(REGFI_LOG_ERROR, "Read failed" 2524 " while parsing hbin at offset 0x%.8X.", offset); 2442 2525 goto fail_locked; 2526 } 2443 2527 2444 2528 if(!regfi_unlock(file, file->cb_lock, "regfi_parse_hbin")) … … 2453 2537 if(strict && (memcmp(hbin->magic, "hbin", 4) != 0)) 2454 2538 { 2455 regfi_add_message(file, REGFI_MSG_INFO, "Magic number mismatch " 2456 "(%.2X %.2X %.2X %.2X) while parsing hbin at offset" 2457 " 0x%.8X.", hbin->magic[0], hbin->magic[1], 2458 hbin->magic[2], hbin->magic[3], offset); 2539 /* This always seems to happen at the end of a file, so we make it an INFO 2540 * message, rather than something more serious. 2541 */ 2542 regfi_log_add(REGFI_LOG_INFO, "Magic number mismatch " 2543 "(%.2X %.2X %.2X %.2X) while parsing hbin at offset" 2544 " 0x%.8X.", hbin->magic[0], hbin->magic[1], 2545 hbin->magic[2], hbin->magic[3], offset); 2459 2546 goto fail; 2460 2547 } … … 2462 2549 hbin->first_hbin_off = IVAL(hbin_header, 0x4); 2463 2550 hbin->block_size = IVAL(hbin_header, 0x8); 2464 /* this should be the same thing as hbin->block_size but just in case */2551 /* this should be the same thing as hbin->block_size, but just in case */ 2465 2552 hbin->next_block = IVAL(hbin_header, 0x1C); 2466 2553 … … 2475 2562 || (hbin->block_size & 0xFFFFF000) != hbin->block_size) 2476 2563 { 2477 regfi_ add_message(file, REGFI_MSG_ERROR, "The hbin offset is not aligned"2478 2479 2564 regfi_log_add(REGFI_LOG_ERROR, "The hbin offset is not aligned" 2565 " or runs off the end of the file" 2566 " while parsing hbin at offset 0x%.8X.", offset); 2480 2567 goto fail; 2481 2568 } … … 2504 2591 if(ret_val == NULL) 2505 2592 { 2506 regfi_ add_message(file, REGFI_MSG_ERROR, "Failed to allocate memory while"2507 2593 regfi_log_add(REGFI_LOG_ERROR, "Failed to allocate memory while" 2594 " parsing NK record at offset 0x%.8X.", offset); 2508 2595 goto fail; 2509 2596 } … … 2515 2602 &cell_length, &unalloc)) 2516 2603 { 2517 regfi_ add_message(file, REGFI_MSG_WARN, "Could not parse cell header"2518 2604 regfi_log_add(REGFI_LOG_WARN, "Could not parse cell header" 2605 " while parsing NK record at offset 0x%.8X.", offset); 2519 2606 goto fail_locked; 2520 2607 } … … 2522 2609 if((nk_header[0x0] != 'n') || (nk_header[0x1] != 'k')) 2523 2610 { 2524 regfi_ add_message(file, REGFI_MSG_WARN, "Magic number mismatch in parsing"2525 2611 regfi_log_add(REGFI_LOG_WARN, "Magic number mismatch in parsing" 2612 " NK record at offset 0x%.8X.", offset); 2526 2613 goto fail_locked; 2527 2614 } … … 2537 2624 || (strict && (ret_val->cell_size & 0x00000007) != 0)) 2538 2625 { 2539 regfi_ add_message(file, REGFI_MSG_WARN, "A length check failed while"2540 2626 regfi_log_add(REGFI_LOG_WARN, "A length check failed while" 2627 " parsing NK record at offset 0x%.8X.", offset); 2541 2628 goto fail_locked; 2542 2629 } … … 2548 2635 if((ret_val->flags & ~REGFI_NK_KNOWN_FLAGS) != 0) 2549 2636 { 2550 regfi_ add_message(file, REGFI_MSG_WARN, "Unknown key flags (0x%.4X) while"2551 2552 2637 regfi_log_add(REGFI_LOG_WARN, "Unknown key flags (0x%.4X) while" 2638 " parsing NK record at offset 0x%.8X.", 2639 (ret_val->flags & ~REGFI_NK_KNOWN_FLAGS), offset); 2553 2640 } 2554 2641 … … 2589 2676 if(strict) 2590 2677 { 2591 regfi_ add_message(file, REGFI_MSG_ERROR, "Contents too large for cell"2592 2678 regfi_log_add(REGFI_LOG_ERROR, "Contents too large for cell" 2679 " while parsing NK record at offset 0x%.8X.", offset); 2593 2680 goto fail_locked; 2594 2681 } … … 2617 2704 || length != ret_val->name_length) 2618 2705 { 2619 regfi_ add_message(file, REGFI_MSG_ERROR, "Failed to read key name"2620 2706 regfi_log_add(REGFI_LOG_ERROR, "Failed to read key name" 2707 " while parsing NK record at offset 0x%.8X.", offset); 2621 2708 goto fail_locked; 2622 2709 } … … 2652 2739 if(!regfi_parse_cell(file->cb, offset, NULL, 0, &cell_length, &unalloc)) 2653 2740 { 2654 regfi_ add_message(file, REGFI_MSG_WARN, "Could not parse cell header"2655 2741 regfi_log_add(REGFI_LOG_WARN, "Could not parse cell header" 2742 " while parsing class name at offset 0x%.8X.", offset); 2656 2743 goto fail_locked; 2657 2744 } … … 2659 2746 if((cell_length & 0x0000007) != 0) 2660 2747 { 2661 regfi_ add_message(file, REGFI_MSG_ERROR, "Cell length not a multiple of 8"2662 2748 regfi_log_add(REGFI_LOG_ERROR, "Cell length not a multiple of 8" 2749 " while parsing class name at offset 0x%.8X.", offset); 2663 2750 goto fail_locked; 2664 2751 } … … 2666 2753 if(cell_length > max_size) 2667 2754 { 2668 regfi_ add_message(file, REGFI_MSG_WARN, "Cell stretches past hbin "2669 2670 2755 regfi_log_add(REGFI_LOG_WARN, "Cell stretches past hbin " 2756 "boundary while parsing class name at offset 0x%.8X.", 2757 offset); 2671 2758 if(strict) 2672 2759 goto fail_locked; … … 2676 2763 if((cell_length - 4) < *name_length) 2677 2764 { 2678 regfi_ add_message(file, REGFI_MSG_WARN, "Class name is larger than"2679 2680 2765 regfi_log_add(REGFI_LOG_WARN, "Class name is larger than" 2766 " cell_length while parsing class name at offset" 2767 " 0x%.8X.", offset); 2681 2768 if(strict) 2682 2769 goto fail_locked; … … 2691 2778 || length != *name_length) 2692 2779 { 2693 regfi_ add_message(file, REGFI_MSG_ERROR, "Could not read class name"2694 2780 regfi_log_add(REGFI_LOG_ERROR, "Could not read class name" 2781 " while parsing class name at offset 0x%.8X.", offset); 2695 2782 goto fail_locked; 2696 2783 } … … 2730 2817 &cell_length, &unalloc)) 2731 2818 { 2732 regfi_ add_message(file, REGFI_MSG_WARN, "Could not parse cell header"2733 2819 regfi_log_add(REGFI_LOG_WARN, "Could not parse cell header" 2820 " while parsing VK record at offset 0x%.8X.", offset); 2734 2821 goto fail_locked; 2735 2822 } … … 2745 2832 || (ret_val->cell_size & 0x00000007) != 0) 2746 2833 { 2747 regfi_ add_message(file, REGFI_MSG_WARN, "Invalid cell size encountered"2748 2834 regfi_log_add(REGFI_LOG_WARN, "Invalid cell size encountered" 2835 " while parsing VK record at offset 0x%.8X.", offset); 2749 2836 goto fail_locked; 2750 2837 } … … 2758 2845 * 0xFFFF. 2759 2846 */ 2760 regfi_ add_message(file, REGFI_MSG_WARN, "Magic number mismatch"2761 2847 regfi_log_add(REGFI_LOG_WARN, "Magic number mismatch" 2848 " while parsing VK record at offset 0x%.8X.", offset); 2762 2849 goto fail_locked; 2763 2850 } … … 2779 2866 if(ret_val->name_length + REGFI_VK_MIN_LENGTH + 4 > ret_val->cell_size) 2780 2867 { 2781 regfi_ add_message(file, REGFI_MSG_WARN, "Name too long for remaining cell"2782 2783 2868 regfi_log_add(REGFI_LOG_WARN, "Name too long for remaining cell" 2869 " space while parsing VK record at offset 0x%.8X.", 2870 offset); 2784 2871 if(strict) 2785 2872 goto fail_locked; … … 2801 2888 || length != ret_val->name_length) 2802 2889 { 2803 regfi_ add_message(file, REGFI_MSG_ERROR, "Could not read value name"2804 2890 regfi_log_add(REGFI_LOG_ERROR, "Could not read value name" 2891 " while parsing VK record at offset 0x%.8X.", offset); 2805 2892 goto fail_locked; 2806 2893 } … … 2856 2943 if(length > REGFI_VK_MAX_DATA_LENGTH) 2857 2944 { 2858 regfi_ add_message(file, REGFI_MSG_WARN, "Value data size %d larger than "2859 2945 regfi_log_add(REGFI_LOG_WARN, "Value data size %d larger than " 2946 "%d, truncating...", length, REGFI_VK_MAX_DATA_LENGTH); 2860 2947 length = REGFI_VK_MAX_DATA_LENGTH; 2861 2948 } … … 2869 2956 if(max_size < 0) 2870 2957 { 2871 regfi_ add_message(file, REGFI_MSG_WARN, "Could not find HBIN for data"2872 2958 regfi_log_add(REGFI_LOG_WARN, "Could not find HBIN for data" 2959 " at offset 0x%.8X.", offset); 2873 2960 goto fail; 2874 2961 } … … 2880 2967 &cell_length, &unalloc)) 2881 2968 { 2882 regfi_ add_message(file, REGFI_MSG_WARN, "Could not parse cell while"2883 2969 regfi_log_add(REGFI_LOG_WARN, "Could not parse cell while" 2970 " parsing data record at offset 0x%.8X.", offset); 2884 2971 goto fail_locked; 2885 2972 } … … 2890 2977 if((cell_length & 0x00000007) != 0) 2891 2978 { 2892 regfi_ add_message(file, REGFI_MSG_WARN, "Cell length not multiple of 8"2893 2894 2979 regfi_log_add(REGFI_LOG_WARN, "Cell length not multiple of 8" 2980 " while parsing data record at offset 0x%.8X.", 2981 offset); 2895 2982 goto fail; 2896 2983 } … … 2898 2985 if(cell_length > max_size) 2899 2986 { 2900 regfi_ add_message(file, REGFI_MSG_WARN, "Cell extends past HBIN boundary"2901 2902 2987 regfi_log_add(REGFI_LOG_WARN, "Cell extends past HBIN boundary" 2988 " while parsing data record at offset 0x%.8X.", 2989 offset); 2903 2990 goto fail; 2904 2991 } … … 2918 3005 else 2919 3006 { 2920 regfi_ add_message(file, REGFI_MSG_WARN, "Data length (0x%.8X) larger than"2921 2922 2923 3007 regfi_log_add(REGFI_LOG_WARN, "Data length (0x%.8X) larger than" 3008 " remaining cell length (0x%.8X)" 3009 " while parsing data record at offset 0x%.8X.", 3010 length, cell_length - 4, offset); 2924 3011 if(strict) 2925 3012 goto fail; … … 2964 3051 if(regfi_seek(file->cb, offset+4, SEEK_SET) == -1) 2965 3052 { 2966 regfi_ add_message(file, REGFI_MSG_WARN, "Could not seek while "2967 3053 regfi_log_add(REGFI_LOG_WARN, "Could not seek while " 3054 "reading data at offset 0x%.8X.", offset); 2968 3055 goto fail_locked; 2969 3056 } … … 2973 3060 || read_length != length) 2974 3061 { 2975 regfi_ add_message(file, REGFI_MSG_ERROR, "Could not read data block while"2976 3062 regfi_log_add(REGFI_LOG_ERROR, "Could not read data block while" 3063 " parsing data record at offset 0x%.8X.", offset); 2977 3064 goto fail_locked; 2978 3065 } … … 3008 3095 if(length > 4) 3009 3096 { 3010 regfi_ add_message(file, REGFI_MSG_ERROR, "Data in offset but length > 4"3011 3012 3097 regfi_log_add(REGFI_LOG_ERROR, "Data in offset but length > 4" 3098 " while parsing data record. (voffset=0x%.8X, length=%d)", 3099 voffset, length); 3013 3100 return ret_val; 3014 3101 } … … 3040 3127 if(REGFI_BIG_DATA_MIN_LENGTH > max_size) 3041 3128 { 3042 regfi_ add_message(file, REGFI_MSG_WARN, "Big data header exceeded max_size "3043 3129 regfi_log_add(REGFI_LOG_WARN, "Big data header exceeded max_size " 3130 "while parsing big data header at offset 0x%.8X.",offset); 3044 3131 goto fail; 3045 3132 } … … 3052 3139 &cell_length, &unalloc)) 3053 3140 { 3054 regfi_ add_message(file, REGFI_MSG_WARN, "Could not parse cell while"3055 3141 regfi_log_add(REGFI_LOG_WARN, "Could not parse cell while" 3142 " parsing big data header at offset 0x%.8X.", offset); 3056 3143 goto fail_locked; 3057 3144 } … … 3062 3149 if((ret_val.buf[0] != 'd') || (ret_val.buf[1] != 'b')) 3063 3150 { 3064 regfi_ add_message(file, REGFI_MSG_WARN, "Unknown magic number"3065 3066 3067 3151 regfi_log_add(REGFI_LOG_WARN, "Unknown magic number" 3152 " (0x%.2X, 0x%.2X) encountered while parsing" 3153 " big data header at offset 0x%.8X.", 3154 ret_val.buf[0], ret_val.buf[1], offset); 3068 3155 goto fail; 3069 3156 } … … 3112 3199 &indirect_length, &unalloc)) 3113 3200 { 3114 regfi_ add_message(file, REGFI_MSG_WARN, "Could not parse cell while"3115 3116 3201 regfi_log_add(REGFI_LOG_WARN, "Could not parse cell while" 3202 " parsing big data indirect record at offset 0x%.8X.", 3203 offset); 3117 3204 goto fail_locked; 3118 3205 } … … 3173 3260 &cell_length, &unalloc)) 3174 3261 { 3175 regfi_ add_message(file, REGFI_MSG_WARN, "Could not parse cell while"3176 3177 3262 regfi_log_add(REGFI_LOG_WARN, "Could not parse cell while" 3263 " parsing big data chunk at offset 0x%.8X.", 3264 chunk_offset); 3178 3265 goto fail_locked; 3179 3266 } … … 3265 3352 if(i+1 != num_chunks) 3266 3353 { 3267 regfi_ add_message(file, REGFI_MSG_WARN, "Left over chunks detected "3268 3269 3354 regfi_log_add(REGFI_LOG_WARN, "Left over chunks detected " 3355 "while constructing big data at offset 0x%.8X " 3356 "(chunk offset 0x%.8X).", offset, cell_info->offset); 3270 3357 } 3271 3358 read_length = data_left; … … 3277 3364 if(read_length > regfi_calc_maxsize(file, cell_info->offset)) 3278 3365 { 3279 regfi_ add_message(file, REGFI_MSG_WARN, "A chunk exceeded the maxsize "3280 3281 3366 regfi_log_add(REGFI_LOG_WARN, "A chunk exceeded the maxsize " 3367 "while constructing big data at offset 0x%.8X " 3368 "(chunk offset 0x%.8X).", offset, cell_info->offset); 3282 3369 goto fail; 3283 3370 } … … 3288 3375 if(regfi_seek(file->cb, cell_info->offset+sizeof(uint32_t), SEEK_SET) == -1) 3289 3376 { 3290 regfi_ add_message(file, REGFI_MSG_WARN, "Could not seek to chunk while "3291 3292 3377 regfi_log_add(REGFI_LOG_WARN, "Could not seek to chunk while " 3378 "constructing big data at offset 0x%.8X " 3379 "(chunk offset 0x%.8X).", offset, cell_info->offset); 3293 3380 goto fail_locked; 3294 3381 } … … 3298 3385 &read_length) != 0 || (read_length != tmp_len)) 3299 3386 { 3300 regfi_ add_message(file, REGFI_MSG_WARN, "Could not read data chunk while"3301 3302 3387 regfi_log_add(REGFI_LOG_WARN, "Could not read data chunk while" 3388 " constructing big data at offset 0x%.8X" 3389 " (chunk offset 0x%.8X).", offset, cell_info->offset); 3303 3390 goto fail_locked; 3304 3391 } … … 3375 3462 if((cell_len == 0) || ((cell_len & 0x00000007) != 0)) 3376 3463 { 3377 regfi_ add_message(file, REGFI_MSG_ERROR, "Bad cell length encountered"3378 3379 3464 regfi_log_add(REGFI_LOG_ERROR, "Bad cell length encountered" 3465 " while parsing unallocated cells at offset 0x%.8X.", 3466 hbin->file_off+curr_off); 3380 3467 break; 3381 3468 } -
trunk/src/common.c
r178 r182 29 29 const char* common_special_chars = ",\"\\"; 30 30 31 #define REGLOOKUP_VERSION "0.1 2.0"31 #define REGLOOKUP_VERSION "0.1?.0" 32 32 33 33 #define REGLOOKUP_EXIT_OK 0 … … 49 49 { 50 50 fprintf(stderr, message); 51 regfi_log_stop(); 51 52 exit(code); 52 53 } 53 54 54 void printMsgs( REGFI_FILE* f)55 { 56 char* msgs = regfi_ get_messages(f);55 void printMsgs() 56 { 57 char* msgs = regfi_log_get_str(); 57 58 if(msgs != NULL) 58 59 { … … 62 63 } 63 64 64 void clearMsgs( REGFI_FILE* f)65 { 66 char* msgs = regfi_ get_messages(f);65 void clearMsgs() 66 { 67 char* msgs = regfi_log_get_str(); 67 68 if(msgs != NULL) 68 69 free(msgs); -
trunk/src/reglookup-recover.c
r181 r182 827 827 } 828 828 829 if(print_verbose) 830 regfi_log_start(REGFI_LOG_ERROR|REGFI_LOG_WARN|REGFI_LOG_INFO); 831 else 832 regfi_log_start(REGFI_LOG_ERROR); 833 829 834 f = regfi_alloc(fd); 830 835 if(f == NULL) … … 833 838 bailOut(REGLOOKUP_EXIT_NOINPUT, "ERROR: Failed to create REGFI_FILE structure.\n"); 834 839 } 835 836 if(print_verbose)837 regfi_set_message_mask(f, REGFI_MSG_ERROR|REGFI_MSG_WARN|REGFI_MSG_INFO);838 else839 regfi_set_message_mask(f, REGFI_MSG_ERROR);840 840 841 841 if(print_header) … … 994 994 995 995 regfi_free(f); 996 regfi_log_stop(); 996 997 close(fd); 997 998 -
trunk/src/reglookup.c
r181 r182 619 619 registry_file = argv[argi]; 620 620 621 if(print_verbose) 622 regfi_log_start(REGFI_LOG_INFO|REGFI_LOG_WARN|REGFI_LOG_ERROR); 623 else 624 regfi_log_start(REGFI_LOG_ERROR|REGFI_LOG_WARN); 625 621 626 fd = openHive(registry_file); 622 627 if(fd < 0) … … 625 630 bailOut(REGLOOKUP_EXIT_NOINPUT, ""); 626 631 } 627 632 628 633 f = regfi_alloc(fd); 629 634 if(f == NULL) … … 633 638 } 634 639 635 if(print_verbose)636 regfi_set_message_mask(f, REGFI_MSG_INFO|REGFI_MSG_WARN|REGFI_MSG_ERROR);637 640 638 641 /* XXX: add command line option to choose output encoding */ … … 678 681 regfi_iterator_free(iter); 679 682 regfi_free(f); 683 regfi_log_stop(); 680 684 close(fd); 681 685
Note: See TracChangeset
for help on using the changeset viewer.