summaryrefslogtreecommitdiff
path: root/ACE/ace/Registry.h
blob: 8d5e613116e1600f8a510bc9add246d2b639b411 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
// -*- C++ -*-

//=============================================================================
/**
 *  @file    Registry.h
 *
 *  @author Irfan Pyarali (irfan@cs.wustl.edu)
 */
//=============================================================================


#ifndef ACE_REGISTRY_H
#define ACE_REGISTRY_H
#include /**/ "ace/pre.h"

#include /**/ "ace/config-all.h"

#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_REGISTRY)
// This only works on registry-capable Win32 platforms.

#include "ace/Containers.h"
#include "ace/SString.h"

ACE_BEGIN_VERSIONED_NAMESPACE_DECL

/**
 * @class ACE_Registry
 *
 * @brief A Name Server implementation
 *
 * The registry interface is inspired by the interface
 * specified in the CORBA Naming Service Specification.
 * The implementation is done through Win32 <Reg*> functions.
 * Other than providing an OO wrapper for the Win32 <Reg*>
 * functions, ACE_Registry provides an abstraction for iteration
 * over the elements of the Registry.
 */
class ACE_Export ACE_Registry
{
public:
  /// International string
  struct ACE_Export Name_Component
  {
    ACE_TString id_;
    ACE_TString kind_;

    bool operator== (const Name_Component &rhs) const;
    bool operator!= (const Name_Component &rhs) const;
    // Comparison
  };
  // The <id_> field is used,
  // but the <kind_> field is currently ignored

  /// A Name is an ordered collections of components (ids)
  typedef ACE_Unbounded_Set<Name_Component> Name;

  /// Separator for components in a name
  static const ACE_TCHAR STRING_SEPARATOR[];

  /// Convert a @a name to a @c string
  static ACE_TString make_string (const Name &name);

  /// Convert a @a string to a @c name
  static Name make_name (const ACE_TString &string);

  /// There are two types of bindings
  enum Binding_Type {INVALID, OBJECT, CONTEXT};

  struct ACE_Export Binding
  {
    /// Empty (default) constructor
    Binding ();

    /// Constructor
    /// (Name version)
    Binding (const Name &binding_name,
             Binding_Type binding_type);

    /// Constructor
    /// (String version)
    Binding (const ACE_TString &binding_name,
             Binding_Type binding_type);

    bool operator== (const Binding &rhs) const;
    bool operator!= (const Binding &rhs) const;
    // Comparison

    /// Name accessor
    /// (Name version)
    void name (Name &name);

    /// Set Name (String version)
    void name (ACE_TString &name);

    /// Get Name (String version)
    ACE_TString name ();

    /// Type accessor
    Binding_Type type ();

  private:
    /// A binding has a name
    ACE_TString name_;

    /// .... and a type
    Binding_Type type_;
  };

  /// A list of bindings
  typedef ACE_Unbounded_Set<Binding> Binding_List;

  // Forward declaration of iterator
  class Binding_Iterator;

  /**
   * @class Object
   *
   * @brief An object representation
   *
   * In CORBA, all objects inherit from (CORBA::Object).
   * For the registry, this is used as a wrapper for an
   * instance of a built-in data type.
   * Think about an object as being similar to a file
   * in a file system.
   */
  class ACE_Export Object
  {
  public:
    /// Default constructor
    Object (void *data = 0,
            u_long size = 0,
            u_long type = REG_NONE);

    /// Set data
    void data (void *data);

    /// Get data
    void *data () const;

    /// Set size
    void size (u_long size);

    /// Get size
    u_long size () const;

    /// Set type
    void type (u_long type);

    /// Get type
    u_long type () const;

  private:
    /// Pointer to data
    void *data_;

    /// Size of the data
    u_long size_;

    /// Type of data
    u_long type_;
  };

  /**
   * @class Naming_Context
   *
   * @brief An context representation
   *
   * Think about a context as being similar to a directory
   * in a file system.
   */
  class ACE_Export Naming_Context
  {
  public:
    /// Friend factory
    friend class ACE_Predefined_Naming_Contexts;

    enum {
      /// Max sizes of names
      /// (Not too sure about this value)
      MAX_OBJECT_NAME_SIZE = BUFSIZ,

      /// Max size of context name
      MAX_CONTEXT_NAME_SIZE = MAXPATHLEN + 1
    };

    /// Empty constructor: keys will be NULL
    Naming_Context ();

    /// Constructor: key_ will be set to @a key
    Naming_Context (const HKEY &key);

    /// Destructor will call <Naming_Context::close>.
    ~Naming_Context ();

    // The following interfaces are for objects

