Changeset 146 for trunk


Ignore:
Timestamp:
02/18/09 23:46:37 (15 years ago)
Author:
tim
Message:

reorganized SK caching
refined interface to HBIN functions

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/regfi.h

    r145 r146  
    158158
    159159
    160 
    161160/* HBIN block */
    162161typedef struct _regfi_hbin
     
    258257  WINSEC_DESC* sec_desc;
    259258  uint32 hbin_off;      /* offset from beginning of this hbin block */
    260  
    261   uint32 sk_off;        /* offset parsed from NK record used as a key
    262                          * to lookup reference to this SK record
    263                          */
    264259 
    265260  uint32 prev_sk_off;
     
    330325  /* Metadata about hbins */
    331326  range_list* hbins;
     327
     328  /* SK record cached since they're repeatedly reused */
     329  lru_cache* sk_cache;
    332330
    333331  /* Error/warning/info messages returned by lower layer functions */
     
    375373  REGFI_FILE* f;
    376374  void_stack* key_positions;
    377   lru_cache* sk_recs;
    378375  REGFI_NK_REC* cur_key;
    379376  uint32 cur_subkey;
     
    384381typedef struct
    385382{
    386   /* XXX: Should probably eliminate the storage of keys here
    387    *      once key caching is implemented.
    388    */
    389383  REGFI_NK_REC* nk;
    390384  uint32 cur_subkey;
     
    437431
    438432/********************************************************/
    439 /* Middle-layer structure caching, loading, and linking */
     433/* Middle-layer structure loading, linking, and caching */
    440434/********************************************************/
    441 REGFI_HBIN*           regfi_lookup_hbin(REGFI_FILE* file, uint32 voffset);
    442435REGFI_NK_REC*         regfi_load_key(REGFI_FILE* file, uint32 offset,
    443436                                     bool strict);
    444 REGFI_SUBKEY_LIST*    regfi_load_subkeylist(REGFI_FILE* file, uint32 offset,
    445                                             uint32 num_keys, uint32 max_size,
    446                                             bool strict);
    447437REGFI_VK_REC*         regfi_load_value(REGFI_FILE* file, uint32 offset,
    448438                                       bool strict);
     439REGFI_SUBKEY_LIST*    regfi_load_subkeylist(REGFI_FILE* file, uint32 offset,
     440                                            uint32 num_keys, uint32 max_size,
     441                                            bool strict);
    449442REGFI_VALUE_LIST*     regfi_load_valuelist(REGFI_FILE* file, uint32 offset,
    450                                            uint32 num_values, uint32 max_size, 
     443                                           uint32 num_values, uint32 max_size,
    451444                                           bool strict);
     445
     446/* These are cached so return values don't need to be freed. */
     447const REGFI_SK_REC*   regfi_load_sk(REGFI_FILE* file, uint32 offset,
     448                                    bool strict);
     449const REGFI_HBIN*     regfi_lookup_hbin(REGFI_FILE* file, uint32 voffset);
     450
     451
    452452
    453453/************************************/
     
    522522void                  regfi_add_message(REGFI_FILE* file, uint16 msg_type,
    523523                                        const char* fmt, ...);
     524REGFI_NK_REC*         regfi_copy_nk(const REGFI_NK_REC* nk);
     525REGFI_VK_REC*         regfi_copy_vk(const REGFI_VK_REC* vk);
     526
    524527#endif  /* _REGFI_H */
  • trunk/lib/lru_cache.c

    r136 r146  
    106106
    107107  if(max_keys == 0)
    108     ret_val->num_buckets = 2048;
     108    ret_val->num_buckets = 1024;
    109109  else
    110110  {
  • trunk/lib/regfi.c

    r145 r146  
    475475 * The offset is a virtual file offset.
    476476 *******************************************************************/
    477 static bool regfi_offset_in_hbin(REGFI_HBIN* hbin, uint32 voffset)
     477static bool regfi_offset_in_hbin(const REGFI_HBIN* hbin, uint32 voffset)
    478478{
    479479  if(!hbin)
     
    493493 * block for it.  NULL if one doesn't exist.
    494494 *******************************************************************/
    495 REGFI_HBIN* regfi_lookup_hbin(REGFI_FILE* file, uint32 voffset)
    496 {
    497   return (REGFI_HBIN*)range_list_find_data(file->hbins, voffset+REGFI_REGF_SIZE);
     495const REGFI_HBIN* regfi_lookup_hbin(REGFI_FILE* file, uint32 voffset)
     496{
     497  return (const REGFI_HBIN*)range_list_find_data(file->hbins,
     498                                                 voffset+REGFI_REGF_SIZE);
    498499}
    499500
     
    541542  REGFI_SUBKEY_LIST* ret_val;
    542543  REGFI_SUBKEY_LIST** sublists;
    543   REGFI_HBIN* sublist_hbin;
     544  const REGFI_HBIN* sublist_hbin;
    544545  uint32 i, num_sublists, off, max_length;
    545546
     
    956957/******************************************************************************
    957958 ******************************************************************************/
    958 REGFI_VK_REC* regfi_load_value(REGFI_FILE* file, uint32 offset, bool strict)
     959REGFI_VK_REC* regfi_load_value(REGFI_FILE* file, uint32 offset,
     960                               bool strict)
    959961{
    960962  REGFI_VK_REC* ret_val = NULL;
    961   REGFI_HBIN* hbin;
     963  const REGFI_HBIN* hbin;
    962964  uint32 data_offset, data_maxsize;
    963965
     
    10181020 ******************************************************************************/
    10191021REGFI_VALUE_LIST* regfi_load_valuelist(REGFI_FILE* file, uint32 offset,
    1020                                        uint32 num_values, uint32 max_size, 
     1022                                       uint32 num_values, uint32 max_size,
    10211023                                       bool strict)
    10221024{
     
    10411043
    10421044
    1043 /*******************************************************************
    1044  * XXX: Need to add full key caching using a
    1045  *      custom cache structure.
    1046  *******************************************************************/
     1045/******************************************************************************
     1046 *
     1047 ******************************************************************************/
    10471048REGFI_NK_REC* regfi_load_key(REGFI_FILE* file, uint32 offset, bool strict)
    10481049{
    1049   REGFI_HBIN* hbin;
    1050   REGFI_HBIN* sub_hbin;
     1050  const REGFI_HBIN* hbin;
     1051  const REGFI_HBIN* sub_hbin;
    10511052  REGFI_NK_REC* nk;
    10521053  uint32 max_length, off;
     
    10581059  /* get the initial nk record */
    10591060  max_length = hbin->block_size + hbin->file_off - offset;
    1060   if ((nk = regfi_parse_nk(file, offset, max_length, true)) == NULL)
     1061  if((nk = regfi_parse_nk(file, offset, max_length, true)) == NULL)
    10611062  {
    10621063    regfi_add_message(file, REGFI_MSG_ERROR, "Could not load NK record at"
     
    10651066  }
    10661067
    1067   /* fill in values */
     1068  /* get value list */
    10681069  if(nk->num_values && (nk->values_off!=REGFI_OFFSET_NONE))
    10691070  {
     
    11021103  }
    11031104
    1104   /* now get subkeys */
     1105  /* now get subkey list */
    11051106  if(nk->num_subkeys && (nk->subkeys_off != REGFI_OFFSET_NONE))
    11061107  {
     
    11411142/******************************************************************************
    11421143 ******************************************************************************/
    1143 static bool regfi_find_root_nk(REGFI_FILE* file, uint32 offset, uint32 hbin_size,
     1144const REGFI_SK_REC* regfi_load_sk(REGFI_FILE* file, uint32 offset, bool strict)
     1145{
     1146  REGFI_SK_REC* ret_val = NULL;
     1147  const REGFI_HBIN* hbin;
     1148  uint32 max_length;
     1149
     1150  /* First look if we have already parsed it */
     1151  ret_val = (REGFI_SK_REC*)lru_cache_find(file->sk_cache, &offset, 4);
     1152
     1153  /* Bail out if we have previously cached a parse failure at this offset. */
     1154  if(ret_val == (void*)REGFI_OFFSET_NONE)
     1155    return NULL;
     1156
     1157  if(ret_val == NULL)
     1158  {
     1159    hbin = regfi_lookup_hbin(file, offset - REGFI_REGF_SIZE);
     1160    if(hbin == NULL)
     1161      return NULL;
     1162
     1163    max_length = hbin->block_size + hbin->file_off - offset;
     1164    ret_val = regfi_parse_sk(file, offset, max_length, strict);
     1165    if(ret_val == NULL)
     1166    { /* Cache the parse failure and bail out. */
     1167      lru_cache_update(file->sk_cache, &offset, 4, (void*)REGFI_OFFSET_NONE);
     1168      return NULL;
     1169    }
     1170
     1171    lru_cache_update(file->sk_cache, &offset, 4, ret_val);
     1172  }
     1173
     1174  return ret_val;
     1175}
     1176
     1177
     1178
     1179/******************************************************************************
     1180 ******************************************************************************/
     1181static bool regfi_find_root_nk(REGFI_FILE* file, uint32 offset,uint32 hbin_size,
    11441182                               uint32* root_offset)
    11451183{
     
    11921230  REGFI_FILE* rb;
    11931231  REGFI_HBIN* hbin = NULL;
    1194   uint32 hbin_off, file_length;
     1232  uint32 hbin_off, file_length, cache_secret;
    11951233  int fd;
    11961234  bool rla;
     
    12411279  }
    12421280
     1281
     1282  /* This secret isn't very secret, but we don't need a good one.  This
     1283   * secret is just designed to prevent someone from trying to blow our
     1284   * caching and make things slow.
     1285   */
     1286  cache_secret = 0x15DEAD05^time(NULL)^(getpid()<<16);
     1287
     1288  /* Cache an unlimited number of SK records.  Typically there are very few. */
     1289  rb->sk_cache = lru_cache_create(0, cache_secret, true);
     1290
    12431291  /* Default message mask */
    12441292  rb->msg_mask = REGFI_MSG_ERROR|REGFI_MSG_WARN;
     
    12511299/*******************************************************************
    12521300 *******************************************************************/
    1253 int regfi_close( REGFI_FILE *file )
     1301int regfi_close(REGFI_FILE *file)
    12541302{
    12551303  int fd;
     
    12661314  range_list_free(file->hbins);
    12671315
     1316  if(file->sk_cache != NULL)
     1317    lru_cache_destroy(file->sk_cache);
    12681318  free(file);
    12691319
     
    12791329{
    12801330  REGFI_NK_REC* nk = NULL;
    1281   REGFI_HBIN*   hbin;
    1282   uint32       root_offset, i, num_hbins;
     1331  REGFI_HBIN* hbin;
     1332  uint32 root_offset, i, num_hbins;
    12831333 
    12841334  if(!file)
     
    12861336
    12871337  /* Scan through the file one HBIN block at a time looking
    1288      for an NK record with a type == 0x002c.
    1289      Normally this is the first nk record in the first hbin
    1290      block (but I'm not assuming that for now) */
    1291 
     1338   * for an NK record with a root key type.
     1339   * This is typically the first NK record in the first HBIN
     1340   * block (but we're not assuming that generally).
     1341   */
    12921342  num_hbins = range_list_size(file->hbins);
    12931343  for(i=0; i < num_hbins; i++)
     
    13611411  {
    13621412    free(ret_val);
    1363     free(root);
    1364     return NULL;
    1365   }
    1366 
    1367   /* This secret isn't very secret, but we don't need a good one.  This
    1368    * secret is just designed to prevent someone from trying to blow our
    1369    * caching and make things slow.
    1370    */
    1371   ret_val->sk_recs = lru_cache_create(127, 0x15DEAD05^time(NULL)^(getpid()<<16),
    1372                                       true);
     1413    return NULL;
     1414  }
    13731415
    13741416  ret_val->f = fh;
     
    13961438  }
    13971439 
    1398   lru_cache_destroy(i->sk_recs);
    1399 
     1440  void_stack_free(i->key_positions);
    14001441  free(i);
    14011442}
     
    15431584const REGFI_SK_REC* regfi_iterator_cur_sk(REGFI_ITERATOR* i)
    15441585{
    1545   REGFI_SK_REC* ret_val = NULL;
    1546   REGFI_HBIN* hbin;
    1547   uint32 max_length, off;
    1548 
    1549   if(i->cur_key == NULL)
    1550     return NULL;
    1551  
    1552   /* First look if we have already parsed it */
    1553   if((i->cur_key->sk_off!=REGFI_OFFSET_NONE)
    1554      && !(ret_val =(REGFI_SK_REC*)lru_cache_find(i->sk_recs,
    1555                                                 &i->cur_key->sk_off, 4)))
    1556   {
    1557     hbin = regfi_lookup_hbin(i->f, i->cur_key->sk_off);
    1558 
    1559     if(hbin == NULL)
    1560       return NULL;
    1561 
    1562     off = i->cur_key->sk_off + REGFI_REGF_SIZE;
    1563     max_length = hbin->block_size + hbin->file_off - off;
    1564     ret_val = regfi_parse_sk(i->f, off, max_length, true);
    1565     if(ret_val == NULL)
    1566       return NULL;
    1567 
    1568     ret_val->sk_off = i->cur_key->sk_off;
    1569     lru_cache_update(i->sk_recs, &i->cur_key->sk_off, 4, ret_val);
    1570   }
    1571 
    1572   return ret_val;
    1573 }
    1574 
     1586  if(i->cur_key == NULL || i->cur_key->sk_off == REGFI_OFFSET_NONE)
     1587    return NULL;
     1588
     1589  return regfi_load_sk(i->f, i->cur_key->sk_off + REGFI_REGF_SIZE, true);
     1590}
    15751591
    15761592
     
    16581674const REGFI_VK_REC* regfi_iterator_cur_value(REGFI_ITERATOR* i)
    16591675{
    1660   REGFI_VK_REC* ret_val = NULL;
     1676  const REGFI_VK_REC* ret_val = NULL;
    16611677  uint32 voffset;
    16621678
     
    16871703  return ret_val;
    16881704}
    1689 
    16901705
    16911706
     
    18521867{
    18531868  uint8 nk_header[REGFI_NK_MIN_LENGTH];
    1854   REGFI_HBIN *hbin;
     1869  const REGFI_HBIN *hbin;
    18551870  REGFI_NK_REC* ret_val;
    18561871  uint32 length,cell_length;
  • trunk/src/reglookup-recover.c

    r145 r146  
    257257{
    258258  void_stack* path_stack = void_stack_new(REGFI_MAX_DEPTH);
    259   REGFI_HBIN* hbin;
     259  const REGFI_HBIN* hbin;
    260260  REGFI_NK_REC* cur_ancestor;
    261261  char* ret_val;
     
    465465  const range_list_element* cur_elem;
    466466  REGFI_VK_REC* vk;
    467   REGFI_HBIN* hbin;
     467  const REGFI_HBIN* hbin;
    468468  uint32 i, off, data_offset, data_maxsize;
    469469
     
    570570  REGFI_NK_REC* nk;
    571571  REGFI_VK_REC* vk;
    572   REGFI_HBIN* hbin;
     572  const REGFI_HBIN* hbin;
    573573  const range_list_element* cur_elem;
    574574  uint32 i, j, num_keys, off, values_length, max_length;
Note: See TracChangeset for help on using the changeset viewer.