Changeset 249


Ignore:
Timestamp:
05/04/11 10:55:22 (14 years ago)
Author:
tim
Message:

reorganized iterator code for simpler locking and easier future key caching

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/regfi.h

    r238 r249  
    653653  REGFI_NTTIME mtime;
    654654
    655   /** Length of keyname_raw */
     655  /** Length of name_raw */
    656656  uint16_t name_length;
    657657
     
    827827
    828828
     829typedef struct _regfi_iter_position
     830{
     831  /* key offset */
     832  uint32_t offset;
     833
     834  /* Index of the current subkey */
     835  uint32_t cur_subkey;
     836
     837  /* Index of the current value */
     838  uint32_t cur_value;
     839
     840  /* The number of subkeys of this key */
     841  uint32_t num_subkeys;
     842
     843  /* The number of values of this key */
     844  uint32_t num_values;
     845
     846} REGFI_ITER_POSITION;
     847
     848
    829849/** Registry hive iterator
    830850 * @ingroup regfiIteratorLayer
     
    838858  void_stack* key_positions;
    839859
    840   /** The current key */
    841   REGFI_NK* cur_key;
    842 
    843   /** Index of the current subkey */
    844   uint32_t cur_subkey;
    845 
    846   /** Index of the current value */
    847   uint32_t cur_value;
     860  REGFI_ITER_POSITION* cur;
    848861} REGFI_ITERATOR;
    849862
    850 
    851 typedef struct _regfi_iter_position
    852 {
    853   REGFI_NK* nk;
    854   uint32_t cur_subkey;
    855   /* We could store a cur_value here as well, but didn't see
    856    * the use in it right now.
    857    */
    858 } REGFI_ITER_POSITION;
    859863
    860864
     
    14051409_EXPORT()
    14061410bool regfi_iterator_find_value(REGFI_ITERATOR* i, const char* name);
     1411
     1412
     1413/** Returns the full path where the iterator is currently located as a list
     1414 *  of NK records
     1415 *
     1416 * @param i     the iterator
     1417 *
     1418 * @return An array of NK record pointers terminated by a NULL pointer. 
     1419 *         This array may be passed directly to regfi_free_record to free
     1420 *         the entire array. 
     1421 *
     1422 * @note In order to use an element of the array independently from the
     1423 *       array (that is, to hold a pointer to an individual NK record while
     1424 *       freeing the remaining array), callers must first use
     1425 *       regfi_reference_record on the elements to be kept.
     1426 *
     1427 * @ingroup regfiIteratorLayer
     1428 */
     1429_EXPORT()
     1430const REGFI_NK** regfi_iterator_cur_path(REGFI_ITERATOR* i);
    14071431
    14081432
  • trunk/lib/regfi.c

    r233 r249  
    18231823  if(ret_val == NULL)
    18241824    return NULL;
     1825 
     1826  ret_val->cur = talloc(ret_val, REGFI_ITER_POSITION);
     1827  if(ret_val->cur == NULL)
     1828  {
     1829    talloc_free(ret_val);
     1830    return NULL;
     1831  }
     1832
     1833  ret_val->key_positions = void_stack_new(REGFI_MAX_DEPTH);
     1834  if(ret_val->key_positions == NULL)
     1835  {
     1836    talloc_free(ret_val);
     1837    return NULL;
     1838  }
     1839  talloc_reparent(NULL, ret_val, ret_val->key_positions);
    18251840
    18261841  root = (REGFI_NK*)regfi_get_rootkey(file);
     
    18301845    return NULL;
    18311846  }
    1832   ret_val->cur_key = root;
    1833   talloc_reparent(NULL, ret_val, root);
    1834 
    1835   ret_val->key_positions = void_stack_new(REGFI_MAX_DEPTH);
    1836   if(ret_val->key_positions == NULL)
    1837   {
    1838     talloc_free(ret_val);
    1839     return NULL;
    1840   }
    1841   talloc_reparent(NULL, ret_val, ret_val->key_positions);
    1842 
     1847
     1848  ret_val->cur->offset = root->offset;
     1849  if(root->subkeys_off == REGFI_OFFSET_NONE)
     1850    ret_val->cur->num_subkeys = 0;
     1851  else
     1852    ret_val->cur->num_subkeys = regfi_fetch_num_subkeys(root);
     1853 
     1854  if(root->values_off == REGFI_OFFSET_NONE)
     1855    ret_val->cur->num_values = 0;
     1856  else
     1857    ret_val->cur->num_values = regfi_fetch_num_values(root);
     1858
     1859  ret_val->cur->cur_subkey = 0;
     1860  ret_val->cur->cur_value = 0;
    18431861  ret_val->f = file;
    1844   ret_val->cur_subkey = 0;
    1845   ret_val->cur_value = 0;
    1846    
     1862
     1863  regfi_free_record(ret_val->f, root);
    18471864  return ret_val;
    18481865}
     
    18551872  talloc_unlink(NULL, i);
    18561873}
    1857 
    18581874
    18591875
     
    18641880{
    18651881  REGFI_NK* subkey;
    1866   REGFI_ITER_POSITION* pos;
    1867 
    1868   pos = talloc(i->key_positions, REGFI_ITER_POSITION);
     1882  REGFI_ITER_POSITION* pos = talloc(i, REGFI_ITER_POSITION);
    18691883  if(pos == NULL)
    18701884    return false;
     
    18731887  if(subkey == NULL)
    18741888  {
     1889    regfi_log_add(REGFI_LOG_WARN, "Could not obtain cur_subkey during"
     1890                  " iterator_down with subkey index (%d) and key offset=%.8X\n",
     1891                  i->cur->cur_subkey, i->cur->offset);
    18751892    talloc_free(pos);
    18761893    return false;
    18771894  }
    18781895
    1879   pos->nk = i->cur_key;
    1880   pos->cur_subkey = i->cur_subkey;
    1881   if(!void_stack_push(i->key_positions, pos))
     1896  if(!void_stack_push(i->key_positions, i->cur))
    18821897  {
    18831898    talloc_free(pos);
    1884     talloc_unlink(NULL, subkey);
     1899    regfi_free_record(i->f, subkey);
    18851900    return false;
    1886   } 
    1887   talloc_reparent(NULL, i, subkey);
    1888 
    1889   i->cur_key = subkey;
    1890   i->cur_subkey = 0;
    1891   i->cur_value = 0;
    1892 
     1901  }
     1902
     1903  pos->offset = subkey->offset;
     1904  if(subkey->subkeys_off == REGFI_OFFSET_NONE)
     1905    pos->num_subkeys = 0;
     1906  else
     1907    pos->num_subkeys = regfi_fetch_num_subkeys(subkey);
     1908
     1909  if(subkey->values_off == REGFI_OFFSET_NONE)
     1910    pos->num_values = 0;
     1911  else
     1912    pos->num_values = regfi_fetch_num_values(subkey);
     1913
     1914  pos->cur_subkey = 0;
     1915  pos->cur_value = 0;
     1916  i->cur = pos;
     1917
     1918  regfi_free_record(i->f, subkey);
    18931919  return true;
    18941920}
     
    19081934    return false;
    19091935 
    1910   talloc_unlink(i, i->cur_key);
     1936  talloc_unlink(i, i->cur);
     1937
    19111938  regfi_unlock(i->f, &i->f->mem_lock, "regfi_iterator_up");
    19121939
    1913   i->cur_key = pos->nk;
    1914   i->cur_subkey = pos->cur_subkey;
    1915   i->cur_value = 0;
    1916   talloc_free(pos);
    1917 
     1940  i->cur = pos;
    19181941  return true;
    19191942}
     
    19351958bool regfi_iterator_find_subkey(REGFI_ITERATOR* i, const char* name)
    19361959{
     1960  const REGFI_NK* cur_key;
    19371961  uint32_t new_index;
    1938 
    1939   if(regfi_find_subkey(i->f, i->cur_key, name, &new_index))
    1940   {
    1941     i->cur_subkey = new_index;
    1942     return true;
    1943   }
    1944 
    1945   return false;
     1962  bool ret_val = false;
     1963
     1964  cur_key = regfi_iterator_cur_key(i);
     1965  if(cur_key == NULL)
     1966    /* XXX: report error */
     1967    return ret_val;
     1968
     1969  if(regfi_find_subkey(i->f, cur_key, name, &new_index))
     1970  {
     1971    i->cur->cur_subkey = new_index;
     1972    ret_val = true;
     1973  }
     1974
     1975  regfi_free_record(i->f, cur_key);
     1976  return ret_val;
    19461977}
    19471978
     
    19822013    return ret_val;
    19832014
    1984   ret_val = talloc_reference(NULL, i->cur_key);
     2015  ret_val = regfi_load_key(i->f, i->cur->offset, i->f->string_encoding, true);
    19852016
    19862017  regfi_unlock(i->f, &i->f->mem_lock, "regfi_iterator_cur_key"); 
     
    20042035bool regfi_iterator_first_subkey(REGFI_ITERATOR* i)
    20052036{
    2006   i->cur_subkey = 0;
    2007  
    2008   return ((i->cur_key != NULL) && (i->cur_key->subkeys_off!=REGFI_OFFSET_NONE)
    2009           && (i->cur_subkey < regfi_fetch_num_subkeys(i->cur_key)));
     2037  i->cur->cur_subkey = 0;
     2038  return (i->cur->cur_subkey < i->cur->num_subkeys);
    20102039}
    20112040
     
    20152044const REGFI_NK* regfi_iterator_cur_subkey(REGFI_ITERATOR* i)
    20162045{
    2017   return regfi_get_subkey(i->f, i->cur_key, i->cur_subkey);
     2046  const REGFI_NK* cur_key;
     2047  const REGFI_NK* ret_val;
     2048 
     2049  cur_key = regfi_iterator_cur_key(i);
     2050  if(cur_key == NULL)
     2051    /* XXX: report error */
     2052    return NULL;
     2053
     2054  ret_val = regfi_get_subkey(i->f, cur_key, i->cur->cur_subkey);
     2055
     2056  regfi_free_record(i->f, cur_key);
     2057  return ret_val;
    20182058}
    20192059
     
    20232063bool regfi_iterator_next_subkey(REGFI_ITERATOR* i)
    20242064{
    2025   i->cur_subkey++;
    2026 
    2027   return ((i->cur_key != NULL) && (i->cur_key->subkeys_off!=REGFI_OFFSET_NONE)
    2028           && (i->cur_subkey < regfi_fetch_num_subkeys(i->cur_key)));
     2065  i->cur->cur_subkey++;
     2066  return (i->cur->cur_subkey < i->cur->num_subkeys);
    20292067}
    20302068
     
    20342072bool regfi_iterator_find_value(REGFI_ITERATOR* i, const char* name)
    20352073{
     2074  const REGFI_NK* cur_key;
    20362075  uint32_t new_index;
    2037 
    2038   if(regfi_find_value(i->f, i->cur_key, name, &new_index))
    2039   {
    2040     i->cur_value = new_index;
    2041     return true;
    2042   }
    2043 
    2044   return false;
     2076  bool ret_val = false;
     2077
     2078  cur_key = regfi_iterator_cur_key(i);
     2079  if(cur_key == NULL)
     2080    /* XXX: report error */
     2081    return ret_val;
     2082
     2083  if(regfi_find_value(i->f, cur_key, name, &new_index))
     2084  {
     2085    i->cur->cur_value = new_index;
     2086    ret_val = true;
     2087  }
     2088
     2089  regfi_free_record(i->f, cur_key);
     2090  return ret_val;
    20452091}
    20462092
     
    20502096bool regfi_iterator_first_value(REGFI_ITERATOR* i)
    20512097{
    2052   i->cur_value = 0;
    2053   return (i->cur_key->values != NULL && i->cur_key->values->elements != NULL
    2054           && (i->cur_value < regfi_fetch_num_values(i->cur_key)));
     2098  i->cur->cur_value = 0;
     2099  return (i->cur->cur_value < i->cur->num_values);
    20552100}
    20562101
     
    20602105const REGFI_VK* regfi_iterator_cur_value(REGFI_ITERATOR* i)
    20612106{
    2062   return regfi_get_value(i->f, i->cur_key, i->cur_value);
     2107  const REGFI_NK* cur_key;
     2108  const REGFI_VK* ret_val = NULL;
     2109
     2110  cur_key = regfi_iterator_cur_key(i);
     2111  if(cur_key == NULL)
     2112    /* XXX: report error */
     2113    return ret_val;
     2114
     2115  ret_val = regfi_get_value(i->f, cur_key, i->cur->cur_value);
     2116 
     2117  regfi_free_record(i->f, cur_key);
     2118  return ret_val;
    20632119}
    20642120
     
    20682124bool regfi_iterator_next_value(REGFI_ITERATOR* i)
    20692125{
    2070   i->cur_value++;
    2071   return (i->cur_key->values != NULL && i->cur_key->values->elements != NULL
    2072           && (i->cur_value < regfi_fetch_num_values(i->cur_key)));
     2126  i->cur->cur_value++;
     2127  return (i->cur->cur_value < i->cur->num_values);
     2128}
     2129
     2130
     2131
     2132
     2133/******************************************************************************
     2134 *****************************************************************************/
     2135const REGFI_NK** regfi_iterator_cur_path(REGFI_ITERATOR* i)
     2136{
     2137  REGFI_NK** ret_val;
     2138  void_stack_iterator* iter;
     2139  const REGFI_ITER_POSITION* cur;
     2140  uint16_t k;
     2141
     2142  ret_val = talloc_array(NULL, REGFI_NK*, void_stack_size(i->key_positions)+2);
     2143  if(ret_val == NULL)
     2144    return NULL;
     2145
     2146  iter = void_stack_iterator_new(i->key_positions);
     2147  if (iter == NULL)
     2148  {
     2149    talloc_free(ret_val);
     2150    return NULL;
     2151  }
     2152 
     2153  if(!regfi_lock(i->f, &i->f->mem_lock, "regfi_cur_path"))
     2154  {
     2155    talloc_free(ret_val);
     2156    return NULL;
     2157  }
     2158
     2159  for(cur=void_stack_iterator_next(iter), k=0;
     2160      cur != NULL; cur=void_stack_iterator_next(iter), k++)
     2161  {
     2162    ret_val[k] = regfi_load_key(i->f, cur->offset, i->f->string_encoding, true);
     2163    talloc_reparent(NULL, ret_val, ret_val[k]);
     2164  }
     2165  ret_val[k] = regfi_load_key(i->f, i->cur->offset, i->f->string_encoding, true);
     2166  talloc_reparent(NULL, ret_val, ret_val[k]);
     2167
     2168  regfi_unlock(i->f, &i->f->mem_lock, "regfi_cur_path");
     2169  void_stack_iterator_free(iter);
     2170
     2171  ret_val[++k] = NULL;
     2172  return (const REGFI_NK**)ret_val;
    20732173}
    20742174
  • trunk/src/reglookup.c

    r233 r249  
    5252
    5353
     54static bool keysEqual(const REGFI_NK* x, const REGFI_NK* y)
     55{
     56  return (x != NULL && y != NULL && x->offset == y->offset);
     57}
     58
    5459void printValue(REGFI_ITERATOR* iter, const REGFI_VK* vk, char* prefix)
    5560{
     61  const REGFI_NK* cur_key;
    5662  const REGFI_DATA* data;
    5763  char* quoted_value = NULL;
     
    100106  if(print_value_mtime)
    101107  {
    102     *tmp_time = regfi_nt2unix_time(&iter->cur_key->mtime);
     108    cur_key = regfi_iterator_cur_key(iter);
     109    *tmp_time = regfi_nt2unix_time(&cur_key->mtime);
    103110    tmp_time_s = gmtime(tmp_time);
    104111    strftime(mtime, sizeof(mtime), "%Y-%m-%d %H:%M:%S", tmp_time_s);
     112    regfi_free_record(iter->f, cur_key);
    105113  }
    106114  else
     
    201209
    202210
    203 /* Returns a quoted path from an iterator's stack */
     211/* Returns a quoted path of the current iterator's position */
    204212char* iter2Path(REGFI_ITERATOR* i)
    205213{
    206   const REGFI_ITER_POSITION* cur;
    207   const REGFI_NK* tmp_key;
     214  const REGFI_NK** path;
     215  uint32_t k;
    208216  uint32_t buf_left = 127;
    209217  uint32_t buf_len = buf_left+1;
     
    213221  char* new_buf;
    214222  char* name;
    215   void_stack_iterator* iter;
    216223 
    217224  buf = (char*)malloc((buf_len)*sizeof(char));
     
    220227  buf[0] = '\0';
    221228
    222   iter = void_stack_iterator_new(i->key_positions);
    223   if (iter == NULL)
     229  path = regfi_iterator_cur_path(i);
     230  if(path == NULL)
    224231  {
    225232    free(buf);
     
    227234  }
    228235
    229   /* skip root element */
    230   if(void_stack_size(i->key_positions) < 1)
    231   {
    232     buf[0] = '/';
    233     buf[1] = '\0';
    234     return buf;
    235   }
    236   cur = void_stack_iterator_next(iter);
    237 
    238   do
    239   {
    240     cur = void_stack_iterator_next(iter);
    241     if (cur == NULL)
    242       tmp_key = i->cur_key;
     236  for(k=0; path[k] != NULL; k++)
     237  {
     238    /* skip root element's name */
     239    if(k == 0)
     240    {
     241      buf[0] = '/';
     242      buf[1] = '\0';
     243    }
    243244    else
    244       tmp_key = cur->nk;
    245 
    246     name = get_quoted_keyname(tmp_key);
    247 
    248     buf[buf_len-buf_left-1] = '/';
    249     buf_left -= 1;
    250     name_len = strlen(name);
    251     if(name_len+1 > buf_left)
    252     {
    253       grow_amt = (uint32_t)(buf_len/2);
    254       buf_len += name_len+1+grow_amt-buf_left;
    255       if((new_buf = realloc(buf, buf_len)) == NULL)
     245    {
     246      name = get_quoted_keyname(path[k]);
     247
     248      buf[buf_len-buf_left-1] = '/';
     249      buf_left -= 1;
     250      name_len = strlen(name);
     251      if(name_len+1 > buf_left)
    256252      {
    257         free(name);
    258         free(buf);
    259         free(iter);
    260         return NULL;
     253        grow_amt = (uint32_t)(buf_len/2);
     254        buf_len += name_len+1+grow_amt-buf_left;
     255        if((new_buf = realloc(buf, buf_len)) == NULL)
     256        {
     257          regfi_free_record(i->f, path);
     258          free(name);
     259          free(buf);
     260          return NULL;
     261        }
     262        buf = new_buf;
     263        buf_left = grow_amt + name_len + 1;
    261264      }
    262       buf = new_buf;
    263       buf_left = grow_amt + name_len + 1;
    264     }
    265     strncpy(buf+(buf_len-buf_left-1), name, name_len);
    266     buf_left -= name_len;
    267     buf[buf_len-buf_left-1] = '\0';
    268     free(name);
    269   } while(cur != NULL);
    270 
     265      strncpy(buf+(buf_len-buf_left-1), name, name_len);
     266      buf_left -= name_len;
     267      buf[buf_len-buf_left-1] = '\0';
     268      free(name);
     269    }
     270  }
     271
     272  regfi_free_record(i->f, path);
    271273  return buf;
    272274}
     
    378380  bool print_this = true;
    379381
    380   root = cur = regfi_iterator_cur_key(iter);
     382  root = regfi_iterator_cur_key(iter);
     383  regfi_reference_record(iter->f, root);
     384  cur = root;
    381385  regfi_iterator_first_subkey(iter);
    382386  sub = regfi_iterator_cur_subkey(iter);
     
    404408    if(sub == NULL)
    405409    {
    406       if(cur != root)
     410      if(!keysEqual(cur, root))
    407411      {
    408412        regfi_free_record(iter->f, cur);
     413        cur = NULL;
    409414        /* We're done with this sub-tree, going up and hitting other branches. */
    410415        if(!regfi_iterator_up(iter))
     
    431436       */
    432437      regfi_free_record(iter->f, cur);
     438      cur = NULL;
    433439      if(!regfi_iterator_down(iter))
    434440      {
     
    444450    }
    445451    printMsgs(iter->f);
    446   } while(!((cur == root) && (sub == NULL)));
     452  } while(!(keysEqual(cur, root) && (sub == NULL)));
     453  if(cur != NULL)
     454    regfi_free_record(iter->f, cur);
    447455  regfi_free_record(iter->f, root);
    448456
Note: See TracChangeset for help on using the changeset viewer.