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