A Form-ra helyezett ComboBox kontrol fogja a kigyűjtött, a számítógépen fellelhető felhasználókat megjeleníteni. Egy név kiválasztásával a ListBox kontrolban jelennek meg a felhasználóhoz kötődő, hasznosabb információk.
A felhasználók listázásához a NetUserEnum API függvényt használhatjuk.
[DllImport("Netapi32.dll")]
public extern static int NetUserEnum(string servername, int level, int filter, out IntPtr bufptr, int prefmaxlen, out int entriesread, out int totalentries, out int resume_handle);
Míg egy konkrét felhasználó információit a NetUserGetInfo függvénnyel kaphatjuk meg.
[DllImport("Netapi32.dll")]
public extern static int NetUserGetInfo([MarshalAs(UnmanagedType.LPWStr)] string servername,[MarshalAs(UnmanagedType.LPWStr)] string username,int level,out IntPtr bufptr);
A NetUserEnum metódus a USER_INFO_0 beépített struktúrát használja, ezek egy tömbjére mutató pointert kell a függvénynek átadni. A struktúra deklarációja:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct USER_INFO_0
{
public String Username;
}
A NetUserGetInfo metódus a USER_INFO_1 struktúrát használja, melyhez a saját deklarációnk a következő:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct USER_INFO_1
{
public string usri1_name;
public int usri1_password_age;
public int usri1_priv;
public string comment;
...
}
A sok lekérdezhető információ közül mi négyfélét jelenítünk meg: a felhasználó nevét, a hozzá kapcsolódó megjegyzést, a felhasználó típusát és a jelszó utolsó változtatása (már ha van jelszó) óta eltelt időt másodpercben.
A GetUserNames metódusba ágyaztuk a felhasználók kigyűjtését. A metódus egy karakterlánc-tömböt ad vissza a nevekkel.
public string[] GetUserNames()
{
string[] users = null;
A változók a függvény meghívásához:
int entries;
int fullentries;
int r;
A mutató, mely tartalmazza a névlistát tartalmazó struktúra-tömb címét:
Majd meghívjuk a metódust:
NetUserEnum(null, 0, 2, out bufferPtr, -1, out entries, out fullentries, out r);
Az entries változó tartalmazza a felhasználók számát, így ha ez nem null, akkor feldolgozzuk a kapott értéket.
Létrehozunk egy struktúra-tömböt.
USER_INFO_0[] localusers = new USER_INFO_0[entries];
users = new string[entries];
for(int i=0;i<entries;i++)
{
Minden egyes felhasználói struktúrát átalakítunk a deklarált struktúrává, és elhelyezzük a tömbben.
localusers[i] = (USER_INFO_0)Marshal.PtrToStructure(bufferPtr, typeof(USER_INFO_0));
bufferPtr = (IntPtr)((bufferPtr)iter + Marshal.SizeOf(typeof(USER_INFO_0)));
A karakterlánc-tömbben pedig a neveket:
users[i] = localusers[i].Username;
}
A NetApiBufferFree metódus meghívására azért van szükség, hogy felszabadítsuk a lefoglalt memóriaterületet. Szintén API függvény, a forrás elején megtalálható a deklarációja.
NetApiBufferFree(bufferPtr);
}
return users;
}
A GetUserDatas metódusban gyűjtjük ki az adott felhasználóhoz kapcsolódó adatokat. A függvény paraméterként kapja a felhasználó nevét, majd egy karakterlánc-tömbben adja vissza az adatokat.
public string[] GetUserData(string name)
{
string[] datas = new string[4];
Deklarálunk egy mutatót, illetve egy USER_INFO_1 típusú struktúrát.
IntPtr bufferPtr;
USER_INFO_1 selecteduser = new USER_INFO_1();
A NetUserGetInfo metódus meghívása egyszerű:
NetUserGetInfo(null,name,1,out bufferPtr);
Nehezebb dolog feldolgozni a kapott értékeket. Ehhez a mutatót átalakítjuk struktúrává.
selecteduser = (USER_INFO_1)Marshal.PtrToStructure(bufferPtr, typeof(USER_INFO_1));
Majd a DATAS karakterlánc-tömbben elhelyezzük a négyfajta információt.
datas[0] = "Felhasználónév: " + selecteduser.usri1_name;
...
}
A struktúra usri1_priv mezője háromféle értéket tartalmazhat. 0 esetén Vendég, 1 esetén Általános felhasználó és 2 esetén Rendszergazda jogosultságú felhasználóról van szó.