What does stdole.dll do?

Viewed 69172

We have a large C# (.net 2.0) app which uses our own C++ COM component and a 3rd party fingerprint scanner library also accessed via COM. We ran into an issue where in production some events from the fingerprint library do not get fired into the C# app, although events from our own C++ COM component fired and were received just fine.

Using MSINFO32 to compare the loaded modules on a working system to those on a failing system we determined that this was caused by STDOLE.DLL not being in the GAC and hence not loaded into the faulty process.

Dragging this file into the GAC caused events to come back fine from the fingerprint COM library.

So what does stdole.dll do? It's 16k in size so it can't be much... is it some sort of link to another library like STDOLE32? How come its absence causes such odd behavior?

How do we distribute stdole.dll? This is an XCOPY deploy app and we don't use the GAC. Should we package it as a resource and use the System.EnterpriseServices.Internal.Publish.GacInstall to ensure it's in the GAC?

7 Answers

I don't think any of the other answers actually answered most of the question "what does stdole.dll do". Here's my understanding.

Summary:

This DLL is near the top of a chain of references leading from your managed application ultimately to unmanaged operating system DLLs which looks like this:

    .NET app -->
        stdole.dll -->
            stdole2.tlb -->
                oleaut32.dll

The links in this chain are well defined but obscure. The rest of this answer walks the chain...


Detailed explanation:

stdole.dll itself is an interop DLL. That means that it is a .NET assembly whose purpose is to essentially act as a wrapper around specific unmanaged classes which have COM interfaces. If you look inside stdole.dll with a tool like ILSpy or dotPeek you can see what's there. Here's an example for the StdPicture interface:

using System.Runtime.InteropServices;

namespace stdole
{
  [CoClass(typeof (StdPictureClass))]
  [Guid("7BF80981-BF32-101A-8BBB-00AA00300CAB")]
  [ComImport]
  public interface StdPicture : Picture
  {
  }
}

All this is is an interface with attributes that encode details of the COM classes that really should be used. DLLs like this are generally created automatically with a tool like tlbimp.exe or Visual Studio will do this for you when you add an unmanaged COM DLL directly to your project as a reference.


We can dig a little deeper. A Guid in the example above 7BF80981-BF32-101A-8BBB-00AA00300CAB is generally going to be found in the Windows registry, that's where the runtime is going to look when stole.StdPicture is actually used from managed code.

If you search for that GUID using RegEdit, you'll find:

Computer\HKEY_CLASSES_ROOT\Interface\{7BF80981-BF32-101A-8BBB-00AA00300CAB}\TypeLib

which has the value 00020430-0000-0000-C000-000000000046.

Searching for that value, you'll find:

Computer\HKEY_CLASSES_ROOT\TypeLib\{00020430-0000-0000-C000-000000000046}

(Most of the other GUIDs from the same DLL would probably have a similar entry).

This key has a lot of interesting details, in fact details for several versions of the underlying implementation. For instance under subkey 2.0\0\win32 the default value is:

C:\WINDOWS\SysWow64\stdole2.tlb

for the 32-bit variant of version 2. That's one step closer to where StdPicture actually is implemented.


A TLB file is just a COM "header" of sorts for a DLL. It doesn't have executable code in itself. Opening stdole2.tlb in a tool like OLEViewDotNet or the original OleView, you can read the IDL of the typelib itself. In this case, the first part has the following:

// typelib filename: stdole2.tlb

[
  uuid(00020430-0000-0000-C000-000000000046),
  version(2.0),
  helpstring("OLE Automation")
]
library stdole
{
    ...
}

Note the uuid has the same value we got from Regedit above. Scrolling down eventually we come to the StdPicture entry, the same example as above:

[
  uuid(0BE35204-8F91-11CE-9DE3-00AA004BB851)
]
coclass StdPicture {
    ...
};

Yet again there's no real code here, just a class definition. Back to RegEdit we can find that uuid:

Computer\HKEY_CLASSES_ROOT\CLSID\{0BE35204-8F91-11CE-9DE3-00AA004BB851}\InprocServer32

whose value is C:\Windows\System32\oleaut32.dll. Now we know that this DLL implements the StdPicture coclass for version 2 of the 32-bit stdole library.

(Though I would have thought this file should be in SysWow64...?)

If you were to follow this chain for some other interface, you might end up at the same DLL or another.

Note that for some languages (like VB6) it is typical for the TLB to be embedded right in the implementing DLL directly. But this is not required for COM and obviously not how Microsoft did it in this case.

Related