Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2016-03

GetAppConfigDir on Windows XP (PT-BR): Configura??es

10 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Bart
to Alexsander Rosa

On 3/30/16, Alexsander Rosa wrote:

Which Lazarus version?
Which Fpc version?
Did you define DisableUtf8RTL in project options?

Lazarus trunk:

  s := getappconfigdirutf8(false);
  e := ExtractFilePath(getappconfigdirutf8(false));
  showmessage('GetAppConfigDir(False) = '^m'"'+s+'"'+
              ^m^m'ExtractFilePath(GetAppConfigDir(False)) = '+
              ^m'"'+e+'"');

Gives me
[Window Title]
test

[Content]
GetAppConfigDir(False) =
"C:\Users\??????\AppData\Local\test\"

ExtractFilePath(GetAppConfigDir(False)) =
"C:\Users\??????\AppData\Local\test\"

[OK]

Notice that the username (??????) is outside my current system codepage and still isdisplayed correctly.

(The code for getAppConfigDirUtf8 in 1.6 does not differ from trunk.)

When do you see the "Configura??es", in a GUI window (like showmessage or a TLabel) or when written to console with writeln??

Bart

Alexsander Rosa
to Bart

Lazarus 1.4.4 with FPC 2.6.4. It's on a TLabel.

2016-03-30 13:36 GMT-03:00 Bart :

Show quoted text 43 lines
On 3/30/16, Alexsander Rosa wrote: Which Lazarus version? Which Fpc version? Did you define DisableUtf8RTL in project options? Lazarus trunk: s := getappconfigdirutf8(false); e := ExtractFilePath(getappconfigdirutf8(false)); showmessage('GetAppConfigDir(False) = '^m'"'+s+'"'+ ^m^m'ExtractFilePath(GetAppConfigDir(False)) = '+ ^m'"'+e+'"'); Gives me [Window Title] test [Content] GetAppConfigDir(False) = "C:\Users\??????\AppData\Local\test\" ExtractFilePath(GetAppConfigDir(False)) = "C:\Users\??????\AppData\Local\test\" [OK] Notice that the username (??????) is outside my current system codepage and still isdisplayed correctly. (The code for getAppConfigDirUtf8 in 1.6 does not differ from trunk.) When do you see the "Configura??es", in a GUI window (like showmessage or a TLabel) or when written to console with writeln?? Bart -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus
Atenciosamente, Alexsander da Rosa -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20160401/eee899b3/attachment.html>
Denis Kozlov
to Alexsander Rosa
Alexsander Rosa wrote
Lazarus 1.4.4 with FPC 2.6.4.

In Lazarus 1.4.4, GetAppConfigDirUTF8 and GetAppConfigFileUTF8 internally use GetAppConfigDirAnsi and GetAppConfigFileAnsi (unless running on Windows CE), respectively. These functions call ANSI version of Windows API and then map the result into UTF8.

If there are characters in the path which do not exist in your current system ANSI code page, then you would get question marks instead, e.g. "Configura??es".

Denis
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20160401/8cf16b30/attachment.html>

Denis Kozlov
to Denis Kozlov
Denis Kozlov wrote 9 lines
In Lazarus 1.4.4, GetAppConfigDirUTF8 and GetAppConfigFileUTF8 internally use GetAppConfigDirAnsi and GetAppConfigFileAnsi (unless running on Windows CE), respectively. These functions call ANSI version of Windows API and then map the result into UTF8. If there are characters in the path which do not exist in your current system ANSI code page, then you would get question marks instead, e.g. "Configura??es".

This issue also affects Lazarus 1.6 and FPC 3.0+.

GetWindowsSpecialDir in FPC 3.0.0 and trunk has severe encoding and buffer overrun issues. SHGetFolderPath links to SHGetFolderPathW if FPC_UNICODE_RTL is defined. But GetWindowsSpecialDir still calls it as SHGetFolderPathA, passing under-sized PChar buffer instead of PWideChar.

Working on a fix.

Denis
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20160401/61d602f8/attachment.html>

Bart
to Denis Kozlov
Denis Kozlov wrote 6 lines
This issue also affects Lazarus 1.6 and FPC 3.0+. GetWindowsSpecialDir in FPC 3.0.0 and trunk has severe encoding and buffer overrun issues. SHGetFolderPath links to SHGetFolderPathW if FPC_UNICODE_RTL is defined. But GetWindowsSpecialDir still calls it as SHGetFolderPathA, passing under-sized PChar buffer instead of PWideChar.

GetAppConfigDirUTF8 on Windows uses SHGetFolderPathW directly and then does Utf16ToUtf8 on the result.
Bypassig the GetWindowsSpecialDir in fpc completely. (revision 43495 by bart, Thu Nov 28 18:37:44 2013)

Bart

