%% 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 }