6
\$\begingroup\$

I have made a class for some Netapi32.dll functions in C#. I would like to know if there are any big problems with it or if there is some other function needed in general.

Functions:

  • NetFileEnum
  • NetShareEnum
  • NetFileClose
  • NetSessionEnum
  • NetApiBufferFree

Here is the class:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;

namespace ph03n1x
{
    public class NetAPI32
    {

        #region Constants
        protected const int MAX_PREFERRED_LENGTH = -1;
        #endregion

        #region StructLayout
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct FILE_INFO_3
        {
            public int fi3_id;
            public int fi3_permission;
            public int fi3_num_locks;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string fi3_pathname;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string fi3_username;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct SESSION_INFO_502
        {
            /// <summary>
            /// Unicode string specifying the name of the computer that established the session.
            /// </summary>
            [MarshalAs(UnmanagedType.LPWStr)]
            public string si502_cname;

            /// <summary>
            /// <value>Unicode string specifying the name of the user who established the session.</value>
            /// </summary>
            [MarshalAs(UnmanagedType.LPWStr)]
            public string si502_username;

            /// <summary>
            /// <value>Specifies the number of files, devices, and pipes opened during the session.</value>
            /// </summary>
            public uint si502_num_opens;

            /// <summary>
            /// <value>Specifies the number of seconds the session has been active. </value>
            /// </summary>
            public uint si502_time;

            /// <summary>
            /// <value>Specifies the number of seconds the session has been idle.</value>
            /// </summary>
            public uint si502_idle_time;

            /// <summary>
            /// <value>Specifies a value that describes how the user established the session.</value>
            /// </summary>
            public uint si502_user_flags;

            /// <summary>
            /// <value>Unicode string that specifies the type of client that established the session.</value>
            /// </summary>
            [MarshalAs(UnmanagedType.LPWStr)]
            public string si502_cltype_name;

            /// <summary>
            /// <value>Specifies the name of the transport that the client is using to communicate with the server.</value>
            /// </summary>
            [MarshalAs(UnmanagedType.LPWStr)]
            public string si502_transport;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct SHARE_INFO_2
        {
            [MarshalAs(UnmanagedType.LPWStr)]
            public string NetName;
            public int ShareType;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string Remark;
            public int Permissions;
            public int MaxUsers;
            public int CurrentUsers;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string Path;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string Password;
        }

        #endregion StructLayout

        #region enum
        public enum NERR
        {
            /// <summary>
            /// Operation was a success.
            /// </summary>
            NERR_Success = 0,

            /// <summary>
            /// More data available to read. dderror getting all data.
            /// </summary>
            ERROR_MORE_DATA = 234,

            /// <summary>
            /// Network browsers not available.
            /// </summary>
            ERROR_NO_BROWSER_SERVERS_FOUND = 6118,

            /// <summary>
            /// LEVEL specified is not valid for this call.
            /// </summary>
            ERROR_INVALID_LEVEL = 124,

            /// <summary>
            /// Security context does not have permission to make this call.
            /// </summary>
            ERROR_ACCESS_DENIED = 5,

            /// <summary>
            /// Parameter was incorrect.
            /// </summary>
            ERROR_INVALID_PARAMETER = 87,

            /// <summary>
            /// Out of memory.
            /// </summary>
            ERROR_NOT_ENOUGH_MEMORY = 8,

            /// <summary>
            /// Unable to contact resource. Connection timed out.
            /// </summary>
            ERROR_NETWORK_BUSY = 54,

            /// <summary>
            /// Network Path not found.
            /// </summary>
            ERROR_BAD_NETPATH = 53,

            /// <summary>
            /// No available network connection to make call.
            /// </summary>
            ERROR_NO_NETWORK = 1222,

            /// <summary>
            /// Pointer is not valid.
            /// </summary>
            ERROR_INVALID_HANDLE_STATE = 1609,

            /// <summary>
            /// Extended Error.
            /// </summary>
            ERROR_EXTENDED_ERROR = 1208,

            /// <summary>
            /// Base.
            /// </summary>
            NERR_BASE = 2100,

            /// <summary>
            /// Unknown Directory.
            /// </summary>
            NERR_UnknownDevDir = (NERR_BASE + 16),

            /// <summary>
            /// Duplicate Share already exists on server.
            /// </summary>
            NERR_DuplicateShare = (NERR_BASE + 18),

            /// <summary>
            /// Memory allocation was to small.
            /// </summary>
            NERR_BufTooSmall = (NERR_BASE + 23)
        }

        public enum NET_API_STATUS : uint
        {
            NERR_Success = 0,

            /// <summary>
            /// This computer name is invalid.
            /// </summary>
            NERR_InvalidComputer = 2351,

            /// <summary>
            /// This operation is only allowed on the primary domain controller of the domain.
            /// </summary>
            NERR_NotPrimary = 2226,

            /// <summary>
            /// This operation is not allowed on this special group.
            /// </summary>
            NERR_SpeGroupOp = 2234,

            /// <summary>
            /// This operation is not allowed on the last administrative account.
            /// </summary>
            NERR_LastAdmin = 2452,

            /// <summary>
            /// The password parameter is invalid.
            /// </summary>
            NERR_BadPassword = 2203,

            /// <summary>
            /// The password does not meet the password policy requirements. Check the minimum password length, password complexity and password history requirements.
            /// </summary>
            NERR_PasswordTooShort = 2245,

            /// <summary>
            /// The user name could not be found.
            /// </summary>
            NERR_UserNotFound = 2221,

            ERROR_ACCESS_DENIED = 5,
            ERROR_NOT_ENOUGH_MEMORY = 8,
            ERROR_INVALID_PARAMETER = 87,
            ERROR_INVALID_NAME = 123,
            ERROR_INVALID_LEVEL = 124,
            ERROR_MORE_DATA = 234,
            ERROR_SESSION_CREDENTIAL_CONFLICT = 1219
        }
        #endregion enum

        #region DllImports

        #region NetFileEnum
        [DllImport("netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern int NetFileEnum(
            string servername,
            string basepath,
            string username,
            int level,
            ref IntPtr bufptr,
            int prefmaxlen,
            out int entriesread,
            out int totalentries,
            IntPtr resume_handle
            );
        #endregion NetFileEnum

        #region NetShareEnum
        [DllImport("netapi32", CharSet = CharSet.Unicode)]
        protected static extern int NetShareEnum(
            string lpServerName,
            int dwLevel,
            out IntPtr lpBuffer,
            int dwPrefMaxLen,
            out int entriesRead,
            out int totalEntries,
            ref int hResume
            );
        #endregion NetShareEnum

        #region NetFileClose
        [DllImport("Netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern int NetFileClose(string servername, int id);
        #endregion NetFileClose

        #region NetSessionEnum
        [DllImport("netapi32.dll", SetLastError = true)]
        public static extern int NetSessionEnum
            (
            [In, MarshalAs(UnmanagedType.LPWStr)] string ServerName,
            [In, MarshalAs(UnmanagedType.LPWStr)] string UncClientName,
            [In, MarshalAs(UnmanagedType.LPWStr)] string UserName,
            Int32 Level,
            out IntPtr bufptr,
            int prefmaxlen,
            ref Int32 entriesread,
            ref Int32 totalentries,
            ref Int32 resume_handle
            );
        #endregion NetSessionEnum

        #region NetApiBufferFree
        [DllImport("Netapi32.dll", SetLastError = true)]
        public static extern int NetApiBufferFree(IntPtr Buffer);
        #endregion NetApiBufferFree

        #endregion DllImports

        #region myMethods
        public static List<SESSION_INFO_502> BuildNetSessionEnumList(string server)
        {
            List<SESSION_INFO_502> list = new List<SESSION_INFO_502>();

            IntPtr BufPtr;
            int res = 0;
            Int32 er = 0, tr = 0, resume = 0;
            SESSION_INFO_502[] results = new SESSION_INFO_502[0];
            res = NetSessionEnum(null, null, null, 502, out BufPtr, -1, ref er, ref tr, ref resume);
            results = new SESSION_INFO_502[er];
            if (res == (int)NERR.ERROR_MORE_DATA || res == (int)NERR.NERR_Success)
            {
                Int32 p = BufPtr.ToInt32();
                for (int i = 0; i < er; i++)
                {

                    SESSION_INFO_502 si = (SESSION_INFO_502)Marshal.PtrToStructure(new IntPtr(p), typeof(SESSION_INFO_502));
                    results[i] = si;
                    p += Marshal.SizeOf(typeof(SESSION_INFO_502));

                    list.Add(si);
                }
            }
            Marshal.FreeHGlobal(BufPtr);

            return list;

        }
        public static List<FILE_INFO_3> BuildNetFileEnumList(string server)
        {
            List<FILE_INFO_3> list = new List<FILE_INFO_3>();

            const int MAX_PREFERRED_LENGTH = -1;
            int dwReadEntries;
            int dwTotalEntries;
            IntPtr pBuffer = IntPtr.Zero;
            FILE_INFO_3 pCurrent = new FILE_INFO_3();

            int dwStatus = NetFileEnum(server, null, null, 3, ref pBuffer, MAX_PREFERRED_LENGTH, out dwReadEntries,
                out dwTotalEntries, IntPtr.Zero);

            if (dwStatus == 0)
            {
                for (int dwIndex = 0; dwIndex < dwReadEntries; dwIndex++)
                {

                    IntPtr iPtr = new IntPtr(pBuffer.ToInt32() + (dwIndex * Marshal.SizeOf(pCurrent)));
                    pCurrent = (FILE_INFO_3)Marshal.PtrToStructure(iPtr, typeof(FILE_INFO_3));

                    list.Add(pCurrent);
                }
                NetApiBufferFree(pBuffer);
            }
            return list;
        }
        public static List<SHARE_INFO_2> BuildNetShareEnumList(string server)
        {
            //Note that this code will only work if run as administrator!!

            List<SHARE_INFO_2> list = new List<SHARE_INFO_2>();
            int entriesRead, totalEntries, nRet, hResume = 0;
            IntPtr pBuffer = IntPtr.Zero;

            nRet = NetShareEnum(server, 2, out pBuffer, -1,
                    out entriesRead, out totalEntries, ref hResume);

            if (entriesRead > 0)
            {
                Type t = typeof(SHARE_INFO_2);
                int offset = Marshal.SizeOf(t);

                for (int i = 0, lpItem = pBuffer.ToInt32(); i < entriesRead; i++, lpItem += offset)
                {
                    IntPtr pItem = new IntPtr(lpItem);

                    SHARE_INFO_2 si = (SHARE_INFO_2)Marshal.PtrToStructure(pItem, t);
                    list.Add(si);
                }
            }
            NetApiBufferFree(pBuffer);

            return list;
        }

        #endregion myMethods
    }
}

Here is some samples on how to use them:

    List<NetAPI32.SHARE_INFO_2> shares = NetAPI32.BuildNetShareEnumList(null);
    foreach (NetAPI32.SHARE_INFO_2 share in shares)
    {
        int maxAllowedUsers = share.MaxUsers;
        int shareType = share.ShareType;
        string shareName = share.NetName;
        string sharePath = share.Path;
        string shareRemark = share.Remark;
        int currentConectedUsers = share.CurrentUsers;
    }

    List<NetAPI32.FILE_INFO_3> fileconnections = NetAPI32.BuildNetFileEnumList(null);
    foreach (NetAPI32.FILE_INFO_3 fileconnection in fileconnections)
    {
        int remoteUserPrimition = fileconnection.fi3_permission;
        string remoteUsername = fileconnection.fi3_username;
        string sharePath = fileconnection.fi3_pathname;
        int shareID = fileconnection.fi3_id;
    }

    List<NetAPI32.SESSION_INFO_502> connectionsInfo = NetAPI32.BuildNetSessionEnumList(null);
    foreach (NetAPI32.SESSION_INFO_502 connectionInfo in connectionsInfo)
    {
        string remoteUsername = connectionInfo.si502_username;
        string remoteIP = connectionInfo.si502_cname;
        int conectionTime = Convert.ToInt32(connectionInfo.si502_time);
        int fileOpenCount = Convert.ToInt32(connectionInfo.si502_num_opens);
    }

Most of the code is a Frankenstein's monster of code googled.

\$\endgroup\$

3 Answers 3

3
\$\begingroup\$

BuildNetSessionEnumList()

  • Declaring multiple variables on the same line reduces readability.
  • You don't really use the SESSION_INFO_502[] results array and you can safely remove it.

Naming

  • You have SHARE_INFO_2 si and FILE_INFO_3 pCurrent.
  • Local variables should be named using camelCase casing. See the .NET style guide.
  • You should avoid shortening variable names; that reduces readability.
  • Using list for the name of each requested List<T> also reduces readability.
  • Other places that have a .NET implementation of NetSessionEnum, e.g. the PInvoke signature, have well-named parameters. Why doesn't your code use those names when calling this method? You name them res, er, tr = 0, and resume which doesn't communicate anything about them.

You should declare variables as near as possible to their usage. In the BuildNetFileEnumList() method you are declaring FILE_INFO_3 pCurrent = new FILE_INFO_3(); at the top but need it only inside of the loop.
Additionally, there's no need to use new at that point, since later in the loop you are assigning a new value to it.


You should be consistent in the style you use.

In the BuildNetSessionEnumList() method you are incrementing the pointer like

    Int32 p = BufPtr.ToInt32();
    for (int i = 0; i < er; i++)
    {

        SESSION_INFO_502 si = (SESSION_INFO_502)Marshal.PtrToStructure(new IntPtr(p), typeof(SESSION_INFO_502));
        p += Marshal.SizeOf(typeof(SESSION_INFO_502));

        list.Add(si);
    }

and in the BuildNetFileEnumList() method like

    for (int dwIndex = 0; dwIndex < dwReadEntries; dwIndex++)
    {

        IntPtr iPtr = new IntPtr(pBuffer.ToInt32() + (dwIndex * Marshal.SizeOf(pCurrent)));
        pCurrent = (FILE_INFO_3)Marshal.PtrToStructure(iPtr, typeof(FILE_INFO_3));

        list.Add(pCurrent);
    }

and in the BuildNetShareEnumList() method you are using a third way

    Type t = typeof(SHARE_INFO_2);
    int offset = Marshal.SizeOf(t);

    for (int i = 0, lpItem = pBuffer.ToInt32(); i < entriesRead; i++, lpItem += offset)
    {
        IntPtr pItem = new IntPtr(lpItem);

        SHARE_INFO_2 si = (SHARE_INFO_2)Marshal.PtrToStructure(pItem, t);
        list.Add(si);
    }

You have declared a protected const int MAX_PREFERRED_LENGTH = -1; at class level and then again inside the BuildNetFileEnumList() method const int MAX_PREFERRED_LENGTH = -1;.

\$\endgroup\$
3
  • \$\begingroup\$ Thanks a lot, I will look into fixing "Frankenstein's monster" feel to it then updating this post with the results. \$\endgroup\$ Commented May 6, 2015 at 4:42
  • 1
    \$\begingroup\$ Don't update the post, see what you may and may not do after receiving answers. \$\endgroup\$
    – Heslacher
    Commented May 6, 2015 at 6:02
  • \$\begingroup\$ Ok thanks for the advice !! i have updated the code somewhat... \$\endgroup\$ Commented May 14, 2015 at 9:21
2
\$\begingroup\$

As of this writing you have a very good detailed answer, and you've already updated your code as answer as well. The new code looks a lot cleaner but both the old code and new code - particularly your build methods - require a server parameter. Just one example of the many:

Old Code:

public static List<SESSION_INFO_502> BuildNetSessionEnumList(string server)

New Code:

public static List<SessionInfo502> BuildNetSessionEnumList(string server)

Since the parameter is not optional, the code to use it looks kind of clunky:

List<NetAPI32.SessionInfo502> connectionsInfo = NetAPI32.BuildNetSessionEnumList(null);

This can be cleaned up by making the parameter optional in the signature, and also by using var when using it. Example:

Definition:

public static List<SessionInfo502> BuildNetSessionEnumList(string server = null)

Usage Example:

var connectionsInfo = NetAPI32.BuildNetSessionEnumList();
\$\endgroup\$
0
0
\$\begingroup\$

I had a bit of time today to work on this, im still not sure if everything is 100% but here is update. Mainly i took out a lot of unnecessary/redundant/confusing code and made things uniform/readable. I may have broken something along the way so please review again. I tried to follow Heslacher's guidelines, and added some extra functions.

Functions:

NetFileEnum
NetShareEnum
NetSessionDel
NetShareDel
NetSessionEnum
NetApiBufferFree

Here is the class again:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;

namespace ph03n1x
{
    public class NetAPI32
    {
        #region StructLayout
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct FileInfo3
        {
            public int SessionID;
            public int Permission;
            public int NumLocks;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string PathName;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string UserName;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct SessionInfo502
        {
            [MarshalAs(UnmanagedType.LPWStr)]
            public string ComputerName;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string UserName;
            public uint NumOpens;
            public uint SecondsActive;
            public uint SecondsIdle;
            public uint UserFlags;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string ClientType;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string Transport;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct ShareInfo2
        {
            [MarshalAs(UnmanagedType.LPWStr)]
            public string NetName;
            public int ShareType;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string Remark;
            public int Permissions;
            public int MaxUsers;
            public int CurrentUsers;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string Path;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string Password;
        }

        #endregion StructLayout

        #region DllImports

        #region NetFileEnum
        [DllImport("netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern int NetFileEnum(
            string serverName,
            string basePath,
            string userName,
            int level,
            ref IntPtr buffer,
            int prefMaxLength,
            out int entriesRead,
            out int totalEntries,
            ref int resumeHandle
            );
        #endregion NetFileEnum

        #region NetShareEnum
        [DllImport("netapi32", CharSet = CharSet.Unicode)]
        protected static extern int NetShareEnum(
            string serverName,
            int level,
            out IntPtr buffer,
            int prefMaxLength,
            out int entriesRead,
            out int totalEntries,
            ref int resumeHandle
            );
        #endregion NetShareEnum

        #region NetSessionDel
        [DllImport("NetApi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        internal static extern uint NetSessionDel(
             string serverName,
             string uncClientName,
             string userName);
        //eg. NetSessionDel(null, null, "USERNAMETODELETE")
        #endregion NetSessionDel

        #region NetShareDel
        [DllImport("netapi32.dll", SetLastError = true)]
        static extern uint NetShareDel(
            [MarshalAs(UnmanagedType.LPWStr)] 
            string serverName,
            [MarshalAs(UnmanagedType.LPWStr)] 
            string shareName,
            Int32 reserved //must be 0
                    );
        #endregion NetShareDel

        #region NetSessionEnum
        [DllImport("netapi32.dll", SetLastError = true)]
        public static extern int NetSessionEnum
            (
            [In, MarshalAs(UnmanagedType.LPWStr)]
            string serverName,
            [In, MarshalAs(UnmanagedType.LPWStr)]
            string uncClientName,
            [In, MarshalAs(UnmanagedType.LPWStr)]
            string userName,
            Int32 level,
            out IntPtr buffer,
            int prefmaxlen,
            out int entriesRead,
            out int totalEntries,
            ref int resumeHandle
            );
        #endregion NetSessionEnum

        #region NetApiBufferFree
        [DllImport("Netapi32.dll", SetLastError = true)]
        public static extern int NetApiBufferFree(IntPtr Buffer);
        #endregion NetApiBufferFree

        #endregion DllImports

        #region Methods
        public static List<SessionInfo502> BuildNetSessionEnumList(string server)
        {
            List<SessionInfo502> list = new List<SessionInfo502>();

            int entriesRead;
            int totalEntries;
            int resumeHandle = 0;
            IntPtr pBuffer = IntPtr.Zero;
            int status = NetSessionEnum(server, null, null, 502, out pBuffer, -1, out entriesRead, out totalEntries, ref resumeHandle);

            if (status == 0 & entriesRead > 0)
            {
                Type shareinfoType = typeof(SessionInfo502);
                int offset = Marshal.SizeOf(shareinfoType);

                for (int i = 0, item = pBuffer.ToInt32(); i < entriesRead; i++, item += offset)
                {
                    IntPtr pItem = new IntPtr(item);

                    SessionInfo502 sessionInfo502 = (SessionInfo502)Marshal.PtrToStructure(pItem, shareinfoType);
                    list.Add(sessionInfo502);
                }
            }
            NetApiBufferFree(pBuffer);
            return list;
        }

        public static List<FileInfo3> BuildNetFileEnumList(string server)
        {
            List<FileInfo3> list = new List<FileInfo3>();

            int entriesRead;
            int totalEntries;
            int resumeHandle = 0;
            IntPtr pBuffer = IntPtr.Zero;
            int status = NetFileEnum(server, null, null, 3, ref pBuffer, -1, out entriesRead, out totalEntries, ref resumeHandle);

            if (status == 0 & entriesRead > 0)
            {
                Type shareinfoType = typeof(FileInfo3);
                int offset = Marshal.SizeOf(shareinfoType);

                for (int i = 0, item = pBuffer.ToInt32(); i < entriesRead; i++, item += offset)
                {
                    IntPtr pItem = new IntPtr(item);

                    FileInfo3 fileInfo3 = (FileInfo3)Marshal.PtrToStructure(pItem, shareinfoType);
                    list.Add(fileInfo3);
                }
                NetApiBufferFree(pBuffer);
            }
            return list;
        }

        public static List<ShareInfo2> BuildNetShareEnumList(string server)
        {
            //Note that this code will only work if run as administrator!!
            List<ShareInfo2> list = new List<ShareInfo2>();

            int entriesRead;
            int totalEntries;
            int resumeHandle = 0;
            IntPtr pBuffer = IntPtr.Zero;
            int status = NetShareEnum(server, 2, out pBuffer, -1, out entriesRead, out totalEntries, ref resumeHandle);

            if (status == 0 & entriesRead > 0)
            {
                Type shareinfoType = typeof(ShareInfo2);
                int offset = Marshal.SizeOf(shareinfoType);

                for (int i = 0, item = pBuffer.ToInt32(); i < entriesRead; i++, item += offset)
                {
                    IntPtr pItem = new IntPtr(item);

                    ShareInfo2 shareInfo2 = (ShareInfo2)Marshal.PtrToStructure(pItem, shareinfoType);
                    list.Add(shareInfo2);
                }
            }
            NetApiBufferFree(pBuffer);

            return list;
        }

        #endregion Methods
    }
}

And here is some samples on how to use them:

List<NetAPI32.ShareInfo2> shares = NetAPI32.BuildNetShareEnumList(null);
foreach (NetAPI32.ShareInfo2 share in shares)
{
    int maxAllowedUsers = share.MaxUsers;
    int shareType = share.ShareType;
    string shareName = share.NetName;
    string sharePath = share.Path;
    string shareRemark = share.Remark;
    int currentConectedUsers = share.CurrentUsers;
}

List<NetAPI32.FileInfo3> fileconnections = NetAPI32.BuildNetFileEnumList(null);
foreach (NetAPI32.FileInfo3 fileconnection in fileconnections)
{
    int remoteUserPrimition = fileconnection.Permission;
    string remoteUsername = fileconnection.UserName;
    string sharePath = fileconnection.PathName;
    int shareID = fileconnection.SessionID;
}

List<NetAPI32.SessionInfo502> connectionsInfo = NetAPI32.BuildNetSessionEnumList(null);
foreach (NetAPI32.SessionInfo502 connectionInfo in connectionsInfo)
{
    string remoteUsername = connectionInfo.UserName;
    string remoteIP = connectionInfo.ComputerName;
    int conectionTime = Convert.ToInt32(connectionInfo.SecondsActive);
    int fileOpenCount = Convert.ToInt32(connectionInfo.NumOpens);
}
\$\endgroup\$
4
  • 2
    \$\begingroup\$ Hi, if you want a follow-up review you should post it as a new question (with a link back to this one if you want to provide context), rather than an answer. \$\endgroup\$ Commented May 14, 2015 at 10:56
  • \$\begingroup\$ thanks for the advice i just didn't want to keep re-posting this everywhere/ every time i made a update, but if you say so... \$\endgroup\$ Commented May 14, 2015 at 11:44
  • 1
    \$\begingroup\$ @DarkPh03n1X A review can be an iterative process. You post a chunk of code and receive many suggestions. Implement those suggestions in a separate post but note it helps if (1) you use the same title but with a "Version 2" or something on the end, and (2) if you put links in each post to all related posts. It's not uncommon to see 4 or 5 versions spawned from an original post. \$\endgroup\$
    – Rick Davin
    Commented May 14, 2015 at 12:31
  • \$\begingroup\$ Ok I will Keep it in mind, i'm going to update the code as soon as i get a chance, then i will create a new toppic \$\endgroup\$ Commented May 25, 2015 at 10:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.