Native Wifi - bezdrôtové siete vo Windows - diel 2
V minulom článku sme si pripravili knižnicu wlanapi.dll. V tejto druhej časti článku si ukážeme ako zistiť zoznam prítomných Wifi kariet, dostupných bezdrôtových sietí ich prístupových bodov a konečne aj pripájanie a odpájanie.
Zistenie prítomných Wifi kariet
Na účely detekcie prítomných Wifi kariet slúži funkcia WlanEnumInterfaces. Jej deklarácia nepatrí medzi tie zákerné; odovzdáte ju handle získané pri inicializácii rozhrania Native Wifi a miesto, kam si prajete uložiť zistené informácie. Tie sú typu WLAN_INTERFACE_INFO_LIST, čo je v podstate pole štruktúr WLAN_INTERFACE_INFO plus ich počet.
DWORD WINAPI WlanEnumInterfaces( _In_ HANDLE hClientHandle, _Reserved_ PVOID pReserved, _Out_ PWLAN_INTERFACE_INFO_LIST *ppInterfaceList );
Štruktúra vráteného zoznamu Wifi kariet je tiež pomerne typická pre knižnicu wlanapi.dll, minimálne pre všetky naše použitie. Každá zo štruktúr WLAN_INTERFACE_INFO obsahuje informácie o jednej prítomnej Wifi karte, konkrétne sa jedná o nasledujúce údaje:
- jedinečný identifikátor karty v rámci rozhrania Native Wifi (GUID),
- ľudsky čitateľný opis (názov),
- aktuálny stav udávajúci, či je karta pripojená k nejakej bezdrôtovej sieti či akú činnosť práve vykonáva.
typedef struct _WLAN_INTERFACE_INFO_LIST { DWORD dwNumberOfItems; DWORD dwIndex; WLAN_INTERFACE_INFO InterfaceInfo[]; } WLAN_INTERFACE_INFO_LIST, *PWLAN_INTERFACE_INFO_LIST;
Buffer pre uloženie svojho výsledku funkcie alokuje sama. Je však na vás, aby ste ho uvoľnili, ak ho už nebudete potrebovať. Za týmto účelom existuje procedúra WlanFreeMemory, ktorá ako svoj jediný parameter akceptuje adresu pamäťového bloku, ktorý má uvoľniť.
VOID WINAPI WlanFreeMemory( _In_ PVOID pMemory );
Zoznam bezdrôtových sietí a prístupových bodov
Akonáhle sa rozhodneme, ktorú z nájdených Wifi kariet využijeme, je na čase zistiť aké bezdrôtovej siete vidí. K tomuto účelu knižnica wlanapi.dll exportuje funkciu WlanGetAvailableNetworkList, ktorej deklarácia je ľahko záludnější ako v prípade predchádzajúcej funkcie. Okrem handle získaného pri inicializácii rozhrania a identifikátora sieťovej karty môžete pomocou parametra dwFlags ovplyvniť aké bezdrôtovej siete má funkcie hľadať. Výsledok je vrátený v poslednom parametri v podobnom duchu ako v prípade zisťovaní dostupných Wifi kariet.
Native Wifi vie s bezdrôtovými sieťami pracovať v dvoch režimoch: pomocou sieťových profilov a bez nich. Sieťový profil možno chápať ako dátovú štruktúru (na disku je uložená vo forme XML súboru, aspoň pre Windows Vista a novšie verzie operačného systému) obsahujúce všetky informácie potrebné na pripojenie ku konkrétnej bezdrôtovej sieti. Profily teda slúži na zapamätanie jednotlivých sietí a Windows ich využívajú pri pripájaní.
Pre naše účely s profilmi pracovať nepotrebujeme a tak parameter dwFlags ponecháme nulový. Zmenou parametra na kombináciu príznakov uvedených v dokumentácii je možné získať zoznam profilov sietí ad-hoc (bezdrôtových sietí vysielaných klasickým počítačom a nie smerovačom) alebo skrytých sieťových profilov.
DWORD WINAPI WlanGetAvailableNetworkList( _In_ HANDLE hClientHandle, _In_ const GUID *pInterfaceGuid, _In_ DWORD dwFlags, _Reserved_ PVOID pReserved, _Out_ PWLAN_AVAILABLE_NETWORK_LIST *ppAvailableNetworkList );
code
Funkcia vráti o každej nájdenej bezdrôtovej sieti rad údajov. Pre naše účely je potrebné poznať jej názov (SSID) a či je zabezpečená, ale vlastnosti ako typ autentizácia, šifrovanie či kvalita signálu sa môžu tiež hodiť.
Akonáhle máme vybranú sieť, ku ktorej sa chceme pripojiť, môžeme začať so zisťovaním ich prístupových bodov, označovaných v rámci Native Wifi ako BSS (basic service set). K tomu použijeme rutinu WlanGetNetworkBssList, pričom musíme opäť uviesť handle získané pri inicializácii rozhrania a identifikátor sieťovej karty. Navyše môžeme špecifikovať SSID siete. Ak tak neurobíme, funkcia vráti zoznam všetkých dostupných BSS pre zadaný typ sietí. Hľadaný typ siete musíme špecifikovať v parametri dot11BssType, pričom máme na výber z nasledujúcich možností:
- dot11_BSS_type_infrastructure - "normálne" siete (vysielané napr. routerom),
- dot11_BSS_type_independent - siete ad-hoc,
- dot11_BSS_type_any - siete ľubovoľného typu (možno použiť iba ak nie je zadaný názov siete),
Parametrom bSecurity knižnici oznámime, či je cieľová sieť zabezpečená. Túto informáciu sa dozvieme pri zisťovaní dostupných bezdrôtových sietí.
DWORD WINAPI WlanGetNetworkBssList( _In_ HANDLE hClientHandle, _In_ const GUID *pInterfaceGuid, const PDOT11_SSID pDot11Ssid, _In_ DOT11_BSS_TYPE dot11BssType, _In_ BOOL bSecurityEnabled, _Reserved_ PVOID pReserved, _Out_ PWLAN_BSS_LIST *ppWlanBssList );
Funkcia vráti zoznam získaných BSS v rovnakom duchu ako funkcie pre získanie zoznamu prítomných Wifi kariet a dostupných bezdrôtových sietí. Jedná sa o pole záznamov o jednotlivých prístupových bodoch, ktoré (to pole) musíte pomocou rutiny WlanFreeMemory uvoľniť, ak ho už ďalej nebudete využívať. O každej BSS sa opäť dozviete veľa údajov, pričom pre naše účely je zaujímavá MAC adresa a prípadne kvalita signálu.
Pripojenie a odpojenie
Teraz už teda máme vybranú sieť, ku ktorej sa chceme pripojiť. Poznáme jej charakteristiky vrátane SSID a máme v ruke zoznam prístupových bodov, ktoré ju vysielajú. Môžeme teda prikročiť k vlastnému pripojenie, ktoré realizuje funkcie WlanConnect.
Funkciu opäť musíme odovzdať handle získané pri inicializácii rozhrania a identifikátor sieťové karty, ktoré si prajeme pripojiť. Podrobnejšie parametre pripojenia je nutné špecifikovať v argumentu pConnectionParameters. WlanConnect totiž dovoľuje pripojiť sa ako cez sieťový profil, tak aj bez neho, pričom je možné, ale nie nutné, špecifikovať aj BSS, napriek ktoré majú tiecť dáta.
DWORD WINAPI WlanConnect( _In_ HANDLE hClientHandle, _In_ const GUID *pInterfaceGuid, _In_ const PWLAN_CONNECTION_PARAMETERS pConnectionParameters, _Reserved_ PVOID pReserved );
Štruktúru WLAN_CONNECTION_PARAMETERS tu podrobne rozpisovať nebudem, pretože je pomerne dlhá a jej kompletné opis (lepší ako ten môj) môžete nájsť v dokumentácii. Pre naše účely potrebujeme cez ňu rozhranie Native Wifi oznámiť nasledujúce:
- Režim pripojenia (položka wlanConnectionMode) nastavíme na wlan_connection_mode_discovery_secure či wlan_connection_mode_discovery_unsecure podľa toho, či cieľová sieť podporuje či nepodporuje zabezpečenia. Túto informáciu sa dozvieme pri zisťovaní zozname dostupných bezdrôtových sietí.
- Názov profilu (strProfile) necháme prázdny, pretože sa žiadny nepripájajú (hodnota NULL).
- Vyplníme SSID cieľovej siete (položka pDot11Ssid).
- zadáme zoznam prístupových bodov, s ktorými si želáme komunikovať. Jedná sa o zoznam MAC, pričom jeho štruktúra pripomína iné zoznamy popísané vyššie (opäť sa jedná v podstate o pole s udaným počtom položiek a ďalšími pomocnými údajmi). Pamäť pre uloženie zoznamu je rozumné alokovať pomocou funkcie WlanAllocateMemory a po použití uvoľniť (WlanFreeMemory). Ak poznáme počet BSS dopredu, môžeme sa uspokojiť so statickou alokácií. Sémantika alokačné funkcia je štandardný; parametrom odovzdáme veľkosť požadovaného bloku v bajtoch a v prípade dostatku pamäti taký blok i obdržíme.
- Špecifikujeme, či je cieľová sieť ad-hoc alebo nie (položka dot11BssType). Túto informáciu opäť získame pri zisťovaní dostupných bezdrôtových sietí.
PVOID WINAPI WlanAllocateMemory( _In_ DWORD dwMemorySize );
Keďže sa pripájame bez účasti sieťového profilu, v zozname bezdrôtových sietí zobrazovanom systémom Windows sa nedozvieme, ku ktorej sieti sme sa pripojili. Pokiaľ ale sieť poskytuje prístup k internetu, prípadný žltý trojuholník s výkričníkom zmizne; systém rozpozná, že sa úspešne pripojil k internetu. Ďalším dôsledkom "bezprofilového" pripojenia je nutnosť pripojiť sa znovu v prípade výpadku. Pokiaľ viem, nie je možné v tomto režime nastaviť automatické pripájanie.
Poznámka: Uvedené tak celkom neplatí pre systémy Windows 8 a novšie, ktoré informáciu o pripojenie ku konkrétnej sieti zobrazí aj bez použitia profilu.Ak sa pýtate, ako sa pomocou funkcie WlanConnect pripojíte k zabezpečenej sieti, tzn. jej úspešné používanie vyžaduje heslo, ktoré ale tejto rutine nie je možné zadať, odpoveď je taká, že Windows v prípade potreby zobrazí okno, do ktorého potrebné údaje vložíte. Musíte mať ale celkom postreh, pretože okno sa objaví len na chvíľu a vo forme notifikácia.
Pripájanie k bezdrôtovej sieti prebieha asynchrónne. To znamená, že po úspešnom volanie funkcie WlanConnect stále nemusíte byť pripojení. K tomu zvyčajne dôjde o pár sekúnd neskôr. Rozhranie Native Wifi poskytuje mechanizmus, ako sa o presnom okamihu pripojenia dozvedieť, jeho opis ale patrí už do iného článku.
Pre odpojenie od bezdrôtovej siete slúži funkcia WlanDisconnect. Okrem všadeprítomného handle stačí len určiť pripojené Wifi karty a všetko by malo fungovať.
DWORD WINAPI WlanDisconnect( _In_ HANDLE hClientHandle, _In_ const GUID *pInterfaceGuid, _Reserved_ PVOID pReserved );
Tým končí ľahká exkurzia po niektorých funkcionalitách rozhranie Native Wifi. Aby sme všetko videli aj v praxi, rozhodol som sa okrem GUI aplikácie vyvinuté priamo na účely NTK vytvoriť aj ukážku konzolovú, jednoduchšie a priamočiarejšie.
Nwtest
Konzolová aplikácie, ktorej kód sa nachádza v súbore pripojenom k tomuto článku, získa zoznam prítomných Wifi kariet. Jednu si vyberie a v jej detekovanom zozname bezdrôtových sietí vyhľadá sieť sa SSID zodpovedajúcim reťazci zadanom v prvom parametri príkazového riadku. K tejto sieti sa pripojí a to iba cez BSS vysielajúci najkvalitnejšie signál.
Aplikáciu som naprogramoval za použitia prostredí Microsoft Visual Studio 2013, ale nemali by ste mať problémy s prekladom aj v starších verziách tohto IDE. Stačí len vytvoriť nový projekt a linkovať statickú knižnicu wlanapi.lib. Projekt som pomenoval nwtest.
WlanClient
Jedná sa o aplikáciu s grafickým rozhraním, ktoré vás prevedie cez výber sieťovej karty, bezdrôtové siete a prístupové, cez ktoré sa chcete pripojiť. Naprogramovaná je v Delphi XE2 a natívne preložená pre platformy x86 a x64. Zdrojové kódy a nápoveda pre bežných užívateľov sú súčasťou balíka. Podobne ako v prípade projektu nwtest, aj s touto aplikáciou jej zdrojovým kódom si môžete robiť, čo uznáte za vhodné, nedávam na ňu žiadne licenčné obmedzenia.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 55x (8.28 kB)
Aplikácia je vrátane zdrojových kódov