Online
Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.078 Beiträge
Delphi 12 Athens
|
Re: Dateiname auf Gültigkeit prüfen
29. Jul 2005, 06:04
Gut, dann werd' ich versuchen es noch etwas zu verbessern.
Allerdings haben die Codes der Anderen mit 'test.txt.' auch ihre Probleme.
Wobei 'test.txt.' als 8.3-Dateiname bei mir nicht durchgehen dürfte ^^
Und das mit dem PosEx vergesse ich manchmal ... da ich es aus 'ner eigenen Codesammlung importiere und weil es in D7 auch nochmal existiert hatte ich es dementsprechend geändert.
eventuell fallen da ja einige unterschiede zum obrigen Code auf ._.
Delphi-Quellcode:
Function CheckFilename(FileName: AnsiString; Mode: TCFNameMode = []; Directory: AnsiString = ''): ByteBool;
Var i: Integer;
Quoted: Boolean;
Buffer: Array[1..MaxPath] of AnsiChar;
P: PAnsiChar;
Begin
Result := False;
If FileName = '' Then Exit;
Quoted := (cnmQuoteEnabled in Mode) and (FileName[1] = '"') and (FileName[_Length(FileName)] = '"');
If Quoted Then FileName := _Copy(FileName, 2, _Length(FileName) - 2);
If (FileName[1] = ' ') and (FileName[_Length(FileName)] = ' ') Then Exit;
For i := _Length(FileName) downto 1 do
If (FileName[i] in CFForbiddenChars) or
((cnmDOSCompatible in Mode) and (not Quoted) and (FileName[i] in CFForbiddenCharsDOS)) or
(((cnm8Point3Names in Mode) or ((cnmQuoteEnabled in Mode) and not Quoted)) and (FileName[i] = ' ')) Then Exit;
If cnm8Point3Names in Mode Then Begin
i := _Pos('.', FileName);
If i = 0 Then i := _Length(FileName) + 1;
If (i > 9) or (_Length(FileName) - i > 3) or (_PosEx('.', FileName, i + 1) > 0) Then Exit;
End;
If Directory <> '' Then Begin
If Directory[_Length(Directory)] <> '\' Then _ConcatV(Directory, '\');
_Swap(FileName, Directory);
_ConcatV(FileName, Directory);
End;
i := GetFullPathNameA(PAnsiChar(FileName), MaxPath, @Buffer, P);
If (i <= 0) or (i >= MaxPath) Then Exit;
Result := True;
End;
Also dann mach ich mich mal wieder an's Werk und mit viel Glück kommt bald (endlich) mal meine UCC raus, wo dieses auch mit drin ist, und dort gibt es dann mit PosEx jedenfalls keine Probleme mehr
[add]
[d]Ach ja, dein zweites Zitat werde ich erstmal ignorieren, da die Leerzeichen bei mir nicht nur am Namensende, sonderen auch am Anfang behandelt werden:[/d]
If (FileName[1] = ' ') and (FileName[_Length(FileName)] = ' ') Then Exit;
Und ja, die Pfadangabe kann fehlerhaft sein, da hier nur der Dateiname geprüft wird.
Aber wenn es gewünscht wird, dann kann ich auch diesen noch mit in die Prüfung aufnehmen.
Obwohl ein "total" falscher Pfadname über GetFullPathName ebenfalls mit behandelt und als Fehler quitiert wird.
[add2]
Ich hoffe es funktioniert und gefällt dir vorerst schonmal so etwas besser.
Wie gesagt, das mit dem Pfad werde ich mir auch noch auf Wunsch vornehmen.
Hab versucht die beiden Zitate mit einfließen zu lassen.
(und wie mir aufgefallen ist, sind Leerzeichen am Anfang unter Umständen auch erlaubt)
Delphi-Quellcode:
Const CFForbiddenChars: Set of AnsiChar = [#0..#31, '"', '*', '/', ':', '<', '>', '?', '\', '|'];
CFForbiddenCharsDOS: Set of AnsiChar = ['+', ';', '=', '[', ']'];
CFForbiddenNames: Array[0..6] of AnsiString = ('AUX', 'CLOCK$', 'COM1', 'COM2', 'COM3', 'COM4',
'COM5', 'COM6', 'COM7', 'COM8', 'COM9', 'CON', 'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6',
'LPT7', 'LPT8', 'LPT9', 'NUL', 'PRN');
Function CheckFilename(FileName: AnsiString; Mode: TCFNameMode = []; Directory: AnsiString = ''): ByteBool;
Var i: Integer;
Quoted: Boolean;
Buffer: Array[1..MAX_PATH] of AnsiChar;
P: PAnsiChar;
Begin
Result := False;
If FileName = '' Then Exit;
Quoted := (cnmQuoteEnabled in Mode) and (FileName[1] = '"') and (FileName[Length(FileName)] = '"');
If Quoted Then FileName := Copy(FileName, 2, Length(FileName) - 2);
If (FileName = '') or
((cnmQuoteEnabled in Mode) and (not Quoted) and (FileName[1] = ' ')) or
((cnmErrorLeftChar in Mode) and (FileName[Length(FileName)] in [' ', '.'])) Then Exit;
For i := Length(FileName) downto 1 do
If (FileName[i] in CFForbiddenChars) or
((cnmDOSCompatible in Mode) and (not Quoted) and (FileName[i] in CFForbiddenCharsDOS)) or
(((cnm8Point3Names in Mode) or ((cnmQuoteEnabled in Mode) and not Quoted)) and (FileName[i] = ' ')) Then Exit;
If cnm8Point3Names in Mode Then Begin
i := Pos('.', FileName);
If i = 0 Then i := Length(FileName) + 1;
If (i > 9) or (Length(FileName) - i > 3) or (PosEx('.', FileName, i + 1) > 0) Then Exit;
End;
For i := 0 to High(CFForbiddenNames) do If LowerCase(FileName[1]) = CFForbiddenNames[i] Then Exit;
If Directory <> '' Then Begin
If Directory[Length(Directory)] <> '\' Then Directory := Directory + '\';
FileName := Directory + FileName;
End;
i := GetFullPathNameA(PAnsiChar(FileName), MAX_PATH, @Buffer, P);
If (i <= 0) or (i >= MAX_PATH) Then Exit;
Result := True;
End;
Ach ja, mir ist so, als wenn sich einige Derivate von PosEx in der CodeLib finden ließen ... jedenfalls ist aber im Forum dazu auch noch eine ganze Menge Code zu finden.
Dennoch kommt ihr schonmal eine Ableitung meiner PosEx-Funktion:
Delphi-Quellcode:
Function _PosEx( Const SubStr, S: AnsiString; Offset: LongInt = 1): LongInt;
ASM
PUSH ESI
PUSH EDI
PUSH EBX
TEST &SubStr, &SubStr
JE @Exit
TEST &S, &S
JE @Exit0
TEST &Offset, &Offset
JG @POff
MOV &Offset, 1
@POff:
MOV ESI, &SubStr
MOV EDI, &S
PUSH EDI
MOV EAX, &Offset
DEC EAX
MOV ECX, [EDI - 4]
MOV EDX, [ESI - 4]
DEC EDX
JS @Fail
SUB ECX, EAX
ADD EDI, EAX
MOV AL, [ESI]
INC ESI
SUB ECX, EDX
JLE @Fail
@Loop:
REPNE SCASB
JNE @Fail
MOV EBX, ECX
PUSH ESI
PUSH EDI
MOV ECX, EDX
REPE CMPSB
POP EDI
POP ESI
JE @Found
MOV ECX, EBX
JMP @Loop
@Fail:
POP EDX
@Exit0:
XOR EAX, EAX
JMP @Exit
@Found:
POP EDX
MOV EAX, EDI
SUB EAX, EDX
@Exit:
POP EBX
POP EDI
POP ESI
End;
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
|