Commit 101abcd8 authored by Piotr Caban's avatar Piotr Caban Committed by Alexandre Julliard

msvcr100: Added fread_s implementation.

parent 436edbdf
......@@ -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"
......@@ -404,6 +405,59 @@ unsigned __int64 CDECL _byteswap_uint64(unsigned __int64 i)
}
/*********************************************************************
* 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.@)
*/
BOOL WINAPI DllMain(HINSTANCE hdll, DWORD reason, LPVOID reserved)
......
......@@ -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 */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment