Module: wine Branch: master Commit: 0db689edf4a2d05db05449a3ca21c0e6c088880f URL: https://source.winehq.org/git/wine.git/?a=commit;h=0db689edf4a2d05db05449a3c...
Author: Alexandre Julliard julliard@winehq.org Date: Thu Jun 30 11:06:29 2022 +0200
ntdll: Add _wsplitpath_s.
Implementation copied from msvcrt.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/ntdll.spec | 1 + dlls/ntdll/wcstring.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index a3832042704..9291ed63f77 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -1554,6 +1554,7 @@ @ cdecl -ret64 _wcstoui64(wstr ptr long) @ cdecl _wcsupr(wstr) @ cdecl _wcsupr_s(wstr long) +@ cdecl _wsplitpath_s(wstr ptr long ptr long ptr long ptr long) @ cdecl _wtoi(wstr) @ cdecl -ret64 _wtoi64(wstr) @ cdecl _wtol(wstr) diff --git a/dlls/ntdll/wcstring.c b/dlls/ntdll/wcstring.c index a0d7042f30c..76190c08c12 100644 --- a/dlls/ntdll/wcstring.c +++ b/dlls/ntdll/wcstring.c @@ -1299,3 +1299,79 @@ LONGLONG __cdecl _wtoi64( LPCWSTR str )
return bMinus ? -RunningTotal : RunningTotal; } + + +/****************************************************************** + * _wsplitpath_s (NTDLL.@) + */ +errno_t __cdecl _wsplitpath_s( const wchar_t *inpath, wchar_t *drive, size_t sz_drive, + wchar_t *dir, size_t sz_dir, wchar_t *fname, size_t sz_fname, + wchar_t *ext, size_t sz_ext ) +{ + const wchar_t *p, *end; + + if (!inpath || (!drive && sz_drive) || + (drive && !sz_drive) || + (!dir && sz_dir) || + (dir && !sz_dir) || + (!fname && sz_fname) || + (fname && !sz_fname) || + (!ext && sz_ext) || + (ext && !sz_ext)) + return EINVAL; + + if (inpath[0] && inpath[1] == ':') + { + if (drive) + { + if (sz_drive <= 2) goto error; + drive[0] = inpath[0]; + drive[1] = inpath[1]; + drive[2] = 0; + } + inpath += 2; + } + else if (drive) drive[0] = '\0'; + + /* look for end of directory part */ + end = NULL; + for (p = inpath; *p; p++) if (*p == '/' || *p == '\') end = p + 1; + + if (end) /* got a directory */ + { + if (dir) + { + if (sz_dir <= end - inpath) goto error; + memcpy( dir, inpath, (end - inpath) * sizeof(wchar_t) ); + dir[end - inpath] = 0; + } + inpath = end; + } + else if (dir) dir[0] = 0; + + /* look for extension: what's after the last dot */ + end = NULL; + for (p = inpath; *p; p++) if (*p == '.') end = p; + + if (!end) end = p; /* there's no extension */ + + if (fname) + { + if (sz_fname <= end - inpath) goto error; + memcpy( fname, inpath, (end - inpath) * sizeof(wchar_t) ); + fname[end - inpath] = 0; + } + if (ext) + { + if (sz_ext <= wcslen(end)) goto error; + wcscpy( ext, end ); + } + return 0; + +error: + if (drive) drive[0] = 0; + if (dir) dir[0] = 0; + if (fname) fname[0]= 0; + if (ext) ext[0]= 0; + return ERANGE; +}