You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

325 lines
12 KiB
C#

namespace OPC.Common
{
using System;
using System.Runtime.InteropServices;
public class ComApi
{
private const uint CLSCTX_INPROC_HANDLER = 2;
private const uint CLSCTX_INPROC_SERVER = 1;
private const uint CLSCTX_LOCAL_SERVER = 4;
private const uint CLSCTX_REMOTE_SERVER = 0x10;
private const uint COLE_DEFAULT_AUTHINFO = uint.MaxValue;
private const uint COLE_DEFAULT_PRINCIPAL = 0;
private const uint EOAC_DEFAULT = 0x800;
private static readonly Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046");
private const uint LEVEL_SERVER_INFO_100 = 100;
private const uint LEVEL_SERVER_INFO_101 = 0x65;
private const int MAX_COMPUTERNAME_LENGTH = 0x1f;
private const int MAX_PREFERRED_LENGTH = -1;
private const uint RPC_C_AUTHN_LEVEL_PKT_PRIVACY = 6;
private const int RPC_C_AUTHZ_DCE = 2;
private const int RPC_C_AUTHZ_DEFAULT = -1;
private const int RPC_C_AUTHZ_NAME = 1;
private const int RPC_C_AUTHZ_NONE = 0;
private const uint RPC_C_IMP_LEVEL_DEFAULT = 0;
private const uint SEC_WINNT_AUTH_IDENTITY_ANSI = 1;
private const uint SEC_WINNT_AUTH_IDENTITY_UNICODE = 2;
private const uint SV_TYPE_SERVER = 2;
private const uint SV_TYPE_WORKSTATION = 1;
private const uint URPC_C_AUTHN_DEFAULT = uint.MaxValue;
private const uint URPC_C_AUTHZ_DEFAULT = uint.MaxValue;
[DllImport("ole32.dll")]
private static extern void CoCreateInstanceEx(ref Guid clsid, [MarshalAs(UnmanagedType.IUnknown)] object punkOuter, uint dwClsCtx, [In] ref COSERVERINFO pServerInfo, uint dwCount, [In, Out] MULTI_QI[] pResults);
[DllImport("ole32.dll")]
private static extern int CoInitializeSecurity(IntPtr pSecDesc, int cAuthSvc, SOLE_AUTHENTICATION_SERVICE[] asAuthSvc, IntPtr pReserved1, uint dwAuthnLevel, uint dwImpLevel, IntPtr pAuthList, uint dwCapabilities, IntPtr pReserved3);
[DllImport("OLE32.DLL", CharSet=CharSet.Auto)]
private static extern uint CoSetProxyBlanket(object pProxy, uint dwAuthnSvc, uint dwAuthzSvc, uint pServerPrincName, uint dwAuthnLevel, uint dwImpLevel, uint pAuthInfo, uint dwCapababilities);
public static object CreateInstance(Guid clsid, Host host)
{
string str = (host != null) ? host.HostName : null;
string str2 = (host != null) ? host.UserName : null;
string str3 = (host != null) ? host.Password : null;
string str4 = (host != null) ? host.Domain : null;
GCHandle handle = GCHandle.Alloc(str2, GCHandleType.Pinned);
GCHandle handle2 = GCHandle.Alloc(str3, GCHandleType.Pinned);
GCHandle handle3 = GCHandle.Alloc(str4, GCHandleType.Pinned);
GCHandle handle4 = new GCHandle();
if ((str2 != null) && (str2 != string.Empty))
{
COAUTHIDENTITY coauthidentity = new COAUTHIDENTITY();
coauthidentity.User = handle.AddrOfPinnedObject();
coauthidentity.UserLength = (str2 != null) ? ((uint) str2.Length) : 0;
coauthidentity.Password = handle2.AddrOfPinnedObject();
coauthidentity.PasswordLength = (str3 != null) ? ((uint) str3.Length) : 0;
coauthidentity.Domain = handle3.AddrOfPinnedObject();
coauthidentity.DomainLength = (str4 != null) ? ((uint) str4.Length) : 0;
coauthidentity.Flags = 2;
handle4 = GCHandle.Alloc(coauthidentity, GCHandleType.Pinned);
}
COAUTHINFO coauthinfo = new COAUTHINFO();
coauthinfo.dwAuthnSvc = 10;
coauthinfo.dwAuthzSvc = 0;
coauthinfo.pwszServerPrincName = IntPtr.Zero;
coauthinfo.dwAuthnLevel = 2;
coauthinfo.dwImpersonationLevel = 3;
coauthinfo.pAuthIdentityData = handle4.IsAllocated ? handle4.AddrOfPinnedObject() : IntPtr.Zero;
coauthinfo.dwCapabilities = 0;
GCHandle handle5 = GCHandle.Alloc(coauthinfo, GCHandleType.Pinned);
COSERVERINFO pServerInfo = new COSERVERINFO();
pServerInfo.pwszName = str;
pServerInfo.pAuthInfo = handle5.AddrOfPinnedObject();
pServerInfo.dwReserved1 = 0;
pServerInfo.dwReserved2 = 0;
GCHandle handle6 = GCHandle.Alloc(IID_IUnknown, GCHandleType.Pinned);
MULTI_QI[] pResults = new MULTI_QI[1];
pResults[0].iid = handle6.AddrOfPinnedObject();
pResults[0].pItf = null;
pResults[0].hr = 0;
try
{
CoCreateInstanceEx(ref clsid, null, 20, ref pServerInfo, 1, pResults);
}
catch (Exception exception)
{
if (handle.IsAllocated)
{
handle.Free();
}
if (handle2.IsAllocated)
{
handle2.Free();
}
if (handle3.IsAllocated)
{
handle3.Free();
}
if (handle4.IsAllocated)
{
handle4.Free();
}
if (handle5.IsAllocated)
{
handle5.Free();
}
if (handle6.IsAllocated)
{
handle6.Free();
}
throw exception;
}
if (handle.IsAllocated)
{
handle.Free();
}
if (handle2.IsAllocated)
{
handle2.Free();
}
if (handle3.IsAllocated)
{
handle3.Free();
}
if (handle4.IsAllocated)
{
handle4.Free();
}
if (handle5.IsAllocated)
{
handle5.Free();
}
if (handle6.IsAllocated)
{
handle6.Free();
}
if (pResults[0].hr != 0)
{
throw new ApplicationException(string.Format("Create Instance Failed: 0x{0,0:X}", pResults[0].hr));
}
return pResults[0].pItf;
}
public static string[] EnumComputers()
{
IntPtr ptr;
int entriesread = 0;
int totalentries = 0;
int num3 = NetServerEnum(IntPtr.Zero, 100, out ptr, -1, out entriesread, out totalentries, 3, IntPtr.Zero, IntPtr.Zero);
if (num3 != 0)
{
throw new ApplicationException("NetApi Error = " + string.Format("0x{0,0:X}", num3));
}
string[] strArray = new string[entriesread];
IntPtr ptr2 = ptr;
for (int i = 0; i < entriesread; i++)
{
SERVER_INFO_100 server_info_ = (SERVER_INFO_100) Marshal.PtrToStructure(ptr2, typeof(SERVER_INFO_100));
strArray[i] = server_info_.sv100_name;
ptr2 = (IntPtr) (ptr2.ToInt32() + Marshal.SizeOf(typeof(SERVER_INFO_100)));
}
NetApiBufferFree(ptr);
return strArray;
}
public static string GetComputerName()
{
string str = null;
int lpnSize = 0x20;
IntPtr lpBuffer = Marshal.AllocCoTaskMem(lpnSize * 2);
if (GetComputerNameW(lpBuffer, ref lpnSize) != 0)
{
str = Marshal.PtrToStringUni(lpBuffer, lpnSize);
}
Marshal.FreeCoTaskMem(lpBuffer);
return str;
}
[DllImport("Kernel32.dll")]
private static extern int GetComputerNameW(IntPtr lpBuffer, ref int lpnSize);
internal static void InitializeSecurity()
{
int num = CoInitializeSecurity(IntPtr.Zero, -1, null, IntPtr.Zero, 1, 2, IntPtr.Zero, 0, IntPtr.Zero);
if (num != 0)
{
throw new ApplicationException("COM Security Error = " + string.Format("0x{0,0:X}", num));
}
}
public static void InitializeSecurity(int authLevel, int impLevel, int eoac)
{
int num = CoInitializeSecurity(IntPtr.Zero, -1, null, IntPtr.Zero, (uint) authLevel, (uint) impLevel, IntPtr.Zero, (uint) eoac, IntPtr.Zero);
if (num != 0)
{
throw new ApplicationException("COM Security Error = " + string.Format("0x{0,0:X}", num));
}
}
[DllImport("Netapi32.dll")]
internal static extern int NetApiBufferFree(IntPtr buffer);
[DllImport("Netapi32.dll")]
private static extern int NetServerEnum(IntPtr servername, uint level, out IntPtr bufptr, int prefmaxlen, out int entriesread, out int totalentries, uint servertype, IntPtr domain, IntPtr resume_handle);
internal static void SetProxyBlanket(object srvUnk)
{
try
{
CoSetProxyBlanket(srvUnk, uint.MaxValue, uint.MaxValue, uint.MaxValue, 6, 0, 0, 0x800);
}
catch (Exception exception)
{
string message = exception.Message;
}
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
private struct COAUTHIDENTITY
{
internal IntPtr User;
internal uint UserLength;
internal IntPtr Domain;
internal uint DomainLength;
internal IntPtr Password;
internal uint PasswordLength;
internal uint Flags;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
private struct COAUTHINFO
{
internal uint dwAuthnSvc;
internal uint dwAuthzSvc;
internal IntPtr pwszServerPrincName;
internal uint dwAuthnLevel;
internal uint dwImpersonationLevel;
internal IntPtr pAuthIdentityData;
internal uint dwCapabilities;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
private struct COSERVERINFO
{
internal uint dwReserved1;
[MarshalAs(UnmanagedType.LPWStr)]
public string pwszName;
public IntPtr pAuthInfo;
public uint dwReserved2;
}
internal enum EOAC
{
ACCESS_CONTROL = 4,
APPID = 8,
CLOAKING = 0x10,
DYNAMIC_CLOAKING = 0x40,
MUTUAL_AUTH = 1,
NONE = 0,
SECURE_REFS = 2,
STATIC_CLOAKING = 0x20
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
private struct MULTI_QI
{
internal IntPtr iid;
[MarshalAs(UnmanagedType.IUnknown)]
internal object pItf;
internal uint hr;
}
internal enum RPC_C_AUTHN_LEVEL
{
DEFAULT,
NONE,
CONNECT,
CALL,
PKT,
PKT_INTEGRITY,
PKT_PRIVACY
}
internal enum RPC_C_AUTHN_SVC
{
DCE_public = 1,
DCE_PUBLIC = 2,
DEC_PUBLIC = 4,
DEFAULT = -1,
DIGEST = 0x15,
DPA = 0x11,
GSS_KERBEROS = 0x10,
GSS_NEGOTIATE = 9,
GSS_SCHANNEL = 14,
MQ = 100,
MSN = 0x12,
NONE = 0,
WINNT = 10
}
internal enum RPC_C_IMP_LEVEL
{
ANONYMOUS = 1,
DELEGATE = 4,
IDENTIFY = 2,
IMPERSONATE = 3
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
private struct SERVER_INFO_100
{
internal uint sv100_platform_id;
[MarshalAs(UnmanagedType.LPWStr)]
internal string sv100_name;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
private struct SOLE_AUTHENTICATION_SERVICE
{
internal uint dwAuthnSvc;
internal uint dwAuthzSvc;
[MarshalAs(UnmanagedType.LPWStr)]
internal string pPrincipalName;
internal int hr;
}
}
}