Subscribe Bookmark RSS Feed

Mapping a Network Drive with a DLL

drc_lewis

Community Trekker

Joined:

Jul 23, 2013

Hello,

I'd like to be able to map (and then unmap) to a specific network drive as part of a JSL file using a DLL. Through talking to some internal IT people they've pointed me to mpr.dll and the WNetAddConnection2 and WNetCancelConnection2 functions. However, I'm not an expert programmer and so even though I've looked at the examples in the Scripting Guide and the examples on this discussion board (which do amazing things) I can't get mine to work. Also, I've never called a DLL before in any programming that I've done... Is there someone who can help me out?

The code that I've cobbled together so far (from an IT colleague who read the help file but doesn't know JMP) is below. Can anyone see obvious errors? I'd really appreciate the help...

Thanks

Colin

(Sorry it didn't format nicely. I tried some options but they looked weird)

// username, password, network map location have all been changed for pasting here
//Load the required DLL
dll_obj = Load Dll("mpr.dll");

//Assign constants to structure members - see constants list below for reference
// These are defined in the dll as DWORD (unsigned positive integers)
dwScope = HexToNumber("00000002"); //&H2;
dwType = HexToNumber("00000001"); //&H1;
dwDisplayType = HexToNumber("00000003"); //&H3;
dwUsage = HexToNumber("00000001"); //&H1;
dwFlags = HexToNumber("00000004"); //&H4;

lpLocalName = "Z:";
lpRemoteName = "\\10.254.1.1\!drive\";
lpComment = "";
lpProvider = "";

lpPassword = "password"; // Network Password
lpUserName = "domain\username";

//Declare exported function and set alias
dll_obj << DeclareFunction(
"WNetAddConnection2",
Alias("MapNetworkDrive"),
StructArg(
  Arg(Int32, "dwScope"),
  Arg(Int32, "dwType"),
  Arg(Int32, "dwDisplayType"),
  Arg(Int32, "dwUsage"),
  Arg(AnsiString, "lpLocalName"),
  Arg(AnsiString, "lpRemoteName"),
  Arg(AnsiString, "lpComment"),
  Arg(AnsiString, "lpProvider"),
  "NETRESOURCE",
  input
),
Arg(AnsiString, "lpPassword", input),
Arg(AnsiString, "lpUserName", input),
Arg(Int32, "dwFlags", input),
Returns(Int32)
);

//Function processing - map drive
/* DLL Function Call Syntax
dll_obj << Alias(
Structure(Every Arg),
PasswordArg,
UsernameArg,
DWFlagsArg
);
*/
result = dll_obj << MapNetworkDrive(
dwScope,
dwType,
dwDisplayType,
dwUsage,
lpLocalName,
lpRemoteName,
lpComment,
lpProvider,
lpPassword,
lpUserName,
dwFlags
);

// Successful connection should return 0 (NO_ERROR)
// Unload DLL
dll_obj << UnloadDll

1 ACCEPTED SOLUTION

Accepted Solutions
Solution

You don't say which version of JMP you're using but if you are able to use the just-release JMP 11, you can do this with the new Run Program command.

Run Program( Executable("net.exe"), Options("use z: \\myserver\share") );

and to un-map the drive

Run Program( Executable("net.exe"), Options("use z: /del") );

This is equivalent to running "net use z: \\myserver\share" from a command prompt.

John

3 REPLIES
Solution

You don't say which version of JMP you're using but if you are able to use the just-release JMP 11, you can do this with the new Run Program command.

Run Program( Executable("net.exe"), Options("use z: \\myserver\share") );

and to un-map the drive

Run Program( Executable("net.exe"), Options("use z: /del") );

This is equivalent to running "net use z: \\myserver\share" from a command prompt.

John

jschroedl

Staff

Joined:

Jun 23, 2011

I had some success using the API you mentioned with a few changes. Here are my changes:

* Changed to use WNetAddConnection2A the 'A' means Ansi so you need to call this version. You could use WNetAddConnection2W if you specified UnicodeString in your Args.

* Changed lpProvider to an Int64 to be able to pass 0 (NULL) for the provider.

//Declare exported function and set alias
dll_obj << DeclareFunction(
"WNetAddConnection2A",
Alias("MapNetworkDrive"),
StructArg(
  Arg(Int32, "dwScope"),
  Arg(Int32, "dwType"),
  Arg(Int32, "dwDisplayType"),
  Arg(Int32, "dwUsage"),
  Arg(AnsiString, "lpLocalName"),
  Arg(AnsiString, "lpRemoteName"),
  Arg(AnsiString, "lpComment"),
//  Arg(AnsiString, "lpProvider"),
  Arg(Int64, "lpProvider"),
  "NETRESOURCE",
  input
),
Arg(AnsiString, "lpPassword", input),
Arg(AnsiString, "lpUserName", input),
Arg(Int32, "dwFlags", input),
Returns(Int32)
);

Call with zero for the provider to let the OS select the provider.

result = dll_obj << MapNetworkDrive(
dwScope,
dwType,
dwDisplayType,
dwUsage,
lpLocalName,
lpRemoteName,
lpComment,
0, // lpProvider = NULL
lpPassword,
lpUserName,
dwFlags
);

A caveat I found is that it returns 1219 (ERROR_SESSION_CREDENTIAL_CONFLICT) if I already have a drive mapped to the specified server. Not sure what it needs there to avoid that but it works fine if I connect to a server which I don't have an existing connection to.

Hope this helps,

John

jschroedl

Staff

Joined:

Jun 23, 2011

To unmap the drive, this works for me:

dll_obj << DeclareFunction(
"WNetCancelConnection2A",
Alias("UnmapNetworkDrive"),
Arg(AnsiString, "lpName", input),
Arg(Int32, "dwFlags", input),
Arg(Int32, "fForce", input),
Returns(Int32)
);

Call it:

result = dll_obj << UnmapNetworkDrive(
     lpLocalName,
     0,
     0,  // 1=force connection closed even if files are opened
);