1 #include "ace/Registry.h"
3 #if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_REGISTRY)
5 # include "ace/os_include/os_netdb.h"
6 # include "ace/OS_NS_unistd.h"
8 // Funky macro to deal with strange error passing semantics
9 // of Win32 Reg*() functions
10 #define ACE_REGISTRY_CALL_RETURN(X) \
12 if (X != ERROR_SUCCESS) \
22 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
24 ACE_TCHAR
const ACE_Registry::STRING_SEPARATOR
[] = ACE_TEXT ("\\");
27 ACE_Registry::Name_Component::operator== (const Name_Component
&rhs
) const
30 rhs
.id_
== this->id_
&&
31 rhs
.kind_
== this->kind_
;
35 ACE_Registry::Name_Component::operator!= (const Name_Component
&rhs
) const
37 return !this->operator== (rhs
);
40 // Simple binding constructor
41 ACE_Registry::Binding::Binding ()
48 // Binding constructor
50 ACE_Registry::Binding::Binding (const Name
&name
,
52 : name_ (ACE_Registry::make_string (name
)),
58 // Binding constructor
60 ACE_Registry::Binding::Binding (const ACE_TString
&name
,
69 ACE_Registry::Binding::operator== (const Binding
&rhs
) const
72 rhs
.name_
== this->name_
&&
73 rhs
.type_
== this->type_
;
77 ACE_Registry::Binding::operator!= (const Binding
&rhs
) const
79 return !this->operator== (rhs
);
85 ACE_Registry::Binding::name (Name
&name
)
87 name
= ACE_Registry::make_name (this->name_
);
94 ACE_Registry::Binding::name (ACE_TString
&name
)
103 ACE_Registry::Binding::name (void)
110 ACE_Registry::Binding_Type
111 ACE_Registry::Binding::type (void)
117 // Simple object constructor
118 ACE_Registry::Object::Object (void *data
,
127 // Object accessors and set methods
129 ACE_Registry::Object::data (void *data
)
136 ACE_Registry::Object::data (void) const
143 ACE_Registry::Object::size (u_long size
)
150 ACE_Registry::Object::size (void) const
157 ACE_Registry::Object::type (u_long type
)
164 ACE_Registry::Object::type (void) const
170 // Simple context constructor
171 ACE_Registry::Naming_Context::Naming_Context (void)
173 parent_key_ ((HKEY
) 0),
179 // Context constructor
180 ACE_Registry::Naming_Context::Naming_Context (const HKEY
&key
)
182 parent_key_ ((HKEY
) 0),
188 ACE_Registry::Naming_Context::Naming_Context (const Naming_Context
&rhs
)
190 parent_key_ (rhs
.parent_key_
),
193 // This is incorrect.
194 // Rather than copying key, we should call ::DuplicateHandle()
195 // But since this is private (and not used), I don't care much
199 const ACE_Registry::Naming_Context
&
200 ACE_Registry::Naming_Context::operator= (const Naming_Context
&rhs
)
210 ACE_Registry::Naming_Context::~Naming_Context ()
216 // Insert <object> with <name> into <this> context
219 ACE_Registry::Naming_Context::bind_new (const Name
&name
,
220 const Object
&object
)
222 return this->bind_new (ACE_Registry::make_string (name
), object
);
226 // Insert <object> with <name> into <this> context
229 ACE_Registry::Naming_Context::bind_new (const ACE_TString
&name
,
230 const Object
&object
)
234 long result
= this->resolve (name
, temp
);
240 result
= this->bind (name
, object
);
245 // Insert or update <object> with <name> into <this> context
248 ACE_Registry::Naming_Context::bind (const Name
&name
,
249 const Object
&object
)
251 return this->bind (ACE_Registry::make_string (name
), object
);
255 // Insert or update <object> with <name> into <this> context
258 ACE_Registry::Naming_Context::bind (const ACE_TString
&name
,
259 const Object
&object
)
261 long result
= ACE_TEXT_RegSetValueEx (this->key_
,
265 (const BYTE
*) object
.data (),
267 ACE_REGISTRY_CALL_RETURN (result
);
271 // Update <object> with <name> in <this> context
274 ACE_Registry::Naming_Context::rebind (const Name
&name
,
275 const Object
&new_object
)
277 return this->rebind (ACE_Registry::make_string (name
), new_object
);
281 // Update <object> with <name> in <this> context
284 ACE_Registry::Naming_Context::rebind (const ACE_TString
&name
,
285 const Object
&new_object
)
288 // find the old one first
289 long result
= this->resolve (name
, old_object
);
291 // no need to delete first
292 result
= this->bind (name
, new_object
);
297 // Find <object> with <name> in <this> context
300 ACE_Registry::Naming_Context::resolve (const Name
&name
,
303 return this->resolve (ACE_Registry::make_string (name
), object
);
307 // Find <object> with <name> in <this> context
310 ACE_Registry::Naming_Context::resolve (const ACE_TString
&name
,
315 void *data
= object
.data ();
316 u_long size
= object
.size ();
318 long result
= ACE_TEXT_RegQueryValueEx (this->key_
,
324 if (result
== ERROR_SUCCESS
)
326 // Reset object state
327 // No need to set object.data()
332 ACE_REGISTRY_CALL_RETURN (result
);
336 // Remove object with <name> in <this> context
339 ACE_Registry::Naming_Context::unbind (const Name
&name
)
341 return this->unbind (ACE_Registry::make_string (name
));
345 // Remove object with <name> in <this> context
348 ACE_Registry::Naming_Context::unbind (const ACE_TString
&name
)
350 long result
= ACE_TEXT_RegDeleteValue (this->key_
,
353 ACE_REGISTRY_CALL_RETURN (result
);
357 // Create new <naming_context> relative to <this> context
358 // This method may not mean a lot in this implementation
360 ACE_Registry::Naming_Context::new_context (Naming_Context
&naming_context
)
362 // Make sure that we reset the state and close keys
363 return naming_context
.close ();
367 // Insert <naming_context> with <name> relative to <this> context
370 ACE_Registry::Naming_Context::bind_new_context (const Name
&name
,
371 Naming_Context
&naming_context
,
373 u_long security_access
,
374 LPSECURITY_ATTRIBUTES security_attributes
)
376 return this->bind_new_context (ACE_Registry::make_string (name
),
380 security_attributes
);
384 // Insert <naming_context> with <name> relative to <this> context
387 ACE_Registry::Naming_Context::bind_new_context (const ACE_TString
&name
,
388 Naming_Context
&naming_context
,
390 u_long security_access
,
391 LPSECURITY_ATTRIBUTES security_attributes
)
395 long result
= ACE_TEXT_RegCreateKeyEx (this->key_
,
402 &naming_context
.key_
,
404 if (result
== ERROR_SUCCESS
)
405 // If create succeeds
407 if (reason
== REG_CREATED_NEW_KEY
)
408 // If new key: success
410 // Set the correct parent
411 naming_context
.parent (this->key_
);
412 // Set the correct name
413 naming_context
.name (name
);
416 // reason == REG_OPENED_EXISTING_KEY
417 // Failed to make new key
419 // reset result to failure
421 // Close the key first
422 ::RegCloseKey (naming_context
.key_
);
424 naming_context
.key_
= (HKEY
) 0;
428 ACE_REGISTRY_CALL_RETURN (result
);
432 // Insert or update <naming_context> with <name> relative to <this> context
435 ACE_Registry::Naming_Context::bind_context (const Name
&name
,
436 /* const */ Naming_Context
&naming_context
,
438 u_long security_access
,
439 LPSECURITY_ATTRIBUTES security_attributes
)
441 return this->bind_context (ACE_Registry::make_string (name
),
445 security_attributes
);
449 // Insert or update <naming_context> with <name> relative to <this> context
452 ACE_Registry::Naming_Context::bind_context (const ACE_TString
&name
,
453 /* const */ Naming_Context
&naming_context
,
455 u_long security_access
,
456 LPSECURITY_ATTRIBUTES security_attributes
)
460 long result
= ACE_TEXT_RegCreateKeyEx (this->key_
,
467 &naming_context
.key_
,
469 if (result
== ERROR_SUCCESS
)
471 // Set the correct parent
472 naming_context
.parent (this->key_
);
473 // Set the correct name
474 naming_context
.name (name
);
477 ACE_REGISTRY_CALL_RETURN (result
);
481 // Rename <naming_context> to <name>
484 ACE_Registry::Naming_Context::rebind_context (const Name
&name
,
485 /* const */ Naming_Context
&new_naming_context
)
487 return this->rebind_context (ACE_Registry::make_string (name
),
492 // Rename <naming_context> to <name>
495 ACE_Registry::Naming_Context::rebind_context (const ACE_TString
&name
,
496 /* const */ Naming_Context
&new_naming_context
)
498 Naming_Context old_naming_context
;
499 // find the old one first
500 long result
= this->resolve_context (name
,
504 // naming_context is found: delete entry
505 result
= this->unbind_context (name
);
508 // successful deletion; rebind
509 // beware of race conditions here
510 // (lets resolve this later)
511 result
= this->bind_new_context (name
, new_naming_context
);
518 // Remove naming_context with <name> from <this> context
521 ACE_Registry::Naming_Context::unbind_context (const Name
&name
)
523 return this->unbind_context (ACE_Registry::make_string (name
));
527 // Remove naming_context with <name> from <this> context
530 ACE_Registry::Naming_Context::unbind_context (const ACE_TString
&name
)
532 long result
= ACE_TEXT_RegDeleteKey (this->key_
,
535 ACE_REGISTRY_CALL_RETURN (result
);
539 // Find <naming_context> with <name> in <this> context
542 ACE_Registry::Naming_Context::resolve_context (const Name
&name
,
543 Naming_Context
&naming_context
,
544 u_long security_access
)
546 return this->resolve_context (ACE_Registry::make_string (name
),
552 // Find <naming_context> with <name> in <this> context
555 ACE_Registry::Naming_Context::resolve_context (const ACE_TString
&name
,
556 Naming_Context
&naming_context
,
557 u_long security_access
)
559 long result
= ACE_TEXT_RegOpenKeyEx (this->key_
,
563 &naming_context
.key_
);
564 if (result
== ERROR_SUCCESS
)
566 // set the correct parent
567 naming_context
.parent (this->key_
);
568 // set the correct name
569 naming_context
.name (name
);
572 ACE_REGISTRY_CALL_RETURN (result
);
576 // Same as unbind_context() with <this> as naming_context
578 ACE_Registry::Naming_Context::destroy (void)
580 // hopefully the parent_key_ is still open
581 long result
= ACE_TEXT_RegDeleteKey (this->parent_key_
,
582 this->name_
.c_str ());
584 ACE_REGISTRY_CALL_RETURN (result
);
588 // Sync content of context to disk
590 ACE_Registry::Naming_Context::flush (void)
592 long result
= ::RegFlushKey (this->key_
);
593 ACE_REGISTRY_CALL_RETURN (result
);
597 // Close the handle of the context
599 ACE_Registry::Naming_Context::close (void)
601 long result
= this->key_
? ::RegCloseKey (this->key_
) : ERROR_SUCCESS
;
602 ACE_REGISTRY_CALL_RETURN (result
);
606 // Convert a <name> to a <string>
608 ACE_Registry::make_string (const Name
&const_name
)
611 Name
&name
= const_cast<Name
&> (const_name
);
613 // Iterator through the components of name
614 for (Name::iterator iterator
= name
.begin ();
615 iterator
!= name
.end ();
618 if (iterator
!= name
.begin ())
619 // If this is not the first component, we will add separators
620 string
+= STRING_SEPARATOR
;
621 const Name_Component
&component
= *iterator
;
623 string
+= component
.id_
;
630 // Convert a <string> to a <name>
632 ACE_Registry::make_name (const ACE_TString
&string
)
634 ACE_TString::size_type new_position
= 0;
635 ACE_TString::size_type last_position
= 0;
638 // Rememeber: NPOS is -1
639 while (new_position
!= ACE_TString::npos
)
641 Name_Component component
;
642 // Find the separator
643 new_position
= string
.find (STRING_SEPARATOR
, new_position
);
644 if (new_position
!= ACE_TString::npos
)
645 // If we have not gone past the end
648 component
.id_
= string
.substr (last_position
,
649 new_position
- last_position
);
650 // Skip past the seperator
652 ACE_OS::strlen (STRING_SEPARATOR
);
656 // Get the last substring
657 component
.id_
= string
.substr (last_position
);
660 last_position
= new_position
;
661 // Insert component into name
662 name
.insert (component
);
671 ACE_Registry::Naming_Context::key (HKEY key
)
679 ACE_Registry::Naming_Context::key (void)
687 ACE_Registry::Naming_Context::parent (HKEY parent
)
689 this->parent_key_
= parent
;
695 ACE_Registry::Naming_Context::parent (void)
697 return this->parent_key_
;
704 ACE_Registry::Naming_Context::name (const Name
&name
)
706 this->name_
= ACE_Registry::make_string (name
);
713 ACE_Registry::Naming_Context::name (Name
&name
)
715 name
= ACE_Registry::make_name (this->name_
);
722 ACE_Registry::Naming_Context::name (const ACE_TString
&name
)
731 ACE_Registry::Naming_Context::name (void)
740 ACE_Registry::Naming_Context::name (ACE_TString
&name
)
746 static const ACE_Registry::Binding_List ace_binding_empty_list
;
748 // listing function: iterator creator
749 // This is useful when there are many objects and contexts
750 // in <this> context and you only want to look at a few entries
753 ACE_Registry::Naming_Context::list (u_long how_many
,
755 Binding_Iterator
&iter
)
757 // Make sure that the list is empty
758 list
= ace_binding_empty_list
;
760 // Correctly initalize the iterator
763 // Make sure that the iterator uses <this> naming context
764 iter
.naming_context (*this);
766 // Start iterations from the objects
767 iter
.current_enumeration (iter
.object_iteration_
);
769 // Get the next <how_many> values
770 return iter
.next_n (how_many
, list
);
774 // listing function: iterator creator
775 // This gives back a listing of all entries in <this> context.
777 ACE_Registry::Naming_Context::list (Binding_List
&list
)
779 // Make sure that the list is empty
780 list
= ace_binding_empty_list
;
782 // Create an iterator
783 ACE_Registry::Binding_Iterator iterator
;
785 // Make sure that the iterator uses <this> naming context
786 iterator
.naming_context (*this);
788 // Start iterations from the objects
789 iterator
.current_enumeration (iterator
.object_iteration_
);
794 ACE_Registry::Binding binding
;
795 result
= iterator
.next_one (binding
);
797 list
.insert (binding
);
805 // Default constructor
806 ACE_Registry::Binding_Iterator::Binding_Iterator ()
808 this->object_iteration_
.iterator (this);
809 this->context_iteration_
.iterator (this);
810 this->iteration_complete_
.iterator (this);
816 ACE_Registry::Binding_Iterator::reset ()
818 this->current_enumeration_
= &this->iteration_complete_
;
819 this->iteration_complete_
.reset ();
820 this->object_iteration_
.reset ();
821 this->context_iteration_
.reset ();
826 ACE_Registry::Binding_Iterator::Iteration_State::reset ()
833 ACE_Registry::Binding_Iterator::Iteration_State::iterator (Binding_Iterator
*iter
)
835 this->parent_
= iter
;
839 ACE_Registry::Binding_Iterator::Iteration_State::Iteration_State (void)
844 ACE_Registry::Binding_Iterator::Iteration_State::~Iteration_State (void)
850 ACE_Registry::Binding_Iterator::next_one (Binding
&binding
)
855 // Get next n (where n is one)
856 long result
= this->next_n (how_many
, list
);
860 binding
= (*list
.begin ());
866 // Next <how_many> entries
868 ACE_Registry::Binding_Iterator::next_n (u_long how_many
,
871 // Make sure that the list is empty
872 list
= ace_binding_empty_list
;
874 return this->current_enumeration_
->next_n (how_many
, list
);
880 ACE_Registry::Binding_Iterator::destroy (void)
887 // Set/Get naming_context
889 ACE_Registry::Binding_Iterator::naming_context (Naming_Context
&naming_context
)
891 this->naming_context_
= &naming_context
;
895 ACE_Registry::Naming_Context
&
896 ACE_Registry::Binding_Iterator::naming_context (void)
898 return *this->naming_context_
;
902 // Set/Get current enumeration
904 ACE_Registry::Binding_Iterator::current_enumeration (Iteration_State
¤t_enumeration
)
906 this->current_enumeration_
= ¤t_enumeration
;
910 ACE_Registry::Binding_Iterator::Iteration_State
&
911 ACE_Registry::Binding_Iterator::current_enumeration (void)
913 return *this->current_enumeration_
;
918 ACE_Registry::Binding_Iterator::Object_Iteration::next_n (u_long how_many
,
922 u_long requested
= how_many
;
924 // While there are more entries to be added to the list
927 ACE_TCHAR string
[ACE_Registry::Naming_Context::MAX_OBJECT_NAME_SIZE
];
928 u_long size
= sizeof string
/ sizeof (ACE_TCHAR
);
929 long result
= ACE_TEXT_RegEnumValue (this->parent_
->naming_context ().key (),
948 Binding
binding (string
, OBJECT
);
949 // Add to binding list
950 list
.insert (binding
);
952 // Continue to add to list
955 case ERROR_NO_MORE_ITEMS
:
956 // Enumeration of objects complete
960 // Current enumeration will become CONTEXTS
961 this->parent_
->current_enumeration (this->parent_
->context_iteration_
);
962 result
= this->parent_
->current_enumeration ().next_n (how_many
,
964 // If we were able to add objects
965 if (requested
!= how_many
)
974 // Current enumeration will become COMPLETE
975 this->parent_
->current_enumeration (this->parent_
->iteration_complete_
);
980 // If we reach here, all of <how_many> pairs were added to the list
981 // Since more entries may be available
982 // current enumeration will remain OBJECTS
988 ACE_Registry::Binding_Iterator::Context_Iteration::next_n (u_long how_many
,
992 u_long requested
= how_many
;
994 // While there are more entries to be added to the list
997 ACE_TCHAR string
[ACE_Registry::Naming_Context::MAX_CONTEXT_NAME_SIZE
];
998 u_long size
= sizeof string
/ sizeof (ACE_TCHAR
);
999 long result
= ACE_TEXT_RegEnumKeyEx (this->parent_
->naming_context (). key (),
1012 // Readjust counters
1018 Binding
binding (string
, CONTEXT
);
1019 // Add to binding list
1020 list
.insert (binding
);
1022 // Continue to add to list
1025 case ERROR_NO_MORE_ITEMS
:
1026 // Enumeration of objects complete
1035 // Current enumeration will become CONTEXTS
1036 this->parent_
->current_enumeration (this->parent_
->iteration_complete_
);
1038 // If we were able to add contexts
1039 if (requested
!= how_many
)
1045 // If we reach here, all of <how_many> pairs were added to the list
1046 // Since more entries may be available
1047 // current enumeration will remain CONTEXTS
1053 ACE_Registry::Binding_Iterator::Iteration_Complete::next_n (u_long how_many
,
1056 ACE_UNUSED_ARG(list
);
1057 ACE_UNUSED_ARG(how_many
);
1064 // Factory method to connect to predefined registries
1065 // This method works for both remote and local machines
1066 // However, for remote machines CLASSES_ROOT and CURRENT_USER
1067 // types are not allowed
1070 ACE_Predefined_Naming_Contexts::connect (ACE_Registry::Naming_Context
&naming_context
,
1072 const ACE_TCHAR
*machine_name
)
1074 #if defined (ACE_HAS_WINCE)
1075 ACE_UNUSED_ARG(naming_context
);
1076 ACE_UNUSED_ARG(predefined
);
1077 ACE_UNUSED_ARG(machine_name
);
1082 if (machine_name
!= 0 && ACE_OS::strcmp (ACE_TEXT ("localhost"), machine_name
) == 0)
1085 if (predefined
== HKEY_LOCAL_MACHINE
|| predefined
== HKEY_USERS
)
1087 ACE_TEXT_RegConnectRegistry (const_cast<ACE_TCHAR
*> (machine_name
),
1089 &naming_context
.key_
);
1090 if (predefined
== HKEY_CURRENT_USER
|| predefined
== HKEY_CLASSES_ROOT
)
1092 // Make sure that for these types, the machine is local
1093 if (machine_name
== 0 ||
1094 ACE_Predefined_Naming_Contexts::is_local_host (machine_name
))
1096 naming_context
.key_
= predefined
;
1103 ACE_REGISTRY_CALL_RETURN (result
);
1104 #endif // ACE_HAS_WINCE
1107 // Check if <machine_name> is the local host
1110 ACE_Predefined_Naming_Contexts::is_local_host (const ACE_TCHAR
*machine_name
)
1112 ACE_TCHAR local_host
[MAXHOSTNAMELEN
];
1113 int result
= ACE_OS::hostname (local_host
, sizeof local_host
/ sizeof (ACE_TCHAR
));
1115 result
= !ACE_OS::strcmp (local_host
, machine_name
);
1121 ACE_END_VERSIONED_NAMESPACE_DECL
1123 #endif /* ACE_WIN32 && !ACE_LACKS_WIN32_REGISTRY */