Advanced Programming Interfaces and Topics

This section contains information about a variety of advanced topics.

Programming Interfaces for Transaction Server

Microsoft Transaction Server supports the following interfaces.

IObjectContext

An ObjectContext does the following:

You obtain a reference to the IObjectContext interface by calling the GetObjectContext function. As with a COM object, you must release an ObjectContext object when you have finished using it. The IObjectContext interface exposes the following methods.

Method Description
CreateInstance Instantiates another Microsoft Transaction Server object.
DisableCommit Declares that the object hasn't finished its work and that its transactional updates are in an inconsistent state. The object retains its state across method calls, and any attempts to commit the transaction before the object calls EnableCommit or SetComplete result in the transaction being aborted.
EnableCommit Declares that the work of the object is not finished, but its transactional updates are in a consistent state. This method allows the transaction to be committed, but the object retains its state across method calls until it calls SetComplete or SetAbort, or until the transaction is complete.
IsCallerInRole  Indicates whether the direct caller of the object is in a specified role (either directly or as part of a group).
IsInTransaction Indicates whether the object is executing within a transaction.
IsSecurityEnabled Indicates whether security is enabled. In Microsoft Transaction Server version 1.0, security is enabled unless the object is running in a client process.
SetAbort Declares that the object has completed its work and can be deactivated on return from the currently executing method; however, its transactional updates are in an inconsistent state or an unrecoverable error occurred. The transaction in which the object was executing must be aborted.
SetComplete Declares that the object has completed its work and can be deactivated on return from the currently executing method; its transactional updates can be committed. When an object that is the root of a transaction calls SetComplete, Transaction Server attempts to commit the transaction on return from the current method.

IObjectControl

The IObjectControl interface allows you to define context-specific initialization and cleanup procedures for your Microsoft Transaction Server objects and specify whether or not the objects can be recycled. Implementing the IObjectControl interface is optional.

If you implement the IObjectControl interface in a component, the Microsoft Transaction Server run-time environment automatically calls the IObjectControl methods on the objects at the appropriate times.

When an object supports the IObjectControl interface, Microsoft Transaction Server calls its Activate method once for each time the object is activated. The Activate method is called before any other methods are called. You can use this method to perform any context-specific initialization an object may require.

An object context is not available from the object's class factory during object construction, so context-specific initialization cannot be performed in an object constructor.

Microsoft Transaction Server calls the object Deactivate method each time the object is deactivated. This can be the result of the object returning from a method in which it calls SetComplete or SetAbort, or the root of the object transaction causing the transaction to complete. Use the Deactivate method to clean up state that you initialized in the Activate method.

After calling the Deactivate method, the Transaction Server run-time environment calls the CanBePooled method. If this method returns true, the deactivated object is placed in an object pool for reuse. If the CanBePooled method returns false, the object is released in the usual way and its destructor is invoked. On systems that do not support object pooling, the value returned by this method is ignored.

The IObjectControl interface is not accessible to the clients of an object or to the object itself. Only the Microsoft Transaction Server run-time environment can invoke the IObjectControl methods. If a client queries for the IObjectControl interface, QueryInterface returns E_NOINTERFACE.

The IObjectControl interface exposes the following methods.

Method Description
Activate Allows an object to perform context-specific initialization whenever it's activated. This method is called by the Transaction Server run-time environment before any other methods are called on the object.
CanBePooled Allows an object to notify the Transaction Server run-time environment of whether it can be pooled for reuse. Return true to pool instances of this component, false otherwise.
Deactivate Allows an object to perform whatever cleanup is necessary before it's recycled or destroyed. This method is called by the Transaction Server run-time environment whenever an object is deactivated.

ISecurityProperty

The ISecurityProperty interface is used to ascertain the security ID of the caller or creator of the current object. This information can then be used to further restrict access or for auditing and logging purposes.

You obtain a reference to the ISecurityProperty interface of an object by calling QueryInterface on the ObjectContext of the object, for example:

m_pIObjectContext->QueryInterface (IID_ISecurityProperty, void**)&m_pISecurityProperty));

