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)
19 BOOL bConnect
= FALSE
;
24 BOOL bDisconnect
= FALSE
;
26 DWORD
DoFormatMessage(DWORD ErrorCode
)
31 if ((RetVal
= FormatMessage(
32 FORMAT_MESSAGE_ALLOCATE_BUFFER
|
33 FORMAT_MESSAGE_FROM_SYSTEM
|
34 FORMAT_MESSAGE_IGNORE_INSERTS
,
37 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
), /* Default language */
42 _tprintf(_T("%s"), (LPTSTR
)lpMsgBuf
);
46 /* return number of TCHAR's stored in output buffer
47 * excluding '\0' - as FormatMessage does*/
55 OpenDriverHandle(VOID
)
58 DWORD dwBytesReturned
;
61 /* Open a handle to the NDISUIO driver */
62 hDriver
= CreateFileW(NDISUIO_DEVICE_NAME
,
63 GENERIC_READ
| GENERIC_WRITE
,
67 FILE_ATTRIBUTE_NORMAL
,
69 if (hDriver
== INVALID_HANDLE_VALUE
)
70 return INVALID_HANDLE_VALUE
;
73 bSuccess
= DeviceIoControl(hDriver
,
74 IOCTL_NDISUIO_BIND_WAIT
,
84 return INVALID_HANDLE_VALUE
;
91 IsWlanAdapter(HANDLE hAdapter
)
94 DWORD dwBytesReturned
;
95 NDISUIO_QUERY_OID QueryOid
;
97 /* WLAN drivers must support this OID */
98 QueryOid
.Oid
= OID_GEN_PHYSICAL_MEDIUM
;
100 bSuccess
= DeviceIoControl(hAdapter
,
101 IOCTL_NDISUIO_QUERY_OID_VALUE
,
108 if (!bSuccess
|| *(PULONG
)QueryOid
.Data
!= NdisPhysicalMediumWirelessLan
)
115 OpenAdapterHandle(DWORD Index
, HANDLE
*hAdapter
, IP_ADAPTER_INDEX_MAP
*IpInfo
)
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
;
125 /* Open the driver handle */
126 hDriver
= OpenDriverHandle();
127 if (hDriver
== INVALID_HANDLE_VALUE
)
130 /* Allocate the binding struct */
131 QueryBinding
= HeapAlloc(GetProcessHeap(), 0, QueryBindingSize
);
134 CloseHandle(hDriver
);
138 /* Query the adapter binding information */
139 QueryBinding
->BindingIndex
= Index
;
140 bSuccess
= DeviceIoControl(hDriver
,
141 IOCTL_NDISUIO_QUERY_BINDING
,
151 HeapFree(GetProcessHeap(), 0, QueryBinding
);
152 CloseHandle(hDriver
);
156 /* Bind to the adapter */
157 bSuccess
= DeviceIoControl(hDriver
,
158 IOCTL_NDISUIO_OPEN_DEVICE
,
159 (PUCHAR
)QueryBinding
+ QueryBinding
->DeviceNameOffset
,
160 QueryBinding
->DeviceNameLength
,
168 HeapFree(GetProcessHeap(), 0, QueryBinding
);
169 CloseHandle(hDriver
);
173 /* Get interface info from the IP helper */
174 dwSize
= sizeof(IP_INTERFACE_INFO
);
176 if (InterfaceInfo
) HeapFree(GetProcessHeap(), 0, InterfaceInfo
);
177 InterfaceInfo
= HeapAlloc(GetProcessHeap(), 0, sizeof(IP_INTERFACE_INFO
));
180 HeapFree(GetProcessHeap(), 0, QueryBinding
);
181 CloseHandle(hDriver
);
184 dwStatus
= GetInterfaceInfo(InterfaceInfo
, &dwSize
);
185 } while (dwStatus
== ERROR_INSUFFICIENT_BUFFER
);
187 if (dwStatus
!= NO_ERROR
)
189 HeapFree(GetProcessHeap(), 0, QueryBinding
);
190 HeapFree(GetProcessHeap(), 0, InterfaceInfo
);
194 for (i
= 0; i
< InterfaceInfo
->NumAdapters
; i
++)
196 if (wcsstr((PWCHAR
)((PUCHAR
)QueryBinding
+ QueryBinding
->DeviceNameOffset
),
197 InterfaceInfo
->Adapter
[i
].Name
))
199 *IpInfo
= InterfaceInfo
->Adapter
[i
];
202 HeapFree(GetProcessHeap(), 0, QueryBinding
);
203 HeapFree(GetProcessHeap(), 0, InterfaceInfo
);
209 HeapFree(GetProcessHeap(), 0, QueryBinding
);
210 HeapFree(GetProcessHeap(), 0, InterfaceInfo
);
211 CloseHandle(hDriver
);
216 /* Only works with the first adapter for now */
218 OpenWlanAdapter(HANDLE
*hAdapter
, IP_ADAPTER_INDEX_MAP
*IpInfo
)
220 DWORD dwCurrentIndex
;
222 for (dwCurrentIndex
= 0; ; dwCurrentIndex
++)
224 if (!OpenAdapterHandle(dwCurrentIndex
, hAdapter
, IpInfo
))
227 if (IsWlanAdapter(*hAdapter
))
230 CloseHandle(*hAdapter
);
237 WlanDisconnect(HANDLE hAdapter
, PIP_ADAPTER_INDEX_MAP IpInfo
)
240 DWORD dwBytesReturned
;
241 NDISUIO_SET_OID SetOid
;
243 /* Release this IP address */
244 IpReleaseAddress(IpInfo
);
246 /* Disassociate from the AP */
247 SetOid
.Oid
= OID_802_11_DISASSOCIATE
;
248 bSuccess
= DeviceIoControl(hAdapter
,
249 IOCTL_NDISUIO_SET_OID_VALUE
,
259 _tprintf(_T("The operation completed successfully.\n"));
267 Char
= toupper(Char
);
309 WlanPrintCurrentStatus(HANDLE hAdapter
)
311 PNDISUIO_QUERY_OID QueryOid
;
314 DWORD dwBytesReturned
;
315 PNDIS_802_11_SSID SsidInfo
;
316 CHAR SsidBuffer
[NDIS_802_11_LENGTH_SSID
+ 1];
319 QueryOidSize
= FIELD_OFFSET(NDISUIO_QUERY_OID
, Data
) + sizeof(NDIS_802_11_SSID
);
320 QueryOid
= HeapAlloc(GetProcessHeap(), 0, QueryOidSize
);
324 QueryOid
->Oid
= OID_802_11_SSID
;
325 SsidInfo
= (PNDIS_802_11_SSID
)QueryOid
->Data
;
327 bSuccess
= DeviceIoControl(hAdapter
,
328 IOCTL_NDISUIO_QUERY_OID_VALUE
,
337 HeapFree(GetProcessHeap(), 0, QueryOid
);
341 /* Copy the SSID to our internal buffer and terminate it */
342 RtlCopyMemory(SsidBuffer
, SsidInfo
->Ssid
, SsidInfo
->SsidLength
);
343 SsidBuffer
[SsidInfo
->SsidLength
] = 0;
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
);
351 QueryOid
->Oid
= OID_802_11_BSSID
;
353 bSuccess
= DeviceIoControl(hAdapter
,
354 IOCTL_NDISUIO_QUERY_OID_VALUE
,
361 if (SsidInfo
->SsidLength
== 0 || !bSuccess
)
363 _tprintf(_T("\nWLAN disconnected\n"));
364 HeapFree(GetProcessHeap(), 0, QueryOid
);
369 _tprintf(_T("\nCurrent wireless configuration information:\n\n"));
372 _tprintf(_T("SSID: %s\n"), SsidBuffer
);
374 _tprintf(_T("BSSID: "));
375 for (i
= 0; i
< sizeof(NDIS_802_11_MAC_ADDRESS
); i
++)
377 UINT BssidData
= QueryOid
->Data
[i
];
379 _tprintf(_T("%.2x"), BssidData
);
381 if (i
!= sizeof(NDIS_802_11_MAC_ADDRESS
) - 1)
386 HeapFree(GetProcessHeap(), 0, QueryOid
);
387 QueryOidSize
= sizeof(NDISUIO_QUERY_OID
);
388 QueryOid
= HeapAlloc(GetProcessHeap(), 0, QueryOidSize
);
392 QueryOid
->Oid
= OID_802_11_INFRASTRUCTURE_MODE
;
394 bSuccess
= DeviceIoControl(hAdapter
,
395 IOCTL_NDISUIO_QUERY_OID_VALUE
,
404 HeapFree(GetProcessHeap(), 0, QueryOid
);
408 _tprintf(_T("Network mode: %s\n"), (*(PUINT
)QueryOid
->Data
== Ndis802_11IBSS
) ? "Adhoc" : "Infrastructure");
410 QueryOid
->Oid
= OID_802_11_WEP_STATUS
;
412 bSuccess
= DeviceIoControl(hAdapter
,
413 IOCTL_NDISUIO_QUERY_OID_VALUE
,
422 HeapFree(GetProcessHeap(), 0, QueryOid
);
426 _tprintf(_T("WEP enabled: %s\n"), (*(PUINT
)QueryOid
->Data
== Ndis802_11WEPEnabled
) ? "Yes" : "No");
429 QueryOid
->Oid
= OID_802_11_RSSI
;
431 bSuccess
= DeviceIoControl(hAdapter
,
432 IOCTL_NDISUIO_QUERY_OID_VALUE
,
441 /* This OID is optional */
442 _tprintf(_T("RSSI: %i dBm\n"), *(PINT
)QueryOid
->Data
);
445 QueryOid
->Oid
= OID_802_11_TX_POWER_LEVEL
;
447 bSuccess
= DeviceIoControl(hAdapter
,
448 IOCTL_NDISUIO_QUERY_OID_VALUE
,
457 /* This OID is optional */
458 _tprintf(_T("Transmission power: %d mW\n"), *(PUINT
)QueryOid
->Data
);
463 QueryOid
->Oid
= OID_802_11_NUMBER_OF_ANTENNAS
;
465 bSuccess
= DeviceIoControl(hAdapter
,
466 IOCTL_NDISUIO_QUERY_OID_VALUE
,
475 /* This OID is optional */
476 _tprintf(_T("Antenna count: %d\n"), *(PUINT
)QueryOid
->Data
);
479 QueryOid
->Oid
= OID_802_11_TX_ANTENNA_SELECTED
;
481 bSuccess
= DeviceIoControl(hAdapter
,
482 IOCTL_NDISUIO_QUERY_OID_VALUE
,
491 UINT TransmitAntenna
= *(PUINT
)QueryOid
->Data
;
493 if (TransmitAntenna
!= 0xFFFFFFFF)
494 _tprintf(_T("Transmit antenna: %d\n"), TransmitAntenna
);
496 _tprintf(_T("Transmit antenna: Any\n"));
499 QueryOid
->Oid
= OID_802_11_RX_ANTENNA_SELECTED
;
501 bSuccess
= DeviceIoControl(hAdapter
,
502 IOCTL_NDISUIO_QUERY_OID_VALUE
,
511 UINT ReceiveAntenna
= *(PUINT
)QueryOid
->Data
;
513 if (ReceiveAntenna
!= 0xFFFFFFFF)
514 _tprintf(_T("Receive antenna: %d\n"), ReceiveAntenna
);
516 _tprintf(_T("Receive antenna: Any\n"));
521 QueryOid
->Oid
= OID_802_11_FRAGMENTATION_THRESHOLD
;
523 bSuccess
= DeviceIoControl(hAdapter
,
524 IOCTL_NDISUIO_QUERY_OID_VALUE
,
533 /* This OID is optional */
534 _tprintf(_T("Fragmentation threshold: %d bytes\n"), *(PUINT
)QueryOid
->Data
);
537 QueryOid
->Oid
= OID_802_11_RTS_THRESHOLD
;
539 bSuccess
= DeviceIoControl(hAdapter
,
540 IOCTL_NDISUIO_QUERY_OID_VALUE
,
549 /* This OID is optional */
550 _tprintf(_T("RTS threshold: %d bytes\n"), *(PUINT
)QueryOid
->Data
);
553 HeapFree(GetProcessHeap(), 0, QueryOid
);
560 WlanConnect(HANDLE hAdapter
)
563 DWORD dwBytesReturned
, SetOidSize
;
564 PNDISUIO_SET_OID SetOid
;
565 PNDIS_802_11_SSID Ssid
;
568 SetOidSize
= sizeof(NDISUIO_SET_OID
);
569 SetOid
= HeapAlloc(GetProcessHeap(), 0, SetOidSize
);
573 /* Set the network mode */
574 SetOid
->Oid
= OID_802_11_INFRASTRUCTURE_MODE
;
575 *(PULONG
)SetOid
->Data
= bAdhoc
? Ndis802_11IBSS
: Ndis802_11Infrastructure
;
577 bSuccess
= DeviceIoControl(hAdapter
,
578 IOCTL_NDISUIO_SET_OID_VALUE
,
587 HeapFree(GetProcessHeap(), 0, SetOid
);
591 /* Set the authentication mode */
592 SetOid
->Oid
= OID_802_11_AUTHENTICATION_MODE
;
593 *(PULONG
)SetOid
->Data
= sWepKey
? Ndis802_11AuthModeShared
: Ndis802_11AuthModeOpen
;
595 bSuccess
= DeviceIoControl(hAdapter
,
596 IOCTL_NDISUIO_SET_OID_VALUE
,
605 HeapFree(GetProcessHeap(), 0, SetOid
);
611 PNDIS_802_11_WEP WepData
;
613 HeapFree(GetProcessHeap(), 0, SetOid
);
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
);
622 /* Add the WEP key */
623 SetOid
->Oid
= OID_802_11_ADD_WEP
;
624 WepData
= (PNDIS_802_11_WEP
)SetOid
->Data
;
626 WepData
->KeyIndex
= 0x80000000;
627 WepData
->KeyLength
= strlen(sWepKey
) >> 1;
628 WepData
->Length
= FIELD_OFFSET(NDIS_802_11_WEP
, KeyMaterial
) + WepData
->KeyLength
;
630 /* Assemble the hex key */
632 while (sWepKey
[i
<< 1] != '\0')
634 WepData
->KeyMaterial
[i
] = CharToHex(sWepKey
[i
<< 1]) << 4;
635 WepData
->KeyMaterial
[i
] |= CharToHex(sWepKey
[(i
<< 1) + 1]);
639 bSuccess
= DeviceIoControl(hAdapter
,
640 IOCTL_NDISUIO_SET_OID_VALUE
,
649 HeapFree(GetProcessHeap(), 0, SetOid
);
654 /* Set the encryption status */
655 SetOid
->Oid
= OID_802_11_WEP_STATUS
;
656 *(PULONG
)SetOid
->Data
= sWepKey
? Ndis802_11WEPEnabled
: Ndis802_11WEPDisabled
;
658 bSuccess
= DeviceIoControl(hAdapter
,
659 IOCTL_NDISUIO_SET_OID_VALUE
,
668 HeapFree(GetProcessHeap(), 0, SetOid
);
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
);
679 SetOid
->Oid
= OID_802_11_BSSID
;
680 RtlFillMemory(SetOid
->Data
, sizeof(NDIS_802_11_MAC_ADDRESS
), 0xFF);
682 bSuccess
= DeviceIoControl(hAdapter
,
683 IOCTL_NDISUIO_SET_OID_VALUE
,
692 HeapFree(GetProcessHeap(), 0, SetOid
);
696 HeapFree(GetProcessHeap(), 0, SetOid
);
697 SetOidSize
= FIELD_OFFSET(NDISUIO_SET_OID
, Data
) + sizeof(NDIS_802_11_SSID
);
698 SetOid
= HeapAlloc(GetProcessHeap(), 0, SetOidSize
);
702 /* Finally, set the SSID */
703 SetOid
->Oid
= OID_802_11_SSID
;
704 Ssid
= (PNDIS_802_11_SSID
)SetOid
->Data
;
706 RtlCopyMemory(Ssid
->Ssid
, sSsid
, strlen(sSsid
));
707 Ssid
->SsidLength
= strlen(sSsid
);
709 bSuccess
= DeviceIoControl(hAdapter
,
710 IOCTL_NDISUIO_SET_OID_VALUE
,
718 HeapFree(GetProcessHeap(), 0, SetOid
);
723 _tprintf(_T("The operation completed successfully.\n"));
728 WlanScan(HANDLE hAdapter
)
731 DWORD dwBytesReturned
;
732 NDISUIO_SET_OID SetOid
;
733 PNDISUIO_QUERY_OID QueryOid
;
735 PNDIS_802_11_BSSID_LIST BssidList
;
738 SetOid
.Oid
= OID_802_11_BSSID_LIST_SCAN
;
740 /* Send the scan OID */
741 bSuccess
= DeviceIoControl(hAdapter
,
742 IOCTL_NDISUIO_SET_OID_VALUE
,
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
);
758 QueryOid
->Oid
= OID_802_11_BSSID_LIST
;
759 BssidList
= (PNDIS_802_11_BSSID_LIST
)QueryOid
->Data
;
761 bSuccess
= DeviceIoControl(hAdapter
,
762 IOCTL_NDISUIO_QUERY_OID_VALUE
,
771 HeapFree(GetProcessHeap(), 0, QueryOid
);
775 if (BssidList
->NumberOfItems
== 0)
777 _tprintf(_T("No networks found in range\n"));
781 PNDIS_WLAN_BSSID BssidInfo
= BssidList
->Bssid
;
782 for (i
= 0; i
< BssidList
->NumberOfItems
; i
++)
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];
790 /* SSID member is a non-null terminated ASCII string */
791 RtlCopyMemory(SsidBuffer
, Ssid
->Ssid
, Ssid
->SsidLength
);
792 SsidBuffer
[Ssid
->SsidLength
] = 0;
796 _tprintf(_T("SSID: %s\n"), SsidBuffer
);
798 _tprintf(_T("BSSID: "));
799 for (j
= 0; j
< sizeof(NDIS_802_11_MAC_ADDRESS
); j
++)
801 UINT BssidData
= BssidInfo
->MacAddress
[j
];
803 _tprintf(_T("%.2x"), BssidData
);
805 if (j
!= sizeof(NDIS_802_11_MAC_ADDRESS
) - 1)
810 _tprintf(_T("Encrypted: %s\n"
813 "Supported Rates (Mbps): "),
814 BssidInfo
->Privacy
== 0 ? "No" : "Yes",
815 NetworkType
== Ndis802_11IBSS
? "Adhoc" : "Infrastructure",
818 for (j
= 0; j
< NDIS_802_11_LENGTH_RATES
; j
++)
820 Rate
= BssidInfo
->SupportedRates
[j
];
823 /* Bit 7 is the basic rates bit */
826 /* SupportedRates are in units of .5 */
829 /* Bit 0 is set so we need to add 0.5 */
830 _tprintf(_T("%u.5 "), (Rate
>> 1));
834 /* Bit 0 is clear so just print the conversion */
835 _tprintf(_T("%u "), (Rate
>> 1));
841 /* Move to the next entry */
842 BssidInfo
= (PNDIS_WLAN_BSSID
)((PUCHAR
)BssidInfo
+ BssidInfo
->Length
);
846 HeapFree(GetProcessHeap(), 0, QueryOid
);
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"));
864 BOOL
ParseCmdline(int argc
, char* argv
[])
868 for (i
= 1; i
< argc
; i
++)
870 if (argv
[i
][0] == '-')
916 int main(int argc
, char* argv
[])
919 IP_ADAPTER_INDEX_MAP IpInfo
;
921 if (!ParseCmdline(argc
, argv
))
924 if (!OpenWlanAdapter(&hAdapter
, &IpInfo
))
926 _tprintf(_T("Unable to find a WLAN adapter on the system\n"));
932 if (!WlanScan(hAdapter
))
934 DoFormatMessage(GetLastError());
935 CloseHandle(hAdapter
);
939 else if (bDisconnect
)
941 if (!WlanDisconnect(hAdapter
, &IpInfo
))
943 DoFormatMessage(GetLastError());
944 CloseHandle(hAdapter
);
950 if (!WlanConnect(hAdapter
))
952 DoFormatMessage(GetLastError());
953 CloseHandle(hAdapter
);
959 if (!WlanPrintCurrentStatus(hAdapter
))
961 DoFormatMessage(GetLastError());
962 CloseHandle(hAdapter
);
967 CloseHandle(hAdapter
);