Beispiel #1
0
VOID
wmainCRTStartup (
    VOID
    )
{
    PSVCHOST_OPTIONS lpOptions;
    SERVICE_TABLE_ENTRYW *pServiceTable;
    LPWSTR pszCmdLine;

    /* Set a generic SEH filter and hard fail all critical errors */
    SetUnhandledExceptionFilter(SvchostUnhandledExceptionFilter);
    SetErrorMode(SEM_FAILCRITICALERRORS);

    /* Initialize the heap allocator */
    MemInit(GetProcessHeap());

    /* Initialize the DLL database and lock */
    InitializeListHead(&DllList);
    InitializeCriticalSection(&ListLock);

    /* Get the command-line and parse it to get the service group */
    pszCmdLine = GetCommandLineW();
    lpOptions = BuildCommandOptions(pszCmdLine);
    if (lpOptions == NULL)
    {
        /* Without a valid command-line, there's nothing for us to do */
        DBG_TRACE("Calling ExitProcess for %ws\n", pszCmdLine);
        ExitProcess(0);
    }

    /* Now use the service group information to lookup all the services */
    BuildServiceArray(lpOptions);

    /* Convert the list of services in this group to the SCM format */
    pServiceTable = BuildServiceTable();
    if (pServiceTable == NULL)
    {
        /* This is critical, bail out without it */
        MemFree(lpOptions);
        return;
    }

    /* Initialize COM and RPC as needed for this service group */
    if (CallPerInstanceInitFunctions(lpOptions) == FALSE)
    {
        /* Exit with a special code indicating COM/RPC setup has failed */
        DBG_ERR("%s", "CallPerInstanceInitFunctions failed -- exiting!\n");
        ExitProcess(1);
    }

    /* We're ready to go -- free the options buffer */
    MemFree(lpOptions);

    /* And call into ADVAPI32 to get our services going */
    StartServiceCtrlDispatcherW(pServiceTable);
}
Beispiel #2
0
int wmain(int argc, LPWSTR argv[])
{
    if (!StartServiceCtrlDispatcherW(ServiceTable))
    {
        DPRINT1("StartServiceCtrlDispatcherW() failed\n");
        return 1;
    }

    return 0;
}
Beispiel #3
0
int wmain( int argc, WCHAR *argv[] )
{
    static const SERVICE_TABLE_ENTRYW service_table[] =
    {
        { termserviceW, ServiceMain },
        { NULL, NULL }
    };

    StartServiceCtrlDispatcherW( service_table );
    return 0;
}
Beispiel #4
0
int APIENTRY _tWinMain(
	_In_		HINSTANCE hInstance,
	_In_opt_	HINSTANCE hPrevInstance,
	_In_		LPTSTR    lpCmdLine,
	_In_		int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

 	// TODO: 在此放置代码。

    // TO_DO: Add any additional services for the process to this table.
    SERVICE_TABLE_ENTRYW DispatchTable[] = 
    { 
        { SVCNAME, (LPSERVICE_MAIN_FUNCTIONW) SvcMain }, 
        { NULL, NULL } 
    }; 
 
    // This call returns when the service has stopped. 
    // The process should simply terminate when the call returns.

    if (StartServiceCtrlDispatcherW( DispatchTable )) 
    {
        return 0;
    }

	MSG msg;
	HACCEL hAccelTable;

	// 初始化全局字符串
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_C_WINDOW, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// 执行应用程序初始化:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_C_WINDOW));

	// 主消息循环:
	while (GetMessage(&msg, NULL, 0, 0))
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return (int) msg.wParam;
}
Beispiel #5
0
 void Service::run( ThreadController* thread )
 {
   mThread = thread;
   WCHAR name[256];
   wcscpy_s( name, 256, mName.c_str() );
   SERVICE_TABLE_ENTRYW stServiceTable[] = {
     { name, _serviceMain },
     { 0, 0 }
   };
   if ( !StartServiceCtrlDispatcherW( stServiceTable ) )
     EXCEPT_WINAPI( L"Couldn't start service control dispatcher" );
 }