The ISecurityProperty interface provides the following methods.

Method Description
GetDirectCallerSID Retrieves the security ID of the external process that called the currently executing method.
GetDirectCreatorSID Retrieves the security ID of the external process that directly created the current object.
GetOriginalCallerSID Retrieves the security ID of the base process that initiated the call sequence from which the current method was called.
GetOriginalCreatorSID Retrieves the security ID of the base process that initiated the activity in which the current object is executing.
ReleaseSID Releases the security ID returned by one of the other ISecurityProperty methods.

ISharedPropertyGroupManager

The ISharedPropertyGroupManager interface is used to create shared property groups and to obtain access to existing shared property groups. You can access the ISharedPropertyGroupManager interface by creating an instance of the SharedPropertyGroupManager by using either IObjectContext::CreateInstance or CoCreateInstance.

The Shared Property Manager is a resource dispenser that you can use to share state among multiple objects within a server process. You cannot use global variables in a distributed environment because of concurrency and name collision issues. The Shared Property Manager eliminates name-collisions by providing shared property groups, which establish unique name spaces for the shared properties they contain. The Shared Property Manager also implements locks and semaphores to protect shared properties from simultaneous access, which could result in lost updates and leave properties in an unpredictable state.

Shared properties can be shared only by objects running in the same process. If you want instances of different components to share properties, you have to install the components in the same Transaction Server package. Because there is a risk that administrators will move components from one package to another, it's safest to limit the use of a shared property group to instances of components that are defined in the same DLL.

It's also important for components sharing properties to have the same activation attribute. If two components in the same package have different activation attributes, they generally won't be able to share properties. For example, if one component is configured to run in a client process and the other is configured to run in a server process, their objects will usually run in different processes, even though they're in the same package.

You should always instantiate the SharedPropertyGroupManager, SharedPropertyGroup, and SharedProperty objects from Transaction Server objects rather than from a base client. If a base client creates shared property groups and properties, the shared properties are inside the base-client process, not in a server process. This means Transaction Server objects cannot share the properties unless the objects, too, are running in the client process (which is generally not a good idea).

When you set the isolation mode to LockMethod, the Shared Property Manager requires access to the ObjectContext of the calling object. You cannot use this isolation mode to create a shared property group from within the constructor of an object or from a non-Transaction Server object because ObjectContext isn't available during object construction and a non-Transaction Server object doesn't have an ObjectContext.

The ISharedPropertyGroupManager interface exposes the following methods.

Method Description
CreatePropertyGroup Creates a new SharedPropertyGroup with a string identifier. If a group with the specified name already exists, CreatePropertyGroup returns a reference to the existing group.
get_Group Returns a reference to an existing shared property group, given a string by which it can be identified.
get__NewEnum Returns a reference to an enumerator that steps through a list of all shared property groups in a given process.

ISharedPropertyGroup

The ISharedPropertyGroup interface is used to create and access the shared properties in a shared property group.

You can access the ISharedPropertyGroup interface by creating a SharedPropertyGroup object with the ISharedPropertyGroupManager::CreatePropertyGroup method.

As with any COM object, you must release a SharedPropertyGroup object when you have finished using it.

The ISharedPropertyGroup interface exposes the following methods.

Method Description
CreateProperty Creates a new shared property identified by a string unique within its property group.
CreatePropertyByPosition Creates a new shared property identified by a numeric index within its property group.
get_Property    Returns a reference to a shared property, given the string name by which the property is identified.
get_PropertyByPosition    Returns a reference to a shared property, given its numeric index in the shared property group.

ISharedProperty

The ISharedProperty interface is used to set or retrieve the value of a shared property. A shared property can contain any data type that can be represented by a variant. You can access the ISharedProperty interface by creating a SharedProperty object with the ISharedPropertyGroup::CreateProperty method or the ISharedPropertyGroup::CreatePropertyByPosition method.

A SharedProperty object can be created or accessed only from within a SharedPropertyGroup. As with any COM object, you must release a SharedProperty object when you have finished using it.

