[PATCH 2/2] msvcp140: Implement _File_size.
Stefan Dösinger
stefan at codeweavers.com
Sun Jul 9 15:14:37 CDT 2017
It differs from the msvcp120 version by the return value in case the
file does not exist. I can make the msvcp120 version a wrapper around
the new version that replaces the ~0ULL with 0 if desired.
Signed-off-by: Stefan Dösinger <stefan at codeweavers.com>
---
dlls/msvcp140/msvcp140.spec | 2 +-
dlls/msvcp140/tests/msvcp140.c | 47 ++++++++++++++++++++++++++++++++++++++++++
dlls/msvcp90/ios.c | 14 +++++++++++++
3 files changed, 62 insertions(+), 1 deletion(-)
diff --git a/dlls/msvcp140/msvcp140.spec b/dlls/msvcp140/msvcp140.spec
index 284f674736..1692d56a9e 100644
--- a/dlls/msvcp140/msvcp140.spec
+++ b/dlls/msvcp140/msvcp140.spec
@@ -3648,7 +3648,7 @@
@ extern _FNan _FNan
@ stub _FSinh
@ extern _FSnan _FSnan
-@ stub _File_size
+@ cdecl _File_size(wstr)
@ cdecl -ret64 _Getcoll() _Getcoll
@ cdecl _Getctype(ptr) _Getctype
@ cdecl _Getcvt(ptr) _Getcvt
diff --git a/dlls/msvcp140/tests/msvcp140.c b/dlls/msvcp140/tests/msvcp140.c
index f3dd4a0ea0..7867d915dc 100644
--- a/dlls/msvcp140/tests/msvcp140.c
+++ b/dlls/msvcp140/tests/msvcp140.c
@@ -153,6 +153,7 @@ static int (__cdecl *p__Reschedule_chore)(const _Threadpool_chore*);
static void (__cdecl *p__Release_chore)(_Threadpool_chore*);
static int (__cdecl *p_To_wide)(const char *src, WCHAR *dst);
+static ULONGLONG(__cdecl *p_File_size)(WCHAR const*);
static HMODULE msvcp;
#define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y)
@@ -216,6 +217,7 @@ static BOOL init(void)
}
SET(p_To_wide, "_To_wide");
+ SET(p_File_size, "_File_size");
init_thiscall_thunk();
return TRUE;
@@ -515,6 +517,50 @@ static void test_to_wide(void)
}
}
+static void test_File_size(void)
+{
+ ULONGLONG val;
+ HANDLE file;
+ LARGE_INTEGER file_size;
+ WCHAR test_f1_W[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','1',0};
+ WCHAR test_f2_W[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','f','2',0};
+ WCHAR test_dir_W[] = {'t','r','2','_','t','e','s','t','_','d','i','r',0};
+ WCHAR test_ne_W[] = {'t','r','2','_','t','e','s','t','_','d','i','r','/','n','e',0};
+ CreateDirectoryW(test_dir_W, NULL);
+
+ file = CreateFileW(test_f1_W, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
+ ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
+ file_size.QuadPart = 7;
+ ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
+ ok(SetEndOfFile(file), "SetEndOfFile failed\n");
+ CloseHandle(file);
+ val = p_File_size(test_f1_W);
+ ok(val == 7, "file_size is %s\n", wine_dbgstr_longlong(val));
+
+ file = CreateFileW(test_f2_W, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
+ ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
+ CloseHandle(file);
+ val = p_File_size(test_f2_W);
+ ok(val == 0, "file_size is %s\n", wine_dbgstr_longlong(val));
+
+ val = p_File_size(test_dir_W);
+ ok(val == 0, "file_size is %s\n", wine_dbgstr_longlong(val));
+
+ errno = 0xdeadbeef;
+ val = p_File_size(test_ne_W);
+ ok(val == ~0ULL, "file_size is %s\n", wine_dbgstr_longlong(val));
+ ok(errno == 0xdeadbeef, "errno = %d\n", errno);
+
+ errno = 0xdeadbeef;
+ val = p_File_size(NULL);
+ ok(val == ~0ULL, "file_size is %s\n", wine_dbgstr_longlong(val));
+ ok(errno == 0xdeadbeef, "errno = %d\n", errno);
+
+ ok(DeleteFileW(test_f1_W), "expect tr2_test_dir/f1 to exist\n");
+ ok(DeleteFileW(test_f2_W), "expect tr2_test_dir/f2 to exist\n");
+ ok(RemoveDirectoryW(test_dir_W), "expect tr2_test_dir to exist\n");
+}
+
START_TEST(msvcp140)
{
if(!init()) return;
@@ -525,5 +571,6 @@ START_TEST(msvcp140)
test__TaskEventLogger();
test_chore();
test_to_wide();
+ test_File_size();
FreeLibrary(msvcp);
}
diff --git a/dlls/msvcp90/ios.c b/dlls/msvcp90/ios.c
index 8e3376c961..3e63a0cf9d 100644
--- a/dlls/msvcp90/ios.c
+++ b/dlls/msvcp90/ios.c
@@ -15471,6 +15471,20 @@ ULONGLONG __cdecl tr2_sys__File_size_wchar(WCHAR const* path)
return ((ULONGLONG)(fad.nFileSizeHigh) << 32) + fad.nFileSizeLow;
}
+/* _File_size, msvcp140 version. Different error handling. */
+ULONGLONG __cdecl _File_size(WCHAR const* path)
+{
+ WIN32_FILE_ATTRIBUTE_DATA fad;
+
+ TRACE("(%s)\n", debugstr_w(path));
+ if(!GetFileAttributesExW(path, GetFileExInfoStandard, &fad))
+ return ~0ULL;
+ if(fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ return 0;
+
+ return ((ULONGLONG)(fad.nFileSizeHigh) << 32) + fad.nFileSizeLow;
+}
+
/* ?_Equivalent at sys@tr2 at std@@YAHPB_W0 at Z */
/* ?_Equivalent at sys@tr2 at std@@YAHPEB_W0 at Z */
int __cdecl tr2_sys__Equivalent_wchar(WCHAR const* path1, WCHAR const* path2)
--
2.13.0
More information about the wine-patches
mailing list