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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2