From 23e4309d1bb2912977e3911756580eaaa4005f4d Mon Sep 17 00:00:00 2001 From: "alexeypa@chromium.org" Date: Sat, 25 Feb 2012 01:28:35 +0000 Subject: Renaming remoting_host_service*.* -> host_service*.* to make class names and file names consistent. Review URL: http://codereview.chromium.org/9467018 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@123619 0039d316-1c4b-4281-b951-d872f2087c98 --- remoting/host/host_service.rc | 113 +++++ remoting/host/host_service_resource.h | 21 + remoting/host/host_service_win.cc | 547 +++++++++++++++++++++++++ remoting/host/host_service_win.h | 117 ++++++ remoting/host/remoting_host_service.rc | 113 ----- remoting/host/remoting_host_service_resource.h | 21 - remoting/host/remoting_host_service_win.cc | 547 ------------------------- remoting/host/remoting_host_service_win.h | 117 ------ remoting/remoting.gyp | 8 +- 9 files changed, 802 insertions(+), 802 deletions(-) create mode 100644 remoting/host/host_service.rc create mode 100644 remoting/host/host_service_resource.h create mode 100644 remoting/host/host_service_win.cc create mode 100644 remoting/host/host_service_win.h delete mode 100644 remoting/host/remoting_host_service.rc delete mode 100644 remoting/host/remoting_host_service_resource.h delete mode 100644 remoting/host/remoting_host_service_win.cc delete mode 100644 remoting/host/remoting_host_service_win.h diff --git a/remoting/host/host_service.rc b/remoting/host/host_service.rc new file mode 100644 index 0000000..983c069 --- /dev/null +++ b/remoting/host/host_service.rc @@ -0,0 +1,113 @@ +// Microsoft Visual C++ generated resource script. +// +#include "host_service_resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "host_service_resource.\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "FileDescription", "Chromoting Host Service" + VALUE "FileVersion", "1, 0, 0, 1" + VALUE "InternalName", "remoting_host_service" + VALUE "LegalCopyright", "Copyright (C) 2012 The Chromium Authors. All rights reserved." + VALUE "OriginalFilename", "remoting_host_service.exe" + VALUE "ProductName", "Chromoting Host Service" + VALUE "ProductVersion", "1, 0, 0, 1" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_DISPLAY_SERVICE_NAME "Chromoting Host Service" + IDS_SERVICE_DESCRIPTION "This service enables incoming Chromoting connections." +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/remoting/host/host_service_resource.h b/remoting/host/host_service_resource.h new file mode 100644 index 0000000..82de04d --- /dev/null +++ b/remoting/host/host_service_resource.h @@ -0,0 +1,21 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by host_service.rc +// +#define IDS_DISPLAY_SERVICE_NAME 101 +#define IDS_SERVICE_DESCRIPTION 102 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/remoting/host/host_service_win.cc b/remoting/host/host_service_win.cc new file mode 100644 index 0000000..ef42a7d --- /dev/null +++ b/remoting/host/host_service_win.cc @@ -0,0 +1,547 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// This file implements the Windows service controlling Me2Me host processes +// running within user sessions. + +#include "remoting/host/host_service_win.h" + +#include +#include +#include + +#include "base/at_exit.h" +#include "base/base_paths.h" +#include "base/bind.h" +#include "base/command_line.h" +#include "base/file_path.h" +#include "base/logging.h" +#include "base/message_loop.h" +#include "base/path_service.h" +#include "base/stringprintf.h" +#include "base/utf_string_conversions.h" +#include "base/win/wrapped_window_proc.h" + +#include "remoting/host/host_service_resource.h" +#include "remoting/base/scoped_sc_handle_win.h" +#include "remoting/host/wts_console_observer_win.h" +#include "remoting/host/wts_session_process_launcher_win.h" + +using base::StringPrintf; + +namespace { + +// Service name. +const char kServiceName[] = "chromoting"; +// TODO(alexeypa): investigate and migrate this over to Chrome's i18n framework. +const char kMuiStringFormat[] = "@%ls,-%d"; +const char kServiceDependencies[] = ""; + +const DWORD kServiceStopTimeoutMs = 30 * 1000; + +// Session id that does not represent any session. +const uint32 kInvalidSession = 0xffffffff; + +// A window class for the session change notifications window. +static const char kSessionNotificationWindowClass[] = + "Chromoting_SessionNotificationWindow"; + +// Command line actions and switches: +// "run" sumply runs the service as usual. +const char kRunActionName[] = "run"; + +// "install" requests the service to be installed. +const char kInstallActionName[] = "install"; + +// "remove" uninstalls the service. +const char kRemoveActionName[] = "remove"; + +// "--console" runs the service interactively for debugging purposes. +const char kConsoleSwitchName[] = "console"; + +// "--help" or "--?" prints the usage message. +const char kHelpSwitchName[] = "help"; +const char kQuestionSwitchName[] = "?"; + +const char kUsageMessage[] = + "\n" + "Usage: %s [action] [options]\n" + "\n" + "Actions:\n" + " run - Run the service. If no action specified 'run' is assumed.\n" + " install - Install the service.\n" + " remove - Uninstall the service.\n" + "\n" + "Options:\n" + " --console - Run the service interactively for debugging purposes.\n" + " --help, --? - Print this message.\n"; + +// Exit codes: +const int kSuccessExitCode = 0; +const int kUsageExitCode = 1; +const int kErrorExitCode = 2; + +void usage(const char* program_name) { + fprintf(stderr, kUsageMessage, program_name); +} + +} // namespace + +namespace remoting { + +HostService::HostService() : + console_session_id_(kInvalidSession), + message_loop_(NULL), + run_routine_(&HostService::RunAsService), + service_name_(ASCIIToUTF16(kServiceName)), + service_status_handle_(0), + shutting_down_(false), + stopped_event_(true, false) { +} + +HostService::~HostService() { +} + +void HostService::AddWtsConsoleObserver(WtsConsoleObserver* observer) { + console_observers_.AddObserver(observer); +} + +void HostService::RemoveWtsConsoleObserver(WtsConsoleObserver* observer) { + console_observers_.RemoveObserver(observer); +} + +void HostService::OnSessionChange() { + // WTSGetActiveConsoleSessionId is a very cheap API. It basically reads + // a single value from shared memory. Therefore it is better to check if + // the console session is still the same every time a session change + // notification event is posted. This also takes care of coalescing multiple + // events into one since we look at the latest state. + uint32 console_session_id = kInvalidSession; + if (!shutting_down_) { + console_session_id = WTSGetActiveConsoleSessionId(); + } + if (console_session_id_ != console_session_id) { + if (console_session_id_ != kInvalidSession) { + FOR_EACH_OBSERVER(WtsConsoleObserver, + console_observers_, + OnSessionDetached()); + } + + console_session_id_ = console_session_id; + + if (console_session_id_ != kInvalidSession) { + FOR_EACH_OBSERVER(WtsConsoleObserver, + console_observers_, + OnSessionAttached(console_session_id_)); + } + } +} + +BOOL WINAPI HostService::ConsoleControlHandler(DWORD event) { + HostService* self = HostService::GetInstance(); + switch (event) { + case CTRL_C_EVENT: + case CTRL_BREAK_EVENT: + case CTRL_CLOSE_EVENT: + case CTRL_LOGOFF_EVENT: + case CTRL_SHUTDOWN_EVENT: + self->message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); + self->stopped_event_.Wait(); + return TRUE; + + default: + return FALSE; + } +} + +HostService* HostService::GetInstance() { + return Singleton::get(); +} + +bool HostService::InitWithCommandLine(const CommandLine* command_line) { + CommandLine::StringVector args = command_line->GetArgs(); + + // Choose the action to perform. + if (!args.empty()) { + if (args.size() > 1) { + LOG(ERROR) << "Invalid command line: more than one action requested."; + return false; + } + if (args[0] == ASCIIToUTF16(kInstallActionName)) { + run_routine_ = &HostService::Install; + } else if (args[0] == ASCIIToUTF16(kRemoveActionName)) { + run_routine_ = &HostService::Remove; + } else if (args[0] != ASCIIToUTF16(kRunActionName)) { + LOG(ERROR) << "Invalid command line: invalid action specified: " + << args[0]; + return false; + } + } + + // Run interactively if needed. + if (run_routine_ == &HostService::RunAsService && + command_line->HasSwitch(kConsoleSwitchName)) { + run_routine_ = &HostService::RunInConsole; + } + + return true; +} + +int HostService::Install() { + ScopedScHandle scmanager( + OpenSCManagerW(NULL, NULL, + SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE)); + if (!scmanager.IsValid()) { + LOG_GETLASTERROR(ERROR) + << "Failed to connect to the service control manager"; + return kErrorExitCode; + } + + FilePath exe; + if (!PathService::Get(base::FILE_EXE, &exe)) { + LOG(ERROR) << "Unable to retrieve the service binary path."; + return kErrorExitCode; + } + + string16 name = StringPrintf(ASCIIToUTF16(kMuiStringFormat).c_str(), + exe.value().c_str(), + IDS_DISPLAY_SERVICE_NAME); + ScopedScHandle service( + CreateServiceW(scmanager, + service_name_.c_str(), + name.c_str(), + SERVICE_QUERY_STATUS | SERVICE_CHANGE_CONFIG, + SERVICE_WIN32_OWN_PROCESS, + SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, + exe.value().c_str(), + NULL, + NULL, + ASCIIToUTF16(kServiceDependencies).c_str(), + NULL, + NULL)); + + if (service.IsValid()) { + // Set the service description if the service is freshly installed. + string16 description = StringPrintf( + ASCIIToUTF16(kMuiStringFormat).c_str(), + exe.value().c_str(), + IDS_SERVICE_DESCRIPTION); + + SERVICE_DESCRIPTIONW info; + info.lpDescription = const_cast(description.c_str()); + if (!ChangeServiceConfig2W(service, SERVICE_CONFIG_DESCRIPTION, &info)) { + LOG_GETLASTERROR(ERROR) << "Failed to set the service description"; + return kErrorExitCode; + } + + printf("The service has been installed successfully.\n"); + return kSuccessExitCode; + } else { + if (GetLastError() == ERROR_SERVICE_EXISTS) { + printf("The service is installed already.\n"); + return kSuccessExitCode; + } else { + LOG_GETLASTERROR(ERROR) + << "Failed to create the service"; + return kErrorExitCode; + } + } +} + +VOID CALLBACK HostService::OnServiceStopped(PVOID context) { + SERVICE_NOTIFY* notify = reinterpret_cast(context); + DCHECK(notify != NULL); + DCHECK(notify->dwNotificationStatus == ERROR_SUCCESS); + DCHECK(notify->dwNotificationTriggered == SERVICE_NOTIFY_STOPPED); + DCHECK(notify->ServiceStatus.dwCurrentState == SERVICE_STOPPED); +} + +int HostService::Remove() { + ScopedScHandle scmanager(OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT)); + if (!scmanager.IsValid()) { + LOG_GETLASTERROR(ERROR) + << "Failed to connect to the service control manager"; + return kErrorExitCode; + } + + ScopedScHandle service( + OpenServiceW(scmanager, service_name_.c_str(), + DELETE | SERVICE_STOP | SERVICE_QUERY_STATUS)); + if (!service.IsValid()) { + if (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) { + printf("The service is not installed.\n"); + return kSuccessExitCode; + } else { + LOG_GETLASTERROR(ERROR) << "Failed to open the service"; + return kErrorExitCode; + } + } + + // Register for the service status notifications. The notification is + // going to be delivered even if the service is stopped already. + SERVICE_NOTIFY notify; + ZeroMemory(¬ify, sizeof(notify)); + notify.dwVersion = SERVICE_NOTIFY_STATUS_CHANGE; + notify.pfnNotifyCallback = &HostService::OnServiceStopped; + notify.pContext = this; + + // The notification callback will be unregistered once the service handle + // is closed. + if (ERROR_SUCCESS != NotifyServiceStatusChange( + service, SERVICE_NOTIFY_STOPPED, ¬ify)) { + LOG_GETLASTERROR(ERROR) + << "Failed to register for the service status notifications"; + return kErrorExitCode; + } + + // Ask SCM to stop the service and wait. + SERVICE_STATUS service_status; + if (ControlService(service, SERVICE_CONTROL_STOP, &service_status)) { + printf("Stopping...\n"); + } + + DWORD wait_result = SleepEx(kServiceStopTimeoutMs, TRUE); + if (wait_result != WAIT_IO_COMPLETION) { + LOG(ERROR) << "Failed to stop the service."; + return kErrorExitCode; + } + + // Try to delete the service now. + if (!DeleteService(service)) { + LOG_GETLASTERROR(ERROR) << "Failed to delete the service"; + return kErrorExitCode; + } + + printf("The service has been removed successfully.\n"); + return kSuccessExitCode; +} + +int HostService::Run() { + return (this->*run_routine_)(); +} + +void HostService::RunMessageLoop() { + WtsSessionProcessLauncher launcher(this); + + // Run the service. + message_loop_->Run(); + + // Clean up the observers by emulating detaching from the console. + shutting_down_ = true; + OnSessionChange(); + + // Release the control handler. + stopped_event_.Signal(); +} + +int HostService::RunAsService() { + SERVICE_TABLE_ENTRYW dispatch_table[] = { + { const_cast(service_name_.c_str()), &HostService::ServiceMain }, + { NULL, NULL } + }; + + if (!StartServiceCtrlDispatcherW(dispatch_table)) { + LOG_GETLASTERROR(ERROR) + << "Failed to connect to the service control manager"; + return kErrorExitCode; + } + + return kSuccessExitCode; +} + +int HostService::RunInConsole() { + MessageLoop message_loop(MessageLoop::TYPE_UI); + + // Allow other threads to post to our message loop. + message_loop_ = &message_loop; + + int result = kErrorExitCode; + + // Subscribe to Ctrl-C and other console events. + if (!SetConsoleCtrlHandler(&HostService::ConsoleControlHandler, TRUE)) { + LOG_GETLASTERROR(ERROR) + << "Failed to set console control handler"; + return result; + } + + // Create a window for receiving session change notifications. + LPCWSTR atom = NULL; + HWND window = NULL; + HINSTANCE instance = GetModuleHandle(NULL); + string16 window_class = ASCIIToUTF16(kSessionNotificationWindowClass); + + WNDCLASSEX wc = {0}; + wc.cbSize = sizeof(wc); + wc.lpfnWndProc = base::win::WrappedWindowProc; + wc.hInstance = instance; + wc.lpszClassName = window_class.c_str(); + atom = reinterpret_cast(RegisterClassExW(&wc)); + if (atom == NULL) { + LOG_GETLASTERROR(ERROR) + << "Failed to register the window class '" + << kSessionNotificationWindowClass << "'"; + goto cleanup; + } + + window = CreateWindowW(atom, 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, instance, 0); + if (window == NULL) { + LOG_GETLASTERROR(ERROR) + << "Failed to creat the session notificationwindow"; + goto cleanup; + } + + // Post a dummy session change notification to peek up the current console + // session. + message_loop.PostTask(FROM_HERE, base::Bind( + &HostService::OnSessionChange, base::Unretained(this))); + + // Subscribe to session change notifications. + if (WTSRegisterSessionNotification(window, + NOTIFY_FOR_ALL_SESSIONS) != FALSE) { + // Run the service. + RunMessageLoop(); + + WTSUnRegisterSessionNotification(window); + result = kSuccessExitCode; + } + +cleanup: + if (window != NULL) { + DestroyWindow(window); + } + + if (atom != 0) { + UnregisterClass(atom, instance); + } + + // Unsubscribe from console events. Ignore the exit code. There is nothing + // we can do about it now and the program is about to exit anyway. Even if + // it crashes nothing is going to be broken because of it. + SetConsoleCtrlHandler(&HostService::ConsoleControlHandler, FALSE); + + message_loop_ = NULL; + return result; +} + +DWORD WINAPI HostService::ServiceControlHandler(DWORD control, + DWORD event_type, + LPVOID event_data, + LPVOID context) { + HostService* self = reinterpret_cast(context); + switch (control) { + case SERVICE_CONTROL_INTERROGATE: + return NO_ERROR; + + case SERVICE_CONTROL_SHUTDOWN: + case SERVICE_CONTROL_STOP: + self->message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); + self->stopped_event_.Wait(); + return NO_ERROR; + + case SERVICE_CONTROL_SESSIONCHANGE: + self->message_loop_->PostTask(FROM_HERE, base::Bind( + &HostService::OnSessionChange, base::Unretained(self))); + return NO_ERROR; + + default: + return ERROR_CALL_NOT_IMPLEMENTED; + } +} + +VOID WINAPI HostService::ServiceMain(DWORD argc, WCHAR* argv[]) { + MessageLoop message_loop; + + // Allow other threads to post to our message loop. + HostService* self = HostService::GetInstance(); + self->message_loop_ = &message_loop; + + // Register the service control handler. + self->service_status_handle_ = + RegisterServiceCtrlHandlerExW(self->service_name_.c_str(), + &HostService::ServiceControlHandler, + self); + if (self->service_status_handle_ == 0) { + LOG_GETLASTERROR(ERROR) + << "Failed to register the service control handler"; + return; + } + + // Report running status of the service. + SERVICE_STATUS service_status; + ZeroMemory(&service_status, sizeof(service_status)); + service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + service_status.dwCurrentState = SERVICE_RUNNING; + service_status.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | + SERVICE_ACCEPT_STOP | + SERVICE_ACCEPT_SESSIONCHANGE; + service_status.dwWin32ExitCode = kSuccessExitCode; + + if (!SetServiceStatus(self->service_status_handle_, &service_status)) { + LOG_GETLASTERROR(ERROR) + << "Failed to report service status to the service control manager"; + return; + } + + // Post a dummy session change notification to peek up the current console + // session. + message_loop.PostTask(FROM_HERE, base::Bind( + &HostService::OnSessionChange, base::Unretained(self))); + + // Run the service. + self->RunMessageLoop(); + + // Tell SCM that the service is stopped. + service_status.dwCurrentState = SERVICE_STOPPED; + service_status.dwControlsAccepted = 0; + + if (!SetServiceStatus(self->service_status_handle_, &service_status)) { + LOG_GETLASTERROR(ERROR) + << "Failed to report service status to the service control manager"; + return; + } + + self->message_loop_ = NULL; +} + +LRESULT CALLBACK HostService::SessionChangeNotificationProc(HWND hwnd, + UINT message, + WPARAM wparam, + LPARAM lparam) { + switch (message) { + case WM_WTSSESSION_CHANGE: { + HostService* self = HostService::GetInstance(); + self->OnSessionChange(); + return 0; + } + + default: + return DefWindowProc(hwnd, message, wparam, lparam); + } +} + +} // namespace remoting + +int main(int argc, char** argv) { + CommandLine::Init(argc, argv); + + // This object instance is required by Chrome code (for example, + // FilePath, LazyInstance, MessageLoop). + base::AtExitManager exit_manager; + + const CommandLine* command_line = CommandLine::ForCurrentProcess(); + + if (command_line->HasSwitch(kHelpSwitchName) || + command_line->HasSwitch(kQuestionSwitchName)) { + usage(argv[0]); + return kSuccessExitCode; + } + + remoting::HostService* service = remoting::HostService::GetInstance(); + if (!service->InitWithCommandLine(command_line)) { + usage(argv[0]); + return kUsageExitCode; + } + + return service->Run(); +} diff --git a/remoting/host/host_service_win.h b/remoting/host/host_service_win.h new file mode 100644 index 0000000..48dd1a9 --- /dev/null +++ b/remoting/host/host_service_win.h @@ -0,0 +1,117 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef REMOTING_HOST_HOST_SERVICE_WIN_H_ +#define REMOTING_HOST_HOST_SERVICE_WIN_H_ + +#include + +#include "base/memory/singleton.h" +#include "base/observer_list.h" +#include "base/string16.h" +#include "base/synchronization/waitable_event.h" + +#include "remoting/host/wts_console_monitor_win.h" + +class CommandLine; +class MessageLoop; + +namespace remoting { + +class WtsConsoleObserver; + +class HostService : public WtsConsoleMonitor { + public: + static HostService* GetInstance(); + + // This function parses the command line and selects the action routine. + bool InitWithCommandLine(const CommandLine* command_line); + + // Invoke the choosen action routine. + int Run(); + + // WtsConsoleMonitor implementation + virtual void AddWtsConsoleObserver(WtsConsoleObserver* observer) OVERRIDE; + virtual void RemoveWtsConsoleObserver( + WtsConsoleObserver* observer) OVERRIDE; + + private: + HostService(); + ~HostService(); + + // Notifies the service of changes in session state. + void OnSessionChange(); + + // This routine registers the service with the service control manager. + int Install(); + + // This routine uninstalls the service previously regerested by Install(). + int Remove(); + + // This is a common entry point to the main service loop called by both + // RunAsService() and RunInConsole(). + void RunMessageLoop(); + + // This function handshakes with the service control manager and starts + // the service. + int RunAsService(); + + // This function starts the service in interactive mode (i.e. as a plain + // console application). + int RunInConsole(); + + static BOOL WINAPI ConsoleControlHandler(DWORD event); + static VOID CALLBACK OnServiceStopped(PVOID context); + + // The control handler of the service. + static DWORD WINAPI ServiceControlHandler(DWORD control, + DWORD event_type, + LPVOID event_data, + LPVOID context); + + // The main service entry point. + static VOID WINAPI ServiceMain(DWORD argc, WCHAR* argv[]); + + static LRESULT CALLBACK SessionChangeNotificationProc(HWND hwnd, + UINT message, + WPARAM wparam, + LPARAM lparam); + + // Current physical console session id. + uint32 console_session_id_; + + // The list of observers receiving notifications about any session attached + // to the physical console. + ObserverList console_observers_; + + // Service message loop. + MessageLoop* message_loop_; + + // The action routine to be executed. + int (HostService::*run_routine_)(); + + // The service name. + string16 service_name_; + + // The service status structure. + SERVICE_STATUS service_status_; + + // The service status handle. + SERVICE_STATUS_HANDLE service_status_handle_; + + // True if the service is being stopped. + bool shutting_down_; + + // A waitable event that is used to wait until the service is stopped. + base::WaitableEvent stopped_event_; + + // Singleton. + friend struct DefaultSingletonTraits; + + DISALLOW_COPY_AND_ASSIGN(HostService); +}; + +} // namespace remoting + +#endif // REMOTING_HOST_HOST_SERVICE_WIN_H_ diff --git a/remoting/host/remoting_host_service.rc b/remoting/host/remoting_host_service.rc deleted file mode 100644 index a24db8c..0000000 --- a/remoting/host/remoting_host_service.rc +++ /dev/null @@ -1,113 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "remoting_host_service_resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "remoting_host_service_resource.\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,1 - PRODUCTVERSION 1,0,0,1 - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "FileDescription", "Chromoting Host Service" - VALUE "FileVersion", "1, 0, 0, 1" - VALUE "InternalName", "remoting_host_service" - VALUE "LegalCopyright", "Copyright (C) 2012 The Chromium Authors. All rights reserved." - VALUE "OriginalFilename", "remoting_host_service.exe" - VALUE "ProductName", "Chromoting Host Service" - VALUE "ProductVersion", "1, 0, 0, 1" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE -BEGIN - IDS_DISPLAY_SERVICE_NAME "Chromoting Host Service" - IDS_SERVICE_DESCRIPTION "This service enables incoming Chromoting connections." -END - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/remoting/host/remoting_host_service_resource.h b/remoting/host/remoting_host_service_resource.h deleted file mode 100644 index 36be281..0000000 --- a/remoting/host/remoting_host_service_resource.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by remoting_host_service.rc -// -#define IDS_DISPLAY_SERVICE_NAME 101 -#define IDS_SERVICE_DESCRIPTION 102 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 103 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/remoting/host/remoting_host_service_win.cc b/remoting/host/remoting_host_service_win.cc deleted file mode 100644 index e0ac078..0000000 --- a/remoting/host/remoting_host_service_win.cc +++ /dev/null @@ -1,547 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// This file implements the Windows service controlling Me2Me host processes -// running within user sessions. - -#include "remoting/host/remoting_host_service_win.h" - -#include -#include -#include - -#include "base/at_exit.h" -#include "base/base_paths.h" -#include "base/bind.h" -#include "base/command_line.h" -#include "base/file_path.h" -#include "base/logging.h" -#include "base/message_loop.h" -#include "base/path_service.h" -#include "base/stringprintf.h" -#include "base/utf_string_conversions.h" -#include "base/win/wrapped_window_proc.h" - -#include "remoting/host/remoting_host_service_resource.h" -#include "remoting/base/scoped_sc_handle_win.h" -#include "remoting/host/wts_console_observer_win.h" -#include "remoting/host/wts_session_process_launcher_win.h" - -using base::StringPrintf; - -namespace { - -// Service name. -const char kServiceName[] = "chromoting"; -// TODO(alexeypa): investigate and migrate this over to Chrome's i18n framework. -const char kMuiStringFormat[] = "@%ls,-%d"; -const char kServiceDependencies[] = ""; - -const DWORD kServiceStopTimeoutMs = 30 * 1000; - -// Session id that does not represent any session. -const uint32 kInvalidSession = 0xffffffff; - -// A window class for the session change notifications window. -static const char kSessionNotificationWindowClass[] = - "Chromoting_SessionNotificationWindow"; - -// Command line actions and switches: -// "run" sumply runs the service as usual. -const char kRunActionName[] = "run"; - -// "install" requests the service to be installed. -const char kInstallActionName[] = "install"; - -// "remove" uninstalls the service. -const char kRemoveActionName[] = "remove"; - -// "--console" runs the service interactively for debugging purposes. -const char kConsoleSwitchName[] = "console"; - -// "--help" or "--?" prints the usage message. -const char kHelpSwitchName[] = "help"; -const char kQuestionSwitchName[] = "?"; - -const char kUsageMessage[] = - "\n" - "Usage: %s [action] [options]\n" - "\n" - "Actions:\n" - " run - Run the service. If no action specified 'run' is assumed.\n" - " install - Install the service.\n" - " remove - Uninstall the service.\n" - "\n" - "Options:\n" - " --console - Run the service interactively for debugging purposes.\n" - " --help, --? - Print this message.\n"; - -// Exit codes: -const int kSuccessExitCode = 0; -const int kUsageExitCode = 1; -const int kErrorExitCode = 2; - -void usage(const char* program_name) { - fprintf(stderr, kUsageMessage, program_name); -} - -} // namespace - -namespace remoting { - -HostService::HostService() : - console_session_id_(kInvalidSession), - message_loop_(NULL), - run_routine_(&HostService::RunAsService), - service_name_(ASCIIToUTF16(kServiceName)), - service_status_handle_(0), - shutting_down_(false), - stopped_event_(true, false) { -} - -HostService::~HostService() { -} - -void HostService::AddWtsConsoleObserver(WtsConsoleObserver* observer) { - console_observers_.AddObserver(observer); -} - -void HostService::RemoveWtsConsoleObserver(WtsConsoleObserver* observer) { - console_observers_.RemoveObserver(observer); -} - -void HostService::OnSessionChange() { - // WTSGetActiveConsoleSessionId is a very cheap API. It basically reads - // a single value from shared memory. Therefore it is better to check if - // the console session is still the same every time a session change - // notification event is posted. This also takes care of coalescing multiple - // events into one since we look at the latest state. - uint32 console_session_id = kInvalidSession; - if (!shutting_down_) { - console_session_id = WTSGetActiveConsoleSessionId(); - } - if (console_session_id_ != console_session_id) { - if (console_session_id_ != kInvalidSession) { - FOR_EACH_OBSERVER(WtsConsoleObserver, - console_observers_, - OnSessionDetached()); - } - - console_session_id_ = console_session_id; - - if (console_session_id_ != kInvalidSession) { - FOR_EACH_OBSERVER(WtsConsoleObserver, - console_observers_, - OnSessionAttached(console_session_id_)); - } - } -} - -BOOL WINAPI HostService::ConsoleControlHandler(DWORD event) { - HostService* self = HostService::GetInstance(); - switch (event) { - case CTRL_C_EVENT: - case CTRL_BREAK_EVENT: - case CTRL_CLOSE_EVENT: - case CTRL_LOGOFF_EVENT: - case CTRL_SHUTDOWN_EVENT: - self->message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); - self->stopped_event_.Wait(); - return TRUE; - - default: - return FALSE; - } -} - -HostService* HostService::GetInstance() { - return Singleton::get(); -} - -bool HostService::InitWithCommandLine(const CommandLine* command_line) { - CommandLine::StringVector args = command_line->GetArgs(); - - // Choose the action to perform. - if (!args.empty()) { - if (args.size() > 1) { - LOG(ERROR) << "Invalid command line: more than one action requested."; - return false; - } - if (args[0] == ASCIIToUTF16(kInstallActionName)) { - run_routine_ = &HostService::Install; - } else if (args[0] == ASCIIToUTF16(kRemoveActionName)) { - run_routine_ = &HostService::Remove; - } else if (args[0] != ASCIIToUTF16(kRunActionName)) { - LOG(ERROR) << "Invalid command line: invalid action specified: " - << args[0]; - return false; - } - } - - // Run interactively if needed. - if (run_routine_ == &HostService::RunAsService && - command_line->HasSwitch(kConsoleSwitchName)) { - run_routine_ = &HostService::RunInConsole; - } - - return true; -} - -int HostService::Install() { - ScopedScHandle scmanager( - OpenSCManagerW(NULL, NULL, - SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE)); - if (!scmanager.IsValid()) { - LOG_GETLASTERROR(ERROR) - << "Failed to connect to the service control manager"; - return kErrorExitCode; - } - - FilePath exe; - if (!PathService::Get(base::FILE_EXE, &exe)) { - LOG(ERROR) << "Unable to retrieve the service binary path."; - return kErrorExitCode; - } - - string16 name = StringPrintf(ASCIIToUTF16(kMuiStringFormat).c_str(), - exe.value().c_str(), - IDS_DISPLAY_SERVICE_NAME); - ScopedScHandle service( - CreateServiceW(scmanager, - service_name_.c_str(), - name.c_str(), - SERVICE_QUERY_STATUS | SERVICE_CHANGE_CONFIG, - SERVICE_WIN32_OWN_PROCESS, - SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, - exe.value().c_str(), - NULL, - NULL, - ASCIIToUTF16(kServiceDependencies).c_str(), - NULL, - NULL)); - - if (service.IsValid()) { - // Set the service description if the service is freshly installed. - string16 description = StringPrintf( - ASCIIToUTF16(kMuiStringFormat).c_str(), - exe.value().c_str(), - IDS_SERVICE_DESCRIPTION); - - SERVICE_DESCRIPTIONW info; - info.lpDescription = const_cast(description.c_str()); - if (!ChangeServiceConfig2W(service, SERVICE_CONFIG_DESCRIPTION, &info)) { - LOG_GETLASTERROR(ERROR) << "Failed to set the service description"; - return kErrorExitCode; - } - - printf("The service has been installed successfully.\n"); - return kSuccessExitCode; - } else { - if (GetLastError() == ERROR_SERVICE_EXISTS) { - printf("The service is installed already.\n"); - return kSuccessExitCode; - } else { - LOG_GETLASTERROR(ERROR) - << "Failed to create the service"; - return kErrorExitCode; - } - } -} - -VOID CALLBACK HostService::OnServiceStopped(PVOID context) { - SERVICE_NOTIFY* notify = reinterpret_cast(context); - DCHECK(notify != NULL); - DCHECK(notify->dwNotificationStatus == ERROR_SUCCESS); - DCHECK(notify->dwNotificationTriggered == SERVICE_NOTIFY_STOPPED); - DCHECK(notify->ServiceStatus.dwCurrentState == SERVICE_STOPPED); -} - -int HostService::Remove() { - ScopedScHandle scmanager(OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT)); - if (!scmanager.IsValid()) { - LOG_GETLASTERROR(ERROR) - << "Failed to connect to the service control manager"; - return kErrorExitCode; - } - - ScopedScHandle service( - OpenServiceW(scmanager, service_name_.c_str(), - DELETE | SERVICE_STOP | SERVICE_QUERY_STATUS)); - if (!service.IsValid()) { - if (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) { - printf("The service is not installed.\n"); - return kSuccessExitCode; - } else { - LOG_GETLASTERROR(ERROR) << "Failed to open the service"; - return kErrorExitCode; - } - } - - // Register for the service status notifications. The notification is - // going to be delivered even if the service is stopped already. - SERVICE_NOTIFY notify; - ZeroMemory(¬ify, sizeof(notify)); - notify.dwVersion = SERVICE_NOTIFY_STATUS_CHANGE; - notify.pfnNotifyCallback = &HostService::OnServiceStopped; - notify.pContext = this; - - // The notification callback will be unregistered once the service handle - // is closed. - if (ERROR_SUCCESS != NotifyServiceStatusChange( - service, SERVICE_NOTIFY_STOPPED, ¬ify)) { - LOG_GETLASTERROR(ERROR) - << "Failed to register for the service status notifications"; - return kErrorExitCode; - } - - // Ask SCM to stop the service and wait. - SERVICE_STATUS service_status; - if (ControlService(service, SERVICE_CONTROL_STOP, &service_status)) { - printf("Stopping...\n"); - } - - DWORD wait_result = SleepEx(kServiceStopTimeoutMs, TRUE); - if (wait_result != WAIT_IO_COMPLETION) { - LOG(ERROR) << "Failed to stop the service."; - return kErrorExitCode; - } - - // Try to delete the service now. - if (!DeleteService(service)) { - LOG_GETLASTERROR(ERROR) << "Failed to delete the service"; - return kErrorExitCode; - } - - printf("The service has been removed successfully.\n"); - return kSuccessExitCode; -} - -int HostService::Run() { - return (this->*run_routine_)(); -} - -void HostService::RunMessageLoop() { - WtsSessionProcessLauncher launcher(this); - - // Run the service. - message_loop_->Run(); - - // Clean up the observers by emulating detaching from the console. - shutting_down_ = true; - OnSessionChange(); - - // Release the control handler. - stopped_event_.Signal(); -} - -int HostService::RunAsService() { - SERVICE_TABLE_ENTRYW dispatch_table[] = { - { const_cast(service_name_.c_str()), &HostService::ServiceMain }, - { NULL, NULL } - }; - - if (!StartServiceCtrlDispatcherW(dispatch_table)) { - LOG_GETLASTERROR(ERROR) - << "Failed to connect to the service control manager"; - return kErrorExitCode; - } - - return kSuccessExitCode; -} - -int HostService::RunInConsole() { - MessageLoop message_loop(MessageLoop::TYPE_UI); - - // Allow other threads to post to our message loop. - message_loop_ = &message_loop; - - int result = kErrorExitCode; - - // Subscribe to Ctrl-C and other console events. - if (!SetConsoleCtrlHandler(&HostService::ConsoleControlHandler, TRUE)) { - LOG_GETLASTERROR(ERROR) - << "Failed to set console control handler"; - return result; - } - - // Create a window for receiving session change notifications. - LPCWSTR atom = NULL; - HWND window = NULL; - HINSTANCE instance = GetModuleHandle(NULL); - string16 window_class = ASCIIToUTF16(kSessionNotificationWindowClass); - - WNDCLASSEX wc = {0}; - wc.cbSize = sizeof(wc); - wc.lpfnWndProc = base::win::WrappedWindowProc; - wc.hInstance = instance; - wc.lpszClassName = window_class.c_str(); - atom = reinterpret_cast(RegisterClassExW(&wc)); - if (atom == NULL) { - LOG_GETLASTERROR(ERROR) - << "Failed to register the window class '" - << kSessionNotificationWindowClass << "'"; - goto cleanup; - } - - window = CreateWindowW(atom, 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, instance, 0); - if (window == NULL) { - LOG_GETLASTERROR(ERROR) - << "Failed to creat the session notificationwindow"; - goto cleanup; - } - - // Post a dummy session change notification to peek up the current console - // session. - message_loop.PostTask(FROM_HERE, base::Bind( - &HostService::OnSessionChange, base::Unretained(this))); - - // Subscribe to session change notifications. - if (WTSRegisterSessionNotification(window, - NOTIFY_FOR_ALL_SESSIONS) != FALSE) { - // Run the service. - RunMessageLoop(); - - WTSUnRegisterSessionNotification(window); - result = kSuccessExitCode; - } - -cleanup: - if (window != NULL) { - DestroyWindow(window); - } - - if (atom != 0) { - UnregisterClass(atom, instance); - } - - // Unsubscribe from console events. Ignore the exit code. There is nothing - // we can do about it now and the program is about to exit anyway. Even if - // it crashes nothing is going to be broken because of it. - SetConsoleCtrlHandler(&HostService::ConsoleControlHandler, FALSE); - - message_loop_ = NULL; - return result; -} - -DWORD WINAPI HostService::ServiceControlHandler(DWORD control, - DWORD event_type, - LPVOID event_data, - LPVOID context) { - HostService* self = reinterpret_cast(context); - switch (control) { - case SERVICE_CONTROL_INTERROGATE: - return NO_ERROR; - - case SERVICE_CONTROL_SHUTDOWN: - case SERVICE_CONTROL_STOP: - self->message_loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); - self->stopped_event_.Wait(); - return NO_ERROR; - - case SERVICE_CONTROL_SESSIONCHANGE: - self->message_loop_->PostTask(FROM_HERE, base::Bind( - &HostService::OnSessionChange, base::Unretained(self))); - return NO_ERROR; - - default: - return ERROR_CALL_NOT_IMPLEMENTED; - } -} - -VOID WINAPI HostService::ServiceMain(DWORD argc, WCHAR* argv[]) { - MessageLoop message_loop; - - // Allow other threads to post to our message loop. - HostService* self = HostService::GetInstance(); - self->message_loop_ = &message_loop; - - // Register the service control handler. - self->service_status_handle_ = - RegisterServiceCtrlHandlerExW(self->service_name_.c_str(), - &HostService::ServiceControlHandler, - self); - if (self->service_status_handle_ == 0) { - LOG_GETLASTERROR(ERROR) - << "Failed to register the service control handler"; - return; - } - - // Report running status of the service. - SERVICE_STATUS service_status; - ZeroMemory(&service_status, sizeof(service_status)); - service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; - service_status.dwCurrentState = SERVICE_RUNNING; - service_status.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | - SERVICE_ACCEPT_STOP | - SERVICE_ACCEPT_SESSIONCHANGE; - service_status.dwWin32ExitCode = kSuccessExitCode; - - if (!SetServiceStatus(self->service_status_handle_, &service_status)) { - LOG_GETLASTERROR(ERROR) - << "Failed to report service status to the service control manager"; - return; - } - - // Post a dummy session change notification to peek up the current console - // session. - message_loop.PostTask(FROM_HERE, base::Bind( - &HostService::OnSessionChange, base::Unretained(self))); - - // Run the service. - self->RunMessageLoop(); - - // Tell SCM that the service is stopped. - service_status.dwCurrentState = SERVICE_STOPPED; - service_status.dwControlsAccepted = 0; - - if (!SetServiceStatus(self->service_status_handle_, &service_status)) { - LOG_GETLASTERROR(ERROR) - << "Failed to report service status to the service control manager"; - return; - } - - self->message_loop_ = NULL; -} - -LRESULT CALLBACK HostService::SessionChangeNotificationProc(HWND hwnd, - UINT message, - WPARAM wparam, - LPARAM lparam) { - switch (message) { - case WM_WTSSESSION_CHANGE: { - HostService* self = HostService::GetInstance(); - self->OnSessionChange(); - return 0; - } - - default: - return DefWindowProc(hwnd, message, wparam, lparam); - } -} - -} // namespace remoting - -int main(int argc, char** argv) { - CommandLine::Init(argc, argv); - - // This object instance is required by Chrome code (for example, - // FilePath, LazyInstance, MessageLoop). - base::AtExitManager exit_manager; - - const CommandLine* command_line = CommandLine::ForCurrentProcess(); - - if (command_line->HasSwitch(kHelpSwitchName) || - command_line->HasSwitch(kQuestionSwitchName)) { - usage(argv[0]); - return kSuccessExitCode; - } - - remoting::HostService* service = remoting::HostService::GetInstance(); - if (!service->InitWithCommandLine(command_line)) { - usage(argv[0]); - return kUsageExitCode; - } - - return service->Run(); -} diff --git a/remoting/host/remoting_host_service_win.h b/remoting/host/remoting_host_service_win.h deleted file mode 100644 index 0317f93..0000000 --- a/remoting/host/remoting_host_service_win.h +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef REMOTING_HOST_REMOTING_HOST_SERVICE_WIN_H_ -#define REMOTING_HOST_REMOTING_HOST_SERVICE_WIN_H_ - -#include - -#include "base/memory/singleton.h" -#include "base/observer_list.h" -#include "base/string16.h" -#include "base/synchronization/waitable_event.h" - -#include "remoting/host/wts_console_monitor_win.h" - -class CommandLine; -class MessageLoop; - -namespace remoting { - -class WtsConsoleObserver; - -class HostService : public WtsConsoleMonitor { - public: - static HostService* GetInstance(); - - // This function parses the command line and selects the action routine. - bool InitWithCommandLine(const CommandLine* command_line); - - // Invoke the choosen action routine. - int Run(); - - // WtsConsoleMonitor implementation - virtual void AddWtsConsoleObserver(WtsConsoleObserver* observer) OVERRIDE; - virtual void RemoveWtsConsoleObserver( - WtsConsoleObserver* observer) OVERRIDE; - - private: - HostService(); - ~HostService(); - - // Notifies the service of changes in session state. - void OnSessionChange(); - - // This routine registers the service with the service control manager. - int Install(); - - // This routine uninstalls the service previously regerested by Install(). - int Remove(); - - // This is a common entry point to the main service loop called by both - // RunAsService() and RunInConsole(). - void RunMessageLoop(); - - // This function handshakes with the service control manager and starts - // the service. - int RunAsService(); - - // This function starts the service in interactive mode (i.e. as a plain - // console application). - int RunInConsole(); - - static BOOL WINAPI ConsoleControlHandler(DWORD event); - static VOID CALLBACK OnServiceStopped(PVOID context); - - // The control handler of the service. - static DWORD WINAPI ServiceControlHandler(DWORD control, - DWORD event_type, - LPVOID event_data, - LPVOID context); - - // The main service entry point. - static VOID WINAPI ServiceMain(DWORD argc, WCHAR* argv[]); - - static LRESULT CALLBACK SessionChangeNotificationProc(HWND hwnd, - UINT message, - WPARAM wparam, - LPARAM lparam); - - // Current physical console session id. - uint32 console_session_id_; - - // The list of observers receiving notifications about any session attached - // to the physical console. - ObserverList console_observers_; - - // Service message loop. - MessageLoop* message_loop_; - - // The action routine to be executed. - int (HostService::*run_routine_)(); - - // The service name. - string16 service_name_; - - // The service status structure. - SERVICE_STATUS service_status_; - - // The service status handle. - SERVICE_STATUS_HANDLE service_status_handle_; - - // True if the service is being stopped. - bool shutting_down_; - - // A waitable event that is used to wait until the service is stopped. - base::WaitableEvent stopped_event_; - - // Singleton. - friend struct DefaultSingletonTraits; - - DISALLOW_COPY_AND_ASSIGN(HostService); -}; - -} // namespace remoting - -#endif // REMOTING_HOST_REMOTING_HOST_SERVICE_WIN_H_ diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index 2c5e546..6ea833e 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -232,10 +232,10 @@ 'sources': [ 'base/scoped_sc_handle_win.cc', 'base/scoped_sc_handle_win.h', - 'host/remoting_host_service.rc', - 'host/remoting_host_service_resource.h', - 'host/remoting_host_service_win.cc', - 'host/remoting_host_service_win.h', + 'host/host_service.rc', + 'host/host_service_resource.h', + 'host/host_service_win.cc', + 'host/host_service_win.h', 'host/wts_console_monitor_win.h', 'host/wts_console_observer_win.h', 'host/wts_session_process_launcher_win.cc', -- cgit v1.1