2 * PROJECT: ReactOS Kernel
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * PURPOSE: CRT: implementation of __[w]splitpath[_s]
5 * PROGRAMMERS: Timo Kreuzer
21 _In_z_
const _TCHAR
* path
,
22 _Out_writes_opt_z_(drive_size
) _TCHAR
* drive
,
23 _In_
size_t drive_size
,
24 _Out_writes_opt_z_(dir_size
) _TCHAR
* dir
,
26 _Out_writes_opt_z_(fname_size
) _TCHAR
* fname
,
27 _In_
size_t fname_size
,
28 _Out_writes_opt_z_(ext_size
) _TCHAR
* ext
,
34 _CRT_INSECURE_DEPRECATE(_splitpath_s
)
39 _In_z_
const _TCHAR
* path
,
40 _Pre_maybenull_ _Post_z_ _TCHAR
* drive
,
41 _Pre_maybenull_ _Post_z_ _TCHAR
* dir
,
42 _Pre_maybenull_ _Post_z_ _TCHAR
* fname
,
43 _Pre_maybenull_ _Post_z_ _TCHAR
* ext
)
46 const _TCHAR
*src
, *dir_start
, *file_start
= 0, *ext_start
= 0;
49 const size_t drive_size
= INT_MAX
, dir_size
= INT_MAX
,
50 fname_size
= INT_MAX
, ext_size
= INT_MAX
;
54 /* Validate parameters */
55 if (MSVCRT_CHECK_PMT((path
== NULL
) ||
56 ((drive
!= NULL
) && (drive_size
== 0)) ||
57 ((dir
!= NULL
) && (dir_size
== 0)) ||
58 ((fname
!= NULL
) && (fname_size
== 0)) ||
59 ((ext
!= NULL
) && (ext_size
== 0))))
66 /* Truncate all output strings */
67 if (drive
) drive
[0] = '\0';
68 if (dir
) dir
[0] = '\0';
69 if (fname
) fname
[0] = '\0';
70 if (ext
) ext
[0] = '\0';
83 _Analysis_assume_(path
!= 0);
86 /* Skip '\\?\' prefix */
87 if ((path
[0] == '\\') && (path
[1] == '\\') &&
88 (path
[2] == '?') && (path
[3] == '\\')) path
+= 4;
91 if (path
[0] == '\0') return _FAILURE
;
93 /* Check if we have a drive letter (only 1 char supported) */
96 if (drive
&& (drive_size
>= 3))
105 /* Scan the rest of the string */
107 while (*path
!= '\0')
109 #if !defined(_UNICODE) && !defined(_LIBCNT_)
110 /* Check for multibyte lead bytes */
111 if (_ismbblead((unsigned char)*path
))
113 /* Check for unexpected end of string */
114 if (path
[1] == 0) break;
116 /* Skip the lead byte and the following byte */
121 /* Remember last path separator and last dot */
122 if ((*path
== '\\') || (*path
== '/')) file_start
= path
+ 1;
123 if (*path
== '.') ext_start
= path
;
127 /* Check if we got a file name / extension */
129 file_start
= dir_start
;
130 if (!ext_start
|| (ext_start
< file_start
))
136 count
= dir_size
- 1;
137 while ((src
< file_start
) && count
--) *dir
++ = *src
++;
144 count
= fname_size
- 1;
145 while (src
< ext_start
&& count
--) *fname
++ = *src
++;
152 count
= ext_size
- 1;
153 while (*src
!= '\0' && count
--) *ext
++ = *src
++;