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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2