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(); } } }