⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 daemon_win32.cpp

📁 硬盘各项性能的测试,如温度容量版本健康度型号
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	switch (state) {		default:			svc_status.dwCheckPoint = checkpoint++;			break;		case SERVICE_RUNNING:		case SERVICE_STOPPED:			svc_status.dwCheckPoint = 0;	}	switch (state) {		case SERVICE_START_PENDING:		case SERVICE_STOP_PENDING:			svc_status.dwControlsAccepted = 0;			break;		default:			svc_status.dwControlsAccepted =				SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN|				SERVICE_ACCEPT_PAUSE_CONTINUE|accept_more;			break;	}	if (!SetServiceStatus(svc_handle, &svc_status)) {		if (svc_status.dwControlsAccepted & accept_more) {			// Retry without SERVICE_ACCEPT_PARAMCHANGE (WinNT4)			svc_status.dwControlsAccepted &= ~accept_more;			accept_more = 0;			SetServiceStatus(svc_handle, &svc_status);		}	}}// Control the service, called by SCMstatic void WINAPI service_control(DWORD ctrlcode){	switch (ctrlcode) {		case SERVICE_CONTROL_STOP:		case SERVICE_CONTROL_SHUTDOWN:			service_report_status(SERVICE_STOP_PENDING, 30);			svc_paused = 0;			SetEvent(sigterm_handle);			break;		case SERVICE_CONTROL_PARAMCHANGE: // Win2000/XP			service_report_status(svc_status.dwCurrentState, 0);			svc_paused = 0;			SetEvent(sighup_handle); // reload			break;		case SERVICE_CONTROL_PAUSE:			service_report_status(SERVICE_PAUSED, 0);			svc_paused = 1;			break;		case SERVICE_CONTROL_CONTINUE:			service_report_status(SERVICE_RUNNING, 0);			{				int was_paused = svc_paused;				svc_paused = 0;				SetEvent(was_paused ? sighup_handle : sigusr1_handle); // reload:recheck			}			break;		case SERVICE_CONTROL_INTERROGATE:		default: // unknown			service_report_status(svc_status.dwCurrentState, 0);			break;	}}// Exit handler for servicestatic void service_exit(void){	// Close signal events	int i;	for (i = 0; i < num_sig_handlers; i++)		CloseHandle(sig_events[i]);	num_sig_handlers = 0;	// Set exitcode	if (daemon_winsvc_exitcode) {		svc_status.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;		svc_status.dwServiceSpecificExitCode = daemon_winsvc_exitcode;	}	// Report stopped	service_report_status(SERVICE_STOPPED, 0);}// Variables for passing main(argc, argv) from daemon_main to service_main()static int (*svc_main_func)(int, char **);static int svc_main_argc;static char ** svc_main_argv;// Main function for service, called by service dispatcherstatic void WINAPI service_main(DWORD argc, LPSTR * argv){	char path[MAX_PATH], *p;	ARGUSED(argc);	// Register control handler	svc_handle = RegisterServiceCtrlHandler(argv[0], service_control);	// Init service status	svc_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;	service_report_status(SERVICE_START_PENDING, 10);	// Service started in \windows\system32, change to .exe directory	if (GetModuleFileNameA(NULL, path, sizeof(path)) && (p = strrchr(path, '\\'))) {		*p = 0; SetCurrentDirectoryA(path);	}		// Install exit handler	atexit(service_exit);	// Do the real work, service status later updated by daemon_detach()	daemon_winsvc_exitcode = svc_main_func(svc_main_argc, svc_main_argv);	exit(daemon_winsvc_exitcode);	// ... continued in service_exit()}/////////////////////////////////////////////////////////////////////////////// Windows Service Admin Functions// Set Service description (Win2000/XP)static int svcadm_setdesc(SC_HANDLE hs, const char * desc){	HINSTANCE hdll;	BOOL (WINAPI * ChangeServiceConfig2A_p)(SC_HANDLE, DWORD, LPVOID);	BOOL ret;	if (!(hdll = LoadLibraryA("ADVAPI32.DLL")))		return FALSE;	if (!((ChangeServiceConfig2A_p = (BOOL (WINAPI *)(SC_HANDLE, DWORD, LPVOID))GetProcAddress(hdll, "ChangeServiceConfig2A"))))		ret = FALSE;	else {		SERVICE_DESCRIPTIONA sd = { (char *)desc };		ret = ChangeServiceConfig2A_p(hs, SERVICE_CONFIG_DESCRIPTION, &sd);	}	FreeLibrary(hdll);	return ret;}// Service install/remove commandsstatic int svcadm_main(const char * ident, const daemon_winsvc_options * svc_opts,                       int argc, char **argv                                      ){	int remove; long err;	SC_HANDLE hm, hs;	if (argc < 2)		return -1;	if (!strcmp(argv[1], "install"))		remove = 0;	else if (!strcmp(argv[1], "remove")) {		if (argc != 2) {			printf("%s: no arguments allowed for command remove\n", ident);			return 1;		}		remove = 1;	}	else		return -1;	printf("%s service %s:", (!remove?"Installing":"Removing"), ident); fflush(stdout);	// Open SCM	if (!(hm = OpenSCManager(NULL/*local*/, NULL/*default*/, SC_MANAGER_ALL_ACCESS))) {		if ((err = GetLastError()) == ERROR_ACCESS_DENIED)			puts(" access to SCManager denied");		else if (err == ERROR_CALL_NOT_IMPLEMENTED)			puts(" services not implemented on this version of Windows");		else			printf(" cannot open SCManager, Error=%ld\n", err);		return 1;	}	if (!remove) {		char path[MAX_PATH+100];		int i;		// Get program path		if (!GetModuleFileNameA(NULL, path, MAX_PATH)) {			printf(" unknown program path, Error=%ld\n", GetLastError());			CloseServiceHandle(hm);			return 1;		}		// Append options		strcat(path, " "); strcat(path, svc_opts->cmd_opt);		for (i = 2; i < argc; i++) {			const char * s = argv[i];			if (strlen(path)+strlen(s)+1 >= sizeof(path))				break;			strcat(path, " "); strcat(path, s);		}		// Create		if (!(hs = CreateService(hm,			svc_opts->svcname, svc_opts->dispname,			SERVICE_ALL_ACCESS,			SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,			SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, path,			NULL/*no load ordering*/, NULL/*no tag id*/,			""/*no depedencies*/, NULL/*local system account*/, NULL/*no pw*/))) {			if ((err = GetLastError()) == ERROR_SERVICE_EXISTS)				puts(" the service is already installed");			else if (err == ERROR_SERVICE_MARKED_FOR_DELETE)				puts(" service is still running and marked for deletion\n"				     "Stop the service and retry install");			else				printf(" failed, Error=%ld\n", err);			CloseServiceHandle(hm);			return 1;		}		// Set optional description		if (svc_opts->descript)			svcadm_setdesc(hs, svc_opts->descript);	}	else {		// Open		if (!(hs = OpenService(hm, svc_opts->svcname, SERVICE_ALL_ACCESS))) {			puts(" not found");			CloseServiceHandle(hm);			return 1;		}		// TODO: Stop service if running		// Remove		if (!DeleteService(hs)) {			if ((err = GetLastError()) == ERROR_SERVICE_MARKED_FOR_DELETE)				puts(" service is still running and marked for deletion\n"				     "Stop the service to remove it");			else				printf(" failed, Error=%ld\n", err);			CloseServiceHandle(hs); CloseServiceHandle(hm);			return 1;		}	}	puts(" done");	CloseServiceHandle(hs); CloseServiceHandle(hm);	return 0;}/////////////////////////////////////////////////////////////////////////////// Main Function// This function must be called from main()// main_func is the function doing the real workint daemon_main(const char * ident, const daemon_winsvc_options * svc_opts,                int (*main_func)(int, char **), int argc, char **argv      ){	int rc;#ifdef _DEBUG	// Enable Debug heap checks	_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)		|_CRTDBG_ALLOC_MEM_DF|_CRTDBG_CHECK_ALWAYS_DF|_CRTDBG_LEAK_CHECK_DF);#endif	// Check for [status|stop|reload|restart|sigusr1|sigusr2] parameters	if ((rc = initd_main(ident, argc, argv)) >= 0)		return rc;	// Check for [install|remove] parameters	if (svc_opts && (rc = svcadm_main(ident, svc_opts, argc, argv)) >= 0)		return rc;	// Run as service if svc_opts.cmd_opt is given as first(!) argument	svc_mode = (svc_opts && argc >= 2 && !strcmp(argv[1], svc_opts->cmd_opt));	if (!svc_mode) {		// Daemon: Try to simulate a Unix-like daemon		HANDLE rev;		BOOL exists;		// Create main event to detect process type:		// 1. new: parent process => start child and wait for detach() or exit() of child.		// 2. exists && signaled: child process => do the real work, signal detach() to parent		// 3. exists && !signaled: already running => exit()		if (!(rev = create_event(EVT_RUNNING, TRUE/*signaled*/, TRUE, &exists)))			return 100;		if (!exists && !debugging()) {			// Event new => parent process			return parent_main(rev);		}		if (WaitForSingleObject(rev, 0) == WAIT_OBJECT_0) {			// Event was signaled => In child process			return child_main(rev, main_func, argc, argv);		}		// Event no longer signaled => Already running!		daemon_help(stdout, ident, "already running");		CloseHandle(rev);		return 1;	}	else {		// Service: Start service_main() via SCM		SERVICE_TABLE_ENTRY service_table[] = {			{ (char*)svc_opts->svcname, service_main }, { NULL, NULL }		};		svc_main_func = main_func;		svc_main_argc = argc;		svc_main_argv = argv;		if (!StartServiceCtrlDispatcher(service_table)) {			printf("%s: cannot dispatch service, Error=%ld\n"				"Option \"%s\" cannot be used to start %s as a service from console.\n"				"Use \"%s install ...\" to install the service\n"				"and \"net start %s\" to start it.\n",				ident, GetLastError(), svc_opts->cmd_opt, ident, ident, ident);#ifdef _DEBUG			if (debugging())				service_main(argc, argv);#endif			return 100;		}		Sleep(1000);		ExitThread(0); // Do not redo exit() processing		/*NOTREACHED*/		return 0;	}}/////////////////////////////////////////////////////////////////////////////// Test Program#ifdef TESTstatic volatile sig_atomic_t caughtsig = 0;static void sig_handler(int sig){	caughtsig = sig;}static void test_exit(void){	printf("Main exit\n");}int test_main(int argc, char **argv){	int i;	int debug = 0;	char * cmd = 0;	printf("PID=%ld\n", GetCurrentProcessId());	for (i = 0; i < argc; i++) {		printf("%d: \"%s\"\n", i, argv[i]);		if (!strcmp(argv[i],"-d"))			debug = 1;	}	if (argc > 1 && argv[argc-1][0] != '-')		cmd = argv[argc-1];	daemon_signal(SIGINT, sig_handler);	daemon_signal(SIGBREAK, sig_handler);	daemon_signal(SIGTERM, sig_handler);	daemon_signal(SIGHUP, sig_handler);	daemon_signal(SIGUSR1, sig_handler);	daemon_signal(SIGUSR2, sig_handler);	atexit(test_exit);	if (!debug) {		printf("Preparing to detach...\n");		Sleep(2000);		daemon_detach("test");		printf("Detached!\n");	}	for (;;) {		daemon_sleep(1);		printf("."); fflush(stdout);		if (caughtsig) {			if (caughtsig == SIGUSR2) {				debug ^= 1;				if (debug)					daemon_enable_console("Daemon[Debug]");				else					daemon_disable_console();			}			else if (caughtsig == SIGUSR1 && cmd) {				char inpbuf[200], outbuf[1000]; int rc;				strcpy(inpbuf, "Hello\nWorld!\n");				rc = daemon_spawn(cmd, inpbuf, strlen(inpbuf), outbuf, sizeof(outbuf));				if (!debug)					daemon_enable_console("Command output");				printf("\"%s\" returns %d\n", cmd, rc);				if (rc >= 0)					printf("output:\n%s.\n", outbuf);				fflush(stdout);				if (!debug) {					Sleep(10000); daemon_disable_console();				}			}			printf("[PID=%ld: Signal=%d]", GetCurrentProcessId(), caughtsig); fflush(stdout);			if (caughtsig == SIGTERM || caughtsig == SIGBREAK)				break;			caughtsig = 0;		}	}	printf("\nExiting on signal %d\n", caughtsig);	return 0;}int main(int argc, char **argv){	static const daemon_winsvc_options svc_opts = {	"-s", "test", "Test Service", "Service to test daemon_win32.c Module"	};	return daemon_main("testd", &svc_opts, test_main, argc, argv);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -