Changeset 7933 for trunk/tools


Ignore:
Timestamp:
Feb 16, 2002, 5:29:55 PM (24 years ago)
Author:
sandervl
Message:

Wine update

Location:
trunk/tools/regedit
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/regedit/README

    r3424 r7933  
    2727  1 - Parse the before.reg and after.reg file into regFixer.pl, in order to
    2828      obtain lines in the form [HKEY\Sub1\Sub2\...\Subn]"Value"="Data" 
    29       (where "Data" can be prefixed by the type identifyer : hex:, hex(0000000?)
     29      (where "Data" can be prefixed by the type identifier : hex:, hex(0000000?)
    3030      or dword:)
    3131
     
    3434
    3535  Now we have a app.reg file that contain what has been done by installing the
    36   application.  To this we extract the part's that we are interested in using
     36  application.  To this we extract the parts that we are interested in using
    3737  grep (and fix it with sed) and put that into app.added by example
    38   ( let say we keep the added values only ).
     38  ( let's say we keep the added values only ).
    3939
    4040  At this point we know which registry entry to add to the wine registry.  It
     
    4343
    4444  I say "similar" because there is a tiny difference between Windows regedit
    45   export format and the format actualy required by the tool.
     45  export format and the format actually required by the tool.
    4646
    47   The problem with this (and it is not a big one) is that regedit export long
    48   data streams onto many lines, and since I dont have tons of time I setup
     47  The problem with this (and it is not a big one) is that regedit exports long
     48  data streams onto many lines, and since I don't have tons of time I setup
    4949  another Perl script (regRestorer.pl) that fixes this (this could easily
    50   be done in C obviously) (left as excercise ;-) ). 
     50  be done in C obviously) (left as exercise ;-) ). 
    5151   
    52   So, once you parsed app.added into regRestorer.pl you get a app.reg ready to
     52  So, once you parsed app.added into regRestorer.pl you get an app.reg ready to
    5353  process by regapi.
    5454
     
    6161                    something "regapi-able"
    6262 
    63   regSet          - Will do the procedure explained herein
     63  regSet.sh       - Will do the procedure explained herein
    6464                    for the added key only.
    6565
     
    7171  -----------------
    7272  1 - Get a snapshot of your windows registry in before.reg, (regedit/export)
    73   2 - Install you're application,
     73  2 - Install your application,
    7474  3 - Get a snapshot of your windows registry in after.reg.
    7575  4 - Invoke ./regSet.sh before.reg after.reg
  • trunk/tools/regedit/regapi.c

    r6565 r7933  
    6969#define QUERY_VALUE_MAX_ARGS  1
    7070
    71 static const char *setValueDelim[SET_VALUE_MAX_ARGS]   = {"=", ""}; 
    72 static const char *queryValueDelim[QUERY_VALUE_MAX_ARGS]   = {""}; 
    73 
    74 /* Array used to extract the data type from a string in getDataType. */
    75 typedef struct tagDataTypeMap
    76 {
    77   char  mask[15];
    78   DWORD dataType;
    79 } dataTypeMap;
    80  
    81 static const dataTypeMap typeMap[] =
    82 {
    83   {"hex:",            REG_BINARY},/* could be REG_NONE (?) */
    84   {"dword:",          REG_DWORD},
    85   {"hex(0):",         REG_NONE},
    86   {"hex(1):",         REG_SZ},
    87   {"hex(2):",         REG_EXPAND_SZ},
    88   {"hex(3):",         REG_BINARY},
    89   {"hex(4):",         REG_DWORD},
    90   {"hex(5):",         REG_DWORD_BIG_ENDIAN},
    91   {"hex(6):",         REG_LINK},
    92   {"hex(7):",         REG_MULTI_SZ},
    93   {"hex(8):",         REG_RESOURCE_LIST},
    94   {"hex(9):",         REG_FULL_RESOURCE_DESCRIPTOR},
    95   {"hex(10):",        REG_RESOURCE_REQUIREMENTS_LIST},
    96   {"hex(80000000):",  0x80000000},
    97   {"hex(80000001):",  0x80000001},
    98   {"hex(80000002):",  0x80000002},
    99   {"hex(80000003):",  0x80000003},
    100   {"hex(80000004):",  0x80000004},
    101   {"hex(80000005):",  0x80000005},
    102   {"hex(80000006):",  0x80000006},
    103   {"hex(80000007):",  0x80000007},
    104   {"hex(80000008):",  0x80000008},
    105   {"hex(80000009):",  0x80000000},
    106   {"hex(8000000a):",  0x8000000A}
    107 };
    108 const static int LAST_TYPE_MAP = sizeof(typeMap)/sizeof(dataTypeMap);
     71static const char *setValueDelim[SET_VALUE_MAX_ARGS]   = {"=", ""};
     72static const char *queryValueDelim[QUERY_VALUE_MAX_ARGS]   = {""};
    10973
    11074
     
    164128 * Generic prototypes
    165129 */
    166 static DWORD   getDataType(LPSTR *lpValue);
     130static DWORD   getDataType(LPSTR *lpValue, DWORD* parse_type);
    167131static LPSTR   getRegKeyName(LPSTR lpLine);
    168132static HKEY    getRegClass(LPSTR lpLine);
     
    250214"                                February 1999.\n"
    251215;
    252              
     216
    253217
    254218/******************************************************************************
     
    256220 * value.  It modifies the input parameter (key value) in order to skip this
    257221 * "now useless" data type information.
    258  */
    259 DWORD getDataType(LPSTR *lpValue)
    260 {
    261   INT   counter  = 0;
    262   DWORD dwReturn = REG_SZ;
    263 
    264   for (; counter < LAST_TYPE_MAP; counter++)
    265   {
    266     LONG len = strlen(typeMap[counter].mask);
    267     if ( strncasecmp( *lpValue, typeMap[counter].mask, len) == IDENTICAL)
     222 *
     223 * Note: Updated based on the algorithm used in 'server/registry.c'
     224 */
     225DWORD getDataType(LPSTR *lpValue, DWORD* parse_type)
     226{
     227    struct data_type { const char *tag; int len; int type; int parse_type; };
     228
     229    static const struct data_type data_types[] =
     230    {                   /* actual type */  /* type to assume for parsing */
     231        { "\"",        1,   REG_SZ,              REG_SZ },
     232        { "str:\"",    5,   REG_SZ,              REG_SZ },
     233        { "str(2):\"", 8,   REG_EXPAND_SZ,       REG_SZ },
     234        { "str(7):\"", 8,   REG_MULTI_SZ,        REG_SZ },
     235        { "hex:",      4,   REG_BINARY,          REG_BINARY },
     236        { "dword:",    6,   REG_DWORD,           REG_DWORD },
     237        { "hex(",      4,   -1,                  REG_BINARY },
     238        { NULL,        0,    0,                  0 }
     239    };
     240
     241    const struct data_type *ptr;
     242    int type;
     243
     244    for (ptr = data_types; ptr->tag; ptr++)
    268245    {
    269       /*
    270        * We found it, modify the value's pointer in order to skip the data
    271        * type identifier, set the return value and exit the loop.
    272        */
    273       (*lpValue) += len;
    274       dwReturn    = typeMap[counter].dataType;
    275       break;
    276     }
    277   }
    278 
    279   return dwReturn;
    280 }
     246        if (memcmp( ptr->tag, *lpValue, ptr->len ))
     247            continue;
     248
     249        /* Found! */
     250        *parse_type = ptr->parse_type;
     251        type=ptr->type;
     252        *lpValue+=ptr->len;
     253        if (type == -1) {
     254            char* end;
     255            /* "hex(xx):" is special */
     256            *lpValue += 4;
     257            type = (int)strtoul( *lpValue , &end, 16 );
     258            if (**lpValue=='\0' || *end!=')' || *(end+1)!=':') {
     259                type=REG_NONE;
     260            } else {
     261                *lpValue=end+2;
     262            }
     263        }
     264        return type;
     265    }
     266    return (**lpValue=='\0'?REG_SZ:REG_NONE);
     267}
     268
    281269/******************************************************************************
    282270 * Extracts from a [HKEY\some\key\path] type of line the key name (what starts
     
    341329
    342330/******************************************************************************
     331 * This is a replacement for strsep which is not portable (missing on Solaris).
     332 */
     333static char* getToken(char** str, const char* delims)
     334{
     335    char* token;
     336
     337    if (*str==NULL) {
     338        /* No more tokens */
     339        return NULL;
     340    }
     341
     342    token=*str;
     343    while (**str!='\0') {
     344        if (strchr(delims,**str)!=NULL) {
     345            **str='\0';
     346            (*str)++;
     347            return token;
     348        }
     349        (*str)++;
     350    }
     351    /* There is no other token */
     352    *str=NULL;
     353    return token;
     354}
     355
     356/******************************************************************************
    343357 * Returns an allocated buffer with a cleaned copy (removed the surrounding
    344358 * dbl quotes) of the passed value.
     
    384398static DWORD convertHexToDWord(char *str, BYTE *buf)
    385399{
    386   char  *s        = str;  /* Pointer to current */
    387   char  *b        = buf;  /* Pointer to result  */
    388   ULONG strPos    = 0;   
    389 
    390   memset(buf, 0, 4);
    391 
    392   while (strPos < 4)  /* 8 byte in a DWORD */
    393   {
    394     char xbuf[3];
    395     char wc;
    396 
    397     memcpy(xbuf,s,2); xbuf[2]='\0';
    398     sscanf(xbuf,"%02x",(UINT*)&wc);
    399     *b++ =(unsigned char)wc;
    400 
    401     s+=2;
    402     strPos+=1;
    403   }                                   
    404 
    405   return 4; /* always 4 byte for the word */
     400  DWORD dw;
     401  char xbuf[9];
     402
     403  memcpy(xbuf,str,8);
     404  xbuf[8]='\0';
     405  sscanf(xbuf,"%08lx",&dw);
     406  memcpy(buf,&dw,sizeof(DWORD));
     407  return sizeof(DWORD);
    406408}
    407409
     
    443445{
    444446  char* str;
    445   char* ptrStr;
    446   BYTE* ptrBuf;
    447 
    448   ULONG current = 0;
    449 
    450   str    = HeapAlloc(GetProcessHeap(), 0, (bufLen*2)+1);
    451   memset(str, 0, (bufLen*2)+1);
    452   ptrStr = str;  /* Pointer to result  */
    453   ptrBuf = buf;  /* Pointer to current */
    454 
    455   while (current < bufLen)
    456   {
    457     BYTE bCur = ptrBuf[current++];
    458     char res[3];
    459 
    460     sprintf(res, "%02x", (unsigned int)*&bCur);
    461     strcat(str, res);
    462   }                                   
     447  DWORD dw;
     448
     449  if ( bufLen != sizeof(DWORD) ) return NULL;
     450
     451  str = HeapAlloc(GetProcessHeap(), 0, (bufLen*2)+1);
     452
     453  memcpy(&dw,buf,sizeof(DWORD));
     454  sprintf(str, "%08lx", dw);
    463455
    464456  /* Get rid of the last comma */
     
    514506  DWORD   dwSize          = KEY_MAX_LEN;
    515507  DWORD   dwType          = 0;
    516   DWORD   dwDataType;
     508  DWORD   dwDataType,dwParseType;
    517509
    518510  LPSTR   lpsCurrentValue;
    519511
    520   LPSTR   keyValue = argv[0];
     512  LPSTR   keyValue = getArg(argv[0]);
    521513  LPSTR   keyData  = argv[1];
    522514
     
    534526
    535527  /* Get the data type stored into the value field */
    536   dwDataType = getDataType(&keyData);
    537    
     528  dwDataType = getDataType(&keyData,&dwParseType);
     529
    538530  memset(lpsCurrentValue, 0, KEY_MAX_LEN);
    539531  hRes = RegQueryValueExA(
     
    558550    DWORD  dwLen;
    559551
    560     if ( dwDataType == REG_SZ )        /* no convertion for string */
     552    if ( dwParseType == REG_SZ)        /* no conversion for string */
    561553    {
    562554      dwLen   = strlen(keyData);
     555      if (dwLen>0 && keyData[dwLen-1]=='"')
     556      {
     557        dwLen--;
     558        keyData[dwLen]='\0';
     559      }
    563560      lpbData = keyData;
    564561    }
    565     else if (dwDataType == REG_DWORD)  /* Convert the dword types */
     562    else if (dwParseType == REG_DWORD)  /* Convert the dword types */
    566563    {
    567564      dwLen   = convertHexToDWord(keyData, convert);
     
    593590        strncpy(argv[1], lpsCurrentValue, dwSize);
    594591        argv[1][dwSize]='\0';
    595     }
    596     }
    597 
    598     return KEY_VALUE_ALREADY_SET;
    599   }
     592      }
     593    }
     594
     595    hRes=KEY_VALUE_ALREADY_SET;
     596  }
     597  if (keyValue != NULL)
     598      HeapFree(GetProcessHeap(), 0, keyValue);
    600599  return hRes;
    601600}
     
    661660    argv[counter]=NULL;
    662661
    663   while( (token = strsep(&cmdline, setValueDelim[argCounter])) != NULL )
    664   {
    665     argv[argCounter++] = getArg(token);
     662  while( (token = getToken(&cmdline, setValueDelim[argCounter])) != NULL )
     663  {
     664    argv[argCounter++] = token;
    666665
    667666    if (argCounter == SET_VALUE_MAX_ARGS)
     
    683682      argv[1],
    684683      currentKeyName);
    685  
     684
    686685  else
    687686    printf("regapi: ERROR Key %s not created. Value: %s, Data: %s\n",
     
    689688      argv[0],
    690689      argv[1]);
    691    
    692   /*
    693    * Do some cleanup
    694    */
    695   for (counter=0; counter<argCounter; counter++)
    696     if (argv[counter] != NULL)
    697       HeapFree(GetProcessHeap(), 0, argv[counter]);
    698690}
    699691
     
    718710    argv[counter]=NULL;
    719711
    720   while( (token = strsep(&cmdline, queryValueDelim[argCounter])) != NULL )
     712  while( (token = getToken(&cmdline, queryValueDelim[argCounter])) != NULL )
    721713  {
    722714    argv[argCounter++] = getArg(token);
     
    728720  /* The value we look for is the first token on the line */
    729721  if ( argv[0] == NULL )
    730     return; /* SHOULD NOT OCCURS */
     722    return; /* SHOULD NOT HAPPEN */
    731723  else
    732724    keyValue = argv[0];
     
    10221014/******************************************************************************
    10231015 * MAIN - WinMain simply validates the first parameter (command to perform)
    1024  *        It then reads the STDIN lines by lines forwarding their processing
     1016 *        It then reads the STDIN line by line forwarding their processing
    10251017 *        to the appropriate method.
    10261018 */
     
    10421034   * get the command, should be the first arg (modify cmdLine)
    10431035   */
    1044   token = strsep(&cmdline, " ");
     1036#ifdef __WIN32OS2__
     1037  token = "setValue";
     1038#else
     1039  token = getToken(&cmdline, " ");
     1040#endif
    10451041  if (token != NULL)
    10461042  {
     
    10621058
    10631059  /*
    1064    * check to see weather we force the action
    1065    * (meaning differ depending on the command performed)
     1060   * check to see wether we force the action
     1061   * (meaning differs depending on the command performed)
    10661062   */
    10671063  if ( cmdline != NULL ) /* will be NULL if '-force' is not provided */
Note: See TracChangeset for help on using the changeset viewer.