%% options
copyright owner = Dirk Krause
copyright year = 2015-xxxx
license = bsd
%% header
/** @file
Access Windows registry, use
8 bit character names.
CRT on Windows: Optional.
*/
#ifndef DK4CONF_H_INCLUDED
#include "dk4conf.h"
#endif
#ifndef DK4TYPES_H_INCLUDED
#include "dk4types.h"
#endif
#ifndef DK4ERROR_H_INCLUDED
#include "dk4error.h"
#endif
#ifndef DK4WREGK_H_INCLUDED
#include "dk4wregk.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/** Open a registry key.
@param pk Parent key identifier.
@param keyname Name of registry key to open.
@param wr Flag: Open for write access too.
@param erp Error report, may be NULL.
@return Pointer to key handle structure on success, NULL on error.
Error codes:
- DK4_E_NOT_SUPPORTED
if the function is run on a non-Windows system,
- DK4_E_INVALID_ARGUMENTS
if pk or keyname is invalid,
- DK4_E_NOT_FOUND
if opening or creating the registry key failed,
- DK4_E_MEMORY_ALLOCATION_FAILED
if memory allocation for the key handle structure failed.
*/
void *
dk4wreg_open_key_c8(int pk, const char *keyname, int wr, dk4_er_t *erp);
/** Set a string value.
@param kptr Key handle structure.
@param name Entry name.
@param val Entry value.
@param expand Flag: Use REG_EXPAND_SZ (1) or REG_SZ (0).
@param erp Error report, may be NULL.
@return 1 on success, 0 on error.
Error codes:
- DK4_E_NOT_SUPPORTED
when called on non-Windows systems,
- DK4_E_INVALID_ARGUMENTS
if kptr or val is NULL,
- DK4_E_MATH_OVERFLOW
if the name is too long,
- DK4_E_SYSTEM
if RegSetValueExA() failed.
*/
int
dk4wreg_set_string_c8(
void *kptr, const char *name, const char *val, int expand, dk4_er_t *erp
);
/** Get string value.
@param kptr Key handle structure.
@param name Entry name.
@param bptr Buffer for result string.
@param sz Result buffer length.
@param expand Pointer to expand flag output variable.
This variable is set to 1 if the string found
is of type REG_EXPAND_SZ. The variable is left
unchanged for REG_SZ.
@param erp Error report, may be NULL.
@return 1 on success, 0 on error.
Error codes:
- DK4_E_NOT_SUPPORTED
when called on non-Windows systems,
- DK4_E_INVALID_ARGUMENTS
if kptr, name, or bptr is NULL or sz is 0,
- DK4_E_NOT_FOUND
if the entry is not found or has 0 length,
- DK4_E_SYNTAX
if the entry is not a string type.
*/
int
dk4wreg_get_string_c8(
void *kptr,
const char *name,
char *bptr,
size_t sz,
int *expand,
dk4_er_t *erp
);
/** Set DWORD registry entry.
@param kptr Key handle structure.
@param name Entry name.
@param val Value.
@param erp Error report, may be NULL.
@return 1 on success, 0 on error.
Error codes:
- DK4_E_NOT_SUPPORTED
when called on a non-Windows system,
- DK4_E_INVALID_ARGUMENTS
if kptr is NULL,
- DK4_E_SYSTEM
if RegSetValueExA() failed.
*/
int
dk4wreg_set_dword_c8(
void *kptr, const char *name, dk4_dword_t val, dk4_er_t *erp
);
/** Retrieve DWORD value from registry.
@param kptr Key handle structure.
@param name Entry name.
@param vptr Pointer to result variable.
@param erp Error report, may be NULL.
@return 1 on success, 0 on error.
*/
int
dk4wreg_get_dword_c8(
void *kptr,
const char *name,
dk4_dword_t *vptr,
dk4_er_t *erp
);
/** Get string value.
@param kptr Key handle structure.
@param name Entry name.
@param dptr Buffer for result string.
@param dsz Result buffer length.
@param b1 First buffer, used for result from RegQueryValue().
Should have same size as dptr.
@param b1sz Size of b1.
@param b2 Second buffer, used for result from ExpandEnvironmentStrings.
Should be 2 characters larger than dptr.
@param b2sz Size of b2.
@param erp Error report, may be NULL.
@return 1 on success, 0 on error.
Error codes:
- DK4_E_NOT_SUPPORTED
when called on non-Windows systems,
- DK4_E_INVALID_ARGUMENTS
if kptr, name, dptr, b1 or b2 is NULL or
dsz, b1sz or b2sz is 0 or out of range,
- DK4_E_BUFFER_TOO_SMALL
if one of the buffers is too small,
- DK4_E_NOT_FOUND
if the entry is not found or has 0 length,
- DK4_E_SYNTAX
if the entry is not a string type.
*/
int
dk4wreg_get_expanded_string_c8(
void *kptr,
const char *name,
char *dptr,
size_t dsz,
char *b1,
size_t b1sz,
char *b2,
size_t b2sz,
dk4_er_t *erp
);
#ifdef __cplusplus
}
#endif
%% module
#include "dk4conf.h"
#include "dk4wregt.h"
#include "dk4wreg8.h"
#ifndef DK4MEM_H_INCLUDED
#include "dk4mem.h"
#endif
#include "dk4maasz.h"
#if DK4_ON_WINDOWS
#ifndef WINDOWS_H_INCLUDED
#include
#define WINDOWS_H_INCLUDED 1
#endif
#ifndef WINBASE_H_INCLUDED
#include
#define WINBASE_H_INCLUDED 1
#endif
#ifndef WINREG_H_INCLUDED
#include
#define WINREG_H_INCLUDED 1
#endif
#endif
#ifndef DK4STR8_H_INCLUDED
#include "dk4str8.h"
#endif
$!trace-include
void *
dk4wreg_open_key_c8(int pk, const char *keyname, int wr, dk4_er_t *erp)
{
#if DK4_ON_WINDOWS
dk4_wreg_key_t *back = NULL;
HKEY park = HKEY_LOCAL_MACHINE;
LONG res;
DWORD disp;
if (NULL != keyname) {
switch (pk) {
case DK4_WREGKEY_HKLM:
case DK4_WREGKEY_HKCU:
case DK4_WREGKEY_HKCL:
case DK4_WREGKEY_KHUS:
case DK4_WREGKEY_HKCC: {
switch (pk) {
case DK4_WREGKEY_HKLM: {
park = HKEY_LOCAL_MACHINE;
} break;
case DK4_WREGKEY_HKCU: {
park = HKEY_CURRENT_USER;
} break;
case DK4_WREGKEY_HKCL: {
park = HKEY_CLASSES_ROOT;
} break;
case DK4_WREGKEY_KHUS: {
park = HKEY_USERS;
} break;
case DK4_WREGKEY_HKCC: {
park = HKEY_CURRENT_CONFIG;
} break;
}
back = dk4mem_new(dk4_wreg_key_t,1,erp);
if (NULL != back) {
res = RegCreateKeyExA(
park,
keyname,
(DWORD)0,
NULL,
REG_OPTION_NON_VOLATILE,
((0 != wr) ? (KEY_ALL_ACCESS) : (KEY_READ)),
NULL,
&(back->hk),
&disp
);
if (ERROR_SUCCESS != res) {
dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
dk4mem_free(back);
back = NULL;
}
}
} break;
default: {
dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
} break;
}
} else {
dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
}
return ((void *)back);
#else
dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
return NULL;
#endif
}
int
dk4wreg_set_string_c8(
void *kptr, const char *name, const char *val, int expand, dk4_er_t *erp
)
{
#if DK4_ON_WINDOWS
dk4_er_t er;
dk4_wreg_key_t *hptr;
int back = 0;
size_t lgt;
DWORD dwt = REG_SZ;
DWORD dw0 = (DWORD)0UL;
DWORD sz;
LONG res;
if ((NULL != kptr) && (NULL != val)) {
if (0 != expand) { dwt = REG_EXPAND_SZ; }
dk4error_init(&er);
lgt = dk4ma_size_t_add( 1, dk4str8_len(val), &er);
if (DK4_E_NONE == er.ec) {
if ((dk4_um_t)0x7FFFFFFFUL >= (dk4_um_t)lgt) {
sz = (DWORD)lgt;
hptr = (dk4_wreg_key_t *)kptr;
res = RegSetValueExA(
hptr->hk,
name,
dw0,
dwt,
(const BYTE *)val,
sz
);
if (ERROR_SUCCESS == res) {
back = 1;
} else {
dk4error_set_ldetails(erp, DK4_E_SYSTEM, res);
}
} else {
dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
}
} else {
dk4error_set_simple_error_code(erp, DK4_E_MATH_OVERFLOW);
}
} else {
dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
}
return back;
#else
dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
return 0;
#endif
}
int
dk4wreg_get_string_c8(
void *kptr,
const char *name,
char *bptr,
size_t sz,
int *expand,
dk4_er_t *erp
)
{
#if DK4_ON_WINDOWS
dk4_wreg_key_t *hptr;
int back = 0;
DWORD dwt = REG_SZ;
DWORD dws;
DWORD dwsbck;
LONG res;
if ((NULL != bptr) && (0 < sz)) {
*bptr = '\0';
}
if ((NULL != kptr) && (NULL != name) && (NULL != bptr) && (0 < sz)) {
if ((dk4_um_t)0x7FFFFFFFUL >= (dk4_um_t)sz) {
dws = (DWORD)sz;
} else {
dws = (DWORD)0x7FFFFFFFUL;
}
dwsbck = dws;
hptr = (dk4_wreg_key_t *)kptr;
res = RegQueryValueExA(
hptr->hk,
name,
NULL,
&dwt,
(LPBYTE)bptr,
&dws
);
if (ERROR_SUCCESS == res) {
switch (dwt) {
case REG_SZ: case REG_EXPAND_SZ: {
if ((DWORD)0L < dws) {
if (dws < dwsbck) { /* dws is positive */
bptr[dws] = '\0';
} else {
bptr[dwsbck-1] = '\0';
}
back = 1;
if (REG_EXPAND_SZ == dwt) {
if (NULL != expand) {
*expand = 1;
}
}
} else {
dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
}
} break;
default: {
/* ERROR: Not a string */
dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
} break;
}
} else {
dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
}
} else {
dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
}
return back;
#else
dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
return 0;
#endif
}
int
dk4wreg_set_dword_c8(
void *kptr, const char *name, dk4_dword_t val, dk4_er_t *erp
)
{
#if DK4_ON_WINDOWS
dk4_wreg_key_t *hptr;
int back = 0;
DWORD dwt = REG_DWORD;
DWORD dws = sizeof(DWORD);
DWORD dw0 = (DWORD)0L;
LONG res;
if (NULL != kptr) {
hptr = (dk4_wreg_key_t *)kptr;
res = RegSetValueExA(
hptr->hk,
name,
dw0,
dwt,
(const BYTE *)(&val),
dws
);
if (ERROR_SUCCESS == res) {
back = 1;
} else {
dk4error_set_ldetails(erp, DK4_E_SYSTEM, res);
}
} else {
dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
}
return back;
#else
dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
return 0;
#endif
}
int
dk4wreg_get_dword_c8(
void *kptr,
const char *name,
dk4_dword_t *vptr,
dk4_er_t *erp
)
{
#if DK4_ON_WINDOWS
dk4_wreg_key_t *hptr;
int back = 0;
DWORD dwt = REG_DWORD;
DWORD dws = (DWORD)sizeof(DWORD);
LONG res;
if ((NULL != kptr) && (NULL != vptr)) {
hptr = (dk4_wreg_key_t *)kptr;
res = RegQueryValueExA(
hptr->hk,
name,
NULL,
&dwt,
(LPBYTE)vptr,
&dws
);
if (ERROR_SUCCESS == res) {
if (REG_DWORD == dwt) {
if ((DWORD)sizeof(DWORD) == dws) {
back = 1;
} else {
dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
}
} else {
dk4error_set_simple_error_code(erp, DK4_E_SYNTAX);
}
} else {
dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND);
}
} else {
dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
}
return back;
#else
dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
return 0;
#endif
}
int
dk4wreg_get_expanded_string_c8(
void *kptr,
const char *name,
char *dptr,
size_t dsz,
char *b1,
size_t b1sz,
char *b2,
size_t b2sz,
dk4_er_t *erp
)
{
#if DK4_ON_WINDOWS
DWORD nc;
DWORD dws;
int expand = 0;
int back = 0;
$? "+ dk4wreg_get_expanded_string_c8 \"%!8s\"", TR_8STR(name)
if ((NULL != dptr) && (0 < dsz)) { *dptr = '\0'; }
if ((NULL != kptr) && (NULL != name) && (NULL != dptr) && (0 < dsz)) {
if ((NULL != b1) && (NULL != b2) && (0 < b1sz) && (2 < b2sz)) {
back = dk4wreg_get_string_c8(kptr, name, b1, b1sz, &expand, erp);
if (0 != back) { $? "- dk4wreg_get_string_c8"
if (0 != expand) { $? ". expansion"
if ((dk4_um_t)(0x7FFFFFFFUL) >= (dk4_um_t)b2sz) {
dws = (DWORD)b2sz; $? ". original size"
} else {
dws = 0x7FFFFFFFUL; $? ". cut size"
}
dws = dws - 2;
nc = ExpandEnvironmentStringsA(b1, b2, dws);
if ((0 < nc) && (nc <= dws)) { $? ". size ok"
back = dk4str8_cpy_s(dptr, dsz, b2, erp);
$!trace-code if (0 != back) {
$? ". result=\"%!8s\"", dptr
$!trace-code }
} else { $? "! buffer size"
dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
}
} else { $? ". no expansion"
back = dk4str8_cpy_s(dptr, dsz, b1, erp);
$!trace-code if (0 != back) {
$? ". result=\"%!8s\"", dptr
$!trace-code }
}
} else { $? "! dk4wreg_get_string_c8"
}
} else { $? "! arguments"
dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
}
} else { $? "! arguments"
dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
} $? "- dk4wreg_get_expanded_string_c8 %d", back
return back;
#else
dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED);
return 0;
#endif
}