Link to home
Start Free TrialLog in
Avatar of Quark-E
Quark-EFlag for United States of America

asked on

Compiled service cannot see or access mapped drives

We have an application server that was running Windows 2003 that I upgraded yesterday to Server 2008.  This server has several homegrown compiled services that interface with legacy systems by writing files out to mapped network drives.

After the upgrade the services couldn't access the drives.  The logs showed a 1219 error, and some testing revealed that only the first connection to the server worked.  We have a total of six connections to different folders on the same server, all under the same credentials.

In 2003 this worked fine.  We used WNetAddConnection2 in VB6 inside of a drive mapping service.  It read all the desired drive letters, paths and credentials from a database, then executed the maps, checking them periodically and re-mapping as needed.

The other services simply verified the drive letter's status they needed, then ran their extract.  Worked great.  All services ran under the System account.  The drive letters weren't accessible in User mode but showed up as Disconnected drives in Explorer.

Once I saw that I couldn't find a quick fix for the 1219 error, since the central IT group doesn't want my service credentials to be able to make a single high-level map, I tried to trick the system by adding entries to the Hosts file that linked the same server IP to six different hostnames.  It worked in that a ping to any of the names resolved to the correct IP, but now I got an error 52 on all of the map attempts, and I couldn't figure out much about that.

I thought I'd make it through the weekend by creating a quick little CMD to make the maps.

That part worked fine, but the services couldn't see the drives, even if I ran them under my personal credentials, to avoid the Null session of the system account.

Finally, I created a quick little test VB6 app that attempted to verify status of a mapped drive, then write to it.  This would work fine in the IDE, or even if I ran the compiled EXE myself.  As soon as I ran it as a service, the program could not 'see' or access the mapped drive, again, no matter what credentials I used for the service.

I will accept one of three things as a solution:

(1) help me find a way to configure my original VB6 drive mapping program so it doesn't get 1219 errors when it makes multiple maps to the same server with the same credentials.  My research seems to show that MS says this is by design for 'security', but why does it work in 2003 and even in 2008 if I make the maps at the command line via CMD instead of via WNetAddConnection2?

(2) Help me figure out how to configure the services so they can see 'normal' mapped drives.  Keep in mind that I've already tried to run the services as myself (I'm an admin), the actual Administrator, and the system account both with and without the Interact with Desktop ticked.

(3) A no- or low-cost completely different way to specify and create mapped drives that are accessible to compiled VB6 services that will attempt to access a drive letter.  In other words, I need a way to create an 'X:' drive that a VB6 service can use, where all the VB program knows is that it needs to write to X:.

Thanks.
ASKER CERTIFIED SOLUTION
Avatar of Robberbaron (robr)
Robberbaron (robr)
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Quark-E

ASKER

robberbaron, how would I pass the credentials from inside VB6 since the machine running the service is stand-alone, and the shares are on the Active Directory?  And if I use WNetAddConnection2 as I already am, it's actually making connections to a UNC path exactly as you list (those are the paths stored on my database, which was my way of handling new additions and changes since I don't even have to touch the VB code at all).

Perhaps I'm missing something.  Thanks for the reply and any follow-up you may have.
sorry. didnt pickup the point about the machine holding the service not being part of domain, so the user credentials have to be provided internally, rather than ineriting the service credentials.
So cant be much help myself.

A few ideas i found.
http://www.tek-tips.com/viewthread.cfm?qid=1382999&page=1  ... CreateProcessWithLogon may be of use though appears messy.

http://msdn.microsoft.com/en-us/library/ms682431(VS.85).aspx   notes ... This value can be used to create a process that uses a different set of credentials locally than it does remotely. This is useful in inter-domain scenarios where there is no trust relationship. )

 http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/2fc48697-b846-4b8e-8351-80798ceda3a1


Avatar of Quark-E

ASKER

I'm going to go ahead and accept your solution, robberbaron, because you got me thinking along slightly different lines, even if I ended up finding a different method than any you directly suggested.  I'll have to move away from my framework where I have a separate drive-mapping service to where each individual service makes any connections it needs when it needs them, but this is probably more efficient anyway.

I can key my database (and the resulting mapped drive letters) to particular programs to ensure than no two ever simultaneously try to map the same letter to different paths.  I will also employ a FileSystemObject call (fsoMain.Drives.Item(varDriveLetter).IsReady), which returns True or False to determine whether I need to make the connection, or if it's available for the file I/O.

The method that seems to work so far in my testing is this:


Set WshNetworkt = CreateObject("WScript.Network")
'
'these variables will be read from an encrypted db table
'in the real world
'you could static them in the connection command below 
'if you wanted something simpler and trusted credentials in source code
'
ServerName = "YourServername"
ShareName = "YourShareName"
DomainName = "DomainName" 'Enter the domain name to authenticate to.
UserID = "DomainUserID" 'Enter the user account
Password = "*****" 'You will need to type a password here
'
'make the actual drive connection
'
WshNetwork.MapNetworkDrive "Y:", "\\" & ServerName & "\" & ShareName, , DomainName & "\" & UserID, Password
'
'do your work with the drive
'
'disconnect the connection (the first True forces even if in use)
'
WshNetwork.RemoveNetworkDrive "Y:", True, True
'
'Clean up
'
Set WshNetwork = nothing

Open in new window

Avatar of Quark-E

ASKER

Thanks.  See my final comment below for the exact implementation I chose.