(file) Return to cimserver_windows.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / WMIMapper / WMIServer

  1 kumpf 1.1 //%/////////////////////////////////////////////////////////////////////////////
  2           //
  3           // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
  4           // The Open Group, Tivoli Systems
  5           //
  6           // Permission is hereby granted, free of charge, to any person obtaining a copy
  7           // 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           // 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           // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 14           // 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           // 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           // 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 kumpf 1.1 //==============================================================================
 23           //
 24           // Author: Mike Day (mdday@us.ibm.com)
 25           //
 26           // Modified By: Mary Hinton (m.hinton@verizon.net)
 27           //              Sushma Fernandes (sushma_fernandes@hp.com)
 28 kumpf 1.2 //		Yi Zhou, Hewlett-Packard Company (yi_zhou@hp.com)
 29 kumpf 1.1 //
 30           //%/////////////////////////////////////////////////////////////////////////////
 31           
 32           #include <windows.h>
 33           #include <process.h>    /* _beginthread, _endthread */
 34           #include <tchar.h>
 35           #include <direct.h>
 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           DWORD cimserver_initialization(DWORD, LPTSTR *, DWORD *) ;
 50 kumpf 1.1 
 51           void GetOptions(
 52               ConfigManager* cm,
 53               int& argc,
 54               char** argv,
 55               const String& pegasusHome);
 56           
 57           void cim_server_service(int argc, char **argv ) { cimserver_windows_main(argc, argv); exit(0); }
 58           int cimserver_fork( ) { return(0); }
 59           int cimserver_kill( ) { return(0); }
 60           Boolean isCIMServerRunning( ) { return(false); }
 61           
 62 kumpf 1.2 // notify parent process to terminate so user knows that cimserver 
 63           // is ready to serve CIM requests. If this plateform needs to implement 
 64           // this functionality, please see sample implementation in cimserver_unix.cpp
 65           void notify_parent(void)
 66           {
 67           }
 68           
 69 kumpf 1.1 static void __cdecl cimserver_windows_thread(void *parm) 
 70           {
 71           
 72 kumpf 1.2 	// Get options (from command line and from configuration file); this
 73           	// removes corresponding options and their arguments fromt he command
 74           	// line.
 75           
 76           	String pegasusHome;
 77           
 78           	// mdh: need to get the environment for the Windows Service to run 
 79           	const char* tmp = getenv("PEGASUS_HOME");
 80           	if (tmp)
 81           	{
 82           		pegasusHome = tmp;
 83           	}
 84 kumpf 1.1 
 85 kumpf 1.2 	ConfigManager::setPegasusHome(pegasusHome);
 86           	
 87             	ConfigManager* configManager = ConfigManager::getInstance();
 88 kumpf 1.1     int dummy = 0;
 89 kumpf 1.2     //String pegasusHome;
 90 kumpf 1.1 
 91 kumpf 1.2 	try
 92 kumpf 1.1     {
 93 kumpf 1.2 		GetOptions(configManager, dummy, NULL, pegasusHome);
 94 kumpf 1.1     }
 95               catch (Exception&)
 96               {
 97 kumpf 1.2 		exit(1);
 98 kumpf 1.1     }
 99           
100 kumpf 1.2 	//
101 kumpf 1.1     // Check the trace options and set global variable
102               //
103               Boolean pegasusIOTrace = false;
104           
105               if (String::equal(configManager->getCurrentValue("trace"), "true"))
106               {
107                   pegasusIOTrace = true;
108               }
109           
110 kumpf 1.2 	//
111 kumpf 1.1     // Check the log trace options and set global variable
112               //
113               Boolean pegasusIOLog = false;
114           
115               if (String::equal(configManager->getCurrentValue("logtrace"), "true"))
116               {
117                   pegasusIOLog = true;
118               }
119 kumpf 1.2 
120           	// The "SSL" property overrides the enableHttp*Connection properties and
121               // enables only the HTTPS connection.
122           	Boolean enableHttpConnection = String::equal(
123           		configManager->getCurrentValue("enableHttpConnection"), "true");
124           
125           	Boolean enableHttpsConnection = String::equal(
126           		configManager->getCurrentValue("enableHttpsConnection"), "true");
127           
128           	if (!enableHttpConnection && !enableHttpsConnection)
129 kumpf 1.1     {
130 kumpf 1.2         Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::WARNING,
131                       "Neither HTTP nor HTTPS connection is enabled.  "
132                       "CIMServer will not be started.");
133                   cerr << "Neither HTTP nor HTTPS connection is enabled.  "
134                       "CIMServer will not be started." << endl;
135                   exit(1);
136 kumpf 1.1     }
137           
138 kumpf 1.2     // Get the connection port configurations
139 kumpf 1.1 
140 kumpf 1.2     Uint32 portNumberHttps;
141               Uint32 portNumberHttp;
142 kumpf 1.1 
143 kumpf 1.2     if (enableHttpsConnection)
144 kumpf 1.1     {
145 kumpf 1.2         String httpsPort = configManager->getCurrentValue("httpsPort");
146                   CString portString = httpsPort.getCString();
147                   char* end = 0;
148                   Uint32 port = strtol(portString, &end, 10);
149                   assert(end != 0 && *end == '\0');
150           
151                   //
152                   // Look up the WBEM-HTTPS port number
153                   //
154                   portNumberHttps = System::lookupPort(WBEM_HTTPS_SERVICE_NAME, port);
155 kumpf 1.1     }
156 kumpf 1.2 
157               if (enableHttpConnection)
158 kumpf 1.1     {
159 kumpf 1.2         String httpPort = configManager->getCurrentValue("httpPort");
160                   CString portString = httpPort.getCString();
161                   char* end = 0;
162                   Uint32 port = strtol(portString, &end, 10);
163                   assert(end != 0 && *end == '\0');
164           
165                   //
166                   // Look up the WBEM-HTTP port number
167                   //
168                   portNumberHttp = System::lookupPort(WBEM_HTTP_SERVICE_NAME, port);
169 kumpf 1.1     }
170           
171               // Set up the Logger
172               Logger::setHomeDirectory("./logs");
173           
174               // Put server start message to the logger
175               Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
176 kumpf 1.2 	"Start $0 %1 $2 ", 88, PEGASUS_NAME, PEGASUS_VERSION,
177           		(pegasusIOTrace ? " Tracing": " "));
178               // ATTN: Should this really be: ?
179               //Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
180               //            "Started $0 version $1.", PEGASUS_NAME, PEGASUS_VERSION);
181           
182 kumpf 1.1      // try loop to bind the address, and run the server
183               try
184               {
185 kumpf 1.2 		Monitor monitor(true);
186 kumpf 1.1         
187 kumpf 1.2 		CIMServer server(&monitor);
188           		server_windows = &server;
189 kumpf 1.1 
190 kumpf 1.2 		if (enableHttpConnection)
191           		{
192           			server_windows->addAcceptor(false, portNumberHttp, false);
193           			Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
194           						"Listening on HTTP port $0.", portNumberHttp);
195           		}
196           		if (enableHttpsConnection)
197           		{
198           			server_windows->addAcceptor(false, portNumberHttps, true);
199           			Logger::put(Logger::STANDARD_LOG, "CIMServer", Logger::INFORMATION,
200           						"Listening on HTTPS port $0.", portNumberHttps);
201           		}
202           
203           		server_windows->bind();
204 kumpf 1.1 
205 kumpf 1.2 		while(!server_windows->terminated())
206           		{
207           			server_windows->runForever();
208           		}
209 kumpf 1.1     }
210               catch(Exception& e)
211               {
212 kumpf 1.2 		PEGASUS_STD(cerr) << "Error: " << e.getMessage() << PEGASUS_STD(endl);
213 kumpf 1.1     }
214           
215               _endthreadex(NULL);
216           }
217           
218           
219           /////////////////////////////////////////////////////////////////
220           //  Windows NT Service Control Code 
221           /////////////////////////////////////////////////////////////////
222 kumpf 1.2 VOID WINAPI  cimserver_windows_main(int argc, char **argv) 
223           {
224           	int ccode;
225           	SERVICE_TABLE_ENTRY dispatch_table[] = 
226           	{
227           		{"wmiserver", cimserver_service_start},
228           		{NULL, NULL}
229           	};
230 kumpf 1.1 
231 kumpf 1.2 	/* let everyone know we are running (or trying to run) as an NT service */
232           	if(!(ccode =  StartServiceCtrlDispatcher(dispatch_table))) 
233           	{
234           		ccode = GetLastError();
235           		// Put server start message to the logger
236           		Logger::put(Logger::STANDARD_LOG, "CIMServer_Windows", Logger::INFORMATION,
237           			"Started as a Windows Service");
238           	}
239 kumpf 1.1 
240 kumpf 1.2 	return;
241 kumpf 1.1 }
242           
243           /////////////////////////////////////////////////////////////////
244           //
245           // called by the NT service control manager to start the SLP service
246           //
247           /////////////////////////////////////////////////////////////////
248           VOID WINAPI cimserver_service_start(DWORD argc, LPTSTR *argv) 
249           {
250           
251 kumpf 1.2 	DWORD status;
252           	DWORD specificError;
253           	pegasus_status.dwServiceType = SERVICE_WIN32;
254           	pegasus_status.dwCurrentState = SERVICE_START_PENDING;
255           	pegasus_status.dwControlsAccepted 
256           		= SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN ;
257           	pegasus_status.dwWin32ExitCode = 0;
258           	pegasus_status.dwServiceSpecificExitCode = 0;
259           	pegasus_status.dwCheckPoint = 0;
260           	pegasus_status.dwWaitHint = 0;
261           	pegasus_status_handle = RegisterServiceCtrlHandler("wmiserver", cimserver_service_ctrl_handler);
262           
263           	if(pegasus_status_handle == (SERVICE_STATUS_HANDLE)0)
264           	{
265           		Logger::put(Logger::STANDARD_LOG, "CIMServer_Windows", Logger::INFORMATION,
266           			"Error installing service handler");
267           		return;
268           	}
269 kumpf 1.1 
270 kumpf 1.2 	// mdday -- I need to replace this hack with registry code
271 kumpf 1.1 
272 kumpf 1.2 	// this is an ugly hack because we should really be getting this data 
273           	// out of the registry. We are essentially forcing pegasus to be run 
274           	// from its build tree. i.e.: 
275           	// PEGASUS_HOME = binary_exe_path minus  "\bin\cimserver.exe"
276           
277           	// so if my build environment is in "c:\my-programs\pegasus\ 
278           	// I will install the service binary path as "c:\my-programs\pegasus\bin\cimserver.exe"
279           	// Therefore I will derive PEGASUS_HOME as "c:\my-programs\pegasus"
280 kumpf 1.1   
281 kumpf 1.2 	// If I do something wierd and run pegasus from "c:\winnt" then this hack will break 
282           	// the service will think its running but the CIMServer object will never have been instantiated. 
283 kumpf 1.1  
284 kumpf 1.2 	SC_HANDLE service_handle, sc_manager;
285           	if(NULL != (sc_manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS))) 
286           	{
287           		if(NULL != (service_handle = OpenService(sc_manager, 
288           												 "wmiserver",
289           												 SERVICE_ALL_ACCESS)))
290 kumpf 1.1 
291 kumpf 1.2 		{
292           			DWORD bytes_needed = 0;
293           			QUERY_SERVICE_CONFIG *svc_config = NULL;
294 kumpf 1.1 	  
295 kumpf 1.2 			QueryServiceConfig(service_handle, svc_config, sizeof(svc_config), &bytes_needed);
296           			if(bytes_needed > 0) 
297 kumpf 1.1 			{
298 kumpf 1.2 				if(NULL != ( svc_config = (QUERY_SERVICE_CONFIG *) malloc(bytes_needed))) 
299           				{
300           					if(TRUE == QueryServiceConfig(service_handle, svc_config, bytes_needed, &bytes_needed)) 
301           					{
302           						Uint32 position;
303           						runPath = new String(svc_config->lpBinaryPathName);
304           						if(PEG_NOT_FOUND != (position = runPath->reverseFind('\\'))) 
305           						{
306           							Uint32 len = runPath->size();
307           							runPath->remove(position, len - position);
308           							position = runPath->reverseFind('\\');
309           							len = runPath->size();
310           							runPath->remove(position, len - position);
311           						}
312           					}
313           
314           					free(svc_config);
315           				}
316 kumpf 1.1 			}
317 kumpf 1.2 
318           			CloseServiceHandle(service_handle);
319 kumpf 1.1 		}
320 kumpf 1.2 
321           		CloseServiceHandle(sc_manager);
322 kumpf 1.1 	}
323           
324 kumpf 1.2 	status = cimserver_initialization(argc, argv, &specificError);
325           	if(status < 0) 
326 kumpf 1.1     {
327 kumpf 1.2 		pegasus_status.dwCurrentState = SERVICE_STOPPED;
328           		pegasus_status.dwCheckPoint = 0;
329           		pegasus_status.dwWaitHint = 0;
330           		pegasus_status.dwWin32ExitCode = status;
331           		pegasus_status.dwServiceSpecificExitCode = specificError;
332           		SetServiceStatus(pegasus_status_handle, &pegasus_status);
333           		Logger::put(Logger::STANDARD_LOG, "CIMServer_Windows", Logger::INFORMATION,
334           			"Error starting Cim Server");
335           		return;
336           	}
337 kumpf 1.1 
338 kumpf 1.2 	pegasus_status.dwCurrentState = SERVICE_RUNNING;
339           	pegasus_status.dwCheckPoint = 0;
340           	pegasus_status.dwWaitHint = 0;
341 kumpf 1.1 
342 kumpf 1.2 	if(!SetServiceStatus(pegasus_status_handle, &pegasus_status)) 
343           	{
344           		if(server_windows != NULL)
345           			server_windows->shutdown();
346           	}
347 kumpf 1.1 
348 kumpf 1.2 	return;
349 kumpf 1.1 }
350           
351 kumpf 1.2 /////////////////////////////////////////////////////////////////
352           //
353           /////////////////////////////////////////////////////////////////
354 kumpf 1.1 VOID WINAPI cimserver_service_ctrl_handler(DWORD opcode) 
355           {
356 kumpf 1.2 	switch(opcode) 
357           	{
358           		case SERVICE_CONTROL_STOP:
359           		case SERVICE_CONTROL_SHUTDOWN:
360           			if(server_windows != NULL)
361           				server_windows->shutdown();
362           			pegasus_status.dwCurrentState = SERVICE_STOPPED;
363           			pegasus_status.dwCheckPoint = 0;
364           			pegasus_status.dwWaitHint = 0;
365           			pegasus_status.dwWin32ExitCode = 0;
366           			SetServiceStatus(pegasus_status_handle, &pegasus_status);
367           			return;
368           			break;
369           		default:
370           			break;
371           	}
372           	
373           	SetServiceStatus(pegasus_status_handle, &pegasus_status);
374 kumpf 1.1 
375 kumpf 1.2 	return;
376 kumpf 1.1 }
377           
378 kumpf 1.2 /////////////////////////////////////////////////////////////////
379           //
380           /////////////////////////////////////////////////////////////////
381 kumpf 1.1 DWORD cimserver_initialization(DWORD argc, LPTSTR *argv, DWORD *specificError) 
382           {
383 kumpf 1.2 	return( _beginthread(cimserver_windows_thread, 0, NULL ));
384 kumpf 1.1 }
385            
386 kumpf 1.2 /////////////////////////////////////////////////////////////////
387           //
388           /////////////////////////////////////////////////////////////////
389           Uint32 cimserver_install_nt_service(String &pegasusHome) 
390           {
391           	SC_HANDLE service_handle, sc_manager;
392           	Uint32 ccode = 0;
393           	
394           	pegasusHome.append("\\bin\\wmiserver.exe");
395 kumpf 1.1 
396 kumpf 1.2 	CString pegHome = pegasusHome.getCString() ;
397           	LPCSTR path_name = (const char*) pegHome;
398           		
399           	if(NULL != (sc_manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS))) 
400               {
401           		if(NULL != (service_handle = CreateService(sc_manager, 
402           												   "wmiserver",
403           												   "Pegasus WMI Mapper",
404           												   SERVICE_ALL_ACCESS,
405           												   SERVICE_WIN32_OWN_PROCESS,
406           												   SERVICE_DEMAND_START,
407           												   SERVICE_ERROR_NORMAL, 
408           												   path_name,
409           												   NULL, 
410           												   NULL, 
411           												   NULL, 
412           												   NULL, 
413           												   NULL))) 
414           		{
415           			ccode = (Uint32)service_handle;
416           		}
417 kumpf 1.2 		
418           		CloseServiceHandle(service_handle);
419 kumpf 1.1 	}
420             
421 kumpf 1.2 	return(ccode);
422 kumpf 1.1 }
423           
424 kumpf 1.2 /////////////////////////////////////////////////////////////////
425           //
426           /////////////////////////////////////////////////////////////////
427 kumpf 1.1 Uint32 cimserver_remove_nt_service(void) 
428           {
429           
430 kumpf 1.2 	SC_HANDLE service_handle, sc_manager;
431           	int ccode = 0;
432           
433           	if(NULL != (sc_manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS))) 
434 kumpf 1.1 	{
435 kumpf 1.2 		if(NULL != (service_handle = OpenService(sc_manager, "wmiserver", DELETE))) 
436           		{
437           			DeleteService(service_handle);
438           			CloseServiceHandle(service_handle);
439           			ccode = 1;
440           		} 
441           		
442           		CloseServiceHandle(sc_manager);
443 kumpf 1.1 	} 
444 kumpf 1.2 	
445           	return(ccode);
446 kumpf 1.1 }

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2