From 09d012360b7821b5546b1334312e3fa53496356a Mon Sep 17 00:00:00 2001
From: xboi209 <xboi209@gmail.com>
Date: Fri, 12 Aug 2016 18:34:04 -0700
Subject: [PATCH 1/4] - Use wide functions instead of narrow functions when
 using WinAPI - Use RtlGetVersion() instead of GetVersionEx()

---
 CMakeLists.txt              |   2 +
 src/bnetd/main.cpp          |   7 +-
 src/bnetd/sql_odbc.cpp      |   2 +-
 src/bnetd/tracker.cpp       |  23 +--
 src/common/gui_printf.cpp   |  29 +--
 src/common/version.h        |  11 ++
 src/compat/mmap.cpp         |   4 +-
 src/compat/uname.cpp        | 366 +++++++++++++++++++++---------------
 src/compat/uname.h          |  48 ++---
 src/win32/d2cs_winmain.cpp  |  51 ++---
 src/win32/d2dbs_winmain.cpp |  56 +++---
 src/win32/service.cpp       | 163 ++++++++++------
 src/win32/winmain.cpp       | 313 +++++++++++++++---------------
 13 files changed, 597 insertions(+), 478 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index fa07da9..abbfbb3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -42,6 +42,8 @@ if (MSVC)
 	if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.0)
 		message(FATAL_ERROR "Visual Studio 2015 or higher required")
 	endif()
+	
+	add_definitions(-DUNICODE -D_UNICODE)
 endif ()
 
 if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
diff --git a/src/bnetd/main.cpp b/src/bnetd/main.cpp
index 5942241..b1de155 100644
--- a/src/bnetd/main.cpp
+++ b/src/bnetd/main.cpp
@@ -32,9 +32,6 @@
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif
-#ifdef HAVE_SYS_UTSNAME_H
-# include <sys/utsname.h>
-#endif
 #ifdef WIN32
 # include "win32/service.h"
 #endif
@@ -490,14 +487,14 @@ void post_server_shutdown(int status)
 
 void pvpgn_greeting(void)
 {
-	struct utsname     utsbuf;
 #ifdef HAVE_GETPID
 	eventlog(eventlog_level_info, __FUNCTION__, PVPGN_SOFTWARE" version " PVPGN_VERSION " process %u", (unsigned int)getpid());
 #else
 	eventlog(eventlog_level_info, __FUNCTION__, PVPGN_SOFTWARE" version "PVPGN_VERSION);
 #endif
 
-	if (!(uname(&utsbuf) < 0))
+	struct utsname utsbuf = {};
+	if (uname(&utsbuf) == 0)
 	{
 		eventlog(eventlog_level_info, __FUNCTION__, "running on %s (%s %s, %s)", utsbuf.sysname, utsbuf.version, utsbuf.release, utsbuf.machine);
 	}
diff --git a/src/bnetd/sql_odbc.cpp b/src/bnetd/sql_odbc.cpp
index 2e2e639..f39fb9d 100644
--- a/src/bnetd/sql_odbc.cpp
+++ b/src/bnetd/sql_odbc.cpp
@@ -17,7 +17,7 @@
  */
 #ifdef WITH_SQL_ODBC
 #include "common/setup_before.h"
-#ifdef WIN32
+#ifdef HAVE_WINDOWS_H
 # include <windows.h>
 #endif
 #include <sqlext.h>
diff --git a/src/bnetd/tracker.cpp b/src/bnetd/tracker.cpp
index 3f61af9..8f09971 100644
--- a/src/bnetd/tracker.cpp
+++ b/src/bnetd/tracker.cpp
@@ -24,10 +24,6 @@
 #include <cstring>
 #include <cerrno>
 
-#ifdef HAVE_SYS_UTSNAME_H
-# include <sys/utsname.h>
-#endif
-
 #include "compat/psock.h"
 #include "compat/strerror.h"
 #include "compat/uname.h"
@@ -93,7 +89,6 @@ namespace pvpgn
 			t_addr const *     addrt;
 			t_elem const *     currt;
 			t_trackpacket      packet;
-			struct utsname     utsbuf;
 			struct sockaddr_in tempaddr;
 			t_laddr_info *     laddr_info;
 			char               tempa[64];
@@ -140,18 +135,16 @@ namespace pvpgn
 				bn_int_nset(&packet.total_logins, connlist_total_logins());
 				bn_int_nset(&packet.total_games, gamelist_total_games());
 
-				if (uname(&utsbuf) < 0)
+				static struct utsname utsbuf = {};
+				if (utsbuf.sysname[0] == '0')
 				{
-					eventlog(eventlog_level_warn, __FUNCTION__, "could not get platform info (uname: %s)", pstrerror(errno));
-					std::strncpy((char *)packet.platform, "", sizeof(packet.platform));
-				}
-				else
-				{
-					std::strncpy((char *)packet.platform,
-						utsbuf.sysname,
-						sizeof(packet.platform));
-					bn_byte_set(&packet.platform[sizeof(packet.platform) - 1], '\0');
+					if (uname(&utsbuf) != 0)
+					{
+						eventlog(eventlog_level_warn, __FUNCTION__, "could not get platform info (uname: %s)", pstrerror(errno));
+						std::snprintf(reinterpret_cast<char*>(packet.platform), sizeof packet.platform, "");
+					}
 				}
+				std::snprintf(reinterpret_cast<char*>(packet.platform), sizeof packet.platform, "%s", utsbuf.sysname);
 
 				LIST_TRAVERSE_CONST(laddrs, currl)
 				{
diff --git a/src/common/gui_printf.cpp b/src/common/gui_printf.cpp
index 9b952bc..77d02a8 100644
--- a/src/common/gui_printf.cpp
+++ b/src/common/gui_printf.cpp
@@ -21,9 +21,12 @@
 #include "common/setup_before.h"
 #include "gui_printf.h"
 
+#include <cstdarg>
+#include <cwchar>
+
 #include <windows.h>
 #include <richedit.h>
-#include <cstdarg>
+
 #include "common/eventlog.h"
 #include "common/setup_after.h"
 
@@ -34,34 +37,32 @@ namespace pvpgn
 
 	static void guiAddText(const char *str, COLORREF clr)
 	{
-		int text_length;
-		CHARRANGE cr;
-		CHARRANGE ds;
-		CHARFORMAT fmt;
-
-		text_length = SendMessage(ghwndConsole, WM_GETTEXTLENGTH, 0, 0);
+		int text_length = SendMessageW(ghwndConsole, WM_GETTEXTLENGTH, 0, 0);
 
 		if (text_length > 30000)
 		{
+			CHARRANGE ds = {};
 			ds.cpMin = 0;
 			ds.cpMax = text_length - 30000;
-			SendMessage(ghwndConsole, EM_EXSETSEL, 0, (LPARAM)&ds);
-			SendMessage(ghwndConsole, EM_REPLACESEL, FALSE, 0);
+			SendMessageW(ghwndConsole, EM_EXSETSEL, 0, (LPARAM)&ds);
+			SendMessageW(ghwndConsole, EM_REPLACESEL, FALSE, 0);
 		}
 
+		CHARRANGE cr = {};
 		cr.cpMin = text_length;
 		cr.cpMax = text_length;
-		SendMessage(ghwndConsole, EM_EXSETSEL, 0, (LPARAM)&cr);
+		SendMessageW(ghwndConsole, EM_EXSETSEL, 0, (LPARAM)&cr);
 
-		fmt.cbSize = sizeof(CHARFORMAT);
+		CHARFORMATW fmt = {};
+		fmt.cbSize = sizeof(CHARFORMATW);
 		fmt.dwMask = CFM_COLOR | CFM_FACE | CFM_SIZE | CFM_BOLD | CFM_ITALIC | CFM_STRIKEOUT | CFM_UNDERLINE;
 		fmt.yHeight = 160;
 		fmt.dwEffects = 0;
 		fmt.crTextColor = clr;
-		strcpy(fmt.szFaceName, "Courier New");
+		std::swprintf(fmt.szFaceName, sizeof fmt.szFaceName, L"%ls", L"Courier New");
 
-		SendMessage(ghwndConsole, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&fmt);
-		SendMessage(ghwndConsole, EM_REPLACESEL, FALSE, (LPARAM)str);
+		SendMessageW(ghwndConsole, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&fmt);
+		SendMessageA(ghwndConsole, EM_REPLACESEL, FALSE, (LPARAM)str);
 	}
 
 	extern int gui_lvprintf(t_eventlog_level l, const char *format, va_list arglist)
diff --git a/src/common/version.h b/src/common/version.h
index 3d5283f..82dad14 100644
--- a/src/common/version.h
+++ b/src/common/version.h
@@ -13,9 +13,20 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
+#ifndef INCLUDED_COMMON_VERSION_H
+#define INCLUDED_COMMON_VERSION_H
+
+#define WIDEN(quote) WIDEN2(quote)
+#define WIDEN2(quote) L##quote
+
 #ifndef PVPGN_VERSION
 #define PVPGN_VERSION "1.99.7-PRO"
+#define PVPGN_VERSIONW WIDEN(PVPGN_VERSIONW)
 #endif
+
 #ifndef PVPGN_SOFTWARE
 #define PVPGN_SOFTWARE "PvPGN"
+#define PVPGN_SOFTWAREW WIDEN(PVPGN_SOFTWARE)
+#endif
+
 #endif
diff --git a/src/compat/mmap.cpp b/src/compat/mmap.cpp
index 4a2b2a8..2a5d24e 100644
--- a/src/compat/mmap.cpp
+++ b/src/compat/mmap.cpp
@@ -26,8 +26,10 @@
 #endif
 #include "common/xalloc.h"
 #include "mmap.h"
+#ifdef HAVE_WINDOWS_H
+#include <Windows.h>
+#endif
 #ifdef WIN32
-# include <windows.h>
 # include <io.h>
 #endif
 #include "common/setup_after.h"
diff --git a/src/compat/uname.cpp b/src/compat/uname.cpp
index 0566276..0baa2b2 100644
--- a/src/compat/uname.cpp
+++ b/src/compat/uname.cpp
@@ -13,28 +13,30 @@
  *
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * win32 part based on win32-uname.c from libguile
- *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
-#include "common/setup_before.h"
 #ifndef HAVE_UNAME
-
-#include <cstring>
-#include <cerrno>
-#ifdef WIN32
-# include <cstdio>
-# include <windows.h>
-#endif
+#include "common/setup_before.h"
 #include "uname.h"
+
+#include <cerrno>
+#include <cstdio>
+#include <cstring>
+#include <string>
+
+#ifdef HAVE_WINDOWS_H
+#include <Windows.h>
+#endif
+
 #include "common/setup_after.h"
 
 
 namespace pvpgn
 {
+	using RtlGetVersionProto = NTSTATUS(WINAPI*)(RTL_OSVERSIONINFOEXW* lpVersionInformation);
+#define STATUS_SUCCESS (0x00000000)
 
-	extern int uname(struct utsname * buf)
+	int uname(struct utsname* buf)
 	{
 		if (!buf)
 		{
@@ -42,155 +44,219 @@ namespace pvpgn
 			return -1;
 		}
 
-#ifdef WIN32
+#ifdef HAVE_WINDOWS_H
+		HMODULE hNtdll = nullptr;
+		if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L"ntdll.dll", &hNtdll) != 0)
 		{
-			enum { WinNT, Win95, Win98, WinUnknown };
-			OSVERSIONINFOEX osver;
-			SYSTEM_INFO sysinfo;
-			DWORD sLength;
-			DWORD os = WinUnknown;
-
-
-			osver.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
-			GetVersionEx((OSVERSIONINFO*)&osver);
-			GetSystemInfo(&sysinfo); 
-
-			// http://msdn.microsoft.com/en-us/library/windows/desktop/ms724833(v=vs.85).aspx
-			switch (osver.dwPlatformId)
+			auto fnRtlGetVersion = reinterpret_cast<RtlGetVersionProto>(GetProcAddress(hNtdll, "RtlGetVersion"));
+			if (fnRtlGetVersion != NULL)
 			{
-			case VER_PLATFORM_WIN32_NT:
-				if (osver.dwMajorVersion == 4)
-					std::strcpy(buf->sysname, "Windows NT4x");
-				else if (osver.dwMajorVersion <= 3)
-					std::strcpy(buf->sysname, "Windows NT3x");
-				else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion < 1)
-					std::strcpy(buf->sysname, "Windows 2000");
-				else if (osver.dwMajorVersion == 5 && (osver.dwMinorVersion == 1 // x86
-					|| (osver.dwMinorVersion == 2 && (osver.wProductType == VER_NT_WORKSTATION) && (sysinfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64))) ) // x64
-					std::strcpy(buf->sysname, "Windows XP");
-				else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 2)
-					std::strcpy(buf->sysname, "Windows Server 2003");
-				else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 0 && (osver.wProductType == VER_NT_WORKSTATION))
-					std::strcpy(buf->sysname, "Windows Vista");
-				else if (osver.dwMajorVersion == 6 && (osver.dwMinorVersion <= 1) && (osver.wProductType != VER_NT_WORKSTATION))
-					std::strcpy(buf->sysname, "Windows Server 2008");
-				else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 1 && (osver.wProductType == VER_NT_WORKSTATION))
-					std::strcpy(buf->sysname, "Windows 7");
-				else if (osver.dwMajorVersion == 6 && (osver.dwMinorVersion >= 2) && (osver.wProductType != VER_NT_WORKSTATION))
-					std::strcpy(buf->sysname, "Windows Server 2012");
-				else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion >= 2 && (osver.wProductType == VER_NT_WORKSTATION))
-					std::strcpy(buf->sysname, "Windows 8.x");
-				// FIXME: dwMinorVersion returns "2" instead of "3" on Windows 8.1
-				//else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 3 && (osver.wProductType == VER_NT_WORKSTATION))
-				//	std::strcpy(buf->sysname, "Windows 8.1");
-				else if (osver.wProductType != VER_NT_WORKSTATION)
-					std::strcpy(buf->sysname, "Windows Server >2012");
-				else
-					std::strcpy(buf->sysname, "Windows >8");
-
-				os = WinNT;
-				break;
-
-			case VER_PLATFORM_WIN32_WINDOWS: /* Win95, Win98 or WinME */
-				if ((osver.dwMajorVersion > 4) ||
-					((osver.dwMajorVersion == 4) && (osver.dwMinorVersion > 0)))
+				RTL_OSVERSIONINFOEXW verinfo = {};
+				verinfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
+				if (fnRtlGetVersion(&verinfo) == STATUS_SUCCESS)
 				{
-					if (osver.dwMinorVersion >= 90)
-						std::strcpy(buf->sysname, "Windows ME"); /* ME */
-					else
-						std::strcpy(buf->sysname, "Windows 98"); /* 98 */
-					os = Win98;
-				}
-				else{
-					std::strcpy(buf->sysname, "Windows 95"); /* 95 */
-					os = Win95;
-				}
+					std::string temp;
 
-				break;
+					SYSTEM_INFO sysinfo = {};
+					GetSystemInfo(&sysinfo);
 
-			case VER_PLATFORM_WIN32s: /* Windows 3.x */
-				std::strcpy(buf->sysname, "Windows");
-				break;
-
-			default:
-				std::strcpy(buf->sysname, "Win32");
-				break;
-			}
-
-			std::snprintf(buf->version, sizeof(buf->version), "%lu.%02lu", osver.dwMajorVersion, osver.dwMinorVersion);
-
-			if (osver.szCSDVersion[0] != '\0' &&
-				(std::strlen(osver.szCSDVersion) + std::strlen(buf->version) + 1) <
-				sizeof (buf->version))
-			{
-				std::strcat(buf->version, " ");
-				std::strcat(buf->version, osver.szCSDVersion);
-			}
-
-			std::sprintf(buf->release, "build %ld", osver.dwBuildNumber & 0xFFFF);
-
-			switch (sysinfo.wProcessorArchitecture)
-			{
-			case PROCESSOR_ARCHITECTURE_PPC:
-				std::strcpy(buf->machine, "ppc");
-				break;
-			case PROCESSOR_ARCHITECTURE_ALPHA:
-				std::strcpy(buf->machine, "alpha");
-				break;
-			case PROCESSOR_ARCHITECTURE_MIPS:
-				std::strcpy(buf->machine, "mips");
-				break;
-			case PROCESSOR_ARCHITECTURE_INTEL:
-				/*
-				 * dwProcessorType is only valid in Win95 and Win98 and WinME
-				 * wProcessorLevel is only valid in WinNT
-				 */
-				switch (os)
-				{
-				case Win95:
-				case Win98:
-					switch (sysinfo.dwProcessorType)
+					switch (verinfo.dwMajorVersion)
 					{
-					case PROCESSOR_INTEL_386:
-					case PROCESSOR_INTEL_486:
-					case PROCESSOR_INTEL_PENTIUM:
-						std::snprintf(buf->machine, sizeof(buf->machine), "i%lu", sysinfo.dwProcessorType);
-						break;
-					default:
-						std::strcpy(buf->machine, "i386");
+					case 10:
+					{
+						if (verinfo.wProductType == VER_NT_WORKSTATION)
+						{
+							temp.append("Windows 10");
+						}
+						else
+						{
+							temp.append("Windows Server 2016");
+						}
+
 						break;
 					}
-					break;
-				case WinNT:
-					std::sprintf(buf->machine, "i%d86", sysinfo.wProcessorLevel);
-					break;
-				default:
-					std::strcpy(buf->machine, "unknown");
-					break;
-				}
-				break;
-			default:
-				std::strcpy(buf->machine, "unknown");
-				break;
-			}
+					case 6:
+					{
+						switch (verinfo.dwMinorVersion)
+						{
+						case 3:
+						{
+							if (verinfo.wProductType == VER_NT_WORKSTATION)
+							{
+								temp.append("Windows 8.1");
+							}
+							else
+							{
+								temp.append("Windows Server 2012 R2");
+							}
 
-			sLength = sizeof (buf->nodename) - 1;
-			GetComputerName(buf->nodename, &sLength);
+							break;
+						}
+						case 2:
+						{
+							if (verinfo.wProductType == VER_NT_WORKSTATION)
+							{
+								temp.append("Windows 8");
+							}
+							else
+							{
+								temp.append("Windows Server 2012");
+							}
+
+							break;
+						}
+						case 1:
+						{
+							if (verinfo.wProductType == VER_NT_WORKSTATION)
+							{
+								temp.append("Windows 7");
+							}
+							else
+							{
+								temp.append("Windows Server 2008 R2");
+							}
+
+							break;
+						}
+						case 0:
+						{
+							if (verinfo.wProductType == VER_NT_WORKSTATION)
+							{
+								temp.append("Windows Vista");
+							}
+							else
+							{
+								temp.append("Windows Server 2008");
+							}
+
+							break;
+						}
+						default:
+						{
+							break;
+						}
+						}
+
+						break;
+					}
+					case 5:
+					{
+						switch (verinfo.dwMinorVersion)
+						{
+						case 2:
+						{
+							if (GetSystemMetrics(SM_SERVERR2) != 0)
+							{
+								temp.append("Windows Server 2003 R2");
+							}
+							else if (verinfo.wSuiteMask & VER_SUITE_WH_SERVER)
+							{
+								temp.append("Windows Home Server");
+							}
+							else if (GetSystemMetrics(SM_SERVERR2) == 0)
+							{
+								temp.append("Windows Server 2003");
+							}
+							else if ((verinfo.wProductType == VER_NT_WORKSTATION) && (sysinfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64))
+							{
+								temp.append("Windows XP Professional x64 Edition");
+							}
+
+							break;
+						}
+						case 1:
+						{
+							temp.append("Windows XP");
+							break;
+						}
+						case 0:
+						{
+							temp.append("Windows 2000");
+							break;
+						}
+						default:
+						{
+							break;
+						}
+						}
+
+						break;
+					}
+					default:
+					{
+						break;
+					}
+					}
+
+					if (temp.empty())
+					{
+						temp.append("Windows");
+					}
+
+					if (verinfo.wServicePackMajor != 0)
+					{
+						temp.append(" SP" + std::to_string(verinfo.wServicePackMajor));
+						if (verinfo.wServicePackMinor != 0)
+						{
+							temp.append("." + std::to_string(verinfo.wServicePackMinor));
+						}
+					}
+
+					std::snprintf(buf->sysname, sizeof buf->sysname, "%s", temp.c_str());
+
+					DWORD len = sizeof buf->nodename;
+					GetComputerNameA(buf->nodename, &len);
+
+					std::snprintf(buf->release, sizeof buf->release, "Build %lu", verinfo.dwBuildNumber);
+					
+					std::snprintf(buf->version, sizeof buf->version, "%lu.%lu", verinfo.dwMajorVersion, verinfo.dwMinorVersion);
+
+					std::string arch;
+					switch (sysinfo.wProcessorArchitecture)
+					{
+					case PROCESSOR_ARCHITECTURE_AMD64:
+					{
+						arch = "x64";
+						break;
+					}
+					case PROCESSOR_ARCHITECTURE_ARM:
+					{
+						arch = "ARM";
+						break;
+					}
+					case PROCESSOR_ARCHITECTURE_IA64:
+					{
+						arch = "Intel Itanium-based";
+						break;
+					}
+					case PROCESSOR_ARCHITECTURE_INTEL:
+					{
+						arch = "x86";
+						break;
+					}
+					case PROCESSOR_ARCHITECTURE_UNKNOWN:
+					default:
+						arch = "Unknown";
+					}
+
+					std::snprintf(buf->machine, sizeof buf->machine, "%s", arch.c_str());
+
+					// leave this empty for now
+					std::snprintf(buf->domainname, sizeof buf->domainname, "");
+				}
+			}
 		}
