Registriert seit: 21. Jul 2002
Ort: Bonn
5.403 Beiträge
Turbo Delphi für Win32
|
Re: Dateiname auf Gültigkeit prüfen
17. Sep 2005, 14:24
himitsu hat noch folgende Version zusammengebastelt:
Delphi-Quellcode:
Type TCFNameMode = Set of (
cnmDOSCompatible, // Tests for file modifier characters ("+", ";", "=" ...).
cnm8Point3Names, // Tests for short file names (8.3).
cnmQuoteEnabled, // File name may be included into quotation marks (").
cnmErrorLeftChar, // Error on chars to be left out.
cnmContainPath); // File name can contain directory. (only if Directory is '')
Const CFForbiddenChars: Set of AnsiChar = [#0..#31, '"', '*', '/', ':', '<', '>', '?', '\', '|'];
CFForbiddenCharsDOS: Set of AnsiChar = ['+', ';', '=', '[', ']'];
CFForbiddenNames: Array[0..22] 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, i2, i3: Integer;
Quoted: Boolean;
Buffer: Array[1..MAX_PATH] of AnsiChar;
P: PAnsiChar;
S: AnsiString;
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 (cnmContainPath in Mode) and (Directory = '') Then Begin
Directory := ExtractFileDir(FileName);
FileName := ExtractFileName(FileName);
End;
{check directory}
i := Length(ExtractFileDrive(FileName)) + 1;
If Copy(FileName, i, 3) = '..\' Then Inc(i, 3);
If i - 1 <= Length(FileName) Then
Repeat
i2 := PosEx('\', FileName, i);
If i2 = 0 Then i2 := Length(FileName) + 1;
If (i = i2) or
((cnmQuoteEnabled in Mode) and (not Quoted) and (FileName[i] = ' ')) or
((cnmErrorLeftChar in Mode) and (FileName[i2 - 1] in [' ', '.'])) Then Exit;
For i3 := i2 - 1 downto i do
If (FileName[i3] in CFForbiddenChars) or
((cnmDOSCompatible in Mode) and (not Quoted) and (FileName[i3] in CFForbiddenCharsDOS)) or
(((cnm8Point3Names in Mode) or ((cnmQuoteEnabled in Mode) and not Quoted)) and (FileName[i3] = ' ')) Then Exit;
If cnm8Point3Names in Mode Then Begin
i3 := PosEx('.', FileName, i);
If i3 = 0 Then i3 := i2;
If (i3 - i > 8) or (i2 - i - i3 > 3) Then Exit;
i3 := PosEx('.', FileName, i3 + 1);
If (i3 > 0) and (i3 < i2) Then Exit;
End;
S := Copy(LowerCase(FileName), i, i2 - i);
For i3 := High(CFForbiddenNames) downto 0 do If S = CFForbiddenNames[i3] Then Exit;
If i2 > Length(FileName) Then Break;
i := i2;
Until False;
{check fileName}
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;
S := LowerCase(FileName);
For i := High(CFForbiddenNames) downto 0 do If S = 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;
Unter Verwendung von folgender PosEx-Variante(falls die Delphi-Version, die ihr benutzt, kein PosEx mitbringen sollte):
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;
[edit=Dax]Highlighting korrigiert. Mfg, Dax[/edit]
|