1 #include <windows.h>
2 #include <malloc.h>
3 #include <errno.h>
4 #include <msvcrt.h>
5
6 static errno_t __cdecl _int_memcpy_s (void *, size_t, const void *, size_t);
7 static errno_t __cdecl _stub (void *, size_t, const void *, size_t);
8
9 errno_t __cdecl (*__MINGW_IMP_SYMBOL(memcpy_s))(void *, size_t, const void *, size_t) =
10 _stub;
11
12 static errno_t __cdecl
_stub(void * d,size_t dn,const void * s,size_t n)13 _stub (void *d, size_t dn, const void *s, size_t n)
14 {
15 errno_t __cdecl (*f)(void *, size_t, const void *, size_t) = __MINGW_IMP_SYMBOL(memcpy_s);
16
17 if (f == _stub)
18 {
19 f = (errno_t __cdecl (*)(void *, size_t, const void *, size_t))
20 GetProcAddress (__mingw_get_msvcrt_handle (), "memcpy_s");
21 if (!f)
22 f = _int_memcpy_s;
23 __MINGW_IMP_SYMBOL(memcpy_s) = f;
24 }
25 return (*f)(d, dn, s, n);
26 }
27
28 errno_t __cdecl
memcpy_s(void * d,size_t dn,const void * s,size_t n)29 memcpy_s (void *d, size_t dn, const void *s, size_t n)
30 {
31 return _stub (d, dn, s, n);
32 }
33
34 static errno_t __cdecl
_int_memcpy_s(void * d,size_t dn,const void * s,size_t n)35 _int_memcpy_s (void *d, size_t dn, const void *s, size_t n)
36 {
37 if (!n)
38 return 0;
39
40 if (!d || !s)
41 {
42 if (d)
43 memset (d, 0, dn);
44 errno = EINVAL;
45 return EINVAL;
46 }
47
48 if (dn < n)
49 {
50 memset (d, 0, dn);
51
52 errno = ERANGE;
53 return ERANGE;
54 }
55
56 memcpy (d, s, n);
57
58 return 0;
59 }
60