1734 lines
		
	
	
	
		
			39 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1734 lines
		
	
	
	
		
			39 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * wpa_gui - WpaGui class
 | |
|  * Copyright (c) 2005-2011, Jouni Malinen <j@w1.fi>
 | |
|  *
 | |
|  * This software may be distributed under the terms of the BSD license.
 | |
|  * See README for more details.
 | |
|  */
 | |
| 
 | |
| #ifdef CONFIG_NATIVE_WINDOWS
 | |
| #include <windows.h>
 | |
| #endif /* CONFIG_NATIVE_WINDOWS */
 | |
| 
 | |
| #include <cstdio>
 | |
| #include <unistd.h>
 | |
| #include <QMessageBox>
 | |
| #include <QCloseEvent>
 | |
| #include <QImageReader>
 | |
| #include <QSettings>
 | |
| 
 | |
| #include "wpagui.h"
 | |
| #include "dirent.h"
 | |
| #include "common/wpa_ctrl.h"
 | |
| #include "userdatarequest.h"
 | |
| #include "networkconfig.h"
 | |
| 
 | |
| #if 1
 | |
| /* Silence stdout */
 | |
| #define printf wpagui_printf
 | |
| static int wpagui_printf(const char *, ...)
 | |
| {
 | |
| 	return 0;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| WpaGui::WpaGui(QApplication *_app, QWidget *parent, const char *, Qt::WFlags)
 | |
| 	: QMainWindow(parent), app(_app)
 | |
| {
 | |
| 	setupUi(this);
 | |
| 
 | |
| #ifdef CONFIG_NATIVE_WINDOWS
 | |
| 	fileStopServiceAction = new QAction(this);
 | |
| 	fileStopServiceAction->setObjectName("Stop Service");
 | |
| 	fileStopServiceAction->setIconText(tr("Stop Service"));
 | |
| 	fileMenu->insertAction(actionWPS, fileStopServiceAction);
 | |
| 
 | |
| 	fileStartServiceAction = new QAction(this);
 | |
| 	fileStartServiceAction->setObjectName("Start Service");
 | |
| 	fileStartServiceAction->setIconText(tr("Start Service"));
 | |
| 	fileMenu->insertAction(fileStopServiceAction, fileStartServiceAction);
 | |
| 
 | |
| 	connect(fileStartServiceAction, SIGNAL(triggered()), this,
 | |
| 		SLOT(startService()));
 | |
| 	connect(fileStopServiceAction, SIGNAL(triggered()), this,
 | |
| 		SLOT(stopService()));
 | |
| 
 | |
| 	addInterfaceAction = new QAction(this);
 | |
| 	addInterfaceAction->setIconText(tr("Add Interface"));
 | |
| 	fileMenu->insertAction(fileStartServiceAction, addInterfaceAction);
 | |
| 
 | |
| 	connect(addInterfaceAction, SIGNAL(triggered()), this,
 | |
| 		SLOT(addInterface()));
 | |
| #endif /* CONFIG_NATIVE_WINDOWS */
 | |
| 
 | |
| 	(void) statusBar();
 | |
| 
 | |
| 	/*
 | |
| 	 * Disable WPS tab by default; it will be enabled if wpa_supplicant is
 | |
| 	 * built with WPS support.
 | |
| 	 */
 | |
| 	wpsTab->setEnabled(false);
 | |
| 	wpaguiTab->setTabEnabled(wpaguiTab->indexOf(wpsTab), false);
 | |
| 
 | |
| 	connect(fileEventHistoryAction, SIGNAL(triggered()), this,
 | |
| 		SLOT(eventHistory()));
 | |
| 	connect(fileSaveConfigAction, SIGNAL(triggered()), this,
 | |
| 		SLOT(saveConfig()));
 | |
| 	connect(actionWPS, SIGNAL(triggered()), this, SLOT(wpsDialog()));
 | |
| 	connect(actionPeers, SIGNAL(triggered()), this, SLOT(peersDialog()));
 | |
| 	connect(fileExitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
 | |
| 	connect(networkAddAction, SIGNAL(triggered()), this,
 | |
| 		SLOT(addNetwork()));
 | |
| 	connect(networkEditAction, SIGNAL(triggered()), this,
 | |
| 		SLOT(editSelectedNetwork()));
 | |
| 	connect(networkRemoveAction, SIGNAL(triggered()), this,
 | |
| 		SLOT(removeSelectedNetwork()));
 | |
| 	connect(networkEnableAllAction, SIGNAL(triggered()), this,
 | |
| 		SLOT(enableAllNetworks()));
 | |
| 	connect(networkDisableAllAction, SIGNAL(triggered()), this,
 | |
| 		SLOT(disableAllNetworks()));
 | |
| 	connect(networkRemoveAllAction, SIGNAL(triggered()), this,
 | |
| 		SLOT(removeAllNetworks()));
 | |
| 	connect(helpIndexAction, SIGNAL(triggered()), this, SLOT(helpIndex()));
 | |
| 	connect(helpContentsAction, SIGNAL(triggered()), this,
 | |
| 		SLOT(helpContents()));
 | |
| 	connect(helpAboutAction, SIGNAL(triggered()), this, SLOT(helpAbout()));
 | |
| 	connect(disconnectButton, SIGNAL(clicked()), this, SLOT(disconnect()));
 | |
| 	connect(scanButton, SIGNAL(clicked()), this, SLOT(scan()));
 | |
| 	connect(connectButton, SIGNAL(clicked()), this, SLOT(connectB()));
 | |
| 	connect(adapterSelect, SIGNAL(activated(const QString&)), this,
 | |
| 		SLOT(selectAdapter(const QString&)));
 | |
| 	connect(networkSelect, SIGNAL(activated(const QString&)), this,
 | |
| 		SLOT(selectNetwork(const QString&)));
 | |
| 	connect(addNetworkButton, SIGNAL(clicked()), this, SLOT(addNetwork()));
 | |
| 	connect(editNetworkButton, SIGNAL(clicked()), this,
 | |
| 		SLOT(editListedNetwork()));
 | |
| 	connect(removeNetworkButton, SIGNAL(clicked()), this,
 | |
| 		SLOT(removeListedNetwork()));
 | |
| 	connect(networkList, SIGNAL(itemSelectionChanged()), this,
 | |
| 		SLOT(updateNetworkDisabledStatus()));
 | |
| 	connect(enableRadioButton, SIGNAL(toggled(bool)), this,
 | |
| 		SLOT(enableListedNetwork(bool)));
 | |
| 	connect(disableRadioButton, SIGNAL(toggled(bool)), this,
 | |
| 		SLOT(disableListedNetwork(bool)));
 | |
| 	connect(scanNetworkButton, SIGNAL(clicked()), this, SLOT(scan()));
 | |
| 	connect(networkList, SIGNAL(itemDoubleClicked(QListWidgetItem *)),
 | |
| 		this, SLOT(editListedNetwork()));
 | |
| 	connect(wpaguiTab, SIGNAL(currentChanged(int)), this,
 | |
| 		SLOT(tabChanged(int)));
 | |
| 	connect(wpsPbcButton, SIGNAL(clicked()), this, SLOT(wpsPbc()));
 | |
| 	connect(wpsPinButton, SIGNAL(clicked()), this, SLOT(wpsGeneratePin()));
 | |
| 	connect(wpsApPinEdit, SIGNAL(textChanged(const QString &)), this,
 | |
| 		SLOT(wpsApPinChanged(const QString &)));
 | |
| 	connect(wpsApPinButton, SIGNAL(clicked()), this, SLOT(wpsApPin()));
 | |
| 
 | |
| 	eh = NULL;
 | |
| 	scanres = NULL;
 | |
| 	peers = NULL;
 | |
| 	add_iface = NULL;
 | |
| 	udr = NULL;
 | |
| 	tray_icon = NULL;
 | |
| 	startInTray = false;
 | |
| 	ctrl_iface = NULL;
 | |
| 	ctrl_conn = NULL;
 | |
| 	monitor_conn = NULL;
 | |
| 	msgNotifier = NULL;
 | |
| 	ctrl_iface_dir = strdup("/var/run/wpa_supplicant");
 | |
| 
 | |
| 	parse_argv();
 | |
| 
 | |
| #ifndef QT_NO_SESSIONMANAGER
 | |
| 	if (app->isSessionRestored()) {
 | |
| 		QSettings settings("wpa_supplicant", "wpa_gui");
 | |
| 		settings.beginGroup("state");
 | |
| 		if (app->sessionId().compare(settings.value("session_id").
 | |
| 					     toString()) == 0)
 | |
| 			startInTray = settings.value("in_tray").toBool();
 | |
| 		settings.endGroup();
 | |
| 	}
 | |
| #endif
 | |
| 
 | |
| 	if (QSystemTrayIcon::isSystemTrayAvailable())
 | |
| 		createTrayIcon(startInTray);
 | |
| 	else
 | |
| 		show();
 | |
| 
 | |
| 	connectedToService = false;
 | |
| 	textStatus->setText(tr("connecting to wpa_supplicant"));
 | |
| 	timer = new QTimer(this);
 | |
| 	connect(timer, SIGNAL(timeout()), SLOT(ping()));
 | |
| 	timer->setSingleShot(FALSE);
 | |
| 	timer->start(1000);
 | |
| 
 | |
| 	if (openCtrlConnection(ctrl_iface) < 0) {
 | |
| 		printf("Failed to open control connection to "
 | |
| 		       "wpa_supplicant.\n");
 | |
| 	}
 | |
| 
 | |
| 	updateStatus();
 | |
| 	networkMayHaveChanged = true;
 | |
| 	updateNetworks();
 | |
| }
 | |
| 
 | |
| 
 | |
| WpaGui::~WpaGui()
 | |
| {
 | |
| 	delete msgNotifier;
 | |
| 
 | |
| 	if (monitor_conn) {
 | |
| 		wpa_ctrl_detach(monitor_conn);
 | |
| 		wpa_ctrl_close(monitor_conn);
 | |
| 		monitor_conn = NULL;
 | |
| 	}
 | |
| 	if (ctrl_conn) {
 | |
| 		wpa_ctrl_close(ctrl_conn);
 | |
| 		ctrl_conn = NULL;
 | |
| 	}
 | |
| 
 | |
| 	if (eh) {
 | |
| 		eh->close();
 | |
| 		delete eh;
 | |
| 		eh = NULL;
 | |
| 	}
 | |
| 
 | |
| 	if (scanres) {
 | |
| 		scanres->close();
 | |
| 		delete scanres;
 | |
| 		scanres = NULL;
 | |
| 	}
 | |
| 
 | |
| 	if (peers) {
 | |
| 		peers->close();
 | |
| 		delete peers;
 | |
| 		peers = NULL;
 | |
| 	}
 | |
| 
 | |
| 	if (add_iface) {
 | |
| 		add_iface->close();
 | |
| 		delete add_iface;
 | |
| 		add_iface = NULL;
 | |
| 	}
 | |
| 
 | |
| 	if (udr) {
 | |
| 		udr->close();
 | |
| 		delete udr;
 | |
| 		udr = NULL;
 | |
| 	}
 | |
| 
 | |
| 	free(ctrl_iface);
 | |
| 	ctrl_iface = NULL;
 | |
| 
 | |
| 	free(ctrl_iface_dir);
 | |
| 	ctrl_iface_dir = NULL;
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::languageChange()
 | |
| {
 | |
| 	retranslateUi(this);
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::parse_argv()
 | |
| {
 | |
| 	int c;
 | |
| 	for (;;) {
 | |
| 		c = getopt(qApp->argc(), qApp->argv(), "i:p:t");
 | |
| 		if (c < 0)
 | |
| 			break;
 | |
| 		switch (c) {
 | |
| 		case 'i':
 | |
| 			free(ctrl_iface);
 | |
| 			ctrl_iface = strdup(optarg);
 | |
| 			break;
 | |
| 		case 'p':
 | |
| 			free(ctrl_iface_dir);
 | |
| 			ctrl_iface_dir = strdup(optarg);
 | |
| 			break;
 | |
| 		case 't':
 | |
| 			startInTray = true;
 | |
| 			break;
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 
 | |
| int WpaGui::openCtrlConnection(const char *ifname)
 | |
| {
 | |
| 	char *cfile;
 | |
| 	int flen;
 | |
| 	char buf[2048], *pos, *pos2;
 | |
| 	size_t len;
 | |
| 
 | |
| 	if (ifname) {
 | |
| 		if (ifname != ctrl_iface) {
 | |
| 			free(ctrl_iface);
 | |
| 			ctrl_iface = strdup(ifname);
 | |
| 		}
 | |
| 	} else {
 | |
| #ifdef CONFIG_CTRL_IFACE_UDP
 | |
| 		free(ctrl_iface);
 | |
| 		ctrl_iface = strdup("udp");
 | |
| #endif /* CONFIG_CTRL_IFACE_UDP */
 | |
| #ifdef CONFIG_CTRL_IFACE_UNIX
 | |
| 		struct dirent *dent;
 | |
| 		DIR *dir = opendir(ctrl_iface_dir);
 | |
| 		free(ctrl_iface);
 | |
| 		ctrl_iface = NULL;
 | |
| 		if (dir) {
 | |
| 			while ((dent = readdir(dir))) {
 | |
| #ifdef _DIRENT_HAVE_D_TYPE
 | |
| 				/* Skip the file if it is not a socket.
 | |
| 				 * Also accept DT_UNKNOWN (0) in case
 | |
| 				 * the C library or underlying file
 | |
| 				 * system does not support d_type. */
 | |
| 				if (dent->d_type != DT_SOCK &&
 | |
| 				    dent->d_type != DT_UNKNOWN)
 | |
| 					continue;
 | |
| #endif /* _DIRENT_HAVE_D_TYPE */
 | |
| 
 | |
| 				if (strcmp(dent->d_name, ".") == 0 ||
 | |
| 				    strcmp(dent->d_name, "..") == 0)
 | |
| 					continue;
 | |
| 				printf("Selected interface '%s'\n",
 | |
| 				       dent->d_name);
 | |
| 				ctrl_iface = strdup(dent->d_name);
 | |
| 				break;
 | |
| 			}
 | |
| 			closedir(dir);
 | |
| 		}
 | |
| #endif /* CONFIG_CTRL_IFACE_UNIX */
 | |
| #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
 | |
| 		struct wpa_ctrl *ctrl;
 | |
| 		int ret;
 | |
| 
 | |
| 		free(ctrl_iface);
 | |
| 		ctrl_iface = NULL;
 | |
| 
 | |
| 		ctrl = wpa_ctrl_open(NULL);
 | |
| 		if (ctrl) {
 | |
| 			len = sizeof(buf) - 1;
 | |
| 			ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf,
 | |
| 					       &len, NULL);
 | |
| 			if (ret >= 0) {
 | |
| 				connectedToService = true;
 | |
| 				buf[len] = '\0';
 | |
| 				pos = strchr(buf, '\n');
 | |
| 				if (pos)
 | |
| 					*pos = '\0';
 | |
| 				ctrl_iface = strdup(buf);
 | |
| 			}
 | |
| 			wpa_ctrl_close(ctrl);
 | |
| 		}
 | |
| #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
 | |
| 	}
 | |
| 
 | |
| 	if (ctrl_iface == NULL) {
 | |
| #ifdef CONFIG_NATIVE_WINDOWS
 | |
| 		static bool first = true;
 | |
| 		if (first && !serviceRunning()) {
 | |
| 			first = false;
 | |
| 			if (QMessageBox::warning(
 | |
| 				    this, qAppName(),
 | |
| 				    tr("wpa_supplicant service is not "
 | |
| 				       "running.\n"
 | |
| 				       "Do you want to start it?"),
 | |
| 				    QMessageBox::Yes | QMessageBox::No) ==
 | |
| 			    QMessageBox::Yes)
 | |
| 				startService();
 | |
| 		}
 | |
| #endif /* CONFIG_NATIVE_WINDOWS */
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| #ifdef CONFIG_CTRL_IFACE_UNIX
 | |
| 	flen = strlen(ctrl_iface_dir) + strlen(ctrl_iface) + 2;
 | |
| 	cfile = (char *) malloc(flen);
 | |
| 	if (cfile == NULL)
 | |
| 		return -1;
 | |
| 	snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ctrl_iface);
 | |
| #else /* CONFIG_CTRL_IFACE_UNIX */
 | |
| 	flen = strlen(ctrl_iface) + 1;
 | |
| 	cfile = (char *) malloc(flen);
 | |
| 	if (cfile == NULL)
 | |
| 		return -1;
 | |
| 	snprintf(cfile, flen, "%s", ctrl_iface);
 | |
| #endif /* CONFIG_CTRL_IFACE_UNIX */
 | |
| 
 | |
| 	if (ctrl_conn) {
 | |
| 		wpa_ctrl_close(ctrl_conn);
 | |
| 		ctrl_conn = NULL;
 | |
| 	}
 | |
| 
 | |
| 	if (monitor_conn) {
 | |
| 		delete msgNotifier;
 | |
| 		msgNotifier = NULL;
 | |
| 		wpa_ctrl_detach(monitor_conn);
 | |
| 		wpa_ctrl_close(monitor_conn);
 | |
| 		monitor_conn = NULL;
 | |
| 	}
 | |
| 
 | |
| 	printf("Trying to connect to '%s'\n", cfile);
 | |
| 	ctrl_conn = wpa_ctrl_open(cfile);
 | |
| 	if (ctrl_conn == NULL) {
 | |
| 		free(cfile);
 | |
| 		return -1;
 | |
| 	}
 | |
| 	monitor_conn = wpa_ctrl_open(cfile);
 | |
| 	free(cfile);
 | |
| 	if (monitor_conn == NULL) {
 | |
| 		wpa_ctrl_close(ctrl_conn);
 | |
| 		return -1;
 | |
| 	}
 | |
| 	if (wpa_ctrl_attach(monitor_conn)) {
 | |
| 		printf("Failed to attach to wpa_supplicant\n");
 | |
| 		wpa_ctrl_close(monitor_conn);
 | |
| 		monitor_conn = NULL;
 | |
| 		wpa_ctrl_close(ctrl_conn);
 | |
| 		ctrl_conn = NULL;
 | |
| 		return -1;
 | |
| 	}
 | |
| 
 | |
| #if defined(CONFIG_CTRL_IFACE_UNIX) || defined(CONFIG_CTRL_IFACE_UDP)
 | |
| 	msgNotifier = new QSocketNotifier(wpa_ctrl_get_fd(monitor_conn),
 | |
| 					  QSocketNotifier::Read, this);
 | |
| 	connect(msgNotifier, SIGNAL(activated(int)), SLOT(receiveMsgs()));
 | |
| #endif
 | |
| 
 | |
| 	adapterSelect->clear();
 | |
| 	adapterSelect->addItem(ctrl_iface);
 | |
| 	adapterSelect->setCurrentIndex(0);
 | |
| 
 | |
| 	len = sizeof(buf) - 1;
 | |
| 	if (wpa_ctrl_request(ctrl_conn, "INTERFACES", 10, buf, &len, NULL) >=
 | |
| 	    0) {
 | |
| 		buf[len] = '\0';
 | |
| 		pos = buf;
 | |
| 		while (*pos) {
 | |
| 			pos2 = strchr(pos, '\n');
 | |
| 			if (pos2)
 | |
| 				*pos2 = '\0';
 | |
| 			if (strcmp(pos, ctrl_iface) != 0)
 | |
| 				adapterSelect->addItem(pos);
 | |
| 			if (pos2)
 | |
| 				pos = pos2 + 1;
 | |
| 			else
 | |
| 				break;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	len = sizeof(buf) - 1;
 | |
| 	if (wpa_ctrl_request(ctrl_conn, "GET_CAPABILITY eap", 18, buf, &len,
 | |
| 			     NULL) >= 0) {
 | |
| 		buf[len] = '\0';
 | |
| 
 | |
| 		QString res(buf);
 | |
| 		QStringList types = res.split(QChar(' '));
 | |
| 		bool wps = types.contains("WSC");
 | |
| 		actionWPS->setEnabled(wps);
 | |
| 		wpsTab->setEnabled(wps);
 | |
| 		wpaguiTab->setTabEnabled(wpaguiTab->indexOf(wpsTab), wps);
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| int WpaGui::ctrlRequest(const char *cmd, char *buf, size_t *buflen)
 | |
| {
 | |
| 	int ret;
 | |
| 
 | |
| 	if (ctrl_conn == NULL)
 | |
| 		return -3;
 | |
| 	ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), buf, buflen, NULL);
 | |
| 	if (ret == -2)
 | |
| 		printf("'%s' command timed out.\n", cmd);
 | |
| 	else if (ret < 0)
 | |
| 		printf("'%s' command failed.\n", cmd);
 | |
| 
 | |
| 	return ret;
 | |
| }
 | |
| 
 | |
| 
 | |
| QString WpaGui::wpaStateTranslate(char *state)
 | |
| {
 | |
| 	if (!strcmp(state, "DISCONNECTED"))
 | |
| 		return tr("Disconnected");
 | |
| 	else if (!strcmp(state, "INACTIVE"))
 | |
| 		return tr("Inactive");
 | |
| 	else if (!strcmp(state, "SCANNING"))
 | |
| 		return tr("Scanning");
 | |
| 	else if (!strcmp(state, "AUTHENTICATING"))
 | |
| 		return tr("Authenticating");
 | |
| 	else if (!strcmp(state, "ASSOCIATING"))
 | |
| 		return tr("Associating");
 | |
| 	else if (!strcmp(state, "ASSOCIATED"))
 | |
| 		return tr("Associated");
 | |
| 	else if (!strcmp(state, "4WAY_HANDSHAKE"))
 | |
| 		return tr("4-Way Handshake");
 | |
| 	else if (!strcmp(state, "GROUP_HANDSHAKE"))
 | |
| 		return tr("Group Handshake");
 | |
| 	else if (!strcmp(state, "COMPLETED"))
 | |
| 		return tr("Completed");
 | |
| 	else
 | |
| 		return tr("Unknown");
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::updateStatus()
 | |
| {
 | |
| 	char buf[2048], *start, *end, *pos;
 | |
| 	size_t len;
 | |
| 
 | |
| 	pingsToStatusUpdate = 10;
 | |
| 
 | |
| 	len = sizeof(buf) - 1;
 | |
| 	if (ctrl_conn == NULL || ctrlRequest("STATUS", buf, &len) < 0) {
 | |
| 		textStatus->setText(tr("Could not get status from "
 | |
| 				       "wpa_supplicant"));
 | |
| 		textAuthentication->clear();
 | |
| 		textEncryption->clear();
 | |
| 		textSsid->clear();
 | |
| 		textBssid->clear();
 | |
| 		textIpAddress->clear();
 | |
| 
 | |
| #ifdef CONFIG_NATIVE_WINDOWS
 | |
| 		static bool first = true;
 | |
| 		if (first && connectedToService &&
 | |
| 		    (ctrl_iface == NULL || *ctrl_iface == '\0')) {
 | |
| 			first = false;
 | |
| 			if (QMessageBox::information(
 | |
| 				    this, qAppName(),
 | |
| 				    tr("No network interfaces in use.\n"
 | |
| 				       "Would you like to add one?"),
 | |
| 				    QMessageBox::Yes | QMessageBox::No) ==
 | |
| 			    QMessageBox::Yes)
 | |
| 				addInterface();
 | |
| 		}
 | |
| #endif /* CONFIG_NATIVE_WINDOWS */
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	buf[len] = '\0';
 | |
| 
 | |
| 	bool auth_updated = false, ssid_updated = false;
 | |
| 	bool bssid_updated = false, ipaddr_updated = false;
 | |
| 	bool status_updated = false;
 | |
| 	char *pairwise_cipher = NULL, *group_cipher = NULL;
 | |
| 	char *mode = NULL;
 | |
| 
 | |
| 	start = buf;
 | |
| 	while (*start) {
 | |
| 		bool last = false;
 | |
| 		end = strchr(start, '\n');
 | |
| 		if (end == NULL) {
 | |
| 			last = true;
 | |
| 			end = start;
 | |
| 			while (end[0] && end[1])
 | |
| 				end++;
 | |
| 		}
 | |
| 		*end = '\0';
 | |
| 
 | |
| 		pos = strchr(start, '=');
 | |
| 		if (pos) {
 | |
| 			*pos++ = '\0';
 | |
| 			if (strcmp(start, "bssid") == 0) {
 | |
| 				bssid_updated = true;
 | |
| 				textBssid->setText(pos);
 | |
| 			} else if (strcmp(start, "ssid") == 0) {
 | |
| 				ssid_updated = true;
 | |
| 				textSsid->setText(pos);
 | |
| 			} else if (strcmp(start, "ip_address") == 0) {
 | |
| 				ipaddr_updated = true;
 | |
| 				textIpAddress->setText(pos);
 | |
| 			} else if (strcmp(start, "wpa_state") == 0) {
 | |
| 				status_updated = true;
 | |
| 				textStatus->setText(wpaStateTranslate(pos));
 | |
| 			} else if (strcmp(start, "key_mgmt") == 0) {
 | |
| 				auth_updated = true;
 | |
| 				textAuthentication->setText(pos);
 | |
| 				/* TODO: could add EAP status to this */
 | |
| 			} else if (strcmp(start, "pairwise_cipher") == 0) {
 | |
| 				pairwise_cipher = pos;
 | |
| 			} else if (strcmp(start, "group_cipher") == 0) {
 | |
| 				group_cipher = pos;
 | |
| 			} else if (strcmp(start, "mode") == 0) {
 | |
| 				mode = pos;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		if (last)
 | |
| 			break;
 | |
| 		start = end + 1;
 | |
| 	}
 | |
| 	if (status_updated && mode)
 | |
| 		textStatus->setText(textStatus->text() + " (" + mode + ")");
 | |
| 
 | |
| 	if (pairwise_cipher || group_cipher) {
 | |
| 		QString encr;
 | |
| 		if (pairwise_cipher && group_cipher &&
 | |
| 		    strcmp(pairwise_cipher, group_cipher) != 0) {
 | |
| 			encr.append(pairwise_cipher);
 | |
| 			encr.append(" + ");
 | |
| 			encr.append(group_cipher);
 | |
| 		} else if (pairwise_cipher) {
 | |
| 			encr.append(pairwise_cipher);
 | |
| 		} else {
 | |
| 			encr.append(group_cipher);
 | |
| 			encr.append(" [group key only]");
 | |
| 		}
 | |
| 		textEncryption->setText(encr);
 | |
| 	} else
 | |
| 		textEncryption->clear();
 | |
| 
 | |
| 	if (!status_updated)
 | |
| 		textStatus->clear();
 | |
| 	if (!auth_updated)
 | |
| 		textAuthentication->clear();
 | |
| 	if (!ssid_updated)
 | |
| 		textSsid->clear();
 | |
| 	if (!bssid_updated)
 | |
| 		textBssid->clear();
 | |
| 	if (!ipaddr_updated)
 | |
| 		textIpAddress->clear();
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::updateNetworks()
 | |
| {
 | |
| 	char buf[2048], *start, *end, *id, *ssid, *bssid, *flags;
 | |
| 	size_t len;
 | |
| 	int first_active = -1;
 | |
| 	int was_selected = -1;
 | |
| 	bool current = false;
 | |
| 
 | |
| 	if (!networkMayHaveChanged)
 | |
| 		return;
 | |
| 
 | |
| 	if (networkList->currentRow() >= 0)
 | |
| 		was_selected = networkList->currentRow();
 | |
| 
 | |
| 	networkSelect->clear();
 | |
| 	networkList->clear();
 | |
| 
 | |
| 	if (ctrl_conn == NULL)
 | |
| 		return;
 | |
| 
 | |
| 	len = sizeof(buf) - 1;
 | |
| 	if (ctrlRequest("LIST_NETWORKS", buf, &len) < 0)
 | |
| 		return;
 | |
| 
 | |
| 	buf[len] = '\0';
 | |
| 	start = strchr(buf, '\n');
 | |
| 	if (start == NULL)
 | |
| 		return;
 | |
| 	start++;
 | |
| 
 | |
| 	while (*start) {
 | |
| 		bool last = false;
 | |
| 		end = strchr(start, '\n');
 | |
| 		if (end == NULL) {
 | |
| 			last = true;
 | |
| 			end = start;
 | |
| 			while (end[0] && end[1])
 | |
| 				end++;
 | |
| 		}
 | |
| 		*end = '\0';
 | |
| 
 | |
| 		id = start;
 | |
| 		ssid = strchr(id, '\t');
 | |
| 		if (ssid == NULL)
 | |
| 			break;
 | |
| 		*ssid++ = '\0';
 | |
| 		bssid = strchr(ssid, '\t');
 | |
| 		if (bssid == NULL)
 | |
| 			break;
 | |
| 		*bssid++ = '\0';
 | |
| 		flags = strchr(bssid, '\t');
 | |
| 		if (flags == NULL)
 | |
| 			break;
 | |
| 		*flags++ = '\0';
 | |
| 
 | |
| 		if (strstr(flags, "[DISABLED][P2P-PERSISTENT]")) {
 | |
| 			if (last)
 | |
| 				break;
 | |
| 			start = end + 1;
 | |
| 			continue;
 | |
| 		}
 | |
| 
 | |
| 		QString network(id);
 | |
| 		network.append(": ");
 | |
| 		network.append(ssid);
 | |
| 		networkSelect->addItem(network);
 | |
| 		networkList->addItem(network);
 | |
| 
 | |
| 		if (strstr(flags, "[CURRENT]")) {
 | |
| 			networkSelect->setCurrentIndex(networkSelect->count() -
 | |
| 						      1);
 | |
| 			current = true;
 | |
| 		} else if (first_active < 0 &&
 | |
| 			   strstr(flags, "[DISABLED]") == NULL)
 | |
| 			first_active = networkSelect->count() - 1;
 | |
| 
 | |
| 		if (last)
 | |
| 			break;
 | |
| 		start = end + 1;
 | |
| 	}
 | |
| 
 | |
| 	if (networkSelect->count() > 1)
 | |
| 		networkSelect->addItem(tr("Select any network"));
 | |
| 
 | |
| 	if (!current && first_active >= 0)
 | |
| 		networkSelect->setCurrentIndex(first_active);
 | |
| 
 | |
| 	if (was_selected >= 0 && networkList->count() > 0) {
 | |
| 		if (was_selected < networkList->count())
 | |
| 			networkList->setCurrentRow(was_selected);
 | |
| 		else
 | |
| 			networkList->setCurrentRow(networkList->count() - 1);
 | |
| 	}
 | |
| 	else
 | |
| 		networkList->setCurrentRow(networkSelect->currentIndex());
 | |
| 
 | |
| 	networkMayHaveChanged = false;
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::helpIndex()
 | |
| {
 | |
| 	printf("helpIndex\n");
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::helpContents()
 | |
| {
 | |
| 	printf("helpContents\n");
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::helpAbout()
 | |
| {
 | |
| 	QMessageBox::about(this, "wpa_gui for wpa_supplicant",
 | |
| 			   "Copyright (c) 2003-2013,\n"
 | |
| 			   "Jouni Malinen <j@w1.fi>\n"
 | |
| 			   "and contributors.\n"
 | |
| 			   "\n"
 | |
| 			   "This software may be distributed under\n"
 | |
| 			   "the terms of the BSD license.\n"
 | |
| 			   "See README for more details.\n"
 | |
| 			   "\n"
 | |
| 			   "This product includes software developed\n"
 | |
| 			   "by the OpenSSL Project for use in the\n"
 | |
| 			   "OpenSSL Toolkit (http://www.openssl.org/)\n");
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::disconnect()
 | |
| {
 | |
| 	char reply[10];
 | |
| 	size_t reply_len = sizeof(reply);
 | |
| 	ctrlRequest("DISCONNECT", reply, &reply_len);
 | |
| 	stopWpsRun(false);
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::scan()
 | |
| {
 | |
| 	if (scanres) {
 | |
| 		scanres->close();
 | |
| 		delete scanres;
 | |
| 	}
 | |
| 
 | |
| 	scanres = new ScanResults();
 | |
| 	if (scanres == NULL)
 | |
| 		return;
 | |
| 	scanres->setWpaGui(this);
 | |
| 	scanres->show();
 | |
| 	scanres->exec();
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::eventHistory()
 | |
| {
 | |
| 	if (eh) {
 | |
| 		eh->close();
 | |
| 		delete eh;
 | |
| 	}
 | |
| 
 | |
| 	eh = new EventHistory();
 | |
| 	if (eh == NULL)
 | |
| 		return;
 | |
| 	eh->addEvents(msgs);
 | |
| 	eh->show();
 | |
| 	eh->exec();
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::ping()
 | |
| {
 | |
| 	char buf[10];
 | |
| 	size_t len;
 | |
| 
 | |
| #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
 | |
| 	/*
 | |
| 	 * QSocketNotifier cannot be used with Windows named pipes, so use a
 | |
| 	 * timer to check for received messages for now. This could be
 | |
| 	 * optimized be doing something specific to named pipes or Windows
 | |
| 	 * events, but it is not clear what would be the best way of doing that
 | |
| 	 * in Qt.
 | |
| 	 */
 | |
| 	receiveMsgs();
 | |
| #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
 | |
| 
 | |
| 	if (scanres && !scanres->isVisible()) {
 | |
| 		delete scanres;
 | |
| 		scanres = NULL;
 | |
| 	}
 | |
| 
 | |
| 	if (eh && !eh->isVisible()) {
 | |
| 		delete eh;
 | |
| 		eh = NULL;
 | |
| 	}
 | |
| 
 | |
| 	if (udr && !udr->isVisible()) {
 | |
| 		delete udr;
 | |
| 		udr = NULL;
 | |
| 	}
 | |
| 
 | |
| 	len = sizeof(buf) - 1;
 | |
| 	if (ctrlRequest("PING", buf, &len) < 0) {
 | |
| 		printf("PING failed - trying to reconnect\n");
 | |
| 		if (openCtrlConnection(ctrl_iface) >= 0) {
 | |
| 			printf("Reconnected successfully\n");
 | |
| 			pingsToStatusUpdate = 0;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	pingsToStatusUpdate--;
 | |
| 	if (pingsToStatusUpdate <= 0) {
 | |
| 		updateStatus();
 | |
| 		updateNetworks();
 | |
| 	}
 | |
| 
 | |
| #ifndef CONFIG_CTRL_IFACE_NAMED_PIPE
 | |
| 	/* Use less frequent pings and status updates when the main window is
 | |
| 	 * hidden (running in taskbar). */
 | |
| 	int interval = isHidden() ? 5000 : 1000;
 | |
| 	if (timer->interval() != interval)
 | |
| 		timer->setInterval(interval);
 | |
| #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
 | |
| }
 | |
| 
 | |
| 
 | |
| static int str_match(const char *a, const char *b)
 | |
| {
 | |
| 	return strncmp(a, b, strlen(b)) == 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::processMsg(char *msg)
 | |
| {
 | |
| 	char *pos = msg, *pos2;
 | |
| 	int priority = 2;
 | |
| 
 | |
| 	if (*pos == '<') {
 | |
| 		/* skip priority */
 | |
| 		pos++;
 | |
| 		priority = atoi(pos);
 | |
| 		pos = strchr(pos, '>');
 | |
| 		if (pos)
 | |
| 			pos++;
 | |
| 		else
 | |
| 			pos = msg;
 | |
| 	}
 | |
| 
 | |
| 	WpaMsg wm(pos, priority);
 | |
| 	if (eh)
 | |
| 		eh->addEvent(wm);
 | |
| 	if (peers)
 | |
| 		peers->event_notify(wm);
 | |
| 	msgs.append(wm);
 | |
| 	while (msgs.count() > 100)
 | |
| 		msgs.pop_front();
 | |
| 
 | |
| 	/* Update last message with truncated version of the event */
 | |
| 	if (strncmp(pos, "CTRL-", 5) == 0) {
 | |
| 		pos2 = strchr(pos, str_match(pos, WPA_CTRL_REQ) ? ':' : ' ');
 | |
| 		if (pos2)
 | |
| 			pos2++;
 | |
| 		else
 | |
| 			pos2 = pos;
 | |
| 	} else
 | |
| 		pos2 = pos;
 | |
| 	QString lastmsg = pos2;
 | |
| 	lastmsg.truncate(40);
 | |
| 	textLastMessage->setText(lastmsg);
 | |
| 
 | |
| 	pingsToStatusUpdate = 0;
 | |
| 	networkMayHaveChanged = true;
 | |
| 
 | |
| 	if (str_match(pos, WPA_CTRL_REQ))
 | |
| 		processCtrlReq(pos + strlen(WPA_CTRL_REQ));
 | |
| 	else if (str_match(pos, WPA_EVENT_SCAN_RESULTS) && scanres)
 | |
| 		scanres->updateResults();
 | |
| 	else if (str_match(pos, WPA_EVENT_DISCONNECTED))
 | |
| 		showTrayMessage(QSystemTrayIcon::Information, 3,
 | |
| 				tr("Disconnected from network."));
 | |
| 	else if (str_match(pos, WPA_EVENT_CONNECTED)) {
 | |
| 		showTrayMessage(QSystemTrayIcon::Information, 3,
 | |
| 				tr("Connection to network established."));
 | |
| 		QTimer::singleShot(5 * 1000, this, SLOT(showTrayStatus()));
 | |
| 		stopWpsRun(true);
 | |
| 	} else if (str_match(pos, WPS_EVENT_AP_AVAILABLE_PBC)) {
 | |
| 		wpsStatusText->setText(tr("WPS AP in active PBC mode found"));
 | |
| 		if (textStatus->text() == "INACTIVE" ||
 | |
| 		    textStatus->text() == "DISCONNECTED")
 | |
| 			wpaguiTab->setCurrentWidget(wpsTab);
 | |
| 		wpsInstructions->setText(tr("Press the PBC button on the "
 | |
| 					    "screen to start registration"));
 | |
| 	} else if (str_match(pos, WPS_EVENT_AP_AVAILABLE_PIN)) {
 | |
| 		wpsStatusText->setText(tr("WPS AP with recently selected "
 | |
| 					  "registrar"));
 | |
| 		if (textStatus->text() == "INACTIVE" ||
 | |
| 		    textStatus->text() == "DISCONNECTED")
 | |
| 			wpaguiTab->setCurrentWidget(wpsTab);
 | |
| 	} else if (str_match(pos, WPS_EVENT_AP_AVAILABLE_AUTH)) {
 | |
| 		showTrayMessage(QSystemTrayIcon::Information, 3,
 | |
| 				"Wi-Fi Protected Setup (WPS) AP\n"
 | |
| 				"indicating this client is authorized.");
 | |
| 		wpsStatusText->setText("WPS AP indicating this client is "
 | |
| 				       "authorized");
 | |
| 		if (textStatus->text() == "INACTIVE" ||
 | |
| 		    textStatus->text() == "DISCONNECTED")
 | |
| 			wpaguiTab->setCurrentWidget(wpsTab);
 | |
| 	} else if (str_match(pos, WPS_EVENT_AP_AVAILABLE)) {
 | |
| 		wpsStatusText->setText(tr("WPS AP detected"));
 | |
| 	} else if (str_match(pos, WPS_EVENT_OVERLAP)) {
 | |
| 		wpsStatusText->setText(tr("PBC mode overlap detected"));
 | |
| 		wpsInstructions->setText(tr("More than one AP is currently in "
 | |
| 					    "active WPS PBC mode. Wait couple "
 | |
| 					    "of minutes and try again"));
 | |
| 		wpaguiTab->setCurrentWidget(wpsTab);
 | |
| 	} else if (str_match(pos, WPS_EVENT_CRED_RECEIVED)) {
 | |
| 		wpsStatusText->setText(tr("Network configuration received"));
 | |
| 		wpaguiTab->setCurrentWidget(wpsTab);
 | |
| 	} else if (str_match(pos, WPA_EVENT_EAP_METHOD)) {
 | |
| 		if (strstr(pos, "(WSC)"))
 | |
| 			wpsStatusText->setText(tr("Registration started"));
 | |
| 	} else if (str_match(pos, WPS_EVENT_M2D)) {
 | |
| 		wpsStatusText->setText(tr("Registrar does not yet know PIN"));
 | |
| 	} else if (str_match(pos, WPS_EVENT_FAIL)) {
 | |
| 		wpsStatusText->setText(tr("Registration failed"));
 | |
| 	} else if (str_match(pos, WPS_EVENT_SUCCESS)) {
 | |
| 		wpsStatusText->setText(tr("Registration succeeded"));
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::processCtrlReq(const char *req)
 | |
| {
 | |
| 	if (udr) {
 | |
| 		udr->close();
 | |
| 		delete udr;
 | |
| 	}
 | |
| 	udr = new UserDataRequest();
 | |
| 	if (udr == NULL)
 | |
| 		return;
 | |
| 	if (udr->setParams(this, req) < 0) {
 | |
| 		delete udr;
 | |
| 		udr = NULL;
 | |
| 		return;
 | |
| 	}
 | |
| 	udr->show();
 | |
| 	udr->exec();
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::receiveMsgs()
 | |
| {
 | |
| 	char buf[256];
 | |
| 	size_t len;
 | |
| 
 | |
| 	while (monitor_conn && wpa_ctrl_pending(monitor_conn) > 0) {
 | |
| 		len = sizeof(buf) - 1;
 | |
| 		if (wpa_ctrl_recv(monitor_conn, buf, &len) == 0) {
 | |
| 			buf[len] = '\0';
 | |
| 			processMsg(buf);
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::connectB()
 | |
| {
 | |
| 	char reply[10];
 | |
| 	size_t reply_len = sizeof(reply);
 | |
| 	ctrlRequest("REASSOCIATE", reply, &reply_len);
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::selectNetwork( const QString &sel )
 | |
| {
 | |
| 	QString cmd(sel);
 | |
| 	char reply[10];
 | |
| 	size_t reply_len = sizeof(reply);
 | |
| 
 | |
| 	if (cmd.contains(QRegExp("^\\d+:")))
 | |
| 		cmd.truncate(cmd.indexOf(':'));
 | |
| 	else
 | |
| 		cmd = "any";
 | |
| 	cmd.prepend("SELECT_NETWORK ");
 | |
| 	ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
 | |
| 	triggerUpdate();
 | |
| 	stopWpsRun(false);
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::enableNetwork(const QString &sel)
 | |
| {
 | |
| 	QString cmd(sel);
 | |
| 	char reply[10];
 | |
| 	size_t reply_len = sizeof(reply);
 | |
| 
 | |
| 	if (cmd.contains(QRegExp("^\\d+:")))
 | |
| 		cmd.truncate(cmd.indexOf(':'));
 | |
| 	else if (!cmd.startsWith("all")) {
 | |
| 		printf("Invalid editNetwork '%s'\n",
 | |
| 		       cmd.toAscii().constData());
 | |
| 		return;
 | |
| 	}
 | |
| 	cmd.prepend("ENABLE_NETWORK ");
 | |
| 	ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
 | |
| 	triggerUpdate();
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::disableNetwork(const QString &sel)
 | |
| {
 | |
| 	QString cmd(sel);
 | |
| 	char reply[10];
 | |
| 	size_t reply_len = sizeof(reply);
 | |
| 
 | |
| 	if (cmd.contains(QRegExp("^\\d+:")))
 | |
| 		cmd.truncate(cmd.indexOf(':'));
 | |
| 	else if (!cmd.startsWith("all")) {
 | |
| 		printf("Invalid editNetwork '%s'\n",
 | |
| 		       cmd.toAscii().constData());
 | |
| 		return;
 | |
| 	}
 | |
| 	cmd.prepend("DISABLE_NETWORK ");
 | |
| 	ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
 | |
| 	triggerUpdate();
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::editNetwork(const QString &sel)
 | |
| {
 | |
| 	QString cmd(sel);
 | |
| 	int id = -1;
 | |
| 
 | |
| 	if (cmd.contains(QRegExp("^\\d+:"))) {
 | |
| 		cmd.truncate(cmd.indexOf(':'));
 | |
| 		id = cmd.toInt();
 | |
| 	}
 | |
| 
 | |
| 	NetworkConfig *nc = new NetworkConfig();
 | |
| 	if (nc == NULL)
 | |
| 		return;
 | |
| 	nc->setWpaGui(this);
 | |
| 
 | |
| 	if (id >= 0)
 | |
| 		nc->paramsFromConfig(id);
 | |
| 	else
 | |
| 		nc->newNetwork();
 | |
| 
 | |
| 	nc->show();
 | |
| 	nc->exec();
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::editSelectedNetwork()
 | |
| {
 | |
| 	if (networkSelect->count() < 1) {
 | |
| 		QMessageBox::information(
 | |
| 			this, tr("No Networks"),
 | |
| 			tr("There are no networks to edit.\n"));
 | |
| 		return;
 | |
| 	}
 | |
| 	QString sel(networkSelect->currentText());
 | |
| 	editNetwork(sel);
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::editListedNetwork()
 | |
| {
 | |
| 	if (networkList->currentRow() < 0) {
 | |
| 		QMessageBox::information(this, tr("Select A Network"),
 | |
| 					 tr("Select a network from the list to"
 | |
| 					    " edit it.\n"));
 | |
| 		return;
 | |
| 	}
 | |
| 	QString sel(networkList->currentItem()->text());
 | |
| 	editNetwork(sel);
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::triggerUpdate()
 | |
| {
 | |
| 	updateStatus();
 | |
| 	networkMayHaveChanged = true;
 | |
| 	updateNetworks();
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::addNetwork()
 | |
| {
 | |
| 	NetworkConfig *nc = new NetworkConfig();
 | |
| 	if (nc == NULL)
 | |
| 		return;
 | |
| 	nc->setWpaGui(this);
 | |
| 	nc->newNetwork();
 | |
| 	nc->show();
 | |
| 	nc->exec();
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::removeNetwork(const QString &sel)
 | |
| {
 | |
| 	QString cmd(sel);
 | |
| 	char reply[10];
 | |
| 	size_t reply_len = sizeof(reply);
 | |
| 
 | |
| 	if (cmd.contains(QRegExp("^\\d+:")))
 | |
| 		cmd.truncate(cmd.indexOf(':'));
 | |
| 	else if (!cmd.startsWith("all")) {
 | |
| 		printf("Invalid editNetwork '%s'\n",
 | |
| 		       cmd.toAscii().constData());
 | |
| 		return;
 | |
| 	}
 | |
| 	cmd.prepend("REMOVE_NETWORK ");
 | |
| 	ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
 | |
| 	triggerUpdate();
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::removeSelectedNetwork()
 | |
| {
 | |
| 	if (networkSelect->count() < 1) {
 | |
| 		QMessageBox::information(this, tr("No Networks"),
 | |
| 			                 tr("There are no networks to remove."
 | |
| 					    "\n"));
 | |
| 		return;
 | |
| 	}
 | |
| 	QString sel(networkSelect->currentText());
 | |
| 	removeNetwork(sel);
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::removeListedNetwork()
 | |
| {
 | |
| 	if (networkList->currentRow() < 0) {
 | |
| 		QMessageBox::information(this, tr("Select A Network"),
 | |
| 					 tr("Select a network from the list "
 | |
| 					    "to remove it.\n"));
 | |
| 		return;
 | |
| 	}
 | |
| 	QString sel(networkList->currentItem()->text());
 | |
| 	removeNetwork(sel);
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::enableAllNetworks()
 | |
| {
 | |
| 	QString sel("all");
 | |
| 	enableNetwork(sel);
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::disableAllNetworks()
 | |
| {
 | |
| 	QString sel("all");
 | |
| 	disableNetwork(sel);
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::removeAllNetworks()
 | |
| {
 | |
| 	QString sel("all");
 | |
| 	removeNetwork(sel);
 | |
| }
 | |
| 
 | |
| 
 | |
| int WpaGui::getNetworkDisabled(const QString &sel)
 | |
| {
 | |
| 	QString cmd(sel);
 | |
| 	char reply[10];
 | |
| 	size_t reply_len = sizeof(reply) - 1;
 | |
| 	int pos = cmd.indexOf(':');
 | |
| 	if (pos < 0) {
 | |
| 		printf("Invalid getNetworkDisabled '%s'\n",
 | |
| 		       cmd.toAscii().constData());
 | |
| 		return -1;
 | |
| 	}
 | |
| 	cmd.truncate(pos);
 | |
| 	cmd.prepend("GET_NETWORK ");
 | |
| 	cmd.append(" disabled");
 | |
| 
 | |
| 	if (ctrlRequest(cmd.toAscii().constData(), reply, &reply_len) >= 0
 | |
| 	    && reply_len >= 1) {
 | |
| 		reply[reply_len] = '\0';
 | |
| 		if (!str_match(reply, "FAIL"))
 | |
| 			return atoi(reply);
 | |
| 	}
 | |
| 
 | |
| 	return -1;
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::updateNetworkDisabledStatus()
 | |
| {
 | |
| 	if (networkList->currentRow() < 0)
 | |
| 		return;
 | |
| 
 | |
| 	QString sel(networkList->currentItem()->text());
 | |
| 
 | |
| 	switch (getNetworkDisabled(sel)) {
 | |
| 	case 0:
 | |
| 		if (!enableRadioButton->isChecked())
 | |
| 			enableRadioButton->setChecked(true);
 | |
| 		return;
 | |
| 	case 1:
 | |
| 		if (!disableRadioButton->isChecked())
 | |
| 			disableRadioButton->setChecked(true);
 | |
| 		return;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::enableListedNetwork(bool enabled)
 | |
| {
 | |
| 	if (networkList->currentRow() < 0 || !enabled)
 | |
| 		return;
 | |
| 
 | |
| 	QString sel(networkList->currentItem()->text());
 | |
| 
 | |
| 	if (getNetworkDisabled(sel) == 1)
 | |
| 		enableNetwork(sel);
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::disableListedNetwork(bool disabled)
 | |
| {
 | |
| 	if (networkList->currentRow() < 0 || !disabled)
 | |
| 		return;
 | |
| 
 | |
| 	QString sel(networkList->currentItem()->text());
 | |
| 
 | |
| 	if (getNetworkDisabled(sel) == 0)
 | |
| 		disableNetwork(sel);
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::saveConfig()
 | |
| {
 | |
| 	char buf[10];
 | |
| 	size_t len;
 | |
| 
 | |
| 	len = sizeof(buf) - 1;
 | |
| 	ctrlRequest("SAVE_CONFIG", buf, &len);
 | |
| 
 | |
| 	buf[len] = '\0';
 | |
| 
 | |
| 	if (str_match(buf, "FAIL"))
 | |
| 		QMessageBox::warning(
 | |
| 			this, tr("Failed to save configuration"),
 | |
| 			tr("The configuration could not be saved.\n"
 | |
| 			   "\n"
 | |
| 			   "The update_config=1 configuration option\n"
 | |
| 			   "must be used for configuration saving to\n"
 | |
| 			   "be permitted.\n"));
 | |
| 	else
 | |
| 		QMessageBox::information(
 | |
| 			this, tr("Saved configuration"),
 | |
| 			tr("The current configuration was saved."
 | |
| 			   "\n"));
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::selectAdapter( const QString & sel )
 | |
| {
 | |
| 	if (openCtrlConnection(sel.toAscii().constData()) < 0)
 | |
| 		printf("Failed to open control connection to "
 | |
| 		       "wpa_supplicant.\n");
 | |
| 	updateStatus();
 | |
| 	updateNetworks();
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::createTrayIcon(bool trayOnly)
 | |
| {
 | |
| 	QApplication::setQuitOnLastWindowClosed(false);
 | |
| 
 | |
| 	tray_icon = new QSystemTrayIcon(this);
 | |
| 	tray_icon->setToolTip(qAppName() + tr(" - wpa_supplicant user interface"));
 | |
| 	if (QImageReader::supportedImageFormats().contains(QByteArray("svg")))
 | |
| 		tray_icon->setIcon(QIcon(":/icons/wpa_gui.svg"));
 | |
| 	else
 | |
| 		tray_icon->setIcon(QIcon(":/icons/wpa_gui.png"));
 | |
| 
 | |
| 	connect(tray_icon,
 | |
| 		SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
 | |
| 		this, SLOT(trayActivated(QSystemTrayIcon::ActivationReason)));
 | |
| 
 | |
| 	ackTrayIcon = false;
 | |
| 
 | |
| 	tray_menu = new QMenu(this);
 | |
| 
 | |
| 	disconnectAction = new QAction(tr("&Disconnect"), this);
 | |
| 	reconnectAction = new QAction(tr("Re&connect"), this);
 | |
| 	connect(disconnectAction, SIGNAL(triggered()), this,
 | |
| 		SLOT(disconnect()));
 | |
| 	connect(reconnectAction, SIGNAL(triggered()), this,
 | |
| 		SLOT(connectB()));
 | |
| 	tray_menu->addAction(disconnectAction);
 | |
| 	tray_menu->addAction(reconnectAction);
 | |
| 	tray_menu->addSeparator();
 | |
| 
 | |
| 	eventAction = new QAction(tr("&Event History"), this);
 | |
| 	scanAction = new QAction(tr("Scan &Results"), this);
 | |
| 	statAction = new QAction(tr("S&tatus"), this);
 | |
| 	connect(eventAction, SIGNAL(triggered()), this, SLOT(eventHistory()));
 | |
| 	connect(scanAction, SIGNAL(triggered()), this, SLOT(scan()));
 | |
| 	connect(statAction, SIGNAL(triggered()), this, SLOT(showTrayStatus()));
 | |
| 	tray_menu->addAction(eventAction);
 | |
| 	tray_menu->addAction(scanAction);
 | |
| 	tray_menu->addAction(statAction);
 | |
| 	tray_menu->addSeparator();
 | |
| 
 | |
| 	showAction = new QAction(tr("&Show Window"), this);
 | |
| 	hideAction = new QAction(tr("&Hide Window"), this);
 | |
| 	quitAction = new QAction(tr("&Quit"), this);
 | |
| 	connect(showAction, SIGNAL(triggered()), this, SLOT(show()));
 | |
| 	connect(hideAction, SIGNAL(triggered()), this, SLOT(hide()));
 | |
| 	connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
 | |
| 	tray_menu->addAction(showAction);
 | |
| 	tray_menu->addAction(hideAction);
 | |
| 	tray_menu->addSeparator();
 | |
| 	tray_menu->addAction(quitAction);
 | |
| 
 | |
| 	tray_icon->setContextMenu(tray_menu);
 | |
| 
 | |
| 	tray_icon->show();
 | |
| 
 | |
| 	if (!trayOnly)
 | |
| 		show();
 | |
| 	inTray = trayOnly;
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::showTrayMessage(QSystemTrayIcon::MessageIcon type, int sec,
 | |
| 			     const QString & msg)
 | |
| {
 | |
| 	if (!QSystemTrayIcon::supportsMessages())
 | |
| 		return;
 | |
| 
 | |
| 	if (isVisible() || !tray_icon || !tray_icon->isVisible())
 | |
| 		return;
 | |
| 
 | |
| 	tray_icon->showMessage(qAppName(), msg, type, sec * 1000);
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::trayActivated(QSystemTrayIcon::ActivationReason how)
 | |
|  {
 | |
| 	switch (how) {
 | |
| 	/* use close() here instead of hide() and allow the
 | |
| 	 * custom closeEvent handler take care of children */
 | |
| 	case QSystemTrayIcon::Trigger:
 | |
| 		ackTrayIcon = true;
 | |
| 		if (isVisible()) {
 | |
| 			close();
 | |
| 			inTray = true;
 | |
| 		} else {
 | |
| 			show();
 | |
| 			inTray = false;
 | |
| 		}
 | |
| 		break;
 | |
| 	case QSystemTrayIcon::MiddleClick:
 | |
| 		showTrayStatus();
 | |
| 		break;
 | |
| 	default:
 | |
| 		break;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::showTrayStatus()
 | |
| {
 | |
| 	char buf[2048];
 | |
| 	size_t len;
 | |
| 
 | |
| 	len = sizeof(buf) - 1;
 | |
| 	if (ctrlRequest("STATUS", buf, &len) < 0)
 | |
| 		return;
 | |
| 	buf[len] = '\0';
 | |
| 
 | |
| 	QString msg, status(buf);
 | |
| 
 | |
| 	QStringList lines = status.split(QRegExp("\\n"));
 | |
| 	for (QStringList::Iterator it = lines.begin();
 | |
| 	     it != lines.end(); it++) {
 | |
| 		int pos = (*it).indexOf('=') + 1;
 | |
| 		if (pos < 1)
 | |
| 			continue;
 | |
| 
 | |
| 		if ((*it).startsWith("bssid="))
 | |
| 			msg.append("BSSID:\t" + (*it).mid(pos) + "\n");
 | |
| 		else if ((*it).startsWith("ssid="))
 | |
| 			msg.append("SSID: \t" + (*it).mid(pos) + "\n");
 | |
| 		else if ((*it).startsWith("pairwise_cipher="))
 | |
| 			msg.append("PAIR: \t" + (*it).mid(pos) + "\n");
 | |
| 		else if ((*it).startsWith("group_cipher="))
 | |
| 			msg.append("GROUP:\t" + (*it).mid(pos) + "\n");
 | |
| 		else if ((*it).startsWith("key_mgmt="))
 | |
| 			msg.append("AUTH: \t" + (*it).mid(pos) + "\n");
 | |
| 		else if ((*it).startsWith("wpa_state="))
 | |
| 			msg.append("STATE:\t" + (*it).mid(pos) + "\n");
 | |
| 		else if ((*it).startsWith("ip_address="))
 | |
| 			msg.append("IP:   \t" + (*it).mid(pos) + "\n");
 | |
| 		else if ((*it).startsWith("Supplicant PAE state="))
 | |
| 			msg.append("PAE:  \t" + (*it).mid(pos) + "\n");
 | |
| 		else if ((*it).startsWith("EAP state="))
 | |
| 			msg.append("EAP:  \t" + (*it).mid(pos) + "\n");
 | |
| 	}
 | |
| 
 | |
| 	if (!msg.isEmpty())
 | |
| 		showTrayMessage(QSystemTrayIcon::Information, 10, msg);
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::closeEvent(QCloseEvent *event)
 | |
| {
 | |
| 	if (eh) {
 | |
| 		eh->close();
 | |
| 		delete eh;
 | |
| 		eh = NULL;
 | |
| 	}
 | |
| 
 | |
| 	if (scanres) {
 | |
| 		scanres->close();
 | |
| 		delete scanres;
 | |
| 		scanres = NULL;
 | |
| 	}
 | |
| 
 | |
| 	if (peers) {
 | |
| 		peers->close();
 | |
| 		delete peers;
 | |
| 		peers = NULL;
 | |
| 	}
 | |
| 
 | |
| 	if (udr) {
 | |
| 		udr->close();
 | |
| 		delete udr;
 | |
| 		udr = NULL;
 | |
| 	}
 | |
| 
 | |
| 	if (tray_icon && !ackTrayIcon) {
 | |
| 		/* give user a visual hint that the tray icon exists */
 | |
| 		if (QSystemTrayIcon::supportsMessages()) {
 | |
| 			hide();
 | |
| 			showTrayMessage(QSystemTrayIcon::Information, 3,
 | |
| 					qAppName() +
 | |
| 					tr(" will keep running in "
 | |
| 					   "the system tray."));
 | |
| 		} else {
 | |
| 			QMessageBox::information(this, qAppName() +
 | |
| 						 tr(" systray"),
 | |
| 						 tr("The program will keep "
 | |
| 						    "running in the system "
 | |
| 						    "tray."));
 | |
| 		}
 | |
| 		ackTrayIcon = true;
 | |
| 	}
 | |
| 
 | |
| 	event->accept();
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::wpsDialog()
 | |
| {
 | |
| 	wpaguiTab->setCurrentWidget(wpsTab);
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::peersDialog()
 | |
| {
 | |
| 	if (peers) {
 | |
| 		peers->close();
 | |
| 		delete peers;
 | |
| 	}
 | |
| 
 | |
| 	peers = new Peers();
 | |
| 	if (peers == NULL)
 | |
| 		return;
 | |
| 	peers->setWpaGui(this);
 | |
| 	peers->show();
 | |
| 	peers->exec();
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::tabChanged(int index)
 | |
| {
 | |
| 	if (index != 2)
 | |
| 		return;
 | |
| 
 | |
| 	if (wpsRunning)
 | |
| 		return;
 | |
| 
 | |
| 	wpsApPinEdit->setEnabled(!bssFromScan.isEmpty());
 | |
| 	if (bssFromScan.isEmpty())
 | |
| 		wpsApPinButton->setEnabled(false);
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::wpsPbc()
 | |
| {
 | |
| 	char reply[20];
 | |
| 	size_t reply_len = sizeof(reply);
 | |
| 
 | |
| 	if (ctrlRequest("WPS_PBC", reply, &reply_len) < 0)
 | |
| 		return;
 | |
| 
 | |
| 	wpsPinEdit->setEnabled(false);
 | |
| 	if (wpsStatusText->text().compare(tr("WPS AP in active PBC mode found"))) {
 | |
| 		wpsInstructions->setText(tr("Press the push button on the AP to "
 | |
| 					 "start the PBC mode."));
 | |
| 	} else {
 | |
| 		wpsInstructions->setText(tr("If you have not yet done so, press "
 | |
| 					 "the push button on the AP to start "
 | |
| 					 "the PBC mode."));
 | |
| 	}
 | |
| 	wpsStatusText->setText(tr("Waiting for Registrar"));
 | |
| 	wpsRunning = true;
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::wpsGeneratePin()
 | |
| {
 | |
| 	char reply[20];
 | |
| 	size_t reply_len = sizeof(reply) - 1;
 | |
| 
 | |
| 	if (ctrlRequest("WPS_PIN any", reply, &reply_len) < 0)
 | |
| 		return;
 | |
| 
 | |
| 	reply[reply_len] = '\0';
 | |
| 
 | |
| 	wpsPinEdit->setText(reply);
 | |
| 	wpsPinEdit->setEnabled(true);
 | |
| 	wpsInstructions->setText(tr("Enter the generated PIN into the Registrar "
 | |
| 				 "(either the internal one in the AP or an "
 | |
| 				 "external one)."));
 | |
| 	wpsStatusText->setText(tr("Waiting for Registrar"));
 | |
| 	wpsRunning = true;
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::setBssFromScan(const QString &bssid)
 | |
| {
 | |
| 	bssFromScan = bssid;
 | |
| 	wpsApPinEdit->setEnabled(!bssFromScan.isEmpty());
 | |
| 	wpsApPinButton->setEnabled(wpsApPinEdit->text().length() == 8);
 | |
| 	wpsStatusText->setText(tr("WPS AP selected from scan results"));
 | |
| 	wpsInstructions->setText(tr("If you want to use an AP device PIN, e.g., "
 | |
| 				 "from a label in the device, enter the eight "
 | |
| 				 "digit AP PIN and click Use AP PIN button."));
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::wpsApPinChanged(const QString &text)
 | |
| {
 | |
| 	wpsApPinButton->setEnabled(text.length() == 8);
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::wpsApPin()
 | |
| {
 | |
| 	char reply[20];
 | |
| 	size_t reply_len = sizeof(reply);
 | |
| 
 | |
| 	QString cmd("WPS_REG " + bssFromScan + " " + wpsApPinEdit->text());
 | |
| 	if (ctrlRequest(cmd.toAscii().constData(), reply, &reply_len) < 0)
 | |
| 		return;
 | |
| 
 | |
| 	wpsStatusText->setText(tr("Waiting for AP/Enrollee"));
 | |
| 	wpsRunning = true;
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::stopWpsRun(bool success)
 | |
| {
 | |
| 	if (wpsRunning)
 | |
| 		wpsStatusText->setText(success ? tr("Connected to the network") :
 | |
| 				       tr("Stopped"));
 | |
| 	else
 | |
| 		wpsStatusText->setText("");
 | |
| 	wpsPinEdit->setEnabled(false);
 | |
| 	wpsInstructions->setText("");
 | |
| 	wpsRunning = false;
 | |
| 	bssFromScan = "";
 | |
| 	wpsApPinEdit->setEnabled(false);
 | |
| 	wpsApPinButton->setEnabled(false);
 | |
| }
 | |
| 
 | |
| 
 | |
| #ifdef CONFIG_NATIVE_WINDOWS
 | |
| 
 | |
| #ifndef WPASVC_NAME
 | |
| #define WPASVC_NAME TEXT("wpasvc")
 | |
| #endif
 | |
| 
 | |
| class ErrorMsg : public QMessageBox {
 | |
| public:
 | |
| 	ErrorMsg(QWidget *parent, DWORD last_err = GetLastError());
 | |
| 	void showMsg(QString msg);
 | |
| private:
 | |
| 	DWORD err;
 | |
| };
 | |
| 
 | |
| ErrorMsg::ErrorMsg(QWidget *parent, DWORD last_err) :
 | |
| 	QMessageBox(parent), err(last_err)
 | |
| {
 | |
| 	setWindowTitle(tr("wpa_gui error"));
 | |
| 	setIcon(QMessageBox::Warning);
 | |
| }
 | |
| 
 | |
| void ErrorMsg::showMsg(QString msg)
 | |
| {
 | |
| 	LPTSTR buf;
 | |
| 
 | |
| 	setText(msg);
 | |
| 	if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
 | |
| 			  FORMAT_MESSAGE_FROM_SYSTEM,
 | |
| 			  NULL, err, 0, (LPTSTR) (void *) &buf,
 | |
| 			  0, NULL) > 0) {
 | |
| 		QString msg = QString::fromWCharArray(buf);
 | |
| 		setInformativeText(QString("[%1] %2").arg(err).arg(msg));
 | |
| 		LocalFree(buf);
 | |
| 	} else {
 | |
| 		setInformativeText(QString("[%1]").arg(err));
 | |
| 	}
 | |
| 
 | |
| 	exec();
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::startService()
 | |
| {
 | |
| 	SC_HANDLE svc, scm;
 | |
| 
 | |
| 	scm = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
 | |
| 	if (!scm) {
 | |
| 		ErrorMsg(this).showMsg(tr("OpenSCManager failed"));
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	svc = OpenService(scm, WPASVC_NAME, SERVICE_START);
 | |
| 	if (!svc) {
 | |
| 		ErrorMsg(this).showMsg(tr("OpenService failed"));
 | |
| 		CloseServiceHandle(scm);
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	if (!StartService(svc, 0, NULL)) {
 | |
| 		ErrorMsg(this).showMsg(tr("Failed to start wpa_supplicant "
 | |
| 				       "service"));
 | |
| 	}
 | |
| 
 | |
| 	CloseServiceHandle(svc);
 | |
| 	CloseServiceHandle(scm);
 | |
| }
 | |
| 
 | |
| 
 | |
| void WpaGui::stopService()
 | |
| {
 | |
| 	SC_HANDLE svc, scm;
 | |
| 	SERVICE_STATUS status;
 | |
| 
 | |
| 	scm = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
 | |
| 	if (!scm) {
 | |
| 		ErrorMsg(this).showMsg(tr("OpenSCManager failed"));
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	svc = OpenService(scm, WPASVC_NAME, SERVICE_STOP);
 | |
| 	if (!svc) {
 | |
| 		ErrorMsg(this).showMsg(tr("OpenService failed"));
 | |
| 		CloseServiceHandle(scm);
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	if (!ControlService(svc, SERVICE_CONTROL_STOP, &status)) {
 | |
| 		ErrorMsg(this).showMsg(tr("Failed to stop wpa_supplicant "
 | |
| 				       "service"));
 | |
| 	}
 | |
| 
 | |
| 	CloseServiceHandle(svc);
 | |
| 	CloseServiceHandle(scm);
 | |
| }
 | |
| 
 | |
| 
 | |
| bool WpaGui::serviceRunning()
 | |
| {
 | |
| 	SC_HANDLE svc, scm;
 | |
| 	SERVICE_STATUS status;
 | |
| 	bool running = false;
 | |
| 
 | |
| 	scm = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
 | |
| 	if (!scm) {
 | |
| 		printf("OpenSCManager failed: %d\n", (int) GetLastError());
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	svc = OpenService(scm, WPASVC_NAME, SERVICE_QUERY_STATUS);
 | |
| 	if (!svc) {
 | |
| 		printf("OpenService failed: %d\n\n", (int) GetLastError());
 | |
| 		CloseServiceHandle(scm);
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	if (QueryServiceStatus(svc, &status)) {
 | |
| 		if (status.dwCurrentState != SERVICE_STOPPED)
 | |
| 			running = true;
 | |
| 	}
 | |
| 
 | |
| 	CloseServiceHandle(svc);
 | |
| 	CloseServiceHandle(scm);
 | |
| 
 | |
| 	return running;
 | |
| }
 | |
| 
 | |
| #endif /* CONFIG_NATIVE_WINDOWS */
 | |
| 
 | |
| 
 | |
| void WpaGui::addInterface()
 | |
| {
 | |
| 	if (add_iface) {
 | |
| 		add_iface->close();
 | |
| 		delete add_iface;
 | |
| 	}
 | |
| 	add_iface = new AddInterface(this, this);
 | |
| 	add_iface->show();
 | |
| 	add_iface->exec();
 | |
| }
 | |
| 
 | |
| 
 | |
| #ifndef QT_NO_SESSIONMANAGER
 | |
| void WpaGui::saveState()
 | |
| {
 | |
| 	QSettings settings("wpa_supplicant", "wpa_gui");
 | |
| 	settings.beginGroup("state");
 | |
| 	settings.setValue("session_id", app->sessionId());
 | |
| 	settings.setValue("in_tray", inTray);
 | |
| 	settings.endGroup();
 | |
| }
 | |
| #endif
 | 
