Changeset 41 for trunk/src


Ignore:
Timestamp:
07/31/05 21:13:15 (19 years ago)
Author:
tim
Message:

Added full printing of values, as with old code.

renamed type conversion functions to follow precedent.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/reglookup.c

    r40 r41  
    4646
    4747
     48/* Returns a newly malloc()ed string which contains original buffer,
     49 * except for non-printable or special characters are quoted in hex
     50 * with the syntax '\xQQ' where QQ is the hex ascii value of the quoted
     51 * character.  A null terminator is added, as only ascii, not binary,
     52 * is returned.
     53 */
     54static char* quote_buffer(const unsigned char* str,
     55                          unsigned int len, char* special)
     56{
     57  unsigned int i;
     58  unsigned int num_written=0;
     59  unsigned int out_len = sizeof(char)*len+1;
     60  char* ret_val = malloc(out_len);
     61
     62  if(ret_val == NULL)
     63    return NULL;
     64
     65  for(i=0; i<len; i++)
     66  {
     67    if(str[i] < 32 || str[i] > 126 || strchr(special, str[i]) != NULL)
     68    {
     69      out_len += 3;
     70      /* XXX: may not be the most efficient way of getting enough memory. */
     71      ret_val = realloc(ret_val, out_len);
     72      if(ret_val == NULL)
     73        break;
     74      num_written += snprintf(ret_val+num_written, (out_len)-num_written,
     75                              "\\x%.2X", str[i]);
     76    }
     77    else
     78      ret_val[num_written++] = str[i];
     79  }
     80  ret_val[num_written] = '\0';
     81
     82  return ret_val;
     83}
     84
     85
     86/* Returns a newly malloc()ed string which contains original string,
     87 * except for non-printable or special characters are quoted in hex
     88 * with the syntax '\xQQ' where QQ is the hex ascii value of the quoted
     89 * character.
     90 */
     91static char* quote_string(const char* str, char* special)
     92{
     93  unsigned int len = strlen(str);
     94  char* ret_val = quote_buffer((const unsigned char*)str, len, special);
     95
     96  return ret_val;
     97}
     98
     99
     100/*
     101 * Convert from UniCode to Ascii ... Does not take into account other lang
     102 * Restrict by ascii_max if > 0
     103 */
     104static int uni_to_ascii(unsigned char *uni, unsigned char *ascii,
     105                        int ascii_max, int uni_max)
     106{
     107  int i = 0;
     108
     109  while (i < ascii_max && (uni[i*2] || uni[i*2+1]))
     110  {
     111    if (uni_max > 0 && (i*2) >= uni_max) break;
     112    ascii[i] = uni[i*2];
     113    i++;
     114  }
     115  ascii[i] = '\0';
     116
     117  return i;
     118}
     119
     120
     121/*
     122 * Convert a data value to a string for display
     123 */
     124static unsigned char* data_to_ascii(unsigned char *datap, int len, int type)
     125{
     126  unsigned char *asciip;
     127  unsigned int i;
     128  unsigned short num_nulls;
     129  unsigned char* ascii;
     130  unsigned char* cur_str;
     131  unsigned char* cur_ascii;
     132  char* cur_quoted;
     133  unsigned int cur_str_len;
     134  unsigned int ascii_max, cur_str_max;
     135  unsigned int str_rem, cur_str_rem, alen;
     136
     137  switch (type)
     138  {
     139  case REG_SZ:
     140    if (print_verbose)
     141      fprintf(stderr, "Len: %d\n", len);
     142   
     143    ascii_max = sizeof(char)*len;
     144    ascii = malloc(ascii_max+4);
     145    if(ascii == NULL)
     146      return NULL;
     147   
     148    /* XXX: This has to be fixed. It has to be UNICODE */
     149    uni_to_ascii(datap, ascii, len, ascii_max);
     150    return ascii;
     151    break;
     152
     153  case REG_EXPAND_SZ:
     154    ascii_max = sizeof(char)*len;
     155    ascii = malloc(ascii_max+2);
     156    if(ascii == NULL)
     157      return NULL;
     158
     159    uni_to_ascii(datap, ascii, len, ascii_max);
     160    return ascii;
     161    break;
     162
     163  case REG_BINARY:
     164    ascii = (unsigned char*)quote_buffer(datap, len, "\\");
     165    return ascii;
     166    break;
     167
     168  case REG_DWORD:
     169    ascii_max = sizeof(char)*10;
     170    ascii = malloc(ascii_max+1);
     171    if(ascii == NULL)
     172      return NULL;
     173
     174    if (*(int *)datap == 0)
     175      snprintf((char*)ascii, ascii_max, "0");
     176    else
     177      snprintf((char*)ascii, ascii_max, "0x%x", *(int *)datap);
     178    return ascii;
     179    break;
     180
     181  case REG_MULTI_SZ:
     182    ascii_max = sizeof(char)*len*4;
     183    cur_str_max = sizeof(char)*len+1;
     184    cur_str = malloc(cur_str_max);
     185    cur_ascii = malloc(cur_str_max);
     186    ascii = malloc(ascii_max+4);
     187    if(ascii == NULL)
     188      return NULL;
     189
     190    /* Reads until it reaches 4 consecutive NULLs,
     191     * which is two nulls in unicode, or until it reaches len, or until we
     192     * run out of buffer.  The latter should never happen, but we shouldn't
     193     * trust our file to have the right lengths/delimiters.
     194     */
     195    asciip = ascii;
     196    num_nulls = 0;
     197    str_rem = ascii_max;
     198    cur_str_rem = cur_str_max;
     199    cur_str_len = 0;
     200
     201    for(i=0; (i < len) && str_rem > 0; i++)
     202    {
     203      *(cur_str+cur_str_len) = *(datap+i);
     204      if(*(cur_str+cur_str_len) == 0)
     205        num_nulls++;
     206      else
     207        num_nulls = 0;
     208      cur_str_len++;
     209
     210      if(num_nulls == 2)
     211      {
     212        uni_to_ascii(cur_str, cur_ascii, cur_str_max, 0);
     213        /* XXX: Should backslashes be quoted as well? */
     214        cur_quoted = quote_string((char*)cur_ascii, "|");
     215        alen = snprintf((char*)asciip, str_rem, "%s", cur_quoted);
     216        asciip += alen;
     217        str_rem -= alen;
     218        free(cur_quoted);
     219
     220        if(*(datap+i+1) == 0 && *(datap+i+2) == 0)
     221          break;
     222        else
     223        {
     224          alen = snprintf((char*)asciip, str_rem, "%c", '|');
     225          asciip += alen;
     226          str_rem -= alen;
     227          memset(cur_str, 0, cur_str_max);
     228          cur_str_len = 0;
     229          num_nulls = 0;
     230          /* To eliminate leading nulls in subsequent strings. */
     231          i++;
     232        }
     233      }
     234    }
     235    *asciip = 0;
     236    return ascii;
     237    break;
     238
     239  default:
     240    return NULL;
     241    break;
     242  }
     243
     244  return NULL;
     245}
     246
     247
    48248void_stack* path2Stack(const char* s)
    49249{
     
    141341void printValue(REGF_VK_REC* vk, char* prefix)
    142342{
     343  uint32 size;
     344  uint8 tmp_buf[4];
     345  char* quoted_value;
     346
    143347  if(!type_filter_enabled || (vk->type == type_filter))
    144     printf("%s/%s:%s=\n", prefix, vk->valuename, type_val2str(vk->type));
     348  {
     349    /* Thanks Microsoft for making this process so straight-forward!!! */
     350    size = (vk->data_size & ~VK_DATA_IN_OFFSET);
     351    if(vk->data_size & VK_DATA_IN_OFFSET)
     352    {
     353      tmp_buf[0] = (uint8)((vk->data_off >> 3) & 0xFF);
     354      tmp_buf[1] = (uint8)((vk->data_off >> 2) & 0xFF);
     355      tmp_buf[2] = (uint8)((vk->data_off >> 1) & 0xFF);
     356      tmp_buf[3] = (uint8)(vk->data_off & 0xFF);
     357      if(size > 4)
     358        size = 4;
     359      quoted_value = data_to_ascii(tmp_buf, 4, vk->type);
     360    }
     361    else
     362    {
     363      /* XXX: This is a safety hack.  No data fields have yet been found
     364       * larger, but length limits are probably better got from fields
     365       * in the registry itself, within reason.
     366       */
     367      if(size > 16384)
     368      {
     369        printf("WARNING: key size %d larger than 16384, truncating...\n", size);
     370        size = 16384;
     371      }
     372      quoted_value = data_to_ascii(vk->data, vk->data_size, vk->type);
     373    }
     374
     375    printf("%s/%s:%s=%s\n", prefix, vk->valuename,
     376           regfio_type_val2str(vk->type), quoted_value);
     377  }
    145378}
    146379
     
    162395  char* path;
    163396  char* val_path;
    164   int key_type = type_str2val("KEY");
     397  int key_type = regfio_type_str2val("KEY");
    165398
    166399  if((cur = (REGF_NK_REC*)void_stack_cur(nk_stack)) != NULL)
     
    338571        bailOut(1, "ERROR: '-t' option requires parameter.\n");
    339572      }
    340       if((type_filter = type_str2val(argv[argi])) == 0)
     573      if((type_filter = regfio_type_str2val(argv[argi])) == 0)
    341574      {
    342575        fprintf(stderr, "ERROR: Invalid type specified: %s.\n", argv[argi]);
Note: See TracChangeset for help on using the changeset viewer.