Discussion:
Problem with mapped drives from VB6
(too old to reply)
R C Nesbit
2012-02-08 18:37:12 UTC
Permalink
I have an application which needs to display a directory
tree and an adjacent file list box.

The form contains a DirListBox and a FileListBox.

The application resides in a mapped drive on a Win2008 SBS
machine.

When a new customer record is created the application
checks to see if there is a directory
(it cleans up the customer name first, removing illegal
character)
sPath = app.path & "\AppDocs\" & <customername>
by setting the Dir1.Path = sPath

Then it adds a further folder:
sPath = sPath & "\" & <recordID>
Dir1.Path = sPath

with an error handler:

if Err = 76 then
MkDir sPath
Resume
end if

This works perfectly on this machine.
It works perfectly if run directly on the server (via a
remote terminal window)

When run from a workstation it crashes with
"Error 75 Path/File Access Error"

All users have full read-write privileges on the mapped
drive.

Any clues?
--
Rob Pearson
GS
2012-02-08 19:59:28 UTC
Permalink
My experience with 'mapped' drives/FOLDERS on a remote server is that
this uses a redirect 'namespace' as opposed to a direct absolute path
(PIDL). That's not the same as accessing a 'mapped' drive/FOLDER on a
local machine. In all probability, your app is trying to access a file
from the 'namespace' the mapped folder points to rather than from its
actual target.

Your directory control MUST return an AbsolutePIDL in order for normal
Dir functions to work. I ran into this issue when building a file
manager app for CNC machine program files. I has built-in
folderview/fileview controls. How I was able to make it work for me was
to use 3rd party OCXs, and I was able to get the author to upgrade the
folderview.OCX to return AbsolutePIDL to a new property I could access.
--
Garry

Free usenet access at http://www.eternal-september.org
ClassicVB Users Regroup! comp.lang.basic.visual.misc
Helmut_Meukel
2012-02-09 09:14:59 UTC
Permalink
My experience with 'mapped' drives/FOLDERS on a remote server is that this
uses a redirect 'namespace' as opposed to a direct absolute path (PIDL).
That's not the same as accessing a 'mapped' drive/FOLDER on a local machine.
In all probability, your app is trying to access a file from the 'namespace'
the mapped folder points to rather than from its actual target.
Your directory control MUST return an AbsolutePIDL in order for normal Dir
functions to work. I ran into this issue when building a file manager app for
CNC machine program files. I has built-in folderview/fileview controls. How I
was able to make it work for me was to use 3rd party OCXs, and I was able to
get the author to upgrade the folderview.OCX to return AbsolutePIDL to a new
property I could access.
I never ran into this problem by using UNC paths instead of mapped
drives. Was it just luck or can't it happen with UNC paths?
I use "\Server name\Share name\data file" even if the program runs on
the "server". Same for the app path: "\\Server\Share\MyApp.exe".
There is no drive mapped to the remote resource.
My programs retrieve the DataSaerverName as a start parameter (Command$),
the share name is always the same for a given app (hardcoded).
This approach gives IMHO most flexibility. The server admin is free
to put the data files anywhere - any drive, any folder - just set
the appropriate share name for this folder. (the same folder can have
multiple share names).
Only if the server admin moves the data files to another server, we have
to change the start parameter for the app on all computers.

I don't like the idea of users being able to browse the data folder of
my app and mess with the files there. So usually I use hidden shares.
Share names with a $ appended to it are hidden, e.g. TankData$ doesn't
show up in Windows Explorer.

