Win32Main: move to win32/
This commit is contained in:
		
							
								
								
									
										173
									
								
								src/win32/Win32Main.cxx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								src/win32/Win32Main.cxx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,173 @@ | ||||
| /* | ||||
|  * Copyright (C) 2003-2014 The Music Player Daemon Project | ||||
|  * http://www.musicpd.org | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along | ||||
|  * with this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
| #include "Main.hxx" | ||||
|  | ||||
| #ifdef WIN32 | ||||
|  | ||||
| #include "Compiler.h" | ||||
| #include "GlobalEvents.hxx" | ||||
| #include "system/FatalError.hxx" | ||||
|  | ||||
| #include <cstdlib> | ||||
| #include <atomic> | ||||
|  | ||||
| #include <glib.h> | ||||
|  | ||||
| #include <windows.h> | ||||
|  | ||||
| static int service_argc; | ||||
| static char **service_argv; | ||||
| static char service_name[] = ""; | ||||
| static std::atomic_bool running; | ||||
| static SERVICE_STATUS_HANDLE service_handle; | ||||
|  | ||||
| static void WINAPI | ||||
| service_main(DWORD argc, CHAR *argv[]); | ||||
|  | ||||
| static SERVICE_TABLE_ENTRY service_registry[] = { | ||||
| 	{service_name, service_main}, | ||||
| 	{nullptr, nullptr} | ||||
| }; | ||||
|  | ||||
| static void | ||||
| service_notify_status(DWORD status_code) | ||||
| { | ||||
| 	SERVICE_STATUS current_status; | ||||
|  | ||||
| 	current_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; | ||||
| 	current_status.dwControlsAccepted = status_code == SERVICE_START_PENDING | ||||
| 		? 0 | ||||
| 		: SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP; | ||||
|  | ||||
| 	current_status.dwCurrentState = status_code; | ||||
| 	current_status.dwWin32ExitCode = NO_ERROR; | ||||
| 	current_status.dwCheckPoint = 0; | ||||
| 	current_status.dwWaitHint = 1000; | ||||
|  | ||||
| 	SetServiceStatus(service_handle, ¤t_status); | ||||
| } | ||||
|  | ||||
| static DWORD WINAPI | ||||
| service_dispatcher(gcc_unused DWORD control, gcc_unused DWORD event_type, | ||||
| 		   gcc_unused void *event_data, gcc_unused void *context) | ||||
| { | ||||
| 	switch (control) { | ||||
| 	case SERVICE_CONTROL_SHUTDOWN: | ||||
| 	case SERVICE_CONTROL_STOP: | ||||
| 		GlobalEvents::Emit(GlobalEvents::SHUTDOWN); | ||||
| 		return NO_ERROR; | ||||
| 	default: | ||||
| 		return NO_ERROR; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void WINAPI | ||||
| service_main(gcc_unused DWORD argc, gcc_unused CHAR *argv[]) | ||||
| { | ||||
| 	DWORD error_code; | ||||
| 	gchar* error_message; | ||||
|  | ||||
| 	service_handle = | ||||
| 		RegisterServiceCtrlHandlerEx(service_name, | ||||
| 					     service_dispatcher, nullptr); | ||||
|  | ||||
| 	if (service_handle == 0) { | ||||
| 		error_code = GetLastError(); | ||||
| 		error_message = g_win32_error_message(error_code); | ||||
| 		FormatFatalError("RegisterServiceCtrlHandlerEx() failed: %s", | ||||
| 				 error_message); | ||||
| 	} | ||||
|  | ||||
| 	service_notify_status(SERVICE_START_PENDING); | ||||
| 	mpd_main(service_argc, service_argv); | ||||
| 	service_notify_status(SERVICE_STOPPED); | ||||
| } | ||||
|  | ||||
| static BOOL WINAPI | ||||
| console_handler(DWORD event) | ||||
| { | ||||
| 	switch (event) { | ||||
| 	case CTRL_C_EVENT: | ||||
| 	case CTRL_CLOSE_EVENT: | ||||
| 		if (running.load()) { | ||||
| 			// Recent msdn docs that process is terminated | ||||
| 			// if this function returns TRUE. | ||||
| 			// We initiate correct shutdown sequence (if possible). | ||||
| 			// Once main() returns CRT will terminate our process | ||||
| 			// regardless our thread is still active. | ||||
| 			// If this did not happen within 3 seconds | ||||
| 			// let's shutdown anyway. | ||||
| 			GlobalEvents::Emit(GlobalEvents::SHUTDOWN); | ||||
| 			// Under debugger it's better to wait indefinitely | ||||
| 			// to allow debugging of shutdown code. | ||||
| 			Sleep(IsDebuggerPresent() ? INFINITE : 3000); | ||||
| 		} | ||||
| 		// If we're not running main loop there is no chance for | ||||
| 		// clean shutdown. | ||||
| 		std::exit(EXIT_FAILURE); | ||||
| 		return TRUE; | ||||
| 	default: | ||||
| 		return FALSE; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int win32_main(int argc, char *argv[]) | ||||
| { | ||||
| 	DWORD error_code; | ||||
| 	gchar* error_message; | ||||
|  | ||||
| 	service_argc = argc; | ||||
| 	service_argv = argv; | ||||
|  | ||||
| 	if (StartServiceCtrlDispatcher(service_registry)) | ||||
| 		return 0; /* run as service successefully */ | ||||
|  | ||||
| 	error_code = GetLastError(); | ||||
| 	if (error_code == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) { | ||||
| 		/* running as console app */ | ||||
| 		running.store(false); | ||||
| 		SetConsoleTitle("Music Player Daemon"); | ||||
| 		SetConsoleCtrlHandler(console_handler, TRUE); | ||||
| 		return mpd_main(argc, argv); | ||||
| 	} | ||||
|  | ||||
| 	error_message = g_win32_error_message(error_code); | ||||
| 	FormatFatalError("StartServiceCtrlDispatcher() failed: %s", | ||||
| 			 error_message); | ||||
| } | ||||
|  | ||||
| void win32_app_started() | ||||
| { | ||||
| 	if (service_handle != 0) | ||||
| 		service_notify_status(SERVICE_RUNNING); | ||||
| 	else | ||||
| 		running.store(true); | ||||
| } | ||||
|  | ||||
| void win32_app_stopping() | ||||
| { | ||||
| 	if (service_handle != 0) | ||||
| 		service_notify_status(SERVICE_STOP_PENDING); | ||||
| 	else | ||||
| 		running.store(false); | ||||
| } | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										
											BIN
										
									
								
								src/win32/mpd.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/win32/mpd.ico
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 345 KiB | 
							
								
								
									
										34
									
								
								src/win32/mpd_win32_rc.rc.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/win32/mpd_win32_rc.rc.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| #include <windows.h> | ||||
