Skip to content

Commit 31a327f

Browse files
oldnewthingdrewbatgit
authored andcommitted
Merged PR 17061: Clarify current directory and relative path warnings
Existing text erroneously implied that the current directory is not thread safe. It also went too far in saying that relative path usage in multithreaded apps is "not supported". It is supported, but the results may not be what apps expect. Provide new guidance.
1 parent 21b21b0 commit 31a327f

File tree

3 files changed

+49
-32
lines changed

3 files changed

+49
-32
lines changed

sdk-api-src/content/fileapi/nf-fileapi-getfullpathnamea.md

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,9 @@ To perform this operation as a transacted operation, use the
6666

6767
For more information about file and path names, see
6868
<a href="/windows/desktop/FileIO/naming-a-file">File Names, Paths, and Namespaces</a>.
69-
<div class="alert"><b>Note</b>  The <b>GetFullPathName</b> function is not recommended for
70-
multithreaded applications or shared library code. For more information, see the Remarks section.</div><div> </div>
69+
<div class="alert"><b>Note</b> See the Remarks section for discussion of
70+
the use of relative paths with the <b>GetFullPathName</b> function
71+
in multithreaded applications or shared library code.</div>
7172

7273
## -parameters
7374

@@ -155,19 +156,22 @@ If the return value is greater than or equal to the value specified in
155156

156157
<div class="alert"><b>Note</b>  Although the return value in this case is a length that includes the terminating null character, the return
157158
value on success does not include the terminating null character in the count.</div>
158-
<div> </div>
159-
Multithreaded applications and shared library code should not use the
160-
<b>GetFullPathName</b> function and should avoid using relative
161-
path names. The current directory state written by the
162-
<a href="/windows/desktop/api/winbase/nf-winbase-setcurrentdirectory">SetCurrentDirectory</a> function is stored as a global
163-
variable in each process, therefore multithreaded applications cannot reliably use this value without possible
164-
data corruption from other threads that may also be reading or setting this value. This limitation also applies
165-
to the <b>SetCurrentDirectory</b> and
166-
<a href="/windows/desktop/api/winbase/nf-winbase-getcurrentdirectory">GetCurrentDirectory</a> functions. The exception being
167-
when the application is guaranteed to be running in a single thread, for example parsing file names from the
168-
command line argument string in the main thread prior to creating any additional threads. Using relative path
169-
names in multithreaded applications or shared library code can yield unpredictable results and is not
170-
supported.
159+
160+
Relative paths passed to the <b>GetFullPathName</b> function are
161+
interpreted as relative to the process's current directory.
162+
The current directory state written by the
163+
<a href="/windows/desktop/api/winbase/nf-winbase-setcurrentdirectory">SetCurrentDirectory</a>
164+
function is global to the process and can be changed by any thread at any time.
165+
Applications should be aware that
166+
consecutive calls to the <b>GetFullPathName</b> function with a relative path
167+
may produce different results if the current directory changes between the two calls.
168+
169+
To avoid problems caused by inconsistent results,
170+
multithreaded applications and shared library code should avoid using relative paths.
171+
If a relative path is received, it should be consumed exactly once,
172+
either by passing the relative path directly to a function like <b>CreateFile</b>,
173+
or by converting it to an absolute path and using the absolute path
174+
from that point forward.
171175

172176
In Windows 8 and Windows Server 2012, this function is supported by the following technologies.
173177

sdk-api-src/content/fileapi/nf-fileapi-getfullpathnamew.md

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,9 @@ To perform this operation as a transacted operation, use the
6666

6767
For more information about file and path names, see
6868
<a href="/windows/desktop/FileIO/naming-a-file">File Names, Paths, and Namespaces</a>.
69-
<div class="alert"><b>Note</b>  The <b>GetFullPathName</b> function is not recommended for
70-
multithreaded applications or shared library code. For more information, see the Remarks section.</div><div> </div>
69+
<div class="alert"><b>Note</b> See the Remarks section for discussion of
70+
the use of relative paths with the <b>GetFullPathName</b> function
71+
in multithreaded applications or shared library code.</div>
7172

