88
99#ifdef _WIN32
1010
11+ #ifdef CLAR_WIN32_LONGPATHS
12+ # define CLAR_MAX_PATH 4096
13+ #else
14+ # define CLAR_MAX_PATH MAX_PATH
15+ #endif
16+
1117#define RM_RETRY_COUNT 5
1218#define RM_RETRY_DELAY 10
1319
@@ -48,21 +54,48 @@ fs_rmdir_rmdir(WCHAR *_wpath)
4854 return 0 ;
4955}
5056
57+ static void translate_path (WCHAR * path , size_t path_size )
58+ {
59+ size_t path_len , i ;
60+
61+ if (wcsncmp (path , L"\\\\?\\" , 4 ) == 0 )
62+ return ;
63+
64+ path_len = wcslen (path );
65+ cl_assert (path_size > path_len + 4 );
66+
67+ for (i = path_len ; i > 0 ; i -- ) {
68+ WCHAR c = path [i - 1 ];
69+
70+ if (c == L'/' )
71+ path [i + 3 ] = L'\\' ;
72+ else
73+ path [i + 3 ] = path [i - 1 ];
74+ }
75+
76+ path [0 ] = L'\\' ;
77+ path [1 ] = L'\\' ;
78+ path [2 ] = L'?' ;
79+ path [3 ] = L'\\' ;
80+ path [path_len + 4 ] = L'\0' ;
81+ }
82+
5183static void
5284fs_rmdir_helper (WCHAR * _wsource )
5385{
54- WCHAR buffer [MAX_PATH ];
86+ WCHAR buffer [CLAR_MAX_PATH ];
5587 HANDLE find_handle ;
5688 WIN32_FIND_DATAW find_data ;
5789 size_t buffer_prefix_len ;
5890
5991 /* Set up the buffer and capture the length */
60- wcscpy_s (buffer , MAX_PATH , _wsource );
61- wcscat_s (buffer , MAX_PATH , L"\\" );
92+ wcscpy_s (buffer , CLAR_MAX_PATH , _wsource );
93+ translate_path (buffer , CLAR_MAX_PATH );
94+ wcscat_s (buffer , CLAR_MAX_PATH , L"\\" );
6295 buffer_prefix_len = wcslen (buffer );
6396
6497 /* FindFirstFile needs a wildcard to match multiple items */
65- wcscat_s (buffer , MAX_PATH , L"*" );
98+ wcscat_s (buffer , CLAR_MAX_PATH , L"*" );
6699 find_handle = FindFirstFileW (buffer , & find_data );
67100 cl_assert (INVALID_HANDLE_VALUE != find_handle );
68101
@@ -72,7 +105,7 @@ fs_rmdir_helper(WCHAR *_wsource)
72105 if (fs__dotordotdot (find_data .cFileName ))
73106 continue ;
74107
75- wcscpy_s (buffer + buffer_prefix_len , MAX_PATH - buffer_prefix_len , find_data .cFileName );
108+ wcscpy_s (buffer + buffer_prefix_len , CLAR_MAX_PATH - buffer_prefix_len , find_data .cFileName );
76109
77110 if (FILE_ATTRIBUTE_DIRECTORY & find_data .dwFileAttributes )
78111 fs_rmdir_helper (buffer );
@@ -123,7 +156,7 @@ fs_rm_wait(WCHAR *_wpath)
123156static void
124157fs_rm (const char * _source )
125158{
126- WCHAR wsource [MAX_PATH ];
159+ WCHAR wsource [CLAR_MAX_PATH ];
127160 DWORD attrs ;
128161
129162 /* The input path is UTF-8. Convert it to wide characters
@@ -133,7 +166,9 @@ fs_rm(const char *_source)
133166 _source ,
134167 -1 , /* Indicates NULL termination */
135168 wsource ,
136- MAX_PATH ));
169+ CLAR_MAX_PATH ));
170+
171+ translate_path (wsource , CLAR_MAX_PATH );
137172
138173 /* Does the item exist? If not, we have no work to do */
139174 attrs = GetFileAttributesW (wsource );
@@ -158,21 +193,23 @@ fs_rm(const char *_source)
158193static void
159194fs_copydir_helper (WCHAR * _wsource , WCHAR * _wdest )
160195{
161- WCHAR buf_source [MAX_PATH ], buf_dest [MAX_PATH ];
196+ WCHAR buf_source [CLAR_MAX_PATH ], buf_dest [CLAR_MAX_PATH ];
162197 HANDLE find_handle ;
163198 WIN32_FIND_DATAW find_data ;
164199 size_t buf_source_prefix_len , buf_dest_prefix_len ;
165200
166- wcscpy_s (buf_source , MAX_PATH , _wsource );
167- wcscat_s (buf_source , MAX_PATH , L"\\" );
201+ wcscpy_s (buf_source , CLAR_MAX_PATH , _wsource );
202+ wcscat_s (buf_source , CLAR_MAX_PATH , L"\\" );
203+ translate_path (buf_source , CLAR_MAX_PATH );
168204 buf_source_prefix_len = wcslen (buf_source );
169205
170- wcscpy_s (buf_dest , MAX_PATH , _wdest );
171- wcscat_s (buf_dest , MAX_PATH , L"\\" );
206+ wcscpy_s (buf_dest , CLAR_MAX_PATH , _wdest );
207+ wcscat_s (buf_dest , CLAR_MAX_PATH , L"\\" );
208+ translate_path (buf_dest , CLAR_MAX_PATH );
172209 buf_dest_prefix_len = wcslen (buf_dest );
173210
174211 /* Get an enumerator for the items in the source. */
175- wcscat_s (buf_source , MAX_PATH , L"*" );
212+ wcscat_s (buf_source , CLAR_MAX_PATH , L"*" );
176213 find_handle = FindFirstFileW (buf_source , & find_data );
177214 cl_assert (INVALID_HANDLE_VALUE != find_handle );
178215
@@ -185,8 +222,8 @@ fs_copydir_helper(WCHAR *_wsource, WCHAR *_wdest)
185222 if (fs__dotordotdot (find_data .cFileName ))
186223 continue ;
187224
188- wcscpy_s (buf_source + buf_source_prefix_len , MAX_PATH - buf_source_prefix_len , find_data .cFileName );
189- wcscpy_s (buf_dest + buf_dest_prefix_len , MAX_PATH - buf_dest_prefix_len , find_data .cFileName );
225+ wcscpy_s (buf_source + buf_source_prefix_len , CLAR_MAX_PATH - buf_source_prefix_len , find_data .cFileName );
226+ wcscpy_s (buf_dest + buf_dest_prefix_len , CLAR_MAX_PATH - buf_dest_prefix_len , find_data .cFileName );
190227
191228 if (FILE_ATTRIBUTE_DIRECTORY & find_data .dwFileAttributes )
192229 fs_copydir_helper (buf_source , buf_dest );
@@ -205,7 +242,7 @@ fs_copydir_helper(WCHAR *_wsource, WCHAR *_wdest)
205242static void
206243fs_copy (const char * _source , const char * _dest )
207244{
208- WCHAR wsource [MAX_PATH ], wdest [MAX_PATH ];
245+ WCHAR wsource [CLAR_MAX_PATH ], wdest [CLAR_MAX_PATH ];
209246 DWORD source_attrs , dest_attrs ;
210247 HANDLE find_handle ;
211248 WIN32_FIND_DATAW find_data ;
@@ -217,14 +254,17 @@ fs_copy(const char *_source, const char *_dest)
217254 _source ,
218255 -1 ,
219256 wsource ,
220- MAX_PATH ));
257+ CLAR_MAX_PATH ));
221258
222259 cl_assert (MultiByteToWideChar (CP_UTF8 ,
223260 MB_ERR_INVALID_CHARS ,
224261 _dest ,
225262 -1 ,
226263 wdest ,
227- MAX_PATH ));
264+ CLAR_MAX_PATH ));
265+
266+ translate_path (wsource , CLAR_MAX_PATH );
267+ translate_path (wdest , CLAR_MAX_PATH );
228268
229269 /* Check the source for existence */
230270 source_attrs = GetFileAttributesW (wsource );
@@ -238,8 +278,8 @@ fs_copy(const char *_source, const char *_dest)
238278 * Use FindFirstFile to parse the path */
239279 find_handle = FindFirstFileW (wsource , & find_data );
240280 cl_assert (INVALID_HANDLE_VALUE != find_handle );
241- wcscat_s (wdest , MAX_PATH , L"\\" );
242- wcscat_s (wdest , MAX_PATH , find_data .cFileName );
281+ wcscat_s (wdest , CLAR_MAX_PATH , L"\\" );
282+ wcscat_s (wdest , CLAR_MAX_PATH , find_data .cFileName );
243283 FindClose (find_handle );
244284
245285 /* Check the new target for existence */
0 commit comments