Beispiel #6
0
int
wmain(int argc, WCHAR* argv[])
{
    SERVICE_TABLE_ENTRYW ServiceTable[] =
    {
        {wszServiceName, _ServiceMain},
        {NULL, NULL}
    };

    UNREFERENCED_PARAMETER(argc);
    UNREFERENCED_PARAMETER(argv);

    StartServiceCtrlDispatcherW(ServiceTable);

    return 0;
}
Beispiel #7
0
// 
//   FUNCTION: CServiceBase::Run(CServiceBase &) 
// 
//   PURPOSE: Register the executable for a service with the Service Control  
//   Manager (SCM). After you call Run(ServiceBase), the SCM issues a Start  
//   command, which results in a call to the OnStart method in the service.  
//   This method blocks until the service has stopped. 
// 
//   PARAMETERS: 
//   * service - the reference to a CServiceBase object. It will become the  
//     singleton service instance of this service application. 
// 
//   RETURN VALUE: If the function succeeds, the return value is TRUE. If the  
//   function fails, the return value is FALSE. To get extended error  
//   information, call GetLastError. 
// 
BOOL CServiceBase::Run(CServiceBase &service) 
{ 
    s_service = &service; 
 
    SERVICE_TABLE_ENTRYW serviceTable[] =  
    { 
        { service.m_name, ServiceMain }, 
        { NULL, NULL } 
    }; 
 
    // Connects the main thread of a service process to the service control  
    // manager, which causes the thread to be the service control dispatcher  
    // thread for the calling process. This call returns when the service has  
    // stopped. The process should simply terminate when the call returns. 
    return StartServiceCtrlDispatcherW(serviceTable); 
} 
Beispiel #8
0
int main(int argc, char* argv[])
{
	// Load configuration
	std::string path(argv[0]);
	unsigned found = path.find_last_of("/\\");
	path = path.substr(0, found + 1);
	Configuration *configuration = Configuration::getInstance(path);
	Log *loggr = Log::getInstance();

	serviceName = L"ChatServer";
	SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
	ServiceTable[0].lpServiceName = serviceName;
	ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTIONW)ServiceMain;
	StartServiceCtrlDispatcherW(&ServiceTable[0]);

	return 0;
}
Beispiel #9
0
/* Initialize the service table for a list (REG_MULTI_SZ) of services */
static BOOL StartGroupServices(LPWSTR services)
{
    LPWSTR service_name = NULL;
    SERVICE_TABLE_ENTRYW *service_table = NULL;
    DWORD service_count;
    BOOL ret;

    /* Count the services to load */
    service_count = 0;
    service_name = services;
    while (*service_name != '\0')
    {
        ++service_count;
        service_name = service_name + lstrlenW(service_name);
        ++service_name;
    }
    WINE_TRACE("Service group contains %d services\n", service_count);

    /* Populate the service table */
    service_table = HeapAlloc(GetProcessHeap(), 0,
            (service_count + 1) * sizeof(SERVICE_TABLE_ENTRYW));
    service_count = 0;
    service_name = services;
    while (*service_name != '\0')
    {
        if (!AddServiceElem(service_name, &service_table[service_count]))
        {
            HeapFree(GetProcessHeap(), 0, service_table);
            return FALSE;
        }
        ++service_count;
        service_name = service_name + lstrlenW(service_name);
        ++service_name;
    }
    service_table[service_count].lpServiceName = NULL;
    service_table[service_count].lpServiceProc = NULL;

    /* Start the services */
    if (!(ret = StartServiceCtrlDispatcherW(service_table)))
        WINE_ERR("StartServiceCtrlDispatcherW failed to start %s: %u\n",
                wine_dbgstr_w(services), GetLastError());

    HeapFree(GetProcessHeap(), 0, service_table);
    return ret;
}
Beispiel #10
0
int _tmain (int argc, LPTSTR argv [])
{
    SERVICE_TABLE_ENTRYW ServiceTable[] =
    {
        {ServiceName, ServiceMain},
        {NULL,        NULL }
    };

    if (InitLogging())
    {
        if (!StartServiceCtrlDispatcherW(ServiceTable))
            LogEvent(L"failed to start the service control dispatcher", GetLastError(), 101, LOG_ALL);

        UninitLogging();
    }

    return 0;
}
Beispiel #11
0
int wmain( int argc, WCHAR *argv[] )
{
    SERVICE_TABLE_ENTRYW service_table[2];

    if (!(driver_name = argv[1]))
    {
        WINE_ERR( "missing device name, winedevice isn't supposed to be run manually\n" );
        return 1;
    }

    service_table[0].lpServiceName = argv[1];
    service_table[0].lpServiceProc = ServiceMain;
    service_table[1].lpServiceName = NULL;
    service_table[1].lpServiceProc = NULL;

    StartServiceCtrlDispatcherW( service_table );
    return 0;
}
Beispiel #12
0
bool
dtr_daemon (const dtr_callbacks  * cb,
            void                 * cb_arg,
            bool                   foreground,
            int                  * exit_code,
            tr_error            ** error)
{
  callbacks = cb;
  callback_arg = cb_arg;

  *exit_code = 1;

  if (foreground)
    {
      if (!SetConsoleCtrlHandler (&handle_console_ctrl, TRUE))
        {
          set_system_error (error, GetLastError (), "SetConsoleCtrlHandler() failed");
          return false;
        }

      *exit_code = cb->on_start (cb_arg, true);
    }
  else
    {
      const SERVICE_TABLE_ENTRY service_table[] =
        {
          { (LPWSTR) service_name, &service_main },
          { NULL, NULL }
        };

      if (!StartServiceCtrlDispatcherW (service_table))
        {
          set_system_error (error, GetLastError (), "StartServiceCtrlDispatcher() failed");
          return false;
        }

      *exit_code = 0;
    }

  return true;
}
Beispiel #13
0
int
wmain(int argc, WCHAR *argv[])
{
    SERVICE_TABLE_ENTRYW ServiceTable[2] =
    {
        {ServiceName, ServiceMain},
        {NULL, NULL}
    };

    UNREFERENCED_PARAMETER(argc);
    UNREFERENCED_PARAMETER(argv);

    DPRINT("wlansvc: main() started\n");

    StartServiceCtrlDispatcherW(ServiceTable);

    DPRINT("wlansvc: main() done\n");

    ExitThread(0);

    return 0;
}
Beispiel #14
0
VOID wmain(int argc, wchar_t *argv[], wchar_t *envp[]) {
	if (argc > 1) {
		AccountName = argv[1];
		DebugOut("argv[1] = \"%S\"\n", argv[1]);
	}
	SERVICE_TABLE_ENTRY DispatchTable[] = {
		{ SERVICE_NAME, ServiceStart },
		{ NULL, NULL }
	};
	if (!StartServiceCtrlDispatcherW(DispatchTable)) {
		DWORD LastError = GetLastError();
		if (LastError == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) {
			for (;;) {
				printf("Service %S options:\n", SERVICE_NAME);
				printf("\t[1] - Install\n");
				printf("\t[2] - Uninstall\n");
				printf("\t[0] - Exit\n");
				printf("Your choose: ");
				char action = getchar();
				while (getchar() != '\n') {}
				switch (action) {
				case '1':
					SvcInstall();
					break;
				case '2':
					SvcUninstall();
					break;
				case '0':
					return;
				default:
					printf(">> Unrecongnized action\n");
					break;
				}
			}
		} else DebugOut(">> StartServiceCtrlDispatcherW failed! (LastError=0x%x)\n", LastError);
	}
}
/*
** Try to start the http server as a windows service. If we are running in
** a interactive console session, this routine fails and returns a non zero
** integer value. When running as service, this routine does not return until
** the service is stopped. In this case, the return value is zero.
*/
int win32_http_service(
  int nPort,                /* TCP port number */
  const char *zNotFound,    /* The --notfound option, or NULL */
  int flags                 /* One or more HTTP_SERVER_ flags */
){
  /* Define the service table. */
  SERVICE_TABLE_ENTRYW ServiceTable[] =
    {{L"", (LPSERVICE_MAIN_FUNCTIONW)win32_http_service_main}, {NULL, NULL}};

  /* Initialize the HttpService structure. */
  hsData.port = nPort;
  hsData.zNotFound = zNotFound;
  hsData.flags = flags;

  /* Try to start the control dispatcher thread for the service. */
  if( !StartServiceCtrlDispatcherW(ServiceTable) ){
    if( GetLastError()==ERROR_FAILED_SERVICE_CONTROLLER_CONNECT ){
      return 1;
    }else{
      fossil_fatal("error from StartServiceCtrlDispatcher()");
    }
  }
  return 0;
}
Beispiel #16
0
int wmain(int argc, wchar_t* argv[])
{
//Windows XP with SP3 support
	#if (defined(PLATFORM_WIN32) && !defined(PLATFORM_WIN64))
		GetFunctionPointer(FUNCTION_GETTICKCOUNT64);
		GetFunctionPointer(FUNCTION_INET_NTOP);
	#endif
#elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX))
int main(int argc, char *argv[])
{
#endif

//Get commands.
	if (argc > 0)
	{
		if (!ReadCommand(argc, argv))
			return EXIT_SUCCESS;
	}
	else {
		return EXIT_FAILURE;
	}

//Read configuration file and WinPcap or LibPcap initialization.
	if (!ReadParameter())
	{
		WSACleanup();
		return EXIT_FAILURE;
	}

//Mark Local DNS address to PTR Records.
	std::thread NetworkInformationMonitorThread(NetworkInformationMonitor);
	NetworkInformationMonitorThread.detach();

//Read IPFilter and Hosts.
	if (Parameter.OperationMode == LISTEN_MODE_CUSTOM || Parameter.BlacklistCheck || Parameter.LocalRouting)
	{
		std::thread IPFilterThread(ReadIPFilter);
		IPFilterThread.detach();
	}

	std::thread HostsThread(ReadHosts);
	HostsThread.detach();

//DNSCurve initialization
#if defined(ENABLE_LIBSODIUM)
	if (Parameter.DNSCurve && DNSCurveParameter.IsEncryption)
	{
		randombytes_set_implementation(&randombytes_salsa20_implementation);
		randombytes_stir();
		DNSCurveInit();
	}
#endif

#if defined(PLATFORM_WIN)
//Service initialization and start service.
	SERVICE_TABLE_ENTRYW ServiceTable[] = {{DEFAULT_LOCAL_SERVICE_NAME, (LPSERVICE_MAIN_FUNCTIONW)ServiceMain}, {nullptr, nullptr}};
	if (!StartServiceCtrlDispatcherW(ServiceTable))
	{
		Parameter.Console = true;
		wprintf_s(L"System Error: Service start error, error code is %lu.\n", GetLastError());
		wprintf_s(L"System Error: Program will continue to run in console mode.\n");
		wprintf_s(L"Please ignore those error messages if you want to run in console mode.\n");

	//Handle the system signal and start all monitors.
		SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE);
		MonitorInit();
	}

#elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX))
	MonitorInit();
#endif

	WSACleanup();
	return EXIT_SUCCESS;
}

