C# - A helyi hálózat tetszőleges számítógépén fellelhető megosztások lekérdezése

forráskód letöltése
A helyi hálózat előnye többek közt, hogy az erőforrásokat elegendő – kivételek azért vannak – egy példányban elhelyezni hálózat egy tetszőleges számítógépén, és azt képes valamennyi munkaállomás elérni. Ehhez csupán annyit kell tennünk, hogy az adott erőforrást fel kell kínálnia az adott számítógépnek, vagyis meg kell azt osztani a hálózaton. Hogy egy adott LAN munkaállomás milyen megosztásokkal rendelkezik, megtudhatjuk egy API függvény meghívásával. Ennek módját mutatjuk be cikkünkben.
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]);
    ...