Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 513
  • Last Modified:

How do i Retrieve the Process Owner ?

I have the ProcessID of a process, now I'd like to know who is running that process.

I guess i could possibly, Open that process get the ProcessToken, and then use ImpersonateUser to Get it...but it seems like the wrong way to do it.


Target platform is NT/2K/XP
Any ideas ?

0
raidos
Asked:
raidos
1 Solution
 
egonoCommented:
listening ...
0
 
intheCommented:
hi,

first you must have SeDebugPrivilege enabled then
OpenProcess()
OpenProcessToken()
GetTokenInformation()
LookupAccountSid()

heres an example unit utilizing the above :

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

function EnableProcessPrivilege(const Enable: Boolean; const Privilege:
string): Boolean;
const
  PrivAttrs: array [Boolean] of DWORD = (0, SE_PRIVILEGE_ENABLED);
var
  Token: THandle;
  ReturnLength: Cardinal;
  TokenPriv: TTokenPrivileges;
begin
  Result := False;
  if OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, Token)
then
  begin
    TokenPriv.PrivilegeCount := 1;
    LookupPrivilegeValue(nil, PChar(Privilege),
TokenPriv.Privileges[0].Luid);
    TokenPriv.Privileges[0].Attributes := PrivAttrs[Enable];
    AdjustTokenPrivileges(Token, False, TokenPriv, SizeOf(TokenPriv), nil,
ReturnLength);
    Result := GetLastError = ERROR_SUCCESS;
    CloseHandle(Token);
  end;
end;

function LookupAccountBySid(Sid: PSID): string;
var
  Name, RefDomain: string;
  NameSize, RefDomainSize: DWORD;
  Use: Cardinal;
begin
  NameSize := 0;
  RefDomainSize := 0;
  LookupAccountSid(nil, Sid, nil, NameSize, nil, RefDomainSize, Use);
  SetLength(Name, NameSize);
  SetLength(RefDomain, RefDomainSize);
  LookupAccountSid(nil, Sid, PChar(Name), NameSize, PChar(RefDomain),
RefDomainSize, Use);
  Result := PChar(RefDomain) + '/' + PChar(Name);
end;

procedure QueryTokenInformation(Token: THandle; InformationClass:
TTokenInformationClass; var Buffer: Pointer);
var
  B: BOOL;
  Length: DWORD;
begin
  Buffer := nil;
  Length := 0;
  B := GetTokenInformation(Token, InformationClass, Buffer, Length, Length);
  while (not B) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) do
  begin
    ReallocMem(Buffer, Length);
    B := GetTokenInformation(Token, InformationClass, Buffer, Length,
Length);
  end;
  if not B then
  begin
    FreeMem(Buffer);
    Buffer := nil;
    raise Exception.Create('Unable to get token information');
  end;
end;

type
  PTokenUser = ^TTokenUser;
  TTokenUser = record
    User: TSidAndAttributes;
  end;

function GetProcessUser(const PID: Longword): string;
var
  Token, Handle: THandle;
  User: PTokenUser;
begin
  Handle := OpenProcess(PROCESS_QUERY_INFORMATION, False, PID);
  if Handle <> 0 then
  begin
    if OpenProcessToken(Handle, TOKEN_QUERY, Token) then
    begin
      QueryTokenInformation(Token, TokenUser, Pointer(User));
      Result := LookupAccountBySid(User.User.Sid);
      CloseHandle(Token);
    end;
    CloseHandle(Handle);
  end;
end;


procedure TForm1.Button1Click(Sender: TObject);
 var
  pID,hProcess:DWord;
  h : hwnd;
 begin   //for a test i used internet explorer
h := FindWindow('IEFrame',nil);
If h <> 0 Then
GetWindowThreadProcessId(h,@pID);  

//now got a test pid ,see who runs it

EnableProcessPrivilege(True, 'SeDebugPrivilege');
Showmessage(GetProcessUser(pID));
end;

end.
//some functions knicked from elsewhere for ease of use//

Regards Barry :)
0
 
raidosAuthor Commented:
Looks neat, will try it today...

Any other ways of doing it barry ? =))
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
intheCommented:
hi,
not that i can think of, most other roads point back to LookupAccountSid(),GetSecurityInfo will give back a pointer to the sID ,to be honest ive not tried any other way.
ps
i was wondering
what method are you using to get the ProcessID?
is this a app thats started remotely or locally?
0
 
raidosAuthor Commented:
The app is local and I'm currently using madshis enumStuff unit to get the ProcessId.

I was reading the Win32Api help yesterday and I came to the conclusion that the "ONLY" way to do it is the way you have given code for.

I guess it will work fine but it seems to me that it is a long route to get the tiny bit of information i want...

Have yet to try the code, I will test it as soon as I can..
0
 
DelFreakCommented:
Listening...
0
 
raidosAuthor Commented:
I'm getting a strange error on this line of your code Barry...=/
-->   AdjustTokenPrivileges(Token, False, TokenPriv, SizeOf(TokenPriv), nil, ReturnLength);

Compiler states: Ambiguous overloaded call to 'AdjustTokenPrivileges'

I've tried Ctrl+Space on function name to select which AdjustTokenPrivileges to use, without any luck.

any ideas ?

Using Delphi 5 Btw..
0
 
raidosAuthor Commented:
i just tried without setting the tokenprivileges and it seems to work without it....i wonder why...

hmm...maybe they aren't necessary ?
0
 
intheCommented:
hi,
the privileges are only nesesary if your not admin or dont have these rights already,if you dont need them you can safly ignore that part.

as for the error im guessing you have WinTypes and or WinProcs in your uses section,just remove them if so as they are replaced by windows unit and this can cause the error you mentioned.
0
 
intheCommented:
if above is not the case (you dont have winprocs in uses) then i'd suggest to try changing the function a little :


function EnableProcessPrivilege ( Enable: Boolean; sPrivilegeName: string): Boolean;
var
  TPPrev,TP : TTokenPrivileges;
  Token    : THandle;
  dwRetLen : DWORD;
begin
  result := False;
  OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, Token);
  TP.PrivilegeCount := 1;
  if LookupPrivilegeValue (nil, PChar (sPrivilegeName), TP.Privileges[0].LUID) then
  begin
    if Enable then
      TP.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
    else
      TP.Privileges[0].Attributes := 0;
      dwRetLen := 0;
    result := AdjustTokenPrivileges (Token, False, TP, SizeOf (TPPrev), TPPrev,dwRetLen)
  end;
  CloseHandle (Token)
end;

be interesting to see if it clears the error.
0
 
raidosAuthor Commented:
Ahhhhhh.....The goddamn Wintypes/Winprocs!!!!!

Grrr...

Great work Barry, I'm gonna go through every last unit of mine searching for Winprocs/Wintypes so i NEVER get this error again.

Thanks
0
 
intheCommented:
ok no probs :)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now