?
Solved

How do i Retrieve the Process Owner ?

Posted on 2002-03-18
12
Medium Priority
?
499 Views
Last Modified: 2013-11-23
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
Comment
Question by:raidos
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
12 Comments
 
LVL 2

Expert Comment

by:egono
ID: 6876910
listening ...
0
 
LVL 17

Accepted Solution

by:
inthe earned 800 total points
ID: 6877965
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
 
LVL 3

Author Comment

by:raidos
ID: 6879202
Looks neat, will try it today...

Any other ways of doing it barry ? =))
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 17

Expert Comment

by:inthe
ID: 6879249
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
 
LVL 3

Author Comment

by:raidos
ID: 6879664
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
 

Expert Comment

by:DelFreak
ID: 6880021
Listening...
0
 
LVL 3

Author Comment

by:raidos
ID: 6885047
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
 
LVL 3

Author Comment

by:raidos
ID: 6885080
i just tried without setting the tokenprivileges and it seems to work without it....i wonder why...

hmm...maybe they aren't necessary ?
0
 
LVL 17

Expert Comment

by:inthe
ID: 6887957
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
 
LVL 17

Expert Comment

by:inthe
ID: 6887982
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
 
LVL 3

Author Comment

by:raidos
ID: 6888145
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
 
LVL 17

Expert Comment

by:inthe
ID: 6888162
ok no probs :)
0

Featured Post

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Suggested Courses
Course of the Month15 days, 2 hours left to enroll

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question