04.08.2013 Views

Un-Mapping Mapped Network Drives Andrew Coates - dFPUG-Portal

Un-Mapping Mapped Network Drives Andrew Coates - dFPUG-Portal

Un-Mapping Mapped Network Drives Andrew Coates - dFPUG-Portal

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

What the article does mention, though, is a couple of<br />

workarounds. The first involves about 30 lines of C code<br />

that calls another couple of functions in MPR.DLL. The<br />

second mentions in passing that there’s yet another<br />

function in MPR.DLL called WNetGetConnection().<br />

WNetGetConnection() is not quite as versatile as<br />

WNetGet<strong>Un</strong>iversalName(). It only accepts a drive letter<br />

and a colon (for instance, H:) rather than a full path.<br />

With a little string manipulation, however, it’s pretty<br />

easy to split up a mapped path, pass the function what it<br />

wants, and then re-assemble a complete UNC path from<br />

the pieces.<br />

To take the drudgery out of calling the Windows API,<br />

I wrote a wrapper function called GetUNCPath() that I<br />

include in any project in which I call either getdir() or<br />

getfile(). You could, of course, write wrappers for getfile()<br />

and getdir() that called GetUNCPath().<br />

For example, if the pub share on the server_pdc<br />

server were mapped as drive s:<br />

? GetUNCPath('s:\documents')<br />

\\server_pdc\pub\documents<br />

? GetUNCPath('c:\temp')<br />

c:\temp<br />

? GetUNCPath('s:\documents\myfile.doc')<br />

\\server_pdc\pub\documents\myfile.doc<br />

The wrapper function itself is pretty straightforward.<br />

The complete function is shown in Listing 1 and is<br />

available in this month’s Subscriber Downloads at<br />

www.pinpub.com/foxtalk. It accepts the mapped drive<br />

path as a compulsory parameter and optionally a length<br />

for the UNC version of the path. This second parameter is<br />

most often passed by the function itself in a recursive call<br />

if the default buffer size guess isn’t large enough (more on<br />

this later).<br />

Listing 1. The complete GetUNCPath source code.<br />

* Program....: GetUNCPath.prg<br />

* Version....: 1.0<br />

* Author.....: <strong>Andrew</strong> <strong>Coates</strong><br />

* Date.......: September 28, 1998<br />

* Notice.....: Copyright © 1998 Civil Solutions, All<br />

* Rights Reserved.<br />

* Compiler...: Visual FoxPro 05.00.00.0415 for Windows<br />

* Abstract...: Wrapper to the API call that converts a<br />

* mapped drive path to the UNC path<br />

* Changes....:<br />

* Originally used WNetGet<strong>Un</strong>iversalName, but that<br />

* doesn't work under Win95 (see KB Q131416). Now uses<br />

* WNetGetConnection, which uses a string rather than a<br />

* structure so STRUCTURE_HEADER is now 0.<br />

lParameters tc<strong>Mapped</strong>Path, tnBufferSize<br />

* from winnetwk.h<br />

#define UNIVERSAL_NAME_INFO_LEVEL 0x00000001<br />

#define REMOTE_NAME_INFO_LEVEL 0x00000002<br />

* from winerror.h<br />

#define NO_ERROR 0<br />

#define ERROR_BAD_DEVICE 1200<br />

#define ERROR_CONNECTION_UNAVAIL 1201<br />

#define ERROR_EXTENDED_ERROR 1208<br />

#define ERROR_MORE_DATA 234<br />

#define ERROR_NOT_SUPPORTED 50<br />

#define ERROR_NO_NET_OR_BAD_PATH 1203<br />

Returning a UNC Path<br />

from getdir()<br />

If you pass getdir() an initial folder in UNC format, then that<br />

folder will be the initially selected folder, but it won’t appear<br />

in the list of drives in the dialog box (see Figure 1). If that<br />

folder or one of its subfolders is selected, then the string<br />

returned will be in UNC. Be careful, though. If you navigate to<br />

a mapped drive from the drive’s drop-down box, there’s no<br />

way to get back to the UNC drive.<br />

#define ERROR_NO_NETWORK 1222<br />

#define ERROR_NOT_CONNECTED 2250<br />

* Local decision - paths aren't likely to be longer<br />

* than this - if they are, this function calls itself<br />

* recursively with the appropriate buffer size as the<br />

* second parameter.<br />

#DEFINE MAX_BUFFER_SIZE 500<br />

* String length at the beginning of the structure<br />

* returned before the UNC path.<br />

* ACC changed to 0 on 9/10/98 - Now using<br />

* WNetGetConnection, which uses a string rather than a<br />

* struct.<br />

#DEFINE STRUCTURE_HEADER 0<br />

local lcReturnValue<br />

if type('tc<strong>Mapped</strong>Path') = "C" and ;<br />

! isnull(tc<strong>Mapped</strong>Path)<br />

Figure 1. Passing<br />

getdir() a UNC<br />

path will initially<br />

display the UNC<br />

path in the dialog<br />

box, but the<br />

unmapped drive<br />

won’t appear in<br />

the drop-down list.<br />

* Split up the passed path to get just the drive.<br />

local lcDrive, lcPath<br />

* Just take the first two characters - we'll put it<br />

* all back together later. If the first two<br />

* characters aren't a valid drive, that's okay. The<br />

* error value returned from the function call will<br />

* handle it.<br />

* Case statement ensures we don't get the "cannot<br />

* access beyond end of string" error.<br />

do case<br />

case len(tc<strong>Mapped</strong>Path) > 2<br />

lcDrive = left(tc<strong>Mapped</strong>Path, 2)<br />

lcPath = substr(tc<strong>Mapped</strong>Path, 3)<br />

case len(tc<strong>Mapped</strong>Path)

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!