-#else
-		std::strcpy(buf->sysname, "unknown");
-		std::strcpy(buf->version, "unknown");
-		std::strcpy(buf->release, "unknown");
-		std::strcpy(buf->machine, "unknown");
-		std::strcpy(buf->nodename, "unknown");
-#endif
-		std::strcpy(buf->domainname, "");
+#else // !HAVE_WINDOWS_H
+		std::snprintf(buf->sysname, sizeof buf->sysname, "Unknown");
+		std::snprintf(buf->nodename, sizeof buf->nodename, "Unknown");
+		std::snprintf(buf->release, sizeof buf->release, "Unknown");
+		std::snprintf(buf->version, sizeof buf->version, "Unknown");
+		std::snprintf(buf->machine, sizeof buf->machine, "Unknown");
+		std::snprintf(buf->domainname, sizeof buf->domainname, "Unknown");
+#endif // HAVE_WINDOWS_H
 
 		return 0;
 	}
 
 }
-
-#else
-typedef int filenotempty; /* make ISO standard happy */
-#endif
+#endif
\ No newline at end of file
diff --git a/src/compat/uname.h b/src/compat/uname.h
index 1291459..b11425b 100644
--- a/src/compat/uname.h
+++ b/src/compat/uname.h
@@ -13,47 +13,35 @@
  *
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
-#ifndef INCLUDED_UNAME_TYPES
-#define INCLUDED_UNAME_TYPES
+#ifndef INCLUDED_UNAME_H
+#define INCLUDED_UNAME_H
 
-#ifndef HAVE_UNAME
+#ifdef HAVE_UNAME
+#ifdef HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+#else
 
 #ifndef SYS_NMLN
-# define SYS_NMLN 64
+#define SYS_NMLN 64
 #endif
 
 namespace pvpgn
 {
-
 	struct utsname
 	{
-		char sysname[SYS_NMLN];
-		char nodename[SYS_NMLN];
-		char release[SYS_NMLN];
-		char version[SYS_NMLN];
-		char machine[SYS_NMLN];
-		char domainname[SYS_NMLN];
+		char sysname[SYS_NMLN + 1];
+		char nodename[SYS_NMLN + 1];
+		char release[SYS_NMLN + 1];
+		char version[SYS_NMLN + 1];
+		char machine[SYS_NMLN + 1];
+		char domainname[SYS_NMLN + 1];
 	};
 
+	int uname(struct utsname* buf);
 }
 
-#endif
-
-#endif
-
-
-#ifndef INCLUDED_UNAME_PROTOS
-#define INCLUDED_UNAME_PROTOS
-
-#ifndef HAVE_UNAME
-namespace pvpgn
-{
-
-	extern int uname(struct utsname * buf);
-
-}
-#endif
-
-#endif
+#endif // HAVE_UNAME
+#endif // INCLUDED_UNAME_H
\ No newline at end of file
diff --git a/src/win32/d2cs_winmain.cpp b/src/win32/d2cs_winmain.cpp
index 7aac67f..3ecdd46 100644
--- a/src/win32/d2cs_winmain.cpp
+++ b/src/win32/d2cs_winmain.cpp
@@ -19,6 +19,9 @@
 #ifdef WIN32_GUI 
 
 #include "common/setup_before.h"
+
+#include <cwchar>
+
 #include <windows.h>
 #include <windowsx.h>
 #include <richedit.h>
@@ -136,7 +139,7 @@ namespace pvpgn
 				signal_quit_wrapper();
 				break;
 			case ID_EDITCONFIG_D2CS:
-				ShellExecute(NULL, "open", "notepad.exe", "conf\\d2cs.conf", NULL, SW_SHOW);
+				ShellExecuteW(NULL, L"open", L"notepad.exe", L"conf\\d2cs.conf", NULL, SW_SHOW);
 				break;
 			case ID_LOADCONFIG_D2CS:
 				d2cs::fprintf(stderr, "Sending Reload Config Signal To d2cs\n");
@@ -185,20 +188,18 @@ namespace pvpgn
 
 		static void OnSize(HWND hwnd, UINT state, int cx, int cy)
 		{
-			NOTIFYICONDATA dta;
-
-			if (state == SIZE_MINIMIZED) {
-				dta.cbSize = sizeof(NOTIFYICONDATA);
+			if (state == SIZE_MINIMIZED)
+			{
+				NOTIFYICONDATAW dta = {};
+				dta.cbSize = sizeof(NOTIFYICONDATAW);
 				dta.hWnd = hwnd;
 				dta.uID = ID_TRAY;
 				dta.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
 				dta.uCallbackMessage = WM_SHELLNOTIFY;
-				dta.hIcon = LoadIcon(GetWindowInstance(hwnd), MAKEINTRESOURCE(ID_ICON1));
-				strcpy(dta.szTip, "D2CS Version");
-				strcat(dta.szTip, " ");
-				strcat(dta.szTip, D2CS_VERSION_STRING);
+				dta.hIcon = LoadIconW(GetWindowInstance(hwnd), MAKEINTRESOURCEW(ID_ICON1));
+				std::swprintf(dta.szTip, sizeof dta.szTip / sizeof *dta.szTip, L"D2CS Version " D2CS_VERSION_STRING);
 
-				Shell_NotifyIcon(NIM_ADD, &dta);
+				Shell_NotifyIconW(NIM_ADD, &dta);
 				ShowWindow(hwnd, SW_HIDE);
 				return;
 			}
@@ -254,7 +255,6 @@ using namespace pvpgn::d2cs;
 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
 	LPSTR lpszCmdLine, int nCmdShow)
 {
-	WNDCLASSEX	wc;
 	HWND		hwnd;
 	MSG			msg;
 	Console     console;
@@ -268,29 +268,33 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
 		return app_main(__argc, __argv);
 	}
 
-	LoadLibrary("RichEd20.dll");
+	if (LoadLibraryW(L"RichEd20.dll") == NULL)
+	{
+		return -1;
+	}
 
-	wc.cbSize = sizeof(WNDCLASSEX);
+	WNDCLASSEXW	wc = {};
+	wc.cbSize = sizeof(WNDCLASSEXW);
 	wc.style = 0;
 	wc.lpfnWndProc = WndProc;
 	wc.cbClsExtra = 0;
 	wc.cbWndExtra = sizeof(LPVOID);
 	wc.hInstance = hInstance;
-	wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(ID_ICON1));
-	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+	wc.hIcon = LoadIconW(hInstance, MAKEINTRESOURCEW(ID_ICON1));
+	wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
 	wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
-	wc.lpszMenuName = MAKEINTRESOURCE(ID_MENU);
-	wc.lpszClassName = "BnetWndClass";
+	wc.lpszMenuName = MAKEINTRESOURCEW(ID_MENU);
+	wc.lpszClassName = L"BnetWndClass";
 
-	if (!RegisterClassEx(&wc))
-		RegisterClass((LPWNDCLASS)&wc.style);
+	if (!RegisterClassExW(&wc))
+		RegisterClassW((LPWNDCLASS)&wc.style);
 