Helmut.
Helmut_Meukel
2012-02-09 09:16:44 UTC
Permalink
My experience with 'mapped' drives/FOLDERS on a remote server is that this
uses a redirect 'namespace' as opposed to a direct absolute path (PIDL).
That's not the same as accessing a 'mapped' drive/FOLDER on a local machine.
In all probability, your app is trying to access a file from the 'namespace'
the mapped folder points to rather than from its actual target.
Your directory control MUST return an AbsolutePIDL in order for normal Dir
functions to work. I ran into this issue when building a file manager app for
CNC machine program files. I has built-in folderview/fileview controls. How I
was able to make it work for me was to use 3rd party OCXs, and I was able to
get the author to upgrade the folderview.OCX to return AbsolutePIDL to a new
property I could access.
I never ran into this problem by using UNC paths instead of mapped
drives. Was it just luck or can't it happen with UNC paths?
I use "\\Server name\Share name\data file" even if the program runs on
the "server". Same for the app path: "\\Server\Share\MyApp.exe".
There is no drive mapped to the remote resource.
My programs retrieve the DataSaerverName as a start parameter
(Command$),
the share name is always the same for a given app (hardcoded).
This approach gives IMHO most flexibility. The server admin is free
to put the data files anywhere - any drive, any folder - just set
the appropriate share name for this folder. (the same folder can have
multiple share names).
Only if the server admin moves the data files to another server, we
have
to change the start parameter for the app on all computers.

I don't like the idea of users being able to browse the data folder of
my app and mess with the files there. So usually I use hidden shares.
Share names with a $ appended to it are hidden, e.g. TankData$ doesn't
show up in Windows Explorer.

Helmut.
GS
2012-02-09 14:40:36 UTC
Permalink
Post by Helmut_Meukel
My experience with 'mapped' drives/FOLDERS on a remote server is that this
uses a redirect 'namespace' as opposed to a direct absolute path (PIDL).
That's not the same as accessing a 'mapped' drive/FOLDER on a local
machine. In all probability, your app is trying to access a file from the
'namespace' the mapped folder points to rather than from its actual target.
Your directory control MUST return an AbsolutePIDL in order for normal Dir
functions to work. I ran into this issue when building a file manager app
for CNC machine program files. I has built-in folderview/fileview controls.
How I was able to make it work for me was to use 3rd party OCXs, and I was
able to get the author to upgrade the folderview.OCX to return AbsolutePIDL
to a new property I could access.
I never ran into this problem by using UNC paths instead of mapped
drives. Was it just luck or can't it happen with UNC paths?
I use "\\Server name\Share name\data file" even if the program runs on
the "server". Same for the app path: "\\Server\Share\MyApp.exe".
There is no drive mapped to the remote resource.
My programs retrieve the DataSaerverName as a start parameter (Command$),
the share name is always the same for a given app (hardcoded).
This approach gives IMHO most flexibility. The server admin is free
to put the data files anywhere - any drive, any folder - just set
the appropriate share name for this folder. (the same folder can have
multiple share names).
Only if the server admin moves the data files to another server, we have
to change the start parameter for the app on all computers.
I don't like the idea of users being able to browse the data folder of
my app and mess with the files there. So usually I use hidden shares.
Share names with a $ appended to it are hidden, e.g. TankData$ doesn't
show up in Windows Explorer.
Helmut.
In this case you are using an absolute path. This is not the same as a
mapped folder to a network share.

AFAIK, when you click on a mapped folder to a network share in WE it
actually accesses the absolute path from the namespace pointer. Perhaps
using system Dir components this is automagically done behind the
scenes, but my experience with using the treeview folder browser is
that it returns the namespace the mapped folder points to. I was never
able to figure out how to get it to return an absolute path to the
network share and so I got the author of my 3rd party FolderView.OCX to
upgrade it to do that. He knew exactly what the issue was and how to
compensate for the namespace redirect issue that happens in WE.
--
Garry

