Nikolay Sivov : msvcrt: Implement _wsopen_s.

Alexandre Julliard julliard at winehq.org
Thu Jan 27 12:43:19 CST 2011


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Thu Jan 27 01:56:30 2011 +0300

msvcrt: Implement _wsopen_s.

---

 dlls/msvcr100/msvcr100.spec  |    2 +-
 dlls/msvcr80/msvcr80.spec    |    2 +-
 dlls/msvcr90/msvcr90.spec    |    2 +-
 dlls/msvcr90/tests/msvcr90.c |   35 ++++++++++++++++++++++++-
 dlls/msvcrt/file.c           |   57 ++++++++++++++++++++++++++++++-----------
 dlls/msvcrt/msvcrt.spec      |    4 +-
 6 files changed, 79 insertions(+), 23 deletions(-)

diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec
index a601f23..d079728 100644
--- a/dlls/msvcr100/msvcr100.spec
+++ b/dlls/msvcr100/msvcr100.spec
@@ -1382,7 +1382,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_s
+@ cdecl _wsopen_s(ptr wstr long long long) msvcrt._wsopen_s
 @ varargs _wspawnl(long wstr wstr) msvcrt._wspawnl
 @ varargs _wspawnle(long wstr wstr) msvcrt._wspawnle
 @ varargs _wspawnlp(long wstr wstr) msvcrt._wspawnlp
diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec
index b4787ad..3ece44c 100644
--- a/dlls/msvcr80/msvcr80.spec
+++ b/dlls/msvcr80/msvcr80.spec
@@ -1238,7 +1238,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_s
+@ cdecl _wsopen_s(ptr wstr long long long) msvcrt._wsopen_s
 @ varargs _wspawnl(long wstr wstr) msvcrt._wspawnl
 @ varargs _wspawnle(long wstr wstr) msvcrt._wspawnle
 @ varargs _wspawnlp(long wstr wstr) msvcrt._wspawnlp
diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec
index 809265b..38cf0fb 100644
--- a/dlls/msvcr90/msvcr90.spec
+++ b/dlls/msvcr90/msvcr90.spec
@@ -1222,7 +1222,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_s
+@ cdecl _wsopen_s(ptr wstr long long long) msvcrt._wsopen_s
 @ varargs _wspawnl(long wstr wstr) msvcrt._wspawnl
 @ varargs _wspawnle(long wstr wstr) msvcrt._wspawnle
 @ varargs _wspawnlp(long wstr wstr) msvcrt._wspawnlp
diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c
index 35995f4..eeb8842 100644
--- a/dlls/msvcr90/tests/msvcr90.c
+++ b/dlls/msvcr90/tests/msvcr90.c
@@ -74,6 +74,7 @@ static int (__cdecl *p_controlfp_s)(unsigned int *, unsigned int, unsigned int);
 static int (__cdecl *p_atoflt)(_CRT_FLOAT *, char *);
 static unsigned int (__cdecl *p_set_abort_behavior)(unsigned int, unsigned int);
 static int (__cdecl *p_sopen_s)(int*, const char*, int, int, int);
+static int (__cdecl *p_wsopen_s)(int*, const wchar_t*, int, int, int);
 
 static void* (WINAPI *pEncodePointer)(void *);
 
@@ -709,10 +710,16 @@ static void test__set_abort_behavior(void)
     p_set_abort_behavior(_WRITE_ABORT_MSG | _CALL_REPORTFAULT, 0xffffffff);
 }
 
-static void test_sopen_s(void)
+static void test__sopen_s(void)
 {
     int ret, fd;
 
+    if(!p_sopen_s)
+    {
+        win_skip("_sopen_s not found\n");
+        return;
+    }
+
     SET_EXPECT(invalid_parameter_handler);
     ret = p_sopen_s(NULL, "test", _O_RDONLY, _SH_DENYNO, _S_IREAD);
     ok(ret == EINVAL, "got %d, expected EINVAL\n", ret);
@@ -724,6 +731,28 @@ static void test_sopen_s(void)
     ok(fd == -1, "got %d\n", fd);
 }
 
+static void test__wsopen_s(void)
+{
+    wchar_t testW[] = {'t','e','s','t',0};
+    int ret, fd;
+
+    if(!p_wsopen_s)
+    {
+        win_skip("_wsopen_s not found\n");
+        return;
+    }
+
+    SET_EXPECT(invalid_parameter_handler);
+    ret = p_wsopen_s(NULL, testW, _O_RDONLY, _SH_DENYNO, _S_IREAD);
+    ok(ret == EINVAL, "got %d, expected EINVAL\n", ret);
+    CHECK_CALLED(invalid_parameter_handler);
+
+    fd = 0xdead;
+    ret = p_wsopen_s(&fd, testW, _O_RDONLY, _SH_DENYNO, _S_IREAD);
+    ok(ret == ENOENT, "got %d, expected ENOENT\n", ret);
+    ok(fd == -1, "got %d\n", fd);
+}
+
 START_TEST(msvcr90)
 {
     HMODULE hcrt;
@@ -758,6 +787,7 @@ START_TEST(msvcr90)
     p_atoflt = (void* )GetProcAddress(hcrt, "_atoflt");
     p_set_abort_behavior = (void *) GetProcAddress(hcrt, "_set_abort_behavior");
     p_sopen_s = (void*) GetProcAddress(hcrt, "_sopen_s");
+    p_wsopen_s = (void*) GetProcAddress(hcrt, "_wsopen_s");
 
     hkernel32 = GetModuleHandleA("kernel32.dll");
     pEncodePointer = (void *) GetProcAddress(hkernel32, "EncodePointer");
@@ -772,5 +802,6 @@ START_TEST(msvcr90)
     test_controlfp_s();
     test__atoflt();
     test__set_abort_behavior();
-    test_sopen_s();
+    test__sopen_s();
+    test__wsopen_s();
 }
diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c
index d56700b..b8077d2 100644
--- a/dlls/msvcrt/file.c
+++ b/dlls/msvcrt/file.c
@@ -1632,22 +1632,27 @@ int CDECL MSVCRT__sopen( const char *path, int oflags, int shflags, ... )
 }
 
 /*********************************************************************
- *              _wsopen (MSVCRT.@)
+ *              _wsopen_s (MSVCRT.@)
  */
-int CDECL MSVCRT__wsopen( const MSVCRT_wchar_t* path, int oflags, int shflags, ... )
+int CDECL MSVCRT__wsopen_s( int *fd, const MSVCRT_wchar_t* path, int oflags, int shflags, int pmode )
 {
-  __ms_va_list ap;
-  int pmode;
   DWORD access = 0, creation = 0, attrib;
+  SECURITY_ATTRIBUTES sa;
   DWORD sharing;
-  int wxflag = 0, fd;
+  int wxflag;
   HANDLE hand;
-  SECURITY_ATTRIBUTES sa;
 
+  TRACE("fd*: %p :file (%s) oflags: 0x%04x shflags: 0x%04x pmode: 0x%04x\n",
+        fd, debugstr_w(path), oflags, shflags, pmode);
 
-  TRACE(":file (%s) oflags: 0x%04x shflags: 0x%04x\n",
-        debugstr_w(path), oflags, shflags);
+  if (!fd)
+  {
+    MSVCRT_INVALID_PMT("null out fd pointer");
+    *MSVCRT__errno() = MSVCRT_EINVAL;
+    return MSVCRT_EINVAL;
+  }
 
+  *fd = -1;
   wxflag = split_oflags(oflags);
   switch (oflags & (MSVCRT__O_RDONLY | MSVCRT__O_WRONLY | MSVCRT__O_RDWR))
   {
@@ -1658,10 +1663,6 @@ int CDECL MSVCRT__wsopen( const MSVCRT_wchar_t* path, int oflags, int shflags, .
 
   if (oflags & MSVCRT__O_CREAT)
   {
-    __ms_va_start(ap, shflags);
-    pmode = va_arg(ap, int);
-    __ms_va_end(ap);
-
     if(pmode & ~(MSVCRT__S_IREAD | MSVCRT__S_IWRITE))
       FIXME(": pmode 0x%04x ignored\n", pmode);
     else
@@ -1698,7 +1699,7 @@ int CDECL MSVCRT__wsopen( const MSVCRT_wchar_t* path, int oflags, int shflags, .
       break;
     default:
       ERR( "Unhandled shflags 0x%x\n", shflags );
-      return -1;
+      return MSVCRT_EINVAL;
   }
   attrib = FILE_ATTRIBUTE_NORMAL;
 
@@ -1718,12 +1719,36 @@ int CDECL MSVCRT__wsopen( const MSVCRT_wchar_t* path, int oflags, int shflags, .
   if (hand == INVALID_HANDLE_VALUE)  {
     WARN(":failed-last error (%d)\n",GetLastError());
     msvcrt_set_errno(GetLastError());
-    return -1;
+    msvcrt_set_errno(GetLastError());
+    return *MSVCRT__errno();
   }
 
-  fd = msvcrt_alloc_fd(hand, wxflag);
+  *fd = msvcrt_alloc_fd(hand, wxflag);
+
+  TRACE(":fd (%d) handle (%p)\n", *fd, hand);
+  return 0;
+}
+
+/*********************************************************************
+ *              _wsopen (MSVCRT.@)
+ */
+int CDECL MSVCRT__wsopen( const MSVCRT_wchar_t *path, int oflags, int shflags, ... )
+{
+  int pmode;
+  int fd;
+
+  if (oflags & MSVCRT__O_CREAT)
+  {
+    __ms_va_list ap;
+
+    __ms_va_start(ap, shflags);
+    pmode = va_arg(ap, int);
+    __ms_va_end(ap);
+  }
+  else
+    pmode = 0;
 
-  TRACE(":fd (%d) handle (%p)\n",fd, hand);
+  MSVCRT__wsopen_s(&fd, path, oflags, shflags, pmode);
   return fd;
 }
 
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index 5582e63..37d2425 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -1159,8 +1159,8 @@
 @ cdecl _wsearchenv(wstr wstr ptr)
 @ cdecl _wsearchenv_s(wstr wstr ptr long)
 @ cdecl _wsetlocale(long wstr) MSVCRT__wsetlocale
-@ varargs _wsopen (wstr long long) MSVCRT__wsopen
-# stub _wsopen_s
+@ varargs _wsopen(wstr long long) MSVCRT__wsopen
+@ cdecl _wsopen_s(ptr wstr long long long) MSVCRT__wsopen_s
 @ varargs _wspawnl(long wstr wstr)
 @ varargs _wspawnle(long wstr wstr)
 @ varargs _wspawnlp(long wstr wstr)




More information about the wine-cvs mailing list