1 /* 2 * PROJECT: ReactOS CRT library 3 * LICENSE: See COPYING in the top level directory 4 * FILE: lib/sdk/crt/stdlib/makepath_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 * _makepath_s (MSVCRT.@) 20 * 21 * Safe version of _makepath. 22 */ 23 int CDECL _makepath_s(char *path, size_t size, const char *drive, 24 const char *directory, const char *filename, 25 const char *extension) 26 { 27 char *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 = strlen(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); 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 = strlen(filename); 75 size_t copylen = min(size - 1, len); 76 77 if (size < 2) 78 goto range; 79 80 memmove(p, filename, copylen); 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 = strlen(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); 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