From d427e980caa6e51250e29c452fe87e9d0226e38b Mon Sep 17 00:00:00 2001 From: Christoph von Wittich Date: Tue, 22 Dec 2009 09:43:11 +0000 Subject: [PATCH] sync kernel32_winetest with wine 1.1.35 svn path=/trunk/; revision=44695 --- rostests/winetests/kernel32/actctx.c | 11 +- rostests/winetests/kernel32/environ.c | 15 +- rostests/winetests/kernel32/file.c | 202 +++++++++++++++++++++++--- rostests/winetests/kernel32/locale.c | 82 +++++++++++ rostests/winetests/kernel32/path.c | 200 ++++++++++++++++++++++++- rostests/winetests/kernel32/volume.c | 5 +- 6 files changed, 484 insertions(+), 31 deletions(-) diff --git a/rostests/winetests/kernel32/actctx.c b/rostests/winetests/kernel32/actctx.c index 8a8d03e224e..8f51dfb1d96 100644 --- a/rostests/winetests/kernel32/actctx.c +++ b/rostests/winetests/kernel32/actctx.c @@ -869,7 +869,7 @@ static void test_basic_info(HANDLE handle) SIZE_T size; BOOL b; - b = pQueryActCtxW(0, handle, NULL, + b = pQueryActCtxW(QUERY_ACTCTX_FLAG_NO_ADDREF, handle, NULL, ActivationContextBasicInformation, &basic, sizeof(basic), &size); @@ -878,7 +878,8 @@ static void test_basic_info(HANDLE handle) ok (basic.dwFlags == 0, "unexpected flags %x\n",basic.dwFlags); ok (basic.hActCtx == handle, "unexpected handle\n"); - b = pQueryActCtxW(QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX, handle, NULL, + b = pQueryActCtxW(QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX | + QUERY_ACTCTX_FLAG_NO_ADDREF, handle, NULL, ActivationContextBasicInformation, &basic, sizeof(basic), &size); if (handle) @@ -960,15 +961,15 @@ static void test_actctx(void) pReleaseActCtx(handle); } - if(!create_manifest_file("test3.manifest", manifest2, -1, "testdep.manifest", testdep_manifest2)) { + if(!create_manifest_file("test2-2.manifest", manifest2, -1, "testdep.manifest", testdep_manifest2)) { skip("Could not create manifest file\n"); return; } trace("manifest2 depmanifest2\n"); - handle = test_create("test3.manifest", manifest2); - DeleteFileA("test3.manifest"); + handle = test_create("test2-2.manifest", manifest2); + DeleteFileA("test2-2.manifest"); DeleteFileA("testdep.manifest"); if(handle != INVALID_HANDLE_VALUE) { test_basic_info(handle); diff --git a/rostests/winetests/kernel32/environ.c b/rostests/winetests/kernel32/environ.c index b3526675b20..19d11b599a2 100755 --- a/rostests/winetests/kernel32/environ.c +++ b/rostests/winetests/kernel32/environ.c @@ -395,7 +395,11 @@ static void test_GetComputerNameExA(void) ok(error == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", error); /* size is not set in win2k */ - size = MAX_COMP_NAME; + if (size == 0) + { + win_skip("Win2k doesn't set the size\n"); + size = MAX_COMP_NAME; + } name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0])); ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError()); ret = pGetComputerNameExA(ComputerNameDnsDomain, name, &size); @@ -410,7 +414,8 @@ static void test_GetComputerNameExA(void) ok(error == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", error); /* size is not set in win2k */ - size = MAX_COMP_NAME; + if (size == 0) + size = MAX_COMP_NAME; name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0])); ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError()); ret = pGetComputerNameExA(ComputerNameDnsFullyQualified, name, &size); @@ -425,7 +430,8 @@ static void test_GetComputerNameExA(void) ok(error == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", error); /* size is not set in win2k */ - size = MAX_COMP_NAME; + if (size == 0) + size = MAX_COMP_NAME; name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0])); ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError()); ret = pGetComputerNameExA(ComputerNameDnsHostname, name, &size); @@ -440,7 +446,8 @@ static void test_GetComputerNameExA(void) ok(error == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", error); /* size is not set in win2k */ - size = MAX_COMP_NAME; + if (size == 0) + size = MAX_COMP_NAME; name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0])); ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError()); ret = pGetComputerNameExA(ComputerNameNetBIOS, name, &size); diff --git a/rostests/winetests/kernel32/file.c b/rostests/winetests/kernel32/file.c index ec61659ad0b..3cc9022b32a 100755 --- a/rostests/winetests/kernel32/file.c +++ b/rostests/winetests/kernel32/file.c @@ -649,12 +649,10 @@ static void test_CopyFileA(void) ok(hmapfile != NULL, "CreateFileMapping: error %d\n", GetLastError()); ret = CopyFileA(source, dest, FALSE); - todo_wine { - ok(!ret, "CopyFileA: expected failure\n"); - ok(GetLastError() == ERROR_USER_MAPPED_FILE || - broken(GetLastError() == ERROR_SHARING_VIOLATION), /* Win9x and WinMe */ - "CopyFileA with mapped dest file: expected ERROR_USER_MAPPED_FILE, got %d\n", GetLastError()); - } + ok(!ret, "CopyFileA: expected failure\n"); + ok(GetLastError() == ERROR_USER_MAPPED_FILE || + broken(GetLastError() == ERROR_SHARING_VIOLATION), /* Win9x */ + "CopyFileA with mapped dest file: expected ERROR_USER_MAPPED_FILE, got %d\n", GetLastError()); CloseHandle(hmapfile); CloseHandle(hfile); @@ -1616,7 +1614,80 @@ static void test_LockFile(void) DeleteFileA( filename ); } -static inline int is_sharing_compatible( DWORD access1, DWORD sharing1, DWORD access2, DWORD sharing2, BOOL is_win9x ) +static BOOL create_fake_dll( LPCSTR filename ) +{ + IMAGE_DOS_HEADER *dos; + IMAGE_NT_HEADERS *nt; + IMAGE_SECTION_HEADER *sec; + BYTE *buffer; + DWORD lfanew = sizeof(*dos); + DWORD size = lfanew + sizeof(*nt) + sizeof(*sec); + DWORD written; + BOOL ret; + + HANDLE file = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 ); + if (file == INVALID_HANDLE_VALUE) return FALSE; + + buffer = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size ); + + dos = (IMAGE_DOS_HEADER *)buffer; + dos->e_magic = IMAGE_DOS_SIGNATURE; + dos->e_cblp = sizeof(*dos); + dos->e_cp = 1; + dos->e_cparhdr = lfanew / 16; + dos->e_minalloc = 0; + dos->e_maxalloc = 0xffff; + dos->e_ss = 0x0000; + dos->e_sp = 0x00b8; + dos->e_lfarlc = lfanew; + dos->e_lfanew = lfanew; + + nt = (IMAGE_NT_HEADERS *)(buffer + lfanew); + nt->Signature = IMAGE_NT_SIGNATURE; +#if defined __i386__ + nt->FileHeader.Machine = IMAGE_FILE_MACHINE_I386; +#elif defined __x86_64__ + nt->FileHeader.Machine = IMAGE_FILE_MACHINE_AMD64; +#elif defined __powerpc__ + nt->FileHeader.Machine = IMAGE_FILE_MACHINE_POWERPC; +#else +# error You must specify the machine type +#endif + nt->FileHeader.NumberOfSections = 1; + nt->FileHeader.SizeOfOptionalHeader = IMAGE_SIZEOF_NT_OPTIONAL_HEADER; + nt->FileHeader.Characteristics = IMAGE_FILE_DLL | IMAGE_FILE_EXECUTABLE_IMAGE; + nt->OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC; + nt->OptionalHeader.MajorLinkerVersion = 1; + nt->OptionalHeader.MinorLinkerVersion = 0; + nt->OptionalHeader.ImageBase = 0x10000000; + nt->OptionalHeader.SectionAlignment = 0x1000; + nt->OptionalHeader.FileAlignment = 0x1000; + nt->OptionalHeader.MajorOperatingSystemVersion = 1; + nt->OptionalHeader.MinorOperatingSystemVersion = 0; + nt->OptionalHeader.MajorImageVersion = 1; + nt->OptionalHeader.MinorImageVersion = 0; + nt->OptionalHeader.MajorSubsystemVersion = 4; + nt->OptionalHeader.MinorSubsystemVersion = 0; + nt->OptionalHeader.SizeOfImage = 0x2000; + nt->OptionalHeader.SizeOfHeaders = size; + nt->OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI; + nt->OptionalHeader.NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES; + + sec = (IMAGE_SECTION_HEADER *)(nt + 1); + memcpy( sec->Name, ".rodata", sizeof(".rodata") ); + sec->Misc.VirtualSize = 0x1000; + sec->VirtualAddress = 0x1000; + sec->SizeOfRawData = 0; + sec->PointerToRawData = 0; + sec->Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE; + + ret = WriteFile( file, buffer, size, &written, NULL ) && written == size; + HeapFree( GetProcessHeap(), 0, buffer ); + CloseHandle( file ); + return ret; +} + +static int is_sharing_compatible( DWORD access1, DWORD sharing1, DWORD access2, DWORD sharing2, BOOL is_win9x ) { if (!is_win9x) { @@ -1641,6 +1712,14 @@ static inline int is_sharing_compatible( DWORD access1, DWORD sharing1, DWORD ac return 1; } +static int is_sharing_map_compatible( DWORD map_access, DWORD access2, DWORD sharing2 ) +{ + if ((map_access == PAGE_READWRITE || map_access == PAGE_EXECUTE_READWRITE) && + !(sharing2 & FILE_SHARE_WRITE)) return 0; + if ((map_access & SEC_IMAGE) && (access2 & GENERIC_WRITE)) return 0; + return 1; +} + static void test_file_sharing(void) { static const DWORD access_modes[] = @@ -1651,20 +1730,20 @@ static void test_file_sharing(void) FILE_SHARE_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_SHARE_DELETE, FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE }; + static const DWORD mapping_modes[] = + { PAGE_READONLY, PAGE_WRITECOPY, PAGE_READWRITE, SEC_IMAGE | PAGE_WRITECOPY }; int a1, s1, a2, s2; int ret; HANDLE h, h2; BOOL is_win9x = FALSE; /* make sure the file exists */ - h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 ); - if (h == INVALID_HANDLE_VALUE) + if (!create_fake_dll( filename )) { ok(0, "couldn't create file \"%s\" (err=%d)\n", filename, GetLastError()); return; } is_win9x = GetFileAttributesW(filenameW) == INVALID_FILE_ATTRIBUTES; - CloseHandle( h ); for (a1 = 0; a1 < sizeof(access_modes)/sizeof(access_modes[0]); a1++) { @@ -1693,12 +1772,10 @@ static void test_file_sharing(void) SetLastError(0xdeadbeef); h2 = CreateFileA( filename, access_modes[a2], sharing_modes[s2], NULL, OPEN_EXISTING, 0, 0 ); - + ret = GetLastError(); if (is_sharing_compatible( access_modes[a1], sharing_modes[s1], access_modes[a2], sharing_modes[s2], is_win9x )) { - ret = GetLastError(); - ok( h2 != INVALID_HANDLE_VALUE, "open failed for modes %x/%x/%x/%x\n", access_modes[a1], sharing_modes[s1], @@ -1706,13 +1783,9 @@ static void test_file_sharing(void) ok( ret == 0xdeadbeef /* Win9x */ || ret == 0, /* XP */ "wrong error code %d\n", ret ); - - CloseHandle( h2 ); } else { - ret = GetLastError(); - ok( h2 == INVALID_HANDLE_VALUE, "open succeeded for modes %x/%x/%x/%x\n", access_modes[a1], sharing_modes[s1], @@ -1720,12 +1793,107 @@ static void test_file_sharing(void) ok( ret == ERROR_SHARING_VIOLATION, "wrong error code %d\n", ret ); } + if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 ); } } CloseHandle( h ); } } + for (a1 = 0; a1 < sizeof(mapping_modes)/sizeof(mapping_modes[0]); a1++) + { + HANDLE m; + + create_fake_dll( filename ); + SetLastError(0xdeadbeef); + h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 ); + if (h == INVALID_HANDLE_VALUE) + { + ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError()); + return; + } + m = CreateFileMappingA( h, NULL, mapping_modes[a1], 0, 0, NULL ); + ok( m != 0, "failed to create mapping %x err %u\n", mapping_modes[a1], GetLastError() ); + CloseHandle( h ); + if (!m) continue; + + for (a2 = 0; a2 < sizeof(access_modes)/sizeof(access_modes[0]); a2++) + { + for (s2 = 0; s2 < sizeof(sharing_modes)/sizeof(sharing_modes[0]); s2++) + { + /* Win9x doesn't support FILE_SHARE_DELETE */ + if (is_win9x && (sharing_modes[s2] & FILE_SHARE_DELETE)) + continue; + + SetLastError(0xdeadbeef); + h2 = CreateFileA( filename, access_modes[a2], sharing_modes[s2], + NULL, OPEN_EXISTING, 0, 0 ); + + ret = GetLastError(); + if (h2 == INVALID_HANDLE_VALUE) + { + if (is_sharing_map_compatible(mapping_modes[a1], access_modes[a2], sharing_modes[s2])) + ok( is_win9x, /* there's no sharing at all with a mapping on win9x */ + "open failed for modes map %x/%x/%x\n", + mapping_modes[a1], access_modes[a2], sharing_modes[s2] ); + ok( ret == ERROR_SHARING_VIOLATION, + "wrong error code %d\n", ret ); + } + else + { + if (!is_sharing_map_compatible(mapping_modes[a1], access_modes[a2], sharing_modes[s2])) + ok( broken(1), /* no checking on nt4 */ + "open succeeded for modes map %x/%x/%x\n", + mapping_modes[a1], access_modes[a2], sharing_modes[s2] ); + ok( ret == 0xdeadbeef /* Win9x */ || + ret == 0, /* XP */ + "wrong error code %d\n", ret ); + CloseHandle( h2 ); + } + } + } + + /* try CREATE_ALWAYS over an existing mapping */ + SetLastError(0xdeadbeef); + h2 = CreateFileA( filename, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, CREATE_ALWAYS, 0, 0 ); + ret = GetLastError(); + if ((mapping_modes[a1] & SEC_IMAGE) || is_win9x) + { + ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %x\n", mapping_modes[a1] ); + ok( ret == ERROR_SHARING_VIOLATION, "wrong error code %d for %x\n", ret, mapping_modes[a1] ); + } + else + { + ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %x\n", mapping_modes[a1] ); + ok( ret == ERROR_USER_MAPPED_FILE, "wrong error code %d for %x\n", ret, mapping_modes[a1] ); + } + if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 ); + + /* try DELETE_ON_CLOSE over an existing mapping */ + SetLastError(0xdeadbeef); + h2 = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0 ); + ret = GetLastError(); + if (is_win9x) + { + ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %x\n", mapping_modes[a1] ); + ok( ret == ERROR_SHARING_VIOLATION, "wrong error code %d for %x\n", ret, mapping_modes[a1] ); + } + else if (mapping_modes[a1] & SEC_IMAGE) + { + ok( h2 == INVALID_HANDLE_VALUE, "create succeeded for map %x\n", mapping_modes[a1] ); + ok( ret == ERROR_ACCESS_DENIED, "wrong error code %d for %x\n", ret, mapping_modes[a1] ); + } + else + { + ok( h2 != INVALID_HANDLE_VALUE, "open failed for map %x err %u\n", mapping_modes[a1], ret ); + } + if (h2 != INVALID_HANDLE_VALUE) CloseHandle( h2 ); + + CloseHandle( m ); + } + SetLastError(0xdeadbeef); h = CreateFileA( filename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, 0 ); ok( h != INVALID_HANDLE_VALUE, "CreateFileA error %d\n", GetLastError() ); diff --git a/rostests/winetests/kernel32/locale.c b/rostests/winetests/kernel32/locale.c index 37dc0aada7e..a462a142857 100755 --- a/rostests/winetests/kernel32/locale.c +++ b/rostests/winetests/kernel32/locale.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "wine/test.h" #include "windef.h" @@ -466,7 +467,10 @@ static void test_GetDateFormatA(void) int ret; SYSTEMTIME curtime; LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT); + LCID lcid_ru = MAKELCID(MAKELANGID(LANG_RUSSIAN, SUBLANG_NEUTRAL), SORT_DEFAULT); char buffer[BUFFER_SIZE], input[BUFFER_SIZE], Expected[BUFFER_SIZE]; + char Broken[BUFFER_SIZE]; + char short_day[10], month[10], genitive_month[10]; memset(&curtime, 2, sizeof(SYSTEMTIME)); /* Invalid time */ STRINGSA("ddd',' MMM dd yy",""); @@ -542,7 +546,85 @@ static void test_GetDateFormatA(void) &curtime, input, buffer, COUNTOF(buffer)); ok(!ret && GetLastError() == ERROR_INVALID_FLAGS, "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError()); + + ret = GetDateFormat(lcid_ru, 0, &curtime, "ddMMMM", buffer, COUNTOF(buffer)); + if (!ret) + { + win_skip("LANG_RUSSIAN locale data unavailable\n"); + return; + } + + /* month part should be in genitive form */ + strcpy(genitive_month, buffer + 2); + ret = GetDateFormat(lcid_ru, 0, &curtime, "MMMM", buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); + strcpy(month, buffer); + ok(strcmp(genitive_month, month) != 0, "Expected different month forms\n"); + + ret = GetDateFormat(lcid_ru, 0, &curtime, "ddd", buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); + strcpy(short_day, buffer); + + STRINGSA("dd MMMMddd dd", ""); + sprintf(Expected, "04 %s%s 04", genitive_month, short_day); + ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); + EXPECT_EQA; + + STRINGSA("MMMMddd dd", ""); + sprintf(Expected, "%s%s 04", month, short_day); + ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); EXPECT_EQA; + + STRINGSA("MMMMddd", ""); + sprintf(Expected, "%s%s", month, short_day); + ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); + EXPECT_EQA; + + STRINGSA("MMMMdd", ""); + sprintf(Expected, "%s04", genitive_month); + sprintf(Broken, "%s04", month); + ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); + ok(strncmp(buffer, Expected, strlen(Expected)) == 0 || + broken(strncmp(buffer, Broken, strlen(Broken)) == 0) /* nt4 */, + "Expected '%s', got '%s'\n", Expected, buffer); + + STRINGSA("MMMMdd ddd", ""); + sprintf(Expected, "%s04 %s", genitive_month, short_day); + sprintf(Broken, "%s04 %s", month, short_day); + ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); + ok(strncmp(buffer, Expected, strlen(Expected)) == 0 || + broken(strncmp(buffer, Broken, strlen(Broken)) == 0) /* nt4 */, + "Expected '%s', got '%s'\n", Expected, buffer); + + STRINGSA("dd dddMMMM", ""); + sprintf(Expected, "04 %s%s", short_day, month); + ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); + EXPECT_EQA; + + STRINGSA("dd dddMMMM ddd MMMMdd", ""); + sprintf(Expected, "04 %s%s %s %s04", short_day, month, short_day, genitive_month); + sprintf(Broken, "04 %s%s %s %s04", short_day, month, short_day, month); + ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); + ok(strncmp(buffer, Expected, strlen(Expected)) == 0 || + broken(strncmp(buffer, Broken, strlen(Broken)) == 0) /* nt4 */, + "Expected '%s', got '%s'\n", Expected, buffer); + + /* with literal part */ + STRINGSA("ddd',' MMMM dd", ""); + sprintf(Expected, "%s, %s 04", short_day, genitive_month); + sprintf(Broken, "%s, %s 04", short_day, month); + ret = GetDateFormat(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer)); + ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError()); + ok(strncmp(buffer, Expected, strlen(Expected)) == 0 || + broken(strncmp(buffer, Broken, strlen(Broken)) == 0) /* nt4 */, + "Expected '%s', got '%s'\n", Expected, buffer); } static void test_GetDateFormatW(void) diff --git a/rostests/winetests/kernel32/path.c b/rostests/winetests/kernel32/path.c index de26fc90112..1c899c8caec 100755 --- a/rostests/winetests/kernel32/path.c +++ b/rostests/winetests/kernel32/path.c @@ -952,14 +952,133 @@ static void test_GetTempPath(void) SetEnvironmentVariableA("TMP", save_TMP); } +static void test_GetLongPathNameA(void) +{ + DWORD length, explength, hostsize; + char tempfile[MAX_PATH]; + char longpath[MAX_PATH]; + char unc_prefix[MAX_PATH]; + char unc_short[MAX_PATH], unc_long[MAX_PATH]; + char temppath[MAX_PATH], temppath2[MAX_PATH]; + HANDLE file; + + if (!pGetLongPathNameA) + return; + + GetTempPathA(MAX_PATH, tempfile); + lstrcatA(tempfile, "longfilename.longext"); + + file = CreateFileA(tempfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + CloseHandle(file); + + /* Test a normal path with a small buffer size */ + memset(temppath, 0, MAX_PATH); + length = pGetLongPathNameA(tempfile, temppath, 4); + /* We have a failure so length should be the minumum plus the terminating '0' */ + ok(length >= lstrlen(tempfile) + 1, "Wrong length\n"); + ok(temppath[0] == 0, "Buffer should not have been touched\n"); + + /* Some UNC syntax tests */ + + memset(temppath, 0, MAX_PATH); + memset(temppath2, 0, MAX_PATH); + lstrcpyA(temppath2, "\\\\?\\"); + lstrcatA(temppath2, tempfile); + explength = length + 4; + + SetLastError(0xdeadbeef); + length = pGetLongPathNameA(temppath2, NULL, 0); + if (length == 0 && GetLastError() == ERROR_BAD_NET_NAME) + { + win_skip("UNC syntax tests don't work on Win98/WinMe\n"); + DeleteFileA(tempfile); + return; + } + ok(length == explength, "Wrong length %d, expected %d\n", length, explength); + + length = pGetLongPathNameA(temppath2, NULL, MAX_PATH); + ok(length == explength, "Wrong length %d, expected %d\n", length, explength); + + length = pGetLongPathNameA(temppath2, temppath, 4); + ok(length == explength, "Wrong length %d, expected %d\n", length, explength); + ok(temppath[0] == 0, "Buffer should not have been touched\n"); + + /* Now an UNC path with the computername */ + lstrcpyA(unc_prefix, "\\\\"); + hostsize = sizeof(unc_prefix) - 2; + GetComputerName(unc_prefix + 2, &hostsize); + lstrcatA(unc_prefix, "\\"); + + /* Create a short syntax for the whole unc path */ + memset(unc_short, 0, MAX_PATH); + GetShortPathNameA(tempfile, temppath, MAX_PATH); + lstrcpyA(unc_short, unc_prefix); + unc_short[lstrlenA(unc_short)] = temppath[0]; + lstrcatA(unc_short, "$\\"); + lstrcatA(unc_short, strchr(temppath, '\\') + 1); + + /* Create a long syntax for reference */ + memset(longpath, 0, MAX_PATH); + pGetLongPathNameA(tempfile, temppath, MAX_PATH); + lstrcpyA(longpath, unc_prefix); + longpath[lstrlenA(longpath)] = temppath[0]; + lstrcatA(longpath, "$\\"); + lstrcatA(longpath, strchr(temppath, '\\') + 1); + + /* NULL test */ + SetLastError(0xdeadbeef); + length = pGetLongPathNameA(unc_short, NULL, 0); + if (length == 0 && GetLastError() == ERROR_BAD_NETPATH) + { + /* Seen on Window XP Home */ + win_skip("UNC with computername is not supported\n"); + DeleteFileA(tempfile); + return; + } + explength = lstrlenA(longpath) + 1; + todo_wine + ok(length == explength, "Wrong length %d, expected %d\n", length, explength); + + length = pGetLongPathNameA(unc_short, NULL, MAX_PATH); + todo_wine + ok(length == explength, "Wrong length %d, expected %d\n", length, explength); + + memset(unc_long, 0, MAX_PATH); + length = pGetLongPathNameA(unc_short, unc_long, lstrlenA(unc_short)); + /* length will include terminating '0' on failure */ + todo_wine + ok(length == explength, "Wrong length %d, expected %d\n", length, explength); + ok(unc_long[0] == 0, "Buffer should not have been touched\n"); + + memset(unc_long, 0, MAX_PATH); + length = pGetLongPathNameA(unc_short, unc_long, length); + /* length doesn't include terminating '0' on success */ + explength--; + todo_wine + { + ok(length == explength, "Wrong length %d, expected %d\n", length, explength); + ok(!lstrcmpiA(unc_long, longpath), "Expected (%s), got (%s)\n", longpath, unc_long); + } + + DeleteFileA(tempfile); +} + static void test_GetLongPathNameW(void) { - DWORD length; + DWORD length, expanded; + BOOL ret; + HANDLE file; WCHAR empty[MAX_PATH]; + WCHAR tempdir[MAX_PATH], name[200]; + WCHAR dirpath[4 + MAX_PATH + 200]; /* To ease removal */ + WCHAR shortpath[4 + MAX_PATH + 200 + 1 + 200]; + static const WCHAR prefix[] = { '\\','\\','?','\\', 0}; + static const WCHAR backslash[] = { '\\', 0}; + static const WCHAR letterX[] = { 'X', 0}; + + if (!pGetLongPathNameW) + return; - /* Not present in all windows versions */ - if(pGetLongPathNameW) - { SetLastError(0xdeadbeef); length = pGetLongPathNameW(NULL,NULL,0); if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) @@ -975,7 +1094,73 @@ static void test_GetLongPathNameW(void) length = pGetLongPathNameW(empty,NULL,0); ok(0==length,"GetLongPathNameW returned %d but expected 0\n",length); ok(GetLastError()==ERROR_PATH_NOT_FOUND,"GetLastError returned %d but expected ERROR_PATH_NOT_FOUND\n",GetLastError()); + + /* Create a long path name. The path needs to exist for these tests to + * succeed so we need the "\\?\" prefix when creating directories and + * files. + */ + name[0] = 0; + while (lstrlenW(name) < (sizeof(name)/sizeof(WCHAR) - 1)) + lstrcatW(name, letterX); + + GetTempPathW(MAX_PATH, tempdir); + + lstrcpyW(shortpath, prefix); + lstrcatW(shortpath, tempdir); + lstrcatW(shortpath, name); + lstrcpyW(dirpath, shortpath); + ret = CreateDirectoryW(shortpath, NULL); + ok(ret, "Could not create the temporary directory : %d\n", GetLastError()); + lstrcatW(shortpath, backslash); + lstrcatW(shortpath, name); + + /* Path does not exist yet and we know it overruns MAX_PATH */ + + /* No prefix */ + SetLastError(0xdeadbeef); + length = pGetLongPathNameW(shortpath + 4, NULL, 0); + ok(length == 0, "Expected 0, got %d\n", length); + todo_wine + ok(GetLastError() == ERROR_PATH_NOT_FOUND, + "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError()); + /* With prefix */ + SetLastError(0xdeadbeef); + length = pGetLongPathNameW(shortpath, NULL, 0); + todo_wine + { + ok(length == 0, "Expected 0, got %d\n", length); + ok(GetLastError() == ERROR_FILE_NOT_FOUND, + "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError()); } + + file = CreateFileW(shortpath, GENERIC_READ|GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + ok(file != INVALID_HANDLE_VALUE, + "Could not create the temporary file : %d.\n", GetLastError()); + CloseHandle(file); + + /* Path exists */ + + /* No prefix */ + SetLastError(0xdeadbeef); + length = pGetLongPathNameW(shortpath + 4, NULL, 0); + todo_wine + { + ok(length == 0, "Expected 0, got %d\n", length); + ok(GetLastError() == ERROR_PATH_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %d\n", GetLastError()); + } + /* With prefix */ + expanded = 4 + (pGetLongPathNameW(tempdir, NULL, 0) - 1) + lstrlenW(name) + 1 + lstrlenW(name) + 1; + SetLastError(0xdeadbeef); + length = pGetLongPathNameW(shortpath, NULL, 0); + ok(length == expanded, "Expected %d, got %d\n", expanded, length); + + /* NULL buffer with length crashes on Windows */ + if (0) + length = pGetLongPathNameW(shortpath, NULL, 20); + + ok(DeleteFileW(shortpath), "Could not delete temporary file\n"); + ok(RemoveDirectoryW(dirpath), "Could not delete temporary directory\n"); } static void test_GetShortPathNameW(void) @@ -1273,11 +1458,18 @@ START_TEST(path) (void*)GetProcAddress( GetModuleHandleA("kernel32.dll"), "NeedCurrentDirectoryForExePathW" ); + /* Report only once */ + if (!pGetLongPathNameA) + win_skip("GetLongPathNameA is not available\n"); + if (!pGetLongPathNameW) + win_skip("GetLongPathNameW is not available\n"); + test_InitPathA(curdir, &curDrive, &otherDrive); test_CurrentDirectoryA(origdir,curdir); test_PathNameA(curdir, curDrive, otherDrive); test_CleanupPathA(origdir,curdir); test_GetTempPath(); + test_GetLongPathNameA(); test_GetLongPathNameW(); test_GetShortPathNameW(); test_GetSystemDirectory(); diff --git a/rostests/winetests/kernel32/volume.c b/rostests/winetests/kernel32/volume.c index f569247a1c2..efd74d5abf2 100644 --- a/rostests/winetests/kernel32/volume.c +++ b/rostests/winetests/kernel32/volume.c @@ -155,8 +155,11 @@ static void test_GetVolumeNameForVolumeMountPointA(void) GetLastError()); /* Try on a arbitrary directory */ + /* On FAT filesystems it seems that GetLastError() is set to + ERROR_INVALID_FUNCTION. */ ret = pGetVolumeNameForVolumeMountPointA(temp_path, volume, len); - ok(ret == FALSE && GetLastError() == ERROR_NOT_A_REPARSE_POINT, + ok(ret == FALSE && (GetLastError() == ERROR_NOT_A_REPARSE_POINT || + GetLastError() == ERROR_INVALID_FUNCTION), "GetVolumeNameForVolumeMountPointA failed on %s, last=%d\n", temp_path, GetLastError()); -- 2.17.1