By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,711 Members | 2,158 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,711 IT Pros & Developers. It's quick & easy.

Getting logged in user from a service?

P: n/a
I am writing a service that monitors when a particular app is started.
Works, but I need to get the user who is currently logged in, and of course
Environment.UserName returns the service logon (NT_AUTHORITY\SYSTEM).

I understand that when the service starts, no user may be logged in, but
that's ok, as the app I am monitoring can only be run by a logged in user.
Do I need to use WMI to get the user context of Explorer.exe or is there a
neater way?

James.

Jun 4 '07 #1
Share this Question
Share on Google+
33 Replies


P: n/a
James,

I'm assuming you are using the Process class or something similar? If
so, you can get the handle to the process through the Handle property.

Once you have that, you can call OpenProcessToken (through the P/Invoke
layer) to open the process token for reading. Once you have that, you can
then call the GetTokenInformation function (again through the P/Invoke
layer) to get the SID of the user that began the process.

Finally, you can call the LookupAccountSid API function using the
pointer to the SID to get the domain name, user name, etc, etc.

Make sure you call CloseHandle on the token you get from the call to
GetTokenInformation.

Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"JamesB" <ja***@somewhere.com.net.com.netwrote in message
news:46***********************@news.zen.co.uk...
>I am writing a service that monitors when a particular app is started.
Works, but I need to get the user who is currently logged in, and of
course Environment.UserName returns the service logon
(NT_AUTHORITY\SYSTEM).

I understand that when the service starts, no user may be logged in, but
that's ok, as the app I am monitoring can only be run by a logged in user.
Do I need to use WMI to get the user context of Explorer.exe or is there a
neater way?

James.

Jun 4 '07 #2

P: n/a
"JamesB" <ja***@somewhere.com.net.com.netwrote in message
news:46***********************@news.zen.co.uk...
>I am writing a service that monitors when a particular app is started.
Works, but I need to get the user who is currently logged in, and of
course Environment.UserName returns the service logon
(NT_AUTHORITY\SYSTEM).

I understand that when the service starts, no user may be logged in, but
that's ok, as the app I am monitoring can only be run by a logged in user.
Do I need to use WMI to get the user context of Explorer.exe or is there a
neater way?

James.

The easiest is to use System.Management and WMI's "Win32_ProcessStartTrace"
class.
Here is how:

using System.Management;
using System.Security.Principal;
....
void WatchProcessStart(string procName)
{
WqlEventQuery q = new WqlEventQuery( );
q.EventClassName = "Win32_ProcessStartTrace";
q.Condition = "ProcessName = '" + procName + "'"; // Put the process
name you want to watch for here...
using(ManagementEventWatcher w = new ManagementEventWatcher(q)){
w.EventArrived += new
EventArrivedEventHandler(ProcessStartEventArrived) ;
w.Start();
// BLOCK this thread, wait for an event to stop the handler and
return...
...
w.Stop();
}
}
static void ProcessStartEventArrived(object sender, EventArrivedEventArgs
e) {
foreach(PropertyData pd in e.NewEvent.Properties) {
string userAccount =
GetUserAccountFromSid(((byte[])e.NewEvent.Properties["Sid"].Value)));
// do something with "userAccount" ..
}
}
static string GetUserAccountFromSid(byte[] sid)
{
SecurityIdentifier si = new SecurityIdentifier(sid, 0);
NTAccount acc = (NTAccount)si.Translate(typeof(NTAccount));
return acc.Value;
}
Willy.

Jun 4 '07 #3

P: n/a

"JamesB" <ja***@somewhere.com.net.com.netwrote in message
news:46***********************@news.zen.co.uk...
>I am writing a service that monitors when a particular app is started.
Works, but I need to get the user who is currently logged in, and of
course
You used the phrase "the user", so this is required reading:
http://blogs.msdn.com/oldnewthing/ar...22/712677.aspx

Make sure you've thought about the questions Raymond asks, then use one of
the solutions already provided by Willy or Nicholas.
Jun 5 '07 #4

P: n/a

"Ben Voigt [C++ MVP]" <rb*@nospam.nospamwrote in message
news:%2****************@TK2MSFTNGP02.phx.gbl...
>
"JamesB" <ja***@somewhere.com.net.com.netwrote in message
news:46***********************@news.zen.co.uk...
>>I am writing a service that monitors when a particular app is started.
Works, but I need to get the user who is currently logged in, and of
course

You used the phrase "the user", so this is required reading:
http://blogs.msdn.com/oldnewthing/ar...22/712677.aspx

Make sure you've thought about the questions Raymond asks, then use one of
the solutions already provided by Willy or Nicholas.
Valid points - it's actually conceivable that users would be running the
monitored application on a terminal server, so I guess when I said "user" I
am indeed meaning the user who has started the monitored application, not
just whoever is logged in on the console!

Jun 5 '07 #5

P: n/a

"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.comwrote in
message news:u%****************@TK2MSFTNGP03.phx.gbl...
James,

I'm assuming you are using the Process class or something similar? If
so, you can get the handle to the process through the Handle property.

Once you have that, you can call OpenProcessToken (through the P/Invoke
layer) to open the process token for reading. Once you have that, you can
then call the GetTokenInformation function (again through the P/Invoke
layer) to get the SID of the user that began the process.

Finally, you can call the LookupAccountSid API function using the
pointer to the SID to get the domain name, user name, etc, etc.

Make sure you call CloseHandle on the token you get from the call to
GetTokenInformation.

Hope this helps.
The "process" I have is Win32_Process (from following another example), so
my code is as below, however my token is always zero.
The "Handle" property on the process object is a string, hence the
conversion to Intptr to pass to the OpenProcessToken command, so perhaps
it's not the same thing?
The process object I have also has GetOwner() and GetOwnerSid() methods,
which would be ideal, however these always seem to return null! The process
object must be correct in a sense though, as the start and stop events where
I pass proc.ProcessID are indeed returning the correct PID as shown in Task
Manager.
James.

