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