3 #include /**/ "NT_Naming_Service.h"
5 #if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES)
7 #include /**/ "Naming_Service.h"
8 #include "tao/ORB_Core.h"
10 #include "orbsvcs/Log_Macros.h"
12 #define REGISTRY_KEY_ROOT HKEY_LOCAL_MACHINE
13 #define TAO_REGISTRY_SUBKEY ACE_TEXT ("SOFTWARE\\ACE\\TAO")
14 #define TAO_NAMING_SERVICE_OPTS_NAME ACE_TEXT ("TaoNamingServiceOptions")
15 #define TAO_SERVICE_PARAM_COUNT "TaoServiceParameterCount"
17 AutoFinalizer::AutoFinalizer (TAO_NT_Naming_Service
&service
)
22 AutoFinalizer::~AutoFinalizer ()
24 service_
.report_status (SERVICE_STOPPED
);
25 ORBSVCS_DEBUG ((LM_DEBUG
, "Reported service stoped\n"));
29 TAO_NT_Naming_Service::TAO_NT_Naming_Service ()
37 TAO_NT_Naming_Service::~TAO_NT_Naming_Service ()
41 for (int i
= 0; i
< argc_save_
; i
++)
42 ACE_OS::free (argv_save_
[i
]);
44 ACE_OS::free (argv_save_
);
49 TAO_NT_Naming_Service::handle_control (DWORD control_code
)
51 if (control_code
== SERVICE_CONTROL_SHUTDOWN
52 || control_code
== SERVICE_CONTROL_STOP
)
54 // Just in case any of the following method calls
55 // throws in a way we do not expect.
56 // This instance's destructor will notify the OS.
57 AutoFinalizer
afinalizer (*this);
59 report_status (SERVICE_STOP_PENDING
);
61 // This must be all that needs to be done since this method is executing
62 // in a separate thread from the one running the reactor.
63 // When the reactor is stopped it calls ORB::destroy(), which in turn
64 // calls ORB::shutdown(1) *and* unbinds the ORB from the ORB table.
68 TAO_ORB_Core_instance ()->orb ()->shutdown (1);
70 catch (const CORBA::Exception
&)
72 // What should we do here? Even the log messages are not
73 // showing up, since the thread that runs this is not an ACE
74 // thread. It is allways spawned/controlled by Windows ...
79 ACE_NT_Service::handle_control (control_code
);
84 TAO_NT_Naming_Service::handle_exception (ACE_HANDLE
)
90 TAO_NT_Naming_Service::report_error (const ACE_TCHAR
*format
,
95 ACE_TEXT_FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
,
101 ORBSVCS_DEBUG ((LM_DEBUG
, format
, val
, msg
));
105 TAO_NT_Naming_Service::arg_manip (char *args
, DWORD arglen
, bool query
)
109 // It looks in the NT Registry under
110 // \\HKEY_LOCAL_MACHINE\SOFTWARE\ACE\TAO for the value of
111 // "TaoNamingServiceOptions" for any Naming Service options such as
112 // "-ORBListenEndpoints".
114 // Get/Set Naming Service options from the NT Registry.
116 LONG result
= ACE_TEXT_RegOpenKeyEx (REGISTRY_KEY_ROOT
,
119 query
? KEY_READ
: KEY_WRITE
,
122 DWORD type
= REG_EXPAND_SZ
;
127 if (result
== ERROR_SUCCESS
)
129 result
= ACE_TEXT_RegQueryValueEx (hkey
,
130 TAO_NAMING_SERVICE_OPTS_NAME
,
135 if (result
!= ERROR_SUCCESS
)
137 this->report_error (ACE_TEXT ("Could not query %s, %s\n"),
138 TAO_NAMING_SERVICE_OPTS_NAME
, result
);
143 this->report_error (ACE_TEXT ("No key for %s, %s\n"),
144 TAO_REGISTRY_SUBKEY
, result
);
149 if (result
!= ERROR_SUCCESS
)
151 result
= ACE_TEXT_RegCreateKeyEx (REGISTRY_KEY_ROOT
,
161 DWORD bufSize
= static_cast<DWORD
>(ACE_OS::strlen (args
) + 1);
162 if (result
== ERROR_SUCCESS
)
164 result
= ACE_TEXT_RegSetValueEx (hkey
,
165 TAO_NAMING_SERVICE_OPTS_NAME
,
170 if (result
!= ERROR_SUCCESS
)
172 this->report_error (ACE_TEXT ("Could not set %s, %s\n"),
173 TAO_NAMING_SERVICE_OPTS_NAME
, result
);
178 this->report_error (ACE_TEXT ("Could not create key %s, %s\n"),
179 TAO_REGISTRY_SUBKEY
, result
);
187 TAO_NT_Naming_Service::set_args (const ACE_TCHAR
*args
)
189 char argbuf
[ACE_DEFAULT_ARGV_BUFSIZ
];
192 this->arg_manip (argbuf
, ACE_DEFAULT_ARGV_BUFSIZ
, true);
193 ACE_OS::printf ("%s\n", argbuf
);
197 ACE_OS::strcpy (argbuf
, ACE_TEXT_ALWAYS_CHAR (args
));
198 this->arg_manip (argbuf
, 0, false);
204 TAO_NT_Naming_Service::init (int argc
,
207 // Add options to the args list (if any).
208 char argbuf
[ACE_DEFAULT_ARGV_BUFSIZ
];
209 this->arg_manip (argbuf
, ACE_DEFAULT_ARGV_BUFSIZ
, true);
211 if (ACE_OS::strlen (argbuf
) > 0)
213 ACE_ARGV
args (argbuf
);
214 // Allocate the internal args list to be one bigger than the
215 // args list passed into the function. We use a 'save' list in
216 // case we use a 'destructive' args list processor - this way we
217 // maintain the correct argv and argc for memory freeing
218 // operations in the destructor.
219 argv_save_
= (ACE_TCHAR
**) ACE_OS::malloc (sizeof (ACE_TCHAR
*) * (argc
+ args
.argc ()));
221 // Copy the values into the internal args buffer.
223 for (i
= 0; i
< argc
; i
++)
224 argv_save_
[i
] = ACE_OS::strdup (argv
[i
]);
227 for (i
= argc
; i
< static_cast<int> ((args
.argc () + argc
)); i
++)
228 argv_save_
[i
] = ACE_OS::strdup (args
.argv ()[j
++]);
230 // Set the arg counter.
231 argc_save_
= argc
+ args
.argc ();
245 TAO_NT_Naming_Service::svc ()
247 TAO_Naming_Service naming_service
;
249 if (naming_service
.init (argc_
, argv_
) == -1)
254 // Just in case handle_control does not get the chance
255 // to execute, or is never called by Windows. This instance's
256 // destructor will inform the OS of our demise.
257 AutoFinalizer
afinalizer (*this);
259 ORBSVCS_DEBUG ((LM_INFO
, "Notifying Windows of service startup\n"));
260 report_status (SERVICE_RUNNING
);
262 naming_service
.run ();
264 catch (const CORBA::Exception
& ex
)
266 ORBSVCS_DEBUG ((LM_INFO
, "Exception in service - exiting\n"));
267 ex
._tao_print_exception ("TAO NT Naming Service");
271 ORBSVCS_DEBUG ((LM_INFO
, "Exiting gracefully\n"));
275 #endif /* ACE_WIN32 && !ACE_LACKS_WIN32_SERVICES */