Version 8.0
 —  DCOM  —

EntireX DCOM Software Development Kit (SDK)

The SDK is a collection of tools and libraries which enable the DCOM developer to build DCOM applications.

This document covers the following topics:


SDK Tools

General Comments

The following differences between DOS and UNIX command syntax apply in general when using a utility with command-line input:

  DOS UNIX
Command switch / -
Input redirection @ (unavailable)
Command arguments midl -? midl -\?

The command switch / (slash) is permitted on UNIX but its use is not recommended. Use "-" (hyphen) instead.

All command arguments have to follow the UNIX shell rules (i.e. quoting, escape characters, wildcards, regular expressions). For example, midl -? does not work with the C shell, so you have to use midl -\? or midl -? (Bourne-compatible shells do not have this problem).

uuidgen

This is the uuidgen utility from Windows with some enhancements to implement functionality found in the guidgen graphical Windows utility.

For more information on how to use uuidgen please consult the Microsoft documentation: RPC Programmer's Guide and Reference - MS Win32 Software Development Kit. Alternatively, look at the online documentation that comes with the MS C/C++ Compiler in the MS Developer Studio. OSF/DCE supply a version of uuidgen, so be sure to use the correct one.

The uuidgen utility (or rather, the RPC library function which uses it) looks up the registry for the MAC (Medium Access Control) address of your NIC (network interface card) as an input parameter for the UID generation. If there is no information in the registry, the uuidgen utility will try to get the hardware address information at runtime and then insert it into the registry automatically for permanent use.

General help information can be found in the uuidgen help pages (activated by uuidgen -help) and the existing Microsoft documentation for uuidgen.

The EntireX DCOM uuidgen utility is based on version 1.00 of uuidgen on Windows. EntireX DCOM specific version information is available in the signature (i.e. with uuidgen -v).

guidgen

In EntireX DCOM, guidgen is an extension to the uuidgen utility. In effect, guidgen is a copy of the uuidgen utility. It is provided for convenience since most people use this utility instead of uuidgen.

For more information on how to use guidgen, consult the Microsoft documentation: RPC Programmer's Guide and Reference - MS Win32 Software Development Kit. Alternatively, look at the online documentation that comes with the MS C/C++ Compiler in the MS Developer Studio.

EntireX DCOM's version of the guidgen utility is based on the version 1.00 of uuidgen on Windows. EntireX DCOM specific version information is available in the signature (i.e. with uuidgen -v).

makedef

The makedef utility is a Bourne shell script provided to compile Windows specific ".def" files. The utility generates a C++ module that has to be compiled and linked into your shared library in order to make it loadable using the Windows LoadLibrary() and GetProcAddress() functions. You can use C preprocessor statements (e.g. #include, #if, #ifdef, #else, #endif) to make makedef conditionally parse blocks of the DEF file.

Usage:

makedef [-RCTAB] [-D<string>] [-U<string>] [-E<entrypoint>] [-I<includepath>] def_file  output_file

Parameters:

midl

EntireX DCOM provides an implementation of the Microsoft Interface Definition Language compiler MIDL. Refer to the Microsoft documentation: RPC Programmer's Guide and Reference - MS Win32 Software Development Kit for a full description of MIDL. To avoid duplication, only a brief summary is provided here. Alternatively, look at the online documentation that comes with the MS C/C++ Compiler in the MS Developer Studio.

Temporary files are created with the tmpnam() standard library function. Refer to your manual page for tmpnam() to get information on the directory used for temporary files. Names of temporary files start with MID. They are removed automatically by MIDL after compilation.

There are no specific error codes, other than the ones documented by Microsoft.

Help information can be found in the midl help pages (activated by midl -help) and the existing Microsoft documentation for MIDL.

Sample IDL files are delivered with the EntireX DCOM SDK.

There is no dependency on the registry that is provided with EntireX DCOM.

The EntireX DCOM implementation of MIDL is based on the version 5.03.0279 of MIDL on Windows. EntireX DCOM-specific version information is available in the signature.

mktyplib

This is a type library generation tool for automation. The EntireX DCOM version of mktyplib is based on version 2.0.0 of mktyplib on Windows. EntireX DCOM-specific version information is available in the signature.

There are no error codes specific to EntireX DCOM, other than the ones documented by Microsoft.

Help information can be found in the mktyplib help page (activated by mktyplib -help) and existing Microsoft documentation for mktyplib.

Coolmc

Coolmc is the EntireX DCOM version of the Windows mc (message compiler) utility. It is used to compile message files containing application-specific messages which can be retrieved from the application by calling a WIN 32 API. Currently, coolmc supports only one language, English.

The syntax of the message file must follow the rules as it does for Windows.

Usage:

coolmc <message-file> 

, e.g. coolmc xyz.mc

This call to coolmc will produce three output files xyz.rc, xyz.h and a binary file with the extension ".bin" (the file name is generated according to the rules on Windows systems).

The file xyz.h will contain macros which define the error number as hexadecimal values (generation of decimal error numbers is not supported).

The file xyz.rc only contains the name of the binary file plus the language definition.

The binary file *.bin contains the message table in an internal, binary format.

The header file xyz.h can be included in your source code to provide the application with the macros for the messages.

If you already have a resource file in your application, include the xyz.rc file in that resource file.

If you do not have any resource file, add the following two lines to your makefile:

$(OBJDIR)/xyz_rc.cxx: xyz.rc
makerc $(C_DEFINES) $(C_INCLUDES) xyz.rc $@

and add xyz_rc.cxx to the list of files to be compiled for your application.

To be able to retrieve messages from a shared library, you must use a ".def" file for the shared library. See the description of makedef, above. You need an additional parameter, -RCTAB, for the makedef call.

In your application you can retrieve these messages using the FormatMessage API.

Top of page

Header Files

The SDK contains a set of header files (Microsoft headers ported to non-Windows platforms as well as headers provided by Software AG) for inclusion in source files for compilation. The header files are located in the directory $EXXDIR/$EXXVERS/sdk/include.

Top of page

Active Template Library

This kit includes an implementation of the Microsoft Active Template Library (ATL) version 3.0. The ATL version provided does not support default template arguments, because these are not supported by the compilers available on the EntireX DCOM platforms.

ATL servers generated by the Microsoft Developer Studio's AppWizard will use calls to GetMessage(), DispatchMessage() and PostQuitMessage() to control the lifetime of the server. EntireX DCOM supports only restricted versions of these Windows API calls. Alternatively, you can use a Win32 Event to signal process shutdown.

Refer to the ATL Program Porting Guide for a description of how to port Active Template Library (ATL) applications from Windows to EntireX DCOM platforms.

Top of page

Component Object Pool

Motivation

It is sometimes undesirable when COM objects maintaining resources which are expensive to create, are shut down as soon as there are no more references to that object. Providing an object pool holding ready-to-use objects for clients to retrieve and put back, and keeping them alive over a period of idleness improves this situation.

Description

The component object pool provides the following services to client applications:

Installation

The object pool is delivered as an executable objpool and a type library objpool.tlb and is installed into the EntireX binary directory. Before it is used for the first time, the object pool needs to be registered with:

$ objpool -RegServer

The object pool is normally a long-running task. It should thus be started as a daemon, either using the daemon starter utility ntwopper:

$ ntwopper -nowait objpool

or by adding it to the list of processes to be started up automatically by the ntd daemon (see COOL_NTD_INIT_COMMAND and COOL_NTD_INIT_START in the dcomconfig file.)

When no object pool instance is running and a client application creates one, the object pool terminates as soon as there are no more objects kept alive in the pool.

The object pool can be unregistered with:

$ objpool -UnregServer.

The IObjPool Interface

The object pooling object provides a dual interface (both dispatch and vtable) interface IObjPool which contains methods to:

Method Descriptions

Method Description Parameters Return Codes
CreateObject
HRESULT CreateObject(
  [in] BSTR wszClsid,
  [out] LONG *dwReg
  [out, retval] IUnknown **pUnk,
);
Creates an object in the pool or returns an interface pointer to an existing, free object.
wszClsid a BSTR containing the string representation of the CLSID or the ProgID of the class to be instantiated. The format of the CLSID is {xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}.
dwReg a pointer to a LONG value to receive an identifier for the created object
pUnk a pointer to an interface pointer to receive a reference to the desired object
CreateObject uses CoCreateInstanceEx to create new objects. If this function fails, CreateObject passes the errorcode returned to the caller.
ReleaseObject
HRESULT ReleaseObject(
  [in] LONG dwReg
);
Releases an object previously created in the pool (marks it as unused).
dwReg a LONG value (received from CreateObject) which identifies the object to be released.
If the object identified by dwReg cannot be found in the pool, E_FAIL is returned.
AddObject
HRESULT AddObject(
  [in] BSTR wszClsid,
  [in] IUnknown *pUnk,
  [out] LONG *dwReg
);
Adds an object created by the caller to the pool.
wszClsid a BSTR containing the string representation of the CLSID or the ProgID of the class to be instantiated. The format of the CLSID is {xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}.
pUnk an IUnknown interface pointer to the object to be added to the pool.
dwReg a pointer to a LONG value to receive an identifier for the added object
 
SetIdleMax
HRESULT SetIdleMax(
  [in] LONG dwReg,
  [in] LONG maxIdleCount
);
Sets the maximum idle period of an object in the pool.
dwReg a LONG value (received from CreateObject) which identifies the object for which the idle time is to be changed
maxIdleCount the maximum number of ticks (one tick is a time period of approximately 10 seconds) an object is kept alive in the pool. The default value is 2.
 
Status
HRESULT Status(
  [in, out] BSTR * bstrBuffer
);
Requests that the server print the status of the pool.
bstrBuffer pointer to a BSTR buffer to receive the status of the pool. bstrBuffer may contain a file name, in which case the objpool server writes its status into this file (on the machine it is running on.
If the client is remote, it cannot access this file directly.
 

Limitations

The current implementation of the object-pooling object has some limitations:

Example Application

Directories and files:

proxy: The Interface description of the server. Used to generate a type library.
client: A Test client. Uses the clerksrv example server for testing.

Start of instruction setTo build

  1. Change to $EXXDIR/$EXXVERS/examples/dcom/objpool

  2. $ make

Start of instruction setTo register the objpool server

Start of instruction setTo run the example client

  1. Build and register $EXXDIR/$EXXVERS/examples/dcom/rental

  2. $ objpoolcl

Top of page

Building DCOM Applications

The following sections provide a brief description of compiling and linking EntireX DCOM applications. The flag settings for the C and C++ compilers for compiling and linking DCOM applications, together with the flag settings necessary for running the MIDL compiler, are in the central makefile in $EXXDIR/$EXXVERS/sdk/samples/make/makefile.incl.

Please refer to the distribution kit for examples of how to build DCOM applications.

Compiling and Linking

Flag Settings

There are two mandatory preprocessor symbols which must be defined to the C, C++ and MIDL compilers in order to build EntireX DCOM applications correctly. These symbols are

Platform Value
AIX CE_TAIX
HP-UX (32 bit) CE_THP9000S800
HP-UX (64 bit) CE_THPUX11_64
Sun Solaris (32 bit) CE_TSUNSOL2
Sun Solaris (64 bit) CE_TSUNSOL7_64
Linux CE_TLINUX86
Linux IA64 (64 bit) CE_TLINUXIA64

For the complete list of the flag settings, please refer to makefile.incl and the sample makefiles.

Processing DEF Files

DEF (shared library definition) files are processed with the makedef utility, which generates C++ files. See the description of the makedef utility in the section SDK Tools above. The C++ files are then compiled to produce .o files, which are then linked to create DLLs (called shared libraries on UNIX systems). The DLLs created on UNIX systems export all symbols (on Windows systems, the symbols in a DLL can be exported selectively).

Generating Proxy/Stub Libraries (DLLs)

Start of instruction setTo generate a proxy/stub library

  1. Write an IDL file which specifies the object and interfaces.

  2. Write a DEF file specifying the library's name which exports at least DLLRegisterServer, DllUnregisterServer, DllCanUnloadNow, DllGetClassObject.

  3. Ensure that the name of the DLL as specified in the DEF file for LIBRARY is the same as the base name of the DLL itself. Thus, for example, if you specify "LIBRARY footest", the library must be named libfootest.so.

  4. Run midl on the IDL file to generate the header, *_i.c, *_p.c and dlldata.c files.

  5. Compile the MIDL-generated C files (and additional ones if present).

  6. Make sure that -DREGISTER_PROXY_DLL and -DCOBJMACROS preprocessor definitions are passed to the compiler when compiling the generated C files.

  7. Link the generated objects to the proxy stub DLL (together with the additional link libraries ole32 and rpcrt4).

  8. Register the generated proxy stub DLL by executing regsvr <path>/<libname>.

Compiling IDL Files

Refer to the MIDL sections in this documentation and to Microsoft's documentation for details on using the MIDL compiler.

Top of page

Using DCOM with Firewalls

For more detailed information see also Michael Nelson's article Using Distributed COM with Firewalls, at: http://www.microsoft.com/com/wpaper/dcomfw.asp.

Network Address Translation

DCOM clients must be able to reach the DCOM server at its actual IP address. It is not possible to access the DCOM server through firewalls that translate the network address. This is due to the fact that the IP address of the server machine is stored in the marshalling packets, which is used by the client to establish a TCP/IP connection.

To enable DCOM to send out the translated Network Address within the marshalling packets to remote DCOM clients, make the following entries in the server machine's registry.

Create the registry key:

HKEY_LOCAL_MACHINE\SOFTWARE\Software AG\EntireX\DCOM\NetworkAddressTranslation

with a MULTI_SZ value named "TranslationList" and define as value the IP address behind (intranet) and in front of (internet) the firewall separated by an equal sign. These settings must correspond to the network address translation of the firewall system.

Example:

If the server IP address behind the firewall were 192.25.192.1 and in front of the firewall 199.166.2.10, the MULTI_SZ values in hex ASCII would be

REGEDIT4
[HKEY_LOCAL_MACHINE\SOFTWARE\Software AG\DCOM\NetworkAddressTranslation]
"TranslationList"=hex(7):31,39,32,2e,32,35,2e,31,39,32,2e,31,3d,\ 31,39,39,2e,31,36,36,2e,32,2e,31,30,00,00

Restricting the Range of TCP Ports

In contrast to other internet applications, by default DCOM dynamically assigns TCP ports in a range between 1024 and 65535. For security reasons firewall systems are usually configured to restrict the range of ports available. Thus, the port range of DCOM must be restricted as well. This is done with the following registry settings:

Create a registry key:

HKEY_LOCAL_MACHINE\Software\Microsoft\Rpc\Internet

with the values: REG_MULTI_SZ Ports one port range per line
REG_SZ PortsInternetAvailable always set to Y
REG_SZ UseInternetPorts Y | N

Example:

Restrict the DCOM port range to the ports 7778 and 7779 (the MULTI_SZ values are given in hex ASCII below).

REGEDIT4
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Rpc\Internet]
"Ports"=hex(7):37,37,37,38,00,37,37,37,39,00,00,00
"PortsInternetAvailable"="Y"
"UseInternetPorts"="Y"

Top of page

Writing DCOM Applications with your own main() Function

DCOM Applications need to perform some basic initialization steps for the WIN32 subsystem (Windows daemon ntd and mutant library) before using any WIN32 APIs. This initialization can be achieved in two ways:

Using CoolMain()

Use CoolMain() as the application's main function, in which case the real main() function is taken from the libmutantstubs.a library. This default main() function performs all the necessary initializations, calls CoolMain() and when this function returns, performs all of the necessary de-initializations.

Example:

#ifdef SAG_COM
#include <coolmain.h>
int CoolMain(int argc, char *argv, char **envp)
#else
int main(int argc, char *argv, char **envp)
#endif
{
  ...
}

Using your own main() function

Define a main() function of your own which initializes the WIN32 subsystem prior to calling any WIN32 APIs by calling CoolMainInit(); de-initialize it by calling CoolMainExit() before returning from main().

Example:

#ifdef SAG_COM
#include <coolmain.h>
#endif


int main(int argc, char *argv, char **envp)
{
#ifdef SAG_COM
   CoolMainInit(argc, argv, envp);
#endif
   ...
#ifdef SAG_COM
   CoolMainExit();
#endif
   return ...;
}

Top of page

Linking DCOM Applications without a C++ Compiler

The default makefile template $EXXDIR/$EXXVERS/include/makefile.incl delivered with the EntireX DCOM SDK uses the C++ Compiler driver to link DCOM binaries (executables as well as shared libraries). If no C++ compiler is installed on your system, it is still possible to build and link DCOM applications by using the C compiler driver even though the DCOM libraries are built with the C++ compiler. The C++ runtime libraries must be added to the list of link libraries.

Note:
The following restrictions apply under HP-UX 11 32-bit

Top of page