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 // Modified By:
26 //
27 //%/////////////////////////////////////////////////////////////////////////////
28
29 #include <windows.h>
30 #include <process.h> /* _beginthread, _endthread */
31 #include <tchar.h>
32 #include <direct.h>
33
34
35 PEGASUS_USING_PEGASUS;
36 PEGASUS_USING_STD;
37
38 static DWORD dieNow = 0;
39 String *runPath;
40 CIMServer *server_windows;
41 static SERVICE_STATUS pegasus_status;
42 static SERVICE_STATUS_HANDLE pegasus_status_handle;
43 mike 1.7
44 VOID WINAPI cimserver_windows_main(int argc, char **argv) ;
45 VOID WINAPI cimserver_service_start(DWORD, LPTSTR *);
46 VOID WINAPI cimserver_service_ctrl_handler(DWORD );
47 DWORD cimserver_initialization(DWORD, LPTSTR *, DWORD *) ;
48
49 void GetOptions(
|
50 mike 1.8 ConfigManager* cm,
|
51 mike 1.7 int& argc,
52 char** argv,
|
53 mike 1.8 const String& pegasusHome);
|
54 mike 1.7
55 void cim_server_service(int argc, char **argv ) { cimserver_windows_main(argc, argv); exit(0); }
56 int cimserver_fork( ) { return(0); }
57
58 static void __cdecl cimserver_windows_thread(void *parm)
59 {
60
61 // Get options (from command line and from configuration file); this
62 // removes corresponding options and their arguments fromt he command
63 // line.
64
|
65 mike 1.8 PEGASUS_TRACE;
66 ConfigManager* configManager = ConfigManager::getInstance();
|
67 mike 1.7 int dummy = 0;
68 String pegasusHome;
|
69 mike 1.8
70 PEGASUS_TRACE;
|
71 mike 1.7 try
72 {
|
73 mike 1.8 PEGASUS_TRACE;
74 GetOptions(configManager, dummy, NULL, pegasusHome);
75 PEGASUS_TRACE;
|
76 mike 1.7 }
77 catch (Exception&)
78 {
79 exit(1);
80 }
|
81 mike 1.8 PEGASUS_TRACE;
|
82 mike 1.7
|
83 mike 1.8 //
|
84 mike 1.7 // Check the trace options and set global variable
|
85 mike 1.8 //
|
86 mike 1.7 Boolean pegasusIOTrace = false;
|
87 mike 1.8
88 if (String::equal(configManager->getCurrentValue("trace"), "true"))
|
89 mike 1.7 {
|
90 mike 1.8 Handler::setMessageTrace(true);
91 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 Handler::setMessageLogTrace(true);
102 pegasusIOLog = true;
|
103 mike 1.7 }
|
104 mike 1.8 Boolean useSSL = false;
105
106 if (String::equal(configManager->getCurrentValue("SSL"), "true"))
107 {
108 useSSL = true;
109 }
110
111 PEGASUS_TRACE;
|
112 mike 1.7
113 // Grab the port otpion:
114
|
115 mike 1.8 String portOption = configManager->getCurrentValue("port");
|
116 mike 1.7 char* address = portOption.allocateCString();
117
|
118 mike 1.8 PEGASUS_TRACE;
|
119 mike 1.7 // Set up the Logger
120 Logger::setHomeDirectory("./logs");
121
122 // Put server start message to the logger
123 Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
124 "Start $0 %1 port $2 $3 ", 88, PEGASUS_NAME, PEGASUS_VERSION,
125 address, (pegasusIOTrace ? " Tracing": " "));
126 // try loop to bind the address, and run the server
127 try
128 {
|
129 mike 1.8 PEGASUS_TRACE;
130 Monitor monitor;
|
131 mike 1.7
|
132 mike 1.8 CIMServer server(&monitor, *runPath, useSSL);
|
133 mike 1.7 server_windows = &server;
|
134 mike 1.8
135 char* end = 0;
136 long portNumber = strtol(address, &end, 10);
137 assert(end != 0 && *end == '\0');
138 server.bind(portNumber);
139 server_windows->bind(portNumber);
140
|
141 mike 1.7 delete [] address;
142 server_windows->runForever();
|
143 mike 1.8 PEGASUS_TRACE;
|
144 mike 1.7 }
145 catch(Exception& e)
146 {
147 PEGASUS_STD(cerr) << "Error: " << e.getMessage() << PEGASUS_STD(endl);
148 }
149
|
150 mike 1.8 PEGASUS_TRACE;
|
151 mike 1.7 _endthreadex(NULL);
152 }
153
154
155 /////////////////////////////////////////////////////////////////
156 // Windows NT Service Control Code
157 /////////////////////////////////////////////////////////////////
158
159
160
161
162 VOID WINAPI cimserver_windows_main(int argc, char **argv)
163 {
|
164 mike 1.8 PEGASUS_TRACE;
|
165 mike 1.7 int ccode;
166 SERVICE_TABLE_ENTRY dispatch_table[] =
167 {
168 {"cimserver", cimserver_service_start},
169 {NULL, NULL}
170 };
171
172 /* let everyone know we are running (or trying to run) as an NT service */
173 if(!(ccode = StartServiceCtrlDispatcher(dispatch_table)))
174 {
175 ccode = GetLastError();
176 // Put server start message to the logger
177 Logger::put(Logger::STANDARD_LOG, "CIMServer_Windows", Logger::INFORMATION,
178 "Started as a Windows Service");
179 }
180 return;
181 }
182
183 /////////////////////////////////////////////////////////////////
184 //
185 // called by the NT service control manager to start the SLP service
186 mike 1.7 //
187 /////////////////////////////////////////////////////////////////
188
189 VOID WINAPI cimserver_service_start(DWORD argc, LPTSTR *argv)
190 {
191
192 DWORD status;
193 DWORD specificError;
194 pegasus_status.dwServiceType = SERVICE_WIN32;
195 pegasus_status.dwCurrentState = SERVICE_START_PENDING;
196 pegasus_status.dwControlsAccepted
197 = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN ;
198 pegasus_status.dwWin32ExitCode = 0;
199 pegasus_status.dwServiceSpecificExitCode = 0;
200 pegasus_status.dwCheckPoint = 0;
201 pegasus_status.dwWaitHint = 0;
202
203 pegasus_status_handle = RegisterServiceCtrlHandler("cimserver", cimserver_service_ctrl_handler);
204 if( pegasus_status_handle == (SERVICE_STATUS_HANDLE)0)
205 {
206 Logger::put(Logger::STANDARD_LOG, "CIMServer_Windows", Logger::INFORMATION,
207 mike 1.7 "Error installing service handler");
208 return;
209 }
210
211 // mdday -- I need to replace this hack with registry code
212
213 // this is an ugly hack because we should really be getting this data
214 // out of the registry. We are essentially forcing pegasus to be run
215 // from its build tree. i.e.:
216 // PEGASUS_HOME = binary_exe_path minus "\bin\cimserver.exe"
217
218 // so if my build environment is in "c:\my-programs\pegasus\
219 // I will install the service binary path as "c:\my-programs\pegasus\bin\cimserver.exe"
220 // Therefore I will derive PEGASUS_HOME as "c:\my-programs\pegasus"
221
222 // If I do something wierd and run pegasus from "c:\winnt" then this hack will break
223 // the service will think its running but the CIMServer object will never have been instantiated.
224
225 SC_HANDLE service_handle, sc_manager;
226 if(NULL != (sc_manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)))
227 {
228 mike 1.7 if(NULL != (service_handle = OpenService(sc_manager,
229 "cimserver",
230 SERVICE_ALL_ACCESS)))
231
232 {
233 DWORD bytes_needed = 0;
234 QUERY_SERVICE_CONFIG *svc_config = NULL;
235
236 QueryServiceConfig(service_handle, svc_config, sizeof(svc_config), &bytes_needed);
237 if(bytes_needed > 0)
238 {
239 if(NULL != ( svc_config = (QUERY_SERVICE_CONFIG *) malloc(bytes_needed)))
240 {
241 if(TRUE == QueryServiceConfig(service_handle, svc_config, bytes_needed, &bytes_needed))
242 {
243 Uint32 position;
244 runPath = new String(svc_config->lpBinaryPathName);
245 if(PEG_NOT_FOUND != (position = runPath->reverseFind('\\')))
246 {
247 Uint32 len = runPath->size();
248 runPath->remove(position, len - position);
249 mike 1.7 position = runPath->reverseFind('\\');
250 len = runPath->size();
251 runPath->remove(position, len - position);
252 }
253 }
254 free(svc_config);
255 }
256 }
257 CloseServiceHandle(service_handle);
258 }
259 CloseServiceHandle(sc_manager);
260 }
261
262 status = cimserver_initialization(argc, argv, &specificError);
263 if(status < 0)
264 {
265 pegasus_status.dwCurrentState = SERVICE_STOPPED;
266 pegasus_status.dwCheckPoint = 0;
267 pegasus_status.dwWaitHint = 0;
268 pegasus_status.dwWin32ExitCode = status;
269 pegasus_status.dwServiceSpecificExitCode = specificError;
270 mike 1.7 SetServiceStatus(pegasus_status_handle, &pegasus_status);
271 Logger::put(Logger::STANDARD_LOG, "CIMServer_Windows", Logger::INFORMATION,
272 "Error starting Cim Server");
273 return;
274 }
275
276 pegasus_status.dwCurrentState = SERVICE_RUNNING;
277 pegasus_status.dwCheckPoint = 0;
278 pegasus_status.dwWaitHint = 0;
279
280 if(!SetServiceStatus(pegasus_status_handle, &pegasus_status))
281 {
282 if(server_windows != NULL)
|
283 mike 1.8 server_windows->shutdown();
|
284 mike 1.7 }
285
286 return;
287 }
288
289 VOID WINAPI cimserver_service_ctrl_handler(DWORD opcode)
290 {
291
292 switch(opcode) {
293 case SERVICE_CONTROL_STOP:
294 case SERVICE_CONTROL_SHUTDOWN:
295 if(server_windows != NULL)
|
296 mike 1.8 server_windows->shutdown();
|
297 mike 1.7 pegasus_status.dwCurrentState = SERVICE_STOPPED;
298 pegasus_status.dwCheckPoint = 0;
299 pegasus_status.dwWaitHint = 0;
300 pegasus_status.dwWin32ExitCode = 0;
301 SetServiceStatus(pegasus_status_handle, &pegasus_status);
302 return;
303 break;
304 default:
305 break;
306 }
307 SetServiceStatus(pegasus_status_handle, &pegasus_status);
308 return;
309 }
310
311 DWORD cimserver_initialization(DWORD argc, LPTSTR *argv, DWORD *specificError)
312 {
313
314 return( _beginthread(cimserver_windows_thread, 0, NULL ));
315 }
316
317
318 mike 1.7 Uint32 cimserver_install_nt_service(String &pegasusHome )
319 {
320 SC_HANDLE service_handle, sc_manager;
321 Uint32 ccode = 0;
322 pegasusHome += "\\bin\\cimserver.exe";
323 LPCSTR path_name = pegasusHome.allocateCString() ;
324 if(NULL != (sc_manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)))
325 {
326 if(NULL != (service_handle = CreateService(sc_manager,
327 "cimserver",
328 "Pegasus CIM Object Manager",
329 SERVICE_ALL_ACCESS,
330 SERVICE_WIN32_OWN_PROCESS,
331 SERVICE_DEMAND_START,
332 SERVICE_ERROR_NORMAL,
333 path_name,
334 NULL, NULL, NULL, NULL, NULL)))
335 {
336 ccode = (Uint32)service_handle;
337 }
338 CloseServiceHandle(service_handle);
339 mike 1.7 }
340
341 return(ccode);
342 }
343
344 Uint32 cimserver_remove_nt_service(void)
345 {
346
347 SC_HANDLE service_handle, sc_manager;
348 int ccode = 0;
349 if(NULL != (sc_manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS)))
350 {
351 if(NULL != (service_handle = OpenService(sc_manager, "cimserver", DELETE)))
352 {
353 DeleteService(service_handle);
354 CloseServiceHandle(service_handle);
355 ccode = 1;
356 }
357 CloseServiceHandle(sc_manager);
358 }
359 return(ccode);
360 mike 1.7 }
|