//Read commands from main program
#if defined(PLATFORM_WIN)
bool __fastcall ReadCommand(int argc, wchar_t* argv[])
#elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX))
bool ReadCommand(int argc, char *argv[])
#endif
{
//Path initialization
#if defined(PLATFORM_WIN)
	if (!FileNameInit(argv[0]))
		return false;
#elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX))
	std::shared_ptr<char> FileName(new char[PATH_MAX + 1U]());
	memset(FileName.get(), 0, PATH_MAX + 1U);
	if (getcwd(FileName.get(), PATH_MAX) == nullptr)
	{
		wprintf(L"Path initialization error.\n");
		return false;
	}
	if (!FileNameInit(FileName.get()))
		return false;
	FileName.reset();
#endif

#if defined(PLATFORM_WIN)
//Winsock initialization
	std::shared_ptr<WSAData> WSAInitialization(new WSAData());
	if (WSAStartup(MAKEWORD(WINSOCK_VERSION_HIGH, WINSOCK_VERSION_LOW), WSAInitialization.get()) != 0 ||
		LOBYTE(WSAInitialization->wVersion) != WINSOCK_VERSION_LOW || HIBYTE(WSAInitialization->wVersion) != WINSOCK_VERSION_HIGH)
	{
		wprintf_s(L"Winsock initialization error, error code is %d.\n", WSAGetLastError());
		PrintError(LOG_ERROR_NETWORK, L"Winsock initialization error", WSAGetLastError(), nullptr, 0);

		WSACleanup();
		return false;
	}

//Read commands.
	std::wstring Commands;
#elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX))
	std::string Commands;
#endif
	for (size_t Index = 1U;(SSIZE_T)Index < argc;++Index)
	{
		Commands = argv[Index];

	//Flush DNS Cache from user.
		if (Commands == COMMAND_FLUSH_DNS)
		{
		#if defined(PLATFORM_WIN)
			FlushDNSMailSlotSender();
		#elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX))
			FlushDNSFIFOSender();
		#endif

			WSACleanup();
			return false;
		}
	//Windows Firewall Test in first start.
	#if defined(PLATFORM_WIN)
		else if (Commands == COMMAND_FIREWALL_TEST)
		{
			if (!FirewallTest(AF_INET6) && !FirewallTest(AF_INET))
			{
				wprintf_s(L"Windows Firewall Test error.\n");
				PrintError(LOG_ERROR_NETWORK, L"Windows Firewall Test error", WSAGetLastError(), nullptr, 0);
			}

			WSACleanup();
			return false;
		}
	#endif
	//Set system daemon.
	#if defined(PLATFORM_LINUX)
		else if (Commands == COMMAND_DISABLE_DAEMON)
		{
			Parameter.Daemon = false;
		}
	#endif
	//Print current version.
		else if (Commands == COMMAND_LONG_PRINT_VERSION || Commands == COMMAND_SHORT_PRINT_VERSION)
		{
			wprintf_s(L"Pcap_DNSProxy ");
			wprintf_s(FULL_VERSION);
			wprintf_s(L"\n");

			WSACleanup();
			return false;
		}
	//Print help messages.
		else if (Commands == COMMAND_LONG_HELP || Commands == COMMAND_SHORT_HELP)
		{
			wprintf_s(L"Usage: Please see ReadMe... files in Documents folder.\n");

			WSACleanup();
			return false;
		}
	//Set working directory from commands.
		else if (Commands == COMMAND_LONG_SET_PATH || Commands == COMMAND_SHORT_SET_PATH)
		{
		//Commands check
			if ((SSIZE_T)Index + 1 >= argc)
			{
				wprintf_s(L"Commands error.\n");
				PrintError(LOG_ERROR_SYSTEM, L"Commands error", 0, nullptr, 0);

				WSACleanup();
				return false;
			}
			else {
				++Index;
				Commands = argv[Index];

			//Path check.
				if (Commands.length() > MAX_PATH)
				{
					wprintf_s(L"Commands error.\n");
					PrintError(LOG_ERROR_SYSTEM, L"Commands error", 0, nullptr, 0);

					WSACleanup();
					return false;
				}
				else {
					if (!FileNameInit(Commands.c_str()))
						return false;
				}
			}
		}
	}

//Set system daemon.
#if defined(PLATFORM_LINUX)
	if (Parameter.Daemon && daemon(0, 0) == RETURN_ERROR)
	{
		PrintError(LOG_ERROR_SYSTEM, L"Set system daemon error", 0, nullptr, 0);
		return false;
	}
#endif

	return true;
}

