Updated through tag hostap_2_5 from git://w1.fi/hostap.git
[mech_eap.git] / libeap / wpa_supplicant / wpa_gui-qt4 / addinterface.cpp
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
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 }