-	hwnd = CreateWindow(TEXT("BnetWndClass"), "Diablo II Character Server",
+	hwnd = CreateWindowExW(0L, L"BnetWndClass", L"Diablo II Character Server",
 		WS_OVERLAPPEDWINDOW,
 		CW_USEDEFAULT, CW_USEDEFAULT,
 		CW_USEDEFAULT, CW_USEDEFAULT,
 		NULL,
-		LoadMenu(hInstance, MAKEINTRESOURCE(ID_MENU)),
+		LoadMenuW(hInstance, MAKEINTRESOURCEW(ID_MENU)),
 		hInstance, NULL);
 
 	if (hwnd) {
@@ -298,9 +302,10 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
 		UpdateWindow(hwnd);
 	}
 
-	while (GetMessage(&msg, NULL, 0, 0)) {
+	while (GetMessageW(&msg, NULL, 0, 0))
+	{
 		TranslateMessage(&msg);
-		DispatchMessage(&msg);
+		DispatchMessageW(&msg);
 
 		if (!d2cs_running && d2cs_run && gui_run) {
 			d2cs_running = TRUE;
diff --git a/src/win32/d2dbs_winmain.cpp b/src/win32/d2dbs_winmain.cpp
index af34005..edc2bfb 100644
--- a/src/win32/d2dbs_winmain.cpp
+++ b/src/win32/d2dbs_winmain.cpp
@@ -18,7 +18,10 @@
 
 #ifdef WIN32_GUI 
 
-#include "common/setup_before.h" 
+#include "common/setup_before.h"
+
+#include <cwchar>
+
 #include <windows.h>
 #include <windowsx.h>
 #include <richedit.h>
@@ -136,7 +139,7 @@ namespace pvpgn
 				d2dbs_signal_quit_wrapper();
 				break;
 			case ID_EDITCONFIG_D2DBS:
-				ShellExecute(NULL, "open", "notepad.exe", "conf\\d2dbs.conf", NULL, SW_SHOW);
+				ShellExecuteW(nullptr, L"open", L"notepad.exe", L"conf\\d2dbs.conf", NULL, SW_SHOW);
 				break;
 			case ID_LOADCONFIG_D2DBS:
 				d2dbs::fprintf(stderr, "Sending Reload Config Signal To d2dbs\n");
@@ -181,20 +184,18 @@ namespace pvpgn
 
 		static void OnSize(HWND hwnd, UINT state, int cx, int cy)
 		{
-			NOTIFYICONDATA dta;
-
-			if (state == SIZE_MINIMIZED) {
-				dta.cbSize = sizeof(NOTIFYICONDATA);
+			if (state == SIZE_MINIMIZED)
+			{
+				NOTIFYICONDATAW dta = {};
+				dta.cbSize = sizeof(NOTIFYICONDATAW);
 				dta.hWnd = hwnd;
 				dta.uID = ID_TRAY;
 				dta.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
 				dta.uCallbackMessage = WM_SHELLNOTIFY;
-				dta.hIcon = LoadIcon(GetWindowInstance(hwnd), MAKEINTRESOURCE(ID_ICON1));
-				strcpy(dta.szTip, "D2DBS Version");
-				strcat(dta.szTip, " ");
-				strcat(dta.szTip, D2DBS_VERSION_NUMBER);
+				dta.hIcon = LoadIconW(GetWindowInstance(hwnd), MAKEINTRESOURCEW(ID_ICON1));
+				std::swprintf(dta.szTip, sizeof dta.szTip / sizeof *dta.szTip, L"D2DBS Version " D2DBS_VERSION_NUMBER);
 
-				Shell_NotifyIcon(NIM_ADD, &dta);
+				Shell_NotifyIconW(NIM_ADD, &dta);
 				ShowWindow(hwnd, SW_HIDE);
 				return;
 			}
@@ -250,7 +251,6 @@ using namespace pvpgn::d2dbs;
 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
 	LPSTR lpszCmdLine, int nCmdShow)
 {
-	WNDCLASSEX	wc;
 	HWND		hwnd;
 	MSG			msg;
 
@@ -265,29 +265,33 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
 		return app_main(__argc, __argv);
 	}
 
-	LoadLibrary("RichEd20.dll");
+	if (LoadLibraryW(L"RichEd20.dll") == NULL)
+	{
+		return -1;
+	}
 
-	wc.cbSize = sizeof(WNDCLASSEX);
+	WNDCLASSEXW wc = {};
+	wc.cbSize = sizeof(WNDCLASSEXW);
 	wc.style = 0;
 	wc.lpfnWndProc = WndProc;
 	wc.cbClsExtra = 0;
 	wc.cbWndExtra = sizeof(LPVOID);
 	wc.hInstance = hInstance;
-	wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(ID_ICON1));
-	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+	wc.hIcon = LoadIconW(hInstance, MAKEINTRESOURCEW(ID_ICON1));
+	wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
 	wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
-	wc.lpszMenuName = MAKEINTRESOURCE(ID_MENU);
-	wc.lpszClassName = "BnetWndClass";
+	wc.lpszMenuName = MAKEINTRESOURCEW(ID_MENU);
+	wc.lpszClassName = L"BnetWndClass";
 
-	if (!RegisterClassEx(&wc))
-		RegisterClass((LPWNDCLASS)&wc.style);
+	if (!RegisterClassExW(&wc))
+		RegisterClassW((LPWNDCLASS)&wc.style);
 
-	hwnd = CreateWindow(TEXT("BnetWndClass"), "Diablo II DataBase Server",
+	hwnd = CreateWindowExW(0L, L"BnetWndClass", L"Diablo II DataBase Server",
 		WS_OVERLAPPEDWINDOW,
 		CW_USEDEFAULT, CW_USEDEFAULT,
 		CW_USEDEFAULT, CW_USEDEFAULT,
 		NULL,
-		LoadMenu(hInstance, MAKEINTRESOURCE(ID_MENU)),
+		LoadMenuW(hInstance, MAKEINTRESOURCEW(ID_MENU)),
 		hInstance, NULL);
 
 	if (hwnd) {
@@ -295,11 +299,13 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
 		UpdateWindow(hwnd);
 	}
 
-	while (GetMessage(&msg, NULL, 0, 0)) {
+	while (GetMessageW(&msg, NULL, 0, 0))
+	{
 		TranslateMessage(&msg);
-		DispatchMessage(&msg);
+		DispatchMessageW(&msg);
 
-		if (!d2dbs_running && d2dbs_run && gui_run) {
+		if (!d2dbs_running && d2dbs_run && gui_run)
+		{
 			d2dbs_running = TRUE;
 			_beginthread(pvpgn::d2dbs::d2dbs, 0, NULL);
 		}
diff --git a/src/win32/service.cpp b/src/win32/service.cpp
index 84081e0..5f4b765 100644
--- a/src/win32/service.cpp
+++ b/src/win32/service.cpp
@@ -17,10 +17,13 @@
 #ifdef WIN32
 
 #include <cstring>
-#include <windows.h>
-#include <winsvc.h>
+#include <cwchar>
+#include <string>
+#include <vector>
 
-#if !defined(WINADVAPI)
+#include <windows.h>
+
+#ifndef WINADVAPI
 #if !defined(_ADVAPI32_)
 #define WINADVAPI DECLSPEC_IMPORT
 #else
@@ -43,64 +46,92 @@ extern int main(int argc, char ** argv);
 SERVICE_STATUS serviceStatus;
 SERVICE_STATUS_HANDLE serviceStatusHandle = 0;
 
-typedef WINADVAPI BOOL(WINAPI *CSD_T)(SC_HANDLE, DWORD, LPCVOID);
+typedef WINADVAPI BOOL(WINAPI *CSD_T)(SC_HANDLE hService, DWORD dwInfoLevel, LPVOID lpInfo);
 
 void Win32_ServiceInstall()
 {
-	SERVICE_DESCRIPTION sdBuf;
-	CSD_T ChangeServiceDescription;
-	HMODULE advapi32;
-	SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
-
-	if (serviceControlManager)
+	SC_HANDLE serviceControlManager = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CREATE_SERVICE);
+	if (!serviceControlManager)
 	{
-		char path[_MAX_PATH + 10];
-		if (GetModuleFileName(0, path, sizeof(path) / sizeof(path[0])) > 0)
-		{
-			SC_HANDLE service;
-			std::strcat(path, " --service");
-			service = CreateService(serviceControlManager,
-				serviceName, serviceLongName,
-				SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
-				SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, path,
-				0, 0, 0, 0, 0);
-			if (service)
-			{
-				sdBuf.lpDescription = serviceDescription;
-
-				if (!(advapi32 = GetModuleHandle("ADVAPI32.DLL")))
-				{
-					CloseServiceHandle(service);
-					CloseServiceHandle(serviceControlManager);
-					return;
-				}
-
-				if (!(ChangeServiceDescription = (CSD_T)GetProcAddress(advapi32, "ChangeServiceConfig2A")))
-				{
-					CloseServiceHandle(service);
-					CloseServiceHandle(serviceControlManager);
-					return;
-				}
-
-				ChangeServiceDescription(
-					service,                // handle to service  
-					SERVICE_CONFIG_DESCRIPTION, // change: description  
-					&sdBuf);
-				CloseServiceHandle(service);
-			}
-		}
-		CloseServiceHandle(serviceControlManager);
+		return;
 	}
+
+	wchar_t path[MAX_PATH + 10] = {};
+	if (GetModuleFileNameW(nullptr, path, sizeof path / sizeof *path) != 0)
+	{
+		return;
+	}
+
+	std::wcscat(path, L"--service");
+
+	auto utf8_decode = [](const std::string& str)
+	{
+		if (str.empty())
+			return std::wstring();
+		int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
+		std::wstring wstrTo(size_needed, 0);
+		MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
+		return wstrTo;
+	};
+
+	SC_HANDLE service = CreateServiceW(serviceControlManager,
+		utf8_decode(serviceName).c_str(), utf8_decode(serviceLongName).c_str(),
+		SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
+		SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, path,
+		0, 0, 0, 0, 0);
+	if (service == NULL)
+	{
+		return;
+	}
+
+	SERVICE_DESCRIPTIONW sdBuf = {};
+	auto temp = utf8_decode(serviceDescription);
+	std::vector<wchar_t> buffer(temp.begin(), temp.end());
+	sdBuf.lpDescription = buffer.data();
+	
+	HMODULE advapi32 = GetModuleHandleW(L"advapi32.dll");
+	if (advapi32 == NULL)
+	{
+		CloseServiceHandle(service);
+		CloseServiceHandle(serviceControlManager);
+		return;
+	}
+
+	auto ChangeServiceDescription = reinterpret_cast<CSD_T>(GetProcAddress(advapi32, "ChangeServiceConfig2W"));
+	if (ChangeServiceDescription == NULL)
+	{
+		CloseServiceHandle(service);
+		CloseServiceHandle(serviceControlManager);
+		return;
+	}
+
+	ChangeServiceDescription(
+		service,                // handle to service  
+		SERVICE_CONFIG_DESCRIPTION, // change: description  
+		&sdBuf);
+	CloseServiceHandle(service);
+
+	CloseServiceHandle(serviceControlManager);
 }
 
 void Win32_ServiceUninstall()
 {
-	SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
+	SC_HANDLE serviceControlManager = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CONNECT);
 
 	if (serviceControlManager)
 	{
-		SC_HANDLE service = OpenService(serviceControlManager,
-			serviceName, SERVICE_QUERY_STATUS | DELETE);
+		auto utf8_decode = [](const std::string& str)
+		{
+			if (str.empty())
+				return std::wstring();
+			int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
+			std::wstring wstrTo(size_needed, 0);
+			MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
+			return wstrTo;
+		};
+
+		SC_HANDLE service = OpenServiceW(serviceControlManager,
+			utf8_decode(serviceName).c_str(), SERVICE_QUERY_STATUS | DELETE);
 		if (service)
 		{
 			SERVICE_STATUS serviceStatus;
@@ -158,7 +189,7 @@ void WINAPI ServiceControlHandler(DWORD controlCode)
 	SetServiceStatus(serviceStatusHandle, &serviceStatus);
 }
 
-void WINAPI ServiceMain(DWORD argc, char *argv[])
+void WINAPI ServiceMain(DWORD argc, char* argv[])
 {
 	// initialise service status
 	serviceStatus.dwServiceType = SERVICE_WIN32;
@@ -170,17 +201,29 @@ void WINAPI ServiceMain(DWORD argc, char *argv[])
 	serviceStatus.dwCheckPoint = 0;
 	serviceStatus.dwWaitHint = 0;
 
-	serviceStatusHandle = RegisterServiceCtrlHandler(serviceName, ServiceControlHandler);
+	auto utf8_decode = [](const std::string& str)
+	{
+		if (str.empty())
+			return std::wstring();
+		int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
+		std::wstring wstrTo(size_needed, 0);
+		MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
+		return wstrTo;
+	};
+
+	serviceStatusHandle = RegisterServiceCtrlHandlerW(utf8_decode(serviceName).c_str(), ServiceControlHandler);
 
 	if (serviceStatusHandle)
 	{
-		char path[_MAX_PATH + 1];
-		unsigned int i, last_slash = 0;
+		wchar_t path[MAX_PATH + 1] = {};
+		unsigned last_slash = 0;
 
-		GetModuleFileName(0, path, sizeof(path) / sizeof(path[0]));
+		GetModuleFileNameW(0, path, sizeof path / sizeof *path);
 
-		for (i = 0; i < std::strlen(path); i++) {
-			if (path[i] == '\\') last_slash = i;
+		for (std::size_t i = 0; i < std::wcslen(path); i++)
+		{
+			if (path[i] == '\\')
+				last_slash = i;
 		}
 
 		path[last_slash] = 0;
@@ -190,7 +233,7 @@ void WINAPI ServiceMain(DWORD argc, char *argv[])
 		SetServiceStatus(serviceStatusHandle, &serviceStatus);
 
 		// do initialisation here
-		SetCurrentDirectory(path);
+		SetCurrentDirectoryW(path);
 
 		// running
 		serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
@@ -228,15 +271,13 @@ void WINAPI ServiceMain(DWORD argc, char *argv[])
 
 void Win32_ServiceRun()
 {
-	SERVICE_TABLE_ENTRY serviceTable[] =
+	SERVICE_TABLE_ENTRYA serviceTable[] =
 	{
 		{ serviceName, ServiceMain },
 		{ 0, 0 }
 	};
 
-	if (!StartServiceCtrlDispatcher(serviceTable))
-	{
-	}
+	StartServiceCtrlDispatcherA(serviceTable);
 }
 
 #endif
diff --git a/src/win32/winmain.cpp b/src/win32/winmain.cpp
index 1a57e7d..08bdbf9 100644
--- a/src/win32/winmain.cpp
+++ b/src/win32/winmain.cpp
@@ -25,8 +25,12 @@
 
 #include <cstdio>
 #include <cstring>
+#include <cwchar>
 #include <string>
+#include <vector>
+
 #include <windows.h>
+
 #if _DEBUG
 #include <dbghelp.h>
 #endif
@@ -72,11 +76,10 @@ namespace pvpgn
 		static void	guiThread(void*);
 		static void	guiAddText(const char *, COLORREF);
 		static void	guiAddText_user(const char *, COLORREF);
-		static void	guiDEAD(std::string msg);
-		static void	guiDEAD(char* msg);
+		static void	guiDEAD(const std::wstring& msg);
 		static void	guiMoveWindow(HWND, RECT*);
-		static void	guiClearLogWindow(void);
-		static void	guiKillTrayIcon(void);
+		static void	guiClearLogWindow();
+		static void	guiKillTrayIcon();
 
 		long PASCAL guiWndProc(HWND, UINT, WPARAM, LPARAM);
 		static void	guiOnCommand(HWND, int, HWND, UINT);
@@ -91,9 +94,9 @@ namespace pvpgn
 		static void	guiOnMouseMove(HWND, int, int, UINT);
 		static void	guiOnLButtonDown(HWND, BOOL, int, int, UINT);
 		static void	guiOnLButtonUp(HWND, int, int, UINT);
-		static void	guiOnServerConfig(void);
+		static void	guiOnServerConfig();
 		static void	guiOnAbout(HWND);
-		static void	guiOnUpdates(void);
+		static void	guiOnUpdates();
 		static void	guiOnAnnounce(HWND);
 		static void	guiOnUserStatusChange(HWND);
 
@@ -129,7 +132,7 @@ namespace pvpgn
 
 		static struct gui_struc gui;
 
-		char	selected_item[255];
+		char selected_item[255] = {};
 
 		int fprintf(FILE *stream, const char *format, ...)
 		{
@@ -143,50 +146,51 @@ namespace pvpgn
 
 		static void guiThread(void *param)
 		{
-			WNDCLASSEX wc;
-			MSG msg;
+			if (LoadLibraryW(L"RichEd20.dll") == nullptr)
+				guiDEAD(L"Could not load RichEd20.dll");
 
-			if (LoadLibrary("RichEd20.dll") == NULL)
-				guiDEAD("Could not load RichEd20.dll");
-			wc.cbSize = sizeof(WNDCLASSEX);
+			WNDCLASSEXW wc = {};
+			wc.cbSize = sizeof(WNDCLASSEXW);
 			wc.style = CS_HREDRAW | CS_VREDRAW;
-			wc.lpfnWndProc = (WNDPROC)guiWndProc;
+			wc.lpfnWndProc = static_cast<WNDPROC>(guiWndProc);
 			wc.cbClsExtra = 0;
 			wc.cbWndExtra = 0;
-			wc.hInstance = (HINSTANCE)param;
-			wc.hIcon = LoadIcon(wc.hInstance, MAKEINTRESOURCE(IDI_ICON1));
-			wc.hCursor = LoadCursor(NULL, IDC_ARROW);
-			wc.hbrBackground = 0;
-			wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
-			wc.lpszClassName = "BnetdWndClass";
-			wc.hIconSm = NULL;
+			wc.hInstance = static_cast<HINSTANCE>(param);
+			wc.hIcon = LoadIconW(wc.hInstance, MAKEINTRESOURCEW(IDI_ICON1));
+			wc.hCursor = LoadCursorW(nullptr, IDC_ARROW);
+			wc.hbrBackground = nullptr;
+			wc.lpszMenuName = MAKEINTRESOURCEW(IDR_MENU);
+			wc.lpszClassName = L"BnetdWndClass";
+			wc.hIconSm = nullptr;
 
-			if (!RegisterClassEx(&wc))
-				guiDEAD("cant register WNDCLASS");
+			if (!RegisterClassExW(&wc))
+				guiDEAD(L"cant register WNDCLASS");
 
-			gui.hwnd = CreateWindowEx(
+			gui.hwnd = CreateWindowExW(
 				0,
 				wc.lpszClassName,
-				"The Player -vs- Player Gaming Network Server",
+				L"Player -vs- Player Gaming Network Server",
 				WS_OVERLAPPEDWINDOW,
 				CW_USEDEFAULT,
 				CW_USEDEFAULT,
 				CW_USEDEFAULT,
 				CW_USEDEFAULT,
-				NULL,
-				NULL,
-				(HINSTANCE)param,
-				NULL);
+				nullptr,
+				nullptr,
+				static_cast<HINSTANCE>(param),
+				nullptr);
 
 			if (!gui.hwnd)
-				guiDEAD("cant create window");
+				guiDEAD(L"cant create window");
 
 			ShowWindow(gui.hwnd, SW_SHOW);
 			SetEvent(gui.event_ready);
-			while (GetMessage(&msg, NULL, 0, 0))
+
+			MSG msg = {};
+			while (GetMessageW(&msg, nullptr, 0, 0))
 			{
 				TranslateMessage(&msg);
-				DispatchMessage(&msg);
+				DispatchMessageW(&msg);
 			}
 		}
 
@@ -209,82 +213,83 @@ namespace pvpgn
 				HANDLE_MSG(hwnd, WM_MOUSEMOVE, guiOnMouseMove);
 
 			case WM_CAPTURECHANGED:
-				guiOnCaptureChanged((HWND)lParam);
+				guiOnCaptureChanged(reinterpret_cast<HWND>(lParam));
 				return 0;
 			case WM_SHELLNOTIFY:
 				return guiOnShellNotify(wParam, lParam);
 			}
 
-			return DefWindowProc(hwnd, message, wParam, lParam);
+			return DefWindowProcW(hwnd, message, wParam, lParam);
 		}
 
 		static BOOL guiOnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
 		{
-			ghwndConsole = CreateWindowEx(
+			ghwndConsole = CreateWindowExW(
 				0,
 				RICHEDIT_CLASS,
-				NULL,
+				nullptr,
 				WS_CHILD | WS_VISIBLE | ES_READONLY | ES_MULTILINE | WS_VSCROLL | WS_HSCROLL | ES_NOHIDESEL,
 				0, 0,
 				0, 0,
 				hwnd,
 				0,
 				0,
-				NULL);
+				nullptr);
 
 			if (!ghwndConsole)
 				return FALSE;
 
-			gui.hwndUsers = CreateWindowEx(
+			gui.hwndUsers = CreateWindowExW(
 				WS_EX_CLIENTEDGE,
-				"LISTBOX",
-				NULL,
+				L"LISTBOX",
+				nullptr,
 				WS_CHILD | WS_VISIBLE | LBS_STANDARD | LBS_NOINTEGRALHEIGHT,
 				0, 0,
 				0, 0,
 				hwnd,
 				0,
 				0,
-				NULL);
+				nullptr);
 
 			if (!gui.hwndUsers)
 				return FALSE;
 
 			//amadeo: temp. button for useredit until rightcklick is working....
-			gui.hwndUserEditButton = CreateWindow(
-				"button",
-				"Edit User Status",
+			gui.hwndUserEditButton = CreateWindowExW(
+				0L,
+				L"button",
+				L"Edit User Status",
 				WS_CHILD | WS_VISIBLE | ES_LEFT,
 				0, 0,
 				0, 0,
 				hwnd,
-				(HMENU)881,
+				reinterpret_cast<HMENU>(881),
 				0,
-				NULL);
+				nullptr);
 
 			if (!gui.hwndUserEditButton)
 				return FALSE;
 
-			gui.hwndUserCount = CreateWindowEx(
+			gui.hwndUserCount = CreateWindowExW(
 				WS_EX_CLIENTEDGE,
-				"edit",
-				" 0 user(s) online:",
+				L"edit",
+				L" 0 user(s) online:",
 				WS_CHILD | WS_VISIBLE | ES_CENTER | ES_READONLY,
 				0, 0,
 				0, 0,
 				hwnd,
 				0,
 				0,
-				NULL);
+				nullptr);
 
 			if (!gui.hwndUserCount)
 				return FALSE;
 
-			SendMessage(gui.hwndUserCount, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), 0);
-			SendMessage(gui.hwndUsers, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), 0);
-			SendMessage(gui.hwndUserEditButton, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), 0);
+			SendMessageW(gui.hwndUserCount, WM_SETFONT, reinterpret_cast<WPARAM>(GetStockObject(DEFAULT_GUI_FONT)), 0);
+			SendMessageW(gui.hwndUsers, WM_SETFONT, reinterpret_cast<WPARAM>(GetStockObject(DEFAULT_GUI_FONT)), 0);
+			SendMessageW(gui.hwndUserEditButton, WM_SETFONT, reinterpret_cast<WPARAM>(GetStockObject(DEFAULT_GUI_FONT)), 0);
 			BringWindowToTop(gui.hwndUsers);
-			std::strcpy(gui.szDefaultStatus, "Void");
+			std::snprintf(gui.szDefaultStatus, sizeof(gui.szDefaultStatus), "%s", "Void");
 
 			gui.y_ratio = (100 << 10) / 100;
 			gui.x_ratio = (0 << 10) / 100;
@@ -412,38 +417,36 @@ namespace pvpgn
 
 		static void guiOnSize(HWND hwnd, UINT state, int cx, int cy)
 		{
-			int cy_console, cy_edge, cx_edge, cy_frame, cy_status;
-
 			if (state == SIZE_MINIMIZED)
 			{
-				NOTIFYICONDATA dta;
+				NOTIFYICONDATAW dta = {};
 
-				dta.cbSize = sizeof(NOTIFYICONDATA);
+				dta.cbSize = sizeof(NOTIFYICONDATAW);
 				dta.hWnd = hwnd;
 				dta.uID = IDI_TRAY;
 				dta.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
 				dta.uCallbackMessage = WM_SHELLNOTIFY;
-				dta.hIcon = LoadIcon(GetWindowInstance(hwnd), MAKEINTRESOURCE(IDI_ICON1));
-				std::strcpy(dta.szTip, std::string(std::string(PVPGN_SOFTWARE) + " " + std::string(PVPGN_VERSION)).c_str());
-				Shell_NotifyIcon(NIM_ADD, &dta);
+				dta.hIcon = LoadIconW(GetWindowInstance(hwnd), MAKEINTRESOURCE(IDI_ICON1));
+				std::swprintf(dta.szTip, sizeof dta.szTip / sizeof *dta.szTip, L"%ls %ls", PVPGN_SOFTWAREW, PVPGN_VERSION);
+				Shell_NotifyIconW(NIM_ADD, &dta);
 				ShowWindow(hwnd, SW_HIDE);
 				return;
 			}
 
 			if (state == SIZE_RESTORED)
 			{
-				NOTIFYICONDATA dta;
+				NOTIFYICONDATAW dta = {};
 
 				dta.hWnd = hwnd;
 				dta.uID = IDI_TRAY;
-				Shell_NotifyIcon(NIM_DELETE, &dta);
+				Shell_NotifyIconW(NIM_DELETE, &dta);
 			}
 
-			cy_status = 0;
-			cy_edge = GetSystemMetrics(SM_CYEDGE);
-			cx_edge = GetSystemMetrics(SM_CXEDGE);
-			cy_frame = (cy_edge << 1) + GetSystemMetrics(SM_CYBORDER) + 1;
-			cy_console = ((cy - cy_status - cy_frame - cy_edge * 2)*gui.y_ratio) >> 10;
+			int cy_status = 0;
+			int cy_edge = GetSystemMetrics(SM_CYEDGE);
+			int cx_edge = GetSystemMetrics(SM_CXEDGE);
+			int cy_frame = (cy_edge << 1) + GetSystemMetrics(SM_CYBORDER) + 1;
+			int cy_console = ((cy - cy_status - cy_frame - cy_edge * 2) * gui.y_ratio) >> 10;
 			gui.rectConsoleEdge.left = 0;
 			gui.rectConsoleEdge.right = cx - 140;
 			gui.rectConsoleEdge.top = 0;
@@ -475,12 +478,12 @@ namespace pvpgn
 				GetCursorPos(&p);
 				ScreenToClient(hwnd, &p);
 				if (PtInRect(&gui.rectHDivider, p))
-					SetCursor(LoadCursor(0, IDC_SIZENS));
+					SetCursor(LoadCursorW(0, IDC_SIZENS));
 
 				return TRUE;
 			}
 
-			return FORWARD_WM_SETCURSOR(hwnd, hwndCursor, codeHitTest, msg, DefWindowProc);
+			return FORWARD_WM_SETCURSOR(hwnd, hwndCursor, codeHitTest, msg, DefWindowProcW);
 		}
 
 		static void guiOnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags)
@@ -537,31 +540,31 @@ namespace pvpgn
 
 		static void guiOnUpdates()
 		{
-			ShellExecute(NULL, "open", "http://pvpgn.pro/", NULL, NULL, SW_SHOW);
+			ShellExecuteW(nullptr, L"open", L"http://pvpgn.pro/", nullptr, nullptr, SW_SHOW);
 		}
 
 		static void guiOnAnnounce(HWND hwnd)
 		{
-			DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_ANN), hwnd, (DLGPROC)AnnDlgProc);
+			DialogBoxW(GetModuleHandleW(nullptr), MAKEINTRESOURCEW(IDD_ANN), hwnd, static_cast<DLGPROC>(AnnDlgProc));
 		}
 
 		static void guiOnUserStatusChange(HWND hwnd)
 		{
 			int  index;
-			index = SendMessage(gui.hwndUsers, LB_GETCURSEL, 0, 0);
-			SendMessage(gui.hwndUsers, LB_GETTEXT, index, (LPARAM)selected_item);
-			DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_KICKUSER), hwnd, (DLGPROC)KickDlgProc);
-			SendMessage(gui.hwndUsers, LB_SETCURSEL, -1, 0);
+			index = SendMessageW(gui.hwndUsers, LB_GETCURSEL, 0, 0);
+			SendMessageW(gui.hwndUsers, LB_GETTEXT, index, reinterpret_cast<LPARAM>(selected_item));
+			DialogBoxW(GetModuleHandleW(nullptr), MAKEINTRESOURCEW(IDD_KICKUSER), hwnd, static_cast<DLGPROC>(KickDlgProc));
+			SendMessageW(gui.hwndUsers, LB_SETCURSEL, -1, 0);
 		}
 
 		static void guiOnAbout(HWND hwnd)
 		{
-			DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_ABOUT), hwnd, (DLGPROC)AboutDlgProc);
+			DialogBoxW(GetModuleHandleW(nullptr), MAKEINTRESOURCEW(IDD_ABOUT), hwnd, static_cast<DLGPROC>(AboutDlgProc));
 		}
 
 		static void guiOnServerConfig()
 		{
-			ShellExecute(NULL, NULL, "conf\\bnetd.conf", NULL, NULL, SW_SHOW);
+			ShellExecuteW(nullptr, nullptr, L"conf\\bnetd.conf", nullptr, nullptr, SW_SHOW);
 		}
 
 		extern void guiOnUpdateUserList()
