我正在尝试连接到远程计算机上的DCOM对象,该远程计算机以与C#应用程序不同的用户身份登录。我已经让我的代码在同一台计算机上运行时连接到同一个DCOM对象,如下所示:
MyDCOMType dcomObject;
Type remoteSessionContextType = Type.GetTypeFromProgID("ServerApp.MyDCOMType");
dcomObject = (MyDCOMType)Activator.CreateInstance(remoteSessionContextType);
string version = dcomObject.GetVersion();
MyDCOMType是在DCOM应用程序(VB6应用程序)中实现的类型,我在项目中添加了它作为参考。我已经能够在C#代码中创建它的实例,并使用预期的结果调用所有方法。现在我试图让它连接到远程机器上的同一个对象。我试图像这样模仿远程系统上的用户(省略了变量定义和错误处理):
if (LogonUser(
userName,
domain,
password,
LOGON32_LOGON_NEW_CREDENTIALS,
LOGON32_PROVIDER_WINNT50,
out token) != false)
{
if (DuplicateToken(token, (int)_SECURITY_IMPERSONATION_LEVEL.SecurityDelegation, out tokenDuplicate) != false)
{
impersonationContext = WindowsIdentity.Impersonate(tokenDuplicate.DangerousGetHandle());
}
}
然后是类似的代码来创建对象:
MyDCOMType dcomObject;
Type remoteSessionContextType = Type.GetTypeFromProgID("ServerApp.MyDCOMType", ipAddress);
dcomObject = (MyDCOMType)Activator.CreateInstance(remoteSessionContextType);
string version = dcomObject.GetVersion();
除了CreateInstance调用抛出UnauthorizedAccessException错误,错误代码为80070005以进行未经授权的访问。
另一件事是我有C ++代码可以做同样完美的事情。那段代码是这样的:
COAUTHINFO AuthInfo;
COAUTHIDENTITY AuthIdentity;
COSERVERINFO ServerInfo;
MULTI_QI Results;
HRESULT hr;
BSTR version;
_MyDCOMType *pSession = NULL;
AuthIdentity.Domain = (unsigned short *) w_domain;
AuthIdentity.DomainLength = wcslen( w_domain);
AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
AuthIdentity.Password = (unsigned short *) w_password;
AuthIdentity.PasswordLength = wcslen(w_password);
AuthIdentity.User = (unsigned short *) w_username;
AuthIdentity.UserLength = wcslen(w_username);
AuthInfo.dwAuthnLevel = RPC_C_AUTHN_LEVEL_CALL;
AuthInfo.dwAuthnSvc = RPC_C_AUTHN_WINNT;
AuthInfo.dwAuthzSvc = RPC_C_AUTHZ_NONE;
AuthInfo.dwCapabilities = EOAC_NONE;
AuthInfo.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
AuthInfo.pAuthIdentityData = &AuthIdentity;
AuthInfo.pwszServerPrincName = NULL;
ServerInfo.dwReserved1 = 0;
ServerInfo.dwReserved2 = 0;
ServerInfo.pAuthInfo = &AuthInfo;
ServerInfo.pwszName = w_nodename;
hr = CoCreateInstanceEx(clsid, NULL, CLSCTX_ALL, &ServerInfo, (ULONG) 1, &Results);
hr = CoSetProxyBlanket(Results.pItf, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, &AuthIdentity, EOAC_NONE);
pSession = (_MyDCOMType *)Results.pItf;
hr = pSession->raw_GetVersion(&version);
它连接到远程服务器,创建DCOM对象,并从中获取数据就好了。我想弄清楚如何让我的C#代码做同样的事情。有任何想法吗?我把其中一个功能搞砸了吗?我错过了一些关键的电话或做错了吗?作为后台,我的计算机和我尝试连接的计算机都在域帐户下登录,但两者都没有权限。 C ++代码模拟远程用户以进行DCOM连接。我试图以这样的方式进行.NET模拟,即在给定手动输入的用户名和密码的情况下,它将对网络连接有效。
或者,如果它不可能,我想我可以编写一个带有相同C ++代码的小C ++ / CLR DLL来处理DCOM连接部分并从C#代码引用它,但我希望避免额外的复杂性。
答案 0 :(得分:0)
我打了一段时间并没有取得任何进展,所以我放弃并写了一个C ++ / CLR DLL,它完美无缺。代码如下:
MyDCOMTalker::MyDCOMTalker(String ^ipAddress, String ^username, String ^password, String ^domain)
{
COAUTHINFO AuthInfo;
COSERVERINFO ServerInfo;
MULTI_QI Results;
CLSID clsid;
AuthIdentity = new COAUTHIDENTITY;
long DSStatus;
BSTR umVersion;
AuthIdentity->Domain = (unsigned short *)Marshal::StringToHGlobalAuto(domain).ToPointer();
AuthIdentity->DomainLength = domain->Length;
AuthIdentity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
AuthIdentity->Password = (unsigned short *)Marshal::StringToHGlobalAuto(password).ToPointer();
AuthIdentity->PasswordLength = password->Length;
AuthIdentity->User = (unsigned short *)Marshal::StringToHGlobalAuto(username).ToPointer();
AuthIdentity->UserLength = username->Length;
AuthInfo.dwAuthnLevel = RPC_C_AUTHN_LEVEL_CALL;
AuthInfo.dwAuthnSvc = RPC_C_AUTHN_WINNT;
AuthInfo.dwAuthzSvc = RPC_C_AUTHZ_NONE;
AuthInfo.dwCapabilities = EOAC_NONE;
AuthInfo.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
AuthInfo.pAuthIdentityData = AuthIdentity;
AuthInfo.pwszServerPrincName = NULL;
ServerInfo.dwReserved1 = 0;
ServerInfo.dwReserved2 = 0;
ServerInfo.pAuthInfo = &AuthInfo;
ServerInfo.pwszName = (LPWSTR)Marshal::StringToHGlobalAuto(ipAddress).ToPointer();
Results.pIID = &_uuidof(_MyDCOMType);
Results.pItf = NULL;
Results.hr = 0;
CoInitialize(NULL);
Marshal::ThrowExceptionForHR(CLSIDFromProgID(L"MyDcomDLL.MyDCOMType", &clsid));
Marshal::ThrowExceptionForHR(CoCreateInstanceEx(clsid, NULL, CLSCTX_ALL, &ServerInfo, (ULONG) 1, &Results));
Marshal::ThrowExceptionForHR(CoSetProxyBlanket(Results.pItf, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE, AuthIdentity, EOAC_NONE));
pSession = (_MyDCOMType*)Results.pItf;
Marshal::ThrowExceptionForHR(pSession->raw_GetVersion(&DSStatus, &umVersion));
if (DSStatus == 0 && umVersion != NULL)
version = Marshal::PtrToStringBSTR((System::IntPtr)umVersion);
else
version = String::Empty;
}
使用类定义:
public ref class MyDCOMTalker
{
private:
_MyDCOMType *pSession;
String ^version;
COAUTHIDENTITY *AuthIdentity;
public:
MyDCOMTalker(String ^ipAddress, String ^username, String ^password, String ^domain);
};
通常的警告适用 - 我删除了更简单的代码的实际功能和错误检查/处理细节,我真的不太了解C ++ / CLR或COM和DCOM,所以可能有些事情可以完成更轻松。如果您知道在C#中有任何改进或方法,请在适当的时候发表评论/回答。
答案 1 :(得分:0)
我已经在托管代码中实现了一个实现。但是,谢谢你,基于你的实现,我能够理解这些东西是如何运作的。
using System;
using System.Runtime.InteropServices;
using System.Net;
namespace PM.Runtime.InteropServices {
[Flags]
public enum CLSCTX : uint {
INPROC_SERVER = 0x1,
INPROC_HANDLER = 0x2,
LOCAL_SERVER = 0x4,
INPROC_SERVER16 = 0x8,
REMOTE_SERVER = 0x10,
INPROC_HANDLER16 = 0x20,
RESERVED1 = 0x40,
RESERVED2 = 0x80,
RESERVED3 = 0x100,
RESERVED4 = 0x200,
NO_CODE_DOWNLOAD = 0x400,
RESERVED5 = 0x800,
NO_CUSTOM_MARSHAL = 0x1000,
ENABLE_CODE_DOWNLOAD = 0x2000,
NO_FAILURE_LOG = 0x4000,
DISABLE_AAA = 0x8000,
ENABLE_AAA = 0x10000,
FROM_DEFAULT_CONTEXT = 0x20000,
ACTIVATE_32_BIT_SERVER = 0x40000,
ACTIVATE_64_BIT_SERVER = 0x80000,
ENABLE_CLOAKING = 0x100000,
APPCONTAINER = 0x400000,
ACTIVATE_AAA_AS_IU = 0x800000,
PS_DLL = 0x80000000,
INPROC = INPROC_SERVER | INPROC_HANDLER,
SERVER = INPROC_SERVER | LOCAL_SERVER | REMOTE_SERVER,
ALL = SERVER | INPROC_HANDLER
}
#region Native Pointers
public abstract class PtrHandle : IDisposable {
~PtrHandle() { Dispose(false); }
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
protected abstract void Dispose(bool disposing);
public abstract IntPtr Handle { get; }
public static implicit operator IntPtr(PtrHandle managedPtr) {
return managedPtr != null ? managedPtr.Handle : IntPtr.Zero;
}
}
public class PinnedObject<T> : PtrHandle {
private GCHandle _handle;
public PinnedObject(ref T obj) {
_handle = GCHandle.Alloc(obj, GCHandleType.Pinned);
}
protected override void Dispose(bool disposing) {
_handle.Free();
}
public override IntPtr Handle {
get { return _handle.AddrOfPinnedObject(); }
}
}
public class GlobalPtr : PtrHandle {
private IntPtr _handle = IntPtr.Zero;
protected GlobalPtr() {}
protected override void Dispose(bool disposing) {
Free(ref _handle); // always release unmanaged memory...
}
protected void SetHandle(IntPtr handle) {
Free(ref _handle);
_handle = handle;
}
// get handle back with: Marshal.PtrToStructure<T>(nativePtr.Handle, T value);
protected void SetHandle<T>(ref T value, bool deleteOld = false) where T: struct {
Free(ref _handle);
_handle = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(T)));
try {
Marshal.StructureToPtr(value, _handle, deleteOld);
} catch {
Free(ref _handle);
throw;
}
}
public sealed override IntPtr Handle {
get { return _handle; }
}
public static void Free<T>(ref T handle) where T: GlobalPtr {
if (handle != null) {
handle.Dispose();
handle = null;
}
}
public static void Free(ref IntPtr handle) {
if (handle != IntPtr.Zero) {
Marshal.FreeHGlobal(handle);
handle = IntPtr.Zero;
}
}
}
public class LPAStr : GlobalPtr {
public LPAStr(string value) {
SetHandle(Marshal.StringToHGlobalAnsi(value));
}
}
public class LPWStr : GlobalPtr {
public LPWStr(string value) {
SetHandle(Marshal.StringToHGlobalUni(value));
}
}
public class PinnedStruct<T> : GlobalPtr where T: struct {
public PinnedStruct(ref T value) {
SetHandle<T>(ref value);
}
}
#endregion
public class WINNTAuthnInfo {
public NetworkCredential Credential;
public uint AuthnLevel;
public uint ImpersonationLevel;
public WINNTAuthnInfo(NetworkCredential Credential,
uint AuthnLevel = ComUtils.RPC_C_AUTHN_LEVEL_DEFAULT,
uint ImpersonationLevel = ComUtils.RPC_C_IMP_LEVEL_IMPERSONATE) {
this.Credential = Credential;
this.AuthnLevel = AuthnLevel;
this.ImpersonationLevel = ImpersonationLevel;
}
public static explicit operator WINNTAuthnInfo(NetworkCredential credential) {
return new WINNTAuthnInfo(credential);
}
}
public static class ComUtils {
private static class Guids {
public const string IID_IUnknown = "00000000-0000-0000-C000-000000000046";
public const string IID_IDispatch = "00020400-0000-0000-C000-000000000046";
}
// IID constants...
public static readonly Guid IID_IUnknown = new Guid(Guids.IID_IUnknown);
public static readonly Guid IID_IDispatch = new Guid(Guids.IID_IDispatch);
#region Constants
// HResult codes...
public const int S_OK = 0;
public const int E_ABORT = -2147467260;
public const int E_ACCESSDENIED = -2147024891;
public const int E_FAIL = -2147467259;
public const int E_HANDLE = -2147024890;
public const int E_INVALIDARG = -2147024809;
public const int E_NOINTERFACE = -2147467262;
public const int E_NOTIMPL = -2147467263;
public const int E_OUTOFMEMORY = -2147024882;
public const int E_POINTER = -2147467261;
public const int E_UNEXPECTED = -2147418113;
public const int REGDB_E_CLASSNOTREG
= -2147221164;
// Some private values...
private const int SEC_WINNT_AUTH_IDENTITY_ANSI = 1;
private const int SEC_WINNT_AUTH_IDENTITY_UNICODE = 2;
public const uint RPC_C_AUTHN_NONE = 0;
public const uint RPC_C_AUTHN_DCE_PRIVATE = 1;
public const uint RPC_C_AUTHN_DCE_PUBLIC = 2;
public const uint RPC_C_AUTHN_DEC_PUBLIC = 4;
public const uint RPC_C_AUTHN_GSS_NEGOTIATE = 9;
public const uint RPC_C_AUTHN_WINNT = 10;
public const uint RPC_C_AUTHN_GSS_SCHANNEL = 14;
public const uint RPC_C_AUTHN_GSS_KERBEROS = 16;
public const uint RPC_C_AUTHN_DPA = 17;
public const uint RPC_C_AUTHN_MSN = 18;
public const uint RPC_C_AUTHN_KERNEL = 20;
public const uint RPC_C_AUTHN_DIGEST = 21;
public const uint RPC_C_AUTHN_NEGO_EXTENDER = 30;
public const uint RPC_C_AUTHN_PKU2U = 31;
public const uint RPC_C_AUTHN_MQ = 100;
public const uint RPC_C_AUTHN_DEFAULT = 0xFFFFFFFF;
public const uint RPC_C_AUTHZ_NONE = 0;
public const uint RPC_C_AUTHZ_NAME = 1;
public const uint RPC_C_AUTHZ_DCE = 2;
public const uint RPC_C_AUTHZ_DEFAULT = 0xFFFFFFFF;
public const uint RPC_C_AUTHN_LEVEL_DEFAULT = 0;
public const uint RPC_C_AUTHN_LEVEL_NONE = 1;
public const uint RPC_C_AUTHN_LEVEL_CONNECT = 2;
public const uint RPC_C_AUTHN_LEVEL_CALL = 3;
public const uint RPC_C_AUTHN_LEVEL_PKT = 4;
public const uint RPC_C_AUTHN_LEVEL_PKT_INTEGRITY = 5;
public const uint RPC_C_AUTHN_LEVEL_PKT_PRIVACY = 6;
public const uint RPC_C_IMP_LEVEL_DEFAULT = 0;
public const uint RPC_C_IMP_LEVEL_ANONYMOUS = 1;
public const uint RPC_C_IMP_LEVEL_IDENTIFY = 2;
public const uint RPC_C_IMP_LEVEL_IMPERSONATE = 3;
public const uint RPC_C_IMP_LEVEL_DELEGATE = 4;
public const uint EOAC_NONE = 0;
#endregion
#region Internal unmanaged pointers...
private class WINNTAuthidEntityPtr : GlobalPtr {
public LPWStr _hdomain = null;
public LPWStr _huser = null;
public LPWStr _hpass = null;
public static WINNTAuthidEntityPtr Create(NetworkCredential credential) {
return credential != null
? new WINNTAuthidEntityPtr(credential) : null;
}
public WINNTAuthidEntityPtr(NetworkCredential credential) {
if (credential == null)
throw new ArgumentNullException("Credential");
try {
string pasword = credential.Password;
var authIdentity = new NativeMethods.COAUTHIDENTITY() {
User = (_huser = new LPWStr(credential.UserName)),
Domain = (_hdomain = new LPWStr(credential.Domain)),
Password = (_hpass = new LPWStr(pasword)),
UserLength = (credential.UserName == null ? 0 : credential.UserName.Length),
DomainLength = (credential.Domain == null ? 0 : credential.Domain .Length),
PasswordLength = (credential.Password == null ? 0 : pasword .Length),
Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE
};
SetHandle<NativeMethods.COAUTHIDENTITY>(ref authIdentity);
} catch {
Free<LPWStr>(ref _hpass);
Free<LPWStr>(ref _hdomain);
Free<LPWStr>(ref _huser);
throw;
}
}
protected override void Dispose(bool disposing) {
base.Dispose(disposing);
Free<LPWStr>(ref _hpass);
Free<LPWStr>(ref _hdomain);
Free<LPWStr>(ref _huser);
}
}
private class WINNTAuthInfoPtr : GlobalPtr {
private WINNTAuthidEntityPtr _identity = null;
public static WINNTAuthInfoPtr Create(WINNTAuthnInfo authInfo) {
return authInfo != null
? new WINNTAuthInfoPtr(authInfo.Credential, authInfo.AuthnLevel, authInfo.ImpersonationLevel) : null;
}
public WINNTAuthInfoPtr(NetworkCredential credential = null,
uint AuthnLevel = RPC_C_AUTHN_LEVEL_DEFAULT,
uint ImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE) {
_identity = WINNTAuthidEntityPtr.Create(credential);
try {
var authInfo = new NativeMethods.COAUTHINFO() {
dwAuthnSvc = RPC_C_AUTHN_WINNT,
dwAuthzSvc = RPC_C_AUTHZ_NONE,
pwszServerPrincName = IntPtr.Zero,
dwAuthnLevel = AuthnLevel,
dwImpersonationLevel = ImpersonationLevel,
pAuthIdentityData = _identity,
dwCapabilities = EOAC_NONE
};
SetHandle<NativeMethods.COAUTHINFO>(ref authInfo);
} catch {
Free<WINNTAuthidEntityPtr>(ref _identity);
throw;
}
}
protected override void Dispose(bool disposing) {
base.Dispose(disposing);
Free<WINNTAuthidEntityPtr>(ref _identity);
}
internal IntPtr Identity { get { return _identity; } }
}
#endregion
public static object CreateInstance(
string progId,
object pUnkOuter = null, CLSCTX dwClsContext = CLSCTX.SERVER) {
return CreateInstanceEx(
NativeMethods.CLSIDFromProgID(progId), IID_IUnknown,
pUnkOuter, dwClsContext);
}
public static object CreateInstance2(
string progId, Guid intfId,
object pUnkOuter = null, CLSCTX dwClsContext = CLSCTX.SERVER) {
return CreateInstanceEx(
NativeMethods.CLSIDFromProgID(progId), intfId,
pUnkOuter, dwClsContext);
}
public static object CreateRemoteInstance(string remoteServer,
string progId, WINNTAuthnInfo authInfo = null,
object pUnkOuter = null, CLSCTX dwClsContext = CLSCTX.REMOTE_SERVER) {
return CreateRemoteInstanceEx(remoteServer,
NativeMethods.CLSIDFromProgID(progId), IID_IUnknown, authInfo,
pUnkOuter, dwClsContext);
}
public static object CreateRemoteInstance2(string remoteServer,
string progId, Guid intfId, WINNTAuthnInfo authInfo = null,
object pUnkOuter = null, CLSCTX dwClsContext = CLSCTX.REMOTE_SERVER) {
return CreateRemoteInstanceEx(remoteServer,
NativeMethods.CLSIDFromProgID(progId), intfId, authInfo,
pUnkOuter, dwClsContext);
}
public static object CreateInstanceEx(
Guid classId, Guid intfId,
object pUnkOuter = null, CLSCTX dwClsContext = CLSCTX.SERVER) {
return NativeMethods.CoCreateInstance(
classId, pUnkOuter, dwClsContext, intfId);
}
public static object CreateRemoteInstanceEx(string remoteServer,
Guid classId, Guid intfId, WINNTAuthnInfo authInfo = null,
object pUnkOuter = null, CLSCTX dwClsContext = CLSCTX.REMOTE_SERVER) {
using (var authInfoPtr = WINNTAuthInfoPtr.Create(authInfo))
using (var intfIdPtr = new PinnedObject<Guid>(ref intfId)) {
NativeMethods.COSERVERINFO si = new NativeMethods.COSERVERINFO() {
dwReserved1 = 0,
pwszName = remoteServer,
pAuthInfo = authInfoPtr,
dwReserved2 = 0
};
NativeMethods.MULTI_QI[] moi = new NativeMethods.MULTI_QI[1];
moi[0] = new NativeMethods.MULTI_QI() {
pIID = intfIdPtr,
pItf = null,
hr = 0
};
NativeMethods.CoCreateInstanceEx(classId, pUnkOuter, dwClsContext, ref si, 1, moi);
if (moi[0].hr < 0)
Marshal.ThrowExceptionForHR(moi[0].hr);
if (moi[0].pItf == null)
Marshal.ThrowExceptionForHR(E_POINTER);
if (authInfoPtr != null && authInfo != null)
SetSecurity(moi[0].pItf, authInfoPtr.Identity, authInfo.AuthnLevel, authInfo.ImpersonationLevel);
return moi[0].pItf;
}
}
private static object SetSecurity(object objDCOM,
IntPtr authidEntity,
uint AuthnLevel = RPC_C_AUTHN_LEVEL_DEFAULT,
uint ImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE) {
//IntPtr ptrInterface = Marshal.GetIUnknownForObject(objDCOM);
NativeMethods.CoSetProxyBlanket(
objDCOM, // pProxy
RPC_C_AUTHN_WINNT, // dwAuthnSvc
RPC_C_AUTHZ_NONE, // dwAuthzSvc
IntPtr.Zero, // pServerPrincName
AuthnLevel, // dwAuthnLevel
ImpersonationLevel, // dwImpLevel
authidEntity, // pAuthInfo
EOAC_NONE); // dwCapabilities
return objDCOM;
}
public static object SetSecurity(object objDCOM, WINNTAuthnInfo authInfo) {
if (authInfo == null)
throw new ArgumentNullException("Authentication-Info");
using (var authidEntity = WINNTAuthidEntityPtr.Create(authInfo.Credential))
return SetSecurity(objDCOM,
authidEntity, authInfo.AuthnLevel, authInfo.ImpersonationLevel);
}
public static object SetSecurity(object objDCOM,
NetworkCredential credential,
uint AuthnLevel = RPC_C_AUTHN_LEVEL_DEFAULT,
uint ImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE) {
using (var authidEntity = WINNTAuthidEntityPtr.Create(credential))
return SetSecurity(objDCOM,
authidEntity, AuthnLevel, ImpersonationLevel);
}
private static class NativeMethods {
public static Guid CLSIDFromProgID(string progId) {
Guid classId;
int hr = NativeMethods.CLSIDFromProgID(progId, out classId);
if (hr < 0)
Marshal.ThrowExceptionForHR(hr);
return classId;
}
[DllImport("ole32.dll")]
public static extern int ProgIDFromCLSID(
[In] ref Guid clsid, [MarshalAs(UnmanagedType.LPWStr)]out string lplpszProgID);
[DllImport("ole32.dll")]
public static extern int CLSIDFromProgID(
[MarshalAs(UnmanagedType.LPWStr)]string lpszProgID, out Guid pclsid);
[DllImport("ole32.dll", ExactSpelling=true, PreserveSig=false)]
[return: MarshalAs(UnmanagedType.Interface)]
public static extern object CoCreateInstance(
[In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
[MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter,
CLSCTX dwClsContext,
[In, MarshalAs(UnmanagedType.LPStruct)] Guid riid);
[StructLayout(LayoutKind.Sequential)]
public struct COAUTHIDENTITY {
//[MarshalAs(UnmanagedType.LPWStr)]
public IntPtr User;
public int UserLength;
//[MarshalAs(UnmanagedType.LPWStr)]
public IntPtr Domain;
public int DomainLength;
//[MarshalAs(UnmanagedType.LPWStr)]
public IntPtr Password;
public int PasswordLength;
public int Flags;
};
[StructLayout(LayoutKind.Sequential)]
public struct COAUTHINFO {
public uint dwAuthnSvc;
public uint dwAuthzSvc;
//[MarshalAs(UnmanagedType.LPWStr)]
public IntPtr pwszServerPrincName;
public uint dwAuthnLevel;
public uint dwImpersonationLevel;
public IntPtr pAuthIdentityData;
public uint dwCapabilities;
}
[StructLayout(LayoutKind.Sequential)]
public struct COSERVERINFO {
public uint dwReserved1;
[MarshalAs(UnmanagedType.LPWStr)]
public string pwszName;
public IntPtr pAuthInfo;
public uint dwReserved2;
}
[StructLayout(LayoutKind.Sequential)]
public struct MULTI_QI {
public IntPtr pIID;
[MarshalAs(UnmanagedType.Interface)] public object pItf;
public int hr;
}
[DllImport("ole32.dll", ExactSpelling=true, PreserveSig=false)]
[return: MarshalAs(UnmanagedType.Interface)]
public static extern object CoCreateInstanceEx(
[In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
[MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter,
CLSCTX dwClsCtx,
[In]ref COSERVERINFO pServerInfo,
uint cmq,
[In, Out] MULTI_QI[] pResults);
[DllImport("Ole32.dll", PreserveSig = false)]
public static extern void CoSetProxyBlanket(
[MarshalAs(UnmanagedType.Interface)]
object pProxy, // IntPtr pProxy,
uint dwAuthnSvc,
uint dwAuthzSvc,
IntPtr pServerPrincName,
uint dwAuthLevel,
uint dwImpLevel,
IntPtr pAuthInfo,
uint dwCapabilities);
}
}
}