Exemple #1
0
static BOOL net_service(int operation, const WCHAR* service_name)
{
    SC_HANDLE SCManager, serviceHandle;
    BOOL result = 0;
    WCHAR service_display_name[4096];
    DWORD buffer_size;

    SCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if(!SCManager)
    {
        output_string(STRING_NO_SCM);
        return FALSE;
    }
    serviceHandle = OpenServiceW(SCManager, service_name, SC_MANAGER_ALL_ACCESS);
    if(!serviceHandle)
    {
        output_string(STRING_NO_SVCHANDLE);
        CloseServiceHandle(SCManager);
        return FALSE;
    }

    buffer_size = sizeof(service_display_name)/sizeof(*service_display_name);
    GetServiceDisplayNameW(SCManager, service_name, service_display_name, &buffer_size);
    if (!service_display_name[0]) lstrcpyW(service_display_name, service_name);

    switch(operation)
    {
    case NET_START:
        output_string(STRING_START_SVC, service_display_name);
        result = StartServiceW(serviceHandle, 0, NULL);

        if(result) output_string(STRING_START_SVC_SUCCESS, service_display_name);
        else
        {
            if (!output_error_string(GetLastError()))
                output_string(STRING_START_SVC_FAIL, service_display_name);
        }
        break;
    case NET_STOP:
        output_string(STRING_STOP_SVC, service_display_name);
        result = StopService(SCManager, serviceHandle);

        if(result) output_string(STRING_STOP_SVC_SUCCESS, service_display_name);
        else
        {
            if (!output_error_string(GetLastError()))
                output_string(STRING_STOP_SVC_FAIL, service_display_name);
        }
        break;
    }

    CloseServiceHandle(serviceHandle);
    CloseServiceHandle(SCManager);
    return result;
}
Exemple #2
0
// https://msdn.microsoft.com/ru-ru/library/windows/desktop/bb540475%28v=vs.85%29.aspx
VOID SvcInstall() {
	WCHAR szPath[MAX_PATH];
	if (!GetModuleFileNameW(NULL, szPath, MAX_PATH)) {
		printf(">> Cannot install service (LastError=0x%x)\n", GetLastError());
		goto _ret;
	}
	SC_HANDLE schSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
	if (NULL == schSCManager) {
		printf(">> OpenSCManagerW failed (LastError=0x%x)\n", GetLastError());
		goto _ret;
	}
	WCHAR wchAccountName[64];
	for (;;) {
		printf(">> Account for granting privilage: ");
		fgetws(wchAccountName, sizeof(wchAccountName), stdin);
		PWCHAR pLineEnd = wcschr(wchAccountName, '\n');
		if (pLineEnd) *pLineEnd = '\0';
		PSID pSid;
		DWORD dwSidLength;
		if (!GetSidByName(wchAccountName, &pSid, &dwSidLength)) {
			printf(">> Failed to get SID by name (\"%S\"). Try again.\n", wchAccountName);
			continue;
		}
		free(pSid);
		break;
	}
	wcscat_s(szPath, L" \"");
	wcscat_s(szPath, wchAccountName);
	wcscat_s(szPath, L"\"");

	//printf("Command line: \"%S\"\n", szPath);

	SC_HANDLE schService = CreateServiceW(schSCManager, SERVICE_NAME, SERVICE_NAME, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, szPath, NULL, NULL, NULL, NULL, NULL);
	if (schService == NULL) {
		DWORD LastError = GetLastError();
		if (LastError == ERROR_SERVICE_EXISTS) {
			printf(">> Service already exists!\n");
			goto _close_sc;
		} else {
			printf(">> CreateServiceW failed (LastError=0x%x)\n", GetLastError());
			goto _close_sc;
		}
	} else printf(">> Service installed successfully!\n");
	if (!StartServiceW(schService, 0, NULL)) {
		printf(">> StartServiceW failed (LastError=0x%x)\n", GetLastError());
		goto _close_service;
	} else printf(">> Service started successfully!\n");
_close_service:
	CloseServiceHandle(schService);
_close_sc:
	CloseServiceHandle(schSCManager);
_ret:
	return;
}
Exemple #3
0
static BOOL
EnableUserModePnpManager(VOID)
{
    SC_HANDLE hSCManager = NULL;
    SC_HANDLE hService = NULL;
    BOOL bRet = FALSE;

    hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
    if (hSCManager == NULL)
    {
        DPRINT1("Unable to open the service control manager.\n");
        DPRINT1("Last Error %d\n", GetLastError());
        goto cleanup;
    }

    hService = OpenServiceW(hSCManager,
                            L"PlugPlay",
                            SERVICE_CHANGE_CONFIG | SERVICE_START);
    if (hService == NULL)
    {
        DPRINT1("Unable to open PlugPlay service\n");
        goto cleanup;
    }

    bRet = ChangeServiceConfigW(hService,
                               SERVICE_NO_CHANGE,
                               SERVICE_AUTO_START,
                               SERVICE_NO_CHANGE,
                               NULL, NULL, NULL,
                               NULL, NULL, NULL, NULL);
    if (!bRet)
    {
        DPRINT1("Unable to change the service configuration\n");
        goto cleanup;
    }

    bRet = StartServiceW(hService, 0, NULL);
    if (!bRet && (GetLastError() != ERROR_SERVICE_ALREADY_RUNNING))
    {
        DPRINT1("Unable to start service\n");
        goto cleanup;
    }

    bRet = TRUE;

cleanup:
    if (hService != NULL)
        CloseServiceHandle(hService);
    if (hSCManager != NULL)
        CloseServiceHandle(hSCManager);
    return bRet;
}
Exemple #4
0
/**
 * Executes a maintenance service command
 *
 * @param  argc    The total number of arguments in argv
 * @param  argv    An array of null terminated strings to pass to the service,
 * @return ERROR_SUCCESS if the service command was started.
 *         Less than 16000, a windows system error code from StartServiceW
 *         More than 20000, 20000 + the last state of the service constant if
 *         the last state is something other than stopped.
 *         17001 if the SCM could not be opened
 *         17002 if the service could not be opened
*/
DWORD
StartServiceCommand(int argc, LPCWSTR* argv)
{
  DWORD lastState = WaitForServiceStop(SVC_NAME, 5);
  if (lastState != SERVICE_STOPPED) {
    return 20000 + lastState;
  }

  // Get a handle to the SCM database.
  SC_HANDLE serviceManager = OpenSCManager(nullptr, nullptr,
                                           SC_MANAGER_CONNECT |
                                           SC_MANAGER_ENUMERATE_SERVICE);
  if (!serviceManager)  {
    return 17001;
  }

  // Get a handle to the service.
  SC_HANDLE service = OpenServiceW(serviceManager,
                                   SVC_NAME,
                                   SERVICE_START);
  if (!service) {
    CloseServiceHandle(serviceManager);
    return 17002;
  }

  // Wait at most 5 seconds trying to start the service in case of errors
  // like ERROR_SERVICE_DATABASE_LOCKED or ERROR_SERVICE_REQUEST_TIMEOUT.
  const DWORD maxWaitMS = 5000;
  DWORD currentWaitMS = 0;
  DWORD lastError = ERROR_SUCCESS;
  while (currentWaitMS < maxWaitMS) {
    BOOL result = StartServiceW(service, argc, argv);
    if (result) {
      lastError = ERROR_SUCCESS;
      break;
    } else {
      lastError = GetLastError();
    }
    Sleep(100);
    currentWaitMS += 100;
  }
  CloseServiceHandle(service);
  CloseServiceHandle(serviceManager);
  return lastError;
}
Exemple #5
0
static HRESULT start_service( const WCHAR *name, VARIANT *retval )
{
    SC_HANDLE manager, service = NULL;
    UINT error = 0;

    if (!(manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE )))
    {
        error = map_error( GetLastError() );
        goto done;
    }
    if (!(service = OpenServiceW( manager, name, SERVICE_START )))
    {
        error = map_error( GetLastError() );
        goto done;
    }
    if (!StartServiceW( service, 0, NULL )) error = map_error( GetLastError() );