//Get path of program from the main function parameter and Winsock initialization
#if defined(PLATFORM_WIN)
bool __fastcall FileNameInit(const wchar_t *OriginalPath)
#elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX))
bool FileNameInit(const char *OriginalPath)
#endif
{
//Path process
#if defined(PLATFORM_WIN)
	Parameter.Path_Global->clear();
	Parameter.Path_Global->push_back(OriginalPath);
	Parameter.Path_Global->front().erase(Parameter.Path_Global->front().rfind(L"\\") + 1U);
	for (size_t Index = 0;Index < Parameter.Path_Global->front().length();++Index)
	{
		if ((Parameter.Path_Global->front()).at(Index) == L'\\')
		{
			Parameter.Path_Global->front().insert(Index, L"\\");
			++Index;
		}
	}
#elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX))
	Parameter.sPath_Global->clear();
	Parameter.sPath_Global->push_back(OriginalPath);
	Parameter.sPath_Global->front().append("/");
	std::wstring StringTemp;
	MBSToWCSString(StringTemp, OriginalPath);
	StringTemp.append(L"/");
	Parameter.Path_Global->clear();
	Parameter.Path_Global->push_back(StringTemp);
	StringTemp.clear();
#endif

//Get path of error/running status log file and mark start time.
	Parameter.Path_ErrorLog->clear();
	*Parameter.Path_ErrorLog = Parameter.Path_Global->front();
	Parameter.Path_ErrorLog->append(L"Error.log");
#if (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX))
	Parameter.sPath_ErrorLog->clear();
	*Parameter.sPath_ErrorLog = Parameter.sPath_Global->front();
	Parameter.sPath_ErrorLog->append("Error.log");
#endif
	Parameter.PrintError = true;
	time(&StartTime);

	return true;
}
Beispiel #17
0
//The Main function of program
int main(int argc, char *argv[])
{
#ifdef _DEBUG
//Handle the system signal.
	SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE);