The ISharedProperty interface exposes the following methods:

ITransactionContextEx

The ITransactionContextEx interface is used by a base client to compose the work of one or more Microsoft Transaction Server objects into an atomic transaction and to commit or abort the transaction. You use a TransactionContextEx object to scope a transaction from a base client. You begin the transaction by instantiating a TransactionContextEx object, and you end the transaction by calling Commit or Abort on it. The base client itself never executes within the transaction.

The TransactionContextEx component is a standard Transaction Server component. Its transaction attribute is set to Requires a new transaction, so it is always the root of a transaction. When a base client instantiates an object by using the ITransactionContextEx::CreateInstance method, the new object and its related elements will participate in the transaction of the TransactionContextEx object unless the transaction attribute of the object is set to Requires a new transaction or Does not support transactions.

To write a TransactionContextEx component, create a component that implements the methods Commit, Abort, and CreateInstance, and set the transaction attribute of the component to Requires a new transaction. The three methods would call GetObjectContext and invoke the SetComplete, SetAbort, and CreateInstance methods of the ObjectContext object.

Before you use TransactionContextEx to compose the work of existing components in a transaction, consider implementing a separate component that not only composes but encapsulates the work into a reusable unit. This new component would not only serve the needs of the current base client, but other clients could also use it.

In one approach, the base client instantiates a TransactionContextEx object, calls the CreateInstance method to instantiate other objects, calls various methods on those objects, and finally calls Commit or Abort on the TransactionContextEx object.

In the other approach, you create a new component that requires a transaction. This new component instantiates the other objects using the CreateInstance method of the ObjectContext of the object, calls the relevant methods on those other objects, and then calls SetComplete or SetAbort on its ObjectContext when it's done. Using this approach, the base client only needs to instantiate this one object, and invoke one method on it; the object does the rest of the work. When other clients require the same functionality, they can reuse the new component.

You obtain a reference to the ITransactionContextEx interface by creating a TransactionContextEx object with a call to CoCreateInstance. For example:

CoCreateInstance(CLSID_TransactionContextEx, NULL, CLSCTX_INPROC, IID_ITransactionContextEx, (void**)&m_pTransactionContext);

The ITransactionContextEx interface exposes the following methods.

Method Description
Abort Aborts the work of all Transaction Server objects participating in the current transaction. The transaction is completed on return from this method.
Commit Commits the work of all Transaction Server objects participating in the current transaction. The transaction is completed on return from this method.
CreateInstance Instantiates another Transaction Server object. If the component that provides the object is configured to support or require a transaction, then the new object runs under the transaction of the TransactionContextEx object.

Building Clients

Clients provide the first tier to your application; they are the only part that the client sees. There are three widely available choices for communicating with clients:

Deploying Clients

This section describes how Transaction Server components are instantiated from a client computer and provides configuration information for client computers to instantiate server components. This section also explores several methods and tools available to configure client computers running Windows NT and Windows-based operating systems.

To deploy clients in a distributed system, you must provide a model for using objects on different computers. Some applications are inherently distributed, such as multiuser games and discussion forums. Others are distributed because at least two of their components run on different computers. Examples include messaging, workflow, and groupware applications.

With Microsoft Transaction Server, you can distribute application components to the locations that make the most sense for your users and application while also considering  optimal network performance and computer resource usage. After the Transaction Server components are distributed to physical locations, you can configure computers so that they can use the components they need.

At minimum, a Transaction Server component must conform to the COM specification for a 32-bit in-process DLL server. It must also have cross-process marshaling support. Therefore, if it is a dispatch or dual interface component, then it must describe all of its interfaces in a type library and use automation marshaling support. If it is a custom interface, then it must provide a proxy/stub DLL that uses fully interpreted standard marshaling. To take advantage of  the full Transaction Server feature set, components should also implement Transaction Server APIs.

After components have been distributed to Transaction Server servers as needed (for more information, see the product documentation), they are ready to be used by clients. Sometimes these clients (called base clients) are installed on the same server, but more often than not, they are on remote machines. These remote clients need to use some communication mechanism to invoke the services of the Transaction Server components. There are four primary methods of doing this:

