0
votes

I am trying to use the third party com object in my .net application.

By this com object I am trying to connect to mssql database.

The com object works only in MTA thread. The "ThreadingModel" value of the object in registry is "Apartment".

When I tried to work with object in Console Application - connection successes. When I change project type to Windows Application - connection fails (com object method returns message "-2147023550:OLE DB error occured. Code 80070542h"). When I add STAThread attribute to the Main method of the console application - connection fails.

I have tried to call my com object from another thread with MTA apartment, but connection also fails.

I'm trying to create my com object by this code:

var result = ComSecurity.CoInitializeSecurity(
                IntPtr.Zero,
                -1,
                IntPtr.Zero,
                IntPtr.Zero,
                RpcAuthnLevel.None,
                RpcImpLevel.Impersonate,
                IntPtr.Zero,
                EoAuthnCap.None,
                IntPtr.Zero);

var serverApplication = Activator.CreateInstance(Type.GetTypeFromProgID("LoodsmanServerApplication.MainSystem")) as IMainSystem;

...

public enum RpcAuthnLevel
    {
        Default = 0,
        None = 1,
        Connect = 2,
        Call = 3,
        Pkt = 4,
        PktIntegrity = 5,
        PktPrivacy = 6
    }

public enum RpcImpLevel
    {
        Default = 0,
        Anonymous = 1,
        Identify = 2,
        Impersonate = 3,
        Delegate = 4
    }

    public enum EoAuthnCap
    {
        None = 0x00,
        MutualAuth = 0x01,
        StaticCloaking = 0x20,
        DynamicCloaking = 0x40,
        AnyAuthority = 0x80,
        MakeFullSIC = 0x100,
        Default = 0x800,
        SecureRefs = 0x02,
        AccessControl = 0x04,
        AppID = 0x08,
        Dynamic = 0x10,
        RequireFullSIC = 0x200,
        AutoImpersonate = 0x400,
        NoCustomMarshal = 0x2000,
        DisableAAA = 0x1000
    }

[DllImport("ole32.dll")]
public static extern int CoInitializeSecurity(IntPtr pVoid, int
            cAuthSvc, IntPtr asAuthSvc, IntPtr pReserved1, RpcAuthnLevel level,
            RpcImpLevel impers, IntPtr pAuthList, EoAuthnCap dwCapabilities, IntPtr
            pReserved3);

Is there any way to use MTA COM object from STA thread?

1
It would be much easier if you would specify what exactly "doesn't work" means. what errors do you get? what do you expect to see? I have a feeling that your problem is not related to threading model. - Zdeslav Vojkovic
I've corrected the question. - Bevz Oleg
Forcing MTA has a side-effect, it forces the data provider to run on another thread. The error is an obscure one, ERROR_BAD_IMPERSONATION_LEVEL. There's something wrong with the user account you use on your main thread, the dbase provider is unhappy with it. I have to guess that you left the important code out of the snippet, something to do with impersonation. - Hans Passant
I've posted code of creating com object - Bevz Oleg
Well, close enough guess, you are using RpcImpLevel.Impersonate. Without any explanation why you do this, the obvious answer is "don't do that". - Hans Passant

1 Answers

0
votes

You should use delegation level instead of impersonation. MTA/STA has nothing to do with it.

var result = ComSecurity.CoInitializeSecurity(
                IntPtr.Zero,
                -1,
                IntPtr.Zero,
                IntPtr.Zero,
                RpcAuthnLevel.None,
                RpcImpLevel.Delegate,
                IntPtr.Zero,
                EoAuthnCap.None,
                IntPtr.Zero);