1 mike 1.7 //%/////////////////////////////////////////////////////////////////////////////
2 //
|
3 kumpf 1.16 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
4 // The Open Group, Tivoli Systems
|
5 mike 1.7 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
7 kumpf 1.16 // of this software and associated documentation files (the "Software"), to
8 // deal in the Software without restriction, including without limitation the
9 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
10 mike 1.7 // sell copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
|
13 kumpf 1.16 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
14 mike 1.7 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
15 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
16 kumpf 1.16 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
17 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
19 mike 1.7 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 //
22 //==============================================================================
23 //
24 // Author: Mike Day (mdday@us.ibm.com)
25 //
|
26 mary 1.11 // Modified By: Mary Hinton (m.hinton@verizon.net)
|
27 kumpf 1.12 // Sushma Fernandes (sushma_fernandes@hp.com)
|
28 mike 1.7 //
29 //%/////////////////////////////////////////////////////////////////////////////
30
31 #include <windows.h>
32 #include <process.h> /* _beginthread, _endthread */
33 #include <tchar.h>
34 #include <direct.h>
35
36
37 PEGASUS_USING_PEGASUS;
38 PEGASUS_USING_STD;
39
40 static DWORD dieNow = 0;
41 String *runPath;
42 CIMServer *server_windows;
43 static SERVICE_STATUS pegasus_status;
44 static SERVICE_STATUS_HANDLE pegasus_status_handle;
45
46 VOID WINAPI cimserver_windows_main(int argc, char **argv) ;
47 VOID WINAPI cimserver_service_start(DWORD, LPTSTR *);
48 VOID WINAPI cimserver_service_ctrl_handler(DWORD );
49 mike 1.7 DWORD cimserver_initialization(DWORD, LPTSTR *, DWORD *) ;
50
51 void GetOptions(
|
52 mike 1.8 ConfigManager* cm,
|
53 mike 1.7 int& argc,
54 char** argv,
|
55 mike 1.8 const String& pegasusHome);
|
56 mike 1.7
57 void cim_server_service(int argc, char **argv ) { cimserver_windows_main(argc, argv); exit(0); }
58 int cimserver_fork( ) { return(0); }
|
59 kumpf 1.15 int cimserver_kill( ) { return(0); }
|
60 mike 1.7
61 static void __cdecl cimserver_windows_thread(void *parm)
62 {
63
64 // Get options (from command line and from configuration file); this
65 // removes corresponding options and their arguments fromt he command
66 // line.
67
|
68 mike 1.8 PEGASUS_TRACE;
69 ConfigManager* configManager = ConfigManager::getInstance();
|
70 mike 1.7 int dummy = 0;
71 String pegasusHome;
|
72 mike 1.8
73 PEGASUS_TRACE;
|
74 mike 1.7 try
75 {
|
76 mike 1.8 PEGASUS_TRACE;
77 GetOptions(configManager, dummy, NULL, pegasusHome);
78 PEGASUS_TRACE;
|
79 mike 1.7 }
80 catch (Exception&)
81 {
82 exit(1);
83 }
|
84 mike 1.8 PEGASUS_TRACE;
|
85 mike 1.7
|
86 mike 1.8 //
|
87 mike 1.7 // Check the trace options and set global variable
|
88 mike 1.8 //
|
89 mike 1.7 Boolean pegasusIOTrace = false;
|
90 mike 1.8
91 if (String::equal(configManager->getCurrentValue("trace"), "true"))
|
92 mike 1.7 {
|
93 mike 1.8 pegasusIOTrace = true;
|
94 mike 1.7 }
95
|
96 mike 1.8 //
97 // Check the log trace options and set global variable
98 //
|
99 mike 1.7 Boolean pegasusIOLog = false;
|
100 mike 1.8
101 if (String::equal(configManager->getCurrentValue("logtrace"), "true"))
|
102 mike 1.7 {
|
103 mike 1.8 pegasusIOLog = true;
|
104 mike 1.7 }
|
105 mike 1.8 Boolean useSSL = false;
106
107 if (String::equal(configManager->getCurrentValue("SSL"), "true"))
108 {
109 useSSL = true;
110 }
111
|
112 mary 1.13 // mdh: need to get the environment for the Windows Service to run
113 const char* tmp = getenv("PEGASUS_HOME");
114 if (tmp)
115 {
116 pegasusHome = tmp;
117 }
118 ConfigManager::setPegasusHome(pegasusHome);
119
|
120 mike 1.8 PEGASUS_TRACE;
|
121 mike 1.7
122 // Grab the port otpion:
123
|
124 kumpf 1.14 String portOption;
125
126 if (useSSL)
127 {
128 portOption = configManager->getCurrentValue("httpsPort");
129 }
130 else
131 {
132 portOption = configManager->getCurrentValue("httpPort");
133 }
|
134 mike 1.7 char* address = portOption.allocateCString();
135
|
136 mike 1.8 PEGASUS_TRACE;
|
137 mike 1.7 // Set up the Logger
138 Logger::setHomeDirectory("./logs");
139
140 // Put server start message to the logger
141 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
142 "Start $0 %1 port $2 $3 ", 88, PEGASUS_NAME, PEGASUS_VERSION,
143 address, (pegasusIOTrace ? " Tracing": " "));
144 // try loop to bind the address, and run the server
145 try
146 {
|
147 mike 1.8 PEGASUS_TRACE;
148 Monitor monitor;
|
149 mike 1.7
|
150 kumpf 1.12 CIMServer server(&monitor, useSSL);
|
151 mike 1.7 server_windows = &server;
|
152 mike 1.8
153 char* end = 0;
154 long portNumber = strtol(address, &end, 10);
155 assert(end != 0 && *end == '\0');
|
156 mary 1.10
|
157 mike 1.8 server_windows->bind(portNumber);
158
|
159 mike 1.7 delete [] address;
|
160 mary 1.10
161 while(!server_windows->terminated())
162 {
163 server_windows->runForever();
164 }
|
165 mike 1.8 PEGASUS_TRACE;
|
166 mike 1.7 }
167 catch(Exception& e)
168 {
169 PEGASUS_STD(cerr) << "Error: " << e.getMessage() << PEGASUS_STD(endl);
170 }
171
|
172 mike 1.8 PEGASUS_TRACE;
|
173 mike 1.7 _endthreadex(NULL);
174 }
175
176
177 /////////////////////////////////////////////////////////////////
178 // Windows NT Service Control Code
179 /////////////////////////////////////////////////////////////////
180
181
182
183
184 VOID WINAPI cimserver_windows_main(int argc, char **argv)
185 {
|
186 mike 1.8 PEGASUS_TRACE;
|
187 mike 1.7 int ccode;
188 SERVICE_TABLE_ENTRY dispatch_table[] =
189 {
190 {"cimserver", cimserver_service_start},
191 {NULL, NULL}
192 };
193
194 /* let everyone know we are running (or trying to run) as an NT service */
195 if(!(ccode = StartServiceCtrlDispatcher(dispatch_table)))
196 {
197 ccode = GetLastError();
198 // Put server start message to the logger
199 Logger::put(Logger::STANDARD_LOG, "CIMServer_Windows", Logger::INFORMATION,
200 "Started as a Windows Service");
201 }
202 return;
203 }
204
205 /////////////////////////////////////////////////////////////////
206 //
207 // called by the NT service control manager to start the SLP service
208 mike 1.7 //
209 /////////////////////////////////////////////////////////////////
210
211 VOID WINAPI cimserver_service_start(DWORD argc, LPTSTR *argv)
212 {
213
214 DWORD status;
215 DWORD specificError;
216 pegasus_status.dwServiceType = SERVICE_WIN32;
217 pegasus_status.dwCurrentState = SERVICE_START_PENDING;
218 pegasus_status.dwControlsAccepted
219 = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN ;
220 pegasus_status.dwWin32ExitCode = 0;
221 pegasus_status.dwServiceSpecificExitCode = 0;
222 pegasus_status.dwCheckPoint = 0;
223 pegasus_status.dwWaitHint = 0;
224
225 pegasus_status_handle = RegisterServiceCtrlHandler("cimserver", cimserver_service_ctrl_handler);
226 if( pegasus_status_handle == (SERVICE_STATUS_HANDLE)0)
227 {
228 Logger::put(Logger::STANDARD_LOG, "CIMServer_Windows", Logger::INFORMATION,
229 mike 1.7 "Error installing service handler");
230 return;
231 }
232
233 // mdday -- I need to replace this hack with registry code
234
235 // this is an ugly hack because we should really be getting this data
236 // out of the registry. We are essentially forcing pegasus to be run
237 // from its build tree. i.e.:
238 // PEGASUS_HOME = binary_exe_path minus "\bin\cimserver.exe"
239
240 // so if my build environment is in "c:\my-programs\pegasus\
241 // I will install the service binary path as "c:\my-programs\pegasus\bin\cimserver.exe"
242 // Therefore I will derive PEGASUS_HOME as "c:\my-programs\pegasus"
243
244 // If I do something wierd and run pegasus from "c:\winnt" then this hack will break
245 // the service will think its running but the CIMServer object will never have been instantiated.
246
247 SC_HANDLE service_handle, sc_manager;
248 if(NULL != (sc_manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)))
249 {
250 mike 1.7 if(NULL != (service_handle = OpenService(sc_manager,
251 "cimserver",
252 SERVICE_ALL_ACCESS)))
253
254 {
255 DWORD bytes_needed = 0;
256 QUERY_SERVICE_CONFIG *svc_config = NULL;
257
258 QueryServiceConfig(service_handle, svc_config, sizeof(svc_config), &bytes_needed);
259 if(bytes_needed > 0)
260 {
261 if(NULL != ( svc_config = (QUERY_SERVICE_CONFIG *) malloc(bytes_needed)))
262 {
263 if(TRUE == QueryServiceConfig(service_handle, svc_config, bytes_needed, &bytes_needed))
264 {
265 Uint32 position;
266 runPath = new String(svc_config->lpBinaryPathName);
267 if(PEG_NOT_FOUND != (position = runPath->reverseFind('\\')))
268 {
269 Uint32 len = runPath->size();
270 runPath->remove(position, len - position);
271 mike 1.7 position = runPath->reverseFind('\\');
272 len = runPath->size();
273 runPath->remove(position, len - position);
274 }
275 }
276 free(svc_config);
277 }
278 }
279 CloseServiceHandle(service_handle);
280 }
281 CloseServiceHandle(sc_manager);
282 }
283
284 status = cimserver_initialization(argc, argv, &specificError);
285 if(status < 0)
286 {
287 pegasus_status.dwCurrentState = SERVICE_STOPPED;
288 pegasus_status.dwCheckPoint = 0;
289 pegasus_status.dwWaitHint = 0;
290 pegasus_status.dwWin32ExitCode = status;
291 pegasus_status.dwServiceSpecificExitCode = specificError;
292 mike 1.7 SetServiceStatus(pegasus_status_handle, &pegasus_status);
293 Logger::put(Logger::STANDARD_LOG, "CIMServer_Windows", Logger::INFORMATION,
294 "Error starting Cim Server");
295 return;
296 }
297
298 pegasus_status.dwCurrentState = SERVICE_RUNNING;
299 pegasus_status.dwCheckPoint = 0;
300 pegasus_status.dwWaitHint = 0;
301
302 if(!SetServiceStatus(pegasus_status_handle, &pegasus_status))
303 {
304 if(server_windows != NULL)
|
305 mike 1.8 server_windows->shutdown();
|
306 mike 1.7 }
307
308 return;
309 }
310
311 VOID WINAPI cimserver_service_ctrl_handler(DWORD opcode)
312 {
313
314 switch(opcode) {
315 case SERVICE_CONTROL_STOP:
316 case SERVICE_CONTROL_SHUTDOWN:
317 if(server_windows != NULL)
|
318 mike 1.8 server_windows->shutdown();
|
319 mike 1.7 pegasus_status.dwCurrentState = SERVICE_STOPPED;
320 pegasus_status.dwCheckPoint = 0;
321 pegasus_status.dwWaitHint = 0;
322 pegasus_status.dwWin32ExitCode = 0;
323 SetServiceStatus(pegasus_status_handle, &pegasus_status);
324 return;
325 break;
326 default:
327 break;
328 }
329 SetServiceStatus(pegasus_status_handle, &pegasus_status);
330 return;
331 }
332
333 DWORD cimserver_initialization(DWORD argc, LPTSTR *argv, DWORD *specificError)
334 {
335
336 return( _beginthread(cimserver_windows_thread, 0, NULL ));
337 }
338
339
340 mike 1.7 Uint32 cimserver_install_nt_service(String &pegasusHome )
341 {
342 SC_HANDLE service_handle, sc_manager;
343 Uint32 ccode = 0;
344 pegasusHome += "\\bin\\cimserver.exe";
345 LPCSTR path_name = pegasusHome.allocateCString() ;
346 if(NULL != (sc_manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)))
347 {
348 if(NULL != (service_handle = CreateService(sc_manager,
349 "cimserver",
350 "Pegasus CIM Object Manager",
351 SERVICE_ALL_ACCESS,
352 SERVICE_WIN32_OWN_PROCESS,
353 SERVICE_DEMAND_START,
354 SERVICE_ERROR_NORMAL,
355 path_name,
356 NULL, NULL, NULL, NULL, NULL)))
357 {
358 ccode = (Uint32)service_handle;
359 }
360 CloseServiceHandle(service_handle);
361 mike 1.7 }
362
363 return(ccode);
364 }
365
366 Uint32 cimserver_remove_nt_service(void)
367 {
368
369 SC_HANDLE service_handle, sc_manager;
370 int ccode = 0;
371 if(NULL != (sc_manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)))
372 {
373 if(NULL != (service_handle = OpenService(sc_manager, "cimserver", DELETE)))
374 {
375 DeleteService(service_handle);
376 CloseServiceHandle(service_handle);
377 ccode = 1;
378 }
379 CloseServiceHandle(sc_manager);
380 }
381 return(ccode);
382 mike 1.7 }
|