Microsoft KB Archive/174024
Article ID: 174024
Article Last Modified on 2/9/2006
- Microsoft OLE 4.0, when used with:
- Microsoft Platform Software Development Kit-January 2000 Edition
This article was previously published under Q174024
This article answers some of the Frequently Asked Questions about DCOM95.
- Does COM work on Windows 95-only networks? Can a Windows 95 machine act as a COM server machine in such a case?
- The DCOMCNFG.EXE program produces an error message when I run it on a Windows 95 machine with Share Level Access control. Does this mean DCOM does not work on such machines?
- When I call CoCreateInstanceEx() specifying a remote Windows 95 machine name, the API returns RPC_S_SERVER_UNAVAILABLE. What is the cause of this error?
- When I call CoCreateInstanceEx() specifying a remote Windows 95 machine name, the API returns CO_E_SERVER_EXEC_FAILURE. What is the cause of this error?
- When I call CoCreateInstanceEx() specifying a remote Windows 95 machine name, the API returns RPC_E_NO_GOOD_SECURITY_PACKAGES. What is the cause of this error?
- When I make a call to the remote COM server running on a Windows 95 machine, I get the error RPC_S_UNKNOWN_AUTHN_SERVICE. What is the cause of this error?
- When I make a call to the remote COM server running on a Windows 95 machine, I get the error RPC_S_SERVER_TOO_BUSY. What is the cause of this error?
- I have a COM client on a Windows 95 machine that launches a server on a Windows NT machine. When the server tries to call the client back, the callback fails with E_ACCESSDENIED. What is the cause of this error?
- How do I make Netclip work between two Windows 95 machines on a Windows 95-only network?
- How do I make Netclip work securely between two Windows 95 machines on a Windows 95/NT network?
In the following discussion, wherever a COM server is mentioned, keep in mind that a COM client that allows callbacks (such as via the Connection Point mechanism) is in fact a COM server, and hence the same factors that apply to a COM server will apply to such a COM client.
Also, please see the References section for additional KB articles that describe some of the issues in more detail.
Q1: Does COM work on Windows 95-only networks? Can a Windows 95 machine act as a COM server machine in such a case?
A: The answers to both the questions are Yes. You can run COM clients and servers on Windows 95-only networks. If there is an NT domain in the network, Windows 95 can provide authentication/authorization via a pass- through security mechanism. If there are no NT domains in the network, only non-secure calls can be made in such networks. Since the default behavior of COM is to make secure calls, this behavior must be changed before a COM client can successfully call a COM server on a Windows 95-only network.
Before we discuss how this is accomplished, let's briefly discuss how security in general works in COM. Security on a remote COM activation is a three step process.
Security on a Remote COM Activation
First, the authentication level set in the COAUTHINFO structure passed to an activation API such as CoCreateInstanceEx() determines if the server- side SCM will attempt to authenticate the client. COAUTHINFO is a field inside the COSERVERINFO structure. If the authentication level set in the COAUTHINFO structure is something other than RPC_C_AUTHN_LEVEL_NONE, the SCM on the server side will attempt to authenticate the client. If this authentication fails, the activation API is rejected. If the authentication level set in the COAUTHINFO structure is RPC_C_AUTHN_LEVEL_NONE, then authentication will not be attempted (this is considered an anonymous activation attempt).
In either case, in the next step, the SCM performs a check to see if the client does indeed have launch permissions on the COM server. If the client does not have launch permissions, the activation API is rejected. If the client has launch permissions, the COM server is launched. For anonymous activation requests, the launch permission security descriptor must contain a NULL DACL or an ACL that allows "Everyone" access. Note that if the server has already been launched, then the launch permission check is not performed.
In the case of Windows 95, a COM server must be pre-launched before a COM client can connect to it, thus there are no launch permissions and hence there is no check for this. However, the authentication step is still performed and, therefore, the authentication level set in COAUTHINFO is important. If the client does not specify an explicit COAUTHINFO structure and leaves the pointer NULL, by default COM attempts to authenticate the client first. If it cannot authenticate the client, it checks the launch security descriptor to see if anonymous activation is allowed. If yes, it will launch the server (as usual, if the server is already launched this check is not done).
The third step of the activation process is to obtain a pointer to the class factory or to the actual object. This step is governed by call security and the access permissions set on the server, which are discussed below. Note that for anonymous activation, call security/access permissions are not checked, but instead if the server permits anonymous activation, a class factory pointer or an object pointer is returned to the client at this time.
Security on a Remote Call
Security on a remote call is a two-step process.
First, the authentication level set on the proxy determines security on a COM call. The default authentication level set on a proxy is determined by how the client and the server call the CoInitializeSecurity() API. The default value is the higher of the values specified by the client and the server for the dwAuthnLevel parameter of this API. For a given call, the client can change the authentication level on the proxy via CoSetProxyBlanket(), thus overriding the default setting. However, the client cannot specify an authentication level on the proxy that is less than that specified by the server in its call to CoInitializeSecurity().
For example, if the server specifies RPC_C_AUTHN_LEVEL_CONNECT in its call to CoInitializeSecurity() and the client specifies RPC_C_AUTHN_LEVEL_PKT, the default authentication level on all proxies in the client is RPC_C_AUTHN_LEVEL_PKT. The client can change the authentication level on a call to RPC_C_AUTHN_LEVEL_PKT_PRIVACY by calling CoSetProxyBlanket(). However, the client cannot change the authentication level to RPC_C_AUTHN_LEVEL_NONE, because the minimum specified by the server is RPC_C_AUTHN_LEVEL_CONNECT. If a process does not explicitly call the CoInitializeSecurity() API, the COM runtime calls the API on behalf of the process. The authentication level for this default call is obtained from the following registry location (note that this is a machine-wide setting and not a process-specific one).
This is a DWORD named value. A value of 1 corresponds to RPC_C_AUTHN_LEVEL_NONE, 2 corresponds to RPC_C_AUTHN_LEVEL_CONNECT, and so on.
When a call arrives, first the authentication level on the call is checked. If the authentication level is something other than RPC_C_AUTHN_LEVEL_NONE, the client is authenticated. Then, if there is a security descriptor for the server's access permissions, an access check is performed by comparing the client's identity against this security descriptor.
If the call comes in at RPC_C_AUTHN_LEVEL_NONE, then a client authentication is not performed. In this case, it is erroneous to specify a security descriptor for the server's access permissions. Therefore, a call to CoInitializeSecurity specifying a non-NULL security descriptor and an authentication level of RPC_C_AUTHN_LEVEL_NONE will return an error. Note, however, that if the server does not call CoInitializeSecurity (instead relies on the default machine-wide authentication level) and if this authentication level is RPC_C_AUTHN_LEVEL_NONE, then an access check is not performed against the (registry-based) security descriptor for the server's class. The client will still be authenticated if the authentication level is other than RPC_C_AUTHN_LEVEL_NONE.
If a call comes in at RPC_C_AUTHN_LEVEL_CONNECT or above, then COM performs an access check to see if the client's account is allowed to call the server by checking the Access Permissions list for the server. If the client's account is not allowed access, the call is rejected. Otherwise the call is allowed.
How to Setup DCOM on a Windows 95-only Network
Call CoInitializeSecurity(), passing RPC_C_AUTHN_LEVEL_NONE as the authentication level. If the server cannot call this API for some reason (for example, it is an in-process DLL server), then change the machine-wide authentication level setting to RPC_C_AUTHN_LEVEL_NONE, by modifying the registry key mentioned in Step 1 above using the Registry Editor. The machine needs to be re-booted for this change to take effect.
WARNING: Using Registry Editor incorrectly can cause serious, system-wide problems that may require you to reinstall Windows 95 to correct them. Microsoft cannot guarantee that any problems resulting from the use of Registry Editor can be solved. Use this tool at your own risk.
NOTE: When making the above change in the registry, it is important to understand that COM call security for the entire machine is turned off. Any client will be able to call into any COM server process running on the machine if the client gets hold of an interface pointer to an object in the server. Therefore, you must be careful when changing this machine-wide setting. It is strongly recommended that a COM server process call CoInitializeSecurity() to set its own security level rather than changing the machine setting.
Upcoming versions of COM will have the ability to specify per-process authentication levels, so that the above workaround is not required. This way, you can control the call security on a process-by-process basis. This feature is available in the DCOM95 1.1 web release (available soon), Internet Explorer 4.0 for Windows 95, and Windows 98 (beta 2 or later).
First, the activation must specify an authentication level of RPC_C_AUTHN_LEVEL_NONE. This can be done either by leaving the COAUTHINFO pointer in COSERVERINFO as NULL (default), or by specifying RPC_C_AUTHN_LEVEL_NONE in the COAUTHINFO struct. In the former case, COM attempts an authenticated activation first and then falls back to a non- authenticated activation. In the latter case, you must also specify RPC_C_IMP_LEVEL_IMPERSONATE for the dwImpersonationLevel parameter.
Second, calls must specify an authentication level of RPC_C_AUTHN_LEVEL_NONE. For this, the client must call CoInitializeSecurity() passing RPC_C_AUTHN_LEVEL_NONE. If you are using CoSetProxyBlanket(), RPC_C_AUTHN_LEVEL_NONE must be specified to this API as well. As in the server case, if the client cannot call CoInitializeSecurity(), then the machine-wide authentication level can be changed in the registry (discussed above).
Third, make sure that secure reference counting is not enabled. Secure reference counting can be enabled in DCOMCNFG and appears in the registry at the following location:
By default, this key is not present and secure reference counting is not enabled.
NOTE: It might appear from the above that the client does not need to call CoInitializeSecurity(), but can use CoSetProxyBlanket() to control the authentication level on individual proxies. However, this will not work correctly because the Release() call always uses the default authentication on the proxy (that is, the one set in CoInitializeSecurity), therefore the client will not be able to shut down the server object unless it sets the default authentication on the proxy as RPC_C_AUTHN_LEVEL_NONE. To do this, you must call CoInitializeSecurity(), either explicitly or implicitly. If the server object does not care about reference counting, this is not an issue.
A: No, this is strictly a limitation of Dcomcnfg.exe. Oleview.exe can be used on machines with share level access control. DCOM works correctly on Share Level access control Windows 95 machines. The answer to Question 1 shows how to set it up without security on these machines.
Q3: When I call CoCreateInstanceEx() specifying a remote Windows 95 machine name, the API returns RPC_S_SERVER_UNAVAILABLE. What is the cause of this error?
A: There are several reasons for this error.
Cause 1: The DNS/WINS Name Resolution Is Not Setup or Working Correctly
First make sure that you can ping the remote machine by name. If you cannot ping it by name, then most likely the DNS/WINS name resolution is not setup or not working correctly on your network. In this case, you cannot specify the machine name to DCOM either. Try pinging it by using its IP address, if this works, you can specify the IP address instead of the machine name to DCOM. If pinging by IP address also does not work, then TCP/IP is not installed properly on your network. You must correct this problem before you can use DCOM on the network. Note that the ability to enumerate NETBIOS shares (via the "net view \\NETBIOSNAME" command) does not mean that TCP/IP is installed correctly, NETBIOS can be running over the NETBEUI transport.
Verify that the EnableDCOM and EnableRemoteConnect registry keys under HKLM\Software\Microsoft\OLE are set to "Y" on the server machine. EnableDCOM must be set to "Y" to enable any distributed COM functionality. EnableRemoteConnect must be set to "Y" to let the machine act as a server. You need to reboot the server machine for this change to take effect.
Cause 2: Rpcss.exe Is Not Started on the Remote Machine Correctly
The other major cause for this error is that Rpcss.exe is not started on the remote machine correctly due to a known bug in DCOM95 1.0. Rpcss.exe is the resolver/end-point mapper process that needs to be running before any remote DCOM calls can be made. Under Windows NT, RPCSS is a Windows NT service, which is started when the machine is started. Under Windows 95, RPCSS process is started on a "lazy" or as-needed basis. Note that for local-only communications, RPCSS is not needed and is not started. But when the EnableRemoteConnect registry entry is set to "Y", RPCSS is started automatically when a COM server calls CoRegisterClassObject() to register its classes.
This is true regardless of whether the client that started the server is on the same machine or on a remote machine. This is also true if the server is started manually (as is the usual case under Windows 95) except under the following condition:
- The call to CoRegisterClassObject() is made from a Single Threaded Apartment (STA) server.
In this case due to a bug in DCOM95, RPCSS.EXE is not started automatically and hence a remote client will fail with an RPC_S_SERVER_UNAVAILABLE error. The same problem happens if a local client launched the server. The local client will work fine, but when a remote client tries to connect to the server, the remote client will get the error.
You can work around this problem by pre-launching RPCSS.EXE before any class objects are registered. A convenient place to do this is in the registry at HKLM\Software\Microsoft\Windows\CurrentVersion\Run, which launches when the shell loads, or \RunServices, which launches immediately upon booting the machine (that is, before login). Add a named value (any name) and a value of "Rpcss.exe". This problem is fixed in the DCOM95 1.1 Web release (available soon), Internet Explorer 4.0 for Windows 95, and Windows 98 (beta 2 or later).
Finally make sure that the COM server process is launched and has successfully registered its classes by calling CoRegisterClassObject().
Q4: When I call CoCreateInstanceEx() specifying a remote Windows 95 machine name, the API returns CO_E_SERVER_EXEC_FAILURE. What is the cause of this error?
A: To resolve this:
Make sure that the following registry entry on the server is set to "Y":
You need to reboot the server machine for this change to take effect.
- Make sure that the COM server is already launched on the machine and has successfully registered its classes by calling CoRegisterClassObject(). DCOM95 does not perform remote activation. Therefore, the server needs to be running before a remote client can connect to it.
Q5: When I call CoCreateInstanceEx() specifying a remote Windows 95 machine name, the API returns RPC_E_NO_GOOD_SECURITY_PACKAGES. What is the cause of this error?
A: This error occurs when Rpcss.exe is started after a client process is started and the client process then makes secure remote COM calls, such as CoCreateInstanceEx(). For example, assume you have a COM client process "A" that starts up and perhaps performs some local COM activities (Rpcss.exe is not yet started). Now another client process "B" starts and performs a remote COM call, which causes Rpcss.exe to start. Now if client "A" attempts to make a secure remote COM call, it will get this error. If client "A" is attempting a non-secure remote COM call, it will get an RPC_E_INVALID_PARAMETER error.
This error occurs because security information is not being synchronized properly if, when it is time to launch RPCSS in a client, COM finds that it has already been launched.
As in the answer to Question 3, you can work around this problem by pre- launching Rpcss.exe before launching the client process. A convenient place to do this is in the registry at HKLM\Software\Microsoft\Windows\CurrentVersion\Run, which launches when the shell loads, or \RunServices, which launches immediately upon booting the machine (that is, before login). Add a named value (any name) and a value of "RPCSS.EXE".
This problem is fixed in the DCOM95 1.1 web release (available soon), Internet Explorer 4.0 for Windows 95, and Windows 98 (beta 2 or later).
Q6: When I make a call to the remote COM server running on a Windows 95 machine, I get the error RPC_S_UNKNOWN_AUTHN_SERVICE. What is the cause of this error?
A: This error means that you are attempting to make a secure call (that is, authentication level on the proxy is RPC_C_AUTHN_LEVEL_CONNECT or above), but the Windows 95 machine is set to Share Level Access control and cannot authenticate the call. Please see the answer to Question 1 for information on how to make non-secure DCOM calls. Note that if the COAUTHINFO structure specifies RPC_C_AUTHN_LEVEL_CONNECT or above, an activation API such as CoCreateInstanceEx() will give the same error.
Q7: When I make a call to the remote COM server running on a Windows 95 machine, I get the error RPC_S_SERVER_TOO_BUSY. What is the cause of this error?
A: This error means that you are attempting to make a secure call at an authentication level above RPC_C_AUTHN_LEVEL_CONNECT. Windows 95 can accept incoming COM calls only at an authentication level of RPC_C_AUTHN_LEVEL_CONNECT or below. There are no restrictions on the authentication level of outgoing calls. Please see the answer to Question 1 for information on how a client's proxy obtains its default authentication level and how a client can change it (via CoSetProxyBlanket). Due to this restriction, a Windows 95 COM server (or a COM client that accepts callbacks) must call CoInitailizeSecurity() specifying at the most RPC_C_AUTHN_LEVEL_CONNECT authentication level. It cannot specify anything above this level. If it does, remote incoming calls will fail with the above error.
Q8: I have a COM client on a Windows 95 machine that launches a server on a Windows NT machine. When the server tries to call the client back, the callback fails with E_ACCESSDENIED. What is the cause of this error?
A: Make sure that the identity of your server is not set to "Launching User". (You can use Dcomcnfg.exe to examine the identity of your server). "Launching User" or "Activate as Activator" processes lack credentials to make secure calls out of their own machine. Note that the same setup will work if the client is on a Windows NT machine and the authentication level on the callback is RPC_C_AUTHN_LEVEL_CONNECT. Windows NT uses the NULL session share mechanism to make this work. This is not possible with Windows 95. Note that even under Windows NT, if the authentication level on the callback is above RPC_C_AUTHN_LEVEL_CONNECT, the callback will fail with the RPC_S_SEC_PKG_ERROR error.
Use Dcomcnfg.exe to change the Identity of the server to either the "Interactive user" or "This User". This will allow the server to make secure callbacks. The other option is to make non-secure callbacks by setting RPC_C_AUTHN_LEVEL_NONE on the callback proxy (see Question 1).
Q9: How do I make Netclip work between two Windows 95 machines on a Windows 95-only network?
A: Netclip is a sample DCOM application that you can use to view a remote machine's clipboard. You can get Netclip from http://www.interdesigner.com/downloads.htm
The following instructions explain how to make Netclip communicate between Windows 95 machines on a Windows 95-only network. Since there are no Windows NT machines or Windows NT domains on this network, there is no User Level Security. Therefore, these instructions turn off DCOM call level security for the whole machine. Please see Question 1 for a discussion of the security implications of this approach.
- Install DCOM95 on both of the machines.
- Ping the server machine from the client machine using its NETBIOS name, DNS name, or IP address. If the ping is successful with any of these names, the same name can be passed as the server machine name to COM. If pinging by IP address does not work, then you cannot use DCOM. You need to install and configure TCP/IP first.
In the registry, the following named value must be set to "Y" on both machines:
The following named value must be set to "Y" on the Netclip server machine:
If you are changing these values, keep in mind that you need to reboot the machine so that this change takes effect.
The following named value (REG_DWORD) must be set to 1 (None) on both machines:
If this named value does not exist, you can create it.
If you are creating/changing this value, keep in mind that you need to reboot the machine for this change to take effect.
NOTE: For machines with User Level Security, you can use Dcomcnfg.exe to make these changes. On a machine with Share Level security, you need to manually (via REGEDIT) or programatically (using the win32 registry APIs) make these changes because Dcomcnfg.exe will not run.
- Restart both computers.
- Start Rpcss.exe from the command line on the Windows 95 machine where the Netclip server is to run. This is a workaround for a known bug in DCOM95 1.0. (see Question 2 for other ways of pre-starting Rpcss.exe) This step is not required if you have DCOM95 1.1, Internet Explorer 4.0, or Windows 98 (beta 2 or later) is installed.
- Start the Netclip server as "netclip /server"
- On the Windows 95 client machine, start Netclip and specify the machine name (or IP address-see step b) of the server machine.
Q10: How do I make Netclip work securely between two Windows 95 machines on a Windows 95/Windows NT network?
A: Since there is a Windows NT domain in the network, you can use the pass-through security provided by the Windows NT domain. To do this, make sure that both of the Windows 95 machines are set to use User Level Access Control with the names of users and groups obtained from the Windows NT domain. You can do this in the Network applet in control panel. Use Dcomcnfg.exe to set the machine-wide authentication level to Connect on both machines. On the Netclip server machine, use Dcomcnfg.exe to give access permissions to the Windows NT domain account that is currently logged onto the Netclip client machine. This can be done either for the default access permissions list of the server machine or custom access permissions of the Netclip server itself. On the Netclip client machine, use Dcomcnfg.exe to give access permissions to the Windows NT domain account that is currently logged onto the Netclip server machine. You need to do this for the default access permissions list of the client machine because the Netclip server will make callbacks into the client and the Netclip client must give access permissions to the server's account. Follow the steps outlined in Question 9 (except Step 4 to turn off call security) to start the Netclip client/server session.
For additional information, please see the following articles in the Microsoft Knowledge Base:
Keywords: kbdcom kbfaq KB174024