Nikolay Sivov : ucrtbase: Added _sopen_dispatch/_wsopen_dispatch.

Alexandre Julliard julliard at winehq.org
Mon Oct 31 14:41:10 CDT 2016


Module: wine
Branch: master
Commit: cc77571898cde37829816707793d2c3c649d6bd8
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=cc77571898cde37829816707793d2c3c649d6bd8

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Sat Oct 29 20:22:27 2016 +0300

ucrtbase: Added _sopen_dispatch/_wsopen_dispatch.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 .../api-ms-win-crt-stdio-l1-1-0.spec               |  4 +-
 dlls/msvcrt/file.c                                 | 40 ++++++++---
 dlls/ucrtbase/tests/misc.c                         | 81 ++++++++++++++++++++++
 dlls/ucrtbase/ucrtbase.spec                        |  4 +-
 4 files changed, 114 insertions(+), 15 deletions(-)

diff --git a/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec b/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec
index 4b8be01..6acd08e 100644
--- a/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec
+++ b/dlls/api-ms-win-crt-stdio-l1-1-0/api-ms-win-crt-stdio-l1-1-0.spec
@@ -87,7 +87,7 @@
 @ cdecl _setmaxstdio(long) ucrtbase._setmaxstdio
 @ cdecl _setmode(long long) ucrtbase._setmode
 @ varargs _sopen(str long long) ucrtbase._sopen
-@ stub _sopen_dispatch
+@ cdecl _sopen_dispatch(str long long long ptr long) ucrtbase._sopen_dispatch
 @ cdecl _sopen_s(ptr str long long long) ucrtbase._sopen_s
 @ cdecl _tell(long) ucrtbase._tell
 @ cdecl -ret64 _telli64(long) ucrtbase._telli64
@@ -107,7 +107,7 @@
 @ cdecl _wpopen(wstr wstr) ucrtbase._wpopen
 @ cdecl _write(long ptr long) ucrtbase._write
 @ varargs _wsopen(wstr long long) ucrtbase._wsopen
-@ stub _wsopen_dispatch
+@ cdecl _wsopen_dispatch(wstr long long long ptr long) ucrtbase._wsopen_dispatch
 @ cdecl _wsopen_s(ptr wstr long long long) ucrtbase._wsopen_s
 @ cdecl _wtempnam(wstr wstr) ucrtbase._wtempnam
 @ cdecl _wtmpnam(ptr) ucrtbase._wtmpnam
diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c
index 432d5c7..8965156 100644
--- a/dlls/msvcrt/file.c
+++ b/dlls/msvcrt/file.c
@@ -2144,9 +2144,10 @@ static int check_bom(HANDLE h, int oflags, BOOL seek)
 }
 
 /*********************************************************************
- *              _wsopen_s (MSVCRT.@)
+ *              _wsopen_dispatch (UCRTBASE.@)
  */
