[WLANCONF]
authorCameron Gutman <aicommander@gmail.com>
Sun, 8 Jan 2012 03:02:58 +0000 (03:02 +0000)
committerCameron Gutman <aicommander@gmail.com>
Sun, 8 Jan 2012 03:02:58 +0000 (03:02 +0000)
- Initial drop of a little WLAN configuration tool to use until WZC is implemented and working
- Doesn't build yet due to missing OID definitions
- Some of this code will eventually be reused when implementing WZC

svn path=/branches/wlan-bringup/; revision=54869

base/applications/network/CMakeLists.txt
base/applications/network/network.rbuild
base/applications/network/wlanconf/CMakeLists.txt [new file with mode: 0644]
base/applications/network/wlanconf/wlanconf.c [new file with mode: 0644]
base/applications/network/wlanconf/wlanconf.rbuild [new file with mode: 0644]
base/applications/network/wlanconf/wlanconf.rc [new file with mode: 0644]

index 02eb61d..b7f2d0e 100644 (file)
@@ -14,3 +14,5 @@ if(NOT MSVC)
 endif()
 add_subdirectory(tracert)
 add_subdirectory(whois)
+add_subdirectory(wlanconf)
+
index 61109ec..13b9a53 100644 (file)
@@ -40,4 +40,7 @@
        <directory name="whois">
                <xi:include href="whois/whois.rbuild" />
        </directory>
+       <directory name="wlanconf">
+               <xi:include href="wlanconf/wlanconf.rbuild" />
+       </directory>
 </group>
