2
0
Эх сурвалжийг харах

+ 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 -

Jonas Maebe 12 жил өмнө
parent
commit
df6a2dce00

+ 28 - 6
rtl/amiga/dos.pp

@@ -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;
-begin
+{$ifndef FPC_ANSI_TEXTFILEREC}
+  r : rawbytestring;
+{$endif not FPC_ANSI_TEXTFILEREC}
+  p : pchar;
+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;

+ 3 - 3
rtl/amiga/sysfile.inc

@@ -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.

+ 3 - 3
rtl/embedded/sysfile.inc

@@ -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;
 
 

+ 10 - 4
rtl/emx/dos.pas

@@ -944,8 +944,11 @@ var
  buffer:array[0..255] of char;
  buffer:array[0..255] of char;
 begin
 begin
   DosError := 0;
   DosError := 0;
-  path:='';
-  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));
@@ -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));

+ 26 - 11
rtl/emx/sysfile.inc

@@ -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);
-    DoDirSeparators(p2);
+    oldp1:=p1;
+    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}

+ 3 - 3
rtl/gba/sysfile.inc

@@ -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;
 
 

+ 18 - 0
rtl/go32v2/dos.pp

@@ -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

+ 24 - 7
rtl/go32v2/sysfile.inc

@@ -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);
-  DoDirSeparators(p2);
+  oldp1:=p1;
+  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;
 
 
 
 

+ 175 - 35
rtl/inc/file.inc

@@ -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);
-  FileRec(f).Handle:=UnusedHandle;
-  FileRec(f).mode:=fmClosed;
-  Move(Name[1],FileRec(f).Name,Length(Name));
+  InitFile(F);
+{$ifdef FPC_ANSI_TEXTFILEREC}
+  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;
 End;
+{$endif FPC_HAS_FEATURE_WIDESTRINGS}
 
 
 
 
-Procedure Assign(out f:File;p:pchar);
+{$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
   Assign Name to file f so it can be used with the file routines
 }
 }
-begin
-  Assign(f,StrPas(p));
-end;
-
+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;c:char);
+Procedure Assign(out f:File;const Name: ShortString);
 {
 {
   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
-  Assign(f,string(c));
-end;
+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;
 
 
+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;const c: AnsiChar);
+Begin
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+  Assign(f,AnsiString(c));
+{$else FPC_HAS_FEATURE_ANSISTRINGS}
+  Assign(f,ShortString(c));
+{$endif FPC_HAS_FEATURE_ANSISTRINGS}
+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
-   exit;
-  If FileRec(f).mode=fmClosed Then
-   Begin
-     Do_Rename(PChar(@FileRec(f).Name),p);
-     { check error code of do_rename }
-     If InOutRes = 0 then
-        Move(p^,FileRec(f).Name,StrLen(p)+1);
-   End;
+  If (InOutRes<>0) or
+     (FileRec(f).mode<>fmClosed) then
+    exit;
+{$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+  { it's slightly faster to convert the unicodestring here to rawbytestring
+    than doing it in do_rename(), because here we still know the length }
+  fs:=ToSingleByteFileSystemEncodedFileName(s);
+  Do_Rename(PFileTextRecChar(@FileRec(f).Name),PAnsiChar(fs),false,true);
+  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];
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+Begin
+  Rename(f,AnsiString(p));
+End;
+{$else FPC_HAS_FEATURE_ANSISTRINGS}
 var
 var
-  p : array[0..1] Of Char;
+  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}
 
 

+ 1 - 1
rtl/inc/filerec.inc

@@ -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;
 
 

+ 1 - 1
rtl/inc/objects.pp

@@ -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

+ 115 - 3
rtl/inc/system.inc

@@ -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 }

+ 43 - 15
rtl/inc/systemh.inc

