Changeset 160 for trunk


Ignore:
Timestamp:
12/06/09 20:00:58 (14 years ago)
Author:
tim
Message:

reorganized classname parsing and interpretation code

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/regfi.h

    r159 r160  
    251251
    252252
     253typedef struct _regfi_classname
     254{
     255  /* As converted to requested character encoding. */
     256  char* interpreted;
     257
     258  /* Represents raw buffer read from classname cell. */
     259  uint8* raw;
     260
     261  /* Length of the raw data. May be shorter than that indicated by parent key.*/
     262  uint16 size;
     263} REGFI_CLASSNAME;
     264
     265
    253266typedef struct _regfi_data
    254267{
     
    299312
    300313  char*  valuename;
     314  uint8* valuename_raw;
    301315  uint16 name_length;
    302316  uint32 hbin_off;      /* offset from beginning of this hbin block */
     
    351365  uint16 name_length;
    352366  uint16 classname_length;
    353   char* classname;
    354367  char* keyname;
     368  uint8* keyname_raw;
    355369  uint32 parent_off;                /* pointer to parent key */
    356370  uint32 classname_off;
     
    554568                                                const char* value_name);
    555569
     570REGFI_CLASSNAME*      regfi_iterator_fetch_classname(REGFI_ITERATOR* i,
     571                                                     const REGFI_NK_REC* key);
    556572REGFI_DATA*           regfi_iterator_fetch_data(REGFI_ITERATOR* i,
    557573                                                const REGFI_VK_REC* value);
     
    583599                                           const char* string_encoding,
    584600                                           uint32 type, REGFI_DATA* data);
     601void                  regfi_free_classname(REGFI_CLASSNAME* classname);
    585602void                  regfi_free_data(REGFI_DATA* data);
     603
    586604
    587605/* These are cached so return values don't need to be freed. */
     
    628646                                       uint32* cell_length, bool* unalloc);
    629647
    630 char*                 regfi_parse_classname(REGFI_FILE* file, uint32 offset,
     648uint8*                regfi_parse_classname(REGFI_FILE* file, uint32 offset,
    631649                                            uint16* name_length,
    632650                                            uint32 max_size, bool strict);
  • trunk/lib/regfi.c

    r159 r160  
    10861086  }
    10871087
    1088   /* Get classname if it exists */
    1089   if(nk->classname_off != REGFI_OFFSET_NONE)
    1090   {
    1091     off = nk->classname_off + REGFI_REGF_SIZE;
    1092     max_size = regfi_calc_maxsize(file, off);
    1093     if(max_size >= 0)
    1094     {
    1095       nk->classname
    1096         = regfi_parse_classname(file, off, &nk->classname_length,
    1097                                 max_size, strict);
    1098     }
    1099     else
    1100     {
    1101       nk->classname = NULL;
    1102       regfi_add_message(file, REGFI_MSG_WARN, "Could not find hbin for class"
    1103                         " name while parsing NK record at offset 0x%.8X.",
    1104                         offset);
    1105     }
    1106 
    1107     if(nk->classname == NULL)
    1108     {
    1109       regfi_add_message(file, REGFI_MSG_WARN, "Could not parse class"
    1110                         " name while parsing NK record at offset 0x%.8X.",
    1111                         offset);
    1112     }
    1113     else
    1114       talloc_steal(nk, nk->classname);
    1115   }
    1116 
    11171088  return nk;
    11181089}
     
    16851656/******************************************************************************
    16861657 *****************************************************************************/
     1658REGFI_CLASSNAME* regfi_iterator_fetch_classname(REGFI_ITERATOR* i,
     1659                                                const REGFI_NK_REC* key)
     1660{
     1661  REGFI_CLASSNAME* ret_val;
     1662  uint8* raw;
     1663  char* interpreted;
     1664  uint32 offset;
     1665  int32 conv_size, max_size;
     1666  uint16 parse_length;
     1667
     1668  if(key->classname_off == REGFI_OFFSET_NONE || key->classname_length == 0)
     1669    return NULL;
     1670
     1671  offset = key->classname_off + REGFI_REGF_SIZE;
     1672  max_size = regfi_calc_maxsize(i->f, offset);
     1673  if(max_size <= 0)
     1674    return NULL;
     1675
     1676  parse_length = key->classname_length;
     1677  raw = regfi_parse_classname(i->f, offset, &parse_length, max_size, true);
     1678 
     1679  if(raw == NULL)
     1680  {
     1681    regfi_add_message(i->f, REGFI_MSG_WARN, "Could not parse class"
     1682                      " name at offset 0x%.8X for key record at offset 0x%.8X.",
     1683                      offset, key->offset);
     1684    return NULL;
     1685  }
     1686
     1687  ret_val = talloc(NULL, REGFI_CLASSNAME);
     1688  if(ret_val == NULL)
     1689    return NULL;
     1690
     1691  ret_val->raw = raw;
     1692  ret_val->size = parse_length;
     1693  talloc_steal(ret_val, raw);
     1694
     1695  interpreted = talloc_array(NULL, char, parse_length);
     1696
     1697  conv_size = regfi_conv_charset(i->string_encoding,
     1698                                 raw, interpreted,
     1699                                 parse_length, parse_length);
     1700  if(conv_size < 0)
     1701  {
     1702    regfi_add_message(i->f, REGFI_MSG_WARN, "Error occurred while"
     1703                      " converting classname to charset %s.  Error message: %s",
     1704                      i->string_encoding, strerror(-conv_size));
     1705    talloc_free(interpreted);
     1706    ret_val->interpreted = NULL;
     1707  }
     1708  else
     1709  {
     1710    interpreted = talloc_realloc(NULL, interpreted, char, conv_size);
     1711    ret_val->interpreted = interpreted;
     1712    talloc_steal(ret_val, interpreted);
     1713  }
     1714
     1715  return ret_val;
     1716}
     1717
     1718
     1719/******************************************************************************
     1720 *****************************************************************************/
    16871721REGFI_DATA* regfi_iterator_fetch_data(REGFI_ITERATOR* i,
    16881722                                      const REGFI_VK_REC* value)
     
    17271761}
    17281762
     1763
     1764/******************************************************************************
     1765 *****************************************************************************/
     1766void regfi_free_classname(REGFI_CLASSNAME* classname)
     1767{
     1768  talloc_free(classname);
     1769}
    17291770
    17301771/******************************************************************************
     
    22752316
    22762317
    2277 char* regfi_parse_classname(REGFI_FILE* file, uint32 offset,
    2278                             uint16* name_length, uint32 max_size, bool strict)
    2279 {
    2280   char* ret_val = NULL;
     2318uint8* regfi_parse_classname(REGFI_FILE* file, uint32 offset,
     2319                             uint16* name_length, uint32 max_size, bool strict)
     2320{
     2321  uint8* ret_val = NULL;
    22812322  uint32 length;
    22822323  uint32 cell_length;
     
    23202361    }
    23212362   
    2322     ret_val = talloc_array(NULL, char, *name_length);
     2363    ret_val = talloc_array(NULL, uint8, *name_length);
    23232364    if(ret_val != NULL)
    23242365    {
    23252366      length = *name_length;
    2326       if((regfi_read(file->fd, (uint8*)ret_val, &length) != 0)
     2367      if((regfi_read(file->fd, ret_val, &length) != 0)
    23272368         || length != *name_length)
    23282369      {
     
    24752516   *   http://msdn2.microsoft.com/en-us/library/ms724872.aspx
    24762517   */
    2477   /*
    2478 XXX
    2479   if(size > REGFI_VK_MAX_DATA_LENGTH)
    2480   {
    2481     *error_msg = (char*)malloc(82);
    2482     if(*error_msg == NULL)
    2483       return NULL;
    2484    
    2485     sprintf(*error_msg, "WARN: value data size %d larger than "
    2486             "%d, truncating...", size, REGFI_VK_MAX_DATA_LENGTH);
    2487     size = REGFI_VK_MAX_DATA_LENGTH;
    2488   }
    2489 
    2490   */
     2518  /* XXX: add way to skip this check at user discression. */
     2519  if(length > REGFI_VK_MAX_DATA_LENGTH)
     2520  {
     2521    regfi_add_message(file, REGFI_MSG_WARN, "Value data size %d larger than "
     2522                      "%d, truncating...", length, REGFI_VK_MAX_DATA_LENGTH);
     2523    length = REGFI_VK_MAX_DATA_LENGTH;
     2524  }
    24912525
    24922526  if(data_in_offset)
  • trunk/src/common.c

    r159 r160  
    145145
    146146/*
    147  * Convert from UTF-16LE to ASCII.  Accepts a Unicode buffer, uni, and
    148  * it's length, uni_max.  Writes ASCII to the buffer ascii, whose size
    149  * is ascii_max.  Writes at most (ascii_max-1) bytes to ascii, and null
    150  * terminates the string.  Returns the length of the data written to
    151  * ascii.  On error, returns a negative errno code.
    152  */
    153 static int uni_to_ascii(unsigned char* uni, char* ascii,
    154                         uint32 uni_max, uint32 ascii_max)
    155 {
    156   char* inbuf = (char*)uni;
    157   char* outbuf = ascii;
    158   size_t in_len = (size_t)uni_max;
    159   size_t out_len = (size_t)(ascii_max-1);
    160   int ret;
    161 
    162   conv_desc = iconv_open("US-ASCII//TRANSLIT", "UTF-16LE");
    163 
    164   ret = iconv(conv_desc, &inbuf, &in_len, &outbuf, &out_len);
    165   if(ret == -1)
    166   {
    167     iconv_close(conv_desc);
    168     return -errno;
    169   }
    170   *outbuf = '\0';
    171 
    172   iconv_close(conv_desc); 
    173   return ascii_max-out_len-1;
    174 }
    175 
    176 
    177 static char* quote_unicode(unsigned char* uni, uint32 length,
    178                            const char* special, char** error_msg)
    179 {
    180   char* ret_val;
    181   char* ascii = NULL;
    182   char* tmp_err;
    183   int ret_err;
    184   *error_msg = NULL;
    185 
    186   if(length+1 > 0)
    187     ascii = malloc(length+1);
    188   if(ascii == NULL)
    189   {
    190     *error_msg = (char*)malloc(27);
    191     if(*error_msg == NULL)
    192       return NULL;
    193     strcpy(*error_msg, "Memory allocation failure.");
    194     return NULL;
    195   }
    196  
    197   ret_err = uni_to_ascii(uni, ascii, length, length+1);
    198   if(ret_err < 0)
    199   {
    200     free(ascii);
    201     tmp_err = strerror(-ret_err);
    202     *error_msg = (char*)malloc(61+strlen(tmp_err));
    203     if(*error_msg == NULL)
    204       return NULL;
    205 
    206     sprintf(*error_msg,
    207             "Unicode conversion failed with '%s'. Quoting as binary.", tmp_err);
    208     ret_val = quote_buffer(uni, length, special);
    209   }
    210   else
    211   {
    212     ret_val = quote_string(ascii, special);
    213     free(ascii);
    214   }
    215  
    216   return ret_val;
    217 }
    218 
    219 
    220 /*
    221147 * Convert a data value to a string for display.  Returns NULL on error,
    222148 * and the string to display if there is no error, or a non-fatal
  • trunk/src/reglookup-recover.c

    r159 r160  
    6666}
    6767
    68 
     68/* XXX: Somewhere in here, need to start looking for and handling classnames */
    6969void printKey(REGFI_FILE* f, REGFI_NK_REC* nk, const char* prefix)
    7070{
  • trunk/src/reglookup.c

    r159 r160  
    282282  char* dacl = NULL;
    283283  char* quoted_classname;
    284   char* error_msg = NULL;
    285284  char mtime[20];
    286285  time_t tmp_time[1];
     
    288287  const REGFI_SK_REC* sk;
    289288  const REGFI_NK_REC* k = regfi_iterator_cur_key(iter);
     289  REGFI_CLASSNAME* classname;
    290290
    291291  *tmp_time = nt_time_to_unix(&k->mtime);
     
    308308      dacl = empty_str;
    309309
    310     if(k->classname != NULL)
    311     {
    312       quoted_classname = quote_unicode((uint8*)k->classname, k->classname_length,
    313                                        key_special_chars, &error_msg);
     310    classname = regfi_iterator_fetch_classname(iter, k);
     311    printMsgs(iter->f);
     312    if(classname != NULL)
     313    {
     314      if(classname->interpreted == NULL)
     315      {
     316        fprintf(stderr, "WARN: Could not convert class name"
     317                " charset for key '%s'.  Quoting raw...\n", full_path);
     318        quoted_classname = quote_buffer(classname->raw, classname->size,
     319                                        key_special_chars);
     320      }
     321      else
     322        quoted_classname = quote_string(classname->interpreted,
     323                                        key_special_chars);
     324
    314325      if(quoted_classname == NULL)
    315326      {
    316         if(error_msg == NULL)
    317           fprintf(stderr, "ERROR: Could not quote classname"
    318                   " for key '%s' due to unknown error.\n", full_path);
    319         else
    320         {
    321           fprintf(stderr, "ERROR: Could not quote classname"
    322                   " for key '%s' due to error: %s\n", full_path, error_msg);
    323           free(error_msg);
    324         }
    325       }
    326       else if (error_msg != NULL)
    327       {
    328         if(print_verbose)
    329           fprintf(stderr, "INFO: While converting classname"
    330                   " for key '%s': %s.\n", full_path, error_msg);
    331         free(error_msg);
     327        fprintf(stderr, "ERROR: Could not quote classname"
     328                " for key '%s' due to unknown error.\n", full_path);
     329        quoted_classname = empty_str;
    332330      }
    333331    }
    334332    else
    335333      quoted_classname = empty_str;
     334    regfi_free_classname(classname);
    336335
    337336    printMsgs(iter->f);
Note: See TracChangeset for help on using the changeset viewer.