Reactos
1/***
2*mbscpy_s_l.c - Copy one string to another (MBCS)
3*
4* Copyright (c) Microsoft Corporation. All rights reserved.
5*
6*Purpose:
7* Copy one string to another (MBCS)
8*
9*******************************************************************************/
10#ifndef _MBCS
11 #error This file should only be compiled with _MBCS defined
12#endif
13
14#include <corecrt_internal_mbstring.h>
15#include <corecrt_internal_securecrt.h>
16
17errno_t __cdecl _mbscpy_s_l(unsigned char *_Dst, size_t _SizeInBytes, const unsigned char *_Src, _LOCALE_ARG_DECL)
18{
19 unsigned char *p;
20 size_t available;
21 BOOL fIsLeadPrefix;
22
23 /* validation section */
24 _VALIDATE_STRING(_Dst, _SizeInBytes);
25 _VALIDATE_POINTER_RESET_STRING(_Src, _Dst, _SizeInBytes);
26
27 _LOCALE_UPDATE;
28 if (_LOCALE_SHORTCUT_TEST)
29 {
30 return strcpy_s((char *)_Dst, _SizeInBytes, (const char *)_Src);
31 }
32
33 p = _Dst;
34 available = _SizeInBytes;
35 while ((*p++ = *_Src++) != 0 && --available > 0)
36 {
37 }
38
39 /*
40 * If we ran out of destination bytes then we did so before copying null.
41 * Only exception to that is if last mbc was invalid (leadbyte+null), which
42 * is treated as null. In that case clear the copied lead byte and return ok.
43 */
44
45 if (available == 0)
46 {
47 if (*_Src == 0) {
48 _ISMBBLEADPREFIX(fIsLeadPrefix,_Dst,p-1);
49 if (fIsLeadPrefix)
50 {
51 p[-1] = 0;
52 _RETURN_MBCS_ERROR;
53 }
54 }
55 _RESET_STRING(_Dst, _SizeInBytes);
56 _RETURN_BUFFER_TOO_SMALL(_Dst, _SizeInBytes);
57 }
58
59 /*
60 * Otherwise we have space left in the dst buffer and stopped copying because
61 * we saw a null in the src. If null is part of invalid MBC (lead byte + null)
62 * then clear the lead byte also.
63 */
64
65 _ISMBBLEADPREFIX(fIsLeadPrefix, _Dst, p-2);
66 if (fIsLeadPrefix && (p - 2) >= _Dst)
67 {
68 p[-2] = 0;
69 available++;
70 _FILL_STRING(_Dst, _SizeInBytes, _SizeInBytes - available + 1);
71 _RETURN_MBCS_ERROR;
72 }
73
74 _FILL_STRING(_Dst, _SizeInBytes, _SizeInBytes - available + 1);
75 _RETURN_NO_ERROR;
76}