[NDISUIO]
[reactos.git] / base / applications / network / wlanconf / wlanconf.c
1 /*
2 * PROJECT: ReactOS WLAN command-line configuration utility
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/network/wlanconf/wlanconf.c
5 * PURPOSE: Allows WLAN configuration via the command prompt
6 * COPYRIGHT: Copyright 2012 Cameron Gutman (cameron.gutman@reactos.org)
7 */
8
9 #include <windows.h>
10 #include <tchar.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <ntddndis.h>
14 #include <nuiouser.h>
15
16 BOOL bScan = FALSE;
17
18 BOOL bConnect = FALSE;
19 char* sSsid = NULL;
20 char* sWepKey = NULL;
21 BOOL bAdhoc = FALSE;
22
23 BOOL bDisconnect = FALSE;
24
25 DWORD DoFormatMessage(DWORD ErrorCode)
26 {
27 LPVOID lpMsgBuf;
28 DWORD RetVal;
29
30 if ((RetVal = FormatMessage(
31 FORMAT_MESSAGE_ALLOCATE_BUFFER |
32 FORMAT_MESSAGE_FROM_SYSTEM |
33 FORMAT_MESSAGE_IGNORE_INSERTS,
34 NULL,
35 ErrorCode,
36 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
37 (LPTSTR) &lpMsgBuf,
38 0,
39 NULL )))
40 {
41 _tprintf(_T("%s"), (LPTSTR)lpMsgBuf);
42
43 LocalFree(lpMsgBuf);
44
45 /* return number of TCHAR's stored in output buffer
46 * excluding '\0' - as FormatMessage does*/
47 return RetVal;
48 }
49 else
50 return 0;
51 }
52
53 HANDLE
54 OpenDriverHandle(VOID)
55 {
56 HANDLE hDriver;
57 DWORD dwBytesReturned;
58 BOOL bSuccess;
59
60 /* Open a handle to the NDISUIO driver */
61 hDriver = CreateFileW(NDISUIO_DEVICE_NAME,
62 GENERIC_READ | GENERIC_WRITE,
63 0,
64 NULL,
65 OPEN_EXISTING,
66 FILE_ATTRIBUTE_NORMAL,
67 NULL);
68 if (hDriver == INVALID_HANDLE_VALUE)
69 return INVALID_HANDLE_VALUE;
70
71 /* Wait for binds */
72 bSuccess = DeviceIoControl(hDriver,
73 IOCTL_NDISUIO_BIND_WAIT,
74 NULL,
75 0,
76 NULL,
77 0,
78 &dwBytesReturned,
79 NULL);
80 if (!bSuccess)
81 {
82 CloseHandle(hDriver);
83 return INVALID_HANDLE_VALUE;
84 }
85
86 return hDriver;
87 }
88
89 BOOL
90 IsWlanAdapter(HANDLE hAdapter)
91 {
92 BOOL bSuccess;
93 DWORD dwBytesReturned;
94 PNDISUIO_QUERY_OID QueryOid;
95 DWORD QueryOidSize;
96
97 QueryOidSize = FIELD_OFFSET(NDISUIO_QUERY_OID, Data) + sizeof(NDIS_802_11_SSID);
98 QueryOid = HeapAlloc(GetProcessHeap(), 0, QueryOidSize);
99 if (!QueryOid)
100 return FALSE;
101
102 /* We're just going to do a OID_802_11_SSID query. WLAN drivers should
103 * always succeed this query (returning SsidLength = 0 if not associated) */
104 QueryOid->Oid = OID_802_11_SSID;
105
106 bSuccess = DeviceIoControl(hAdapter,
107 IOCTL_NDISUIO_QUERY_OID_VALUE,
108 QueryOid,
109 QueryOidSize,
110 QueryOid,
111 QueryOidSize,
112 &dwBytesReturned,
113 NULL);
114
115 HeapFree(GetProcessHeap(), 0, QueryOid);
116
117 return bSuccess;
118 }
119
120 HANDLE
121 OpenAdapterHandle(DWORD Index)
122 {
123 HANDLE hDriver;
124 BOOL bSuccess;
125 DWORD dwBytesReturned;
126 DWORD QueryBindingSize = sizeof(NDISUIO_QUERY_BINDING) + (1024 * sizeof(WCHAR));
127 PNDISUIO_QUERY_BINDING QueryBinding;
128
129 /* Open the driver handle */
130 hDriver = OpenDriverHandle();
131 if (hDriver == INVALID_HANDLE_VALUE)
132 return INVALID_HANDLE_VALUE;
133
134 /* Allocate the binding struct */
135 QueryBinding = HeapAlloc(GetProcessHeap(), 0, QueryBindingSize);
136 if (!QueryBinding)
137 {
138 CloseHandle(hDriver);
139 return INVALID_HANDLE_VALUE;
140 }
141
142 /* Query the adapter binding information */
143 QueryBinding->BindingIndex = Index;
144 bSuccess = DeviceIoControl(hDriver,
145 IOCTL_NDISUIO_QUERY_BINDING,
146 QueryBinding,
147 QueryBindingSize,
148 QueryBinding,
149 QueryBindingSize,
150 &dwBytesReturned,
151 NULL);
152
153 if (!bSuccess)
154 {
155 HeapFree(GetProcessHeap(), 0, QueryBinding);
156 CloseHandle(hDriver);
157 return INVALID_HANDLE_VALUE;
158 }
159
160 /* Bind to the adapter */
161 bSuccess = DeviceIoControl(hDriver,
162 IOCTL_NDISUIO_OPEN_DEVICE,
163 (PUCHAR)QueryBinding + QueryBinding->DeviceNameOffset,
164 QueryBinding->DeviceNameLength,
165 NULL,
166 0,
167 &dwBytesReturned,
168 NULL);
169 HeapFree(GetProcessHeap(), 0, QueryBinding);
170
171 if (!bSuccess)
172 {
173 CloseHandle(hDriver);
174 return INVALID_HANDLE_VALUE;
175 }
176
177 return hDriver;
178 }
179
180 /* Only works with the first adapter for now */
181 HANDLE
182 OpenWlanAdapter(VOID)
183 {
184 DWORD dwCurrentIndex;
185 HANDLE hCurrentAdapter;
186
187 for (dwCurrentIndex = 0; ; dwCurrentIndex++)
188 {
189 hCurrentAdapter = OpenAdapterHandle(dwCurrentIndex);
190 if (hCurrentAdapter == INVALID_HANDLE_VALUE)
191 break;
192
193 if (IsWlanAdapter(hCurrentAdapter))
194 return hCurrentAdapter;
195 else
196 CloseHandle(hCurrentAdapter);
197 }
198
199 return INVALID_HANDLE_VALUE;
200 }
201
202 BOOL
203 WlanDisconnect(HANDLE hAdapter)
204 {
205 BOOL bSuccess;
206 DWORD dwBytesReturned;
207 NDISUIO_SET_OID SetOid;
208
209 SetOid.Oid = OID_802_11_DISASSOCIATE;
210
211 bSuccess = DeviceIoControl(hAdapter,
212 IOCTL_NDISUIO_SET_OID_VALUE,
213 &SetOid,
214 sizeof(SetOid),
215 NULL,
216 0,
217 &dwBytesReturned,
218 NULL);
219 if (!bSuccess)
220 return FALSE;
221
222 _tprintf(_T("The operation completed successfully.\n"));
223 return TRUE;
224 }
225
226 static
227 UCHAR
228 CharToHex(CHAR Char)
229 {
230 Char = toupper(Char);
231
232 switch (Char)
233 {
234 case '0':
235 return 0x0;
236 case '1':
237 return 0x1;
238 case '2':
239 return 0x2;
240 case '3':
241 return 0x3;
242 case '4':
243 return 0x4;
244 case '5':
245 return 0x5;
246 case '6':
247 return 0x6;
248 case '7':
249 return 0x7;
250 case '8':
251 return 0x8;
252 case '9':
253 return 0x9;
254 case 'A':
255 return 0xA;
256 case 'B':
257 return 0xB;
258 case 'C':
259 return 0xC;
260 case 'D':
261 return 0xD;
262 case 'E':
263 return 0xE;
264 case 'F':
265 return 0xF;
266 default:
267 return 0;
268 }
269 }
270
271 BOOL
272 WlanPrintCurrentStatus(HANDLE hAdapter)
273 {
274 PNDISUIO_QUERY_OID QueryOid;
275 DWORD QueryOidSize;
276 BOOL bSuccess;
277 DWORD dwBytesReturned;
278 PNDIS_802_11_SSID SsidInfo;
279 CHAR SsidBuffer[NDIS_802_11_LENGTH_SSID + 1];
280 DWORD i;
281
282 QueryOidSize = FIELD_OFFSET(NDISUIO_QUERY_OID, Data) + sizeof(NDIS_802_11_SSID);
283 QueryOid = HeapAlloc(GetProcessHeap(), 0, QueryOidSize);
284 if (!QueryOid)
285 return FALSE;
286
287 QueryOid->Oid = OID_802_11_SSID;
288 SsidInfo = (PNDIS_802_11_SSID)QueryOid->Data;
289
290 bSuccess = DeviceIoControl(hAdapter,
291 IOCTL_NDISUIO_QUERY_OID_VALUE,
292 QueryOid,
293 QueryOidSize,
294 QueryOid,
295 QueryOidSize,
296 &dwBytesReturned,
297 NULL);
298 if (!bSuccess)
299 {
300 HeapFree(GetProcessHeap(), 0, QueryOid);
301 return FALSE;
302 }
303
304 if (SsidInfo->SsidLength == 0)
305 {
306 _tprintf(_T("\nWLAN disconnected\n"));
307 HeapFree(GetProcessHeap(), 0, QueryOid);
308 return TRUE;
309 }
310 else
311 {
312 _tprintf(_T("\nCurrent wireless association information:\n\n"));
313 }
314
315 /* Copy the SSID to our internal buffer and terminate it */
316 RtlCopyMemory(SsidBuffer, SsidInfo->Ssid, SsidInfo->SsidLength);
317 SsidBuffer[SsidInfo->SsidLength] = 0;
318
319 _tprintf(_T("SSID: %s\n"), SsidBuffer);
320
321 HeapFree(GetProcessHeap(), 0, QueryOid);
322 QueryOidSize = FIELD_OFFSET(NDISUIO_QUERY_OID, Data) + sizeof(NDIS_802_11_MAC_ADDRESS);
323 QueryOid = HeapAlloc(GetProcessHeap(), 0, QueryOidSize);
324 if (!QueryOid)
325 return FALSE;
326
327 QueryOid->Oid = OID_802_11_BSSID;
328
329 bSuccess = DeviceIoControl(hAdapter,
330 IOCTL_NDISUIO_QUERY_OID_VALUE,
331 QueryOid,
332 QueryOidSize,
333 QueryOid,
334 QueryOidSize,
335 &dwBytesReturned,
336 NULL);
337 if (!bSuccess)
338 {
339 HeapFree(GetProcessHeap(), 0, QueryOid);
340 return FALSE;
341 }
342
343 _tprintf(_T("BSSID: "));
344 for (i = 0; i < sizeof(NDIS_802_11_MAC_ADDRESS); i++)
345 {
346 UINT BssidData = QueryOid->Data[i];
347
348 _tprintf(_T("%.2x"), BssidData);
349
350 if (i != sizeof(NDIS_802_11_MAC_ADDRESS) - 1)
351 _tprintf(_T(":"));
352 }
353 _tprintf(_T("\n"));
354
355 HeapFree(GetProcessHeap(), 0, QueryOid);
356 QueryOidSize = sizeof(NDISUIO_QUERY_OID);
357 QueryOid = HeapAlloc(GetProcessHeap(), 0, QueryOidSize);
358 if (!QueryOid)
359 return FALSE;
360
361 QueryOid->Oid = OID_802_11_INFRASTRUCTURE_MODE;
362
363 bSuccess = DeviceIoControl(hAdapter,
364 IOCTL_NDISUIO_QUERY_OID_VALUE,
365 QueryOid,
366 QueryOidSize,
367 QueryOid,
368 QueryOidSize,
369 &dwBytesReturned,
370 NULL);
371 if (!bSuccess)
372 {
373 HeapFree(GetProcessHeap(), 0, QueryOid);
374 return FALSE;
375 }
376
377 _tprintf(_T("Network mode: %s\n"), (*(PUINT)QueryOid->Data == Ndis802_11IBSS) ? "Adhoc" : "Infrastructure");
378
379 QueryOid->Oid = OID_802_11_WEP_STATUS;
380
381 bSuccess = DeviceIoControl(hAdapter,
382 IOCTL_NDISUIO_QUERY_OID_VALUE,
383 QueryOid,
384 QueryOidSize,
385 QueryOid,
386 QueryOidSize,
387 &dwBytesReturned,
388 NULL);
389 if (!bSuccess)
390 {
391 HeapFree(GetProcessHeap(), 0, QueryOid);
392 return FALSE;
393 }
394
395 _tprintf(_T("WEP enabled: %s\n"), (*(PUINT)QueryOid->Data == Ndis802_11WEPEnabled) ? "Yes" : "No");
396
397 _tprintf("\n");
398 QueryOid->Oid = OID_802_11_RSSI;
399
400 bSuccess = DeviceIoControl(hAdapter,
401 IOCTL_NDISUIO_QUERY_OID_VALUE,
402 QueryOid,
403 QueryOidSize,
404 QueryOid,
405 QueryOidSize,
406 &dwBytesReturned,
407 NULL);
408 if (bSuccess)
409 {
410 /* This OID is optional */
411 _tprintf(_T("RSSI: %i dBm\n"), *(PINT)QueryOid->Data);
412 }
413
414 QueryOid->Oid = OID_802_11_TX_POWER_LEVEL;
415
416 bSuccess = DeviceIoControl(hAdapter,
417 IOCTL_NDISUIO_QUERY_OID_VALUE,
418 QueryOid,
419 QueryOidSize,
420 QueryOid,
421 QueryOidSize,
422 &dwBytesReturned,
423 NULL);
424 if (bSuccess)
425 {
426 /* This OID is optional */
427 _tprintf(_T("Transmission power: %d mW\n"), *(PUINT)QueryOid->Data);
428 }
429
430 _tprintf(_T("\n"));
431
432 QueryOid->Oid = OID_802_11_NUMBER_OF_ANTENNAS;
433
434 bSuccess = DeviceIoControl(hAdapter,
435 IOCTL_NDISUIO_QUERY_OID_VALUE,
436 QueryOid,
437 QueryOidSize,
438 QueryOid,
439 QueryOidSize,
440 &dwBytesReturned,
441 NULL);
442 if (bSuccess)
443 {
444 /* This OID is optional */
445 _tprintf(_T("Antenna count: %d\n"), *(PUINT)QueryOid->Data);
446 }
447
448 QueryOid->Oid = OID_802_11_TX_ANTENNA_SELECTED;
449
450 bSuccess = DeviceIoControl(hAdapter,
451 IOCTL_NDISUIO_QUERY_OID_VALUE,
452 QueryOid,
453 QueryOidSize,
454 QueryOid,
455 QueryOidSize,
456 &dwBytesReturned,
457 NULL);
458 if (bSuccess)
459 {
460 UINT TransmitAntenna = *(PUINT)QueryOid->Data;
461
462 if (TransmitAntenna != 0xFFFFFFFF)
463 _tprintf(_T("Transmit antenna: %d\n"), TransmitAntenna);
464 else
465 _tprintf(_T("Transmit antenna: Any\n"));
466 }
467
468 QueryOid->Oid = OID_802_11_RX_ANTENNA_SELECTED;
469
470 bSuccess = DeviceIoControl(hAdapter,
471 IOCTL_NDISUIO_QUERY_OID_VALUE,
472 QueryOid,
473 QueryOidSize,
474 QueryOid,
475 QueryOidSize,
476 &dwBytesReturned,
477 NULL);
478 if (bSuccess)
479 {
480 UINT ReceiveAntenna = *(PUINT)QueryOid->Data;
481
482 if (ReceiveAntenna != 0xFFFFFFFF)
483 _tprintf(_T("Receive antenna: %d\n"), ReceiveAntenna);
484 else
485 _tprintf(_T("Receive antenna: Any\n"));
486 }
487
488 _tprintf(_T("\n"));
489
490 QueryOid->Oid = OID_802_11_FRAGMENTATION_THRESHOLD;
491
492 bSuccess = DeviceIoControl(hAdapter,
493 IOCTL_NDISUIO_QUERY_OID_VALUE,
494 QueryOid,
495 QueryOidSize,
496 QueryOid,
497 QueryOidSize,
498 &dwBytesReturned,
499 NULL);
500 if (bSuccess)
501 {
502 /* This OID is optional */
503 _tprintf(_T("Fragmentation threshold: %d bytes\n"), *(PUINT)QueryOid->Data);
504 }
505
506 QueryOid->Oid = OID_802_11_RTS_THRESHOLD;
507
508 bSuccess = DeviceIoControl(hAdapter,
509 IOCTL_NDISUIO_QUERY_OID_VALUE,
510 QueryOid,
511 QueryOidSize,
512 QueryOid,
513 QueryOidSize,
514 &dwBytesReturned,
515 NULL);
516 if (bSuccess)
517 {
518 /* This OID is optional */
519 _tprintf(_T("RTS threshold: %d bytes\n"), *(PUINT)QueryOid->Data);
520 }
521
522 HeapFree(GetProcessHeap(), 0, QueryOid);
523
524 _tprintf(_T("\n"));
525 return TRUE;
526 }
527
528 BOOL
529 WlanConnect(HANDLE hAdapter)
530 {
531 BOOL bSuccess;
532 DWORD dwBytesReturned, SetOidSize;
533 PNDISUIO_SET_OID SetOid;
534 PNDIS_802_11_SSID Ssid;
535 DWORD i;
536
537 SetOidSize = sizeof(NDISUIO_SET_OID);
538 SetOid = HeapAlloc(GetProcessHeap(), 0, SetOidSize);
539 if (!SetOid)
540 return FALSE;
541
542 /* Set the network mode */
543 SetOid->Oid = OID_802_11_INFRASTRUCTURE_MODE;
544 *(PULONG)SetOid->Data = bAdhoc ? Ndis802_11IBSS : Ndis802_11Infrastructure;
545
546 bSuccess = DeviceIoControl(hAdapter,
547 IOCTL_NDISUIO_SET_OID_VALUE,
548 SetOid,
549 SetOidSize,
550 NULL,
551 0,
552 &dwBytesReturned,
553 NULL);
554 if (!bSuccess)
555 {
556 HeapFree(GetProcessHeap(), 0, SetOid);
557 return FALSE;
558 }
559
560 /* Set the authentication mode */
561 SetOid->Oid = OID_802_11_AUTHENTICATION_MODE;
562 *(PULONG)SetOid->Data = sWepKey ? Ndis802_11AuthModeShared : Ndis802_11AuthModeOpen;
563
564 bSuccess = DeviceIoControl(hAdapter,
565 IOCTL_NDISUIO_SET_OID_VALUE,
566 SetOid,
567 SetOidSize,
568 NULL,
569 0,
570 &dwBytesReturned,
571 NULL);
572 if (!bSuccess)
573 {
574 HeapFree(GetProcessHeap(), 0, SetOid);
575 return FALSE;
576 }
577
578 if (sWepKey)
579 {
580 PNDIS_802_11_WEP WepData;
581
582 HeapFree(GetProcessHeap(), 0, SetOid);
583
584 SetOidSize = FIELD_OFFSET(NDISUIO_SET_OID, Data) +
585 FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial) +
586 (strlen(sWepKey) >> 1);
587 SetOid = HeapAlloc(GetProcessHeap(), 0, SetOidSize);
588 if (!SetOid)
589 return FALSE;
590
591 /* Add the WEP key */
592 SetOid->Oid = OID_802_11_ADD_WEP;
593 WepData = (PNDIS_802_11_WEP)SetOid->Data;
594
595 WepData->KeyIndex = 0x80000000;
596 WepData->KeyLength = strlen(sWepKey) >> 1;
597 WepData->Length = FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial) + WepData->KeyLength;
598
599 /* Assemble the hex key */
600 i = 0;
601 while (sWepKey[i << 1] != '\0')
602 {
603 WepData->KeyMaterial[i] = CharToHex(sWepKey[i << 1]) << 4;
604 WepData->KeyMaterial[i] |= CharToHex(sWepKey[(i << 1) + 1]);
605 i++;
606 }
607
608 bSuccess = DeviceIoControl(hAdapter,
609 IOCTL_NDISUIO_SET_OID_VALUE,
610 SetOid,
611 SetOidSize,
612 NULL,
613 0,
614 &dwBytesReturned,
615 NULL);
616 if (!bSuccess)
617 {
618 HeapFree(GetProcessHeap(), 0, SetOid);
619 return FALSE;
620 }
621 }
622
623 /* Set the encryption status */
624 SetOid->Oid = OID_802_11_WEP_STATUS;
625 *(PULONG)SetOid->Data = sWepKey ? Ndis802_11WEPEnabled : Ndis802_11WEPDisabled;
626
627 bSuccess = DeviceIoControl(hAdapter,
628 IOCTL_NDISUIO_SET_OID_VALUE,
629 SetOid,
630 SetOidSize,
631 NULL,
632 0,
633 &dwBytesReturned,
634 NULL);
635 if (!bSuccess)
636 {
637 HeapFree(GetProcessHeap(), 0, SetOid);
638 return FALSE;
639 }
640
641 HeapFree(GetProcessHeap(), 0, SetOid);
642 SetOidSize = FIELD_OFFSET(NDISUIO_SET_OID, Data) + sizeof(NDIS_802_11_MAC_ADDRESS);
643 SetOid = HeapAlloc(GetProcessHeap(), 0, SetOidSize);
644 if (!SetOid)
645 return FALSE;
646
647 /* Set the BSSID */
648 SetOid->Oid = OID_802_11_BSSID;
649 RtlFillMemory(SetOid->Data, sizeof(NDIS_802_11_MAC_ADDRESS), 0xFF);
650
651 bSuccess = DeviceIoControl(hAdapter,
652 IOCTL_NDISUIO_SET_OID_VALUE,
653 SetOid,
654 SetOidSize,
655 NULL,
656 0,
657 &dwBytesReturned,
658 NULL);
659 if (!bSuccess)
660 {
661 HeapFree(GetProcessHeap(), 0, SetOid);
662 return FALSE;
663 }
664
665 HeapFree(GetProcessHeap(), 0, SetOid);
666 SetOidSize = FIELD_OFFSET(NDISUIO_SET_OID, Data) + sizeof(NDIS_802_11_SSID);
667 SetOid = HeapAlloc(GetProcessHeap(), 0, SetOidSize);
668 if (!SetOid)
669 return FALSE;
670
671 /* Finally, set the SSID */
672 SetOid->Oid = OID_802_11_SSID;
673 Ssid = (PNDIS_802_11_SSID)SetOid->Data;
674
675 RtlCopyMemory(Ssid->Ssid, sSsid, strlen(sSsid));
676 Ssid->SsidLength = strlen(sSsid);
677
678 bSuccess = DeviceIoControl(hAdapter,
679 IOCTL_NDISUIO_SET_OID_VALUE,
680 SetOid,
681 SetOidSize,
682 NULL,
683 0,
684 &dwBytesReturned,
685 NULL);
686
687 HeapFree(GetProcessHeap(), 0, SetOid);
688
689 if (!bSuccess)
690 return FALSE;
691
692 _tprintf(_T("The operation completed successfully.\n"));
693 return TRUE;
694 }
695
696 BOOL
697 WlanScan(HANDLE hAdapter)
698 {
699 BOOL bSuccess;
700 DWORD dwBytesReturned;
701 NDISUIO_SET_OID SetOid;
702 PNDISUIO_QUERY_OID QueryOid;
703 DWORD QueryOidSize;
704 PNDIS_802_11_BSSID_LIST BssidList;
705 DWORD i, j;
706
707 SetOid.Oid = OID_802_11_BSSID_LIST_SCAN;
708
709 /* Send the scan OID */
710 bSuccess = DeviceIoControl(hAdapter,
711 IOCTL_NDISUIO_SET_OID_VALUE,
712 &SetOid,
713 sizeof(SetOid),
714 NULL,
715 0,
716 &dwBytesReturned,
717 NULL);
718 if (!bSuccess)
719 return FALSE;
720
721 /* Allocate space for 15 networks to be returned */
722 QueryOidSize = sizeof(NDISUIO_QUERY_OID) + (sizeof(NDIS_WLAN_BSSID) * 15);
723 QueryOid = HeapAlloc(GetProcessHeap(), 0, QueryOidSize);
724 if (!QueryOid)
725 return FALSE;
726
727 QueryOid->Oid = OID_802_11_BSSID_LIST;
728 BssidList = (PNDIS_802_11_BSSID_LIST)QueryOid->Data;
729
730 bSuccess = DeviceIoControl(hAdapter,
731 IOCTL_NDISUIO_QUERY_OID_VALUE,
732 QueryOid,
733 QueryOidSize,
734 QueryOid,
735 QueryOidSize,
736 &dwBytesReturned,
737 NULL);
738 if (!bSuccess)
739 {
740 HeapFree(GetProcessHeap(), 0, QueryOid);
741 return FALSE;
742 }
743
744 if (BssidList->NumberOfItems == 0)
745 {
746 _tprintf(_T("No networks found in range\n"));
747 }
748 else
749 {
750 PNDIS_WLAN_BSSID BssidInfo = BssidList->Bssid;
751 for (i = 0; i < BssidList->NumberOfItems; i++)
752 {
753 PNDIS_802_11_SSID Ssid = &BssidInfo->Ssid;
754 NDIS_802_11_RSSI Rssi = BssidInfo->Rssi;
755 NDIS_802_11_NETWORK_INFRASTRUCTURE NetworkType = BssidInfo->InfrastructureMode;
756 CHAR SsidBuffer[NDIS_802_11_LENGTH_SSID + 1];
757 UINT Rate;
758
759 /* SSID member is a non-null terminated ASCII string */
760 RtlCopyMemory(SsidBuffer, Ssid->Ssid, Ssid->SsidLength);
761 SsidBuffer[Ssid->SsidLength] = 0;
762
763 _tprintf(_T("\nSSID: %s\n"
764 "Encrypted: %s\n"
765 "Network Type: %s\n"
766 "RSSI: %i dBm\n"
767 "Supported Rates (Mbps): "),
768 SsidBuffer,
769 BssidInfo->Privacy == 0 ? "No" : "Yes",
770 NetworkType == Ndis802_11IBSS ? "Adhoc" : "Infrastructure",
771 (int)Rssi);
772
773 for (j = 0; j < NDIS_802_11_LENGTH_RATES; j++)
774 {
775 Rate = BssidInfo->SupportedRates[j];
776 if (Rate != 0)
777 {
778 /* Bit 7 is the basic rates bit */
779 Rate = Rate & 0x7F;
780
781 /* SupportedRates are in units of .5 */
782 if (Rate & 0x01)
783 {
784 /* Bit 0 is set so we need to add 0.5 */
785 _tprintf(_T("%u.5 "), (Rate >> 1));
786 }
787 else
788 {
789 /* Bit 0 is clear so just print the conversion */
790 _tprintf(_T("%u "), (Rate >> 1));
791 }
792 }
793 }
794 _tprintf(_T("\n"));
795
796 /* Move to the next entry */
797 BssidInfo = (PNDIS_WLAN_BSSID)((PUCHAR)BssidInfo + BssidInfo->Length);
798 }
799 }
800
801 HeapFree(GetProcessHeap(), 0, QueryOid);
802
803 return bSuccess;
804 }
805
806 VOID Usage()
807 {
808 _tprintf(_T("\nConfigures a WLAN adapter.\n\n"
809 "WLANCONF [-c SSID [-w WEP] [-a]] [-d] [-s]\n\n"
810 " -c SSID Connects to a supplied SSID.\n"
811 " -w WEP Specifies a WEP key to use.\n"
812 " -a Specifies the target network is ad-hoc\n"
813 " -d Disconnects from the current AP.\n"
814 " -s Scans and displays a list of access points in range.\n\n"
815 " Passing no parameters will print information about the current WLAN connection\n"));
816 }
817
818
819 BOOL ParseCmdline(int argc, char* argv[])
820 {
821 INT i;
822
823 for (i = 1; i < argc; i++)
824 {
825 if (argv[i][0] == '-')
826 {
827 switch (argv[i][1])
828 {
829 case 's':
830 bScan = TRUE;
831 break;
832 case 'd':
833 bDisconnect = TRUE;
834 break;
835 case 'c':
836 if (i == argc - 1)
837 {
838 Usage();
839 return FALSE;
840 }
841 bConnect = TRUE;
842 sSsid = argv[++i];
843 break;
844 case 'w':
845 if (i == argc - 1)
846 {
847 Usage();
848 return FALSE;
849 }
850 sWepKey = argv[++i];
851 break;
852 case 'a':
853 bAdhoc = TRUE;
854 break;
855 default :
856 Usage();
857 return FALSE;
858 }
859
860 }
861 else
862 {
863 Usage();
864 return FALSE;
865 }
866 }
867
868 return TRUE;
869 }
870
871 int main(int argc, char* argv[])
872 {
873 HANDLE hAdapter;
874
875 if (!ParseCmdline(argc, argv))
876 return -1;
877
878 hAdapter = OpenWlanAdapter();
879 if (hAdapter == INVALID_HANDLE_VALUE)
880 {
881 DoFormatMessage(GetLastError());
882 return -1;
883 }
884
885 if (bScan)
886 {
887 if (!WlanScan(hAdapter))
888 {
889 DoFormatMessage(GetLastError());
890 CloseHandle(hAdapter);
891 return -1;
892 }
893 }
894 else if (bDisconnect)
895 {
896 if (!WlanDisconnect(hAdapter))
897 {
898 DoFormatMessage(GetLastError());
899 CloseHandle(hAdapter);
900 return -1;
901 }
902 }
903 else if (bConnect)
904 {
905 if (!WlanConnect(hAdapter))
906 {
907 DoFormatMessage(GetLastError());
908 CloseHandle(hAdapter);
909 return -1;
910 }
911 }
912 else
913 {
914 if (!WlanPrintCurrentStatus(hAdapter))
915 {
916 DoFormatMessage(GetLastError());
917 CloseHandle(hAdapter);
918 return -1;
919 }
920 }
921
922 CloseHandle(hAdapter);
923 return 0;
924 }