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