Denis Kozlov
to Bart
Bart wrote 17 lines
On 4/1/16, Denis Kozlov wrote: > This issue also affects Lazarus 1.6 and FPC 3.0+. > > GetWindowsSpecialDir in FPC 3.0.0 and trunk has severe encoding and buffer > overrun issues. SHGetFolderPath links to SHGetFolderPathW if > FPC_UNICODE_RTL is defined. But GetWindowsSpecialDir still calls it as > SHGetFolderPathA, passing under-sized PChar buffer instead of PWideChar. GetAppConfigDirUTF8 on Windows uses SHGetFolderPathW directly and then does Utf16ToUtf8 on the result. Bypassig the GetWindowsSpecialDir in fpc completely. (revision 43495 by bart, Thu Nov 28 18:37:44 2013) Bart

Yes, Lazarus 1.7 uses SHGetFolderPath directly. Lazarus 1.6 fixes branch still uses GetWindowsSpecialDir.

This patch should fix GetWindowsSpecialDir, GetAppConfigDir and GetAppConfigFile in FPC:
http://bugs.freepascal.org/view.php?id=29942

Maybe LCL can then use FPC's implementation?

Denis
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20160401/360c6c01/attachment.html>

Bart
to Denis Kozlov
Denis Kozlov wrote
Yes, Lazarus 1.7 uses SHGetFolderPath directly. Lazarus 1.6 fixes branch still uses GetWindowsSpecialDir. From the 1.6 fixes brach, file

($lazarus)/components/lazutils/winlazfileutils.inc

This happens in the initialization section when Windows version > WinMe:

_GetAppConfigDirUtf8 := @GetAppConfigDirWide;
function GetAppConfigDirWide(Global: Boolean; Create: boolean = false): string;
const
  CSIDL_GLOBAL = {$IFDEF
WINCE}CSIDL_WINDOWS{$ELSE}CSIDL_COMMON_APPDATA{$ENDIF WINCE};
  CSIDL_LOCAL = {$IFDEF WINCE}CSIDL_APPDATA{$ELSE}CSIDL_LOCAL_APPDATA{$ENDIF};
begin
  If Global then
    Result := GetWindowsSpecialDirW(CSIDL_GLOBAL)
  else
    Result := GetWindowsSpecialDirW(CSIDL_LOCAL);
...

And GetWindowsSpecialDirW is also in winlazfileutils.inc:

function GetWindowsSpecialDirW(ID :  Integer) : String;
Var
  APath : Array[0..MAX_PATH] of WideChar;
  WS: WideString;
  Len: SizeInt;
begin
  Result := '';
  if (CFGDLLHandle = 0) then
    InitDLL;
  If (SHGetFolderPathW  Nil) then
  begin
    FillChar(APath{%H-}, SizeOf(APath), #0);
    if SHGetFolderPathW(0,ID or CSIDL_FLAG_CREATE,0,0, at APATH[0]) = S_OK then
    begin
      Len := StrLen(APath);
      SetLength(WS, Len);
      System.Move(APath[0], WS[1], Len * SizeOf(WideChar));
      Result := AppendPathDelim(Utf16ToUtf8(WS));
    end;
  end
  else  //note: only on Windows < XP
    Result := SysToUtf8(GetWindowsSpecialDir(ID));
end;
And SHGetFolderPathW is initialized like this:
      Pointer(ShGetFolderPathW):=GetProcAddress(CFGDLLHandle,'SHGetFolderPathW');

So, also on the 1.6 branch we directly call the Windows Wide API (provided you are NOT on a Win9x system).

I showed you the revision, you can read that I implemented it that way, so why do you think it's not true what I'm telling you? This was introduce way before the 1.6 was branched off. I tested it with unicode characters (some oriental characters) outside my system codepage (western european) and it works as expected.

Note:
Mattias renamed GetWindowsSpecialDirW into SHGetFolderPathUTF8 and exposed it in the interface section of LazFileUtils.

Bart

Denis Kozlov
to Bart
Bart wrote
So, also on the 1.6 branch we directly call the Windows Wide API (provided you are NOT on a Win9x system).

Sorry Bart, you are right.

I overlooked "Win32MajorVersion <= 4" after seeing "{$ifndef WinCE}". I went straight to GetAppConfigDirAnsi to discover issues with SysUtils.GetAppConfigDir, or specifically with GetWindowsSpecialDir. So, issues with GetWindowsSpecialDir are a concern only for FPC then.

Denis

Denis Kozlov
to Alexsander Rosa: How can I get GetAppConfigDir correctly on Windows XP (PT-BR)? The path includes the word…
Alexsander Rosa wrote 5 lines
How can I get GetAppConfigDir correctly on Windows XP (PT-BR)? The path includes the word "configura??es" (settings, in portuguese). dir_config := ExtractFilePath(GetAppConfigDirUTF8(false)); Any hints?

Can you reproduce this problem if you creating a new (empty) application project in Lazarus? Can you zip it and share?

Local tests with Lazarus 1.4.4 and 1.6, on Windows XP and 7, show that GetAppConfigDirUTF8 is operating correctly with various Unicode symbols in the path.

Denis
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20160402/d2949ce8/attachment.html>