Some mistakes in your code
> [DllImport("netapi32.dll", CharSet=CharSet.Auto)]
> static extern int NetWkstaUserEnum(StringBuilder
> servername,
> int level,
> ref int bufptr,
> int prefmaxlen,
> ref int entriesread,
> ref int totalentries,
> ref int resume_handle);
The ref params are out params
[DllImport("netapi32.dll", CharSet=CharSet.Auto)]
static extern int NetWkstaUserEnum(StringBuilder servername,
int level,
out IntPtr bufptr,
int prefmaxlen,
out int entriesread,
out int totalentries,
out int resume_handle);
> [StructLayout(LayoutKind.Sequential)]
> public struct WKSTA_USER_INFO_1
> {
> public int wkui1_username;
> public int wkui1_logon_domain;
> public int wkui1_oth_domains;
> public int wkui1_logon_server;
> }
The struct declaration is
[StructLayout(LayoutKind.Sequential)]
public struct WKSTA_USER_INFO_1
{
[MarshalAs(UnmanagedType.LPWStr)]
public string wkui1_username;
[MarshalAs(UnmanagedType.LPWStr)]
public string wkui1_logon_domain;
[MarshalAs(UnmanagedType.LPWStr)]
public string wkui1_oth_domains;
[MarshalAs(UnmanagedType.LPWStr)]
public string wkui1_logon_server;
}
Why int if you know is a LPWSTR?
typedef struct _WKSTA_USER_INFO_1 {
LPWSTR wkui1_username;
LPWSTR wkui1_logon_domain;
LPWSTR wkui1_oth_domains;
LPWSTR wkui1_logon_server;
}WKSTA_USER_INFO_1,
And the call and looping
nStructSize = Marshal.SizeOf(wui1);
System.Type typeOfStruct = typeof(WKSTA_USER_INFO_1);
do
{
nStatus = NetWkstaUserEnum(
strServer,
1,
out bufptr,
MAX_PREFERRED_LENGTH,
out dwEntriesread,
out dwTotalentries,
out dwResumehandle
);
//
// If the call succeeds,
//
if ( (nStatus == NERR_SUCCESS) | (nStatus == ERROR_MORE_DATA) )
{
if (dwEntriesread > 0)
{
//
// Loop through the entries.
//
for (int i = 0; i < dwEntriesread; i++)
{
// Marshal.PtrToStructure((System.IntPtr) bufptr,
wui1);
wui1 =
(WKSTA_USER_INFO_1)Marshal.PtrToStructure(bufptr, typeOfStruct);
// marshal struct pointer to struct; the second parameter is a System.Type,
which must denote the type of the structure
Console.WriteLine(wui1.wkui1_username +
wui1.wkui1_logon_domain);
bufptr = (IntPtr)(bufptr.ToInt32() + nStructSize); //
inc the pointer to
struct array
}
}
else
{
Console.WriteLine("A system error has occurred : " + nStatus);
}
}
}
while(nStatus == ERROR_MORE_DATA);
You have attached a full console class.
Dumitru Sbenghe
http://www.dsbenghe.home.ro/
> -----Original Message-----
> From: dotnet discussion [mailto:[EMAIL PROTECTED]]On Behalf Of
> Powell, Simon
> Sent: Monday, May 20, 2002 11:02 AM
> To: [EMAIL PROTECTED]
> Subject: [DOTNET] .NET and using APIs
>
>
> I'm trying to use various APIs with C#, in particular using APIs
> that return
> structs and make use of pointers such as LPBYTE, LPDWORD etc. In
> particular
> I'm trying to use the API NET_API_STATUS NetWkstaUserEnum(LPWSTR
> servername,
> DWORD level, LPBYTE *bufptr, DWORD prefmaxlen, LPDWORD entriesread,
> LPDWORD totalentries, LPDWORD resumehandle );, but having great difficulty
> trying to return the data. Below is some of the code written so far.
>
> private void Form1_Load(object sender, System.EventArgs e)
> {
> listView1.Columns.Add("Username", -2,
> HorizontalAlignment.Left);
> listView1.Columns.Add("Domain", -2,
> HorizontalAlignment.Left);
> listView1.Columns.Add("Machine", -2,
> HorizontalAlignment.Left);
> listView1.View = View.Details;
>
> }
>
> [DllImport("netapi32.dll", CharSet=CharSet.Auto)]
> static extern int NetWkstaUserEnum(StringBuilder
> servername,
> int level,
> ref int bufptr,
> int prefmaxlen,
> ref int entriesread,
> ref int totalentries,
> ref int resume_handle);
>
> [DllImport("netapi32.dll")]
> static extern int NetApiBufferFree(int Buffer);
>
> // for use on Win NT/2000 only
> [StructLayout(LayoutKind.Sequential)]
> public struct WKSTA_USER_INFO_0
> {
> public int wkui0_username;
> }
>
> [StructLayout(LayoutKind.Sequential)]
> public struct WKSTA_USER_INFO_1
> {
> public int wkui1_username;
> public int wkui1_logon_domain;
> public int wkui1_oth_domains;
> public int wkui1_logon_server;
> }
>
> private const int MAX_PREFERRED_LENGTH = -1;
> private const int NERR_SUCCESS = 0x0;
> private const int ERROR_MORE_DATA = 0x234;
>
>
> private void button1_Click(object sender, System.EventArgs
> e)
> {
> StringBuilder strServer = new
> StringBuilder(textBox1.Text);
> int bufptr = 0;
> int dwEntriesread = 0;
> int dwTotalentries = 0;
> int dwResumehandle = 0;
> int nStatus;
> int nStructSize;
>
> WKSTA_USER_INFO_1 wui1 = new WKSTA_USER_INFO_1();
>
> this.listView1.Items.Clear();
>
> do
> {
> nStatus = NetWkstaUserEnum(
> strServer,
> 1,
> ref bufptr,
> MAX_PREFERRED_LENGTH,
> ref dwEntriesread,
> ref dwTotalentries,
> ref dwResumehandle
> );
>
> //
> // If the call succeeds,
> //
> if ((nStatus == NERR_SUCCESS) |
> (nStatus ==
> ERROR_MORE_DATA))
> {
> if (dwEntriesread > 0)
> {
> //
> // Loop through
> the entries.
> //
> for (int i = 0; (i <
> dwEntriesread); i++)
> {
> nStructSize =
> Marshal.SizeOf(wui1);
>
> Marshal.PtrToStructure((System.IntPtr) bufptr, wui1);
>
> MessageBox.Show(wui1.wkui1_username);
>
> }
> }
> else
> {
> MessageBox.Show("A system
> error has occurred : " + nStatus);
>
> }
> }
>
>
> }
> while(nStatus == ERROR_MORE_DATA);
>
> NetApiBufferFree(bufptr);
>
>
> }
>
> }
>
> I tried to use the platform documentation as template, but failed
> miserably.
> If anyone can help or point me in the direction of a good book it would be
> much appreciated.
>
> Simon
>
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace WinAPIInterop
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
[DllImport("netapi32.dll", CharSet=CharSet.Auto)]
static extern int NetWkstaUserEnum(StringBuilder servername,
int level,
out IntPtr bufptr,
int prefmaxlen,
out int entriesread,
out int totalentries,
out int resume_handle);
[DllImport("netapi32.dll")]
static extern int NetApiBufferFree(int Buffer);
/*
// for use on Win NT/2000 only
[StructLayout(LayoutKind.Sequential)]
public struct WKSTA_USER_INFO_0
{
public int wkui0_username;
}
*/
[StructLayout(LayoutKind.Sequential)]
public struct WKSTA_USER_INFO_1
{
[MarshalAs(UnmanagedType.LPWStr)]
public string wkui1_username;
[MarshalAs(UnmanagedType.LPWStr)]
public string wkui1_logon_domain;
[MarshalAs(UnmanagedType.LPWStr)]
public string wkui1_oth_domains;
[MarshalAs(UnmanagedType.LPWStr)]
public string wkui1_logon_server;
}
private const int MAX_PREFERRED_LENGTH = -1;
private const int NERR_SUCCESS = 0x0;
private const int ERROR_MORE_DATA = 0x234;
static public void test()
{
StringBuilder strServer = new StringBuilder("GICADURU"); //new
StringBuilder(textBox1.Text);
IntPtr bufptr;
int dwEntriesread = 0;
int dwTotalentries = 0;
int dwResumehandle = 0;
int nStatus;
int nStructSize;
WKSTA_USER_INFO_1 wui1 = new WKSTA_USER_INFO_1();
nStructSize = Marshal.SizeOf(wui1);
System.Type typeOfStruct = typeof(WKSTA_USER_INFO_1);
do
{
nStatus = NetWkstaUserEnum(
strServer,
1,
out bufptr,
MAX_PREFERRED_LENGTH,
out dwEntriesread,
out dwTotalentries,
out dwResumehandle
);
//
// If the call succeeds,
//
if ( (nStatus == NERR_SUCCESS) | (nStatus ==
ERROR_MORE_DATA) )
{
if (dwEntriesread > 0)
{
//
// Loop through the entries.
//
for (int i = 0; i < dwEntriesread; i++)
{
wui1 =
(WKSTA_USER_INFO_1)Marshal.PtrToStructure(bufptr, typeOfStruct);
Console.WriteLine(wui1.wkui1_username + wui1.wkui1_logon_domain);
bufptr =
(IntPtr)(bufptr.ToInt32() + nStructSize);
}
}
else
{
Console.WriteLine("A system error has
occurred : " + nStatus);
}
}
}
while(nStatus == ERROR_MORE_DATA);
NetApiBufferFree(bufptr.ToInt32());
}
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//
test();
}
}
}