Contexts

It is often necessary for an application to associate certain information with a given registry key. To assist developers in doing so in a convenient and performant manner, the CBRegistry component provides context parameters in a number of events.

A context carries an application-defined value that identifies or points to some application-defined data, and registry key has a separate context associated with it. The CBRegistry component treats context values as opaque; it stores the context values passed to it by the application, and ensures that the correct values are exposed again whenever some event fires for a particular registry key; but does not otherwise attempt to use said values in any way.

Context Lifetimes

Contexts in CBRegistry are available in all events that correspond to registry key operations. They are created before the BeforeCreateKey or BeforeOpenKey event fires, and are deleted after the AfterCloseKey event fires (or, more accurately, after the CleanupKeyContext event fires).

Context Use-Cases

Contexts are most helpful when used to store information associated with a registry key that can be used to speed up later events. For example, the only time the CBRegistry component exposes the name of a registry key is during the BeforeCreateKey and BeforeOpenKey events. Applications that wish to use the key name in later events can store it in the key context and then access it in the desired events later. A similar strategy can also be applied for events related to registry key values.

More generally, applications are free to obtain and store whatever information they wish using contexts, so long as their event handlers comply with the restrictions described by the Recursive Calls topic.

Using Contexts

In Go, there is no completely safe way to store struct references in contexts either directly or indirectly, which is why all context parameters are integers. To emulate such capabilities, the following approach is recommended:

  1. Create a global map instance for the application (i.e., a singleton), with keys that are integers and values of whatever type is desired.
  2. When the application needs to create a context struct in an event handler, a "key" can be created using the hash of the full file/directory name (including path), potentially mixed with additional information.
    • For file contexts, a hash of the full file/directory name is sufficiently unique since the context is exposed in all events pertaining to that file/directory.
    • For handle and enumeration contexts, additional information must be mixed in since multiple handle and/or enumeration contexts may be present at once for any given file/directory.
  3. Using the created key, add the struct to the map.
  4. Set the Context parameter to the key used in the previous step.
  5. To access the struct in a later event, use the key stored by the context to retrieve the struct from the map.

Notes:

  • Applications must take care to enforce proper thread synchronization when accessing the map since events are always fired using worker native threads. Please refer to the Threading and Concurrency topic for more information.
  • In 32-bit applications, contexts are stored in 32-bit variables internally, thus the higher 32 bits of 64-bit values are lost.

Copyright (c) 2022 Callback Technologies, Inc. - All rights reserved.
CBFS Filter 2020 Go Edition - Version 20.0 [Build 8317]