ReactOS  0.4.13-dev-73-gcfe54aa
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  */
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 
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
GLsizei const GLchar ** path
Definition: glext.h:7234
Definition: arc.h:39
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
const char * filename
Definition: ioapi.h:135
GLsizeiptr size
Definition: glext.h:5919
_CRTIMP int *__cdecl _errno(void)
Definition: errno.c:19
#define ERANGE
Definition: acclib.h:92
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
GLenum GLint * range
Definition: glext.h:7539
#define CDECL
Definition: compat.h:21
Definition: services.c:325
#define min(a, b)
Definition: monoChain.cc:55
GLfloat GLfloat p
Definition: glext.h:8902