done:
    set_variant( VT_UI4, error, NULL, retval );
    CloseServiceHandle( service );
    CloseServiceHandle( manager );
    return S_OK;
}
Exemple #6
0
BOOL
StartDriver(LPCWSTR lpDriverName)
{
    SC_HANDLE hSCManager;
    SC_HANDLE hService;
    BOOL bRet;

    hSCManager = OpenSCManagerW(NULL,
                                NULL,
                                SC_MANAGER_ALL_ACCESS);
    if (!hSCManager)
        return FALSE;

    hService = OpenServiceW(hSCManager,
                            lpDriverName,
                            SERVICE_ALL_ACCESS);
    if (!hService)
    {
        CloseServiceHandle(hSCManager);
        return FALSE;
    }

    bRet = StartServiceW(hService, 0, NULL);
    if (!bRet)
    {
        if (GetLastError() == ERROR_SERVICE_ALREADY_RUNNING)
        {
            wprintf(L"%s.sys already running\n", DRIVER_NAME);
            bRet = TRUE;
        }
    }

    CloseServiceHandle(hService);
    CloseServiceHandle(hSCManager);

    return bRet;
}
Exemple #7
0
BOOL StartServiceCtrl(LPCWSTR lpcwszName)
{
	SC_HANDLE hScm = NULL;
	SC_HANDLE hSrv = NULL;
	hScm = OpenSCManagerW(0, 0, SC_MANAGER_CONNECT);
	if(hScm == NULL){
		OutputDebugString(_T("OpenSCManager failed"));
		return FALSE;
	}
	hSrv = OpenServiceW(hScm, lpcwszName, SERVICE_START);
	if(hSrv == NULL){
		OutputDebugString(_T("OpenService failed"));
		CloseServiceHandle(hScm);
		return FALSE;
	}
	if( StartServiceW(hSrv, 0, NULL) == FALSE ){
		OutputDebugString(_T("StartService failed"));
	}

	CloseServiceHandle(hSrv);
	CloseServiceHandle(hScm);

	return TRUE;
}
/* dupe ifdef needed for mkindex
** COMMAND: winsrv*
** Usage: fossil winsrv METHOD ?SERVICE-NAME? ?OPTIONS?
**
** Where METHOD is one of: create delete show start stop.
**
** The winsrv command manages Fossil as a Windows service.  This allows
** (for example) Fossil to be running in the background when no user
** is logged in.
**
** In the following description of the methods, "Fossil-DSCM" will be
** used as the default SERVICE-NAME:
**
**    fossil winsrv create ?SERVICE-NAME? ?OPTIONS?
**
**         Creates a service. Available options include:
**
**         -D|--display DISPLAY-NAME
**
**              Sets the display name of the service. This name is shown
**              by graphical interface programs. By default, the display name
**              equals to the service name.
**
**         -S|--start TYPE
**
**              Sets the start type of the service. TYPE can be "manual",
**              which means you need to start the service yourself with the
**              'fossil winsrv start' command or with the "net start" command
**              from the operating system. If TYPE is set to "auto", the service
**              will be started automatically by the system during startup.
**
**         -U|--username USERNAME
**
**              Specifies the user account which will be used to run the
**              service. The account needs the "Logon as a service" right
**              enabled in its profile. Specify local accounts as follows:
**              ".\\USERNAME". By default, the "LocalSystem" account will be
**              used.
**
**         -W|--password PASSWORD
**
**              Password for the user account.
**
**         The following options are more or less the same as for the "server"
**         command and influence the behaviour of the http server:
**
**         -P|--port TCPPORT
**
**              Specifies the TCP port (default port is 8080) on which the
**              server should listen.
**
**         -R|--repository REPOSITORY
**
**              Specifies the name of the repository to be served.
**              The repository option may be omitted if the working directory
**              is within an open checkout.
**              The REPOSITORY can be a directory (aka folder) that contains
**              one or more repositories with names ending in ".fossil".
**              In that case, the first element of the URL is used to select
**              among the various repositories.
**
**         --notfound URL
**
**              If REPOSITORY is a directory that contains one or more
**              repositories with names of the form "*.fossil" then the
**              first element of the URL  pathname selects among the various
**              repositories. If the pathname does not select a valid
**              repository and the --notfound option is available,
**              then the server redirects (HTTP code 302) to the URL of
**              --notfound.
**
**         --localauth
**
**              Enables automatic login if the --localauth option is present
**              and the "localauth" setting is off and the connection is from
**              localhost.
**
**
**    fossil winsrv delete ?SERVICE-NAME?
**
**         Deletes a service. If the service is currently running, it will be
**         stopped first and then deleted.
**
**
**    fossil winsrv show ?SERVICE-NAME?
**
**         Shows how the service is configured and its current state.
**
**
**    fossil winsrv start ?SERVICE-NAME?
**
**         Start the service.
**
**
**    fossil winsrv stop ?SERVICE-NAME?
**
**         Stop the service.
**
**
** NOTE: This command is available on Windows operating systems only and
**       requires administrative rights on the machine executed.
**
*/
void cmd_win32_service(void){
  int n;
  const char *zMethod;
  const char *zSvcName = "Fossil-DSCM";    /* Default service name */

  if( g.argc<3 ){
    usage("create|delete|show|start|stop ...");
  }
  zMethod = g.argv[2];
  n = strlen(zMethod);

  if( strncmp(zMethod, "create", n)==0 ){
    SC_HANDLE hScm;
    SC_HANDLE hSvc;
    SERVICE_DESCRIPTIONW
      svcDescr = {L"Fossil - Distributed Software Configuration Management"};
    char *zErrFmt = "unable to create service '%s': %s";
    DWORD dwStartType = SERVICE_DEMAND_START;
    const char *zDisplay    = find_option("display", "D", 1);
    const char *zStart      = find_option("start", "S", 1);
    const char *zUsername   = find_option("username", "U", 1);
    const char *zPassword   = find_option("password", "W", 1);
    const char *zPort       = find_option("port", "P", 1);
    const char *zNotFound   = find_option("notfound", 0, 1);
    const char *zLocalAuth  = find_option("localauth", 0, 0);
    const char *zRepository = find_option("repository", "R", 1);
    Blob binPath;

    verify_all_options();
    if( g.argc==4 ){
      zSvcName = g.argv[3];
    }else if( g.argc>4 ){
      fossil_fatal("to much arguments for create method.");
    }
    /* Process service creation specific options. */
    if( !zDisplay ){
      zDisplay = zSvcName;
    }
    if( zStart ){
      if( strncmp(zStart, "auto", strlen(zStart))==0 ){
        dwStartType = SERVICE_AUTO_START;
      }else if( strncmp(zStart, "manual", strlen(zStart))==0 ){
        dwStartType = SERVICE_DEMAND_START;
      }else{
        fossil_fatal(zErrFmt, zSvcName,
                     "specify 'auto' or 'manual' for the '-S|--start' option");
      }
    }
    /* Process options for Fossil running as server. */
    if( zPort && (atoi(zPort)<=0) ){
      fossil_fatal(zErrFmt, zSvcName,
                   "port number must be in the range 1 - 65535.");
    }
    if( !zRepository ){
      db_must_be_within_tree();
    }else if( file_isdir(zRepository)==1 ){
      g.zRepositoryName = mprintf("%s", zRepository);
      file_simplify_name(g.zRepositoryName, -1, 0);
    }else{
      db_open_repository(zRepository);
    }
    db_close(0);
    /* Build the fully-qualified path to the service binary file. */
    blob_zero(&binPath);
    blob_appendf(&binPath, "\"%s\" server", g.nameOfExe);
    if( zPort ) blob_appendf(&binPath, " --port %s", zPort);
    if( zNotFound ) blob_appendf(&binPath, " --notfound \"%s\"", zNotFound);
    if( zLocalAuth ) blob_append(&binPath, " --localauth", -1);
    blob_appendf(&binPath, " \"%s\"", g.zRepositoryName);
    /* Create the service. */
    hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    hSvc = CreateServiceW(
             hScm,                                    /* Handle to the SCM */
             fossil_utf8_to_unicode(zSvcName),           /* Name of the service */
             fossil_utf8_to_unicode(zDisplay),           /* Display name */
             SERVICE_ALL_ACCESS,                      /* Desired access */
             SERVICE_WIN32_OWN_PROCESS,               /* Service type */
             dwStartType,                             /* Start type */
             SERVICE_ERROR_NORMAL,                    /* Error control */
             fossil_utf8_to_unicode(blob_str(&binPath)), /* Binary path */
             NULL,                                    /* Load ordering group */
             NULL,                                    /* Tag value */
             NULL,                                    /* Service dependencies */
             fossil_utf8_to_unicode(zUsername),          /* Service account */
             fossil_utf8_to_unicode(zPassword)           /* Account password */
           );
    if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    /* Set the service description. */
    ChangeServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION, &svcDescr);
    fossil_print("Service '%s' successfully created.\n", zSvcName);
    CloseServiceHandle(hSvc);
    CloseServiceHandle(hScm);
  }else
  if( strncmp(zMethod, "delete", n)==0 ){
    SC_HANDLE hScm;
    SC_HANDLE hSvc;
    SERVICE_STATUS sstat;
    char *zErrFmt = "unable to delete service '%s': %s";

    verify_all_options();
    if( g.argc==4 ){
      zSvcName = g.argv[3];
    }else if( g.argc>4 ){
      fossil_fatal("to much arguments for delete method.");
    }
    hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), SERVICE_ALL_ACCESS);
    if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    QueryServiceStatus(hSvc, &sstat);
    if( sstat.dwCurrentState!=SERVICE_STOPPED ){
      fossil_print("Stopping service '%s'", zSvcName);
      if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){
        if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){
          fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
        }
      }
      while( sstat.dwCurrentState!=SERVICE_STOPPED ){
        Sleep(100);
        fossil_print(".");
        QueryServiceStatus(hSvc, &sstat);
      }
      fossil_print("\nService '%s' stopped.\n", zSvcName);
    }
    if( !DeleteService(hSvc) ){
      if( GetLastError()==ERROR_SERVICE_MARKED_FOR_DELETE ){
        fossil_warning("Service '%s' already marked for delete.\n", zSvcName);
      }else{
        fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
      }
    }else{
      fossil_print("Service '%s' successfully deleted.\n", zSvcName);
    }
    CloseServiceHandle(hSvc);
    CloseServiceHandle(hScm);
  }else
  if( strncmp(zMethod, "show", n)==0 ){
    SC_HANDLE hScm;
    SC_HANDLE hSvc;
    SERVICE_STATUS sstat;
    LPQUERY_SERVICE_CONFIGW pSvcConfig;
    LPSERVICE_DESCRIPTIONW pSvcDescr;
    BOOL bStatus;
    DWORD nRequired;
    const char *zErrFmt = "unable to show service '%s': %s";
    static const char *const zSvcTypes[] = {
      "Driver service",
      "File system driver service",
      "Service runs in its own process",
      "Service shares a process with other services",
      "Service can interact with the desktop"
    };
    const char *zSvcType = "";
    static const char *const zSvcStartTypes[] = {
      "Started by the system loader",
      "Started by the IoInitSystem function",
      "Started automatically by the service control manager",
      "Started manually",
      "Service cannot be started"
    };
    const char *zSvcStartType = "";
    static const char *const zSvcStates[] = {
      "Stopped", "Starting", "Stopping", "Running",
      "Continue pending", "Pause pending", "Paused"
    };
    const char *zSvcState = "";

    verify_all_options();
    if( g.argc==4 ){
      zSvcName = g.argv[3];
    }else if( g.argc>4 ){
      fossil_fatal("to much arguments for show method.");
    }
    hScm = OpenSCManagerW(NULL, NULL, GENERIC_READ);
    if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), GENERIC_READ);
    if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    /* Get the service configuration */
    bStatus = QueryServiceConfigW(hSvc, NULL, 0, &nRequired);
    if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){
      fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    }
    pSvcConfig = fossil_malloc(nRequired);
    bStatus = QueryServiceConfigW(hSvc, pSvcConfig, nRequired, &nRequired);
    if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    /* Translate the service type */
    switch( pSvcConfig->dwServiceType ){
      case SERVICE_KERNEL_DRIVER:       zSvcType = zSvcTypes[0]; break;
      case SERVICE_FILE_SYSTEM_DRIVER:  zSvcType = zSvcTypes[1]; break;
      case SERVICE_WIN32_OWN_PROCESS:   zSvcType = zSvcTypes[2]; break;
      case SERVICE_WIN32_SHARE_PROCESS: zSvcType = zSvcTypes[3]; break;
      case SERVICE_INTERACTIVE_PROCESS: zSvcType = zSvcTypes[4]; break;
    }
    /* Translate the service start type */
    switch( pSvcConfig->dwStartType ){
      case SERVICE_BOOT_START:    zSvcStartType = zSvcStartTypes[0]; break;
      case SERVICE_SYSTEM_START:  zSvcStartType = zSvcStartTypes[1]; break;
      case SERVICE_AUTO_START:    zSvcStartType = zSvcStartTypes[2]; break;
      case SERVICE_DEMAND_START:  zSvcStartType = zSvcStartTypes[3]; break;
      case SERVICE_DISABLED:      zSvcStartType = zSvcStartTypes[4]; break;
    }
    /* Get the service description. */
    bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION,
                                  NULL, 0, &nRequired);
    if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){
      fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    }
    pSvcDescr = fossil_malloc(nRequired);
    bStatus = QueryServiceConfig2W(hSvc, SERVICE_CONFIG_DESCRIPTION,
                                  (LPBYTE)pSvcDescr, nRequired, &nRequired);
    if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    /* Retrieves the current status of the specified service. */
    bStatus = QueryServiceStatus(hSvc, &sstat);
    if( !bStatus ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    /* Translate the current state. */
    switch( sstat.dwCurrentState ){
      case SERVICE_STOPPED:          zSvcState = zSvcStates[0]; break;
      case SERVICE_START_PENDING:    zSvcState = zSvcStates[1]; break;
      case SERVICE_STOP_PENDING:     zSvcState = zSvcStates[2]; break;
      case SERVICE_RUNNING:          zSvcState = zSvcStates[3]; break;
      case SERVICE_CONTINUE_PENDING: zSvcState = zSvcStates[4]; break;
      case SERVICE_PAUSE_PENDING:    zSvcState = zSvcStates[5]; break;
      case SERVICE_PAUSED:           zSvcState = zSvcStates[6]; break;
    }
    /* Print service information to terminal */
    fossil_print("Service name .......: %s\n", zSvcName);
    fossil_print("Display name .......: %s\n",
                 fossil_unicode_to_utf8(pSvcConfig->lpDisplayName));
    fossil_print("Service description : %s\n",
                 fossil_unicode_to_utf8(pSvcDescr->lpDescription));
    fossil_print("Service type .......: %s.\n", zSvcType);
    fossil_print("Service start type .: %s.\n", zSvcStartType);
    fossil_print("Binary path name ...: %s\n",
                 fossil_unicode_to_utf8(pSvcConfig->lpBinaryPathName));
    fossil_print("Service username ...: %s\n",
                 fossil_unicode_to_utf8(pSvcConfig->lpServiceStartName));
    fossil_print("Current state ......: %s.\n", zSvcState);
    /* Cleanup */
    fossil_free(pSvcConfig);
    fossil_free(pSvcDescr);
    CloseServiceHandle(hSvc);
    CloseServiceHandle(hScm);
  }else
  if( strncmp(zMethod, "start", n)==0 ){
    SC_HANDLE hScm;
    SC_HANDLE hSvc;
    SERVICE_STATUS sstat;
    char *zErrFmt = "unable to start service '%s': %s";

    verify_all_options();
    if( g.argc==4 ){
      zSvcName = g.argv[3];
    }else if( g.argc>4 ){
      fossil_fatal("to much arguments for start method.");
    }
    hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), SERVICE_ALL_ACCESS);
    if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    QueryServiceStatus(hSvc, &sstat);
    if( sstat.dwCurrentState!=SERVICE_RUNNING ){
      fossil_print("Starting service '%s'", zSvcName);
      if( sstat.dwCurrentState!=SERVICE_START_PENDING ){
        if( !StartServiceW(hSvc, 0, NULL) ){
          fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
        }
      }
      while( sstat.dwCurrentState!=SERVICE_RUNNING ){
        Sleep(100);
        fossil_print(".");
        QueryServiceStatus(hSvc, &sstat);
      }
      fossil_print("\nService '%s' started.\n", zSvcName);
    }else{
      fossil_print("Service '%s' is already started.\n", zSvcName);
    }
    CloseServiceHandle(hSvc);
    CloseServiceHandle(hScm);
  }else
  if( strncmp(zMethod, "stop", n)==0 ){
    SC_HANDLE hScm;
    SC_HANDLE hSvc;
    SERVICE_STATUS sstat;
    char *zErrFmt = "unable to stop service '%s': %s";

    verify_all_options();
    if( g.argc==4 ){
      zSvcName = g.argv[3];
    }else if( g.argc>4 ){
      fossil_fatal("to much arguments for stop method.");
    }
    hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    hSvc = OpenServiceW(hScm, fossil_utf8_to_unicode(zSvcName), SERVICE_ALL_ACCESS);
    if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
    QueryServiceStatus(hSvc, &sstat);
    if( sstat.dwCurrentState!=SERVICE_STOPPED ){
      fossil_print("Stopping service '%s'", zSvcName);
      if( sstat.dwCurrentState!=SERVICE_STOP_PENDING ){
        if( !ControlService(hSvc, SERVICE_CONTROL_STOP, &sstat) ){
          fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
        }
      }
      while( sstat.dwCurrentState!=SERVICE_STOPPED ){
        Sleep(100);
        fossil_print(".");
        QueryServiceStatus(hSvc, &sstat);
      }
      fossil_print("\nService '%s' stopped.\n", zSvcName);
    }else{
      fossil_print("Service '%s' is already stopped.\n", zSvcName);
    }
    CloseServiceHandle(hSvc);
    CloseServiceHandle(hScm);
  }else
  {
    fossil_fatal("METHOD should be one of:"
                 " create delete show start stop");
  }
  return;
}
Exemple #9
0
EASYHOOK_NT_EXPORT RtlInstallService(
            WCHAR* InServiceName,
            WCHAR* InExePath,
            WCHAR* InChannelName)
{
/*
Description:

    This method is intended for the managed layer only. It will
    provide a convenient way to install a service which seems to
    be impossible with NET code in any efficient manner.
    
Parameters:

    - InServiceName

        A unique service name under which the service shall be registered.
        In case of the EasyHook service, this value is expected to be exactly
        the filename without extension of the full "InExePath".

    - InExePath

        A relative or absolute path to the service EXE file.

    - InChannelName

        The channel name for the service to register its IPC channel.
        This should be randomly generated.

Returns:

    STATUS_ALREADY_REGISTERED

        A service with this name is already registered. To prevent name collisions
        I recommend to rename the service to an unique name for your specific
        application. Please refer to the README file for more information.

    STATUS_ACCESS_DENIED

        You are not administrator?!
*/
	SC_HANDLE			hSCManager = NULL;
	SC_HANDLE			hService = NULL;
    NTSTATUS            NtStatus;
    LPCWSTR		        StartParams[1] = {InChannelName};
    ULONG               res;

	if((hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS)) == NULL)
		THROW(STATUS_ACCESS_DENIED, L"Unable to open service control manager. Check for administrator privileges!");

	/* 
        Does service exist?
        Internally the service will always be removed automatically. 
        So there shouldn't be any problems. Only if two or more concurrent
        applications are using EasyHook, this will lead to an error, because
        it is very hard to don't get them confused.
    */
	if((hService = OpenService(hSCManager, InServiceName, SERVICE_ALL_ACCESS)) == NULL)
	{
		if(GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST)
			THROW(STATUS_INTERNAL_ERROR, L"Unable to open already registered service.");
	}
	else
	{
        DeleteService(hService);

        CloseServiceHandle(hService);

        hService = NULL;

        THROW(STATUS_ALREADY_REGISTERED, L"The service is already registered. Use the service control manager to remove it!");
	}

	// install service
	if((hService = CreateServiceW(
			hSCManager,              
			InServiceName,            
			InServiceName,           
			SERVICE_ALL_ACCESS,        
			SERVICE_WIN32_OWN_PROCESS,
			SERVICE_DEMAND_START,    
			SERVICE_ERROR_NORMAL,     
			InExePath,            
			NULL, NULL, NULL, NULL, NULL)) == NULL)
		THROW(STATUS_INTERNAL_ERROR, L"Unable to install service as system process.");

    // start service
	if(!StartServiceW(hService, 1, (LPCWSTR*)StartParams))
    {
        res = GetLastError();

        THROW(STATUS_INTERNAL_ERROR, L"Unable to start service.");
    }

    RETURN(STATUS_SUCCESS);