DCOM is currently available on Windows NT 4.0 Server and Workstation, Windows 95, Solaris, and should be available on most major platforms in the near future. DCOM will soon encompass HTTP, but for now, HTTP must be treated as a separate entity. Since HTTP currently requires IIS 3.0 with Active Server Pages or a custom ISAPI component to access components, the real base client is IIS. IIS then uses DCOM to communicate with Transaction Server components. Remote Automation and custom transport mechanisms may be necessary to support legacy platforms.

All of these mechanisms require some form of client configuration. We will discuss configuring clients for DCOM and Remote Automation.

When you install a component in a package, Transaction Server edits the registry to map a component's class identifier to an absolute server location. Before a component can execute in the Transaction Server run-time environment, it must be registered.

Transaction Server uses the registry to hold configuration information. For a client computer to instantiate objects on a remote (server) computer, its registry must have the following entries:

Application identifier (APPID)

This key has all the Distributed COM-specific configuration information for the component. An example of this entry is:

HKEY_CLASSES_ROOT\
   AppID\
      {93618C8D-3E39-11D0-B964-0080C7394688}

Class identifier (CLSID)

HKEY_CLASSES_ROOT\
   CLSID\
      {93618C8D-3E39-11D0-B964-0080C7394688}

Interface identifier (IID)

HKEY_CLASSES_ROOT\
   Interface\
      {2E93DA21-8DA6-11CF-BE4D-00AA00A2FA25}

Proxy/stub CLSID

HKEY_CLASSES_ROOT\
   Interface\
      {2E93DA21-8DA6-11CF-BE4D-00AA00A2FA25}\ProxyStub32
HKEY_CLASSES_ROOT\
   CLSID\
      {2E93DA21-8DA6-11CF-BE4D-00AA00A2FA25}

Components that rely on standard automation marshaling also require a type-library key. A type library interprets functions and parameters so that they can be properly marshaled.

Type library identifier (Typelib)

HKEY_CLASSES_ROOT\
   TypeLib\
      {93618C92-3E39-11D0-B964-0080C7394688}
HKEY_CLASSES_ROOT\
   Interface\
      TypeLib\{93618C92-3E39-11D0-B964-0080C7394688}

If you use Transaction Server Explorer to configure client computers, Transaction Server automatically configures the registry on the client computer with these entries. If your client computer(s) does not have Transaction Server installed, you must use other tools to configure the client registry or configure it manually.

There are three tools to configure client computers:

The following table indicates which client configuration methods are supported for client computers running Windows NT and Windows-based operating systems.

Operating system on client computer Transaction Server Explorer DCOM Remote Automation
Microsoft Windows NT Server      
   Version 4.0
   Version 3.51    
Microsoft Windows NT Workstation  
   Version 4.0
   Version 3.51  
Microsoft Windows 95
Microsoft Windows for Workgroups 3.11  
Microsoft Windows 3.x

Client Configuration Tools

You can use other tools to configure client computers.

Clireg16.exe and Clireg32.exe

Use these 16-bit and 32-bit client registration files to register a component on a client computer for remote execution. This utility ships with many Microsoft enterprise development tools and uses Visual Basic registration files (.vbr) to register them. Visual Basic produces these files when it builds a component, but other languages may require that they be created by hand. The Client Registration utility can be used to optionally register a type library (.tlb) and set additional component options.

The syntax for the Client Registration utility is:

CLIREG[32 | 16] 
vbrfile -s server_name  | 
-p network_protocol  | 
-a authentication_level  | 
-t typelib_file  | 
-u | -d | -q  | -l  | -nologo  | [-h|?]

If you create a Setup program using the Visual Basic Setup Wizard, this utility is automatically included in Setup.lst. When you run the Setup program, it automatically registers the component. For more information about this utility and using the Setup Wizard, see the Microsoft Visual Basic documentation.

Starting with Visual Basic version 5.0, this utility can be used to configure components for either Remote Automation or DCOM. Previous versions could only configure for Remote Automation.

