Commit 899d9a04 authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

msvcrt: Added _splitpath_s implementation.

parent ed2a02b7
...@@ -1116,7 +1116,7 @@ ...@@ -1116,7 +1116,7 @@
@ cdecl _spawnvp(long str ptr) msvcrt._spawnvp @ cdecl _spawnvp(long str ptr) msvcrt._spawnvp
@ cdecl _spawnvpe(long str ptr ptr) msvcrt._spawnvpe @ cdecl _spawnvpe(long str ptr ptr) msvcrt._spawnvpe
@ cdecl _splitpath(str ptr ptr ptr ptr) msvcrt._splitpath @ cdecl _splitpath(str ptr ptr ptr ptr) msvcrt._splitpath
@ stub _splitpath_s @ cdecl _splitpath_s(str ptr long ptr long ptr long ptr long) msvcrt._splitpath_s
@ stub _sprintf_l @ stub _sprintf_l
@ stub _sprintf_p @ stub _sprintf_p
@ stub _sprintf_p_l @ stub _sprintf_p_l
......
...@@ -970,7 +970,7 @@ ...@@ -970,7 +970,7 @@
@ cdecl _spawnvp(long str ptr) msvcrt._spawnvp @ cdecl _spawnvp(long str ptr) msvcrt._spawnvp
@ cdecl _spawnvpe(long str ptr ptr) msvcrt._spawnvpe @ cdecl _spawnvpe(long str ptr ptr) msvcrt._spawnvpe
@ cdecl _splitpath(str ptr ptr ptr ptr) msvcrt._splitpath @ cdecl _splitpath(str ptr ptr ptr ptr) msvcrt._splitpath
@ stub _splitpath_s @ cdecl _splitpath_s(str ptr long ptr long ptr long ptr long) msvcrt._splitpath_s
@ stub _sprintf_l @ stub _sprintf_l
@ stub _sprintf_p @ stub _sprintf_p
@ stub _sprintf_p_l @ stub _sprintf_p_l
......
...@@ -956,7 +956,7 @@ ...@@ -956,7 +956,7 @@
@ cdecl _spawnvp(long str ptr) msvcrt._spawnvp @ cdecl _spawnvp(long str ptr) msvcrt._spawnvp
@ cdecl _spawnvpe(long str ptr ptr) msvcrt._spawnvpe @ cdecl _spawnvpe(long str ptr ptr) msvcrt._spawnvpe
@ cdecl _splitpath(str ptr ptr ptr ptr) msvcrt._splitpath @ cdecl _splitpath(str ptr ptr ptr ptr) msvcrt._splitpath
@ stub _splitpath_s @ cdecl _splitpath_s(str ptr long ptr long ptr long ptr long) msvcrt._splitpath_s
@ stub _sprintf_l @ stub _sprintf_l
@ stub _sprintf_p @ stub _sprintf_p
@ stub _sprintf_p_l @ stub _sprintf_p_l
......
...@@ -745,27 +745,42 @@ int CDECL _wrmdir(const MSVCRT_wchar_t * dir) ...@@ -745,27 +745,42 @@ int CDECL _wrmdir(const MSVCRT_wchar_t * dir)
return -1; return -1;
} }
/********************************************************************* /******************************************************************
* _wsplitpath (MSVCRT.@) * _splitpath_s (MSVCRT.@)
*
* Unicode version of _splitpath.
*/ */
void CDECL _wsplitpath(const MSVCRT_wchar_t *inpath, MSVCRT_wchar_t *drv, MSVCRT_wchar_t *dir, int _splitpath_s(const char* inpath,
MSVCRT_wchar_t *fname, MSVCRT_wchar_t *ext ) char* drive, MSVCRT_size_t sz_drive,
char* dir, MSVCRT_size_t sz_dir,
char* fname, MSVCRT_size_t sz_fname,
char* ext, MSVCRT_size_t sz_ext)
{ {
const MSVCRT_wchar_t *p, *end; const char *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))
{
*MSVCRT__errno() = MSVCRT_EINVAL;
return MSVCRT_EINVAL;
}
if (inpath[0] && inpath[1] == ':') if (inpath[0] && inpath[1] == ':')
{ {
if (drv) if (drive)
{ {
drv[0] = inpath[0]; if (sz_drive <= 2) goto do_error;
drv[1] = inpath[1]; drive[0] = inpath[0];
drv[2] = 0; drive[1] = inpath[1];
drive[2] = 0;
} }
inpath += 2; inpath += 2;
} }
else if (drv) drv[0] = 0; else if (drive) drive[0] = '\0';
/* look for end of directory part */ /* look for end of directory part */
end = NULL; end = NULL;
...@@ -775,7 +790,8 @@ void CDECL _wsplitpath(const MSVCRT_wchar_t *inpath, MSVCRT_wchar_t *drv, MSVCRT ...@@ -775,7 +790,8 @@ void CDECL _wsplitpath(const MSVCRT_wchar_t *inpath, MSVCRT_wchar_t *drv, MSVCRT
{ {
if (dir) if (dir)
{ {
memcpy( dir, inpath, (end - inpath) * sizeof(MSVCRT_wchar_t) ); if (sz_dir <= end - inpath) goto do_error;
memcpy( dir, inpath, (end - inpath) );
dir[end - inpath] = 0; dir[end - inpath] = 0;
} }
inpath = end; inpath = end;
...@@ -790,10 +806,33 @@ void CDECL _wsplitpath(const MSVCRT_wchar_t *inpath, MSVCRT_wchar_t *drv, MSVCRT ...@@ -790,10 +806,33 @@ void CDECL _wsplitpath(const MSVCRT_wchar_t *inpath, MSVCRT_wchar_t *drv, MSVCRT
if (fname) if (fname)
{ {
memcpy( fname, inpath, (end - inpath) * sizeof(MSVCRT_wchar_t) ); if (sz_fname <= end - inpath) goto do_error;
memcpy( fname, inpath, (end - inpath) );
fname[end - inpath] = 0; fname[end - inpath] = 0;
} }
if (ext) strcpyW( ext, end ); if (ext)
{
if (sz_ext <= strlen(end)) goto do_error;
strcpy( ext, end );
}
return 0;
do_error:
if (drive) drive[0] = '\0';
if (dir) dir[0] = '\0';
if (fname) fname[0]= '\0';
if (ext) ext[0]= '\0';
*MSVCRT__errno() = MSVCRT_ERANGE;
return MSVCRT_ERANGE;
}
/*********************************************************************
* _splitpath (MSVCRT.@)
*/
void CDECL _splitpath(const char *inpath, char *drv, char *dir,
char *fname, char *ext)
{
_splitpath_s(inpath, drv, MSVCRT__MAX_DRIVE, dir, MSVCRT__MAX_DIR,
fname, MSVCRT__MAX_FNAME, ext, MSVCRT__MAX_EXT);
} }
/****************************************************************** /******************************************************************
...@@ -809,15 +848,18 @@ int _wsplitpath_s(const MSVCRT_wchar_t* inpath, ...@@ -809,15 +848,18 @@ int _wsplitpath_s(const MSVCRT_wchar_t* inpath,
{ {
const MSVCRT_wchar_t *p, *end; const MSVCRT_wchar_t *p, *end;
if (!inpath) return MSVCRT_EINVAL; if (!inpath || (!drive && sz_drive) ||
if (!drive && sz_drive) return MSVCRT_EINVAL; (drive && !sz_drive) ||
if (drive && !sz_drive) return MSVCRT_EINVAL; (!dir && sz_dir) ||
if (!dir && sz_dir) return MSVCRT_EINVAL; (dir && !sz_dir) ||
if (dir && !sz_dir) return MSVCRT_EINVAL; (!fname && sz_fname) ||
if (!fname && sz_fname) return MSVCRT_EINVAL; (fname && !sz_fname) ||
if (fname && !sz_fname) return MSVCRT_EINVAL; (!ext && sz_ext) ||
if (!ext && sz_ext) return MSVCRT_EINVAL; (ext && !sz_ext))
if (ext && !sz_ext) return MSVCRT_EINVAL; {
*MSVCRT__errno() = MSVCRT_EINVAL;
return MSVCRT_EINVAL;
}
if (inpath[0] && inpath[1] == ':') if (inpath[0] && inpath[1] == ':')
{ {
...@@ -871,10 +913,23 @@ do_error: ...@@ -871,10 +913,23 @@ do_error:
if (dir) dir[0] = '\0'; if (dir) dir[0] = '\0';
if (fname) fname[0]= '\0'; if (fname) fname[0]= '\0';
if (ext) ext[0]= '\0'; if (ext) ext[0]= '\0';
*MSVCRT__errno() = MSVCRT_ERANGE;
return MSVCRT_ERANGE; return MSVCRT_ERANGE;
} }
/********************************************************************* /*********************************************************************
* _wsplitpath (MSVCRT.@)
*
* Unicode version of _splitpath.
*/
void CDECL _wsplitpath(const MSVCRT_wchar_t *inpath, MSVCRT_wchar_t *drv, MSVCRT_wchar_t *dir,
MSVCRT_wchar_t *fname, MSVCRT_wchar_t *ext)
{
_wsplitpath_s(inpath, drv, MSVCRT__MAX_DRIVE, dir, MSVCRT__MAX_DIR,
fname, MSVCRT__MAX_FNAME, ext, MSVCRT__MAX_EXT);
}
/*********************************************************************
* _wfullpath (MSVCRT.@) * _wfullpath (MSVCRT.@)
* *
* Unicode version of _fullpath. * Unicode version of _fullpath.
......
...@@ -47,6 +47,11 @@ ...@@ -47,6 +47,11 @@
#define MSVCRT_I64_MIN (-MSVCRT_I64_MAX-1) #define MSVCRT_I64_MIN (-MSVCRT_I64_MAX-1)
#define MSVCRT_UI64_MAX (((unsigned __int64)0xffffffff << 32) | 0xffffffff) #define MSVCRT_UI64_MAX (((unsigned __int64)0xffffffff << 32) | 0xffffffff)
#define MSVCRT__MAX_DRIVE 3
#define MSVCRT__MAX_DIR 256
#define MSVCRT__MAX_FNAME 256
#define MSVCRT__MAX_EXT 256
typedef unsigned short MSVCRT_wchar_t; typedef unsigned short MSVCRT_wchar_t;
typedef unsigned short MSVCRT_wint_t; typedef unsigned short MSVCRT_wint_t;
typedef unsigned short MSVCRT_wctype_t; typedef unsigned short MSVCRT_wctype_t;
......
...@@ -892,8 +892,8 @@ ...@@ -892,8 +892,8 @@
@ cdecl _spawnve(long str ptr ptr) MSVCRT__spawnve @ cdecl _spawnve(long str ptr ptr) MSVCRT__spawnve
@ cdecl _spawnvp(long str ptr) @ cdecl _spawnvp(long str ptr)
@ cdecl _spawnvpe(long str ptr ptr) MSVCRT__spawnvpe @ cdecl _spawnvpe(long str ptr ptr) MSVCRT__spawnvpe
@ cdecl _splitpath(str ptr ptr ptr ptr) ntdll._splitpath @ cdecl _splitpath(str ptr ptr ptr ptr)
# stub _splitpath_s @ cdecl _splitpath_s(str ptr long ptr long ptr long ptr long)
# stub _sprintf_l # stub _sprintf_l
# stub _sprintf_p_l # stub _sprintf_p_l
# stub _sprintf_s_l # stub _sprintf_s_l
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment