From: YongHaoHu Subject: [PATCH 4/6]: msvcp110: Add tr2_sys__Stat implementation and test. Message-Id: <558EE280.6020805@gmail.com> Date: Sun, 28 Jun 2015 01:50:56 +0800 --- dlls/msvcp110/msvcp110.spec | 4 +-- dlls/msvcp120/msvcp120.spec | 4 +-- dlls/msvcp120/tests/msvcp120.c | 52 +++++++++++++++++++++++++++++++++++++ dlls/msvcp120_app/msvcp120_app.spec | 4 +-- dlls/msvcp90/ios.c | 50 +++++++++++++++++++++++++++++++++++ 5 files changed, 108 insertions(+), 6 deletions(-) diff --git a/dlls/msvcp110/msvcp110.spec b/dlls/msvcp110/msvcp110.spec index 3a9e025..35e856c 100644 --- a/dlls/msvcp110/msvcp110.spec +++ b/dlls/msvcp110/msvcp110.spec @@ -1757,8 +1757,8 @@ @ stub -arch=win64 ?_Src@?3??_Getffld@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator@GU?$char_traits@G@std@@@3@1AEAVios_base@3@PEAH@Z@4QBDB @ stub -arch=win32 ?_Src@?3??_Getffld@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABAHPADAAV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@3@1AAVios_base@3@PAH@Z@4QBDB @ stub -arch=win64 ?_Src@?3??_Getffld@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@3@1AEAVios_base@3@PEAH@Z@4QBDB -@ stub -arch=win32 ?_Stat@sys@tr2@std@@YA?AW4file_type@123@PBDAAH@Z -@ stub -arch=win64 ?_Stat@sys@tr2@std@@YA?AW4file_type@123@PEBDAEAH@Z +@ cdecl -arch=win32 ?_Stat@sys@tr2@std@@YA?AW4file_type@123@PBDAAH@Z(str ptr) tr2_sys__Stat +@ cdecl -arch=win64 ?_Stat@sys@tr2@std@@YA?AW4file_type@123@PEBDAEAH@Z(str ptr) tr2_sys__Stat @ stub -arch=win32 ?_Stat@sys@tr2@std@@YA?AW4file_type@123@PB_WAAH@Z @ stub -arch=win64 ?_Stat@sys@tr2@std@@YA?AW4file_type@123@PEB_WAEAH@Z @ cdecl -arch=win32 ?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PBD@Z(str) tr2_sys__Statvfs diff --git a/dlls/msvcp120/msvcp120.spec b/dlls/msvcp120/msvcp120.spec index b251ca3..e319ed5 100644 --- a/dlls/msvcp120/msvcp120.spec +++ b/dlls/msvcp120/msvcp120.spec @@ -1718,8 +1718,8 @@ @ stub -arch=win64 ?_Src@?3??_Getffld@?$num_get@GV?$istreambuf_iterator@GU?$char_traits@G@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator@GU?$char_traits@G@std@@@3@1AEAVios_base@3@PEAH@Z@4QBDB @ stub -arch=win32 ?_Src@?3??_Getffld@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@ABAHPADAAV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@3@1AAVios_base@3@PAH@Z@4QBDB @ stub -arch=win64 ?_Src@?3??_Getffld@?$num_get@_WV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@std@@@std@@AEBAHPEADAEAV?$istreambuf_iterator@_WU?$char_traits@_W@std@@@3@1AEAVios_base@3@PEAH@Z@4QBDB -@ stub -arch=win32 ?_Stat@sys@tr2@std@@YA?AW4file_type@123@PBDAAH@Z -@ stub -arch=win64 ?_Stat@sys@tr2@std@@YA?AW4file_type@123@PEBDAEAH@Z +@ cdecl -arch=win32 ?_Stat@sys@tr2@std@@YA?AW4file_type@123@PBDAAH@Z(str ptr) tr2_sys__Stat +@ cdecl -arch=win64 ?_Stat@sys@tr2@std@@YA?AW4file_type@123@PEBDAEAH@Z(str ptr) tr2_sys__Stat @ stub -arch=win32 ?_Stat@sys@tr2@std@@YA?AW4file_type@123@PB_WAAH@Z @ stub -arch=win64 ?_Stat@sys@tr2@std@@YA?AW4file_type@123@PEB_WAEAH@Z @ cdecl -arch=win32 ?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PBD@Z(str) tr2_sys__Statvfs diff --git a/dlls/msvcp120/tests/msvcp120.c b/dlls/msvcp120/tests/msvcp120.c index 0e54667..1154519 100644 --- a/dlls/msvcp120/tests/msvcp120.c +++ b/dlls/msvcp120/tests/msvcp120.c @@ -44,6 +44,12 @@ typedef struct { ULONGLONG available; } space_info; +typedef enum { + status_unknown, file_not_found, regular_file, directory_file, + symlink_file, block_file, character_file, fifo_file, socket_file, + type_unknown +} file_type; + static inline const char* debugstr_longlong(ULONGLONG ll) { static char string[17]; @@ -75,6 +81,7 @@ static MSVCP_bool (__cdecl *p_tr2_sys__Remove_dir)(char const*); static int (__cdecl *p_tr2_sys__Copy_file)(char const*, char const*, MSVCP_bool); static int (__cdecl *p_tr2_sys__Rename)(char const*, char const*); static space_info (__cdecl *p_tr2_sys__Statvfs)(char const*); +static file_type (__cdecl *p_tr2_sys__Stat)(char const*, int *); static HMODULE msvcp; #define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y) @@ -121,6 +128,8 @@ static BOOL init(void) "?_Rename@sys@tr2@std@@YAHPEBD0@Z"); SET(p_tr2_sys__Statvfs, "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PEBD@Z"); + SET(p_tr2_sys__Stat, + "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PEBDAEAH@Z"); } else { SET(p_tr2_sys__File_size, "?_File_size@sys@tr2@std@@YA_KPBD@Z"); @@ -140,6 +149,8 @@ static BOOL init(void) "?_Rename@sys@tr2@std@@YAHPBD0@Z"); SET(p_tr2_sys__Statvfs, "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PBD@Z"); + SET(p_tr2_sys__Stat, + "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PBDAAH@Z"); } msvcr = GetModuleHandleA("msvcr120.dll"); @@ -678,6 +689,46 @@ static void test_tr2_sys__Statvfs(void) 0, debugstr_longlong(info.free)); } +static void test_tr2_sys__Stat(void) +{ + int i, err_code; + HANDLE file; + file_type val; + struct { + char const *path; + file_type ret; + int err_code; + } tests[] = { + { NULL, status_unknown, ERROR_INVALID_PARAMETER }, + { "tr2_test_dir", directory_file, ERROR_SUCCESS }, + { "tr2_test_dir\\f1", regular_file, ERROR_SUCCESS }, + { "\\\\.\\PiPe\\tests_pipe.c", regular_file, ERROR_SUCCESS }, + { "tr2_test_dir\\not_exist_file ", file_not_found, ERROR_SUCCESS }, + { "tr2_test_dir\\??invalid_name>>", file_not_found, ERROR_SUCCESS }, + }; + + CreateDirectoryA("tr2_test_dir", NULL); + file = CreateFileA("tr2_test_dir/f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL); + ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n"); + CloseHandle(file); + file = CreateNamedPipeA("\\\\.\\PiPe\\tests_pipe.c", + PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 2, 1024, 1024, + NMPWAIT_USE_DEFAULT_WAIT, NULL); + ok(file != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); + + for(i=0; i= 100 #define VBTABLE_ALIGN 8 #else @@ -14333,6 +14339,50 @@ space_info __cdecl tr2_sys__Statvfs(const char* path) return info; } +static file_type stat_set_error(int *err_code) +{ + file_type ret; + *err_code = ERROR_SUCCESS; + + switch(GetLastError()) { + case ERROR_FILE_NOT_FOUND: + case ERROR_BAD_NETPATH: + case ERROR_INVALID_NAME: + case ERROR_BAD_PATHNAME: + case ERROR_PATH_NOT_FOUND: + ret = file_not_found; + break; + case ERROR_BAD_DEV_TYPE: + ret = regular_file; + break; + default: + ret = status_unknown; + } + return ret; +} + +/* ?_Stat@sys@tr2@std@@YA?AW4file_type@123@PBDAAH@Z */ +/* ?_Stat@sys@tr2@std@@YA?AW4file_type@123@PEBDAEAH@Z */ +file_type tr2_sys__Stat(char const *path, int *err_code) +{ + TRACE("(%s %p)\n", debugstr_a(path), err_code); + DWORD attr; + if(!path) { + *err_code = ERROR_INVALID_PARAMETER; + return status_unknown; + } + + attr = GetFileAttributesA(path); + if(attr == INVALID_FILE_ATTRIBUTES) + return stat_set_error(err_code); + + if(attr & FILE_ATTRIBUTE_REPARSE_POINT) + FIXME("reparse point is not supported yet\n"); + + *err_code = ERROR_SUCCESS; + return (attr & FILE_ATTRIBUTE_DIRECTORY)?directory_file:regular_file; +} + /* ??0strstream@std@@QAE@PADHH@Z */ /* ??0strstream@std@@QEAA@PEAD_JH@Z */ #if STREAMSIZE_BITS == 64