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 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 
     35 AddInterface::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 
     62 void 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
    108 bool 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 
    188 void 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