Service executant programme avec droits d'administrateurs

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
ChaudEf
Messages : 179
Inscription : dim. 27/déc./2015 17:02
Localisation : Strasbourg

Service executant programme avec droits d'administrateurs

Message par ChaudEf »

Bonjour
J'utilise le code de JHPJHP pour creer des services (http://www.purebasic.fr/english/viewtop ... 12&t=60881), mais je plante sur un point.
Le service lance un programme, et tout ce passe bien, mais si je regle cet exe a necessiter les droits d'administrateurs, ca ne marche plus.

Est ce que les services n'ont pas acces aux programmes necessitant droits d'administration, ou j'ai mal configure quelque chose?

Merci.

n.b. tant que j'y suis, n'y-a-t-il pas un moyen plus facile (et plus court) pour creer un service?

ci joint le code de JHP

Code : Tout sélectionner

Global ServiceName.s = ProgramParameter()
Global lpServiceStatus.SERVICE_STATUS
Global hServiceStatus

Prototype protoGetProcessImageFileName(hProcess, lpImageFileName, nSize)
Prototype protoQueryFullProcessImageName(hProcess, dwFlags, lpExeName, lpdwSize)
Prototype protoWTSGetActiveConsoleSessionId()
Prototype protoWTSQueryUserToken(SessionId, phToken)
Prototype protoCreateEnvironmentBlock(lpEnvironment, hToken, bInherit)
Prototype protoDestroyEnvironmentBlock(lpEnvironment)

