[PATCH 1/1] Implemented _sopen_s

Nikolay Sivov nsivov at codeweavers.com
Tue Jan 25 18:59:13 CST 2011


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

diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec
index b4a0f7b..a8c3a7a 100644
--- a/dlls/msvcr100/msvcr100.spec
+++ b/dlls/msvcr100/msvcr100.spec
@@ -1106,7 +1106,7 @@
 @ stub _snwscanf_s
 @ stub _snwscanf_s_l
 @ varargs _sopen(str long long) msvcrt._sopen
-@ stub _sopen_s
+@ cdecl _sopen_s(ptr str long long long) msvcrt._sopen_s
 @ varargs _spawnl(long str str) msvcrt._spawnl
 @ varargs _spawnle(long str str) msvcrt._spawnle
 @ varargs _spawnlp(long str str) msvcrt._spawnlp
diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec
index 814edf2..a5aa459 100644
--- a/dlls/msvcr80/msvcr80.spec
+++ b/dlls/msvcr80/msvcr80.spec
@@ -960,7 +960,7 @@
 @ stub _snwscanf_s
 @ stub _snwscanf_s_l
 @ varargs _sopen(str long long) msvcrt._sopen
-@ stub _sopen_s
+@ cdecl _sopen_s(ptr str long long long) msvcrt._sopen_s
 @ varargs _spawnl(long str str) msvcrt._spawnl
 @ varargs _spawnle(long str str) msvcrt._spawnle
 @ varargs _spawnlp(long str str) msvcrt._spawnlp
diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec
index e39ef87..874427f 100644
--- a/dlls/msvcr90/msvcr90.spec
+++ b/dlls/msvcr90/msvcr90.spec
@@ -946,7 +946,7 @@
 @ stub _snwscanf_s
 @ stub _snwscanf_s_l
 @ varargs _sopen(str long long) msvcrt._sopen
-@ stub _sopen_s
+@ cdecl _sopen_s(ptr str long long long) msvcrt._sopen_s
 @ varargs _spawnl(long str str) msvcrt._spawnl
 @ varargs _spawnle(long str str) msvcrt._spawnle
 @ varargs _spawnlp(long str str) msvcrt._spawnlp
diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c
index dcf893d..35995f4 100644
--- a/dlls/msvcr90/tests/msvcr90.c
+++ b/dlls/msvcr90/tests/msvcr90.c
@@ -20,6 +20,9 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <math.h>
+#include <fcntl.h>
+#include <share.h>
+#include <sys/stat.h>
 
 #include <windef.h>
 #include <winbase.h>
@@ -70,6 +73,7 @@ static void (__cdecl *p_qsort_s)(void *, size_t, size_t, int (__cdecl *)(void *,
 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 void* (WINAPI *pEncodePointer)(void *);
 
@@ -705,6 +709,21 @@ static void test__set_abort_behavior(void)
     p_set_abort_behavior(_WRITE_ABORT_MSG | _CALL_REPORTFAULT, 0xffffffff);
 }
 
+static void test_sopen_s(void)
+{
+    int ret, fd;
+
+    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);
+    CHECK_CALLED(invalid_parameter_handler);
+
+    fd = 0xdead;
+    ret = p_sopen_s(&fd, "test", _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;
@@ -738,6 +757,7 @@ START_TEST(msvcr90)
     p_controlfp_s = (void *) GetProcAddress(hcrt, "_controlfp_s");
     p_atoflt = (void* )GetProcAddress(hcrt, "_atoflt");
     p_set_abort_behavior = (void *) GetProcAddress(hcrt, "_set_abort_behavior");
+    p_sopen_s = (void*) GetProcAddress(hcrt, "_sopen_s");
 
     hkernel32 = GetModuleHandleA("kernel32.dll");
     pEncodePointer = (void *) GetProcAddress(hkernel32, "EncodePointer");
@@ -752,4 +772,5 @@ START_TEST(msvcr90)
     test_controlfp_s();
     test__atoflt();
     test__set_abort_behavior();
+    test_sopen_s();
 }
diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c
index 3847f84..d56700b 100644
--- a/dlls/msvcrt/file.c
+++ b/dlls/msvcrt/file.c
@@ -1513,22 +1513,27 @@ int CDECL MSVCRT__pipe(int *pfds, unsigned int psize, int textmode)
 }
 
 /*********************************************************************
- *              _sopen (MSVCRT.@)
+ *              _sopen_s (MSVCRT.@)
  */
-int CDECL MSVCRT__sopen( const char *path, int oflags, int shflags, ... )
+int CDECL MSVCRT__sopen_s( int *fd, const char *path, int oflags, int shflags, int pmode )
 {
-  __ms_va_list ap;
-  int pmode;
   DWORD access = 0, creation = 0, attrib;
   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, path, oflags, shflags, pmode);
 
-  TRACE(":file (%s) oflags: 0x%04x shflags: 0x%04x\n",
-        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))
   {
@@ -1539,10 +1544,6 @@ int CDECL MSVCRT__sopen( const char *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
@@ -1579,7 +1580,7 @@ int CDECL MSVCRT__sopen( const char *path, int oflags, int shflags, ... )
       break;
     default:
       ERR( "Unhandled shflags 0x%x\n", shflags );
-      return -1;
+      return MSVCRT_EINVAL;
   }
   attrib = FILE_ATTRIBUTE_NORMAL;
 
@@ -1595,16 +1596,38 @@ int CDECL MSVCRT__sopen( const char *path, int oflags, int shflags, ... )
   sa.bInheritHandle       = (oflags & MSVCRT__O_NOINHERIT) ? FALSE : TRUE;
 
   hand = CreateFileA(path, access, sharing, &sa, creation, attrib, 0);
-
   if (hand == INVALID_HANDLE_VALUE)  {
-    WARN(":failed-last error (%d)\n",GetLastError());
+    WARN(":failed-last error (%d)\n", GetLastError());
     msvcrt_set_errno(GetLastError());
-    return -1;
+    return *MSVCRT__errno();
   }
 
-  fd = msvcrt_alloc_fd(hand, wxflag);
+  *fd = msvcrt_alloc_fd(hand, wxflag);
 
-  TRACE(":fd (%d) handle (%p)\n",fd, hand);
+  TRACE(":fd (%d) handle (%p)\n", *fd, hand);
+  return 0;
+}
+
+/*********************************************************************
+ *              _sopen (MSVCRT.@)
+ */
+int CDECL MSVCRT__sopen( const char *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;
+
+  MSVCRT__sopen_s(&fd, path, oflags, shflags, pmode);
   return fd;
 }
 
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index 85334d3..49e8de2 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -887,7 +887,7 @@
 # stub _snwscanf_s
 # stub _snwscanf_s_l
 @ varargs _sopen(str long long) MSVCRT__sopen
-# stub _sopen_s
+@ cdecl _sopen_s(ptr str long long long) MSVCRT__sopen_s
 @ varargs _spawnl(long str str)
 @ varargs _spawnle(long str str)
 @ varargs _spawnlp(long str str)
-- 
1.5.6.5


--------------070406070106000604050608--



More information about the wine-patches mailing list