Regsvr.exe and Regsvr32.exe

You can use the Regsvr.exe and Regsvr32.exe utilities to manually register and unregister components.

Regsvr32.exe is part of the Transaction Server installation and is located in the Mtx folder. It can only be used on in-process servers. To use this tool to register a component on a client, the component must be installed on the client. Regsvr32.exe is useful for registering the proxy/stub component. The proxy/stub component provides marshaling support, is implemented as an in-process DLL server, must be installed on the client, and must be registered.

The syntax for the Regsvr.exe utility is:

REGSVR[32]  [-u] component_name

Oleview

The Oleview utility can:

Oleview requires either Windows 95 or Windows NT 4.0 and either Internet Explorer version 3.0 or the ActiveX SDK. It is currently available on http://www.microsoft.com/oledev. Oleview allows registration from the user interface only. This is not very useful when providing an automatic client registration but can be handy when troubleshooting.

DCOM Configuration Tool

You can use the DCOM configuration tool (Dcomcnfg.exe) to view and edit properties for DCOM components as well as to:

Dcomenfg.exe allows registration from the user interface only. This is not very useful when providing an automatic client registration but can be handy when troubleshooting.

Remote Automation Connection Manager

The Remote Automation Connection Manger ships with Visual Basic and several of the other enterprise development tools. It can be used to view and edit properties for DCOM and Remote Automation components and to:

The Remote Automation Connection Manager allows registration from the user interface only. This is not very useful when providing an automatic client registration but can be handy when troubleshooting.

Registry Editor

Use the Registry Editor (Regedit) to manually edit settings in the system registry. Use this tool carefully. It is easy to introduce an error in the registry that could cause the computer to become unstable. You can use this tool to import registry entries from a registry file (.reg) or to create a registry file by exporting entries.

You can use any text editor to edit the registration files (.reg) and Visual Basic registration files (.vbr).

Using DCOM

If Microsoft Transaction Server is not installed on the client computer but DCOM is, you can still instantiate a Transaction Server object.

