Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(603)

Unified Diff: service/service_main.h

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « service/build.scons ('k') | service/service_main.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: service/service_main.h
diff --git a/service/service_main.h b/service/service_main.h
deleted file mode 100644
index 93b471f5053ae7d57c408a59de66d1257216419c..0000000000000000000000000000000000000000
--- a/service/service_main.h
+++ /dev/null
@@ -1,515 +0,0 @@
-// Copyright 2006-2010 Google Inc.
-//
-// Licensed 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.
-// ========================================================================
-
-// The service is a bootstrap for a local system process to start
-// when the computer starts. The service shuts itself down in 30 seconds.
-//
-// The service can be started in one of two modes:
-// * As a regular service, typically at system startup.
-// * As a COM service, typically by an Omaha client using IGoogleUpdateCore.
-// The COM case is distinguished from the regular service case by registering a
-// ServiceParameters command line in the AppID registration.
-//
-// In all cases, the service initializes COM, and allows for IGoogleUpdateCore
-// clients to connect to the service. In the regular service case, the service
-// shuts down after a small idle check timeout, provided that there are no COM
-// clients connected. In the COM server case, and in the case where there are
-// COM clients connected in the regular service case, the service will shut down
-// when the last client disconnects.
-//
-// To be exact, the service will initiate shutdown in all cases when the ATL
-// module count drops to zero.
-//
-// ATL does not allow for directly reusing the delayed COM shutdown mechanism
-// available for Local servers. The assumption likely being that services run
-// forever. Since we do not want our service to run forever, we override some
-// of the functions to get the same effect.
-
-#ifndef OMAHA_SERVICE_SERVICE_MAIN_H_
-#define OMAHA_SERVICE_SERVICE_MAIN_H_
-
-#include <atlbase.h>
-#include <atlcom.h>
-#include "base/basictypes.h"
-#include "base/scoped_ptr.h"
-#include "omaha/base/atlregmapex.h"
-#include "omaha/base/debug.h"
-// Use client/resource.h because it does not use StringFormatter and some of the
-// strings are only used during Setup, which is part of the client.
-// TODO(omaha3): It is a little unexpected to access strings in a header. It
-// would be nice to avoid that. Also, this file is included by both client
-// (setup_service.cc) and server (goopdate.cc) code.
-#include "omaha/client/resource.h"
-#include "omaha/common/command_line_builder.h"
-#include "omaha/common/const_cmd_line.h"
-#include "omaha/common/const_goopdate.h"
-#include "omaha/common/goopdate_utils.h"
-#include "omaha/core/google_update_core.h"
-#include "omaha/goopdate/google_update3.h"
-#include "omaha/goopdate/non_localized_resource.h"
-#include "omaha/goopdate/ondemand.h"
-#include "omaha/goopdate/update3web.h"
-#include "omaha/goopdate/worker.h"
-#include "omaha/net/network_config.h"
-
-namespace omaha {
-
-class Update3ServiceMode {
- public:
- static CommandLineMode commandline_mode();
- static CString reg_name();
- static CString default_name();
- static DWORD service_start_type();
- static _ATL_OBJMAP_ENTRY* object_map();
- static bool allow_access_from_medium();
- static CString app_id_string();
- static CString GetCurrentServiceName();
- static HRESULT PreMessageLoop();
-};
-
-class UpdateMediumServiceMode {
- public:
- static CommandLineMode commandline_mode();
- static CString reg_name();
- static CString default_name();
- static DWORD service_start_type();
- static _ATL_OBJMAP_ENTRY* object_map();
- static bool allow_access_from_medium();
- static CString app_id_string();
- static CString GetCurrentServiceName();
- static HRESULT PreMessageLoop();
-};
-
-#pragma warning(push)
-// C4640: construction of local static object is not thread-safe
-#pragma warning(disable : 4640)
-
-template <typename T>
-class ServiceModule
- : public CAtlServiceModuleT<ServiceModule<T>, IDS_SERVICE_NAME> {
- public:
- typedef CAtlServiceModuleT<ServiceModule, IDS_SERVICE_NAME> Base;
-
- DECLARE_REGISTRY_APPID_RESOURCEID_EX(IDR_GOOGLE_UPDATE3_SERVICE_APPID,
- T::app_id_string())
-
- BEGIN_REGISTRY_MAP()
- REGMAP_ENTRY(_T("DESCRIPTION"), _T("ServiceModule"))
- REGMAP_ENTRY(_T("FILENAME"), kServiceFileName)
- END_REGISTRY_MAP()
-
- ServiceModule()
- : service_thread_(NULL),
- is_service_com_server_(false) {
- SERVICE_LOG(L1, (_T("[ServiceModule]")));
- _tcscpy(m_szServiceName, T::GetCurrentServiceName());
- }
-
- ~ServiceModule() {
- SERVICE_LOG(L1, (_T("[~ServiceModule]")));
- ASSERT1(!service_thread_);
-
- // ServiceModule is typically created on the stack. We cannot reset the
- // _pAtlModule here, because objects are destroyed at destructor unwind
- // time, and require access to the module.
- }
-
- HRESULT InitializeSecurity() throw() {
- SERVICE_LOG(L3, (_T("[InitializeSecurity]")));
-
- return InitializeServerSecurity(T::allow_access_from_medium());
- }
-
- void ServiceMain(DWORD argc, LPTSTR* argv) throw() {
- ASSERT1(argc <= 2);
- is_service_com_server_ =
- argc == 2 && !CString(argv[1]).CompareNoCase(kCmdLineServiceComServer);
- SERVICE_LOG(L3, (_T("[ServiceMain][is_service_com_server_][%d]"),
- is_service_com_server_));
- Base::ServiceMain(argc, argv);
- }
-
- HRESULT RegisterClassObjects(DWORD class_context,
- DWORD flags) throw() {
- SERVICE_LOG(L3, (_T("[RegisterClassObjects]")));
- for (_ATL_OBJMAP_ENTRY* objmap_entry = T::object_map();
- objmap_entry->pclsid != NULL;
- objmap_entry++) {
- HRESULT hr = objmap_entry->RegisterClassObject(class_context, flags);
- if (FAILED(hr)) {
- SERVICE_LOG(LE, (_T("[RegisterClassObject failed][%s][0x%x]"),
- GuidToString(*objmap_entry->pclsid), hr));
- return hr;
- }
- }
-
- return S_OK;
- }
-
- HRESULT RevokeClassObjects() throw() {
- SERVICE_LOG(L3, (_T("[RevokeClassObjects]")));
- for (_ATL_OBJMAP_ENTRY* objmap_entry = T::object_map();
- objmap_entry->pclsid != NULL;
- objmap_entry++) {
- HRESULT hr = objmap_entry->RevokeClassObject();
- if (FAILED(hr)) {
- SERVICE_LOG(LE, (_T("[RevokeClassObject failed][%s][0x%x]"),
- GuidToString(*objmap_entry->pclsid), hr));
- return hr;
- }
- }
-
- return S_OK;
- }
-
- HRESULT RegisterServer(BOOL, const CLSID* = NULL) throw() {
- SERVICE_LOG(L3, (_T("[RegisterServer]")));
- for (_ATL_OBJMAP_ENTRY* objmap_entry = T::object_map();
- objmap_entry->pclsid != NULL;
- objmap_entry++) {
- HRESULT hr = objmap_entry->pfnUpdateRegistry(TRUE);
- if (FAILED(hr)) {
- SERVICE_LOG(LE, (_T("[pfnUpdateRegistry failed][%s][0x%x]"),
- GuidToString(*objmap_entry->pclsid), hr));
- return hr;
- }
-
- hr = AtlRegisterClassCategoriesHelper(*objmap_entry->pclsid,
- objmap_entry->pfnGetCategoryMap(),
- TRUE);
- if (FAILED(hr)) {
- SERVICE_LOG(LE, (_T("[RegisterServer fail][%s][0x%x]"),
- GuidToString(*objmap_entry->pclsid), hr));
- return hr;
- }
- }
-
- return S_OK;
- }
-
- HRESULT UnregisterServer(BOOL, const CLSID* = NULL) throw() {
- SERVICE_LOG(L3, (_T("[UnregisterServer]")));
- for (_ATL_OBJMAP_ENTRY* objmap_entry = T::object_map();
- objmap_entry->pclsid != NULL;
- objmap_entry++) {
- HRESULT hr = AtlRegisterClassCategoriesHelper(*objmap_entry->pclsid,
- objmap_entry->pfnGetCategoryMap(),
- FALSE);
- if (FAILED(hr)) {
- SERVICE_LOG(LE, (_T("[RegisterServer fail][%s][0x%x]"),
- GuidToString(*objmap_entry->pclsid), hr));
- return hr;
- }
-
- hr = objmap_entry->pfnUpdateRegistry(FALSE);
- if (FAILED(hr)) {
- SERVICE_LOG(LE, (_T("[pfnUpdateRegistry failed][%s][0x%x]"),
- GuidToString(*objmap_entry->pclsid), hr));
- return hr;
- }
- }
-
- return S_OK;
- }
-
- HRESULT RegisterCOMService() {
- SERVICE_LOG(L3, (_T("[RegisterCOMService]")));
- HRESULT hr = UpdateRegistryAppId(TRUE);
- if (FAILED(hr)) {
- SERVICE_LOG(LE, (_T("[UpdateRegistryAppId failed][0x%x]"), hr));
- return hr;
- }
-
- RegKey key_app_id;
- hr = key_app_id.Open(HKEY_CLASSES_ROOT, _T("AppID"), KEY_WRITE);
- if (FAILED(hr)) {
- SERVICE_LOG(LE, (_T("[Could not open HKLM\\AppID][0x%x]"), hr));
- return hr;
- }
-
- RegKey key;
- hr = key.Create(key_app_id.Key(), GetAppIdT());
- if (FAILED(hr)) {
- SERVICE_LOG(LE, (_T("[Fail open HKLM-AppID-%s][0x%x]"), GetAppId(), hr));
- return hr;
- }
-
- // m_szServiceName is set in the constructor.
- hr = key.SetValue(_T("LocalService"), m_szServiceName);
- if (FAILED(hr)) {
- SERVICE_LOG(LE, (_T("[Could not set LocalService value][0x%x]"), hr));
- return hr;
- }
-
- // The SCM will pass this switch to ServiceMain() during COM activation.
- hr = key.SetValue(_T("ServiceParameters"), kCmdLineServiceComServer);
- if (FAILED(hr)) {
- SERVICE_LOG(LE, (_T("[Set ServiceParameters value failed][0x%x]"), hr));
- return hr;
- }
-
- return RegisterServer(FALSE);
- }
-
- HRESULT UnregisterCOMService() {
- SERVICE_LOG(L3, (_T("[UnregisterCOMService]")));
- HRESULT hr = UnregisterServer(FALSE);
- if (FAILED(hr)) {
- SERVICE_LOG(LE, (_T("[UnregisterServer failed][0x%x]"), hr));
- return hr;
- }
-
- return UpdateRegistryAppId(FALSE);
- }
-
- HRESULT PreMessageLoop(int show_cmd) {
- UNREFERENCED_PARAMETER(show_cmd);
-
- SERVICE_LOG(L1, (_T("[PreMessageLoop]")));
-
- m_dwThreadID = ::GetCurrentThreadId();
- service_thread_ = ::OpenThread(SYNCHRONIZE, false, m_dwThreadID);
-
- if (is_service_com_server_) {
- return InitializeCOMServer();
- }
-
- // This is the regular service case. Call T::PreMessageLoop() and exit.
- SetServiceStatus(SERVICE_RUNNING);
-
- HRESULT hr = T::PreMessageLoop();
- if (FAILED(hr)) {
- SERVICE_LOG(LE, (_T("[T::PreMessageLoop() failed][0x%x]"), hr));
- }
-
- SetServiceStatus(SERVICE_STOP_PENDING);
-
- // S_FALSE is returned to exit the service immediately.
- return S_FALSE;
- }
-
- HRESULT PostMessageLoop() {
- SERVICE_LOG(L1, (_T("[PostMessageLoop]")));
-
- if (!is_service_com_server_) {
- return S_OK;
- }
-
- return Base::PostMessageLoop();
- }
-
- int Main(int show_cmd) {
- if (CAtlBaseModule::m_bInitFailed) {
- SERVICE_LOG(LE, (_T("[CAtlBaseModule init failed]")));
- return -1;
- }
-
- return static_cast<int>(Start(show_cmd));
- }
-
- // This is cloned from CAtlExeModuleT.Lock(). The one difference is the call
- // to ::CoAddRefServerProcess(). See the description for Unlock() below for
- // further information.
- virtual LONG Lock() throw() {
- ::CoAddRefServerProcess();
- LONG retval = CComGlobalsThreadModel::Increment(&m_nLockCnt);
- SERVICE_LOG(L3, (_T("[ServiceModule::Lock][%d]"), retval));
- return retval;
- }
-
- // This is cloned from CAtlExeModuleT.Unlock(). The differences are:
- //
- // * the call to ::CoReleaseServerProcess(), to ensure that the class
- // factories are suspended once the lock count drops to zero. This fixes a
- // a race condition where an activation request could come in in the middle
- // of shutting down. This shutdown mechanism works with free threaded servers.
- //
- // There are race issues with the ATL delayed shutdown mechanism, hence the
- // associated code has been eliminated, and we have an assert to make sure
- // m_bDelayShutdown is not set.
- //
- // * the call to "OnStop()" instead of the "::PostThreadMessage(m_dwMainThre".
- // OnStop() correctly sets the service status to SERVICE_STOP_PENDING, and
- // posts a WM_QUIT to the service thread.
- virtual LONG Unlock() throw() {
- ASSERT1(!m_bDelayShutdown);
-
- ::CoReleaseServerProcess();
- LONG retval = CComGlobalsThreadModel::Decrement(&m_nLockCnt);
- SERVICE_LOG(L3, (_T("[ServiceModule::Unlock][%d]"), retval));
-
- if (retval == 0) {
- OnStop();
- }
-
- return retval;
- }
-
- // This is cloned from CAtlExeModuleT.MonitorShutdown(). The only difference
- // is the call to "OnStop()" instead of the
- // "::PostThreadMessage(m_dwMainThreadID".
- void MonitorShutdown() throw() {
- SERVICE_LOG(L3, (_T("[MonitorShutdown]")));
-
- while (true) {
- ::WaitForSingleObject(m_hEventShutdown, INFINITE);
- SERVICE_LOG(L4, (_T("[Infinite Wait][%d][%d]"), m_bActivity, m_nLockCnt));
-
- DWORD wait = 0;
- do {
- m_bActivity = false;
- wait = ::WaitForSingleObject(m_hEventShutdown, m_dwTimeOut);
- } while (wait == WAIT_OBJECT_0);
-
- SERVICE_LOG(L4, (_T("[MonitorShutdown][%d][%d]"),
- m_bActivity, m_nLockCnt));
- if (!m_bActivity && m_nLockCnt == 0) {
- ::CoSuspendClassObjects();
- if (m_nLockCnt == 0) {
- break;
- }
- }
- }
-
- ::CloseHandle(m_hEventShutdown);
- OnStop();
- }
-
- // This is cloned from CAtlExeModuleT.StartMonitor().
- HANDLE StartMonitor() throw() {
- SERVICE_LOG(L3, (_T("[StartMonitor]")));
- m_hEventShutdown = ::CreateEvent(NULL, false, false, NULL);
- if (m_hEventShutdown == NULL) {
- return NULL;
- }
-
- DWORD thread_id(0);
- HANDLE monitor = ::CreateThread(NULL, 0, MonitorProc, this, 0, &thread_id);
- if (monitor == NULL) {
- ::CloseHandle(m_hEventShutdown);
- }
-
- return monitor;
- }
-
- // This is cloned from CAtlExeModuleT.MonitorProc().
- static DWORD WINAPI MonitorProc(void* pv) throw() {
- SERVICE_LOG(L3, (_T("[MonitorProc]")));
- ServiceModule* service_module = static_cast<ServiceModule*>(pv);
- ASSERT1(service_module);
-
- service_module->MonitorShutdown();
- return 0;
- }
-
- private:
- // Should only be called from the client, such as during Setup, since it only
- // supports one language.
- // Assumes the resources have been loaded.
- static CString GetServiceDescription() {
- CString company_name;
- VERIFY1(company_name.LoadString(IDS_FRIENDLY_COMPANY_NAME));
- CString description;
- description.FormatMessage(IDS_SERVICE_DESCRIPTION, company_name);
- return description;
- }
-
- HRESULT InitializeCOMServer() {
- SERVICE_LOG(L1, (_T("[InitializeCOMServer]")));
-
- // Initialize COM security right at the beginning, because Worker
- // initialization can cause interface marshaling. The first few lines below
- // are adapted from the beginning of CAtlServiceModuleT::PreMessageLoop().
- ASSERT1(m_bService);
- HRESULT hr = InitializeSecurity();
- if (FAILED(hr)) {
- return hr;
- }
-
- DisableCOMExceptionHandling();
-
- NetworkConfigManager::set_is_machine(true);
-
- // Create NetworkConfigManager singleton by referencing it.
- NetworkConfigManager::Instance();
-
- // Register and resume the COM class objects. We call the CAtlExeModuleT
- // member instead of CAtlServiceModuleT, because the latter also tries to
- // initialize security, which we have already done above.
- return CAtlExeModuleT<ServiceModule>::PreMessageLoop(SW_HIDE);
- }
-
- // When Start executes, it blocks on StartServiceCtrlDispatcher.
- // Internally, the SCM creates a service thread which starts executing code
- // specified by SERVICE_TABLE_ENTRY. The ATL code then calls PreMessageLoop
- // and PostMessageLoop on this thread. When the service stops, the execution
- // flow returns from StartServiceCtrlDispatcher and the main thread blocks
- // waiting on the service thread to exit.
- // Before synchronizing the main thread and the service thread, race condition
- // resulted in http://b/1134747.
- HRESULT Start(int show_cmd) {
- SERVICE_LOG(L1, (_T("[Start]")));
- UNREFERENCED_PARAMETER(show_cmd);
-
- SERVICE_TABLE_ENTRY st[] = {
- { m_szServiceName, Base::_ServiceMain },
- { NULL, NULL }
- };
-
- m_status.dwWin32ExitCode = 0;
- if (!::StartServiceCtrlDispatcher(st)) {
- m_status.dwWin32ExitCode = ::GetLastError();
- }
-
- if (service_thread_) {
- DWORD result(::WaitForSingleObject(service_thread_, kShutdownIntervalMs));
- ASSERT1(result == WAIT_OBJECT_0);
- ::CloseHandle(service_thread_);
- service_thread_ = NULL;
- }
-
- return m_status.dwWin32ExitCode;
- }
-
- HANDLE service_thread_; // The service thread provided by the SCM.
- bool is_service_com_server_; // True if the service is being invoked by COM.
-
- // Service shut down wait timeout. The main thread waits for the service
- // thread to exit, after the service stops.
- static const DWORD kShutdownIntervalMs = 1000L * 30; // 30 seconds.
-
- // Service idle check timeout. The service shuts down itself after startup.
- static const DWORD kIdleCheckIntervalMs = 1000L * 30; // 30 seconds.
-
- // Service failover constants.
- //
- // Time after which the SCM resets the failure count to zero if there are
- // no failures.
- static const DWORD kResetPeriodSec = 60 * 60 * 24; // 1 day.
-
- // Time to wait before performing the specified action.
- static const DWORD kActionDelayMs = 1000L * 60 * 15; // 15 minutes.
-
- DISALLOW_EVIL_CONSTRUCTORS(ServiceModule);
-};
-
-#pragma warning(pop)
-
-typedef ServiceModule<Update3ServiceMode> Update3ServiceModule;
-typedef ServiceModule<UpdateMediumServiceMode> UpdateMediumServiceModule;
-
-} // namespace omaha
-
-#endif // OMAHA_SERVICE_SERVICE_MAIN_H_
« no previous file with comments | « service/build.scons ('k') | service/service_main.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698