1 /* 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) 7 */ 8 9 #include <stdio.h> 10 #include <stdarg.h> 11 #include <tchar.h> 12 13 #include <windef.h> 14 #include <winbase.h> 15 #include <devioctl.h> 16 #include <ntddndis.h> 17 #include <nuiouser.h> 18 #include <iphlpapi.h> 19 20 #include <conutils.h> 21 22 #include "resource.h" 23 24 BOOL bScan = FALSE; 25 26 BOOL bConnect = FALSE; 27 WCHAR *sSsid = NULL; 28 WCHAR *sWepKey = NULL; 29 BOOL bAdhoc = FALSE; 30 31 BOOL bDisconnect = FALSE; 32 33 VOID DoFormatMessage(DWORD ErrorCode) 34 { 35 if (ErrorCode == ERROR_SUCCESS) 36 return; 37 38 ConMsgPuts(StdErr, FORMAT_MESSAGE_FROM_SYSTEM, 39 NULL, ErrorCode, LANG_USER_DEFAULT); 40 } 41 42 HANDLE 43 OpenDriverHandle(VOID) 44 { 45 HANDLE hDriver; 46 DWORD dwBytesReturned; 47 BOOL bSuccess; 48 49 /* Open a handle to the NDISUIO driver */ 50 hDriver = CreateFileW(NDISUIO_DEVICE_NAME, 51 GENERIC_READ | GENERIC_WRITE, 52 0, 53 NULL, 54 OPEN_EXISTING, 55 FILE_ATTRIBUTE_NORMAL, 56 NULL); 57 if (hDriver == INVALID_HANDLE_VALUE) 58 return INVALID_HANDLE_VALUE; 59 60 /* Wait for binds */ 61 bSuccess = DeviceIoControl(hDriver, 62 IOCTL_NDISUIO_BIND_WAIT, 63 NULL, 64 0, 65 NULL, 66 0, 67 &dwBytesReturned, 68 NULL); 69 if (!bSuccess) 70 { 71 CloseHandle(hDriver); 72 return INVALID_HANDLE_VALUE; 73 } 74 75 return hDriver; 76 } 77 78 BOOL 79 IsWlanAdapter(HANDLE hAdapter) 80 { 81 BOOL bSuccess; 82 DWORD dwBytesReturned; 83 NDISUIO_QUERY_OID QueryOid; 84 85 /* WLAN drivers must support this OID */ 86 QueryOid.Oid = OID_GEN_PHYSICAL_MEDIUM; 87 88 bSuccess = DeviceIoControl(hAdapter, 89 IOCTL_NDISUIO_QUERY_OID_VALUE, 90 &QueryOid, 91 sizeof(QueryOid), 92 &QueryOid, 93 sizeof(QueryOid), 94 &dwBytesReturned, 95 NULL); 96 if (!bSuccess || *(PULONG)QueryOid.Data != NdisPhysicalMediumWirelessLan) 97 return FALSE; 98 99 return TRUE; 100 } 101 102 BOOL 103 OpenAdapterHandle(DWORD Index, HANDLE *hAdapter, IP_ADAPTER_INDEX_MAP *IpInfo) 104 { 105 HANDLE hDriver; 106 BOOL bSuccess; 107 DWORD dwBytesReturned; 108 DWORD QueryBindingSize = sizeof(NDISUIO_QUERY_BINDING) + (1024 * sizeof(WCHAR)); 109 PNDISUIO_QUERY_BINDING QueryBinding; 110 DWORD dwStatus, dwSize; 111 LONG i; 112 PIP_INTERFACE_INFO InterfaceInfo = NULL; 113 114 /* Open the driver handle */ 115 hDriver = OpenDriverHandle(); 116 if (hDriver == INVALID_HANDLE_VALUE) 117 return FALSE; 118 119 /* Allocate the binding struct */ 120 QueryBinding = HeapAlloc(GetProcessHeap(), 0, QueryBindingSize); 121 if (!QueryBinding) 122 { 123 CloseHandle(hDriver); 124 return FALSE; 125 } 126 127 /* Query the adapter binding information */ 128 QueryBinding->BindingIndex = Index; 129 bSuccess = DeviceIoControl(hDriver, 130 IOCTL_NDISUIO_QUERY_BINDING, 131 QueryBinding, 132 QueryBindingSize, 133 QueryBinding, 134 QueryBindingSize, 135 &dwBytesReturned, 136 NULL); 137 138 if (!bSuccess) 139 { 140 HeapFree(GetProcessHeap(), 0, QueryBinding); 141 CloseHandle(hDriver); 142 return FALSE; 143 } 144 145 /* Bind to the adapter */ 146 bSuccess = DeviceIoControl(hDriver, 147 IOCTL_NDISUIO_OPEN_DEVICE, 148 (PUCHAR)QueryBinding + QueryBinding->DeviceNameOffset, 149 QueryBinding->DeviceNameLength, 150 NULL, 151 0, 152 &dwBytesReturned, 153 NULL); 154 155 if (!bSuccess) 156 { 157 HeapFree(GetProcessHeap(), 0, QueryBinding); 158 CloseHandle(hDriver); 159 return FALSE; 160 } 161 162 /* Get interface info from the IP helper */ 163 dwSize = sizeof(IP_INTERFACE_INFO); 164 do { 165 if (InterfaceInfo) HeapFree(GetProcessHeap(), 0, InterfaceInfo); 166 InterfaceInfo = HeapAlloc(GetProcessHeap(), 0, dwSize); 167 if (!InterfaceInfo) 168 { 169 HeapFree(GetProcessHeap(), 0, QueryBinding); 170 CloseHandle(hDriver); 171 return FALSE; 172 } 173 dwStatus = GetInterfaceInfo(InterfaceInfo, &dwSize); 174 } while (dwStatus == ERROR_INSUFFICIENT_BUFFER); 175 176 if (dwStatus != NO_ERROR) 177 { 178 HeapFree(GetProcessHeap(), 0, QueryBinding); 179 HeapFree(GetProcessHeap(), 0, InterfaceInfo); 180 CloseHandle(hDriver); 181 return FALSE; 182 } 183 184 for (i = 0; i < InterfaceInfo->NumAdapters; i++) 185 { 186 if (wcsstr((PWCHAR)((PUCHAR)QueryBinding + QueryBinding->DeviceNameOffset), 187 InterfaceInfo->Adapter[i].Name)) 188 { 189 *IpInfo = InterfaceInfo->Adapter[i]; 190 *hAdapter = hDriver; 191 192 HeapFree(GetProcessHeap(), 0, QueryBinding); 193 HeapFree(GetProcessHeap(), 0, InterfaceInfo); 194 195 return TRUE; 196 } 197 } 198 199 HeapFree(GetProcessHeap(), 0, QueryBinding); 200 HeapFree(GetProcessHeap(), 0, InterfaceInfo); 201 CloseHandle(hDriver); 202 203 return FALSE; 204 } 205 206 /* Only works with the first adapter for now */ 207 BOOL 208 OpenWlanAdapter(HANDLE *hAdapter, IP_ADAPTER_INDEX_MAP *IpInfo) 209 { 210 DWORD dwCurrentIndex; 211 212 for (dwCurrentIndex = 0; ; dwCurrentIndex++) 213 { 214 if (!OpenAdapterHandle(dwCurrentIndex, hAdapter, IpInfo)) 215 break; 216 217 if (IsWlanAdapter(*hAdapter)) 218 return TRUE; 219 else 220 CloseHandle(*hAdapter); 221 } 222 223 return FALSE; 224 } 225 226 BOOL 227 WlanDisconnect(HANDLE hAdapter, PIP_ADAPTER_INDEX_MAP IpInfo) 228 { 229 BOOL bSuccess; 230 DWORD dwBytesReturned; 231 NDISUIO_SET_OID SetOid; 232 233 /* Release this IP address */ 234 IpReleaseAddress(IpInfo); 235 236 /* Disassociate from the AP */ 237 SetOid.Oid = OID_802_11_DISASSOCIATE; 238 bSuccess = DeviceIoControl(hAdapter, 239 IOCTL_NDISUIO_SET_OID_VALUE, 240 &SetOid, 241 FIELD_OFFSET(NDISUIO_SET_OID, Data), 242 NULL, 243 0, 244 &dwBytesReturned, 245 NULL); 246 if (!bSuccess) 247 return FALSE; 248 249 ConResPuts(StdOut, IDS_SUCCESS); 250 return TRUE; 251 } 252 253 static 254 UCHAR 255 CharToHex(WCHAR Char) 256 { 257 if ((Char >= L'0') && (Char <= L'9')) 258 return Char - L'0'; 259 260 if ((Char >= L'a') && (Char <= L'f')) 261 return Char - L'a' + 10; 262 263 if ((Char >= L'A') && (Char <= L'F')) 264 return Char - L'A' + 10; 265 266 return 0; 267 } 268 269 BOOL 270 WlanPrintCurrentStatus(HANDLE hAdapter) 271 { 272 PNDISUIO_QUERY_OID QueryOid; 273 DWORD QueryOidSize; 274 BOOL bSuccess; 275 DWORD dwBytesReturned; 276 PNDIS_802_11_SSID SsidInfo; 277 CHAR SsidBuffer[NDIS_802_11_LENGTH_SSID + 1]; 278 DWORD i; 279 WCHAR szMsgBuf[128]; 280 281 QueryOidSize = FIELD_OFFSET(NDISUIO_QUERY_OID, Data) + sizeof(NDIS_802_11_SSID); 282 QueryOid = HeapAlloc(GetProcessHeap(), 0, QueryOidSize); 283 if (!QueryOid) 284 return FALSE; 285 286 QueryOid->Oid = OID_802_11_SSID; 287 SsidInfo = (PNDIS_802_11_SSID)QueryOid->Data; 288 289 bSuccess = DeviceIoControl(hAdapter, 290 IOCTL_NDISUIO_QUERY_OID_VALUE, 291 QueryOid, 292 QueryOidSize, 293 QueryOid, 294 QueryOidSize, 295 &dwBytesReturned, 296 NULL); 297 if (!bSuccess) 298 { 299 HeapFree(GetProcessHeap(), 0, QueryOid); 300 return FALSE; 301 } 302 303 /* Copy the SSID to our internal buffer and terminate it */ 304 RtlCopyMemory(SsidBuffer, SsidInfo->Ssid, SsidInfo->SsidLength); 305 SsidBuffer[SsidInfo->SsidLength] = 0; 306 307 HeapFree(GetProcessHeap(), 0, QueryOid); 308 QueryOidSize = FIELD_OFFSET(NDISUIO_QUERY_OID, Data) + sizeof(NDIS_802_11_MAC_ADDRESS); 309 QueryOid = HeapAlloc(GetProcessHeap(), 0, QueryOidSize); 310 if (!QueryOid) 311 return FALSE; 312 313 QueryOid->Oid = OID_802_11_BSSID; 314 315 bSuccess = DeviceIoControl(hAdapter, 316 IOCTL_NDISUIO_QUERY_OID_VALUE, 317 QueryOid, 318 QueryOidSize, 319 QueryOid, 320 QueryOidSize, 321 &dwBytesReturned, 322 NULL); 323 if (SsidInfo->SsidLength == 0 || !bSuccess) 324 { 325 ConResPuts(StdOut, IDS_WLAN_DISCONNECT); 326 HeapFree(GetProcessHeap(), 0, QueryOid); 327 return TRUE; 328 } 329 else 330 { 331 ConResPuts(StdOut, IDS_MSG_CURRENT_WIRELESS); 332 } 333 334 printf("SSID: %s\n", SsidBuffer); 335 336 printf("BSSID: "); 337 for (i = 0; i < sizeof(NDIS_802_11_MAC_ADDRESS); i++) 338 { 339 UINT BssidData = QueryOid->Data[i]; 340 341 printf("%.2x", BssidData); 342 343 if (i != sizeof(NDIS_802_11_MAC_ADDRESS) - 1) 344 printf(":"); 345 } 346 printf("\n"); 347 348 HeapFree(GetProcessHeap(), 0, QueryOid); 349 QueryOidSize = sizeof(NDISUIO_QUERY_OID); 350 QueryOid = HeapAlloc(GetProcessHeap(), 0, QueryOidSize); 351 if (!QueryOid) 352 return FALSE; 353 354 QueryOid->Oid = OID_802_11_INFRASTRUCTURE_MODE; 355 356 bSuccess = DeviceIoControl(hAdapter, 357 IOCTL_NDISUIO_QUERY_OID_VALUE, 358 QueryOid, 359 QueryOidSize, 360 QueryOid, 361 QueryOidSize, 362 &dwBytesReturned, 363 NULL); 364 if (!bSuccess) 365 { 366 HeapFree(GetProcessHeap(), 0, QueryOid); 367 return FALSE; 368 } 369 370 K32LoadStringW(GetModuleHandle(NULL), 371 *(PUINT)QueryOid->Data == Ndis802_11IBSS ? IDS_ADHOC : IDS_INFRASTRUCTURE, 372 szMsgBuf, 373 ARRAYSIZE(szMsgBuf)); 374 ConResPrintf(StdOut, IDS_MSG_NETWORK_MODE, szMsgBuf); 375 376 QueryOid->Oid = OID_802_11_WEP_STATUS; 377 378 bSuccess = DeviceIoControl(hAdapter, 379 IOCTL_NDISUIO_QUERY_OID_VALUE, 380 QueryOid, 381 QueryOidSize, 382 QueryOid, 383 QueryOidSize, 384 &dwBytesReturned, 385 NULL); 386 if (!bSuccess) 387 { 388 HeapFree(GetProcessHeap(), 0, QueryOid); 389 return FALSE; 390 } 391 392 K32LoadStringW(GetModuleHandle(NULL), 393 *(PUINT)QueryOid->Data == Ndis802_11WEPEnabled ? IDS_YES : IDS_NO, 394 szMsgBuf, 395 ARRAYSIZE(szMsgBuf)); 396 ConResPrintf(StdOut, IDS_MSG_WEP_ENABLED, szMsgBuf); 397 398 printf("\n"); 399 QueryOid->Oid = OID_802_11_RSSI; 400 401 bSuccess = DeviceIoControl(hAdapter, 402 IOCTL_NDISUIO_QUERY_OID_VALUE, 403 QueryOid, 404 QueryOidSize, 405 QueryOid, 406 QueryOidSize, 407 &dwBytesReturned, 408 NULL); 409 if (bSuccess) 410 { 411 /* This OID is optional */ 412 printf("RSSI: %i dBm\n", *(PINT)QueryOid->Data); 413 } 414 415 QueryOid->Oid = OID_802_11_TX_POWER_LEVEL; 416 417 bSuccess = DeviceIoControl(hAdapter, 418 IOCTL_NDISUIO_QUERY_OID_VALUE, 419 QueryOid, 420 QueryOidSize, 421 QueryOid, 422 QueryOidSize, 423 &dwBytesReturned, 424 NULL); 425 if (bSuccess) 426 { 427 /* This OID is optional */ 428 ConResPrintf(StdOut, IDS_MSG_TRANSMISSION_POWER, *(PUINT)QueryOid->Data); 429 } 430 431 printf("\n"); 432 433 QueryOid->Oid = OID_802_11_NUMBER_OF_ANTENNAS; 434 435 bSuccess = DeviceIoControl(hAdapter, 436 IOCTL_NDISUIO_QUERY_OID_VALUE, 437 QueryOid, 438 QueryOidSize, 439 QueryOid, 440 QueryOidSize, 441 &dwBytesReturned, 442 NULL); 443 if (bSuccess) 444 { 445 /* This OID is optional */ 446 ConResPrintf(StdOut, IDS_MSG_ANTENNA_COUNT, *(PUINT)QueryOid->Data); 447 } 448 449 QueryOid->Oid = OID_802_11_TX_ANTENNA_SELECTED; 450 451 bSuccess = DeviceIoControl(hAdapter, 452 IOCTL_NDISUIO_QUERY_OID_VALUE, 453 QueryOid, 454 QueryOidSize, 455 QueryOid, 456 QueryOidSize, 457 &dwBytesReturned, 458 NULL); 459 if (bSuccess) 460 { 461 UINT TransmitAntenna = *(PUINT)QueryOid->Data; 462 463 if (TransmitAntenna != 0xFFFFFFFF) 464 ConResPrintf(StdOut, IDS_MSG_TRANSMIT_ANTENNA, TransmitAntenna); 465 else 466 ConResPuts(StdOut, IDS_MSG_TRANSMIT_ANTENNA_ANY); 467 } 468 469 QueryOid->Oid = OID_802_11_RX_ANTENNA_SELECTED; 470 471 bSuccess = DeviceIoControl(hAdapter, 472 IOCTL_NDISUIO_QUERY_OID_VALUE, 473 QueryOid, 474 QueryOidSize, 475 QueryOid, 476 QueryOidSize, 477 &dwBytesReturned, 478 NULL); 479 if (bSuccess) 480 { 481 UINT ReceiveAntenna = *(PUINT)QueryOid->Data; 482 483 if (ReceiveAntenna != 0xFFFFFFFF) 484 ConResPrintf(StdOut, IDS_MSG_RECEIVE_ANTENNA, ReceiveAntenna); 485 else 486 ConResPuts(StdOut, IDS_MSG_RECEIVE_ANTENNA_ANY); 487 } 488 489 printf("\n"); 490 491 QueryOid->Oid = OID_802_11_FRAGMENTATION_THRESHOLD; 492 493 bSuccess = DeviceIoControl(hAdapter, 494 IOCTL_NDISUIO_QUERY_OID_VALUE, 495 QueryOid, 496 QueryOidSize, 497 QueryOid, 498 QueryOidSize, 499 &dwBytesReturned, 500 NULL); 501 if (bSuccess) 502 { 503 /* This OID is optional */ 504 ConResPrintf(StdOut, IDS_MSG_FRAGMENT_THRESHOLD, *(PUINT)QueryOid->Data); 505 } 506 507 QueryOid->Oid = OID_802_11_RTS_THRESHOLD; 508 509 bSuccess = DeviceIoControl(hAdapter, 510 IOCTL_NDISUIO_QUERY_OID_VALUE, 511 QueryOid, 512 QueryOidSize, 513 QueryOid, 514 QueryOidSize, 515 &dwBytesReturned, 516 NULL); 517 if (bSuccess) 518 { 519 /* This OID is optional */ 520 ConResPrintf(StdOut, IDS_MSG_RTS_THRESHOLD, *(PUINT)QueryOid->Data); 521 } 522 523 HeapFree(GetProcessHeap(), 0, QueryOid); 524 525 printf("\n"); 526 return TRUE; 527 } 528 529 BOOL 530 WlanConnect(HANDLE hAdapter) 531 { 532 CHAR SsidBuffer[NDIS_802_11_LENGTH_SSID + 1]; 533 BOOL bSuccess; 534 DWORD dwBytesReturned, SetOidSize; 535 PNDISUIO_SET_OID SetOid; 536 PNDIS_802_11_SSID Ssid; 537 DWORD i; 538 539 SetOidSize = sizeof(NDISUIO_SET_OID); 540 SetOid = HeapAlloc(GetProcessHeap(), 0, SetOidSize); 541 if (!SetOid) 542 return FALSE; 543 544 /* Set the network mode */ 545 SetOid->Oid = OID_802_11_INFRASTRUCTURE_MODE; 546 *(PULONG)SetOid->Data = bAdhoc ? Ndis802_11IBSS : Ndis802_11Infrastructure; 547 548 bSuccess = DeviceIoControl(hAdapter, 549 IOCTL_NDISUIO_SET_OID_VALUE, 550 SetOid, 551 SetOidSize, 552 NULL, 553 0, 554 &dwBytesReturned, 555 NULL); 556 if (!bSuccess) 557 { 558 HeapFree(GetProcessHeap(), 0, SetOid); 559 return FALSE; 560 } 561 562 /* Set the authentication mode */ 563 SetOid->Oid = OID_802_11_AUTHENTICATION_MODE; 564 *(PULONG)SetOid->Data = sWepKey ? Ndis802_11AuthModeShared : Ndis802_11AuthModeOpen; 565 566 bSuccess = DeviceIoControl(hAdapter, 567 IOCTL_NDISUIO_SET_OID_VALUE, 568 SetOid, 569 SetOidSize, 570 NULL, 571 0, 572 &dwBytesReturned, 573 NULL); 574 if (!bSuccess) 575 { 576 HeapFree(GetProcessHeap(), 0, SetOid); 577 return FALSE; 578 } 579 580 if (sWepKey) 581 { 582 PNDIS_802_11_WEP WepData; 583 584 HeapFree(GetProcessHeap(), 0, SetOid); 585 586 SetOidSize = FIELD_OFFSET(NDISUIO_SET_OID, Data) + 587 FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial) + 588 (wcslen(sWepKey) >> 1); 589 SetOid = HeapAlloc(GetProcessHeap(), 0, SetOidSize); 590 if (!SetOid) 591 return FALSE; 592 593 /* Add the WEP key */ 594 SetOid->Oid = OID_802_11_ADD_WEP; 595 WepData = (PNDIS_802_11_WEP)SetOid->Data; 596 597 WepData->KeyIndex = 0x80000000; 598 WepData->KeyLength = wcslen(sWepKey) >> 1; 599 WepData->Length = FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial) + WepData->KeyLength; 600 601 /* Assemble the hex key */ 602 i = 0; 603 while (sWepKey[i << 1] != '\0') 604 { 605 WepData->KeyMaterial[i] = CharToHex(sWepKey[i << 1]) << 4; 606 WepData->KeyMaterial[i] |= CharToHex(sWepKey[(i << 1) + 1]); 607 i++; 608 } 609 610 bSuccess = DeviceIoControl(hAdapter, 611 IOCTL_NDISUIO_SET_OID_VALUE, 612 SetOid, 613 SetOidSize, 614 NULL, 615 0, 616 &dwBytesReturned, 617 NULL); 618 if (!bSuccess) 619 { 620 HeapFree(GetProcessHeap(), 0, SetOid); 621 return FALSE; 622 } 623 } 624 625 /* Set the encryption status */ 626 SetOid->Oid = OID_802_11_WEP_STATUS; 627 *(PULONG)SetOid->Data = sWepKey ? Ndis802_11WEPEnabled : Ndis802_11WEPDisabled; 628 629 bSuccess = DeviceIoControl(hAdapter, 630 IOCTL_NDISUIO_SET_OID_VALUE, 631 SetOid, 632 SetOidSize, 633 NULL, 634 0, 635 &dwBytesReturned, 636 NULL); 637 if (!bSuccess) 638 { 639 HeapFree(GetProcessHeap(), 0, SetOid); 640 return FALSE; 641 } 642 643 HeapFree(GetProcessHeap(), 0, SetOid); 644 SetOidSize = FIELD_OFFSET(NDISUIO_SET_OID, Data) + sizeof(NDIS_802_11_MAC_ADDRESS); 645 SetOid = HeapAlloc(GetProcessHeap(), 0, SetOidSize); 646 if (!SetOid) 647 return FALSE; 648 649 /* Set the BSSID */ 650 SetOid->Oid = OID_802_11_BSSID; 651 RtlFillMemory(SetOid->Data, sizeof(NDIS_802_11_MAC_ADDRESS), 0xFF); 652 653 bSuccess = DeviceIoControl(hAdapter, 654 IOCTL_NDISUIO_SET_OID_VALUE, 655 SetOid, 656 SetOidSize, 657 NULL, 658 0, 659 &dwBytesReturned, 660 NULL); 661 if (!bSuccess) 662 { 663 HeapFree(GetProcessHeap(), 0, SetOid); 664 return FALSE; 665 } 666 667 HeapFree(GetProcessHeap(), 0, SetOid); 668 SetOidSize = FIELD_OFFSET(NDISUIO_SET_OID, Data) + sizeof(NDIS_802_11_SSID); 669 SetOid = HeapAlloc(GetProcessHeap(), 0, SetOidSize); 670 if (!SetOid) 671 return FALSE; 672 673 /* Finally, set the SSID */ 674 SetOid->Oid = OID_802_11_SSID; 675 Ssid = (PNDIS_802_11_SSID)SetOid->Data; 676 677 snprintf(SsidBuffer, sizeof(SsidBuffer), "%S", sSsid); 678 RtlCopyMemory(Ssid->Ssid, SsidBuffer, strlen(SsidBuffer)); 679 Ssid->SsidLength = strlen(SsidBuffer); 680 681 bSuccess = DeviceIoControl(hAdapter, 682 IOCTL_NDISUIO_SET_OID_VALUE, 683 SetOid, 684 SetOidSize, 685 NULL, 686 0, 687 &dwBytesReturned, 688 NULL); 689 690 HeapFree(GetProcessHeap(), 0, SetOid); 691 692 if (!bSuccess) 693 return FALSE; 694 695 ConResPuts(StdOut, IDS_SUCCESS); 696 return TRUE; 697 } 698 699 BOOL 700 WlanScan(HANDLE hAdapter) 701 { 702 BOOL bSuccess; 703 DWORD dwBytesReturned; 704 NDISUIO_SET_OID SetOid; 705 PNDISUIO_QUERY_OID QueryOid; 706 DWORD QueryOidSize; 707 PNDIS_802_11_BSSID_LIST BssidList; 708 DWORD i, j; 709 DWORD dwNetworkCount; 710 WCHAR szMsgBuf[128]; 711 712 SetOid.Oid = OID_802_11_BSSID_LIST_SCAN; 713 714 /* Send the scan OID */ 715 bSuccess = DeviceIoControl(hAdapter, 716 IOCTL_NDISUIO_SET_OID_VALUE, 717 &SetOid, 718 FIELD_OFFSET(NDISUIO_SET_OID, Data), 719 NULL, 720 0, 721 &dwBytesReturned, 722 NULL); 723 if (!bSuccess) 724 return FALSE; 725 726 /* Wait 2 seconds for the scan to return some results */ 727 Sleep(2000); 728 729 /* Allocate space for 10 networks to be returned initially */ 730 QueryOid = NULL; 731 dwNetworkCount = 10; 732 for (;;) 733 { 734 if (QueryOid) 735 HeapFree(GetProcessHeap(), 0, QueryOid); 736 737 QueryOidSize = sizeof(NDISUIO_QUERY_OID) + (sizeof(NDIS_WLAN_BSSID) * dwNetworkCount); 738 QueryOid = HeapAlloc(GetProcessHeap(), 0, QueryOidSize); 739 if (!QueryOid) 740 return FALSE; 741 742 QueryOid->Oid = OID_802_11_BSSID_LIST; 743 BssidList = (PNDIS_802_11_BSSID_LIST)QueryOid->Data; 744 745 bSuccess = DeviceIoControl(hAdapter, 746 IOCTL_NDISUIO_QUERY_OID_VALUE, 747 QueryOid, 748 QueryOidSize, 749 QueryOid, 750 QueryOidSize, 751 &dwBytesReturned, 752 NULL); 753 if (!bSuccess && GetLastError() == ERROR_INSUFFICIENT_BUFFER) 754 { 755 /* Try allocating space for 10 more networks */ 756 dwNetworkCount += 10; 757 } 758 else 759 { 760 break; 761 } 762 } 763 764 if (!bSuccess) 765 { 766 HeapFree(GetProcessHeap(), 0, QueryOid); 767 return FALSE; 768 } 769 770 if (BssidList->NumberOfItems == 0) 771 { 772 ConResPuts(StdOut, IDS_NO_NETWORK); 773 } 774 else 775 { 776 PNDIS_WLAN_BSSID BssidInfo = BssidList->Bssid; 777 for (i = 0; i < BssidList->NumberOfItems; i++) 778 { 779 PNDIS_802_11_SSID Ssid = &BssidInfo->Ssid; 780 NDIS_802_11_RSSI Rssi = BssidInfo->Rssi; 781 NDIS_802_11_NETWORK_INFRASTRUCTURE NetworkType = BssidInfo->InfrastructureMode; 782 CHAR SsidBuffer[NDIS_802_11_LENGTH_SSID + 1]; 783 UINT Rate; 784 785 /* SSID member is a non-null terminated ASCII string */ 786 RtlCopyMemory(SsidBuffer, Ssid->Ssid, Ssid->SsidLength); 787 SsidBuffer[Ssid->SsidLength] = 0; 788 789 printf("\nSSID: %s\n", SsidBuffer); 790 791 printf("BSSID: "); 792 for (j = 0; j < sizeof(NDIS_802_11_MAC_ADDRESS); j++) 793 { 794 UINT BssidData = BssidInfo->MacAddress[j]; 795 796 printf("%.2x", BssidData); 797 798 if (j != sizeof(NDIS_802_11_MAC_ADDRESS) - 1) 799 printf(":"); 800 } 801 printf("\n"); 802 803 K32LoadStringW(GetModuleHandle(NULL), 804 BssidInfo->Privacy == 0 ? IDS_NO : IDS_YES, 805 szMsgBuf, 806 ARRAYSIZE(szMsgBuf)); 807 ConResPrintf(StdOut, IDS_MSG_ENCRYPTED, szMsgBuf); 808 K32LoadStringW(GetModuleHandle(NULL), 809 NetworkType == Ndis802_11IBSS ? IDS_ADHOC : IDS_INFRASTRUCTURE, 810 szMsgBuf, 811 ARRAYSIZE(szMsgBuf)); 812 ConResPrintf(StdOut, IDS_MSG_NETWORK_TYPE, szMsgBuf); 813 ConResPrintf(StdOut, IDS_MSG_RSSI, (int)Rssi); 814 ConResPuts(StdOut, IDS_MSG_SUPPORT_RATE); 815 816 for (j = 0; j < NDIS_802_11_LENGTH_RATES; j++) 817 { 818 Rate = BssidInfo->SupportedRates[j]; 819 if (Rate != 0) 820 { 821 /* Bit 7 is the basic rates bit */ 822 Rate = Rate & 0x7F; 823 824 /* SupportedRates are in units of .5 */ 825 if (Rate & 0x01) 826 { 827 /* Bit 0 is set so we need to add 0.5 */ 828 printf("%u.5 ", (Rate >> 1)); 829 } 830 else 831 { 832 /* Bit 0 is clear so just print the conversion */ 833 printf("%u ", (Rate >> 1)); 834 } 835 } 836 } 837 printf("\n"); 838 839 /* Move to the next entry */ 840 BssidInfo = (PNDIS_WLAN_BSSID)((PUCHAR)BssidInfo + BssidInfo->Length); 841 } 842 } 843 844 HeapFree(GetProcessHeap(), 0, QueryOid); 845 846 return bSuccess; 847 } 848 849 BOOL ParseCmdline(int argc, WCHAR *argv[]) 850 { 851 INT i; 852 853 for (i = 1; i < argc; i++) 854 { 855 if (argv[i][0] == L'-') 856 { 857 switch (argv[i][1]) 858 { 859 case L's': 860 bScan = TRUE; 861 break; 862 case L'd': 863 bDisconnect = TRUE; 864 break; 865 case L'c': 866 if (i == argc - 1) 867 { 868 ConResPuts(StdOut, IDS_USAGE); 869 return FALSE; 870 } 871 bConnect = TRUE; 872 sSsid = argv[++i]; 873 break; 874 case L'w': 875 if (i == argc - 1) 876 { 877 ConResPuts(StdOut, IDS_USAGE); 878 return FALSE; 879 } 880 sWepKey = argv[++i]; 881 break; 882 case L'a': 883 bAdhoc = TRUE; 884 break; 885 default : 886 ConResPuts(StdOut, IDS_USAGE); 887 return FALSE; 888 } 889 890 } 891 else 892 { 893 ConResPuts(StdOut, IDS_USAGE); 894 return FALSE; 895 } 896 } 897 898 return TRUE; 899 } 900 901 int wmain(int argc, WCHAR *argv[]) 902 { 903 HANDLE hAdapter; 904 IP_ADAPTER_INDEX_MAP IpInfo; 905 906 /* Initialize the Console Standard Streams */ 907 ConInitStdStreams(); 908 909 if (!ParseCmdline(argc, argv)) 910 return -1; 911 912 if (!OpenWlanAdapter(&hAdapter, &IpInfo)) 913 { 914 ConResPuts(StdOut, IDS_NO_WLAN_ADAPTER); 915 return -1; 916 } 917 918 if (bScan) 919 { 920 if (!WlanScan(hAdapter)) 921 { 922 DoFormatMessage(GetLastError()); 923 CloseHandle(hAdapter); 924 return -1; 925 } 926 } 927 else if (bDisconnect) 928 { 929 if (!WlanDisconnect(hAdapter, &IpInfo)) 930 { 931 DoFormatMessage(GetLastError()); 932 CloseHandle(hAdapter); 933 return -1; 934 } 935 } 936 else if (bConnect) 937 { 938 if (!WlanConnect(hAdapter)) 939 { 940 DoFormatMessage(GetLastError()); 941 CloseHandle(hAdapter); 942 return -1; 943 } 944 } 945 else 946 { 947 if (!WlanPrintCurrentStatus(hAdapter)) 948 { 949 DoFormatMessage(GetLastError()); 950 CloseHandle(hAdapter); 951 return -1; 952 } 953 } 954 955 CloseHandle(hAdapter); 956 return 0; 957 } 958