ReactOS 0.4.16-dev-125-g798ea90
wmakpath_s.c
Go to the documentation of this file.
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 */
23int 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
116range:
117 path[0] = '\0';
118 *_errno() = ERANGE;
119 return ERANGE;
120}
121
#define EINVAL
Definition: acclib.h:90
#define ERANGE
Definition: acclib.h:92
#define CDECL
Definition: compat.h:29
GLsizeiptr size
Definition: glext.h:5919
GLenum GLint * range
Definition: glext.h:7539
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
const char * filename
Definition: ioapi.h:137
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define min(a, b)
Definition: monoChain.cc:55
#define strlenW(s)
Definition: unicode.h:34
_CRTIMP int *__cdecl _errno(void)
Definition: errno.c:17
int CDECL _wmakepath_s(wchar_t *path, size_t size, const wchar_t *drive, const wchar_t *directory, const wchar_t *filename, const wchar_t *extension)
Definition: wmakpath_s.c:23