Changeset 161 for trunk/lib


Ignore:
Timestamp:
12/07/09 12:01:22 (14 years ago)
Author:
tim
Message:

added support for UTF-16LE key names

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/regfi.c

    r160 r161  
    1919 * You should have received a copy of the GNU General Public License
    2020 * along with this program; if not, write to the Free Software
    21  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
     21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    2222 *
    2323 * $Id$
     
    3333   "MULTI_SZ", "RSRC_LIST", "RSRC_DESC", "RSRC_REQ_LIST", "QWORD"};
    3434
     35const char* regfi_encoding_names[] =
     36  {"US-ASCII//TRANSLIT", "UTF-8//TRANSLIT", "UTF-16LE//TRANSLIT"};
    3537
    3638
     
    102104
    103105
    104 /* Returns NULL on error */
     106/******************************************************************************
     107 * Returns NULL for an invalid e
     108 *****************************************************************************/
     109static const char* regfi_encoding_int2str(REGFI_ENCODING e)
     110{
     111  if(e < REGFI_NUM_ENCODINGS)
     112    return regfi_encoding_names[e];
     113
     114  return NULL;
     115}
     116
     117
     118/******************************************************************************
     119 * Returns NULL for an invalid val
     120 *****************************************************************************/
    105121const char* regfi_type_val2str(unsigned int val)
    106122{
     
    115131
    116132
    117 /* Returns -1 on error */
     133/******************************************************************************
     134 * Returns -1 on error
     135 *****************************************************************************/
    118136int regfi_type_str2val(const char* str)
    119137{
     
    10041022 *
    10051023 ******************************************************************************/
    1006 REGFI_NK_REC* regfi_load_key(REGFI_FILE* file, uint32 offset, bool strict)
     1024REGFI_NK_REC* regfi_load_key(REGFI_FILE* file, uint32 offset,
     1025                             REGFI_ENCODING output_encoding, bool strict)
    10071026{
    10081027  REGFI_NK_REC* nk;
    10091028  uint32 off;
    1010   int32 max_size;
     1029  int32 max_size, tmp_size;
     1030  REGFI_ENCODING from_encoding;
    10111031
    10121032  max_size = regfi_calc_maxsize(file, offset);
     
    10211041    return NULL;
    10221042  }
     1043
     1044  from_encoding = (nk->flags & REGFI_NK_FLAG_ASCIINAME)
     1045    ? REGFI_ENCODING_ASCII : REGFI_ENCODING_UTF16LE;
     1046
     1047  if(from_encoding == output_encoding)
     1048  {
     1049    nk->keyname_raw = talloc_realloc(nk, nk->keyname_raw, uint8, nk->name_length+1);
     1050    nk->keyname_raw[nk->name_length] = '\0';
     1051    nk->keyname = (char*)nk->keyname_raw;
     1052  }
     1053  else
     1054  {
     1055    nk->keyname = talloc_array(nk, char, nk->name_length+1);
     1056    if(nk->keyname == NULL)
     1057    {
     1058      regfi_free_key(nk);
     1059      return NULL;
     1060    }
     1061
     1062    tmp_size = regfi_conv_charset(regfi_encoding_int2str(from_encoding),
     1063                                  regfi_encoding_int2str(output_encoding),
     1064                                  nk->keyname_raw, nk->keyname,
     1065                                  nk->name_length, nk->name_length+1);
     1066    if(tmp_size < 0)
     1067    {
     1068      regfi_add_message(file, REGFI_MSG_WARN, "Error occurred while converting"
     1069                        " keyname to encoding %s.  Error message: %s",
     1070                        regfi_encoding_int2str(output_encoding),
     1071                        strerror(-tmp_size));
     1072      talloc_free(nk->keyname);
     1073      nk->keyname = NULL;
     1074    }
     1075  }
     1076
    10231077
    10241078  /* get value list */
     
    11321186/******************************************************************************
    11331187 ******************************************************************************/
    1134 REGFI_NK_REC* regfi_find_root_nk(REGFI_FILE* file, const REGFI_HBIN* hbin)
     1188REGFI_NK_REC* regfi_find_root_nk(REGFI_FILE* file, const REGFI_HBIN* hbin,
     1189                                 REGFI_ENCODING output_encoding)
    11351190{
    11361191  REGFI_NK_REC* nk = NULL;
     
    11511206    if(!unalloc)
    11521207    {
    1153       nk = regfi_load_key(file, cur_offset, true);
     1208      nk = regfi_load_key(file, cur_offset, output_encoding, true);
    11541209      if(nk != NULL)
    11551210      {
    1156         if(nk->key_type & REGFI_NK_FLAG_ROOT)
     1211        if(nk->flags & REGFI_NK_FLAG_ROOT)
    11571212          return nk;
    11581213      }
     
    12701325 * rest of the file if that fails.
    12711326 ******************************************************************************/
    1272 REGFI_NK_REC* regfi_rootkey(REGFI_FILE *file)
     1327REGFI_NK_REC* regfi_rootkey(REGFI_FILE* file, REGFI_ENCODING output_encoding)
    12731328{
    12741329  REGFI_NK_REC* nk = NULL;
     
    12801335
    12811336  root_offset = file->root_cell+REGFI_REGF_SIZE;
    1282   nk = regfi_load_key(file, root_offset, true);
     1337  nk = regfi_load_key(file, root_offset, output_encoding, true);
    12831338  if(nk != NULL)
    12841339  {
    1285     if(nk->key_type & REGFI_NK_FLAG_ROOT)
     1340    if(nk->flags & REGFI_NK_FLAG_ROOT)
    12861341      return nk;
    12871342  }
     
    12981353  {
    12991354    hbin = (REGFI_HBIN*)range_list_get(file->hbins, i)->data;
    1300     nk = regfi_find_root_nk(file, hbin);
     1355    nk = regfi_find_root_nk(file, hbin, output_encoding);
    13011356  }
    13021357
     
    13351390/******************************************************************************
    13361391 *****************************************************************************/
    1337 REGFI_ITERATOR* regfi_iterator_new(REGFI_FILE* file, uint32 output_encoding)
     1392REGFI_ITERATOR* regfi_iterator_new(REGFI_FILE* file,
     1393                                   REGFI_ENCODING output_encoding)
    13381394{
    13391395  REGFI_NK_REC* root;
    1340   REGFI_ITERATOR* ret_val = talloc(NULL, REGFI_ITERATOR);
     1396  REGFI_ITERATOR* ret_val;
     1397
     1398  if(output_encoding != REGFI_ENCODING_UTF8
     1399     && output_encoding != REGFI_ENCODING_ASCII)
     1400  {
     1401    regfi_add_message(file, REGFI_MSG_ERROR, "Invalid output_encoding supplied"
     1402                      " in creation of regfi iterator.");
     1403    return NULL;
     1404  }
     1405
     1406  ret_val = talloc(NULL, REGFI_ITERATOR);
    13411407  if(ret_val == NULL)
    13421408    return NULL;
    13431409
    1344   root = regfi_rootkey(file);
     1410  root = regfi_rootkey(file, output_encoding);
    13451411  if(root == NULL)
    13461412  {
     
    13611427  ret_val->cur_subkey = 0;
    13621428  ret_val->cur_value = 0;
    1363  
    1364   switch (output_encoding)
    1365   {
    1366   case 0:
    1367   case 1:
    1368     ret_val->string_encoding = "US-ASCII//TRANSLIT";
    1369     break;
    1370   case 2:
    1371     ret_val->string_encoding = "UTF-8//TRANSLIT";
    1372     break;
    1373   default:
    1374     talloc_free(ret_val);
    1375     return NULL;
    1376   }
    1377  
     1429  ret_val->string_encoding = output_encoding;
     1430   
    13781431  return ret_val;
    13791432}
     
    15591612  nk_offset = i->cur_key->subkeys->elements[i->cur_subkey].offset;
    15601613
    1561   return regfi_load_key(i->f, nk_offset+REGFI_REGF_SIZE, true);
     1614  return regfi_load_key(i->f, nk_offset+REGFI_REGF_SIZE, i->string_encoding,
     1615                        true);
    15621616}
    15631617
     
    16951749  interpreted = talloc_array(NULL, char, parse_length);
    16961750
    1697   conv_size = regfi_conv_charset(i->string_encoding,
     1751  conv_size = regfi_conv_charset(regfi_encoding_int2str(REGFI_ENCODING_UTF16LE),
     1752                                 regfi_encoding_int2str(i->string_encoding),
    16981753                                 raw, interpreted,
    16991754                                 parse_length, parse_length);
     
    18021857/******************************************************************************
    18031858 *****************************************************************************/
    1804 bool regfi_interpret_data(REGFI_FILE* file, const char* string_encoding,
     1859bool regfi_interpret_data(REGFI_FILE* file, REGFI_ENCODING string_encoding,
    18051860                          uint32 type, REGFI_DATA* data)
    18061861{
     
    18271882    }
    18281883     
    1829     tmp_size = regfi_conv_charset(string_encoding,
     1884    tmp_size = regfi_conv_charset(regfi_encoding_int2str(REGFI_ENCODING_UTF16LE),
     1885                                  regfi_encoding_int2str(string_encoding),
    18301886                                  data->raw, (char*)tmp_str,
    18311887                                  data->size, data->size);
     
    18931949     * then parse and quote fields individually.
    18941950     */
    1895     tmp_size = regfi_conv_charset(string_encoding,
     1951    tmp_size = regfi_conv_charset(regfi_encoding_int2str(REGFI_ENCODING_UTF16LE),
     1952                                  regfi_encoding_int2str(string_encoding),
    18961953                                  data->raw, (char*)tmp_str,
    18971954                                  data->size, data->size);
     
    19692026
    19702027
    1971 
    19722028/*******************************************************************
    19732029 * Convert from UTF-16LE to specified character set.
    19742030 * On error, returns a negative errno code.
    19752031 *******************************************************************/
    1976 int32 regfi_conv_charset(const char* output_charset,
     2032int32 regfi_conv_charset(const char* input_charset, const char* output_charset,
    19772033                         uint8* input, char* output,
    19782034                         uint32 input_len, uint32 output_max)
     
    19852041  int ret;
    19862042
     2043  /* XXX: Consider creating a couple of conversion descriptors earlier,
     2044   *      storing them on an iterator so they don't have to be recreated
     2045   *      each time.
     2046   */
     2047
    19872048  /* Set up conversion descriptor. */
    1988   conv_desc = iconv_open(output_charset, "UTF-16LE");
     2049  conv_desc = iconv_open(output_charset, input_charset);
    19892050
    19902051  ret = iconv(conv_desc, &inbuf, &in_len, &outbuf, &out_len);
     
    22272288  ret_val->magic[0] = nk_header[0x0];
    22282289  ret_val->magic[1] = nk_header[0x1];
    2229   ret_val->key_type = SVAL(nk_header, 0x2);
    2230  
    2231   if((ret_val->key_type & ~REGFI_NK_KNOWN_FLAGS) != 0)
     2290  ret_val->flags = SVAL(nk_header, 0x2);
     2291 
     2292  if((ret_val->flags & ~REGFI_NK_KNOWN_FLAGS) != 0)
    22322293  {
    22332294    regfi_add_message(file, REGFI_MSG_WARN, "Unknown key flags (0x%.4X) while"
    22342295                      " parsing NK record at offset 0x%.8X.",
    2235                       (ret_val->key_type & ~REGFI_NK_KNOWN_FLAGS), offset);
     2296                      (ret_val->flags & ~REGFI_NK_KNOWN_FLAGS), offset);
    22362297  }
    22372298
     
    22682329  ret_val->name_length = SVAL(nk_header, 0x48);
    22692330  ret_val->classname_length = SVAL(nk_header, 0x4A);
     2331  ret_val->keyname = NULL;
    22702332
    22712333  if(ret_val->name_length + REGFI_NK_MIN_LENGTH > ret_val->cell_size)
     
    22932355  }
    22942356
    2295   ret_val->keyname = talloc_array(ret_val, char, ret_val->name_length+1);
    2296   if(ret_val->keyname == NULL)
     2357  ret_val->keyname_raw = talloc_array(ret_val, uint8, ret_val->name_length);
     2358  if(ret_val->keyname_raw == NULL)
    22972359  {
    22982360    talloc_free(ret_val);
     
    23022364  /* Don't need to seek, should be at the right offset */
    23032365  length = ret_val->name_length;
    2304   if((regfi_read(file->fd, (uint8*)ret_val->keyname, &length) != 0)
     2366  if((regfi_read(file->fd, (uint8*)ret_val->keyname_raw, &length) != 0)
    23052367     || length != ret_val->name_length)
    23062368  {
     
    23102372    return NULL;
    23112373  }
    2312   ret_val->keyname[ret_val->name_length] = '\0';
    23132374
    23142375  return ret_val;
Note: See TracChangeset for help on using the changeset viewer.