#endif

	if (argc > 0)
	{
		std::shared_ptr<wchar_t> wPath(new wchar_t[MAX_PATH]());
	//Path initialization and Winsock initialization.
		MultiByteToWideChar(CP_ACP, NULL, argv[0], MBSTOWCS_NULLTERMINATE, wPath.get(), MAX_PATH);
		if (FileInit(wPath.get()) == EXIT_FAILURE)
			return EXIT_FAILURE;
		wPath.reset();

	//Windows Firewall Test in first start.
		if (argc > 1 && strlen(argv[1U]) == strlen("--FirstStart") && memcmp(argv[1], ("--FirstStart"), strlen("--FirstStart")) == 0)
		{
			if (FirewallTest(AF_INET6) == EXIT_FAILURE && FirewallTest(AF_INET) == EXIT_FAILURE)
			{
				PrintError(WINSOCK_ERROR, L"Windows Firewall Test error", NULL, nullptr, NULL);

				WSACleanup();
				return EXIT_FAILURE;
			}
			else {
				return EXIT_SUCCESS;
			}
		}
	}
	else {
		return EXIT_FAILURE;
	}

//Read configuration file and WinPcap initialization.
	if (Parameter.ReadParameter() == EXIT_FAILURE)
	{
		WSACleanup();
		return EXIT_FAILURE;
	}
	std::thread CaptureInitializationThread(CaptureInit);
	CaptureInitializationThread.detach();

//Get Localhost DNS PTR Records.
	std::thread IPv6LocalAddressThread(LocalAddressToPTR, AF_INET6);
	std::thread IPv4LocalAddressThread(LocalAddressToPTR, AF_INET);
	IPv6LocalAddressThread.detach();
	IPv4LocalAddressThread.detach();

//DNSCurve initialization
	if (Parameter.DNSCurve && DNSCurveParameter.Encryption)
	{
		randombytes_set_implementation(&randombytes_salsa20_implementation);
		DNSCurveInit();
	}
	
//Read IPFilter, start DNS Cache monitor(Timer type) and read Hosts.
	if (Parameter.FileRefreshTime > 0)
	{
		if (Parameter.OperationMode == LISTEN_CUSTOMMODE)
		{
			std::thread IPFilterThread(&Configuration::ReadIPFilter, std::ref(Parameter));
			IPFilterThread.detach();
		}

		if (Parameter.CacheType != 0)
		{
			std::thread DNSCacheTimerThread(DNSCacheTimerMonitor, Parameter.CacheType);
			DNSCacheTimerThread.detach();
		}

		std::thread HostsThread(&Configuration::ReadHosts, std::ref(Parameter));
		HostsThread.detach();
	}

