00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "CArchDaemonWindows.h"
00020 #include "CArch.h"
00021 #include "CArchMiscWindows.h"
00022 #include "XArchWindows.h"
00023 #include "stdvector.h"
00024
00025
00026
00027
00028
00029 CArchDaemonWindows* CArchDaemonWindows::s_daemon = NULL;
00030
00031 CArchDaemonWindows::CArchDaemonWindows() :
00032 m_daemonThreadID(0)
00033 {
00034 m_quitMessage = RegisterWindowMessage("SynergyDaemonExit");
00035 }
00036
00037 CArchDaemonWindows::~CArchDaemonWindows()
00038 {
00039
00040 }
00041
00042 int
00043 CArchDaemonWindows::runDaemon(RunFunc runFunc)
00044 {
00045 assert(s_daemon != NULL);
00046
00047 return s_daemon->doRunDaemon(runFunc);
00048 }
00049
00050 void
00051 CArchDaemonWindows::daemonRunning(bool running)
00052 {
00053
00054
00055
00056
00057 if (s_daemon != NULL) {
00058 s_daemon->doDaemonRunning(running);
00059 }
00060 }
00061
00062 UINT
00063 CArchDaemonWindows::getDaemonQuitMessage()
00064 {
00065 if (s_daemon != NULL) {
00066 return s_daemon->doGetDaemonQuitMessage();
00067 }
00068 else {
00069 return 0;
00070 }
00071 }
00072
00073 void
00074 CArchDaemonWindows::daemonFailed(int result)
00075 {
00076
00077
00078
00079
00080 if (s_daemon != NULL) {
00081 throw XArchDaemonRunFailed(result);
00082 }
00083 }
00084
00085 void
00086 CArchDaemonWindows::installDaemon(const char* name,
00087 const char* description,
00088 const char* pathname,
00089 const char* commandLine,
00090 const char* dependencies,
00091 bool allUsers)
00092 {
00093
00094
00095 if (!allUsers || CArchMiscWindows::isWindows95Family()) {
00096
00097 HKEY key = (allUsers && CArchMiscWindows::isWindows95Family()) ?
00098 open95ServicesKey() : openUserStartupKey();
00099 if (key == NULL) {
00100
00101 throw XArchDaemonInstallFailed(new XArchEvalWindows);
00102 }
00103
00104
00105 std::string value;
00106 value += "\"";
00107 value += pathname;
00108 value += "\" ";
00109 value += commandLine;
00110
00111
00112 CArchMiscWindows::setValue(key, name, value);
00113
00114
00115 CArchMiscWindows::closeKey(key);
00116 }
00117
00118
00119 else {
00120
00121 SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_WRITE);
00122 if (mgr == NULL) {
00123
00124 throw XArchDaemonInstallFailed(new XArchEvalWindows);
00125 }
00126
00127
00128 SC_HANDLE service = CreateService(mgr,
00129 name,
00130 name,
00131 0,
00132 SERVICE_WIN32_OWN_PROCESS |
00133 SERVICE_INTERACTIVE_PROCESS,
00134 SERVICE_AUTO_START,
00135 SERVICE_ERROR_NORMAL,
00136 pathname,
00137 NULL,
00138 NULL,
00139 dependencies,
00140 NULL,
00141 NULL);
00142 if (service == NULL) {
00143
00144 DWORD err = GetLastError();
00145 if (err != ERROR_SERVICE_EXISTS) {
00146 CloseServiceHandle(mgr);
00147 throw XArchDaemonInstallFailed(new XArchEvalWindows(err));
00148 }
00149 }
00150 else {
00151
00152 CloseServiceHandle(service);
00153 }
00154
00155
00156 CloseServiceHandle(mgr);
00157
00158
00159 HKEY key = openNTServicesKey();
00160 key = CArchMiscWindows::addKey(key, name);
00161 if (key == NULL) {
00162
00163 DWORD err = GetLastError();
00164 try {
00165 uninstallDaemon(name, allUsers);
00166 }
00167 catch (...) {
00168
00169 }
00170 throw XArchDaemonInstallFailed(new XArchEvalWindows(err));
00171 }
00172
00173
00174 CArchMiscWindows::setValue(key, _T("Description"), description);
00175
00176
00177 key = CArchMiscWindows::addKey(key, _T("Parameters"));
00178 if (key == NULL) {
00179
00180 DWORD err = GetLastError();
00181 CArchMiscWindows::closeKey(key);
00182 try {
00183 uninstallDaemon(name, allUsers);
00184 }
00185 catch (...) {
00186
00187 }
00188 throw XArchDaemonInstallFailed(new XArchEvalWindows(err));
00189 }
00190 CArchMiscWindows::setValue(key, _T("CommandLine"), commandLine);
00191
00192
00193 CArchMiscWindows::closeKey(key);
00194 }
00195 }
00196
00197 void
00198 CArchDaemonWindows::uninstallDaemon(const char* name, bool allUsers)
00199 {
00200
00201
00202 if (!allUsers || CArchMiscWindows::isWindows95Family()) {
00203
00204 HKEY key = (allUsers && CArchMiscWindows::isWindows95Family()) ?
00205 open95ServicesKey() : openUserStartupKey();
00206 if (key == NULL) {
00207
00208 throw XArchDaemonUninstallNotInstalled(new XArchEvalWindows);
00209 }
00210
00211
00212 CArchMiscWindows::deleteValue(key, name);
00213
00214
00215 CArchMiscWindows::closeKey(key);
00216 }
00217
00218
00219 else {
00220
00221 HKEY key = openNTServicesKey();
00222 key = CArchMiscWindows::openKey(key, name);
00223 if (key != NULL) {
00224 CArchMiscWindows::deleteKey(key, _T("Parameters"));
00225 CArchMiscWindows::closeKey(key);
00226 }
00227
00228
00229 SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_WRITE);
00230 if (mgr == NULL) {
00231
00232 throw XArchDaemonUninstallFailed(new XArchEvalWindows);
00233 }
00234
00235
00236 SC_HANDLE service = OpenService(mgr, name, DELETE | SERVICE_STOP);
00237 if (service == NULL) {
00238 DWORD err = GetLastError();
00239 CloseServiceHandle(mgr);
00240 if (err != ERROR_SERVICE_DOES_NOT_EXIST) {
00241 throw XArchDaemonUninstallFailed(new XArchEvalWindows(err));
00242 }
00243 throw XArchDaemonUninstallNotInstalled(new XArchEvalWindows(err));
00244 }
00245
00246
00247 SERVICE_STATUS status;
00248 ControlService(service, SERVICE_CONTROL_STOP, &status);
00249
00250
00251 const bool okay = (DeleteService(service) == 0);
00252 const DWORD err = GetLastError();
00253
00254
00255 CloseServiceHandle(service);
00256 CloseServiceHandle(mgr);
00257
00258
00259
00260 ARCH->sleep(1);
00261
00262
00263 if (!okay && isDaemonInstalled(name, allUsers)) {
00264 if (err == ERROR_SUCCESS) {
00265
00266
00267
00268 return;
00269 }
00270 if (err == ERROR_IO_PENDING) {
00271
00272 return;
00273 }
00274 if (err != ERROR_SERVICE_MARKED_FOR_DELETE) {
00275 throw XArchDaemonUninstallFailed(new XArchEvalWindows(err));
00276 }
00277 throw XArchDaemonUninstallNotInstalled(new XArchEvalWindows(err));
00278 }
00279 }
00280 }
00281
00282 int
00283 CArchDaemonWindows::daemonize(const char* name, DaemonFunc func)
00284 {
00285 assert(name != NULL);
00286 assert(func != NULL);
00287
00288
00289 if (CArchMiscWindows::isWindows95Family()) {
00290 typedef DWORD (WINAPI *RegisterServiceProcessT)(DWORD, DWORD);
00291
00292
00293
00294 HINSTANCE kernel = LoadLibrary("kernel32.dll");
00295 if (kernel == NULL) {
00296 throw XArchDaemonFailed(new XArchEvalWindows);
00297 }
00298 RegisterServiceProcessT RegisterServiceProcess =
00299 reinterpret_cast<RegisterServiceProcessT>(
00300 GetProcAddress(kernel,
00301 "RegisterServiceProcess"));
00302 if (RegisterServiceProcess == NULL) {
00303
00304 DWORD err = GetLastError();
00305 FreeLibrary(kernel);
00306 throw XArchDaemonFailed(new XArchEvalWindows(err));
00307 }
00308 if (RegisterServiceProcess(0, 1) == 0) {
00309
00310 DWORD err = GetLastError();
00311 FreeLibrary(kernel);
00312 throw XArchDaemonFailed(new XArchEvalWindows(err));
00313 }
00314 FreeLibrary(kernel);
00315
00316
00317 return func(1, &name);
00318 }
00319
00320
00321 else {
00322
00323 m_daemonFunc = func;
00324
00325
00326 SERVICE_TABLE_ENTRY entry[2];
00327 entry[0].lpServiceName = const_cast<char*>(name);
00328 entry[0].lpServiceProc = &CArchDaemonWindows::serviceMainEntry;
00329 entry[1].lpServiceName = NULL;
00330 entry[1].lpServiceProc = NULL;
00331
00332
00333
00334 s_daemon = this;
00335 if (StartServiceCtrlDispatcher(entry) == 0) {
00336
00337 s_daemon = NULL;
00338 throw XArchDaemonFailed(new XArchEvalWindows);
00339 }
00340
00341 s_daemon = NULL;
00342 return m_daemonResult;
00343 }
00344 }
00345
00346 bool
00347 CArchDaemonWindows::canInstallDaemon(const char* , bool allUsers)
00348 {
00349
00350
00351 if (!allUsers || CArchMiscWindows::isWindows95Family()) {
00352
00353 HKEY key = (allUsers && CArchMiscWindows::isWindows95Family()) ?
00354 open95ServicesKey() : openUserStartupKey();
00355 CArchMiscWindows::closeKey(key);
00356 return (key != NULL);
00357 }
00358
00359
00360 else {
00361
00362 SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_WRITE);
00363 if (mgr == NULL) {
00364 return false;
00365 }
00366 CloseServiceHandle(mgr);
00367
00368
00369 HKEY key = openNTServicesKey();
00370
00371
00372 CArchMiscWindows::closeKey(key);
00373
00374 return (key != NULL);
00375 }
00376 }
00377
00378 bool
00379 CArchDaemonWindows::isDaemonInstalled(const char* name, bool allUsers)
00380 {
00381
00382 SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_READ);
00383 if (mgr == NULL) {
00384 return false;
00385 }
00386
00387
00388 SC_HANDLE service = OpenService(mgr, name, GENERIC_READ);
00389
00390
00391 if (service != NULL) {
00392 CloseServiceHandle(service);
00393 }
00394 CloseServiceHandle(mgr);
00395
00396 return (service != NULL);
00397 }
00398
00399 HKEY
00400 CArchDaemonWindows::openNTServicesKey()
00401 {
00402 static const char* s_keyNames[] = {
00403 _T("SYSTEM"),
00404 _T("CurrentControlSet"),
00405 _T("Services"),
00406 NULL
00407 };
00408
00409 return CArchMiscWindows::addKey(HKEY_LOCAL_MACHINE, s_keyNames);
00410 }
00411
00412 HKEY
00413 CArchDaemonWindows::open95ServicesKey()
00414 {
00415 static const char* s_keyNames[] = {
00416 _T("Software"),
00417 _T("Microsoft"),
00418 _T("Windows"),
00419 _T("CurrentVersion"),
00420 _T("RunServices"),
00421 NULL
00422 };
00423
00424 return CArchMiscWindows::addKey(HKEY_LOCAL_MACHINE, s_keyNames);
00425 }
00426
00427 HKEY
00428 CArchDaemonWindows::openUserStartupKey()
00429 {
00430 static const char* s_keyNames[] = {
00431 _T("Software"),
00432 _T("Microsoft"),
00433 _T("Windows"),
00434 _T("CurrentVersion"),
00435 _T("Run"),
00436 NULL
00437 };
00438
00439 return CArchMiscWindows::addKey(HKEY_CURRENT_USER, s_keyNames);
00440 }
00441
00442 bool
00443 CArchDaemonWindows::isRunState(DWORD state)
00444 {
00445 switch (state) {
00446 case SERVICE_START_PENDING:
00447 case SERVICE_CONTINUE_PENDING:
00448 case SERVICE_RUNNING:
00449 return true;
00450
00451 default:
00452 return false;
00453 }
00454 }
00455
00456 int
00457 CArchDaemonWindows::doRunDaemon(RunFunc run)
00458 {
00459
00460 assert(m_serviceMutex != NULL);
00461 assert(run != NULL);
00462
00463
00464 MSG dummy;
00465 PeekMessage(&dummy, NULL, 0, 0, PM_NOREMOVE);
00466
00467 int result = 0;
00468 ARCH->lockMutex(m_serviceMutex);
00469 m_daemonThreadID = GetCurrentThreadId();
00470 while (m_serviceState != SERVICE_STOPPED) {
00471
00472 while (!isRunState(m_serviceState) &&
00473 m_serviceState != SERVICE_STOP_PENDING) {
00474 ARCH->waitCondVar(m_serviceCondVar, m_serviceMutex, -1.0);
00475 }
00476
00477
00478 if (m_serviceState != SERVICE_STOP_PENDING) {
00479 ARCH->unlockMutex(m_serviceMutex);
00480 try {
00481 result = run();
00482 }
00483 catch (...) {
00484 ARCH->lockMutex(m_serviceMutex);
00485 setStatusError(0);
00486 m_serviceState = SERVICE_STOPPED;
00487 setStatus(m_serviceState);
00488 ARCH->broadcastCondVar(m_serviceCondVar);
00489 ARCH->unlockMutex(m_serviceMutex);
00490 throw;
00491 }
00492 ARCH->lockMutex(m_serviceMutex);
00493 }
00494
00495
00496 if (m_serviceState == SERVICE_PAUSE_PENDING) {
00497 m_serviceState = SERVICE_PAUSED;
00498 }
00499 else {
00500 m_serviceState = SERVICE_STOPPED;
00501 }
00502 setStatus(m_serviceState);
00503 ARCH->broadcastCondVar(m_serviceCondVar);
00504 }
00505 ARCH->unlockMutex(m_serviceMutex);
00506 return result;
00507 }
00508
00509 void
00510 CArchDaemonWindows::doDaemonRunning(bool running)
00511 {
00512 ARCH->lockMutex(m_serviceMutex);
00513 if (running) {
00514 m_serviceState = SERVICE_RUNNING;
00515 setStatus(m_serviceState);
00516 ARCH->broadcastCondVar(m_serviceCondVar);
00517 }
00518 ARCH->unlockMutex(m_serviceMutex);
00519 }
00520
00521 UINT
00522 CArchDaemonWindows::doGetDaemonQuitMessage()
00523 {
00524 return m_quitMessage;
00525 }
00526
00527 void
00528 CArchDaemonWindows::setStatus(DWORD state)
00529 {
00530 setStatus(state, 0, 0);
00531 }
00532
00533 void
00534 CArchDaemonWindows::setStatus(DWORD state, DWORD step, DWORD waitHint)
00535 {
00536 assert(s_daemon != NULL);
00537
00538 SERVICE_STATUS status;
00539 status.dwServiceType = SERVICE_WIN32_OWN_PROCESS |
00540 SERVICE_INTERACTIVE_PROCESS;
00541 status.dwCurrentState = state;
00542 status.dwControlsAccepted = SERVICE_ACCEPT_STOP |
00543 SERVICE_ACCEPT_PAUSE_CONTINUE |
00544 SERVICE_ACCEPT_SHUTDOWN;
00545 status.dwWin32ExitCode = NO_ERROR;
00546 status.dwServiceSpecificExitCode = 0;
00547 status.dwCheckPoint = step;
00548 status.dwWaitHint = waitHint;
00549 SetServiceStatus(s_daemon->m_statusHandle, &status);
00550 }
00551
00552 void
00553 CArchDaemonWindows::setStatusError(DWORD error)
00554 {
00555 assert(s_daemon != NULL);
00556
00557 SERVICE_STATUS status;
00558 status.dwServiceType = SERVICE_WIN32_OWN_PROCESS |
00559 SERVICE_INTERACTIVE_PROCESS;
00560 status.dwCurrentState = SERVICE_STOPPED;
00561 status.dwControlsAccepted = SERVICE_ACCEPT_STOP |
00562 SERVICE_ACCEPT_PAUSE_CONTINUE |
00563 SERVICE_ACCEPT_SHUTDOWN;
00564 status.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
00565 status.dwServiceSpecificExitCode = error;
00566 status.dwCheckPoint = 0;
00567 status.dwWaitHint = 0;
00568 SetServiceStatus(s_daemon->m_statusHandle, &status);
00569 }
00570
00571 void
00572 CArchDaemonWindows::serviceMain(DWORD argc, LPTSTR* argvIn)
00573 {
00574 typedef std::vector<LPCTSTR> ArgList;
00575 typedef std::vector<std::string> Arguments;
00576 const char** argv = const_cast<const char**>(argvIn);
00577
00578
00579 m_serviceMutex = ARCH->newMutex();
00580 m_serviceCondVar = ARCH->newCondVar();
00581
00582
00583 m_statusHandle = RegisterServiceCtrlHandler(argv[0],
00584 &CArchDaemonWindows::serviceHandlerEntry);
00585 if (m_statusHandle == 0) {
00586
00587 m_daemonResult = -1;
00588 ARCH->closeCondVar(m_serviceCondVar);
00589 ARCH->closeMutex(m_serviceMutex);
00590 return;
00591 }
00592
00593
00594 m_serviceState = SERVICE_START_PENDING;
00595 setStatus(m_serviceState, 0, 10000);
00596
00597 std::string commandLine;
00598
00599
00600
00601 Arguments args;
00602 ArgList myArgv;
00603 if (argc <= 1) {
00604
00605 HKEY key = openNTServicesKey();
00606 key = CArchMiscWindows::openKey(key, argvIn[0]);
00607 key = CArchMiscWindows::openKey(key, _T("Parameters"));
00608 if (key != NULL) {
00609 commandLine = CArchMiscWindows::readValueString(key,
00610 _T("CommandLine"));
00611 }
00612
00613
00614 if (!commandLine.empty()) {
00615
00616 std::string::size_type i = commandLine.find_first_not_of(" \t");
00617 while (i != std::string::npos && i != commandLine.size()) {
00618
00619 std::string::size_type e;
00620 if (commandLine[i] == '\"') {
00621
00622 ++i;
00623 e = commandLine.find("\"", i);
00624
00625
00626 if (e == std::string::npos ||
00627 (e + 1 != commandLine.size() &&
00628 commandLine[e + 1] != ' ' &&
00629 commandLine[e + 1] != '\t')) {
00630 args.clear();
00631 break;
00632 }
00633
00634
00635 args.push_back(commandLine.substr(i, e - i));
00636 i = e + 1;
00637 }
00638 else {
00639
00640 e = commandLine.find_first_of(" \t", i);
00641 if (e == std::string::npos) {
00642 e = commandLine.size();
00643 }
00644
00645
00646 args.push_back(commandLine.substr(i, e - i));
00647 i = e + 1;
00648 }
00649
00650
00651 i = commandLine.find_first_not_of(" \t", i);
00652 }
00653
00654
00655 myArgv.push_back(argv[0]);
00656
00657
00658 for (size_t j = 0; j < args.size(); ++j) {
00659 myArgv.push_back(args[j].c_str());
00660 }
00661
00662
00663 argc = (DWORD)myArgv.size();
00664 argv = &myArgv[0];
00665 }
00666 }
00667
00668 m_commandLine = commandLine;
00669
00670 try {
00671
00672 m_daemonResult = m_daemonFunc(static_cast<int>(argc), argv);
00673 }
00674 catch (XArchDaemonRunFailed& e) {
00675 setStatusError(e.m_result);
00676 m_daemonResult = -1;
00677 }
00678 catch (...) {
00679 setStatusError(1);
00680 m_daemonResult = -1;
00681 }
00682
00683
00684 ARCH->closeCondVar(m_serviceCondVar);
00685 ARCH->closeMutex(m_serviceMutex);
00686
00687
00688 m_serviceState = SERVICE_STOPPED;
00689 setStatus(m_serviceState, 0, 10000);
00690 }
00691
00692 void WINAPI
00693 CArchDaemonWindows::serviceMainEntry(DWORD argc, LPTSTR* argv)
00694 {
00695 s_daemon->serviceMain(argc, argv);
00696 }
00697
00698 void
00699 CArchDaemonWindows::serviceHandler(DWORD ctrl)
00700 {
00701 assert(m_serviceMutex != NULL);
00702 assert(m_serviceCondVar != NULL);
00703
00704 ARCH->lockMutex(m_serviceMutex);
00705
00706
00707 if (s_daemon == NULL || m_serviceState == SERVICE_STOPPED) {
00708 if (s_daemon != NULL) {
00709 setStatus(m_serviceState);
00710 }
00711 ARCH->unlockMutex(m_serviceMutex);
00712 return;
00713 }
00714
00715 switch (ctrl) {
00716 case SERVICE_CONTROL_PAUSE:
00717 m_serviceState = SERVICE_PAUSE_PENDING;
00718 setStatus(m_serviceState, 0, 5000);
00719 PostThreadMessage(m_daemonThreadID, m_quitMessage, 0, 0);
00720 while (isRunState(m_serviceState)) {
00721 ARCH->waitCondVar(m_serviceCondVar, m_serviceMutex, -1.0);
00722 }
00723 break;
00724
00725 case SERVICE_CONTROL_CONTINUE:
00726
00727 m_serviceState = SERVICE_CONTINUE_PENDING;
00728 setStatus(m_serviceState, 0, 5000);
00729 ARCH->broadcastCondVar(m_serviceCondVar);
00730 break;
00731
00732 case SERVICE_CONTROL_STOP:
00733 case SERVICE_CONTROL_SHUTDOWN:
00734 m_serviceState = SERVICE_STOP_PENDING;
00735 setStatus(m_serviceState, 0, 5000);
00736 PostThreadMessage(m_daemonThreadID, m_quitMessage, 0, 0);
00737 ARCH->broadcastCondVar(m_serviceCondVar);
00738 while (isRunState(m_serviceState)) {
00739 ARCH->waitCondVar(m_serviceCondVar, m_serviceMutex, -1.0);
00740 }
00741 break;
00742
00743 default:
00744
00745
00746
00747 case SERVICE_CONTROL_INTERROGATE:
00748 setStatus(m_serviceState);
00749 break;
00750 }
00751
00752 ARCH->unlockMutex(m_serviceMutex);
00753 }
00754
00755 void WINAPI
00756 CArchDaemonWindows::serviceHandlerEntry(DWORD ctrl)
00757 {
00758 s_daemon->serviceHandler(ctrl);
00759 }
00760
00761 void
00762 CArchDaemonWindows::start(const char* name)
00763 {
00764
00765 SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_READ);
00766 if (mgr == NULL) {
00767 throw XArchDaemonFailed(new XArchEvalWindows());
00768 }
00769
00770
00771 SC_HANDLE service = OpenService(
00772 mgr, name, SERVICE_START);
00773
00774 if (service == NULL) {
00775 CloseServiceHandle(mgr);
00776 throw XArchDaemonFailed(new XArchEvalWindows());
00777 }
00778
00779
00780 if (!StartService(service, 0, NULL)) {
00781 throw XArchDaemonFailed(new XArchEvalWindows());
00782 }
00783 }
00784
00785 void
00786 CArchDaemonWindows::stop(const char* name)
00787 {
00788
00789 SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_READ);
00790 if (mgr == NULL) {
00791 throw XArchDaemonFailed(new XArchEvalWindows());
00792 }
00793
00794
00795 SC_HANDLE service = OpenService(
00796 mgr, name,
00797 SERVICE_STOP | SERVICE_QUERY_STATUS);
00798
00799 if (service == NULL) {
00800 CloseServiceHandle(mgr);
00801 throw XArchDaemonFailed(new XArchEvalWindows());
00802 }
00803
00804
00805 SERVICE_STATUS ss;
00806 if (!ControlService(service, SERVICE_CONTROL_STOP, &ss)) {
00807 DWORD dwErrCode = GetLastError();
00808 if (dwErrCode != ERROR_SERVICE_NOT_ACTIVE) {
00809 throw XArchDaemonFailed(new XArchEvalWindows());
00810 }
00811 }
00812 }
00813
00814 void
00815 CArchDaemonWindows::installDaemon()
00816 {
00817
00818 if (!isDaemonInstalled(DEFAULT_DAEMON_NAME, true)) {
00819 char path[MAX_PATH];
00820 GetModuleFileName(CArchMiscWindows::instanceWin32(), path, MAX_PATH);
00821 installDaemon(DEFAULT_DAEMON_NAME, DEFAULT_DAEMON_INFO, path, "", "", true);
00822 }
00823
00824 start(DEFAULT_DAEMON_NAME);
00825 }
00826
00827 void
00828 CArchDaemonWindows::uninstallDaemon()
00829 {
00830
00831 if (isDaemonInstalled(LEGACY_SERVER_DAEMON_NAME, true)) {
00832 uninstallDaemon(LEGACY_SERVER_DAEMON_NAME, true);
00833 }
00834 if (isDaemonInstalled(LEGACY_CLIENT_DAEMON_NAME, true)) {
00835 uninstallDaemon(LEGACY_CLIENT_DAEMON_NAME, true);
00836 }
00837
00838
00839 if (isDaemonInstalled(DEFAULT_DAEMON_NAME, true)) {
00840 uninstallDaemon(DEFAULT_DAEMON_NAME, true);
00841 }
00842 }