1 /*
2 * PROJECT: ReactOS CRT library
3 * LICENSE: See COPYING in the top level directory
4 * FILE: lib/sdk/crt/stdlib/wmakpath_s.c
5 * PURPOSE: Creates a path
6 * PROGRAMMERS: Wine team
7 * Copyright 1996,1998 Marcus Meissner
8 * Copyright 1996 Jukka Iivonen
9 * Copyright 1997,2000 Uwe Bonnes
10 * Copyright 2000 Jon Griffiths
11 *
12 */
13
14 #include <precomp.h>
15 #include <stdlib.h>
16 #include <string.h>
17
18 /*********************************************************************
19 * _wmakepath_s (MSVCRT.@)
20 *
21 * Safe version of _wmakepath.
22 */
_wmakepath_s(wchar_t * path,size_t size,const wchar_t * drive,const wchar_t * directory,const wchar_t * filename,const wchar_t * extension)23 int CDECL _wmakepath_s(wchar_t *path, size_t size, const wchar_t *drive,
24 const wchar_t *directory, const wchar_t *filename,
25 const wchar_t *extension)
26 {
27 wchar_t *p = path;
28
29 if (!path || !size)
30 {
31 *_errno() = EINVAL;
32 return EINVAL;
33 }
34
35 if (drive && drive[0])
36 {
37 if (size <= 2)
38 goto range;
39
40 *p++ = drive[0];
41 *p++ = ':';
42 size -= 2;
43 }
44
45 if (directory && directory[0])
46 {
47 size_t len = strlenW(directory);
48 unsigned int needs_separator = directory[len - 1] != '/' && directory[len - 1] != '\\';
49 size_t copylen = min(size - 1, len);
50
51 if (size < 2)
52 goto range;
53
54 memmove(p, directory, copylen * sizeof(wchar_t));
55
56 if (size <= len)
57 goto range;
58
59 p += copylen;
60 size -= copylen;
61
62 if (needs_separator)
63 {
64 if (size < 2)
65 goto range;
66
67 *p++ = '\\';
68 size -= 1;
69 }
70 }
71
72 if (filename && filename[0])
73 {
74 size_t len = strlenW(filename);
75 size_t copylen = min(size - 1, len);
76
77 if (size < 2)
78 goto range;
79
80 memmove(p, filename, copylen * sizeof(wchar_t));
81
82 if (size <= len)
83 goto range;
84
85 p += len;
86 size -= len;
87 }
88
89 if (extension && extension[0])
90 {
91 size_t len = strlenW(extension);
92 unsigned int needs_period = extension[0] != '.';
93 size_t copylen;
94
95 if (size < 2)
96 goto range;
97
98 if (needs_period)
99 {
100 *p++ = '.';
101 size -= 1;
102 }
103
104 copylen = min(size - 1, len);
105 memcpy(p, extension, copylen * sizeof(wchar_t));
106
107 if (size <= len)
108 goto range;
109
110 p += copylen;
111 }
112
113 *p = '\0';
114 return 0;
115
116 range:
117 path[0] = '\0';
118 *_errno() = ERANGE;
119 return ERANGE;
120 }
121
122