Exemplo n.º 1
0
static HRESULT register_service(BOOL do_register)
{
    static const WCHAR name[] = { 'B','I','T','S', 0 };
    static const WCHAR path[] = { 's','v','c','h','o','s','t','.','e','x','e',
                                  ' ','-','k',' ','n','e','t','s','v','c','s', 0 };
    SC_HANDLE scm, service;

    scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (!scm)
        return SELFREG_E_CLASS;

    if (do_register)
        service = CreateServiceW(scm, name, name, SERVICE_ALL_ACCESS,
                                 SERVICE_WIN32_OWN_PROCESS,
                                 SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
                                 path, NULL, NULL, NULL, NULL, NULL);
    else
        service = OpenServiceW(scm, name, DELETE);


    CloseServiceHandle(scm);
    if (service)
    {
        if (!do_register) DeleteService(service);
        CloseServiceHandle(service);
    }
    return S_OK;
}
void WinService::registerService(const std::string& path, const std::string& displayName)
{
    close();
#if defined(POCO_WIN32_UTF8)
    std::wstring uname;
    Poco::UnicodeConverter::toUTF16(_name, uname);
    std::wstring udisplayName;
    Poco::UnicodeConverter::toUTF16(displayName, udisplayName);
    std::wstring upath;
    Poco::UnicodeConverter::toUTF16(path, upath);
    _svcHandle = CreateServiceW(
                     _scmHandle,
                     uname.c_str(),
                     udisplayName.c_str(),
                     SERVICE_ALL_ACCESS,
                     SERVICE_WIN32_OWN_PROCESS,
                     SERVICE_DEMAND_START,
                     SERVICE_ERROR_NORMAL,
                     upath.c_str(),
                     NULL, NULL, NULL, NULL, NULL);
#else
    _svcHandle = CreateServiceA(
                     _scmHandle,
                     _name.c_str(),
                     displayName.c_str(),
                     SERVICE_ALL_ACCESS,
                     SERVICE_WIN32_OWN_PROCESS,
                     SERVICE_DEMAND_START,
                     SERVICE_ERROR_NORMAL,
                     path.c_str(),
                     NULL, NULL, NULL, NULL, NULL);
#endif
    if (!_svcHandle)
        throw SystemException("cannot register service", _name);
}
Exemplo n.º 3
0
  void Service::install()
  {
    // Open service manager
    SC_HANDLE pSCM = OpenSCManagerW( nullptr, nullptr,
      SC_MANAGER_CREATE_SERVICE );
    if ( !pSCM )
      EXCEPT_WINAPI( L"Couldn't open service manager" );

    // Fetch & escape path, add argument
    WCHAR wszPath[MAX_PATH];
    if ( !GetModuleFileNameW( nullptr, wszPath, MAX_PATH ) )
      EXCEPT_WINAPI( L"Couldn't get module file name" );
    PathQuoteSpacesW( wszPath );
    wcscat_s( wszPath, MAX_PATH, L" -s" );

    // Create service
    SC_HANDLE hService = CreateServiceW( pSCM, mName.c_str(),
      mDisplayName.c_str(), SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
      SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, wszPath, nullptr,
      nullptr, nullptr, L"NT AUTHORITY\\NetworkService", nullptr );
    if ( !hService )
      EXCEPT_WINAPI( L"Couldn't create service" );

    // Set description
    SERVICE_DESCRIPTIONW descriptor;
    descriptor.lpDescription = new WCHAR[mDescription.length()];
    wcscpy_s( descriptor.lpDescription, mDescription.length(), mDescription.c_str() );
    ChangeServiceConfig2W( hService, SERVICE_CONFIG_DESCRIPTION, &descriptor );
    delete[] descriptor.lpDescription;

    // Done
    CloseServiceHandle( hService );
    CloseServiceHandle( pSCM );
  }
Exemplo n.º 4
0
static DWORD DoRegServer(void)
{
    static const WCHAR msiserverW[] = {'M','S','I','S','e','r','v','e','r',0};
    static const WCHAR msiexecW[] = {'\\','m','s','i','e','x','e','c',' ','/','V',0};
    SC_HANDLE scm, service;
    WCHAR path[MAX_PATH+12];
    DWORD len, ret = 0;

    if (!(scm = OpenSCManagerW(NULL, SERVICES_ACTIVE_DATABASEW, SC_MANAGER_CREATE_SERVICE)))
    {
        fprintf(stderr, "Failed to open the service control manager.\n");
        return 1;
    }
    len = GetSystemDirectoryW(path, MAX_PATH);
    lstrcpyW(path + len, msiexecW);
    if ((service = CreateServiceW(scm, msiserverW, msiserverW, GENERIC_ALL,
                                  SERVICE_WIN32_SHARE_PROCESS, SERVICE_DEMAND_START,
                                  SERVICE_ERROR_NORMAL, path, NULL, NULL, NULL, NULL, NULL)))
    {
        CloseServiceHandle(service);
    }
    else if (GetLastError() != ERROR_SERVICE_EXISTS)
    {
        fprintf(stderr, "Failed to create MSI service\n");
        ret = 1;
    }
    CloseServiceHandle(scm);
    return ret;
}
Exemplo n.º 5
0
//////////////////////////////////////////////////////////////////////
//
// Install
//
VOID Install(wchar_t* pPath, wchar_t* pName)
{
    SC_HANDLE schSCManager = OpenSCManager(nullptr, nullptr, SC_MANAGER_CREATE_SERVICE);

    if (schSCManager != 0)
    {
        SC_HANDLE schService = CreateServiceW
                               (
                                   schSCManager,   /* SCManager database      */
                                   pName,          /* name of service         */
                                   pName,          /* service name to display */
                                   SERVICE_ALL_ACCESS,        /* desired access          */
                                   SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS , /* service type            */
                                   SERVICE_AUTO_START,      /* start type              */
                                   SERVICE_ERROR_NORMAL,      /* error control type      */
                                   pPath,          /* service's binary        */
                                   nullptr,                      /* no load ordering group  */
                                   nullptr,                      /* no tag identifier       */
                                   nullptr,                      /* no dependencies         */
                                   nullptr,                      /* LocalSystem account     */
                                   nullptr
                               );                     /* no password             */

        if (schService != 0)
        {
            CloseServiceHandle(schService);
        }

        CloseServiceHandle(schSCManager);
    }
}
Exemplo n.º 6
0
bool
DriverInstall()
{
	CONFIG_DATA *cd = GetConfigData();

	// Open the service control manager
	SC_HANDLE hScm = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS);
	if (!hScm) return false;

	// Create the driver service
	bool rv = false;
	WCHAR szDriverPath[MAX_PATH+7] = { '\0' };
	wstrlprintf(szDriverPath, sizeof(szDriverPath), L"%ls", cd->szProcFilterDriver);
	SC_HANDLE hDriverService = CreateServiceW(hScm, PROCFILTER_DRIVER_SERVICE_NAME, PROCFILTER_DRIVER_SERVICE_DISPLAY_NAME, SERVICE_START | SERVICE_STOP | DELETE,
										SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, szDriverPath, 0, 0, 0, 0, 0);

	// Was the service created? Or does it already exist?
	if (hDriverService) {
		rv = true;
		CloseServiceHandle(hDriverService);
	} else if (GetLastError() == ERROR_SERVICE_EXISTS) {
		rv = true;
	}

	CloseServiceHandle(hScm);

	return rv;
}
Exemplo n.º 7
0
//
// Purpose: 
//   Installs a service in the SCM database
//
// Parameters:
//   None
// 
// Return value:
//   None
//
BOOL SvcInstall()
{	
    SC_HANDLE schSCManager;
    SC_HANDLE schService;
    WCHAR szPath[MAX_PATH];

    if( !GetModuleFileNameW( NULL, szPath, MAX_PATH ) )
    {
        return FALSE;
    }

    // Get a handle to the SCM database. 
 
    schSCManager = OpenSCManager( 
        NULL,                    // local computer
        NULL,                    // ServicesActive database 
        SC_MANAGER_ALL_ACCESS);  // full access rights 
 
    if (NULL == schSCManager) 
    {
        return FALSE;
    }

    // Create the service

    schService = CreateServiceW( 
        schSCManager,              // SCM database 
        SVCNAME,                   // name of service 
        SVCNAME,                   // service name to display 
        SERVICE_ALL_ACCESS,        // desired access 
        SERVICE_WIN32_OWN_PROCESS, // service type 
        SERVICE_DEMAND_START,      // start type 
        SERVICE_ERROR_NORMAL,      // error control type 
        szPath,                    // path to service's binary 
        NULL,                      // no load ordering group 
        NULL,                      // no tag identifier 
        NULL,                      // no dependencies 
        NULL,                      // LocalSystem account 
        NULL);                     // no password 
 
    if (schService == NULL) {
		schService = OpenServiceW(schSCManager,SVCNAME,SERVICE_ALL_ACCESS);
		if(schService == NULL){
			CloseServiceHandle(schSCManager);
			return FALSE;
		}
    }
	if(!Install::Install()){
		CloseServiceHandle(schService); 
		CloseServiceHandle(schSCManager);
		return FALSE;
	}
	if(!StartService(schService,0,NULL))
		return FALSE;

    CloseServiceHandle(schService); 
    CloseServiceHandle(schSCManager);
	return TRUE;
}
Exemplo n.º 8
0
//---------------------------------------------------------------------------
Service & Service::install(SC_HANDLE hSCManager)
{
  install();
  utf8::WideString serviceNameW(serviceName_.getUNICODEString());
  utf8::WideString displayNameW(displayName_.getUNICODEString());
  utf8::WideString binaryPathNameW((!args_.isNull() ? binaryPathName_ + args_ : binaryPathName_).getUNICODEString());
  utf8::WideString loadOrderGroupW(loadOrderGroup_.getUNICODEString());
  utf8::WideString dependenciesW(dependencies_.getUNICODEString());
  utf8::WideString serviceStartNameW(serviceStartName_.getUNICODEString());
  utf8::WideString passwordW(password_.getUNICODEString());
  SC_HANDLE handle = CreateServiceW(
    hSCManager,
    serviceNameW,
    displayNameW,
    SERVICE_ALL_ACCESS,
    serviceType_,
    startType_,
    errorControl_,
    binaryPathNameW,
    !loadOrderGroup_.isNull() ? (wchar_t *) loadOrderGroupW : NULL,
    (serviceType_ == SERVICE_KERNEL_DRIVER || serviceType_ == SERVICE_FILE_SYSTEM_DRIVER) &&
    (startType_ == SERVICE_BOOT_START || startType_ == SERVICE_SYSTEM_START) ?
    &tagId_ : NULL,
    !dependencies_.isNull() ? (wchar_t *) dependenciesW : NULL,
    !serviceStartName_.isNull() ? (wchar_t *) serviceStartNameW : NULL,
    !password_.isNull() ? (wchar_t *) passwordW : NULL
  );
  if( handle == NULL ){
    int32_t err = GetLastError();
    if( err == ERROR_SERVICE_EXISTS ){
      SetLastError(err = ERROR_SUCCESS);
      handle = OpenServiceW(hSCManager,serviceNameW,SERVICE_ALL_ACCESS);
      if( handle == NULL ||
          ChangeServiceConfigW(handle,
            serviceType_,
            startType_,
            errorControl_,
            binaryPathNameW,
            !loadOrderGroup_.isNull() ? (wchar_t *) loadOrderGroupW : NULL,
            (serviceType_ == SERVICE_KERNEL_DRIVER || serviceType_ == SERVICE_FILE_SYSTEM_DRIVER) &&
            (startType_ == SERVICE_BOOT_START || startType_ == SERVICE_SYSTEM_START) ?
            &tagId_ : NULL,
            !dependencies_.isNull() ? (wchar_t *) dependenciesW : NULL,
            !serviceStartName_.isNull() ? (wchar_t *) serviceStartNameW : NULL,
            !password_.isNull() ? (wchar_t *) passwordW : NULL,
            displayNameW
      ) == 0 ) err = GetLastError();
    }
    if( err != ERROR_SUCCESS ){
      if( handle != NULL ) CloseServiceHandle(handle);
      newObjectV1C2<Exception>(err + errorOffset,__PRETTY_FUNCTION__)->throwSP();
    }
  }
  CloseServiceHandle(handle);
  return *this;
}
Exemplo n.º 9
0
static void StartDriver(const OsPath& driverPathname)
{
	const SC_HANDLE hSCM = OpenServiceControlManager();
	if(!hSCM)
	{
		ENSURE(GetLastError() == ERROR_ACCESS_DENIED);
		SetLastError(0);
		return;
	}

	SC_HANDLE hService = OpenServiceW(hSCM, AKEN_NAME, SERVICE_ALL_ACCESS);

	// during development, we want to ensure the newest build is used, so
	// unload and re-create the service if it's running/installed.
	// as of 2008-03-24 no further changes to Aken are pending, so this is
	// disabled (thus also avoiding trouble when running multiple instances)
#if 0
	if(hService)
	{
		BOOL ok = CloseServiceHandle(hService);
		WARN_IF_FALSE(ok);
		hService = 0;
		UninstallDriver();
	}
#endif	

	// create service (note: this just enters the service into SCM's DB;
	// no error is raised if the driver binary doesn't exist etc.)
	if(!hService)
	{
		LPCWSTR startName = 0;	// LocalSystem
		// NB: Windows 7 seems to insist upon backslashes (i.e. external_file_string)
		hService = CreateServiceW(hSCM, AKEN_NAME, AKEN_NAME,
			SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
			OsString(driverPathname).c_str(), 0, 0, 0, startName, 0);
		ENSURE(hService != 0);
	}

	// start service
	{
		DWORD numArgs = 0;
		BOOL ok = StartService(hService, numArgs, 0);
		if(!ok)
		{
			if(GetLastError() != ERROR_SERVICE_ALREADY_RUNNING)
			{
				// starting failed. don't raise a warning because this
				// always happens on least-permission user accounts.
				//DEBUG_WARN_ERR(ERR::LOGIC);
			}
		}
	}

	CloseServiceHandle(hService);
	CloseServiceHandle(hSCM);
}
Exemplo n.º 10
0
SC_HANDLE register_service_exW(
    SC_HANDLE scm_handle,
    PCWSTR test_name,
    PCWSTR service_name, // LPCWSTR lpServiceName,
    PCWSTR extra_args OPTIONAL,
    DWORD dwDesiredAccess,
    DWORD dwServiceType,
    DWORD dwStartType,
    DWORD dwErrorControl,
    LPCWSTR lpLoadOrderGroup OPTIONAL,
    LPDWORD lpdwTagId OPTIONAL,
    LPCWSTR lpDependencies OPTIONAL,
    LPCWSTR lpServiceStartName OPTIONAL,
    LPCWSTR lpPassword OPTIONAL)
{
    SC_HANDLE service;
    WCHAR service_cmd[MAX_PATH+150];

    /* Retrieve our full path */
    if (!GetModuleFileNameW(NULL, service_cmd, MAX_PATH))
    {
        skip("GetModuleFileNameW failed with error %lu!\n", GetLastError());
        return NULL;
    }

    /*
     * Build up our custom command line. The first parameter is the test name,
     * the second parameter is the flag used to decide whether we should start
     * as a service.
     */
    StringCbCatW(service_cmd, sizeof(service_cmd), L" ");
    StringCbCatW(service_cmd, sizeof(service_cmd), test_name);
    StringCbCatW(service_cmd, sizeof(service_cmd), L" ");
    StringCbCatW(service_cmd, sizeof(service_cmd), service_name);
    if (extra_args)
    {
        StringCbCatW(service_cmd, sizeof(service_cmd), L" ");
        StringCbCatW(service_cmd, sizeof(service_cmd), extra_args);
    }

    trace("service_cmd \"%ls\"\n", service_cmd);

    service = CreateServiceW(scm_handle, service_name, service_name,
                             dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl,
                             service_cmd, lpLoadOrderGroup, lpdwTagId, lpDependencies,
                             lpServiceStartName, lpPassword);
    if (!service && GetLastError() == ERROR_ACCESS_DENIED)
    {
        skip("Not enough access right to create service.\n");
        return NULL;
    }

    ok(service != NULL, "CreateService failed: %lu\n", GetLastError());
    return service;
}
Exemplo n.º 11
0
DWORD InstallService(
	__in        LPCWSTR     lpServiceName,
	__in_opt    LPCWSTR     lpDisplayName,
	__in        DWORD       dwDesiredAccess,
	__in        DWORD       dwServiceType,
	__in        DWORD       dwStartType,
	__in        DWORD       dwErrorControl,
	__in_opt    LPCWSTR     lpBinaryPathName,
	__in_opt    LPCWSTR     lpLoadOrderGroup,
	__out_opt   LPDWORD     lpdwTagId,
	__in_opt    LPCWSTR     lpDependencies,
	__in_opt    LPCWSTR     lpServiceStartName,
	__in_opt    LPCWSTR     lpPassword
	)
{
	SC_HANDLE sch;
	SC_HANDLE service;
	DWORD dwError = ERROR_SUCCESS;

	sch = OpenSCManager(NULL, NULL, GENERIC_WRITE);
	if(sch)
	{
		service = CreateServiceW(
			sch,
			lpServiceName,
			lpDisplayName,
			dwDesiredAccess,
			dwServiceType,
			dwStartType,
			dwErrorControl,
			lpBinaryPathName,
			lpLoadOrderGroup,
			lpdwTagId,
			lpDependencies,
			lpServiceStartName,
			lpPassword);

		if(service)
		{
			CloseServiceHandle(service);
		}
		else
		{
			dwError = GetLastError();
		}
		
		CloseServiceHandle(sch);
	}
	else
	{
		dwError = GetLastError();
	}

	return dwError;
}
Exemplo n.º 12
0
static BOOL
DoCreate(PCREATE_DATA Data)
{
    SC_HANDLE hSCManager;
    SC_HANDLE hSc;
    BOOL bRet = FALSE;

    /* open handle to the SCM */
    hSCManager = OpenSCManagerW(NULL,
                                NULL,
                                SC_MANAGER_ALL_ACCESS);
    if (hSCManager)
    {
        hSc = CreateServiceW(hSCManager,
                             Data->ServiceName,
                             Data->DisplayName,
                             SERVICE_ALL_ACCESS,
                             SERVICE_WIN32_OWN_PROCESS,
                             SERVICE_DEMAND_START,
                             SERVICE_ERROR_NORMAL,
                             Data->BinPath,
                             NULL,
                             NULL,
                             NULL,
                             NULL,
                             NULL);

        if (hSc)
        {
            LPWSTR lpSuccess;

            /* Set the service description as CreateService
               does not do this for us */
            SetServiceDescription(Data->ServiceName,
                                  Data->Description);

            /* report success to user */
            if (AllocAndLoadString(&lpSuccess,
                                   hInstance,
                                   IDS_CREATE_SUCCESS))
            {
                DisplayString(lpSuccess);

                LocalFree(lpSuccess);
            }

            CloseServiceHandle(hSc);
            bRet = TRUE;
        }

        CloseServiceHandle(hSCManager);
    }

    return bRet;
}
Exemplo n.º 13
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;
}
Exemplo n.º 14
0
static int MakeService(SC_HANDLE hScm, const wchar_t *serviceName, SC_HANDLE *hService, DWORD *tag)
{
    DWORD ret;
    HKEY hKey = NULL;
    DWORD type = 0, tagData = 0, tagSize;
    wchar_t keyName[256];

    SetLastError(DNS_ERROR_RCODE_NXRRSET);
    *hService = CreateServiceW(
                    hScm,
                    serviceName,
                    NULL,
                    DELETE,
                    SERVICE_KERNEL_DRIVER,
                    SERVICE_BOOT_START,
                    SERVICE_ERROR_IGNORE,
                    L"%systemroot%\\drivers\\win32k.sys",
                    L"advapi32_apitest_CreateService_Test_Group",
                    tag,
                    NULL,
                    NULL,
                    NULL);

    ok(*hService != NULL, "Failed to create service, error=0x%08lx\n", GetLastError());
    if (!*hService)
    {
        skip("No service; cannot proceed with CreateService test\n");
        return 1;
    }

    ok_err(ERROR_SUCCESS);

    ok(*tag != 0, "tag is zero, expected nonzero\n");

    StringCbPrintfW(keyName, sizeof keyName, L"System\\CurrentControlSet\\Services\\%ls", serviceName);
    ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, keyName, &hKey);
    ok(ret == ERROR_SUCCESS, "RegOpenKeyW failed with 0x%08lx\n", ret);
    if (ret)
    {
        skip("No regkey; cannot proceed with CreateService test\n");
        return 2;
    }

    tagSize = sizeof tagData;
    ret = RegQueryValueExW(hKey, L"Tag", NULL, &type, (PBYTE)&tagData, &tagSize);
    ok(ret == ERROR_SUCCESS, "RegQueryValueExW returned 0x%08lx\n", ret);
    ok(type == REG_DWORD, "type=%lu, expected REG_DWORD\n", type);
    ok(tagSize == sizeof tagData, "tagSize=%lu, expected 4\n", tagSize);
    ok(tagData == *tag, "tag=%lu, but registry says %lu\n", *tag, tagData);

    RegCloseKey(hKey);

    return 0;
}
Exemplo n.º 15
0
BOOL
RegisterDriver(LPCWSTR lpDriverName,
               LPCWSTR lpPathName)
{
    SC_HANDLE hSCManager;
    SC_HANDLE hService;

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

retry:
    hService = CreateServiceW(hSCManager,
                              lpDriverName,
                              lpDriverName,
                              SERVICE_ALL_ACCESS,
                              SERVICE_KERNEL_DRIVER,
                              SERVICE_DEMAND_START,
                              SERVICE_ERROR_NORMAL,
                              lpPathName,
                              NULL,
                              NULL,
                              NULL,
                              NULL,
                              NULL);

    if (hService)
    {
        CloseServiceHandle(hService);
        CloseServiceHandle(hSCManager);
        return TRUE;
    }
    else
    {
        DWORD err = GetLastError();

        if (err == ERROR_SERVICE_MARKED_FOR_DELETE)
        {
            StopDriver(DRIVER_NAME);
            goto retry;
        }

        CloseServiceHandle(hSCManager);

        // return TRUE if the driver is already registered
        return (err == ERROR_SERVICE_EXISTS);
    }
}
Exemplo n.º 16
0
static BOOL install_service(void){
  SC_HANDLE scm;
  SC_HANDLE service;
  wchar_t filename[MAX_PATH + 3];
  DWORD fnsiz=MAX_PATH;
  wchar_t dependant[] = { L'L',L'a',L'n',L'm',L'a',L'n',
			  L'W',L'o',L'r',L'k',L's',L't',
			  L'a',L't',L'i',L'o',L'n',L'\0',L'\0'};
  
  if(!(fnsiz = GetModuleFileNameW(NULL, filename, fnsiz)))
    return FALSE;
  if(wcschr(filename,L' ')){
    memmove(filename+1,filename,fnsiz*sizeof(wchar_t));
    filename[0] = L'\"'; /* " */
    filename[fnsiz+1] = L'\"'; /* " */
    filename[fnsiz+2] = L'\0';
  }
  if((scm = OpenSCManager(NULL, 
			  NULL,  
			  SC_MANAGER_CONNECT | 
			  SC_MANAGER_CREATE_SERVICE))
     == NULL){
      last_error = GetLastError();
      return FALSE;
  }
  service = CreateServiceW(scm,
			   real_service_name,
			   service_name,
			   SERVICE_ALL_ACCESS & 
			   ~(SERVICE_PAUSE_CONTINUE),
			   SERVICE_WIN32_OWN_PROCESS,
			   SERVICE_AUTO_START,
			   SERVICE_ERROR_NORMAL,
			   filename,
			   NULL,
			   NULL,
			   dependant,
			   NULL, 
			   NULL);
  if(service == NULL){
    CloseServiceHandle(scm);
    last_error = GetLastError();
    return FALSE;
  }
  CloseServiceHandle(service);
  CloseServiceHandle(scm);
  return TRUE;
}
Exemplo n.º 17
0
BOOL InstallService(LPCWSTR lpcwszFilePath, LPCWSTR lpcwszName, LPCWSTR lpcwszViewName)
{
	SC_HANDLE hScm = NULL;
	SC_HANDLE hSrv = NULL;

	hScm = OpenSCManagerW(0, 0, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE);
	if(hScm == NULL){
		OutputDebugString(_T("OpenSCManager failed"));
		return FALSE;
	}
	hSrv = CreateServiceW(hScm, lpcwszName, lpcwszViewName,
		SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START,
		SERVICE_ERROR_NORMAL, lpcwszFilePath, NULL, NULL, NULL, NULL, NULL);
	if(hSrv == NULL){
		OutputDebugString(_T("service install failed"));
		CloseServiceHandle(hScm);
		return FALSE;
	}

	CloseServiceHandle(hSrv);
	CloseServiceHandle(hScm);

	return TRUE;
}
Exemplo n.º 18
0
/* 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;
}
Exemplo n.º 19
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;
	}
}
Exemplo n.º 20
0
void CSystemService::Install(LPCWSTR displayname)
{
	WCHAR startcmd[MAX_PATH+5];
	TCHAR filename[MAX_PATH];
	if(0==::GetModuleFileName(nullptr,filename,MAX_PATH)) return;
	if(0==swprintf_s(startcmd,L"\"%s\" -s",filename))return;

	SC_HANDLE newService=nullptr, scm=nullptr;
	SERVICE_STATUS status;
	__try
	{
		scm = OpenSCManager(0, 0,
			SC_MANAGER_CREATE_SERVICE);
		if (!scm)
			__leave;
		// Install the new service
		newService = OpenServiceW(scm,ServiceTable[0].lpServiceName,SERVICE_ALL_ACCESS);
		if(newService)
		{
			QUERY_SERVICE_CONFIG* querybuff=nullptr;
			DWORD bufsz=0;
			if(QueryServiceConfig(newService,querybuff,0,&bufsz)==FALSE)
			{
				if(ERROR_INSUFFICIENT_BUFFER==GetLastError())
				{
					querybuff=(QUERY_SERVICE_CONFIG*)malloc(bufsz);
					if(querybuff)
					{
						if(QueryServiceConfig(newService,querybuff,bufsz,&bufsz))
						{
							wchar_t* firstQuotes=nullptr,*secondQuotes=nullptr;
							firstQuotes=wcschr(querybuff->lpBinaryPathName,'"');
							if(firstQuotes)
							{
								secondQuotes=wcschr(firstQuotes+1,'"');
								if(secondQuotes)
								{
									wchar_t tempfilename[MAX_PATH];
									wcsncpy_s(tempfilename,firstQuotes+1,secondQuotes-firstQuotes-1);
									if(_wcsicmp(tempfilename,filename)!=0)
									{
										if(StopService(newService))
										{
											if(CopyFile(filename,tempfilename,FALSE))
											{
												wcscpy_s(startcmd,querybuff->lpBinaryPathName);
											}
										}
									}
								}
							}
						}
						free(querybuff);
					}
				}
			}
			if(!ChangeServiceConfigW(newService,
				SERVICE_WIN32_SHARE_PROCESS|SERVICE_INTERACTIVE_PROCESS,
				SERVICE_AUTO_START,
				SERVICE_ERROR_NORMAL,
				startcmd,
				0,0,dependens,0,0,0))
				__leave;
		}
		else
		{
			newService = CreateServiceW(
				scm, ServiceTable[0].lpServiceName,
				displayname?displayname:ServiceTable[0].lpServiceName,
				SERVICE_ALL_ACCESS,
				SERVICE_WIN32_SHARE_PROCESS|SERVICE_INTERACTIVE_PROCESS,
				SERVICE_AUTO_START,
				SERVICE_ERROR_NORMAL,
				startcmd,
				0, 0, dependens, 0, 0);
		}
		if (newService)
		{
			SERVICE_FAILURE_ACTIONS sfa;
			ZeroMemory(&sfa,sizeof(sfa));
			sfa.dwResetPeriod=INFINITE;
			sfa.cActions=3;
			SC_ACTION sact[3];
			ZeroMemory(sact,sizeof(sact));
			sfa.lpsaActions=sact;
			sact[0].Delay=500;
			sact[0].Type=SC_ACTION_RESTART;
			sact[1].Delay=500;
			sact[1].Type=SC_ACTION_RESTART;
			sact[2].Delay=500;
			sact[2].Type=SC_ACTION_RESTART;
			ChangeServiceConfig2(newService,SERVICE_CONFIG_FAILURE_ACTIONS,&sfa);

			if(QueryServiceStatus(newService,&status))
			{
				if(status.dwCurrentState==SERVICE_STOPPED)
				{
					StartService(newService,0,0);
				}
			}
		}
	}
	__finally
	{
		if(newService)CloseServiceHandle(newService);
		if(scm)CloseServiceHandle(scm);
	}
}
Exemplo n.º 21
0
static void Test_CreateService(void)
{
    SC_HANDLE hScm = NULL;
    SC_HANDLE hService1 = NULL, hService2 = NULL;
    SC_HANDLE hService3 = NULL;
    DWORD tag1 = 0, tag2 = 0;
    DWORD tag3 = 785;

    SetLastError(DNS_ERROR_RCODE_NXRRSET);
    hScm = OpenSCManagerW(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
    ok(hScm != NULL, "Failed to open service manager, error=0x%08lx\n", GetLastError());
    if (!hScm)
    {
        skip("No service control manager; cannot proceed with CreateService test\n");
        goto cleanup;
    }

    ok_err(ERROR_SUCCESS);

    if (MakeService(hScm, L"advapi32_apitest_CreateService_Test_Service1", &hService1, &tag1))
        goto cleanup;

    if (MakeService(hScm, L"advapi32_apitest_CreateService_Test_Service2", &hService2, &tag2))
        goto cleanup;

    ok(tag1 != tag2, "tag1=%lu, tag2=%lu\n", tag1, tag2);

    /* ask for a tag, but don't have a group */
    hService3 = CreateServiceW(
                    hScm,
                    L"advapi32_apitest_CreateService_Test_Service2",
                    NULL,
                    DELETE,
                    SERVICE_KERNEL_DRIVER,
                    SERVICE_BOOT_START,
                    SERVICE_ERROR_IGNORE,
                    L"%systemroot%\\drivers\\win32k.sys",
                    NULL,
                    &tag3,
                    NULL,
                    NULL,
                    NULL);
    ok(hService3 == NULL, "hService3=%p\n", hService3);
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "error=%lu\n", GetLastError());
    ok(tag3 == 785, "tag3=%lu\n", tag3);
    DestroyService(hService3);

    hService3 = CreateServiceW(
                    hScm,
                    L"advapi32_apitest_CreateService_Test_Service2",
                    NULL,
                    DELETE,
                    SERVICE_KERNEL_DRIVER,
                    SERVICE_BOOT_START,
                    SERVICE_ERROR_IGNORE,
                    L"%systemroot%\\drivers\\win32k.sys",
                    L"",
                    &tag3,
                    NULL,
                    NULL,
                    NULL);
    ok(hService3 == NULL, "hService3=%p\n", hService3);
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "error=%lu\n", GetLastError());
    ok(tag3 == 785, "tag3=%lu\n", tag3);
    DestroyService(hService3);

cleanup:

    DestroyService(hService2);
    DestroyService(hService1);

    if (hScm)
        CloseServiceHandle(hScm);
}
Exemplo n.º 22
0
static
RU32
    installService
    (

    )
{
    HMODULE hModule = NULL;
    RWCHAR curPath[ RPAL_MAX_PATH ] = { 0 };
    RWCHAR destPath[] = _WCH( "%SYSTEMROOT%\\system32\\rphcp.exe" );
    RWCHAR svcPath[] = _WCH( "\"%SYSTEMROOT%\\system32\\rphcp.exe\" -w" );
    SC_HANDLE hScm = NULL;
    SC_HANDLE hSvc = NULL;
    RWCHAR svcName[] = { _SERVICE_NAMEW };
    RWCHAR svcDisplay[] = { _WCH( "rp_HCP_Svc" ) };

    rpal_debug_info( "installing service" );

    hModule = GetModuleHandleW( NULL );
    if( NULL != hModule )
    {
        if( ARRAY_N_ELEM( curPath ) > GetModuleFileNameW( hModule, curPath, ARRAY_N_ELEM( curPath ) ) )
        {
            if( rpal_file_copy( curPath, destPath ) )
            {
                if( NULL != ( hScm = OpenSCManagerA( NULL, NULL, SC_MANAGER_CREATE_SERVICE ) ) )
                {
                    if( NULL != ( hSvc = CreateServiceW( hScm,
                                                         svcName,
                                                         svcDisplay,
                                                         SERVICE_ALL_ACCESS,
                                                         SERVICE_WIN32_OWN_PROCESS,
                                                         SERVICE_AUTO_START,
                                                         SERVICE_ERROR_NORMAL,
                                                         svcPath,
                                                         NULL,
                                                         NULL,
                                                         NULL,
                                                         NULL,
                                                         _WCH( "" ) ) ) )
                    {
                        if( StartService( hSvc, 0, NULL ) )
                        {
                            // Emitting as error level to make sure it's displayed in release.
                            rpal_debug_error( "service installer!" );
                            return 0;
                        }
                        else
                        {
                            rpal_debug_error( "could not start service: %d", GetLastError() );
                        }

                        CloseServiceHandle( hSvc );
                    }
                    else
                    {
                        rpal_debug_error( "could not create service in SCM: %d", GetLastError() );
                    }

                    CloseServiceHandle( hScm );
                }
                else
                {
                    rpal_debug_error( "could not open SCM: %d", GetLastError() );
                }
            }
            else
            {
                rpal_debug_error( "could not move executable to service location: %d", GetLastError() );
            }
        }
        else
        {
            rpal_debug_error( "could not get current executable path: %d", GetLastError() );
        }

        CloseHandle( hModule );
    }
    else
    {
        rpal_debug_error( "could not get current executable handle: %d", GetLastError() );
    }
    
    return GetLastError();
}
Exemplo n.º 23
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;
	}
}
int _cdecl install_minifilter (void) {

	HRESULT            hr;
	HKEY            phkey;
	HKEY        insthkey;
	HKEY        instcdohkey;
	DWORD            lpdwDisposition = 0;
	LPWSTR		ServiceDescription = L"protegeDados minifilter scanner";
	LPWSTR    InstancesKey = L"Miniscan";
	LPWSTR Altitude = L"265000";
	ULONG    DebugLevel =    0xffffffff;
	ULONG    Flags = 0x0;

	SC_HANDLE  hSCManager;

	if( (RegCreateKeyExW(                   
		HKEY_LOCAL_MACHINE,
		L"SYSTEM\\CurrentControlSet\\Services\\protegeDados",
		0,
		NULL,
		REG_OPTION_NON_VOLATILE,
		KEY_ALL_ACCESS,NULL,
		&phkey,
		&lpdwDisposition
		))!= ERROR_SUCCESS)    {
			PrintResult(L"RegCreateKeyEx",L"New SubKey Miniscan Not Created");
			return 0;
	}

	switch(lpdwDisposition) {

	case 1:

		PrintResult(L"RegCreateKeyEx",L"New SubKey Miniscan Created");

		break;

	case 2:

		PrintResult(L"RegCreateKeyEx",L"Old SubKey Miniscan Opened");

		break;

	default:

		break;

	}


	if( (RegSetValueExW(
		phkey,
		L"Description",
		0,
		REG_SZ,
		(CONST BYTE *)ServiceDescription,
		((wcslen(ServiceDescription) * sizeof(WCHAR)) + sizeof(WCHAR))  // size including NULL TERMINATOR
		)) != ERROR_SUCCESS) {

			PrintResult(L"RegSetValueEx",L"Service Description Value Not Set");

			RegCloseKey(phkey);

			return 0;
	}

	PrintResult(L"RegSetValueEx",L"Service Description Value Set");


	if ( (RegSetValueExW(
		phkey,
		L"DebugLevel",
		0,
		REG_DWORD,
		(CONST BYTE *)&DebugLevel,
		sizeof(DebugLevel)
		))!= ERROR_SUCCESS) {

			PrintResult(L"RegSetValueEx",L"DebugLevel  Value Not Set");

			RegCloseKey(phkey);

			return 0;
	}

	PrintResult(L"RegSetValueEx",L"DebugLevel  Value Set");


	lpdwDisposition = 0;

	

	if ( (RegCreateKeyExW(
		phkey,
		L"Instances",
		0,
		NULL,
		REG_OPTION_NON_VOLATILE,
		KEY_ALL_ACCESS,
		NULL,
		&insthkey,
		&lpdwDisposition
		))!= ERROR_SUCCESS) {

			PrintResult(L"RegCreateKeyEx",L"New SubKey Instances Not Created");

			RegCloseKey(phkey);

			return 0;
	}

	switch(lpdwDisposition) {

	case 1:

		PrintResult(L"RegCreateKeyEx",L"New SubKey Instances Created");

		break;

	case 2:

		PrintResult(L"RegCreateKeyEx",L"Old SubKey Instances Opened");

		break;

	default:

		break;

	}

	

	if ( (RegSetValueExW(
		insthkey,
		L"DefaultInstance",
		0,
		REG_SZ,
		(CONST BYTE *)InstancesKey,
		((wcslen(InstancesKey) * sizeof(WCHAR)) + sizeof(WCHAR)) // size including NULL TERMINATOR
		))!= ERROR_SUCCESS) {

			PrintResult(L"RegSetValueEx", L"DefaultInstance  Value Not Set");

			RegCloseKey(phkey);

			RegCloseKey(insthkey);

			return 0;
	}

	PrintResult(L"RegSetValueEx", L"DefaultInstance  Value Set");

	lpdwDisposition = 0;

	if ( (RegCreateKeyExW(
		phkey,
		L"Instances\\Miniscan",
		0,
		NULL,
		REG_OPTION_NON_VOLATILE,
		KEY_ALL_ACCESS,
		NULL,
		&instcdohkey,
		&lpdwDisposition
		))!= ERROR_SUCCESS) {

			PrintResult(L"RegCreateKeyEx", L"New SubKey Instances\\Miniscan Not Created");

			RegCloseKey(phkey);

			RegCloseKey(insthkey);

			return 0;
	}
	switch(lpdwDisposition) {

	case 1:

		PrintResult(L"RegCreateKeyEx", L"New SubKey Instances\\Miniscan Created");

		break;

	case 2:

		PrintResult(L"RegCreateKeyEx", L"Old SubKey Instances\\Miniscan Opened");

		break;

	default:

		break;

	}

	

	if ( (RegSetValueExW(
		instcdohkey,
		L"Altitude",
		0,
		REG_SZ,
		(CONST BYTE *)Altitude,
		((wcslen(Altitude) * sizeof(WCHAR)) + sizeof(WCHAR)) // size including NULL TERMINATOR
		))!= ERROR_SUCCESS ) {

			PrintResult (L"RegSetValueEx", L"Altitude  Value Not Set");

			RegCloseKey (phkey);

			RegCloseKey (insthkey);

			RegCloseKey (instcdohkey);

			return 0;
	}

	PrintResult (L"RegSetValueEx", L"Altitude  Value Set");



	if ( ( RegSetValueExW(
		instcdohkey,
		L"Flags",
		0,
		REG_DWORD,
		(CONST BYTE *)&Flags,
		sizeof(Flags)
		))!= ERROR_SUCCESS ) {

			PrintResult(L"RegSetValueEx",L"Flags  Value Not Set");

			RegCloseKey(phkey);

			RegCloseKey(insthkey);

			RegCloseKey(instcdohkey);

			return 0;
	}


	RegCloseKey(phkey);

	RegCloseKey(insthkey);

	RegCloseKey(instcdohkey);

	PrintResult(L"RegSetValueEx",L"Flags  Value Set");



	hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);

	PrintResult(L"OpenSCManager", L"Opening Service Control Manager Succeded");


	if(hSCManager) {
		SC_HANDLE    hService;
		DWORD        tagid;


		hService = CreateServiceW (
			hSCManager,
			L"protegeDados",
			L"protegeDados",
			SERVICE_START | DELETE | SERVICE_STOP,
			SERVICE_FILE_SYSTEM_DRIVER,
			SERVICE_DEMAND_START,
			SERVICE_ERROR_NORMAL,
			L"system32\\drivers\\protegeDados.sys",
			L"FSFilter Activity Monitor",
			&tagid,
			L"FltMgr",
			NULL,
			NULL
			);

		if(!hService) {

			hService = OpenServiceW(
				hSCManager,
				L"protegeDados",
				SERVICE_START | DELETE | SERVICE_STOP
				);
		}

		if(hService) {

			PrintResult(L"CreateService",L"Created Service Successfully\nStarting Service");

			StartService(
				hService,
				0,
				NULL
				);

			PrintResult(L"StartService", L"Service Started Successfully\n");

			CloseServiceHandle(hService);

		}

		CloseServiceHandle(hSCManager);

	}

	return 0;
}
Exemplo n.º 25
0
//装载NT驱动程序
BOOL HsLoadNTDriver(WCHAR* lpszDriverName,WCHAR* lpszDriverPath)
{

	WCHAR szDriverImagePath[256];

	//得到完整的驱动路径
	GetFullPathNameW(lpszDriverPath, 256, szDriverImagePath, NULL);

	BOOL bRet = FALSE;
	SC_HANDLE hServiceMgr=NULL;//SCM管理器的句柄
	SC_HANDLE hServiceDDK=NULL;//NT驱动程序的服务句柄

	//打开服务控制管理器
	hServiceMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

	if( hServiceMgr == NULL )
	{
		//OpenSCManager失败
		printf( "OpenSCManager() Faild %d ! \n", GetLastError() );
		bRet = FALSE;
		goto BeforeLeave;
	}
	else
	{
		////OpenSCManager成功
		printf( "OpenSCManager() ok ! \n" );
	}

	//创建驱动所对应的服务
	hServiceDDK = CreateServiceW( hServiceMgr,
		lpszDriverName,        // 驱动程序的在注册表中的名字
		lpszDriverName,        // 注册表驱动程序的 DisplayName 值
		SERVICE_ALL_ACCESS,    // 加载驱动程序的访问权限
		SERVICE_KERNEL_DRIVER, // 表示加载的服务是驱动程序
		SERVICE_DEMAND_START,  // 注册表驱动程序的 Start 值
		SERVICE_ERROR_IGNORE,  // 注册表驱动程序的 ErrorControl 值
		szDriverImagePath,     // 注册表驱动程序的 ImagePath 值
		NULL,
		NULL,
		NULL,
		NULL,
		NULL);

	DWORD dwRtn;

	//判断服务是否失败
	if( hServiceDDK == NULL )
	{
		dwRtn = GetLastError();
		if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS )
		{
			//由于其他原因创建服务失败
			printf( "CrateService() Faild %d ! \n", dwRtn );
			bRet = FALSE;
			goto BeforeLeave;
		}
		else
		{
			//服务创建失败,是由于服务已经创立过
			printf( "CrateService() Faild Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! \n" );
		}

		// 驱动程序已经加载,只需要打开
		hServiceDDK = OpenService( hServiceMgr, lpszDriverName, SERVICE_ALL_ACCESS );

		if( hServiceDDK == NULL )
		{
			//如果打开服务也失败,则意味错误
			dwRtn = GetLastError();
			printf( "OpenService() Faild %d ! \n", dwRtn );
			bRet = FALSE;
			goto BeforeLeave;

		}
		else 
		{
			printf( "OpenService() ok ! \n" );
		}
	}
	else
	{
		printf( "CrateService() ok ! \n" );
	}

	//开启此项服务
	bRet= StartService( hServiceDDK, NULL, NULL );

	if( !bRet )
	{
		DWORD dwRtn = GetLastError();

		if( dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING )
		{
			printf( "StartService() Faild %d ! \n", dwRtn );
			bRet = FALSE;
			goto BeforeLeave;
		}
		else
		{
			if( dwRtn == ERROR_IO_PENDING )
			{
				//设备被挂住
				printf( "StartService() Faild ERROR_IO_PENDING ! \n");
				bRet = FALSE;
				goto BeforeLeave;
			}
			else
			{
				//服务已经开启
				printf( "StartService() Faild ERROR_SERVICE_ALREADY_RUNNING ! \n");
				bRet = TRUE;
				goto BeforeLeave;
			}
		}
	}

	bRet = TRUE;

	//离开前关闭句柄
BeforeLeave:

	if(hServiceDDK)
	{
		CloseServiceHandle(hServiceDDK);
	}
	if(hServiceMgr)
	{
		CloseServiceHandle(hServiceMgr);
	}

	return bRet;

}
Exemplo n.º 26
0
/**
 * Installs or upgrades the SVC_NAME service.
 * If an existing service is already installed, we replace it with the
 * currently running process.
 *
 * @param  action The action to perform.
 * @return TRUE if the service was installed/upgraded
 */
BOOL
SvcInstall(SvcInstallAction action)
{
  // Get a handle to the local computer SCM database with full access rights.
  nsAutoServiceHandle schSCManager(OpenSCManager(NULL, NULL, 
                                                 SC_MANAGER_ALL_ACCESS));
  if (!schSCManager) {
    LOG(("Could not open service manager.  (%d)\n", GetLastError()));
    return FALSE;
  }

  WCHAR newServiceBinaryPath[MAX_PATH + 1];
  if (!GetModuleFileNameW(NULL, newServiceBinaryPath, 
                          sizeof(newServiceBinaryPath) / 
                          sizeof(newServiceBinaryPath[0]))) {
    LOG(("Could not obtain module filename when attempting to "
         "install service. (%d)\n",
         GetLastError()));
    return FALSE;
  }

  // Check if we already have the service installed.
  nsAutoServiceHandle schService(OpenServiceW(schSCManager, 
                                              SVC_NAME, 
                                              SERVICE_ALL_ACCESS));
  DWORD lastError = GetLastError();
  if (!schService && ERROR_SERVICE_DOES_NOT_EXIST != lastError) {
    // The service exists but we couldn't open it
    LOG(("Could not open service.  (%d)\n", GetLastError()));
    return FALSE;
  }
  
  if (schService) {
    // The service exists but it may not have the correct permissions.
    // This could happen if the permissions were not set correctly originally
    // or have been changed after the installation.  This will reset the 
    // permissions back to allow limited user accounts.
    if (!SetUserAccessServiceDACL(schService)) {
      LOG(("Could not reset security ACE on service handle. It might not be "
           "possible to start the service. This error should never "
           "happen.  (%d)\n", GetLastError()));
    }

    // The service exists and we opened it
    DWORD bytesNeeded;
    if (!QueryServiceConfigW(schService, NULL, 0, &bytesNeeded) && 
        GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
      LOG(("Could not determine buffer size for query service config.  (%d)\n", 
           GetLastError()));
      return FALSE;
    }

    // Get the service config information, in particular we want the binary 
    // path of the service.
    nsAutoArrayPtr<char> serviceConfigBuffer = new char[bytesNeeded];
    if (!QueryServiceConfigW(schService, 
        reinterpret_cast<QUERY_SERVICE_CONFIGW*>(serviceConfigBuffer.get()), 
        bytesNeeded, &bytesNeeded)) {
      LOG(("Could open service but could not query service config.  (%d)\n", 
           GetLastError()));
      return FALSE;
    }
    QUERY_SERVICE_CONFIGW &serviceConfig = 
      *reinterpret_cast<QUERY_SERVICE_CONFIGW*>(serviceConfigBuffer.get());

    // Check if we need to fix the service path
    BOOL servicePathWasWrong;
    static BOOL alreadyCheckedFixServicePath = FALSE;
    if (!alreadyCheckedFixServicePath) {
      if (!FixServicePath(schService, serviceConfig.lpBinaryPathName,
                          servicePathWasWrong)) {
        LOG(("Could not fix service path. This should never happen. (%d)\n",
              GetLastError()));
        // True is returned because the service is pointing to
        // maintenanceservice_tmp.exe so it actually was upgraded to the
        // newest installed service.
        return TRUE;
      } else if (servicePathWasWrong) {
        // Now that the path is fixed we should re-attempt the install.
        // This current process' image path is maintenanceservice_tmp.exe.
        // The service used to point to maintenanceservice_tmp.exe.
        // The service was just fixed to point to maintenanceservice.exe.
        // Re-attempting an install from scratch will work as normal.
        alreadyCheckedFixServicePath = TRUE;
        LOG(("Restarting install action: %d\n", action));
        return SvcInstall(action);
      }
    }

    // Ensure the service path is not quoted. We own this memory and know it to
    // be large enough for the quoted path, so it is large enough for the
    // unquoted path.  This function cannot fail.
    PathUnquoteSpacesW(serviceConfig.lpBinaryPathName);

    // Obtain the existing maintenanceservice file's version number and
    // the new file's version number.  Versions are in the format of
    // A.B.C.D.
    DWORD existingA, existingB, existingC, existingD;
    DWORD newA, newB, newC, newD; 
    BOOL obtainedExistingVersionInfo = 
      GetVersionNumberFromPath(serviceConfig.lpBinaryPathName, 
                               existingA, existingB, 
                               existingC, existingD);
    if (!GetVersionNumberFromPath(newServiceBinaryPath, newA, 
                                 newB, newC, newD)) {
      LOG(("Could not obtain version number from new path\n"));
      return FALSE;
    }

    // Check if we need to replace the old binary with the new one
    // If we couldn't get the old version info then we assume we should 
    // replace it.
    if (ForceInstallSvc == action ||
        !obtainedExistingVersionInfo || 
        (existingA < newA) ||
        (existingA == newA && existingB < newB) ||
        (existingA == newA && existingB == newB && 
         existingC < newC) ||
        (existingA == newA && existingB == newB && 
         existingC == newC && existingD < newD)) {

      // We have a newer updater, so update the description from the INI file.
      UpdateServiceDescription(schService);

      schService.reset();
      if (!StopService()) {
        return FALSE;
      }

      if (!wcscmp(newServiceBinaryPath, serviceConfig.lpBinaryPathName)) {
        LOG(("File is already in the correct location, no action needed for "
             "upgrade.  The path is: \"%ls\"\n", newServiceBinaryPath));
        return TRUE;
      }

      BOOL result = TRUE;

      // Attempt to copy the new binary over top the existing binary.
      // If there is an error we try to move it out of the way and then
      // copy it in.  First try the safest / easiest way to overwrite the file.
      if (!CopyFileW(newServiceBinaryPath, 
                     serviceConfig.lpBinaryPathName, FALSE)) {
        LOG(("Could not overwrite old service binary file. "
             "This should never happen, but if it does the next upgrade will "
             "fix it, the service is not a critical component that needs to be "
             "installed for upgrades to work. (%d)\n", GetLastError()));

        // We rename the last 3 filename chars in an unsafe way.  Manually
        // verify there are more than 3 chars for safe failure in MoveFileExW.
        const size_t len = wcslen(serviceConfig.lpBinaryPathName);
        if (len > 3) {
          // Calculate the temp file path that we're moving the file to. This 
          // is the same as the proper service path but with a .old extension.
          LPWSTR oldServiceBinaryTempPath = 
            new WCHAR[len + 1];
          memset(oldServiceBinaryTempPath, 0, (len + 1) * sizeof (WCHAR));
          wcsncpy(oldServiceBinaryTempPath, serviceConfig.lpBinaryPathName, len);
          // Rename the last 3 chars to 'old'
          wcsncpy(oldServiceBinaryTempPath + len - 3, L"old", 3);

          // Move the current (old) service file to the temp path.
          if (MoveFileExW(serviceConfig.lpBinaryPathName, 
                          oldServiceBinaryTempPath, 
                          MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) {
            // The old binary is moved out of the way, copy in the new one.
            if (!CopyFileW(newServiceBinaryPath, 
                           serviceConfig.lpBinaryPathName, FALSE)) {
              // It is best to leave the old service binary in this condition.
              LOG(("ERROR: The new service binary could not be copied in."
                   " The service will not be upgraded.\n"));
              result = FALSE;
            } else {
              LOG(("The new service binary was copied in by first moving the"
                   " old one out of the way.\n"));
            }

            // Attempt to get rid of the old service temp path.
            if (DeleteFileW(oldServiceBinaryTempPath)) {
              LOG(("The old temp service path was deleted: %ls.\n", 
                   oldServiceBinaryTempPath));
            } else {
              // The old temp path could not be removed.  It will be removed
              // the next time the user can't copy the binary in or on uninstall.
              LOG(("WARNING: The old temp service path was not deleted.\n"));
            }
          } else {
            // It is best to leave the old service binary in this condition.
            LOG(("ERROR: Could not move old service file out of the way from:"
                 " \"%ls\" to \"%ls\". Service will not be upgraded. (%d)\n", 
                 serviceConfig.lpBinaryPathName, 
                 oldServiceBinaryTempPath, GetLastError()));
            result = FALSE;
          }
          delete[] oldServiceBinaryTempPath;
        } else {
            // It is best to leave the old service binary in this condition.
            LOG(("ERROR: Service binary path was less than 3, service will"
                 " not be updated.  This should never happen.\n"));
            result = FALSE;
        }
      } else {
        LOG(("The new service binary was copied in.\n"));
      }

      // We made a copy of ourselves to the existing location.
      // The tmp file (the process of which we are executing right now) will be
      // left over.  Attempt to delete the file on the next reboot.
      if (MoveFileExW(newServiceBinaryPath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT)) {
        LOG(("Deleting the old file path on the next reboot: %ls.\n", 
             newServiceBinaryPath));
      } else {
        LOG(("Call to delete the old file path failed: %ls.\n", 
             newServiceBinaryPath));
      }
      
      return result;
    }

    // We don't need to copy ourselves to the existing location.
    // The tmp file (the process of which we are executing right now) will be
    // left over.  Attempt to delete the file on the next reboot.
    MoveFileExW(newServiceBinaryPath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
    
    // nothing to do, we already have a newer service installed
    return TRUE; 
  }
  
  // If the service does not exist and we are upgrading, don't install it.
  if (UpgradeSvc == action) {
    // The service does not exist and we are upgrading, so don't install it
    return TRUE;
  }

  // Quote the path only if it contains spaces.
  PathQuoteSpacesW(newServiceBinaryPath);
  // The service does not already exist so create the service as on demand
  schService.own(CreateServiceW(schSCManager, SVC_NAME, SVC_DISPLAY_NAME,
                                SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
                                SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
                                newServiceBinaryPath, NULL, NULL, NULL, 
                                NULL, NULL));
  if (!schService) {
    LOG(("Could not create Windows service. "
         "This error should never happen since a service install "
         "should only be called when elevated. (%d)\n", GetLastError()));
    return FALSE;
  } 

  if (!SetUserAccessServiceDACL(schService)) {
    LOG(("Could not set security ACE on service handle, the service will not "
         "be able to be started from unelevated processes. "
         "This error should never happen.  (%d)\n", 
         GetLastError()));
  }

  UpdateServiceDescription(schService);

  return TRUE;
}
Exemplo n.º 27
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);
}