Previous | Contents | Index |
All COM components (implemented as either an out-of-process server or as an in-process server) must be registered in the OpenVMS Registry before you can use them.
Out-of-process servers, which are implemented as executable programs ( .EXE files), usually contain code to register and unregister the components contained within them. The advantage an out-of-process server has over an in-process server is that you can run the executable and automatically create the necessary registry keys.
In-process servers, which are usually implemented as dynamic link libraries ( .DLL files) on Windows NT or as shareable images on OpenVMS, also contain code to register and unregister the components within them automatically. However, these in-process servers cannot be run the same way as an executable image because they do not contain a main entry point. As a result, you must manually register the components contained within a .DLL , or create a command procedure to perform the registration.
Microsoft provides the REGSVR32 utility that you can use to register the components contained within a DLL. REGSVR32 takes as a command line argument the following:
When registering a DLL's components, REGSVR32 searches the specified DLL for the DllRegisterServer symbol and, if found, calls it. When unregistering a DLL, REGSVR32 calls DllUnregisterServer . This means that all in-process components that you want to register automatically must include these two entry points in their export files.
To facilitate the registration of components contained within shareable images on OpenVMS systems, Compaq created the DCOM$REGSVR32 utility. The DCOM$REGSVR32 utility does the same things that the Microsoft REGSVR32 utility does. Any shareable images that contain components to be registered must also include the DllRegisterServer and DllUnregisterServer universal symbols in their symbol vectors. Both the DCOM$REGSVR32 and the REGSVR32 utilities use the same command line syntax.
During the COM for OpenVMS installation, the system places the DCOM$REGSVR32.EXE file in the SYS$SYSTEM directory.
Before you use the DCOM$REGSVR32 utility, you must define a symbol that allows the utility to accept foreign command lines. For example:
$ regsvr32 :== $DCOM$REGSVR32 |
Alternatively, you can activate the DCOM$REGSVR32 utility as follows:
$ MCR DCOM$REGSVR32 |
You can use either method to activate the utility, and register or unregister components contained in shareable images.
To display help for DCOM$REGSVR32, enter the following:
$ regsvr32 -? |
Table 6-1 summarizes the DCOM$REGSVR32 command line options.
Switch | Use |
---|---|
-?, /? | Display help file (this table). |
shareable-image-name | Register the specified shareable image name. |
-u or /u image-name | Unregister the specified shareable image name. |
The DCOM$REGSVR32 utility requires that the shareable image name contain a full directory specification. |
Example 6-4 demonstrates how to register an in-process component (contained within a shareable image) using the DCOM$REGSVR32 utility.
Example 6-4 Registering a Component Using the DCOM$REGSVR32 Utility |
---|
$ regsvr32 USER$DISK:[SEYMOUR.DISPATCH_SAMPLE1]CMPNT$SHR.EXE Class factory: Create self. DllRegisterServer: Registering Server DLL Creating key CLSID\{0C092C2C-882C-11CF-A6BB-0080C7B2D682} Creating key CLSID\{0C092C2C-882C-11CF-A6BB-0080C7B2D682}\InProcServer32 Creating key CLSID\{0C092C2C-882C-11CF-A6BB-0080C7B2D682}\ProgID Creating key CLSID\{0C092C2C-882C-11CF-A6BB-0080C7B2D682}\VersionIndependentProgID Creating key CLSID\{0C092C2C-882C-11CF-A6BB-0080C7B2D682}\TypeLib Creating key InsideCOM.Chap11 Creating key InsideCOM.Chap11\CLSID Creating key InsideCOM.Chap11\CurVer Creating key InsideCOM.Chap11.1 Creating key InsideCOM.Chap11.1\CLSID Class factory: Destroy self. |
Example 6-5 demonstrates how to unregister an in-process component (contained within a shareable image) using the DCOM$REGSVR32 utility.
Example 6-5 Unregistering a Component Using the DCOM$REGSVR32 Utility |
---|
$ regsvr32 /u USER$DISK:[SEYMOUR.DISPATCH_SAMPLE1]CMPNT$SHR.EXE Class factory: Create self. DllUnregisterServer: Unregistering Server DLL Deleting key InProcServer32 Deleting key ProgID Deleting key VersionIndependentProgID Deleting key TypeLib Deleting key LocalServer32 Deleting key CLSID\{0C092C2C-882C-11CF-A6BB-0080C7B2D682} Deleting key CLSID Deleting key CurVer Deleting key InsideCOM.Chap11 Deleting key CLSID Deleting key InsideCOM.Chap11.1 Class factory: Destroy self. |
This chapter explains how to develop COM applications for OpenVMS.
The following sections describe how to create a COM for OpenVMS application.
Building COM for OpenVMS applications places demands on the virtual memory requirements of a process. You should have a minimum page file quota of 100,000 pagelets before building a COM for OpenVMS application. This is a DEC C++ compiler requirement. |
Use the DCOM$GUIDGEN utility to generate 16-byte globally unique identifiers (GUIDs). The utility supports both OpenVMS and UNIX styles. For example:
$ SET COMMAND DCOM$LIBRARY:DCOM$GUIDGEN.CLD $ DCOM$GUIDGEN [/FORMAT=value] [/COUNT=value] [/OUTPUT=value] |
$ mcr dcom$guidgen [-cdghirs?] [-on] |
The following table summarizes the GUID format options.
OpenVMS qualifier (value) | UNIX switch | Use |
---|---|---|
IDL | -i | Output GUID in an IDL interface template. |
STRUCT | -s | Output GUID as an initialized C struct. |
IMPLEMENT_OLECREATE | -c | Output GUID in IMPLEMENT_OLECREATE(...) format. |
DEFINE_GUID | -d | Output GUID in DEFINE_GUID(...) format. |
GUID_STRUCT | -g | Output GUID as an initialized static const GUID struct. |
REGISTRY_GUID | -r | Output GUID in registry format. |
The last four options in the preceding table are the same as the four options in the Windows NT Guidgen utility. |
The following table lists additional options supported by the DCOM$GUIDGEN utility.
OpenVMS qualifier | UNIX switch | Use |
---|---|---|
/OUTPUT= filename | -o filename | Redirect output to a specified file. |
/COUNT= number | -n number | Number of GUIDs to generate. |
not available | -h , -? | Display command option summary. |
You can specify more than one format for the same GUID.
7.2 Step 2: Build an Application Using the MIDL Compiler
The following sections describe how to use the MIDL compiler to build
an application.
7.2.1 Running the MIDL Compiler
The MIDL compiler consists of the following separate images:
To run MIDL, you must first define a DCL symbol. For example:
$ midl :== $dcom$midl $ midl -? $ midl -Oicf -idcom$library: example.idl |
The
midl -?
command displays a list of valid command line arguments. For a list of
these arguments, see Appendix A.
7.2.2 Running the MIDL Compiler with DCOM$RUNSHRLIB
The DCOM$MIDL.EXE utility gets its arguments from the DCL foreign command line buffer. DCL foreign commands can have a maximum of 255 characters.
Because of the number of arguments that DCOM$MIDL.EXE can accept, you might exceed this maximum number of characters if you specify a complex MIDL command (for example, a command that contains mixed-case arguments that require quotation marks).
As a workaround, you can use the SYS$SYSTEM:DCOM$RUNSHRLIB.EXE utility. Use the following procedure:
$ SET COMMAND DCOM$LIBRARY:DCOM$RUNSHRLIB.CLD |
Argument | Value | Required/Optional |
---|---|---|
P1 | Name of the shareable image library. This can be a logical name, the name of an image in SYS$SHARE: , or a full file specification. | Required |
P2 | Name of the routine to be called as a C or C++ main() routine with an argc/argv vector. | Required |
P3 | List of qualifiers in quotation marks. | Optional |
$ midl :== DCOM$RUNSHRLIB DCOM$MIDL_SHR DCOM$MIDL_MAIN |
$ midl :== $dcom$midl $ midl -Zp8 -Oicf -Os -oldnames -char unsigned - -error allocation -error bounds_check -error stub_data - -ms_ext -c_ext -out [.OBJ] - -I[INC] -I[PROJECT_WIDE_INC] -I[COMMON_INC] -IDCOM$LIBRARY: - -DRMS_DB "-DOpenVMS_Definitions" "-DPermanentProcess" - -header [.obj]example.h -client none -server none example.idl %DCL-W-TKNOVF, command element is too long - shorten |
$ set command dcom$library:dcom$runshrlib.cld $ midl :== DCOM$RUNSHRLIB DCOM$MIDL_SHR DCOM$MIDL_MAIN $ midl "-Zp8 -Oicf -Os -oldnames -char unsigned",- "-error allocation -error bounds_check -error stub_data",- "-ms_ext -c_ext -out [.OBJ]",- "-I[INC] -I[PROJECT_WIDE_INC] -I[COMMON_INC] -IDCOM$LIBRARY:",- "-DRMS_DB -DOpenVMS_Definitions -DPermanentProcess",- "-header [.obj]example.h -client none -server none example.idl" |
When running MIDL on OpenVMS, you must specify the
-Oicf
MIDL command line switch.
7.2.4 Required Include Directories
MIDL components typically import UNKNWN.IDL , which contains the component definitions for IUnknown and IClassFactory . UNKNWN.IDL and other COM-related IDL and header files are located in DCOM$LIBRARY . To build your component's IDL file, use the following switch:
-IDCOM$LIBRARY: |
The
VMS_DCOM.H
header file contains macro definitions that enable your COM for
OpenVMS application to compile properly with Bristol's Wind/U®
Win32 environment. You must include this header file in every source
file and header file you create that relies on COM APIs or Win32 APIs.
Because the files generated by MIDL rely on parts of the Win32
environment, Compaq has modified the MIDL compiler for OpenVMS to
include
VMS_DCOM.H
in all output files.
7.3 Step 3: Compile the COM Application
The following sections describe how to compile COM for OpenVMS applications.
A COM application developer will need access to the OpenVMS registry to register and control access to a given application. For more information about OpenVMS Registry privileges, see Section 10.5.1 and Section 6.3. |
The VMS_DCOM.H file defines several macros used by the Wind/U Win32 environment. An include statement that specifies this header file should be the first noncommented line in any source file (code or header files) that you write. However, this is not always guaranteed to be true for files generated by MIDL. Be sure to always include the following /DEFINE qualifier on all of your C and CXX commands:
/DEFINE=(UNICODE=1,_WINDU_SOURCE=0X041000,_WIN32_DCOM) |
The UNICODE macro ensures that the wide character variants of Win32 APIs and data structures are enabled when you compile your code. (This macro is also defined in VMS_DCOM.H .) Omitting this macro can lead to compilation failures when building with the Wind/U Win32 environment.
The other two macro definitions are recognized by the Wind/U header
files and are required to ensure the proper definition of structures
and COM APIs.
7.3.2 Required Include Directories
COM for OpenVMS applications typically require header files that come from DCOM$LIBRARY .
Include the following qualifier on your C and CXX command lines:
/INCLUDE=DCOM$LIBRARY |
If you already have an
/INCLUDE
qualifier on your command line, modify the command to include
DCOM$LIBRARY
.
7.3.3 Required Header File: VMS_DCOM.H
The VMS_DCOM.H header file defines several macros used by the Wind/U header files.
Include this header file as the first noncommented line in your source
files (both header files and implementation files).
7.3.4 Required C++ Qualifiers
You must specify the following C++ qualifiers when you build COM for OpenVMS applications:
There are no qualifiers unique to DEC C that you must specify when you
build COM for OpenVMS applications.
7.4 Step 4: Link the COM Application
To build a COM for OpenVMS application, you must build both client and component images. Because you can implement a component as either an in-process component or an out-of-process component, you must build either a shareable image or an executable image, or both. If you are creating a new interface, you must also build a proxy/stub shareable image, unless you are using the IDispatch interface. In that case, the Automation Marshaler will be used instead of the proxy/stub shareable image. The proxy/stub shareable image provides an interface-specific object that packages parameters for that interface in preparation for a remote method call. A proxy runs in the sender's address space and communicates with a corresponding stub in the receiver's address space.
The following sections describe the steps you must follow to link the
client, component, and proxy/stub images.
7.4.1 Linking the Client and the Out-of-Process Component
Although you do not need to specify any qualifiers to link the client or the component executable images, you must link both images with the following:
The specific link-time dependencies are as follows:
If you have one or more C++ modules, use the C++ linker (CXXLINK) instead of the standard OpenVMS linker so you can specify the location of your C++ repository (/CXX_REPOSITORY qualifier). For example:
$ CXXLINK/your-specific-linker-qualifiers list-of-object-modules, - _$ DCOM$WIN32:WINDU.OPT/OPTIONS, DCOM$LIBRARY:DCOM.OPT/OPTIONS - _$ application.OPT/OPTIONS /REPOSITORY=[.CXX_REPOSITORY] |
Other ways of including the options file are as follows:
The component in-process shareable image dependency list differs slightly from that of the client and component executables. The specific link-time dependencies are as follows:
Linking the in-process component shareable image requires that you create a symbol vector for the entry points that COM for OpenVMS expects to call within the shareable image. The Win32 run-time environment enforces a naming standard on the DllMain entry point, which must contain the following:
For example, a component shareable image with the name CMPNT$SHR would define the symbol vector using the following options file:
! ! The list of symbols exported by CMPNT$SHR.EXE. ! SYMBOL_VECTOR=(- _WindU_DllMain_CMPNT$/DllMain = PROCEDURE,- DllGetClassObject = PROCEDURE,- DllCanUnloadNow = PROCEDURE,- DllRegisterServer = PROCEDURE,- DllUnregisterServer = PROCEDURE) |
A component shareable image with the name CMPNT_SHARE would define the symbol vector using the following options file:
! ! The list of symbols exported by CMPNT_SHARE.EXE. ! SYMBOL_VECTOR=(- _WindU_DllMain_CMPNT_SHARE/DllMain = PROCEDURE,- DllGetClassObject = PROCEDURE,- DllCanUnloadNow = PROCEDURE,- DllRegisterServer = PROCEDURE,- DllUnregisterServer = PROCEDURE) |
The proxy/stub shareable image dependency list differs slightly from that of the client and component executables. The specific link-time dependencies are as follows:
Linking the proxy/stub shareable image is more involved because you must create a symbol vector for the entry points that COM for OpenVMS expects to call within the shareable image. The Win32 run-time environment enforces a naming standard on the DllMain entry point, which must contain the following:
For example, a proxy/stub shareable image with the name PROXY$SHR would define the symbol vector using the following options file:
! ! RPC Shareable Image ! SYS$LIBRARY:DCOM$RPCRT4_SHR.EXE/SHARE ! ! ! The list of symbols exported by PROXY$SHR.EXE. ! SYMBOL_VECTOR=(- _Windu_DllMain_PROXY$/DllMain = PROCEDURE,- DllGetClassObject = PROCEDURE,- DllCanUnloadNow = PROCEDURE,- GetProxyDllInfo = PROCEDURE,- DllRegisterServer = PROCEDURE,- DllUnregisterServer = PROCEDURE) |
A proxy/stub shareable image with the name PROXY_SHARE would define the symbol vector using the following options file:
! ! RPC Shareable Image ! SYS$LIBRARY:DCOM$RPCRT4_SHR.EXE/SHARE ! ! ! The list of symbols exported by PROXY_SHARE.EXE. ! SYMBOL_VECTOR=(- _Windu_DllMain_PROXY_SHARE/DllMain = PROCEDURE,- DllGetClassObject = PROCEDURE,- DllCanUnloadNow = PROCEDURE,- GetProxyDllInfo = PROCEDURE,- DllRegisterServer = PROCEDURE,- DllUnregisterServer = PROCEDURE) |
The following sections list and describe the required OpenVMS Registry
entries.
7.5.1 HKEY_CLASSES_ROOT\CLSID
The CLSID subkey contains all CLSIDs for the components supported on your system. You must register your components' CLSIDs here. Each registered CLSID should contain the following:
A class identifier (CLSID) is a globally unique identifier (GUID) associated with an OLE class object. COM for OpenVMS server applications typically register their CLSIDs in the OpenVMS Registry so clients can locate and load the executable code associated with the OLE class object.
Register the CLSID for the component under the subkey HKEY_CLASSES_ROOT\CLSID .
A component CLSID registration should contain the following subkeys:
HKEY_CLASSES_ROOT\CLSID\{GUID}\TYPELIB {value=LIBID} |
The proxy/stub shareable image provides an interface-specific object for packaging parameters for that interface. Because the proxy/stub shareable image contains an object, it needs a CLSID and it needs to be included in the OpenVMS Registry. You must register a CLSID for the proxy in the OpenVMS Registry the same way as the CLSID for the component.
The CLSID for the proxy should be registered under the subkey HKEY_CLASSES_ROOT\CLSID .
A proxy/stub CLSID registration should contain the following subkey:
The Interface subkey contains all interfaces registered with the system. You must register the component's interface IDs (IIDs) in this subkey.
Each interface registered contains at least one of the following subkeys:
As you develop and test COM components, you will find that the OpenVMS and Windows NT systems return seemingly indecipherable error codes. To help you make these codes more understandable, Compaq has included the NTA$VMSGetMessage routine to translate error codes into displayable text.
To implement this routine, you must include the NTA_MESSAGE.H file in the DCOM$LIBRARY: directory and link with the DCOM$LIBRARY:NTA_GETMSG.OBJ object module.
The following section describes the NTA$VMSGetMessage routine.
The NTA$VMSGetMessage routine translates error codes into displayable text. The input error code must be one of the following:
- An OpenVMS error code
- A Windows HRESULT
- A Windows Win32 error code
- A Windows NT status code set as "user defined"
Return=NTA$VMSGetMessage (status, text, flag, [count])
Description This routine uses the OpenVMS SYS$GETMSG system service. The messages are stored in the SYS$MESSAGE:NTAWINMSG.EXE and SYS$MESSAGE:NTARPCMSG.EXE images.status
OpenVMS usage: error_code type: longword (unsigned) access: read only mechanism: by value
This status field must be one of the following:
Input Error Code Example OpenVMS error code 0x074AA6BA Windows HRESULT 0x80070031 Windows Win32 error code 0x00000031 Windows NT status code with the user-defined bit set 0xE74AA6BA If the security API returns a Windows NT status code, the format of the status field is an OpenVMS status code OR'd with the Windows NT status control bits set. For example:
Input Error Code Result OpenVMS error code 0x074AA6BA Windows NT status code 0xE74AA6BA text
OpenVMS usage: error_text type: character string access: write mechanism: by reference
This argument is a NULL terminated string that contains the returned text from the SYS$GETMSG system service. The maximum size returned (as defined by the SYS$GETMSG system service) is 256 bytes. To avoid overwriting memory, the caller must provide a buffer address of at least 257 bytes.flag
OpenVMS usage: flag type: longword (unsigned) access: read only mechanism: by value
Controls the translation of the error code. The following values are defined in NTA_MESSAGE.H:
NTAWIN$_UNKNOWN Unknown error code NTAWIN$_VMS OpenVMS error code NTAWIN$_NT Windows HRESULT error code NTAWIN$_WINDOWS Windows Win32 error code NTAWIN$_USER Windows NT status code If you provide the value NTAWIN$_UNKNOWN, the routine makes its best estimate as to the correct text. The routine parses the text as follows:
- Check for a Windows HRESULT (high-order nibble = 0x8). If this check fails, go to the next step.
- Check for a Windows NT user defined status code (high-order nibble = 0xE). If this check fails, go to the next step.
- Assume this is an OpenVMS error code.
The system cannot tell the difference between an OpenVMS error code and a Windows Win32 error code.count
OpenVMS usage: FAO count type: longword (unsigned) access: write mechanism: by reference
This argument is the optionally returned FAO argument count in the returned message. Currently all NTAWIN messages use ASCII substitution arguments (!AS) only. The caller must convert all numeric data to ASCII before performing the substitution with SYS$FAO.
To call this routine, you must include the NTA_MESSAGE.H file in the DCOM$LIBRARY: directory and link with the SYS$LIBRARY:DCOM$WIN32_SHR shareable image.
Any status from the SYS$GETMSG system service.For more information about the SYS$GETMSG system service, see the OpenVMS System Services Reference Manual.
Authentication is the act of verifying a user's identity by the computer system before permitting access to the system. After successfully authenticating a user, the system binds the user's authorization information to the user's process in the form of credentials. The system uses these credentials to determine whether to grant or deny access to system resources.
OpenVMS provides both native (SYSUAF-based) and Windows NT-compatible authentication and authorization capabilities as follows:
After OpenVMS successfully authenticates a user (either native or
Windows NT), OpenVMS attaches the user's native credentials to the
process using a structure known as a persona. If the system
used Windows NT for authentication, OpenVMS also attaches the user's
Windows NT credentials to the process (as an extension to the
persona).
8.2 Acquiring Windows NT Credentials Using NTA$LOGON
NTA$LOGON is a utility that allows you to acquire NTLM credentials. All processes that need Windows NT security to access the OpenVMS Registry or COM for OpenVMS facilities require NTLM credentials.
You must provide NTA$LOGON with a user account name, a password, and (if required) a domain name. NTA$LOGON uses the Authentication and Credential Management (ACM) Authority to contact the domain controller and acquire a Windows NT access token. NTA$LOGON merges the Windows NT information with the user's OpenVMS credentials.
For a detailed review of NTA$LOGON dependencies and a description of how NTA$LOGON interacts with other parts of the OpenVMS infrastructure, see Section 5.1 and Section 4.8 (especially the ACME server and Advanced Server for OpenVMS server).
To use the NTA$LOGON utility, you can enter any of the following:
$ RUN SYS$SYSTEM:NTA$LOGON |
$ NTLOGON :== $NTA$LOGON $ NTLOGON |
$ MCR NTA$LOGON |
Table 8-1 shows the NTA$LOGON utility command line parameters.
Argument | Value | Required/Optional |
---|---|---|
P1 | User account name. If an account name is needed but was not specified on the command line, NTA$LOGON prompts for input. | Optional |
P2 | Password. If a password is needed but was not supplied on the command line, NTA$LOGON prompts for input (echoing suppressed). | Optional |
Example 8-1 shows a typical NTA$LOGON session to acquire credentials.
Example 8-1 Sample NTA$LOGON Session |
---|
$ NTLOGON :== $NTA$LOGON $ NTLOGON joesmith Password: |
Windows NT domain names and user account names are not case sensitive. NTA$LOGON converts all domain names and user account names to uppercase. If you specify a password on the command line, DCL converts all characters to uppercase, unless you enclose the password in quotation marks (""). |
NTA$LOGON accepts the following optional qualifiers:
DCE$COMMON:[000000]NTA$LOGON.DAT |
DCE$COMMON:[000000]NTA$LOGON.DAT |
The /READ_FILE and /WRITE_FILE qualifiers are intended to be used only by servers that have no other way to acquire Windows NT credentials to access the OpenVMS Registry or COM for OpenVMS facilities. Compaq does not recommend general use of the /READ_FILE and /WRITE_FILE qualifiers. Once you have written a password into a disk file, Compaq recommends you take strong precautions to protect the password file from unauthorized access. |
Example 8-2 shows how a user acquires NT credentials for the first time.
Example 8-2 Acquiring Windows NT Credentials for the First Time |
---|
$ NTLOGON :== $NTA$LOGON $ NTLOGON/LIST ERROR: NtOpenProcessToken() failure: -1073741700 0xc000007c %SYSTEM-E-NOSUCHEXT, no such extension found $ NTLOGON/LOG JOESMITH [Persona #1 NT extension: Account= "JOESMITH" Domain= "NT_DOMAIN" ] Password: |
Example 8-3 shows how the user replaces the Windows NT credentials.
Example 8-3 Replacing Windows NT Credentials |
---|
$ NTLOGON/DELETE $ NTLOGON/OVERRIDE_MAPPING/DOMAIN=OTHER_DOMAIN Username: janebrown Password: |
Example 8-4 shows how a user saves a password in a disk file. The system requests that the user enter the password twice with echoing suppressed.
Example 8-4 Saving a Password to a File |
---|
$ NTLOGON :== $NTA$LOGON $ NTLOGON/WRITE_FILE=DEV:[DIR]NTA$LOGON.DAT COM_SERVER Password: Confirm: $ NTLOGON/READ_FILE=DEV:[DIR]NTA$LOGON.DAT/LIST File DEV:[DIR]NTA$LOGON.DAT contains the following records: 02-MAR-1999 16:57:23.20 COM_SERVER |
After you have created this file, you can add the following to a DCL command procedure:
$ NTLOGON :== $NTA$LOGON $ NTLOGON/READ_FILE=DEV:[DIR]NTA$LOGON.DAT COM_SERVER |
The Authentication and Credential Management authority authenticates users and determines the user security profile for OpenVMS and Windows NT. The ACME_SERVER process provides these ACM services. The ACME_SERVER process uses plug-in modules called ACME agents. ACME agents perform the actual work of responding to authentication requests, query requests, and event requests.
The OpenVMS ACME agent (VMS$VMS_ACMESHR.EXE) provides OpenVMS native services. The MSV1_0 ACME agent (PWRK$MSV1_0_ACMESHR.EXE, an Advanced Server for OpenVMS product component) provides Windows NT connectivity services.
The MSV1_0 ACME agent forwards Windows NT connectivity service requests from NTA$LOGON and SSPI/NTLM to an Advanced Server for OpenVMS process running on one or more systems in the cluster. The PWRK$ACME_SERVER logical name can contain a comma-delimited list of cluster node names to which the MSV1_0 ACME can forward requests. Running the Advanced Server for OpenVMS process on more than one cluster node and including the node names in the PWRK$ACME_SERVER logical name allows the MSV1_0 ACME agent to fail over a request automatically if a connection is interrupted. If the logical name is undefined, the system defaults to the local machine name.
The ACME_SERVER process must be present on any system running RPC or
COM for OpenVMS. However, the Advanced Server for OpenVMS process needs to
be present on only one node in the cluster.
8.3.1 Windows NT Authentication on OpenVMS
Because the ACME_SERVER returns to its callers a complete OpenVMS persona with the requested attached Windows NT persona extension, the VMS ACME agent enforces the following rules:
To start the ACME_SERVER process and configure the MSV1_0 ACME agent at system startup, add the following entry to SYLOGICALS.COM:
$ DEFINE NTA$NT_ACME_TO_BE_STARTED YES |
You can also start the ACME_SERVER process manually using the following startup command file:
$ @SYS$STARTUP:NTA$STARTUP_NT_ACME |
To shut down ACME_SERVER, enter the following command:
$ SET SERVER ACME/EXIT |
If an abnormal condition in an ACME agent prevents a normal server shutdown, use the /ABORT qualifier in the place of the /EXIT qualifier to force the ACME_SERVER to terminate.
To turn on ACME_SERVER logging, enter the following command:
$ SET SERVER ACME/LOG |
This command creates a ACME$SERVER.LOG file in the SYS$MANAGER directory. You might find this file useful when you are trying to diagnose potential problems.
To display the ACME_SERVER configuration information, enter the following command:
$ SHOW SERVER ACME[/FULL] |
Table 8-2 lists and describes systemwide logical names you can use to control certain features of the MSV1_0 ACME agent.
Logical name | Description |
---|---|
PWRK$ACME_SERVER | Comma-delimited list of cluster SCS node names that are running Advanced Server for OpenVMS processes that can service Windows NT connectivity requests. If you do not define the node names, the MSV1_0 ACME agent tries to connect to the Advanced Server for OpenVMS process on the local system. |
PWRK$ACME_RETRY_COUNT | The maximum number of retry attempts the MSV1_0 ACME agent performs when connecting to an Advanced Server for OpenVMS process. The default value is 10. |
PWRK$ACME_RETRY_INTERVAL |
The number of tenths of seconds between retry attempts. The default is
2.5 seconds.
|
ATL (Active Template Library) is a set of template-based C++ classes from Microsoft that simplify the development of COM components. ATL provides support for key COM features, such as stock implementations of IUnknown, IClassFactory, IDispatch, dual interfaces, and connection points. It also provides support for more advanced COM features, such as enumerator classes and tear-off interfaces.
The ATL COM AppWizard and ATL Object Wizard in Microsoft Visual Studio can be used to quickly create code for simple COM objects that can be copied to OpenVMS systems and built with very few modifications.
The COM for OpenVMS ATL is based on Microsoft ATL Version 3.0. You must be running COM Version 1.1-B for OpenVMS or higher. ATL on OpenVMS Alpha Version 7.2-1 requires Compaq C++ Version 6.2-016 or higher.
COM for OpenVMS provides ATL as source code in header files that you include in your application.
Table 9-1 shows the differences between the ATL implementation on Windows NT and OpenVMS.
Implementation | Windows NT | OpenVMS |
---|---|---|
Interface | GUI | Character cell |
Server models | Single threaded or multithreaded | Multithreaded only |
ATL available as DLL | Yes (not required) | No |
Application registration | Automatic using UpdateRegistryFromResource function in ATLBASE.H | Automatic using UpdateRegistryFromFile function in ATLBASE.H |
ATL component types |
In-process as DLL
Out-of-process as EXE |
In-process as shareable image
Out-of-process as an executable image |
The following sections describe how to create a COM for
OpenVMS application using ATL.
9.2.1 Step 1: Create the ATL Component in Microsoft Visual Studio
Generate the code using the Microsoft Visual Studio ATL COM AppWizard. For information about using the ATL COM AppWizard, see the Microsoft Developer Network (MSDN) documentation.
Copy the generated files to OpenVMS. For example, copy the files using File Transfer Protocol (FTP) in ASCII mode. Table 9-2 lists and describes the files that the ATL COM AppWizard would generate for a project named mycomapp .
File name | Description | Platform | In-Process or Out-of-Process |
---|---|---|---|
mycomapp.cpp | Contains the implementation of DllMain, DllCanUnloadNow, DllGetClassObject, DllRegisterServer and DllUnregisterServer. Also contains the object map, which is a list of the ATL objects in your mycomapp. This is initially blank, because you have not created an object yet. | Windows NT/OpenVMS | Both |
mycomapp.def |
The standard Windows module definition file for the DLL.
Note: MYCOMAPP.DEF becomes MYCOMPAP$SHR.OPT on OpenVMS. |
Windows NT | In-process |
mycomapp.dsw | The mycomapp workspace. | Windows NT | Both |
mycomapp.dsp | The file that contains the mycomapp settings. | Windows NT | Both |
mycomapp.idl | The interface definition language file, which describes the interfaces specific to your objects. | Windows NT/OpenVMS | Both |
mycomapp.rc | The resource file, which initially contains the version information and a string containing the mycomapp name. | Windows NT | Both |
Resource.h | The header file for the resource file. | Windows NT/OpenVMS | Both |
mycomappps.mk | The make file that can be used to build a proxy/stub DLL. You do not need this file. | Windows NT | Proxy/stub |
mycomapps.def |
The module definition file for the proxy/stub DLL.
Note: MYCOMAPPPS.DEF becomes MYCOMAPPPS$SHR.OPT on OpenVMS. |
Windows NT | Proxy/stub |
StdAfx.cpp | The file that will include the ATL implementation files. | Windows NT/OpenVMS | Both |
StdAfx.h | The file that will include the ATL header files. To make the mycomapp DLL useful, you need to add a control, using the ATL Object Wizard. | Windows NT/OpenVMS | Both |
mycomapp.rgs | A registrar script for your COM server. | Windows NT/OpenVMS | Both |
myinterface.rgs | A registrar script for your COM server. | Windows NT/OpenVMS | Both |
myinterface.cpp | The interfaces specific to your object. | Windows NT/OpenVMS | Both |
myinterface.h | The header file for the interfaces. | Windows NT/OpenVMS | Both |
Make the following changes to the generated files before you build ATL
applications on OpenVMS.
9.2.2.1 Remove _ATL_MIN_CRT
When the ATL COM AppWizard generates
mycomapp
, it also defines the macro
_ATL_MIN_CRT
as part of the GUI support. Because OpenVMS does not have a graphical
interface, you must remove (or not define)
_ATL_MIN_CRT
when you build on OpenVMS.
9.2.2.2 Include ATLMAIN.CXX
On OpenVMS, you must include ATLMAIN.CXX for out-of-process components.
ATLMAIN.CXX defines the wWinMain() function.
9.2.2.3 Modify Registration Procedure
OpenVMS does not support registering the application using the UpdateRegistryFromResource function. You must use the OpenVMS UpdateRegistryFromFile function in the ATLBASE.H header file. You must make the necessary changes to your application. The following table shows the changes you must make.
File to search | Search for | Replace with |
---|---|---|
Interface header file | DECLARE_REGISTRY_RESOURCEID | DECLARE_REGISTRY_FILE |
Project source file | _Module.UpdateRegistryFromResource | _Module.UpdateRegistryFromFile |
The following example shows sample coding changes.
#ifdef __vms DECLARE_REGISTRY_FILE(_T("MYINTERFACE.RGS")) #else DECLARE_REGISTRY_RESOURCEID(IDR_MYINTERFACE) #endif #ifdef __vms _Module.UpdateRegistryFromFile(_T_"MYCOMAPP.RGS"), TRUE); #else _Module.UpdateRegistryFromResource(IDR_MYCOMPAPP, TRUE); #endif |
This process is the same as shown in Section 7.2.
For example (in-process):
$ MIDL :== $DCOM$MIDL.EXE $ MIDL -nologo -Oicf mycompapp.idl - -IDCOM$LIBRARY - -iid mycompapp_i.c - -proxy mycompapp_p.c - -dlldata dlldata.c - -tlb mycompapp$shr.tlb |
For example (out-of-process):
$ MIDL :== $DCOM$MIDL.EXE $ MIDL -nologo -Oicf mycompapp.idl - -IDCOM$LIBRARY - -iid mycompapp_i.c - -proxy mycompapp_p.c - -dlldata dlldata.c - -tlb mycompapp.tlb |
Compaq recommends that the name of your type library match the name of
your executable or shareable image.
9.2.4 Step 4: Compile the ATL COM Application
The following sections describe how to compile COM for OpenVMS
applications.
9.2.4.1 Required Header File: ATLBASE.H
The
VMS_ATL.H
header file defines several macros used by the Wind/U header files.
VMS_ATL.H
is already included in the
ATLBASE.H
header file. When creating ATL source code, you must include
ATLBASE.H
as the first noncommented line in your source (both header and
implementation) files.
9.2.4.2 Required Macro Definitions
Include the following /DEFINE qualifier on all of your C and CXX commands:
/DEFINE=(UNICODE=1,_WINDU_SOURCE=0X041000,_WIN32_DCOM,_ATL_STATIC_REGISTRY) |
The UNICODE macro ensures that wide-character variants of Win32 APIs and data structures are enabled when you compile. (The UNICODE macro is also defined in VMS_DCOM.H.) If you omit the UNICODE macro, your compile fails when you build using the Wind/U Win32 environment.
The other two macro definitions are recognized by the Wind/U header files and are required to ensure the proper definition of structures and COM APIs.
The
_ATL_STATIC_REGISTRY
macro enables you to statically link with the ATL registry component (
Registrar
) for optimized Registry access. You can add the macro either by
including the /DEFINE qualifier on the command line or by adding the
stdafx.h header file to your code.
9.2.4.3 Required Include Directories
COM for OpenVMS applications typically require header files that come from DCOM$LIBRARY . The ATL header files and source files are also located in DCOM$LIBRARY .
Include the following qualifier on your C and CXX command lines:
/INCLUDE=DCOM$LIBRARY |
If you already have an
/INCLUDE
qualifier on your command line, modify the command to include
DCOM$LIBRARY
.
9.2.4.4 Required C++ Qualifiers
You must specify the following C++ qualifiers when you build COM for OpenVMS applications:
To build a COM for OpenVMS application, you must build both client and component images. Because you can implement a component as either an in-process component or an out-of-process component, you must build either a shareable image or an executable image, or both.
The following sections describe the steps you must follow to link the
client, component, and proxy/stub images.
9.2.5.1 Linking the Client and the Out-of-Process Component
Although you do not need to specify any qualifiers to link the client or the component executable images, you must link both images. The specific link-time dependency is as follows:
If you have one or more C++ modules, use the C++ linker (CXXLINK) instead of the standard OpenVMS linker so you can specify the location of your C++ repository (/CXX_REPOSITORY qualifier). For example:
$ CXXLINK/your-specific-linker-qualifiers list-of-object-modules, - _$ DCOM$LIBRARY:DCOM.OPT/OPTIONS, application.OPT/OPTIONS - _$ /REPOSITORY=[.CXX_REPOSITORY] |
You can also include the list of object modules in an options file
instead of on the command line.
9.2.5.2 Linking the In-Process Component Shareable Image
The in-process component shareable image dependency list differs slightly from that of the client and component executables. The specific link-time dependencies are as follows:
Use the procedure described in Section 7.4.2.1 to create a symbol vector for the in-process component shareable image.
Use the procedure described in Section 7.4.3 to create a symbol vector
for the proxy/stub shareable image.
9.3 ATL Samples
TESTATL is an out-of-process sample, and MATH101 is an in-process sample.
You can find the sample ATL applications shown in this chapter in the following directories on the COM for OpenVMS kit:
DCOM$EXAMPLES:[TESTATL_OUTPROC] DCOM$EXAMPLES:[TESTATL_INPROC] |
If you are running authenticated COM, before you build the application on OpenVMS, you must run NTA$LOGON and acquire Windows NT credentials. For more information, see Section 8.2. |
This sample implements a COM client and server in which the component provides one interface: ISum .
Given sources initially generated by the Microsoft Visual Studio ATL AppWizard and a few applied changes, the sample demonstrates the build, registration, and execution of the ATL application on OpenVMS.
The following sections describe how to create the application using the
Microsoft ATL AppWizard on Windows NT and how to build the
application on an OpenVMS system.
9.3.1.1 Creating the Application on Windows NT
Use the following guidelines when generating a skeleton project and simple objects using the Microsoft Visual Studio ATL AppWizard.
A README file describes how to build, register, and run this COM for OpenVMS sample. The file is located in:
DCOM$EXAMPLES:[TESTATL_OUTPROC]README-TESTATL_OUTPROC.TXT |
This sample implements a COM client and server in which the component provides three interfaces: ISum, IDiv, and IMul.
Given sources initially generated by the Microsoft Visual Studio ATL AppWizard, the sample demonstrates the build, registration, and execution of the shareable application on an OpenVMS system.
The following sections describe how to build the application.
9.3.2.1 Creating the Application on Windows NT
Use the following guidelines when generating a skeleton project and simple objects using the Microsoft Visual Studio ATL AppWizard.
A README file describes how to build, register, and run this COM for OpenVMS sample. The file is located in:
DCOM$EXAMPLES:[TESTATL_INPROC]README-TESTATL_INPROC.TXT |
The following resources can provide you with more information about ATL:
www.microsoft.com/com |
Previous | Next | Contents | Index |