ReactOS 0.4.16-dev-835-gd769f56
makepath.cpp
Go to the documentation of this file.
1//
2// makepath.cpp
3//
4// Copyright (c) Microsoft Corporation. All rights reserved.
5//
6// Defines the makepath family of functions, which compose a path string.
7//
9#include <mbstring.h>
10#include <stdlib.h>
11
12
13
14static char const* previous_character(char const* const first, char const* const current) throw()
15{
16 return reinterpret_cast<char const*>(_mbsdec(
17 reinterpret_cast<unsigned char const*>(first),
18 reinterpret_cast<unsigned char const*>(current)));
19}
20
21static wchar_t const* previous_character(wchar_t const*, wchar_t const* const current) throw()
22{
23 return current - 1;
24}
25
26
27
28template <typename Character>
30 _Out_writes_z_(count) Character* const buffer,
31 size_t const count) throw()
32{
33 // This is referenced only in the Debug CRT build
35
38 return EINVAL; // This is unreachable
39}
40
41
42
43// These functions compose a path string from its component parts. They
44// concatenate the drive, directory, file_name, and extension into the provided
45// result_buffer. For the functions that do not have a buffer count parameter,
46// the buffer is assumed to be large enough to hold however many characters are
47// required.
48//
49// The drive may or may not contain a ':'. The directory may or may not contain
50// a leading or trailing '/' or '\'. The extension may or may not contain a
51// leading '.'.
52template <typename Character>
54 _Out_writes_z_(result_count) Character* const result_buffer,
55 _In_ size_t const result_count,
56 _In_opt_z_ Character const* const drive,
57 _In_opt_z_ Character const* const directory,
58 _In_opt_z_ Character const* const file_name,
59 _In_opt_z_ Character const* const extension
60 ) throw()
61{
62 _VALIDATE_STRING(result_buffer, result_count);
63
64 Character* result_it = result_buffer;
65
66 // For the non-secure makepath functions, result_count is _CRT_UNBOUNDED_BUFFER_SIZE.
67 // In this case, we do not want to perform arithmetic with the result_count. Instead,
68 // we set the result_end to nullptr: result_it will never be a null pointer,
69 // and when we need to perform arithmetic with result_end we can check it for
70 // null first.
71 Character* const result_end = result_count != _CRT_UNBOUNDED_BUFFER_SIZE
72 ? result_buffer + result_count
73 : nullptr;
74
75 CRT_WARNING_DISABLE_PUSH(26015, "Silence prefast about overflow - covered by result_end for secure callers")
76
77 // Copy the drive:
78 if (drive && drive[0] != '\0')
79 {
80 if (result_end != nullptr && result_end - result_it < 2)
81 return cleanup_after_error(result_buffer, result_count);
82
83 *result_it++ = *drive;
84 *result_it++ = ':';
85 }
86
87 // Copy the directory:
88 if (directory && directory[0] != '\0')
89 {
90 Character const* source_it = directory;
91 while (*source_it != '\0')
92 {
93 if ((result_end != nullptr) && (result_it >= result_end))
94 return cleanup_after_error(result_buffer, result_count);
95
96 *result_it++ = *source_it++;
97 }
98
99 // Write a trailing backslash if there isn't one:
100 source_it = previous_character(directory, source_it);
101 if (*source_it != '/' && *source_it != '\\')
102 {
103 if ((result_end != nullptr) && (result_it >= result_end))
104 return cleanup_after_error(result_buffer, result_count);
105
106 *result_it++ = '\\';
107 }
108 }
109
110 // Copy the file name:
111 if (file_name)
112 {
113 Character const* source_it = file_name;
114 while (*source_it != '\0')
115 {
116 if ((result_end != nullptr) && (result_it >= result_end))
117 return cleanup_after_error(result_buffer, result_count);
118
119 *result_it++ = *source_it++;
120 }
121 }
122
123 // Copy the extension:
124 if (extension)
125 {
126 // Add a '.' if one is required:
127 if (extension[0] != '\0' && extension[0] != '.')
128 {
129 if ((result_end != nullptr) && (result_it >= result_end))
130 return cleanup_after_error(result_buffer, result_count);
131
132 *result_it++ = '.';
133 }
134
135 Character const* source_it = extension;
136 while (*source_it != '\0')
137 {
138 if ((result_end != nullptr) && (result_it >= result_end))
139 return cleanup_after_error(result_buffer, result_count);
140
141 *result_it++ = *source_it++;
142 }
143 }
144
145 // Copy the null terminator:
146 if ((result_end != nullptr) && (result_it >= result_end))
147 return cleanup_after_error(result_buffer, result_count);
148
149 *result_it++ = '\0';
150
152
153 _FILL_STRING(result_buffer, result_count, result_it - result_buffer);
154 return 0;
155}
156
157
158
159extern "C" void __cdecl _makepath(
160 char* const result_buffer,
161 char const* const drive,
162 char const* const directory,
163 char const* const file_name,
164 char const* const extension
165 )
166{
168}
169
170extern "C" void __cdecl _wmakepath(
171 wchar_t* const result_buffer,
172 wchar_t const* const drive,
173 wchar_t const* const directory,
174 wchar_t const* const file_name,
175 wchar_t const* const extension
176 )
177{
179}
180
181
182
184 char* const result_buffer,
185 size_t const result_count,
186 char const* const drive,
187 char const* const directory,
188 char const* const file_name,
189 char const* const extension
190 )
191{
192 return common_makepath_s(result_buffer, result_count, drive, directory, file_name, extension);
193}
194
196 wchar_t* const result_buffer,
197 size_t const result_count,
198 wchar_t const* const drive,
199 wchar_t const* const directory,
200 wchar_t const* const file_name,
201 wchar_t const* const extension
202 )
203{
204 return common_makepath_s(result_buffer, result_count, drive, directory, file_name, extension);
205}
#define EINVAL
Definition: acclib.h:90
#define __cdecl
Definition: accygwin.h:79
#define _CRT_UNBOUNDED_BUFFER_SIZE
#define _FILL_STRING
#define _RETURN_BUFFER_TOO_SMALL(_String, _Size)
#define _RESET_STRING(_String, _Size)
#define _VALIDATE_STRING(_String, _Size)
result_buffer_count char *const result_buffer
Definition: cvt.cpp:111
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint buffer
Definition: glext.h:5915
const GLint * first
Definition: glext.h:5794
_Check_return_ _CRTIMP unsigned char *__cdecl _mbsdec(_In_reads_z_(_Pos-_Start+1) const unsigned char *_Start, _In_z_ const unsigned char *_Pos)
_makepath
Definition: stdlib.h:1096
#define CRT_WARNING_DISABLE_PUSH(wn, message)
#define CRT_WARNING_POP
static char const * previous_character(char const *const first, char const *const current)
Definition: makepath.cpp:14
static errno_t __cdecl cleanup_after_error(_Out_writes_z_(count) Character *const buffer, size_t const count)
Definition: makepath.cpp:29
static errno_t __cdecl common_makepath_s(_Out_writes_z_(result_count) Character *const result_buffer, _In_ size_t const result_count, _In_opt_z_ Character const *const drive, _In_opt_z_ Character const *const directory, _In_opt_z_ Character const *const file_name, _In_opt_z_ Character const *const extension)
Definition: makepath.cpp:53
void __cdecl _wmakepath(wchar_t *const result_buffer, wchar_t const *const drive, wchar_t const *const directory, wchar_t const *const file_name, wchar_t const *const extension)
Definition: makepath.cpp:170
errno_t __cdecl _makepath_s(char *const result_buffer, size_t const result_count, char const *const drive, char const *const directory, char const *const file_name, char const *const extension)
Definition: makepath.cpp:183
errno_t __cdecl _wmakepath_s(wchar_t *const result_buffer, size_t const result_count, wchar_t const *const drive, wchar_t const *const directory, wchar_t const *const file_name, wchar_t const *const extension)
Definition: makepath.cpp:195
struct task_struct * current
Definition: linux.c:32
static LPCWSTR file_name
Definition: protocol.c:147
#define _Out_writes_z_(s)
Definition: no_sal2.h:180
#define _In_opt_z_
Definition: no_sal2.h:218
#define _In_
Definition: no_sal2.h:158
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
int errno_t
Definition: corecrt.h:615
#define const
Definition: zconf.h:233