1 karl 1.6 //%2006////////////////////////////////////////////////////////////////////////
|
2 h.sterling 1.1 //
3 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
6 // IBM Corp.; EMC Corporation, The Open Group.
7 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
9 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.6 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 h.sterling 1.1 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
20 //
21 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 //%/////////////////////////////////////////////////////////////////////////////
33
34 h.sterling 1.1 #include <windows.h>
35 #include <process.h> /* _beginthread, _endthread */
36 #include <tchar.h>
37 #include <direct.h>
|
38 kumpf 1.7 #include <Pegasus/Common/MessageLoader.h>
39 #include <Pegasus/Common/Thread.h>
|
40 h.sterling 1.1 #include <Pegasus/Server/CIMServer.h>
|
41 kumpf 1.8 #include <Service/ServerRunStatus.h>
|
42 h.sterling 1.1
43 #include "Service.cpp"
44
45 PEGASUS_USING_PEGASUS;
46 PEGASUS_USING_STD;
47
48 //-------------------------------------------------------------------------
49 // GLOBALS
50 //-------------------------------------------------------------------------
51 static Mutex _cimserverLock;
52 static ServerProcess* _server_proc = 0;
53 static bool _shutdown = false;
54 static Service pegasus_service;
55 static HANDLE pegasus_service_event = NULL;
|
56 kumpf 1.10 static LPCSTR g_cimservice_key =
57 TEXT("SYSTEM\\CurrentControlSet\\Services\\%s");
|
58 h.sterling 1.1 static LPCSTR g_cimservice_home = TEXT("home");
59 static int g_argc = 0;
60 static char **g_argv = 0;
61
62 // Constants representing the command line options.
63 static const char OPTION_INSTALL[] = "install";
64 static const char OPTION_REMOVE[] = "remove";
65 static const char OPTION_START[] = "start";
66 static const char OPTION_STOP[] = "stop";
67
68 //-------------------------------------------------------------------------
69 // PROTOTYPES
70 //-------------------------------------------------------------------------
71 int cimserver_windows_main(int flag, int argc, char **argv);
72 static bool _getRegInfo(const char *lpchKeyword, char *lpchRetValue);
73 static bool _setRegInfo(const char *lpchKeyword, const char *lpchValue);
74
75 //-------------------------------------------------------------------------
76 // NO-OPs for windows platform
77 //-------------------------------------------------------------------------
|
78 kumpf 1.10 int ServerProcess::cimserver_fork() { return(0); }
|
79 h.sterling 1.1 void ServerProcess::notify_parent(int id) { return; }
80 void cimserver_exitRC(int rc) {}
|
81 kumpf 1.10 int ServerProcess::cimserver_initialize() { return 0; }
82 int ServerProcess::cimserver_wait() { return 0; }
|
83 h.sterling 1.1
84
85 //-------------------------------------------------------------------------
86 // Helper for platform specific handling
87 //-------------------------------------------------------------------------
88
89 ServerProcess::ServerProcess()
90 {
|
91 kumpf 1.10 // Be sure to call cimserver_set_process right after instantiating this in
92 // order for everything to work
|
93 h.sterling 1.1 }
94
95 ServerProcess::~ServerProcess()
96 {
97 }
98
99 void ServerProcess::cimserver_set_process(void* p)
100 {
|
101 kumpf 1.10 AutoMutex am(_cimserverLock);
|
102 h.sterling 1.1 _server_proc = static_cast<ServerProcess *>(p);
|
103 kumpf 1.10 if (_server_proc && _shutdown)
|
104 h.sterling 1.1 _server_proc->cimserver_stop();
105
106 pegasus_service = Service(getProcessName());
107 }
108
109 void signal_shutdown()
110 {
|
111 kumpf 1.10 AutoMutex am(_cimserverLock);
|
112 h.sterling 1.1 _shutdown = true;
|
113 kumpf 1.10 if (_server_proc)
|
114 h.sterling 1.1 _server_proc->cimserver_stop();
115 }
116
117 //-------------------------------------------------------------------------
118 // Run main server asynchronously
119 //-------------------------------------------------------------------------
|
120 kumpf 1.10 static unsigned __stdcall cimserver_windows_thread(void* parm)
|
121 h.sterling 1.1 {
122 int argc = 0;
|
123 kumpf 1.10 int rc = _server_proc->cimserver_run(g_argc, g_argv, false, false);
|
124 h.sterling 1.1 SetEvent(pegasus_service_event);
|
125 kumpf 1.10 _endthreadex(rc);
|
126 h.sterling 1.1 return rc;
127 }
128
129 //-------------------------------------------------------------------------
130 // Windows NT Service Control Code
131 //-------------------------------------------------------------------------
132
133 //-------------------------------------------------------------------------
134 // START/STOP handler
135 //-------------------------------------------------------------------------
136 int cimserver_windows_main(int flag, int argc, char *argv[])
137 {
|
138 kumpf 1.10 switch(flag)
|
139 h.sterling 1.1 {
140 case Service::STARTUP_FLAG:
141 {
142 //
143 // Start up main run in a separate thread and wait for it to finish.
144 //
145
146 unsigned threadid = 0;
147 g_argc = argc;
148 g_argv = argv;
|
149 kumpf 1.10 HANDLE hThread = (HANDLE)_beginthreadex(
150 NULL, 0, cimserver_windows_thread, NULL, 0, &threadid);
151 if (hThread == NULL)
|
152 h.sterling 1.1 return 1;
153
|
154 kumpf 1.10 WaitForSingleObject(pegasus_service_event, INFINITE);
|
155 h.sterling 1.1
156 //
157 // Shutdown the cimserver.
158 //
159
160 signal_shutdown();
161
162 //
163 // Make sure we upate the SCM that our stop is pending.
164 // Wait for the main run thread to exit.
165 //
166
167 DWORD dwCheckPoint = 1; // service code should have already started at 0
168
|
169 kumpf 1.10 while (WaitForSingleObject(hThread, 3000) == WAIT_TIMEOUT)
|
170 h.sterling 1.1 {
171 pegasus_service.report_status(
|
172 kumpf 1.10 SERVICE_STOP_PENDING, NO_ERROR, dwCheckPoint++, 5000);
|
173 h.sterling 1.1 }
174
|
175 kumpf 1.10 CloseHandle(hThread);
|
176 h.sterling 1.1 break;
177 }
178 case Service::SHUTDOWN_FLAG:
179 SetEvent(pegasus_service_event);
180 break;
181
182 default:
183 break;
184 }
185
186 return 0;
187 }
188
189
190 //-------------------------------------------------------------------------
191 // INSTALL
192 //-------------------------------------------------------------------------
193 bool cimserver_install_nt_service(char *service_name)
194 {
|
195 kumpf 1.10 Service::ReturnCode status = Service::SERVICE_RETURN_SUCCESS;
196 char filename[_MAX_PATH] = {0};
197 char displayname[_MAX_PATH] = {0};
198 char descriptionname[_MAX_PATH] = {0};
199
200 // If service name is specified, override default
201 if (service_name == NULL)
202 {
203 strcpy(displayname, _server_proc->getExtendedName());
204 }
205 else
206 {
207 pegasus_service.SetServiceName(service_name);
208 sprintf(displayname, "%s - %s",
209 _server_proc->getExtendedName(),
210 service_name);
211 }
212
213 strcpy(descriptionname, _server_proc->getDescription());
214
215 if (0 != GetModuleFileName(NULL, filename, sizeof(filename)))
216 kumpf 1.10 {
217 status =
218 pegasus_service.Install(displayname, descriptionname, filename);
219
220 // Upon success, set home in registry
221 if (status == Service::SERVICE_RETURN_SUCCESS)
222 {
223 char pegasus_homepath[_MAX_PATH];
224 System::extract_file_path(filename, pegasus_homepath);
225 pegasus_homepath[strlen(pegasus_homepath)-1] = '\0';
226 strcpy(filename, pegasus_homepath);
227 System::extract_file_path(filename, pegasus_homepath);
228 pegasus_homepath[strlen(pegasus_homepath)-1] = '\0';
229 _setRegInfo(g_cimservice_home, pegasus_homepath);
230 }
231 }
232 else
233 {
234 status = (Service::ReturnCode) GetLastError();
235 }
236
237 kumpf 1.10 return (status == Service::SERVICE_RETURN_SUCCESS);
|
238 h.sterling 1.1 }
239
240 //-------------------------------------------------------------------------
241 // REMOVE
242 //-------------------------------------------------------------------------
|
243 kumpf 1.10 bool cimserver_remove_nt_service(char* service_name)
|
244 h.sterling 1.1 {
|
245 kumpf 1.10 Service::ReturnCode status = Service::SERVICE_RETURN_SUCCESS;
|
246 h.sterling 1.1
|
247 kumpf 1.10 // If service name is specified, override default
248 if (service_name != NULL)
|
249 h.sterling 1.1 {
|
250 kumpf 1.10 pegasus_service.SetServiceName(service_name);
|
251 h.sterling 1.1 }
252
|
253 kumpf 1.10 status = pegasus_service.Remove();
|
254 h.sterling 1.1
|
255 kumpf 1.10 return (status == Service::SERVICE_RETURN_SUCCESS);
|
256 h.sterling 1.1 }
257
258 //-------------------------------------------------------------------------
259 // START
260 //-------------------------------------------------------------------------
|
261 kumpf 1.10 bool cimserver_start_nt_service(
262 char* service_name,
263 int num_args,
264 char** service_args)
|
265 h.sterling 1.1 {
|
266 kumpf 1.10 Service::ReturnCode status = Service::SERVICE_RETURN_SUCCESS;
|
267 h.sterling 1.1
|
268 kumpf 1.10 // If service name is specified, override default
269 if (service_name != NULL)
|
270 h.sterling 1.1 {
|
271 kumpf 1.10 pegasus_service.SetServiceName(service_name);
|
272 h.sterling 1.1 }
273
|
274 kumpf 1.10 if (num_args > 0 && service_args != NULL)
275 {
276 pegasus_service.SetServiceArgs(num_args, service_args);
277 }
|
278 h.sterling 1.1
|
279 kumpf 1.10 status = pegasus_service.Start(5);
|
280 h.sterling 1.1
|
281 kumpf 1.10 return (status == Service::SERVICE_RETURN_SUCCESS);
|
282 h.sterling 1.1 }
283
284 //-------------------------------------------------------------------------
285 // STOP
286 //-------------------------------------------------------------------------
|
287 kumpf 1.10 bool cimserver_stop_nt_service(char* service_name)
|
288 h.sterling 1.1 {
|
289 kumpf 1.10 Service::ReturnCode status = Service::SERVICE_RETURN_SUCCESS;
|
290 h.sterling 1.1
|
291 kumpf 1.10 // If service name is specified, override default
292 if (service_name != NULL)
|
293 h.sterling 1.1 {
|
294 kumpf 1.10 pegasus_service.SetServiceName(service_name);
|
295 h.sterling 1.1 }
296
|
297 kumpf 1.10 status = pegasus_service.Stop(5);
|
298 h.sterling 1.1
|
299 kumpf 1.10 return (status == Service::SERVICE_RETURN_SUCCESS);
|
300 h.sterling 1.1 }
301
302 //-------------------------------------------------------------------------
303 // HELPER Utilities
304 //-------------------------------------------------------------------------
|
305 kumpf 1.10 static bool _getRegInfo(
306 const char* lpchKeyword,
307 char* lpchRetValue)
|
308 h.sterling 1.1 {
|
309 kumpf 1.10 HKEY hKey;
310 DWORD dw = _MAX_PATH;
311 char subKey[_MAX_PATH] = {0};
312
313 sprintf(subKey, g_cimservice_key, pegasus_service.GetServiceName());
|
314 h.sterling 1.1
|
315 kumpf 1.10 if ((RegOpenKeyEx(
316 HKEY_LOCAL_MACHINE,
317 subKey,
318 0,
319 KEY_READ,
320 &hKey)) != ERROR_SUCCESS)
|
321 h.sterling 1.1 {
|
322 kumpf 1.10 return false;
|
323 h.sterling 1.1 }
324
|
325 kumpf 1.10 if ((RegQueryValueEx(
326 hKey,
327 lpchKeyword,
328 NULL,
329 NULL,
330 (LPBYTE)lpchRetValue,
331 &dw)) != ERROR_SUCCESS)
|
332 h.sterling 1.1 {
|
333 kumpf 1.10 RegCloseKey(hKey);
334 return false;
|
335 h.sterling 1.1 }
336
|
337 kumpf 1.10 RegCloseKey(hKey);
|
338 h.sterling 1.1
|
339 kumpf 1.10 return true;
|
340 h.sterling 1.1 }
341
|
342 kumpf 1.10 static bool _setRegInfo(
343 const char* lpchKeyword,
344 const char* lpchValue)
|
345 h.sterling 1.1 {
|
346 kumpf 1.10 HKEY hKey;
347 DWORD dw = _MAX_PATH;
348 char home_key[_MAX_PATH] = {0};
349 char subKey[_MAX_PATH] = {0};
|
350 h.sterling 1.1
|
351 kumpf 1.10 if (lpchKeyword == NULL || lpchValue == NULL)
352 return false;
|
353 h.sterling 1.1
|
354 kumpf 1.10 sprintf(subKey, g_cimservice_key, pegasus_service.GetServiceName());
|
355 h.sterling 1.1
|
356 kumpf 1.10 if ((RegCreateKeyEx(
357 HKEY_LOCAL_MACHINE,
358 subKey,
359 0,
360 NULL,
361 0,
362 KEY_ALL_ACCESS,
363 NULL,
364 &hKey,
365 NULL) != ERROR_SUCCESS))
|
366 h.sterling 1.1 {
|
367 kumpf 1.10 return false;
|
368 h.sterling 1.1 }
369
|
370 kumpf 1.10 if ((RegSetValueEx(
371 hKey,
372 lpchKeyword,
373 0,
374 REG_SZ,
375 (CONST BYTE *)lpchValue,
376 (DWORD)(strlen(lpchValue)+1))) != ERROR_SUCCESS)
|
377 h.sterling 1.1 {
|
378 kumpf 1.10 RegCloseKey(hKey);
379 return false;
|
380 h.sterling 1.1 }
381
|
382 kumpf 1.10 RegCloseKey(hKey);
|
383 h.sterling 1.1
|
384 kumpf 1.10 return true;
|
385 h.sterling 1.1 }
386
387 //void ServerProcess::setHome(const String& home)
|
388 kumpf 1.10 String ServerProcess::getHome()
|
389 h.sterling 1.1 {
|
390 kumpf 1.7 String home;
|
391 h.sterling 1.1
|
392 kumpf 1.10 // Determine the absolute path to the running program
393 char exe_pathname[_MAX_PATH] = {0};
394 char home_pathname[_MAX_PATH] = {0};
395 if (0 != GetModuleFileName(NULL, exe_pathname, sizeof(exe_pathname)))
396 {
397 // Pegasus home search rules:
398 // - look in registry (if set)
399 // - if not found, look in PEGASUS_HOME (if set)
400 // - if not found, use exe directory minus one level
401
402 bool found_reg = _getRegInfo("home", home_pathname);
403 if (found_reg)
404 {
405 // Make sure home matches
406 String current_home(home_pathname);
407 String current_exe(exe_pathname);
408 current_home.toLower();
409 current_exe.toLower();
410
411 Uint32 pos = current_exe.find(current_home);
412 if (pos != PEG_NOT_FOUND)
413 kumpf 1.10 {
414 home = home_pathname;
415 }
416 else
417 {
418 found_reg = false;
419 }
420 }
421 if (found_reg == false)
422 {
423 const char* tmp = getenv("PEGASUS_HOME");
424 if (tmp)
425 {
426 home = tmp;
427 }
428 else
429 {
430 // ASSUMPTION: At a minimum, the cimserver program is running
431 // from a "bin" directory
432 home = FileSystem::extractFilePath(exe_pathname);
433 home.remove(home.size()-1, 1);
434 kumpf 1.10 home = FileSystem::extractFilePath(home);
435 home.remove(home.size()-1, 1);
436 }
437 }
438 }
|
439 h.sterling 1.1 return home;
440 }
441
442 //
443 // Our console control handler
444 //
445
|
446 kumpf 1.10 static BOOL WINAPI ControlHandler(DWORD dwCtrlType)
|
447 h.sterling 1.1 {
|
448 kumpf 1.10 switch (dwCtrlType)
|
449 h.sterling 1.1 {
450 case CTRL_BREAK_EVENT: // use Ctrl+C or Ctrl+Break to simulate
451 case CTRL_C_EVENT: // SERVICE_CONTROL_STOP in debug mode
452 {
453 signal_shutdown();
454 return TRUE;
455 }
456 }
457 return FALSE;
458 }
459
460 //
461 // Platform specific run
462 //
463
|
464 kumpf 1.4 int ServerProcess::platform_run(
465 int argc,
466 char** argv,
467 Boolean shutdownOption,
468 Boolean debugOutputOption)
|
469 h.sterling 1.1 {
470 //
471 // Check for my command line options
472 //
473
|
474 kumpf 1.10 for (int i = 1; i < argc; )
|
475 h.sterling 1.1 {
476 const char* arg = argv[i];
477
478 // Check for -option
479 if (*arg == '-')
480 {
481 // Get the option
482 const char* option = arg + 1;
483
484 if (strcmp(option, OPTION_INSTALL) == 0)
485 {
486 //
487 // Install as a NT service
488 //
489 char *opt_arg = NULL;
490 if (i+1 < argc)
491 {
492 opt_arg = argv[i+1];
493
494 }
|
495 kumpf 1.10 if (cimserver_install_nt_service(opt_arg))
|
496 h.sterling 1.1 {
497 //l10n
498 //cout << "\nPegasus installed as NT Service";
499 MessageLoaderParms parms(
500 "src.Server.cimserver.INSTALLED_NT_SERVICE",
501 "\nPegasus installed as a Windows service");
502 cout << MessageLoader::getMessage(parms) << endl;
503 exit(0);
504 }
505 else
506 {
507 exit(0);
508 }
509 }
510 else if (strcmp(option, OPTION_REMOVE) == 0)
511 {
512 //
513 // Remove Pegasus as an NT service
514 //
515 char *opt_arg = NULL;
516 if (i+1 < argc)
517 h.sterling 1.1 {
|
518 kumpf 1.10 opt_arg = argv[i+1];
|
519 h.sterling 1.1 }
|
520 kumpf 1.10 if (cimserver_remove_nt_service(opt_arg))
|
521 h.sterling 1.1 {
522 //l10n
523 //cout << "\nPegasus removed as NT Service";
524 MessageLoaderParms parms(
525 "src.Server.cimserver.REMOVED_NT_SERVICE",
526 "\nPegasus removed as a Windows service");
527 cout << MessageLoader::getMessage(parms) << endl;
528 exit(0);
529 }
530 else
531 {
532 exit(0);
533 }
534
535 }
536 else if (strcmp(option, OPTION_START) == 0)
537 {
538 //
539 // Start as a NT service
540 //
541 char *opt_arg = NULL;
542 h.sterling 1.1 int num_args = 0;
543 if (i+1 < argc)
544 {
|
545 kumpf 1.10 opt_arg = argv[i+1];
|
546 h.sterling 1.1 num_args = argc - 3;
547 }
548 else
549 {
550 num_args = argc - 2;
551 }
552
553 char **service_args = &argv[1];
|
554 kumpf 1.10 if (cimserver_start_nt_service(opt_arg, num_args, service_args))
|
555 h.sterling 1.1 {
556 MessageLoaderParms parms(
557 "src.Server.cimserver.STARTED_NT_SERVICE",
558 "\nPegasus started as a Windows service");
559 cout << MessageLoader::getMessage(parms) << endl;
560 exit(0);
561 }
562 else
563 {
564 exit(0);
565 }
566 }
567 else if (strcmp(option, OPTION_STOP) == 0)
568 {
569 //
570 // Stop as a NT service
571 //
572 char *opt_arg = NULL;
573 if (i+1 < argc)
574 {
|
575 kumpf 1.10 opt_arg = argv[i+1];
|
576 h.sterling 1.1 }
|
577 kumpf 1.10 if (cimserver_stop_nt_service(opt_arg))
|
578 h.sterling 1.1 {
579 MessageLoaderParms parms(
580 "src.Server.cimserver.STOPPED_NT_SERVICE",
581 "\nPegasus stopped as a Windows service");
582 cout << MessageLoader::getMessage(parms) << endl;
583 exit(0);
584 }
585 else
586 {
587 exit(0);
588 }
589 }
590 else
591 i++;
592 }
593 else
594 i++;
595 }
596
597 //
598 // Signal ourself as running
599 h.sterling 1.1 //
600
|
601 kumpf 1.8 // NOTE: This object must persist for the life of the server process
|
602 kumpf 1.11 ServerRunStatus serverRunStatus(getProcessName(), 0);
|
603 kumpf 1.8
604 if (!shutdownOption)
605 {
|
606 dave.sudlik 1.9 serverRunStatus.setServerRunning();
|
607 kumpf 1.8 }
|
608 h.sterling 1.1
609 //
610 // Check if already running
611 //
612 // Hmm, when starting as a service, should we do this here (before
613 // starting the control dispatcher)? If we do then the SCM reports
|
614 kumpf 1.10 // a dumb message to the user. If we don't, and it in the serviceProc
|
615 h.sterling 1.1 // then the service will start up then die silently.
616 //
617
|
618 kumpf 1.8 if (!shutdownOption && serverRunStatus.isServerRunning())
|
619 h.sterling 1.1 {
620 MessageLoaderParms parms(
621 "src.Server.cimserver.UNABLE_TO_START_SERVER_ALREADY_RUNNING",
|
622 kumpf 1.10 "Unable to start CIMServer.\nCIMServer is already running.");
|
623 h.sterling 1.1 Logger::put(
624 Logger::ERROR_LOG, "CIMServer", Logger::SEVERE,
|
625 kumpf 1.10 MessageLoader::getMessage(parms));
626 PEGASUS_STD(cerr) << MessageLoader::getMessage(parms) <<
627 PEGASUS_STD(endl);
|
628 h.sterling 1.1 return 1;
629 }
630
631 //
632 // Check if running from a console window. If so then just run
633 // as a console process.
634 //
635
636 char console_title[ _MAX_PATH ] = {0};
|
637 kumpf 1.10 if (GetConsoleTitle(console_title, _MAX_PATH) > 0)
|
638 h.sterling 1.1 {
|
639 kumpf 1.10 SetConsoleCtrlHandler(ControlHandler, TRUE);
|
640 h.sterling 1.1
|
641 kumpf 1.4 return cimserver_run(argc, argv, shutdownOption, debugOutputOption);
|
642 h.sterling 1.1 }
643
644 //
645 // Run as a service
646 //
647
|
648 kumpf 1.10 pegasus_service_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
649 h.sterling 1.1
650 Service::ReturnCode status;
|
651 kumpf 1.10 status = pegasus_service.Run(cimserver_windows_main);
|
652 h.sterling 1.1
|
653 kumpf 1.10 if (status != Service::SERVICE_RETURN_SUCCESS)
|
654 h.sterling 1.1 {
655 // todo: put into localized messages when messages unfreezes.
656 Logger::put_l(
657 Logger::ERROR_LOG, "CIMServer", Logger::SEVERE,
658 "src.Server.cimserver_windows.LISTENING_ON_HTTP_PORT",
|
659 kumpf 1.10 "Error during service run: code = $0.",
660 status);
|
661 h.sterling 1.1 return 1;
662 }
663
664 return 0;
665 }
|