How to get current drive mapping

G

Guest

I am actually trying to get the UNC path of the main module of a process
running from a mapped drive, and I am trying to do this from a service. The
ProcessModule class only provides the full path with the mapped drive letter,
but the drive letter refers to the drive mapping for the user that started
the process, and cannot be resolved to a UNC path from a service running
under LocalSystem.
Presumably, therefore, I need to get the drive mapping either for the user
account associated with the process, or possibly even for the process's
session ID (I am not clear whether mappings are per user or per session). Can
anyone give me a clue as to how I go about this?
 
N

Nicholas Paldino [.NET/C# MVP]

Dave,

Unfortunately, the only option that you have here is to have the client
process do the resolution of the mapped drive to the UNC path. You can do
this on the client with the WNetGetUniversalName API function (you will have
to make the call through the P/Invoke layer).

Hope this helps.
 
G

Guest

Thanks Nicholas, but I think you've slightly misunderstood - I don't have a
"client process" - I am getting a list of the currently running processes and
trying to find out where they were run from.
I've looked at WNetGetUniversalName but it has the same problem as
WNetGetConnection which I am using now - it will only resolve drive mappings
for the current logon session.
The Process.Mainmodule.FullPath gives me the location, but (for some strange
reason) with a drive letter not a UNC. I can find the user account of the
process, and the sessionID, so surely it must be possible to find the current
drive mapping for that logon session and thus the UNC path. (Of course, the
mapping may have changed since the process was started, but there's not much
I can do about that)
--
Dave


Nicholas Paldino said:
Dave,

Unfortunately, the only option that you have here is to have the client
process do the resolution of the mapped drive to the UNC path. You can do
this on the client with the WNetGetUniversalName API function (you will have
to make the call through the P/Invoke layer).

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Dave said:
I am actually trying to get the UNC path of the main module of a process
running from a mapped drive, and I am trying to do this from a service.
The
ProcessModule class only provides the full path with the mapped drive
letter,
but the drive letter refers to the drive mapping for the user that started
the process, and cannot be resolved to a UNC path from a service running
under LocalSystem.
Presumably, therefore, I need to get the drive mapping either for the user
account associated with the process, or possibly even for the process's
session ID (I am not clear whether mappings are per user or per session).
Can
anyone give me a clue as to how I go about this?
 
G

Guest

Nicholas
One more thing. I am using PsSetCreateProcessNotifyRoutine from within a
driver to actually trap processes starting and stopping. Is there any way I
can extend the driver to get the true UNC path of the process? I'm hunting
through driver functions now but I haven't found anything yet.
--
Dave


Nicholas Paldino said:
Dave,

Unfortunately, the only option that you have here is to have the client
process do the resolution of the mapped drive to the UNC path. You can do
this on the client with the WNetGetUniversalName API function (you will have
to make the call through the P/Invoke layer).

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Dave said:
I am actually trying to get the UNC path of the main module of a process
running from a mapped drive, and I am trying to do this from a service.
The
ProcessModule class only provides the full path with the mapped drive
letter,
but the drive letter refers to the drive mapping for the user that started
the process, and cannot be resolved to a UNC path from a service running
under LocalSystem.
Presumably, therefore, I need to get the drive mapping either for the user
account associated with the process, or possibly even for the process's
session ID (I am not clear whether mappings are per user or per session).
Can
anyone give me a clue as to how I go about this?
 
W

Willy Denoyette [MVP]

Dave said:
I am actually trying to get the UNC path of the main module of a process
running from a mapped drive, and I am trying to do this from a service. The
ProcessModule class only provides the full path with the mapped drive letter,
but the drive letter refers to the drive mapping for the user that started
the process, and cannot be resolved to a UNC path from a service running
under LocalSystem.
Presumably, therefore, I need to get the drive mapping either for the user
account associated with the process, or possibly even for the process's
session ID (I am not clear whether mappings are per user or per session). Can
anyone give me a clue as to how I go about this?


Drive mappings are per logon session. The easiest way to resolve this is by using
System.Management and the WMI classes Win32_MappedLogicalDisk and Win32_LogonSession.
The ProviderName property of the Win32_MappedLogicalDisk instance holds the UNC path name of
the associated SessionID and the drive letter.

Willy.
 
N

Nicholas Paldino [.NET/C# MVP]

Dave,

The only way I can think of possibly doing this would be to impersonate
the user that ran the process and then run WNetGetUniversalName while
impersonating. However, in order to do that, you will have to have access
to each user's username (easy) and password (not so easy) so you can make
the call to LogonUser.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Dave said:
Thanks Nicholas, but I think you've slightly misunderstood - I don't have
a
"client process" - I am getting a list of the currently running processes
and
trying to find out where they were run from.
I've looked at WNetGetUniversalName but it has the same problem as
WNetGetConnection which I am using now - it will only resolve drive
mappings
for the current logon session.
The Process.Mainmodule.FullPath gives me the location, but (for some
strange
reason) with a drive letter not a UNC. I can find the user account of the
process, and the sessionID, so surely it must be possible to find the
current
drive mapping for that logon session and thus the UNC path. (Of course,
the
mapping may have changed since the process was started, but there's not
much
I can do about that)
--
Dave


Nicholas Paldino said:
Dave,

Unfortunately, the only option that you have here is to have the
client
process do the resolution of the mapped drive to the UNC path. You can
do
this on the client with the WNetGetUniversalName API function (you will
have
to make the call through the P/Invoke layer).

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Dave said:
I am actually trying to get the UNC path of the main module of a process
running from a mapped drive, and I am trying to do this from a service.
The
ProcessModule class only provides the full path with the mapped drive
letter,
but the drive letter refers to the drive mapping for the user that
started
the process, and cannot be resolved to a UNC path from a service
running
under LocalSystem.
Presumably, therefore, I need to get the drive mapping either for the
user
account associated with the process, or possibly even for the process's
session ID (I am not clear whether mappings are per user or per
session).
Can
anyone give me a clue as to how I go about this?
 
G

Guest

Thanks Willy. Unfortunately there is a problem with this -
Win32_MappedLogicalDisk returns null for the ProviderName. There is
apparently a hotfix for this (http://support.microsoft.com/kb/923262), but we
are producing a commercial application and can hardly ask all our customers
to apply a hotfix in order to make our program work.
Another Microsoft suggestion
(http://www.microsoft.com/technet/scriptcenter/resources/qanda/oct05/hey1027.mspx)
is to use Win32_LogicalDisk, but this appears to only work for the current
session, which puts me right back to the original problem.
Any further suggestions would be most welcome.
 
G

Guest

Yes, I also thought of that, but, as you say, without the user's logon
password it can't work.
Willy Denoyette suggests I use WMI. Sadly there are also problems with that
(see my last post) because of a bug that requires a hotfix. Nevertheless, if
the bug is fixed then allegedly WMI can get the information I need - which
begs the question, how does WMI get the information? If WMI can get it from
the operating system, then surely an application should also be able to get
it directly from the OS without going through WMI.
--
Dave


Nicholas Paldino said:
Dave,

The only way I can think of possibly doing this would be to impersonate
the user that ran the process and then run WNetGetUniversalName while
impersonating. However, in order to do that, you will have to have access
to each user's username (easy) and password (not so easy) so you can make
the call to LogonUser.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Dave said:
Thanks Nicholas, but I think you've slightly misunderstood - I don't have
a
"client process" - I am getting a list of the currently running processes
and
trying to find out where they were run from.
I've looked at WNetGetUniversalName but it has the same problem as
WNetGetConnection which I am using now - it will only resolve drive
mappings
for the current logon session.
The Process.Mainmodule.FullPath gives me the location, but (for some
strange
reason) with a drive letter not a UNC. I can find the user account of the
process, and the sessionID, so surely it must be possible to find the
current
drive mapping for that logon session and thus the UNC path. (Of course,
the
mapping may have changed since the process was started, but there's not
much
I can do about that)
--
Dave


Nicholas Paldino said:
Dave,

Unfortunately, the only option that you have here is to have the
client
process do the resolution of the mapped drive to the UNC path. You can
do
this on the client with the WNetGetUniversalName API function (you will
have
to make the call through the P/Invoke layer).

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

I am actually trying to get the UNC path of the main module of a process
running from a mapped drive, and I am trying to do this from a service.
The
ProcessModule class only provides the full path with the mapped drive
letter,
but the drive letter refers to the drive mapping for the user that
started
the process, and cannot be resolved to a UNC path from a service
running
under LocalSystem.
Presumably, therefore, I need to get the drive mapping either for the
user
account associated with the process, or possibly even for the process's
session ID (I am not clear whether mappings are per user or per
session).
Can
anyone give me a clue as to how I go about this?
 
W

Willy Denoyette [MVP]

Dave said:
Thanks Willy. Unfortunately there is a problem with this -
Win32_MappedLogicalDisk returns null for the ProviderName. There is
apparently a hotfix for this (http://support.microsoft.com/kb/923262), but we
are producing a commercial application and can hardly ask all our customers
to apply a hotfix in order to make our program work.
Another Microsoft suggestion
(http://www.microsoft.com/technet/scriptcenter/resources/qanda/oct05/hey1027.mspx)
is to use Win32_LogicalDisk, but this appears to only work for the current
session, which puts me right back to the original problem.
Any further suggestions would be most welcome.

Bummer.
However, I'm not entirely clear on why you need the UNC for, the UNC name can't be used from
another logon session as is the case with your service. Why don't you map the share from
inside your service?

Willy.
 
G

Guest

Without going into too much detail, I need to know if file x:\myfile on one
computer is the same file as y:\myfile on a different computer. The UNC name
uniquely defines a file on the network, whereas a mapped drive doesn't. (A
drive mapping can change with time as well. OK a share can be renamed too,
but less often and only by the sharer).
 
W

Willy Denoyette [MVP]

Dave said:
Without going into too much detail, I need to know if file x:\myfile on one
computer is the same file as y:\myfile on a different computer. The UNC name
uniquely defines a file on the network, whereas a mapped drive doesn't. (A
drive mapping can change with time as well. OK a share can be renamed too,
but less often and only by the sharer).


I understand that, but as I said, you can't share a network connection across logon
sessions.
That means that a network session \\server\share established from a logon session belonging
to user with identity BOB, can't be used by another user identity like "network service".
Only applications running in BOB's session can access the share.
All you can do is establish a network session from within your service, this can be done in
several ways:
1) spawn a "net use" command , using System.Diagnostics.Process.Start.
2) call WNetAddConnection2 using PInvoke.
3) When running in a W2K AD domain realm, you can grant access to the share(s) to the
$servername, where servername (a domain member) is the name of the machine running your
service.

Willy.
 
G

Guest

I don't need to actually make a connection. I am enumerating the processes on
the computer, and each Process has a MainModule.Filename that tells me where
it was run from, but if it was run from a shared drive then it will be
x:\Program Files\Myprogs\Myprog.exe or whatever. The Process also has a
session ID. I just want Windows to tell me "what is the share name
corresponding to this drive letter on this session" so that I can get the UNC
name of the program. I don't want to access it, I just want to know what it
is.
Process enumeration is actually done by a driver that uses
PsSetCreateProcessNotifyRoutine. At the moment the driver simply provides the
process ID, but if there were some way of doing the mapped drive->UNC
translation in the driver, that would be a possibility.
 
W

Willy Denoyette [MVP]

Dave said:
I don't need to actually make a connection. I am enumerating the processes on
the computer, and each Process has a MainModule.Filename that tells me where
it was run from, but if it was run from a shared drive then it will be
x:\Program Files\Myprogs\Myprog.exe or whatever. The Process also has a
session ID. I just want Windows to tell me "what is the share name
corresponding to this drive letter on this session" so that I can get the UNC
name of the program. I don't want to access it, I just want to know what it
is.
Process enumeration is actually done by a driver that uses
PsSetCreateProcessNotifyRoutine. At the moment the driver simply provides the
process ID, but if there were some way of doing the mapped drive->UNC
translation in the driver, that would be a possibility.

I see. Well, I' afraid there is no reliable way to do what you are looking for. The reason
is that "drive mapping " is really legacy, you really don't need to map a drive in order to
access a share.
You can establish a network session without specifying a drive letter, consider following
command:
net use \\server\share password /user:domain\user
this will bring \\server\share in the local File Systems namespace, and you can load/run an
application from this share by issuing following cmd command (or from code):
\\server\share\someprogram.exe

However, as there is no drive is mapped, you can't get at the mapping between drive letter
and UNC path, only thing you can do in this case is query for the command line (using
System.Management), which will look like this:
\\server\share\someprogram.exe.
so, you can retrieve the UNC path from the command line. However this works when starting a
program using the UNC path syntax.

Willy.
 
G

Guest

Hi Willy
yes, I understand all that. And if a progam is run using the method you
describe then the mainModule.Filename property shows the UNC path as you
would expect. However, many people still use shared drives, and we wanted to
be able to cater for them in our product. Still, if it can't be done it can't
be done. Thanks for taking the time to help.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top