THROW_OUTRO:
FINALLY_OUTRO:
	{
		if(hService != NULL)
		{
			DeleteService(hService);

			CloseServiceHandle(hService);
		}

		if(hSCManager != NULL)
			CloseServiceHandle(hSCManager);

        return NtStatus;
	}
}
Exemple #10
0
/* Start the service argv[2] */
static
INT
StartOneService(INT argc, WCHAR **argv)
{
    SC_HANDLE hManager = NULL;
    SC_HANDLE hService = NULL;
    LPCWSTR *lpArgVectors = NULL;
    DWORD dwError = ERROR_SUCCESS;
    INT nError = 0;
    INT i;

    hManager = OpenSCManagerW(NULL,
                              SERVICES_ACTIVE_DATABASE,
                              SC_MANAGER_ENUMERATE_SERVICE);
    if (hManager == NULL)
    {
        dwError = GetLastError();
        nError = 1;
        goto done;
    }

    hService = OpenServiceW(hManager,
                            argv[2],
                            SERVICE_START);
    if (hService == NULL)
    {
        dwError = GetLastError();
        nError = 1;
        goto done;
    }

    lpArgVectors = HeapAlloc(GetProcessHeap(),
                             0,
                             (argc - 2) * sizeof(LPCWSTR));
    if (lpArgVectors == NULL)
    {
        dwError = GetLastError();
        nError = 1;
        goto done;
    }

    for (i = 2; i < argc; i++)
    {
        lpArgVectors[i - 2] = argv[i];
    }

    if (!StartServiceW(hService,
                       (DWORD)argc - 2,
                       lpArgVectors))
    {
        dwError = GetLastError();
        nError = 1;
    }

done:
    if (lpArgVectors != NULL)
        HeapFree(GetProcessHeap(), 0, (LPVOID)lpArgVectors);

    if (hService != NULL)
        CloseServiceHandle(hService);

    if (hManager != NULL)
        CloseServiceHandle(hManager);

    if (dwError != ERROR_SUCCESS)
    {
        /* FIXME: Print proper error message */
        printf("Error: %lu\n", dwError);
    }

    return nError;
}
Exemple #11
0
EASYHOOK_NT_EXPORT RhInstallDriver(
			WCHAR* InDriverPath,
			WCHAR* InDriverName)
{
/*
Description:

	Installs the given driver.

Parameters:

	- InDriverPath

		A relative or full path to the driver's executable

	- InDriverName

		A name to register the driver in the service control manager.

*/   
	WCHAR				DriverPath[MAX_PATH + 1];
	SC_HANDLE			hSCManager = NULL;
	SC_HANDLE			hService = NULL;	
	NTSTATUS			NtStatus;

	GetFullPathNameW(InDriverPath, MAX_PATH, DriverPath, NULL);

	if(!RtlFileExists(DriverPath))
		THROW(STATUS_NOT_FOUND, L"The EasyHook driver file does not exist.");

	if((hSCManager = OpenSCManagerW(
			NULL, 
			NULL, 
			SC_MANAGER_ALL_ACCESS)) == NULL)
		THROW(STATUS_ACCESS_DENIED, L"Unable to open service control manager. Are you running as administrator?");

	// does service exist?
	if((hService = OpenService(
			hSCManager, 
			InDriverName, 
			SERVICE_ALL_ACCESS)) == NULL)
	{
		if(GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST)
			THROW(STATUS_INTERNAL_ERROR, L"An unknown error has occurred during driver installation.");

		// Create the service
		if((hService = CreateServiceW(
				hSCManager,              
				InDriverName,            
				InDriverName,           
				SERVICE_ALL_ACCESS,        
				SERVICE_KERNEL_DRIVER,
				SERVICE_DEMAND_START,    
				SERVICE_ERROR_NORMAL,     
				DriverPath,            
				NULL, NULL, NULL, NULL, NULL)) == NULL)
			THROW(STATUS_INTERNAL_ERROR, L"Unable to install driver.");
	}

	// start and connect service...
	if(!StartServiceW(hService, 0, NULL) && (GetLastError() != ERROR_SERVICE_ALREADY_RUNNING)
			&& (GetLastError() != ERROR_SERVICE_DISABLED))
		THROW(STATUS_INTERNAL_ERROR, L"Unable to start driver!");

	RETURN;
	
THROW_OUTRO:
FINALLY_OUTRO:
	{
		if(hService != NULL)
		{
			DeleteService(hService);

			CloseServiceHandle(hService);
		}

		if(hSCManager != NULL)
			CloseServiceHandle(hSCManager);

		return NtStatus;
	}
}
Exemple #12
0
static void Test_LockUnlockServiceDatabaseWithServiceStart(void)
{
    BOOL bError = FALSE;

    SC_HANDLE hScm  = NULL;
    SC_HANDLE hSvc  = NULL;
    SC_LOCK   hLock = NULL;

    LPQUERY_SERVICE_CONFIGW lpConfig = NULL;
    DWORD dwRequiredSize = 0;
    SERVICE_STATUS status;
    BOOL bWasRunning = FALSE;
    DWORD dwOldStartType = 0;

    /* Open the services database */
    SetLastError(0xdeadbeef);
    hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_LOCK);
    ok(hScm != NULL, "Failed to open service manager, error=0x%08lx\n", GetLastError());
    if (!hScm)
    {
        skip("No service control manager; cannot proceed with LockUnlockServiceDatabaseWithServiceStart test\n");
        goto cleanup;
    }
    ok_err(ERROR_SUCCESS);

    /* Grab a handle to the testing service */
    SetLastError(0xdeadbeef);
    hSvc = OpenServiceW(hScm, TESTING_SERVICE, SERVICE_START | SERVICE_STOP | SERVICE_CHANGE_CONFIG | SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS);
    ok(hSvc != NULL, "hSvc = 0x%p, expected non-null, error=0x%08lx\n", hSvc, GetLastError());
    if (!hSvc)
    {
        skip("Cannot open a handle to service %S; cannot proceed with LockUnlockServiceDatabaseWithServiceStart test\n", TESTING_SERVICE);
        goto cleanup;
    }
    ok_err(ERROR_SUCCESS);

    /* Lock the services database */
    SetLastError(0xdeadbeef);
    hLock = LockServiceDatabase(hScm);
    ok(hLock != NULL, "hLock = 0x%p, expected non-zero, error=0x%08lx\n", hLock, GetLastError());
    if (!hLock)
    {
        skip("Cannot lock the services database; cannot proceed with LockUnlockServiceDatabaseWithServiceStart test\n");
        goto cleanup;
    }
    ok_err(ERROR_SUCCESS);

    /* To proceed further, firstly attempt to stop the testing service */
    QueryServiceConfigW(hSvc, NULL, 0, &dwRequiredSize);
    lpConfig = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwRequiredSize);
    QueryServiceConfigW(hSvc, lpConfig, dwRequiredSize, &dwRequiredSize);
    dwOldStartType = lpConfig->dwStartType;
    HeapFree(GetProcessHeap(), 0, lpConfig);
    if (dwOldStartType == SERVICE_DISABLED)
    {
        ChangeServiceConfigW(hSvc,
                             SERVICE_NO_CHANGE,
                             SERVICE_DEMAND_START,
                             SERVICE_NO_CHANGE,
                             NULL,
                             NULL,
                             NULL,
                             NULL,
                             NULL,
                             NULL,
                             NULL);
    }
    QueryServiceStatus(hSvc, &status);
    bWasRunning = (status.dwCurrentState != SERVICE_STOPPED);
    if (bWasRunning)
    {
        ControlService(hSvc, SERVICE_CONTROL_STOP, &status);
        Sleep(1000); /* Wait 1 second for the service to stop */
    }

    /* Now try to start it (this test won't work under Windows Vista / 7 / 8) */
    SetLastError(0xdeadbeef);
    bError = StartServiceW(hSvc, 0, NULL);
    ok(bError == FALSE, "bError = %u, expected FALSE\n", bError);
    ok_err(ERROR_SERVICE_DATABASE_LOCKED);
    Sleep(1000); /* Wait 1 second for the service to start */

    /* Stop the testing service */
    ControlService(hSvc, SERVICE_CONTROL_STOP, &status);
    Sleep(1000); /* Wait 1 second for the service to stop */

    /* Now unlock the services database */
    SetLastError(0xdeadbeef);
    bError = UnlockServiceDatabase(hLock);
    ok(bError == TRUE, "bError = %u, expected TRUE\n", bError);
    ok_err(ERROR_SUCCESS);

    /* Try to start again the service, this time the database unlocked */
    SetLastError(0xdeadbeef);
    bError = StartServiceW(hSvc, 0, NULL);
    ok(bError == TRUE, "bError = %u, expected TRUE\n", bError);
    ok_err(ERROR_SUCCESS);
    Sleep(1000); /* Wait 1 second for the service to start */

    /* Stop the testing service */
    ControlService(hSvc, SERVICE_CONTROL_STOP, &status);
    Sleep(1000); /* Wait 1 second for the service to stop */

    /* Restore its original state */
    if (bWasRunning)
    {
        StartServiceW(hSvc, 0, NULL);
    }

    if (dwOldStartType == SERVICE_DISABLED)
    {
        ChangeServiceConfigW(hSvc,
                             SERVICE_NO_CHANGE,
                             SERVICE_DISABLED,
                             SERVICE_NO_CHANGE,
                             NULL,
                             NULL,
                             NULL,
                             NULL,
                             NULL,
                             NULL,
                             NULL);
    }


