Image of Navigational Map linked to Home / Contents / Search (Back)Slash and Burn

by Miles Forrest - Independent Developer
Image of Line Break

I think we've all been bitten by App.Path's inconsistencies with backslash over the years.

OK, I concede that it's not actually inconsistent, but it isn't consistent either.

OK, I concede that it's actually consistent to include the trailing backslash for root directories and not for others, because the backslash is the start of the directory name, not the end. So that means it's DOS' fault.

OK, I concede it's not actually DOS' fault per se - I mean, what else could DOS do?

Anyway, if you'd stop arguing with me, the point is that that pesky backslash causes me pain. It annoys me. So I fixed the problem.

This little module is invaluable, even though it only contains five small functions.

Type FILETIME  '  8  Bytes
     dwLowDateTime As Long
     dwHighDateTime As Long
End Type

Type WIN32_FIND_DATA  '  318  Bytes
        dwFileAttributes As Long
        ftCreationTime As FILETIME
        ftLastAccessTime As FILETIME
        ftLastWriteTime As FILETIME
        nFileSizeHigh As Long
        nFileSizeLow As Long
        dwReserved¯ As Long
        dwReserved1 As Long
        cFileName As String * 255
        cAlternate As String * 14
End Type

Private Const INVALID_HANDLE_VALUE& = -1

Private Declare Function GetLogicalDriveStrings& Lib "kernel32" Alias "GetLogicalDriveStringsA"_
    (ByVal nBufferLength As Long, ByVal lpBuffer As String)
Private Declare Function FindFirstFile& Lib "kernel32" Alias "FindFirstFileA"_
    (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA)
Private Declare Function FindClose& Lib "kernel32"_
    (ByVal hFindFile As Long)
The FileExists Function finds a file or directory, and returns True if it exists. Just throw it a file or directory name (with or without trailing backslash!) and Bob's your uncle.
Public Function FileExists(ByVal zvDirectoryFileName As String) As Boolean

Dim typpFindFileData As WIN32_FIND_DATA
Dim lpHandle As Long
Dim lpSuccess As Long
Dim lpBufferLength As Long
Dim zpLogicalDrives As String * 106  '26 drive letters, 4 characters for each 
                                     'and 2 nulls at the end

'Are we dealing with the root directory of a logical drive?
'(Put the 2 spaces in just in case the input string is less
'that 2 characters which will case right$ to blow up)
If Right$("  " & zvDirectoryFileName, 2) = ":\" Then
  'Get a list of the logical drives in the format "A:\#c:\#d:\##"  where # is NULL
  lpSuccess = GetLogicalDriveStrings(106, zpLogicalDrives)
  FileExists = Not (InStr(1, zpLogicalDrives, zvDirectoryFileName, vbTextCompare) = 0)
  'Find the file
  lpHandle = FindFirstFile(zvDirectoryFileName, typpFindFileData)

  'If the handle is invalid then the path\file is not found (or errored)
  FileExists = Not (INVALID_HANDLE_VALUE = lpHandle)

  'Zap the structure
  lpSuccess = FindClose(lpHandle)
End If
End Function

The PutBackslashPostfix Function is my all purpose "get that trailing backslash there" workhorse. If there's no trailing backslash, there is when this is finished with it!

Public Function PutBackslashPostfix(ByVal svPath As String) As String

PutBackslashPostfix = IIf(Len(svPath) = 0, "\", svPath &_
   IIf(Right$(svPath, 1) = "\", "", "\"))

End Function
Of course, it's not only trailing backslashes that need to be attacked. Sometimes you need to insert one at the fornt. PutBackslashPrefix handles this.
Public Function PutBackslashPrefix(ByVal svPath As String) As String

PutBackslashPrefix = IIf(Len(svPath) = 0, "\", _
   IIf(Left$(svPath, 1) = "\", "", "\") & svPath)
End Function
Not surprisingly, I also went to town with a similar pair of removal functions.
Public Function RemoveBackslashPostfix(ByVal svPath As String) As String

RemoveBackslashPostfix = IIf(Len(svPath) = 0, "", _
   IIf(Right$(svPath, 1) = "\", Left$(svPath, Len(svPath) - 1), svPath))
End Function

Public Function RemoveBackslashPrefix(ByVal svPath As String) As String

RemoveBackslashPrefix = IIf(Len(svPath) = 0, "", _
   IIf(Left$(svPath, 1) = "\", Right$(svPath, Len(svPath) - 1), svPath))
End Function

So now, I don't care whose fault it is, or whether it's inconsistent or not.

The important thing is, it's fixed.

Written by: Miles Forrest
August '98

Image of Arrow linked to Previous Article Image of Arrow linked to Next Article
Image of Line Break