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.