void
ArchDaemonWindows::uninstallDaemon()
{
	// remove legacy services if installed.
	if (isDaemonInstalled(LEGACY_SERVER_DAEMON_NAME)) {
		uninstallDaemon(LEGACY_SERVER_DAEMON_NAME);
	}
	if (isDaemonInstalled(LEGACY_CLIENT_DAEMON_NAME)) {
		uninstallDaemon(LEGACY_CLIENT_DAEMON_NAME);
	}

	// remove new service if installed.
	if (isDaemonInstalled(DEFAULT_DAEMON_NAME)) {
		uninstallDaemon(DEFAULT_DAEMON_NAME);
	}
}
Exemple #2
0
void
ArchDaemonWindows::uninstallDaemon()
{
    // remove service if installed.
    if (isDaemonInstalled(DEFAULT_DAEMON_NAME)) {
        uninstallDaemon(DEFAULT_DAEMON_NAME);
    }
}
void
ArchDaemonWindows::installDaemon()
{
	// install default daemon if not already installed.
	if (!isDaemonInstalled(DEFAULT_DAEMON_NAME)) {
		char path[MAX_PATH];
		GetModuleFileName(ArchMiscWindows::instanceWin32(), path, MAX_PATH);
		
		// wrap in quotes so a malicious user can't start \Program.exe as admin.
		std::stringstream ss;
		ss << '"';
		ss << path;
		ss << '"';

		installDaemon(DEFAULT_DAEMON_NAME, DEFAULT_DAEMON_INFO, ss.str().c_str(), "", "");
	}

	start(DEFAULT_DAEMON_NAME);
}
void
ArchDaemonWindows::uninstallDaemon(const char* name)
{
	// remove parameters for this service.  ignore failures.
	HKEY key = openNTServicesKey();
	key      = ArchMiscWindows::openKey(key, name);
	if (key != NULL) {
		ArchMiscWindows::deleteKey(key, _T("Parameters"));
		ArchMiscWindows::closeKey(key);
	}

	// open service manager
	SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_WRITE);
	if (mgr == NULL) {
		// can't open service manager
		throw XArchDaemonUninstallFailed(new XArchEvalWindows);
	}

	// open the service.  oddly, you must open a service to delete it.
	SC_HANDLE service = OpenService(mgr, name, DELETE | SERVICE_STOP);
	if (service == NULL) {
		DWORD err = GetLastError();
		CloseServiceHandle(mgr);
		if (err != ERROR_SERVICE_DOES_NOT_EXIST) {
			throw XArchDaemonUninstallFailed(new XArchEvalWindows(err));
		}
		throw XArchDaemonUninstallNotInstalled(new XArchEvalWindows(err));
	}

	// stop the service.  we don't care if we fail.
	SERVICE_STATUS status;
	ControlService(service, SERVICE_CONTROL_STOP, &status);

	// delete the service
	const bool okay = (DeleteService(service) == 0);
	const DWORD err = GetLastError();

	// clean up
	CloseServiceHandle(service);
	CloseServiceHandle(mgr);

	// give windows a chance to remove the service before
	// we check if it still exists.
	ARCH->sleep(1);

	// handle failure.  ignore error if service isn't installed anymore.
	if (!okay && isDaemonInstalled(name)) {
		if (err == ERROR_SUCCESS) {
			// this seems to occur even though the uninstall was successful.
			// it could be a timing issue, i.e., isDaemonInstalled is
			// called too soon. i've added a sleep to try and stop this.
			return;
		}
		if (err == ERROR_IO_PENDING) {
			// this seems to be a spurious error
			return;
		}
		if (err != ERROR_SERVICE_MARKED_FOR_DELETE) {
			throw XArchDaemonUninstallFailed(new XArchEvalWindows(err));
		}
		throw XArchDaemonUninstallNotInstalled(new XArchEvalWindows(err));
	}
}
void
CArchDaemonWindows::uninstallDaemon(const char* name, bool allUsers)
{
	// if not for all users then use the user's autostart registry.
	// key.  if windows 95 family then use windows 95 services key.
	if (!allUsers || CArchMiscWindows::isWindows95Family()) {
		// open registry
		HKEY key = (allUsers && CArchMiscWindows::isWindows95Family()) ?
							open95ServicesKey() : openUserStartupKey();
		if (key == NULL) {
			// can't open key.  daemon is probably not installed.
			throw XArchDaemonUninstallNotInstalled(new XArchEvalWindows);
		}

		// remove entry
		CArchMiscWindows::deleteValue(key, name);

		// clean up
		CArchMiscWindows::closeKey(key);
	}

	// windows NT family services
	else {
		// remove parameters for this service.  ignore failures.
		HKEY key = openNTServicesKey();
		key      = CArchMiscWindows::openKey(key, name);
		if (key != NULL) {
			CArchMiscWindows::deleteKey(key, _T("Parameters"));
			CArchMiscWindows::closeKey(key);
		}

		// open service manager
		SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_WRITE);
		if (mgr == NULL) {
			// can't open service manager
			throw XArchDaemonUninstallFailed(new XArchEvalWindows);
		}

		// open the service.  oddly, you must open a service to delete it.
		SC_HANDLE service = OpenService(mgr, name, DELETE);
		if (service == NULL) {
			DWORD err = GetLastError();
			CloseServiceHandle(mgr);
			if (err != ERROR_SERVICE_DOES_NOT_EXIST) {
				throw XArchDaemonUninstallFailed(new XArchEvalWindows(err));
			}
			throw XArchDaemonUninstallNotInstalled(new XArchEvalWindows(err));
		}

		// delete the service
		const bool okay = (DeleteService(service) == 0);
		const DWORD err = GetLastError();

		// clean up
		CloseServiceHandle(service);
		CloseServiceHandle(mgr);

		// handle failure.  ignore error if service isn't installed anymore.
		if (!okay && isDaemonInstalled(name, allUsers)) {
			if (err != ERROR_SERVICE_MARKED_FOR_DELETE) {
				throw XArchDaemonUninstallFailed(new XArchEvalWindows(err));
			}
			throw XArchDaemonUninstallNotInstalled(new XArchEvalWindows(err));
		}
	}
}