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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2