diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index 1c720dcad36..9b4cecda13c 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 f4bde1a3914..4eaed927f74 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 01ebec7b2e9..a2b8359e839 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 dcf893de9a8..35995f46d2e 100644 --- a/dlls/msvcr90/tests/msvcr90.c +++ b/dlls/msvcr90/tests/msvcr90.c @@ -20,6 +20,9 @@ #include #include #include +#include +#include +#include #include #include @@ -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 3847f8415a9..d56700b1fd4 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 50a0b214c1e..7fd3dfab8db 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)