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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2