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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2