diff --git a/base/applications/network/wlanconf/CMakeLists.txt b/base/applications/network/wlanconf/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b3de531
--- /dev/null
@@ -0,0 +1,8 @@
+
+include_directories(
+    BEFORE include
+    ${REACTOS_SOURCE_DIR}/include/reactos/drivers/ndisuio)
+add_executable(wlanconf wlanconf.c wlanconf.rc)
+set_module_type(wlanconf win32cui)
+add_importlibs(wlanconf kernel32)
+add_cd_file(TARGET wlanconf DESTINATION reactos/system32 FOR all)
diff --git a/base/applications/network/wlanconf/wlanconf.c b/base/applications/network/wlanconf/wlanconf.c
new file mode 100644 (file)
index 0000000..9f4a18b
--- /dev/null
@@ -0,0 +1,430 @@
+/*
+ * PROJECT:     ReactOS WLAN command-line configuration utility
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        base/applications/network/wlanconf/wlanconf.c
+ * PURPOSE:     Allows WLAN configuration via the command prompt
+ * COPYRIGHT:   Copyright 2012 Cameron Gutman (cameron.gutman@reactos.org)
+ */
+
+#include <windows.h>
+#include <tchar.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ntddndis.h>
+#include <nuiouser.h>
+
+BOOL bScan = FALSE;
+
+BOOL bConnect = FALSE;
+char* sSsid = NULL;
+
+BOOL bDisconnect = FALSE;
+
+DWORD DoFormatMessage(DWORD ErrorCode)
+{
+    LPVOID lpMsgBuf;
+    DWORD RetVal;
+
+    if ((RetVal = FormatMessage(
+            FORMAT_MESSAGE_ALLOCATE_BUFFER |
+            FORMAT_MESSAGE_FROM_SYSTEM |
+            FORMAT_MESSAGE_IGNORE_INSERTS,
+            NULL,
+            ErrorCode,
+            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
+            (LPTSTR) &lpMsgBuf,
+            0,
+            NULL )))
+    {
+        _tprintf(_T("%s"), (LPTSTR)lpMsgBuf);
+
+        LocalFree(lpMsgBuf);
+
+        /* return number of TCHAR's stored in output buffer
+         * excluding '\0' - as FormatMessage does*/
+        return RetVal;
+    }
+    else
+        return 0;
+}
+
+HANDLE
+OpenDriverHandle(VOID)
+{
+    HANDLE hDriver;
+    DWORD dwBytesReturned;
+    BOOL bSuccess;
+
+    /* Open a handle to this NDISUIO driver */
+    hDriver = CreateFileW(NDISUIO_DEVICE_NAME,
+                          GENERIC_READ | GENERIC_WRITE,
+                          0,
+                          NULL,
+                          OPEN_EXISTING,
+                          FILE_ATTRIBUTE_NORMAL,
+                          NULL);
+    if (hDriver == INVALID_HANDLE_VALUE)
+        return INVALID_HANDLE_VALUE;
+    
+    /* Wait for binds */
+    bSuccess = DeviceIoControl(hDriver,
+                               IOCTL_NDISUIO_BIND_WAIT,
+                               NULL,
+                               0,
+                               NULL,
+                               0,
+                               &dwBytesReturned,
+                               NULL);
+    if (!bSuccess)
+    {
+        CloseHandle(hDriver);
+        return INVALID_HANDLE_VALUE;
+    }
+    
+    return hDriver;
+}
+
+BOOL
+IsWlanAdapter(HANDLE hAdapter)
+{
+    BOOL bSuccess;
+    DWORD dwBytesReturned;
+    NDISUIO_QUERY_OID QueryOid;
+
+    /* NDIS 5.1 WLAN drivers must support this OID */
+    QueryOid.Oid = OID_GEN_PHYSICAL_MEDIUM;
+
+    bSuccess = DeviceIoControl(hAdapter,
+                               IOCTL_NDISUIO_QUERY_OID_VALUE,
+                               &QueryOid,
+                               sizeof(QueryOid),
+                               &QueryOid,
+                               sizeof(QueryOid),
+                               &dwBytesReturned,
+                               NULL);
+    if (!bSuccess || *(PULONG)QueryOid.Data != NdisPhysicalMediumWirelessLan)
+        return FALSE;
+
+    return TRUE;
+}
+
+HANDLE
+OpenAdapterHandle(DWORD Index)
+{
+    HANDLE hDriver;
+    BOOL bSuccess;
+    DWORD dwBytesReturned;
+    char Buffer[1024];
+    PNDISUIO_QUERY_BINDING QueryBinding = (PNDISUIO_QUERY_BINDING)Buffer;
+    
+    /* Open the driver handle */
+    hDriver = OpenDriverHandle();
+    if (hDriver == INVALID_HANDLE_VALUE)
+        return INVALID_HANDLE_VALUE;
+
+    /* Query for bindable adapters */
+    QueryBinding->BindingIndex = 0;
+    do {
+        bSuccess = DeviceIoControl(hDriver,
+                                   IOCTL_NDISUIO_QUERY_BINDING,
+                                   NULL,
+                                   0,
+                                   NULL,
+                                   0,
+                                   &dwBytesReturned,
+                                   NULL);
+        if (QueryBinding->BindingIndex == Index)
+            break;
+        QueryBinding->BindingIndex++;
+    } while (bSuccess);
+
+    if (!bSuccess)
+    {
+        CloseHandle(hDriver);
+        return INVALID_HANDLE_VALUE;
+    }
+    
+    /* Bind to the adapter */
+    bSuccess = DeviceIoControl(hDriver,
+                               IOCTL_NDISUIO_OPEN_DEVICE,
+                               (PUCHAR)QueryBinding + QueryBinding->DeviceNameOffset,
+                               QueryBinding->DeviceNameLength,
+                               NULL,
+                               0,
+                               &dwBytesReturned,
+                               NULL);
+    if (!bSuccess)
+    {
+        CloseHandle(hDriver);
+        return INVALID_HANDLE_VALUE;
+    }
+    
+    return hDriver;
+}
+
+/* Only works with the first adapter for now */
+HANDLE
+OpenWlanAdapter(VOID)
+{
+    DWORD dwCurrentIndex;
+    HANDLE hCurrentAdapter;
+
+    for (dwCurrentIndex = 0; ; dwCurrentIndex++)
+    {
+        hCurrentAdapter = OpenAdapterHandle(dwCurrentIndex);
+        if (hCurrentAdapter == INVALID_HANDLE_VALUE)
+            break;
+        
+        if (IsWlanAdapter(hCurrentAdapter))
+            return hCurrentAdapter;
+        else
+            CloseHandle(hCurrentAdapter);
+    }
+
+    return INVALID_HANDLE_VALUE;
+}
+
+BOOL
+WlanDisconnect(HANDLE hAdapter)
+{
+    BOOL bSuccess;
+    DWORD dwBytesReturned;
+    NDISUIO_SET_OID SetOid;
+    
+    SetOid.Oid = OID_802_11_DISASSOCIATE;
+    
+    bSuccess = DeviceIoControl(hAdapter,
+                               IOCTL_NDISUIO_SET_OID_VALUE,
+                               &SetOid,
+                               sizeof(SetOid),
+                               NULL,
+                               0,
+                               &dwBytesReturned,
+                               NULL);
+
+    return bSuccess;
+}
+
+BOOL
+WlanConnect(HANDLE hAdapter)
+{
+    BOOL bSuccess;
+    DWORD dwBytesReturned;
+    PNDISUIO_SET_OID SetOid;
+    PNDIS_802_11_SSID Ssid;
+
+    SetOid = HeapAlloc(GetProcessHeap(), 0, sizeof(NDISUIO_SET_OID) + sizeof(NDIS_802_11_SSID));
+    if (!SetOid)
+        return FALSE;
+
+    SetOid->Oid = OID_802_11_SSID;
+    Ssid = SetOid->Data;
+    
+    /* Fill the OID data buffer */
+    RtlCopyMemory(Ssid->Ssid, sSsid, strlen(sSsid));
+    Ssid->SsidLength = strlen(sSsid);
+    
+    bSuccess = DeviceIoControl(hAdapter,
+                               IOCTL_NDISUIO_SET_OID_VALUE,
+                               &SetOid,
+                               sizeof(SetOid),
+                               NULL,
+                               0,
+                               &dwBytesReturned,
+                               NULL);
+    
+    HeapFree(GetProcessHeap(), 0, SetOid);
+    
+    return bSuccess;
+}
+
+BOOL
+WlanScan(HANDLE hAdapter)
+{
+    BOOL bSuccess;
+    DWORD dwBytesReturned;
+    NDISUIO_SET_OID SetOid;
+    PNDISUIO_QUERY_OID QueryOid;
+    DWORD QueryOidSize;
+    PNDIS_802_11_BSSID_LIST_EX BssidList;
+    DWORD i, j;
+
+    SetOid.Oid = OID_802_11_BSSID_LIST_SCAN;
+    
+    /* Send the scan OID */
+    bSuccess = DeviceIoControl(hAdapter,
+                               IOCTL_NDISUIO_SET_OID_VALUE,
+                               &SetOid,
+                               sizeof(SetOid),
+                               NULL,
+                               0,
+                               &dwBytesReturned,
+                               NULL);
+    if (!bSuccess)
+        return FALSE;
+    
+    /* Allocate space for 15 networks to be returned */
+    QueryOidSize = sizeof(NDISUIO_QUERY_OID) + (sizeof(NDIS_WLAN_BSSID_EX) * 15);
+    QueryOid = HeapAlloc(GetProcessHeap(), 0, QueryOidSize);
+    if (!QueryOid)
+        return FALSE;
+    
+    QueryOid->Oid = OID_802_11_BSSID_LIST;
+    BssidList = QueryOid->Data;
+
+    bSuccess = DeviceIoControl(hAdapter,
+                               IOCTL_NDISUIO_QUERY_OID_VALUE,
+                               QueryOid,
+                               QueryOidSize,
+                               QueryOid,
+                               QueryOidSize,
+                               &dwBytesReturned,
+                               NULL);
+    if (!bSuccess)
+    {
+        HeapFree(GetProcessHeap(), 0, QueryOid);
+        return FALSE;
+    }
+
+    if (BssidList->NumberOfItems == 0)
+    {
+        _tprintf(_T("No networks found in range\n"));
+    }
+    else
+    {
+        for (i = 0; i < BssidList->NumberOfItems; i++)
+        {
+            PNDIS_WLAN_BSSID_EX BssidInfo = BssidList->Bssid[i];
+            PNDIS_802_11_SSID Ssid = &BssidInfo->Ssid;
+            UCHAR SupportedRates[16] = &BssidInfo->SupportedRates;
+            NDIS_802_11_RSSI Rssi = BssidInfo->Rssi;
+            NDIS_802_11_NETWORK_INFRASTRUCTURE NetworkType = BssidInfo->InfrastructureMode;
+            CHAR SsidBuffer[33];
+
+            /* SSID member is a non-null terminated ASCII string */
+            RtlCopyMemory(SsidBuffer, Ssid->Ssid, Ssid->SsidLength);
+            SsidBuffer[Ssid->SsidLength] = 0;
+            
+            _tprintf(_T("\nSSID: %s\n"
+                        "Encrypted: %s"
+                        "Network Type: %s\n"
+                        "RSSI: %i\n"
+                        "Supported Rates: "),
+                        SsidBuffer,
+                        BssidInfo->Privacy == 0 ? "No" : "Yes",
+                        NetworkType == Ndis802_11IBSS ? "Adhoc" : "Infrastructure",
+                        (int)Rssi);
+            
+            for (j = 0; j < 16; j++)
+            {
+                if (SupportedRates[j] != 0)
+                {
+                    /* SupportedRates are in units of .5 */
+                    _tprintf(_T("%d "), (SupportedRates[j] << 2));
+                }
+            }
+            _tprintf(_T("\n"));
+        }
+    }
+    
+    HeapFree(GetProcessHeap(), 0, QueryOid);
+    
+    return bSuccess;
+}
+
+VOID Usage()
+{
+    _tprintf(_T("\nConfigures a WLAN adapter.\n\n"
+    "WLANCONF [-c SSID] [-d] [-s]\n\n"
+    "  -c SSID       Connects to a supplied SSID.\n"
+    "  -d            Disconnects from the current AP.\n"
+    "  -s            Scans and displays a list of access points in range.\n"));
+}
+
+
+BOOL ParseCmdline(int argc, char* argv[])
+{
+    INT i;
+    
+    for (i = 1; i < argc; i++)
+    {
+        if ((argc > 1) && (argv[i][0] == '-'))
+        {
+            TCHAR c;
+            
+            while ((c = *++argv[i]) != '\0')
+            {
+                switch (c)
+                {
+                    case 's' :
+                        bScan = TRUE;
+                        break;
+                    case 'd' :
+                        bDisconnect = TRUE;
+                        break;
+                    case 'c' :
+                        bConnect = TRUE;
+                        sSsid = argv[++i];
+                        break;
+                    default :
+                        Usage();
+                        return FALSE;
+                }
+            }
+        }
+    }
+
+    if (!bScan && !bDisconnect && !bConnect)
+    {
+        Usage();
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+int main(int argc, char* argv[])
+{
+    HANDLE hAdapter;
+
+    if (!ParseCmdline(argc, argv))
+        return -1;
+    
+    hAdapter = OpenWlanAdapter();
+    if (hAdapter == INVALID_HANDLE_VALUE)
+    {
+        DoFormatMessage(GetLastError());
+        return -1;
+    }
+    
+    if (bScan)
+    {
+        if (!WlanScan(hAdapter))
+        {
+            DoFormatMessage(GetLastError());
+            CloseHandle(hAdapter);
+            return -1;
+        }
+    }
+    else if (bDisconnect)
+    {
+        if (!WlanDisconnect(hAdapter))
+        {
+            DoFormatMessage(GetLastError());
+            CloseHandle(hAdapter);
+            return -1;
+        }
+    }
+    else
+    {
+        if (!WlanConnect(hAdapter))
+        {
+            DoFormatMessage(GetLastError());
+            CloseHandle(hAdapter);
+            return -1;
+        }
+    }
+
+    CloseHandle(hAdapter);
+    return 0;
+}
diff --git a/base/applications/network/wlanconf/wlanconf.rbuild b/base/applications/network/wlanconf/wlanconf.rbuild
new file mode 100644 (file)
index 0000000..6a0d727
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<!DOCTYPE module SYSTEM "../../../../tools/rbuild/project.dtd">
+<module name="wlanconf" type="win32cui" installbase="system32" installname="wlanconf.exe">
+       <include base="wlanconf">.</include>
+       <include base="ReactOS">include/reactos/drivers/ndisuio</include>
+       <file>wlanconf.c</file>
+       <file>wlanconf.rc</file>
+</module>
diff --git a/base/applications/network/wlanconf/wlanconf.rc b/base/applications/network/wlanconf/wlanconf.rc
new file mode 100644 (file)
index 0000000..78b2584
--- /dev/null
@@ -0,0 +1,7 @@
+#define REACTOS_STR_FILE_DESCRIPTION    "ReactOS WLAN Configuration Tool\0"
+#define REACTOS_STR_INTERNAL_NAME   "wlanconf\0"
+#define REACTOS_STR_ORIGINAL_FILENAME   "wlanconf.exe\0"
+#define REACTOS_STR_ORIGINAL_COPYRIGHT  "Cameron Gutman (cameron.gutman@reactos.org)\0"
+#include <reactos/version.rc>
+
+