//Service initialization and start service.
	SERVICE_TABLE_ENTRYW ServiceTable[] = {{LOCAL_SERVICENAME, (LPSERVICE_MAIN_FUNCTIONW)ServiceMain}, {nullptr, NULL}};
	if (!StartServiceCtrlDispatcherW(ServiceTable))
	{
		PrintError(SYSTEM_ERROR, L"Service start error", GetLastError(), nullptr, NULL);

		WSACleanup();
		return EXIT_FAILURE;
	}

	WSACleanup();
	return EXIT_SUCCESS;
}
Beispiel #18
0
int 
wmain(int argc, WCHAR **argv)
{
  // If command-line parameter is "install", install the service
  // or upgrade if already installed
  // If command line parameter is "forceinstall", install the service
  // even if it is older than what is already installed.
  // If command-line parameter is "upgrade", upgrade the service
  // but do not install it if it is not already installed.
  // If command line parameter is "uninstall", uninstall the service.
  // Otherwise, the service is probably being started by the SCM.
  bool forceInstall = !lstrcmpi(argv[1], L"forceinstall");
  if (!lstrcmpi(argv[1], L"install") || forceInstall) {
    WCHAR updatePath[MAX_PATH + 1];
    if (GetLogDirectoryPath(updatePath)) {
      LogInit(updatePath, L"maintenanceservice-install.log");
    }

    LOG(("Installing service"));
    SvcInstallAction action = InstallSvc;
    if (forceInstall) {
      action = ForceInstallSvc;
      LOG((" with force specified"));
    }
    LOG(("...\n"));

    if (!SvcInstall(action)) {
      LOG(("Could not install service (%d)\n", GetLastError()));
      LogFinish();
      return 1;
    }

    LOG(("The service was installed successfully\n"));
    LogFinish();
    return 0;
  } 

  if (!lstrcmpi(argv[1], L"upgrade")) {
    WCHAR updatePath[MAX_PATH + 1];
    if (GetLogDirectoryPath(updatePath)) {
      LogInit(updatePath, L"maintenanceservice-install.log");
    }
    LOG(("Upgrading service if installed...\n"));
    if (!SvcInstall(UpgradeSvc)) {
      LOG(("Could not upgrade service (%d)\n", GetLastError()));
      LogFinish();
      return 1;
    }

    LOG(("The service was upgraded successfully\n"));
    LogFinish();
    return 0;
  }

  if (!lstrcmpi(argv[1], L"uninstall")) {
    WCHAR updatePath[MAX_PATH + 1];
    if (GetLogDirectoryPath(updatePath)) {
      LogInit(updatePath, L"maintenanceservice-uninstall.log");
    }
    LOG(("Uninstalling service...\n"));
    if (!SvcUninstall()) {
      LOG(("Could not uninstall service (%d)\n", GetLastError()));
      LogFinish();
      return 1;
    }
    LOG(("The service was uninstalled successfully\n"));
    LogFinish();
    return 0;
  }

  SERVICE_TABLE_ENTRYW DispatchTable[] = { 
    { SVC_NAME, (LPSERVICE_MAIN_FUNCTIONW) SvcMain }, 
    { NULL, NULL } 
  }; 

  // This call returns when the service has stopped. 
  // The process should simply terminate when the call returns.
  if (!StartServiceCtrlDispatcherW(DispatchTable)) {
    LOG(("StartServiceCtrlDispatcher failed (%d)\n", GetLastError()));
  }

  return 0;
}
Beispiel #19
0
int wmain(
	int argc, 
	wchar_t* argv[])
{
#elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX))
int main(
	int argc, 
	char *argv[])
{
#endif

//Get commands.
	if (argc > 0)
	{
		if (!ReadCommand(argc, argv))
			return EXIT_SUCCESS;
	}
	else {
		return EXIT_FAILURE;
	}

//Read configuration file.
	if (!ReadParameter(true))
		return EXIT_FAILURE;

//DNSCurve initialization
#if defined(ENABLE_LIBSODIUM)
	if (Parameter.DNSCurve)
	{
		DNSCurveParameterModificating.SetToMonitorItem();

	//Encryption mode initialization
		if (DNSCurveParameter.IsEncryption)
			DNSCurveInit();
	}
#endif

//Mark Local DNS address to PTR Records, read Parameter(Monitor mode), IPFilter and Hosts.
	ParameterModificating.SetToMonitorItem();
	std::thread NetworkInformationMonitorThread(std::bind(NetworkInformationMonitor));
	NetworkInformationMonitorThread.detach();
	std::thread ReadParameterThread(std::bind(ReadParameter, false));
	ReadParameterThread.detach();
	std::thread ReadHostsThread(std::bind(ReadHosts));
	ReadHostsThread.detach();
	if (Parameter.OperationMode == LISTEN_MODE_CUSTOM || Parameter.DataCheck_Blacklist || Parameter.LocalRouting)
	{
		std::thread ReadIPFilterThread(std::bind(ReadIPFilter));
		ReadIPFilterThread.detach();
	}

#if defined(PLATFORM_WIN)
//Service initialization and start service.
	SERVICE_TABLE_ENTRYW ServiceTable[]{{SYSTEM_SERVICE_NAME, (LPSERVICE_MAIN_FUNCTIONW)ServiceMain}, {nullptr, nullptr}};
	if (!StartServiceCtrlDispatcherW(ServiceTable))
	{
		GlobalRunningStatus.Console = true;
		auto ErrorCode = GetLastError();
		
	//Print to screen.
		std::unique_lock<std::mutex> ScreenMutex(ScreenLock);
		fwprintf_s(stderr, L"System Error: Service start error, error code is %lu.\n", ErrorCode);
		fwprintf_s(stderr, L"System Error: Program will continue to run in console mode.\n");
		fwprintf_s(stderr, L"Please ignore these error messages if you want to run in console mode.\n\n");
		ScreenMutex.unlock();

	//Handle the system signal and start all monitors.
		SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE);
		MonitorInit();
	}
#elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX))
	MonitorInit();
#endif

	return EXIT_SUCCESS;
}

//Read commands from main program
#if defined(PLATFORM_WIN)
bool __fastcall ReadCommand(
	int argc, 
	wchar_t *argv[])
#elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX))
bool ReadCommand(
	int argc, 
	char *argv[])