Free usenet access at http://www.eternal-september.org
ClassicVB Users Regroup! comp.lang.basic.visual.misc
Farnsworth
2012-02-09 15:03:23 UTC
Permalink
Post by GS
In this case you are using an absolute path. This is not the same as a
mapped folder to a network share.
AFAIK, when you click on a mapped folder to a network share in WE it
actually accesses the absolute path from the namespace pointer. Perhaps
using system Dir components this is automagically done behind the scenes,
but my experience with using the treeview folder browser is that it
returns the namespace the mapped folder points to. I was never able to
figure out how to get it to return an absolute path to the network share
and so I got the author of my 3rd party FolderView.OCX to upgrade it to do
that. He knew exactly what the issue was and how to compensate for the
namespace redirect issue that happens in WE.
I am not sure if this is the problem that the OP has, but in your case, you
could use SHParseDisplayName() to get ITEMIDLIST, then call
SHGetPathFromIDList() to get the full path. My guess is that this for
folders that are shown as "Desktop", "My Documents", and virtual folders
that some software create, like some FTP programs. There are probably other
functions that I have missed.
Farnsworth
2012-02-09 15:23:54 UTC
Permalink
Post by Farnsworth
I am not sure if this is the problem that the OP has,
Also, the OP is using DirListBox/FileListBox and these don't view the
virtual folders like "Desktop", "My Documents", etc.
DaveO
2012-02-09 15:36:35 UTC
Permalink
Post by GS
AFAIK, when you click on a mapped folder to a network share in WE it
actually accesses the absolute path from the namespace pointer. Perhaps
using system Dir components this is automagically done behind the scenes,
but my experience with using the treeview folder browser is that it
returns the namespace the mapped folder points to. I was never able to
figure out how to get it to return an absolute path to the network share
and so I got the author of my 3rd party FolderView.OCX to upgrade it to do
that. He knew exactly what the issue was and how to compensate for the
namespace redirect issue that happens in WE.
You want to dereference mapped drives do you? try this:

(as ever watch out for line wrapping)

DECLARATIONS
-------------------
Private Const RESOURCETYPE_ANY As Long = &H0
Private Const RESOURCE_CONNECTED As Long = &H1

Private Type NETRESOURCE
dwScope As Long
dwType As Long
dwDisplayType As Long
dwUsage As Long
lpLocalName As Long
lpRemoteName As Long
lpComment As Long
lpProvider As Long
End Type

Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal
lpString As Any) As Long
Private Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal
lpString1 As Any, ByVal lpString2 As Any) As Long
Private Declare Function WNetOpenEnum Lib "mpr.dll" Alias "WNetOpenEnumA"
(ByVal dwScope As Long, ByVal dwType As Long, ByVal dwUsage As Long,
lpNetResource As Any, lphEnum As Long) As Long
Private Declare Function WNetEnumResource Lib "mpr.dll" Alias
"WNetEnumResourceA" (ByVal hEnum As Long, lpcCount As Long, lpBuffer As Any,
lpBufferSize As Long) As Long
Private Declare Function WNetCloseEnum Lib "mpr.dll" (ByVal hEnum As Long)
As Long

FUNCTION
-------------
Public Function LetterToUNC(DriveLetter As String) As String
Dim hEnum As Long
Dim NetInfo(1023) As NETRESOURCE
Dim entries As Long
Dim nStatus As Long
Dim LocalName As String
Dim UNCName As String
Dim i As Long
Dim r As Long

' Begin the enumeration
nStatus = WNetOpenEnum(RESOURCE_CONNECTED, RESOURCETYPE_ANY, 0&, ByVal 0&,
hEnum)
LetterToUNC = DriveLetter

'Check for success from open enum
If ((nStatus = 0) And (hEnum <> 0)) Then
' Set number of entries
entries = 1024

' Enumerate the resource
nStatus = WNetEnumResource(hEnum, entries, NetInfo(0),
CLng(Len(NetInfo(0))) * 1024)

' Check for success
If nStatus = 0 Then
For i = 0 To entries - 1
' Get the local name
LocalName = ""
If NetInfo(i).lpLocalName <> 0 Then
LocalName = Space(lstrlen(NetInfo(i).lpLocalName) + 1)
r = lstrcpy(LocalName, NetInfo(i).lpLocalName)
End If
If Len(LocalName) <> 0 Then LocalName = Left(LocalName,
(Len(LocalName) - 1))
If UCase$(LocalName) = UCase$(DriveLetter) Then
UNCName = ""
If NetInfo(i).lpRemoteName <> 0 Then
UNCName = Space(lstrlen(NetInfo(i).lpRemoteName) + 1)
r = lstrcpy(UNCName, NetInfo(i).lpRemoteName)
End If
If Len(UNCName) <> 0 Then UNCName = Left(UNCName, (Len(UNCName) -
1))
LetterToUNC = UNCName
Exit For
End If
Next i
End If
End If

' End enumeration
nStatus = WNetCloseEnum(hEnum)
End Function