|  | ||||
| #define VERSION_NUMBER @VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_REVISION@,@VERSION_EXTRA@ | ||||
| #define VERSION_NUMBER_STR "@VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_REVISION@,@VERSION_EXTRA@" | ||||
|  | ||||
| MPD_ICON ICON "@top_srcdir@/src/win32/mpd.ico" | ||||
|  | ||||
| 1 VERSIONINFO | ||||
| FILETYPE VFT_APP | ||||
| FILEOS VOS__WINDOWS32 | ||||
| PRODUCTVERSION VERSION_NUMBER | ||||
|  | ||||
| FILEVERSION VERSION_NUMBER | ||||
| BEGIN | ||||
| 	BLOCK "StringFileInfo" | ||||
| 	BEGIN | ||||
| 		BLOCK "040904B0" | ||||
| 		BEGIN | ||||
| 			VALUE "CompanyName", "Music Player Daemon Project" | ||||
| 			VALUE "ProductName", "Music Player Daemon" | ||||
| 			VALUE "ProductVersion", VERSION_NUMBER_STR | ||||
| 			VALUE "InternalName", "mpd" | ||||
| 			VALUE "OriginalFilename", "mpd.exe" | ||||
| 			VALUE "FileVersion", "@VERSION@" | ||||
| 			VALUE "FileDescription", "Music Player Daemon @VERSION@" | ||||
| 			VALUE "LegalCopyright", "Copyright \251 The Music Player Daemon Project" | ||||
| 		END | ||||
| 	END | ||||
|  | ||||
| 	BLOCK "VarFileInfo" | ||||
| 	BEGIN | ||||
| 		VALUE "Translation", 0x409, 1200 | ||||
| 	END | ||||
| END | ||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann