Microsoft KB Archive/171974

From BetaArchive Wiki

Article ID: 171974

Article Last Modified on 7/11/2005


  • Microsoft OLE 4.0, when used with:
    • Microsoft Platform Software Development Kit-January 2000 Edition

This article was previously published under Q171974


DCOM supports connecting to an object on a remote machine ROT (Running object table) using file monikers. ROTMONK is a COM server/client sample that demonstrates how to achieve this functionality.

The following file is available for download from the Microsoft Download Center:

For additional information about how to download Microsoft Support files, click the following article number to view the article in the Microsoft Knowledge Base:

119591 How to Obtain Microsoft Support Files from Online Services

Microsoft scanned this file for viruses. Microsoft used the most current virus-detection software that was available on the date that the file was posted. The file is stored on security-enhanced servers that help to prevent any unauthorized changes to the file.


There are a few things that you need to know so that you can make this feature work properly:

  1. If the server supports multiple clients to connect to it, the server must register its class object to be multiple use. Even though the clients connect via the ROT, the server must still register the class as multiple-use so that COM can marshal the interface for each client.
  2. The server has to register the object in the ROT with ROTFLAGS_ALLOWANYCLIENT flag. Otherwise, the moniker is registered with a security descriptor that allows only clients from the same security context to access it. When the server specifies ROTFLAGS_ALLOWANYCLIENT, any clients can access it. Also, refer to the ROTFLAGS_ALLOWANYCLIENT documentation in Win32 SDK. This flag is only available for servers that run as a service, the interactive user, or a specific user.

    In order for a ROT registration with ROTFLAGS_ALLOWANYCLIENT to succeed, the following regsitry entries must be present:


    where app.exe is the module name of the registering process (just the name of the process is sufficient, paths must not be specified). APPIDGUID is a placeholder for a real GUID of the AppID of this process:

    [HKEY_CLASSES_ROOT\AppID\{APPIDGUID}] "RunAs"="Interactive User"

    The RunAs named value can specify either "Interactive User" or a specific user. A RunAs entry must be present because the system prohibits "activate as activator" processes from registering in the ROT with ROTFLAGS_ALLOWANYCLIENT. This is done for security reasons.
  3. The client and the server have to use the same physical file to create the moniker, and the file has to be shared out so the client can access this file. As an example a client would do:

    CreateFileMoniker("\\machinename\sharename\path to file...")

    while the server might do something like:

    CreateFileMoniker("path to drive based file....");

    Due to a bug in the OLE libraries, if the server shares out the root directory (for example, c:\) and if the client creates a file moniker on the same physical file the two file monikers are not considered the same. The reason for this is that when the system is recreating the local file name from the UNC name, there is an extra "\" added in the file name which causes the two file monikers to be different. If you share out any directory besides root directory, then this problem does not occur.

File Moniker Specific

  1. The server needs to implement IPersistFile to support bind to objects through file moniker.
  2. At the bare minimum, the file should be a structured storage file with the class id of the object written with WriteClassStg.

The sample contains the server code in the root directory, and client code in the client subdirectory.

Server File

rotmonk.cpp   WinMain, and main windows procedure, and registering an
              object in ROT.
oleinit.cpp   OLE initialization and class factory registration.
persist.cpp   Bare-bone implementation of IPersistFile Interface.
debug.cpp     Helper trace function for debugging.
rotmonk.reg   Server registration file.
rotmonk.rmp   The dummy file on which the File Moniker is created, if this
              file does not exist, the server program can recreate it.

Client File

Client.cpp    WinMain, and Main Windows Procedure, and binding to an object
              in ROT.
oleinit.cpp   OLE initialization.
Debug.cpp     Helper trace function for debugging.

To Run the Sample

  1. Edit the server registration file (rotmonk.reg) to point to the server executable's correct path. Double-click the registration file so that the server is registered on the machine where the server will be running.
  2. To configure the server with dcomcnfg:

    1. Open dcomcnfg.exe where the server will be running.
    2. Select and double-click "DCOM ROT Monk Sample."
    3. Select the Security Tab.
    4. Select Custom Launch permission, and then Custom Access Permission.
    5. Select Launch Permission. Make sure that at least the following are in the list:

      - System
      - Interactive
      - The user who will be logging on the client machine
    6. Select Access Permission. Make sure that at least the following are in the list:

      - System
      - Interactive
      - The user who will be logging on the client machine
    7. Select the Identity Tab.
    8. Select "Interactive user".
  3. Make sure you have a c:\temp\rotmonk directory, and share the temp directory so that the client machine can connect to this share. The server will create rotmonk.rmp file there, if the file does not exist.
  4. Run the dbmon.exe (to catch OutputDebugString...) and then run the server, or Run the server in Debugger.
  5. Run the client on the client machine. (You can also run dbmon.exe on the client machine, if you want to catch OutputDebugString from the client program.)

    1. Select Test, Machine Name.
    2. Under Machine name, specify the machine "<machine name>"
    3. Specify Moniker Name as "\\<machine name>\<share Name>\<path to file including file name>"
    4. Select Test, and then Bind to Object.
  6. The server should output "Object Id 1 Ref Count 4 Object Count 1" in dbmon/debugger. When you run another client on the client machine, you should see that it gets connected to same object. The server will output "Object Id 1 Ref Count 4 Object Count 1". In this sample, the 1st object has the Object Id of 1, and is registered in the ROT. This is the only object registered in the ROT. If you get another Object ID, then the object has been created through ClassFactory.
  7. Run OLEView on the server machine, and instantiate the "DCOM ROT Monk Sample". Double-click the IPersist interface. The server will output "Object Id 2 Ref Count 3 Object Count 2", which basically demonstrates that this (OLEView) client went through the ClassFactory and got a another object, as opposed to the same object in the previous case.

Additional query words: Rotmonk 95

Keywords: kbhowto kbdownload kbfile kbdcom kbsample KB171974