@@ -570,101 +573,95 @@ namespace pvpgn
 			t_elem const * curr;
 			t_account * acc;
 
-			SendMessage(gui.hwndUsers, LB_RESETCONTENT, 0, 0);
+			SendMessageW(gui.hwndUsers, LB_RESETCONTENT, 0, 0);
 
 			LIST_TRAVERSE_CONST(connlist(), curr)
 			{
-				if (!(c = (t_connection *)elem_get_data(curr))) continue;
-				if (!(acc = conn_get_account(c))) continue;
+				if (!(c = (t_connection *)elem_get_data(curr)))
+					continue;
+				if (!(acc = conn_get_account(c)))
+					continue;
 
-				SendMessage(gui.hwndUsers, LB_ADDSTRING, 0, (LPARAM)account_get_name(acc));
+				SendMessageW(gui.hwndUsers, LB_ADDSTRING, 0, reinterpret_cast<LPARAM>(account_get_name(acc)));
 			}
 
-			std::string UserCount(std::to_string(connlist_login_get_length()) + " user(s) online:");
-			SendMessage(gui.hwndUserCount, WM_SETTEXT, 0, (LPARAM)UserCount.c_str());
+			std::wstring user_count(std::to_wstring(connlist_login_get_length()) + L" user(s) online:");
+			SendMessageW(gui.hwndUserCount, WM_SETTEXT, 0, reinterpret_cast<LPARAM>(user_count.c_str()));
 		}
 
 		static void guiAddText(const char *str, COLORREF clr)
 		{
-			int text_length;
-			CHARRANGE cr;
-			CHARRANGE ds;
-			CHARFORMAT fmt;
-			text_length = SendMessage(ghwndConsole, WM_GETTEXTLENGTH, 0, 0);
+			int text_length = SendMessageW(ghwndConsole, WM_GETTEXTLENGTH, 0, 0);
 
 			if (text_length > 30000)
 			{
+				CHARRANGE ds = {};
 				ds.cpMin = 0;
 				ds.cpMax = text_length - 30000;
-				SendMessage(ghwndConsole, EM_EXSETSEL, 0, (LPARAM)&ds);
-				SendMessage(ghwndConsole, EM_REPLACESEL, FALSE, 0);
+				SendMessageW(ghwndConsole, EM_EXSETSEL, 0, reinterpret_cast<LPARAM>(&ds));
+				SendMessageW(ghwndConsole, EM_REPLACESEL, FALSE, 0);
 			}
 
+			CHARRANGE cr = {};
 			cr.cpMin = text_length;
 			cr.cpMax = text_length;
+			SendMessageW(ghwndConsole, EM_EXSETSEL, 0, reinterpret_cast<LPARAM>(&cr));
 
-			SendMessage(ghwndConsole, EM_EXSETSEL, 0, (LPARAM)&cr);
-
-			fmt.cbSize = sizeof(CHARFORMAT);
+			CHARFORMATW fmt = {};
+			fmt.cbSize = sizeof(CHARFORMATW);
 			fmt.dwMask = CFM_COLOR | CFM_FACE | CFM_SIZE | CFM_BOLD | CFM_ITALIC | CFM_STRIKEOUT | CFM_UNDERLINE;
 			fmt.yHeight = 160;
 			fmt.dwEffects = 0;
 			fmt.crTextColor = clr;
-			std::strcpy(fmt.szFaceName, "Courier New");
+			std::swprintf(fmt.szFaceName, sizeof fmt.szFaceName / sizeof *fmt.szFaceName, L"%ls", L"Courier New");
 
-			SendMessage(ghwndConsole, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&fmt);
-			SendMessage(ghwndConsole, EM_REPLACESEL, FALSE, (LPARAM)str);
+			SendMessageW(ghwndConsole, EM_SETCHARFORMAT, SCF_SELECTION, reinterpret_cast<LPARAM>(&fmt));
+			SendMessageA(ghwndConsole, EM_REPLACESEL, FALSE, reinterpret_cast<LPARAM>(str));
 		}
 
