-- v2: msvcrt: Call _wfindnext64 in _findnext64 function. msvcrt: Call _wfindfirst64 in _findfirst64 function. msvcrt: Call _wfindnext32 in _findnext32 function. msvcrt: Call _wfindfirst32 in _findfirst32 function. include: Cleanup corecrt_io.h file and use it in io.h. msvcrt: Prepare _searchenv_s() for utf-8 encoded filename.
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 | 7 +++++++ 2 files changed, 18 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..ad0eb086fbe 100644 --- a/dlls/ucrtbase/tests/file.c +++ b/dlls/ucrtbase/tests/file.c @@ -320,6 +320,13 @@ 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)); + todo_wine_if(!is_lossless_convertion(file)) + 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 ad0eb086fbe..227e7d47058 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 227e7d47058..1e2a141260a 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 1e2a141260a..f050a0e47e6 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 f050a0e47e6..ef732479165 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);