1
0
mirror of https://github.com/solemnwarning/ipxwrapper synced 2024-12-30 16:45:37 +01:00
ipxwrapper/src/common.c

278 lines
6.2 KiB
C

/* IPXWrapper - Common functions
* Copyright (C) 2011 Daniel Collins <solemnwarning@solemnwarning.net>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <windows.h>
#include <iphlpapi.h>
#include "common.h"
#include "config.h"
enum ipx_log_level min_log_level = LOG_INFO;
static const char *dll_names[] = {
"ipxwrapper.dll",
"wsock32.dll",
"mswsock.dll",
"dpwsockx.dll",
"ws2_32.dll",
NULL
};
static HANDLE dll_handles[] = {NULL, NULL, NULL, NULL, NULL};
/* Convert a windows error number to an error message */
const char *w32_error(DWORD errnum) {
static char buf[1024] = {'\0'};
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errnum, 0, buf, 1023, NULL);
buf[strcspn(buf, "\r\n")] = '\0';
return buf;
}
HKEY reg_open_main(bool readwrite)
{
return reg_open_subkey(HKEY_CURRENT_USER, "Software\\IPXWrapper", readwrite);
}
HKEY reg_open_subkey(HKEY parent, const char *path, bool readwrite)
{
if(parent == NULL)
{
return NULL;
}
HKEY key;
int err;
if(readwrite)
{
err = RegCreateKeyEx(parent, path, 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &key, NULL);
}
else{
err = RegOpenKeyEx(parent, path, 0, KEY_READ, &key);
}
if(err != ERROR_SUCCESS)
{
if(err != ERROR_FILE_NOT_FOUND)
{
log_printf(LOG_ERROR, "Could not open registry: %s", w32_error(err));
}
return NULL;
}
return key;
}
void reg_close(HKEY key)
{
if(key != NULL)
{
RegCloseKey(key);
}
}
/* Check if a value exists.
* Returns true on success, false on failure.
*/
bool reg_check_value(HKEY key, const char *name)
{
if(key != NULL && RegQueryValueEx(key, name, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
return true;
}
return false;
}
bool reg_get_bin(HKEY key, const char *name, void *buf, size_t size, const void *default_value)
{
if(key != NULL)
{
DWORD bs = size;
int err = RegQueryValueEx(key, name, NULL, NULL, (BYTE*)buf, &bs);
if(err == ERROR_SUCCESS)
{
if(bs == size)
{
return true;
}
else{
log_printf(LOG_WARNING, "Registry value with incorrect size: %s", name);
}
}
else if(err != ERROR_FILE_NOT_FOUND)
{
log_printf(LOG_ERROR, "Error reading registry value: %s", w32_error(err));
}
}
if(default_value)
{
memcpy(buf, default_value, size);
}
return false;
}
bool reg_set_bin(HKEY key, const char *name, void *buf, size_t size)
{
if(key != NULL)
{
int err = RegSetValueEx(key, name, 0, REG_BINARY, (BYTE*)buf, size);
if(err == ERROR_SUCCESS)
{
return true;
}
else{
log_printf(LOG_ERROR, "Error writing registry value: %s", w32_error(err));
}
}
return false;
}
DWORD reg_get_dword(HKEY key, const char *name, DWORD default_value)
{
DWORD buf;
reg_get_bin(key, name, &buf, sizeof(buf), &default_value);
return buf;
}
bool reg_set_dword(HKEY key, const char *name, DWORD value)
{
if(key != NULL)
{
int err = RegSetValueEx(key, name, 0, REG_DWORD, (BYTE*)&value, sizeof(value));
if(err == ERROR_SUCCESS)
{
return true;
}
else{
log_printf(LOG_ERROR, "Error writing registry value: %s", w32_error(err));
}
}
return false;
}
/* Read a 32-bit network address from the registry.
* Returns default_value upon failure.
*/
addr32_t reg_get_addr32(HKEY key, const char *name, addr32_t default_value)
{
unsigned char buf[4], default_buf[4];
addr32_out(default_buf, default_value);
reg_get_bin(key, name, buf, 4, default_buf);
return addr32_in(buf);
}
/* Store a 32-bit network address in the registry.
* Returns true on success, false on failure.
*/
bool reg_set_addr32(HKEY key, const char *name, addr32_t value)
{
unsigned char buf[4];
addr32_out(buf, value);
return reg_set_bin(key, name, buf, sizeof(buf));
}
/* Read a 48-bit network address from the registry.
* Returns default_value upon failure.
*/
addr48_t reg_get_addr48(HKEY key, const char *name, addr48_t default_value)
{
unsigned char buf[6], default_buf[6];
addr48_out(default_buf, default_value);
reg_get_bin(key, name, buf, 6, default_buf);
return addr48_in(buf);
}
/* Store a 48-bit network address in the registry.
* Returns true on success, false on failure.
*/
bool reg_set_addr48(HKEY key, const char *name, addr48_t value)
{
unsigned char buf[6];
addr48_out(buf, value);
return reg_set_bin(key, name, buf, sizeof(buf));
}
void load_dll(unsigned int dllnum) {
char path[512];
if(dllnum) {
GetSystemDirectory(path, sizeof(path));
if(strlen(path) + strlen(dll_names[dllnum]) + 2 > sizeof(path)) {
log_printf(LOG_ERROR, "Path buffer too small, cannot load %s", dll_names[dllnum]);
abort();
}
strcat(path, "\\");
strcat(path, dll_names[dllnum]);
}
const char *dll = dllnum ? path : dll_names[dllnum];
dll_handles[dllnum] = LoadLibrary(dll);
if(!dll_handles[dllnum]) {
log_printf(LOG_ERROR, "Error loading %s: %s", dll, w32_error(GetLastError()));
abort();
}
}
void unload_dlls(void) {
int i;
for(i = 0; dll_names[i]; i++) {
if(dll_handles[i]) {
FreeLibrary(dll_handles[i]);
dll_handles[i] = NULL;
}
}
}
void __stdcall *find_sym(unsigned int dllnum, const char *symbol) {
if(!dll_handles[dllnum]) {
load_dll(dllnum);
}
void *ptr = GetProcAddress(dll_handles[dllnum], symbol);
if(!ptr) {
log_printf(LOG_ERROR, "Missing symbol in %s: %s", dll_names[dllnum], symbol);
abort();
}
return ptr;
}
void __stdcall log_call(unsigned int dllnum, const char *symbol) {
log_printf(LOG_CALL, "%s:%s", dll_names[dllnum], symbol);
}