#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "wrapcommon.h"
#define IDN_GLOBAL 1
#define IDN_PERPROG 2
#define IDN_CURUSER 4
#define IDNKEY_WRAPPER "Software\\JPNIC\\IDN"
#define IDNKEY_PERPROG "Software\\JPNIC\\IDN\\PerProg"
#define IDNVAL_WHERE "Where"
#define IDNVAL_ENCODE "Encoding"
#define IDNVAL_LOGLVL "LogLevel"
#define IDNVAL_LOGFILE "LogFile"
#define IDNVAL_INSDIR "InstallDir"
static int GetRegistry(HKEY top, const char *key, const char *name,
DWORD type, void *param, DWORD length);
static char *GetPerProgKey(char *buf, size_t len);
static int GetFromRegistry(const char *name, int where, DWORD type,
void *param, DWORD length);
static int GetIntFromRegistry(const char *name, int defvalue, int where);
static BOOL GetStringFromRegistry(const char *name, char *result,
size_t length, int where);
static int
GetRegistry(HKEY top, const char *key, const char *name, DWORD type,
void *param, DWORD length)
{
LONG stat;
HKEY hk;
DWORD realtype;
stat = RegOpenKeyEx(top, key, 0, KEY_READ, &hk);
if (stat != ERROR_SUCCESS) {
return 0;
}
stat = RegQueryValueEx(hk, (LPCTSTR)name, NULL,
&realtype, (LPBYTE)param, &length);
RegCloseKey(hk);
if (stat != ERROR_SUCCESS || realtype != type)
return 0;
return 1;
}
static char *
GetPerProgKey(char *buf, size_t len)
{
char exename[256];
char prgname[256];
char *p, *last;
GetModuleFileName(NULL, exename, 256);
for (p = exename, last = NULL; *p != '\0'; p++) {
if (*p == '/' || *p == '\\') {
last = p;
}
}
strcpy(prgname, (last == NULL) ? exename : (last + 1));
if ((p = strrchr(prgname, '.')) != NULL) {
*p = '\0';
}
if (strlen(IDNKEY_PERPROG) + 1 + strlen(prgname) >= len) {
return (NULL);
}
sprintf(buf, "%s\\%s", IDNKEY_PERPROG, prgname);
return buf;
}
static int
GetFromRegistry(const char *name, int where, DWORD type,
void *param, DWORD length)
{
if (where & IDN_PERPROG) {
char keyname[256];
if (GetPerProgKey(keyname, sizeof(keyname)) != NULL) {
if (((where & IDN_CURUSER) &&
GetRegistry(HKEY_CURRENT_USER, keyname, name,
type, param, length)) ||
GetRegistry(HKEY_LOCAL_MACHINE, keyname, name,
type, param, length)) {
return (1);
}
}
}
if (where & IDN_GLOBAL) {
if (((where & IDN_CURUSER) &&
GetRegistry(HKEY_CURRENT_USER, IDNKEY_WRAPPER, name,
type, param, length)) ||
GetRegistry(HKEY_LOCAL_MACHINE, IDNKEY_WRAPPER, name,
type, param, length)) {
return (1);
}
}
return (0);
}
static int
GetIntFromRegistry(const char *name, int defvalue, int where)
{
DWORD param;
if (GetFromRegistry(name, where, REG_DWORD, ¶m, sizeof(param))) {
return ((int)param);
}
return (defvalue);
}
static BOOL
GetStringFromRegistry(const char *name, char *result, size_t length, int where)
{
if (GetFromRegistry(name, where, REG_SZ, result, (DWORD)length)) {
return (TRUE);
}
return (FALSE);
}
int
idnEncodeWhere(void)
{
int v = GetIntFromRegistry(IDNVAL_WHERE, IDN_ENCODE_ALWAYS,
IDN_GLOBAL|IDN_PERPROG|IDN_CURUSER);
idnLogPrintf(idn_log_level_trace, "idnEncodeWhere: %d\n", v);
return (v);
}
BOOL
idnGetLogFile(char *file, size_t len)
{
BOOL v = GetStringFromRegistry(IDNVAL_LOGFILE, file, len,
IDN_GLOBAL|IDN_CURUSER);
idnLogPrintf(idn_log_level_trace, "idnGetLogFile: %-.100s\n",
(v == TRUE) ? file : "<none>");
return (v);
}
BOOL
idnGetPrgEncoding(char *enc, size_t len)
{
if (GetStringFromRegistry(IDNVAL_ENCODE, enc, len,
IDN_PERPROG|IDN_CURUSER) != TRUE ||
enc[0] == '\0') {
sprintf(enc, "CP%d", GetACP());
}
idnLogPrintf(idn_log_level_trace,
"idnGetPrgEncoding: %-.30s\n", enc);
return (TRUE);
}
int
idnGetLogLevel(void)
{
int v = GetIntFromRegistry(IDNVAL_LOGLVL, 0,
IDN_GLOBAL|IDN_CURUSER);
idnLogPrintf(idn_log_level_trace, "idnGetLogLevel: %d\n", v);
return (v);
}
BOOL
idnGetInstallDir(char *dir, size_t len)
{
BOOL v = GetStringFromRegistry(IDNVAL_INSDIR, dir, len, IDN_GLOBAL);
idnLogPrintf(idn_log_level_trace, "idnGetInstallDir: %-.100s\n",
(v == TRUE) ? dir : "<none>");
return (v);
}