|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|