Changeset 61


Ignore:
Timestamp:
07/17/06 21:56:59 (18 years ago)
Author:
tim
Message:

various minor speedups and memory leak fixes. Added support for NONE and LINK types.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/regfio.h

    r54 r61  
    66 * Windows NT registry I/O library
    77 *
    8  * Copyright (C) 2005 Timothy D. Morgan
     8 * Copyright (C) 2005-2006 Timothy D. Morgan
    99 * Copyright (C) 2005 Gerald (Jerry) Carter
    1010 *
     
    6767#define REG_KEY                        255
    6868
    69 typedef struct _val_str {
    70   unsigned int val;
    71   const char * str;
    72 } VAL_STR;
    7369
    7470#define REGF_BLOCKSIZE          0x1000
  • trunk/lib/regfio.c

    r59 r61  
    66 * Windows NT registry I/O library
    77 *
    8  * Copyright (C) 2005 Timothy D. Morgan
     8 * Copyright (C) 2005-2006 Timothy D. Morgan
    99 * Copyright (C) 2005 Gerald (Jerry) Carter
    1010 *
     
    2828
    2929
    30 
    3130/* Registry types mapping */
    32 const VAL_STR reg_type_names[] =
    33 {
    34   { REG_SZ,                        "SZ"           },
    35   { REG_EXPAND_SZ,                 "EXPAND_SZ"    },
    36   { REG_BINARY,                    "BINARY"       },
    37   { REG_DWORD,                     "DWORD"        },
    38   { REG_DWORD_BE,                  "DWORD_BE"     },
    39   { REG_LINK,                      "LINK"         },
    40   { REG_MULTI_SZ,                  "MULTI_SZ"     },
    41   { REG_RESOURCE_LIST,             "RSRC_LIST"    },
    42   { REG_FULL_RESOURCE_DESCRIPTOR,  "RSRC_DESC"    },
    43   { REG_RESOURCE_REQUIREMENTS_LIST,"RSRC_REQ_LIST"},
    44   { REG_KEY,                       "KEY"          },
    45   { 0,                             NULL           },
    46 };
     31const unsigned int regfio_num_reg_types = 11;
     32static const char* regfio_type_names[] =
     33  {"NONE", "SZ", "EXPAND_SZ", "BINARY", "DWORD", "DWORD_BE", "LINK"
     34   "MULTI_SZ", "RSRC_LIST", "RSRC_DESC", "RSRC_REQ_LIST"};
    4735
    4836
     
    5038const char* regfio_type_val2str(unsigned int val)
    5139{
     40  if(val == REG_KEY)
     41    return "KEY";
     42 
     43  if(val >= regfio_num_reg_types)
     44    return NULL;
     45 
     46  return regfio_type_names[val];
     47}
     48
     49
     50/* Returns -1 on error */
     51int regfio_type_str2val(const char* str)
     52{
    5253  int i;
    5354
    54   for(i=0; reg_type_names[i].val && reg_type_names[i].str; i++)
    55     if (reg_type_names[i].val == val)
    56       return reg_type_names[i].str;
    57 
    58   return NULL;
    59 }
    60 
    61 
    62 /* Returns 0 on error */
    63 int regfio_type_str2val(const char* str)
    64 {
    65   int i;
    66 
    67   for(i=0; reg_type_names[i].val && reg_type_names[i].str; i++)
    68     if (strcmp(reg_type_names[i].str, str) == 0)
    69       return reg_type_names[i].val;
    70 
    71   return 0;
     55  if(strcmp("KEY", str) == 0)
     56    return REG_KEY;
     57
     58  for(i=0; i < regfio_num_reg_types; i++)
     59    if (strcmp(regfio_type_names[i], str) == 0)
     60      return i;
     61
     62  if(strcmp("DWORD_LE", str) == 0)
     63    return REG_DWORD_LE;
     64
     65  return -1;
    7266}
    7367
     
    182176  char* perms_str;
    183177  char* sid_str;
     178  char* ace_delim = "";
    184179  char* ret_val = NULL;
    185   char* ace_delim = "";
     180  char* tmp_val = NULL;
     181  bool failed = false;
    186182  char field_delim = ':';
    187183
    188   for (i = 0; i < acl->num_aces; i++)
     184  for (i = 0; i < acl->num_aces && !failed; i++)
    189185  {
    190186    sid_str = regfio_sid2str(&acl->ace[i].trustee);
     
    193189    flags_str = regfio_ace_flags2str(acl->ace[i].flags);
    194190   
    195     if(flags_str == NULL || perms_str == NULL
    196        || type_str == NULL || sid_str == NULL)
    197       return NULL;
    198 
    199     /* XXX: this is slow */
    200     extra = strlen(sid_str) + strlen(type_str)
    201           + strlen(perms_str) + strlen(flags_str)+5;
    202     ret_val = realloc(ret_val, size+extra);
    203     if(ret_val == NULL)
    204       return NULL;
    205     size += snprintf(ret_val+size, extra, "%s%s%c%s%c%s%c%s",
    206                      ace_delim,sid_str,
    207                      field_delim,type_str,
    208                      field_delim,perms_str,
    209                      field_delim,flags_str);
    210     ace_delim = "|";
    211     free(sid_str);
    212     free(perms_str);
    213     free(flags_str);
     191    if(flags_str != NULL && perms_str != NULL
     192       && type_str != NULL && sid_str != NULL)
     193    {
     194      /* XXX: this is slow */
     195      extra = strlen(sid_str) + strlen(type_str)
     196        + strlen(perms_str) + strlen(flags_str)+5;
     197      tmp_val = realloc(ret_val, size+extra);
     198
     199      if(tmp_val == NULL)
     200      {
     201        free(ret_val);
     202        failed = true;
     203      }
     204      else
     205      {
     206        ret_val = tmp_val;
     207        size += snprintf(ret_val+size, extra, "%s%s%c%s%c%s%c%s",
     208                         ace_delim,sid_str,
     209                         field_delim,type_str,
     210                         field_delim,perms_str,
     211                         field_delim,flags_str);
     212        ace_delim = "|";
     213      }
     214    }
     215    else
     216      failed = true;
     217
     218    if(sid_str != NULL)
     219      free(sid_str);
     220    if(sid_str != NULL)
     221      free(perms_str);
     222    if(sid_str != NULL)
     223      free(flags_str);
    214224  }
    215225
     
    254264                       uint32 block_size )
    255265{
     266  const int hdr_size = 0x20;
    256267  int bytes_read, returned;
    257268  char *buffer;
     
    279290    }
    280291
    281     returned = read( file->fd, hdr, 0x20 );
    282     if ( (returned == -1) || (returned < 0x20) ) {
    283       /*DEBUG(0,("read_block: failed to read in HBIN header. Is the file corrupt?\n"));*/
    284       return -1;
     292    bytes_read = returned = 0;
     293    while (bytes_read < hdr_size)
     294    {
     295      returned = read(file->fd, hdr + bytes_read, hdr_size - bytes_read);
     296      if(returned == -1 && errno != EINTR && errno != EAGAIN)
     297      {
     298        /*DEBUG(0,("read_block: read of hdr failed (%s)\n",strerror(errno)));*/
     299        return -1;
     300      }
     301
     302      if(returned == 0)
     303        return -1;
     304
     305      bytes_read += returned;
    285306    }
    286307
     
    310331  while ( bytes_read < block_size )
    311332  {
    312     if((returned =
    313         read(file->fd, buffer+bytes_read, block_size-bytes_read)) == -1)
     333    returned = read(file->fd, buffer+bytes_read, block_size-bytes_read);
     334    if(returned == -1 && errno != EINTR && errno != EAGAIN)
    314335    {
    315336      /*DEBUG(0,("read_block: read() failed (%s)\n", strerror(errno) ));*/
    316       return false;
    317     }
     337      return -1;
     338    }
     339
    318340    if ((returned == 0) && (bytes_read < block_size))
    319341    {
    320342      /*DEBUG(0,("read_block: not a vald registry file ?\n" ));*/
    321       return false;
     343      return -1;
    322344    }   
    323345
  • trunk/src/reglookup.c

    r59 r61  
    33 * Gerald Carter''s regfio interface.
    44 *
    5  * Copyright (C) 2005 Timothy D. Morgan
     5 * Copyright (C) 2005-2006 Timothy D. Morgan
    66 * Copyright (C) 2002 Richard Sharpe, rsharpe@richardsharpe.com
    77 *
     
    2828#include <strings.h>
    2929#include <time.h>
     30#include <iconv.h>
    3031#include "../include/regfio.h"
    3132#include "../include/void_stack.h"
     
    4344/* Other globals */
    4445const char* special_chars = ",\"\\";
     46iconv_t conv_desc;
     47
    4548
    4649void bailOut(int code, char* message)
     
    5457 * except for non-printable or special characters are quoted in hex
    5558 * with the syntax '\xQQ' where QQ is the hex ascii value of the quoted
    56  * character.  A null terminator is added, as only ascii, not binary,
     59 * character.  A null terminator is added, since only ascii, not binary,
    5760 * is returned.
    5861 */
     
    6063                          unsigned int len, const char* special)
    6164{
    62   unsigned int i;
    63   unsigned int num_written=0;
    64   unsigned int out_len = sizeof(char)*len+1;
    65   char* ret_val = malloc(out_len);
     65  unsigned int i, added_len;
     66  unsigned int num_written = 0;
     67
     68  unsigned int buf_len = sizeof(char)*(len+1);
     69  char* ret_val = malloc(buf_len);
     70  char* tmp_buf;
    6671
    6772  if(ret_val == NULL)
     
    7075  for(i=0; i<len; i++)
    7176  {
     77    if(buf_len <= (num_written+5))
     78    {
     79      /* Expand the buffer by the memory consumption rate seen so far
     80       * times the amount of input left to process.  The expansion is bounded
     81       * below by a minimum safety increase, and above by the maximum possible
     82       * output string length.
     83       */
     84      added_len = (len-i)*num_written/(i+1);
     85      if((buf_len+added_len) > (len*4+1))
     86        buf_len = len*4+1;
     87      else
     88      {
     89        if (added_len < 5)
     90          buf_len += 5;
     91        else
     92          buf_len += added_len;
     93      }
     94
     95      tmp_buf = realloc(ret_val, buf_len);
     96      if(tmp_buf == NULL)
     97      {
     98        free(ret_val);
     99        return NULL;
     100      }
     101      ret_val = tmp_buf;
     102    }
     103   
    72104    if(str[i] < 32 || str[i] > 126 || strchr(special, str[i]) != NULL)
    73105    {
    74       out_len += 3;
    75       /* XXX: may not be the most efficient way of getting enough memory. */
    76       ret_val = realloc(ret_val, out_len);
    77       if(ret_val == NULL)
    78         break;
    79       num_written += snprintf(ret_val+num_written, (out_len)-num_written,
     106      num_written += snprintf(ret_val + num_written, buf_len - num_written,
    80107                              "\\x%.2X", str[i]);
    81108    }
     
    107134
    108135/*
    109  * Convert from UniCode to Ascii ... Does not take into account other lang
    110  * Restrict by ascii_max if > 0
     136 * Convert from Unicode to ASCII.
    111137 */
    112 static int uni_to_ascii(unsigned char *uni, unsigned char *ascii,
    113                         int ascii_max, int uni_max)
    114 {
    115   int i = 0;
    116 
    117   while (i < ascii_max && (uni[i*2] || uni[i*2+1]))
    118   {
    119     if (uni_max > 0 && (i*2) >= uni_max) break;
    120     ascii[i] = uni[i*2];
    121     i++;
    122   }
    123   ascii[i] = '\0';
    124 
    125   return i;
     138static int uni_to_ascii(unsigned char* uni, char* ascii,
     139                        unsigned int uni_max, unsigned int ascii_max)
     140{
     141  char* inbuf = (char*)uni;
     142  char* outbuf = ascii;
     143  int ret;
     144
     145  /* Set up conversion descriptor. */
     146  conv_desc = iconv_open("US-ASCII", "UTF-16LE");
     147
     148  ret = iconv(conv_desc, &inbuf, &uni_max, &outbuf, &ascii_max);
     149  if(ret == -1)
     150  {
     151    iconv_close(conv_desc);
     152    return -1;
     153  }
     154
     155  iconv_close(conv_desc); 
     156  return strlen(ascii);
    126157}
    127158
     
    130161 * Convert a data value to a string for display
    131162 */
    132 static unsigned char* data_to_ascii(unsigned char *datap, int len, int type)
    133 {
    134   unsigned char *asciip;
     163static char* data_to_ascii(unsigned char *datap, int len, int type)
     164{
     165  char* asciip;
    135166  unsigned int i;
    136167  unsigned short num_nulls;
    137   unsigned char* ascii;
     168  char* ascii;
    138169  unsigned char* cur_str;
    139   unsigned char* cur_ascii;
     170  char* cur_ascii;
    140171  char* cur_quoted;
    141172  unsigned int cur_str_len;
     
    145176  switch (type)
    146177  {
     178    /* REG_LINK is a symbolic link, stored as a unicode string. */
     179  case REG_LINK:
    147180  case REG_SZ:
    148181    ascii_max = sizeof(char)*len;
     
    151184      return NULL;
    152185   
    153     /* XXX: This has to be fixed. It has to be UNICODE */
    154     uni_to_ascii(datap, ascii, len, ascii_max);
    155     cur_quoted = quote_string((char*)ascii, special_chars);
     186    if(uni_to_ascii(datap, ascii, len, ascii_max) < 0)
     187    {
     188      free(ascii);
     189      return NULL;
     190    }
     191    cur_quoted = quote_string(ascii, special_chars);
    156192    free(ascii);
    157     return (unsigned char*)cur_quoted;
     193    return cur_quoted;
    158194    break;
    159195
     196    /* XXX: This could be Unicode or ASCII.  Are we processing it
     197     *      correctly in both cases?
     198     */
    160199  case REG_EXPAND_SZ:
    161200    ascii_max = sizeof(char)*len;
     
    164203      return NULL;
    165204
    166     uni_to_ascii(datap, ascii, len, ascii_max);
    167     cur_quoted = quote_string((char*)ascii, special_chars);
     205    if(uni_to_ascii(datap, ascii, len, ascii_max) < 0)
     206    {
     207      free(ascii);
     208      return NULL;
     209    }
     210    cur_quoted = quote_string(ascii, special_chars);
    168211    free(ascii);
    169     return (unsigned char*)cur_quoted;
     212    return cur_quoted;
    170213    break;
    171214
     
    176219      return NULL;
    177220
    178     snprintf((char*)ascii, ascii_max, "0x%.2X%.2X%.2X%.2X",
     221    snprintf(ascii, ascii_max, "0x%.2X%.2X%.2X%.2X",
    179222             datap[0], datap[1], datap[2], datap[3]);
    180223    return ascii;
     
    187230      return NULL;
    188231
    189     snprintf((char*)ascii, ascii_max, "0x%.2X%.2X%.2X%.2X",
     232    snprintf(ascii, ascii_max, "0x%.2X%.2X%.2X%.2X",
    190233             datap[3], datap[2], datap[1], datap[0]);
    191234    return ascii;
     
    226269      if(num_nulls == 2)
    227270      {
    228         uni_to_ascii(cur_str, cur_ascii, cur_str_max, 0);
    229         cur_quoted = quote_string((char*)cur_ascii, ",|\"\\");
    230         alen = snprintf((char*)asciip, str_rem, "%s", cur_quoted);
     271        if(uni_to_ascii(cur_str, cur_ascii, cur_str_max, cur_str_max) < 0)
     272        {
     273          free(ascii);
     274          free(cur_ascii);
     275          free(cur_str);
     276          return NULL;
     277        }
     278
     279        cur_quoted = quote_string(cur_ascii, ",|\"\\");
     280        alen = snprintf(asciip, str_rem, "%s", cur_quoted);
    231281        asciip += alen;
    232282        str_rem -= alen;
     
    237287        else
    238288        {
    239           alen = snprintf((char*)asciip, str_rem, "%c", '|');
    240           asciip += alen;
    241           str_rem -= alen;
     289          if(str_rem > 0)
     290          {
     291            asciip[0] = '|';
     292            asciip[1] = '\0';
     293            asciip++;
     294            str_rem--;
     295          }
    242296          memset(cur_str, 0, cur_str_max);
    243297          cur_str_len = 0;
     
    255309
    256310  /* XXX: Dont know what to do with these yet, just print as binary... */
     311  case REG_NONE:
    257312  case REG_RESOURCE_LIST:
    258313  case REG_FULL_RESOURCE_DESCRIPTOR:
     
    260315
    261316  case REG_BINARY:
    262     return (unsigned char*)quote_buffer(datap, len, special_chars);
     317    return quote_buffer(datap, len, special_chars);
    263318    break;
    264319
     
    369424  uint32 size;
    370425  uint8 tmp_buf[4];
    371   unsigned char* quoted_value;
     426  char* quoted_value;
    372427  char* quoted_prefix;
    373428  char* quoted_name;
     
    397452      size = 16384;
    398453    }
     454
    399455    quoted_value = data_to_ascii(vk->data, vk->data_size, vk->type);
    400456  }
     
    443499  time_t tmp_time[1];
    444500  struct tm* tmp_time_s = NULL;
    445 
     501  char* quoted_path = NULL;
     502
     503  /* XXX: it would be faster to always pass a quoted string to this
     504   *      function, instead of re-quoting it every call. */
     505  /* XXX: check return of quote_string */
     506  quoted_path = quote_string(full_path, special_chars);
    446507  *tmp_time = nt_time_to_unix(&k->mtime);
    447508  tmp_time_s = gmtime(tmp_time);
     
    463524      dacl = empty_str;
    464525
    465     printf("%s,KEY,,%s,%s,%s,%s,%s\n", full_path, mtime,
     526    printf("%s,KEY,,%s,%s,%s,%s,%s\n", quoted_path, mtime,
    466527           owner, group, sacl, dacl);
    467528
     
    476537  }
    477538  else
    478     printf("%s,KEY,,%s\n", full_path, mtime);
     539    printf("%s,KEY,,%s\n", quoted_path, mtime);
     540
     541  free(quoted_path);
    479542}
    480543
     
    673736static void usage(void)
    674737{
    675   fprintf(stderr, "Usage: readreg [-v] [-s]"
     738  fprintf(stderr, "Usage: reglookup [-v] [-s]"
    676739          " [-p <PATH_FILTER>] [-t <TYPE_FILTER>]"
    677740          " <REGISTRY_FILE>\n");
    678741  /* XXX: replace version string with Subversion property? */
    679   fprintf(stderr, "Version: 0.2.2\n");
     742  fprintf(stderr, "Version: 0.3.0\n");
    680743  fprintf(stderr, "Options:\n");
    681744  fprintf(stderr, "\t-v\t sets verbose mode.\n");
     
    728791        bailOut(1, "ERROR: '-t' option requires parameter.\n");
    729792      }
    730       if((type_filter = regfio_type_str2val(argv[argi])) == 0)
     793      if((type_filter = regfio_type_str2val(argv[argi])) < 0)
    731794      {
    732795        fprintf(stderr, "ERROR: Invalid type specified: %s.\n", argv[argi]);
    733796        bailOut(1, "");
    734797      }
    735 
    736798      type_filter_enabled = true;
    737799    }
Note: See TracChangeset for help on using the changeset viewer.