示例#1
0
文件: SCM.cpp 项目: ChugR/qpid-cpp
/**
  * Attempt to start the service.
  */
void SCM::start(const string& serviceName)
{
    // Ensure we have a handle to the SCM database.
    openSvcManager();

    // Get a handle to the service.
    AutoServiceHandle svc(::OpenService(scmHandle,
                                        serviceName.c_str(),
                                        SERVICE_ALL_ACCESS));
    QPID_WINDOWS_CHECK_NULL(svc);

    // Check the status in case the service is not stopped.
    DWORD state = waitForStateChangeFrom(svc, SERVICE_STOP_PENDING);
    if (state == SERVICE_STOP_PENDING)
        throw qpid::Exception("Timed out waiting for running service to stop.");

    // Attempt to start the service.
    QPID_WINDOWS_CHECK_NOT(::StartService(svc, 0, NULL), 0);

    QPID_LOG(info, "Service start pending...");

    // Check the status until the service is no longer start pending.
    state = waitForStateChangeFrom(svc, SERVICE_START_PENDING);
    // Determine whether the service is running.
    if (state == SERVICE_RUNNING) {
        QPID_LOG(info, "Service started successfully");
    }
    else {
        throw qpid::Exception(QPID_MSG("Service not yet running; state now " << state));
    }
}
示例#2
0
文件: SCM.cpp 项目: ChugR/qpid-cpp
void SCM::openSvcManager()
{
    if (NULL != scmHandle)
        return;

    scmHandle = ::OpenSCManager(NULL,    // local computer
                                NULL,    // ServicesActive database
                                SC_MANAGER_ALL_ACCESS); // Rights
    QPID_WINDOWS_CHECK_NULL(scmHandle);
}
示例#3
0
文件: SCM.cpp 项目: ChugR/qpid-cpp
void SCM::uninstall(const string& serviceName)
{
    // Ensure there's a handle to the SCM database.
    openSvcManager();
    AutoServiceHandle svc(::OpenService(scmHandle,
                                        serviceName.c_str(),
                                        DELETE));
    QPID_WINDOWS_CHECK_NULL((SC_HANDLE)svc);
    QPID_WINDOWS_CHECK_NOT(::DeleteService(svc), 0);
    QPID_LOG(info, "Service deleted successfully.");
}
示例#4
0
文件: SCM.cpp 项目: ChugR/qpid-cpp
void SCM::stop(const string& serviceName)
{
    // Ensure a handle to the SCM database.
    openSvcManager();

    // Get a handle to the service.
    AutoServiceHandle svc(::OpenService(scmHandle,
                                        serviceName.c_str(),
                                        SERVICE_STOP | SERVICE_QUERY_STATUS |
                                        SERVICE_ENUMERATE_DEPENDENTS));
    QPID_WINDOWS_CHECK_NULL(svc);

    // Make sure the service is not already stopped; if it's stop-pending,
    // wait for it to finalize.
    DWORD state = waitForStateChangeFrom(svc, SERVICE_STOP_PENDING);
    if (state == SERVICE_STOPPED) {
        QPID_LOG(info, "Service is already stopped");
        return;
    }

    // If the service is running, dependencies must be stopped first.
    std::auto_ptr<ENUM_SERVICE_STATUS> deps;
    DWORD numDeps = getDependentServices(svc, deps);
    for (DWORD i = 0; i < numDeps; i++)
        stop(deps.get()[i].lpServiceName);

    // Dependents stopped; send a stop code to the service.
    SERVICE_STATUS_PROCESS ssp;
    if (!::ControlService(svc, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS)&ssp))
        throw qpid::Exception(QPID_MSG("Stopping " << serviceName << ": " <<
                                       qpid::sys::strError(::GetLastError())));

    // Wait for the service to stop.
    state = waitForStateChangeFrom(svc, SERVICE_STOP_PENDING);
    if (state == SERVICE_STOPPED)
        QPID_LOG(info, QPID_MSG("Service " << serviceName <<
                                " stopped successfully."));
}
示例#5
0
void Poller::monitorHandle(PollerHandle& handle, Direction dir) {
    HANDLE h = (HANDLE)(handle.impl->fd);
    if (h != INVALID_HANDLE_VALUE) {
        HANDLE iocpHandle = ::CreateIoCompletionPort (h, impl->iocp, 0, 0);
        QPID_WINDOWS_CHECK_NULL(iocpHandle);
    }
    else {
        // INPUT is used to request a callback; OUTPUT to request a write
        assert(dir == Poller::INPUT || dir == Poller::OUTPUT);

        if (dir == Poller::OUTPUT) {
            windows::AsynchWriteWanted *result =
                new windows::AsynchWriteWanted(handle.impl->cb);
            PostQueuedCompletionStatus(impl->iocp, 0, 0, result->overlapped());
        }
        else {
            windows::AsynchCallbackRequest *result =
                new windows::AsynchCallbackRequest(handle.impl->cb,
                                                   handle.impl->cbRequest);
            PostQueuedCompletionStatus(impl->iocp, 0, 0, result->overlapped());
        }
    }
}
示例#6
0
文件: SCM.cpp 项目: ChugR/qpid-cpp
/**
  * Install this executable as a service
  */
