Community Forums
Page 2 of 5 FirstFirst 1234 ... LastLast
Results 6 to 10 of 21

Thread: ServiceExistsService InstallScript function doesn't seem to always work within Vista

  1. #6
    Join Date
    May 2007
    Location
    Eden Praire, MN
    Posts
    709
    I tried setting the properties on setup.exe to "Run this program as administrator" and got the same results.
    FYI, GetExtendedErrInfo reveals ScriptFile=C:\CodeBases\isdev\Script\ISRT\Src\Service.rul LineNumber=327 Error=5.
    Right... when I use SC QUERY in cmd window I don't need to elevate the process.
    I tried ignoring the result for 'ServiceExistsService' and proceeded to execute 'ServiceGetServiceState'. That fails too. In that case GetExtendedErrInfo shows ScriptFile=C:\CodeBases\isdev\Script\ISRT\Src\Service.rul LineNumber=357 Error=6.
    I don't think it is a Vista permissions issue because after I get these errors I can "LaunchAppAndWait" a bat file that stops, uninstalls, reinstalls, and starts MSDTC (which I was hoping not to do if it was already running, but it seems I can't detect that). So it seems to be a problem with ServiceExistsService and ServiceGetServiceState.

  2. #7
    Join Date
    Jul 2003
    Location
    Austin, TX
    Posts
    4,430
    Sorry for disapearing, I've been swamped at work. I'm restoring a Vista image to play with this a bit.

    In the mean time, try looking at this:

    http://www.installsite.org/pages/en/isp_svc.htm

    Windows Installer does such a good job ( with one exception: services that require assemblies to be in the GAC to start ) of handling services that i usually don't roll script to interact with the SCM.

    Back in the `old` days, InstallScript had no SCM functions in it's language so we used the wrapper functions on InstallSite. Give it a try... I'll let you know how my testing goes.
    Christopher Painter
    ISWIX, LLC.
    Visit iswix.com for contact information

  3. #8
    Join Date
    Jul 2003
    Location
    Austin, TX
    Posts
    4,430
    I can reproduce this problem, however I can also resolve it.

    If you build your MSI with a setup.exe bootstrapper and manifest the setup to require administrative privs, you'll notice it starts working. This is because the entire process ( including the MSI client side UI sequence ) is elevated.

    You are also correct that sc query works unelevated.

    I'm going to pass this over to Macrovision, but here is my theory. I'm guessing that ServiceExistsService is calling OpenSCManager and asking for more access rights then are needed. Give me some time and I'll see if I can come up with a home-grown SCM function that can check the service state without experiencing this problem...

    OpenSCManager:
    http://msdn2.microsoft.com/en-us/library/ms684323.aspx

    Service Security and Access Rights:
    http://msdn2.microsoft.com/en-us/library/ms685981.aspx
    Christopher Painter
    ISWIX, LLC.
    Visit iswix.com for contact information

  4. #9
    Join Date
    Jan 2006
    Posts
    1,114
    I have been very busy, too bad because I could've provided some additional info here.

    Any of the InstallScript service functions attempt to open the service with SC_MANAGER_ALL_ACCESS permissions. This is not going to work for a standard user account.

    I've created a WO for this under Issue IOC-000059857.

    The best workaround is to only run this in deferred context or set your requested execution level to asAdministrator.

  5. #10
    Join Date
    Jul 2003
    Location
    Austin, TX
    Posts
    4,430
    Time for me to write a blog.....

    I didn't have access to the source code for ServiceExistsService but I do have access to example Code from InstallSite. Changing the rights request to the OpenSCManager and OpenService to only require SC_MANAGER_CONNECT privedge allows the ServiceExists check to be made on Vista without requiring the elevated token from UAC.

    Put the below code in a NTService.rul file and call it from Setup.rul like this:

    //top of setup.rul
    #include "NTService.rul"

    // inside your function
    bExists = _IsServiceAvailable( "BITS" );



    Code:
    #if _ISCRIPT_VER >= 0x600
      #ifndef AddressString
        #define AddressString   &
      #endif
    #endif
    
    // constants copied from Winsvc.h
    #define SC_MANAGER_ALL_ACCESS          0x000F003F
    #define SERVICE_ALL_ACCESS             0x000F01FF
    #define SC_MANAGER_CONNECT			   0x00000001
    
    // Prototype the service control APIs
    prototype NUMBER AdvAPI32.OpenSCManagerA(POINTER, POINTER, NUMBER);
    prototype NUMBER Advapi32.OpenServiceA(NUMBER, POINTER, NUMBER);
    prototype BOOL   AdvAPI32.CloseServiceHandle(NUMBER);
    prototype BOOL   Advapi32.QueryServiceStatus(NUMBER, POINTER);
    prototype NUMBER KERNEL.GetLastError();
    
    // global service handles, filled and released
    POINTER ptrMcName, ptrDBName, pszSStartName;
    NUMBER  schService, schSCManager;
    
    // prototype the InstallScript functions.
    prototype _InitServiceConnections(STRING);
    prototype _CloseServiceConnections();
    prototype _IsServiceAvailable(STRING);
    
    function _InitServiceConnections(szServiceName)
    	NUMBER nReturn, nResult;
    begin
      // Initialize global variables
      schService = NULL;
      schSCManager = NULL;
      ptrMcName = NULL;     // use local machine
      ptrDBName = NULL;     // open services active database
    
      // Locals
      nReturn = 0;
      nResult = 0;
    
      // Load ADVAPI32.DLL, which is necessary for Service Manager-
      // related functions.
      if (UseDLL("AdvAPI32.dll") < 0) then
    #ifdef _NTS_DEBUG
        MessageBox ("Couldn't load AdvAPI32.dll.", SEVERE);
    #endif
        nReturn = -1;
      endif;
    
      // First establish the connection with the Service Manager
      if (nReturn = 0) then
        schSCManager = OpenSCManagerA(ptrMcName, ptrDBName, SC_MANAGER_CONNECT);
        if (schSCManager = NULL) then
          nResult = GetLastError();
    #ifdef _NTS_DEBUG
          SprintfBox(INFORMATION, "OpenSCManagerA Error",
                     "Error connecting to Service Manager.\n\n" +
                     "Error number = %ld.", nResult);
    #endif
          nReturn = -1;
        endif;
      endif;
    
      if (szServiceName != "") then
        pszSStartName = AddressString(szServiceName);  //FIX IS3
        if (nReturn = 0) then
          // Now open the service.
          schService = OpenServiceA(schSCManager, pszSStartName, SC_MANAGER_CONNECT);  //FIX IS3
          if (schService = NULL) then
            nResult = GetLastError();
    #ifdef _NTS_DEBUG
            SprintfBox(INFORMATION, "OpenService Error",
                       "Error opening service.\n\n"+
                       "Error number = %ld.", nResult);
    #endif
            nReturn = -1;
          endif;
        endif;
      endif;
      
      return nReturn;
    end;
    
    /////////////////////////////////////////////////////////////
    //    FUNCTION:  _CloseServiceConnections()
    //
    // DESCRIPTION:  Closes connections to services and manager
    //
    //      OUTPUT:  0 If function is successful in connecting
    //              -1 If function fails to connect
    /////////////////////////////////////////////////////////////
    function _CloseServiceConnections()
    	NUMBER nResult;
    begin
      // Close connection to Service Manager
      if (schSCManager != NULL) then
        nResult = CloseServiceHandle(schSCManager);
      endif;
    
      // Close handle of the service installed
      if (schService != NULL) then
        nResult = CloseServiceHandle(schService);
      endif;
    
      // Deinitialize global variables, just in case
      schService = NULL;
      schSCManager = NULL;
      ptrMcName = NULL;     // use local machine
      ptrDBName = NULL;     // open services active database
    
      UnUseDLL("AdvAPI32.dll");
    
      return nResult;
    end;
    
    
    /////////////////////////////////////////////////////////////
    // FUNCTION: _IsServiceAvailable(szServiceName)
    //
    // DESCRIPTION:  Checks to see if a service is installed
    //
    // INPUT:  szServiceName = service name to check for
    //
    //      OUTPUT:  0 If service is available
    //              -1 If service is unavailable
    /////////////////////////////////////////////////////////////
    function _IsServiceAvailable(szServiceName)
    	NUMBER nvResult;
    begin
      nvResult = _InitServiceConnections(szServiceName);
      _CloseServiceConnections();
      return nvResult;
    end;
    Christopher Painter
    ISWIX, LLC.
    Visit iswix.com for contact information

Page 2 of 5 FirstFirst 1234 ... LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •