Je cherche à écrire dans la base de registre dans HKEY_LOCAL_MACHINE, sachant que l'utilisateur qui exécutera mon application, n'a pas les droits en écriture.

J'ai donc trouvé le code suivant, qui fonctionne quand on a déjà les droits Admin :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
var
   hToken: Cardinal;
   Reg: Tregistry;
begin
   hToken := PerformLogon('admin', 'domaine', 'Motdepasse');
   try
      if not ImpersonateLoggedOnUser(hToken) then
      begin
         Application.MessageBox(PChar(SysErrorMessage(GetLastError)), 'ImpersonateLoggedOnUser', MB_ICONERROR + MB_OK);
         Exit;
      end;
 
      try
         Reg := TRegistry.Create;
         try
            Reg.RootKey := HKEY_LOCAL_MACHINE;
            if Reg.OpenKey('SOFTWARE\MonApp', False) then
            begin
               Reg.WriteString('TEST', 'poiop');
               Reg.CloseKey;
            end
            else
               Application.MessageBox(PChar(SysErrorMessage(GetLastError)), 'TRegistry', MB_ICONERROR + MB_OK);
         finally
            Reg.Free;
         end;
      finally
         if not RevertToSelf then
            Application.MessageBox(PChar(SysErrorMessage(GetLastError)), 'RevertToSelf', MB_ICONERROR + MB_OK);
      end;
   finally
      CloseHandle(hToken);
   end;
Et pour obtenir le jeton :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
function PerformLogon(const User, Domain, Password: string): Cardinal;
begin
   if not LogonUser(PChar(User), PChar(Domain), PChar(Password), LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, Result) then
   begin
      if GetLastError = ERROR_PRIVILEGE_NOT_HELD then
         Application.MessageBox(PChar('ERROR_PRIVILEGE_NOT_HELD' + #13#10 + SysErrorMessage(GetLastError)), 'LogonUser', MB_ICONERROR + MB_OK)
      else
         Application.MessageBox(PChar(SysErrorMessage(GetLastError)), 'LogonUser', MB_ICONERROR + MB_OK);
      Exit;
   end;
end;
Sauf que, quand je teste sous une session utilisateur (normal), j'obtiens l'erreur :
ERROR_PRIVILEGE_NOT_HELD
Le client ne dispose pas d'un privilège nécessaire
L'aide Delphi indique qu'il faut avoir le privilège SE_TCB_NAME, même s'il n'est pas activé.

Comment ajouter ce privilège à l'utilisateur courant ?
Ou comment faire autrement ?

J'ai testé sur un XP Pro SP2, et un 2000 SP4. Donc, ca doit être supporté (voir http://msdn2.microsoft.com/en-us/library/aa378612.aspx).