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