@@ -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;p:pchar);
-Procedure Assign(out f:File;c:char);
+Procedure Assign(out f:File;const Name: ShortString);
+Procedure Assign(out f:File;const p: PAnsiChar);
+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;p:pchar);
-Procedure Assign(out f:TypedFile;c:char);
+Procedure Assign(out f:TypedFile;const Name:shortstring);
+Procedure Assign(out f:TypedFile;const p:PAnsiChar);
+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;p:pchar);
-Procedure Assign(out t:Text;c:char);
+Procedure Assign(out t:Text;const s:shortstring);
+Procedure Rename(var t:Text;const s:shortstring);
+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;

+ 172 - 31
rtl/inc/text.inc

@@ -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;
+end;
 
 
 
 
-Procedure Assign(out t:Text;p:pchar);
+{$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
+Procedure Assign(out t:Text;const s : UnicodeString);
 begin
 begin
-  Assign(t,StrPas(p));
+  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;
 end;
+{$endif FPC_HAS_FEATURE_WIDESTRINGS}
 
 
 
 
-Procedure Assign(out t:Text;c:char);
-begin
-  Assign(t,string(c));
-end;
+{$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;
+
+
+Procedure Assign(out t:Text;const p: PAnsiChar);
+Begin
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+  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;const c: AnsiChar);
+Begin
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+  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
-   exit;
-  If TextRec(t).mode=fmClosed Then
-   Begin
-     Do_Rename(PChar(@TextRec(t).Name),p);
-     { check error code of do_rename }
-     If InOutRes = 0 then
-         Move(p^,TextRec(t).Name,StrLen(p)+1);
-   End;
+  If (InOutRes<>0) or
+     (TextRec(t).mode<>fmClosed) then
+    exit;
+{$ifdef FPCRTL_FILESYSTEM_SINGLE_BYTE_API}
+  { it's slightly faster to convert the unicodestring here to rawbytestring
+    than doing it in do_rename(), because here we still know the length }
+  fs:=ToSingleByteFileSystemEncodedFileName(s);
+  Do_Rename(PFileTextRecChar(@TextRec(t).Name),PAnsiChar(fs),false,true);
+  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);
+{$ifdef FPC_HAS_FEATURE_ANSISTRINGS}
+Begin
+  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;c : char);[IOCheck];
+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
 var
-  p : array[0..1] Of Char;
+  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

+ 2 - 2
rtl/inc/textrec.inc

@@ -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}

+ 24 - 16
rtl/inc/typefile.inc

@@ -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);
-  FileRec(f).Handle:=UnusedHandle;
-  FileRec(f).mode:=fmClosed;
-  Move(Name[1],FileRec(f).Name,Length(Name));
+  Assign(UnTypedFile(f),Name);
 End;
 End;
+{$endif FPC_HAS_FEATURE_WIDESTRINGS}
 
 
 
 
-Procedure Assign(out f:TypedFile;p:pchar);
+{$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
   Assign Name to file f so it can be used with the file routines
 }
 }
-begin
-  Assign(f,StrPas(p));
-end;
+Begin
+  Assign(UnTypedFile(f),Name);
+End;
+{$endif FPC_HAS_FEATURE_ANSISTRINGS}
 
 
 
 
-Procedure Assign(out f:TypedFile;c:char);
+Procedure Assign(out f:TypedFile;const Name: ShortString);
 {
 {
   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
-  Assign(f,string(c));
+Begin
+  Assign(UnTypedFile(f),Name);
+End;
+
+
+Procedure Assign(out f:TypedFile;const p:PAnsiChar);
+Begin
+  Assign(UnTypedFile(f),p);
 end;
 end;
 
 
 
 
+Procedure Assign(out f:TypedFile;const c:AnsiChar);
+Begin
+  Assign(UnTypedFile(f),c);
+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;
 
 

+ 10 - 2
rtl/macos/dos.pp

@@ -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);

+ 3 - 3
rtl/macos/sysfile.inc

@@ -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.

+ 28 - 6
rtl/morphos/dos.pp

@@ -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;
-begin
+{$ifndef FPC_ANSI_TEXTFILEREC}
+  r : rawbytestring;
+{$endif not FPC_ANSI_TEXTFILEREC}
+  p : pchar;
+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;

+ 3 - 3
rtl/morphos/sysfile.inc

@@ -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.

+ 26 - 4
rtl/msdos/dos.pp

@@ -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);
-  dosregs.ds:=Seg(filerec(f).name);
+{$ifdef FPC_ANSI_TEXTFILEREC}
+  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);
-  dosregs.ds:=Seg(filerec(f).name);
+{$ifdef FPC_ANSI_TEXTFILEREC}
+  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;

