|
Wenn ein String eine gültige vollständige Pfadangabe zu einer Datei bzw. einem Verzeichnis darstellen soll, muss er zwei Bedingungen erfüllen. Zum einen muss der Pfad mit einer gültigen Wurzel beginnen - entweder mit einer Laufwerksbezeichnung (wie etwa "c:\") oder mit einem UNC-Namen eines freigegebenen Netzwerkordners (wie etwa "\\Server\Ordner"). Zum anderen dürfen die auf die Wurzel folgenden Pfadbestandteile keine ungültigen Zeichen enthalten, die das Dateisystem für sich reserviert hat - diese sind das (doppelte) Anführungszeichen und die Zeichen "*\:><|?/". Eine Pfadangabe, der Leerzeichen enthält, kann jedoch von Anführungszeichen eingeschlossen sein, die daher zur weiteren Prüfung erst entfernt werden müssen.
Im einfachsten Fall können Sie die Prüfung der Gültigkeit erledigen, indem Sie einfach prüfen, ob die Pfadangabe auf eine bereits vorhandene Datei bzw. auf einen bereits vorhandenen Ordner verweist. Ist dies der Fall, handelt es sich ja zwangsläufig um eine gültige Pfadangabe, und weitere Prüfungen erübrigen sich.
Die folgende Funktion IsValidPath verwendet eine Reihe von API-Funktionen aus der so genannten "Shell Lightweight Utility"-Bibliothek (SHLWAPI.DLL), die ab Windows 98 bzw. beim Vorhandensein eines Internet Explorers ab Version 4 zur Verfügung steht. Einige dieser Funktionen legen ihre Ergebnisse C-typisch in einem Puffer ab, in dem das Ende des Resultat-Strings durch ein Null-Zeichen (Ascii 0 bzw. vbNullChar) markiert ist - das Abschneiden dieses Puffers an dieser Stelle erfolgt auf die in "Null-Schneider" beschriebene Weise.
Da die Prüfung, ob die Pfadangabe bereits auf eine vorhandene Datei bzw. auf einen vorhandenen Ordner verweist, bei UNC-Pfadangaben unter Umständen etwas länger dauern kann, wenn das Betriebssystem die Wurzel nicht sofort findet, können Sie im zweiten Parameter der Funktion TestUNCPaths die Prüfung bei UNC-Pfadangaben gegebenenfalls unterbinden, indem Sie hier den Wert False übergeben.
Private Declare Function InStrNullChar Lib "kernel32.dll" _
Alias "lstrlenA" (ByVal lpString As Any) As Long
Private Declare Function PathFileExists Lib "shlwapi.dll" _
Alias "PathFileExistsA" (ByVal pszPath As String) As Long
Private Declare Function PathIsUNC Lib "shlwapi.dll" _
Alias "PathIsUNCA" (ByVal pszPath As String) As Long
Private Declare Function PathIsUNCServer Lib "shlwapi.dll" _
Alias "PathIsUNCServerA" (ByVal pszPath As String) As Long
Private Declare Function PathRemoveFileSpec Lib "shlwapi.dll" _
Alias "PathRemoveFileSpecA" (ByVal pszPath As String) As Long
Private Declare Function PathStripToRoot Lib "shlwapi.dll" _
Alias "PathStripToRootA" (ByVal pszPath As String) As Long
Private Declare Sub PathUnquoteSpaces Lib "shlwapi.dll" _
Alias "PathUnquoteSpacesA" (ByVal lpsz As String)
Public Function IsValidPath(Path As String, _
Optional ByVal TestUNCPaths As Boolean = True) As Boolean
Dim i As Integer
Dim c As Integer
Dim nBytes() As Byte
Dim nChar As String
Dim nOK As Boolean
Dim nParentPath As String
Dim nPos As Long
Dim nRoot As String
Dim nPath As String
Dim nPathParts() As String
Dim nStart As Integer
Const kCharAsterisk = 42
Const kCharBackSlash = 92
Const kCharColon = 58
Const kCharGreaterThan = 62
Const kCharLowerThan = 60
Const kCharPipe = 124
Const kCharQuestion = 63
Const kCharQuote = 34
Const kCharSlash = 47
nPath = Path
Zunächst werden Anführungszeichen, die eventuell die Pfadangabe einschließen, entfernt:
PathUnquoteSpaces nPath
nPath = Left$(nPath, InStrNullChar(nPath))
Hier erfolgt nun die Prüfung, ob die Pfadangabe auf eine vorhandene Datei oder einen vorhandenen Ordner verweist:
If Not CBool(PathIsUNC(nPath) And Not TestUNCPaths) Then
If CBool(PathFileExists(nPath)) Then
IsValidPath = True
Exit Function
End If
End If
nRoot = nPath
Die Funktion PathStripToRoot versucht, die Pfadangabe auf eine Wurzel zu reduzieren. Schlägt schon dies fehl (die Funktion gibt den Wert 0 zurück), kann es sich nicht um eine gültige Pfadangabe handeln.
If PathStripToRoot(nRoot) Then
nRoot = Left$(nRoot, InStrNullChar(nRoot))
Handelt es sich bei der Wurzel um eine UNC-Pfadangabe,
If PathIsUNC(nRoot) Then
nPos = InStrRev(nRoot, "\")
nRoot = Left$(nRoot, nPos - 1)
wird weiterhin geprüft, ob die Server-Angabe in der Wurzel gültig ist:
If PathIsUNCServer(nRoot) Then
In jedem Fall wird anschließend die Wurzel von der gesamten Pfadangabe entfernt, um anschließend die Prüfung der verbleibenden Pfadangabe auf ungültige Zeichen vornehmen zu können:
nPath = Mid$(nPath, Len(nRoot) + 1)
End If
Else
nPath = Mid$(nPath, Len(nRoot) + 1)
End If
If Len(nPath) Then
Hierzu wird die verbleibende Pfadangabe in ihre Bestandteile zerlegt:
nPathParts = Split(nPath, "\")
Da bei UNC-Pfaden die verbleibende Pfadangabe mit einem Backslash beginnt, braucht natürlich der erste, leer bleibende Pfadbestandteil nicht auf ungültige Zeichen geprüft werden:
If Len(nPathParts(0)) Then
nStart = 0
Else
nStart = 1
End If
For i = nStart To UBound(nPathParts)
Jeder Bestandteil wird nun in ein Byte-Array umgewandelt, das die Ascii-Werte der einzelnen Zeichen enthält. Da Visual Basic einen String intern als Unicode-String behandelt, würde eine einfache Zuweisung an ein Byte-Array zu je zwei Elementen je Zeichen führen. Die vorherige Konvertierung mit StrConv sorgt daher dafür, dass nun die Ascii-Zeichen selbst im Array landen:
nBytes = StrConv(nPathParts(i), vbFromUnicode)
Nun wird jedes Byte des Arrays auf ungültige Zeichen geprüft. Tritt ein ungültiges Zeichen auf, werden die beiden verschachtelten Schleifen verlassen - es kann sich nicht mehr um eine gültige Pfadangabe handeln und eine weitere Prüfung erübrigt sich:
For c = 0 To UBound(nBytes)
Select Case nBytes(c)
Case Is < 32, Is > 255, _
kCharAsterisk, kCharBackSlash, kCharColon, _
kCharGreaterThan, kCharLowerThan, kCharPipe, _
kCharQuestion, kCharQuote, kCharSlash
nOK = False
Exit For
Case Else
nOK = True
End Select
Next 'c
If Not nOK Then
Exit For
End If
Next 'i
IsValidPath = nOK
End If
End If
End Function
|