patterncsharpMinor
Class to wrap Netapi32.dll functions
Viewed 0 times
dllnetapi32functionsclasswrap
Problem
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:
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
{
///
/// Unicode string specifying the name of the computer that established the session.
///
[MarshalAs(UnmanagedType.LPWStr)]
public string si502_cname;
///
/// Unicode string specifying the name of the user who established the session.
///
[MarshalAs(UnmanagedType.LPWStr)]
public string si502_username;
///
/// Specifies the number of files, devices, and pipes opened during the session.
///
public uint si502_num_opens;
///
/// Specifies the number of seconds the session has been active.
///
public uint si502_time;
///
/// Specifies the number of seconds the session has been idle.
///
public uint si502_idle_time;
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
{
///
/// Unicode string specifying the name of the computer that established the session.
///
[MarshalAs(UnmanagedType.LPWStr)]
public string si502_cname;
///
/// Unicode string specifying the name of the user who established the session.
///
[MarshalAs(UnmanagedType.LPWStr)]
public string si502_username;
///
/// Specifies the number of files, devices, and pipes opened during the session.
///
public uint si502_num_opens;
///
/// Specifies the number of seconds the session has been active.
///
public uint si502_time;
///
/// Specifies the number of seconds the session has been idle.
///
public uint si502_idle_time;
Solution
BuildNetSessionEnumList()
Naming
You should declare variables as near as possible to their usage. In the
Additionally, there's no need to use
You should be consistent in the style you use.
In the
and in the
and in the
You have declared a
- Declaring multiple variables on the same line reduces readability.
- You don't really use the
SESSION_INFO_502[] resultsarray and you can safely remove it.
Naming
- You have
SHARE_INFO_2 siandFILE_INFO_3 pCurrent.
- Local variables should be named using
camelCasecasing. See the .NET style guide.
- You should avoid shortening variable names; that reduces readability.
- Using
listfor the name of each requestedListalso 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 themres,er,tr = 0, andresumewhich 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;.Code Snippets
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);
}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);
}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);
}Context
StackExchange Code Review Q#88640, answer score: 3
Revisions (0)
No revisions yet.