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
= sizeof(NDISUIO_QUERY_OID
) + 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
,
227 Char
= toupper(Char
);
269 WlanConnect(HANDLE hAdapter
)
272 DWORD dwBytesReturned
, SetOidSize
;
273 PNDISUIO_SET_OID SetOid
;
274 PNDIS_802_11_SSID Ssid
;
277 SetOidSize
= sizeof(NDISUIO_SET_OID
);
278 SetOid
= HeapAlloc(GetProcessHeap(), 0, SetOidSize
);
282 /* Set the network mode */
283 SetOid
->Oid
= OID_802_11_INFRASTRUCTURE_MODE
;
284 *(PULONG
)SetOid
->Data
= bAdhoc
? Ndis802_11IBSS
: Ndis802_11Infrastructure
;
286 bSuccess
= DeviceIoControl(hAdapter
,
287 IOCTL_NDISUIO_SET_OID_VALUE
,
296 HeapFree(GetProcessHeap(), 0, SetOid
);
300 /* Set the authentication mode */
301 SetOid
->Oid
= OID_802_11_AUTHENTICATION_MODE
;
302 *(PULONG
)SetOid
->Data
= sWepKey
? Ndis802_11AuthModeShared
: Ndis802_11AuthModeOpen
;
304 bSuccess
= DeviceIoControl(hAdapter
,
305 IOCTL_NDISUIO_SET_OID_VALUE
,
314 HeapFree(GetProcessHeap(), 0, SetOid
);
320 PNDIS_802_11_WEP WepData
;
322 HeapFree(GetProcessHeap(), 0, SetOid
);
324 SetOidSize
= sizeof(NDISUIO_SET_OID
) + FIELD_OFFSET(NDIS_802_11_WEP
, KeyMaterial
) +
325 (strlen(sWepKey
) >> 1);
326 SetOid
= HeapAlloc(GetProcessHeap(), 0, SetOidSize
);
330 /* Add the WEP key */
331 SetOid
->Oid
= OID_802_11_ADD_WEP
;
332 WepData
= (PNDIS_802_11_WEP
)SetOid
->Data
;
334 WepData
->KeyIndex
= 0x80000000;
335 WepData
->KeyLength
= strlen(sWepKey
) >> 1;
336 WepData
->Length
= FIELD_OFFSET(NDIS_802_11_WEP
, KeyMaterial
) + WepData
->KeyLength
;
338 /* Assemble the hex key */
340 while (sWepKey
[i
<< 1] != '\0')
342 WepData
->KeyMaterial
[i
] = CharToHex(sWepKey
[i
<< 1]) << 4;
343 WepData
->KeyMaterial
[i
] |= CharToHex(sWepKey
[(i
<< 1) + 1]);
347 bSuccess
= DeviceIoControl(hAdapter
,
348 IOCTL_NDISUIO_SET_OID_VALUE
,
357 HeapFree(GetProcessHeap(), 0, SetOid
);
362 /* Set the encryption status */
363 SetOid
->Oid
= OID_802_11_WEP_STATUS
;
364 *(PULONG
)SetOid
->Data
= sWepKey
? Ndis802_11WEPEnabled
: Ndis802_11WEPDisabled
;
366 bSuccess
= DeviceIoControl(hAdapter
,
367 IOCTL_NDISUIO_SET_OID_VALUE
,
376 HeapFree(GetProcessHeap(), 0, SetOid
);
380 HeapFree(GetProcessHeap(), 0, SetOid
);
381 SetOidSize
= sizeof(NDISUIO_SET_OID
) + sizeof(NDIS_802_11_MAC_ADDRESS
);
382 SetOid
= HeapAlloc(GetProcessHeap(), 0, SetOidSize
);
387 SetOid
->Oid
= OID_802_11_BSSID
;
388 RtlFillMemory(SetOid
->Data
, sizeof(NDIS_802_11_MAC_ADDRESS
), 0xFF);
390 bSuccess
= DeviceIoControl(hAdapter
,
391 IOCTL_NDISUIO_SET_OID_VALUE
,
400 HeapFree(GetProcessHeap(), 0, SetOid
);
404 HeapFree(GetProcessHeap(), 0, SetOid
);
405 SetOidSize
= sizeof(NDISUIO_SET_OID
) + sizeof(NDIS_802_11_SSID
);
406 SetOid
= HeapAlloc(GetProcessHeap(), 0, SetOidSize
);
410 /* Finally, set the SSID */
411 SetOid
->Oid
= OID_802_11_SSID
;
412 Ssid
= (PNDIS_802_11_SSID
)SetOid
->Data
;
414 RtlCopyMemory(Ssid
->Ssid
, sSsid
, strlen(sSsid
));
415 Ssid
->SsidLength
= strlen(sSsid
);
417 bSuccess
= DeviceIoControl(hAdapter
,
418 IOCTL_NDISUIO_SET_OID_VALUE
,
426 HeapFree(GetProcessHeap(), 0, SetOid
);
432 WlanScan(HANDLE hAdapter
)
435 DWORD dwBytesReturned
;
436 NDISUIO_SET_OID SetOid
;
437 PNDISUIO_QUERY_OID QueryOid
;
439 PNDIS_802_11_BSSID_LIST BssidList
;
442 SetOid
.Oid
= OID_802_11_BSSID_LIST_SCAN
;
444 /* Send the scan OID */
445 bSuccess
= DeviceIoControl(hAdapter
,
446 IOCTL_NDISUIO_SET_OID_VALUE
,
456 /* Allocate space for 15 networks to be returned */
457 QueryOidSize
= sizeof(NDISUIO_QUERY_OID
) + (sizeof(NDIS_WLAN_BSSID
) * 15);
458 QueryOid
= HeapAlloc(GetProcessHeap(), 0, QueryOidSize
);
462 QueryOid
->Oid
= OID_802_11_BSSID_LIST
;
463 BssidList
= (PNDIS_802_11_BSSID_LIST
)QueryOid
->Data
;
465 bSuccess
= DeviceIoControl(hAdapter
,
466 IOCTL_NDISUIO_QUERY_OID_VALUE
,
475 HeapFree(GetProcessHeap(), 0, QueryOid
);
479 if (BssidList
->NumberOfItems
== 0)
481 _tprintf(_T("No networks found in range\n"));
485 PNDIS_WLAN_BSSID BssidInfo
= BssidList
->Bssid
;
486 for (i
= 0; i
< BssidList
->NumberOfItems
; i
++)
488 PNDIS_802_11_SSID Ssid
= &BssidInfo
->Ssid
;
489 NDIS_802_11_RSSI Rssi
= BssidInfo
->Rssi
;
490 NDIS_802_11_NETWORK_INFRASTRUCTURE NetworkType
= BssidInfo
->InfrastructureMode
;
491 CHAR SsidBuffer
[NDIS_802_11_LENGTH_SSID
+ 1];
494 /* SSID member is a non-null terminated ASCII string */
495 RtlCopyMemory(SsidBuffer
, Ssid
->Ssid
, Ssid
->SsidLength
);
496 SsidBuffer
[Ssid
->SsidLength
] = 0;
498 _tprintf(_T("\nSSID: %s\n"
502 "Supported Rates (Mbps): "),
504 BssidInfo
->Privacy
== 0 ? "No" : "Yes",
505 NetworkType
== Ndis802_11IBSS
? "Adhoc" : "Infrastructure",
508 for (j
= 0; j
< NDIS_802_11_LENGTH_RATES
; j
++)
510 Rate
= BssidInfo
->SupportedRates
[j
];
513 /* Bit 7 is the basic rates bit */
516 /* SupportedRates are in units of .5 */
519 _tprintf(_T("%u "), Rate
);
524 /* Move to the next entry */
525 BssidInfo
= (PNDIS_WLAN_BSSID
)((PUCHAR
)BssidInfo
+ BssidInfo
->Length
);
529 HeapFree(GetProcessHeap(), 0, QueryOid
);
536 _tprintf(_T("\nConfigures a WLAN adapter.\n\n"
537 "WLANCONF [-c SSID [-w WEP] [-a]] [-d] [-s]\n\n"
538 " -c SSID Connects to a supplied SSID.\n"
539 " -w WEP Specifies a WEP key to use.\n"
540 " -a Specifies the target network is ad-hoc\n"
541 " -d Disconnects from the current AP.\n"
542 " -s Scans and displays a list of access points in range.\n"));
546 BOOL
ParseCmdline(int argc
, char* argv
[])
550 for (i
= 1; i
< argc
; i
++)
552 if (argv
[i
][0] == '-')
595 if (!bScan
&& !bDisconnect
&& !bConnect
)
604 int main(int argc
, char* argv
[])
608 if (!ParseCmdline(argc
, argv
))
611 hAdapter
= OpenWlanAdapter();
612 if (hAdapter
== INVALID_HANDLE_VALUE
)
614 DoFormatMessage(GetLastError());
620 if (!WlanScan(hAdapter
))
622 DoFormatMessage(GetLastError());
623 CloseHandle(hAdapter
);
627 else if (bDisconnect
)
629 if (!WlanDisconnect(hAdapter
))
631 DoFormatMessage(GetLastError());
632 CloseHandle(hAdapter
);
638 if (!WlanConnect(hAdapter
))
640 DoFormatMessage(GetLastError());
641 CloseHandle(hAdapter
);
646 CloseHandle(hAdapter
);