Files
sigmaker-ida/idasdk75/include/registry.hpp
2021-06-05 21:10:25 +03:00

376 lines
10 KiB
C++

/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-2020 Hex-Rays
* ALL RIGHTS RESERVED.
*
*/
#ifndef __REGISTRY_HPP
#define __REGISTRY_HPP
/*! \file registry.hpp
\brief Registry related functions
IDA uses the registry to store global configuration options that must
persist after IDA has been closed.
On Windows, IDA uses the Windows registry directly. On Unix systems, the registry
is stored in a file (typically ~/.idapro/ida.reg).
The root key for accessing IDA settings in the registry is defined by #ROOT_KEY_NAME.
*/
/// Key used to store IDA settings in registry (Windows version).
/// \note this name is automatically prepended to all
/// key names passed to functions in this file.
#define ROOT_KEY_NAME "Software\\Hex-Rays\\IDA"
/// \cond
// Low level functions. DO NOT USE THEM. See the wrappers below.
// 'mode' is:
// - 0: data is a raw buffer, and its datalen must be able to hold the entire binary contents
// - 1: data is a raw buffer, and its datalen doesn't need to be able to hold the entire binary contents
// - 2: data is a ::bytevec_t*, datalen is ignored.
idaman bool ida_export reg_bin_op(
const char *name,
bool save,
void *data,
size_t datalen,
const char *subkey,
int mode = 0);
idaman bool ida_export reg_str_get(qstring *buf, const char *name, const char *subkey);
idaman void ida_export reg_str_set(const char *name, const char *subkey, const char *buf);
idaman int ida_export reg_int_op(
const char *name,
bool save,
int value,
const char *subkey = NULL);
/// \endcond
/// Types of values stored in the registry
enum regval_type_t
{
reg_unknown = 0, ///< unknown
reg_sz = 1, ///< utf8 string
reg_binary = 3, ///< binary data
reg_dword = 4 ///< 32-bit number
};
/// Delete a key from the registry
idaman bool ida_export reg_delete_subkey(const char *name);
/// Delete a subtree from the registry
idaman bool ida_export reg_delete_tree(const char *name);
/// Delete a value from the registry.
/// \param name value name
/// \param subkey parent key
/// \return success
idaman bool ida_export reg_delete(const char *name, const char *subkey = NULL);
/// Is there already a key with the given name?
idaman bool ida_export reg_subkey_exists(const char *name);
/// Is there already a value with the given name?
/// \param name value name
/// \param subkey parent key
idaman bool ida_export reg_exists(const char *name, const char *subkey = NULL);
/// Retrieve the child names of the given key.
/// \param out result
/// \param name key name
/// \param subkeys if true, collect subkey names. if false, collect value names.
/// \return false if the given key does not exist
idaman bool ida_export reg_subkey_children(qstrvec_t *out, const char *name, bool subkeys);
/// Get data type of a given value.
/// \param out result
/// \param name value name
/// \param subkey key name
/// \return false if the [key+]value doesn't exist
idaman bool ida_export reg_data_type(regval_type_t *out, const char *name, const char *subkey = NULL);
/// Retrieve all string values associated with the given key.
/// Also see reg_update_strlist().
idaman void ida_export reg_read_strlist(qstrvec_t *list, const char *subkey);
/// Update list of strings associated with given key.
/// \param subkey key name
/// \param add string to be added to list, can be NULL
/// \param maxrecs limit list to this size
/// \param rem string to be removed from list, can be NULL
/// \param ignorecase ignore case for 'add' and 'rem'
idaman void ida_export reg_update_strlist(
const char *subkey,
const char *add,
size_t maxrecs,
const char *rem = NULL,
bool ignorecase = false);
/// Write binary data to the registry.
/// \param name value name
/// \param data input, must not be NULL
/// \param datalen length of input in bytes
/// \param subkey key name
inline void reg_write_binary(
const char *name,
const void *data,
size_t datalen,
const char *subkey = NULL)
{
reg_bin_op(name, true, CONST_CAST(void *)(data), datalen, subkey);
}
/// Read binary data from the registry.
/// \param name value name
/// \param[out] data result, must not be NULL
/// \param datalen length of out buffer in bytes
/// \param subkey key name
/// \return false if 'data' is not large enough to hold all data present.
/// in this case 'data' is left untouched.
inline bool reg_read_binary(
const char *name,
void *data,
size_t datalen,
const char *subkey = NULL)
{
return reg_bin_op(name, false, data, datalen, subkey);
}
/// Read a chunk of binary data from the registry.
/// This function succeeds even in the case of a partial read.
/// \param name value name
/// \param[out] data result, must not be NULL
/// \param datalen length of output buffer in bytes
/// \param subkey key name
/// \return success
inline bool reg_read_binary_part(
const char *name,
void *data,
size_t datalen,
const char *subkey = NULL)
{
return reg_bin_op(name, false, data, datalen, subkey, 1);
}
/// Read binary data from the registry.
/// \param name value name
/// \param[out] data output buffer, must not be NULL
/// \param subkey key name
/// \return success
inline bool reg_read_binary(
const char *name,
bytevec_t *data,
const char *subkey = NULL)
{
return reg_bin_op(name, false, data, 0, subkey, 2);
}
/// Write a string to the registry.
/// \param name value name
/// \param utf8 utf8-encoded string
/// \param subkey key name
inline void reg_write_string(
const char *name,
const char *utf8,
const char *subkey = NULL)
{
reg_str_set(name, subkey, utf8);
}
/// Read a string from the registry.
/// \param[out] utf8 output buffer
/// \param name value name
/// \param subkey key name
/// \return success
inline bool reg_read_string(
qstring *utf8,
const char *name,
const char *subkey = NULL)
{
return reg_str_get(utf8, name, subkey);
}
/// Read integer value from the registry.
/// \param name value name
/// \param defval default value
/// \param subkey key name
/// \return the value read from the registry, or 'defval' if the read failed
inline int reg_read_int(const char *name, int defval, const char *subkey = NULL)
{
return reg_int_op(name, false, defval, subkey);
}
/// Write integer value to the registry.
/// \param name value name
/// \param value value to write
/// \param subkey key name
inline void reg_write_int(const char *name, int value, const char *subkey = NULL)
{
reg_int_op(name, true, value, subkey);
}
/// Read boolean value from the registry.
/// \param name value name
/// \param defval default value
/// \param subkey key name
/// \return boolean read from registry, or 'defval' if the read failed
inline bool reg_read_bool(const char *name, bool defval, const char *subkey = NULL)
{
return reg_int_op(name, false, int(defval), subkey) != 0;
}
/// Write boolean value to the registry.
/// \param name value name
/// \param value boolean to write (nonzero = true)
/// \param subkey key name
inline void reg_write_bool(const char *name, int value, const char *subkey = NULL)
{
reg_int_op(name, true, value != 0, subkey);
}
/// Get all subkey names of given key
inline bool reg_subkey_subkeys(qstrvec_t *out, const char *name)
{
return reg_subkey_children(out, name, true);
}
/// Get all value names under given key
inline bool reg_subkey_values(qstrvec_t *out, const char *name)
{
return reg_subkey_children(out, name, false);
}
/// Update registry with a file list.
/// Case sensitivity will vary depending on the target OS.
/// \note 'add' and 'rem' must be UTF-8, just like for regular string operations.
inline void reg_update_filestrlist(
const char *subkey,
const char *add,
size_t maxrecs,
const char *rem = NULL)
{
reg_update_strlist(
subkey, add, maxrecs, rem,
#ifdef __NT__ // Ignore case in Windows
true
#else
false
#endif
);
}
//-----------------------------------------------------------------------------
// INTERNALS
/// \cond
#define _RVN_(f) regname_ ## f
#ifndef __DEFINE_REG_NAMES__
#define REG_VAL_NAME(n,s) \
extern const char _RVN_(n)[]
#else
#define REG_VAL_NAME(n,s) \
extern const char _RVN_(n)[]; \
const char _RVN_(n)[] = s
#endif
#define REG_BOOL_FUNC(func, valname) \
REG_VAL_NAME(func, valname); \
inline void regset_ ## func(bool value) \
{ reg_write_bool(_RVN_(func), value); } \
inline bool regget_ ## func(bool def) \
{ return reg_read_bool(_RVN_(func), def); }
#define REG_INT_FUNC(func, valname) \
REG_VAL_NAME(func,valname); \
inline void regset_ ## func(int value) \
{ \
reg_int_op(_RVN_(func), true, value); \
} \
inline int regget_ ## func(int def=0) \
{ \
return reg_int_op(_RVN_(func), false, def); \
}
idaman void ida_export reg_load(void);
idaman void ida_export reg_flush(void);
// if using history functions below, you have to define the following two variables
extern const char regkey_history[];
extern int max_history_files; // max number of files in the file menu
// and in the welcome box
#define MAX_HISTORY_FILES_DEF 10 // default value
inline void regget_history(qstrvec_t *list)
{
#ifdef DEMO
qnotused(list);
#else
reg_read_strlist(list, regkey_history);
#endif
}
inline void reg_update_history(const char *addfile, const char *removefile = NULL)
{
#ifdef DEMO
qnotused(addfile);
qnotused(removefile);
#else
// On Windows avoid duplicate upper/lower-case entries
// by using reg_update_filestrlist() which takes care of case sensitivity
reg_update_filestrlist(regkey_history, addfile, max_history_files, removefile);
#endif
}
inline void reg_history_size_truncate(void)
{
#ifndef DEMO
reg_update_strlist(regkey_history, NULL, max_history_files, NULL);
#endif
}
/// \endcond
#endif // __REGISTRY_HPP