Crossfire Server, Branches 1.12  R18729
win32.c
Go to the documentation of this file.
1 /*
2  CrossFire, A Multiplayer game for X-windows
3 
4  Copyright (C) 1992 Frank Tore Johansen
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 
20  The author can be reached via e-mail to frankj@ifi.uio.no.
21 */
22 
30 #include <global.h>
31 
32 #include <stdarg.h>
33 #include <malloc.h>
34 #include <string.h>
35 #include <errno.h>
36 #include <mmsystem.h>
37 
39 struct timezone {
42 };
43 
54 int gettimeofday(struct timeval *time_Info, struct timezone *timezone_Info) {
55  /* Get the time, if they want it */
56  if (time_Info != NULL) {
57  time_Info->tv_sec = time(NULL);
58  time_Info->tv_usec = timeGetTime()*1000;
59  }
60  /* Get the timezone, if they want it */
61  if (timezone_Info != NULL) {
62  _tzset();
63  timezone_Info->tz_minuteswest = _timezone;
64  timezone_Info->tz_dsttime = _daylight;
65  }
66  /* And return */
67  return 0;
68 }
69 
78 DIR *opendir(const char *dir) {
79  DIR *dp;
80  char *filespec;
81  long handle;
82  int index;
83 
84  filespec = malloc(strlen(dir)+2+1);
85  strcpy(filespec, dir);
86  index = strlen(filespec)-1;
87  if (index >= 0 && (filespec[index] == '/' || filespec[index] == '\\'))
88  filespec[index] = '\0';
89  strcat(filespec, "/*");
90 
91  dp = (DIR *)malloc(sizeof(DIR));
92  dp->offset = 0;
93  dp->finished = 0;
94  dp->dir = strdup(dir);
95 
96  if ((handle = _findfirst(filespec, &(dp->fileinfo))) < 0) {
97  free(filespec);
98  free(dp);
99  return NULL;
100  }
101  dp->handle = handle;
102  free(filespec);
103 
104  return dp;
105 }
106 
116 struct dirent *readdir(DIR *dp) {
117  if (!dp || dp->finished)
118  return NULL;
119 
120  if (dp->offset != 0) {
121  if (_findnext(dp->handle, &(dp->fileinfo)) < 0) {
122  dp->finished = 1;
123  if (ENOENT == errno)
124  /* Clear error set to mean no more files else that breaks things */
125  errno = 0;
126  return NULL;
127  }
128  }
129  dp->offset++;
130 
131  strncpy(dp->dent.d_name, dp->fileinfo.name, _MAX_FNAME);
132  dp->dent.d_name[_MAX_FNAME] = '\0';
133  dp->dent.d_ino = 1;
134  /* reclen is used as meaning the length of the whole record */
135  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);
136  dp->dent.d_off = dp->offset;
137 
138  return &(dp->dent);
139 }
140 
149 int closedir(DIR *dp) {
150  if (!dp)
151  return 0;
152  _findclose(dp->handle);
153  if (dp->dir)
154  free(dp->dir);
155  if (dp)
156  free(dp);
157 
158  return 0;
159 }
160 
167 void rewinddir(DIR *dir_Info) {
168  /* Re-set to the beginning */
169  char *filespec;
170  long handle;
171  int index;
172 
173  dir_Info->handle = 0;
174  dir_Info->offset = 0;
175  dir_Info->finished = 0;
176 
177  filespec = malloc(strlen(dir_Info->dir)+2+1);
178  strcpy(filespec, dir_Info->dir);
179  index = strlen(filespec)-1;
180  if (index >= 0 && (filespec[index] == '/' || filespec[index] == '\\'))
181  filespec[index] = '\0';
182  strcat(filespec, "/*");
183 
184  if ((handle = _findfirst(filespec, &(dir_Info->fileinfo))) < 0) {
185  if (errno == ENOENT) {
186  dir_Info->finished = 1;
187  }
188  }
189  dir_Info->handle = handle;
190  free(filespec);
191 }
192 
193 /* Service-related stuff
194 
195  Those functions are called while init is still being done, so no logging available.
196 
197  Not useful for plugins, though.
198 
199  */
200 
203 
204 #ifndef PYTHON_PLUGIN_EXPORTS
205 
206 SERVICE_STATUS m_ServiceStatus;
207 SERVICE_STATUS_HANDLE m_ServiceStatusHandle;
209 #define SERVICE_NAME "Crossfire"
210 
211 #define SERVICE_DISPLAY "Crossfire server"
212 
213 #define SERVICE_DESCRIPTION "Crossfire is a multiplayer online RPG game."
214 
215 #include <winsvc.h>
216 
222  char strDir[1024];
223  HANDLE schSCManager, schService;
224  char *strDescription = SERVICE_DESCRIPTION;
225 
226  GetModuleFileName(NULL, strDir, 1024);
227  strcat(strDir, " -srv");
228 
229  schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
230 
231  if (schSCManager == NULL) {
232  printf("openscmanager failed");
233  exit(1);
234  }
235 
236  schService = CreateService(schSCManager,
237  SERVICE_NAME,
238  SERVICE_DISPLAY, /* service name to display */
239  SERVICE_ALL_ACCESS, /* desired access */
240  SERVICE_WIN32_OWN_PROCESS, /* service type */
241  SERVICE_DEMAND_START, /* start type */
242  SERVICE_ERROR_NORMAL, /* error control type */
243  strDir, /* service's binary */
244  NULL, /* no load ordering group */
245  NULL, /* no tag identifier */
246  NULL, /* no dependencies */
247  NULL, /* LocalSystem account */
248  NULL); /* no password */
249 
250  if (schService == NULL) {
251  printf("createservice failed");
252  exit(1);
253  }
254 
255  ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &strDescription);
256 
257  CloseServiceHandle(schService);
258  CloseServiceHandle(schSCManager);
259  exit(0);
260 }
261 
267  HANDLE schSCManager;
268  SC_HANDLE hService;
269 
270  schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
271 
272  if (schSCManager == NULL) {
273  printf("open failed");
274  exit(1);
275  }
276 
277  hService = OpenService(schSCManager, SERVICE_NAME, SERVICE_ALL_ACCESS);
278 
279  if (hService == NULL) {
280  printf("openservice failed");
281  exit(1);
282  }
283 
284  if (DeleteService(hService) == 0) {
285  printf("Delete failed");
286  exit(1);
287  }
288 
289  if (CloseServiceHandle(hService) == 0) {
290  printf("close failed");
291  exit(1);
292  }
293 
294  if (!CloseServiceHandle(schSCManager)) {
295  printf("close schSCManager failed");
296  exit(1);
297  }
298 
299  exit(0);
300 }
301 
308 void WINAPI ServiceCtrlHandler(DWORD Opcode) {
309  switch (Opcode) {
310  case SERVICE_CONTROL_PAUSE:
311  m_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
312  break;
313 
314  case SERVICE_CONTROL_CONTINUE:
315  m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
316  break;
317 
318  case SERVICE_CONTROL_STOP:
319  m_ServiceStatus.dwWin32ExitCode = 0;
320  m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
321  m_ServiceStatus.dwCheckPoint = 0;
322  m_ServiceStatus.dwWaitHint = 0;
323 
324  SetServiceStatus(m_ServiceStatusHandle, &m_ServiceStatus);
325 
326  bRunning = 0;
327 
328  LOG(llevInfo, "Service stopped.\n");
329 
330  break;
331 
332  case SERVICE_CONTROL_INTERROGATE:
333  break;
334  }
335  return;
336 }
337 
338 extern int main(int argc, char **argv);
339 
347 void WINAPI ServiceMain(DWORD argc, LPTSTR *argv) {
348  char strDir[1024];
349  char *strSlash;
350 
351  GetModuleFileName(NULL, strDir, 1024);
352  strSlash = strrchr(strDir, '\\');
353  if (strSlash)
354  *strSlash = '\0';
355  chdir(strDir);
356 
357  m_ServiceStatus.dwServiceType = SERVICE_WIN32;
358  m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
359  m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
360  m_ServiceStatus.dwWin32ExitCode = 0;
361  m_ServiceStatus.dwServiceSpecificExitCode = 0;
362  m_ServiceStatus.dwCheckPoint = 0;
363  m_ServiceStatus.dwWaitHint = 0;
364 
365  m_ServiceStatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler);
366  if (m_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0) {
367  return;
368  }
369 
370  m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
371  m_ServiceStatus.dwCheckPoint = 0;
372  m_ServiceStatus.dwWaitHint = 0;
373  SetServiceStatus(m_ServiceStatusHandle, &m_ServiceStatus);
374 
375  bRunning = 1;
376  main(0, NULL);
377 
378  return;
379 }
380 
385  SERVICE_TABLE_ENTRY DispatchTable[] = {
387  { NULL, NULL }
388  };
389  StartServiceCtrlDispatcher(DispatchTable);
390  exit(0);
391 }
392 #endif /* PYTHON_PLUGIN_EXPORTS */
int tz_dsttime
Definition: win32.c:41
struct dirent dent
Definition: win32.h:144
#define SERVICE_DESCRIPTION
Definition: win32.c:213
unsigned short d_reclen
Definition: win32.h:131
int closedir(DIR *dp)
Definition: win32.c:149
short finished
Definition: win32.h:141
int bRunning
Definition: win32.c:202
char * dir
Definition: win32.h:143
DIR * opendir(const char *dir)
Definition: win32.c:78
void service_handle()
Definition: win32.c:384
int gettimeofday(struct timeval *time_Info, struct timezone *timezone_Info)
Definition: win32.c:54
long handle
Definition: win32.h:139
Definition: win32.h:128
void service_unregister()
Definition: win32.c:266
short offset
Definition: win32.h:140
Definition: win32.h:138
#define SERVICE_NAME
Definition: win32.c:209
long d_ino
Definition: win32.h:129
void WINAPI ServiceCtrlHandler(DWORD Opcode)
Definition: win32.c:308
int main(int argc, char **argv)
Definition: devel.c:50
void service_register()
Definition: win32.c:221
char d_name[_MAX_FNAME+1]
Definition: win32.h:132
SERVICE_STATUS m_ServiceStatus
Definition: win32.c:206
struct dirent * readdir(DIR *dp)
Definition: win32.c:116
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:63
off_t d_off
Definition: win32.h:130
struct _finddata_t fileinfo
Definition: win32.h:142
Definition: win32.c:39
SERVICE_STATUS_HANDLE m_ServiceStatusHandle
Definition: win32.c:207
void rewinddir(DIR *dir_Info)
Definition: win32.c:167
void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
Definition: win32.c:347
int tz_minuteswest
Definition: win32.c:40
#define SERVICE_DISPLAY
Definition: win32.c:211