#endif
{
//Path initialization
#if defined(PLATFORM_WIN)
	if (!FileNameInit(argv[0]))
		return false;
#elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX))
	char FileName[PATH_MAX + 1U] = {0};
	if (getcwd(FileName, PATH_MAX) == nullptr)
	{
		std::unique_lock<std::mutex> ScreenMutex(ScreenLock);
		fwprintf(stderr, L"Path initialization error.\n");

		return false;
	}
	if (!FileNameInit(FileName))
		return false;
#endif

//Screen output buffer setting
	if (setvbuf(stderr, NULL, _IONBF, 0) != 0)
	{
		auto ErrorCode = errno;
		std::unique_lock<std::mutex> ScreenMutex(ScreenLock);
		fwprintf_s(stderr, L"Screen output buffer setting error, error code is %d.\n", ErrorCode);
		ScreenLock.unlock();
		PrintError(LOG_LEVEL_2, LOG_ERROR_NETWORK, L"Screen output buffer setting error", ErrorCode, nullptr, 0);

		return false;
	}

//Winsock initialization
#if defined(PLATFORM_WIN)
	WSAData WSAInitialization = {0};
	if (WSAStartup(MAKEWORD(WINSOCK_VERSION_HIGH, WINSOCK_VERSION_LOW), &WSAInitialization) != 0 || 
		LOBYTE(WSAInitialization.wVersion) != WINSOCK_VERSION_LOW || HIBYTE(WSAInitialization.wVersion) != WINSOCK_VERSION_HIGH)
	{
		auto ErrorCode = WSAGetLastError();
		std::unique_lock<std::mutex> ScreenMutex(ScreenLock);
		fwprintf_s(stderr, L"Winsock initialization error, error code is %d.\n", ErrorCode);
		ScreenLock.unlock();
		PrintError(LOG_LEVEL_1, LOG_ERROR_NETWORK, L"Winsock initialization error", ErrorCode, nullptr, 0);

		return false;
	}
	else {
		GlobalRunningStatus.Initialization_WinSock = true;
	}

//Read commands.
	std::wstring Commands;
#elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX))
	std::string Commands;
#endif
	for (size_t Index = 1U;(SSIZE_T)Index < argc;++Index)
	{
		Commands = argv[Index];

	//Flush DNS Cache from user.
		if (Commands == COMMAND_FLUSH_DNS)
		{
		#if defined(PLATFORM_WIN)
			FlushDNSMailSlotSender();
		#elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX))
			FlushDNSFIFOSender();
		#endif

			return false;
		}
	//Windows Firewall Test in first start.
	#if defined(PLATFORM_WIN)
		else if (Commands == COMMAND_FIREWALL_TEST)
		{
			if (!FirewallTest(AF_INET6) && !FirewallTest(AF_INET))
			{
				auto ErrorCode = WSAGetLastError();
				std::unique_lock<std::mutex> ScreenMutex(ScreenLock);
				fwprintf_s(stderr, L"Windows Firewall Test error, error code is %d.\n", ErrorCode);
				ScreenMutex.unlock();
				PrintError(LOG_LEVEL_2, LOG_ERROR_NETWORK, L"Windows Firewall Test error", ErrorCode, nullptr, 0);
			}

			return false;
		}
	#endif
	//Set system daemon.
	#if defined(PLATFORM_LINUX)
		else if (Commands == COMMAND_DISABLE_DAEMON)
		{
			GlobalRunningStatus.Daemon = false;
		}
	#endif
	//Print current version.
		else if (Commands == COMMAND_LONG_PRINT_VERSION || Commands == COMMAND_SHORT_PRINT_VERSION)
		{
			std::unique_lock<std::mutex> ScreenMutex(ScreenLock);
			fwprintf_s(stderr, L"Pcap_DNSProxy ");
			fwprintf_s(stderr, FULL_VERSION);
			fwprintf_s(stderr, L"\n");

			return false;
		}
	//Print library version.
		else if (Commands == COMMAND_LIB_VERSION)
		{
			std::unique_lock<std::mutex> ScreenMutex(ScreenLock);

		#if (defined(ENABLE_LIBSODIUM) || defined(ENABLE_PCAP))
			std::wstring LibVersion;

			//LibSodium version
			#if defined(ENABLE_LIBSODIUM)
				if (MBSToWCSString(SODIUM_VERSION_STRING, strlen(SODIUM_VERSION_STRING), LibVersion))
					fwprintf_s(stderr, L"LibSodium version %ls\n", LibVersion.c_str());
			#endif

			//WinPcap or LibPcap version
			#if defined(ENABLE_PCAP)
				if (MBSToWCSString(pcap_lib_version(), strlen(pcap_lib_version()), LibVersion))
					fwprintf_s(stderr, L"%ls\n", LibVersion.c_str());
			#endif
		#else
			fwprintf(stderr, L"No any available libraries.\n");
		#endif

			return false;
		}
	//Print help messages.
		else if (Commands == COMMAND_LONG_HELP || Commands == COMMAND_SHORT_HELP)
		{
			std::unique_lock<std::mutex> ScreenMutex(ScreenLock);

			fwprintf_s(stderr, L"Pcap_DNSProxy ");
			fwprintf_s(stderr, FULL_VERSION);
		#if defined(PLATFORM_WIN)
			fwprintf_s(stderr, L"(Windows)\n");
		#elif defined(PLATFORM_OPENWRT)
			fwprintf(stderr, L"(OpenWrt)\n");
		#elif defined(PLATFORM_LINUX)
			fwprintf(stderr, L"(Linux)\n");
		#elif defined(PLATFORM_MACX)
			fwprintf(stderr, L"(Mac)\n");
		#endif
			fwprintf_s(stderr, COPYRIGHT_MESSAGE);
			fwprintf_s(stderr, L"\nUsage: Please visit ReadMe... files in Documents folder.\n");
			fwprintf_s(stderr, L"   -v/--version:          Print current version on screen.\n");
			fwprintf_s(stderr, L"   --lib-version:         Print current version of libraries on screen.\n");
			fwprintf_s(stderr, L"   -h/--help:             Print help messages on screen.\n");
			fwprintf_s(stderr, L"   --flush-dns:           Flush all DNS cache in program and system immediately.\n");
		#if defined(PLATFORM_WIN)
			fwprintf_s(stderr, L"   --first-setup:         Test local firewall.\n");
		#endif
			fwprintf_s(stderr, L"   -c/--config-file Path: Set path of configuration file.\n");
		#if defined(PLATFORM_LINUX)
			fwprintf(stderr, L"   --disable-daemon:      Disable daemon mode.\n");
		#endif

			return false;
		}
	//Set working directory from commands.
		else if (Commands == COMMAND_LONG_SET_PATH || Commands == COMMAND_SHORT_SET_PATH)
		{
		//Commands check
			if ((SSIZE_T)Index + 1 >= argc)
			{
				std::unique_lock<std::mutex> ScreenMutex(ScreenLock);
				fwprintf(stderr, L"Commands error.\n");
				ScreenMutex.unlock();
				PrintError(LOG_LEVEL_1, LOG_ERROR_SYSTEM, L"Commands error", 0, nullptr, 0);

				return false;
			}
			else {
				++Index;
				Commands = argv[Index];

			//Path check.
				if (Commands.length() > MAX_PATH)
				{
					std::unique_lock<std::mutex> ScreenMutex(ScreenLock);
					fwprintf_s(stderr, L"Commands error.\n");
					ScreenLock.unlock();
					PrintError(LOG_LEVEL_1, LOG_ERROR_SYSTEM, L"Commands error", 0, nullptr, 0);

					return false;
				}
				else {
					if (!FileNameInit(Commands.c_str()))
						return false;
				}
			}
		}
	}

//Set system daemon.
#if defined(PLATFORM_LINUX)
	if (GlobalRunningStatus.Daemon && daemon(0, 0) == RETURN_ERROR)
	{
		PrintError(LOG_LEVEL_2, LOG_ERROR_SYSTEM, L"Set system daemon error", 0, nullptr, 0);
		return false;
	}
#endif

	return true;
}

