DCOM98 for Windows 98, version 1.3
Release Notes
DCOM98 provides Distributed COM support for Microsoft® Windows®
98. The DCOM wire protocol transparently provides support for
reliable, secure, and efficient communication between Component
Object Model (COM) components such as ActiveX® controls, scripts,
and Java applets residing on different machines in a LAN, a WAN, or
on the Internet. With DCOM, your application can be distributed
across locations that make the most sense to you and to the
application.
For more in-depth information, see the DCOM Technical overview
available in the MSDN
Online Library.
Contents
New
Features Bug
Fixes Known
Issues Differences
from DCOM on Windows NT Redistribution Support
& Resources DCOM98
File List
New Features
Visual Studio 6.0 Process Monitoring Support
In support of Visual Studio 6.0, DCOM98 provides monitoring
information for developers to help them understand the behavior,
performance, and structure of their application. If you are using
Visual Studio Analyzer on a computer that is running Windows 98, you
should always use this version of DCOM98.
COM Internet Services
The COM Internet Services (CIS) enable clients and servers to be
connected over the Internet using COM. CIS consists of
- A new DCOM protocol, Tunneled TCP
- A new moniker type, OBJREF moniker
- A new CISCNFG utility
For CIS client support in Windows 98, you must install both
DCOM98 and DCOMCNFG. Then use the CISCNFG tool, which is installed
when you install the DCOM configuration utility, to change the
registry key that defines which protocol to use for remote
processes. In the Command Prompt window, enter:
ciscnfg <protocol>
Where <protocol> is:
- rpc to use RPC
- http to use HTTP
- tcp_http to try TCP first and then, if the server times out,
to try HTTP.
The ciscnfg command with no argument provides usage
information.
No SDK updates are required to use the Tunneled TCP protocol.
There are a few updates for OBJREF monikers.
CreateObjrefMoniker
Creates an OBJREF moniker based on a pointer to an
object.
WINOLEAPI CreateObjrefMoniker(
LPUNKNOWN pUnk, //Pointer to the object
LPMONIKER *ppMk //Address of pointer to OBJREF moniker
);
Parameters
pUnk
Pointer to the IUnknown interface on the object that the moniker
is to represent.
ppMk
Address of a pointer to the IMoniker interface on the OBJREF
moniker created.
Return Values This function supports the standard return values
E_OUTOFMEMORY and E_UNEXPECTED, as well as the
following:
S_OK
The OBJREF moniker was successfully created
Remarks
Clients use OBJREF monikers to obtain a marshaled pointer to a
running object in the server's address space. The server typically
calls CreateObjrefMoniker to create an OBJREF moniker and
then calls IMoniker::GetDisplayName, and finally releases the
moniker. The display name for an OBJREF moniker is of the form:
OBJREF:nnnnnnnn
Where nnnnnnnn is an arbitrarily long base-64 encoding that
encapsulates the machine location, process endpoint, and interface
pointer ID (IPID) of the running object.
The display name can then be transferred to the client as text.
For example, the display name can reside on an HTML page that the
client downloads.
The client can pass the display name to
MkParseDisplayName, which creates an OBJREF moniker based on
the display name. A call to the moniker's
IMoniker::BindToObject method then obtains a marshaled
pointer to the running instance on the server. For example, a
server-side COM component contained in an active server page can
create an OBJREF moniker, obtain its display name, and write the
display name to the HTML output that is sent to the client browser.
A script that runs on the client side can use the display name to
get access to the running object itself. A client-side Visual Basic®
script, for instance, could store the display name in a variable
called strMyName and include this line:
objMyInstance = GetObject(strMyName)
The script engine internally makes the calls to
MkParseDisplayName and IMoniker::BindToObject, and the
script can then use objMyInstance to refer directly to the
running object.
If the running object uses static IPIDs and the server process
always runs on the same computer at a well-known endpoint, the
display name of the OBJREF moniker will always be the same. In that
case, the server can store the display name instead of calculating
it each time it receives a request for the object.
IMoniker - OBJREF Moniker Implementation
OBJREF monikers represent a reference to an object instance that
is running on an out-of-process server, either locally or remotely.
The moniker identifies the object instance and the computer the
object is running on.
An OBJREF moniker is similar in many ways to a pointer moniker,
except that the running object is out-of-process. A client can call
IMoniker::BindToObject on an OBJREF moniker and use the
pointer it obtains to access the running object, regardless of its
location.
An important distinction from a pointer moniker is that the
display name of an OBJREF moniker can be embedded in an HTML page,
and the running object represented by the moniker can be bound by a
client script, applet, or ActiveX control.
When to Use
The primary use for an OBJREF moniker is to obtain access to a
running object instance over the Internet. An active server page or
some other means of generating dynamic HTML content places the
display name of an OBJREF moniker in a parameter to an applet or an
ActiveX control. The code of the applet or control calls
CreateObjrefMoniker to create an OBJREF moniker based on the
display name, and it then calls IMoniker::BindToObject on the
resulting OBJREF moniker to get access to the running object
instance. The active server page (ASP) then marshals a pointer to
the running object back to the page's client.
Remarks
IMoniker::BindToObject. For OBJREF monikers, the pmkToLeft
parameter must be NULL. Because the OBJREF moniker represents
a running object, no activation takes place. If the represented
object is no longer running, BindToObject fails with
E_UNEXPECTED.
IMoniker::BindToStorage. This method obtains a marshaled
pointer to the requested interface on the storage that contains the
running object. Because the OBJREF moniker represents a running
object, no activation takes place. If the represented object is no
longer running, BindToStorage fails with
E_UNEXPECTED.
IMoniker::Reduce. This method returns
MK_S_REDUCED_TO_SELF and passes back the same moniker.
IMoniker::ComposeWith. If pmkRight is an
anti-moniker, the returned moniker is NULL. If
pmkRight is a composite whose leftmost component is an
anti-moniker, the returned moniker is the composite with the
leftmost anti-moniker removed. If pmkRight is neither an
anti-moniker nor a composite moniker whose leftmost component is an
anti-moniker, then the method checks the fOnlyIfNotGeneric
parameter. If it is FALSE, the method combines the two monikers into
a generic composite; if it is TRUE, the method sets
*ppmkComposite to NULL and returns
MK_E_NEEDGENERIC.
IMoniker::Enum. This method returns S_OK and sets
ppenumMoniker to NULL.
IMoniker::IsEqual. This method returns S_OK if
*pmkOther is an OBJREF moniker and the paths for both
monikers are identical (using a case-insensitive comparison).
Otherwise, the method returns S_FALSE.
IMoniker::Hash. This method calculates a hash value for
the moniker.
IMoniker::IsRunning. Because OBJREF monikers represent a
running object instance, this method returns TRUE unless the object
is known to be no longer running because a recent call failed. The
method ignores pmkToLeft.
IMoniker::GetTimeOfLastChange. This method returns
E_NOTIMPL.
IMoniker::Inverse. This method returns an anti-moniker
(i.e., the results of calling CreateAntiMoniker).
IMoniker::CommonPrefixWith. If the two monikers are equal,
this method returns MK_S_US and sets *ppmkPrefix to
NULL. If the other moniker is not an OBJREF moniker, this method
passes both monikers to the MonikerCommonPrefixWith function.
This function correctly handles the case where the other moniker is
a generic composite.
If there is no common prefix, this method returns
MK_E_. IMoniker::RelativePathTo. This method
returns E_NOTIMPL.
IMoniker::GetDisplayName. This method obtains the display
name for the OBJREF moniker. The display name is a 64-bit encoding
that encapsulates the machine location, process endpoint, and
interface pointer ID (IPID) of the running object. For future
compatibility, the display name is restricted to characters that can
be specified as part of a URL.
IMoniker::ParseDisplayName. If pmkToLeft is not
NULL, this method returns MK_E_SYNTAX.
IMoniker::IsSystemMoniker. This method returns S_OK
and passes back MKSYS_OBJREFMONIKER.
Support for Visual Basic 6.0 Data Types
Visual Basic 6.0 allows Visual Basic variants to contain user-
defined data structures. DCOM98 now supports remoting of these
variants.
Back to contents
Bug Fixes
Race Condition When Unloading Multiple Modules
When multiple modules were unloaded simultaneously, a race
condition would occur. Depending upon the order in which the modules
were unloaded, an access violation could result. This has been
corrected in this release of DCOM98.
Desktop Unresponsive During RPC Protocol Negotiations
Earlier versions of DCOM98 did not dispatch messages while they
were negotiating RPC protocols. In certain cases, if the user
launched another application during the time that RPC protocols were
being negotiated, the machine would appear to be unresponsive. After
30 seconds, processing of messages would resume. This behavior has
been changed in the latest release of DCOM98, and applications can
be launched while RPC protocols are being negotiated.
Desktop Unresponsive When New Application Launched
RPC creates a hidden window in the Multiple-Threaded Apartment
(MTA), which is not required to dispatch messages per DCOM spec.
When a user launches a new application from the desktop, Windows
sends a message to all other window handles, notifying them of this
event, and expecting a reply. Under earlier versions of DCOM98, the
hidden RPC window might not reply, and Windows would hang. This
version of DCOM98 fixes this problem, and the RPC window no longer
makes the desktop unresponsive when new applications are
launched.
Multiple IP Addresses Heap Corruption
In certain situations, if you were running a previous version of
DCOM98 on a machine with more than one IP address, the IP address
buffer would be overrun and the heap would be corrupted. This has
been fixed in the latest release of DCOM98.
Only First IP Address Used
If you were running a previous version of DCOM98 on a machine
that had two network adapter cards (and therefore two IP addresses,
each assigned to a different address card), DCOM98 would use only
one network adapter. In this release of DCOM98, if the first one
tried does not work, the second one will be used.
RPC Now Tries Multiple IP Addresses
When doing a remote procedure call to a machine with multiple IP
addresses, subsequent IP addresses will now be tried if connecting
to the first one fails.
File Monikers Support Additional Path Syntax
File monikers can now be created out of arguments of the form
<startdir><relativepath>, such as
"C:\bug\bug\..\..\foo.jpg." Prior to this release of DCOM98, only
relative paths (e.g., "..\..\foo.jpg") or absolute paths (e.g.,
"C:\foo.jpg") were permitted.
General Protection Fault When Oleaut32.dll Unloaded
In previous versions of DCOM98, a general protection fault
occurred when Oleaut32.dll was unloaded before a call to
CoUninitialize. This would most often occur when a VB
application created a control statically linked to Oleaut32.dll, and
then freed the control prior to calling CoUninitialize. This
no longer causes a general protection fault in the latest release of
DCOM98.
Visual Basic Type Marshaling and Unmarshaling
The marshalling and unmarshaling of certain Visual Basic data
types has been fixed. Array parameters with a size greater than 64K
are now allowed. Structures defined using aliases to the type are
now marshaled and unmarshaled correctly.
Atoms Being Deleted Too Many Times in OleUninitialize
This bug appeared in applications that call OleInitialize
and OleUninitialize multiple times. During initialization,
OLE adds many atoms for DDE RPC. If the atoms have already been
added by another thread, they are not added again. However, during
uninitialization, atoms were always deleted, and the handles were
not nullified. Therefore, the next time OleInitialize was
called, the old handles would still exist, even though the atoms
were already deleted, and OLE would not add them again. This led to
all OLE atoms being invalid after multiple calls to
OleInitialize and OleUninitialize. This problem has
been fixed in this release of DCOM98.
ADO Servers Shut Down Properly
Active Data Objects (ADOs) use pointer monikers to start a server
process. Previous versions of DCOM98 contained a bug involving
pointer moniker reference counting, whereby pointer monikers were
created with an initial reference count of 1, rather than 0.
Therefore, the reference count of the pointer moniker would never
get to zero, and the pointer moniker would never be freed. As a
result, ADO servers were never shut down, even after the last
pointer to them had been released. This has been fixed in this
release of DCOM98.
CoCreateInstance Works with Own DNS Name
In previous versions of DCOM98, calling CoCreateInstance
with the fully qualified name of the local machine did not work.
This has been fixed in the current version of DCOM98, and
CoCreateInstance now correctly creates and instance on the
local machine.
Slow Commit On Root Storage With Very Large Compound File
In previous versions of DCOM98, the commit time on a root storage
opened in STGM_TRANSACTED mode became very slow as the compound file
became very large (e.g. 400M). The internal page table limits have
been increased, and this is no longer a problem.
Exporting Objects From a Recreated MTA
In previous versions of DCOM98, a server could not export an
object from a Multi-Threaded Apartment (MTA) if this was not the
first time the MTA had been created in the process. This has been
fixed. Now, if a server creates an MTA, destroys it, and
subsequently recreates the MTA, objects will be able to be exported
from the MTA.
Multiple Instances Of Visual Basic 4 Exes
In previous versions of DCOM98 if you started multiple instances
of the same Visual Basic 4 executable, then shut them down in any
order but LIFO (Last-In First-Out), the last exe would hang. This
was also true of E-Forms in Microsoft Exchange. This has been fixed
in the latest release of DCOM98. You may now shut down Visual Basic
4 exes in any order.
Extended Characters in Visual Basic File Names
If you named a Visual Basic module or class using extended
characters for a given language, that file might not open on
machines configured for a different locale. This has been fixed.
Heap Memory Leak When Using IDataObject/IAdviseSink
There was a memory leak when using Uniform Data Transfer between
a data object on a local server that implements the
IDataObject interface and a client that implements
IAdviseSink. When the client used the STA model, every call
would leak 32 bytes. This problem manifests itself as the server
taking more and more time to execute. The leak has been fixed.
Back to contents
Known Issues
Corel WordPerfect Suite 7: Installation Causes Invalid Page
Fault
If you install Corel WordPerfect Suite 7 on a Windows 98 system
running DCOM98, you may get an invalid page fault in PfOd70.pfc
during installation. If this error appears, just close the error
message dialog box. Setup should continue successfully.
Microsoft Access 95: Database Replication Does Not Work
If you try to replicate an Access database using Microsoft Access
95 on machines with DCOM98 installed, you may get the following
error message:
Microsoft Access cannot complete this operation
because it can't find or initialize the dynamic-link library
Msjtrclr.
This is a problem in Microsoft Access 95. You may work around
this issue by writing a program which uses the Access object model
rather than the replica tool, or by using the briefcase for
replication. Microsoft Access 97 is not affected by this issue.
WordPerfect
If you have a WordPerfect document containing an embedded Corel
spreadsheet and the spreadsheet contains another embedded object
(for example, a bitmap), you may get a warning dialog saying you’ve
lost the network connection when you close the innermost object.
There may be four or five such warnings. All these warnings are
benign. Just close them and continue.
Multiple-threaded apartment (MTA) clients that use BSTR
conversion routines may block DDE messages
Automation BSTR conversion routines (for example, BstrFromR4)
create hidden windows to facilitate the type conversion. These
windows do not service the Windows message queue. If such a window
is created from within an MTA client, DDE messages may be blocked.
The client thread has no obligation to service the message queue
under the MTA programming model. If it does not, this top-level
window causes global broadcast messages to block.
There are two ways to work around this situation. Either call the
BSTR conversion routines from within a single-threaded apartment
(STA) client, or make the client’s MTA thread behave like an STA
thread. (An STA thread must service the message queue.) If the
thread is blocking on a win32 handle, it must call the
MsgWaitForMultipleObjects function to simultaneously dispatch
Windows messages.
DLL path names longer than 127 characters cause error
If you register a DLL with a path name of 128 characters or
longer, the registration will succeed, but CoCreateInstance
or CoGetClassObject will return an error
(REGDB_E_CLASSNOTREG) when accessing an object supported by this
DLL.
Back to contents
Differences from DCOM on Windows NT
Security Capabilities of DCOM98
The core functionality and application programming interface
(API) for DCOM98 are identical in both Windows 98 and Windows NT
4.0. However, certain capabilities related to security are different
because of the different security infrastructures of the operating
systems. Using the default security settings of the system is
recommended; it is also necessary to enable "user-level" security on
file-system shares. (See below.)
The following services, which can be used to override default
security, are available:
- CoInitializeSecurity
- CoQueryAuthenticationService
- CoQueryProxyBlanket
- CoSetProxyBlanket
- CoQueryClientBlanket
- IClientSecurity Interface
- IServerSecurity Interface
However, certain capabilities that are part of DCOM for Windows
NT will not be available on Windows 98 because of differences in the
security infrastructure on Windows 98.
In particular, the lack of security functions in the Win32 API,
such as the ability to create access control lists (ACLs), and the
AccessCheck function, as well as the lack of a security
context associated with thread and process tokens, should be taken
into account. Windows 98 does not natively support these functions
or constructs. Because of this, DCOM98 will not support
impersonation (specifically, the CoImpersonateClient and
CoRevertToSelf helper functions over the
IServerSecurity interface), which is based on thread- and
process-token security in Windows NT 4.0. Impersonation is commonly
used to automatically control access to restrictable system
resources such as the file system, other processes, and the network.
These resources are not restrictable on Windows 98.
DCOM98 does, however, offer programmers various helper objects to
provide ACL and access-check functionality, which can be used to
explicitly control access by remote clients to both system and
user-defined resources or data. These helper objects are provided by
the system object CLSID_DCOMAccessControl, which implements
the IAccessControl interface.
IAccessControl should be used to manage security
permissions programmatically wherever portability between Windows 98
and Windows NT is a concern. The CLSID_DCOMAccessControl
object is available in all releases of DCOM98 and in Windows NT 4.0
SP2 or later. For details about IAccessControl, see the
Platform SDK documentation.
Launch and Access Security
Controlling who can launch server-class code is not supported in
DCOM98, because launching servers is not supported. Servers/classes
must already be running in order for remote clients to connect to
them and make use of their services.
DCOM98 does support the ability to connect to already running
classes/servers. Access security is supported via the
\APPID\{.}\AccessPermissions registry key and adjusted via
the DCOMCNFG tool or during installation or setup of the
server code. Unauthenticated users will be able to use servers if
you configure the class to support unauthenticated connections
(through static configuration tools or dynamically via the
CoInitializeSecurity function). You can also build arbitrary
ACLs to define which users and groups can access specific
services.
Authentication Levels
DCOM98 clients can make DCOM calls using any authentication
level. DCOM98 servers or clients receiving callbacks can accept only
DCOM calls using RPC_C_AUTHN_LEVEL_NONE or RPC_C_AUTHN_LEVEL_CONNECT
authentication levels.
Transports
DCOM98 supports only TCP connectivity. If you do not have the
TCP/IP protocol installed, DCOM98 will not be able to support
cross-machine COM.
Registry Settings
The following registry keys found under
HKEY_LOCAL_MACHINE\Software\Microsoft\OLE are established by
DCOM98:
EnableDCOM (default value = "Y"). Enables DCOM on this
machine. When set to "N", the machine is prevented from connecting
to or activating objects on remote machines, and remote machines are
unable to connect to objects on the local machine. Setting this
value to "Y" enables either connectivity as a client to remote
objects (when EnableRemoteConnect='N', as explained below),
or full client/server connectivity (when
EnableRemoteConnect='Y', as explained below).
EnableRemoteConnect (default value = "N"). Enables COM
servers to support remote clients. When this value is set to "Y",
references to interfaces on local objects can be passed to remote
clients, and remote clients are allowed to connect to running
objects. When this value is set to "N", this machine is allowed to
connect to remote objects but cannot act as a server: the machine is
prevented from connecting to running objects.
In addition, the following registry key is found under
HKEY_CLASSES_ROOT\CLSID:
{bdc67890-4fc0-11d0-a805-00aa006d2ea4}\InstalledVersion.
Contains the version number of DCOM98 in the format "a,b,c,d". This
value can be used by Internet Component Download to determine
whether DCOM98 is installed. This value is added to the registry
during setup and should not be modified.
Using Windows 98 as a remote server host
Windows 98 can be a remote server host, with the following
caveats:
- There is no launch capability. The server process must be
already running for a client to connect to it.
- If secure connections are needed, the server (and in the case
of callbacks, the client) must have user-level access control with
the name of a security provider set.
- The registry value "EnableRemoteConnect" must be set to
"Y".
DCOM98 has been tested most extensively using the Windows NT
Domain security provider. You may encounter problems using other
security providers.
To establish user-level access control, you must have Filesec.vxd
installed. This file is generally installed on Windows 98 machines
when you install file and print sharing.
To enable user-level access control, open the Network dialog box
in Control Panel, click the Access Control tab, check the box marked
User-level Access Control, and enter the name of your security
domain. This may affect the way you currently share directories on
the network from your computer; see the online documentation for
details. If you do not have an Access Control tab in your network
configuration control panel, you need to install a network client
service. Click the Network clients, setting up entry in the online
help index for information on installing a network client.
Back to contents
Redistribution
DCOM98 may not be redistributed. For additional information,
please review the redistribution guidelines contained in the
end-user license agreement (license.txt).
Back to contents
Support & Resources
Paid Support
DCOM98 application development is supported by Microsoft Product
Support Services. You can ask questions through your Premier Level
support contract. You can also ask questions through your
Professional Level contract or purchase individual Professional
Support incidents (essentially a one-time fee for one question). If
you would like to understand more about Microsoft's paid support
options, you can call Microsoft Support Sales at (800) 936-3500 from
6:00 a.m. to 6:00 p.m. Pacific time, Monday through Friday,
excluding holidays. Please note that technical support is not
available through this number. Microsoft Product Support Services
Information is also available on the World Wide Web at http://www.microsoft.com.wstub.archive.org/support/.
Free Support
Newsgroups are a great place for free peer support. As time and
resources allow, Microsoft developers, program managers, support
engineers, and test engineers visit the site to collect feedback and
answer questions or correct misperceptions. There is no guarantee
that you will receive a response from Microsoft to any newsgroup
posting.
The following newsgroups can be used to ask questions about
DCOM98:
The DCOM mailing list is another good form of free peer support.
An advantage to being on a mailing list is that this is where
Microsoft will make early announcements of information on a given
topic. Again, it is peer support, and Microsoft staff will often
lurk there, but are not guaranteed to respond to any postings.
To learn more about the DCOM mailing list as well as other
DCOM-related lists, please review the E-Mail
Aliases and Mailing List page.
Providing Feedback
Please send any comments or bug reports to the DCOM mailing
list.
Resources
You can find additional information about DCOM on the COM
Home Page.
Back to contents
DCOM98 File List
This table lists the version numbers of files distributed with
DCOM98.
File Name |
DCOM98 |
asycfilt.dll |
2.40.4275.1 |
comcat.dll |
5.0.1601.1 |
compobj.dll |
2.30.200.0 |
dcom2w98.dll |
2.10.35.35 |
dllhost.exe |
4.71.2900.0 |
imagehlp.dll |
4.0.1381.1 |
iprop.dll |
4.0.1381.6 |
ole2.dll |
2.30.200.0 |
ole32.dll |
4.71.2900.0 |
oleaut32.dll |
2.40.4275.1 |
olecnv32.dll |
4.71.2900.0 |
olepro32.dll |
5.0.4275.1 |
olethk32.dll |
4.71.2900.0 |
rpcltc1.dll |
4.71.2900.0 |
rpcltc5.dll |
4.71.2900.0 |
rpcltccm.dll |
4.71.2900.0 |
rpclts5.dll |
4.71.2900.0 |
rpcltscm.dll |
4.71.2900.0 |
rpcmqcl.dll |
4.71.2900.0 |
rpcmqsvr.dll |
4.71.2900.0 |
rpcns4.dll |
4.71.2900.0 |
rpcrt4.dll |
4.71.2900.2 |
rpcss.exe |
4.71.2900.0 |
secur32.dll |
4.10.0.1999 |
stdole2.tlb |
2.40.4275.1 |
stdole32.tlb |
2.10.3027.1 |
storage.dll |
2.30.200.0 |
This table lists the version numbers of files distributed with
DC0M95CFG.
File Name |
DCOM95CFG |
dcomcnfg.exe |
5.00.1603.0 |
ciscnfg.exe |
4.71.2618.0 |
Back to contents
Last Updated: 4/14/99
©2002 Microsoft
Corporation. All rights reserved. Terms
of Use.
|