From: Amine Khaldi Date: Sat, 12 May 2012 19:33:11 +0000 (+0000) Subject: [KERNEL32_WINETEST] X-Git-Tag: backups/ros-csrss@57560~972 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=b8eb8fbaacabf27b634e97f33be78fbda37b4178;hp=6cdf643af6e3da8a25e0c94648aab912786dec13 [KERNEL32_WINETEST] * Sync to Wine 1.5.4. I excluded loader and virtual tests from the sync until bug #7071 is fixed. See issue #7070 for more details. svn path=/trunk/; revision=56567 --- diff --git a/rostests/winetests/kernel32/actctx.c b/rostests/winetests/kernel32/actctx.c index b7f30109786..3af6e6317f9 100644 --- a/rostests/winetests/kernel32/actctx.c +++ b/rostests/winetests/kernel32/actctx.c @@ -591,7 +591,7 @@ static HANDLE test_create(const char *file, const char *manifest) ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); ok(actctx.cbSize == sizeof(actctx), "actctx.cbSize=%d\n", actctx.cbSize); - ok(actctx.dwFlags == 0, "actctx.=%d\n", actctx.dwFlags); + ok(actctx.dwFlags == 0, "actctx.dwFlags=%d\n", actctx.dwFlags); ok(actctx.lpSource == path, "actctx.lpSource=%p\n", actctx.lpSource); ok(actctx.wProcessorArchitecture == 0, "actctx.wProcessorArchitecture=%d\n", actctx.wProcessorArchitecture); @@ -599,7 +599,7 @@ static HANDLE test_create(const char *file, const char *manifest) ok(actctx.lpAssemblyDirectory == NULL, "actctx.lpAssemblyDirectory=%p\n", actctx.lpAssemblyDirectory); ok(actctx.lpResourceName == NULL, "actctx.lpResourceName=%p\n", actctx.lpResourceName); - ok(actctx.lpApplicationName == NULL, "actctx.lpApplocationName=%p\n", + ok(actctx.lpApplicationName == NULL, "actctx.lpApplicationName=%p\n", actctx.lpApplicationName); ok(actctx.hModule == NULL, "actctx.hModule=%p\n", actctx.hModule); diff --git a/rostests/winetests/kernel32/atom.c b/rostests/winetests/kernel32/atom.c index 15ef04cb9f5..0c1740869ac 100755 --- a/rostests/winetests/kernel32/atom.c +++ b/rostests/winetests/kernel32/atom.c @@ -168,11 +168,11 @@ static void test_get_atom_name(void) if (unicode_OS) { - static const WCHAR sampleW[10] = {'.','.','.','.','.','.','.','.','.','.'}; + static const WCHAR sampleW[] = {'.','.','.','.','.','.','.','.','.','.'}; for (i = 0; i < 10; i++) bufW[i] = '.'; ok( !GlobalGetAtomNameW( atom, bufW, 0 ), "succeeded\n" ); - ok( !memcmp( bufW, sampleW, 10 * sizeof(WCHAR) ), "should not touch buffer\n" ); + ok( !memcmp( bufW, sampleW, sizeof(sampleW) ), "should not touch buffer\n" ); } /* Test integer atoms */ @@ -266,7 +266,7 @@ static void test_get_atom_name(void) { /* len == 0 with ERROR_MORE_DATA is on NT3.51 */ ok(len == 1 || (len == 0 && GetLastError() == ERROR_MORE_DATA), - "0x%04x: got %u with %d (excepted '1' or '0' with " + "0x%04x: got %u with %d (expected '1' or '0' with " "ERROR_MORE_DATA)\n", i, len, GetLastError()); ok(outW[1] == DOUBLE('.'), "buffer overwrite\n"); } @@ -442,11 +442,11 @@ static void test_local_get_atom_name(void) if (unicode_OS) { - static const WCHAR sampleW[10] = {'.','.','.','.','.','.','.','.','.','.'}; + static const WCHAR sampleW[] = {'.','.','.','.','.','.','.','.','.','.'}; for (i = 0; i < 10; i++) bufW[i] = '.'; ok( !GetAtomNameW( atom, bufW, 0 ), "succeeded\n" ); - ok( !memcmp( bufW, sampleW, 10 * sizeof(WCHAR) ), "should not touch buffer\n" ); + ok( !memcmp( bufW, sampleW, sizeof(sampleW) ), "should not touch buffer\n" ); } /* Test integer atoms */ diff --git a/rostests/winetests/kernel32/change.c b/rostests/winetests/kernel32/change.c index 4d0bc1c43ce..6142e438cb0 100755 --- a/rostests/winetests/kernel32/change.c +++ b/rostests/winetests/kernel32/change.c @@ -858,7 +858,7 @@ static void test_readdirectorychanges_cr(void) ok(fni->FileNameLength == lstrlenW(szFile)*sizeof(WCHAR), "FileNameLength = %d\n", fni->FileNameLength); ok(!memcmp(fni->FileName, szFile, lstrlenW(szFile)*sizeof(WCHAR)), - "FileName = %s\n", wine_dbgstr_w(fni->FileName)); + "FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR))); r = pReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE, FILE_NOTIFY_CHANGE_FILE_NAME, NULL, &ov, readdirectorychanges_cr); @@ -878,7 +878,7 @@ static void test_readdirectorychanges_cr(void) ok(fni->FileNameLength == lstrlenW(szFile)*sizeof(WCHAR), "FileNameLength = %d\n", fni->FileNameLength); ok(!memcmp(fni->FileName, szFile, lstrlenW(szFile)*sizeof(WCHAR)), - "FileName = %s\n", wine_dbgstr_w(fni->FileName)); + "FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR))); r = pReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE, FILE_NOTIFY_CHANGE_FILE_NAME, NULL, &ov, readdirectorychanges_cr); @@ -894,7 +894,7 @@ static void test_readdirectorychanges_cr(void) ok(fni->FileNameLength == lstrlenW(szFile)*sizeof(WCHAR), "FileNameLength = %d\n", fni->FileNameLength); ok(!memcmp(fni->FileName, szFile, lstrlenW(szFile)*sizeof(WCHAR)), - "FileName = %s\n", wine_dbgstr_w(fni->FileName)); + "FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR))); r = pReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE, FILE_NOTIFY_CHANGE_FILE_NAME, NULL, &ov, readdirectorychanges_cr); @@ -910,7 +910,7 @@ static void test_readdirectorychanges_cr(void) ok(fni->FileNameLength == lstrlenW(szFile)*sizeof(WCHAR), "FileNameLength = %d\n", fni->FileNameLength); ok(!memcmp(fni->FileName, szFile, lstrlenW(szFile)*sizeof(WCHAR)), - "FileName = %s\n", wine_dbgstr_w(fni->FileName)); + "FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR))); CloseHandle(hdir); @@ -934,7 +934,7 @@ static void test_readdirectorychanges_cr(void) ok(fni->FileNameLength == lstrlenW(szDir)*sizeof(WCHAR), "FileNameLength = %d\n", fni->FileNameLength); ok(!memcmp(fni->FileName, szDir, lstrlenW(szDir)*sizeof(WCHAR)), - "FileName = %s\n", wine_dbgstr_w(fni->FileName)); + "FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR))); ok(fni->NextEntryOffset != 0, "no next entry in movement event\n"); fni_next = (FILE_NOTIFY_INFORMATION*)((char*)fni+fni->NextEntryOffset); ok(fni_next->NextEntryOffset == 0, "there should be no more events in buffer\n"); @@ -942,7 +942,7 @@ static void test_readdirectorychanges_cr(void) ok(fni_next->FileNameLength == lstrlenW(szFile)*sizeof(WCHAR), "FileNameLength = %d\n", fni_next->FileNameLength); ok(!memcmp(fni_next->FileName, szFile, lstrlenW(szFile)*sizeof(WCHAR)), - "FileName = %s\n", wine_dbgstr_w(fni_next->FileName)); + "FileName = %s\n", wine_dbgstr_wn(fni_next->FileName, fni_next->FileNameLength/sizeof(WCHAR))); } else { @@ -975,7 +975,7 @@ static void test_readdirectorychanges_cr(void) ok(fni->FileNameLength == lstrlenW(szDir)*sizeof(WCHAR), "FileNameLength = %d\n", fni->FileNameLength); ok(!memcmp(fni->FileName, szDir, lstrlenW(szDir)*sizeof(WCHAR)), - "FileName = %s\n", wine_dbgstr_w(fni->FileName)); + "FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR))); if (fni->NextEntryOffset) fni_next = (FILE_NOTIFY_INFORMATION*)((char*)fni+fni->NextEntryOffset); else @@ -993,7 +993,7 @@ static void test_readdirectorychanges_cr(void) ok(fni_next->FileNameLength == lstrlenW(szDir)*sizeof(WCHAR), "FileNameLength = %d\n", fni_next->FileNameLength); ok(!memcmp(fni_next->FileName, szDir, lstrlenW(szDir)*sizeof(WCHAR)), - "FileName = %s\n", wine_dbgstr_w(fni_next->FileName)); + "FileName = %s\n", wine_dbgstr_wn(fni_next->FileName, fni_next->FileNameLength/sizeof(WCHAR))); CloseHandle(hdir); RemoveDirectoryW(file); diff --git a/rostests/winetests/kernel32/codepage.c b/rostests/winetests/kernel32/codepage.c index 8f9c4e11956..61bcf547dba 100755 --- a/rostests/winetests/kernel32/codepage.c +++ b/rostests/winetests/kernel32/codepage.c @@ -211,8 +211,8 @@ static void test_string_conversion(LPBOOL bUsedDefaultChar) int ret; WCHAR wc1 = 228; /* Western Windows-1252 character */ WCHAR wc2 = 1088; /* Russian Windows-1251 character not displayable for Windows-1252 */ - WCHAR wcs[5] = {'T', 'h', 1088, 'i', 0}; /* String with ASCII characters and a Russian character */ - WCHAR dbwcs[3] = {28953, 25152, 0}; /* String with Chinese (codepage 950) characters */ + static const WCHAR wcs[] = {'T', 'h', 1088, 'i', 0}; /* String with ASCII characters and a Russian character */ + static const WCHAR dbwcs[] = {28953, 25152, 0}; /* String with Chinese (codepage 950) characters */ SetLastError(0xdeadbeef); ret = WideCharToMultiByte(1252, 0, &wc1, 1, &mbc, 1, NULL, bUsedDefaultChar); diff --git a/rostests/winetests/kernel32/comm.c b/rostests/winetests/kernel32/comm.c index b08174f3520..895a9ab7949 100755 --- a/rostests/winetests/kernel32/comm.c +++ b/rostests/winetests/kernel32/comm.c @@ -1115,9 +1115,8 @@ static void test_WaitRx(HANDLE hcom) ZeroMemory( &overlapped, sizeof(overlapped)); overlapped.hEvent = hComPortEvent; - ok((hComWriteEvent = CreateEvent( NULL, TRUE, FALSE, NULL )) !=0, - "CreateEvent res %d\n", - GetLastError()); + hComWriteEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); + ok(hComWriteEvent != NULL, "CreateEvent res %d\n", GetLastError()); ZeroMemory( &overlapped_w, sizeof(overlapped_w)); overlapped_w.hEvent = hComWriteEvent; diff --git a/rostests/winetests/kernel32/console.c b/rostests/winetests/kernel32/console.c index f24866623cd..d0c58f80edf 100755 --- a/rostests/winetests/kernel32/console.c +++ b/rostests/winetests/kernel32/console.c @@ -780,6 +780,28 @@ static void testScreenBuffer(HANDLE hConOut) "GetLastError: expecting %u got %u\n", ERROR_INVALID_HANDLE, GetLastError()); + /* trying to write non-console handle */ + SetLastError(0xdeadbeef); + ok(!WriteConsoleA(hFileOutRW, test_str1, lstrlenA(test_str1), &len, NULL), + "Shouldn't succeed\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, + "GetLastError: expecting %u got %u\n", + ERROR_INVALID_HANDLE, GetLastError()); + + SetLastError(0xdeadbeef); + ok(!WriteConsoleA(hFileOutRO, test_str1, lstrlenA(test_str1), &len, NULL), + "Shouldn't succeed\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, + "GetLastError: expecting %u got %u\n", + ERROR_INVALID_HANDLE, GetLastError()); + + SetLastError(0xdeadbeef); + ok(!WriteConsoleA(hFileOutWT, test_str1, lstrlenA(test_str1), &len, NULL), + "Shouldn't succeed\n"); + todo_wine ok(GetLastError() == ERROR_INVALID_HANDLE, + "GetLastError: expecting %u got %u\n", + ERROR_INVALID_HANDLE, GetLastError()); + CloseHandle(hFileOutRW); CloseHandle(hFileOutRO); CloseHandle(hFileOutWT); @@ -1116,6 +1138,68 @@ static void test_OpenConsoleW(void) CloseHandle(ret); } +static void test_CreateFileW(void) +{ + static const WCHAR coninW[] = {'C','O','N','I','N','$',0}; + static const WCHAR conoutW[] = {'C','O','N','O','U','T','$',0}; + + static const struct + { + LPCWSTR name; + DWORD access; + BOOL inherit; + DWORD creation; + DWORD gle; + BOOL is_broken; + } cf_table[] = { + {coninW, 0, FALSE, 0, ERROR_INVALID_PARAMETER, TRUE}, + {coninW, 0, FALSE, OPEN_ALWAYS, 0, FALSE}, + {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, 0, ERROR_INVALID_PARAMETER, TRUE}, + {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, CREATE_NEW, 0, FALSE}, + {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, CREATE_ALWAYS, 0, FALSE}, + {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_ALWAYS, 0, FALSE}, + {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, TRUNCATE_EXISTING, 0, FALSE}, + {conoutW, 0, FALSE, 0, ERROR_INVALID_PARAMETER, TRUE}, + {conoutW, 0, FALSE, OPEN_ALWAYS, 0, FALSE}, + {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, 0, ERROR_INVALID_PARAMETER, TRUE}, + {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, CREATE_NEW, 0, FALSE}, + {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, CREATE_ALWAYS, 0, FALSE}, + {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_ALWAYS, 0, FALSE}, + {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, TRUNCATE_EXISTING, 0, FALSE}, + }; + + int index; + HANDLE ret; + SECURITY_ATTRIBUTES sa; + + for (index = 0; index < sizeof(cf_table)/sizeof(cf_table[0]); index++) + { + SetLastError(0xdeadbeef); + + sa.nLength = sizeof(sa); + sa.lpSecurityDescriptor = NULL; + sa.bInheritHandle = cf_table[index].inherit; + + ret = CreateFileW(cf_table[index].name, cf_table[index].access, + FILE_SHARE_READ|FILE_SHARE_WRITE, &sa, + cf_table[index].creation, FILE_ATTRIBUTE_NORMAL, NULL); + if (ret == INVALID_HANDLE_VALUE) + { + ok(cf_table[index].gle, + "Expected CreateFileW not to return INVALID_HANDLE_VALUE for index %d\n", index); + ok(GetLastError() == cf_table[index].gle, + "Expected GetLastError() to return %u for index %d, got %u\n", + cf_table[index].gle, index, GetLastError()); + } + else + { + ok(!cf_table[index].gle || broken(cf_table[index].is_broken) /* Win7 */, + "Expected CreateFileW to succeed for index %d\n", index); + CloseHandle(ret); + } + } +} + static void test_VerifyConsoleIoHandle( HANDLE handle ) { BOOL ret; @@ -2546,6 +2630,7 @@ START_TEST(console) test_GetConsoleProcessList(); test_OpenConsoleW(); + test_CreateFileW(); test_OpenCON(); test_VerifyConsoleIoHandle(hConOut); test_GetSetStdHandle(); diff --git a/rostests/winetests/kernel32/file.c b/rostests/winetests/kernel32/file.c index bc423d70150..9cfb664f79d 100755 --- a/rostests/winetests/kernel32/file.c +++ b/rostests/winetests/kernel32/file.c @@ -1591,7 +1591,7 @@ static void test_offset_in_overlapped_structure(void) static void test_LockFile(void) { - HANDLE handle; + HANDLE handle, handle2; DWORD written; OVERLAPPED overlapped; int limited_LockFile; @@ -1606,6 +1606,14 @@ static void test_LockFile(void) ok(0,"couldn't create file \"%s\" (err=%d)\n",filename,GetLastError()); return; } + handle2 = CreateFileA( filename, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, 0, 0 ); + if (handle2 == INVALID_HANDLE_VALUE) + { + ok( 0, "couldn't open file \"%s\" (err=%d)\n", filename, GetLastError() ); + goto cleanup; + } ok( WriteFile( handle, sillytext, strlen(sillytext), &written, NULL ), "write failed\n" ); ok( LockFile( handle, 0, 0, 0, 0 ), "LockFile failed\n" ); @@ -1656,6 +1664,22 @@ static void test_LockFile(void) "UnlockFileEx 150,100 again succeeded\n" ); } + /* shared lock can overlap exclusive if handles are equal */ + S(U(overlapped)).Offset = 300; + ok( LockFileEx( handle, LOCKFILE_EXCLUSIVE_LOCK, 0, 100, 0, &overlapped ), + "LockFileEx exclusive 300,100 failed\n" ); + ok( !LockFileEx( handle2, LOCKFILE_FAIL_IMMEDIATELY, 0, 100, 0, &overlapped ), + "LockFileEx handle2 300,100 succeeded\n" ); + ret = LockFileEx( handle, LOCKFILE_FAIL_IMMEDIATELY, 0, 100, 0, &overlapped ); + ok( ret, "LockFileEx 300,100 failed\n" ); + ok( UnlockFileEx( handle, 0, 100, 0, &overlapped ), "UnlockFileEx 300,100 failed\n" ); + /* exclusive lock is removed first */ + ok( LockFileEx( handle2, LOCKFILE_FAIL_IMMEDIATELY, 0, 100, 0, &overlapped ), + "LockFileEx handle2 300,100 failed\n" ); + ok( UnlockFileEx( handle2, 0, 100, 0, &overlapped ), "UnlockFileEx 300,100 failed\n" ); + if (ret) + ok( UnlockFileEx( handle, 0, 100, 0, &overlapped ), "UnlockFileEx 300,100 failed\n" ); + ret = LockFile( handle, 0, 0x10000000, 0, 0xf0000000 ); if (ret) { @@ -1689,6 +1713,8 @@ static void test_LockFile(void) ok( UnlockFile( handle, 100, 0, 0, 0 ), "UnlockFile 100,0 failed\n" ); + CloseHandle( handle2 ); +cleanup: CloseHandle( handle ); DeleteFileA( filename ); } @@ -1732,12 +1758,12 @@ static BOOL create_fake_dll( LPCSTR filename ) #elif defined __sparc__ nt->FileHeader.Machine = IMAGE_FILE_MACHINE_SPARC; #elif defined __arm__ - nt->FileHeader.Machine = IMAGE_FILE_MACHINE_ARM; + nt->FileHeader.Machine = IMAGE_FILE_MACHINE_ARMV7; #else # error You must specify the machine type #endif nt->FileHeader.NumberOfSections = 1; - nt->FileHeader.SizeOfOptionalHeader = IMAGE_SIZEOF_NT_OPTIONAL_HEADER; + nt->FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER); nt->FileHeader.Characteristics = IMAGE_FILE_DLL | IMAGE_FILE_EXECUTABLE_IMAGE; nt->OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR_MAGIC; nt->OptionalHeader.MajorLinkerVersion = 1; @@ -2393,7 +2419,8 @@ static void test_read_write(void) user_apc_ran = FALSE; if (pQueueUserAPC) { trace("Queueing an user APC\n"); /* verify the file is non alerable */ - ok(pQueueUserAPC(&user_apc, GetCurrentThread(), 0), "QueueUserAPC failed: %d\n", GetLastError()); + ret = pQueueUserAPC(&user_apc, GetCurrentThread(), 0); + ok(ret, "QueueUserAPC failed: %d\n", GetLastError()); } SetLastError(12345678); @@ -3124,6 +3151,92 @@ static void test_ReplaceFileW(void) } } +static void test_CreatFile(void) +{ + static const struct test_data + { + DWORD disposition, access, error, clean_up; + } td[] = + { + /* 0 */ { 0, 0, ERROR_INVALID_PARAMETER, 0 }, + /* 1 */ { 0, GENERIC_READ, ERROR_INVALID_PARAMETER, 0 }, + /* 2 */ { 0, GENERIC_READ|GENERIC_WRITE, ERROR_INVALID_PARAMETER, 0 }, + /* 3 */ { CREATE_NEW, 0, ERROR_FILE_EXISTS, 1 }, + /* 4 */ { CREATE_NEW, 0, 0, 1 }, + /* 5 */ { CREATE_NEW, GENERIC_READ, 0, 1 }, + /* 6 */ { CREATE_NEW, GENERIC_WRITE, 0, 1 }, + /* 7 */ { CREATE_NEW, GENERIC_READ|GENERIC_WRITE, 0, 0 }, + /* 8 */ { CREATE_ALWAYS, 0, 0, 0 }, + /* 9 */ { CREATE_ALWAYS, GENERIC_READ, 0, 0 }, + /* 10*/ { CREATE_ALWAYS, GENERIC_WRITE, 0, 0 }, + /* 11*/ { CREATE_ALWAYS, GENERIC_READ|GENERIC_WRITE, 0, 1 }, + /* 12*/ { OPEN_EXISTING, 0, ERROR_FILE_NOT_FOUND, 0 }, + /* 13*/ { CREATE_ALWAYS, 0, 0, 0 }, + /* 14*/ { OPEN_EXISTING, 0, 0, 0 }, + /* 15*/ { OPEN_EXISTING, GENERIC_READ, 0, 0 }, + /* 16*/ { OPEN_EXISTING, GENERIC_WRITE, 0, 0 }, + /* 17*/ { OPEN_EXISTING, GENERIC_READ|GENERIC_WRITE, 0, 1 }, + /* 18*/ { OPEN_ALWAYS, 0, 0, 0 }, + /* 19*/ { OPEN_ALWAYS, GENERIC_READ, 0, 0 }, + /* 20*/ { OPEN_ALWAYS, GENERIC_WRITE, 0, 0 }, + /* 21*/ { OPEN_ALWAYS, GENERIC_READ|GENERIC_WRITE, 0, 0 }, + /* 22*/ { TRUNCATE_EXISTING, 0, ERROR_INVALID_PARAMETER, 0 }, + /* 23*/ { TRUNCATE_EXISTING, GENERIC_READ, ERROR_INVALID_PARAMETER, 0 }, + /* 24*/ { TRUNCATE_EXISTING, GENERIC_WRITE, 0, 0 }, + /* 25*/ { TRUNCATE_EXISTING, GENERIC_READ|GENERIC_WRITE, 0, 0 } + }; + char temp_path[MAX_PATH]; + char file_name[MAX_PATH]; + DWORD i, ret, written; + HANDLE hfile; + + GetTempPath(MAX_PATH, temp_path); + GetTempFileName(temp_path, "tmp", 0, file_name); + + for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) + { + SetLastError(0xdeadbeef); + hfile = CreateFile(file_name, td[i].access, 0, NULL, td[i].disposition, 0, 0); + if (!td[i].error) + { + ok(hfile != INVALID_HANDLE_VALUE, "%d: CreateFile error %d\n", i, GetLastError()); + written = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = WriteFile(hfile, &td[i].error, sizeof(td[i].error), &written, NULL); + if (td[i].access & GENERIC_WRITE) + ok(ret, "%d: WriteFile error %d\n", i, GetLastError()); + else + { + ok(!ret, "%d: WriteFile should fail\n", i); + ok(GetLastError() == ERROR_ACCESS_DENIED, "%d: expected ERROR_ACCESS_DENIED, got %d\n", i, GetLastError()); + } + CloseHandle(hfile); + } + else + { + /* FIXME: remove the condition below once Wine is fixed */ + if (td[i].disposition == TRUNCATE_EXISTING && !(td[i].access & GENERIC_WRITE)) + { + todo_wine + { + ok(hfile == INVALID_HANDLE_VALUE, "%d: CreateFile should fail\n", i); + ok(GetLastError() == td[i].error, "%d: expected %d, got %d\n", i, td[i].error, GetLastError()); + } + CloseHandle(hfile); + } + else + { + ok(hfile == INVALID_HANDLE_VALUE, "%d: CreateFile should fail\n", i); + ok(GetLastError() == td[i].error, "%d: expected %d, got %d\n", i, td[i].error, GetLastError()); + } + } + + if (td[i].clean_up) DeleteFile(file_name); + } + + DeleteFile(file_name); +} + START_TEST(file) { InitFunctionPointers(); @@ -3139,6 +3252,7 @@ START_TEST(file) test_GetTempFileNameA(); test_CopyFileA(); test_CopyFileW(); + test_CreatFile(); test_CreateFileA(); test_CreateFileW(); test_DeleteFileA(); diff --git a/rostests/winetests/kernel32/format_msg.c b/rostests/winetests/kernel32/format_msg.c index 37ea3e9cbf9..1f56440f60e 100755 --- a/rostests/winetests/kernel32/format_msg.c +++ b/rostests/winetests/kernel32/format_msg.c @@ -125,6 +125,7 @@ static void test_message_from_string_wide(void) static const WCHAR s_sp002sp001[] = {' ',' ','0','0','0','2',',',' ',' ','0','0','1',0}; static const WCHAR s_sp002sp003[] = {' ',' ','0','0','0','2',',',' ','0','0','0','0','3',0}; static const WCHAR s_sp001004[] = {' ',' ','0','0','1',',','0','0','0','0','0','4',0}; + static const WCHAR s_null[] = {'(','n','u','l','l',')',0}; static const WCHAR init_buf[] = {'x', 'x', 'x', 'x', 'x', 'x'}; static const WCHAR broken_buf[] = {'t','e','s','t','x','x'}; @@ -381,6 +382,12 @@ static void test_message_from_string_wide(void) ok(!lstrcmpW(s_crlfcrlf, out), "failed out=%s\n", wine_dbgstr_w(out)); ok(r==4,"failed: r=%d\n", r); + /* null string as argument */ + r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1, 0, + 0, out, sizeof(out)/sizeof(WCHAR), NULL); + ok(!lstrcmpW(s_null, out),"failed out=[%s]\n", wine_dbgstr_w(out)); + ok(r==6,"failed: r=%d\n",r); + /* precision and width */ r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_13s, @@ -700,6 +707,12 @@ static void test_message_from_string(void) ok(!strcmp("\r\n\r\n", out),"failed out=[%s]\n",out); ok(r==4,"failed: r=%d\n",r); + /* null string as argument */ + r = doit(FORMAT_MESSAGE_FROM_STRING, "%1", 0, + 0, out, sizeof(out)/sizeof(CHAR), NULL); + ok(!strcmp("(null)", out),"failed out=[%s]\n",out); + ok(r==6,"failed: r=%d\n",r); + /* precision and width */ r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!3s!", diff --git a/rostests/winetests/kernel32/locale.c b/rostests/winetests/kernel32/locale.c index e13247e20cd..1cc66105f77 100755 --- a/rostests/winetests/kernel32/locale.c +++ b/rostests/winetests/kernel32/locale.c @@ -30,6 +30,9 @@ #include #include +#undef WINVER +#define WINVER 0x0600 + #include "wine/test.h" #include "windef.h" #include "winbase.h" @@ -71,20 +74,30 @@ static BOOL (WINAPI *pEnumSystemLanguageGroupsA)(LANGUAGEGROUP_ENUMPROC, DWORD, static BOOL (WINAPI *pEnumLanguageGroupLocalesA)(LANGGROUPLOCALE_ENUMPROC, LGRPID, DWORD, LONG_PTR); static BOOL (WINAPI *pEnumUILanguagesA)(UILANGUAGE_ENUMPROC, DWORD, LONG_PTR); static BOOL (WINAPI *pEnumSystemLocalesEx)(LOCALE_ENUMPROCEX, DWORD, LPARAM, LPVOID); +static LCID (WINAPI *pLocaleNameToLCID)(LPCWSTR, DWORD); +static INT (WINAPI *pLCIDToLocaleName)(LCID, LPWSTR, INT, DWORD); static INT (WINAPI *pFoldStringA)(DWORD, LPCSTR, INT, LPSTR, INT); static INT (WINAPI *pFoldStringW)(DWORD, LPCWSTR, INT, LPWSTR, INT); static BOOL (WINAPI *pIsValidLanguageGroup)(LGRPID, DWORD); +static INT (WINAPI *pIdnToNameprepUnicode)(DWORD, LPCWSTR, INT, LPWSTR, INT); +static INT (WINAPI *pIdnToAscii)(DWORD, LPCWSTR, INT, LPWSTR, INT); +static INT (WINAPI *pIdnToUnicode)(DWORD, LPCWSTR, INT, LPWSTR, INT); static void InitFunctionPointers(void) { hKernel32 = GetModuleHandleA("kernel32"); pEnumSystemLanguageGroupsA = (void*)GetProcAddress(hKernel32, "EnumSystemLanguageGroupsA"); pEnumLanguageGroupLocalesA = (void*)GetProcAddress(hKernel32, "EnumLanguageGroupLocalesA"); + pLocaleNameToLCID = (void*)GetProcAddress(hKernel32, "LocaleNameToLCID"); + pLCIDToLocaleName = (void*)GetProcAddress(hKernel32, "LCIDToLocaleName"); pFoldStringA = (void*)GetProcAddress(hKernel32, "FoldStringA"); pFoldStringW = (void*)GetProcAddress(hKernel32, "FoldStringW"); pIsValidLanguageGroup = (void*)GetProcAddress(hKernel32, "IsValidLanguageGroup"); pEnumUILanguagesA = (void*)GetProcAddress(hKernel32, "EnumUILanguagesA"); pEnumSystemLocalesEx = (void*)GetProcAddress(hKernel32, "EnumSystemLocalesEx"); + pIdnToNameprepUnicode = (void*)GetProcAddress(hKernel32, "IdnToNameprepUnicode"); + pIdnToAscii = (void*)GetProcAddress(hKernel32, "IdnToAscii"); + pIdnToUnicode = (void*)GetProcAddress(hKernel32, "IdnToUnicode"); } #define eq(received, expected, label, type) \ @@ -1135,12 +1148,63 @@ static void test_GetNumberFormatA(void) } } +struct comparestringa_entry { + LCID lcid; + DWORD flags; + const char *first; + int first_len; + const char *second; + int second_len; + int ret; +}; + +static const struct comparestringa_entry comparestringa_data[] = { + { LOCALE_SYSTEM_DEFAULT, 0, "EndDialog", -1, "_Property", -1, CSTR_GREATER_THAN }, + { LOCALE_SYSTEM_DEFAULT, 0, "osp_vba.sreg0070", -1, "_IEWWBrowserComp", -1, CSTR_GREATER_THAN }, + { LOCALE_SYSTEM_DEFAULT, 0, "r", -1, "\\", -1, CSTR_GREATER_THAN }, + { LOCALE_SYSTEM_DEFAULT, 0, "osp_vba.sreg0031", -1, "OriginalDatabase", -1, CSTR_GREATER_THAN }, + { LOCALE_SYSTEM_DEFAULT, 0, "AAA", -1, "aaa", -1, CSTR_GREATER_THAN }, + { LOCALE_SYSTEM_DEFAULT, 0, "AAA", -1, "aab", -1, CSTR_LESS_THAN }, + { LOCALE_SYSTEM_DEFAULT, 0, "AAA", -1, "Aab", -1, CSTR_LESS_THAN }, + { LOCALE_SYSTEM_DEFAULT, 0, ".AAA", -1, "Aab", -1, CSTR_LESS_THAN }, + { LOCALE_SYSTEM_DEFAULT, 0, ".AAA", -1, "A.ab", -1, CSTR_LESS_THAN }, + { LOCALE_SYSTEM_DEFAULT, 0, "aa", -1, "AB", -1, CSTR_LESS_THAN }, + { LOCALE_SYSTEM_DEFAULT, 0, "aa", -1, "Aab", -1, CSTR_LESS_THAN }, + { LOCALE_SYSTEM_DEFAULT, 0, "aB", -1, "Aab", -1, CSTR_GREATER_THAN }, + { LOCALE_SYSTEM_DEFAULT, 0, "Ba", -1, "bab", -1, CSTR_LESS_THAN }, + { LOCALE_SYSTEM_DEFAULT, 0, "{100}{83}{71}{71}{71}", -1, "Global_DataAccess_JRO", -1, CSTR_LESS_THAN }, + { LOCALE_SYSTEM_DEFAULT, 0, "a", -1, "{", -1, CSTR_GREATER_THAN }, + { LOCALE_SYSTEM_DEFAULT, 0, "A", -1, "{", -1, CSTR_GREATER_THAN }, + { LOCALE_SYSTEM_DEFAULT, 0, "3.5", 0, "4.0", -1, CSTR_LESS_THAN }, + { LOCALE_SYSTEM_DEFAULT, 0, "3.5", -1, "4.0", -1, CSTR_LESS_THAN }, + { LOCALE_SYSTEM_DEFAULT, 0, "3.520.4403.2", -1, "4.0.2927.10", -1, CSTR_LESS_THAN }, + /* hyphen and apostrophe are treated differently depending on whether SORT_STRINGSORT specified or not */ + { LOCALE_SYSTEM_DEFAULT, 0, "-o", -1, "/m", -1, CSTR_GREATER_THAN }, + { LOCALE_SYSTEM_DEFAULT, 0, "/m", -1, "-o", -1, CSTR_LESS_THAN }, + { LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "-o", -1, "/m", -1, CSTR_LESS_THAN }, + { LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "/m", -1, "-o", -1, CSTR_GREATER_THAN }, + { LOCALE_SYSTEM_DEFAULT, 0, "'o", -1, "/m", -1, CSTR_GREATER_THAN }, + { LOCALE_SYSTEM_DEFAULT, 0, "/m", -1, "'o", -1, CSTR_LESS_THAN }, + { LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "'o", -1, "/m", -1, CSTR_LESS_THAN }, + { LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "/m", -1, "'o", -1, CSTR_GREATER_THAN }, + { LOCALE_SYSTEM_DEFAULT, 0, "aLuZkUtZ", 8, "aLuZkUtZ", 9, CSTR_EQUAL }, + { LOCALE_SYSTEM_DEFAULT, 0, "aLuZkUtZ", 7, "aLuZkUtZ\0A", 10, CSTR_LESS_THAN } +}; static void test_CompareStringA(void) { - int ret; + int ret, i; LCID lcid = MAKELCID(MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT), SORT_DEFAULT); + for (i = 0; i < sizeof(comparestringa_data)/sizeof(struct comparestringa_entry); i++) + { + const struct comparestringa_entry *entry = &comparestringa_data[i]; + + ret = CompareStringA(entry->lcid, entry->flags, entry->first, entry->first_len, + entry->second, entry->second_len); + ok(ret == entry->ret, "%d: got %d, expected %d\n", i, ret, entry->ret); + } + ret = CompareStringA(lcid, NORM_IGNORECASE, "Salut", -1, "Salute", -1); ok (ret== 1, "(Salut/Salute) Expected 1, got %d\n", ret); @@ -1189,89 +1253,6 @@ static void test_CompareStringA(void) ret = lstrcmpA(NULL, ""); ok (ret == -1 || broken(ret == -2) /* win9x */, "lstrcmpA(NULL, \"\") should return -1, got %d\n", ret); - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT,0,"EndDialog",-1,"_Property",-1); - ok( ret == 3, "EndDialog vs _Property ... expected 3, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT,0,"osp_vba.sreg0070",-1,"_IEWWBrowserComp",-1); - ok( ret == 3, "osp_vba.sreg0070 vs _IEWWBrowserComp ... expected 3, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT,0,"r",-1,"\\",-1); - ok( ret == 3, "r vs \\ ... expected 3, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT,0,"osp_vba.sreg0031", -1, "OriginalDatabase", -1 ); - ok( ret == 3, "osp_vba.sreg0031 vs OriginalDatabase ... expected 3, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "AAA", -1, "aaa", -1 ); - ok( ret == 3, "AAA vs aaa expected 3, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "AAA", -1, "aab", -1 ); - ok( ret == 1, "AAA vs aab expected 1, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "AAA", -1, "Aab", -1 ); - ok( ret == 1, "AAA vs Aab expected 1, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, ".AAA", -1, "Aab", -1 ); - ok( ret == 1, ".AAA vs Aab expected 1, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, ".AAA", -1, "A.ab", -1 ); - ok( ret == 1, ".AAA vs A.ab expected 1, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "aa", -1, "AB", -1 ); - ok( ret == 1, "aa vs AB expected 1, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "aa", -1, "Aab", -1 ); - ok( ret == 1, "aa vs Aab expected 1, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "aB", -1, "Aab", -1 ); - ok( ret == 3, "aB vs Aab expected 3, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "Ba", -1, "bab", -1 ); - ok( ret == 1, "Ba vs bab expected 1, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "{100}{83}{71}{71}{71}", -1, "Global_DataAccess_JRO", -1 ); - ok( ret == 1, "{100}{83}{71}{71}{71} vs Global_DataAccess_JRO expected 1, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "a", -1, "{", -1 ); - ok( ret == 3, "a vs { expected 3, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "A", -1, "{", -1 ); - ok( ret == 3, "A vs { expected 3, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "3.5", 0, "4.0", -1 ); - ok(ret == 1, "3.5/0 vs 4.0/-1 expected 1, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "3.5", -1, "4.0", -1 ); - ok(ret == 1, "3.5 vs 4.0 expected 1, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "3.520.4403.2", -1, "4.0.2927.10", -1 ); - ok(ret == 1, "3.520.4403.2 vs 4.0.2927.10 expected 1, got %d\n", ret); - - /* hyphen and apostrophe are treated differently depending on - * whether SORT_STRINGSORT specified or not - */ - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "-o", -1, "/m", -1 ); - ok(ret == 3, "-o vs /m expected 3, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "/m", -1, "-o", -1 ); - ok(ret == 1, "/m vs -o expected 1, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "-o", -1, "/m", -1 ); - ok(ret == 1, "-o vs /m expected 1, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "/m", -1, "-o", -1 ); - ok(ret == 3, "/m vs -o expected 3, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "'o", -1, "/m", -1 ); - ok(ret == 3, "'o vs /m expected 3, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "/m", -1, "'o", -1 ); - ok(ret == 1, "/m vs 'o expected 1, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "'o", -1, "/m", -1 ); - ok(ret == 1, "'o vs /m expected 1, got %d\n", ret); - - ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "/m", -1, "'o", -1 ); - ok(ret == 3, "/m vs 'o expected 3, got %d\n", ret); if (0) { /* this requires collation table patch to make it MS compatible */ ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "'o", -1, "-o", -1 ); @@ -1311,11 +1292,6 @@ static void test_CompareStringA(void) ok(ret == 1, "-m vs `o expected 1, got %d\n", ret); } - ret = CompareStringA(LOCALE_USER_DEFAULT, 0, "aLuZkUtZ", 8, "aLuZkUtZ", 9); - ok(ret == 2, "aLuZkUtZ vs aLuZkUtZ\\0 expected 2, got %d\n", ret); - - ret = CompareStringA(LOCALE_USER_DEFAULT, 0, "aLuZkUtZ", 7, "aLuZkUtZ\0A", 10); - ok(ret == 1, "aLuZkUtZ vs aLuZkUtZ\\0A expected 1, got %d\n", ret); /* WinXP handles embedded NULLs differently than earlier versions */ ret = CompareStringA(LOCALE_USER_DEFAULT, 0, "aLuZkUtZ", 8, "aLuZkUtZ\0A", 10); @@ -1674,6 +1650,43 @@ static void test_LCMapStringW(void) "unexpected error code %d\n", GetLastError()); } +static void test_LocaleNames(void) +{ + LCID lcid; + INT ret; + WCHAR buffer[LOCALE_NAME_MAX_LENGTH]; + + if (!pLocaleNameToLCID) + { + win_skip( "LocaleNameToLCID not available\n" ); + return; + } + + /* special cases */ + buffer[0] = 0; + lcid = pLocaleNameToLCID(LOCALE_NAME_USER_DEFAULT, 0); + ok(lcid == GetUserDefaultLCID() || broken(GetLastError() == ERROR_INVALID_PARAMETER /* Vista */), + "Expected lcid == %08x, got %08x, error %d\n", lcid, GetUserDefaultLCID(), GetLastError()); + ret = pLCIDToLocaleName(lcid, buffer, LOCALE_NAME_MAX_LENGTH, 0); + ok(ret > 0, "Expected ret > 0, got %d, error %d\n", ret, GetLastError()); + trace("%08x, %s\n", lcid, wine_dbgstr_w(buffer)); + + buffer[0] = 0; + lcid = pLocaleNameToLCID(LOCALE_NAME_SYSTEM_DEFAULT, 0); + todo_wine ok(!lcid && GetLastError() == ERROR_INVALID_PARAMETER, + "Expected lcid != 0, got %08x, error %d\n", lcid, GetLastError()); + ret = pLCIDToLocaleName(lcid, buffer, LOCALE_NAME_MAX_LENGTH, 0); + ok(ret > 0, "Expected ret > 0, got %d, error %d\n", ret, GetLastError()); + trace("%08x, %s\n", lcid, wine_dbgstr_w(buffer)); + + buffer[0] = 0; + lcid = pLocaleNameToLCID(LOCALE_NAME_INVARIANT, 0); + todo_wine ok(lcid == 0x7F, "Expected lcid = 0x7F, got %08x, error %d\n", lcid, GetLastError()); + ret = pLCIDToLocaleName(lcid, buffer, LOCALE_NAME_MAX_LENGTH, 0); + ok(ret > 0, "Expected ret > 0, got %d, error %d\n", ret, GetLastError()); + trace("%08x, %s\n", lcid, wine_dbgstr_w(buffer)); +} + /* this requires collation table patch to make it MS compatible */ static const char * const strings_sorted[] = { @@ -2098,6 +2111,18 @@ static void test_FoldStringW(void) { 'W','i','n','e',0x0348,0x0551,0x1323,0x280d,'W','i','n','e','\0' }; + static const WCHAR foldczone_todo_src[] = + { + 0x3c5,0x308,0x6a,0x30c,0xa0,0xaa,0 + }; + static const WCHAR foldczone_todo_dst[] = + { + 0x3cb,0x1f0,' ','a',0 + }; + static const WCHAR foldczone_todo_broken_dst[] = + { + 0x3cb,0x1f0,0xa0,0xaa,0 + }; static const WCHAR ligatures_src[] = { 'W', 'i', 'n', 'e', 0x03a6, 0x03b9, 0x03bd, 0x03b5, @@ -2242,6 +2267,13 @@ static void test_FoldStringW(void) ok(!memcmp(dst, foldczone_dst, sizeof(foldczone_dst)), "MAP_FOLDCZONE: Expanded incorrectly\n"); + ret = pFoldStringW(MAP_FOLDCZONE|MAP_PRECOMPOSED, foldczone_todo_src, -1, dst, 256); + todo_wine ok(ret == sizeof(foldczone_todo_dst)/sizeof(foldczone_todo_dst[0]), + "Got %d, error %d\n", ret, GetLastError()); + todo_wine ok(!memcmp(dst, foldczone_todo_dst, sizeof(foldczone_todo_dst)) + || broken(!memcmp(dst, foldczone_todo_broken_dst, sizeof(foldczone_todo_broken_dst))), + "MAP_FOLDCZONE: Expanded incorrectly (%s)\n", wine_dbgstr_w(dst)); + /* MAP_EXPAND_LIGATURES */ SetLastError(0); ret = pFoldStringW(MAP_EXPAND_LIGATURES, ligatures_src, -1, dst, 256); @@ -2803,6 +2835,311 @@ static void test_GetStringTypeW(void) ok(types[i] & C1_SPACE || broken(types[i] == C1_CNTRL) || broken(types[i] == 0), "incorrect types returned for %x -> (%x does not have %x)\n",space_special[i], types[i], C1_SPACE ); } +static void test_IdnToNameprepUnicode(void) +{ + struct { + DWORD in_len; + const WCHAR in[64]; + DWORD ret; + const WCHAR out[64]; + DWORD flags; + DWORD err; + DWORD todo; + } test_data[] = { + { + 5, {'t','e','s','t',0}, + 5, {'t','e','s','t',0}, + 0, 0xdeadbeef + }, + { + 3, {'a',0xe111,'b'}, + 0, {0}, + 0, ERROR_INVALID_NAME + }, + { + 4, {'t',0,'e',0}, + 0, {0}, + 0, ERROR_INVALID_NAME + }, + { + 1, {'T',0}, + 1, {'T',0}, + 0, 0xdeadbeef + }, + { + 1, {0}, + 0, {0}, + 0, ERROR_INVALID_NAME + }, + { + 6, {' ','-','/','[',']',0}, + 6, {' ','-','/','[',']',0}, + 0, 0xdeadbeef + }, + { + 3, {'a','-','a'}, + 3, {'a','-','a'}, + IDN_USE_STD3_ASCII_RULES, 0xdeadbeef + }, + { + 3, {'a','a','-'}, + 0, {0}, + IDN_USE_STD3_ASCII_RULES, ERROR_INVALID_NAME + }, + { /* FoldString is not working as expected when MAP_FOLDCZONE is specified (composition+compatibility) */ + 10, {'T',0xdf,0x130,0x143,0x37a,0x6a,0x30c,' ',0xaa,0}, + 12, {'t','s','s','i',0x307,0x144,' ',0x3b9,0x1f0,' ','a',0}, + 0, 0xdeadbeef, TRUE + }, + { + 11, {'t',0xad,0x34f,0x1806,0x180b,0x180c,0x180d,0x200b,0x200c,0x200d,0}, + 2, {'t',0}, + 0, 0xdeadbeef + }, + { /* Another example of incorrectly working FoldString (composition) */ + 2, {0x3b0, 0}, + 2, {0x3b0, 0}, + 0, 0xdeadbeef, TRUE + }, + { + 2, {0x221, 0}, + 0, {0}, + 0, ERROR_NO_UNICODE_TRANSLATION + }, + { + 2, {0x221, 0}, + 2, {0x221, 0}, + IDN_ALLOW_UNASSIGNED, 0xdeadbeef + }, + { + 5, {'a','.','.','a',0}, + 0, {0}, + 0, ERROR_INVALID_NAME + }, + { + 3, {'a','.',0}, + 3, {'a','.',0}, + 0, 0xdeadbeef + }, + }; + + WCHAR buf[1024]; + DWORD i, ret, err; + + if (!pIdnToNameprepUnicode) + { + win_skip("IdnToNameprepUnicode is not available\n"); + return; + } + + ret = pIdnToNameprepUnicode(0, test_data[0].in, + test_data[0].in_len, NULL, 0); + ok(ret == test_data[0].ret, "ret = %d\n", ret); + + SetLastError(0xdeadbeef); + ret = pIdnToNameprepUnicode(0, test_data[1].in, + test_data[1].in_len, NULL, 0); + err = GetLastError(); + ok(ret == test_data[1].ret, "ret = %d\n", ret); + ok(err == test_data[1].err, "err = %d\n", err); + + SetLastError(0xdeadbeef); + ret = pIdnToNameprepUnicode(0, test_data[0].in, -1, + buf, sizeof(buf)/sizeof(WCHAR)); + err = GetLastError(); + ok(ret == test_data[0].ret, "ret = %d\n", ret); + ok(err == 0xdeadbeef, "err = %d\n", err); + + SetLastError(0xdeadbeef); + ret = pIdnToNameprepUnicode(0, test_data[0].in, -2, + buf, sizeof(buf)/sizeof(WCHAR)); + err = GetLastError(); + ok(ret == 0, "ret = %d\n", ret); + ok(err == ERROR_INVALID_PARAMETER, "err = %d\n", err); + + SetLastError(0xdeadbeef); + ret = pIdnToNameprepUnicode(0, test_data[0].in, 0, + buf, sizeof(buf)/sizeof(WCHAR)); + err = GetLastError(); + ok(ret == 0, "ret = %d\n", ret); + ok(err == ERROR_INVALID_NAME, "err = %d\n", err); + + ret = pIdnToNameprepUnicode(IDN_ALLOW_UNASSIGNED|IDN_USE_STD3_ASCII_RULES, + test_data[0].in, -1, buf, sizeof(buf)/sizeof(WCHAR)); + ok(ret == test_data[0].ret, "ret = %d\n", ret); + + SetLastError(0xdeadbeef); + ret = pIdnToNameprepUnicode(0, NULL, 0, NULL, 0); + err = GetLastError(); + ok(ret == 0, "ret = %d\n", ret); + ok(err == ERROR_INVALID_PARAMETER, "err = %d\n", err); + + SetLastError(0xdeadbeef); + ret = pIdnToNameprepUnicode(4, NULL, 0, NULL, 0); + err = GetLastError(); + ok(ret == 0, "ret = %d\n", ret); + ok(err == ERROR_INVALID_FLAGS, "err = %d\n", err); + + for (i=0; i +static DWORD (WINAPI *pGetDllDirectoryA)(DWORD,LPSTR); +static DWORD (WINAPI *pGetDllDirectoryW)(DWORD,LPWSTR); +static BOOL (WINAPI *pSetDllDirectoryA)(LPCSTR); +static BOOL (WINAPI *pGetModuleHandleExA)(DWORD,LPCSTR,HMODULE*); +static BOOL (WINAPI *pGetModuleHandleExW)(DWORD,LPCWSTR,HMODULE*); + static BOOL is_unicode_enabled = TRUE; static BOOL cmpStrAW(const char* a, const WCHAR* b, DWORD lenA, DWORD lenB) @@ -44,13 +50,21 @@ static void testGetModuleFileName(const char* name) /* first test, with enough space in buffer */ memset(bufA, '-', sizeof(bufA)); + SetLastError(0xdeadbeef); len1A = GetModuleFileNameA(hMod, bufA, sizeof(bufA)); + ok(GetLastError() == ERROR_SUCCESS || + broken(GetLastError() == 0xdeadbeef), /* <= XP SP3 */ + "LastError was not reset: %u\n", GetLastError()); ok(len1A > 0, "Getting module filename for handle %p\n", hMod); if (is_unicode_enabled) { memset(bufW, '-', sizeof(bufW)); + SetLastError(0xdeadbeef); len1W = GetModuleFileNameW(hMod, bufW, sizeof(bufW) / sizeof(WCHAR)); + ok(GetLastError() == ERROR_SUCCESS || + broken(GetLastError() == 0xdeadbeef), /* <= XP SP3 */ + "LastError was not reset: %u\n", GetLastError()); ok(len1W > 0, "Getting module filename for handle %p\n", hMod); } @@ -378,6 +392,294 @@ static void testLoadLibraryEx(void) } +static void testGetDllDirectory(void) +{ + CHAR bufferA[MAX_PATH]; + WCHAR bufferW[MAX_PATH]; + DWORD length, ret; + int i; + static const char *dll_directories[] = + { + "", + "C:\\Some\\Path", + "C:\\Some\\Path\\", + "Q:\\A\\Long\\Path with spaces that\\probably\\doesn't exist!", + }; + const int test_count = sizeof(dll_directories) / sizeof(dll_directories[0]); + + if (!pGetDllDirectoryA || !pGetDllDirectoryW) + { + win_skip("GetDllDirectory not available\n"); + return; + } + if (!pSetDllDirectoryA) + { + win_skip("SetDllDirectoryA not available\n"); + return; + } + + for (i = 0; i < test_count; i++) + { + length = strlen(dll_directories[i]); + if (!pSetDllDirectoryA(dll_directories[i])) + { + skip("i=%d, SetDllDirectoryA failed\n", i); + continue; + } + + /* no buffer, determine length */ + ret = pGetDllDirectoryA(0, NULL); + ok(ret == length + 1, "Expected %u, got %u\n", length + 1, ret); + + ret = pGetDllDirectoryW(0, NULL); + ok(ret == length + 1, "Expected %u, got %u\n", length + 1, ret); + + /* buffer of exactly the right size */ + bufferA[length] = 'A'; + bufferA[length + 1] = 'A'; + ret = pGetDllDirectoryA(length + 1, bufferA); + ok(ret == length, "i=%d, Expected %u, got %u\n", i, length, ret); + ok(bufferA[length + 1] == 'A', "i=%d, Buffer overflow\n", i); + ok(strcmp(bufferA, dll_directories[i]) == 0, "i=%d, Wrong path returned: '%s'\n", i, bufferA); + + bufferW[length] = 'A'; + bufferW[length + 1] = 'A'; + ret = pGetDllDirectoryW(length + 1, bufferW); + ok(ret == length, "i=%d, Expected %u, got %u\n", i, length, ret); + ok(bufferW[length + 1] == 'A', "i=%d, Buffer overflow\n", i); + ok(cmpStrAW(dll_directories[i], bufferW, length, length), + "i=%d, Wrong path returned: %s\n", i, wine_dbgstr_w(bufferW)); + + /* zero size buffer + * the A version always null-terminates the buffer, + * the W version doesn't do it on some platforms */ + bufferA[0] = 'A'; + ret = pGetDllDirectoryA(0, bufferA); + ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret); + ok(bufferA[0] == 0, "i=%d, Buffer not null terminated\n", i); + + bufferW[0] = 'A'; + ret = pGetDllDirectoryW(0, bufferW); + ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret); + ok(bufferW[0] == 0 || /* XP, 2003 */ + broken(bufferW[0] == 'A'), "i=%d, Buffer overflow\n", i); + + /* buffer just one too short */ + bufferA[0] = 'A'; + ret = pGetDllDirectoryA(length, bufferA); + ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret); + ok(bufferA[0] == 0, "i=%d, Buffer not null terminated\n", i); + + bufferW[0] = 'A'; + ret = pGetDllDirectoryW(length, bufferW); + ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret); + ok(bufferW[0] == 0 || /* XP, 2003 */ + broken(bufferW[0] == 'A'), "i=%d, Buffer overflow\n", i); + + /* no buffer, but too short length */ + ret = pGetDllDirectoryA(length, NULL); + ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret); + + ret = pGetDllDirectoryW(length, NULL); + ok(ret == length + 1, "i=%d, Expected %u, got %u\n", i, length + 1, ret); + } + + /* unset whatever we did so following tests won't be affected */ + pSetDllDirectoryA(NULL); +} + +static void init_pointers(void) +{ + HMODULE hKernel32 = GetModuleHandleA("kernel32.dll"); + +#define MAKEFUNC(f) (p##f = (void*)GetProcAddress(hKernel32, #f)) + MAKEFUNC(GetDllDirectoryA); + MAKEFUNC(GetDllDirectoryW); + MAKEFUNC(SetDllDirectoryA); + MAKEFUNC(GetModuleHandleExA); + MAKEFUNC(GetModuleHandleExW); +#undef MAKEFUNC +} + +static void testGetModuleHandleEx(void) +{ + static const WCHAR kernel32W[] = {'k','e','r','n','e','l','3','2',0}; + static const WCHAR nosuchmodW[] = {'n','o','s','u','c','h','m','o','d',0}; + BOOL ret; + DWORD error; + HMODULE mod, mod_kernel32; + + if (!pGetModuleHandleExA || !pGetModuleHandleExW) + { + win_skip( "GetModuleHandleEx not available\n" ); + return; + } + + SetLastError( 0xdeadbeef ); + ret = pGetModuleHandleExA( 0, NULL, NULL ); + error = GetLastError(); + ok( !ret, "unexpected success\n" ); + ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + + SetLastError( 0xdeadbeef ); + ret = pGetModuleHandleExA( 0, "kernel32", NULL ); + error = GetLastError(); + ok( !ret, "unexpected success\n" ); + ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + + SetLastError( 0xdeadbeef ); + mod = (HMODULE)0xdeadbeef; + ret = pGetModuleHandleExA( 0, "kernel32", &mod ); + ok( ret, "unexpected failure %u\n", GetLastError() ); + ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod ); + FreeLibrary( mod ); + + SetLastError( 0xdeadbeef ); + mod = (HMODULE)0xdeadbeef; + ret = pGetModuleHandleExA( 0, "nosuchmod", &mod ); + error = GetLastError(); + ok( !ret, "unexpected success\n" ); + ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error ); + ok( mod == NULL, "got %p\n", mod ); + + SetLastError( 0xdeadbeef ); + ret = pGetModuleHandleExW( 0, NULL, NULL ); + error = GetLastError(); + ok( !ret, "unexpected success\n" ); + ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + + SetLastError( 0xdeadbeef ); + ret = pGetModuleHandleExW( 0, kernel32W, NULL ); + error = GetLastError(); + ok( !ret, "unexpected success\n" ); + ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + + SetLastError( 0xdeadbeef ); + mod = (HMODULE)0xdeadbeef; + ret = pGetModuleHandleExW( 0, kernel32W, &mod ); + ok( ret, "unexpected failure %u\n", GetLastError() ); + ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod ); + FreeLibrary( mod ); + + SetLastError( 0xdeadbeef ); + mod = (HMODULE)0xdeadbeef; + ret = pGetModuleHandleExW( 0, nosuchmodW, &mod ); + error = GetLastError(); + ok( !ret, "unexpected success\n" ); + ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error ); + ok( mod == NULL, "got %p\n", mod ); + + SetLastError( 0xdeadbeef ); + ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, NULL ); + error = GetLastError(); + ok( !ret, "unexpected success\n" ); + ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + + SetLastError( 0xdeadbeef ); + ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "kernel32", NULL ); + error = GetLastError(); + ok( !ret, "unexpected success\n" ); + ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + + SetLastError( 0xdeadbeef ); + mod = (HMODULE)0xdeadbeef; + ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "kernel32", &mod ); + ok( ret, "unexpected failure %u\n", GetLastError() ); + ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod ); + + SetLastError( 0xdeadbeef ); + mod = (HMODULE)0xdeadbeef; + ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, "nosuchmod", &mod ); + error = GetLastError(); + ok( !ret, "unexpected success\n" ); + ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error ); + ok( mod == NULL, "got %p\n", mod ); + + SetLastError( 0xdeadbeef ); + ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, NULL, NULL ); + error = GetLastError(); + ok( !ret, "unexpected success\n" ); + ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + + SetLastError( 0xdeadbeef ); + ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, kernel32W, NULL ); + error = GetLastError(); + ok( !ret, "unexpected success\n" ); + ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + + SetLastError( 0xdeadbeef ); + mod = (HMODULE)0xdeadbeef; + ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, kernel32W, &mod ); + ok( ret, "unexpected failure %u\n", GetLastError() ); + ok( mod != (HMODULE)0xdeadbeef, "got %p\n", mod ); + + SetLastError( 0xdeadbeef ); + mod = (HMODULE)0xdeadbeef; + ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, nosuchmodW, &mod ); + error = GetLastError(); + ok( !ret, "unexpected success\n" ); + ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error ); + ok( mod == NULL, "got %p\n", mod ); + + mod_kernel32 = LoadLibraryA( "kernel32" ); + + SetLastError( 0xdeadbeef ); + ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, NULL, NULL ); + error = GetLastError(); + ok( !ret, "unexpected success\n" ); + ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + + SetLastError( 0xdeadbeef ); + ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)mod_kernel32, NULL ); + error = GetLastError(); + ok( !ret, "unexpected success\n" ); + ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + + SetLastError( 0xdeadbeef ); + mod = (HMODULE)0xdeadbeef; + ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)mod_kernel32, &mod ); + ok( ret, "unexpected failure %u\n", GetLastError() ); + ok( mod == mod_kernel32, "got %p\n", mod ); + FreeLibrary( mod ); + + SetLastError( 0xdeadbeef ); + mod = (HMODULE)0xdeadbeef; + ret = pGetModuleHandleExA( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)0xbeefdead, &mod ); + error = GetLastError(); + ok( !ret, "unexpected success\n" ); + ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error ); + ok( mod == NULL, "got %p\n", mod ); + + SetLastError( 0xdeadbeef ); + ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, NULL, NULL ); + error = GetLastError(); + ok( !ret, "unexpected success\n" ); + ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + + SetLastError( 0xdeadbeef ); + ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)mod_kernel32, NULL ); + error = GetLastError(); + ok( !ret, "unexpected success\n" ); + ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); + + SetLastError( 0xdeadbeef ); + mod = (HMODULE)0xdeadbeef; + ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)mod_kernel32, &mod ); + ok( ret, "unexpected failure %u\n", GetLastError() ); + ok( mod == mod_kernel32, "got %p\n", mod ); + FreeLibrary( mod ); + + SetLastError( 0xdeadbeef ); + mod = (HMODULE)0xdeadbeef; + ret = pGetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCWSTR)0xbeefdead, &mod ); + error = GetLastError(); + ok( !ret, "unexpected success\n" ); + ok( error == ERROR_MOD_NOT_FOUND, "got %u\n", error ); + ok( mod == NULL, "got %p\n", mod ); + + FreeLibrary( mod_kernel32 ); +} + START_TEST(module) { WCHAR filenameW[MAX_PATH]; @@ -392,13 +694,18 @@ START_TEST(module) is_unicode_enabled = FALSE; } + init_pointers(); + testGetModuleFileName(NULL); testGetModuleFileName("kernel32.dll"); testGetModuleFileName_Wrong(); + testGetDllDirectory(); + testLoadLibraryA(); testNestedLoadLibraryA(); testLoadLibraryA_Wrong(); testGetProcAddress_Wrong(); testLoadLibraryEx(); + testGetModuleHandleEx(); } diff --git a/rostests/winetests/kernel32/pipe.c b/rostests/winetests/kernel32/pipe.c index ed787949289..3484c62c791 100755 --- a/rostests/winetests/kernel32/pipe.c +++ b/rostests/winetests/kernel32/pipe.c @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include #include #include @@ -72,6 +71,19 @@ static void test_CreateNamedPipe(int pipemode) ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_NAME, "CreateNamedPipe should fail if name doesn't start with \\\\.\\pipe\n"); + if (pipemode == PIPE_TYPE_BYTE) + { + /* Bad parameter checks */ + hnp = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_MESSAGE, + /* nMaxInstances */ 1, + /* nOutBufSize */ 1024, + /* nInBufSize */ 1024, + /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, + /* lpSecurityAttrib */ NULL); + ok(hnp == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_PARAMETER, + "CreateNamedPipe should fail with PIPE_TYPE_BYTE | PIPE_READMODE_MESSAGE\n"); + } + hnp = CreateNamedPipe(NULL, PIPE_ACCESS_DUPLEX, pipemode | PIPE_WAIT, 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL); @@ -375,7 +387,7 @@ static void test_CreateNamedPipe_instances_must_match(void) ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); hnp2 = CreateNamedPipe(PIPENAME, PIPE_ACCESS_INBOUND, PIPE_TYPE_BYTE | PIPE_WAIT, - /* nMaxInstances */ 1, + /* nMaxInstances */ 2, /* nOutBufSize */ 1024, /* nInBufSize */ 1024, /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, @@ -385,7 +397,25 @@ static void test_CreateNamedPipe_instances_must_match(void) ok(CloseHandle(hnp), "CloseHandle\n"); - /* etc, etc */ + /* check everything else */ + hnp = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, + /* nMaxInstances */ 4, + /* nOutBufSize */ 1024, + /* nInBufSize */ 1024, + /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT, + /* lpSecurityAttrib */ NULL); + ok(hnp != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); + + hnp2 = CreateNamedPipe(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE, + /* nMaxInstances */ 3, + /* nOutBufSize */ 102, + /* nInBufSize */ 24, + /* nDefaultWait */ 1234, + /* lpSecurityAttrib */ NULL); + ok(hnp2 != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n"); + + ok(CloseHandle(hnp), "CloseHandle\n"); + ok(CloseHandle(hnp2), "CloseHandle\n"); } /** implementation of alarm() */ @@ -480,7 +510,8 @@ static DWORD CALLBACK serverThreadMain2(LPVOID arg) user_apc_ran = FALSE; if (i == 0 && pQueueUserAPC) { trace("Queueing an user APC\n"); /* verify the pipe is non alerable */ - ok(pQueueUserAPC(&user_apc, GetCurrentThread(), 0), "QueueUserAPC failed: %d\n", GetLastError()); + success = pQueueUserAPC(&user_apc, GetCurrentThread(), 0); + ok(success, "QueueUserAPC failed: %d\n", GetLastError()); } /* Wait for client to connect */ diff --git a/rostests/winetests/kernel32/process.c b/rostests/winetests/kernel32/process.c index b3b8d180cc2..8aadf2a6e5f 100755 --- a/rostests/winetests/kernel32/process.c +++ b/rostests/winetests/kernel32/process.c @@ -62,6 +62,7 @@ static LPVOID (WINAPI *pVirtualAllocEx)(HANDLE, LPVOID, SIZE_T, DWORD, DWORD); static BOOL (WINAPI *pVirtualFreeEx)(HANDLE, LPVOID, SIZE_T, DWORD); static BOOL (WINAPI *pQueryFullProcessImageNameA)(HANDLE hProcess, DWORD dwFlags, LPSTR lpExeName, PDWORD lpdwSize); static BOOL (WINAPI *pQueryFullProcessImageNameW)(HANDLE hProcess, DWORD dwFlags, LPWSTR lpExeName, PDWORD lpdwSize); +static DWORD (WINAPI *pK32GetProcessImageFileNameA)(HANDLE,LPSTR,DWORD); /* ############################### */ static char base[MAX_PATH]; @@ -204,6 +205,7 @@ static int init(void) pVirtualFreeEx = (void *) GetProcAddress(hkernel32, "VirtualFreeEx"); pQueryFullProcessImageNameA = (void *) GetProcAddress(hkernel32, "QueryFullProcessImageNameA"); pQueryFullProcessImageNameW = (void *) GetProcAddress(hkernel32, "QueryFullProcessImageNameW"); + pK32GetProcessImageFileNameA = (void *) GetProcAddress(hkernel32, "K32GetProcessImageFileNameA"); return 1; } @@ -1638,21 +1640,70 @@ static void test_GetProcessVersion(void) CloseHandle(pi.hThread); } -static void test_ProcessNameA(void) +static void test_GetProcessImageFileNameA(void) +{ + DWORD rc; + CHAR process[MAX_PATH]; + static const char harddisk[] = "\\Device\\HarddiskVolume"; + + if (!pK32GetProcessImageFileNameA) + { + win_skip("K32GetProcessImageFileNameA is unavailable\n"); + return; + } + + /* callers must guess the buffer size */ + SetLastError(0xdeadbeef); + rc = pK32GetProcessImageFileNameA(GetCurrentProcess(), NULL, 0); + ok(!rc && GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "K32GetProcessImageFileNameA(no buffer): returned %u, le=%u\n", rc, GetLastError()); + + *process = '\0'; + rc = pK32GetProcessImageFileNameA(GetCurrentProcess(), process, sizeof(process)); + expect_eq_d(rc, lstrlenA(process)); + if (strncmp(process, harddisk, lstrlenA(harddisk))) + { + todo_wine win_skip("%s is probably on a network share, skipping tests\n", process); + return; + } + + if (!pQueryFullProcessImageNameA) + win_skip("QueryFullProcessImageNameA unavailable (added in Windows Vista)\n"); + else + { + CHAR image[MAX_PATH]; + DWORD length; + + length = sizeof(image); + expect_eq_d(TRUE, pQueryFullProcessImageNameA(GetCurrentProcess(), PROCESS_NAME_NATIVE, image, &length)); + expect_eq_d(length, lstrlenA(image)); + ok(lstrcmpi(process, image) == 0, "expected '%s' to be equal to '%s'\n", process, image); + } +} + +static void test_QueryFullProcessImageNameA(void) { #define INIT_STR "Just some words" DWORD length, size; - CHAR buf[1024]; + CHAR buf[MAX_PATH], module[MAX_PATH]; if (!pQueryFullProcessImageNameA) { win_skip("QueryFullProcessImageNameA unavailable (added in Windows Vista)\n"); return; } + + *module = '\0'; + SetLastError(0); /* old Windows don't reset it on success */ + size = GetModuleFileNameA(NULL, module, sizeof(module)); + ok(size && GetLastError() != ERROR_INSUFFICIENT_BUFFER, "GetModuleFileName failed: %u le=%u\n", size, GetLastError()); + /* get the buffer length without \0 terminator */ - length = 1024; + length = sizeof(buf); expect_eq_d(TRUE, pQueryFullProcessImageNameA(GetCurrentProcess(), 0, buf, &length)); expect_eq_d(length, lstrlenA(buf)); + ok((buf[0] == '\\' && buf[1] == '\\') || + lstrcmpi(buf, module) == 0, "expected %s to match %s\n", buf, module); /* when the buffer is too small * - function fail with error ERROR_INSUFFICIENT_BUFFER @@ -1676,8 +1727,8 @@ static void test_ProcessNameA(void) expect_eq_s(INIT_STR, buf); /* this is a difference between the ascii and the unicode version - * the unicode version crashes when the size is big enough to hold the result - * ascii version through an error + * the unicode version crashes when the size is big enough to hold + * the result while the ascii version throws an error */ size = 1024; expect_eq_d(FALSE, pQueryFullProcessImageNameA(GetCurrentProcess(), 0, NULL, &size)); @@ -1685,13 +1736,13 @@ static void test_ProcessNameA(void) expect_eq_d(ERROR_INVALID_PARAMETER, GetLastError()); } -static void test_ProcessName(void) +static void test_QueryFullProcessImageNameW(void) { HANDLE hSelf; - WCHAR module_name[1024]; + WCHAR module_name[1024], device[1024]; WCHAR deviceW[] = {'\\','D', 'e','v','i','c','e',0}; WCHAR buf[1024]; - DWORD size; + DWORD size, len; if (!pQueryFullProcessImageNameW) { @@ -1736,13 +1787,6 @@ static void test_ProcessName(void) expect_eq_d(0, size); expect_eq_d(ERROR_INSUFFICIENT_BUFFER, GetLastError()); - /* native path */ - size = sizeof(buf) / sizeof(buf[0]); - expect_eq_d(TRUE, pQueryFullProcessImageNameW(hSelf, PROCESS_NAME_NATIVE, buf, &size)); - expect_eq_d(lstrlenW(buf), size); - ok(buf[0] == '\\', "NT path should begin with '\\'\n"); - todo_wine ok(memcmp(buf, deviceW, sizeof(WCHAR)*lstrlenW(deviceW)) == 0, "NT path should begin with \\Device\n"); - /* Buffer too small */ size = lstrlenW(module_name)/2; SetLastError(0xdeadbeef); @@ -1752,6 +1796,33 @@ static void test_ProcessName(void) expect_eq_d(ERROR_INSUFFICIENT_BUFFER, GetLastError()); expect_eq_ws_i(module_name, buf); /* buffer not changed */ + + /* native path */ + size = sizeof(buf) / sizeof(buf[0]); + expect_eq_d(TRUE, pQueryFullProcessImageNameW(hSelf, PROCESS_NAME_NATIVE, buf, &size)); + expect_eq_d(lstrlenW(buf), size); + ok(buf[0] == '\\', "NT path should begin with '\\'\n"); + ok(memcmp(buf, deviceW, sizeof(WCHAR)*lstrlenW(deviceW)) == 0, "NT path should begin with \\Device\n"); + + module_name[2] = '\0'; + *device = '\0'; + size = QueryDosDeviceW(module_name, device, sizeof(device)/sizeof(device[0])); + ok(size, "QueryDosDeviceW failed: le=%u\n", GetLastError()); + len = lstrlenW(device); + ok(size >= len+2, "expected %d to be greater than %d+2 = strlen(%s)\n", size, len, wine_dbgstr_w(device)); + + if (size >= lstrlenW(buf)) + { + ok(0, "expected %s\\ to match the start of %s\n", wine_dbgstr_w(device), wine_dbgstr_w(buf)); + } + else + { + ok(buf[len] == '\\', "expected '%c' to be a '\\' in %s\n", buf[len], wine_dbgstr_w(module_name)); + buf[len] = '\0'; + ok(lstrcmpiW(device, buf) == 0, "expected %s to match %s\n", wine_dbgstr_w(device), wine_dbgstr_w(buf)); + ok(lstrcmpiW(module_name+3, buf+len+1) == 0, "expected '%s' to match '%s'\n", wine_dbgstr_w(module_name+3), wine_dbgstr_w(buf+len+1)); + } + CloseHandle(hSelf); } @@ -1888,8 +1959,9 @@ START_TEST(process) test_ExitCode(); test_OpenProcess(); test_GetProcessVersion(); - test_ProcessNameA(); - test_ProcessName(); + test_GetProcessImageFileNameA(); + test_QueryFullProcessImageNameA(); + test_QueryFullProcessImageNameW(); test_Handles(); test_SystemInfo(); test_RegistryQuota(); diff --git a/rostests/winetests/kernel32/profile.c b/rostests/winetests/kernel32/profile.c index 07b351cf7d8..211d0c6075d 100755 --- a/rostests/winetests/kernel32/profile.c +++ b/rostests/winetests/kernel32/profile.c @@ -448,8 +448,8 @@ static void test_profile_delete_on_close(void) h = CreateFile(testfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL); - ok( WriteFile( h, contents, sizeof contents - 1, &size, NULL ), - "Cannot write test file: %x\n", GetLastError() ); + res = WriteFile( h, contents, sizeof contents - 1, &size, NULL ); + ok( res, "Cannot write test file: %x\n", GetLastError() ); ok( size == sizeof contents - 1, "Test file: partial write\n"); SetLastError(0xdeadbeef); @@ -472,8 +472,8 @@ static void test_profile_refresh(void) h = CreateFile(testfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL); - ok( WriteFile( h, contents1, sizeof contents1 - 1, &size, NULL ), - "Cannot write test file: %x\n", GetLastError() ); + res = WriteFile( h, contents1, sizeof contents1 - 1, &size, NULL ); + ok( res, "Cannot write test file: %x\n", GetLastError() ); ok( size == sizeof contents1 - 1, "Test file: partial write\n"); SetLastError(0xdeadbeef); @@ -488,8 +488,8 @@ static void test_profile_refresh(void) h = CreateFile(testfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL); - ok( WriteFile( h, contents2, sizeof contents2 - 1, &size, NULL ), - "Cannot write test file: %x\n", GetLastError() ); + res = WriteFile( h, contents2, sizeof contents2 - 1, &size, NULL ); + ok( res, "Cannot write test file: %x\n", GetLastError() ); ok( size == sizeof contents2 - 1, "Test file: partial write\n"); SetLastError(0xdeadbeef); @@ -500,6 +500,13 @@ static void test_profile_refresh(void) /* This also deletes the file */ CloseHandle(h); + + /* Cache must be invalidated if file no longer exists and default must be returned */ + SetLastError(0xdeadbeef); + res = GetPrivateProfileInt(SECTION, KEY, 421, testfile); + ok( res == 421 || + broken(res == 0 && GetLastError() == 0xdeadbeef), /* Win9x, WinME */ + "Got %d instead of 421\n", res); } static void create_test_file(LPCSTR name, LPCSTR data, DWORD size) diff --git a/rostests/winetests/kernel32/sync.c b/rostests/winetests/kernel32/sync.c index 98d996fabe7..e875c795059 100755 --- a/rostests/winetests/kernel32/sync.c +++ b/rostests/winetests/kernel32/sync.c @@ -18,7 +18,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#define _WIN32_WINNT 0x500 +#define _WIN32_WINNT 0x502 #include #include #include @@ -35,6 +35,8 @@ static HANDLE (WINAPI *pCreateWaitableTimerA)(SECURITY_ATTRIBUTES*,BOOL,LPCSTR); static BOOL (WINAPI *pDeleteTimerQueueEx)(HANDLE, HANDLE); static BOOL (WINAPI *pDeleteTimerQueueTimer)(HANDLE, HANDLE, HANDLE); static HANDLE (WINAPI *pOpenWaitableTimerA)(DWORD,BOOL,LPCSTR); +static HANDLE (WINAPI *pCreateMemoryResourceNotification)(MEMORY_RESOURCE_NOTIFICATION_TYPE); +static BOOL (WINAPI *pQueryMemoryResourceNotification)(HANDLE, PBOOL); static void test_signalandwait(void) { @@ -131,12 +133,23 @@ static void test_mutex(void) int i; DWORD failed = 0; + SetLastError(0xdeadbeef); + hOpened = OpenMutex(0, FALSE, "WineTestMutex"); + ok(hOpened == NULL, "OpenMutex succeeded\n"); + ok(GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError()); + + SetLastError(0xdeadbeef); hCreated = CreateMutex(NULL, FALSE, "WineTestMutex"); ok(hCreated != NULL, "CreateMutex failed with error %d\n", GetLastError()); + SetLastError(0xdeadbeef); hOpened = OpenMutex(0, FALSE, "WineTestMutex"); - ok(hOpened == NULL, "OpenMutex succeded\n"); +todo_wine + ok(hOpened == NULL, "OpenMutex succeeded\n"); +todo_wine + ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError()); + SetLastError(0xdeadbeef); hOpened = OpenMutex(GENERIC_EXECUTE, FALSE, "WineTestMutex"); ok(hOpened != NULL, "OpenMutex failed with error %d\n", GetLastError()); wait_ret = WaitForSingleObject(hOpened, INFINITE); @@ -149,6 +162,7 @@ static void test_mutex(void) ok(wait_ret == WAIT_OBJECT_0, "WaitForSingleObject failed with error 0x%08x\n", wait_ret); } + SetLastError(0xdeadbeef); hOpened = OpenMutex(GENERIC_READ | GENERIC_WRITE, FALSE, "WineTestMutex"); ok(hOpened != NULL, "OpenMutex failed with error %d\n", GetLastError()); wait_ret = WaitForSingleObject(hOpened, INFINITE); @@ -157,22 +171,30 @@ static void test_mutex(void) for (i = 0; i < 32; i++) { + SetLastError(0xdeadbeef); hOpened = OpenMutex(0x1 << i, FALSE, "WineTestMutex"); if(hOpened != NULL) { + SetLastError(0xdeadbeef); ret = ReleaseMutex(hOpened); ok(ret, "ReleaseMutex failed with error %d, access %x\n", GetLastError(), 1 << i); CloseHandle(hOpened); } else { + if ((1 << i) == ACCESS_SYSTEM_SECURITY) + todo_wine ok(GetLastError() == ERROR_PRIVILEGE_NOT_HELD, "wrong error %u, access %x\n", GetLastError(), 1 << i); + else + todo_wine ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u, , access %x\n", GetLastError(), 1 << i); ReleaseMutex(hCreated); failed |=0x1 << i; } } - ok( failed == 0x0de0fffe, "open succeded when it shouldn't: %x\n", failed); +todo_wine + ok( failed == 0x0de0fffe, "open succeeded when it shouldn't: %x\n", failed); + SetLastError(0xdeadbeef); ret = ReleaseMutex(hCreated); ok(!ret && (GetLastError() == ERROR_NOT_OWNER), "ReleaseMutex should have failed with ERROR_NOT_OWNER instead of %d\n", GetLastError()); @@ -300,6 +322,8 @@ static void test_event(void) SECURITY_ATTRIBUTES sa; SECURITY_DESCRIPTOR sd; ACL acl; + DWORD ret; + BOOL val; /* no sd */ handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event"); @@ -360,6 +384,39 @@ static void test_event(void) ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError()); CloseHandle( handle ); + + /* resource notifications are events too */ + + if (!pCreateMemoryResourceNotification || !pQueryMemoryResourceNotification) + { + trace( "memory resource notifications not supported\n" ); + return; + } + handle = pCreateMemoryResourceNotification( HighMemoryResourceNotification + 1 ); + ok( !handle, "CreateMemoryResourceNotification succeeded\n" ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); + ret = pQueryMemoryResourceNotification( handle, &val ); + ok( !ret, "QueryMemoryResourceNotification succeeded\n" ); + ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() ); + + handle = pCreateMemoryResourceNotification( LowMemoryResourceNotification ); + ok( handle != 0, "CreateMemoryResourceNotification failed err %u\n", GetLastError() ); + ret = WaitForSingleObject( handle, 10 ); + ok( ret == WAIT_OBJECT_0 || ret == WAIT_TIMEOUT, "WaitForSingleObject wrong ret %u\n", ret ); + + val = ~0; + ret = pQueryMemoryResourceNotification( handle, &val ); + ok( ret, "QueryMemoryResourceNotification failed err %u\n", GetLastError() ); + ok( val == FALSE || val == TRUE, "wrong value %u\n", val ); + ret = CloseHandle( handle ); + ok( ret, "CloseHandle failed err %u\n", GetLastError() ); + + handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event"); + val = ~0; + ret = pQueryMemoryResourceNotification( handle, &val ); + ok( ret, "QueryMemoryResourceNotification failed err %u\n", GetLastError() ); + ok( val == FALSE || val == TRUE, "wrong value %u\n", val ); + CloseHandle( handle ); } static void test_semaphore(void) @@ -1074,6 +1131,8 @@ START_TEST(sync) pDeleteTimerQueueEx = (void*)GetProcAddress(hdll, "DeleteTimerQueueEx"); pDeleteTimerQueueTimer = (void*)GetProcAddress(hdll, "DeleteTimerQueueTimer"); pOpenWaitableTimerA = (void*)GetProcAddress(hdll, "OpenWaitableTimerA"); + pCreateMemoryResourceNotification = (void *)GetProcAddress(hdll, "CreateMemoryResourceNotification"); + pQueryMemoryResourceNotification = (void *)GetProcAddress(hdll, "QueryMemoryResourceNotification"); test_signalandwait(); test_mutex(); diff --git a/rostests/winetests/kernel32/volume.c b/rostests/winetests/kernel32/volume.c index f4a0f143c7d..1d027826754 100644 --- a/rostests/winetests/kernel32/volume.c +++ b/rostests/winetests/kernel32/volume.c @@ -44,6 +44,12 @@ static void test_query_dos_deviceA(void) DWORD ret, ret2, buflen=32768; BOOL found = FALSE; + /* callers must guess the buffer size */ + SetLastError(0xdeadbeef); + ret = QueryDosDeviceA( NULL, NULL, 0 ); + ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, + "QueryDosDeviceA(no buffer): returned %u, le=%u\n", ret, GetLastError()); + buffer = HeapAlloc( GetProcessHeap(), 0, buflen ); SetLastError(0xdeadbeef); ret = QueryDosDeviceA( NULL, buffer, buflen );