    /**
     * Insert @a object with @a name into @c this context.
     * This will fail if @a name already exists
     * (Name version)
     */
    int bind_new (const Name &name,
                  const Object &object);

    /**
     * Insert @a object with @a name into @c this context
     * This will fail if @a name already exists
     * (String version)
     */
    int bind_new (const ACE_TString &name,
                  const Object &object);

    /**
     * Insert or update @a object with @a name into @c this context
     * This will not fail if @a name already exists
     * (Name version)
     */
    int bind (const Name &name,
              const Object &object);

    /**
     * Insert or update <object> with @a name into @c this context
     * This will not fail if @a name already exists
     * (String version)
     */
    int bind (const ACE_TString &name,
              const Object &object);

    /// Update <object> with @a name in @c this context
    /// (Name version)
    int rebind (const Name &name,
                const Object &object);

    /// Update <object> with @a name in @c this context
    int rebind (const ACE_TString &name,
                const Object &object);

    /// Find <object> with @a name in @c this context
    /// (Name version)
    int resolve (const Name &name,
                 Object &object);

    /// Find <object> with @a name in @c this context
    int resolve (const ACE_TString &name,
                 Object &object);

    /// Delete object with @a name in @c this context
    /// (Name version)
    int unbind (const Name &name);

    /// Delete object with @a name in @c this context
    int unbind (const ACE_TString &name);


    // The following interfaces are for Naming Context

    /// Create new @c naming_context
    int new_context (Naming_Context &naming_context);

    /**
     * Insert <naming_context> with @a name relative to @c this context
     * This will fail if @a name already exists
     * (Name version)
     */
    int bind_new_context (const Name &name,
                          Naming_Context &naming_context,
                          u_long persistence = REG_OPTION_NON_VOLATILE,
                          u_long security_access = KEY_ALL_ACCESS,
                          LPSECURITY_ATTRIBUTES security_attributes = 0);

    /// Insert <naming_context> with @a name relative to @c this context
    /// This will fail if @a name already exists
    int bind_new_context (const ACE_TString &name,
                          Naming_Context &naming_context,
                          u_long persistence = REG_OPTION_NON_VOLATILE,
                          u_long security_access = KEY_ALL_ACCESS,
                          LPSECURITY_ATTRIBUTES security_attributes = 0);

    /**
     * Insert or update <naming_context> with @a name relative to @c this context
     * This will not fail if @a name already exists
     * (Name version)
     */
    int bind_context (const Name &name,
                      /* const */ Naming_Context &naming_context,
                      u_long persistence = REG_OPTION_NON_VOLATILE,
                      u_long security_access = KEY_ALL_ACCESS,
                      LPSECURITY_ATTRIBUTES security_attributes = 0);

    /// Insert or update <naming_context> with @a name relative to @c this context
    /// This will not fail if @a name already exists
    int bind_context (const ACE_TString &name,
                      /* const */ Naming_Context &naming_context,
                      u_long persistence = REG_OPTION_NON_VOLATILE,
                      u_long security_access = KEY_ALL_ACCESS,
                      LPSECURITY_ATTRIBUTES security_attributes = 0);

    /// Rename <naming_context> to @a name
    /// (Name version)
    int rebind_context (const Name &name,
                        /* const */ Naming_Context &naming_context);

    /// Rename <naming_context> to @a name
    int rebind_context (const ACE_TString &name,
                        /* const */ Naming_Context &naming_context);

    /// Find <naming_context> with @a name in @c this context
    /// (Name version)
    int resolve_context (const Name &name,
                         Naming_Context &naming_context,
                         u_long security_access = KEY_ALL_ACCESS);

    /// Find <naming_context> with @a name in @c this context
    int resolve_context (const ACE_TString &name,
                         Naming_Context &naming_context,
                         u_long security_access = KEY_ALL_ACCESS);

    /// Remove naming_context with @a name from @c this context
    /// (Name version)
    int unbind_context (const Name &name);

    /// Remove naming_context with @a name from @c this context
    int unbind_context (const ACE_TString &name);

    /// Same as <unbind_context> with @c this as naming_context
    int destroy ();

    /**
     * listing function: iterator creator
     * This is useful when there are many objects and contexts
     * in @c this context and you only want to look at a few entries
     * at a time
     */
    int list (u_long how_many,
              Binding_List &list,
              Binding_Iterator &iterator);

    /// listing function: iterator creator
    /// This gives back a listing of all entries in @c this context.
    int list (Binding_List &list);

    // Some other necessary functions which are
    // not part of the CORBA interface

    /// Sync content of context to disk
    int flush ();

