mirror of
https://github.com/boostorg/build.git
synced 2026-02-14 00:32:11 +00:00
Some system headers on POSIX systems indirectly include strings.h in extern "C" region. This sometimes results in Boost.Build's strings.h being included into such region, which marks all string_* functions as extern "C" and changes their name mangling rules accordingly, which causes linking errors. To resolve this header conflict, this commit renames strings.h to jam_strings.h. And strings.cpp to jam_strings.cpp for consistency. Fixes https://github.com/boostorg/build/issues/468.
202 lines
5.1 KiB
C++
202 lines
5.1 KiB
C++
/*
|
|
Copyright Paul Lin 2003. Copyright 2006 Bojan Resnik.
|
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
|
|
# include "jam.h"
|
|
|
|
# if defined( OS_NT ) || defined( OS_CYGWIN )
|
|
|
|
# include "lists.h"
|
|
# include "object.h"
|
|
# include "parse.h"
|
|
# include "frames.h"
|
|
# include "jam_strings.h"
|
|
|
|
# define WIN32_LEAN_AND_MEAN
|
|
# include <windows.h>
|
|
|
|
# define MAX_REGISTRY_DATA_LENGTH 4096
|
|
# define MAX_REGISTRY_KEYNAME_LENGTH 256
|
|
# define MAX_REGISTRY_VALUENAME_LENGTH 16384
|
|
|
|
typedef struct
|
|
{
|
|
LPCSTR name;
|
|
HKEY value;
|
|
} KeyMap;
|
|
|
|
static const KeyMap dlRootKeys[] = {
|
|
{ "HKLM", HKEY_LOCAL_MACHINE },
|
|
{ "HKCU", HKEY_CURRENT_USER },
|
|
{ "HKCR", HKEY_CLASSES_ROOT },
|
|
{ "HKEY_LOCAL_MACHINE", HKEY_LOCAL_MACHINE },
|
|
{ "HKEY_CURRENT_USER", HKEY_CURRENT_USER },
|
|
{ "HKEY_CLASSES_ROOT", HKEY_CLASSES_ROOT },
|
|
{ 0, 0 }
|
|
};
|
|
|
|
static HKEY get_key(char const** path)
|
|
{
|
|
const KeyMap *p;
|
|
|
|
for (p = dlRootKeys; p->name; ++p)
|
|
{
|
|
int n = strlen(p->name);
|
|
if (!strncmp(*path,p->name,n))
|
|
{
|
|
if ((*path)[n] == '\\' || (*path)[n] == 0)
|
|
{
|
|
*path += n + 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return p->value;
|
|
}
|
|
|
|
LIST * builtin_system_registry( FRAME * frame, int flags )
|
|
{
|
|
char const* path = object_str( list_front( lol_get(frame->args, 0) ) );
|
|
LIST* result = L0;
|
|
HKEY key = get_key(&path);
|
|
|
|
if (
|
|
key != 0
|
|
&& ERROR_SUCCESS == RegOpenKeyEx(key, path, 0, KEY_QUERY_VALUE, &key)
|
|
)
|
|
{
|
|
DWORD type;
|
|
BYTE data[MAX_REGISTRY_DATA_LENGTH];
|
|
DWORD len = sizeof(data);
|
|
LIST * const field = lol_get(frame->args, 1);
|
|
|
|
if ( ERROR_SUCCESS ==
|
|
RegQueryValueEx(key, field ? object_str( list_front( field ) ) : 0, 0, &type, data, &len) )
|
|
{
|
|
switch (type)
|
|
{
|
|
|
|
case REG_EXPAND_SZ:
|
|
{
|
|
long len;
|
|
string expanded[1];
|
|
string_new(expanded);
|
|
|
|
while (
|
|
(len = ExpandEnvironmentStrings(
|
|
(LPCSTR)data, expanded->value, expanded->capacity))
|
|
> expanded->capacity
|
|
)
|
|
string_reserve(expanded, len);
|
|
|
|
expanded->size = len - 1;
|
|
|
|
result = list_push_back( result, object_new(expanded->value) );
|
|
string_free( expanded );
|
|
}
|
|
break;
|
|
|
|
case REG_MULTI_SZ:
|
|
{
|
|
char* s;
|
|
|
|
for (s = (char*)data; *s; s += strlen(s) + 1)
|
|
result = list_push_back( result, object_new(s) );
|
|
|
|
}
|
|
break;
|
|
|
|
case REG_DWORD:
|
|
{
|
|
char buf[100];
|
|
sprintf( buf, "%u", *(PDWORD)data );
|
|
result = list_push_back( result, object_new(buf) );
|
|
}
|
|
break;
|
|
|
|
case REG_SZ:
|
|
result = list_push_back( result, object_new( (const char *)data ) );
|
|
break;
|
|
}
|
|
}
|
|
RegCloseKey(key);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
static LIST* get_subkey_names(HKEY key, char const* path)
|
|
{
|
|
LIST* result = 0;
|
|
|
|
if ( ERROR_SUCCESS ==
|
|
RegOpenKeyEx(key, path, 0, KEY_ENUMERATE_SUB_KEYS, &key)
|
|
)
|
|
{
|
|
char name[MAX_REGISTRY_KEYNAME_LENGTH];
|
|
DWORD name_size = sizeof(name);
|
|
DWORD index;
|
|
FILETIME last_write_time;
|
|
|
|
for ( index = 0;
|
|
ERROR_SUCCESS == RegEnumKeyEx(
|
|
key, index, name, &name_size, 0, 0, 0, &last_write_time);
|
|
++index,
|
|
name_size = sizeof(name)
|
|
)
|
|
{
|
|
name[name_size] = 0;
|
|
result = list_append(result, list_new(object_new(name)));
|
|
}
|
|
|
|
RegCloseKey(key);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static LIST* get_value_names(HKEY key, char const* path)
|
|
{
|
|
LIST* result = 0;
|
|
|
|
if ( ERROR_SUCCESS == RegOpenKeyEx(key, path, 0, KEY_QUERY_VALUE, &key) )
|
|
{
|
|
char name[MAX_REGISTRY_VALUENAME_LENGTH];
|
|
DWORD name_size = sizeof(name);
|
|
DWORD index;
|
|
|
|
for ( index = 0;
|
|
ERROR_SUCCESS == RegEnumValue(
|
|
key, index, name, &name_size, 0, 0, 0, 0);
|
|
++index,
|
|
name_size = sizeof(name)
|
|
)
|
|
{
|
|
name[name_size] = 0;
|
|
result = list_append(result, list_new(object_new(name)));
|
|
}
|
|
|
|
RegCloseKey(key);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
LIST * builtin_system_registry_names( FRAME * frame, int flags )
|
|
{
|
|
char const* path = object_str( list_front( lol_get(frame->args, 0) ) );
|
|
char const* result_type = object_str( list_front( lol_get(frame->args, 1) ) );
|
|
|
|
HKEY key = get_key(&path);
|
|
|
|
if ( !strcmp(result_type, "subkeys") )
|
|
return get_subkey_names(key, path);
|
|
if ( !strcmp(result_type, "values") )
|
|
return get_value_names(key, path);
|
|
return 0;
|
|
}
|
|
|
|
# endif
|