[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