+ unicodestring support for assign/erase/rename

+ codepage support for textrec/filerec and the above routines
  * textrec/filerec now store the filename by default using widechar. It is
    possible to switch back to ansichars using the FPC_ANSI_TEXTFILEREC define.
    In that case, from now on the filename will always be stored in
    DefaultFileSystemEncoding
  * fixed potential buffer overflows and non-null-terminated file names in
    textrec/filerec
  + dodirseparators(pwidechar), changed the dodirseparators(pchar/pwidechar)
    parameters into var-parameters and gave those routines an extra parameter
    that indicates whether the p(wide)char can be changed in place if
    necessary or whether a copy must be made first (avoids us having to make
    all strings always unique everywhere, because they might be changed on
    some platforms via a pchar)
  * do_open/do_erase/do_rename got extra boolean parameters indicating whether
    the passed pchars point to data that can be freely changed (to pass on to
    dodirseparators() if applicable)
  * objects.pp: force assign(pchar) to be called, because
    assign(array[0..255]) cannot choose between pchar and rawbytestring
    versions (and removing the pchar version means that assign(pchar) will
    be mapped to assign(shortstring) in {$h-})
  * fixed up some routines in other units that depend on the format of
    the textrec/filerec.name field

git-svn-id: branches/cpstrrtl@25137 -
This commit is contained in:
Jonas Maebe 2013-07-19 16:30:51 +00:00
parent d676bbf9af
commit df6a2dce00
41 changed files with 1042 additions and 333 deletions

View File

@ -725,7 +725,11 @@ var
begin begin
DosError:=0; DosError:=0;
FTime := 0; FTime := 0;
Str := StrPas(filerec(f).name); {$ifdef FPC_ANSI_TEXTFILEREC}
Str := strpas(filerec(f).Name);
{$else}
Str := ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
{$endif}
DoDirSeparators(Str); DoDirSeparators(Str);
FLock := dosLock(Str, SHARED_LOCK); FLock := dosLock(Str, SHARED_LOCK);
IF FLock <> 0 then begin IF FLock <> 0 then begin
@ -756,7 +760,11 @@ end;
FLock: longint; FLock: longint;
Begin Begin
new(DateStamp); new(DateStamp);
Str := StrPas(filerec(f).name); {$ifdef FPC_ANSI_TEXTFILEREC}
Str := strpas(filerec(f).Name);
{$else}
Str := ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
{$endif}
DoDirSeparators(str); DoDirSeparators(str);
{ Check first of all, if file exists } { Check first of all, if file exists }
FLock := dosLock(Str, SHARED_LOCK); FLock := dosLock(Str, SHARED_LOCK);
@ -788,7 +796,11 @@ begin
DosError:=0; DosError:=0;
flags:=0; flags:=0;
New(info); New(info);
Str := StrPas(filerec(f).name); {$ifdef FPC_ANSI_TEXTFILEREC}
Str := strpas(filerec(f).Name);
{$else}
Str := ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
{$endif}
DoDirSeparators(str); DoDirSeparators(str);
{ open with shared lock to check if file exists } { open with shared lock to check if file exists }
MyLock:=dosLock(Str,SHARED_LOCK); MyLock:=dosLock(Str,SHARED_LOCK);
@ -825,7 +837,17 @@ procedure setfattr(var f; attr : word);
var var
flags: longint; flags: longint;
tmpLock : longint; tmpLock : longint;
{$ifndef FPC_ANSI_TEXTFILEREC}
r : rawbytestring;
{$endif not FPC_ANSI_TEXTFILEREC}
p : pchar;
begin begin
{$ifdef FPC_ANSI_TEXTFILEREC}
p := @filerec(f).Name;
{$else}
r := ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
p := pchar(r);
{$endif}
DosError:=0; DosError:=0;
flags:=FIBF_WRITE; flags:=FIBF_WRITE;
@ -836,10 +858,10 @@ begin
{ converts the path (KB) } { converts the path (KB) }
{ create a shared lock on the file } { create a shared lock on the file }
tmpLock:=Lock(filerec(f).name,SHARED_LOCK); tmpLock:=Lock(p,SHARED_LOCK);
if tmpLock <> 0 then begin if tmpLock <> 0 then begin
Unlock(tmpLock); Unlock(tmpLock);
if not SetProtection(filerec(f).name,flags) then DosError:=5; if not SetProtection(p,flags) then DosError:=5;
end else end else
DosError:=3; DosError:=3;
end; end;

View File

