Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.188 Beiträge
 
Delphi 12 Athens
 
#3

Re: Dateiname auf Gültigkeit prüfen

  Alt 29. Jul 2005, 05: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;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests