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