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 NDISUIO_QUERY_OID QueryOid
;
96 /* NDIS 5.1 WLAN drivers must support this OID */
97 QueryOid
.Oid
= OID_GEN_PHYSICAL_MEDIUM
;
99 bSuccess
= DeviceIoControl(hAdapter
,
100 IOCTL_NDISUIO_QUERY_OID_VALUE
,
107 if (!bSuccess
|| *(PULONG
)QueryOid
.Data
!= NdisPhysicalMediumWirelessLan
)
114 OpenAdapterHandle(DWORD Index
)
118 DWORD dwBytesReturned
;
119 DWORD QueryBindingSize
= sizeof(NDISUIO_QUERY_BINDING
) + (1024 * sizeof(WCHAR
));
120 PNDISUIO_QUERY_BINDING QueryBinding
;
122 /* Open the driver handle */
123 hDriver
= OpenDriverHandle();
124 if (hDriver
== INVALID_HANDLE_VALUE
)
125 return INVALID_HANDLE_VALUE
;
127 /* Allocate the binding struct */
128 QueryBinding
= HeapAlloc(GetProcessHeap(), 0, QueryBindingSize
);
131 CloseHandle(hDriver
);
132 return INVALID_HANDLE_VALUE
;
135 /* Query the adapter binding information */
136 QueryBinding
->BindingIndex
= Index
;
137 bSuccess
= DeviceIoControl(hDriver
,
138 IOCTL_NDISUIO_QUERY_BINDING
,
148 HeapFree(GetProcessHeap(), 0, QueryBinding
);
149 CloseHandle(hDriver
);
150 return INVALID_HANDLE_VALUE
;
153 /* Bind to the adapter */
154 bSuccess
= DeviceIoControl(hDriver
,
155 IOCTL_NDISUIO_OPEN_DEVICE
,
156 (PUCHAR
)QueryBinding
+ QueryBinding
->DeviceNameOffset
,
157 QueryBinding
->DeviceNameLength
,
162 HeapFree(GetProcessHeap(), 0, QueryBinding
);
166 CloseHandle(hDriver
);
167 return INVALID_HANDLE_VALUE
;
173 /* Only works with the first adapter for now */
175 OpenWlanAdapter(VOID
)
177 DWORD dwCurrentIndex
;
178 HANDLE hCurrentAdapter
;
180 for (dwCurrentIndex
= 0; ; dwCurrentIndex
++)
182 hCurrentAdapter
= OpenAdapterHandle(dwCurrentIndex
);
183 if (hCurrentAdapter
== INVALID_HANDLE_VALUE
)
186 if (IsWlanAdapter(hCurrentAdapter
))
187 return hCurrentAdapter
;
189 CloseHandle(hCurrentAdapter
);
192 return INVALID_HANDLE_VALUE
;
196 WlanDisconnect(HANDLE hAdapter
)
199 DWORD dwBytesReturned
;
200 NDISUIO_SET_OID SetOid
;
202 SetOid
.Oid
= OID_802_11_DISASSOCIATE
;
204 bSuccess
= DeviceIoControl(hAdapter
,
205 IOCTL_NDISUIO_SET_OID_VALUE
,
220 Char
= toupper(Char
);
262 WlanConnect(HANDLE hAdapter
)
265 DWORD dwBytesReturned
, SetOidSize
;
266 PNDISUIO_SET_OID SetOid
;
267 PNDIS_802_11_SSID Ssid
;
270 SetOidSize
= sizeof(NDISUIO_SET_OID
);
271 SetOid
= HeapAlloc(GetProcessHeap(), 0, SetOidSize
);
275 /* Set the network mode */
276 SetOid
->Oid
= OID_802_11_INFRASTRUCTURE_MODE
;
277 *(PULONG
)SetOid
->Data
= bAdhoc
? Ndis802_11IBSS
: Ndis802_11Infrastructure
;
279 bSuccess
= DeviceIoControl(hAdapter
,
280 IOCTL_NDISUIO_SET_OID_VALUE
,
289 HeapFree(GetProcessHeap(), 0, SetOid
);
293 /* Set the authentication mode */
294 SetOid
->Oid
= OID_802_11_AUTHENTICATION_MODE
;
295 *(PULONG
)SetOid
->Data
= sWepKey
? Ndis802_11AuthModeShared
: Ndis802_11AuthModeOpen
;
297 bSuccess
= DeviceIoControl(hAdapter
,
298 IOCTL_NDISUIO_SET_OID_VALUE
,
307 HeapFree(GetProcessHeap(), 0, SetOid
);
313 PNDIS_802_11_WEP WepData
;
315 HeapFree(GetProcessHeap(), 0, SetOid
);
317 SetOidSize
= sizeof(NDISUIO_SET_OID
) + FIELD_OFFSET(NDIS_802_11_WEP
, KeyMaterial
) +
318 (strlen(sWepKey
) >> 2);
319 SetOid
= HeapAlloc(GetProcessHeap(), 0, SetOidSize
);
323 /* Add the WEP key */
324 SetOid
->Oid
= OID_802_11_ADD_WEP
;
325 WepData
= (PNDIS_802_11_WEP
)SetOid
->Data
;
327 WepData
->KeyIndex
= 0x80000000;
328 WepData
->KeyLength
= strlen(sWepKey
) >> 2;
329 WepData
->Length
= FIELD_OFFSET(NDIS_802_11_WEP
, KeyMaterial
) + WepData
->KeyLength
;
331 /* Assemble the hex key */
333 while (sWepKey
[i
<< 2] != '\0')
335 WepData
->KeyMaterial
[i
] = CharToHex(sWepKey
[i
<< 2]) << 4;
336 WepData
->KeyMaterial
[i
] |= CharToHex(sWepKey
[(i
<< 2) + 1]);
340 bSuccess
= DeviceIoControl(hAdapter
,
341 IOCTL_NDISUIO_SET_OID_VALUE
,
350 HeapFree(GetProcessHeap(), 0, SetOid
);
355 /* Set the encryption status */
356 SetOid
->Oid
= OID_802_11_WEP_STATUS
;
357 *(PULONG
)SetOid
->Data
= sWepKey
? Ndis802_11WEPEnabled
: Ndis802_11WEPDisabled
;
359 bSuccess
= DeviceIoControl(hAdapter
,
360 IOCTL_NDISUIO_SET_OID_VALUE
,
369 HeapFree(GetProcessHeap(), 0, SetOid
);
373 HeapFree(GetProcessHeap(), 0, SetOid
);
374 SetOidSize
= sizeof(NDISUIO_SET_OID
) + sizeof(NDIS_802_11_MAC_ADDRESS
);
375 SetOid
= HeapAlloc(GetProcessHeap(), 0, SetOidSize
);
380 SetOid
->Oid
= OID_802_11_BSSID
;
381 RtlFillMemory(SetOid
->Data
, sizeof(NDIS_802_11_MAC_ADDRESS
), 0xFF);
383 bSuccess
= DeviceIoControl(hAdapter
,
384 IOCTL_NDISUIO_SET_OID_VALUE
,
393 HeapFree(GetProcessHeap(), 0, SetOid
);
397 HeapFree(GetProcessHeap(), 0, SetOid
);
398 SetOidSize
= sizeof(NDISUIO_SET_OID
) + sizeof(NDIS_802_11_SSID
);
399 SetOid
= HeapAlloc(GetProcessHeap(), 0, SetOidSize
);
403 /* Finally, set the SSID */
404 SetOid
->Oid
= OID_802_11_SSID
;
405 Ssid
= (PNDIS_802_11_SSID
)SetOid
->Data
;
407 RtlCopyMemory(Ssid
->Ssid
, sSsid
, strlen(sSsid
));
408 Ssid
->SsidLength
= strlen(sSsid
);
410 bSuccess
= DeviceIoControl(hAdapter
,
411 IOCTL_NDISUIO_SET_OID_VALUE
,
419 HeapFree(GetProcessHeap(), 0, SetOid
);
425 WlanScan(HANDLE hAdapter
)
428 DWORD dwBytesReturned
;
429 NDISUIO_SET_OID SetOid
;
430 PNDISUIO_QUERY_OID QueryOid
;
432 PNDIS_802_11_BSSID_LIST BssidList
;
435 SetOid
.Oid
= OID_802_11_BSSID_LIST_SCAN
;
437 /* Send the scan OID */
438 bSuccess
= DeviceIoControl(hAdapter
,
439 IOCTL_NDISUIO_SET_OID_VALUE
,
449 /* Allocate space for 15 networks to be returned */
450 QueryOidSize
= sizeof(NDISUIO_QUERY_OID
) + (sizeof(NDIS_WLAN_BSSID
) * 15);
451 QueryOid
= HeapAlloc(GetProcessHeap(), 0, QueryOidSize
);
455 QueryOid
->Oid
= OID_802_11_BSSID_LIST
;
456 BssidList
= (PNDIS_802_11_BSSID_LIST
)QueryOid
->Data
;
458 bSuccess
= DeviceIoControl(hAdapter
,
459 IOCTL_NDISUIO_QUERY_OID_VALUE
,
468 HeapFree(GetProcessHeap(), 0, QueryOid
);
472 if (BssidList
->NumberOfItems
== 0)
474 _tprintf(_T("No networks found in range\n"));
478 PNDIS_WLAN_BSSID BssidInfo
= BssidList
->Bssid
;
479 for (i
= 0; i
< BssidList
->NumberOfItems
; i
++)
481 PNDIS_802_11_SSID Ssid
= &BssidInfo
->Ssid
;
482 NDIS_802_11_RSSI Rssi
= BssidInfo
->Rssi
;
483 NDIS_802_11_NETWORK_INFRASTRUCTURE NetworkType
= BssidInfo
->InfrastructureMode
;
484 CHAR SsidBuffer
[NDIS_802_11_LENGTH_SSID
+ 1];
487 /* SSID member is a non-null terminated ASCII string */
488 RtlCopyMemory(SsidBuffer
, Ssid
->Ssid
, Ssid
->SsidLength
);
489 SsidBuffer
[Ssid
->SsidLength
] = 0;
491 _tprintf(_T("\nSSID: %s\n"
495 "Supported Rates (Mbps): "),
497 BssidInfo
->Privacy
== 0 ? "No" : "Yes",
498 NetworkType
== Ndis802_11IBSS
? "Adhoc" : "Infrastructure",
501 for (j
= 0; j
< NDIS_802_11_LENGTH_RATES
; j
++)
503 Rate
= BssidInfo
->SupportedRates
[j
];
506 /* SupportedRates are in units of .5 */
509 _tprintf(_T("%u "), Rate
);
514 /* Move to the next entry */
515 BssidInfo
= (PNDIS_WLAN_BSSID
)((PUCHAR
)BssidInfo
+ BssidInfo
->Length
);
519 HeapFree(GetProcessHeap(), 0, QueryOid
);
526 _tprintf(_T("\nConfigures a WLAN adapter.\n\n"
527 "WLANCONF [-c SSID [-w WEP] [-a]] [-d] [-s]\n\n"
528 " -c SSID Connects to a supplied SSID.\n"
529 " -w WEP Specifies a WEP key to use.\n"
530 " -a Specifies the target network is ad-hoc\n"
531 " -d Disconnects from the current AP.\n"
532 " -s Scans and displays a list of access points in range.\n"));
536 BOOL
ParseCmdline(int argc
, char* argv
[])
540 for (i
= 1; i
< argc
; i
++)
542 if (argv
[i
][0] == '-')
585 if (!bScan
&& !bDisconnect
&& !bConnect
)
594 int main(int argc
, char* argv
[])
598 if (!ParseCmdline(argc
, argv
))
601 hAdapter
= OpenWlanAdapter();
602 if (hAdapter
== INVALID_HANDLE_VALUE
)
604 DoFormatMessage(GetLastError());
610 if (!WlanScan(hAdapter
))
612 DoFormatMessage(GetLastError());
613 CloseHandle(hAdapter
);
617 else if (bDisconnect
)
619 if (!WlanDisconnect(hAdapter
))
621 DoFormatMessage(GetLastError());
622 CloseHandle(hAdapter
);
628 if (!WlanConnect(hAdapter
))
630 DoFormatMessage(GetLastError());
631 CloseHandle(hAdapter
);
636 CloseHandle(hAdapter
);