mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 04:39:45 +00:00
msvcr100: Added fread_s implementation.
This commit is contained in:
parent
436edbdfc7
commit
101abcd8b1
@ -25,6 +25,7 @@
|
||||
#include "stdlib.h"
|
||||
#include "errno.h"
|
||||
#include "malloc.h"
|
||||
#include "limits.h"
|
||||
#include "sys/stat.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
@ -403,6 +404,59 @@ unsigned __int64 CDECL _byteswap_uint64(unsigned __int64 i)
|
||||
((i>>8)&0xFF000000) + ((i>>24)&0xFF0000) + ((i>>40)&0xFF00) + (i>>56);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* fread_s (MSVCR100.@)
|
||||
*/
|
||||
size_t CDECL fread_s(void *buf, size_t buf_size, size_t elem_size, size_t count, FILE *stream)
|
||||
{
|
||||
size_t bytes_left, buf_pos;
|
||||
|
||||
TRACE("(%p %lu %lu %lu %p\n", buf, (unsigned long)buf_size,
|
||||
(unsigned long)elem_size, (unsigned long)count, stream);
|
||||
|
||||
|
||||
if(!CHECK_PMT(stream != NULL)) {
|
||||
if(buf && buf_size)
|
||||
memset(buf, 0, buf_size);
|
||||
return 0;
|
||||
}
|
||||
if(!elem_size || !count) return 0;
|
||||
if(!CHECK_PMT(buf != NULL)) return 0;
|
||||
if(!CHECK_PMT(SIZE_MAX/count >= elem_size)) return 0;
|
||||
|
||||
bytes_left = elem_size*count;
|
||||
buf_pos = 0;
|
||||
while(bytes_left) {
|
||||
if(stream->_cnt > 0) {
|
||||
size_t size = bytes_left<stream->_cnt ? bytes_left : stream->_cnt;
|
||||
|
||||
if(!CHECK_PMT_ERR(size <= buf_size-buf_pos, ERANGE)) {
|
||||
memset(buf, 0, buf_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fread((char*)buf+buf_pos, 1, size, stream);
|
||||
buf_pos += size;
|
||||
bytes_left -= size;
|
||||
}else {
|
||||
int c = _filbuf(stream);
|
||||
|
||||
if(c == EOF)
|
||||
break;
|
||||
|
||||
if(!CHECK_PMT_ERR(buf_size-buf_pos > 0, ERANGE)) {
|
||||
memset(buf, 0, buf_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
((char*)buf)[buf_pos++] = c;
|
||||
bytes_left--;
|
||||
}
|
||||
}
|
||||
|
||||
return buf_pos/elem_size;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* DllMain (MSVCR100.@)
|
||||
*/
|
||||
|
@ -1669,7 +1669,7 @@
|
||||
@ cdecl fputwc(long ptr) msvcrt.fputwc
|
||||
@ cdecl fputws(wstr ptr) msvcrt.fputws
|
||||
@ cdecl fread(ptr long long ptr) msvcrt.fread
|
||||
@ stub fread_s
|
||||
@ cdecl fread_s(ptr long long long ptr)
|
||||
@ cdecl free(ptr) msvcrt.free
|
||||
@ cdecl freopen(str str ptr) msvcrt.freopen
|
||||
@ cdecl freopen_s(ptr str str ptr) msvcrt.freopen_s
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
@ -68,6 +69,9 @@ static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
|
||||
static int* (__cdecl *p_errno)(void);
|
||||
static int (__cdecl *p_wmemcpy_s)(wchar_t *dest, size_t numberOfElements, const wchar_t *src, size_t count);
|
||||
static int (__cdecl *p_wmemmove_s)(wchar_t *dest, size_t numberOfElements, const wchar_t *src, size_t count);
|
||||
static FILE* (__cdecl *p_fopen)(const char*,const char*);
|
||||
static int (__cdecl *p_fclose)(FILE*);
|
||||
static size_t (__cdecl *p_fread_s)(void*,size_t,size_t,size_t,FILE*);
|
||||
|
||||
/* make sure we use the correct errno */
|
||||
#undef errno
|
||||
@ -91,6 +95,9 @@ static BOOL init(void)
|
||||
SET(p_set_invalid_parameter_handler, "_set_invalid_parameter_handler");
|
||||
SET(p_wmemcpy_s, "wmemcpy_s");
|
||||
SET(p_wmemmove_s, "wmemmove_s");
|
||||
SET(p_fopen, "fopen");
|
||||
SET(p_fclose, "fclose");
|
||||
SET(p_fread_s, "fread_s");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -247,6 +254,78 @@ static void test_wmemmove_s(void)
|
||||
"Cannot reset invalid parameter handler\n");
|
||||
}
|
||||
|
||||
static void test_fread_s(void)
|
||||
{
|
||||
static const char test_file[] = "fread_s.tst";
|
||||
int ret;
|
||||
char buf[10];
|
||||
|
||||
FILE *f = fopen(test_file, "w");
|
||||
if(!f) {
|
||||
skip("Error creating test file\n");
|
||||
return;
|
||||
}
|
||||
fwrite("test", 1, 4, f);
|
||||
fclose(f);
|
||||
|
||||
ok(p_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
|
||||
"Invalid parameter handler was already set\n");
|
||||
|
||||
SET_EXPECT(invalid_parameter_handler);
|
||||
errno = 0xdeadbeef;
|
||||
ret = p_fread_s(buf, sizeof(buf), 1, 1, NULL);
|
||||
ok(ret == 0, "fread_s returned %d, expected 0\n", ret);
|
||||
ok(errno == EINVAL, "errno = %d, expected EINVAL\n", errno);
|
||||
CHECK_CALLED(invalid_parameter_handler);
|
||||
|
||||
f = p_fopen(test_file, "r");
|
||||
errno = 0xdeadbeef;
|
||||
ret = p_fread_s(NULL, sizeof(buf), 0, 1, f);
|
||||
ok(ret == 0, "fread_s returned %d, expected 0\n", ret);
|
||||
ok(errno == 0xdeadbeef, "errno = %d, expected 0xdeadbeef\n", errno);
|
||||
ret = p_fread_s(NULL, sizeof(buf), 1, 0, f);
|
||||
ok(ret == 0, "fread_s returned %d, expected 0\n", ret);
|
||||
ok(errno == 0xdeadbeef, "errno = %d, expected 0xdeadbeef\n", errno);
|
||||
|
||||
SET_EXPECT(invalid_parameter_handler);
|
||||
errno = 0xdeadbeef;
|
||||
ret = p_fread_s(NULL, sizeof(buf), 1, 1, f);
|
||||
ok(ret == 0, "fread_s returned %d, expected 0\n", ret);
|
||||
ok(errno == EINVAL, "errno = %d, expected EINVAL\n", errno);
|
||||
CHECK_CALLED(invalid_parameter_handler);
|
||||
|
||||
SET_EXPECT(invalid_parameter_handler);
|
||||
errno = 0xdeadbeef;
|
||||
buf[1] = 'a';
|
||||
ret = p_fread_s(buf, 3, 1, 10, f);
|
||||
ok(ret == 0, "fread_s returned %d, expected 0\n", ret);
|
||||
ok(buf[0] == 0, "buf[0] = '%c', expected 0\n", buf[0]);
|
||||
ok(buf[1] == 0, "buf[1] = '%c', expected 0\n", buf[1]);
|
||||
ok(errno == ERANGE, "errno = %d, expected ERANGE\n", errno);
|
||||
CHECK_CALLED(invalid_parameter_handler);
|
||||
|
||||
SET_EXPECT(invalid_parameter_handler);
|
||||
errno = 0xdeadbeef;
|
||||
ret = p_fread_s(buf, 2, 1, 10, f);
|
||||
ok(ret == 0, "fread_s returned %d, expected 0\n", ret);
|
||||
ok(buf[0] == 0, "buf[0] = '%c', expected 0\n", buf[0]);
|
||||
ok(errno == ERANGE, "errno = %d, expected ERANGE\n", errno);
|
||||
CHECK_CALLED(invalid_parameter_handler);
|
||||
|
||||
memset(buf, 'a', sizeof(buf));
|
||||
ret = p_fread_s(buf, sizeof(buf), 3, 10, f);
|
||||
ok(ret==1, "fread_s returned %d, expected 1\n", ret);
|
||||
ok(buf[0] == 'e', "buf[0] = '%c', expected 'e'\n", buf[0]);
|
||||
ok(buf[1] == 's', "buf[1] = '%c', expected 's'\n", buf[1]);
|
||||
ok(buf[2] == 't', "buf[2] = '%c', expected 't'\n", buf[2]);
|
||||
ok(buf[3] == 'a', "buf[3] = '%c', expected 'a'\n", buf[3]);
|
||||
p_fclose(f);
|
||||
|
||||
ok(p_set_invalid_parameter_handler(NULL) == test_invalid_parameter_handler,
|
||||
"Cannot reset invalid parameter handler\n");
|
||||
unlink(test_file);
|
||||
}
|
||||
|
||||
START_TEST(msvcr100)
|
||||
{
|
||||
if (!init())
|
||||
@ -254,4 +333,5 @@ START_TEST(msvcr100)
|
||||
|
||||
test_wmemcpy_s();
|
||||
test_wmemmove_s();
|
||||
test_fread_s();
|
||||
}
|
||||
|
@ -1323,7 +1323,7 @@
|
||||
@ cdecl fputwc(long ptr) msvcrt.fputwc
|
||||
@ cdecl fputws(wstr ptr) msvcrt.fputws
|
||||
@ cdecl fread(ptr long long ptr) msvcrt.fread
|
||||
@ stub fread_s
|
||||
@ cdecl fread_s(ptr long long long ptr) msvcr100.fread_s
|
||||
@ cdecl free(ptr) msvcrt.free
|
||||
@ cdecl freopen(str str ptr) msvcrt.freopen
|
||||
@ cdecl freopen_s(ptr str str ptr) msvcrt.freopen_s
|
||||
|
@ -1324,7 +1324,7 @@
|
||||
@ cdecl fputwc(long ptr) msvcrt.fputwc
|
||||
@ cdecl fputws(wstr ptr) msvcrt.fputws
|
||||
@ cdecl fread(ptr long long ptr) msvcrt.fread
|
||||
@ stub fread_s
|
||||
@ cdecl fread_s(ptr long long long ptr) msvcr100.fread_s
|
||||
@ cdecl free(ptr) msvcrt.free
|
||||
@ cdecl freopen(str str ptr) msvcrt.freopen
|
||||
@ cdecl freopen_s(ptr str str ptr) msvcrt.freopen_s
|
||||
|
@ -38,4 +38,12 @@
|
||||
#define I64_MAX _I64_MAX
|
||||
#define UI64_MAX _UI64_MAX
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
# ifdef _WIN64
|
||||
# define SIZE_MAX UI64_MAX
|
||||
# else
|
||||
# define SIZE_MAX UINT_MAX
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* __WINE_LIMITS_H */
|
||||
|
Loading…
Reference in New Issue
Block a user