-int CDECL MSVCRT__wsopen_s( int *fd, const MSVCRT_wchar_t* path, int oflags, int shflags, int pmode )
+int CDECL MSVCRT__wsopen_dispatch( const MSVCRT_wchar_t* path, int oflags, int shflags, int pmode,
+    int *fd, int secure )
 {
   DWORD access = 0, creation = 0, attrib;
   SECURITY_ATTRIBUTES sa;
@@ -2154,8 +2155,8 @@ int CDECL MSVCRT__wsopen_s( int *fd, const MSVCRT_wchar_t* path, int oflags, int
   int wxflag;
   HANDLE hand;
 
-  TRACE("fd*: %p :file (%s) oflags: 0x%04x shflags: 0x%04x pmode: 0x%04x\n",
-        fd, debugstr_w(path), oflags, shflags, pmode);
+  TRACE("path: (%s) oflags: 0x%04x shflags: 0x%04x pmode: 0x%04x fd*: %p secure: %d\n",
+        debugstr_w(path), oflags, shflags, pmode, fd, secure);
 
   if (!MSVCRT_CHECK_PMT( fd != NULL )) return MSVCRT_EINVAL;
 
@@ -2306,6 +2307,15 @@ int CDECL MSVCRT__wsopen_s( int *fd, const MSVCRT_wchar_t* path, int oflags, int
   return 0;
 }
 
+
+/*********************************************************************
+ *              _wsopen_s (MSVCRT.@)
+ */
+int CDECL MSVCRT__wsopen_s( int *fd, const MSVCRT_wchar_t* path, int oflags, int shflags, int pmode )
+{
+    return MSVCRT__wsopen_dispatch( path, oflags, shflags, pmode, fd, 1 );
+}
+
 /*********************************************************************
  *              _wsopen (MSVCRT.@)
  */
@@ -2325,14 +2335,15 @@ int CDECL MSVCRT__wsopen( const MSVCRT_wchar_t *path, int oflags, int shflags, .
   else
     pmode = 0;
 
-  MSVCRT__wsopen_s(&fd, path, oflags, shflags, pmode);
-  return fd;
+  return MSVCRT__wsopen_dispatch(path, oflags, shflags, pmode, &fd, 0) ? -1 : fd;
 }
 
+
 /*********************************************************************
- *              _sopen_s (MSVCRT.@)
+ *              _sopen_dispatch (UCRTBASE.@)
  */
-int CDECL MSVCRT__sopen_s( int *fd, const char *path, int oflags, int shflags, int pmode )
+int CDECL MSVCRT__sopen_dispatch( const char *path, int oflags, int shflags,
+    int pmode, int *fd, int secure)
 {
     MSVCRT_wchar_t *pathW;
     int ret;
@@ -2343,12 +2354,20 @@ int CDECL MSVCRT__sopen_s( int *fd, const char *path, int oflags, int shflags, i
     if(!MSVCRT_CHECK_PMT(path && (pathW = msvcrt_wstrdupa(path))))
         return MSVCRT_EINVAL;
 
-    ret = MSVCRT__wsopen_s(fd, pathW, oflags, shflags, pmode);
+    ret = MSVCRT__wsopen_dispatch(pathW, oflags, shflags, pmode, fd, secure);
     MSVCRT_free(pathW);
     return ret;
 }
 
 /*********************************************************************
+ *              _sopen_s (MSVCRT.@)
+ */
+int CDECL MSVCRT__sopen_s( int *fd, const char *path, int oflags, int shflags, int pmode )
+{
+    return MSVCRT__sopen_dispatch(path, oflags, shflags, pmode, fd, 1);
+}
+
+/*********************************************************************
  *              _sopen (MSVCRT.@)
  */
 int CDECL MSVCRT__sopen( const char *path, int oflags, int shflags, ... )
@@ -2367,8 +2386,7 @@ int CDECL MSVCRT__sopen( const char *path, int oflags, int shflags, ... )
   else
     pmode = 0;
 
-  MSVCRT__sopen_s(&fd, path, oflags, shflags, pmode);
-  return fd;
+  return MSVCRT__sopen_dispatch(path, oflags, shflags, pmode, &fd, 0) ? -1 : fd;
 }
 
 /*********************************************************************
diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c
index ad22699..cc82022 100644
--- a/dlls/ucrtbase/tests/misc.c
+++ b/dlls/ucrtbase/tests/misc.c
@@ -22,6 +22,10 @@
 #include <wchar.h>
 #include <stdio.h>
 #include <float.h>
+#include <io.h>
+#include <sys/stat.h>
+#include <share.h>
+#include <fcntl.h>
 
 #include <windef.h>
 #include <winbase.h>
@@ -74,6 +78,8 @@ static _invalid_parameter_handler (CDECL *p__set_thread_local_invalid_parameter_
 static _invalid_parameter_handler (CDECL *p__get_thread_local_invalid_parameter_handler)(void);
 static int (CDECL *p__ltoa_s)(LONG, char*, size_t, int);
 static char* (CDECL *p__get_narrow_winmain_command_line)(void);
+static int (CDECL *p_sopen_dispatch)(const char *, int, int, int, int *, int);
+static int (CDECL *p_sopen_s)(int *, const char *, int, int, int);
 
 static void test__initialize_onexit_table(void)
 {
@@ -365,10 +371,83 @@ static BOOL init(void)
     p__get_thread_local_invalid_parameter_handler = (void*)GetProcAddress(module, "_get_thread_local_invalid_parameter_handler");
     p__ltoa_s = (void*)GetProcAddress(module, "_ltoa_s");
     p__get_narrow_winmain_command_line = (void*)GetProcAddress(GetModuleHandleA("ucrtbase.dll"), "_get_narrow_winmain_command_line");
+    p_sopen_dispatch = (void*)GetProcAddress(module, "_sopen_dispatch");
+    p_sopen_s = (void*)GetProcAddress(module, "_sopen_s");
 
     return TRUE;
 }
 
+static void test__sopen_dispatch(void)
+{
+    int ret, fd;
+    char *tempf;
+
+    tempf = _tempnam(".", "wne");
+
+    fd = 0;
+    ret = p_sopen_dispatch(tempf, _O_CREAT, _SH_DENYWR, 0xff, &fd, 0);
+    ok(!ret, "got %d\n", ret);
+    ok(fd > 0, "got fd %d\n", fd);
+    _close(fd);
+    unlink(tempf);
+
+    p__set_invalid_parameter_handler(global_invalid_parameter_handler);
+
+    SET_EXPECT(global_invalid_parameter_handler);
+    fd = 0;
+    ret = p_sopen_dispatch(tempf, _O_CREAT, _SH_DENYWR, 0xff, &fd, 1);
+todo_wine {
+    ok(ret == EINVAL, "got %d\n", ret);
+    ok(fd == -1, "got fd %d\n", fd);
+    CHECK_CALLED(global_invalid_parameter_handler);
+}
+    if (fd > 0)
+    {
+        _close(fd);
+        unlink(tempf);
+    }
+
+    p__set_invalid_parameter_handler(NULL);
+
+    free(tempf);
+}
+
+static void test__sopen_s(void)
+{
+    int ret, fd;
+    char *tempf;
+
+    tempf = _tempnam(".", "wne");
+
+    fd = 0;
+    ret = p_sopen_s(&fd, tempf, _O_CREAT, _SH_DENYWR, 0);
+    ok(!ret, "got %d\n", ret);
+    ok(fd > 0, "got fd %d\n", fd);
+    _close(fd);
+    unlink(tempf);
+
+    /* _open() does not validate pmode */
+    fd = _open(tempf, _O_CREAT, 0xff);
+    ok(fd > 0, "got fd %d\n", fd);
+    _close(fd);
+    unlink(tempf);
+
+    p__set_invalid_parameter_handler(global_invalid_parameter_handler);
+
+    /* _sopen_s() invokes invalid parameter handler on invalid pmode */
+    SET_EXPECT(global_invalid_parameter_handler);
+    fd = 0;
+    ret = p_sopen_s(&fd, tempf, _O_CREAT, _SH_DENYWR, 0xff);
+todo_wine {
+    ok(ret == EINVAL, "got %d\n", ret);
+    ok(fd == -1, "got fd %d\n", fd);
+    CHECK_CALLED(global_invalid_parameter_handler);
+}
+    p__set_invalid_parameter_handler(NULL);
+
+    free(tempf);
+}
+
 START_TEST(misc)
 {
     int arg_c;
@@ -389,4 +468,6 @@ START_TEST(misc)
     test__execute_onexit_table();
     test___fpe_flt_rounds();
     test__get_narrow_winmain_command_line(arg_v[0]);
+    test__sopen_dispatch();
+    test__sopen_s();
 }
diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec
index f0598ce..47608f9 100644
--- a/dlls/ucrtbase/ucrtbase.spec
+++ b/dlls/ucrtbase/ucrtbase.spec
@@ -1902,7 +1902,7 @@
 @ stub _setsystime(ptr long)
 @ cdecl _sleep(long) MSVCRT__sleep
 @ varargs _sopen(str long long) MSVCRT__sopen
-@ stub _sopen_dispatch
+@ cdecl _sopen_dispatch(str long long long ptr long) MSVCRT__sopen_dispatch
 @ cdecl _sopen_s(ptr str long long long) MSVCRT__sopen_s
 @ varargs _spawnl(long str str)
 @ varargs _spawnle(long str str)
@@ -2109,7 +2109,7 @@
 @ cdecl _wsearchenv_s(wstr wstr ptr long) MSVCRT__wsearchenv_s
 @ cdecl _wsetlocale(long wstr) MSVCRT__wsetlocale
 @ varargs _wsopen(wstr long long) MSVCRT__wsopen
-@ stub _wsopen_dispatch
+@ cdecl _wsopen_dispatch(wstr long long long ptr long) MSVCRT__wsopen_dispatch
 @ cdecl _wsopen_s(ptr wstr long long long) MSVCRT__wsopen_s
 @ varargs _wspawnl(long wstr wstr)
 @ varargs _wspawnle(long wstr wstr)




More information about the wine-cvs mailing list