    /// Close the handle of the context
    /// @note <close> does not call <flush>
    int close ();

    // Accessors

    /// Get key
    HKEY key ();

    // void parent (HKEY parent);
    /// Get parent
    HKEY parent ();

    /// Get name
    /// (Name version)
    void name (Name &name);

    /// Set name (String version)
    void name (ACE_TString &name);

    /// Get name (String version)
    ACE_TString name ();

  protected:
    /// Set key
    void key (HKEY key);

    /// Set parent
    void parent (HKEY parent);

    /// Set name
    /// (Name version)
    void name (const Name &name);

    /// Set name
    /// (String version)
    void name (const ACE_TString &name);

  private:
    /// Disallow copy constructors
    Naming_Context (const Naming_Context &rhs);

    /// Disallow assignment
    const Naming_Context &operator= (const Naming_Context &rhs);

    /// Key for self
    HKEY key_;

    /// Key for parent
    HKEY parent_key_;

    /// Name of self
    ACE_TString name_;
  };

  /**
   * @class Binding_Iterator
   *
   * @brief An iterator
   *
   * Useful when iteratorating over a few entries at a time
   */
  class ACE_Export Binding_Iterator
  {
  public:
    /// Friend factory
    friend class Naming_Context;

    /// Default constructor
    Binding_Iterator ();

    /// Next entry
    int next_one (Binding &binding);

    /// Next <how_many> entries
    int next_n (u_long how_many,
                Binding_List &list);

    /// Cleanup
    int destroy ();

    /// Reset the internal state of the iterator
    void reset ();

    /// Get naming_context that the iterator is iterating over
    Naming_Context &naming_context ();

  private:
    /// Set naming_context that the iterator is iterating over
    void naming_context (Naming_Context& naming_context);

    /// Reference to context
    Naming_Context *naming_context_;

  public:
    // This should really be private
    // But the compiler is broken

    /**
     * @class Iteration_State
     *
     * Base class for state
     */
    class ACE_Export Iteration_State
      {
      public:
        /// Constructor
        Iteration_State ();

        /// Destructor
        virtual ~Iteration_State ();

        /// Set the iterator reference.
        void iterator (Binding_Iterator *iterator);

        /// Next <how_many> entries
        virtual int next_n (u_long how_many,
                            Binding_List &list) = 0;

        /// Reset state
        void reset ();

      protected:
        /// Pointer to parent iterator
        Binding_Iterator *parent_;

        u_long index_;
      };

  private:
    class ACE_Export Object_Iteration : public Iteration_State
      {
        /// Next <how_many> entries
        int next_n (u_long how_many,
                    Binding_List &list);
      };

    class ACE_Export Context_Iteration : public Iteration_State
    {
    public:
      /// Next @a how_many entries
      int next_n (u_long how_many,
                  Binding_List &list);
    };

    class ACE_Export Iteration_Complete : public Iteration_State
    {
    public:
      /// Next @a how_many entries
      int next_n (u_long how_many,
                  Binding_List &list);
    };

    /// Friend states
    friend class Iteration_State;
    friend class Object_Iteration;
    friend class Context_Iteration;
    friend class Iteration_Complete;

    /// Instances of all states
    Object_Iteration object_iteration_;
    Context_Iteration context_iteration_;
    Iteration_Complete iteration_complete_;

    /// Pointer to current state
    Iteration_State *current_enumeration_;

    /// Set current_enumeration
    void current_enumeration (Iteration_State& current_enumeration);

    /// Get current_enumeration
    Iteration_State &current_enumeration ();
  };
};

/**
 * @class ACE_Predefined_Naming_Contexts
 *
 * @brief A factory for predefined registries, which exist by default
 * on Win32 platforms
 *
 * This factory can connect to both local and remote
 * predefined registries.
 */
class ACE_Export ACE_Predefined_Naming_Contexts
{
public:
  /**
   * Factory method for connecting to predefined registries.  This
   * method works for both remote and local machines.  However, for
   * remote machines, HKEY_CLASSES_ROOT and HKEY_CURRENT_USER types
   * are not allowed
   */
  static int connect (ACE_Registry::Naming_Context &naming_context,
                      HKEY predefined = HKEY_LOCAL_MACHINE,
                      const ACE_TCHAR *machine_name = 0);

private:
  /// Check if @a machine_name is the local host
  static int is_local_host (const ACE_TCHAR *machine_name);
};

ACE_END_VERSIONED_NAMESPACE_DECL

#endif /* ACE_WIN32 && !ACE_LACKS_WIN32_REGISTRY */
#include /**/ "ace/post.h"
#endif /* ACE_REGISTRY_H */