Commit a5bb38e4 authored by François Gouget's avatar François Gouget Committed by Alexandre Julliard

Correct handling of strings in setValue.

Better handling of str(x) and hex(x) in setValue. Misc typos.
parent 608a33c5
...@@ -46,44 +46,8 @@ static BOOL bTheKeyIsOpen = FALSE; ...@@ -46,44 +46,8 @@ static BOOL bTheKeyIsOpen = FALSE;
/* Delimiters used to parse the "value" to query queryValue*/ /* Delimiters used to parse the "value" to query queryValue*/
#define QUERY_VALUE_MAX_ARGS 1 #define QUERY_VALUE_MAX_ARGS 1
static const char *setValueDelim[SET_VALUE_MAX_ARGS] = {"=", ""}; static const char *setValueDelim[SET_VALUE_MAX_ARGS] = {"=", ""};
static const char *queryValueDelim[QUERY_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);
/* /*
...@@ -141,7 +105,7 @@ static const BOOL commandSaveRegistry[COMMAND_COUNT] = { ...@@ -141,7 +105,7 @@ static const BOOL commandSaveRegistry[COMMAND_COUNT] = {
/* /*
* Generic prototypes * Generic prototypes
*/ */
static DWORD getDataType(LPSTR *lpValue); static DWORD getDataType(LPSTR *lpValue, DWORD* parse_type);
static LPSTR getRegKeyName(LPSTR lpLine); static LPSTR getRegKeyName(LPSTR lpLine);
static HKEY getRegClass(LPSTR lpLine); static HKEY getRegClass(LPSTR lpLine);
static LPSTR getArg(LPSTR arg); static LPSTR getArg(LPSTR arg);
...@@ -227,35 +191,59 @@ static char helpText[] = ...@@ -227,35 +191,59 @@ static char helpText[] =
" The input file format is a list of DLLs to unregister\n" " The input file format is a list of DLLs to unregister\n"
" February 1999.\n" " February 1999.\n"
; ;
/****************************************************************************** /******************************************************************************
* This function returns the HKEY associated with the data type encoded in the * 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 * value. It modifies the input parameter (key value) in order to skip this
* "now useless" data type information. * "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; struct data_type { const char *tag; int len; int type; int parse_type; };
DWORD dwReturn = REG_SZ;
static const struct data_type data_types[] =
for (; counter < LAST_TYPE_MAP; counter++) { /* actual type */ /* type to assume for parsing */
{ { "\"", 1, REG_SZ, REG_SZ },
LONG len = strlen(typeMap[counter].mask); { "str:\"", 5, REG_SZ, REG_SZ },
if ( strncasecmp( *lpValue, typeMap[counter].mask, len) == IDENTICAL) { "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++)
{ {
/* if (memcmp( ptr->tag, *lpValue, ptr->len ))
* We found it, modify the value's pointer in order to skip the data continue;
* type identifier, set the return value and exit the loop.
*/ /* Found! */
(*lpValue) += len; *parse_type = ptr->parse_type;
dwReturn = typeMap[counter].dataType; type=ptr->type;
break; *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);
return dwReturn;
} }
/****************************************************************************** /******************************************************************************
* Extracts from a [HKEY\some\key\path] type of line the key name (what starts * Extracts from a [HKEY\some\key\path] type of line the key name (what starts
* after the first '\' and end before the ']' * after the first '\' and end before the ']'
...@@ -495,11 +483,11 @@ static HRESULT setValue(LPSTR *argv) ...@@ -495,11 +483,11 @@ static HRESULT setValue(LPSTR *argv)
HRESULT hRes; HRESULT hRes;
DWORD dwSize = KEY_MAX_LEN; DWORD dwSize = KEY_MAX_LEN;
DWORD dwType = 0; DWORD dwType = 0;
DWORD dwDataType; DWORD dwDataType,dwParseType;
LPSTR lpsCurrentValue; LPSTR lpsCurrentValue;
LPSTR keyValue = argv[0]; LPSTR keyValue = getArg(argv[0]);
LPSTR keyData = argv[1]; LPSTR keyData = argv[1];
/* Make some checks */ /* Make some checks */
...@@ -515,8 +503,8 @@ static HRESULT setValue(LPSTR *argv) ...@@ -515,8 +503,8 @@ static HRESULT setValue(LPSTR *argv)
keyValue[0] = '\0'; keyValue[0] = '\0';
/* Get the data type stored into the value field */ /* Get the data type stored into the value field */
dwDataType = getDataType(&keyData); dwDataType = getDataType(&keyData,&dwParseType);
memset(lpsCurrentValue, 0, KEY_MAX_LEN); memset(lpsCurrentValue, 0, KEY_MAX_LEN);
hRes = RegQueryValueExA( hRes = RegQueryValueExA(
currentKeyHandle, currentKeyHandle,
...@@ -539,12 +527,17 @@ static HRESULT setValue(LPSTR *argv) ...@@ -539,12 +527,17 @@ static HRESULT setValue(LPSTR *argv)
BYTE convert[KEY_MAX_LEN]; BYTE convert[KEY_MAX_LEN];
DWORD dwLen; DWORD dwLen;
if ( dwDataType == REG_SZ ) /* no convertion for string */ if ( dwParseType == REG_SZ) /* no conversion for string */
{ {
dwLen = strlen(keyData); dwLen = strlen(keyData);
if (dwLen>0 && keyData[dwLen-1]=='"')
{
dwLen--;
keyData[dwLen]='\0';
}
lpbData = keyData; lpbData = keyData;
} }
else if (dwDataType == REG_DWORD) /* Convert the dword types */ else if (dwParseType == REG_DWORD) /* Convert the dword types */
{ {
dwLen = convertHexToDWord(keyData, convert); dwLen = convertHexToDWord(keyData, convert);
lpbData = convert; lpbData = convert;
...@@ -574,11 +567,13 @@ static HRESULT setValue(LPSTR *argv) ...@@ -574,11 +567,13 @@ static HRESULT setValue(LPSTR *argv)
if ( argv[1] != NULL ) { if ( argv[1] != NULL ) {
strncpy(argv[1], lpsCurrentValue, dwSize); strncpy(argv[1], lpsCurrentValue, dwSize);
argv[1][dwSize]='\0'; argv[1][dwSize]='\0';
} }
} }
return KEY_VALUE_ALREADY_SET; hRes=KEY_VALUE_ALREADY_SET;
} }
if (keyValue != NULL)
HeapFree(GetProcessHeap(), 0, keyValue);
return hRes; return hRes;
} }
...@@ -644,7 +639,7 @@ static void processSetValue(LPSTR cmdline) ...@@ -644,7 +639,7 @@ static void processSetValue(LPSTR cmdline)
while( (token = getToken(&cmdline, setValueDelim[argCounter])) != NULL ) while( (token = getToken(&cmdline, setValueDelim[argCounter])) != NULL )
{ {
argv[argCounter++] = getArg(token); argv[argCounter++] = token;
if (argCounter == SET_VALUE_MAX_ARGS) if (argCounter == SET_VALUE_MAX_ARGS)
break; /* Stop processing args no matter what */ break; /* Stop processing args no matter what */
...@@ -664,19 +659,12 @@ static void processSetValue(LPSTR cmdline) ...@@ -664,19 +659,12 @@ static void processSetValue(LPSTR cmdline)
argv[0], argv[0],
argv[1], argv[1],
currentKeyName); currentKeyName);
else else
printf("regapi: ERROR Key %s not created. Value: %s, Data: %s\n", printf("regapi: ERROR Key %s not created. Value: %s, Data: %s\n",
currentKeyName, currentKeyName,
argv[0], argv[0],
argv[1]); argv[1]);
/*
* Do some cleanup
*/
for (counter=0; counter<argCounter; counter++)
if (argv[counter] != NULL)
HeapFree(GetProcessHeap(), 0, argv[counter]);
} }
/****************************************************************************** /******************************************************************************
...@@ -709,7 +697,7 @@ static void processQueryValue(LPSTR cmdline) ...@@ -709,7 +697,7 @@ static void processQueryValue(LPSTR cmdline)
/* The value we look for is the first token on the line */ /* The value we look for is the first token on the line */
if ( argv[0] == NULL ) if ( argv[0] == NULL )
return; /* SHOULD NOT OCCURS */ return; /* SHOULD NOT HAPPEN */
else else
keyValue = argv[0]; keyValue = argv[0];
...@@ -1003,7 +991,7 @@ static void doUnregisterDLL(LPSTR stdInput) { ...@@ -1003,7 +991,7 @@ static void doUnregisterDLL(LPSTR stdInput) {
/****************************************************************************** /******************************************************************************
* MAIN - WinMain simply validates the first parameter (command to perform) * 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. * to the appropriate method.
*/ */
int PASCAL WinMain (HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) int PASCAL WinMain (HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
...@@ -1043,8 +1031,8 @@ int PASCAL WinMain (HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) ...@@ -1043,8 +1031,8 @@ int PASCAL WinMain (HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
} }
/* /*
* check to see weather we force the action * check to see wether we force the action
* (meaning differ depending on the command performed) * (meaning differs depending on the command performed)
*/ */
if ( cmdline != NULL ) /* will be NULL if '-force' is not provided */ if ( cmdline != NULL ) /* will be NULL if '-force' is not provided */
if ( strstr(cmdline, "-force") != NULL ) if ( strstr(cmdline, "-force") != NULL )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment