Jump to content
Sign in to follow this  
ThomasRiedelDk

FireDaemon / NSSM clone?

Recommended Posts

I am trying to run a Win32.exe from inside a service application, - trying to make a servicemanager similar to NSSM.
I try with  AppPath = 'C:\Windows\notepad.exe', I get an error like: "Required privilege missing".
Any clous?

 

function TMyService.StartProcessAsUser(const AppPath: string): Boolean;
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  SecAttr: TSecurityAttributes;
  hToken, hDupToken: THandle;
  UserName, Password, Domain: string;
begin
  Result := False;

  if LogonUser(PChar(FUserName), PChar(FDomain), PChar(FPassword),
      LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, hToken) then
  begin
    if DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, nil, SecurityImpersonation, TokenPrimary, hDupToken) then
    begin
      ZeroMemory(@StartupInfo, SizeOf(TStartupInfo));
      StartupInfo.cb := SizeOf(TStartupInfo);
      StartupInfo.lpDesktop := PChar('Winsta0\Default');
      StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
      StartupInfo.wShowWindow := SW_show;

      if CreateProcessAsUser(hDupToken, PChar(AppPath), nil, nil, nil, False,
        CREATE_NEW_CONSOLE or CREATE_UNICODE_ENVIRONMENT, nil, nil, StartupInfo, ProcessInfo) then
      begin
        Result := True;
        CloseHandle(ProcessInfo.hProcess);
        CloseHandle(ProcessInfo.hThread);
      end else
      begin
        var ErrCode := GetLastError();
        var errormsg : string;
        SetLength(ErrorMsg, 512);
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS, nil,
          ErrCode, 0, PChar(ErrorMsg), Length(ErrorMsg), nil);
        ShowMessage('Fejl ved start af proces: ' + ErrorMsg);
      end;
      CloseHandle(hDupToken);
    end;
    CloseHandle(hToken);
  end;
end;

function SetTokenPrivilege(const APrivilege: string; const AEnable: Boolean = true): Boolean;
var
  LToken: THandle;
  LTokenPriv: TOKEN_PRIVILEGES;
  LPrevTokenPriv: TOKEN_PRIVILEGES;
  LLength: Cardinal;
  LErrval: Cardinal;
begin
  Result := False;
  if OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, LToken) then
  try
    // Get the locally unique identifier (LUID) .
    if LookupPrivilegeValue(nil, PChar(APrivilege), LTokenPriv.Privileges[0].Luid) then
    begin
      LTokenPriv.PrivilegeCount := 1; // one privilege to set
      case AEnable of
        True: LTokenPriv.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
        False: LTokenPriv.Privileges[0].Attributes := 0;
      end;
      LPrevTokenPriv := LTokenPriv;
      // Enable or disable the privilege
      Result := AdjustTokenPrivileges(LToken, False, LTokenPriv, SizeOf(LPrevTokenPriv), LPrevTokenPriv, LLength);
    end;
  finally
    CloseHandle(LToken);
  end;
end;



function TMyService.StartProcess(const AppPath: string): Boolean;
begin
  SetTokenPrivilege('SeAssignPrimaryTokenPrivilege');
  SetTokenPrivilege('SeTcbPrivilege'); // Giver fuld kontrol over tokens
  SetTokenPrivilege('SeIncreaseQuotaPrivilege');
  SetTokenPrivilege('SeImpersonatePrivilege');

  //result := StartProcessWithLogon(apppath, fusername, fpassword, fdomain);

  Result := StartProcessAsUser(AppPath);
end;

 

Share this post


Link to post

Under which user is the service running?
Open "Services", double-click your service, check the "Logon as" tab (W11).

Does it allow interacting with the desktop?
 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×