using System; using System.Net; using System.ComponentModel; using System.Runtime.InteropServices; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using C4IT.Logging; using static C4IT.Logging.cLogManager; using System.Reflection; namespace C4IT_IAM { public class cNetworkConnection : IDisposable { private const uint MAX_PREFERRED_LENGTH = 0xFFFFFFFF; private const int NERR_Success = 0; string _networkName; public cNetworkConnection(string networkName, string userName, string Password) { LogMethodBegin(MethodBase.GetCurrentMethod()); try { _networkName = networkName; var netResource = new NetResource() { Scope = ResourceScope.GlobalNetwork, ResourceType = ResourceType.Disk, DisplayType = ResourceDisplaytype.Share, RemoteName = networkName }; var result = WNetAddConnection2( netResource, Password, userName, 0); if (result != 0) { DefaultLogger.LogEntry(LogLevels.Debug, $"Error in connect occured ({result}) {new Win32Exception(result).Message}"); throw new Win32Exception(result); } } finally { LogMethodEnd(MethodBase.GetCurrentMethod()); } } ~cNetworkConnection() { Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { WNetCancelConnection2(_networkName, 0, true); } public SHARE_INFO_1[] EnumNetShares(string Server) { List ShareInfos = new List(); int entriesread = 0; int totalentries = 0; int resume_handle = 0; int nStructSize = Marshal.SizeOf(typeof(SHARE_INFO_1)); IntPtr bufPtr = IntPtr.Zero; StringBuilder server = new StringBuilder(Server); int ret = NetShareEnum(server, 1, ref bufPtr, MAX_PREFERRED_LENGTH, ref entriesread, ref totalentries, ref resume_handle); if (ret == NERR_Success) { IntPtr currentPtr = bufPtr; for (int i = 0; i < entriesread; i++) { SHARE_INFO_1 shi1 = (SHARE_INFO_1)Marshal.PtrToStructure(currentPtr, typeof(SHARE_INFO_1)); ShareInfos.Add(shi1); currentPtr += nStructSize; } NetApiBufferFree(bufPtr); return ShareInfos.ToArray(); } else { ShareInfos.Add(new SHARE_INFO_1("ERROR=" + ret.ToString(), 10, string.Empty)); return ShareInfos.ToArray(); } } public static bool TryGetDfsEntryPath(string dfsEntryPath, out string entryPath) { entryPath = string.Empty; if (string.IsNullOrWhiteSpace(dfsEntryPath)) return false; IntPtr buffer = IntPtr.Zero; try { int result = NetDfsGetInfo(dfsEntryPath, null, null, 1, ref buffer); if (result != NERR_Success || buffer == IntPtr.Zero) return false; DFS_INFO_1 info = (DFS_INFO_1)Marshal.PtrToStructure(buffer, typeof(DFS_INFO_1)); entryPath = info.EntryPath ?? dfsEntryPath; return !string.IsNullOrWhiteSpace(entryPath); } catch (Exception ex) { DefaultLogger.LogException(ex); return false; } finally { if (buffer != IntPtr.Zero) NetApiBufferFree(buffer); } } [DllImport("mpr.dll")] private static extern int WNetAddConnection2(NetResource netResource, string password, string username, int flags); [DllImport("mpr.dll")] private static extern int WNetCancelConnection2(string name, int flags, bool force); [DllImport("Netapi32.dll", SetLastError = true)] static extern int NetApiBufferFree(IntPtr Buffer); [DllImport("Netapi32.dll", CharSet = CharSet.Unicode)] private static extern int NetShareEnum( StringBuilder ServerName, int level, ref IntPtr bufPtr, uint prefmaxlen, ref int entriesread, ref int totalentries, ref int resume_handle ); [DllImport("Netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern int NetDfsGetInfo( string DfsEntryPath, string ServerName, string ShareName, int Level, ref IntPtr Buffer ); } [StructLayout(LayoutKind.Sequential)] public class NetResource { public ResourceScope Scope; public ResourceType ResourceType; public ResourceDisplaytype DisplayType; public int Usage; public string LocalName; public string RemoteName; public string Comment; public string Provider; } public enum ResourceScope : int { Connected = 1, GlobalNetwork, Remembered, Recent, Context }; public enum ResourceType : int { Any = 0, Disk = 1, Print = 2, Reserved = 8, } public enum ResourceDisplaytype : int { Generic = 0x0, Domain = 0x01, Server = 0x02, Share = 0x03, File = 0x04, Group = 0x05, Network = 0x06, Root = 0x07, Shareadmin = 0x08, Directory = 0x09, Tree = 0x0a, Ndscontainer = 0x0b } public enum NetError : uint { NERR_Success = 0, NERR_BASE = 2100, NERR_UnknownDevDir = (NERR_BASE + 16), NERR_DuplicateShare = (NERR_BASE + 18), NERR_BufTooSmall = (NERR_BASE + 23), } public enum SHARE_TYPE : uint { STYPE_DISKTREE = 0, STYPE_PRINTQ = 1, STYPE_DEVICE = 2, STYPE_IPC = 3, STYPE_SPECIAL = 0x80000000, } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct SHARE_INFO_1 { public string shi1_netname; public uint shi1_type; public string shi1_remark; public SHARE_INFO_1(string sharename, uint sharetype, string remark) { this.shi1_netname = sharename; this.shi1_type = sharetype; this.shi1_remark = remark; } public override string ToString() { return shi1_netname; } } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct DFS_INFO_1 { public string EntryPath; } }