A munkaállomások megosztásait a NETAPI32.DLL állományban implementált NetShareEnum metódus képes lekérdezni. A megoldás taglalása előtt megemlítendő, hogy amennyiben a mellékletalkalmazást Windows 98 rendszeren futtatjuk, akkor ott nem található meg a NETAPI32.DLL állomány. Ott a SVRAPI.DLL dinamikusan szerkeszthető könyvtárra kell hivatkozni.
A metódus deklarációja a következő:
Osztály:
int NetShareEnum (
string lpServerName,
int dwLevel,
out IntPtr lpBuffer,
int dwPrefMaxLen,
out int entriesRead,
out int totalEntries,
ref int hResume
);
A metódussal tehát információ szerezhető a hálózat megosztásairól.
Paraméterek
string lpServerName
A lekérdezendő számítógép neve. Windows NT esetében a nevet a „\\” karakterlánccal kell kezdeni.
int dwLevel
Az információ típusát jelzendő, meg kell adnunk egy egész számot. A szám a harmadik paraméterben megadott pointer által jelzett memóriaterületen található adatstruktúra típusát jelzi.
out IntPtr lpBuffer
Az eredményadatok területére mutató pointer.
int dwPrefMaxLen
A lefoglalandó maximális memóriaterület nagysága bájtban.
out int entriesRead
A lekérdezett megosztott erőforrások száma.
out int totalEntries
A lehetséges erőforrásszám.
ref int hResume
A lekérdezéskor nullára választandó változó, mely mindig a következő lekérdezéshez szükséges kezelőt tartalmazza.
Visszatérési érték
Sikeres lekérdezéskor nulla.
A második paraméterben megadható egész szám ötféle lehet, melyekhez öt struktúratípus tartozik.
| Szám |
Struktúra |
| 0 |
SHARE_INFO_0 |
| 1 |
SHARE_INFO_1 |
| 2 |
SHARE_INFO_2 |
| 50 |
SHARE_INFO_50 |
| 502 |
SHARE_INFO_502 |
Megjegyzendő, hogy csak az utolsó kettő típus használható Windows 9x rendszerek esetében.
A paraméterként megadott mutatót a NETAPI32.DLL egy másik metódusával kell felszabadítanunk a megoldás után, melynek deklarációját is a Win32 osztályunk tartalmazza.
[DllImport("netapi32.dll")]
protected static extern int NetApiBufferFree(IntPtr lpBuffer);
A Win32 osztályban találjuk az Enumeration nevű metódust, melyben a tulajdonképpeni lekérdezést végezzük.
A NetShareEnum első hívásakor a második paramétert 2 értékre választjuk. Előfordulhat azonban, hogy a célszámítógépen nem megengedett ez a fajta lekérdezés jogosultsághiány miatt. Ekkor a metódushívás eredménye egy ERROR_ACCESS_DENIED értékű hiba.
result = NetShareEnum(server, level, out ptr, -1, out entriesRead, out totals, ref res);
if (ERROR_ACCESS_DENIED == result)
{
level = 1;
result = NetShareEnum(server, level, out ptr, -1, out entriesRead, out totals, ref res);
}
Ekkor a lekérdezést még egyszer lefuttatjuk, de a második paraméter már 1 lesz. Amennyiben a lekérdezés hiba nélkül lefut, valamint a kapott erőforrások száma nem nulla, akkor egy ciklussal kiértékeljük a struktúra-tömböt.
if (NO_ERROR == result && entriesRead > 0)
{
Type t = (2 == level) ? typeof(SHARE_INFO_2) : typeof(SHARE_INFO_1);
int offset = Marshal.SizeOf(t);
Az átadott egésznek megfelelően dolgozunk a SHARE_INFO_1 vagy a SHARE_INFO_2 struktúrákkal.
for (int i=0,lpItem = ptr.ToInt32(); i<entriesRead; i++, lpItem += offset)
{
IntPtr p = new IntPtr(lpItem);
string[] info = new string[4];
if (1 == level)
{
SHARE_INFO_1 si = (SHARE_INFO_1)Marshal.PtrToStructure(p, t);
info[0] = si.NetName;
info[1] = string.Empty;
info[2] = si.ShareType.ToString();
info[3] = si.Remark;
shares.Add(info);
}
...
Az erőforrások mindegyikéről négy adatot tárolunk el egy tömbben, melyet a metódus visszaad. Ezek a kapott struktúrák mezőiben találhatók. Tároljuk az erőforrás nevét, ahol lehet az elérési útvonalat, a típust és a jellemzőit.
A művelet végén felszabadítjuk a pointer által mutatott memóriaterületet.
if (IntPtr.Zero != ptr) NetApiBufferFree(ptr);
A lekérdezés eredményeit a Form ListBox kontroljában jelenítjük meg.
ArrayList list = Win32.Enumeration(textBox1.Text);
if (list.Count != 0)
{
string[] info = new string[4];
for(int i=0;i<list.Count;i++)
{
info = (string[])list[i];
listBox1.Items.Add("Megosztás neve: " + info[0]);
...