summaryrefslogtreecommitdiff
path: root/ZeroTierUI
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@zerotier.com>2014-02-27 16:28:55 -0800
committerAdam Ierymenko <adam.ierymenko@zerotier.com>2014-02-27 16:28:55 -0800
commit9d05897f7a3d06f5504b3bb75dd7e822e5faebf9 (patch)
tree94b4fca19138ef431d547fa9cbee4f429c7b7de9 /ZeroTierUI
parentcbeb9c523644a49abb679bc4c97859238d28da2d (diff)
downloadinfinitytier-9d05897f7a3d06f5504b3bb75dd7e822e5faebf9.tar.gz
infinitytier-9d05897f7a3d06f5504b3bb75dd7e822e5faebf9.zip
Windows service works now!
Diffstat (limited to 'ZeroTierUI')
-rw-r--r--ZeroTierUI/installdialog.h2
-rw-r--r--ZeroTierUI/main.cpp104
2 files changed, 102 insertions, 4 deletions
diff --git a/ZeroTierUI/installdialog.h b/ZeroTierUI/installdialog.h
index 498bc16b..2b38a775 100644
--- a/ZeroTierUI/installdialog.h
+++ b/ZeroTierUI/installdialog.h
@@ -38,6 +38,8 @@
#include "../node/Address.hpp"
+// Right now InstallDialog is only used on Mac
+
namespace Ui {
class InstallDialog;
}
diff --git a/ZeroTierUI/main.cpp b/ZeroTierUI/main.cpp
index c2849edc..84e1e121 100644
--- a/ZeroTierUI/main.cpp
+++ b/ZeroTierUI/main.cpp
@@ -25,6 +25,10 @@
* LLC. Start here: http://www.zerotier.com/
*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
#include "mainwindow.h"
#include "installdialog.h"
#include "licensedialog.h"
@@ -33,12 +37,62 @@
#include <QDir>
#include <QString>
#include <QFont>
+#include <QMessageBox>
+
+#include "../node/Constants.hpp"
+#include "../node/Defaults.hpp"
#ifdef __WINDOWS__
#include <WinSock2.h>
#include <windows.h>
-#endif
+#include "../windows/ZeroTierOne/ZeroTierOneService.h"
+
+// Returns true if started or already running, false if failed or not installed
+static bool startWindowsService()
+{
+ SERVICE_STATUS ssSvcStatus;
+ SC_HANDLE schSCManager = NULL;
+ SC_HANDLE schService = NULL;
+
+ schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
+ if (schSCManager == NULL)
+ return false;
+
+ schService = OpenService(schSCManager, ZT_SERVICE_NAME, SERVICE_QUERY_STATUS | SERVICE_START);
+ if (schService == NULL) {
+ CloseServiceHandle(schSCManager);
+ return false;
+ }
+
+ int tries = 0;
+ bool running = true;
+
+ for(;;) {
+ memset(&ssSvcStatus,0,sizeof(ssSvcStatus));
+ if ((++tries > 20)||(!QueryServiceStatus(schService,&ssSvcStatus))) {
+ running = false;
+ break;
+ }
+
+ if (ssSvcStatus.dwCurrentState == SERVICE_RUNNING) {
+ break;
+ } else if (ssSvcStatus.dwCurrentState == SERVICE_START_PENDING) {
+ Sleep(500);
+ continue;
+ }
+
+ memset(&ssSvcStatus,0,sizeof(ssSvcStatus));
+ ControlService(schService, SERVICE_CONTROL_START, &ssSvcStatus);
+ Sleep(500);
+ }
+
+ CloseServiceHandle(schService);
+ CloseServiceHandle(schSCManager);
+ return running;
+}
+#endif // __WINDOWS__
+// Globally visible settings for the app
QSettings *settings = (QSettings *)0;
int main(int argc, char *argv[])
@@ -46,6 +100,7 @@ int main(int argc, char *argv[])
QApplication a(argc, argv);
#ifdef __WINDOWS__
+ // Start up Winsock2
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2),&wsaData);
@@ -65,12 +120,11 @@ int main(int argc, char *argv[])
// InstallDialog is an alternative main window. It will re-launch the app
// when done.
InstallDialog id;
+ id.setStyleSheet(a.styleSheet());
id.show();
return a.exec();
}
-#endif
-#ifdef __APPLE__
{
// Put QSettings here because this is one of the writable directories allowed
// in Apple's app store sandbox specs. We might end up in app store someday.
@@ -78,7 +132,7 @@ int main(int argc, char *argv[])
QDir::root().mkpath(zt1AppSupport);
settings = new QSettings(zt1AppSupport + "/ui.ini",QSettings::IniFormat);
}
-#else
+#else // on non-Apple boxen put it in the standard place using the default format
settings = new QSettings("ZeroTier Networks","ZeroTier One");
#endif
@@ -88,6 +142,48 @@ int main(int argc, char *argv[])
ld.exec();
}
+#ifdef __WINDOWS__
+ {
+ bool winSvcInstalled = false;
+ while (!startWindowsService()) {
+ if (winSvcInstalled) {
+ // Service was installed and subsequently failed to start again, so
+ // something is wrong!
+ QMessageBox::critical((QWidget *)0,"Service Not Available","Unable to locate or start ZeroTier One service. There may be a problem with the installation. Try installing from the .msi file again or e-mail contact@zerotier.com if you cannot install. (Error: service failed to start)",QMessageBox::Ok);
+ return 1;
+ }
+
+#ifdef _WIN64
+ BOOL is64Bit = TRUE;
+#else
+ BOOL is64Bit = FALSE;
+ IsWow64Process(GetCurrentProcess(),&is64Bit);
+#endif
+ std::string exe(ZeroTier::ZT_DEFAULTS.defaultHomePath + "\\zerotier-one_");
+ exe.append((is64Bit == TRUE) ? "x64.exe" : "x86.exe");
+
+ if (QFile::exists(exe.c_str())) {
+ STARTUPINFOA si;
+ PROCESS_INFORMATION pi;
+ memset(&si,0,sizeof(si));
+ memset(&pi,0,sizeof(pi));
+ if (CreateProcessA(NULL,const_cast <LPSTR>((exe + " -I").c_str()),NULL,NULL,FALSE,CREATE_NO_WINDOW|CREATE_NEW_PROCESS_GROUP,NULL,NULL,&si,&pi)) {
+ WaitForSingleObject(pi.hProcess,INFINITE);
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ winSvcInstalled = true;
+ }
+ }
+
+ if (!winSvcInstalled) {
+ // Service failed to install -- installation problem like missing .exe
+ QMessageBox::critical((QWidget *)0,"Service Not Available","Unable to locate or start ZeroTier One service. There may be a problem with the installation. Try installing from the .msi file again or e-mail contact@zerotier.com if you cannot install. (Error: service not installed)",QMessageBox::Ok);
+ return 1;
+ }
+ }
+ }
+#endif
+
MainWindow w;
w.show();
return a.exec();