diff options
author | Adam Ierymenko <adam.ierymenko@zerotier.com> | 2014-02-27 16:28:55 -0800 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@zerotier.com> | 2014-02-27 16:28:55 -0800 |
commit | 9d05897f7a3d06f5504b3bb75dd7e822e5faebf9 (patch) | |
tree | 94b4fca19138ef431d547fa9cbee4f429c7b7de9 /ZeroTierUI | |
parent | cbeb9c523644a49abb679bc4c97859238d28da2d (diff) | |
download | infinitytier-9d05897f7a3d06f5504b3bb75dd7e822e5faebf9.tar.gz infinitytier-9d05897f7a3d06f5504b3bb75dd7e822e5faebf9.zip |
Windows service works now!
Diffstat (limited to 'ZeroTierUI')
-rw-r--r-- | ZeroTierUI/installdialog.h | 2 | ||||
-rw-r--r-- | ZeroTierUI/main.cpp | 104 |
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(); |