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 #define COUNT_OF(a) (sizeof(a) / sizeof(a[0]))
20 #define MAX_BUFFER_SIZE 5024
24 BOOL bConnect
= FALSE
;
29 BOOL bDisconnect
= FALSE
;
31 /* This takes strings from a resource stringtable and outputs it to
32 the command prompt. */
33 VOID
PrintResourceString(INT resID
, ...)
35 TCHAR szMsgBuf
[MAX_BUFFER_SIZE
];
38 va_start(arg_ptr
, resID
);
39 LoadString(GetModuleHandle(NULL
), resID
, szMsgBuf
, MAX_BUFFER_SIZE
);
40 _vtprintf(szMsgBuf
, arg_ptr
);
44 DWORD
DoFormatMessage(DWORD ErrorCode
)
49 if ((RetVal
= FormatMessage(
50 FORMAT_MESSAGE_ALLOCATE_BUFFER
|
51 FORMAT_MESSAGE_FROM_SYSTEM
|
52 FORMAT_MESSAGE_IGNORE_INSERTS
,
55 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
), /* Default language */
60 _tprintf(_T("%s"), (LPTSTR
)lpMsgBuf
);
64 /* return number of TCHAR's stored in output buffer
65 * excluding '\0' - as FormatMessage does*/
73 OpenDriverHandle(VOID
)
76 DWORD dwBytesReturned
;
79 /* Open a handle to the NDISUIO driver */
80 hDriver
= CreateFileW(NDISUIO_DEVICE_NAME
,
81 GENERIC_READ
| GENERIC_WRITE
,
85 FILE_ATTRIBUTE_NORMAL
,
87 if (hDriver
== INVALID_HANDLE_VALUE
)
88 return INVALID_HANDLE_VALUE
;
91 bSuccess
= DeviceIoControl(hDriver
,
92 IOCTL_NDISUIO_BIND_WAIT
,
101 CloseHandle(hDriver
);
102 return INVALID_HANDLE_VALUE
;
109 IsWlanAdapter(HANDLE hAdapter
)
112 DWORD dwBytesReturned
;
113 NDISUIO_QUERY_OID QueryOid
;
115 /* WLAN drivers must support this OID */
116 QueryOid
.Oid
= OID_GEN_PHYSICAL_MEDIUM
;
118 bSuccess
= DeviceIoControl(hAdapter
,
119 IOCTL_NDISUIO_QUERY_OID_VALUE
,
126 if (!bSuccess
|| *(PULONG
)QueryOid
.Data
!= NdisPhysicalMediumWirelessLan
)
133 OpenAdapterHandle(DWORD Index
, HANDLE
*hAdapter
, IP_ADAPTER_INDEX_MAP
*IpInfo
)
137 DWORD dwBytesReturned
;
138 DWORD QueryBindingSize
= sizeof(NDISUIO_QUERY_BINDING
) + (1024 * sizeof(WCHAR
));
139 PNDISUIO_QUERY_BINDING QueryBinding
;
140 DWORD dwStatus
, dwSize
;
142 PIP_INTERFACE_INFO InterfaceInfo
= NULL
;
144 /* Open the driver handle */
145 hDriver
= OpenDriverHandle();
146 if (hDriver
== INVALID_HANDLE_VALUE
)
149 /* Allocate the binding struct */
150 QueryBinding
= HeapAlloc(GetProcessHeap(), 0, QueryBindingSize
);
153 CloseHandle(hDriver
);
157 /* Query the adapter binding information */
158 QueryBinding
->BindingIndex
= Index
;
159 bSuccess
= DeviceIoControl(hDriver
,
160 IOCTL_NDISUIO_QUERY_BINDING
,
170 HeapFree(GetProcessHeap(), 0, QueryBinding
);
171 CloseHandle(hDriver
);
175 /* Bind to the adapter */
176 bSuccess
= DeviceIoControl(hDriver
,
177 IOCTL_NDISUIO_OPEN_DEVICE
,
178 (PUCHAR
)QueryBinding
+ QueryBinding
->DeviceNameOffset
,
179 QueryBinding
->DeviceNameLength
,
187 HeapFree(GetProcessHeap(), 0, QueryBinding
);
188 CloseHandle(hDriver
);
192 /* Get interface info from the IP helper */
193 dwSize
= sizeof(IP_INTERFACE_INFO
);
195 if (InterfaceInfo
) HeapFree(GetProcessHeap(), 0, InterfaceInfo
);
196 InterfaceInfo
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
199 HeapFree(GetProcessHeap(), 0, QueryBinding
);
200 CloseHandle(hDriver
);
203 dwStatus
= GetInterfaceInfo(InterfaceInfo
, &dwSize
);
204 } while (dwStatus
== ERROR_INSUFFICIENT_BUFFER
);
206 if (dwStatus
!= NO_ERROR
)
208 HeapFree(GetProcessHeap(), 0, QueryBinding
);
209 HeapFree(GetProcessHeap(), 0, InterfaceInfo
);
210 CloseHandle(hDriver
);
214 for (i
= 0; i
< InterfaceInfo
->NumAdapters
; i
++)
216 if (wcsstr((PWCHAR
)((PUCHAR
)QueryBinding
+ QueryBinding
->DeviceNameOffset
),
217 InterfaceInfo
->Adapter
[i
].Name
))
219 *IpInfo
= InterfaceInfo
->Adapter
[i
];
222 HeapFree(GetProcessHeap(), 0, QueryBinding
);
223 HeapFree(GetProcessHeap(), 0, InterfaceInfo
);
229 HeapFree(GetProcessHeap(), 0, QueryBinding
);
230 HeapFree(GetProcessHeap(), 0, InterfaceInfo
);
231 CloseHandle(hDriver
);
236 /* Only works with the first adapter for now */
238 OpenWlanAdapter(HANDLE
*hAdapter
, IP_ADAPTER_INDEX_MAP
*IpInfo
)
240 DWORD dwCurrentIndex
;
242 for (dwCurrentIndex
= 0; ; dwCurrentIndex
++)
244 if (!OpenAdapterHandle(dwCurrentIndex
, hAdapter
, IpInfo
))
247 if (IsWlanAdapter(*hAdapter
))
250 CloseHandle(*hAdapter
);
257 WlanDisconnect(HANDLE hAdapter
, PIP_ADAPTER_INDEX_MAP IpInfo
)
260 DWORD dwBytesReturned
;
261 NDISUIO_SET_OID SetOid
;
263 /* Release this IP address */
264 IpReleaseAddress(IpInfo
);
266 /* Disassociate from the AP */
267 SetOid
.Oid
= OID_802_11_DISASSOCIATE
;
268 bSuccess
= DeviceIoControl(hAdapter
,
269 IOCTL_NDISUIO_SET_OID_VALUE
,
279 PrintResourceString(IDS_SUCCESS
);
287 Char
= toupper(Char
);
329 WlanPrintCurrentStatus(HANDLE hAdapter
)
331 PNDISUIO_QUERY_OID QueryOid
;
334 DWORD dwBytesReturned
;
335 PNDIS_802_11_SSID SsidInfo
;
336 CHAR SsidBuffer
[NDIS_802_11_LENGTH_SSID
+ 1];
340 QueryOidSize
= FIELD_OFFSET(NDISUIO_QUERY_OID
, Data
) + sizeof(NDIS_802_11_SSID
);
341 QueryOid
= HeapAlloc(GetProcessHeap(), 0, QueryOidSize
);
345 QueryOid
->Oid
= OID_802_11_SSID
;
346 SsidInfo
= (PNDIS_802_11_SSID
)QueryOid
->Data
;
348 bSuccess
= DeviceIoControl(hAdapter
,
349 IOCTL_NDISUIO_QUERY_OID_VALUE
,
358 HeapFree(GetProcessHeap(), 0, QueryOid
);
362 /* Copy the SSID to our internal buffer and terminate it */
363 RtlCopyMemory(SsidBuffer
, SsidInfo
->Ssid
, SsidInfo
->SsidLength
);
364 SsidBuffer
[SsidInfo
->SsidLength
] = 0;
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
);
372 QueryOid
->Oid
= OID_802_11_BSSID
;
374 bSuccess
= DeviceIoControl(hAdapter
,
375 IOCTL_NDISUIO_QUERY_OID_VALUE
,
382 if (SsidInfo
->SsidLength
== 0 || !bSuccess
)
384 PrintResourceString(IDS_WLAN_DISCONNECT
);
385 HeapFree(GetProcessHeap(), 0, QueryOid
);
390 PrintResourceString(IDS_MSG_CURRENT_WIRELESS
);
393 _tprintf(_T("SSID: %hs\n"), SsidBuffer
);
395 _tprintf(_T("BSSID: "));
396 for (i
= 0; i
< sizeof(NDIS_802_11_MAC_ADDRESS
); i
++)
398 UINT BssidData
= QueryOid
->Data
[i
];
400 _tprintf(_T("%.2x"), BssidData
);
402 if (i
!= sizeof(NDIS_802_11_MAC_ADDRESS
) - 1)
407 HeapFree(GetProcessHeap(), 0, QueryOid
);
408 QueryOidSize
= sizeof(NDISUIO_QUERY_OID
);
409 QueryOid
= HeapAlloc(GetProcessHeap(), 0, QueryOidSize
);
413 QueryOid
->Oid
= OID_802_11_INFRASTRUCTURE_MODE
;
415 bSuccess
= DeviceIoControl(hAdapter
,
416 IOCTL_NDISUIO_QUERY_OID_VALUE
,
425 HeapFree(GetProcessHeap(), 0, QueryOid
);
429 LoadString(GetModuleHandle(NULL
),
430 *(PUINT
)QueryOid
->Data
== Ndis802_11IBSS
? IDS_ADHOC
: IDS_INFRASTRUCTURE
,
433 PrintResourceString(IDS_MSG_NETWORK_MODE
, szMsgBuf
);
435 QueryOid
->Oid
= OID_802_11_WEP_STATUS
;
437 bSuccess
= DeviceIoControl(hAdapter
,
438 IOCTL_NDISUIO_QUERY_OID_VALUE
,
447 HeapFree(GetProcessHeap(), 0, QueryOid
);
451 LoadString(GetModuleHandle(NULL
),
452 *(PUINT
)QueryOid
->Data
== Ndis802_11WEPEnabled
? IDS_YES
: IDS_NO
,
455 PrintResourceString(IDS_MSG_WEP_ENABLED
, szMsgBuf
);
458 QueryOid
->Oid
= OID_802_11_RSSI
;
460 bSuccess
= DeviceIoControl(hAdapter
,
461 IOCTL_NDISUIO_QUERY_OID_VALUE
,
470 /* This OID is optional */
471 _tprintf(_T("RSSI: %i dBm\n"), *(PINT
)QueryOid
->Data
);
474 QueryOid
->Oid
= OID_802_11_TX_POWER_LEVEL
;
476 bSuccess
= DeviceIoControl(hAdapter
,
477 IOCTL_NDISUIO_QUERY_OID_VALUE
,
486 /* This OID is optional */
487 PrintResourceString(IDS_MSG_TRANSMISSION_POWER
, *(PUINT
)QueryOid
->Data
);
492 QueryOid
->Oid
= OID_802_11_NUMBER_OF_ANTENNAS
;
494 bSuccess
= DeviceIoControl(hAdapter
,
495 IOCTL_NDISUIO_QUERY_OID_VALUE
,
504 /* This OID is optional */
505 PrintResourceString(IDS_MSG_ANTENNA_COUNT
, *(PUINT
)QueryOid
->Data
);
508 QueryOid
->Oid
= OID_802_11_TX_ANTENNA_SELECTED
;
510 bSuccess
= DeviceIoControl(hAdapter
,
511 IOCTL_NDISUIO_QUERY_OID_VALUE
,
520 UINT TransmitAntenna
= *(PUINT
)QueryOid
->Data
;
522 if (TransmitAntenna
!= 0xFFFFFFFF)
523 PrintResourceString(IDS_MSG_TRANSMIT_ANTENNA
, TransmitAntenna
);
525 PrintResourceString(IDS_MSG_TRANSMIT_ANTENNA_ANY
);
528 QueryOid
->Oid
= OID_802_11_RX_ANTENNA_SELECTED
;
530 bSuccess
= DeviceIoControl(hAdapter
,
531 IOCTL_NDISUIO_QUERY_OID_VALUE
,
540 UINT ReceiveAntenna
= *(PUINT
)QueryOid
->Data
;
542 if (ReceiveAntenna
!= 0xFFFFFFFF)
543 PrintResourceString(IDS_MSG_RECEIVE_ANTENNA
, ReceiveAntenna
);
545 PrintResourceString(IDS_MSG_RECEIVE_ANTENNA_ANY
);
550 QueryOid
->Oid
= OID_802_11_FRAGMENTATION_THRESHOLD
;
552 bSuccess
= DeviceIoControl(hAdapter
,
553 IOCTL_NDISUIO_QUERY_OID_VALUE
,
562 /* This OID is optional */
563 PrintResourceString(IDS_MSG_FRAGMENT_THRESHOLD
, *(PUINT
)QueryOid
->Data
);
566 QueryOid
->Oid
= OID_802_11_RTS_THRESHOLD
;
568 bSuccess
= DeviceIoControl(hAdapter
,
569 IOCTL_NDISUIO_QUERY_OID_VALUE
,
578 /* This OID is optional */
579 PrintResourceString(IDS_MSG_RTS_THRESHOLD
, *(PUINT
)QueryOid
->Data
);
582 HeapFree(GetProcessHeap(), 0, QueryOid
);
589 WlanConnect(HANDLE hAdapter
)
592 DWORD dwBytesReturned
, SetOidSize
;
593 PNDISUIO_SET_OID SetOid
;
594 PNDIS_802_11_SSID Ssid
;
597 SetOidSize
= sizeof(NDISUIO_SET_OID
);
598 SetOid
= HeapAlloc(GetProcessHeap(), 0, SetOidSize
);
602 /* Set the network mode */
603 SetOid
->Oid
= OID_802_11_INFRASTRUCTURE_MODE
;
604 *(PULONG
)SetOid
->Data
= bAdhoc
? Ndis802_11IBSS
: Ndis802_11Infrastructure
;
606 bSuccess
= DeviceIoControl(hAdapter
,
607 IOCTL_NDISUIO_SET_OID_VALUE
,
616 HeapFree(GetProcessHeap(), 0, SetOid
);
620 /* Set the authentication mode */
621 SetOid
->Oid
= OID_802_11_AUTHENTICATION_MODE
;
622 *(PULONG
)SetOid
->Data
= sWepKey
? Ndis802_11AuthModeShared
: Ndis802_11AuthModeOpen
;
624 bSuccess
= DeviceIoControl(hAdapter
,
625 IOCTL_NDISUIO_SET_OID_VALUE
,
634 HeapFree(GetProcessHeap(), 0, SetOid
);
640 PNDIS_802_11_WEP WepData
;
642 HeapFree(GetProcessHeap(), 0, SetOid
);
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
);
651 /* Add the WEP key */
652 SetOid
->Oid
= OID_802_11_ADD_WEP
;
653 WepData
= (PNDIS_802_11_WEP
)SetOid
->Data
;
655 WepData
->KeyIndex
= 0x80000000;
656 WepData
->KeyLength
= strlen(sWepKey
) >> 1;
657 WepData
->Length
= FIELD_OFFSET(NDIS_802_11_WEP
, KeyMaterial
) + WepData
->KeyLength
;
659 /* Assemble the hex key */
661 while (sWepKey
[i
<< 1] != '\0')
663 WepData
->KeyMaterial
[i
] = CharToHex(sWepKey
[i
<< 1]) << 4;
664 WepData
->KeyMaterial
[i
] |= CharToHex(sWepKey
[(i
<< 1) + 1]);
668 bSuccess
= DeviceIoControl(hAdapter
,
669 IOCTL_NDISUIO_SET_OID_VALUE
,
678 HeapFree(GetProcessHeap(), 0, SetOid
);
683 /* Set the encryption status */
684 SetOid
->Oid
= OID_802_11_WEP_STATUS
;
685 *(PULONG
)SetOid
->Data
= sWepKey
? Ndis802_11WEPEnabled
: Ndis802_11WEPDisabled
;
687 bSuccess
= DeviceIoControl(hAdapter
,
688 IOCTL_NDISUIO_SET_OID_VALUE
,
697 HeapFree(GetProcessHeap(), 0, SetOid
);
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
);
708 SetOid
->Oid
= OID_802_11_BSSID
;
709 RtlFillMemory(SetOid
->Data
, sizeof(NDIS_802_11_MAC_ADDRESS
), 0xFF);
711 bSuccess
= DeviceIoControl(hAdapter
,
712 IOCTL_NDISUIO_SET_OID_VALUE
,
721 HeapFree(GetProcessHeap(), 0, SetOid
);
725 HeapFree(GetProcessHeap(), 0, SetOid
);
726 SetOidSize
= FIELD_OFFSET(NDISUIO_SET_OID
, Data
) + sizeof(NDIS_802_11_SSID
);
727 SetOid
= HeapAlloc(GetProcessHeap(), 0, SetOidSize
);
731 /* Finally, set the SSID */
732 SetOid
->Oid
= OID_802_11_SSID
;
733 Ssid
= (PNDIS_802_11_SSID
)SetOid
->Data
;
735 RtlCopyMemory(Ssid
->Ssid
, sSsid
, strlen(sSsid
));
736 Ssid
->SsidLength
= strlen(sSsid
);
738 bSuccess
= DeviceIoControl(hAdapter
,
739 IOCTL_NDISUIO_SET_OID_VALUE
,
747 HeapFree(GetProcessHeap(), 0, SetOid
);
752 PrintResourceString(IDS_SUCCESS
);
757 WlanScan(HANDLE hAdapter
)
760 DWORD dwBytesReturned
;
761 NDISUIO_SET_OID SetOid
;
762 PNDISUIO_QUERY_OID QueryOid
;
764 PNDIS_802_11_BSSID_LIST BssidList
;
768 SetOid
.Oid
= OID_802_11_BSSID_LIST_SCAN
;
770 /* Send the scan OID */
771 bSuccess
= DeviceIoControl(hAdapter
,
772 IOCTL_NDISUIO_SET_OID_VALUE
,
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
);
788 QueryOid
->Oid
= OID_802_11_BSSID_LIST
;
789 BssidList
= (PNDIS_802_11_BSSID_LIST
)QueryOid
->Data
;
791 bSuccess
= DeviceIoControl(hAdapter
,
792 IOCTL_NDISUIO_QUERY_OID_VALUE
,
801 HeapFree(GetProcessHeap(), 0, QueryOid
);
805 if (BssidList
->NumberOfItems
== 0)
807 PrintResourceString(IDS_NO_NETWORK
);
811 PNDIS_WLAN_BSSID BssidInfo
= BssidList
->Bssid
;
812 for (i
= 0; i
< BssidList
->NumberOfItems
; i
++)
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];
820 /* SSID member is a non-null terminated ASCII string */
821 RtlCopyMemory(SsidBuffer
, Ssid
->Ssid
, Ssid
->SsidLength
);
822 SsidBuffer
[Ssid
->SsidLength
] = 0;
824 _tprintf(_T("\nSSID: %hs\n"), SsidBuffer
);
826 _tprintf(_T("BSSID: "));
827 for (j
= 0; j
< sizeof(NDIS_802_11_MAC_ADDRESS
); j
++)
829 UINT BssidData
= BssidInfo
->MacAddress
[j
];
831 _tprintf(_T("%.2x"), BssidData
);
833 if (j
!= sizeof(NDIS_802_11_MAC_ADDRESS
) - 1)
838 LoadString(GetModuleHandle(NULL
),
839 BssidInfo
->Privacy
== 0 ? IDS_NO
: IDS_YES
,
842 PrintResourceString(IDS_MSG_ENCRYPTED
, szMsgBuf
);
843 LoadString(GetModuleHandle(NULL
),
844 NetworkType
== Ndis802_11IBSS
? IDS_ADHOC
: IDS_INFRASTRUCTURE
,
847 PrintResourceString(IDS_MSG_NETWORK_TYPE
, szMsgBuf
);
848 PrintResourceString(IDS_MSG_RSSI
, (int)Rssi
);
849 PrintResourceString(IDS_MSG_SUPPORT_RATE
);
851 for (j
= 0; j
< NDIS_802_11_LENGTH_RATES
; j
++)
853 Rate
= BssidInfo
->SupportedRates
[j
];
856 /* Bit 7 is the basic rates bit */
859 /* SupportedRates are in units of .5 */
862 /* Bit 0 is set so we need to add 0.5 */
863 _tprintf(_T("%u.5 "), (Rate
>> 1));
867 /* Bit 0 is clear so just print the conversion */
868 _tprintf(_T("%u "), (Rate
>> 1));
874 /* Move to the next entry */
875 BssidInfo
= (PNDIS_WLAN_BSSID
)((PUCHAR
)BssidInfo
+ BssidInfo
->Length
);
879 HeapFree(GetProcessHeap(), 0, QueryOid
);
884 BOOL
ParseCmdline(int argc
, char *argv
[])
888 for (i
= 1; i
< argc
; i
++)
890 if (argv
[i
][0] == '-')
903 PrintResourceString(IDS_USAGE
);
912 PrintResourceString(IDS_USAGE
);
921 PrintResourceString(IDS_USAGE
);
928 PrintResourceString(IDS_USAGE
);
936 int main(int argc
, char *argv
[])
939 IP_ADAPTER_INDEX_MAP IpInfo
;
941 if (!ParseCmdline(argc
, argv
))
944 if (!OpenWlanAdapter(&hAdapter
, &IpInfo
))
946 PrintResourceString(IDS_NO_WLAN_ADAPTER
);
952 if (!WlanScan(hAdapter
))
954 DoFormatMessage(GetLastError());
955 CloseHandle(hAdapter
);
959 else if (bDisconnect
)
961 if (!WlanDisconnect(hAdapter
, &IpInfo
))
963 DoFormatMessage(GetLastError());
964 CloseHandle(hAdapter
);
970 if (!WlanConnect(hAdapter
))
972 DoFormatMessage(GetLastError());
973 CloseHandle(hAdapter
);
979 if (!WlanPrintCurrentStatus(hAdapter
))
981 DoFormatMessage(GetLastError());
982 CloseHandle(hAdapter
);
987 CloseHandle(hAdapter
);