POSSIBLE USAGE
--------------------
Private Function DeRefPath(ChkPath As String) As String
If Mid$(ChkPath, 2, 1) = ":" Then
DeRefPath = LetterToUNC(Left$(ChkPath, 2)) & Mid$(ChkPath, 3)
Else
DeRefPath = ChkPath
End If
End Function


This is from my library of "possibly useful code" I've collected over the
years and is largely unattributed so I'd like to both thank and apologise to
whoever I "borrowed" whatever I based this code on.



Regards

DaveO
GS
2012-02-09 18:52:37 UTC
Permalink
My intent was to NOT have to use API workarounds. I already did this
using Brad Martinez's VBExplorer as a base (with different APIs) and it
just took too much coding for my liking. Thus, I went with ssware's
folderview/fileview OCXs so I ended up with a leaner/smaller EXE that
also gave me added functionality beyond what was doable in VBExplorer
(or WE for that matter). Turned out to be a worthwhile investment,
allowing me to build apps with fully customizeable built-in explorers.

Since it's imminent that the vbruntime will be deprecated soon, I've
rewritten the app using these OCXs in VS2008 C++ MFC. Everything else I
do revolves around MS Excel VBA (where these OCXs also work). I'd stick
with VB6 if I knew that we can distribute the runtime without legal
issues, but I'm prepared to move forward regardless. Given the learning
curve is about equal for transitioning to VB.Net/C#/C++ I decided C++
is probably going to serve me best down the road since I don't plan to
upgrade any 3rd party OCXs to Winforms compatible versions.
--
Garry

Free usenet access at http://www.eternal-september.org
ClassicVB Users Regroup! comp.lang.basic.visual.misc
DaveO
2012-02-10 10:49:18 UTC
Permalink
Post by GS
Since it's imminent that the vbruntime will be deprecated soon,
Says who?

http://msdn.microsoft.com/nb-no/vbrun/ms788708%28en-us%29.aspx

Executive Summary

The Visual Basic team is committed to "It Just Works" compatibility for
Visual Basic 6.0 applications on Windows Vista, Windows Server 2008
including R2, Windows 7, and Windows 8.