@ -170,7 +170,7 @@ begin
end; end;
end; end;
procedure do_erase(p : pchar); procedure do_erase(p : pchar; pchangeable: boolean);
var var
tmpStr: array[0..255] of Char; tmpStr: array[0..255] of Char;
begin begin
@ -180,7 +180,7 @@ begin
dosError2InOut(IoErr); dosError2InOut(IoErr);
end; end;
procedure do_rename(p1,p2 : pchar); procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
{ quite stack-effective code, huh? :) damn path conversions... (KB) } { quite stack-effective code, huh? :) damn path conversions... (KB) }
var var
tmpStr1: array[0..255] of Char; tmpStr1: array[0..255] of Char;
@ -306,7 +306,7 @@ begin
end; end;
end; end;
procedure do_open(var f;p:pchar;flags:longint); procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
{ {
filerec and textrec have both handle and mode as the first items so filerec and textrec have both handle and mode as the first items so
they could use the same routine for opening/creating. they could use the same routine for opening/creating.

View File

@ -27,11 +27,11 @@ begin
end; end;
procedure do_erase(p : pchar); procedure do_erase(p : pchar; pchangeable: boolean);
begin begin
end; end;
procedure do_rename(p1,p2 : pchar); procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
begin begin
end; end;
@ -69,7 +69,7 @@ procedure do_truncate(handle, pos: longint);
begin begin
end; end;
procedure do_open(var f;p:pchar;flags:longint); procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
begin begin
end; end;

View File

@ -944,8 +944,11 @@ var
buffer:array[0..255] of char; buffer:array[0..255] of char;
begin begin
DosError := 0; DosError := 0;
path:=''; {$ifdef FPC_ANSI_TEXTFILEREC}
path := StrPas(filerec(f).Name); path:=filerec(f).Name;
{$else}
path:=ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
{$endif}
{ Takes care of slash and backslash support } { Takes care of slash and backslash support }
path:=FExpand(path); path:=FExpand(path);
move(path[1],buffer,length(path)); move(path[1],buffer,length(path));
@ -974,9 +977,12 @@ var
path: pathstr; path: pathstr;
buffer:array[0..255] of char; buffer:array[0..255] of char;
begin begin
path:='';
DosError := 0; DosError := 0;
path := StrPas(filerec(f).Name); {$ifdef FPC_ANSI_TEXTFILEREC}
path:=filerec(f).Name;
{$else}
path:=ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
{$endif}
{ Takes care of slash and backslash support } { Takes care of slash and backslash support }
path:=FExpand(path); path:=FExpand(path);
move(path[1],buffer,length(path)); move(path[1],buffer,length(path));

View File

@ -40,10 +40,12 @@ begin
end; end;
end; end;
procedure do_erase(p:Pchar); procedure do_erase(p:Pchar; pchangeable: boolean);
var
oldp: pchar;
begin begin
DoDirSeparators(p); oldp:=p;
DoDirSeparators(p,pchangeable);
asm asm
movl P,%edx movl P,%edx
movb $0x41,%ah movb $0x41,%ah
@ -52,13 +54,18 @@ begin
movw %ax,inoutres movw %ax,inoutres
.LERASE1: .LERASE1:
end ['eax', 'edx']; end ['eax', 'edx'];
if p<>oldp then
freemem(p);
end; end;
procedure do_rename(p1,p2:Pchar); procedure do_rename(p1,p2:Pchar; p1changeable, p2changeable: boolean);
var
oldp1, oldp2 : pchar;
begin begin
DoDirSeparators(p1); oldp1:=p1;
DoDirSeparators(p2); oldp2:=p2;
DoDirSeparators(p1,p1changeable);
DoDirSeparators(p2,p2changeable);
asm asm
movl P1, %edx movl P1, %edx
movl P2, %edi movl P2, %edi
@ -68,6 +75,10 @@ begin
movw %ax,inoutres movw %ax,inoutres
.LRENAME1: .LRENAME1:
end ['eax', 'edx', 'edi']; end ['eax', 'edx', 'edi'];
if p1<>oldp1 then
freemem(p1);
if p2<>oldp2 then
freemem(p2);
end; end;
function do_read (H: THandle; Addr: pointer; Len: longint): longint; assembler; function do_read (H: THandle; Addr: pointer; Len: longint): longint; assembler;
@ -254,7 +265,7 @@ begin
end; end;
end; end;
procedure do_open(var f;p:pchar;flags:longint); procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
{ {
filerec and textrec have both handle and mode as the first items so filerec and textrec have both handle and mode as the first items so
@ -264,10 +275,10 @@ procedure do_open(var f;p:pchar;flags:longint);
when (flags and $10000) there is no check for close (needed for textfiles) when (flags and $10000) there is no check for close (needed for textfiles)
} }
var Action: cardinal; var
Action: cardinal;
oldp : pchar;
begin begin
DoDirSeparators(p);
{ close first if opened } { close first if opened }
if ((flags and $10000)=0) then if ((flags and $10000)=0) then
begin begin
@ -309,6 +320,8 @@ begin
end; end;
exit; exit;
end; end;
oldp:=p;
DoDirSeparators(p,pchangeable);
Action := Action or (Flags and $FF); Action := Action or (Flags and $FF);
(* DenyNone if sharing not specified. *) (* DenyNone if sharing not specified. *)
if Flags and 112 = 0 then if Flags and 112 = 0 then
@ -356,6 +369,8 @@ begin
FileRec (F).Mode := fmOutput; {fool fmappend} FileRec (F).Mode := fmOutput; {fool fmappend}
end; end;
end; end;
if oldp<>p then
freemem(p);
end; end;
{$ASMMODE INTEL} {$ASMMODE INTEL}

View File

@ -27,11 +27,11 @@ begin
end; end;
procedure do_erase(p : pchar); procedure do_erase(p : pchar; pchangeable: boolean);
begin begin
end; end;
procedure do_rename(p1,p2 : pchar); procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
begin begin
end; end;
@ -69,7 +69,7 @@ procedure do_truncate(handle, pos: longint);
begin begin
end; end;
procedure do_open(var f;p:pchar;flags:longint); procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
begin begin
end; end;

View File

@ -1083,8 +1083,17 @@ end;
procedure getfattr(var f;var attr : word); procedure getfattr(var f;var attr : word);
{$ifndef FPC_ANSI_TEXTFILEREC}
var
r: rawbytestring;
{$endif not FPC_ANSI_TEXTFILEREC}
begin begin
{$ifdef FPC_ANSI_TEXTFILEREC}
copytodos(filerec(f).name,strlen(filerec(f).name)+1); copytodos(filerec(f).name,strlen(filerec(f).name)+1);
{$else}
r:=ToSingleByteFileSystemEncodedFileName(filerec(f).name);
copytodos(pchar(r)^,length(r)+1);
{$endif}
dosregs.edx:=tb_offset; dosregs.edx:=tb_offset;
dosregs.ds:=tb_segment; dosregs.ds:=tb_segment;
if LFNSupport then if LFNSupport then
@ -1101,6 +1110,10 @@ end;
procedure setfattr(var f;attr : word); procedure setfattr(var f;attr : word);
{$ifndef FPC_ANSI_TEXTFILEREC}
var
r: rawbytestring;
{$endif not FPC_ANSI_TEXTFILEREC}
begin begin
{ Fail for setting VolumeId. } { Fail for setting VolumeId. }
if ((attr and VolumeID)<>0) then if ((attr and VolumeID)<>0) then
@ -1108,7 +1121,12 @@ begin
doserror:=5; doserror:=5;
exit; exit;
end; end;
{$ifdef FPC_ANSI_TEXTFILEREC}
copytodos(filerec(f).name,strlen(filerec(f).name)+1); copytodos(filerec(f).name,strlen(filerec(f).name)+1);
{$else}
r:=ToSingleByteFileSystemEncodedFileName(filerec(f).name);
copytodos(pchar(r)^,length(r)+1);
{$endif}
dosregs.edx:=tb_offset; dosregs.edx:=tb_offset;
dosregs.ds:=tb_segment; dosregs.ds:=tb_segment;
if LFNSupport then if LFNSupport then

View File

@ -54,11 +54,13 @@ begin
end; end;
procedure do_erase(p : pchar); procedure do_erase(p : pchar; pchangeable: boolean);
var var
regs : trealregs; regs : trealregs;
oldp : pchar;
begin begin
DoDirSeparators(p); oldp:=p;
DoDirSeparators(p,pchangeable);
syscopytodos(longint(p),strlen(p)+1); syscopytodos(longint(p),strlen(p)+1);
regs.realedx:=tb_offset; regs.realedx:=tb_offset;
regs.realds:=tb_segment; regs.realds:=tb_segment;
@ -71,15 +73,20 @@ begin
sysrealintr($21,regs); sysrealintr($21,regs);
if (regs.realflags and carryflag) <> 0 then if (regs.realflags and carryflag) <> 0 then
GetInOutRes(lo(regs.realeax)); GetInOutRes(lo(regs.realeax));
if p<>oldp then
freemem(p);
end; end;
procedure do_rename(p1,p2 : pchar); procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
var var
regs : trealregs; regs : trealregs;
oldp1, oldp2 : pchar;
begin begin
DoDirSeparators(p1); oldp1:=p1;
DoDirSeparators(p2); oldp2:=p2;
DoDirSeparators(p1,p1changeable);
DoDirSeparators(p2,p2changeable);
if strlen(p1)+strlen(p2)+3>tb_size then if strlen(p1)+strlen(p2)+3>tb_size then
HandleError(217); HandleError(217);
sysseg_move(get_ds,longint(p2),dos_selector,tb,strlen(p2)+1); sysseg_move(get_ds,longint(p2),dos_selector,tb,strlen(p2)+1);
@ -96,6 +103,10 @@ begin
sysrealintr($21,regs); sysrealintr($21,regs);
if (regs.realflags and carryflag) <> 0 then if (regs.realflags and carryflag) <> 0 then
GetInOutRes(lo(regs.realeax)); GetInOutRes(lo(regs.realeax));
if p1<>oldp1 then
freemem(p1);
if p2<>oldp2 then
freemem(p2);
end; end;
@ -280,7 +291,7 @@ begin
end; end;
procedure do_open(var f;p:pchar;flags:longint); procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
{ {
filerec and textrec have both handle and mode as the first items so filerec and textrec have both handle and mode as the first items so
they could use the same routine for opening/creating. they could use the same routine for opening/creating.
@ -291,8 +302,8 @@ procedure do_open(var f;p:pchar;flags:longint);
var var
regs : trealregs; regs : trealregs;
action : longint; action : longint;
oldp : pchar;
begin begin
DoDirSeparators(p);
{ close first if opened } { close first if opened }
if ((flags and $10000)=0) then if ((flags and $10000)=0) then
begin begin
@ -334,6 +345,8 @@ begin
end; end;
exit; exit;
end; end;
oldp:=p;
DoDirSeparators(p,pchangeable);
{ real dos call } { real dos call }
syscopytodos(longint(p),strlen(p)+1); syscopytodos(longint(p),strlen(p)+1);
{$ifndef RTLLITE} {$ifndef RTLLITE}
@ -385,6 +398,8 @@ begin
if (regs.realflags and carryflag) <> 0 then if (regs.realflags and carryflag) <> 0 then
begin begin
GetInOutRes(lo(regs.realeax)); GetInOutRes(lo(regs.realeax));
if oldp<>p then
freemem(p);
exit; exit;
end end
else else
@ -419,6 +434,8 @@ begin
do_seekend(filerec(f).handle); do_seekend(filerec(f).handle);
filerec(f).mode:=fmoutput; {fool fmappend} filerec(f).mode:=fmoutput; {fool fmappend}
end; end;
if oldp<>p then
freemem(p);
end; end;

View File

@ -18,35 +18,85 @@
type type
UnTypedFile=File; UnTypedFile=File;
Procedure Assign(out f:File;const Name:string); procedure InitFile(var f : file);
begin
FillChar(f,SizeOf(FileRec),0);
FileRec(f).Handle:=UnusedHandle;
FileRec(f).mode:=fmClosed;
end;
{$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
Procedure Assign(out f:File;const Name: UnicodeString);
{ {
Assign Name to file f so it can be used with the file routines Assign Name to file f so it can be used with the file routines
} }
Begin Begin
FillChar(f,SizeOf(FileRec),0); InitFile(F);
FileRec(f).Handle:=UnusedHandle; {$ifdef FPC_ANSI_TEXTFILEREC}
FileRec(f).mode:=fmClosed; FileRec(f).Name:=ToSingleByteFileSystemEncodedFileName(Name);
Move(Name[1],FileRec(f).Name,Length(Name)); {$else FPC_ANSI_TEXTFILEREC}
FileRec(f).Name:=Name;
{$endif FPC_ANSI_TEXTFILEREC}
{ null terminate, since the name array is regularly used as p(wide)char }
FileRec(f).Name[high(FileRec(f).Name)]:=#0;
End;
{$endif FPC_HAS_FEATURE_WIDESTRINGS}
{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
Procedure Assign(out f:File;const Name: RawByteString);
{
Assign Name to file f so it can be used with the file routines
}
Begin
InitFile(F);
{$ifdef FPC_ANSI_TEXTFILEREC}
{ ensure the characters in the record's filename are encoded correctly }
FileRec(f).Name:=ToSingleByteFileSystemEncodedFileName(Name);
{$else FPC_ANSI_TEXTFILEREC}
FileRec(f).Name:=Name;
{$endif FPC_ANSI_TEXTFILEREC}
{ null terminate, since the name array is regularly used as p(wide)char }
FileRec(f).Name[high(FileRec(f).Name)]:=#0;
End;
{$endif FPC_HAS_FEATURE_ANSISTRINGS}
Procedure Assign(out f:File;const Name: ShortString);
{
Assign Name to file f so it can be used with the file routines
}
Begin
{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
Assign(f,AnsiString(Name));
{$else FPC_HAS_FEATURE_ANSISTRINGS}
InitFile(f);
{ warning: no encoding support }
FileRec(f).Name:=Name;
{ null terminate, since the name array is regularly used as p(wide)char }
FileRec(f).Name[high(FileRec(f).Name)]:=#0;
{$endif FPC_HAS_FEATURE_ANSISTRINGS}
End; End;
Procedure Assign(out f:File;const p: PAnsiChar);
Begin
{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
Assign(f,AnsiString(p));
{$else FPC_HAS_FEATURE_ANSISTRINGS}
{ no use in making this the one that does the work, since the name field is
limited to 255 characters anyway }
Assign(f,strpas(p));
{$endif FPC_HAS_FEATURE_ANSISTRINGS}
End;
Procedure Assign(out f:File;p:pchar); Procedure Assign(out f:File;const c: AnsiChar);
{ Begin
Assign Name to file f so it can be used with the file routines {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
} Assign(f,AnsiString(c));
begin {$else FPC_HAS_FEATURE_ANSISTRINGS}
Assign(f,StrPas(p)); Assign(f,ShortString(c));
end; {$endif FPC_HAS_FEATURE_ANSISTRINGS}
End;
Procedure Assign(out f:File;c:char);
{
Assign Name to file f so it can be used with the file routines
}
begin
Assign(f,string(c));
end;
Procedure Rewrite(var f:File;l:Longint);[IOCheck]; Procedure Rewrite(var f:File;l:Longint);[IOCheck];
{ {
@ -69,7 +119,7 @@ Begin
else else
Begin Begin
{ Reopen with filemode 2, to be Tp compatible (PFV) } { Reopen with filemode 2, to be Tp compatible (PFV) }
Do_Open(f,PChar(@FileRec(f).Name),$1002); Do_Open(f,PFileTextRecChar(@FileRec(f).Name),$1002,false);
FileRec(f).RecSize:=l; FileRec(f).RecSize:=l;
End; End;
End; End;
@ -95,7 +145,7 @@ Begin
InOutRes:=2 InOutRes:=2
else else
Begin Begin
Do_Open(f,PChar(@FileRec(f).Name),Filemode); Do_Open(f,PFileTextRecChar(@FileRec(f).Name),Filemode,false);
FileRec(f).RecSize:=l; FileRec(f).RecSize:=l;
End; End;
End; End;
@ -383,44 +433,134 @@ Begin
If InOutRes <> 0 then If InOutRes <> 0 then
exit; exit;
If FileRec(f).mode=fmClosed Then If FileRec(f).mode=fmClosed Then
Do_Erase(PChar(@FileRec(f).Name)); Do_Erase(PFileTextRecChar(@FileRec(f).Name),false);
End; End;
Procedure Rename(var f : File;p:pchar);[IOCheck]; Procedure Rename(var f : File; const S : UnicodeString);[IOCheck];
{$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
var
fs: RawByteString;
{$endif FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
Begin Begin
If InOutRes <> 0 then If (InOutRes<>0) or
exit; (FileRec(f).mode<>fmClosed) then
If FileRec(f).mode=fmClosed Then exit;
Begin {$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
Do_Rename(PChar(@FileRec(f).Name),p); { it's slightly faster to convert the unicodestring here to rawbytestring
{ check error code of do_rename } than doing it in do_rename(), because here we still know the length }
If InOutRes = 0 then fs:=ToSingleByteFileSystemEncodedFileName(s);
Move(p^,FileRec(f).Name,StrLen(p)+1); Do_Rename(PFileTextRecChar(@FileRec(f).Name),PAnsiChar(fs),false,true);
End; If InOutRes=0 then
FileRec(f).Name:=fs
{$else FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
Do_Rename(PFileTextRecChar(@FileRec(f).Name),PUnicodeChar(S),false,false);
If InOutRes=0 then
{$ifdef FPC_ANSI_TEXTFILEREC}
FileRec(f).Name:=ToSingleByteFileSystemEncodedFileName(s);
{$else FPC_ANSI_TEXTFILEREC}
FileRec(f).Name:=s
{$endif FPC_ANSI_TEXTFILEREC}
{$endif FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
End; End;
Procedure Rename(var f : File;const s : string);[IOCheck]; Procedure Rename(var f : File;const s : RawByteString);[IOCheck];
var
{$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
fs: RawByteString;
pdst: PAnsiChar;
{$else FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
fs: UnicodeString;
pdst: PUnicodeChar;
{$endif FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
dstchangeable: boolean;
Begin
If (InOutRes<>0) or
(FileRec(f).mode<>fmClosed) then
exit;
{$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
dstchangeable:=false;
pdst:=PAnsiChar(s);
if StringCodePage(s)<>DefaultFileSystemCodePage then
begin
fs:=ToSingleByteFileSystemEncodedFileName(s);
pdst:=PAnsiChar(fs);
dstchangeable:=true;
end
else
fs:=s;
{$else FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
{ it's slightly faster to convert the rawbytestring here to unicodestring
than doing it in do_rename, because here we still know the length }
fs:=unicodestring(s);
pdst:=PUnicodeChar(fs);
dstchangeable:=true;
{$endif FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
Do_Rename(PFileTextRecChar(@FileRec(f).Name),pdst,false,dstchangeable);
If InOutRes=0 then
{$if defined(FPC_ANSI_TEXTFILEREC) and not defined(FPCRTL_FILESYSTEM_SINGLE_BYTE_API)}
FileRec(f).Name:=ToSingleByteFileSystemEncodedFileName(fs)
{$else FPC_ANSI_TEXTFILEREC and not FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
FileRec(f).Name:=fs
{$endif FPC_ANSI_TEXTFILEREC and not FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
End;
Procedure Rename(var f : File;const s : ShortString);[IOCheck];
{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
Begin
Rename(f,AnsiString(s));
End;
{$else FPC_HAS_FEATURE_ANSISTRINGS}
var var
p : array[0..255] Of Char; p : array[0..255] Of Char;
Begin Begin
If InOutRes <> 0 then
exit;
Move(s[1],p,Length(s)); Move(s[1],p,Length(s));
p[Length(s)]:=#0; p[Length(s)]:=#0;
Rename(f,Pchar(@p)); Rename(f,Pchar(@p));
End; End;
{$endif FPC_HAS_FEATURE_ANSISTRINGS}
Procedure Rename(var f : File;c : char);[IOCheck]; Procedure Rename(var f:File;const p : PAnsiChar);[IOCheck];
var {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
p : array[0..1] Of Char; Begin
Rename(f,AnsiString(p));
End;
{$else FPC_HAS_FEATURE_ANSISTRINGS}
var
len: SizeInt
Begin
If InOutRes<>0 then
exit;
If FileRec(f).mode=fmClosed Then
Begin
Do_Rename(PFileTextRecChar(@FileRec(f).Name),p,false);
{ check error code of do_rename }
If InOutRes=0 then
begin
len:=min(StrLen(p),high(FileRec(f).Name));
Move(p^,FileRec(f).Name,len);
FileRec(f).Name[len]:=#0;
end;
End;
End;
{$endif FPC_HAS_FEATURE_ANSISTRINGS}
Procedure Rename(var f:File;const c : AnsiChar);[IOCheck];
{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
Begin
Rename(f,AnsiString(c));
End;
{$else FPC_HAS_FEATURE_ANSISTRINGS}
var
p : array[0..1] Of AnsiChar;
Begin Begin
If InOutRes <> 0 then
exit;
p[0]:=c; p[0]:=c;
p[1]:=#0; p[1]:=#0;
Rename(f,Pchar(@p)); Rename(f,PAnsiChar(@p));
End; End;
{$endif FPC_HAS_FEATURE_ANSISTRINGS}

View File

@ -35,6 +35,6 @@ type
RecSize : SizeInt; RecSize : SizeInt;
_private : array[1..3 * SizeOf(SizeInt) + 5 * SizeOf (pointer)] of byte; _private : array[1..3 * SizeOf(SizeInt) + 5 * SizeOf (pointer)] of byte;
UserData : array[1..32] of byte; UserData : array[1..32] of byte;
name : array[0..filerecnamelength] of char; name : array[0..filerecnamelength] of TFileTextRecChar;
End; End;

View File

@ -1389,7 +1389,7 @@ BEGIN
Begin { Check status okay } Begin { Check status okay }
If (Handle = InvalidHandle) Then If (Handle = InvalidHandle) Then
Begin { File not open } Begin { File not open }
Assign(FileInfo,FName); Assign(FileInfo,@FName);
{ Handle the mode } { Handle the mode }
if OpenMode =stCreate then if OpenMode =stCreate then
Begin Begin

View File

@ -1416,13 +1416,49 @@ end;
{$ifdef FPC_HAS_FEATURE_FILEIO} {$ifdef FPC_HAS_FEATURE_FILEIO}
{ Allow slash and backslash as separators } { Allow slash and backslash as separators }
procedure DoDirSeparators(p:Pchar); procedure DoDirSeparators(var p: pchar; inplace: boolean = true);
var var
i : longint; i : longint;
len : sizeint;
newp : pchar;
begin begin
for i:=0 to strlen(p) do len:=length(p);
newp:=nil;
for i:=0 to len do
if p[i] in AllowDirectorySeparators then if p[i] in AllowDirectorySeparators then
p[i]:=DirectorySeparator; begin
if not inplace and
not assigned(newp) then
begin
getmem(newp,len+1);
move(p^,newp^,len+1);
p:=newp;
end;
p[i]:=DirectorySeparator;
end;
end;
procedure DoDirSeparators(var p: pwidechar; inplace: boolean = true);
var
i : longint;
len : sizeint;
newp : pwidechar;
begin
len:=length(p);
newp:=nil;
for i:=0 to len do
if (ord(p[i])<255) and
(ansichar(ord(p[i])) in AllowDirectorySeparators) then
begin
if not inplace and
not assigned(newp) then
begin
getmem(newp,(len+1)*2);
move(p^,newp^,(len+1)*2);
p:=newp;
end;
p[i]:=DirectorySeparator;
end;
end; end;
procedure DoDirSeparators(var p:shortstring); procedure DoDirSeparators(var p:shortstring);
@ -1480,6 +1516,82 @@ end;
{ OS dependent low level file functions } { OS dependent low level file functions }
{$ifdef FPC_HAS_FEATURE_FILEIO} {$ifdef FPC_HAS_FEATURE_FILEIO}
{$i sysfile.inc} {$i sysfile.inc}
{$ifndef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
{$ifdef FPC_ANSI_TEXTFILEREC}
procedure do_open(var f; p: pansichar; flags: longint; pchangeable: boolean);
var
u: UnicodeString;
begin
widestringmanager.Ansi2UnicodeMoveProc(p,DefaultFileSystemCodePage,u,length(p));
do_open(f,pwidechar(u),flags,true);
end;
procedure do_erase(p: pansichar; pchangeable: boolean);
var
u: UnicodeString;
begin
widestringmanager.Ansi2UnicodeMoveProc(p,DefaultFileSystemCodePage,u,length(p));
do_erase(pwidechar(u),true);
end;
procedure do_rename(src, dst: pansichar; srcchangeable, dstchangeable: boolean);
var
usrc, udst: UnicodeString;
begin
widestringmanager.Ansi2UnicodeMoveProc(src,DefaultFileSystemCodePage,usrc,length(src));
widestringmanager.Ansi2UnicodeMoveProc(dst,DefaultFileSystemCodePage,udst,length(dst));
do_rename(pwidechar(usrc),pwidechar(udst),true,true);
end;
procedure do_rename(src: pansichar; dst: pwidechar; srcchangeable, dstchangeable: boolean);
var
usrc: UnicodeString;
begin
widestringmanager.Ansi2UnicodeMoveProc(src,DefaultFileSystemCodePage,usrc,length(src));
do_rename(pwidechar(usrc),dst,true,dstchangeable);
end;
{$endif FPC_ANSI_TEXTFILEREC}
{$endif not FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
{$ifndef FPCRTL_FILESYSTEM_TWO_BYTE_API}
{$ifndef FPC_ANSI_TEXTFILEREC}
procedure do_open(var f; p: pwidechar; flags: longint; pchangeable: boolean);
var
s: RawByteString;
begin
widestringmanager.Unicode2AnsiMoveProc(p,s,DefaultFileSystemCodePage,length(p));
do_open(f,pansichar(s),flags,true);
end;
procedure do_erase(p: pwidechar; pchangeable: boolean);
var
s: RawByteString;
begin
widestringmanager.Unicode2AnsiMoveProc(p,s,DefaultFileSystemCodePage,length(p));
do_erase(pansichar(s),true);
end;
procedure do_rename(src, dst: pwidechar; srcchangeable, dstchangeable: boolean);
var
rsrc, rdst: RawByteString;
begin
widestringmanager.Unicode2AnsiMoveProc(src,rsrc,DefaultFileSystemCodePage,length(src));
widestringmanager.Unicode2AnsiMoveProc(dst,rdst,DefaultFileSystemCodePage,length(dst));
do_rename(pansichar(rsrc),pansichar(rdst),true,true);
end;
procedure do_rename(src: pwidechar; dst: pansichar; srcchangeable, dstchangeable: boolean);
var
rsrc: RawByteString;
begin
widestringmanager.Unicode2AnsiMoveProc(src,rsrc,DefaultFileSystemCodePage,length(src));
do_rename(pansichar(rsrc),dst,true,dstchangeable);
end;
{$endif not FPC_ANSI_TEXTFILEREC}
{$endif not FPCRTL_FILESYSTEM_TWO_BYTE_API}
{$endif FPC_HAS_FEATURE_FILEIO} {$endif FPC_HAS_FEATURE_FILEIO}
{ Text file } { Text file }

View File

@ -495,6 +495,12 @@ Type
TSystemCodePage = Word; TSystemCodePage = Word;
{$ifdef VER2_6}
{ the size of textrec/filerec is hardcoded in the 2.6 compiler binary }
{$define FPC_ANSI_TEXTFILEREC}
{$endif}
TFileTextRecChar = {$ifdef FPC_ANSI_TEXTFILEREC}AnsiChar{$else}UnicodeChar{$endif};
PFileTextRecChar = ^TFileTextRecChar;
TTextLineBreakStyle = (tlbsLF,tlbsCRLF,tlbsCR); TTextLineBreakStyle = (tlbsLF,tlbsCRLF,tlbsCR);
@ -1098,9 +1104,20 @@ procedure SetMultiByteRTLFileSystemCodePage(CodePage: TSystemCodePage);
****************************************************************************} ****************************************************************************}
{$ifdef FPC_HAS_FEATURE_FILEIO} {$ifdef FPC_HAS_FEATURE_FILEIO}
Procedure Assign(out f:File;const Name:string); Procedure Assign(out f:File;const Name: ShortString);
Procedure Assign(out f:File;p:pchar); Procedure Assign(out f:File;const p: PAnsiChar);
Procedure Assign(out f:File;c:char); Procedure Assign(out f:File;const c: AnsiChar);
Procedure Rename(var f:File;const s : ShortString);
Procedure Rename(var f:File;const p : PAnsiChar);
Procedure Rename(var f:File;const c : AnsiChar);
{$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
Procedure Assign(out f:File;const Name: UnicodeString);
Procedure Rename(var f:File;const s : UnicodeString);
{$endif FPC_HAS_FEATURE_WIDESTRINGS}
{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
Procedure Assign(out f:File;const Name: RawByteString);
Procedure Rename(var f:File;const s : RawByteString);
{$endif FPC_HAS_FEATURE_ANSISTRINGS}
Procedure Rewrite(var f:File;l:Longint); Procedure Rewrite(var f:File;l:Longint);
Procedure Rewrite(var f:File); Procedure Rewrite(var f:File);
Procedure Reset(var f:File;l:Longint); Procedure Reset(var f:File;l:Longint);
@ -1123,9 +1140,6 @@ Function FileSize(var f:File):Int64;
Procedure Seek(var f:File;Pos:Int64); Procedure Seek(var f:File;Pos:Int64);
Function EOF(var f:File):Boolean; Function EOF(var f:File):Boolean;
Procedure Erase(var f:File); Procedure Erase(var f:File);
Procedure Rename(var f:File;const s:string);
Procedure Rename(var f:File;p:pchar);
Procedure Rename(var f:File;c:char);
Procedure Truncate (var F:File); Procedure Truncate (var F:File);
{$endif FPC_HAS_FEATURE_FILEIO} {$endif FPC_HAS_FEATURE_FILEIO}
@ -1135,9 +1149,15 @@ Procedure Truncate (var F:File);
****************************************************************************} ****************************************************************************}
{$ifdef FPC_HAS_FEATURE_FILEIO} {$ifdef FPC_HAS_FEATURE_FILEIO}
Procedure Assign(out f:TypedFile;const Name:string); Procedure Assign(out f:TypedFile;const Name:shortstring);
Procedure Assign(out f:TypedFile;p:pchar); Procedure Assign(out f:TypedFile;const p:PAnsiChar);
Procedure Assign(out f:TypedFile;c:char); Procedure Assign(out f:TypedFile;const c:AnsiChar);
{$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
Procedure Assign(out f:TypedFile;const Name:unicodestring);
{$endif FPC_HAS_FEATURE_WIDESTRINGS}
{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
Procedure Assign(out f:TypedFile;const Name:rawbytestring);
{$endif FPC_HAS_FEATURE_ANSISTRINGS}
Procedure Reset(var f : TypedFile); [INTERNPROC: fpc_in_Reset_TypedFile]; Procedure Reset(var f : TypedFile); [INTERNPROC: fpc_in_Reset_TypedFile];
Procedure Rewrite(var f : TypedFile); [INTERNPROC: fpc_in_Rewrite_TypedFile]; Procedure Rewrite(var f : TypedFile); [INTERNPROC: fpc_in_Rewrite_TypedFile];
{$endif FPC_HAS_FEATURE_FILEIO} {$endif FPC_HAS_FEATURE_FILEIO}
@ -1147,18 +1167,26 @@ Procedure Rewrite(var f : TypedFile); [INTERNPROC: fpc_in_Rewrite_TypedFile];
****************************************************************************} ****************************************************************************}
{$ifdef FPC_HAS_FEATURE_TEXTIO} {$ifdef FPC_HAS_FEATURE_TEXTIO}
Procedure Assign(out t:Text;const s:string); Procedure Assign(out t:Text;const s:shortstring);
Procedure Assign(out t:Text;p:pchar); Procedure Rename(var t:Text;const s:shortstring);
Procedure Assign(out t:Text;c:char); Procedure Assign(out t:Text;const p:PAnsiChar);
Procedure Rename(var t:Text;const p:PAnsiChar);
Procedure Assign(out t:Text;const c:AnsiChar);
Procedure Rename(var t:Text;const c:AnsiChar);
{$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
Procedure Assign(out t:Text;const s:unicodestring);
Procedure Rename(var t:Text;const s:unicodestring);
{$endif FPC_HAS_FEATURE_WIDESTRINGS}
{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
Procedure Rename(var t:Text;const s:rawbytestring);
Procedure Assign(out t:Text;const s:rawbytestring);
{$endif FPC_HAS_FEATURE_ANSISTRINGS}
Procedure Close(var t:Text); Procedure Close(var t:Text);
Procedure Rewrite(var t:Text); Procedure Rewrite(var t:Text);
Procedure Reset(var t:Text); Procedure Reset(var t:Text);
Procedure Append(var t:Text); Procedure Append(var t:Text);
Procedure Flush(var t:Text); Procedure Flush(var t:Text);
Procedure Erase(var t:Text); Procedure Erase(var t:Text);
Procedure Rename(var t:Text;const s:string);
Procedure Rename(var t:Text;p:pchar);
Procedure Rename(var t:Text;c:char);
Function EOF(var t:Text):Boolean; Function EOF(var t:Text):Boolean;
Function EOF:Boolean; Function EOF:Boolean;
Function EOLn(var t:Text):Boolean; Function EOLn(var t:Text):Boolean;

View File

@ -57,7 +57,7 @@ Begin
exit; exit;
end; end;
End; End;
Do_Open(t,PChar(@t.Name),Flags); Do_Open(t,PFileTextRecChar(@t.Name),Flags,False);
t.CloseFunc:=@FileCloseFunc; t.CloseFunc:=@FileCloseFunc;
t.FlushFunc:=nil; t.FlushFunc:=nil;
if t.Mode=fmInput then if t.Mode=fmInput then
@ -74,9 +74,9 @@ Begin
end; end;
End; End;
Procedure InitText(Var t : Text);
Procedure Assign(out t:Text;const s:String); begin
Begin
FillChar(t,SizeOf(TextRec),0); FillChar(t,SizeOf(TextRec),0);
{ only set things that are not zero } { only set things that are not zero }
TextRec(t).Handle:=UnusedHandle; TextRec(t).Handle:=UnusedHandle;
@ -89,20 +89,74 @@ Begin
tlbsCRLF: TextRec(t).LineEnd := #13#10; tlbsCRLF: TextRec(t).LineEnd := #13#10;
tlbsCR: TextRec(t).LineEnd := #13; tlbsCR: TextRec(t).LineEnd := #13;
End; End;
Move(s[1],TextRec(t).Name,Length(s)); end;
{$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
Procedure Assign(out t:Text;const s : UnicodeString);
begin
InitText(t);
{$ifdef FPC_ANSI_TEXTFILEREC}
TextRec(t).Name:=ToSingleByteFileSystemEncodedFileName(S);
{$else FPC_ANSI_TEXTFILEREC}
TextRec(t).Name:=S;
{$endif FPC_ANSI_TEXTFILEREC}
{ null terminate, since the name array is regularly used as p(wide)char }
TextRec(t).Name[high(TextRec(t).Name)]:=#0;
end;
{$endif FPC_HAS_FEATURE_WIDESTRINGS}
{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
Procedure Assign(out t:Text;const s: RawByteString);
Begin
InitText(t);
{$ifdef FPC_ANSI_TEXTFILEREC}
{ ensure the characters in the record's filename are encoded correctly }
TextRec(t).Name:=ToSingleByteFileSystemEncodedFileName(S);
{$else FPC_ANSI_TEXTFILEREC}
TextRec(t).Name:=S;
{$endif FPC_ANSI_TEXTFILEREC}
{ null terminate, since the name array is regularly used as p(wide)char }
TextRec(t).Name[high(TextRec(t).Name)]:=#0;
End;
{$endif FPC_HAS_FEATURE_ANSISTRINGS}
Procedure Assign(out t:Text;const s: ShortString);
Begin
{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
Assign(t,AnsiString(s));
{$else FPC_HAS_FEATURE_ANSISTRINGS}
InitText(t);
{ warning: no encoding support }
TextRec(t).Name:=s;
{ null terminate, since the name array is regularly used as p(wide)char }
TextRec(t).Name[high(TextRec(t).Name)]:=#0;
{$endif FPC_HAS_FEATURE_ANSISTRINGS}
End; End;
Procedure Assign(out t:Text;p:pchar); Procedure Assign(out t:Text;const p: PAnsiChar);
begin Begin
Assign(t,StrPas(p)); {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
end; Assign(t,AnsiString(p));
{$else FPC_HAS_FEATURE_ANSISTRINGS}
{ no use in making this the one that does the work, since the name field is
limited to 255 characters anyway }
Assign(t,strpas(p));
{$endif FPC_HAS_FEATURE_ANSISTRINGS}
End;
Procedure Assign(out t:Text;c:char); Procedure Assign(out t:Text;const c: AnsiChar);
begin Begin
Assign(t,string(c)); {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
end; Assign(t,AnsiString(c));
{$else FPC_HAS_FEATURE_ANSISTRINGS}
Assign(t,ShortString(c));
{$endif FPC_HAS_FEATURE_ANSISTRINGS}
End;
Procedure Close(var t : Text);[IOCheck]; Procedure Close(var t : Text);[IOCheck];
@ -204,47 +258,134 @@ Begin
If InOutRes <> 0 then If InOutRes <> 0 then
exit; exit;
If TextRec(t).mode=fmClosed Then If TextRec(t).mode=fmClosed Then
Do_Erase(PChar(@TextRec(t).Name)); Do_Erase(PFileTextRecChar(@TextRec(t).Name),false);
End; End;
Procedure Rename(var t : text;p:pchar);[IOCheck]; Procedure Rename(var t : Text;const s : unicodestring);[IOCheck];
{$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
var
fs: RawByteString;
{$endif FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
Begin Begin
If InOutRes <> 0 then If (InOutRes<>0) or
exit; (TextRec(t).mode<>fmClosed) then
If TextRec(t).mode=fmClosed Then exit;
Begin {$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
Do_Rename(PChar(@TextRec(t).Name),p); { it's slightly faster to convert the unicodestring here to rawbytestring
{ check error code of do_rename } than doing it in do_rename(), because here we still know the length }
If InOutRes = 0 then fs:=ToSingleByteFileSystemEncodedFileName(s);
Move(p^,TextRec(t).Name,StrLen(p)+1); Do_Rename(PFileTextRecChar(@TextRec(t).Name),PAnsiChar(fs),false,true);
End; If InOutRes=0 then
TextRec(t).Name:=fs
{$else FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
Do_Rename(PFileTextRecChar(@TextRec(t).Name),PUnicodeChar(S),false,false);
If InOutRes=0 then
{$ifdef FPC_ANSI_TEXTTextRec}
TextRec(t).Name:=ToSingleByteFileSystemEncodedFileName(s);
{$else FPC_ANSI_TEXTFILEREC}
TextRec(t).Name:=s
{$endif FPC_ANSI_TEXTFILEREC}
{$endif FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
End; End;
Procedure Rename(var t : Text;const s : string);[IOCheck]; Procedure Rename(var t : Text;const s : rawbytestring);[IOCheck];
var
{$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
fs: RawByteString;
pdst: PAnsiChar;
{$else FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
fs: UnicodeString;
pdst: PUnicodeChar;
{$endif FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
dstchangeable: boolean;
Begin
If (InOutRes<>0) or
(TextRec(t).mode<>fmClosed) then
exit;
{$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
dstchangeable:=false;
pdst:=PAnsiChar(s);
if StringCodePage(s)<>DefaultFileSystemCodePage then
begin
fs:=ToSingleByteFileSystemEncodedFileName(s);
pdst:=PAnsiChar(fs);
dstchangeable:=true;
end
else
fs:=s;
{$else FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
{ it's slightly faster to convert the rawbytestring here to unicodestring
than doing it in do_rename, because here we still know the length }
fs:=unicodestring(s);
pdst:=PUnicodeChar(fs);
dstchangeable:=true;
{$endif FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
Do_Rename(PFileTextRecChar(@TextRec(t).Name),pdst,false,dstchangeable);
If InOutRes=0 then
{$if defined(FPC_ANSI_TEXTTextRec) and not defined(FPCRTL_FILESYSTEM_SINGLE_BYTE_API)}
TextRec(t).Name:=ToSingleByteFileSystemEncodedFileName(fs)
{$else FPC_ANSI_TEXTTextRec and not FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
TextRec(t).Name:=fs
{$endif FPC_ANSI_TEXTTextRec and not FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
End;
Procedure Rename(var t : Text;const s : ShortString);[IOCheck];
{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
Begin
Rename(t,AnsiString(s));
End;
{$else FPC_HAS_FEATURE_ANSISTRINGS}
var var
p : array[0..255] Of Char; p : array[0..255] Of Char;
Begin Begin
If InOutRes <> 0 then
exit;
Move(s[1],p,Length(s)); Move(s[1],p,Length(s));
p[Length(s)]:=#0; p[Length(s)]:=#0;
Rename(t,Pchar(@p)); Rename(t,Pchar(@p));
End; End;
{$endif FPC_HAS_FEATURE_ANSISTRINGS}
Procedure Rename(var t:Text;const p:PAnsiChar);
Procedure Rename(var t : Text;c : char);[IOCheck]; {$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
var Begin
p : array[0..1] Of Char; Rename(t,AnsiString(p));
End;
{$else FPC_HAS_FEATURE_ANSISTRINGS}
var
len: SizeInt
Begin
If InOutRes<>0 then
exit;
If TextRec(t).mode=fmClosed Then
Begin
Do_Rename(PFileTextRecChar(@TextRec(t).Name),p,false);
{ check error code of do_rename }
If InOutRes=0 then
begin
len:=min(StrLen(p),high(TextRec(t).Name));
Move(p^,TextRec(t).Name,len);
TextRec(t).Name[len]:=#0;
end;
End;
End;
{$endif FPC_HAS_FEATURE_ANSISTRINGS}
Procedure Rename(var t : Text;const c : AnsiChar);[IOCheck];
{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
Begin
Rename(t,AnsiString(c));
End;
{$else FPC_HAS_FEATURE_ANSISTRINGS}
var
p : array[0..1] Of AnsiChar;
Begin Begin
If InOutRes <> 0 then
exit;
p[0]:=c; p[0]:=c;
p[1]:=#0; p[1]:=#0;
Rename(t,Pchar(@p)); Rename(t,PAnsiChar(@p));
End; End;
{$endif FPC_HAS_FEATURE_ANSISTRINGS}
Function Eof(Var t: Text): Boolean;[IOCheck]; Function Eof(Var t: Text): Boolean;[IOCheck];
Begin Begin

View File

@ -29,7 +29,7 @@ const
{$endif CPUAVR} {$endif CPUAVR}
type type
TLineEndStr = string [3]; TLineEndStr = string [3];
TextBuf = array[0..TextRecBufSize-1] of char; TextBuf = array[0..TextRecBufSize-1] of ansichar;
{ using packed makes the compiler to generate ugly code on some CPUs, further { using packed makes the compiler to generate ugly code on some CPUs, further
using packed causes the compiler to handle arrays of text wrongly, see see tw0754 e.g. on arm } using packed causes the compiler to handle arrays of text wrongly, see see tw0754 e.g. on arm }
TextRec = {$ifdef VER2_6} packed {$endif} Record TextRec = {$ifdef VER2_6} packed {$endif} Record
@ -45,7 +45,7 @@ type
flushfunc, flushfunc,
closefunc : codepointer; closefunc : codepointer;
UserData : array[1..32] of byte; UserData : array[1..32] of byte;
name : array[0..textrecnamelength-1] of char; name : array[0..textrecnamelength-1] of TFileTextRecChar;
LineEnd : TLineEndStr; LineEnd : TLineEndStr;
buffer : textbuf; buffer : textbuf;
{$ifdef FPC_HAS_CPSTRING} {$ifdef FPC_HAS_CPSTRING}

View File

@ -15,48 +15,56 @@
subroutines for typed file handling subroutines for typed file handling
****************************************************************************} ****************************************************************************}
Procedure Assign(out f:TypedFile;const Name:string); {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
Procedure Assign(out f:TypedFile;const Name: UnicodeString);
{ {
Assign Name to file f so it can be used with the file routines Assign Name to file f so it can be used with the file routines
} }
Begin Begin
FillChar(f,SizeOF(FileRec),0); Assign(UnTypedFile(f),Name);
FileRec(f).Handle:=UnusedHandle; End;
FileRec(f).mode:=fmClosed; {$endif FPC_HAS_FEATURE_WIDESTRINGS}
Move(Name[1],FileRec(f).Name,Length(Name));
{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
Procedure Assign(out f:TypedFile;const Name: RawByteString);
{
Assign Name to file f so it can be used with the file routines
}
Begin
Assign(UnTypedFile(f),Name);
End;
{$endif FPC_HAS_FEATURE_ANSISTRINGS}
Procedure Assign(out f:TypedFile;const Name: ShortString);
{
Assign Name to file f so it can be used with the file routines
}
Begin
Assign(UnTypedFile(f),Name);
End; End;
Procedure Assign(out f:TypedFile;p:pchar); Procedure Assign(out f:TypedFile;const p:PAnsiChar);
{ Begin
Assign Name to file f so it can be used with the file routines Assign(UnTypedFile(f),p);
}
begin
Assign(f,StrPas(p));
end; end;
Procedure Assign(out f:TypedFile;c:char); Procedure Assign(out f:TypedFile;const c:AnsiChar);
{ Begin
Assign Name to file f so it can be used with the file routines Assign(UnTypedFile(f),c);
}
begin
Assign(f,string(c));
end; end;
Procedure fpc_reset_typed(var f : TypedFile;Size : Longint);[Public,IOCheck, Alias:'FPC_RESET_TYPED']; compilerproc; Procedure fpc_reset_typed(var f : TypedFile;Size : Longint);[Public,IOCheck, Alias:'FPC_RESET_TYPED']; compilerproc;
Begin Begin
If InOutRes <> 0 then
exit;
Reset(UnTypedFile(f),Size); Reset(UnTypedFile(f),Size);
End; End;
Procedure fpc_rewrite_typed(var f : TypedFile;Size : Longint);[Public,IOCheck, Alias:'FPC_REWRITE_TYPED']; compilerproc; Procedure fpc_rewrite_typed(var f : TypedFile;Size : Longint);[Public,IOCheck, Alias:'FPC_REWRITE_TYPED']; compilerproc;
Begin Begin
If InOutRes <> 0 then
exit;
Rewrite(UnTypedFile(f),Size); Rewrite(UnTypedFile(f),Size);
End; End;

View File

@ -803,7 +803,11 @@ End;
paramBlock: CInfoPBRec; paramBlock: CInfoPBRec;
begin begin
DosError := PathArgToFSSpec(StrPas(filerec(f).name), spec); {$ifdef FPC_ANSI_TEXTFILEREC}
DosError := PathArgToFSSpec(filerec(f).name, spec);
{$else}
DosError := PathArgToFSSpec(ToSingleByteFileSystemEncodedFileName(filerec(f).name), spec);
{$endif}
if (DosError = 0) or (DosError = 2) then if (DosError = 0) or (DosError = 2) then
begin begin
DosError := DoFindOne(spec, paramBlock); DosError := DoFindOne(spec, paramBlock);
@ -822,7 +826,11 @@ End;
macfiletime: UInt32; macfiletime: UInt32;
begin begin
DosError := PathArgToFSSpec(StrPas(filerec(f).name), spec); {$ifdef FPC_ANSI_TEXTFILEREC}
DosError := PathArgToFSSpec(filerec(f).name, spec);
{$else}
DosError := PathArgToFSSpec(ToSingleByteFileSystemEncodedFileName(filerec(f).name), spec);
{$endif}
if (DosError = 0) or (DosError = 2) then if (DosError = 0) or (DosError = 2) then
begin begin
DosError := DoFindOne(spec, paramBlock); DosError := DoFindOne(spec, paramBlock);

View File

@ -40,7 +40,7 @@ begin
{$endif} {$endif}
end; end;
procedure do_erase(p : pchar); procedure do_erase(p : pchar; pchangeable: boolean);
var var
spec: FSSpec; spec: FSSpec;
@ -63,7 +63,7 @@ begin
InOutRes:=res; InOutRes:=res;
end; end;
procedure do_rename(p1,p2 : pchar); procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
var var
s1,s2: AnsiString; s1,s2: AnsiString;
begin begin
@ -196,7 +196,7 @@ begin
{$endif} {$endif}
end; end;
procedure do_open(var f;p:pchar;flags:longint); procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
{ {
filerec and textrec have both handle and mode as the first items so filerec and textrec have both handle and mode as the first items so
they could use the same routine for opening/creating. they could use the same routine for opening/creating.

View File

@ -725,7 +725,11 @@ var
begin begin
DosError:=0; DosError:=0;
FTime := 0; FTime := 0;
Str := StrPas(filerec(f).name); {$ifdef FPC_ANSI_TEXTFILEREC}
Str := strpas(filerec(f).Name);
{$else}
Str := ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
{$endif}
DoDirSeparators(Str); DoDirSeparators(Str);
FLock := dosLock(Str, SHARED_LOCK); FLock := dosLock(Str, SHARED_LOCK);
IF FLock <> 0 then begin IF FLock <> 0 then begin
@ -756,7 +760,11 @@ end;
FLock: longint; FLock: longint;
Begin Begin
new(DateStamp); new(DateStamp);
Str := StrPas(filerec(f).name); {$ifdef FPC_ANSI_TEXTFILEREC}
Str := strpas(filerec(f).Name);
{$else}
Str := ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
{$endif}
DoDirSeparators(str); DoDirSeparators(str);
{ Check first of all, if file exists } { Check first of all, if file exists }
FLock := dosLock(Str, SHARED_LOCK); FLock := dosLock(Str, SHARED_LOCK);
@ -788,7 +796,11 @@ begin
DosError:=0; DosError:=0;
flags:=0; flags:=0;
New(info); New(info);
Str := StrPas(filerec(f).name); {$ifdef FPC_ANSI_TEXTFILEREC}
Str := strpas(filerec(f).Name);
{$else}
Str := ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
{$endif}
DoDirSeparators(str); DoDirSeparators(str);
{ open with shared lock to check if file exists } { open with shared lock to check if file exists }
MyLock:=dosLock(Str,SHARED_LOCK); MyLock:=dosLock(Str,SHARED_LOCK);
@ -825,7 +837,17 @@ procedure setfattr(var f; attr : word);
var var
flags: longint; flags: longint;
tmpLock : longint; tmpLock : longint;
{$ifndef FPC_ANSI_TEXTFILEREC}
r : rawbytestring;
{$endif not FPC_ANSI_TEXTFILEREC}
p : pchar;
begin begin
{$ifdef FPC_ANSI_TEXTFILEREC}
p := @filerec(f).Name;
{$else}
r := ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
p := pchar(r);
{$endif}
DosError:=0; DosError:=0;
flags:=FIBF_WRITE; flags:=FIBF_WRITE;
@ -836,10 +858,10 @@ begin
{ converts the path (KB) } { converts the path (KB) }
{ create a shared lock on the file } { create a shared lock on the file }
tmpLock:=Lock(filerec(f).name,SHARED_LOCK); tmpLock:=Lock(p,SHARED_LOCK);
if tmpLock <> 0 then begin if tmpLock <> 0 then begin
Unlock(tmpLock); Unlock(tmpLock);
if not SetProtection(filerec(f).name,flags) then DosError:=5; if not SetProtection(p,flags) then DosError:=5;
end else end else
DosError:=3; DosError:=3;
end; end;

View File

@ -171,7 +171,7 @@ begin
end; end;
end; end;
procedure do_erase(p : pchar); procedure do_erase(p : pchar; pchangeable: boolean);
var var
tmpStr: array[0..255] of Char; tmpStr: array[0..255] of Char;
begin begin
@ -181,7 +181,7 @@ begin
dosError2InOut(IoErr); dosError2InOut(IoErr);
end; end;
procedure do_rename(p1,p2 : pchar); procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
{ quite stack-effective code, huh? :) damn path conversions... (KB) } { quite stack-effective code, huh? :) damn path conversions... (KB) }
var var
tmpStr1: array[0..255] of Char; tmpStr1: array[0..255] of Char;
@ -311,7 +311,7 @@ begin
end; end;
end; end;
procedure do_open(var f;p:pchar;flags:longint); procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
{ {
filerec and textrec have both handle and mode as the first items so filerec and textrec have both handle and mode as the first items so
they could use the same routine for opening/creating. they could use the same routine for opening/creating.

View File

@ -902,9 +902,20 @@ end;
procedure getfattr(var f;var attr : word); procedure getfattr(var f;var attr : word);
var
path: pchar;
{$ifndef FPC_ANSI_TEXTFILEREC}
r: rawbytestring;
{$endif not FPC_ANSI_TEXTFILEREC}
begin begin
dosregs.dx:=Ofs(filerec(f).name); {$ifdef FPC_ANSI_TEXTFILEREC}
dosregs.ds:=Seg(filerec(f).name); path:=@filerec(f).Name;
{$else}
r:=ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
path:=pchar(r);
{$endif}
dosregs.dx:=Ofs(path^);
dosregs.ds:=Seg(path^);
if LFNSupport then if LFNSupport then
begin begin
dosregs.ax:=$7143; dosregs.ax:=$7143;
@ -919,6 +930,11 @@ end;
procedure setfattr(var f;attr : word); procedure setfattr(var f;attr : word);
var
path: pchar;
{$ifndef FPC_ANSI_TEXTFILEREC}
r: rawbytestring;
{$endif not FPC_ANSI_TEXTFILEREC}
begin begin
{ Fail for setting VolumeId. } { Fail for setting VolumeId. }
if ((attr and VolumeID)<>0) then if ((attr and VolumeID)<>0) then
@ -926,8 +942,14 @@ begin
doserror:=5; doserror:=5;
exit; exit;
end; end;
dosregs.dx:=Ofs(filerec(f).name); {$ifdef FPC_ANSI_TEXTFILEREC}
dosregs.ds:=Seg(filerec(f).name); path:=@filerec(f).Name;
{$else}
r:=ToSingleByteFileSystemEncodedFileName(filerec(f).Name);
path:=pchar(r);
{$endif}
dosregs.dx:=Ofs(path);
dosregs.ds:=Seg(path);
if LFNSupport then if LFNSupport then
begin begin
dosregs.ax:=$7143; dosregs.ax:=$7143;

View File

@ -54,11 +54,13 @@ begin
end; end;
procedure do_erase(p : pchar); procedure do_erase(p : pchar; pchangeable: boolean);
var var
regs : Registers; regs : Registers;
oldp : pchar;
begin begin
DoDirSeparators(p); oldp:=p;
DoDirSeparators(p,pchangeable);
regs.DX:=Ofs(p^); regs.DX:=Ofs(p^);
regs.DS:=Seg(p^); regs.DS:=Seg(p^);
if LFNSupport then if LFNSupport then
@ -70,15 +72,20 @@ begin
MsDos(regs); MsDos(regs);
if (regs.Flags and fCarry) <> 0 then if (regs.Flags and fCarry) <> 0 then
GetInOutRes(regs.AX); GetInOutRes(regs.AX);
if p<>oldp then
freemem(p);
end; end;
procedure do_rename(p1,p2 : pchar); procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
var var
regs : Registers; regs : Registers;
oldp1, oldp2 : pchar;
begin begin
DoDirSeparators(p1); oldp1:=p1;
DoDirSeparators(p2); oldp2:=p2;
DoDirSeparators(p1,p1changeable);
DoDirSeparators(p2,p2changeable);
regs.DS:=Seg(p1^); regs.DS:=Seg(p1^);
regs.DX:=Ofs(p1^); regs.DX:=Ofs(p1^);
regs.ES:=Seg(p2^); regs.ES:=Seg(p2^);
@ -91,6 +98,10 @@ begin
MsDos(regs); MsDos(regs);
if (regs.Flags and fCarry) <> 0 then if (regs.Flags and fCarry) <> 0 then
GetInOutRes(regs.AX); GetInOutRes(regs.AX);
if p1<>oldp1 then
freemem(p1);
if p2<>oldp2 then
freemem(p2);
end; end;
@ -229,7 +240,7 @@ begin
Increase_file_handle_count:=true; Increase_file_handle_count:=true;
end; end;
procedure do_open(var f;p:pchar;flags:longint); procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
{ {
filerec and textrec have both handle and mode as the first items so filerec and textrec have both handle and mode as the first items so
they could use the same routine for opening/creating. they could use the same routine for opening/creating.
@ -240,8 +251,8 @@ procedure do_open(var f;p:pchar;flags:longint);
var var
regs : Registers; regs : Registers;
action : longint; action : longint;
oldp : pchar;
begin begin
DoDirSeparators(p);
{ close first if opened } { close first if opened }
if ((flags and $10000)=0) then if ((flags and $10000)=0) then
begin begin
@ -283,6 +294,8 @@ begin
end; end;
exit; exit;
end; end;
oldp:=p;
DoDirSeparators(p,pchangeable);
{$ifndef RTLLITE} {$ifndef RTLLITE}
if LFNSupport then if LFNSupport then
begin begin
@ -332,6 +345,8 @@ begin
if (regs.Flags and fCarry) <> 0 then if (regs.Flags and fCarry) <> 0 then
begin begin
GetInOutRes(regs.AX); GetInOutRes(regs.AX);
if oldp<>p then
freemem(p);
exit; exit;
end end
else else
@ -366,6 +381,8 @@ begin
do_seekend(filerec(f).handle); do_seekend(filerec(f).handle);
filerec(f).mode:=fmoutput; {fool fmappend} filerec(f).mode:=fmoutput; {fool fmappend}
end; end;
if oldp<>p then
freemem(p);
end; end;

View File

@ -34,7 +34,7 @@ begin
end; end;
procedure do_erase(p : pchar); procedure do_erase(p : pwidechar; pchangeable: boolean);
var var
ntstr: TNtUnicodeString; ntstr: TNtUnicodeString;
objattr: TObjectAttributes; objattr: TObjectAttributes;
@ -42,11 +42,13 @@ var
h: THandle; h: THandle;
disp: TFileDispositionInformation; disp: TFileDispositionInformation;
res: LongInt; res: LongInt;
oldp: pwidechar;
begin begin
InoutRes := 4; InoutRes := 4;
DoDirSeparators(p); oldp:=p;
DoDirSeparators(p,pchangeable);
SysPCharToNtStr(ntstr, p, 0); SysPWideCharToNtStr(ntstr, p, 0);
SysInitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil); SysInitializeObjectAttributes(objattr, @ntstr, 0, 0, Nil);
res := NtCreateFile(@h, NT_DELETE or NT_SYNCHRONIZE, @objattr, @iostatus, Nil, res := NtCreateFile(@h, NT_DELETE or NT_SYNCHRONIZE, @objattr, @iostatus, Nil,
@ -71,10 +73,12 @@ begin
SysFreeNtStr(ntstr); SysFreeNtStr(ntstr);
Errno2InoutRes; Errno2InoutRes;
if p<>oldp then
freemem(p);
end; end;
procedure do_rename(p1,p2 : pchar); procedure do_rename(p1,p2 : pwidechar; p1changeable, p2changeable: boolean);
var var
h: THandle; h: THandle;
objattr: TObjectAttributes; objattr: TObjectAttributes;
@ -82,12 +86,14 @@ var
dest, src: TNtUnicodeString; dest, src: TNtUnicodeString;
renameinfo: PFileRenameInformation; renameinfo: PFileRenameInformation;
res: LongInt; res: LongInt;
oldp1, oldp2 : pwidechar;
begin begin
DoDirSeparators(p1); oldp1:=p1;
DoDirSeparators(p2); oldp2:=p2;
{ check whether the destination exists first } { check whether the destination exists first }
SysPCharToNtStr(dest, p2, 0); DoDirSeparators(p2,p2changeable);
SysPWideCharToNtStr(dest, p2, 0);
SysInitializeObjectAttributes(objattr, @dest, 0, 0, Nil); SysInitializeObjectAttributes(objattr, @dest, 0, 0, Nil);
res := NtCreateFile(@h, 0, @objattr, @iostatus, Nil, 0, res := NtCreateFile(@h, 0, @objattr, @iostatus, Nil, 0,
@ -99,7 +105,8 @@ begin
errno := 5; errno := 5;
Errno2InoutRes; Errno2InoutRes;
end else begin end else begin
SysPCharToNtStr(src, p1, 0); DoDirSeparators(p1,p1changeable);
SysPWideCharToNtStr(src, p1, 0);
SysInitializeObjectAttributes(objattr, @src, 0, 0, Nil); SysInitializeObjectAttributes(objattr, @src, 0, 0, Nil);
res := NtCreateFile(@h, GENERIC_ALL or NT_SYNCHRONIZE or FILE_READ_ATTRIBUTES, res := NtCreateFile(@h, GENERIC_ALL or NT_SYNCHRONIZE or FILE_READ_ATTRIBUTES,
@ -138,6 +145,10 @@ begin
end; end;
SysFreeNtStr(dest); SysFreeNtStr(dest);
if p1<>oldp1 then
freemem(p1);
if p2<>oldp2 then
freemem(p2);
end; end;
@ -292,7 +303,7 @@ begin
end; end;
procedure do_open(var f;p:pchar;flags:longint); procedure do_open(var f;p:pwidechar;flags:longint; pchangeable: boolean);
{ {
filerec and textrec have both handle and mode as the first items so filerec and textrec have both handle and mode as the first items so
they could use the same routine for opening/creating. they could use the same routine for opening/creating.
@ -306,8 +317,8 @@ var
iostatus: TIoStatusBlock; iostatus: TIoStatusBlock;
ntstr: TNtUnicodeString; ntstr: TNtUnicodeString;
res: LongInt; res: LongInt;
oldp : pwidechar;
begin begin
DoDirSeparators(p);
{ close first if opened } { close first if opened }
if ((flags and $10000)=0) then if ((flags and $10000)=0) then
begin begin
@ -378,7 +389,9 @@ begin
exit; exit;
end; end;
SysPCharToNtStr(ntstr, p, 0); oldp:=p;
DoDirSeparators(p,pchangeable);
SysPWideCharToNtStr(ntstr, p, 0);
SysInitializeObjectAttributes(objattr, @ntstr, OBJ_INHERIT, 0, Nil); SysInitializeObjectAttributes(objattr, @ntstr, OBJ_INHERIT, 0, Nil);
@ -399,4 +412,6 @@ begin
errno := res; errno := res;
Errno2InoutRes; Errno2InoutRes;
end; end;
if oldp<>p then
freemem(p);
end; end;

View File

@ -372,6 +372,19 @@ begin
aNtStr.Buffer[i] := aText[i]; aNtStr.Buffer[i] := aText[i];
end; end;
procedure SysPWideCharToNtStr(var aNtStr: TNtUnicodeString; aText: PWideChar;
aLen: LongWord);
var
i: Integer;
begin
if (aLen = 0) and (aText <> Nil) and (aText^ <> #0) then
aLen := Length(aText);
aNtStr.Length := aLen * SizeOf(WideChar);
aNtStr.MaximumLength := aNtStr.Length;
aNtStr.Buffer := GetMem(aNtStr.Length);
Move(aText[0],aNtStr.Buffer[0],aLen);
end;
procedure SysUnicodeStringToNtStr(var aNtStr: TNtUnicodeString; const s: UnicodeString); procedure SysUnicodeStringToNtStr(var aNtStr: TNtUnicodeString; const s: UnicodeString);
var var
i: Integer; i: Integer;

View File

@ -88,7 +88,7 @@ begin
InOutRes := 0; InOutRes := 0;
end; end;
procedure do_erase(p: pchar); procedure do_erase(p: pchar; pchangeable: boolean);
var var
res: longint; res: longint;
begin begin
@ -100,7 +100,7 @@ begin
InOutRes := 0; InOutRes := 0;
end; end;
procedure do_rename(p1, p2: pchar); procedure do_rename(p1, p2: pchar; p1changeable, p2changeable: boolean);
var var
res: longint; res: longint;
begin begin
@ -209,7 +209,7 @@ begin
InOutRes := 0; InOutRes := 0;
end; end;
procedure do_open(var f;p:pchar;flags:longint); procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
{ {
filerec and textrec have both handle and mode as the first items so filerec and textrec have both handle and mode as the first items so
they could use the same routine for opening/creating. they could use the same routine for opening/creating.

View File

@ -80,7 +80,7 @@ begin
InOutRes := 0; InOutRes := 0;
end; end;
procedure do_erase(p : pchar); procedure do_erase(p : pchar; pchangeable: boolean);
VAR res : LONGINT; VAR res : LONGINT;
begin begin
res := _unlink (p); res := _unlink (p);
@ -90,7 +90,7 @@ begin
InOutRes := 0; InOutRes := 0;
end; end;
procedure do_rename(p1,p2 : pchar); procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
VAR res : LONGINT; VAR res : LONGINT;
begin begin
res := _rename (p1,p2); res := _rename (p1,p2);
@ -189,7 +189,7 @@ begin
end; end;
// mostly stolen from syslinux // mostly stolen from syslinux
procedure do_open(var f;p:pchar;flags:longint); procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
{ {
filerec and textrec have both handle and mode as the first items so filerec and textrec have both handle and mode as the first items so
they could use the same routine for opening/creating. they could use the same routine for opening/creating.

View File

@ -553,10 +553,21 @@ end;
procedure getfattr(var f;var attr : word); procedure getfattr(var f;var attr : word);
VAR StatBuf : TStat; var
StatBuf : TStat;
{$ifndef FPC_ANSI_TEXTFILEREC}
r: rawbytestring;
{$endif not FPC_ANSI_TEXTFILEREC}
p: pchar;
begin begin
doserror := 0; doserror := 0;
if Fpstat (@textrec(f).name, StatBuf) = 0 then {$ifdef FPC_ANSI_TEXTFILEREC}
p := @filerec(f).name;
{$else FPC_ANSI_TEXTFILEREC}
r := ToSingleByteFileSystemEncodedFileName(filerec(f).name);
p := pchar(r);
{$endif FPC_ANSI_TEXTFILEREC}
if Fpstat (p, StatBuf) = 0 then
attr := nwattr2dosattr (StatBuf.st_mode) attr := nwattr2dosattr (StatBuf.st_mode)
else else
begin begin
@ -570,8 +581,18 @@ procedure setfattr(var f;attr : word);
var var
StatBuf : TStat; StatBuf : TStat;
newMode : longint; newMode : longint;
{$ifndef FPC_ANSI_TEXTFILEREC}
r: rawbytestring;
{$endif not FPC_ANSI_TEXTFILEREC}
p: pchar;
begin begin
if Fpstat (@textrec(f).name,StatBuf) = 0 then {$ifdef FPC_ANSI_TEXTFILEREC}
p := @filerec(f).name;
{$else FPC_ANSI_TEXTFILEREC}
r := ToSingleByteFileSystemEncodedFileName(filerec(f).name);
p := pchar(r);
{$endif FPC_ANSI_TEXTFILEREC}
if Fpstat (p,StatBuf) = 0 then
begin begin
newmode := StatBuf.st_mode and ($FFFF0000 - M_A_RDONLY-M_A_HIDDEN-M_A_SYSTEM-M_A_ARCH); {only this can be set by dos unit} newmode := StatBuf.st_mode and ($FFFF0000 - M_A_RDONLY-M_A_HIDDEN-M_A_SYSTEM-M_A_ARCH); {only this can be set by dos unit}
newmode := newmode or M_A_BITS_SIGNIFICANT; {set netware attributes} newmode := newmode or M_A_BITS_SIGNIFICANT; {set netware attributes}

View File

@ -84,7 +84,7 @@ begin
InOutRes := 0; InOutRes := 0;
end; end;
procedure do_erase(p : pchar); procedure do_erase(p : pchar; pchangeable: boolean);
VAR res : LONGINT; VAR res : LONGINT;
begin begin
res := unlink (p); res := unlink (p);
@ -94,7 +94,7 @@ begin
InOutRes := 0; InOutRes := 0;
end; end;
procedure do_rename(p1,p2 : pchar); procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
VAR res : LONGINT; VAR res : LONGINT;
begin begin
res := rename (p1,p2); res := rename (p1,p2);
@ -221,7 +221,7 @@ end;
{$ifdef IOpossix} {$ifdef IOpossix}
// mostly stolen from syslinux // mostly stolen from syslinux
procedure do_open(var f;p:pchar;flags:longint); procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
{ {
filerec and textrec have both handle and mode as the first items so filerec and textrec have both handle and mode as the first items so
they could use the same routine for opening/creating. they could use the same routine for opening/creating.

View File

@ -592,10 +592,19 @@ procedure GetFAttr (var F; var Attr: word);
var var
PathInfo: TFileStatus3; PathInfo: TFileStatus3;
RC: cardinal; RC: cardinal;
{$ifndef FPC_ANSI_TEXTFILEREC}
R: rawbytestring;
{$endif not FPC_ANSI_TEXTFILEREC}
P: pchar;
begin begin
Attr := 0; Attr := 0;
RC := DosQueryPathInfo (@FileRec (F).Name, ilStandard, {$ifdef FPC_ANSI_TEXTFILEREC}
@PathInfo, SizeOf (PathInfo)); P := @FileRec (F).Name;
{$else FPC_ANSI_TEXTFILEREC}
R := ToSingleByteFileSystemEncodedFileName (FileRec (F).Name);
P := PChar (R);
{$endif FPC_ANSI_TEXTFILEREC}
RC := DosQueryPathInfo (P, ilStandard, @PathInfo, SizeOf (PathInfo));
DosError := integer (RC); DosError := integer (RC);
if RC = 0 then if RC = 0 then
Attr := PathInfo.AttrFile; Attr := PathInfo.AttrFile;
@ -606,14 +615,23 @@ procedure SetFAttr (var F; Attr: word);
var var
PathInfo: TFileStatus3; PathInfo: TFileStatus3;
RC: cardinal; RC: cardinal;
{$ifndef FPC_ANSI_TEXTFILEREC}
R: rawbytestring;
{$endif not FPC_ANSI_TEXTFILEREC}
P: pchar;
begin begin
RC := DosQueryPathInfo (@FileRec (F).Name, ilStandard, {$ifdef FPC_ANSI_TEXTFILEREC}
@PathInfo, SizeOf (PathInfo)); P := @FileRec (F).Name;
{$else FPC_ANSI_TEXTFILEREC}
R := ToSingleByteFileSystemEncodedFileName (FileRec (F).Name);
P := PChar (R);
{$endif FPC_ANSI_TEXTFILEREC}
RC := DosQueryPathInfo (P, ilStandard, @PathInfo, SizeOf (PathInfo));
if RC = 0 then if RC = 0 then
begin begin
PathInfo.AttrFile := Attr; PathInfo.AttrFile := Attr;
RC := DosSetPathInfo (@FileRec (F).Name, ilStandard, @PathInfo, RC := DosSetPathInfo (P, ilStandard, @PathInfo, SizeOf (PathInfo),
SizeOf (PathInfo), doWriteThru); doWriteThru);
end; end;
DosError := integer (RC); DosError := integer (RC);
end; end;

View File

@ -31,17 +31,30 @@ begin
{$endif} {$endif}
end; end;
procedure do_erase(p:Pchar); procedure do_erase(p:Pchar; pchangeable: boolean);
var
oldp: pchar;
begin begin
DoDirSeparators(p); oldp:=p;
DoDirSeparators(p,pchangeable);
inoutres:=DosDelete(p); inoutres:=DosDelete(p);
if p<>oldp then
freemem(p);
end; end;
procedure do_rename(p1,p2:Pchar); procedure do_rename(p1,p2:Pchar; p1changeable, p2changeable: boolean);
var
oldp1, oldp2 : pchar;
begin begin
DoDirSeparators(p1); oldp1:=p1;
DoDirSeparators(p2); oldp2:=p2;
DoDirSeparators(p1,p1changeable);
DoDirSeparators(p2,p2changeable);
inoutres:=DosMove(p1, p2); inoutres:=DosMove(p1, p2);
if p1<>oldp1 then
freemem(p1);
if p2<>oldp2 then
freemem(p2);
end; end;
function do_read(h:thandle;addr:pointer;len:longint):longint; function do_read(h:thandle;addr:pointer;len:longint):longint;
@ -141,7 +154,7 @@ begin
Increase_File_Handle_Count := false; Increase_File_Handle_Count := false;
end; end;
procedure do_open(var f;p:pchar;flags:longint); procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
{ {
filerec and textrec have both handle and mode as the first items so filerec and textrec have both handle and mode as the first items so
they could use the same routine for opening/creating. they could use the same routine for opening/creating.
@ -152,9 +165,8 @@ procedure do_open(var f;p:pchar;flags:longint);
} }
var var
Action, Attrib, OpenFlags, FM: Cardinal; Action, Attrib, OpenFlags, FM: Cardinal;
oldp : pchar;
begin begin
// convert unix slashes to normal slashes
DoDirSeparators(p);
// close first if opened // close first if opened
if ((flags and $10000)=0) then if ((flags and $10000)=0) then
@ -211,6 +223,9 @@ begin
exit; exit;
end; end;
oldp:=p;
// convert unix slashes to normal slashes
DoDirSeparators(p,pchangeable);
Attrib:=32 {faArchive}; Attrib:=32 {faArchive};
InOutRes:=Sys_DosOpenL(p, FileRec(F).Handle, Action, 0, Attrib, OpenFlags, FM, nil); InOutRes:=Sys_DosOpenL(p, FileRec(F).Handle, Action, 0, Attrib, OpenFlags, FM, nil);
@ -235,6 +250,9 @@ begin
end; end;
if oldp<>p then
freemem(p);
{$ifdef IODEBUG} {$ifdef IODEBUG}
writeln('do_open,', filerec(f).handle, ',', filerec(f).name, ',', filerec(f).mode, ', InOutRes=', InOutRes); writeln('do_open,', filerec(f).handle, ',', filerec(f).name, ',', filerec(f).mode, ', InOutRes=', InOutRes);
{$endif} {$endif}

View File

@ -31,13 +31,13 @@ begin
end; end;
procedure do_erase(p : pchar); procedure do_erase(p : pchar; pchangeable: boolean);
begin begin
end; end;
procedure do_rename(p1,p2 : pchar); procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
begin begin
end; end;
@ -85,7 +85,7 @@ begin
end; end;
procedure do_open(var f;p:pchar;flags:longint); procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
begin begin
end; end;

View File

@ -780,9 +780,24 @@ Procedure GetFAttr(var f; var attr : word);
Var Var
info : baseunix.stat; info : baseunix.stat;
LinAttr : longint; LinAttr : longint;
p : pchar;
{$ifndef FPC_ANSI_TEXTFILEREC}
r : RawByteString;
{$endif not FPC_ANSI_TEXTFILEREC}
Begin Begin
DosError:=0; DosError:=0;
if FPStat(@textrec(f).name[0],info)<0 then {$ifdef FPC_ANSI_TEXTFILEREC}
{ encoding is already correct }
p:=@textrec(f).name;
{$else}
r:=ToSingleByteFileSystemEncodedFileName(textrec(f).name);
p:=pchar(r);
{$endif}
{ use the pchar rather than the rawbytestring version so that we don't check
a second time whether the string needs to be converted to the right code
page
}
if FPStat(p,info)<0 then
begin begin
Attr:=0; Attr:=0;
DosError:=3; DosError:=3;
@ -794,7 +809,7 @@ Begin
Attr:=$10 Attr:=$10
else else
Attr:=$0; Attr:=$0;
if fpAccess(@textrec(f).name[0],W_OK)<0 then if fpAccess(p,W_OK)<0 then
Attr:=Attr or $1; Attr:=Attr or $1;
if filerec(f).name[0]='.' then if filerec(f).name[0]='.' then
Attr:=Attr or $2; Attr:=Attr or $2;
@ -822,7 +837,10 @@ Procedure setftime(var f; time : longint);
Var Var
utim: utimbuf; utim: utimbuf;
DT: DateTime; DT: DateTime;
p : pchar;
{$ifndef FPC_ANSI_TEXTFILEREC}
r : Rawbytestring;
{$endif not FPC_ANSI_TEXTFILEREC}
Begin Begin
doserror:=0; doserror:=0;
with utim do with utim do
@ -831,7 +849,18 @@ Begin
UnPackTime(Time,DT); UnPackTime(Time,DT);
modtime:=DTToUnixDate(DT); modtime:=DTToUnixDate(DT);
end; end;
if fputime(@filerec(f).name[0],@utim)<0 then {$ifdef FPC_ANSI_TEXTFILEREC}
{ encoding is already correct }
p:=@textrec(f).name;
{$else}
r:=ToSingleByteFileSystemEncodedFileName(textrec(f).name);
p:=pchar(r);
{$endif}
{ use the pchar rather than the rawbytestring version so that we don't check
a second time whether the string needs to be converted to the right code
page
}
if fputime(p,@utim)<0 then
begin begin
Time:=0; Time:=0;
doserror:=3; doserror:=3;

View File

@ -74,12 +74,11 @@ Const
Var Var
Lpr : String[255]; { Contains path to lpr binary, including null char } Lpr : String[255]; { Contains path to lpr binary, including null char }
Procedure PrintAndDelete (f:string); Procedure PrintAndDelete (const f: RawByteString);
var var
i: pid_t; i: pid_t;
p,pp : ppchar; p,pp : ppchar;
begin begin
f:=f+#0;
if lpr='' then if lpr='' then
exit; exit;
i:=fpFork; i:=fpFork;
@ -114,8 +113,17 @@ end;
Procedure OpenLstPipe ( Var F : Text); Procedure OpenLstPipe ( Var F : Text);
var
r: rawbytestring;
begin begin
POpen (f,StrPas(textrec(f).name),'W'); {$ifdef FPC_ANSI_TEXTFILEREC}
{ encoding is already correct }
r:=textrec(f).name;
SetCodePage(r,DefaultFileSystemCodePage,false);
{$else}
r:=ToSingleByteFileSystemEncodedFileName(textrec(f).name);
{$endif}
POpen (f,r,'W');
end; end;
@ -123,6 +131,7 @@ end;
Procedure OpenLstFile ( Var F : Text); Procedure OpenLstFile ( Var F : Text);
var var
i : cint; i : cint;
r: rawbytestring;
begin begin
{$IFDEF PRINTERDEBUG} {$IFDEF PRINTERDEBUG}
writeln ('Printer : In OpenLstFile'); writeln ('Printer : In OpenLstFile');
@ -130,8 +139,15 @@ begin
If textrec(f).mode <> fmoutput then If textrec(f).mode <> fmoutput then
exit; exit;
textrec(f).userdata[15]:=0; { set Zero length flag } textrec(f).userdata[15]:=0; { set Zero length flag }
{$ifdef FPC_ANSI_TEXTFILEREC}
{ encoding is already correct }
r:=textrec(f).name;
SetCodePage(r,DefaultFileSystemCodePage,false);
{$else}
r:=ToSingleByteFileSystemEncodedFileName(textrec(f).name);
{$endif}
repeat repeat
i:=fpOpen(StrPas(textrec(f).name),(Open_WrOnly or Open_Creat), 438); i:=fpOpen(pansichar(r),(Open_WrOnly or Open_Creat), 438);
until (i<>-1) or (fpgeterrno<>ESysEINTR); until (i<>-1) or (fpgeterrno<>ESysEINTR);
if i<0 then if i<0 then
textrec(f).mode:=fmclosed textrec(f).mode:=fmclosed
@ -154,12 +170,20 @@ begin
{ In case length is zero, don't print : lpr would give an error } { In case length is zero, don't print : lpr would give an error }
if (textrec(f).userdata[15]=0) and (textrec(f).userdata[16]=P_TOF) then if (textrec(f).userdata[15]=0) and (textrec(f).userdata[16]=P_TOF) then
begin begin
fpUnlink(StrPas(textrec(f).name)); {$IFDEF FPC_ANSI_TEXTFILEREC}
fpUnlink(pansichar(@textrec(f).name));
{$ELSE}
fpUnlink(ToSingleByteFileSystemEncodedFileName(textrec(f).name));
{$ENDIF}
exit exit
end; end;
{ Non empty : needs printing ? } { Non empty : needs printing ? }
if (textrec(f).userdata[16]=P_TOF) then if (textrec(f).userdata[16]=P_TOF) then
PrintAndDelete (strpas(textrec(f).name)); {$IFDEF FPC_ANSI_TEXTFILEREC}
PrintAndDelete (textrec(f).name);
{$ELSE}
PrintAndDelete (ToSingleByteFileSystemEncodedFileName(textrec(f).name));
{$ENDIF}
textrec(f).mode:=fmclosed textrec(f).mode:=fmclosed
end; end;

View File

@ -22,7 +22,7 @@ Begin
until (res<>-1) or (geterrno<>ESysEINTR); until (res<>-1) or (geterrno<>ESysEINTR);
End; End;
Procedure Do_Erase(p:pchar); Procedure Do_Erase(p: pchar; pchangeable: boolean);
var var
fileinfo : stat; fileinfo : stat;
Begin Begin
@ -58,7 +58,7 @@ end;
Procedure Do_Rename(p1,p2:pchar); Procedure Do_Rename(p1,p2:pchar; p1changeable, p2changeable: boolean);
Begin Begin
If Fprename(p1,p2)<0 Then If Fprename(p1,p2)<0 Then
Errno2Inoutres Errno2Inoutres
@ -145,7 +145,7 @@ Begin
InOutRes:=0; InOutRes:=0;
End; End;
Procedure Do_Open(var f;p:pchar;flags:longint); Procedure Do_Open(var f; p: pchar; flags: longint; pchangeable: boolean);
{ {
FileRec and textrec have both Handle and mode as the first items so FileRec and textrec have both Handle and mode as the first items so
they could use the same routine for opening/creating. they could use the same routine for opening/creating.

View File

@ -37,11 +37,13 @@ begin
GetInOutRes(lo(regs.realeax)); GetInOutRes(lo(regs.realeax));
end; end;
procedure do_erase(p : pchar); procedure do_erase(p : pchar; pchangeable: boolean);
var var
regs : trealregs; regs : trealregs;
oldp : pchar;
begin begin
DoDirSeparators(p); oldp:=p;
DoDirSeparators(p,pchangeable);
syscopytodos(longint(p),strlen(p)+1); syscopytodos(longint(p),strlen(p)+1);
regs.realedx:=tb_offset; regs.realedx:=tb_offset;
regs.realds:=tb_segment; regs.realds:=tb_segment;
@ -54,14 +56,19 @@ begin
sysrealintr($21,regs); sysrealintr($21,regs);
if (regs.realflags and carryflag) <> 0 then if (regs.realflags and carryflag) <> 0 then
GetInOutRes(lo(regs.realeax)); GetInOutRes(lo(regs.realeax));
if p<>oldp then
freemem(p);
end; end;
procedure do_rename(p1,p2 : pchar); procedure do_rename(p1,p2 : pchar; p1changeable, p2changeable: boolean);
var var
regs : trealregs; regs : trealregs;
oldp1, oldp2 : pchar;
begin begin
DoDirSeparators(p1); oldp1:=p1;
DoDirSeparators(p2); oldp2:=p2;
DoDirSeparators(p1,p1changeable);
DoDirSeparators(p2,p2changeable);
if strlen(p1)+strlen(p2)+3>tb_size then if strlen(p1)+strlen(p2)+3>tb_size then
HandleError(217); HandleError(217);
sysseg_move(get_ds,sizeuint(p2),dos_selector,tb,strlen(p2)+1); sysseg_move(get_ds,sizeuint(p2),dos_selector,tb,strlen(p2)+1);
@ -78,6 +85,10 @@ begin
sysrealintr($21,regs); sysrealintr($21,regs);
if (regs.realflags and carryflag) <> 0 then if (regs.realflags and carryflag) <> 0 then
GetInOutRes(lo(regs.realeax)); GetInOutRes(lo(regs.realeax));
if p1<>oldp1 then
freemem(p1);
if p2<>oldp2 then
freemem(p2);
end; end;
function do_write(h:longint;addr:pointer;len : longint) : longint; function do_write(h:longint;addr:pointer;len : longint) : longint;
@ -260,7 +271,7 @@ begin
end; end;
procedure do_open(var f;p:pchar;flags:longint); procedure do_open(var f;p:pchar;flags:longint; pchangeable: boolean);
{ {
filerec and textrec have both handle and mode as the first items so filerec and textrec have both handle and mode as the first items so
they could use the same routine for opening/creating. they could use the same routine for opening/creating.
@ -272,8 +283,8 @@ var
regs : trealregs; regs : trealregs;
action : longint; action : longint;
Avoid6c00 : boolean; Avoid6c00 : boolean;
oldp : pchar;
begin begin
DoDirSeparators(p);
{ check if Extended Open/Create API is safe to use } { check if Extended Open/Create API is safe to use }
Avoid6c00 := lo(dos_version) < 7; Avoid6c00 := lo(dos_version) < 7;
{ close first if opened } { close first if opened }
@ -317,6 +328,8 @@ begin
end; end;
exit; exit;
end; end;
oldp:=p;
DoDirSeparators(p,pchangeable);
{ real dos call } { real dos call }
syscopytodos(longint(p),strlen(p)+1); syscopytodos(longint(p),strlen(p)+1);
{$ifndef RTLLITE} {$ifndef RTLLITE}
@ -379,6 +392,8 @@ begin
if (regs.realflags and carryflag) <> 0 then if (regs.realflags and carryflag) <> 0 then
begin begin
GetInOutRes(lo(regs.realeax)); GetInOutRes(lo(regs.realeax));
if oldp<>p then
freemem(p);
exit; exit;
end end
else else
@ -413,6 +428,8 @@ begin
do_seekend(filerec(f).handle); do_seekend(filerec(f).handle);
filerec(f).mode:=fmoutput; {fool fmappend} filerec(f).mode:=fmoutput; {fool fmappend}
end; end;
if oldp<>p then
freemem(p);
end; end;
function do_isdevice(handle:THandle):boolean; function do_isdevice(handle:THandle):boolean;

View File

@ -29,14 +29,14 @@ begin
//_fclose (_PFILE(pointer(handle))^); //_fclose (_PFILE(pointer(handle))^);
end; end;
procedure do_erase(p: pchar); procedure do_erase(p: pchar; pchangeable: boolean);
begin begin
if FileIODevice.FileIO.DoErase <> nil then if FileIODevice.FileIO.DoErase <> nil then
FileIODevice.FileIO.DoErase(p); FileIODevice.FileIO.DoErase(p);
// _unlink(p); // _unlink(p);
end; end;
procedure do_rename(p1, p2: pchar); procedure do_rename(p1, p2: pchar; p1changeable, p2changeable: boolean);
begin begin
// _rename(p1, p2); // _rename(p1, p2);
if FileIODevice.FileIO.DoRename <> nil then if FileIODevice.FileIO.DoRename <> nil then
@ -93,7 +93,7 @@ begin
FileIODevice.FileIO.DoTruncate(handle, pos); FileIODevice.FileIO.DoTruncate(handle, pos);
end; end;
procedure do_open(var f; p: pchar; flags: longint); procedure do_open(var f; p: pchar; flags: longint; pchangeable: boolean);
begin begin
(* (*
{ close first if opened } { close first if opened }

View File

@ -612,9 +612,11 @@ end;
procedure getfattr(var f;var attr : word); procedure getfattr(var f;var attr : word);
var var
l : longint; l : longint;
s : RawByteString;
begin begin
doserror:=0; doserror:=0;
l:=GetFileAttributes(filerec(f).name); s:=ToSingleByteFileSystemEncodedFileName(filerec(f).name);
l:=GetFileAttributes(pchar(s));
if l=longint($ffffffff) then if l=longint($ffffffff) then
begin begin
doserror:=getlasterror; doserror:=getlasterror;
@ -626,15 +628,19 @@ end;
procedure setfattr(var f;attr : word); procedure setfattr(var f;attr : word);
var s : RawByteString;
begin begin
{ Fail for setting VolumeId } { Fail for setting VolumeId }
if (attr and VolumeID)<>0 then if (attr and VolumeID)<>0 then
doserror:=5 doserror:=5
else else
if SetFileAttributes(filerec(f).name,attr) then begin
doserror:=0 s:=ToSingleByteFileSystemEncodedFileName(filerec(f).name);
else if SetFileAttributes(pchar(s),attr) then
doserror:=getlasterror; doserror:=0
else
doserror:=getlasterror;
end;
end; end;
{ change to short filename if successful win32 call PM } { change to short filename if successful win32 call PM }

View File

@ -32,31 +32,44 @@ begin
end; end;
procedure do_erase(p : pchar); procedure do_erase(p: pwidechar; pchangeable: boolean);
var
oldp: pwidechar;
begin begin
DoDirSeparators(p); oldp:=p;
if DeleteFile(p)=0 then DoDirSeparators(p,pchangeable);
if DeleteFileW(p)=0 then
Begin Begin
errno:=GetLastError; errno:=GetLastError;
if errno=5 then if errno=5 then
begin begin
if ((GetFileAttributes(p) and FILE_ATTRIBUTE_DIRECTORY)=FILE_ATTRIBUTE_DIRECTORY) then if ((GetFileAttributesW(p) and FILE_ATTRIBUTE_DIRECTORY)=FILE_ATTRIBUTE_DIRECTORY) then
errno:=2; errno:=2;
end; end;
Errno2InoutRes; Errno2InoutRes;
end; end;
if p<>oldp then
freemem(p);
end; end;
procedure do_rename(p1,p2 : pchar); procedure do_rename(p1,p2: pwidechar; p1changeable, p2changeable: boolean);
var
oldp1,oldp2: pwidechar;
begin begin
DoDirSeparators(p1); oldp1:=p1;
DoDirSeparators(p2); oldp2:=p2;
if MoveFile(p1,p2)=0 then DoDirSeparators(p1,p1changeable);
DoDirSeparators(p2,p2changeable);
if MoveFileW(p1,p2)=0 then
Begin Begin
errno:=GetLastError; errno:=GetLastError;
Errno2InoutRes; Errno2InoutRes;
end; end;
if p1<>oldp1 then
freemem(p1);
if p2<>oldp2 then
freemem(p2);
end; end;
@ -191,7 +204,7 @@ begin
end; end;
procedure do_open(var f;p:pchar;flags:longint); procedure do_open(var f; p: pwidechar; flags: longint; pchangeable: boolean);
{ {
filerec and textrec have both handle and mode as the first items so filerec and textrec have both handle and mode as the first items so
they could use the same routine for opening/creating. they could use the same routine for opening/creating.
@ -207,8 +220,8 @@ Var
shflags, shflags,
oflags,cd : longint; oflags,cd : longint;
security : TSecurityAttributes; security : TSecurityAttributes;
oldp : pwidechar;
begin begin
DoDirSeparators(p);
{ close first if opened } { close first if opened }
if ((flags and $10000)=0) then if ((flags and $10000)=0) then
begin begin
@ -223,6 +236,8 @@ begin
end; end;
end; end;
end; end;
oldp:=p;
DoDirSeparators(p,pchangeable);
{ reset file handle } { reset file handle }
filerec(f).handle:=UnusedHandle; filerec(f).handle:=UnusedHandle;
{ convert filesharing } { convert filesharing }
@ -280,12 +295,14 @@ begin
FileRec(f).mode:=fmoutput; {fool fmappend} FileRec(f).mode:=fmoutput; {fool fmappend}
end; end;
end; end;
{ no dirseparators can have been replaced in the empty string -> no need
to check whether we have to free p }
exit; exit;
end; end;
security.nLength := Sizeof(TSecurityAttributes); security.nLength := Sizeof(TSecurityAttributes);
security.bInheritHandle:=true; security.bInheritHandle:=true;
security.lpSecurityDescriptor:=nil; security.lpSecurityDescriptor:=nil;
filerec(f).handle:=CreateFile(p,oflags,shflags,@security,cd,FILE_ATTRIBUTE_NORMAL,0); filerec(f).handle:=CreateFileW(p,oflags,shflags,@security,cd,FILE_ATTRIBUTE_NORMAL,0);
{ append mode } { append mode }
if ((flags and $100)<>0) and if ((flags and $100)<>0) and
@ -303,4 +320,6 @@ begin
errno:=GetLastError; errno:=GetLastError;
Errno2InoutRes; Errno2InoutRes;
end; end;
if oldp<>p then
freemem(p);
end; end;

View File

@ -280,29 +280,18 @@ threadvar
stdcall;external KernelDLL name 'GetFileType'; stdcall;external KernelDLL name 'GetFileType';
function GetProcAddress(hModule:THandle; lpProcName:pchar):pointer; stdcall; external KernelDLL name 'GetProcAddress'; function GetProcAddress(hModule:THandle; lpProcName:pchar):pointer; stdcall; external KernelDLL name 'GetProcAddress';
{$ifdef FPC_UNICODE_RTL} { File }
function GetFileAttributes(p : punicodechar) : dword; function DeleteFileW(p : punicodechar) : longint;
stdcall;external KernelDLL name 'GetFileAttributesW';
function DeleteFile(p : punicodechar) : longint;
stdcall;external KernelDLL name 'DeleteFileW'; stdcall;external KernelDLL name 'DeleteFileW';
function MoveFile(old,_new : punicodechar) : longint; function MoveFileW(old,_new : punicodechar) : longint;
stdcall;external KernelDLL name 'MoveFileW'; stdcall;external KernelDLL name 'MoveFileW';
function CreateFile(lpFileName:punicodechar; dwDesiredAccess:DWORD; dwShareMode:DWORD; function CreateFileW(lpFileName:punicodechar; dwDesiredAccess:DWORD; dwShareMode:DWORD;
lpSecurityAttributes:PSECURITYATTRIBUTES; dwCreationDisposition:DWORD; lpSecurityAttributes:PSECURITYATTRIBUTES; dwCreationDisposition:DWORD;
dwFlagsAndAttributes:DWORD; hTemplateFile:DWORD):THandle; dwFlagsAndAttributes:DWORD; hTemplateFile:DWORD):THandle;
stdcall;external KernelDLL name 'CreateFileW'; stdcall;external KernelDLL name 'CreateFileW';
{$else} function GetFileAttributesW(p : punicodechar) : dword;
function GetFileAttributes(p : pchar) : dword; stdcall;external KernelDLL name 'GetFileAttributesW';
stdcall;external KernelDLL name 'GetFileAttributesA';
function DeleteFile(p : pchar) : longint;
stdcall;external KernelDLL name 'DeleteFileA';
function MoveFile(old,_new : pchar) : longint;
stdcall;external KernelDLL name 'MoveFileA';
function CreateFile(lpFileName:pchar; dwDesiredAccess:DWORD; dwShareMode:DWORD;
lpSecurityAttributes:PSECURITYATTRIBUTES; dwCreationDisposition:DWORD;
dwFlagsAndAttributes:DWORD; hTemplateFile:DWORD):THandle;
stdcall;external KernelDLL name 'CreateFileA';
{$endif}
{ Directory } { Directory }
function CreateDirectoryW(name : pointer;sec : pointer) : longbool; function CreateDirectoryW(name : pointer;sec : pointer) : longbool;
stdcall;external KernelDLL name 'CreateDirectoryW'; stdcall;external KernelDLL name 'CreateDirectoryW';

View File

@ -484,7 +484,9 @@ end;
procedure getfattr(var f;var attr : word); procedure getfattr(var f;var attr : word);
var var
l : cardinal; l : cardinal;
buf: array[0..MaxPathLen] of WideChar; {$ifdef FPC_ANSI_TEXTFILEREC}
u: unicodestring;
{$endif FPC_ANSI_TEXTFILEREC}
begin begin
if filerec(f).name[0] = #0 then if filerec(f).name[0] = #0 then
begin begin
@ -494,8 +496,12 @@ begin
else else
begin begin
doserror:=0; doserror:=0;
AnsiToWideBuf(@filerec(f).name, -1, buf, SizeOf(buf)); {$ifdef FPC_ANSI_TEXTFILEREC}
l:=GetFileAttributes(buf); widestringmanager.Ansi2UnicodeMoveProc(filerec(f).name,DefaultFileSystemCodePage,u,length(filerec(f).name));
l:=GetFileAttributes(pwidechar(u));
{$else}
l:=GetFileAttributes(filerec(f).name);
{$endif}
if l = $ffffffff then if l = $ffffffff then
begin begin
doserror:=Last2DosError(GetLastError); doserror:=Last2DosError(GetLastError);

View File

@ -87,12 +87,17 @@ function Win32GetCurrentThreadId:DWORD;
function TlsAlloc : DWord; function TlsAlloc : DWord;
function TlsFree(dwTlsIndex : DWord) : LongBool; function TlsFree(dwTlsIndex : DWord) : LongBool;
function GetFileAttributes(p : pchar) : dword;
function DeleteFile(p : pchar) : longint; function GetFileAttributesW(p : pwidechar) : dword;
function MoveFile(old,_new : pchar) : longint; cdecl; external KernelDLL name 'GetFileAttributesW';
function CreateFile(lpFileName:pchar; dwDesiredAccess:DWORD; dwShareMode:DWORD; function DeleteFileW(p : pwidechar) : longint;
cdecl; external KernelDLL name 'DeleteFileW';
function MoveFileW(old,_new : pwidechar) : longint;
cdecl; external KernelDLL name 'MoveFileW';
function CreateFileW(lpFileName:pwidechar; dwDesiredAccess:DWORD; dwShareMode:DWORD;
lpSecurityAttributes:pointer; dwCreationDisposition:DWORD; lpSecurityAttributes:pointer; dwCreationDisposition:DWORD;
dwFlagsAndAttributes:DWORD; hTemplateFile:DWORD):longint; dwFlagsAndAttributes:DWORD; hTemplateFile:DWORD):longint;
cdecl; external KernelDLL name 'CreateFileW';
{$ifdef CPUARM} {$ifdef CPUARM}
@ -416,53 +421,6 @@ end;
WinAPI wrappers implementation WinAPI wrappers implementation
*****************************************************************************} *****************************************************************************}
function GetFileAttributesW(p : pwidechar) : dword;
cdecl; external KernelDLL name 'GetFileAttributesW';
function DeleteFileW(p : pwidechar) : longint;
cdecl; external KernelDLL name 'DeleteFileW';
function MoveFileW(old,_new : pwidechar) : longint;
cdecl; external KernelDLL name 'MoveFileW';
function CreateFileW(lpFileName:pwidechar; dwDesiredAccess:DWORD; dwShareMode:DWORD;
lpSecurityAttributes:pointer; dwCreationDisposition:DWORD;
dwFlagsAndAttributes:DWORD; hTemplateFile:DWORD):longint;
cdecl; external KernelDLL name 'CreateFileW';
function GetFileAttributes(p : pchar) : dword;
var
buf: array[0..MaxPathLen] of WideChar;
begin
AnsiToWideBuf(p, -1, buf, SizeOf(buf));
GetFileAttributes := GetFileAttributesW(buf);
end;
function DeleteFile(p : pchar) : longint;
var
buf: array[0..MaxPathLen] of WideChar;
begin
AnsiToWideBuf(p, -1, buf, SizeOf(buf));
DeleteFile := DeleteFileW(buf);
end;
function MoveFile(old,_new : pchar) : longint;
var
buf_old, buf_new: array[0..MaxPathLen] of WideChar;
begin
AnsiToWideBuf(old, -1, buf_old, SizeOf(buf_old));
AnsiToWideBuf(_new, -1, buf_new, SizeOf(buf_new));
MoveFile := MoveFileW(buf_old, buf_new);
end;
function CreateFile(lpFileName:pchar; dwDesiredAccess:DWORD; dwShareMode:DWORD;
lpSecurityAttributes:pointer; dwCreationDisposition:DWORD;
dwFlagsAndAttributes:DWORD; hTemplateFile:DWORD):longint;
var
buf: array[0..MaxPathLen] of WideChar;
begin
AnsiToWideBuf(lpFileName, -1, buf, SizeOf(buf));
CreateFile := CreateFileW(buf, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
end;
const const
{$ifdef CPUARM} {$ifdef CPUARM}
UserKData = $FFFFC800; UserKData = $FFFFC800;