Changeset 8


Ignore:
Timestamp:
05/28/05 23:02:58 (20 years ago)
Author:
tim
Message:

Sped up type filtering by converting string types to integers up front

Eliminated some bcopy() calls.

Split quote_string() functionality out into quote_buffer().
Now using quote_buffer() to generate BIN output.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/reglookup.c

    r7 r8  
    22 * $Id$
    33 *
    4  * A utility to edit a Windows NT/2K etc registry file.
     4 * A utility to read a Windows NT/2K etc registry file.
    55 *
    66 * This code was taken from Richard Sharpe''s editreg utility, in the
     
    332332#define REG_TYPE_DWORD     4
    333333#define REG_TYPE_MULTISZ   7
     334/* Not a real type in the registry */
     335#define REG_TYPE_KEY       255
    334336
    335337typedef struct _val_str {
     
    403405
    404406char* prefix_filter = "";
    405 char* type_filter = "";
     407int type_filter = 0;
    406408bool type_filter_enabled = false;
    407409
     
    424426
    425427
    426 /* Returns a newly malloc()ed string which contains original string,
     428/* Returns a newly malloc()ed string which contains original buffer,
    427429 * except for non-printable or special characters are quoted in hex
    428430 * with the syntax '\xQQ' where QQ is the hex ascii value of the quoted
    429  * character.
    430  */
    431 static
    432 char* quote_string(const char* str, char* special)
     431 * character.  A null terminator is added, as only ascii, not binary,
     432 * is returned.
     433 */
     434static
     435char* quote_buffer(const unsigned char* str, char* special, unsigned int len)
    433436{
    434437  unsigned int i;
    435438  unsigned int num_written=0;
    436   unsigned int len = strlen(str);
    437439  unsigned int out_len = sizeof(char)*len+1;
    438440  char* ret_val = malloc(out_len);
     441
    439442  if(ret_val == NULL)
    440443    return NULL;
     
    445448    {
    446449      out_len += 3;
     450      /* XXX: may not be the most efficient way of getting enough memory. */
    447451      ret_val = realloc(ret_val, out_len);
    448452      if(ret_val == NULL)
    449453        break;
    450       num_written += snprintf(ret_val+num_written, out_len-num_written,
     454      num_written += snprintf(ret_val+num_written, (out_len)-num_written,
    451455                              "\\x%.2X", str[i]);
    452456    }
     
    458462  return ret_val;
    459463}
     464
     465
     466/* Returns a newly malloc()ed string which contains original string,
     467 * except for non-printable or special characters are quoted in hex
     468 * with the syntax '\xQQ' where QQ is the hex ascii value of the quoted
     469 * character.
     470 */
     471static
     472char* quote_string(const char* str, char* special)
     473{
     474  unsigned int len = strlen(str);
     475  char* ret_val = quote_buffer((const unsigned char*)str, special, len);
     476
     477  return ret_val;
     478}
     479
    460480
    461481
     
    533553  if (str_is_prefix(prefix_filter, new_path))
    534554  {
    535     if (!type_filter_enabled || (strcmp(type_filter, "KEY") == 0))
     555    if (!type_filter_enabled || (type_filter == REG_TYPE_KEY))
    536556      printf("%s%s:KEY\n", path, key_tree->name);
    537557
     
    797817  /*
    798818   * add the new key at the new slot
    799    * FIXME: Sort the list someday
     819   * XXX: Sort the list someday
    800820   */
    801821
     
    876896   { REG_TYPE_DWORD,    "DWORD" },
    877897   { REG_TYPE_MULTISZ,  "MULTI_SZ" },
    878    /*   { REG_TYPE_KEY,      "KEY" },*/
     898   { REG_TYPE_KEY,      "KEY" },
    879899   { 0, NULL },
    880900};
    881901
     902
    882903static
    883904const char *val_to_str(unsigned int val, const VAL_STR *val_array)
    884905{
    885   int i = 0;
    886 
    887   if (!val_array) return NULL;
    888 
    889   while (val_array[i].val && val_array[i].str) {
    890 
    891     if (val_array[i].val == val) return val_array[i].str;
    892     i++;
    893 
    894   }
     906  int i;
     907
     908  if (!val_array)
     909    return NULL;
     910
     911  for(i=0; val_array[i].val && val_array[i].str; i++)
     912    if (val_array[i].val == val)
     913      return val_array[i].str;
    895914
    896915  return NULL;
    897 
    898 }
     916}
     917
     918
     919/* Returns 0 on error */
     920static
     921int str_to_val(const char* str, const VAL_STR *val_array)
     922{
     923  int i;
     924
     925  if (!val_array)
     926    return 0;
     927
     928  for(i=0; val_array[i].val && val_array[i].str; i++)
     929    if (strcmp(val_array[i].str, str) == 0)
     930      return val_array[i].val;
     931
     932  return 0;
     933}
     934
    899935
    900936/*
     
    947983      return NULL;
    948984   
    949     /* FIXME. This has to be fixed. It has to be UNICODE */
     985    /* XXX: This has to be fixed. It has to be UNICODE */
    950986    uni_to_ascii(datap, ascii, len, ascii_max);
    951987    return ascii;
     
    963999
    9641000  case REG_TYPE_BIN:
    965     ascii_max = sizeof(char)*len*3;
    966     ascii = malloc(ascii_max+4);
    967     if(ascii == NULL)
    968       return NULL;
    969 
    970     asciip = ascii;
    971     for (i=0; (i<len)&&(i+1)*3<ascii_max; i++) {
    972       int str_rem = ascii_max - ((int)asciip - (int)ascii);
    973       asciip += snprintf((char*)asciip, str_rem, "%02x",
    974                          *(unsigned char *)(datap+i));
    975       if (i < len && str_rem > 0)
    976         *asciip = ' '; asciip++;       
    977     }
    978     *asciip = '\0';
     1001    ascii = (unsigned char*)quote_buffer(datap, "\\", len);
    9791002    return ascii;
    9801003    break;
     
    10251048      {
    10261049        uni_to_ascii(cur_str, cur_ascii, cur_str_max, 0);
     1050        /* XXX: Should backslashes be quoted as well? */
    10271051        cur_quoted = quote_string((char*)cur_ascii, "|");
    10281052        alen = snprintf((char*)asciip, str_rem, "%s", cur_quoted);
     
    12591283  tmp = (ACE *)malloc(sizeof(ACE));
    12601284
    1261   if (!tmp) return NULL;
     1285  if (!tmp)
     1286    return NULL;
    12621287
    12631288  tmp->type = CVAL(&ace->type);
     
    12921317    tmp->aces[i] = dup_ace(ace);
    12931318    ace = (REG_ACE *)((char *)ace + SVAL(&ace->length));
    1294     /* XXX: FIXME, should handle malloc errors */
     1319    /* XXX: should handle NULLs returned from dup_ace() */
    12951320  }
    12961321
     
    14931518    { /* The data is pointed to by the offset */
    14941519      char *dat_ptr = LOCN(regf->base, dat_off);
    1495       /* XXX: replace with memcpy */
    1496       bcopy(dat_ptr, dtmp, dat_len);
     1520      memcpy(dtmp, dat_ptr, dat_len);
    14971521    }
    14981522    else { /* The data is in the offset or type */
    14991523      /*
    1500        * FIXME.
     1524       * XXX:
    15011525       * Some registry files seem to have wierd fields. If top bit is set,
    15021526       * but len is 0, the type seems to be the value ...
     
    15041528       */
    15051529      dat_len = dat_len & 0x7FFFFFFF;
    1506       /* XXX: replace with memcpy */
    1507       bcopy(&dat_off, dtmp, dat_len);
     1530      memcpy(dtmp, &dat_off, dat_len);
    15081531    }
    15091532
     
    15641587
    15651588 error:
    1566   /* XXX: FIXME, free the partially allocated structure */
     1589  /* XXX: free the partially allocated structure */
    15671590  return NULL;
    15681591}
     
    17101733   
    17111734    /*
     1735     * XXX:
    17121736     * I am keeping class name as an ascii string for the moment.
    17131737     * That means it needs to be converted on output.
    17141738     * It will also piss off people who need Unicode/UTF-8 strings. Sorry.
    1715      * XXX: FIXME
    17161739     */
    17171740    tmp->class_name = strdup((char*)cls_name);
     
    20992122  unsigned char* data_asc;
    21002123  char* new_path;
    2101   const char* str_type = val_to_str(val_type,reg_type_names);
     2124  const char* str_type;
    21022125
    21032126  if(!val_name)
    21042127    val_name = "";
    2105   if(!str_type)
    2106     str_type = "";
    21072128  if(!path)
    21082129    path = "";
     
    21172138  if (str_is_prefix(prefix_filter, new_path))
    21182139  {
    2119     if (!type_filter_enabled || (strcmp(type_filter, str_type) == 0))
     2140    if (!type_filter_enabled || (type_filter == val_type))
    21202141    {
    21212142      if(!val_name)
    21222143        val_name = "<No Name>";
     2144
     2145      str_type = val_to_str(val_type,reg_type_names);
     2146      if(!str_type)
     2147        str_type = "";
    21232148     
    21242149      data_asc = data_to_ascii((unsigned char *)data_blk, data_len, val_type);
     
    21382163  fprintf(stderr, "Usage: readreg [-f<PREFIX_FILTER>] [-t<TYPE_FILTER>] "
    21392164                  "[-v] [-p] [-k] [-s] <REGISTRY_FILE>\n");
     2165  /* XXX: replace version string with Subversion tag? */
    21402166  fprintf(stderr, "Version: 0.1\n");
    21412167  fprintf(stderr, "\n\t-v\t sets verbose mode.");
     
    21762202
    21772203    case 't':
    2178       /* XXX: this should be converted to the integer form of types up front,
    2179        *      and then used to filter with a simple comparison later.
    2180        */
    2181       type_filter = strdup(optarg);
     2204      type_filter = str_to_val(optarg, reg_type_names);
    21822205      type_filter_enabled = true;
    21832206      regf_opt++;
Note: See TracChangeset for help on using the changeset viewer.