//Get path of program from the main function parameter and Winsock initialization
#if defined(PLATFORM_WIN)
bool __fastcall FileNameInit(
	const wchar_t *OriginalPath)
#elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX))
bool FileNameInit(
	const char *OriginalPath)
#endif
{
//Path process
#if defined(PLATFORM_WIN)
	GlobalRunningStatus.Path_Global->clear();
	GlobalRunningStatus.Path_Global->push_back(OriginalPath);
	GlobalRunningStatus.Path_Global->front().erase(GlobalRunningStatus.Path_Global->front().rfind(L"\\") + 1U);
	for (size_t Index = 0;Index < GlobalRunningStatus.Path_Global->front().length();++Index)
	{
		if ((GlobalRunningStatus.Path_Global->front()).at(Index) == L'\\')
		{
			GlobalRunningStatus.Path_Global->front().insert(Index, L"\\");
			++Index;
		}
	}
#elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX))
	GlobalRunningStatus.sPath_Global->clear();
	GlobalRunningStatus.sPath_Global->push_back(OriginalPath);
	GlobalRunningStatus.sPath_Global->front().append("/");
	std::wstring StringTemp;
	if (!MBSToWCSString(OriginalPath, PATH_MAX + 1U, StringTemp))
		return false;
	StringTemp.append(L"/");
	GlobalRunningStatus.Path_Global->clear();
	GlobalRunningStatus.Path_Global->push_back(StringTemp);
	StringTemp.clear();
#endif

//Get path of error/running status log file and mark start time.
	GlobalRunningStatus.Path_ErrorLog->clear();
	*GlobalRunningStatus.Path_ErrorLog = GlobalRunningStatus.Path_Global->front();
	GlobalRunningStatus.Path_ErrorLog->append(L"Error.log");
#if (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX))
	GlobalRunningStatus.sPath_ErrorLog->clear();
	*GlobalRunningStatus.sPath_ErrorLog = GlobalRunningStatus.sPath_Global->front();
	GlobalRunningStatus.sPath_ErrorLog->append("Error.log");
#endif
	Parameter.PrintLogLevel = DEFAULT_LOG_LEVEL;
	GlobalRunningStatus.StartupTime = time(nullptr);

	return true;
}