msvcr90: Add semi-stub fread_s implementation. (try 3)

Kusanagi Kouichi slash at ac.auone-net.jp
Fri Dec 23 09:30:20 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       |   33 +++++++++++++++++++
 dlls/msvcr90/msvcr90.spec    |    2 +-
 dlls/msvcr90/tests/msvcr90.c |   71 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 107 insertions(+), 3 deletions(-)

diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec
index 38ec0e1..64f177c 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 a083053..61f7be9 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 6b97e2f..8dbc068 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);
 
@@ -366,3 +367,35 @@ int CDECL MSVCR90__vswprintf_p(wchar_t *buffer, size_t length, const wchar_t *fo
 {
     return _vswprintf_p_l(buffer, length, format, NULL, args);
 }
+
+/*********************************************************************
+ *		fread_s (MSVCR90.@)
+ */
+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)
+  {
+    _invalid_parameter(NULL, NULL, NULL, 0, 0);
+    if (bufsize)
+      errno = EINVAL;
+    return 0;
+  }
+
+  if (!fp)
+  {
+    _invalid_parameter(NULL, NULL, NULL, 0, 0);
+    memset(buf, 0, bufsize);
+    return 0;
+  }
+
+  if (bufsize / size < count)
+  {
+    FIXME("buffer size is insufficient\n");
+    return -1;
+  }
+
+  return fread(buf, size, count, fp);
+}
diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec
index 475e3a9..9f34fc5 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..f41e9bc 100644
--- a/dlls/msvcr90/tests/msvcr90.c
+++ b/dlls/msvcr90/tests/msvcr90.c
@@ -109,6 +109,7 @@ 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_fread_s)(char *, size_t, size_t, size_t, FILE *);
 
 
 /* type info */
@@ -296,6 +297,7 @@ 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_fread_s, "fread_s");
 
     hkernel32 = GetModuleHandleA("kernel32.dll");
     pEncodePointer = (void *) GetProcAddress(hkernel32, "EncodePointer");
@@ -1137,6 +1139,74 @@ static void test_nonblocking_file_access(void)
     p_unlink("test_file");
 }
 
+static void test_fread_s( void )
+{
+    static const char name[] = "empty1", aaa[sizeof name] = "aaaaaa", zero[sizeof name];
+    char buff[sizeof name];
+    FILE *file;
+    int ret;
+
+    if (!p_fread_s)
+    {
+        skip("fread_s 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");
+
+    file = fopen(name, "rb");
+    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);
+    errno = 0;
+    ret = p_fread_s(NULL, 0, 1, 1, NULL);
+    ok(errno == 0, "errno was set to %d\n", errno);
+    ok(ret == 0, "read %d items, expected 0\n", ret);
+    CHECK_CALLED(invalid_parameter_handler);
+
+    ret = ftell(file);
+    ok(ret == 0, "File position should be 0 but %d\n", ret);
+
+    strcpy(buff, aaa);
+    SET_EXPECT(invalid_parameter_handler);
+    ret = p_fread_s(buff, 1, sizeof name, 1, NULL);
+    ok(ret == 0, "read %d items, expected 0\n", ret);
+    CHECK_CALLED(invalid_parameter_handler);
+    ok(buff[0] == 0, "Buffer should be filled with 0\n");
+    ok(memcmp(buff + 1, aaa + 1, sizeof name - 1) == 0, "Rest of buffer should not be modified\n");
+
+    strcpy(buff, aaa);
+    SET_EXPECT(invalid_parameter_handler);
+    ret = p_fread_s(buff, 1, 1, sizeof name, NULL);
+    ok(ret == 0, "read %d items, expected 0\n", ret);
+    CHECK_CALLED(invalid_parameter_handler);
+    ok(buff[0] == 0, "Buffer should be filled with 0\n");
+    ok(memcmp(buff + 1, aaa + 1, sizeof name - 1) == 0, "Rest of buffer should not be modified\n");
+
+    strcpy(buff, aaa);
+    SET_EXPECT(invalid_parameter_handler);
+    ret = p_fread_s(buff, sizeof name, 1, 1, NULL);
+    ok(ret == 0, "read %d items, expected 0\n", ret);
+    CHECK_CALLED(invalid_parameter_handler);
+    ok(memcmp(buff, zero, sizeof name) == 0, "Buffer should be filled with 0\n");
+
+    ret = fclose(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 +1229,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