[fpc-pascal] DoDirSeparators and special filenames on Windows

Sven Barth pascaldragon at googlemail.com
Mon Sep 9 14:13:26 CEST 2013


Am 09.09.2013 13:47, schrieb Sven Barth:
> Am 09.09.2013 13:31, schrieb Sven Barth:
>> Am 08.09.2013 22:32, schrieb Tomas Hajny:
>>> On Sun, September 8, 2013 19:32, Sven Barth wrote:
>>>> On 08.09.2013 14:17, Bart wrote:
>>>>> On 9/8/13, Tomas Hajny <XHajT03 at hajny.biz> wrote:
>>>>>
>>>>>> Why do you believe that ExpandFilename is not threadsafe (on 
>>>>>> Windows or
>>>>>> any other platform)?
>>>>> ..
>>>>>> The only platform specific part inside
>>>>>> ExpandFilename is a call to GetDir function retrieving the current
>>>>>> directory. If that is not 'threadsafe' by itself (on Windows), then
>>>>>> your
>>>>>> statement is correct,
>>>>> And that is exactly the point.
>>>>> GetDir calls GetCurentDirectory and MS says (see:
>>>>> http://msdn.microsoft.com/en-us/library/windows/desktop/aa364934%28v=vs.85%29.aspx) 
>>>>>
>>>>> that multithreaded applications should not call GetCurrentDirectory.
>>>> The problem is not GetCurrentDirectory itself (this function and
>>>> SetCurrentDirectory use the process's PEB lock to access the current
>>>> directory which is stored inside the PEB as well), but that different
>>>> threads could call SetCurrentDirectory with different values and 
>>>> thus a
>>>> thread who expected the current directory to be a specific one might
>>>> resolve a relative path (by using another WinAPI function) using a
>>>> current directory set by a different thread.
>>> I believe that there are three different things:
>>>
>>> 1) We have a sequence in GetDir implementation for Windows targets 
>>> which
>>> changes the current directory. While this is obviously necessary due to
>>> limitations of the respective Win32/64 API for retrieving current
>>> directory combined with characteristics of the supported path names, it
>>> may not be expected by the programmers who may have no call to
>>> SetCurrentDirectory within their code and thus expect no issues with
>>> thread safety. I don't know if it is possible to use a critical 
>>> section or
>>> something like that to avoid switching to another thread during this
>>> context, but it might be useful to think about it in my opinion.
>> On Windows this is completely useless. A process has only *one* 
>> current directory. The current-directory-per-drive ones are only 
>> implemented inside the command line interpreter and other programs 
>> that use the crt library (not to be confused with the crt unit). So 
>> the calling of SetCurrentDirectory inside ExpandFilename is not only 
>> not threadsafe, but doesn't result in something useful either!
> Correction, there seems to be a bit more magic going on... I'll report 
> back.
Ok, while a process does indeed only have a single current directory the 
kernel32 DLL is setting up environment variables to reference the 
current directories of other drives and resolves them when 
SetCurrentDirectory is called.

My suggestion: Don't use the SetCurrentDirectory stuff inside GetDir 
anymore, but instead use GetFullPathName with the drive as parameter 
(see 
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364963%28v=vs.85%29.aspx 
). It's still not thread safe in sense of your (3) (but that is the 
programmer's problem anyway), but the GetDir function itself would be 
thread safe.
Just in case: GetFullPathName is supported in Win9x and since Windows NT 
3.0.

Regards,
Sven



More information about the fpc-pascal mailing list