-		static void guiDEAD(std::string message)
+		static void guiDEAD(const std::wstring& message)
 		{
-			char *msgLastError = nullptr;
+			wchar_t* error_message = nullptr;
 
-			FormatMessage(
+			FormatMessageW(
 				FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
-				NULL,
+				nullptr,
 				GetLastError(),
 				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-				(LPTSTR)&msgLastError,
+				reinterpret_cast<LPWSTR>(&error_message),
 				0,
-				NULL);
+				nullptr);
 
-			char *nl = std::strchr(msgLastError, '\r');
+			wchar_t* nl = std::wcschr(error_message, '\r');
 			if (nl)
-				*nl = 0;
+				*nl = '0';
 
-			std::string errorStr(message + "\nGetLastError() = '" + std::string(msgLastError) + "'\n");
+			MessageBoxW(0, std::wstring(message + L"\nGetLastError() = " + error_message).c_str(), L"guiDEAD", MB_ICONSTOP | MB_OK);
 
-			LocalFree(msgLastError);
-
-			MessageBox(0, errorStr.c_str(), "guiDEAD", MB_ICONSTOP | MB_OK);
+			LocalFree(error_message);
 
 			std::exit(1);
 		}
-		static void guiDEAD(char *message)
-		{
-			guiDEAD(std::string(message));
-		}
 
 		static void guiMoveWindow(HWND hwnd, RECT* r)
 		{
 			MoveWindow(hwnd, r->left, r->top, r->right - r->left, r->bottom - r->top, TRUE);
 		}
 
