Changeset 161


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

added support for UTF-16LE key names

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/regfi.h

    r160 r161  
    6060#define REGFI_MSG_WARN  0x0004
    6161#define REGFI_MSG_ERROR 0x0010
     62
     63typedef uint8 REGFI_ENCODING;
     64/* regfi library supported character encodings */
     65#define REGFI_ENCODING_ASCII   0
     66#define REGFI_ENCODING_UTF8    1
     67#define REGFI_ENCODING_DEFAULT REGFI_ENCODING_ASCII
     68/* UTF16LE is not supported for output */
     69#define REGFI_ENCODING_UTF16LE 2
     70
     71#define REGFI_NUM_ENCODINGS    3
    6272
    6373/* Windows is lame */
     
    360370 
    361371  /* header information */
    362   uint16 key_type;
     372  uint16 flags;
    363373  uint8  magic[REGFI_CELL_MAGIC_SIZE];
    364374  NTTIME mtime;
     
    479489  void_stack* key_positions;
    480490  REGFI_NK_REC* cur_key;
    481   const char* string_encoding;
     491  REGFI_ENCODING string_encoding;
    482492  uint32 cur_subkey;
    483493  uint32 cur_value;
     
    529539 *   file            -- The opened registry file the iterator should be
    530540 *                      created for.
    531  *   output_encoding -- An integer representing the output string encoding.
    532  *                      These integers currently map to a specific set of
    533  *                      iconv(3) encodings.
     541 *   output_encoding -- Character encoding that strings should be returned in.
     542 *                      Only supply the REGFI_ENCODING_* constants, as others
     543 *                      will be rejected.
    534544 *                      The following values are currently accepted:
    535  *                      0 - default (currently US-ASCII//TRANSLIT)
    536  *                      1 - US-ASCII//TRANSLIT
    537  *                      2 - UTF-8//TRANSLIT
     545 *                      REGFI_ENCODING_DEFAULT (currently REGFI_ENCODING_ASCII)
     546 *                      REGFI_ENCODING_ASCII
     547 *                      REGFI_ENCODING_UTF8
    538548 *
    539549 *                      XXX: This encoding only applies to specific data
     
    545555 */
    546556REGFI_ITERATOR*       regfi_iterator_new(REGFI_FILE* file,
    547                                          uint32 output_encoding);
     557                                         REGFI_ENCODING output_encoding);
    548558void                  regfi_iterator_free(REGFI_ITERATOR* i);
    549559bool                  regfi_iterator_down(REGFI_ITERATOR* i);
     
    578588/********************************************************/
    579589REGFI_NK_REC*         regfi_load_key(REGFI_FILE* file, uint32 offset,
     590                                     REGFI_ENCODING output_encoding,
    580591                                     bool strict);
    581592REGFI_VK_REC*         regfi_load_value(REGFI_FILE* file, uint32 offset,
     
    597608                                          bool strict);
    598609bool                  regfi_interpret_data(REGFI_FILE* file,
    599                                            const char* string_encoding,
     610                                           REGFI_ENCODING string_encoding,
    600611                                           uint32 type, REGFI_DATA* data);
    601612void                  regfi_free_classname(REGFI_CLASSNAME* classname);
     
    666677/*    Private Functions             */
    667678/************************************/
    668 REGFI_NK_REC*         regfi_rootkey(REGFI_FILE* file);
     679REGFI_NK_REC*         regfi_rootkey(REGFI_FILE* file,
     680                                    REGFI_ENCODING output_encoding);
    669681void                  regfi_subkeylist_free(REGFI_SUBKEY_LIST* list);
    670682uint32                regfi_read(int fd, uint8* buf, uint32* length);
     
    689701REGFI_VK_REC*         regfi_copy_vk(const REGFI_VK_REC* vk);
    690702int32                 regfi_calc_maxsize(REGFI_FILE* file, uint32 offset);
    691 int32                 regfi_conv_charset(const char* output_charset,
     703int32                 regfi_conv_charset(const char* input_charset,
     704                                         const char* output_charset,
    692705                                         uint8* input, char* output,
    693706                                         uint32 input_len, uint32 output_max);
  • 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;
  • trunk/src/reglookup-recover.c

    r160 r161  
    127127  /* XXX: Add command line option to choose output encoding */
    128128  if(vk->data != NULL
    129      && !regfi_interpret_data(f, "US-ASCII//TRANSLIT", vk->type, vk->data))
     129     && !regfi_interpret_data(f, REGFI_ENCODING_ASCII, vk->type, vk->data))
    130130  {
    131131    fprintf(stderr, "WARN: Error occurred while interpreting data for VK record"
     
    271271      else
    272272      {
    273         if(cur_ancestor->key_type & REGFI_NK_FLAG_ROOT)
     273        if(cur_ancestor->flags & REGFI_NK_FLAG_ROOT)
    274274          virt_offset = REGFI_OFFSET_NONE;
    275275        else
  • trunk/src/reglookup.c

    r160 r161  
    191191{
    192192  const REGFI_ITER_POSITION* cur;
     193  const REGFI_NK_REC* tmp_key;
    193194  uint32 buf_left = 127;
    194195  uint32 buf_len = buf_left+1;
     
    198199  char* new_buf;
    199200  char* name;
    200   const char* cur_name;
    201201  void_stack_iterator* iter;
    202202 
     
    226226    cur = void_stack_iterator_next(iter);
    227227    if (cur == NULL)
    228       cur_name = i->cur_key->keyname;
    229     else
    230       cur_name = cur->nk->keyname;
     228      tmp_key = i->cur_key;
     229    else
     230      tmp_key = cur->nk;
     231
     232    if(tmp_key->keyname == NULL)
     233      name = quote_buffer(i->cur_key->keyname_raw, i->cur_key->name_length,
     234                          key_special_chars);
     235    else
     236      name = quote_string(tmp_key->keyname, key_special_chars);
    231237
    232238    buf[buf_len-buf_left-1] = '/';
    233239    buf_left -= 1;
    234     name = quote_string(cur_name, key_special_chars);
    235240    name_len = strlen(name);
    236241    if(name_len+1 > buf_left)
     
    617622
    618623  /* XXX: add command line option to choose output encoding */
    619   iter = regfi_iterator_new(f, 0);
     624  iter = regfi_iterator_new(f, REGFI_ENCODING_ASCII);
    620625  if(iter == NULL)
    621626  {
Note: See TracChangeset for help on using the changeset viewer.