Merge pull request from RElesgoe/master

Use wide functions from WinAPI when possible and update greeting message
This commit is contained in:
RElesgoe 2016-08-12 22:01:00 -07:00 committed by GitHub
commit 9763715f70
13 changed files with 626 additions and 503 deletions

View file

@ -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")

View file

@ -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
@ -184,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)
{
@ -488,28 +485,28 @@ void post_server_shutdown(int status)
return;
}
void pvpgn_greeting(void)
void pvpgn_greeting()
{
struct utsname utsbuf;
#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
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);
}
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");

View file

@ -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>
@ -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]);

View file

@ -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)
{

View file

@ -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)

View file

@ -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

View file

@ -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"

View file

@ -13,28 +13,28 @@
*
* 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>
#define STATUS_SUCCESS (0x00000000)
#endif
#include "common/setup_after.h"
namespace pvpgn
{
extern int uname(struct utsname * buf)
int uname(struct utsname* buf)
{
if (!buf)
{
@ -42,155 +42,221 @@ namespace pvpgn
return -1;
}
#ifdef WIN32
#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)
{
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

View file

@ -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

View file

@ -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;

View file

@ -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);
}

View file

@ -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

View file

@ -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);