-		static void guiClearLogWindow(void)
+		static void guiClearLogWindow()
 		{
-			SendMessage(ghwndConsole, WM_SETTEXT, 0, 0);
+			SendMessageW(ghwndConsole, WM_SETTEXT, 0, 0);
 		}
 
-		static void guiKillTrayIcon(void)
+		static void guiKillTrayIcon()
 		{
-			NOTIFYICONDATA dta;
+			NOTIFYICONDATAW dta = {};
 
-			dta.cbSize = sizeof(NOTIFYICONDATA);
+			dta.cbSize = sizeof(NOTIFYICONDATAW);
 			dta.hWnd = gui.hwnd;
 			dta.uID = IDI_TRAY;
 			dta.uFlags = 0;
-			Shell_NotifyIcon(NIM_DELETE, &dta);
+			Shell_NotifyIconW(NIM_DELETE, &dta);
 		}
 
 		BOOL CALLBACK AboutDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
@@ -700,26 +697,35 @@ namespace pvpgn
 				{
 				case IDOK:
 				{
-					int len = GetWindowTextLength(GetDlgItem(hwnd, IDC_EDIT1));
+					int len = GetWindowTextLengthW(GetDlgItem(hwnd, IDC_EDIT1));
 
 					if (len > 0)
 					{
-						char* buf = static_cast<char*>(GlobalAlloc(GPTR, len + 1));
-						GetDlgItemText(hwnd, IDC_EDIT1, buf, len + 1);
+						std::wstring buff(len, 0);
+						GetDlgItemTextW(hwnd, IDC_EDIT1, &buff[0], buff.size());
 
-						t_message *message = message_create(message_type_error, nullptr, buf);
+						auto utf8_encode = [](const std::wstring& wstr)
+						{
+							if (wstr.empty())
+								return std::string();
+							int size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr.data(), static_cast<int>(wstr.size()), nullptr, 0, nullptr, nullptr);
+							std::string strTo(size_needed, 0);
+							WideCharToMultiByte(CP_UTF8, 0, wstr.data(), static_cast<int>(wstr.size()), &strTo[0], size_needed, nullptr, nullptr);
+							return strTo;
+						};
+
+						t_message* const message = message_create(message_type_error, nullptr, utf8_encode(buff).c_str());
 						if (message)
 						{
 							message_send_all(message);
 							message_destroy(message);
 						}
 
-						GlobalFree((HGLOBAL)buf);
-						SetDlgItemText(hwnd, IDC_EDIT1, "");
+						SetDlgItemTextW(hwnd, IDC_EDIT1, L"");
 					}
 					else
 					{
-						MessageBox(hwnd, "You didn't enter anything!", "Warning", MB_OK);
+						MessageBoxW(hwnd, L"You didn't enter anything!", L"Warning", MB_OK);
 					}
 					break;
 				}
@@ -741,23 +747,23 @@ namespace pvpgn
 			case WM_INITDIALOG:
 				if (selected_item[0] != 0)
 				{
-					SetDlgItemText(hwnd, IDC_EDITKICK, selected_item);
+					SetDlgItemTextA(hwnd, IDC_EDITKICK, selected_item);
 				}
 
 				return TRUE;
 			case WM_COMMAND:
