I am using latest trunk to test some old units out and have come across a problem, with my routine that get user's Documents Folder.
The routine is working fine, when user has standard characters; but when user has character like áé etc, then it fails and raises the exception in the code.
If I use this code on Lazarus Trunk, It does not work and produces no result, I have modified the code to show an 'Oops' message which is triggered if the call to SHGetSpecialFolderPathW fails. Which it does on Trunk.I also use Lazarus trunk and the code works fine. It's more likely a windows related issue(privilege, elevation, etc...). Please try:
Is it possible I have found a bug in Lazarus Trunk?
Is it possible I have found a bug in Lazarus Trunk?No, you added the bug all by yourself. Instead of using the working code provided by GetMem, you added a conversion that is doomed to fail. Why?
function GetSpecialFolder(const CSIDL: Integer): WideString; ... Result := SysToUTF8(SpecialPath)
The problem you are having josh, is that most versions of Windows DO NOT "speak" UTF8/16, or even necessarily Unicode correctly. You will need to ensure that any strings passed to Windows API functions are converted to old-fashioned ASCII code strings.That is not correct. The WinAPI functions that work with old-fashioned ANSI strings do not work with Lazarus Unicode system. You must use the W versions that work with Unicode.
The original function of the first post is working perfectly on my Win7 VM with a special user "UmlautUser-äöüÄ". The only thing that needs to be changed is that SysToUTF8 must be replaced by WinCPToUTF8 on fpc 3+.It works if all the characters belong to the current codepage. Isn't it so?
I think the return type of your function should be UnicodeString instead of WideString. WideString should be used only with OLE programming.You can use both. UnicodeString is reference counted on the other hand WideString basically is the same good old COM BSTR type windows always used, without ref. count. WideString is slower though, since windows makes a copy on winapi calls. Unless you don't call a winapi 1000x times, you should be fine. The funny thing is UnicodeChar points back to WideChar. :)
SHGetSpecialFolderPath is not supported. Instead, use ShGetFolderPath
@rvk
According to @Josh SHGetKnownFolderPathW also fails, see a few post above.
The problem is that it is not even getting to the systoutf8 function, the function SHGetSpecialFolderPathW(0, SpecialPath, CSIDL, False) is returning FALSE, and the error being reported is 'The System Cannot find the path specified'.Why don't you just test with the working function provided by GetMem? Why must you modify it first?
I have tried using WinCPToUTF8 but this has no change in that the error is prior to this.Uhhh, no! For some reason you fail to understand the fundamentals.
You can use both. UnicodeString is reference counted on the other hand WideString basically is the same good old COM BSTR type windows always used, without ref. count. WideString is slower though, since windows makes a copy on winapi calls.That's why UnicodeString should be used instead. WideString is a wrong type here. Why to use it without any benefit?
The funny thing is UnicodeChar points back to WideChar. :)Yes, there is no memory management involved. The types are identical.
Why to use it without any benefit?Widestring is available from delphi4 up, is like a good old friend. Besides I have a few, old projects in delphi 2007 where UnicodeString is not yet available. I'm using for historical reasons, no real benefit.
Widestring is available from delphi4 up, is like a good old friend. Besides I have a few, old projects in delphi 2007 where UnicodeString is not yet available. I'm using for historical reasons, no real benefit.Ok, that is a good reason. :)
I have created a video, which I will upload somewhere in minute, so you can see the oddity ( note the vid has the systoutf8 in it, but I have tested with and without and the result is the same).We believe the problem is real. Did you test privileges as GetMem suggested? It sounds like the most probable cause now.
https://youtu.be/V9dGD1k3XLA
I am now not using systoutf8, and the error is still occuring in the IDE, ...True, the error is not related to string conversions. It is likely a privileges issue.
@Thaddy, thanks for your explanation, I do understand what you are saying, but this does not cover the issue that running the app in the IDE fails, and running directly it works ok.That means that the IDE might not handle virtual folders very well under Windows. I suspect a low-level IO is used instead of the shell api routines. The latter api is the only one that can handle virtual folders under windows transparently. Today I am stuck on arm, but I think this can be easily confirmed by someone else. Worst case scenario is that some idiot hooked the IO API in the Lazarus IDE. In that case: that's an idiot.
That means that the IDE might not handle virtual folders very well under Windows. I suspect a low-level IO is used instead of the shell api routines.Thaddy, the call is already directly to the WinApi with SHGetSpecialFolderPathW. And it seems SHGetFolderPathW (which is called from windirs) also fails in that situation. No virtual directories are used or called.
So it may be just a odd combination of situations that are causing the problem.PS. also disable ANY antivirusscanner you might have running !!!
@rvk, I have just tried -deactivating my AV completely and still suffering the same issue.Well I can't test on windows today before 20:00 ECT, but what about declaring all strings in the routine as unicodestring? FPC will convert a UTF8 to UTF16 automatically..
I will try a complete separate installation of trunk in separate folder, it will take some time so will be an hour or so before I can report back on results of that.
What is odd is this only happens when user has utf8 characters in it, ...Actually on Windows they are UTF-16. Anyway, the user name has Unicode characters outside the 7-bit ASCII range.
I have just tried -deactivating my AV completely and still suffering the same issue.Maybe deactivating isn't enough in this case. It might still be sitting in between.
Anyway, the user name has Unicode characters outside the 7-bit ASCII range.That's not a mystery, but fully allowed.
Still a mystery...
It's a mystery why the API call fails (in case of OP's computer). And only on extended characters at that.Anyway, the user name has Unicode characters outside the 7-bit ASCII range.That's not a mystery, but fully allowed.
Still a mystery...
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Users\UmlautUser-äöüÄ>cd \
C:\>dir shell32.dll /s
Volume in drive C has no label.
Volume Serial Number is 9C53-3EF9
Directory of C:\Windows\System32
11/21/2010 05:23 AM 14,174,208 shell32.dll
1 File(s) 14,174,208 bytes
Directory of C:\Windows\SysWOW64
11/21/2010 05:24 AM 12,872,192 shell32.dll
1 File(s) 12,872,192 bytes
Directory of C:\Windows\winsxs\amd64_microsoft-windows-shell32_31bf3856ad364e35
_6.1.7601.17514_none_ca4f304d289b7800
11/21/2010 05:23 AM 14,174,208 shell32.dll
1 File(s) 14,174,208 bytes
Directory of C:\Windows\winsxs\wow64_microsoft-windows-shell32_31bf3856ad364e35
_6.1.7601.17514_none_d4a3da9f5cfc39fb
11/21/2010 05:24 AM 12,872,192 shell32.dll
1 File(s) 12,872,192 bytes
Total Files Listed:
4 File(s) 54,092,800 bytes
0 Dir(s) 6,162,755,584 bytes free
C:\>
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Users\joáh>cd\
C:\>dir shell32.dll /s
Volume in drive C has no label.
Volume Serial Number is 40EB-6EBC
Directory of C:\Windows\System32
20/06/2017 13:57 14,183,936 shell32.dll
1 File(s) 14,183,936 bytes
Directory of C:\Windows\SysWOW64
20/06/2017 13:57 12,880,896 shell32.dll
1 File(s) 12,880,896 bytes
Directory of C:\Windows\winsxs\amd64_microsoft-windows-shell32_31bf3856ad364e35
_6.1.7601.17514_none_ca4f304d289b7800
21/11/2010 04:23 14,174,208 shell32.dll
1 File(s) 14,174,208 bytes
Directory of C:\Windows\winsxs\amd64_microsoft-windows-shell32_31bf3856ad364e35
_6.1.7601.18222_none_ca42435328a5836f
26/07/2013 03:24 14,172,672 shell32.dll
1 File(s) 14,172,672 bytes
Directory of C:\Windows\winsxs\amd64_microsoft-windows-shell32_31bf3856ad364e35
_6.1.7601.18952_none_ca21e0d928bdc353
02/11/2015 02:00 14,176,768 shell32.dll
1 File(s) 14,176,768 bytes
Directory of C:\Windows\winsxs\amd64_microsoft-windows-shell32_31bf3856ad364e35
_6.1.7601.22403_none_cae2822641b201d5
26/07/2013 03:24 14,176,256 shell32.dll
1 File(s) 14,176,256 bytes
Directory of C:\Windows\winsxs\amd64_microsoft-windows-shell32_31bf3856ad364e35
_6.1.7601.23155_none_caae56a441d8e264
02/11/2015 02:00 14,182,912 shell32.dll
1 File(s) 14,182,912 bytes
Directory of C:\Windows\winsxs\amd64_microsoft-windows-shell32_31bf3856ad364e35
_6.1.7601.23806_none_cae573d441af5c17
20/06/2017 13:57 14,183,936 shell32.dll
1 File(s) 14,183,936 bytes
Directory of C:\Windows\winsxs\wow64_microsoft-windows-shell32_31bf3856ad364e35
_6.1.7601.17514_none_d4a3da9f5cfc39fb
21/11/2010 04:24 12,872,192 shell32.dll
1 File(s) 12,872,192 bytes
Directory of C:\Windows\winsxs\wow64_microsoft-windows-shell32_31bf3856ad364e35
_6.1.7601.18222_none_d496eda55d06456a
26/07/2013 02:55 12,872,704 shell32.dll
1 File(s) 12,872,704 bytes
Directory of C:\Windows\winsxs\wow64_microsoft-windows-shell32_31bf3856ad364e35
_6.1.7601.18952_none_d4768b2b5d1e854e
02/11/2015 02:00 12,875,776 shell32.dll
1 File(s) 12,875,776 bytes
Directory of C:\Windows\winsxs\wow64_microsoft-windows-shell32_31bf3856ad364e35
_6.1.7601.22403_none_d5372c787612c3d0
26/07/2013 02:56 12,874,752 shell32.dll
1 File(s) 12,874,752 bytes
Directory of C:\Windows\winsxs\wow64_microsoft-windows-shell32_31bf3856ad364e35
_6.1.7601.23155_none_d50300f67639a45f
02/11/2015 02:00 12,878,848 shell32.dll
1 File(s) 12,878,848 bytes
Directory of C:\Windows\winsxs\wow64_microsoft-windows-shell32_31bf3856ad364e35
_6.1.7601.23806_none_d53a1e2676101e12
20/06/2017 13:57 12,880,896 shell32.dll
1 File(s) 12,880,896 bytes
Total Files Listed:
14 File(s) 189,386,752 bytes
0 Dir(s) 28,598,775,808 bytes free
C:\>
GNU gdb (GDB) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb)