ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/win32.C
Revision: 1.2
Committed: Tue Aug 29 08:01:38 2006 UTC (17 years, 9 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: STABLE
Changes since 1.1: +111 -111 lines
Log Message:
expand initial tabs to spaces

File Contents

# User Rev Content
1 elmex 1.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    
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     struct timezone {
32 root 1.2 int tz_minuteswest;
33     int tz_dsttime;
34 elmex 1.1 };
35    
36    
37     struct itimerval {
38 root 1.2 struct timeval it_interval; /* next value */
39     struct timeval it_value; /* current value */
40 elmex 1.1 };
41    
42     #define ITIMER_REAL 0 /*generates sigalrm */
43     #define ITIMER_VIRTUAL 1 /*generates sigvtalrm */
44     #define ITIMER_VIRT 1 /*generates sigvtalrm */
45     #define ITIMER_PROF 2 /*generates sigprof */
46    
47    
48     /* Functions to capsule or serve linux style function
49     * for Windows Visual C++
50     */
51     int gettimeofday(struct timeval *time_Info, struct timezone *timezone_Info)
52     {
53 root 1.2 /* Get the time, if they want it */
54     if (time_Info != NULL) {
55     time_Info->tv_sec = time(NULL);
56     time_Info->tv_usec = timeGetTime()*1000;
57     }
58     /* Get the timezone, if they want it */
59     if (timezone_Info != NULL) {
60     _tzset();
61     timezone_Info->tz_minuteswest = _timezone;
62     timezone_Info->tz_dsttime = _daylight;
63     }
64     /* And return */
65     return 0;
66 elmex 1.1 }
67    
68     DIR *opendir(const char *dir)
69     {
70 root 1.2 DIR *dp;
71     char *filespec;
72     long handle;
73     int index;
74    
75     filespec = malloc(strlen(dir) + 2 + 1);
76     strcpy(filespec, dir);
77     index = strlen(filespec) - 1;
78     if (index >= 0 && (filespec[index] == '/' || filespec[index] == '\\'))
79     filespec[index] = '\0';
80     strcat(filespec, "/*");
81    
82     dp = (DIR *) malloc(sizeof(DIR));
83     dp->offset = 0;
84     dp->finished = 0;
85     dp->dir = strdup(dir);
86    
87     if ((handle = _findfirst(filespec, &(dp->fileinfo))) < 0) {
88     free(filespec); free(dp);
89     return NULL;
90     }
91     dp->handle = handle;
92     free(filespec);
93 elmex 1.1
94 root 1.2 return dp;
95 elmex 1.1 }
96    
97     struct dirent *readdir(DIR * dp)
98     {
99 root 1.2 if (!dp || dp->finished)
100     return NULL;
101 elmex 1.1
102 root 1.2 if (dp->offset != 0) {
103     if (_findnext(dp->handle, &(dp->fileinfo)) < 0) {
104     dp->finished = 1;
105 elmex 1.1 if (ENOENT == errno)
106     /* Clear error set to mean no more files else that breaks things */
107     errno = 0;
108 root 1.2 return NULL;
109     }
110     }
111     dp->offset++;
112    
113     strncpy(dp->dent.d_name, dp->fileinfo.name, _MAX_FNAME);
114     dp->dent.d_name[_MAX_FNAME] = '\0';
115     dp->dent.d_ino = 1;
116 elmex 1.1 /* reclen is used as meaning the length of the whole record */
117 root 1.2 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);
118     dp->dent.d_off = dp->offset;
119 elmex 1.1
120 root 1.2 return &(dp->dent);
121 elmex 1.1 }
122    
123     int closedir(DIR * dp)
124     {
125 root 1.2 if (!dp)
126     return 0;
127     _findclose(dp->handle);
128     if (dp->dir)
129     free(dp->dir);
130     if (dp)
131     free(dp);
132 elmex 1.1
133 root 1.2 return 0;
134 elmex 1.1 }
135    
136     void rewinddir(DIR *dir_Info)
137     {
138 root 1.2 /* Re-set to the beginning */
139     char *filespec;
140     long handle;
141     int index;
142    
143     dir_Info->handle = 0;
144     dir_Info->offset = 0;
145     dir_Info->finished = 0;
146    
147     filespec = malloc(strlen(dir_Info->dir) + 2 + 1);
148     strcpy(filespec, dir_Info->dir);
149     index = strlen(filespec) - 1;
150     if (index >= 0 && (filespec[index] == '/' || filespec[index] == '\\'))
151     filespec[index] = '\0';
152     strcat(filespec, "/*");
153    
154     if ((handle = _findfirst(filespec, &(dir_Info->fileinfo))) < 0) {
155     if (errno == ENOENT) {
156     dir_Info->finished = 1;
157     }
158     }
159     dir_Info->handle = handle;
160     free(filespec);
161 elmex 1.1 }
162    
163     /* Service-related stuff
164    
165     Those functions are called while init is still being done, so no logging available.
166    
167     Not useful for plugins, though.
168    
169     */
170    
171     int bRunning;
172    
173     #ifndef PYTHON_PLUGIN_EXPORTS
174    
175     SERVICE_STATUS m_ServiceStatus;
176     SERVICE_STATUS_HANDLE m_ServiceStatusHandle;
177     #define SERVICE_NAME "Crossfire"
178     #define SERVICE_DISPLAY "Crossfire server"
179     #define SERVICE_DESCRIPTION "Crossfire is a multiplayer online RPG game."
180    
181     #include <winsvc.h>
182    
183     void service_register( )
184     {
185 root 1.2 char strDir[ 1024 ];
186     HANDLE schSCManager,schService;
187 elmex 1.1 char* strDescription = SERVICE_DESCRIPTION;
188    
189 root 1.2 GetModuleFileName( NULL, strDir, 1024 );
190 elmex 1.1 strcat( strDir, " -srv" );
191    
192 root 1.2 schSCManager = OpenSCManager( NULL,NULL,SC_MANAGER_ALL_ACCESS );
193 elmex 1.1
194 root 1.2 if (schSCManager == NULL)
195 elmex 1.1 {
196     printf( "openscmanager failed" );
197 root 1.2 exit( 1 );
198 elmex 1.1 }
199    
200     schService = CreateService(schSCManager, SERVICE_NAME, SERVICE_DISPLAY, // service name to display
201     SERVICE_ALL_ACCESS, // desired access
202     SERVICE_WIN32_OWN_PROCESS, // service type
203     SERVICE_DEMAND_START, // start type
204     SERVICE_ERROR_NORMAL, // error control type
205     strDir, // service's binary
206     NULL, // no load ordering group
207     NULL, // no tag identifier
208     NULL, // no dependencies
209     NULL, // LocalSystem account
210     NULL); // no password
211    
212     if (schService == NULL)
213     {
214     printf( "createservice failed" );
215     exit( 1 );
216     }
217    
218     ChangeServiceConfig2( schService, SERVICE_CONFIG_DESCRIPTION, &strDescription );
219    
220     CloseServiceHandle(schService);
221     CloseServiceHandle( schSCManager );
222     exit( 0 );
223     }
224    
225     void service_unregister( )
226     {
227 root 1.2 HANDLE schSCManager;
228     SC_HANDLE hService;
229 elmex 1.1
230 root 1.2 schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
231 elmex 1.1
232 root 1.2 if (schSCManager == NULL)
233 elmex 1.1 {
234     printf( "open failed" );
235 root 1.2 exit( 1 );
236 elmex 1.1 }
237    
238 root 1.2 hService=OpenService(schSCManager, SERVICE_NAME, SERVICE_ALL_ACCESS);
239 elmex 1.1
240 root 1.2 if (hService == NULL)
241 elmex 1.1 {
242     printf( "openservice failed" );
243 root 1.2 exit( 1 );
244 elmex 1.1 }
245    
246 root 1.2 if(DeleteService(hService)==0)
247 elmex 1.1 {
248     printf( "Delete failed" );
249 root 1.2 exit( 1 );
250 elmex 1.1 }
251    
252 root 1.2 if(CloseServiceHandle(hService)==0)
253 elmex 1.1 {
254     printf( "close failed" );
255 root 1.2 exit( 1 );
256 elmex 1.1 }
257    
258     if ( !CloseServiceHandle( schSCManager ) )
259     {
260     printf( "close schSCManager failed" );
261     exit( 1 );
262     }
263    
264     exit( 0 );
265     }
266    
267     void WINAPI ServiceCtrlHandler(DWORD Opcode)
268     {
269     switch(Opcode)
270     {
271     case SERVICE_CONTROL_PAUSE:
272     m_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
273     break;
274    
275     case SERVICE_CONTROL_CONTINUE:
276     m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
277     break;
278    
279     case SERVICE_CONTROL_STOP:
280     m_ServiceStatus.dwWin32ExitCode = 0;
281     m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
282     m_ServiceStatus.dwCheckPoint = 0;
283     m_ServiceStatus.dwWaitHint = 0;
284    
285     SetServiceStatus (m_ServiceStatusHandle,&m_ServiceStatus);
286    
287 root 1.2 bRunning = 0;
288 elmex 1.1
289     LOG( llevInfo, "Service stopped.\n" );
290    
291 root 1.2 break;
292 elmex 1.1
293     case SERVICE_CONTROL_INTERROGATE:
294     break;
295     }
296     return;
297     }
298    
299     extern int main( int argc, char** argv );
300    
301     void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
302     {
303 root 1.2 char strDir[ 1024 ];
304 elmex 1.1 char* strSlash;
305    
306 root 1.2 GetModuleFileName( NULL, strDir, 1024 );
307 elmex 1.1 strSlash = strrchr( strDir, '\\' );
308     if ( strSlash )
309     *strSlash = '\0';
310     chdir( strDir );
311    
312     m_ServiceStatus.dwServiceType = SERVICE_WIN32;
313     m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
314     m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
315     m_ServiceStatus.dwWin32ExitCode = 0;
316     m_ServiceStatus.dwServiceSpecificExitCode = 0;
317     m_ServiceStatus.dwCheckPoint = 0;
318     m_ServiceStatus.dwWaitHint = 0;
319    
320     m_ServiceStatusHandle = RegisterServiceCtrlHandler( SERVICE_NAME, ServiceCtrlHandler );
321     if (m_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
322     {
323     return;
324     }
325    
326     m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
327     m_ServiceStatus.dwCheckPoint = 0;
328     m_ServiceStatus.dwWaitHint = 0;
329     SetServiceStatus (m_ServiceStatusHandle, &m_ServiceStatus);
330    
331     bRunning = 1;
332     main( 0, NULL );
333    
334     return;
335     }
336    
337     void service_handle( )
338     {
339     SERVICE_TABLE_ENTRY DispatchTable[ ] = { { SERVICE_NAME, ServiceMain },{ NULL, NULL } };
340 root 1.2 StartServiceCtrlDispatcher( DispatchTable );
341 elmex 1.1 exit( 0 );
342     }
343     #endif /* PYTHON_PLUGIN_EXPORTS */