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