The Visual Basic team's goal is that Visual Basic 6.0 applications that
run on Windows XP will also run on Windows Vista, Windows Server 2008,
Windows 7, and Windows 8. As detailed in this document, the core Visual
Basic 6.0 runtime will be supported for the full lifetime of Windows
Vista, Windows Server 2008, Windows 7, and Windows 8, which is five
years of mainstream support followed by five years of extended support
(http://support.microsoft.com/gp/lifepolicy).

(with thanks to Karl)

What's the problem with using the API anyway, how do you think the OCX's
work, pixiedust?

Regards
DaveO.
GS
2012-02-11 03:00:25 UTC
Permalink
Post by DaveO
Post by GS
Since it's imminent that the vbruntime will be deprecated soon,
Says who?
http://msdn.microsoft.com/nb-no/vbrun/ms788708%28en-us%29.aspx
Executive Summary
The Visual Basic team is committed to "It Just Works" compatibility for
Visual Basic 6.0 applications on Windows Vista, Windows Server 2008
including R2, Windows 7, and Windows 8.
The Visual Basic team's goal is that Visual Basic 6.0 applications that
run on Windows XP will also run on Windows Vista, Windows Server 2008,
Windows 7, and Windows 8. As detailed in this document, the core Visual
Basic 6.0 runtime will be supported for the full lifetime of Windows
Vista, Windows Server 2008, Windows 7, and Windows 8, which is five
years of mainstream support followed by five years of extended support
(http://support.microsoft.com/gp/lifepolicy).
(with thanks to Karl)
Yeah, I saw that AFTER I posted. Looks like there's no rush to replace
my VB6 apps anytime soon!<bg>
Post by DaveO
What's the problem with using the API anyway, how do you think the OCX's
work, pixiedust?
As I stated, I already did that via Brad Martinez's VBExplorer. The 3rd
party OCXs have extended features unique to themselves and so no need
to use standard controls with lots of APIs since they don't come with
the extended features that have been built into the 3rd party OCXs.
Sure, I could build my own custom controls but at what cost? Cheaper &
easier to go with ready-made stuff IMO!<g>
Post by DaveO
Regards
DaveO.
--
Garry

Free usenet access at http://www.eternal-september.org
ClassicVB Users Regroup! comp.lang.basic.visual.misc
Deanna Earley
2012-02-09 09:56:03 UTC
Permalink
On 08/02/2012 18:37, R C Nesbit wrote:
<SNIP>
Post by R C Nesbit
This works perfectly on this machine.
It works perfectly if run directly on the server (via a
remote terminal window)
When run from a workstation it crashes with
"Error 75 Path/File Access Error"
All users have full read-write privileges on the mapped
drive.
On both the folder AND the share?
As a sanity check, can that use create a folder in that location in
Explorer?
--
Deanna Earley (***@icode.co.uk)
i-Catcher Development Team
http://www.icode.co.uk/icatcher/

iCode Systems

(Replies direct to my email address will be ignored.
Please reply to the group.)
R C Nesbit
2012-02-09 10:08:57 UTC
Permalink
Post by Deanna Earley
Post by R C Nesbit
When run from a workstation it crashes with
"Error 75 Path/File Access Error"
All users have full read-write privileges on the mapped
drive.
On both the folder AND the share?
As a sanity check, can that use create a folder in that location in
Explorer?
Yes, we checked that.
--
Rob Pearson
R C Nesbit
2012-02-09 15:14:42 UTC
Permalink
Post by R C Nesbit
Post by Deanna Earley
Post by R C Nesbit
When run from a workstation it crashes with
"Error 75 Path/File Access Error"
All users have full read-write privileges on the mapped
drive.
On both the folder AND the share?
As a sanity check, can that use create a folder in that location in
Explorer?
Yes, we checked that.
Just to muddy the waters even more, we tried it on our office running
it from our Linux server from a Win7 workstation - it worked fine.
We took a laptop to another office and hooked onto their Win2008 server
and it worked fine there, so it *could* be a permisions issue, but you
can create folders on the share using WE
--
Rob Pearson
Farnsworth
2012-02-09 15:32:16 UTC
Permalink
Post by R C Nesbit
I have an application which needs to display a directory
tree and an adjacent file list box.
The form contains a DirListBox and a FileListBox.
The application resides in a mapped drive on a Win2008 SBS
machine.
When a new customer record is created the application
checks to see if there is a directory
(it cleans up the customer name first, removing illegal
character)
sPath = app.path & "\AppDocs\" & <customername>
by setting the Dir1.Path = sPath
sPath = sPath & "\" & <recordID>
Dir1.Path = sPath
if Err = 76 then
MkDir sPath
Resume
end if
This works perfectly on this machine.
It works perfectly if run directly on the server (via a
remote terminal window)
When run from a workstation it crashes with
"Error 75 Path/File Access Error"
MkDir and DirListBox/FileListBox would generate an error if an intermediate
folder does not exist. Could be because the admin made "AppDocs" into a
share and mapped that instead. I would print the path as the app sees it in
the error message. Example:

MsgBox Err.Number & ": " & Err.Description & vbCrLf & "Path is '" & sPath &
"'"

This prints the error and the path surrounded by single quotes, just in case
there are extra spaces. Tell the user to press Ctrl+C when the dialog
appears. This copies the contents to the Clipboard as text. This feature was
present since the Windows 9x days.
R C Nesbit
2012-02-09 18:14:22 UTC
Permalink
Post by Farnsworth
MkDir and DirListBox/FileListBox would generate an error if an intermediate
folder does not exist. Could be because the admin made "AppDocs" into a
share and mapped that instead. I would print the path as the app sees it in
MsgBox Err.Number & ": " & Err.Description & vbCrLf & "Path is '" & sPath &
"'"
This prints the error and the path surrounded by single quotes, just in case
there are extra spaces. Tell the user to press Ctrl+C when the dialog
appears. This copies the contents to the Clipboard as text. This feature was
present since the Windows 9x days.
Which would be great (actually I have lots of error handlers all logging the
err, error, Calling Routine, UserID, date & time to an errlog table.

However this error happens *inside* the error handler, so just dumps out.
--
Rob Pearson
Loading...