Procedure AdjustCurrentProcessPrivilege(LookupPrivilege.s, PrivilegeState)
  Result = #False

  If OpenProcessToken_(GetCurrentProcess_(), #TOKEN_ADJUST_PRIVILEGES | #TOKEN_QUERY, @TokenHandle)
    lpLuid.LUID : #SE_PRIVILEGE_REMOVED = 4

    If LookupPrivilegeValue_(#Null, LookupPrivilege , @lpLuid)
      NewState.TOKEN_PRIVILEGES

      With NewState
        \PrivilegeCount = 1
        \Privileges[0]\Luid\LowPart = lpLuid\LowPart
        \Privileges[0]\Luid\HighPart = lpLuid\HighPart

        If PrivilegeState
          \Privileges[0]\Attributes = #SE_PRIVILEGE_ENABLED
        Else
          \Privileges[0]\Attributes = #SE_PRIVILEGE_REMOVED
        EndIf
      EndWith
      Result = AdjustTokenPrivileges_(TokenHandle, #False, @NewState, SizeOf(TOKEN_PRIVILEGES), @PreviousState.TOKEN_PRIVILEGES, @ReturnLength)
    EndIf
    CloseHandle_(TokenHandle)
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure.s GetProcessPath(hProcess)
  Protected GetProcessImageFileName.protoGetProcessImageFileName
  Protected QueryFullProcessImageName.protoQueryFullProcessImageName

  Result.s = ""

  If hProcess
    Select OSVersion()
      Case #PB_OS_Windows_XP
        psapi = OpenLibrary(#PB_Any, "psapi.dll")

        If IsLibrary(psapi)
          GetProcessImageFileName = GetFunction(psapi, "GetProcessImageFileNameW")

          If GetProcessImageFileName
            nSize = #MAX_PATH
            Dim lpBuffer.c(nSize)
            lpImageFileName.s = Space(nSize)
            GetProcessImageFileName(hProcess, @lpImageFileName, nSize)
            BufferLength = GetLogicalDriveStrings_(nSize, @lpBuffer(0))

            Repeat
              lpDeviceName.s = ""

              While lpBuffer(rtnCount)
                lpDeviceName + Chr(lpBuffer(rtnCount))
                rtnCount + 1
              Wend
              lpDeviceName = Left(lpDeviceName, Len(lpDeviceName) - 1)
              lpTargetPath.s = Space(nSize)
              QueryDosDevice_(lpDeviceName, @lpTargetPath, nSize)

              If Left(lpImageFileName, Len(lpTargetPath)) = lpTargetPath
                Result = Trim(ReplaceString(lpImageFileName, lpTargetPath, lpDeviceName))
                Break
              EndIf
              rtnCount + 1
            Until rtnCount >= BufferLength
          EndIf
          CloseLibrary(psapi)
        EndIf
      Default
        kernel32 = OpenLibrary(#PB_Any, "kernel32.dll")

        If IsLibrary(kernel32)
          QueryFullProcessImageName = GetFunction(kernel32, "QueryFullProcessImageNameW")

          If QueryFullProcessImageName
            lpdwSize = #MAX_PATH
            lpExeName.s = Space(lpdwSize)
            QueryFullProcessImageName(hProcess, 0, @lpExeName, @lpdwSize)
            Result = Trim(lpExeName)
          EndIf
          CloseLibrary(kernel32)
        EndIf
    EndSelect
    CloseHandle_(hProcess)
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure.s GetProcessList()
  Result.s = ""
  hSnapshot = CreateToolhelp32Snapshot_(#TH32CS_SNAPPROCESS, #Null)

  If hSnapshot
    ProcEntry.PROCESSENTRY32
    ProcEntry\dwSize = SizeOf(PROCESSENTRY32)

    If Process32First_(hSnapshot, @ProcEntry)
      While Process32Next_(hSnapshot, @ProcEntry)
        AdjustCurrentProcessPrivilege("SeTcbPrivilege", #True)
        dwProcessId = ProcEntry\th32ProcessID
        hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, #False, dwProcessId)

        If hProcess
          Result + GetProcessPath(hProcess) + #CRLF$
          CloseHandle_(hProcess)
        EndIf
      Wend
      CloseLibrary(kernel32)
    EndIf
    CloseHandle_(hSnapshot)
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure RunProcessAsUser(lpApplicationName, lpCommandLine = #Null, lpCurrentDirectory = #Null)
  Protected WTSGetActiveConsoleSessionId.protoWTSGetActiveConsoleSessionId
  Protected WTSQueryUserToken.protoWTSQueryUserToken
  Protected CreateEnvironmentBlock.protoCreateEnvironmentBlock
  Protected DestroyEnvironmentBlock.protoDestroyEnvironmentBlock

  Result = #False
  kernel32 = OpenLibrary(#PB_Any, "kernel32.dll")

  If IsLibrary(kernel32)
    WTSGetActiveConsoleSessionId = GetFunction(kernel32, "WTSGetActiveConsoleSessionId")
    dwSessionId = WTSGetActiveConsoleSessionId()

    If dwSessionId
      wtsapi32 = OpenLibrary(#PB_Any, "wtsapi32.dll")

      If IsLibrary(wtsapi32)
        WTSQueryUserToken = GetFunction(wtsapi32, "WTSQueryUserToken")

        If WTSQueryUserToken(dwSessionId, @TokenHandle)
          sa.SECURITY_ATTRIBUTES
          #SecurityImpersonation = 2
          #TokenPrimary = 1

          If DuplicateTokenEx_(TokenHandle, #MAXIMUM_ALLOWED, @sa, #SecurityImpersonation, #TokenPrimary, @ImpersonateToken)
            If ImpersonateLoggedOnUser_(ImpersonateToken)
              userenv = OpenLibrary(#PB_Any, "userenv.dll")

              If IsLibrary(userenv)
                CreateEnvironmentBlock = GetFunction(userenv, "CreateEnvironmentBlock")
                DestroyEnvironmentBlock = GetFunction(userenv, "DestroyEnvironmentBlock")

                If CreateEnvironmentBlock(@pEnvironment, ImpersonateToken, #False)
                  #CREATE_UNICODE_ENVIRONMENT = $400
                  dwCreationFlags = #NORMAL_PRIORITY_CLASS | #CREATE_NEW_CONSOLE | #CREATE_UNICODE_ENVIRONMENT
                  si.STARTUPINFO
                  ZeroMemory_(@si, SizeOf(STARTUPINFO))
                  si\cb = SizeOf(STARTUPINFO)
                  si\lpDesktop = @"WinSta0\Default"
                  pi.PROCESS_INFORMATION
                  ZeroMemory_(@pi, SizeOf(PROCESS_INFORMATION))
                  Result = CreateProcessAsUser_(ImpersonateToken, lpApplicationName, lpCommandLine, @sa, @sa, #False, dwCreationFlags, pEnvironment, lpCurrentDirectory, @si, @pi)
                  SetLastError_(0)
                  DestroyEnvironmentBlock(pEnvironment)
                EndIf
                CloseLibrary(userenv)
              EndIf
              RevertToSelf_()
            EndIf
            CloseHandle_(ImpersonateToken)
          EndIf
          CloseHandle_(TokenHandle)
        EndIf
        CloseLibrary(wtsapi32)
      EndIf
    EndIf
    CloseLibrary(kernel32)
  EndIf
EndProcedure

Procedure ServiceHandler(fdwControl)
  Select fdwControl
    Case #SERVICE_CONTROL_PAUSE
      lpServiceStatus\dwCurrentState = #SERVICE_PAUSED
    Case #SERVICE_CONTROL_CONTINUE
      lpServiceStatus\dwCurrentState = #SERVICE_RUNNING
    Case #SERVICE_CONTROL_STOP, #SERVICE_CONTROL_SHUTDOWN
      With lpServiceStatus
        \dwCurrentState = #SERVICE_STOP_PENDING
        \dwWin32ExitCode = 0
        \dwServiceSpecificExitCode = 0
        \dwCheckPoint = 0
        \dwWaitHint = 0
      EndWith
      SetServiceStatus_(hServiceStatus, @lpServiceStatus)
      lpServiceStatus\dwCurrentState = #SERVICE_STOPPED
      SetServiceStatus_(hServiceStatus, @lpServiceStatus)
    Case #SERVICE_CONTROL_INTERROGATE
  EndSelect
  SetServiceStatus_(hServiceStatus, @lpServiceStatus)
EndProcedure

Procedure ServiceMain()
  With lpServiceStatus
    \dwServiceType = #SERVICE_WIN32_OWN_PROCESS | #SERVICE_INTERACTIVE_PROCESS
    \dwCurrentState = #SERVICE_START_PENDING
    \dwControlsAccepted = #SERVICE_ACCEPT_STOP | #SERVICE_ACCEPT_SHUTDOWN
    \dwWin32ExitCode = 0
    \dwServiceSpecificExitCode = 0
    \dwCheckPoint = 0
    \dwWaitHint = 0
  EndWith
  hServiceStatus = RegisterServiceCtrlHandler_(ServiceName, @ServiceHandler())

  If hServiceStatus
    SetServiceStatus_(hServiceStatus, @lpServiceStatus)
    lpServiceStatus\dwCurrentState = #SERVICE_RUNNING
    SetServiceStatus_(hServiceStatus, @lpServiceStatus)
    ServiceFile.s = GetPathPart(ProgramFilename()) + ServiceName + ".exe"

    While lpServiceStatus\dwCurrentState = #SERVICE_RUNNING
      If FindString(GetProcessList(), ServiceFile, 1, #PB_String_NoCase) = 0
        RunProcessAsUser(@ServiceFile, @ServiceName)
      EndIf
      Delay(10000)
    Wend

    With lpServiceStatus
      \dwCurrentState = #SERVICE_STOP_PENDING
      \dwWin32ExitCode = 0
      \dwServiceSpecificExitCode = 0
      \dwCheckPoint = 0
      \dwWaitHint = 0
    EndWith
    SetServiceStatus_(hServiceStatus, @lpServiceStatus)
    lpServiceStatus\dwCurrentState = #SERVICE_STOPPED
    SetServiceStatus_(hServiceStatus, @lpServiceStatus)
  EndIf
EndProcedure

Procedure ServiceInit()
  Dim lpServiceTable.SERVICE_TABLE_ENTRY(2)
  lpServiceTable(0)\lpServiceName = @ServiceName
  lpServiceTable(0)\lpServiceProc = @ServiceMain()
  lpServiceTable(1)\lpServiceName = #Null
  lpServiceTable(1)\lpServiceProc = #Null
  StartServiceCtrlDispatcher_(@lpServiceTable())
EndProcedure

ServiceInit()
Windows 10 x64 -- Purebasic 5.70 LTS x86
Avatar de l’utilisateur
Pierre Bellisle
Messages : 25
Inscription : jeu. 21/juin/2018 6:01

Re: Service executant programme avec droits d'administrateur

Message par Pierre Bellisle »

Salut,
J'ai écris un service qui donne les droits de "Système Administrateur" aux applications qu'il démarre.
Je peu appeler des machins comme RegEdit.exe sans que le dialogue UAC n’apparaisse.
La base du prochain algorithme proviens de Subverting "Vista UAC in Both 32 and 64 bit Architectures"
Mon code fonctionne bien sous Windows Sept et Dix, probablement aussi sous Vista et Huit, ça demeure toutefois à vérifier.
Puisque mon code a été écris avec un autre langage que PB, je préfère ne bricoler qu'une liste des APIs important et la démarche suivie.
Je ne suis pas sûr que Frédérique accepterait ma version originale, c'est son site après tout. :-)
Le service lui même doit être fusionné avec un manifeste qui réclame les droits d'administrateur,
le dialogue de l'UAC n’apparaîtra qu'à l’installation de celui ci.

Code : Tout sélectionner

 ;Start a exe with SysAdmin right from a service
 
 ;Obtain the currently active session id; every logged on user in the system has a unique session id
 SessionId = WTSGetActiveConsoleSessionId() ;Get the session-id of the console session: SessionId = 1 Console Active Pierre ou 0 Services Disconnected ""

 ;Get the ProcessId of the WinLogon that have the same SessionId as Current user dwSessionId
 ;Obtain the process id of the winlogon process that is running within the currently active session
 hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, #Null)
 RetValProc = Process32First(hProcessSnapshot, ProcessEntry)
 While RetValProc
   If LCase(ProcessEntry.szExeFile) = "winlogon.exe" ;May be more than one
     ProcessIdToSessionId(ProcessEntry.th32ProcessID, ProcessSessionId) ;Process session id RunAsAdmin for winlogon
     If ProcessSessionId = SessionId ;Need WinLogOn sessionId like in TaskManager
       ;Obtain a handle to the winlogon process
       hProcess = OpenProcess(#MAXIMUM_ALLOWED, #False, ProcessEntry.th32ProcessID)
       If hProcess 
         If OpenProcessToken(hProcess, #TOKEN_DUPLICATE, hProcessToken) 

           ;Security attibute structure used in DuplicateTokenEx and CreateProcessAsUser
           ;I would prefer to not have to use a security attribute variable and to just
           ;simply pass null and inherit (by default) the security attributes
           ;of the existing token. However, in C# structures are value types and therefore
           ;cannot be assigned the null value.
           SecurityAttributes.nLength = SizeOf(#SECURITY_ATTRIBUTES)
           ;Copy the access token of the winlogon process; the newly created token will be a primary token
           If DuplicateTokenEx(hProcessToken, #MAXIMUM_ALLOWED, SecurityAttributes, SecurityIdentification, TokenPrimary, hUserTokenDup) 

             ;By default CreateProcessAsUser creates a process on a non-interactive window station, meaning
             ;the window station has a desktop that is invisible and the process is incapable of receiving
             ;user input. To remedy this we set the lpDesktop parameter to indicate we want to enable user
             ;interaction with the new process.
             zWinSta0             = "winsta0\default"
             StartupInf.lpDesktop = @zWinSta0 ;Interactive window station parameter; basically this indicates that the process created can display a GUI on the desktop
             StartupInf.cb        = SizeOf(STARTUPINFO)

             ;Flags that specify the priority and creation method of the process
             CreationFlags = #NORMAL_PRIORITY_CLASS | #CREATE_NEW_CONSOLE
             
             Define sCurDir.s{#MAX_PATH}
             If FindString(sExeName, "\") 
               sCurDir = Left(sExeName, FindString(sExeName, "\"))
             End If
             
             ;Create a new process in the current user's logon session
             ProcedureReturn(CreateProcessAsUser ;Ok if return TRUE
               (hUserTokenDup,                   ;Client's access token
                #Null,                           ;File to execute
                @sExeName,                       ;Command line
                SecurityAttributes,              ;Pointer to process SECURITY_ATTRIBUTES
                SecurityAttributes,              ;Pointer to thread SECURITY_ATTRIBUTES
                #False,                          ;Handles are not inheritable
                CreationFlags,                   ;Creation flags
                #Null,                           ;Pointer to new environment block
                @sCurDir,                        ;Name of current directory
                @StartupInf,                     ;Pointer to STARTUPINFO structure
                @ProcessInfo)                    ;Receives information about new process
                CloseHandle(hUserTokenDup))
           EndIf
           CloseHandle(hProcessToken)
         End If
         CloseHandle(hProcess)
       EndIf
       Break ;Job done
     EndIf
   EndIf
   RetValProc = Process32Next(hProcessSnapshot, ProcessEntry)
 Wend
 CloseHandle(hProcessSnapshot) 
Dernière modification par Pierre Bellisle le dim. 01/juil./2018 20:21, modifié 3 fois.
Avatar de l’utilisateur
Ar-S
Messages : 9472
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Service executant programme avec droits d'administrateur

Message par Ar-S »

Bonjour Pierre.
Le code de ChaudEf est en PB même s'il utilise les API windows.
Merci de ne pas poster des code non PB sur ce forum. Convertissez les ou joignez un lien vers le site du langage en question mais je ne vois pas trop l'intérêt là.
Merci de ta compréhension.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
celtic88
Messages : 309
Inscription : sam. 12/sept./2015 14:31
Localisation : Alger

Re: Service executant programme avec droits d'administrateur

Message par celtic88 »

tu veux créer un service pour exécuter des programmes avec droits d'administrateurs ?

:?
.....i Love Pb :)
Avatar de l’utilisateur
Pierre Bellisle
Messages : 25
Inscription : jeu. 21/juin/2018 6:01

Re: Service executant programme avec droits d'administrateur

Message par Pierre Bellisle »

De ChaudEf: Le service lance un programme, et tout ce passe bien, mais si je regle cet exe a necessiter les droits d'administrateurs, ca ne marche plus.
Salut Celtic,
Si je comprend bien le désir de ChaudEf, c'est ce qu'il veut.
Un moyen qui fonctionne bien est d'utiliser du code faisant appel aux APIs mentionné dans mon message précédent.
Avatar de l’utilisateur
cage
Messages : 506
Inscription : ven. 16/oct./2015 18:22
Localisation : France
Contact :

Re: Service executant programme avec droits d'administrateur

Message par cage »

Bonjour,

J'avais noté dans mes marques-pages ce lien :
https://f-lefevre.developpez.com/tutoriels/purebasic/service-windows/

Si cela peut aider.

cage
■ Win10 64-bit (Intel Celeron CPU N2920 @ 1.86GHz, 4,0GB RAM, Intel HD Graphics) & PB 6.00 LTS
■ Vivre et laisser vivre.
■ PureBasic pour le fun
■ Gérard sur le forum Anglais
■ Mes sites: http://pbcage.free.fr - http://yh.toolbox.free.fr
Avatar de l’utilisateur
Pierre Bellisle
Messages : 25
Inscription : jeu. 21/juin/2018 6:01

Re: Service executant programme avec droits d'administrateur

Message par Pierre Bellisle »

Bonjour Cage,

Franck a fait du boulot de bonne qualité avec son tuto!
C'est assurément une adresse à conserver pour ceux qui veulent écrire un service.

Le message de ChaudEf date d'une année, espérerons qu'il reviendras sonder le terrain.

À+
Avatar de l’utilisateur
ChaudEf
Messages : 179
Inscription : dim. 27/déc./2015 17:02
Localisation : Strasbourg

Re: Service executant programme avec droits d'administrateur

Message par ChaudEf »

Bonjour les amis.
Je me suis repenché sur le sujet, et j'ai rencontre le même problème. Je viens voir sur le forum Purebasic, et je vois que j'ai pose exactement cette question il y a deux ans, et on m'a même répondu entre temps :)
Apparemment je n'étais plus dedans quand on m'a répondu, je ne me souviens pas. En tout les cas merci pour les réponses.

@Pierre Bellisle Ton code n'est pas en Purebasic, je n'ai donc pas pu en profiter.

@cage Ce tutoriel est intéressant, mais ne parle pas de mon problème.

@celtic88 Je vais mieux expliquer ma question.

Pour un de mes projets, j'aurais besoin d'un service qui ferait des vérifications sur l'ordinateur. J'ai donc utilise des codes de service que j'ai trouvé sur le forum, mais dès que le service touche des choses qui nécessitent des droits d'administrateur, il passe à la ligne d'après, et ne fait pas le boulot.
Pour illustrer le problème, j'ai écrit un programme d'une seul ligne, un petit MessageRequester. Si je compile le programme sans l'option "Request administrator mode", et que j'écris dans le code du service qu'il lance ce programme, il n'y a pas de souci. Mais si je choisit l'option "administrator mode", le programme ne s'ouvre pas.
Un autre exemple que j'ai eu était de créer une tache planifie (avec un RunProgram("SchTasks"....), mais le service n'a pas éffectue la création.

Donc ma question est comment donner au service les droits d'administrateur pour qu'il puisse exécuter ces tâches
Évidemment le service lui-même a été compile avec l'option coche, et installe avec un programme qui a les droits d'administrateurs.

Merci.
Windows 10 x64 -- Purebasic 5.70 LTS x86
Marc56
Messages : 2146
Inscription : sam. 08/févr./2014 15:19

Re: Service executant programme avec droits d'administrateur

Message par Marc56 »

Pour illustrer le problème, j'ai écrit un programme d'une seul ligne, un petit MessageRequester. Si je compile le programme sans l'option "Request administrator mode", et que j'écris dans le code du service qu'il lance ce programme, il n'y a pas de souci. Mais si je choisit l'option "administrator mode", le programme ne s'ouvre pas.
Un autre exemple que j'ai eu était de créer une tache planifie (avec un RunProgram("SchTasks"....), mais le service n'a pas éffectue la création.
Donc ma question est comment donner au service les droits d'administrateur pour qu'il puisse exécuter ces tâches
Évidemment le service lui-même a été compile avec l'option coche, et installe avec un programme qui a les droits d'administrateurs.
:arrow: Ce n'est pas celui qui l'installe, mais c'est celui qui le lance qui donne à un programme des droits (administrateur ou autre)

Que le programme soit lancé par un utilisateur "interactif" (connecté) ou un utilisateur "programmé" (service) c'est pareil.
Si un service doit effectuer des opérations que seul un administrateur peut faire, alors ce service doit être lancé par un compte ayant des droits administrateur (ou sur le compte System, mais c'est fortement déconseillé)
Avatar de l’utilisateur
ChaudEf
Messages : 179
Inscription : dim. 27/déc./2015 17:02
Localisation : Strasbourg

Re: Service executant programme avec droits d'administrateur

Message par ChaudEf »

J;ai trouve une super solution, une fonction nomme "RunAsSystemAdmin", ecrite par "Pierre Bellisle" https://www.purebasic.fr/english/viewto ... =5&t=71635, et qui fait exactement ce que j'avais besoin.

Je cherche maintenant un moyen d'envoyer des parametres a l'exe que je lance de cette facon.

Si ca peut aider quelqu'un, voici la fonction.

Code : Tout sélectionner

Import "Kernel32.lib"
 WTSGetActiveConsoleSessionId()
 ProcessIdToSessionId(ProcessEntry_th32ProcessID.l, ProcessSessionId.l)
EndImport
#TokenPrimary = 1

Procedure.l RunAsSystemAdmin(sExeName.s)
 ;Launches the given application with full system admin rights bypassing the UAC prompt
 ;sExeName The name of the application to launch

 Protected  ProcessInfo.PROCESS_INFORMATION
 Protected  ProcessEntry.PROCESSENTRY32
 Protected  SecurityAttributes.SECURITY_ATTRIBUTES
 Protected  StartupInf.STARTUPINFO
 Static     zWinSta0.s{20}
 Protected  hUserTokenDup.l
 Protected  hProcess.l
 Protected  hProcessSnapshot.l
 Protected  hProcessToken.l
 Protected  SessionId.l
 Protected  ProcessSessionId.l
 Protected  CreationFlags.l
 Protected  RetValProc.l
 Protected  *FunctionPointer


 ;Obtain the currently active session id; every logged on user in the system has a unique session id
 SessionId = WTSGetActiveConsoleSessionId() ;Get the session-id of the console session: SessionId = 1 Console Active UserName or 0 Services Disconnected ""
 If SessionId <> #INVALID_HANDLE_VALUE
   ;Get the ProcessId of the WinLogon that have the same SessionId as the User's dwSessionId
   ;Obtain the process id of the winlogon process that is running within the currently active session
   hProcessSnapshot = CreateToolhelp32Snapshot_(#TH32CS_SNAPPROCESS | #TH32CS_SNAPTHREAD, #Null)
   If hProcessSnapshot <> #INVALID_HANDLE_VALUE
     ProcessEntry\dwSize = SizeOf(PROCESSENTRY32)
     RetValProc          = Process32First_(hProcessSnapshot, @ProcessEntry)
     While RetValProc
       Protected *BStr
       Protected *BStrData.String
       *BStr            = @ProcessEntry\szExeFile
       *BStrData.String =  @*BStr
       If LCase(*BStrData\s) = "winlogon.exe" ;May be more than one
         ProcessIdToSessionId(ProcessEntry\th32ProcessID, @ProcessSessionId) ;Process session id RunAsAdmin for winlogon, return nonzero on success
         If ProcessSessionId = SessionId ;Need WinLogOn sessionId like in TaskManager
           ;Obtain a handle to the winlogon process
           hProcess = OpenProcess_(#MAXIMUM_ALLOWED, #False, ProcessEntry\th32ProcessID)
           If hProcess
             If OpenProcessToken_(hProcess, #TOKEN_DUPLICATE, @hProcessToken)
               ;Security attibute structure used in DuplicateTokenEx and CreateProcessAsUser
               SecurityAttributes\nLength = SizeOf(SECURITY_ATTRIBUTES)
               ;Copy the access token of the winlogon process, the newly created token will be a primary token
               If DuplicateTokenEx_(hProcessToken, #MAXIMUM_ALLOWED, SecurityAttributes, #SecurityIdentification,
                                    #TokenPrimary, @hUserTokenDup)
                 ;By default CreateProcessAsUser creates a process on a non-interactive window station, meaning
                 ;the window station has a desktop that is invisible and the process is incapable of receiving
                 ;user input. To remedy this we set the lpDesktop parameter to indicate we want to enable user
                 ;interaction with the new process.
                 zWinSta0             = "winsta0\default"
                 StartupInf\lpDesktop = @zWinSta0 ;Interactive window station parameter; basically this indicates that the process created can display a GUI on the desktop
                 StartupInf\cb        = SizeOf(STARTUPINFO)

                 ;Flags that specify the priority and creation method of the process
                 CreationFlags = #NORMAL_PRIORITY_CLASS | #CREATE_NEW_CONSOLE


                 Protected zCurDir.s{#MAX_PATH}
                 If FindString(sExeName, "\")
                   zCurDir = Left(sExeName, Len(sExeName) - FindString(ReverseString(sExeName), "\"))
                 Else
                 EndIf
                 ;Create a new process in the current user's logon session, Ok if return TRUE
                 ;RegEdit/Admin      can't see HKEY_LOCAL_MACHINE\SECURITY\* (Cache-Policy-Recovery-RXACT-SAM)
                 ;RegEdit/SystemAdmin can see HKEY_LOCAL_MACHINE\SECURITY\* (Cache-Policy-Recovery-RXACT-SAM)
                 ProcedureReturn(CreateProcessAsUser_(hUserTokenDup,       ;Client's access token
                                                      #Null,               ;File to execute
                                                      @sExeName,           ;Command line
                                                      @SecurityAttributes, ;Pointer to process SECURITY_ATTRIBUTES
                                                      @SecurityAttributes, ;Pointer to thread SECURITY_ATTRIBUTES
                                                      #False,              ;Handles are not inheritable
                                                      CreationFlags,       ;Creation flags
                                                      #Null,               ;Pointer to new environment block
                                                      @zCurDir,            ;BYVAL %NULL, _ 'Name of current directory
                                                      @StartupInf,         ;Pointer to STARTUPINFO structure
                                                      @ProcessInfo))       ;Receives information about new process
                 CloseHandle_(hUserTokenDup)
               EndIf
               CloseHandle_(hProcessToken)
             EndIf
             CloseHandle_(hProcess)
           EndIf
           Break ;Job done
         EndIf
       EndIf
       RetValProc = Process32Next_(hProcessSnapshot, ProcessEntry)
     Wend
     CloseHandle_(hProcessSnapshot)
   EndIf
 EndIf

EndProcedure

Dernière modification par ChaudEf le ven. 24/mai/2019 9:20, modifié 2 fois.
Windows 10 x64 -- Purebasic 5.70 LTS x86
Avatar de l’utilisateur
Ar-S
Messages : 9472
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Service executant programme avec droits d'administrateur

Message par Ar-S »

ça avait l'air sympa mais...

Erreur

Code : Tout sélectionner

If #Debug : OutputDebugString_("RunAsSystemAdmin") : EndIf


Connait pas

Code : Tout sélectionner

WTSGetActiveConsoleSessionId()
C'est sympa de partager mais partagez des codes complets sinon ça ne sert à rien.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
ChaudEf
Messages : 179
Inscription : dim. 27/déc./2015 17:02
Localisation : Strasbourg

Re: Service executant programme avec droits d'administrateur

Message par ChaudEf »

Desole, j'ai corrige le message d'origine

Mais c'est pour utiliser dans un service
Windows 10 x64 -- Purebasic 5.70 LTS x86
Avatar de l’utilisateur
Ar-S
Messages : 9472
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Service executant programme avec droits d'administrateur

Message par Ar-S »

J'ai regardé le topic, je n'arrive déjà pas à lancer son code sans erreurs.. C'est pourtant intéressant.

Pour ton soucis, lorsqu'on regarde dans les services.msc, les programmes avec parametres se lancent de façon classique.
"Chemin exe" --param

As tu essayé de mettre

Code : Tout sélectionner

chr(34)+chemin_de_ton_exe$+chr(34)+" "+parametre$ 
pour le nom de ton sExeName.s ?
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
ChaudEf
Messages : 179
Inscription : dim. 27/déc./2015 17:02
Localisation : Strasbourg

Re: Service executant programme avec droits d'administrateur

Message par ChaudEf »

Je viens d'essayer, en ecrivant

Code : Tout sélectionner

C:\Windows\system32\SchTasks.exe /Create /XML C:\Users\Showf\Desktop\OneDrive.xml /TN onedrive
Rien ne se passe

Pourtant dans le cmd normal, cela cree la tache
Windows 10 x64 -- Purebasic 5.70 LTS x86
Répondre