private void OnEventArrived(object sender,
System.Management.EventArrivedEventArgs e)
{
try
{
string eventName = e.NewEvent.ClassPath.ClassName;

//Create process obj
WMI.Win32.Process proc = new
WMI.Win32.Process(e.NewEvent["TargetInstance"] as ManagementBaseObject);

//Get handle...
int ph = Convert.ToInt32(proc.Handle);
IntPtr pHandle = new IntPtr(ph);
IntPtr token = IntPtr.Zero;

//get processtoken
try
{
if (OpenProcessToken(pHandle, TOKEN_ACCESS.TOKEN_QUERY,
out token) == 0)
{
//throw new ApplicationException("Can't open process
token for: " + process.ProcessName);
}
CloseHandle(token);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}

String userAccount = "";

if (eventName.CompareTo("__InstanceCreationEvent")==0 )
{
// Started
if (Started!=null)
Started(this, e, (Int16)proc.ProcessId,
userAccount);

}
else if (eventName.CompareTo("__InstanceDeletionEvent")==0 )
{
// Terminated
if (Terminated!=null)
Terminated(this, e, (Int16)proc.ProcessId,
userAccount );

}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}

Jun 5 '07 #6

P: n/a
"JamesB" <ja***@somewhere.com.net.com.netwrote in message
news:46***********************@news.zen.co.uk...
>
"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.comwrote
in message news:u%****************@TK2MSFTNGP03.phx.gbl...
>James,

I'm assuming you are using the Process class or something similar? If
so, you can get the handle to the process through the Handle property.

Once you have that, you can call OpenProcessToken (through the
P/Invoke layer) to open the process token for reading. Once you have
that, you can then call the GetTokenInformation function (again through
the P/Invoke layer) to get the SID of the user that began the process.

Finally, you can call the LookupAccountSid API function using the
pointer to the SID to get the domain name, user name, etc, etc.

Make sure you call CloseHandle on the token you get from the call to
GetTokenInformation.

Hope this helps.
The "process" I have is Win32_Process (from following another example), so
my code is as below, however my token is always zero.
The "Handle" property on the process object is a string, hence the
conversion to Intptr to pass to the OpenProcessToken command, so perhaps
it's not the same thing?
The process object I have also has GetOwner() and GetOwnerSid() methods,
which would be ideal, however these always seem to return null! The
process object must be correct in a sense though, as the start and stop
events where I pass proc.ProcessID are indeed returning the correct PID as
shown in Task Manager.
James.

private void OnEventArrived(object sender,
System.Management.EventArrivedEventArgs e)
{
try
{
string eventName = e.NewEvent.ClassPath.ClassName;

//Create process obj
WMI.Win32.Process proc = new
WMI.Win32.Process(e.NewEvent["TargetInstance"] as ManagementBaseObject);

//Get handle...
int ph = Convert.ToInt32(proc.Handle);
IntPtr pHandle = new IntPtr(ph);
IntPtr token = IntPtr.Zero;

//get processtoken
try
{
if (OpenProcessToken(pHandle, TOKEN_ACCESS.TOKEN_QUERY,
out token) == 0)
{
//throw new ApplicationException("Can't open
process token for: " + process.ProcessName);
}
CloseHandle(token);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}

String userAccount = "";

if (eventName.CompareTo("__InstanceCreationEvent")==0 )
{
// Started
if (Started!=null)
Started(this, e, (Int16)proc.ProcessId,
userAccount);

}
else if (eventName.CompareTo("__InstanceDeletionEvent")==0 )
{
// Terminated
if (Terminated!=null)
Terminated(this, e, (Int16)proc.ProcessId,
userAccount );

}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}


You should use "Win32_ProcessStartTrace" for this (supposing you are running
XP or higher), take a look at my other reply in this thread for details.

Willy.

Jun 5 '07 #7

P: n/a

"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:2C**********************************@microsof t.com...
You should use "Win32_ProcessStartTrace" for this (supposing you are
running XP or higher), take a look at my other reply in this thread for
details.

Willy.
Your example looked like it would block when the monitored app ran (until it
stopped?) - is that right? Not tried it yet.
Plus, manu users are still on W2k so if the Win32_ProcessStartTrace option
is XP or above, it may not be suitable.
Thanks though!

Jun 5 '07 #8

P: n/a
"JamesB" <ja***@somewhere.com.net.com.netwrote in message
news:46***********************@news.zen.co.uk...
>
"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:2C**********************************@microsof t.com...
>You should use "Win32_ProcessStartTrace" for this (supposing you are
running XP or higher), take a look at my other reply in this thread for
details.

Willy.

Your example looked like it would block when the monitored app ran (until
it stopped?) - is that right? Not tried it yet.
Not at all, in the sample I need to block the thread that owns the
ManagementEventWatcher object, this is required to keep the object alive as
long as you need to watch for events. Events from the trace provider keep
arriving on a worker thread from the pool.

Plus, manu users are still on W2k so if the Win32_ProcessStartTrace option
is XP or above, it may not be suitable.
True, but this means that in this case you are "watching" for instance
events on the Win_Process class, this implies polling with the inherent risk
to miss events.

Anyway, when you got the PID of the process, you can get the owner by
calling the "GetOwner" method on the Win32_process class instance.
Here is how...
static string GetOwner(int Pid)
{
string owner = null;
SelectQuery selectQuery = new SelectQuery(String.Format("Select *
from Win32_Process where ProcessId={0}", Pid));
Console.WriteLine(selectQuery.QueryString);
using (ManagementObjectSearcher searcher =
new ManagementObjectSearcher(selectQuery))
{
foreach (ManagementObject proc in searcher.Get())
{
Console.WriteLine(proc["Name"].ToString());
string[] s = new String[2];
proc.InvokeMethod("GetOwner", (object[])s);
if (String.IsNullOrEmpty(s[0]))
owner = "NA";
else
owner = s[1] + "\\" + s[0];
}
}
return owner;
}

However, keep in mind that you wont get anything back if the process has
already terminated at the moment you call this function.
This can happen when short living processes are getting traced.
Willy.

Jun 5 '07 #9

P: n/a
Your example looked like it would block when the monitored app ran (until
it stopped?) - is that right? Not tried it yet.
Plus, manu users are still on W2k so if the Win32_ProcessStartTrace option
is XP or above, it may not be suitable.
Thanks though!
Whatever method you choose, you'll still have to factor in what happens if
the service is stopped and then re-started (given that the app you're
monitoring may already be running at this point - or rather this is usually
an issue unless your app is dependent on the service in some way). I don't
know what WMI classes you should rely on off-hand to assist in this area (to
enumerate and locate running processes) since I normally rely on the the
WinAPI itself. In this regard Nicholas' technique is more mainstream (really
the de facto way of doing things) though WMI is normally easier (and worth
considering on those merits though I'd personally stick with the WinAPI
because it is more mainstream).
Jun 5 '07 #10

P: n/a
"Larry Smith" <no_spam@_nospam.comwrote in message
news:u3**************@TK2MSFTNGP04.phx.gbl...
>Your example looked like it would block when the monitored app ran (until
it stopped?) - is that right? Not tried it yet.
Plus, manu users are still on W2k so if the Win32_ProcessStartTrace
option is XP or above, it may not be suitable.
Thanks though!

Whatever method you choose, you'll still have to factor in what happens if
the service is stopped and then re-started (given that the app you're
monitoring may already be running at this point - or rather this is
usually an issue unless your app is dependent on the service in some way).
I don't know what WMI classes you should rely on off-hand to assist in
this area (to enumerate and locate running processes) since I normally
rely on the the WinAPI itself. In this regard Nicholas' technique is more
mainstream (really the de facto way of doing things) though WMI is
normally easier (and worth considering on those merits though I'd
personally stick with the WinAPI because it is more mainstream).


The purpose of the Framework is to virtualize the underlying OS services and
the HW, for instance by providing a layer in top of Win32, so you better
stay away from calling Win32 API's through PInvoke if you can achieve the
same (or better) when using the Framework classes.

That said, when the service restarts, you simply need to query whether the
process is already running using the System.Diagnostics.Process class or the
System.Management classes , get it's PID and pass it to something like the
"GetOwner" (using WMI Win32_Process class) I posted in my previous reply.
Willy.

Jun 5 '07 #11

P: n/a
The purpose of the Framework is to virtualize the underlying OS services
and the HW, for instance by providing a layer in top of Win32, so you
better stay away from calling Win32 API's through PInvoke if you can
achieve the same (or better) when using the Framework classes.

That said, when the service restarts, you simply need to query whether the
process is already running using the System.Diagnostics.Process class or
the System.Management classes , get it's PID and pass it to something like
the "GetOwner" (using WMI Win32_Process class) I posted in my previous
reply.
He's dealing with Windows constructs here (services, WMI etc) which either
have no (compatible) analogue outside the Windows world or whose support
and/or availability is questionable (assuming he's even targetting such
environments which is highly unlikely). Pedantic arguments about a virtual
environment therefore don't apply IMO. Arguments about ease-of-use do apply
however so on that we agree. P/Invoke is complicated and error-prone so
should generally be avoided where possible. However, a service is inherently
low-level and shouldn't be relying on .NET in the first place IMO. Even WMI
is questionable here. While supported in .NET, a service should usually be
light-weight with few dependencies. This is much better accomplished by
relying on native OS functionality. Unfortunately, in the real world you
require very experienced (and more expensive) C++/ WinAPI developers to
write and support this. It's not viable in many shops and these types of
developers are also becoming an endangered species (I'm one of them). Your
points are therefore well taken.
Jun 5 '07 #12

P: n/a
"Larry Smith" <no_spam@_nospam.comwrote in message
news:un****************@TK2MSFTNGP03.phx.gbl...
>The purpose of the Framework is to virtualize the underlying OS services
and the HW, for instance by providing a layer in top of Win32, so you
better stay away from calling Win32 API's through PInvoke if you can
achieve the same (or better) when using the Framework classes.

That said, when the service restarts, you simply need to query whether
the process is already running using the System.Diagnostics.Process class
or the System.Management classes , get it's PID and pass it to something
like the "GetOwner" (using WMI Win32_Process class) I posted in my
previous reply.

He's dealing with Windows constructs here (services, WMI etc) which either
have no (compatible) analogue outside the Windows world or whose support
and/or availability is questionable (assuming he's even targetting such
environments which is highly unlikely). Pedantic arguments about a virtual
environment therefore don't apply IMO. Arguments about ease-of-use do
apply however so on that we agree. P/Invoke is complicated and error-prone
so should generally be avoided where possible. However, a service is
inherently low-level and shouldn't be relying on .NET in the first place
IMO. Even WMI is questionable here. While supported in .NET, a service
should usually be light-weight with few dependencies. This is much better
accomplished by relying on native OS functionality. Unfortunately, in the
real world you require very experienced (and more expensive) C++/ WinAPI
developers to write and support this. It's not viable in many shops and
these types of developers are also becoming an endangered species (I'm one
of them). Your points are therefore well taken.

Sorry, I'm afraid I have to disagree with your statement that a Service as
being low-level and should not rely on .NET, why did MS add Windows Services
support to the FCL if this was true? The days that authoring a Service was
a privilege of C++ are over, however, I agree that not all services should
be implementd using .NET, but the same goes for other kind of applications,
I also agree, that as a result of .NET, way too many applications are now
implemented as a Windows Services, but that's just another discussion.
Now , when I'm talking about "virtualization" I'm actually talking about
hiding details like "Windows OS" flavors and versions, and this is what the
CLR and the .NET Framework is all about. If you are coding directly against
the OS services (that is, by directly calling WIN32 Api's) you have to
consider a lot of things at "development" time, things like - is the API
available on the *target* machine? - What are the security constraints, what
privileges are there required to call these API when running as say "Local
Service"? Can the API access a remote server instance? Most of these things
are taken care of by the framework and it's underlying services, whatever
these are, and in this particular case the underlying service is native WMI
in top of Win32.
Even if you opt to use C++ to implement "low-level" Services, you should
definitely consider WMI for most of it's "management" tasks, and this is
exactly what most of the MS Services do these day's.
Willy.


Jun 5 '07 #13

P: n/a
CLR and the .NET Framework is all about. If you are coding directly
against the OS services (that is, by directly calling WIN32 Api's) you
have to consider a lot of things at "development" time, things like - is
the API available on the *target* machine? - What are the security
constraints, what privileges are there required to call these API when
running as say "Local Service"? Can the API access a remote server
instance? Most of these things are taken care of by the framework and it's
underlying services, whatever these are, and in this particular case the
underlying service is native WMI in top of Win32.
I don't see how using .NET Framework exempts you from worrying about
security constraints, privileges, etc. It might automatically enable a held
privilege in your token, that's about it.
Jun 5 '07 #14

P: n/a
Sorry, I'm afraid I have to disagree with your statement that a Service as
being low-level and should not rely on .NET, why did MS add Windows
Services support to the FCL if this was true?
That's a specious argument since MSFT is not the final arbiter on what's
good or bad for the programming community. Someone made the call to provide
it but they've provided many things over the years that weren't widely
adopted or necessarily good. In this case it's my judgment that they
provided it simply for ease-of-use. That's a good thing but it doesn't mean
it's the ideal platform for writing a service and IMO it's usually not. A
service is normally low-level by nature since it usually runs under the
System account as a member of the TCB (Trusted Computing Base). Its purpose
is to provide an-going (usually non-interactive) service of some type,
equivalent to a native OS service really. It should therefore have a small
footprint with few dependencies. .NET is a behemoth that doesn't lend itself
well to this. The OS itself does.
I agree that not all services should be implementd using .NET, but the
same goes for other kind of applications, I also agree, that as a result
of .NET, way too many applications are now implemented as a Windows
Services, but that's just another discussion.
Now , when I'm talking about "virtualization" I'm actually talking about
hiding details like "Windows OS" flavors and versions, and this is what
the CLR and the .NET Framework is all about. If you are coding directly
against the OS services (that is, by directly calling WIN32 Api's) you
have to consider a lot of things at "development" time, things like - is
the API available on the *target* machine? - What are the security
constraints, what privileges are there required to call these API when
running as say "Local Service"? Can the API access a remote server
instance? Most of these things are taken care of by the framework and it's
underlying services, whatever these are, and in this particular case the
underlying service is native WMI in top of Win32.
That sounds good in theory but in practice few services require OS-specific
function calls. The same core APIs that most people rely on to write a
service have been around for many years now. They usually work without issue
from one version of Windows to the next so it's rarely a consideration.
Other issues you mentioned are valid but only to a point. Privileges are
required to perform certain tasks for instance whether you use .NET or not.
If you don't have a required privilege in your token then how will .NET help
here. It will fail unless the .NET security mechanism relies on another
system I'm not familiar with (circumventing the standard Windows security
model). Even if you do have a privilege in your token it may be disabled
(most are by default) in which case it needs to be explicitly enabled to
work (even when running under the System account though most are enabled by
default - this is not the case for most other accounts however including the
administrator account itself)..Does NET do this in any or all cases? I'm not
a .NET expert so I don't know. I do believe you're simplifying the situation
however as .NET is not a panacea. Many of these issues still need to be
considered even though .NET is obviously easier to work with (which is not
in dispute)..
Even if you opt to use C++ to implement "low-level" Services, you should
definitely consider WMI for most of it's "management" tasks, and this is
exactly what most of the MS Services do these day's.
In my (long) experience WMI is not widely used in most organizations. That's
not a judgment call on WMI itself since I have tinkered with it on occasion.
It is an observation however. IMO the real issue is the OS itself. I agree
with the overall sentiment of your arguments but the Windows API is what
really needs to be changed to facilitate a simpler (and version-agnostic)
model. While that may not happen anytime soon since MSFT is probably
frightened to do it (and for good reason), the API is really showing its age
now. I don't believe .NET is always the answer however and sometimes you
just have to rely on the OS directly (or at least it should be strongly
considered for certain tasks like services).
Jun 5 '07 #15

P: n/a
"Ben Voigt [C++ MVP]" <rb*@nospam.nospamwrote in message
news:e3**************@TK2MSFTNGP06.phx.gbl...
>CLR and the .NET Framework is all about. If you are coding directly
against the OS services (that is, by directly calling WIN32 Api's) you
have to consider a lot of things at "development" time, things like - is
the API available on the *target* machine? - What are the security
constraints, what privileges are there required to call these API when
running as say "Local Service"? Can the API access a remote server
instance? Most of these things are taken care of by the framework and
it's underlying services, whatever these are, and in this particular case
the underlying service is native WMI in top of Win32.

I don't see how using .NET Framework exempts you from worrying about
security constraints, privileges, etc. It might automatically enable a
held privilege in your token, that's about it.

No, the system.Management classes (and this is what we are talking about
here) and WMI makes it possible to call OS services without YOU having the
need to run with these elevated privileges.

Willy.

Jun 5 '07 #16

P: n/a
news:e3**************@TK2MSFTNGP06.phx.gbl...
>>CLR and the .NET Framework is all about. If you are coding directly
against the OS services (that is, by directly calling WIN32 Api's) you
have to consider a lot of things at "development" time, things like - is
the API available on the *target* machine? - What are the security
constraints, what privileges are there required to call these API when
running as say "Local Service"? Can the API access a remote server
instance? Most of these things are taken care of by the framework and
it's underlying services, whatever these are, and in this particular
case the underlying service is native WMI in top of Win32.

I don't see how using .NET Framework exempts you from worrying about
security constraints, privileges, etc. It might automatically enable a
held privilege in your token, that's about it.


No, the system.Management classes (and this is what we are talking about
here) and WMI makes it possible to call OS services without YOU having the
need to run with these elevated privileges.
Can you cite an example since this appears to defy standard Windows security
(if I understand you correctly).
Jun 5 '07 #17

P: n/a
On Tue, 05 Jun 2007 11:27:00 -0700, Larry Smith <no_spam@_nospam.com>
wrote:
>No, the system.Management classes (and this is what we are talking about
here) and WMI makes it possible to call OS services without YOU having
the
need to run with these elevated privileges.

Can you cite an example since this appears to defy standard Windows
security
(if I understand you correctly).
I can't cite an example with respect to WMI, since I haven't used it.
However, Windows services are themselves a broad category of examples of
just what Willy is talking about. The whole point for many services is to
provide a point of access through which users can access
otherwise-sensitive areas of the computer.

The service itself runs at elevated privileges, providing filtered access
to things that no user can with their default privileges access.

As an example: is it a bad thing, in defiance of standard Windows
security, for there to be a SQL Server service that has elevated rights to
access a database, and which delegates those rights (in a controlled way)
to a user that connects to the SQL Server service?

Pete
Jun 5 '07 #18

P: n/a
"Larry Smith" <no_spam@_nospam.comwrote in message
news:eJ**************@TK2MSFTNGP02.phx.gbl...
>Sorry, I'm afraid I have to disagree with your statement that a Service
as being low-level and should not rely on .NET, why did MS add Windows
Services support to the FCL if this was true?

That's a specious argument since MSFT is not the final arbiter on what's
good or bad for the programming community. Someone made the call to
provide it but they've provided many things over the years that weren't
widely adopted or necessarily good. In this case it's my judgment that
they provided it simply for ease-of-use. That's a good thing but it
doesn't mean it's the ideal platform for writing a service and IMO it's
usually not. A service is normally low-level by nature since it usually
runs under the System account as a member of the TCB (Trusted Computing
Base).
Not at all, services should run with the least priviliges possible (don't
make the same mistake now that MS has made 15 years ago), Services should
run as "Local Service" or "Network Service", running as SYSTEM is considered
a serious security threat.

is to provide an-going (usually non-interactive) service of some type,
equivalent to a native OS service really. It should therefore have a small
footprint with few dependencies. .NET is a behemoth that doesn't lend
itself well to this. The OS itself does.
Let me see, I have a couple of native (MSFT) services running that consume
between 110 and 175MB (dwm.exe) on Vista, these are no .NET services, do you
call these low-level, small footprint, what about Exchange, SQLServer are
these also low-level services? Or do you consider them low-level because
they are written in C++? Or do you consider the CLR and a couple of BCL
libraries too much overhead?
Note that a managed process as a larger base footprint but this is just
overhead because of the runtime, once you add code this overhead gets less
important, especially when you have multiple managed applications loaded
(not necessarely services), because a lot of the code can be shared as of
V2.
>I agree that not all services should be implementd using .NET, but the
same goes for other kind of applications, I also agree, that as a result
of .NET, way too many applications are now implemented as a Windows
Services, but that's just another discussion.
Now , when I'm talking about "virtualization" I'm actually talking about
hiding details like "Windows OS" flavors and versions, and this is what
the CLR and the .NET Framework is all about. If you are coding directly
against the OS services (that is, by directly calling WIN32 Api's) you
have to consider a lot of things at "development" time, things like - is
the API available on the *target* machine? - What are the security
constraints, what privileges are there required to call these API when
running as say "Local Service"? Can the API access a remote server
instance? Most of these things are taken care of by the framework and
it's underlying services, whatever these are, and in this particular case
the underlying service is native WMI in top of Win32.

That sounds good in theory but in practice few services require
OS-specific function calls. The same core APIs that most people rely on to
write a service have been around for many years now. They usually work
without issue from one version of Windows to the next so it's rarely a
consideration. Other issues you mentioned are valid but only to a point.
Privileges are required to perform certain tasks for instance whether you
use .NET or not.
Not at all, you don't need special privileges because of .NET, you need them
to call some of the WIN32 API's, sure if you run all of your services as
SYSTEM, all of the possible privileges are enabled and this not an issue,
but then you are running in the worse possible environment security wise.
But if you run with the "Least Privileges" enabled, you cannot call every
API you like without enabling the privileges, and here is where the problem
starts, and what forces user applications run as administrator, but again
these day's are gone with Vista and Windows Server2008.
If you don't have a required privilege in your token then how will .NET
help here. It will fail unless the .NET security mechanism relies on
another system I'm not familiar with (circumventing the standard Windows
security model). Even if you do have a privilege in your token it may be
disabled (most are by default) in which case it needs to be explicitly
enabled to work (even when running under the System account though most
are enabled by default - this is not the case for most other accounts
however including the administrator account itself)..Does NET do this in
any or all cases? I'm not a .NET expert so I don't know. I do believe
you're simplifying the situation however as .NET is not a panacea. Many of
these issues still need to be considered even though .NET is obviously
easier to work with (which is not in dispute)..
WMI runs as another service (as Network Service"), all calls from
System.Management (the WMI wrapper) are executed by this service, and this
service takes care about authentication authorization and enabling of
"privileges" required by the WMI method actually requested. Each WIM class
method clearly states (in the metabase) which "privilege" is required to
execute a certain method, WMI enables the privilege by adjusting his token,
all the user user has to do is a simple set the EnablePrivileges property
for the duration of the connection of for the duration of the call. No need
to PInvoke the security API's, which would be necessary when calling the
API4s directly from C# or any other managed language, as the FCL don't
expose most of these API's.

>Even if you opt to use C++ to implement "low-level" Services, you should
definitely consider WMI for most of it's "management" tasks, and this is
exactly what most of the MS Services do these day's.

In my (long) experience WMI is not widely used in most organizations.

Note that WMI was included with W2K only, earlier versions of NT based OSses
did not come with WMI installed, now W2K and up come with WMI installed,
Vista and Windows2008 (which adds +200 new classes to the pack) can't live
without WMI and most major services like Exchange, SQLServer need WMI for
management purposes, even the CLR exposes it's counter data through WMI and
Office11 and 12 do use WMI to expose some of it's features and statistics .
Other services and appications (take perfmon) in the system heavely rely on
WMI as well, disable WMI and you kill these services too, stop this service
and the system will restart it automatically

That's
not a judgment call on WMI itself since I have tinkered with it on
occasion. It is an observation however. IMO the real issue is the OS
itself. I agree with the overall sentiment of your arguments but the
Windows API is what really needs to be changed to facilitate a simpler
(and version-agnostic) model. While that may not happen anytime soon since
MSFT is probably frightened to do it (and for good reason), the API is
really showing its age now. I don't believe .NET is always the answer
however and sometimes you just have to rely on the OS directly (or at
least it should be strongly considered for certain tasks like services).
I never said .NET was the solution for all problems in software business,
this is even not the point of this discussion, I believe that it only
accounts for a small but growing portion of the tasks at hand, what's
important is that it enables solutions that were previously too hard (which
in general means too expensive) to implement. It's an enabling technology,
no more no less.
In the company I work for, we have 80000 PC's managed using SMS and MOM,
and some other management tools that also run in top of WMI, these tools,
built by major companies like IBM and HP, completely rely on WMI.

Willy.

Jun 5 '07 #19

P: n/a
"Larry Smith" <no_spam@_nospam.comwrote in message
news:OS**************@TK2MSFTNGP02.phx.gbl...
>news:e3**************@TK2MSFTNGP06.phx.gbl...
>>>CLR and the .NET Framework is all about. If you are coding directly
against the OS services (that is, by directly calling WIN32 Api's) you
have to consider a lot of things at "development" time, things like -
is the API available on the *target* machine? - What are the security
constraints, what privileges are there required to call these API when
running as say "Local Service"? Can the API access a remote server
instance? Most of these things are taken care of by the framework and
it's underlying services, whatever these are, and in this particular
case the underlying service is native WMI in top of Win32.

I don't see how using .NET Framework exempts you from worrying about
security constraints, privileges, etc. It might automatically enable a
held privilege in your token, that's about it.


No, the system.Management classes (and this is what we are talking about
here) and WMI makes it possible to call OS services without YOU having
the need to run with these elevated privileges.

Can you cite an example since this appears to defy standard Windows
security (if I understand you correctly).

Not at all, WMI is client/server based using DCOM, you call a service and
the service executes the service call, when WMI needs to "enable" a
privilege (note that I said 'enable'), it' s up to the caller to ask the
service to enable the required (whatever this one may be)privilege, the user
doesn't need to know the "privilege" required, WMI know which one as it's
stored in it's metabase.
In the exceptional case (there are only a few) that a call requires a
privilege that is not held by the WMI account (say "Network Service"), then
it's up to the caller to run as a more privileged user (or get a stronger
logon token) and ask WMI to impersonate when executing the service call.
Willy.

Jun 5 '07 #20

P: n/a
"Peter Duniho" <Np*********@nnowslpianmk.comwrote in message
news:op***************@petes-computer.local...
On Tue, 05 Jun 2007 11:27:00 -0700, Larry Smith <no_spam@_nospam.com>
wrote:
>>No, the system.Management classes (and this is what we are talking about
here) and WMI makes it possible to call OS services without YOU having
the
need to run with these elevated privileges.

Can you cite an example since this appears to defy standard Windows
security
(if I understand you correctly).

I can't cite an example with respect to WMI, since I haven't used it.
However, Windows services are themselves a broad category of examples of
just what Willy is talking about. The whole point for many services is to
provide a point of access through which users can access
otherwise-sensitive areas of the computer.

The service itself runs at elevated privileges, providing filtered access
to things that no user can with their default privileges access.

As an example: is it a bad thing, in defiance of standard Windows
security, for there to be a SQL Server service that has elevated rights to
access a database, and which delegates those rights (in a controlled way)
to a user that connects to the SQL Server service?

Pete

That's right. I guess Larry has missed the point that WMI is C/S based.
Clients are connecting over DCOM, using highly optimized LRPC's (that is
over shared memory) for local connections, and because of this it enjoys all
the security benefits of DCOM for the session and great performance, but
when it comes to "privileges", he's using his own token or an impersonation
token (it's even possible to use Kerberos delegation) to execute whatever
service implemented in so called loadable service providers (in-proc or
out-proc).This model is exactly what SQLServer uses when connecting using
shared memory as C/S protocol.
Note that it's even possible to inject a (high performance) provider in the
clients code, but this is a discussion for another NG.
Note that WMI uses DCOM over SMB (or should I say CIFS ;-)) when connecting
to a remote instance, however, this is an implementation detail, the same
security rules apply.

Willy.

Willy.
Jun 5 '07 #21

P: n/a
Not at all, WMI is client/server based using DCOM, you call a service and
the service executes the service call, when WMI needs to "enable" a
privilege (note that I said 'enable'), it' s up to the caller to ask the
service to enable the required (whatever this one may be)privilege, the
user doesn't need to know the "privilege" required, WMI know which one as
it's stored in it's metabase.
In the exceptional case (there are only a few) that a call requires a
privilege that is not held by the WMI account (say "Network Service"),
then it's up to the caller to run as a more privileged user (or get a
stronger logon token) and ask WMI to impersonate when executing the
service call.
Part of my argument has been in response to these (sometimes) confusiing
comments about security. All WMI would be doing here is enabling privileges
that are already present in the caller's token (not its own). That's what
Ben Voight was referring to in his earlier response. It's a minor
convenience but one that's expected over the native OS since WMI sits on top
of it (providing higher-level services). If you don't have the required
privilege(s) in the first place however then WMI can't help you. Nor should
impersonation be required here since it's not needed. Your earlier comments
such as "... most of these things are taken care of by the framework and
it's underlying services" and " ... WMI makes it possible to call OS
services without YOU having the need to run with these elevated privileges"
are therefore misleading. Security is still an issue that needs to be
considered but you've been implying otherwise. In any case, I can't counter
arguments about ease-of-use in general. Higher-level services are inherently
easier to use by their very nature so it's compelling to champion their use.
They're not always the right tool for the job however. The entire crux of my
argument centers around that and their place in a service in particular. I
find your earlier arguments about monolithic services as self-defeating in
fact since there's no special threshold involved here. Nor is memory
consumption (necessarily) an accurate indicator of just how big these apps
really are (since memory is affected by other things such as the amount of
client data currently being cached). A small footprint is therefore a
relative term. Imagine how much larger and slower those services would be if
they actually relied on .NET instead of C++ and the native OS (which they
most likely do at the core). Do you think MSFT or most organizations would
even consider .NET for most services? Not likely.
Jun 5 '07 #22

P: n/a
"Larry Smith" <no_spam@_nospam.comwrote in message
news:OC**************@TK2MSFTNGP03.phx.gbl...
>Not at all, WMI is client/server based using DCOM, you call a service and
the service executes the service call, when WMI needs to "enable" a
privilege (note that I said 'enable'), it' s up to the caller to ask the
service to enable the required (whatever this one may be)privilege, the
user doesn't need to know the "privilege" required, WMI know which one as
it's stored in it's metabase.
In the exceptional case (there are only a few) that a call requires a
privilege that is not held by the WMI account (say "Network Service"),
then it's up to the caller to run as a more privileged user (or get a
stronger logon token) and ask WMI to impersonate when executing the
service call.

Part of my argument has been in response to these (sometimes) confusiing
comments about security. All WMI would be doing here is enabling
privileges that are already present in the caller's token (not its own).
That's what Ben Voight was referring to in his earlier response. It's a
minor convenience but one that's expected over the native OS since WMI
sits on top of it (providing higher-level services). If you don't have the
required privilege(s) in the first place however then WMI can't help you.
Nor should impersonation be required here since it's not needed. Your
earlier comments such as "... most of these things are taken care of by
the framework and it's underlying services" and " ... WMI makes it
possible to call OS services without YOU having the need to run with these
elevated privileges" are therefore misleading. Security is still an issue
that needs to be considered but you've been implying otherwise. In any
case, I can't counter arguments about ease-of-use in general. Higher-level
services are inherently easier to use by their very nature so it's
compelling to champion their use. They're not always the right tool for
the job however. The entire crux of my argument centers around that and
their place in a service in particular. I find your earlier arguments
about monolithic services as self-defeating in fact since there's no
special threshold involved here. Nor is memory consumption (necessarily)
an accurate indicator of just how big these apps really are (since memory
is affected by other things such as the amount of client data currently
being cached). A small footprint is therefore a relative term. Imagine how
much larger and slower those services would be if they actually relied on
.NET instead of C++ and the native OS (which they most likely do at the
core). Do you think MSFT or most organizations would even consider .NET
for most services? Not likely.

All WMI's security levels are highly customizable, the namespaces are all
protected by DACL's you can adjust, you can prevent certain user to access,
read, write, execute etc...it's namespaces, if a user is allowed to execute
a method, WMI will simply enable or add the privilege (to it's own
token)when needed on a per call basis.

Some classes and methods need an impersonation token from the base client,
if the token holds a needed privilege to execute or access a namespace
class, WMI enables this privilege, when the token misses the privilege, the
call fails.
That way it's possible to perform some administrative tasks without you, the
client, to run as an administrator, you are simply delegating the task to
another more privileged process, which on it's turn is rather restricted.
Look back at what Nicholas proposed, get the Handle of another process, if
you don't run in the same logon session, you won't be able to access to
process object to obtain the Handle (that is, Win32 OpenProcess will return
access denied) unless you are running as administrator and even then, you
won't probably be able to get all handles, there is nothing you can do
without a process handle, game over. This is not an issue when using WMI (or
System.Management, this is .NET right!).

Just try this as non administrator,

Process [] procs= Process.GetProcesses();
foreach(Process pro in procs)
{
try {
IntPtr handle = pro.Handle;
}
catch( Exception ex){Console.WriteLine(ex);}
}
and watch all:
System.ComponentModel.Win32Exception: Access is denied
at System.Diagnostics.ProcessManager.OpenProcess(Int3 2 processId, Int32
access, Boolean throw
IfExited)
thrown on you ...

This is exactly why so many programs run in the "administrators" account
these days, worse some have "SeDebugPrivilege" enabled, talking about a
surface attack.

Willy.


Jun 5 '07 #23

P: n/a
"Larry Smith" <no_spam@_nospam.comwrote in message
news:OC**************@TK2MSFTNGP03.phx.gbl...
>Not at all, WMI is client/server based using DCOM, you call a service and
the service executes the service call, when WMI needs to "enable" a
privilege (note that I said 'enable'), it' s up to the caller to ask the
service to enable the required (whatever this one may be)privilege, the
user doesn't need to know the "privilege" required, WMI know which one as
it's stored in it's metabase.
In the exceptional case (there are only a few) that a call requires a
privilege that is not held by the WMI account (say "Network Service"),
then it's up to the caller to run as a more privileged user (or get a
stronger logon token) and ask WMI to impersonate when executing the
service call.

Part of my argument has been in response to these (sometimes) confusiing
comments about security. All WMI would be doing here is enabling
privileges that are already present in the caller's token (not its own).
That's what Ben Voight was referring to in his earlier response. It's a
minor convenience but one that's expected over the native OS since WMI
sits on top of it (providing higher-level services). If you don't have the
required privilege(s) in the first place however then WMI can't help you.
Nor should impersonation be required here since it's not needed. Your
earlier comments such as "... most of these things are taken care of by
the framework and it's underlying services" and " ... WMI makes it
possible to call OS services without YOU having the need to run with these
elevated privileges" are therefore misleading. Security is still an issue
that needs to be considered but you've been implying otherwise.
Really where? The client doesn't need to run with elevated privileges to
perform a task, which otherwise would require administrator privileges, see
my other reply concerning the OpenProcess API call. All there is done is
delegate the request to another Service that runs with restricted privileges
(NOT as SYSTEM), you the clients needs higher privileges than thos taht can
be enabled or added to the service access token, the Client will need to run
with higher privileges or the call will fail, this is basically DCOM
security and access control, and privilege management combined. If this is
not secure, then tell me what's more secure, however, don't tell me that you
call security API's (as you suggested from the beginning), because most
important will require you to run with high privileges (see LogonUser,
OpenProcess etc..)
In any case, I can't counter
arguments about ease-of-use in general. Higher-level services are
inherently easier to use by their very nature so it's compelling to
champion their use. They're not always the right tool for the job however.
The entire crux of my argument centers around that and their place in a
service in particular. I find your earlier arguments about monolithic
services as self-defeating in fact since there's no special threshold
involved here. Nor is memory consumption (necessarily) an accurate
indicator of just how big these apps really are (since memory is affected
by other things such as the amount of client data currently being cached).
A small footprint is therefore a relative term. Imagine how much larger
and slower those services would be if they actually relied on .NET instead
of C++ and the native OS (which they most likely do at the core). Do you
think MSFT or most organizations would even consider .NET for most
services? Not likely.
so what? MSFT doesn't consider .NET to build SQLServer or Office either,
does that mean you shouldn't use it either? However it uses .NET for
Bizztalk and Windows Live services.
Tell me what do you call low-level services then, what makes you think that
native code services are more low level than .NET services, for the SCM they
are exactly the same , at run-time all there is executed is native code,
point.
What makes you think that .NET services are that much slower than native C++
services, they are performing largely at the same level, with only a slight
advantage for native C++ in some special cases, but that's not important for
a Service anyway, services are not the applications that consume a lot of
CPU or other resources, question is do they perform at an acceptable level,
and here the answer is YES in most cases.
Is it because you have the .NET BCL loaded in that process that you think
they are high level?, what if you are using native C++ using ATL "service"
templates, is this low level enough? Do you think MSFT services are using
ATL, sure they don't, but what does this prove, that *you* shouldn't use ATL
either?

Note that this discussion is getting largely OT, the OP has a Service built
using C# and he's allready using System.Management (aka native WMI
wrappers), I answered his question based on his usage scenario, I'm not here
to tell people not to use .NET for this really.
In your opinion he should use low-level stuff, by which I guess you mean
native C++ calling Win32 API's, not using WMI (this, while almost all MSFT's
Services expose their state and a lot of their management functions through
WMI).
If this is the case, I'm afraid we will have to agree to disagree.

Willy.

Jun 5 '07 #24

P: n/a
... WMI will simply ... add the privilege (to it's own token)when needed
on a per call basis.
That would be surprising considering that privileges can't be added to an
existing token since tokens are mostly immutable. There is no function that
does this. You need to add it to an existing account first and create a new
logon session. At least that's the way Windows security has always worked
assuming MSFT hasn't made any radical changes lately (which would greatly
surprise me in this area). Of course MSFT can always make their own code do
anything it wants but I don't see why they would breach their own security.
Some classes and methods need an impersonation token from the base client,
if the token holds a needed privilege to execute or access a namespace
class, WMI enables this privilege, when the token misses the privilege,
the call fails.
That way it's possible to perform some administrative tasks without you,
the client, to run as an administrator, you are simply delegating the task
to another more privileged process, which on it's turn is rather
restricted.
Look back at what Nicholas proposed, get the Handle of another process, if
you don't run in the same logon session, you won't be able to access to
process object to obtain the Handle (that is, Win32 OpenProcess will
return access denied) unless you are running as administrator and even
then, you won't probably be able to get all handles, there is nothing you
can do without a process handle, game over. This is not an issue when
using WMI (or System.Management, this is .NET right!).
An administrator can do anything it wants including accessing all handles.
It just has to enable the SeDebugPrivilege privilege in its own token. I
don't follow the other details however. If a program has the correct
privilege(s) to do something then it doesn't need to delegate it to someone
else. It can just do it on its own though it may have to enable a given
privilege first (a simple task). If by delegating however you mean allowing
WMI to peform the privileged operation using its own credentials (on the
client's behalf), then this itself would be a a serious security violation
by allowing an ordinary user to perform a privileged operation. I therefore
don't see how WMI eliminates security issues for the programmer. It might
simplify the housekeeping which is good and useful but you still need to
consider the security environment you're running in (since WMI will fail if
you access something you don't have permission for). This is no different
than when you roll your own code without WMI.
>
Just try this as non administrator,

Process [] procs= Process.GetProcesses();
foreach(Process pro in procs)
{
try {
IntPtr handle = pro.Handle;
}
catch( Exception ex){Console.WriteLine(ex);}
}
and watch all:
System.ComponentModel.Win32Exception: Access is denied
at System.Diagnostics.ProcessManager.OpenProcess(Int3 2 processId, Int32
access, Boolean throw
IfExited)
thrown on you ...

This is exactly why so many programs run in the "administrators" account
these days, worse some have "SeDebugPrivilege" enabled, talking about a
surface attack.
Only administrators normally have SeDebugPrivilege by default though it's
not enabled by default (which is the reason you can't end another session's
process from the task manager for instance, even as an administrator). The
administrator can easily enable this privilege on-the-fly however. In fact,
if you do this using some utility for instance (which is easily written
yourself), you'll find that you can end another session's process from the
task manager. In any case, a rogue process that compromises the administor
account can do whatever it wants.so the SeDebugPrivilege is irrelevant
(since it can easily be enabled if required)
Jun 6 '07 #25

P: n/a

"JamesB" <ja***@somewhere.com.net.com.netwrote in message
news:46***********************@news.zen.co.uk...
>I am writing a service that monitors when a particular app is started.
Works, but I need to get the user who is currently logged in, and of
course Environment.UserName returns the service logon
(NT_AUTHORITY\SYSTEM).

I understand that when the service starts, no user may be logged in, but
that's ok, as the app I am monitoring can only be run by a logged in user.
Do I need to use WMI to get the user context of Explorer.exe or is there a
neater way?

James.
Many thanks for the replies - after following the advice here and doing a
bit more playing around, I seem to have got it working.
Seems I also kicked off an interesting debate as well, which I'll digest
when I have a bit of time, the various viewpoints are probably worthy of
checking out!
James

Jun 6 '07 #26

P: n/a
"Larry Smith" <no_spam@_nospam.comwrote in message
news:e3**************@TK2MSFTNGP02.phx.gbl...
>... WMI will simply ... add the privilege (to it's own token)when needed
on a per call basis.

That would be surprising considering that privileges can't be added to an
existing token since tokens are mostly immutable. There is no function
that does this. You need to add it to an existing account first and create
a new logon session. At least that's the way Windows security has always
worked assuming MSFT hasn't made any radical changes lately (which would
greatly surprise me in this area). Of course MSFT can always make their
own code do anything it wants but I don't see why they would breach their
own security.
Sorry, the above (...add the privilege ) is completely wrong, sure you
can't add privileges to a token, just forget about it, sorry for the
confusion.
There is nothing to fear, MSFT did not breach their own security. Basically,
what a "regular" client" running in a normal (non system logon session) can
do depends on:
1. His own token, if he specifies "Impersonation" when creating an instance
of a WMI class, then all he can do is specified by his own privileges. Note
that here the DCOM (RCP) rules, like authentication and authorization apply,
and the server will handle the request on a thread that has called
"CoImpersonateClient", no surprises here.
2, When using "identity" as impersonation level, the client request runs on
a thread that impersonates the WMI process token, per default, this is the
"Local Network" account token. However, other accounts are possible as well,
all depends on which account was specified when the "DCOM Launcher" (aka.
COM SCM) started the WMI service using CreateProcessAsUser. The DCOM
Launcher process runs in the TCB, and sometime you'll notice a WMI service
processes running as SYSTEM as well, but this is only to handle some OS or
Kernel space requests (WMI enabled drivers ).
3. And when using "Delegate" as impersonation token, WMI is able to
delegate, that is perform remote requests on behalf of the client he's
impersonating.

What a "non-regular user" client can do is a bit different, when running in
the debugger, I've seen threads running with higher privileges enabled than
those contained in the "Local Service" token. It looks like WMI using the
highly privileged token (duplicated) of the DCOM launcher to create a
restricted token when impersonating. So apparently, MSFT uses a backdoor, in
order to execute with elevated privileges without the need to launch a WMI
instance running as "SYSTEM".
>Some classes and methods need an impersonation token from the base
client, if the token holds a needed privilege to execute or access a
namespace class, WMI enables this privilege, when the token misses the
privilege, the call fails.
That way it's possible to perform some administrative tasks without you,
the client, to run as an administrator, you are simply delegating the
task to another more privileged process, which on it's turn is rather
restricted.
Look back at what Nicholas proposed, get the Handle of another process,
if you don't run in the same logon session, you won't be able to access
to process object to obtain the Handle (that is, Win32 OpenProcess will
return access denied) unless you are running as administrator and even
then, you won't probably be able to get all handles, there is nothing you
can do without a process handle, game over. This is not an issue when
using WMI (or System.Management, this is .NET right!).

An administrator can do anything it wants including accessing all handles.
It just has to enable the SeDebugPrivilege privilege in its own token.
And this is exactly my point. Using WMI, you don't need to run as
administrator (or with SeDebugPrivileges") enabled, to get at the process
handle. The process properties are stored in the WMI metabase at process
creation time by the OS loader (right, the OS is highly WMI aware). Once WMI
has the process handle he can query for the current properties (no special
privileges needed here).
Of course, some methods on the class needs specific privileges, for instance
a non admin client cannot kill processes other than those created by the
impersonating user.
I don't follow the other details however. If a program has the correct
privilege(s) to do something then it doesn't need to delegate it to
someone else. It can just do it on its own though it may have to enable a
given privilege first (a simple task). If by delegating however you mean
allowing WMI to peform the privileged operation using its own credentials
(on the client's behalf), then this itself would be a a serious security
violation by allowing an ordinary user to perform a privileged operation.
I therefore don't see how WMI eliminates security issues for the
programmer. It might simplify the housekeeping which is good and useful
but you still need to consider the security environment you're running in
(since WMI will fail if you access something you don't have permission
for). This is no different than when you roll your own code without WMI.
>>
Just try this as non administrator,

Process [] procs= Process.GetProcesses();
foreach(Process pro in procs)
{
try {
IntPtr handle = pro.Handle;
}
catch( Exception ex){Console.WriteLine(ex);}
}
and watch all:
System.ComponentModel.Win32Exception: Access is denied
at System.Diagnostics.ProcessManager.OpenProcess(Int3 2 processId, Int32
access, Boolean throw
IfExited)
thrown on you ...

This is exactly why so many programs run in the "administrators" account
these days, worse some have "SeDebugPrivilege" enabled, talking about a
surface attack.

Only administrators normally have SeDebugPrivilege by default though it's
not enabled by default (which is the reason you can't end another
session's process from the task manager for instance, even as an
administrator). The administrator can easily enable this privilege
on-the-fly however. In fact, if you do this using some utility for
instance (which is easily written yourself), you'll find that you can end
another session's process from the task manager. In any case, a rogue
process that compromises the administor account can do whatever it
wants.so the SeDebugPrivilege is irrelevant (since it can easily be
enabled if required)
Again this is the whole point, this requires the process to run with
elevated privileges. Go back at the sample above (C# code) You can't
enumerate the running processes to get the handles when not running as
administrator (SeDebugPrivileges needed to get the handle), but you need the
handle to call "OpenProcessToken" as per Nicholas suggestion. The result of
this is that many application run as "administrator" or with
"SeDebugPrivileges" (wrong wrong) and the developers/users are surprised
when their application fails when moving to Vista. Keep in mind that the
Framework does NOT offer the possibility to "enable" privileges, so here
again you have to adjust the token privileges using a PInvoke call.
There are many other samples I can give that are nicely solved by delegating
to WMI, because WMI is based on a database (the metabase) that stores a lot
of information you can't directly obtain without running with elevated
privileges when calling Win32 API's.
Look back at the code I initially posted (which requires XP or higher), no
special privileges needed no single PInvoke call - problem solved, try to
implement the same using Win32 API calls without the need to run with
elevated privileges.

Willy.
Jun 6 '07 #27

P: n/a
In all honesty your explanation of the situation is very puzzling. If I
undserstand what you're saying then my contention is that WMI is providing
access to something that non-admin users don't normally have access to. If a
regular user tries to access another logon session's handle via
"OpenProcess()" then it will fail because they don't have "SeDebugPrivilege"
in their token. Based on what you've described however, WMI *will* provide
access to the same (or related) information by specifying "identity" as the
impersonation level (which apparently is something different than
"SecurityIdentification" in the WinAPI - see here
http://msdn2.microsoft.com/en-us/library/aa379572.aspx). My question then is
why? There's a dual and conflicting system of security here. Either MSFT
considers it safe for a normal user to access another logon session's
process or they don't. It makes no sense to say you're not allowed to do
this using "OpenProcess()" because you lack a required privilege but OTOH
(wink, wink) just use WMI as a (wide-open) backdoor. If so then why isn't
this privilege simply removed as a prerequisite for calling "OpenProces()"
in the first place. Perhaps it's for backwards compatibility reasons but
obviously it's not a security issue anymore (according to MSFT). In fact,
your contention that WMI is much easier and safer because users don't need
to run with these elevated privileges (for some things) doesn't apply in an
environment where those privileges *are* needed. Therefore, it's not only
*not* a problem to have them, but it's an intrinsic requirement though it
should be kept to a minimum of course (where access is always govenred on a
need-to-know basis). In our on-going example then if you really don't need
these privileges then sure, don't grant user rights that they don't need.
Again however, why does "OpenProcess()" say that you *do* need them.
Finally, as for DCOM, this is the distrbuted component of the COM SCM.
They're not the same so I don't see why it even comes into the picture
unless a remote call is required (and even then why is DCOM used given its
notorious configuration problems and issues with firewalls). My experience
with WMI is limited so I can't really comment on its particular security
requirements. After considering what you've said however coupled with a
quick scan of links such as
http://msdn2.microsoft.com/En-US/library/aa390428.aspx and
http://msdn2.microsoft.com/En-US/library/aa389290.aspx, I maintain it's not
as simple as you would have me believe (from a security perspective anyway).
I think I'll put the issue to rest now however but will read any final
follow-up you might want to provide :)
Jun 7 '07 #28

P: n/a

"Larry Smith" <no_spam@_nospam.comwrote in message
news:Ov**************@TK2MSFTNGP05.phx.gbl...
In all honesty your explanation of the situation is very puzzling. If I
undserstand what you're saying then my contention is that WMI is providing
access to something that non-admin users don't normally have access to. If
a regular user tries to access another logon session's handle via
"OpenProcess()" then it will fail because they don't have
"SeDebugPrivilege" in their token. Based on what you've described however,
WMI *will* provide access to the same (or related) information by
specifying "identity" as the impersonation level (which apparently is
something different than "SecurityIdentification" in the WinAPI - see here
http://msdn2.microsoft.com/en-us/library/aa379572.aspx). My question then
is why? There's a dual and conflicting system of security here. Either
MSFT considers it safe for a normal user to access another logon session's
process or they don't. It makes no sense to say you're not allowed to do
this using "OpenProcess()" because you lack a required privilege but OTOH
(wink, wink) just use WMI as a (wide-open) backdoor. If so then why isn't
I believe that OpenProcess() requires different permissions depending on the
required level of access, and the .NET Process.Handle request
PROCESS_ALL_ACCESS or whatever that constant is, and therefore fails,
whereas calling OpenProcess directly would be allowed.

To get the user owning a process, I think only PROCESS_QUERY_INFO (again,
possibly mangled the name slightly) would be required, and it should be
equally possible with or without WMI.
Jun 7 '07 #29

P: n/a
Tell me what do you call low-level services then, what makes you think
that native code services are more low level than .NET services, for the
SCM they are exactly the same , at run-time all there is executed is
native code, point.
What makes you think that .NET services are that much slower than native
C++ services, they are performing largely at the same level, with only a
slight advantage for native C++ in some special cases, but that's not
important for a Service anyway, services are not the applications that
consume a lot of CPU or other resources, question is do they perform at an
acceptable level, and here the answer is YES in most cases.
The .NET GC is optimized for user-interactivity (either with mouse/keyboard
or over network). It significantly delays freeing memory to gain
performance, and this is only appropriate for an active request. For a
background service to allocate hundreds of megabytes of memory more than it
needs would be rather poor.
Jun 7 '07 #30

P: n/a
"Larry Smith" <no_spam@_nospam.comwrote in message
news:Ov**************@TK2MSFTNGP05.phx.gbl...
In all honesty your explanation of the situation is very puzzling. If I
undserstand what you're saying then my contention is that WMI is providing
access to something that non-admin users don't normally have access to. If
a regular user tries to access another logon session's handle via
"OpenProcess()" then it will fail because they don't have
"SeDebugPrivilege" in their token. Based on what you've described however,
WMI *will* provide access to the same (or related) information by
specifying "identity" as the impersonation level (which apparently is
something different than "SecurityIdentification" in the WinAPI - see here
http://msdn2.microsoft.com/en-us/library/aa379572.aspx). My question then
is why?
I know, WMI is a complex distributed architecture.
Talking about processes, WMI does give access to process INFO, that doesn't
mean that you are also allowed to perform all possible actions on the
process object.
WMI is a provider/consumer based architecture. One of the most important
providers is CIMWIN32 (WMI's root\cimv2 namespace), a number of system
components do load provider components (COM DLL's), or do keep dynamic
structured info for the providers to be picked-up when needed (through
shared memory segments), this complex structure forms the cimwin32
provider. Each provider is also registered with WBEM (which is WMI) which
keeps a repository describing the providers features (classes properties
etc) , and WMI keeps also static and semi-dynamic instance data in this
store, this sore plus the dynamic instance data held by the components is
what is called the metabase. You can check the repository is
%Windir%\system32\wbem\repository.

There are different provider types, like there are instance providers,
method providers, event providers etc.
When we talk about Process info we are talking about the Win32_process class
"instance" provider, a consumer can ask about the state of a specific
process by means of a WQL query.
Say a consumer needs the status of a process with PID = 123, for this he
issues a query like :
Select * from WIn32_Process where processid=123 ,
this one is passed to WMI, WMI authenticates and performs an access check to
see whether the caller is allowed to "read" properties from this namespace
class (subject of WMI's security settings). When this check succeeds, he
loads the provider for the Process class (that is cimwin32 in root\cimv2),
if not already loaded, and passes the query to the provider. One step
performed by the provider in this case is a call to "OpenProcess" passing
the pid requested as argument. When the thread has no "SeDebugPrivilege" in
its token, the call will fail and the provider will pick-up the data
provided by the system component, in case of the above query this is the
handle value of the corresponding process. Note I said the "handle value",
which is nothing special as the handle value is the same as the PID and is
nothing else than an index in the process handle table. The caller cannot do
anything with this handle value, security is not compromised. With this
handle value as key, WMI picks the instance from the dynamic data blob
provided by the system component, this structured data blob is precisely
described in the repository and is returned to the consumer as instance data
for the process with PI=123.
You can check this process yourself by means of the wbemtest utility, run it
as non admin and do some experiments.
Now, the Win32_process class has also an associated method provider, and
this one implements methods like Create, Terminate, AttachDebugger etc..
Say that a consumer wants' to terminate a process, to do this he has to get
the instance like above and when done he has to execute a method on the
class (Win32_Process) of this instance. In this case WMI will perform an
access check to see whether the consumer is allowed to execute methods on
this namespace class, when it's the case, he will call the "Terminate"
method of the provider (remember providers are COM servers), the Terminate
method will call Win32 TerminateProcess as part of it's implementation and
when when the issuer (that is the impersonator) is allowed to kill the
process the API will succeed, else the API fails.
So in case the client had specified impersonate when connecting, the
provider will execute on a thread that impersonates the consumer and the
call will succeed for all process owned by this caller, all others will
fail. If the caller is an "administrator" he can do pretty much what he
likes, if he's a standard user he can only do what a standard user can do,
no security is compromised.
If the caller sets "identity" when connecting, he can pretty much do
nothing, as the thread will now impersonate "Local Service" and this one is
not allowed to execute any method.
There is a lot more to tell about this, the above is only a small fraction
of the total picture, just experiment yourself, run wbemtest, look at the
processes using tools like "processexplorer", attach a debugger to the WMI
hosting process, look at the providers getting loaded, check the executing
threads tokens and set breakpoints on critical API's you want to trace. This
will take some time, but if you are interested you will sure understand how
things fit together. Take also special notice of the DLL's loaded in several
service process (you'll see a lot of the load wbemcore.dll), also take note
of the shared memory segments like there are:
\BaseNamedObjects\__ComCatalogCache__
and the events like:
\BaseNamedObjects\EVENT_READYROOT/CIMV2PROVIDERSUBSYSTEM

these form the channels over which WMI communicates with the system
components.
Watch the WMI hosting process getting active and getting turned of (DCOM
lifecycle management comes into play here).

There's a dual and conflicting system of security here. Either MSFT
considers it safe for a normal user to access another logon session's
process or they don't. It makes no sense to say you're not allowed to do
this using "OpenProcess()" because you lack a required privilege but OTOH
(wink, wink) just use WMI as a (wide-open) backdoor. If so then why isn't
this privilege simply removed as a prerequisite for calling "OpenProces()"
in the first place.
See above, WMI does not pass a usable handle back to the consumer, only an
handle value, which you can even guess as it's the same as the PID.
Also keep in mind that you can't use an arbitraty handle across process
boundaries, unless the owner pushes the handle in your process handle table
by means of a DuplicateHandle call.
Perhaps it's for backwards compatibility reasons but
obviously it's not a security issue anymore (according to MSFT). In fact,
your contention that WMI is much easier and safer because users don't need
to run with these elevated privileges (for some things) doesn't apply in
an environment where those privileges *are* needed. Therefore, it's not
only *not* a problem to have them, but it's an intrinsic requirement
though it should be kept to a minimum of course (where access is always
govenred on a need-to-know basis). In our on-going example then if you
really don't need these privileges then sure, don't grant user rights that
they don't need. Again however, why does "OpenProcess()" say that you *do*
need them.
"OpenProcess" is the oldest API that exists in WIN32, it's also what I call
a "gateway "API, if you can call it to get a process handle, you can use
that handle without needing any further access checks. Why it requires
"SeDebugPrivileges" is because it was supposed to be called from Debuggers
only (and administrators and the TCB). But there is nothing inherently
dangerous about calling OpenProcess to get an handle, what should have been
protected is what you do with this handle, but MSFT choosed to protect the
root of all the API's that needed a process handle, so they did not need to
enter the kernel each time a handle was passed in another API (obviously for
performance reasons). This is much like there is done at the Filesystem
level, here access checks are only done when you open a file, no further
checks are done when you access the file!!

Pre-XP requires a caller to run in the TCB in order to call LogonUser, lucky
for us all MSFT has lifted this requirement as from XP on.
I'm pretty sure they cannot lift this requirement on "OpenProcess" without
breaking a lot of code, and without the need to change a lot of their own
API's.
Finally, as for DCOM, this is the distrbuted component of the COM SCM.
They're not the same so I don't see why it even comes into the picture
DCOM is a location independent IPC mechanims which can be used
"cross-process, local system" and "cross-process, remote systems". What we
are talking here (what the OP was talking about) is "cross-process, local
system". local DCOM uses shared memory as RPC channel, also called LRPC,
this is an highly optimized IPC mechanism. There ar no security mechanisms
involved no network components are used, thisngs get completely different
when talking cross machine. Note, however, that WMI can also ise COM, that
is it can load providers in-process of the consumer, VISTA and Windows 2008
provide more of these providers, but this is FAR beyond the scope of this NG
and thread.
unless a remote call is required (and even then why is DCOM used given its
notorious configuration problems and issues with firewalls). My experience
with WMI is limited so I can't really comment on its particular security
requirements. After considering what you've said however coupled with a
quick scan of links such as
http://msdn2.microsoft.com/En-US/library/aa390428.aspx and
http://msdn2.microsoft.com/En-US/library/aa389290.aspx, I maintain it's
not as simple as you would have me believe (from a security perspective
anyway). I think I'll put the issue to rest now however but will read any
final follow-up you might want to provide :)
I never said it was simple, basically it's simple, but it can get pretty
complex, as long as you are talking about local server/client connections
(cross-process same machine) over DCOM, there is no issue with firewalls, if
you are talking about cross machine DCOM then there are. This is the case
with all distributed systems, all of hem are using the network so all of
them are confronted with firewalls these days. Note also that WMI is about
enterprise management, it's not something you will use at home.
Willy.
Jun 7 '07 #31

P: n/a
"Ben Voigt [C++ MVP]" <rb*@nospam.nospamwrote in message
news:%2****************@TK2MSFTNGP05.phx.gbl...
>Tell me what do you call low-level services then, what makes you think
that native code services are more low level than .NET services, for the
SCM they are exactly the same , at run-time all there is executed is
native code, point.
What makes you think that .NET services are that much slower than native
C++ services, they are performing largely at the same level, with only a
slight advantage for native C++ in some special cases, but that's not
important for a Service anyway, services are not the applications that
consume a lot of CPU or other resources, question is do they perform at
an acceptable level, and here the answer is YES in most cases.

The .NET GC is optimized for user-interactivity (either with
mouse/keyboard or over network). It significantly delays freeing memory
to gain performance, and this is only appropriate for an active request.
For a background service to allocate hundreds of megabytes of memory more
than it needs would be rather poor.

Not true, there are different modes of GC, there is the server GC and there
is the workstation GC, the upcoming version of the CLR will allow you to
further tune the GC behavior, it will be possible to delay the GC until the
process is ready to take the hit. Note that when I read the above that I
have to assume that you think you can't write Web services and Remoting
services using .NET either! IIS 's worker processes that load .NET web
applications and Webservices are just services right! Grab a copy of Vista
or Longhorn and watch, WCF endpoints are hosted in a "managed code" service,
more will come in the picture when the product matures, and a lot more will
come with the next version of the OS ;-)
Note that I'm still trying to prove myself that .NET cannot be used for
certain scenarios, I have quite a list of NO NO's, like stay away from
kernel space (Drivers etc), stay away from the Explorer shell (add-ins),
don't use it to mimic COM components like Active X, stay away from
multimedia stuff that requires nearly real-time responses, don't use managed
code when memory footprint is really a concern, but "generic application
services" implemented as Windows Services are not one of them.
Note, that you should be careful when implementing a service, be it in
native code or managed code, and like I've said before this my real concern
with .NET, some people think that because it's easy with .NET to implement
Windows Services, that they must implement a lot as a service. I've seen
people using .NET Windows Service just to kick-off batch processes at
several intervals ( once per day, per week you name it), jeez what a waste
of resources, but years ago I've noticed the same when ATL Service templates
became made available for the C++ community.

Note also that the GC out-performs the native memory manager in most cases.
But don't let us start this old discussion again.
Willy.
Jun 7 '07 #32

P: n/a
"Ben Voigt [C++ MVP]" <rb*@nospam.nospamwrote in message
news:eQ**************@TK2MSFTNGP02.phx.gbl...
>
"Larry Smith" <no_spam@_nospam.comwrote in message
news:Ov**************@TK2MSFTNGP05.phx.gbl...
>In all honesty your explanation of the situation is very puzzling. If I
undserstand what you're saying then my contention is that WMI is
providing access to something that non-admin users don't normally have
access to. If a regular user tries to access another logon session's
handle via "OpenProcess()" then it will fail because they don't have
"SeDebugPrivilege" in their token. Based on what you've described
however, WMI *will* provide access to the same (or related) information
by specifying "identity" as the impersonation level (which apparently is
something different than "SecurityIdentification" in the WinAPI - see
here http://msdn2.microsoft.com/en-us/library/aa379572.aspx). My question
then is why? There's a dual and conflicting system of security here.
Either MSFT considers it safe for a normal user to access another logon
session's process or they don't. It makes no sense to say you're not
allowed to do this using "OpenProcess()" because you lack a required
privilege but OTOH (wink, wink) just use WMI as a (wide-open) backdoor.
If so then why isn't

I believe that OpenProcess() requires different permissions depending on
the required level of access, and the .NET Process.Handle request
PROCESS_ALL_ACCESS or whatever that constant is, and therefore fails,
whereas calling OpenProcess directly would be allowed.

To get the user owning a process, I think only PROCESS_QUERY_INFO (again,
possibly mangled the name slightly) would be required, and it should be
equally possible with or without WMI.



True, but this is not the case here, WMI does not call OpenProcess with
PROCESS_QUERY_INFO, convince yourself, attach a debugger to the WMI process
and set a breakpoint on kernel32!openprocess, issue a "select * from
win32_process" from a WMI client and you see that the dwDesiredAccess is not
PROCESS_QUERY_INFO, notice that the call fails with an HR=0xc0000022 which
will get translated into a "dos" error 5 (access denied), when the base
client is not an admin.
Now, WMI does not need the "handle" to interrogate the process properties,
he doesn't need to get the process token, he can get all relevant info
directly from the System (notably from the "process manager "in ntdll.dll,
which is WMI aware), only thing is that it might be a bit slower than using
the "normal Win32 API's".
The process manager stores the info about the running processes in a list,
that is mapped on a shared memory segment. This list holds all properties as
defined in the WMI schema for the Win32_Process class., and it's that blob
of data that gets translated by the WMI provider into Win32_ process
instance data.
The process manager is also an event source, signaling events like "Process
creation", "Process deletion", "Thread Creation" etc... to registered event
handlers (notably the WMI event providers). The eventing architecture is
implementation dependent, and most of it's functionality is only available
on XP and higher. On W2K (with limited functionality) and XP the event
system is WPP based, while W2K3 and up uses ETW as an high speed eventing
architecture. On Vista and Longhorn everything is ETW based.
So, if you go back to my original reply to the OP, where I said that he
should use "Win32_ProcessStartTrace" to get at the process identity, is
because this is the fastest way to get at the process owner, the process
manager fires an event and the eventhandler gets all properties he needs,
just with a few lines of C# code, mission accomplished.

Willy.

Jun 8 '07 #33

P: n/a
"Willy Denoyette [MVP]" <wi*************@telenet.bewrote in message
news:%2****************@TK2MSFTNGP02.phx.gbl...
"Ben Voigt [C++ MVP]" <rb*@nospam.nospamwrote in message
news:eQ**************@TK2MSFTNGP02.phx.gbl...
>>
"Larry Smith" <no_spam@_nospam.comwrote in message
news:Ov**************@TK2MSFTNGP05.phx.gbl...
>>In all honesty your explanation of the situation is very puzzling. If I
undserstand what you're saying then my contention is that WMI is
providing access to something that non-admin users don't normally have
access to. If a regular user tries to access another logon session's
handle via "OpenProcess()" then it will fail because they don't have
"SeDebugPrivilege" in their token. Based on what you've described
however, WMI *will* provide access to the same (or related) information
by specifying "identity" as the impersonation level (which apparently is
something different than "SecurityIdentification" in the WinAPI - see
here http://msdn2.microsoft.com/en-us/library/aa379572.aspx). My
question then is why? There's a dual and conflicting system of security
here. Either MSFT considers it safe for a normal user to access another
logon session's process or they don't. It makes no sense to say you're
not allowed to do this using "OpenProcess()" because you lack a required
privilege but OTOH (wink, wink) just use WMI as a (wide-open) backdoor.
If so then why isn't

I believe that OpenProcess() requires different permissions depending on
the required level of access, and the .NET Process.Handle request
PROCESS_ALL_ACCESS or whatever that constant is, and therefore fails,
whereas calling OpenProcess directly would be allowed.

To get the user owning a process, I think only PROCESS_QUERY_INFO (again,
possibly mangled the name slightly) would be required, and it should be
equally possible with or without WMI.


True, but this is not the case here, WMI does not call OpenProcess with
PROCESS_QUERY_INFO, convince yourself, attach a debugger to the WMI
process and set a breakpoint on kernel32!openprocess, issue a "select *
from win32_process" from a WMI client and you see that the dwDesiredAccess
is not PROCESS_QUERY_INFO, notice that the call fails with an
HR=0xc0000022 which will get translated into a "dos" error 5 (access
denied), when the base client is not an admin.
Now, WMI does not need the "handle" to interrogate the process properties,
he doesn't need to get the process token, he can get all relevant info
directly from the System (notably from the "process manager "in ntdll.dll,
which is WMI aware), only thing is that it might be a bit slower than
using the "normal Win32 API's".
The process manager stores the info about the running processes in a list,
that is mapped on a shared memory segment. This list holds all properties
as defined in the WMI schema for the Win32_Process class., and it's that
blob of data that gets translated by the WMI provider into Win32_ process
instance data.
The process manager is also an event source, signaling events like
"Process creation", "Process deletion", "Thread Creation" etc... to
registered event handlers (notably the WMI event providers). The eventing
architecture is implementation dependent, and most of it's functionality
is only available on XP and higher. On W2K (with limited functionality)
and XP the event system is WPP based, while W2K3 and up uses ETW as an
high speed eventing architecture. On Vista and Longhorn everything is ETW
based.
So, if you go back to my original reply to the OP, where I said that he
should use "Win32_ProcessStartTrace" to get at the process identity, is
because this is the fastest way to get at the process owner, the process
manager fires an event and the eventhandler gets all properties he needs,
just with a few lines of C# code, mission accomplished.

Oh, forgot to add that PROCESS_QUERY_INFORMATION is only able to Open
Processes running in the same logon session.

Willy.

Jun 8 '07 #34

This discussion thread is closed

Replies have been disabled for this discussion.