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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2