+ 24 - 7
rtl/msdos/sysfile.inc

@@ -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);
-  DoDirSeparators(p2);
+  oldp1:=p1;
+  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;
 
 
 
 

+ 26 - 11
rtl/nativent/sysfile.inc

@@ -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);
-  DoDirSeparators(p2);
+  oldp1:=p1;
+  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;

+ 13 - 0
rtl/nativent/sysos.inc

@@ -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;

+ 3 - 3
rtl/nds/sysfile.inc

@@ -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.

+ 3 - 3
rtl/netware/sysfile.inc

@@ -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.

+ 24 - 3
rtl/netwlibc/dos.pp

@@ -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}

+ 3 - 3
rtl/netwlibc/sysfile.inc

@@ -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.

+ 24 - 6
rtl/os2/dos.pas

@@ -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,
-                                                 @PathInfo, SizeOf (PathInfo));
+{$ifdef FPC_ANSI_TEXTFILEREC}
+  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,
-                                                 @PathInfo, SizeOf (PathInfo));
+{$ifdef FPC_ANSI_TEXTFILEREC}
+  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,
-                                               SizeOf (PathInfo), doWriteThru);
+    RC := DosSetPathInfo (P, ilStandard, @PathInfo, SizeOf (PathInfo),
+                                                        doWriteThru);
   end;
   end;
   DosError := integer (RC);
   DosError := integer (RC);
 end;
 end;

+ 26 - 8
rtl/os2/sysfile.inc

@@ -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);
-  DoDirSeparators(p2);
+  oldp1:=p1;
+  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}

+ 3 - 3
rtl/symbian/sysfile.inc

@@ -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;

+ 33 - 4
rtl/unix/dos.pp

@@ -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;

+ 30 - 6
rtl/unix/printer.pp

@@ -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;
 
 

+ 3 - 3
rtl/unix/sysfile.inc

@@ -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.

+ 24 - 7
rtl/watcom/sysfile.inc

@@ -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);
-  DoDirSeparators(p2);
+  oldp1:=p1;
+  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;

+ 3 - 3
rtl/wii/sysfile.inc

@@ -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 }

+ 11 - 5
rtl/win/dos.pp

@@ -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
-    doserror:=0
-  else
-    doserror:=getlasterror;
+     begin
+       s:=ToSingleByteFileSystemEncodedFileName(filerec(f).name);
+       if SetFileAttributes(pchar(s),attr) then
+        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 }

+ 30 - 11
rtl/win/sysfile.inc

@@ -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);
-   if DeleteFile(p)=0 then
+   oldp:=p;
+   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);
-  DoDirSeparators(p2);
-  if MoveFile(p1,p2)=0 then
+  oldp1:=p1;
+  oldp2:=p2;
+  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;

+ 7 - 18
rtl/win/sysos.inc

@@ -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}
-    function GetFileAttributes(p : punicodechar) : dword;
-     stdcall;external KernelDLL name 'GetFileAttributesW';
-   function DeleteFile(p : punicodechar) : longint;
+   { File }
+   function DeleteFileW(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 GetFileAttributes(p : pchar) : dword;
-     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}
+   function GetFileAttributesW(p : punicodechar) : dword;
+     stdcall;external KernelDLL name 'GetFileAttributesW';
+
    { 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';

+ 9 - 3
rtl/wince/dos.pp

@@ -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));
-      l:=GetFileAttributes(buf);
+{$ifdef FPC_ANSI_TEXTFILEREC}
+      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);

+ 9 - 51
rtl/wince/system.pp

@@ -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 MoveFile(old,_new : pchar) : longint;
-function CreateFile(lpFileName:pchar; dwDesiredAccess:DWORD; dwShareMode:DWORD;
+
+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;
                    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;