7273
## -parameters
7374

@@ -155,19 +156,22 @@ If the return value is greater than or equal to the value specified in
155156

156157
<div class="alert"><b>Note</b>  Although the return value in this case is a length that includes the terminating null character, the return
157158
value on success does not include the terminating null character in the count.</div>
158-
<div> </div>
159-
Multithreaded applications and shared library code should not use the
160-
<b>GetFullPathName</b> function and should avoid using relative
161-
path names. The current directory state written by the
162-
<a href="/windows/desktop/api/winbase/nf-winbase-setcurrentdirectory">SetCurrentDirectory</a> function is stored as a global
163-
variable in each process, therefore multithreaded applications cannot reliably use this value without possible
164-
data corruption from other threads that may also be reading or setting this value. This limitation also applies
165-
to the <b>SetCurrentDirectory</b> and
166-
<a href="/windows/desktop/api/winbase/nf-winbase-getcurrentdirectory">GetCurrentDirectory</a> functions. The exception being
167-
when the application is guaranteed to be running in a single thread, for example parsing file names from the
168-
command line argument string in the main thread prior to creating any additional threads. Using relative path
169-
names in multithreaded applications or shared library code can yield unpredictable results and is not
170-
supported.
159+
160+
Relative paths passed to the <b>GetFullPathName</b> function are
161+
interpreted as relative to the process's current directory.
162+
The current directory state written by the
163+
<a href="/windows/desktop/api/winbase/nf-winbase-setcurrentdirectory">SetCurrentDirectory</a>
164+
function is global to the process and can be changed by any thread at any time.
165+
Applications should be aware that
166+
consecutive calls to the <b>GetFullPathName</b> function with a relative path
167+
may produce different results if the current directory changes between the two calls.
168+
169+
To avoid problems caused by inconsistent results,
170+
multithreaded applications and shared library code should avoid using relative paths.
171+
If a relative path is received, it should be consumed exactly once,
172+
either by passing the relative path directly to a function like <b>CreateFile</b>,
173+
or by converting it to an absolute path and using the absolute path
174+
from that point forward.
171175

172176
In Windows 8 and Windows Server 2012, this function is supported by the following technologies.
173177

sdk-api-src/content/winbase/nf-winbase-setcurrentdirectory.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,17 @@ Each process has a single current directory made up of two parts:
9090
<li>A disk designator that is either a drive letter followed by a colon, or a server name and share name (&#92;&#92;<i>servername</i>&#92;<i>sharename</i>)</li>
9191
<li>A directory on the disk designator</li>
9292
</ul>
93-
Multithreaded applications and shared library code should not use the
94-
<b>SetCurrentDirectory</b> function and should avoid using relative path names. The current directory state written by the <b>SetCurrentDirectory</b> function is stored as a global variable in each process, therefore multithreaded applications cannot reliably use this value without possible data corruption from other threads that may also be reading or setting this value. This limitation also applies to the <a href="/windows/desktop/api/winbase/nf-winbase-getcurrentdirectory">GetCurrentDirectory</a> and <a href="/windows/desktop/api/fileapi/nf-fileapi-getfullpathnamea">GetFullPathName</a> functions. The exception being when the application is guaranteed to be running in a single thread, for example parsing file names from the command line argument string in the main thread prior to creating any additional threads. Using relative path names in multithreaded applications or shared library code can yield unpredictable results and is not supported.
93+
94+
The current directory is shared by all threads of the process:
95+
If one thread changes the current directory, it affects all threads
96+
in the process.
97+
Multithreaded applications and shared library code should avoid
98+
calling the <b>SetCurrentDirectory</b> function due to the risk of
99+
affecting relative path calculations being performed by other threads.
100+
Conversely,
101+
multithreaded applications and shared library code should avoid
102+
using relative paths so that they are unaffected by changes to the
103+
current directory performed by other threads.
95104

96105
In Windows 8 and Windows Server 2012, this function is supported by the following technologies.
97106

0 commit comments

Comments
 (0)