cleanup:
    if (hSvc)
        CloseServiceHandle(hSvc);

    if (hScm)
        CloseServiceHandle(hScm);

    return;
}
Exemple #13
0
static void
_RunRemoteTest(const char* szTestName)
{
    BOOL bSuccessful = FALSE;
    char szBuffer[1024];
    DWORD cbRead;
    DWORD cbWritten;
    HANDLE hCommandPipe = INVALID_HANDLE_VALUE;
    HANDLE hFind = INVALID_HANDLE_VALUE;
    HANDLE hOutputPipe = INVALID_HANDLE_VALUE;
    PWSTR p;
    SC_HANDLE hSC = NULL;
    SC_HANDLE hService = NULL;
    SERVICE_STATUS ServiceStatus;
    WCHAR wszFilePath[MAX_PATH + 20];
    WIN32_FIND_DATAW fd;

    // Do a dummy EnumPrintersW call.
    // This guarantees that the Spooler Service has actually loaded localspl.dll, which is a requirement for our injected DLL to work properly.
    EnumPrintersW(PRINTER_ENUM_LOCAL | PRINTER_ENUM_NAME, NULL, 1, NULL, 0, &cbRead, &cbWritten);

    // Get the full path to our EXE file.
    if (!GetModuleFileNameW(NULL, wszFilePath, MAX_PATH))
    {
        skip("GetModuleFileNameW failed with error %lu!\n", GetLastError());
        goto Cleanup;
    }

    // Replace the extension.
    p = wcsrchr(wszFilePath, L'.');
    if (!p)
    {
        skip("File path has no file extension: %S\n", wszFilePath);
        goto Cleanup;
    }

    wcscpy(p, L".dll");

    // Check if the corresponding DLL file exists.
    hFind = FindFirstFileW(wszFilePath, &fd);
    if (hFind == INVALID_HANDLE_VALUE)
    {
        skip("My DLL file \"%S\" does not exist!\n", wszFilePath);
        goto Cleanup;
    }

    // Change the extension back to .exe and add the parameters.
    wcscpy(p, L".exe service dummy");

    // Open a handle to the service manager.
    hSC = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (!hSC)
    {
        skip("OpenSCManagerW failed with error %lu!\n", GetLastError());
        goto Cleanup;
    }

    // Ensure that the spooler service is running.
    hService = OpenServiceW(hSC, L"spooler", SERVICE_QUERY_STATUS);
    if (!hService)
    {
        skip("OpenServiceW failed for the spooler service with error %lu!\n", GetLastError());
        goto Cleanup;
    }

    if (!QueryServiceStatus(hService, &ServiceStatus))
    {
        skip("QueryServiceStatus failed for the spooler service with error %lu!\n", GetLastError());
        goto Cleanup;
    }

    if (ServiceStatus.dwCurrentState != SERVICE_RUNNING)
    {
        skip("Spooler Service is not running!\n");
        goto Cleanup;
    }

    CloseServiceHandle(hService);

    // Try to open the service if we've created it in a previous run.
    hService = OpenServiceW(hSC, SERVICE_NAME, SERVICE_ALL_ACCESS);
    if (!hService)
    {
        if (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
        {
            // Create the service.
            hService = CreateServiceW(hSC, SERVICE_NAME, NULL, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, wszFilePath, NULL, NULL, NULL, NULL, NULL);
            if (!hService)
            {
                skip("CreateServiceW failed with error %lu!\n", GetLastError());
                goto Cleanup;
            }
        }
        else
        {
            skip("OpenServiceW failed with error %lu!\n", GetLastError());
            goto Cleanup;
        }
    }

    // Create pipes for the communication with the injected DLL.
    hCommandPipe = CreateNamedPipeW(COMMAND_PIPE_NAME, PIPE_ACCESS_OUTBOUND, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, 1024, 1024, 10000, NULL);
    if (hCommandPipe == INVALID_HANDLE_VALUE)
    {
        skip("CreateNamedPipeW failed for the command pipe with error %lu!\n", GetLastError());
        goto Cleanup;
    }

    hOutputPipe = CreateNamedPipeW(OUTPUT_PIPE_NAME, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 1024, 1024, 10000, NULL);
    if (hOutputPipe == INVALID_HANDLE_VALUE)
    {
        skip("CreateNamedPipeW failed for the output pipe with error %lu!\n", GetLastError());
        goto Cleanup;
    }

    // Start the service with "service" and a dummy parameter (to distinguish it from a call by rosautotest to localspl_apitest:service)
    if (!StartServiceW(hService, 0, NULL))
    {
        skip("StartServiceW failed with error %lu!\n", GetLastError());
        goto Cleanup;
    }

    // Wait till it has injected the DLL and the DLL expects its test name.
    if (!ConnectNamedPipe(hCommandPipe, NULL) && GetLastError() != ERROR_PIPE_CONNECTED)
    {
        skip("ConnectNamedPipe failed for the command pipe with error %lu!\n", GetLastError());
        goto Cleanup;
    }

    // Send the test name.
    if (!WriteFile(hCommandPipe, szTestName, strlen(szTestName) + sizeof(char), &cbWritten, NULL))
    {
        skip("WriteFile failed with error %lu!\n", GetLastError());
        goto Cleanup;
    }

    // Now wait for the DLL to connect to the output pipe.
    if (!ConnectNamedPipe(hOutputPipe, NULL))
    {
        skip("ConnectNamedPipe failed for the output pipe with error %lu!\n", GetLastError());
        goto Cleanup;
    }

    // Get all testing messages from the pipe and output them on stdout.
    while (ReadFile(hOutputPipe, szBuffer, sizeof(szBuffer), &cbRead, NULL) && cbRead)
        fwrite(szBuffer, sizeof(char), cbRead, stdout);

    bSuccessful = TRUE;

Cleanup:
    if (hCommandPipe != INVALID_HANDLE_VALUE)
        CloseHandle(hCommandPipe);

    if (hOutputPipe != INVALID_HANDLE_VALUE)
        CloseHandle(hOutputPipe);

    if (hFind != INVALID_HANDLE_VALUE)
        FindClose(hFind);

    if (hService)
        CloseServiceHandle(hService);

    if (hSC)
        CloseServiceHandle(hSC);

    // If we successfully received test output through the named pipe, we have also output a summary line already.
    // Prevent the testing framework from outputting another "0 tests executed" line in this case.
    if (bSuccessful)
        ExitProcess(0);
}