1/* 2 * wpa_gui - AddInterface class 3 * Copyright (c) 2008, Jouni Malinen <j@w1.fi> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15#include <cstdio> 16#include "wpa_ctrl.h" 17 18#include <QMessageBox> 19 20#include "wpagui.h" 21#include "addinterface.h" 22 23#ifdef CONFIG_NATIVE_WINDOWS 24#include <windows.h> 25 26#ifndef WPA_KEY_ROOT 27#define WPA_KEY_ROOT HKEY_LOCAL_MACHINE 28#endif 29#ifndef WPA_KEY_PREFIX 30#define WPA_KEY_PREFIX TEXT("SOFTWARE\\wpa_supplicant") 31#endif 32#endif /* CONFIG_NATIVE_WINDOWS */ 33 34 35AddInterface::AddInterface(WpaGui *_wpagui, QWidget *parent) 36 : QDialog(parent), wpagui(_wpagui) 37{ 38 setWindowTitle("Select network interface to add"); 39 resize(400, 200); 40 vboxLayout = new QVBoxLayout(this); 41 42 interfaceWidget = new QTreeWidget(this); 43 interfaceWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); 44 interfaceWidget->setUniformRowHeights(true); 45 interfaceWidget->setSortingEnabled(true); 46 interfaceWidget->setColumnCount(3); 47 interfaceWidget->headerItem()->setText(0, "driver"); 48 interfaceWidget->headerItem()->setText(1, "interface"); 49 interfaceWidget->headerItem()->setText(2, "description"); 50 interfaceWidget->setItemsExpandable(FALSE); 51 interfaceWidget->setRootIsDecorated(FALSE); 52 vboxLayout->addWidget(interfaceWidget); 53 54 connect(interfaceWidget, 55 SIGNAL(itemActivated(QTreeWidgetItem *, int)), this, 56 SLOT(interfaceSelected(QTreeWidgetItem *))); 57 58 addInterfaces(); 59} 60 61 62void AddInterface::addInterfaces() 63{ 64#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE 65 struct wpa_ctrl *ctrl; 66 int ret; 67 char buf[2048]; 68 size_t len; 69 70 ctrl = wpa_ctrl_open(NULL); 71 if (ctrl == NULL) 72 return; 73 74 len = sizeof(buf) - 1; 75 ret = wpa_ctrl_request(ctrl, "INTERFACE_LIST", 14, buf, &len, NULL); 76 if (ret < 0) { 77 wpa_ctrl_close(ctrl); 78 return; 79 } 80 buf[len] = '\0'; 81 82 wpa_ctrl_close(ctrl); 83 84 QString ifaces(buf); 85 QStringList lines = ifaces.split(QRegExp("\\n")); 86 for (QStringList::Iterator it = lines.begin(); 87 it != lines.end(); it++) { 88 QStringList arg = (*it).split(QChar('\t')); 89 if (arg.size() < 3) 90 continue; 91 QTreeWidgetItem *item = new QTreeWidgetItem(interfaceWidget); 92 if (!item) 93 break; 94 95 item->setText(0, arg[0]); 96 item->setText(1, arg[1]); 97 item->setText(2, arg[2]); 98 } 99 100 interfaceWidget->resizeColumnToContents(0); 101 interfaceWidget->resizeColumnToContents(1); 102 interfaceWidget->resizeColumnToContents(2); 103#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 104} 105 106 107#ifdef CONFIG_NATIVE_WINDOWS 108bool AddInterface::addRegistryInterface(const QString &ifname) 109{ 110 HKEY hk, ihk; 111 LONG ret; 112 int id, tmp; 113 TCHAR name[10]; 114 DWORD val, i; 115 116 ret = RegOpenKeyEx(WPA_KEY_ROOT, WPA_KEY_PREFIX TEXT("\\interfaces"), 117 0, KEY_ENUMERATE_SUB_KEYS | KEY_CREATE_SUB_KEY, 118 &hk); 119 if (ret != ERROR_SUCCESS) 120 return false; 121 122 id = -1; 123 124 for (i = 0; ; i++) { 125 TCHAR name[255]; 126 DWORD namelen; 127 128 namelen = 255; 129 ret = RegEnumKeyEx(hk, i, name, &namelen, NULL, NULL, NULL, 130 NULL); 131 132 if (ret == ERROR_NO_MORE_ITEMS) 133 break; 134 135 if (ret != ERROR_SUCCESS) 136 break; 137 138 if (namelen >= 255) 139 namelen = 255 - 1; 140 name[namelen] = '\0'; 141 142#ifdef UNICODE 143 QString s((QChar *) name, namelen); 144#else /* UNICODE */ 145 QString s(name); 146#endif /* UNICODE */ 147 tmp = s.toInt(); 148 if (tmp > id) 149 id = tmp; 150 } 151 152 id += 1; 153 154#ifdef UNICODE 155 wsprintf(name, L"%04d", id); 156#else /* UNICODE */ 157 os_snprintf(name, sizeof(name), "%04d", id); 158#endif /* UNICODE */ 159 ret = RegCreateKeyEx(hk, name, 0, NULL, 0, KEY_WRITE, NULL, &ihk, 160 NULL); 161 RegCloseKey(hk); 162 if (ret != ERROR_SUCCESS) 163 return false; 164 165#ifdef UNICODE 166 RegSetValueEx(ihk, TEXT("adapter"), 0, REG_SZ, 167 (LPBYTE) ifname.unicode(), 168 (ifname.length() + 1) * sizeof(TCHAR)); 169 170#else /* UNICODE */ 171 RegSetValueEx(ihk, TEXT("adapter"), 0, REG_SZ, 172 (LPBYTE) ifname.toLocal8Bit(), ifname.length() + 1); 173#endif /* UNICODE */ 174 RegSetValueEx(ihk, TEXT("config"), 0, REG_SZ, 175 (LPBYTE) TEXT("default"), 8 * sizeof(TCHAR)); 176 RegSetValueEx(ihk, TEXT("ctrl_interface"), 0, REG_SZ, 177 (LPBYTE) TEXT(""), 1 * sizeof(TCHAR)); 178 val = 1; 179 RegSetValueEx(ihk, TEXT("skip_on_error"), 0, REG_DWORD, (LPBYTE) &val, 180 sizeof(val)); 181 182 RegCloseKey(ihk); 183 return true; 184} 185#endif /* CONFIG_NATIVE_WINDOWS */ 186 187 188void AddInterface::interfaceSelected(QTreeWidgetItem *sel) 189{ 190 if (!sel) 191 return; 192 193#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE 194 struct wpa_ctrl *ctrl; 195 int ret; 196 char buf[20], cmd[256]; 197 size_t len; 198 199 /* 200 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB 201 * <driver_param>TAB<bridge_name> 202 */ 203 snprintf(cmd, sizeof(cmd), 204 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s", 205 sel->text(1).toAscii().constData(), 206 "default", 207 sel->text(0).toAscii().constData(), 208 "yes", "", ""); 209 cmd[sizeof(cmd) - 1] = '\0'; 210 211 ctrl = wpa_ctrl_open(NULL); 212 if (ctrl == NULL) 213 return; 214 215 len = sizeof(buf) - 1; 216 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, NULL); 217 wpa_ctrl_close(ctrl); 218 219 if (ret < 0) { 220 QMessageBox::warning(this, "wpa_gui", 221 "Add interface command could not be " 222 "completed."); 223 return; 224 } 225 226 buf[len] = '\0'; 227 if (buf[0] != 'O' || buf[1] != 'K') { 228 QMessageBox::warning(this, "wpa_gui", 229 "Failed to add the interface."); 230 return; 231 } 232 233#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 234 235#ifdef CONFIG_NATIVE_WINDOWS 236 if (!addRegistryInterface(sel->text(1))) { 237 QMessageBox::information(this, "wpa_gui", 238 "Failed to add the interface into " 239 "registry."); 240 } 241#endif /* CONFIG_NATIVE_WINDOWS */ 242 243 wpagui->selectAdapter(sel->text(1)); 244 close(); 245} 246