2011-08-28 21:27:06 +00:00
|
|
|
/* 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>
|
2011-08-29 10:03:58 +00:00
|
|
|
#include <iphlpapi.h>
|
2011-08-28 21:27:06 +00:00
|
|
|
|
|
|
|
#include "common.h"
|
2011-08-29 10:03:58 +00:00
|
|
|
#include "config.h"
|
2011-08-28 21:27:06 +00:00
|
|
|
|
|
|
|
HKEY regkey = NULL;
|
|
|
|
|
2011-11-16 21:32:59 +00:00
|
|
|
enum ipx_log_level min_log_level = LOG_INFO;
|
2011-09-11 13:28:41 +00:00
|
|
|
|
|
|
|
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};
|
|
|
|
|
2011-08-28 21:27:06 +00:00
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2012-10-20 19:21:59 +00:00
|
|
|
/* Format an IPX address as a string.
|
|
|
|
*
|
|
|
|
* The socket number should be in network byte order and the supplied buffer
|
|
|
|
* must be at least IPX_SADDR_SIZE bytes long.
|
|
|
|
*/
|
|
|
|
void ipx_to_string(char *buf, const netnum_t net, const nodenum_t node, uint16_t sock)
|
|
|
|
{
|
|
|
|
/* World's ugliest use of sprintf? */
|
|
|
|
|
|
|
|
sprintf(
|
|
|
|
buf,
|
|
|
|
|
|
|
|
"%02X:%02X:%02X:%02X/%02X:%02X:%02X:%02X:%02X:%02X/%hu",
|
|
|
|
|
|
|
|
(unsigned int)(unsigned char)(net[0]),
|
|
|
|
(unsigned int)(unsigned char)(net[1]),
|
|
|
|
(unsigned int)(unsigned char)(net[2]),
|
|
|
|
(unsigned int)(unsigned char)(net[3]),
|
|
|
|
|
|
|
|
(unsigned int)(unsigned char)(node[0]),
|
|
|
|
(unsigned int)(unsigned char)(node[1]),
|
|
|
|
(unsigned int)(unsigned char)(node[2]),
|
|
|
|
(unsigned int)(unsigned char)(node[3]),
|
|
|
|
(unsigned int)(unsigned char)(node[4]),
|
|
|
|
(unsigned int)(unsigned char)(node[5]),
|
|
|
|
|
|
|
|
ntohs(sock)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2011-08-28 21:27:06 +00:00
|
|
|
BOOL reg_open(REGSAM access) {
|
|
|
|
int err = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\IPXWrapper", 0, access, ®key);
|
|
|
|
|
|
|
|
if(err != ERROR_SUCCESS) {
|
2011-11-16 21:32:59 +00:00
|
|
|
log_printf(LOG_ERROR, "Could not open registry: %s", w32_error(err));
|
2011-08-28 21:27:06 +00:00
|
|
|
regkey = NULL;
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void reg_close(void) {
|
|
|
|
if(regkey) {
|
|
|
|
RegCloseKey(regkey);
|
|
|
|
regkey = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
char reg_get_char(const char *val_name, char default_val) {
|
|
|
|
char buf;
|
2011-09-21 21:57:28 +00:00
|
|
|
return reg_get_bin(val_name, &buf, 1) == 1 ? buf : default_val;
|
2011-08-28 21:27:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DWORD reg_get_bin(const char *val_name, void *buf, DWORD size) {
|
|
|
|
if(!regkey) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int err = RegQueryValueEx(regkey, val_name, NULL, NULL, (BYTE*)buf, &size);
|
|
|
|
|
|
|
|
if(err != ERROR_SUCCESS) {
|
2011-09-21 21:57:28 +00:00
|
|
|
if(err != ERROR_FILE_NOT_FOUND) {
|
2011-11-16 21:32:59 +00:00
|
|
|
log_printf(LOG_ERROR, "Error reading registry value: %s", w32_error(err));
|
2011-09-21 21:57:28 +00:00
|
|
|
}
|
|
|
|
|
2011-08-28 21:27:06 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2011-09-19 00:43:16 +00:00
|
|
|
DWORD reg_get_dword(const char *val_name, DWORD default_val) {
|
|
|
|
DWORD buf;
|
|
|
|
return reg_get_bin(val_name, &buf, sizeof(buf)) == sizeof(buf) ? buf : default_val;
|
|
|
|
}
|
|
|
|
|
2011-09-11 13:28:41 +00:00
|
|
|
void load_dll(unsigned int dllnum) {
|
|
|
|
char path[512];
|
2011-08-28 21:27:06 +00:00
|
|
|
|
2011-09-11 13:28:41 +00:00
|
|
|
if(dllnum) {
|
|
|
|
GetSystemDirectory(path, sizeof(path));
|
|
|
|
|
|
|
|
if(strlen(path) + strlen(dll_names[dllnum]) + 2 > sizeof(path)) {
|
2011-11-16 21:32:59 +00:00
|
|
|
log_printf(LOG_ERROR, "Path buffer too small, cannot load %s", dll_names[dllnum]);
|
2011-09-11 13:28:41 +00:00
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
|
|
|
strcat(path, "\\");
|
|
|
|
strcat(path, dll_names[dllnum]);
|
|
|
|
}
|
2011-08-28 21:27:06 +00:00
|
|
|
|
2011-09-15 14:28:31 +00:00
|
|
|
const char *dll = dllnum ? path : dll_names[dllnum];
|
|
|
|
|
|
|
|
dll_handles[dllnum] = LoadLibrary(dll);
|
2011-09-11 13:28:41 +00:00
|
|
|
if(!dll_handles[dllnum]) {
|
2011-11-16 21:32:59 +00:00
|
|
|
log_printf(LOG_ERROR, "Error loading %s: %s", dll, w32_error(GetLastError()));
|
2011-09-11 13:28:41 +00:00
|
|
|
abort();
|
2011-08-28 21:27:06 +00:00
|
|
|
}
|
2011-09-11 13:28:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void unload_dlls(void) {
|
|
|
|
int i;
|
2011-08-28 21:27:06 +00:00
|
|
|
|
2011-09-11 13:28:41 +00:00
|
|
|
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);
|
|
|
|
}
|
2011-08-28 21:27:06 +00:00
|
|
|
|
2011-09-11 13:28:41 +00:00
|
|
|
void *ptr = GetProcAddress(dll_handles[dllnum], symbol);
|
|
|
|
if(!ptr) {
|
2011-11-16 21:32:59 +00:00
|
|
|
log_printf(LOG_ERROR, "Missing symbol in %s: %s", dll_names[dllnum], symbol);
|
2011-09-11 13:28:41 +00:00
|
|
|
abort();
|
2011-08-28 21:27:06 +00:00
|
|
|
}
|
|
|
|
|
2011-09-11 13:28:41 +00:00
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void __stdcall log_call(unsigned int dllnum, const char *symbol) {
|
2011-11-16 21:32:59 +00:00
|
|
|
log_printf(LOG_CALL, "%s:%s", dll_names[dllnum], symbol);
|
2011-08-28 21:27:06 +00:00
|
|
|
}
|