Crossfire Server, Trunk
win32.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
21 #if defined(WIN32) || defined (CF_MXE_CROSS_COMPILE)
22 
23 #include <global.h>
24 
25 #include <stdarg.h>
26 #include <malloc.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <mmsystem.h>
30 
31 #if 0
32 
40 DIR *opendir(const char *dir) {
41  DIR *dp;
42  char *filespec;
43  long handle;
44  int index;
45 
46  filespec = malloc(strlen(dir)+2+1);
47  strcpy(filespec, dir);
48  index = strlen(filespec)-1;
49  if (index >= 0 && (filespec[index] == '/' || filespec[index] == '\\'))
50  filespec[index] = '\0';
51  strcat(filespec, "/*");
52 
53  dp = (DIR *)malloc(sizeof(DIR));
54  dp->offset = 0;
55  dp->finished = 0;
56  dp->dir = strdup(dir);
57 
58  if ((handle = _findfirst(filespec, &(dp->fileinfo))) < 0) {
59  free(filespec);
60  free(dp);
61  return NULL;
62  }
63  dp->handle = handle;
64  free(filespec);
65 
66  return dp;
67 }
68 
78 struct dirent *readdir(DIR *dp) {
79  if (!dp || dp->finished)
80  return NULL;
81 
82  if (dp->offset != 0) {
83  if (_findnext(dp->handle, &(dp->fileinfo)) < 0) {
84  dp->finished = 1;
85  if (ENOENT == errno)
86  /* Clear error set to mean no more files else that breaks things */
87  errno = 0;
88  return NULL;
89  }
90  }
91  dp->offset++;
92 
93  strncpy(dp->dent.d_name, dp->fileinfo.name, _MAX_FNAME);
94  dp->dent.d_name[_MAX_FNAME] = '\0';
95  dp->dent.d_ino = 1;
96  /* reclen is used as meaning the length of the whole record */
97  dp->dent.d_reclen = strlen(dp->dent.d_name)+sizeof(char)+sizeof(dp->dent.d_ino)+sizeof(dp->dent.d_reclen)+sizeof(dp->dent.d_off);
98  dp->dent.d_off = dp->offset;
99 
100  return &(dp->dent);
101 }
102 
111 int closedir(DIR *dp) {
112  if (!dp)
113  return 0;
114  _findclose(dp->handle);
115  free(dp->dir);
116  free(dp);
117 
118  return 0;
119 }
120 
127 void rewinddir(DIR *dir_Info) {
128  /* Re-set to the beginning */
129  char *filespec;
130  long handle;
131  int index;
132 
133  dir_Info->handle = 0;
134  dir_Info->offset = 0;
135  dir_Info->finished = 0;
136 
137  filespec = malloc(strlen(dir_Info->dir)+2+1);
138  strcpy(filespec, dir_Info->dir);
139  index = strlen(filespec)-1;
140  if (index >= 0 && (filespec[index] == '/' || filespec[index] == '\\'))
141  filespec[index] = '\0';
142  strcat(filespec, "/*");
143 
144  if ((handle = _findfirst(filespec, &(dir_Info->fileinfo))) < 0) {
145  if (errno == ENOENT) {
146  dir_Info->finished = 1;
147  }
148  }
149  dir_Info->handle = handle;
150  free(filespec);
151 }
152 #endif
153 
154 /* Service-related stuff
155 
156  Those functions are called while init is still being done, so no logging available.
157  */
158 
160 int bRunning;
161 
163 SERVICE_STATUS m_ServiceStatus;
165 SERVICE_STATUS_HANDLE m_ServiceStatusHandle;
167 #define SERVICE_NAME L"Crossfire"
168 
169 #define SERVICE_DISPLAY L"Crossfire server"
170 
171 #define SERVICE_DESCRIPTION L"Crossfire is a multiplayer online RPG game."
172 
173 #include <winsvc.h>
174 
179 void service_register(void) {
180  TCHAR strDir[MAX_PATH];
181  SC_HANDLE schSCManager;
182  SC_HANDLE schService;
183  wchar_t *strDescription = SERVICE_DESCRIPTION;
184 
185  GetModuleFileName(NULL, strDir, MAX_PATH);
186  wcscat(strDir, L" -srv");
187 
188  schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
189 
190  if (schSCManager == NULL) {
191  printf("openscmanager failed");
192  exit(1);
193  }
194 
195  schService = CreateService(schSCManager,
196  SERVICE_NAME,
197  SERVICE_DISPLAY, /* service name to display */
198  SERVICE_ALL_ACCESS, /* desired access */
199  SERVICE_WIN32_OWN_PROCESS, /* service type */
200  SERVICE_DEMAND_START, /* start type */
201  SERVICE_ERROR_NORMAL, /* error control type */
202  strDir, /* service's binary */
203  NULL, /* no load ordering group */
204  NULL, /* no tag identifier */
205  NULL, /* no dependencies */
206  NULL, /* LocalSystem account */
207  NULL); /* no password */
208 
209  if (schService == NULL) {
210  printf("createservice failed");
211  exit(1);
212  }
213 
214  ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &strDescription);
215 
216  CloseServiceHandle(schService);
217  CloseServiceHandle(schSCManager);
218  exit(0);
219 }
220 
225 void service_unregister(void) {
226  SC_HANDLE schSCManager;
227  SC_HANDLE hService;
228 
229  schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
230 
231  if (schSCManager == NULL) {
232  printf("open failed");
233  exit(1);
234  }
235 
236  hService = OpenService(schSCManager, SERVICE_NAME, SERVICE_ALL_ACCESS);
237 
238  if (hService == NULL) {
239  printf("openservice failed");
240  exit(1);
241  }
242 
243  if (DeleteService(hService) == 0) {
244  printf("Delete failed");
245  exit(1);
246  }
247 
248  if (CloseServiceHandle(hService) == 0) {
249  printf("close failed");
250  exit(1);
251  }
252 
253  if (!CloseServiceHandle(schSCManager)) {
254  printf("close schSCManager failed");
255  exit(1);
256  }
257 
258  exit(0);
259 }
260 
267 void WINAPI ServiceCtrlHandler(DWORD Opcode) {
268  switch (Opcode) {
269  case SERVICE_CONTROL_PAUSE:
270  m_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
271  break;
272 
273  case SERVICE_CONTROL_CONTINUE:
274  m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
275  break;
276 
277  case SERVICE_CONTROL_STOP:
278  m_ServiceStatus.dwWin32ExitCode = 0;
279  m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
280  m_ServiceStatus.dwCheckPoint = 0;
281  m_ServiceStatus.dwWaitHint = 0;
282 
283  SetServiceStatus(m_ServiceStatusHandle, &m_ServiceStatus);
284 
285  bRunning = 0;
286 
287  LOG(llevInfo, "Service stopped.\n");
288 
289  break;
290 
291  case SERVICE_CONTROL_INTERROGATE:
292  break;
293  }
294  return;
295 }
296 
297 extern int main(int argc, char **argv);
298 
306 void WINAPI ServiceMain(DWORD argc, LPTSTR *argv) {
307  TCHAR strDir[1024];
308  wchar_t *strSlash;
309 
310  GetModuleFileName(NULL, strDir, 1024);
311  strSlash = wcschr(strDir, '\\');
312  if (strSlash)
313  *strSlash = '\0';
314  _wchdir(strDir);
315 
316  m_ServiceStatus.dwServiceType = SERVICE_WIN32;
317  m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
318  m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
319  m_ServiceStatus.dwWin32ExitCode = 0;
320  m_ServiceStatus.dwServiceSpecificExitCode = 0;
321  m_ServiceStatus.dwCheckPoint = 0;
322  m_ServiceStatus.dwWaitHint = 0;
323 
324  m_ServiceStatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler);
325  if (m_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0) {
326  return;
327  }
328 
329  m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
330  m_ServiceStatus.dwCheckPoint = 0;
331  m_ServiceStatus.dwWaitHint = 0;
332  SetServiceStatus(m_ServiceStatusHandle, &m_ServiceStatus);
333 
334  bRunning = 1;
335  main(0, NULL);
336 
337  return;
338 }
339 
343 void service_handle(void) {
344  SERVICE_TABLE_ENTRY DispatchTable[] = {
345  { SERVICE_NAME, ServiceMain },
346  { NULL, NULL }
347  };
348  StartServiceCtrlDispatcher(DispatchTable);
349  exit(0);
350 }
351 
352 #endif // WIN32
global.h
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.cpp:58
service_handle
void service_handle()
service_register
void service_register()
opendir
DIR * opendir(const char *)
main
main(int argc, char *argv)
Definition: land.c:277
readdir
struct dirent * readdir(DIR *)
service_unregister
void service_unregister()
bRunning
int bRunning
llevInfo
@ llevInfo
Definition: logger.h:12
npc_dialog.index
int index
Definition: npc_dialog.py:102
QuestAdvance.handle
def handle()
Definition: QuestAdvance.py:37
rewinddir
void rewinddir(DIR *)
closedir
int closedir(DIR *)