From: Piotr Caban piotr@codeweavers.com
--- dlls/msvcrt/file.c | 85 ++++---------------------------------- dlls/ucrtbase/tests/file.c | 4 ++ 2 files changed, 11 insertions(+), 78 deletions(-)
diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c index 737548afd31..ee52c37552a 100644 --- a/dlls/msvcrt/file.c +++ b/dlls/msvcrt/file.c @@ -65,6 +65,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt); #undef _stat64i32 #undef _wstat64i32 #undef _wstat64 +int __cdecl _wstat64(const wchar_t*, struct _stat64*);
/* for stat mode, permissions apply to all,owner and group */ #define ALL_S_IREAD (_S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6)) @@ -284,11 +285,6 @@ static int MSVCRT_umask = 0; static LONG tmpnam_unique; static LONG tmpnam_s_unique;
-static const unsigned int EXE = 'e' << 16 | 'x' << 8 | 'e'; -static const unsigned int BAT = 'b' << 16 | 'a' << 8 | 't'; -static const unsigned int CMD = 'c' << 16 | 'm' << 8 | 'd'; -static const unsigned int COM = 'c' << 16 | 'o' << 8 | 'm'; - #define TOUL(x) (ULONGLONG)(x) static const ULONGLONG WCEXE = TOUL('e') << 32 | TOUL('x') << 16 | TOUL('e'); static const ULONGLONG WCBAT = TOUL('b') << 32 | TOUL('a') << 16 | TOUL('t'); @@ -3191,80 +3187,13 @@ int CDECL _setmode(int fd,int mode) */ int CDECL _stat64(const char* path, struct _stat64 * buf) { - DWORD dw; - WIN32_FILE_ATTRIBUTE_DATA hfi; - unsigned short mode = ALL_S_IREAD; - int plen; - - TRACE(":file (%s) buf(%p)\n", path, buf); - - plen = strlen(path); - while (plen && path[plen-1]==' ') - plen--; - - if (plen==2 && path[1]==':') - { - *_errno() = ENOENT; - return -1; - } - -#if _MSVCR_VER<140 - if (plen>=2 && path[plen-2]!=':' && (path[plen-1]=='\' || path[plen-1]=='/')) - { - *_errno() = ENOENT; - return -1; - } -#endif - - if (!GetFileAttributesExA(path, GetFileExInfoStandard, &hfi)) - { - TRACE("failed (%ld)\n", GetLastError()); - *_errno() = ENOENT; - return -1; - } - - memset(buf,0,sizeof(struct _stat64)); - - /* FIXME: rdev isn't drive num, despite what the docs say-what is it? - Bon 011120: This FIXME seems incorrect - Also a letter as first char isn't enough to be classified - as a drive letter - */ - if (isalpha(*path)&& (*(path+1)==':')) - buf->st_dev = buf->st_rdev = _toupper_l(*path, NULL) - 'A'; /* drive num */ - else - buf->st_dev = buf->st_rdev = _getdrive() - 1; - - /* Dir, or regular file? */ - if (hfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - mode |= (_S_IFDIR | ALL_S_IEXEC); - else - { - mode |= _S_IFREG; - /* executable? */ - if (plen > 6 && path[plen-4] == '.') /* shortest exe: "\x.exe" */ - { - unsigned int ext = _tolower_l(path[plen-1], NULL) | - (_tolower_l(path[plen-2], NULL) << 8) | - (_tolower_l(path[plen-3], NULL) << 16); - if (ext == EXE || ext == BAT || ext == CMD || ext == COM) - mode |= ALL_S_IEXEC; - } - } - - if (!(hfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) - mode |= ALL_S_IWRITE; + wchar_t *pathW = NULL; + int ret;
- buf->st_mode = mode; - buf->st_nlink = 1; - buf->st_size = ((__int64)hfi.nFileSizeHigh << 32) + hfi.nFileSizeLow; - RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastAccessTime, &dw); - buf->st_atime = dw; - RtlTimeToSecondsSince1970((LARGE_INTEGER *)&hfi.ftLastWriteTime, &dw); - buf->st_mtime = buf->st_ctime = dw; - TRACE("%d %d %#I64x %I64d %I64d %I64d\n", buf->st_mode, buf->st_nlink, - buf->st_size, buf->st_atime, buf->st_mtime, buf->st_ctime); - return 0; + if (path && !(pathW = wstrdupa_utf8(path))) return -1; + ret = _wstat64(pathW, buf); + free(pathW); + return ret; }
/********************************************************************* diff --git a/dlls/ucrtbase/tests/file.c b/dlls/ucrtbase/tests/file.c index cdf90e797ae..5615ea8c128 100644 --- a/dlls/ucrtbase/tests/file.c +++ b/dlls/ucrtbase/tests/file.c @@ -239,6 +239,7 @@ static void test_utf8(void) const WCHAR dirW[] = L"dir\x0119\x015b\x0107";
char file2[32], buf[256], *p; + struct _stat64 stat; FILE *f; int ret;
@@ -287,6 +288,9 @@ static void test_utf8(void) ret = access(file, 0); ok(!ret, "access returned %d, error %d\n", ret, errno);
+ ret = _stat64(file, &stat); + ok(!ret, "_stat64 returned %d, error %d\n", ret, errno); + ret = _chmod(file, _S_IREAD | _S_IWRITE); ok(!ret, "_chmod returned %d, error %d\n", ret, errno);
From: Piotr Caban piotr@codeweavers.com
--- dlls/msvcrt/file.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c index ee52c37552a..8bf191d6a61 100644 --- a/dlls/msvcrt/file.c +++ b/dlls/msvcrt/file.c @@ -4969,12 +4969,19 @@ int CDECL _wremove(const wchar_t *path) */ int CDECL rename(const char *oldpath,const char *newpath) { - TRACE(":from %s to %s\n", oldpath, newpath); - if (MoveFileExA(oldpath, newpath, MOVEFILE_COPY_ALLOWED)) - return 0; - TRACE(":failed (%ld)\n", GetLastError()); - msvcrt_set_errno(GetLastError()); - return -1; + wchar_t *oldpathW = NULL, *newpathW = NULL; + int ret; + + if (oldpath && !(oldpathW = wstrdupa_utf8(oldpath))) return -1; + if (newpath && !(newpathW = wstrdupa_utf8(newpath))) + { + free(oldpathW); + return -1; + } + ret = _wrename(oldpathW, newpathW); + free(oldpathW); + free(newpathW); + return ret; }
/*********************************************************************
From: Piotr Caban piotr@codeweavers.com
--- dlls/msvcrt/file.c | 29 ++++++++++++++++------------- dlls/ucrtbase/tests/file.c | 10 +++++++++- 2 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c index 8bf191d6a61..22888d88a8a 100644 --- a/dlls/msvcrt/file.c +++ b/dlls/msvcrt/file.c @@ -3440,20 +3440,22 @@ __int64 CDECL _telli64(int fd) */ char * CDECL _tempnam(const char *dir, const char *prefix) { - char tmpbuf[MAX_PATH]; - const char *tmp_dir = getenv("TMP"); + wchar_t *dirW = NULL, *prefixW = NULL, *retW; + char *ret;
- if (tmp_dir) dir = tmp_dir; - - TRACE("dir (%s) prefix (%s)\n", dir, prefix); - if (GetTempFileNameA(dir,prefix,0,tmpbuf)) - { - TRACE("got name (%s)\n", tmpbuf); - DeleteFileA(tmpbuf); - return _strdup(tmpbuf); - } - TRACE("failed (%ld)\n", GetLastError()); - return NULL; + if (dir && !(dirW = wstrdupa_utf8(dir))) return NULL; + if (prefix && !(prefixW = wstrdupa_utf8(prefix))) + { + free(dirW); + return NULL; + } + retW = _wtempnam(dirW, prefixW); + free(dirW); + free(prefixW); + /* TODO: don't do the conversion */ + ret = astrdupw_utf8(retW); + free(retW); + return ret; }
/********************************************************************* @@ -3467,6 +3469,7 @@ wchar_t * CDECL _wtempnam(const wchar_t *dir, const wchar_t *prefix) if (tmp_dir) dir = tmp_dir;
TRACE("dir (%s) prefix (%s)\n", debugstr_w(dir), debugstr_w(prefix)); + /* TODO: use whole prefix */ if (GetTempFileNameW(dir,prefix,0,tmpbuf)) { TRACE("got name (%s)\n", debugstr_w(tmpbuf)); diff --git a/dlls/ucrtbase/tests/file.c b/dlls/ucrtbase/tests/file.c index 5615ea8c128..0214015c37a 100644 --- a/dlls/ucrtbase/tests/file.c +++ b/dlls/ucrtbase/tests/file.c @@ -238,7 +238,7 @@ static void test_utf8(void) const WCHAR fileW[] = L"file\x0119\x015b\x0107.a"; const WCHAR dirW[] = L"dir\x0119\x015b\x0107";
- char file2[32], buf[256], *p; + char file2[32], buf[256], *p, *q; struct _stat64 stat; FILE *f; int ret; @@ -339,6 +339,14 @@ static void test_utf8(void) ok(!ret, "_rmdir returned %d, errno %d\n", ret, errno); }
+ p = _tempnam(NULL, file); + ok(!!p, "_tempnam returned NULL, error %d\n", errno); + q = strrchr(p, '\'); + ok(!!q, "_tempnam returned %s\n", debugstr_a(p)); + todo_wine ok(!memcmp(q + 1, file, ARRAY_SIZE(file) - 1), + "incorrect file prefix: %s\n", debugstr_a(p)); + free(p); + setlocale(LC_ALL, "C"); }
From: Piotr Caban piotr@codeweavers.com
--- dlls/msvcrt/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcrt/dir.c b/dlls/msvcrt/dir.c index ff26a0ce2b8..587517ab1bb 100644 --- a/dlls/msvcrt/dir.c +++ b/dlls/msvcrt/dir.c @@ -1747,8 +1747,8 @@ int CDECL _wsearchenv_s(const wchar_t* file, const wchar_t* env, /* Try CWD first */ if (GetFileAttributesW( file ) != INVALID_FILE_ATTRIBUTES) { - if (GetFullPathNameW( file, count, buf, NULL )) return 0; - msvcrt_set_errno(GetLastError()); + if (!_wfullpath(buf, file, count)) + return *_errno(); return 0; }
From: Piotr Caban piotr@codeweavers.com
--- dlls/msvcrt/dir.c | 15 +++++++++++---- dlls/ucrtbase/tests/file.c | 6 ++++++ 2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/dlls/msvcrt/dir.c b/dlls/msvcrt/dir.c index 587517ab1bb..1ba14308f85 100644 --- a/dlls/msvcrt/dir.c +++ b/dlls/msvcrt/dir.c @@ -1639,6 +1639,7 @@ int CDECL _searchenv_s(const char* file, const char* env, char *buf, size_t coun char *envVal, *penv, *end; char path[MAX_PATH]; size_t path_len, fname_len; + int old_errno, access;
if (!MSVCRT_CHECK_PMT(file != NULL)) return EINVAL; if (!MSVCRT_CHECK_PMT(buf != NULL)) return EINVAL; @@ -1651,10 +1652,13 @@ int CDECL _searchenv_s(const char* file, const char* env, char *buf, size_t coun *buf = '\0';
/* Try CWD first */ - if (GetFileAttributesA( file ) != INVALID_FILE_ATTRIBUTES) + old_errno = *_errno(); + access = _access(file, 0); + *_errno() = old_errno; + if (!access) { - if (GetFullPathNameA( file, count, buf, NULL )) return 0; - msvcrt_set_errno(GetLastError()); + if (!_fullpath(buf, file, count)) + return *_errno(); return 0; }
@@ -1700,7 +1704,10 @@ int CDECL _searchenv_s(const char* file, const char* env, char *buf, size_t coun
memcpy(path + path_len, file, fname_len + 1); TRACE("Checking for file %s\n", path); - if (GetFileAttributesA( path ) != INVALID_FILE_ATTRIBUTES) + old_errno = *_errno(); + access = _access(path, 0); + *_errno() = old_errno; + if (!access) { if (path_len + fname_len + 1 > count) { diff --git a/dlls/ucrtbase/tests/file.c b/dlls/ucrtbase/tests/file.c index 0214015c37a..248fdc92dd3 100644 --- a/dlls/ucrtbase/tests/file.c +++ b/dlls/ucrtbase/tests/file.c @@ -320,6 +320,12 @@ static void test_utf8(void) ret = remove(file2); ok(!ret, "remove returned %d, errno %d\n", ret, errno);
+ buf[0] = 'x'; + _searchenv(file, "env", buf); + p = strrchr(buf, '\'); + ok(!!p, "buf = %s\n", debugstr_a(buf)); + ok(!strcmp(p + 1, file), "buf = %s\n", debugstr_a(buf)); + ret = _wunlink(fileW); todo_wine_if(GetACP() != CP_UTF8) ok(!ret, "_wunlink returned %d, errno %d\n", ret, errno); if (ret)
From: Piotr Caban piotr@codeweavers.com
--- include/msvcrt/corecrt_io.h | 45 ++++++++++++++++ include/msvcrt/io.h | 100 +----------------------------------- 2 files changed, 46 insertions(+), 99 deletions(-)
diff --git a/include/msvcrt/corecrt_io.h b/include/msvcrt/corecrt_io.h index c59a3592fe9..bd4f104ec2d 100644 --- a/include/msvcrt/corecrt_io.h +++ b/include/msvcrt/corecrt_io.h @@ -54,6 +54,15 @@ struct _finddata64_t { char name[260]; };
+/* The following are also defined in dos.h */ +#define _A_NORMAL 0x00000000 +#define _A_RDONLY 0x00000001 +#define _A_HIDDEN 0x00000002 +#define _A_SYSTEM 0x00000004 +#define _A_VOLID 0x00000008 +#define _A_SUBDIR 0x00000010 +#define _A_ARCH 0x00000020 + #ifdef _UCRT # ifdef _USE_32BIT_TIME_T # define _findfirst _findfirst32 @@ -86,7 +95,17 @@ extern "C" {
_ACRTIMP int __cdecl _access(const char*,int); _ACRTIMP int __cdecl _chmod(const char*,int); +_ACRTIMP int __cdecl _chsize(int,__msvcrt_long); +_ACRTIMP int __cdecl _chsize_s(int,__int64); +_ACRTIMP int __cdecl _close(int); _ACRTIMP int __cdecl _creat(const char*,int); +_ACRTIMP int __cdecl _dup(int); +_ACRTIMP int __cdecl _dup2(int,int); +_ACRTIMP int __cdecl _eof(int); +_ACRTIMP __int64 __cdecl _filelengthi64(int); +_ACRTIMP __msvcrt_long __cdecl _filelength(int); +_ACRTIMP int __cdecl _findclose(intptr_t); +#ifdef _UCRT _ACRTIMP intptr_t __cdecl _findfirst32(const char*,struct _finddata32_t*); _ACRTIMP intptr_t __cdecl _findfirst32i64(const char*, struct _finddata32i64_t*); _ACRTIMP intptr_t __cdecl _findfirst64(const char*,struct _finddata64_t*); @@ -95,10 +114,36 @@ _ACRTIMP int __cdecl _findnext32(intptr_t,struct _finddata32_t*); _ACRTIMP int __cdecl _findnext32i64(intptr_t,struct _finddata32i64_t*); _ACRTIMP int __cdecl _findnext64(intptr_t,struct _finddata64_t*); _ACRTIMP int __cdecl _findnext64i32(intptr_t,struct _finddata64i32_t*); +#else +_ACRTIMP intptr_t __cdecl _findfirst(const char*,struct _finddata_t*); +_ACRTIMP intptr_t __cdecl _findfirsti64(const char*, struct _finddatai64_t*); +_ACRTIMP intptr_t __cdecl _findfirst64(const char*, struct _finddata64_t*); +_ACRTIMP int __cdecl _findnext(intptr_t,struct _finddata_t*); +_ACRTIMP int __cdecl _findnexti64(intptr_t, struct _finddatai64_t*); +_ACRTIMP int __cdecl _findnext64(intptr_t, struct _finddata64_t*); +#endif +_ACRTIMP intptr_t __cdecl _get_osfhandle(int); +_ACRTIMP int __cdecl _isatty(int); +_ACRTIMP int __cdecl _locking(int,int,__msvcrt_long); +_ACRTIMP __msvcrt_long __cdecl _lseek(int,__msvcrt_long,int); +_ACRTIMP __int64 __cdecl _lseeki64(int,__int64,int); _ACRTIMP char* __cdecl _mktemp(char*); +_ACRTIMP int __cdecl _mktemp_s(char*,size_t); _ACRTIMP int __cdecl _open(const char*,int,...); +_ACRTIMP int __cdecl _open_osfhandle(intptr_t,int); +_ACRTIMP int __cdecl _pipe(int*,unsigned int,int); +_ACRTIMP int __cdecl _read(int,void*,unsigned int); +_ACRTIMP int __cdecl _setmode(int,int); _ACRTIMP int __cdecl _sopen(const char*,int,int,...); +_ACRTIMP errno_t __cdecl _sopen_dispatch(const char*,int,int,int,int*,int); +_ACRTIMP errno_t __cdecl _sopen_s(int*,const char*,int,int,int); +_ACRTIMP __msvcrt_long __cdecl _tell(int); +_ACRTIMP __int64 __cdecl _telli64(int); +_ACRTIMP int __cdecl _umask(int); _ACRTIMP int __cdecl _unlink(const char*); +_ACRTIMP int __cdecl _write(int,const void*,unsigned int); +_ACRTIMP int __cdecl remove(const char*); +_ACRTIMP int __cdecl rename(const char*,const char*);
#ifdef __cplusplus } diff --git a/include/msvcrt/io.h b/include/msvcrt/io.h index 0d434177e97..9bca915c56f 100644 --- a/include/msvcrt/io.h +++ b/include/msvcrt/io.h @@ -9,103 +9,7 @@ #define __WINE_IO_H
#include <corecrt.h> -#include <corecrt_wio.h> - -#include <pshpack8.h> - -/* The following are also defined in dos.h */ -#define _A_NORMAL 0x00000000 -#define _A_RDONLY 0x00000001 -#define _A_HIDDEN 0x00000002 -#define _A_SYSTEM 0x00000004 -#define _A_VOLID 0x00000008 -#define _A_SUBDIR 0x00000010 -#define _A_ARCH 0x00000020 - -#ifndef _FINDDATA_T_DEFINED -#define _FINDDATA_T_DEFINED -struct _finddata_t -{ - unsigned attrib; - time_t time_create; - time_t time_access; - time_t time_write; - _fsize_t size; - char name[260]; -}; - -struct _finddatai64_t -{ - unsigned attrib; - time_t time_create; - time_t time_access; - time_t time_write; - __int64 DECLSPEC_ALIGN(8) size; - char name[260]; -}; - -struct _finddata64_t -{ - unsigned attrib; - __time64_t time_create; - __time64_t time_access; - __time64_t time_write; - __int64 DECLSPEC_ALIGN(8) size; - char name[260]; -}; -#endif /* _FINDDATA_T_DEFINED */ - -#ifdef __cplusplus -extern "C" { -#endif - -_ACRTIMP int __cdecl _access(const char*,int); -_ACRTIMP int __cdecl _chmod(const char*,int); -_ACRTIMP int __cdecl _chsize(int,__msvcrt_long); -_ACRTIMP int __cdecl _chsize_s(int,__int64); -_ACRTIMP int __cdecl _close(int); -_ACRTIMP int __cdecl _commit(int); -_ACRTIMP int __cdecl _creat(const char*,int); -_ACRTIMP int __cdecl _dup(int); -_ACRTIMP int __cdecl _dup2(int,int); -_ACRTIMP int __cdecl _eof(int); -_ACRTIMP __int64 __cdecl _filelengthi64(int); -_ACRTIMP __msvcrt_long __cdecl _filelength(int); -_ACRTIMP int __cdecl _findclose(intptr_t); -_ACRTIMP intptr_t __cdecl _findfirst(const char*,struct _finddata_t*); -_ACRTIMP intptr_t __cdecl _findfirsti64(const char*, struct _finddatai64_t*); -_ACRTIMP intptr_t __cdecl _findfirst64(const char*, struct _finddata64_t*); -_ACRTIMP int __cdecl _findnext(intptr_t,struct _finddata_t*); -_ACRTIMP int __cdecl _findnexti64(intptr_t, struct _finddatai64_t*); -_ACRTIMP int __cdecl _findnext64(intptr_t, struct _finddata64_t*); -_ACRTIMP intptr_t __cdecl _get_osfhandle(int); -_ACRTIMP int __cdecl _isatty(int); -_ACRTIMP int __cdecl _locking(int,int,__msvcrt_long); -_ACRTIMP __msvcrt_long __cdecl _lseek(int,__msvcrt_long,int); -_ACRTIMP __int64 __cdecl _lseeki64(int,__int64,int); -_ACRTIMP char* __cdecl _mktemp(char*); -_ACRTIMP int __cdecl _mktemp_s(char*,size_t); -_ACRTIMP int __cdecl _open(const char*,int,...); -_ACRTIMP int __cdecl _open_osfhandle(intptr_t,int); -_ACRTIMP int __cdecl _pipe(int*,unsigned int,int); -_ACRTIMP int __cdecl _read(int,void*,unsigned int); -_ACRTIMP int __cdecl _setmode(int,int); -_ACRTIMP int __cdecl _sopen(const char*,int,int,...); -_ACRTIMP errno_t __cdecl _sopen_dispatch(const char*,int,int,int,int*,int); -_ACRTIMP errno_t __cdecl _sopen_s(int*,const char*,int,int,int); -_ACRTIMP __msvcrt_long __cdecl _tell(int); -_ACRTIMP __int64 __cdecl _telli64(int); -_ACRTIMP int __cdecl _umask(int); -_ACRTIMP int __cdecl _unlink(const char*); -_ACRTIMP int __cdecl _write(int,const void*,unsigned int); - -_ACRTIMP int __cdecl remove(const char*); -_ACRTIMP int __cdecl rename(const char*,const char*); - -#ifdef __cplusplus -} -#endif - +#include <corecrt_io.h>
static inline int access(const char* path, int mode) { return _access(path, mode); } static inline int chmod(const char* path, int mode) { return _chmod(path, mode); } @@ -141,6 +45,4 @@ _ACRTIMP int __cdecl sopen(const char*,int,int,...) __attribute__((alias("_sopen #define sopen _sopen #endif /* __GNUC__ */
-#include <poppack.h> - #endif /* __WINE_IO_H */
From: Piotr Caban piotr@codeweavers.com
--- dlls/msvcrt/dir.c | 45 ++++++++++++++++++++++---------------- dlls/ucrtbase/tests/file.c | 13 +++++++++++ 2 files changed, 39 insertions(+), 19 deletions(-)
diff --git a/dlls/msvcrt/dir.c b/dlls/msvcrt/dir.c index 1ba14308f85..257f49d5351 100644 --- a/dlls/msvcrt/dir.c +++ b/dlls/msvcrt/dir.c @@ -387,25 +387,6 @@ intptr_t CDECL _findfirst(const char * fspec, struct _finddata_t* ft) return (intptr_t)hfind; }
-/********************************************************************* - * _findfirst32 (MSVCRT.@) - */ -intptr_t CDECL _findfirst32(const char * fspec, struct _finddata32_t* ft) -{ - WIN32_FIND_DATAA find_data; - HANDLE hfind; - - hfind = FindFirstFileA(fspec, &find_data); - if (hfind == INVALID_HANDLE_VALUE) - { - msvcrt_set_errno(GetLastError()); - return -1; - } - msvcrt_fttofd32(&find_data, ft); - TRACE(":got handle %p\n", hfind); - return (intptr_t)hfind; -} - /********************************************************************* * _wfindfirst (MSVCRT.@) * @@ -448,6 +429,32 @@ intptr_t CDECL _wfindfirst32(const wchar_t * fspec, struct _wfinddata32_t* ft) return (intptr_t)hfind; }
+static int finddata32_wtoa(const struct _wfinddata32_t *wfd, struct _finddata32_t *fd) +{ + fd->attrib = wfd->attrib; + fd->time_create = wfd->time_create; + fd->time_access = wfd->time_access; + fd->time_write = wfd->time_write; + fd->size = wfd->size; + return convert_wcs_to_acp_utf8(wfd->name, fd->name, ARRAY_SIZE(fd->name)); +} + +/********************************************************************* + * _findfirst32 (MSVCRT.@) + */ +intptr_t CDECL _findfirst32(const char *fspec, struct _finddata32_t *ft) +{ + struct _wfinddata32_t wft; + wchar_t *fspecW = NULL; + intptr_t ret; + + if (fspec && !(fspecW = wstrdupa_utf8(fspec))) return -1; + ret = _wfindfirst32(fspecW, &wft); + free(fspecW); + if (!finddata32_wtoa(&wft, ft)) return -1; + return ret; +} + /********************************************************************* * _findfirsti64 (MSVCRT.@) * diff --git a/dlls/ucrtbase/tests/file.c b/dlls/ucrtbase/tests/file.c index 248fdc92dd3..73aa5da0659 100644 --- a/dlls/ucrtbase/tests/file.c +++ b/dlls/ucrtbase/tests/file.c @@ -239,7 +239,9 @@ static void test_utf8(void) const WCHAR dirW[] = L"dir\x0119\x015b\x0107";
char file2[32], buf[256], *p, *q; + struct _finddata32_t fdata32; struct _stat64 stat; + intptr_t hfind; FILE *f; int ret;
@@ -317,6 +319,17 @@ static void test_utf8(void) ok(!memcmp(buf, file, sizeof(file) - 1), "buf = %s\n", debugstr_a(buf)); ok(buf[ARRAY_SIZE(file) - 1] == 'b', "buf = %s\n", debugstr_a(buf));
+ strcpy(buf, file); + strcat(buf, "*"); + fdata32.name[0] = 'x'; + hfind = _findfirst32(buf, &fdata32); + ok(hfind != -1, "_findfirst32 returned %Id, errno %d\n", hfind, errno); + todo_wine_if(!is_lossless_convertion(dir)) + ok(!memcmp(file, fdata32.name, sizeof(file) - 1), "fdata32.name = %s\n", debugstr_a(fdata32.name)); + + ret = _findclose(hfind); + ok(!ret, "_findclose returned %d, errno %d\n", ret, errno); + ret = remove(file2); ok(!ret, "remove returned %d, errno %d\n", ret, errno);
From: Piotr Caban piotr@codeweavers.com
--- dlls/msvcrt/dir.c | 48 ++++++++++---------------------------- dlls/ucrtbase/tests/file.c | 6 +++++ 2 files changed, 18 insertions(+), 36 deletions(-)
diff --git a/dlls/msvcrt/dir.c b/dlls/msvcrt/dir.c index 257f49d5351..0448a2a8523 100644 --- a/dlls/msvcrt/dir.c +++ b/dlls/msvcrt/dir.c @@ -77,26 +77,6 @@ static void msvcrt_fttofd( const WIN32_FIND_DATAA *fd, struct _finddata_t* ft) strcpy(ft->name, fd->cFileName); }
-/* INTERNAL: Translate WIN32_FIND_DATAA to finddata32_t */ -static void msvcrt_fttofd32( const WIN32_FIND_DATAA *fd, struct _finddata32_t* ft) -{ - DWORD dw; - - if (fd->dwFileAttributes == FILE_ATTRIBUTE_NORMAL) - ft->attrib = 0; - else - ft->attrib = fd->dwFileAttributes; - - RtlTimeToSecondsSince1970( (const LARGE_INTEGER *)&fd->ftCreationTime, &dw ); - ft->time_create = dw; - RtlTimeToSecondsSince1970( (const LARGE_INTEGER *)&fd->ftLastAccessTime, &dw ); - ft->time_access = dw; - RtlTimeToSecondsSince1970( (const LARGE_INTEGER *)&fd->ftLastWriteTime, &dw ); - ft->time_write = dw; - ft->size = fd->nFileSizeLow; - strcpy(ft->name, fd->cFileName); -} - /* INTERNAL: Translate WIN32_FIND_DATAW to wfinddata_t */ static void msvcrt_wfttofd( const WIN32_FIND_DATAW *fd, struct _wfinddata_t* ft) { @@ -612,37 +592,33 @@ int CDECL _findnext(intptr_t hand, struct _finddata_t * ft) }
/********************************************************************* - * _findnext32 (MSVCRT.@) + * _wfindnext32 (MSVCRT.@) */ -int CDECL _findnext32(intptr_t hand, struct _finddata32_t * ft) +int CDECL _wfindnext32(intptr_t hand, struct _wfinddata32_t * ft) { - WIN32_FIND_DATAA find_data; + WIN32_FIND_DATAW find_data;
- if (!FindNextFileA((HANDLE)hand, &find_data)) + if (!FindNextFileW((HANDLE)hand, &find_data)) { *_errno() = ENOENT; return -1; }
- msvcrt_fttofd32(&find_data, ft); + msvcrt_wfttofd32(&find_data, ft); return 0; }
/********************************************************************* - * _wfindnext32 (MSVCRT.@) + * _findnext32 (MSVCRT.@) */ -int CDECL _wfindnext32(intptr_t hand, struct _wfinddata32_t * ft) +int CDECL _findnext32(intptr_t hand, struct _finddata32_t *ft) { - WIN32_FIND_DATAW find_data; - - if (!FindNextFileW((HANDLE)hand, &find_data)) - { - *_errno() = ENOENT; - return -1; - } + struct _wfinddata32_t wft; + int ret;
- msvcrt_wfttofd32(&find_data, ft); - return 0; + ret = _wfindnext32(hand, &wft); + if (!ret && !finddata32_wtoa(&wft, ft)) ret = -1; + return ret; }
/********************************************************************* diff --git a/dlls/ucrtbase/tests/file.c b/dlls/ucrtbase/tests/file.c index 73aa5da0659..1379759199d 100644 --- a/dlls/ucrtbase/tests/file.c +++ b/dlls/ucrtbase/tests/file.c @@ -327,9 +327,15 @@ static void test_utf8(void) todo_wine_if(!is_lossless_convertion(dir)) ok(!memcmp(file, fdata32.name, sizeof(file) - 1), "fdata32.name = %s\n", debugstr_a(fdata32.name));
+ fdata32.name[0] = 'x'; + ret = _findnext32(hfind, &fdata32); + ok(!ret, "_findnext32 returned %d, errno %d\n", ret, errno); + todo_wine_if(!is_lossless_convertion(dir)) + ok(!memcmp(file, fdata32.name, sizeof(file) - 1), "fdata32.name = %s\n", debugstr_a(fdata32.name)); ret = _findclose(hfind); ok(!ret, "_findclose returned %d, errno %d\n", ret, errno);
+ ret = remove(file2); ok(!ret, "remove returned %d, errno %d\n", ret, errno);
From: Piotr Caban piotr@codeweavers.com
--- dlls/msvcrt/dir.c | 47 ++++++++++++++++++++++---------------- dlls/ucrtbase/tests/file.c | 11 +++++++++ 2 files changed, 38 insertions(+), 20 deletions(-)
diff --git a/dlls/msvcrt/dir.c b/dlls/msvcrt/dir.c index 0448a2a8523..f5d95f1217e 100644 --- a/dlls/msvcrt/dir.c +++ b/dlls/msvcrt/dir.c @@ -457,45 +457,52 @@ intptr_t CDECL _findfirsti64(const char * fspec, struct _finddatai64_t* ft) }
/********************************************************************* - * _findfirst64 (MSVCRT.@) + * _wfindfirst64 (MSVCRT.@) * - * 64-bit version of _findfirst. + * Unicode version of _findfirst64. */ -intptr_t CDECL _findfirst64(const char * fspec, struct _finddata64_t* ft) +intptr_t CDECL _wfindfirst64(const wchar_t * fspec, struct _wfinddata64_t* ft) { - WIN32_FIND_DATAA find_data; + WIN32_FIND_DATAW find_data; HANDLE hfind;
- hfind = FindFirstFileA(fspec, &find_data); + hfind = FindFirstFileW(fspec, &find_data); if (hfind == INVALID_HANDLE_VALUE) { msvcrt_set_errno(GetLastError()); return -1; } - msvcrt_fttofd64(&find_data,ft); + msvcrt_wfttofd64(&find_data,ft); TRACE(":got handle %p\n",hfind); return (intptr_t)hfind; }
+static int finddata64_wtoa(const struct _wfinddata64_t *wfd, struct _finddata64_t *fd) +{ + fd->attrib = wfd->attrib; + fd->time_create = wfd->time_create; + fd->time_access = wfd->time_access; + fd->time_write = wfd->time_write; + fd->size = wfd->size; + return convert_wcs_to_acp_utf8(wfd->name, fd->name, ARRAY_SIZE(fd->name)); +} + /********************************************************************* - * _wfindfirst64 (MSVCRT.@) + * _findfirst64 (MSVCRT.@) * - * Unicode version of _findfirst64. + * 64-bit version of _findfirst. */ -intptr_t CDECL _wfindfirst64(const wchar_t * fspec, struct _wfinddata64_t* ft) +intptr_t CDECL _findfirst64(const char *fspec, struct _finddata64_t *ft) { - WIN32_FIND_DATAW find_data; - HANDLE hfind; + struct _wfinddata64_t wft; + wchar_t *fspecW = NULL; + intptr_t ret;
- hfind = FindFirstFileW(fspec, &find_data); - if (hfind == INVALID_HANDLE_VALUE) - { - msvcrt_set_errno(GetLastError()); - return -1; - } - msvcrt_wfttofd64(&find_data,ft); - TRACE(":got handle %p\n",hfind); - return (intptr_t)hfind; + if (fspec && !(fspecW = wstrdupa_utf8(fspec))) return -1; + ret = _wfindfirst64(fspecW, &wft); + free(fspecW); + if (!finddata64_wtoa(&wft, ft)) return -1; + return ret; }
/********************************************************************* diff --git a/dlls/ucrtbase/tests/file.c b/dlls/ucrtbase/tests/file.c index 1379759199d..a8934338a4b 100644 --- a/dlls/ucrtbase/tests/file.c +++ b/dlls/ucrtbase/tests/file.c @@ -240,6 +240,7 @@ static void test_utf8(void)
char file2[32], buf[256], *p, *q; struct _finddata32_t fdata32; + struct _finddata64_t fdata64; struct _stat64 stat; intptr_t hfind; FILE *f; @@ -336,6 +337,16 @@ static void test_utf8(void) ok(!ret, "_findclose returned %d, errno %d\n", ret, errno);
+ strcpy(buf, file); + strcat(buf, "*"); + fdata64.name[0] = 'x'; + hfind = _findfirst64(buf, &fdata64); + ok(hfind != -1, "_findfirst64 returned %Id, errno %d\n", hfind, errno); + todo_wine_if(!is_lossless_convertion(dir)) + ok(!memcmp(file, fdata64.name, sizeof(file) - 1), "fdata64.name = %s\n", debugstr_a(fdata64.name)); + ret = _findclose(hfind); + ok(!ret, "_findclose returned %d, errno %d\n", ret, errno); + ret = remove(file2); ok(!ret, "remove returned %d, errno %d\n", ret, errno);
From: Piotr Caban piotr@codeweavers.com
--- dlls/msvcrt/dir.c | 52 ++++++++++---------------------------- dlls/ucrtbase/tests/file.c | 6 +++++ 2 files changed, 20 insertions(+), 38 deletions(-)
diff --git a/dlls/msvcrt/dir.c b/dlls/msvcrt/dir.c index f5d95f1217e..b72682db806 100644 --- a/dlls/msvcrt/dir.c +++ b/dlls/msvcrt/dir.c @@ -137,26 +137,6 @@ static void msvcrt_fttofdi64( const WIN32_FIND_DATAA *fd, struct _finddatai64_t* strcpy(ft->name, fd->cFileName); }
-/* INTERNAL: Translate WIN32_FIND_DATAA to finddata64_t */ -static void msvcrt_fttofd64( const WIN32_FIND_DATAA *fd, struct _finddata64_t* ft) -{ - DWORD dw; - - if (fd->dwFileAttributes == FILE_ATTRIBUTE_NORMAL) - ft->attrib = 0; - else - ft->attrib = fd->dwFileAttributes; - - RtlTimeToSecondsSince1970( (const LARGE_INTEGER *)&fd->ftCreationTime, &dw ); - ft->time_create = dw; - RtlTimeToSecondsSince1970( (const LARGE_INTEGER *)&fd->ftLastAccessTime, &dw ); - ft->time_access = dw; - RtlTimeToSecondsSince1970( (const LARGE_INTEGER *)&fd->ftLastWriteTime, &dw ); - ft->time_write = dw; - ft->size = ((__int64)fd->nFileSizeHigh) << 32 | fd->nFileSizeLow; - strcpy(ft->name, fd->cFileName); -} - /* INTERNAL: Translate WIN32_FIND_DATAW to wfinddata64_t */ static void msvcrt_wfttofd64( const WIN32_FIND_DATAW *fd, struct _wfinddata64_t* ft) { @@ -667,41 +647,37 @@ int CDECL _findnexti64(intptr_t hand, struct _finddatai64_t * ft) }
/********************************************************************* - * _findnext64 (MSVCRT.@) + * _wfindnext64 (MSVCRT.@) * - * 64-bit version of _findnext. + * Unicode version of _wfindnext64. */ -int CDECL _findnext64(intptr_t hand, struct _finddata64_t * ft) +int CDECL _wfindnext64(intptr_t hand, struct _wfinddata64_t * ft) { - WIN32_FIND_DATAA find_data; + WIN32_FIND_DATAW find_data;
- if (!FindNextFileA((HANDLE)hand, &find_data)) + if (!FindNextFileW((HANDLE)hand, &find_data)) { *_errno() = ENOENT; return -1; }
- msvcrt_fttofd64(&find_data,ft); + msvcrt_wfttofd64(&find_data,ft); return 0; }
/********************************************************************* - * _wfindnext64 (MSVCRT.@) + * _findnext64 (MSVCRT.@) * - * Unicode version of _wfindnext64. + * 64-bit version of _findnext. */ -int CDECL _wfindnext64(intptr_t hand, struct _wfinddata64_t * ft) +int CDECL _findnext64(intptr_t hand, struct _finddata64_t * ft) { - WIN32_FIND_DATAW find_data; - - if (!FindNextFileW((HANDLE)hand, &find_data)) - { - *_errno() = ENOENT; - return -1; - } + struct _wfinddata64_t wft; + int ret;
- msvcrt_wfttofd64(&find_data,ft); - return 0; + ret = _wfindnext64(hand, &wft); + if (!ret && !finddata64_wtoa(&wft, ft)) ret = -1; + return ret; }
/********************************************************************* diff --git a/dlls/ucrtbase/tests/file.c b/dlls/ucrtbase/tests/file.c index a8934338a4b..3663575ca74 100644 --- a/dlls/ucrtbase/tests/file.c +++ b/dlls/ucrtbase/tests/file.c @@ -342,6 +342,12 @@ static void test_utf8(void) fdata64.name[0] = 'x'; hfind = _findfirst64(buf, &fdata64); ok(hfind != -1, "_findfirst64 returned %Id, errno %d\n", hfind, errno); + todo_wine_if(!is_lossless_convertion(dir)) + ok(!memcmp(file, fdata64.name, sizeof(file) - 1), "fdata64.name = %s\n", debugstr_a(fdata64.name)); + + fdata64.name[0] = 'x'; + ret = _findnext64(hfind, &fdata64); + ok(!ret, "_findnext64 returned %d, errno %d\n", ret, errno); todo_wine_if(!is_lossless_convertion(dir)) ok(!memcmp(file, fdata64.name, sizeof(file) - 1), "fdata64.name = %s\n", debugstr_a(fdata64.name)); ret = _findclose(hfind);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=150222
Your paranoid android.
=== debian11 (32 bit ja:JP report) ===
ucrtbase: file.c:363: Test failed: buf = "C:\users\winetest\AppData\Local\Temp\wct\dir\xc4\x99\xc5\x9b\xc4\x81E\file\xc4\x99\xc5\x9b\xc4\x81Ea"