1 /*
2 * wpa_gui - AddInterface class
3 * Copyright (c) 2008, Jouni Malinen <j@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
AddInterface(WpaGui * _wpagui,QWidget * parent)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
addInterfaces()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
addRegistryInterface(const QString & ifname)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
interfaceSelected(QTreeWidgetItem * sel)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