[2/2] msvcr90: Implement fread_s.
Kusanagi Kouichi
slash at ac.auone-net.jp
Wed Dec 21 09:49:52 CST 2011
Signed-off-by: Kusanagi Kouichi <slash at ac.auone-net.jp>
---
dlls/msvcr100/msvcr100.spec | 2 +-
dlls/msvcr80/msvcr80.spec | 2 +-
dlls/msvcr90/msvcr90.c | 25 +++++++++++++++
dlls/msvcr90/msvcr90.spec | 2 +-
dlls/msvcr90/tests/msvcr90.c | 70 ++++++++++++++++++++++++++++++++++++++++++
5 files changed, 98 insertions(+), 3 deletions(-)
diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec
index b4266bf..07303c8 100644
--- a/dlls/msvcr100/msvcr100.spec
+++ b/dlls/msvcr100/msvcr100.spec
@@ -1466,7 +1466,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) msvcr90.fread_s
@ cdecl free(ptr) msvcrt.free
@ cdecl freopen(str str ptr) msvcrt.freopen
@ cdecl freopen_s(ptr str str ptr) msvcrt.freopen_s
diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec
index 1dabc60..374dfd0 100644
--- a/dlls/msvcr80/msvcr80.spec
+++ b/dlls/msvcr80/msvcr80.spec
@@ -1322,7 +1322,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) msvcr90.fread_s
@ cdecl free(ptr) msvcrt.free
@ cdecl freopen(str str ptr) msvcrt.freopen
@ cdecl freopen_s(ptr str str ptr) msvcrt.freopen_s
diff --git a/dlls/msvcr90/msvcr90.c b/dlls/msvcr90/msvcr90.c
index e07beb3..564fc53 100644
--- a/dlls/msvcr90/msvcr90.c
+++ b/dlls/msvcr90/msvcr90.c
@@ -29,6 +29,7 @@
#include "winbase.h"
#include "wine/debug.h"
#include "sys/stat.h"
+#include "stdio.h"
WINE_DEFAULT_DEBUG_CHANNEL(msvcr90);
@@ -375,3 +376,27 @@ int CDECL _fclose_nolock(FILE *fp)
FIXME("stub\n");
return fclose(fp);
}
+
+/*********************************************************************
+ * fread_s (MSVCRT.@)
+ */
+int CDECL fread_s(char * const buf, const size_t bufsize, const size_t size, const size_t count, FILE * const fp)
+{
+ if (size == 0 || count == 0)
+ return 0;
+
+ if (!buf || !fp)
+ {
+ _invalid_parameter(NULL, NULL, NULL, 0, 0);
+ return 0;
+ }
+
+ if (bufsize / size < count)
+ {
+ _invalid_parameter(NULL, NULL, NULL, 0, 0);
+ fseek(fp, bufsize, SEEK_CUR);
+ return 0;
+ }
+
+ return fread(buf, size, count, fp);
+}
diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec
index 2bc2f3c..0ac05b4 100644
--- a/dlls/msvcr90/msvcr90.spec
+++ b/dlls/msvcr90/msvcr90.spec
@@ -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)
@ cdecl free(ptr) msvcrt.free
@ cdecl freopen(str str ptr) msvcrt.freopen
@ cdecl freopen_s(ptr str str ptr) msvcrt.freopen_s
diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c
index 09b4a40..7f597a7 100644
--- a/dlls/msvcr90/tests/msvcr90.c
+++ b/dlls/msvcr90/tests/msvcr90.c
@@ -109,6 +109,10 @@ static int (__cdecl *p_fileno)(FILE*);
static int (__cdecl *p_feof)(FILE*);
static int (__cdecl *p_ferror)(FILE*);
static int (__cdecl *p_flsbuf)(int, FILE*);
+static int (__cdecl *p_fopen_s)(FILE**, const char*, const char*);
+static int (__cdecl *p_fread_s)(char *, size_t, size_t, size_t, FILE *);
+static __int64 (__cdecl *p__ftelli64)(FILE *);
+static int (__cdecl *p__fclose_nolock)(FILE *);
/* type info */
@@ -296,6 +300,10 @@ static BOOL init(void)
SET(p_type_info_name_internal_method, "?_name_internal_method at type_info@@QBEPBDPAU__type_info_node@@@Z");
SET(ptype_info_dtor, "??1type_info@@UAE at XZ");
}
+ SET(p_fopen_s, "fopen_s");
+ SET(p_fread_s, "fread_s");
+ SET(p__ftelli64, "_ftelli64");
+ SET(p__fclose_nolock, "_fclose_nolock");
hkernel32 = GetModuleHandleA("kernel32.dll");
pEncodePointer = (void *) GetProcAddress(hkernel32, "EncodePointer");
@@ -1137,6 +1145,67 @@ static void test_nonblocking_file_access(void)
p_unlink("test_file");
}
+static void test_fread_s( void )
+{
+ const char name[] = "empty1";
+ char buff[sizeof name];
+ FILE *file;
+ int ret;
+
+ if (!p_fopen_s || !p_fread_s || !p__ftelli64 || !p__fclose_nolock)
+ {
+ skip("fopen_s, fread_s, _ftelli64 or _fclose_nolock is not available\n");
+ return;
+ }
+
+ file = fopen(name, "w");
+ ok(file != 0, "fopen failed\n");
+ ret = fwrite(name, sizeof(name), 1, file);
+ ok(ret == 1, "fwrite failed\n");
+ ret = fclose(file);
+ ok(ret != EOF, "File failed to close\n");
+
+ /* fread_s raises an exeption if a file was opened by fopen */
+ ret = p_fopen_s(&file, name, "rb");
+ ok(ret == 0, "fopen_s failed with %d\n", ret);
+ ok(file != 0, "fopen_s failed to return value\n");
+
+ ret = p_fread_s(NULL, 0, 0, 1, NULL);
+ ok(ret == 0, "read %d items, expected 0\n", ret);
+
+ ret = p_fread_s(NULL, 0, 1, 0, NULL);
+ ok(ret == 0, "read %d items, expected 0\n", ret);
+
+ SET_EXPECT(invalid_parameter_handler);
+ ret = p_fread_s(buff, 1, 1, 1, NULL);
+ ok(ret == 0, "read %d items, expected 0\n", ret);
+ CHECK_CALLED(invalid_parameter_handler);
+
+ SET_EXPECT(invalid_parameter_handler);
+ ret = p_fread_s(NULL, 1, 1, 1, file);
+ ok(ret == 0, "read %d items, expected 0\n", ret);
+ CHECK_CALLED(invalid_parameter_handler);
+
+ SET_EXPECT(invalid_parameter_handler);
+ ret = p_fread_s(buff, 1, sizeof name, 1, file);
+ ok(ret == 0, "read %d items, expected 0\n", ret);
+ CHECK_CALLED(invalid_parameter_handler);
+
+ /* ftell raises an exeption */
+ ret = p__ftelli64(file);
+ ok(ret == 1, "File position should be 1 but %d\n", ret);
+
+ ret = p_fread_s(buff, sizeof buff - 1, 1, sizeof name - 1, file);
+ ok(ret == sizeof name - 1, "read %d items, expected %lu\n", ret, sizeof name - 1);
+ ok(strcmp(name + 1, buff) == 0, "File content mismatch! Got \"%s\", expected \"%s\"\n", buff, name);
+
+ /* fclose raises an exception if a file was opened by fopen_s */
+ ret = p__fclose_nolock(file);
+ ok(ret != EOF, "File failed to close\n");
+
+ ok(_unlink(name) == 0, "Couldn't unlink file named '%s', errno = %d (%#x)\n", name, errno, errno);
+}
+
START_TEST(msvcr90)
{
if(!init())
@@ -1159,4 +1228,5 @@ START_TEST(msvcr90)
test_getptd();
test__vswprintf_l();
test_nonblocking_file_access();
+ test_fread_s();
}
--
1.7.7.3
More information about the wine-patches
mailing list