Figure 4    COM Services on Unix

COM Service Description
Remote Procedure Call (RPC) Underlying wire protocol used by COM.
Service Control Manager (SCM) Automatically loads COM servers either in the client's process for in-process activation or in a designated host process for out-of-process activation.
Monikers Objects that contain the location of and bind to another object. For example, you can use composite monikers to navigate through object hierarchies using a simple text file path.
Windows NT registry Local file-based system database that COM uses to map CLSIDs to file names of COM objects (for local activation) or remote computer names (for remote activation).
OLE Automation Allows an object to expose a set of properties and methods to another object.
Microsoft Interface Definition Language (MIDL) compiler Compiler that processes Interface Definition Language (IDL) files to produce application type libraries and headers. COM classes are defined in IDL in order to provide a language-neutral description of the data types exported by the server.
Structured storage Storage-related interfaces that allow you to use a structured collection of storage (directories) and streams (files) to handle a single file-system entity. This saves you from using a single file handle for manipulating a single file-system entity.
Uniform Data Transfer Allows all types of data transfer to be performed by a single data object. The data source chooses the best mode of transfer (such as compound files versus global memory).
NTLM security Windows NT security in which the server process challenges the client process. The client process returns a response (an encryption of the challenge). The server encrypts the original challenge and compares the response to the encrypted challenge. If the client process response matches the original challenge encryption, the client process is authenticated. See the sidebar "Windows NT Security on Unix" for more details.
Win32 API (non-GUI only) The application programming interface for Windows.
Active Template Library (ATL) Templates that facilitate building Win32-based applications.


Figure 5   COM Conformance Test Suite Categories

Test Suite Category APIs Tested
Memory CoTaskMemAlloc, CoTaskMemFree, CoTaskMemRealloc
Object Instantiation and Class Factory CoCreateInstance, CoCreateInstanceEx, CoGetClassObject, CoRegisterClassObject, CoRevokeClassObject, CoAddRefServerProcess, CoReleaseServerProcess, CoSuspendClassObjects, CoResumeClassObjects
Miscellaneous CoLoadLibrary, CoFreeLibrary, CoCreateGuid, CoFreeAllLibraries, CoFreeUnusedLibraries, CoGetCurrentProcess, IMultiQI, IStorage, IStream
Class Emulation CoTreatAsClass
Marshaling CoCreateFreeThreadedMarshaler, CoGetStandardMarshal, CoGetMarshalSizeMax, CoMarshalInterface, CoReleaseMarshalData, CoUnmarshalInterface, IMarshal, IStdMarshalInfo
Object Lifetime IExternalConnection, CoLockObjectExternal
Security CoCopyProxy, CoGetCallContext, CoImpersonateClient, CoInitializeSecurity, CoQueryAuthenticationServices, CoQueryClientBlanket, CoQueryProxyBlanket, CoSetProxyBlanket, CoRevertToSelf, IClientSecurity, IServerSecurity
Running Object Table and Custom Moniker GetRunningObjectTable, IRunningObjectTable, IROTData, IClassActivator
Automation and Self-description CreateTypeLib, LoadRegTypeLib, ITypeLib, ITypeLib2, ITypeInfo, ITypeInfo2, IProvideClassInfo, IProvideClassInfo2


Figure 6    Resource Table String Entries

#include <windows.h>
#include <wchar.h>
#include <resource.h>
 
static struct string_table_entry { int idx; WCHAR * psz; } string_table[] =
{
    IDS_ATLTEST2_DESC, L"AtlTest2 Class"
};
 
int LoadStringW(
    HINSTANCE hInstance,
    UINT uId,
    LPWSTR lpBuffer,
    int nBufferMax
)
{
    int string_table_length = sizeof(string_table) /   sizeof(string_table_entry);
 
    for (int i = 0 ; i < string_table_length ; i++)
    {
        if (string_table[i].idx == uId)
        {
            wcsncpy(lpBuffer, string_table[i].psz, nBufferMax);
            return wcslen(lpBuffer);
        }
    }
    return 0;
}

Figure 7   Sample Unix makefile


#
# makefile.make : UNIX makefile sample
#
 
include $(DCOMAKE)/makefile.incl
 
IDLINCS = -I../../proxy/unix
ATL_INCLUDES = \
                -I../../proxy/unix \
                -I$(DCOSDK)/atl21
 
all: $(OBJDIR) $(BINDIR)/atltest2_s

register:
                @echo "Registering the ATL 2.1 Test Server ..."
                $(BINDIR)/atltest2_s -register

$(OBJDIR):
        mkdir -p $@
 
OBJECTS = $(OBJDIR)/atlinc.o $(OBJDIR)/atltest2_s.o $(OBJDIR)/atltest_rc.o
 
$(BINDIR)/atltest2_s : $(OBJECTS)
                       $(CXX_COMPILER_NAME) -o $@ \
                       $(PROGRAM_LD_FLAGS) \
                       $(OBJECTS) \
                       $(PROGRAM_LINKLIBS)
 
$(OBJECTS) : ../$$(@F:.o=.cpp) ../../proxy/unix/atltest2.h ../atltest.h \
    ../stdafx.h ../atlinc.cpp
                $(CXX_COMPILER_NAME) -c -o $@ ../$(@F:.o=.cpp) \    $(TEMPLATE_FLAGS) $(CC_FLAGS) $(C_DEFINES) $(IDLINCS) \
                $(C_INCLUDES) $(ATL_INCLUDES)
 
clean:
       rm -f $(BINDIR)/atltest2_s
       rm -rf $(OBJDIR)

Figure 8   CreateCommandLine


LPTSTR CreateCommandLine(int argc, char *argv[])
{
    char *pszCmdLine=NULL;
    int     cArgs;
    int     CmdLineLength=0;
    TCHAR *pszUCmdLine=NULL;
    int     iUCmdLineLen=0;
 
    for (cArgs = 0; cArgs < argc; cArgs++) {
        CmdLineLength += strlen(argv[cArgs]) + 1; // Add space between args and // null termination
    }
    pszCmdLine = (char *)calloc(1, CmdLineLength);
 
    for (cArgs = 0; cArgs < argc; cArgs++) {
        strcat(pszCmdLine, argv[cArgs]);
        strcat(pszCmdLine, "\0");
    }
    pszUCmdLine = (TCHAR *)calloc(1, CmdLineLength*sizeof(wchar_t));
    iUCmdLineLen = mbstowcs(pszUCmdLine, pszCmdLine, CmdLineLength);
    return(pszUCmdLine);
}