regapi fixes
François Gouget
fgouget at codeweavers.com
Fri Nov 9 06:31:42 CST 2001
This patch adds support for str(x) and fixes a serious bug in the way
regapi handles strings for setValue.
The previous code was removing the quotes before trying to decode the
format of the value (in getDataType). So "Setting"="Some String" would
give 'value=Some String'. That's fine usually but what happens for:
"Setting"="hex(2):Some String"
-> type=2
expected_format=binary
value=Some String -> to be interpreted as a binary value...
somehow
"Setting"=str(2):"Some String"
-> type=2 (once I added support for str(x))
expected_format=string
value="Some String -> notice the extra "
The conclusion is that quote removal must not be done before
getDataType is called.
Changelog:
François Gouget <fgouget at codeweavers.com>
* programs/regapi/regapi.c
Correct handling of strings in setValue
Better handling of str(x) and hex(x) in setValue
Misc typos
--
François Gouget
fgouget at codeweavers.com
-------------- next part --------------
Index: programs/regapi/regapi.c
===================================================================
RCS file: /home/wine/wine/programs/regapi/regapi.c,v
retrieving revision 1.16
diff -u -r1.16 regapi.c
--- programs/regapi/regapi.c 2001/11/06 22:24:40 1.16
+++ programs/regapi/regapi.c 2001/11/09 09:59:12
@@ -46,46 +46,10 @@
/* Delimiters used to parse the "value" to query queryValue*/
#define QUERY_VALUE_MAX_ARGS 1
-static const char *setValueDelim[SET_VALUE_MAX_ARGS] = {"=", ""};
-static const char *queryValueDelim[QUERY_VALUE_MAX_ARGS] = {""};
+static const char *setValueDelim[SET_VALUE_MAX_ARGS] = {"=", ""};
+static const char *queryValueDelim[QUERY_VALUE_MAX_ARGS] = {""};
-/* Array used to extract the data type from a string in getDataType. */
-typedef struct tagDataTypeMap
-{
- char mask[15];
- DWORD dataType;
-} dataTypeMap;
-
-static const dataTypeMap typeMap[] =
-{
- {"hex:", REG_BINARY},/* could be REG_NONE (?) */
- {"dword:", REG_DWORD},
- {"hex(0):", REG_NONE},
- {"hex(1):", REG_SZ},
- {"hex(2):", REG_EXPAND_SZ},
- {"hex(3):", REG_BINARY},
- {"hex(4):", REG_DWORD},
- {"hex(5):", REG_DWORD_BIG_ENDIAN},
- {"hex(6):", REG_LINK},
- {"hex(7):", REG_MULTI_SZ},
- {"hex(8):", REG_RESOURCE_LIST},
- {"hex(9):", REG_FULL_RESOURCE_DESCRIPTOR},
- {"hex(10):", REG_RESOURCE_REQUIREMENTS_LIST},
- {"hex(80000000):", 0x80000000},
- {"hex(80000001):", 0x80000001},
- {"hex(80000002):", 0x80000002},
- {"hex(80000003):", 0x80000003},
- {"hex(80000004):", 0x80000004},
- {"hex(80000005):", 0x80000005},
- {"hex(80000006):", 0x80000006},
- {"hex(80000007):", 0x80000007},
- {"hex(80000008):", 0x80000008},
- {"hex(80000009):", 0x80000000},
- {"hex(8000000a):", 0x8000000A}
-};
-const static int LAST_TYPE_MAP = sizeof(typeMap)/sizeof(dataTypeMap);
-
/*
* Forward declaration
*/
@@ -141,7 +105,7 @@
/*
* Generic prototypes
*/
-static DWORD getDataType(LPSTR *lpValue);
+static DWORD getDataType(LPSTR *lpValue, DWORD* parse_type);
static LPSTR getRegKeyName(LPSTR lpLine);
static HKEY getRegClass(LPSTR lpLine);
static LPSTR getArg(LPSTR arg);
@@ -227,35 +191,59 @@
" The input file format is a list of DLLs to unregister\n"
" February 1999.\n"
;
-
+
/******************************************************************************
* This function returns the HKEY associated with the data type encoded in the
* value. It modifies the input parameter (key value) in order to skip this
* "now useless" data type information.
+ *
+ * Note: Updated based on the algorithm used in 'server/registry.c'
*/
-DWORD getDataType(LPSTR *lpValue)
+DWORD getDataType(LPSTR *lpValue, DWORD* parse_type)
{
- INT counter = 0;
- DWORD dwReturn = REG_SZ;
+ struct data_type { const char *tag; int len; int type; int parse_type; };
- for (; counter < LAST_TYPE_MAP; counter++)
- {
- LONG len = strlen(typeMap[counter].mask);
- if ( strncasecmp( *lpValue, typeMap[counter].mask, len) == IDENTICAL)
+ static const struct data_type data_types[] =
+ { /* actual type */ /* type to assume for parsing */
+ { "\"", 1, REG_SZ, REG_SZ },
+ { "str:\"", 5, REG_SZ, REG_SZ },
+ { "str(2):\"", 8, REG_EXPAND_SZ, REG_SZ },
+ { "str(7):\"", 8, REG_MULTI_SZ, REG_SZ },
+ { "hex:", 4, REG_BINARY, REG_BINARY },
+ { "dword:", 6, REG_DWORD, REG_DWORD },
+ { "hex(", 4, -1, REG_BINARY },
+ { NULL, 0, 0, 0 }
+ };
+
+ const struct data_type *ptr;
+ int type;
+
+ for (ptr = data_types; ptr->tag; ptr++)
{
- /*
- * We found it, modify the value's pointer in order to skip the data
- * type identifier, set the return value and exit the loop.
- */
- (*lpValue) += len;
- dwReturn = typeMap[counter].dataType;
- break;
- }
- }
+ if (memcmp( ptr->tag, *lpValue, ptr->len ))
+ continue;
- return dwReturn;
+ /* Found! */
+ *parse_type = ptr->parse_type;
+ type=ptr->type;
+ *lpValue+=ptr->len;
+ if (type == -1) {
+ char* end;
+ /* "hex(xx):" is special */
+ *lpValue += 4;
+ type = (int)strtoul( *lpValue , &end, 16 );
+ if (**lpValue=='\0' || *end!=')' || *(end+1)!=':') {
+ type=REG_NONE;
+ } else {
+ *lpValue=end+2;
+ }
+ }
+ return type;
+ }
+ return (**lpValue=='\0'?REG_SZ:REG_NONE);
}
+
/******************************************************************************
* Extracts from a [HKEY\some\key\path] type of line the key name (what starts
* after the first '\' and end before the ']'
@@ -495,11 +483,11 @@
HRESULT hRes;
DWORD dwSize = KEY_MAX_LEN;
DWORD dwType = 0;
- DWORD dwDataType;
+ DWORD dwDataType,dwParseType;
LPSTR lpsCurrentValue;
- LPSTR keyValue = argv[0];
+ LPSTR keyValue = getArg(argv[0]);
LPSTR keyData = argv[1];
/* Make some checks */
@@ -515,8 +503,8 @@
keyValue[0] = '\0';
/* Get the data type stored into the value field */
- dwDataType = getDataType(&keyData);
-
+ dwDataType = getDataType(&keyData,&dwParseType);
+
memset(lpsCurrentValue, 0, KEY_MAX_LEN);
hRes = RegQueryValueExA(
currentKeyHandle,
@@ -539,12 +527,17 @@
BYTE convert[KEY_MAX_LEN];
DWORD dwLen;
- if ( dwDataType == REG_SZ ) /* no convertion for string */
+ if ( dwParseType == REG_SZ) /* no conversion for string */
{
dwLen = strlen(keyData);
+ if (dwLen>0 && keyData[dwLen-1]=='"')
+ {
+ dwLen--;
+ keyData[dwLen]='\0';
+ }
lpbData = keyData;
}
- else if (dwDataType == REG_DWORD) /* Convert the dword types */
+ else if (dwParseType == REG_DWORD) /* Convert the dword types */
{
dwLen = convertHexToDWord(keyData, convert);
lpbData = convert;
@@ -574,11 +567,13 @@
if ( argv[1] != NULL ) {
strncpy(argv[1], lpsCurrentValue, dwSize);
argv[1][dwSize]='\0';
- }
+ }
}
- return KEY_VALUE_ALREADY_SET;
+ hRes=KEY_VALUE_ALREADY_SET;
}
+ if (keyValue != NULL)
+ HeapFree(GetProcessHeap(), 0, keyValue);
return hRes;
}
@@ -644,7 +639,7 @@
while( (token = getToken(&cmdline, setValueDelim[argCounter])) != NULL )
{
- argv[argCounter++] = getArg(token);
+ argv[argCounter++] = token;
if (argCounter == SET_VALUE_MAX_ARGS)
break; /* Stop processing args no matter what */
@@ -664,19 +659,12 @@
argv[0],
argv[1],
currentKeyName);
-
+
else
printf("regapi: ERROR Key %s not created. Value: %s, Data: %s\n",
currentKeyName,
argv[0],
argv[1]);
-
- /*
- * Do some cleanup
- */
- for (counter=0; counter<argCounter; counter++)
- if (argv[counter] != NULL)
- HeapFree(GetProcessHeap(), 0, argv[counter]);
}
/******************************************************************************
@@ -709,7 +697,7 @@
/* The value we look for is the first token on the line */
if ( argv[0] == NULL )
- return; /* SHOULD NOT OCCURS */
+ return; /* SHOULD NOT HAPPEN */
else
keyValue = argv[0];
@@ -1003,7 +991,7 @@
/******************************************************************************
* MAIN - WinMain simply validates the first parameter (command to perform)
- * It then reads the STDIN lines by lines forwarding their processing
+ * It then reads the STDIN line by line forwarding their processing
* to the appropriate method.
*/
int PASCAL WinMain (HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
@@ -1043,8 +1031,8 @@
}
/*
- * check to see weather we force the action
- * (meaning differ depending on the command performed)
+ * check to see wether we force the action
+ * (meaning differs depending on the command performed)
*/
if ( cmdline != NULL ) /* will be NULL if '-force' is not provided */
if ( strstr(cmdline, "-force") != NULL )
More information about the wine-patches
mailing list