diff options
22 files changed, 454 insertions, 402 deletions
diff --git a/qpid/cpp/src/posix/QpiddBroker.cpp b/qpid/cpp/src/posix/QpiddBroker.cpp index 1cebcfc3ac..694751c27c 100644 --- a/qpid/cpp/src/posix/QpiddBroker.cpp +++ b/qpid/cpp/src/posix/QpiddBroker.cpp @@ -31,10 +31,11 @@ #include <unistd.h> #include <sys/utsname.h> -using namespace std; -using namespace qpid; -using qpid::broker::Broker; -using qpid::broker::Daemon; +using std::cout; +using std::endl; + +namespace qpid { +namespace broker { BootstrapOptions::BootstrapOptions(const char* argv0) : qpid::Options("Options"), @@ -197,7 +198,9 @@ int QpiddBroker::execute (QpiddOptions *options) { return 0; } +}} // namespace qpid::Broker + int main(int argc, char* argv[]) { - return run_broker(argc, argv); + return qpid::broker::run_broker(argc, argv); } diff --git a/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp b/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp index f183ff8e0c..3f854c7510 100644 --- a/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp +++ b/qpid/cpp/src/qpid/agent/ManagementAgentImpl.cpp @@ -31,9 +31,11 @@ #include <fstream> #include <boost/lexical_cast.hpp> +namespace qpid { +namespace management { + using namespace qpid::client; using namespace qpid::framing; -using namespace qpid::management; using namespace qpid::sys; using namespace std; using std::stringstream; @@ -1260,7 +1262,7 @@ void ManagementAgentImpl::ConnectionThread::run() int totalSleep = 0; do { sys::Mutex::ScopedUnlock _unlock(connLock); - ::sleep(delayMin); + qpid::sys::sleep(delayMin); totalSleep += delayMin; } while (totalSleep < delay && !shutdown); sleeping = false; @@ -1396,8 +1398,10 @@ void ManagementAgentImpl::PublishThread::run() sleepTime = 1; while (totalSleep < agent.getInterval() && !shutdown) { - ::sleep(sleepTime); + qpid::sys::sleep(sleepTime); totalSleep += sleepTime; } } } + +}}
\ No newline at end of file diff --git a/qpid/cpp/src/qpid/broker/Exchange.cpp b/qpid/cpp/src/qpid/broker/Exchange.cpp index f311b79578..ad688ba314 100644 --- a/qpid/cpp/src/qpid/broker/Exchange.cpp +++ b/qpid/cpp/src/qpid/broker/Exchange.cpp @@ -32,7 +32,9 @@ #include "qpid/sys/ExceptionHolder.h" #include <stdexcept> -using namespace qpid::broker; +namespace qpid { +namespace broker { + using namespace qpid::framing; using qpid::framing::Buffer; using qpid::framing::FieldTable; @@ -408,3 +410,5 @@ bool Exchange::routeWithAlternate(Deliverable& msg) } return msg.delivered; } + +}}
\ No newline at end of file diff --git a/qpid/cpp/src/qpid/broker/Queue.cpp b/qpid/cpp/src/qpid/broker/Queue.cpp index 01ce017289..d79e24ee0e 100644 --- a/qpid/cpp/src/qpid/broker/Queue.cpp +++ b/qpid/cpp/src/qpid/broker/Queue.cpp @@ -56,7 +56,9 @@ #include <boost/intrusive_ptr.hpp> -using namespace qpid::broker; +namespace qpid { +namespace broker { + using namespace qpid::sys; using namespace qpid::framing; using qpid::management::ManagementAgent; @@ -1706,3 +1708,5 @@ void Queue::UsageBarrier::destroy() parent.deleted = true; while (count) parent.messageLock.wait(); } + +}}
\ No newline at end of file diff --git a/qpid/cpp/src/qpid/log/posix/SinkOptions.cpp b/qpid/cpp/src/qpid/log/posix/SinkOptions.cpp index ffa7633e3b..8459938e5c 100644 --- a/qpid/cpp/src/qpid/log/posix/SinkOptions.cpp +++ b/qpid/cpp/src/qpid/log/posix/SinkOptions.cpp @@ -30,6 +30,10 @@ using std::string; using qpid::Exception; +namespace qpid { +namespace log { +namespace posix { + namespace { // SyslogFacilities maps from syslog values to the text equivalents. @@ -110,10 +114,6 @@ std::string basename(const std::string path) { } // namespace -namespace qpid { -namespace log { -namespace posix { - std::ostream& operator<<(std::ostream& o, const SyslogFacility& f) { return o << SyslogFacilities().name(f.value); } diff --git a/qpid/cpp/src/qpid/management/ManagementAgent.cpp b/qpid/cpp/src/qpid/management/ManagementAgent.cpp index 8c2cb95faa..cb07d5d047 100644 --- a/qpid/cpp/src/qpid/management/ManagementAgent.cpp +++ b/qpid/cpp/src/qpid/management/ManagementAgent.cpp @@ -44,14 +44,15 @@ #include <sstream> #include <typeinfo> +namespace qpid { +namespace management { + using boost::intrusive_ptr; using qpid::framing::Uuid; using qpid::types::Variant; using qpid::amqp_0_10::MapCodec; using qpid::amqp_0_10::ListCodec; -using qpid::sys::Mutex; using namespace qpid::framing; -using namespace qpid::management; using namespace qpid::broker; using namespace qpid; using namespace std; @@ -2961,9 +2962,6 @@ bool ManagementAgent::moveDeletedObjectsLH() { return !deleteList.empty(); } -namespace qpid { -namespace management { - namespace { QPID_TSS const qpid::broker::ConnectionState* executionContext = 0; } @@ -2977,4 +2975,4 @@ const qpid::broker::ConnectionState* getManagementExecutionContext() return executionContext; } -}} +}}
\ No newline at end of file diff --git a/qpid/cpp/src/qpid/store/MessageStorePlugin.cpp b/qpid/cpp/src/qpid/store/MessageStorePlugin.cpp index 2a8d971987..20231bf910 100644 --- a/qpid/cpp/src/qpid/store/MessageStorePlugin.cpp +++ b/qpid/cpp/src/qpid/store/MessageStorePlugin.cpp @@ -28,6 +28,9 @@ #include "qpid/DataDir.h" #include "qpid/log/Statement.h" +namespace qpid { +namespace store { + /* * The MessageStore pointer given to the Broker points to static storage. * Thus, it cannot be deleted, especially by the broker. To prevent deletion, @@ -42,9 +45,6 @@ namespace { }; } -namespace qpid { -namespace store { - static MessageStorePlugin static_instance_registers_plugin; diff --git a/qpid/cpp/src/qpid/store/ms-clfs/MessageLog.cpp b/qpid/cpp/src/qpid/store/ms-clfs/MessageLog.cpp index 14d63a4cd4..849a0a44e8 100644 --- a/qpid/cpp/src/qpid/store/ms-clfs/MessageLog.cpp +++ b/qpid/cpp/src/qpid/store/ms-clfs/MessageLog.cpp @@ -32,6 +32,10 @@ #include "MessageLog.h" #include "Lsn.h" +namespace qpid { +namespace store { +namespace ms_clfs { + namespace { // Structures that hold log records. Each has a type field at the start. @@ -97,10 +101,6 @@ struct MessageDequeue { } // namespace -namespace qpid { -namespace store { -namespace ms_clfs { - void MessageLog::initialize() { diff --git a/qpid/cpp/src/qpid/store/ms-clfs/TransactionLog.cpp b/qpid/cpp/src/qpid/store/ms-clfs/TransactionLog.cpp index 04780e83e8..0ef046d7c8 100644 --- a/qpid/cpp/src/qpid/store/ms-clfs/TransactionLog.cpp +++ b/qpid/cpp/src/qpid/store/ms-clfs/TransactionLog.cpp @@ -33,6 +33,10 @@ #include "Transaction.h" #include "Lsn.h" +namespace qpid { +namespace store { +namespace ms_clfs { + namespace { // Structures that hold log records. Each has a type field at the start. @@ -95,10 +99,6 @@ struct TransactionDelete { } // namespace -namespace qpid { -namespace store { -namespace ms_clfs { - void TransactionLog::initialize() { diff --git a/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp b/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp index c25159985e..01ff8b6bfa 100644 --- a/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp +++ b/qpid/cpp/src/qpid/sys/posix/AsynchIO.cpp @@ -41,7 +41,9 @@ #include <boost/bind.hpp> #include <boost/lexical_cast.hpp> -using namespace qpid::sys; +namespace qpid { +namespace sys { +namespace posix { namespace { @@ -71,10 +73,6 @@ __thread int64_t threadMaxIoTimeNs = 2 * 1000000; // start at 2ms /* * Asynch Acceptor */ -namespace qpid { -namespace sys { -namespace posix { - class AsynchAcceptor : public qpid::sys::AsynchAcceptor { public: AsynchAcceptor(const Socket& s, AsynchAcceptor::Callback callback); diff --git a/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp b/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp index 73f15617dc..2a7cf16923 100644 --- a/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp +++ b/qpid/cpp/src/qpid/sys/ssl/SslIo.cpp @@ -37,8 +37,9 @@ #include <boost/bind.hpp> -using namespace qpid::sys; -using namespace qpid::sys::ssl; +namespace qpid { +namespace sys { +namespace ssl { namespace { @@ -448,3 +449,5 @@ SecuritySettings SslIO::getSecuritySettings() { settings.authid = socket.getClientAuthId(); return settings; } + +}}} diff --git a/qpid/cpp/src/qpid/sys/windows/Socket.cpp b/qpid/cpp/src/qpid/sys/windows/Socket.cpp index 1fa4768329..b085f67539 100644 --- a/qpid/cpp/src/qpid/sys/windows/Socket.cpp +++ b/qpid/cpp/src/qpid/sys/windows/Socket.cpp @@ -32,6 +32,9 @@ #include <winsock2.h> +namespace qpid { +namespace sys { + // Need to initialize WinSock. Ideally, this would be a singleton or embedded // in some one-time initialization function. I tried boost singleton and could // not get it to compile (and others located in google had the same problem). @@ -76,13 +79,6 @@ protected: static WinSockSetup setup; -} /* namespace */ - -namespace qpid { -namespace sys { - -namespace { - std::string getName(SOCKET fd, bool local) { ::sockaddr_storage name_s; // big enough for any socket address diff --git a/qpid/cpp/src/qpid/sys/windows/SslAsynchIO.cpp b/qpid/cpp/src/qpid/sys/windows/SslAsynchIO.cpp index 11a3389e45..25cc94b290 100644 --- a/qpid/cpp/src/qpid/sys/windows/SslAsynchIO.cpp +++ b/qpid/cpp/src/qpid/sys/windows/SslAsynchIO.cpp @@ -38,6 +38,10 @@ #include <queue> #include <boost/bind.hpp> +namespace qpid { +namespace sys { +namespace windows { + namespace { /* @@ -66,10 +70,6 @@ namespace { }; } -namespace qpid { -namespace sys { -namespace windows { - SslAsynchIO::SslAsynchIO(const qpid::sys::Socket& s, CredHandle hCred, ReadCallback rCb, diff --git a/qpid/cpp/src/qpidd.cpp b/qpid/cpp/src/qpidd.cpp index a0e329ca9d..b5686c6ab8 100644 --- a/qpid/cpp/src/qpidd.cpp +++ b/qpid/cpp/src/qpidd.cpp @@ -29,6 +29,9 @@ #include <memory> using namespace std; +namespace qpid { +namespace broker { + auto_ptr<QpiddOptions> options; // Broker real entry; various system-invoked entrypoints call here. @@ -87,3 +90,4 @@ int run_broker(int argc, char *argv[], bool hidden) } return 1; } +}} diff --git a/qpid/cpp/src/qpidd.h b/qpid/cpp/src/qpidd.h index a3150a2737..f7f84d11da 100644 --- a/qpid/cpp/src/qpidd.h +++ b/qpid/cpp/src/qpidd.h @@ -26,6 +26,9 @@ #include <memory> +namespace qpid { +namespace broker { + // BootstrapOptions is a minimal subset of options used for a pre-parse // of the command line to discover which plugin modules need to be loaded. // The pre-parse is necessary because plugin modules may supply their own @@ -70,4 +73,5 @@ public: // Broker real entry; various system-invoked entrypoints call here. int run_broker(int argc, char *argv[], bool hidden = false); +}} #endif /*!QPID_H*/ diff --git a/qpid/cpp/src/tests/RefCounted.cpp b/qpid/cpp/src/tests/RefCounted.cpp index e4c1da5696..3ac3895322 100644 --- a/qpid/cpp/src/tests/RefCounted.cpp +++ b/qpid/cpp/src/tests/RefCounted.cpp @@ -21,15 +21,15 @@ #include "unit_test.h" +namespace qpid { +namespace tests { + QPID_AUTO_TEST_SUITE(RefCountedTestSuiteTestSuite) using boost::intrusive_ptr; using namespace std; using namespace qpid; -namespace qpid { -namespace tests { - struct CountMe : public RefCounted { static int instances; CountMe() { ++instances; } diff --git a/qpid/cpp/src/tests/StringUtils.cpp b/qpid/cpp/src/tests/StringUtils.cpp index 6a19119288..c50287a4f4 100644 --- a/qpid/cpp/src/tests/StringUtils.cpp +++ b/qpid/cpp/src/tests/StringUtils.cpp @@ -23,9 +23,11 @@ #include "unit_test.h" +namespace qpid { +namespace tests { + QPID_AUTO_TEST_SUITE(StringUtilsTestSuite) -using namespace qpid; using std::string; QPID_AUTO_TEST_CASE(testSplit_general) @@ -75,3 +77,5 @@ QPID_AUTO_TEST_CASE(testSplit_empty) } QPID_AUTO_TEST_SUITE_END() + +}} diff --git a/qpid/cpp/src/tests/qpid-send.cpp b/qpid/cpp/src/tests/qpid-send.cpp index b1213a484f..91eef0cd71 100644 --- a/qpid/cpp/src/tests/qpid-send.cpp +++ b/qpid/cpp/src/tests/qpid-send.cpp @@ -36,15 +36,26 @@ #include <iostream> #include <memory> -using namespace std; -using namespace qpid::messaging; -using namespace qpid::types; - -typedef std::vector<std::string> string_vector; +using std::string; +using std::ios_base; + +using qpid::messaging::Address; +using qpid::messaging::Connection; +using qpid::messaging::Duration; +using qpid::messaging::FailoverUpdates; +using qpid::messaging::Message; +using qpid::messaging::Receiver; +using qpid::messaging::Session; +using qpid::messaging::Sender; +using qpid::types::Exception; +using qpid::types::Uuid; +using qpid::types::Variant; namespace qpid { namespace tests { +typedef std::vector<std::string> string_vector; + struct Options : public qpid::Options { bool help; @@ -223,10 +234,6 @@ const string EOS("eos"); const string SN("sn"); const string TS("ts"); -}} // namespace qpid::tests - -using namespace qpid::tests; - class ContentGenerator { public: virtual ~ContentGenerator() {} @@ -329,6 +336,20 @@ public: } }; +}} // namespace qpid::tests + +using qpid::tests::Options; +using qpid::tests::Reporter; +using qpid::tests::Throughput; +using qpid::tests::ContentGenerator; +using qpid::tests::GroupGenerator; +using qpid::tests::GetlineContentGenerator; +using qpid::tests::MapContentGenerator; +using qpid::tests::FixedContentGenerator; +using qpid::tests::SN; +using qpid::tests::TS; +using qpid::tests::EOS; + int main(int argc, char ** argv) { Connection connection; diff --git a/qpid/cpp/src/tests/testagent.cpp b/qpid/cpp/src/tests/testagent.cpp index 98520b424a..e6010a8e00 100644 --- a/qpid/cpp/src/tests/testagent.cpp +++ b/qpid/cpp/src/tests/testagent.cpp @@ -36,9 +36,12 @@ #include <sstream> +namespace qpid { +namespace tests { + static bool running = true; -using namespace std; +using std::string; using qpid::management::ManagementAgent; using qpid::management::ManagementObject; using qpid::management::Manageable; @@ -191,12 +194,14 @@ int main_int(int argc, char** argv) return 0; } +}} // namespace qpid::tests + int main(int argc, char** argv) { try { - return main_int(argc, argv); + return qpid::tests::main_int(argc, argv); } catch(std::exception& e) { - cerr << "Top Level Exception: " << e.what() << endl; + std::cerr << "Top Level Exception: " << e.what() << std::endl; return 1; } } diff --git a/qpid/cpp/src/tests/windows/DisableWin32ErrorWindows.cpp b/qpid/cpp/src/tests/windows/DisableWin32ErrorWindows.cpp index 024f20b147..14f1e46606 100644 --- a/qpid/cpp/src/tests/windows/DisableWin32ErrorWindows.cpp +++ b/qpid/cpp/src/tests/windows/DisableWin32ErrorWindows.cpp @@ -32,7 +32,9 @@ #include <windows.h> #include <iostream> -namespace { +namespace qpid { +namespace tests { +namespace windows { // Instead of popping up a window for exceptions, just print something out LONG _stdcall UnhandledExceptionFilter (PEXCEPTION_POINTERS pExceptionInfo) @@ -73,4 +75,4 @@ redirect_errors_to_stderr::redirect_errors_to_stderr() SetUnhandledExceptionFilter (&UnhandledExceptionFilter); } -} // namespace +}}} // namespace diff --git a/qpid/cpp/src/windows/QpiddBroker.cpp b/qpid/cpp/src/windows/QpiddBroker.cpp index 42ba97bdb1..e73fcf0af5 100644 --- a/qpid/cpp/src/windows/QpiddBroker.cpp +++ b/qpid/cpp/src/windows/QpiddBroker.cpp @@ -32,7 +32,8 @@ #include <iostream> #include <windows.h> -using namespace qpid::broker; +namespace qpid { +namespace broker { BootstrapOptions::BootstrapOptions(const char* argv0) : qpid::Options("Options"), @@ -451,6 +452,7 @@ int QpiddBroker::execute (QpiddOptions *options) { return 0; } +}} // namespace qpid::broker int main(int argc, char* argv[]) { @@ -459,13 +461,13 @@ int main(int argc, char* argv[]) // the service is stopped. SERVICE_TABLE_ENTRY dispatchTable[] = { - { "", (LPSERVICE_MAIN_FUNCTION)ServiceMain }, + { "", (LPSERVICE_MAIN_FUNCTION)qpid::broker::ServiceMain }, { NULL, NULL } }; if (!StartServiceCtrlDispatcher(dispatchTable)) { DWORD err = ::GetLastError(); if (err == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) // Run as console - return run_broker(argc, argv); + return qpid::broker::run_broker(argc, argv); throw QPID_WINDOWS_ERROR(err); } return 0; diff --git a/qpid/cpp/src/windows/SCM.cpp b/qpid/cpp/src/windows/SCM.cpp index 232bb04c17..2eeb143427 100644 --- a/qpid/cpp/src/windows/SCM.cpp +++ b/qpid/cpp/src/windows/SCM.cpp @@ -1,332 +1,332 @@ -/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-#include "qpid/log/Statement.h"
-#include "qpid/sys/windows/check.h"
-#include "SCM.h"
-
-#pragma comment(lib, "advapi32.lib")
-
-namespace {
-
-// Container that will close a SC_HANDLE upon destruction.
-class AutoServiceHandle {
-public:
- AutoServiceHandle(SC_HANDLE h_ = NULL) : h(h_) {}
- ~AutoServiceHandle() { if (h != NULL) ::CloseServiceHandle(h); }
- void release() { h = NULL; }
- void reset(SC_HANDLE newHandle)
- {
- if (h != NULL)
- ::CloseServiceHandle(h);
- h = newHandle;
- }
- operator SC_HANDLE() const { return h; }
-
-private:
- SC_HANDLE h;
-};
-
-}
-
-namespace qpid {
-namespace windows {
-
-SCM::SCM() : scmHandle(NULL)
-{
-}
-
-SCM::~SCM()
-{
- if (NULL != scmHandle)
- ::CloseServiceHandle(scmHandle);
-}
-
-/**
- * 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");
-}
-
-/**
- *
- */
-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.");
-}
-
-/**
- * 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));
- }
-}
-
-/**
- *
- */
-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."));
-}
-
-/**
- *
- */
-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);
-}
-
-DWORD SCM::waitForStateChangeFrom(SC_HANDLE svc, DWORD originalState)
-{
- SERVICE_STATUS_PROCESS ssStatus;
- DWORD bytesNeeded;
- DWORD waitTime;
- if (!::QueryServiceStatusEx(svc, // handle to service
- SC_STATUS_PROCESS_INFO, // information level
- (LPBYTE)&ssStatus, // address of structure
- sizeof(ssStatus), // size of structure
- &bytesNeeded)) // size needed if buffer is too small
- throw QPID_WINDOWS_ERROR(::GetLastError());
-
- // Save the tick count and initial checkpoint.
- DWORD startTickCount = ::GetTickCount();
- DWORD oldCheckPoint = ssStatus.dwCheckPoint;
-
- // Wait for the service to change out of the noted state.
- while (ssStatus.dwCurrentState == originalState) {
- // Do not wait longer than the wait hint. A good interval is
- // one-tenth of the wait hint but not less than 1 second
- // and not more than 10 seconds.
- waitTime = ssStatus.dwWaitHint / 10;
- if (waitTime < 1000)
- waitTime = 1000;
- else if (waitTime > 10000)
- waitTime = 10000;
-
- ::Sleep(waitTime);
-
- // Check the status until the service is no longer stop pending.
- if (!::QueryServiceStatusEx(svc,
- SC_STATUS_PROCESS_INFO,
- (LPBYTE) &ssStatus,
- sizeof(ssStatus),
- &bytesNeeded))
- throw QPID_WINDOWS_ERROR(::GetLastError());
-
- if (ssStatus.dwCheckPoint > oldCheckPoint) {
- // Continue to wait and check.
- startTickCount = ::GetTickCount();
- oldCheckPoint = ssStatus.dwCheckPoint;
- } else {
- if ((::GetTickCount() - startTickCount) > ssStatus.dwWaitHint)
- break;
- }
- }
- return ssStatus.dwCurrentState;
-}
-
-/**
- * Get the services that depend on @arg svc. All dependent service info
- * is returned in an array of ENUM_SERVICE_STATUS structures via @arg deps.
- *
- * @retval The number of dependent services.
- */
-DWORD SCM::getDependentServices(SC_HANDLE svc,
- std::auto_ptr<ENUM_SERVICE_STATUS>& deps)
-{
- DWORD bytesNeeded;
- DWORD numEntries;
-
- // Pass a zero-length buffer to get the required buffer size.
- if (::EnumDependentServices(svc,
- SERVICE_ACTIVE,
- 0,
- 0,
- &bytesNeeded,
- &numEntries)) {
- // If the Enum call succeeds, then there are no dependent
- // services, so do nothing.
- return 0;
- }
-
- if (::GetLastError() != ERROR_MORE_DATA)
- throw QPID_WINDOWS_ERROR((::GetLastError()));
-
- // Allocate a buffer for the dependencies.
- deps.reset((LPENUM_SERVICE_STATUS)(new char[bytesNeeded]));
- // Enumerate the dependencies.
- if (!::EnumDependentServices(svc,
- SERVICE_ACTIVE,
- deps.get(),
- bytesNeeded,
- &bytesNeeded,
- &numEntries))
- throw QPID_WINDOWS_ERROR((::GetLastError()));
- return numEntries;
-}
-
-} } // namespace qpid::windows
+/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +#include "qpid/log/Statement.h" +#include "qpid/sys/windows/check.h" +#include "SCM.h" + +#pragma comment(lib, "advapi32.lib") + +namespace qpid { +namespace windows { + +namespace { + +// Container that will close a SC_HANDLE upon destruction. +class AutoServiceHandle { +public: + AutoServiceHandle(SC_HANDLE h_ = NULL) : h(h_) {} + ~AutoServiceHandle() { if (h != NULL) ::CloseServiceHandle(h); } + void release() { h = NULL; } + void reset(SC_HANDLE newHandle) + { + if (h != NULL) + ::CloseServiceHandle(h); + h = newHandle; + } + operator SC_HANDLE() const { return h; } + +private: + SC_HANDLE h; +}; + +} + +SCM::SCM() : scmHandle(NULL) +{ +} + +SCM::~SCM() +{ + if (NULL != scmHandle) + ::CloseServiceHandle(scmHandle); +} + +/** + * 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"); +} + +/** + * + */ +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."); +} + +/** + * 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)); + } +} + +/** + * + */ +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.")); +} + +/** + * + */ +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); +} + +DWORD SCM::waitForStateChangeFrom(SC_HANDLE svc, DWORD originalState) +{ + SERVICE_STATUS_PROCESS ssStatus; + DWORD bytesNeeded; + DWORD waitTime; + if (!::QueryServiceStatusEx(svc, // handle to service + SC_STATUS_PROCESS_INFO, // information level + (LPBYTE)&ssStatus, // address of structure + sizeof(ssStatus), // size of structure + &bytesNeeded)) // size needed if buffer is too small + throw QPID_WINDOWS_ERROR(::GetLastError()); + + // Save the tick count and initial checkpoint. + DWORD startTickCount = ::GetTickCount(); + DWORD oldCheckPoint = ssStatus.dwCheckPoint; + + // Wait for the service to change out of the noted state. + while (ssStatus.dwCurrentState == originalState) { + // Do not wait longer than the wait hint. A good interval is + // one-tenth of the wait hint but not less than 1 second + // and not more than 10 seconds. + waitTime = ssStatus.dwWaitHint / 10; + if (waitTime < 1000) + waitTime = 1000; + else if (waitTime > 10000) + waitTime = 10000; + + ::Sleep(waitTime); + + // Check the status until the service is no longer stop pending. + if (!::QueryServiceStatusEx(svc, + SC_STATUS_PROCESS_INFO, + (LPBYTE) &ssStatus, + sizeof(ssStatus), + &bytesNeeded)) + throw QPID_WINDOWS_ERROR(::GetLastError()); + + if (ssStatus.dwCheckPoint > oldCheckPoint) { + // Continue to wait and check. + startTickCount = ::GetTickCount(); + oldCheckPoint = ssStatus.dwCheckPoint; + } else { + if ((::GetTickCount() - startTickCount) > ssStatus.dwWaitHint) + break; + } + } + return ssStatus.dwCurrentState; +} + +/** + * Get the services that depend on @arg svc. All dependent service info + * is returned in an array of ENUM_SERVICE_STATUS structures via @arg deps. + * + * @retval The number of dependent services. + */ +DWORD SCM::getDependentServices(SC_HANDLE svc, + std::auto_ptr<ENUM_SERVICE_STATUS>& deps) +{ + DWORD bytesNeeded; + DWORD numEntries; + + // Pass a zero-length buffer to get the required buffer size. + if (::EnumDependentServices(svc, + SERVICE_ACTIVE, + 0, + 0, + &bytesNeeded, + &numEntries)) { + // If the Enum call succeeds, then there are no dependent + // services, so do nothing. + return 0; + } + + if (::GetLastError() != ERROR_MORE_DATA) + throw QPID_WINDOWS_ERROR((::GetLastError())); + + // Allocate a buffer for the dependencies. + deps.reset((LPENUM_SERVICE_STATUS)(new char[bytesNeeded])); + // Enumerate the dependencies. + if (!::EnumDependentServices(svc, + SERVICE_ACTIVE, + deps.get(), + bytesNeeded, + &bytesNeeded, + &numEntries)) + throw QPID_WINDOWS_ERROR((::GetLastError())); + return numEntries; +} + +} } // namespace qpid::windows |