Merge pull request from pvpgn/master

Pull changes in master branch into develop branch
This commit is contained in:
RElesgoe 2020-05-18 04:32:30 -07:00 committed by GitHub
commit bd58cf32c5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 325 additions and 225 deletions

View file

@ -79,7 +79,7 @@ make
make install
```
#### Ubuntu 16.04
#### Ubuntu 16.04, 18.04
```
sudo apt-get -y install build-essential git cmake zlib1g-dev
git clone https://github.com/pvpgn/pvpgn-server.git
@ -102,7 +102,7 @@ cd pvpgn-server && cmake -G "Unix Makefiles" -H./ -B./build
cd build && make
```
#### Debian 8
#### Debian 8 with clang compiler
```
sudo apt-get -y install build-essential zlib1g-dev clang libc++-dev git
wget https://cmake.org/files/v3.7/cmake-3.7.1-Linux-x86_64.tar.gz
@ -143,6 +143,11 @@ cd build && make
Full instructions: [Русский](http://harpywar.com/?a=articles&b=2&c=1&d=74) | [English](http://harpywar.com/?a=articles&b=2&c=1&d=74&lang=en)
## Hosting on LAN or VPS with private IP address
Some VPS providers do not assign your server a direct public IP. If that is the case or you host at home behind NAT you need to setup the route translation in `address_translation.conf`. The public address is pushed as the route server address to game clients when seeking games. Failure to push the correct address to game clients results in players not being able to match and join games (long game search and error).
If your network interface is directly bound to public IP, PvPGN can figure it out on it's own and this step is not necessary.
## License
This program is free software; you can redistribute it and/or

View file

@ -35,24 +35,44 @@
# ${-19} - substitute arguments 0-19 here #
# ${2-} - substitue all arguments from 2 until the end here #
# #
@
//doubt //dt //d
[0]/me looks with doubt
[1+]/me looks at ${1-} with doubt
@
//numusers //nu
[0]%IThere are %u users online.
[0]%IThere are %g games online.
[0]%IThere are %c channels online.
[1+]%EThat command does not take any arguments.
@
//askban //ab
[2+]/w $1 Please ban ${2-}.
@
//statsme //sm
[0]/stats %u
@
//pvpgn
[*]/announce PVPGN rulez!
# %a - Number of registered accounts #
# %c - Number of existing channels #
# %g - Number of running games #
# %G - Number of games with the same clienttag #
# %h - Hostname of the server #
# %H - Contact name (as set in bnetd.conf) #
# %i - The userid of the user #
# %I - The username of the user #
# %N - Name of the game the user has connected with #
# %m - Check the user's mail #
# %r - IP address of the user #
# %s - Servername #
# %t - The clienttag of the user #
# %u - Number of users currently logged in #
# %U - Number of users logged in with the same clienttag #
# %v - Server version #
# #
# Examples #
#@
#//doubt //dt //d
#[0]/me looks with doubt
#[1+]/me looks at ${1-} with doubt
#@
#//numusers //nu
#[0]%IThere are %u users online.
#[0]%IThere are %g games online.
#[0]%IThere are %c channels online.
#[1+]%EThat command does not take any arguments.
#@
#//askban //ab
#[2+]/w $1 Please ban ${2-}.
#@
#//statsme //sm
#[0]/stats %u
#@
#//pvpgn
#[*]/announce PVPGN rulez!
#
# #
##############################################################################

View file

@ -419,12 +419,12 @@ max_friends = 20
# Set track=0 to disable tracking. Any other number will set number
# of seconds between sending tracking packets. This is ON by default.
#track = 0
track = 0
track = 60
# Tracking server(s)
# Use a comma delimited list of hostnames with optional UDP port numbers
# after colons. (port 6114 is the default for the newer tracking protocol)
trackaddrs = "track.pvpgn.org,bntrack.darkwings.org,bnet.mivabe.nl,track.eurobattle.net"
trackaddrs = "track.pvpgn.pro,track.pvpgn.org,bntrack.darkwings.org,bnet.mivabe.nl,track.eurobattle.net"
# Change these to match your system, for example:
location = "unknown"

View file

@ -407,7 +407,7 @@ track = 60
# Tracking server(s)
# Use a comma delimited list of hostnames with optional UDP port numbers
# after colons. (port 6114 is the default for the newer tracking protocol)
trackaddrs = "track.pvpgn.org,bntrack.darkwings.org,bnet.mivabe.nl,track.eurobattle.net"
trackaddrs = "track.pvpgn.pro,track.pvpgn.org,bntrack.darkwings.org,bnet.mivabe.nl,track.eurobattle.net"
# Change these to match your system, for example:
location = "unknown"

View file

@ -864,6 +864,21 @@
}
]
}
},
"PMAC": {
"0x4f": {
"checkRevisionFile": "PMACver1.mpq",
"equation": "A=3845581634 B=880823580 C=1363937103 4 A=A-S B=B-C C=C-A A=A-B",
"entries": [
{
"title": "Warcraft II BNE 2.02",
"version": "2.0.2.1",
"hash": "0xaed93b05",
"fileMetadata": "Warcraft II BNE 05/21/101 15:44:14 931587",
"versionTag": "W2BN_202"
}
]
}
}
},
"STAR": {
@ -1329,6 +1344,21 @@
}
]
}
},
"PMAC": {
"0xd1": {
"checkRevisionFile": "PMACver1.mpq",
"equation": "A=3845581634 B=880823580 C=1363937103 4 A=A-S B=B-C C=C-A A=A-B",
"entries": [
{
"title": "Starcraft - Broodwar (Expansion) 1.15 - (Starcraft mode)",
"version": "1.15.0.1",
"hash": "0xeb5f82bd",
"fileMetadata": "Starcraft 07/16/107 18:00:00 1606200",
"versionTag": "STAR_115"
}
]
}
}
},
"SEXP": {
@ -1613,6 +1643,21 @@
}
]
}
},
"PMAC": {
"0xd1": {
"checkRevisionFile": "PMACver1.mpq",
"equation": "A=3845581634 B=880823580 C=1363937103 4 A=A-S B=B-C C=C-A A=A-B",
"entries": [
{
"title": "Starcraft - Broodwar (Expansion) 1.15 - (Broodwar mode)",
"version": "1.15.0.1",
"hash": "0xeb5f82bd",
"fileMetadata": "Starcraft 07/16/107 18:00:00 1606200",
"versionTag": "SEXP_115"
}
]
}
}
},
"DRTL": {
@ -1650,6 +1695,34 @@
}
]
}
},
"PMAC": {
"0x2a": {
"checkRevisionFile": "PMACver1.mpq",
"equation": "A=3845581634 B=880823580 C=1363937103 4 A=A-S B=B-C C=C-A A=A-B",
"entries": [
{
"title": "Diablo 109",
"version": "1.0.9.2",
"hash": "0x2b079060",
"fileMetadata": "Diablo 05/12/101 15:42:00 1160990",
"versionTag": "DRTL_109"
}
]
},
"0x28": {
"checkRevisionFile": "PMACver1.mpq",
"equation": "A=3845581634 B=880823580 C=1363937103 4 A=A-S B=B-C C=C-A A=A-B",
"entries": [
{
"title": "Diablo 108",
"version": "1.0.8.0",
"hash": "0x82f94d6a",
"fileMetadata": "Diablo 06/13/100 12:00:00 1113966",
"versionTag": "DRTL_108"
}
]
}
}
},
"D2XP": {

View file

@ -854,57 +854,74 @@ static int on_client_charlistreq(t_connection * c, t_packet * packet)
packet_set_type(rpacket,D2CS_CLIENT_CHARLISTREPLY);
bn_short_set(&rpacket->u.d2cs_client_charlistreply.u1,0);
n=0;
try {
Directory dir(path);
while ((charname=dir.read())) {
charinfo = (t_d2charinfo_file*)xmalloc(sizeof(t_d2charinfo_file));
if (d2charinfo_load(account,charname,charinfo)<0) {
eventlog(eventlog_level_error,__FUNCTION__,"error loading charinfo for {}(*{})",charname,account);
xfree((void *)charinfo);
continue;
bool retry = true;
while (retry)
{
try {
Directory dir(path);
while ((charname = dir.read())) {
charinfo = (t_d2charinfo_file*)xmalloc(sizeof(t_d2charinfo_file));
if (d2charinfo_load(account, charname, charinfo) < 0) {
eventlog(eventlog_level_error, __FUNCTION__, "error loading charinfo for {}(*{})", charname, account);
xfree((void*)charinfo);
continue;
}
eventlog(eventlog_level_debug, __FUNCTION__, "adding char {} (*{})", charname, account);
d2charlist_add_char(&charlist_head, charinfo, 0);
n++;
if (n >= maxchar) break;
}
eventlog(eventlog_level_debug,__FUNCTION__,"adding char {} (*{})", charname, account);
d2charlist_add_char(&charlist_head,charinfo,0);
n++;
if (n>=maxchar) break;
}
if (prefs_allow_newchar() && (n<maxchar)) {
bn_short_set(&rpacket->u.d2cs_client_charlistreply.maxchar,maxchar);
} else {
bn_short_set(&rpacket->u.d2cs_client_charlistreply.maxchar,0);
}
if (!std::strcmp(charlist_sort_order, "ASC"))
{
t_elist * curr, * safe;
t_d2charlist * ccharlist;
if (prefs_allow_newchar() && (n < maxchar)) {
bn_short_set(&rpacket->u.d2cs_client_charlistreply.maxchar, maxchar);
}
else {
bn_short_set(&rpacket->u.d2cs_client_charlistreply.maxchar, 0);
}
if (!std::strcmp(charlist_sort_order, "ASC"))
{
t_elist* curr, * safe;
t_d2charlist* ccharlist;
elist_for_each_safe(curr,&charlist_head,safe)
{
ccharlist = elist_entry(curr,t_d2charlist,list);
packet_append_string(rpacket,(char*)ccharlist->charinfo->header.charname);
packet_append_string(rpacket,(char *)&ccharlist->charinfo->portrait);
xfree((void *)ccharlist->charinfo);
xfree((void *)ccharlist);
}
}
else
{
t_elist * curr, * safe;
t_d2charlist * ccharlist;
elist_for_each_safe(curr, &charlist_head, safe)
{
ccharlist = elist_entry(curr, t_d2charlist, list);
packet_append_string(rpacket, (char*)ccharlist->charinfo->header.charname);
packet_append_string(rpacket, (char*)&ccharlist->charinfo->portrait);
xfree((void*)ccharlist->charinfo);
xfree((void*)ccharlist);
}
}
else
{
t_elist* curr, * safe;
t_d2charlist* ccharlist;
elist_for_each_safe_rev(curr,&charlist_head,safe)
{
ccharlist = elist_entry(curr,t_d2charlist,list);
packet_append_string(rpacket,(char*)ccharlist->charinfo->header.charname);
packet_append_string(rpacket,(char *)&ccharlist->charinfo->portrait);
xfree((void *)ccharlist->charinfo);
xfree((void *)ccharlist);
elist_for_each_safe_rev(curr, &charlist_head, safe)
{
ccharlist = elist_entry(curr, t_d2charlist, list);
packet_append_string(rpacket, (char*)ccharlist->charinfo->header.charname);
packet_append_string(rpacket, (char*)&ccharlist->charinfo->portrait);
xfree((void*)ccharlist->charinfo);
xfree((void*)ccharlist);
}
}
}
retry = false;
}
catch (const Directory::OpenError&) {
ERROR1("(*{}) charinfo directory do not exist, building it", account);
if (p_mkdir(path, S_IRWXU) == 0)
{
INFO1("Successfully created charinfo directory ({})", path);
}
else
{
ERROR2("Failed to create charinfo directory ({}), errno = {}", path, errno);
retry = false;
bn_short_set(&rpacket->u.d2cs_client_charlistreply.maxchar, 0);
}
}
} catch(const Directory::OpenError&) {
INFO1("(*{}) charinfo directory do not exist, building it",account);
p_mkdir(path,S_IRWXU);
}
bn_short_set(&rpacket->u.d2cs_client_charlistreply.currchar,n);
bn_short_set(&rpacket->u.d2cs_client_charlistreply.currchar2,n);
@ -953,70 +970,87 @@ static int on_client_charlistreq_110(t_connection * c, t_packet * packet)
packet_set_type(rpacket,D2CS_CLIENT_CHARLISTREPLY_110);
bn_short_set(&rpacket->u.d2cs_client_charlistreply_110.u1,0);
n=0;
try {
Directory dir(path);
bool retry = true;
while (retry)
{
try {
Directory dir(path);
exp_time = prefs_get_char_expire_time();
while ((charname=dir.read())) {
charinfo = (t_d2charinfo_file*)xmalloc(sizeof(t_d2charinfo_file));
if (d2charinfo_load(account,charname,charinfo)<0) {
eventlog(eventlog_level_error,__FUNCTION__,"error loading charinfo for {}(*{})",charname,account);
xfree(charinfo);
continue;
exp_time = prefs_get_char_expire_time();
while ((charname = dir.read())) {
charinfo = (t_d2charinfo_file*)xmalloc(sizeof(t_d2charinfo_file));
if (d2charinfo_load(account, charname, charinfo) < 0) {
eventlog(eventlog_level_error, __FUNCTION__, "error loading charinfo for {}(*{})", charname, account);
xfree(charinfo);
continue;
}
if (exp_time) {
curr_exp_time = bn_int_get(charinfo->header.last_time) + exp_time;
}
else {
curr_exp_time = 0x7FFFFFFF;
}
eventlog(eventlog_level_debug, __FUNCTION__, "adding char {} (*{})", charname, account);
d2charlist_add_char(&charlist_head, charinfo, curr_exp_time);
n++;
if (n >= maxchar) break;
}
if (exp_time) {
curr_exp_time = bn_int_get(charinfo->header.last_time)+exp_time;
} else {
curr_exp_time = 0x7FFFFFFF;
if (n >= maxchar)
maxchar = 0;
if (!std::strcmp(charlist_sort_order, "ASC"))
{
t_elist* curr, * safe;
t_d2charlist* ccharlist;
elist_for_each_safe(curr, &charlist_head, safe)
{
bn_int bn_exp_time;
ccharlist = elist_entry(curr, t_d2charlist, list);
bn_int_set(&bn_exp_time, ccharlist->expiration_time);
packet_append_data(rpacket, bn_exp_time, sizeof(bn_exp_time));
packet_append_string(rpacket, (char*)ccharlist->charinfo->header.charname);
packet_append_string(rpacket, (char*)&ccharlist->charinfo->portrait);
xfree((void*)ccharlist->charinfo);
xfree((void*)ccharlist);
}
}
eventlog(eventlog_level_debug,__FUNCTION__,"adding char {} (*{})", charname, account);
d2charlist_add_char(&charlist_head,charinfo,curr_exp_time);
n++;
if (n>=maxchar) break;
else
{
t_elist* curr, * safe;
t_d2charlist* ccharlist;
elist_for_each_safe_rev(curr, &charlist_head, safe)
{
bn_int bn_exp_time;
ccharlist = elist_entry(curr, t_d2charlist, list);
bn_int_set(&bn_exp_time, ccharlist->expiration_time);
packet_append_data(rpacket, bn_exp_time, sizeof(bn_exp_time));
packet_append_string(rpacket, (char*)ccharlist->charinfo->header.charname);
packet_append_string(rpacket, (char*)&ccharlist->charinfo->portrait);
xfree((void*)ccharlist->charinfo);
xfree((void*)ccharlist);
}
}
retry = false;
}
if (n>=maxchar)
maxchar = 0;
if (!std::strcmp(charlist_sort_order, "ASC"))
{
t_elist * curr, *safe;
t_d2charlist * ccharlist;
elist_for_each_safe(curr,&charlist_head,safe)
{
bn_int bn_exp_time;
ccharlist = elist_entry(curr,t_d2charlist,list);
bn_int_set(&bn_exp_time,ccharlist->expiration_time);
packet_append_data(rpacket,bn_exp_time,sizeof(bn_exp_time));
packet_append_string(rpacket,(char*)ccharlist->charinfo->header.charname);
packet_append_string(rpacket,(char *)&ccharlist->charinfo->portrait);
xfree((void *)ccharlist->charinfo);
xfree((void *)ccharlist);
}
catch (const Directory::OpenError&) {
ERROR1("(*{}) charinfo directory do not exist, building it", account);
if (p_mkdir(path, S_IRWXU) == 0)
{
INFO1("Successfully created charinfo directory ({})", path);
}
else
{
ERROR2("Failed to create charinfo directory ({}), errno = {}", path, errno);
retry = false;
}
}
else
{
t_elist * curr, *safe;
t_d2charlist * ccharlist;
elist_for_each_safe_rev(curr,&charlist_head,safe)
{
bn_int bn_exp_time;
ccharlist = elist_entry(curr,t_d2charlist,list);
bn_int_set(&bn_exp_time,ccharlist->expiration_time);
packet_append_data(rpacket,bn_exp_time,sizeof(bn_exp_time));
packet_append_string(rpacket,(char*)ccharlist->charinfo->header.charname);
packet_append_string(rpacket,(char *)&ccharlist->charinfo->portrait);
xfree((void *)ccharlist->charinfo);
xfree((void *)ccharlist);
}
}
} catch (const Directory::OpenError&) {
INFO1("(*{}) charinfo directory do not exist, building it",account);
p_mkdir(path,S_IRWXU);
}
bn_short_set(&rpacket->u.d2cs_client_charlistreply.currchar,n);
bn_short_set(&rpacket->u.d2cs_client_charlistreply.currchar2,n);
bn_short_set(&rpacket->u.d2cs_client_charlistreply.maxchar,maxchar);

View file

@ -1,5 +1,15 @@
#include "console_resource.h"
#define APSTUDIO_READONLY_SYMBOLS
#ifndef __BORLANDC__
#ifdef __AFXRES_H__
#include "afxres.h"
#else
#include "winres.h"
#endif
#endif
/* Icon */
ID_ICON1 ICON DISCARDABLE "win32/logo01.ico"

View file

@ -17,13 +17,9 @@
#ifdef WIN32
#include <cstring>
#include <cwchar>
#include <string>
#include <vector>
#include <windows.h>
#ifndef WINADVAPI
#if !defined(WINADVAPI)
#if !defined(_ADVAPI32_)
#define WINADVAPI DECLSPEC_IMPORT
#else
@ -38,100 +34,72 @@ extern char serviceDescription[];
extern int g_ServiceStatus;
#ifdef WIN32_GUI
extern int app_main(int argc, char ** argv);
extern int app_main(int argc, char** argv);
#else
extern int main(int argc, char ** argv);
extern int main(int argc, char** argv);
#endif
SERVICE_STATUS serviceStatus;
SERVICE_STATUS_HANDLE serviceStatusHandle = 0;
typedef WINADVAPI BOOL(WINAPI *CSD_T)(SC_HANDLE hService, DWORD dwInfoLevel, LPVOID lpInfo);
typedef WINADVAPI BOOL(WINAPI* CSD_T)(SC_HANDLE, DWORD, LPCVOID);
void Win32_ServiceInstall()
{
SC_HANDLE serviceControlManager = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CREATE_SERVICE);
if (!serviceControlManager)
{
return;
}
SERVICE_DESCRIPTIONA sdBuf;
CSD_T ChangeServiceDescription;
HMODULE advapi32;
SC_HANDLE serviceControlManager = OpenSCManagerA(0, 0, SC_MANAGER_CREATE_SERVICE);
wchar_t path[MAX_PATH + 10] = {};
if (GetModuleFileNameW(nullptr, path, sizeof path / sizeof *path) != 0)
if (serviceControlManager)
{
return;
}
char path[_MAX_PATH + 10];
if (GetModuleFileNameA(0, path, sizeof(path) / sizeof(path[0])) > 0)
{
SC_HANDLE service;
std::strcat(path, " --service");
service = CreateServiceA(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;
std::wcscat(path, L"--service");
if (!(advapi32 = GetModuleHandleA("ADVAPI32.DLL")))
{
CloseServiceHandle(service);
CloseServiceHandle(serviceControlManager);
return;
}
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;
};
if (!(ChangeServiceDescription = (CSD_T)GetProcAddress(advapi32, "ChangeServiceConfig2A")))
{
CloseServiceHandle(service);
CloseServiceHandle(serviceControlManager);
return;
}
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);
ChangeServiceDescription(
service, // handle to service
SERVICE_CONFIG_DESCRIPTION, // change: description
&sdBuf);
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 = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CONNECT);
SC_HANDLE serviceControlManager = OpenSCManagerA(0, 0, SC_MANAGER_CONNECT);
if (serviceControlManager)
{
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);
SC_HANDLE service = OpenServiceA(serviceControlManager,
serviceName, SERVICE_QUERY_STATUS | DELETE);
if (service)
{
SERVICE_STATUS serviceStatus;
@ -201,29 +169,17 @@ void WINAPI ServiceMain(DWORD argc, char* argv[])
serviceStatus.dwCheckPoint = 0;
serviceStatus.dwWaitHint = 0;
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);
serviceStatusHandle = RegisterServiceCtrlHandlerA(serviceName, ServiceControlHandler);
if (serviceStatusHandle)
{
wchar_t path[MAX_PATH + 1] = {};
unsigned last_slash = 0;
char path[_MAX_PATH + 1];
unsigned int i, last_slash = 0;
GetModuleFileNameW(0, path, sizeof path / sizeof *path);
GetModuleFileNameA(0, path, sizeof(path) / sizeof(path[0]));
for (std::size_t i = 0; i < std::wcslen(path); i++)
{
if (path[i] == '\\')
last_slash = i;
for (i = 0; i < std::strlen(path); i++) {
if (path[i] == '\\') last_slash = i;
}
path[last_slash] = 0;
@ -233,7 +189,7 @@ void WINAPI ServiceMain(DWORD argc, char* argv[])
SetServiceStatus(serviceStatusHandle, &serviceStatus);
// do initialisation here
SetCurrentDirectoryW(path);
SetCurrentDirectoryA(path);
// running
serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
@ -277,7 +233,9 @@ void Win32_ServiceRun()
{ 0, 0 }
};
StartServiceCtrlDispatcherA(serviceTable);
if (!StartServiceCtrlDispatcherA(serviceTable))
{
}
}
#endif
#endif