-				switch (LOWORD(wParam)) {
+				switch (LOWORD(wParam))
+				{
 				case IDC_KICK_EXECUTE:
 				{
-					GetDlgItemText(hwnd, IDC_EDITKICK, selected_item, 32);
+					GetDlgItemTextA(hwnd, IDC_EDITKICK, selected_item, sizeof selected_item);
 
-					t_connection * conngui = connlist_find_connection_by_accountname(selected_item);
-					t_account * accountgui = accountlist_find_account(selected_item);
+					t_connection* const conngui = connlist_find_connection_by_accountname(selected_item);
+					t_account* const accountgui = accountlist_find_account(selected_item);
 
 					if (conngui == nullptr)
 					{
-						std::strcat(selected_item, " could not be found in Userlist!");
-						MessageBox(hwnd, selected_item, "Error", MB_OK);
+						MessageBoxA(hwnd, std::string(std::string(selected_item) + " could not be found in Userlist!").c_str(), "Error", MB_OK);
 					}
 					else
 					{
@@ -770,26 +776,26 @@ namespace pvpgn
 						BOOL messageq = FALSE;
 						BOOL kickq = FALSE;
 
-						if (SendMessage(hButton2, BM_GETCHECK, 0, 0) == BST_CHECKED)
+						if (SendMessageW(hButton2, BM_GETCHECK, 0, 0) == BST_CHECKED)
 						{
 							account_set_admin(accountgui);
 							account_set_command_groups(accountgui, 255);
 							messageq = TRUE;
 						}
 
-						if (SendMessage(hButton3, BM_GETCHECK, 0, 0) == BST_CHECKED)
+						if (SendMessageW(hButton3, BM_GETCHECK, 0, 0) == BST_CHECKED)
 						{
 							account_set_auth_operator(accountgui, nullptr, 1);
 							messageq = TRUE;
 						}
 
-						if (SendMessage(hButton4, BM_GETCHECK, 0, 0) == BST_CHECKED)
+						if (SendMessageW(hButton4, BM_GETCHECK, 0, 0) == BST_CHECKED)
 						{
 							account_set_strattr(accountgui, "BNET\\auth\\announce", "true");
 							messageq = TRUE;
 						}
 
-						if (SendMessage(hButton, BM_GETCHECK, 0, 0) == BST_CHECKED)
+						if (SendMessageW(hButton, BM_GETCHECK, 0, 0) == BST_CHECKED)
 						{
 							char temp[60];
 							char ipadr[110];
@@ -804,7 +810,7 @@ namespace pvpgn
 
 							std::strcpy(temp, " a ");
 							std::strcat(temp, ipadr);
-							handle_ipban_command(NULL, temp);
+							handle_ipban_command(nullptr, temp);
 
 							temp[0] = 0;
 							std::strcpy(temp, " has been added to IpBanList");
@@ -812,15 +818,15 @@ namespace pvpgn
 							if (messageq == TRUE)
 							{
 								std::strcat(ipadr, " and UserStatus changed");
-								MessageBox(hwnd, ipadr, "ipBan & StatusChange", MB_OK);
+								MessageBoxA(hwnd, ipadr, "ipBan & StatusChange", MB_OK);
 								messageq = FALSE;
 								kickq = FALSE;
 							}
 							else
-								MessageBox(hwnd, ipadr, "ipBan", MB_OK);
+								MessageBoxA(hwnd, ipadr, "ipBan", MB_OK);
 						}
 
-						if (SendMessage(hButton1, BM_GETCHECK, 0, 0) == BST_CHECKED)
+						if (SendMessageW(hButton1, BM_GETCHECK, 0, 0) == BST_CHECKED)
 						{
 							conn_set_state(conngui, conn_state_destroy);
 							kickq = TRUE;
@@ -829,19 +835,19 @@ namespace pvpgn
 						if ((messageq == TRUE) && (kickq == TRUE))
 						{
 							std::strcat(selected_item, "has been kicked and Status has changed");
-							MessageBox(hwnd, selected_item, "UserKick & StatusChange", MB_OK);
+							MessageBoxA(hwnd, selected_item, "UserKick & StatusChange", MB_OK);
 						}
 
 						if ((kickq == TRUE) && (messageq == FALSE))
 						{
 							std::strcat(selected_item, " has been kicked from the server");
-							MessageBox(hwnd, selected_item, "UserKick", MB_OK);
+							MessageBoxA(hwnd, selected_item, "UserKick", MB_OK);
 						}
 
 						if ((kickq == FALSE) && (messageq == TRUE))
 						{
 							std::strcat(selected_item, "'s Status has been changed");
-							MessageBox(hwnd, selected_item, "StatusChange", MB_OK);
+							MessageBoxA(hwnd, selected_item, "StatusChange", MB_OK);
 						}
 
 						selected_item[0] = 0;
@@ -866,28 +872,27 @@ namespace pvpgn
 #if _DEBUG
 void make_minidump(EXCEPTION_POINTERS* e)
 {
-	auto hDbgHelp = LoadLibraryA("dbghelp");
+	HMODULE hDbgHelp = LoadLibraryW(L"dbghelp.dll");
 	if (hDbgHelp == nullptr)
 		return;
-	auto pMiniDumpWriteDump = (decltype(&MiniDumpWriteDump))GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
+
+	auto pMiniDumpWriteDump = reinterpret_cast<decltype(&MiniDumpWriteDump)>(GetProcAddress(hDbgHelp, "MiniDumpWriteDump"));
 	if (pMiniDumpWriteDump == nullptr)
 		return;
 
-	char name[MAX_PATH];
+	wchar_t name[MAX_PATH] = {};
 	{
-		auto nameEnd = name + GetModuleFileNameA(GetModuleHandleA(0), name, MAX_PATH);
+		auto nameEnd = name + GetModuleFileNameW(GetModuleHandleW(nullptr), name, MAX_PATH);
 		SYSTEMTIME t;
 		GetSystemTime(&t);
-		wsprintfA(nameEnd - strlen(".exe"),
-			"_%4d%02d%02d_%02d%02d%02d.dmp",
-			t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond);
+		wsprintfW(nameEnd - std::wcslen(L".exe"), L"_%4d%02d%02d_%02d%02d%02d.dmp", t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond);
 	}
 
-	auto hFile = CreateFileA(name, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+	auto hFile = CreateFileW(name, GENERIC_WRITE, FILE_SHARE_READ, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
 	if (hFile == INVALID_HANDLE_VALUE)
 		return;
 
-	MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
+	MINIDUMP_EXCEPTION_INFORMATION exceptionInfo = {};
 	exceptionInfo.ThreadId = GetCurrentThreadId();
 	exceptionInfo.ExceptionPointers = e;
 	exceptionInfo.ClientPointers = FALSE;
@@ -903,6 +908,8 @@ void make_minidump(EXCEPTION_POINTERS* e)
 
 	CloseHandle(hFile);
 
+	FreeLibrary(hDbgHelp);
+
 	return;
 }
 
@@ -936,7 +943,7 @@ int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE reserved, LPSTR lpCmdLine, i
 	}
 
 	pvpgn::bnetd::gui.main_finished = FALSE;
-	pvpgn::bnetd::gui.event_ready = CreateEvent(NULL, FALSE, FALSE, NULL);
+	pvpgn::bnetd::gui.event_ready = CreateEventW(nullptr, FALSE, FALSE, nullptr);
 	_beginthread(pvpgn::bnetd::guiThread, 0, (void*)hInstance);
 	WaitForSingleObject(pvpgn::bnetd::gui.event_ready, INFINITE);
 

From 1e36d4995ddabfe647a39d0bec444a1715fe5095 Mon Sep 17 00:00:00 2001
From: xboi209 <xboi209@gmail.com>
Date: Fri, 12 Aug 2016 18:40:10 -0700
Subject: [PATCH 2/4] Update greeting message in pvpgn_greeting()

---
 src/bnetd/main.cpp | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/bnetd/main.cpp b/src/bnetd/main.cpp
index b1de155..92b86d6 100644
--- a/src/bnetd/main.cpp
+++ b/src/bnetd/main.cpp
@@ -181,7 +181,7 @@ void post_server_shutdown(int status);
 int eventlog_startup(void);
 int fork_bnetd(int foreground);
 char * write_to_pidfile(void);
-void pvpgn_greeting(void);
+void pvpgn_greeting();
 
 int eventlog_startup(void)
 {
@@ -485,10 +485,10 @@ void post_server_shutdown(int status)
 	return;
 }
 
-void pvpgn_greeting(void)
+void pvpgn_greeting()
 {
 #ifdef HAVE_GETPID
-	eventlog(eventlog_level_info, __FUNCTION__, PVPGN_SOFTWARE" version " PVPGN_VERSION " process %u", (unsigned int)getpid());
+	eventlog(eventlog_level_info, __FUNCTION__, PVPGN_SOFTWARE " " PVPGN_VERSION " process %d", static_cast<int>(getpid()));
 #else
 	eventlog(eventlog_level_info, __FUNCTION__, PVPGN_SOFTWARE" version "PVPGN_VERSION);
 #endif
@@ -498,15 +498,15 @@ void pvpgn_greeting(void)
 	{
 		eventlog(eventlog_level_info, __FUNCTION__, "running on %s (%s %s, %s)", utsbuf.sysname, utsbuf.version, utsbuf.release, utsbuf.machine);
 	}
+	else
+	{
+		eventlog(eventlog_level_info, __FUNCTION__, "uname() failed");
+	}
 
-	printf("You are currently Running " PVPGN_SOFTWARE " " PVPGN_VERSION "\n");
+	printf("You are currently running " PVPGN_SOFTWARE " " PVPGN_VERSION "\n");
 	printf("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n");
 	printf("If you need support:\n");
-	printf(" * READ the documentation at http://pvpgndocs.berlios.de/\n");
-	printf(" * you can subscribe to the pvpgn-users mailing list at \n");
-	printf("   https://lists.berlios.de/mailman/listinfo/pvpgn-users\n");
-	printf(" * check out the forums at http://forums.pvpgn.org\n");
-	printf(" * visit us on IRC on irc.pvpgn.org channel #pvpgn\n");
+	printf(" * Create an issue at https://github.com/pvpgn/pvpgn-server\n");
 	printf("\nServer is now running.\n");
 	printf("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n");
 

From 96d017284ffba0a33cf2a1427029142bf626edeb Mon Sep 17 00:00:00 2001
From: xboi209 <xboi209@gmail.com>
Date: Fri, 12 Aug 2016 20:54:35 -0700
Subject: [PATCH 3/4] - Use narrow functions in sql_odbc.cpp - Remove use of
 TCHAR types

---
 src/bnetd/sql_odbc.cpp | 34 +++++++++++++++++++---------------
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/src/bnetd/sql_odbc.cpp b/src/bnetd/sql_odbc.cpp
index f39fb9d..39ab17b 100644
--- a/src/bnetd/sql_odbc.cpp
+++ b/src/bnetd/sql_odbc.cpp
@@ -93,14 +93,14 @@ namespace pvpgn
 #define p_SQLAllocConnect	SQLAllocConnect
 #define p_SQLAllocStmt		SQLAllocStmt
 #define p_SQLBindCol		SQLBindCol
-#define p_SQLColAttribute	SQLColAttribute
-#define p_SQLConnect		SQLConnect
+#define p_SQLColAttribute	SQLColAttributeA
+#define p_SQLConnect		SQLConnectA
 #define p_SQLDisconnect		SQLDisconnect
-#define p_SQLExecDirect		SQLExecDirect
+#define p_SQLExecDirect		SQLExecDirectA
 #define p_SQLFetch		SQLFetch
 #define p_SQLFreeHandle		SQLFreeHandle
 #define p_SQLRowCount		SQLRowCount
-#define p_SQLGetDiagRec		SQLGetDiagRec
+#define p_SQLGetDiagRec		SQLGetDiagRecA
 #define p_SQLNumResultCols	SQLNumResultCols
 #else
 		/* RUNTIME_LIBS */
@@ -387,18 +387,21 @@ namespace pvpgn
 				return NULL;
 			}
 			fields[fieldCount] = NULL;
-			for (i = 0; i < fieldCount; i++) {
-				TCHAR *fName;
-				TCHAR *tmp;
+			for (i = 0; i < fieldCount; i++)
+			{
 				SQLSMALLINT fNameSz;
 				p_SQLColAttribute(res->stmt, i + 1, SQL_DESC_NAME, NULL, 0, &fNameSz, NULL);
-				fName = (TCHAR *)xmalloc(fNameSz);
-				if (!fName) {
+				char* fName = (char*)xmalloc(fNameSz);
+				if (!fName)
+				{
 					return NULL;
 				}
 				p_SQLColAttribute(res->stmt, i + 1, SQL_DESC_NAME, fName, fNameSz, &fNameSz, NULL);
-				tmp = fName;
-				for (; *tmp; ++tmp) *tmp = safe_toupper(*tmp);
+				char* tmp = fName;
+				for (; *tmp; ++tmp)
+				{
+					*tmp = safe_toupper(*tmp);
+				}
 				fields[i] = fName;
 			}
 			return fields;
@@ -450,12 +453,13 @@ namespace pvpgn
 			row[fieldCount] = NULL;
 			sizes = (SQLINTEGER *)xcalloc(sizeof *sizes, fieldCount);
 
-			for (i = 0; i < fieldCount; i++) {
-				TCHAR *cell;
+			for (i = 0; i < fieldCount; i++)
+			{
 				SQLLEN cellSz;
 				p_SQLColAttribute(stmt, i + 1, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, &cellSz);
-				cell = (TCHAR *)xcalloc(sizeof *cell, ++cellSz);
-				if (!cell) {
+				char* cell = (char*)xcalloc(sizeof *cell, ++cellSz);
+				if (!cell)
+				{
 					return NULL;
 				}
 				p_SQLBindCol(stmt, i + 1, SQL_C_CHAR, cell, cellSz, &sizes[i]);

From b12ebbacd41441a4147ee30801e18e339278737c Mon Sep 17 00:00:00 2001
From: xboi209 <xboi209@gmail.com>
Date: Fri, 12 Aug 2016 21:17:17 -0700
Subject: [PATCH 4/4] Move Windows-specific code to appropriate #ifdef block

---
 src/compat/uname.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/compat/uname.cpp b/src/compat/uname.cpp
index 0baa2b2..7ddb131 100644
--- a/src/compat/uname.cpp
+++ b/src/compat/uname.cpp
@@ -26,6 +26,7 @@
 
 #ifdef HAVE_WINDOWS_H
 #include <Windows.h>
+#define STATUS_SUCCESS (0x00000000)
 #endif
 
 #include "common/setup_after.h"
@@ -33,9 +34,6 @@
 
 namespace pvpgn
 {
-	using RtlGetVersionProto = NTSTATUS(WINAPI*)(RTL_OSVERSIONINFOEXW* lpVersionInformation);
-#define STATUS_SUCCESS (0x00000000)
-
 	int uname(struct utsname* buf)
 	{
 		if (!buf)
@@ -45,6 +43,8 @@ namespace pvpgn
 		}
 
 #ifdef HAVE_WINDOWS_H
+		using RtlGetVersionProto = NTSTATUS(WINAPI*)(RTL_OSVERSIONINFOEXW* lpVersionInformation);
+
 		HMODULE hNtdll = nullptr;
 		if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, L"ntdll.dll", &hNtdll) != 0)
 		{