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)
18 BOOL bConnect
= FALSE
;
23 BOOL bDisconnect
= FALSE
;
25 DWORD
DoFormatMessage(DWORD ErrorCode
)
30 if ((RetVal
= FormatMessage(
31 FORMAT_MESSAGE_ALLOCATE_BUFFER
|
32 FORMAT_MESSAGE_FROM_SYSTEM
|
33 FORMAT_MESSAGE_IGNORE_INSERTS
,
36 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
), /* Default language */
41 _tprintf(_T("%s"), (LPTSTR
)lpMsgBuf
);
45 /* return number of TCHAR's stored in output buffer
46 * excluding '\0' - as FormatMessage does*/
54 OpenDriverHandle(VOID
)
57 DWORD dwBytesReturned
;
60 /* Open a handle to the NDISUIO driver */
61 hDriver
= CreateFileW(NDISUIO_DEVICE_NAME
,
62 GENERIC_READ
| GENERIC_WRITE
,
66 FILE_ATTRIBUTE_NORMAL
,
68 if (hDriver
== INVALID_HANDLE_VALUE
)
69 return INVALID_HANDLE_VALUE
;
72 bSuccess
= DeviceIoControl(hDriver
,
73 IOCTL_NDISUIO_BIND_WAIT
,
83 return INVALID_HANDLE_VALUE
;
90 IsWlanAdapter(HANDLE hAdapter
)
93 DWORD dwBytesReturned
;
94 PNDISUIO_QUERY_OID QueryOid
;
97 QueryOidSize
= FIELD_OFFSET(NDISUIO_QUERY_OID
, Data
) + sizeof(NDIS_802_11_SSID
);
98 QueryOid
= HeapAlloc(GetProcessHeap(), 0, QueryOidSize
);
102 /* We're just going to do a OID_802_11_SSID query. WLAN drivers should
103 * always succeed this query (returning SsidLength = 0 if not associated) */
104 QueryOid
->Oid
= OID_802_11_SSID
;
106 bSuccess
= DeviceIoControl(hAdapter
,
107 IOCTL_NDISUIO_QUERY_OID_VALUE
,
115 HeapFree(GetProcessHeap(), 0, QueryOid
);
121 OpenAdapterHandle(DWORD Index
)
125 DWORD dwBytesReturned
;
126 DWORD QueryBindingSize
= sizeof(NDISUIO_QUERY_BINDING
) + (1024 * sizeof(WCHAR
));
127 PNDISUIO_QUERY_BINDING QueryBinding
;
129 /* Open the driver handle */
130 hDriver
= OpenDriverHandle();
131 if (hDriver
== INVALID_HANDLE_VALUE
)
132 return INVALID_HANDLE_VALUE
;
134 /* Allocate the binding struct */
135 QueryBinding
= HeapAlloc(GetProcessHeap(), 0, QueryBindingSize
);
138 CloseHandle(hDriver
);
139 return INVALID_HANDLE_VALUE
;
142 /* Query the adapter binding information */
143 QueryBinding
->BindingIndex
= Index
;
144 bSuccess
= DeviceIoControl(hDriver
,
145 IOCTL_NDISUIO_QUERY_BINDING
,
155 HeapFree(GetProcessHeap(), 0, QueryBinding
);
156 CloseHandle(hDriver
);
157 return INVALID_HANDLE_VALUE
;
160 /* Bind to the adapter */
161 bSuccess
= DeviceIoControl(hDriver
,
162 IOCTL_NDISUIO_OPEN_DEVICE
,
163 (PUCHAR
)QueryBinding
+ QueryBinding
->DeviceNameOffset
,
164 QueryBinding
->DeviceNameLength
,
169 HeapFree(GetProcessHeap(), 0, QueryBinding
);
173 CloseHandle(hDriver
);
174 return INVALID_HANDLE_VALUE
;
180 /* Only works with the first adapter for now */
182 OpenWlanAdapter(VOID
)
184 DWORD dwCurrentIndex
;
185 HANDLE hCurrentAdapter
;
187 for (dwCurrentIndex
= 0; ; dwCurrentIndex
++)
189 hCurrentAdapter
= OpenAdapterHandle(dwCurrentIndex
);
190 if (hCurrentAdapter
== INVALID_HANDLE_VALUE
)
193 if (IsWlanAdapter(hCurrentAdapter
))
194 return hCurrentAdapter
;
196 CloseHandle(hCurrentAdapter
);
199 return INVALID_HANDLE_VALUE
;
203 WlanDisconnect(HANDLE hAdapter
)
206 DWORD dwBytesReturned
;
207 NDISUIO_SET_OID SetOid
;
209 SetOid
.Oid
= OID_802_11_DISASSOCIATE
;
211 bSuccess
= DeviceIoControl(hAdapter
,
212 IOCTL_NDISUIO_SET_OID_VALUE
,
222 _tprintf(_T("The operation completed successfully.\n"));
230 Char
= toupper(Char
);
272 WlanPrintCurrentStatus(HANDLE hAdapter
)
274 PNDISUIO_QUERY_OID QueryOid
;
277 DWORD dwBytesReturned
;
278 PNDIS_802_11_SSID SsidInfo
;
279 CHAR SsidBuffer
[NDIS_802_11_LENGTH_SSID
+ 1];
282 QueryOidSize
= FIELD_OFFSET(NDISUIO_QUERY_OID
, Data
) + sizeof(NDIS_802_11_SSID
);
283 QueryOid
= HeapAlloc(GetProcessHeap(), 0, QueryOidSize
);
287 QueryOid
->Oid
= OID_802_11_SSID
;
288 SsidInfo
= (PNDIS_802_11_SSID
)QueryOid
->Data
;
290 bSuccess
= DeviceIoControl(hAdapter
,
291 IOCTL_NDISUIO_QUERY_OID_VALUE
,
300 HeapFree(GetProcessHeap(), 0, QueryOid
);
304 if (SsidInfo
->SsidLength
== 0)
306 _tprintf(_T("\nWLAN disconnected\n"));
307 HeapFree(GetProcessHeap(), 0, QueryOid
);
312 _tprintf(_T("\nCurrent wireless association information:\n\n"));
315 /* Copy the SSID to our internal buffer and terminate it */
316 RtlCopyMemory(SsidBuffer
, SsidInfo
->Ssid
, SsidInfo
->SsidLength
);
317 SsidBuffer
[SsidInfo
->SsidLength
] = 0;
319 _tprintf(_T("SSID: %s\n"), SsidBuffer
);
321 HeapFree(GetProcessHeap(), 0, QueryOid
);
322 QueryOidSize
= FIELD_OFFSET(NDISUIO_QUERY_OID
, Data
) + sizeof(NDIS_802_11_MAC_ADDRESS
);
323 QueryOid
= HeapAlloc(GetProcessHeap(), 0, QueryOidSize
);
327 QueryOid
->Oid
= OID_802_11_BSSID
;
329 bSuccess
= DeviceIoControl(hAdapter
,
330 IOCTL_NDISUIO_QUERY_OID_VALUE
,
339 HeapFree(GetProcessHeap(), 0, QueryOid
);
343 _tprintf(_T("BSSID: "));
344 for (i
= 0; i
< sizeof(NDIS_802_11_MAC_ADDRESS
); i
++)
346 UINT BssidData
= QueryOid
->Data
[i
];
348 _tprintf(_T("%.2x"), BssidData
);
350 if (i
!= sizeof(NDIS_802_11_MAC_ADDRESS
) - 1)
355 HeapFree(GetProcessHeap(), 0, QueryOid
);
356 QueryOidSize
= sizeof(NDISUIO_QUERY_OID
);
357 QueryOid
= HeapAlloc(GetProcessHeap(), 0, QueryOidSize
);
361 QueryOid
->Oid
= OID_802_11_INFRASTRUCTURE_MODE
;
363 bSuccess
= DeviceIoControl(hAdapter
,
364 IOCTL_NDISUIO_QUERY_OID_VALUE
,
373 HeapFree(GetProcessHeap(), 0, QueryOid
);
377 _tprintf(_T("Network mode: %s\n"), (*(PUINT
)QueryOid
->Data
== Ndis802_11IBSS
) ? "Adhoc" : "Infrastructure");
379 QueryOid
->Oid
= OID_802_11_WEP_STATUS
;
381 bSuccess
= DeviceIoControl(hAdapter
,
382 IOCTL_NDISUIO_QUERY_OID_VALUE
,
391 HeapFree(GetProcessHeap(), 0, QueryOid
);
395 _tprintf(_T("WEP enabled: %s\n"), (*(PUINT
)QueryOid
->Data
== Ndis802_11WEPEnabled
) ? "Yes" : "No");
398 QueryOid
->Oid
= OID_802_11_RSSI
;
400 bSuccess
= DeviceIoControl(hAdapter
,
401 IOCTL_NDISUIO_QUERY_OID_VALUE
,
410 /* This OID is optional */
411 _tprintf(_T("RSSI: %i dBm\n"), *(PINT
)QueryOid
->Data
);
414 QueryOid
->Oid
= OID_802_11_TX_POWER_LEVEL
;
416 bSuccess
= DeviceIoControl(hAdapter
,
417 IOCTL_NDISUIO_QUERY_OID_VALUE
,
426 /* This OID is optional */
427 _tprintf(_T("Transmission power: %d mW\n"), *(PUINT
)QueryOid
->Data
);
432 QueryOid
->Oid
= OID_802_11_NUMBER_OF_ANTENNAS
;
434 bSuccess
= DeviceIoControl(hAdapter
,
435 IOCTL_NDISUIO_QUERY_OID_VALUE
,
444 /* This OID is optional */
445 _tprintf(_T("Antenna count: %d\n"), *(PUINT
)QueryOid
->Data
);
448 QueryOid
->Oid
= OID_802_11_TX_ANTENNA_SELECTED
;
450 bSuccess
= DeviceIoControl(hAdapter
,
451 IOCTL_NDISUIO_QUERY_OID_VALUE
,
460 UINT TransmitAntenna
= *(PUINT
)QueryOid
->Data
;
462 if (TransmitAntenna
!= 0xFFFFFFFF)
463 _tprintf(_T("Transmit antenna: %d\n"), TransmitAntenna
);
465 _tprintf(_T("Transmit antenna: Any\n"));
468 QueryOid
->Oid
= OID_802_11_RX_ANTENNA_SELECTED
;
470 bSuccess
= DeviceIoControl(hAdapter
,
471 IOCTL_NDISUIO_QUERY_OID_VALUE
,
480 UINT ReceiveAntenna
= *(PUINT
)QueryOid
->Data
;
482 if (ReceiveAntenna
!= 0xFFFFFFFF)
483 _tprintf(_T("Receive antenna: %d\n"), ReceiveAntenna
);
485 _tprintf(_T("Receive antenna: Any\n"));
490 QueryOid
->Oid
= OID_802_11_FRAGMENTATION_THRESHOLD
;
492 bSuccess
= DeviceIoControl(hAdapter
,
493 IOCTL_NDISUIO_QUERY_OID_VALUE
,
502 /* This OID is optional */
503 _tprintf(_T("Fragmentation threshold: %d bytes\n"), *(PUINT
)QueryOid
->Data
);
506 QueryOid
->Oid
= OID_802_11_RTS_THRESHOLD
;
508 bSuccess
= DeviceIoControl(hAdapter
,
509 IOCTL_NDISUIO_QUERY_OID_VALUE
,
518 /* This OID is optional */
519 _tprintf(_T("RTS threshold: %d bytes\n"), *(PUINT
)QueryOid
->Data
);
522 HeapFree(GetProcessHeap(), 0, QueryOid
);
529 WlanConnect(HANDLE hAdapter
)
532 DWORD dwBytesReturned
, SetOidSize
;
533 PNDISUIO_SET_OID SetOid
;
534 PNDIS_802_11_SSID Ssid
;
537 SetOidSize
= sizeof(NDISUIO_SET_OID
);
538 SetOid
= HeapAlloc(GetProcessHeap(), 0, SetOidSize
);
542 /* Set the network mode */
543 SetOid
->Oid
= OID_802_11_INFRASTRUCTURE_MODE
;
544 *(PULONG
)SetOid
->Data
= bAdhoc
? Ndis802_11IBSS
: Ndis802_11Infrastructure
;
546 bSuccess
= DeviceIoControl(hAdapter
,
547 IOCTL_NDISUIO_SET_OID_VALUE
,
556 HeapFree(GetProcessHeap(), 0, SetOid
);
560 /* Set the authentication mode */
561 SetOid
->Oid
= OID_802_11_AUTHENTICATION_MODE
;
562 *(PULONG
)SetOid
->Data
= sWepKey
? Ndis802_11AuthModeShared
: Ndis802_11AuthModeOpen
;
564 bSuccess
= DeviceIoControl(hAdapter
,
565 IOCTL_NDISUIO_SET_OID_VALUE
,
574 HeapFree(GetProcessHeap(), 0, SetOid
);
580 PNDIS_802_11_WEP WepData
;
582 HeapFree(GetProcessHeap(), 0, SetOid
);
584 SetOidSize
= FIELD_OFFSET(NDISUIO_SET_OID
, Data
) +
585 FIELD_OFFSET(NDIS_802_11_WEP
, KeyMaterial
) +
586 (strlen(sWepKey
) >> 1);
587 SetOid
= HeapAlloc(GetProcessHeap(), 0, SetOidSize
);
591 /* Add the WEP key */
592 SetOid
->Oid
= OID_802_11_ADD_WEP
;
593 WepData
= (PNDIS_802_11_WEP
)SetOid
->Data
;
595 WepData
->KeyIndex
= 0x80000000;
596 WepData
->KeyLength
= strlen(sWepKey
) >> 1;
597 WepData
->Length
= FIELD_OFFSET(NDIS_802_11_WEP
, KeyMaterial
) + WepData
->KeyLength
;
599 /* Assemble the hex key */
601 while (sWepKey
[i
<< 1] != '\0')
603 WepData
->KeyMaterial
[i
] = CharToHex(sWepKey
[i
<< 1]) << 4;
604 WepData
->KeyMaterial
[i
] |= CharToHex(sWepKey
[(i
<< 1) + 1]);
608 bSuccess
= DeviceIoControl(hAdapter
,
609 IOCTL_NDISUIO_SET_OID_VALUE
,
618 HeapFree(GetProcessHeap(), 0, SetOid
);
623 /* Set the encryption status */
624 SetOid
->Oid
= OID_802_11_WEP_STATUS
;
625 *(PULONG
)SetOid
->Data
= sWepKey
? Ndis802_11WEPEnabled
: Ndis802_11WEPDisabled
;
627 bSuccess
= DeviceIoControl(hAdapter
,
628 IOCTL_NDISUIO_SET_OID_VALUE
,
637 HeapFree(GetProcessHeap(), 0, SetOid
);
641 HeapFree(GetProcessHeap(), 0, SetOid
);
642 SetOidSize
= FIELD_OFFSET(NDISUIO_SET_OID
, Data
) + sizeof(NDIS_802_11_MAC_ADDRESS
);
643 SetOid
= HeapAlloc(GetProcessHeap(), 0, SetOidSize
);
648 SetOid
->Oid
= OID_802_11_BSSID
;
649 RtlFillMemory(SetOid
->Data
, sizeof(NDIS_802_11_MAC_ADDRESS
), 0xFF);
651 bSuccess
= DeviceIoControl(hAdapter
,
652 IOCTL_NDISUIO_SET_OID_VALUE
,
661 HeapFree(GetProcessHeap(), 0, SetOid
);
665 HeapFree(GetProcessHeap(), 0, SetOid
);
666 SetOidSize
= FIELD_OFFSET(NDISUIO_SET_OID
, Data
) + sizeof(NDIS_802_11_SSID
);
667 SetOid
= HeapAlloc(GetProcessHeap(), 0, SetOidSize
);
671 /* Finally, set the SSID */
672 SetOid
->Oid
= OID_802_11_SSID
;
673 Ssid
= (PNDIS_802_11_SSID
)SetOid
->Data
;
675 RtlCopyMemory(Ssid
->Ssid
, sSsid
, strlen(sSsid
));
676 Ssid
->SsidLength
= strlen(sSsid
);
678 bSuccess
= DeviceIoControl(hAdapter
,
679 IOCTL_NDISUIO_SET_OID_VALUE
,
687 HeapFree(GetProcessHeap(), 0, SetOid
);
692 _tprintf(_T("The operation completed successfully.\n"));
697 WlanScan(HANDLE hAdapter
)
700 DWORD dwBytesReturned
;
701 NDISUIO_SET_OID SetOid
;
702 PNDISUIO_QUERY_OID QueryOid
;
704 PNDIS_802_11_BSSID_LIST BssidList
;
707 SetOid
.Oid
= OID_802_11_BSSID_LIST_SCAN
;
709 /* Send the scan OID */
710 bSuccess
= DeviceIoControl(hAdapter
,
711 IOCTL_NDISUIO_SET_OID_VALUE
,
721 /* Allocate space for 15 networks to be returned */
722 QueryOidSize
= sizeof(NDISUIO_QUERY_OID
) + (sizeof(NDIS_WLAN_BSSID
) * 15);
723 QueryOid
= HeapAlloc(GetProcessHeap(), 0, QueryOidSize
);
727 QueryOid
->Oid
= OID_802_11_BSSID_LIST
;
728 BssidList
= (PNDIS_802_11_BSSID_LIST
)QueryOid
->Data
;
730 bSuccess
= DeviceIoControl(hAdapter
,
731 IOCTL_NDISUIO_QUERY_OID_VALUE
,
740 HeapFree(GetProcessHeap(), 0, QueryOid
);
744 if (BssidList
->NumberOfItems
== 0)
746 _tprintf(_T("No networks found in range\n"));
750 PNDIS_WLAN_BSSID BssidInfo
= BssidList
->Bssid
;
751 for (i
= 0; i
< BssidList
->NumberOfItems
; i
++)
753 PNDIS_802_11_SSID Ssid
= &BssidInfo
->Ssid
;
754 NDIS_802_11_RSSI Rssi
= BssidInfo
->Rssi
;
755 NDIS_802_11_NETWORK_INFRASTRUCTURE NetworkType
= BssidInfo
->InfrastructureMode
;
756 CHAR SsidBuffer
[NDIS_802_11_LENGTH_SSID
+ 1];
759 /* SSID member is a non-null terminated ASCII string */
760 RtlCopyMemory(SsidBuffer
, Ssid
->Ssid
, Ssid
->SsidLength
);
761 SsidBuffer
[Ssid
->SsidLength
] = 0;
763 _tprintf(_T("\nSSID: %s\n"
767 "Supported Rates (Mbps): "),
769 BssidInfo
->Privacy
== 0 ? "No" : "Yes",
770 NetworkType
== Ndis802_11IBSS
? "Adhoc" : "Infrastructure",
773 for (j
= 0; j
< NDIS_802_11_LENGTH_RATES
; j
++)
775 Rate
= BssidInfo
->SupportedRates
[j
];
778 /* Bit 7 is the basic rates bit */
781 /* SupportedRates are in units of .5 */
784 /* Bit 0 is set so we need to add 0.5 */
785 _tprintf(_T("%u.5 "), (Rate
>> 1));
789 /* Bit 0 is clear so just print the conversion */
790 _tprintf(_T("%u "), (Rate
>> 1));
796 /* Move to the next entry */
797 BssidInfo
= (PNDIS_WLAN_BSSID
)((PUCHAR
)BssidInfo
+ BssidInfo
->Length
);
801 HeapFree(GetProcessHeap(), 0, QueryOid
);
808 _tprintf(_T("\nConfigures a WLAN adapter.\n\n"
809 "WLANCONF [-c SSID [-w WEP] [-a]] [-d] [-s]\n\n"
810 " -c SSID Connects to a supplied SSID.\n"
811 " -w WEP Specifies a WEP key to use.\n"
812 " -a Specifies the target network is ad-hoc\n"
813 " -d Disconnects from the current AP.\n"
814 " -s Scans and displays a list of access points in range.\n\n"
815 " Passing no parameters will print information about the current WLAN connection\n"));
819 BOOL
ParseCmdline(int argc
, char* argv
[])
823 for (i
= 1; i
< argc
; i
++)
825 if (argv
[i
][0] == '-')
871 int main(int argc
, char* argv
[])
875 if (!ParseCmdline(argc
, argv
))
878 hAdapter
= OpenWlanAdapter();
879 if (hAdapter
== INVALID_HANDLE_VALUE
)
881 DoFormatMessage(GetLastError());
887 if (!WlanScan(hAdapter
))
889 DoFormatMessage(GetLastError());
890 CloseHandle(hAdapter
);
894 else if (bDisconnect
)
896 if (!WlanDisconnect(hAdapter
))
898 DoFormatMessage(GetLastError());
899 CloseHandle(hAdapter
);
905 if (!WlanConnect(hAdapter
))
907 DoFormatMessage(GetLastError());
908 CloseHandle(hAdapter
);
914 if (!WlanPrintCurrentStatus(hAdapter
))
916 DoFormatMessage(GetLastError());
917 CloseHandle(hAdapter
);
922 CloseHandle(hAdapter
);