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