00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "torservice.h"
00029
00030
00031
00032 bool
00033 TorService::isSupported()
00034 {
00035 bool supported = false;
00036 #if defined(Q_OS_WIN32)
00037 supported = (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based);
00038 #endif
00039 return supported;
00040 }
00041
00042
00043 TorService::TorService(const QString &torPath, const QString &torrc,
00044 QObject* parent)
00045 : QObject(parent)
00046 {
00047 Q_UNUSED(torrc);
00048
00049
00050 _torrc = "\"C:\\Program Files\\Tor\\torrc\"";
00051 _torPath = "\"" + torPath + "\"";
00052 _manager = NULL;
00053 _service = NULL;
00054
00055 initialize();
00056 }
00057
00058
00059 TorService::~TorService()
00060 {
00061 close();
00062 }
00063
00064
00065 void
00066 TorService::close()
00067 {
00068 #if defined(Q_OS_WIN32)
00069 if (_service) {
00070 CloseServiceHandle(_service);
00071 _service = NULL;
00072 }
00073
00074 if (_manager) {
00075 CloseServiceHandle(_manager);
00076 _manager = NULL;
00077 }
00078 #endif
00079 }
00080
00081
00082 void
00083 TorService::initialize()
00084 {
00085
00086 #if defined(Q_OS_WIN32)
00087 if (isSupported()) {
00088
00089 if (_manager == NULL) {
00090 _manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
00091 }
00092
00093 if (_service == NULL) {
00094 _service = OpenServiceA(_manager, TOR_SERVICE_NAME, TOR_SERVICE_ACCESS);
00095 }
00096 }
00097 #endif
00098 }
00099
00100
00101 bool
00102 TorService::isInstalled()
00103 {
00104 return _service != NULL;
00105 }
00106
00107
00108 bool
00109 TorService::isRunning()
00110 {
00111 #if defined(Q_OS_WIN32)
00112 return (status() == SERVICE_RUNNING);
00113 #else
00114 return false;
00115 #endif
00116 }
00117
00118
00119 void
00120 TorService::start()
00121 {
00122 if (!isSupported()) {
00123 emit startFailed(tr("Services not supported on this platform."));
00124 return;
00125 }
00126
00127 if (!isInstalled()) {
00128 if (!install()) {
00129 emit startFailed(tr("Unable to install the Tor service."));
00130 return;
00131 }
00132 }
00133 #if defined(Q_OS_WIN32)
00134
00135 initialize();
00136
00137
00138 if (!isRunning()) StartService(_service, 0, NULL);
00139
00140 int tries = 0;
00141 while (true) {
00142 if (isRunning()) break;
00143 tries++;
00144 Sleep(1000);
00145 if (tries > 5) break;
00146 }
00147
00148 if (isRunning()) {
00149 emit started();
00150
00151 } else {
00152 emit startFailed(tr("Unable to start Tor service."));
00153 }
00154 #endif
00155 }
00156
00157
00158 void
00159 TorService::stop()
00160 {
00161 #if defined(Q_OS_WIN32)
00162 if (isRunning()) {
00163 SERVICE_STATUS stat;
00164 stat.dwCurrentState = SERVICE_RUNNING;
00165 ControlService(_service, SERVICE_CONTROL_STOP, &stat);
00166
00167 int tries = 0;
00168 while (true) {
00169 if (status() == SERVICE_STOPPED) break;
00170 tries++;
00171 Sleep(1000);
00172 if (tries > 5) break;
00173 }
00174 }
00175
00176 if (!isRunning()) emit finished();
00177 #endif
00178 }
00179
00180
00181 bool
00182 TorService::install()
00183 {
00184 #if defined(Q_OS_WIN32)
00185 if (!isSupported()) return false;
00186
00187
00188 initialize();
00189
00190 if (!isInstalled()) {
00191 QString command = _torPath + " --nt-service -f " + _torrc;
00192
00193 _service = CreateServiceA(_manager, TOR_SERVICE_NAME, TOR_SERVICE_DISP,
00194 TOR_SERVICE_ACCESS, SERVICE_WIN32_OWN_PROCESS,
00195 SERVICE_AUTO_START, SERVICE_ERROR_IGNORE,
00196 command.toAscii().data(), NULL, NULL, NULL, NULL, "");
00197
00198 SERVICE_DESCRIPTION desc;
00199 desc.lpDescription = TOR_SERVICE_DESC;
00200 ChangeServiceConfig2(_service, SERVICE_CONFIG_DESCRIPTION, &desc);
00201 }
00202 return isInstalled();
00203 #else
00204 return false;
00205 #endif
00206 }
00207
00208
00209 bool
00210 TorService::remove()
00211 {
00212 #if defined(Q_OS_WIN32)
00213 if (!isSupported()) return false;
00214 if (isInstalled()) {
00215
00216 stop();
00217
00218
00219 if (!DeleteService(_service)) return false;
00220
00221
00222 close();
00223 }
00224
00225 return !isInstalled();
00226 #else
00227 return false;
00228 #endif
00229 }
00230
00231
00232
00233 DWORD
00234 TorService::status()
00235 {
00236 #if defined(Q_OS_WIN32)
00237 if (!(isSupported() && _manager && _service)) return DWORD(-1);
00238
00239 SERVICE_STATUS s;
00240 DWORD stat = SERVICE_ERROR;
00241
00242 if (QueryServiceStatus(_service, &s)) {
00243 stat = s.dwCurrentState;
00244 }
00245 return stat;
00246 #else
00247 return 0;
00248 #endif
00249 }
00250