[Tutor] getUncPath(mappedDrive)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

[Tutor] getUncPath(mappedDrive)

Albert-jan Roskam
Hi,

Is there a function that takes a file path with a mapped drive (z:\blah) and returns the associated UNC path (\\server\share\ding\dang\dong\blah)? I looked in os.path, but it doesn't seem to have this. The link below seems to be a solution (code in the bottom of the page), but I can't install win32com.client in the office :-( Is there any built-in function?
 http://stackoverflow.com/questions/2244767/python-check-network-map

Thanks!

Regards,
Albert-Jan

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
All right, but apart from the sanitation, the medicine, education, wine, public order, irrigation, roads, a
fresh water system, and public health, what have the Romans ever done for us?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] getUncPath(mappedDrive)

Tim Golden-4
On 24/03/2012 20:13, Albert-Jan Roskam wrote:

> Hi,
>
> Is there a function that takes a file path with a mapped drive
> (z:\blah) and returns the associated UNC path
> (\\server\share\ding\dang\dong\blah)? I looked in os.path, but it
> doesn't seem to have this. The link below seems to be a solution
> (code in the bottom of the page), but I can't install win32com.client
> in the office :-( Is there any built-in function?
>
> http://stackoverflow.com/questions/2244767/python-check-network-map

There's nothing built-in. The easiest function to emulate
through ctypes is probably WNetGetConnection:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa385453%28v=vs.85%29.aspx

(this is available from pywin32 via the win32wnet package
but I assume you can't install that either)

TJG
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] getUncPath(mappedDrive)

Albert-jan Roskam


From: Tim Golden <[hidden email]>
To:
Cc: Python Mailing List <[hidden email]>
Sent: Saturday, March 24, 2012 9:22 PM
Subject: Re: [Tutor] getUncPath(mappedDrive)

On 24/03/2012 20:13, Albert-Jan Roskam wrote:

> Hi,
>
> Is there a function that takes a file path with a mapped drive
> (z:\blah) and returns the associated UNC path
> (\\server\share\ding\dang\dong\blah)? I looked in os.path, but it
> doesn't seem to have this. The link below seems to be a solution
> (code in the bottom of the page), but I can't install win32com.client
> in the office :-( Is there any built-in function?
>
> http://stackoverflow.com/questions/2244767/python-check-network-map

There's nothing built-in. The easiest function to emulate
through ctypes is probably WNetGetConnection:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa385453%28v=vs.85%29.aspx

(this is available from pywin32 via the win32wnet package
but I assume you can't install that either)

TJG
_______________________________________________
Hi Tim,

Thanks! This seems a feasible approach. I have found this Python project that exposes some of the functions of mpr.dll: http://sourceforge.net/projects/wnetconnect/ WNetGetConnection is not among the functions, but the code will help. I have to read up on ctypes.Structure though as I never really understood this.

Cheers,
Albert-Jan



_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] getUncPath(mappedDrive)

Tim Golden-4
On 24/03/2012 21:29, Albert-Jan Roskam wrote:
>     Thanks! This seems a feasible approach. I have found this Python
>     project that exposes some of the functions of mpr.dll:
>     http://sourceforge.net/projects/wnetconnect/ WNetGetConnection is
>     not among the functions, but the code will help. I have to read up
>     on ctypes.Structure though as I never really understood this.

This particular function call doesn't require too much work
in fact. Something like the following code -- error-handling
mostly omitted -- should do the trick:

<code>
import ctypes
#
# Get the ANSI version of the function from its DLL
#
WNetGetConnection = ctypes.windll.mpr.WNetGetConnectionA

ERROR_MORE_DATA = 234

#
# Set up the drive name to map back from
# and an empty buffer with zero length.
#
local_name = "Z:"
length = ctypes.c_long (0)
remote_name = ctypes.create_string_buffer ("")

#
# Call the function, expecting to receive an ERROR_MORE_DATA
# result, which indicates that the buffer is too small and
# which populates the length field with the right length.
#
result = WNetGetConnection (
   local_name,
   remote_name,
   ctypes.byref (length)
)
#
# Assuming we did get that error, recreate the buffer and
# call again with the supplied length. This isn't strictly
# necessary (you could probably get away with hard-coding
# 2048 or whatever) but it does save you having to guess.
#
if result == ERROR_MORE_DATA:
   remote_name = ctypes.create_string_buffer (length.value)
   result = WNetGetConnection (
     local_name,
     remote_name,
     ctypes.byref (length)
   )

#
# If the result of either call was an error, raise an Exception
#
if result != 0:
   raise RuntimeError ("Error %d" % result)

print "Remote name is", remote_name.value

</code>

TJG
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] getUncPath(mappedDrive)

Albert-jan Roskam



From: Tim Golden <[hidden email]>
To: Albert-Jan Roskam <[hidden email]>
Cc: Python Mailing List <[hidden email]>
Sent: Saturday, March 24, 2012 11:25 PM
Subject: Re: [Tutor] getUncPath(mappedDrive)

On 24/03/2012 21:29, Albert-Jan Roskam wrote:
>    Thanks! This seems a feasible approach. I have found this Python
>    project that exposes some of the functions of mpr.dll:
>    http://sourceforge.net/projects/wnetconnect/ WNetGetConnection is
>    not among the functions, but the code will help. I have to read up
>    on ctypes.Structure though as I never really understood this.

This particular function call doesn't require too much work
in fact. Something like the following code -- error-handling
mostly omitted -- should do the trick:

<code>
import ctypes
#
# Get the ANSI version of the function from its DLL
#
WNetGetConnection = ctypes.windll.mpr.WNetGetConnectionA

ERROR_MORE_DATA = 234

#
# Set up the drive name to map back from
# and an empty buffer with zero length.
#
local_name = "Z:"
length = ctypes.c_long (0)
remote_name = ctypes.create_string_buffer ("")

#
# Call the function, expecting to receive an ERROR_MORE_DATA
# result, which indicates that the buffer is too small and
# which populates the length field with the right length.
#
result = WNetGetConnection (
  local_name,
  remote_name,
  ctypes.byref (length)
)
#
# Assuming we did get that error, recreate the buffer and
# call again with the supplied length. This isn't strictly
# necessary (you could probably get away with hard-coding
# 2048 or whatever) but it does save you having to guess.
#
if result == ERROR_MORE_DATA:
  remote_name = ctypes.create_string_buffer (length.value)
  result = WNetGetConnection (
    local_name,
    remote_name,
    ctypes.byref (length)
  )

#
# If the result of either call was an error, raise an Exception
#
if result != 0:
  raise RuntimeError ("Error %d" % result)

print "Remote name is", remote_name.value

</code>

TJG

Hi Tim,

Thank you so much for this! I think this would also be a valuable addition to os.path (where I'd expect it to be).
You call WNetGetConnection twice: one time with a 'dummy' string buffer, and one time with a buffer of the exact required length. If I'd run a function getUncPath() on a gazillion paths, wouldn't it be more effcient to hard-code the length to 2048 as you suggest in your comment?

Regards,
Albert-Jan

_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] getUncPath(mappedDrive)

Tim Golden-4
On 25/03/2012 09:12, Albert-Jan Roskam wrote:
>     Thank you so much for this! I think this would also be a valuable
>     addition to os.path (where I'd expect it to be).
>     You call WNetGetConnection twice: one time with a 'dummy' string
>     buffer, and one time with a buffer of the exact required length. If
>     I'd run a function getUncPath() on a gazillion paths, wouldn't it be
>     more effcient to hard-code the length to 2048 as you suggest in your
>     comment?

The fail-and-resize-the-buffer dance is fairly common on
Windows. The advantage of the technique is that
it will cope with any path length. If you hardcode to 2048
(or whatever length) then the time will come when you'll
encounter a longer path and then you'll have to rewrite your
code with 4096 or 8192 etc. Obviously, if you have control
over all the paths you're interested in, and you know that
they can't grow beyond MAXLEN characters, then by all means
use MAXLEN as the buffer size and shorten your code.

In terms of efficiency, I imagine you'd have to run the function
on an unusually high number of paths -- and you've only got
26 possible drive letters in the first place -- so it looks
to me like a premature optimisation!

TJG
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] getUncPath(mappedDrive)

danz
This post has NOT been accepted by the mailing list yet.
In reply to this post by Tim Golden-4
Tim.

I came across your code while searching for a similar need.  Your post was the best I could find on the subject.  Perhaps more importantly, you showed me that going down the ctypes rabbit hole can be less intimidating than I assumed.  Thanks!

My use case was a little different than the original poster's.  I need to retrieve the network paths for all of the mapped drives that are currently connected.  I chose a different implementation, that seems to work well.  I would appreciate any comments you have on this approach.

BTW, Thank you for the information on your website.  Your information and pointers to GetDriveType() and GetVolumeInformation() helped me a a lot.

Dan

-------------------
import subprocess

def available_network_drives():
    net_drives = dict()
    for line in subprocess.check_output(['net', 'use']).splitlines():
        if line.startswith('OK'):
            fields = line.split()
            net_drives[fields[1]] = fields[2]   # [1] == key, [2] == net_path
    return net_drives
   
print available_network_drives()
Reply | Threaded
Open this post in threaded view
|

Re: [Tutor] getUncPath(mappedDrive)

danz
This post has NOT been accepted by the mailing list yet.
I apologize to all, but my above code won't work with paths that have embedded spaces.  It also turns out that the "net use" command inserts a carriage-return/line-feed between the Path and Network fields when the last character position of the Path exceeds 80 characters.

My above approach seemed  simpler, but that's just because I posted it before adequate testing.  Unfortunately, in order to make it actually work for all cases, the implementation becomes more complex and begins to look like a kludge.  So my recommendation is to use Tim's ctypes approach.