Changeset 7933 for trunk/tools
- Timestamp:
- Feb 16, 2002, 5:29:55 PM (24 years ago)
- Location:
- trunk/tools/regedit
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/tools/regedit/README
r3424 r7933 27 27 1 - Parse the before.reg and after.reg file into regFixer.pl, in order to 28 28 obtain lines in the form [HKEY\Sub1\Sub2\...\Subn]"Value"="Data" 29 (where "Data" can be prefixed by the type identif yer : hex:, hex(0000000?)29 (where "Data" can be prefixed by the type identifier : hex:, hex(0000000?) 30 30 or dword:) 31 31 … … 34 34 35 35 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 using36 application. To this we extract the parts that we are interested in using 37 37 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 ). 39 39 40 40 At this point we know which registry entry to add to the wine registry. It … … 43 43 44 44 I say "similar" because there is a tiny difference between Windows regedit 45 export format and the format actual y required by the tool.45 export format and the format actually required by the tool. 46 46 47 The problem with this (and it is not a big one) is that regedit export long48 data streams onto many lines, and since I don t have tons of time I setup47 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 49 49 another Perl script (regRestorer.pl) that fixes this (this could easily 50 be done in C obviously) (left as ex cercise ;-) ).50 be done in C obviously) (left as exercise ;-) ). 51 51 52 So, once you parsed app.added into regRestorer.pl you get a app.reg ready to52 So, once you parsed app.added into regRestorer.pl you get an app.reg ready to 53 53 process by regapi. 54 54 … … 61 61 something "regapi-able" 62 62 63 regSet 63 regSet.sh - Will do the procedure explained herein 64 64 for the added key only. 65 65 … … 71 71 ----------------- 72 72 1 - Get a snapshot of your windows registry in before.reg, (regedit/export) 73 2 - Install you 'reapplication,73 2 - Install your application, 74 74 3 - Get a snapshot of your windows registry in after.reg. 75 75 4 - Invoke ./regSet.sh before.reg after.reg -
trunk/tools/regedit/regapi.c
r6565 r7933 69 69 #define QUERY_VALUE_MAX_ARGS 1 70 70 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); 71 static const char *setValueDelim[SET_VALUE_MAX_ARGS] = {"=", ""}; 72 static const char *queryValueDelim[QUERY_VALUE_MAX_ARGS] = {""}; 109 73 110 74 … … 164 128 * Generic prototypes 165 129 */ 166 static DWORD getDataType(LPSTR *lpValue );130 static DWORD getDataType(LPSTR *lpValue, DWORD* parse_type); 167 131 static LPSTR getRegKeyName(LPSTR lpLine); 168 132 static HKEY getRegClass(LPSTR lpLine); … … 250 214 " February 1999.\n" 251 215 ; 252 216 253 217 254 218 /****************************************************************************** … … 256 220 * value. It modifies the input parameter (key value) in order to skip this 257 221 * "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 */ 225 DWORD 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++) 268 245 { 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 281 269 /****************************************************************************** 282 270 * Extracts from a [HKEY\some\key\path] type of line the key name (what starts … … 341 329 342 330 /****************************************************************************** 331 * This is a replacement for strsep which is not portable (missing on Solaris). 332 */ 333 static 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 /****************************************************************************** 343 357 * Returns an allocated buffer with a cleaned copy (removed the surrounding 344 358 * dbl quotes) of the passed value. … … 384 398 static DWORD convertHexToDWord(char *str, BYTE *buf) 385 399 { 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); 406 408 } 407 409 … … 443 445 { 444 446 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); 463 455 464 456 /* Get rid of the last comma */ … … 514 506 DWORD dwSize = KEY_MAX_LEN; 515 507 DWORD dwType = 0; 516 DWORD dwDataType ;508 DWORD dwDataType,dwParseType; 517 509 518 510 LPSTR lpsCurrentValue; 519 511 520 LPSTR keyValue = argv[0];512 LPSTR keyValue = getArg(argv[0]); 521 513 LPSTR keyData = argv[1]; 522 514 … … 534 526 535 527 /* Get the data type stored into the value field */ 536 dwDataType = getDataType(&keyData );537 528 dwDataType = getDataType(&keyData,&dwParseType); 529 538 530 memset(lpsCurrentValue, 0, KEY_MAX_LEN); 539 531 hRes = RegQueryValueExA( … … 558 550 DWORD dwLen; 559 551 560 if ( dw DataType == REG_SZ ) /* no convertion for string */552 if ( dwParseType == REG_SZ) /* no conversion for string */ 561 553 { 562 554 dwLen = strlen(keyData); 555 if (dwLen>0 && keyData[dwLen-1]=='"') 556 { 557 dwLen--; 558 keyData[dwLen]='\0'; 559 } 563 560 lpbData = keyData; 564 561 } 565 else if (dw DataType == REG_DWORD) /* Convert the dword types */562 else if (dwParseType == REG_DWORD) /* Convert the dword types */ 566 563 { 567 564 dwLen = convertHexToDWord(keyData, convert); … … 593 590 strncpy(argv[1], lpsCurrentValue, dwSize); 594 591 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); 600 599 return hRes; 601 600 } … … 661 660 argv[counter]=NULL; 662 661 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; 666 665 667 666 if (argCounter == SET_VALUE_MAX_ARGS) … … 683 682 argv[1], 684 683 currentKeyName); 685 684 686 685 else 687 686 printf("regapi: ERROR Key %s not created. Value: %s, Data: %s\n", … … 689 688 argv[0], 690 689 argv[1]); 691 692 /*693 * Do some cleanup694 */695 for (counter=0; counter<argCounter; counter++)696 if (argv[counter] != NULL)697 HeapFree(GetProcessHeap(), 0, argv[counter]);698 690 } 699 691 … … 718 710 argv[counter]=NULL; 719 711 720 while( (token = strsep(&cmdline, queryValueDelim[argCounter])) != NULL )712 while( (token = getToken(&cmdline, queryValueDelim[argCounter])) != NULL ) 721 713 { 722 714 argv[argCounter++] = getArg(token); … … 728 720 /* The value we look for is the first token on the line */ 729 721 if ( argv[0] == NULL ) 730 return; /* SHOULD NOT OCCURS*/722 return; /* SHOULD NOT HAPPEN */ 731 723 else 732 724 keyValue = argv[0]; … … 1022 1014 /****************************************************************************** 1023 1015 * MAIN - WinMain simply validates the first parameter (command to perform) 1024 * It then reads the STDIN line s by linesforwarding their processing1016 * It then reads the STDIN line by line forwarding their processing 1025 1017 * to the appropriate method. 1026 1018 */ … … 1042 1034 * get the command, should be the first arg (modify cmdLine) 1043 1035 */ 1044 token = strsep(&cmdline, " "); 1036 #ifdef __WIN32OS2__ 1037 token = "setValue"; 1038 #else 1039 token = getToken(&cmdline, " "); 1040 #endif 1045 1041 if (token != NULL) 1046 1042 { … … 1062 1058 1063 1059 /* 1064 * check to see we ather we force the action1065 * (meaning differ depending on the command performed)1060 * check to see wether we force the action 1061 * (meaning differs depending on the command performed) 1066 1062 */ 1067 1063 if ( cmdline != NULL ) /* will be NULL if '-force' is not provided */
Note:
See TracChangeset
for help on using the changeset viewer.