Add _krb5_store_string_to_reg_value() for Windows
The new _krb5_store_string_to_reg_value() function permits the caller to create REG_SZ, REG_EXPAND_SZ, REG_DWORD, and REG_MULTI_SZ entries in the registry. Change-Id: Ib5740ad07209618d8ea4c0bf3c75615f27e98b4e
This commit is contained in:
@@ -51,7 +51,8 @@ DLLSDKDEPS= \
|
||||
$(PTHREAD_LIB) \
|
||||
secur32.lib \
|
||||
shell32.lib \
|
||||
dnsapi.lib
|
||||
dnsapi.lib \
|
||||
shlwapi.lib
|
||||
|
||||
DEF=$(OBJ)\heimdal.def
|
||||
|
||||
|
@@ -35,9 +35,179 @@
|
||||
#error config_reg.c is only for Windows
|
||||
#endif
|
||||
|
||||
#include <shlwapi.h>
|
||||
|
||||
#ifndef MAX_DWORD
|
||||
#define MAX_DWORD 0xFFFFFFFF
|
||||
#endif
|
||||
|
||||
#define REGPATH_KERBEROS "SOFTWARE\\Kerberos"
|
||||
#define REGPATH_HEIMDAL "SOFTWARE\\Heimdal"
|
||||
|
||||
/**
|
||||
* Store a string as a registry value of the specified type
|
||||
*
|
||||
* The following registry types are handled:
|
||||
*
|
||||
* - REG_DWORD: The string is converted to a number.
|
||||
*
|
||||
* - REG_SZ: The string is stored as is.
|
||||
*
|
||||
* - REG_EXPAND_SZ: The string is stored as is.
|
||||
*
|
||||
* - REG_MULTI_SZ:
|
||||
*
|
||||
* . If a separator is specified, the input string is broken
|
||||
* up into multiple strings and stored as a multi-sz.
|
||||
*
|
||||
* . If no separator is provided, the input string is stored
|
||||
* as a multi-sz.
|
||||
*
|
||||
* - REG_NONE:
|
||||
*
|
||||
* . If the string is all numeric, it will be stored as a
|
||||
* REG_DWORD.
|
||||
*
|
||||
* . Otherwise, the string is stored as a REG_SZ.
|
||||
*
|
||||
* Other types are rejected.
|
||||
*
|
||||
* If cb_data is MAX_DWORD, the string pointed to by data must be nul-terminated
|
||||
* otherwise a buffer overrun will occur.
|
||||
*
|
||||
* @param [in]valuename Name of the registry value to be modified or created
|
||||
* @param [in]type Type of the value. REG_NONE if unknown
|
||||
* @param [in]data The input string to be stored in the registry.
|
||||
* @param [in]cb_data Size of the input string in bytes. MAX_DWORD if unknown.
|
||||
* @param [in]separator Separator character for parsing strings.
|
||||
*
|
||||
* @retval 0 if success or non-zero on error.
|
||||
* If non-zero is returned, an error message has been set using
|
||||
* krb5_set_error_message().
|
||||
*
|
||||
*/
|
||||
int
|
||||
_krb5_store_string_to_reg_value(krb5_context context,
|
||||
HKEY key, const char * valuename,
|
||||
DWORD type, const char *data, DWORD cb_data,
|
||||
const char * separator)
|
||||
{
|
||||
LONG rcode;
|
||||
DWORD dwData;
|
||||
BYTE static_buffer[16384];
|
||||
BYTE *pbuffer = &static_buffer[0];
|
||||
|
||||
if (data == NULL)
|
||||
{
|
||||
if (context)
|
||||
krb5_set_error_message(context, 0,
|
||||
"'data' must not be NULL");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cb_data == MAX_DWORD)
|
||||
{
|
||||
cb_data = (DWORD)strlen(data) + 1;
|
||||
}
|
||||
else if ((type == REG_MULTI_SZ && cb_data >= sizeof(static_buffer) - 1) ||
|
||||
cb_data >= sizeof(static_buffer))
|
||||
{
|
||||
if (context)
|
||||
krb5_set_error_message(context, 0, "cb_data too big");
|
||||
return -1;
|
||||
}
|
||||
else if (data[cb_data-1] != '\0')
|
||||
{
|
||||
memcpy(static_buffer, data, cb_data);
|
||||
static_buffer[cb_data++] = '\0';
|
||||
if (type == REG_MULTI_SZ)
|
||||
static_buffer[cb_data++] = '\0';
|
||||
data = static_buffer;
|
||||
}
|
||||
|
||||
if (type == REG_NONE)
|
||||
{
|
||||
/*
|
||||
* If input is all numeric, convert to DWORD and save as REG_DWORD.
|
||||
* Otherwise, store as REG_SZ.
|
||||
*/
|
||||
if ( StrToIntExA( data, STIF_SUPPORT_HEX, &dwData) )
|
||||
{
|
||||
type = REG_DWORD;
|
||||
} else {
|
||||
type = REG_SZ;
|
||||
}
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case REG_SZ:
|
||||
case REG_EXPAND_SZ:
|
||||
rcode = RegSetValueEx(key, valuename, 0, type, data, cb_data);
|
||||
if (rcode)
|
||||
{
|
||||
if (context)
|
||||
krb5_set_error_message(context, 0,
|
||||
"Unexpected error when setting registry value %s gle 0x%x",
|
||||
valuename,
|
||||
GetLastError());
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case REG_MULTI_SZ:
|
||||
if (separator && *separator)
|
||||
{
|
||||
int i;
|
||||
char *cp;
|
||||
|
||||
if (data != static_buffer)
|
||||
static_buffer[cb_data++] = '\0';
|
||||
|
||||
for ( cp = static_buffer; cp < static_buffer+cb_data; cp++)
|
||||
{
|
||||
if (*cp == *separator)
|
||||
*cp = '\0';
|
||||
}
|
||||
|
||||
rcode = RegSetValueEx(key, valuename, 0, type, data, cb_data);
|
||||
if (rcode)
|
||||
{
|
||||
if (context)
|
||||
krb5_set_error_message(context, 0,
|
||||
"Unexpected error when setting registry value %s gle 0x%x",
|
||||
valuename,
|
||||
GetLastError());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case REG_DWORD:
|
||||
if ( !StrToIntExA( data, STIF_SUPPORT_HEX, &dwData) )
|
||||
{
|
||||
if (context)
|
||||
krb5_set_error_message(context, 0,
|
||||
"Unexpected error when parsing %s as number gle 0x%x",
|
||||
data,
|
||||
GetLastError());
|
||||
}
|
||||
|
||||
rcode = RegSetValueEx(key, valuename, 0, type, dwData, sizeof(DWORD));
|
||||
if (rcode)
|
||||
{
|
||||
if (context)
|
||||
krb5_set_error_message(context, 0,
|
||||
"Unexpected error when setting registry value %s gle 0x%x",
|
||||
valuename,
|
||||
GetLastError());
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a registry value as a string
|
||||
*
|
||||
|
Reference in New Issue
Block a user