void SCM::install(const string& serviceName,
                  const string& serviceDesc,
                  const string& args,
                  DWORD startType,
                  const string& account,
                  const string& password,
                  const string& depends)
{
    // Handle dependent service name list; Windows wants a set of nul-separated
    // names ending with a double nul.
    string depends2 = depends;
    if (!depends2.empty()) {
        // CDL to null delimiter w/ trailing double null
        size_t p = 0;
        while ((p = depends2.find_first_of( ',', p)) != string::npos)
            depends2.replace(p, 1, 1, '\0');
        depends2.push_back('\0');
        depends2.push_back('\0');
    }

#if 0
    // I'm nervous about adding a user/password check here. Is this a
    // potential attack vector, letting users check passwords without
    // control?   -Steve Huston, Feb 24, 2011

    // Validate account, password
    HANDLE hToken = NULL;
    bool logStatus = false;
    if (!account.empty() && !password.empty() &&
        !(logStatus = ::LogonUserA(account.c_str(),
                                   "",
                                   password.c_str(),
                                   LOGON32_LOGON_NETWORK,
                                   LOGON32_PROVIDER_DEFAULT,
                                   &hToken ) != 0))
        std::cout << "warning: supplied account & password failed with LogonUser." << std::endl;
    if (logStatus)
        ::CloseHandle(hToken);
#endif

    // Get fully qualified .exe name
    char myPath[MAX_PATH];
    DWORD myPathLength = ::GetModuleFileName(NULL, myPath, MAX_PATH);
    QPID_WINDOWS_CHECK_NOT(myPathLength, 0);
    string imagePath(myPath, myPathLength);
    if (!args.empty())
        imagePath += " " + args;

    // Ensure there's a handle to the SCM database.
    openSvcManager();

    // Create the service
    SC_HANDLE svcHandle;
    svcHandle = ::CreateService(scmHandle,                 // SCM database
                                serviceName.c_str(),       // name of service
                                serviceDesc.c_str(),       // name to display
                                SERVICE_ALL_ACCESS,        // desired access
                                SERVICE_WIN32_OWN_PROCESS, // service type
                                startType,                 // start type
                                SERVICE_ERROR_NORMAL,      // error cntrl type
                                imagePath.c_str(),         // path to service's binary w/ optional arguments
                                NULL,                      // no load ordering group
                                NULL,                      // no tag identifier
                                depends2.empty() ? NULL : depends2.c_str(),
                                account.empty() ? NULL : account.c_str(), // account name, or NULL for LocalSystem
                                password.empty() ? NULL : password.c_str()); // password, or NULL for none
    QPID_WINDOWS_CHECK_NULL(svcHandle);
    ::CloseServiceHandle(svcHandle);
    QPID_LOG(info, "Service installed successfully");
}
示例#7
0
 PollerPrivate() :
     iocp(::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0)),
     threadsRunning(0),
     isShutdown(false) {
     QPID_WINDOWS_CHECK_NULL(iocp);
 }