Platforms. DCOM is currently supported for Microsoft Windows NT 4.0 and  Windows 95 platforms, and on UNIX and MVS from Software AG (http://www.sagus.com).

Development Tools. You can use Microsoft Visual Basic, Microsoft Visual C++, Microsoft Visual J++, or any other language that can build a COM component.

Client Computer Requirements.

For marshaling components:

For Registry entries:

The following keys are required to register the type library. These keys are not required for a custom-marshaled interface. The entire key has the structure:

HKEY_CLASSES_ROOT\
   TypeLib\
      {LIBID_of_typelib}
         Default = human_readable_string 
HKEY_CLASSES_ROOT\
   TypeLib\
      {LIBID_of_typelib}\major.minor\HELPDIR 
         Default = [helpfile_path]
HKEY_CLASSES_ROOT\
   TypeLib\
      {LIBID_of_typelib}\major.minor\Flags 
         Default = typelib_flags
HKEY_CLASSES_ROOT\
   TypeLib\
      {LIBID_of_typelib}\major.minor\lcid\platform 
         Default = localized_typelib_filename

The following key sets up the Program Identifier (ProgID) for the component. This key is required for Visual Basic programs. The entire key has the structure:

HKEY_CLASSES_ROOT\
   Program_Identifier 
      Default = AppName.ObjectName
HKEY_CLASSES_ROOT\
   Program_Identifier\
      CLSID 
         Default = {CLSID_of_component}

The following keys set up the Class Identifier (CLSID) of the component. There are many keys, but these are the most important for MTS components. There needs to be a similar entry for the marshaling proxy/stub component for custom interfaces. The entire key has the structure:

HKEY_CLASSES_ROOT\
   CLSID\
      {CLSID_of_component} 
         Default = human_readable_string_often_progid
         AppID = {AppID_of_component} 
HKEY_CLASSES_ROOT\
   CLSID\
      {CLSID_of_component}\ProgID 
         Default = AppName.ObjectName.VersionNumber
HKEY_CLASSES_ROOT\
   CLSID\
      {CLSID_of_component}\VersionIndependentProgID 
         Default = AppName.ObjectName
HKEY_CLASSES_ROOT\
   CLSID\
      {CLSID_of_component}\LocalServer[32] 
         Default = filepath[/Automation]
HKEY_CLASSES_ROOT\
   CLSID\
      {CLSID_of_component}\InProcServer[32] 
         Default = filepath[/Automation]
HKEY_CLASSES_ROOT\
   CLSID\
      {CLSID_of_component}\InProcHandler[32] 
         Default = filepath[/Automation]
HKEY_CLASSES_ROOT\
   CLSID\
      {CLSID_of_component}\Programmable
HKEY_CLASSES_ROOT\
   CLSID\
      {CLSID_of_component}\TypeLib 
         Default = {LIBID_of_typelib}

The following key sets up the Interface Identifier (IID) for the component. There is at least one Interface key per class identifier. The entire key has the structure:

HKEY_CLASSES_ROOT\
   Interface\
      {IID_of_interface_1} 
         Default = InterfaceName
HKEY_CLASSES_ROOT\
   Interface\
      {IID_of_interface_1}\Typelib 
         Default = {LIBID_of_typelib}
HKEY_CLASSES_ROOT\
   Interface\
      {IID_of_interface_1}\ProxyStubClsid[32] 
         Default = {CLSID_of_proxy/stub}
HKEY_CLASSES_ROOT\
   Interface\
      {IID_of_interface_1}\NumMethods 
         Default = number_of_methods_in_interface
HKEY_CLASSES_ROOT\
   Interface\
      {IID_of_interface_1}\BaseInterface
         Default = {CLSID_of_interface_derived_from}

The following keys are DCOM-specific keys:

These keys fill in the AppID entries for the application. The entire key has the structure:

HKEY_LOCAL_MACHINE\
   SOFTWARE\
      Classes\
         AppID\
            {AppID_of_component}
RemoteServerName = remote_server_name
ActivateAtStorage = activate_on_same_system_as_persistent_storage
LocalService = run_application_as_a_Win32_service
ServiceParameters = parameters_passed_to_a_LocalService_on_invocation
RunAs = run_server_as_a_given_user
LaunchPermission = ACL_for_launch_permissions
AccessPermission =  ACL_for_access_permissions

These keys set the default DCOM settings. These settings affect the whole computer. The entire key has the structure:

HKEY_LOCAL_MACHINE\
   Software\
      Microsoft\
         OLE
EnableDCOM = value_that_sets_global_activation_policy
DefaultLaunchPermission = value_that_defines_default_ACL
DefaultAccessPermission = value_that_defines_default_access_permission_list
LegacyAuthenticationLevel = value_that_sets_default_authentication_level
LegacyImpersonationLevel = value_that_sets_default_impersonation_level
LegacyMutualAuthentication = value_that_enables_mutual_authentication
LegacySecureReferences = value_that_secures_IUnknown_methods

Using Remote Automation

Remote Automation (RA) allows clients to access objects on other computers. Like DCOM, RA uses remote procedure calls to communicate between client and server. However, while DCOM allows access for any COM interface across the network (across machine boundaries), RA supports only IDispatch interfaces (dispinterfaces and dual interfaces).

Remote Automation is a precursor to Distributed COM, is not language-specific, and can be used for both 16-bit and 32-bit Windows platforms. Remote Automation ships with Microsoft Visual Basic 4.0 and later and Microsoft Visual C++ 4.2 Enterprise Edition.

Platforms. Remote Automation is supported on Windows NT 4.0, Windows NT 3.51, Windows 95, Windows for Workgroups 3.11, and Windows 3.1.

Development Tools. You can use Microsoft Visual Basic, Microsoft Visual C++, Microsoft Visual J++ or any other language that can build a dispinterface or dual-interface component.

Client Computer Requirements.

For marshaling components:

For Registry entries:

The following keys are required to register the type library. These keys are not required for a custom marshaled interface. The entire key has the structure:

HKEY_CLASSES_ROOT\
   TypeLib\
      {LIBID_of_typelib}
         Default = human_readable_string 
HKEY_CLASSES_ROOT\
   TypeLib\
      {LIBID_of_typelib}\major.minor\HELPDIR 
         Default = [helpfile_path]
HKEY_CLASSES_ROOT\
   TypeLib\
      {LIBID_of_typelib}\major.minor\Flags 
         Default = typelib_flags
HKEY_CLASSES_ROOT\
   TypeLib\
      {LIBID_of_typelib}\major.minor\lcid\platform 
         Default = localized_typelib_filename

The following key sets up the Program Identifier (ProgID) for the component. This key is required for Visual Basic programs. The entire key has the structure:

HKEY_CLASSES_ROOT\
   Program_Identifier 
      Default = AppName.ObjectName
HKEY_CLASSES_ROOT\
   Program_Identifier\
      CLSID 
         Default = {CLSID_of_component}

The following keys set up the Class Identifier (CLSID) of the component. There are many keys, but these are the most important for MTS components. There needs to be a similar entry for the marshaling proxy/stub component for custom interfaces. The entire key has the structure:

HKEY_CLASSES_ROOT\
   CLSID\
      {CLSID_of_component} 
         Default = human_readable_string_often_progid
         AppID = {AppID_of_component} 
HKEY_CLASSES_ROOT\
   CLSID\
      {CLSID_of_component}\ProgID 
         Default = AppName.ObjectName.VersionNumber
HKEY_CLASSES_ROOT\
   CLSID\
      {CLSID_of_component}\VersionIndependentProgID 
         Default = AppName.ObjectName
HKEY_CLASSES_ROOT\
   CLSID\
      {CLSID_of_component}\LocalServer[32] 
         Default = filepath[/Automation]
HKEY_CLASSES_ROOT\
   CLSID\
      {CLSID_of_component}\InProcServer[32] 
         Default = filepath[/Automation]
HKEY_CLASSES_ROOT\
   CLSID\
      {CLSID_of_component}\InProcHandler[32] 
         Default = filepath[/Automation]
HKEY_CLASSES_ROOT\
   CLSID\
      {CLSID_of_component}\Programmable
HKEY_CLASSES_ROOT\
   CLSID\
      {CLSID_of_component}\TypeLib 
         Default = {LIBID_of_typelib}

The following key sets up the Interface Identifier (IID) for the component. There is at least one Interface key per class identifier. The entire key has the structure:

HKEY_CLASSES_ROOT\
   Interface\
      {IID_of_interface_1} 
         Default = InterfaceName
HKEY_CLASSES_ROOT\
   Interface\
      {IID_of_interface_1}\Typelib 
         Default = {LIBID_of_typelib}
HKEY_CLASSES_ROOT\
   Interface\
      {IID_of_interface_1}\ProxyStubClsid[32] 
         Default = {CLSID_of_proxy/stub}
HKEY_CLASSES_ROOT\
   Interface\
      {IID_of_interface_1}\NumMethods 
         Default = number_of_methods_in_interface
HKEY_CLASSES_ROOT\
   Interface\
      {IID_of_interface_1}\BaseInterface
         Default = {CLSID_of_interface_derived_from}

The following keys are RA-specific keys:

HKEY_CLASSES_ROOT\
   CLSID\
      {CLSID_of_component}\
         InprocServer32 
            Default = "C:\WINNT\System32\autprx32.dll"
HKEY_CLASSES_ROOT\
   CLSID\
   {CLSID_of_component}\
      InprocServer 
         Default = "C:\WINNT\System\autprx.dll"
HKEY_CLASSES_ROOT\
   CLSID\
      {CLSID_of_component}\
         NetworkAddress
            Default = SampleServer
HKEY_CLASSES_ROOT\
   CLSID\
      {CLSID_of_component}\
         AuthenticationLevel 
            Default = some_RPC_auth_level
HKEY_CLASSES_ROOT\
   CLSID\
      {CLSID_of_component}\
         ProtocolSequence 
            Default = some_network_protocol